diff -Nru kdepim-runtime-4.14.6/accountwizard/accountwizard.desktop kdepim-runtime-15.08.0/accountwizard/accountwizard.desktop --- kdepim-runtime-4.14.6/accountwizard/accountwizard.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/accountwizard.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -[Desktop Entry] -Name=Account Wizard -Name[bg]=Помощник за сметки -Name[bs]=Čarobnjak naloga -Name[ca]=Assistent de comptes -Name[ca@valencia]=Assistent de comptes -Name[cs]=Průvodce nastavením účtu -Name[da]=Kontoguide -Name[de]=Zugangsassistent -Name[el]=Οδηγός Λογαριασμού -Name[en_GB]=Account Wizard -Name[es]=Asistente de cuentas -Name[et]=Kontonõustaja -Name[fi]=Opastettu tilien asetus -Name[fr]=Assistant de comptes -Name[ga]=Treoraí Cuntais -Name[gl]=Asistente de contas -Name[hu]=Azonosítóbeállító varázsló -Name[ia]=Assistente de conto -Name[it]=Procedura guidata per la creazione di account -Name[ja]=アカウントウィザード -Name[kk]=Тіркелгі шебері -Name[km]=អ្នក​ជំនួយការ​គណនី -Name[ko]=계정 마법사 -Name[lt]=Paskyros vediklis -Name[lv]=Konta vednis -Name[mai]=खाता विजार्ड -Name[nb]=Konto-veiviser -Name[nds]=Konto-Hölper -Name[nl]=Accountassistent -Name[pa]=ਅਕਾਊਂਟ ਸਹਾਇਕ -Name[pl]=Pomocnik konta -Name[pt]=Assistente de Contas -Name[pt_BR]=Assistente de contas -Name[ro]=Expert conturi -Name[ru]=Мастер учётных записей -Name[sk]=Sprievodca účtom -Name[sl]=Čarovnik za račune -Name[sr]=Чаробњак за налоге -Name[sr@ijekavian]=Чаробњак за налоге -Name[sr@ijekavianlatin]=Čarobnjak za naloge -Name[sr@latin]=Čarobnjak za naloge -Name[sv]=Kontoguide -Name[tr]=Hesap Sihirbazı -Name[ug]=زىيارەت يېتەكچىسى -Name[uk]=Майстер облікових записів -Name[x-test]=xxAccount Wizardxx -Name[zh_CN]=账户向导 -Name[zh_TW]=帳號精靈 -Exec=accountwizard --package %u -Type=Application -NoDisplay=true -Comment=Launch the account wizard to configure PIM accounts. -Comment[bs]=Pokreni čarobnjaka za naloge za konfigurisanje PIM naloga. -Comment[ca]=Llança l'assistent de comptes per a configurar comptes de PIM. -Comment[ca@valencia]=Llança l'assistent de comptes per a configurar comptes de PIM. -Comment[cs]=Spustit průvodce nastavením PIM účtů. -Comment[da]=Start kontoguiden for at konfigurere PIM-konti. -Comment[de]=Den Zugangsassistenten zum Einrichten von PIM-Zugängen starten. -Comment[el]=Εκτέλεση του οδηγού λογαριασμού για τη διαμόρφωση λογαριασμών PIM. -Comment[en_GB]=Launch the account wizard to configure PIM accounts. -Comment[es]=Lanzar el asistente de cuentas para configurar las cuentas PIM. -Comment[et]=Kontonõustaja käivitamine PIM-kontode seadistamiseks. -Comment[fi]=Käynnistä PIM-tilien opastettu asetus. -Comment[fr]=Lance l'assistant de compte pour configurer les comptes PIM. -Comment[gl]=Iniciar o asistente de contas para configurar as contas de información persoal -Comment[hu]=A PIM azonosítókat beállító varázsló elindítása. -Comment[ia]=Aperi le assistente de conto pro configurar contos del Administration de Informationes Personal -Comment[it]=Esegue la procedura guidata per la creazione di account per configurare gli account di PIM. -Comment[kk]=PIM тіркелгілерін баптау үшін шеберін жегеді. -Comment[km]=ចាប់ផ្ដើម​អ្នក​ជំនួយការ​គណនី​ ដើម្បី​កំណត់​រចនាសម្ព័ន្ធ​គណនី PIM ។ -Comment[ko]=계정 마법사를 실행하여 PIM 계정을 설정합니다. -Comment[lt]=PIM paskyros nustatymui, paleisti paskyros vediklį. -Comment[lv]=Palaiž konta vedni, lai konfigurētu PIM kontus. -Comment[nb]=Start kontoveiviseren for å sette opp PIM-kontoer. -Comment[nds]=Konto-Hölper för't Inrichten vun PIM-Kontos starten -Comment[nl]=Start de accountassistent om PIM-accounts in te stellen. -Comment[pl]=Uruchom pomocnika konta, aby ustawić konta ZIO. -Comment[pt]=Lançar o assistente de contas para configurar as contas PIM. -Comment[pt_BR]=Executa o assistente para configuração das contas PIM. -Comment[ro]=Lansează expertul de conturi pentru a configura conturi noi. -Comment[ru]=Мастер для настройки учётных записей персонального информационного менеджера. -Comment[sk]=Spustí sprievodcu účtami na nasatavenie PIM účtov. -Comment[sl]=Zaženite čarovnika za nastavljanje računov za osebne podatke. -Comment[sr]=Покрените чаробњак да подесите ПИМ налоге. -Comment[sr@ijekavian]=Покрените чаробњак да подесите ПИМ налоге. -Comment[sr@ijekavianlatin]=Pokrenite čarobnjak da podesite PIM naloge. -Comment[sr@latin]=Pokrenite čarobnjak da podesite PIM naloge. -Comment[sv]=Starta kontoguiden för att anpassa konton för personlig informationshantering. -Comment[tr]=PIM hesaplarını düzenlemek için hesap sihirbazını başlat. -Comment[ug]=PIM ھېساباتلىرىنى سەپلەشتە ئىشلىتىدىغان ھېسابات يېتەكچىسىنى ئىجرا قىلىش -Comment[uk]=Запустити майстер облікових записів для налаштування. -Comment[x-test]=xxLaunch the account wizard to configure PIM accounts.xx -Comment[zh_CN]=调用账户向导配置个人信息账户。 -Comment[zh_TW]=啟動帳號精靈來設定 PIM 帳號 -MimeType=application/x-accountwizard-package; -Terminal=false diff -Nru kdepim-runtime-4.14.6/accountwizard/accountwizard.knsrc kdepim-runtime-15.08.0/accountwizard/accountwizard.knsrc --- kdepim-runtime-4.14.6/accountwizard/accountwizard.knsrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/accountwizard.knsrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -[KNewStuff3] -ProvidersUrl=http://download.kde.org/ocs/providers.xml -Categories=Akonadi Email Providers -TargetDir=akonadi/accountwizard -Uncompress=archive diff -Nru kdepim-runtime-4.14.6/accountwizard/accountwizard-mime.xml kdepim-runtime-15.08.0/accountwizard/accountwizard-mime.xml --- kdepim-runtime-4.14.6/accountwizard/accountwizard-mime.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/accountwizard-mime.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ - - - - KDE Accountwizard Package - - - diff -Nru kdepim-runtime-4.14.6/accountwizard/CMakeLists.txt kdepim-runtime-15.08.0/accountwizard/CMakeLists.txt --- kdepim-runtime-4.14.6/accountwizard/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ -add_definitions( -DQT_NO_CAST_FROM_ASCII ) -add_definitions( -DQT_NO_CAST_TO_ASCII ) - -# allow to disable GHNS support on resource-constrained systems -option( ACCOUNTWIZARD_NO_GHNS "Disable GHNS support in the account wizard" ${KDEPIM_MOBILE_UI} ) -if ( ACCOUNTWIZARD_NO_GHNS ) - add_definitions( -DACCOUNTWIZARD_NO_GHNS ) -endif () - -set(accountwizard_srcs - dialog.cpp - typepage.cpp - loadpage.cpp - global.cpp - page.cpp - dynamicpage.cpp - setupmanager.cpp - setuppage.cpp - resource.cpp - setupobject.cpp - transport.cpp - configfile.cpp - ldap.cpp - identity.cpp - servertest.cpp - personaldatapage.cpp - ispdb/ispdb.cpp -) - -kde4_add_ui_files(accountwizard_srcs - ui/typepage.ui - ui/loadpage.ui - ui/setuppage.ui - ui/personaldatapage.ui -) - -set(accountwizard_libs - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_MAILTRANSPORT_LIBS} - ${KDEPIMLIBS_KPIMUTILS_LIBS} - ${KDE4_KROSSCORE_LIBS} - ${KDE4_KDECORE_LIBS} - ${KDE4_KIO_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${KDEPIMLIBS_KPIMIDENTITIES_LIBS} - ${QT_QTGUI_LIBRARY} - ${QT_QTUITOOLS_LIBRARY} -) - -if ( NOT ACCOUNTWIZARD_NO_GHNS ) - set(accountwizard_srcs ${accountwizard_srcs} providerpage.cpp) - kde4_add_ui_files(accountwizard_srcs ui/providerpage.ui) - set(accountwizard_libs ${accountwizard_libs} ${KDE4_KNEWSTUFF3_LIBS}) -endif () - -kde4_add_executable(accountwizard ${accountwizard_srcs} main.cpp) -target_link_libraries(accountwizard ${accountwizard_libs}) - -kde4_add_plugin(accountwizard_plugin ${accountwizard_srcs} inprocess-main.cpp) -target_link_libraries(accountwizard_plugin ${accountwizard_libs}) - -if ( NOT ACCOUNTWIZARD_NO_GHNS ) - install(FILES accountwizard.knsrc DESTINATION ${CONFIG_INSTALL_DIR}) -endif () -install(TARGETS accountwizard ${INSTALL_TARGETS_DEFAULT_ARGS}) -install(TARGETS accountwizard_plugin DESTINATION ${PLUGIN_INSTALL_DIR}) -install(PROGRAMS accountwizard.desktop DESTINATION ${XDG_APPS_INSTALL_DIR}) -install(FILES accountwizard-mime.xml DESTINATION ${XDG_MIME_INSTALL_DIR}) -update_xdg_mimetypes(${XDG_MIME_INSTALL_DIR}) - -add_subdirectory(wizards) diff -Nru kdepim-runtime-4.14.6/accountwizard/configfile.cpp kdepim-runtime-15.08.0/accountwizard/configfile.cpp --- kdepim-runtime-4.14.6/accountwizard/configfile.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/configfile.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -/* - Copyright (c) 2010-2015 Laurent Montel - - 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 "configfile.h" - -#include -#include -#include -#include - -ConfigFile::ConfigFile( const QString & configName, QObject *parent ) - : SetupObject( parent ) -{ - m_name = configName; - m_config = new KConfig( configName ); -} - -ConfigFile::~ConfigFile() -{ - delete m_config; -} - -void ConfigFile::write() -{ - create(); -} - -void ConfigFile::create() -{ - emit info( i18n( "Writing config file for %1...",m_name ) ); - - foreach ( const Config &c, m_configData ) { - KConfigGroup grp = m_config->group( c.group ); - if ( c.obscure ) - grp.writeEntry( c.key, KStringHandler::obscure( c.value ) ); - else - grp.writeEntry( c.key, c.value ); - } - - m_config->sync(); - emit finished( i18n( "Config file for %1 is writing.", m_name ) ); -} - -void ConfigFile::destroy() -{ - emit info( i18n( "Config file for %1 was not changed.", m_name ) ); -} - -void ConfigFile::setName( const QString &name ) -{ - m_name = name; -} - - -void ConfigFile::setConfig( const QString &group, const QString &key, const QString &value ) -{ - Config conf; - conf.group = group; - conf.key = key; - conf.value = value; - conf.obscure = false; - m_configData.append( conf ); -} - -void ConfigFile::setPassword(const QString& group, const QString& key, const QString& value) -{ - Config conf; - conf.group = group; - conf.key = key; - conf.value = value; - conf.obscure = true; - m_configData.append( conf ); -} - - diff -Nru kdepim-runtime-4.14.6/accountwizard/configfile.h kdepim-runtime-15.08.0/accountwizard/configfile.h --- kdepim-runtime-4.14.6/accountwizard/configfile.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/configfile.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -/* - Copyright (c) 2010-2015 Laurent Montel - - 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 CONFIGFILE_H -#define CONFIGFILE_H - -#include "setupobject.h" - -class KConfig; - -struct Config { - QString group; - QString key; - QString value; - bool obscure; -}; - -class ConfigFile : public SetupObject -{ - Q_OBJECT - public: - explicit ConfigFile( const QString& configName, QObject *parent = 0 ); - ~ConfigFile(); - void create(); - void destroy(); - public slots: - Q_SCRIPTABLE void write(); - Q_SCRIPTABLE void setName( const QString & name ); - Q_SCRIPTABLE void setConfig( const QString &group, const QString &key, const QString &value ); - Q_SCRIPTABLE void setPassword( const QString &group, const QString &key, const QString &value ); - private: - QList m_configData; - QString m_name; - KConfig *m_config; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/dialog.cpp kdepim-runtime-15.08.0/accountwizard/dialog.cpp --- kdepim-runtime-4.14.6/accountwizard/dialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/dialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,206 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - Copyright (c) 2010 Tom Albers - - 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 "dialog.h" -#include "personaldatapage.h" -#ifndef ACCOUNTWIZARD_NO_GHNS -#include "providerpage.h" -#endif -#include "typepage.h" -#include "loadpage.h" -#include "global.h" -#include "dynamicpage.h" -#include "setupmanager.h" -#include "servertest.h" -#include "setuppage.h" - -#include - -#include -#include -#include -#include - -#include - -Dialog::Dialog(QWidget* parent, Qt::WindowFlags flags ) : - KAssistantDialog( parent, flags ) -{ -#if defined (Q_WS_MAEMO_5) || defined (MEEGO_EDITION_HARMATTAN) - setWindowState( Qt::WindowFullScreen ); -#endif - - showButton( Help, false ); // we don't have help for the account wizard atm - - mSetupManager = new SetupManager( this ); - const bool showPersonalDataPage = Global::typeFilter().size() == 1 && Global::typeFilter().first() == KMime::Message::mimeType(); - - if ( showPersonalDataPage ) { - // todo: dont ask these details based on a setting of the desktop file. - PersonalDataPage *pdpage = new PersonalDataPage( this ); - addPage( pdpage, i18n( "Provide personal data" ) ); - connect( pdpage, SIGNAL(manualWanted(bool)), SLOT(slotManualConfigWanted(bool)) ); - if ( !Global::assistant().isEmpty() ) { - pdpage->setHideOptionInternetSearch( true ); - } - } - - if ( Global::assistant().isEmpty() ) { - TypePage* typePage = new TypePage( this ); - connect( typePage->treeview(), SIGNAL(doubleClicked(QModelIndex)), SLOT(slotNextPage()) ); -#ifndef ACCOUNTWIZARD_NO_GHNS - connect( typePage, SIGNAL(ghnsWanted()), SLOT(slotGhnsWanted()) ); -#endif - mTypePage = addPage( typePage, i18n( "Select Account Type" ) ); - setAppropriate( mTypePage, false ); - -#ifndef ACCOUNTWIZARD_NO_GHNS - ProviderPage *ppage = new ProviderPage( this ); - connect( typePage, SIGNAL(ghnsWanted()), ppage, SLOT(startFetchingData()) ); - connect( ppage->treeview(), SIGNAL(doubleClicked(QModelIndex)), SLOT(slotNextPage()) ); - connect( ppage, SIGNAL(ghnsNotWanted()), SLOT(slotGhnsNotWanted()) ); - mProviderPage = addPage( ppage, i18n( "Select Provider" ) ); - setAppropriate( mProviderPage, false ); -#endif - } - - LoadPage *loadPage = new LoadPage( this ); - mLoadPage = addPage( loadPage, i18n( "Loading Assistant" ) ); - setAppropriate( mLoadPage, false ); - loadPage->exportObject( this, QLatin1String( "Dialog" ) ); - loadPage->exportObject( mSetupManager, QLatin1String( "SetupManager" ) ); - loadPage->exportObject( new ServerTest( this ), QLatin1String( "ServerTest" ) ); - connect( loadPage, SIGNAL(aboutToStart()), SLOT(clearDynamicPages()) ); - - SetupPage *setupPage = new SetupPage( this ); - mLastPage = addPage( setupPage, i18n( "Setting up Account" ) ); - mSetupManager->setSetupPage( setupPage ); - - slotManualConfigWanted( !showPersonalDataPage ); - - Page *page = qobject_cast( currentPage()->widget() ); - page->enterPageNext(); - emit page->pageEnteredNext(); - enableButton( KDialog::Help, false ); -} - -KPageWidgetItem* Dialog::addPage(Page* page, const QString &title) -{ - KPageWidgetItem *item = KAssistantDialog::addPage( page, title ); - connect( page, SIGNAL(leavePageNextOk()), SLOT(slotNextOk()) ); - connect( page, SIGNAL(leavePageBackOk()), SLOT(slotBackOk()) ); - page->setPageWidgetItem( item ); - return item; -} - - -void Dialog::slotNextPage() -{ - next(); -} - -void Dialog::next() -{ - Page *page = qobject_cast( currentPage()->widget() ); - page->leavePageNext(); - page->leavePageNextRequested(); -} - -void Dialog::slotNextOk() -{ - Page *page = qobject_cast( currentPage()->widget() ); - emit page->pageLeftNext(); - KAssistantDialog::next(); - page = qobject_cast( currentPage()->widget() ); - page->enterPageNext(); - emit page->pageEnteredNext(); -} - - -void Dialog::back() -{ - Page *page = qobject_cast( currentPage()->widget() ); - page->leavePageBack(); - page->leavePageBackRequested(); -} - -void Dialog::slotBackOk() -{ - Page *page = qobject_cast( currentPage()->widget() ); - emit page->pageLeftBack(); - KAssistantDialog::back(); - page = qobject_cast( currentPage()->widget() ); - page->enterPageBack(); - emit page->pageEnteredBack(); -} - -QObject* Dialog::addPage(const QString& uiFile, const QString &title ) -{ - kDebug() << uiFile; - DynamicPage *page = new DynamicPage( Global::assistantBasePath() + uiFile, this ); - connect( page, SIGNAL(leavePageNextOk()), SLOT(slotNextOk()) ); - connect( page, SIGNAL(leavePageBackOk()), SLOT(slotBackOk()) ); - KPageWidgetItem* item = insertPage( mLastPage, page, title ); - page->setPageWidgetItem( item ); - mDynamicPages.push_back( item ); - return page; -} - -void Dialog::slotManualConfigWanted( bool show ) -{ - Q_ASSERT( mTypePage ); - setAppropriate( mTypePage, show ); - setAppropriate( mLoadPage, show ); -} - -#ifndef ACCOUNTWIZARD_NO_GHNS -void Dialog::slotGhnsWanted() -{ - Q_ASSERT( mProviderPage ); - setAppropriate( mProviderPage, true ); - setCurrentPage( mProviderPage ); -} - -void Dialog::slotGhnsNotWanted() -{ - Q_ASSERT( mProviderPage ); - setAppropriate( mProviderPage, false ); -} -#endif - -SetupManager* Dialog::setupManager() -{ - return mSetupManager; -} - -void Dialog::clearDynamicPages() -{ - foreach ( KPageWidgetItem *item, mDynamicPages ) - removePage( item ); - mDynamicPages.clear(); -} - -void Dialog::reject() -{ - connect( mSetupManager, SIGNAL(rollbackComplete()), SLOT(close()) ); - mSetupManager->requestRollback(); -} - - diff -Nru kdepim-runtime-4.14.6/accountwizard/dialog.h kdepim-runtime-15.08.0/accountwizard/dialog.h --- kdepim-runtime-4.14.6/accountwizard/dialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/dialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 DIALOG_H -#define DIALOG_H - -#include "setupmanager.h" -#include - -class Page; -class TypePage; - -class Dialog : public KAssistantDialog -{ - Q_OBJECT - public: - explicit Dialog( QWidget *parent = 0, Qt::WindowFlags flags = 0 ); - - /* reimpl */ void next(); - /* reimpl */ void back(); - - // give room for certain pages to create objects too. - SetupManager* setupManager(); - - public slots: - Q_SCRIPTABLE QObject* addPage( const QString &uiFile, const QString &title ); - - void reject(); - - private slots: - void slotNextPage(); -#ifndef ACCOUNTWIZARD_NO_GHNS - void slotGhnsWanted(); - void slotGhnsNotWanted(); -#endif - void slotManualConfigWanted( bool ); - void slotNextOk(); - void slotBackOk(); - void clearDynamicPages(); - - private: - KPageWidgetItem* addPage( Page* page, const QString &title ); - - private: - SetupManager* mSetupManager; - KPageWidgetItem* mLastPage; - KPageWidgetItem* mProviderPage; - KPageWidgetItem* mTypePage; - KPageWidgetItem* mLoadPage; - QVector mDynamicPages; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/dynamicpage.cpp kdepim-runtime-15.08.0/accountwizard/dynamicpage.cpp --- kdepim-runtime-4.14.6/accountwizard/dynamicpage.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/dynamicpage.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "dynamicpage.h" - -#include - -#include -#include -#include -#include - -DynamicPage::DynamicPage(const QString& uiFile, KAssistantDialog* parent) : Page( parent ) -{ - QVBoxLayout *layout = new QVBoxLayout; - layout->setMargin( 0 ); - setLayout( layout ); - -#ifdef KDEPIM_MOBILE_UI - // for mobile ui we put the page into a scroll area in case it's too big - QScrollArea *pageParent = new QScrollArea( this ); - pageParent->setFrameShape( QFrame::NoFrame ); - pageParent->setWidgetResizable( true ); - layout->addWidget( pageParent ); -#else - QWidget *pageParent = this; -#endif - - QUiLoader loader; - QFile file( uiFile ); - file.open( QFile::ReadOnly ); - kDebug() << uiFile; - m_dynamicWidget = loader.load( &file, pageParent ); - file.close(); - -#ifdef KDEPIM_MOBILE_UI - pageParent->setWidget( m_dynamicWidget ); -#else - layout->addWidget( m_dynamicWidget ); -#endif - - setValid( true ); -} - -QObject* DynamicPage::widget() const -{ - return m_dynamicWidget; -} - diff -Nru kdepim-runtime-4.14.6/accountwizard/dynamicpage.h kdepim-runtime-15.08.0/accountwizard/dynamicpage.h --- kdepim-runtime-4.14.6/accountwizard/dynamicpage.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/dynamicpage.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 DYNAMICPAGE_H -#define DYNAMICPAGE_H - -#include "page.h" - -class DynamicPage : public Page -{ - Q_OBJECT - public: - explicit DynamicPage( const QString &uiFile, KAssistantDialog* parent = 0 ); - - public slots: - /// returns the top-level widget of the UI file - Q_SCRIPTABLE QObject* widget() const; - - private: - QWidget* m_dynamicWidget; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/global.cpp kdepim-runtime-15.08.0/accountwizard/global.cpp --- kdepim-runtime-4.14.6/accountwizard/global.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/global.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "global.h" - -#include -#include -#include -#include -#include -#include -#include - -class GlobalPrivate -{ - public: - QStringList filter; - QString assistant; -}; - -K_GLOBAL_STATIC( GlobalPrivate, sInstance ) - - -QString Global::assistant() -{ - return sInstance->assistant; -} - -void Global::setAssistant(const QString& assistant) -{ - const QFileInfo info( assistant ); - if ( info.isAbsolute() ) { - sInstance->assistant = assistant; - return; - } - - const QStringList list = KGlobal::dirs()->findAllResources( - "data", QLatin1String( "akonadi/accountwizard/*.desktop" ), - KStandardDirs::Recursive | KStandardDirs::NoDuplicates ); - foreach ( const QString &entry, list ) { - const QFileInfo info( entry ); - const QDir dir( info.absolutePath() ); - kDebug() << dir.dirName(); - if ( dir.dirName() == assistant ) { - sInstance->assistant = entry; - return; - } - } - - sInstance->assistant.clear(); -} - - -QStringList Global::typeFilter() -{ - return sInstance->filter; -} - -void Global::setTypeFilter(const QStringList& filter) -{ - sInstance->filter = filter; -} - -QString Global::assistantBasePath() -{ - const QFileInfo info( assistant() ); - if ( info.isAbsolute() ) - return info.absolutePath() + QDir::separator(); - return QString(); -} - -QString Global::unpackAssistant( const KUrl& remotePackageUrl ) -{ - QString localPackageFile; - if ( remotePackageUrl.protocol() == QLatin1String( "file" ) ) { - localPackageFile = remotePackageUrl.path(); - } else { - QString remoteFileName = QFileInfo( remotePackageUrl.path() ).fileName(); - localPackageFile = KStandardDirs::locateLocal( "cache", QLatin1String("accountwizard/") + remoteFileName ); - KIO::Job* job = KIO::copy( remotePackageUrl, localPackageFile, KIO::Overwrite | KIO::HideProgressInfo ); - kDebug() << "downloading remote URL" << remotePackageUrl << "to" << localPackageFile; - if ( !KIO::NetAccess::synchronousRun( job, 0 ) ) - return QString(); - } - - const KUrl file( QLatin1String("tar://") + localPackageFile ); - const QFileInfo fi( localPackageFile ); - const QString assistant = fi.baseName(); - const QString dest = KStandardDirs::locateLocal( "appdata", QLatin1String("/") ); - KStandardDirs::makeDir( dest + file.fileName() ); - KIO::Job* getJob = KIO::copy( file, dest, KIO::Overwrite | KIO::HideProgressInfo ); - if ( KIO::NetAccess::synchronousRun( getJob, 0 ) ) { - kDebug() << "worked, unpacked in " << dest; - return dest + file.fileName() + QLatin1Char('/') + assistant + QLatin1Char('/') + assistant + QLatin1String(".desktop"); - } else { - kDebug() << "failed" << getJob->errorString(); - return QString(); - } -} diff -Nru kdepim-runtime-4.14.6/accountwizard/global.h kdepim-runtime-15.08.0/accountwizard/global.h --- kdepim-runtime-4.14.6/accountwizard/global.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/global.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 GLOBAL_H -#define GLOBAL_H - -#include -#include - -namespace Global -{ - QStringList typeFilter(); - void setTypeFilter( const QStringList &filter ); - - QString assistant(); - void setAssistant( const QString &assistant ); - - QString assistantBasePath(); - - QString unpackAssistant( const KUrl& remotePackageUrl ); -} - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/HOWTO kdepim-runtime-15.08.0/accountwizard/HOWTO --- kdepim-runtime-4.14.6/accountwizard/HOWTO 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/HOWTO 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -You can create packages too... Want to read about it? -http://techbase.kde.org/Development/Tutorials/Akonadi/CreatingAccountWizardPackages diff -Nru kdepim-runtime-4.14.6/accountwizard/identity.cpp kdepim-runtime-15.08.0/accountwizard/identity.cpp --- kdepim-runtime-4.14.6/accountwizard/identity.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/identity.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,152 +0,0 @@ -/* - Copyright (c) 2010-2015 Laurent Montel - - 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 "identity.h" -#include "transport.h" - -#include -#include - -#include - -Identity::Identity( QObject *parent ) - : SetupObject( parent ), - m_transport( 0 ) -{ - m_manager = new KPIMIdentities::IdentityManager( false, this, "mIdentityManager" ); - m_identity = &m_manager->newFromScratch( QString() ); - Q_ASSERT( m_identity != 0 ); -} - -Identity::~Identity() -{ - delete m_manager; -} - -void Identity::create() -{ - emit info( i18n( "Setting up identity..." ) ); - - // store identity information - // TODO now that we have the identity object around anyway we can probably get rid of most of the other members - m_identity->setIdentityName( identityName() ); - m_identity->setFullName( m_realName ); - m_identity->setPrimaryEmailAddress( m_email ); - m_identity->setOrganization( m_organization ); - if ( m_transport && m_transport->transportId() > 0 ) - m_identity->setTransport( QString::number( m_transport->transportId() ) ); - if ( !m_signature.isEmpty() ) { - const KPIMIdentities::Signature sig( m_signature ); - m_identity->setSignature( sig ); - } - if ( !m_prefCryptoFormat.isEmpty() ) - m_identity->setPreferredCryptoMessageFormat( m_prefCryptoFormat ); - if ( !m_xface.isEmpty() ) { - m_identity->setXFaceEnabled( true ); - m_identity->setXFace( m_xface ); - } - m_manager->setAsDefault( m_identity->uoid() ); - m_manager->commit(); - - emit finished( i18n( "Identity set up." ) ); -} - -QString Identity::identityName() const -{ - // create identity name - QString name( m_identityName ); - if ( name.isEmpty() ) { - name = i18nc( "Default name for new email accounts/identities.", "Unnamed" ); - - QString idName = m_email; - int pos = idName.indexOf( QLatin1Char('@') ); - if ( pos != -1 ) { - name = idName.mid( 0, pos ); - } - - // Make the name a bit more human friendly - name.replace( QLatin1Char('.'), QLatin1Char(' ') ); - pos = name.indexOf( QLatin1Char(' ') ); - if ( pos != 0 ) { - name[ pos + 1 ] = name[ pos + 1 ].toUpper(); - } - name[ 0 ] = name[ 0 ].toUpper(); - } - - if ( !m_manager->isUnique( name ) ) { - name = m_manager->makeUnique( name ); - } - return name; -} - - -void Identity::destroy() -{ - m_manager->removeIdentityForced( m_identity->identityName() ); - m_manager->commit(); - m_identity = 0; - emit info( i18n( "Identity removed." ) ); -} - -void Identity::setIdentityName(const QString& name) -{ - m_identityName = name; -} - -void Identity::setRealName( const QString &name ) -{ - m_realName = name; -} - -void Identity::setOrganization( const QString &org ) -{ - m_organization = org; -} - -void Identity::setEmail( const QString &email ) -{ - m_email = email; -} - -uint Identity::uoid() const -{ - return m_identity->uoid(); -} - -void Identity::setTransport(QObject* transport) -{ - m_transport = qobject_cast( transport ); - setDependsOn( qobject_cast( transport ) ); -} - -void Identity::setSignature(const QString& sig) -{ - m_signature = sig; -} - -void Identity::setPreferredCryptoMessageFormat(const QString& format) -{ - m_prefCryptoFormat = format; -} - -void Identity::setXFace(const QString& xface) -{ - m_xface = xface; -} - diff -Nru kdepim-runtime-4.14.6/accountwizard/identity.h kdepim-runtime-15.08.0/accountwizard/identity.h --- kdepim-runtime-4.14.6/accountwizard/identity.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/identity.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -/* - Copyright (c) 2010-2015 Laurent Montel - - 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 IDENTITY_H -#define IDENTITY_H - -#include "setupobject.h" - -class Transport; - -namespace KPIMIdentities { - class Identity; - class IdentityManager; -} - -class Identity : public SetupObject -{ - Q_OBJECT - public: - explicit Identity( QObject *parent = 0 ); - ~Identity(); - void create(); - void destroy(); - - public slots: - Q_SCRIPTABLE void setIdentityName( const QString &name ); - Q_SCRIPTABLE void setRealName( const QString & name ); - Q_SCRIPTABLE void setEmail( const QString &email ); - Q_SCRIPTABLE void setOrganization( const QString &org ); - Q_SCRIPTABLE void setSignature( const QString &sig ); - Q_SCRIPTABLE uint uoid() const; - Q_SCRIPTABLE void setTransport( QObject* transport ); - Q_SCRIPTABLE void setPreferredCryptoMessageFormat( const QString &format ); - Q_SCRIPTABLE void setXFace( const QString &xface ); - - protected: - QString identityName() const; - - private: - QString m_identityName; - QString m_realName; - QString m_email; - QString m_organization; - QString m_signature; - QString m_prefCryptoFormat; - QString m_xface; - Transport *m_transport; - KPIMIdentities::IdentityManager *m_manager; - KPIMIdentities::Identity *m_identity; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/inprocess-main.cpp kdepim-runtime-15.08.0/accountwizard/inprocess-main.cpp --- kdepim-runtime-4.14.6/accountwizard/inprocess-main.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/inprocess-main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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 "dialog.h" -#include "global.h" - -#include -#include -#include -#include - -class AccountWizard : public QObject -{ - Q_OBJECT - public: - explicit AccountWizard( QObject* parent = 0 ) : QObject( parent ) {} - - public slots: - void run( const QStringList &types, QWidget *parent ) - { - if ( !types.isEmpty() ) - Global::setTypeFilter( types ); - Dialog dlg( parent ); - dlg.exec(); - } -}; - -Q_EXPORT_PLUGIN2( accountwizard, AccountWizard ) - -#include "inprocess-main.moc" diff -Nru kdepim-runtime-4.14.6/accountwizard/ispdb/CMakeLists.txt kdepim-runtime-15.08.0/accountwizard/ispdb/CMakeLists.txt --- kdepim-runtime-4.14.6/accountwizard/ispdb/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/ispdb/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ - -set(ispdb_srcs - main.cpp - ispdb.cpp -) - -kde4_add_executable(ispdb ${ispdb_srcs}) - -target_link_libraries(ispdb - ${KDE4_KDECORE_LIBS} - ${KDE4_KIO_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} -) - -install(TARGETS ispdb ${INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/accountwizard/ispdb/ispdb.cpp kdepim-runtime-15.08.0/accountwizard/ispdb/ispdb.cpp --- kdepim-runtime-4.14.6/accountwizard/ispdb/ispdb.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/ispdb/ispdb.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,277 +0,0 @@ -/* - Copyright (c) 2010 Omat Holding B.V. - - 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 "ispdb.h" -#include -#include -#include -#include - -#include -#include - -Ispdb::Ispdb( QObject *parent ) - : QObject( parent ), mServerType( DataBase ) -{ -} - -Ispdb::~Ispdb() -{ -} - -void Ispdb::setEmail( const QString& address ) -{ - KMime::Types::Mailbox box; - box.fromUnicodeString( address ); - mAddr = box.addrSpec(); -} - -void Ispdb::start() -{ - kDebug() << mAddr.asString(); - // we should do different things in here. But lets focus in the db first. - lookupInDb(); -} - -void Ispdb::startJob( const KUrl&url ) -{ - QMap< QString, QVariant > map; - map[QLatin1String("errorPage")] = false; - - KIO::TransferJob* job = KIO::get( url, KIO::NoReload, KIO::HideProgressInfo ); - job->setMetaData( map ); - connect( job, SIGNAL(result(KJob*)), - this, SLOT(slotResult(KJob*)) ); - connect( job, SIGNAL(data(KIO::Job*,QByteArray)), - this, SLOT(dataArrived(KIO::Job*,QByteArray)) ); -} - -void Ispdb::lookupInDb() -{ - KUrl url; - switch( mServerType ) - { - case IspAutoConfig: - { - url = KUrl( QLatin1String("http://autoconfig.") + mAddr.domain.toLower() + QLatin1String("/mail/config-v1.1.xml?emailaddress=") + mAddr.asString().toLower() ); - Q_EMIT searchType(i18n("Lookup configuration: Email provider")); - break; - } - case IspWellKnow: - { - url = KUrl( QLatin1String("http://") + mAddr.domain.toLower() + QLatin1String("/.well-known/autoconfig/mail/config-v1.1.xml") ); - Q_EMIT searchType(i18n("Lookup configuration: Trying common server name")); - break; - } - case DataBase: - { - url = KUrl( QLatin1String("https://autoconfig.thunderbird.net/v1.1/") + mAddr.domain.toLower() ); - Q_EMIT searchType(i18n("Lookup configuration: Mozilla database")); - break; - } - } - startJob( url ); -} - -void Ispdb::slotResult( KJob* job ) -{ - if ( job->error() ) { - kDebug() << "Fetching failed" << job->errorString(); - bool lookupFinished = false; - - switch( mServerType ) { - case IspAutoConfig: { - mServerType = IspWellKnow; - break; - } - case IspWellKnow: { - lookupFinished = true; - break; - } - case DataBase: { - mServerType = IspAutoConfig; - break; - } - } - - if ( lookupFinished ) - { - emit finished( false ); - return; - } - lookupInDb(); - return; - } - - //kDebug() << mData; - QDomDocument document; - bool ok = document.setContent( mData ); - if ( !ok ) { - kDebug() << "Could not parse xml" << mData; - emit finished( false ); - return; - } - - QDomElement docElem = document.documentElement(); - QDomNode m = docElem.firstChild(); // emailprovider - QDomNode n = m.firstChild(); // emailprovider - - while ( !n.isNull() ) { - QDomElement e = n.toElement(); - if ( !e.isNull() ) { - //kDebug() << qPrintable( e.tagName() ); - const QString tagName( e.tagName() ); - if ( tagName == QLatin1String( "domain" ) ) - mDomains << e.text(); - else if ( tagName == QLatin1String( "displayName" ) ) - mDisplayName = e.text(); - else if ( tagName == QLatin1String( "displayShortName" ) ) - mDisplayShortName = e.text(); - else if ( tagName == QLatin1String( "incomingServer" ) - && e.attribute( QLatin1String("type") ) == QLatin1String( "imap" ) ) { - server s = createServer( e ); - if (s.isValid()) - mImapServers.append( s ); - } else if ( tagName == QLatin1String( "incomingServer" ) - && e.attribute( QLatin1String("type") ) == QLatin1String( "pop3" ) ) { - server s = createServer( e ); - if (s.isValid()) - mPop3Servers.append( s ); - } else if ( tagName == QLatin1String( "outgoingServer" ) - && e.attribute( QLatin1String("type") ) == QLatin1String( "smtp" ) ) { - server s = createServer( e ); - if (s.isValid()) - mSmtpServers.append( s ); - } - } - n = n.nextSibling(); - } - - // comment this section out when you are tired of it... - kDebug() << "------------------ summary --------------"; - kDebug() << "Domains" << mDomains; - kDebug() << "Name" << mDisplayName << "(" << mDisplayShortName << ")"; - kDebug() << "Imap servers:"; - foreach ( const server& s, mImapServers ) { - kDebug() << s.hostname << s.port << s.socketType << s.username << s.authentication; - } - kDebug() << "pop3 servers:"; - foreach ( const server& s, mPop3Servers ) { - kDebug() << s.hostname << s.port << s.socketType << s.username << s.authentication; - } - kDebug() << "smtp servers:"; - foreach ( const server& s, mSmtpServers ) { - kDebug() << s.hostname << s.port << s.socketType << s.username << s.authentication; - } - // end section. - - emit finished( true ); -} - -server Ispdb::createServer( const QDomElement& n ) -{ - QDomNode o = n.firstChild(); - server s; - while ( !o.isNull() ) { - QDomElement f = o.toElement(); - if ( !f.isNull() ) { - const QString tagName( f.tagName() ); - if ( tagName == QLatin1String( "hostname" ) ) - s.hostname = replacePlaceholders( f.text() ); - else if ( tagName == QLatin1String( "port" ) ) - s.port = f.text().toInt(); - else if ( tagName == QLatin1String( "socketType" ) ) { - const QString type( f.text() ); - if ( type == QLatin1String( "plain" ) ) - s.socketType = None; - else if ( type == QLatin1String( "SSL" ) ) - s.socketType = SSL; - if ( type == QLatin1String( "STARTTLS" ) ) - s.socketType = StartTLS; - } else if ( tagName == QLatin1String( "username" ) ) { - s.username = replacePlaceholders( f.text() ); - } else if ( tagName == QLatin1String( "authentication" ) ) { - const QString type( f.text() ); - if ( type == QLatin1String( "password-cleartext" ) - || type == QLatin1String( "plain" ) ) - s.authentication = Plain; - else if ( type == QLatin1String( "password-encrypted" ) - || type == QLatin1String( "secure" ) ) - s.authentication = CramMD5; - else if ( type == QLatin1String( "NTLM" ) ) - s.authentication = NTLM; - else if ( type == QLatin1String( "GSSAPI" ) ) - s.authentication = GSSAPI; - else if ( type == QLatin1String( "client-ip-based" ) ) - s.authentication = ClientIP; - else if ( type == QLatin1String( "none" ) ) - s.authentication = NoAuth; - } - } - o = o.nextSibling(); - } - return s; -} - -QString Ispdb::replacePlaceholders( const QString& in ) -{ - QString out( in ); - out.replace( QLatin1String("%EMAILLOCALPART%"), mAddr.localPart ); - out.replace( QLatin1String("%EMAILADDRESS%"), mAddr.asString() ); - out.replace( QLatin1String("%EMAILDOMAIN%"), mAddr.domain ); - return out; -} - -void Ispdb::dataArrived( KIO::Job*, const QByteArray& data ) -{ - mData.append( data ); -} - -// The getters - -QStringList Ispdb::relevantDomains() const -{ - return mDomains; -} - -QString Ispdb::name( length l ) const -{ - if ( l == Long ) - return mDisplayName; - else if ( l == Short ) - return mDisplayShortName; - else - return QString(); //make compiler happy. Not me. -} - -QList< server > Ispdb::imapServers() const -{ - return mImapServers; -} - -QList< server > Ispdb::pop3Servers() const -{ - return mPop3Servers; -} - -QList< server > Ispdb::smtpServers() const -{ - return mSmtpServers; -} - diff -Nru kdepim-runtime-4.14.6/accountwizard/ispdb/ispdb.h kdepim-runtime-15.08.0/accountwizard/ispdb/ispdb.h --- kdepim-runtime-4.14.6/accountwizard/ispdb/ispdb.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/ispdb/ispdb.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,133 +0,0 @@ -/* - Copyright (c) 2010 Omat Holding B.V. - - 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 ISPDB_H -#define ISPDB_H - -#include - -#include -#include - -class QDomElement; - -struct server; - -/** - This class will search in Mozilla's database for an xml file - describing the isp data belonging to that address. This class - searches and wraps the result for further usage. References: - https://wiki.mozilla.org/Thunderbird:Autoconfiguration - https://developer.mozilla.org/en/Thunderbird/Autoconfiguration - https://ispdb.mozillamessaging.com/ -*/ -class Ispdb : public QObject -{ - Q_OBJECT -public: - enum socketType { None = 0, SSL, StartTLS }; - - /** - Ispdb uses custom authtyps, hence the enum here. - @see https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat - In particular, note that Ispdb's Plain represents both Cleartext and AUTH Plain - We will always treat it as Cleartext - */ - enum authType { Plain = 0, CramMD5, NTLM, GSSAPI, ClientIP, NoAuth }; - enum length { Long = 0, Short }; - - /** Constructor */ - explicit Ispdb( QObject *parent = 0 ); - - /** Destructor */ - ~Ispdb(); - - /** After finished() has been emitted you can - retrieve the domains that are covered by these - settings */ - QStringList relevantDomains() const; - - /** After finished() has been emitted you can - get the name of the provider, you can get a long - name and a short one */ - QString name( length ) const; - - /** After finished() has been emitted you can - get a list of imap servers available for this provider */ - QList< server > imapServers() const; - - /** After finished() has been emitted you can - get a list of pop3 servers available for this provider */ - QList< server > pop3Servers() const; - - /** After finished() has been emitted you can - get a list of smtp servers available for this provider */ - QList< server > smtpServers() const; - -public slots: - /** Sets the emailaddress you want to servers for */ - void setEmail( const QString& ); - - /** Starts looking up the servers which belong to the e-mailaddress */ - void start(); - -private slots: - void slotResult( KJob* ); - void dataArrived( KIO::Job*, const QByteArray& data ); - -signals: - /** emitted when done. **/ - void finished( bool ); - void searchType( const QString &type ); - -private: - enum searchServerType { IspAutoConfig = 0, IspWellKnow, DataBase }; - - server createServer( const QDomElement& n ); - void lookupInDb(); - QString replacePlaceholders( const QString& ); - void startJob( const KUrl&url ); - - KMime::Types::AddrSpec mAddr; // emailaddress - QByteArray mData; // storage of incoming data from kio - - // storage of the results - QStringList mDomains; - QString mDisplayName, mDisplayShortName; - QList< server > mImapServers, mPop3Servers, mSmtpServers; - Ispdb::searchServerType mServerType; -}; - -struct server { - server() { - port = -1; - authentication = Ispdb::Plain; - socketType = Ispdb::None; - } - bool isValid() const { - return (port != -1); - } - QString hostname; - int port; - Ispdb::socketType socketType; - QString username; - Ispdb::authType authentication; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/ispdb/main.cpp kdepim-runtime-15.08.0/accountwizard/ispdb/main.cpp --- kdepim-runtime-4.14.6/accountwizard/ispdb/main.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/ispdb/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -/* - Copyright (c) 2010 Omat Holding B.V. - - 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 "ispdb.h" - -#include -#include -#include -#include - -int main( int argc, char **argv ) -{ - KAboutData aboutData( "ispdb", 0, - ki18n( "ISPDB Assistant" ), - "0.1", - ki18n( "Helps setting up PIM accounts" ), - KAboutData::License_LGPL, - ki18n( "(c) 2010 Omat Holding B.V." ), - KLocalizedString(), - "http://pim.kde.org/akonadi/" ); - aboutData.setProgramIconName( "akonadi" ); - aboutData.addAuthor( ki18n( "Tom Albers" ), ki18n( "Author" ), "toma@kde.org" ); - - KCmdLineArgs::init( argc, argv, &aboutData ); - KCmdLineOptions options; - options.add( "email ", ki18n( "Tries to fetch the settings for that email address" ) ); - KCmdLineArgs::addCmdLineOptions( options ); - KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - - QString email; - if ( !args->getOption( "email" ).isEmpty() ) - email = args->getOption( "email" ); - else - email = "blablabla@gmail.com"; - - - KApplication app; - - Ispdb ispdb; - ispdb.setEmail( email ); - ispdb.start(); - - return app.exec(); - -} diff -Nru kdepim-runtime-4.14.6/accountwizard/ldap.cpp kdepim-runtime-15.08.0/accountwizard/ldap.cpp --- kdepim-runtime-4.14.6/accountwizard/ldap.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/ldap.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -/* - Copyright (c) 2010-2015 Laurent Montel - - 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 "ldap.h" - -#include -#include -#include - - -Ldap::Ldap( QObject *parent ) - : SetupObject( parent ) -{ -} - -Ldap::~Ldap() -{ -} - -void Ldap::create() -{ - emit info( i18n( "Setting up LDAP server..." ) ); - - if ( m_server.isEmpty() || m_user.isEmpty() ) - return; - - const QString host = m_server; - - // Figure out the basedn - QString basedn = host; - // If the user gave a full email address, the domain name - // of that overrides the server name for the ldap dn - const QString user = m_user; - int pos = user.indexOf( QLatin1String("@") ); - if ( pos > 0 ) { - const QString h = user.mid( pos+1 ); - if ( !h.isEmpty() ) - // The user did type in a domain on the email address. Use that - basedn = h; - } - { // while we're here, write default domain - KConfig c( QLatin1String("kmail2rc") ); - KConfigGroup group = c.group( "General" ); - group.writeEntry( "Default domain", basedn ); - } - - basedn.replace( QLatin1Char('.'), QLatin1String(",dc=") ); - basedn.prepend( QLatin1String("dc=") ); - - // Set the changes - KConfig c( QLatin1String("kabldaprc") ); - KConfigGroup group = c.group( "LDAP" ); - bool hasMyServer = false; - uint selHosts = group.readEntry( "NumSelectedHosts", 0 ); - for ( uint i = 0 ; i < selHosts && !hasMyServer; ++i ) - if ( group.readEntry( QString::fromLatin1( "SelectedHost%1" ).arg( i ), QString() ) == host ) - hasMyServer = true; - if ( !hasMyServer ) { - group.writeEntry( "NumSelectedHosts", selHosts + 1 ); - group.writeEntry( QString::fromLatin1( "SelectedHost%1" ).arg( selHosts ), host ); - group.writeEntry( QString::fromLatin1( "SelectedBase%1" ).arg( selHosts ), basedn ); - group.writeEntry( QString::fromLatin1( "SelectedPort%1" ).arg( selHosts ), "389" ); - if ( !m_authMethod.isEmpty() ) { - group.writeEntry( QString::fromLatin1( "SelectedAuth%1" ).arg( selHosts ), m_authMethod ); - group.writeEntry( QString::fromLatin1( "SelectedBind%1" ).arg( selHosts ), m_bindDn ); - group.writeEntry( QString::fromLatin1( "SelectedPwdBind%1" ).arg( selHosts ), m_password ); - } - } - emit finished( i18n( "LDAP set up." ) ); -} - -void Ldap::destroy() -{ - emit info( i18n( "LDAP not configuring." ) ); -} - -void Ldap::setUser( const QString &user ) -{ - m_user = user; -} - -void Ldap::setServer( const QString &server ) -{ - m_server = server; -} - -void Ldap::setAuthenticationMethod(const QString& meth) -{ - m_authMethod = meth; -} - -void Ldap::setBindDn(const QString& bindDn) -{ - m_bindDn = bindDn; -} - -void Ldap::setPassword(const QString& password) -{ - m_password = password; -} - diff -Nru kdepim-runtime-4.14.6/accountwizard/ldap.h kdepim-runtime-15.08.0/accountwizard/ldap.h --- kdepim-runtime-4.14.6/accountwizard/ldap.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/ldap.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -/* - Copyright (c) 2010-2015 Laurent Montel - - 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 LDAP_H -#define LDAP_H - -#include "setupobject.h" - - -class Ldap : public SetupObject -{ - Q_OBJECT - public: - explicit Ldap( QObject *parent = 0 ); - ~Ldap(); - void create(); - void destroy(); - public slots: - Q_SCRIPTABLE void setUser( const QString & name ); - Q_SCRIPTABLE void setServer( const QString &server ); - Q_SCRIPTABLE void setAuthenticationMethod( const QString &meth ); - Q_SCRIPTABLE void setBindDn( const QString &bindDn ); - Q_SCRIPTABLE void setPassword( const QString &password ); - private: - QString m_user; - QString m_server; - QString m_bindDn; - QString m_authMethod; - QString m_password; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/loadpage.cpp kdepim-runtime-15.08.0/accountwizard/loadpage.cpp --- kdepim-runtime-4.14.6/accountwizard/loadpage.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/loadpage.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "loadpage.h" -#include "global.h" -#include -#include -#include -#include -#include - -LoadPage::LoadPage(KAssistantDialog* parent) : - Page( parent ), - m_action( 0 ) -{ - ui.setupUi( this ); - setValid( false ); -} - -void LoadPage::enterPageNext() -{ - setValid( false ); - // FIXME: deletion seems to delete the exported objects as well, killing the entire wizard... - //delete m_action; - m_action = 0; - emit aboutToStart(); - - const KConfig f( Global::assistant() ); - KConfigGroup grp( &f, "Wizard" ); - const QString scriptFile = grp.readEntry( "Script", QString() ); - if ( scriptFile.isEmpty() ) { - ui.statusLabel->setText( i18n( "No script specified in '%1'.", Global::assistant() ) ); - return; - } - if ( !QFile::exists( Global::assistantBasePath() + scriptFile ) ) { - ui.statusLabel->setText( i18n( "Unable to load assistant: File '%1' does not exist.", Global::assistantBasePath() + scriptFile ) ); - return; - } - ui.statusLabel->setText( i18n( "Loading script '%1'...", Global::assistantBasePath() + scriptFile ) ); - - m_action = new Kross::Action( this, QLatin1String("AccountWizard") ); - typedef QPair ObjectStringPair; - foreach ( const ObjectStringPair &exportedObject, m_exportedObjects ) - m_action->addQObject( exportedObject.first, exportedObject.second ); - - if ( !m_action->setFile( Global::assistantBasePath() + scriptFile ) ) { - ui.statusLabel->setText( i18n( "Failed to load script: '%1'.", m_action->errorMessage() ) ); - return; - } - - KConfigGroup grpTranslate( &f, "Translate" ); - const QString poFileName = grpTranslate.readEntry( "Filename" ); - if ( !poFileName.isEmpty() ) - KGlobal::locale()->insertCatalog( poFileName ); - - m_action->trigger(); - - m_parent->next(); -} - -void LoadPage::enterPageBack() -{ - // TODO: if we are the first page, call enterPageNext(), hm, can we get here then at all? - m_parent->back(); -} - -void LoadPage::exportObject(QObject* object, const QString& name) -{ - m_exportedObjects.push_back( qMakePair( object, name ) ); -} - - diff -Nru kdepim-runtime-4.14.6/accountwizard/loadpage.h kdepim-runtime-15.08.0/accountwizard/loadpage.h --- kdepim-runtime-4.14.6/accountwizard/loadpage.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/loadpage.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 LOADPAGE_H -#define LOADPAGE_H - -#include "page.h" - -#include "ui_loadpage.h" - -namespace Kross { -class Action; -} - -class LoadPage : public Page -{ - Q_OBJECT - public: - explicit LoadPage( KAssistantDialog *parent ); - - virtual void enterPageNext(); - virtual void enterPageBack(); - - void exportObject( QObject *object, const QString &name ); - - Q_SIGNALS: - void aboutToStart(); - - private: - Ui::LoadPage ui; - QVector< QPair< QObject*, QString > > m_exportedObjects; - Kross::Action* m_action; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/main.cpp kdepim-runtime-15.08.0/accountwizard/main.cpp --- kdepim-runtime-4.14.6/accountwizard/main.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "dialog.h" -#include "global.h" - -#include - -#include -#include -#include -#include -#include - - -#include - -int main( int argc, char **argv ) -{ - KAboutData aboutData( "accountwizard", 0, - ki18n( "Account Assistant" ), - "0.1", - ki18n( "Helps setting up PIM accounts" ), - KAboutData::License_LGPL, - ki18n( "(c) 2009 the Akonadi developers" ), - KLocalizedString(), - "http://pim.kde.org/akonadi/" ); - aboutData.setProgramIconName( QLatin1String("akonadi") ); - aboutData.addAuthor( ki18n( "Volker Krause" ), ki18n( "Author" ), "vkrause@kde.org" ); - aboutData.addAuthor( ki18n( "Laurent Montel" ), KLocalizedString() , "montel@kde.org" ); - - KCmdLineArgs::init( argc, argv, &aboutData ); - - KCmdLineOptions options; - options.add( "type ", ki18n( "Only offer accounts that support the given type." ) ); - options.add( "assistant ", ki18n( "Run the specified assistant." ) ); - options.add( "package ", ki18n( "unpack fullpath on startup and launch that assistant" ) ); - KCmdLineArgs::addCmdLineOptions( options ); - KUniqueApplication::addCmdLineOptions(); - - if ( !KUniqueApplication::start() ) { - fprintf( stderr, "accountwizard is already running!\n" ); - exit( 0 ); - } - - KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - - KUniqueApplication app; - KGlobal::locale()->insertCatalog( QLatin1String("libakonadi") ); - - Akonadi::Control::start( 0 ); - - if ( !args->getOption( "package" ).isEmpty() ) { - Global::setAssistant( Global::unpackAssistant( KUrl( args->getOption( "package" ) ) ) ); - } else - Global::setAssistant( args->getOption( "assistant" ) ); - - if ( !args->getOption( "type" ).isEmpty() ) - Global::setTypeFilter( args->getOption( "type" ).split( QLatin1Char(',') ) ); - args->clear(); - Dialog dlg( 0/*, Qt::WindowStaysOnTopHint*/ ); - dlg.show(); - - return app.exec(); -} diff -Nru kdepim-runtime-4.14.6/accountwizard/Messages.sh kdepim-runtime-15.08.0/accountwizard/Messages.sh --- kdepim-runtime-4.14.6/accountwizard/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -#!/bin/sh -$EXTRACTRC ui/*.ui >> rc.cpp -$XGETTEXT *.cpp ispdb/*.cpp -o $podir/accountwizard.pot diff -Nru kdepim-runtime-4.14.6/accountwizard/page.cpp kdepim-runtime-15.08.0/accountwizard/page.cpp --- kdepim-runtime-4.14.6/accountwizard/page.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/page.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "page.h" -#include -#include - -Page::Page(KAssistantDialog* parent): - QWidget(parent), - m_item( 0 ), - m_parent( parent ), - m_valid( false ) -{ -} - - -void Page::setPageWidgetItem(KPageWidgetItem* item) -{ - m_item = item; - m_parent->setValid( m_item, m_valid ); -} - - -void Page::setValid(bool valid) -{ - if ( !m_item ) - m_valid = valid; - else - m_parent->setValid( m_item, valid ); -} - -void Page::nextPage() -{ - m_parent->next(); -} - -void Page::enterPageBack() {} -void Page::enterPageNext() {} -void Page::leavePageBack() {} -void Page::leavePageNext() {} - -void Page::leavePageBackRequested() { emit leavePageBackOk(); } -void Page::leavePageNextRequested() { emit leavePageNextOk(); } - diff -Nru kdepim-runtime-4.14.6/accountwizard/page.h kdepim-runtime-15.08.0/accountwizard/page.h --- kdepim-runtime-4.14.6/accountwizard/page.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/page.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 PAGE_H -#define PAGE_H - -#include - -class KAssistantDialog; -class KPageWidgetItem; - -class Page : public QWidget -{ - Q_OBJECT - public: - explicit Page( KAssistantDialog *parent ); - - void setPageWidgetItem( KPageWidgetItem *item ); - - virtual void enterPageNext(); - virtual void enterPageBack(); - virtual void leavePageNext(); - virtual void leavePageBack(); - virtual void leavePageNextRequested(); - virtual void leavePageBackRequested(); - - signals: - Q_SCRIPTABLE void pageEnteredNext(); - Q_SCRIPTABLE void pageEnteredBack(); - Q_SCRIPTABLE void pageLeftNext(); - Q_SCRIPTABLE void pageLeftBack(); - Q_SCRIPTABLE void leavePageNextOk(); - Q_SCRIPTABLE void leavePageBackOk(); - - public slots: - Q_SCRIPTABLE void setValid( bool valid ); - Q_SCRIPTABLE void nextPage(); - - protected: - KPageWidgetItem *m_item; - KAssistantDialog *m_parent; - - private: - friend class Dialog; - bool m_valid; -}; - -#endif // PAGE_H diff -Nru kdepim-runtime-4.14.6/accountwizard/personaldatapage.cpp kdepim-runtime-15.08.0/accountwizard/personaldatapage.cpp --- kdepim-runtime-4.14.6/accountwizard/personaldatapage.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/personaldatapage.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,278 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - Copyright (c) 2010 Tom Albers - Copyright (c) 2012 Laurent Montel - - 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 "personaldatapage.h" - -#include "config-enterprise.h" -#include "global.h" -#include "dialog.h" -#include "transport.h" -#include "resource.h" -#include "ispdb/ispdb.h" - -#include -#include - -#include - -#include - - -QString accountName(Ispdb *ispdb, QString username) -{ - const int pos(username.indexOf(QLatin1Char('@'))); - username = username.left(pos); - return ispdb->name( Ispdb::Long ) + QString::fromLatin1(" (%1)").arg(username); -} - -PersonalDataPage::PersonalDataPage(Dialog* parent) : - Page( parent ), mIspdb( 0 ), mSetupManager( parent->setupManager() ) -{ - QWidget *pageParent = this; - - ui.setupUi( pageParent ); - - KPIMUtils::EmailValidator* emailValidator = new KPIMUtils::EmailValidator( this ); - ui.emailEdit->setValidator( emailValidator ); - - // KEmailSettings defaults - ui.nameEdit->setText( mSetupManager->name() ); - ui.emailEdit->setText( mSetupManager->email() ); - slotTextChanged(); - connect( ui.emailEdit, SIGNAL(textChanged(QString)), SLOT(slotTextChanged()) ); - connect( ui.nameEdit, SIGNAL(textChanged(QString)), SLOT(slotTextChanged()) ); - connect( ui.createAccountPb, SIGNAL(clicked()), SLOT(slotCreateAccountClicked()) ); - connect( ui.buttonGroup, SIGNAL(buttonClicked(QAbstractButton*)), SLOT(slotRadioButtonClicked(QAbstractButton*)) ); -#ifdef KDEPIM_ENTERPRISE_BUILD - ui.checkOnlineGroupBox->setChecked( false ); -#endif -} - -void PersonalDataPage::setHideOptionInternetSearch( bool hide ) -{ - ui.checkOnlineGroupBox->setChecked( !hide ); - ui.checkOnlineGroupBox->setVisible( !hide ); -} - -void PersonalDataPage::slotRadioButtonClicked( QAbstractButton* button) -{ - QString smptHostname; - if ( !mIspdb->smtpServers().isEmpty() ) { - server s = mIspdb->smtpServers().first(); - smptHostname = s.hostname; - } - ui.outgoingLabel->setText( i18n( "SMTP, %1", smptHostname ) ); - if ( button == ui.imapAccount ) { - server simap = mIspdb->imapServers().first(); // should be ok. - ui.incommingLabel->setText( i18n( "IMAP, %1", simap.hostname ) ); - ui.usernameLabel->setText( simap.username ); - } else if ( button == ui.pop3Account ) { - server spop3 = mIspdb->pop3Servers().first(); // should be ok. - ui.incommingLabel->setText( i18n( "POP3, %1", spop3.hostname ) ); - ui.usernameLabel->setText( spop3.username ); - } -} - -void PersonalDataPage::slotCreateAccountClicked() -{ - configureSmtpAccount(); - if ( ui.imapAccount->isChecked() ) - configureImapAccount(); - else - configurePop3Account(); - emit leavePageNextOk(); // go to the next page - mSetupManager->execute(); -} - -void PersonalDataPage::slotTextChanged() -{ - // Ignore the password field, as that can be empty when auth is based on ip-address. - setValid( !ui.emailEdit->text().isEmpty() && - !ui.nameEdit->text().isEmpty() && - KPIMUtils::isValidSimpleAddress( ui.emailEdit->text() ) ); -} - -void PersonalDataPage::leavePageNext() -{ - ui.stackedPage->setCurrentIndex( 0 ); - ui.imapAccount->setChecked( true ); - mSetupManager->setPersonalDataAvailable( true ); - mSetupManager->setName( ui.nameEdit->text() ); - mSetupManager->setPassword( ui.passwordEdit->text() ); - mSetupManager->setEmail( ui.emailEdit->text().trimmed() ); - - if ( ui.checkOnlineGroupBox->isChecked() ) { - // since the user can go back and forth, explicitly disable the man page - emit manualWanted( false ); - setCursor( Qt::BusyCursor ); - ui.mProgress->start(); - kDebug() << "Searching on internet"; - delete mIspdb; - mIspdb = new Ispdb( this ); - connect(mIspdb, SIGNAL(searchType(QString)), this, SLOT(slotSearchType(QString))); - mIspdb->setEmail( ui.emailEdit->text() ); - mIspdb->start(); - - connect( mIspdb, SIGNAL(finished(bool)), - SLOT(ispdbSearchFinished(bool)) ); - } else { - emit manualWanted( true ); // enable the manual page - emit leavePageNextOk(); // go to the next page - } -} - -void PersonalDataPage::ispdbSearchFinished( bool ok ) -{ - kDebug() << ok; - - unsetCursor(); - ui.mProgress->stop(); - if ( ok ) { - - if ( !mIspdb->imapServers().isEmpty() && !mIspdb->pop3Servers().isEmpty() ) - { - ui.stackedPage->setCurrentIndex( 1 ); - slotRadioButtonClicked( ui.imapAccount ); - } - else - automaticConfigureAccount(); - - } else { - emit manualWanted( true ); // enable the manual page - emit leavePageNextOk(); - } -} - -void PersonalDataPage::slotSearchType(const QString &type) -{ - ui.mProgress->setActiveLabel(type); -} - -void PersonalDataPage::configureSmtpAccount() -{ - if ( !mIspdb->smtpServers().isEmpty() ) { - server s = mIspdb->smtpServers().first(); // should be ok. - kDebug() << "Configuring transport for" << s.hostname; - - QObject* object = mSetupManager->createTransport( QLatin1String("smtp") ); - Transport* t = qobject_cast( object ); - t->setName( accountName(mIspdb,s.username) ); - t->setHost( s.hostname ); - t->setPort( s.port ); - t->setUsername( s.username ); - t->setPassword( ui.passwordEdit->text() ); - switch ( s.authentication ) { - case Ispdb::Plain: t->setAuthenticationType( QLatin1String("plain") ); break; - case Ispdb::CramMD5: t->setAuthenticationType( QLatin1String("cram-md5") ); break; - case Ispdb::NTLM: t->setAuthenticationType( QLatin1String("ntlm") ); break; - case Ispdb::GSSAPI: t->setAuthenticationType( QLatin1String("gssapi") ); break; - case Ispdb::ClientIP: break; - case Ispdb::NoAuth: break; - default: break; - } - switch ( s.socketType ) { - case Ispdb::Plain: t->setEncryption( QLatin1String("none") );break; - case Ispdb::SSL: t->setEncryption( QLatin1String("ssl") );break; - case Ispdb::StartTLS: t->setEncryption( QLatin1String("tls") );break; - default: break; - } - } else - kDebug() << "No transport to be created...."; -} - -void PersonalDataPage::configureImapAccount() -{ - if ( !mIspdb->imapServers().isEmpty() ) { - server s = mIspdb->imapServers().first(); // should be ok. - kDebug() << "Configuring imap for" << s.hostname; - - QObject* object = mSetupManager->createResource( QLatin1String("akonadi_imap_resource") ); - Resource* t = qobject_cast( object ); - t->setName( accountName(mIspdb,s.username) ); - t->setOption( QLatin1String("ImapServer"), s.hostname ); - t->setOption( QLatin1String("ImapPort"), s.port ); - t->setOption( QLatin1String("UserName"), s.username ); - t->setOption( QLatin1String("Password"), ui.passwordEdit->text() ); - switch ( s.authentication ) { - case Ispdb::Plain: t->setOption( QLatin1String("Authentication"), MailTransport::Transport::EnumAuthenticationType::CLEAR ); break; - case Ispdb::CramMD5: t->setOption( QLatin1String("Authentication"), MailTransport::Transport::EnumAuthenticationType::CRAM_MD5 ); break; - case Ispdb::NTLM: t->setOption( QLatin1String("Authentication"), MailTransport::Transport::EnumAuthenticationType::NTLM ); break; - case Ispdb::GSSAPI: t->setOption( QLatin1String("Authentication"), MailTransport::Transport::EnumAuthenticationType::GSSAPI ); break; - case Ispdb::ClientIP: break; - case Ispdb::NoAuth: break; - default: break; - } - switch ( s.socketType ) { - case Ispdb::None: t->setOption( QLatin1String("Safety"), QLatin1String("None") );break; - case Ispdb::SSL: t->setOption( QLatin1String("Safety"), QLatin1String("SSL") );break; - case Ispdb::StartTLS: t->setOption( QLatin1String("Safety"), QLatin1String("STARTTLS") );break; - default: break; - } - } -} - -void PersonalDataPage::configurePop3Account() -{ - if ( !mIspdb->pop3Servers().isEmpty() ) { - server s = mIspdb->pop3Servers().first(); // should be ok. - kDebug() << "No Imap to be created, configuring pop3 for" << s.hostname; - - QObject* object = mSetupManager->createResource( QLatin1String("akonadi_pop3_resource") ); - Resource* t = qobject_cast( object ); - t->setName( accountName(mIspdb,s.username) ); - t->setOption( QLatin1String("Host"), s.hostname ); - t->setOption( QLatin1String("Port"), s.port ); - t->setOption( QLatin1String("Login"), s.username ); - t->setOption( QLatin1String("Password"), ui.passwordEdit->text() ); - switch ( s.authentication ) { - case Ispdb::Plain: t->setOption( QLatin1String("AuthenticationMethod"), MailTransport::Transport::EnumAuthenticationType::PLAIN ); break; - case Ispdb::CramMD5: t->setOption( QLatin1String("AuthenticationMethod"), MailTransport::Transport::EnumAuthenticationType::CRAM_MD5 ); break; - case Ispdb::NTLM: t->setOption( QLatin1String("AuthenticationMethod"), MailTransport::Transport::EnumAuthenticationType::NTLM ); break; - case Ispdb::GSSAPI: t->setOption( QLatin1String("AuthenticationMethod"), MailTransport::Transport::EnumAuthenticationType::GSSAPI ); break; - case Ispdb::ClientIP: - case Ispdb::NoAuth: - default: t->setOption( QLatin1String("AuthenticationMethod"), MailTransport::Transport::EnumAuthenticationType::CLEAR ); break; - } - switch ( s.socketType ) { - case Ispdb::SSL: t->setOption( QLatin1String("UseSSL"), 1 );break; - case Ispdb::StartTLS: t->setOption( QLatin1String("UseTLS"), 1 );break; - case Ispdb::None: - default: t->setOption( QLatin1String("UseTLS"), 1 ); break; - } - } -} - -void PersonalDataPage::automaticConfigureAccount() -{ - configureSmtpAccount(); - configureImapAccount(); - configurePop3Account(); - emit leavePageNextOk(); // go to the next page - mSetupManager->execute(); -} - -void PersonalDataPage::leavePageNextRequested() -{ - // override base class with doing nothing... -} - - - diff -Nru kdepim-runtime-4.14.6/accountwizard/personaldatapage.h kdepim-runtime-15.08.0/accountwizard/personaldatapage.h --- kdepim-runtime-4.14.6/accountwizard/personaldatapage.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/personaldatapage.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - Copyright (c) 2010 Tom Albers - Copyright (c) 2012 Laurent Montel - - 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 PERSONALDATA_H -#define PERSONALDATA_H - -#include "page.h" -#include "setupmanager.h" -#include "dialog.h" - -#include "ui_personaldatapage.h" - -class Ispdb; - -class PersonalDataPage : public Page -{ - Q_OBJECT - public: - explicit PersonalDataPage( Dialog* parent = 0 ); - void setHideOptionInternetSearch( bool ); - - virtual void leavePageNext(); - virtual void leavePageNextRequested(); - - private slots: - void ispdbSearchFinished( bool ok ); - void slotTextChanged(); - void slotCreateAccountClicked(); - void slotRadioButtonClicked( QAbstractButton* button); - void slotSearchType(const QString&); - - signals: - void manualWanted( bool ); - - private: - void automaticConfigureAccount(); - void configureSmtpAccount(); - void configureImapAccount(); - void configurePop3Account(); - - Ui::PersonalDataPage ui; - Ispdb* mIspdb; - SetupManager *mSetupManager; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/providerpage.cpp kdepim-runtime-15.08.0/accountwizard/providerpage.cpp --- kdepim-runtime-4.14.6/accountwizard/providerpage.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/providerpage.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,176 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - Copyright (c) 2010 Tom Albers - - 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 "providerpage.h" -#include "global.h" - -#include -#include -#include - -ProviderPage::ProviderPage(KAssistantDialog* parent) : - Page( parent ), - m_model( new QStandardItemModel( this ) ), - m_downloadManager( new KNS3::DownloadManager( this ) ), - m_newPageWanted( false ), - m_newPageReady( false ) -{ - ui.setupUi( this ); - - QSortFilterProxyModel *proxy = new QSortFilterProxyModel( this ); - proxy->setSourceModel( m_model ); - ui.listView->setModel( proxy ); - ui.searchLine->setProxy( proxy ); - - m_fetchItem = new QStandardItem( i18n( "Fetching provider list..." ) ); - m_fetchItem->setFlags(Qt::NoItemFlags); - m_model->appendRow( m_fetchItem ); - - // we can start the search, whenever the user reaches this page, chances - // are we have the full list. - connect( m_downloadManager, SIGNAL(searchResult(KNS3::Entry::List)), - SLOT(fillModel(KNS3::Entry::List)) ); - connect( m_downloadManager, SIGNAL(entryStatusChanged(KNS3::Entry)), - SLOT(providerStatusChanged(KNS3::Entry)) ); - m_downloadManager->setSearchOrder( KNS3::DownloadManager::Alphabetical ); - - connect( ui.listView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(selectionChanged()) ); - - kDebug(); -} - -void ProviderPage::startFetchingData() -{ - m_downloadManager->search( 0, 100000 ); -} - -void ProviderPage::fillModel( const KNS3::Entry::List& list ) -{ - kDebug(); - m_model->removeRows( m_model->indexFromItem( m_fetchItem ).row(), 1 ); - - // KNS3::Entry::Entry() is private, so we need to save the whole list. - // we can not use a QHash or whatever, as that needs that constructor... - m_providerEntries = list; - - foreach ( const KNS3::Entry& e, list ) { - kDebug() << "Found Entry: " << e.name(); - - QStandardItem *item = new QStandardItem( e.name() ); - item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); - item->setData( e.name(), Qt::ToolTipRole ); - item->setData( e.id(), Qt::UserRole ); - item->setData( e.providerId(), Qt::UserRole+ 1 ); - m_model->appendRow( item ); - } -} - -void ProviderPage::selectionChanged() -{ - if ( ui.listView->selectionModel()->hasSelection() ) { - setValid( true ); - } else { - setValid( false ); - } -} - -void ProviderPage::leavePageNext() -{ - m_newPageReady = false; - if ( !ui.listView->selectionModel()->hasSelection() ) - return; - const QModelIndex index = ui.listView->selectionModel()->selectedIndexes().first(); - if ( !index.isValid() ) - return; - - const QSortFilterProxyModel *proxy = static_cast( ui.listView->model() ); - const QStandardItem* item = m_model->itemFromIndex( proxy->mapToSource( index ) ); - kDebug() << "Item selected:"<< item->text(); - - // download and execute it... - foreach ( const KNS3::Entry& e, m_providerEntries ) { - if ( e.id() == item->data( Qt::UserRole ) && - e.providerId() == item->data( Qt::UserRole+ 1 ) ) { - - m_wantedProvider.entryId = e.id(); - m_wantedProvider.entryProviderId = e.providerId(); - - if ( e.status() == KNS3::Entry::Installed ) { - kDebug() << "already installed" << e.installedFiles(); - findDesktopAndSetAssistant( e.installedFiles() ); - } else { - kDebug() << "Starting download for " << e.name(); - m_downloadManager->installEntry( e ); - } - - break; - } - } -} - -void ProviderPage::providerStatusChanged( const KNS3::Entry& e ) -{ - kDebug() << e.name(); - if ( e.id() == m_wantedProvider.entryId && - e.providerId() == m_wantedProvider.entryProviderId && - e.status() == KNS3::Entry::Installed ) { - findDesktopAndSetAssistant( e.installedFiles() ); - } -} - -void ProviderPage::findDesktopAndSetAssistant( const QStringList& list ) -{ - foreach ( const QString& file, list ) { - kDebug() << file; - if ( file.endsWith( QLatin1String ( ".desktop" ) ) ) { - kDebug() << "Yay, a desktop file!" << file; - Global::setAssistant( file ); - m_newPageReady = true; - if ( m_newPageWanted ) { - kDebug() << "New page was already requested, now we are done, approve it"; - emit leavePageNextOk(); - } - break; - } - } -} - -QTreeView *ProviderPage::treeview() const -{ - return ui.listView; -} - -void ProviderPage::leavePageBackRequested() -{ - emit leavePageBackOk(); - emit ghnsNotWanted(); -} - -void ProviderPage::leavePageNextRequested() -{ - m_newPageWanted = true; - if ( m_newPageReady ) { - kDebug() << "New page requested and we are done, so ok..."; - emit leavePageNextOk(); - } else { - kDebug() << "New page requested, but we are not done yet..."; - } -} - diff -Nru kdepim-runtime-4.14.6/accountwizard/providerpage.h kdepim-runtime-15.08.0/accountwizard/providerpage.h --- kdepim-runtime-4.14.6/accountwizard/providerpage.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/providerpage.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - Copyright (c) 2010 Tom Albers - - 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 PROVIDERPAGE_H -#define PROVIDERPAGE_H - -#include "page.h" -#include - -#include "ui_providerpage.h" -#include - -struct Provider { - QString entryId; - QString entryProviderId; -}; - -namespace KNS3 { - class DownloadManager; -} - -class ProviderPage : public Page -{ - Q_OBJECT - public: - explicit ProviderPage( KAssistantDialog* parent = 0 ); - - virtual void leavePageNext(); - virtual void leavePageNextRequested(); - virtual void leavePageBackRequested(); - - QTreeView *treeview() const; - - signals: - void ghnsNotWanted(); - - public slots: - void startFetchingData(); - - private slots: - void fillModel( const KNS3::Entry::List& ); - void selectionChanged(); - void providerStatusChanged( const KNS3::Entry& ); - - private: - void findDesktopAndSetAssistant( const QStringList& list ); - - Ui::ProviderPage ui; - QStandardItemModel *m_model; - QStandardItem *m_fetchItem; - KNS3::DownloadManager *m_downloadManager; - KNS3::Entry::List m_providerEntries; - Provider m_wantedProvider; - bool m_newPageWanted; - bool m_newPageReady; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/resource.cpp kdepim-runtime-15.08.0/accountwizard/resource.cpp --- kdepim-runtime-4.14.6/accountwizard/resource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/resource.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,165 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "resource.h" - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -using namespace Akonadi; - -static QVariant::Type argumentType( const QMetaObject *mo, const QString &method ) -{ - QMetaMethod m; - for ( int i = 0; i < mo->methodCount(); ++i ) { - const QString signature = QString::fromLatin1( mo->method( i ).signature() ); - if ( signature.contains( method + QLatin1Char( '(' ) ) ) { - m = mo->method( i ); - break; - } - } - - if ( !m.signature() ) { - kWarning() << "Did not find D-Bus method: " << method << " available methods are:"; - for ( int i = 0; i < mo->methodCount(); ++i ) - kWarning() << mo->method( i ).signature(); - return QVariant::Invalid; - } - - const QList argTypes = m.parameterTypes(); - if ( argTypes.count() != 1 ) - return QVariant::Invalid; - - return QVariant::nameToType( argTypes.first() ); -} - -Resource::Resource(const QString& type, QObject* parent) : - SetupObject( parent ), - m_typeIdentifier( type ) -{ -} - -void Resource::setOption( const QString &key, const QVariant &value ) -{ - m_settings.insert( key, value ); -} - -void Resource::setName( const QString &name ) -{ - m_name = name; -} - -void Resource::create() -{ - const AgentType type = AgentManager::self()->type( m_typeIdentifier ); - if ( !type.isValid() ) { - emit error( i18n( "Resource type '%1' is not available.", m_typeIdentifier ) ); - return; - } - - // check if unique instance already exists - kDebug() << type.capabilities(); - if ( type.capabilities().contains( QLatin1String( "Unique" ) ) ) { - foreach ( const AgentInstance &instance, AgentManager::self()->instances() ) { - kDebug() << instance.type().identifier() << ( instance.type() == type ); - if ( instance.type() == type ) { - emit finished( i18n( "Resource '%1' is already set up.", type.name() ) ); - return; - } - } - } - - emit info( i18n( "Creating resource instance for '%1'...", type.name() ) ); - AgentInstanceCreateJob *job = new AgentInstanceCreateJob( type, this ); - connect( job, SIGNAL(result(KJob*)), SLOT(instanceCreateResult(KJob*)) ); - job->start(); -} - - -void Resource::instanceCreateResult(KJob* job) -{ - if ( job->error() ) { - emit error( i18n( "Failed to create resource instance: %1", job->errorText() ) ); - return; - } - - m_instance = qobject_cast( job )->instance(); - - if ( !m_settings.isEmpty() ) { - emit info( i18n( "Configuring resource instance..." ) ); - QDBusInterface iface( QLatin1String("org.freedesktop.Akonadi.Resource.") + m_instance.identifier(), QLatin1String("/Settings") ); - if ( !iface.isValid() ) { - emit error( i18n( "Unable to configure resource instance." ) ); - return; - } - - // configure resource - if ( !m_name.isEmpty() ) - m_instance.setName( m_name ); - QMap::const_iterator end( m_settings.constEnd() ); - for ( QMap::const_iterator it = m_settings.constBegin(); it != end; ++it ) { - kDebug() << "Setting up " << it.key() << " for agent " << m_instance.identifier(); - const QString methodName = QString::fromLatin1( "set%1" ).arg( it.key() ); - QVariant arg = it.value(); - const QVariant::Type targetType = argumentType( iface.metaObject(), methodName ); - if ( !arg.canConvert( targetType ) ) { - emit error( i18n( "Could not convert value of setting '%1' to required type %2.", it.key(), QLatin1String(QVariant::typeToName( targetType )) ) ); - return; - } - arg.convert( targetType ); - QDBusReply reply = iface.call( methodName, arg ); - if ( !reply.isValid() ) { - emit error( i18n( "Could not set setting '%1': %2", it.key(), reply.error().message() ) ); - return; - } - } - m_instance.reconfigure(); - } - - emit finished( i18n( "Resource setup completed." ) ); -} - -void Resource::destroy() -{ - if ( m_instance.isValid() ) { - AgentManager::self()->removeInstance( m_instance ); - emit info( i18n( "Removed resource instance for '%1'.", m_instance.type().name() ) ); - } -} - -QString Resource::identifier() -{ - return m_instance.identifier(); -} - -void Resource::reconfigure() -{ - m_instance.reconfigure(); -} - - diff -Nru kdepim-runtime-4.14.6/accountwizard/resource.h kdepim-runtime-15.08.0/accountwizard/resource.h --- kdepim-runtime-4.14.6/accountwizard/resource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/resource.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 RESOURCE_H -#define RESOURCE_H - -#include "setupobject.h" -#include -#include - -class KJob; - -class Resource : public SetupObject -{ - Q_OBJECT - public: - explicit Resource( const QString &type, QObject *parent = 0 ); - void create(); - void destroy(); - - public slots: - Q_SCRIPTABLE void setName( const QString &name ); - Q_SCRIPTABLE void setOption( const QString &key, const QVariant &value ); - Q_SCRIPTABLE QString identifier(); - Q_SCRIPTABLE void reconfigure(); - - private slots: - void instanceCreateResult( KJob* job ); - - private: - QString m_typeIdentifier, m_name; - QMap m_settings; - Akonadi::AgentInstance m_instance; -}; -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/servertest.cpp kdepim-runtime-15.08.0/accountwizard/servertest.cpp --- kdepim-runtime-4.14.6/accountwizard/servertest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/servertest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -/* - Copyright (c) 2010 Tom Albers - - 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 "servertest.h" -#include -#include - -#include -#include -#include - -ServerTest::ServerTest( QObject* parent) : - QObject(parent), m_serverTest( new MailTransport::ServerTest( 0 ) ) -{ - kDebug() << "Welcome!"; - connect( m_serverTest, SIGNAL(finished(QList)), - SLOT(testFinished(QList)) ); -} - -ServerTest::~ServerTest() -{ - delete m_serverTest; -} - -void ServerTest::test( const QString server, const QString protocol ) -{ - kDebug() << server << protocol; - m_serverTest->setServer( server ); - m_serverTest->setProtocol( protocol ); - m_serverTest->start(); -} - -void ServerTest::testFinished( QList< int > list ) -{ - kDebug() << "types: " << list; - if ( list.contains( MailTransport::Transport::EnumEncryption::TLS ) ) { - emit testResult( QLatin1String("tls") ); - } else if ( list.contains( MailTransport::Transport::EnumEncryption::SSL ) ) { - emit testResult( QLatin1String("ssl") ); - } else { - KMessageBox::information( 0, i18n( "There seems to be a problem in reaching this server " - "or choosing a safe way to sent the credentials to server. We advise you to " - "check the settings of the account and adjust it manually if needed." ), - i18n( "Autodetecting settings failed" ) ); - emit testFail(); - } -} - diff -Nru kdepim-runtime-4.14.6/accountwizard/servertest.h kdepim-runtime-15.08.0/accountwizard/servertest.h --- kdepim-runtime-4.14.6/accountwizard/servertest.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/servertest.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - Copyright (c) 2010 Tom Albers - - 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 SERVERTEST_H -#define SERVERTEST_H - -#include - -namespace MailTransport { - class ServerTest; -} - -class ServerTest : public QObject -{ - Q_OBJECT - public: - explicit ServerTest( QObject *parent ); - ~ServerTest(); - - public slots: - /* @p protocol being 'imap' 'smtp' or 'pop3' */ - Q_SCRIPTABLE void test( const QString server, const QString protocol ); - - signals: - /* returns the advised setting, @p result begin 'ssl' 'tls' or 'none'. */ - void testResult( const QString& result ); - - /* returns if no connection is possible, test failed. */ - void testFail(); - - private slots: - void testFinished( QList< int > list ); - - private: - MailTransport::ServerTest* m_serverTest; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/setupmanager.cpp kdepim-runtime-15.08.0/accountwizard/setupmanager.cpp --- kdepim-runtime-4.14.6/accountwizard/setupmanager.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/setupmanager.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,245 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "setupmanager.h" -#include "resource.h" -#include "setuppage.h" -#include "transport.h" -#include "configfile.h" -#include "ldap.h" -#include "identity.h" - -#include -#include - -SetupManager::SetupManager( QWidget* parent) : - QObject(parent), - m_currentSetupObject( 0 ), - m_page( 0 ), - m_wallet( 0 ), - m_personalDataAvailable( false ), - m_rollbackRequested( false ) -{ - KEMailSettings e; - m_name = e.getSetting( KEMailSettings::RealName ); - m_email = e.getSetting( KEMailSettings::EmailAddress ); -} - -SetupManager::~SetupManager() -{ - delete m_wallet; -} - -void SetupManager::setSetupPage(SetupPage* page) -{ - m_page = page; -} - -QObject* SetupManager::createResource(const QString& type) -{ - return connectObject( new Resource( type, this ) ); -} - -QObject* SetupManager::createTransport(const QString& type) -{ - return connectObject( new Transport( type, this ) ); -} - -QObject* SetupManager::createConfigFile(const QString& fileName) -{ - return connectObject( new ConfigFile( fileName, this ) ); -} - -QObject* SetupManager::createLdap() -{ - return connectObject( new Ldap( this ) ); -} - - -QObject* SetupManager::createIdentity() -{ - return connectObject( new Identity( this ) ); -} - -static bool dependencyCompare( SetupObject *left, SetupObject *right ) -{ - if ( !left->dependsOn() && right->dependsOn() ) - return true; - return false; -} - -void SetupManager::execute() -{ - m_page->setStatus( i18n( "Setting up account..." ) ); - m_page->setValid( false ); - - // ### FIXME this is a bad over-simplification and would need a real topological sort - // but for current usage it is good enough - qStableSort( m_objectToSetup.begin(), m_objectToSetup.end(), dependencyCompare ); - setupNext(); -} - -void SetupManager::setupSucceeded(const QString& msg) -{ - Q_ASSERT( m_page ); - m_page->addMessage( SetupPage::Success, msg ); - if(m_currentSetupObject) { - m_setupObjects.append( m_currentSetupObject ); - m_currentSetupObject = 0; - } - setupNext(); -} - -void SetupManager::setupFailed(const QString& msg) -{ - Q_ASSERT( m_page ); - m_page->addMessage( SetupPage::Error, msg ); - if( m_currentSetupObject ) { - m_setupObjects.append( m_currentSetupObject ); - m_currentSetupObject = 0; - } - rollback(); -} - -void SetupManager::setupInfo(const QString& msg) -{ - Q_ASSERT( m_page ); - m_page->addMessage( SetupPage::Info, msg ); -} - -void SetupManager::setupNext() -{ - // user canceld during the previous setup step - if ( m_rollbackRequested ) { - rollback(); - return; - } - - if ( m_objectToSetup.isEmpty() ) { - m_page->setStatus( i18n( "Setup complete." ) ); - m_page->setProgress( 100 ); - m_page->setValid( true ); - } else { - const int setupObjectCount = m_objectToSetup.size() + m_setupObjects.size(); - const int remainingObjectCount = setupObjectCount - m_objectToSetup.size(); - m_page->setProgress( ( remainingObjectCount * 100 ) / setupObjectCount ); - m_currentSetupObject = m_objectToSetup.takeFirst(); - m_currentSetupObject->create(); - } -} - -void SetupManager::rollback() -{ - m_page->setStatus( i18n( "Failed to set up account, rolling back..." ) ); - const int setupObjectCount = m_objectToSetup.size() + m_setupObjects.size(); - int remainingObjectCount = m_setupObjects.size(); - foreach ( SetupObject* obj, m_setupObjects ) { - m_page->setProgress( ( remainingObjectCount * 100 ) / setupObjectCount ); - if( obj ) { - obj->destroy(); - m_objectToSetup.prepend( obj ); - } - } - m_setupObjects.clear(); - m_page->setProgress( 0 ); - m_page->setStatus( i18n( "Failed to set up account." ) ); - m_page->setValid( true ); - m_rollbackRequested = false; - emit rollbackComplete(); -} - -SetupObject* SetupManager::connectObject(SetupObject* obj) -{ - connect( obj, SIGNAL(finished(QString)), SLOT(setupSucceeded(QString)) ); - connect( obj, SIGNAL(info(QString)), SLOT(setupInfo(QString)) ); - connect( obj, SIGNAL(error(QString)), SLOT(setupFailed(QString)) ); - m_objectToSetup.append( obj ); - return obj; -} - -void SetupManager::setName( const QString& name ) -{ - m_name = name; -} - -QString SetupManager::name() -{ - return m_name; -} - -void SetupManager::setEmail( const QString& email) -{ - m_email = email; -} - -QString SetupManager::email() -{ - return m_email; -} - -void SetupManager::setPassword( const QString& password) -{ - m_password = password; -} - -QString SetupManager::password() -{ - return m_password; -} - -QString SetupManager::country() -{ - return KGlobal::locale()->country(); -} - -void SetupManager::openWallet() -{ - using namespace KWallet; - if ( Wallet::isOpen( Wallet::NetworkWallet() ) ) - return; - - Q_ASSERT( parent()->isWidgetType() ); - m_wallet = Wallet::openWallet( Wallet::NetworkWallet(), qobject_cast( parent() )->effectiveWinId(), Wallet::Asynchronous ); - QEventLoop loop; - connect( m_wallet, SIGNAL(walletOpened(bool)), &loop, SLOT(quit()) ); - loop.exec(); -} - -bool SetupManager::personalDataAvailable() -{ - return m_personalDataAvailable; -} - -void SetupManager::setPersonalDataAvailable(bool available) -{ - m_personalDataAvailable = available; -} - -void SetupManager::requestRollback() -{ - if ( m_setupObjects.isEmpty() ) { - emit rollbackComplete(); - } else { - m_rollbackRequested = true; - if ( !m_currentSetupObject ) - rollback(); - } -} - - diff -Nru kdepim-runtime-4.14.6/accountwizard/setupmanager.h kdepim-runtime-15.08.0/accountwizard/setupmanager.h --- kdepim-runtime-4.14.6/accountwizard/setupmanager.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/setupmanager.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 SETUPMANAGER_H -#define SETUPMANAGER_H - -#include - -namespace KWallet { - class Wallet; -} - -class SetupObject; -class SetupPage; - -class SetupManager : public QObject -{ - Q_OBJECT - public: - explicit SetupManager( QWidget *parent ); - ~SetupManager(); - void setSetupPage( SetupPage* page ); - - void setName( const QString& ); - void setEmail( const QString& ); - void setPassword( const QString& ); - void setPersonalDataAvailable( bool available ); - - public slots: - Q_SCRIPTABLE bool personalDataAvailable(); - Q_SCRIPTABLE QString name(); - Q_SCRIPTABLE QString email(); - Q_SCRIPTABLE QString password(); - Q_SCRIPTABLE QString country(); - /** Ensures the wallet is open for subsequent sync wallet access in the resources. */ - Q_SCRIPTABLE void openWallet(); - Q_SCRIPTABLE QObject* createResource( const QString &type ); - Q_SCRIPTABLE QObject* createTransport( const QString &type ); - Q_SCRIPTABLE QObject* createConfigFile( const QString &configName ); - Q_SCRIPTABLE QObject* createLdap(); - Q_SCRIPTABLE QObject* createIdentity(); - Q_SCRIPTABLE void execute(); - - void requestRollback(); - - signals: - void rollbackComplete(); - - private: - void setupNext(); - void rollback(); - SetupObject* connectObject( SetupObject* obj ); - - private slots: - void setupSucceeded( const QString &msg ); - void setupFailed( const QString &msg ); - void setupInfo( const QString &msg ); - - private: - QString m_name, m_email, m_password; - QList m_objectToSetup; - QList m_setupObjects; - SetupObject* m_currentSetupObject; - SetupPage* m_page; - KWallet::Wallet *m_wallet; - bool m_personalDataAvailable; - bool m_rollbackRequested; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/setupobject.cpp kdepim-runtime-15.08.0/accountwizard/setupobject.cpp --- kdepim-runtime-4.14.6/accountwizard/setupobject.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/setupobject.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "setupobject.h" - -SetupObject::SetupObject(QObject* parent): QObject(parent), m_dependsOn( 0 ) -{ -} - -SetupObject* SetupObject::dependsOn() const -{ - return m_dependsOn; -} - -void SetupObject::setDependsOn(SetupObject* obj) -{ - m_dependsOn = obj; -} - diff -Nru kdepim-runtime-4.14.6/accountwizard/setupobject.h kdepim-runtime-15.08.0/accountwizard/setupobject.h --- kdepim-runtime-4.14.6/accountwizard/setupobject.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/setupobject.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 SETUPOBJECT_H -#define SETUPOBJECT_H - -#include - -class SetupObject : public QObject -{ - Q_OBJECT - public: - explicit SetupObject( QObject *parent ); - - virtual void create() = 0; - virtual void destroy() = 0; - - SetupObject* dependsOn() const; - void setDependsOn( SetupObject* obj ); - - signals: - void error( const QString &msg ); - void info( const QString &msg ); - void finished( const QString &msg ); - - private: - SetupObject *m_dependsOn; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/setuppage.cpp kdepim-runtime-15.08.0/accountwizard/setuppage.cpp --- kdepim-runtime-4.14.6/accountwizard/setuppage.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/setuppage.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "setuppage.h" - -#include - -SetupPage::SetupPage(KAssistantDialog* parent) : - Page(parent), - m_msgModel( new QStandardItemModel( this ) ) -{ - ui.setupUi( this ); - ui.detailView->setModel( m_msgModel ); - connect( ui.detailsButton, SIGNAL(clicked()), SLOT(detailsClicked()) ); -} - -void SetupPage::enterPageNext() -{ - ui.stackWidget->setCurrentIndex( 0 ); -} - -void SetupPage::detailsClicked() -{ - ui.stackWidget->setCurrentIndex( 1 ); -} - -void SetupPage::addMessage(SetupPage::MessageType type, const QString& msg) -{ - QStandardItem *item = new QStandardItem; - item->setText( msg ); - item->setEditable( false ); - switch ( type ) { - case Success: - item->setIcon( KIcon( QLatin1String("dialog-ok") ) ); - break; - case Info: - item->setIcon( KIcon( QLatin1String("dialog-information" )) ); - break; - case Error: - item->setIcon( KIcon( QLatin1String("dialog-error") ) ); - break; - } - m_msgModel->appendRow( item ); -} - -void SetupPage::setStatus(const QString& msg) -{ - ui.progressLabel->setText( msg ); -} - -void SetupPage::setProgress(int percent) -{ - ui.progressBar->setValue( percent ); -} - diff -Nru kdepim-runtime-4.14.6/accountwizard/setuppage.h kdepim-runtime-15.08.0/accountwizard/setuppage.h --- kdepim-runtime-4.14.6/accountwizard/setuppage.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/setuppage.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 SETUPPAGE_H -#define SETUPPAGE_H - -#include "page.h" -#include "ui_setuppage.h" - -class QStandardItemModel; - -class SetupPage : public Page -{ - Q_OBJECT - public: - explicit SetupPage( KAssistantDialog *parent ); - virtual void enterPageNext(); - - enum MessageType { - Success, - Info, - Error - }; - void addMessage( MessageType type, const QString &msg ); - void setStatus( const QString &msg ); - void setProgress( int percent ); - - private slots: - void detailsClicked(); - - private: - Ui::SetupPage ui; - QStandardItemModel* m_msgModel; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/TODO kdepim-runtime-15.08.0/accountwizard/TODO --- kdepim-runtime-4.14.6/accountwizard/TODO 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/TODO 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -- figure out i18n for the actual wizards (DONE) -- imap+pop3wizard has no encryption as default i.c.w. plain auth method. Not a good default! -- remember which set up resources/transports/ldap accounts/identities belong together so we can offer to remove them in one go again -- add more wizards (In progress) -- sort out password fields at least for pop3. diff -Nru kdepim-runtime-4.14.6/accountwizard/transport.cpp kdepim-runtime-15.08.0/accountwizard/transport.cpp --- kdepim-runtime-4.14.6/accountwizard/transport.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/transport.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,156 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "transport.h" - -#include - -#include -#include - -#define TABLE_SIZE x - -template -struct StringValueTable { - const char * name; - typename T::type value; - typedef typename T::type value_type; -}; - -static const StringValueTable transportTypeEnums[] = { - { "smtp", MailTransport::Transport::EnumType::SMTP }, - { "sendmail", MailTransport::Transport::EnumType::Sendmail }, - { "akonadi", MailTransport::Transport::EnumType::Akonadi } -}; -static const int transportTypeEnumsSize = sizeof( transportTypeEnums ) / sizeof ( *transportTypeEnums ); - -static const StringValueTable encryptionEnum[] = { - { "none", MailTransport::Transport::EnumEncryption::None }, - { "ssl", MailTransport::Transport::EnumEncryption::SSL }, - { "tls", MailTransport::Transport::EnumEncryption::TLS } -}; -static const int encryptionEnumSize = sizeof( encryptionEnum ) / sizeof( *encryptionEnum ); - -static const StringValueTable authenticationTypeEnum[] = { - { "login", MailTransport::Transport::EnumAuthenticationType::LOGIN }, - { "plain", MailTransport::Transport::EnumAuthenticationType::PLAIN }, - { "cram-md5", MailTransport::Transport::EnumAuthenticationType::CRAM_MD5 }, - { "digest-md5", MailTransport::Transport::EnumAuthenticationType::DIGEST_MD5 }, - { "gssapi", MailTransport::Transport::EnumAuthenticationType::GSSAPI }, - { "ntlm", MailTransport::Transport::EnumAuthenticationType::NTLM }, - { "apop", MailTransport::Transport::EnumAuthenticationType::APOP }, - { "clear", MailTransport::Transport::EnumAuthenticationType::CLEAR }, - { "anonymous", MailTransport::Transport::EnumAuthenticationType::ANONYMOUS } -}; -static const int authenticationTypeEnumSize = sizeof( authenticationTypeEnum ) / sizeof( *authenticationTypeEnum ); - -template -static typename T::value_type stringToValue( const T *table, const int tableSize, const QString &string ) -{ - const QString ref = string.toLower(); - for ( int i = 0; i < tableSize; ++i ) { - if ( ref == QLatin1String( table[i].name ) ) - return table[i].value; - } - return table[0].value; // TODO: error handling -} - -Transport::Transport(const QString& type, QObject* parent) : - SetupObject( parent ), - m_transportId( -1 ), - m_port( -1 ), - m_encr( MailTransport::Transport::EnumEncryption::TLS ), - m_auth( MailTransport::Transport::EnumAuthenticationType::PLAIN ) -{ - m_transportType = stringToValue( transportTypeEnums, transportTypeEnumsSize, type ); - if ( m_transportType == MailTransport::Transport::EnumType::SMTP ) - m_port = 25; -} - -void Transport::create() -{ - emit info( i18n( "Setting up mail transport account..." ) ); - MailTransport::Transport* mt = MailTransport::TransportManager::self()->createTransport(); - mt->setName( m_name ); - mt->setHost( m_host ); - if ( m_port > 0 ) - mt->setPort( m_port ); - if ( !m_user.isEmpty() ) { - mt->setUserName( m_user ); - mt->setRequiresAuthentication( true ); - } - if ( !m_password.isEmpty() ) { - mt->setStorePassword( true ); - mt->setPassword( m_password ); - } - mt->setEncryption( m_encr ); - mt->setAuthenticationType( m_auth ); - m_transportId = mt->id(); - mt->writeConfig(); - MailTransport::TransportManager::self()->addTransport( mt ); - MailTransport::TransportManager::self()->setDefaultTransport( mt->id() ); - emit finished( i18n( "Mail transport account set up." ) ); -} - -void Transport::destroy() -{ - MailTransport::TransportManager::self()->removeTransport( m_transportId ); - emit info( i18n( "Mail transport account deleted." ) ); -} - -void Transport::setName( const QString &name ) -{ - m_name = name; -} - -void Transport::setHost( const QString &host ) -{ - m_host = host; -} - -void Transport::setPort( int port ) -{ - m_port = port; -} - -void Transport::setUsername( const QString &user ) -{ - m_user = user; -} - -void Transport::setPassword( const QString &password ) -{ - m_password = password; -} - -void Transport::setEncryption( const QString &encryption ) -{ - m_encr = stringToValue( encryptionEnum, encryptionEnumSize, encryption ); -} - -void Transport::setAuthenticationType( const QString &authType ) -{ - m_auth = stringToValue( authenticationTypeEnum, authenticationTypeEnumSize, authType ); -} - -int Transport::transportId() const -{ - return m_transportId; -} - diff -Nru kdepim-runtime-4.14.6/accountwizard/transport.h kdepim-runtime-15.08.0/accountwizard/transport.h --- kdepim-runtime-4.14.6/accountwizard/transport.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/transport.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 TRANSPORT_H -#define TRANSPORT_H - -#include "setupobject.h" -#include - - -class Transport : public SetupObject -{ - Q_OBJECT - public: - explicit Transport( const QString &type, QObject *parent = 0 ); - void create(); - void destroy(); - - int transportId() const; - - public slots: - Q_SCRIPTABLE void setName( const QString &name ); - Q_SCRIPTABLE void setHost( const QString &host ); - Q_SCRIPTABLE void setPort( int port ); - Q_SCRIPTABLE void setUsername( const QString &user ); - Q_SCRIPTABLE void setPassword( const QString &password ); - Q_SCRIPTABLE void setEncryption( const QString &encryption ); - Q_SCRIPTABLE void setAuthenticationType( const QString &authType ); - - private: - MailTransport::Transport::EnumEncryption stringToEncryption( const QString &encryptionString ); - MailTransport::Transport::EnumAuthenticationType stringToAuthType( const QString &authString ); - - private: - int m_transportId; - MailTransport::Transport::EnumType::type m_transportType; - QString m_name; - QString m_host; - int m_port; - QString m_user; - QString m_password; - MailTransport::Transport::EnumEncryption::type m_encr; - MailTransport::Transport::EnumAuthenticationType::type m_auth; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/typepage.cpp kdepim-runtime-15.08.0/accountwizard/typepage.cpp --- kdepim-runtime-4.14.6/accountwizard/typepage.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/typepage.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "typepage.h" - -#include -#include -#include - -#include -#include "global.h" -#include - -TypePage::TypePage(KAssistantDialog* parent) : - Page( parent ), - m_model( new QStandardItemModel( this ) ) -{ - ui.setupUi( this ); -#ifdef KDEPIM_MOBILE_UI - ui.label->setHidden( true ); - ui.searchLine->setHidden( true ); -#endif - -#ifdef ACCOUNTWIZARD_NO_GHNS - ui.ghnsButton->hide(); -#endif - - QSortFilterProxyModel *proxy = new QSortFilterProxyModel( this ); - proxy->setSourceModel( m_model ); - ui.listView->setModel( proxy ); - ui.searchLine->setProxy( proxy ); - - const QStringList list = KGlobal::dirs()->findAllResources( "data", QLatin1String( "akonadi/accountwizard/*.desktop" ), - KStandardDirs::Recursive | KStandardDirs::NoDuplicates ); - const QStringList filter = Global::typeFilter(); - foreach ( const QString &entry, list ) { - KDesktopFile f( entry ); - kDebug() << entry << f.readName(); - const KConfig configWizard( entry ); - KConfigGroup grp( &configWizard, "Wizard" ); - const QStringList lstType = grp.readEntry( "Type", QStringList() ); - if ( lstType.isEmpty() ) { - kDebug() << QString::fromLatin1( " %1 doesn't contains specific type" ).arg( f.readName() ); - } - if ( !filter.isEmpty() ) { - // stolen from agentfilterproxymodel - bool found = false; - foreach ( const QString &mimeType, lstType ) { - if ( filter.contains( mimeType ) ) { - found = true; - break; - } else { - foreach ( const QString &type, filter ) { - KMimeType::Ptr typePtr = KMimeType::mimeType( type, KMimeType::ResolveAliases ); - if ( !typePtr.isNull() && typePtr->is( mimeType ) ) { - found = true; - break; - } - } - } - if ( found ) - break; - } - if ( !found ) - continue; - } - QStandardItem *item = new QStandardItem( f.readName() ); - item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); - item->setData( entry, Qt::UserRole ); - if ( !f.readIcon().isEmpty() ) - item->setData( KIcon( f.readIcon() ), Qt::DecorationRole ); - item->setData( f.readComment(), Qt::ToolTipRole ); - m_model->appendRow( item ); - } - - connect( ui.listView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(selectionChanged()) ); - connect( ui.ghnsButton, SIGNAL(clicked()), SIGNAL(ghnsWanted()) ); -} - -void TypePage::selectionChanged() -{ - if ( ui.listView->selectionModel()->hasSelection() ) { - setValid( true ); - } else { - setValid( false ); - } -} - -void TypePage::leavePageNext() -{ - if ( !ui.listView->selectionModel()->hasSelection() ) - return; - const QModelIndex index = ui.listView->selectionModel()->selectedIndexes().first(); - Global::setAssistant( index.data( Qt::UserRole ).toString() ); -} - -QTreeView *TypePage::treeview() const -{ - return ui.listView; -} - diff -Nru kdepim-runtime-4.14.6/accountwizard/typepage.h kdepim-runtime-15.08.0/accountwizard/typepage.h --- kdepim-runtime-4.14.6/accountwizard/typepage.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/typepage.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 TYPEPAGE_H -#define TYPEPAGE_H - -#include "page.h" -#include - -#include "ui_typepage.h" - -class TypePage : public Page -{ - Q_OBJECT - public: - explicit TypePage( KAssistantDialog* parent = 0 ); - - virtual void leavePageNext(); - QTreeView *treeview() const; - - signals: - void ghnsWanted(); - - private slots: - void selectionChanged(); - private: - Ui::TypePage ui; - QStandardItemModel *m_model; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/accountwizard/ui/loadpage.ui kdepim-runtime-15.08.0/accountwizard/ui/loadpage.ui --- kdepim-runtime-4.14.6/accountwizard/ui/loadpage.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/ui/loadpage.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ - - - LoadPage - - - - 0 - 0 - 400 - 84 - - - - - - - Qt::Vertical - - - - 20 - 129 - - - - - - - - Loading assistant... - - - Qt::AlignCenter - - - - - - - Qt::Vertical - - - - 20 - 129 - - - - - - - - - diff -Nru kdepim-runtime-4.14.6/accountwizard/ui/personaldatapage.ui kdepim-runtime-15.08.0/accountwizard/ui/personaldatapage.ui --- kdepim-runtime-4.14.6/accountwizard/ui/personaldatapage.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/ui/personaldatapage.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,283 +0,0 @@ - - - PersonalDataPage - - - - 0 - 0 - 521 - 289 - - - - - - - With a few simple steps we create the right settings for you. Please follow the steps of this wizard carefully. - - - true - - - - - - - - - Full name: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - nameEdit - - - - - - - - 0 - 22 - - - - - - - - E-mail address: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - emailEdit - - - - - - - - 0 - 22 - - - - - - - - - 0 - 22 - - - - QLineEdit::Password - - - - - - - Password: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - passwordEdit - - - - - - - - - 0 - - - - - - - Find provider settings on the Internet - - - true - - - - - - Check online for the settings needed for this email provider. Only the domain name part of the e-mail address will be sent over the Internet at this point. If this option is unchecked, the account can be set up manually. - - - true - - - - - - - - - - - - - - - - - - - - - - - IMAP account - - - true - - - buttonGroup - - - - - - - POP3 account - - - buttonGroup - - - - - - - - - - - Incoming: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - TextLabel - - - - - - - Outgoing: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - TextLabel - - - - - - - Username: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - TextLabel - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Create Account - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 20 - - - - - - - - - KLineEdit - QLineEdit -
klineedit.h
-
- - KPIMUtils::ProgressIndicatorLabel - QLabel -
kpimutils/progressindicatorlabel.h
- 1 -
-
- - - - - -
diff -Nru kdepim-runtime-4.14.6/accountwizard/ui/providerpage.ui kdepim-runtime-15.08.0/accountwizard/ui/providerpage.ui --- kdepim-runtime-4.14.6/accountwizard/ui/providerpage.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/ui/providerpage.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ - - - ProviderPage - - - - 0 - 0 - 400 - 172 - - - - - - - Select your provider from the list below or click advanced if your provider is not listed - - - true - - - - - - - - - - false - - - true - - - true - - - true - - - true - - - true - - - true - - - - - - - - KFilterProxySearchLine - QWidget -
kfilterproxysearchline.h
-
-
- - -
diff -Nru kdepim-runtime-4.14.6/accountwizard/ui/setuppage.ui kdepim-runtime-15.08.0/accountwizard/ui/setuppage.ui --- kdepim-runtime-4.14.6/accountwizard/ui/setuppage.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/ui/setuppage.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ - - - SetupPage - - - - 0 - 0 - 400 - 143 - - - - - - - 0 - - - - - - - Qt::Vertical - - - - 20 - 109 - - - - - - - - Setting up account... - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - &Details... - - - - - - - - - Qt::Vertical - - - - 20 - 74 - - - - - - - - - - - - - - - - - - - - KPushButton - QPushButton -
kpushbutton.h
-
-
- - -
diff -Nru kdepim-runtime-4.14.6/accountwizard/ui/typepage.ui kdepim-runtime-15.08.0/accountwizard/ui/typepage.ui --- kdepim-runtime-4.14.6/accountwizard/ui/typepage.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/ui/typepage.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,84 +0,0 @@ - - - TypePage - - - - 0 - 0 - 400 - 151 - - - - - - - Select which kind of account you want to create: - - - - - - - - - - false - - - true - - - true - - - true - - - true - - - true - - - true - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Check for more on Internet - - - - - - - - - - KFilterProxySearchLine - QWidget -
kfilterproxysearchline.h
-
-
- - -
diff -Nru kdepim-runtime-4.14.6/accountwizard/wizards/CMakeLists.txt kdepim-runtime-15.08.0/accountwizard/wizards/CMakeLists.txt --- kdepim-runtime-4.14.6/accountwizard/wizards/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/wizards/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -add_subdirectory(tine20) diff -Nru kdepim-runtime-4.14.6/accountwizard/wizards/tine20/CMakeLists.txt kdepim-runtime-15.08.0/accountwizard/wizards/tine20/CMakeLists.txt --- kdepim-runtime-4.14.6/accountwizard/wizards/tine20/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/wizards/tine20/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ - -install ( FILES tine20wizard.desktop tine20wizard.es tine20wizard.ui DESTINATION ${DATA_INSTALL_DIR}/akonadi/accountwizard/tine20 ) diff -Nru kdepim-runtime-4.14.6/accountwizard/wizards/tine20/Messages.sh kdepim-runtime-15.08.0/accountwizard/wizards/tine20/Messages.sh --- kdepim-runtime-4.14.6/accountwizard/wizards/tine20/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/wizards/tine20/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -#! /usr/bin/env bash -$EXTRACTRC *.ui >> rc.cpp -$XGETTEXT *.cpp -o $podir/accountwizard_tine20.pot -$XGETTEXT -kqsTr *.es -j -o $podir/accountwizard_tine20.pot diff -Nru kdepim-runtime-4.14.6/accountwizard/wizards/tine20/tine20wizard.desktop kdepim-runtime-15.08.0/accountwizard/wizards/tine20/tine20wizard.desktop --- kdepim-runtime-4.14.6/accountwizard/wizards/tine20/tine20wizard.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/wizards/tine20/tine20wizard.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -[Desktop Entry] -Name=Tine 2.0 Groupware Server -Name[bs]=Tine 2.0 Groupware Server -Name[ca]=Servidor de treball en grup Tine 2.0 -Name[ca@valencia]=Servidor de treball en grup Tine 2.0 -Name[cs]=Groupware Server Tine 2.0 -Name[da]=Tine 2.0 groupware-server -Name[de]=Tine 2.0 Groupware-Server -Name[el]=Tine 2.0 Groupware Server -Name[en_GB]=Tine 2.0 Groupware Server -Name[es]=Servidor de trabajo en grupo Tine 2.0 -Name[et]=Tine 2.0 grupitöö server -Name[fi]=Tine 2.0 -työryhmäpalvelin -Name[fr]=Serveur de logiciels de collaboration Tine 2.0 -Name[ga]=Freastalaí Groupware Tine 2.0 -Name[gl]=Servidor de grupos Tine 2.0 -Name[hu]=Tine 2.0 csoportmunka-kiszolgáló -Name[ia]=Servitor de Tine 2.0 Groupware -Name[it]=Server di groupware Tine 2.0 -Name[kk]=Tine 2.0 топтық іс сервері -Name[km]=ម៉ាស៊ីន​បម្រើ Tine ២.០ Groupware -Name[ko]=Tine 2.0 그룹웨어 서버 -Name[lt]=Tine 2.0 grupinio darbo serveris -Name[lv]=Tine 2.0 grupprogrammatūras serveris -Name[nb]=Tine 2.0 gruppevare-tjener -Name[nds]=Tine 2.0-Arbeitkoppel-Server -Name[nl]=Tine 2.0 groupwareserver -Name[pl]=Serwer Groupware Tine 2.0 -Name[pt]=Servidor de Groupware Tine 2.0 -Name[pt_BR]=Servidor groupware Tine 2.0 -Name[ru]=Сервер совместной работы Tine 2.0 -Name[sk]=Tine 2.0 Groupware Server -Name[sl]=Strežnik Tine 2.0 za skupinsko delo -Name[sr]=Тинеов групверски сервер -Name[sr@ijekavian]=Тинеов групверски сервер -Name[sr@ijekavianlatin]=Tineov grupverski server -Name[sr@latin]=Tineov grupverski server -Name[sv]=Tine 2.0 grupprogramserver -Name[tr]=Tine 2.0 Groupware Sunucusu -Name[uk]=Сервер групової роботи Tine 2.0 -Name[x-test]=xxTine 2.0 Groupware Serverxx -Name[zh_CN]=Tine 2.0 群件服务器 -Name[zh_TW]=Tine 2.0 群組伺服器 -Icon=applications-internet -Comment=Tine 2.0 Groupware Server -Comment[bs]=Tine 2.0 Groupware Server -Comment[ca]=Servidor de treball en grup Tine 2.0 -Comment[ca@valencia]=Servidor de treball en grup Tine 2.0 -Comment[cs]=Groupware Server Tine 2.0 -Comment[da]=Tine 2.0 groupware-server -Comment[de]=Tine 2.0 Groupware-Server -Comment[el]=Εξυπηρετητής Tine 2.0 Groupware -Comment[en_GB]=Tine 2.0 Groupware Server -Comment[es]=Servidor de trabajo en grupo Tine 2.0 -Comment[et]=Tine 2.0 grupitöö server -Comment[fi]=Tine 2.0 -työryhmäpalvelin -Comment[fr]=Serveur de logiciels de collaboration Tine 2.0 -Comment[ga]=Freastalaí Groupware Tine 2.0 -Comment[gl]=Servidor de grupos Tine 2.0 -Comment[hu]=Tine 2.0 csoportmunka-kiszolgáló -Comment[ia]=Servitor de Tine 2.0 Groupware -Comment[it]=Server di groupware Tine 2.0 -Comment[kk]=Tine 2.0 топтық іс сервері -Comment[km]=ម៉ាស៊ីន​បម្រើ Tine ២.០ Groupware -Comment[ko]=Tine 2.0 그룹웨어 서버 -Comment[lt]=Tine 2.0 grupinio darbo serveris -Comment[lv]=Tine 2.0 grupprogrammatūras serveris -Comment[nb]=Tine 2.0 gruppevare-tjener -Comment[nds]=Tine 2.0-Arbeitkoppel-Server -Comment[nl]=Tine 2.0 groupwareserver -Comment[pl]=Serwer Groupware Tine 2.0 -Comment[pt]=Servidor de 'Groupware' Tine 2.0 -Comment[pt_BR]=Servidor groupware Tine 2.0 -Comment[ru]=Сервер совместной работы Tine 2.0 -Comment[sk]=Tine 2.0 Groupware Server -Comment[sl]=Strežnik Tine 2.0 za skupinsko delo -Comment[sr]=Тинеов групверски сервер -Comment[sr@ijekavian]=Тинеов групверски сервер -Comment[sr@ijekavianlatin]=Tineov grupverski server -Comment[sr@latin]=Tineov grupverski server -Comment[sv]=Tine 2.0 grupprogramserver -Comment[tr]=Tine 2.0 Groupware Sunucusu -Comment[uk]=Сервер групової роботи Tine 2.0 -Comment[x-test]=xxTine 2.0 Groupware Serverxx -Comment[zh_CN]=Tine 2.0 群件服务器 -Comment[zh_TW]=Tine 2.0 群組伺服器 - -[Wizard] -Type=message/rfc822,text/directory,text/calendar -Script=tine20wizard.es - -[Translate] -Filename=accountwizard_tine20 diff -Nru kdepim-runtime-4.14.6/accountwizard/wizards/tine20/tine20wizard.es kdepim-runtime-15.08.0/accountwizard/wizards/tine20/tine20wizard.es --- kdepim-runtime-4.14.6/accountwizard/wizards/tine20/tine20wizard.es 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/wizards/tine20/tine20wizard.es 1970-01-01 00:00:00.000000000 +0000 @@ -1,177 +0,0 @@ -/* - Copyright (c) 2012 Volker Krause - Copyright (c) 2010 Casey Link - - 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. -*/ - -// add this function to trim user input of whitespace when needed -String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); }; - -var page = Dialog.addPage( "tine20wizard.ui", qsTr("Personal Settings") ); -var userChangedServerAddress = false; - -page.widget().nameEdit.text = SetupManager.name() -page.widget().emailEdit.text = SetupManager.email() -page.widget().passwordEdit.text = SetupManager.password() -guessServerName(); - -if ( SetupManager.personalDataAvailable() ) { - page.widget().nameEdit.visible = false; - page.widget().nameLabel.visible = false; - page.widget().emailEdit.visible = false; - page.widget().emailLabel.visible = false; - page.widget().passwordEdit.visible = false; - page.widget().passwordLabel.visible = false; -} - - -function guessServerName() -{ - if ( userChangedServerAddress == true ) { - return; - } - - var email = page.widget().emailEdit.text; - var pos = email.indexOf( "@" ); - if ( pos >= 0 && (pos + 1) < email.length ) { - var server = email.slice( pos + 1, email.length ); - page.widget().serverAddress.text = server; - } - - userChangedServerAddress = false; -} - -function emailChanged( arg ) -{ - validateInput(); - guessServerName(); -} - -function serverChanged( arg ) -{ - validateInput(); - if ( arg == "" ) { - userChangedServerAddress = false; - } else { - userChangedServerAddress = true; - } -} - -function validateInput() -{ - if ( page.widget().serverAddress.text.trim() == "" || page.widget().emailEdit.text.trim() == "" ) { - page.setValid( false ); - } else { - page.setValid( true ); - } -} - -// stage 1, setup identity and run imap server test -// stage 2, smtp setup (no server test) and Dav resources -var stage = 1; -var identity; // global so it can be accesed in setup and testOk - -function setup() -{ - print("setup() " + stage); - var serverAddress = page.widget().serverAddress.text.trim(); - if ( stage == 1 ) { - SetupManager.openWallet(); - - identity = SetupManager.createIdentity(); - identity.setEmail( page.widget().emailEdit.text ); - identity.setRealName( page.widget().nameEdit.text ); - - ServerTest.test( serverAddress, "imap" ); - } else { // stage 2 - var smtp = SetupManager.createTransport( "smtp" ); - smtp.setName( serverAddress ); - smtp.setHost( serverAddress ); - smtp.setPort( 25 ); - smtp.setEncryption( "TLS" ); - smtp.setAuthenticationType( "plain" ); - smtp.setUsername( page.widget().emailEdit.text ); - smtp.setPassword( page.widget().passwordEdit.text ); - identity.setTransport( smtp ); - - var dav = SetupManager.createResource( "akonadi_davgroupware_resource" ); - print("dav: " + dav ); - try { - dav.setName( "Tine 2.0" ); - dav.setOption( "DisplayName", "Tine 2.0" ); - dav.setOption( "RefreshInterval", 60 ); - dav.setOption( "RemoteUrls", ["$default$|CalDav|https://" + page.widget().serverAddress.text.trim() + "/calendars", - "$default$|CardDav|https://" + page.widget().serverAddress.text.trim() + "/addressbooks"] ); - dav.setOption( "DefaultUsername", page.widget().emailEdit.text.trim() ); - } catch (e) { print(e); } - - print("pre-exec"); - SetupManager.execute(); - print("post-exec"); - } -} - -function testResultFail() -{ - testOk( -1 ); -} - -function testOk( arg ) -{ - print("testOk arg =", arg); - var imapRes = SetupManager.createResource( "akonadi_imap_resource" ); - imapRes.setName( page.widget().serverAddress.text.trim() ); - imapRes.setOption( "ImapServer", page.widget().serverAddress.text.trim() ); - imapRes.setOption( "UserName", page.widget().emailEdit.text.trim() ); - imapRes.setOption( "Password", page.widget().passwordEdit.text.trim() ); - imapRes.setOption( "UseDefaultIdentity", false ); - imapRes.setOption( "AccountIdentity", identity.uoid() ); - imapRes.setOption( "DisconnectedModeEnabled", true ); - imapRes.setOption( "IntervalCheckTime", 60 ); - imapRes.setOption( "SubscriptionEnabled", true ); - imapRes.setOption( "SieveSupport", false ); - imapRes.setOption( "Authentication", 7 ); // ClearText - if ( arg == "ssl" ) { - // The ENUM used for authentication (in the imap resource only) - imapRes.setOption( "Safety", "SSL" ); // SSL/TLS - imapRes.setOption( "ImapPort", 993 ); - } else if ( arg == "tls" ) { // tls is really STARTTLS - imapRes.setOption( "Safety", "STARTTLS" ); // STARTTLS - imapRes.setOption( "ImapPort", 143 ); - } else if ( arg == "none" ) { - imapRes.setOption( "Safety", "NONE" ); // No encryption - imapRes.setOption( "ImapPort", 143 ); - } else { - // safe default fallback in case server test failed - imapRes.setOption( "Safety", "STARTTLS" ); - imapRes.setOption( "ImapPort", 143 ); - } - stage = 2; - setup(); -} - -try { - ServerTest.testFail.connect(testResultFail); - ServerTest.testResult.connect(testOk); - page.widget().emailEdit.textChanged.connect(emailChanged); - page.widget().serverAddress.textChanged.connect(serverChanged); - page.pageLeftNext.connect(setup); -} catch (e) { - print(e); -} - -validateInput(); diff -Nru kdepim-runtime-4.14.6/accountwizard/wizards/tine20/tine20wizard.ui kdepim-runtime-15.08.0/accountwizard/wizards/tine20/tine20wizard.ui --- kdepim-runtime-4.14.6/accountwizard/wizards/tine20/tine20wizard.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/accountwizard/wizards/tine20/tine20wizard.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ - - - tine20Wizard - - - - 0 - 0 - 368 - 124 - - - - - QFormLayout::ExpandingFieldsGrow - - - - - &Name: - - - nameEdit - - - - - - - - - - &Email: - - - emailEdit - - - - - - - - - - &Password: - - - passwordEdit - - - - - - - QLineEdit::Password - - - - - - - &Server Address: - - - serverAddress - - - - - - - - - - - KLineEdit - QLineEdit -
klineedit.h
-
-
- - serverAddress - - - -
diff -Nru kdepim-runtime-4.14.6/agents/akonadinepomukfeederagent.desktop kdepim-runtime-15.08.0/agents/akonadinepomukfeederagent.desktop --- kdepim-runtime-4.14.6/agents/akonadinepomukfeederagent.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/akonadinepomukfeederagent.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -[Desktop Entry] -Name=Akonadi Nepomuk Feeder -Name[bs]=Akonadi Nepomuk napajač -Name[ca]=Alimentador del Nepomuk per a l'Akonadi -Name[ca@valencia]=Alimentador del Nepomuk per a l'Akonadi -Name[cs]=Akonadi podavač Nepomuku -Name[da]=Akonadi Nepomuk-feeder -Name[de]=Nepomuk-Modul für Akonadi -Name[el]=Τροφοδότης Nepomuk του Akonadi -Name[en_GB]=Akonadi Nepomuk Feeder -Name[es]=Alimentador Nepomuk de Akonadi -Name[et]=Akonadi Nepomuki söötur -Name[fi]=Akonadi Nepomuk Feeder -Name[fr]=Connecteur Nepomuk pour Akonadi -Name[ga]=Fothaire Nepomuk Akonadi -Name[gl]=Alimentador de Nepomuk para Akonadi -Name[hu]=Akonadi Nepomuk feltöltő -Name[ia]=Syndication de Akonadi Nepomuk -Name[it]=Fornitore Akonadi per Nepomuk -Name[kk]=Nepomuk эл.пошта бергіші -Name[km]=កម្មវិធី​មតិ​ព័ត៌មាន Akonadi Nepomuk -Name[ko]=Akonadi Nepomuk 공급자 -Name[lt]=Akonadi Nepomuk šaltinis -Name[lv]=Akonadi Nepomuk barotājs -Name[nb]=Akonadi innmating til Nepomuk -Name[nds]=Nepomuk-Ingaav för Akonadi -Name[nl]=Akonadi Nepumuk-feeder -Name[pl]=Podajnik Akonadi Nepomuk -Name[pt]=Fontes do Nepomuk para o Akonadi -Name[pt_BR]=Alimentador do Nepomuk para o Akonadi -Name[ru]=Akonadi Nepomuk Feeder -Name[sk]=Kŕmitko Nepomuk Akonadi -Name[sl]=Podajalnik za Nepomuk -Name[sr]=Непомуков уводник Аконадија -Name[sr@ijekavian]=Непомуков уводник Аконадија -Name[sr@ijekavianlatin]=Nepomukov uvodnik Akonadija -Name[sr@latin]=Nepomukov uvodnik Akonadija -Name[sv]=Akonadi-inmatning till Nepomuk -Name[tr]=Akonadi Nepomuk Besleyici -Name[uk]=Передавач даних Akonadi Nepomuk -Name[x-test]=xxAkonadi Nepomuk Feederxx -Name[zh_CN]=Akonadi Nepomuk 邮件采集器 -Name[zh_TW]=Akonadi Nepomuk Feeder - -Type=AkonadiAgent -Exec=akonadi_nepomuk_feeder -Icon=nepomuk - -# This agent is disabled, do not autostart it. -# KDE5: remove this file -X-Akonadi-MimeTypes= -X-Akonadi-Capabilities= -X-Akonadi-Identifier=akonadi_nepomuk_feeder diff -Nru kdepim-runtime-4.14.6/agents/cmake/FindXsltproc.cmake kdepim-runtime-15.08.0/agents/cmake/FindXsltproc.cmake --- kdepim-runtime-4.14.6/agents/cmake/FindXsltproc.cmake 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/cmake/FindXsltproc.cmake 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,32 @@ +# Find xsltproc executable and provide a macro to generate D-Bus interfaces. +# +# The following variables are defined : +# XSLTPROC_EXECUTABLE - path to the xsltproc executable +# Xsltproc_FOUND - true if the program was found +# +find_program(XSLTPROC_EXECUTABLE xsltproc DOC "Path to the xsltproc executable") +mark_as_advanced(XSLTPROC_EXECUTABLE) + +if(XSLTPROC_EXECUTABLE) + set(Xsltproc_FOUND TRUE) + + # We depend on kdepimlibs, make sure it's found + if(NOT DEFINED KF5Akonadi_DATA_DIR) + find_package(KF5Akonadi REQUIRED) + endif() + + + # Macro to generate a D-Bus interface description from a KConfigXT file + macro(kcfg_generate_dbus_interface _kcfg _name) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml + COMMAND ${XSLTPROC_EXECUTABLE} --stringparam interfaceName ${_name} + ${KF5Akonadi_DATA_DIR}/kcfg2dbus.xsl + ${_kcfg} + > ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml + DEPENDS ${KF5Akonadi_DATA_DIR}/kcfg2dbus.xsl + ${_kcfg} + ) + endmacro() +endif() + diff -Nru kdepim-runtime-4.14.6/agents/CMakeLists.txt kdepim-runtime-15.08.0/agents/CMakeLists.txt --- kdepim-runtime-4.14.6/agents/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,20 +1,49 @@ +project(agents) +cmake_minimum_required(VERSION 2.8.12) + add_definitions( -DQT_NO_CAST_FROM_ASCII ) add_definitions( -DQT_NO_CAST_TO_ASCII ) -macro(kdepim_add_agent _target) - if(KDEPIM_BUILD_AGENTS_AS_PLUGINS) - add_definitions(-DKDEPIM_PLUGIN_AGENT) - kde4_add_plugin(${_target} ${ARGN}) - install( TARGETS ${_target} DESTINATION ${PLUGIN_INSTALL_DIR}/ ) - else() - kde4_add_executable(${_target} ${ARGN}) - install(TARGETS ${_target} ${INSTALL_TARGETS_DEFAULT_ARGS}) - endif() -endmacro() +if ("${CMAKE_SOURCE_DIR}" STREQUAL "${agents_SOURCE_DIR}") + + find_package(ECM 5.9.0 CONFIG REQUIRED) + set(CMAKE_MODULE_PATH ${agents_SOURCE_DIR}/cmake ${ECM_MODULE_PATH}) + + include(ECMPackageConfigHelpers) + include(ECMSetupVersion) + include(FeatureSummary) + include(KDEInstallDirs) + include(KDECMakeSettings) + include(KDEFrameworkCompilerSettings) + + set(KDEPIMLIBS_LIB_VERSION "4.75.0") + set(KF5_VERSION "5.9.0") + set(QT_REQUIRED_VERSION "5.4.0") + # KF5 package + find_package(KF5Config ${KF5_VERSION} CONFIG REQUIRED) + find_package(KF5NotifyConfig ${KF5_VERSION} CONFIG REQUIRED) + + # KdepimLibs package + find_package(KF5Akonadi ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5Mime ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5AkonadiMime ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5MailTransport ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5PimIdentities ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5AkonadiContact ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5CalendarCore ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + + + # Xsltproc + find_package(Xsltproc) + set_package_properties(Xsltproc PROPERTIES DESCRIPTION "XSLT processor from libxslt" TYPE REQUIRED PURPOSE "Required to generate D-Bus interfaces for all Akonadi resources.") + +endif() add_subdirectory( maildispatcher ) add_subdirectory( newmailnotifier ) add_subdirectory( migration ) add_subdirectory( invitations ) -install(FILES akonadinepomukfeederagent.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents") +if ("${CMAKE_SOURCE_DIR}" STREQUAL "${agents_SOURCE_DIR}") + feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) +endif() diff -Nru kdepim-runtime-4.14.6/agents/invitations/CMakeLists.txt kdepim-runtime-15.08.0/agents/invitations/CMakeLists.txt --- kdepim-runtime-4.14.6/agents/invitations/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/invitations/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,35 +1,41 @@ + + set( invitationsagent_SRCS invitationsagent.cpp incidenceattribute.cpp ) -#kde4_add_ui_files(invitationsagent_SRCS settings.ui) -#kde4_add_kcfg_files(invitationsagent_SRCS settings.kcfgc) +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_invitations_agent\") + +#ki18n_wrap_ui(invitationsagent_SRCS settings.ui) +#kconfig_add_kcfg_files(invitationsagent_SRCS settings.kcfgc) #kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/invitationsagent.kcfg org.kde.Akonadi.MailDispatcher.Settings) -#qt4_add_dbus_adaptor(invitationsagent_SRCS +#qt5_add_dbus_adaptor(invitationsagent_SRCS # ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.MailDispatcher.Settings.xml settings.h Settings #) -## qt4_add_dbus_adaptor( invitationsagent_SRCS +## qt5_add_dbus_adaptor( invitationsagent_SRCS ## ${KDE4_DBUS_INTERFACES_DIR}/org.kde.Akonadi.MailDispatcher.xml invitationsagent.h MailDispatcherAgent ## ) -kde4_add_executable(akonadi_invitations_agent ${invitationsagent_SRCS}) +add_executable(akonadi_invitations_agent ${invitationsagent_SRCS}) target_link_libraries(akonadi_invitations_agent - ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_AKONADI_KMIME_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${KDEPIMLIBS_MAILTRANSPORT_LIBS} - ${KDEPIMLIBS_KCALCORE_LIBS} + KF5::KIOCore + KF5::AkonadiCore + KF5::AkonadiMime + KF5::Mime + KF5::MailTransport + KF5::CalendarCore + KF5::AkonadiAgentBase + KF5::IdentityManagement ) -if (Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_invitations_agent PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) set_target_properties(akonadi_invitations_agent PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.invitationsagent") set_target_properties(akonadi_invitations_agent PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi Invitations Calendar") endif () -install(TARGETS akonadi_invitations_agent ${INSTALL_TARGETS_DEFAULT_ARGS}) -install(FILES invitationsagent.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents") +install(TARGETS akonadi_invitations_agent ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) +install(FILES invitationsagent.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents") diff -Nru kdepim-runtime-4.14.6/agents/invitations/incidenceattribute.cpp kdepim-runtime-15.08.0/agents/invitations/incidenceattribute.cpp --- kdepim-runtime-4.14.6/agents/invitations/incidenceattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/invitations/incidenceattribute.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,68 +26,68 @@ class IncidenceAttribute::Private { - public: +public: QString status; Akonadi::Item::Id referenceId; - explicit Private() : referenceId( -1 ) {} + explicit Private() : referenceId(-1) {} }; IncidenceAttribute::IncidenceAttribute() - : Attribute(), d( new Private ) + : Attribute(), d(new Private) { } IncidenceAttribute::~IncidenceAttribute() { - delete d; + delete d; } QByteArray IncidenceAttribute::type() const { - static const QByteArray sType( "incidence" ); + static const QByteArray sType("incidence"); return sType; } -Attribute* IncidenceAttribute::clone() const +Attribute *IncidenceAttribute::clone() const { - IncidenceAttribute *other = new IncidenceAttribute; - return other; + IncidenceAttribute *other = new IncidenceAttribute; + return other; } QByteArray IncidenceAttribute::serialized() const { - QString data; - QTextStream out( &data ); - out << d->status; - out << d->referenceId; - return data.toUtf8(); + QString data; + QTextStream out(&data); + out << d->status; + out << d->referenceId; + return data.toUtf8(); } -void IncidenceAttribute::deserialize( const QByteArray &data ) -{ - QString s( QString::fromUtf8( data ) ); - QTextStream in( &s ); - in >> d->status; - in >> d->referenceId; +void IncidenceAttribute::deserialize(const QByteArray &data) +{ + QString s(QString::fromUtf8(data)); + QTextStream in(&s); + in >> d->status; + in >> d->referenceId; } QString IncidenceAttribute::status() const { - return d->status; + return d->status; } -void IncidenceAttribute::setStatus( const QString &newstatus ) const +void IncidenceAttribute::setStatus(const QString &newstatus) const { - d->status = newstatus; + d->status = newstatus; } Akonadi::Item::Id IncidenceAttribute::reference() const { - return d->referenceId; + return d->referenceId; } -void IncidenceAttribute::setReference( Akonadi::Item::Id id ) +void IncidenceAttribute::setReference(Akonadi::Item::Id id) { - d->referenceId = id; + d->referenceId = id; } diff -Nru kdepim-runtime-4.14.6/agents/invitations/incidenceattribute.h kdepim-runtime-15.08.0/agents/invitations/incidenceattribute.h --- kdepim-runtime-4.14.6/agents/invitations/incidenceattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/invitations/incidenceattribute.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,22 +20,23 @@ #ifndef INCIDENCEATTRIBUTE_H #define INCIDENCEATTRIBUTE_H -#include -#include +#include +#include -namespace Akonadi { +namespace Akonadi +{ class IncidenceAttribute : public Akonadi::Attribute { - public: +public: explicit IncidenceAttribute(); ~IncidenceAttribute(); - virtual QByteArray type() const; - virtual Attribute* clone() const; + QByteArray type() const Q_DECL_OVERRIDE; + Attribute *clone() const Q_DECL_OVERRIDE; - virtual QByteArray serialized() const; - virtual void deserialize( const QByteArray &data ); + QByteArray serialized() const Q_DECL_OVERRIDE; + void deserialize(const QByteArray &data) Q_DECL_OVERRIDE; /** * The status the invitation is in. @@ -44,16 +45,16 @@ * "new", "accepted", "tentative", "counter", "cancel", "reply", "delegated" */ QString status() const; - void setStatus( const QString &newstatus ) const; + void setStatus(const QString &newstatus) const; /** * The referenced item. This is used e.g. in the invitationagent to * let users know where the original mail message is. */ Akonadi::Item::Id reference() const; - void setReference( Akonadi::Item::Id id ); + void setReference(Akonadi::Item::Id id); - private: +private: class Private; Private *const d; }; diff -Nru kdepim-runtime-4.14.6/agents/invitations/invitationsagent.cpp kdepim-runtime-15.08.0/agents/invitations/invitationsagent.cpp --- kdepim-runtime-4.14.6/agents/invitations/invitationsagent.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/invitations/invitationsagent.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,66 +21,66 @@ #include "incidenceattribute.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include #include #include -#include +#include #include #include #include #include -#include +#include #include -#include #include #include #include #include +#include using namespace Akonadi; class InvitationsCollectionRequestJob : public SpecialCollectionsRequestJob { - public: - InvitationsCollectionRequestJob( SpecialCollections* collection, InvitationsAgent *agent ) - : SpecialCollectionsRequestJob( collection, agent ) +public: + InvitationsCollectionRequestJob(SpecialCollections *collection, InvitationsAgent *agent) + : SpecialCollectionsRequestJob(collection, agent) { - setDefaultResourceType( QLatin1String( "akonadi_ical_resource" ) ); + setDefaultResourceType(QStringLiteral("akonadi_ical_resource")); - QVariantMap options; - options.insert( QLatin1String( "Path" ), QString( KGlobal::dirs()->localxdgdatadir() + QLatin1String( "akonadi_invitations" ) ) ); - options.insert( QLatin1String( "Name" ), i18n( "Invitations" ) ); - setDefaultResourceOptions( options ); - - QMap displayNameMap; - displayNameMap.insert( "invitations", i18n( "Invitations" ) ); - setTypes( displayNameMap.keys() ); - setNameForTypeMap( displayNameMap ); - - QMap iconNameMap; - iconNameMap.insert( "invitations", QLatin1String( "folder" ) ); - setIconForTypeMap( iconNameMap ); + QVariantMap options; + options.insert(QStringLiteral("Path"), QString(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QStringLiteral("akonadi_invitations"))); + options.insert(QStringLiteral("Name"), i18n("Invitations")); + setDefaultResourceOptions(options); + + QMap displayNameMap; + displayNameMap.insert("invitations", i18n("Invitations")); + setTypes(displayNameMap.keys()); + setNameForTypeMap(displayNameMap); + + QMap iconNameMap; + iconNameMap.insert("invitations", QStringLiteral("folder")); + setIconForTypeMap(iconNameMap); } virtual ~InvitationsCollectionRequestJob() @@ -90,27 +90,27 @@ class InvitationsCollection : public SpecialCollections { - public: +public: class Settings : public KCoreConfigSkeleton { - public: + public: Settings() { - setCurrentGroup( QLatin1String("Invitations") ); - addItemString( QLatin1String("DefaultResourceId"), m_id, QString() ); + setCurrentGroup(QStringLiteral("Invitations")); + addItemString(QStringLiteral("DefaultResourceId"), m_id, QString()); } virtual ~Settings() { } - private: + private: QString m_id; }; - InvitationsCollection( InvitationsAgent *agent ) - : Akonadi::SpecialCollections( new Settings ), m_agent( agent ), sInvitationsType( "invitations" ) + InvitationsCollection(InvitationsAgent *agent) + : Akonadi::SpecialCollections(new Settings), m_agent(agent), sInvitationsType("invitations") { } @@ -120,45 +120,46 @@ void clear() { - m_collection = Collection(); + m_collection = Collection(); } bool hasDefaultCollection() const { - return SpecialCollections::hasDefaultCollection( sInvitationsType ); + return SpecialCollections::hasDefaultCollection(sInvitationsType); } Collection defaultCollection() const { - if ( !m_collection.isValid() ) - m_collection = SpecialCollections::defaultCollection( sInvitationsType ); + if (!m_collection.isValid()) { + m_collection = SpecialCollections::defaultCollection(sInvitationsType); + } - return m_collection; + return m_collection; } void registerDefaultCollection() { - defaultCollection(); - registerCollection( sInvitationsType, m_collection ); + defaultCollection(); + registerCollection(sInvitationsType, m_collection); } - SpecialCollectionsRequestJob* reguestJob() const + SpecialCollectionsRequestJob *reguestJob() const { - InvitationsCollectionRequestJob *job = new InvitationsCollectionRequestJob( const_cast( this ), - m_agent ); - job->requestDefaultCollection( sInvitationsType ); + InvitationsCollectionRequestJob *job = new InvitationsCollectionRequestJob(const_cast(this), + m_agent); + job->requestDefaultCollection(sInvitationsType); - return job; + return job; } - private: +private: InvitationsAgent *m_agent; const QByteArray sInvitationsType; mutable Collection m_collection; }; -InvitationsAgentItem::InvitationsAgentItem( InvitationsAgent *agent, const Item &originalItem ) - : QObject( agent ), m_agent( agent ), m_originalItem( originalItem ) +InvitationsAgentItem::InvitationsAgentItem(InvitationsAgent *agent, const Item &originalItem) + : QObject(agent), m_agent(agent), m_originalItem(originalItem) { } @@ -166,395 +167,404 @@ { } -void InvitationsAgentItem::add( const Item &item ) +void InvitationsAgentItem::add(const Item &item) { - kDebug(); - const Collection collection = m_agent->collection(); - Q_ASSERT( collection.isValid() ); + qDebug(); + const Collection collection = m_agent->collection(); + Q_ASSERT(collection.isValid()); - ItemCreateJob *job = new ItemCreateJob( item, collection, this ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(createItemResult(KJob*)) ); + ItemCreateJob *job = new ItemCreateJob(item, collection, this); + connect(job, &InvitationsCollectionRequestJob::result, this, &InvitationsAgentItem::createItemResult); - m_jobs << job; + m_jobs << job; - job->start(); + job->start(); } -void InvitationsAgentItem::createItemResult( KJob *job ) +void InvitationsAgentItem::createItemResult(KJob *job) { - ItemCreateJob *createJob = qobject_cast( job ); - m_jobs.removeAll( createJob ); - if ( createJob->error() ) { - kWarning() << "Failed to create new Item in invitations collection." << createJob->errorText(); - return; - } + ItemCreateJob *createJob = qobject_cast(job); + m_jobs.removeAll(createJob); + if (createJob->error()) { + qWarning() << "Failed to create new Item in invitations collection." << createJob->errorText(); + return; + } - if ( !m_jobs.isEmpty() ) - return; + if (!m_jobs.isEmpty()) { + return; + } - ItemFetchJob *fetchJob = new ItemFetchJob( m_originalItem, this ); - connect( fetchJob, SIGNAL(result(KJob*)), this, SLOT(fetchItemDone(KJob*)) ); - fetchJob->start(); + ItemFetchJob *fetchJob = new ItemFetchJob(m_originalItem, this); + connect(fetchJob, &ItemFetchJob::result, this, &InvitationsAgentItem::fetchItemDone); + fetchJob->start(); } -void InvitationsAgentItem::fetchItemDone( KJob *job ) +void InvitationsAgentItem::fetchItemDone(KJob *job) { - if ( job->error() ) { - kWarning() << "Failed to fetch Item in invitations collection." << job->errorText(); - return; - } + if (job->error()) { + qWarning() << "Failed to fetch Item in invitations collection." << job->errorText(); + return; + } - ItemFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob->items().count() == 1 ); + ItemFetchJob *fetchJob = qobject_cast(job); + Q_ASSERT(fetchJob->items().count() == 1); - Item modifiedItem = fetchJob->items().first(); - Q_ASSERT( modifiedItem.isValid() ); + Item modifiedItem = fetchJob->items().at(0); + Q_ASSERT(modifiedItem.isValid()); - modifiedItem.setFlag( Akonadi::MessageFlags::HasInvitation ); - ItemModifyJob *modifyJob = new ItemModifyJob( modifiedItem, this ); - connect( modifyJob, SIGNAL(result(KJob*)), this, SLOT(modifyItemDone(KJob*)) ); - modifyJob->start(); + modifiedItem.setFlag(Akonadi::MessageFlags::HasInvitation); + ItemModifyJob *modifyJob = new ItemModifyJob(modifiedItem, this); + connect(modifyJob, &ItemModifyJob::result, this, &InvitationsAgentItem::modifyItemDone); + modifyJob->start(); } -void InvitationsAgentItem::modifyItemDone( KJob *job ) +void InvitationsAgentItem::modifyItemDone(KJob *job) { - if ( job->error() ) { - kWarning() << "Failed to modify Item in invitations collection." << job->errorText(); - return; - } + if (job->error()) { + qWarning() << "Failed to modify Item in invitations collection." << job->errorText(); + return; + } - //ItemModifyJob *mj = qobject_cast( job ); - //kDebug()<<"Job successful done."; + //ItemModifyJob *mj = qobject_cast( job ); + //qDebug()<<"Job successful done."; } -InvitationsAgent::InvitationsAgent( const QString &id ) - : AgentBase( id ), AgentBase::ObserverV2() - , m_invitationsCollection( new InvitationsCollection( this ) ) +InvitationsAgent::InvitationsAgent(const QString &id) + : AgentBase(id), AgentBase::ObserverV2() + , m_invitationsCollection(new InvitationsCollection(this)) { - kDebug(); + qDebug(); - changeRecorder()->setChangeRecordingEnabled( false ); // behave like Monitor - changeRecorder()->itemFetchScope().fetchFullPayload(); - changeRecorder()->setMimeTypeMonitored( QLatin1String("message/rfc822"), true ); - //changeRecorder()->setCollectionMonitored( Collection::root(), true ); + changeRecorder()->setChangeRecordingEnabled(false); // behave like Monitor + changeRecorder()->itemFetchScope().fetchFullPayload(); + changeRecorder()->setMimeTypeMonitored(QStringLiteral("message/rfc822"), true); + //changeRecorder()->setCollectionMonitored( Collection::root(), true ); - connect( this, SIGNAL(reloadConfiguration()), this, SLOT(initStart()) ); - QTimer::singleShot( 0, this, SLOT(initStart()) ); + connect(this, &InvitationsAgent::reloadConfiguration, this, &InvitationsAgent::initStart); + QTimer::singleShot(0, this, SLOT(initStart())); } InvitationsAgent::~InvitationsAgent() { - delete m_invitationsCollection; + delete m_invitationsCollection; } void InvitationsAgent::initStart() { - kDebug(); + qDebug(); - m_invitationsCollection->clear(); - if ( m_invitationsCollection->hasDefaultCollection() ) { - initDone(); - } else { - SpecialCollectionsRequestJob *job = m_invitationsCollection->reguestJob(); - connect( job, SIGNAL(result(KJob*)), this, SLOT(initDone(KJob*)) ); - job->start(); - } + m_invitationsCollection->clear(); + if (m_invitationsCollection->hasDefaultCollection()) { + initDone(); + } else { + SpecialCollectionsRequestJob *job = m_invitationsCollection->reguestJob(); + connect(job, &InvitationsCollectionRequestJob::result, this, &InvitationsAgent::initDone); + job->start(); + } - /* - KConfig config( "akonadi_invitations_agent" ); - KConfigGroup group = config.group( "General" ); - m_resourceId = group.readEntry( "DefaultCalendarAgent", "default_ical_resource" ); - newAgentCreated = false; - m_invitations = Akonadi::Collection(); - AgentInstance resource = AgentManager::self()->instance( m_resourceId ); - if ( resource.isValid() ) { - emit status( AgentBase::Running, i18n( "Reading..." ) ); - QMetaObject::invokeMethod( this, "createAgentResult", Qt::QueuedConnection ); - } else { - emit status( AgentBase::Running, i18n( "Creating..." ) ); - AgentType type = AgentManager::self()->type( QLatin1String( "akonadi_ical_resource" ) ); - AgentInstanceCreateJob *job = new AgentInstanceCreateJob( type, this ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(createAgentResult(KJob*)) ); - job->start(); - } - */ -} + /* + KConfig config( "akonadi_invitations_agent" ); + KConfigGroup group = config.group( "General" ); + m_resourceId = group.readEntry( "DefaultCalendarAgent", "default_ical_resource" ); + newAgentCreated = false; + m_invitations = Akonadi::Collection(); + AgentInstance resource = AgentManager::self()->instance( m_resourceId ); + if ( resource.isValid() ) { + Q_EMIT status( AgentBase::Running, i18n( "Reading..." ) ); + QMetaObject::invokeMethod( this, "createAgentResult", Qt::QueuedConnection ); + } else { + Q_EMIT status( AgentBase::Running, i18n( "Creating..." ) ); + AgentType type = AgentManager::self()->type( QLatin1String( "akonadi_ical_resource" ) ); + AgentInstanceCreateJob *job = new AgentInstanceCreateJob( type, this ); + connect(job, &InvitationsCollectionRequestJob::result, this, &InvitationsAgent::createAgentResult); + job->start(); + } + */ +} + +void InvitationsAgent::initDone(KJob *job) +{ + if (job) { + if (job->error()) { + qWarning() << "Failed to request default collection:" << job->errorText(); + return; + } -void InvitationsAgent::initDone( KJob *job ) -{ - if ( job ) { - if ( job->error() ) { - kWarning() << "Failed to request default collection:" << job->errorText(); - return; + m_invitationsCollection->registerDefaultCollection(); } - m_invitationsCollection->registerDefaultCollection(); - } - - Q_ASSERT( m_invitationsCollection->defaultCollection().isValid() ); - emit status( AgentBase::Idle, i18n( "Ready to dispatch invitations" ) ); + Q_ASSERT(m_invitationsCollection->defaultCollection().isValid()); + Q_EMIT status(AgentBase::Idle, i18n("Ready to dispatch invitations")); } Collection InvitationsAgent::collection() { - return m_invitationsCollection->defaultCollection(); + return m_invitationsCollection->defaultCollection(); } #if 0 -KPIMIdentities::IdentityManager* InvitationsAgent::identityManager() +KIdentityManagement::IdentityManager *InvitationsAgent::identityManager() { - if ( !m_IdentityManager ) - m_IdentityManager = new KPIMIdentities::IdentityManager( true /* readonly */, this ); - return m_IdentityManager; + if (!m_IdentityManager) { + m_IdentityManager = new KIdentityManagement::IdentityManager(true /* readonly */, this); + } + return m_IdentityManager; } #endif -void InvitationsAgent::configure( WId windowId ) +void InvitationsAgent::configure(WId windowId) { - kDebug() << windowId; - /* - QWidget *parent = QWidget::find( windowId ); - KDialog *dialog = new KDialog( parent ); - QVBoxLayout *layout = new QVBoxLayout( dialog->mainWidget() ); - //layout->addWidget( ); - dialog->mainWidget()->setLayout( layout ); - */ - initStart(); //reload + qDebug() << windowId; + /* + QWidget *parent = QWidget::find( windowId ); + QDialog *dialog = new QDialog( parent ); + QVBoxLayout *layout = new QVBoxLayout( dialog->mainWidget() ); + //layout->addWidget( ); + dialog->mainWidget()->setLayout( layout ); + */ + initStart(); //reload } #if 0 -void InvitationsAgent::createAgentResult( KJob *job ) +void InvitationsAgent::createAgentResult(KJob *job) { - kDebug(); - AgentInstance agent; - if ( job ) { - if ( job->error() ) { - kWarning() << job->errorString(); - emit status( AgentBase::Broken, i18n( "Failed to create resource: %1", job->errorString() ) ); - return; - } - - AgentInstanceCreateJob *j = static_cast( job ); - agent = j->instance(); - agent.setName( i18n( "Invitations" ) ); - m_resourceId = agent.identifier(); - - QDBusInterface conf( QString::fromLatin1( "org.freedesktop.Akonadi.Resource." ) + m_resourceId, - QString::fromLatin1( "/Settings" ), - QString::fromLatin1( "org.kde.Akonadi.ICal.Settings" ) ); - QDBusReply reply = conf.call( QString::fromLatin1( "setPath" ), - KGlobal::dirs()->localxdgdatadir() + "akonadi_ical_resource" ); - - if ( !reply.isValid() ) { - kWarning() << "dbus call failed, m_resourceId=" << m_resourceId; - emit status( AgentBase::Broken, i18n( "Failed to set the directory for invitations via D-Bus" ) ); - AgentManager::self()->removeInstance( agent ); - return; - } + qDebug(); + AgentInstance agent; + if (job) { + if (job->error()) { + qWarning() << job->errorString(); + Q_EMIT status(AgentBase::Broken, i18n("Failed to create resource: %1", job->errorString())); + return; + } - KConfig config( "akonadi_invitations_agent" ); - KConfigGroup group = config.group( "General" ); - group.writeEntry( "DefaultCalendarAgent", m_resourceId ); + AgentInstanceCreateJob *j = static_cast(job); + agent = j->instance(); + agent.setName(i18n("Invitations")); + m_resourceId = agent.identifier(); + + QDBusInterface conf(QString::fromLatin1("org.freedesktop.Akonadi.Resource.") + m_resourceId, + QString::fromLatin1("/Settings"), + QString::fromLatin1("org.kde.Akonadi.ICal.Settings")); + QDBusReply reply = conf.call(QString::fromLatin1("setPath"), + QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + "akonadi_ical_resource"); + + if (!reply.isValid()) { + qWarning() << "dbus call failed, m_resourceId=" << m_resourceId; + Q_EMIT status(AgentBase::Broken, i18n("Failed to set the directory for invitations via D-Bus")); + AgentManager::self()->removeInstance(agent); + return; + } - newAgentCreated = true; - agent.reconfigure(); - } else { - agent = AgentManager::self()->instance( m_resourceId ); - Q_ASSERT( agent.isValid() ); - } - - ResourceSynchronizationJob *j = new ResourceSynchronizationJob( agent, this ); - connect( j, SIGNAL(result(KJob*)), this, SLOT(resourceSyncResult(KJob*)) ); - j->start(); -} - -void InvitationsAgent::resourceSyncResult( KJob *job ) -{ - kDebug(); - if ( job->error() ) { - kWarning() << job->errorString(); - emit status( AgentBase::Broken, i18n( "Failed to synchronize collection: %1", job->errorString() ) ); - if ( newAgentCreated ) - AgentManager::self()->removeInstance( AgentManager::self()->instance( m_resourceId ) ); - return; - } - CollectionFetchJob *fjob = new CollectionFetchJob( Collection::root(), CollectionFetchJob::Recursive, this ); - fjob->fetchScope().setContentMimeTypes( QStringList() << "text/calendar" ); - fjob->fetchScope().setResource( m_resourceId ); - connect( fjob, SIGNAL(result(KJob*)), this, SLOT(collectionFetchResult(KJob*)) ); - fjob->start(); -} - -void InvitationsAgent::collectionFetchResult( KJob *job ) -{ - kDebug(); - - if ( job->error() ) { - kWarning() << job->errorString(); - emit status( AgentBase::Broken, i18n( "Failed to fetch collection: %1", job->errorString() ) ); - if ( newAgentCreated ) - AgentManager::self()->removeInstance( AgentManager::self()->instance( m_resourceId ) ); - return; - } - - CollectionFetchJob *fj = static_cast( job ); - - if ( newAgentCreated ) { - // if the agent was just created then there is exactly one collection already - // and we just use that one. - Q_ASSERT( fj->collections().count() == 1 ); - m_invitations = fj->collections().first(); - initDone(); - return; - } + KConfig config("akonadi_invitations_agent"); + KConfigGroup group = config.group("General"); + group.writeEntry("DefaultCalendarAgent", m_resourceId); + + newAgentCreated = true; + agent.reconfigure(); + } else { + agent = AgentManager::self()->instance(m_resourceId); + Q_ASSERT(agent.isValid()); + } + + ResourceSynchronizationJob *j = new ResourceSynchronizationJob(agent, this); + connect(j, &AgentInstanceCreateJob::result, this, &InvitationsAgent::resourceSyncResult); + j->start(); +} + +void InvitationsAgent::resourceSyncResult(KJob *job) +{ + qDebug(); + if (job->error()) { + qWarning() << job->errorString(); + Q_EMIT status(AgentBase::Broken, i18n("Failed to synchronize collection: %1", job->errorString())); + if (newAgentCreated) { + AgentManager::self()->removeInstance(AgentManager::self()->instance(m_resourceId)); + } + return; + } + CollectionFetchJob *fjob = new CollectionFetchJob(Collection::root(), CollectionFetchJob::Recursive, this); + fjob->fetchScope().setContentMimeTypes(QStringList() << "text/calendar"); + fjob->fetchScope().setResource(m_resourceId); + connect(fjob, &CollectionFetchJob::result, this, &InvitationsAgent::collectionFetchResult); + fjob->start(); +} + +void InvitationsAgent::collectionFetchResult(KJob *job) +{ + qDebug(); + + if (job->error()) { + qWarning() << job->errorString(); + Q_EMIT status(AgentBase::Broken, i18n("Failed to fetch collection: %1", job->errorString())); + if (newAgentCreated) { + AgentManager::self()->removeInstance(AgentManager::self()->instance(m_resourceId)); + } + return; + } + + CollectionFetchJob *fj = static_cast(job); - KConfig config( "akonadi_invitations_agent" ); - KConfigGroup group = config.group( "General" ); - const QString collectionId = group.readEntry( "DefaultCalendarCollection", QString() ); - if ( !collectionId.isEmpty() ) { - // look if the collection is still there. It may the case that there exists such - // a collection with the defined collectionId but that this is not a valid one - // and therefore not in the resultset. - const int id = collectionId.toInt(); - foreach ( const Collection &c, fj->collections() ) { - if ( c.id() == id ) { - m_invitations = c; + if (newAgentCreated) { + // if the agent was just created then there is exactly one collection already + // and we just use that one. + Q_ASSERT(fj->collections().count() == 1); + m_invitations = fj->collections().at(0); initDone(); return; - } } - } - // we need to create a new collection and use that one... - Collection c; - c.setName( "invitations" ); - c.setParent( Collection::root() ); - Q_ASSERT( !m_resourceId.isNull() ); - c.setResource( m_resourceId ); - c.setContentMimeTypes( QStringList() - << "text/calendar" - << "application/x-vnd.akonadi.calendar.event" - << "application/x-vnd.akonadi.calendar.todo" - << "application/x-vnd.akonadi.calendar.journal" - << "application/x-vnd.akonadi.calendar.freebusy" ); - CollectionCreateJob *cj = new CollectionCreateJob( c, this ); - connect( cj, SIGNAL(result(KJob*)), this, SLOT(collectionCreateResult(KJob*)) ); - cj->start(); -} - -void InvitationsAgent::collectionCreateResult( KJob *job ) -{ - kDebug(); - if ( job->error() ) { - kWarning() << job->errorString(); - emit status( AgentBase::Broken, i18n( "Failed to create collection: %1", job->errorString() ) ); - if ( newAgentCreated ) - AgentManager::self()->removeInstance( AgentManager::self()->instance( m_resourceId ) ); - return; - } - CollectionCreateJob *j = static_cast( job ); - m_invitations = j->collection(); - initDone(); + KConfig config("akonadi_invitations_agent"); + KConfigGroup group = config.group("General"); + const QString collectionId = group.readEntry("DefaultCalendarCollection", QString()); + if (!collectionId.isEmpty()) { + // look if the collection is still there. It may the case that there exists such + // a collection with the defined collectionId but that this is not a valid one + // and therefore not in the resultset. + const int id = collectionId.toInt(); + foreach (const Collection &c, fj->collections()) { + if (c.id() == id) { + m_invitations = c; + initDone(); + return; + } + } + } + + // we need to create a new collection and use that one... + Collection c; + c.setName("invitations"); + c.setParent(Collection::root()); + Q_ASSERT(!m_resourceId.isNull()); + c.setResource(m_resourceId); + c.setContentMimeTypes(QStringList() + << "text/calendar" + << "application/x-vnd.akonadi.calendar.event" + << "application/x-vnd.akonadi.calendar.todo" + << "application/x-vnd.akonadi.calendar.journal" + << "application/x-vnd.akonadi.calendar.freebusy"); + CollectionCreateJob *cj = new CollectionCreateJob(c, this); + connect(cj, &CollectionCreateJob::result, this, &InvitationsAgent::collectionCreateResult); + cj->start(); +} + +void InvitationsAgent::collectionCreateResult(KJob *job) +{ + qDebug(); + if (job->error()) { + qWarning() << job->errorString(); + Q_EMIT status(AgentBase::Broken, i18n("Failed to create collection: %1", job->errorString())); + if (newAgentCreated) { + AgentManager::self()->removeInstance(AgentManager::self()->instance(m_resourceId)); + } + return; + } + CollectionCreateJob *j = static_cast(job); + m_invitations = j->collection(); + initDone(); } #endif -Item InvitationsAgent::handleContent( const QString &vcal, - const KCalCore::MemoryCalendar::Ptr &calendar, - const Item &item ) +Item InvitationsAgent::handleContent(const QString &vcal, + const KCalCore::MemoryCalendar::Ptr &calendar, + const Item &item) { - KCalCore::ICalFormat format; - KCalCore::ScheduleMessage::Ptr message = format.parseScheduleMessage( calendar, vcal ); - if ( !message ) { - kWarning() << "Invalid invitation:" << vcal; - return Item(); - } + KCalCore::ICalFormat format; + KCalCore::ScheduleMessage::Ptr message = format.parseScheduleMessage(calendar, vcal); + if (!message) { + qWarning() << "Invalid invitation:" << vcal; + return Item(); + } - kDebug() << "id=" << item.id() << "remoteId=" << item.remoteId() << "vcal=" << vcal; + qDebug() << "id=" << item.id() << "remoteId=" << item.remoteId() << "vcal=" << vcal; - KCalCore::Incidence::Ptr incidence = message->event().staticCast(); - Q_ASSERT( incidence ); + KCalCore::Incidence::Ptr incidence = message->event().staticCast(); + Q_ASSERT(incidence); - IncidenceAttribute *attr = new IncidenceAttribute; - attr->setStatus( QLatin1String("new") ); //TODO - //attr->setFrom( message->from()->asUnicodeString() ); - attr->setReference( item.id() ); + IncidenceAttribute *attr = new IncidenceAttribute; + attr->setStatus(QLatin1String("new")); //TODO + //attr->setFrom( message->from()->asUnicodeString() ); + attr->setReference(item.id()); - Item newItem; - newItem.setMimeType( incidence->mimeType() ); - newItem.addAttribute( attr ); - newItem.setPayload( KCalCore::Incidence::Ptr( incidence->clone() ) ); - return newItem; + Item newItem; + newItem.setMimeType(incidence->mimeType()); + newItem.addAttribute(attr); + newItem.setPayload(KCalCore::Incidence::Ptr(incidence->clone())); + return newItem; } -void InvitationsAgent::itemAdded( const Item &item, const Collection &collection ) +void InvitationsAgent::itemAdded(const Item &item, const Collection &collection) { - kDebug() << item.id() << collection; - Q_UNUSED( collection ); - - if ( !m_invitationsCollection->defaultCollection().isValid() ) { - kDebug() << "No default collection found"; - return; - } + qDebug() << item.id() << collection; + Q_UNUSED(collection); - if ( collection.isVirtual() ) - return; - - if ( !item.hasPayload() ) { - kDebug() << "Item has no payload"; - return; - } - - KMime::Message::Ptr message = item.payload(); - - //TODO check if we are the sender and need to ignore the message... - //const QString sender = message->sender()->asUnicodeString(); - //if ( identityManager()->thatIsMe( sender ) ) return; + if (!m_invitationsCollection->defaultCollection().isValid()) { + qDebug() << "No default collection found"; + return; + } - KCalCore::MemoryCalendar::Ptr calendar( new KCalCore::MemoryCalendar( KSystemTimeZones::local() ) ); - if ( message->contentType()->isMultipart() ) { - kDebug() << "message is multipart:" << message->attachments().size(); + if (collection.isVirtual()) { + return; + } - InvitationsAgentItem *it = 0; - foreach ( KMime::Content *content, message->contents() ) { + if (!item.hasPayload()) { + qDebug() << "Item has no payload"; + return; + } - KMime::Headers::ContentType *ct = content->contentType(); - Q_ASSERT( ct ); - kDebug() << "Mimetype of the body part is " << ct->mimeType(); - if ( ct->mimeType() != "text/calendar" ) - continue; + KMime::Message::Ptr message = item.payload(); - Item newItem = handleContent( QLatin1String(content->body()), calendar, item ); - if ( !newItem.hasPayload() ) { - kDebug() << "new item has no payload"; - continue; - } + //TODO check if we are the sender and need to ignore the message... + //const QString sender = message->sender()->asUnicodeString(); + //if ( identityManager()->thatIsMe( sender ) ) return; + + KCalCore::MemoryCalendar::Ptr calendar(new KCalCore::MemoryCalendar(KSystemTimeZones::local())); + if (message->contentType()->isMultipart()) { + qDebug() << "message is multipart:" << message->attachments().size(); + + InvitationsAgentItem *it = Q_NULLPTR; + foreach (KMime::Content *content, message->contents()) { + + KMime::Headers::ContentType *ct = content->contentType(); + Q_ASSERT(ct); + qDebug() << "Mimetype of the body part is " << ct->mimeType(); + if (ct->mimeType() != "text/calendar") { + continue; + } + + Item newItem = handleContent(QLatin1String(content->body()), calendar, item); + if (!newItem.hasPayload()) { + qDebug() << "new item has no payload"; + continue; + } + + if (!it) { + it = new InvitationsAgentItem(this, item); + } - if ( !it ) - it = new InvitationsAgentItem( this, item ); + it->add(newItem); + } + } else { + qDebug() << "message is not multipart"; - it->add( newItem ); - } - } else { - kDebug() << "message is not multipart"; + KMime::Headers::ContentType *ct = message->contentType(); + Q_ASSERT(ct); + qDebug() << "Mimetype of the body is " << ct->mimeType(); + if (ct->mimeType() != "text/calendar") { + return; + } - KMime::Headers::ContentType *ct = message->contentType(); - Q_ASSERT( ct ); - kDebug() << "Mimetype of the body is " << ct->mimeType(); - if ( ct->mimeType() != "text/calendar" ) - return; + qDebug() << "Message has an invitation in the body, processing"; - kDebug() << "Message has an invitation in the body, processing"; + Item newItem = handleContent(QLatin1String(message->body()), calendar, item); + if (!newItem.hasPayload()) { + qDebug() << "new item has no payload"; + return; + } - Item newItem = handleContent( QLatin1String(message->body()), calendar, item ); - if ( !newItem.hasPayload() ) { - kDebug() << "new item has no payload"; - return; + InvitationsAgentItem *it = new InvitationsAgentItem(this, item); + it->add(newItem); } - - InvitationsAgentItem *it = new InvitationsAgentItem( this, item ); - it->add( newItem ); - } } -AKONADI_AGENT_MAIN( InvitationsAgent ) +AKONADI_AGENT_MAIN(InvitationsAgent) diff -Nru kdepim-runtime-4.14.6/agents/invitations/invitationsagent.h kdepim-runtime-15.08.0/agents/invitations/invitationsagent.h --- kdepim-runtime-4.14.6/agents/invitations/invitationsagent.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/invitations/invitationsagent.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,10 +22,10 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include #include @@ -36,47 +36,47 @@ class InvitationsAgentItem : public QObject { - Q_OBJECT + Q_OBJECT - public: +public: InvitationsAgentItem(InvitationsAgent *a, const Akonadi::Item &originalItem); virtual ~InvitationsAgentItem(); void add(const Akonadi::Item &newItem); - private Q_SLOTS: - void createItemResult( KJob *job ); - void fetchItemDone( KJob* ); - void modifyItemDone( KJob *job ); +private Q_SLOTS: + void createItemResult(KJob *job); + void fetchItemDone(KJob *); + void modifyItemDone(KJob *job); - private: +private: InvitationsAgent *m_agent; const Akonadi::Item m_originalItem; - QList m_jobs; + QList m_jobs; }; class InvitationsAgent : public Akonadi::AgentBase, public Akonadi::AgentBase::ObserverV2 { - Q_OBJECT + Q_OBJECT - public: - explicit InvitationsAgent( const QString &id ); +public: + explicit InvitationsAgent(const QString &id); virtual ~InvitationsAgent(); Akonadi::Collection collection(); - public Q_SLOTS: - virtual void configure( WId windowId ); +public Q_SLOTS: + void configure(WId windowId) Q_DECL_OVERRIDE; - private Q_SLOTS: +private Q_SLOTS: void initStart(); - void initDone( KJob *job = 0 ); + void initDone(KJob *job = Q_NULLPTR); - private: - Akonadi::Item handleContent( const QString &vcal, - const KCalCore::MemoryCalendar::Ptr &calendar, - const Akonadi::Item &item ); +private: + Akonadi::Item handleContent(const QString &vcal, + const KCalCore::MemoryCalendar::Ptr &calendar, + const Akonadi::Item &item); - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; /* virtual void itemChanged( const Akonadi::Item &item, const QSet &partIdentifiers ); @@ -92,7 +92,7 @@ virtual void collectionChanged( const Akonadi::Collection &collection, const QSet &changedAttributes ); */ - private: +private: QString m_resourceId; InvitationsCollection *m_invitationsCollection; Akonadi::Collection m_collection; diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/akonadi_maildispatcher_agent.notifyrc kdepim-runtime-15.08.0/agents/maildispatcher/akonadi_maildispatcher_agent.notifyrc --- kdepim-runtime-4.14.6/agents/maildispatcher/akonadi_maildispatcher_agent.notifyrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/akonadi_maildispatcher_agent.notifyrc 2015-08-10 21:01:02.000000000 +0000 @@ -98,6 +98,7 @@ [Event/emailsent] Name=E-mail successfully sent +Name[bg]=Е-пощата е изпратена успешно Name[bs]=E-mail uspješno poslan Name[ca]=Correu electrònic enviat correctament Name[ca@valencia]=Correu electrònic enviat correctament @@ -147,6 +148,7 @@ [Event/sendingfailed] Name=E-mail sending failed +Name[bg]=Грешка при изпращане на е-пощата Name[bs]=Slanje elektronske pošte neuspjelo Name[ca]=Ha fallat en enviar el correu electrònic Name[ca@valencia]=Ha fallat en enviar el correu electrònic diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/aborttest.cpp kdepim-runtime-15.08.0/agents/maildispatcher/autotests/aborttest.cpp --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/aborttest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/aborttest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,240 @@ +/* + Copyright 2009 Constantin Berzan + + 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 "aborttest.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define SPAM_ADDRESS "idanoka@gmail.com" +// NOTE: This test relies on a large SMTP message taking long enough to deliver, +// for it to call abort. So we need a valid receiver and a not-too-fast connection. +#define MESSAGE_MB 1 + +using namespace Akonadi; +using namespace KMime; +using namespace MailTransport; + +void AbortTest::initTestCase() +{ + QVERIFY(Control::start()); + QTest::qWait(1000); + + qRegisterMetaType(); + qRegisterMetaType(); + + // Get the outbox and clear it. + SpecialMailCollectionsRequestJob *rjob = new SpecialMailCollectionsRequestJob(this); + rjob->requestDefaultCollection(SpecialMailCollections::Outbox); + QSignalSpy spy(rjob, SIGNAL(result(KJob*))); + spy.wait(0); + outbox = SpecialMailCollections::self()->defaultCollection(SpecialMailCollections::Outbox); + QVERIFY(outbox.isValid()); + ItemDeleteJob *djob = new ItemDeleteJob(outbox); + djob->exec(); // may give error if outbox empty + + // Verify transports. + akoTid = TransportManager::self()->defaultTransportId(); + Transport *t = TransportManager::self()->transportById(akoTid); + QVERIFY(t); + QCOMPARE(t->type(), int(Transport::EnumType::Akonadi)); + QList tids = TransportManager::self()->transportIds(); + tids.removeAll(akoTid); + QCOMPARE(tids.count(), 1); + smtpTid = tids.first(); + t = TransportManager::self()->transportById(smtpTid); + QVERIFY(t); + QCOMPARE(t->type(), int(Transport::EnumType::SMTP)); + + // Set sink collection. + t = TransportManager::self()->transportById(akoTid); + const QString rid = t->host(); + const AgentInstance agent = AgentManager::self()->instance(rid); + QVERIFY(agent.isValid()); + CollectionPathResolver *resolver = new CollectionPathResolver(QLatin1String("sink"), this); + QVERIFY(resolver->exec()); + sink = Collection(resolver->collection()); + QVERIFY(sink.isValid()); + QDBusInterface conf(QLatin1String("org.freedesktop.Akonadi.Resource.") + rid, + QStringLiteral("/Settings"), QStringLiteral("org.kde.Akonadi.MailTransportDummy.Settings")); + QVERIFY(conf.isValid()); + QDBusReply reply = conf.call(QLatin1String("setSink"), sink.id()); + QVERIFY(reply.isValid()); + agent.reconfigure(); + + // Watch sink collection. + monitor = new Monitor(this); + monitor->setCollectionMonitored(sink); +} + +void AbortTest::testAbort() +{ + // Get the MDA interface. + DispatcherInterface iface; + QVERIFY(iface.dispatcherInstance().isValid()); + QVERIFY(iface.dispatcherInstance().isOnline()); + + // Create a large message. + qDebug() << "Building message."; + Message::Ptr msg = Message::Ptr(new Message); + QByteArray line(70, 'a'); + line.append("\n"); + QByteArray content("\n"); + for (int i = 0; i < MESSAGE_MB * 1024 * 1024 / line.length() + 10; i++) { + content.append(line); + } + QVERIFY(content.length() > MESSAGE_MB * 1024 * 1024); // >10MiB + msg->setContent(content); + + // Queue the message. + qDebug() << "Queuing message."; + MessageQueueJob *qjob = new MessageQueueJob(this); + qjob->setMessage(msg); + qjob->transportAttribute().setTransportId(smtpTid); + // default dispatch mode + // default sent-mail collection + qjob->addressAttribute().setFrom(QLatin1String("naiba")); + qjob->addressAttribute().setTo(QStringList() << QLatin1String(SPAM_ADDRESS)); + QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Idle); + AKVERIFYEXEC(qjob); + + // Wait for the MDA to begin dispatching. + for (int ds = 0; iface.dispatcherInstance().status() == AgentInstance::Idle; ds++) { + QTest::qWait(100); + if (ds % 10 == 0) { + qDebug() << "Waiting for the MDA to begin dispatching." << ds / 10 << "seconds elapsed."; + } + + QVERIFY2(ds <= 100, "Timeout"); + } + QTest::qWait(100); + + // Tell the MDA to abort. + QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Running); + iface.dispatcherInstance().abortCurrentTask(); + for (int ds = 0; iface.dispatcherInstance().status() != AgentInstance::Idle; ds++) { + QTest::qWait(100); + if (ds % 10 == 0) { + qDebug() << "Waiting for the MDA to become idle after aborting." << ds / 10 << "seconds elapsed."; + } + + QVERIFY2(ds <= 100, "Timeout"); + } + QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Idle); + + // Verify that item has an ErrorAttribute. + ItemFetchJob *fjob = new ItemFetchJob(outbox); + fjob->fetchScope().fetchAllAttributes(); + AKVERIFYEXEC(fjob); + QCOMPARE(fjob->items().count(), 1); + Item item = fjob->items().at(0); + QVERIFY(item.hasAttribute()); + ErrorAttribute *eA = item.attribute(); + qDebug() << "Stored error:" << eA->message(); + + // "Fix" the item and send again, this time with the default (Akonadi) transport. + item.removeAttribute(); + item.clearFlag(Akonadi::MessageFlags::HasError); + item.setFlag(Akonadi::MessageFlags::Queued); + TransportAttribute *newTA = new TransportAttribute(akoTid); + item.addAttribute(newTA); + ItemModifyJob *cjob = new ItemModifyJob(item); + QSignalSpy *addSpy = new QSignalSpy(monitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection))); + AKVERIFYEXEC(cjob); + + // Verify that the item got sent. + for (int ds = 0; addSpy->isEmpty(); ds++) { + QTest::qWait(100); + if (ds % 10 == 0) { + qDebug() << "Waiting for an item to be sent." << ds / 10 << "seconds elapsed."; + } + + QVERIFY2(ds <= 100, "Timeout"); + } + QCOMPARE(addSpy->count(), 1); + QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Idle); +} + +void AbortTest::testAbortWhileIdle() +{ + // Get the MDA interface. + DispatcherInterface iface; + QVERIFY(iface.dispatcherInstance().isValid()); + QVERIFY(iface.dispatcherInstance().isOnline()); + + // Abort thin air. + QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Idle); + iface.dispatcherInstance().abortCurrentTask(); + QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Idle); + + // Queue a message (to check that subsequent messages are being sent). + QVERIFY(monitor); + QSignalSpy *addSpy = new QSignalSpy(monitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection))); + Message::Ptr msg = Message::Ptr(new Message); + msg->setContent("\ntestAbortWhileIdle"); + MessageQueueJob *qjob = new MessageQueueJob(this); + qjob->setMessage(msg); + qjob->transportAttribute().setTransportId(akoTid); + // default dispatch mode + // default sent-mail collection + qjob->addressAttribute().setFrom(QLatin1String("naiba")); + qjob->addressAttribute().setTo(QStringList() << QStringLiteral("dracu")); + QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Idle); + AKVERIFYEXEC(qjob); + + // Verify that the item got sent. + for (int s = 0; addSpy->isEmpty(); s++) { + QTest::qWait(1000); + QVERIFY2(s <= 10, "Timeout"); + } + QCOMPARE(addSpy->count(), 1); + QCOMPARE(iface.dispatcherInstance().status(), AgentInstance::Idle); +} + +QTEST_AKONADIMAIN(AbortTest) + diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/aborttest.h kdepim-runtime-15.08.0/agents/maildispatcher/autotests/aborttest.h --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/aborttest.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/aborttest.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,54 @@ +/* + Copyright 2009 Constantin Berzan + + 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 ABORTTEST_H +#define ABORTTEST_H + +#include + +#include + +namespace Akonadi +{ +class Monitor; +} + +/** + This attempts to send a large message, then aborts it, then tries to send + it again and verify that it succeeds. + */ +class AbortTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void initTestCase(); + void testAbort(); + void testAbortWhileIdle(); + +private: + int akoTid; + int smtpTid; + Akonadi::Collection outbox; + Akonadi::Collection sink; + Akonadi::Monitor *monitor; + +}; + +#endif diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/CMakeLists.txt kdepim-runtime-15.08.0/agents/maildispatcher/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,48 @@ +include(ECMMarkAsTest) + +find_package(Qt5Test CONFIG REQUIRED) + +set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) + +# Stolen from kdepimlibs/akonadi/tests +macro(add_akonadi_isolated_test _source) + get_filename_component(_targetName ${_source} NAME_WE) + set(_srcList ${_source} ) + + add_executable(${_targetName} ${_srcList}) + ecm_mark_as_test(maildispatcher-${_targetName}) + target_link_libraries(${_targetName} + Qt5::Test + KF5::AkonadiCore + KF5::AkonadiMime + KF5::MailTransport + KF5::Mime + KF5::I18n + KF5::ConfigGui + Qt5::DBus + Qt5::Widgets + ) + + # based on kde4_add_unit_test + if (WIN32) + get_target_property( _loc ${_targetName} LOCATION ) + set(_executable ${_loc}.bat) + else () + set(_executable ${EXECUTABLE_OUTPUT_PATH}/${_targetName}) + endif () + if (UNIX) + set(_executable ${_executable}.shell) + endif () + + find_program(_testrunner akonaditest) + + if (KDEPIM_RUN_ISOLATED_TESTS) + add_test( maildispatcheragent-${_targetName} ${_testrunner} -c ${CMAKE_CURRENT_SOURCE_DIR}/unittestenv/config.xml ${_executable} ) + endif () +endmacro(add_akonadi_isolated_test) + + + +add_akonadi_isolated_test( aborttest.cpp ) +add_akonadi_isolated_test( dupetest.cpp ) + diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/dupetest.cpp kdepim-runtime-15.08.0/agents/maildispatcher/autotests/dupetest.cpp --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/dupetest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/dupetest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,221 @@ +/* + Copyright 2009 Constantin Berzan + + 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 "dupetest.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +static const int TIMEOUT_SECONDS = 60; +static const int MAXCOUNT = 99; // must be 2-digit! + +using namespace Akonadi; +using namespace KMime; +using namespace MailTransport; + +void DupeTest::initTestCase() +{ + QVERIFY(Control::start()); + QTest::qWait(1000); // give the MDA time to start + + qRegisterMetaType(); + qRegisterMetaType(); + + // we need a default Akonadi transport + int tid = TransportManager::self()->defaultTransportId(); + Transport *t = TransportManager::self()->transportById(tid); + QVERIFY(t); + QCOMPARE(t->type(), int(Transport::EnumType::Akonadi)); + + // set the sink collection + const QString rid = t->host(); + const AgentInstance agent = AgentManager::self()->instance(rid); + QVERIFY(agent.isValid()); + CollectionPathResolver *resolver = new CollectionPathResolver(QLatin1String("sink"), this); + QVERIFY(resolver->exec()); + sink = Collection(resolver->collection()); + QVERIFY(sink.isValid()); + QDBusInterface conf(QLatin1String("org.freedesktop.Akonadi.Resource.") + rid, + QLatin1String("/Settings"), QStringLiteral("org.kde.Akonadi.MailTransportDummy.Settings")); + QVERIFY(conf.isValid()); + QDBusReply reply = conf.call(QLatin1String("setSink"), sink.id()); + QVERIFY(reply.isValid()); + agent.reconfigure(); + + // set up monitor + monitor = new Monitor(this); + monitor->setCollectionMonitored(sink); + monitor->itemFetchScope().fetchFullPayload(); +} + +void DupeTest::testDupes_data() +{ + QTest::addColumn("message"); // the prefix of the message to send (-msg## is appended) + QTest::addColumn("count"); // how many copies to send + QTest::addColumn("delay"); // number of ms to wait before sending next copy + + QTest::newRow("1-nodelay") << "\n1-nodelay" << 1 << 0; + QTest::newRow("2-nodelay") << "\n2-nodelay" << 2 << 0; + QTest::newRow("5-nodelay") << "\n5-nodelay" << 5 << 0; + QTest::newRow("10-nodelay") << "\n10-nodelay" << 10 << 0; + QTest::newRow("20-nodelay") << "\n20-nodelay" << 20 << 0; + QTest::newRow("50-nodelay") << "\n50-nodelay" << 50 << 0; + QTest::newRow("99-nodelay") << "\n99-nodelay" << 99 << 0; + QTest::newRow("2-veryshortdelay") << "\n2-veryshortdelay" << 2 << 20; + QTest::newRow("5-veryshortdelay") << "\n5-veryshortdelay" << 5 << 20; + QTest::newRow("10-veryshortdelay") << "\n10-veryshortdelay" << 10 << 20; + QTest::newRow("20-veryshortdelay") << "\n20-veryshortdelay" << 20 << 20; + QTest::newRow("50-veryshortdelay") << "\n50-veryshortdelay" << 50 << 20; + QTest::newRow("99-veryshortdelay") << "\n99-veryshortdelay" << 99 << 20; + QTest::newRow("2-shortdelay") << "\n2-shortdelay" << 2 << 100; + QTest::newRow("5-shortdelay") << "\n5-shortdelay" << 5 << 100; + QTest::newRow("10-shortdelay") << "\n10-shortdelay" << 10 << 100; + QTest::newRow("20-shortdelay") << "\n20-shortdelay" << 20 << 100; + QTest::newRow("50-shortdelay") << "\n50-shortdelay" << 50 << 100; + QTest::newRow("99-shortdelay") << "\n99-shortdelay" << 99 << 99; + QTest::newRow("2-longdelay") << "\n2-longdelay" << 2 << 1000; + QTest::newRow("5-longdelay") << "\n5-longdelay" << 5 << 1000; + QTest::newRow("5-verylongdelay") << "\n5-verylongdelay" << 5 << 4000; + Q_ASSERT(99 <= MAXCOUNT); + Q_ASSERT(MAXCOUNT < 100); // 2-digit + + // TODO I'm not sure more items means a better test + // TODO test large items + // TODO test modifying items while they are being sent... +} + +void DupeTest::testDupes() +{ + QFETCH(QString, message); + QFETCH(int, count); + QFETCH(int, delay); + + // clean sink + ItemFetchJob *fjob = new ItemFetchJob(sink, this); + AKVERIFYEXEC(fjob); + if (fjob->items().count() > 0) { + // this test is needed because ItemDeleteJob gives error if no items are found + ItemDeleteJob *djob = new ItemDeleteJob(sink, this); + AKVERIFYEXEC(djob); + } + fjob = new ItemFetchJob(sink, this); + AKVERIFYEXEC(fjob); + QCOMPARE(fjob->items().count(), 0); + + // queue messages + Q_ASSERT(monitor); + QSignalSpy *addSpy = new QSignalSpy(monitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection))); + qDebug() << "Queuing" << count << "messages..."; + for (int i = 0; i < count; i++) { + //qDebug() << "Queuing message" << i + 1 << "of" << count; + + Message::Ptr msg = Message::Ptr(new Message); + msg->setContent(QString::fromLatin1("%1-msg%2\n").arg(message).arg(i + 1, 2, 10, QLatin1Char('0')).toLatin1()); + + MessageQueueJob *job = new MessageQueueJob(this); + job->setMessage(msg); + job->transportAttribute().setTransportId(TransportManager::self()->defaultTransportId()); + // default dispatch mode + // default sent-mail collection + job->addressAttribute().setFrom(QLatin1String("naiba")); + job->addressAttribute().setTo(QStringList() << QStringLiteral("dracu")); + //AKVERIFYEXEC( job ); + job->start(); + QTest::qWait(delay); + } + qDebug() << "Queued" << count << "messages."; + + // wait for the MDA to send them + int seconds = 0; + while (true) { + seconds++; + QTest::qWait(1000); + qDebug() << seconds << "seconds elapsed." << addSpy->count() << "messages got to sink."; + if (addSpy->count() >= count) { + break; + } + +#if 0 + if (seconds >= TIMEOUT_SECONDS) { + qDebug() << "Timeout, gdb master!"; + QTest::qWait(1000 * 1000); + } +#endif + QVERIFY2(seconds < TIMEOUT_SECONDS, "Timeout"); + } + + // TODO I should verify that the MDA has actually finished its work and has an empty queue + QTest::qWait(2000); + + // verify what has been sent + fjob = new ItemFetchJob(sink, this); + fjob->fetchScope().fetchFullPayload(); + AKVERIFYEXEC(fjob); + const Item::List items = fjob->items(); + int found[ MAXCOUNT ]; + for (int i = 0; i < count; i++) { + found[i] = 0; + } + for (int i = 0; i < items.count(); i++) { + QVERIFY(items[i].hasPayload()); + Message::Ptr msg = items[i].payload(); + const QByteArray content = msg->encodedContent(); + //qDebug() << "i" << i << "content" << content; + int loc = content.indexOf("-msg"); + QVERIFY(loc >= 0); + bool ok; + int who = content.mid(loc + 4, 2).toInt(&ok); + QVERIFY(ok); + //qDebug() << "identified msg" << who; + QVERIFY(who > 0 && who <= count); + found[ who - 1 ]++; + } + for (int i = 0; i < count; i++) { + if (found[i] > 1) { + qDebug() << "found duplicate message" << i + 1 << "(" << found[i] << "times )"; + } else if (found[i] < 1) { + qDebug() << "didn't find message" << i + 1; + } + QCOMPARE(found[i], 1); + } + QCOMPARE(addSpy->count(), count); + QCOMPARE(items.count(), count); +} + +QTEST_AKONADIMAIN(DupeTest) + diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/dupetest.h kdepim-runtime-15.08.0/agents/maildispatcher/autotests/dupetest.h --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/dupetest.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/dupetest.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,48 @@ +/* + Copyright 2009 Constantin Berzan + + 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 DUPETEST_H +#define DUPETEST_H + +#include + +#include +#include + +/** + This queues a bunch of messages very quickly one after the other, lets the + MDA send them via the dummy mailtransport resource, and then verify that the + correct number of messages has been sent. + */ +class DupeTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void initTestCase(); + void testDupes_data(); + void testDupes(); + +private: + Akonadi::Collection sink; + Akonadi::Monitor *monitor; + +}; + +#endif diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/TODO kdepim-runtime-15.08.0/agents/maildispatcher/autotests/TODO --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/TODO 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/TODO 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,6 @@ +* test online / offline +* figure out why ksyscoca is started (it's not the wallet apparently) +* aborttest: test aborting when there is >1 message queued +* test the various SendBehaviours and DispatchModes +* dupetest -> probably faster and more effective if I just use random intervals + of time between queuing messages diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/config.xml kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/config.xml --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/config.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/config.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,7 @@ + + kdehome + xdgconfig + xdglocal + akonadi_knut_resource + akonadi_mailtransport_dummy_resource + diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/akonadi-firstrunrc kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/akonadi-firstrunrc --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/akonadi-firstrunrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/akonadi-firstrunrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,3 @@ +[ProcessedDefaults] +defaultaddressbook=done +defaultcalendar=done diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,4 @@ +[General] +DataFile[$e]=$KDEHOME/testdata.xml +FileWatchingEnabled=false + diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/akonadi_mailtransport_dummy_resource_0rc kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/akonadi_mailtransport_dummy_resource_0rc --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/akonadi_mailtransport_dummy_resource_0rc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/akonadi_mailtransport_dummy_resource_0rc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,2 @@ +[General] +Sink=123 diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/kdebugrc kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/kdebugrc --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/kdebugrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/kdebugrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,110 @@ +[0] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[5250] +InfoOutput=2 + +[5251] +InfoOutput=2 + +[5252] +InfoOutput=2 + +[5253] +InfoOutput=2 + +[5254] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[5255] +InfoOutput=2 + +[5256] +InfoOutput=2 + +[5257] +InfoOutput=2 + +[5258] +InfoOutput=2 + +[5259] +InfoOutput=2 + +[5260] +InfoOutput=2 + +[5261] +InfoOutput=2 + +[5262] +InfoOutput=2 + +[5263] +InfoOutput=2 + +[5264] +InfoOutput=2 + +[5265] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[5266] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[5295] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[5324] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[7129] +InfoOutput=2 diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/kdedrc kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/kdedrc --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/kdedrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/kdedrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,3 @@ +[General] +CheckSycoca=false +CheckFileStamps=false diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/kwalletrc kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/kwalletrc --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/kwalletrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/kwalletrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,2 @@ +[Wallet] +Enabled=false diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/mailtransports kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/mailtransports --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/mailtransports 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/mailtransports 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,23 @@ +[$Version] +update_info=mailtransports.upd:initial-kmail-migration,mailtransports.upd:initial-knode-migration + +[General] +default-transport=666 + +[Transport 666] +host=akonadi_mailtransport_dummy_resource_0 +id=666 +name=Dummy Akonadi Transport +type=Akonadi + +[Transport 549190884] +auth=true +encryption=SSL +host=smtp.gmail.com +id=549190884 +name=idanoka2-stored +password=ᄒᄡᄚᄆᄒᄏᄊᆱᄎᆲᆱ +port=465 +storepass=true +user=idanoka2@gmail.com + diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/qttestrc kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/qttestrc --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/qttestrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/share/config/qttestrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,2 @@ +[Notification Messages] +WalletMigrate=false diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/testdata.xml kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/testdata.xml --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/kdehome/testdata.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/kdehome/testdata.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,4 @@ + + + + diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/xdgconfig/akonadi/akonadiserverrc kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/xdgconfig/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/xdgconfig/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/xdgconfig/akonadi/akonadiserverrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,4 @@ +[%General] + +[Search] +Manager=Dummy diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/xdglocal/.keep kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/xdglocal/.keep --- kdepim-runtime-4.14.6/agents/maildispatcher/autotests/unittestenv/xdglocal/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/autotests/unittestenv/xdglocal/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/CMakeLists.txt kdepim-runtime-15.08.0/agents/maildispatcher/CMakeLists.txt --- kdepim-runtime-4.14.6/agents/maildispatcher/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,21 +1,26 @@ -add_subdirectory( tests ) + +if (BUILD_TESTING) + add_subdirectory( autotests ) +endif() + +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_maildispatcher_agent\") set( maildispatcheragent_SRCS + maildispatcher_debug.cpp maildispatcheragent.cpp outboxqueue.cpp sendjob.cpp sentactionhandler.cpp storeresultjob.cpp - #configdialog.cpp ) -kde4_add_ui_files(maildispatcheragent_SRCS settings.ui) -kde4_add_kcfg_files(maildispatcheragent_SRCS settings.kcfgc) +ki18n_wrap_ui(maildispatcheragent_SRCS settings.ui) +kconfig_add_kcfg_files(maildispatcheragent_SRCS settings.kcfgc) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/maildispatcheragent.kcfg org.kde.Akonadi.MailDispatcher.Settings) -qt4_add_dbus_adaptor(maildispatcheragent_SRCS +qt5_add_dbus_adaptor(maildispatcheragent_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.MailDispatcher.Settings.xml settings.h Settings ) -qt4_add_dbus_adaptor( maildispatcheragent_SRCS +qt5_add_dbus_adaptor( maildispatcheragent_SRCS org.freedesktop.Akonadi.MailDispatcherAgent.xml maildispatcheragent.h MailDispatcherAgent ) @@ -23,19 +28,20 @@ add_definitions(-DMAIL_SERIALIZER_PLUGIN_STATIC) endif () -kdepim_add_agent(akonadi_maildispatcher_agent ${maildispatcheragent_SRCS}) +add_executable(akonadi_maildispatcher_agent ${maildispatcheragent_SRCS}) if (RUNTIME_PLUGINS_STATIC) target_link_libraries(akonadi_maildispatcher_agent akonadi_serializer_mail) endif () -if (Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_maildispatcher_agent PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) set_target_properties(akonadi_maildispatcher_agent PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.maildispatcher") set_target_properties(akonadi_maildispatcher_agent PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi Maildispatcher") endif () -target_link_libraries(akonadi_maildispatcher_agent ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_AKONADI_KMIME_LIBS} ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} ${KDEPIMLIBS_KMIME_LIBS} ${KDEPIMLIBS_MAILTRANSPORT_LIBS} ${KDE4_KNOTIFYCONFIG_LIBS}) +target_link_libraries(akonadi_maildispatcher_agent KF5::AkonadiCore KF5::AkonadiMime KF5::Mime KF5::MailTransport KF5::AkonadiAgentBase KF5::NotifyConfig KF5::DBusAddons) -install( FILES maildispatcheragent.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) -install( FILES akonadi_maildispatcher_agent.notifyrc DESTINATION "${DATA_INSTALL_DIR}/akonadi_maildispatcher_agent" ) +install( TARGETS akonadi_maildispatcher_agent ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} ) +install( FILES maildispatcheragent.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) +install( FILES akonadi_maildispatcher_agent.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFY5RCDIR} ) diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/configdialog.cpp kdepim-runtime-15.08.0/agents/maildispatcher/configdialog.cpp --- kdepim-runtime-4.14.6/agents/maildispatcher/configdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/configdialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -/* - Copyright 2008 Ingo Klöcker - - 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 "configdialog.h" - -#include "settings.h" - -#include -#include -#include -#include -#include - -using namespace Akonadi; - -ConfigDialog::ConfigDialog( QWidget *parent ) - : KDialog( parent ) -{ - mUi.setupUi( mainWidget() ); - - mManager = new KConfigDialogManager( this, Settings::self() ); - mManager->updateWidgets(); - - ui.outboxSelector->setMimeTypeFilter( QStringList() << KMime::Message::mimeType() ); - - // collection has no name if I skip the fetch job and just do Collection c(id) - CollectionFetchJob *job = new CollectionFetchJob( Collection( Settings::self()->outbox() ), CollectionFetchJob::Base ); - if ( job->exec() ) { - const Collection::List collections = job->collections(); - - if ( !collections.isEmpty() ) - ui.outboxSelector->setCollection( collections.first() ); - } - - ui.sentMailSelector->setMimeTypeFilter( QStringList() << KMime::Message::mimeType() ); - job = new CollectionFetchJob( Collection( Settings::self()->sentMail() ), CollectionFetchJob::Base ); - if ( job->exec() ) { - const Collection::List collections = job->collections(); - if ( !collections.isEmpty() ) - ui.sentMailSelector->setCollection( collections.first() ); - } - - connect( this, SIGNAL(okClicked()), this, SLOT(save()) ); -} - -void ConfigDialog::save() -{ - mManager->updateSettings(); - - const Collection outbox = ui.outboxSelector->collection(); - if ( outbox.isValid() ) { - kDebug() << "Collection" << outbox.id() << "selected for outbox."; - Settings::self()->setOutbox( outbox.id() ); - } - - const Collection sentMail = ui.sentMailSelector->collection(); - if ( sentMail.isValid() ) { - kDebug() << "Collection" << sentMail.id() << "selected for sentMail."; - Settings::self()->setSentMail( sentMail.id() ); - } - - Settings::self()->writeConfig(); -} - diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/configdialog.h kdepim-runtime-15.08.0/agents/maildispatcher/configdialog.h --- kdepim-runtime-4.14.6/agents/maildispatcher/configdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/configdialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/* - Copyright 2008 Ingo Klöcker - - 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 CONFIGDIALOG_H -#define CONFIGDIALOG_H - -#include - -#include "ui_settings.h" - -class KConfigDialogManager; - -class ConfigDialog : public KDialog -{ - Q_OBJECT - - public: - explicit ConfigDialog( QWidget *parent = 0 ); - - private Q_SLOTS: - void save(); - - private: - Ui::ConfigDialog mUi; - KConfigDialogManager *mManager; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/maildispatcheragent.cpp kdepim-runtime-15.08.0/agents/maildispatcher/maildispatcheragent.cpp --- kdepim-runtime-4.14.6/agents/maildispatcher/maildispatcheragent.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/maildispatcheragent.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -28,31 +28,22 @@ #include "settings.h" #include "settingsadaptor.h" -#include -#include -#include +#include +#include +#include #include #include -#include -#include -#include -#include +#include "maildispatcher_debug.h" #include #include #include -#include -#include +#include #include #include -#ifdef KDEPIM_STATIC_LIBS -extern bool ___MailTransport____INIT(); -#endif - #ifdef MAIL_SERIALIZER_PLUGIN_STATIC -#include Q_IMPORT_PLUGIN(akonadi_serializer_mail) #endif @@ -61,17 +52,17 @@ class MailDispatcherAgent::Private { - public: - Private( MailDispatcherAgent *parent ) - : q( parent ), - queue( 0 ), - currentJob( 0 ), - aborting( false ), - sendingInProgress( false ), - sentAnything( false ), - errorOccurred( false ), - sentItemsSize( 0 ), - sentActionHandler( 0 ) +public: + Private(MailDispatcherAgent *parent) + : q(parent), + queue(Q_NULLPTR), + currentJob(Q_NULLPTR), + aborting(false), + sendingInProgress(false), + sentAnything(false), + errorOccurred(false), + sentItemsSize(0), + sentActionHandler(Q_NULLPTR) { } @@ -79,7 +70,7 @@ { } - MailDispatcherAgent * const q; + MailDispatcherAgent *const q; OutboxQueue *queue; SendJob *currentJob; @@ -91,283 +82,281 @@ qulonglong sentItemsSize; SentActionHandler *sentActionHandler; - // slots: + // Q_SLOTS: void abort(); void dispatch(); - void itemFetched( const Item &item ); - void queueError( const QString &message ); - void sendPercent( KJob *job, unsigned long percent ); - void sendResult( KJob *job ); + void itemFetched(const Item &item); + void queueError(const QString &message); + void sendPercent(KJob *job, unsigned long percent); + void sendResult(KJob *job); void emitStatusReady(); }; - void MailDispatcherAgent::Private::abort() { - if ( !q->isOnline() ) { - kDebug() << "Offline. Ignoring call."; - return; - } - - if ( aborting ) { - kDebug() << "Already aborting."; - return; - } - - if ( !sendingInProgress && queue->isEmpty() ) { - kDebug() << "MDA is idle."; - Q_ASSERT( q->status() == AgentBase::Idle ); - } else { - kDebug() << "Aborting..."; - aborting = true; - if ( currentJob ) { - currentJob->abort(); + if (!q->isOnline()) { + qCDebug(MAILDISPATCHER_LOG) << "Offline. Ignoring call."; + return; + } + + if (aborting) { + qCDebug(MAILDISPATCHER_LOG) << "Already aborting."; + return; + } + + if (!sendingInProgress && queue->isEmpty()) { + qCDebug(MAILDISPATCHER_LOG) << "MDA is idle."; + Q_ASSERT(q->status() == AgentBase::Idle); + } else { + qCDebug(MAILDISPATCHER_LOG) << "Aborting..."; + aborting = true; + if (currentJob) { + currentJob->abort(); + } + // Further SendJobs will mark remaining items in the queue as 'aborted'. } - // Further SendJobs will mark remaining items in the queue as 'aborted'. - } } void MailDispatcherAgent::Private::dispatch() { - Q_ASSERT( queue ); + Q_ASSERT(queue); - if ( !q->isOnline() || sendingInProgress ) { - kDebug() << "Offline or busy. See you later."; - return; - } - - if ( !queue->isEmpty() ) { - if ( !sentAnything ) { - sentAnything = true; - sentItemsSize = 0; - emit q->percent( 0 ); - } - emit q->status( AgentBase::Running, - i18np( "Sending messages (1 item in queue)...", - "Sending messages (%1 items in queue)...", queue->count() ) ); - kDebug() << "Attempting to dispatch the next message."; - sendingInProgress = true; - queue->fetchOne(); // will trigger itemFetched - } else { - kDebug() << "Empty queue."; - if ( aborting ) { - // Finished marking messages as 'aborted'. - aborting = false; - sentAnything = false; - emit q->status( AgentBase::Idle, i18n( "Sending canceled." ) ); - QTimer::singleShot( 3000, q, SLOT(emitStatusReady()) ); + if (!q->isOnline() || sendingInProgress) { + qCDebug(MAILDISPATCHER_LOG) << "Offline or busy. See you later."; + return; + } + + if (!queue->isEmpty()) { + if (!sentAnything) { + sentAnything = true; + sentItemsSize = 0; + Q_EMIT q->percent(0); + } + Q_EMIT q->status(AgentBase::Running, + i18np("Sending messages (1 item in queue)...", + "Sending messages (%1 items in queue)...", queue->count())); + qCDebug(MAILDISPATCHER_LOG) << "Attempting to dispatch the next message."; + sendingInProgress = true; + queue->fetchOne(); // will trigger itemFetched } else { - if ( sentAnything ) { - // Finished sending messages in queue. - sentAnything = false; - emit q->percent( 100 ); - emit q->status( AgentBase::Idle, i18n( "Finished sending messages." ) ); - - if ( !errorOccurred ) { - KNotification *notify = new KNotification( QLatin1String("emailsent") ); - notify->setComponentData( q->componentData() ); - notify->setTitle( i18nc( "Notification title when email was sent", "E-Mail Successfully Sent" ) ); - notify->setText( i18nc( "Notification when the email was sent", "Your E-Mail has been sent successfully." ) ); - notify->sendEvent(); + qCDebug(MAILDISPATCHER_LOG) << "Empty queue."; + if (aborting) { + // Finished marking messages as 'aborted'. + aborting = false; + sentAnything = false; + Q_EMIT q->status(AgentBase::Idle, i18n("Sending canceled.")); + QTimer::singleShot(3000, q, SLOT(emitStatusReady())); + } else { + if (sentAnything) { + // Finished sending messages in queue. + sentAnything = false; + Q_EMIT q->percent(100); + Q_EMIT q->status(AgentBase::Idle, i18n("Finished sending messages.")); + + if (!errorOccurred) { + KNotification *notify = new KNotification(QStringLiteral("emailsent")); + notify->setComponentName(QStringLiteral("akonadi_maildispatcher_agent")); + notify->setTitle(i18nc("Notification title when email was sent", "E-Mail Successfully Sent")); + notify->setText(i18nc("Notification when the email was sent", "Your E-Mail has been sent successfully.")); + notify->sendEvent(); + } + } else { + // Empty queue. + Q_EMIT q->status(AgentBase::Idle, i18n("No items in queue.")); + } + QTimer::singleShot(3000, q, SLOT(emitStatusReady())); } - } else { - // Empty queue. - emit q->status( AgentBase::Idle, i18n( "No items in queue." ) ); - } - QTimer::singleShot( 3000, q, SLOT(emitStatusReady()) ); - } - errorOccurred = false; - } + errorOccurred = false; + } } +MailDispatcherAgent::MailDispatcherAgent(const QString &id) + : AgentBase(id), + d(new Private(this)) +{ + Kdelibs4ConfigMigrator migrate(QStringLiteral("maildispatcheragent")); + migrate.setConfigFiles(QStringList() << QStringLiteral("maildispatcheragentrc") << QStringLiteral("akonadi_maildispatcher_agent.notifyrc")); + migrate.migrate(); -MailDispatcherAgent::MailDispatcherAgent( const QString &id ) - : AgentBase( id ), - d( new Private( this ) ) -{ - kDebug() << "maildispatcheragent: At your service, sir!"; - + qCDebug(MAILDISPATCHER_LOG) << "maildispatcheragent: At your service, sir!"; #ifdef KDEPIM_STATIC_LIBS ___MailTransport____INIT(); #endif - KGlobal::locale()->insertCatalog( QLatin1String("libakonadi-kmime") ); // for special collection translation + new SettingsAdaptor(Settings::self()); + new MailDispatcherAgentAdaptor(this); - new SettingsAdaptor( Settings::self() ); - new MailDispatcherAgentAdaptor( this ); + KDBusConnectionPool::threadConnection().registerObject(QStringLiteral("/Settings"), + Settings::self(), QDBusConnection::ExportAdaptors); - DBusConnectionPool::threadConnection().registerObject( QLatin1String( "/Settings" ), - Settings::self(), QDBusConnection::ExportAdaptors ); + KDBusConnectionPool::threadConnection().registerObject(QStringLiteral("/MailDispatcherAgent"), + this, QDBusConnection::ExportAdaptors); + KDBusConnectionPool::threadConnection().registerService(QStringLiteral("org.freedesktop.Akonadi.MailDispatcherAgent")); + + d->queue = new OutboxQueue(this); + connect(d->queue, SIGNAL(newItems()), + this, SLOT(dispatch())); + connect(d->queue, SIGNAL(itemReady(Akonadi::Item)), + this, SLOT(itemFetched(Akonadi::Item))); + connect(d->queue, SIGNAL(error(QString)), + this, SLOT(queueError(QString))); + connect(this, SIGNAL(itemProcessed(Akonadi::Item,bool)), + d->queue, SLOT(itemProcessed(Akonadi::Item,bool))); + connect(this, SIGNAL(abortRequested()), + this, SLOT(abort())); - DBusConnectionPool::threadConnection().registerObject( QLatin1String( "/MailDispatcherAgent" ), - this, QDBusConnection::ExportAdaptors ); - DBusConnectionPool::threadConnection().registerService( QLatin1String( "org.freedesktop.Akonadi.MailDispatcherAgent" ) ); - - d->queue = new OutboxQueue( this ); - connect( d->queue, SIGNAL(newItems()), - this, SLOT(dispatch()) ); - connect( d->queue, SIGNAL(itemReady(Akonadi::Item)), - this, SLOT(itemFetched(Akonadi::Item)) ); - connect( d->queue, SIGNAL(error(QString)), - this, SLOT(queueError(QString)) ); - connect( this, SIGNAL(itemProcessed(Akonadi::Item,bool)), - d->queue, SLOT(itemProcessed(Akonadi::Item,bool)) ); - connect( this, SIGNAL(abortRequested()), - this, SLOT(abort()) ); + d->sentActionHandler = new SentActionHandler(this); - d->sentActionHandler = new SentActionHandler( this ); - - setNeedsNetwork( true ); + setNeedsNetwork(true); } MailDispatcherAgent::~MailDispatcherAgent() { - delete d; + delete d; } -void MailDispatcherAgent::configure( WId windowId ) +void MailDispatcherAgent::configure(WId windowId) { - Q_UNUSED( windowId ); - KNotifyConfigWidget::configure( 0 ); + Q_UNUSED(windowId); + KNotifyConfigWidget::configure(Q_NULLPTR); } -void MailDispatcherAgent::doSetOnline( bool online ) +void MailDispatcherAgent::doSetOnline(bool online) { - Q_ASSERT( d->queue ); - if ( online ) { - kDebug() << "Online. Dispatching messages."; - emit status( AgentBase::Idle, i18n( "Online, sending messages in queue." ) ); - QTimer::singleShot( 0, this, SLOT(dispatch()) ); - } else { - kDebug() << "Offline."; - emit status( AgentBase::Idle, i18n( "Offline, message sending suspended." ) ); + Q_ASSERT(d->queue); + if (online) { + qCDebug(MAILDISPATCHER_LOG) << "Online. Dispatching messages."; + Q_EMIT status(AgentBase::Idle, i18n("Online, sending messages in queue.")); + QTimer::singleShot(0, this, SLOT(dispatch())); + } else { + qCDebug(MAILDISPATCHER_LOG) << "Offline."; + Q_EMIT status(AgentBase::Idle, i18n("Offline, message sending suspended.")); - // TODO: This way, the OutboxQueue will continue to react to changes in - // the outbox, but the MDA will just not send anything. Is this what we - // want? - } + // TODO: This way, the OutboxQueue will continue to react to changes in + // the outbox, but the MDA will just not send anything. Is this what we + // want? + } - AgentBase::doSetOnline( online ); + AgentBase::doSetOnline(online); } -void MailDispatcherAgent::Private::itemFetched( const Item &item ) +void MailDispatcherAgent::Private::itemFetched(const Item &item) { - kDebug() << "Fetched item" << item.id() << "; creating SendJob."; - Q_ASSERT( sendingInProgress ); - Q_ASSERT( !currentItem.isValid() ); - currentItem = item; - Q_ASSERT( currentJob == 0 ); - emit q->itemDispatchStarted(); + qCDebug(MAILDISPATCHER_LOG) << "Fetched item" << item.id() << "; creating SendJob."; + Q_ASSERT(sendingInProgress); + Q_ASSERT(!currentItem.isValid()); + currentItem = item; + Q_ASSERT(currentJob == 0); + Q_EMIT q->itemDispatchStarted(); - currentJob = new SendJob( item, q ); - if ( aborting ) { - currentJob->setMarkAborted(); - } + currentJob = new SendJob(item, q); + if (aborting) { + currentJob->setMarkAborted(); + } - q->status( AgentBase::Running, i18nc( "Message with given subject is being sent.", "Sending: %1", - item.payload()->subject()->asUnicodeString() ) ); + q->status(AgentBase::Running, i18nc("Message with given subject is being sent.", "Sending: %1", + item.payload()->subject()->asUnicodeString())); - connect( currentJob, SIGNAL(result(KJob*)), - q, SLOT(sendResult(KJob*)) ); - connect( currentJob, SIGNAL(percent(KJob*,ulong)), - q, SLOT(sendPercent(KJob*,ulong)) ); + connect(currentJob, SIGNAL(result(KJob*)), + q, SLOT(sendResult(KJob*))); + connect(currentJob, SIGNAL(percent(KJob*,ulong)), + q, SLOT(sendPercent(KJob*,ulong))); - currentJob->start(); + currentJob->start(); } -void MailDispatcherAgent::Private::queueError( const QString &message ) +void MailDispatcherAgent::Private::queueError(const QString &message) { - emit q->error( message ); - errorOccurred = true; - // FIXME figure out why this does not set the status to Broken, etc. + Q_EMIT q->error(message); + errorOccurred = true; + // FIXME figure out why this does not set the status to Broken, etc. } -void MailDispatcherAgent::Private::sendPercent( KJob *job, unsigned long ) +void MailDispatcherAgent::Private::sendPercent(KJob *job, unsigned long) { - Q_ASSERT( sendingInProgress ); - Q_ASSERT( job == currentJob ); - // The progress here is actually the TransportJob, not the entire SendJob, - // because the post-job doesn't report progress. This should be fine, - // since the TransportJob is the lengthiest operation. + Q_ASSERT(sendingInProgress); + Q_ASSERT(job == currentJob); + // The progress here is actually the TransportJob, not the entire SendJob, + // because the post-job doesn't report progress. This should be fine, + // since the TransportJob is the lengthiest operation. - // Give the transport 80% of the weight, and move-to-sendmail 20%. - const double transportWeight = 0.8; + // Give the transport 80% of the weight, and move-to-sendmail 20%. + const double transportWeight = 0.8; - const int percent = 100 * ( sentItemsSize + job->processedAmount( KJob::Bytes ) * transportWeight ) - / ( sentItemsSize + currentItem.size() + queue->totalSize() ); + const int percent = 100 * (sentItemsSize + job->processedAmount(KJob::Bytes) * transportWeight) + / (sentItemsSize + currentItem.size() + queue->totalSize()); - kDebug() << "sentItemsSize" << sentItemsSize - << "this job processed" << job->processedAmount( KJob::Bytes ) - << "queue totalSize" << queue->totalSize() - << "total total size (sent+current+queue)" << ( sentItemsSize + currentItem.size() + queue->totalSize() ) - << "new percentage" << percent << "old percentage" << q->progress(); + qCDebug(MAILDISPATCHER_LOG) << "sentItemsSize" << sentItemsSize + << "this job processed" << job->processedAmount(KJob::Bytes) + << "queue totalSize" << queue->totalSize() + << "total total size (sent+current+queue)" << (sentItemsSize + currentItem.size() + queue->totalSize()) + << "new percentage" << percent << "old percentage" << q->progress(); - if ( percent != q->progress() ) { - // The progress can decrease too, if messages got added to the queue. - emit q->percent( percent ); - } - - // It is possible that the number of queued messages has changed. - emit q->status( AgentBase::Running, - i18np( "Sending messages (1 item in queue)...", - "Sending messages (%1 items in queue)...", 1 + queue->count() ) ); -} - -void MailDispatcherAgent::Private::sendResult( KJob *job ) -{ - Q_ASSERT( sendingInProgress ); - Q_ASSERT( job == currentJob ); - currentJob->disconnect( q ); - currentJob = 0; - - Q_ASSERT( currentItem.isValid() ); - sentItemsSize += currentItem.size(); - emit q->itemProcessed( currentItem, !job->error() ); - - const Akonadi::Item sentItem = currentItem; - currentItem = Item(); + if (percent != q->progress()) { + // The progress can decrease too, if messages got added to the queue. + Q_EMIT q->percent(percent); + } - if ( job->error() ) { - // The SendJob gave the item an ErrorAttribute, so we don't have to - // do anything. - kDebug() << "Sending failed. error:" << job->errorString(); + // It is possible that the number of queued messages has changed. + Q_EMIT q->status(AgentBase::Running, + i18np("Sending messages (1 item in queue)...", + "Sending messages (%1 items in queue)...", 1 + queue->count())); +} + +void MailDispatcherAgent::Private::sendResult(KJob *job) +{ + Q_ASSERT(sendingInProgress); + Q_ASSERT(job == currentJob); + currentJob->disconnect(q); + currentJob = Q_NULLPTR; + + Q_ASSERT(currentItem.isValid()); + sentItemsSize += currentItem.size(); + Q_EMIT q->itemProcessed(currentItem, !job->error()); + + const Akonadi::Item sentItem = currentItem; + currentItem = Item(); + + if (job->error()) { + // The SendJob gave the item an ErrorAttribute, so we don't have to + // do anything. + qCDebug(MAILDISPATCHER_LOG) << "Sending failed. error:" << job->errorString(); + + KNotification *notify = new KNotification(QLatin1String("sendingfailed")); + notify->setComponentName(QLatin1String("akonadi_maildispatcher_agent")); + notify->setTitle(i18nc("Notification title when email sending failed", "E-Mail Sending Failed")); + notify->setText(job->errorString()); + notify->sendEvent(); - KNotification *notify = new KNotification( QLatin1String("sendingfailed") ); - notify->setComponentData( q->componentData() ); - notify->setTitle( i18nc( "Notification title when email sending failed", "E-Mail Sending Failed" ) ); - notify->setText( job->errorString() ); - notify->sendEvent(); + errorOccurred = true; + } else { + qCDebug(MAILDISPATCHER_LOG) << "Sending succeeded."; - errorOccurred = true; - } else { - kDebug() << "Sending succeeded."; + // handle possible sent actions + const MailTransport::SentActionAttribute *attribute = sentItem.attribute(); + if (attribute) { + foreach (const MailTransport::SentActionAttribute::Action &action, attribute->actions()) { + sentActionHandler->runAction(action); + } + } + } - // handle possible sent actions - const MailTransport::SentActionAttribute *attribute = sentItem.attribute(); - if ( attribute ) { - foreach ( const MailTransport::SentActionAttribute::Action &action, attribute->actions() ) - sentActionHandler->runAction( action ); - } - } - - // dispatch next message - sendingInProgress = false; - QTimer::singleShot( 0, q, SLOT(dispatch()) ); + // dispatch next message + sendingInProgress = false; + QTimer::singleShot(0, q, SLOT(dispatch())); } void MailDispatcherAgent::Private::emitStatusReady() { - if ( q->status() == AgentBase::Idle ) { - // If still idle after aborting, clear 'aborted' status. - emit q->status( AgentBase::Idle, i18n( "Ready to dispatch messages." ) ); - } + if (q->status() == AgentBase::Idle) { + // If still idle after aborting, clear 'aborted' status. + Q_EMIT q->status(AgentBase::Idle, i18n("Ready to dispatch messages.")); + } } -#ifdef KDEPIM_PLUGIN_AGENT -AKONADI_AGENT_FACTORY( MailDispatcherAgent, akonadi_maildispatcher_agent ) -#else -AKONADI_AGENT_MAIN( MailDispatcherAgent ) +#ifndef KDEPIM_PLUGIN_AGENT +AKONADI_AGENT_MAIN(MailDispatcherAgent) #endif #include "moc_maildispatcheragent.cpp" diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/maildispatcheragent.desktop kdepim-runtime-15.08.0/agents/maildispatcher/maildispatcheragent.desktop --- kdepim-runtime-4.14.6/agents/maildispatcher/maildispatcheragent.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/maildispatcheragent.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -67,7 +67,7 @@ Comment[nb]=Sender ut e-postmeldinger Comment[nds]=Verdeelt Nettpost Comment[nl]=Verstuurt e-mailberichten -Comment[pl]=Rozsyła wiadomości e-mail +Comment[pl]=Rozsyła wiadomości pocztowe Comment[pt]=Trata das mensagens de e-mail Comment[pt_BR]=Encaminhamento de e-mails Comment[ro]=Remite scrisori electronice diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/maildispatcheragent.h kdepim-runtime-15.08.0/agents/maildispatcher/maildispatcheragent.h --- kdepim-runtime-4.14.6/agents/maildispatcher/maildispatcheragent.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/maildispatcheragent.h 2015-08-10 21:01:02.000000000 +0000 @@ -21,9 +21,10 @@ #ifndef MAILDISPATCHERAGENT_H #define MAILDISPATCHERAGENT_H -#include +#include -namespace Akonadi { +namespace Akonadi +{ class Item; } @@ -32,43 +33,43 @@ */ class MailDispatcherAgent : public Akonadi::AgentBase { - Q_OBJECT + Q_OBJECT - Q_CLASSINFO( "D-Bus Interface", "org.freedesktop.Akonadi.MailDispatcherAgent" ) + Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Akonadi.MailDispatcherAgent") - public: - explicit MailDispatcherAgent( const QString &id ); +public: + explicit MailDispatcherAgent(const QString &id); ~MailDispatcherAgent(); - public Q_SLOTS: - virtual void configure( WId windowId ); +public Q_SLOTS: + void configure(WId windowId) Q_DECL_OVERRIDE; - Q_SIGNALS: +Q_SIGNALS: /** * Emitted when the MDA has attempted to send an item. */ - void itemProcessed( const Akonadi::Item &item, bool result ); + void itemProcessed(const Akonadi::Item &item, bool result); /** * Emitted when the MDA has begun processing an item */ Q_SCRIPTABLE void itemDispatchStarted(); - protected: - virtual void doSetOnline( bool online ); +protected: + void doSetOnline(bool online) Q_DECL_OVERRIDE; - private: +private: //@cond PRIVATE class Private; - Private* const d; + Private *const d; - Q_PRIVATE_SLOT( d, void abort() ) - Q_PRIVATE_SLOT( d, void dispatch() ) - Q_PRIVATE_SLOT( d, void itemFetched( const Akonadi::Item& ) ) - Q_PRIVATE_SLOT( d, void queueError( const QString& ) ) - Q_PRIVATE_SLOT( d, void sendPercent( KJob*, unsigned long ) ) - Q_PRIVATE_SLOT( d, void sendResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void emitStatusReady() ) + Q_PRIVATE_SLOT(d, void abort()) + Q_PRIVATE_SLOT(d, void dispatch()) + Q_PRIVATE_SLOT(d, void itemFetched(const Akonadi::Item &)) + Q_PRIVATE_SLOT(d, void queueError(const QString &)) + Q_PRIVATE_SLOT(d, void sendPercent(KJob *, unsigned long)) + Q_PRIVATE_SLOT(d, void sendResult(KJob *)) + Q_PRIVATE_SLOT(d, void emitStatusReady()) //@endcond }; diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/maildispatcher_debug.cpp kdepim-runtime-15.08.0/agents/maildispatcher/maildispatcher_debug.cpp --- kdepim-runtime-4.14.6/agents/maildispatcher/maildispatcher_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/maildispatcher_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 "maildispatcher_debug.h" +Q_LOGGING_CATEGORY(MAILDISPATCHER_LOG, "log_maildispatcher") + diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/maildispatcher_debug.h kdepim-runtime-15.08.0/agents/maildispatcher/maildispatcher_debug.h --- kdepim-runtime-4.14.6/agents/maildispatcher/maildispatcher_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/maildispatcher_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 MAILDISPATCHER_DEBUG_H +#define MAILDISPATCHER_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(MAILDISPATCHER_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/outboxqueue.cpp kdepim-runtime-15.08.0/agents/maildispatcher/outboxqueue.cpp --- kdepim-runtime-4.14.6/agents/maildispatcher/outboxqueue.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/outboxqueue.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,18 +23,17 @@ #include #include -#include +#include "maildispatcher_debug.h" #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -54,14 +53,14 @@ */ class OutboxQueue::Private { - public: - Private( OutboxQueue *qq ) - : q( qq ), - outbox( -1 ), - monitor( 0 ), - futureTimer( 0 ), - totalSize( 0 ), - outboxDiscoveryRetries( 0 ) +public: + Private(OutboxQueue *qq) + : q(qq), + outbox(-1), + monitor(Q_NULLPTR), + futureTimer(Q_NULLPTR), + totalSize(0), + outboxDiscoveryRetries(0) { } @@ -92,368 +91,366 @@ QSet ignore; void initQueue(); - void addIfComplete( const Item &item ); + void addIfComplete(const Item &item); - // slots: + // Q_SLOTS: void checkFuture(); - void collectionFetched( KJob *job ); - void itemFetched( KJob *job ); + void collectionFetched(KJob *job); + void itemFetched(KJob *job); void localFoldersChanged(); - void localFoldersRequestResult( KJob *job ); - void itemAdded( const Item &item ); - void itemChanged( const Item &item ); - void itemMoved( const Item &item, const Collection &source, const Collection &dest ); - void itemRemoved( const Item &item ); - void itemProcessed( const Item &item, bool result ); + void localFoldersRequestResult(KJob *job); + void itemAdded(const Item &item); + void itemChanged(const Item &item); + void itemMoved(const Item &item, const Collection &source, const Collection &dest); + void itemRemoved(const Item &item); + void itemProcessed(const Item &item, bool result); }; - void OutboxQueue::Private::initQueue() { - totalSize = 0; - queue.clear(); + totalSize = 0; + queue.clear(); - kDebug() << "Fetching items in collection" << outbox.id(); - ItemFetchJob *job = new ItemFetchJob( outbox ); - job->fetchScope().fetchAllAttributes(); - job->fetchScope().fetchFullPayload( false ); - connect( job, SIGNAL(result(KJob*)), q, SLOT(collectionFetched(KJob*)) ); -} - -void OutboxQueue::Private::addIfComplete( const Item &item ) -{ - if ( ignore.contains( item.id() ) ) { - kDebug() << "Item" << item.id() << "is ignored."; - return; - } - - if ( queue.contains( item ) ) { - kDebug() << "Item" << item.id() << "already in queue!"; - return; - } - - if ( !item.hasAttribute() ) { - kWarning() << "Item" << item.id() << "does not have the required attribute Address."; - return; - } - - if ( !item.hasAttribute() ) { - kWarning() << "Item" << item.id() << "does not have the required attribute DispatchMode."; - return; - } - - if ( !item.hasAttribute() ) { - kWarning() << "Item" << item.id() << "does not have the required attribute SentBehaviour."; - return; - } - - if ( !item.hasAttribute() ) { - kWarning() << "Item" << item.id() << "does not have the required attribute Transport."; - return; - } - - if ( !item.hasFlag( Akonadi::MessageFlags::Queued ) ) { - kDebug() << "Item" << item.id() << "has no '$QUEUED' flag."; - return; - } - - const DispatchModeAttribute *dispatchModeAttribute = item.attribute(); - Q_ASSERT( dispatchModeAttribute ); - if ( dispatchModeAttribute->dispatchMode() == DispatchModeAttribute::Manual ) { - kDebug() << "Item" << item.id() << "is queued to be sent manually."; - return; - } - - const TransportAttribute *transportAttribute = item.attribute(); - Q_ASSERT( transportAttribute ); - if ( transportAttribute->transport() == 0 ) { - kWarning() << "Item" << item.id() << "has invalid transport."; - return; - } - - const SentBehaviourAttribute *sentBehaviourAttribute = item.attribute(); - Q_ASSERT( sentBehaviourAttribute ); - if ( sentBehaviourAttribute->sentBehaviour() == SentBehaviourAttribute::MoveToCollection && - !sentBehaviourAttribute->moveToCollection().isValid() ) { - kWarning() << "Item" << item.id() << "has invalid sent-mail collection."; - return; - } - - // This check requires fetchFullPayload. -> slow (?) - /* - if ( !item.hasPayload() ) { - kWarning() << "Item" << item.id() << "does not have KMime::Message::Ptr payload."; - return; - } - */ - - if ( dispatchModeAttribute->dispatchMode() == DispatchModeAttribute::Automatic && - dispatchModeAttribute->sendAfter().isValid() && - dispatchModeAttribute->sendAfter() > QDateTime::currentDateTime() ) { - // All the above was OK, so accept it for the future. - kDebug() << "Item" << item.id() << "is accepted to be sent in the future."; - futureMap.insert( dispatchModeAttribute->sendAfter(), item ); - Q_ASSERT( !futureItems.contains( item ) ); - futureItems.insert( item ); - checkFuture(); - return; - } - - kDebug() << "Item" << item.id() << "is accepted into the queue (size" << item.size() << ")."; - Q_ASSERT( !queue.contains( item ) ); - totalSize += item.size(); - queue.append( item ); - emit q->newItems(); + qCDebug(MAILDISPATCHER_LOG) << "Fetching items in collection" << outbox.id(); + ItemFetchJob *job = new ItemFetchJob(outbox); + job->fetchScope().fetchAllAttributes(); + job->fetchScope().fetchFullPayload(false); + connect(job, SIGNAL(result(KJob*)), q, SLOT(collectionFetched(KJob*))); } -void OutboxQueue::Private::checkFuture() +void OutboxQueue::Private::addIfComplete(const Item &item) { - kDebug() << "The future is here." << futureMap.count() << "items in futureMap."; - Q_ASSERT( futureTimer ); - futureTimer->stop(); - // By default, re-check in one hour. - futureTimer->setInterval( 60 * 60 * 1000 ); - - // Check items in ascending order of date. - while ( !futureMap.isEmpty() ) { - QMap::iterator it = futureMap.begin(); - kDebug() << "Item with due date" << it.key(); - if ( it.key() > QDateTime::currentDateTime() ) { - const int secs = QDateTime::currentDateTime().secsTo( it.key() ) + 1; - kDebug() << "Future, in" << secs << "seconds."; - Q_ASSERT( secs >= 0 ); - if ( secs < 60 * 60 ) { - futureTimer->setInterval( secs * 1000 ); - } - break; // all others are in the future too + if (ignore.contains(item.id())) { + qCDebug(MAILDISPATCHER_LOG) << "Item" << item.id() << "is ignored."; + return; } - if ( !futureItems.contains( it.value() ) ) { - kDebug() << "Item disappeared."; - } else { - kDebug() << "Due date is here. Queuing."; - addIfComplete( it.value() ); - futureItems.remove( it.value() ); + + if (queue.contains(item)) { + qCDebug(MAILDISPATCHER_LOG) << "Item" << item.id() << "already in queue!"; + return; + } + + if (!item.hasAttribute()) { + qCWarning(MAILDISPATCHER_LOG) << "Item" << item.id() << "does not have the required attribute Address."; + return; + } + + if (!item.hasAttribute()) { + qCWarning(MAILDISPATCHER_LOG) << "Item" << item.id() << "does not have the required attribute DispatchMode."; + return; + } + + if (!item.hasAttribute()) { + qCWarning(MAILDISPATCHER_LOG) << "Item" << item.id() << "does not have the required attribute SentBehaviour."; + return; + } + + if (!item.hasAttribute()) { + qCWarning(MAILDISPATCHER_LOG) << "Item" << item.id() << "does not have the required attribute Transport."; + return; + } + + if (!item.hasFlag(Akonadi::MessageFlags::Queued)) { + qCDebug(MAILDISPATCHER_LOG) << "Item" << item.id() << "has no '$QUEUED' flag."; + return; + } + + const DispatchModeAttribute *dispatchModeAttribute = item.attribute(); + Q_ASSERT(dispatchModeAttribute); + if (dispatchModeAttribute->dispatchMode() == DispatchModeAttribute::Manual) { + qCDebug(MAILDISPATCHER_LOG) << "Item" << item.id() << "is queued to be sent manually."; + return; + } + + const TransportAttribute *transportAttribute = item.attribute(); + Q_ASSERT(transportAttribute); + if (transportAttribute->transport() == Q_NULLPTR) { + qCWarning(MAILDISPATCHER_LOG) << "Item" << item.id() << "has invalid transport."; + return; + } + + const SentBehaviourAttribute *sentBehaviourAttribute = item.attribute(); + Q_ASSERT(sentBehaviourAttribute); + if (sentBehaviourAttribute->sentBehaviour() == SentBehaviourAttribute::MoveToCollection && + !sentBehaviourAttribute->moveToCollection().isValid()) { + qCWarning(MAILDISPATCHER_LOG) << "Item" << item.id() << "has invalid sent-mail collection."; + return; + } + + // This check requires fetchFullPayload. -> slow (?) + /* + if ( !item.hasPayload() ) { + qCWarning(MAILDISPATCHER_LOG) << "Item" << item.id() << "does not have KMime::Message::Ptr payload."; + return; + } + */ + + if (dispatchModeAttribute->dispatchMode() == DispatchModeAttribute::Automatic && + dispatchModeAttribute->sendAfter().isValid() && + dispatchModeAttribute->sendAfter() > QDateTime::currentDateTime()) { + // All the above was OK, so accept it for the future. + qCDebug(MAILDISPATCHER_LOG) << "Item" << item.id() << "is accepted to be sent in the future."; + futureMap.insert(dispatchModeAttribute->sendAfter(), item); + Q_ASSERT(!futureItems.contains(item)); + futureItems.insert(item); + checkFuture(); + return; + } + + qCDebug(MAILDISPATCHER_LOG) << "Item" << item.id() << "is accepted into the queue (size" << item.size() << ")."; + Q_ASSERT(!queue.contains(item)); + totalSize += item.size(); + queue.append(item); + Q_EMIT q->newItems(); +} + +void OutboxQueue::Private::checkFuture() +{ + qCDebug(MAILDISPATCHER_LOG) << "The future is here." << futureMap.count() << "items in futureMap."; + Q_ASSERT(futureTimer); + futureTimer->stop(); + // By default, re-check in one hour. + futureTimer->setInterval(60 * 60 * 1000); + + // Check items in ascending order of date. + while (!futureMap.isEmpty()) { + QMap::iterator it = futureMap.begin(); + qCDebug(MAILDISPATCHER_LOG) << "Item with due date" << it.key(); + if (it.key() > QDateTime::currentDateTime()) { + const int secs = QDateTime::currentDateTime().secsTo(it.key()) + 1; + qCDebug(MAILDISPATCHER_LOG) << "Future, in" << secs << "seconds."; + Q_ASSERT(secs >= 0); + if (secs < 60 * 60) { + futureTimer->setInterval(secs * 1000); + } + break; // all others are in the future too + } + if (!futureItems.contains(it.value())) { + qCDebug(MAILDISPATCHER_LOG) << "Item disappeared."; + } else { + qCDebug(MAILDISPATCHER_LOG) << "Due date is here. Queuing."; + addIfComplete(it.value()); + futureItems.remove(it.value()); + } + futureMap.erase(it); } - futureMap.erase( it ); - } - kDebug() << "Timer set to checkFuture again in" << futureTimer->interval() / 1000 << "seconds" - << "(that is" << futureTimer->interval() / 1000 / 60 << "minutes)."; + qCDebug(MAILDISPATCHER_LOG) << "Timer set to checkFuture again in" << futureTimer->interval() / 1000 << "seconds" + << "(that is" << futureTimer->interval() / 1000 / 60 << "minutes)."; - futureTimer->start(); + futureTimer->start(); } -void OutboxQueue::Private::collectionFetched( KJob *job ) +void OutboxQueue::Private::collectionFetched(KJob *job) { - if ( job->error() ) { - kWarning() << "Failed to fetch outbox collection. Queue will be empty until the outbox changes."; - return; - } + if (job->error()) { + qCWarning(MAILDISPATCHER_LOG) << "Failed to fetch outbox collection. Queue will be empty until the outbox changes."; + return; + } - const ItemFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob ); - kDebug() << "Fetched" << fetchJob->items().count() << "items."; + const ItemFetchJob *fetchJob = qobject_cast(job); + Q_ASSERT(fetchJob); + qCDebug(MAILDISPATCHER_LOG) << "Fetched" << fetchJob->items().count() << "items."; - foreach ( const Item &item, fetchJob->items() ) { - addIfComplete( item ); - } + foreach (const Item &item, fetchJob->items()) { + addIfComplete(item); + } } -void OutboxQueue::Private::itemFetched( KJob *job ) +void OutboxQueue::Private::itemFetched(KJob *job) { - if ( job->error() ) { - kDebug() << "Error fetching item:" << job->errorString() << ". Trying next item in queue."; - q->fetchOne(); - } + if (job->error()) { + qCDebug(MAILDISPATCHER_LOG) << "Error fetching item:" << job->errorString() << ". Trying next item in queue."; + q->fetchOne(); + } - const ItemFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob ); - if ( fetchJob->items().count() != 1 ) { - kDebug() << "Fetched" << fetchJob->items().count() << ", expected 1. Trying next item in queue."; - q->fetchOne(); - } + const ItemFetchJob *fetchJob = qobject_cast(job); + Q_ASSERT(fetchJob); + if (fetchJob->items().count() != 1) { + qCDebug(MAILDISPATCHER_LOG) << "Fetched" << fetchJob->items().count() << ", expected 1. Trying next item in queue."; + q->fetchOne(); + } - if ( !fetchJob->items().isEmpty() ) { - emit q->itemReady( fetchJob->items().first() ); - } + if (!fetchJob->items().isEmpty()) { + Q_EMIT q->itemReady(fetchJob->items().at(0)); + } } void OutboxQueue::Private::localFoldersChanged() { - // Called on startup, and whenever the local folders change. + // Called on startup, and whenever the local folders change. - if ( SpecialMailCollections::self()->hasDefaultCollection( SpecialMailCollections::Outbox ) ) { - // Outbox is ready, init the queue from it. - const Collection collection = SpecialMailCollections::self()->defaultCollection( SpecialMailCollections::Outbox ); - Q_ASSERT( collection.isValid() ); - - if ( outbox != collection ) { - monitor->setCollectionMonitored( outbox, false ); - monitor->setCollectionMonitored( collection, true ); - outbox = collection; - kDebug() << "Changed outbox to" << outbox.id(); - initQueue(); - } - } else { - // Outbox is not ready. Request it, since otherwise we will not know when - // new messages appear. - // (Note that we are a separate process, so we get no notification when - // MessageQueueJob requests the Outbox.) - monitor->setCollectionMonitored( outbox, false ); - outbox = Collection( -1 ); - - SpecialMailCollectionsRequestJob *job = new SpecialMailCollectionsRequestJob( q ); - job->requestDefaultCollection( SpecialMailCollections::Outbox ); - connect( job, SIGNAL(result(KJob*)), q, SLOT(localFoldersRequestResult(KJob*)) ); - - kDebug() << "Requesting outbox folder."; - job->start(); - } - - // make sure we have a place to dump the sent mails as well - if ( !SpecialMailCollections::self()->hasDefaultCollection( SpecialMailCollections::SentMail ) ) { - SpecialMailCollectionsRequestJob *job = new SpecialMailCollectionsRequestJob( q ); - job->requestDefaultCollection( SpecialMailCollections::SentMail ); - - kDebug() << "Requesting sent-mail folder"; - job->start(); - } -} - -void OutboxQueue::Private::localFoldersRequestResult( KJob *job ) -{ - if ( job->error() ) { - // We tried to create the outbox, but that failed. This could be because some - // other process, the mail app, for example, tried to create it at the - // same time. So try again, once or twice, but wait a little in between, longer - // each time. If we still haven't managed to create it after a few retries, - // error hard. - - if ( ++outboxDiscoveryRetries <= OUTBOX_DISCOVERY_RETRIES ) { - const int timeout = OUTBOX_DISCOVERY_WAIT_TIME * outboxDiscoveryRetries; - kWarning() << "Failed to get outbox folder. Retrying in: " << timeout; - QTimer::singleShot( timeout, q, SLOT(localFoldersChanged()) ); + if (SpecialMailCollections::self()->hasDefaultCollection(SpecialMailCollections::Outbox)) { + // Outbox is ready, init the queue from it. + const Collection collection = SpecialMailCollections::self()->defaultCollection(SpecialMailCollections::Outbox); + Q_ASSERT(collection.isValid()); + + if (outbox != collection) { + monitor->setCollectionMonitored(outbox, false); + monitor->setCollectionMonitored(collection, true); + outbox = collection; + qCDebug(MAILDISPATCHER_LOG) << "Changed outbox to" << outbox.id(); + initQueue(); + } } else { - kWarning() << "Failed to get outbox folder. Giving up."; ; - emit q->error( i18n( "Could not access the outbox folder (%1).", job->errorString() ) ); + // Outbox is not ready. Request it, since otherwise we will not know when + // new messages appear. + // (Note that we are a separate process, so we get no notification when + // MessageQueueJob requests the Outbox.) + monitor->setCollectionMonitored(outbox, false); + outbox = Collection(-1); + + SpecialMailCollectionsRequestJob *job = new SpecialMailCollectionsRequestJob(q); + job->requestDefaultCollection(SpecialMailCollections::Outbox); + connect(job, SIGNAL(result(KJob*)), q, SLOT(localFoldersRequestResult(KJob*))); + + qCDebug(MAILDISPATCHER_LOG) << "Requesting outbox folder."; + job->start(); } - return; - } - localFoldersChanged(); + // make sure we have a place to dump the sent mails as well + if (!SpecialMailCollections::self()->hasDefaultCollection(SpecialMailCollections::SentMail)) { + SpecialMailCollectionsRequestJob *job = new SpecialMailCollectionsRequestJob(q); + job->requestDefaultCollection(SpecialMailCollections::SentMail); + + qCDebug(MAILDISPATCHER_LOG) << "Requesting sent-mail folder"; + job->start(); + } } -void OutboxQueue::Private::itemAdded( const Item &item ) +void OutboxQueue::Private::localFoldersRequestResult(KJob *job) { - addIfComplete( item ); + if (job->error()) { + // We tried to create the outbox, but that failed. This could be because some + // other process, the mail app, for example, tried to create it at the + // same time. So try again, once or twice, but wait a little in between, longer + // each time. If we still haven't managed to create it after a few retries, + // error hard. + + if (++outboxDiscoveryRetries <= OUTBOX_DISCOVERY_RETRIES) { + const int timeout = OUTBOX_DISCOVERY_WAIT_TIME * outboxDiscoveryRetries; + qCWarning(MAILDISPATCHER_LOG) << "Failed to get outbox folder. Retrying in: " << timeout; + QTimer::singleShot(timeout, q, SLOT(localFoldersChanged())); + } else { + qCWarning(MAILDISPATCHER_LOG) << "Failed to get outbox folder. Giving up."; ; + Q_EMIT q->error(i18n("Could not access the outbox folder (%1).", job->errorString())); + } + return; + } + + localFoldersChanged(); } -void OutboxQueue::Private::itemChanged( const Item &item ) +void OutboxQueue::Private::itemAdded(const Item &item) { - addIfComplete( item ); - // TODO: if the item is moved out of the outbox, will I get itemChanged? + addIfComplete(item); } -void OutboxQueue::Private::itemMoved( const Item &item, const Collection &source, const Collection &destination ) +void OutboxQueue::Private::itemChanged(const Item &item) { - if ( source == outbox ) { - itemRemoved( item ); - } else if ( destination == outbox ) { - addIfComplete( item ); - } + addIfComplete(item); + // TODO: if the item is moved out of the outbox, will I get itemChanged? } -void OutboxQueue::Private::itemRemoved( const Item &removedItem ) +void OutboxQueue::Private::itemMoved(const Item &item, const Collection &source, const Collection &destination) { - // @p item has size=0, so get the size from our own copy. - const int index = queue.indexOf( removedItem ); - if ( index == -1 ) { - // Item was not in queue at all. - return; - } - - Item item( queue.takeAt( index ) ); - kDebug() << "Item" << item.id() << "(size" << item.size() << ") was removed from the queue."; - totalSize -= item.size(); - - futureItems.remove( removedItem ); + if (source == outbox) { + itemRemoved(item); + } else if (destination == outbox) { + addIfComplete(item); + } } -void OutboxQueue::Private::itemProcessed( const Item &item, bool result ) +void OutboxQueue::Private::itemRemoved(const Item &removedItem) { - Q_ASSERT( ignore.contains( item.id() ) ); - if ( !result ) { - // Give the user a chance to re-send the item if it failed. - ignore.remove( item.id() ); - } -} + // @p item has size=0, so get the size from our own copy. + const int index = queue.indexOf(removedItem); + if (index == -1) { + // Item was not in queue at all. + return; + } + Item item(queue.takeAt(index)); + qCDebug(MAILDISPATCHER_LOG) << "Item" << item.id() << "(size" << item.size() << ") was removed from the queue."; + totalSize -= item.size(); -OutboxQueue::OutboxQueue( QObject *parent ) - : QObject( parent ), - d( new Private( this ) ) -{ - d->monitor = new Monitor( this ); - d->monitor->itemFetchScope().fetchAllAttributes(); - d->monitor->itemFetchScope().fetchFullPayload( false ); - connect( d->monitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)), - this, SLOT(itemAdded(Akonadi::Item)) ); - connect( d->monitor, SIGNAL(itemChanged(Akonadi::Item,QSet)), - this, SLOT(itemChanged(Akonadi::Item)) ); - connect( d->monitor, SIGNAL(itemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)), - this, SLOT(itemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)) ); - connect( d->monitor, SIGNAL(itemRemoved(Akonadi::Item)), - this, SLOT(itemRemoved(Akonadi::Item)) ); + futureItems.remove(removedItem); +} - connect( SpecialMailCollections::self(), SIGNAL(defaultCollectionsChanged()), this, SLOT(localFoldersChanged()) ); - d->localFoldersChanged(); +void OutboxQueue::Private::itemProcessed(const Item &item, bool result) +{ + Q_ASSERT(ignore.contains(item.id())); + if (!result) { + // Give the user a chance to re-send the item if it failed. + ignore.remove(item.id()); + } +} - d->futureTimer = new QTimer( this ); - connect( d->futureTimer, SIGNAL(timeout()), this, SLOT(checkFuture()) ); - d->futureTimer->start( 60 * 60 * 1000 ); // 1 hour +OutboxQueue::OutboxQueue(QObject *parent) + : QObject(parent), + d(new Private(this)) +{ + d->monitor = new Monitor(this); + d->monitor->itemFetchScope().fetchAllAttributes(); + d->monitor->itemFetchScope().fetchFullPayload(false); + connect(d->monitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)), + this, SLOT(itemAdded(Akonadi::Item))); + connect(d->monitor, SIGNAL(itemChanged(Akonadi::Item,QSet)), + this, SLOT(itemChanged(Akonadi::Item))); + connect(d->monitor, SIGNAL(itemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)), + this, SLOT(itemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection))); + connect(d->monitor, SIGNAL(itemRemoved(Akonadi::Item)), + this, SLOT(itemRemoved(Akonadi::Item))); + + connect(SpecialMailCollections::self(), SIGNAL(defaultCollectionsChanged()), this, SLOT(localFoldersChanged())); + d->localFoldersChanged(); + + d->futureTimer = new QTimer(this); + connect(d->futureTimer, SIGNAL(timeout()), this, SLOT(checkFuture())); + d->futureTimer->start(60 * 60 * 1000); // 1 hour } OutboxQueue::~OutboxQueue() { - delete d; + delete d; } bool OutboxQueue::isEmpty() const { - return d->queue.isEmpty(); + return d->queue.isEmpty(); } int OutboxQueue::count() const { - if ( d->queue.count() == 0 ) { - // TODO Is this asking for too much? - Q_ASSERT( d->totalSize == 0 ); - } - return d->queue.count(); + if (d->queue.count() == 0) { + // TODO Is this asking for too much? + Q_ASSERT(d->totalSize == 0); + } + return d->queue.count(); } qulonglong OutboxQueue::totalSize() const { - return d->totalSize; + return d->totalSize; } void OutboxQueue::fetchOne() { - if ( isEmpty() ) { - kDebug() << "Empty queue."; - return; - } - - const Item item = d->queue.takeFirst(); - - d->totalSize -= item.size(); - Q_ASSERT( !d->ignore.contains( item.id() ) ); - d->ignore.insert( item.id() ); - - ItemFetchJob *job = new ItemFetchJob( item ); - job->fetchScope().fetchAllAttributes(); - job->fetchScope().fetchFullPayload(); - connect( job, SIGNAL(result(KJob*)), this, SLOT(itemFetched(KJob*)) ); + if (isEmpty()) { + qCDebug(MAILDISPATCHER_LOG) << "Empty queue."; + return; + } + + const Item item = d->queue.takeFirst(); + + d->totalSize -= item.size(); + Q_ASSERT(!d->ignore.contains(item.id())); + d->ignore.insert(item.id()); + + ItemFetchJob *job = new ItemFetchJob(item); + job->fetchScope().fetchAllAttributes(); + job->fetchScope().fetchFullPayload(); + connect(job, SIGNAL(result(KJob*)), this, SLOT(itemFetched(KJob*))); } #include "moc_outboxqueue.cpp" diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/outboxqueue.h kdepim-runtime-15.08.0/agents/maildispatcher/outboxqueue.h --- kdepim-runtime-4.14.6/agents/maildispatcher/outboxqueue.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/outboxqueue.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,29 +20,28 @@ #ifndef OUTBOXQUEUE_H #define OUTBOXQUEUE_H -#include +#include +#include -#include -#include +#include class KJob; - /** * @short Monitors the outbox collection and provides a queue of messages for the MDA to send. */ class OutboxQueue : public QObject { - Q_OBJECT - friend class MailDispatcherAgent; + Q_OBJECT + friend class MailDispatcherAgent; - public: +public: /** * Creates a new outbox queue. * * @param parent The parent object. */ - explicit OutboxQueue( QObject *parent = 0 ); + explicit OutboxQueue(QObject *parent = Q_NULLPTR); /** * Destroys the outbox queue. @@ -69,28 +68,27 @@ */ void fetchOne(); - Q_SIGNALS: - void itemReady( const Akonadi::Item &item ); +Q_SIGNALS: + void itemReady(const Akonadi::Item &item); void newItems(); - void error( const QString &error ); + void error(const QString &error); - private: +private: //@cond PRIVATE class Private; - Private* const d; + Private *const d; - Q_PRIVATE_SLOT( d, void checkFuture() ) - Q_PRIVATE_SLOT( d, void collectionFetched( KJob* ) ) - Q_PRIVATE_SLOT( d, void itemFetched( KJob* ) ) - Q_PRIVATE_SLOT( d, void localFoldersChanged() ) - Q_PRIVATE_SLOT( d, void localFoldersRequestResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void itemAdded( Akonadi::Item ) ) - Q_PRIVATE_SLOT( d, void itemChanged( Akonadi::Item ) ) - Q_PRIVATE_SLOT( d, void itemMoved( Akonadi::Item, Akonadi::Collection, Akonadi::Collection ) ) - Q_PRIVATE_SLOT( d, void itemRemoved( Akonadi::Item ) ) - Q_PRIVATE_SLOT( d, void itemProcessed( Akonadi::Item, bool ) ) + Q_PRIVATE_SLOT(d, void checkFuture()) + Q_PRIVATE_SLOT(d, void collectionFetched(KJob *)) + Q_PRIVATE_SLOT(d, void itemFetched(KJob *)) + Q_PRIVATE_SLOT(d, void localFoldersChanged()) + Q_PRIVATE_SLOT(d, void localFoldersRequestResult(KJob *)) + Q_PRIVATE_SLOT(d, void itemAdded(Akonadi::Item)) + Q_PRIVATE_SLOT(d, void itemChanged(Akonadi::Item)) + Q_PRIVATE_SLOT(d, void itemMoved(Akonadi::Item, Akonadi::Collection, Akonadi::Collection)) + Q_PRIVATE_SLOT(d, void itemRemoved(Akonadi::Item)) + Q_PRIVATE_SLOT(d, void itemProcessed(Akonadi::Item, bool)) //@endcond }; - #endif diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/sendjob.cpp kdepim-runtime-15.08.0/agents/maildispatcher/sendjob.cpp --- kdepim-runtime-4.14.6/agents/maildispatcher/sendjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/sendjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,20 +21,20 @@ #include "storeresultjob.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "maildispatcher_debug.h" #include #include #include @@ -59,14 +59,14 @@ */ class SendJob::Private { - public: - Private( const Item &itm, SendJob *qq ) - : q( qq ), - item( itm ), - currentJob( 0 ), - interface( 0 ), - mailfilterInterface( 0 ), - aborting( false ) +public: + Private(const Item &itm, SendJob *qq) + : q(qq), + item(itm), + currentJob(Q_NULLPTR), + interface(Q_NULLPTR), + mailfilterInterface(Q_NULLPTR), + aborting(false) { } @@ -80,409 +80,409 @@ void doAkonadiTransport(); void doTraditionalTransport(); - void doPostJob( bool transportSuccess, const QString &transportMessage ); - void storeResult( bool success, const QString &message = QString() ); + void doPostJob(bool transportSuccess, const QString &transportMessage); + void storeResult(bool success, const QString &message = QString()); void abortPostJob(); - bool filterItem( int filterset ); + bool filterItem(int filterset); // slots void doTransport(); - void transportPercent( KJob *job, unsigned long percent ); - void transportResult( KJob *job ); - void resourceProgress( const AgentInstance &instance ); - void resourceResult( qlonglong itemId, int result, const QString &message ); - void postJobResult( KJob *job ); - void doEmitResult( KJob *job ); - void slotSentMailCollectionFetched( KJob *job ); + void transportPercent(KJob *job, unsigned long percent); + void transportResult(KJob *job); + void resourceProgress(const AgentInstance &instance); + void resourceResult(qlonglong itemId, int result, const QString &message); + void postJobResult(KJob *job); + void doEmitResult(KJob *job); + void slotSentMailCollectionFetched(KJob *job); }; - void SendJob::Private::doTransport() { - kDebug() << "Transporting message."; + qCDebug(MAILDISPATCHER_LOG) << "Transporting message."; + + if (aborting) { + qCDebug(MAILDISPATCHER_LOG) << "Marking message as aborted."; + q->setError(UserDefinedError); + q->setErrorText(i18n("Message sending aborted.")); + storeResult(false, i18n("Message sending aborted.")); + return; + } + + // Is it an Akonadi transport or a traditional one? + const TransportAttribute *transportAttribute = item.attribute(); + Q_ASSERT(transportAttribute); + if (!transportAttribute->transport()) { + storeResult(false, i18n("Could not initiate message transport. Possibly invalid transport.")); + return; + } + + const TransportType type = transportAttribute->transport()->transportType(); + if (!type.isValid()) { + storeResult(false, i18n("Could not send message. Invalid transport.")); + return; + } + + if (!filterItem(8)) { //BeforeOutbound + return; + } - if ( aborting ) { - kDebug() << "Marking message as aborted."; - q->setError( UserDefinedError ); - q->setErrorText( i18n( "Message sending aborted." ) ); - storeResult( false, i18n( "Message sending aborted." ) ); - return; - } - - // Is it an Akonadi transport or a traditional one? - const TransportAttribute *transportAttribute = item.attribute(); - Q_ASSERT( transportAttribute ); - if ( !transportAttribute->transport() ) { - storeResult( false, i18n( "Could not initiate message transport. Possibly invalid transport." ) ); - return; - } - - const TransportType type = transportAttribute->transport()->transportType(); - if ( !type.isValid() ) { - storeResult( false, i18n( "Could not send message. Invalid transport." ) ); - return; - } - - if ( !filterItem( 8 ) ) //BeforeOutbound - return; - - if ( type.type() == Transport::EnumType::Akonadi ) { - // Send the item directly to the resource that will send it. - resourceId = transportAttribute->transport()->host(); - doAkonadiTransport(); - } else { - // Use a traditional transport job. - doTraditionalTransport(); - } + if (type.type() == Transport::EnumType::Akonadi) { + // Send the item directly to the resource that will send it. + resourceId = transportAttribute->transport()->host(); + doAkonadiTransport(); + } else { + // Use a traditional transport job. + doTraditionalTransport(); + } } void SendJob::Private::doAkonadiTransport() { - Q_ASSERT( !resourceId.isEmpty() ); - Q_ASSERT( interface == 0 ); + Q_ASSERT(!resourceId.isEmpty()); + Q_ASSERT(interface == 0); + + interface = new QDBusInterface( + QLatin1String("org.freedesktop.Akonadi.Resource.") + resourceId, + QLatin1String("/Transport"), QStringLiteral("org.freedesktop.Akonadi.Resource.Transport"), + KDBusConnectionPool::threadConnection(), q); + + if (!interface->isValid()) { + storeResult(false, i18n("Failed to get D-Bus interface of resource %1.", resourceId)); + delete interface; + interface = Q_NULLPTR; + return; + } - interface = new QDBusInterface( - QLatin1String( "org.freedesktop.Akonadi.Resource." ) + resourceId, - QLatin1String( "/Transport" ), QLatin1String( "org.freedesktop.Akonadi.Resource.Transport" ), - DBusConnectionPool::threadConnection(), q ); - - if ( !interface->isValid() ) { - storeResult( false, i18n( "Failed to get D-Bus interface of resource %1.", resourceId ) ); - delete interface; - interface = 0; - return; - } - - // Signals. - QObject::connect( AgentManager::self(), SIGNAL(instanceProgressChanged(Akonadi::AgentInstance)), - q, SLOT(resourceProgress(Akonadi::AgentInstance)) ); - QObject::connect( interface, SIGNAL(transportResult(qlonglong,int,QString)), - q, SLOT(resourceResult(qlonglong,int,QString)) ); - - // Start sending. - const QDBusReply reply = interface->call( QLatin1String( "send" ), item.id() ); - if ( !reply.isValid() ) { - storeResult( false, i18n( "Invalid D-Bus reply from resource %1.", resourceId ) ); - return; - } + // Signals. + QObject::connect(AgentManager::self(), SIGNAL(instanceProgressChanged(Akonadi::AgentInstance)), + q, SLOT(resourceProgress(Akonadi::AgentInstance))); + QObject::connect(interface, SIGNAL(transportResult(qlonglong,int,QString)), + q, SLOT(resourceResult(qlonglong,int,QString))); + + // Start sending. + const QDBusReply reply = interface->call(QLatin1String("send"), item.id()); + if (!reply.isValid()) { + storeResult(false, i18n("Invalid D-Bus reply from resource %1.", resourceId)); + return; + } } void SendJob::Private::doTraditionalTransport() { - const TransportAttribute *transportAttribute = item.attribute(); - TransportJob *job = TransportManager::self()->createTransportJob( transportAttribute->transportId() ); + const TransportAttribute *transportAttribute = item.attribute(); + TransportJob *job = TransportManager::self()->createTransportJob(transportAttribute->transportId()); - Q_ASSERT( job ); - Q_ASSERT( currentJob == 0 ); + Q_ASSERT(job); + Q_ASSERT(currentJob == 0); - currentJob = job; + currentJob = job; - // Message. - Q_ASSERT( item.hasPayload() ); - const Message::Ptr message = item.payload(); - bool needAssemble = false; - if ( message->hasHeader( "Bcc" ) ) { - message->removeHeader( "Bcc" ); - needAssemble = true; - } - if( message->hasHeader( "X-KMail-Identity" ) ) { - message->removeHeader( "X-KMail-Identity" ); - needAssemble = true; - } - if ( message->hasHeader( "X-KMail-Dictionary") ) { - message->removeHeader( "X-KMail-Dictionary" ); - needAssemble = true; - } - if(needAssemble) { - message->assemble(); - } - const QByteArray content = message->encodedContent( true ) + "\r\n"; - Q_ASSERT( !content.isEmpty() ); - - // Addresses. - const AddressAttribute *addressAttribute = item.attribute(); - Q_ASSERT( addressAttribute ); - - job->setData( content ); - job->setSender( addressAttribute->from() ); - job->setTo( addressAttribute->to() ); - job->setCc( addressAttribute->cc() ); - job->setBcc( addressAttribute->bcc() ); - - // Signals. - connect( job, SIGNAL(result(KJob*)), - q, SLOT(transportResult(KJob*)) ); - connect( job, SIGNAL(percent(KJob*,ulong)), - q, SLOT(transportPercent(KJob*,ulong)) ); - - job->start(); -} - -void SendJob::Private::transportPercent( KJob *job, unsigned long ) -{ - Q_ASSERT( currentJob == job ); - kDebug() << "Processed amount" << job->processedAmount( KJob::Bytes ) - << "total amount" << job->totalAmount( KJob::Bytes ); - - q->setTotalAmount( KJob::Bytes, job->totalAmount( KJob::Bytes ) ); // Is not set at the time of start(). - q->setProcessedAmount( KJob::Bytes, job->processedAmount( KJob::Bytes ) ); -} - -void SendJob::Private::transportResult( KJob *job ) -{ - Q_ASSERT( currentJob == job ); - currentJob = 0; - doPostJob( !job->error(), job->errorString() ); -} - -void SendJob::Private::resourceProgress( const AgentInstance &instance ) -{ - if ( !interface ) { - // We might have gotten a very late signal. - kWarning() << "called but no resource job running!"; - return; - } - - if ( instance.identifier() == resourceId ) { - // This relies on the resource's progress representing the progress of - // sending this item. - q->setPercent( instance.progress() ); - } -} - -void SendJob::Private::resourceResult( qlonglong itemId, int result, - const QString &message ) -{ - Q_UNUSED( itemId ); - Q_ASSERT( interface ); - delete interface; // So that abort() knows the transport job is over. - interface = 0; + // Message. + Q_ASSERT(item.hasPayload()); + const Message::Ptr message = item.payload(); + bool needAssemble = false; + if (message->hasHeader("Bcc")) { + message->removeHeader("Bcc"); + needAssemble = true; + } + if (message->hasHeader("X-KMail-Identity")) { + message->removeHeader("X-KMail-Identity"); + needAssemble = true; + } + if (message->hasHeader("X-KMail-Dictionary")) { + message->removeHeader("X-KMail-Dictionary"); + needAssemble = true; + } + + if (needAssemble) { + message->assemble(); + } + const QByteArray content = message->encodedContent(true) + "\r\n"; + Q_ASSERT(!content.isEmpty()); + + // Addresses. + const AddressAttribute *addressAttribute = item.attribute(); + Q_ASSERT(addressAttribute); - const TransportResourceBase::TransportResult transportResult = - static_cast( result ); + job->setData(content); + job->setSender(addressAttribute->from()); + job->setTo(addressAttribute->to()); + job->setCc(addressAttribute->cc()); + job->setBcc(addressAttribute->bcc()); - const bool success = ( transportResult == TransportResourceBase::TransportSucceeded ); + // Signals. + connect(job, SIGNAL(result(KJob*)), + q, SLOT(transportResult(KJob*))); + connect(job, SIGNAL(percent(KJob*,ulong)), + q, SLOT(transportPercent(KJob*,ulong))); - Q_ASSERT( itemId == item.id() ); - doPostJob( success, message ); + job->start(); } -void SendJob::Private::abortPostJob() +void SendJob::Private::transportPercent(KJob *job, unsigned long) { - // We were unlucky and LocalFolders is recreating its stuff right now. - // We will not wait for it. - kWarning() << "Default sent mail collection unavailable, not moving the mail after sending."; - q->setError( UserDefinedError ); - q->setErrorText( i18n( "Default sent-mail folder unavailable. Keeping message in outbox." ) ); - storeResult( false, q->errorString() ); + Q_ASSERT(currentJob == job); + qCDebug(MAILDISPATCHER_LOG) << "Processed amount" << job->processedAmount(KJob::Bytes) + << "total amount" << job->totalAmount(KJob::Bytes); + + q->setTotalAmount(KJob::Bytes, job->totalAmount(KJob::Bytes)); // Is not set at the time of start(). + q->setProcessedAmount(KJob::Bytes, job->processedAmount(KJob::Bytes)); } -void SendJob::Private::doPostJob( bool transportSuccess, const QString &transportMessage ) +void SendJob::Private::transportResult(KJob *job) { - kDebug() << "success" << transportSuccess << "message" << transportMessage; + Q_ASSERT(currentJob == job); + currentJob = Q_NULLPTR; + doPostJob(!job->error(), job->errorString()); +} - if ( !transportSuccess ) { - kDebug() << "Error transporting."; - q->setError( UserDefinedError ); +void SendJob::Private::resourceProgress(const AgentInstance &instance) +{ + if (!interface) { + // We might have gotten a very late signal. + qCWarning(MAILDISPATCHER_LOG) << "called but no resource job running!"; + return; + } - const QString error = aborting ? i18n( "Message transport aborted." ) - : i18n( "Failed to transport message." ); + if (instance.identifier() == resourceId) { + // This relies on the resource's progress representing the progress of + // sending this item. + q->setPercent(instance.progress()); + } +} - q->setErrorText( error + QLatin1Char(' ') + transportMessage ); - storeResult( false, q->errorString() ); - } else { - kDebug() << "Success transporting."; +void SendJob::Private::resourceResult(qlonglong itemId, int result, + const QString &message) +{ + Q_UNUSED(itemId); + Q_ASSERT(interface); + delete interface; // So that abort() knows the transport job is over. + interface = Q_NULLPTR; - // Delete or move to sent-mail. - const SentBehaviourAttribute *attribute = item.attribute(); - Q_ASSERT( attribute ); + const TransportResourceBase::TransportResult transportResult = + static_cast(result); + + const bool success = (transportResult == TransportResourceBase::TransportSucceeded); - if ( attribute->sentBehaviour() == SentBehaviourAttribute::Delete ) { - kDebug() << "Deleting item from outbox."; - currentJob = new ItemDeleteJob( item ); - QObject::connect( currentJob, SIGNAL(result(KJob*)), q, SLOT(postJobResult(KJob*)) ); + Q_ASSERT(itemId == item.id()); + doPostJob(success, message); +} + +void SendJob::Private::abortPostJob() +{ + // We were unlucky and LocalFolders is recreating its stuff right now. + // We will not wait for it. + qCWarning(MAILDISPATCHER_LOG) << "Default sent mail collection unavailable, not moving the mail after sending."; + q->setError(UserDefinedError); + q->setErrorText(i18n("Default sent-mail folder unavailable. Keeping message in outbox.")); + storeResult(false, q->errorString()); +} + +void SendJob::Private::doPostJob(bool transportSuccess, const QString &transportMessage) +{ + qCDebug(MAILDISPATCHER_LOG) << "success" << transportSuccess << "message" << transportMessage; + + if (!transportSuccess) { + qCDebug(MAILDISPATCHER_LOG) << "Error transporting."; + q->setError(UserDefinedError); + + const QString error = aborting ? i18n("Message transport aborted.") + : i18n("Failed to transport message."); + + q->setErrorText(error + QLatin1Char(' ') + transportMessage); + storeResult(false, q->errorString()); } else { - if ( attribute->sentBehaviour() == SentBehaviourAttribute::MoveToDefaultSentCollection ) { - if ( SpecialMailCollections::self()->hasDefaultCollection( SpecialMailCollections::SentMail ) ) { - currentJob = new ItemMoveJob( item, SpecialMailCollections::self()->defaultCollection( SpecialMailCollections::SentMail ) , q ); - QObject::connect( currentJob, SIGNAL(result(KJob*)), q, SLOT(postJobResult(KJob*)) ); + qCDebug(MAILDISPATCHER_LOG) << "Success transporting."; + + // Delete or move to sent-mail. + const SentBehaviourAttribute *attribute = item.attribute(); + Q_ASSERT(attribute); + + if (attribute->sentBehaviour() == SentBehaviourAttribute::Delete) { + qCDebug(MAILDISPATCHER_LOG) << "Deleting item from outbox."; + currentJob = new ItemDeleteJob(item); + QObject::connect(currentJob, SIGNAL(result(KJob*)), q, SLOT(postJobResult(KJob*))); } else { - abortPostJob(); - } - } else { - kDebug() << "sentBehaviour=" << attribute->sentBehaviour() << "using collection from attribute"; - currentJob = new CollectionFetchJob( attribute->moveToCollection(), Akonadi::CollectionFetchJob::Base ); - QObject::connect( currentJob, SIGNAL(result(KJob*)), - q, SLOT(slotSentMailCollectionFetched(KJob*)) ); + if (attribute->sentBehaviour() == SentBehaviourAttribute::MoveToDefaultSentCollection) { + if (SpecialMailCollections::self()->hasDefaultCollection(SpecialMailCollections::SentMail)) { + currentJob = new ItemMoveJob(item, SpecialMailCollections::self()->defaultCollection(SpecialMailCollections::SentMail) , q); + QObject::connect(currentJob, SIGNAL(result(KJob*)), q, SLOT(postJobResult(KJob*))); + } else { + abortPostJob(); + } + } else { + qCDebug(MAILDISPATCHER_LOG) << "sentBehaviour=" << attribute->sentBehaviour() << "using collection from attribute"; + currentJob = new CollectionFetchJob(attribute->moveToCollection(), Akonadi::CollectionFetchJob::Base); + QObject::connect(currentJob, SIGNAL(result(KJob*)), + q, SLOT(slotSentMailCollectionFetched(KJob*))); - } + } + } } - } } -bool SendJob::Private::filterItem( int filterset ) +bool SendJob::Private::filterItem(int filterset) { - Q_ASSERT( mailfilterInterface == 0 ); + Q_ASSERT(mailfilterInterface == 0); - // TODO: create on stack - mailfilterInterface = new QDBusInterface( - QLatin1String( "org.freedesktop.Akonadi.MailFilterAgent" ), - QLatin1String( "/MailFilterAgent" ), QLatin1String( "org.freedesktop.Akonadi.MailFilterAgent" ), - DBusConnectionPool::threadConnection(), q ); + // TODO: create on stack + mailfilterInterface = new QDBusInterface( + QLatin1String("org.freedesktop.Akonadi.MailFilterAgent"), + QLatin1String("/MailFilterAgent"), QStringLiteral("org.freedesktop.Akonadi.MailFilterAgent"), + KDBusConnectionPool::threadConnection(), q); + + if (!mailfilterInterface->isValid()) { + storeResult(false, i18n("Failed to get D-Bus interface of mailfilteragent.")); + delete mailfilterInterface; + mailfilterInterface = Q_NULLPTR; + return false; + } + //Outbound = 0x2 + const QDBusReply reply = mailfilterInterface->call(QLatin1String("filterItem"), item.id(), filterset, QString()); + if (!reply.isValid()) { + storeResult(false, i18n("Invalid D-Bus reply from mailfilteragent")); + delete mailfilterInterface; + mailfilterInterface = Q_NULLPTR; + return false; + } - if ( !mailfilterInterface->isValid() ) { - storeResult( false, i18n( "Failed to get D-Bus interface of mailfilteragent." ) ); - delete mailfilterInterface; - mailfilterInterface = 0; - return false; - } - - //Outbound = 0x2 - const QDBusReply reply = mailfilterInterface->call( QLatin1String( "filterItem" ), item.id(), filterset, QString() ); - if ( !reply.isValid() ) { - storeResult( false, i18n( "Invalid D-Bus reply from mailfilteragent" ) ); delete mailfilterInterface; - mailfilterInterface = 0; - return false; - } - - delete mailfilterInterface; - mailfilterInterface = 0; - return true; + mailfilterInterface = Q_NULLPTR; + return true; } -void SendJob::Private::slotSentMailCollectionFetched(KJob* job) +void SendJob::Private::slotSentMailCollectionFetched(KJob *job) { - Akonadi::Collection fetchCol; - bool ok = false; - if ( !job->error() ) { - const CollectionFetchJob *const fetchJob = qobject_cast( job ); - if ( !fetchJob->collections().isEmpty() ) { - fetchCol = fetchJob->collections().first(); - ok = true; + Akonadi::Collection fetchCol; + bool ok = false; + if (!job->error()) { + const CollectionFetchJob *const fetchJob = qobject_cast(job); + if (!fetchJob->collections().isEmpty()) { + fetchCol = fetchJob->collections().at(0); + ok = true; + } } - } - if ( !ok ) { - if ( !SpecialMailCollections::self()->hasDefaultCollection( SpecialMailCollections::SentMail ) ) { - abortPostJob(); - return; + if (!ok) { + if (!SpecialMailCollections::self()->hasDefaultCollection(SpecialMailCollections::SentMail)) { + abortPostJob(); + return; + } + fetchCol = SpecialMailCollections::self()->defaultCollection(SpecialMailCollections::SentMail); } - fetchCol = SpecialMailCollections::self()->defaultCollection( SpecialMailCollections::SentMail ); - } - currentJob = new ItemMoveJob( item, fetchCol, q ); - QObject::connect( currentJob, SIGNAL(result(KJob*)), q, SLOT(postJobResult(KJob*)) ); + currentJob = new ItemMoveJob(item, fetchCol, q); + QObject::connect(currentJob, SIGNAL(result(KJob*)), q, SLOT(postJobResult(KJob*))); } -void SendJob::Private::postJobResult( KJob *job ) +void SendJob::Private::postJobResult(KJob *job) { - Q_ASSERT( currentJob == job ); - currentJob = 0; - const SentBehaviourAttribute *attribute = item.attribute(); - Q_ASSERT( attribute ); - + Q_ASSERT(currentJob == job); + currentJob = Q_NULLPTR; + const SentBehaviourAttribute *attribute = item.attribute(); + Q_ASSERT(attribute); - if ( job->error() ) { - kDebug() << "Error deleting or moving to sent-mail."; + if (job->error()) { + qCDebug(MAILDISPATCHER_LOG) << "Error deleting or moving to sent-mail."; - QString errorString; - switch( attribute->sentBehaviour() ) { - case SentBehaviourAttribute::Delete: - errorString = - i18n( "Sending succeeded, but failed to remove the message from the outbox." ); - break; - default: - errorString = - i18n( "Sending succeeded, but failed to move the message to the sent-mail folder." ); - break; + QString errorString; + switch (attribute->sentBehaviour()) { + case SentBehaviourAttribute::Delete: + errorString = + i18n("Sending succeeded, but failed to remove the message from the outbox."); + break; + default: + errorString = + i18n("Sending succeeded, but failed to move the message to the sent-mail folder."); + break; + } + q->setError(UserDefinedError); + q->setErrorText(errorString + QLatin1Char(' ') + job->errorString()); + storeResult(false, q->errorString()); + } else { + qCDebug(MAILDISPATCHER_LOG) << "Success deleting or moving to sent-mail."; + if (!filterItem(2)) { //Outbound + return; + } + if (attribute->sentBehaviour() == SentBehaviourAttribute::Delete) { + q->emitResult(); + } else { + storeResult(true); + } } - q->setError( UserDefinedError ); - q->setErrorText( errorString + QLatin1Char(' ') + job->errorString() ); - storeResult( false, q->errorString() ); - } else { - kDebug() << "Success deleting or moving to sent-mail."; - if ( !filterItem( 2 ) ) //Outbound - return; - if ( attribute->sentBehaviour() == SentBehaviourAttribute::Delete ) - q->emitResult(); - else - storeResult( true ); - } } -void SendJob::Private::storeResult( bool success, const QString &message ) +void SendJob::Private::storeResult(bool success, const QString &message) { - kDebug() << "success" << success << "message" << message; + qCDebug(MAILDISPATCHER_LOG) << "success" << success << "message" << message; - Q_ASSERT( currentJob == 0 ); - currentJob = new StoreResultJob( item, success, message ); - connect( currentJob, SIGNAL(result(KJob*)), q, SLOT(doEmitResult(KJob*)) ); + Q_ASSERT(currentJob == 0); + currentJob = new StoreResultJob(item, success, message); + connect(currentJob, SIGNAL(result(KJob*)), q, SLOT(doEmitResult(KJob*))); } -void SendJob::Private::doEmitResult( KJob *job ) +void SendJob::Private::doEmitResult(KJob *job) { - Q_ASSERT( currentJob == job ); - currentJob = 0; + Q_ASSERT(currentJob == job); + currentJob = Q_NULLPTR; - if ( job->error() ) { - kWarning() << "Error storing result."; - q->setError( UserDefinedError ); - q->setErrorText( q->errorString() + QLatin1Char(' ') + i18n( "Failed to store result in item." ) + QLatin1Char(' ') + job->errorString() ); - } else { - kDebug() << "Success storing result."; - // It is still possible that the transport failed. - StoreResultJob* srJob = static_cast( job ); - if ( !srJob->success() ) { - q->setError( UserDefinedError ); - q->setErrorText( srJob->message() ); + if (job->error()) { + qCWarning(MAILDISPATCHER_LOG) << "Error storing result."; + q->setError(UserDefinedError); + q->setErrorText(q->errorString() + QLatin1Char(' ') + i18n("Failed to store result in item.") + QLatin1Char(' ') + job->errorString()); + } else { + qCDebug(MAILDISPATCHER_LOG) << "Success storing result."; + // It is still possible that the transport failed. + StoreResultJob *srJob = static_cast(job); + if (!srJob->success()) { + q->setError(UserDefinedError); + q->setErrorText(srJob->message()); + } } - } - q->emitResult(); + q->emitResult(); } - -SendJob::SendJob( const Item &item, QObject *parent ) - : KJob( parent ), - d( new Private( item, this ) ) +SendJob::SendJob(const Item &item, QObject *parent) + : KJob(parent), + d(new Private(item, this)) { } SendJob::~SendJob() { - delete d; + delete d; } void SendJob::start() { - QTimer::singleShot( 0, this, SLOT(doTransport()) ); + QTimer::singleShot(0, this, SLOT(doTransport())); } void SendJob::setMarkAborted() { - Q_ASSERT( !d->aborting ); - d->aborting = true; + Q_ASSERT(!d->aborting); + d->aborting = true; } void SendJob::abort() { - setMarkAborted(); + setMarkAborted(); - if ( dynamic_cast( d->currentJob ) ) { - kDebug() << "Abort called, active transport job."; - // Abort transport. - d->currentJob->kill( KJob::EmitResult ); - } else if ( d->interface != 0 ) { - kDebug() << "Abort called, propagating to resource."; - // Abort resource doing transport. - AgentInstance instance = AgentManager::self()->instance( d->resourceId ); - instance.abortCurrentTask(); - } else { - kDebug() << "Abort called, but no transport job is active."; - // Either transport has not started, in which case doTransport will - // mark the item as aborted, or the item has already been sent, in which - // case there is nothing we can do. - } + if (dynamic_cast(d->currentJob)) { + qCDebug(MAILDISPATCHER_LOG) << "Abort called, active transport job."; + // Abort transport. + d->currentJob->kill(KJob::EmitResult); + } else if (d->interface != Q_NULLPTR) { + qCDebug(MAILDISPATCHER_LOG) << "Abort called, propagating to resource."; + // Abort resource doing transport. + AgentInstance instance = AgentManager::self()->instance(d->resourceId); + instance.abortCurrentTask(); + } else { + qCDebug(MAILDISPATCHER_LOG) << "Abort called, but no transport job is active."; + // Either transport has not started, in which case doTransport will + // mark the item as aborted, or the item has already been sent, in which + // case there is nothing we can do. + } } #include "moc_sendjob.cpp" diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/sendjob.h kdepim-runtime-15.08.0/agents/maildispatcher/sendjob.h --- kdepim-runtime-4.14.6/agents/maildispatcher/sendjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/sendjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,7 +22,8 @@ #include -namespace Akonadi { +namespace Akonadi +{ class Item; } @@ -35,16 +36,16 @@ */ class SendJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new send job. * * @param item The item to send. * @param parent The parent object. */ - explicit SendJob( const Akonadi::Item &item, QObject *parent = 0 ); + explicit SendJob(const Akonadi::Item &item, QObject *parent = Q_NULLPTR); /** * Destroys the send job. @@ -54,7 +55,7 @@ /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * If this function is called before the job is started, the SendJob will @@ -71,21 +72,20 @@ */ void abort(); - private: +private: //@cond PRIVATE class Private; Private *const d; - Q_PRIVATE_SLOT( d, void doTransport() ) - Q_PRIVATE_SLOT( d, void transportPercent( KJob*, unsigned long ) ) - Q_PRIVATE_SLOT( d, void transportResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void resourceProgress( const Akonadi::AgentInstance& ) ) - Q_PRIVATE_SLOT( d, void resourceResult( qlonglong, int, const QString& ) ) - Q_PRIVATE_SLOT( d, void postJobResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void doEmitResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void slotSentMailCollectionFetched( KJob* ) ) + Q_PRIVATE_SLOT(d, void doTransport()) + Q_PRIVATE_SLOT(d, void transportPercent(KJob *, unsigned long)) + Q_PRIVATE_SLOT(d, void transportResult(KJob *)) + Q_PRIVATE_SLOT(d, void resourceProgress(const Akonadi::AgentInstance &)) + Q_PRIVATE_SLOT(d, void resourceResult(qlonglong, int, const QString &)) + Q_PRIVATE_SLOT(d, void postJobResult(KJob *)) + Q_PRIVATE_SLOT(d, void doEmitResult(KJob *)) + Q_PRIVATE_SLOT(d, void slotSentMailCollectionFetched(KJob *)) //@endcond }; - #endif diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/sentactionhandler.cpp kdepim-runtime-15.08.0/agents/maildispatcher/sentactionhandler.cpp --- kdepim-runtime-4.14.6/agents/maildispatcher/sentactionhandler.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/sentactionhandler.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,50 +21,52 @@ #include "sentactionhandler.h" -#include -#include -#include +#include +#include +#include +#include "maildispatcher_debug.h" using namespace MailTransport; -SentActionHandler::SentActionHandler( QObject *parent ) - : QObject( parent ) +SentActionHandler::SentActionHandler(QObject *parent) + : QObject(parent) { } -void SentActionHandler::runAction( const SentActionAttribute::Action &action ) +void SentActionHandler::runAction(const SentActionAttribute::Action &action) { - if ( action.type() == SentActionAttribute::Action::MarkAsReplied || - action.type() == SentActionAttribute::Action::MarkAsForwarded ) { + if (action.type() == SentActionAttribute::Action::MarkAsReplied || + action.type() == SentActionAttribute::Action::MarkAsForwarded) { - const Akonadi::Item item( action.value().toLongLong() ); - Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( item ); - connect( job, SIGNAL(result(KJob*)), SLOT(itemFetchResult(KJob*)) ); - job->setProperty( "type", static_cast( action.type() ) ); - } + const Akonadi::Item item(action.value().toLongLong()); + Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob(item); + connect(job, &Akonadi::ItemFetchJob::result, this, &SentActionHandler::itemFetchResult); + job->setProperty("type", static_cast(action.type())); + } } -void SentActionHandler::itemFetchResult( KJob *job ) +void SentActionHandler::itemFetchResult(KJob *job) { - if ( job->error() ) { - kWarning() << job->errorText(); - return; - } - - Akonadi::ItemFetchJob *fetchJob = qobject_cast( job ); - if ( fetchJob->items().isEmpty() ) - return; - - Akonadi::Item item = fetchJob->items().first(); - - const SentActionAttribute::Action::Type type = static_cast( job->property( "type" ).toInt() ); - if ( type == SentActionAttribute::Action::MarkAsReplied ) { - item.setFlag( Akonadi::MessageFlags::Replied ); - } else if ( type == SentActionAttribute::Action::MarkAsForwarded ) { - item.setFlag( Akonadi::MessageFlags::Forwarded ); - } + if (job->error()) { + qCWarning(MAILDISPATCHER_LOG) << job->errorText(); + return; + } + + Akonadi::ItemFetchJob *fetchJob = qobject_cast(job); + if (fetchJob->items().isEmpty()) { + return; + } + + Akonadi::Item item = fetchJob->items().at(0); + + const SentActionAttribute::Action::Type type = static_cast(job->property("type").toInt()); + if (type == SentActionAttribute::Action::MarkAsReplied) { + item.setFlag(Akonadi::MessageFlags::Replied); + } else if (type == SentActionAttribute::Action::MarkAsForwarded) { + item.setFlag(Akonadi::MessageFlags::Forwarded); + } - Akonadi::ItemModifyJob *modifyJob = new Akonadi::ItemModifyJob( item ); - modifyJob->setIgnorePayload( true ); + Akonadi::ItemModifyJob *modifyJob = new Akonadi::ItemModifyJob(item); + modifyJob->setIgnorePayload(true); } diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/sentactionhandler.h kdepim-runtime-15.08.0/agents/maildispatcher/sentactionhandler.h --- kdepim-runtime-4.14.6/agents/maildispatcher/sentactionhandler.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/sentactionhandler.h 2015-08-10 21:01:02.000000000 +0000 @@ -30,15 +30,15 @@ class SentActionHandler : public QObject { - Q_OBJECT + Q_OBJECT - public: - explicit SentActionHandler( QObject *parent = 0 ); +public: + explicit SentActionHandler(QObject *parent = Q_NULLPTR); - void runAction( const MailTransport::SentActionAttribute::Action &action ); + void runAction(const MailTransport::SentActionAttribute::Action &action); - private Q_SLOTS: - void itemFetchResult( KJob *job ); +private Q_SLOTS: + void itemFetchResult(KJob *job); }; #endif diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/storeresultjob.cpp kdepim-runtime-15.08.0/agents/maildispatcher/storeresultjob.cpp --- kdepim-runtime-4.14.6/agents/maildispatcher/storeresultjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/storeresultjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,11 +19,11 @@ #include "storeresultjob.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include "maildispatcher_debug.h" #include #include #include @@ -36,9 +36,9 @@ */ class StoreResultJob::Private { - public: - Private( StoreResultJob *qq ) - : q( qq ), success( false ) +public: + Private(StoreResultJob *qq) + : q(qq), success(false) { } @@ -47,94 +47,94 @@ bool success; QString message; - // slots: - void fetchDone( KJob *job ); - void modifyDone( KJob *job ); + // Q_SLOTS: + void fetchDone(KJob *job); + void modifyDone(KJob *job); }; - -void StoreResultJob::Private::fetchDone( KJob *job ) +void StoreResultJob::Private::fetchDone(KJob *job) { - if ( job->error() ) - return; + if (job->error()) { + return; + } - kDebug(); + qCDebug(MAILDISPATCHER_LOG); - const ItemFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob ); - if ( fetchJob->items().count() != 1 ) { - kError() << "Fetched" << fetchJob->items().count() << "items, expected 1."; - q->setError( Unknown ); - q->setErrorText( i18n( "Failed to fetch item." ) ); - q->commit(); - return; - } + const ItemFetchJob *fetchJob = qobject_cast(job); + Q_ASSERT(fetchJob); + if (fetchJob->items().count() != 1) { + qCritical() << "Fetched" << fetchJob->items().count() << "items, expected 1."; + q->setError(Unknown); + q->setErrorText(i18n("Failed to fetch item.")); + q->commit(); + return; + } - // Store result in item. - Item item = fetchJob->items().first(); - if ( success ) { - item.clearFlag( Akonadi::MessageFlags::Queued ); - item.setFlag( Akonadi::MessageFlags::Sent ); - item.setFlag( Akonadi::MessageFlags::Seen ); - } else { - item.setFlag( Akonadi::MessageFlags::HasError ); - ErrorAttribute *errorAttribute = new ErrorAttribute( message ); - item.addAttribute( errorAttribute ); - - // If dispatch failed, set the DispatchModeAttribute to Manual. - // Otherwise, the user will *never* be able to try sending the mail again, - // as Send Queued Messages will ignore it. - if ( item.hasAttribute() ) { - item.attribute()->setDispatchMode( MailTransport::DispatchModeAttribute::Manual ); + // Store result in item. + Item item = fetchJob->items().at(0); + if (success) { + item.clearFlag(Akonadi::MessageFlags::Queued); + item.setFlag(Akonadi::MessageFlags::Sent); + item.setFlag(Akonadi::MessageFlags::Seen); } else { - item.addAttribute( new DispatchModeAttribute( MailTransport::DispatchModeAttribute::Manual ) ); + item.setFlag(Akonadi::MessageFlags::HasError); + ErrorAttribute *errorAttribute = new ErrorAttribute(message); + item.addAttribute(errorAttribute); + + // If dispatch failed, set the DispatchModeAttribute to Manual. + // Otherwise, the user will *never* be able to try sending the mail again, + // as Send Queued Messages will ignore it. + if (item.hasAttribute()) { + item.attribute()->setDispatchMode(MailTransport::DispatchModeAttribute::Manual); + } else { + item.addAttribute(new DispatchModeAttribute(MailTransport::DispatchModeAttribute::Manual)); + } } - } - ItemModifyJob *modifyJob = new ItemModifyJob( item, q ); - QObject::connect( modifyJob, SIGNAL(result(KJob*)), q, SLOT(modifyDone(KJob*)) ); + ItemModifyJob *modifyJob = new ItemModifyJob(item, q); + QObject::connect(modifyJob, SIGNAL(result(KJob*)), q, SLOT(modifyDone(KJob*))); } -void StoreResultJob::Private::modifyDone( KJob *job ) +void StoreResultJob::Private::modifyDone(KJob *job) { - if ( job->error() ) - return; + if (job->error()) { + return; + } - kDebug(); + qCDebug(MAILDISPATCHER_LOG); - q->commit(); + q->commit(); } - -StoreResultJob::StoreResultJob( const Item &item, bool success, const QString &message, QObject *parent ) - : TransactionSequence( parent ), - d( new Private( this ) ) -{ - d->item = item; - d->success = success; - d->message = message; +StoreResultJob::StoreResultJob(const Item &item, bool success, const QString &message, QObject *parent) + : TransactionSequence(parent), + d(new Private(this)) +{ + d->item = item; + d->success = success; + d->message = message; } StoreResultJob::~StoreResultJob() { - delete d; + delete d; } void StoreResultJob::doStart() { - // Fetch item in case it was modified elsewhere. - ItemFetchJob *job = new ItemFetchJob( d->item, this ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(fetchDone(KJob*)) ); + // Fetch item in case it was modified elsewhere. + ItemFetchJob *job = new ItemFetchJob(d->item, this); + connect(job, SIGNAL(result(KJob*)), this, SLOT(fetchDone(KJob*))); } bool StoreResultJob::success() const { - return d->success; + return d->success; } QString StoreResultJob::message() const { - return d->message; + return d->message; } #include "moc_storeresultjob.cpp" diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/storeresultjob.h kdepim-runtime-15.08.0/agents/maildispatcher/storeresultjob.h --- kdepim-runtime-4.14.6/agents/maildispatcher/storeresultjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/storeresultjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,11 +20,12 @@ #ifndef STORERESULTJOB_H #define STORERESULTJOB_H -#include +#include #include -namespace Akonadi { +namespace Akonadi +{ class Item; } @@ -36,9 +37,9 @@ */ class StoreResultJob : public Akonadi::TransactionSequence { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new store result job. * @@ -47,7 +48,7 @@ * @param message An error message in case the mail could not be dispatched. * @param parent The parent object. */ - explicit StoreResultJob( const Akonadi::Item &item, bool success, const QString &message, QObject *parent = 0 ); + explicit StoreResultJob(const Akonadi::Item &item, bool success, const QString &message, QObject *parent = Q_NULLPTR); /** * Destroys the store result job. @@ -57,17 +58,17 @@ bool success() const; QString message() const; - protected: +protected: // reimpl from TransactionSequence - virtual void doStart(); + void doStart() Q_DECL_OVERRIDE; - private: +private: //@cond PRIVATE class Private; Private *const d; - Q_PRIVATE_SLOT( d, void fetchDone( KJob *job ) ) - Q_PRIVATE_SLOT( d, void modifyDone( KJob *job ) ) + Q_PRIVATE_SLOT(d, void fetchDone(KJob *job)) + Q_PRIVATE_SLOT(d, void modifyDone(KJob *job)) //@endcond }; diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/aborttest.cpp kdepim-runtime-15.08.0/agents/maildispatcher/tests/aborttest.cpp --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/aborttest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/aborttest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,237 +0,0 @@ -/* - Copyright 2009 Constantin Berzan - - 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 "aborttest.h" - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#define SPAM_ADDRESS "idanoka@gmail.com" -// NOTE: This test relies on a large SMTP message taking long enough to deliver, -// for it to call abort. So we need a valid receiver and a not-too-fast connection. -#define MESSAGE_MB 1 - -using namespace Akonadi; -using namespace KMime; -using namespace MailTransport; - -void AbortTest::initTestCase() -{ - QVERIFY( Control::start() ); - QTest::qWait( 1000 ); - - qRegisterMetaType(); - qRegisterMetaType(); - - // Get the outbox and clear it. - SpecialMailCollectionsRequestJob *rjob = new SpecialMailCollectionsRequestJob( this ); - rjob->requestDefaultCollection( SpecialMailCollections::Outbox ); - QTest::kWaitForSignal( rjob, SIGNAL(result(KJob*)) ); - outbox = SpecialMailCollections::self()->defaultCollection( SpecialMailCollections::Outbox ); - QVERIFY( outbox.isValid() ); - ItemDeleteJob *djob = new ItemDeleteJob( outbox ); - djob->exec(); // may give error if outbox empty - - // Verify transports. - akoTid = TransportManager::self()->defaultTransportId(); - Transport *t = TransportManager::self()->transportById( akoTid ); - QVERIFY( t ); - QCOMPARE( t->type(), int( Transport::EnumType::Akonadi ) ); - QList tids = TransportManager::self()->transportIds(); - tids.removeAll( akoTid ); - QCOMPARE( tids.count(), 1 ); - smtpTid = tids.first(); - t = TransportManager::self()->transportById( smtpTid ); - QVERIFY( t ); - QCOMPARE( t->type(), int( Transport::EnumType::SMTP ) ); - - // Set sink collection. - t = TransportManager::self()->transportById( akoTid ); - const QString rid = t->host(); - const AgentInstance agent = AgentManager::self()->instance( rid ); - QVERIFY( agent.isValid() ); - CollectionPathResolver *resolver = new CollectionPathResolver( QLatin1String("sink"), this ); - QVERIFY( resolver->exec() ); - sink = Collection( resolver->collection() ); - QVERIFY( sink.isValid() ); - QDBusInterface conf( QLatin1String("org.freedesktop.Akonadi.Resource.") + rid, - QLatin1String("/Settings"), QLatin1String("org.kde.Akonadi.MailTransportDummy.Settings") ); - QVERIFY( conf.isValid() ); - QDBusReply reply = conf.call( QLatin1String("setSink"), sink.id() ); - QVERIFY( reply.isValid() ); - agent.reconfigure(); - - // Watch sink collection. - monitor = new Monitor( this ); - monitor->setCollectionMonitored( sink ); -} - -void AbortTest::testAbort() -{ - // Get the MDA interface. - DispatcherInterface iface; - QVERIFY( iface.dispatcherInstance().isValid() ); - QVERIFY( iface.dispatcherInstance().isOnline() ); - - // Create a large message. - kDebug() << "Building message."; - Message::Ptr msg = Message::Ptr( new Message ); - QByteArray line( 70, 'a' ); - line.append( "\n" ); - QByteArray content( "\n" ); - for ( int i = 0; i < MESSAGE_MB * 1024 * 1024 / line.length() + 10; i++ ) { - content.append( line ); - } - QVERIFY( content.length() > MESSAGE_MB * 1024 * 1024 ); // >10MiB - msg->setContent( content ); - - // Queue the message. - kDebug() << "Queuing message."; - MessageQueueJob *qjob = new MessageQueueJob( this ); - qjob->setMessage( msg ); - qjob->transportAttribute().setTransportId( smtpTid ); - // default dispatch mode - // default sent-mail collection - qjob->addressAttribute().setFrom( QLatin1String("naiba") ); - qjob->addressAttribute().setTo( QStringList() <fetchScope().fetchAllAttributes(); - AKVERIFYEXEC( fjob ); - QCOMPARE( fjob->items().count(), 1 ); - Item item = fjob->items().first(); - QVERIFY( item.hasAttribute() ); - ErrorAttribute *eA = item.attribute(); - kDebug() << "Stored error:" << eA->message(); - - // "Fix" the item and send again, this time with the default (Akonadi) transport. - item.removeAttribute(); - item.clearFlag( Akonadi::MessageFlags::HasError ); - item.setFlag( Akonadi::MessageFlags::Queued ); - TransportAttribute *newTA = new TransportAttribute( akoTid ); - item.addAttribute( newTA ); - ItemModifyJob *cjob = new ItemModifyJob( item ); - QSignalSpy *addSpy = new QSignalSpy( monitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)) ); - AKVERIFYEXEC( cjob ); - - // Verify that the item got sent. - for ( int ds = 0; addSpy->isEmpty(); ds++ ) { - QTest::qWait( 100 ); - if ( ds % 10 == 0 ) { - kDebug() << "Waiting for an item to be sent." << ds / 10 << "seconds elapsed."; - } - - QVERIFY2( ds <= 100, "Timeout" ); - } - QCOMPARE( addSpy->count(), 1 ); - QCOMPARE( iface.dispatcherInstance().status(), AgentInstance::Idle ); -} - -void AbortTest::testAbortWhileIdle() -{ - // Get the MDA interface. - DispatcherInterface iface; - QVERIFY( iface.dispatcherInstance().isValid() ); - QVERIFY( iface.dispatcherInstance().isOnline() ); - - // Abort thin air. - QCOMPARE( iface.dispatcherInstance().status(), AgentInstance::Idle ); - iface.dispatcherInstance().abortCurrentTask(); - QCOMPARE( iface.dispatcherInstance().status(), AgentInstance::Idle ); - - // Queue a message (to check that subsequent messages are being sent). - QVERIFY( monitor ); - QSignalSpy *addSpy = new QSignalSpy( monitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)) ); - Message::Ptr msg = Message::Ptr( new Message ); - msg->setContent( "\ntestAbortWhileIdle" ); - MessageQueueJob *qjob = new MessageQueueJob( this ); - qjob->setMessage( msg ); - qjob->transportAttribute().setTransportId( akoTid ); - // default dispatch mode - // default sent-mail collection - qjob->addressAttribute().setFrom( QLatin1String("naiba") ); - qjob->addressAttribute().setTo( QStringList()<< QLatin1String("dracu" ) ); - QCOMPARE( iface.dispatcherInstance().status(), AgentInstance::Idle ); - AKVERIFYEXEC( qjob ); - - // Verify that the item got sent. - for ( int s = 0; addSpy->isEmpty(); s++ ) { - QTest::qWait( 1000 ); - QVERIFY2( s <= 10, "Timeout" ); - } - QCOMPARE( addSpy->count(), 1 ); - QCOMPARE( iface.dispatcherInstance().status(), AgentInstance::Idle ); -} - -QTEST_AKONADIMAIN( AbortTest, NoGUI ) - diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/aborttest.h kdepim-runtime-15.08.0/agents/maildispatcher/tests/aborttest.h --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/aborttest.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/aborttest.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - Copyright 2009 Constantin Berzan - - 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 ABORTTEST_H -#define ABORTTEST_H - -#include - -#include - -namespace Akonadi { - class Monitor; -} - -/** - This attempts to send a large message, then aborts it, then tries to send - it again and verify that it succeeds. - */ -class AbortTest : public QObject -{ - Q_OBJECT - - private Q_SLOTS: - void initTestCase(); - void testAbort(); - void testAbortWhileIdle(); - - private: - int akoTid; - int smtpTid; - Akonadi::Collection outbox; - Akonadi::Collection sink; - Akonadi::Monitor *monitor; - -}; - - -#endif diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/CMakeLists.txt kdepim-runtime-15.08.0/agents/maildispatcher/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) - -# Stolen from kdepimlibs/akonadi/tests -macro(add_akonadi_isolated_test _source) - get_filename_component(_targetName ${_source} NAME_WE) - set(_srcList ${_source} ) - - kde4_add_executable(${_targetName} TEST ${_srcList}) - target_link_libraries(${_targetName} - ${QT_QTTEST_LIBRARY} - ${QT_QTGUI_LIBRARY} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_AKONADI_KMIME_LIBS} - ${KDE4_KDECORE_LIBS} - ${KDEPIMLIBS_MAILTRANSPORT_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${QT_QTCORE_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ) - - # based on kde4_add_unit_test - if (WIN32) - get_target_property( _loc ${_targetName} LOCATION ) - set(_executable ${_loc}.bat) - else () - set(_executable ${EXECUTABLE_OUTPUT_PATH}/${_targetName}) - endif () - if (UNIX) - set(_executable ${_executable}.shell) - endif () - - find_program(_testrunner akonaditest) - - if (KDEPIM_RUN_ISOLATED_TESTS) - add_test( maildispatcheragent-${_targetName} ${_testrunner} -c ${CMAKE_CURRENT_SOURCE_DIR}/unittestenv/config.xml ${_executable} ) - endif () -endmacro(add_akonadi_isolated_test) - - - -add_akonadi_isolated_test( aborttest.cpp ) -add_akonadi_isolated_test( dupetest.cpp ) - diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/dupetest.cpp kdepim-runtime-15.08.0/agents/maildispatcher/tests/dupetest.cpp --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/dupetest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/dupetest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,221 +0,0 @@ -/* - Copyright 2009 Constantin Berzan - - 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 "dupetest.h" - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - - -static const int TIMEOUT_SECONDS = 60; -static const int MAXCOUNT = 99; // must be 2-digit! - -using namespace Akonadi; -using namespace KMime; -using namespace MailTransport; - -void DupeTest::initTestCase() -{ - QVERIFY( Control::start() ); - QTest::qWait( 1000 ); // give the MDA time to start - - qRegisterMetaType(); - qRegisterMetaType(); - - // we need a default Akonadi transport - int tid = TransportManager::self()->defaultTransportId(); - Transport *t = TransportManager::self()->transportById( tid ); - QVERIFY( t ); - QCOMPARE( t->type(), int( Transport::EnumType::Akonadi ) ); - - // set the sink collection - const QString rid = t->host(); - const AgentInstance agent = AgentManager::self()->instance( rid ); - QVERIFY( agent.isValid() ); - CollectionPathResolver *resolver = new CollectionPathResolver( QLatin1String("sink"), this ); - QVERIFY( resolver->exec() ); - sink = Collection( resolver->collection() ); - QVERIFY( sink.isValid() ); - QDBusInterface conf( QLatin1String("org.freedesktop.Akonadi.Resource.") + rid, - QLatin1String("/Settings"), QLatin1String("org.kde.Akonadi.MailTransportDummy.Settings") ); - QVERIFY( conf.isValid() ); - QDBusReply reply = conf.call( QLatin1String("setSink"), sink.id() ); - QVERIFY( reply.isValid() ); - agent.reconfigure(); - - // set up monitor - monitor = new Monitor( this ); - monitor->setCollectionMonitored( sink ); - monitor->itemFetchScope().fetchFullPayload(); -} - -void DupeTest::testDupes_data() -{ - QTest::addColumn( "message" ); // the prefix of the message to send (-msg## is appended) - QTest::addColumn( "count" ); // how many copies to send - QTest::addColumn( "delay" ); // number of ms to wait before sending next copy - - QTest::newRow( "1-nodelay" ) << "\n1-nodelay" << 1 << 0; - QTest::newRow( "2-nodelay" ) << "\n2-nodelay" << 2 << 0; - QTest::newRow( "5-nodelay" ) << "\n5-nodelay" << 5 << 0; - QTest::newRow( "10-nodelay" ) << "\n10-nodelay" << 10 << 0; - QTest::newRow( "20-nodelay" ) << "\n20-nodelay" << 20 << 0; - QTest::newRow( "50-nodelay" ) << "\n50-nodelay" << 50 << 0; - QTest::newRow( "99-nodelay" ) << "\n99-nodelay" << 99 << 0; - QTest::newRow( "2-veryshortdelay" ) << "\n2-veryshortdelay" << 2 << 20; - QTest::newRow( "5-veryshortdelay" ) << "\n5-veryshortdelay" << 5 << 20; - QTest::newRow( "10-veryshortdelay" ) << "\n10-veryshortdelay" << 10 << 20; - QTest::newRow( "20-veryshortdelay" ) << "\n20-veryshortdelay" << 20 << 20; - QTest::newRow( "50-veryshortdelay" ) << "\n50-veryshortdelay" << 50 << 20; - QTest::newRow( "99-veryshortdelay" ) << "\n99-veryshortdelay" << 99 << 20; - QTest::newRow( "2-shortdelay" ) << "\n2-shortdelay" << 2 << 100; - QTest::newRow( "5-shortdelay" ) << "\n5-shortdelay" << 5 << 100; - QTest::newRow( "10-shortdelay" ) << "\n10-shortdelay" << 10 << 100; - QTest::newRow( "20-shortdelay" ) << "\n20-shortdelay" << 20 << 100; - QTest::newRow( "50-shortdelay" ) << "\n50-shortdelay" << 50 << 100; - QTest::newRow( "99-shortdelay" ) << "\n99-shortdelay" << 99 << 99; - QTest::newRow( "2-longdelay" ) << "\n2-longdelay" << 2 << 1000; - QTest::newRow( "5-longdelay" ) << "\n5-longdelay" << 5 << 1000; - QTest::newRow( "5-verylongdelay" ) << "\n5-verylongdelay" << 5 << 4000; - Q_ASSERT( 99 <= MAXCOUNT ); - Q_ASSERT( MAXCOUNT < 100 ); // 2-digit - - // TODO I'm not sure more items means a better test - // TODO test large items - // TODO test modifying items while they are being sent... -} - -void DupeTest::testDupes() -{ - QFETCH( QString, message ); - QFETCH( int, count ); - QFETCH( int, delay ); - - // clean sink - ItemFetchJob *fjob = new ItemFetchJob( sink, this ); - AKVERIFYEXEC( fjob ); - if ( fjob->items().count() > 0 ) { - // this test is needed because ItemDeleteJob gives error if no items are found - ItemDeleteJob *djob = new ItemDeleteJob( sink, this ); - AKVERIFYEXEC( djob ); - } - fjob = new ItemFetchJob( sink, this ); - AKVERIFYEXEC( fjob ); - QCOMPARE( fjob->items().count(), 0 ); - - // queue messages - Q_ASSERT( monitor ); - QSignalSpy *addSpy = new QSignalSpy( monitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)) ); - kDebug() << "Queuing" << count << "messages..."; - for ( int i = 0; i < count; i++ ) { - //kDebug() << "Queuing message" << i + 1 << "of" << count; - - Message::Ptr msg = Message::Ptr( new Message ); - msg->setContent( QString::fromLatin1( "%1-msg%2\n" ).arg( message ).arg( i + 1, 2, 10, QLatin1Char( '0' ) ).toLatin1() ); - - MessageQueueJob *job = new MessageQueueJob( this ); - job->setMessage( msg ); - job->transportAttribute().setTransportId( TransportManager::self()->defaultTransportId() ); - // default dispatch mode - // default sent-mail collection - job->addressAttribute().setFrom( QLatin1String("naiba") ); - job->addressAttribute().setTo( QStringList() << QLatin1String( "dracu" ) ); - //AKVERIFYEXEC( job ); - job->start(); - QTest::qWait( delay ); - } - kDebug() << "Queued" << count << "messages."; - - // wait for the MDA to send them - int seconds = 0; - while ( true ) { - seconds++; - QTest::qWait( 1000 ); - kDebug() << seconds << "seconds elapsed." << addSpy->count() << "messages got to sink."; - if ( addSpy->count() >= count ) - break; - -#if 0 - if ( seconds >= TIMEOUT_SECONDS ) { - kDebug() << "Timeout, gdb master!"; - QTest::qWait( 1000*1000 ); - } -#endif - QVERIFY2( seconds < TIMEOUT_SECONDS, "Timeout" ); - } - - // TODO I should verify that the MDA has actually finished its work and has an empty queue - QTest::qWait( 2000 ); - - // verify what has been sent - fjob = new ItemFetchJob( sink, this ); - fjob->fetchScope().fetchFullPayload(); - AKVERIFYEXEC( fjob ); - const Item::List items = fjob->items(); - int found[ MAXCOUNT ]; - for ( int i = 0; i < count; i++ ) { - found[i] = 0; - } - for ( int i = 0; i < items.count(); i++ ) { - QVERIFY( items[i].hasPayload() ); - Message::Ptr msg = items[i].payload(); - const QByteArray content = msg->encodedContent(); - //kDebug() << "i" << i << "content" << content; - int loc = content.indexOf( "-msg" ); - QVERIFY( loc >= 0 ); - bool ok; - int who = content.mid( loc + 4, 2 ).toInt( &ok ); - QVERIFY( ok ); - //kDebug() << "identified msg" << who; - QVERIFY( who > 0 && who <= count ); - found[ who - 1 ]++; - } - for ( int i = 0; i < count; i++ ) { - if ( found[i] > 1 ) { - kDebug() << "found duplicate message" << i + 1 << "(" << found[i] << "times )"; - } else if ( found[i] < 1 ) { - kDebug() << "didn't find message" << i + 1; - } - QCOMPARE( found[i], 1 ); - } - QCOMPARE( addSpy->count(), count ); - QCOMPARE( items.count(), count ); -} - -QTEST_AKONADIMAIN( DupeTest, NoGUI ) - diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/dupetest.h kdepim-runtime-15.08.0/agents/maildispatcher/tests/dupetest.h --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/dupetest.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/dupetest.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -/* - Copyright 2009 Constantin Berzan - - 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 DUPETEST_H -#define DUPETEST_H - -#include -#include - -#include -#include - - -/** - This queues a bunch of messages very quickly one after the other, lets the - MDA send them via the dummy mailtransport resource, and then verify that the - correct number of messages has been sent. - */ -class DupeTest : public QObject -{ - Q_OBJECT - - private Q_SLOTS: - void initTestCase(); - void testDupes_data(); - void testDupes(); - - private: - Akonadi::Collection sink; - Akonadi::Monitor *monitor; - -}; - - -#endif diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/TODO kdepim-runtime-15.08.0/agents/maildispatcher/tests/TODO --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/TODO 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/TODO 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -* test online / offline -* figure out why ksyscoca is started (it's not the wallet apparently) -* aborttest: test aborting when there is >1 message queued -* test the various SendBehaviours and DispatchModes -* dupetest -> probably faster and more effective if I just use random intervals - of time between queuing messages diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/config.xml kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/config.xml --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/config.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/config.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ - - kdehome - xdgconfig - xdglocal - akonadi_knut_resource - akonadi_mailtransport_dummy_resource - diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[ProcessedDefaults] -defaultaddressbook=done -defaultcalendar=done diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -[General] -DataFile[$e]=$KDEHOME/testdata.xml -FileWatchingEnabled=false - diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/akonadi_mailtransport_dummy_resource_0rc kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/akonadi_mailtransport_dummy_resource_0rc --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/akonadi_mailtransport_dummy_resource_0rc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/akonadi_mailtransport_dummy_resource_0rc 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -[General] -Sink=123 diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/kdebugrc kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/kdebugrc --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/kdebugrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/kdebugrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,110 +0,0 @@ -[0] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[5250] -InfoOutput=2 - -[5251] -InfoOutput=2 - -[5252] -InfoOutput=2 - -[5253] -InfoOutput=2 - -[5254] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[5255] -InfoOutput=2 - -[5256] -InfoOutput=2 - -[5257] -InfoOutput=2 - -[5258] -InfoOutput=2 - -[5259] -InfoOutput=2 - -[5260] -InfoOutput=2 - -[5261] -InfoOutput=2 - -[5262] -InfoOutput=2 - -[5263] -InfoOutput=2 - -[5264] -InfoOutput=2 - -[5265] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[5266] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[5295] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[5324] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[7129] -InfoOutput=2 diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/kdedrc kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/kdedrc --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/kdedrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/kdedrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[General] -CheckSycoca=false -CheckFileStamps=false diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/kwalletrc kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/kwalletrc --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/kwalletrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/kwalletrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -[Wallet] -Enabled=false diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/mailtransports kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/mailtransports --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/mailtransports 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/mailtransports 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -[$Version] -update_info=mailtransports.upd:initial-kmail-migration,mailtransports.upd:initial-knode-migration - -[General] -default-transport=666 - -[Transport 666] -host=akonadi_mailtransport_dummy_resource_0 -id=666 -name=Dummy Akonadi Transport -type=Akonadi - -[Transport 549190884] -auth=true -encryption=SSL -host=smtp.gmail.com -id=549190884 -name=idanoka2-stored -password=ᄒᄡᄚᄆᄒᄏᄊᆱᄎᆲᆱ -port=465 -storepass=true -user=idanoka2@gmail.com - diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/qttestrc kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/qttestrc --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/share/config/qttestrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/share/config/qttestrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -[Notification Messages] -WalletMigrate=false diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/testdata.xml kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/testdata.xml --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/kdehome/testdata.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/kdehome/testdata.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ - - - - diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -[%General] - -[Search] -Manager=Dummy diff -Nru kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/xdglocal/.keep kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/xdglocal/.keep --- kdepim-runtime-4.14.6/agents/maildispatcher/tests/unittestenv/xdglocal/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/maildispatcher/tests/unittestenv/xdglocal/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/agents/migration/autotests/CMakeLists.txt kdepim-runtime-15.08.0/agents/migration/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/agents/migration/autotests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/autotests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,12 @@ + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/.. +) + +add_executable(schedulertest schedulertest.cpp ../migrationscheduler.cpp ../migrationexecutor.cpp) +target_link_libraries(schedulertest + gidmigration + KF5::AkonadiCore + Qt5::Test +) +add_test(schedulertest schedulertest) diff -Nru kdepim-runtime-4.14.6/agents/migration/autotests/dummymigrator.cpp kdepim-runtime-15.08.0/agents/migration/autotests/dummymigrator.cpp --- kdepim-runtime-4.14.6/agents/migration/autotests/dummymigrator.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/autotests/dummymigrator.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * Copyright 2013 Christian Mollekopf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "dummymigrator.h" +#include +#include + +DummyMigrator::DummyMigrator(const QString &identifier) + : MigratorBase(QLatin1String("dummymigrator") + identifier, QString(), QString()) +{} + +QString DummyMigrator::displayName() const +{ + return QStringLiteral("dummymigrator"); +} + +void DummyMigrator::startWork() +{ + qDebug(); + QTimer::singleShot(10000, this, SLOT(onTimerElapsed())); +} + +void DummyMigrator::onTimerElapsed() +{ + qDebug(); + setMigrationState(Complete); +} + +bool DummyMigrator::shouldAutostart() const +{ + return true; +} + +bool DummyMigrator::canStart() +{ + return true; +} + +void DummyMigrator::pause() +{ + qDebug(); + MigratorBase::pause(); +} + +void DummyMigrator::abort() +{ + qDebug(); + MigratorBase::abort(); +} + diff -Nru kdepim-runtime-4.14.6/agents/migration/autotests/dummymigrator.h kdepim-runtime-15.08.0/agents/migration/autotests/dummymigrator.h --- kdepim-runtime-4.14.6/agents/migration/autotests/dummymigrator.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/autotests/dummymigrator.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,49 @@ +/* + * Copyright 2013 Christian Mollekopf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef DUMMYMIGRATOR_H +#define DUMMYMIGRATOR_H + +#include + +/** + * Dummy migrator that simply completes after 10s and always autostarts. + * Add to the scheduler to play with the migrationagent. + */ +class DummyMigrator : public MigratorBase +{ + Q_OBJECT +public: + explicit DummyMigrator(const QString &identifier); + + QString displayName() const Q_DECL_OVERRIDE; + void startWork() Q_DECL_OVERRIDE; + + bool shouldAutostart() const Q_DECL_OVERRIDE; + bool canStart() Q_DECL_OVERRIDE; + void pause() Q_DECL_OVERRIDE; + + void abort() Q_DECL_OVERRIDE; +private Q_SLOTS: + void onTimerElapsed(); +}; + +#endif \ No newline at end of file diff -Nru kdepim-runtime-4.14.6/agents/migration/autotests/schedulertest.cpp kdepim-runtime-15.08.0/agents/migration/autotests/schedulertest.cpp --- kdepim-runtime-4.14.6/agents/migration/autotests/schedulertest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/autotests/schedulertest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,286 @@ +/* + * Copyright 2013 Christian Mollekopf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include + +#include "../migrationscheduler.h" +#include + +Q_DECLARE_METATYPE(QModelIndex) + +class Testmigrator: public MigratorBase +{ + Q_OBJECT +public: + explicit Testmigrator(const QString &identifier, QObject *parent = Q_NULLPTR): + MigratorBase(QLatin1String("testmigrator") + identifier, QString(), QString(), parent), mAutostart(false) + {} + + QString displayName() const Q_DECL_OVERRIDE + { + return QStringLiteral("name"); + } + + void startWork() Q_DECL_OVERRIDE + {} + + void abort() Q_DECL_OVERRIDE { + setMigrationState(Aborted); + } + + virtual void complete() + { + setMigrationState(Complete); + } + + bool shouldAutostart() const Q_DECL_OVERRIDE + { + return mAutostart; + } + + void pause() Q_DECL_OVERRIDE { + setMigrationState(Paused); + } + + void resume() Q_DECL_OVERRIDE { + setMigrationState(InProgress); + } + + bool mAutostart; +}; + +class TestJobTracker : public KJobTrackerInterface +{ +public: + TestJobTracker() : mPercent(0) + {} + + void registerJob(KJob *job) Q_DECL_OVERRIDE { + KJobTrackerInterface::registerJob(job); + mJobs << job; + } + + void unregisterJob(KJob *job) Q_DECL_OVERRIDE { + mJobs.removeAll(job); + } + + void finished(KJob *job) Q_DECL_OVERRIDE { + mJobs.removeAll(job); + } + + void percent(KJob *job, long unsigned int percent) Q_DECL_OVERRIDE { + Q_UNUSED(job); + mPercent = percent; + } + + QList mJobs; + int mPercent; +}; + +class SchedulerTest: public QObject +{ + Q_OBJECT +private Q_SLOTS: + + void initTestcase() + { + qRegisterMetaType(); + } + + void testInsertRow() + { + MigrationScheduler scheduler; + QAbstractItemModel &model(scheduler.model()); + + QCOMPARE(model.rowCount(), 0); + + QSignalSpy rowsInsertedSpy(&model, SIGNAL(rowsInserted(QModelIndex,int,int))); + QVERIFY(rowsInsertedSpy.isValid()); + + scheduler.addMigrator(QSharedPointer(new Testmigrator(QLatin1String("id")))); + QCOMPARE(model.rowCount(), 1); + QCOMPARE(rowsInsertedSpy.count(), 1); + + QVERIFY(model.index(0, 0).isValid()); + QVERIFY(!model.index(1, 0).isValid()); + + scheduler.addMigrator(QSharedPointer(new Testmigrator(QLatin1String("id2")))); + QCOMPARE(model.rowCount(), 2); + QCOMPARE(rowsInsertedSpy.count(), 2); + } + + void testDisplayName() + { + MigrationScheduler scheduler; + scheduler.addMigrator(QSharedPointer(new Testmigrator(QLatin1String("id")))); + QAbstractItemModel &model(scheduler.model()); + QCOMPARE(model.data(model.index(0, 0)).toString(), QStringLiteral("name")); + } + + void testStartStop() + { + MigrationScheduler scheduler; + QSharedPointer migrator(new Testmigrator(QLatin1String("id"))); + scheduler.addMigrator(migrator); + + scheduler.start(migrator->identifier()); + QCOMPARE(migrator->migrationState(), MigratorBase::InProgress); + + scheduler.abort(migrator->identifier()); + QCOMPARE(migrator->migrationState(), MigratorBase::Aborted); + } + + void testNoDuplicates() + { + MigrationScheduler scheduler; + scheduler.addMigrator(QSharedPointer(new Testmigrator(QLatin1String("id")))); + scheduler.addMigrator(QSharedPointer(new Testmigrator(QLatin1String("id")))); + QAbstractItemModel &model(scheduler.model()); + QCOMPARE(model.rowCount(), 1); + } + + void testMigrationStateChanged() + { + MigrationScheduler scheduler; + scheduler.addMigrator(QSharedPointer(new Testmigrator(QLatin1String("id1")))); + QSharedPointer migrator(new Testmigrator(QLatin1String("id2"))); + scheduler.addMigrator(migrator); + scheduler.addMigrator(QSharedPointer(new Testmigrator(QLatin1String("id3")))); + QAbstractItemModel &model(scheduler.model()); + + QSignalSpy spy(&model, SIGNAL(dataChanged(QModelIndex,QModelIndex))); + QVERIFY(spy.isValid()); + migrator->start(); + + QCOMPARE(spy.count(), 1); + const QVariantList args = spy.takeFirst(); + QCOMPARE(args.at(0).value().row(), 1); + QCOMPARE(args.at(1).value().row(), 1); + } + + void testRunMultiple() + { + MigrationScheduler scheduler; + + QSharedPointer m1(new Testmigrator(QLatin1String("id1"))); + scheduler.addMigrator(m1); + + QSharedPointer m2(new Testmigrator(QLatin1String("id2"))); + scheduler.addMigrator(m2); + + scheduler.start(m1->identifier()); + scheduler.start(m2->identifier()); + + QCOMPARE(m1->migrationState(), MigratorBase::InProgress); + QCOMPARE(m2->migrationState(), MigratorBase::InProgress); + } + + void testRunAutostart() + { + MigrationScheduler scheduler; + + QSharedPointer m1(new Testmigrator(QLatin1String("id1"))); + m1->mAutostart = true; + scheduler.addMigrator(m1); + + QSharedPointer m2(new Testmigrator(QLatin1String("id2"))); + m2->mAutostart = true; + scheduler.addMigrator(m2); + + QCOMPARE(m1->migrationState(), MigratorBase::InProgress); + qDebug() << m2->migrationState(); + QCOMPARE(m2->migrationState(), MigratorBase::None); + m1->complete(); + QCOMPARE(m2->migrationState(), MigratorBase::InProgress); + + } + + void testJobTracker() + { + TestJobTracker jobTracker; + MigrationScheduler scheduler(&jobTracker); + QSharedPointer m1(new Testmigrator(QLatin1String("id1"))); + m1->mAutostart = true; + scheduler.addMigrator(m1); + + QCOMPARE(jobTracker.mJobs.size(), 1); + + m1->complete(); + + //Give the job some time to delete itself + QTest::qWait(500); + + QCOMPARE(jobTracker.mJobs.size(), 0); + } + + void testSuspend() + { + TestJobTracker jobTracker; + MigrationScheduler scheduler(&jobTracker); + QSharedPointer m1(new Testmigrator(QLatin1String("id1"))); + m1->mAutostart = true; + scheduler.addMigrator(m1); + jobTracker.mJobs.first()->suspend(); + QCOMPARE(m1->migrationState(), MigratorBase::Paused); + jobTracker.mJobs.first()->resume(); + QCOMPARE(m1->migrationState(), MigratorBase::InProgress); + } + + /* + * Even if the migrator doesn't implement suspend, the executor suspends after completing the current job and waits with starting the second job. + */ + void testJobFinishesDuringSuspend() + { + TestJobTracker jobTracker; + MigrationScheduler scheduler(&jobTracker); + QSharedPointer m1(new Testmigrator(QLatin1String("id1"))); + m1->mAutostart = true; + scheduler.addMigrator(m1); + QSharedPointer m2(new Testmigrator(QLatin1String("id2"))); + m2->mAutostart = true; + scheduler.addMigrator(m2); + jobTracker.mJobs.first()->suspend(); + m1->complete(); + QCOMPARE(m2->migrationState(), MigratorBase::None); + jobTracker.mJobs.first()->resume(); + QCOMPARE(m2->migrationState(), MigratorBase::InProgress); + } + + void testProgressReporting() + { + TestJobTracker jobTracker; + MigrationScheduler scheduler(&jobTracker); + QSharedPointer m1(new Testmigrator(QLatin1String("id1"))); + m1->mAutostart = true; + scheduler.addMigrator(m1); + QCOMPARE(jobTracker.mPercent, 0); + m1->complete(); + QCOMPARE(jobTracker.mPercent, 100); + } + +}; + +QTEST_MAIN(SchedulerTest) + +#include "schedulertest.moc" diff -Nru kdepim-runtime-4.14.6/agents/migration/CMakeLists.txt kdepim-runtime-15.08.0/agents/migration/CMakeLists.txt --- kdepim-runtime-4.14.6/agents/migration/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,22 +1,27 @@ include_directories( ${Boost_INCLUDE_DIR} - tests + ${kdepim-runtime_SOURCE_DIR}/migration + ${kdepim-runtime_SOURCE_DIR} ) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS} -fPIC") +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_migration_agent\") + +kde_enable_exceptions() + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") set(migrationagent_SRCS migrationagent.cpp migrationstatuswidget.cpp migrationexecutor.cpp migrationscheduler.cpp - tests/dummymigrator.cpp + autotests/dummymigrator.cpp ) -kde4_add_executable(akonadi_migration_agent ${migrationagent_SRCS}) +add_executable(akonadi_migration_agent ${migrationagent_SRCS}) -if (Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_migration_agent PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) set_target_properties(akonadi_migration_agent PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.migrationagent") set_target_properties(akonadi_migration_agent PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi Migrationagent") @@ -24,17 +29,14 @@ target_link_libraries(akonadi_migration_agent gidmigration - ${KDE4_KDEUI_LIBRARY} - ${KDE4_KDECORE_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KABC_LIBS} - ${QT_QTCORE_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ${KDE4_KIDLETIME_LIBRARY} - ${KDE4_SOLID_LIBS} + KF5::AkonadiCore + KF5::AkonadiAgentBase + KF5::Contacts ) -install(TARGETS akonadi_migration_agent ${INSTALL_TARGETS_DEFAULT_ARGS}) -install(FILES migrationagent.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents") +install(TARGETS akonadi_migration_agent ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) +install(FILES migrationagent.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}//akonadi/agents") -add_subdirectory(tests) \ No newline at end of file +if(BUILD_TESTING) + add_subdirectory(autotests) +endif() diff -Nru kdepim-runtime-4.14.6/agents/migration/migrationagent.cpp kdepim-runtime-15.08.0/agents/migration/migrationagent.cpp --- kdepim-runtime-4.14.6/agents/migration/migrationagent.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/migrationagent.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,36 +23,48 @@ #include "migrationstatuswidget.h" #include -#include +#include #include -#include +#include #include #include +#include +#include -namespace Akonadi { +namespace Akonadi +{ MigrationAgent::MigrationAgent(const QString &id) -: AgentBase(id), - mScheduler(new KUiServerJobTracker) + : AgentBase(id), + mScheduler(new KUiServerJobTracker) { - mScheduler.addMigrator(QSharedPointer(new GidMigrator(KABC::Addressee::mimeType()))); + KLocalizedString::setApplicationDomain("akonadi_migration_agent"); + mScheduler.addMigrator(QSharedPointer(new GidMigrator(KContacts::Addressee::mimeType()))); } void MigrationAgent::configure(WId windowId) { - KDialog *dlg = new KDialog(); + QDialog *dlg = new QDialog(); + QVBoxLayout *topLayout = new QVBoxLayout; + dlg->setLayout(topLayout); + + MigrationStatusWidget *widget = new MigrationStatusWidget(mScheduler, dlg); + topLayout->addWidget(widget); dlg->setAttribute(Qt::WA_DeleteOnClose); - dlg->setMainWidget(new MigrationStatusWidget(mScheduler, dlg)); - dlg->setCaption(i18nc("Title of the window that shows the status of the migration agent and offers controls to start/stop individual migration jobs.", "Migration Status")); - dlg->setButtons(KDialog::Close); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); + connect(buttonBox, &QDialogButtonBox::accepted, dlg, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, dlg, &QDialog::reject); + topLayout->addWidget(buttonBox); + + dlg->setWindowTitle(i18nc("Title of the window that shows the status of the migration agent and offers controls to start/stop individual migration jobs.", "Migration Status")); dlg->resize(600, 300); if (windowId) { - #ifndef Q_WS_WIN +#ifndef Q_OS_WIN KWindowSystem::setMainWindow(dlg, windowId); - #else +#else KWindowSystem::setMainWindow(dlg, (HWND)windowId); - #endif +#endif } dlg->show(); } diff -Nru kdepim-runtime-4.14.6/agents/migration/migrationagent.desktop kdepim-runtime-15.08.0/agents/migration/migrationagent.desktop --- kdepim-runtime-4.14.6/agents/migration/migrationagent.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/migrationagent.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -26,6 +26,7 @@ Name[pt_BR]=Agente de Migração Name[ru]=Агент переноса данных Name[sk]=Agent migrácie +Name[sl]=Posrednik za selitev Name[sr]=Агент селидбе Name[sr@ijekavian]=Агент селидбе Name[sr@ijekavianlatin]=Agent selidbe diff -Nru kdepim-runtime-4.14.6/agents/migration/migrationagent.h kdepim-runtime-15.08.0/agents/migration/migrationagent.h --- kdepim-runtime-4.14.6/agents/migration/migrationagent.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/migrationagent.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,17 +22,18 @@ #ifndef MIGRATIONAGENT_H #define MIGRATIONAGENT_H -#include +#include #include "migrationscheduler.h" -namespace Akonadi { +namespace Akonadi +{ class MigrationAgent : public AgentBase, public AgentBase::ObserverV2 { Q_OBJECT public: explicit MigrationAgent(const QString &id); - virtual void configure(WId windowId); + void configure(WId windowId) Q_DECL_OVERRIDE; private: MigrationScheduler mScheduler; }; diff -Nru kdepim-runtime-4.14.6/agents/migration/migrationexecutor.cpp kdepim-runtime-15.08.0/agents/migration/migrationexecutor.cpp --- kdepim-runtime-4.14.6/agents/migration/migrationexecutor.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/migrationexecutor.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,10 +23,10 @@ #include MigrationExecutor::MigrationExecutor() -: KJob(), - mSuspended(false), - mTotalAmount(0), - mAlreadyProcessed(0) + : KJob(), + mSuspended(false), + mTotalAmount(0), + mAlreadyProcessed(0) { setCapabilities(Suspendable); } @@ -34,7 +34,7 @@ void MigrationExecutor::start() { setPercent(0); - emit description(this, i18nc("User visible name of ongoing Akonadi migration jobs", "PIM Maintenance")); + Q_EMIT description(this, i18nc("User visible name of ongoing Akonadi migration jobs", "PIM Maintenance")); } void MigrationExecutor::add(const QSharedPointer &migrator) @@ -55,13 +55,13 @@ migrator = mCurrentMigrator.toStrongRef(); } if (migrator) { - emit infoMessage(this, i18nc("PIM-Maintenance is in progress.", "In progress...")); + Q_EMIT infoMessage(this, i18nc("PIM-Maintenance is in progress.", "In progress...")); connect(migrator.data(), SIGNAL(stoppedProcessing()), this, SLOT(onStoppedProcessing())); migrator->start(); } else { // Reset the notification status, otherwise we get notification "In progress...[finished]" // without any description that it's related to PIM-Maintenance - emit infoMessage(this, i18n("PIM Maintenance")); + Q_EMIT infoMessage(this, i18n("PIM Maintenance")); emitResult(); } } @@ -71,7 +71,7 @@ mAlreadyProcessed++; Q_ASSERT(mTotalAmount > 0); //TODO: setProcessedAmount would be better, but we need support for suitable units first (there's only files, folders, bytes). - setPercent(mAlreadyProcessed*100.0/mTotalAmount); + setPercent(mAlreadyProcessed * 100.0 / mTotalAmount); mCurrentMigrator.clear(); executeNext(); } @@ -86,7 +86,7 @@ mCurrentMigrator.clear(); } } - emit infoMessage(this, i18nc("PIM-Maintenance is paused.", "Paused.")); + Q_EMIT infoMessage(this, i18nc("PIM-Maintenance is paused.", "Paused.")); mSuspended = true; return true; } diff -Nru kdepim-runtime-4.14.6/agents/migration/migrationexecutor.h kdepim-runtime-15.08.0/agents/migration/migrationexecutor.h --- kdepim-runtime-4.14.6/agents/migration/migrationexecutor.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/migrationexecutor.h 2015-08-10 21:01:02.000000000 +0000 @@ -40,13 +40,13 @@ public: MigrationExecutor(); void add(const QSharedPointer &); - virtual void start(); + void start() Q_DECL_OVERRIDE; protected: - virtual bool doResume(); - virtual bool doSuspend(); + bool doResume() Q_DECL_OVERRIDE; + bool doSuspend() Q_DECL_OVERRIDE; -private slots: +private Q_SLOTS: void onStoppedProcessing(); void executeNext(); diff -Nru kdepim-runtime-4.14.6/agents/migration/migrationscheduler.cpp kdepim-runtime-15.08.0/agents/migration/migrationscheduler.cpp --- kdepim-runtime-4.14.6/agents/migration/migrationscheduler.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/migrationscheduler.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,55 +22,54 @@ #include "migrationscheduler.h" #include -#include -#include +#include +#include #include #include "migrationexecutor.h" void LogModel::message(MigratorBase::MessageType type, const QString &msg) { - switch ( type ) { + switch (type) { case MigratorBase::Success: { - QStandardItem *item = new QStandardItem(KIcon(QLatin1String("dialog-ok-apply")), msg); + QStandardItem *item = new QStandardItem(QIcon::fromTheme(QStringLiteral("dialog-ok-apply")), msg); item->setEditable(false); appendRow(item); break; } case MigratorBase::Skip: { - QStandardItem *item = new QStandardItem(KIcon(QLatin1String("dialog-ok")), msg); + QStandardItem *item = new QStandardItem(QIcon::fromTheme(QStringLiteral("dialog-ok")), msg); item->setEditable(false); appendRow(item); break; } case MigratorBase::Info: { - QStandardItem *item = new QStandardItem(KIcon(QLatin1String("dialog-information")), msg); + QStandardItem *item = new QStandardItem(QIcon::fromTheme(QStringLiteral("dialog-information")), msg); item->setEditable(false); appendRow(item); break; } case MigratorBase::Warning: { - QStandardItem *item = new QStandardItem(KIcon(QLatin1String("dialog-warning")), msg); + QStandardItem *item = new QStandardItem(QIcon::fromTheme(QStringLiteral("dialog-warning")), msg); item->setEditable(false); appendRow(item); break; } case MigratorBase::Error: { - QStandardItem *item = new QStandardItem(KIcon(QLatin1String("dialog-error")), msg); + QStandardItem *item = new QStandardItem(QIcon::fromTheme(QStringLiteral("dialog-error")), msg); item->setEditable(false); appendRow(item); break; } default: - kError() << "unknown type " << type; + qCritical() << "unknown type " << type; } } - Row::Row(const QSharedPointer &migrator, MigratorModel &model) -: QObject(), - mMigrator(migrator), - mModel(model) + : QObject(), + mMigrator(migrator), + mModel(model) { connect(migrator.data(), SIGNAL(stateChanged(MigratorBase::MigrationState)), this, SLOT(stateChanged(MigratorBase::MigrationState))); connect(migrator.data(), SIGNAL(progress(int)), this, SLOT(progress(int))); @@ -109,14 +108,14 @@ Q_ASSERT(p >= 0); if (p >= 0) { const QModelIndex idx = index(p, col); - emit dataChanged(idx, idx); + Q_EMIT dataChanged(idx, idx); } } bool MigratorModel::addMigrator(const QSharedPointer &m) { if (migrator(m->identifier())) { - kWarning() << "Model already contains a migrator with the identifier: " << m; + qWarning() << "Model already contains a migrator with the identifier: " << m; return false; } const int pos = mMigrators.size(); @@ -144,7 +143,7 @@ if (row >= rowCount(parent) || row < 0) { return QModelIndex(); } - return createIndex(row, column, static_cast(mMigrators.at(row).data())); + return createIndex(row, column, static_cast(mMigrators.at(row).data())); } QModelIndex MigratorModel::parent(const QModelIndex &/*child*/) const @@ -156,14 +155,14 @@ { if (role == Qt::DisplayRole) { switch (section) { - case Name: - return i18nc("Name of the migrator in this row", "Name"); - case Progress: - return i18nc("Progress of the mgirator in %", "Progress"); - case State: - return i18nc("Current status of the migrator (done, in progress, ...)", "Status"); - default: - Q_ASSERT(false); + case Name: + return i18nc("Name of the migrator in this row", "Name"); + case Progress: + return i18nc("Progress of the mgirator in %", "Progress"); + case State: + return i18nc("Current status of the migrator (done, in progress, ...)", "Status"); + default: + Q_ASSERT(false); } } return QVariant(); @@ -171,32 +170,32 @@ QVariant MigratorModel::data(const QModelIndex &index, int role) const { - const Row *row = static_cast(index.internalPointer()); + const Row *row = static_cast(index.internalPointer()); const QSharedPointer migrator(row->mMigrator); if (!migrator) { - kWarning() << "migrator not found"; + qWarning() << "migrator not found"; return QVariant(); } switch (role) { - case Qt::DisplayRole: - switch (index.column()) { - case Name: - return migrator->displayName(); - case Progress: - return QString::fromLatin1("%1 %").arg(migrator->progress()); - case State: - return migrator->status(); - default: - Q_ASSERT(false); - } - case IdentifierRole: - return migrator->identifier(); - case LogfileRole: - return migrator->logfile(); - case Qt::ToolTipRole: - return migrator->description(); + case Qt::DisplayRole: + switch (index.column()) { + case Name: + return migrator->displayName(); + case Progress: + return QStringLiteral("%1 %").arg(migrator->progress()); + case State: + return migrator->status(); default: - break; + Q_ASSERT(false); + } + case IdentifierRole: + return migrator->identifier(); + case LogfileRole: + return migrator->logfile(); + case Qt::ToolTipRole: + return migrator->description(); + default: + break; } return QVariant(); } @@ -221,9 +220,9 @@ } MigrationScheduler::MigrationScheduler(KJobTrackerInterface *jobTracker, QObject *parent) - :QObject(parent), - mModel(new MigratorModel), - mJobTracker(jobTracker) + : QObject(parent), + mModel(new MigratorModel), + mJobTracker(jobTracker) { } @@ -244,12 +243,12 @@ } } -QAbstractItemModel& MigrationScheduler::model() +QAbstractItemModel &MigrationScheduler::model() { return *mModel; } -QStandardItemModel& MigrationScheduler::logModel(const QString &identifier) +QStandardItemModel &MigrationScheduler::logModel(const QString &identifier) { Q_ASSERT(mLogModel.contains(identifier)); return *mLogModel.value(identifier); diff -Nru kdepim-runtime-4.14.6/agents/migration/migrationscheduler.h kdepim-runtime-15.08.0/agents/migration/migrationscheduler.h --- kdepim-runtime-4.14.6/agents/migration/migrationscheduler.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/migrationscheduler.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,11 +22,10 @@ #ifndef MIGRATIONSCHEDULER_H #define MIGRATIONSCHEDULER_H -#include +#include "migratorbase.h" #include #include #include -#include #include #include @@ -37,7 +36,7 @@ class LogModel : public QStandardItemModel { Q_OBJECT -public slots: +public Q_SLOTS: void message(MigratorBase::MessageType type, const QString &msg); }; @@ -52,7 +51,7 @@ bool operator==(const Row &other) const; -private slots: +private Q_SLOTS: void stateChanged(MigratorBase::MigrationState); void progress(int); }; @@ -71,12 +70,12 @@ }; bool addMigrator(const QSharedPointer &migrator); - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; - virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const; - virtual QModelIndex parent(const QModelIndex &child) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; + int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; + QModelIndex parent(const QModelIndex &child) const Q_DECL_OVERRIDE; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; QSharedPointer migrator(const QString &identifier) const; QList< QSharedPointer > migrators() const; @@ -107,7 +106,7 @@ { Q_OBJECT public: - explicit MigrationScheduler(KJobTrackerInterface *jobTracker = 0, QObject *parent = 0); + explicit MigrationScheduler(KJobTrackerInterface *jobTracker = Q_NULLPTR, QObject *parent = Q_NULLPTR); virtual ~MigrationScheduler(); void addMigrator(const QSharedPointer &migrator); diff -Nru kdepim-runtime-4.14.6/agents/migration/migrationstatuswidget.cpp kdepim-runtime-15.08.0/agents/migration/migrationstatuswidget.cpp --- kdepim-runtime-4.14.6/agents/migration/migrationstatuswidget.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/migrationstatuswidget.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,36 +23,34 @@ #include "migrationscheduler.h" #include #include -#include #include #include -#include #include #include -#include -#include -#include +#include +#include #include +#include MigrationStatusWidget::MigrationStatusWidget(MigrationScheduler &scheduler, QWidget *parent) - :QWidget(parent), - mScheduler(scheduler) + : QWidget(parent), + mScheduler(scheduler) { QVBoxLayout *vboxLayout = new QVBoxLayout; { KToolBar *toolbar = new KToolBar(QLatin1String("MigrationControlToolbar"), this); QAction *start = toolbar->addAction(QLatin1String("Start")); - start->setIcon(KIcon(QLatin1String("media-playback-start"))); - connect(start, SIGNAL(triggered(bool)), this, SLOT(startSelected())); + start->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start"))); + connect(start, &QAction::triggered, this, &MigrationStatusWidget::startSelected); QAction *pause = toolbar->addAction(QLatin1String("Pause")); - pause->setIcon(KIcon(QLatin1String("media-playback-pause"))); - connect(pause, SIGNAL(triggered(bool)), this, SLOT(pauseSelected())); + pause->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-pause"))); + connect(pause, &QAction::triggered, this, &MigrationStatusWidget::pauseSelected); QAction *abort = toolbar->addAction(QLatin1String("Abort")); - abort->setIcon(KIcon(QLatin1String("media-playback-stop"))); - connect(abort, SIGNAL(triggered(bool)), this, SLOT(abortSelected())); + abort->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-stop"))); + connect(abort, &QAction::triggered, this, &MigrationStatusWidget::abortSelected); vboxLayout->addWidget(toolbar); } @@ -63,7 +61,7 @@ Q_ASSERT(mSelectionModel); //Not sure why this is required, but otherwise the view doesn't load anything from the model treeView->update(QModelIndex()); - connect(treeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(onItemActivated(QModelIndex))); + connect(treeView, &QTreeView::doubleClicked, this, &MigrationStatusWidget::onItemActivated); vboxLayout->addWidget(treeView); } @@ -93,8 +91,15 @@ void MigrationStatusWidget::onItemActivated(const QModelIndex &index) { - KDialog *dlg = new KDialog(this); + QDialog *dlg = new QDialog(this); + QVBoxLayout *topLayout = new QVBoxLayout; + dlg->setLayout(topLayout); QWidget *widget = new QWidget(dlg); + topLayout->addWidget(widget); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); + connect(buttonBox, &QDialogButtonBox::accepted, dlg, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, dlg, &QDialog::reject); + topLayout->addWidget(buttonBox); QVBoxLayout *vboxLayout = new QVBoxLayout; { @@ -106,20 +111,17 @@ } { QHBoxLayout *hboxLayout = new QHBoxLayout; - QLabel *label = new QLabel(QString::fromLatin1("%2").arg(index.data(MigratorModel::LogfileRole).toString()).arg(ki18n("Logfile").toString()), widget); + QLabel *label = new QLabel(QStringLiteral("%2").arg(index.data(MigratorModel::LogfileRole).toString()).arg(ki18n("Logfile").toString()), widget); label->setOpenExternalLinks(true); hboxLayout->addWidget(label); hboxLayout->addStretch(); vboxLayout->addLayout(hboxLayout); } widget->setLayout(vboxLayout); - dlg->setMainWidget(widget); dlg->setAttribute(Qt::WA_DeleteOnClose); - dlg->setCaption(i18nc("Title of the window displaying the log of a single migration job.", "Migration Info")); - dlg->setButtons(KDialog::Close); + dlg->setWindowTitle(i18nc("Title of the window displaying the log of a single migration job.", "Migration Info")); dlg->resize(600, 300); dlg->show(); } - diff -Nru kdepim-runtime-4.14.6/agents/migration/migrationstatuswidget.h kdepim-runtime-15.08.0/agents/migration/migrationstatuswidget.h --- kdepim-runtime-4.14.6/agents/migration/migrationstatuswidget.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/migrationstatuswidget.h 2015-08-10 21:01:02.000000000 +0000 @@ -30,15 +30,15 @@ { Q_OBJECT public: - explicit MigrationStatusWidget(MigrationScheduler &scheduler, QWidget *parent = 0); -private slots: + explicit MigrationStatusWidget(MigrationScheduler &scheduler, QWidget *parent = Q_NULLPTR); +private Q_SLOTS: void startSelected(); void pauseSelected(); void abortSelected(); private: MigrationScheduler &mScheduler; QItemSelectionModel *mSelectionModel; -public slots: +public Q_SLOTS: void onItemActivated(const QModelIndex &); }; diff -Nru kdepim-runtime-4.14.6/agents/migration/tests/CMakeLists.txt kdepim-runtime-15.08.0/agents/migration/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/agents/migration/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/.. -) - -kde4_add_executable(schedulertest schedulertest.cpp ../migrationscheduler.cpp ../migrationexecutor.cpp) -target_link_libraries(schedulertest - gidmigration - ${KDE4_KDEUI_LIBRARY} - ${KDE4_KDECORE_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${QT_QTCORE_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ${QT_QTTEST_LIBRARY} -) -add_test(schedulertest schedulertest) \ No newline at end of file diff -Nru kdepim-runtime-4.14.6/agents/migration/tests/dummymigrator.cpp kdepim-runtime-15.08.0/agents/migration/tests/dummymigrator.cpp --- kdepim-runtime-4.14.6/agents/migration/tests/dummymigrator.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/tests/dummymigrator.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright 2013 Christian Mollekopf - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License or (at your option) version 3 or any later version - * accepted by the membership of KDE e.V. (or its successor approved - * by the membership of KDE e.V.), which shall act as a proxy - * defined in Section 14 of version 3 of the license. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "dummymigrator.h" -#include -#include - -DummyMigrator::DummyMigrator(const QString &identifier) -: MigratorBase(QLatin1String("dummymigrator") + identifier, QString(), QString()) -{} - -QString DummyMigrator::displayName() const -{ - return QLatin1String("dummymigrator"); -} - -void DummyMigrator::startWork() -{ - kDebug(); - QTimer::singleShot(10000, this, SLOT(onTimerElapsed())); -} - -void DummyMigrator::onTimerElapsed() -{ - kDebug(); - setMigrationState(Complete); -} - -bool DummyMigrator::shouldAutostart() const -{ - return true; -} - -bool DummyMigrator::canStart() -{ - return true; -} - -void DummyMigrator::pause() -{ - kDebug(); - MigratorBase::pause(); -} - -void DummyMigrator::abort() -{ - kDebug(); - MigratorBase::abort(); -} - diff -Nru kdepim-runtime-4.14.6/agents/migration/tests/dummymigrator.h kdepim-runtime-15.08.0/agents/migration/tests/dummymigrator.h --- kdepim-runtime-4.14.6/agents/migration/tests/dummymigrator.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/tests/dummymigrator.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright 2013 Christian Mollekopf - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License or (at your option) version 3 or any later version - * accepted by the membership of KDE e.V. (or its successor approved - * by the membership of KDE e.V.), which shall act as a proxy - * defined in Section 14 of version 3 of the license. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifndef DUMMYMIGRATOR_H -#define DUMMYMIGRATOR_H - -#include - -/** - * Dummy migrator that simply completes after 10s and always autostarts. - * Add to the scheduler to play with the migrationagent. - */ -class DummyMigrator : public MigratorBase -{ - Q_OBJECT -public: - explicit DummyMigrator(const QString &identifier); - - virtual QString displayName() const; - virtual void startWork(); - - virtual bool shouldAutostart() const; - virtual bool canStart(); - virtual void pause(); - - virtual void abort(); -private slots: - void onTimerElapsed(); -}; - -#endif \ No newline at end of file diff -Nru kdepim-runtime-4.14.6/agents/migration/tests/schedulertest.cpp kdepim-runtime-15.08.0/agents/migration/tests/schedulertest.cpp --- kdepim-runtime-4.14.6/agents/migration/tests/schedulertest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/migration/tests/schedulertest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,293 +0,0 @@ -/* - * Copyright 2013 Christian Mollekopf - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License or (at your option) version 3 or any later version - * accepted by the membership of KDE e.V. (or its successor approved - * by the membership of KDE e.V.), which shall act as a proxy - * defined in Section 14 of version 3 of the license. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include -#include -#include -#include - -#include "../migrationscheduler.h" -#include - -Q_DECLARE_METATYPE(QModelIndex) - -class Testmigrator: public MigratorBase -{ - Q_OBJECT -public: - explicit Testmigrator(const QString &identifier, QObject *parent = 0): - MigratorBase(QLatin1String("testmigrator") + identifier, QString(), QString(), parent), mAutostart(false) - {} - - virtual QString displayName() const - { - return QLatin1String("name"); - } - - virtual void startWork() - {} - - virtual void abort() - { - setMigrationState(Aborted); - } - - virtual void complete() - { - setMigrationState(Complete); - } - - virtual bool shouldAutostart() const - { - return mAutostart; - } - - virtual void pause() - { - setMigrationState(Paused); - } - - virtual void resume() - { - setMigrationState(InProgress); - } - - bool mAutostart; -}; - -class TestJobTracker : public KJobTrackerInterface -{ -public: - TestJobTracker() : mPercent(0) - {} - - virtual void registerJob(KJob* job) - { - KJobTrackerInterface::registerJob(job); - mJobs << job; - } - - virtual void unregisterJob(KJob* job) - { - mJobs.removeAll(job); - } - - virtual void finished(KJob* job) - { - mJobs.removeAll(job); - } - - virtual void percent(KJob* job, long unsigned int percent) - { - Q_UNUSED(job); - mPercent = percent; - } - - QList mJobs; - int mPercent; -}; - -class SchedulerTest: public QObject -{ - Q_OBJECT -private slots: - - void initTestcase() - { - qRegisterMetaType(); - } - - void testInsertRow() - { - MigrationScheduler scheduler; - QAbstractItemModel &model(scheduler.model()); - - QCOMPARE(model.rowCount(), 0); - - QSignalSpy rowsInsertedSpy(&model, SIGNAL(rowsInserted(QModelIndex,int,int))); - QVERIFY(rowsInsertedSpy.isValid()); - - scheduler.addMigrator(QSharedPointer(new Testmigrator(QLatin1String("id")))); - QCOMPARE(model.rowCount(), 1); - QCOMPARE(rowsInsertedSpy.count(), 1); - - QVERIFY(model.index(0, 0).isValid()); - QVERIFY(!model.index(1, 0).isValid()); - - scheduler.addMigrator(QSharedPointer(new Testmigrator(QLatin1String("id2")))); - QCOMPARE(model.rowCount(), 2); - QCOMPARE(rowsInsertedSpy.count(), 2); - } - - void testDisplayName() - { - MigrationScheduler scheduler; - scheduler.addMigrator(QSharedPointer(new Testmigrator(QLatin1String("id")))); - QAbstractItemModel &model(scheduler.model()); - QCOMPARE(model.data(model.index(0, 0)).toString(), QLatin1String("name")); - } - - void testStartStop() - { - MigrationScheduler scheduler; - QSharedPointer migrator(new Testmigrator(QLatin1String("id"))); - scheduler.addMigrator(migrator); - - scheduler.start(migrator->identifier()); - QCOMPARE(migrator->migrationState(), MigratorBase::InProgress); - - scheduler.abort(migrator->identifier()); - QCOMPARE(migrator->migrationState(), MigratorBase::Aborted); - } - - void testNoDuplicates() - { - MigrationScheduler scheduler; - scheduler.addMigrator(QSharedPointer(new Testmigrator(QLatin1String("id")))); - scheduler.addMigrator(QSharedPointer(new Testmigrator(QLatin1String("id")))); - QAbstractItemModel &model(scheduler.model()); - QCOMPARE(model.rowCount(), 1); - } - - void testMigrationStateChanged() - { - MigrationScheduler scheduler; - scheduler.addMigrator(QSharedPointer(new Testmigrator(QLatin1String("id1")))); - QSharedPointer migrator(new Testmigrator(QLatin1String("id2"))); - scheduler.addMigrator(migrator); - scheduler.addMigrator(QSharedPointer(new Testmigrator(QLatin1String("id3")))); - QAbstractItemModel &model(scheduler.model()); - - QSignalSpy spy(&model, SIGNAL(dataChanged(QModelIndex,QModelIndex))); - QVERIFY(spy.isValid()); - migrator->start(); - - QCOMPARE(spy.count(), 1); - const QVariantList args = spy.takeFirst(); - QCOMPARE(args.at(0).value().row(), 1); - QCOMPARE(args.at(1).value().row(), 1); - } - - void testRunMultiple() - { - MigrationScheduler scheduler; - - QSharedPointer m1(new Testmigrator(QLatin1String("id1"))); - scheduler.addMigrator(m1); - - QSharedPointer m2(new Testmigrator(QLatin1String("id2"))); - scheduler.addMigrator(m2); - - scheduler.start(m1->identifier()); - scheduler.start(m2->identifier()); - - QCOMPARE(m1->migrationState(), MigratorBase::InProgress); - QCOMPARE(m2->migrationState(), MigratorBase::InProgress); - } - - void testRunAutostart() - { - MigrationScheduler scheduler; - - QSharedPointer m1(new Testmigrator(QLatin1String("id1"))); - m1->mAutostart = true; - scheduler.addMigrator(m1); - - QSharedPointer m2(new Testmigrator(QLatin1String("id2"))); - m2->mAutostart = true; - scheduler.addMigrator(m2); - - QCOMPARE(m1->migrationState(), MigratorBase::InProgress); - kDebug() << m2->migrationState(); - QCOMPARE(m2->migrationState(), MigratorBase::None); - m1->complete(); - QCOMPARE(m2->migrationState(), MigratorBase::InProgress); - - } - - void testJobTracker() - { - TestJobTracker jobTracker; - MigrationScheduler scheduler(&jobTracker); - QSharedPointer m1(new Testmigrator(QLatin1String("id1"))); - m1->mAutostart = true; - scheduler.addMigrator(m1); - - QCOMPARE(jobTracker.mJobs.size(), 1); - - m1->complete(); - - //Give the job some time to delete itself - QTest::qWait(500); - - QCOMPARE(jobTracker.mJobs.size(), 0); - } - - void testSuspend() - { - TestJobTracker jobTracker; - MigrationScheduler scheduler(&jobTracker); - QSharedPointer m1(new Testmigrator(QLatin1String("id1"))); - m1->mAutostart = true; - scheduler.addMigrator(m1); - jobTracker.mJobs.first()->suspend(); - QCOMPARE(m1->migrationState(), MigratorBase::Paused); - jobTracker.mJobs.first()->resume(); - QCOMPARE(m1->migrationState(), MigratorBase::InProgress); - } - - /* - * Even if the migrator doesn't implement suspend, the executor suspends after completing the current job and waits with starting the second job. - */ - void testJobFinishesDuringSuspend() - { - TestJobTracker jobTracker; - MigrationScheduler scheduler(&jobTracker); - QSharedPointer m1(new Testmigrator(QLatin1String("id1"))); - m1->mAutostart = true; - scheduler.addMigrator(m1); - QSharedPointer m2(new Testmigrator(QLatin1String("id2"))); - m2->mAutostart = true; - scheduler.addMigrator(m2); - jobTracker.mJobs.first()->suspend(); - m1->complete(); - QCOMPARE(m2->migrationState(), MigratorBase::None); - jobTracker.mJobs.first()->resume(); - QCOMPARE(m2->migrationState(), MigratorBase::InProgress); - } - - void testProgressReporting() - { - TestJobTracker jobTracker; - MigrationScheduler scheduler(&jobTracker); - QSharedPointer m1(new Testmigrator(QLatin1String("id1"))); - m1->mAutostart = true; - scheduler.addMigrator(m1); - QCOMPARE(jobTracker.mPercent, 0); - m1->complete(); - QCOMPARE(jobTracker.mPercent, 100); - } - -}; - -QTEST_MAIN(SchedulerTest) - -#include "schedulertest.moc" diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/akonadi_newmailnotifier_agent.notifyrc kdepim-runtime-15.08.0/agents/newmailnotifier/akonadi_newmailnotifier_agent.notifyrc --- kdepim-runtime-4.14.6/agents/newmailnotifier/akonadi_newmailnotifier_agent.notifyrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/akonadi_newmailnotifier_agent.notifyrc 2015-08-10 21:01:02.000000000 +0000 @@ -1,6 +1,7 @@ [Global] IconName=kmail Comment=New email notify +Comment[bg]=Уведомяване за нова поща Comment[bs]=Obavijest o novoj pošti Comment[ca]=Notificador de correu electrònic nou Comment[ca@valencia]=Notificador de correu electrònic nou @@ -43,6 +44,7 @@ Comment[zh_CN]=新邮件提醒 Comment[zh_TW]=新郵件通知 Name=New email notify +Name[bg]=Уведомяване за нова поща Name[bs]=Obavijest o novoj pošti Name[ca]=Notificador de correu electrònic nou Name[ca@valencia]=Notificador de correu electrònic nou @@ -88,6 +90,7 @@ [Event/new-email] Name=New email arrived +Name[bg]=Пристигна нова поща Name[bs]=Nova pošta stigla Name[ca]=Ha arribat correu electrònic nou Name[ca@valencia]=Ha arribat correu electrònic nou @@ -132,43 +135,3 @@ Name[zh_TW]=新郵件已抵達 Action=Popup -[Event/text-to-speak-not-found] -Name=Jovie Text-to-Speech Service not found -Name[bs]=Jovie Tservis za prebacivanje teksta u govor nije nađen -Name[ca]=No s'ha trobat el servei Jovie de text a veu -Name[ca@valencia]=No s'ha trobat el servei Jovie de text a veu -Name[da]=Jovie tekst-til-tale-tjeneste ikke fundet -Name[de]=Der Sprachausgabedienstes Jovie wurde nicht gefunden -Name[el]=Η υπηρεσία Jovie Text-to-Speech δε βρέθηκε -Name[en_GB]=Jovie Text-to-Speech Service not found -Name[es]=Servicio de texto a voz Jovie no encontrado -Name[et]=Jovie teksti ettelugemise teenust ei leitud -Name[fi]=Jovie-puhesyntetisaattoria ei löytynyt -Name[fr]=Impossible de trouver le service de synthèse vocale Jovie -Name[gl]=Non foi posíbel atopar o servizo de texto lido Jovie -Name[hu]=A Jovie szövegfelolvasó szolgáltatás nem található -Name[ia]=Il non trovava le servicio de texto-a-Voce Jovie -Name[it]=Servizio di sintesi vocale Jovie non trovato -Name[kk]=Jovie мәтінді дауыстап оқу қызметі табылған жоқ -Name[ko]=Jovie 텍스트 음성 합성 서비스를 찾을 수 없음 -Name[lt]=Jovie Tekstas į kalbą tarnyba nerasta -Name[nb]=Fant ikke Jovie tekst-til-tale-tjeneste -Name[nds]=Vörleesdeenst „Jovie“ lett sik nich finnen -Name[nl]=Tekst-naar-spraak-service van Jovie niet gevonden -Name[pl]=NIe znaleziono usługi tekst-do-mowy Jovie -Name[pt]=Serviço de Texto-para-Fala Jovie Não Encontrado -Name[pt_BR]=Não foi encontrado o serviço de Texto-para-Fala do Jovie -Name[ru]=Не удалось найти службу синтеза речи Jovie -Name[sk]=Služba textu na reč Jovie sa nenašla -Name[sr]=Сервис за текст‑у‑говор Џови није нађен -Name[sr@ijekavian]=Сервис за текст‑у‑говор Џови није нађен -Name[sr@ijekavianlatin]=Servis za tekst‑u‑govor Džovi nije nađen -Name[sr@latin]=Servis za tekst‑u‑govor Džovi nije nađen -Name[sv]=Jovie text-till-taltjänst hittades inte -Name[tr]=Jovie Metin Okuma Hizmeti bulunamadı -Name[uk]=Не знайдено служби синтезу мовлення Jovie -Name[x-test]=xxJovie Text-to-Speech Service not foundxx -Name[zh_CN]=未找到 Jovie 语音合成服务 -Name[zh_TW]=找不到 Jovie 文字轉語音服務 -Action=Popup - diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/autotests/CMakeLists.txt kdepim-runtime-15.08.0/agents/newmailnotifier/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/agents/newmailnotifier/autotests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/autotests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ - -set( newmailnotifierattribute_source newmailnotifierattributetest.cpp ../newmailnotifierattribute.cpp) -kde4_add_unit_test( newmailnotifierattributetest ${newmailnotifierattribute_source}) -target_link_libraries( newmailnotifierattributetest ${QT_QTTEST_LIBRARY} ${KDE4_KDECORE_LIBS} ${QT_QTGUI_LIBRARY} ${KDEPIMLIBS_AKONADI_LIBS}) diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/autotests/newmailnotifierattributetest.cpp kdepim-runtime-15.08.0/agents/newmailnotifier/autotests/newmailnotifierattributetest.cpp --- kdepim-runtime-4.14.6/agents/newmailnotifier/autotests/newmailnotifierattributetest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/autotests/newmailnotifierattributetest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -/* - Copyright (c) 2014 Montel Laurent - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#include "newmailnotifierattributetest.h" -#include "../newmailnotifierattribute.h" -#include - -NewMailNotifierAttributeTest::NewMailNotifierAttributeTest(QObject *parent) - : QObject(parent) -{ - -} - -NewMailNotifierAttributeTest::~NewMailNotifierAttributeTest() -{ - -} - -void NewMailNotifierAttributeTest::shouldHaveDefaultValue() -{ - NewMailNotifierAttribute attr; - QVERIFY(!attr.ignoreNewMail()); -} - -void NewMailNotifierAttributeTest::shouldSetIgnoreNotification() -{ - NewMailNotifierAttribute attr; - bool ignore = false; - attr.setIgnoreNewMail(ignore); - QCOMPARE(attr.ignoreNewMail(), ignore); - ignore = true; - attr.setIgnoreNewMail(ignore); - QCOMPARE(attr.ignoreNewMail(), ignore); -} - -void NewMailNotifierAttributeTest::shouldSerializedData() -{ - NewMailNotifierAttribute attr; - attr.setIgnoreNewMail(true); - QByteArray ba = attr.serialized(); - NewMailNotifierAttribute result; - result.deserialize(ba); - QVERIFY(attr == result); -} - -void NewMailNotifierAttributeTest::shouldCloneAttribute() -{ - NewMailNotifierAttribute attr; - attr.setIgnoreNewMail(true); - NewMailNotifierAttribute *result = attr.clone(); - QVERIFY(attr == *result); - delete result; -} - -QTEST_KDEMAIN(NewMailNotifierAttributeTest, NoGUI) diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/autotests/newmailnotifierattributetest.h kdepim-runtime-15.08.0/agents/newmailnotifier/autotests/newmailnotifierattributetest.h --- kdepim-runtime-4.14.6/agents/newmailnotifier/autotests/newmailnotifierattributetest.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/autotests/newmailnotifierattributetest.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -/* - Copyright (c) 2014 Montel Laurent - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef NEWMAILNOTIFIERATTRIBUTETEST_H -#define NEWMAILNOTIFIERATTRIBUTETEST_H - -#include - -class NewMailNotifierAttributeTest : public QObject -{ - Q_OBJECT -public: - explicit NewMailNotifierAttributeTest(QObject *parent = 0); - ~NewMailNotifierAttributeTest(); -private Q_SLOTS: - void shouldHaveDefaultValue(); - void shouldSetIgnoreNotification(); - void shouldSerializedData(); - void shouldCloneAttribute(); -}; - -#endif // NEWMAILNOTIFIERATTRIBUTETEST_H diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/CMakeLists.txt kdepim-runtime-15.08.0/agents/newmailnotifier/CMakeLists.txt --- kdepim-runtime-4.14.6/agents/newmailnotifier/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,59 +1,56 @@ -include_directories( - ${kdepim-runtime_SOURCE_DIR} - ${Boost_INCLUDE_DIR} -) -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) +include_directories(${kdepim-runtime_BINARY_DIR}) +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_newmailnotifier_agent\") + add_definitions( -DQT_NO_CAST_FROM_ASCII ) add_definitions( -DQT_NO_CAST_TO_ASCII ) - - set(newmailnotifieragent_SRCS + newmailnotifier_debug.cpp newmailnotifiersettingsdialog.cpp newmailnotifieragent.cpp - newmailnotifierattribute.cpp specialnotifierjob.cpp newmailnotifierselectcollectionwidget.cpp newmailnotifiershowmessagejob.cpp ) -kde4_add_kcfg_files(newmailnotifieragent_SRCS +kconfig_add_kcfg_files(newmailnotifieragent_SRCS newmailnotifieragentsettings.kcfgc ) -qt4_add_dbus_adaptor(newmailnotifieragent_SRCS org.freedesktop.Akonadi.NewMailNotifier.xml newmailnotifieragent.h NewMailNotifierAgent) +qt5_add_dbus_adaptor(newmailnotifieragent_SRCS org.freedesktop.Akonadi.NewMailNotifier.xml newmailnotifieragent.h NewMailNotifierAgent) -kde4_add_executable( akonadi_newmailnotifier_agent ${newmailnotifieragent_SRCS}) +add_executable( akonadi_newmailnotifier_agent ${newmailnotifieragent_SRCS}) target_link_libraries( akonadi_newmailnotifier_agent - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${KDEPIMLIBS_AKONADI_KMIME_LIBS} - ${QT_QTCORE_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ${KDE4_KNOTIFYCONFIG_LIBS} - ${KDEPIMLIBS_KABC_LIBS} - ${KDEPIMLIBS_KPIMUTILS_LIBS} - ${KDEPIMLIBS_AKONADI_CONTACT_LIBS} - ${KDEPIMLIBS_KPIMIDENTITIES_LIBS} + KF5::AkonadiCore + KF5::Mime + KF5::AkonadiMime + KF5::AkonadiContact + KF5::Codecs + KF5::IdentityManagement + KF5::NotifyConfig + KF5::AkonadiAgentBase + KF5::DBusAddons ) +if (Qt5TextToSpeech_FOUND) + target_link_libraries(akonadi_newmailnotifier_agent + Qt5::TextToSpeech) +endif() -if (Q_WS_MAC) +if( APPLE ) set_target_properties( akonadi_newmailnotifier_agent PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/Info.plist.template) set_target_properties( akonadi_newmailnotifier_agent PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.newmailnotifier") set_target_properties( akonadi_newmailnotifier_agent PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE New Mail Notifier") endif () -install(TARGETS akonadi_newmailnotifier_agent ${INSTALL_TARGETS_DEFAULT_ARGS} ) +install(TARGETS akonadi_newmailnotifier_agent ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} ) -install(FILES newmailnotifieragent.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents") -install(FILES akonadi_newmailnotifier_agent.notifyrc DESTINATION "${DATA_INSTALL_DIR}/akonadi_newmailnotifier_agent" ) +install(FILES newmailnotifieragent.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents") +install(FILES akonadi_newmailnotifier_agent.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFY5RCDIR} ) -add_subdirectory(kconf_update) -add_subdirectory(autotests) diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/kconf_update/CMakeLists.txt kdepim-runtime-15.08.0/agents/newmailnotifier/kconf_update/CMakeLists.txt --- kdepim-runtime-4.14.6/agents/newmailnotifier/kconf_update/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/kconf_update/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -install( FILES newmailnotifier.upd DESTINATION ${KCONF_UPDATE_INSTALL_DIR}) diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/kconf_update/newmailnotifier.upd kdepim-runtime-15.08.0/agents/newmailnotifier/kconf_update/newmailnotifier.upd --- kdepim-runtime-4.14.6/agents/newmailnotifier/kconf_update/newmailnotifier.upd 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/kconf_update/newmailnotifier.upd 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -# Migrate kmail's notifier setting to Akonadi new mail notifier -Id=initial-newmailnotifier-migration -File=kmail2rc,akonadi_newmailnotifier_agentrc -Group=General,General -Key=beep-on-mail,beepOnNewMails -Key=VerboseNewMailNotification,verboseNotification diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifieragent.cpp kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifieragent.cpp --- kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifieragent.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifieragent.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,92 +21,77 @@ #include "newmailnotifieragent.h" -#include "newmailnotifierattribute.h" +#include #include "specialnotifierjob.h" #include "newmailnotifieradaptor.h" #include "newmailnotifieragentsettings.h" #include "newmailnotifiersettingsdialog.h" -#include +#include -#include +#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -#include -#include -#include -#include -#include #include +#include +#include "newmailnotifier_debug.h" #include - +#include +#include using namespace Akonadi; -NewMailNotifierAgent::NewMailNotifierAgent( const QString &id ) - : AgentBase( id ) +NewMailNotifierAgent::NewMailNotifierAgent(const QString &id) + : AgentBase(id) { - Akonadi::AttributeFactory::registerAttribute(); - new NewMailNotifierAdaptor( this ); + Kdelibs4ConfigMigrator migrate(QStringLiteral("newmailnotifieragent")); + migrate.setConfigFiles(QStringList() << QStringLiteral("akonadi_newmailnotifier_agentrc") << QStringLiteral("akonadi_newmailnotifier_agent.notifyrc")); + migrate.migrate(); + + KLocalizedString::setApplicationDomain("akonadi_newmailnotifier_agent"); + Akonadi::AttributeFactory::registerAttribute(); + new NewMailNotifierAdaptor(this); - mIdentityManager = new KPIMIdentities::IdentityManager( false, this ); + mIdentityManager = new KIdentityManagement::IdentityManager(false, this); connect(mIdentityManager, SIGNAL(changed()), SLOT(slotIdentitiesChanged())); slotIdentitiesChanged(); - mDefaultPixmap = KIcon( QLatin1String("kmail") ).pixmap( KIconLoader::SizeMedium, KIconLoader::SizeMedium ); + mDefaultPixmap = QIcon::fromTheme(QStringLiteral("kmail")).pixmap(KIconLoader::SizeMedium, KIconLoader::SizeMedium); - DBusConnectionPool::threadConnection().registerObject( QLatin1String( "/NewMailNotifierAgent" ), - this, QDBusConnection::ExportAdaptors ); - DBusConnectionPool::threadConnection().registerService( QLatin1String( "org.freedesktop.Akonadi.NewMailNotifierAgent" ) ); - - connect( Akonadi::AgentManager::self(), SIGNAL(instanceStatusChanged(Akonadi::AgentInstance)), - this, SLOT(slotInstanceStatusChanged(Akonadi::AgentInstance)) ); - connect( Akonadi::AgentManager::self(), SIGNAL(instanceRemoved(Akonadi::AgentInstance)), - this, SLOT(slotInstanceRemoved(Akonadi::AgentInstance)) ); - connect( Akonadi::AgentManager::self(), SIGNAL(instanceAdded(Akonadi::AgentInstance)), - this, SLOT(slotInstanceAdded(Akonadi::AgentInstance)) ); - connect( Akonadi::AgentManager::self(), SIGNAL(instanceNameChanged(Akonadi::AgentInstance)), - this, SLOT(slotInstanceNameChanged(Akonadi::AgentInstance)) ); - - - changeRecorder()->setMimeTypeMonitored( KMime::Message::mimeType() ); - changeRecorder()->itemFetchScope().setCacheOnly( true ); - changeRecorder()->itemFetchScope().setFetchModificationTime( false ); - changeRecorder()->fetchCollection( true ); - changeRecorder()->setChangeRecordingEnabled( false ); - changeRecorder()->ignoreSession( Akonadi::Session::defaultSession() ); - changeRecorder()->collectionFetchScope().setAncestorRetrieval( Akonadi::CollectionFetchScope::All ); + KDBusConnectionPool::threadConnection().registerObject(QStringLiteral("/NewMailNotifierAgent"), + this, QDBusConnection::ExportAdaptors); + KDBusConnectionPool::threadConnection().registerService(QStringLiteral("org.freedesktop.Akonadi.NewMailNotifierAgent")); + + connect(Akonadi::AgentManager::self(), &Akonadi::AgentManager::instanceStatusChanged, this, &NewMailNotifierAgent::slotInstanceStatusChanged); + connect(Akonadi::AgentManager::self(), &Akonadi::AgentManager::instanceRemoved, this, &NewMailNotifierAgent::slotInstanceRemoved); + connect(Akonadi::AgentManager::self(), &Akonadi::AgentManager::instanceAdded, this, &NewMailNotifierAgent::slotInstanceAdded); + connect(Akonadi::AgentManager::self(), &Akonadi::AgentManager::instanceNameChanged, this, &NewMailNotifierAgent::slotInstanceNameChanged); + + changeRecorder()->setMimeTypeMonitored(KMime::Message::mimeType()); + changeRecorder()->itemFetchScope().setCacheOnly(true); + changeRecorder()->itemFetchScope().setFetchModificationTime(false); + changeRecorder()->fetchCollection(true); + changeRecorder()->setChangeRecordingEnabled(false); + changeRecorder()->ignoreSession(Akonadi::Session::defaultSession()); + changeRecorder()->collectionFetchScope().setAncestorRetrieval(Akonadi::CollectionFetchScope::All); changeRecorder()->setCollectionMonitored(Collection::root(), true); - mTimer.setInterval( 5 * 1000 ); - connect( &mTimer, SIGNAL(timeout()), SLOT(slotShowNotifications()) ); + mTimer.setInterval(5 * 1000); + connect(&mTimer, &QTimer::timeout, this, &NewMailNotifierAgent::slotShowNotifications); - if (NewMailNotifierAgentSettings::textToSpeakEnabled()) { - if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QLatin1String("org.kde.kttsd"))) { - QString error; - if (KToolInvocation::startServiceByDesktopName(QLatin1String("kttsd"), QStringList(), &error)) { - KNotification::event( QLatin1String("text-to-speak-not-found"), - i18n("Starting Jovie Text-to-Speech Service Failed %1", error), - mDefaultPixmap, - 0, - KNotification::CloseOnTimeout, - KGlobal::mainComponent()); - } - } - } if (isActive()) { - mTimer.setSingleShot( true ); + mTimer.setSingleShot(true); } } @@ -125,7 +110,7 @@ void NewMailNotifierAgent::setExcludeMyselfFromNotification(bool b) { NewMailNotifierAgentSettings::setExcludeEmailsFromMe(b); - NewMailNotifierAgentSettings::self()->writeConfig(); + NewMailNotifierAgentSettings::self()->save(); } bool NewMailNotifierAgent::excludeMyselfFromNotification() const @@ -136,7 +121,7 @@ void NewMailNotifierAgent::setShowPhoto(bool show) { NewMailNotifierAgentSettings::setShowPhoto(show); - NewMailNotifierAgentSettings::self()->writeConfig(); + NewMailNotifierAgentSettings::self()->save(); } bool NewMailNotifierAgent::showPhoto() const @@ -147,7 +132,7 @@ void NewMailNotifierAgent::setShowFrom(bool show) { NewMailNotifierAgentSettings::setShowFrom(show); - NewMailNotifierAgentSettings::self()->writeConfig(); + NewMailNotifierAgentSettings::self()->save(); } bool NewMailNotifierAgent::showFrom() const @@ -158,7 +143,7 @@ void NewMailNotifierAgent::setShowSubject(bool show) { NewMailNotifierAgentSettings::setShowSubject(show); - NewMailNotifierAgentSettings::self()->writeConfig(); + NewMailNotifierAgentSettings::self()->save(); } bool NewMailNotifierAgent::showSubject() const @@ -169,7 +154,7 @@ void NewMailNotifierAgent::setShowFolderName(bool show) { NewMailNotifierAgentSettings::setShowFolder(show); - NewMailNotifierAgentSettings::self()->writeConfig(); + NewMailNotifierAgentSettings::self()->save(); } bool NewMailNotifierAgent::showFolderName() const @@ -180,7 +165,7 @@ void NewMailNotifierAgent::setEnableAgent(bool enabled) { NewMailNotifierAgentSettings::setEnabled(enabled); - NewMailNotifierAgentSettings::self()->writeConfig(); + NewMailNotifierAgentSettings::self()->save(); if (!enabled) { clearAll(); } @@ -189,7 +174,7 @@ void NewMailNotifierAgent::setVerboseMailNotification(bool verbose) { NewMailNotifierAgentSettings::setVerboseNotification(verbose); - NewMailNotifierAgentSettings::self()->writeConfig(); + NewMailNotifierAgentSettings::self()->save(); } bool NewMailNotifierAgent::verboseMailNotification() const @@ -200,7 +185,7 @@ void NewMailNotifierAgent::setBeepOnNewMails(bool beep) { NewMailNotifierAgentSettings::setBeepOnNewMails(beep); - NewMailNotifierAgentSettings::self()->writeConfig(); + NewMailNotifierAgentSettings::self()->save(); } bool NewMailNotifierAgent::beepOnNewMails() const @@ -211,7 +196,7 @@ void NewMailNotifierAgent::setTextToSpeakEnabled(bool enabled) { NewMailNotifierAgentSettings::setTextToSpeakEnabled(enabled); - NewMailNotifierAgentSettings::self()->writeConfig(); + NewMailNotifierAgentSettings::self()->save(); } bool NewMailNotifierAgent::textToSpeakEnabled() const @@ -222,7 +207,7 @@ void NewMailNotifierAgent::setTextToSpeak(const QString &msg) { NewMailNotifierAgentSettings::setTextToSpeak(msg); - NewMailNotifierAgentSettings::self()->writeConfig(); + NewMailNotifierAgentSettings::self()->save(); } QString NewMailNotifierAgent::textToSpeak() const @@ -249,23 +234,22 @@ void NewMailNotifierAgent::setShowButtonToDisplayMail(bool b) { NewMailNotifierAgentSettings::setShowButtonToDisplayMail(b); - NewMailNotifierAgentSettings::self()->writeConfig(); + NewMailNotifierAgentSettings::self()->save(); } - void NewMailNotifierAgent::showConfigureDialog(qlonglong windowId) { - configure( windowId ); + configure(windowId); } -void NewMailNotifierAgent::configure( WId windowId ) +void NewMailNotifierAgent::configure(WId windowId) { QPointer dialog = new NewMailNotifierSettingsDialog; if (windowId) { -#ifndef Q_WS_WIN - KWindowSystem::setMainWindow( dialog, windowId ); +#ifndef Q_OS_WIN + KWindowSystem::setMainWindow(dialog, windowId); #else - KWindowSystem::setMainWindow( dialog, (HWND)windowId ); + KWindowSystem::setMainWindow(dialog, (HWND)windowId); #endif } dialog->exec(); @@ -274,21 +258,22 @@ bool NewMailNotifierAgent::excludeSpecialCollection(const Akonadi::Collection &collection) const { - if ( collection.hasAttribute() ) + if (collection.hasAttribute()) { return true; + } - if ( collection.hasAttribute() ) { - if (collection.attribute()->ignoreNewMail()) { + if (collection.hasAttribute()) { + if (collection.attribute()->ignoreNewMail()) { return true; } } - if (!collection.contentMimeTypes().contains( KMime::Message::mimeType()) ) { + if (!collection.contentMimeTypes().contains(KMime::Message::mimeType())) { return true; } SpecialMailCollections::Type type = SpecialMailCollections::self()->specialCollectionType(collection); - switch(type) { + switch (type) { case SpecialMailCollections::Invalid: //Not a special collection case SpecialMailCollections::Inbox: return false; @@ -298,24 +283,25 @@ } -void NewMailNotifierAgent::itemsRemoved(const Item::List &items ) +void NewMailNotifierAgent::itemsRemoved(const Item::List &items) { - if (!isActive()) + if (!isActive()) { return; + } QHash< Akonadi::Collection, QList >::iterator end(mNewMails.end()); - for ( QHash< Akonadi::Collection, QList >::iterator it = mNewMails.begin(); it != end; ++it ) { + for (QHash< Akonadi::Collection, QList >::iterator it = mNewMails.begin(); it != end; ++it) { QList idList = it.value(); bool itemFound = false; - Q_FOREACH( const Item &item, items ) { + Q_FOREACH (const Item &item, items) { if (idList.contains(item.id())) { - idList.removeAll( item.id() ); + idList.removeAll(item.id()); itemFound = true; } } if (itemFound) { if (mNewMails[it.key()].isEmpty()) { - mNewMails.remove( it.key() ); + mNewMails.remove(it.key()); } else { mNewMails[it.key()] = idList; } @@ -323,18 +309,19 @@ } } -void NewMailNotifierAgent::itemsFlagsChanged( const Akonadi::Item::List &items, const QSet &addedFlags, const QSet &removedFlags ) +void NewMailNotifierAgent::itemsFlagsChanged(const Akonadi::Item::List &items, const QSet &addedFlags, const QSet &removedFlags) { - if (!isActive()) + if (!isActive()) { return; + } Q_FOREACH (const Akonadi::Item &item, items) { QHash< Akonadi::Collection, QList >::iterator end(mNewMails.end()); - for ( QHash< Akonadi::Collection, QList >::iterator it = mNewMails.begin(); it != end; ++it ) { - QList idList= it.value(); + for (QHash< Akonadi::Collection, QList >::iterator it = mNewMails.begin(); it != end; ++it) { + QList idList = it.value(); if (idList.contains(item.id()) && addedFlags.contains("\\SEEN")) { - idList.removeAll( item.id() ); - if ( idList.isEmpty() ) { - mNewMails.remove( it.key() ); + idList.removeAll(item.id()); + if (idList.isEmpty()) { + mNewMails.remove(it.key()); break; } else { (*it) = idList; @@ -344,33 +331,34 @@ } } -void NewMailNotifierAgent::itemsMoved( const Akonadi::Item::List &items, const Akonadi::Collection &collectionSource, const Akonadi::Collection &collectionDestination ) +void NewMailNotifierAgent::itemsMoved(const Akonadi::Item::List &items, const Akonadi::Collection &collectionSource, const Akonadi::Collection &collectionDestination) { - if (!isActive()) + if (!isActive()) { return; + } Q_FOREACH (const Akonadi::Item &item, items) { if (ignoreStatusMail(item)) { continue; } - if ( excludeSpecialCollection(collectionSource) ) { + if (excludeSpecialCollection(collectionSource)) { continue; // outbox, sent-mail, trash, drafts or templates. } - if ( mNewMails.contains( collectionSource ) ) { + if (mNewMails.contains(collectionSource)) { QList idListFrom = mNewMails[ collectionSource ]; - if ( idListFrom.contains( item.id() ) ) { - idListFrom.removeAll( item.id() ); + if (idListFrom.contains(item.id())) { + idListFrom.removeAll(item.id()); - if ( idListFrom.isEmpty() ) { - mNewMails.remove( collectionSource ); + if (idListFrom.isEmpty()) { + mNewMails.remove(collectionSource); } else { mNewMails[ collectionSource ] = idListFrom; } - if ( !excludeSpecialCollection(collectionDestination) ) { + if (!excludeSpecialCollection(collectionDestination)) { QList idListTo = mNewMails[ collectionDestination ]; - idListTo.append( item.id() ); + idListTo.append(item.id()); mNewMails[ collectionDestination ] = idListTo; } } @@ -381,18 +369,20 @@ bool NewMailNotifierAgent::ignoreStatusMail(const Akonadi::Item &item) { Akonadi::MessageStatus status; - status.setStatusFromFlags( item.flags() ); - if ( status.isRead() || status.isSpam() || status.isIgnored() ) + status.setStatusFromFlags(item.flags()); + if (status.isRead() || status.isSpam() || status.isIgnored()) { return true; + } return false; } -void NewMailNotifierAgent::itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ) +void NewMailNotifierAgent::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) { - if (!isActive()) + if (!isActive()) { return; + } - if ( excludeSpecialCollection(collection) ) { + if (excludeSpecialCollection(collection)) { return; // outbox, sent-mail, trash, drafts or templates. } @@ -400,19 +390,21 @@ return; } - if ( !mTimer.isActive() ) { + if (!mTimer.isActive()) { mTimer.start(); } - mNewMails[ collection ].append( item.id() ); + mNewMails[ collection ].append(item.id()); } void NewMailNotifierAgent::slotShowNotifications() { - if (mNewMails.isEmpty()) + if (mNewMails.isEmpty()) { return; + } - if (!isActive()) + if (!isActive()) { return; + } if (!mInstanceNameInProgress.isEmpty()) { //Restart timer until all is done. @@ -428,23 +420,25 @@ QStringList texts; QHash< Akonadi::Collection, QList >::const_iterator end(mNewMails.constEnd()); const int numberOfCollection(mNewMails.count()); - if (numberOfCollection > 1) + if (numberOfCollection > 1) { hasUniqMessage = false; + } - for ( QHash< Akonadi::Collection, QList >::const_iterator it = mNewMails.constBegin(); it != end; ++it ) { + for (QHash< Akonadi::Collection, QList >::const_iterator it = mNewMails.constBegin(); it != end; ++it) { Akonadi::EntityDisplayAttribute *attr = it.key().attribute(); QString displayName; - if ( attr && !attr->displayName().isEmpty() ) + if (attr && !attr->displayName().isEmpty()) { displayName = attr->displayName(); - else + } else { displayName = it.key().name(); + } if (hasUniqMessage) { if (it.value().count() == 0) { //You can have an unique folder with 0 message return; - } else if (it.value().count() == 1 ) { - item = it.value().first(); + } else if (it.value().count() == 1) { + item = it.value().at(0); currentPath = displayName; break; } else { @@ -453,7 +447,7 @@ } QString resourceName; if (!mCacheResourceName.contains(it.key().resource())) { - Q_FOREACH ( const Akonadi::AgentInstance &instance, Akonadi::AgentManager::self()->instances() ) { + Q_FOREACH (const Akonadi::AgentInstance &instance, Akonadi::AgentManager::self()->instances()) { if (instance.identifier() == it.key().resource()) { mCacheResourceName.insert(instance.identifier(), instance.name()); resourceName = instance.name(); @@ -464,50 +458,53 @@ resourceName = mCacheResourceName.value(it.key().resource()); } const int numberOfEmails(it.value().count()); - if (numberOfEmails>0) { - texts.append( i18np( "One new email in %2 from \"%3\"", "%1 new emails in %2 from \"%3\"", numberOfEmails, displayName, - resourceName ) ); + if (numberOfEmails > 0) { + texts.append(i18ncp("%2 = name of mail folder; %3 = name of Akonadi POP3/IMAP/etc resource (as user named it)", + "One new email in %2 from \"%3\"", + "%1 new emails in %2 from \"%3\"", numberOfEmails, displayName, + resourceName)); } } if (hasUniqMessage) { SpecialNotifierJob *job = new SpecialNotifierJob(mListEmails, currentPath, item, this); job->setDefaultPixmap(mDefaultPixmap); - connect(job, SIGNAL(displayNotification(QPixmap,QString)), SLOT(slotDisplayNotification(QPixmap,QString))); + connect(job, &SpecialNotifierJob::displayNotification, this, &NewMailNotifierAgent::slotDisplayNotification); + mNewMails.clear(); return; } else { - message = texts.join( QLatin1String("
") ); + message = texts.join(QStringLiteral("
")); } } else { - message = i18n( "New mail arrived" ); + message = i18n("New mail arrived"); } - kDebug() << message; + qCDebug(NEWMAILNOTIFIER_LOG) << message; slotDisplayNotification(mDefaultPixmap, message); mNewMails.clear(); } - void NewMailNotifierAgent::slotDisplayNotification(const QPixmap &pixmap, const QString &message) { - KNotification::event( QLatin1String("new-email"), - message, - pixmap, - 0, - KNotification::CloseOnTimeout, - KGlobal::mainComponent()); + KNotification::event(QStringLiteral("new-email"), + message, + pixmap, + Q_NULLPTR, + KNotification::CloseOnTimeout, + QStringLiteral("akonadi_newmailnotifier_agent")); - if ( NewMailNotifierAgentSettings::beepOnNewMails() ) { + if (NewMailNotifierAgentSettings::beepOnNewMails()) { KNotification::beep(); } } void NewMailNotifierAgent::slotInstanceNameChanged(const Akonadi::AgentInstance &instance) { - if (!isActive()) + if (!isActive()) { return; + } const QString identifier(instance.identifier()); if (mCacheResourceName.contains(identifier)) { @@ -518,21 +515,20 @@ void NewMailNotifierAgent::slotInstanceStatusChanged(const Akonadi::AgentInstance &instance) { - if (!isActive()) + if (!isActive()) { return; + } const QString identifier(instance.identifier()); - switch(instance.status()) { + switch (instance.status()) { case Akonadi::AgentInstance::Broken: - case Akonadi::AgentInstance::Idle: - { + case Akonadi::AgentInstance::Idle: { if (mInstanceNameInProgress.contains(identifier)) { mInstanceNameInProgress.removeAll(identifier); } break; } - case Akonadi::AgentInstance::Running: - { + case Akonadi::AgentInstance::Running: { if (!excludeAgentType(instance)) { if (!mInstanceNameInProgress.contains(identifier)) { mInstanceNameInProgress.append(identifier); @@ -548,11 +544,11 @@ bool NewMailNotifierAgent::excludeAgentType(const Akonadi::AgentInstance &instance) { - if ( instance.type().mimeTypes().contains( KMime::Message::mimeType() ) ) { - const QStringList capabilities( instance.type().capabilities() ); - if ( capabilities.contains( QLatin1String("Resource") ) && - !capabilities.contains( QLatin1String("Virtual") ) && - !capabilities.contains( QLatin1String("MailTransport") ) ) { + if (instance.type().mimeTypes().contains(KMime::Message::mimeType())) { + const QStringList capabilities(instance.type().capabilities()); + if (capabilities.contains(QStringLiteral("Resource")) && + !capabilities.contains(QStringLiteral("Virtual")) && + !capabilities.contains(QStringLiteral("MailTransport"))) { return false; } else { return true; @@ -563,8 +559,9 @@ void NewMailNotifierAgent::slotInstanceRemoved(const Akonadi::AgentInstance &instance) { - if (!isActive()) + if (!isActive()) { return; + } const QString identifier(instance.identifier()); if (mInstanceNameInProgress.contains(identifier)) { @@ -579,10 +576,10 @@ void NewMailNotifierAgent::printDebug() { - kDebug()<<"instance in progress: "< // make sure this is included before QHash, otherwise it wont find the correct qHash implementation for some reason -#include +#include // make sure this is included before QHash, otherwise it wont find the correct qHash implementation for some reason +#include #include #include #include -namespace Akonadi { +namespace Akonadi +{ class AgentInstance; } -namespace KPIMIdentities { +namespace KIdentityManagement +{ class IdentityManager; } @@ -41,7 +43,7 @@ Q_OBJECT public: - explicit NewMailNotifierAgent( const QString &id ); + explicit NewMailNotifierAgent(const QString &id); void showConfigureDialog(qlonglong windowId = 0); @@ -81,15 +83,15 @@ void setShowButtonToDisplayMail(bool b); protected: - void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - void itemsMoved( const Akonadi::Item::List &items, const Akonadi::Collection &sourceCollection, const Akonadi::Collection &destinationCollection ); - void itemsRemoved( const Akonadi::Item::List &items ); - void itemsFlagsChanged( const Akonadi::Item::List &items, const QSet &addedFlags, const QSet &removedFlags ); - void doSetOnline(bool online); + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void itemsMoved(const Akonadi::Item::List &items, const Akonadi::Collection &sourceCollection, const Akonadi::Collection &destinationCollection) Q_DECL_OVERRIDE; + void itemsRemoved(const Akonadi::Item::List &items) Q_DECL_OVERRIDE; + void itemsFlagsChanged(const Akonadi::Item::List &items, const QSet &addedFlags, const QSet &removedFlags) Q_DECL_OVERRIDE; + void doSetOnline(bool online) Q_DECL_OVERRIDE; -private slots: +private Q_SLOTS: void slotShowNotifications(); - void configure(WId windowId); + void configure(WId windowId) Q_DECL_OVERRIDE; void slotInstanceStatusChanged(const Akonadi::AgentInstance &instance); void slotInstanceRemoved(const Akonadi::AgentInstance &instance); void slotInstanceAdded(const Akonadi::AgentInstance &instance); @@ -109,7 +111,7 @@ QHash mCacheResourceName; QTimer mTimer; QStringList mInstanceNameInProgress; - KPIMIdentities::IdentityManager *mIdentityManager; + KIdentityManagement::IdentityManager *mIdentityManager; }; #endif diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifieragentsettings.kcfg kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifieragentsettings.kcfg --- kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifieragentsettings.kcfg 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifieragentsettings.kcfg 2015-08-10 21:01:02.000000000 +0000 @@ -3,6 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" > + KLocalizedString true diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifierattribute.cpp kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifierattribute.cpp --- kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifierattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifierattribute.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -/* - Copyright (c) 2013-2015 Montel Laurent - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#include "newmailnotifierattribute.h" - -#include -#include -#include - -class NewMailNotifierAttributePrivate -{ -public: - NewMailNotifierAttributePrivate() - : ignoreNewMail(false) - { - } - bool ignoreNewMail; -}; - -NewMailNotifierAttribute::NewMailNotifierAttribute() - : d(new NewMailNotifierAttributePrivate) -{ -} - -NewMailNotifierAttribute::~NewMailNotifierAttribute() -{ - delete d; -} - -NewMailNotifierAttribute *NewMailNotifierAttribute::clone() const -{ - NewMailNotifierAttribute *attr = new NewMailNotifierAttribute(); - attr->setIgnoreNewMail(ignoreNewMail()); - return attr; -} - -QByteArray NewMailNotifierAttribute::type() const -{ - static const QByteArray sType( "newmailnotifierattribute" ); - return sType; -} - -QByteArray NewMailNotifierAttribute::serialized() const -{ - QByteArray result; - QDataStream s( &result, QIODevice::WriteOnly ); - s << ignoreNewMail(); - return result; -} - -void NewMailNotifierAttribute::deserialize( const QByteArray &data ) -{ - QDataStream s( data ); - s >> d->ignoreNewMail; -} - -bool NewMailNotifierAttribute::ignoreNewMail() const -{ - return d->ignoreNewMail; -} - -void NewMailNotifierAttribute::setIgnoreNewMail(bool b) -{ - d->ignoreNewMail = b; -} - -bool NewMailNotifierAttribute::operator==(const NewMailNotifierAttribute &other) const -{ - return d->ignoreNewMail == other.ignoreNewMail(); -} diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifierattribute.h kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifierattribute.h --- kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifierattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifierattribute.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -/* - Copyright (c) 2013-2015 Montel Laurent - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef NEWMAILNOTIFIERATTRIBUTE_H -#define NEWMAILNOTIFIERATTRIBUTE_H - -#include - - -class NewMailNotifierAttributePrivate; -class NewMailNotifierAttribute : public Akonadi::Attribute -{ -public: - NewMailNotifierAttribute(); - ~NewMailNotifierAttribute(); - - /* reimpl */ - NewMailNotifierAttribute *clone() const; - QByteArray type() const; - QByteArray serialized() const; - void deserialize( const QByteArray &data ); - - bool ignoreNewMail() const; - void setIgnoreNewMail(bool b); - bool operator==(const NewMailNotifierAttribute &other) const; - -private: - friend class NewMailNotifierAttributePrivate; - NewMailNotifierAttributePrivate * const d; -}; - -#endif // NEWMAILNOTIFIERATTRIBUTE_H diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifier_debug.cpp kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifier_debug.cpp --- kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifier_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifier_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 "newmailnotifier_debug.h" +Q_LOGGING_CATEGORY(NEWMAILNOTIFIER_LOG, "log_newmailnotifier") + diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifier_debug.h kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifier_debug.h --- kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifier_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifier_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 NEWMAILNOTIFIER_DEBUG_H +#define NEWMAILNOTIFIER_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(NEWMAILNOTIFIER_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifierselectcollectionwidget.cpp kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifierselectcollectionwidget.cpp --- kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifierselectcollectionwidget.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifierselectcollectionwidget.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,24 +18,23 @@ */ #include "newmailnotifierselectcollectionwidget.h" -#include "newmailnotifierattribute.h" +#include - -#include -#include +#include +#include #include -#include -#include -#include +#include +#include +#include #include #include #include -#include +#include #include -#include +#include "newmailnotifier_debug.h" #include #include @@ -53,39 +52,37 @@ vbox->addWidget(label); // Create a new change recorder. - mChangeRecorder = new Akonadi::ChangeRecorder( this ); - mChangeRecorder->setMimeTypeMonitored( KMime::Message::mimeType() ); - mChangeRecorder->fetchCollection( true ); - mChangeRecorder->setAllMonitored( true ); + mChangeRecorder = new Akonadi::ChangeRecorder(this); + mChangeRecorder->setMimeTypeMonitored(KMime::Message::mimeType()); + mChangeRecorder->fetchCollection(true); + mChangeRecorder->setAllMonitored(true); - mModel = new Akonadi::EntityTreeModel( mChangeRecorder, this ); + mModel = new Akonadi::EntityTreeModel(mChangeRecorder, this); // Set the model to show only collections, not items. - mModel->setItemPopulationStrategy( Akonadi::EntityTreeModel::NoItemPopulation ); - connect(mModel, SIGNAL(collectionTreeFetched(Akonadi::Collection::List)), SLOT(slotCollectionTreeFetched())); + mModel->setItemPopulationStrategy(Akonadi::EntityTreeModel::NoItemPopulation); + connect(mModel, &Akonadi::EntityTreeModel::collectionTreeFetched, this, &NewMailNotifierSelectCollectionWidget::slotCollectionTreeFetched); - Akonadi::CollectionFilterProxyModel *mimeTypeProxy = new Akonadi::CollectionFilterProxyModel( this ); - mimeTypeProxy->setExcludeVirtualCollections( true ); - mimeTypeProxy->addMimeTypeFilters( QStringList() << KMime::Message::mimeType() ); - mimeTypeProxy->setSourceModel( mModel ); + Akonadi::CollectionFilterProxyModel *mimeTypeProxy = new Akonadi::CollectionFilterProxyModel(this); + mimeTypeProxy->setExcludeVirtualCollections(true); + mimeTypeProxy->addMimeTypeFilters(QStringList() << KMime::Message::mimeType()); + mimeTypeProxy->setSourceModel(mModel); // Create the Check proxy model. - mSelectionModel = new QItemSelectionModel( mimeTypeProxy ); - mCheckProxy = new KCheckableProxyModel( this ); - mCheckProxy->setSelectionModel( mSelectionModel ); - mCheckProxy->setSourceModel( mimeTypeProxy ); - + mSelectionModel = new QItemSelectionModel(mimeTypeProxy); + mCheckProxy = new KCheckableProxyModel(this); + mCheckProxy->setSelectionModel(mSelectionModel); + mCheckProxy->setSourceModel(mimeTypeProxy); mCollectionFilter = new KRecursiveFilterProxyModel(this); mCollectionFilter->setSourceModel(mCheckProxy); mCollectionFilter->setDynamicSortFilter(true); mCollectionFilter->setFilterCaseSensitivity(Qt::CaseInsensitive); - KLineEdit *searchLine = new KLineEdit(this); searchLine->setPlaceholderText(i18n("Search...")); searchLine->setClearButtonShown(true); - connect(searchLine, SIGNAL(textChanged(QString)), - this, SLOT(slotSetCollectionFilter(QString))); + connect(searchLine, &QLineEdit::textChanged, + this, &NewMailNotifierSelectCollectionWidget::slotSetCollectionFilter); vbox->addWidget(searchLine); @@ -94,17 +91,17 @@ mFolderView->setAlternatingRowColors(true); vbox->addWidget(mFolderView); - mFolderView->setModel( mCollectionFilter ); + mFolderView->setModel(mCollectionFilter); QHBoxLayout *hbox = new QHBoxLayout; vbox->addLayout(hbox); - KPushButton *button = new KPushButton(i18n("&Select All"), this); - connect(button, SIGNAL(clicked(bool)), this, SLOT(slotSelectAllCollections())); + QPushButton *button = new QPushButton(i18n("&Select All"), this); + connect(button, &QPushButton::clicked, this, &NewMailNotifierSelectCollectionWidget::slotSelectAllCollections); hbox->addWidget(button); - button = new KPushButton(i18n("&Unselect All"), this); - connect(button, SIGNAL(clicked(bool)), this, SLOT(slotUnselectAllCollections())); + button = new QPushButton(i18n("&Unselect All"), this); + connect(button, &QPushButton::clicked, this, &NewMailNotifierSelectCollectionWidget::slotUnselectAllCollections); hbox->addWidget(button); hbox->addStretch(1); setLayout(vbox); @@ -147,76 +144,75 @@ void NewMailNotifierSelectCollectionWidget::updateStatus(const QModelIndex &parent) { - const int nbCol = mCheckProxy->rowCount( parent ); - for ( int i = 0; i < nbCol; ++i ) { - const QModelIndex child = mCheckProxy->index( i, 0, parent ); + const int nbCol = mCheckProxy->rowCount(parent); + for (int i = 0; i < nbCol; ++i) { + const QModelIndex child = mCheckProxy->index(i, 0, parent); const Akonadi::Collection collection = - mCheckProxy->data( child, Akonadi::EntityTreeModel::CollectionRole ).value(); + mCheckProxy->data(child, Akonadi::EntityTreeModel::CollectionRole).value(); - NewMailNotifierAttribute *attr = collection.attribute(); + Akonadi::NewMailNotifierAttribute *attr = collection.attribute(); if (!attr || !attr->ignoreNewMail()) { - mCheckProxy->setData( child, Qt::Checked, Qt::CheckStateRole ); + mCheckProxy->setData(child, Qt::Checked, Qt::CheckStateRole); } - updateStatus( child ); + updateStatus(child); } mNeedUpdate = false; } void NewMailNotifierSelectCollectionWidget::forceStatus(const QModelIndex &parent, bool status) { - const int nbCol = mCheckProxy->rowCount( parent ); - for ( int i = 0; i < nbCol; ++i ) { - const QModelIndex child = mCheckProxy->index( i, 0, parent ); - mCheckProxy->setData( child, status ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole ); - forceStatus( child, status ); + const int nbCol = mCheckProxy->rowCount(parent); + for (int i = 0; i < nbCol; ++i) { + const QModelIndex child = mCheckProxy->index(i, 0, parent); + mCheckProxy->setData(child, status ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole); + forceStatus(child, status); } } void NewMailNotifierSelectCollectionWidget::updateCollectionsRecursive(const QModelIndex &parent) { - const int nbCol = mCheckProxy->rowCount( parent ); - for ( int i = 0; i < nbCol; ++i ) { - const QModelIndex child = mCheckProxy->index( i, 0, parent ); + const int nbCol = mCheckProxy->rowCount(parent); + for (int i = 0; i < nbCol; ++i) { + const QModelIndex child = mCheckProxy->index(i, 0, parent); Akonadi::Collection collection = - mCheckProxy->data( child, Akonadi::EntityTreeModel::CollectionRole ).value(); + mCheckProxy->data(child, Akonadi::EntityTreeModel::CollectionRole).value(); - NewMailNotifierAttribute *attr = collection.attribute(); - Akonadi::CollectionModifyJob *modifyJob = 0; - const bool selected = (mCheckProxy->data( child, Qt::CheckStateRole ).value() != 0); + Akonadi::NewMailNotifierAttribute *attr = collection.attribute(); + Akonadi::CollectionModifyJob *modifyJob = Q_NULLPTR; + const bool selected = (mCheckProxy->data(child, Qt::CheckStateRole).value() != 0); if (selected && attr && attr->ignoreNewMail()) { - collection.removeAttribute(); + collection.removeAttribute(); modifyJob = new Akonadi::CollectionModifyJob(collection); modifyJob->setProperty("AttributeAdded", true); } else if (!selected && (!attr || !attr->ignoreNewMail())) { - attr = collection.attribute(Akonadi::Entity::AddIfMissing); + attr = collection.attribute(Akonadi::Entity::AddIfMissing); attr->setIgnoreNewMail(true); modifyJob = new Akonadi::CollectionModifyJob(collection); modifyJob->setProperty("AttributeAdded", false); } if (modifyJob) { - connect(modifyJob, SIGNAL(finished(KJob*)), SLOT(slotModifyJobDone(KJob*))); + connect(modifyJob, &Akonadi::CollectionModifyJob::finished, this, &NewMailNotifierSelectCollectionWidget::slotModifyJobDone); } updateCollectionsRecursive(child); } } -void NewMailNotifierSelectCollectionWidget::slotModifyJobDone(KJob* job) +void NewMailNotifierSelectCollectionWidget::slotModifyJobDone(KJob *job) { - Akonadi::CollectionModifyJob *modifyJob = qobject_cast(job); + Akonadi::CollectionModifyJob *modifyJob = qobject_cast(job); if (modifyJob && job->error()) { if (job->property("AttributeAdded").toBool()) { - kWarning() << "Failed to append NewMailNotifierAttribute to collection" - << modifyJob->collection().id() << ":" - << job->errorString(); + qCWarning(NEWMAILNOTIFIER_LOG) << "Failed to append NewMailNotifierAttribute to collection" + << modifyJob->collection().id() << ":" + << job->errorString(); } else { - kWarning() << "Failed to remove NewMailNotifierAttribute from collection" - << modifyJob->collection().id() << ":" - << job->errorString(); + qCWarning(NEWMAILNOTIFIER_LOG) << "Failed to remove NewMailNotifierAttribute from collection" + << modifyJob->collection().id() << ":" + << job->errorString(); } } } - diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifierselectcollectionwidget.h kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifierselectcollectionwidget.h --- kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifierselectcollectionwidget.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifierselectcollectionwidget.h 2015-08-10 21:01:02.000000000 +0000 @@ -21,12 +21,13 @@ #define NEWMAILNOTIFIERSELECTCOLLECTIONWIDGET_H #include -#include +#include #include class QItemSelectionModel; class KRecursiveFilterProxyModel; -namespace Akonadi { +namespace Akonadi +{ class EntityTreeModel; class ChangeRecorder; } @@ -38,7 +39,7 @@ { Q_OBJECT public: - explicit NewMailNotifierSelectCollectionWidget(QWidget *parent=0); + explicit NewMailNotifierSelectCollectionWidget(QWidget *parent = Q_NULLPTR); ~NewMailNotifierSelectCollectionWidget(); void updateCollectionsRecursive(const QModelIndex &parent); @@ -46,9 +47,9 @@ private Q_SLOTS: void slotSelectAllCollections(); void slotUnselectAllCollections(); - void slotModifyJobDone(KJob* job); + void slotModifyJobDone(KJob *job); void slotUpdateCollectionStatus(); - void slotSetCollectionFilter(const QString&); + void slotSetCollectionFilter(const QString &); void slotCollectionTreeFetched(); diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifiersettingsdialog.cpp kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifiersettingsdialog.cpp --- kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifiersettingsdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifiersettingsdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,46 +26,57 @@ #include #include -#include +#include #include -#include -#include +#include #include -#include +#include +#include #include #include #include #include #include -#include #include +#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include -static const char * textToSpeakMessage = - I18N_NOOP( "" +static const char *textToSpeakMessage = + I18N_NOOP("" "

Here you can define message. " "You can use:

" "
    " "
  • %s set subject
  • " "
  • %f set from
  • " "
" - "
" ); + "
"); NewMailNotifierSettingsDialog::NewMailNotifierSettingsDialog(QWidget *parent) - : KDialog(parent) + : QDialog(parent) { - setCaption( i18n("New Mail Notifier settings") ); - setWindowIcon( KIcon( QLatin1String("kmail") ) ); - setButtons( Help | Ok|Cancel ); - connect(this, SIGNAL(okClicked()), this, SLOT(slotOkClicked())); + setWindowTitle(i18n("New Mail Notifier settings")); + setWindowIcon(QIcon::fromTheme(QStringLiteral("kmail"))); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); + okButton->setDefault(true); + okButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &NewMailNotifierSettingsDialog::slotOkClicked); + connect(buttonBox, &QDialogButtonBox::rejected, this, &NewMailNotifierSettingsDialog::reject); QWidget *w = new QWidget; + mainLayout->addWidget(w); + mainLayout->addWidget(buttonBox); QVBoxLayout *lay = new QVBoxLayout; w->setLayout(lay); QTabWidget *tab = new QTabWidget; @@ -107,7 +118,7 @@ vbox->addStretch(); tab->addTab(settings, i18n("Display")); - +#ifdef HAVE_SPEECH QWidget *textSpeakWidget = new QWidget; vbox = new QVBoxLayout; textSpeakWidget->setLayout(vbox); @@ -115,18 +126,18 @@ mTextToSpeak->setChecked(NewMailNotifierAgentSettings::textToSpeakEnabled()); vbox->addWidget(mTextToSpeak); - QLabel *howIsItWork = new QLabel(i18n( "How does this work?" )); + QLabel *howIsItWork = new QLabel(i18n("How does this work?")); howIsItWork->setTextInteractionFlags(Qt::LinksAccessibleByMouse); howIsItWork->setContextMenuPolicy(Qt::NoContextMenu); vbox->addWidget(howIsItWork); - connect(howIsItWork, SIGNAL(linkActivated(QString)),SLOT(slotHelpLinkClicked(QString)) ); + connect(howIsItWork, &QLabel::linkActivated, this, &NewMailNotifierSettingsDialog::slotHelpLinkClicked); QHBoxLayout *textToSpeakLayout = new QHBoxLayout; textToSpeakLayout->setMargin(0); QLabel *lab = new QLabel(i18n("Message:")); textToSpeakLayout->addWidget(lab); - mTextToSpeakSetting = new KLineEdit; - mTextToSpeakSetting->setClearButtonShown(true); + mTextToSpeakSetting = new QLineEdit; + mTextToSpeakSetting->setClearButtonEnabled(true); mTextToSpeakSetting->setText(NewMailNotifierAgentSettings::textToSpeak()); mTextToSpeakSetting->setEnabled(mTextToSpeak->isChecked()); mTextToSpeakSetting->setWhatsThis(i18n(textToSpeakMessage)); @@ -134,74 +145,70 @@ vbox->addLayout(textToSpeakLayout); vbox->addStretch(); tab->addTab(textSpeakWidget, i18n("Text to Speak")); - connect(mTextToSpeak, SIGNAL(toggled(bool)), mTextToSpeakSetting, SLOT(setEnabled(bool))); + connect(mTextToSpeak, &QCheckBox::toggled, mTextToSpeakSetting, &QLineEdit::setEnabled); +#else + mTextToSpeak = Q_NULLPTR; + mTextToSpeakSetting = Q_NULLPTR; +#endif mNotify = new KNotifyConfigWidget(this); - mNotify->setApplication(QLatin1String("akonadi_newmailnotifier_agent")); + mNotify->setApplication(QStringLiteral("akonadi_newmailnotifier_agent")); tab->addTab(mNotify, i18n("Notify")); mSelectCollection = new NewMailNotifierSelectCollectionWidget; tab->addTab(mSelectCollection, i18n("Folders")); - setMainWidget(w); - - mAboutData = new KAboutData( - QByteArray( "newmailnotifieragent" ), - QByteArray(), - ki18n( "New Mail Notifier Agent" ), - QByteArray( KDEPIM_RUNTIME_VERSION ), - ki18n( "Notifies about new mail." ), - KAboutData::License_GPL_V2, - ki18n( "Copyright (C) 2013 Laurent Montel" ) ); - - mAboutData->addAuthor( ki18n( "Laurent Montel" ), - ki18n( "Maintainer" ), "montel@kde.org" ); - - mAboutData->setProgramIconName( QLatin1String("kmail") ); - mAboutData->setTranslator( ki18nc( "NAME OF TRANSLATORS", "Your names" ), - ki18nc( "EMAIL OF TRANSLATORS", "Your emails" ) ); - + KAboutData aboutData = KAboutData( + QStringLiteral("newmailnotifieragent"), + i18n("New Mail Notifier Agent"), + QLatin1String(KDEPIM_RUNTIME_VERSION), + i18n("Notifies about new mail."), + KAboutLicense::GPL_V2, + i18n("Copyright (C) 2013-2015 Laurent Montel")); + + aboutData.addAuthor(i18n("Laurent Montel"), + i18n("Maintainer"), QStringLiteral("montel@kde.org")); + aboutData.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"), + i18nc("EMAIL OF TRANSLATORS", "Your emails")); - KHelpMenu *helpMenu = new KHelpMenu(this, mAboutData, true); + KHelpMenu *helpMenu = new KHelpMenu(this, aboutData, true); //Initialize menu - KMenu *menu = helpMenu->menu(); - helpMenu->action(KHelpMenu::menuAboutApp)->setIcon(KIcon(QLatin1String("kmail"))); - setButtonMenu( Help, menu ); + QMenu *menu = helpMenu->menu(); + helpMenu->action(KHelpMenu::menuAboutApp)->setIcon(QIcon::fromTheme(QStringLiteral("kmail"))); + buttonBox->button(QDialogButtonBox::Help)->setMenu(menu); readConfig(); } NewMailNotifierSettingsDialog::~NewMailNotifierSettingsDialog() { writeConfig(); - delete mAboutData; } static const char *myConfigGroupName = "NewMailNotifierDialog"; void NewMailNotifierSettingsDialog::readConfig() { - KConfigGroup group( KGlobal::config(), myConfigGroupName ); + KConfigGroup group(KSharedConfig::openConfig(), myConfigGroupName); - const QSize size = group.readEntry( "Size", QSize(500, 300) ); - if ( size.isValid() ) { - resize( size ); + const QSize size = group.readEntry("Size", QSize(500, 300)); + if (size.isValid()) { + resize(size); } } void NewMailNotifierSettingsDialog::writeConfig() { - KConfigGroup group( KGlobal::config(), myConfigGroupName ); - group.writeEntry( "Size", size() ); + KConfigGroup group(KSharedConfig::openConfig(), myConfigGroupName); + group.writeEntry("Size", size()); group.sync(); } - void NewMailNotifierSettingsDialog::slotHelpLinkClicked(const QString &) { const QString help = - i18n( textToSpeakMessage); + i18n(textToSpeakMessage); - QWhatsThis::showText( QCursor::pos(), help ); + QWhatsThis::showText(QCursor::pos(), help); } void NewMailNotifierSettingsDialog::slotOkClicked() @@ -213,13 +220,13 @@ NewMailNotifierAgentSettings::setShowSubject(mShowSubject->isChecked()); NewMailNotifierAgentSettings::setShowFolder(mShowFolders->isChecked()); NewMailNotifierAgentSettings::setExcludeEmailsFromMe(mExcludeMySelf->isChecked()); +#ifdef HAVE_SPEECH NewMailNotifierAgentSettings::setTextToSpeakEnabled(mTextToSpeak->isChecked()); NewMailNotifierAgentSettings::setTextToSpeak(mTextToSpeakSetting->text()); +#endif NewMailNotifierAgentSettings::setShowButtonToDisplayMail(mAllowToShowMail->isChecked()); - NewMailNotifierAgentSettings::self()->writeConfig(); + NewMailNotifierAgentSettings::self()->save(); mNotify->save(); accept(); } - - diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifiersettingsdialog.h kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifiersettingsdialog.h --- kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifiersettingsdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifiersettingsdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,19 +20,18 @@ #ifndef NEWMAILNOTIFIERSETTINGSDIALOG_H #define NEWMAILNOTIFIERSETTINGSDIALOG_H -#include -#include +#include +#include class KNotifyConfigWidget; class QCheckBox; -class KLineEdit; -class KAboutData; +class QLineEdit; class NewMailNotifierSelectCollectionWidget; -class NewMailNotifierSettingsDialog : public KDialog +class NewMailNotifierSettingsDialog : public QDialog { Q_OBJECT public: - explicit NewMailNotifierSettingsDialog(QWidget *parent=0); + explicit NewMailNotifierSettingsDialog(QWidget *parent = Q_NULLPTR); ~NewMailNotifierSettingsDialog(); private Q_SLOTS: @@ -50,9 +49,8 @@ QCheckBox *mAllowToShowMail; KNotifyConfigWidget *mNotify; QCheckBox *mTextToSpeak; - KLineEdit *mTextToSpeakSetting; + QLineEdit *mTextToSpeakSetting; NewMailNotifierSelectCollectionWidget *mSelectCollection; - KAboutData *mAboutData; }; #endif // NEWMAILNOTIFIERSETTINGSDIALOG_H diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifiershowmessagejob.cpp kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifiershowmessagejob.cpp --- kdepim-runtime-4.14.6/agents/newmailnotifier/newmailnotifiershowmessagejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/newmailnotifiershowmessagejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -16,7 +16,7 @@ */ #include "newmailnotifiershowmessagejob.h" - +#include "newmailnotifier_debug.h" #include #include #include @@ -39,21 +39,21 @@ Q_EMIT emitResult(); return; } - const QString kmailInterface = QLatin1String("org.kde.kmail"); + const QString kmailInterface = QStringLiteral("org.kde.kmail"); QDBusReply reply = QDBusConnection::sessionBus().interface()->isServiceRegistered(kmailInterface); if (!reply.isValid() || !reply.value()) { // Program is not already running, so start it QString errmsg; - if (KToolInvocation::startServiceByDesktopName(QLatin1String("kmail2"), QString(), &errmsg)) { - qDebug()<<" Can not start kmail"< -#include +#include class NewMailNotifierShowMessageJob : public KJob { Q_OBJECT public: - explicit NewMailNotifierShowMessageJob(Akonadi::Item::Id id, QObject *parent=0); + explicit NewMailNotifierShowMessageJob(Akonadi::Item::Id id, QObject *parent = Q_NULLPTR); ~NewMailNotifierShowMessageJob(); - void start(); + void start() Q_DECL_OVERRIDE; private: Akonadi::Item::Id mId; }; - #endif // NEWMAILNOTIFIERSHOWMESSAGEJOB_H diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/NEWS kdepim-runtime-15.08.0/agents/newmailnotifier/NEWS --- kdepim-runtime-4.14.6/agents/newmailnotifier/NEWS 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/NEWS 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -4.14: ------ -Add button to show email diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/specialnotifierjob.cpp kdepim-runtime-15.08.0/agents/newmailnotifier/specialnotifierjob.cpp --- kdepim-runtime-4.14.6/agents/newmailnotifier/specialnotifierjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/specialnotifierjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,21 +20,22 @@ #include "newmailnotifieragentsettings.h" #include -#include -#include -#include +#include +#include +#include #include -#include +#include #include #include +#include "newmailnotifier_debug.h" #include -#include -#include -#include +#ifdef HAVE_SPEECH +#include +#endif SpecialNotifierJob::SpecialNotifierJob(const QStringList &listEmails, const QString &path, Akonadi::Item::Id id, QObject *parent) : QObject(parent), @@ -43,10 +44,10 @@ mItemId(id) { Akonadi::Item item(mItemId); - Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( item, this ); - job->fetchScope().fetchPayloadPart( Akonadi::MessagePart::Envelope, true ); + Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob(item, this); + job->fetchScope().fetchPayloadPart(Akonadi::MessagePart::Envelope, true); - connect( job, SIGNAL(result(KJob*)), SLOT(slotItemFetchJobDone(KJob*)) ); + connect(job, &Akonadi::ItemFetchJob::result, this, &SpecialNotifierJob::slotItemFetchJobDone); } SpecialNotifierJob::~SpecialNotifierJob() @@ -61,17 +62,17 @@ void SpecialNotifierJob::slotItemFetchJobDone(KJob *job) { - if ( job->error() ) { - kWarning() << job->errorString(); + if (job->error()) { + qCWarning(NEWMAILNOTIFIER_LOG) << job->errorString(); deleteLater(); return; } - const Akonadi::Item::List lst = qobject_cast( job )->items(); + const Akonadi::Item::List lst = qobject_cast(job)->items(); if (lst.count() == 1) { const Akonadi::Item item = lst.first(); - if ( !item.hasPayload() ) { - kDebug()<<" message has not payload."; + if (!item.hasPayload()) { + qCDebug(NEWMAILNOTIFIER_LOG) << " message has not payload."; deleteLater(); return; } @@ -80,32 +81,32 @@ mFrom = mb->from()->asUnicodeString(); mSubject = mb->subject()->asUnicodeString(); if (NewMailNotifierAgentSettings::showPhoto()) { - Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob( this ); - job->setLimit( 1 ); - job->setQuery( Akonadi::ContactSearchJob::Email, KPIMUtils::firstEmailAddress(mFrom).toLower(), Akonadi::ContactSearchJob::ExactMatch ); - connect( job, SIGNAL(result(KJob*)), SLOT(slotSearchJobFinished(KJob*)) ); + Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob(this); + job->setLimit(1); + job->setQuery(Akonadi::ContactSearchJob::Email, KEmailAddress::firstEmailAddress(mFrom).toLower(), Akonadi::ContactSearchJob::ExactMatch); + connect(job, &Akonadi::ItemFetchJob::result, this, &SpecialNotifierJob::slotSearchJobFinished); } else { emitNotification(mDefaultPixmap); deleteLater(); } } else { - kWarning()<<" Found item different from 1: "<( job ); - if ( searchJob->error() ) { - kWarning() << "Unable to fetch contact:" << searchJob->errorText(); + const Akonadi::ContactSearchJob *searchJob = qobject_cast(job); + if (searchJob->error()) { + qCWarning(NEWMAILNOTIFIER_LOG) << "Unable to fetch contact:" << searchJob->errorText(); emitNotification(mDefaultPixmap); return; } if (!searchJob->contacts().isEmpty()) { - const KABC::Addressee addressee = searchJob->contacts().first(); - const KABC::Picture photo = addressee.photo(); + const KContacts::Addressee addressee = searchJob->contacts().at(0); + const KContacts::Picture photo = addressee.photo(); const QImage image = photo.data(); if (image.isNull()) { emitNotification(mDefaultPixmap); @@ -120,7 +121,7 @@ void SpecialNotifierJob::emitNotification(const QPixmap &pixmap) { if (NewMailNotifierAgentSettings::excludeEmailsFromMe()) { - Q_FOREACH( const QString &email, mListEmails) { + Q_FOREACH (const QString &email, mListEmails) { if (mFrom.contains(email)) { //Exclude this notification deleteLater(); @@ -131,15 +132,15 @@ QStringList result; if (NewMailNotifierAgentSettings::showFrom()) { - result << i18n("From: %1", Qt::escape(mFrom)); + result << i18n("From: %1", mFrom.toHtmlEscaped()); } if (NewMailNotifierAgentSettings::showSubject()) { QString subject = mSubject.simplified(); - if (subject.length()> 80) { + if (subject.length() > 80) { subject.truncate(80); - subject += QLatin1String("..."); + subject += QStringLiteral("..."); } - result << i18n("Subject: %1", Qt::escape(subject)); + result << i18n("Subject: %1", subject.toHtmlEscaped()); } if (NewMailNotifierAgentSettings::showFolder()) { result << i18n("In: %1", mPath); @@ -147,31 +148,31 @@ if (NewMailNotifierAgentSettings::textToSpeakEnabled()) { if (!NewMailNotifierAgentSettings::textToSpeak().isEmpty()) { - if (QDBusConnection::sessionBus().interface()->isServiceRegistered(QLatin1String("org.kde.kttsd"))) { - QDBusInterface ktts(QLatin1String("org.kde.kttsd"), QLatin1String("/KSpeech"), QLatin1String("org.kde.KSpeech")); - QString message = NewMailNotifierAgentSettings::textToSpeak(); - message.replace(QLatin1String("%s"), Qt::escape(mSubject)); - message.replace(QLatin1String("%f"), Qt::escape(mFrom)); - ktts.asyncCall(QLatin1String("say"), message, 0); - } +#ifdef HAVE_SPEECH + QTextToSpeech *speech = new QTextToSpeech(this); + QString message = NewMailNotifierAgentSettings::textToSpeak(); + message.replace(QStringLiteral("%s"), mSubject.toHtmlEscaped()); + message.replace(QStringLiteral("%f"), mFrom.toHtmlEscaped()); + speech->say(message); +#endif } } if (NewMailNotifierAgentSettings::showButtonToDisplayMail()) { - KNotification *notification= new KNotification ( QLatin1String("new-email"), 0, KNotification::CloseOnTimeout); - notification->setText( result.join(QLatin1String("\n")) ); - notification->setPixmap( pixmap ); - notification->setActions( QStringList() << i18n( "Show mail..." ) ); + KNotification *notification = new KNotification(QStringLiteral("new-email"), Q_NULLPTR, KNotification::CloseOnTimeout); + notification->setText(result.join(QStringLiteral("\n"))); + notification->setPixmap(pixmap); + notification->setActions(QStringList() << i18n("Show mail...")); - connect(notification, SIGNAL(activated(uint)), this, SLOT(slotOpenMail()) ); - connect(notification, SIGNAL(closed()), this, SLOT(deleteLater())); + connect(notification, static_cast(&KNotification::activated), this, &SpecialNotifierJob::slotOpenMail); + connect(notification, &KNotification::closed, this, &SpecialNotifierJob::deleteLater); notification->sendEvent(); - if ( NewMailNotifierAgentSettings::beepOnNewMails() ) { + if (NewMailNotifierAgentSettings::beepOnNewMails()) { KNotification::beep(); } } else { - emit displayNotification(pixmap, result.join(QLatin1String("\n"))); + Q_EMIT displayNotification(pixmap, result.join(QStringLiteral("\n"))); deleteLater(); } } diff -Nru kdepim-runtime-4.14.6/agents/newmailnotifier/specialnotifierjob.h kdepim-runtime-15.08.0/agents/newmailnotifier/specialnotifierjob.h --- kdepim-runtime-4.14.6/agents/newmailnotifier/specialnotifierjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/agents/newmailnotifier/specialnotifierjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -18,9 +18,8 @@ #ifndef SPECIALNOTIFIERJOB_H #define SPECIALNOTIFIERJOB_H - #include -#include +#include #include #include class KJob; @@ -29,7 +28,7 @@ { Q_OBJECT public: - explicit SpecialNotifierJob(const QStringList &listEmails, const QString &path, Akonadi::Item::Id id, QObject *parent = 0); + explicit SpecialNotifierJob(const QStringList &listEmails, const QString &path, Akonadi::Item::Id id, QObject *parent = Q_NULLPTR); ~SpecialNotifierJob(); void setDefaultPixmap(const QPixmap &pixmap); @@ -38,8 +37,8 @@ void displayNotification(const QPixmap &pixmap, const QString &message); private Q_SLOTS: - void slotSearchJobFinished( KJob *job ); - void slotItemFetchJobDone(KJob*); + void slotSearchJobFinished(KJob *job); + void slotItemFetchJobDone(KJob *); void slotOpenMail(); private: void emitNotification(const QPixmap &pixmap); diff -Nru kdepim-runtime-4.14.6/cmake/modules/FindXsltproc.cmake kdepim-runtime-15.08.0/cmake/modules/FindXsltproc.cmake --- kdepim-runtime-4.14.6/cmake/modules/FindXsltproc.cmake 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/cmake/modules/FindXsltproc.cmake 2015-08-10 21:01:02.000000000 +0000 @@ -11,19 +11,20 @@ set(Xsltproc_FOUND TRUE) # We depend on kdepimlibs, make sure it's found - if(NOT DEFINED KDEPIMLIBS_DATA_DIR) - find_package(KdepimLibs REQUIRED) + if(NOT DEFINED KF5Akonadi_DATA_DIR) + find_package(KF5Akonadi REQUIRED) endif() + # Macro to generate a D-Bus interface description from a KConfigXT file macro(kcfg_generate_dbus_interface _kcfg _name) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml COMMAND ${XSLTPROC_EXECUTABLE} --stringparam interfaceName ${_name} - ${KDEPIMLIBS_DATA_DIR}/akonadi-kde/kcfg2dbus.xsl + ${KF5Akonadi_DATA_DIR}/kcfg2dbus.xsl ${_kcfg} > ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml - DEPENDS ${KDEPIMLIBS_DATA_DIR}/akonadi-kde/kcfg2dbus.xsl + DEPENDS ${KF5Akonadi_DATA_DIR}/kcfg2dbus.xsl ${_kcfg} ) endmacro() diff -Nru kdepim-runtime-4.14.6/CMakeLists.txt kdepim-runtime-15.08.0/CMakeLists.txt --- kdepim-runtime-4.14.6/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,7 +1,6 @@ -project(kdepim-runtime) +cmake_minimum_required(VERSION 2.8.12) -# where to look first for cmake modules. This line must be the first one or cmake will use the system's FindFoo.cmake -set(CMAKE_MODULE_PATH ${kdepim-runtime_SOURCE_DIR}/cmake/modules) +project(kdepim-runtime) ############### KDEPIM-Runtime version ################ # KDEPIM_RUNTIME_VERSION @@ -33,180 +32,132 @@ # 3.2 alpha1 if(NOT DEFINED KDEPIM_RUNTIME_DEV_VERSION) - set(KDEPIM_RUNTIME_DEV_VERSION "") + set(KDEPIM_RUNTIME_DEV_VERSION "beta1") endif() -set(KDEPIM_RUNTIME_VERSION "4.14.6${KDEPIM_RUNTIME_DEV_VERSION}") +set(KDEPIM_RUNTIME_VERSION_NUMBER "4.80") +set(KDEPIM_RUNTIME_VERSION "${KDEPIM_RUNTIME_VERSION_NUMBER}${KDEPIM_RUNTIME_DEV_VERSION}") configure_file(kdepim-runtime-version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/kdepim-runtime-version.h @ONLY) -############### search-related options ################ - -add_definitions(-DQT_USE_QSTRINGBUILDER) - -############### search packages used by KDE ############### +find_package(ECM 5.12.0 REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${kdepim-runtime_SOURCE_DIR}/cmake/modules ${ECM_MODULE_PATH}) -set(CMAKE_AUTOMOC ON) - -# Kdelibs -find_package(KDE4 4.13.0 REQUIRED) -include(KDE4Defaults) +include(ECMPackageConfigHelpers) +include(ECMSetupVersion) +include(FeatureSummary) +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDEFrameworkCompilerSettings) +include(ECMInstallIcons) + +set(KF5_VERSION "5.12.0") +set(QT_REQUIRED_VERSION "5.4.0") + +set(KDEPIMLIBS_LIB_VERSION "4.88.0") + +set(KDEPIMRUNTIME_LIB_VERSION "${KDEPIM_RUNTIME_VERSION_NUMBER}.0") +set(KDEPIMRUNTIME_LIB_SOVERSION "5") + + +set(KCONTACTS_LIB_VERSION "4.91.0") +set(KCALENDARCORE_LIB_VERSION "4.79.0") +set(IDENTITYMANAGEMENT_LIB_VERSION "4.78.0") +set(KMAILTRANSPORT_LIB_VERSION "4.78.0") +set(CALENDARUTILS_LIB_VERSION "4.78.0") +set(KIMAP_LIB_VERSION "4.80.0") +set(KMBOX_LIB_VERSION "4.79.0") +set(AKONADICALENDAR_LIB_VERSION "4.78.0") +set(SYNDICATION_LIB_VERSION "4.78.0") +set(KONTACTINTERFACE_LIB_VERSION "4.78.0") +set(AKONADIKALARM_LIB_VERSION "4.78.0") +set(KMIME_LIB_VERSION "4.81.0") +set(XMLRPCCLIENT_LIB_VERSION "4.78.0") +set(KCONTACTS_LIB_VERSION "4.78.0") +set(AKONADIMIME_LIB_VERSION "4.78.0") +set(AKONADICONTACT_LIB_VERSION "4.78.0") +set(AKONADINOTE_LIB_VERSION "4.78.0") +set(AKONADISOCIALUTIL_LIB_VERSION "4.78.0") +set(KPIMTEXTEDIT_LIB_VERSION "4.78.0") + +set( SHARED_MIME_INFO_MINIMUM_VERSION "0.40" ) +find_package( SharedMimeInfo REQUIRED ) + + +find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED Widgets Test Declarative XmlPatterns) + +# QT5 package +find_package(Qt5WebKitWidgets ${QT_REQUIRED_VERSION} REQUIRED NO_MODULE) + +find_package(Qt5 OPTIONAL_COMPONENTS TextToSpeech) +if (NOT Qt5TextToSpeech_FOUND) + message(STATUS "Qt5TextToSpeech not found, speech feature will be disabled") +else() + add_definitions(-DHAVE_SPEECH) +endif() -# KdepimLibs -find_package(KdepimLibs 4.14.6) -set_package_properties(KdepimLibs PROPERTIES DESCRIPTION "The KDEPIM libraries" URL "http://www.kde.org" TYPE REQUIRED) +set(KF5AkonadiServer_MIN_VERSION "5.0.50") +find_package(KF5AkonadiServer ${KF5AkonadiServer_MIN_VERSION} CONFIG REQUIRED) +# KF5 package +find_package(KF5KCMUtils ${KF5_VERSION} CONFIG REQUIRED) +find_package(KF5KDELibs4Support ${KF5_VERSION} CONFIG REQUIRED) +find_package(KF5Config ${KF5_VERSION} CONFIG REQUIRED) +find_package(KF5NotifyConfig ${KF5_VERSION} CONFIG REQUIRED) +find_package(KF5KIO ${KF5_VERSION} CONFIG REQUIRED) +find_package(KF5ItemModels ${KF5_VERSION} CONFIG REQUIRED) +find_package(KF5NotifyConfig ${KF5_VERSION} CONFIG REQUIRED) +find_package(KF5Kross ${KF5_VERSION} CONFIG REQUIRED) +find_package(KF5Codecs ${KF5_VERSION} CONFIG REQUIRED) + +# KdepimLibs package +find_package(KF5Akonadi ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5Mime ${KMIME_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5AkonadiMime ${AKONADIMIME_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5MailTransport ${KMAILTRANSPORT_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5IdentityManagement ${IDENTITYMANAGEMENT_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5AkonadiContact ${AKONADICONTACT_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5Contacts ${KCONTACTS_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5AlarmCalendar ${AKONADIKALARM_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5CalendarCore ${KCALENDARCORE_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5CalendarUtils ${CALENDARUTILS_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5Mbox ${KMBOX_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5PimTextEdit ${KPIMTEXTEDIT_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5IMAP ${KIMAP_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5Syndication ${SYNDICATION_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5AkonadiNotes ${AKONADINOTE_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5AkonadiSocialUtils ${AKONADISOCIALUTIL_LIB_VERSION} CONFIG REQUIRED) #Boost # Don't use BoostConfig.cmake set(Boost_NO_BOOST_CMAKE TRUE) find_package(Boost 1.34.0) set_package_properties(Boost PROPERTIES DESCRIPTION "Boost C++ Libraries" URL "http://www.boost.org" TYPE REQUIRED PURPOSE "Boost is required by Akonadi") -# Akonadi -find_package(Akonadi 1.12.90 QUIET CONFIG) -set_package_properties(Akonadi PROPERTIES DESCRIPTION "Akonadi server libraries" URL "http://pim.kde.org/akonadi" TYPE REQUIRED PURPOSE "Access to PIM storage and services") - -# shared-mime-info -find_package(SharedMimeInfo 0.30) -set_package_properties(SharedMimeInfo PROPERTIES DESCRIPTION "The shared-mime-info utility" URL "http://freedesktop.org/wiki/Software/shared-mime-info" TYPE REQUIRED PURPOSE "Information about filetypes") - -# Libkolab -find_package(Libkolab 0.5.2 QUIET CONFIG) -set_package_properties(Libkolab PROPERTIES DESCRIPTION "libkolab" URL "http://mirror.kolabsys.com/pub/releases" TYPE OPTIONAL PURPOSE "The Kolab Format libraries are required to build the Kolab Groupware Resource") - -# Libkolabxml -find_package(Libkolabxml 1.0 QUIET CONFIG) -set_package_properties(Libkolabxml PROPERTIES DESCRIPTION "Kolabxml" URL "http://mirror.kolabsys.com/pub/releases" TYPE OPTIONAL PURPOSE "The Kolab XML Format Schema Definitions Library is required to build the Kolab Groupware Resource") - -# Libkgapi2 -find_package(LibKGAPI2 2.2.0 QUIET CONFIG) -set_package_properties(LibKGAPI2 PROPERTIES DESCRIPTION "KDE-based library for accessing various Google services" URL "https://projects.kde.org/libkgapi" TYPE OPTIONAL PURPOSE "LibKGAPI is required to build Akonadi resources to access Google Contacts, Calendars and Tasks and Gmail") - -# Libkfbapi -find_package(LibKFbAPI 1.0 QUIET CONFIG) -set_package_properties(LibKFbAPI PROPERTIES DESCRIPTION "A library to access Facebook services" URL "http://projects.kde.org/libkfbapi" TYPE OPTIONAL PURPOSE "LibKFbAPI is required to build Akonadi resources to access Facebook's contacts, events, notes and posts" ) - -if(LibKGAPI2_FOUND OR LibKFbAPI_FOUND) - find_package(QJSON) - set_package_properties(QJSON PROPERTIES DESCRIPTION "Qt library for handling JSON data" URL "http://qjson.sourceforge.net/" TYPE REQUIRED PURPOSE "Required to build the Google and Facebook resources") -endif() - -# Xsltproc -find_package(Xsltproc) -set_package_properties(Xsltproc PROPERTIES DESCRIPTION "XSLT processor from libxslt" TYPE REQUIRED PURPOSE "Required to generate D-Bus interfaces for all Akonadi resources.") - -find_package(AccountsQt 1.11 QUIET CONFIG) -set_package_properties(AccountsQt PROPERTIES DESCRIPTION "Qt bindings for accounts-sso" URL "https://code.google.com/p/accounts-sso/" TYPE OPTIONAL PURPOSE "Required to support AccountsQt in different resources") - -find_package(SignOnQt 8.56 QUIET CONFIG) -set_package_properties(SignOnQt PROPERTIES DESCRIPTION "SignOn Qt bindings for accounts-sso" URL "https://code.google.com/p/accounts-sso/" TYPE OPTIONAL PURPOSE "Required to support SignOn in different resources") - -############### Load the CTest options ############### - -# CMake is irritating and doesn't allow setting the tests timeout globally. -# Let's work around this. The global timeout is now 2 minutes. -set(_DartConfigFile "${CMAKE_BINARY_DIR}/DartConfiguration.tcl") -if(EXISTS ${_DartConfigFile}) - set(DartTestingTimeout "120") - file(READ ${_DartConfigFile} _DartConfigFile_content) - string(REGEX REPLACE "TimeOut: 1500" "TimeOut: ${DartTestingTimeout}" _DartConfigFile_content ${_DartConfigFile_content}) - file(WRITE ${_DartConfigFile} ${_DartConfigFile_content}) -endif() - -# 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) - -option(KDEPIM_RUN_ISOLATED_TESTS "Run the isolated tests." FALSE) - -############### Desktop vs. Mobile options ############## - option(KDEPIM_MOBILE_UI "Build UI for mobile devices instead of for desktops" FALSE) if (KDEPIM_MOBILE_UI) add_definitions( -DKDEPIM_MOBILE_UI ) - if(NOT QT_QTDECLARATIVE_FOUND) - message(FATAL_ERROR "The QtDeclarative library is required for building the mobile UI") - endif() endif () -set(LIBRARY_TYPE SHARED) - -#FIXME: kde4_add_plugin doesn't have a parameter to build the plugins statically. -if (RUNTIME_PLUGINS_STATIC) - set(SERIALIZER_TYPE STATIC) -endif () - -############### Enterprise build options ################# - -option(KDEPIM_ENTERPRISE_BUILD "Enable features specific to the enterprise branch, which are normally disabled. Also, it disables many components not needed for Kontact such as the Kolab client." FALSE) - -# config-enterprise.h is needed for both ENTERPRISE_BUILD and BUILD_EVERYTHING -configure_file(config-enterprise.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-enterprise.h ) - -############### Needed commands before building anything ############### - -include_directories(${kdepim-runtime_SOURCE_DIR} ${kdepim-runtime_BINARY_DIR} ${KDEPIMLIBS_INCLUDE_DIRS} ${AKONADI_INCLUDE_DIR} ${KDE4_INCLUDES} ${Boost_INCLUDE_DIR}) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}") - -############### Generate akonadi-config.h ############### - -configure_file(akonadi-version.h.cmake "${kdepim-runtime_BINARY_DIR}/akonadi-version.h" @ONLY) - - -############### Macros ############### - -# resource tests -macro( akonadi_add_resourcetest _testname _script ) - if ( ${EXECUTABLE_OUTPUT_PATH} ) - set( _exepath ${EXECUTABLE_OUTPUT_PATH} ) - else () - set( _exepath ${kdepim-runtime_BINARY_DIR}/resourcetester ) - endif () - if (WIN32) - set(_resourcetester ${_exepath}/resourcetester.bat) - else () - set(_resourcetester ${_exepath}/resourcetester) - endif () - if (UNIX) - set(_resourcetester ${_resourcetester}.shell) - endif () - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${_script} ${CMAKE_CURRENT_BINARY_DIR}/${_script} COPYONLY) - if (KDEPIM_RUN_ISOLATED_TESTS) - add_test( akonadi-mysql-db-${_testname} akonaditest -c ${kdepim-runtime_SOURCE_DIR}/resourcetester/tests/unittestenv/config-mysql-db.xml ${_resourcetester} -c ${CMAKE_CURRENT_BINARY_DIR}/${_script} ) - endif () -endmacro( akonadi_add_resourcetest ) +option(KDEPIM_RUN_ISOLATED_TESTS "Run the isolated tests." FALSE) -############### Now, we add the components ############### add_subdirectory(resources) add_subdirectory(agents) -add_subdirectory(libkdepim-copy) add_subdirectory(plugins) -add_subdirectory(accountwizard) add_subdirectory(defaultsetup) -add_subdirectory(resourcetester) add_subdirectory(kioslave) add_subdirectory(kcm) -add_subdirectory(tray) add_subdirectory(migration) -if (KDEPIMLIBS_KRESOURCES_LIBS) - add_subdirectory(kresources) -endif () -if (QT_QTDECLARATIVE_FOUND) - add_subdirectory(qml) -endif () -#if(OPENSYNC_FOUND) -# add_subdirectory(opensync) -#endif(OPENSYNC_FOUND) - -############### Here we install some extra stuff ############### ## install the MIME type spec file for KDEPIM specific MIME types -install(FILES kdepim-mime.xml DESTINATION ${XDG_MIME_INSTALL_DIR}) -update_xdg_mimetypes(${XDG_MIME_INSTALL_DIR}) +install(FILES kdepim-mime.xml DESTINATION ${KDE_INSTALL_MIMEDIR}) +update_xdg_mimetypes(${KDE_INSTALL_MIMEDIR}) + + +install( FILES kdepim-runtime.categories DESTINATION ${KDE_INSTALL_CONFDIR} ) feature_summary(WHAT ALL - INCLUDE_QUIET_PACKAGES - FATAL_ON_MISSING_REQUIRED_PACKAGES - ) + INCLUDE_QUIET_PACKAGES + FATAL_ON_MISSING_REQUIRED_PACKAGES +) diff -Nru kdepim-runtime-4.14.6/config-enterprise.h.cmake kdepim-runtime-15.08.0/config-enterprise.h.cmake --- kdepim-runtime-4.14.6/config-enterprise.h.cmake 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/config-enterprise.h.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -#cmakedefine KDEPIM_ENTERPRISE_BUILD 1 - diff -Nru kdepim-runtime-4.14.6/debian/changelog kdepim-runtime-15.08.0/debian/changelog --- kdepim-runtime-4.14.6/debian/changelog 2015-08-14 22:12:46.000000000 +0000 +++ kdepim-runtime-15.08.0/debian/changelog 2015-08-27 16:39:09.000000000 +0000 @@ -1,14 +1,42 @@ -kdepim-runtime (4:4.14.6-0ubuntu3) wily; urgency=medium +kdepim-runtime (4:15.08.0-0ubuntu1) wily; urgency=medium - * Remove hard-coded runtime dependency on libkolab0. + * New upstream release - -- Matthias Klose Sat, 15 Aug 2015 00:12:35 +0200 + -- Jonathan Riddell Fri, 21 Aug 2015 17:41:27 +0100 -kdepim-runtime (4:4.14.6-0ubuntu2) wily; urgency=medium +kdepim-runtime (4:15.07.90-0ubuntu2) wily; urgency=medium - * No-change rebuild for renamed libkolab1v5. + * Remove explicit libkolab dependency - -- Matthias Klose Fri, 14 Aug 2015 17:30:08 +0200 + -- Jonathan Riddell Mon, 24 Aug 2015 10:21:44 +0100 + +kdepim-runtime (4:15.07.90-0ubuntu1) wily; urgency=medium + + [ Jonathan Riddell ] + * New upstream release + + [ José Manuel Santamaría Lema ] + * Build depend on default boost libraries, this makes the package buildable + in wily. + + [ Harald Sitter ] + * KDE Frameworks5 port + + -- Jonathan Riddell Fri, 21 Aug 2015 17:37:19 +0100 + +kdepim-runtime (4:4.14.8-0ubuntu2) UNRELEASED; urgency=medium + + * Vivid backport. + + -- Scarlett Clark Sat, 30 May 2015 08:19:03 -0700 + +kdepim-runtime (4:4.14.7-0ubuntu1) UNRELEASED; urgency=medium + + * New upstream release + * Fix watch file. + * wrap-and-sort + + -- Scarlett Clark Thu, 16 Apr 2015 06:13:54 -0700 kdepim-runtime (4:4.14.6-0ubuntu1) vivid; urgency=medium diff -Nru kdepim-runtime-4.14.6/debian/control kdepim-runtime-15.08.0/debian/control --- kdepim-runtime-4.14.6/debian/control 2015-08-14 22:12:04.000000000 +0000 +++ kdepim-runtime-15.08.0/debian/control 2015-08-26 16:23:12.000000000 +0000 @@ -1,8 +1,7 @@ Source: kdepim-runtime Section: x11 Priority: optional -Maintainer: Kubuntu Developers -XSBC-Original-Maintainer: Debian Qt/KDE Maintainers +Maintainer: Debian/Kubuntu Qt/KDE Maintainers Uploaders: Sune Vuorela , Fathi Boudra , Modestas Vainius , @@ -10,30 +9,47 @@ Maximiliano Curia Build-Depends: cmake, debhelper (>= 9), - kde-sc-dev-latest (>= 4:4.12), - kdelibs5-dev (>= 4:4.14.2), - kdepimlibs5-dev (>= 4:4.14.2), - libakonadi-dev (>= 1.12), - libboost-dev (>= 1.40.0-2), - libkgapi-dev (>= 2.2.0), - libkolab-dev (>= 0.5), - libkolabxml-dev (>= 1.0), - libqjson-dev, - libqtwebkit-dev, - libstreamanalyzer-dev, - libx11-dev, + extra-cmake-modules, + kio-dev, + kross-dev, + libboost-dev, + libkf5akonadi-dev, + libkf5akonadicalendar-dev, + libkf5akonadicontact-dev, + libkf5akonadimime-dev, + libkf5akonadinotes-dev, + libkf5akonadisocialutils-dev, + libkf5alarmcalendar-dev, + libkf5calendarcore-dev, + libkf5calendarutils-dev, + libkf5codecs-dev, + libkf5config-dev, + libkf5contacts-dev, + libkf5gapi-dev, + libkf5identitymanagement-dev, + libkf5imap-dev, + libkf5itemmodels-dev, + libkf5kcmutils-dev, + libkf5kdelibs4support-dev, + libkf5mailtransport-dev, + libkf5mbox-dev, + libkf5mime-dev, + libkf5notifyconfig-dev, + libkf5pimtextedit-dev, + libkf5syndication-dev, + libqt5webkit5-dev, + libqt5xmlpatterns5-dev, + libsasl2-dev, pkg-config, pkg-kde-tools (>= 0.12), + qtbase5-dev, + qtquick1-5-dev, shared-mime-info (>= 0.30), - xsltproc, - libaccounts-qt-dev, - libsignon-qt-dev, - libkfbapi-dev, - libsasl2-dev, -Standards-Version: 3.9.5 + xsltproc +Standards-Version: 3.9.6 XS-Testsuite: autopkgtest Homepage: http://pim.kde.org/ -X-Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-kde/kde-sc/kdepim-runtime.git +X-Vcs-Browser: http://anonscm.debian.org/cgit/pkg-kde/kde-sc/kdepim-runtime.git X-Vcs-Git: git://anonscm.debian.org/pkg-kde/kde-sc/kdepim-runtime.git Vcs-Browser: http://bazaar.launchpad.net/~kubuntu-packagers/kubuntu-packaging/kdepim-runtime Vcs-Bzr: https://code.launchpad.net/~kubuntu-packagers/kubuntu-packaging/kdepim-runtime diff -Nru kdepim-runtime-4.14.6/debian/kdepim-runtime.install kdepim-runtime-15.08.0/debian/kdepim-runtime.install --- kdepim-runtime-4.14.6/debian/kdepim-runtime.install 2015-03-13 22:05:23.000000000 +0000 +++ kdepim-runtime-15.08.0/debian/kdepim-runtime.install 2015-08-26 16:23:12.000000000 +0000 @@ -1,189 +1,119 @@ -usr/bin/accountwizard +etc/xdg/kdepim-runtime.categories +usr/bin/akonadi_akonotes_resource usr/bin/akonadi_birthdays_resource +usr/bin/akonadi_contacts_resource usr/bin/akonadi_davgroupware_resource -usr/bin/akonadi_facebook_resource usr/bin/akonadi_googlecalendar_resource usr/bin/akonadi_googlecontacts_resource +usr/bin/akonadi_ical_resource usr/bin/akonadi_icaldir_resource usr/bin/akonadi_imap_resource usr/bin/akonadi_invitations_agent -usr/bin/akonadi_kabc_resource -usr/bin/akonadi_kcal_resource -usr/bin/akonadi_kdeaccounts_resource -usr/bin/akonadi_kolabproxy_resource -usr/bin/akonadi_localbookmarks_resource +usr/bin/akonadi_kalarm_dir_resource +usr/bin/akonadi_kalarm_resource +usr/bin/akonadi_maildir_resource usr/bin/akonadi_maildispatcher_agent -usr/bin/akonadi_mailtransport_dummy_resource +usr/bin/akonadi_mbox_resource usr/bin/akonadi_migration_agent usr/bin/akonadi_mixedmaildir_resource usr/bin/akonadi_newmailnotifier_agent -usr/bin/akonadi_nntp_resource +usr/bin/akonadi_notes_resource usr/bin/akonadi_openxchange_resource usr/bin/akonadi_pop3_resource +usr/bin/akonadi_vcard_resource usr/bin/akonadi_vcarddir_resource -usr/bin/akonaditray usr/bin/gidmigrator -usr/bin/kaddressbookmigrator -usr/bin/kjotsmigrator -usr/bin/kmail-migrator -usr/bin/knotes-migrator -usr/bin/kres-migrator -usr/lib/kde4/accountwizard_plugin.so -usr/lib/kde4/akonadi_akonotes_resource.so -usr/lib/kde4/akonadi_contacts_resource.so -usr/lib/kde4/akonadi_ical_resource.so -usr/lib/kde4/akonadi_kalarm_dir_resource.so -usr/lib/kde4/akonadi_kalarm_resource.so -usr/lib/kde4/akonadi_maildir_resource.so -usr/lib/kde4/akonadi_mbox_resource.so -usr/lib/kde4/akonadi_notes_resource.so -usr/lib/kde4/akonadi_serializer_addressee.so -usr/lib/kde4/akonadi_serializer_bookmark.so -usr/lib/kde4/akonadi_serializer_contactgroup.so -usr/lib/kde4/akonadi_serializer_kalarm.so -usr/lib/kde4/akonadi_serializer_kcal.so -usr/lib/kde4/akonadi_serializer_kcalcore.so -usr/lib/kde4/akonadi_serializer_mail.so -usr/lib/kde4/akonadi_serializer_microblog.so -usr/lib/kde4/akonadi_serializer_socialnotification.so -usr/lib/kde4/akonadi_vcard_resource.so -usr/lib/kde4/imports/org/kde/BreadcrumbNavigationView.qml -usr/lib/kde4/imports/org/kde/Dialog.qml -usr/lib/kde4/imports/org/kde/Flap.qml -usr/lib/kde4/imports/org/kde/Flap2.qml -usr/lib/kde4/imports/org/kde/SlideoutPanel.qml -usr/lib/kde4/imports/org/kde/SlideoutPanelContainer.qml -usr/lib/kde4/imports/org/kde/akonadi/AkonadiBreadcrumbNavigationView.qml -usr/lib/kde4/imports/org/kde/akonadi/CollectionDelegate.qml -usr/lib/kde4/imports/org/kde/akonadi/border_dot.png -usr/lib/kde4/imports/org/kde/akonadi/check.png -usr/lib/kde4/imports/org/kde/akonadi/collectionview.qml -usr/lib/kde4/imports/org/kde/akonadi/qmldir -usr/lib/kde4/imports/org/kde/akonadi/sliderbackground.png -usr/lib/kde4/imports/org/kde/akonadi/transparentplus.png -usr/lib/kde4/imports/org/kde/dividing-line-horizontal.png -usr/lib/kde4/imports/org/kde/dividing-line.png -usr/lib/kde4/imports/org/kde/flap-collapsed-bottom.png -usr/lib/kde4/imports/org/kde/flap-collapsed-mid.png -usr/lib/kde4/imports/org/kde/flap-collapsed-top.png -usr/lib/kde4/imports/org/kde/flap-expanded-bottom.png -usr/lib/kde4/imports/org/kde/flap-expanded-mid.png -usr/lib/kde4/imports/org/kde/flap-expanded-top.png -usr/lib/kde4/imports/org/kde/libkdeqmlplugin.so -usr/lib/kde4/imports/org/kde/list-line-top.png -usr/lib/kde4/imports/org/kde/qmldir -usr/lib/kde4/imports/org/kde/scrollable-bottom.png -usr/lib/kde4/imports/org/kde/scrollable-top.png -usr/lib/kde4/kabc_akonadi.so -usr/lib/kde4/kcal_akonadi.so -usr/lib/kde4/kcm_akonadi.so -usr/lib/kde4/kcm_akonadi_resources.so -usr/lib/kde4/kcm_akonadi_server.so -usr/lib/kde4/kio_akonadi.so -usr/lib/libakonadi-filestore.so.4 -usr/lib/libakonadi-filestore.so.4.* -usr/lib/libfolderarchivesettings.so.4 -usr/lib/libfolderarchivesettings.so.4.* -usr/lib/libkdepim-copy.so.4 -usr/lib/libkdepim-copy.so.4.* -usr/lib/libkmindexreader.so.4 -usr/lib/libkmindexreader.so.4.* -usr/lib/libmaildir.so.4 -usr/lib/libmaildir.so.4.* -usr/share/akonadi/agents/akonadinepomukfeederagent.desktop +usr/lib/*/libakonadi-filestore.so.* +usr/lib/*/libakonadi-singlefileresource.so.* +usr/lib/*/libfolderarchivesettings.so.* +usr/lib/*/libkmindexreader.so.* +usr/lib/*/libmaildir.so.* +usr/lib/*/qt5/plugins/akonadi_serializer_addressee.so +usr/lib/*/qt5/plugins/akonadi_serializer_contactgroup.so +usr/lib/*/qt5/plugins/akonadi_serializer_kalarm.so +usr/lib/*/qt5/plugins/akonadi_serializer_kcalcore.so +usr/lib/*/qt5/plugins/akonadi_serializer_mail.so +usr/lib/*/qt5/plugins/kcm_akonadi.so +usr/lib/*/qt5/plugins/kcm_akonadi_resources.so +usr/lib/*/qt5/plugins/kcm_akonadi_server.so +usr/lib/*/qt5/plugins/kf5/kio/akonadi.so +usr/share/akonadi/accountwizard/contacts/contactswizard.desktop +usr/share/akonadi/accountwizard/contacts/contactswizard.es +usr/share/akonadi/accountwizard/contacts/contactswizard.ui +usr/share/akonadi/accountwizard/ical/icalwizard.desktop +usr/share/akonadi/accountwizard/ical/icalwizard.es +usr/share/akonadi/accountwizard/ical/icalwizard.ui +usr/share/akonadi/accountwizard/imap/imapwizard.desktop +usr/share/akonadi/accountwizard/imap/imapwizard.es +usr/share/akonadi/accountwizard/imap/imapwizard.ui +usr/share/akonadi/accountwizard/mailbox/mailboxwizard.desktop +usr/share/akonadi/accountwizard/mailbox/mailboxwizard.es +usr/share/akonadi/accountwizard/mailbox/mailboxwizard.ui +usr/share/akonadi/accountwizard/maildir/maildirwizard.desktop +usr/share/akonadi/accountwizard/maildir/maildirwizard.es +usr/share/akonadi/accountwizard/maildir/maildirwizard.ui +usr/share/akonadi/accountwizard/pop3/pop3wizard.desktop +usr/share/akonadi/accountwizard/pop3/pop3wizard.es +usr/share/akonadi/accountwizard/pop3/pop3wizard.ui +usr/share/akonadi/accountwizard/vcard/vcardwizard.desktop +usr/share/akonadi/accountwizard/vcard/vcardwizard.es +usr/share/akonadi/accountwizard/vcard/vcardwizard.ui +usr/share/akonadi/accountwizard/vcarddir/vcarddirwizard.desktop +usr/share/akonadi/accountwizard/vcarddir/vcarddirwizard.es +usr/share/akonadi/accountwizard/vcarddir/vcarddirwizard.ui usr/share/akonadi/agents/akonotesresource.desktop usr/share/akonadi/agents/birthdaysresource.desktop usr/share/akonadi/agents/contactsresource.desktop usr/share/akonadi/agents/davgroupwareresource.desktop -usr/share/akonadi/agents/facebookresource.desktop usr/share/akonadi/agents/googlecalendarresource.desktop usr/share/akonadi/agents/googlecontactsresource.desktop usr/share/akonadi/agents/icaldirresource.desktop usr/share/akonadi/agents/icalresource.desktop usr/share/akonadi/agents/imapresource.desktop usr/share/akonadi/agents/invitationsagent.desktop -usr/share/akonadi/agents/kabcresource.desktop usr/share/akonadi/agents/kalarmdirresource.desktop usr/share/akonadi/agents/kalarmresource.desktop -usr/share/akonadi/agents/kcalresource.desktop -usr/share/akonadi/agents/kdeaccountsresource.desktop -usr/share/akonadi/agents/kolabproxyresource.desktop -usr/share/akonadi/agents/localbookmarksresource.desktop usr/share/akonadi/agents/maildirresource.desktop usr/share/akonadi/agents/maildispatcheragent.desktop usr/share/akonadi/agents/mboxresource.desktop usr/share/akonadi/agents/migrationagent.desktop usr/share/akonadi/agents/mixedmaildirresource.desktop -usr/share/akonadi/agents/mtdummyresource.desktop usr/share/akonadi/agents/newmailnotifieragent.desktop -usr/share/akonadi/agents/nntpresource.desktop usr/share/akonadi/agents/notesresource.desktop usr/share/akonadi/agents/openxchangeresource.desktop usr/share/akonadi/agents/pop3resource.desktop usr/share/akonadi/agents/vcarddirresource.desktop usr/share/akonadi/agents/vcardresource.desktop -usr/share/applications/kde4/accountwizard.desktop -usr/share/applications/kde4/akonaditray.desktop -usr/share/autostart/kaddressbookmigrator.desktop -usr/share/icons/hicolor/*/apps/akonaditray.png -usr/share/icons/hicolor/*/apps/facebookresource.png -usr/share/icons/hicolor/*/apps/kolab.png -usr/share/icons/hicolor/*/apps/ox.png -usr/share/icons/hicolor/scalable/apps/akonaditray.svgz -usr/share/kde4/apps/akonadi/accountwizard/contacts/ -usr/share/kde4/apps/akonadi/accountwizard/ical/ -usr/share/kde4/apps/akonadi/accountwizard/imap/ -usr/share/kde4/apps/akonadi/accountwizard/kolab/ -usr/share/kde4/apps/akonadi/accountwizard/mailbox/ -usr/share/kde4/apps/akonadi/accountwizard/maildir/ -usr/share/kde4/apps/akonadi/accountwizard/pop3/ -usr/share/kde4/apps/akonadi/accountwizard/tine20/ -usr/share/kde4/apps/akonadi/firstrun/defaultaddressbook -usr/share/kde4/apps/akonadi/firstrun/defaultcalendar -usr/share/kde4/apps/akonadi/firstrun/defaultnotebook -usr/share/kde4/apps/akonadi/plugins/serializer/akonadi_serializer_addressee.desktop -usr/share/kde4/apps/akonadi/plugins/serializer/akonadi_serializer_bookmark.desktop -usr/share/kde4/apps/akonadi/plugins/serializer/akonadi_serializer_contactgroup.desktop -usr/share/kde4/apps/akonadi/plugins/serializer/akonadi_serializer_kalarm.desktop -usr/share/kde4/apps/akonadi/plugins/serializer/akonadi_serializer_kcal.desktop -usr/share/kde4/apps/akonadi/plugins/serializer/akonadi_serializer_kcalcore.desktop -usr/share/kde4/apps/akonadi/plugins/serializer/akonadi_serializer_mail.desktop -usr/share/kde4/apps/akonadi/plugins/serializer/akonadi_serializer_microblog.desktop -usr/share/kde4/apps/akonadi/plugins/serializer/akonadi_serializer_socialnotification.desktop -usr/share/kde4/apps/akonadi_facebook_resource/akonadi_facebook_resource.notifyrc -usr/share/kde4/apps/akonadi_kolabproxy_resource/akonadi_kolabproxy_resource.notifyrc -usr/share/kde4/apps/akonadi_maildispatcher_agent/akonadi_maildispatcher_agent.notifyrc -usr/share/kde4/apps/akonadi_newmailnotifier_agent/akonadi_newmailnotifier_agent.notifyrc -usr/share/kde4/apps/kconf_update/newmailnotifier.upd -usr/share/kde4/config/accountwizard.knsrc -usr/share/kde4/config/kmail-migratorrc -usr/share/kde4/config/kres-migratorrc -usr/share/kde4/services/akonadi.protocol -usr/share/kde4/services/akonadi/davgroupware-providers/citadel.desktop -usr/share/kde4/services/akonadi/davgroupware-providers/davical.desktop -usr/share/kde4/services/akonadi/davgroupware-providers/egroupware.desktop -usr/share/kde4/services/akonadi/davgroupware-providers/opengroupware.desktop -usr/share/kde4/services/akonadi/davgroupware-providers/owncloud-pre5.desktop -usr/share/kde4/services/akonadi/davgroupware-providers/owncloud.desktop -usr/share/kde4/services/akonadi/davgroupware-providers/scalix.desktop -usr/share/kde4/services/akonadi/davgroupware-providers/sogo.desktop -usr/share/kde4/services/akonadi/davgroupware-providers/yahoo.desktop -usr/share/kde4/services/akonadi/davgroupware-providers/zarafa.desktop -usr/share/kde4/services/akonadi/davgroupware-providers/zimbra.desktop -usr/share/kde4/services/kcm_akonadi.desktop -usr/share/kde4/services/kcm_akonadi_resources.desktop -usr/share/kde4/services/kcm_akonadi_server.desktop -usr/share/kde4/services/kresources/kabc/akonadi.desktop -usr/share/kde4/services/kresources/kcal/akonadi.desktop -usr/share/kde4/servicetypes/davgroupwareprovider.desktop -usr/share/mime/packages/accountwizard-mime.xml +usr/share/akonadi/firstrun/birthdaycalendar +usr/share/akonadi/firstrun/defaultaddressbook +usr/share/akonadi/firstrun/defaultcalendar +usr/share/akonadi/firstrun/defaultnotebook +usr/share/akonadi/plugins/serializer/akonadi_serializer_addressee.desktop +usr/share/akonadi/plugins/serializer/akonadi_serializer_contactgroup.desktop +usr/share/akonadi/plugins/serializer/akonadi_serializer_kalarm.desktop +usr/share/akonadi/plugins/serializer/akonadi_serializer_kcalcore.desktop +usr/share/akonadi/plugins/serializer/akonadi_serializer_mail.desktop +usr/share/icons/hicolor/128x128/apps/ox.png +usr/share/icons/hicolor/16x16/apps/ox.png +usr/share/icons/hicolor/32x32/apps/ox.png +usr/share/icons/hicolor/48x48/apps/ox.png +usr/share/icons/hicolor/64x64/apps/ox.png +usr/share/knotifications5/akonadi_maildispatcher_agent.notifyrc +usr/share/knotifications5/akonadi_newmailnotifier_agent.notifyrc +usr/share/kservices5/akonadi.protocol +usr/share/kservices5/akonadi/davgroupware-providers/citadel.desktop +usr/share/kservices5/akonadi/davgroupware-providers/davical.desktop +usr/share/kservices5/akonadi/davgroupware-providers/egroupware.desktop +usr/share/kservices5/akonadi/davgroupware-providers/opengroupware.desktop +usr/share/kservices5/akonadi/davgroupware-providers/owncloud-pre5.desktop +usr/share/kservices5/akonadi/davgroupware-providers/owncloud.desktop +usr/share/kservices5/akonadi/davgroupware-providers/scalix.desktop +usr/share/kservices5/akonadi/davgroupware-providers/sogo.desktop +usr/share/kservices5/akonadi/davgroupware-providers/yahoo.desktop +usr/share/kservices5/akonadi/davgroupware-providers/zarafa.desktop +usr/share/kservices5/akonadi/davgroupware-providers/zimbra.desktop +usr/share/kservices5/kcm_akonadi.desktop +usr/share/kservices5/kcm_akonadi_resources.desktop +usr/share/kservices5/kcm_akonadi_server.desktop +usr/share/kservicetypes5/davgroupwareprovider.desktop usr/share/mime/packages/kdepim-mime.xml -usr/share/mime/packages/x-vnd.akonadi.socialnotification.xml -usr/bin/akonadi_kolab_resource -usr/share/akonadi/agents/kolabresource.desktop -usr/share/kde4/apps/akonadi/accountwizard/vcard/vcardwizard.desktop -usr/share/kde4/apps/akonadi/accountwizard/vcard/vcardwizard.es -usr/share/kde4/apps/akonadi/accountwizard/vcard/vcardwizard.ui -usr/share/kde4/apps/akonadi/accountwizard/vcarddir/vcarddirwizard.desktop -usr/share/kde4/apps/akonadi/accountwizard/vcarddir/vcarddirwizard.es -usr/share/kde4/apps/akonadi/accountwizard/vcarddir/vcarddirwizard.ui diff -Nru kdepim-runtime-4.14.6/debian/kdepim-runtime.lintian-overrides kdepim-runtime-15.08.0/debian/kdepim-runtime.lintian-overrides --- kdepim-runtime-4.14.6/debian/kdepim-runtime.lintian-overrides 2015-03-13 22:05:23.000000000 +0000 +++ kdepim-runtime-15.08.0/debian/kdepim-runtime.lintian-overrides 2015-08-26 16:23:12.000000000 +0000 @@ -1,4 +1,3 @@ kdepim-runtime: package-name-doesnt-match-sonames -kdepim-runtime: executable-not-elf-or-script usr/share/autostart/kaddressbookmigrator.desktop kdepim-runtime: image-file-in-usr-lib kdepim-runtime: no-symbols-control-file diff -Nru kdepim-runtime-4.14.6/debian/not-installed kdepim-runtime-15.08.0/debian/not-installed --- kdepim-runtime-4.14.6/debian/not-installed 2015-03-13 22:05:23.000000000 +0000 +++ kdepim-runtime-15.08.0/debian/not-installed 2015-08-26 16:23:12.000000000 +0000 @@ -1,10 +1,10 @@ -./usr/lib/libakonadi-filestore.so -./usr/lib/libakonadi-xml.so -./usr/lib/libfolderarchivesettings.so -./usr/lib/libkdepim-copy.so -./usr/lib/libkmindexreader.so -./usr/lib/libmaildir.so -./usr/lib/libnepomukfeederpluginlib.a +# TODO: talk to usptream about getting these not installed. they are not used. ./usr/share/dbus-1/interfaces/org.kde.Akonadi.Maildir.Settings.xml ./usr/share/dbus-1/interfaces/org.kde.Akonadi.MixedMaildir.Settings.xml -./usr/lib/sasl2/libkdexoauth2.so + +# TODO: upstream SKIP_NAMELINK so we get no symlinks for private libs +./usr/lib/*/libakonadi-filestore.so +./usr/lib/*/libakonadi-singlefileresource.so +./usr/lib/*/libfolderarchivesettings.so +./usr/lib/*/libkmindexreader.so +./usr/lib/*/libmaildir.so diff -Nru kdepim-runtime-4.14.6/debian/patches/hide_akonaditray.diff kdepim-runtime-15.08.0/debian/patches/hide_akonaditray.diff --- kdepim-runtime-4.14.6/debian/patches/hide_akonaditray.diff 2015-03-13 22:05:23.000000000 +0000 +++ kdepim-runtime-15.08.0/debian/patches/hide_akonaditray.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -Author: Michael Biebl -Description: Hide akonaditray to not show up in the menu. -Last-Update: 2011-10-21 -Forwarded: no - -Index: kdepim-runtime/tray/akonaditray.desktop -=================================================================== ---- kdepim-runtime.orig/tray/akonaditray.desktop 2013-11-10 00:47:26.185186739 +0100 -+++ kdepim-runtime/tray/akonaditray.desktop 2013-11-10 00:47:26.181186903 +0100 -@@ -99,3 +99,4 @@ - GenericName[x-test]=xxAkonadi Tray Utilityxx - GenericName[zh_CN]=Akonadi 托盘工具 - GenericName[zh_TW]=Akonadi 系統匣工具 -+NoDisplay=true diff -Nru kdepim-runtime-4.14.6/debian/patches/kubuntu_signonqt4.diff kdepim-runtime-15.08.0/debian/patches/kubuntu_signonqt4.diff --- kdepim-runtime-4.14.6/debian/patches/kubuntu_signonqt4.diff 2015-03-13 22:05:23.000000000 +0000 +++ kdepim-runtime-15.08.0/debian/patches/kubuntu_signonqt4.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -98,8 +98,8 @@ - find_package(AccountsQt 1.11 QUIET CONFIG) - set_package_properties(AccountsQt PROPERTIES DESCRIPTION "Qt bindings for accounts-sso" URL "https://code.google.com/p/accounts-sso/" TYPE OPTIONAL PURPOSE "Required to support AccountsQt in different resources") - --find_package(SignOnQt 8.56 QUIET CONFIG) --set_package_properties(SignOnQt PROPERTIES DESCRIPTION "SignOn Qt bindings for accounts-sso" URL "https://code.google.com/p/accounts-sso/" TYPE OPTIONAL PURPOSE "Required to support SignOn in different resources") -+find_package(SignOnQt4 8.56 QUIET CONFIG) -+set_package_properties(SignOnQt4 PROPERTIES DESCRIPTION "SignOn Qt bindings for accounts-sso" URL "https://code.google.com/p/accounts-sso/" TYPE OPTIONAL PURPOSE "Required to support SignOn in different resources") - - ############### Load the CTest options ############### - ---- a/resources/dav/resource/CMakeLists.txt -+++ b/resources/dav/resource/CMakeLists.txt -@@ -55,7 +55,7 @@ - urlconfigurationdialog.cpp - ) - -- if(${AccountsQt_FOUND} AND ${SignOnQt_FOUND}) -+ if(${AccountsQt_FOUND} AND ${SignOnQt4_FOUND}) - include_directories(${ACCOUNTSQT_INCLUDE_DIRS} ${SIGNONQT_INCLUDE_DIRS}) - add_definitions(-DHAVE_ACCOUNTS) - set(davgroupwareresource_SRCS ../../shared/getcredentialsjob.cpp ${davgroupwareresource_SRCS}) -@@ -94,7 +94,7 @@ - ${KDEPIMLIBS_KABC_LIBS} - ${KDEPIMLIBS_KCALCORE_LIBS}) - -- if(${AccountsQt_FOUND} AND ${SignOnQt_FOUND}) -+ if(${AccountsQt_FOUND} AND ${SignOnQt4_FOUND}) - target_link_libraries(akonadi_davgroupware_resource - ${ACCOUNTSQT_LIBRARIES} - ${SIGNONQT_LIBRARIES}) ---- a/resources/facebook/CMakeLists.txt -+++ b/resources/facebook/CMakeLists.txt -@@ -1,7 +1,7 @@ - project(facebookresource) - include_directories(${LibKFbAPI_INCLUDE_DIR}) - include_directories(${QJSON_INCLUDE_DIR} ${qjson_INCLUDE_DIR}) --if(${AccountsQt_FOUND} AND ${SignOnQt_FOUND}) -+if(${AccountsQt_FOUND} AND ${SignOnQt4_FOUND}) - include_directories(${ACCOUNTSQT_INCLUDE_DIRS} ${SIGNONQT_INCLUDE_DIRS}) - add_definitions(-DHAVE_ACCOUNTS) - set(facebookresource_SRCS ../shared/getcredentialsjob.cpp) -@@ -71,7 +71,7 @@ - ${LibKFbAPI_LIBRARY} - ) - --if(${AccountsQt_FOUND} AND ${SignOnQt_FOUND}) -+if(${AccountsQt_FOUND} AND ${SignOnQt4_FOUND}) - target_link_libraries(akonadi_facebook_resource - ${ACCOUNTSQT_LIBRARIES} - ${SIGNONQT_LIBRARIES}) ---- a/resources/google/calendar/CMakeLists.txt -+++ b/resources/google/calendar/CMakeLists.txt -@@ -62,7 +62,7 @@ - ${LibKGAPI2_LIBRARY} - ) - --if(${AccountsQt_FOUND} AND ${SignOnQt_FOUND}) -+if(${AccountsQt_FOUND} AND ${SignOnQt4_FOUND}) - target_link_libraries(akonadi_googlecalendar_resource - ${ACCOUNTSQT_LIBRARIES} - ${SIGNONQT_LIBRARIES}) ---- a/resources/google/contacts/CMakeLists.txt -+++ b/resources/google/contacts/CMakeLists.txt -@@ -49,7 +49,7 @@ - ${LibKGAPI2_LIBRARY} - ) - --if(${AccountsQt_FOUND} AND ${SignOnQt_FOUND}) -+if(${AccountsQt_FOUND} AND ${SignOnQt4_FOUND}) - target_link_libraries(akonadi_googlecontacts_resource - ${ACCOUNTSQT_LIBRARIES} - ${SIGNONQT_LIBRARIES}) ---- a/resources/google/CMakeLists.txt -+++ b/resources/google/CMakeLists.txt -@@ -4,7 +4,7 @@ - add_definitions( -DQT_NO_CAST_TO_ASCII ) - - --if(${AccountsQt_FOUND} AND ${SignOnQt_FOUND}) -+if(${AccountsQt_FOUND} AND ${SignOnQt4_FOUND}) - include_directories(${ACCOUNTSQT_INCLUDE_DIRS} ${SIGNONQT_INCLUDE_DIRS} ../) - add_definitions(-DHAVE_ACCOUNTS) - set(accounts_SRCS ../../shared/getcredentialsjob.cpp) diff -Nru kdepim-runtime-4.14.6/debian/patches/series kdepim-runtime-15.08.0/debian/patches/series --- kdepim-runtime-4.14.6/debian/patches/series 2015-03-13 22:05:23.000000000 +0000 +++ kdepim-runtime-15.08.0/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -hide_akonaditray.diff -kubuntu_signonqt4.diff diff -Nru kdepim-runtime-4.14.6/debian/rules kdepim-runtime-15.08.0/debian/rules --- kdepim-runtime-4.14.6/debian/rules 2015-03-13 22:05:23.000000000 +0000 +++ kdepim-runtime-15.08.0/debian/rules 2015-08-26 16:23:12.000000000 +0000 @@ -1,6 +1,6 @@ #!/usr/bin/make -f -include /usr/share/pkg-kde-tools/qt-kde-team/2/debian-qt-kde.mk +include /usr/share/pkg-kde-tools/qt-kde-team/3/debian-qt-kde.mk .PHONY: override_dh_auto_test diff -Nru kdepim-runtime-4.14.6/debian/watch kdepim-runtime-15.08.0/debian/watch --- kdepim-runtime-4.14.6/debian/watch 2015-03-13 22:05:23.000000000 +0000 +++ kdepim-runtime-15.08.0/debian/watch 2015-08-26 16:23:12.000000000 +0000 @@ -1,2 +1,3 @@ version=3 -http://download.kde.org/stable/applications/14.12.3/src/kdepim-runtime-([\d\.]*).tar.xz +http://download.kde.org/stable/applications/([\d.]+)/src/kdepim-runtime-([\d.]+).tar.xz +http://download.kde.org/unstable/applications/([\d.]+)/src/kdepim-runtime-([\d.]+).tar.xz diff -Nru kdepim-runtime-4.14.6/defaultsetup/CMakeLists.txt kdepim-runtime-15.08.0/defaultsetup/CMakeLists.txt --- kdepim-runtime-4.14.6/defaultsetup/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/defaultsetup/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -7,4 +7,4 @@ ${CMAKE_CURRENT_BINARY_DIR}/defaultaddressbook ${CMAKE_CURRENT_BINARY_DIR}/defaultnotebook ${CMAKE_CURRENT_BINARY_DIR}/birthdaycalendar - DESTINATION ${DATA_INSTALL_DIR}/akonadi/firstrun ) + DESTINATION ${KDE_INSTALL_DATADIR}/akonadi/firstrun ) diff -Nru kdepim-runtime-4.14.6/defaultsetup/defaultcalendar.desktop kdepim-runtime-15.08.0/defaultsetup/defaultcalendar.desktop --- kdepim-runtime-4.14.6/defaultsetup/defaultcalendar.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/defaultsetup/defaultcalendar.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -2,6 +2,7 @@ Id=defaultcalendar Type=akonadi_ical_resource Name=Personal Calendar +Name[bg]=Личен календар Name[bs]=Lični kalendar Name[ca]=Calendari personal Name[ca@valencia]=Calendari personal diff -Nru kdepim-runtime-4.14.6/defaultsetup/defaultnotebook.desktop kdepim-runtime-15.08.0/defaultsetup/defaultnotebook.desktop --- kdepim-runtime-4.14.6/defaultsetup/defaultnotebook.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/defaultsetup/defaultnotebook.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -46,7 +46,6 @@ Name[ne]=टिपोट Name[nl]=Notities Name[nn]=Notat -Name[oc]=Nòtas Name[pa]=ਨੋਟਿਸ Name[pl]=Notatki Name[pt]=Notas @@ -55,7 +54,7 @@ Name[ru]=Заметки Name[se]=Nohtat Name[sk]=Poznámky -Name[sl]=Notice +Name[sl]=Sporočilca Name[sq]=Shënimet Name[sr]=Белешке Name[sr@ijekavian]=Биљешке diff -Nru kdepim-runtime-4.14.6/.gitignore kdepim-runtime-15.08.0/.gitignore --- kdepim-runtime-4.14.6/.gitignore 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/.gitignore 2015-08-10 21:01:02.000000000 +0000 @@ -19,3 +19,6 @@ avail Doxyfile *.user +/build/ +CMakeLists.txt.user* + diff -Nru kdepim-runtime-4.14.6/kcm/akonadiconfigmodule.cpp kdepim-runtime-15.08.0/kcm/akonadiconfigmodule.cpp --- kdepim-runtime-4.14.6/kcm/akonadiconfigmodule.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kcm/akonadiconfigmodule.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,15 +22,14 @@ #include #include -K_PLUGIN_FACTORY( AkonadiConfigModuleFactory, registerPlugin(); ) -K_EXPORT_PLUGIN( AkonadiConfigModuleFactory( "kcm_akonadi" ) ) - -AkonadiConfigModule::AkonadiConfigModule( QWidget * parent, const QVariantList & args ) : - KCModuleContainer( parent ) +K_PLUGIN_FACTORY(AkonadiConfigModuleFactory, registerPlugin();) +AkonadiConfigModule::AkonadiConfigModule(QWidget *parent, const QVariantList &args) : + KCModuleContainer(parent) { - Q_UNUSED( args ); - setButtons( KCModule::Default | KCModule::Apply ); - addModule( QLatin1String( "kcm_akonadi_resources" ) ); - addModule( QLatin1String( "kcm_akonadi_server" ) ); + Q_UNUSED(args); + setButtons(KCModule::Default | KCModule::Apply); + addModule(QStringLiteral("kcm_akonadi_resources")); + addModule(QStringLiteral("kcm_akonadi_server")); } +#include "akonadiconfigmodule.moc" diff -Nru kdepim-runtime-4.14.6/kcm/akonadiconfigmodule.h kdepim-runtime-15.08.0/kcm/akonadiconfigmodule.h --- kdepim-runtime-4.14.6/kcm/akonadiconfigmodule.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kcm/akonadiconfigmodule.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,8 +24,8 @@ class AkonadiConfigModule : public KCModuleContainer { - public: - explicit AkonadiConfigModule( QWidget *parent = 0, const QVariantList &args = QVariantList() ); +public: + explicit AkonadiConfigModule(QWidget *parent = Q_NULLPTR, const QVariantList &args = QVariantList()); }; #endif diff -Nru kdepim-runtime-4.14.6/kcm/CMakeLists.txt kdepim-runtime-15.08.0/kcm/CMakeLists.txt --- kdepim-runtime-4.14.6/kcm/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kcm/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,35 +1,48 @@ +project(kcmakonadi) add_definitions( -DQT_NO_CAST_FROM_ASCII ) add_definitions( -DQT_NO_CAST_TO_ASCII ) -include_directories( ${kdepim-runtime_SOURCE_DIR} ) + +if ("${CMAKE_SOURCE_DIR}" STREQUAL "${kcmakonadi_SOURCE_DIR}") + set(KDEPIMLIBS_LIB_VERSION "4.75.0") + find_package(KF5KCMUtils ${KF5_VERSION} CONFIG REQUIRED) + find_package(KF5Akonadi ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) +endif() + +add_definitions(-DTRANSLATION_DOMAIN=\"kcm_akonadi\") set(akonadi_resources_kcm_srcs configmodule.cpp resourcesmanagementwidget.cpp) -kde4_add_ui_files(akonadi_resources_kcm_srcs resourcesmanagementwidget.ui ) -kde4_add_plugin(kcm_akonadi_resources ${akonadi_resources_kcm_srcs}) -target_link_libraries(kcm_akonadi_resources ${KDE4_KDEUI_LIBS} ${KDEPIMLIBS_AKONADI_LIBS}) +ki18n_wrap_ui(akonadi_resources_kcm_srcs resourcesmanagementwidget.ui ) +add_library(kcm_akonadi_resources MODULE ${akonadi_resources_kcm_srcs}) +target_link_libraries(kcm_akonadi_resources KF5::AkonadiCore KF5::AkonadiWidgets Qt5::Widgets) set(akonadi_server_kcm_srcs serverconfigmodule.cpp) -kde4_add_ui_files(akonadi_server_kcm_srcs serverconfigmodule.ui +ki18n_wrap_ui(akonadi_server_kcm_srcs serverconfigmodule.ui servermysqlstorage.ui serverpsqlstorage.ui serverstoragedriver.ui) -kde4_add_plugin(kcm_akonadi_server ${akonadi_server_kcm_srcs}) -target_link_libraries(kcm_akonadi_server ${KDE4_KIO_LIBS} ${KDEPIMLIBS_AKONADI_LIBS} ${AKONADI_COMMON_LIBRARIES}) +add_library(kcm_akonadi_server MODULE ${akonadi_server_kcm_srcs}) +target_link_libraries(kcm_akonadi_server KF5::KIOCore KF5::AkonadiWidgets KF5::KCMUtils KF5::I18n KF5::Completion KF5::KIOWidgets KF5::AkonadiPrivate) set(akonadi_kcm_srcs akonadiconfigmodule.cpp) -kde4_add_plugin(kcm_akonadi ${akonadi_kcm_srcs}) -target_link_libraries(kcm_akonadi ${KDE4_KCMUTILS_LIBS}) +add_library(kcm_akonadi MODULE ${akonadi_kcm_srcs}) +target_link_libraries(kcm_akonadi KF5::KCMUtils KF5::AkonadiWidgets KF5::AkonadiCore) install(TARGETS kcm_akonadi_resources kcm_akonadi_server kcm_akonadi - DESTINATION ${PLUGIN_INSTALL_DIR}) + DESTINATION ${KDE_INSTALL_PLUGINDIR}) install(FILES kcm_akonadi_resources.desktop kcm_akonadi_server.desktop kcm_akonadi.desktop - DESTINATION ${SERVICES_INSTALL_DIR}) + DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) + +if ("${CMAKE_SOURCE_DIR}" STREQUAL "${kcmakonadi_SOURCE_DIR}") + feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) +endif() + diff -Nru kdepim-runtime-4.14.6/kcm/configmodule.cpp kdepim-runtime-15.08.0/kcm/configmodule.cpp --- kdepim-runtime-4.14.6/kcm/configmodule.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kcm/configmodule.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,29 +21,30 @@ #include "configmodule.h" #include "resourcesmanagementwidget.h" -#include +#include #include #include #include -#include +#include -K_PLUGIN_FACTORY( ResourcesConfigFactory, registerPlugin(); ) -K_EXPORT_PLUGIN( ResourcesConfigFactory( "imaplib" ) ) +K_PLUGIN_FACTORY(ResourcesConfigFactory, registerPlugin();) -ConfigModule::ConfigModule( QWidget * parent, const QVariantList & args ) : - KCModule( ResourcesConfigFactory::componentData(), parent, args ) +ConfigModule::ConfigModule(QWidget *parent, const QVariantList &args) : + KCModule(parent, args) { - KGlobal::locale()->insertCatalog( QLatin1String("kcm_akonadi") ); - KGlobal::locale()->insertCatalog( QLatin1String("libakonadi") ); - Akonadi::Control::widgetNeedsAkonadi(this); - setButtons( KCModule::Default | KCModule::Apply ); - QVBoxLayout *l = new QVBoxLayout( this ); - l->setMargin( 0 ); + Akonadi::ControlGui::widgetNeedsAkonadi(this); + setButtons(KCModule::Default | KCModule::Apply); + QVBoxLayout *l = new QVBoxLayout(this); + l->setMargin(0); QStringList args2; - foreach ( const QVariant& item, args ) - args2 << item.toString(); + args2.reserve(args.count()); + foreach (const QVariant &item, args) { + args2 << item.toString(); + } - ResourcesManagementWidget *tmw = new ResourcesManagementWidget( this, args2 ); - l->addWidget( tmw ); + ResourcesManagementWidget *tmw = new ResourcesManagementWidget(this, args2); + l->addWidget(tmw); } +#include "configmodule.moc" + diff -Nru kdepim-runtime-4.14.6/kcm/configmodule.h kdepim-runtime-15.08.0/kcm/configmodule.h --- kdepim-runtime-4.14.6/kcm/configmodule.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kcm/configmodule.h 2015-08-10 21:01:02.000000000 +0000 @@ -29,8 +29,8 @@ class ConfigModule : public KCModule { public: - explicit ConfigModule( QWidget *parent = 0, - const QVariantList &args = QVariantList() ); + explicit ConfigModule(QWidget *parent = Q_NULLPTR, + const QVariantList &args = QVariantList()); }; #endif diff -Nru kdepim-runtime-4.14.6/kcm/kcm_akonadi.desktop kdepim-runtime-15.08.0/kcm/kcm_akonadi.desktop --- kdepim-runtime-4.14.6/kcm/kcm_akonadi.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kcm/kcm_akonadi.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,5 @@ [Desktop Entry] -Exec=kcmshell4 kcm_akonadi +Exec=kcmshell5 kcm_akonadi Icon=akonadi Type=Service ServiceTypes=KCModule diff -Nru kdepim-runtime-4.14.6/kcm/kcm_akonadi_resources.desktop kdepim-runtime-15.08.0/kcm/kcm_akonadi_resources.desktop --- kdepim-runtime-4.14.6/kcm/kcm_akonadi_resources.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kcm/kcm_akonadi_resources.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,5 @@ [Desktop Entry] -Exec=kcmshell4 kcm_akonadi_resources +Exec=kcmshell5 kcm_akonadi_resources Icon=akonadi Type=Service ServiceTypes=KCModule @@ -11,99 +11,66 @@ X-KDE-ParentApp=kcontrol X-KDE-ParentComponents= X-KDE-CfgDlgHierarchy= -X-KDE-System-Settings-Parent-Category=personal-information +X-KDE-System-Settings-Parent-Category=connectivity +X-KDE-Weight=40 -Name=Akonadi Resources Configuration -Name[ar]=ضبط موارد اكوندا -Name[bs]=Konfiguracija Akonadi resursa -Name[ca]=Configuració de recursos de l'Akonadi -Name[ca@valencia]=Configuració de recursos de l'Akonadi -Name[cs]=Nastavení zdrojů Akonadi -Name[da]=Akonadi ressourcekonfiguration -Name[de]=Einrichtung der Akonadi-Ressourcen -Name[el]=Διαμόρφωση πόρων του Akonadi -Name[en_GB]=Akonadi Resources Configuration -Name[es]=Configuración de recursos de Akonadi -Name[et]=Akonadi ressursside seadistused -Name[fi]=Akonadi-resurssien asetukset -Name[fr]=Configuration des ressources Akonadi -Name[ga]=Cumraíocht Acmhainní Akonadi -Name[gl]=Configuración dos recursos do Akonadi -Name[hu]=Akonadi-erőforrások -Name[ia]=Configuration de ressources pro Akonadi -Name[it]=Configurazione risorse di Akonadi -Name[ja]=Akonadi リソースの設定 -Name[kk]=Akonadi ресурстарын баптау -Name[km]=ការ​កំណត់​រចនាសម្ព័ន្ធ​ធនធាន Akonadi -Name[ko]=Akonadi 자원 설정 -Name[lt]=Akonadi resursų konfigūravimas -Name[lv]=Akonadi resursu konfigurācija -Name[mr]=आकोनाडी संसाधन संयोजना -Name[nb]=Akonadi ressursoppsett -Name[nds]=Akonadi-Ressourceninstellen -Name[nl]=Akonadi hulpbronnenconfiguratie -Name[nn]=Akonadi ressursoppsett -Name[pa]=ਅਕੌਂਡੀ ਸਰੋਤ ਸੰਰਚਨਾ -Name[pl]=Ustawienia zasobów Akonadi -Name[pt]=Configuração dos Recursos do Akonadi -Name[pt_BR]=Configuração dos recursos do Akonadi -Name[ro]=Configurare resurse Akonadi -Name[ru]=Настройка источников Akonadi -Name[sk]=Nastavenie zdrojov Akonadi -Name[sl]=Nastavitve virov za Akonadi -Name[sr]=Подешавање ресурса Аконадија -Name[sr@ijekavian]=Подешавање ресурса Аконадија -Name[sr@ijekavianlatin]=Podešavanje resursa Akonadija -Name[sr@latin]=Podešavanje resursa Akonadija -Name[sv]=Akonadi-resursinställning -Name[tr]=Akonadi Kaynak Yapılandırması -Name[uk]=Налаштування ресурсів Akonadi -Name[x-test]=xxAkonadi Resources Configurationxx -Name[zh_CN]=Akonadi 资源配置 -Name[zh_TW]=Akonadi 資源設定 -Comment=Configuration of the Akonadi Personal Information Management framework -Comment[ar]=ضبط إطار إدارة المعلومات الشخصية اكوندا -Comment[bs]=Konfiguracija Akonadi frameworka za upravljanje licnim podacima -Comment[ca]=Configuració de l'entorn per a la gestió de la informació personal de l'Akonadi -Comment[ca@valencia]=Configuració de l'entorn per a la gestió de la informació personal de l'Akonadi -Comment[da]=Konfiguration af Akonadi - framework til håndtering af personlig information (PIM) -Comment[de]=Einrichtung des persönlichen Informationsmanagement von Akonadi -Comment[el]=Διαμόρφωση του διαχειριστή προσωπικών πληροφοριών Akonadi -Comment[en_GB]=Configuration of the Akonadi Personal Information Management framework -Comment[es]=Configuración de la infraestructura para administración de información personal Akonadi -Comment[et]=Akonadi personaalse teabe halduse (PIM) raamistiku seadistused -Comment[fi]=Akonadin PIM-kehyksen asetukset -Comment[fr]=Configuration du gestionnaire d'informations personnelles Akonadi -Comment[gl]=Configuración da infraestrutura do Xestor de Información Persoal Akonadi -Comment[hu]=Az Akonadi keretrendszer beállításai -Comment[ia]=Configuration de rete pro Administration de Informationes Personal de Akonadi -Comment[it]=Configurazione dell'infrastruttura Akonadi per la gestione delle informazioni personali -Comment[ja]=Akonadi PIM (個人情報管理) フレームワークの設定 -Comment[kk]=Akonadi дербес мәліметті басқару құрылымың басқару -Comment[km]=ការ​កំណត់​រចនាសម្ព័ន្ធ​គម្រោងការ​ការ​គ្រប់គ្រង​ព័ត៌មាន​ផ្ទាល់ខ្លួន Akonadi -Comment[ko]=Akonadi 개인 정보 관리 프레임워크 설정 -Comment[lt]=Akonadi asmeninės informacijos tvarkymo aplinkos konfigūravimas -Comment[lv]=Akonadi personīgās informācijas pārvaldības ietvara konfigurācija -Comment[mr]=आकोनाडी वैयक्तिक माहिती व्यवस्थापन रचनेची संयोजना -Comment[nb]=Oppsett av rammeverket for Akonadi personlig informasjonsbehandler -Comment[nds]=Den Pleger för persöönliche Informatschonen Akonadi instellen -Comment[nl]=Configuratie van het persoonlijke informatiebeheer raamwerk van Akonadi -Comment[nn]=Oppsett av Akonadi-rammeverket for handtering av personleg informasjon -Comment[pa]=ਅਕੌਂਡੀ ਨਿੱਜੀ ਜਾਣਕਾਰੀ ਪਰਬੰਧ ਫਰੇਮਵਰਕ ਦੀ ਸੰਰਚਨਾ -Comment[pl]=Ustawienia systemu do zarządzania informacjami osobistymi Akonadi -Comment[pt]=Configuração da plataforma de Gestão de Informação Pessoal do Akonadi -Comment[pt_BR]=Configuração da plataforma do gerenciador de informações pessoais do Akonadi -Comment[ro]=Configurarea platformei de gestiune a informațiilor personale Akonadi -Comment[ru]=Настройка инфраструктуры персональных данных Akonadi -Comment[sk]=Nastavenie frameworku správy osobných informácií Akonadi -Comment[sl]=Nastavitve ogrodja Akonadi za upravljanje z osebnimi podatki -Comment[sr]=Подешавање Аконади, радног оквира за управљање личним подацима -Comment[sr@ijekavian]=Подешавање Аконади, радног оквира за управљање личним подацима -Comment[sr@ijekavianlatin]=Podešavanje Akonadi, radnog okvira za upravljanje ličnim podacima -Comment[sr@latin]=Podešavanje Akonadi, radnog okvira za upravljanje ličnim podacima -Comment[sv]=Inställning av Akonadi: Ramverk för personlig informationshantering -Comment[tr]=Akonadi Kişisel Bilgi Yönetimi çalışma ortamının yapılandırması -Comment[uk]=Налаштування оболонки керування особистою інформацією Akonadi -Comment[x-test]=xxConfiguration of the Akonadi Personal Information Management frameworkxx -Comment[zh_CN]=Akonadi 个人信息管理框架配置 -Comment[zh_TW]=Akonadi 個人資訊管理者架構的設定 +Name=PIM Accounts and Resources +Name[ca]=Comptes i recursos del PIM +Name[de]=PIM-Zugänge und Ressourcen +Name[el]=Λογαριασμοί και πόροι PIM +Name[en_GB]=PIM Accounts and Resources +Name[es]=Cuentas y recursos PIM +Name[fi]=PIM-tilit ja resurssit +Name[fr]=Comptes et ressources PIM +Name[gl]=Contas e recursos PIM +Name[hu]=PIM fiókok és erőforrások +Name[it]=Account e risorse di PIM +Name[ko]=PIM 계정과 자원 +Name[nb]=PIM-kontoer og ressurser +Name[nds]=PIM-Kontos un -Ressourcen +Name[nl]=PIM-accounts en hulpbronnen +Name[pl]=Konta i zasoby ZIO +Name[pt]=Contas e Recursos de PIM +Name[pt_BR]=Contas e Recursos de PIM +Name[sk]=Účty a zdroje PIM +Name[sl]=Računi in viri PIM +Name[sr]=ПИМ налози и ресурси +Name[sr@ijekavian]=ПИМ налози и ресурси +Name[sr@ijekavianlatin]=PIM nalozi i resursi +Name[sr@latin]=PIM nalozi i resursi +Name[sv]=Konton och resurser för personlig informationshantering +Name[tr]=PIM Hesapları ve Kaynaklar +Name[uk]=Облікові записи та ресурси особистих даних +Name[x-test]=xxPIM Accounts and Resourcesxx +Name[zh_CN]=个人信息账户和资源 +Name[zh_TW]=個人資訊管理帳號與資源 +Comment=Personal Information Management Resources (Akonadi) +Comment[ca]=Recursos per a la gestió de la informació personal (Akonadi) +Comment[de]=Akonadi-Ressourcen für Persönliches Informationsmanagement +Comment[el]=Πόροι διαχειριστή προσωπικών πληροφοριών (Akonadi) +Comment[en_GB]=Personal Information Management Resources (Akonadi) +Comment[es]=Recursos de gestión de información personal (Akonadi) +Comment[fi]=Henkilökohtaisten tietojen hallinnan resurssit (Akonadi) +Comment[fr]=Gestion des ressources d'informations personnelles (Akonadi) +Comment[gl]=Recursos PIM (Akonadi) +Comment[hu]=Személyes információkezelő erőforrásai (Akonadi) +Comment[it]=Risorse della gestione informazioni personali (Akonadi) +Comment[ko]=개인 정보 관리 자원(Akonadi) +Comment[nb]=Ressurser for behandling av personlige opplysninger (Akonadi) +Comment[nds]=Persöönlich-Informatschonenpleeg-Ressourcen (Akonadi) +Comment[nl]=Hulpmiddelen voor de beheerder van persoonlijke informatie (Akonadi) +Comment[pl]=Zasoby zarządzania informacjami osobistymi (Akonadi) +Comment[pt]=Recursos de Gestão de Informações Pessoais (Akonadi) +Comment[pt_BR]=Recursos do Gerenciador de Informações Pessoais (Akonadi) +Comment[sk]=Zdroje správy osobných informácií (Akonadi) +Comment[sl]=Viri za upravljanje z osebnimi podatki (Akonadi) +Comment[sr]=Ресурси управљања личним подацима (Аконади) +Comment[sr@ijekavian]=Ресурси управљања личним подацима (Аконади) +Comment[sr@ijekavianlatin]=Resursi upravljanja ličnim podacima (Akonadi) +Comment[sr@latin]=Resursi upravljanja ličnim podacima (Akonadi) +Comment[sv]=Resurser för personlig informationshantering (Akonadi) +Comment[tr]=Kişisel Bilgi Yöneticisi Kaynakları (Akonadi) +Comment[uk]=Ресурси керування особистими даними (Akonadi) +Comment[x-test]=xxPersonal Information Management Resources (Akonadi)xx +Comment[zh_CN]=个人信息管理器资源 (Akonadi) +Comment[zh_TW]=個人資訊管理資源(Akonadi) diff -Nru kdepim-runtime-4.14.6/kcm/kcm_akonadi_server.desktop kdepim-runtime-15.08.0/kcm/kcm_akonadi_server.desktop --- kdepim-runtime-4.14.6/kcm/kcm_akonadi_server.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kcm/kcm_akonadi_server.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,5 @@ [Desktop Entry] -Exec=kcmshell4 kcm_akonadi_server +Exec=kcmshell5 kcm_akonadi_server Icon=akonadi Type=Service ServiceTypes=KCModule diff -Nru kdepim-runtime-4.14.6/kcm/resourcesmanagementwidget.cpp kdepim-runtime-15.08.0/kcm/resourcesmanagementwidget.cpp --- kdepim-runtime-4.14.6/kcm/resourcesmanagementwidget.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kcm/resourcesmanagementwidget.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,50 +24,50 @@ #include "resourcesmanagementwidget.h" #include "ui_resourcesmanagementwidget.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include -#include #include #include +#include class ResourcesManagementWidget::Private { public: Ui::ResourcesManagementWidget ui; - QHash menuOptions; + QHash menuOptions; QStringList wantedMimeTypes; }; -ResourcesManagementWidget::ResourcesManagementWidget( QWidget *parent, const QStringList &args ) : - QWidget( parent ), - d( new Private ) +ResourcesManagementWidget::ResourcesManagementWidget(QWidget *parent, const QStringList &args) : + QWidget(parent), + d(new Private) { d->wantedMimeTypes = args; - d->ui.setupUi( this ); + d->ui.setupUi(this); - d->ui.resourcesList->agentFilterProxyModel()->addCapabilityFilter( QLatin1String("Resource") ); - foreach ( const QString& type, d->wantedMimeTypes ) - d->ui.resourcesList->agentFilterProxyModel()->addMimeTypeFilter( type ); - connect( d->ui.resourcesList->view()->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), - SLOT(updateButtonState()) ); - connect( d->ui.resourcesList, SIGNAL(doubleClicked(Akonadi::AgentInstance)), - SLOT(editClicked()) ); - - connect( d->ui.addButton, SIGNAL(clicked()), SLOT(addClicked()) ); - connect( d->ui.editButton, SIGNAL(clicked()), SLOT(editClicked()) ); - connect( d->ui.removeButton, SIGNAL(clicked()), SLOT(removeClicked()) ); - - d->ui.mFilterAccount->setProxy( d->ui.resourcesList->agentFilterProxyModel() ); - d->ui.mFilterAccount->lineEdit()->setTrapReturnKey( true ); + d->ui.resourcesList->agentFilterProxyModel()->addCapabilityFilter(QStringLiteral("Resource")); + foreach (const QString &type, d->wantedMimeTypes) { + d->ui.resourcesList->agentFilterProxyModel()->addMimeTypeFilter(type); + } + connect(d->ui.resourcesList->view()->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), + SLOT(updateButtonState())); + connect(d->ui.resourcesList, &Akonadi::AgentInstanceWidget::doubleClicked, this, &ResourcesManagementWidget::editClicked); + + connect(d->ui.addButton, &QPushButton::clicked, this, &ResourcesManagementWidget::addClicked); + connect(d->ui.editButton, &QPushButton::clicked, this, &ResourcesManagementWidget::editClicked); + connect(d->ui.removeButton, &QPushButton::clicked, this, &ResourcesManagementWidget::removeClicked); + + d->ui.mFilterAccount->setProxy(d->ui.resourcesList->agentFilterProxyModel()); + //QT5 d->ui.mFilterAccount->lineEdit()->setTrapReturnKey( true ); updateButtonState(); - Akonadi::Control::widgetNeedsAkonadi( this ); + Akonadi::ControlGui::widgetNeedsAkonadi(this); } ResourcesManagementWidget::~ResourcesManagementWidget() @@ -77,29 +77,30 @@ void ResourcesManagementWidget::updateButtonState() { - const QList instanceList = d->ui.resourcesList->selectedAgentInstances(); - if ( instanceList.isEmpty() ) { - d->ui.editButton->setEnabled( false ); - d->ui.removeButton->setEnabled( false ); + const Akonadi::AgentInstance::List instanceList = d->ui.resourcesList->selectedAgentInstances(); + if (instanceList.isEmpty()) { + d->ui.editButton->setEnabled(false); + d->ui.removeButton->setEnabled(false); } else { const Akonadi::AgentInstance current = instanceList.first(); - d->ui.editButton->setEnabled( !current.type().capabilities().contains( QLatin1String( "NoConfig" ) ) ); - d->ui.removeButton->setEnabled( true ); + d->ui.editButton->setEnabled(!current.type().capabilities().contains(QStringLiteral("NoConfig"))); + d->ui.removeButton->setEnabled(true); } } void ResourcesManagementWidget::addClicked() { - Akonadi::AgentTypeDialog dlg( this ); - Akonadi::AgentFilterProxyModel* filter = dlg.agentFilterProxyModel(); - foreach ( const QString& type, d->wantedMimeTypes ) - filter->addMimeTypeFilter( type ); + Akonadi::AgentTypeDialog dlg(this); + Akonadi::AgentFilterProxyModel *filter = dlg.agentFilterProxyModel(); + foreach (const QString &type, d->wantedMimeTypes) { + filter->addMimeTypeFilter(type); + } - if ( dlg.exec() ) { + if (dlg.exec()) { const Akonadi::AgentType agentType = dlg.agentType(); - if ( agentType.isValid() ) { - Akonadi::AgentInstanceCreateJob *job = new Akonadi::AgentInstanceCreateJob( agentType, this ); - job->configure( this ); + if (agentType.isValid()) { + Akonadi::AgentInstanceCreateJob *job = new Akonadi::AgentInstanceCreateJob(agentType, this); + job->configure(this); job->start(); } } @@ -107,31 +108,32 @@ void ResourcesManagementWidget::editClicked() { - const QList instanceList = d->ui.resourcesList->selectedAgentInstances(); - if ( !instanceList.isEmpty() && instanceList.first().isValid() ) { + const Akonadi::AgentInstance::List instanceList = d->ui.resourcesList->selectedAgentInstances(); + if (!instanceList.isEmpty() && instanceList.first().isValid()) { KWindowSystem::allowExternalProcessWindowActivation(); Akonadi::AgentInstance instance = instanceList.first(); - instance.configure( this ); + instance.configure(this); } } void ResourcesManagementWidget::removeClicked() { - const QList instanceList = d->ui.resourcesList->selectedAgentInstances(); - if ( !instanceList.isEmpty() ) { - if ( KMessageBox::questionYesNo( this, - i18np( "Do you really want to delete the selected agent instance?", - "Do you really want to delete these %1 agent instances?", - instanceList.size() ), - i18n( "Multiple Agent Deletion" ), - KStandardGuiItem::del(), - KStandardGuiItem::cancel(), - QString(), - KMessageBox::Dangerous ) - == KMessageBox::Yes ) { - foreach ( const Akonadi::AgentInstance &agent, instanceList ) - Akonadi::AgentManager::self()->removeInstance( agent ); - updateButtonState(); + const Akonadi::AgentInstance::List instanceList = d->ui.resourcesList->selectedAgentInstances(); + if (!instanceList.isEmpty()) { + if (KMessageBox::questionYesNo(this, + i18np("Do you really want to delete the selected agent instance?", + "Do you really want to delete these %1 agent instances?", + instanceList.size()), + i18n("Multiple Agent Deletion"), + KStandardGuiItem::del(), + KStandardGuiItem::cancel(), + QString(), + KMessageBox::Dangerous) + == KMessageBox::Yes) { + foreach (const Akonadi::AgentInstance &agent, instanceList) { + Akonadi::AgentManager::self()->removeInstance(agent); + } + updateButtonState(); } } } diff -Nru kdepim-runtime-4.14.6/kcm/resourcesmanagementwidget.h kdepim-runtime-15.08.0/kcm/resourcesmanagementwidget.h --- kdepim-runtime-4.14.6/kcm/resourcesmanagementwidget.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kcm/resourcesmanagementwidget.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,11 +24,10 @@ #ifndef RESOURCES_MANAGEMENTWIDGET_H #define RESOURCES_MANAGEMENTWIDGET_H -#include +#include #include -#include - +#include /** @short A widget to manage imaplib @@ -45,8 +44,8 @@ @param filter The mimetypes which you want shown in the widget. Leave it empty to see them all. */ - explicit ResourcesManagementWidget( QWidget *parent = 0, - const QStringList &filter=QStringList() ); + explicit ResourcesManagementWidget(QWidget *parent = Q_NULLPTR, + const QStringList &filter = QStringList()); /** Destroys the widget. @@ -61,7 +60,7 @@ private: class Private; - Private * const d; + Private *const d; }; #endif diff -Nru kdepim-runtime-4.14.6/kcm/resourcesmanagementwidget.ui kdepim-runtime-15.08.0/kcm/resourcesmanagementwidget.ui --- kdepim-runtime-4.14.6/kcm/resourcesmanagementwidget.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kcm/resourcesmanagementwidget.ui 2015-08-10 21:01:02.000000000 +0000 @@ -28,7 +28,7 @@ - + Remove resource from your Akonadi server. @@ -43,7 +43,7 @@ - + Modify your installed resources @@ -58,7 +58,7 @@ - + Add resource to your Akonadi server. @@ -87,14 +87,9 @@
kfilterproxysearchline.h
- KPushButton - QPushButton -
kpushbutton.h
-
- Akonadi::AgentInstanceWidget QWidget -
akonadi/agentinstancewidget.h
+
AkonadiWidgets/agentinstancewidget.h
diff -Nru kdepim-runtime-4.14.6/kcm/serverconfigmodule.cpp kdepim-runtime-15.08.0/kcm/serverconfigmodule.cpp --- kdepim-runtime-4.14.6/kcm/serverconfigmodule.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kcm/serverconfigmodule.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,8 +19,7 @@ #include "serverconfigmodule.h" -#include -#include +#include #include #include @@ -28,214 +27,213 @@ #include #include -#include -#include +#include +#include #include +#include -K_PLUGIN_FACTORY( ServerConfigModuleFactory, registerPlugin(); ) -K_EXPORT_PLUGIN( ServerConfigModuleFactory( "kcm_akonadi_server" ) ) +K_PLUGIN_FACTORY(ServerConfigModuleFactory, registerPlugin();) using namespace Akonadi; -ServerConfigModule::ServerConfigModule( QWidget * parent, const QVariantList & args ) : - KCModule( ServerConfigModuleFactory::componentData(), parent, args ) +ServerConfigModule::ServerConfigModule(QWidget *parent, const QVariantList &args) : + KCModule(parent, args) { - KGlobal::locale()->insertCatalog( QLatin1String("kcm_akonadi") ); - KGlobal::locale()->insertCatalog( QLatin1String("libakonadi") ); + QVBoxLayout *layout = new QVBoxLayout(this); + setLayout(layout); - QVBoxLayout *layout = new QVBoxLayout( this ); - setLayout( layout ); + QWidget *storage_driver = new QWidget(this); + layout->addWidget(storage_driver); + ui_driver.setupUi(storage_driver); + + m_stackWidget = new QStackedWidget(this); + layout->addWidget(m_stackWidget); + + // supported drivers + ui_driver.driverBox->addItem(QLatin1String("Mysql"), QVariant(QLatin1String("QMYSQL"))); + ui_driver.driverBox->addItem(QLatin1String("PostgreSQL"), QVariant(QLatin1String("QPSQL"))); + ui_driver.driverBox->addItem(QLatin1String("SQLite"), QVariant(QLatin1String("QSQLITE3"))); + + setButtons(KCModule::Default | KCModule::Apply); + + // MySQL + m_mysqlWidget = new QWidget(this); + m_stackWidget->addWidget(m_mysqlWidget); + ui_mysql.setupUi(m_mysqlWidget); + + // PSQL + m_psqlWidget = new QWidget(this); + m_stackWidget->addWidget(m_psqlWidget); + ui_psql.setupUi(m_psqlWidget); + + // SQLite + m_sqliteWidget = new QWidget(this); + m_stackWidget->addWidget(m_sqliteWidget); + // ui_sqlite.setupUi( m_sqliteWidget ); + + m_stackWidget->setCurrentWidget(m_mysqlWidget); + + QWidget *widget = new QWidget(this); + layout->addWidget(widget); + ui.setupUi(widget); + + connect(ui_mysql.startServer, SIGNAL(toggled(bool)), SLOT(changed())); + connect(ui_mysql.serverPath, SIGNAL(textChanged(QString)), SLOT(changed())); + connect(ui_mysql.name, SIGNAL(textChanged(QString)), SLOT(changed())); + connect(ui_mysql.host, SIGNAL(textChanged(QString)), SLOT(changed())); + connect(ui_mysql.username, SIGNAL(textChanged(QString)), SLOT(changed())); + connect(ui_mysql.password, SIGNAL(textChanged(QString)), SLOT(changed())); + connect(ui_mysql.options, SIGNAL(textChanged(QString)), SLOT(changed())); + + connect(ui_psql.startServer, SIGNAL(toggled(bool)), SLOT(changed())); + connect(ui_psql.name, SIGNAL(textChanged(QString)), SLOT(changed())); + connect(ui_psql.host, SIGNAL(textChanged(QString)), SLOT(changed())); + connect(ui_psql.username, SIGNAL(textChanged(QString)), SLOT(changed())); + connect(ui_psql.password, SIGNAL(textChanged(QString)), SLOT(changed())); + connect(ui_psql.port, SIGNAL(textChanged(QString)), SLOT(changed())); + connect(ui_psql.startServer, SIGNAL(toggled(bool)), ui_psql.messagewidget, SLOT(setHidden(bool))); + + connect(ui.startStopButton, SIGNAL(clicked()), SLOT(startStopClicked())); + connect(ui.restartButton, SIGNAL(clicked()), SLOT(restartClicked())); + connect(ui.selfTestButton, SIGNAL(clicked()), SLOT(selfTestClicked())); - QWidget *storage_driver = new QWidget( this ); - layout->addWidget( storage_driver ); - ui_driver.setupUi( storage_driver ); - - m_stackWidget = new QStackedWidget( this ); - layout->addWidget( m_stackWidget ); - - // supported drivers - ui_driver.driverBox->addItem( QLatin1String("Mysql"), QVariant( QLatin1String("QMYSQL") ) ); - ui_driver.driverBox->addItem( QLatin1String("PostgreSQL"), QVariant( QLatin1String("QPSQL") ) ); - ui_driver.driverBox->addItem( QLatin1String("SQLite"), QVariant( QLatin1String("QSQLITE3") ) ); - - setButtons( KCModule::Default | KCModule::Apply ); - - // MySQL - m_mysqlWidget = new QWidget( this ); - m_stackWidget->addWidget( m_mysqlWidget ); - ui_mysql.setupUi( m_mysqlWidget ); - - // PSQL - m_psqlWidget = new QWidget( this ); - m_stackWidget->addWidget( m_psqlWidget ); - ui_psql.setupUi( m_psqlWidget ); - - // SQLite - m_sqliteWidget = new QWidget( this ); - m_stackWidget->addWidget( m_sqliteWidget ); - // ui_sqlite.setupUi( m_sqliteWidget ); - - m_stackWidget->setCurrentWidget( m_mysqlWidget ); - - QWidget *widget = new QWidget( this ); - layout->addWidget( widget ); - ui.setupUi( widget ); - - connect( ui_mysql.startServer, SIGNAL(toggled(bool)), SLOT(changed()) ); - connect( ui_mysql.serverPath, SIGNAL(textChanged(QString)), SLOT(changed()) ); - connect( ui_mysql.name, SIGNAL(textChanged(QString)), SLOT(changed()) ); - connect( ui_mysql.host, SIGNAL(textChanged(QString)), SLOT(changed()) ); - connect( ui_mysql.username, SIGNAL(textChanged(QString)), SLOT(changed()) ); - connect( ui_mysql.password, SIGNAL(textChanged(QString)), SLOT(changed()) ); - connect( ui_mysql.options, SIGNAL(textChanged(QString)), SLOT(changed()) ); - - connect( ui_psql.startServer, SIGNAL(toggled(bool)), SLOT(changed()) ); - connect( ui_psql.name, SIGNAL(textChanged(QString)), SLOT(changed()) ); - connect( ui_psql.host, SIGNAL(textChanged(QString)), SLOT(changed()) ); - connect( ui_psql.username, SIGNAL(textChanged(QString)), SLOT(changed()) ); - connect( ui_psql.password, SIGNAL(textChanged(QString)), SLOT(changed()) ); - connect( ui_psql.port, SIGNAL(textChanged(QString)), SLOT(changed()) ); - connect( ui_psql.startServer, SIGNAL(toggled(bool)), ui_psql.messagewidget, SLOT(setHidden(bool))); - - connect( ui.startStopButton, SIGNAL(clicked()), SLOT(startStopClicked()) ); - connect( ui.restartButton, SIGNAL(clicked()), SLOT(restartClicked()) ); - connect( ui.selfTestButton, SIGNAL(clicked()), SLOT(selfTestClicked()) ); + connect(ServerManager::self(), SIGNAL(started()), SLOT(updateStatus())); + connect(ServerManager::self(), SIGNAL(stopped()), SLOT(updateStatus())); - connect( ServerManager::self(), SIGNAL(started()), SLOT(updateStatus()) ); - connect( ServerManager::self(), SIGNAL(stopped()), SLOT(updateStatus()) ); - - connect( ui_driver.driverBox, SIGNAL(currentIndexChanged(int)), SLOT(driverChanged(int)) ); - connect( ui_driver.driverBox, SIGNAL(currentIndexChanged(int)), SLOT(changed()) ); + connect(ui_driver.driverBox, SIGNAL(currentIndexChanged(int)), SLOT(driverChanged(int))); + connect(ui_driver.driverBox, SIGNAL(currentIndexChanged(int)), SLOT(changed())); } void ServerConfigModule::load() { - const QString serverConfigFile = XdgBaseDirs::akonadiServerConfigFile( XdgBaseDirs::ReadWrite ); - QSettings settings( serverConfigFile, QSettings::IniFormat ); - settings.beginGroup( QLatin1String("QMYSQL") ); - ui_mysql.startServer->setChecked( settings.value( QLatin1String("StartServer"), true ).toBool() ); - ui_mysql.serverPath->setUrl( KUrl::fromPath( settings.value( QLatin1String("ServerPath"), QString() ).toString() ) ); - ui_mysql.name->setText( settings.value( QLatin1String("Name"), QLatin1String("akonadi") ).toString() ); - ui_mysql.host->setText( settings.value( QLatin1String("Host"), QString() ).toString() ); - ui_mysql.username->setText( settings.value( QLatin1String("User"), QString() ).toString() ); - ui_mysql.password->setText( settings.value( QLatin1String("Password"), QString() ).toString() ); - ui_mysql.options->setText( settings.value( QLatin1String("Options"), QString() ).toString() ); - settings.endGroup(); - - // postgresql group - settings.beginGroup( QLatin1String("QPSQL") ); - ui_psql.startServer->setChecked( settings.value( QLatin1String("StartServer"), true ).toBool() ); - ui_psql.name->setText( settings.value( QLatin1String("Name"), QLatin1String("akonadi") ).toString() ); - ui_psql.host->setText( settings.value( QLatin1String("Host"), QString() ).toString() ); - ui_psql.username->setText( settings.value( QLatin1String("User"), QString() ).toString() ); - ui_psql.password->setText( settings.value( QLatin1String("Password"), QString() ).toString() ); - ui_psql.port->setText( settings.value( QLatin1String("Port"), QLatin1String("5432") ).toString() ); - ui_psql.messagewidget->setVisible( !ui_psql.startServer->isChecked() ); - ui_psql.messagewidget->setCloseButtonVisible( false ); - ui_psql.messagewidget->setWordWrap( true ); - ui_psql.messagewidget->setMessageType( KMessageWidget::Information ); - ui_psql.messagewidget->setText( i18nc( "@info: special setting to configure", - "Make sure you have %1 in your server postgres.conf " - "file before starting Akonadi.", QLatin1String( "standard_conforming_strings = on" ) ) ); - settings.endGroup(); - - // selected driver - settings.beginGroup( QLatin1String("GENERAL") ); - ui_driver.driverBox->setCurrentIndex( ui_driver.driverBox->findData( settings.value ( QLatin1String("Driver"), QLatin1String("QMYSQL") ) ) ); - driverChanged( ui_driver.driverBox->currentIndex() ); - settings.endGroup(); + const QString serverConfigFile = XdgBaseDirs::akonadiServerConfigFile(XdgBaseDirs::ReadWrite); + QSettings settings(serverConfigFile, QSettings::IniFormat); + settings.beginGroup(QLatin1String("QMYSQL")); + ui_mysql.startServer->setChecked(settings.value(QLatin1String("StartServer"), true).toBool()); + ui_mysql.serverPath->setUrl(QUrl::fromLocalFile(settings.value(QLatin1String("ServerPath"), QString()).toString())); + ui_mysql.name->setText(settings.value(QLatin1String("Name"), QStringLiteral("akonadi")).toString()); + ui_mysql.host->setText(settings.value(QLatin1String("Host"), QString()).toString()); + ui_mysql.username->setText(settings.value(QLatin1String("User"), QString()).toString()); + ui_mysql.password->setText(settings.value(QLatin1String("Password"), QString()).toString()); + ui_mysql.options->setText(settings.value(QLatin1String("Options"), QString()).toString()); + settings.endGroup(); + + // postgresql group + settings.beginGroup(QLatin1String("QPSQL")); + ui_psql.startServer->setChecked(settings.value(QLatin1String("StartServer"), true).toBool()); + ui_psql.name->setText(settings.value(QLatin1String("Name"), QStringLiteral("akonadi")).toString()); + ui_psql.host->setText(settings.value(QLatin1String("Host"), QString()).toString()); + ui_psql.username->setText(settings.value(QLatin1String("User"), QString()).toString()); + ui_psql.password->setText(settings.value(QLatin1String("Password"), QString()).toString()); + ui_psql.port->setText(settings.value(QLatin1String("Port"), QStringLiteral("5432")).toString()); + ui_psql.messagewidget->setVisible(!ui_psql.startServer->isChecked()); + ui_psql.messagewidget->setCloseButtonVisible(false); + ui_psql.messagewidget->setWordWrap(true); + ui_psql.messagewidget->setMessageType(KMessageWidget::Information); + ui_psql.messagewidget->setText(i18nc("@info: special setting to configure", + "Make sure you have %1 in your server postgres.conf " + "file before starting Akonadi.", QStringLiteral("standard_conforming_strings = on"))); + settings.endGroup(); + + // selected driver + settings.beginGroup(QLatin1String("GENERAL")); + ui_driver.driverBox->setCurrentIndex(ui_driver.driverBox->findData(settings.value(QLatin1String("Driver"), QStringLiteral("QMYSQL")))); + driverChanged(ui_driver.driverBox->currentIndex()); + settings.endGroup(); - updateStatus(); + updateStatus(); } void ServerConfigModule::save() { - kDebug(); - const QString serverConfigFile = XdgBaseDirs::akonadiServerConfigFile( XdgBaseDirs::ReadWrite ); - QSettings settings( serverConfigFile, QSettings::IniFormat ); - settings.beginGroup( QLatin1String("QMYSQL") ); - settings.setValue( QLatin1String("StartServer"), ui_mysql.startServer->isChecked() ); - settings.setValue( QLatin1String("ServerPath"), ui_mysql.serverPath->url().toLocalFile() ); - settings.setValue( QLatin1String("Name"), ui_mysql.name->text() ); - settings.setValue( QLatin1String("Host"), ui_mysql.host->text() ); - settings.setValue( QLatin1String("User"), ui_mysql.username->text() ); - settings.setValue( QLatin1String("Password"), ui_mysql.password->text() ); - settings.setValue( QLatin1String("Options"), ui_mysql.options->text() ); - settings.endGroup(); - - // postgresql group - settings.beginGroup( QLatin1String("QPSQL") ); - settings.setValue( QLatin1String("StartServer"), ui_psql.startServer->isChecked() ); - settings.setValue( QLatin1String("Name"), ui_psql.name->text() ); - settings.setValue( QLatin1String("Host"), ui_psql.host->text() ); - settings.setValue( QLatin1String("User"), ui_psql.username->text() ); - settings.setValue( QLatin1String("Password"), ui_psql.password->text() ); - settings.setValue( QLatin1String("Port"), ui_psql.port->text() ); - settings.endGroup(); - - // sqlite group - settings.beginGroup( QLatin1String("SQLITE") ); - // TODO: make it configurable - settings.setValue( QLatin1String("Name"), QLatin1String("akonadi") ); - settings.endGroup(); - - // selected driver - settings.beginGroup( QLatin1String("GENERAL") ); - settings.setValue( QLatin1String("Driver"), ui_driver.driverBox->itemData( ui_driver.driverBox->currentIndex() ).toString() ); - settings.endGroup(); - settings.sync(); + qDebug(); + const QString serverConfigFile = XdgBaseDirs::akonadiServerConfigFile(XdgBaseDirs::ReadWrite); + QSettings settings(serverConfigFile, QSettings::IniFormat); + settings.beginGroup(QLatin1String("QMYSQL")); + settings.setValue(QLatin1String("StartServer"), ui_mysql.startServer->isChecked()); + settings.setValue(QLatin1String("ServerPath"), ui_mysql.serverPath->url().toLocalFile()); + settings.setValue(QLatin1String("Name"), ui_mysql.name->text()); + settings.setValue(QLatin1String("Host"), ui_mysql.host->text()); + settings.setValue(QLatin1String("User"), ui_mysql.username->text()); + settings.setValue(QLatin1String("Password"), ui_mysql.password->text()); + settings.setValue(QLatin1String("Options"), ui_mysql.options->text()); + settings.endGroup(); + + // postgresql group + settings.beginGroup(QLatin1String("QPSQL")); + settings.setValue(QLatin1String("StartServer"), ui_psql.startServer->isChecked()); + settings.setValue(QLatin1String("Name"), ui_psql.name->text()); + settings.setValue(QLatin1String("Host"), ui_psql.host->text()); + settings.setValue(QLatin1String("User"), ui_psql.username->text()); + settings.setValue(QLatin1String("Password"), ui_psql.password->text()); + settings.setValue(QLatin1String("Port"), ui_psql.port->text()); + settings.endGroup(); + + // sqlite group + settings.beginGroup(QLatin1String("SQLITE")); + // TODO: make it configurable + settings.setValue(QLatin1String("Name"), QStringLiteral("akonadi")); + settings.endGroup(); + + // selected driver + settings.beginGroup(QLatin1String("GENERAL")); + settings.setValue(QLatin1String("Driver"), ui_driver.driverBox->itemData(ui_driver.driverBox->currentIndex()).toString()); + settings.endGroup(); + settings.sync(); - // TODO: restart server if needed + // TODO: restart server if needed } void ServerConfigModule::defaults() { - ui_mysql.startServer->setChecked( true ); - // TODO: detect default server path - ui_mysql.name->setText( QLatin1String("akonadi") ); + ui_mysql.startServer->setChecked(true); + // TODO: detect default server path + ui_mysql.name->setText(QLatin1String("akonadi")); - ui_driver.driverBox->setCurrentIndex( ui_driver.driverBox->findData( QLatin1String("QMYSQL") ) ); + ui_driver.driverBox->setCurrentIndex(ui_driver.driverBox->findData(QLatin1String("QMYSQL"))); } void ServerConfigModule::updateStatus() { - if ( ServerManager::isRunning() ) { - ui.statusLabel->setText( i18n( "The Akonadi server is running." ) ); - ui.startStopButton->setText( i18n( "Stop" ) ); - ui.restartButton->setEnabled( true ); - } else { - ui.statusLabel->setText( i18n( "The Akonadi server is not running." ) ); - ui.startStopButton->setText( i18n( "Start" ) ); - ui.restartButton->setEnabled( false ); - } + if (ServerManager::isRunning()) { + ui.statusLabel->setText(i18n("The Akonadi server is running.")); + ui.startStopButton->setText(i18n("Stop")); + ui.restartButton->setEnabled(true); + } else { + ui.statusLabel->setText(i18n("The Akonadi server is not running.")); + ui.startStopButton->setText(i18n("Start")); + ui.restartButton->setEnabled(false); + } } void ServerConfigModule::startStopClicked() { - if ( ServerManager::isRunning() ) - Control::stop( this ); - else - Control::start( this ); + if (ServerManager::isRunning()) { + ControlGui::stop(this); + } else { + ControlGui::start(this); + } } void ServerConfigModule::restartClicked() { - Control::restart( this ); + ControlGui::restart(this); } void ServerConfigModule::selfTestClicked() { - ServerManager::showSelfTestDialog( this ); + ServerManager::showSelfTestDialog(this); } -void ServerConfigModule::driverChanged( int index ) +void ServerConfigModule::driverChanged(int index) { - if ( ui_driver.driverBox->itemData( index ).toString() == QLatin1String("QMYSQL") ) { - m_stackWidget->setCurrentWidget( m_mysqlWidget ); - } else if ( ui_driver.driverBox->itemData( index ).toString() == QLatin1String("QPSQL") ) { - m_stackWidget->setCurrentWidget( m_psqlWidget ); - } else { - m_stackWidget->setCurrentWidget( m_sqliteWidget ); - } + if (ui_driver.driverBox->itemData(index).toString() == QLatin1String("QMYSQL")) { + m_stackWidget->setCurrentWidget(m_mysqlWidget); + } else if (ui_driver.driverBox->itemData(index).toString() == QLatin1String("QPSQL")) { + m_stackWidget->setCurrentWidget(m_psqlWidget); + } else { + m_stackWidget->setCurrentWidget(m_sqliteWidget); + } } +#include "serverconfigmodule.moc" diff -Nru kdepim-runtime-4.14.6/kcm/serverconfigmodule.h kdepim-runtime-15.08.0/kcm/serverconfigmodule.h --- kdepim-runtime-4.14.6/kcm/serverconfigmodule.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kcm/serverconfigmodule.h 2015-08-10 21:01:02.000000000 +0000 @@ -32,22 +32,22 @@ class ServerConfigModule : public KCModule { - Q_OBJECT - public: - explicit ServerConfigModule( QWidget * parent, const QVariantList & args ); + Q_OBJECT +public: + explicit ServerConfigModule(QWidget *parent, const QVariantList &args); void load(); void save(); void defaults(); - private slots: +private Q_SLOTS: void updateStatus(); void startStopClicked(); void restartClicked(); void selfTestClicked(); void driverChanged(int); - private: +private: Ui::ServerConfigModule ui; Ui::StorageDriver ui_driver; Ui::MySQLStoragePage ui_mysql; diff -Nru kdepim-runtime-4.14.6/kcm/serverconfigmodule.ui kdepim-runtime-15.08.0/kcm/serverconfigmodule.ui --- kdepim-runtime-4.14.6/kcm/serverconfigmodule.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kcm/serverconfigmodule.ui 2015-08-10 21:01:02.000000000 +0000 @@ -35,7 +35,7 @@
- + Test your MySQL settings for Akonadi. @@ -58,7 +58,7 @@ - + Stop Akonadi @@ -68,7 +68,7 @@ - + Restart Akonadi @@ -82,13 +82,6 @@ - - - KPushButton - QPushButton -
kpushbutton.h
-
-
diff -Nru kdepim-runtime-4.14.6/kdepim-runtime.categories kdepim-runtime-15.08.0/kdepim-runtime.categories --- kdepim-runtime-4.14.6/kdepim-runtime.categories 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/kdepim-runtime.categories 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,18 @@ +log_maildispatcher maildispacher agent (kdepim-runtime) +log_newmailnotifier mailnotifier agent (kdepim-runtime) +log_akonadislave kioslave (akonadi) +log_maildirresource maildir resource (kdepim-runtime) +log_libmaildir libmaildir (kdepim-runtime) +log_imapresource imap resource (kdepim-runtime) +log_mboxresource mbox resource (kdepim-runtime) +log_birthdays birthdays resource (kdepim-runtime) +log_davresource dav resource (kdepim-runtime) +log_kolabresource kolab resource (kdepim-runtime) +log_mixedmaildirresource mixedmaildir resource (kdepim-runtime) +log_mixedmaildir mixed maildir resource (kdepim-runtime) +log_kalarmresource kalarm file resource (kdepim-runtime) +log_kalarmdirresource kalarm directory resource (kdepim-runtime) +log_pop3resource pop3 resource (kdepim-runtime) +log_akonadi_serializer_kalarm akonadi serializer plugins (kdepim-runtime) +log_akonadi_serializer_mail akonadi mail plugins (kdepim-runtime) +log_resources_contacts contacts resource (kdepim-runtime) diff -Nru kdepim-runtime-4.14.6/kioslave/akonadi.protocol kdepim-runtime-15.08.0/kioslave/akonadi.protocol --- kdepim-runtime-4.14.6/kioslave/akonadi.protocol 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kioslave/akonadi.protocol 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,5 @@ [Protocol] -exec=kio_akonadi +exec=kf5/kio/akonadi protocol=akonadi input=none output=filesystem diff -Nru kdepim-runtime-4.14.6/kioslave/akonadislave.cpp kdepim-runtime-15.08.0/kioslave/akonadislave.cpp --- kdepim-runtime-4.14.6/kioslave/akonadislave.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kioslave/akonadislave.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,215 +19,226 @@ #include "akonadislave.h" -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -extern "C" { int KDE_EXPORT kdemain(int argc, char **argv); } - -int kdemain(int argc, char **argv) { - - KCmdLineArgs::init( argc, argv, "kio_akonadi", 0, KLocalizedString(), 0 ); - - KCmdLineOptions options; - options.add( "+protocol", ki18n( "Protocol name" ) ); - options.add( "+pool", ki18n( "Socket name" ) ); - options.add( "+app", ki18n( "Socket name" ) ); - KCmdLineArgs::addCmdLineOptions( options ); - KApplication app( false ); - - KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - AkonadiSlave slave( args->arg( 1 ).toLocal8Bit(), args->arg( 2 ).toLocal8Bit() ); - slave.dispatchLoop(); +#include +#include +#include +#include +#include +#include +#include + +#include "akonadislave_debug.h" + +#include +#include +#include +#include +#include + +extern "C" { + int Q_DECL_EXPORT kdemain(int argc, char **argv); +} + +int kdemain(int argc, char **argv) +{ + QApplication app(argc, argv); + KAboutData aboutData(QStringLiteral("kio_akonadi"), QString(), QStringLiteral("0")); + QCommandLineParser parser; + KAboutData::setApplicationData(aboutData); + parser.addVersionOption(); + parser.addHelpOption(); + parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("+protocol"), i18n("Protocol name"))); + parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("+pool"), i18n("Socket name"))); + parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("+app"), i18n("Socket name"))); + + aboutData.setupCommandLine(&parser); + parser.process(app); + aboutData.processCommandLine(&parser); - return 0; + AkonadiSlave slave(parser.positionalArguments().at(1).toLocal8Bit(), parser.positionalArguments().at(2).toLocal8Bit()); + slave.dispatchLoop(); + + return 0; } using namespace Akonadi; -AkonadiSlave::AkonadiSlave(const QByteArray & pool_socket, const QByteArray & app_socket) : - KIO::SlaveBase( "akonadi", pool_socket, app_socket ) +AkonadiSlave::AkonadiSlave(const QByteArray &pool_socket, const QByteArray &app_socket) : + KIO::SlaveBase("akonadi", pool_socket, app_socket) { - kDebug( 7129 ) << "kio_akonadi starting up"; + qCDebug(AKONADISLAVE_LOG) << "kio_akonadi starting up"; } AkonadiSlave::~ AkonadiSlave() { - kDebug( 7129 ) << "kio_akonadi shutting down"; + qCDebug(AKONADISLAVE_LOG) << "kio_akonadi shutting down"; } -void AkonadiSlave::get(const KUrl & url) +void AkonadiSlave::get(const QUrl &url) { - const Item item = Item::fromUrl( url ); - ItemFetchJob *job = new ItemFetchJob( item ); - job->fetchScope().fetchFullPayload(); - - if ( !job->exec() ) { - error( KIO::ERR_INTERNAL, job->errorString() ); - return; - } - - if ( job->items().count() != 1 ) { - error( KIO::ERR_DOES_NOT_EXIST, i18n( "No such item." ) ); - } else { - const Item item = job->items().first(); - QByteArray tmp = item.payloadData(); - data( tmp ); - data( QByteArray() ); - finished(); - } + const Item item = Item::fromUrl(url); + ItemFetchJob *job = new ItemFetchJob(item); + job->fetchScope().fetchFullPayload(); + + if (!job->exec()) { + error(KIO::ERR_INTERNAL, job->errorString()); + return; + } - finished(); + if (job->items().count() != 1) { + error(KIO::ERR_DOES_NOT_EXIST, i18n("No such item.")); + } else { + const Item item = job->items().at(0); + QByteArray tmp = item.payloadData(); + data(tmp); + data(QByteArray()); + finished(); + } + + finished(); } -void AkonadiSlave::stat(const KUrl & url) +void AkonadiSlave::stat(const QUrl &url) { - kDebug( 7129 ) << url; + qCDebug(AKONADISLAVE_LOG) << url; - // Stats for a collection - if ( Collection::fromUrl( url ).isValid() ) { - Collection collection = Collection::fromUrl( url ); + // Stats for a collection + if (Collection::fromUrl(url).isValid()) { + Collection collection = Collection::fromUrl(url); + + if (collection != Collection::root()) { + // Check that the collection exists. + CollectionFetchJob *job = new CollectionFetchJob(collection, CollectionFetchJob::Base); + if (!job->exec()) { + error(KIO::ERR_INTERNAL, job->errorString()); + return; + } + + if (job->collections().count() != 1) { + error(KIO::ERR_DOES_NOT_EXIST, i18n("No such item.")); + return; + } - if ( collection != Collection::root() ) { - // Check that the collection exists. - CollectionFetchJob *job = new CollectionFetchJob( collection, CollectionFetchJob::Base ); - if ( !job->exec() ) { - error( KIO::ERR_INTERNAL, job->errorString() ); - return; + collection = job->collections().at(0); } - if ( job->collections().count() != 1 ) { - error( KIO::ERR_DOES_NOT_EXIST, i18n( "No such item." ) ); - return; + statEntry(entryForCollection(collection)); + finished(); + } + // Stats for an item + else if (Item::fromUrl(url).isValid()) { + ItemFetchJob *job = new ItemFetchJob(Item::fromUrl(url)); + + if (!job->exec()) { + error(KIO::ERR_INTERNAL, job->errorString()); + return; } - collection = job->collections().first(); - } - - statEntry( entryForCollection( collection ) ); - finished(); - } - // Stats for an item - else if ( Item::fromUrl( url ).isValid() ) { - ItemFetchJob *job = new ItemFetchJob( Item::fromUrl( url ) ); + if (job->items().count() != 1) { + error(KIO::ERR_DOES_NOT_EXIST, i18n("No such item.")); + return; + } - if ( !job->exec() ) { - error( KIO::ERR_INTERNAL, job->errorString() ); - return; + const Item item = job->items().at(0); + statEntry(entryForItem(item)); + finished(); } +} - if ( job->items().count() != 1 ) { - error( KIO::ERR_DOES_NOT_EXIST, i18n( "No such item." ) ); - return; - } +void AkonadiSlave::del(const QUrl &url, bool isFile) +{ + qCDebug(AKONADISLAVE_LOG) << url; - const Item item = job->items().first(); - statEntry( entryForItem( item ) ); - finished(); - } + if (!isFile) { // It's a directory + Collection collection = Collection::fromUrl(url); + CollectionDeleteJob *job = new CollectionDeleteJob(collection); + if (!job->exec()) { + error(KIO::ERR_INTERNAL, job->errorString()); + return; + } + finished(); + } else { // It's a file + ItemDeleteJob *job = new ItemDeleteJob(Item::fromUrl(url)); + if (!job->exec()) { + error(KIO::ERR_INTERNAL, job->errorString()); + return; + } + finished(); + } } -void AkonadiSlave::del( const KUrl &url, bool isFile ) +void AkonadiSlave::listDir(const QUrl &url) { - kDebug( 7129 ) << url; + qCDebug(AKONADISLAVE_LOG) << url; - if ( !isFile ) { // It's a directory - Collection collection = Collection::fromUrl( url ); - CollectionDeleteJob *job = new CollectionDeleteJob( collection ); - if ( !job->exec() ) { - error( KIO::ERR_INTERNAL, job->errorString() ); - return; + if (!Collection::fromUrl(url).isValid()) { + error(KIO::ERR_DOES_NOT_EXIST, i18n("No such collection.")); + return; } - finished(); - } else { // It's a file - ItemDeleteJob* job = new ItemDeleteJob( Item::fromUrl( url ) ); - if ( !job->exec() ) { - error( KIO::ERR_INTERNAL, job->errorString() ); - return; + + // Fetching collections + Collection collection = Collection::fromUrl(url); + if (!collection.isValid()) { + error(KIO::ERR_DOES_NOT_EXIST, i18n("No such collection.")); + return; + } + CollectionFetchJob *job = new CollectionFetchJob(collection, CollectionFetchJob::FirstLevel); + if (!job->exec()) { + error(KIO::ERR_CANNOT_ENTER_DIRECTORY, job->errorString()); + return; } + + Collection::List collections = job->collections(); + foreach (const Collection &col, collections) { + listEntry(entryForCollection(col), false); + } + + // Fetching items + if (collection != Collection::root()) { + ItemFetchJob *fjob = new ItemFetchJob(collection); + if (!fjob->exec()) { + error(KIO::ERR_INTERNAL, job->errorString()); + return; + } + Item::List items = fjob->items(); + totalSize(collections.count() + items.count()); + foreach (const Item &item, items) { + listEntry(entryForItem(item), false); + } + } + + listEntry(KIO::UDSEntry(), true); finished(); - } } -void AkonadiSlave::listDir( const KUrl &url ) +KIO::UDSEntry AkonadiSlave::entryForItem(const Akonadi::Item &item) { - kDebug( 7129 ) << url; - - if ( !Collection::fromUrl( url ).isValid() ) { - error( KIO::ERR_DOES_NOT_EXIST, i18n( "No such collection." ) ); - return; - } - - // Fetching collections - Collection collection = Collection::fromUrl( url ); - if ( !collection.isValid() ) { - error( KIO::ERR_DOES_NOT_EXIST, i18n( "No such collection." ) ); - return; - } - CollectionFetchJob *job = new CollectionFetchJob( collection, CollectionFetchJob::FirstLevel ); - if ( !job->exec() ) { - error( KIO::ERR_CANNOT_ENTER_DIRECTORY, job->errorString() ); - return; - } - - Collection::List collections = job->collections(); - foreach ( const Collection &col, collections ) - listEntry( entryForCollection( col ), false ); - - // Fetching items - if ( collection != Collection::root() ) { - ItemFetchJob* fjob = new ItemFetchJob( collection ); - if ( !fjob->exec() ) { - error( KIO::ERR_INTERNAL, job->errorString() ); - return; - } - Item::List items = fjob->items(); - totalSize( collections.count() + items.count() ); - foreach ( const Item &item, items ) - listEntry( entryForItem( item ), false ); - } - - listEntry( KIO::UDSEntry(), true ); - finished(); -} - -KIO::UDSEntry AkonadiSlave::entryForItem(const Akonadi::Item& item) -{ - KIO::UDSEntry entry; - entry.insert( KIO::UDSEntry::UDS_NAME, QString::number( item.id() ) ); - entry.insert( KIO::UDSEntry::UDS_MIME_TYPE, item.mimeType() ); - entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG ); - entry.insert( KIO::UDSEntry::UDS_URL, item.url().url() ); - entry.insert( KIO::UDSEntry::UDS_SIZE, item.size() ); - entry.insert( KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH ); - entry.insert( KIO::UDSEntry::UDS_MODIFICATION_TIME, item.modificationTime().toTime_t() ); - return entry; -} - -KIO::UDSEntry AkonadiSlave::entryForCollection(const Akonadi::Collection& collection) -{ - KIO::UDSEntry entry; - entry.insert( KIO::UDSEntry::UDS_NAME, collection.name() ); - entry.insert( KIO::UDSEntry::UDS_MIME_TYPE, Collection::mimeType() ); - entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR ); - entry.insert( KIO::UDSEntry::UDS_URL, collection.url().url() ); - entry.insert( KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH ); - if ( EntityDisplayAttribute *attr = collection.attribute() ) { - if ( !attr->iconName().isEmpty() ) - entry.insert( KIO::UDSEntry::UDS_ICON_NAME, attr->iconName() ); - if ( !attr->displayName().isEmpty() ) - entry.insert( KIO::UDSEntry::UDS_DISPLAY_NAME, attr->displayName() ); - } - return entry; + KIO::UDSEntry entry; + entry.insert(KIO::UDSEntry::UDS_NAME, QString::number(item.id())); + entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, item.mimeType()); + entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG); + entry.insert(KIO::UDSEntry::UDS_URL, item.url().url()); + entry.insert(KIO::UDSEntry::UDS_SIZE, item.size()); + entry.insert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH); + entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, item.modificationTime().toTime_t()); + return entry; +} + +KIO::UDSEntry AkonadiSlave::entryForCollection(const Akonadi::Collection &collection) +{ + KIO::UDSEntry entry; + entry.insert(KIO::UDSEntry::UDS_NAME, collection.name()); + entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, Collection::mimeType()); + entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); + entry.insert(KIO::UDSEntry::UDS_URL, collection.url().url()); + entry.insert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH); + if (EntityDisplayAttribute *attr = collection.attribute()) { + if (!attr->iconName().isEmpty()) { + entry.insert(KIO::UDSEntry::UDS_ICON_NAME, attr->iconName()); + } + if (!attr->displayName().isEmpty()) { + entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, attr->displayName()); + } + } + return entry; } diff -Nru kdepim-runtime-4.14.6/kioslave/akonadislave_debug.cpp kdepim-runtime-15.08.0/kioslave/akonadislave_debug.cpp --- kdepim-runtime-4.14.6/kioslave/akonadislave_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/kioslave/akonadislave_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 "akonadislave_debug.h" +Q_LOGGING_CATEGORY(AKONADISLAVE_LOG, "log_akonadislave") + diff -Nru kdepim-runtime-4.14.6/kioslave/akonadislave_debug.h kdepim-runtime-15.08.0/kioslave/akonadislave_debug.h --- kdepim-runtime-4.14.6/kioslave/akonadislave_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/kioslave/akonadislave_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 AKONADISLAVE_DEBUG_H +#define AKONADISLAVE_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(AKONADISLAVE_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/kioslave/akonadislave.h kdepim-runtime-15.08.0/kioslave/akonadislave.h --- kdepim-runtime-4.14.6/kioslave/akonadislave.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kioslave/akonadislave.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,40 +22,41 @@ #include -namespace Akonadi { +namespace Akonadi +{ class Item; class Collection; } class AkonadiSlave : public KIO::SlaveBase { - public: - AkonadiSlave( const QByteArray &pool_socket, const QByteArray &app_socket ); +public: + AkonadiSlave(const QByteArray &pool_socket, const QByteArray &app_socket); virtual ~AkonadiSlave(); /** * Reimplemented from SlaveBase */ - virtual void get( const KUrl &url ); + void get(const QUrl &url) Q_DECL_OVERRIDE; /** * Reimplemented from SlaveBase */ - virtual void stat( const KUrl &url ); + void stat(const QUrl &url) Q_DECL_OVERRIDE; /** * Reimplemented from SlaveBase */ - virtual void listDir( const KUrl &url ); + void listDir(const QUrl &url) Q_DECL_OVERRIDE; /** * Reimplemented from SlaveBase */ - virtual void del( const KUrl &url, bool isFile ); + void del(const QUrl &url, bool isFile) Q_DECL_OVERRIDE; - private: - static KIO::UDSEntry entryForItem( const Akonadi::Item &item ); - static KIO::UDSEntry entryForCollection( const Akonadi::Collection &collection ); +private: + static KIO::UDSEntry entryForItem(const Akonadi::Item &item); + static KIO::UDSEntry entryForCollection(const Akonadi::Collection &collection); }; #endif diff -Nru kdepim-runtime-4.14.6/kioslave/CMakeLists.txt kdepim-runtime-15.08.0/kioslave/CMakeLists.txt --- kdepim-runtime-4.14.6/kioslave/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kioslave/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,21 +1,52 @@ -include_directories( ${kdepim-runtime_SOURCE_DIR} ) +project(kioslave) +cmake_minimum_required(VERSION 2.8.12) -add_definitions( -DQT_NO_CAST_FROM_ASCII ) -add_definitions( -DQT_NO_CAST_TO_ASCII ) +if ("${CMAKE_SOURCE_DIR}" STREQUAL "${kioslave_SOURCE_DIR}") -set(kio_akonadi_srcs akonadislave.cpp ) +find_package(ECM 5.9.0 CONFIG REQUIRED) + set(CMAKE_MODULE_PATH ${resources_SOURCE_DIR}/cmake ${ECM_MODULE_PATH}) + include(ECMPackageConfigHelpers) + include(ECMSetupVersion) + include(FeatureSummary) + include(KDEInstallDirs) + include(KDECMakeSettings) + include(KDEFrameworkCompilerSettings) -kde4_add_plugin(kio_akonadi ${kio_akonadi_srcs}) + set(KDEPIMLIBS_LIB_VERSION "4.75.0") + set(KF5_VERSION "5.9.0") + set(QT_REQUIRED_VERSION "5.4.0") + find_package(KF5KIO ${KF5_VERSION} CONFIG REQUIRED) + find_package(KF5Akonadi ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) +endif() -target_link_libraries(kio_akonadi ${KDE4_KIO_LIBS} ${KDEPIMLIBS_AKONADI_LIBS} ) +set(kio_akonadi_SRCS akonadislave.cpp akonadislave_debug.cpp) -install(TARGETS kio_akonadi DESTINATION ${PLUGIN_INSTALL_DIR} ) + +add_library(kio_akonadi MODULE ${kio_akonadi_SRCS}) + + + +target_link_libraries(kio_akonadi + KF5::KIOCore + KF5::AkonadiCore + KF5::I18n + Qt5::DBus + Qt5::Widgets + ) +set_target_properties(kio_akonadi PROPERTIES OUTPUT_NAME "akonadi") + +install(TARGETS kio_akonadi DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf5/kio ) ########### install files ############### -install( FILES akonadi.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) +install( FILES akonadi.protocol DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) + +if ("${CMAKE_SOURCE_DIR}" STREQUAL "${kioslave_SOURCE_DIR}") + feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) +endif() + diff -Nru kdepim-runtime-4.14.6/kresources/CMakeLists.txt kdepim-runtime-15.08.0/kresources/CMakeLists.txt --- kdepim-runtime-4.14.6/kresources/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) -include_directories (${kdepim-runtime_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${KDE4_INCLUDES} ${QT_QTDBUS_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/shared) - -add_definitions( - -DKRESOURCES_DEPRECATED= - -DKABC_DEPRECATED= - -DKCAL_DEPRECATED= -) -# This one won't be needed when CMake 2.8.13 is depended on. -add_definitions( - -DKRESOURCES_DEPRECATED_EXPORT=KRESOURCES_EXPORT - -DKABC_DEPRECATED_EXPORT=KABC_EXPORT - -DKCAL_DEPRECATED_EXPORT=KCAL_EXPORT -) - -# include (ConfigureChecks.cmake) -# configure_file (config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) - -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - -set( RESOURCE_AKONADI_SHARED_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/shared/abstractsubresourcemodel.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/shared/concurrentjobs.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/shared/idarbiterbase.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/shared/itemfetchadapter.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/shared/itemsavejob.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/shared/resourceconfigbase.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/shared/resourceprivatebase.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/shared/storecollectiondialog.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/shared/storecollectionfilterproxymodel.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/shared/storecollectionmodel.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/shared/subresourcebase.cpp -) - -add_subdirectory(kabc) -add_subdirectory(kcal) diff -Nru kdepim-runtime-4.14.6/kresources/kabc/akonadi.desktop kdepim-runtime-15.08.0/kresources/kabc/akonadi.desktop --- kdepim-runtime-4.14.6/kresources/kabc/akonadi.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kabc/akonadi.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -[Desktop Entry] -Name=Akonadi Address Books -Name[ar]=دفتر عناوين اكوندا -Name[bg]=Адресници Akonadi -Name[bs]=Akonadi adresar -Name[ca]=Llibreta d'adreces de l'Akonadi -Name[ca@valencia]=Llibreta d'adreces de l'Akonadi -Name[cs]=Kniha adres Akonadi -Name[da]=Akonadi-adressebøger -Name[de]=Akonadi-Adressbücher -Name[el]=Βιβλία διευθύνσεων του Akonadi -Name[en_GB]=Akonadi Address Books -Name[es]=Libreta de direcciones Akonadi -Name[et]=Akonadi aadressiraamatud -Name[fi]=Akonadin osoitekirjat -Name[fr]=Carnet d'adresses Akonadi -Name[ga]=Leabhair Sheoltaí Akonadi -Name[gl]=Cadernos de enderezos do Akonadi -Name[hu]=Akonadi-címjegyzékek -Name[ia]=Adressarios de Akonadi -Name[it]=Rubrica indirizzi di Akonadi -Name[ja]=Akonadi アドレス帳 -Name[kk]=Akonadi адрестік кітапшасы -Name[km]=សៀវភៅ​អាសយដ្ឋាន Akonadi -Name[ko]=Akonadi 주소록 -Name[lt]=Akonadi adresų knygelės -Name[lv]=Akonadi adrešu grāmatas -Name[nb]=Akonadi adressebøker -Name[nds]=Akonadi-Adressbook instellen -Name[nl]=Adresboek van Akonadi -Name[nn]=Akonadi-adressebøker -Name[pa]=ਅਕੌਂਡੀ ਐਡਰੈੱਸ ਬੁੱਕ -Name[pl]=Książki adresowe Akonadi -Name[pt]=Livros de Endereços do Akonadi -Name[pt_BR]=Livro de endereços do Akonadi -Name[ro]=Cărți de adrese Akonadi -Name[ru]=Адресные книги Akonadi -Name[sk]=Adresár Akonadi -Name[sl]=Akonadijevi imeniki -Name[sr]=Адресари Аконадија -Name[sr@ijekavian]=Адресари Аконадија -Name[sr@ijekavianlatin]=Adresari Akonadija -Name[sr@latin]=Adresari Akonadija -Name[sv]=Akonadi adressböcker -Name[tr]=Akonadi Adres Defterleri -Name[uk]=Адресні книги Akonadi -Name[x-test]=xxAkonadi Address Booksxx -Name[zh_CN]=Akonadi 地址簿 -Name[zh_TW]=Akonadi 通訊錄 -Comment=Provides access to contacts stored in Akonadi address book folders -Comment[ar]=يوفر الدخول لجهات الإتصال المحفوظة في مجلد دفتر عناوين اكوندا -Comment[bs]=Omogućuje pristup kontaktima pohranjenim u Akonadi imenicima -Comment[ca]=Proporciona accés als contactes emmagatzemats a les carpetes de la llibreta d'adreces de l'Akonadi -Comment[ca@valencia]=Proporciona l'accés als contactes emmagatzemats en carpetes de la llibreta d'adreces de l'Akonadi -Comment[da]=Giver adgang til kontakter lagret i Akonadi adressebogs-mapper -Comment[de]=Ermöglicht den Zugriff auf Kontakte, die in Akonadi-Adressbuchordnern gespeichert sind. -Comment[el]=Παρέχει πρόσβαση σε επαφές αποθηκευμένες σε φακέλους βιβλίων διευθύνσεων του Akonadi -Comment[en_GB]=Provides access to contacts stored in Akonadi address book folders -Comment[es]=Proporciona acceso a los contactos almacenados en carpetas de la libreta de direcciones de Akonadi -Comment[et]=Võimaldab kasutada Akonadi aadressiraamatukaustadesse salvestatud kontakte -Comment[fi]=Tarjoaa pääsyn Akonadin osoitekirjakansioihin tallennettuihin yhteystietoihin -Comment[fr]=Fournit l'accès aux contacts enregistrés dans les dossiers du carnet d'adresses Akonadi -Comment[gl]=Fornece acceso aos contactos almacenados nos cartafoles de caderno de enderezos do Akonadi -Comment[hu]=Hozzáférést biztosít Akonadi-címjegyzékekben tárolt névjegyekhez -Comment[ia]=Provide accesso a contactos salveguardate in dossiers de adressarios de Akonadi -Comment[it]=Consente l'accesso ai contatti memorizzati in cartelle di tipo rubrica di Akonadi -Comment[ja]=Akonadi のアドレス帳フォルダに保存されている連絡先へのアクセスを提供します -Comment[kk]=Akonadi адрестік кітапшасының қапшығындағы контакттарға қатынау -Comment[km]=ចូល​ដំណើរការ​ទៅ​កាន់​ទំនាក់ទំនង​ដែល​បាន​ទុក​នៅ​ក្នុង​ថត​សៀវភៅ​អាសយដ្ឋាន Akonadi -Comment[ko]=Akonadi 주소록에 저장된 연락처에 접근합니다 -Comment[lt]=Suteikia priėjimą prie adresatų, saugomų Akonadi adresų knygelės aplankuose -Comment[lv]=Nodrošina piekļuvi kontaktiem, kas glabājas Akonadi adrešu grāmatu mapēs -Comment[nb]=Gir tilgang til kontakter lagret i Akonadi adressebok-mappene -Comment[nds]=Stellt Togriep op binnen Akonadi sien Adressbookornern wohrte Kontakten praat -Comment[nl]=Geeft toegang tot de in de adresboekmappen van Akonadi opgeslagen contactpersonen -Comment[nn]=Gjev tilgang til kontaktar lagra i Akonadi-adressebokmapper -Comment[pa]=ਅਕੌਂਡੀ ਐਡਰੈੱਸ ਬੁੱਕ ਫੋਲਡਰਾਂ ਵਿੱਚ ਸਟੋਰ ਕੀਤੇ ਸੰਪਰਕਾਂ ਲਈ ਅਸੈੱਸ ਹੈ -Comment[pl]=Zapewnia dostęp do wizytówek przechowywanych w katalogach książki adresowej Akonadi -Comment[pt]=Oferece o acesso aos contactos guardados nas pastas do livro de endereços do Akonadi -Comment[pt_BR]=Fornece acesso aos contatos armazenados nas pastas do livro de endereços do Akonadi -Comment[ro]=Oferă acces la contactele stocate în dosarele cărții de adrese Akonadi -Comment[ru]=Доступ к папкам адресных книг Akonadi -Comment[sk]=Poskytuje prístup ku kontaktom uloženým v priečinkoch adresára Akonadi -Comment[sl]=Omogoča dostop do stikov, shranjenih v Akonadijevih mapah z imeniki -Comment[sr]=Омогућава приступ контактима смештеним у адресним фасциклама Аконадија -Comment[sr@ijekavian]=Омогућава приступ контактима смјештеним у адресним фасциклама Аконадија -Comment[sr@ijekavianlatin]=Omogućava pristup kontaktima smještenim u adresnim fasciklama Akonadija -Comment[sr@latin]=Omogućava pristup kontaktima smeštenim u adresnim fasciklama Akonadija -Comment[sv]=Ger tillgång till kontakter lagrade i Akonadi adressbokskataloger -Comment[tr]=Akonadi adres defteri dizinlerindeki kişilere erişimi sağlar -Comment[uk]="Надає доступ до контактів, які зберігаються у теках адресної книги Akonadi" -Comment[x-test]=xxProvides access to contacts stored in Akonadi address book foldersxx -Comment[zh_CN]=提供对存储在 Akonadi 地址簿文件夹中的联系人的访问支持 -Comment[zh_TW]=提供存取儲存在 Akonadi 通訊錄資料夾中的聯絡人 -X-KDE-Library=kabc_akonadi -Type=Service -ServiceTypes=KResources/Plugin -X-KDE-ResourceFamily=contact -X-KDE-ResourceType=akonadi diff -Nru kdepim-runtime-4.14.6/kresources/kabc/CMakeLists.txt kdepim-runtime-15.08.0/kresources/kabc/CMakeLists.txt --- kdepim-runtime-4.14.6/kresources/kabc/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kabc/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ - -#include_directories( ${CMAKE_SOURCE_DIR}/kabc ) -include_directories( ${Boost_INCLUDE_DIR} ) - -########### next target ############### - -set(kabc_akonadi_SRCS resourceakonadiplugin.cpp resourceakonadi.cpp resourceakonadi_p.cpp resourceakonadiconfig.cpp subresource.cpp -${RESOURCE_AKONADI_SHARED_SOURCES} ) - - -kde4_add_plugin(kabc_akonadi ${kabc_akonadi_SRCS}) - -target_link_libraries(kabc_akonadi ${KDEPIMLIBS_KABC_LIBS} ${KDEPIMLIBS_AKONADI_LIBS} ${KDE4_KCMUTILS_LIBS}) - - -install(TARGETS kabc_akonadi DESTINATION ${PLUGIN_INSTALL_DIR} ) - - -########### install files ############### - -install( FILES akonadi.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kresources/kabc ) diff -Nru kdepim-runtime-4.14.6/kresources/kabc/Messages.sh kdepim-runtime-15.08.0/kresources/kabc/Messages.sh --- kdepim-runtime-4.14.6/kresources/kabc/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kabc/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -#! /usr/bin/env bash -$XGETTEXT *.cpp -o $podir/kabc_akonadi.pot diff -Nru kdepim-runtime-4.14.6/kresources/kabc/resourceakonadiconfig.cpp kdepim-runtime-15.08.0/kresources/kabc/resourceakonadiconfig.cpp --- kdepim-runtime-4.14.6/kresources/kabc/resourceakonadiconfig.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kabc/resourceakonadiconfig.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -/* - This file is part of libkabc. - Copyright (c) 2008, 2009 Kevin Krammer - - 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 "resourceakonadiconfig.h" - -#include "resourceakonadi.h" -#include "storecollectionmodel.h" - -#include -#include - -#include -#include - -#include -#include -#include -#include - -using namespace KABC; - -ResourceAkonadiConfig::ResourceAkonadiConfig( QWidget *parent ) - : ResourceConfigBase( QStringList() << Addressee::mimeType() - << ContactGroup::mimeType(), - parent ) -{ - const QString sourcesTitle = i18nc( "@title:window", "Manage Address Book Sources" ); - mSourcesDialog->setCaption( sourcesTitle ); - mSourcesButton->setText( sourcesTitle ); - - mInfoTextLabel->setText( i18nc( "@info", - "By default you will be asked where to put a " - "new Contact or Distribution List when you create " - "them." - "For convenience it is also possible to configure " - "a default folder for each of the two data items." - "If the folder list below is empty, you might " - "have to add an address book source through " - "%1", - sourcesTitle ) ); - - mItemTypes[ Addressee::mimeType() ] = i18nc( "@item:inlistbox, address book entries", "Contacts" ); - mItemTypes[ ContactGroup::mimeType() ] = i18nc( "@item:inlistbox, email distribution lists", "Distribution Lists" ); - - QCheckBox *checkBox = new QCheckBox( mButtonBox ); - mButtonBox->addButton( checkBox, QDialogButtonBox::ApplyRole ); - checkBox->setText( mItemTypes[ Addressee::mimeType() ] ); - mMimeCheckBoxes.insert( Addressee::mimeType(), checkBox ); - checkBox->setEnabled( false ); - - checkBox = new QCheckBox( mButtonBox ); - mButtonBox->addButton( checkBox, QDialogButtonBox::ApplyRole ); - checkBox->setText( mItemTypes[ ContactGroup::mimeType() ] ); - mMimeCheckBoxes.insert( ContactGroup::mimeType(), checkBox ); - checkBox->setEnabled( false ); - - connectMimeCheckBoxes(); -} - diff -Nru kdepim-runtime-4.14.6/kresources/kabc/resourceakonadiconfig.h kdepim-runtime-15.08.0/kresources/kabc/resourceakonadiconfig.h --- kdepim-runtime-4.14.6/kresources/kabc/resourceakonadiconfig.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kabc/resourceakonadiconfig.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -/* - This file is part of libkabc. - Copyright (c) 2008, 2009 Kevin Krammer - - 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 KABC_RESOURCEAKONADICONFIG_H -#define KABC_RESOURCEAKONADICONFIG_H - -#include "resourceconfigbase.h" - -namespace KABC { - -class ResourceAkonadiConfig : public ResourceConfigBase -{ - Q_OBJECT - - public: - ResourceAkonadiConfig( QWidget *parent = 0 ); -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/kresources/kabc/resourceakonadi.cpp kdepim-runtime-15.08.0/kresources/kabc/resourceakonadi.cpp --- kdepim-runtime-4.14.6/kresources/kabc/resourceakonadi.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kabc/resourceakonadi.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,257 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - This file is part of libkabc. - Copyright (c) 2008-2009 Kevin Krammer - - 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 "resourceakonadi.h" - -#include "resourceakonadi_p.h" -#include "resourceakonadiconfig.h" - -using namespace KABC; - -ResourceAkonadi::ResourceAkonadi() - : ResourceABC(), d( new Private( this ) ) -{ - KGlobal::locale()->insertCatalog("kresources_shared_akonadi"); -} - -ResourceAkonadi::ResourceAkonadi( const KConfigGroup &group ) - : ResourceABC( group ), d( new Private( group, this ) ) -{ -} - -ResourceAkonadi::~ResourceAkonadi() -{ - delete d; -} - -void ResourceAkonadi::clear() -{ - // clear local caches - d->clear(); - - ResourceABC::clear(); -} - -void ResourceAkonadi::writeConfig( KConfigGroup &group ) -{ - kDebug( 5700 ); - ResourceABC::writeConfig( group ); - - d->writeConfig( group ); -} - -bool ResourceAkonadi::doOpen() -{ - return d->doOpen(); -} - -void ResourceAkonadi::doClose() -{ - d->clear(); - d->doClose(); -} - -Ticket *ResourceAkonadi::requestSaveTicket() -{ - kDebug( 5700 ); - if ( !addressBook() ) { - kDebug( 5700 ) << "no addressbook"; - return 0; - } - - return createTicket( this ); -} - -void ResourceAkonadi::releaseSaveTicket( Ticket *ticket ) -{ - delete ticket; -} - -bool ResourceAkonadi::load() -{ - kDebug( 5700 ); - - d->clear(); - return d->doLoad(); -} - -bool ResourceAkonadi::asyncLoad() -{ - kDebug( 5700 ); - - d->clear(); - return d->doAsyncLoad(); -} - -bool ResourceAkonadi::save( Ticket *ticket ) -{ - Q_UNUSED( ticket ); - kDebug( 5700 ); - - return d->doSave(); -} - -bool ResourceAkonadi::asyncSave( Ticket *ticket ) -{ - Q_UNUSED( ticket ); - kDebug( 5700 ); - - return d->doAsyncSave(); -} - -void ResourceAkonadi::insertAddressee( const Addressee &addr ) -{ - kDebug( 5700 ); - if ( d->insertAddressee( addr ) ) { - ResourceABC::insertAddressee( addr ); - } -} - -void ResourceAkonadi::removeAddressee( const Addressee &addr ) -{ - kDebug( 5700 ); - d->removeAddressee( addr ); - - ResourceABC::removeAddressee( addr ); -} - -void ResourceAkonadi::insertDistributionList( DistributionList *list ) -{ - kDebug( 5700 ) << "identifier=" << list->identifier() - << ", name=" << list->name(); - - if ( d->insertDistributionList( list ) ) { - ResourceABC::insertDistributionList( list ); - } -} - -void ResourceAkonadi::removeDistributionList( DistributionList *list ) -{ - kDebug( 5700 ) << "identifier=" << list->identifier() - << ", name=" << list->name(); - - d->removeDistributionList( list ); - - ResourceABC::removeDistributionList( list ); -} - -bool ResourceAkonadi::subresourceActive( const QString &subResource ) const -{ - kDebug( 5700 ) << "subResource" << subResource; - - bool active = false; - SubResource *resource = d->subResource( subResource ); - if ( resource != 0 ) { - active = resource->isActive(); - } - - return active; -} - -bool ResourceAkonadi::subresourceWritable( const QString &subResource ) const -{ - kDebug( 5700 ) << "subResource" << subResource; - - bool writable = false; - SubResource *resource = d->subResource( subResource ); - if ( resource != 0 ) { - writable = resource->isWritable(); - } - - return writable; -} - -QString ResourceAkonadi::subresourceLabel( const QString &subResource ) const -{ - kDebug( 5700 ) << "subResource" << subResource; - - QString label; - SubResource *resource = d->subResource( subResource ); - if ( resource != 0 ) { - label = resource->label(); - } - - return label; -} - -int ResourceAkonadi::subresourceCompletionWeight( const QString &subResource ) const -{ - kDebug( 5700 ) << "subResource" << subResource; - - int weight = 80; - SubResource *resource = d->subResource( subResource ); - if ( resource != 0 ) { - weight = resource->completionWeight(); - } - - return weight; -} - -QStringList ResourceAkonadi::subresources() const -{ - kDebug( 5700 ) << d->subResourceIdentifiers(); - return d->subResourceIdentifiers(); -} - -QMap ResourceAkonadi::uidToResourceMap() const -{ - return d->uidToResourceMap(); -} - -StoreConfigIface &ResourceAkonadi::storeConfig() -{ - return *d; -} - -void ResourceAkonadi::setSubresourceActive( const QString &subResource, bool active ) -{ - kDebug( 5700 ) << "subResource" << subResource << ", active" << active; - - // TODO check if this check for change isn't already handled in the private - bool changed = false; - - SubResource *resource = d->subResource( subResource ); - if ( resource != 0 ) { - if ( active != resource->isActive() ) { - resource->setActive( active ); - changed = true; - } - } - - if ( changed ) - addressBook()->emitAddressBookChanged(); -} - -void ResourceAkonadi::setSubresourceCompletionWeight( const QString &subResource, int weight ) -{ - kDebug( 5700 ) << "subResource" << subResource << ", weight" << weight; - - SubResource *resource = d->subResource( subResource ); - if ( resource != 0 ) { - resource->setCompletionWeight( weight ); - } -} - -bool ResourceAkonadi::readOnly() const -{ - return d->isReadOnly(); -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/kabc/resourceakonadi.h kdepim-runtime-15.08.0/kresources/kabc/resourceakonadi.h --- kdepim-runtime-4.14.6/kresources/kabc/resourceakonadi.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kabc/resourceakonadi.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -/* - This file is part of libkabc. - Copyright (c) 2008 Kevin Krammer - - 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 KABC_RESOURCEAKONADI_H -#define KABC_RESOURCEAKONADI_H - -#include "kabc/resourceabc.h" - -#include "sharedresourceiface.h" - -class KJob; -class QModelIndex; - -namespace Akonadi { - class Collection; - class Item; -} - -namespace KABC { - -class ResourceAkonadi : public ResourceABC, public SharedResourceIface -{ - Q_OBJECT - - public: - - ResourceAkonadi(); - explicit ResourceAkonadi( const KConfigGroup &group ); - virtual ~ResourceAkonadi(); - - virtual void clear(); - - virtual void writeConfig( KConfigGroup &group ); - - virtual bool doOpen(); - virtual void doClose(); - - virtual Ticket *requestSaveTicket(); - virtual void releaseSaveTicket( Ticket *ticket ); - - virtual bool load(); - virtual bool asyncLoad(); - virtual bool save( Ticket *ticket ); - virtual bool asyncSave( Ticket *ticket ); - - virtual void insertAddressee( const Addressee &addr ); - virtual void removeAddressee( const Addressee &addr ); - - virtual void insertDistributionList( DistributionList *list ); - virtual void removeDistributionList( DistributionList *list ); - - virtual bool subresourceActive( const QString &subResource ) const; - virtual bool subresourceWritable( const QString &subResource ) const; - virtual QString subresourceLabel( const QString &subResource ) const; - virtual int subresourceCompletionWeight( const QString &subResource ) const; - virtual QStringList subresources() const; - virtual QMap uidToResourceMap() const; - - virtual bool readOnly() const; - - StoreConfigIface &storeConfig(); - - public Q_SLOTS: - virtual void setSubresourceActive( const QString &subResource, bool active ); - virtual void setSubresourceCompletionWeight( const QString &subResource, int weight ); - - private: - class Private; - Private *const d; -}; - -} - -#endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/kabc/resourceakonadi_p.cpp kdepim-runtime-15.08.0/kresources/kabc/resourceakonadi_p.cpp --- kdepim-runtime-4.14.6/kresources/kabc/resourceakonadi_p.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kabc/resourceakonadi_p.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,533 +0,0 @@ -/* - This file is part of libkabc. - Copyright (c) 2009 Kevin Krammer - - 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 "resourceakonadi_p.h" - -#include "resourceakonadiconfig.h" -#include "storecollectiondialog.h" - -#include -#include - -#include -#include -#include - -using namespace KABC; - -ResourceAkonadi::Private::Private( ResourceAkonadi *parent ) - : SharedResourcePrivate( new IdArbiter(), parent ), - mParent( parent ), mInternalDataChange( false ) -{ -} - -ResourceAkonadi::Private::Private( const KConfigGroup &config, ResourceAkonadi *parent ) - : SharedResourcePrivate( config, new IdArbiter(), parent ), - mParent( parent ), mInternalDataChange( false ) -{ -} - -bool ResourceAkonadi::Private::insertAddressee( const KABC::Addressee &addressee ) -{ - const QString uid = addressee.uid(); - - if ( mParent->mAddrMap.constFind( uid ) != mParent->mAddrMap.constEnd() ) { - changeLocalItem( uid ); - return true; - } - - return addLocalItem( uid, Addressee::mimeType() ); -} - -void ResourceAkonadi::Private::removeAddressee( const KABC::Addressee &addressee ) -{ - removeLocalItem( addressee.uid() ); -} - -bool ResourceAkonadi::Private::insertDistributionList( KABC::DistributionList *list ) -{ - if ( mInternalDataChange ) { - return true; - } - - const QString uid = list->identifier(); - if ( mParent->mDistListMap.constFind( uid ) != mParent->mDistListMap.constEnd() ) { - changeLocalItem( uid ); - return true; - } - - return addLocalItem( uid, ContactGroup::mimeType() ); - -} - -void ResourceAkonadi::Private::removeDistributionList( KABC::DistributionList *list ) -{ - if ( mInternalDataChange ) { - return; - } - - removeLocalItem( list->identifier() ); -} - -QMap ResourceAkonadi::Private::uidToResourceMap() const -{ - return mUidToResourceMap; -} - -bool ResourceAkonadi::Private::openResource() -{ - kDebug( 5700 ); - return true; -} - -bool ResourceAkonadi::Private::closeResource() -{ - kDebug( 5700 ); - // clear local caches - mParent->mAddrMap.clear(); - - // take a copy of mDistListMap, then clear it and finally qDeleteAll - // the copy to avoid problems with removeDistributionList() called by - // ~DistributionList(). - BoolGuard internalChange( mInternalDataChange, true ); - DistributionListMap tempDistListMap( mParent->mDistListMap ); - mParent->mDistListMap.clear(); - qDeleteAll( tempDistListMap ); - - return true; -} - -void ResourceAkonadi::Private::clearResource() -{ - kDebug( 5700 ); - // clear local caches - mParent->mAddrMap.clear(); - - // take a copy of mDistListMap, then clear it and finally qDeleteAll - // the copy to avoid problems with removeDistributionList() called by - // ~DistributionList(). - BoolGuard internalChange( mInternalDataChange, true ); - DistributionListMap tempDistListMap( mParent->mDistListMap ); - mParent->mDistListMap.clear(); - qDeleteAll( tempDistListMap ); - - SharedResourcePrivate::clearResource(); -} - -Akonadi::Item ResourceAkonadi::Private::createItem( const QString &kresId ) -{ - Akonadi::Item item; - - DistributionList *list = mParent->mDistListMap.value( kresId, 0 ); - if ( list != 0 ) { - item.setMimeType( ContactGroup::mimeType() ); - item.setPayload( contactGroupFromDistList( list ) ); - } else { - item.setMimeType( Addressee::mimeType() ); - item.setPayload( mParent->mAddrMap.value( kresId ) ); - } - - return item; -} - -Akonadi::Item ResourceAkonadi::Private::updateItem( const Akonadi::Item &item, const QString &kresId, const QString &originalId ) -{ - Akonadi::Item update( item ); - - DistributionList *list = mParent->mDistListMap.value( kresId, 0 ); - if ( list != 0 ) { - ContactGroup contactGroup = contactGroupFromDistList( list ); - contactGroup.setId( originalId ); - - update.setPayload( contactGroup ); - } else { - Addressee addressee = mParent->mAddrMap.value( kresId ); - addressee.setUid( originalId ); - update.setPayload( addressee ); - } - - return update; -} - -StoreConfigIface::CollectionsByMimeType ResourceAkonadi::Private::storeCollectionsFromOldDefault() const -{ - Q_ASSERT( mDefaultStoreCollection.isValid() ); - - CollectionsByMimeType storeCollections; - - if ( Akonadi::MimeTypeChecker::isWantedCollection( mDefaultStoreCollection, Addressee::mimeType() ) ) { - storeCollections[ Addressee::mimeType() ] = mDefaultStoreCollection; - } - if ( Akonadi::MimeTypeChecker::isWantedCollection( mDefaultStoreCollection, ContactGroup::mimeType() ) ) { - storeCollections[ ContactGroup::mimeType() ] = mDefaultStoreCollection; - } - - return storeCollections; -} - -void ResourceAkonadi::Private::subResourceAdded( SubResourceBase *subResourceBase ) -{ - kDebug( 5700 ) << "id=" << subResourceBase->subResourceIdentifier(); - - SharedResourcePrivate::subResourceAdded( subResourceBase ); - - SubResource *subResource = qobject_cast( subResourceBase ); - - connect( subResource, SIGNAL(addresseeAdded(KABC::Addressee,QString)), - this, SLOT(addresseeAdded(KABC::Addressee,QString)) ); - connect( subResource, SIGNAL(addresseeChanged(KABC::Addressee,QString)), - this, SLOT(addresseeChanged(KABC::Addressee,QString)) ); - connect( subResource, SIGNAL(addresseeRemoved(QString,QString)), - this, SLOT(addresseeRemoved(QString,QString)) ); - - connect( subResource, SIGNAL(contactGroupAdded(KABC::ContactGroup,QString)), - this, SLOT(contactGroupAdded(KABC::ContactGroup,QString)) ); - connect( subResource, SIGNAL(contactGroupChanged(KABC::ContactGroup,QString)), - this, SLOT(contactGroupChanged(KABC::ContactGroup,QString)) ); - connect( subResource, SIGNAL(contactGroupRemoved(QString,QString)), - this, SLOT(contactGroupRemoved(QString,QString)) ); - - emit mParent->signalSubresourceAdded( mParent, QLatin1String( "contact" ), subResourceBase->subResourceIdentifier() ); -} - -void ResourceAkonadi::Private::subResourceRemoved( SubResourceBase *subResourceBase ) -{ - kDebug( 5700 ) << "id=" << subResourceBase->subResourceIdentifier(); - - SharedResourcePrivate::subResourceRemoved( subResourceBase ); - - SubResource *subResource = qobject_cast( subResourceBase ); - - disconnect( subResource, SIGNAL(addresseeAdded(KABC::Addressee,QString)), - this, SLOT(addresseeAdded(KABC::Addressee,QString)) ); - disconnect( subResource, SIGNAL(addresseeChanged(KABC::Addressee,QString)), - this, SLOT(addresseeChanged(KABC::Addressee,QString)) ); - disconnect( subResource, SIGNAL(addresseeRemoved(QString,QString)), - this, SLOT(addresseeRemoved(QString,QString)) ); - - disconnect( subResource, SIGNAL(contactGroupAdded(KABC::ContactGroup,QString)), - this, SLOT(contactGroupAdded(KABC::ContactGroup,QString)) ); - disconnect( subResource, SIGNAL(contactGroupChanged(KABC::ContactGroup,QString)), - this, SLOT(contactGroupChanged(KABC::ContactGroup,QString)) ); - disconnect( subResource, SIGNAL(contactGroupRemoved(QString,QString)), - this, SLOT(contactGroupRemoved(QString,QString)) ); - - // block scope for BoolGuard - { - BoolGuard internalChange( mInternalDataChange, true ); - - QMap::iterator it = mUidToResourceMap.begin(); - while ( it != mUidToResourceMap.end() ) { - if ( it.value() == subResourceBase->subResourceIdentifier() ) { - const QString uid = it.key(); - - mChanges.remove( uid ); - mIdArbiter->removeArbitratedId( uid ); - - mParent->mAddrMap.remove( uid ); - - DistributionList *distList = mParent->mDistListMap.value( uid, 0 ); - delete distList; - - it = mUidToResourceMap.erase( it ); - } else { - ++it; - } - } - } - - emit mParent->signalSubresourceRemoved( mParent, QLatin1String( "contact" ), subResourceBase->subResourceIdentifier() ); - - emit mParent->addressBook()->emitAddressBookChanged(); -} - -void ResourceAkonadi::Private::loadingResult( bool ok, const QString &errorString ) -{ - SharedResourcePrivate::loadingResult( ok, errorString ); - - if ( ok ) { - emit mParent->loadingFinished( mParent ); - mModel.startMonitoring(); - } else { - emit mParent->loadingError( mParent, errorString ); - } -} - -void ResourceAkonadi::Private::savingResult( bool ok, const QString &errorString ) -{ - SharedResourcePrivate::savingResult( ok, errorString ); - - if ( ok ) { - mChanges.clear(); - emit mParent->savingFinished( mParent ); - } else { - emit mParent->savingError( mParent, errorString ); - } -} - -const SubResourceBase *ResourceAkonadi::Private::storeSubResourceFromUser( const QString &uid, const QString &mimeType ) -{ - Q_UNUSED( uid ); - - Q_ASSERT( mStoreCollectionDialog != 0 ); - - if ( mimeType == Addressee::mimeType() ) { - mStoreCollectionDialog->setLabelText( i18nc( "@label where to store a new address book entry", "Please select a storage folder for this contact:" ) ); - } else if ( mimeType == ContactGroup::mimeType() ) { - mStoreCollectionDialog->setLabelText( i18nc( "@label where to store a new email distribution list", "Please select a storage folder for this distribution list:" ) ); - } else { - kError( 5700 ) << "Unexpected MIME type:" << mimeType; - mStoreCollectionDialog->setLabelText( i18nc( "@label", "Please select a storage folder:" ) ); - } - - mStoreCollectionDialog->setMimeType( mimeType ); - - const SubResourceBase *resource = 0; - while ( resource == 0 ) { - if ( mStoreCollectionDialog->exec() != QDialog::Accepted ) { - return 0; - } - - Akonadi::Collection collection = mStoreCollectionDialog->selectedCollection(); - if ( collection.isValid() ) { - resource = mModel.subResource( collection.id() ); - } - } - - return resource; -} - -void ResourceAkonadi::Private::subResourceChanged( const QString &subResourceIdentifier ) -{ - emit mParent->signalSubresourceChanged( mParent, QLatin1String( "contact" ), subResourceIdentifier ); -} - -void ResourceAkonadi::Private::addresseeAdded( const KABC::Addressee &addressee, const QString &subResourceIdentifier ) -{ - kDebug( 5700 ) << "Addressee (uid=" << addressee.uid() - << ", name=" << addressee.formattedName() - << "), subResource=" << subResourceIdentifier; - - mChanges.remove( addressee.uid() ); - - // check if we already have it, i.e. if it is the result of us saving it - if ( mParent->mAddrMap.constFind( addressee.uid() ) == mParent->mAddrMap.constEnd() ) { - Addressee addr = addressee; - addr.setResource( mParent ); - mParent->mAddrMap.insert( addressee.uid(), addr ); - - mUidToResourceMap.insert( addressee.uid(), subResourceIdentifier ); - - if ( !isLoading() ) { - mParent->addressBook()->emitAddressBookChanged(); - } - } -} - -void ResourceAkonadi::Private::addresseeChanged( const KABC::Addressee &addressee, const QString &subResourceIdentifier ) -{ - kDebug( 5700 ) << "Addressee (uid=" << addressee.uid() - << ", name=" << addressee.formattedName() - << "), subResource=" << subResourceIdentifier; - - mChanges.remove( addressee.uid() ); - - Addressee oldAddressee = mParent->mAddrMap[ addressee.uid() ]; - if ( oldAddressee == addressee ) { - kDebug( 5700 ) << "No change to addressee data"; - return; - } - - Addressee addr = addressee; - addr.setResource( mParent ); - mParent->mAddrMap[ addressee.uid() ] = addr; - - if ( !isLoading() ) { - mParent->addressBook()->emitAddressBookChanged(); - } -} - -void ResourceAkonadi::Private::addresseeRemoved( const QString &uid, const QString &subResourceIdentifier ) -{ - kDebug( 5700 ) << "Addressee (uid=" << uid - << "), subResource=" << subResourceIdentifier; - - mChanges.remove( uid ); - - // check if we still have it, i.e. it is not a result of us deleting it - if ( mParent->mAddrMap.constFind( uid ) != mParent->mAddrMap.constEnd() ) { - mParent->mAddrMap.remove( uid ); - mUidToResourceMap.remove( uid ); - - if ( !isLoading() ) { - mParent->addressBook()->emitAddressBookChanged(); - } - } -} - -void ResourceAkonadi::Private::contactGroupAdded( const KABC::ContactGroup &contactGroup, const QString &subResourceIdentifier ) -{ - kDebug( 5700 ) << "ContactGroup (uid=" << contactGroup.id() - << ", name=" << contactGroup.name() - << "), subResource=" << subResourceIdentifier; - - mChanges.remove( contactGroup.id() ); - - // check if we already have it, i.e. if it is the result of us saving it - if ( mParent->mDistListMap.constFind( contactGroup.id() ) == mParent->mDistListMap.constEnd() ) { - // block scope for BoolGuard - { - BoolGuard internalChange( mInternalDataChange, true ); - (void)distListFromContactGroup( contactGroup ); - } - - mUidToResourceMap.insert( contactGroup.id(), subResourceIdentifier ); - - if ( !isLoading() ) { - mParent->addressBook()->emitAddressBookChanged(); - } - } -} - -void ResourceAkonadi::Private::contactGroupChanged( const KABC::ContactGroup &contactGroup, const QString &subResourceIdentifier ) -{ - kDebug( 5700 ) << "ContactGroup (uid=" << contactGroup.id() - << ", name=" << contactGroup.name() - << "), subResource=" << subResourceIdentifier; - - mChanges.remove( contactGroup.id() ); - - // TODO check if we can compare distribution lists and whether we - // can do update instead of remove/add - DistributionListMap::iterator findIt = mParent->mDistListMap.find( contactGroup.id() ); - if ( findIt == mParent->mDistListMap.end() ) { - kError( 5700 ) << "No distribution list for changed contactgroup"; - contactGroupAdded( contactGroup, subResourceIdentifier ); - return; - } - - // block scope for BoolGuard - { - BoolGuard internalChange( mInternalDataChange, true ); - DistributionList *distList = findIt.value(); - delete distList; - distList = distListFromContactGroup( contactGroup ); - } - - if ( !isLoading() ) { - mParent->addressBook()->emitAddressBookChanged(); - } -} - -void ResourceAkonadi::Private::contactGroupRemoved( const QString &uid, const QString &subResourceIdentifier ) -{ - kDebug( 5700 ) << "ContactGroup (uid=" << uid - << "), subResource=" << subResourceIdentifier; - - mChanges.remove( uid ); - - // check if we still have it, i.e. it is not a result of us deleting it - const DistributionListMap::const_iterator findIt = mParent->mDistListMap.constFind( uid ); - if ( findIt != mParent->mDistListMap.constEnd() ) { - // block scope for BoolGuard - { - BoolGuard internalChange( mInternalDataChange, true ); - DistributionList *distList = findIt.value(); - delete distList; - } - mUidToResourceMap.remove( uid ); - - if ( !isLoading() ) { - mParent->addressBook()->emitAddressBookChanged(); - } - } -} - -DistributionList *ResourceAkonadi::Private::distListFromContactGroup( const ContactGroup &contactGroup ) const -{ - DistributionList *list = new DistributionList( mParent, contactGroup.id(), contactGroup.name() ); - - for ( unsigned int refIndex = 0; refIndex < contactGroup.contactReferenceCount(); ++refIndex ) { - const ContactGroup::ContactReference &reference = contactGroup.contactReference( refIndex ); - - Addressee addressee; - Addressee::Map::const_iterator it = mParent->mAddrMap.constFind( reference.uid() ); - if ( it == mParent->mAddrMap.constEnd() ) { - addressee.setUid( reference.uid() ); - - // TODO any way to set a good name? - } else - addressee = it.value(); - - // TODO how to handle ContactGroup::Reference custom fields? - - list->insertEntry( addressee, reference.preferredEmail() ); - } - - for ( unsigned int dataIndex = 0; dataIndex < contactGroup.dataCount(); ++dataIndex ) { - const ContactGroup::Data &data = contactGroup.data( dataIndex ); - - Addressee addressee; - addressee.setName( data.name() ); - addressee.insertEmail( data.email() ); - - // TODO how to handle ContactGroup::Data custom fields? - - list->insertEntry( addressee ); - } - - return list; -} - -ContactGroup ResourceAkonadi::Private::contactGroupFromDistList( const KABC::DistributionList* list ) const -{ - ContactGroup contactGroup( list->name() ); - contactGroup.setId( list->identifier() ); - - DistributionList::Entry::List entries = list->entries(); - foreach ( const DistributionList::Entry &entry, entries ) { - Addressee addressee = entry.addressee(); - const QString email = entry.email(); - if ( addressee.isEmpty() ) { - if ( email.isEmpty() ) - continue; - - ContactGroup::Data data( email, email ); - contactGroup.append( data ); - } else { - Addressee baseAddressee = mParent->mAddrMap.value( addressee.uid() ); - if ( baseAddressee.isEmpty() ) { - ContactGroup::Data data( email, email ); - // TODO: transer custom fields? - contactGroup.append( data ); - } else { - ContactGroup::ContactReference reference( addressee.uid() ); - reference.setPreferredEmail( email ); - // TODO: transer custom fields? - contactGroup.append( reference ); - } - } - } - - return contactGroup; -} - - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/kabc/resourceakonadi_p.h kdepim-runtime-15.08.0/kresources/kabc/resourceakonadi_p.h --- kdepim-runtime-4.14.6/kresources/kabc/resourceakonadi_p.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kabc/resourceakonadi_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,107 +0,0 @@ -/* - This file is part of libkabc. - Copyright (c) 2009 Kevin Krammer - - 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 KABC_RESOURCEAKONADI_P_H -#define KABC_RESOURCEAKONADI_P_H - -#include "subresource.h" -#include "resourceakonadi.h" -#include "sharedresourceprivate.h" - -namespace KABC { - class Addressee; - class ContactGroup; - class DistributionList; -} - -class KConfigGroup; - -class KABC::ResourceAkonadi::Private : public SharedResourcePrivate -{ - Q_OBJECT - - public: - explicit Private( ResourceAkonadi *parent ); - - Private( const KConfigGroup &config, ResourceAkonadi *parent ); - - bool insertAddressee( const KABC::Addressee &addressee ); - - void removeAddressee( const KABC::Addressee &addressee ); - - bool insertDistributionList( KABC::DistributionList *list ); - - void removeDistributionList( KABC::DistributionList *list ); - - QMap uidToResourceMap() const; - - public: - ResourceAkonadi *mParent; - - protected: - bool mInternalDataChange; - - protected: - bool openResource(); - - bool closeResource(); - - void clearResource(); - - void subResourceAdded( SubResourceBase *subResource ); - - void subResourceRemoved( SubResourceBase *subResource ); - - void loadingResult( bool ok, const QString &errorString ); - - void savingResult( bool ok, const QString &errorString ); - - const SubResourceBase *storeSubResourceFromUser( const QString &uid, const QString &mimeType ); - - Akonadi::Item createItem( const QString &kresId ); - - Akonadi::Item updateItem( const Akonadi::Item &item, const QString &kresId, const QString &originalId ); - - CollectionsByMimeType storeCollectionsFromOldDefault() const; - - protected Q_SLOTS: - void subResourceChanged( const QString &subResourceIdentifier ); - - void addresseeAdded( const KABC::Addressee &addressee, const QString &subResourceIdentifier ); - - void addresseeChanged( const KABC::Addressee &addressee, const QString &subResourceIdentifier ); - - void addresseeRemoved( const QString &uid, const QString &subResourceIdentifier ); - - void contactGroupAdded( const KABC::ContactGroup &contactGroup, const QString &subResourceIdentifier ); - - void contactGroupChanged( const KABC::ContactGroup &contactGroup, const QString &subResourceIdentifier ); - - void contactGroupRemoved( const QString &uid, const QString &subResourceIdentifier ); - - private: - KABC::DistributionList *distListFromContactGroup( const KABC::ContactGroup &contactGroup ) const; - - KABC::ContactGroup contactGroupFromDistList( const KABC::DistributionList* list ) const; -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/kabc/resourceakonadiplugin.cpp kdepim-runtime-15.08.0/kresources/kabc/resourceakonadiplugin.cpp --- kdepim-runtime-4.14.6/kresources/kabc/resourceakonadiplugin.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kabc/resourceakonadiplugin.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* - This file is part of libkabc. - Copyright (c) 2008 Kevin Krammer - - 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 "kabc/kabc_export.h" -#include "resourceakonadi.h" -#include "resourceakonadiconfig.h" - -#include -#include - -using namespace KABC; - -class ResourceAkonadiKABCFactory : public KRES::PluginFactory -{ - public: - ResourceAkonadiKABCFactory() - : KRES::PluginFactory() - { - KGlobal::locale()->insertCatalog( QLatin1String( "kabc_akonadi" ) ); - } -}; - -K_EXPORT_PLUGIN(ResourceAkonadiKABCFactory) diff -Nru kdepim-runtime-4.14.6/kresources/kabc/subresource.cpp kdepim-runtime-15.08.0/kresources/kabc/subresource.cpp --- kdepim-runtime-4.14.6/kresources/kabc/subresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kabc/subresource.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,184 +0,0 @@ - -/* - This file is part of libkabc. - Copyright (c) 2009 Kevin Krammer - - 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 "subresource.h" - -#include - -#include -#include - -#include -#include -#include - -using namespace KABC; - -QString IdArbiter::createArbitratedId() const -{ - QString id; - do { - id = KRandom::randomString( 10 ); - } while ( mArbitratedToOriginal.constFind( id ) != mArbitratedToOriginal.constEnd() ); - - return id; -} - -SubResource::SubResource( const Akonadi::Collection &collection ) - : SubResourceBase( collection ), - mCompletionWeight( 80 ) -{ -} - -SubResource::~SubResource() -{ -} - -QStringList SubResource::supportedMimeTypes() -{ - return QStringList() << Addressee::mimeType() << ContactGroup::mimeType(); -} - -void SubResource::setCompletionWeight( int weight ) -{ - mCompletionWeight = weight; -} - -int SubResource::completionWeight() const -{ - return mCompletionWeight; -} - -void SubResource::readTypeSpecificConfig( const KConfigGroup &config ) -{ - mCompletionWeight = config.readEntry( QLatin1String( "CompletionWeight" ), 80 ); -} - -void SubResource::writeTypeSpecificConfig( KConfigGroup &config ) const -{ - config.writeEntry( QLatin1String( "CompletionWeight" ), mCompletionWeight ); -} - -void SubResource::collectionChanged( const Akonadi::Collection &collection ) -{ - bool changed = false; - - const QString oldLabel = label( mCollection ); - const QString newLabel = label( collection ); - if ( oldLabel != newLabel ) { - kDebug( 5700 ) << "SubResource label changed from" << oldLabel - << "to" << newLabel; - changed = true; - } - - const bool oldWritable = isWritable( mCollection ); - const bool newWritable = isWritable( collection ); - if ( oldWritable != newWritable ) { - kDebug( 5700 ) << "SubResource isWritable changed from" << oldWritable - << "to" << newWritable; - changed = true; - } - - if ( changed ) { - mCollection = collection; - emit subResourceChanged( subResourceIdentifier() ); - } -} - -void SubResource::itemAdded( const Akonadi::Item &item ) -{ - Q_ASSERT( mIdArbiter != 0 ); - - QString arbitratedId; - QString kresId; - if ( item.hasPayload() ) { - Addressee addressee = item.payload(); - kresId = addressee.uid(); - - arbitratedId = mIdArbiter->arbitrateOriginalId( addressee.uid() ); - addressee.setUid( arbitratedId ); - - emit addresseeAdded( addressee, subResourceIdentifier() ); - } else if ( item.hasPayload() ) { - ContactGroup contactGroup = item.payload(); - kresId = contactGroup.id(); - - arbitratedId = mIdArbiter->arbitrateOriginalId( contactGroup.id() ); - contactGroup.setId( arbitratedId ); - - emit contactGroupAdded( contactGroup, subResourceIdentifier() ); - } else { - kError( 5700 ) << "Neither Addressee nor ContactGroup payload"; - return; - } - - mMappedItems.insert( arbitratedId, item ); - mMappedIds.insert( item.id(), arbitratedId ); -} - -void SubResource::itemChanged( const Akonadi::Item &item ) -{ - Q_ASSERT( mIdArbiter != 0 ); - - const QString kresId = mMappedIds.value( item.id() ); - Q_ASSERT( !kresId.isEmpty() ); - - if ( item.hasPayload() ) { - Addressee addressee = item.payload(); - - addressee.setUid( kresId ); - - emit addresseeChanged( addressee, subResourceIdentifier() ); - } else if ( item.hasPayload() ) { - ContactGroup contactGroup = item.payload(); - - contactGroup.setId( kresId ); - - emit contactGroupChanged( contactGroup, subResourceIdentifier() ); - } else { - kError( 5700 ) << "Neither Addressee nor ContactGroup payload"; - return; - } - - mMappedItems[ kresId ] = item; -} - -void SubResource::itemRemoved( const Akonadi::Item &item ) -{ - Q_ASSERT( mIdArbiter != 0 ); - - const QString kresId = mMappedIds.value( item.id() ); - Q_ASSERT( !kresId.isEmpty() ); - - if ( Akonadi::MimeTypeChecker::isWantedItem( item, Addressee::mimeType() ) ) { - emit addresseeRemoved( kresId, subResourceIdentifier() ); - } else if ( Akonadi::MimeTypeChecker::isWantedItem( item, ContactGroup::mimeType() ) ) { - emit contactGroupRemoved( kresId, subResourceIdentifier() ); - } - - mMappedItems.remove( kresId ); - mMappedIds.remove( item.id() ); - - mIdArbiter->removeArbitratedId( kresId ); -} - - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/kabc/subresource.h kdepim-runtime-15.08.0/kresources/kabc/subresource.h --- kdepim-runtime-4.14.6/kresources/kabc/subresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kabc/subresource.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -/* - This file is part of libkabc. - Copyright (c) 2009 Kevin Krammer - - 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 KABC_RESOURCEAKONADI_SUBRESOURCE_H -#define KABC_RESOURCEAKONADI_SUBRESOURCE_H - -#include "idarbiterbase.h" -#include "subresourcebase.h" - -namespace Akonadi { - class Collection; -} - -namespace KABC { - class Addressee; - class ContactGroup; -} - -class IdArbiter : public IdArbiterBase -{ - protected: - QString createArbitratedId() const; -}; - -class SubResource : public SubResourceBase -{ - Q_OBJECT - - public: - explicit SubResource( const Akonadi::Collection &collection ); - - ~SubResource(); - - static QStringList supportedMimeTypes(); - - void setCompletionWeight( int weight ); - - int completionWeight() const; - - Q_SIGNALS: - void subResourceChanged( const QString &subResourceIdentifier ); - - void addresseeAdded( const KABC::Addressee &addressee, const QString &subResourceIdentifier ); - - void addresseeChanged( const KABC::Addressee &addressee, const QString &subResourceIdentifier ); - - void addresseeRemoved( const QString &uid, const QString &subResourceIdentifier ); - - void contactGroupAdded( const KABC::ContactGroup &contactGroup, const QString &subResourceIdentifier ); - - void contactGroupChanged( const KABC::ContactGroup &contactGroup, const QString &subResourceIdentifier ); - - void contactGroupRemoved( const QString &uid, const QString &subResourceIdentifier ); - - protected: - int mCompletionWeight; - - protected: - void readTypeSpecificConfig( const KConfigGroup &config ); - - void writeTypeSpecificConfig( KConfigGroup &config ) const; - - void collectionChanged( const Akonadi::Collection &collection ); - - void itemAdded( const Akonadi::Item &item ); - - void itemChanged( const Akonadi::Item &item ); - - void itemRemoved( const Akonadi::Item &item ); -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/kcal/akonadi.desktop kdepim-runtime-15.08.0/kresources/kcal/akonadi.desktop --- kdepim-runtime-4.14.6/kresources/kcal/akonadi.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kcal/akonadi.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -[Desktop Entry] -Name=Akonadi -Name[ar]=اكوندا -Name[bg]=Akonadi -Name[bs]=Akonadi -Name[ca]=Akonadi -Name[ca@valencia]=Akonadi -Name[cs]=Akonadi -Name[da]=Akonadi -Name[de]=Akonadi-Ressource -Name[el]=Akonadi -Name[en_GB]=Akonadi -Name[eo]=Akonadi -Name[es]=Akonadi -Name[et]=Akonadi -Name[fi]=Akonadi -Name[fr]=Akonadi -Name[ga]=Akonadi -Name[gl]=Akonadi -Name[hu]=Akonadi -Name[ia]=Akonadi -Name[it]=Akonadi -Name[ja]=Akonadi -Name[kk]=Akonadi -Name[km]=Akonadi -Name[ko]=Akonadi -Name[lt]=Akonadi -Name[lv]=Akonadi -Name[mai]=Akonadi -Name[mr]=आकोनाडी -Name[nb]=Akonadi -Name[nds]=Akonadi -Name[nl]=Akonadi -Name[nn]=Akonadi -Name[pa]=ਅਕੌਂਡੀ -Name[pl]=Akonadi -Name[pt]=Akonadi -Name[pt_BR]=Akonadi -Name[ro]=Akonadi -Name[ru]=Akonadi -Name[sk]=Akonadi -Name[sl]=Akonadi -Name[sq]=Akonadi -Name[sr]=Аконади -Name[sr@ijekavian]=Аконади -Name[sr@ijekavianlatin]=Akonadi -Name[sr@latin]=Akonadi -Name[sv]=Akonadi -Name[tr]=Akonadi -Name[ug]=Akonadi -Name[uk]=Akonadi -Name[x-test]=xxAkonadixx -Name[zh_CN]=Akonadi -Name[zh_TW]=Akonadi -Comment=Provides access to calendars stored in Akonadi calendar folders -Comment[ar]=يوفر الوصول للتقويمات المحفوظة في مجلد تقويم اكوندا -Comment[bs]=Omogućava pristup kalendarima pohranjenim u Akonadi direktorijima kalendara -Comment[ca]=Proporciona accés als calendaris emmagatzemats a les carpetes de calendari de l'Akonadi -Comment[ca@valencia]=Proporciona l'accés als calendaris emmagatzemats en carpetes del calendari de l'Akonadi -Comment[da]=Giver adgang til kalendere lagret i Akonadi kalender-mapper -Comment[de]=Ermöglicht den Zugriff auf Kalender, die in Akonadi-Ordnern gespeichert sind. -Comment[el]=Παρέχει πρόσβαση σε ημερολόγια αποθηκευμένα σε φακέλους ημερολογίου του Akonadi -Comment[en_GB]=Provides access to calendars stored in Akonadi calendar folders -Comment[es]=Proporciona acceso a calendarios almacenados en carpetas de calendario de Akonadi -Comment[et]=Võimaldab kasutada Akonadi kalendrikaustadesse salvestatud kalendreid -Comment[fi]=Tarjoaa pääsyn Akonadin kalenterikansioihin tallennettuihin kalentereihin -Comment[fr]=Fournit l'accès aux calendriers enregistrés dans les dossiers d'agenda Akonadi -Comment[gl]=Fornece acceso aos calendarios almacenados nos cartafoles de calendario do Akonadi -Comment[hr]=Nudi pristup kalendarima pohranjenima u Akonadijeve kalendarske mape -Comment[hu]=Hozzáférést biztosít Akonadi-naptárak tartalmához -Comment[ia]=Provide accesso a calendarios salveguardate in dossiers pro calendarios de Akonadi -Comment[it]=Consente l'accesso alle voci di calendario memorizzate in cartelle di tipo calendario di Akonadi -Comment[ja]=Akonadi のカレンダーフォルダに保存されているカレンダーへのアクセスを提供します -Comment[kk]=Akonadi күнтізбенің қапшығындағы күнтізбелеріне қатынау -Comment[km]=ផ្ដល់​សិទ្ធិ​ចូល​ដំណើរការ​ទៅកាន់​ប្រតិទិន​ដែល​បាន​រក្សាទុក​នៅ​ក្នុង​ថត​ប្រតិទិន Akonadi -Comment[ko]=Akonadi 달력 폴더에 저장된 달력에 접근합니다 -Comment[lt]=Suteikia priėjimą prie kalendorių, saugomų Akonadi kalendorių aplankuose -Comment[lv]=Nodrošina piekļuvi kalendāriem, kas glabājas Akonadi kalendāru mapēs -Comment[nb]=Gir tilgang til kalendere lagret i Akonadi adressebok-mappene -Comment[nds]=Stellt Togriep op binnen Akonadi sien Kalennerornern wohrte Kalenners praat -Comment[nl]=Geeft toegang tot de in de agendamappen van Akonadi opgeslagen agenda's -Comment[nn]=Gjev tilgang til kalendrar lagra i Akonadi-kalendermapper -Comment[pa]=ਅਕੌਂਡੀ ਕੈਲੰਡਰ ਫੋਲਡਰਾਂ ਵਿੱਚ ਸਟੋਰ ਕੀਤੇ ਕੈਲੰਡਰਾਂ ਲਈ ਅਸੈੱਸ ਹੈ -Comment[pl]=Zapewnia dostęp do kalendarzy przechowywanych w katalogach kalendarzy Akonadi -Comment[pt]=Oferece o acesso aos calendários guardados nas pastas de calendários do Akonadi -Comment[pt_BR]=Fornece acesso aos calendários armazenados nas pastas de calendários do Akonadi -Comment[ro]=Oferă acces la calendarele stocate în dosarele de calendar Akonadi -Comment[ru]=Доступ к папкам календарей Akonadi -Comment[sk]=Poskytuje prístup ku kalendárom uloženým v priečinkoch kalendára Akonadi -Comment[sl]=Omogoča dostop do koledarjev, shranjenih v Akonadijevih mapah s koledarji -Comment[sr]=Омогућава приступ календарима смештеним у календарским фасциклама Аконадија -Comment[sr@ijekavian]=Омогућава приступ календарима смјештеним у календарским фасциклама Аконадија -Comment[sr@ijekavianlatin]=Omogućava pristup kalendarima smještenim u kalendarskim fasciklama Akonadija -Comment[sr@latin]=Omogućava pristup kalendarima smeštenim u kalendarskim fasciklama Akonadija -Comment[sv]=Ger tillgång till kalendrar lagrade i Akonadi-kalenderkataloger -Comment[tr]=Akonadi takvim dizinlerindeki takvimlere erişim sağlar -Comment[uk]="Надає доступ до календарів, які зберігаються у теках календарів Akonadi" -Comment[x-test]=xxProvides access to calendars stored in Akonadi calendar foldersxx -Comment[zh_CN]=提供对存储在 Akonadi 日历文件夹中的日历的访问支持 -Comment[zh_TW]=提供存取儲存在 Akonadi 通訊錄資料夾中的行事曆 -X-KDE-Library=kcal_akonadi -Type=Service -X-KDE-ServiceTypes=KResources/Plugin -X-KDE-ResourceFamily=calendar -X-KDE-ResourceType=akonadi diff -Nru kdepim-runtime-4.14.6/kresources/kcal/CMakeLists.txt kdepim-runtime-15.08.0/kresources/kcal/CMakeLists.txt --- kdepim-runtime-4.14.6/kresources/kcal/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kcal/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - -include_directories (${Boost_INCLUDE_DIR}) - -########### next target ############### - -set(kcal_akonadi_SRCS resourceakonadiplugin.cpp resourceakonadi.cpp resourceakonadi_p.cpp resourceakonadiconfig.cpp subresource.cpp ${RESOURCE_AKONADI_SHARED_SOURCES}) - - -kde4_add_plugin(kcal_akonadi ${kcal_akonadi_SRCS}) - -target_link_libraries(kcal_akonadi ${KDEPIMLIBS_AKONADI_KCAL_LIBS} ${KDEPIMLIBS_KCAL_LIBS} ${KDEPIMLIBS_AKONADI_LIBS} ${KDE4_KCMUTILS_LIBS}) - - -install(TARGETS kcal_akonadi DESTINATION ${PLUGIN_INSTALL_DIR} ) - - -########### install files ############### - -install( FILES akonadi.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kresources/kcal ) diff -Nru kdepim-runtime-4.14.6/kresources/kcal/Messages.sh kdepim-runtime-15.08.0/kresources/kcal/Messages.sh --- kdepim-runtime-4.14.6/kresources/kcal/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kcal/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -#! /bin/sh -$XGETTEXT *.cpp -o $podir/kcal_akonadi.pot diff -Nru kdepim-runtime-4.14.6/kresources/kcal/resourceakonadiconfig.cpp kdepim-runtime-15.08.0/kresources/kcal/resourceakonadiconfig.cpp --- kdepim-runtime-4.14.6/kresources/kcal/resourceakonadiconfig.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kcal/resourceakonadiconfig.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -/* - This file is part of libkcal. - Copyright (c) 2008, 2009 Kevin Krammer - - 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 "resourceakonadiconfig.h" - -#include "resourceakonadi.h" -#include "storecollectionmodel.h" - -#include - -#include -#include - -#include -#include -#include -#include - -using namespace KCal; - -ResourceAkonadiConfig::ResourceAkonadiConfig( QWidget *parent ) - : ResourceConfigBase( QStringList() << QLatin1String( "text/calendar" ), parent ) -{ - const QString sourcesTitle = i18nc( "@title:window", "Manage Calendar Sources" ); - mSourcesDialog->setCaption( sourcesTitle ); - mSourcesButton->setText( sourcesTitle ); - - mInfoTextLabel->setText( i18nc( "@info", - "By default you will be asked where to put a " - "new Event, Todo or Journal when you create them." - "For convenience it is also possible to configure " - "a default folder for each of the three data items." - "If the folder list below is empty, you might " - "have to add a calendar source through " - "%1", - sourcesTitle ) ); - - mItemTypes[ Akonadi::IncidenceMimeTypeVisitor::eventMimeType() ] = - i18nc( "@item:inlistbox, calendar entries", "Events" ); - mItemTypes[ Akonadi::IncidenceMimeTypeVisitor::todoMimeType() ] = - i18nc( "@item:inlistbox, calendar entries", "Todos" ); - mItemTypes[ Akonadi::IncidenceMimeTypeVisitor::journalMimeType() ] = - i18nc( "@item:inlistbox, calendar entries", "Journals" ); - - QCheckBox *checkBox = new QCheckBox( mButtonBox ); - mButtonBox->addButton( checkBox, QDialogButtonBox::ApplyRole ); - checkBox->setText( mItemTypes[ Akonadi::IncidenceMimeTypeVisitor::eventMimeType() ] ); - mMimeCheckBoxes.insert( Akonadi::IncidenceMimeTypeVisitor::eventMimeType(), checkBox ); - checkBox->setEnabled( false ); - - checkBox = new QCheckBox( mButtonBox ); - mButtonBox->addButton( checkBox, QDialogButtonBox::ApplyRole ); - checkBox->setText( mItemTypes[ Akonadi::IncidenceMimeTypeVisitor::todoMimeType() ] ); - mMimeCheckBoxes.insert( Akonadi::IncidenceMimeTypeVisitor::todoMimeType(), checkBox ); - checkBox->setEnabled( false ); - - checkBox = new QCheckBox( mButtonBox ); - mButtonBox->addButton( checkBox, QDialogButtonBox::ApplyRole ); - checkBox->setText( mItemTypes[ Akonadi::IncidenceMimeTypeVisitor::journalMimeType() ] ); - mMimeCheckBoxes.insert( Akonadi::IncidenceMimeTypeVisitor::journalMimeType(), checkBox ); - checkBox->setEnabled( false ); - - connectMimeCheckBoxes(); -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/kcal/resourceakonadiconfig.h kdepim-runtime-15.08.0/kresources/kcal/resourceakonadiconfig.h --- kdepim-runtime-4.14.6/kresources/kcal/resourceakonadiconfig.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kcal/resourceakonadiconfig.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -/* - This file is part of libkcal. - Copyright (c) 2008, 2009 Kevin Krammer - - 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 KCAL_RESOURCEAKONADICONFIG_H -#define KCAL_RESOURCEAKONADICONFIG_H - -#include "resourceconfigbase.h" - -namespace KCal { - -class ResourceAkonadiConfig : public ResourceConfigBase -{ - Q_OBJECT - - public: - ResourceAkonadiConfig( QWidget *parent = 0 ); -}; - -} - -#endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/kcal/resourceakonadi.cpp kdepim-runtime-15.08.0/kresources/kcal/resourceakonadi.cpp --- kdepim-runtime-4.14.6/kresources/kcal/resourceakonadi.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kcal/resourceakonadi.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,452 +0,0 @@ -/* - This file is part of libkcal. - Copyright (c) 2008-2009 Kevin Krammer - - 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 "resourceakonadi.h" - -#include "resourceakonadi_p.h" -#include "resourceakonadiconfig.h" - -#include -#include - -#include -#include -#include - -#include - -using namespace Akonadi; -using namespace KCal; - -typedef boost::shared_ptr IncidencePtr; - -ResourceAkonadi::ResourceAkonadi() - : ResourceCalendar(), d( new Private( this ) ) -{ -} - -ResourceAkonadi::ResourceAkonadi( const KConfigGroup &group ) - : ResourceCalendar( group ), d( new Private( group, this ) ) -{ - KGlobal::locale()->insertCatalog("kresources_shared_akonadi"); -} - -ResourceAkonadi::~ResourceAkonadi() -{ - delete d; -} - -void ResourceAkonadi::writeConfig( KConfigGroup &group ) -{ - ResourceCalendar::writeConfig( group ); - - d->writeConfig( group ); -} - -StoreConfigIface &ResourceAkonadi::storeConfig() -{ - return *d; -} - -KABC::Lock *ResourceAkonadi::lock() -{ - return d->mLock; -} - -bool ResourceAkonadi::addEvent( Event *event ) -{ - const QString uid = event->uid(); - const QString mimeType = d->mMimeVisitor.mimeType( event ); - - kDebug( 5800 ) << "Event (uid=" << uid - << ", summary=" << event->summary() - << ")"; - - if ( d->addLocalItem( uid, mimeType ) ) { - return d->mCalendar.addEvent( event ); - } - - return false; -} - -bool ResourceAkonadi::deleteEvent( Event *event ) -{ - return d->mCalendar.deleteEvent( event ); -} - -void ResourceAkonadi::deleteAllEvents() -{ - d->mCalendar.deleteAllEvents(); -} - -Event *ResourceAkonadi::event( const QString &uid ) -{ - return d->mCalendar.event( uid ); -} - -Event::List ResourceAkonadi::rawEvents( EventSortField sortField, - SortDirection sortDirection ) -{ - return d->mCalendar.rawEvents( sortField, sortDirection ); -} - -Event::List ResourceAkonadi::rawEventsForDate( const QDate &date, - const KDateTime::Spec ×pec, - EventSortField sortField, - SortDirection sortDirection ) -{ - return d->mCalendar.rawEventsForDate( date, timespec, sortField, sortDirection ); -} - -Event::List ResourceAkonadi::rawEventsForDate( const KDateTime &date ) -{ - return d->mCalendar.rawEventsForDate( date ); -} - -Event::List ResourceAkonadi::rawEvents( const QDate &start, const QDate &end, - const KDateTime::Spec ×pec, - bool inclusive ) -{ - return d->mCalendar.rawEvents( start, end, timespec, inclusive ); -} - -bool ResourceAkonadi::addTodo( Todo *todo ) -{ - const QString uid = todo->uid(); - const QString mimeType = d->mMimeVisitor.mimeType( todo ); - - kDebug( 5800 ) << "Todo (uid=" << uid - << ", summary=" << todo->summary() - << ")"; - - if ( d->addLocalItem( uid, mimeType ) ) { - return d->mCalendar.addTodo( todo ); - } - - return false; -} - -bool ResourceAkonadi::deleteTodo( Todo *todo ) -{ - return d->mCalendar.deleteTodo( todo ); -} - -void ResourceAkonadi::deleteAllTodos() -{ - d->mCalendar.deleteAllTodos(); -} - -Todo *ResourceAkonadi::todo( const QString &uid ) -{ - return d->mCalendar.todo( uid ); -} - -Todo::List ResourceAkonadi::rawTodos( TodoSortField sortField, - SortDirection sortDirection ) -{ - return d->mCalendar.rawTodos( sortField, sortDirection ); -} - -Todo::List ResourceAkonadi::rawTodosForDate( const QDate &date ) -{ - return d->mCalendar.rawTodosForDate( date ); -} - -bool ResourceAkonadi::addJournal( Journal *journal ) -{ - const QString uid = journal->uid(); - const QString mimeType = d->mMimeVisitor.mimeType( journal ); - - kDebug( 5800 ) << "Journal (uid=" << uid - << ", summary=" << journal->summary() - << ")"; - - if ( d->addLocalItem( uid, mimeType ) ) { - return d->mCalendar.addJournal( journal ); - } - - return false; -} - -bool ResourceAkonadi::deleteJournal( Journal *journal ) -{ - return d->mCalendar.deleteJournal( journal ); -} - -void ResourceAkonadi::deleteAllJournals() -{ - d->mCalendar.deleteAllJournals(); -} - -Journal *ResourceAkonadi::journal( const QString &uid ) -{ - return d->mCalendar.journal( uid ); -} - -Journal::List ResourceAkonadi::rawJournals( JournalSortField sortField, - SortDirection sortDirection ) -{ - return d->mCalendar.rawJournals( sortField, sortDirection ); -} - -Journal::List ResourceAkonadi::rawJournalsForDate( const QDate &date ) -{ - return d->mCalendar.rawJournalsForDate( date ); -} - -Alarm::List ResourceAkonadi::alarms( const KDateTime &from, const KDateTime &to ) -{ - return d->mCalendar.alarms( from, to ); -} - -Alarm::List ResourceAkonadi::alarmsTo( const KDateTime &to ) -{ - return d->mCalendar.alarmsTo( to ); -} - -void ResourceAkonadi::setTimeSpec( const KDateTime::Spec &timeSpec ) -{ - d->mCalendar.setTimeSpec( timeSpec ); -} - -KDateTime::Spec ResourceAkonadi::timeSpec() const -{ - return d->mCalendar.timeSpec(); -} - -void ResourceAkonadi::setTimeZoneId( const QString &timeZoneId ) -{ - d->mCalendar.setTimeZoneId( timeZoneId ); -} - -QString ResourceAkonadi::timeZoneId() const -{ - return d->mCalendar.timeZoneId(); -} - -void ResourceAkonadi::shiftTimes( const KDateTime::Spec &oldSpec, - const KDateTime::Spec &newSpec ) -{ - d->mCalendar.shiftTimes( oldSpec, newSpec ); -} - -bool ResourceAkonadi::canHaveSubresources() const -{ - return true; -} - -QString ResourceAkonadi::labelForSubresource( const QString &subResource ) const -{ - kDebug( 5800 ) << "subresource=" << subResource; - - QString label; - SubResource *resource = d->subResource( subResource ); - if ( resource != 0 ) { - label = resource->label(); - } - - return label; -} - -void ResourceAkonadi::setSubresourceActive( const QString &subResource, bool active ) -{ - kDebug( 5800 ) << "subResource" << subResource << ", active" << active; - - // TODO might no longer be necessary - bool changed = false; - - SubResource *resource = d->subResource( subResource ); - if ( resource != 0 ) { - if ( active != resource->isActive() ) { - resource->setActive( active ); - changed = true; - } - } - - if ( changed ) { - emit resourceChanged( this ); - } -} - -bool ResourceAkonadi::subresourceActive( const QString &subResource ) const -{ - bool active = false; - SubResource *resource = d->subResource( subResource ); - if ( resource != 0 ) { - active = resource->isActive(); - } - - return active; -} - -bool ResourceAkonadi::subresourceWritable( const QString &subResource ) const -{ - bool writable = false; - SubResource *resource = d->subResource( subResource ); - if ( resource != 0 ) { - writable = resource->isWritable(); - } - - return writable; -} - -bool ResourceAkonadi::addSubresource( const QString &resource, const QString &parent ) -{ - kDebug( 5800 ) << "resource=" << resource << ", parent=" << parent; - Q_ASSERT( !resource.isEmpty() ); - - if ( parent.isEmpty() ) { - kError( 5800 ) << "Cannot create Akonadi toplevel collection"; - // TODO probably display a dialog working on the agent filter proxy model - // and then create and name the resource appropriately. - return false; - } - - SubResource *subResource = d->subResource( parent ); - if ( subResource == 0 ) { - kError( 5800 ) << "No such parent subresource/collection:" << parent; - return false; - } - - return subResource->createChildSubResource( resource ); -} - -bool ResourceAkonadi::removeSubresource( const QString &resource ) -{ - kDebug( 5800 ) << "resource=" << resource; - Q_ASSERT( !resource.isEmpty() ); - - SubResource *subResource = d->subResource( resource ); - if ( subResource == 0 ) { - kError( 5800 ) << "No such subresource: " << resource; - return false; - } - - return subResource->remove(); -} - -QString ResourceAkonadi::subresourceType( const QString &resource ) -{ - kDebug( 5800 ) << "resource=" << resource; - - QString type; - SubResource *subResource = d->subResource( resource ); - if ( subResource != 0 ) { - type = subResource->subResourceType(); - } - - return type; -} - -QString ResourceAkonadi::subresourceIdentifier( Incidence *incidence ) -{ - return d->subResourceIdentifier( incidence->uid() ); -} - -QStringList ResourceAkonadi::subresources() const -{ - kDebug( 5800 ) << d->subResourceIdentifiers(); - return d->subResourceIdentifiers(); -} - -QString ResourceAkonadi::infoText() const -{ - const QString online = i18nc( "@info access to the source's backend possible", "Online" ); - const QString offline = i18nc( "@info currently no access to the source's backend possible", - "Offline" ); - const QLatin1String br( "
" ); - - QString text = i18nc( "@info:tooltip visible name of the resource", - "%1", resourceName() ); - text += i18nc( "@info:tooltip resource type", "Type: Akonadi Calendar Resource" ) + br; - - const int rowCount = d->mAgentFilterModel->rowCount(); - for ( int row = 0; row < rowCount; ++row ) { - QModelIndex index = d->mAgentFilterModel->index( row, 0 ); - if ( index.isValid() ) { - QVariant data = d->mAgentFilterModel->data( index, AgentInstanceModel::InstanceRole ); - if ( data.isValid() ) { - AgentInstance instance = data.value(); - if ( instance.isValid() ) { - // TODO probably add progress if "Running" - QString status = instance.statusMessage(); - - text += br; - text += i18nc( "@info:tooltip name of a calendar data source", - "%1", instance.name() ) + br; - text += i18nc( "@info:tooltip status of a calendar data source and its " - "online/offline state", - "Status: %1 (%2)", status, - ( instance.isOnline() ? online : offline ) ) + br; - } - } - } - } - - return text; -} - -bool ResourceAkonadi::doLoad( bool syncCache ) -{ - kDebug( 5800 ) << "syncCache=" << syncCache; - - d->clear(); - return d->doLoad(); -} - -bool ResourceAkonadi::doSave( bool syncCache ) -{ - kDebug( 5800 ) << "syncCache=" << syncCache; - - return d->doSave(); -} - -bool ResourceAkonadi::doSave( bool syncCache, Incidence *incidence ) -{ - kDebug( 5800 ) << "syncCache=" << syncCache - << ", incidence" << incidence->uid(); - - return d->doSaveIncidence( incidence ); -} - -bool ResourceAkonadi::doOpen() -{ - return d->doOpen(); -} - -void ResourceAkonadi::doClose() -{ - // this clear() should not emit resourceChanged inspite of incidence pointers becoming - // invalid. None of the other resources to it and bug 196215 suggests it can even lead - // to crashes - bool blocked = blockSignals( true ); - d->clear(); - blockSignals( blocked ); - - d->doClose(); -} - -bool ResourceAkonadi::readOnly() const -{ - return d->isReadOnly(); -} - - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/kcal/resourceakonadi.h kdepim-runtime-15.08.0/kresources/kcal/resourceakonadi.h --- kdepim-runtime-4.14.6/kresources/kcal/resourceakonadi.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kcal/resourceakonadi.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,172 +0,0 @@ -/* - This file is part of libkcal. - Copyright (c) 2008 Kevin Krammer - - 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 KCAL_RESOURCEAKONADI_H -#define KCAL_RESOURCEAKONADI_H - -#include "kcal/resourcecalendar.h" - -#include "sharedresourceiface.h" - -namespace Akonadi { - class Collection; - class Item; -} - -class KJob; - -class QModelIndex; - -namespace KCal { - -class ResourceAkonadi : public ResourceCalendar, public SharedResourceIface -{ - Q_OBJECT - - public: - ResourceAkonadi(); - explicit ResourceAkonadi( const KConfigGroup &group ); - virtual ~ResourceAkonadi(); - - virtual void writeConfig( KConfigGroup &group ); - - StoreConfigIface &storeConfig(); - - virtual KABC::Lock *lock(); - - virtual bool addEvent( Event *event ); - - virtual bool deleteEvent( Event *event ); - - virtual void deleteAllEvents(); - - virtual Event *event( const QString &uid ); - - virtual Event::List rawEvents( - EventSortField sortField = EventSortUnsorted, - SortDirection sortDirection = SortDirectionAscending ); - - virtual Event::List rawEventsForDate( - const QDate &date, - const KDateTime::Spec ×pec = KDateTime::Spec(), - EventSortField sortField = EventSortUnsorted, - SortDirection sortDirection = SortDirectionAscending ); - - virtual Event::List rawEventsForDate( const KDateTime &date ); - - virtual Event::List rawEvents( - const QDate &start, const QDate &end, - const KDateTime::Spec ×pec = KDateTime::Spec(), - bool inclusive = false ); - - virtual bool addTodo( Todo *todo ); - - virtual bool deleteTodo( Todo *todo ); - - virtual void deleteAllTodos(); - - virtual Todo *todo( const QString &uid ); - - virtual Todo::List rawTodos( - TodoSortField sortField = TodoSortUnsorted, - SortDirection sortDirection = SortDirectionAscending ); - - virtual Todo::List rawTodosForDate( const QDate &date ); - - virtual bool addJournal( Journal *journal ); - - virtual bool deleteJournal( Journal *journal ); - - virtual void deleteAllJournals(); - - virtual Journal *journal( const QString &uid ); - - virtual Journal::List rawJournals( - JournalSortField sortField = JournalSortUnsorted, - SortDirection sortDirection = SortDirectionAscending ); - - virtual Journal::List rawJournalsForDate( const QDate &date ); - - virtual Alarm::List alarms( const KDateTime &from, - const KDateTime &to ); - - virtual Alarm::List alarmsTo( const KDateTime &to ); - - virtual void setTimeSpec( const KDateTime::Spec &timeSpec ); - - virtual KDateTime::Spec timeSpec() const; - - virtual void setTimeZoneId( const QString &timeZoneId ); - - virtual QString timeZoneId() const; - - virtual void shiftTimes( const KDateTime::Spec &oldSpec, - const KDateTime::Spec &newSpec ); - - virtual bool canHaveSubresources() const; - - virtual QString labelForSubresource( const QString &subResource ) const; - - virtual void setSubresourceActive( const QString &subResource, bool active ); - - virtual bool subresourceActive( const QString &subResource ) const; - - virtual bool subresourceWritable( const QString &subResource ) const; - - virtual QString subresourceIdentifier( Incidence *incidence ); - - virtual QStringList subresources() const; - - virtual bool addSubresource( const QString &resource, const QString &parent ); - - virtual bool removeSubresource( const QString &resource ); - - virtual QString subresourceType( const QString &resource ); - - virtual QString infoText() const; - - virtual bool readOnly() const; - - protected: - virtual bool doLoad( bool syncCache ); - - virtual bool doSave( bool syncCache ); - - virtual bool doSave( bool syncCache, Incidence *incidence ); - - virtual bool doOpen(); - - virtual void doClose(); - - using QObject::event; // prevent warning about hidden virtual method - - private: - //@cond PRIVATE - Q_DISABLE_COPY( ResourceAkonadi ) - - class Private; - Private *const d; - //@endcond -}; - -} - -#endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/kcal/resourceakonadi_p.cpp kdepim-runtime-15.08.0/kresources/kcal/resourceakonadi_p.cpp --- kdepim-runtime-4.14.6/kresources/kcal/resourceakonadi_p.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kcal/resourceakonadi_p.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,429 +0,0 @@ -/* - This file is part of libkcal. - Copyright (c) 2009 Kevin Krammer - - 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 "resourceakonadi_p.h" - -#include "concurrentjobs.h" -#include "itemsavecontext.h" -#include "resourceakonadiconfig.h" -#include "storecollectiondialog.h" - -#include -#include - -#include - -using namespace KCal; - -ResourceAkonadi::Private::Private( ResourceAkonadi *parent ) - : SharedResourcePrivate( new IdArbiter(), parent ), - mParent( parent ), mCalendar( QLatin1String( "UTC" ) ), - mLock( new KABC::LockNull( true ) ), mInternalCalendarModification( false ), - mAgentModel( 0 ), mAgentFilterModel( 0 ) -{ -} - -ResourceAkonadi::Private::Private( const KConfigGroup &config, ResourceAkonadi *parent ) - : SharedResourcePrivate( config, new IdArbiter(), parent ), - mParent( parent ), mCalendar( QLatin1String( "UTC" ) ), - mLock( new KABC::LockNull( true ) ), mInternalCalendarModification( false ), - mAgentModel( 0 ), mAgentFilterModel( 0 ) -{ -} - -ResourceAkonadi::Private::~Private() -{ - delete mLock; -} - -bool ResourceAkonadi::Private::doSaveIncidence( Incidence *incidence ) -{ - const ChangeByKResId::const_iterator findIt = mChanges.constFind( incidence->uid() ); - if ( findIt == mChanges.constEnd() ) { - kWarning( 5800 ) << "No change for incidence (uid=" << incidence->uid() - << ", summary=" << incidence->summary() << ")"; - return true; - } - - ItemSaveContext saveContext; - if ( !prepareItemSaveContext( findIt, saveContext ) ) { - const QString message = i18nc( "@info:status", "Processing change set failed" ); - savingResult( false, message ); - return false; - } - - ConcurrentItemSaveJob itemSaveJob( saveContext ); - if ( !itemSaveJob.exec() ) { - savingResult( false, itemSaveJob->errorString() ); - return false; - } - - mChanges.remove( incidence->uid() ); - - return true; -} - -QString ResourceAkonadi::Private::subResourceIdentifier( const QString &incidenceUid ) const -{ - return mUidToResourceMap.value( incidenceUid ); -} - -bool ResourceAkonadi::Private::openResource() -{ - kDebug( 5800 ) << (void*) mAgentModel << "state=" << state(); - if ( mAgentModel == 0 && state() != Failed ) { - mAgentModel = new Akonadi::AgentInstanceModel( this ); - mAgentFilterModel = new Akonadi::AgentFilterProxyModel( this ); - mAgentFilterModel->addCapabilityFilter( QLatin1String( "Resource" ) ); - mAgentFilterModel->addMimeTypeFilter( QLatin1String( "text/calendar" ) ); - - mAgentFilterModel->setSourceModel( mAgentModel ); - } - - mCalendar.registerObserver( this ); - - return true; -} - -bool ResourceAkonadi::Private::closeResource() -{ - mCalendar.unregisterObserver( this ); - - return true; -} - -void ResourceAkonadi::Private::clearResource() -{ - SharedResourcePrivate::clearResource(); - // block scope for BoolGuard - { - BoolGuard internalModification( mInternalCalendarModification, true ); - mCalendar.close(); - } - - emit mParent->resourceChanged( mParent ); -} - -const SubResourceBase *ResourceAkonadi::Private::storeSubResourceFromUser( const QString &uid, const QString &mimeType ) -{ - Q_UNUSED( uid ); - - Q_ASSERT( mStoreCollectionDialog != 0 ); - - if ( mimeType == Akonadi::IncidenceMimeTypeVisitor::eventMimeType() ) { - mStoreCollectionDialog->setLabelText( i18nc( "@label where to store a calendar entry of type Event", "Please select a storage folder for this Event" ) ); - } else if ( mimeType == Akonadi::IncidenceMimeTypeVisitor::todoMimeType() ) { - mStoreCollectionDialog->setLabelText( i18nc( "@label where to store a calendar entry of type Todo", "Please select a storage folder for this Todo" ) ); - } else if ( mimeType == Akonadi::IncidenceMimeTypeVisitor::journalMimeType() ) { - mStoreCollectionDialog->setLabelText( i18nc( "@label where to store a calendar entry of type Journal", "Please select a storage folder for this Journal" ) ); - } else if ( mimeType == QLatin1String( "text/calendar" ) ) { - kWarning( 5800 ) << "Unexpected generic MIME type text/calendar"; - mStoreCollectionDialog->setLabelText( i18nc( "@label where to store a calendar entry of unspecified type", "Please select a storage folder for this calendar entry" ) ); - } else { - kError( 5800 ) << "Unexpected MIME type:" << mimeType; - mStoreCollectionDialog->setLabelText( i18nc( "@label", "Please select a storage folder" ) ); - } - - // FIXME should be sub MIME type - mStoreCollectionDialog->setMimeType( QLatin1String( "text/calendar" ) ); - - const SubResourceBase *resource = 0; - while ( resource == 0 ) { - if ( mStoreCollectionDialog->exec() != QDialog::Accepted ) { - return 0; - } - - Akonadi::Collection collection = mStoreCollectionDialog->selectedCollection(); - if ( collection.isValid() ) { - resource = mModel.subResource( collection.id() ); - } - } - - return resource; -} - -Akonadi::Item ResourceAkonadi::Private::createItem( const QString &kresId ) -{ - Akonadi::Item item; - - Incidence *cachedIncidence = mCalendar.incidence( kresId ); - kDebug( 5800 ) << "kresId=" << kresId - << "cachedIncidence=" << (void*) cachedIncidence; - if ( cachedIncidence != 0 ) { - item.setMimeType( mMimeVisitor.mimeType( cachedIncidence ) ); - item.setPayload( IncidencePtr( cachedIncidence->clone() ) ); - } - - return item; -} - -Akonadi::Item ResourceAkonadi::Private::updateItem( const Akonadi::Item &item, const QString &kresId, const QString &originalId ) -{ - Akonadi::Item update( item ); - - Incidence *cachedIncidence = mCalendar.incidence( kresId ); - if ( cachedIncidence != 0 ) { - IncidencePtr incidencePtr( cachedIncidence->clone() ); - incidencePtr->setUid( originalId ); - - update.setPayload( incidencePtr ); - } - - return update; -} - -StoreConfigIface::CollectionsByMimeType ResourceAkonadi::Private::storeCollectionsFromOldDefault() const -{ - Q_ASSERT( mDefaultStoreCollection.isValid() ); - - CollectionsByMimeType storeCollections; - - // FIXME should be sub MIME type -// if ( Akonadi::MimeTypeChecker::isWantedCollection( mDefaultStoreCollection, KCal::MimeTypeVisitor::eventMimeType() ) ) { -// storeCollections[ KCal::MimeTypeVisitor::eventMimeType() ] = mDefaultStoreCollection; -// } -// if ( Akonadi::MimeTypeChecker::isWantedCollection( mDefaultStoreCollection, KCal::MimeTypeVisitor::todoMimeType() ) ) { -// storeCollections[ KCal::MimeTypeVisitor::todoMimeType() ] = mDefaultStoreCollection; -// } -// if ( Akonadi::MimeTypeChecker::isWantedCollection( mDefaultStoreCollection, KCal::MimeTypeVisitor::journalMimeType() ) ) { -// storeCollections[ KCal::MimeTypeVisitor::journalMimeType() ] = mDefaultStoreCollection; -// } - - storeCollections[ Akonadi::IncidenceMimeTypeVisitor::eventMimeType() ] = mDefaultStoreCollection; - storeCollections[ Akonadi::IncidenceMimeTypeVisitor::todoMimeType() ] = mDefaultStoreCollection; - storeCollections[ Akonadi::IncidenceMimeTypeVisitor::journalMimeType() ] = mDefaultStoreCollection; - - return storeCollections; -} - -void ResourceAkonadi::Private::calendarIncidenceAdded( Incidence *incidence ) -{ - Q_UNUSED( incidence ); - if ( mInternalCalendarModification ) { - return; - } - - // added to the calendar needs to be caught at resource level, e.g - // addEvent() method - Q_ASSERT( mUidToResourceMap.constFind( incidence->uid() ) != mUidToResourceMap.constEnd() ); -} - -void ResourceAkonadi::Private::calendarIncidenceChanged( Incidence *incidence ) -{ - if ( mInternalCalendarModification ) { - return; - } - - kDebug( 5800 ) << "Incidence (uid=" << incidence->uid() - << ", summary=" << incidence->summary() - << ")"; - - changeLocalItem( incidence->uid() ); -} - -void ResourceAkonadi::Private::calendarIncidenceDeleted( Incidence *incidence ) -{ - if ( mInternalCalendarModification ) { - return; - } - - kDebug( 5800 ) << "Incidence (uid=" << incidence->uid() - << ", summary=" << incidence->summary() - << ")"; - - removeLocalItem( incidence->uid() ); -} - -void ResourceAkonadi::Private::subResourceAdded( SubResourceBase *subResourceBase ) -{ - kDebug( 5800 ) << "id=" << subResourceBase->subResourceIdentifier(); - - SharedResourcePrivate::subResourceAdded( subResourceBase ); - - SubResource *subResource = qobject_cast( subResourceBase ); - - connect( subResource, SIGNAL(incidenceAdded(IncidencePtr,QString)), - this, SLOT(incidenceAdded(IncidencePtr,QString)) ); - connect( subResource, SIGNAL(incidenceChanged(IncidencePtr,QString)), - this, SLOT(incidenceChanged(IncidencePtr,QString)) ); - connect( subResource, SIGNAL(incidenceRemoved(QString,QString)), - this, SLOT(incidenceRemoved(QString,QString)) ); - - emit mParent->signalSubresourceAdded( mParent, QLatin1String( "calendar" ), subResourceBase->subResourceIdentifier(), subResourceBase->label() ); -} - -void ResourceAkonadi::Private::subResourceRemoved( SubResourceBase *subResourceBase ) -{ - kDebug( 5800 ) << "id=" << subResourceBase->subResourceIdentifier(); - - SharedResourcePrivate::subResourceRemoved( subResourceBase ); - - SubResource *subResource = qobject_cast( subResourceBase ); - - disconnect( subResource, SIGNAL(incidenceAdded(IncidencePtr,QString)), - this, SLOT(incidenceAdded(IncidencePtr,QString)) ); - disconnect( subResource, SIGNAL(incidenceChanged(IncidencePtr,QString)), - this, SLOT(incidenceChanged(IncidencePtr,QString)) ); - disconnect( subResource, SIGNAL(incidenceRemoved(QString,QString)), - this, SLOT(incidenceRemoved(QString,QString)) ); - - // block scope for BoolGuard - { - BoolGuard internalModification( mInternalCalendarModification, true ); - QMap::iterator it = mUidToResourceMap.begin(); - while ( it != mUidToResourceMap.end() ) { - if ( it.value() == subResourceBase->subResourceIdentifier() ) { - const QString uid = it.key(); - - mChanges.remove( uid ); - mIdArbiter->removeArbitratedId( uid ); - - Incidence *cachedIncidence = mCalendar.incidence( uid ); - if ( cachedIncidence != 0 ) { - mCalendar.deleteIncidence( cachedIncidence ); - } - - it = mUidToResourceMap.erase( it ); - } else { - ++it; - } - } - } - - emit mParent->signalSubresourceRemoved( mParent, QLatin1String( "calendar" ), subResourceBase->subResourceIdentifier() ); - - emit mParent->resourceChanged( mParent ); -} - -void ResourceAkonadi::Private::loadingResult( bool ok, const QString &errorString ) -{ - SharedResourcePrivate::loadingResult( ok, errorString ); - - if ( ok ) { - emit mParent->resourceLoaded( mParent ); - } else { - mParent->loadError( errorString ); - } -} - -void ResourceAkonadi::Private::savingResult( bool ok, const QString &errorString ) -{ - SharedResourcePrivate::savingResult( ok, errorString ); - - if ( ok ) { - emit mParent->resourceSaved( mParent ); - } else { - mParent->saveError( errorString ); - } -} - -void ResourceAkonadi::Private::incidenceAdded( const IncidencePtr &incidencePtr, const QString &subResourceIdentifier ) -{ - kDebug( 5800 ) << "Incidence (uid=" << incidencePtr->uid() - << ", summary=" << incidencePtr->summary() - << "), subResource=" << subResourceIdentifier; - - mChanges.remove( incidencePtr->uid() ); - - // check if we already have it, i.e. if it is the result of us saving it - if ( mCalendar.incidence( incidencePtr->uid() ) == 0 ) { - Incidence *incidence = incidencePtr->clone(); - - // block scope for BoolGuard - { - BoolGuard internalModification( mInternalCalendarModification, true ); - mCalendar.addIncidence( incidence ); - } - - mUidToResourceMap.insert( incidence->uid(), subResourceIdentifier ); - - if ( !isLoading() ) { - emit mParent->resourceChanged( mParent ); - } - } -} - -void ResourceAkonadi::Private::incidenceChanged( const IncidencePtr &incidencePtr, const QString &subResourceIdentifier ) -{ - kDebug( 5800 ) << "Incidence (uid=" << incidencePtr->uid() - << ", summary=" << incidencePtr->summary() - << "), subResource=" << subResourceIdentifier; - - mChanges.remove( incidencePtr->uid() ); - - Incidence *cachedIncidence = mCalendar.incidence( incidencePtr->uid() ); - if ( cachedIncidence == 0 ) { - kWarning( 5800 ) << "Incidence" << incidencePtr->uid() - << "changed but no longer in local list"; - return; - } - - // block scope for BoolGuard - { - BoolGuard internalModification( mInternalCalendarModification, true ); - // make sure any observer the resource might have installed gets properly notified - cachedIncidence->startUpdates(); - bool assignResult = mIncidenceAssigner.assign( cachedIncidence, incidencePtr.get() ); - if ( assignResult ) { - cachedIncidence->updated(); - } - cachedIncidence->endUpdates(); - - if ( !assignResult ) { - kWarning( 5800 ) << "Incidence (uid=" << cachedIncidence->uid() - << ", summary=" << cachedIncidence->summary() - << ") changed type. Replacing it."; - - mCalendar.deleteIncidence( cachedIncidence ); - mCalendar.addIncidence( incidencePtr->clone() ); - } - } - - if ( !isLoading() ) { - emit mParent->resourceChanged( mParent ); - } -} - -void ResourceAkonadi::Private::incidenceRemoved( const QString &uid, const QString &subResourceIdentifier ) -{ - kDebug( 5800 ) << "Incidence (uid=" << uid - << "), subResource=" << subResourceIdentifier; - - mUidToResourceMap.remove( uid ); - - Incidence *cachedIncidence = mCalendar.incidence( uid ); - if ( cachedIncidence == 0 ) { - kWarning() << "Incidence (uid=" << uid << ") no longer in local list"; - return; - } - - // block scope for BoolGuard - { - BoolGuard internalModification( mInternalCalendarModification, true ); - mCalendar.deleteIncidence( cachedIncidence ); - } - - if ( !isLoading() ) { - emit mParent->resourceChanged( mParent ); - } -} - - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/kcal/resourceakonadi_p.h kdepim-runtime-15.08.0/kresources/kcal/resourceakonadi_p.h --- kdepim-runtime-4.14.6/kresources/kcal/resourceakonadi_p.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kcal/resourceakonadi_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +0,0 @@ -/* - This file is part of libkcal. - Copyright (c) 2009 Kevin Krammer - - 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 KCAL_RESOURCEAKONADI_P_H -#define KCAL_RESOURCEAKONADI_P_H - -#include "subresource.h" -#include "resourceakonadi.h" -#include "sharedresourceprivate.h" - -#include -#include -#include - -namespace Akonadi { - class AgentFilterProxyModel; - class AgentInstanceModel; -} - -namespace KABC { - class LockNull; -} - -class KConfigGroup; - -class KCal::ResourceAkonadi::Private : public SharedResourcePrivate, - public KCal::Calendar::CalendarObserver -{ - Q_OBJECT - - public: - explicit Private( ResourceAkonadi *parent ); - - Private( const KConfigGroup &config, ResourceAkonadi *parent ); - - ~Private(); - - bool doSaveIncidence( Incidence *incidence ); - - QString subResourceIdentifier( const QString &incidenceUid ) const; - - public: - ResourceAkonadi *mParent; - - CalendarLocal mCalendar; - - KABC::LockNull *mLock; - - bool mInternalCalendarModification; - - AssignmentVisitor mIncidenceAssigner; - - Akonadi::IncidenceMimeTypeVisitor mMimeVisitor; - - Akonadi::AgentInstanceModel *mAgentModel; - Akonadi::AgentFilterProxyModel *mAgentFilterModel; - - protected: - bool openResource(); - - bool closeResource(); - - void clearResource(); - - void subResourceAdded( SubResourceBase *subResource ); - - void subResourceRemoved( SubResourceBase *subResource ); - - void loadingResult( bool ok, const QString &errorString ); - - void savingResult( bool ok, const QString &errorString ); - - const SubResourceBase *storeSubResourceFromUser( const QString &uid, const QString &mimeType ); - - Akonadi::Item createItem( const QString &kresId ); - - Akonadi::Item updateItem( const Akonadi::Item &item, const QString &kresId, const QString &originalId ); - - CollectionsByMimeType storeCollectionsFromOldDefault() const; - - // from the CalendarObserver interface - void calendarIncidenceAdded( KCal::Incidence *incidence ); - - void calendarIncidenceChanged( KCal::Incidence *incidence ); - - void calendarIncidenceDeleted( KCal::Incidence *incidence ); - - protected Q_SLOTS: - void incidenceAdded( const IncidencePtr &incidencePtr, const QString &subResourceIdentifier ); - - void incidenceChanged( const IncidencePtr &incidencePtr, const QString &subResourceIdentifier ); - - void incidenceRemoved( const QString &uid, const QString &subResourceIdentifier ); -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/kcal/resourceakonadiplugin.cpp kdepim-runtime-15.08.0/kresources/kcal/resourceakonadiplugin.cpp --- kdepim-runtime-4.14.6/kresources/kcal/resourceakonadiplugin.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kcal/resourceakonadiplugin.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -/* - This file is part of libkcal. - Copyright (c) 2008 Kevin Krammer - - 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 "resourceakonadi.h" -#include "resourceakonadiconfig.h" - -#include -#include - -using namespace KCal; - -class ResourceAkonadiKCalFactory : public KRES::PluginFactory -{ - public: - ResourceAkonadiKCalFactory() - : KRES::PluginFactory() - { - KGlobal::locale()->insertCatalog( QLatin1String( "kcal_akonadi" ) ); - } -}; - -K_EXPORT_PLUGIN(ResourceAkonadiKCalFactory) diff -Nru kdepim-runtime-4.14.6/kresources/kcal/subresource.cpp kdepim-runtime-15.08.0/kresources/kcal/subresource.cpp --- kdepim-runtime-4.14.6/kresources/kcal/subresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kcal/subresource.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,172 +0,0 @@ -/* - This file is part of libkcal. - Copyright (c) 2009 Kevin Krammer - - 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 "subresource.h" - -#include "concurrentjobs.h" - -#include - -#include -#include -#include - -using namespace KCal; - -QString IdArbiter::createArbitratedId() const -{ - // FIXME needs to be a calendar UID - QString id; - do { - id = CalFormat::createUniqueId(); - } while ( mArbitratedToOriginal.constFind( id ) != mArbitratedToOriginal.constEnd() ); - - return id; -} - -SubResource::SubResource( const Akonadi::Collection &collection ) - : SubResourceBase( collection ) -{ -} - -SubResource::~SubResource() -{ -} - -QStringList SubResource::supportedMimeTypes() -{ - return QStringList() << QLatin1String( "text/calendar" ); -} - -bool SubResource::createChildSubResource( const QString &resourceName ) -{ - if ( ( mCollection.rights() & Akonadi::Collection::CanCreateCollection ) == 0 ) { - kError( 5800 ) << "Parent collection does not allow creation of child collections"; - return false; - } - - Akonadi::Collection collection; - collection.setName( resourceName ); - collection.setParentCollection( mCollection ); - - // TODO should we set content mime types at all? - collection.setContentMimeTypes( mCollection.contentMimeTypes() ); - - ConcurrentCollectionCreateJob colCreateJob( collection ); - if ( !colCreateJob.exec() ) { - kError( 5800 ) << "CollectionCreateJob failed:" << colCreateJob->errorString(); - return false; - } - - return true; -} - -bool SubResource::remove() -{ - ConcurrentCollectionDeleteJob colDeleteJob( mCollection ); - if ( !colDeleteJob.exec() ) { - kError( 5800 ) << "CollectionDeleteJob failed:" << colDeleteJob->errorString(); - return false; - } - - return true; -} - -QString SubResource::subResourceType() const -{ - QStringList mimeTypes = mCollection.contentMimeTypes(); - mimeTypes.removeAll( Akonadi::Collection::mimeType() ); - if ( mimeTypes.count() > 1 ) - return QString(); // mixed - - KMimeType::Ptr mimeType = KMimeType::mimeType( mimeTypes[ 0 ], KMimeType::ResolveAliases ); - if ( !mimeType.isNull() ) { - if ( mimeType->is( QLatin1String( "application/x-vnd.akonadi.calendar.event" ) ) ) - return QLatin1String( "event" ); - - if ( mimeType->is( QLatin1String( "application/x-vnd.akonadi.calendar.todo" ) ) ) - return QLatin1String( "todo" ); - - if ( mimeType->is( QLatin1String( "application/x-vnd.akonadi.calendar.journal" ) ) ) - return QLatin1String( "journal" ); - } - - return QString(); -} - -void SubResource::itemAdded( const Akonadi::Item &item ) -{ - Q_ASSERT( mIdArbiter != 0 ); - - QString arbitratedId; - if ( item.hasPayload() ) { - IncidencePtr incidencePtr = item.payload(); - - arbitratedId = mIdArbiter->arbitrateOriginalId( incidencePtr->uid() ); - incidencePtr->setUid( arbitratedId ); - - emit incidenceAdded( incidencePtr, subResourceIdentifier() ); - } else { - kError( 5800 ) << "No IncidencePtr payload"; - return; - } - - mMappedItems.insert( arbitratedId, item ); - mMappedIds.insert( item.id(), arbitratedId ); -} - -void SubResource::itemChanged( const Akonadi::Item &item ) -{ - Q_ASSERT( mIdArbiter != 0 ); - - const QString kresId = mMappedIds.value( item.id() ); - Q_ASSERT( !kresId.isEmpty() ); - - if ( item.hasPayload() ) { - IncidencePtr incidencePtr = item.payload(); - - incidencePtr->setUid( kresId ); - - emit incidenceChanged( incidencePtr, subResourceIdentifier() ); - } else { - kError( 5800 ) << "No IncidencePtr payload"; - return; - } - - mMappedItems[ kresId ] = item; -} - -void SubResource::itemRemoved( const Akonadi::Item &item ) -{ - Q_ASSERT( mIdArbiter != 0 ); - - const QString kresId = mMappedIds.value( item.id() ); - Q_ASSERT( !kresId.isEmpty() ); - - emit incidenceRemoved( kresId, subResourceIdentifier() ); - - mMappedItems.remove( kresId ); - mMappedIds.remove( item.id() ); - - mIdArbiter->removeArbitratedId( kresId ); -} - - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/kcal/subresource.h kdepim-runtime-15.08.0/kresources/kcal/subresource.h --- kdepim-runtime-4.14.6/kresources/kcal/subresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/kcal/subresource.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -/* - This file is part of libkcal. - Copyright (c) 2009 Kevin Krammer - - 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 KCAL_RESOURCEAKONADI_SUBRESOURCE_H -#define KCAL_RESOURCEAKONADI_SUBRESOURCE_H - -#include "idarbiterbase.h" -#include "subresourcebase.h" - -#include - -#include - -typedef boost::shared_ptr IncidencePtr; - -class IdArbiter : public IdArbiterBase -{ - protected: - QString createArbitratedId() const; -}; - -class SubResource : public SubResourceBase -{ - Q_OBJECT - - public: - explicit SubResource( const Akonadi::Collection &collection ); - - ~SubResource(); - - static QStringList supportedMimeTypes(); - - bool createChildSubResource( const QString &resourceName ); - - bool remove(); - - QString subResourceType() const; - - Q_SIGNALS: - void incidenceAdded( const IncidencePtr &incidencePtr, const QString &subResourceIdentifier ); - - void incidenceChanged( const IncidencePtr &incidencePtr, const QString &subResourceIdentifier ); - - void incidenceRemoved( const QString &uid, const QString &subResourceIdentifier ); - - protected: - void itemAdded( const Akonadi::Item &item ); - - void itemChanged( const Akonadi::Item &item ); - - void itemRemoved( const Akonadi::Item &item ); -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/abstractsubresourcemodel.cpp kdepim-runtime-15.08.0/kresources/shared/abstractsubresourcemodel.cpp --- kdepim-runtime-4.14.6/kresources/shared/abstractsubresourcemodel.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/abstractsubresourcemodel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,316 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 "abstractsubresourcemodel.h" - -#include "concurrentjobs.h" -#include "itemfetchadapter.h" - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -using namespace Akonadi; - -class AbstractSubResourceModel::AsyncLoadContext -{ - public: - explicit AsyncLoadContext( AbstractSubResourceModel *parent ) - : mColFetchJob( 0 ), mResult( true ) - { - mColFetchJob = new CollectionFetchJob( Collection::root(), CollectionFetchJob::Recursive ); - - connect( mColFetchJob, SIGNAL(collectionsReceived(Akonadi::Collection::List)), - parent, SLOT(asyncCollectionsReceived(Akonadi::Collection::List)) ); - connect( mColFetchJob, SIGNAL(result(KJob*)), - parent, SLOT(asyncCollectionsResult(KJob*)) ); - } - - ~AsyncLoadContext() - { - delete mColFetchJob; - - qDeleteAll( mItemFetchJobs ); - } - - public: - CollectionFetchJob *mColFetchJob; - - QSet mItemFetchJobs; - - bool mResult; - QString mErrorString; -}; - -AbstractSubResourceModel::AbstractSubResourceModel( const QStringList &supportedMimeTypes, QObject *parent ) - : QObject( parent ), - mMonitor( new Monitor( this ) ), - mMimeChecker( new MimeTypeChecker() ), - mAsyncLoadContext( 0 ) -{ - mMimeChecker->setWantedMimeTypes( supportedMimeTypes ); - - mMonitor->blockSignals( true ); - - foreach ( const QString &mimeType, supportedMimeTypes ) { - mMonitor->setMimeTypeMonitored( mimeType ); - } - - mMonitor->setCollectionMonitored( Akonadi::Collection::root() ); - mMonitor->fetchCollection( true ); - mMonitor->itemFetchScope().fetchFullPayload(); - - connect( mMonitor, SIGNAL(collectionAdded(Akonadi::Collection,Akonadi::Collection)), - SLOT(monitorCollectionAdded(Akonadi::Collection)) ); - connect( mMonitor, SIGNAL(collectionChanged(Akonadi::Collection)), - SLOT(monitorCollectionChanged(Akonadi::Collection)) ); - connect( mMonitor, SIGNAL(collectionRemoved(Akonadi::Collection)), - SLOT(monitorCollectionRemoved(Akonadi::Collection)) ); - - connect( mMonitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)), - SLOT(monitorItemAdded(Akonadi::Item,Akonadi::Collection)) ); - connect( mMonitor, SIGNAL(itemChanged(Akonadi::Item,QSet)), - SLOT(monitorItemChanged(Akonadi::Item)) ); - connect( mMonitor, SIGNAL(itemRemoved(Akonadi::Item)), - SLOT(monitorItemRemoved(Akonadi::Item)) ); -} - -AbstractSubResourceModel::~AbstractSubResourceModel() -{ - delete mAsyncLoadContext; - delete mMimeChecker; -} - -QStringList AbstractSubResourceModel::subResourceIdentifiers() const -{ - return mSubResourceIdentifiers.toList(); -} - -void AbstractSubResourceModel::startMonitoring() -{ - mMonitor->blockSignals( false ); -} - -void AbstractSubResourceModel::stopMonitoring() -{ - mMonitor->blockSignals( true ); -} - -void AbstractSubResourceModel::clear() -{ - clearModel(); - - mSubResourceIdentifiers.clear(); -} - -bool AbstractSubResourceModel::load() -{ - ConcurrentCollectionFetchJob colFetchJob; - - if ( !colFetchJob.exec() ) { - kError( 5650 ) << "Loading collections failed:" << colFetchJob->errorString(); - emit loadingResult( false, colFetchJob->errorString() ); - return false; - } - - const Collection::List collections = colFetchJob->collections(); - foreach ( const Collection &collection, collections ) { - if ( mMimeChecker->isWantedCollection( collection ) ) { - collectionAdded( collection ); - mMonitor->setCollectionMonitored( collection ); - ConcurrentItemFetchJob itemFetchJob( collection ); - if ( !itemFetchJob.exec() ) { - kError( 5650 ) << "Loading items for collection (id=" << collection.id() - << ", remoteId=" << collection.remoteId() - << "failed:" << itemFetchJob->errorString(); - emit loadingResult( false, itemFetchJob->errorString() ); - return false; - } - - const Item::List items = itemFetchJob->items(); - foreach ( const Item &item, items ) { - if ( mMimeChecker->isWantedItem( item ) ) { - itemAdded( item, collection ); - } - } - } - } - - emit loadingResult( true, QString() ); - return true; -} - -bool AbstractSubResourceModel::asyncLoad() -{ - if ( mAsyncLoadContext != 0 ) { - const QString message = i18nc( "@info:status", "Loading already in progress" ); - emit loadingResult( false, message ); - return false; - } - - mAsyncLoadContext = new AsyncLoadContext( this ); - - return true; -} - -void AbstractSubResourceModel::monitorCollectionAdded( const Akonadi::Collection &collection ) -{ - // TODO check whether we need to do something while an async load is in progress - if ( mMimeChecker->isWantedCollection( collection ) ) { - collectionAdded( collection ); - } -} - -void AbstractSubResourceModel::monitorCollectionChanged( const Akonadi::Collection &collection ) -{ - // TODO check whether we need to do something while an async load is in progress - if ( mMimeChecker->isWantedCollection( collection ) ) { - collectionChanged( collection ); - } -} - -void AbstractSubResourceModel::monitorCollectionRemoved( const Akonadi::Collection &collection ) -{ - // TODO check whether we need to do something while an async load is in progress - mMonitor->setCollectionMonitored( collection, false ); - collectionRemoved( collection ); -} - -void AbstractSubResourceModel::monitorItemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ) -{ - // TODO check whether we need to do something while an async load is in progress - if ( mMimeChecker->isWantedItem( item ) ) { - itemAdded( item, collection ); - } -} - -void AbstractSubResourceModel::monitorItemChanged( const Akonadi::Item &item ) -{ - // TODO check whether we need to do something while an async load is in progress - if ( mMimeChecker->isWantedItem( item ) ) { - itemChanged( item ); - } -} - -void AbstractSubResourceModel::monitorItemRemoved( const Akonadi::Item &item ) -{ - // TODO check whether we need to do something while an async load is in progress - if ( mMimeChecker->isWantedItem( item ) ) { - itemRemoved( item ); - } -} - -void AbstractSubResourceModel::asyncCollectionsReceived( const Akonadi::Collection::List &collections ) -{ - AsyncLoadContext *context = mAsyncLoadContext; - if ( context == 0 ) { - return; - } - - foreach ( const Collection &collection, collections ) { - if ( mMimeChecker->isWantedCollection( collection ) ) { - collectionAdded( collection ); - mMonitor->setCollectionMonitored( collection ); - - context->mItemFetchJobs.insert( new ItemFetchAdapter( collection, this ) ); - } - } -} - -void AbstractSubResourceModel::asyncCollectionsResult( KJob *job ) -{ - AsyncLoadContext *context = mAsyncLoadContext; - if ( context == 0 ) { - return; - } - - Q_ASSERT( job == context->mColFetchJob ); - - context->mColFetchJob = 0; - - if ( job->error() != 0 ) { - mAsyncLoadContext = 0; - - kError( 5650 ) << "Loading collections failed:" << job->errorString(); - emit loadingResult( false, job->errorString() ); - - delete context; - return; - } - - if ( context->mItemFetchJobs.isEmpty() ) { - mAsyncLoadContext = 0; - - emit loadingResult( true, QString() ); - - delete context; - } -} - -void AbstractSubResourceModel::asyncItemsReceived( const Akonadi::Collection &collection, const Akonadi::Item::List &items ) -{ - foreach ( const Item &item, items ) { - if ( mMimeChecker->isWantedItem( item ) ) { - itemAdded( item, collection ); - } - } -} - -void AbstractSubResourceModel::asyncItemsResult( ItemFetchAdapter *fetcher, KJob *job ) -{ - AsyncLoadContext *context = mAsyncLoadContext; - if ( context == 0 ) { - return; - } - - context->mItemFetchJobs.remove( fetcher ); - - if ( job->error() != 0 ) { - mAsyncLoadContext = 0; - - const Collection collection = fetcher->collection(); - kError( 5650 ) << "Loading items for collection (id=" << collection.id() - << ", remoteId=" << collection.remoteId() - << "failed:" << job->errorString(); - emit loadingResult( false, job->errorString() ); - - delete context; - return; - } - - if ( context->mColFetchJob == 0 && mAsyncLoadContext->mItemFetchJobs.isEmpty() ) { - mAsyncLoadContext = 0; - - emit loadingResult( true, QString() ); - - delete context; - } -} - - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/abstractsubresourcemodel.h kdepim-runtime-15.08.0/kresources/shared/abstractsubresourcemodel.h --- kdepim-runtime-4.14.6/kresources/shared/abstractsubresourcemodel.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/abstractsubresourcemodel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,123 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_ABSTRACTSUBRESOURCEMODEL_H -#define KRES_AKONADI_ABSTRACTSUBRESOURCEMODEL_H - -#include -#include - -#include -#include - -namespace Akonadi { - class MimeTypeChecker; - class Monitor; -} - -class ItemFetchAdapter; -class KJob; - -typedef QSet StringIdSet; -class QStringList; -class SubResourceBase; - -class AbstractSubResourceModel : public QObject -{ - Q_OBJECT - - public: - AbstractSubResourceModel( const QStringList &supportedMimeTypes, QObject *parent ); - - virtual ~AbstractSubResourceModel(); - - QStringList subResourceIdentifiers() const; - - void startMonitoring(); - - void stopMonitoring(); - - void clear(); - - bool load(); - - bool asyncLoad(); - - virtual SubResourceBase *subResourceBase( Akonadi::Collection::Id colId ) const = 0; - - Q_SIGNALS: - void subResourceAdded( SubResourceBase *subResource ); - - void subResourceRemoved( SubResourceBase *subResource ); - - void loadingResult( bool ok, const QString &errorString ); - - protected: - Akonadi::Monitor *mMonitor; - Akonadi::MimeTypeChecker *mMimeChecker; - - StringIdSet mSubResourceIdentifiers; - - protected: - virtual void clearModel() = 0; - - virtual void collectionAdded( const Akonadi::Collection &collection ) = 0; - - virtual void collectionChanged( const Akonadi::Collection &collection ) = 0; - - virtual void collectionRemoved( const Akonadi::Collection &collection ) = 0; - - virtual void itemAdded( const Akonadi::Item &item, - const Akonadi::Collection &collection ) = 0; - - virtual void itemChanged( const Akonadi::Item &item ) = 0; - - virtual void itemRemoved( const Akonadi::Item &item ) = 0; - - private: - class AsyncLoadContext; - AsyncLoadContext *mAsyncLoadContext; - - private Q_SLOTS: - void monitorCollectionAdded( const Akonadi::Collection &collection ); - - void monitorCollectionChanged( const Akonadi::Collection &collection ); - - void monitorCollectionRemoved( const Akonadi::Collection &collection ); - - void monitorItemAdded( const Akonadi::Item &item, - const Akonadi::Collection &collection ); - - void monitorItemChanged( const Akonadi::Item &item ); - - void monitorItemRemoved( const Akonadi::Item &item ); - - void asyncCollectionsReceived( const Akonadi::Collection::List &collections ); - - void asyncCollectionsResult( KJob *job ); - - void asyncItemsReceived( const Akonadi::Collection &collection, const Akonadi::Item::List &items ); - - void asyncItemsResult( ItemFetchAdapter *fetcher, KJob *job ); -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/concurrentjobs.cpp kdepim-runtime-15.08.0/kresources/shared/concurrentjobs.cpp --- kdepim-runtime-4.14.6/kresources/shared/concurrentjobs.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/concurrentjobs.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,166 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 "concurrentjobs.h" - -#include "itemsavecontext.h" - -#include - -using namespace Akonadi; - -ConcurrentJobBase::~ConcurrentJobBase() -{ -} - -ConcurrentJobBase::JobRunner::JobRunner( ConcurrentJobBase *parent ) - : QThread(), mParent( parent ) -{ - Q_ASSERT( mParent != 0 ); -} - -void ConcurrentJobBase::JobRunner::run() -{ - QMutexLocker mutexLocker( &( mParent->mMutex ) ); - - mParent->createJob(); - Job *job = mParent->job(); - Q_ASSERT( job != 0 ); - - mParent->mRunnerResult = job->exec(); - if ( mParent->mRunnerResult ) { - mParent->handleSuccess(); - } else { - mParent->mErrorString = job->errorString(); - } - - delete job; - - mParent->mCondition.wakeAll(); -} - -const ConcurrentCollectionFetchJob *ConcurrentCollectionFetchJob::operator->() const -{ - return this; -} - -Collection::List ConcurrentCollectionFetchJob::collections() const -{ - return mCollections; -} - -void ConcurrentCollectionFetchJob::createJob() -{ - mJob = new CollectionFetchJob( Collection::root(), CollectionFetchJob::Recursive ); -} - -void ConcurrentCollectionFetchJob::handleSuccess() -{ - mCollections = mJob->collections(); -} - -ConcurrentItemFetchJob::ConcurrentItemFetchJob( const Collection &collection ) - : ConcurrentJob(), - mCollection( collection ) -{ -} - -const ConcurrentItemFetchJob *ConcurrentItemFetchJob::operator->() const -{ - return this; -} - -Item::List ConcurrentItemFetchJob::items() const -{ - return mItems; -} - -void ConcurrentItemFetchJob::createJob() -{ - mJob = new ItemFetchJob( mCollection ); - mJob->fetchScope().fetchFullPayload(); -} - -void ConcurrentItemFetchJob::handleSuccess() -{ - mItems = mJob->items(); -} - -ConcurrentItemSaveJob::ConcurrentItemSaveJob( const ItemSaveContext &saveContext ) - : ConcurrentJob(), - mSaveContext( saveContext ) -{ -} - -const ConcurrentItemSaveJob *ConcurrentItemSaveJob::operator->() const -{ - return this; -} - -void ConcurrentItemSaveJob::createJob() -{ - mJob = new ItemSaveJob( mSaveContext ); -} - -void ConcurrentItemSaveJob::handleSuccess() -{ -} - -ConcurrentCollectionCreateJob::ConcurrentCollectionCreateJob( const Akonadi::Collection &collection ) - : ConcurrentJob(), - mCollection( collection ) -{ -} - -const ConcurrentCollectionCreateJob *ConcurrentCollectionCreateJob::operator->() const -{ - return this; -} - -void ConcurrentCollectionCreateJob::createJob() -{ - mJob = new CollectionCreateJob( mCollection ); -} - -void ConcurrentCollectionCreateJob::handleSuccess() -{ -} - -ConcurrentCollectionDeleteJob::ConcurrentCollectionDeleteJob( const Akonadi::Collection &collection ) - : ConcurrentJob(), - mCollection( collection ) -{ -} - -const ConcurrentCollectionDeleteJob *ConcurrentCollectionDeleteJob::operator->() const -{ - return this; -} - -void ConcurrentCollectionDeleteJob::createJob() -{ - mJob = new CollectionDeleteJob( mCollection ); -} - -void ConcurrentCollectionDeleteJob::handleSuccess() -{ -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/concurrentjobs.h kdepim-runtime-15.08.0/kresources/shared/concurrentjobs.h --- kdepim-runtime-4.14.6/kresources/shared/concurrentjobs.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/concurrentjobs.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,195 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_CONCURRENTJOBS_H -#define KRES_AKONADI_CONCURRENTJOBS_H - -#include "itemsavejob.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -class ItemSaveContext; - -class ConcurrentJobBase -{ - public: - virtual ~ConcurrentJobBase(); - - QString errorString() const - { - return mErrorString; - } - - protected: - bool mRunnerResult; - - QString mErrorString; - - QMutex mMutex; - QWaitCondition mCondition; - - protected: - virtual void createJob() = 0; - - virtual void handleSuccess() = 0; - - virtual Akonadi::Job *job() = 0; - - class JobRunner : public QThread - { - public: - JobRunner( ConcurrentJobBase *parent ); - - protected: - void run(); - - private: - ConcurrentJobBase *mParent; - }; -}; - -template -class ConcurrentJob : public ConcurrentJobBase -{ - public: - ConcurrentJob() : mJob( 0 ) {} - - virtual ~ConcurrentJob() {} - - bool exec() - { - JobRunner *runner = new JobRunner( this ); - QObject::connect( runner, SIGNAL( finished() ), runner, SLOT( deleteLater() ) ); - - QMutexLocker mutexLocker( &mMutex ); - - runner->start(); - - mCondition.wait( &mMutex ); - - return mRunnerResult; - } - - protected: - JobClass *mJob; - - protected: - Akonadi::Job *job() - { - return mJob; - } -}; - -class ConcurrentCollectionFetchJob : public ConcurrentJob -{ - public: - const ConcurrentCollectionFetchJob *operator->() const; - - Akonadi::Collection::List collections() const; - - protected: - Akonadi::Collection::List mCollections; - - protected: - void createJob(); - - void handleSuccess(); -}; - -class ConcurrentItemFetchJob : public ConcurrentJob -{ - public: - ConcurrentItemFetchJob( const Akonadi::Collection &collection ); - - const ConcurrentItemFetchJob *operator->() const; - - Akonadi::Item::List items() const; - - protected: - const Akonadi::Collection mCollection; - Akonadi::Item::List mItems; - - protected: - void createJob(); - - void handleSuccess(); -}; - -class ConcurrentItemSaveJob : public ConcurrentJob -{ - public: - ConcurrentItemSaveJob( const ItemSaveContext &saveContext ); - - const ConcurrentItemSaveJob *operator->() const; - - protected: - const ItemSaveContext &mSaveContext; - - protected: - void createJob(); - - void handleSuccess(); -}; - -class ConcurrentCollectionCreateJob : public ConcurrentJob -{ - public: - ConcurrentCollectionCreateJob( const Akonadi::Collection &collection ); - - const ConcurrentCollectionCreateJob *operator->() const; - - protected: - Akonadi::Collection mCollection; - - protected: - void createJob(); - - void handleSuccess(); -}; - -class ConcurrentCollectionDeleteJob : public ConcurrentJob -{ - public: - ConcurrentCollectionDeleteJob( const Akonadi::Collection &collection ); - - const ConcurrentCollectionDeleteJob *operator->() const; - - protected: - Akonadi::Collection mCollection; - - protected: - void createJob(); - - void handleSuccess(); -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/idarbiterbase.cpp kdepim-runtime-15.08.0/kresources/shared/idarbiterbase.cpp --- kdepim-runtime-4.14.6/kresources/shared/idarbiterbase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/idarbiterbase.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 "idarbiterbase.h" - -IdArbiterBase::~IdArbiterBase() -{ -} - -QString IdArbiterBase::arbitrateOriginalId( const QString &originalId ) -{ - const IdSet arbitratedIds = mapToArbitratedIds( originalId ); - QString arbitratedId; - if ( arbitratedIds.contains( originalId ) ) { - arbitratedId = createArbitratedId(); - } else { - arbitratedId = originalId; - } - - mOriginalToArbitrated[ originalId ].insert( arbitratedId ); - mArbitratedToOriginal.insert( arbitratedId, originalId ); - - return arbitratedId; -} - -QString IdArbiterBase::mapToOriginalId( const QString &arbitratedId ) const -{ - const IdMapping::const_iterator findIt = mArbitratedToOriginal.constFind( arbitratedId ); - if ( findIt != mArbitratedToOriginal.constEnd() ) { - return findIt.value(); - } - - return QString(); -} - -void IdArbiterBase::clear() -{ - mOriginalToArbitrated.clear(); - mArbitratedToOriginal.clear(); -} - -QString IdArbiterBase::removeArbitratedId( const QString &arbitratedId ) -{ - IdMapping::iterator findIt = mArbitratedToOriginal.find( arbitratedId ); - if ( findIt != mArbitratedToOriginal.end() ) { - const QString orignalId = findIt.value(); - - IdSetMapping::iterator origIt = mOriginalToArbitrated.find( orignalId ); - origIt.value().remove( arbitratedId ); - if ( origIt.value().isEmpty() ) { - mOriginalToArbitrated.erase( origIt ); - } - - mArbitratedToOriginal.erase( findIt ); - return orignalId; - } - - return QString(); -} - -IdArbiterBase::IdSet IdArbiterBase::mapToArbitratedIds( const QString &originalId ) const -{ - const IdSetMapping::const_iterator findIt = mOriginalToArbitrated.constFind( originalId ); - if ( findIt != mOriginalToArbitrated.constEnd() ) { - return findIt.value(); - } - - return IdSet(); -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/idarbiterbase.h kdepim-runtime-15.08.0/kresources/shared/idarbiterbase.h --- kdepim-runtime-4.14.6/kresources/shared/idarbiterbase.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/idarbiterbase.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_IDARBITERBASE_H -#define KRES_AKONADI_IDARBITERBASE_H - -#include -#include - -class IdArbiterBase -{ - public: - virtual ~IdArbiterBase(); - - QString arbitrateOriginalId( const QString &originalId ); - - QString removeArbitratedId( const QString &arbitratedId ); - - QString mapToOriginalId( const QString &arbitratedId ) const; - - void clear(); - - protected: - typedef QSet IdSet; - typedef QHash IdMapping; - typedef QHash IdSetMapping; - IdSetMapping mOriginalToArbitrated; - IdMapping mArbitratedToOriginal; - - protected: - IdSet mapToArbitratedIds( const QString &originalId ) const; - - virtual QString createArbitratedId() const = 0; -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/itemfetchadapter.cpp kdepim-runtime-15.08.0/kresources/shared/itemfetchadapter.cpp --- kdepim-runtime-4.14.6/kresources/shared/itemfetchadapter.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/itemfetchadapter.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 "itemfetchadapter.h" - -#include -#include - -using namespace Akonadi; - -ItemFetchAdapter::ItemFetchAdapter( const Collection &collection, QObject *parent ) - : QObject( parent ), mCollection( collection ) -{ - ItemFetchJob *job = new ItemFetchJob( mCollection, this ); - job->fetchScope().fetchFullPayload(); - - connect( job, SIGNAL(itemsReceived(Akonadi::Item::List)), - SLOT(jobItemsReceived(Akonadi::Item::List)) ), - connect( job, SIGNAL(result(KJob*)), - SLOT (jobResult(KJob*)) ); - - connect( this, SIGNAL(itemsReceived(Akonadi::Collection,Akonadi::Item::List)), - parent, SLOT(asyncItemsReceived(Akonadi::Collection,Akonadi::Item::List)) ); - - connect( this, SIGNAL(result(ItemFetchAdapter*,KJob*)), - parent, SLOT(asyncItemsResult(ItemFetchAdapter*,KJob*)) ); -} - -Collection ItemFetchAdapter::collection() const -{ - return mCollection; -} - -void ItemFetchAdapter::jobItemsReceived( const Item::List &items ) -{ - emit itemsReceived( mCollection, items ); -} - -void ItemFetchAdapter::jobResult( KJob *job ) -{ - emit result( this, job ); -} - - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/itemfetchadapter.h kdepim-runtime-15.08.0/kresources/shared/itemfetchadapter.h --- kdepim-runtime-4.14.6/kresources/shared/itemfetchadapter.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/itemfetchadapter.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_ITEMFETCHADAPTER_H -#define KRES_AKONADI_ITEMFETCHADAPTER_H - -#include -#include - -#include - -class KJob; - -class ItemFetchAdapter : public QObject -{ - Q_OBJECT - - public: - ItemFetchAdapter( const Akonadi::Collection &collection, QObject *parent ); - - Akonadi::Collection collection() const; - - Q_SIGNALS: - void itemsReceived( const Akonadi::Collection &collection, const Akonadi::Item::List &items ); - - void result( ItemFetchAdapter* fetcher, KJob *job ); - - protected: - const Akonadi::Collection mCollection; - - protected Q_SLOTS: - void jobItemsReceived( const Akonadi::Item::List &items ); - void jobResult( KJob *job ); -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/itemsavecontext.h kdepim-runtime-15.08.0/kresources/shared/itemsavecontext.h --- kdepim-runtime-4.14.6/kresources/shared/itemsavecontext.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/itemsavecontext.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_ITEMSAVECONTEXT_H -#define KRES_AKONADI_ITEMSAVECONTEXT_H - -#include -#include - -class ItemAddContext -{ - public: - typedef QList List; - - public: - Akonadi::Item item; - Akonadi::Collection collection; -}; - -class ItemSaveContext -{ -public: - ItemAddContext::List addedItems; - Akonadi::Item::List changedItems; - Akonadi::Item::List removedItems; -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/itemsavejob.cpp kdepim-runtime-15.08.0/kresources/shared/itemsavejob.cpp --- kdepim-runtime-4.14.6/kresources/shared/itemsavejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/itemsavejob.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 "itemsavejob.h" - -#include "itemsavecontext.h" - -#include -#include -#include - -#include - -using namespace Akonadi; - -ItemSaveJob::ItemSaveJob( const ItemSaveContext &saveContext ) -{ - foreach ( const ItemAddContext &addContext, saveContext.addedItems ) { - kDebug( 5650 ) << "CreateJob for Item (mimeType=" << addContext.item.mimeType() - << "), collection (id=" << addContext.collection.id() - << ", remoteId=" << addContext.collection.remoteId() - << ")"; - (void)new ItemCreateJob( addContext.item, addContext.collection, this ); - } - - foreach ( const Item &item, saveContext.changedItems ) { - kDebug( 5650 ) << "ModifyJob for Item (id=" << item.id() - << ", remoteId=" << item.remoteId() - << ", mimeType=" << item.mimeType() - << ")"; - (void)new ItemModifyJob( item, this ); - } - - foreach ( const Item &item, saveContext.removedItems ) { - kDebug( 5650 ) << "DeleteJob for Item (id=" << item.id() - << ", remoteId=" << item.remoteId() - << ", mimeType=" << item.mimeType() - << ")"; - (void)new ItemDeleteJob( item, this ); - } -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/itemsavejob.h kdepim-runtime-15.08.0/kresources/shared/itemsavejob.h --- kdepim-runtime-4.14.6/kresources/shared/itemsavejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/itemsavejob.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_ITEMSAVEJOB_H -#define KRES_AKONADI_ITEMSAVEJOB_H - -#include - -class ItemSaveContext; - -class ItemSaveJob : public Akonadi::TransactionSequence -{ - public: - ItemSaveJob( const ItemSaveContext &saveContext ); -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/Messages.sh kdepim-runtime-15.08.0/kresources/shared/Messages.sh --- kdepim-runtime-4.14.6/kresources/shared/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -#! /bin/sh -$XGETTEXT *.cpp -o $podir/kresources_shared_akonadi.pot diff -Nru kdepim-runtime-4.14.6/kresources/shared/resourceconfigbase.cpp kdepim-runtime-15.08.0/kresources/shared/resourceconfigbase.cpp --- kdepim-runtime-4.14.6/kresources/shared/resourceconfigbase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/resourceconfigbase.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,238 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 "resourceconfigbase.h" - -#include "sharedresourceiface.h" -#include "storecollectionmodel.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -class AkonadiResourceDialog : public KDialog -{ - public: - AkonadiResourceDialog( const QStringList &mimeList, QWidget *parent ) - : KDialog( parent ) - { - QWidget *widget = KCModuleLoader::loadModule( "kcm_akonadi_resources", - KCModuleLoader::Inline, this, mimeList ); - setMainWidget( widget ); - - setButtons( Close ); - setDefaultButton( Close ); - } -}; - -ResourceConfigBase::ResourceConfigBase( const QStringList &mimeList, QWidget *parent ) - : KRES::ConfigWidget( parent ), - mCollectionView( 0 ), - mButtonBox( 0 ), - mSyncAction( 0 ), - mSyncButton( 0 ), - mInfoTextLabel( 0 ), - mSourcesDialog( 0 ), - mSourcesButton( 0 ) -{ - Akonadi::Control::start( this ); - QVBoxLayout *mainLayout = new QVBoxLayout( this ); - mainLayout->setMargin( KDialog::marginHint() ); - mainLayout->setSpacing( KDialog::spacingHint() ); - - mCollectionModel = new Akonadi::StoreCollectionModel( this ); - - QWidget *widget = new QWidget( this ); - - QHBoxLayout *collectionLayout = new QHBoxLayout( widget ); - collectionLayout->setMargin( KDialog::marginHint() ); - collectionLayout->setSpacing( KDialog::spacingHint() ); - - Akonadi::CollectionFilterProxyModel *filterModel = - new Akonadi::CollectionFilterProxyModel( this ); - filterModel->addMimeTypeFilters( mimeList ); - filterModel->setSourceModel( mCollectionModel ); - - mCollectionView = new Akonadi::CollectionView( widget ); - mCollectionView->setSelectionMode( QAbstractItemView::SingleSelection ); - mCollectionView->setModel( filterModel ); - mCollectionView->header()->setResizeMode( QHeaderView::ResizeToContents ); - - connect( mCollectionView, SIGNAL(currentChanged(Akonadi::Collection)), - this, SLOT(collectionChanged(Akonadi::Collection)) ); - - collectionLayout->addWidget( mCollectionView ); - - KActionCollection *actionCollection = new KActionCollection( this ); - - Akonadi::StandardActionManager *actionManager = - new Akonadi::StandardActionManager( actionCollection, this ); - actionManager->setCollectionSelectionModel( mCollectionView->selectionModel() ); - - mSyncAction = actionManager->createAction( Akonadi::StandardActionManager::SynchronizeCollections ); - - mButtonBox = new QDialogButtonBox( Qt::Vertical, widget ); - collectionLayout->addWidget( mButtonBox ); - - mSyncButton = new QPushButton( mSyncAction->text() ); - mSyncButton->setIcon( mSyncAction->icon() ); - mButtonBox->addButton( mSyncButton, QDialogButtonBox::ActionRole ); - connect( mSyncButton, SIGNAL(clicked()), mSyncAction, SLOT(trigger()) ); - mSourcesDialog = new AkonadiResourceDialog( mimeList, this ); - - mSourcesButton = new QPushButton( this ); - mButtonBox->addButton( mSourcesButton, QDialogButtonBox::ActionRole ); - - connect( mSourcesButton, SIGNAL(clicked()), mSourcesDialog, SLOT(show()) ); - - mInfoTextLabel = new QLabel( this ); - mInfoTextLabel->setWordWrap( true ); - - mainLayout->addWidget( mInfoTextLabel ); - mainLayout->addWidget( widget ); - - updateCollectionButtonState(); - - connect( actionManager, SIGNAL(actionStateUpdated()), - this, SLOT(updateCollectionButtonState()) ); -} - -ResourceConfigBase::~ResourceConfigBase() -{ -} - -void ResourceConfigBase::loadSettings( KRES::Resource *resource ) -{ - SharedResourceIface* akonadiResource = dynamic_cast( resource ); - if ( akonadiResource == 0 ) { - kError( 5650 ) << "Given resource is not an Akonadi bridge"; - return; - } - - Akonadi::StoreCollectionModel::StoreItemsByCollection storeMapping; - - mStoreCollections = akonadiResource->storeConfig().storeCollectionsByMimeType(); - StoreConfigIface::CollectionsByMimeType::const_iterator it = mStoreCollections.constBegin(); - StoreConfigIface::CollectionsByMimeType::const_iterator endIt = mStoreCollections.constEnd(); - for ( ; it != endIt; ++it ) { - storeMapping[ it.value().id() ] << mItemTypes[ it.key() ]; - } - - mCollectionModel->setStoreMapping( storeMapping ); -} - -void ResourceConfigBase::saveSettings( KRES::Resource *resource ) -{ - SharedResourceIface* akonadiResource = dynamic_cast( resource ); - if ( akonadiResource == 0 ) { - kError( 5650 ) << "Given resource is not an Akonadi bridge"; - return; - } - - akonadiResource->storeConfig().setStoreCollectionsByMimeType( mStoreCollections ); -} - -void ResourceConfigBase::connectMimeCheckBoxes() -{ - foreach ( const QCheckBox *checkBox, mMimeCheckBoxes ) { - connect( checkBox, SIGNAL(toggled(bool)), SLOT(mimeCheckBoxToggled(bool)) ); - } -} - -void ResourceConfigBase::updateCollectionButtonState() -{ - mSyncButton->setEnabled( mSyncAction->isEnabled() ); -} - -void ResourceConfigBase::collectionChanged( const Akonadi::Collection &collection ) -{ - mCollection = collection; - - MimeCheckBoxes::const_iterator it = mMimeCheckBoxes.constBegin(); - MimeCheckBoxes::const_iterator endIt = mMimeCheckBoxes.constEnd(); - for ( ; it != endIt; ++it ) { - const QString mimeType = it.key(); - QCheckBox *checkBox = it.value(); - - checkBox->blockSignals( true ); - checkBox->setChecked( mStoreCollections.value( mimeType, Akonadi::Collection() ) == mCollection ); - checkBox->blockSignals( false ); - - checkBox->setEnabled( mCollection.isValid() ); - } -} - -void ResourceConfigBase::mimeCheckBoxToggled( bool checked ) -{ - QString mimeType; - QCheckBox *checkBox = 0; - MimeCheckBoxes::const_iterator it = mMimeCheckBoxes.constBegin(); - MimeCheckBoxes::const_iterator endIt = mMimeCheckBoxes.constEnd(); - for ( ; it != endIt; ++it ) { - if ( it.value() == QObject::sender() ) { - mimeType = it.key(); - checkBox = it.value(); - break; - } - } - - Q_ASSERT( !mimeType.isEmpty() && checkBox != 0 ); - - const QString itemType = mItemTypes.value( mimeType, QString() ); - - Akonadi::StoreCollectionModel::StoreItemsByCollection storeMapping = mCollectionModel->storeMapping(); - - if ( checked ) { - Akonadi::StoreCollectionModel::StoreItemsByCollection::iterator it = - storeMapping.begin(); - Akonadi::StoreCollectionModel::StoreItemsByCollection::iterator endIt = - storeMapping.end(); - for ( ; it != endIt; ++it ) { - it.value().removeAll( itemType ); - } - - storeMapping[ mCollection.id() ] << itemType; - mStoreCollections[ mimeType ] = mCollection; - } else { - storeMapping[ mCollection.id() ].removeAll( itemType ); - mStoreCollections.remove( mimeType ); - } - - mCollectionModel->setStoreMapping( storeMapping ); -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/resourceconfigbase.h kdepim-runtime-15.08.0/kresources/shared/resourceconfigbase.h --- kdepim-runtime-4.14.6/kresources/shared/resourceconfigbase.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/resourceconfigbase.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_RESOURCECONFIGBASE_H -#define KRES_AKONADI_RESOURCECONFIGBASE_H - -#include "storeconfigiface.h" - -#include - -#include - -#include - -namespace Akonadi { - class CollectionView; - class StoreCollectionModel; -} - -class KAction; -class KDialog; -class QCheckBox; -class QDialogButtonBox; -class QLabel; -class QPushButton; - -class ResourceConfigBase : public KRES::ConfigWidget -{ - Q_OBJECT - - public: - explicit ResourceConfigBase( const QStringList &mimeList, QWidget *parent = 0 ); - - ~ResourceConfigBase(); - - public Q_SLOTS: - void loadSettings( KRES::Resource *resource ); - - void saveSettings( KRES::Resource *resource ); - - protected: - const QStringList mMimeList; - - typedef QHash ItemTypesByMimeType; - ItemTypesByMimeType mItemTypes; - - Akonadi::Collection mCollection; - - Akonadi::StoreCollectionModel *mCollectionModel; - Akonadi::CollectionView *mCollectionView; - - QDialogButtonBox *mButtonBox; - - typedef QHash MimeCheckBoxes; - MimeCheckBoxes mMimeCheckBoxes; - - StoreConfigIface::CollectionsByMimeType mStoreCollections; - - KAction *mSyncAction; - QPushButton *mSyncButton; - - QLabel *mInfoTextLabel; - - KDialog *mSourcesDialog; - QPushButton *mSourcesButton; - - protected: - void connectMimeCheckBoxes(); - - private Q_SLOTS: - void updateCollectionButtonState(); - - void collectionChanged( const Akonadi::Collection &collection ); - - void mimeCheckBoxToggled( bool checked ); -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/resourceprivatebase.cpp kdepim-runtime-15.08.0/kresources/shared/resourceprivatebase.cpp --- kdepim-runtime-4.14.6/kresources/shared/resourceprivatebase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/resourceprivatebase.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,508 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 "resourceprivatebase.h" - -#include "concurrentjobs.h" -#include "idarbiterbase.h" -#include "itemsavecontext.h" -#include "storecollectiondialog.h" -#include "subresourcebase.h" - -#include -#include - -#include -#include - -ResourcePrivateBase::ResourcePrivateBase( IdArbiterBase *idArbiter, QObject *parent ) - : QObject( parent ), - mIdArbiter( idArbiter ), - mStoreCollectionDialog( 0 ), - mState( Closed ), - mLoadingInProgress( false ) -{ -} - -ResourcePrivateBase::ResourcePrivateBase( const KConfigGroup &config, IdArbiterBase *idArbiter, QObject *parent ) - : QObject( parent ), - mConfig( config ), - mIdArbiter( idArbiter ), - mStoreCollectionDialog( 0 ), - mState( Closed ), - mLoadingInProgress( false ) -{ - const QLatin1String resourceKey( "DefaultAkonadiResourceIdentifier" ); - mDefaultResourceIdentifier = config.readEntry( resourceKey, QString() ); - - const QLatin1String urlKey( "CollectionUrl" ); - KUrl url = config.readEntry( urlKey, KUrl() ); - if ( url.isValid() ) { - mDefaultStoreCollection = Akonadi::Collection::fromUrl( url ); - } - - const KConfigGroup storeConfig = config.group( QLatin1String( "StoreConfig" ) ); - if ( storeConfig.isValid() ) { - const QStringList groups = storeConfig.groupList(); - foreach ( const QString &group, groups ) { - KConfigGroup mimeConfig = storeConfig.group( group ); - - url = mimeConfig.readEntry( urlKey ); - kDebug( 5650 ) << "read MIME config pair: mimeType=" << group - << ", url=" << url; - if ( url.isValid() ) { - mStoreCollectionsByMimeType[ group ] = Akonadi::Collection::fromUrl( url ); - } - } - } -} - -ResourcePrivateBase::~ResourcePrivateBase() -{ - delete mIdArbiter; - delete mStoreCollectionDialog; -} - -bool ResourcePrivateBase::doOpen() -{ - kDebug( 5650 ); - if ( mState == Opened ) { - kWarning( 5650 ) << "Trying to open already opened resource"; - return true; - } - - if ( !startAkonadi() ) { - kError( 5650 ) << "Failed to start Akonadi"; - mState = Failed; - return false; - } - - if ( !openResource() ) { - kError( 5650 ) << "Failed to do type specific open"; - mState = Failed; - return false; - } - - mState = Opened; - return true; -} - -bool ResourcePrivateBase::doClose() -{ - if ( mConfig.isValid() ) { - writeConfig( mConfig ); - } - - bool result = closeResource(); - - mState = Closed; - - return result; -} - -bool ResourcePrivateBase::doLoad() -{ - kDebug( 5650 ) << "isLoading=" << isLoading(); - mLoadingInProgress = true; - - bool result = loadResource(); - - Q_ASSERT( !mLoadingInProgress ); // subclass must have called loadingResult - - return result; -} - -bool ResourcePrivateBase::doAsyncLoad() -{ - kDebug( 5650 ) << "isLoading=" << isLoading(); - mLoadingInProgress = true; - - return asyncLoadResource(); -} - -bool ResourcePrivateBase::doSave() -{ - kDebug( 5650 ) << mChanges.count() << "changes"; - - if ( mState == Closed ) { - const QString message = i18nc( "@info:status", "Cannot save to closed resource" ); - savingResult( false, message ); - return false; - } - - if ( mState == Failed ) { - const QString message = i18nc( "@info:status", "Cannot save while not connected to Akonadi" ); - savingResult( false, message ); - return false; - } - - if ( mChanges.isEmpty() ) { - return true; - } - - ItemSaveContext saveContext; - if ( !prepareItemSaveContext( saveContext ) ) { - const QString message = i18nc( "@info:status", "Processing change set failed" ); - savingResult( false, message ); - return false; - } - - ConcurrentItemSaveJob itemSaveJob( saveContext ); - if ( !itemSaveJob.exec() ) { - savingResult( false, itemSaveJob->errorString() ); - return false; - } - - return true; -} - -bool ResourcePrivateBase::doAsyncSave() -{ - kDebug( 5650 ) << mChanges.count() << "changes"; - - if ( mState == Closed ) { - const QString message = i18nc( "@info:status", "Cannot save to closed resource" ); - savingResult( false, message ); - return false; - } - - if ( mState == Failed ) { - const QString message = i18nc( "@info:status", "Cannot save while not connected to Akonadi" ); - savingResult( false, message ); - return false; - } - - if ( mChanges.isEmpty() ) { - return true; - } - - ItemSaveContext saveContext; - if ( !prepareItemSaveContext( saveContext ) ) { - const QString message = i18nc( "@info:status", "Processing change set failed" ); - savingResult( false, message ); - return false; - } - - ItemSaveJob *itemSaveJob = new ItemSaveJob( saveContext ); - connect( itemSaveJob, SIGNAL(result(KJob*)), - SLOT(savingResult(KJob*)) ); - - return true; -} - -void ResourcePrivateBase::writeConfig( KConfigGroup &config ) const -{ - const QLatin1String urlKey( "CollectionUrl" ); - const QLatin1String resourceKey( "DefaultAkonadiResourceIdentifier" ); - - Akonadi::Collection defaultStoreCollection = mDefaultStoreCollection; - QString defaultResourceIdentifier = mDefaultResourceIdentifier; - - // if we have new store config, then delete the old keys - if ( !mStoreCollectionsByMimeType.isEmpty() ) { - defaultStoreCollection = Akonadi::Collection(); - defaultResourceIdentifier.clear(); - } - - // if we have a valid default store collection, then delete the resource identifier key - if ( defaultStoreCollection.isValid() ) { - defaultResourceIdentifier.clear(); - config.writeEntry( urlKey, defaultStoreCollection.url() ); - } else { - config.deleteEntry( urlKey ); - } - - if ( !defaultResourceIdentifier.isEmpty() ) { - config.writeEntry( resourceKey, defaultResourceIdentifier ); - } else { - config.deleteEntry( resourceKey ); - } - - KConfigGroup storeConfig = config.group( QLatin1String( "StoreConfig" ) ); - QSet mimeConfigs = QSet::fromList( storeConfig.groupList() ); - - CollectionsByMimeType::const_iterator it = mStoreCollectionsByMimeType.constBegin(); - CollectionsByMimeType::const_iterator endIt = mStoreCollectionsByMimeType.constEnd(); - for ( ; it != endIt; ++it ) { - KConfigGroup mimeConfig = storeConfig.group( it.key() ); - - mimeConfig.writeEntry( urlKey, it.value().url() ); - mimeConfigs.remove( it.key() ); - - kDebug( 5650 ) << "wrote MIME config pair: mimeType=" << it.key() - << ", url=" << it.value().url(); - } - - foreach ( const QString &group, mimeConfigs ) { - storeConfig.deleteGroup( group ); - } - - writeResourceConfig( config ); -} - -void ResourcePrivateBase::clear() -{ - mIdArbiter->clear(); - mChanges.clear(); - clearResource(); -} - -void ResourcePrivateBase::setStoreCollectionsByMimeType( const StoreConfigIface::CollectionsByMimeType &collections ) -{ - mStoreCollectionsByMimeType = collections; - - mDefaultStoreCollection = Akonadi::Collection(); -} - -StoreConfigIface::CollectionsByMimeType ResourcePrivateBase::storeCollectionsByMimeType() const -{ - if ( mStoreCollectionsByMimeType.isEmpty() && mDefaultStoreCollection.isValid() ) { - return storeCollectionsFromOldDefault(); - } - - return mStoreCollectionsByMimeType; -} - -bool ResourcePrivateBase::addLocalItem( const QString &uid, const QString &mimeType ) -{ - kDebug( 5650 ) << "uid=" << uid << ", mimeType=" << mimeType; - - // check if there is a sub resource with a mapped item for the identifier - // if there is, we have a change, otherwise its an add - const SubResourceBase *resource = findSubResourceForMappedItem( uid ); - if ( resource == 0 ) { - mChanges[ uid ] = Added; - - if ( mStoreCollectionDialog == 0 ) { - mStoreCollectionDialog = new StoreCollectionDialog(); - mStoreCollectionDialog->setSubResourceModel( subResourceModel() ); - } - - resource = storeSubResourceForMimeType( mimeType ); - if ( resource == 0 ) { - // check possible store sub resources. if there is only one, use it - // otherwise we need to ask the user - QList possibleStores = writableSubResourcesForMimeType( mimeType ); - if ( possibleStores.count() == 1 ) { - kDebug( 5650 ) << "Only one possible sub resource for MIME type=" - << mimeType; - resource = possibleStores.first(); - } else { - resource = storeSubResourceFromUser( uid, mimeType ); - if ( resource == 0 ) { - mChanges.remove( uid ); - return false; - } - } - } - } else { - mChanges[ uid ] = Changed; - } - - Q_ASSERT( resource != 0 ); - mUidToResourceMap[ uid ] = resource->subResourceIdentifier(); - - return true; -} - -void ResourcePrivateBase::changeLocalItem( const QString &uid ) -{ - const QString subResource = mUidToResourceMap.value( uid ); - kDebug( 5650 ) << "uid=" << uid << ", subResource=" << subResource; - - Q_ASSERT( !subResource.isEmpty() ); - - const SubResourceBase *resource = subResourceBase( subResource ); - Q_ASSERT( resource != 0 ); - - if ( resource->hasMappedItem( uid ) ) { - mChanges[ uid ] = Changed; - } else { - mChanges[ uid ] = Added; - } -} - -void ResourcePrivateBase::removeLocalItem( const QString &uid ) -{ - const QString subResource = mUidToResourceMap.value( uid ); - kDebug( 5650 ) << "uid=" << uid << ", subResource=" << subResource; - - Q_ASSERT( !subResource.isEmpty() ); - - const SubResourceBase *resource = subResourceBase( subResource ); - Q_ASSERT( resource != 0 ); - - if ( resource->hasMappedItem( uid ) ) { - mChanges[ uid ] = Removed; - } else { - mChanges.remove( uid ); - } -} - -ResourcePrivateBase::State ResourcePrivateBase::state() const -{ - return mState; -} - -bool ResourcePrivateBase::isLoading() const -{ - return mLoadingInProgress; -} - -bool ResourcePrivateBase::startAkonadi() -{ - return Akonadi::Control::start(); -} - -Akonadi::Collection ResourcePrivateBase::storeCollectionForMimeType( const QString &mimeType ) const -{ - kDebug( 5650 ) << "mimeType=" << mimeType; - - if ( mStoreCollectionsByMimeType.isEmpty() && mDefaultStoreCollection.isValid() ) { - if ( Akonadi::MimeTypeChecker::isWantedCollection( mDefaultStoreCollection, mimeType ) ) { - kDebug( 5650 ) << "Taking DefaultStoreCollection: id=" << mDefaultStoreCollection.id() - << ", remoteId=" << mDefaultStoreCollection.remoteId(); - return mDefaultStoreCollection; - } - } - - Akonadi::Collection collection = mStoreCollectionsByMimeType.value( mimeType ); - if ( collection.isValid() ) { - kDebug( 5650 ) << "Found storage collection in map: id=" << collection.id() - << ", remoteId=" << collection.remoteId(); - return collection; - } - - return Akonadi::Collection(); -} - -bool ResourcePrivateBase::prepareItemSaveContext( ItemSaveContext &saveContext ) -{ - ChangeByKResId::const_iterator it = mChanges.constBegin(); - ChangeByKResId::const_iterator endIt = mChanges.constEnd(); - for ( ; it != endIt; ++it ) { - if ( !prepareItemSaveContext( it, saveContext ) ) { - return false; - } - } - - return true; -} - - -bool ResourcePrivateBase::prepareItemSaveContext( const ChangeByKResId::const_iterator &it, ItemSaveContext &saveContext ) -{ - const QString kresId = it.key(); - const SubResourceBase *resource = subResourceBase( mUidToResourceMap.value( kresId ) ); - Q_ASSERT( resource != 0 ); - - switch ( it.value() ) { - case Added: { - ItemAddContext addContext; - addContext.collection = resource->collection(); - addContext.item = createItem( kresId ); - - saveContext.addedItems << addContext; - break; - } - - case Changed: { - Akonadi::Item item = updateItem( resource->mappedItem( kresId ), kresId, mIdArbiter->mapToOriginalId( kresId ) ); - - saveContext.changedItems << item; - break; - } - - case Removed: - saveContext.removedItems << resource->mappedItem( kresId ); - break; - - case NoChange: - Q_ASSERT( "Invalid ChangeType in change map" ); - break; - } - - return true; -} - - -void ResourcePrivateBase::subResourceAdded( SubResourceBase *subResource ) -{ - Q_ASSERT( mIdArbiter != 0 ); - - subResource->setIdArbiter( mIdArbiter ); - subResource->readConfig( mConfig ); - - // if we don't have a valid default store collection yet, check if our - // config indicates a default resource and whether the newly added sub resource - // maps to one of its collections - if ( !mDefaultStoreCollection.isValid() ) { - if ( !mDefaultResourceIdentifier.isEmpty() ) { - if ( subResource->collection().resource() == mDefaultResourceIdentifier ) { - mDefaultStoreCollection = subResource->collection(); - mDefaultResourceIdentifier.clear(); - } - } - } else if ( mDefaultStoreCollection == subResource->collection() ) { - // update locally cached instance - mDefaultStoreCollection = subResource->collection(); - } - - // check if any of the MIME type specific collections can be updated - CollectionsByMimeType::iterator it = mStoreCollectionsByMimeType.begin(); - CollectionsByMimeType::iterator endIt = mStoreCollectionsByMimeType.end(); - for (; it != endIt; ++it ) { - if ( it.value() == subResource->collection() ) { - // update locally cached instance - it.value() = subResource->collection(); - } - } -} - -void ResourcePrivateBase::subResourceRemoved( SubResourceBase *subResource ) -{ - Q_UNUSED( subResource ); -} - -void ResourcePrivateBase::loadingResult( bool ok, const QString &errorString ) -{ - Q_UNUSED( ok ); - Q_UNUSED( errorString ); - - Q_ASSERT( mLoadingInProgress ); - - mLoadingInProgress = false; -} - -void ResourcePrivateBase::savingResult( bool ok, const QString &errorString ) -{ - Q_UNUSED( errorString ); - if ( ok ) { - mChanges.clear(); - } -} - -void ResourcePrivateBase::savingResult( KJob *job ) -{ - savingResult( job->error() == 0, job->errorString() ); -} - - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/resourceprivatebase.h kdepim-runtime-15.08.0/kresources/shared/resourceprivatebase.h --- kdepim-runtime-4.14.6/kresources/shared/resourceprivatebase.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/resourceprivatebase.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,193 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_RESOURCEPRIVATEBASE_H -#define KRES_AKONADI_RESOURCEPRIVATEBASE_H - -#include - -#include "storeconfigiface.h" - -#include - -#include - -namespace Akonadi { - class Item; -} - -class AbstractSubResourceModel; -class IdArbiterBase; -class ItemSaveContext; -class KJob; -class StoreCollectionDialog; -class SubResourceBase; - -class ResourcePrivateBase : public QObject, public StoreConfigIface -{ - Q_OBJECT - - public: - enum State { - Closed, - Opened, - Failed - }; - - enum ChangeType { - NoChange, - Added, - Changed, - Removed - }; - - typedef QHash ChangeByKResId; - - ResourcePrivateBase( IdArbiterBase *idArbiter, QObject *parent ); - - ResourcePrivateBase( const KConfigGroup &config, IdArbiterBase *idArbiter, QObject *parent ); - - virtual ~ResourcePrivateBase(); - - bool doOpen(); - - bool doClose(); - - bool doLoad(); - - bool doAsyncLoad(); - - bool doSave(); - - bool doAsyncSave(); - - void writeConfig( KConfigGroup &config ) const; - - void clear(); - - void setStoreCollectionsByMimeType( const CollectionsByMimeType &collections ); - - CollectionsByMimeType storeCollectionsByMimeType() const; - - bool addLocalItem( const QString &uid, const QString &mimeType ); - - void changeLocalItem( const QString &uid ); - - void removeLocalItem( const QString &uid ); - - protected: - KConfigGroup mConfig; - - IdArbiterBase *mIdArbiter; - - ChangeByKResId mChanges; - - Akonadi::Collection mDefaultStoreCollection; - - CollectionsByMimeType mStoreCollectionsByMimeType; - - QMap mUidToResourceMap; - - StoreCollectionDialog *mStoreCollectionDialog; - - protected: - State state() const; - - bool isLoading() const; - - bool startAkonadi(); - - Akonadi::Collection storeCollectionForMimeType( const QString &mimeType ) const; - - bool prepareItemSaveContext( ItemSaveContext &saveContext ); - - bool prepareItemSaveContext( const ChangeByKResId::const_iterator &it, ItemSaveContext &saveContext ); - - virtual bool openResource() = 0; - - virtual bool closeResource() = 0; - - virtual bool loadResource() = 0; - - virtual bool asyncLoadResource() = 0; - - virtual void writeResourceConfig( KConfigGroup &config ) const = 0; - - virtual void clearResource() = 0; - - virtual const SubResourceBase *subResourceBase( const QString &subResourceIdentifier ) const = 0; - - virtual const SubResourceBase *findSubResourceForMappedItem( const QString &kresId ) const = 0; - - virtual const SubResourceBase *storeSubResourceForMimeType( const QString &mimeType ) const = 0; - - virtual QList writableSubResourcesForMimeType( const QString &mimeType ) const = 0; - - virtual const SubResourceBase *storeSubResourceFromUser( const QString &kresId, const QString &mimeType ) = 0; - - virtual Akonadi::Item createItem( const QString &kresId ) = 0; - - virtual Akonadi::Item updateItem( const Akonadi::Item &item, const QString &kresId, const QString &originalId ) = 0; - - virtual const AbstractSubResourceModel *subResourceModel() const = 0; - - virtual CollectionsByMimeType storeCollectionsFromOldDefault() const = 0; - - protected Q_SLOTS: - virtual void subResourceAdded( SubResourceBase *subResource ); - - virtual void subResourceRemoved( SubResourceBase *subResource ); - - virtual void loadingResult( bool ok, const QString &errorString ); - - virtual void savingResult( bool ok, const QString &errorString ); - - private Q_SLOTS: - void savingResult( KJob *job ); - - private: - State mState; - bool mLoadingInProgress; - - QString mDefaultResourceIdentifier; -}; - -class BoolGuard -{ - public: - BoolGuard( bool &variable, bool overrideValue ) - : mVariable( variable ), mBaseValue( variable ) - { - mVariable = overrideValue; - } - - ~BoolGuard() - { - mVariable = mBaseValue; - } - - protected: - bool &mVariable; - const bool mBaseValue; -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/sharedresourceiface.h kdepim-runtime-15.08.0/kresources/shared/sharedresourceiface.h --- kdepim-runtime-4.14.6/kresources/shared/sharedresourceiface.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/sharedresourceiface.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_SHAREDRESOURCEIFACE_H -#define KRES_AKONADI_SHAREDRESOURCEIFACE_H - -class StoreConfigIface; - -class SharedResourceIface -{ - public: - virtual ~SharedResourceIface() {} - - virtual StoreConfigIface &storeConfig() = 0; -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/sharedresourceprivate.h kdepim-runtime-15.08.0/kresources/shared/sharedresourceprivate.h --- kdepim-runtime-4.14.6/kresources/shared/sharedresourceprivate.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/sharedresourceprivate.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,144 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_SHAREDRESOURCEPRIVATE_H -#define KRES_AKONADI_SHAREDRESOURCEPRIVATE_H - -#include "resourceprivatebase.h" -#include "subresourcemodel.h" - -template -class SharedResourcePrivate : public ResourcePrivateBase -{ - public: - typedef SubResourceModel SubResourceModelClass; - - SharedResourcePrivate( IdArbiter *idArbiter, QObject *parent ) - : ResourcePrivateBase( idArbiter, parent ), - mModel( this ) - { - connect( &mModel, SIGNAL(subResourceAdded(SubResourceBase*)), - SLOT(subResourceAdded(SubResourceBase*)) ); - - connect( &mModel, SIGNAL(subResourceRemoved(SubResourceBase*)), - SLOT(subResourceRemoved(SubResourceBase*)) ); - - connect( &mModel, SIGNAL(loadingResult(bool,QString)), - SLOT(loadingResult(bool,QString)) ); - } - - SharedResourcePrivate( const KConfigGroup &config, IdArbiter *idArbiter, QObject *parent ) - : ResourcePrivateBase( config, idArbiter, parent ), - mModel( this ) - { - connect( &mModel, SIGNAL(subResourceAdded(SubResourceBase*)), - SLOT(subResourceAdded(SubResourceBase*)) ); - - connect( &mModel, SIGNAL(subResourceRemoved(SubResourceBase*)), - SLOT(subResourceRemoved(SubResourceBase*)) ); - - connect( &mModel, SIGNAL(loadingResult(bool,QString)), - SLOT(loadingResult(bool,QString)) ); - } - - QStringList subResourceIdentifiers() const - { - return mModel.subResourceIdentifiers(); - } - - SubResourceClass *subResource( const QString &id ) const - { - return mModel.subResource( id ); - } - - bool isReadOnly() const - { - return !mModel.hasWritableSubResource(); - } - - protected: - SubResourceModelClass mModel; - - protected: - bool loadResource() - { - mModel.stopMonitoring(); - return mModel.load(); - } - - bool asyncLoadResource() - { - mModel.stopMonitoring(); - return mModel.asyncLoad(); - } - - void writeResourceConfig( KConfigGroup &config ) const - { - mModel.writeConfig( config ); - } - - void clearResource() - { - mModel.clear(); - } - - const SubResourceBase *subResourceBase( const QString &subResourceIdentifier ) const - { - return subResource( subResourceIdentifier ); - } - - const SubResourceBase *findSubResourceForMappedItem( const QString &kresId ) const - { - return mModel.findSubResourceForMappedItem( kresId ); - } - - const SubResourceBase *storeSubResourceForMimeType( const QString &mimeType ) const - { - Akonadi::Collection collection = storeCollectionForMimeType( mimeType ); - if ( collection.isValid() ) { - return mModel.subResource( collection.id() ); - } - - return 0; - } - - QList writableSubResourcesForMimeType( const QString &mimeType ) const - { - return mModel.writableSubResourceBasesForMimeType( mimeType ); - } - - const AbstractSubResourceModel *subResourceModel() const - { - return &mModel; - } - - void loadingResult( bool ok, const QString &errorString ) - { - ResourcePrivateBase::loadingResult( ok, errorString ); - - if ( ok ) { - mModel.startMonitoring(); - } - } -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/storecollectiondialog.cpp kdepim-runtime-15.08.0/kresources/shared/storecollectiondialog.cpp --- kdepim-runtime-4.14.6/kresources/shared/storecollectiondialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/storecollectiondialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,169 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 "storecollectiondialog.h" - -#include "storecollectionfilterproxymodel.h" - -#include -#include - -#include - -#include -#include - -using namespace Akonadi; - -static QModelIndex findCollection( const Collection &collection, - const QModelIndex &parent, QAbstractItemModel *model) -{ - const int rowCount = model->rowCount( parent ); - - for ( int row = 0; row < rowCount; ++row ) { - QModelIndex index = model->index( row, 0, parent ); - if ( !index.isValid() ) - continue; - - QVariant data = model->data( index, CollectionModel::CollectionIdRole ); - if ( !data.isValid() ) - continue; - - if ( data.toInt() == collection.id() ) { - return index; - } - - index = findCollection( collection, index, model ); - if ( index.isValid() ) - return index; - } - - return QModelIndex(); -} - -StoreCollectionDialog::StoreCollectionDialog( QWidget* parent ) - : KDialog( parent ), - mLabel( 0 ), - mFilterModel( 0 ), - mView( 0 ) -{ - setCaption( i18nc( "@title:window", "Target Folder Selection" ) ); - - setButtons( KDialog::Ok | KDialog::Cancel ); - - CollectionModel *model = new CollectionModel( this ); - - QWidget *widget = new QWidget( this ); - - QVBoxLayout *mainLayout = new QVBoxLayout( widget ); - mainLayout->setMargin( KDialog::marginHint() ); - mainLayout->setSpacing( KDialog::spacingHint() ); - - // initially hide label until a text is set - mLabel = new QLabel( widget ); - mLabel->hide(); - - mainLayout->addWidget( mLabel ); - - mFilterModel = new StoreCollectionFilterProxyModel( this ); - mFilterModel->setSourceModel( model ); - - mView = new CollectionView( widget ); - mView->setSelectionMode( QAbstractItemView::SingleSelection ); - mView->setModel( mFilterModel ); - - connect( mView, SIGNAL(currentChanged(Akonadi::Collection)), - this, SLOT(collectionChanged(Akonadi::Collection)) ); - connect( mView->model(), SIGNAL(rowsInserted(QModelIndex,int,int)), - this, SLOT(collectionsInserted(QModelIndex,int,int)) ); - - mainLayout->addWidget( mView ); - - setMainWidget( widget ); -} - -StoreCollectionDialog::~StoreCollectionDialog() -{ -} - -void StoreCollectionDialog::setLabelText( const QString &labelText ) -{ - mLabel->setText( labelText ); - mLabel->show(); -} - -void StoreCollectionDialog::setMimeType( const QString &mimeType ) -{ - mFilterModel->clearFilters(); - mFilterModel->addMimeTypeFilter( mimeType ); -} - -void StoreCollectionDialog::setSelectedCollection( const Collection &collection ) -{ - mSelectedCollection = collection; - - QModelIndex index = findCollection( mSelectedCollection, mView->rootIndex(), mView->model() ); - if ( index.isValid() ) { - mView->setCurrentIndex( index ); - } -} - -Collection StoreCollectionDialog::selectedCollection() const -{ - return mSelectedCollection; -} - -void StoreCollectionDialog::setSubResourceModel( const AbstractSubResourceModel *subResourceModel ) -{ - mFilterModel->setSubResourceModel( subResourceModel ); -} - -void StoreCollectionDialog::collectionChanged( const Collection &collection ) -{ - mSelectedCollection = collection; -} - -void StoreCollectionDialog::collectionsInserted( const QModelIndex &parent, int start, int end ) -{ - QAbstractItemModel *model = mView->model(); - - for ( int row = start; row <= end; ++row ) { - QModelIndex index = model->index( row, 0, parent ); - if ( !index.isValid() ) - continue; - - QVariant data = model->data( index, CollectionModel::CollectionIdRole ); - if ( !data.isValid() ) - continue; - - if ( data.toLongLong() == mSelectedCollection.id() ) { - mView->setCurrentIndex( index ); - return; - } - - index = findCollection( mSelectedCollection, index, model ); - if ( index.isValid() ) { - mView->setCurrentIndex( index ); - return; - } - } -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/storecollectiondialog.h kdepim-runtime-15.08.0/kresources/shared/storecollectiondialog.h --- kdepim-runtime-4.14.6/kresources/shared/storecollectiondialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/storecollectiondialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_STORECOLLECTIONDIALOG_H -#define KRES_AKONADI_STORECOLLECTIONDIALOG_H - -#include - -#include - -namespace Akonadi { - class CollectionView; - class StoreCollectionFilterProxyModel; -} - -class AbstractSubResourceModel; -class QLabel; -class QModelIndex; - -class StoreCollectionDialog : public KDialog -{ - Q_OBJECT - - public: - explicit StoreCollectionDialog( QWidget* parent = 0 ); - - ~StoreCollectionDialog(); - - void setLabelText( const QString &labelText ); - - void setMimeType( const QString &mimeType ); - - void setSelectedCollection( const Akonadi::Collection &collection ); - - Akonadi::Collection selectedCollection() const; - - void setSubResourceModel( const AbstractSubResourceModel *subResourceModel ); - - protected: - QLabel *mLabel; - Akonadi::StoreCollectionFilterProxyModel *mFilterModel; - Akonadi::CollectionView *mView; - - Akonadi::Collection mSelectedCollection; - - protected Q_SLOTS: - void collectionChanged( const Akonadi::Collection &collection ); - void collectionsInserted( const QModelIndex &parent, int start, int end ); -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/storecollectionfilterproxymodel.cpp kdepim-runtime-15.08.0/kresources/shared/storecollectionfilterproxymodel.cpp --- kdepim-runtime-4.14.6/kresources/shared/storecollectionfilterproxymodel.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/storecollectionfilterproxymodel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 "storecollectionfilterproxymodel.h" - -#include "abstractsubresourcemodel.h" -#include "subresourcebase.h" - -#include - -using namespace Akonadi; - -StoreCollectionFilterProxyModel::StoreCollectionFilterProxyModel( QObject *parent ) - : CollectionFilterProxyModel( parent ), - mSubResourceModel( 0 ) -{ -} - -StoreCollectionFilterProxyModel::~StoreCollectionFilterProxyModel() -{ -} - -void StoreCollectionFilterProxyModel::setSubResourceModel( const AbstractSubResourceModel *subResourceModel ) -{ - if ( mSubResourceModel != subResourceModel ) { - mSubResourceModel = subResourceModel; - invalidateFilter(); - } -} - -bool StoreCollectionFilterProxyModel::filterAcceptsRow( int sourceRow, - const QModelIndex &sourceParent) const -{ - // if the base class rejects it, it doesn't match our MIME type criteria - if ( !CollectionFilterProxyModel::filterAcceptsRow( sourceRow, sourceParent ) ) { - return false; - } - - QModelIndex index = sourceModel()->index( sourceRow, 0, sourceParent ); - if ( index.isValid() ) { - QVariant data = sourceModel()->data( index, CollectionModel::CollectionRole ); - if ( data.isValid() ) { - Collection collection = data.value(); - if ( collection.isValid() ) { - // only accept collections into which we can store new items - if ( ( collection.rights() & Collection::CanCreateItem ) != 0 ) { - // if we have a sub resource model, check the associated sub resource, - // otherwise just accept - if ( mSubResourceModel != 0 ) { - SubResourceBase *subResource = mSubResourceModel->subResourceBase( collection.id() ); - - // only accept sub resources which are active - return subResource != 0 && subResource->isActive(); - } - - return true; - } - } - } - } - - return false; -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/storecollectionfilterproxymodel.h kdepim-runtime-15.08.0/kresources/shared/storecollectionfilterproxymodel.h --- kdepim-runtime-4.14.6/kresources/shared/storecollectionfilterproxymodel.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/storecollectionfilterproxymodel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_STORECOLLECTIONFILTERPROXYMODEL_H -#define KRES_AKONADI_STORECOLLECTIONFILTERPROXYMODEL_H - -#include - -class AbstractSubResourceModel; - -namespace Akonadi { - -class StoreCollectionFilterProxyModel : public CollectionFilterProxyModel -{ - Q_OBJECT - - public: - explicit StoreCollectionFilterProxyModel( QObject *parent ); - - ~StoreCollectionFilterProxyModel(); - - void setSubResourceModel( const AbstractSubResourceModel *subResourceModel ); - - protected: - const AbstractSubResourceModel *mSubResourceModel; - - protected: - bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent) const; -}; - -} - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/storecollectionmodel.cpp kdepim-runtime-15.08.0/kresources/shared/storecollectionmodel.cpp --- kdepim-runtime-4.14.6/kresources/shared/storecollectionmodel.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/storecollectionmodel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 "storecollectionmodel.h" - -#include - -#include -#include - -#include - -using namespace Akonadi; - -StoreCollectionModel::StoreCollectionModel( QObject *parent ) - : CollectionModel( parent ) -{ -} - -int StoreCollectionModel::columnCount( const QModelIndex &parent ) const -{ - if ( parent.isValid() && parent.column() != 0 ) { - return 0; - } - - return 2; -} - -QVariant StoreCollectionModel::data( const QModelIndex &index, int role ) const -{ - if ( !index.isValid() ) { - return QVariant(); - } - - Collection collection = collectionForId( CollectionModel::data( index, CollectionIdRole ).toLongLong() ); - if ( !collection.isValid() ) { - return QVariant(); - } - - if ( index.column() == 1 && ( role == ItemTypeRole || role == Qt::DisplayRole ) ) { - QStringList itemTypes = mStoreMapping.value( collection.id(), QStringList() ); - itemTypes.sort(); - return itemTypes.join( QLatin1String( ", " ) ); - } - - return CollectionModel::data( index, role ); -} - -QVariant StoreCollectionModel::headerData( int section, Qt::Orientation orientation, int role ) const -{ - if ( orientation == Qt::Horizontal && role == Qt::DisplayRole ) - if ( section == 1 ) { - return i18nc( "@title:column data types which should be stored here by default", - "Defaults" ); - } - - return CollectionModel::headerData( section, orientation, role ); -} - -void StoreCollectionModel::setStoreMapping( const StoreCollectionModel::StoreItemsByCollection &storeMapping ) -{ - if ( mStoreMapping != storeMapping ) { - mStoreMapping = storeMapping; - reset(); - } -} - -StoreCollectionModel::StoreItemsByCollection StoreCollectionModel::storeMapping() const -{ - return mStoreMapping; -} - - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/storecollectionmodel.h kdepim-runtime-15.08.0/kresources/shared/storecollectionmodel.h --- kdepim-runtime-4.14.6/kresources/shared/storecollectionmodel.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/storecollectionmodel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_STORECOLLECTIONMODEL_H -#define KRES_AKONADI_STORECOLLECTIONMODEL_H - -#include -#include - -#include - -namespace Akonadi { - -class StoreCollectionModel : public CollectionModel -{ - Q_OBJECT - - public: - typedef QHash StoreItemsByCollection; - - enum Roles { - ItemTypeRole = CollectionModel::UserRole + 1, - UserRole = CollectionModel::UserRole + 8 - }; - - explicit StoreCollectionModel( QObject *parent = 0 ); - - virtual int columnCount( const QModelIndex & parent = QModelIndex() ) const; - - virtual QVariant data( const QModelIndex & index, int role = Qt::DisplayRole ) const; - - virtual QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; - - void setStoreMapping( const StoreItemsByCollection &storeMapping ); - - StoreItemsByCollection storeMapping() const; - - protected: - StoreItemsByCollection mStoreMapping; -}; - -} - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/storeconfigiface.h kdepim-runtime-15.08.0/kresources/shared/storeconfigiface.h --- kdepim-runtime-4.14.6/kresources/shared/storeconfigiface.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/storeconfigiface.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_STORECONFIGIFACE_H -#define KRES_AKONADI_STORECONFIGIFACE_H - -#include - -namespace Akonadi { - class Collection; -} - -class AbstractSubResourceModel; - -class StoreConfigIface -{ - public: - typedef QHash CollectionsByMimeType; - - virtual ~StoreConfigIface() {} - - virtual CollectionsByMimeType storeCollectionsByMimeType() const = 0; - - virtual void setStoreCollectionsByMimeType( const CollectionsByMimeType &collections ) = 0; -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/subresourcebase.cpp kdepim-runtime-15.08.0/kresources/shared/subresourcebase.cpp --- kdepim-runtime-4.14.6/kresources/shared/subresourcebase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/subresourcebase.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,226 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 "subresourcebase.h" - -#include - -#include -#include -#include - -using namespace Akonadi; - -SubResourceBase::SubResourceBase( const Akonadi::Collection &collection ) - : mCollection( collection ), - mActive( true ), - mIdArbiter( 0 ) -{ -} - -SubResourceBase::~SubResourceBase() -{ -} - -void SubResourceBase::setIdArbiter( IdArbiterBase *idArbiter ) -{ - mIdArbiter = idArbiter; -} - -QString SubResourceBase::label() const -{ - return label( mCollection ); -} - -void SubResourceBase::setActive( bool active ) -{ - if ( mActive != active ) { - mActive = active; - - if ( mActive ) { - foreach ( const Item &item, mItems ) { - itemAdded( item ); - } - } else { - foreach ( const Item &item, mItems ) { - itemRemoved( item ); - } - } - } -} - -bool SubResourceBase::isActive() const -{ - return mActive; -} - -bool SubResourceBase::isWritable() const -{ - return isWritable( mCollection ); -} - -QString SubResourceBase::subResourceIdentifier() const -{ - return mCollection.url().url(); -} - -void SubResourceBase::readConfig( const KConfigGroup &config ) -{ - if ( !config.isValid() ) - return; - - const QString collectionUrl = mCollection.url().url(); - if ( !config.hasGroup( collectionUrl ) ) - return; - - KConfigGroup group( &config, collectionUrl ); - mActive = group.readEntry( QLatin1String( "Active" ), true ); - - readTypeSpecificConfig( config ); -} - -void SubResourceBase::writeConfig( KConfigGroup &config ) const -{ - KConfigGroup group( &config, mCollection.url().url() ); - - group.writeEntry( QLatin1String( "Active" ), mActive ); -} - -void SubResourceBase::changeCollection( const Akonadi::Collection &collection ) -{ - Q_ASSERT( collection.id() == mCollection.id() ); - - // first pass to subclass, then update member so subclasses can - // check what changed - collectionChanged( collection ); - - mCollection = collection; -} - -void SubResourceBase::addItem( const Akonadi::Item &item ) -{ - const ItemsByItemId::const_iterator findIt = mItems.constFind( item.id() ); - if ( findIt != mItems.constEnd() ) { - kWarning( 5650 ) << "Item id=" << item.id() - << ", remoteId=" << item.remoteId() - << ", mimeType=" << item.mimeType() - << "is already part of this subresource" - << "(id=" << mCollection.id() - << ", remoteId=" << mCollection.remoteId() - << ")"; - if ( mActive ) { - itemChanged( item ); - } - } else { - if ( mActive ) { - itemAdded( item ); - } - mItems.insert( item.id(), item ); - } -} - -void SubResourceBase::changeItem( const Akonadi::Item &item ) -{ - ItemsByItemId::iterator findIt = mItems.find( item.id() ); - if ( findIt == mItems.end() ) { - kWarning( 5650 ) << "Item id=" << item.id() - << ", remoteId=" << item.remoteId() - << ", mimeType=" << item.mimeType() - << "is not yet part of this subresource" - << "(id=" << mCollection.id() - << ", remoteId=" << mCollection.remoteId() - << ")"; - if ( mActive ) { - itemAdded( item ); - } - mItems.insert( item.id(), item ); - } else { - if ( mActive ) { - itemChanged( item ); - } - findIt.value() = item; - } -} - -void SubResourceBase::removeItem( const Akonadi::Item &item ) -{ - ItemsByItemId::iterator findIt = mItems.find( item.id() ); - if ( findIt == mItems.end() ) { - kWarning( 5650 ) << "Item id=" << item.id() - << ", remoteId=" << item.remoteId() - << ", mimeType=" << item.mimeType() - << "is not part of this subresource" - << "(id=" << mCollection.id() - << ", remoteId=" << mCollection.remoteId() - << ")"; - } else { - if ( mActive ) { - itemRemoved( item ); - } - mItems.erase( findIt ); - } -} - -bool SubResourceBase::hasMappedItem( const QString &kresId ) const -{ - return mMappedItems.constFind( kresId ) != mMappedItems.constEnd(); -} - -Akonadi::Item SubResourceBase::mappedItem( const QString &kresId ) const -{ - return mMappedItems.value( kresId ); -} - -Akonadi::Collection SubResourceBase::collection() const -{ - return mCollection; -} - -void SubResourceBase::readTypeSpecificConfig( const KConfigGroup &config ) -{ - Q_UNUSED( config ); -} - -void SubResourceBase::writeTypeSpecificConfig( KConfigGroup &config ) const -{ - Q_UNUSED( config ); -} - -void SubResourceBase::collectionChanged( const Akonadi::Collection &collection ) -{ - Q_UNUSED( collection ); -} - -QString SubResourceBase::label( const Akonadi::Collection &collection ) -{ - return collection.displayName(); -} - -bool SubResourceBase::isWritable( const Akonadi::Collection &collection ) -{ - Akonadi::Collection::Rights itemRights; - itemRights |= Akonadi::Collection::CanCreateItem; - itemRights |= Akonadi::Collection::CanChangeItem; - itemRights |= Akonadi::Collection::CanDeleteItem; - - return ( collection.rights() & itemRights ) != 0; -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/subresourcebase.h kdepim-runtime-15.08.0/kresources/shared/subresourcebase.h --- kdepim-runtime-4.14.6/kresources/shared/subresourcebase.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/subresourcebase.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_SUBRESOURCEBASE_H -#define KRES_AKONADI_SUBRESOURCEBASE_H - -#include -#include - -#include - -class IdArbiterBase; -class KConfigGroup; - -class SubResourceBase : public QObject -{ - Q_OBJECT - - public: - typedef QHash ItemsByItemId; - typedef QHash ItemsByKResId; - typedef QHash KResIdByItemId; - - explicit SubResourceBase( const Akonadi::Collection &collection ); - - virtual ~SubResourceBase(); - - void setIdArbiter( IdArbiterBase *idArbiter ); - - QString label() const; - - void setActive( bool active ); - - bool isActive() const; - - bool isWritable() const; - - QString subResourceIdentifier() const; - - void readConfig( const KConfigGroup &config ); - - void writeConfig( KConfigGroup &config ) const; - - void changeCollection( const Akonadi::Collection &collection ); - - void addItem( const Akonadi::Item &item ); - - void changeItem( const Akonadi::Item &item ); - - void removeItem( const Akonadi::Item &item ); - - bool hasMappedItem( const QString &kresId ) const; - - Akonadi::Item mappedItem( const QString &kresId ) const; - - Akonadi::Collection collection() const; - - protected: - Akonadi::Collection mCollection; - bool mActive; - - ItemsByItemId mItems; - - IdArbiterBase *mIdArbiter; - - ItemsByKResId mMappedItems; - KResIdByItemId mMappedIds; - - protected: - virtual void readTypeSpecificConfig( const KConfigGroup &config ); - - virtual void writeTypeSpecificConfig( KConfigGroup &config ) const; - - virtual void collectionChanged( const Akonadi::Collection &collection ); - - virtual void itemAdded( const Akonadi::Item &item ) = 0; - - virtual void itemChanged( const Akonadi::Item &item ) = 0; - - virtual void itemRemoved( const Akonadi::Item &item ) = 0; - - static QString label( const Akonadi::Collection &collection ); - - static bool isWritable( const Akonadi::Collection &collection ); -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/kresources/shared/subresourcemodel.h kdepim-runtime-15.08.0/kresources/shared/subresourcemodel.h --- kdepim-runtime-4.14.6/kresources/shared/subresourcemodel.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/kresources/shared/subresourcemodel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,242 +0,0 @@ -/* - This file is part of kdepim. - Copyright (c) 2009 Kevin Krammer - - 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 KRES_AKONADI_SUBRESOURCEMODEL_H -#define KRES_AKONADI_SUBRESOURCEMODEL_H - -#include "abstractsubresourcemodel.h" -#include "subresourcebase.h" - -#include -#include -#include - -#include -#include - -template -class SubResourceModel : public AbstractSubResourceModel -{ - public: - typedef QHash SubResByColId; - typedef QHash SubResByKResId; - typedef QSet ColIdSet; - typedef QHash ColIdsByItemId; - - explicit SubResourceModel( QObject *parent ) - : AbstractSubResourceModel( SubResourceClass::supportedMimeTypes(), parent ) - { - } - - void writeConfig( KConfigGroup &config ) const - { - foreach ( const SubResourceClass *subResource, mSubResourcesByColId ) { - subResource->writeConfig( config ); - } - } - - SubResourceClass *subResource( Akonadi::Collection::Id colId ) const - { - return mSubResourcesByColId.value( colId, 0 ); - } - - SubResourceClass *subResource( const QString &kresId ) const - { - return mSubResourcesByKResId.value( kresId, 0 ); - } - - SubResourceBase *subResourceBase( Akonadi::Collection::Id colId ) const - { - return subResource( colId ); - } - - QList writableSubResourcesForMimeType( const QString &mimeType ) const - { - Akonadi::MimeTypeChecker mimeChecker; - mimeChecker.addWantedMimeType( mimeType ); - - QList result; - foreach ( SubResourceClass *subResource, mSubResourcesByColId ) { - if ( subResource->isWritable() && mimeChecker.isWantedCollection( subResource->collection() ) ) { - result << subResource; - } - } - - return result; - } - - QList writableSubResourceBasesForMimeType( const QString &mimeType ) const - { - Akonadi::MimeTypeChecker mimeChecker; - mimeChecker.addWantedMimeType( mimeType ); - - QList result; - foreach ( const SubResourceClass *subResource, mSubResourcesByColId ) { - if ( subResource->isWritable() && mimeChecker.isWantedCollection( subResource->collection() ) ) { - result << subResource; - } - } - - return result; - } - - bool hasWritableSubResource() const - { - Akonadi::MimeTypeChecker mimeChecker; - mimeChecker.setWantedMimeTypes( SubResourceClass::supportedMimeTypes() ); - - foreach ( const SubResourceClass *subResource, mSubResourcesByColId ) { - if ( subResource->isWritable() && mimeChecker.isWantedCollection( subResource->collection() ) ) { - return true; - } - } - return false; - } - - SubResourceClass *findSubResourceForMappedItem( const QString &kresId ) const - { - foreach ( SubResourceClass *subResource, mSubResourcesByColId ) { - if ( subResource->hasMappedItem( kresId ) ) { - return subResource; - } - } - - return 0; - } - - protected: - SubResByColId mSubResourcesByColId; - SubResByKResId mSubResourcesByKResId; - ColIdsByItemId mCollectionsByItemId; - - protected: - void clearModel() - { - qDeleteAll( mSubResourcesByColId ); - mSubResourcesByColId.clear(); - mSubResourcesByKResId.clear(); - mCollectionsByItemId.clear(); - } - - protected: - void collectionAdded( const Akonadi::Collection &collection ) - { - if ( mSubResourcesByColId.value( collection.id(), 0 ) == 0 ) { - SubResourceClass *subResource = new SubResourceClass( collection ); - - mSubResourcesByColId.insert( collection.id(), subResource ); - mSubResourcesByKResId.insert( subResource->subResourceIdentifier(), subResource ); - mSubResourceIdentifiers.insert( subResource->subResourceIdentifier() ); - - emit subResourceAdded( subResource ); - } else - collectionChanged( collection ); - } - - void collectionChanged( const Akonadi::Collection &collection ) - { - SubResourceClass *subResource = mSubResourcesByColId.value( collection.id(), 0 ); - if ( subResource != 0 ) { - subResource->changeCollection( collection ); - } else { - collectionAdded( collection ); - } - } - - void collectionRemoved( const Akonadi::Collection &collection ) - { - SubResourceClass *subResource = mSubResourcesByColId.take( collection.id() ); - if ( subResource == 0 ) { - return; - } - - mSubResourcesByKResId.remove( subResource->subResourceIdentifier() ); - mSubResourceIdentifiers.remove( subResource->subResourceIdentifier() ); - - emit subResourceRemoved( subResource ); - - ColIdsByItemId::iterator it = mCollectionsByItemId.begin(); - ColIdsByItemId::iterator endIt = mCollectionsByItemId.end(); - while ( it != endIt ) { - ColIdSet colIds = it.value(); - colIds.remove( collection.id() ); - - if ( colIds.isEmpty() ) { - it = mCollectionsByItemId.erase( it ); - } else { - ++it; - } - } - - delete subResource; - } - - void itemAdded( const Akonadi::Item &item, - const Akonadi::Collection &collection ) - { - SubResourceClass *subResource = mSubResourcesByColId.value( collection.id(), 0 ); - if ( subResource == 0 ) { - kWarning( 5650 ) << "Item id=" << item.id() - << ", remoteId=" << item.remoteId() - << ", mimeType=" << item.mimeType() - << "added to an unknown collection" - << "(id=" << collection.id() - << ", remoteId=" << collection.remoteId() - << ")"; - } else { - subResource->addItem( item ); - - // insert if not present yet - mCollectionsByItemId[ item.id() ].insert( collection.id() ); - } - } - - void itemChanged( const Akonadi::Item &item ) - { - const ColIdSet colIds = mCollectionsByItemId.value( item.id() ); - foreach ( const Akonadi::Collection::Id id, colIds ) { - SubResourceClass *subResource = mSubResourcesByColId.value( id, 0 ); - Q_ASSERT( subResource != 0 ); - - subResource->changeItem( item ); - } - } - - void itemRemoved( const Akonadi::Item &item ) - { - ColIdsByItemId::iterator findIt = mCollectionsByItemId.find( item.id() ); - if ( findIt == mCollectionsByItemId.end() ) { - return; - } - - foreach ( const Akonadi::Collection::Id id, findIt.value() ) { - SubResourceClass *subResource = mSubResourcesByColId.value( id, 0 ); - Q_ASSERT( subResource != 0 ); - - subResource->removeItem( item ); - } - - mCollectionsByItemId.erase( findIt ); - } -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/libkdepim-copy/calendardiffalgo.cpp kdepim-runtime-15.08.0/libkdepim-copy/calendardiffalgo.cpp --- kdepim-runtime-4.14.6/libkdepim-copy/calendardiffalgo.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/libkdepim-copy/calendardiffalgo.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,214 +0,0 @@ -/* - This file is part of libkdepim. - - Copyright (c) 2004 Tobias Koenig - - 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 "calendardiffalgo.h" - -#include - -#include -#include - -using namespace KPIM; - -#ifndef KDE_USE_FINAL -static bool compareString( const QString &left, const QString &right ) -{ - if ( left.isEmpty() && right.isEmpty() ) - return true; - else - return left == right; -} -#endif - -static QString toString( const QDate &date ) -{ - return date.toString(); -} - -static QString toString( const KDateTime &dateTime ) -{ - return dateTime.dateTime().toString(); -} - -static QString toString( const QString str ) -{ - return str; -} - -static QString toString( bool value ) -{ - if ( value ) - return i18n( "Yes" ); - else - return i18n( "No" ); -} - -CalendarDiffAlgo::CalendarDiffAlgo( const KCalCore::Incidence::Ptr &leftIncidence, - const KCalCore::Incidence::Ptr &rightIncidence ) - : mLeftIncidence( leftIncidence ), mRightIncidence( rightIncidence ) -{ -} - -void CalendarDiffAlgo::run() -{ - begin(); - - diffIncidenceBase( mLeftIncidence, mRightIncidence ); - diffIncidence( mLeftIncidence, mRightIncidence ); - - KCalCore::Event::Ptr leftEvent = mLeftIncidence.dynamicCast(); - KCalCore::Event::Ptr rightEvent = mRightIncidence.dynamicCast(); - if ( leftEvent && rightEvent ) { - diffEvent( leftEvent, rightEvent ); - } else { - KCalCore::Todo::Ptr leftTodo = mLeftIncidence.dynamicCast(); - KCalCore::Todo::Ptr rightTodo = mRightIncidence.dynamicCast(); - if ( leftTodo && rightTodo ) { - diffTodo( leftTodo, rightTodo ); - } - } - - end(); -} - -void CalendarDiffAlgo::diffIncidenceBase( const KCalCore::IncidenceBase::Ptr &left, const KCalCore::IncidenceBase::Ptr &right ) -{ - diffVector( i18n( "Attendees" ), left->attendees(), right->attendees() ); - - if ( left->dtStart() != right->dtStart() ) - conflictField( i18n( "Start time" ), left->dtStart().toString(), right->dtStart().toString() ); - - if ( !compareString( left->organizer()->fullName(), right->organizer()->fullName() ) ) - conflictField( i18n( "Organizer" ), left->organizer()->fullName(), right->organizer()->fullName() ); - - if ( !compareString( left->uid(), right->uid() ) ) - conflictField( i18n( "UID" ), left->uid(), right->uid() ); - - if ( left->allDay() != right->allDay() ) - conflictField( i18n( "Is all-day" ), toString( left->allDay() ), toString( right->allDay() ) ); - - if ( left->hasDuration() != right->hasDuration() ) - conflictField( i18n( "Has duration" ), toString( left->hasDuration() ), toString( right->hasDuration() ) ); - - if ( left->duration() != right->duration() ) - conflictField( i18n( "Duration" ), QString::number( left->duration().asSeconds() ), QString::number( right->duration().asSeconds() ) ); -} - -void CalendarDiffAlgo::diffIncidence( const KCalCore::Incidence::Ptr &left, - const KCalCore::Incidence::Ptr &right ) -{ - if ( !compareString( left->description(), right->description() ) ) - conflictField( i18n( "Description" ), left->description(), right->description() ); - - if ( !compareString( left->summary(), right->summary() ) ) - conflictField( i18n( "Summary" ), left->summary(), right->summary() ); - - if ( left->status() != right->status() ) - conflictField( i18n( "Status" ), - KCalUtils::Stringify::incidenceStatus( left->status() ), - KCalUtils::Stringify::incidenceStatus( right->status() ) ); - - - if ( left->secrecy() != right->secrecy() ) - conflictField( i18n( "Secrecy" ), toString( left->secrecy() ), toString( right->secrecy() ) ); - - if ( left->priority() != right->priority() ) - conflictField( i18n( "Priority" ), toString( left->priority() ), toString( right->priority() ) ); - - if ( !compareString( left->location(), right->location() ) ) - conflictField( i18n( "Location" ), left->location(), right->location() ); - - diffList( i18n( "Categories" ), left->categories(), right->categories() ); - diffVector( i18n( "Alarms" ), left->alarms(), right->alarms() ); - diffList( i18n( "Resources" ), left->resources(), right->resources() ); - diffVector( i18n( "Attachments" ), left->attachments(), right->attachments() ); - diffList( i18n( "Exception Dates" ), left->recurrence()->exDates(), right->recurrence()->exDates() ); - diffList( i18n( "Exception Times" ), left->recurrence()->exDateTimes(), right->recurrence()->exDateTimes() ); - // TODO: recurrence dates and date/times, exrules, rrules - - if ( left->created() != right->created() ) - conflictField( i18n( "Created" ), left->created().toString(), right->created().toString() ); - - if ( !compareString( left->relatedTo(), right->relatedTo() ) ) - conflictField( i18n( "Related Uid" ), left->relatedTo(), right->relatedTo() ); -} - -void CalendarDiffAlgo::diffEvent( const KCalCore::Event::Ptr &left, const KCalCore::Event::Ptr &right ) -{ - if ( left->hasEndDate() != right->hasEndDate() ) - conflictField( i18n( "Has End Date" ), toString( left->hasEndDate() ), toString( right->hasEndDate() ) ); - - if ( left->dtEnd() != right->dtEnd() ) - conflictField( i18n( "End Date" ), left->dtEnd().toString(), right->dtEnd().toString() ); - - // TODO: check transparency -} - -void CalendarDiffAlgo::diffTodo( const KCalCore::Todo::Ptr &left, const KCalCore::Todo::Ptr &right ) -{ - if ( left->hasStartDate() != right->hasStartDate() ) - conflictField( i18n( "Has Start Date" ), toString( left->hasStartDate() ), toString( right->hasStartDate() ) ); - - if ( left->hasDueDate() != right->hasDueDate() ) - conflictField( i18n( "Has Due Date" ), toString( left->hasDueDate() ), toString( right->hasDueDate() ) ); - - if ( left->dtDue() != right->dtDue() ) - conflictField( i18n( "Due Date" ), left->dtDue().toString(), right->dtDue().toString() ); - - if ( left->hasCompletedDate() != right->hasCompletedDate() ) - conflictField( i18n( "Has Complete Date" ), toString( left->hasCompletedDate() ), toString( right->hasCompletedDate() ) ); - - if ( left->percentComplete() != right->percentComplete() ) - conflictField( i18n( "Complete" ), QString::number( left->percentComplete() ), QString::number( right->percentComplete() ) ); - - if ( left->completed() != right->completed() ) - conflictField( i18n( "Completed" ), toString( left->completed() ), toString( right->completed() ) ); -} - -template -void CalendarDiffAlgo::diffList( const QString &id, - const QList &left, const QList &right ) -{ - for ( int i = 0; i < left.count(); ++i ) { - if ( !right.contains( left[ i ] ) ) - additionalLeftField( id, toString( left[ i ] ) ); - } - - for ( int i = 0; i < right.count(); ++i ) { - if ( !left.contains( right[ i ] ) ) - additionalRightField( id, toString( right[ i ] ) ); - } -} - -template -void CalendarDiffAlgo::diffVector( const QString &id, - const QVector &left, const QVector &right ) -{ - for ( int i = 0; i < left.count(); ++i ) { - if ( !right.contains( left[ i ] ) ) - additionalLeftField( id, toString( left[ i ] ) ); - } - - for ( int i = 0; i < right.count(); ++i ) { - if ( !left.contains( right[ i ] ) ) - additionalRightField( id, toString( right[ i ] ) ); - } -} diff -Nru kdepim-runtime-4.14.6/libkdepim-copy/calendardiffalgo.h kdepim-runtime-15.08.0/libkdepim-copy/calendardiffalgo.h --- kdepim-runtime-4.14.6/libkdepim-copy/calendardiffalgo.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/libkdepim-copy/calendardiffalgo.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -/* - This file is part of libkdepim. - - Copyright (c) 2004 Tobias Koenig - - 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 KDEPIM_CALENDARDIFFALGO_H -#define KDEPIM_CALENDARDIFFALGO_H - -#include "diffalgo.h" -#include -#include -#include - -namespace KPIM { - -class KDEPIM_COPY_EXPORT CalendarDiffAlgo : public DiffAlgo -{ - public: - CalendarDiffAlgo( const KCalCore::Incidence::Ptr &leftIncidence, - const KCalCore::Incidence::Ptr &rightIncidence ); - - void run(); - - private: - template - void diffList( const QString &id, const QList &left, const QList &right ); - - template - void diffVector( const QString &id, const QVector &left, const QVector &right ); - - void diffIncidenceBase( const KCalCore::IncidenceBase::Ptr &, const KCalCore::IncidenceBase::Ptr &); - void diffIncidence( const KCalCore::Incidence::Ptr &, const KCalCore::Incidence::Ptr & ); - void diffEvent( const KCalCore::Event::Ptr &, const KCalCore::Event::Ptr & ); - void diffTodo( const KCalCore::Todo::Ptr &, const KCalCore::Todo::Ptr & ); - - KCalCore::Incidence::Ptr mLeftIncidence; - KCalCore::Incidence::Ptr mRightIncidence; -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/libkdepim-copy/CMakeLists.txt kdepim-runtime-15.08.0/libkdepim-copy/CMakeLists.txt --- kdepim-runtime-4.14.6/libkdepim-copy/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/libkdepim-copy/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ - -add_subdirectory( tests ) -add_definitions( -DQT_NO_CAST_FROM_ASCII ) -add_definitions( -DQT_NO_CAST_TO_ASCII ) - -#add_definitions(-DKDE_DEFAULT_DEBUG_AREA=5300) - -########### next target ############### - - -set(kdepim-copy_LIB_SRCS - calendardiffalgo.cpp - diffalgo.cpp - htmldiffalgodisplay.cpp - kincidencechooser.cpp -) - -kde4_add_library(kdepim-copy ${LIBRARY_TYPE} ${kdepim-copy_LIB_SRCS}) - -target_link_libraries(kdepim-copy - ${KDE4_KDEUI_LIBS} - ${KDEPIMLIBS_KCALCORE_LIBS} - ${KDEPIMLIBS_KCALUTILS_LIBS} -) - -set_target_properties(kdepim-copy PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION}) -install(TARGETS kdepim-copy ${INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/libkdepim-copy/diffalgo.cpp kdepim-runtime-15.08.0/libkdepim-copy/diffalgo.cpp --- kdepim-runtime-4.14.6/libkdepim-copy/diffalgo.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/libkdepim-copy/diffalgo.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -/* - This file is part of libkdepim. - - Copyright (c) 2004 Tobias Koenig - - 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 "diffalgo.h" -#include -#include - -using namespace KPIM; - -void DiffAlgo::begin() -{ - QList::Iterator it; - for ( it = mDisplays.begin(); it != mDisplays.end(); ++it ) - (*it)->begin(); -} - -void DiffAlgo::end() -{ - QList::Iterator it; - for ( it = mDisplays.begin(); it != mDisplays.end(); ++it ) - (*it)->end(); -} - -void DiffAlgo::setLeftSourceTitle( const QString &title ) -{ - QList::Iterator it; - for ( it = mDisplays.begin(); it != mDisplays.end(); ++it ) - (*it)->setLeftSourceTitle( title ); -} - -void DiffAlgo::setRightSourceTitle( const QString &title ) -{ - QList::Iterator it; - for ( it = mDisplays.begin(); it != mDisplays.end(); ++it ) - (*it)->setRightSourceTitle( title ); -} - -void DiffAlgo::additionalLeftField( const QString &id, const QString &value ) -{ - QList::Iterator it; - for ( it = mDisplays.begin(); it != mDisplays.end(); ++it ) - (*it)->additionalLeftField( id, value ); -} - -void DiffAlgo::additionalRightField( const QString &id, const QString &value ) -{ - QList::Iterator it; - for ( it = mDisplays.begin(); it != mDisplays.end(); ++it ) - (*it)->additionalRightField( id, value ); -} - -void DiffAlgo::conflictField( const QString &id, const QString &leftValue, - const QString &rightValue ) -{ - QList::Iterator it; - for ( it = mDisplays.begin(); it != mDisplays.end(); ++it ) - (*it)->conflictField( id, leftValue, rightValue ); -} - -void DiffAlgo::addDisplay( DiffAlgoDisplay *display ) -{ - if ( !mDisplays.contains( display ) ) - mDisplays.append( display ); -} - -void DiffAlgo::removeDisplay( DiffAlgoDisplay *display ) -{ - mDisplays.removeAll( display ); -} diff -Nru kdepim-runtime-4.14.6/libkdepim-copy/diffalgo.h kdepim-runtime-15.08.0/libkdepim-copy/diffalgo.h --- kdepim-runtime-4.14.6/libkdepim-copy/diffalgo.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/libkdepim-copy/diffalgo.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,138 +0,0 @@ -/* - This file is part of libkdepim. - - Copyright (c) 2004 Tobias Koenig - - 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 KDEPIM_DIFFALGO_H -#define KDEPIM_DIFFALGO_H - -#include "libkdepim-copy_export.h" -#include - -namespace KPIM { - -/** - DiffAlgo and DiffAlgoDisplay work together for displaying differences between - two PIM objects like contacts, events or todos. - DiffAlgo is the bas class for the diffing algorithm and DiffAlgoDisplay is - responsible for representation. The separation makes it possible to use one - display for all diffing algorithm and vice versa. - */ -class DiffAlgoDisplay -{ - public: - virtual ~DiffAlgoDisplay(){} - /** - Is called on the start of the diff. - */ - virtual void begin() = 0; - - /** - Is called on the end of the diff. - */ - virtual void end() = 0; - - /** - Sets the title of the left data source. - */ - virtual void setLeftSourceTitle( const QString &title ) = 0; - - /** - Sets the title of the right data source. - */ - virtual void setRightSourceTitle( const QString &title ) = 0; - - /** - Adds a field which is only available in the left data source. - */ - virtual void additionalLeftField( const QString &id, const QString &value ) = 0; - - /** - Adds a field which is only available in the right data source. - */ - virtual void additionalRightField( const QString &id, const QString &value ) = 0; - - /** - Adds a conflict between two fields. - */ - virtual void conflictField( const QString &id, const QString &leftValue, - const QString &rightValue ) = 0; -}; - - -class KDEPIM_COPY_EXPORT DiffAlgo -{ - public: - /** - Destructor. - */ - virtual ~DiffAlgo() {} - - /** - Starts the diffing algorithm. - */ - virtual void run() = 0; - - /** - Must be called on the start of the diff. - */ - void begin(); - - /** - Must be called on the end of the diff. - */ - void end(); - - /** - Sets the title of the left data source. - */ - void setLeftSourceTitle( const QString &title ); - - /** - Sets the title of the right data source. - */ - void setRightSourceTitle( const QString &title ); - - /** - Adds a field which is only available in the left data source. - */ - void additionalLeftField( const QString &id, const QString &value ); - - /** - Adds a field which is only available in the right data source. - */ - void additionalRightField( const QString &id, const QString &value ); - - /** - Adds a conflict between two fields. - */ - void conflictField( const QString &id, const QString &leftValue, - const QString &rightValue ); - - void addDisplay( DiffAlgoDisplay *display ); - void removeDisplay( DiffAlgoDisplay *display ); - - - private: - QList mDisplays; -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/libkdepim-copy/htmldiffalgodisplay.cpp kdepim-runtime-15.08.0/libkdepim-copy/htmldiffalgodisplay.cpp --- kdepim-runtime-4.14.6/libkdepim-copy/htmldiffalgodisplay.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/libkdepim-copy/htmldiffalgodisplay.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -/* - This file is part of libkdepim. - - Copyright (c) 2004 Tobias Koenig - - 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 "htmldiffalgodisplay.h" -#include -#include - -using namespace KPIM; - -static QString textToHTML( const QString &text ) -{ - return Qt::convertFromPlainText( text ); -} - -HTMLDiffAlgoDisplay::HTMLDiffAlgoDisplay( QWidget *parent ) - : KTextBrowser( parent ) -{ - setWordWrapMode( QTextOption::WrapAtWordBoundaryOrAnywhere ); - setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff ); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff ); -} - -void HTMLDiffAlgoDisplay::begin() -{ - clear(); - mText.clear(); - - mText.append( QLatin1String("") ); - mText.append( QString::fromLatin1( "" ) - .arg( KColorScheme( QPalette::Active, KColorScheme::View ).foreground().color().name() ) - .arg( KColorScheme( QPalette::Active, KColorScheme::View ).background().color().name() ) ); - - mText.append( QLatin1String("
") ); - mText.append( QString::fromLatin1( "" ) - .arg( mLeftTitle ) - .arg( mRightTitle ) ); -} - -void HTMLDiffAlgoDisplay::end() -{ - mText.append( QLatin1String("
%1 %2
" - "" - "") ); - - setHtml( mText ); -} - -void HTMLDiffAlgoDisplay::setLeftSourceTitle( const QString &title ) -{ - mLeftTitle = title; -} - -void HTMLDiffAlgoDisplay::setRightSourceTitle( const QString &title ) -{ - mRightTitle = title; -} - -void HTMLDiffAlgoDisplay::additionalLeftField( const QString &id, const QString &value ) -{ - mText.append( QString::fromLatin1( "%1:%2" ) - .arg( id ) - .arg( textToHTML( value ) ) ); -} - -void HTMLDiffAlgoDisplay::additionalRightField( const QString &id, const QString &value ) -{ - mText.append( QString::fromLatin1( "%1:%2" ) - .arg( id ) - .arg( textToHTML( value ) ) ); -} - -void HTMLDiffAlgoDisplay::conflictField( const QString &id, const QString &leftValue, - const QString &rightValue ) -{ - mText.append( QString::fromLatin1( "%1:%2%3" ) - .arg( id ) - .arg( textToHTML( leftValue ) ) - .arg( textToHTML( rightValue ) ) ); -} diff -Nru kdepim-runtime-4.14.6/libkdepim-copy/htmldiffalgodisplay.h kdepim-runtime-15.08.0/libkdepim-copy/htmldiffalgodisplay.h --- kdepim-runtime-4.14.6/libkdepim-copy/htmldiffalgodisplay.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/libkdepim-copy/htmldiffalgodisplay.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - This file is part of libkdepim. - - Copyright (c) 2004 Tobias Koenig - - 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 KDEPIM_HTMLDIFFALGODISPLAY_H -#define KDEPIM_HTMLDIFFALGODISPLAY_H - -#include "libkdepim-copy_export.h" -#include "diffalgo.h" - -#include - -namespace KPIM { - -class KDEPIM_COPY_EXPORT HTMLDiffAlgoDisplay : virtual public DiffAlgoDisplay, public KTextBrowser -{ - public: - HTMLDiffAlgoDisplay( QWidget *parent ); - - void begin(); - void end(); - void setLeftSourceTitle( const QString &title ); - void setRightSourceTitle( const QString &title ); - void additionalLeftField( const QString &id, const QString &value ); - void additionalRightField( const QString &id, const QString &value ); - void conflictField( const QString &id, const QString &leftValue, - const QString &rightValue ); - - private: - QString mLeftTitle; - QString mRightTitle; - QString mText; -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/libkdepim-copy/kincidencechooser.cpp kdepim-runtime-15.08.0/libkdepim-copy/kincidencechooser.cpp --- kdepim-runtime-4.14.6/libkdepim-copy/kincidencechooser.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/libkdepim-copy/kincidencechooser.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,468 +0,0 @@ -/* - This file is part of libkdepim. - - Copyright (c) 2004 Lutz Rogowski - Copyright (c) 2009 Allen Winter - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, permission is given to link this program - with any edition of Qt, and distribute the resulting executable, - without including the source code for Qt in the source distribution. -*/ - -#include "kincidencechooser.h" -using namespace KPIM; - - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace KCalCore; -using namespace KCalUtils; - -int KIncidenceChooser::chooseMode = KIncidenceChooser::ask; - -KIncidenceChooser::KIncidenceChooser( QWidget *parent ) - : KDialog( parent ) -{ - setModal( true ); - QWidget *topFrame = mainWidget(); - QGridLayout *topLayout = new QGridLayout( topFrame ); - topLayout->setMargin( 5 ); - topLayout->setSpacing( 3 ); - - int iii = 0; - setWindowTitle( i18nc( "@title:window", "Conflict Detected" ) ); - QLabel *lab; - lab = new QLabel( - i18nc( "@info", - "A conflict was detected. This probably means someone edited " - "the same incidence on the server while you changed it locally." - "You have to check mail again to apply your changes " - "to the server." ), topFrame ); - lab->setWordWrap( true ); - topLayout->addWidget( lab, iii, 0, 1, 3 ); - ++iii; - KHBox *b_box = new KHBox( topFrame ); - topLayout->addWidget( b_box, iii, 0, 1, 3 ); - ++iii; - QPushButton *locBut = new QPushButton( i18nc( "@action:button", "Take Local" ), b_box ); - connect( locBut, SIGNAL(clicked()), this, SLOT(takeIncidence1()) ); - locBut->setToolTip( - i18nc( "@info:tooltip", "Take your local copy of the incidence" ) ); - locBut->setWhatsThis( - i18nc( "@info:whatsthis", - "A conflict was detected between your local copy of the incidence " - "and the remote incidence on the server. Press the \"Take Local\" " - "button to make sure your local copy is used." ) ); - - QPushButton *remBut = new QPushButton( i18nc( "@action:button", "Take New" ), b_box ); - connect( remBut, SIGNAL(clicked()), this, SLOT(takeIncidence2()) ); - remBut->setToolTip( - i18nc( "@info:tooltip", "Take the server copy of the incidence" ) ); - remBut->setWhatsThis( - i18nc( "@info:whatsthis", - "A conflict was detected between your local copy of the incidence " - "and the remote incidence on the server. Press the \"Take New\" " - "button to use the server copy, thereby overwriting your local copy" ) ); - - QPushButton *bothBut = new QPushButton( i18nc( "@action:button", "Take Both" ), b_box ); - bothBut->setFocus(); //kolab/issue4147: "Take Both" should be default - connect( bothBut, SIGNAL(clicked()), this, SLOT(takeBoth()) ); - bothBut->setToolTip( - i18nc( "@info:tooltip", "Take both copies of the incidence" ) ); - bothBut->setWhatsThis( - i18nc( "@info:whatsthis", - "A conflict was detected between your local copy of the incidence " - "and the remote incidence on the server. Press the \"Take Both\" " - "button to keep both the local and the server copies." ) ); - - topLayout->setSpacing( spacingHint() ); - topLayout->setMargin( marginHint() ); - - mInc1lab = new QLabel( i18nc( "@label", "Local incidence" ), topFrame ); - topLayout->addWidget( mInc1lab, iii, 0 ); - - mInc1Sumlab = new QLabel( i18nc( "@label", "Local incidence summary" ), topFrame ); - topLayout->addWidget( mInc1Sumlab, iii, 1, 1, 2 ); - ++iii; - - topLayout->addWidget( new QLabel( i18nc( "@label", "Last modified:" ), topFrame ), iii, 0 ); - - mMod1lab = new QLabel( i18nc( "@label", "Set Last modified" ), topFrame ); - topLayout->addWidget( mMod1lab, iii, 1 ); - - mShowDetails1 = new QPushButton( i18nc( "@action:button", "Show Details" ), topFrame ); - mShowDetails1->setToolTip( - i18nc( "@info:tooltip", "Hide/Show incidence details" ) ); - mShowDetails1->setWhatsThis( - i18nc( "@info:whatsthis", - "Press this button to toggle the incidence details display." ) ); - connect( mShowDetails1, SIGNAL(clicked()), this, SLOT(showIncidence1()) ); - topLayout->addWidget( mShowDetails1, iii, 2 ); - ++iii; - - mInc2lab = new QLabel( i18nc( "@label", "Local incidence" ), topFrame ); - topLayout->addWidget( mInc2lab, iii, 0 ); - - mInc2Sumlab = new QLabel( i18nc( "@label", "Local incidence summary" ), topFrame ); - topLayout->addWidget( mInc2Sumlab, iii, 1, 1, 2 ); - ++iii; - - topLayout->addWidget( new QLabel( i18nc( "@label", "Last modified:" ), topFrame ), iii, 0 ); - - mMod2lab = new QLabel( i18nc( "@label", "Set Last modified" ), topFrame ); - topLayout->addWidget( mMod2lab, iii, 1 ); - - mShowDetails2 = new QPushButton( i18nc( "@action:button", "Show Details" ), topFrame ); - mShowDetails2->setToolTip( - i18nc( "@info:tooltip", "Hide/Show incidence details" ) ); - mShowDetails2->setWhatsThis( - i18nc( "@info:whatsthis", - "Press this button to toggle the incidence details display." ) ); - connect( mShowDetails2, SIGNAL(clicked()), this, SLOT(showIncidence2()) ); - topLayout->addWidget( mShowDetails2, iii, 2 ); - ++iii; - // -#if 0 - // commented out for now, because the diff code has too many bugs - mDiffBut = new QPushButton( i18nc( "@action:button", "Show Differences" ), topFrame ); - mDiffBut->setToolTip( - i18nc( "@info:tooltip", "Show the differences between the two incidences" ) ); - mDiffBut->setWhatsThis( - i18nc( "@info:whatsthis", - "Press the \"Show Differences\" button to see the specific " - "differences between the incidences which are in conflict." ) ); - connect( mDiffBut, SIGNAL(clicked()), this, SLOT(showDiff()) ); - topLayout->addWidget( mDiffBut, iii, 0, 1, 3 ); - ++iii; -#else - mDiffBut = 0; -#endif - QGroupBox *groupBox = new QGroupBox( i18nc( "@title:group", "Sync Preferences" ), topFrame ); - QVBoxLayout *groupBoxLayout = new QVBoxLayout; - mBg = new QButtonGroup( topFrame ); - groupBox->setToolTip( i18nc( "@info:tooltip", "Sync Preferences" ) ); - groupBox->setWhatsThis( i18nc( "@info:whatsthis", "Sync Preferences" ) ); - topLayout->addWidget( groupBox, iii, 0, 1, 3 ); - ++iii; - - QRadioButton *locRad = new QRadioButton( - i18nc( "@option:radio", "Take local copy on conflict" ) ); - mBg->addButton( locRad, KIncidenceChooser::local ); - locRad->setToolTip( - i18nc( "@info:tooltip", "Take local copy of the incidence on conflicts" ) ); - locRad->setWhatsThis( - i18nc( "@info:whatsthis", - "When a conflict is detected between a local copy of an incidence " - "and a remote incidence on the server, this option enforces using " - "the local copy." ) ); - groupBoxLayout->addWidget( locRad ); - - QRadioButton *remRad = new QRadioButton( - i18nc( "@option:radio", "Take remote copy on conflict" ) ); - mBg->addButton( remRad, KIncidenceChooser::remote ); - remRad->setToolTip( - i18nc( "@info:tooltip", "Take remote copy of the incidence on conflicts" ) ); - remRad->setWhatsThis( - i18nc( "@info:whatsthis", - "When a conflict is detected between a local copy of an incidence " - "and a remote incidence on the server, this option enforces using " - "the remote copy." ) ); - groupBoxLayout->addWidget( remRad ); - - QRadioButton *newRad = new QRadioButton( - i18nc( "@option:radio", "Take newest incidence on conflict" ) ); - mBg->addButton( newRad, KIncidenceChooser::newest ); - newRad->setToolTip( - i18nc( "@info:tooltip", "Take newest version of the incidence on conflicts" ) ); - newRad->setWhatsThis( - i18nc( "@info:whatsthis", - "When a conflict is detected between a local copy of an incidence " - "and a remote incidence on the server, this option enforces using " - "the newest version available." ) ); - groupBoxLayout->addWidget( newRad ); - - QRadioButton *askRad = new QRadioButton( - i18nc( "@option:radio", "Ask for every conflict" ) ); - mBg->addButton( askRad, KIncidenceChooser::ask ); - askRad->setToolTip( - i18nc( "@info:tooltip", "Ask for every incidence conflict" ) ); - askRad->setWhatsThis( - i18nc( "@info:whatsthis", - "When a conflict is detected between a local copy of an incidence " - "and a remote incidence on the server, this option says to ask " - "the user which version they want to keep." ) ); - groupBoxLayout->addWidget( askRad ); - - QRadioButton *bothRad = new QRadioButton( - i18nc( "@option:radio", "Take both on conflict" ) ); - mBg->addButton( bothRad, KIncidenceChooser::both ); - bothRad->setToolTip( - i18nc( "@info:tooltip", "Take both incidences on conflict" ) ); - bothRad->setWhatsThis( - i18nc( "@info:whatsthis", - "When a conflict is detected between a local copy of an incidence " - "and a remote incidence on the server, this option says to keep " - "both versions of the incidence." ) ); - groupBoxLayout->addWidget( bothRad ); - - mBg->button( chooseMode )->setChecked( true ); - groupBox->setLayout( groupBoxLayout ); - - QPushButton *applyBut = new QPushButton( - i18nc( "@action:button", "Apply preference to all conflicts of this sync" ), topFrame ); - connect( applyBut, SIGNAL(clicked()), this, SLOT(setSyncMode()) ); - applyBut->setToolTip( - i18nc( "@info:tooltip", - "Apply the preference to all conflicts that may occur during the sync" ) ); - applyBut->setWhatsThis( - i18nc( "@info:whatsthis", - "Press this button to apply the selected preference to all " - "future conflicts that might occur during this sync." ) ); - topLayout->addWidget( applyBut, iii, 0, 1, 3 ); - - mTbL = 0; - mTbN = 0; - mDisplayDiff = 0; - mSelIncidence = Incidence::Ptr(); - diff = 0; -} - -KIncidenceChooser::~KIncidenceChooser() -{ - delete mTbL; - delete mTbN; - if ( mDisplayDiff ) { - delete mDisplayDiff; - delete diff; - } -} - -void KIncidenceChooser::setIncidence( const Incidence::Ptr &local, - const Incidence::Ptr &remote ) -{ - - mInc1 = local; - mInc2 = remote; - setLabels(); - -} -Incidence::Ptr KIncidenceChooser::getIncidence( ) -{ - Incidence::Ptr retval = mSelIncidence; - if ( chooseMode == KIncidenceChooser::local ) { - retval = mInc1; - } else if ( chooseMode == KIncidenceChooser::remote ) { - retval = mInc2; - } else if ( chooseMode == KIncidenceChooser::both ) { - retval = Incidence::Ptr(); - } else if ( chooseMode == KIncidenceChooser::newest ) { - if ( mInc1->lastModified() == mInc2->lastModified() ) { - retval = Incidence::Ptr(); - } - if ( mInc1->lastModified() > mInc2->lastModified() ) { - retval = mInc1; - } else { - retval = mInc2; - } - } - return retval; -} - -void KIncidenceChooser::setSyncMode() -{ - chooseMode = mBg->checkedId(); - if ( chooseMode != KIncidenceChooser::ask ) { - KDialog::accept(); - } -} - -void KIncidenceChooser::useGlobalMode() -{ - if ( chooseMode != KIncidenceChooser::ask ) { - KDialog::reject(); - } -} - -void KIncidenceChooser::setLabels() -{ - Incidence::Ptr inc = mInc1; - QLabel *des = mInc1lab; - QLabel *sum = mInc1Sumlab; - - if ( inc->type() == Incidence::TypeEvent ) { - des->setText( i18nc( "@label", "Local Event" ) ); - sum->setText( inc->summary().left( 30 ) ); - if ( mDiffBut ) { - mDiffBut->setEnabled( true ); - } - } else if ( inc->type() == Incidence::TypeTodo ) { - des->setText( i18nc( "@label", "Local Todo" ) ); - sum->setText( inc->summary().left( 30 ) ); - if ( mDiffBut ) { - mDiffBut->setEnabled( true ); - } - } else if ( inc->type() == Incidence::TypeJournal ) { - des->setText( i18nc( "@label", "Local Journal" ) ); - sum->setText( inc->description().left( 30 ) ); - if ( mDiffBut ) { - mDiffBut->setEnabled( false ); - } - } - mMod1lab->setText( KGlobal::locale()->formatDateTime( inc->lastModified().dateTime() ) ); - inc = mInc2; - des = mInc2lab; - sum = mInc2Sumlab; - if ( inc->type() == Incidence::TypeEvent ) { - des->setText( i18nc( "@label", "New Event" ) ); - sum->setText( inc->summary().left( 30 ) ); - } else if ( inc->type() == Incidence::TypeJournal ) { - des->setText( i18nc( "@label", "New Todo" ) ); - sum->setText( inc->summary().left( 30 ) ); - } else if ( inc->type() == Incidence::TypeJournal ) { - des->setText( i18nc( "@label", "New Journal" ) ); - sum->setText( inc->description().left( 30 ) ); - - } - mMod2lab->setText( KGlobal::locale()->formatDateTime( inc->lastModified().dateTime() ) ); -} - -void KIncidenceChooser::showIncidence1() -{ - if ( mTbL ) { - if ( mTbL->isVisible() ) { - mShowDetails1->setText( i18nc( "@action:button", "Show Details" ) ); - mTbL->hide(); - } else { - mShowDetails1->setText( i18nc( "@action:button", "Hide Details" ) ); - mTbL->show(); - mTbL->raise(); - } - return; - } - mTbL = new KDialog( this ); - mTbL->setCaption( mInc1lab->text() ); - mTbL->setModal( false ); - mTbL->setButtons( Ok ); - connect( mTbL, SIGNAL(okClicked()), this, SLOT(detailsDialogClosed()) ); - KTextBrowser *textBrowser = new KTextBrowser( mTbL ); - mTbL->setMainWidget( textBrowser ); - textBrowser->setHtml( IncidenceFormatter::extensiveDisplayStr( QString(), mInc1 ) ); - textBrowser->setToolTip( i18nc( "@info:tooltip", "Incidence details" ) ); - textBrowser->setWhatsThis( i18nc( "@info:whatsthis", - "This area shows the incidence details" ) ); - mTbL->setMinimumSize( 400, 400 ); - mShowDetails1->setText( i18nc( "@action:button", "Hide Details" ) ); - mTbL->show(); - mTbL->raise(); -} - -void KIncidenceChooser::detailsDialogClosed() -{ - KDialog *dialog = static_cast( const_cast( sender() ) ); - if ( dialog == mTbL ) { - mShowDetails1->setText( i18nc( "@action:button", "Show details..." ) ); - } else { - mShowDetails2->setText( i18nc( "@action:button", "Show details..." ) ); - } -} - -void KIncidenceChooser::showDiff() -{ - if ( mDisplayDiff ) { - mDisplayDiff->show(); - mDisplayDiff->raise(); - return; - } - mDisplayDiff = new KPIM::HTMLDiffAlgoDisplay( this ); - if ( mInc1->summary().left( 20 ) != mInc2->summary().left( 20 ) ) { - mDisplayDiff->setWindowTitle( - i18nc( "@title:window", - "Differences of %1 and %2", - mInc1->summary().left( 20 ), mInc2->summary().left( 20 ) ) ); - } else { - mDisplayDiff->setWindowTitle( - i18nc( "@title:window", - "Differences of %1", mInc1->summary().left( 20 ) ) ); - } - - diff = new KPIM::CalendarDiffAlgo( mInc1, mInc2 ); - diff->setLeftSourceTitle( i18nc( "@title:column", "Local incidence" ) ); - diff->setRightSourceTitle( i18nc( "@title:column", "Remote incidence" ) ); - diff->addDisplay( mDisplayDiff ); - diff->run(); - mDisplayDiff->show(); - mDisplayDiff->raise(); -} - -void KIncidenceChooser::showIncidence2() -{ - if ( mTbN ) { - if ( mTbN->isVisible() ) { - mShowDetails2->setText( i18nc( "@label", "Show Details" ) ); - mTbN->hide(); - } else { - mShowDetails2->setText( i18nc( "@label", "Hide Details" ) ); - mTbN->show(); - mTbN->raise(); - } - return; - } - mTbN = new KDialog( this ); - mTbN->setCaption( mInc2lab->text() ); - mTbN->setModal( false ); - mTbN->setButtons( Ok ); - connect( mTbN, SIGNAL(okClicked()), this, SLOT(detailsDialogClosed()) ); - KTextBrowser *textBrowser = new KTextBrowser( mTbN ); - mTbN->setMainWidget( textBrowser ); - textBrowser->setHtml( IncidenceFormatter::extensiveDisplayStr( QString(), mInc2 ) ); - textBrowser->setToolTip( i18nc( "@info:tooltip", "Incidence details" ) ); - textBrowser->setWhatsThis( i18nc( "@info:whatsthis", - "This area shows the incidence details" ) ); - mTbN->setMinimumSize( 400, 400 ); - mShowDetails2->setText( i18nc( "@label", "Hide Details" ) ); - mTbN->show(); - mTbN->raise(); -} - -void KIncidenceChooser::takeIncidence1() -{ - mSelIncidence = mInc1; - KDialog::accept(); -} - -void KIncidenceChooser::takeIncidence2() -{ - mSelIncidence = mInc2; - KDialog::accept(); -} - -void KIncidenceChooser::takeBoth() -{ - mSelIncidence = Incidence::Ptr(); - KDialog::accept(); -} - diff -Nru kdepim-runtime-4.14.6/libkdepim-copy/kincidencechooser.h kdepim-runtime-15.08.0/libkdepim-copy/kincidencechooser.h --- kdepim-runtime-4.14.6/libkdepim-copy/kincidencechooser.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/libkdepim-copy/kincidencechooser.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -/* - This file is part of libkdepim. - - Copyright (c) 2004 Lutz Rogowski - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, permission is given to link this program - with any edition of Qt, and distribute the resulting executable, - without including the source code for Qt in the source distribution. -*/ -#ifndef KDEPIM_KINCIDENCECHOOSER_H -#define KDEPIM_KINCIDENCECHOOSER_H - -#include "libkdepim-copy_export.h" -#include "calendardiffalgo.h" -#include "htmldiffalgodisplay.h" - -#include - -#include - -class QButtonGroup; -class QLabel; - -namespace KPIM { - -/** - @brief - Dialog to change the korganizer configuration. -*/ - -class KDEPIM_COPY_EXPORT KIncidenceChooser : public KDialog -{ - Q_OBJECT - public: - enum mode { - local, - remote, - newest, - ask, - both - }; - - /** Initialize dialog and pages */ - KIncidenceChooser( QWidget *parent = 0 ); - ~KIncidenceChooser(); - void setIncidence( const KCalCore::Incidence::Ptr &, - const KCalCore::Incidence::Ptr & ); - KCalCore::Incidence::Ptr getIncidence(); - static int chooseMode; - - public Q_SLOTS: - void useGlobalMode(); - - protected Q_SLOTS: - void showIncidence1(); - void showIncidence2(); - void showDiff(); - void takeIncidence1(); - void takeIncidence2(); - void takeBoth(); - void setLabels(); - void setSyncMode(); - void detailsDialogClosed(); - - private: - HTMLDiffAlgoDisplay *mDisplayDiff; - CalendarDiffAlgo *diff; - KDialog *mTbL, *mTbN; - KCalCore::Incidence::Ptr mSelIncidence; - KCalCore::Incidence::Ptr mInc1, mInc2; - QButtonGroup *mBg; - QPushButton *mDiffBut, *mShowDetails1, *mShowDetails2; - QLabel *mInc1lab, *mInc2lab, *mInc1Sumlab, *mInc2Sumlab, *mMod1lab, *mMod2lab; -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/libkdepim-copy/libkdepim-copy_export.h kdepim-runtime-15.08.0/libkdepim-copy/libkdepim-copy_export.h --- kdepim-runtime-4.14.6/libkdepim-copy/libkdepim-copy_export.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/libkdepim-copy/libkdepim-copy_export.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2007 David Faure - - 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 KDEPIM_COPY_EXPORT_H -#define KDEPIM_COPY_EXPORT_H - -/* needed for KDE_EXPORT and KDE_IMPORT macros */ -#include - -#ifndef KDEPIM_COPY_EXPORT -# if defined(KDEPIM_STATIC_LIBS) - /* No export/import for static libraries */ -# define KDEPIM_COPY_EXPORT -# elif defined(MAKE_KDEPIM_COPY_LIB) - /* We are building this library */ -# define KDEPIM_COPY_EXPORT KDE_EXPORT -# else - /* We are using this library */ -# define KDEPIM_COPY_EXPORT KDE_IMPORT -# endif -#endif - -# ifndef KDEPIM_COPY_EXPORT_DEPRECATED -# define KDEPIM_COPY_EXPORT_DEPRECATED KDE_DEPRECATED KDEPIM_COPY_EXPORT -# endif - -#endif diff -Nru kdepim-runtime-4.14.6/libkdepim-copy/Messages.sh kdepim-runtime-15.08.0/libkdepim-copy/Messages.sh --- kdepim-runtime-4.14.6/libkdepim-copy/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/libkdepim-copy/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -#! /bin/sh -#$XGETTEXT *.cpp -o $podir/libkdepim.pot diff -Nru kdepim-runtime-4.14.6/libkdepim-copy/tests/CMakeLists.txt kdepim-runtime-15.08.0/libkdepim-copy/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/libkdepim-copy/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/libkdepim-copy/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ - -set(testkincidencechooser_SRCS testkincidencechooser.cpp ) - -kde4_add_executable(testkincidencechooser TEST ${testkincidencechooser_SRCS}) - -target_link_libraries(testkincidencechooser kdepim-copy ${KDE4_KDEUI_LIBS} ${KDEPIMLIBS_KCALCORE_LIBS} ) diff -Nru kdepim-runtime-4.14.6/libkdepim-copy/tests/testkincidencechooser.cpp kdepim-runtime-15.08.0/libkdepim-copy/tests/testkincidencechooser.cpp --- kdepim-runtime-4.14.6/libkdepim-copy/tests/testkincidencechooser.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/libkdepim-copy/tests/testkincidencechooser.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -/* - Copyright (C) 2009 Allen Winter - - 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 -#include - -#include - -#include "../kincidencechooser.h" -using namespace KPIM; - -using namespace KCalCore; - -int main( int argc, char **argv ) -{ - KCmdLineArgs::init( argc, argv, "testkincidencechooser", 0, - ki18n( "KIncidenceChooserTest" ), "1.0", - ki18n( "kincidencechooser test app" ) ); - KApplication app; - KIncidenceChooser *chooser = new KIncidenceChooser(); - - Event::Ptr event( new Event() ); - event->setSummary( i18n( "Meeting" ) ); - event->setDescription( i18n( "Discuss foo" ) ); - chooser->setIncidence( event, event ); - chooser->resize( 600, 600 ); - chooser->show(); - return app.exec(); -} diff -Nru kdepim-runtime-4.14.6/MIGRATE-CONFIG-APPS kdepim-runtime-15.08.0/MIGRATE-CONFIG-APPS --- kdepim-runtime-4.14.6/MIGRATE-CONFIG-APPS 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/MIGRATE-CONFIG-APPS 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,3 @@ +Migrate configrc done: +- agent/newmailnotifieragent: akonadi_newmailnotifier_agentrc, akonadi_newmailnotifier_agent.notifyrc +- agent/maildispatcher: maildispatcheragentrc, akonadi_maildispatcher_agent.notifyrc diff -Nru kdepim-runtime-4.14.6/migration/cmake/FindXsltproc.cmake kdepim-runtime-15.08.0/migration/cmake/FindXsltproc.cmake --- kdepim-runtime-4.14.6/migration/cmake/FindXsltproc.cmake 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/cmake/FindXsltproc.cmake 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,32 @@ +# Find xsltproc executable and provide a macro to generate D-Bus interfaces. +# +# The following variables are defined : +# XSLTPROC_EXECUTABLE - path to the xsltproc executable +# Xsltproc_FOUND - true if the program was found +# +find_program(XSLTPROC_EXECUTABLE xsltproc DOC "Path to the xsltproc executable") +mark_as_advanced(XSLTPROC_EXECUTABLE) + +if(XSLTPROC_EXECUTABLE) + set(Xsltproc_FOUND TRUE) + + # We depend on kdepimlibs, make sure it's found + if(NOT DEFINED KF5Akonadi_DATA_DIR) + find_package(KF5Akonadi REQUIRED) + endif() + + + # Macro to generate a D-Bus interface description from a KConfigXT file + macro(kcfg_generate_dbus_interface _kcfg _name) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml + COMMAND ${XSLTPROC_EXECUTABLE} --stringparam interfaceName ${_name} + ${KF5Akonadi_DATA_DIR}/kcfg2dbus.xsl + ${_kcfg} + > ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml + DEPENDS ${KF5Akonadi_DATA_DIR}/kcfg2dbus.xsl + ${_kcfg} + ) + endmacro() +endif() + diff -Nru kdepim-runtime-4.14.6/migration/CMakeLists.txt kdepim-runtime-15.08.0/migration/CMakeLists.txt --- kdepim-runtime-4.14.6/migration/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,24 +1,45 @@ +project(migration) + + +if ("${CMAKE_SOURCE_DIR}" STREQUAL "${migration_SOURCE_DIR}") + find_package(ECM 5.9.0 CONFIG REQUIRED) + set(CMAKE_MODULE_PATH ${migration_SOURCE_DIR}/cmake ${ECM_MODULE_PATH}) + + include(ECMPackageConfigHelpers) + include(ECMSetupVersion) + include(FeatureSummary) + include(KDEInstallDirs) + include(KDECMakeSettings) + include(KDEFrameworkCompilerSettings) + set(KDEPIMLIBS_LIB_VERSION "4.75.0") + set(KF5_VERSION "5.9.0") + set(QT_REQUIRED_VERSION "5.4.0") + + find_package(KF5Config ${KF5_VERSION} CONFIG REQUIRED) + find_package(KF5KDELibs4Support ${KF5_VERSION} CONFIG REQUIRED) + find_package(KF5Akonadi ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5Mime ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5Contacts ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5MailTransport ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5Mbox ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5AkonadiMime ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5PimTextEdit ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5IMAP ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) +endif() + add_definitions( -DQT_NO_CAST_FROM_ASCII ) add_definitions( -DQT_NO_CAST_TO_ASCII ) +#REMOVE IT +remove_definitions(-DQT_NO_CAST_FROM_BYTEARRAY) -add_definitions( - -DKRESOURCES_DEPRECATED= - -DKABC_DEPRECATED= - -DKCAL_DEPRECATED= -) -# This one won't be needed when CMake 2.8.13 is depended on. -add_definitions( - -DKRESOURCES_DEPRECATED_EXPORT=KRESOURCES_EXPORT - -DKABC_DEPRECATED_EXPORT=KABC_EXPORT - -DKCAL_DEPRECATED_EXPORT=KCAL_EXPORT -) -add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/ ) -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) +# Xsltproc +find_package(Xsltproc) +set_package_properties(Xsltproc PROPERTIES DESCRIPTION "XSLT processor from libxslt" TYPE REQUIRED PURPOSE "Required to generate D-Bus interfaces for all Akonadi resources.") + set( MIGRATION_AKONADI_SHARED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/kmigratorbase.cpp @@ -28,13 +49,9 @@ ) -add_subdirectory( kmail ) -add_subdirectory( kaddressbook ) -add_subdirectory( kjots ) add_subdirectory( gid ) -if (KDEPIMLIBS_KRESOURCES_LIBS) - add_subdirectory( knotes ) - add_subdirectory( kres ) - add_subdirectory( tests ) -endif () + +if ("${CMAKE_SOURCE_DIR}" STREQUAL "${migration_SOURCE_DIR}") + feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) +endif() diff -Nru kdepim-runtime-4.14.6/migration/entitytreecreatejob.cpp kdepim-runtime-15.08.0/migration/entitytreecreatejob.cpp --- kdepim-runtime-4.14.6/migration/entitytreecreatejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/entitytreecreatejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -17,97 +17,101 @@ 02110-1301, USA. */ - #include "entitytreecreatejob.h" +#include +#include -#include -#include +#include using namespace Akonadi; static const char collectionIdMappingProperty[] = "collectionIdMappingProperty"; -EntityTreeCreateJob::EntityTreeCreateJob( const QList< Akonadi::Collection::List > &collections, const Akonadi::Item::List &items, QObject* parent ) - : Akonadi::TransactionSequence( parent ), m_collections( collections ), m_items( items ), m_pendingJobs( 0 ) +EntityTreeCreateJob::EntityTreeCreateJob(const QList< Akonadi::Collection::List > &collections, const Akonadi::Item::List &items, QObject *parent) + : Akonadi::TransactionSequence(parent), m_collections(collections), m_items(items), m_pendingJobs(0) { } void EntityTreeCreateJob::doStart() { - if ( !m_collections.isEmpty() ) - createNextLevelOfCollections(); - createReadyItems(); + if (!m_collections.isEmpty()) { + createNextLevelOfCollections(); + } + createReadyItems(); } void EntityTreeCreateJob::createNextLevelOfCollections() { - CollectionCreateJob *job; + CollectionCreateJob *job; - const Collection::List colList = m_collections.takeFirst(); - foreach ( const Collection &collection, colList ) { - ++m_pendingJobs; - job = new CollectionCreateJob( collection, this ); - job->setProperty( collectionIdMappingProperty, collection.id() ); - connect( job, SIGNAL(result(KJob*)), SLOT(collectionCreateJobDone(KJob*)) ); - } + const Collection::List colList = m_collections.takeFirst(); + foreach (const Collection &collection, colList) { + ++m_pendingJobs; + job = new CollectionCreateJob(collection, this); + job->setProperty(collectionIdMappingProperty, collection.id()); + connect(job, &CollectionCreateJob::result, this, &EntityTreeCreateJob::collectionCreateJobDone); + } } void EntityTreeCreateJob::createReadyItems() { - Item::List::iterator it; - for ( it = m_items.begin(); it != m_items.end(); ) { - Collection parentCollection = ( *it ).parentCollection(); - if ( parentCollection.isValid() ) { - (void) new ItemCreateJob( *it, parentCollection, this ); - it = m_items.erase( it ); - } else { - ++it; - } - } - if ( m_items.isEmpty() && m_collections.isEmpty() ) - commit(); + Item::List::iterator it; + for (it = m_items.begin(); it != m_items.end();) { + Collection parentCollection = (*it).parentCollection(); + if (parentCollection.isValid()) { + (void) new ItemCreateJob(*it, parentCollection, this); + it = m_items.erase(it); + } else { + ++it; + } + } + if (m_items.isEmpty() && m_collections.isEmpty()) { + commit(); + } } -void EntityTreeCreateJob::collectionCreateJobDone( KJob *job ) +void EntityTreeCreateJob::collectionCreateJobDone(KJob *job) { - Q_ASSERT( m_pendingJobs > 0 ); - --m_pendingJobs; - CollectionCreateJob *collectionCreateJob = qobject_cast( job ); - Collection createdCollection = collectionCreateJob->collection(); - - if ( job->error() ) { - kDebug() << job->errorString(); - return; - } - - const Collection::Id creationId = job->property( collectionIdMappingProperty ).toLongLong(); - - Item::List::iterator it; - const Item::List::iterator end = m_items.end(); - for ( it = m_items.begin(); it != end; ++it ) { - kDebug() << "updating items"; - if ( it->parentCollection().id() == creationId ) { - it->setParentCollection( createdCollection ); - } - } - - createReadyItems(); - - if ( !m_collections.isEmpty() ) { - Collection::List::iterator col_it; - const Collection::List::iterator col_end = m_collections[0].end(); - for ( col_it = m_collections[0].begin(); col_it != col_end; ++col_it ) { - if ( col_it->parentCollection().id() == creationId ) { - col_it->setParentCollection( createdCollection ); - } + Q_ASSERT(m_pendingJobs > 0); + --m_pendingJobs; + CollectionCreateJob *collectionCreateJob = qobject_cast(job); + Collection createdCollection = collectionCreateJob->collection(); + + if (job->error()) { + qDebug() << job->errorString(); + return; } - if ( m_pendingJobs == 0 ) - createNextLevelOfCollections(); - } - if ( m_items.isEmpty() && m_collections.isEmpty() ) - commit(); + const Collection::Id creationId = job->property(collectionIdMappingProperty).toLongLong(); + + Item::List::iterator it; + const Item::List::iterator end = m_items.end(); + for (it = m_items.begin(); it != end; ++it) { + qDebug() << "updating items"; + if (it->parentCollection().id() == creationId) { + it->setParentCollection(createdCollection); + } + } + + createReadyItems(); + + if (!m_collections.isEmpty()) { + Collection::List::iterator col_it; + const Collection::List::iterator col_end = m_collections[0].end(); + for (col_it = m_collections[0].begin(); col_it != col_end; ++col_it) { + if (col_it->parentCollection().id() == creationId) { + col_it->setParentCollection(createdCollection); + } + } + if (m_pendingJobs == 0) { + createNextLevelOfCollections(); + } + } + + if (m_items.isEmpty() && m_collections.isEmpty()) { + commit(); + } } diff -Nru kdepim-runtime-4.14.6/migration/entitytreecreatejob.h kdepim-runtime-15.08.0/migration/entitytreecreatejob.h --- kdepim-runtime-4.14.6/migration/entitytreecreatejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/entitytreecreatejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -17,34 +17,33 @@ 02110-1301, USA. */ - #ifndef ENTITYTREECREATEJOB_H #define ENTITYTREECREATEJOB_H -#include -#include -#include -#include +#include +#include +#include +#include class EntityTreeCreateJob : public Akonadi::TransactionSequence { - Q_OBJECT + Q_OBJECT public: - explicit EntityTreeCreateJob( const QList &collections, const Akonadi::Item::List &items, QObject* parent = 0 ); + explicit EntityTreeCreateJob(const QList &collections, const Akonadi::Item::List &items, QObject *parent = Q_NULLPTR); - /* reimp */ void doStart(); + /* reimp */ void doStart(); -private slots: - void collectionCreateJobDone( KJob * ); +private Q_SLOTS: + void collectionCreateJobDone(KJob *); private: - void createNextLevelOfCollections(); - void createReadyItems(); + void createNextLevelOfCollections(); + void createReadyItems(); private: - QList m_collections; - Akonadi::Item::List m_items; - int m_pendingJobs; + QList m_collections; + Akonadi::Item::List m_items; + int m_pendingJobs; }; #endif diff -Nru kdepim-runtime-4.14.6/migration/gid/CMakeLists.txt kdepim-runtime-15.08.0/migration/gid/CMakeLists.txt --- kdepim-runtime-4.14.6/migration/gid/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/gid/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -4,22 +4,21 @@ ${MIGRATION_AKONADI_SHARED_SOURCES} ) -kde4_add_library(gidmigration STATIC ${gid_SRCS}) +add_library(gidmigration STATIC ${gid_SRCS}) target_link_libraries(gidmigration - ${QT_QTCORE_LIBRARY} - ${KDE4_KDECORE_LIBS} - ${KDE4_KDEPIMLIBS_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} + KF5::AkonadiCore + KF5::Mime + KF5::ConfigCore + KF5::I18n + KF5::KDELibs4Support + Qt5::Core + Qt5::Widgets ) -kde4_add_executable(gidmigrator main.cpp) +add_executable(gidmigrator main.cpp) target_link_libraries(gidmigrator gidmigration - ${QT_QTCORE_LIBRARY} - ${KDE4_KDECORE_LIBS} - ${KDE4_KDEPIMLIBS_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} + KF5::AkonadiWidgets + KF5::Mime ) -install(TARGETS gidmigrator ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(TARGETS gidmigrator ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/migration/gid/gidmigrationjob.cpp kdepim-runtime-15.08.0/migration/gid/gidmigrationjob.cpp --- kdepim-runtime-4.14.6/migration/gid/gidmigrationjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/gid/gidmigrationjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,18 +18,18 @@ */ #include "gidmigrationjob.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include using namespace Akonadi; UpdateJob::UpdateJob(const Collection &col, QObject *parent) -: Job(parent), - mCollection(col), - mModJobRunning(false) + : Job(parent), + mCollection(col), + mModJobRunning(false) {} UpdateJob::~UpdateJob() @@ -44,7 +44,7 @@ fetchJob->fetchScope().setFetchRemoteIdentification(false); fetchJob->fetchScope().fetchFullPayload(true); //Limit scope to envelope only for mail - connect(fetchJob, SIGNAL(itemsReceived(Akonadi::Item::List)), this, SLOT(itemsReceived(Akonadi::Item::List))); + connect(fetchJob, &ItemFetchJob::itemsReceived, this, &UpdateJob::itemsReceived); } void UpdateJob::itemsReceived(const Akonadi::Item::List &items) @@ -62,7 +62,7 @@ //This slot is automatically called for all subjobs by KCompositeJob //FIXME the fetch job emits result before itemsReceived, because itemsReceived is triggered using the result signal (which is wrong IMO). See ItemFetchJob::timeout //If result was emitted at the end we could avoid having to call processNext in itemsReceived and locking it. - ItemFetchJob * const fetchJob = dynamic_cast(job); + ItemFetchJob *const fetchJob = dynamic_cast(job); const bool fetchReturnedNoItems = fetchJob && fetchJob->items().isEmpty(); Job::slotResult(job); if (fetchReturnedNoItems) { @@ -91,10 +91,9 @@ return true; } - GidMigrationJob::GidMigrationJob(const QStringList &mimeTypeFilter, QObject *parent) -: Job(parent), - mMimeTypeFilter(mimeTypeFilter) + : Job(parent), + mMimeTypeFilter(mimeTypeFilter) { } @@ -106,8 +105,8 @@ { CollectionFetchJob *fetchJob = new CollectionFetchJob(Collection::root(), CollectionFetchJob::Recursive, this); fetchJob->fetchScope().setContentMimeTypes(mMimeTypeFilter); - connect(fetchJob, SIGNAL(collectionsReceived(Akonadi::Collection::List)), this, SLOT(collectionsReceived(Akonadi::Collection::List))); - connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(collectionsFetched(KJob*))); + connect(fetchJob, &CollectionFetchJob::collectionsReceived, this, &GidMigrationJob::collectionsReceived); + connect(fetchJob, &CollectionFetchJob::result, this, &GidMigrationJob::collectionsFetched); } void GidMigrationJob::collectionsReceived(const Collection::List &collections) @@ -115,7 +114,7 @@ mCollections << collections; } -void GidMigrationJob::collectionsFetched( KJob *job ) +void GidMigrationJob::collectionsFetched(KJob *job) { //Errors are propagated by KCompositeJob if (!job->error()) { @@ -131,7 +130,7 @@ } const Collection col = mCollections.takeLast(); UpdateJob *updateJob = new UpdateJob(col, this); - connect(updateJob, SIGNAL(result(KJob*)), this, SLOT(itemsUpdated(KJob*))); + connect(updateJob, &UpdateJob::result, this, &GidMigrationJob::itemsUpdated); } void GidMigrationJob::itemsUpdated(KJob *job) diff -Nru kdepim-runtime-4.14.6/migration/gid/gidmigrationjob.h kdepim-runtime-15.08.0/migration/gid/gidmigrationjob.h --- kdepim-runtime-4.14.6/migration/gid/gidmigrationjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/gid/gidmigrationjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,9 +20,9 @@ #ifndef AKONADI_GIDMIGRATIONJOB_H #define AKONADI_GIDMIGRATIONJOB_H -#include -#include -#include +#include +#include +#include #include #include @@ -42,19 +42,19 @@ * @param mimeTypeFilter The list of mimetypes of objects to be migrated. * @param parent The parent object. */ - explicit GidMigrationJob(const QStringList &mimeTypeFilter, QObject *parent = 0); + explicit GidMigrationJob(const QStringList &mimeTypeFilter, QObject *parent = Q_NULLPTR); /** * Destroys the item fetch job. */ virtual ~GidMigrationJob(); - virtual void doStart(); + void doStart() Q_DECL_OVERRIDE; -private slots: +private Q_SLOTS: void collectionsReceived(const Akonadi::Collection::List &); - void collectionsFetched(KJob*); - void itemsUpdated(KJob*); + void collectionsFetched(KJob *); + void itemsUpdated(KJob *); private: void processCollection(); @@ -69,13 +69,13 @@ { Q_OBJECT public: - explicit UpdateJob(const Akonadi::Collection &col, QObject *parent = 0); + explicit UpdateJob(const Akonadi::Collection &col, QObject *parent = Q_NULLPTR); virtual ~UpdateJob(); - virtual void doStart(); - virtual void slotResult(KJob *job); + void doStart() Q_DECL_OVERRIDE; + void slotResult(KJob *job) Q_DECL_OVERRIDE; -private slots: +private Q_SLOTS: void itemsReceived(const Akonadi::Item::List &items); private: bool processNext(); diff -Nru kdepim-runtime-4.14.6/migration/gid/gidmigrator.cpp kdepim-runtime-15.08.0/migration/gid/gidmigrator.cpp --- kdepim-runtime-4.14.6/migration/gid/gidmigrator.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/gid/gidmigrator.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -11,7 +11,6 @@ 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, @@ -24,8 +23,8 @@ #include "gidmigrationjob.h" GidMigrator::GidMigrator(const QString &mimeType) - :MigratorBase(QLatin1String("gidmigrator") + mimeType), - mMimeType(mimeType) + : MigratorBase(QLatin1String("gidmigrator") + mimeType), + mMimeType(mimeType) { } @@ -41,7 +40,7 @@ QString GidMigrator::description() const { - return i18n("Ensures that all items with the mimetype %1 have a GID if a GID extractor is available.",mMimeType); + return i18n("Ensures that all items with the mimetype %1 have a GID if a GID extractor is available.", mMimeType); } bool GidMigrator::canStart() @@ -57,13 +56,13 @@ void GidMigrator::startWork() { GidMigrationJob *job = new GidMigrationJob(QStringList() << mMimeType, this); - connect(job, SIGNAL(result(KJob*)), this, SLOT(migrationFinished(KJob*))); + connect(job, &GidMigrationJob::result, this, &GidMigrator::migrationFinished); } void GidMigrator::migrationFinished(KJob *job) { if (job->error()) { - emit message(Error, i18n("Migration failed: %1", job->errorString())); + Q_EMIT message(Error, i18n("Migration failed: %1", job->errorString())); setMigrationState(Failed); } else { setMigrationState(Complete); diff -Nru kdepim-runtime-4.14.6/migration/gid/gidmigrator.h kdepim-runtime-15.08.0/migration/gid/gidmigrator.h --- kdepim-runtime-4.14.6/migration/gid/gidmigrator.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/gid/gidmigrator.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,7 +20,7 @@ #ifndef GIDMIGRATOR_H #define GIDMIGRATOR_H -#include +#include #include class GidMigrator: public MigratorBase @@ -39,7 +39,7 @@ protected: virtual void startWork(); -private slots: +private Q_SLOTS: void migrationFinished(KJob *); private: QString mMimeType; diff -Nru kdepim-runtime-4.14.6/migration/gid/main.cpp kdepim-runtime-15.08.0/migration/gid/main.cpp --- kdepim-runtime-4.14.6/migration/gid/main.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/gid/main.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -17,61 +17,66 @@ Boston, MA 02110-1301, USA. */ -#include +#include #include -#include + #include #include #include -#include -#include -#include -#include +#include + +#include +#include +#include #include +#include +#include #include "gidmigrator.h" int main(int argc, char **argv) { - KAboutData aboutData("gid-migrator", 0, - ki18n("GID Migration Tool"), - "0.1", - ki18n("Migration of Akonadi Items to support GID"), - KAboutData::License_LGPL, - ki18n("(c) 2013 the Akonadi developers"), - KLocalizedString(), - "http://pim.kde.org/akonadi/"); - aboutData.setProgramIconName(QLatin1String("akonadi")); - aboutData.addAuthor(ki18n("Christian Mollekopf"), ki18n("Author"), "mollekopf@kolabsys.com"); - - KCmdLineArgs::init(argc, argv, &aboutData); - KCmdLineOptions options; - options.add("interactive", ki18n("Show reporting dialog")); - options.add("interactive-on-change", ki18n("Show report only if changes were made")); - options.add("mimetype", ki18n("Mimetype to migrate")); - KCmdLineArgs::addCmdLineOptions(options); - KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + KLocalizedString::setApplicationDomain("gid-migrator"); + KAboutData aboutData(QStringLiteral("gid-migrator"), + i18n("GID Migration Tool"), + QStringLiteral("0.1"), + i18n("Migration of Akonadi Items to support GID"), + KAboutLicense::LGPL, + i18n("(c) 2013-2015 the Akonadi developers"), + QStringLiteral("http://pim.kde.org/akonadi/")); + aboutData.addAuthor(i18n("Christian Mollekopf"), i18n("Author"), QStringLiteral("mollekopf@kolabsys.com")); + + QCommandLineParser parser; + QApplication app(argc, argv); + parser.addVersionOption(); + parser.addHelpOption(); + parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("interactive"), i18n("Show reporting dialog"))); + parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("interactive-on-change"), i18n("Show report only if changes were made"))); + parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("mimetype"), i18n("MIME type to migrate"))); + + aboutData.setupCommandLine(&parser); + parser.process(app); + aboutData.processCommandLine(&parser); - KApplication *app = new KApplication(); - app->setQuitOnLastWindowClosed(false); + app.setQuitOnLastWindowClosed(false); + app.setWindowIcon(QIcon::fromTheme(QStringLiteral("akonadi"))); KGlobal::setAllowQuit(true); - KGlobal::locale()->insertCatalog(QLatin1String("libakonadi")); - if (!Akonadi::Control::start(0)) { + if (!Akonadi::ControlGui::start(0)) { return 2; } - InfoDialog *infoDialog = 0; - if (args->isSet("interactive") || args->isSet("interactive-on-change")) { - infoDialog = new InfoDialog(args->isSet("interactive-on-change")); - Akonadi::Control::widgetNeedsAkonadi(infoDialog); + InfoDialog *infoDialog = Q_NULLPTR; + if (parser.isSet(QStringLiteral("interactive")) || parser.isSet(QStringLiteral("interactive-on-change"))) { + infoDialog = new InfoDialog(parser.isSet(QStringLiteral("interactive-on-change"))); + Akonadi::ControlGui::widgetNeedsAkonadi(infoDialog); infoDialog->show(); } - const QString mimeType = args->getOption("mimetype"); + const QString mimeType = parser.value(QStringLiteral("mimetype")); if (mimeType.isEmpty()) { - kWarning() << "set the mimetype to migrate"; + qWarning() << "set the mimetype to migrate"; return 5; } @@ -79,13 +84,13 @@ if (infoDialog && migrator) { infoDialog->migratorAdded(); QObject::connect(migrator, SIGNAL(message(MigratorBase::MessageType,QString)), - infoDialog, SLOT(message(MigratorBase::MessageType,QString))); - QObject::connect(migrator, SIGNAL(destroyed()), infoDialog, SLOT(migratorDone())); + infoDialog, SLOT(message(MigratorBase::MessageType,QString))); + QObject::connect(migrator, &QObject::destroyed, infoDialog, &InfoDialog::migratorDone); QObject::connect(migrator, SIGNAL(progress(int)), infoDialog, SLOT(progress(int))); } - QObject::connect(migrator, SIGNAL(stoppedProcessing()), app, SLOT(quit)); + QObject::connect(migrator, SIGNAL(stoppedProcessing()), &app, SLOT(quit)); migrator->start(); - const int result = app->exec(); + const int result = app.exec(); if (InfoDialog::hasError() || migrator->migrationState() == MigratorBase::Failed) { return 3; } diff -Nru kdepim-runtime-4.14.6/migration/infodialog.cpp kdepim-runtime-15.08.0/migration/infodialog.cpp --- kdepim-runtime-4.14.6/migration/infodialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/infodialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,8 +20,8 @@ #include "infodialog.h" #include -#include -#include +#include +#include #include #include @@ -30,157 +30,164 @@ #include #include #include +#include +#include +#include enum { - // The max value of the scrollbar. Don't change this without making the kmail - // migrator use this. It still uses hardcoded "100". - MAX_PROGRESS = 100 + // The max value of the scrollbar. Don't change this without making the kmail + // migrator use this. It still uses hardcoded "100". + MAX_PROGRESS = 100 }; bool InfoDialog::mError = false; -InfoDialog::InfoDialog( bool closeWhenDone ) : - mMigratorCount( 0 ), - mChange( false ), - mCloseWhenDone( closeWhenDone ), - mAutoScrollList( true ) -{ - setAttribute( Qt::WA_DeleteOnClose ); - - KGlobal::ref(); - setButtons( Close ); - enableButton( Close, false ); - - QWidget *widget = new QWidget( this ); - QVBoxLayout *widgetLayout = new QVBoxLayout( widget ); - - mList = new QListWidget( widget ); - mList->setMinimumWidth( 640 ); - widgetLayout->addWidget( mList ); - - QHBoxLayout *statusLayout = new QHBoxLayout; - widgetLayout->addLayout( statusLayout ); - - mStatusLabel = new QLabel( widget ); - mStatusLabel->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred ); - statusLayout->addWidget( mStatusLabel ); - - mProgressBar = new QProgressBar( widget ); - mProgressBar->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred ); - mProgressBar->setMinimumWidth( 200 ); - statusLayout->addWidget( mProgressBar ); +InfoDialog::InfoDialog(bool closeWhenDone) : + mMigratorCount(0), + mChange(false), + mCloseWhenDone(closeWhenDone), + mAutoScrollList(true) +{ + setAttribute(Qt::WA_DeleteOnClose); + + mButtonBox = new QDialogButtonBox(QDialogButtonBox::Close); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + connect(mButtonBox, &QDialogButtonBox::accepted, this, &InfoDialog::accept); + connect(mButtonBox, &QDialogButtonBox::rejected, this, &InfoDialog::reject); + mButtonBox->button(QDialogButtonBox::Close)->setEnabled(false); + + QWidget *widget = new QWidget(this); + QVBoxLayout *widgetLayout = new QVBoxLayout(widget); + + mList = new QListWidget(widget); + mList->setMinimumWidth(640); + widgetLayout->addWidget(mList); + + QHBoxLayout *statusLayout = new QHBoxLayout; + widgetLayout->addLayout(statusLayout); + + mStatusLabel = new QLabel(widget); + mStatusLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); + statusLayout->addWidget(mStatusLabel); + + mProgressBar = new QProgressBar(widget); + mProgressBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + mProgressBar->setMinimumWidth(200); + statusLayout->addWidget(mProgressBar); + mainLayout->addWidget(widget); + mainLayout->addWidget(mButtonBox); - setMainWidget( widget ); } InfoDialog::~InfoDialog() { - KGlobal::deref(); } -static KMigratorBase::MessageType convertType( MigratorBase::MessageType type ) +static KMigratorBase::MessageType convertType(MigratorBase::MessageType type) { - switch ( type ) { + switch (type) { case MigratorBase::Success: return KMigratorBase::Success; case MigratorBase::Error: return KMigratorBase::Error; case MigratorBase::Skip: return KMigratorBase::Skip; case MigratorBase::Warning: return KMigratorBase::Warning; case MigratorBase::Info: return KMigratorBase::Info; - } - return KMigratorBase::Info; + } + return KMigratorBase::Info; } -void InfoDialog::message( MigratorBase::MessageType type, const QString& msg ) +void InfoDialog::message(MigratorBase::MessageType type, const QString &msg) { - message( convertType(type), msg ); + message(convertType(type), msg); } -void InfoDialog::message(KMigratorBase::MessageType type, const QString & msg) +void InfoDialog::message(KMigratorBase::MessageType type, const QString &msg) { - bool autoScroll = mAutoScrollList; + bool autoScroll = mAutoScrollList; - QListWidgetItem *item = new QListWidgetItem( msg, mList ); - switch ( type ) { + QListWidgetItem *item = new QListWidgetItem(msg, mList); + switch (type) { case KMigratorBase::Success: - item->setIcon( KIcon( QLatin1String("dialog-ok-apply") ) ); - mChange = true; - kDebug() << msg; - break; + item->setIcon(QIcon::fromTheme(QStringLiteral("dialog-ok-apply"))); + mChange = true; + qDebug() << msg; + break; case KMigratorBase::Skip: - item->setIcon( KIcon( QLatin1String("dialog-ok") ) ); - kDebug() << msg; - break; + item->setIcon(QIcon::fromTheme(QStringLiteral("dialog-ok"))); + qDebug() << msg; + break; case KMigratorBase::Info: - item->setIcon( KIcon( QLatin1String("dialog-information") ) ); - kDebug() << msg; - break; + item->setIcon(QIcon::fromTheme(QStringLiteral("dialog-information"))); + qDebug() << msg; + break; case KMigratorBase::Warning: - item->setIcon( KIcon( QLatin1String("dialog-warning") ) ); - kDebug() << msg; - break; + item->setIcon(QIcon::fromTheme(QStringLiteral("dialog-warning"))); + qDebug() << msg; + break; case KMigratorBase::Error: { - item->setIcon( KIcon( QLatin1String("dialog-error") ) ); + item->setIcon(QIcon::fromTheme(QStringLiteral("dialog-error"))); QFont currentFont = font(); - currentFont.setBold( true ); - item->setFont( currentFont ); + currentFont.setBold(true); + item->setFont(currentFont); mError = true; - kError() << msg; - } - break; + qCritical() << msg; + } + break; default: - kError() << "WTF?"; - } + qCritical() << "WTF?"; + } - mAutoScrollList = autoScroll; + mAutoScrollList = autoScroll; - if ( autoScroll ) { - mList->scrollToItem( item ); - } + if (autoScroll) { + mList->scrollToItem(item); + } } void InfoDialog::migratorAdded() { - ++mMigratorCount; - QApplication::setOverrideCursor( KCursor( QLatin1String( "wait" ), Qt::WaitCursor ) ); + ++mMigratorCount; + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); } void InfoDialog::migratorDone() { - QApplication::restoreOverrideCursor(); + QApplication::restoreOverrideCursor(); - --mMigratorCount; - if ( mMigratorCount == 0 ) { - enableButton( Close, true ); - status( QString() ); - if ( mCloseWhenDone && !hasError() && !hasChange() ) - accept(); - } + --mMigratorCount; + if (mMigratorCount == 0) { + mButtonBox->button(QDialogButtonBox::Close)->setEnabled(true); + status(QString()); + if (mCloseWhenDone && !hasError() && !hasChange()) { + accept(); + } + } } -void InfoDialog::status( const QString &msg ) +void InfoDialog::status(const QString &msg) { - mStatusLabel->setText( msg ); - if ( msg.isEmpty() ) { - progress( 0, MAX_PROGRESS, MAX_PROGRESS ); - mProgressBar->setFormat( QString() ); - } + mStatusLabel->setText(msg); + if (msg.isEmpty()) { + progress(0, MAX_PROGRESS, MAX_PROGRESS); + mProgressBar->setFormat(QString()); + } } -void InfoDialog::progress( int value ) +void InfoDialog::progress(int value) { - mProgressBar->setFormat( QLatin1String( "%p%" ) ); - mProgressBar->setValue( value ); + mProgressBar->setFormat(QStringLiteral("%p%")); + mProgressBar->setValue(value); } -void InfoDialog::progress( int min, int max, int value ) +void InfoDialog::progress(int min, int max, int value) { - mProgressBar->setFormat( QLatin1String( "%p%" ) ); - mProgressBar->setRange( min, max ); - mProgressBar->setValue( value ); + mProgressBar->setFormat(QStringLiteral("%p%")); + mProgressBar->setRange(min, max); + mProgressBar->setValue(value); } -void InfoDialog::scrollBarMoved( int value ) +void InfoDialog::scrollBarMoved(int value) { - mAutoScrollList = ( value == mList->verticalScrollBar()->maximum() ); + mAutoScrollList = (value == mList->verticalScrollBar()->maximum()); } diff -Nru kdepim-runtime-4.14.6/migration/infodialog.h kdepim-runtime-15.08.0/migration/infodialog.h --- kdepim-runtime-4.14.6/migration/infodialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/infodialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,39 +22,48 @@ #include "kmigratorbase.h" #include "migratorbase.h" - -#include +#include +#include class QLabel; class QListWidget; class QProgressBar; +class QDialogButtonBox; -class InfoDialog : public KDialog +class InfoDialog : public QDialog { - Q_OBJECT - public: - InfoDialog( bool closeWhenDone = true ); + Q_OBJECT +public: + InfoDialog(bool closeWhenDone = true); ~InfoDialog(); - public slots: - void message( KMigratorBase::MessageType type, const QString &msg ); - void message( MigratorBase::MessageType type, const QString &msg ); +public Q_SLOTS: + void message(KMigratorBase::MessageType type, const QString &msg); + void message(MigratorBase::MessageType type, const QString &msg); void migratorAdded(); void migratorDone(); - static bool hasError() { return mError; } - bool hasChange() const { return mChange; } - - void status( const QString &msg ); - - void progress( int value ); - void progress( int min, int max, int value ); - - private slots: - void scrollBarMoved( int value ); - - private: + static bool hasError() + { + return mError; + } + bool hasChange() const + { + return mChange; + } + + void status(const QString &msg); + + void progress(int value); + void progress(int min, int max, int value); + +private Q_SLOTS: + void scrollBarMoved(int value); + +private: + QEventLoopLocker eventLoopLocker; + QDialogButtonBox *mButtonBox; QListWidget *mList; QLabel *mStatusLabel; QProgressBar *mProgressBar; diff -Nru kdepim-runtime-4.14.6/migration/kaddressbook/CMakeLists.txt kdepim-runtime-15.08.0/migration/kaddressbook/CMakeLists.txt --- kdepim-runtime-4.14.6/migration/kaddressbook/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kaddressbook/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -set( kaddressbookmigrator_SRCS kaddressbookmigrator.cpp ) - -kde4_add_executable( kaddressbookmigrator ${kaddressbookmigrator_SRCS} ) - -target_link_libraries(kaddressbookmigrator ${KDE4_KDECORE_LIBS} ${KDEPIMLIBS_KABC_LIBS}) - -install(TARGETS kaddressbookmigrator ${INSTALL_TARGETS_DEFAULT_ARGS}) -install(PROGRAMS kaddressbookmigrator.desktop DESTINATION ${AUTOSTART_INSTALL_DIR}) diff -Nru kdepim-runtime-4.14.6/migration/kaddressbook/kaddressbookmigrator.cpp kdepim-runtime-15.08.0/migration/kaddressbook/kaddressbookmigrator.cpp --- kdepim-runtime-4.14.6/migration/kaddressbook/kaddressbookmigrator.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kaddressbook/kaddressbookmigrator.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -/* - Copyright (c) 2009 Tobias Koenig - - 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 -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -KABC::Addressee::List readContacts( bool *ok ) -{ - const QString fileName = KStandardDirs::locateLocal( "data", QLatin1String("kabc/std.vcf") ); - QFile file( fileName ); - if ( !file.open( QIODevice::ReadOnly ) ) { - kDebug() << QString::fromLatin1("Unable to open file %1 for reading" ).arg( fileName ); - *ok = false; - return KABC::Addressee::List(); - } - - const QByteArray content = file.readAll(); - file.close(); - - KABC::VCardConverter converter; - - *ok = true; - return converter.parseVCards( content ); -} - -bool writeContacts( const KABC::Addressee::List &contacts ) -{ - const QString path = QDir::home().absolutePath() + QLatin1String("/.local/share/contacts/"); - if ( !QDir::root().mkpath( path ) ) - return false; - - KABC::VCardConverter converter; - for ( int i = 0; i < contacts.count(); ++i ) { - const KABC::Addressee contact = contacts.at( i ); - const QByteArray content = converter.createVCard( contact ); - - const QString fileName = path + QDir::separator() + contact.uid() + QLatin1String(".vcf"); - QFile file( fileName ); - if ( !file.open( QIODevice::WriteOnly ) ) { - kDebug() << QString::fromLatin1( "Unable to open file %1 for writing" ).arg( fileName ); - return false; - } - - file.write( content ); - file.close(); - } - - return true; -} - -void convertAddressBook() -{ - /* The conversion is done by reading the file based default kresource address book - * $HOME/.kde/share/apps/kabc/std.vcf and creating a directory based address book - * under $HOME/.local/share/contacts. - */ - - bool ok = false; - const KABC::Addressee::List contacts = readContacts( &ok ); - if ( !ok ) - return; - - writeContacts( contacts ); -} - -int main( int argc, char **argv ) -{ - KAboutData aboutData( "kaddressbookmigrator", QByteArray(), ki18n( "Migration tool for the KDE address book" ), "0.1" ); - aboutData.addAuthor( ki18n( "Tobias Koenig" ), ki18n( "Author" ), "tokoe@kde.org" ); - - KCmdLineArgs::init( argc, argv, &aboutData ); - KCmdLineOptions options; - options.add( "disable-autostart", ki18n( "Disable automatic startup on login" ) ); - KCmdLineArgs::addCmdLineOptions( options ); - - QCoreApplication app( KCmdLineArgs::qtArgc(), KCmdLineArgs::qtArgv() ); - - KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - - if ( args->isSet( "disable-autostart" ) ) { - KSharedConfigPtr config = KGlobal::config(); - KConfigGroup group( config, "Startup" ); - group.writeEntry( "EnableAutostart", false ); - } - args->clear(); - convertAddressBook(); - - return 0; -} diff -Nru kdepim-runtime-4.14.6/migration/kaddressbook/kaddressbookmigrator.desktop kdepim-runtime-15.08.0/migration/kaddressbook/kaddressbookmigrator.desktop --- kdepim-runtime-4.14.6/migration/kaddressbook/kaddressbookmigrator.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kaddressbook/kaddressbookmigrator.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ -[Desktop Entry] -Name=kaddressbookmigrator -Name[bg]=kaddressbookmigrator -Name[bs]=kaddressbookmigrator -Name[ca]=kaddressbookmigrator -Name[ca@valencia]=kaddressbookmigrator -Name[cs]=kaddressbookmigrator -Name[da]=kaddressbookmigrator -Name[de]=Adressbuch-Migration -Name[el]=Μετατροπέας σε βιβλία διευθύνσεων του KAddressbook -Name[en_GB]=kaddressbookmigrator -Name[es]=kaddressbookmigrator -Name[et]=KDE aadressiraamatu migreerija -Name[fi]=kaddressbookmigrator -Name[fr]=kaddressbookmigrator -Name[ga]=kaddressbookmigrator -Name[gl]=kaddressbookmigrator -Name[hu]=kaddressbookmigrator -Name[ia]=Migrator de KAddressbook -Name[it]=kaddressbookmigrator -Name[ja]=アドレス帳移行ツール -Name[kk]=kaddressbookmigrator -Name[km]=kaddressbookmigrator -Name[ko]=kaddressbookmigrator -Name[lt]=kaddressbookmigrator -Name[lv]=kaddressbookmigrator -Name[nb]=kaddressbookmigrator -Name[nds]=KAdressbook-Överföhren -Name[nl]=kaddressbookmigrator -Name[nn]=kaddressbookmigrator -Name[pa]=kaddressbookmigrator -Name[pl]=kaddressbookmigrator -Name[pt]=kaddressbookmigrator -Name[pt_BR]=kaddressbookmigrator -Name[ru]=kaddressbookmigrator -Name[sk]=kaddressbookmigrator -Name[sl]=kaddressbookmigrator -Name[sr]=Мигратор К‑адресара -Name[sr@ijekavian]=Мигратор К‑адресара -Name[sr@ijekavianlatin]=Migrator K‑adresara -Name[sr@latin]=Migrator K‑adresara -Name[sv]=Adressboksöverföring -Name[tr]=kaddressbookmigrator -Name[uk]=kaddressbookmigrator -Name[x-test]=xxkaddressbookmigratorxx -Name[zh_CN]=KDE 地址簿迁移程序 -Name[zh_TW]=kaddressbookmigrator -Exec=kaddressbookmigrator --disable-autostart -Type=Application -Comment=Tool to migrate the old kresource based address book to Akonadi. -Comment[bs]=Alat za pomjeranje adresara baziranog na kresource u Akonadi. -Comment[ca]=Eina per a migrar l'adreça de contactes antiga basada en kresource a l'Akonadi. -Comment[ca@valencia]=Eina per a migrar l'adreça de contactes antiga basada en kresource a l'Akonadi. -Comment[da]=Værktøj til at migrere den gamle kresource-baserede adressebog til Akonadi. -Comment[de]=Werkzeug zum Migrieren alter auf Ressourcen basierender Adressbücher nach Akonadi -Comment[el]=Εργαλείο μετατροπής των παλιών βιβλίων διευθύνσεων του kresource σε βιβλία διευθύνσεων συμβατά με το Akonadi. -Comment[en_GB]=Tool to migrate the old kresource based address book to Akonadi. -Comment[es]=Herramienta para migrar la vieja libreta de direcciones basada en kresource a Akonadi. -Comment[et]=Tööriist vana KResource'i põhise aadressiraamatu migreerimiseks Akonadisse. -Comment[fi]=Työkalu vanhan kresource-pohjaisen osoitekirjan siirtämiseksi Akonadiin. -Comment[fr]=Outil permettant la migration du carnet d'adresses reposant sur l'ancienne « KResource » vers Akonadi. -Comment[gl]=Ferramenta para migrar o caderno de enderezos antigo baseado en kresource para Akonadi. -Comment[hu]=Segédprogram a régi, kresource alapú címjegyzék Akonadira migrálásához. -Comment[ia]=Instrumento pro transferer le etere adressario basate sur KResource a Akonadi. -Comment[it]=Strumento per migrare in Akonadi la rubrica del vecchio tipo kresource. -Comment[ja]=KDE の以前のリソースによるアドレス帳を Akonadi へ移行するツール -Comment[kk]=Ескі kresource адрестік кітапша мәліметін Akonadi-ге көшіру құралы -Comment[km]=ឧបករណ៍​ត្រូវ​ប្ដូរ​ kresource ចាស់​ដែល​មាន​មូលដ្ឋាន​លើ​សៀវភៅ​អាសយដ្ឋាន​ទៅ​កាន់ Akonadi ។ -Comment[ko]=과거 KResource 기반 주소록을 Akonadi로 이전합니다. -Comment[lt]=Įrankis, skirtas senų „kresource“ tipo adresų knygučių migravimui į Akonadi -Comment[lv]=Rīks veco kresource balstīto adrešu grāmatu migrēšanai uz Akonadi. -Comment[nb]=Verktøy for å overføre den gamle kresource-baserte adresseboka til Akonadi. -Comment[nds]=Programm för't Överföhren vun dat ole, op KRessource opbuut Adressbook na Akonadi -Comment[nl]=Hulpmiddel om het oude op kresource gebaseerde adresboek naar Akonadi te migreren. -Comment[pl]=Narzędzie to migracji starej książki adresowej kresource do Akonadi. -Comment[pt]=Uma ferramenta para migrar os livros de endereços antigos com KResources para o Akonadi. -Comment[pt_BR]=Ferramenta de migração do livro de endereços antigo baseado no kresource para o Akonadi. -Comment[ru]=Инструмент миграции старой адресной книги kresource в адресную книгу Akonadi. -Comment[sk]=Nástroj na migráciu starého adresára založeného na kresource do Akonadi. -Comment[sl]=Orodje za selitev starega imenika, temelječega na KResource, v Akonadi -Comment[sr]=Алатка за пресељење старих адресара у Аконади. -Comment[sr@ijekavian]=Алатка за пресељење старих адресара у Аконади. -Comment[sr@ijekavianlatin]=Alatka za preseljenje starih adresara u Akonadi. -Comment[sr@latin]=Alatka za preseljenje starih adresara u Akonadi. -Comment[sv]=Verktyg för att överföra en gammal adressbok baserad på kresource till Akonadi. -Comment[tr]=Kresource tabanlı eski adres defterini Akonadi'ye taşımak için araç -Comment[uk]="Інструмент для перетворення старої, заснованої на kresource адресної книги на адресну книгу Akonadi." -Comment[x-test]=xxTool to migrate the old kresource based address book to Akonadi.xx -Comment[zh_CN]=用于将基于 kresource 的旧地址簿资源迁移到 Akonadi 存储后端的工具。 -Comment[zh_TW]=將使用舊的 kresource 的通訊錄移植到 Akonadi 上。 -Terminal=false -NoDisplay=true -X-KDE-autostart-condition=kaddressbookmigratorrc:Startup:EnableAutostart:true -OnlyShowIn=KDE; diff -Nru kdepim-runtime-4.14.6/migration/kaddressbook/Messages.sh kdepim-runtime-15.08.0/migration/kaddressbook/Messages.sh --- kdepim-runtime-4.14.6/migration/kaddressbook/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kaddressbook/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -#!/bin/sh -$XGETTEXT ../*.cpp *.cpp -o $podir/kaddressbookmigrator.pot diff -Nru kdepim-runtime-4.14.6/migration/kjots/CMakeLists.txt kdepim-runtime-15.08.0/migration/kjots/CMakeLists.txt --- kdepim-runtime-4.14.6/migration/kjots/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kjots/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ - -set( kjotsmigrator_SRCS - main.cpp - kjotsmigrator.cpp - ${MIGRATION_AKONADI_SHARED_SOURCES} -) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/../../resources/maildir -) - -macro(add_resource_iface _kcfgFile _ifaceName _className) - kcfg_generate_dbus_interface(${kdepim-runtime_SOURCE_DIR}/resources/${_kcfgFile} ${_ifaceName}) - string(TOLOWER ${_className} _codeFile) - set_source_files_properties( ${CMAKE_CURRENT_BINARY_DIR}/${_ifaceName}.xml PROPERTIES INCLUDE "metatype.h") - qt4_add_dbus_interface(kjotsmigrator_SRCS - ${CMAKE_CURRENT_BINARY_DIR}/${_ifaceName}.xml ${_codeFile} ${_className} - ) -endmacro() - -add_resource_iface( maildir/maildirresource.kcfg - org.kde.Akonadi.Maildir.Settings MaildirSettings ) - -kde4_add_executable( kjotsmigrator ${kjotsmigrator_SRCS} ) - -target_link_libraries(kjotsmigrator - ${QT_QTXML_LIBRARY} - ${KDE4_KDECORE_LIBS} - ${KDE4_KDEPIMLIBS_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KPIMTEXTEDIT_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - maildir -) - -install(TARGETS kjotsmigrator ${INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/migration/kjots/kjotsmigrator.cpp kdepim-runtime-15.08.0/migration/kjots/kjotsmigrator.cpp --- kdepim-runtime-4.14.6/migration/kjots/kjotsmigrator.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kjots/kjotsmigrator.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,358 +0,0 @@ -/* - Copyright (c) 2010 Stephen Kelly - - 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 "kjotsmigrator.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "maildirsettings.h" - -#include "entitytreecreatejob.h" -#include - -using namespace Akonadi; - -KJotsMigrator::KJotsMigrator() - : KMigratorBase(), unicode( false ) -{ - m_dataDir = QDir( KStandardDirs::locateLocal( "data", QLatin1String("kjots") ) ); - m_dataDir.setNameFilters( QStringList( QLatin1String("*.book") ) ); - - if ( !m_dataDir.exists() ) { - return; - } - - const QString &kjotsCfgFile = KStandardDirs::locateLocal( "config", QLatin1String( "kjotsrc" ) ); - - KConfig config( kjotsCfgFile ); - KConfigGroup cfgGroup = config.group( "kjots" ); - unicode = cfgGroup.readEntry( "Unicode", false ); -} - -KJotsMigrator::~KJotsMigrator() -{ - -} - -void KJotsMigrator::migrate() -{ - emit message( Info, i18n( "Beginning KJots migration..." ) ); - - createAgentInstance( QLatin1String("akonadi_akonotes_resource"), this, SLOT(notesResourceCreated(KJob*)) ); -} - -void KJotsMigrator::notesResourceCreated( KJob *job ) -{ - if ( job->error() ) { - emit message( Error, i18n( "Failed to create resource for local notes: %1", job->errorText() ) ); - deleteLater(); - return; - } - emit message( Info, i18n( "Created local notes resource." ) ); - - AgentInstance instance = static_cast< AgentInstanceCreateJob* >( job )->instance(); - - instance.setName( i18nc( "Default name for resource holding notes", "Local Notes" ) ); - - OrgKdeAkonadiMaildirSettingsInterface *iface = new OrgKdeAkonadiMaildirSettingsInterface( - QLatin1String("org.freedesktop.Akonadi.Resource.") + instance.identifier(), - QLatin1String("/Settings"), QDBusConnection::sessionBus(), this ); - - if ( !iface->isValid() ) { - migrationFailed( i18n( "Failed to obtain D-Bus interface for remote configuration." ), instance ); - delete iface; - return; - } - - QDBusPendingReply response = iface->setPath( KGlobal::dirs()->localxdgdatadir() + QLatin1String("/notes/") + KRandom::randomString( 10 ) ); - - // make sure the config is saved - iface->writeConfig(); - - instance.reconfigure(); - m_resourceIdentifier = instance.identifier(); - - ResourceSynchronizationJob *syncJob = new ResourceSynchronizationJob( instance, this ); - connect( syncJob, SIGNAL(result(KJob*)), SLOT(syncDone(KJob*))); - syncJob->start(); -} - -void KJotsMigrator::syncDone(KJob *job) -{ - if ( job->error() ) { - emit message( Error, i18n( "Synchronizing the resource failed: %1" , job->errorString() ) ); - return; - } - emit message( Info, i18n( "Instance \"%1\" synchronized" , m_resourceIdentifier ) ); - - CollectionFetchJob *collectionFetchJob = new CollectionFetchJob( Collection::root(), CollectionFetchJob::FirstLevel, this ); - connect( collectionFetchJob, SIGNAL(collectionsReceived(Akonadi::Collection::List)), SLOT(rootCollectionsRecieved(Akonadi::Collection::List)) ); - connect( collectionFetchJob, SIGNAL(result(KJob*)), SLOT(rootFetchFinished(KJob*)) ); -} - -void KJotsMigrator::rootFetchFinished( KJob *job ) -{ - if ( job->error() ) { - emit message( Error, i18nc( "A job to fetch akonadi resources failed. %1 is the error string.", "Fetching resources failed: %1" , job->errorString() ) ); - } -} - -void KJotsMigrator::rootCollectionsRecieved( const Akonadi::Collection::List &list ) -{ - foreach ( const Collection &collection, list ) { - if ( collection.resource() == m_resourceIdentifier ) { - m_resourceCollection = collection; - emit message( Info, i18n( "New resource is rooted at Collection(%1)", collection.id() ) ); - startMigration(); - return; - } - } - emit message( Error, i18n( "Could not find root collection for resource \"%1\"" ,m_resourceIdentifier ) ); -} - -void KJotsMigrator::startMigration() -{ - m_bookFiles = m_dataDir.entryList(); - migrateNext(); -} - -void KJotsMigrator::migrateNext() -{ - if ( m_bookFiles.isEmpty() ) { - migrationFinished(); - return; - } - - QString bookFileName = m_bookFiles.takeFirst(); - emit message( Info, i18nc( "A migration tool is migrating the file named %1", "Migrating \"%1\"..." ,bookFileName ) ); - migrateLegacyBook( bookFileName ); -} - -void KJotsMigrator::migrationFinished() -{ - emit message( Info, i18n( "KJots notes migration finished" ) ); - deleteLater(); -} - -// This method taken from KJotsBook::openBook -void KJotsMigrator::migrateLegacyBook( const QString& fileName ) -{ - QFile file( KStandardDirs::locateLocal( "data", QLatin1String("kjots/") ) + QLatin1Char('/') + fileName ); - QDomDocument doc( QLatin1String("KJots") ); - bool oldBook = false; - - if ( !file.exists() || !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) { - emit message( Error, i18n( "Failed to open file: \"%1\"" ,fileName ) ); - return; - } - - emit message( Info, i18n( "Opened file: %1" , file.fileName() ) ); - - //Determine if this is a KDE3.5 era book. - QByteArray firstLine = file.readLine(); - file.reset(); - - if ( !firstLine.startsWith( "error() ) { - emit message( Error, i18n( "Error migrating book: %1", job->errorString() ) ); - } - migrateNext(); -} - - -void KJotsMigrator::parseBookXml( QDomElement &me, bool oldBook, const Collection &parentCollection, int depth ) -{ - Collection collection; - collection.setParentCollection( parentCollection ); - collection.setContentMimeTypes( QStringList() << Collection::mimeType() << QLatin1String("text/x-vnd.akonadi.note") ); - - QDomNode n = me.firstChild(); - - EntityDisplayAttribute *eda = new EntityDisplayAttribute(); - eda->setIconName( QLatin1String("x-office-address-book") ); - while ( !n.isNull() ) { - QDomElement e = n.toElement(); // try to convert the node to an element. - if ( !e.isNull() ) { - - if ( e.tagName() == QLatin1String("Title") ) { - eda->setDisplayName( e.text() ); - collection.setName( KRandom::randomString( 10 ) ); - } else - if ( e.tagName() == QLatin1String("ID") ) { - // Legacy ID attribute? - // setId(e.text().toULongLong()); - } else - if ( e.tagName() == QLatin1String("Color") ) { - QColor color( e.text() ); - eda->setBackgroundColor( color ); - } - if ( e.tagName() == QLatin1String("KJotsPage") ) { - parsePageXml( e, oldBook, collection ); - } else if ( e.tagName() == QLatin1String("KJotsBook") ) { - parseBookXml( e, oldBook, collection, depth + 1 ); - } else { - // Fatal error. Continue. - } - } - n = n.nextSibling(); - } - collection.addAttribute( eda ); - - while ( m_collectionLists.size() <= depth ) - m_collectionLists.append( Collection::List() ); - - Q_ASSERT( m_collectionLists.size() > depth ); - m_collectionLists[depth].append( collection ); - -} - -void KJotsMigrator::parsePageXml( QDomElement&me , bool oldBook, const Collection &parentCollection ) -{ - // serialize document to kmime message and append to items. - KMime::Message::Ptr note = KMime::Message::Ptr( new KMime::Message() ); - QByteArray encoding = "utf-8"; - - QTextDocument document; - EntityDisplayAttribute *eda = new EntityDisplayAttribute(); - eda->setIconName( QLatin1String("text-plain") ); - bool isRichText = false; - if ( me.tagName() == QLatin1String("KJotsPage") ) { - QDomNode n = me.firstChild(); - while ( !n.isNull() ) { - // Titles and Ids? - QDomElement e = n.toElement(); - if ( !e.isNull() ) { - if ( e.tagName() == QLatin1String("Title") ) { - note->subject()->fromUnicodeString( e.text(), encoding ); - } else - if ( e.tagName() == QLatin1String("ID") ) { - // Legacy ID attribute? - // setId(e.text().toULongLong()); - } else - if ( e.tagName() == QLatin1String("Color") ) { - QColor color( e.text() ); - eda->setBackgroundColor( color ); - } - if ( e.tagName() == QLatin1String("Text") ) { - QString bodyText = e.text(); - - //This is for 3.5 era book support. Remove when appropriate. - if ( e.hasAttribute( QLatin1String("fixed") ) ) { - bodyText.replace( QLatin1String("]]>"), QLatin1String("]]>") ); - } - - if ( oldBook ) { - // Ensure that whitespace is reproduced as in kjots of kde3.5. - // https://bugs.kde.org/show_bug.cgi?id=175100 - document.setPlainText( bodyText ); - } else { - if ( Qt::mightBeRichText( bodyText ) ) { - document.setHtml( bodyText ); - isRichText = KPIMTextEdit::TextUtils::containsFormatting( &document ); - } else - document.setPlainText( bodyText ); - } - } else { - // Fatal error move on. - } - } - n = n.nextSibling(); - } - } - KMime::Content* c = note->mainBodyPart(); - - note->contentType( true )->setMimeType( isRichText ? "text/html" : "text/plain" ); - note->contentType( true )->setCharset( "utf-8" ); - note->contentTransferEncoding( true )->setEncoding( KMime::Headers::CEquPr ); - c->fromUnicodeString( isRichText ? document.toHtml() : document.toPlainText() ); - - note->assemble(); - - Item item; - item.setParentCollection( parentCollection ); - item.setMimeType( QLatin1String("text/x-vnd.akonadi.note") ); - item.setPayload( note ); - item.addAttribute( eda ); - - m_items.append( item ); -} - -void KJotsMigrator::migrationFailed( const QString& errorMsg, const Akonadi::AgentInstance& instance ) -{ - Q_UNUSED( instance ) - emit message( Error, i18n( "Migration failed: %1" ,errorMsg ) ); -} - - diff -Nru kdepim-runtime-4.14.6/migration/kjots/kjotsmigrator.h kdepim-runtime-15.08.0/migration/kjots/kjotsmigrator.h --- kdepim-runtime-4.14.6/migration/kjots/kjotsmigrator.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kjots/kjotsmigrator.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -/* - Copyright (c) 2010 Stephen Kelly - - 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 KJOTSMIGRATOR_H -#define KJOTSMIGRATOR_H - -#include "kmigratorbase.h" - -#include - -#include - -#include -#include - -class QDomElement; - -class KJotsMigrator : public KMigratorBase -{ - Q_OBJECT -public: - KJotsMigrator(); - virtual ~KJotsMigrator(); - - /* reimp */ void migrate(); - /* reimp */ void migrateNext(); - -protected: - /* reimp */ void migrationFailed( const QString& errorMsg, const Akonadi::AgentInstance& instance = Akonadi::AgentInstance() ); - -private slots: - void notesResourceCreated( KJob *job ); - void bookMigrateJobFinished( KJob *job ); - void rootCollectionsRecieved( const Akonadi::Collection::List &list ); - void rootFetchFinished( KJob *job ); - void syncDone(KJob *job); - -private: - void migrateLegacyBook( const QString &filename ); - void parsePageXml( QDomElement&, bool, const Akonadi::Collection &parentCollection ); - void parseBookXml( QDomElement&, bool, const Akonadi::Collection &parentCollection, int depth ); - - void migrationFinished(); - void startMigration(); - -private: - QDir m_backupDir; - QDir m_dataDir; - QStringList m_bookFiles; - bool unicode; - QString m_resourceIdentifier; - - Akonadi::Item::List m_items; - QList m_collectionLists; - Akonadi::Collection m_resourceCollection; - -}; - -#endif - diff -Nru kdepim-runtime-4.14.6/migration/kjots/main.cpp kdepim-runtime-15.08.0/migration/kjots/main.cpp --- kdepim-runtime-4.14.6/migration/kjots/main.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kjots/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/* - Copyright (c) 2010 Stephen Kelly - - 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 "kjotsmigrator.h" - -#include "infodialog.h" - -#include - -#include -#include -#include -#include -#include - - -int main( int argc, char **argv ) -{ - KAboutData aboutData( "kjotsmigrator", 0, - ki18n( "KJots Migration Tool" ), - "0.1", - ki18n( "Migration of KJots notes to Akonadi" ), - KAboutData::License_LGPL, - ki18n( "(c) 2010 the Akonadi developers" ), - KLocalizedString(), - "http://pim.kde.org/akonadi/" ); - aboutData.setProgramIconName( QLatin1String("akonadi") ); - aboutData.addAuthor( ki18n( "Stephen Kelly" ), ki18n( "Author" ), "steveire@gmail.com" ); - - KCmdLineArgs::init( argc, argv, &aboutData ); - KCmdLineOptions options; - options.add( "interactive", ki18n( "Show reporting dialog" ) ); - options.add( "interactive-on-change", ki18n( "Show report only if changes were made" ) ); - KCmdLineArgs::addCmdLineOptions( options ); - KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - - KApplication *app = new KApplication(); - app->setQuitOnLastWindowClosed( false ); - - KGlobal::setAllowQuit( true ); - KGlobal::locale()->insertCatalog( QLatin1String("libakonadi") ); - - if ( !Akonadi::Control::start( 0 ) ) - return 2; - - InfoDialog *infoDialog = 0; - if ( args->isSet( "interactive" ) || args->isSet( "interactive-on-change" ) ) { - infoDialog = new InfoDialog( args->isSet( "interactive-on-change" ) ); - infoDialog->show(); - } - args->clear(); - - KJotsMigrator *migrator = new KJotsMigrator; - if ( infoDialog && migrator ) { - infoDialog->migratorAdded(); - QObject::connect( migrator, SIGNAL(message(KMigratorBase::MessageType,QString)), - infoDialog, SLOT(message(KMigratorBase::MessageType,QString)) ); - QObject::connect( migrator, SIGNAL(destroyed()), infoDialog, SLOT(migratorDone()) ); - } - - const int result = app->exec(); - if ( InfoDialog::hasError() ) - return 3; - return result; -} diff -Nru kdepim-runtime-4.14.6/migration/kjots/Messages.sh kdepim-runtime-15.08.0/migration/kjots/Messages.sh --- kdepim-runtime-4.14.6/migration/kjots/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kjots/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -#!/bin/sh -$XGETTEXT ../*.cpp *.cpp -o $podir/kjotsmigrator.pot diff -Nru kdepim-runtime-4.14.6/migration/kjots/metatype.h kdepim-runtime-15.08.0/migration/kjots/metatype.h --- kdepim-runtime-4.14.6/migration/kjots/metatype.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kjots/metatype.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -/* Copyright 2009 Thomas McGuire - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 POP3_METATYPE_H -#define POP3_METATYPE_H - -#include -#include - -#include - -Q_DECLARE_METATYPE(QList) - -#endif diff -Nru kdepim-runtime-4.14.6/migration/kmail/abstractcollectionmigrator.cpp kdepim-runtime-15.08.0/migration/kmail/abstractcollectionmigrator.cpp --- kdepim-runtime-4.14.6/migration/kmail/abstractcollectionmigrator.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/abstractcollectionmigrator.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,841 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.com - Copyright (C) 2011 Kevin Krammer, kevin.krammer@gmx.at - - 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 "abstractcollectionmigrator.h" - -#include "libmaildir/maildir.h" -#include "mixedmaildirstore.h" - -#include "filestore/collectionfetchjob.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "collectionannotationsattribute.h" - -#include -#include -#include - -#include -#include - -#define KOLAB_SHAREDSEEN "/shared/vendor/cmu/cyrus-imapd/sharedseen" -#define KOLAB_INCIDENCESFOR "/shared/vendor/kolab/incidences-for" -#define KOLAB_FOLDERTYPE "/shared/vendor/kolab/folder-type" - - -using namespace Akonadi; -using KPIM::Maildir; - -typedef QHash CollectionHash; -typedef QQueue CollectionQueue; - -typedef QHash IconNameHash; - -static QString remoteIdPath( const Collection& collection ) { - const Collection parent = collection.parentCollection(); - if ( parent.remoteId().isEmpty() ) { - return collection.remoteId(); - } - - return remoteIdPath( parent ) + QLatin1Char( '/' ) + collection.remoteId(); -} - -class AbstractCollectionMigrator::Private -{ - AbstractCollectionMigrator *const q; - - public: - Private( AbstractCollectionMigrator *parent, const AgentInstance &resource, const QString &resourceName, MixedMaildirStore *store ) - : q( parent ), mResource( resource ), mResourceName( resourceName ), mStore( store ), mHiddenSession( 0 ), mKMailConfig( 0 ), - mEmailIdentityConfig( 0 ), mKcmKmailSummaryConfig( 0 ), mTemplatesConfig( 0 ), mOverallCollectionsCount( 0 ), - mProcessedCollectionsCount( 0 ), mNeedModifyJob( false ) - { - } - - ~Private() - { - delete mHiddenSession; - } - - void migrateConfig(); - void collectionDone(); - - public: - AgentInstance mResource; - const QString mResourceName; - MixedMaildirStore *mStore; - Session *mHiddenSession; - - QString mTopLevelFolder; - QString mTopLevelCollectionName; - QString mTopLevelRemoteId; - KSharedConfigPtr mKMailConfig; - KSharedConfigPtr mEmailIdentityConfig; - KSharedConfigPtr mKcmKmailSummaryConfig; - KSharedConfigPtr mTemplatesConfig; - - CollectionQueue mCollectionQueue; - int mOverallCollectionsCount; - int mProcessedCollectionsCount; - - CollectionHash mAkonadiCollectionsByPath; - - Collection mCurrentCollection; - Collection mCurrentStoreCollection; - QString mCurrentFolderId; - QString mCurrentStoreFolderId; - - bool mNeedModifyJob; - - static IconNameHash mIconNamesBySpecialType; - - public: // slots - void collectionFetchResult( KJob *job ); - void collectionCreateResult( KJob *job ); - void modifyResult( KJob *job ); - void processNextCollection(); - - private: - QStringList folderPathComponentsForCollection( const Collection &collection, bool isStoreCollection = false ) const; - QString folderIdentifierForCollection( const Collection &collection, bool isStoreCollection = false ) const; - void processingDone(); -}; - -IconNameHash AbstractCollectionMigrator::Private::mIconNamesBySpecialType; - -void AbstractCollectionMigrator::Private::migrateConfig() -{ - // TODO should we have the new settings in a new KMail config? - - if ( mCurrentFolderId.isEmpty() || !mCurrentCollection.isValid() ) { - return; - } -// kDebug( KDE_DEFAULT_DEBUG_AREA ) << "migrating config for folderId" << mCurrentFolderId -// << "to collectionId" << mCurrentCollection.id(); - - // general folder specific settings - const QString folderGroupPattern = QLatin1String( "Folder-%1" ); - if ( mKMailConfig->hasGroup( folderGroupPattern.arg( mCurrentFolderId ) ) ) { - KConfigGroup oldGroup( mKMailConfig, folderGroupPattern.arg( mCurrentFolderId ) ); - KConfigGroup newGroup( mKMailConfig, folderGroupPattern.arg( mCurrentCollection.id() ) ); - oldGroup.copyTo( &newGroup ); - oldGroup.deleteGroup(); - newGroup.writeEntry( "ConvertedFrom", mCurrentFolderId ); - if ( newGroup.readEntry( "UseCustomIcons", false ) ) { - EntityDisplayAttribute *attribute = mCurrentCollection.attribute( Akonadi::Collection::AddIfMissing ); - //kDebug( KDE_DEFAULT_DEBUG_AREA )<<" NormalIconPath :"<setIconName( newGroup.readEntry( "NormalIconPath" ) ); - attribute->setActiveIconName( newGroup.readEntry( "UnreadIconPath" ) ); - - // collection modification needs to be sent to Akonadi - mNeedModifyJob = true; - } - - newGroup.deleteEntry( "UseCustomIcons" ); - newGroup.deleteEntry( "UnreadIconPath" ); - newGroup.deleteEntry( "NormalIconPath" ); - - Akonadi::CollectionAnnotationsAttribute *annotationsAttribute = mCurrentCollection.attribute( Entity::AddIfMissing ); - QMap annotations = annotationsAttribute->annotations(); - if ( newGroup.readEntry( "SharedSeenFlags", false ) ) { - annotations[ KOLAB_SHAREDSEEN ] = "true"; - mNeedModifyJob = true; - } - newGroup.deleteEntry( "SharedSeenFlags" ); - if ( newGroup.hasKey( "IncidencesFor" ) ) { - const QString incidenceFor = newGroup.readEntry( "IncidencesFor" ); - //kDebug( KDE_DEFAULT_DEBUG_AREA ) << "IncidencesFor=" << incidenceFor; - if ( incidenceFor == QLatin1String("nobody") ) { - annotations[ KOLAB_INCIDENCESFOR ] = "nobody"; - } else if ( incidenceFor == QLatin1String("admins") ) { - annotations[ KOLAB_INCIDENCESFOR ] = "admins"; - } else if ( incidenceFor == QLatin1String("readers") ) { - annotations[ KOLAB_INCIDENCESFOR ] = "readers"; - } else { - annotations[ KOLAB_INCIDENCESFOR ] = "admins"; //Default - } - mNeedModifyJob = true; - newGroup.deleteEntry( "IncidencesFor" ); - } - if ( newGroup.hasKey( "Annotation-FolderType" ) ) { - const QString annotationFolderType = newGroup.readEntry( "Annotation-FolderType" ); - EntityDisplayAttribute *attribute = mCurrentCollection.attribute( Akonadi::Collection::AddIfMissing ); - if ( annotationFolderType == QLatin1String("mail") ) { - //???? - } else if ( annotationFolderType == QLatin1String("event") ) { - annotations[ KOLAB_FOLDERTYPE ] = "event"; - attribute->setIconName( QLatin1String("view-calendar") ); - } else if ( annotationFolderType == QLatin1String("task") ) { - annotations[ KOLAB_FOLDERTYPE ] = "task"; - attribute->setIconName( QLatin1String("view-pim-tasks") ); - } else if ( annotationFolderType == QLatin1String("contact") ) { - annotations[ KOLAB_FOLDERTYPE ] = "contact"; - attribute->setIconName( QLatin1String("view-pim-contacts") ); - } else if ( annotationFolderType == QLatin1String("note") ) { - annotations[ KOLAB_FOLDERTYPE ] = "note"; - attribute->setIconName( QLatin1String("view-pim-notes") ); - } else if ( annotationFolderType == QLatin1String("journal") ) { - annotations[ KOLAB_FOLDERTYPE ] = "journal"; - attribute->setIconName( QLatin1String("view-pim-journal") ); - } else { - //???? - } - mNeedModifyJob = true; - newGroup.deleteEntry( "Annotation-FolderType" ); - } - const QString whofield = newGroup.readEntry( "WhoField" ); - if ( !whofield.isEmpty() ) { - Akonadi::MessageFolderAttribute *messageFolder = mCurrentCollection.attribute( Akonadi::Entity::AddIfMissing ); - - if ( whofield == QLatin1String( "To" ) ) - messageFolder->setOutboundFolder( true ); - else if( whofield == QLatin1String( "From" ) ) - messageFolder->setOutboundFolder( false ); - mNeedModifyJob = true; - } - newGroup.deleteEntry( "WhoField" ); - - //Delete old entry - newGroup.deleteEntry( "TotalMsgs" ); - newGroup.deleteEntry( "FolderSize" ); - newGroup.deleteEntry( "UnreadMsgs" ); - newGroup.deleteEntry( "Compactable" ); - newGroup.deleteEntry( "ContentsType" ); - newGroup.deleteEntry( "NoContent" ); - newGroup.deleteEntry( "ReadOnly" ); - newGroup.deleteEntry( "UploadAllFlags" ); - newGroup.deleteEntry( "PermanentFlags" ); - newGroup.deleteEntry( "StorageQuotaUsage" ); - newGroup.deleteEntry( "StorageQuotaLimit" ); - newGroup.deleteEntry( "StorageQuotaRoot" ); - newGroup.deleteEntry( "FolderAttributes" ); - newGroup.deleteEntry( "AlarmsBlocked" ); - newGroup.deleteEntry( "IncidencesForChanged" ); - newGroup.deleteEntry( "UserRights" ); - newGroup.deleteEntry( "StatusChangedLocally" ); - - newGroup.deleteEntry( "MainFolderViewItemDnDSortingKey" ); - newGroup.deleteEntry( "MainFolderViewItemIsExpanded" ); - newGroup.deleteEntry( "MainFolderViewItemIsHidden" ); - newGroup.deleteEntry( "MainFolderViewItemIsSelected" ); - - newGroup.deleteEntry( "Annotation-FolderType" ); - newGroup.deleteEntry( "AnnotationFolderTypeChanged" ); - newGroup.deleteEntry( "SystemLabel" ); - newGroup.deleteEntry( "ImapPath" ); - - //Migrate favorite folder - if ( newGroup.hasKey( "Id" ) ) { - uint value = newGroup.readEntry( "Id", 0 ); - bool favoriteCollectionsMigrated = mKMailConfig->hasGroup( "FavoriteCollections" ); - - KConfigGroup newFavoriteGroup( mKMailConfig, "FavoriteCollections" ); - if ( mKMailConfig->hasGroup( "FavoriteFolderView" ) && !favoriteCollectionsMigrated ) { - KConfigGroup oldFavoriteGroup( mKMailConfig, "FavoriteFolderView" ); - const QList lIds = oldFavoriteGroup.readEntry( "FavoriteFolderIds", QList() ); - const QStringList lNames = oldFavoriteGroup.readEntry( "FavoriteFolderNames", QStringList() ); - oldFavoriteGroup.copyTo( &newFavoriteGroup ); - oldFavoriteGroup.deleteGroup(); - - //kDebug( KDE_DEFAULT_DEBUG_AREA ) << "FAVORITE COLLECTION lIds=" << lIds<<" lNames="< lIds = newFavoriteGroup.readEntry( "FavoriteCollectionIds", QList() ); - if ( lIds.contains( value ) ) { - const int pos = lIds.indexOf( value ); - lIds.replace( pos, mCurrentCollection.id() ); - newFavoriteGroup.writeEntry( "FavoriteCollectionIds", lIds ); - } - } - newGroup.deleteEntry( "Id" ); - } - } - - // check emailidentity - const QStringList identityGroups = mEmailIdentityConfig->groupList().filter( QRegExp( QLatin1String("Identity #\\d+") ) ); - //kDebug( KDE_DEFAULT_DEBUG_AREA ) << "identityGroups=" << identityGroups; - Q_FOREACH ( const QString &groupName, identityGroups ) { - KConfigGroup identityGroup( mEmailIdentityConfig, groupName ); - if ( identityGroup.readEntry( "Drafts" ) == mCurrentFolderId ) - identityGroup.writeEntry( "Drafts", mCurrentCollection.id() ); - if ( identityGroup.readEntry( "Templates" ) == mCurrentFolderId ) - identityGroup.writeEntry( "Templates", mCurrentCollection.id() ); - if ( identityGroup.readEntry( "Fcc" ) == mCurrentFolderId ) - identityGroup.writeEntry( "Fcc", mCurrentCollection.id() ); - - } - - // Check kcmkmailsummaryrc General/ActiveFolders - KConfigGroup kcmkmailsummary( mKcmKmailSummaryConfig, "General" ); - if ( kcmkmailsummary.hasKey( "ActiveFolders" ) ) { - if ( !kcmkmailsummary.hasKey( "Role_CheckState" ) ) { - kcmkmailsummary.writeEntry( "Role_CheckState", kcmkmailsummary.readEntry( "ActiveFolders", QStringList() ) ); - kcmkmailsummary.sync(); - } - - QStringList lstCollection = kcmkmailsummary.readEntry( "Role_CheckState", QStringList() ); - QString visualPath( mCurrentFolderId ); - visualPath.remove( QLatin1String(".directory") ); - visualPath.replace( QLatin1String("/."), QLatin1String("/") ); - if ( !visualPath.isEmpty() && ( visualPath.at( 0 ) == QLatin1Char('.') ) ) - visualPath.remove( 0, 1 ); //remove first "." - - const QString localFolderPattern = QLatin1String( "/Local/%1" ); - const QString imapFolderPattern = QLatin1String( "/%1" ); - const QString newCollectionPattern = QLatin1String( "c%1" ); - if ( lstCollection.contains( localFolderPattern.arg( visualPath ) ) ) { - const int pos = lstCollection.indexOf( localFolderPattern.arg( visualPath ) ); - lstCollection.replace( pos, newCollectionPattern.arg( mCurrentCollection.id() ) ); - lstCollection.insert( pos+1, QLatin1String("2") ); - kcmkmailsummary.writeEntry( "Role_CheckState", lstCollection ); - } else if ( lstCollection.contains( imapFolderPattern.arg( visualPath ) ) ) { - const int pos = lstCollection.indexOf( imapFolderPattern.arg( visualPath ) ); - lstCollection.replace( pos, newCollectionPattern.arg( mCurrentCollection.id() ) ); - lstCollection.insert( pos+1, QLatin1String("2") ); - - kcmkmailsummary.writeEntry( "Role_CheckState", lstCollection ); - } - } - - // Check Composer/previous-fcc - KConfigGroup composer( mKMailConfig, "Composer" ); - if ( composer.readEntry( "previous-fcc" ) == mCurrentFolderId ) - composer.writeEntry( "previous-fcc", mCurrentCollection.id() ); - - // Check FolderSelectionDialog/LastSelectedFolder - KConfigGroup folderSelection( mKMailConfig, "FolderSelectionDialog" ); - if ( folderSelection.readEntry( "LastSelectedFolder", mCurrentFolderId ) == mCurrentFolderId ) - folderSelection.writeEntry( "LastSelectedFolder", mCurrentCollection.id() ); - folderSelection.deleteEntry( "TreeWidgetLayout" ); - - - // Check General/startupFolder - KConfigGroup general( mKMailConfig, "General" ); - if ( general.readEntry( "startupFolder" ) == mCurrentFolderId ) - general.writeEntry( "startupFolder", mCurrentCollection.id() ); - general.deleteEntry( "default-mailbox-format" ); - - // check all expire folder - const QStringList folderGroups = mKMailConfig->groupList().filter( QLatin1String("Folder-") ); - //kDebug( KDE_DEFAULT_DEBUG_AREA ) << "folderGroups=" << folderGroups; - Q_FOREACH ( const QString &groupName, folderGroups ) { - KConfigGroup filterGroup( mKMailConfig, groupName ); - if ( filterGroup.readEntry( "ExpireToFolder" ) == mCurrentFolderId ) - filterGroup.writeEntry( "ExpireToFolder", mCurrentCollection.id() ); - } - - // check all account folder - const QStringList accountGroups = mKMailConfig->groupList().filter( QRegExp( QLatin1String("Account \\d+") ) ); - //kDebug( KDE_DEFAULT_DEBUG_AREA ) << "accountGroups=" << accountGroups; - Q_FOREACH ( const QString &groupName, accountGroups ) { - KConfigGroup accountGroup( mKMailConfig, groupName ); - - if ( accountGroup.readEntry( "Folder" ) == mCurrentFolderId ) { - accountGroup.writeEntry( "Folder", mCurrentCollection.id() ); - } - - if ( accountGroup.readEntry( "trash" ) == mCurrentFolderId ) { - accountGroup.writeEntry( "trash" , mCurrentCollection.id() ); - - // this is configured as a trash collection, so make sure it gets the appropriate attribute - // unless there is already a trash collection for this resource - // (unfortunately special collections enforce uniqueness per resource) - if ( !SpecialMailCollections::self()->hasCollection( SpecialMailCollections::Trash, mResource ) ) { - q->registerAsSpecialCollection( SpecialMailCollections::Trash ); - } - } - } - - // check all filters - const QStringList filterGroups = mKMailConfig->groupList().filter( QRegExp( QLatin1String("Filter #\\d+") ) ); - //kDebug( KDE_DEFAULT_DEBUG_AREA ) << "filterGroups=" << filterGroups; - Q_FOREACH ( const QString &groupName, filterGroups ) { - KConfigGroup filterGroup( mKMailConfig, groupName ); - - const QStringList actionKeys = filterGroup.keyList().filter( QRegExp( QLatin1String("action-args-\\d+") ) ); - //kDebug( KDE_DEFAULT_DEBUG_AREA ) << "actionKeys=" << actionKeys; - - Q_FOREACH ( const QString &actionKey, actionKeys ) { - if ( filterGroup.readEntry( actionKey, QString() ) == mCurrentFolderId ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "replacing folder id for action" << actionKey - << "in group" << groupName; - filterGroup.writeEntry( actionKey, mCurrentCollection.id() ); - } - } - } - - // check MessageListView::StorageModelAggregations - KConfigGroup storageModelAggregationGroup( mKMailConfig, QLatin1String( "MessageListView::StorageModelAggregations" ) ); - const QString setForStorageAggregationModelPattern = QLatin1String( "SetForStorageModel%1" ); - if ( storageModelAggregationGroup.hasKey( setForStorageAggregationModelPattern.arg( mCurrentFolderId ) ) ) { - const QString value = storageModelAggregationGroup.readEntry( setForStorageAggregationModelPattern.arg( mCurrentFolderId ) ); - storageModelAggregationGroup.writeEntry( setForStorageAggregationModelPattern.arg( mCurrentCollection.id() ),value ); - storageModelAggregationGroup.deleteEntry( setForStorageAggregationModelPattern.arg( mCurrentFolderId ) ); - } - - // check MessageListView::StorageModelThemes - KConfigGroup storageModelThemesGroup( mKMailConfig, QLatin1String( "MessageListView::StorageModelThemes" ) ); - const QString setForStorageModelPattern = QLatin1String( "SetForStorageModel%1" ); - if ( storageModelThemesGroup.hasKey( setForStorageModelPattern.arg( mCurrentFolderId ) ) ) { - const QString value = storageModelThemesGroup.readEntry( setForStorageModelPattern.arg( mCurrentFolderId ) ); - storageModelThemesGroup.writeEntry( setForStorageModelPattern.arg( mCurrentCollection.id() ),value ); - storageModelThemesGroup.deleteEntry( setForStorageModelPattern.arg( mCurrentFolderId ) ); - } - - // check MessageListView::StorageModelSortOrder - KConfigGroup sortOrderGroup( mKMailConfig, QLatin1String( "MessageListView::StorageModelSortOrder" ) ); - const QString groupSortDirectionPattern = QLatin1String( "%1GroupSortDirection" ); - const QString groupSortingPattern = QLatin1String( "%1GroupSorting" ); - const QString messageSortDirectionPattern = QLatin1String( "%1MessageSortDirection" ); - const QString messageSortingPattern = QLatin1String( "%1MessageSorting" ); - - if ( sortOrderGroup.hasKey( groupSortDirectionPattern.arg( mCurrentFolderId ) ) ) { - const QString value = sortOrderGroup.readEntry( groupSortDirectionPattern.arg( mCurrentFolderId ) ); - sortOrderGroup.writeEntry( groupSortDirectionPattern.arg( mCurrentCollection.id() ), value ); - sortOrderGroup.deleteEntry( groupSortDirectionPattern.arg( mCurrentFolderId ) ); - } - - if ( sortOrderGroup.hasKey( groupSortingPattern.arg( mCurrentFolderId ) ) ) { - const QString value = sortOrderGroup.readEntry( groupSortingPattern.arg( mCurrentFolderId ) ); - sortOrderGroup.writeEntry( groupSortingPattern.arg( mCurrentCollection.id() ), value ); - sortOrderGroup.deleteEntry( groupSortingPattern.arg( mCurrentFolderId ) ); - } - - if ( sortOrderGroup.hasKey( messageSortingPattern.arg( mCurrentFolderId ) ) ) { - const QString value = sortOrderGroup.readEntry( messageSortingPattern.arg( mCurrentFolderId ) ); - sortOrderGroup.writeEntry( messageSortingPattern.arg( mCurrentCollection.id() ), value ); - sortOrderGroup.deleteEntry( messageSortingPattern.arg( mCurrentFolderId ) ); - } - - if ( sortOrderGroup.hasKey( messageSortDirectionPattern.arg( mCurrentFolderId ) ) ) { - const QString value = sortOrderGroup.readEntry( messageSortDirectionPattern.arg( mCurrentFolderId ) ); - sortOrderGroup.writeEntry( messageSortDirectionPattern.arg( mCurrentCollection.id() ), value ); - sortOrderGroup.deleteEntry( messageSortDirectionPattern.arg( mCurrentFolderId ) ); - } - - - - - // check MessageListView::StorageModelSelectedMessages - KConfigGroup selectedMessagesGroup( mKMailConfig, QLatin1String( "MessageListView::StorageModelSelectedMessages" ) ); - const QString storageModelPattern = QLatin1String( "MessageUniqueIdForStorageModel%1" ); - if ( selectedMessagesGroup.hasKey( storageModelPattern.arg( mCurrentFolderId ) ) ) { - //kDebug( KDE_DEFAULT_DEBUG_AREA ) << "replacing selected message entry for" - // << mCurrentFolderId; - const qulonglong defValue = 0; - const qulonglong value = selectedMessagesGroup.readEntry( storageModelPattern.arg( mCurrentFolderId ), defValue ); - selectedMessagesGroup.writeEntry( storageModelPattern.arg( mCurrentCollection.id() ), value ); - selectedMessagesGroup.deleteEntry( storageModelPattern.arg( mCurrentFolderId ) ); - } - - // folder specific templates - const QString templatesGroupPattern = QLatin1String( "Templates #%1" ); - if ( mKMailConfig->hasGroup( templatesGroupPattern.arg( mCurrentFolderId ) ) ) { - KConfigGroup oldGroup( mKMailConfig, templatesGroupPattern.arg( mCurrentFolderId ) ); - KConfigGroup newGroup( mTemplatesConfig, templatesGroupPattern.arg( mCurrentCollection.id() ) ); - - oldGroup.copyTo( &newGroup ); - oldGroup.deleteGroup(); - } - -} - -void AbstractCollectionMigrator::Private::collectionDone() -{ - mCurrentStoreFolderId = QString(); - mCurrentStoreCollection = Collection(); - mCurrentFolderId = QString(); - mCurrentCollection = Collection(); - - QMetaObject::invokeMethod( q, "processNextCollection", Qt::QueuedConnection ); - - q->migrationProgress( mProcessedCollectionsCount, mOverallCollectionsCount ); -} - -void AbstractCollectionMigrator::Private::collectionFetchResult( KJob *job ) -{ - if ( job->error() != 0 ) { - kError() << "Store CollectionFetch failed:" << job->errorString(); - q->migrationCancelled( job->errorString() ); - return; - } - - FileStore::CollectionFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob != 0 ); - - mCollectionQueue << fetchJob->collections(); - mOverallCollectionsCount = mCollectionQueue.count(); - - processNextCollection(); -} - -void AbstractCollectionMigrator::Private::collectionCreateResult( KJob *job ) -{ - const QString idPath = job->property( "remoteIdPath" ).value(); - if ( job->error() != 0 ) { - kError() << "Akonadi CollectionCreate for" << idPath << "failed:" << job->errorString(); - processNextCollection(); - return; - } - - CollectionCreateJob *createJob = qobject_cast( job ); - Q_ASSERT( createJob != 0 ); - - const Collection collection = createJob->collection(); - - mAkonadiCollectionsByPath.insert( idPath, collection ); - - mCurrentFolderId = folderIdentifierForCollection( collection ); - mCurrentCollection = collection; - mNeedModifyJob = false; - -// kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Store Collection:" << mCurrentStoreCollection -// << "Akonadi Collection:" << collection; - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Store Collection: remoteId=" << mCurrentStoreCollection.remoteId() - << "parent=" << mCurrentStoreCollection.parentCollection().remoteId() - << "\nStore Collection: id=" << collection.id() << "remoteId=" << collection.remoteId() - << "parent=" << collection.parentCollection().remoteId() - << "\nFolder ID=" << mCurrentFolderId; - - q->migrateCollection( collection, mCurrentFolderId ); -} - -void AbstractCollectionMigrator::Private::modifyResult( KJob *job ) -{ - if ( job->error() ) { - kError() << job->error(); - } - - collectionDone(); -} - -void AbstractCollectionMigrator::Private::processNextCollection() -{ - if ( mCollectionQueue.isEmpty() ) { - processingDone(); - return; - } - - ++mProcessedCollectionsCount; - - const Collection storeCollection = mCollectionQueue.dequeue(); - - mCurrentStoreFolderId = folderIdentifierForCollection( storeCollection, true ); - mCurrentStoreCollection = storeCollection; - - const QString idPath = remoteIdPath( storeCollection ); - -// mStoreCollectionsByPath.insert( idPath, storeCollection ); -// kDebug( KDE_DEFAULT_DEBUG_AREA ) << "inserting storeCollection" << storeCollection.remoteId() -// << "at idPath" << idPath; - - // create on Akonadi server - Collection collection = storeCollection; - const Collection parent = collection.parentCollection(); - if ( parent == Collection::root() ) { - collection.setParentCollection( Collection::root() ); - collection.setName( mTopLevelCollectionName ); - } else if ( parent.remoteId() == mStore->topLevelCollection().remoteId() && !mTopLevelRemoteId.isEmpty() ) { - collection.setRemoteId( mTopLevelRemoteId ); - collection.setParentCollection( Collection::root() ); - collection.setName( mTopLevelCollectionName ); - } else { - CollectionHash::const_iterator findIt = mAkonadiCollectionsByPath.constFind( remoteIdPath( parent ) ); - if ( findIt != mAkonadiCollectionsByPath.constEnd() ) { - collection.setParentCollection( findIt.value() ); - } else { - kError() << "storeCollection with idPath" << idPath << "parent=" << parent.remoteId() - << "does not have parent in Akonadi collection hash"; - } - collection.setRemoteId( q->mapRemoteIdFromStore( collection.remoteId() ) ); - } - - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Processing collection" << collection.remoteId() - << "remoteIdPath=" << idPath - << ", " << mCollectionQueue.count() << "remaining"; - - CollectionCreateJob *createJob = new CollectionCreateJob( collection, mHiddenSession ); - createJob->setProperty( "remoteIdPath", idPath ); - QObject::connect( createJob, SIGNAL(result(KJob*)), q, SLOT(collectionCreateResult(KJob*)) ); -} - -QStringList AbstractCollectionMigrator::Private::folderPathComponentsForCollection( const Collection &collection, bool isStoreCollection ) const -{ - QStringList result; - - if ( collection.parentCollection() == Collection::root() ) { - if ( !mTopLevelFolder.isEmpty() && !isStoreCollection ) { - result << mTopLevelFolder; - } - } else { - result = folderPathComponentsForCollection( collection.parentCollection() ); - result << collection.remoteId(); - } - - return result; -} - -QString AbstractCollectionMigrator::Private::folderIdentifierForCollection( const Collection &collection, bool isStoreCollection ) const -{ - QStringList components = folderPathComponentsForCollection( collection, isStoreCollection ); - - QString result; - while ( !components.isEmpty() ) { - QString component = components.front(); - component.remove( QLatin1Char( '/' ) ); - - components.pop_front(); - if ( !components.isEmpty() ) { - result += Maildir::subDirNameForFolderName( component ) + QLatin1Char( '/' ); - } else { - result += component; - } - } - - return result; -} - -void AbstractCollectionMigrator::Private::processingDone() -{ - if ( mOverallCollectionsCount == 0 ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Resource" << mResourceName - << "did not have any local collections"; -/* q->migrationCancelled( i18nc( "@info:status", "Resource '%1' did not have any folders", - mResource.name() ) );*/ - } else { - q->migrationDone(); - } -} - -AbstractCollectionMigrator::AbstractCollectionMigrator( const AgentInstance &resource, const QString &resourceName, MixedMaildirStore *store, QObject *parent ) - : QObject( parent ), d( new Private( this, resource, resourceName, store ) ) -{ - Q_ASSERT( store != 0 ); - - d->mHiddenSession = new Session( resource.identifier().toLatin1() ); -} - -AbstractCollectionMigrator::~AbstractCollectionMigrator() -{ - delete d; -} - -void AbstractCollectionMigrator::setTopLevelFolder( const QString &topLevelFolder, const QString &name, const QString &remoteId ) -{ - d->mTopLevelFolder = topLevelFolder; - d->mTopLevelCollectionName = name; - d->mTopLevelRemoteId = remoteId; -} - -QString AbstractCollectionMigrator::topLevelFolder() const -{ - return d->mTopLevelFolder; -} - -void AbstractCollectionMigrator::setKMailConfig( const KSharedConfigPtr &config ) -{ - d->mKMailConfig = config; -} - -void AbstractCollectionMigrator::setEmailIdentityConfig( const KSharedConfigPtr &config ) -{ - d->mEmailIdentityConfig = config; -} - -void AbstractCollectionMigrator::setKcmKmailSummaryConfig( const KSharedConfigPtr& config ) -{ - d->mKcmKmailSummaryConfig = config; -} - -void AbstractCollectionMigrator::setTemplatesConfig( const KSharedConfigPtr& config ) -{ - d->mTemplatesConfig = config; -} - -void AbstractCollectionMigrator::startMigration() -{ - Collection topLevelCollection; - if ( d->mTopLevelFolder.isEmpty() ) { - topLevelCollection = d->mStore->topLevelCollection(); - } else { - topLevelCollection.setRemoteId( d->mTopLevelFolder ); - topLevelCollection.setParentCollection( d->mStore->topLevelCollection() ); - topLevelCollection.setContentMimeTypes( QStringList() << Collection::mimeType() ); - topLevelCollection.setRights( Collection::CanChangeCollection | - Collection::CanCreateCollection | - Collection::CanDeleteCollection ); - } - - FileStore::CollectionFetchJob *fetchJob = d->mStore->fetchCollections( topLevelCollection, FileStore::CollectionFetchJob::Recursive ); - QObject::connect( fetchJob, SIGNAL(result(KJob*)), this, SLOT(collectionFetchResult(KJob*)) ); - - d->mCollectionQueue << topLevelCollection; - d->mOverallCollectionsCount = d->mCollectionQueue.count(); -} - -void AbstractCollectionMigrator::migrationProgress( int processedCollections, int seenCollections ) -{ - emit progress( 0, seenCollections, processedCollections ); -} - -QString AbstractCollectionMigrator::mapRemoteIdFromStore( const QString &storeRemotedId ) const -{ - return storeRemotedId; -} - -void AbstractCollectionMigrator::collectionProcessed() -{ - d->migrateConfig(); - - if ( d->mNeedModifyJob ) { - CollectionModifyJob *job = new CollectionModifyJob( d->mCurrentCollection ); - connect( job, SIGNAL(result(KJob*)), SLOT(modifyResult(KJob*)) ); - } else { - d->collectionDone(); - } -} - -void AbstractCollectionMigrator::migrationDone() -{ - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "processed" << d->mProcessedCollectionsCount << "collections" - << "seen" << d->mOverallCollectionsCount; - - emit migrationFinished( d->mResource, QString() ); -} - -void AbstractCollectionMigrator::migrationCancelled( const QString &error ) -{ - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "processed" << d->mProcessedCollectionsCount << "collections" - << "seen" << d->mOverallCollectionsCount; - - emit migrationFinished( d->mResource, error ); -} - -const AgentInstance AbstractCollectionMigrator::resource() const -{ - return d->mResource; -} - -QString AbstractCollectionMigrator::resourceName() const -{ - return d->mResourceName; -} - -KSharedConfigPtr AbstractCollectionMigrator::kmailConfig() const -{ - return d->mKMailConfig; -} - -KSharedConfigPtr AbstractCollectionMigrator::emailIdentityConfig() const -{ - return d->mEmailIdentityConfig; -} - -void AbstractCollectionMigrator::registerAsSpecialCollection( int type ) -{ - Q_ASSERT( type > SpecialMailCollections::Invalid && type < SpecialMailCollections::LastType ); - - SpecialMailCollections::Type colType = (SpecialMailCollections::Type)type; - - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Registering collection" << d->mCurrentCollection.name() << "for type" << type; - SpecialMailCollections::self()->registerCollection( colType, d->mCurrentCollection ); - - if ( Private::mIconNamesBySpecialType.isEmpty() ) { - Private::mIconNamesBySpecialType.insert( SpecialMailCollections::Root, - QLatin1String( "folder" ) ); - Private::mIconNamesBySpecialType.insert( SpecialMailCollections::Inbox, - QLatin1String( "mail-folder-inbox" ) ); - Private::mIconNamesBySpecialType.insert( SpecialMailCollections::Outbox, - QLatin1String( "mail-folder-outbox" ) ); - Private::mIconNamesBySpecialType.insert( SpecialMailCollections::SentMail, - QLatin1String( "mail-folder-sent" ) ); - Private::mIconNamesBySpecialType.insert( SpecialMailCollections::Trash, - QLatin1String( "user-trash" ) ); - Private::mIconNamesBySpecialType.insert( SpecialMailCollections::Drafts, - QLatin1String( "document-properties" ) ); - Private::mIconNamesBySpecialType.insert( SpecialMailCollections::Templates, - QLatin1String( "document-new" ) ); - } - - IconNameHash::const_iterator findIt = Private::mIconNamesBySpecialType.constFind( colType ); - if ( findIt != Private::mIconNamesBySpecialType.constEnd() ) { - EntityDisplayAttribute *attribute = d->mCurrentCollection.attribute( Entity::AddIfMissing ); - Q_ASSERT( attribute != 0 ); - - attribute->setIconName( findIt.value() ); - d->mNeedModifyJob = true; - } -} - -MixedMaildirStore *AbstractCollectionMigrator::store() -{ - return d->mStore; -} - -Session *AbstractCollectionMigrator::hiddenSession() -{ - return d->mHiddenSession; -} - -Collection AbstractCollectionMigrator::currentStoreCollection() const -{ - return d->mCurrentStoreCollection; -} - -QString AbstractCollectionMigrator::currentStoreFolderId() const -{ - return d->mCurrentStoreFolderId; -} - -#include "moc_abstractcollectionmigrator.cpp" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/migration/kmail/abstractcollectionmigrator.h kdepim-runtime-15.08.0/migration/kmail/abstractcollectionmigrator.h --- kdepim-runtime-4.14.6/migration/kmail/abstractcollectionmigrator.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/abstractcollectionmigrator.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.com - Copyright (C) 2011 Kevin Krammer, kevin.krammer@gmx.at - - 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 ABSTRACTCOLLECTIONMIGRATOR_H -#define ABSTRACTCOLLECTIONMIGRATOR_H - -#include - -namespace Akonadi { - class AgentInstance; - class Collection; - class Session; -} - -class KJob; -class KSharedConfig; - -template class KSharedPtr; -typedef KSharedPtr KSharedConfigPtr; - -class MixedMaildirStore; - -class AbstractCollectionMigrator : public QObject -{ - Q_OBJECT - - public: - AbstractCollectionMigrator( const Akonadi::AgentInstance &resource, const QString &resourceName, MixedMaildirStore *store, QObject *parent = 0 ); - ~AbstractCollectionMigrator(); - - virtual void setTopLevelFolder( const QString &topLevelFolder, const QString &name, const QString &remoteId = QString() ); - - QString topLevelFolder() const; - - virtual void setKMailConfig( const KSharedConfigPtr &config ); - virtual void setEmailIdentityConfig( const KSharedConfigPtr &config ); - virtual void setKcmKmailSummaryConfig( const KSharedConfigPtr &config ); - virtual void setTemplatesConfig( const KSharedConfigPtr &config ); - - public Q_SLOTS: - void startMigration(); - - Q_SIGNALS: - void migrationFinished( const Akonadi::AgentInstance &resource, const QString &error ); - - void message( int type, const QString &msg ); - - void status( const QString &msg ); - void progress( int value ); - void progress( int min, int max, int value ); - - protected: - virtual void migrateCollection( const Akonadi::Collection &collection, const QString &folderId ) = 0; - - // override if subclass wants to do its own reporting - virtual void migrationProgress( int processedCollections, int seenCollections ); - - virtual QString mapRemoteIdFromStore( const QString &storeRemotedId ) const; - - void collectionProcessed(); - void migrationDone(); - void migrationCancelled( const QString &error ); - - const Akonadi::AgentInstance resource() const; - QString resourceName() const; - KSharedConfigPtr kmailConfig() const; - KSharedConfigPtr emailIdentityConfig() const; - - // TODO SpecialMailCollections doesn't export its enum to bytearray mapping - // so we use an int for the enum value - void registerAsSpecialCollection( int type ); - - MixedMaildirStore *store(); - - Akonadi::Session *hiddenSession(); - - Akonadi::Collection currentStoreCollection() const; - - QString currentStoreFolderId() const; - - private: - class Private; - Private *const d; - - Q_PRIVATE_SLOT( d, void collectionFetchResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void collectionCreateResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void modifyResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void processNextCollection() ) -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/migration/kmail/CMakeLists.txt kdepim-runtime-15.08.0/migration/kmail/CMakeLists.txt --- kdepim-runtime-4.14.6/migration/kmail/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -set(kmail-migrator_srcs - abstractcollectionmigrator.cpp - emptyresourcecleaner.cpp - imapcacheadapter.cpp - imapcachecollectionmigrator.cpp - imapcachelocalimporter.cpp - kmailmigrator.cpp - localfolderscollectionmigrator.cpp - main.cpp - ${MIGRATION_AKONADI_SHARED_SOURCES} - ${CMAKE_CURRENT_SOURCE_DIR}/../../resources/shared/collectionannotationsattribute.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/../../resources/shared/createandsettagsjob.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/../../resources/mixedmaildir/mixedmaildirstore.cpp -) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/../../resources/maildir - ${CMAKE_CURRENT_SOURCE_DIR}/../../resources/mbox - ${CMAKE_CURRENT_SOURCE_DIR}/../../resources/mixedmaildir - ${CMAKE_CURRENT_SOURCE_DIR}/../../resources/shared - ${CMAKE_CURRENT_SOURCE_DIR}/../../resources/shared/filestore -) - -macro(add_resource_iface _kcfgFile _ifaceName _className) - kcfg_generate_dbus_interface(${kdepim-runtime_SOURCE_DIR}/resources/${_kcfgFile} ${_ifaceName}) - string(TOLOWER ${_className} _codeFile) - set_source_files_properties( ${CMAKE_CURRENT_BINARY_DIR}/${_ifaceName}.xml PROPERTIES INCLUDE "metatype.h") - qt4_add_dbus_interface(kmail-migrator_srcs - ${CMAKE_CURRENT_BINARY_DIR}/${_ifaceName}.xml ${_codeFile} ${_className} - ) -endmacro() - -add_resource_iface( imap/imapresource.kcfg - org.kde.Akonadi.Imap.Settings ImapSettings ) -add_resource_iface( pop3/settings.kcfg - org.kde.Akonadi.POP3.Settings Pop3Settings ) -add_resource_iface( mbox/mboxresource.kcfg - org.kde.Akonadi.Mbox.Settings MboxSettings ) -add_resource_iface( maildir/maildirresource.kcfg - org.kde.Akonadi.Maildir.Settings MaildirSettings ) -add_resource_iface( mixedmaildir/mixedmaildirresource.kcfg - org.kde.Akonadi.MixedMaildir.Settings MixedMaildirSettings ) - -kde4_add_app_icon(kmail-migrator_srcs "${KDE4_ICON_DIR}/oxygen/*/apps/akonadi.png") -kde4_add_executable(kmail-migrator ${kmail-migrator_srcs} ) -target_link_libraries(kmail-migrator - ${KDEPIMLIBS_KMBOX_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${KDEPIMLIBS_KPIMUTILS_LIBS} - ${KDEPIMLIBS_AKONADI_KMIME_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDE4_KDEUI_LIBS} - ${KDE4_KIO_LIBS} - akonadi-filestore - maildir - kmindexreader -) - -install(TARGETS kmail-migrator ${INSTALL_TARGETS_DEFAULT_ARGS}) -install(FILES kmail-migratorrc DESTINATION ${CONFIG_INSTALL_DIR}) diff -Nru kdepim-runtime-4.14.6/migration/kmail/emptyresourcecleaner.cpp kdepim-runtime-15.08.0/migration/kmail/emptyresourcecleaner.cpp --- kdepim-runtime-4.14.6/migration/kmail/emptyresourcecleaner.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/emptyresourcecleaner.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,229 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "emptyresourcecleaner.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -using namespace Akonadi; - -typedef QHash CollectionHash; - -class EmptyResourceCleaner::Private -{ - EmptyResourceCleaner *const q; - - public: - Private( EmptyResourceCleaner *parent, const AgentInstance &resource ) - : q( parent ), mResource( resource ), mOptions( CheckOnly ) - { - } - - void deleteCollections(); - void deleteResource(); - - void cleaupFinished(); - - public: - AgentInstance mResource; - - CleaningOptions mOptions; - - Collection::List mAllCollections; - CollectionHash mDeletableCollections; - CollectionHash mDeletedCollections; - - public: // slots - void collectionFetchResult( KJob *job ); - void collectionDeleteResult( KJob *job ); -}; - -void EmptyResourceCleaner::Private::deleteCollections() -{ - CollectionHash::iterator it = mDeletableCollections.begin(); - while ( it != mDeletableCollections.end() ) { - const Collection collection = it.value(); - const Collection parent = collection.parentCollection(); - if ( mDeletedCollections.contains( parent.id() ) ) { - mDeletedCollections.insert( collection.id(), collection ); - it = mDeletableCollections.erase( it ); - } else { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Removing collection: id=" << collection.id() - << "remoteId=" << collection.remoteId(); - CollectionDeleteJob *deleteJob = new CollectionDeleteJob( collection ); - deleteJob->setProperty( "collection", QVariant::fromValue( collection ) ); - connect( deleteJob, SIGNAL(result(KJob*)), q, SLOT(collectionDeleteResult(KJob*)) ); - return; - } - } - - Q_ASSERT( mDeletableCollections.isEmpty() ); - - if ( mOptions.testFlag( DeleteEmptyResource ) && - mDeletedCollections.count() == mAllCollections.count() ) { - deleteResource(); - } else { - emit q->cleanupFinished( mResource ); - } -} - -void EmptyResourceCleaner::Private::deleteResource() -{ - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Removing resource" << mResource.identifier(); - - AgentManager::self()->removeInstance( mResource ); - - emit q->cleanupFinished( mResource ); -} - -void EmptyResourceCleaner::Private::collectionFetchResult( KJob *job ) -{ - if ( job->error() != 0 ) { - kError() << job->errorString(); - emit q->cleanupFinished( mResource ); - return; - } - - CollectionFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob != 0 ); - - mAllCollections = fetchJob->collections(); - CollectionHash nonEmptyCollections; - Q_FOREACH ( const Collection &collection, mAllCollections ) { - qint64 itemCount = collection.statistics().count(); - // TODO should be async as well - if ( itemCount == -1 ) { - ItemFetchJob *itemFetch = new ItemFetchJob( collection ); - if ( itemFetch->exec() ) { - itemCount = itemFetch->items().count(); - } - } - - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "collection" << collection.name() - << "has" << itemCount - << "items"; - if ( itemCount == 0 ) { - mDeletableCollections.insert( collection.id(), collection ); - } else { - nonEmptyCollections.insert( collection.id(), collection ); - } - } - - kDebug( KDE_DEFAULT_DEBUG_AREA ) << mDeletableCollections.count() - << "potenially deletable collections" - << nonEmptyCollections.count() << "not empty"; - - Q_FOREACH ( const Collection &collection, nonEmptyCollections ) { - Collection parent = collection.parentCollection(); - while ( parent.isValid() && parent != Collection::root() ) { - mDeletableCollections.remove( parent.id() ); - parent = parent.parentCollection(); - } - } - - kDebug( KDE_DEFAULT_DEBUG_AREA ) << mDeletableCollections.count() << "of" - << mAllCollections.count() << "are empty"; - - if ( mOptions.testFlag( DeleteEmptyCollections ) ) { - deleteCollections(); - } else if ( mOptions.testFlag( DeleteEmptyResource ) && - mDeletableCollections.count() == mAllCollections.count() ) { - deleteResource(); - } else { - emit q->cleanupFinished( mResource ); - } -} - -void EmptyResourceCleaner::Private::collectionDeleteResult( KJob *job ) -{ - if ( job->error() != 0 ) { - kError() << job->errorString(); - emit q->cleanupFinished( mResource ); - return; - } - - CollectionDeleteJob *deleteJob = qobject_cast( job ); - Q_ASSERT( deleteJob != 0 ); - - const Collection collection = deleteJob->property( "collection" ).value(); - mDeletableCollections.remove( collection.id() ); - mDeletedCollections.insert( collection.id(), collection ); - - deleteCollections(); -} - -EmptyResourceCleaner::EmptyResourceCleaner( const AgentInstance &resource, QObject *parent ) - : QObject( parent ), d( new Private( this, resource ) ) -{ - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Creating cleaner for resource" - << d->mResource.identifier(); - connect( this, SIGNAL(cleanupFinished(Akonadi::AgentInstance)), SLOT(deleteLater()) ); - - CollectionFetchScope scope; - scope.setResource( d->mResource.identifier() ); - scope.setAncestorRetrieval( CollectionFetchScope::All ); - scope.setIncludeStatistics( true ); - - CollectionFetchJob *fetchJob = new CollectionFetchJob( Collection::root(), CollectionFetchJob::Recursive ); - fetchJob->setFetchScope( scope ); - connect( fetchJob, SIGNAL(result(KJob*)), SLOT(collectionFetchResult(KJob*)) ); -} - -EmptyResourceCleaner::~EmptyResourceCleaner() -{ - delete d; -} - -void EmptyResourceCleaner::setCleaningOptions( CleaningOptions options ) -{ - d->mOptions = options; -} - -EmptyResourceCleaner::CleaningOptions EmptyResourceCleaner::cleaningOptions() const -{ - return d->mOptions; -} - -Collection::List EmptyResourceCleaner::deletableCollections() const -{ - return d->mDeletableCollections.values(); -} - -bool EmptyResourceCleaner::isResourceDeletable() const -{ - return ( d->mDeletedCollections.count() + d->mDeletableCollections.count() ) - == d->mAllCollections.count(); -} - -#include "moc_emptyresourcecleaner.cpp" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/migration/kmail/emptyresourcecleaner.h kdepim-runtime-15.08.0/migration/kmail/emptyresourcecleaner.h --- kdepim-runtime-4.14.6/migration/kmail/emptyresourcecleaner.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/emptyresourcecleaner.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 EMPTYRESOURCECLEANER_H -#define EMPTYRESOURCECLEANER_H - -#include - -namespace Akonadi -{ - class AgentInstance; - class Collection; -} - -class KJob; - -template class QList; - -class EmptyResourceCleaner : public QObject -{ - Q_OBJECT - - public: - enum CleaningOption { - CheckOnly = 0x00, - DeleteEmptyCollections = 0x01, - DeleteEmptyResource = 0x02 - }; - - Q_DECLARE_FLAGS( CleaningOptions, CleaningOption ) - - explicit EmptyResourceCleaner( const Akonadi::AgentInstance &resource, QObject *parent = 0 ); - ~EmptyResourceCleaner(); - - void setCleaningOptions( CleaningOptions options ); - - CleaningOptions cleaningOptions() const; - - QList deletableCollections() const; - - bool isResourceDeletable() const; - - Q_SIGNALS: - void cleanupFinished( const Akonadi::AgentInstance &resource ); - - private: - class Private; - Private *const d; - - Q_PRIVATE_SLOT( d, void collectionFetchResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void collectionDeleteResult( KJob* ) ) -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS( EmptyResourceCleaner::CleaningOptions ) - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/migration/kmail/imapcacheadapter.cpp kdepim-runtime-15.08.0/migration/kmail/imapcacheadapter.cpp --- kdepim-runtime-4.14.6/migration/kmail/imapcacheadapter.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/imapcacheadapter.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,168 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2011 Kevin Krammer, kevin.krammer@gmx.at - - 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 "imapcacheadapter.h" - -#include "kmigratorbase.h" - -#include "mixedmaildirsettings.h" -#include "mixedmaildirstore.h" - -#include - -#include -#include -#include -#include - -#include - -#include - -using namespace Akonadi; - -class ImapCacheAdapter::Private -{ - ImapCacheAdapter *const q; - - public: - Private( ImapCacheAdapter *parent, MixedMaildirStore *store ) - : q( parent ), mStore( store ) - { - } - - void processNextCollection(); - - void createResource(); - - public: - MixedMaildirStore *const mStore; - - QQueue mPendingCollections; - - public: // slots - void createResourceResult( KJob *job ); - void collectionModifyResult( KJob *job ); -}; - -void ImapCacheAdapter::Private::processNextCollection() -{ - kDebug() << mPendingCollections.count() << "pending collections"; - - if ( mPendingCollections.isEmpty() ) { - createResource(); - return; - } - - const Collection collection = mPendingCollections.dequeue(); - kDebug() << "processing: name=" << collection.name() - << "remoteId=" << collection.remoteId() - << "parent=" << collection.parentCollection().remoteId(); - - FileStore::CollectionModifyJob *job = mStore->modifyCollection( collection ); - connect( job, SIGNAL(result(KJob*)), q, SLOT(collectionModifyResult(KJob*)) ); -} - -void ImapCacheAdapter::Private::createResource() -{ - const QString typeId = QLatin1String( "akonadi_mixedmaildir_resource" ); - AgentInstanceCreateJob *job = new AgentInstanceCreateJob( typeId, q ); - connect( job, SIGNAL(result(KJob*)), q, SLOT(createResourceResult(KJob*)) ); - job->start(); -} - -void ImapCacheAdapter::Private::createResourceResult( KJob *job ) -{ - if ( job->error() != 0 ) { - kError() << "Creation of MixedMaildir resource for local cache adapter failed:" << job->errorString(); - emit q->finished( KMigratorBase::Error, - i18n( "Could not create adapter for previous KMail version's disconnected IMAP cache" ) ); - return; - } - - AgentInstanceCreateJob *createJob = qobject_cast( job ); - - AgentInstance instance = createJob->instance(); - - OrgKdeAkonadiMixedMaildirSettingsInterface *iface = new OrgKdeAkonadiMixedMaildirSettingsInterface( - QLatin1String("org.freedesktop.Akonadi.Resource.") + instance.identifier(), - QLatin1String("/Settings"), QDBusConnection::sessionBus(), q ); - - if ( !iface->isValid() ) { - kError() << "Failed to obtain D-Bus interface for remote configuration of local cache adapter resource" << instance.identifier(); - delete iface; - - AgentManager::self()->removeInstance( instance ); - - emit q->finished( KMigratorBase::Error, - i18n( "Could not configure adapter for previous KMail version's disconnected IMAP cache" ) ); - return; - } - - const QString name = - i18nc( "@title account name", "Previous KMail's disconnected IMAP cache" ); - instance.setName( name ); - iface->setPath( mStore->path() ); - - // make sure the config is saved - iface->writeConfig(); - delete iface; - - instance.reconfigure(); - - emit q->finished( KMigratorBase::Success, i18n( "Access to previous KMail version's cache enabled" ) ); -} - -void ImapCacheAdapter::Private::collectionModifyResult( KJob *job ) -{ - if ( job->error() != 0 ) { - kError() << "Rename of DIMAP top level collection failed:" << job->errorString(); - } - - processNextCollection(); -} - -ImapCacheAdapter::ImapCacheAdapter( MixedMaildirStore *store, QObject *parent ) - : QObject( parent ), d( new Private( this, store ) ) -{ -} - -ImapCacheAdapter::~ImapCacheAdapter() -{ - delete d; -} - -void ImapCacheAdapter::addAccount( const QString &topLevelFolder, const QString &accountName ) -{ - Collection collection; - collection.setRemoteId( topLevelFolder ); - collection.setParentCollection( d->mStore->topLevelCollection() ); - collection.setName( accountName ); - - d->mPendingCollections << collection; -} - -void ImapCacheAdapter::start() -{ - d->processNextCollection(); -} - -#include "moc_imapcacheadapter.cpp" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/migration/kmail/imapcacheadapter.h kdepim-runtime-15.08.0/migration/kmail/imapcacheadapter.h --- kdepim-runtime-4.14.6/migration/kmail/imapcacheadapter.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/imapcacheadapter.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2011 Kevin Krammer, kevin.krammer@gmx.at - - 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 IMAPCACHEADAPTER_H -#define IMAPCACHEADAPTER_H - -#include - -class KJob; -class MixedMaildirStore; - -class ImapCacheAdapter : public QObject -{ - Q_OBJECT - - public: - explicit ImapCacheAdapter( MixedMaildirStore *store, QObject *parent = 0 ); - ~ImapCacheAdapter(); - - void addAccount( const QString &topLevelFolder, const QString &accountName ); - - Q_SIGNALS: - void finished( int messageType, const QString &message ); - - public Q_SLOTS: - void start(); - - private: - class Private; - Private *const d; - - Q_PRIVATE_SLOT( d, void createResourceResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void collectionModifyResult( KJob* ) ) -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/migration/kmail/imapcachecollectionmigrator.cpp kdepim-runtime-15.08.0/migration/kmail/imapcachecollectionmigrator.cpp --- kdepim-runtime-4.14.6/migration/kmail/imapcachecollectionmigrator.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/imapcachecollectionmigrator.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,646 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.com - Copyright (C) 2011 Kevin Krammer, kevin.krammer@gmx.at - - 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 "imapcachecollectionmigrator.h" - -#include "kmigratorbase.h" - -#include "libmaildir/maildir.h" -#include "mixedmaildirstore.h" -#include "subscriptionjob_p.h" - -#include "filestore/itemfetchjob.h" -#include "filestore/itemdeletejob.h" - -#include "createandsettagsjob.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -using namespace Akonadi; -using KPIM::Maildir; - -typedef QHash UidHash; - -class ImapCacheCollectionMigrator::Private -{ - ImapCacheCollectionMigrator *const q; - - public: - Private( ImapCacheCollectionMigrator *parent ) - : q( parent ), - mImportNewMessages( false ), mImportCachedMessages( false ), - mRemoveDeletedMessages( false ), mDeleteImportedMessages( false ), - mItemProgress( -1 ) - { - } - - bool isUnsubscribedImapFolder( const Collection &collection, QString &idPath ) const; - - public: - Collection mCurrentCollection; - Item::List mItems; - UidHash mUidHash; - QStringList mDeletedUids; - - bool mImportNewMessages; - bool mImportCachedMessages; - bool mRemoveDeletedMessages; - bool mDeleteImportedMessages; - - KConfigGroup mCurrentFolderGroup; - - QHash mTagListHash; - - int mItemProgress; - - QSet mUnsubscribedImapFolders; - Collection::List mUnsubscribedCollections; - - public: // slots - void fetchItemsResult( KJob *job ); - void processNextItem(); - void processNextDeletedUid(); - void fetchItemResult( KJob *job ); - void itemCreateResult( KJob *job ); - void itemDeletePhase1Result( KJob *job ); - void itemDeletePhase2Result( KJob *job ); - void cacheItemDeleteResult( KJob *job ); - void unsubscribeCollections(); - void unsubscribeCollectionsResult( KJob *job ); -}; - -bool ImapCacheCollectionMigrator::Private::isUnsubscribedImapFolder( const Collection &collection, QString &idPath ) const -{ - if ( collection.parentCollection() == Collection::root() ) { - idPath = QString(); - return false; - } - - bool parentResult = isUnsubscribedImapFolder( collection.parentCollection(), idPath ); - - idPath = idPath + collection.remoteId(); - - return parentResult || mUnsubscribedImapFolders.contains( idPath ); -} - -void ImapCacheCollectionMigrator::Private::fetchItemsResult( KJob *job ) -{ - if ( job->error() != 0 ) { - kWarning() << "Store Fetch for item list in collection" << mCurrentCollection.remoteId() - << "returned error: code=" << job->error() << "text=" << job->errorString(); - if ( mRemoveDeletedMessages ) { - processNextDeletedUid(); - } else { - emit q->status( QString() ); - mCurrentCollection = Collection(); - q->collectionProcessed(); - } - return; - } - - FileStore::ItemFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob != 0 ); - - const QVariant uidHashVar = fetchJob->property( "remoteIdToIndexUid" ); - if ( !uidHashVar.isValid() ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "No UIDs from index for collection" << mCurrentCollection.name(); - if ( mRemoveDeletedMessages ) { - processNextDeletedUid(); - } else { - emit q->status( QString() ); - mCurrentCollection = Collection(); - q->collectionProcessed(); - } - return; - } - - mUidHash.clear(); - const QHash uidHash = uidHashVar.value< QHash >(); - QHash::const_iterator it = uidHash.constBegin(); - QHash::const_iterator endIt = uidHash.constEnd(); - for ( ; it != endIt; ++it ) { - const QString uid = it.value().isValid() ? it.value().value() : QString(); - mUidHash.insert( it.key(), uid ); - } - - mItems = fetchJob->items(); - kDebug( KDE_DEFAULT_DEBUG_AREA ) << mItems.count() << "items for target collection" << mCurrentCollection.remoteId(); - - const QVariant tagListHashVar = fetchJob->property( "remoteIdToTagList" ); - if ( !tagListHashVar.isValid() ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "No tags from index for collection" << mCurrentCollection.name(); - } else { - mTagListHash = tagListHashVar.value< QHash >(); - kDebug( KDE_DEFAULT_DEBUG_AREA ) << mTagListHash.count() << "items have tags"; - } - - // filter out items we don't process later on - const int oldCount = mItems.count(); - - Item::List::iterator itemIt = mItems.begin(); - while ( itemIt != mItems.end() ) { - const QString storeRemoteId = ( *itemIt ).remoteId(); - if ( mImportCachedMessages || - ( mImportNewMessages && !mUidHash.contains( storeRemoteId ) ) || - mTagListHash.contains( storeRemoteId ) ) { - ++itemIt; - } else { - itemIt = mItems.erase( itemIt ); - } - } - - if ( oldCount != mItems.count() ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "After filtering:" << mItems.count() << "items remaining"; - } - - mItemProgress = -1; - emit q->progress( 0, mItems.count(), 0 ); - processNextItem(); -} - -void ImapCacheCollectionMigrator::Private::processNextItem() -{ -// kDebug( KDE_DEFAULT_DEBUG_AREA ) << "mCurrentCollection=" << mCurrentCollection.name() -// << mItems.count() << "items to go"; - - emit q->progress( ++mItemProgress ); - emit q->status( i18ncp( "@info:status folder name and number of messages to import before finished", - "%1: one message left to import", "%1: %2 messages left to import", - mCurrentCollection.name(), mItems.count() ) ); - - if ( mItems.isEmpty() ) { - if ( mDeletedUids.isEmpty() ) { - emit q->status( QString() ); - mCurrentCollection = Collection(); - q->collectionProcessed(); - } else if ( mRemoveDeletedMessages ) { - processNextDeletedUid(); - } - return; - } - - Item item = mItems.front(); - mItems.pop_front(); - - // don't import items that are marked deleted. These come from normal/online IMAP caches - // which didn't get their mbox cache files compacted - Akonadi::MessageStatus status; - status.setStatusFromFlags( item.flags() ); - if ( status.isDeleted() ) { - //kDebug() << "Cache item" << item.remoteId() << "is marked as Deleted. Skip it"; - QMetaObject::invokeMethod( q, "processNextItem", Qt::QueuedConnection ); - return; - } - - const QString storeRemoteId = item.remoteId(); - if ( mImportCachedMessages || ( mImportNewMessages && !mUidHash.contains( storeRemoteId ) ) ) { - FileStore::ItemFetchJob *job = q->store()->fetchItem( item ); - job->fetchScope().fetchFullPayload( true ); - connect( job, SIGNAL(result(KJob*)), q, SLOT(fetchItemResult(KJob*)) ); - } else if ( mTagListHash.contains( storeRemoteId ) ) { - ItemCreateJob *createJob = 0; - - if ( !mUidHash.contains( storeRemoteId ) ) { - item.setRemoteId( QString() ); - createJob = new ItemCreateJob( item, mCurrentCollection ); - } else { - const QString uid = mUidHash[ storeRemoteId ]; - item.setRemoteId( uid ); - createJob = new ItemCreateJob( item, mCurrentCollection, q->hiddenSession() ); - } - - createJob->setProperty( "storeRemoteId", storeRemoteId ); - createJob->setProperty( "storeParentCollection", QVariant::fromValue( item.parentCollection() ) ); - connect( createJob, SIGNAL(result(KJob*)), q, SLOT(itemCreateResult(KJob*)) ); - - } else { - QMetaObject::invokeMethod( q, "processNextItem", Qt::QueuedConnection ); - } -} - -void ImapCacheCollectionMigrator::Private::processNextDeletedUid() -{ -// kDebug( KDE_DEFAULT_DEBUG_AREA ) << "mCurrentCollection=" << mCurrentCollection.name() -// << mDeletedUids.count() << "items to go"; - - if ( mDeletedUids.isEmpty() ) { - if ( mCurrentFolderGroup.isValid() ) { - const QString key = QLatin1String( "UIDSDeletedSinceLastSync" ); - if ( !mCurrentFolderGroup.readEntry( key, QStringList() ).isEmpty() ) { - mCurrentFolderGroup.deleteEntry( QLatin1String( "UIDSDeletedSinceLastSync" ) ); - } - } - mCurrentFolderGroup = KConfigGroup(); - mCurrentCollection = Collection(); - emit q->status( QString() ); - q->collectionProcessed(); - return; - } - - const QString uid = mDeletedUids.front(); - mDeletedUids.pop_front(); - - // we need to first create an item using the hidden session so that Akonadi knows the item - // and then delete it using the normal session so that the IMAP resource gets the delete - Item item; - item.setMimeType( KMime::Message::mimeType() ); - item.setRemoteId( uid ); - - ItemCreateJob *createJob = new ItemCreateJob( item, mCurrentCollection, q->hiddenSession() ); - connect( createJob, SIGNAL(result(KJob*)), q, SLOT(itemDeletePhase1Result(KJob*)) ); -} - -void ImapCacheCollectionMigrator::Private::fetchItemResult( KJob *job ) -{ - FileStore::ItemFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob != 0 ); - - Item item = fetchJob->item(); - if ( job->error() != 0 ) { - kWarning() << "Store Fetch for single item" << item.remoteId() << "returned error: code=" - << job->error() << "text=" << job->errorString(); - processNextItem(); - return; - } - - const Item::List items = fetchJob->items(); - if ( items.isEmpty() ) { - kWarning() << "Store Fetch for single item" << item.remoteId() << "returned empty list"; - } else { - const Item cacheItem = items[ 0 ]; - if ( !cacheItem.hasPayload() ) { - kWarning() << "Store Fetch for single item" << item.remoteId() << "returned item without payload"; - } else { - item.setPayload( cacheItem.payload() ); - } - } - - ItemCreateJob *createJob = 0; - - const QString storeRemoteId = item.remoteId(); - const QString uid = mUidHash[ item.remoteId() ]; - if ( uid.isEmpty() && mImportNewMessages ) { - item.setRemoteId( QString() ); - createJob = new ItemCreateJob( item, mCurrentCollection ); - -// kDebug( KDE_DEFAULT_DEBUG_AREA ) << "unsynchronized cacheItem: remoteId=" << item.remoteId() -// << "mimeType=" << item.mimeType() -// << "flags=" << item.flags(); - } else if ( mImportCachedMessages ) { - item.setRemoteId( uid ); - createJob = new ItemCreateJob( item, mCurrentCollection, q->hiddenSession() ); - -// kDebug( KDE_DEFAULT_DEBUG_AREA ) << "synchronized cacheItem: remoteId=" << item.remoteId() -// << "mimeType=" << item.mimeType() -// << "flags=" << item.flags(); - } - - if ( createJob != 0 ) { - createJob->setProperty( "storeRemoteId", storeRemoteId ); - createJob->setProperty( "storeParentCollection", QVariant::fromValue( item.parentCollection() ) ); - connect( createJob, SIGNAL(result(KJob*)), q, SLOT(itemCreateResult(KJob*)) ); - } else { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Skipping cacheItem: remoteId=" << item.remoteId() - << "mimeType=" << item.mimeType() - << "flags=" << item.flags(); - processNextItem(); - } -} - -void ImapCacheCollectionMigrator::Private::itemCreateResult( KJob *job ) -{ - ItemCreateJob *createJob = qobject_cast( job ); - Q_ASSERT( createJob != 0 ); - - const Item item = createJob->item(); - const QString storeRemoteId = job->property( "storeRemoteId" ).value(); - - if ( job->error() != 0 ) { - kWarning() << "Akonadi Create for single item" << item.remoteId() << "returned error: code=" - << job->error() << "text=" << job->errorString(); - - processNextItem(); - } else if ( !storeRemoteId.isEmpty() ) { - const QStringList tagList = mTagListHash[ storeRemoteId ].value(); - if ( !tagList.isEmpty() ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Tagging item" << item.url() << "with" << tagList; - - Akonadi::Tag::List tags; - Q_FOREACH( const QString &tag, tagList ) { - if ( tag.isEmpty() ) { - kWarning() << "TagList for item" << item.url() << "contains an empty tag"; - } else { - tags << Akonadi::Tag(tag); - } - } - new CreateAndSetTagsJob(item, tags); - } - - const Collection storeCollection = job->property( "storeParentCollection" ).value(); - if ( mDeleteImportedMessages && !storeCollection.remoteId().isEmpty() ) { - Item cacheItem = item; - cacheItem.setRemoteId( storeRemoteId ); - cacheItem.setParentCollection( storeCollection ); - FileStore::ItemDeleteJob *deleteJob = q->store()->deleteItem( cacheItem ); - connect( deleteJob, SIGNAL(result(KJob*)), q, SLOT(cacheItemDeleteResult(KJob*)) ); - } else { - processNextItem(); - } - } else { - processNextItem(); - } -} - -void ImapCacheCollectionMigrator::Private::itemDeletePhase1Result( KJob *job ) -{ - ItemCreateJob *createJob = qobject_cast( job ); - Q_ASSERT( createJob != 0 ); - - const Item item = createJob->item(); - - if ( job->error() != 0 ) { - kWarning() << "Akonadi Create for single item" << item.remoteId() << "returned error: code=" - << job->error() << "text=" << job->errorString(); - processNextDeletedUid(); - } else { - ItemDeleteJob *deleteJob = new ItemDeleteJob( item ); - connect( deleteJob, SIGNAL(result(KJob*)), q, SLOT(itemDeletePhase2Result(KJob*)) ); - } -} - -void ImapCacheCollectionMigrator::Private::itemDeletePhase2Result( KJob *job ) -{ - ItemDeleteJob *deleteJob = qobject_cast( job ); - Q_ASSERT( deleteJob != 0 ); - - const Item::List items = deleteJob->deletedItems(); - const Item item = items.isEmpty() ? Item() : items[ 0 ]; - - if ( job->error() != 0 ) { - kWarning() << "Akonadi Delete for single item" << item.remoteId() << "returned error: code=" - << job->error() << "text=" << job->errorString(); - } - - processNextDeletedUid(); -} - -void ImapCacheCollectionMigrator::Private::cacheItemDeleteResult( KJob *job ) -{ - FileStore::ItemDeleteJob *deleteJob = qobject_cast( job ); - Q_ASSERT( deleteJob != 0 ); - - const Item item = deleteJob->item(); - - if ( job->error() != 0 ) { - kWarning() << "Store Delete for single item" << item.remoteId() << "returned error: code=" - << job->error() << "text=" << job->errorString(); - } - - processNextItem(); -} - -void ImapCacheCollectionMigrator::Private::unsubscribeCollections() -{ - if ( !mUnsubscribedCollections.isEmpty() ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Locally Unsubscribe" << mUnsubscribedCollections.count() << "collections"; - - SubscriptionJob *job = new SubscriptionJob( q ); - job->unsubscribe( mUnsubscribedCollections ); - QObject::connect( job, SIGNAL(result(KJob*)), q, SLOT(unsubscribeCollectionsResult(KJob*)) ); - } -} - -void ImapCacheCollectionMigrator::Private::unsubscribeCollectionsResult( KJob *job ) -{ - if ( job->error() != 0 ) { - kError() << "Unsubscribing of " << mUnsubscribedCollections.count() << "collections failed:" - << job->error(); - } else { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Unsubscribing of " << mUnsubscribedCollections.count() << "collections succeeded"; - } -} - -ImapCacheCollectionMigrator::ImapCacheCollectionMigrator( const AgentInstance &resource, const QString &resourceName, MixedMaildirStore *store, QObject *parent ) - : AbstractCollectionMigrator( resource, resourceName, store, parent ), d( new Private( this ) ) -{ - connect( this, SIGNAL(migrationFinished(Akonadi::AgentInstance,QString)), - SLOT(unsubscribeCollections()) ); -} - -ImapCacheCollectionMigrator::~ImapCacheCollectionMigrator() -{ - delete d; -} - -void ImapCacheCollectionMigrator::setMigrationOptions( const MigrationOptions &options ) -{ - MigrationOptions actualOptions = options; - - if ( store() == 0 ) { - emit message( KMigratorBase::Skip, - i18nc( "@info:status", "No cache for account %1 available", - resourceName() ) ); - kWarning() << "No store for folder" << topLevelFolder() - << "so only config migration (instead of" << options << ") for" - << resource().identifier() << resourceName(); - actualOptions = ConfigOnly; - } - - d->mImportNewMessages = actualOptions.testFlag( ImportNewMessages ); - d->mImportCachedMessages = actualOptions.testFlag( ImportCachedMessages ); - d->mRemoveDeletedMessages = actualOptions.testFlag( RemoveDeletedMessages ); - d->mDeleteImportedMessages = actualOptions.testFlag( DeleteImportedMessages ); -} - -ImapCacheCollectionMigrator::MigrationOptions ImapCacheCollectionMigrator::migrationOptions() const -{ - MigrationOptions options; - if ( d->mImportNewMessages ) { - options |= ImportNewMessages; - } - if ( d->mImportCachedMessages ) { - options |= ImportCachedMessages; - } - if ( d->mRemoveDeletedMessages ) { - options |= RemoveDeletedMessages; - } - if ( d->mDeleteImportedMessages ) { - options |= DeleteImportedMessages; - } - return options; -} - -void ImapCacheCollectionMigrator::setUnsubscribedImapFolders( const QStringList &imapFolders ) -{ - d->mUnsubscribedImapFolders.clear(); - Q_FOREACH ( const QString &imapFolder, imapFolders ) { - if ( imapFolder.endsWith( QLatin1Char( '/' ) ) ) { - d->mUnsubscribedImapFolders << imapFolder.left( imapFolder.size() - 1 ); - } else { - d->mUnsubscribedImapFolders << imapFolder; - } - } - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "unsubscribed imap folders:" << d->mUnsubscribedImapFolders; -} - -void ImapCacheCollectionMigrator::migrateCollection( const Collection &collection, const QString &folderId ) -{ - QString imapIdPath; - if ( d->isUnsubscribedImapFolder( collection, imapIdPath ) ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Collection id=" << collection.id() - << ", remoteId=" << collection.remoteId() << ", imapIdPath=" << imapIdPath - << "is locally unsubscribed"; - - // could check if this very collection is one of the unsubscribed using imapIdPath. - // however, KMail treats subfolders of unsubscribed folders as unsubscribed as well - // so unsubscribe the too. otherwise their contents get downloaded on first interval check - d->mUnsubscribedCollections << collection; - - emit status( QString() ); - collectionProcessed(); - return; - } - - if ( migrationOptions() == ConfigOnly ) { - emit status( QString() ); - collectionProcessed(); - return; - } - - // check that we don't get entered while we are still processing - Q_ASSERT( !d->mCurrentCollection.isValid() ); - - Q_ASSERT( store() != 0 ); - - if ( collection.parentCollection() == Collection::root() ) { - emit status( QString() ); - collectionProcessed(); - return; - } - - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Akonadi collection remoteId=" << collection.remoteId() << ", parent=" << collection.parentCollection().remoteId(); - - Collection cache = currentStoreCollection(); - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Cache collection remoteId=" << cache.remoteId() << ", parent=" << cache.parentCollection().remoteId(); - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "folderId=" << folderId << "imapIdPath=" << imapIdPath; - - d->mDeletedUids.clear(); - if ( d->mRemoveDeletedMessages ) { - Q_ASSERT( kmailConfig() ); - - const QString groupName = QLatin1String( "Folder-" ) + folderId; - if ( kmailConfig()->hasGroup( groupName ) ) { - d->mCurrentFolderGroup = KConfigGroup( kmailConfig(), groupName ); - d->mDeletedUids = d->mCurrentFolderGroup.readEntry( QLatin1String( "UIDSDeletedSinceLastSync" ), QStringList() ); - } - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "DeleteUids=" << d->mDeletedUids; - } - - d->mCurrentCollection = collection; - d->mTagListHash.clear(); - - emit message( KMigratorBase::Info, i18nc( "@info:status", "Starting cache migration for folder %1 of account %2", collection.name(), resourceName() ) ); - - emit status( collection.name() ); - - if ( d->mImportNewMessages || d->mImportCachedMessages ) { - FileStore::ItemFetchJob *job = store()->fetchItems( cache ); - connect( job, SIGNAL(result(KJob*)), SLOT(fetchItemsResult(KJob*)) ); - emit status( i18nc( "@info:status foldername", "%1: listing messages...", collection.name() ) ); - } else if ( d->mRemoveDeletedMessages ) { - emit status( collection.name() ); - d->processNextDeletedUid(); - } else { - emit status( QString() ); - collectionProcessed(); - } -} - -void ImapCacheCollectionMigrator::migrationProgress( int processedCollections, int seenCollections ) -{ - // if we potentially migrate items, use item progress instead - // use base implementation if only collections are processed - if ( migrationOptions() == ConfigOnly ) { - AbstractCollectionMigrator::migrationProgress( processedCollections, seenCollections ); - } -} - -QString ImapCacheCollectionMigrator::mapRemoteIdFromStore( const QString &storeRemotedId ) const -{ - const QString accountId = topLevelFolder(); - const KConfigGroup accountGroup = kmailConfig()->group( QString::fromLatin1( "Account %1" ).arg( accountId ) ); - - const QString folderId = currentStoreFolderId(); - const KConfigGroup folderGroup - = kmailConfig()->group( QString::fromLatin1( "Folder-%1" ).arg( folderId ) ); - - QString imapPath = folderGroup.readEntry( "ImapPath", QString() ); - imapPath.remove( 0, 1 ); - imapPath.chop( 1 ); - - QChar separator = QLatin1Char('/'); - int namespaceLength = -1; - - for ( int i=0; i<=2; i++ ) { - QStringList namespaces = accountGroup.readEntry( QString::number( i ), QStringList() ); - namespaces.replaceInStrings( QRegExp( QLatin1String("\"") ), QLatin1String("") ); - - foreach ( const QString &ns, namespaces ) { - QString imapNs = ns; - imapNs.chop( 1 ); - - if ( ( ns.size()>namespaceLength ) - && imapPath.startsWith( imapNs ) ) { - - const QString potentialSeparator - = accountGroup.readEntry( QString::fromLatin1( "Namespace:%1" ).arg( ns ), QString() ); - - if ( !potentialSeparator.isEmpty() ) { - namespaceLength = ns.size(); - separator = potentialSeparator.at( 0 ); - } - } - } - } - - return separator + storeRemotedId; -} - -#include "moc_imapcachecollectionmigrator.cpp" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/migration/kmail/imapcachecollectionmigrator.h kdepim-runtime-15.08.0/migration/kmail/imapcachecollectionmigrator.h --- kdepim-runtime-4.14.6/migration/kmail/imapcachecollectionmigrator.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/imapcachecollectionmigrator.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.com - Copyright (C) 2011 Kevin Krammer, kevin.krammer@gmx.at - - 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 IMAPCACHECOLLECTIONMIGRATOR_H -#define IMAPCACHECOLLECTIONMIGRATOR_H - -#include "abstractcollectionmigrator.h" - -class ImapCacheCollectionMigrator : public AbstractCollectionMigrator -{ - Q_OBJECT - - public: - enum MigrationOption { - ConfigOnly = 0x0, - ImportNewMessages = 0x01, - ImportCachedMessages = 0x02, - RemoveDeletedMessages = 0x04, - DeleteImportedMessages = 0x08 - }; - - Q_DECLARE_FLAGS( MigrationOptions, MigrationOption ) - - ImapCacheCollectionMigrator( const Akonadi::AgentInstance &resource, const QString &resourceName, MixedMaildirStore *store, QObject *parent = 0 ); - - ~ImapCacheCollectionMigrator(); - - void setMigrationOptions( const MigrationOptions &options ); - - MigrationOptions migrationOptions() const; - - void setUnsubscribedImapFolders( const QStringList &imapFolders ); - - protected: - void migrateCollection( const Akonadi::Collection &collection, const QString &folderId ); - - // overridden because of own reporting - void migrationProgress( int processedCollections, int seenCollections ); - - QString mapRemoteIdFromStore( const QString &storeRemotedId ) const; - - private: - class Private; - Private *const d; - - Q_PRIVATE_SLOT( d, void fetchItemsResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void processNextItem() ) - Q_PRIVATE_SLOT( d, void processNextDeletedUid() ) - Q_PRIVATE_SLOT( d, void fetchItemResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void itemCreateResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void itemDeletePhase1Result( KJob* ) ) - Q_PRIVATE_SLOT( d, void itemDeletePhase2Result( KJob* ) ) - Q_PRIVATE_SLOT( d, void cacheItemDeleteResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void unsubscribeCollections() ) - Q_PRIVATE_SLOT( d, void unsubscribeCollectionsResult( KJob* ) ) -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS( ImapCacheCollectionMigrator::MigrationOptions ) - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/migration/kmail/imapcachelocalimporter.cpp kdepim-runtime-15.08.0/migration/kmail/imapcachelocalimporter.cpp --- kdepim-runtime-4.14.6/migration/kmail/imapcachelocalimporter.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/imapcachelocalimporter.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,348 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "imapcachelocalimporter.h" - -#include "maildirsettings.h" -#include "mixedmaildirstore.h" - -#include "filestore/collectionfetchjob.h" -#include "filestore/itemfetchjob.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -using namespace Akonadi; - -static QString remoteIdPath( const Collection& collection ) { - const Collection parent = collection.parentCollection(); - if ( parent.remoteId().isEmpty() ) { - return collection.remoteId(); - } - - return remoteIdPath( parent ) + QLatin1Char( '/' ) + collection.remoteId(); -} - -class ImapCacheLocalImporter::Private -{ - ImapCacheLocalImporter *const q; - - public: - Private( ImapCacheLocalImporter *parent, MixedMaildirStore *store ) - : q( parent ), mStore( store ), mHiddenSession( 0 ), - mItemProgress( -1 ) - { - } - - ~Private() - { - delete mHiddenSession; - } - - void processNextCollection(); - void processNextItem(); - - public: - MixedMaildirStore *mStore; - Session *mHiddenSession; - - QString mTopLevelFolder; - QString mAccountName; - - AgentInstance mResource; - - Collection::List mPendingCollections; - Item::List mPendingItems; - - typedef QHash CollectionHash; - CollectionHash mStoreCollectionsByPath; - CollectionHash mAkonadiCollectionsByPath; - - Collection mCurrentCollection; - int mItemProgress; - - public: // slots - void createResourceResult( KJob *job ); - void configureResource(); - void collectionFetchResult( KJob *job ); - void collectionCreateResult( KJob *job ); - void itemFetchResult( KJob *job ); - void itemCreateResult( KJob *job ); -}; - -void ImapCacheLocalImporter::Private::processNextCollection() -{ - if ( mPendingCollections.isEmpty() ) { - configureResource(); - return; - } - - const Collection storeCollection = mPendingCollections.front(); - mPendingCollections.pop_front(); - - const QString idPath = remoteIdPath( storeCollection ); - mStoreCollectionsByPath.insert( idPath, storeCollection ); -// kDebug( KDE_DEFAULT_DEBUG_AREA ) << "inserting storeCollection" << storeCollection.remoteId() -// << "at idPath" << idPath; - - // create on Akonadi server - Collection collection = storeCollection; - const Collection parent = collection.parentCollection(); - if ( parent.remoteId() == mStore->topLevelCollection().remoteId() ) { - collection.setParentCollection( Collection::root() ); - - const QFileInfo pathInfo( QDir( mStore->path() ), mTopLevelFolder ); - collection.setRemoteId( pathInfo.absoluteFilePath() ); - collection.setName( i18nc( "@title account name", "Local Copies of %1", mAccountName ) ); - } else { - CollectionHash::const_iterator findIt = mAkonadiCollectionsByPath.constFind( remoteIdPath( parent ) ); - if ( findIt != mAkonadiCollectionsByPath.constEnd() ) { - collection.setParentCollection( findIt.value() ); - } else { - kError() << "storeCollection with idPath" << idPath << "parent=" << parent.remoteId() - << "does not have parent in Akonadi collection hash"; - } - } - - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Processing collection" << collection.remoteId() - << "remoteIdPath=" << idPath - << ", " << mPendingCollections.count() << "remaining"; - - CollectionCreateJob *createJob = new CollectionCreateJob( collection, mHiddenSession ); - createJob->setProperty( "remoteIdPath", idPath ); - QObject::connect( createJob, SIGNAL(result(KJob*)), q, SLOT(collectionCreateResult(KJob*)) ); -} - -void ImapCacheLocalImporter::Private::processNextItem() -{ - emit q->progress( ++mItemProgress ); - emit q->status( i18ncp( "@info:status folder name and number of messages to import before finished", - "%1: one message left to import", "%1: %2 messages left to import", - mCurrentCollection.name(), mPendingItems.count() ) ); - - if ( mPendingItems.isEmpty() ) { - processNextCollection(); - return; - } - - const Item item = mPendingItems.front(); - mPendingItems.pop_front(); - -// kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Processing item" << item.remoteId() -// << "parentCollection" << item.parentCollection().id() -// << "remoteIdPath=" << remoteIdPath( item.parentCollection() ) -// << ", " << mPendingCollections.count() << "remaining"; - - ItemCreateJob *createJob = new ItemCreateJob( item, item.parentCollection(), mHiddenSession ); - QObject::connect( createJob, SIGNAL(result(KJob*)), q, SLOT(itemCreateResult(KJob*)) ); -} - -void ImapCacheLocalImporter::Private::createResourceResult( KJob *job ) -{ - if ( job->error() != 0 ) { - kError() << "Creation of Maildir resource for local cache copy of account" - << mAccountName << "failed:" << job->errorString(); - emit q->importFinished( mResource, - i18n( "Cannot provide access to local copies of " - "disconnected IMAP account %1", - mAccountName ) ); - return; - } - - AgentInstanceCreateJob *createJob = qobject_cast( job ); - mResource = createJob->instance(); - - mHiddenSession = new Session( mResource.identifier().toLatin1() ); - - Collection topLevelCollection; - topLevelCollection.setRemoteId( mTopLevelFolder ); - topLevelCollection.setParentCollection( mStore->topLevelCollection() ); - topLevelCollection.setContentMimeTypes( QStringList() << Collection::mimeType() ); - topLevelCollection.setRights( Collection::CanChangeCollection | - Collection::CanCreateCollection | - Collection::CanDeleteCollection ); - - mPendingCollections << topLevelCollection; - - FileStore::CollectionFetchJob *fetchJob = mStore->fetchCollections( topLevelCollection, FileStore::CollectionFetchJob::Recursive ); - QObject::connect( fetchJob, SIGNAL(result(KJob*)), q, SLOT(collectionFetchResult(KJob*)) ); -} - -void ImapCacheLocalImporter::Private::configureResource() -{ - OrgKdeAkonadiMaildirSettingsInterface *iface = new OrgKdeAkonadiMaildirSettingsInterface( - QLatin1String("org.freedesktop.Akonadi.Resource.") + mResource.identifier(), - QLatin1String("/Settings"), QDBusConnection::sessionBus(), q ); - - if ( !iface->isValid() ) { - q->importFinished( mResource, i18n( "Failed to obtain D-Bus interface for remote configuration." ) ); - delete iface; - return; - } - - const QFileInfo pathInfo( QDir( mStore->path() ), mTopLevelFolder ); - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "resource working path=" << pathInfo.absoluteFilePath(); - iface->setPath( pathInfo.absoluteFilePath() ); - - // make sure the config is saved - iface->writeConfig(); - - mResource.setName( i18nc( "@title account name", "Local Copies of %1", mAccountName ) ); - mResource.reconfigure(); - - emit q->status( QString() ); - emit q->importFinished( mResource, QString() ); -} - -void ImapCacheLocalImporter::Private::collectionFetchResult( KJob *job ) -{ - if ( job->error() != 0 ) { - kError() << "Store CollectionFetch failed:" << job->errorString(); - } else { - FileStore::CollectionFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob != 0 ); - - mPendingCollections << fetchJob->collections(); - } - - processNextCollection(); -} - -void ImapCacheLocalImporter::Private::collectionCreateResult( KJob *job ) -{ - const QString idPath = job->property( "remoteIdPath" ).value(); - if ( job->error() != 0 ) { - kError() << "Akonadi CollectionCreate for" << idPath << "failed:" << job->errorString(); - processNextCollection(); - return; - } - - CollectionCreateJob *createJob = qobject_cast( job ); - Q_ASSERT( createJob != 0 ); - - const Collection collection = createJob->collection(); - mCurrentCollection = collection; -/* kDebug( KDE_DEFAULT_DEBUG_AREA ) << "inserting collection" << collection.id() - << collection.remoteId() - << "at idPath" << idPath;*/ - mAkonadiCollectionsByPath.insert( idPath, collection ); - -/* kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Checking for storeCollection with idPath" << idPath;*/ - const Collection storeCollection = mStoreCollectionsByPath[ idPath ]; - Q_ASSERT( !storeCollection.remoteId().isEmpty() ); - - FileStore::ItemFetchJob *fetchJob = mStore->fetchItems( storeCollection ); - fetchJob->setProperty( "remoteIdPath", idPath ); - QObject::connect( fetchJob, SIGNAL(result(KJob*)), q, SLOT(itemFetchResult(KJob*)) ); - - emit q->status( i18nc( "@info:status foldername", "%1: listing messages...", collection.name() ) ); -} - -void ImapCacheLocalImporter::Private::itemFetchResult( KJob *job ) -{ - const QString idPath = job->property( "remoteIdPath" ).value(); - if ( job->error() != 0 ) { - kError() << "Store ItemFetch for" << idPath << "failed:" << job->errorString(); - processNextCollection(); - return; - } - - FileStore::ItemFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob != 0 ); - - const Collection collection = mAkonadiCollectionsByPath[ idPath ]; - Q_ASSERT( collection.isValid() ); - - Item::List items = fetchJob->items(); - Item::List::iterator it = items.begin(); - Item::List::iterator endIt = items.end(); - for ( ; it != endIt; ++it ) { - ( *it ).setParentCollection( collection ); - } - - mPendingItems << items; - - mItemProgress = -1; - emit q->progress( 0, mPendingItems.count(), 0 ); - processNextItem(); -} - -void ImapCacheLocalImporter::Private::itemCreateResult( KJob *job ) -{ - ItemCreateJob *createJob = qobject_cast( job ); - Q_ASSERT( createJob != 0 ); - if ( createJob->error() != 0 ) { - const Item item = createJob->item(); - kError() << "Akonadi ItemCreate for" << item.parentCollection().remoteId() - << "/" << item.remoteId() << "failed:" << job->errorString(); - return; - } - - processNextItem(); -} - -ImapCacheLocalImporter::ImapCacheLocalImporter( MixedMaildirStore *store, QObject *parent ) - : QObject( parent ), d( new Private( this, store ) ) -{ - Q_ASSERT( store != 0 ); -} - -ImapCacheLocalImporter::~ImapCacheLocalImporter() -{ - delete d; -} - -void ImapCacheLocalImporter::setTopLevelFolder( const QString &topLevelFolder ) -{ - d->mTopLevelFolder = topLevelFolder; -} - -void ImapCacheLocalImporter::setAccountName( const QString &accountName ) -{ - d->mAccountName = accountName; -} - -QString ImapCacheLocalImporter::accountName() const -{ - return d->mAccountName; -} - -void ImapCacheLocalImporter::startImport() -{ - Q_ASSERT( !d->mTopLevelFolder.isEmpty() ); - Q_ASSERT( !d->mAccountName.isEmpty() ); - - const QString typeId = QLatin1String( "akonadi_maildir_resource" ); - AgentInstanceCreateJob *job = new AgentInstanceCreateJob( typeId, this ); - connect( job, SIGNAL(result(KJob*)), SLOT(createResourceResult(KJob*)) ); - job->start(); -} - -#include "moc_imapcachelocalimporter.cpp" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/migration/kmail/imapcachelocalimporter.h kdepim-runtime-15.08.0/migration/kmail/imapcachelocalimporter.h --- kdepim-runtime-4.14.6/migration/kmail/imapcachelocalimporter.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/imapcachelocalimporter.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 IMAPCACHELOCALIMPORTER_H -#define IMAPCACHELOCALIMPORTER_H - -#include - -namespace Akonadi -{ - class AgentInstance; -} - -class MixedMaildirStore; - -class ImapCacheLocalImporter : public QObject -{ - Q_OBJECT - - public: - explicit ImapCacheLocalImporter( MixedMaildirStore *store, QObject *parent = 0 ); - - ~ImapCacheLocalImporter(); - - void setTopLevelFolder( const QString &topLevelFolder ); - - void setAccountName( const QString &accountName ); - - QString accountName() const; - - Q_SIGNALS: - void status( const QString &msg ); - void progress( int value ); - void progress( int min, int max, int value ); - - void importFinished( const Akonadi::AgentInstance &resource, const QString &error ); - - public Q_SLOTS: - void startImport(); - - private: - class Private; - Private *const d; - - Q_PRIVATE_SLOT( d, void createResourceResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void configureResource() ) - Q_PRIVATE_SLOT( d, void collectionFetchResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void collectionCreateResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void itemFetchResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void itemCreateResult( KJob* ) ) -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/migration/kmail/kmailmigrator.cpp kdepim-runtime-15.08.0/migration/kmail/kmailmigrator.cpp --- kdepim-runtime-4.14.6/migration/kmail/kmailmigrator.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/kmailmigrator.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1358 +0,0 @@ -/* - Copyright (c) 2009 Jonathan Armond - Copyright (c) 2010 Volker Krause - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.com - Copyright (C) 2011 Kevin Krammer, kevin.krammer@gmx.at - - 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 "kmailmigrator.h" - - -// avoid metatype.h from interfering -#define POP3_METATYPE_H - -#include "imapsettings.h" -#include "pop3settings.h" -#include "mboxsettings.h" -#include "maildirsettings.h" -#include "mixedmaildirsettings.h" -#include "mixedmaildirstore.h" -#include "emptyresourcecleaner.h" -#include "imapcacheadapter.h" -#include "imapcachecollectionmigrator.h" -#include "localfolderscollectionmigrator.h" - -#include "collectionannotationsattribute.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -using Akonadi::AgentManager; -using Akonadi::AgentInstance; -using Akonadi::AgentInstanceCreateJob; - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -Q_DECLARE_METATYPE(QList); - -using KWallet::Wallet; - -using namespace KMail; - -/* Enums for use over DBus. Can't include settings.h for each resource because - all have same class name. If resource interfaces are changed, these will need - changing too. */ -enum MboxLocking { Procmail, MuttDotLock, MuttDotLockPrivileged, MboxNone }; - -#define SPECIALCOLLECTIONS_LOCK_SERVICE QLatin1String( "org.kde.pim.SpecialCollections" ) - -static MixedMaildirStore *createStoreFromBasePath( const QString &basePath ) -{ - MixedMaildirStore *store = 0; - const QFileInfo baseDir( basePath ); - if ( baseDir.exists() && baseDir.isDir() ) { - store = new MixedMaildirStore; - store->setPath( baseDir.absoluteFilePath() ); - } - - return store; -} - -static void backupConfig( const QString &name, const QDir &backupDir ) -{ - const QString configFile = KStandardDirs::locate( "config", name ); - if ( !configFile.isEmpty() ) { - QFile::copy( configFile, QFileInfo( backupDir, name ).absoluteFilePath() ); - } -} - -KMailMigrator::KMailMigrator() : - KMigratorBase(), - mWallet( 0 ), - mDImapCache( 0 ), - mImapCache( 0 ), - mForwardResourceNotifications( false ), - mImapCacheAdapter( 0 ) -{ - Akonadi::AttributeFactory::registerAttribute(); - connect( AgentManager::self(), SIGNAL(instanceStatusChanged(Akonadi::AgentInstance)), - this, SLOT(instanceStatusChanged(Akonadi::AgentInstance)) ); - connect( AgentManager::self(), SIGNAL(instanceProgressChanged(Akonadi::AgentInstance)), - this, SLOT(instanceProgressChanged(Akonadi::AgentInstance)) ); -} - -KMailMigrator::~KMailMigrator() -{ - delete mWallet; - delete mDImapCache; - delete mImapCache; -} - -void KMailMigrator::migrate() -{ - emit message( Info, i18n( "Beginning KMail migration..." ) ); - - // copy config files to backup locations - const KDateTime now = KDateTime::currentLocalDateTime(); - const QDir backupDir( KGlobal::dirs()->saveLocation( "appdata", now.toString() ) ); - - // copy current configs to backup location - // strickly speaking neither kmailrc not mailtransports are changed by the migrator - // but copy them anyway as the belong conceptually to the KMail1 -> KMail2 migration - backupConfig( QLatin1String("kmailrc"), backupDir ); - backupConfig( QLatin1String("mailtransports"), backupDir ); - backupConfig( QLatin1String("emailidentities"), backupDir ); - backupConfig( QLatin1String("kcmkmailsummaryrc"), backupDir ); - backupConfig( QLatin1String("templatesconfigurationrc"), backupDir ); - - KSharedConfigPtr oldConfig = KSharedConfig::openConfig( QLatin1String( "kmailrc" ) ); - mConfig = KSharedConfig::openConfig( QLatin1String( "kmail2rc" ) ); - - const QFileInfo migratorConfigInfo( KStandardDirs::locateLocal( "config", KGlobal::config()->name() ) ); - - const QString &newKMailCfgFile = KStandardDirs::locateLocal( "config", QLatin1String( "kmail2rc" ) ); - - // copy old config into new config, if - bool copy = false; - // there is no migrator config (no migration happened yet or full rerun) - copy = copy || !migratorConfigInfo.exists(); - // new config does not exist yet - copy = copy || !QFileInfo( newKMailCfgFile ).exists(); - // new config is empty - copy = copy || mConfig->groupList().isEmpty(); - // new config does not contain any account groups - copy = copy || mConfig->groupList().filter( QRegExp( QLatin1String("Account \\d+") ) ).isEmpty(); - - if ( copy ) { - kDebug() << "Copying content from kmailrc"; - oldConfig->copyTo( newKMailCfgFile, mConfig.data() ); - } else { - kDebug() << "Ignoring kmailrc, just using contents from kmail2rc"; - } - - mEmailIdentityConfig = KSharedConfig::openConfig( QLatin1String( "emailidentities" ) ); - - mKcmKmailSummaryConfig = KSharedConfig::openConfig( QLatin1String( "kcmkmailsummaryrc" ) ); - - mTemplatesConfig = KSharedConfig::openConfig( QLatin1String( "templatesconfigurationrc" ) ); - - deleteOldGroup(); - migrateTags(); - migrateRCFiles(); - migrateNotifyFile(); - - // copy autosave files if there are any - const QString autoSaveDir = KGlobal::dirs()->saveLocation( "data", QLatin1String("kmail/autosave"), false ); - if ( !autoSaveDir.isEmpty() ) { - const QString destDir = KGlobal::dirs()->saveLocation( "data", QLatin1String("kmail2") ); - KIO::CopyJob *job = KIO::copy( KUrl::fromPath( autoSaveDir ), - KUrl::fromPath( destDir ), - KIO::HideProgressInfo ); - job->setAutoSkip( true ); - job->setWriteIntoExistingDirectories( true ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(autoSaveCopyResult(KJob*)) ); - } - - mAccounts = mConfig->groupList().filter( QRegExp( QLatin1String("Account \\d+") ) ); - - mIt = mAccounts.begin(); - migrateNext(); -} - -void KMailMigrator::autoSaveCopyResult( KJob *job ) -{ - if ( job->error() ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "error=" << job->error() - << "text=" << job->errorString(); - } -} - -void KMailMigrator::deleteOldGroup() -{ - deleteOldGroup( QLatin1String("GroupwareFolderInfo") ); - deleteOldGroup( QLatin1String("Groupware") ); - deleteOldGroup( QLatin1String("IMAP Resource") ); - deleteOldGroup( QLatin1String("Folder_local_root") ); - deleteOldGroup( QLatin1String("Folder_search") ); -} - -void KMailMigrator::deleteOldGroup( const QString& name ) { - if ( mConfig->hasGroup( name ) ) { - KConfigGroup groupName( mConfig, name ); - groupName.deleteGroup(); - } -} - -void KMailMigrator::migrateNotifyFile() -{ - const QString notifyFile = KStandardDirs::locate( "config", QLatin1String("kmail.notifyrc") ); - if ( !notifyFile.isEmpty() ) { - QFile::copy( notifyFile, KStandardDirs::locateLocal( "config", QLatin1String("kmail2.notifyrc" )) ); - } - -} - -void KMailMigrator::migrateTags() -{ - KConfigGroup tagMigrationConfig( KGlobal::config(), QLatin1String( "MessageTags" ) ); - const QStringList migratedTags = tagMigrationConfig.readEntry( "MigratedTags", QStringList() ); - - const QStringList tagGroups = mConfig->groupList().filter( QRegExp( QLatin1String("MessageTag #\\d+") ) ); - - QSet groupNames = tagGroups.toSet(); - groupNames.subtract( migratedTags.toSet() ); - - kDebug() << "Tag Groups:" << tagGroups << "MigratedTags:" << migratedTags - << "Unmigrated Tags:" << groupNames; - - QStringList newlyMigratedTags; - Q_FOREACH ( const QString &groupName, groupNames ) { - const KConfigGroup group( mConfig, groupName ); - - const QString label = group.readEntry( QLatin1String( "Label" ), QString() ); - if ( label.isEmpty() ) { - continue; - } - const QString name = group.readEntry( QLatin1String( "Name" ), QString() ); - if ( name.isEmpty() ) { - continue; - } - - const QColor textColor = group.readEntry( QLatin1String( "text-color" ), QColor() ); - const QColor backgroundColor = group.readEntry( QLatin1String( "background-color" ), QColor() ); - const bool hasFont = group.hasKey( QLatin1String( "text-font" ) ); - const QFont textFont = group.readEntry( QLatin1String( "text-font" ), QFont() ); - - const bool inToolbar = group.readEntry( QLatin1String( "toolbar" ), false ); - const QString iconName = group.readEntry( QLatin1String( "icon" ), QString::fromLatin1( "mail-tagged" ) ); - - const QString shortcut = group.readEntry( QLatin1String( "shortcut" ), QString() ); - - Akonadi::Tag tag(label); - Akonadi::TagAttribute *attr = tag.attribute(Akonadi::AttributeEntity::AddIfMissing); - attr->setDisplayName(name); - attr->setIconName( iconName ); - attr->setInToolbar( inToolbar ); - if (hasFont) { - attr->setFont( textFont.toString() ); - } - attr->setBackgroundColor( backgroundColor ); - attr->setTextColor( textColor ); - attr->setShortcut( shortcut ); - - Akonadi::TagCreateJob *createJob = new Akonadi::TagCreateJob(tag); - createJob->setMergeIfExisting(true); - - kDebug() << "Tag: label=" << label << "name=" << name - << "textColor=" << textColor << "backgroundColor=" << backgroundColor - << "hasFont=" << hasFont << "font=" << textFont - << "icon=" << iconName << "inToolbar=" << inToolbar - << "shortcut=" << shortcut; - - newlyMigratedTags << groupName; - } - - //Cleanup migrated group - Q_FOREACH ( const QString &groupName, newlyMigratedTags ) { - deleteOldGroup( groupName ); - } - - if ( !newlyMigratedTags.isEmpty() ) { - tagMigrationConfig.writeEntry( "MigratedTags", migratedTags + newlyMigratedTags ); - tagMigrationConfig.sync(); - } -} - -void KMailMigrator::migrateRCFiles() -{ - const QDir sourceDir( KStandardDirs::locateLocal( "data", QLatin1String("kmail") ) ); - const QDir targetDir( KStandardDirs::locateLocal( "data", QLatin1String("kmail2") ) ); - KStandardDirs::makeDir( targetDir.absolutePath() ); - - const QFileInfoList files = sourceDir.entryInfoList( QStringList() << QLatin1String( "*.rc" ), - QDir::Files | QDir::Readable ); - Q_FOREACH ( const QFileInfo &fileInfo, files ) { - QFile file( fileInfo.absoluteFilePath() ); - file.copy( QFileInfo( targetDir, fileInfo.fileName() ).absoluteFilePath() ); - } -} - -void KMailMigrator::migrateNext() -{ - while ( mIt != mAccounts.end() ) { - mCurrentAccount = *mIt; - const KConfigGroup group( mConfig, mCurrentAccount ); - - const QString name = group.readEntry( "Name" ); - const QString idString = group.readEntry( "Id" ); - if ( migrationState( idString ) == None ) { - ++mIt; - if ( !migrateCurrentAccount() ) { - emit message( Error, i18n( "No backend for '%1' available.", name ) ); - migrateNext(); - } - return; - } - - if ( migrationState( idString ) == Complete ) - emit message( Skip, i18n( "'%1' has been already migrated.", name ) ); - - ++mIt; - } - if ( mIt == mAccounts.end() ) { - if ( mImapCacheAdapter != 0 ) { - emit message( Info, i18n( "Enabling access to the disconnected IMAP cache of the previous KMail version" ) ); - emit status( QString() ); - mImapCacheAdapter->start(); - } else { - migrateLocalFolders(); - } - } -} - -void KMailMigrator::migrateLocalFolders() -{ - if ( migrationState( QLatin1String("LocalFolders") ) == Complete ) { - emit message( Skip, i18n( "Local folders have already been migrated." ) ); - emit status( QString() ); - migrationDone(); - return; - } - - KConfigGroup cfgGroup( mConfig, "General" ); - cfgGroup.deleteEntry( "QuotaUnit" ); - cfgGroup.deleteEntry( "default-mailbox-format" ); - mConfig->sync(); - const QString localMaildirDefaultPath = KStandardDirs::locateLocal( "data", QLatin1String( "kmail/mail" ) ); - mLocalMaildirPath = cfgGroup.readPathEntry( "folders", localMaildirDefaultPath ); - const QFileInfo fileInfo( mLocalMaildirPath ); - if ( !fileInfo.exists() || !fileInfo.isDir() ) { - emit status( QString() ); - migrationDone(); - } else { - kDebug() << mLocalMaildirPath; - - emit message( Info, i18nc( "@info:status", "Migrating local folders in '%1'...", mLocalMaildirPath ) ); - - // show status/progress info of resources in our dialog - mForwardResourceNotifications = true; - - createAgentInstance( QLatin1String("akonadi_mixedmaildir_resource"), this, - SLOT(localMaildirCreated(KJob*)) ); - } -} - -void KMailMigrator::migrationDone() -{ - emit message( Success, i18n( "Migration successfully completed." ) ); - - migrateInstanceTrashFolder(); - - mConfig->sync(); - kDebug() << "Deleting" << mFailedInstances.count() << "failed resource instances"; - Q_FOREACH ( const AgentInstance &instance, mFailedInstances ) { - if ( instance.isValid() ) { - AgentManager::self()->removeInstance( instance ); - } - } - cleanupConfigFile(); - migrateConfigurationDialogRestriction(); - deleteLater(); - kDebug() << "Restarting Akonadi"; - - Akonadi::Control::restart(); -} - -OrgKdeAkonadiImapSettingsInterface* KMailMigrator::createImapSettingsInterface( const Akonadi::AgentInstance& instance ) -{ - OrgKdeAkonadiImapSettingsInterface *iface = new OrgKdeAkonadiImapSettingsInterface( - QLatin1String("org.freedesktop.Akonadi.Resource.") + instance.identifier(), - QLatin1String("/Settings"), QDBusConnection::sessionBus(), this ); - if ( !iface->isValid() ) { - migrationFailed( i18n( "Failed to obtain D-Bus interface for remote configuration." ), instance ); - delete iface; - return 0; - } - return iface; -} - -OrgKdeAkonadiPOP3SettingsInterface* KMailMigrator::createPop3SettingsInterface( const Akonadi::AgentInstance& instance ) -{ - OrgKdeAkonadiPOP3SettingsInterface *iface = new OrgKdeAkonadiPOP3SettingsInterface( - QLatin1String("org.freedesktop.Akonadi.Resource.") + instance.identifier(), - QLatin1String("/Settings"), QDBusConnection::sessionBus(), this ); - if ( !iface->isValid() ) { - migrationFailed( i18n( "Failed to obtain D-Bus interface for remote configuration." ), instance ); - delete iface; - return 0; - } - return iface; -} - -void KMailMigrator::migrateConfigurationDialogRestriction() -{ - if ( mConfig->hasGroup( "ConfigurationDialogRestrictions" ) ) { - KSharedConfigPtr resourcebaseconfig = KSharedConfig::openConfig( QLatin1String( "resourcebaserc" ) ); - KConfigGroup oldGroup = mConfig->group( "ConfigurationDialogRestrictions" ); - KConfigGroup newGroup = resourcebaseconfig->group( "ConfigurationDialogRestrictions" ); - oldGroup.copyTo( &newGroup ); - oldGroup.deleteGroup(); - } - -} - -void KMailMigrator::cleanupConfigFile() -{ - mIt = mAccounts.begin(); - AccountIterator end( mAccounts.end() ) ; - - while ( mIt != end ) { - const QString accountName = *mIt; - deleteOldGroup( accountName ); - ++mIt; - } - - deleteOldGroup( QLatin1String("FavoriteFolderView") ); - - if ( mConfig->hasGroup( "Internal" ) ) { - KConfigGroup cfgGroup( mConfig, "General" ); - cfgGroup.deleteEntry( "MsgDictSizeHint" ); - } -} - -void KMailMigrator::migrateInstanceTrashFolder() -{ - mIt = mAccounts.begin(); - while ( mIt != mAccounts.end() ) { - const QString accountName = *mIt; - const KConfigGroup group( mConfig, accountName ); - if ( mAccountInstance.contains( accountName ) ) { - AccountConfig accountConf = mAccountInstance.value( accountName ); - Akonadi::AgentInstance instance = accountConf.instance; - if ( accountConf.imapAccount ) { //Imap - OrgKdeAkonadiImapSettingsInterface *iface = createImapSettingsInterface( instance ); - if ( iface ) { - const qint64 value = group.readEntry( "trash", -1 ); - if ( value != -1 ) { - iface->setTrashCollection( value ); - // make sure the config is saved - iface->writeConfig(); - instance.reconfigure(); - } - } - } else { //Pop3 - OrgKdeAkonadiPOP3SettingsInterface *iface = createPop3SettingsInterface( instance ); - if ( iface ) { - const qint64 value = group.readEntry( "Folder", -1 ); - if ( value != -1 ) { - iface->setTargetCollection( value ); - // make sure the config is saved - iface->writeConfig(); - instance.reconfigure(); - } - } - } - } - ++mIt; - } -} - -void KMailMigrator::migrationFailed( const QString &errorMsg, - bool doMigrateNext, - const AgentInstance &instance ) -{ - const KConfigGroup group( mConfig, mCurrentAccount ); - emit message( Error, i18n( "Migration of '%1' to Akonadi resource failed: %2", - group.readEntry( "Name" ), errorMsg ) ); - - if ( instance.isValid() ) { - mFailedInstances << instance; - } - - mCurrentAccount.clear(); - mCurrentInstance = AgentInstance(); - - if ( doMigrateNext ) { - migrateNext(); - } -} - -void KMailMigrator::migrationCompleted( const AgentInstance &instance, bool doMigrateNext ) -{ - const KConfigGroup group( mConfig, mCurrentAccount ); - const QString accountId = group.readEntry( QLatin1String( "Id" ) ); - - // check if the account is used in filters - const QStringList filterGroups = mConfig->groupList().filter( QRegExp( QLatin1String("Filter #\\d+") ) ); - //kDebug( KDE_DEFAULT_DEBUG_AREA ) << "filterGroups=" << filterGroups; - Q_FOREACH ( const QString &groupName, filterGroups ) { - KConfigGroup filterGroup( mConfig, groupName ); - - QStringList accountsSet = filterGroup.readEntry( QLatin1String( "accounts-set" ), QStringList() ); - //if ( !accountsSet.isEmpty() ) { - // kDebug( KDE_DEFAULT_DEBUG_AREA ) << "accountsSet=" << accountsSet; - //} - const int index = accountsSet.indexOf( accountId ); - if ( index != -1 ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "replacing account id" << accountId - << "in filter" << groupName - << "with resource id" << instance.identifier(); - accountsSet.replace( index, instance.identifier() ); - filterGroup.writeEntry( QLatin1String( "accounts-set" ), accountsSet ); - } - } - - setMigrationState( group.readEntry( "Id" ), Complete, instance.identifier(), - group.readEntry( "Type" ).toLower() ); - emit message( Success, i18n( "Migration of '%1' succeeded.", group.readEntry( "Name" ) ) ); - mCurrentAccount.clear(); - mCurrentInstance = AgentInstance(); - - if ( doMigrateNext ) { - migrateNext(); - } -} - -void KMailMigrator::connectCollectionMigrator( AbstractCollectionMigrator *migrator ) -{ - connect( migrator, SIGNAL(message(int,QString)), - SLOT (collectionMigratorMessage(int,QString)) ); - connect( migrator, SIGNAL(status(QString)), SIGNAL (status(QString)) ); - connect( migrator, SIGNAL(progress(int)), SIGNAL (progress(int)) ); - connect( migrator, SIGNAL(progress(int,int,int)), SIGNAL (progress(int,int,int)) ); - connect( migrator, SIGNAL(migrationFinished(Akonadi::AgentInstance,QString)), - this, SLOT(collectionMigratorFinished()) ); - connect( migrator, SIGNAL(status(QString)), - SLOT (collectionMigratorEmittedNotification()) ); - connect( migrator, SIGNAL(progress(int)), - SLOT (collectionMigratorEmittedNotification()) ); - connect( migrator, SIGNAL(progress(int,int,int)), - SLOT (collectionMigratorEmittedNotification()) ); -} - -void KMailMigrator::migratePassword( const QString &idString, const AgentInstance &instance, - const QString &newFolder, const QString& passwordFromFilePassword ) -{ - QString password; - if ( mWallet == 0 ) { - mWallet = Wallet::openWallet( Wallet::NetworkWallet(), 0 ); - } - if ( mWallet && mWallet->isOpen() ) { - if ( !passwordFromFilePassword.isEmpty() ) - password = passwordFromFilePassword; - - if ( password.isEmpty() && mWallet->hasFolder( QLatin1String("kmail") ) ) { - mWallet->setFolder( QLatin1String("kmail") ); - mWallet->readPassword( QLatin1String("account-") + idString, password ); - } - - if ( !password.isEmpty() ) { - if ( !mWallet->hasFolder( newFolder ) ) - mWallet->createFolder( newFolder ); - mWallet->setFolder( newFolder ); - - mWallet->writePassword( instance.identifier() + QLatin1String("rc") , password ); - } - } -} - -bool KMailMigrator::migrateCurrentAccount() -{ - if ( mCurrentAccount.isEmpty() ) - return false; - const KConfigGroup group( mConfig, mCurrentAccount ); - - emit message( Info, i18n( "Trying to migrate '%1' to resource...", group.readEntry( "Name" ) ) ); - - // show status/progress info of resources in our dialog - mForwardResourceNotifications = true; - - const QString type = group.readEntry( "Type" ).toLower(); - if ( type == QLatin1String( "imap" ) ) { - createAgentInstance( QLatin1String("akonadi_imap_resource"), this, - SLOT(imapAccountCreated(KJob*)) ); - } else if ( type == QLatin1String( "dimap" ) ) { - createAgentInstance( QLatin1String("akonadi_imap_resource"), this, - SLOT(imapDisconnectedAccountCreated(KJob*)) ); - - } else if ( type == QLatin1String( "pop" ) ) { - createAgentInstance( QLatin1String("akonadi_pop3_resource"), this, - SLOT(pop3AccountCreated(KJob*)) ); - } else if ( type == QLatin1String( "maildir" ) ) { - createAgentInstance( QLatin1String("akonadi_maildir_resource"), this, - SLOT(maildirAccountCreated(KJob*)) ); - } else if ( type == QLatin1String( "local" ) ) { - createAgentInstance( QLatin1String("akonadi_mbox_resource"), this, - SLOT(mboxAccountCreated(KJob*)) ); - } else { - return false; - } - - return true; -} - -void KMailMigrator::imapDisconnectedAccountCreated( KJob * job ) -{ - if ( job->error() ) { - migrationFailed( i18n( "Failed to create resource: %1", job->errorText() ) ); - return; - } - emit message( Info, i18n( "Created disconnected imap resource" ) ); - migrateImapAccount( job, true ); -} - -void KMailMigrator::imapAccountCreated( KJob *job ) -{ - if ( job->error() ) { - migrationFailed( i18n( "Failed to create resource: %1", job->errorText() ) ); - return; - } - emit message( Info, i18n( "Created imap resource" ) ); - migrateImapAccount( job, false ); -} - - -void KMailMigrator::migrateImapAccount( KJob *job, bool disconnected ) -{ - AgentInstance instance = static_cast< AgentInstanceCreateJob* >( job )->instance(); - mCurrentInstance = instance; - - AccountConfig conf; - conf.instance = instance; - conf.imapAccount = true; - conf.disconnectedImap = disconnected; - mAccountInstance.insert( mCurrentAccount, conf ); - - KConfigGroup config( mConfig, mCurrentAccount ); - - const QString nameAccount = config.readEntry( "Name" ); - instance.setName( nameAccount ); - emit status( nameAccount ); - - ImapCacheCollectionMigrator::MigrationOptions options = ImapCacheCollectionMigrator::ImportNewMessages; - if ( disconnected ) { - const KConfigGroup dimapConfig( KGlobal::config(), QLatin1String( "Disconnected IMAP" ) ); - if ( dimapConfig.isValid() ) { - options = ImapCacheCollectionMigrator::ConfigOnly; - - if ( dimapConfig.readEntry( QLatin1String( "ImportNewMessages" ), false ) ) { - options |= ImapCacheCollectionMigrator::ImportNewMessages; - } - - if ( dimapConfig.readEntry( QLatin1String( "ImportCachedMessages" ), false ) ) { - options |= ImapCacheCollectionMigrator::ImportCachedMessages; - } - - if ( dimapConfig.readEntry( QLatin1String( "RemoveDeletedMessages" ), false ) ) { - options |= ImapCacheCollectionMigrator::RemoveDeletedMessages; - } - } - } - - MixedMaildirStore *store = 0; - if ( disconnected ) { -#if 0 - if ( mDeleteCacheAfterImport ) { - options |= ImapCacheCollectionMigrator::DeleteImportedMessages; - } -#endif - if ( mDImapCache == 0 ) { - mDImapCache = createStoreFromBasePath( KStandardDirs::locateLocal( "data", QLatin1String( "kmail/dimap" ) ) ); - } - store = mDImapCache; - } else { - if ( mImapCache == 0 ) { - mImapCache = createStoreFromBasePath( KStandardDirs::locateLocal( "data", QLatin1String( "kmail/imap" ) ) ); - } - store = mImapCache; - } - - ImapCacheCollectionMigrator *collectionMigrator = new ImapCacheCollectionMigrator( instance, nameAccount, store, this ); - QString topLevelFolder = config.readEntry( "Folder" ); - if ( topLevelFolder.isEmpty() ) { - topLevelFolder = config.readEntry( "Id" ); - } - - const QString topLevelRemoteId = - QLatin1String("imap://") + config.readEntry( "login" ) + QLatin1Char('@') + config.readEntry( "host" ) + QLatin1Char('/'); - - collectionMigrator->setTopLevelFolder( topLevelFolder, nameAccount, topLevelRemoteId ); - collectionMigrator->setMigrationOptions( options ); - - kDebug() << "Starting IMAP collection migration: options=" - << collectionMigrator->migrationOptions(); - collectionMigrator->setKMailConfig( mConfig ); - collectionMigrator->setEmailIdentityConfig( mEmailIdentityConfig ); - collectionMigrator->setKcmKmailSummaryConfig( mKcmKmailSummaryConfig ); - collectionMigrator->setTemplatesConfig( mTemplatesConfig ); - - if ( config.readEntry( "locally-subscribed-folders", false ) ) { - collectionMigrator->setUnsubscribedImapFolders( config.readEntry( "locallyUnsubscribedFolders", QStringList() ) ); - } - - if ( disconnected && store ) { - if ( mImapCacheAdapter == 0 ) { - mImapCacheAdapter = new ImapCacheAdapter( store, this ); - connect( mImapCacheAdapter, SIGNAL(finished(int,QString)), - SLOT(imapCacheAdaptionFinished(int,QString)) ); - } - mImapCacheAdapter->addAccount( topLevelFolder, nameAccount ); - } - - connect( collectionMigrator, SIGNAL(migrationFinished(Akonadi::AgentInstance,QString)), - SLOT(imapFoldersMigrationFinished(Akonadi::AgentInstance,QString)) ); - - connectCollectionMigrator( collectionMigrator ); - - collectionMigrator->startMigration(); -} - -void KMailMigrator::pop3AccountCreated( KJob *job ) -{ - if ( job->error() ) { - migrationFailed( i18n( "Failed to create resource: %1", job->errorText() ) ); - return; - } - emit message( Info, i18n( "Created pop3 resource" ) ); - - AgentInstance instance = static_cast< AgentInstanceCreateJob* >( job )->instance(); - mCurrentInstance = instance; - KConfigGroup config( mConfig, mCurrentAccount ); - - OrgKdeAkonadiPOP3SettingsInterface *iface = createPop3SettingsInterface( instance ); - if ( !iface ) { - return; - } - - AccountConfig conf; - conf.instance = instance; - conf.imapAccount = false; - mAccountInstance.insert( mCurrentAccount, conf ); - - iface->setHost( config.readEntry( "host", QString() ) ); - iface->setPort( config.readEntry( "port", 110u ) ); - iface->setLogin( config.readEntry( "login", QString() ) ); - if ( config.readEntry( "use-ssl", true ) ) - iface->setUseSSL( true ); - if ( config.readEntry( "use-tls", true ) ) - iface->setUseTLS( true ); - if ( config.readEntry( "pipelining", false ) ) - iface->setPipelining( true ); - if ( config.readEntry( "leave-on-server", true ) ) { - iface->setLeaveOnServer( true ); - iface->setLeaveOnServerDays( config.readEntry( "leave-on-server-days", -1 ) ); - iface->setLeaveOnServerCount( config.readEntry( "leave-on-server-count", -1 ) ); - iface->setLeaveOnServerSize( config.readEntry( "leave-on-server-size", -1 ) ); - } - if ( config.readEntry( "filter-on-server", false ) ) { - iface->setFilterOnServer( true ); - iface->setFilterCheckSize( config.readEntry( "filter-os-check-size" ).toUInt() ); - } - const int checkInterval = config.readEntry( "check-interval", 0 ); - if ( checkInterval == 0 ) - iface->setIntervalCheckEnabled( false ); - else { - iface->setIntervalCheckEnabled( true ); - iface->setIntervalCheckInterval( checkInterval ); - } - - // check-exclude in Account section means that this account should not be included - // in manual checks. In KMail UI this is called "Include in manual checks" - KConfigGroup resourceGroup( mConfig, QString::fromLatin1( "Resource %1" ).arg( instance.identifier() ) ); - resourceGroup.writeEntry( "IncludeInManualChecks", !config.readEntry( "check-exclude", false ) ); - const KConfigGroup generalGroup( mConfig, "General" ); - resourceGroup.writeEntry( "CheckOnStartup", generalGroup.readEntry( "checkmail-startup", false ) ); - resourceGroup.writeEntry( "OfflineOnShutdown", true ); - - // Akonadi kmail uses enums for storing auth options - // so we have to convert from the old string representations - typedef MailTransport::Transport::EnumAuthenticationType AuthType; - QString authOpt = config.readEntry( "auth" ); - if ( authOpt.contains( QLatin1String("PLAIN"), Qt::CaseInsensitive ) ) - iface->setAuthenticationMethod( AuthType::PLAIN ); - else if ( authOpt.contains( QLatin1String("CRAM"), Qt::CaseInsensitive ) ) - iface->setAuthenticationMethod( AuthType::CRAM_MD5 ); - else if ( authOpt.contains( QLatin1String("DIGEST"), Qt::CaseInsensitive ) ) - iface->setAuthenticationMethod( AuthType::DIGEST_MD5); - else if ( authOpt.contains( QLatin1String("GSSAPI"), Qt::CaseInsensitive ) ) - iface->setAuthenticationMethod( AuthType::GSSAPI ); - else if ( authOpt.contains( QLatin1String("NTLM"), Qt::CaseInsensitive ) ) - iface->setAuthenticationMethod( AuthType::NTLM); - else if ( authOpt.contains( QLatin1String("APOP"), Qt::CaseInsensitive ) ) - iface->setAuthenticationMethod( AuthType::APOP ); - else - iface->setAuthenticationMethod( AuthType::CLEAR ); - iface->setPrecommand( config.readPathEntry( "precommand", QString() ) ); - - QString encpasswd; - - if ( config.readEntry( "store-passwd", false ) ) { - encpasswd = config.readEntry( "pass" ); - if ( encpasswd.isEmpty() ) { - encpasswd = config.readEntry( "passwd" ); - if ( !encpasswd.isEmpty() ) - encpasswd = importPassword( encpasswd ); - } - - if ( !encpasswd.isEmpty() ) { - encpasswd = KStringHandler::obscure( encpasswd ); - } - config.deleteEntry( "store-passwd" ); - config.deleteEntry( "passwd" ); - } - migratePassword( config.readEntry( "Id" ), instance, QLatin1String("pop3"), encpasswd ); - - // POP3 filter from files in kmail appdata - const QString popFilterFileName = QString::fromLatin1( "kmail/%1:@%2:%3" ) - .arg( config.readEntry( "login", QString() ) ) - .arg( config.readEntry( "host", QString() ) ) - .arg( config.readEntry( "port", 110u ) ); - - const KConfig popFilterConfig( popFilterFileName, KConfig::SimpleConfig, "data" ); - const KConfigGroup popFilterGroup( &popFilterConfig, QString() ); - iface->setDownloadLater( popFilterGroup.readEntry( "downloadLater", QStringList() ) ); - iface->setSeenUidList( popFilterGroup.readEntry( "seenUidList", QStringList() ) ); - iface->setSeenUidTimeList( popFilterGroup.readEntry( "seenUidTimeList", QList() ) ); - - // make sure the config is saved - iface->writeConfig(); - - //Info: there is trash item in config which is default and we can't configure it => don't look at it in pop account. - config.deleteEntry( "trash" ); - config.deleteEntry( "use-default-identity" ); - const QString nameAccount = config.readEntry( "Name" ); - instance.setName( nameAccount ); - emit status( nameAccount ); - instance.reconfigure(); - config.sync(); - migrationCompleted( instance ); -} - -void KMailMigrator::mboxAccountCreated( KJob *job ) -{ - if ( job->error() ) { - migrationFailed( i18n( "Failed to create resource: %1", job->errorText() ) ); - return; - } - emit message( Info, i18n( "Created mbox resource" ) ); - - AgentInstance instance = static_cast< AgentInstanceCreateJob* >( job )->instance(); - mCurrentInstance = instance; - KConfigGroup config( mConfig, mCurrentAccount ); - - OrgKdeAkonadiMboxSettingsInterface *iface = new OrgKdeAkonadiMboxSettingsInterface( - QLatin1String("org.freedesktop.Akonadi.Resource.") + instance.identifier(), - QLatin1String("/Settings"), QDBusConnection::sessionBus(), this ); - - if ( !iface->isValid() ) { - migrationFailed( i18n( "Failed to obtain D-Bus interface for remote configuration." ), instance ); - delete iface; - return; - } - - iface->setPath( config.readEntry( "Location" ) ); - const QString lockType = config.readEntry( "LockType" ).toLower(); - if ( lockType == QLatin1String( "procmail_locktype" ) ) { - iface->setLockfileMethod( Procmail ); - iface->setLockfile( config.readEntry( "ProcmailLockFile" ) ); - } else if ( lockType == QLatin1String( "mutt_dotlock" ) ) - iface->setLockfileMethod( MuttDotLock ); - else if ( lockType == QLatin1String( "mutt_dotlock_privileged" ) ) - iface->setLockfileMethod( MuttDotLockPrivileged ); - else if ( lockType == QLatin1String( "none" ) ) - iface->setLockfileMethod( MboxNone ); - - // make sure the config is saved - iface->writeConfig(); - - // check-exclude in Account section means that this account should not be included - // in manual checks. In KMail UI this is called "Include in manual checks" - KConfigGroup resourceGroup( mConfig, QString::fromLatin1( "Resource %1" ).arg( instance.identifier() ) ); - resourceGroup.writeEntry( "IncludeInManualChecks", !config.readEntry( "check-exclude", false ) ); - const KConfigGroup generalGroup( mConfig, "General" ); - resourceGroup.writeEntry( "CheckOnStartup", generalGroup.readEntry( "checkmail-startup", false ) ); - resourceGroup.writeEntry( "OfflineOnShutdown", false ); - - //Info: there is trash item in config which is default and we can't configure it => don't look at it in pop account. - config.deleteEntry( "trash" ); - config.deleteEntry( "identity-id" ); - config.deleteEntry( "use-default-identity" ); - //We can't specify folder in akonadi - config.deleteEntry( "Folder" ); - - //TODO check-interval for the moment mbox doesn't support it - - const QString nameAccount = config.readEntry( "Name" ); - instance.setName( nameAccount ); - emit status( nameAccount ); - instance.reconfigure(); - config.sync(); - migrationCompleted( instance ); -} - -void KMailMigrator::maildirAccountCreated( KJob *job ) -{ - if ( job->error() ) { - migrationFailed( i18n( "Failed to create resource: %1", job->errorText() ) ); - return; - } - emit message( Info, i18n( "Created maildir resource" ) ); - - AgentInstance instance = static_cast< AgentInstanceCreateJob* >( job )->instance(); - mCurrentInstance = instance; - KConfigGroup config( mConfig, mCurrentAccount ); - - OrgKdeAkonadiMaildirSettingsInterface *iface = new OrgKdeAkonadiMaildirSettingsInterface( - QLatin1String("org.freedesktop.Akonadi.Resource.") + instance.identifier(), - QLatin1String("/Settings"), QDBusConnection::sessionBus(), this ); - - if ( !iface->isValid() ) { - migrationFailed( i18n( "Failed to obtain D-Bus interface for remote configuration." ), instance ); - delete iface; - return; - } - - iface->setPath( config.readEntry( "Location" ) ); - - // make sure the config is saved - iface->writeConfig(); - - // check-exclude in Account section means that this account should not be included - // in manual checks. In KMail UI this is called "Include in manual checks" - KConfigGroup resourceGroup( mConfig, QString::fromLatin1( "Resource %1" ).arg( instance.identifier() ) ); - resourceGroup.writeEntry( "IncludeInManualChecks", !config.readEntry( "check-exclude", false ) ); - const KConfigGroup generalGroup( mConfig, "General" ); - resourceGroup.writeEntry( "CheckOnStartup", generalGroup.readEntry( "checkmail-startup", false ) ); - resourceGroup.writeEntry( "OfflineOnShutdown", false ); - - //Info: there is trash item in config which is default and we can't configure it => don't look at it in pop account. - config.deleteEntry( "trash" ); - config.deleteEntry( "identity-id" ); - config.deleteEntry( "use-default-identity" ); - //Now in akonadi we can't specify a folder where we put email, it's a specific top root - config.deleteEntry( "Folder" ); - - //TODO: check-interval for the moment maildir doesn't support check-interval. - - const QString nameAccount = config.readEntry( "Name" ); - instance.setName( nameAccount ); - emit status( nameAccount ); - instance.reconfigure(); - config.sync(); - migrationCompleted( instance ); -} - -void KMailMigrator::localMaildirCreated( KJob *job ) -{ - if ( job->error() ) { - emit message( Error, i18n( "Failed to create resource for local folders: %1", job->errorText() ) ); - deleteLater(); - return; - } - emit message( Info, i18n( "Created local maildir resource." ) ); - - AgentInstance instance = static_cast< AgentInstanceCreateJob* >( job )->instance(); - mCurrentInstance = instance; - - // do not include KMail folders in manual checks by default - KConfigGroup resourceGroup( mConfig, QString::fromLatin1( "Resource %1" ).arg( instance.identifier() ) ); - resourceGroup.writeEntry( "IncludeInManualChecks", false ); - // do not synchronize on startup - resourceGroup.writeEntry( "CheckOnStartup", false ); - resourceGroup.writeEntry( "OfflineOnShutdown", false ); - - const bool specialCollectionsLock = - QDBusConnection::sessionBus().registerService( SPECIALCOLLECTIONS_LOCK_SERVICE ); - - KConfig specialMailCollectionsConfig( QLatin1String( "specialmailcollectionsrc" ) ); - KConfigGroup specialMailCollectionsGroup = specialMailCollectionsConfig.group( QLatin1String( "SpecialCollections" ) ); - - QString defaultInstanceName; - QString defaultResourceId = specialMailCollectionsGroup.readEntry( QLatin1String( "DefaultResourceId" ) ); - if ( defaultResourceId.isEmpty() ) { - kDebug() << "No resource configured for special mail collections, using the migrated" - << instance.identifier(); - defaultResourceId = instance.identifier(); - } else { - const AgentInstance defaultInstance = AgentManager::self()->instance( defaultResourceId ); - if ( !defaultInstance.isValid() ) { - kDebug() << "Resource" << defaultResourceId - << " configured for special mail collections does not exist, using the migrated" - << instance.identifier(); - defaultResourceId = instance.identifier(); - } else { - defaultInstanceName = defaultInstance.name(); - } - } - - const QString instanceName = i18n( "KMail Folders" ); - - if ( defaultInstanceName.isEmpty() && specialCollectionsLock ) { - specialMailCollectionsGroup.writeEntry( QLatin1String( "DefaultResourceId" ), defaultResourceId ); - specialMailCollectionsGroup.sync(); - - emit message( Info, - i18nc( "@info:status resource that will provide folder such as outbox, sent", - "Using '%1' for default outbox, sent mail, trash, etc.", - instanceName ) ); - } else { - emit message( Info, - i18nc( "@info:status resource that will provide folder such as outbox, sent", - "Keeping '%1' for default outbox, sent mail, trash, etc.", - defaultInstanceName ) ); - } - - if ( specialCollectionsLock ) { - QDBusConnection::sessionBus().unregisterService( SPECIALCOLLECTIONS_LOCK_SERVICE ); - } - - instance.setName( instanceName ); - emit status( instanceName ); - - MixedMaildirStore *store = createStoreFromBasePath( mLocalMaildirPath ); - - LocalFoldersCollectionMigrator *collectionMigrator = new LocalFoldersCollectionMigrator( instance, instanceName, store, this ); - collectionMigrator->setTopLevelFolder( QString(), instanceName ); - collectionMigrator->setKMailConfig( mConfig ); - collectionMigrator->setEmailIdentityConfig( mEmailIdentityConfig ); - collectionMigrator->setKcmKmailSummaryConfig( mKcmKmailSummaryConfig ); - collectionMigrator->setTemplatesConfig( mTemplatesConfig ); - - connect( collectionMigrator, SIGNAL(migrationFinished(Akonadi::AgentInstance,QString)), - SLOT(localFoldersMigrationFinished(Akonadi::AgentInstance,QString)) ); - connectCollectionMigrator( collectionMigrator ); - - collectionMigrator->startMigration(); -} - -void KMailMigrator::localFoldersMigrationFinished( const AgentInstance &instance, const QString &error ) -{ - OrgKdeAkonadiMixedMaildirSettingsInterface *iface = new OrgKdeAkonadiMixedMaildirSettingsInterface( - QLatin1String("org.freedesktop.Akonadi.Resource.") + instance.identifier(), - QLatin1String("/Settings"), QDBusConnection::sessionBus(), this ); - - if ( !iface->isValid() ) { - migrationFailed( i18n("Failed to obtain D-Bus interface for remote configuration."), instance ); - delete iface; - return; - } - - iface->setPath( mLocalMaildirPath ); - - // make sure the config is saved - iface->writeConfig(); - - AgentInstance resource = instance; - resource.reconfigure(); - - if ( error.isEmpty() ) { - KConfigGroup config( KGlobal::config(), QLatin1String( "SpecialMailCollections" ) ); - if ( config.readEntry( QLatin1String( "TakeOverIfDefaultIsTotallyEmpty" ), false ) ) { - KConfig specialMailCollectionsConfig( QLatin1String( "specialmailcollectionsrc" ) ); - KConfigGroup specialMailCollectionsGroup = specialMailCollectionsConfig.group( QLatin1String( "SpecialCollections" ) ); - - QString defaultResourceId = specialMailCollectionsGroup.readEntry( QLatin1String( "DefaultResourceId" ) ); - - AgentInstance defaultResource = AgentManager::self()->instance( defaultResourceId ); - if ( defaultResource.isValid() && defaultResourceId != instance.identifier() ) { - kDebug() << "Attempting take over of special mail collections role from" - << defaultResourceId; - - EmptyResourceCleaner *cleaner = new EmptyResourceCleaner( defaultResource, this ); - cleaner->setCleaningOptions( EmptyResourceCleaner::CheckOnly ); - connect( cleaner, SIGNAL(cleanupFinished(Akonadi::AgentInstance)), - SLOT(specialColDefaultResourceCheckFinished(Akonadi::AgentInstance)) ); - return; - } - } - - mCurrentInstance = AgentInstance(); - - setMigrationState( QLatin1String("LocalFolders"), Complete, instance.identifier(), QLatin1String("LocalFolders") ); - emit message( Success, i18n( "Local folders migrated successfully." ) ); - emit status( QString() ); - migrationDone(); - - } else { - mCurrentInstance = AgentInstance(); - - migrationFailed( error, instance ); - } -} - -void KMailMigrator::imapFoldersMigrationFinished( const AgentInstance &instance, const QString &error ) -{ - kDebug() << "imapMigrationFinished: instance=" << instance.identifier() - << "error=" << error; - - OrgKdeAkonadiImapSettingsInterface *iface = createImapSettingsInterface( instance ); - if ( !iface ) { - return; - } - - const bool disconnected = mAccountInstance[ mCurrentAccount ].disconnectedImap; - - KConfigGroup config( mConfig, mCurrentAccount ); - const QString nameAccount = config.readEntry( "Name" ); - - iface->setImapServer( config.readEntry( "host" ) ); - iface->setImapPort( config.readEntry( "port", 143 ) ); - iface->setUserName( config.readEntry( "login" ) ); - if ( config.readEntry( "use-ssl" ).toLower() == QLatin1String("true") ) - iface->setSafety( QLatin1String("SSL") ); - else if ( config.readEntry( "use-tls" ).toLower() == QLatin1String("true") ) - iface->setSafety( QLatin1String("STARTTLS") ); - else - iface->setSafety( QLatin1String("NONE") ); - const QString authentication = config.readEntry( "auth" ).toUpper(); - if ( authentication == QLatin1String( "LOGIN" ) ) - iface->setAuthentication( MailTransport::Transport::EnumAuthenticationType::LOGIN ); - else if ( authentication == QLatin1String( "PLAIN" ) ) - iface->setAuthentication( MailTransport::Transport::EnumAuthenticationType::PLAIN ); - else if ( authentication == QLatin1String( "CRAM-MD5" ) ) - iface->setAuthentication( MailTransport::Transport::EnumAuthenticationType::CRAM_MD5 ); - else if ( authentication == QLatin1String( "DIGEST-MD5" ) ) - iface->setAuthentication( MailTransport::Transport::EnumAuthenticationType::DIGEST_MD5 ); - else if ( authentication == QLatin1String( "NTLM" ) ) - iface->setAuthentication( MailTransport::Transport::EnumAuthenticationType::NTLM ); - else if ( authentication == QLatin1String( "GSSAPI" ) ) - iface->setAuthentication( MailTransport::Transport::EnumAuthenticationType::GSSAPI ); - else if ( authentication == QLatin1String( "ANONYMOUS" ) ) - iface->setAuthentication( MailTransport::Transport::EnumAuthenticationType::ANONYMOUS ); - else { - iface->setAuthentication( MailTransport::Transport::EnumAuthenticationType::CLEAR ); - } - if ( config.readEntry( "subscribed-folders" ).toLower() == QLatin1String("true") ) - iface->setSubscriptionEnabled( true ); - - // skip interval checking so it doesn't interfere with cache importing - iface->setIntervalCheckTime( -1 ); //exclude - - // check-exclude in Account section means that this account should not be included - // in manual checks. In KMail UI this is called "Include in manual checks" - KConfigGroup resourceGroup( mConfig, QString::fromLatin1( "Resource %1" ).arg( instance.identifier() ) ); - resourceGroup.writeEntry( "IncludeInManualChecks", !config.readEntry( "check-exclude", false ) ); - const KConfigGroup generalGroup( mConfig, "General" ); - resourceGroup.writeEntry( "CheckOnStartup", generalGroup.readEntry( "checkmail-startup", false ) ); - resourceGroup.writeEntry( "OfflineOnShutdown", true ); - - iface->setSieveSupport( config.readEntry( "sieve-support", false ) ); - iface->setSieveReuseConfig( config.readEntry( "sieve-reuse-config", true ) ); - iface->setSievePort( config.readEntry( "sieve-port", 2000 ) ); - iface->setSieveAlternateUrl( config.readEntry( "sieve-alternate-url" ) ); - iface->setSieveVacationFilename( config.readEntry( "sieve-vacation-filename", "kmail-vacation.siv" ) ); - iface->setDisconnectedModeEnabled( disconnected ); - if ( !disconnected ) { - iface->setAutomaticExpungeEnabled( config.readEntry( "auto-expunge", true ) ); - } - const bool useDefaultIdentity = config.readEntry( "use-default-identity", true ); - iface->setUseDefaultIdentity( useDefaultIdentity ); - if ( !useDefaultIdentity ) - iface->setAccountIdentity( config.readEntry( "identity-id" ).toInt() ); - - QString encpasswd ; - if ( config.readEntry( "store-passwd", false ) ) { - encpasswd = config.readEntry( "pass" ); - if ( encpasswd.isEmpty() ) { - encpasswd = config.readEntry( "passwd" ); - if ( !encpasswd.isEmpty() ) - encpasswd = importPassword( encpasswd ); - } - - if ( !encpasswd.isEmpty() ) { - encpasswd = KStringHandler::obscure( encpasswd ); - } - config.deleteEntry( "store-passwd" ); - config.deleteEntry( "passwd" ); - } - migratePassword( config.readEntry( "Id" ), instance, QLatin1String("imap"), encpasswd ); - - // enable interval checking in case this had been configured - const int checkInterval = config.readEntry( "check-interval", 0 ); - if ( checkInterval != 0 ) { - iface->setIntervalCheckEnabled( true ); - iface->setIntervalCheckTime( checkInterval ); - } - - // make sure the config is saved - iface->writeConfig(); - - AgentInstance resource = instance; - resource.reconfigure(); - - config.deleteEntry( "locally-subscribed-folders" ); - config.deleteEntry( "locallyUnsubscribedFolders" ); - - config.deleteEntry( "capabilities" ); - - if ( error.isEmpty() ) { - migrationCompleted( instance ); - } else { - migrationFailed( error, true, instance ); - } -} - -void KMailMigrator::collectionMigratorMessage( int type, const QString &msg ) -{ - switch ( type ) { - case Success: - emit message( Success, msg ); - break; - - case Skip: - emit message( Skip, msg ); - break; - - case Warning: - emit message( Warning, msg ); - break; - - case Info: - emit message( Info, msg ); - break; - - case Error: - emit message( Error, msg ); - break; - - default: - kError() << "Unknown message type" << type << "msg=" << msg; - break; - } -} - -void KMailMigrator::collectionMigratorFinished() -{ - emit status( QString() ); -} - -void KMailMigrator::collectionMigratorEmittedNotification() -{ - mForwardResourceNotifications = false; -} - -void KMailMigrator::instanceStatusChanged( const AgentInstance &instance ) -{ - if ( !mForwardResourceNotifications ) { - return; - } - - if ( instance.identifier() != mCurrentInstance.identifier() ) { - return; - } - - if ( instance.status() == AgentInstance::Idle ) { - emit status( QString() ); - } else { - emit status( instance.statusMessage() ); - } -} - -void KMailMigrator::instanceProgressChanged( const AgentInstance &instance ) -{ - if ( !mForwardResourceNotifications ) { - return; - } - - if ( instance.identifier() != mCurrentInstance.identifier() ) { - return; - } - - emit progress( 0, 100, instance.progress() ); -} - -void KMailMigrator::imapCacheAdaptionFinished( int messageType, const QString &messageText ) -{ - emit message( (KMigratorBase::MessageType)messageType, messageText ); - - mImapCacheAdapter = 0; - - migrateNext(); -} - -void KMailMigrator::specialColDefaultResourceCheckFinished( const AgentInstance &instance ) -{ - KConfig specialMailCollectionsConfig( QLatin1String( "specialmailcollectionsrc" ) ); - KConfigGroup specialMailCollectionsGroup = specialMailCollectionsConfig.group( QLatin1String( "SpecialCollections" ) ); - - const EmptyResourceCleaner *cleaner = qobject_cast( QObject::sender() ); - - const bool specialCollectionsLock = - QDBusConnection::sessionBus().registerService( SPECIALCOLLECTIONS_LOCK_SERVICE ); - - const QString localFoldersIdentifier = mCurrentInstance.identifier(); - if ( cleaner->isResourceDeletable() && specialCollectionsLock ) { - specialMailCollectionsGroup.writeEntry( QLatin1String( "DefaultResourceId" ), localFoldersIdentifier ); - specialMailCollectionsGroup.sync(); - AgentManager::self()->removeInstance( instance ); - - kDebug() << "Former special mail collection resource" << instance.identifier() - << "successfully delete, now using" << specialMailCollectionsGroup.readEntry( QLatin1String( "DefaultResourceId" ) ); - } else { - kDebug() << "Former special mail collection resource" << instance.identifier() - << "still valid"; - } - - if ( specialCollectionsLock ) { - QDBusConnection::sessionBus().unregisterService( SPECIALCOLLECTIONS_LOCK_SERVICE ); - } - - mCurrentInstance = AgentInstance(); - - setMigrationState( QLatin1String("LocalFolders"), Complete, localFoldersIdentifier, QLatin1String("LocalFolders") ); - emit message( Success, i18n( "Local folders migrated successfully." ) ); - emit status( QString() ); - migrationDone(); -} - -QString KMailMigrator::importPassword(const QString &aStr) -{ - unsigned int i, val; - unsigned int len = aStr.length(); - QByteArray result; - result.resize( len ); - - for ( i = 0; i < len; i++ ) { - val = aStr[i].toLatin1() - ' '; - val = ( 255-' ') - val; - result[i] = (char)( val + ' '); - } - result[i] = '\0'; - - return KStringHandler::obscure( QString::fromLatin1(result) ); -} - - diff -Nru kdepim-runtime-4.14.6/migration/kmail/kmailmigrator.h kdepim-runtime-15.08.0/migration/kmail/kmailmigrator.h --- kdepim-runtime-4.14.6/migration/kmail/kmailmigrator.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/kmailmigrator.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,161 +0,0 @@ -/* - Copyright (c) 2009 Jonathan Armond - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 KMAILMIGRATOR_H -#define KMAILMIGRATOR_H - -#include "kmigratorbase.h" - -#include - -#include -#include - -class AbstractCollectionMigrator; -class ImapCacheAdapter; -class KJob; -class MixedMaildirStore; -class OrgKdeAkonadiImapSettingsInterface; -class OrgKdeAkonadiPOP3SettingsInterface; - -namespace KWallet -{ - class Wallet; -} - -namespace KMail -{ - -/** - * KMail to Akonadi account migrator - */ -class KMailMigrator : public KMigratorBase -{ - Q_OBJECT - - public: - KMailMigrator(); - virtual ~KMailMigrator(); - - void migrate(); - - void migrateTags(); - void migrateRCFiles(); - void migrateNotifyFile(); - void migrateNext(); - void migrateLocalFolders(); - void migrationDone(); - void deleteOldGroup(); - void migrateConfigurationDialogRestriction(); - - Q_SIGNALS: - void status( const QString &msg ); - void progress( int value ); - void progress( int min, int max, int value ); - - private Q_SLOTS: - void imapAccountCreated( KJob *job ); - void imapDisconnectedAccountCreated( KJob *job ); - void pop3AccountCreated( KJob *job ); - void mboxAccountCreated( KJob *job ); - void maildirAccountCreated( KJob *job ); - void localMaildirCreated( KJob *job ); - - void localFoldersMigrationFinished( const Akonadi::AgentInstance &instance, const QString &error ); - void imapFoldersMigrationFinished( const Akonadi::AgentInstance &instance, const QString &error ); - - void collectionMigratorMessage( int type, const QString &msg ); - void collectionMigratorFinished(); - void collectionMigratorEmittedNotification(); - - void instanceStatusChanged( const Akonadi::AgentInstance &instance ); - void instanceProgressChanged( const Akonadi::AgentInstance &instance ); - -#if 0 - void imapCacheImportFinished( const Akonadi::AgentInstance &instance, const QString &error ); - void imapCacheCleanupFinished( const Akonadi::AgentInstance &instance ); -#endif - void imapCacheAdaptionFinished( int messageType, const QString &message ); - - void specialColDefaultResourceCheckFinished( const Akonadi::AgentInstance &instance ); - - void autoSaveCopyResult( KJob* ); - - private: - void deleteOldGroup( const QString& ); - void migrateImapAccount( KJob *job, bool disconnected ); - bool migrateCurrentAccount(); - void migrationFailed( const QString &errorMsg, const Akonadi::AgentInstance &instance - = Akonadi::AgentInstance() ) - { - migrationFailed( errorMsg, true, instance ); - } - - void migrationFailed( const QString &errorMsg, bool doMigrateNext, - const Akonadi::AgentInstance &instance = Akonadi::AgentInstance() ); - void migrationCompleted( const Akonadi::AgentInstance &instance, bool doMigrateNext = true ); - - void connectCollectionMigrator( AbstractCollectionMigrator *migrator ); - - void migrateInstanceTrashFolder(); - - void migratePassword( const QString &idString, const Akonadi::AgentInstance &instance, - const QString &newFolder, const QString &passwordFromFilePassword ); - - OrgKdeAkonadiImapSettingsInterface* createImapSettingsInterface( const Akonadi::AgentInstance& instance ); - OrgKdeAkonadiPOP3SettingsInterface* createPop3SettingsInterface( const Akonadi::AgentInstance& instance ); - - //code from kmaccount - QString importPassword( const QString &aStr ); - void cleanupConfigFile(); - - private: - KWallet::Wallet *mWallet; - KSharedConfigPtr mConfig; - KSharedConfigPtr mEmailIdentityConfig; - KSharedConfigPtr mKcmKmailSummaryConfig; - KSharedConfigPtr mTemplatesConfig; - QString mCurrentAccount; - QStringList mAccounts; - QString mLocalMaildirPath; - typedef QStringList::iterator AccountIterator; - AccountIterator mIt; - Akonadi::AgentInstance mCurrentInstance; - MixedMaildirStore *mDImapCache; - MixedMaildirStore *mImapCache; - - struct AccountConfig { - AccountConfig() : imapAccount( false ), disconnectedImap( false ) { } - Akonadi::AgentInstance instance; - bool imapAccount; - bool disconnectedImap; - }; - QHash mAccountInstance; - QList mFailedInstances; - - bool mForwardResourceNotifications; - - ImapCacheAdapter *mImapCacheAdapter; -}; - -} // namespace KMail - -#endif diff -Nru kdepim-runtime-4.14.6/migration/kmail/kmail-migratorrc kdepim-runtime-15.08.0/migration/kmail/kmail-migratorrc --- kdepim-runtime-4.14.6/migration/kmail/kmail-migratorrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/kmail-migratorrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -[Migration] -Enabled=true -TargetVersion=1 - -[SpecialMailCollections] -TakeOverIfDefaultIsTotallyEmpty=true - -[Disconnected IMAP] -ImportNewMessages=true -ImportCachedMessages=false -RemoveDeletedMessages=false diff -Nru kdepim-runtime-4.14.6/migration/kmail/localfolderscollectionmigrator.cpp kdepim-runtime-15.08.0/migration/kmail/localfolderscollectionmigrator.cpp --- kdepim-runtime-4.14.6/migration/kmail/localfolderscollectionmigrator.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/localfolderscollectionmigrator.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,123 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.com - Copyright (C) 2011 Kevin Krammer, kevin.krammer@gmx.at - - 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 "localfolderscollectionmigrator.h" - -#include -#include - -#include -#include -#include - -#include - -using namespace Akonadi; - -typedef QHash TypeHash; - -class LocalFoldersCollectionMigrator::Private -{ - LocalFoldersCollectionMigrator *const q; - - public: - explicit Private( LocalFoldersCollectionMigrator *parent ) - : q( parent ) - { - } - - public: - TypeHash mSystemFolders; -}; - -LocalFoldersCollectionMigrator::LocalFoldersCollectionMigrator( const AgentInstance &resource, const QString &resourceName, MixedMaildirStore *store, QObject *parent ) - : AbstractCollectionMigrator( resource, resourceName, store, parent ), d( new Private( this ) ) -{ -} - -LocalFoldersCollectionMigrator::~LocalFoldersCollectionMigrator() -{ - delete d; -} - -void LocalFoldersCollectionMigrator::setKMailConfig( const KSharedConfigPtr &config ) -{ - AbstractCollectionMigrator::setKMailConfig( config ); - - const KConfigGroup group( config, QLatin1String( "General" ) ); - - if ( group.hasKey( QLatin1String( "inboxFolder" ) ) ) { - const QString name = group.readEntry( QLatin1String( "inboxFolder" ), i18nc( "mail folder name for role inbox", "inbox" ) ); - d->mSystemFolders.insert( name, SpecialMailCollections::Inbox ); - } else - d->mSystemFolders.insert( QLatin1String( "inbox" ), SpecialMailCollections::Inbox ); - - if ( group.hasKey( QLatin1String( "outboxFolder" ) ) ) { - const QString name = group.readEntry( QLatin1String( "outboxFolder" ), i18nc( "mail folder name for role outbox", "outbox" ) ); - d->mSystemFolders.insert( name, SpecialMailCollections::Outbox ); - } else - d->mSystemFolders.insert( QLatin1String( "outbox" ), SpecialMailCollections::Outbox ); - - if ( group.hasKey( QLatin1String( "sentFolder" ) ) ) { - const QString name = group.readEntry( QLatin1String( "sentFolder" ), i18nc( "mail folder name for role sent-mail", "sent-mail" ) ); - d->mSystemFolders.insert( name, SpecialMailCollections::SentMail ); - } else - d->mSystemFolders.insert( QLatin1String( "sent-mail" ), SpecialMailCollections::SentMail ); - - if ( group.hasKey( QLatin1String( "trashFolder" ) ) ) { - const QString name = group.readEntry( QLatin1String( "trashFolder" ), i18nc( "mail folder name for role trash", "trash" ) ); - d->mSystemFolders.insert( name, SpecialMailCollections::Trash ); - } else - d->mSystemFolders.insert( QLatin1String( "trash" ), SpecialMailCollections::Trash ); - - if ( group.hasKey( QLatin1String( "draftsFolder" ) ) ) { - const QString name = group.readEntry( QLatin1String( "draftsFolder" ), i18nc( "mail folder name for role drafts", "drafts" ) ); - d->mSystemFolders.insert( name, SpecialMailCollections::Drafts ); - } else - d->mSystemFolders.insert( QLatin1String( "drafts" ), SpecialMailCollections::Drafts ); - - if ( group.hasKey( QLatin1String( "templatesFolder" ) ) ) { - const QString name = group.readEntry( QLatin1String( "templatesFolder" ), i18nc( "mail folder name for role templates", "templates" ) ); - d->mSystemFolders.insert( name, SpecialMailCollections::Templates ); - } else - d->mSystemFolders.insert( QLatin1String( "templates" ), SpecialMailCollections::Templates ); -} - -void LocalFoldersCollectionMigrator::migrateCollection( const Collection &collection, const QString &folderId ) -{ - Q_UNUSED( folderId ); - - emit status( collection.name() ); - - if ( collection.parentCollection() == Collection::root() ) { - registerAsSpecialCollection( SpecialMailCollections::Root ); - } else { - const TypeHash::const_iterator typeIt = d->mSystemFolders.constFind( collection.name() ); - if ( typeIt != d->mSystemFolders.constEnd() ) { - registerAsSpecialCollection( *typeIt ); - } - } - - collectionProcessed(); -} - - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/migration/kmail/localfolderscollectionmigrator.h kdepim-runtime-15.08.0/migration/kmail/localfolderscollectionmigrator.h --- kdepim-runtime-4.14.6/migration/kmail/localfolderscollectionmigrator.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/localfolderscollectionmigrator.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.com - Copyright (C) 2011 Kevin Krammer, kevin.krammer@gmx.at - - 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 LOCALFOLDERSCOLLECTIONMIGRATOR_H -#define LOCALFOLDERSCOLLECTIONMIGRATOR_H - -#include "abstractcollectionmigrator.h" - -class LocalFoldersCollectionMigrator : public AbstractCollectionMigrator -{ - Q_OBJECT - - public: - LocalFoldersCollectionMigrator( const Akonadi::AgentInstance &resource, const QString &resourceName, MixedMaildirStore *store, QObject *parent = 0 ); - - void setKMailConfig( const KSharedConfigPtr &config ); - - ~LocalFoldersCollectionMigrator(); - - protected: - void migrateCollection( const Akonadi::Collection &collection, const QString &folderId ); - - private: - class Private; - Private *const d; -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/migration/kmail/main.cpp kdepim-runtime-15.08.0/migration/kmail/main.cpp --- kdepim-runtime-4.14.6/migration/kmail/main.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ -/* - Copyright (c) 2009 Jonathan Armond - Copyright (c) 2010 Volker Krause - - 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 "kmailmigrator.h" - -#include "infodialog.h" - -#include - -#include -#include -#include -#include -#include - - -using namespace KMail; - -int main( int argc, char **argv ) -{ - KAboutData aboutData( "kmail-migrator", 0, - ki18n( "KMail Migration Tool" ), - "0.1", - ki18n( "Migration of KMail accounts to Akonadi" ), - KAboutData::License_LGPL, - ki18n( "(c) 2009-2010 the Akonadi developers" ), - KLocalizedString(), - "http://pim.kde.org/akonadi/" ); - aboutData.setProgramIconName( QLatin1String("akonadi") ); - aboutData.addAuthor( ki18n( "Jonathan Armond" ), ki18n( "Author" ), "jon.armond@gmail.com" ); - - KCmdLineArgs::init( argc, argv, &aboutData ); - KCmdLineOptions options; - options.add( "interactive", ki18n( "Show reporting dialog" ) ); - options.add( "interactive-on-change", ki18n( "Show report only if changes were made" ) ); - KCmdLineArgs::addCmdLineOptions( options ); - KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - - KApplication *app = new KApplication(); - app->setQuitOnLastWindowClosed( false ); - - KGlobal::setAllowQuit( true ); - KGlobal::locale()->insertCatalog( QLatin1String("libakonadi") ); - - if ( !Akonadi::Control::start( 0 ) ) - return 2; - - InfoDialog *infoDialog = 0; - if ( args->isSet( "interactive" ) || args->isSet( "interactive-on-change" ) ) { - infoDialog = new InfoDialog( args->isSet( "interactive-on-change" ) ); - infoDialog->show(); - } - - // Don't run the migration twice - // The second time, it would only copy kmailrc over kmail2rc and - // not migrate the accounts and folders again... - KConfigGroup migrationCfg( KGlobal::config(), "Migration" ); - const bool enabled = migrationCfg.readEntry( "Enabled", false ); - const int currentVersion = migrationCfg.readEntry( "Version", 0 ); - const int targetVersion = migrationCfg.readEntry( "TargetVersion", 1 ); - if ( !enabled || currentVersion >= targetVersion ) { - kWarning() << "Migration of kmailrc has already run, not running it again"; - return 4; - } - - KMailMigrator *migrator = new KMailMigrator; - if ( infoDialog && migrator ) { - infoDialog->migratorAdded(); - QObject::connect( migrator, SIGNAL(message(KMigratorBase::MessageType,QString)), - infoDialog, SLOT(message(KMigratorBase::MessageType,QString)) ); - QObject::connect( migrator, SIGNAL(destroyed()), infoDialog, SLOT(migratorDone()) ); - QObject::connect( migrator, SIGNAL(status(QString)), infoDialog, SLOT(status(QString)) ); - QObject::connect( migrator, SIGNAL(progress(int)), infoDialog, SLOT(progress(int)) ); - QObject::connect( migrator, SIGNAL(progress(int,int,int)), - infoDialog, SLOT(progress(int,int,int)) ); - } - args->clear(); - const int result = app->exec(); - if ( InfoDialog::hasError() ) - return 3; - - // if we have succeeded, update version information - migrationCfg.writeEntry( "Version", targetVersion ); - migrationCfg.sync(); - - return result; -} diff -Nru kdepim-runtime-4.14.6/migration/kmail/Messages.sh kdepim-runtime-15.08.0/migration/kmail/Messages.sh --- kdepim-runtime-4.14.6/migration/kmail/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -#!/bin/sh -$XGETTEXT ../*.cpp *.cpp *.h -o $podir/kmail-migrator.pot diff -Nru kdepim-runtime-4.14.6/migration/kmail/messagetag.trig kdepim-runtime-15.08.0/migration/kmail/messagetag.trig --- kdepim-runtime-4.14.6/migration/kmail/messagetag.trig 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/messagetag.trig 1970-01-01 00:00:00.000000000 +0000 @@ -1,102 +0,0 @@ -# -# Copyright (c) 2009 Sebastian Trueg -# All rights reserved, licensed under either CC-BY or BSD. -# -# You are free: -# * to Share - to copy, distribute and transmit the work -# * to Remix - to adapt the work -# Under the following conditions: -# * Attribution - You must attribute the work in the manner specified by the author -# or licensor (but not in any way that suggests that they endorse you or your use -# of the work). -# -# 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 the authors nor the names of contributors may -# be used to endorse or promote products derived from this ontology without -# specific prior written permission. -# -# THIS ONTOLOGY 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 ONTOLOGY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -@prefix nao: . -@prefix nfo: . -@prefix nie: . -@prefix rdfs: . -@prefix nrl: . -@prefix xsd: . -@prefix rdf: . -@prefix kmail: . - -kmail: { - kmail:priority - a rdf:Property ; - rdfs:label "priority" ; - rdfs:comment "A priority used by KMail to prioritize tags - mainly to sort the tags in the GUI." ; - rdfs:domain nao:Tag ; - rdfs:range xsd:integer . - - kmail:font - a rdf:Property ; - rdfs:label "font" ; - rdfs:comment "The font including point size and so on KMail uses to format email headers." ; - rdfs:domain nao:Tag ; - rdfs:range xsd:string . - - kmail:textColor - a rdf:Property ; - rdfs:label "text color" ; - rdfs:comment "String value (#RRGGBB) of the text color used by KMail to display email headers." ; - rdfs:domain nao:Tag ; - rdfs:range xsd:string . - - kmail:backgroundColor - a rdf:Property ; - rdfs:label "background color" ; - rdfs:comment "String value (#RRGGBB) of the background color used by KMail to display email headers." ; - rdfs:domain nao:Tag ; - rdfs:range xsd:string . - - kmail:shortcut - a rdf:Property ; - rdfs:label "shortcut" ; - rdfs:comment "The keyboard shortcut that triggers tagging with this tag." ; - rdfs:domain nao:Tag ; - rdfs:range xsd:string . - - kmail:inToolbar - a rdf:Property ; - rdfs:label "in toolbar" ; - rdfs:comment "Whether to show this tag in the toolbar of KMail." ; - rdfs:domain nao:Tag ; - rdfs:range xsd:boolean . -} - - { - kmail: - a nrl:Ontology ; - nao:hasDefaultNamespace "http://www.kde.org/kmail-ext#" ; - nao:hasDefaultNamespaceAbbreviation "kmail" ; - nao:lastModified "2010-01-08T14:59:09.500Z" ; - nao:status "Unstable" ; - nao:updatable "0 " ; - nao:version "0.1" . - - - a nrl:GraphMetadata ; - nrl:coreGraphMetadataFor kmail: . -} diff -Nru kdepim-runtime-4.14.6/migration/kmail/metatype.h kdepim-runtime-15.08.0/migration/kmail/metatype.h --- kdepim-runtime-4.14.6/migration/kmail/metatype.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/metatype.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -/* Copyright 2009 Thomas McGuire - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 POP3_METATYPE_H -#define POP3_METATYPE_H - -#include -#include - -#include - -Q_DECLARE_METATYPE(QList) - -#endif diff -Nru kdepim-runtime-4.14.6/migration/kmail/mixedtreeconverter.cpp kdepim-runtime-15.08.0/migration/kmail/mixedtreeconverter.cpp --- kdepim-runtime-4.14.6/migration/kmail/mixedtreeconverter.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/mixedtreeconverter.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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 "mixedtreeconverter.h" - -#include -#include -#include -#include - -MixedTreeConverter::MixedTreeConverter(QObject* parent): QObject(parent) -{ -} - -void MixedTreeConverter::convert(const QString& basePath) -{ - const KPIM::Maildir md( basePath, true ); - if ( !md.isValid() ) { - emit conversionDone( i18n( "'%1' is not a valid maildir folder.", basePath ) ); - return; - } - - convert( md ); - - emit conversionDone( QString() ); -} - -void MixedTreeConverter::convert(const KPIM::Maildir& md) -{ - kDebug() << md.path(); - if ( !md.isValid() ) - return; - - // recurse into maildirs, nothing to do there - foreach ( const QString &subFolder, md.subFolderList() ) { - kDebug() << subFolder; - convert( md.subFolder( subFolder ) ); - } - - // code from Maildir::subFolder minus the safety checks - QDir dir( md.path() ); - if ( !md.isRoot() ) { - dir.cdUp(); - const QString subDirPath = QString::fromLatin1( ".%1.directory" ).arg( md.name() ); - if ( dir.exists( subDirPath ) ) { - dir.cd( subDirPath ); - } else { - return; - } - } - - // look for mboxes - dir.setFilter( QDir::Files ); - foreach ( const QString &file, dir.entryList() ) { - convertMbox( dir.absolutePath() + QDir::separator() + file ); - - // recurse into mbox sub-folders - QDir subDir( dir ); - const QString subDirPath = QString::fromLatin1( ".%1.directory" ).arg( file ); - if ( subDir.exists( subDirPath ) ) - subDir.cd( subDirPath ); - else - continue; - convert( KPIM::Maildir( subDir.path(), true ) ); - } -} - -void MixedTreeConverter::convertMbox(const QString& path) -{ - kDebug() << path; - - // (0) check if this mbox has been converted before already - if ( path.endsWith( ".kmail-migrator-backup" ) ) - return; - - // (1) move mbox out of the way to make room for the maildir - const QString mboxBackupPath( path + ".kmail-migrator-backup" ); - if ( !QFile::rename( path, mboxBackupPath ) ) { - emit conversionDone( i18n( "Unable to move mbox file '%1' to backup location.", path ) ); - return; - } - - // (2) create the maildir that will contain the mbox content - KPIM::Maildir md( path ); - if ( !md.create() ) { - emit conversionDone( i18n( "Unable to create maildir folder at '%1'.", path ) ); - return; - } - - // (3) move messages from mbox to maildir - MBox mbox; - if ( !mbox.load( mboxBackupPath ) ) { - emit conversionDone( i18n( "Unable to open mbox file at '%1'.", mboxBackupPath ) ); - return; - } - foreach ( const MsgEntryInfo &entry, mbox.entryList() ) { - if ( md.addEntry( mbox.readRawEntry( entry.offset ) ).isEmpty() ) { - emit conversionDone( i18n( "Unable to add new message to maildir '%1'.", path ) ); - return; - } - } -} - - diff -Nru kdepim-runtime-4.14.6/migration/kmail/mixedtreeconverter.h kdepim-runtime-15.08.0/migration/kmail/mixedtreeconverter.h --- kdepim-runtime-4.14.6/migration/kmail/mixedtreeconverter.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/mixedtreeconverter.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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 MIXEDTREECONVERTER_H -#define MIXEDTREECONVERTER_H -#include - -namespace KPIM { - class Maildir; -} - -/** - Converts a mixed mbox/maildir tree to pure maildir -*/ -class MixedTreeConverter : public QObject -{ - Q_OBJECT - public: - explicit MixedTreeConverter( QObject *parent = 0 ); - - void convert( const QString &basePath ); - - signals: - void conversionDone( const QString &error ); - - private: - void convert( const KPIM::Maildir &md ); - void convertMbox( const QString &path ); -}; - -#endif diff -Nru kdepim-runtime-4.14.6/migration/kmail/subscriptionjob_p.h kdepim-runtime-15.08.0/migration/kmail/subscriptionjob_p.h --- kdepim-runtime-4.14.6/migration/kmail/subscriptionjob_p.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmail/subscriptionjob_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -/* - Copyright (c) 2007 Volker Krause - - 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_SUBSCRIPTIONJOB_P_H -#define AKONADI_SUBSCRIPTIONJOB_P_H - -#include -#include - -namespace Akonadi { - -class SubscriptionJobPrivate; - -/** - * @internal - * - * @short Job to manipulate the local subscription state of a set of collections. - */ -class AKONADI_EXPORT SubscriptionJob : public Job -{ - Q_OBJECT - public: - /** - * Creates a new subscription job. - * - * @param parent The parent object. - */ - explicit SubscriptionJob( QObject *parent = 0 ); - - /** - * Destroys the subscription job. - */ - ~SubscriptionJob(); - - /** - * Subscribes to the given list of collections. - * - * @param collections List of collections to subscribe to. - */ - void subscribe( const Collection::List &collections ); - - /** - * Unsubscribes from the given list of collections. - * - * @param collections List of collections to unsubscribe from. - */ - void unsubscribe( const Collection::List &collections ); - - protected: - void doStart(); - void doHandleResponse( const QByteArray &tag, const QByteArray &data ); - - private: - Q_DECLARE_PRIVATE( SubscriptionJob ) -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/migration/kmigratorbase.cpp kdepim-runtime-15.08.0/migration/kmigratorbase.cpp --- kdepim-runtime-4.14.6/migration/kmigratorbase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmigratorbase.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,120 +19,126 @@ #include "kmigratorbase.h" -#include -#include -#include +#include +#include +#include #include #include -#include #include -#include -#include +#include +#include #include #include #include #include +#include +#include +#include using namespace Akonadi; -namespace { +namespace +{ -QString messageTypeToString( KMigratorBase::MessageType type ) +QString messageTypeToString(KMigratorBase::MessageType type) { - switch ( type ) { - case KMigratorBase::Success: return QLatin1String( "Success" ); - case KMigratorBase::Skip: return QLatin1String( "Skipped" ); - case KMigratorBase::Info: return QLatin1String( "Info " ); - case KMigratorBase::Warning: return QLatin1String( "WARNING" ); - case KMigratorBase::Error: return QLatin1String( "ERROR " ); - } - Q_ASSERT( false ); - return QString(); + switch (type) { + case KMigratorBase::Success: return QStringLiteral("Success"); + case KMigratorBase::Skip: return QStringLiteral("Skipped"); + case KMigratorBase::Info: return QStringLiteral("Info "); + case KMigratorBase::Warning: return QStringLiteral("WARNING"); + case KMigratorBase::Error: return QStringLiteral("ERROR "); + } + Q_ASSERT(false); + return QString(); } } -KMigratorBase::KMigratorBase() : m_logFile( 0 ) +KMigratorBase::KMigratorBase() : m_logFile(0) { - KGlobal::ref(); - const QString logFileName = KStandardDirs::locateLocal( "data", KGlobal::mainComponent().componentName() + QLatin1String("/migration.log") ); - m_logFile = new QFile( logFileName ); - if ( !m_logFile->open( QFile::Append ) ) { - delete m_logFile; - m_logFile = 0; - kWarning() << "Unable to open log file: " << logFileName; - } - logMessage( Info, QLatin1String("Starting migration...") ); - connect( this, SIGNAL(message(KMigratorBase::MessageType,QString)), SLOT(logMessage(KMigratorBase::MessageType,QString)) ); + const QString logFileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + KGlobal::mainComponent().componentName() + QLatin1String("/migration.log") ; + QFileInfo fileInfo(logFileName); + QDir().mkpath(fileInfo.absolutePath()); + + m_logFile = new QFile(logFileName); + if (!m_logFile->open(QFile::Append)) { + delete m_logFile; + m_logFile = 0; + qWarning() << "Unable to open log file: " << logFileName; + } + logMessage(Info, QStringLiteral("Starting migration...")); + connect(this, &KMigratorBase::message, this, &KMigratorBase::logMessage); - // load the vtable before we continue - QTimer::singleShot( 0, this, SLOT(migrate()) ); + // load the vtable before we continue + QTimer::singleShot(0, this, SLOT(migrate())); } KMigratorBase::~KMigratorBase() { - logMessage( Info, QLatin1String("Migration finished.") ); - delete m_logFile; - KGlobal::deref(); -} - -KMigratorBase::MigrationState KMigratorBase::migrationState( const QString &identifier ) const -{ - KConfigGroup cfg( KGlobal::config(), QLatin1String("Resource ") + identifier ); - QMetaEnum e = metaObject()->enumerator( metaObject()->indexOfEnumerator( "MigrationState" ) ); - const QString s = cfg.readEntry( "MigrationState", e.valueToKey( None ) ); - MigrationState state = (MigrationState)e.keyToValue( s.toLatin1() ); - - if ( state != None ) { - const QString resId = cfg.readEntry( "ResourceIdentifier", "" ); - // previously migrated but removed again - if ( !AgentManager::self()->instance( resId ).isValid() ) - state = None; - } - - return state; -} - -void KMigratorBase::setMigrationState( const QString &identifier, MigrationState state, - const QString &resId, const QString &type ) -{ - KConfigGroup cfg( KGlobal::config(), QLatin1String("Resource ") + identifier ); - QMetaEnum e = metaObject()->enumerator( metaObject()->indexOfEnumerator( "MigrationState" ) ); - const QString stateStr = QLatin1String(e.valueToKey( state )); - cfg.writeEntry( "MigrationState", stateStr ); - cfg.writeEntry( "ResourceIdentifier", resId ); - cfg.sync(); - - cfg = KConfigGroup( KGlobal::config(), "Bridged" ); - QStringList bridgedResources = cfg.readEntry( type + QLatin1String("Resources"), QStringList() ); - if ( state == Bridged ) { - if ( !bridgedResources.contains( identifier ) ) - bridgedResources << identifier; - } else { - bridgedResources.removeAll( identifier ); - } - cfg.writeEntry( type + QLatin1String("Resources"), bridgedResources ); - cfg.sync(); -} - -KJob *KMigratorBase::createAgentInstance(const QString& typeId, QObject* receiver, const char* slot) -{ - emit message( Info, i18n( "Creating instance of type %1", typeId ) ); - AgentInstanceCreateJob *job = new AgentInstanceCreateJob( typeId, this ); - connect( job, SIGNAL(result(KJob*)), receiver, slot ); - job->start(); - return job; -} - -void KMigratorBase::logMessage(KMigratorBase::MessageType type, const QString& msg) -{ - if ( m_logFile ) { - m_logFile->write( QString( QLatin1Char( '[' ) + QDateTime::currentDateTime().toString() + QLatin1String( "] " ) - + messageTypeToString( type ) + QLatin1String( ": " ) + msg + QLatin1Char( '\n' ) ).toUtf8() ); - m_logFile->flush(); - } + logMessage(Info, QStringLiteral("Migration finished.")); + delete m_logFile; +} + +KMigratorBase::MigrationState KMigratorBase::migrationState(const QString &identifier) const +{ + KConfigGroup cfg(KSharedConfig::openConfig(), QStringLiteral("Resource ") + identifier); + QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("MigrationState")); + const QString s = cfg.readEntry("MigrationState", e.valueToKey(None)); + MigrationState state = (MigrationState)e.keyToValue(s.toLatin1()); + + if (state != None) { + const QString resId = cfg.readEntry("ResourceIdentifier", ""); + // previously migrated but removed again + if (!AgentManager::self()->instance(resId).isValid()) { + state = None; + } + } + + return state; +} + +void KMigratorBase::setMigrationState(const QString &identifier, MigrationState state, + const QString &resId, const QString &type) +{ + KConfigGroup cfg(KSharedConfig::openConfig(), QStringLiteral("Resource ") + identifier); + QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("MigrationState")); + const QString stateStr = QLatin1String(e.valueToKey(state)); + cfg.writeEntry("MigrationState", stateStr); + cfg.writeEntry("ResourceIdentifier", resId); + cfg.sync(); + + cfg = KConfigGroup(KSharedConfig::openConfig(), "Bridged"); + QStringList bridgedResources = cfg.readEntry(type + QLatin1String("Resources"), QStringList()); + if (state == Bridged) { + if (!bridgedResources.contains(identifier)) { + bridgedResources << identifier; + } + } else { + bridgedResources.removeAll(identifier); + } + cfg.writeEntry(type + QLatin1String("Resources"), bridgedResources); + cfg.sync(); +} + +KJob *KMigratorBase::createAgentInstance(const QString &typeId, QObject *receiver, const char *slot) +{ + Q_EMIT message(Info, i18n("Creating instance of type %1", typeId)); + AgentInstanceCreateJob *job = new AgentInstanceCreateJob(typeId, this); + connect(job, SIGNAL(result(KJob*)), receiver, slot); + job->start(); + return job; +} + +void KMigratorBase::logMessage(KMigratorBase::MessageType type, const QString &msg) +{ + if (m_logFile) { + m_logFile->write(QString(QLatin1Char('[') + QDateTime::currentDateTime().toString() + QLatin1String("] ") + + messageTypeToString(type) + QLatin1String(": ") + msg + QLatin1Char('\n')).toUtf8()); + m_logFile->flush(); + } } diff -Nru kdepim-runtime-4.14.6/migration/kmigratorbase.h kdepim-runtime-15.08.0/migration/kmigratorbase.h --- kdepim-runtime-4.14.6/migration/kmigratorbase.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kmigratorbase.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,8 +20,8 @@ #ifndef KMIGRATORBASE_H #define KMIGRATORBASE_H -#include - +#include +#include #include class QFile; @@ -32,61 +32,62 @@ */ class KMigratorBase : public QObject { - Q_OBJECT - public: + Q_OBJECT +public: enum MigrationState { - None, - Bridged, - Complete + None, + Bridged, + Complete }; enum MessageType { - Success, - Skip, - Info, - Warning, - Error + Success, + Skip, + Info, + Warning, + Error }; - Q_ENUMS( MigrationState ) + Q_ENUMS(MigrationState) KMigratorBase(); virtual ~KMigratorBase(); /** * Read resource migration state. - * + * * @return MigrationState and None if the resource with @param identifier as identifier is not available. */ - MigrationState migrationState( const QString &identifier ) const; + MigrationState migrationState(const QString &identifier) const; /** * Set resource migration state. - * + * * Persists migration state in the resource config. * @param resId and @param state is registered under @param identifier. * Additionally all bridged resources are registered in the @param type and @param identifier. */ - void setMigrationState( const QString &identifier, MigrationState state, - const QString &resId, const QString &type ); + void setMigrationState(const QString &identifier, MigrationState state, + const QString &resId, const QString &type); virtual void migrateNext() = 0; - protected: - KJob *createAgentInstance( const QString &typeId, QObject *receiver, const char* slot ); - virtual void migrationFailed( const QString &errorMsg, const Akonadi::AgentInstance &instance - = Akonadi::AgentInstance() ) = 0; +protected: + KJob *createAgentInstance(const QString &typeId, QObject *receiver, const char *slot); + virtual void migrationFailed(const QString &errorMsg, const Akonadi::AgentInstance &instance + = Akonadi::AgentInstance()) = 0; - signals: - void message( KMigratorBase::MessageType type, const QString &msg ); +Q_SIGNALS: + void message(KMigratorBase::MessageType type, const QString &msg); - protected slots: +protected Q_SLOTS: virtual void migrate() = 0; - private slots: - void logMessage( KMigratorBase::MessageType type, const QString &msg ); +private Q_SLOTS: + void logMessage(KMigratorBase::MessageType type, const QString &msg); - private: - QFile* m_logFile; +private: + QFile *m_logFile; + QEventLoopLocker eventLoopLocker; }; #endif diff -Nru kdepim-runtime-4.14.6/migration/knotes/CMakeLists.txt kdepim-runtime-15.08.0/migration/knotes/CMakeLists.txt --- kdepim-runtime-4.14.6/migration/knotes/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ - -set(knotes-migrator_srcs - main.cpp - knotesmigrator.cpp - notelockattribute.cpp - knotesmigratorconfig.cpp - notealarmattribute.cpp - notedisplayattribute.cpp - showfoldernotesattribute.cpp - ${MIGRATION_AKONADI_SHARED_SOURCES} -) - -kde4_add_kcfg_files(knotes-migrator_srcs knoteconfig.kcfgc) - -macro(add_resource_iface _kcfgFile _ifaceName _className) - kcfg_generate_dbus_interface(${kdepim-runtime_SOURCE_DIR}/resources/${_kcfgFile} ${_ifaceName}) - string(TOLOWER ${_className} _codeFile) - qt4_add_dbus_interface(knotes-migrator_srcs - ${CMAKE_CURRENT_BINARY_DIR}/${_ifaceName}.xml ${_codeFile} ${_className} - ) -endmacro() - -add_resource_iface( maildir/maildirresource.kcfg org.kde.Akonadi.Maildir.Settings MaildirSettings ) - -kde4_add_executable(knotes-migrator ${knotes-migrator_srcs}) - -target_link_libraries(knotes-migrator - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KABC_LIBS} - ${KDEPIMLIBS_KCAL_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${KDE4_KDECORE_LIBS} - ${QT_QTGUI_LIBRARY} -) - -install(TARGETS knotes-migrator ${INSTALL_TARGETS_DEFAULT_ARGS}) -#install(FILES knotes-migratorrc DESTINATION ${CONFIG_INSTALL_DIR}) diff -Nru kdepim-runtime-4.14.6/migration/knotes/knoteconfig.kcfg kdepim-runtime-15.08.0/migration/knotes/knoteconfig.kcfg --- kdepim-runtime-4.14.6/migration/knotes/knoteconfig.kcfg 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/knoteconfig.kcfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ - - - kglobalsettings.h - - - - - Qt::yellow - - - - Qt::black - - - - 300 - - - - 300 - - - - true - - - - - - KGlobalSettings::generalFont() - - - - KGlobalSettings::windowTitleFont() - - - - true - - - - false - - - - 4 - - - - false - - - - - - - - - - - - -10 - - - - false - - - - QPoint( -10000, -10000 ) - - - - false - - - - false - - - - false - - - diff -Nru kdepim-runtime-4.14.6/migration/knotes/knoteconfig.kcfgc kdepim-runtime-15.08.0/migration/knotes/knoteconfig.kcfgc --- kdepim-runtime-4.14.6/migration/knotes/knoteconfig.kcfgc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/knoteconfig.kcfgc 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -File=knoteconfig.kcfg -ClassName=KNoteConfig -Mutators=true diff -Nru kdepim-runtime-4.14.6/migration/knotes/knotesmigratorconfig.cpp kdepim-runtime-15.08.0/migration/knotes/knotesmigratorconfig.cpp --- kdepim-runtime-4.14.6/migration/knotes/knotesmigratorconfig.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/knotesmigratorconfig.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -/* - Copyright (c) 2013-2015 Montel Laurent - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "knotesmigratorconfig.h" -#include "knoteconfig.h" - -#include -#include - -#include -using namespace KCal; - -KNotesMigratorConfig::KNotesMigratorConfig(KCal::Journal *journal) - : mJournal(journal), - mConfig(0) -{ - const QString configPath = KGlobal::dirs()->saveLocation( "data", QLatin1String("knotes/") ) + QLatin1String("notes/") + journal->uid(); - if (!configPath.isEmpty()) { - mConfig = new KNoteConfig( KSharedConfig::openConfig( configPath, KConfig::NoGlobals ) ); - mConfig->readConfig(); - } -} - -KNotesMigratorConfig::~KNotesMigratorConfig() -{ - delete mConfig; -} - -bool KNotesMigratorConfig::readOnly() const -{ - if (mConfig) - return mConfig->readOnly(); - return false; -} - -KNoteConfig *KNotesMigratorConfig::noteConfig() -{ - return mConfig; -} diff -Nru kdepim-runtime-4.14.6/migration/knotes/knotesmigratorconfig.h kdepim-runtime-15.08.0/migration/knotes/knotesmigratorconfig.h --- kdepim-runtime-4.14.6/migration/knotes/knotesmigratorconfig.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/knotesmigratorconfig.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -/* - Copyright (c) 2013-2015 Montel Laurent - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef KNOTESMIGRATORCONFIG_H -#define KNOTESMIGRATORCONFIG_H - -namespace KCal { -class Journal; -} -class KNoteConfig; -class KNotesMigratorConfig -{ -public: - KNotesMigratorConfig(KCal::Journal *journal); - ~KNotesMigratorConfig(); - - bool readOnly() const; - KNoteConfig *noteConfig(); -private: - KCal::Journal *mJournal; - KNoteConfig *mConfig; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/migration/knotes/knotesmigrator.cpp kdepim-runtime-15.08.0/migration/knotes/knotesmigrator.cpp --- kdepim-runtime-4.14.6/migration/knotes/knotesmigrator.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/knotesmigrator.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,273 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - Copyright (c) 2013-2015 Laurent Montel - - 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 "knotesmigrator.h" -#include "notelockattribute.h" -#include "notealarmattribute.h" -#include "notedisplayattribute.h" -#include "showfoldernotesattribute.h" -#include "knotesmigratorconfig.h" -#include "knoteconfig.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "entitytreecreatejob.h" -#include - -#include -#include -#include "maildirsettings.h" -#include - - -using namespace Akonadi; - -KNotesMigrator::KNotesMigrator() : - KMigratorBase(), mIndexResource(-1), m_notesResource( 0 ) -{ - Akonadi::AttributeFactory::registerAttribute(); - Akonadi::AttributeFactory::registerAttribute(); - Akonadi::AttributeFactory::registerAttribute(); - Akonadi::AttributeFactory::registerAttribute(); - const QString kresCfgFile = KStandardDirs::locateLocal( "config", QLatin1String( "kresources/notes/stdrc" ) ); - mConfig = new KConfig( kresCfgFile ); - const KConfigGroup generalGroup( mConfig, QLatin1String( "General" ) ); - mUnknownTypeResources = generalGroup.readEntry( QLatin1String( "ResourceKeys" ), QStringList() ); - m_notesResource = new KCal::CalendarLocal( QString() ); -} - -KNotesMigrator::~KNotesMigrator() -{ - delete m_notesResource; - delete mConfig; -} - -void KNotesMigrator::migrate() -{ - emit message( Info, i18n( "Beginning KNotes migration..." ) ); - migrateNext(); -} - -void KNotesMigrator::migrateNext() -{ - ++mIndexResource; - - if (mUnknownTypeResources.isEmpty() || mIndexResource >= mUnknownTypeResources.count()) { - emit message( Info, i18n( "KNotes migration finished" ) ); - deleteLater(); - return; - } - - const KConfigGroup kresCfgGroup( mConfig, QString::fromLatin1( "Resource_%1" ).arg( mUnknownTypeResources.at(mIndexResource) ) ); - const QString resourceType = kresCfgGroup.readEntry( QLatin1String( "ResourceType" ), QString() ); - if (resourceType == QLatin1String("file")) { - createAgentInstance( QLatin1String("akonadi_akonotes_resource"), this, SLOT(notesResourceCreated(KJob*)) ); - } else { - migrateNext(); - } -} - -void KNotesMigrator::notesResourceCreated(KJob * job) -{ - if ( job->error() ) { - migrationFailed( i18n( "Failed to create resource: %1", job->errorText() ) ); - migrateNext(); - return; - } - - const KConfigGroup kresCfgGroup( mConfig, QString::fromLatin1( "Resource_%1" ).arg( mUnknownTypeResources.at(mIndexResource) ) ); - - m_agentInstance = static_cast( job )->instance(); - m_agentInstance.setName( kresCfgGroup.readEntry( "ResourceName", "Migrated Notes" ) ); - - const QString resourcePath = kresCfgGroup.readEntry( "NotesURL" ); - KUrl url( resourcePath ); - - if ( !QFile::exists( url.toLocalFile() ) ) { - migrateNext(); - return; - } - - - const bool success = m_notesResource->load( url.toLocalFile() ); - if ( !success ) { - migrationFailed( i18n( "Failed to open file for reading: %1" , resourcePath ) ); - migrateNext(); - return; - } - - OrgKdeAkonadiMaildirSettingsInterface *iface = new OrgKdeAkonadiMaildirSettingsInterface( - QLatin1String("org.freedesktop.Akonadi.Resource.") + m_agentInstance.identifier(), - QLatin1String("/Settings"), QDBusConnection::sessionBus(), this ); - - if ( !iface->isValid() ) { - migrationFailed( i18n( "Failed to obtain D-Bus interface for remote configuration." ), m_agentInstance ); - delete iface; - migrateNext(); - return; - } - const bool isReadOnly = kresCfgGroup.readEntry("ResourceIsReadOnly", false); - iface->setReadOnly( isReadOnly ); - - QDBusPendingReply response = iface->setPath( KGlobal::dirs()->localxdgdatadir() + QLatin1String("/notes/") + KRandom::randomString( 10 ) ); - - // make sure the config is saved - iface->writeConfig(); - - m_agentInstance.reconfigure(); - - ResourceSynchronizationJob *syncJob = new ResourceSynchronizationJob( m_agentInstance, this ); - connect( syncJob, SIGNAL(result(KJob*)), SLOT(syncDone(KJob*))); - syncJob->start(); -} - -void KNotesMigrator::syncDone(KJob *job) -{ - Q_UNUSED( job ); - emit message( Info, i18n( "Instance \"%1\" synchronized" , m_agentInstance.identifier() ) ); - - CollectionFetchJob *collectionFetchJob = new CollectionFetchJob( Collection::root(), CollectionFetchJob::FirstLevel, this ); - connect( collectionFetchJob, SIGNAL(collectionsReceived(Akonadi::Collection::List)), SLOT(rootCollectionsRecieved(Akonadi::Collection::List)) ); - connect( collectionFetchJob, SIGNAL(result(KJob*)), SLOT(rootFetchFinished(KJob*)) ); -} - -void KNotesMigrator::rootFetchFinished( KJob *job ) -{ - emit message( Info, i18n( "Root fetch finished" ) ); - if ( job->error() ) { - emit message( Error, i18nc( "A job to fetch akonadi resources failed. %1 is the error string.", "Fetching resources failed: %1" , job->errorString() ) ); - } -} - -void KNotesMigrator::rootCollectionsRecieved( const Akonadi::Collection::List &list ) -{ - emit message( Info, i18n( "Received root collections" ) ); - foreach ( const Collection &collection, list ) { - if ( collection.resource() == m_agentInstance.identifier() ) { - m_resourceCollection = collection; - startMigration(); - return; - } - } - emit message( Error, i18n( "Could not find root collection for resource \"%1\"" ,m_agentInstance.identifier() ) ); - migrateNext(); -} - -void KNotesMigrator::startMigration() -{ - KCal::Journal::List oldNotesList = m_notesResource->rawJournals(); - Akonadi::Item::List newItemsList; - KConfig config(QLatin1String("globalnotesettings")); - KConfigGroup grp = config.group(QLatin1String("SelectNoteFolder")); - grp.writeEntry("DefaultFolder", m_resourceCollection.id()); - config.sync(); - - emit message( Info, i18np( "Starting migration of %1 note", "Starting migration of %1 notes", oldNotesList.size() ) ); - - foreach ( KCal::Journal *journal, oldNotesList ) { - Item newItem; - newItem.setMimeType( QLatin1String("text/x-vnd.akonadi.note") ); - newItem.setParentCollection( m_resourceCollection ); - KMime::Message::Ptr note( new KMime::Message() ); - - QByteArray encoding( "utf-8" ); - note->subject( true )->fromUnicodeString( journal->summary(), encoding ); - note->mainBodyPart()->fromUnicodeString( journal->description() ); - note->contentType( true )->setMimeType( journal->descriptionIsRich() ? "text/html" : "text/plain" ); - - note->assemble(); - KNotesMigratorConfig *config = new KNotesMigratorConfig(journal); - if (config) { - - if (config->readOnly()) { - newItem.addAttribute( new NoteLockAttribute() ); - } - - //Position/Editor/Color etc. - NoteDisplayAttribute *displayAttribute = new NoteDisplayAttribute(); - displayAttribute->setBackgroundColor(config->noteConfig()->bgColor()); - displayAttribute->setForegroundColor(config->noteConfig()->fgColor()); - displayAttribute->setSize(QSize(config->noteConfig()->width(), config->noteConfig()->height())); - displayAttribute->setRememberDesktop(config->noteConfig()->rememberDesktop()); - displayAttribute->setTabSize(config->noteConfig()->tabSize()); - displayAttribute->setFont(config->noteConfig()->font()); - displayAttribute->setTitleFont(config->noteConfig()->titleFont()); - displayAttribute->setDesktop(config->noteConfig()->desktop()); - displayAttribute->setIsHidden(config->noteConfig()->hideNote()); - displayAttribute->setPosition(config->noteConfig()->position()); - displayAttribute->setShowInTaskbar(config->noteConfig()->showInTaskbar()); - displayAttribute->setKeepAbove(config->noteConfig()->keepAbove()); - displayAttribute->setKeepBelow(config->noteConfig()->keepBelow()); - displayAttribute->setAutoIndent(config->noteConfig()->autoIndent()); - newItem.addAttribute( displayAttribute ); - delete config; - } - - //Alarm. - //In note we have an unique alarm. - if (!journal->alarms().isEmpty()) { - KCal::Alarm *alarm = journal->alarms().first(); - if (alarm->hasTime()) { - NoteAlarmAttribute *alarmAttribute = new NoteAlarmAttribute; - alarmAttribute->setDateTime(alarm->time()); - newItem.addAttribute( alarmAttribute ); - } - } - newItem.setPayload( note ); - newItemsList.append( newItem ); - } - - EntityTreeCreateJob *createJob = new EntityTreeCreateJob( QList(), newItemsList,this ); - connect(createJob, SIGNAL(result(KJob*)), SLOT(newResourceFilled(KJob*))); -} - -void KNotesMigrator::newResourceFilled(KJob* job) -{ - Q_UNUSED( job ); - showDefaultCollection(); -} - -void KNotesMigrator::showDefaultCollection() -{ - ShowFolderNotesAttribute *attribute = m_resourceCollection.attribute( Akonadi::Collection::AddIfMissing ); - Q_UNUSED(attribute); - Akonadi::CollectionModifyJob *job = new Akonadi::CollectionModifyJob( m_resourceCollection ); - connect(job, SIGNAL(result(KJob*)), SLOT(slotCollectionModify(KJob*))); -} - -void KNotesMigrator::slotCollectionModify(KJob* job) -{ - Q_UNUSED( job ); - migrateNext(); -} - -void KNotesMigrator::migrationFailed( const QString& errorMsg, const Akonadi::AgentInstance& instance ) -{ - Q_UNUSED( instance ) - emit message( Error, i18n( "Migration failed: %1" ,errorMsg ) ); -} - diff -Nru kdepim-runtime-4.14.6/migration/knotes/knotesmigrator.h kdepim-runtime-15.08.0/migration/knotes/knotesmigrator.h --- kdepim-runtime-4.14.6/migration/knotes/knotesmigrator.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/knotesmigrator.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - Copyright (c) 2010 Stephen Kelly - Copyright (c) 2013-2015 Laurent Montel - - 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 KNOTESMIGRATOR_H -#define KNOTESMIGRATOR_H - -#include "kmigratorbase.h" -#include -#include -#include - -#include - -#include - -class KJob; - -/** - * Migrate KNotes resources to Akonadi - */ -class KNotesMigrator : public KMigratorBase -{ - Q_OBJECT -public: - KNotesMigrator(); - ~KNotesMigrator(); - - /* reimp */ void migrate(); - /* reimp */ void migrateNext(); -protected: - /* reimp */ void migrationFailed( const QString& errorMsg, const Akonadi::AgentInstance& instance = Akonadi::AgentInstance() ); - -private slots: - void notesResourceCreated( KJob* job ); - void syncDone(KJob *job); - void rootFetchFinished( KJob *job ); - void rootCollectionsRecieved( const Akonadi::Collection::List &list ); - void newResourceFilled( KJob *job ); - void slotCollectionModify(KJob *job); - -private: - void startMigration(); - void showDefaultCollection(); - -private: - int mIndexResource; - QStringList mUnknownTypeResources; - Akonadi::Collection m_resourceCollection; - Akonadi::AgentInstance m_agentInstance; - - KCal::CalendarLocal *m_notesResource; - KConfig *mConfig; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/migration/knotes/main.cpp kdepim-runtime-15.08.0/migration/knotes/main.cpp --- kdepim-runtime-4.14.6/migration/knotes/main.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -/* - Copyright (c) 2013-2015 Montel Laurent - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "knotesmigrator.h" - -#include "infodialog.h" - -#include - -#include -#include -#include -#include -#include - -int main( int argc, char **argv ) -{ - KAboutData aboutData( "knotesmigrator", 0, - ki18n( "KNotes Migration Tool" ), - "0.1", - ki18n( "Migration of KNotes notes to Akonadi" ), - KAboutData::License_LGPL, - ki18n( "(c) 2013 the Akonadi developers" ), - KLocalizedString(), - "http://pim.kde.org/akonadi/" ); - aboutData.setProgramIconName( QLatin1String("akonadi") ); - aboutData.addAuthor( ki18n( "Laurent Montel" ), ki18n( "Author" ), "montel@kde.org" ); - - KCmdLineArgs::init( argc, argv, &aboutData ); - KCmdLineOptions options; - options.add( "interactive", ki18n( "Show reporting dialog" ) ); - options.add( "interactive-on-change", ki18n( "Show report only if changes were made" ) ); - KCmdLineArgs::addCmdLineOptions( options ); - KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - - KApplication *app = new KApplication(); - app->setQuitOnLastWindowClosed( false ); - - KGlobal::setAllowQuit( true ); - KGlobal::locale()->insertCatalog( QLatin1String("libakonadi") ); - - if ( !Akonadi::Control::start( 0 ) ) - return 2; - - InfoDialog *infoDialog = 0; - if ( args->isSet( "interactive" ) || args->isSet( "interactive-on-change" ) ) { - infoDialog = new InfoDialog( args->isSet( "interactive-on-change" ) ); - infoDialog->show(); - } - args->clear(); - - KNotesMigrator *migrator = new KNotesMigrator; - if ( infoDialog && migrator ) { - infoDialog->migratorAdded(); - QObject::connect( migrator, SIGNAL(message(KMigratorBase::MessageType,QString)), - infoDialog, SLOT(message(KMigratorBase::MessageType,QString)) ); - QObject::connect( migrator, SIGNAL(destroyed()), infoDialog, SLOT(migratorDone()) ); - } - - const int result = app->exec(); - if ( InfoDialog::hasError() ) - return 3; - return result; -} diff -Nru kdepim-runtime-4.14.6/migration/knotes/Messages.sh kdepim-runtime-15.08.0/migration/knotes/Messages.sh --- kdepim-runtime-4.14.6/migration/knotes/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -#!/bin/sh -$XGETTEXT ../*.cpp *.cpp -o $podir/knotes-migrator.pot diff -Nru kdepim-runtime-4.14.6/migration/knotes/notealarmattribute.cpp kdepim-runtime-15.08.0/migration/knotes/notealarmattribute.cpp --- kdepim-runtime-4.14.6/migration/knotes/notealarmattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/notealarmattribute.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -/* - Copyright (c) 2013-2015 Montel Laurent - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "notealarmattribute.h" - -#include - -NoteAlarmAttribute::NoteAlarmAttribute() - : Akonadi::Attribute() -{ - -} - -NoteAlarmAttribute::~NoteAlarmAttribute() -{ - -} - -NoteAlarmAttribute* NoteAlarmAttribute::clone() const -{ - NoteAlarmAttribute *attr = new NoteAlarmAttribute(); - attr->setDateTime(dateTime()); - return attr; -} - -void NoteAlarmAttribute::deserialize(const QByteArray& data) -{ - QDataStream s( data ); - s >> mDateTime; -} - -QByteArray NoteAlarmAttribute::serialized() const -{ - QByteArray result; - QDataStream s( &result, QIODevice::WriteOnly ); - s << mDateTime; - return result; -} - -QByteArray NoteAlarmAttribute::type() const -{ - static const QByteArray sType( "NoteAlarmAttribute" ); - return sType; -} - -void NoteAlarmAttribute::setDateTime(const KDateTime &dateTime) -{ - mDateTime = dateTime; -} - -KDateTime NoteAlarmAttribute::dateTime() const -{ - return mDateTime; -} - - diff -Nru kdepim-runtime-4.14.6/migration/knotes/notealarmattribute.h kdepim-runtime-15.08.0/migration/knotes/notealarmattribute.h --- kdepim-runtime-4.14.6/migration/knotes/notealarmattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/notealarmattribute.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -/* - Copyright (c) 2013-2015 Montel Laurent - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef NOTE_ALARM_ATTRIBUTE_H -#define NOTE_ALARM_ATTRIBUTE_H - -#include - -#include - -class NoteAlarmAttribute : public Akonadi::Attribute -{ -public: - NoteAlarmAttribute(); - ~NoteAlarmAttribute(); - - QByteArray type() const; - - NoteAlarmAttribute* clone() const; - - QByteArray serialized() const; - - void deserialize( const QByteArray &data ); - - void setDateTime(const KDateTime &dateTime); - KDateTime dateTime() const; - -private: - KDateTime mDateTime; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/migration/knotes/notedisplayattribute.cpp kdepim-runtime-15.08.0/migration/knotes/notedisplayattribute.cpp --- kdepim-runtime-4.14.6/migration/knotes/notedisplayattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/notedisplayattribute.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,256 +0,0 @@ -/* - Copyright (c) 2013-2015 Montel Laurent - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#include "notedisplayattribute.h" - -#include - -#include - - -NoteDisplayAttribute::NoteDisplayAttribute() - : Akonadi::Attribute(), - mFont(KGlobalSettings::generalFont()), - mTitleFont(KGlobalSettings::windowTitleFont()), - mBackgroundColor(Qt::yellow), - mForegroundgroundColor(Qt::black), - mSize(300,300), - mPosition(QPoint( -10000, -10000 )), - mTabSize(4), - mDesktop(-10), - mRememberDesktop(true), - mAutoIndent(true), - mHide(false), - mShowInTaskbar(false), - mKeepAbove(false), - mKeepBelove(false), - mKeepBelow(false) -{ - -} - -NoteDisplayAttribute::~NoteDisplayAttribute() -{ - -} - -NoteDisplayAttribute* NoteDisplayAttribute::clone() const -{ - NoteDisplayAttribute *attr = new NoteDisplayAttribute(); - attr->setBackgroundColor(backgroundColor()); - attr->setForegroundColor(foregroundColor()); - attr->setSize(size()); - attr->setRememberDesktop(rememberDesktop()); - attr->setTabSize(tabSize()); - attr->setFont(font()); - attr->setTitleFont(titleFont()); - attr->setDesktop(desktop()); - attr->setIsHidden(isHidden()); - attr->setPosition(position()); - attr->setShowInTaskbar(showInTaskbar()); - attr->setKeepAbove(keepAbove()); - attr->setKeepBelow(keepBelow()); - attr->setAutoIndent(autoIndent()); - return attr; -} - -void NoteDisplayAttribute::deserialize(const QByteArray& data) -{ - QDataStream s( data ); - s >> mFont; - s >> mTitleFont; - s >> mBackgroundColor; - s >> mForegroundgroundColor; - s >> mSize; - s >> mPosition; - s >> mTabSize; - s >> mDesktop; - s >> mRememberDesktop; - s >> mAutoIndent; - s >> mHide; - s >> mShowInTaskbar; - s >> mKeepAbove; - s >> mKeepBelove; - s >> mKeepBelow; -} - -QByteArray NoteDisplayAttribute::serialized() const -{ - QByteArray result; - QDataStream s( &result, QIODevice::WriteOnly ); - s << mFont; - s << mTitleFont; - s << mBackgroundColor; - s << mForegroundgroundColor; - s << mSize; - s << mPosition; - s << mTabSize; - s << mDesktop; - s << mRememberDesktop; - s << mAutoIndent; - s << mHide; - s << mShowInTaskbar; - s << mKeepAbove; - s << mKeepBelove; - s << mKeepBelow; - return result; -} - -QByteArray NoteDisplayAttribute::type() const -{ - static const QByteArray sType( "NoteDisplayAttribute" ); - return sType; -} - -void NoteDisplayAttribute::setBackgroundColor(const QColor &color) -{ - mBackgroundColor = color; -} - -QColor NoteDisplayAttribute::backgroundColor() const -{ - return mBackgroundColor; -} - -void NoteDisplayAttribute::setForegroundColor(const QColor &color) -{ - mForegroundgroundColor = color; -} - -QSize NoteDisplayAttribute::size() const -{ - return mSize; -} - -void NoteDisplayAttribute::setSize(const QSize &size) -{ - mSize = size; -} - -QColor NoteDisplayAttribute::foregroundColor() const -{ - return mForegroundgroundColor; -} - -bool NoteDisplayAttribute::rememberDesktop() const -{ - return mRememberDesktop; -} - -void NoteDisplayAttribute::setRememberDesktop(bool b) -{ - mRememberDesktop = b; -} - -int NoteDisplayAttribute::tabSize() const -{ - return mTabSize; -} - -void NoteDisplayAttribute::setTabSize(int value) -{ - mTabSize = value; -} - -bool NoteDisplayAttribute::autoIndent() const -{ - return mAutoIndent; -} - -void NoteDisplayAttribute::setAutoIndent(bool b) -{ - mAutoIndent = b; -} - -void NoteDisplayAttribute::setFont(const QFont &f) -{ - mFont = f; -} - -QFont NoteDisplayAttribute::font() const -{ - return mFont; -} - -void NoteDisplayAttribute::setTitleFont(const QFont &f) -{ - mTitleFont = f; -} - -QFont NoteDisplayAttribute::titleFont() const -{ - return mTitleFont; -} - -void NoteDisplayAttribute::setDesktop(int v) -{ - mDesktop = v; -} - -int NoteDisplayAttribute::desktop() const -{ - return mDesktop; -} - -void NoteDisplayAttribute::setIsHidden(bool b) -{ - mHide = b; -} - -bool NoteDisplayAttribute::isHidden() const -{ - return mHide; -} - -void NoteDisplayAttribute::setPosition(const QPoint &pos) -{ - mPosition = pos; -} - -QPoint NoteDisplayAttribute::position() const -{ - return mPosition; -} - -void NoteDisplayAttribute::setShowInTaskbar(bool b) -{ - mShowInTaskbar = b; -} - -bool NoteDisplayAttribute::showInTaskbar() const -{ - return mShowInTaskbar; -} - -void NoteDisplayAttribute::setKeepAbove(bool b) -{ - mKeepAbove = b; -} - -bool NoteDisplayAttribute::keepAbove() const -{ - return mKeepAbove; -} - -void NoteDisplayAttribute::setKeepBelow(bool b) -{ - mKeepBelow = b; -} - -bool NoteDisplayAttribute::keepBelow() const -{ - return mKeepBelow; -} diff -Nru kdepim-runtime-4.14.6/migration/knotes/notedisplayattribute.h kdepim-runtime-15.08.0/migration/knotes/notedisplayattribute.h --- kdepim-runtime-4.14.6/migration/knotes/notedisplayattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/notedisplayattribute.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,94 +0,0 @@ -/* - Copyright (c) 2013-2015 Montel Laurent - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef NOTE_DISPLAY_ATTRIBUTE_H -#define NOTE_DISPLAY_ATTRIBUTE_H - -#include - -#include -#include -#include -#include - -class NoteDisplayAttribute : public Akonadi::Attribute -{ -public: - NoteDisplayAttribute(); - ~NoteDisplayAttribute(); - - QByteArray type() const; - - NoteDisplayAttribute* clone() const; - - QByteArray serialized() const; - - void deserialize( const QByteArray &data ); - - void setBackgroundColor(const QColor &color); - QColor backgroundColor() const; - QColor foregroundColor() const; - void setForegroundColor(const QColor &color); - - QSize size() const; - void setSize(const QSize &size); - - bool rememberDesktop() const; - void setRememberDesktop(bool b); - void setTabSize(int value); - int tabSize() const; - - - void setFont(const QFont &f); - QFont font() const; - void setTitleFont(const QFont &f); - QFont titleFont() const; - - void setDesktop(int v); - int desktop() const; - void setIsHidden(bool b); - bool isHidden() const; - void setPosition(const QPoint &pos); - QPoint position() const; - void setShowInTaskbar(bool b); - bool showInTaskbar() const; - void setKeepAbove(bool b); - bool keepAbove() const; - void setKeepBelow(bool b); - bool keepBelow() const; - - bool autoIndent() const; - void setAutoIndent(bool b); -private: - QFont mFont; - QFont mTitleFont; - QColor mBackgroundColor; - QColor mForegroundgroundColor; - QSize mSize; - QPoint mPosition; - int mTabSize; - int mDesktop; - bool mRememberDesktop; - bool mAutoIndent; - bool mHide; - bool mShowInTaskbar; - bool mKeepAbove; - bool mKeepBelove; - bool mKeepBelow; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/migration/knotes/notelockattribute.cpp kdepim-runtime-15.08.0/migration/knotes/notelockattribute.cpp --- kdepim-runtime-4.14.6/migration/knotes/notelockattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/notelockattribute.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 "notelockattribute.h" - -#include - -NoteLockAttribute::NoteLockAttribute() - : Akonadi::Attribute() -{ - -} - -NoteLockAttribute::~NoteLockAttribute() -{ - -} - -NoteLockAttribute* NoteLockAttribute::clone() const -{ - return new NoteLockAttribute(); -} - -void NoteLockAttribute::deserialize(const QByteArray& data) -{ - Q_UNUSED( data ); -} - -QByteArray NoteLockAttribute::serialized() const -{ - return "-"; -} - -QByteArray NoteLockAttribute::type() const -{ - //We can't change this name! - static const QByteArray sType( "KJotsLockAttribute" ); - return sType; -} - - diff -Nru kdepim-runtime-4.14.6/migration/knotes/notelockattribute.h kdepim-runtime-15.08.0/migration/knotes/notelockattribute.h --- kdepim-runtime-4.14.6/migration/knotes/notelockattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/notelockattribute.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 KJOTS_LOCK_ATTRIBUTE_H -#define KJOTS_LOCK_ATTRIBUTE_H - -#include - -class NoteLockAttribute : public Akonadi::Attribute -{ -public: - NoteLockAttribute(); - ~NoteLockAttribute(); - - QByteArray type() const; - - NoteLockAttribute* clone() const; - - QByteArray serialized() const; - - void deserialize( const QByteArray &data ); -}; - -#endif diff -Nru kdepim-runtime-4.14.6/migration/knotes/showfoldernotesattribute.cpp kdepim-runtime-15.08.0/migration/knotes/showfoldernotesattribute.cpp --- kdepim-runtime-4.14.6/migration/knotes/showfoldernotesattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/showfoldernotesattribute.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -/* - Copyright (c) 2013-2015 Montel Laurent - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#include "showfoldernotesattribute.h" - -#include -ShowFolderNotesAttribute::ShowFolderNotesAttribute() -{ -} - -ShowFolderNotesAttribute::~ShowFolderNotesAttribute() -{ -} - -ShowFolderNotesAttribute *ShowFolderNotesAttribute::clone() const -{ - return new ShowFolderNotesAttribute(); -} - -QByteArray ShowFolderNotesAttribute::type() const -{ - static const QByteArray sType( "showfoldernotesattribute" ); - return sType; -} - -QByteArray ShowFolderNotesAttribute::serialized() const -{ - return "-"; -} - -void ShowFolderNotesAttribute::deserialize( const QByteArray &data ) -{ - Q_UNUSED( data ); -} diff -Nru kdepim-runtime-4.14.6/migration/knotes/showfoldernotesattribute.h kdepim-runtime-15.08.0/migration/knotes/showfoldernotesattribute.h --- kdepim-runtime-4.14.6/migration/knotes/showfoldernotesattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/knotes/showfoldernotesattribute.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/* - Copyright (c) 2013-2015 Montel Laurent - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef SHOWFOLDERNOTESATTRIBUTE_H -#define SHOWFOLDERNOTESATTRIBUTE_H - -#include - -class ShowFolderNotesAttribute : public Akonadi::Attribute -{ -public: - ShowFolderNotesAttribute(); - ~ShowFolderNotesAttribute(); - - /* reimpl */ - ShowFolderNotesAttribute *clone() const; - QByteArray type() const; - QByteArray serialized() const; - void deserialize( const QByteArray &data ); -}; - -#endif // SHOWFOLDERNOTESATTRIBUTE_H diff -Nru kdepim-runtime-4.14.6/migration/kres/CMakeLists.txt kdepim-runtime-15.08.0/migration/kres/CMakeLists.txt --- kdepim-runtime-4.14.6/migration/kres/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kres/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -set(kres-migrator_srcs - main.cpp - kabcmigrator.cpp - kcalmigrator.cpp - kresmigratorbase.cpp - ${MIGRATION_AKONADI_SHARED_SOURCES} -) - -macro(add_resource_iface _kcfgFile _ifaceName _className) - kcfg_generate_dbus_interface(${kdepim-runtime_SOURCE_DIR}/resources/${_kcfgFile} ${_ifaceName}) - string(TOLOWER ${_className} _codeFile) - qt4_add_dbus_interface(kres-migrator_srcs - ${CMAKE_CURRENT_BINARY_DIR}/${_ifaceName}.xml ${_codeFile} ${_className} - ) -endmacro() - -add_resource_iface( vcard/vcardresource.kcfg org.kde.Akonadi.VCard.Settings VCardSettings ) -add_resource_iface( ical/icalresource.kcfg org.kde.Akonadi.ICal.Settings ICalSettings ) -add_resource_iface( birthdays/birthdaysresource.kcfg org.kde.Akonadi.Birthdays.Settings BirthdaysSettings ) -add_resource_iface( maildir/maildirresource.kcfg org.kde.Akonadi.Maildir.Settings MaildirSettings ) -add_resource_iface( dav/resource/davgroupwareresource.kcfg org.kde.Akonadi.davGroupware.Settings DavSettings ) - -kde4_add_app_icon(kres-migrator_srcs "${KDE4_ICON_DIR}/oxygen/*/apps/akonadi.png") -kde4_add_executable(kres-migrator ${kres-migrator_srcs}) - -target_link_libraries(kres-migrator - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDE4_KRESOURCE_LIBS} - ${KDEPIMLIBS_KABC_LIBS} - ${KDEPIMLIBS_KCAL_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${KDE4_KDECORE_LIBS} - ${QT_QTGUI_LIBRARY} -) - -install(TARGETS kres-migrator ${INSTALL_TARGETS_DEFAULT_ARGS}) -install(FILES kres-migratorrc DESTINATION ${CONFIG_INSTALL_DIR}) diff -Nru kdepim-runtime-4.14.6/migration/kres/kabcmigrator.cpp kdepim-runtime-15.08.0/migration/kres/kabcmigrator.cpp --- kdepim-runtime-4.14.6/migration/kres/kabcmigrator.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kres/kabcmigrator.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 "kabcmigrator.h" - -#include "vcardsettings.h" - -#include -#include -#include -#include - -#include - -using namespace Akonadi; - -KABCMigrator::KABCMigrator() : - KResMigrator( QLatin1String("contact"), QLatin1String("akonadi_kabc_resource") ) -{ -} - -bool KABCMigrator::migrateResource( KABC::Resource* res) -{ - kDebug() << res->identifier() << res->type(); - if ( res->type() == QLatin1String("file") ) - return migrateFileResource( res ); - else - return false; - //return true; this line will never been reached -} - -bool KABCMigrator::migrateFileResource(KABC::Resource * res) -{ - const KConfigGroup kresCfg = kresConfig( res ); - const QString format = kresCfg.readEntry( "FileFormat", "" ); - if ( format == QLatin1String("binary") ) { - emit message( Warning, i18n( "Unsupported file format found. " - "The file format '%1' is no longer supported, please convert to another one.", format ) ); - return false; - } else if ( format != QLatin1String("vcard") ) { - emit message( Skip, i18n( "File format '%1' is not yet supported natively.", format ) ); - return false; - } - createAgentInstance( QLatin1String("akonadi_vcard_resource"), this, SLOT(fileResourceCreated(KJob*)) ); - return true; -} - -void KABCMigrator::fileResourceCreated(KJob * job) -{ - if ( job->error() ) { - migrationFailed( i18n( "Failed to create resource: %1", job->errorText() ) ); - return; - } - KABC::Resource *res = currentResource(); - AgentInstance instance = static_cast( job )->instance(); - const KConfigGroup kresCfg = kresConfig( res ); - instance.setName( kresCfg.readEntry( "ResourceName", i18n("Migrated Addressbook") ) ); - - OrgKdeAkonadiVCardSettingsInterface *iface = new OrgKdeAkonadiVCardSettingsInterface( QLatin1String("org.freedesktop.Akonadi.Resource.") + instance.identifier(), - QLatin1String("/Settings"), QDBusConnection::sessionBus(), this ); - if ( !iface->isValid() ) { - migrationFailed( i18n( "Failed to obtain D-Bus interface for remote configuration." ), instance ); - delete iface; - return; - } - iface->setPath( kresCfg.readPathEntry( "FileName", KStandardDirs::locateLocal( "data", QLatin1String("kabc/std.vcf") ) ) ); - iface->setReadOnly( res->readOnly() ); - - // make sure the config is saved - iface->writeConfig(); - - instance.reconfigure(); - migrationCompleted( instance ); -} - diff -Nru kdepim-runtime-4.14.6/migration/kres/kabcmigrator.h kdepim-runtime-15.08.0/migration/kres/kabcmigrator.h --- kdepim-runtime-4.14.6/migration/kres/kabcmigrator.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kres/kabcmigrator.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 KABCMIGRATOR_H -#define KABCMIGRATOR_H - -#include "kresmigrator.h" - -#include - -#include - -class KJob; - -/** - * Migrate KABC resources to Akonadi - */ -class KABCMigrator : public KResMigrator -{ - Q_OBJECT - public: - KABCMigrator(); - - bool migrateResource( KABC::Resource *res ); - - private slots: - void fileResourceCreated( KJob* job ); - - private: - bool migrateFileResource( KABC::Resource *res ); -}; - -#endif diff -Nru kdepim-runtime-4.14.6/migration/kres/kcalmigrator.cpp kdepim-runtime-15.08.0/migration/kres/kcalmigrator.cpp --- kdepim-runtime-4.14.6/migration/kres/kcalmigrator.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kres/kcalmigrator.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,169 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 "kcalmigrator.h" - -#include "icalsettings.h" -#include "birthdayssettings.h" -#include "davsettings.h" - -#include -#include -#include -#include - -#include - -#include - -using namespace Akonadi; - -KCalMigrator::KCalMigrator() : - KResMigrator( QLatin1String("calendar"), QLatin1String("akonadi_kcal_resource") ) -{ -} - -bool KCalMigrator::migrateResource( KCal::ResourceCalendar* res) -{ - kDebug() << res->identifier() << res->type(); - if ( res->type() == QLatin1String("file") ) - createAgentInstance( QLatin1String("akonadi_ical_resource"), this, SLOT(fileResourceCreated(KJob*)) ); - else if ( res->type() == QLatin1String("birthdays") ) - createAgentInstance( QLatin1String("akonadi_birthdays_resource"), this, SLOT(birthdaysResourceCreated(KJob*)) ); - else if ( res->type() == QLatin1String("groupdav") ) - createAgentInstance( QLatin1String("akonadi_davgroupware_resource"), this, SLOT(davResourceCreated(KJob*)) ); - else - return false; - return true; -} - -void KCalMigrator::fileResourceCreated(KJob * job) -{ - if ( job->error() ) { - migrationFailed( i18n( "Failed to create resource: %1", job->errorText() ) ); - return; - } - KCal::ResourceCalendar *res = currentResource(); - AgentInstance instance = static_cast( job )->instance(); - const KConfigGroup kresCfg = kresConfig( res ); - instance.setName( kresCfg.readEntry( "ResourceName", i18n("Migrated Calendar") ) ); - - OrgKdeAkonadiICalSettingsInterface *iface = new OrgKdeAkonadiICalSettingsInterface( QLatin1String("org.freedesktop.Akonadi.Resource.") + instance.identifier(), - QLatin1String("/Settings"), QDBusConnection::sessionBus(), this ); - if ( !iface->isValid() ) { - migrationFailed( i18n( "Failed to obtain D-Bus interface for remote configuration." ), instance ); - delete iface; - return; - } - iface->setPath( kresCfg.readPathEntry( "CalendarURL", QLatin1String("") ) ); - iface->setReadOnly( res->readOnly() ); - - // make sure the config is saved - iface->writeConfig(); - - instance.reconfigure(); - migrationCompleted( instance ); -} - -void KCalMigrator::birthdaysResourceCreated(KJob* job) -{ - if ( job->error() ) { - migrationFailed( i18n( "Failed to create birthdays resource: %1", job->errorText() ) ); - return; - } - KCal::ResourceCalendar *res = currentResource(); - AgentInstance instance = static_cast( job )->instance(); - const KConfigGroup kresCfg = kresConfig( res ); - instance.setName( kresCfg.readEntry( "ResourceName", i18n("Migrated Birthdays") ) ); - - OrgKdeAkonadiBirthdaysSettingsInterface *iface = - new OrgKdeAkonadiBirthdaysSettingsInterface( QLatin1String("org.freedesktop.Akonadi.Resource.") + instance.identifier(), - QLatin1String("/Settings"), QDBusConnection::sessionBus(), this ); - if ( !iface->isValid() ) { - migrationFailed( i18n( "Failed to obtain D-Bus interface for remote configuration." ), instance ); - delete iface; - return; - } - iface->setEnableAlarm( kresCfg.readEntry( "Alarm", true ) ); - iface->setAlarmDays( kresCfg.readEntry( "AlarmDays", 1 ) ); - iface->setFilterOnCategories( kresCfg.readEntry( "UseCategories", false ) ); - iface->setFilterCategories( kresCfg.readEntry( "Categories", QStringList() ) ); - instance.reconfigure(); - migrationCompleted( instance ); -} - -void KCalMigrator::davResourceCreated(KJob *job) -{ - if ( job->error() ) { - migrationFailed( i18n( "Failed to create DAV resource: %1", job->errorText() ) ); - return; - } - KCal::ResourceCalendar *res = currentResource(); - AgentInstance instance = static_cast( job )->instance(); - const KConfigGroup kresCfg = kresConfig( res ); - QString name = kresCfg.readEntry( "ResourceName", i18n("Migrated GroupDAV") ); - instance.setName( name ); - - QString groupdavCfgFile = KStandardDirs::locateLocal( "config", QLatin1String("kresources_groupwarerc") ); - if ( !KStandardDirs::exists( groupdavCfgFile ) ) { - migrationFailed( i18n( "Failed to find the configuration file for the GroupDAV KResource" ), instance ); - return; - } - - KConfig groupdavCfg( groupdavCfgFile ); - if ( !groupdavCfg.hasGroup( res->identifier() + QLatin1String(":General") ) ) { - migrationFailed( i18n( "Apparently invalid configuration file for the GroupDAV KResource" ), instance ); - return; - } - KConfigGroup groupdavGeneralCfg = groupdavCfg.group( res->identifier() + QLatin1String(":General") ); - - OrgKdeAkonadiDavGroupwareSettingsInterface *iface = - new OrgKdeAkonadiDavGroupwareSettingsInterface( QLatin1String("org.freedesktop.Akonadi.Resource.") + instance.identifier(), - QLatin1String("/Settings"), QDBusConnection::sessionBus(), this ); - if ( !iface->isValid() ) { - migrationFailed( i18n( "Failed to obtain D-Bus interface for remote configuration." ), instance ); - delete iface; - return; - } - - QString user = groupdavGeneralCfg.readEntry( "User" ); - QString url = groupdavGeneralCfg.readEntry( "Url" ); - if ( user.isEmpty() || url.isEmpty() ) { - migrationFailed( i18n( "Empty username or URL in GroupDAV KResource configuration" ), instance ); - delete iface; - return; - } - - if ( !url.endsWith( QLatin1Char('/') ) ) - url.append( QLatin1String("/") ); - - QStringList remoteUrls; - remoteUrls << QString( user + QLatin1String("|GroupDav|") + url ); - kDebug() << name << remoteUrls; - - iface->setDisplayName( name ); - iface->setRemoteUrls( remoteUrls ); - iface->writeConfig(); - - // Must restart the resource to get the first sync done right - instance.restart(); - migrationCompleted( instance ); -} - - diff -Nru kdepim-runtime-4.14.6/migration/kres/kcalmigrator.h kdepim-runtime-15.08.0/migration/kres/kcalmigrator.h --- kdepim-runtime-4.14.6/migration/kres/kcalmigrator.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kres/kcalmigrator.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 KCALMIGRATOR_H -#define KCALMIGRATOR_H - -#include "kresmigrator.h" - -#include - -#include - -class KJob; - -/** - * Migrate KCal resources to Akonadi - */ -class KCalMigrator : public KResMigrator -{ - Q_OBJECT - public: - KCalMigrator(); - - bool migrateResource( KCal::ResourceCalendar *res ); - - private slots: - void fileResourceCreated( KJob* job ); - void birthdaysResourceCreated( KJob *job ); - void davResourceCreated( KJob *job ); -}; - -#endif diff -Nru kdepim-runtime-4.14.6/migration/kres/kresmigratorbase.cpp kdepim-runtime-15.08.0/migration/kres/kresmigratorbase.cpp --- kdepim-runtime-4.14.6/migration/kres/kresmigratorbase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kres/kresmigratorbase.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,177 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 "kresmigratorbase.h" - -#include -#include - -#include -#include - -#include -#include -#include -#include - -using namespace Akonadi; - -KResMigratorBase::KResMigratorBase(const QString & type, const QString &bridgeType) : - KMigratorBase(), - mType( type ), - mBridgeType( bridgeType ), - mCurrentKResource( 0 ), - mBridgingInProgress( false ) -{ - KConfigGroup cfg( KGlobal::config(), "Bridged" ); - mPendingBridgedResources = cfg.readEntry( mType + QLatin1String("Resources"), QStringList() ); -} - -void KResMigratorBase::migrateToBridge( KRES::Resource *res, const QString & typeId) -{ - kDebug() << res->type() << res->identifier() << typeId; - - if ( migrationState( res->identifier() ) != None ) { - migrateNext(); - return; - } - - emit message( Info, i18n( "Trying to migrate '%1' to compatibility bridge...", res->resourceName() ) ); - mBridgingInProgress = true; - createAgentInstance( typeId, this, SLOT(resourceBridgeCreated(KJob*)) ); -} - -void KResMigratorBase::resourceBridgeCreated(KJob * job) -{ - kDebug(); - if ( job->error() ) { - migrationFailed( i18n( "Unable to create compatibility bridge: %1", job->errorText() ) ); - return; - } - KRES::Resource *res = mCurrentKResource; - Q_ASSERT( res ); - AgentInstance instance = static_cast( job )->instance(); - const KConfigGroup kresCfg = kresConfig( res ); - instance.setName( kresCfg.readEntry( "ResourceName", "Bridged KResource" ) ); - - const QString akoResCfgFile = KStandardDirs::locateLocal( "config", QString::fromLatin1( "%1rc" ).arg( instance.identifier() ) ); - KConfig *akoResConfig = new KConfig( akoResCfgFile ); - KConfigGroup bridgeResCfg( akoResConfig, kresCfg.name() ); - kresCfg.copyTo( &bridgeResCfg ); - bridgeResCfg.writeEntry( "ResourceIsActive", true ); - bridgeResCfg.sync(); - - KConfigGroup generalCfg( akoResConfig, "General" ); - generalCfg.writeEntry( "ResourceKeys", res->identifier() ); - generalCfg.writeEntry( "Standard", res->identifier() ); - generalCfg.sync(); - - akoResConfig->sync(); - delete akoResConfig; - - instance.reconfigure(); - migratedToBridge( instance ); -} - -void KResMigratorBase::setBridgingOnly(bool b) -{ - mBridgeOnly = b; -} - -void KResMigratorBase::migrationFailed(const QString & errorMsg, const Akonadi::AgentInstance & instance) -{ - if ( mBridgingInProgress ) { - emit message( Error, i18n( "Migration of '%1' to compatibility bridge failed: %2", - mCurrentKResource->resourceName(), errorMsg ) ); - } else { - emit message( Error, i18n( "Migration of '%1' to native backend failed: %2", - mCurrentKResource->resourceName(), errorMsg ) ); - } - - if ( instance.isValid() ) { - AgentManager::self()->removeInstance( instance ); - } - - // native backend failed, try the bridge instead - if ( !mBridgingInProgress && mCurrentKResource && !mBridgeType.isEmpty() ) { - migrateToBridge( mCurrentKResource, mBridgeType ); - return; - } - - mBridgingInProgress = false; - mCurrentKResource = 0; - migrateNext(); -} - -void KResMigratorBase::setOmitClientBridge(bool b) -{ - mOmitClientBridge = b; -} - -void KResMigratorBase::migrationCompleted( const Akonadi::AgentInstance &instance, const QString &kresId, const QString &kresName ) -{ - // do an initial sync so the resource shows up in the folder tree at least - AgentInstance nonConstInstance = instance; - nonConstInstance.synchronize(); - - // check if this one was previously bridged and remove the bridge - KConfigGroup cfg( KGlobal::config(), QLatin1String("Resource ") + kresId ); - const QString bridgeId = cfg.readEntry( "ResourceIdentifier", "" ); - if ( bridgeId != instance.identifier() ) { - const AgentInstance bridge = AgentManager::self()->instance( bridgeId ); - AgentManager::self()->removeInstance( bridge ); - } - - setMigrationState( kresId, Complete, instance.identifier(), mType ); - emit message( Success, i18n( "Migration of '%1' succeeded.", kresName ) ); -} - -void KResMigratorBase::createKolabResource( const QString &kresId, const QString &kresName ) -{ - // check if kolab resource exists. If not, create one. - Akonadi::AgentInstance kolabAgent = Akonadi::AgentManager::self()->instance( QLatin1String("akonadi_kolabproxy_resource") ); - if ( !kolabAgent.isValid() ) { - emit message( Info, i18n( "Attempting to create kolab resource" ) ); - KJob * job = createAgentInstance(QLatin1String( "akonadi_kolabproxy_resource"), this, SLOT(kolabResourceCreated(KJob*)) ); - job->setProperty( "kresId", kresId ); - job->setProperty( "kresName", kresName ); - } else { - migrationCompleted( kolabAgent, kresId, kresName ); - migrateNext(); - } -} - -void KResMigratorBase::kolabResourceCreated( KJob *job ) -{ - const QString kresId = job->property( "kresId" ).value(); - const QString kresName = job->property( "kresName" ).value(); - - if ( job->error() != 0 ) { - kError() << "Failed to create Kolab resource for" << kresName << "(id=" << kresId << "):" << job->errorString(); - emit message( Error, i18n( "Failed to create kolab proxy resource." ) ); - } else { - AgentInstanceCreateJob *createJob = qobject_cast( job ); - Q_ASSERT( createJob != 0 ); - migrationCompleted( createJob->instance(), kresId, kresName ); - } - migrateNext(); -} - - - diff -Nru kdepim-runtime-4.14.6/migration/kres/kresmigratorbase.h kdepim-runtime-15.08.0/migration/kres/kresmigratorbase.h --- kdepim-runtime-4.14.6/migration/kres/kresmigratorbase.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kres/kresmigratorbase.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 KRESMIGRATORBASE_H -#define KRESMIGRATORBASE_H - -#include "kmigratorbase.h" - -#include - -namespace KRES { - class Resource; -} - -class KJob; - -/** - * Non-template QObject part of KResMigrator. - */ -class KResMigratorBase : public KMigratorBase -{ - Q_OBJECT - - public: - KResMigratorBase( const QString &type, const QString &bridgeType ); - virtual ~KResMigratorBase() {} - - void migrateToBridge( KRES::Resource* res, const QString &typeId ); - virtual void migratedToBridge(const Akonadi::AgentInstance & instance) = 0; - - virtual KConfigGroup kresConfig( KRES::Resource* res ) const = 0; - - void setBridgingOnly( bool b ); - void setOmitClientBridge( bool b ); - - void migrationFailed( const QString &errorMsg, const Akonadi::AgentInstance &instance = Akonadi::AgentInstance() ); - - protected: - QString mType; - QString mBridgeType; - QStringList mPendingBridgedResources; - bool mBridgeOnly; - bool mOmitClientBridge; - KRES::Resource *mCurrentKResource; - bool mBridgingInProgress; - - protected: - void migrationCompleted( const Akonadi::AgentInstance &instance, const QString &kresId, const QString &kresName ); - - void createKolabResource( const QString &kresId, const QString &kresName ); - - private slots: - void resourceBridgeCreated( KJob *job ); - void kolabResourceCreated( KJob *job ); -}; - -#endif diff -Nru kdepim-runtime-4.14.6/migration/kres/kresmigrator.h kdepim-runtime-15.08.0/migration/kres/kresmigrator.h --- kdepim-runtime-4.14.6/migration/kres/kresmigrator.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kres/kresmigrator.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,322 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 KRESMIGRATOR_H -#define KRESMIGRATOR_H - -#include "kresmigratorbase.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -using namespace Akonadi; - -template class KResMigrator : public KResMigratorBase -{ - public: - KResMigrator( const QString &type, const QString &bridgeType ) : - KResMigratorBase( type, bridgeType ), - mConfig( 0 ), - mManager( 0 ), - mBridgeManager( 0 ), - mClientBridgeFound( false ) - { - } - - virtual ~KResMigrator() - { - delete mBridgeManager; - mBridgeManager = 0; - delete mManager; - mManager = 0; - delete mConfig; - mConfig = 0; - } - - void migrate() - { - const QString kresCfgFile = KStandardDirs::locateLocal( "config", QString::fromLatin1( "kresources/%1/stdrc" ).arg( mType ) ); - mConfig = new KConfig( kresCfgFile ); - const KConfigGroup generalGroup( mConfig, QLatin1String( "General" ) ); - mUnknownTypeResources = QSet::fromList( generalGroup.readEntry( QLatin1String( "ResourceKeys" ), QStringList() ) ); - - mManager = new KRES::Manager( mType ); - mManager->readConfig(); - { - ResourceIterator it = mManager->begin(); - while ( it != mManager->end() ) { - mResourcesToMigrate.append( *it ); - ++it; - } - mIt = mResourcesToMigrate.constBegin(); - } - migrateNext(); - } - - void migrateNext() - { - while ( mIt != mResourcesToMigrate.constEnd() ) { - mUnknownTypeResources.remove( ( *mIt )->identifier() ); - if ( ( *mIt )->type() == QLatin1String("akonadi") ) { - mClientBridgeIdentifier = ( *mIt )->identifier(); - mClientBridgeFound = true; - emit message( Skip, i18n( "Client-side bridge already set up." ) ); - ++mIt; - continue; - } - //KConfigGroup cfg( KGlobal::config(), QLatin1String("Resource ") + ( *mIt )->identifier() ); - kDebug() << "migrateNext:" << ( *mIt )->identifier(); - if ( migrationState( ( *mIt )->identifier() ) == None ) { - emit message( Info, i18n( "Trying to migrate '%1'...", ( *mIt )->resourceName() ) ); - mPendingBridgedResources.removeAll( ( *mIt )->identifier() ); - T* res = *mIt; - mCurrentKResource = res; - ++mIt; - - if ( res->type() == QLatin1String("imap") ) { - createKolabResource( res->identifier(), res->resourceName() ); - } else { - bool nativeAvailable = mBridgeOnly ? false : migrateResource( res ); - if ( !nativeAvailable ) { - emit message( Info, i18n( "No native backend for '%1' available.", res->resourceName() ) ); - migrateToBridge( res, mBridgeType ); - } - } - return; - } - if ( migrationState( ( *mIt )->identifier() ) == Bridged && - !mPendingBridgedResources.contains( ( *mIt )->identifier() ) ) - mPendingBridgedResources << ( *mIt )->identifier(); - if ( migrationState( ( *mIt )->identifier() ) == Complete ) - emit message( Skip, i18n( "'%1' has already been migrated.", ( *mIt )->resourceName() ) ); - ++mIt; - } - if ( !mBridgeType.isEmpty() ) { - if ( mIt == mResourcesToMigrate.constEnd() ) { - migrateBridged(); - if ( mPendingBridgedResources.isEmpty() ) { - migrateUnknown(); - if ( mUnknownTypeResources.isEmpty() ) { - deleteLater(); - } - } - } - } else { - migrateUnknown(); - if ( mUnknownTypeResources.isEmpty() ) { - deleteLater(); - } - } - } - - void migrateBridged() - { - delete mBridgeManager; - mBridgeManager = 0; - - if ( mPendingBridgedResources.isEmpty() ) { - setupClientBridge(); - return; - } - const QString resId = mPendingBridgedResources.takeFirst(); - KConfigGroup resMigrationCfg( KGlobal::config(), QLatin1String("Resource ") + resId ); - const QString akoResId = resMigrationCfg.readEntry( "ResourceIdentifier", "" ); - if ( akoResId.isEmpty() ) { - mUnknownTypeResources.remove( resId ); - emit message( Error, i18n( "No Akonadi agent identifier specified for previously bridged resource '%1'", resId ) ); - migrateNext(); - return; - } - - const QString bridgedCfgFile = KStandardDirs::locateLocal( "config", QString::fromLatin1( "%1rc" ).arg( akoResId ) ); - kDebug() << bridgedCfgFile; - if ( !QFile::exists( bridgedCfgFile ) ) { - emit message( Info, i18n( "Bridged resource %1 does not exist anymore, trying a direct migration", akoResId ) ); - setMigrationState( resId /*old id*/, None, - QString() /*akonadi id*/, mType ); - - ResourceIterator it = mManager->begin(); - while ( it != mManager->end() ) { - if ( ( *it )->identifier() == resId ) { - mResourcesToMigrate.append( *it ); - break; - } - ++it; - } - migrateNext(); - return; - } - mUnknownTypeResources.remove( resId ); - delete mConfig; - mConfig = new KConfig( bridgedCfgFile ); - - mBridgeManager = new KRES::Manager( mType ); - mBridgeManager->readConfig( mConfig ); - if ( !mBridgeManager->standardResource() ) { - // the plugin for this type might no longer be available - const KConfigGroup kresCfgGroup( mConfig, QString::fromLatin1( "Resource_%1" ).arg( resId ) ); - const QString resourceType = kresCfgGroup.readEntry( QLatin1String( "ResourceType" ), QString() ); - if ( !resourceType.isEmpty() ) { - if ( resourceType == QLatin1String( "imap" ) ) { - createKolabResource( resId, kresCfgGroup.readEntry( QLatin1String( "ResourceName" ), QString() ) ); - return; - } - - if ( migrateUnknownResource( resId, resourceType, kresCfgGroup ) ) { - migrateNext(); - return; - } - } - emit message( Error, i18n( "Bridged resource '%1' has no standard resource.", resId ) ); - migrateNext(); - return; - } - - T *res = mBridgeManager->standardResource(); - emit message( Info, i18n( "Trying to migrate '%1' from compatibility bridge to native backend...", res->resourceName() ) ); - mCurrentKResource = res; - bool nativeAvailable = migrateResource( res ); - if ( !nativeAvailable ) { - emit message( Skip, i18n( "No native backend available, keeping compatibility bridge for '%1'.", res->resourceName() ) ); - migrateNext(); - } - } - - virtual bool migrateResource( T *res ) = 0; - - virtual bool migrateUnknownResource( const QString &kresId, const QString &kresType, const KConfigGroup &kresConfig ) - { - Q_UNUSED( kresId ); - Q_UNUSED( kresType ); - Q_UNUSED( kresConfig ); - - migrateNext(); - return false; - } - - KConfigGroup kresConfig( KRES::Resource* res ) const - { - return KConfigGroup( mConfig, QLatin1String("Resource_") + res->identifier() ); - } - - T* currentResource() - { - T* res = dynamic_cast( mCurrentKResource ); - Q_ASSERT( res ); - return res; - } - - void migrationCompleted( const Akonadi::AgentInstance &instance ) - { - KResMigratorBase::migrationCompleted( instance, mCurrentKResource->identifier(), mCurrentKResource->resourceName() ); - migrationCompletedHelper( instance ); - } - - void migratedToBridge(const Akonadi::AgentInstance & instance) - { - mBridgingInProgress = false; - setMigrationState( mCurrentKResource->identifier(), Bridged, instance.identifier(), mType ); - emit message( Success, i18n( "Migration of '%1' to compatibility bridge succeeded.", mCurrentKResource->resourceName() ) ); - migrationCompletedHelper( instance ); - } - - private: - - // This is called when a native migration or a migration to a bridged resource is - // successfully completed. - void migrationCompletedHelper( const Akonadi::AgentInstance & instance ) - { - if ( mManager->standardResource() == mCurrentKResource ) { - mAgentForOldDefaultResource = instance.identifier(); - } - mManager->setActive( mCurrentKResource, false ); - mCurrentKResource = 0; - migrateNext(); - } - - void setupClientBridge() - { - if ( !mOmitClientBridge ) { - if ( !mClientBridgeFound ) { - emit message( Info, i18n( "Setting up client-side bridge..." ) ); - T* clientBridge = mManager->createResource( QLatin1String("akonadi") ); - if ( clientBridge ) { - mClientBridgeIdentifier = clientBridge->identifier(); - clientBridge->setResourceName( i18n( "Akonadi Compatibility Resource" ) ); - mManager->add( clientBridge ); - mManager->setStandardResource( clientBridge ); - emit message( Info, i18n( "Client-side bridge set up successfully." ) ); - } else { - emit message( Error, i18n( "Could not create client-side bridge, check if Akonadi KResource bridge is installed." ) ); - } - } - - mManager->writeConfig(); - const QString keyName( QLatin1String("DefaultAkonadiResourceIdentifier") ); - KConfigGroup clientBridgeConfig( mConfig, QLatin1String("Resource_") + mClientBridgeIdentifier ); - if ( !clientBridgeConfig.hasKey( keyName ) && - !mAgentForOldDefaultResource.isEmpty() ) { - clientBridgeConfig.writeEntry( keyName, mAgentForOldDefaultResource ); - } - } - } - - void migrateUnknown() - { - if ( mUnknownTypeResources.isEmpty() ) { - return; - } - - QSet::iterator setIt = mUnknownTypeResources.begin(); - const QString kresId = *setIt; - mUnknownTypeResources.erase( setIt ); - - const KConfigGroup kresCfgGroup( mConfig, QString::fromLatin1( "Resource_%1" ).arg( kresId ) ); - const QString resourceType = kresCfgGroup.readEntry( QLatin1String( "ResourceType" ), QString() ); - const QString resourceName = kresCfgGroup.readEntry( QLatin1String( "ResourceName" ), QString() ); - - kDebug() << "migrating Unknown" << resourceName << ", type=" << resourceType << ",id=" << kresId; - - if ( resourceType == QLatin1String( "imap" ) ) { - createKolabResource( kresId, resourceName ); - } else { - migrateUnknownResource( kresId, resourceType, kresCfgGroup ); - } - } - - private: - KConfig *mConfig; - KRES::Manager *mManager, *mBridgeManager; - typedef typename KRES::Manager::Iterator ResourceIterator; - typename QList::const_iterator mIt; - QList mResourcesToMigrate; - bool mClientBridgeFound; - QString mClientBridgeIdentifier; - QString mAgentForOldDefaultResource; - QSet mUnknownTypeResources; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/migration/kres/kres-migratorrc kdepim-runtime-15.08.0/migration/kres/kres-migratorrc --- kdepim-runtime-4.14.6/migration/kres/kres-migratorrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kres/kres-migratorrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -[Migration] -Enabled=true -SetupClientBridge=false -TargetVersion=3 diff -Nru kdepim-runtime-4.14.6/migration/kres/main.cpp kdepim-runtime-15.08.0/migration/kres/main.cpp --- kdepim-runtime-4.14.6/migration/kres/main.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kres/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,113 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 "kabcmigrator.h" -#include "kcalmigrator.h" -#include "infodialog.h" - -#include -#include -#include -#include - -#include - -void connectMigrator( KResMigratorBase *m, InfoDialog *dlg ) -{ - if ( !dlg || !m ) - return; - dlg->migratorAdded(); - QObject::connect( m, SIGNAL(message(KMigratorBase::MessageType,QString)), dlg, - SLOT(message(KMigratorBase::MessageType,QString)) ); - QObject::connect( m, SIGNAL(destroyed()), dlg, SLOT(migratorDone()) ); -} - -int main( int argc, char **argv ) -{ - KAboutData aboutData( "kres-migrator", 0, - ki18n( "KResource Migration Tool" ), - "0.1", - ki18n( "Migration of KResource settings and application to Akonadi" ), - KAboutData::License_LGPL, - ki18n( "(c) 2008 the Akonadi developers" ), - KLocalizedString(), - "http://pim.kde.org/akonadi/" ); - aboutData.setProgramIconName( QLatin1String("akonadi") ); - aboutData.addAuthor( ki18n( "Volker Krause" ), ki18n( "Author" ), "vkrause@kde.org" ); - - const QStringList supportedTypes = QStringList() << QLatin1String("contact") << QLatin1String("calendar") << QLatin1String("notes"); - - KCmdLineArgs::init( argc, argv, &aboutData ); - KCmdLineOptions options; - options.add( "bridge-only", ki18n( "Only migrate to Akonadi KResource bridges" ) ); - options.add( "omit-client-bridge", ki18n( "Omit setting up of the client side compatibility bridges" ) ); - options.add( "contacts-only", ki18n( "Only migrate contact resources" ) ); - options.add( "calendar-only", ki18n( "Only migrate calendar resources" ) ); - options.add( "type ", ki18n( "Only migrate the specified types (supported: contact, calendar, notes)" ), - supportedTypes.join( QLatin1String(",") ).toLatin1() ); - options.add( "interactive", ki18n( "Show reporting dialog" ) ); - options.add( "interactive-on-change", ki18n( "Show report only if changes were made" ) ); - KCmdLineArgs::addCmdLineOptions( options ); - KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - - QStringList typesToMigrate; - foreach ( const QString &type, args->getOption( "type" ).split( QLatin1Char(',') ) ) { - if ( !supportedTypes.contains( type ) ) - kWarning() << "Unknown resource type: " << type; - else if ( !QDBusConnection::sessionBus().registerService( QLatin1String("org.kde.Akonadi.KResMigrator.") + type ) ) - kWarning() << "Migrator instance already running for type " << type; - else - typesToMigrate << type; - } - if ( typesToMigrate.isEmpty() ) - return 1; - - KApplication app; - app.setQuitOnLastWindowClosed( false ); - - KGlobal::setAllowQuit( true ); - KGlobal::locale()->insertCatalog( QLatin1String("libakonadi") ); - - InfoDialog *infoDialog = 0; - if ( args->isSet( "interactive" ) || args->isSet( "interactive-on-change" ) ) { - infoDialog = new InfoDialog( args->isSet( "interactive-on-change" ) ); - infoDialog->show(); - } - - foreach ( const QString &type, typesToMigrate ) { - KResMigratorBase *m = 0; - if ( type == QLatin1String("contact") ) - m = new KABCMigrator(); - else if ( type == QLatin1String("calendar") ) - m = new KCalMigrator(); - else { - kError() << "Unknown resource type: " << type; - continue; - } - m->setBridgingOnly( args->isSet( "bridge-only" ) ); - m->setOmitClientBridge( args->isSet( "omit-client-bridge" ) ); - connectMigrator( m, infoDialog ); - } - - args->clear(); - const int result = app.exec(); - if ( InfoDialog::hasError() ) - return 3; - return result; -} diff -Nru kdepim-runtime-4.14.6/migration/kres/Messages.sh kdepim-runtime-15.08.0/migration/kres/Messages.sh --- kdepim-runtime-4.14.6/migration/kres/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kres/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -#!/bin/sh -$XGETTEXT ../*.cpp *.cpp *.h -o $podir/kres-migrator.pot diff -Nru kdepim-runtime-4.14.6/migration/kres/metatype.h kdepim-runtime-15.08.0/migration/kres/metatype.h --- kdepim-runtime-4.14.6/migration/kres/metatype.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/kres/metatype.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -/* Copyright 2009 Thomas McGuire - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 POP3_METATYPE_H -#define POP3_METATYPE_H - -#include -#include - -#include - -Q_DECLARE_METATYPE(QList) - -#endif diff -Nru kdepim-runtime-4.14.6/migration/migratorbase.cpp kdepim-runtime-15.08.0/migration/migratorbase.cpp --- kdepim-runtime-4.14.6/migration/migratorbase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/migratorbase.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,35 +20,37 @@ */ #include "migratorbase.h" -#include -#include +#include #include #include -#include +#include #include #include +#include +#include +#include +#include static QString messageTypeToString(MigratorBase::MessageType type) { switch (type) { - case MigratorBase::Success: return QLatin1String("Success"); - case MigratorBase::Skip: return QLatin1String("Skipped"); - case MigratorBase::Info: return QLatin1String("Info "); - case MigratorBase::Warning: return QLatin1String("WARNING"); - case MigratorBase::Error: return QLatin1String("ERROR "); + case MigratorBase::Success: return QStringLiteral("Success"); + case MigratorBase::Skip: return QStringLiteral("Skipped"); + case MigratorBase::Info: return QStringLiteral("Info "); + case MigratorBase::Warning: return QStringLiteral("WARNING"); + case MigratorBase::Error: return QStringLiteral("ERROR "); } Q_ASSERT(false); return QString(); } - static QMap fillMigrationStateMapping() { QMap map; - map.insert(QLatin1String("Complete"), MigratorBase::Complete); - map.insert(QLatin1String("Aborted"), MigratorBase::Aborted); - map.insert(QLatin1String("InProgress"), MigratorBase::InProgress); - map.insert(QLatin1String("Failed"), MigratorBase::Failed); + map.insert(QStringLiteral("Complete"), MigratorBase::Complete); + map.insert(QStringLiteral("Aborted"), MigratorBase::Aborted); + map.insert(QStringLiteral("InProgress"), MigratorBase::InProgress); + map.insert(QStringLiteral("Failed"), MigratorBase::Failed); return map; } @@ -67,27 +69,29 @@ } MigratorBase::MigratorBase(const QString &identifier, QObject *parent) -: QObject(parent), - mIdentifier(identifier), - mMigrationState(None), - mConfig(new KConfig(Akonadi::ServerManager::addNamespace(QLatin1String("akonadi-migrationrc")))) -{ - const QString logFileName = KStandardDirs::locateLocal("data", KGlobal::mainComponent().componentName() + QLatin1String("/") + identifier + QLatin1String("migration.log")); + : QObject(parent), + mIdentifier(identifier), + mMigrationState(None), + mConfig(new KConfig(Akonadi::ServerManager::addNamespace(QStringLiteral("akonadi-migrationrc")))) +{ + const QString logFileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + KGlobal::mainComponent().componentName() + QStringLiteral("/") + identifier + QStringLiteral("migration.log"); + QFileInfo fileInfo(logFileName); + QDir().mkpath(fileInfo.absolutePath()); setLogfile(logFileName); - connect(this, SIGNAL(message(MigratorBase::MessageType,QString)), SLOT(logMessage(MigratorBase::MessageType,QString))); + connect(this, &MigratorBase::message, this, &MigratorBase::logMessage); loadState(); } MigratorBase::MigratorBase(const QString &identifier, const QString &configFile, const QString &logFile, QObject *parent) -: QObject(parent), - mIdentifier(identifier), - mMigrationState(None) + : QObject(parent), + mIdentifier(identifier), + mMigrationState(None) { if (!configFile.isEmpty()) { mConfig.reset(new KConfig(configFile)); } setLogfile(logFile); - connect(this, SIGNAL(message(MigratorBase::MessageType,QString)), SLOT(logMessage(MigratorBase::MessageType,QString))); + connect(this, &MigratorBase::message, this, &MigratorBase::logMessage); loadState(); } @@ -102,7 +106,7 @@ mLogFile.reset(new QFile(logfile)); if (!mLogFile->open(QFile::Append)) { mLogFile.reset(); - kWarning() << "Unable to open log file: " << logfile; + qWarning() << "Unable to open log file: " << logfile; } } else { mLogFile.reset(); @@ -135,7 +139,7 @@ bool MigratorBase::canStart() { if (mIdentifier.isEmpty()) { - emit message(Error, i18n("Missing Identifier")); + Q_EMIT message(Error, i18n("Missing Identifier")); return false; } return true; @@ -144,17 +148,17 @@ void MigratorBase::start() { if (mMigrationState == InProgress) { - kWarning() << "already running"; + qWarning() << "already running"; return; } if (!canStart()) { - emit message(Error, i18n("Failed to start migration because migrator is not ready")); - emit stoppedProcessing(); + Q_EMIT message(Error, i18n("Failed to start migration because migrator is not ready")); + Q_EMIT stoppedProcessing(); return; } //TODO acquire dbus lock logMessage(Info, displayName()); - emit message(Info, i18n("Starting migration...")); + Q_EMIT message(Info, i18n("Starting migration...")); setMigrationState(InProgress); setProgress(0); startWork(); @@ -162,24 +166,24 @@ void MigratorBase::pause() { - kWarning() << "pause is not implemented"; + qWarning() << "pause is not implemented"; } void MigratorBase::resume() { - kWarning() << "resume is not implemented"; + qWarning() << "resume is not implemented"; } void MigratorBase::abort() { - kWarning() << "abort is not implemented"; + qWarning() << "abort is not implemented"; } void MigratorBase::logMessage(MigratorBase::MessageType type, const QString &msg) { if (mLogFile) { - mLogFile->write(QString(QLatin1Char('[') + QDateTime::currentDateTime().toString() + QLatin1String("] ") - + messageTypeToString(type) + QLatin1String(": ") + msg + QLatin1Char('\n')).toUtf8()); + mLogFile->write(QString(QLatin1Char('[') + QDateTime::currentDateTime().toString() + QStringLiteral("] ") + + messageTypeToString(type) + QStringLiteral(": ") + msg + QLatin1Char('\n')).toUtf8()); mLogFile->flush(); } } @@ -193,32 +197,32 @@ { mMigrationState = state; switch (state) { - case Complete: - setProgress(100); - emit message(Success, i18n("Migration complete")); - emit stoppedProcessing(); - break; - case Aborted: - emit message(Skip, i18n("Migration aborted")); - emit stoppedProcessing(); - break; - case InProgress: - break; - case Failed: - emit message(Error, i18n("Migration failed")); - emit stoppedProcessing(); - break; - case Paused: - emit message(Info, i18n("Migration paused")); - emit stateChanged(mMigrationState); - return; - default: - kWarning() << "invalid state " << state; - Q_ASSERT(false); - return; + case Complete: + setProgress(100); + Q_EMIT message(Success, i18n("Migration complete")); + Q_EMIT stoppedProcessing(); + break; + case Aborted: + Q_EMIT message(Skip, i18n("Migration aborted")); + Q_EMIT stoppedProcessing(); + break; + case InProgress: + break; + case Failed: + Q_EMIT message(Error, i18n("Migration failed")); + Q_EMIT stoppedProcessing(); + break; + case Paused: + Q_EMIT message(Info, i18n("Migration paused")); + Q_EMIT stateChanged(mMigrationState); + return; + default: + qWarning() << "invalid state " << state; + Q_ASSERT(false); + return; } saveState(); - emit stateChanged(mMigrationState); + Q_EMIT stateChanged(mMigrationState); } MigratorBase::MigrationState MigratorBase::migrationState() const @@ -228,26 +232,26 @@ void MigratorBase::saveState() { - config().writeEntry(QLatin1String("MigrationState"), stateToIdentifier(mMigrationState)); + config().writeEntry(QStringLiteral("MigrationState"), stateToIdentifier(mMigrationState)); } void MigratorBase::loadState() { - const QString state = config().readEntry(QLatin1String("MigrationState"), QString()); + const QString state = config().readEntry(QStringLiteral("MigrationState"), QString()); if (!state.isEmpty()) { mMigrationState = identifierToState(state); } if (mMigrationState == InProgress) { - emit message(Warning, i18n("This migration has already been started once but was aborted")); + Q_EMIT message(Warning, i18n("This migration has already been started once but was aborted")); mMigrationState = NeedsUpdate; } switch (mMigrationState) { - case Complete: - mProgress = 100; - break; - default: - mProgress = 0; + case Complete: + mProgress = 100; + break; + default: + mProgress = 0; } } @@ -268,20 +272,20 @@ { if (mProgress != prog) { mProgress = prog; - emit progress(prog); + Q_EMIT progress(prog); } } QString MigratorBase::status() const { switch (mMigrationState) { - case None: return i18nc("@info:status", "Not started"); - case InProgress: return i18nc("@info:status", "Running..."); - case Complete: return i18nc("@info:status", "Complete"); - case Aborted: return i18nc("@info:status", "Aborted"); - case Paused: return i18nc("@info:status", "Paused"); - case NeedsUpdate: return i18nc("@info:status", "Needs Update"); - case Failed: return i18nc("@info:status", "Failed"); + case None: return i18nc("@info:status", "Not started"); + case InProgress: return i18nc("@info:status", "Running..."); + case Complete: return i18nc("@info:status", "Complete"); + case Aborted: return i18nc("@info:status", "Aborted"); + case Paused: return i18nc("@info:status", "Paused"); + case NeedsUpdate: return i18nc("@info:status", "Needs Update"); + case Failed: return i18nc("@info:status", "Failed"); } return QString(); } diff -Nru kdepim-runtime-4.14.6/migration/migratorbase.h kdepim-runtime-15.08.0/migration/migratorbase.h --- kdepim-runtime-4.14.6/migration/migratorbase.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/migratorbase.h 2015-08-10 21:01:02.000000000 +0000 @@ -40,7 +40,7 @@ KConfigGroup &configGroup() { - return mConfigGroup; + return mConfigGroup; } template @@ -85,14 +85,14 @@ /** * Default constructor with default config and logfile */ - explicit MigratorBase(const QString &identifier, QObject *parent = 0); + explicit MigratorBase(const QString &identifier, QObject *parent = Q_NULLPTR); /** * Constructor that allows to inject a configfile and logfile. * * Pass and empty string to disable config and log. */ - explicit MigratorBase(const QString &identifier, const QString &configFile, const QString &logFile, QObject *parent = 0); + explicit MigratorBase(const QString &identifier, const QString &configFile, const QString &logFile, QObject *parent = Q_NULLPTR); virtual ~MigratorBase(); @@ -184,7 +184,7 @@ */ QString status() const; -signals: +Q_SIGNALS: //Signal for state changes void stateChanged(MigratorBase::MigrationState); @@ -207,7 +207,7 @@ void setProgress(int); -private slots: +private Q_SLOTS: /** * Logs a message, that appears in the logfile and potentially in a log window. * Do not call this directly. Emit the message signal instead, which is connected to this slot. diff -Nru kdepim-runtime-4.14.6/migration/tests/CMakeLists.txt kdepim-runtime-15.08.0/migration/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/migration/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -project(migrationtests) - -set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) - -include(AkonadiMacros) -set(KDEPIMLIBS_RUN_ISOLATED_TESTS TRUE) -set(KDEPIMLIBS_RUN_SQLITE_ISOLATED_TESTS TRUE) - -set(_srcList - testnotesmigration.cpp - ../kjots/kjotsmigrator.cpp - ../kres/kresmigratorbase.cpp - ${MIGRATION_AKONADI_SHARED_SOURCES} -) -include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/../kjots - ${CMAKE_CURRENT_BINARY_DIR}/../kres -) - -macro(add_resource_iface _kcfgFile _ifaceName _className) - kcfg_generate_dbus_interface(${kdepim-runtime_SOURCE_DIR}/resources/${_kcfgFile} ${_ifaceName}) - string(TOLOWER ${_className} _codeFile) - qt4_add_dbus_interface(_srcList - ${CMAKE_CURRENT_BINARY_DIR}/${_ifaceName}.xml ${_codeFile} ${_className} - ) -endmacro() - -add_resource_iface( maildir/maildirresource.kcfg - org.kde.Akonadi.Maildir.Settings MaildirSettings ) - -add_akonadi_isolated_test_advanced( testgidmigration.cpp "${MIGRATION_AKONADI_SHARED_SOURCES};../gid/gidmigrationjob.cpp" "" ) - -kde4_add_executable(testmigratorbase testmigratorbase.cpp ../migratorbase.cpp) -target_link_libraries(testmigratorbase - gidmigration - ${KDE4_KDECORE_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${QT_QTCORE_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ${QT_QTTEST_LIBRARY} -) -add_test(testmigratorbase testmigratorbase) diff -Nru kdepim-runtime-4.14.6/migration/tests/testgidmigration.cpp kdepim-runtime-15.08.0/migration/tests/testgidmigration.cpp --- kdepim-runtime-4.14.6/migration/tests/testgidmigration.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/testgidmigration.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +0,0 @@ -/* - Copyright 2013 Christian Mollekopf - - 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 "testgidmigration.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "gid/gidmigrationjob.h" - - -bool TestSerializer::deserialize(Akonadi::Item &item, const QByteArray &label, QIODevice &data, int /* version */ ) -{ - if (label != Akonadi::Item::FullPayload) { - return false; - } - item.setPayload(data.readAll()); - return true; -} - -void TestSerializer::serialize(const Akonadi::Item &item, const QByteArray &label, QIODevice &data, int &/* version */) -{ - Q_ASSERT(label == Akonadi::Item::FullPayload); - data.write(item.payload()); -} - -QString TestSerializer::extractGid(const Akonadi::Item &item) const -{ - if (item.gid().isEmpty()) { - return item.url().url(); - } - return item.gid(); -} - - -void TestGidMigration::allItemsHaveGid(const Collection &col, bool haveGid, bool *success) -{ - *success = false; - - ItemFetchJob *fetchJob = new ItemFetchJob(col); - fetchJob->fetchScope().fetchFullPayload(); - fetchJob->fetchScope().setFetchGid(true); - AKVERIFYEXEC(fetchJob); - QCOMPARE(fetchJob->items().count(), 15); - - Q_FOREACH (const Item &item, fetchJob->items()) { - if (haveGid) { - QVERIFY2(!item.gid().isEmpty(), QString::fromLatin1("Item %1 (%2) does not have GID!").arg(item.id()).arg(item.remoteId()).toUtf8().constData()); - } else { - QVERIFY2(item.gid().isEmpty(), QString::fromLatin1("Item %1 (%2) has GID!").arg(item.id()).arg(item.remoteId()).toUtf8().constData()); - } - } - - *success = true; -} - -TestGidMigration::TestGidMigration(QObject *parent) -: QObject(parent) -{ - -} - -void TestGidMigration::initTestCase() -{ - AkonadiTest::checkTestIsIsolated(); -} - -void TestGidMigration::init() -{ - AkonadiTest::setAllResourcesOffline(); - Akonadi::AgentInstance agent = Akonadi::AgentManager::self()->instance(QLatin1String("akonadi_knut_resource_0")); - QVERIFY(agent.isValid()); - agent.setIsOnline(true); - - Akonadi::ItemSerializerPlugin::overridePluginLookup(new TestSerializer); -} - -void TestGidMigration::testMigration() -{ - Akonadi::CollectionPathResolver *resolver = new CollectionPathResolver(QLatin1String("res1/foo"), this); - AKVERIFYEXEC(resolver); - const Entity::Id colId = resolver->collection(); - bool allItemsHaveGidOk = false; - - allItemsHaveGid(Collection(colId), false, &allItemsHaveGidOk); - QVERIFY(allItemsHaveGidOk); - - GidMigrationJob *migrationJob = new GidMigrationJob(QStringList() << QLatin1String("application/octet-stream"), this); - AKVERIFYEXEC(migrationJob); - - allItemsHaveGid(Collection(colId), true, &allItemsHaveGidOk); - QVERIFY(allItemsHaveGidOk); -} - -QTEST_AKONADIMAIN(TestGidMigration, NoGUI) diff -Nru kdepim-runtime-4.14.6/migration/tests/testgidmigration.h kdepim-runtime-15.08.0/migration/tests/testgidmigration.h --- kdepim-runtime-4.14.6/migration/tests/testgidmigration.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/testgidmigration.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -/* - Copyright 2013 Christian Mollekopf - - 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 TESTGIDMIGRATION_H -#define TESTGIDMIGRATION_H - -#include - -#include -#include - -namespace Akonadi { - class EntityTreeModel; -} - -using namespace Akonadi; - -class TestGidMigration : public QObject -{ - Q_OBJECT -public: - explicit TestGidMigration(QObject *parent = 0); - -private Q_SLOTS: - void init(); - void initTestCase(); - void testMigration(); - -private: - void allItemsHaveGid(const Collection &collection, bool haveGid, bool *success); - - Akonadi::EntityTreeModel *mEtm; -}; - -#include -#include - -class TestSerializer: public QObject, - public Akonadi::ItemSerializerPlugin, - public Akonadi::GidExtractorInterface -{ - Q_OBJECT - Q_INTERFACES(Akonadi::ItemSerializerPlugin) - Q_INTERFACES(Akonadi::GidExtractorInterface) - - public: - bool deserialize(Akonadi::Item &item, const QByteArray &label, QIODevice &data, int version ); - void serialize(const Akonadi::Item &item, const QByteArray &label, QIODevice &data, int &version ); - QString extractGid(const Akonadi::Item &item) const; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/migration/tests/testmigratorbase.cpp kdepim-runtime-15.08.0/migration/tests/testmigratorbase.cpp --- kdepim-runtime-4.14.6/migration/tests/testmigratorbase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/testmigratorbase.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,143 +0,0 @@ -/* - * Copyright 2013 Christian Mollekopf - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License or (at your option) version 3 or any later version - * accepted by the membership of KDE e.V. (or its successor approved - * by the membership of KDE e.V.), which shall act as a proxy - * defined in Section 14 of version 3 of the license. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include -#include -#include - -#include "migratorbase.h" - -class Testmigrator: public MigratorBase -{ - Q_OBJECT -public: - bool mCanStart; - - explicit Testmigrator(const QString &identifier, QObject *parent = 0) - : MigratorBase(QLatin1String("testmigrator") + identifier, parent), - mCanStart(true) - {}; - - explicit Testmigrator(const QString &identifier, const QString &logfile, const QString &configFile, QObject *parent = 0) - : MigratorBase(QLatin1String("testmigrator") + identifier, configFile, logfile, parent), - mCanStart(true) - {}; - - virtual bool canStart() - { - return mCanStart; - } - - virtual void startWork() - { - emit started(); - } - - virtual void pause() - { - setMigrationState(Paused); - } - - virtual void abort() - { - setMigrationState(Aborted); - } - - void setComplete() - { - setMigrationState(Complete); - } - -signals: - void started(); -}; - -class MigratorBaseTest: public QObject -{ - Q_OBJECT -private slots: - - void initTest() - { - qRegisterMetaType(); - } - - void testStart() - { - Testmigrator migrator(QLatin1String("id")); - { - QSignalSpy spy(&migrator, SIGNAL(started())); - QSignalSpy stateSpy(&migrator, SIGNAL(stateChanged(MigratorBase::MigrationState))); - QVERIFY(spy.isValid()); - migrator.mCanStart = false; - migrator.start(); - QCOMPARE(spy.count(), 0); - QCOMPARE(stateSpy.count(), 0); - migrator.mCanStart = true; - migrator.start(); - QCOMPARE(spy.count(), 1); - QCOMPARE(stateSpy.count(), 1); - QCOMPARE(stateSpy.takeFirst().at(0).value(), MigratorBase::InProgress); - } - { - QSignalSpy spy(&migrator, SIGNAL(stateChanged(MigratorBase::MigrationState))); - QVERIFY(spy.isValid()); - migrator.abort(); - QCOMPARE(spy.count(), 1); - QCOMPARE(spy.takeFirst().at(0).value(), MigratorBase::Aborted); - } - { - QSignalSpy spy(&migrator, SIGNAL(stateChanged(MigratorBase::MigrationState))); - QVERIFY(spy.isValid()); - migrator.setComplete(); - QCOMPARE(spy.count(), 1); - QCOMPARE(spy.takeFirst().at(0).value(), MigratorBase::Complete); - } - } - - void testDisableLogAndConfig() - { - Testmigrator migrator(QLatin1String("id"), QString(), QString()); - migrator.start(); - migrator.setComplete(); - } - - void testPersistState() - { - const QString configFile(QDir::tempPath() + QLatin1String("/testconfig.cfg")); - QFile file(configFile); - file.remove(); - { - Testmigrator migrator(QLatin1String("id"), QString(), configFile); - QCOMPARE(migrator.migrationState(), MigratorBase::None); - migrator.setComplete(); - } - { - Testmigrator migrator(QLatin1String("id"), QString(), configFile); - QCOMPARE(migrator.migrationState(), MigratorBase::Complete); - } - } - -}; - -QTEST_MAIN(MigratorBaseTest) - -#include "testmigratorbase.moc" diff -Nru kdepim-runtime-4.14.6/migration/tests/testnotesmigration.cpp kdepim-runtime-15.08.0/migration/tests/testnotesmigration.cpp --- kdepim-runtime-4.14.6/migration/tests/testnotesmigration.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/testnotesmigration.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,148 +0,0 @@ -/* - Copyright 2010 Stephen Kelly - - 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 "testnotesmigration.h" - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include "kjots/kjotsmigrator.h" -#include "kres/knotesmigrator.h" - -#include - -using namespace Akonadi; - -void NotesMigrationTest::initTestCase() -{ - ItemFetchScope scope; - scope.fetchFullPayload( true ); // Need to have full item when adding it to the internal data structure - scope.fetchAttribute< EntityDisplayAttribute >(); - - Akonadi::ChangeRecorder *changeRecorder = new Akonadi::ChangeRecorder( this ); - changeRecorder->fetchCollection( true ); - changeRecorder->setItemFetchScope( scope ); - changeRecorder->setCollectionMonitored( Collection::root() ); - changeRecorder->setMimeTypeMonitored( "text/x-vnd.akonadi.note" ); - - m_etm = new Akonadi::EntityTreeModel( changeRecorder, this ); - connect( m_etm, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(checkRowsInserted(QModelIndex,int,int))); - -} - -void NotesMigrationTest::testKJotsBooksMigration() -{ - KJotsMigrator *migrator = new KJotsMigrator; - Q_UNUSED( migrator ) - - m_expectedStructure.insert( "Local Notes", ( QStringList() << "rich content book" << "Something" << "Book2" << "kde3_book3" << "kde3_test1" ) ); - m_expectedStructure.insert( "Something", ( QStringList() << "Page 1" << "Page 2" ) ); - m_expectedStructure.insert( "Book2", ( QStringList() << "Page 1" << "Page 2" << "Nested book" ) ); - m_expectedStructure.insert( "Nested book", ( QStringList() << "nested page 1" << "nested page 2" ) ); - m_expectedStructure.insert( "rich content book", ( QStringList() << "rich content page 1" << "rich content page 2" ) ); - m_expectedStructure.insert( "kde3_book3", ( QStringList() << "kde3_book3 Page 1" ) ); - m_expectedStructure.insert( "kde3_test1", ( QStringList() << "kde3_book2" << "kde3_Page 1" << "kde3_Page 2" ) ); - m_expectedStructure.insert( "kde3_book2", ( QStringList() << "kde3_nested Page 1" ) ); - - QTest::qWait( 5000 ); - - QHashIterator it( m_expectedStructure ); - while ( it.hasNext() ) { - it.next(); - QString key = it.key(); - QStringList value = it.value(); - value.sort(); - QVERIFY( m_seenStructure.contains( key ) ); - QStringList seenValue = m_seenStructure.value( key ); - seenValue.sort(); - QVERIFY( value == seenValue ); - } -} - -void NotesMigrationTest::checkRowsInserted( const QModelIndex &parent, int start, int end ) -{ - const int rowCount = m_etm->rowCount( parent ); - Q_UNUSED( rowCount ) - static const int column = 0; - if ( !parent.isValid() && !m_expectedStructure.isEmpty() ) { - Collection resourceRootCollection = m_etm->index( start, column, parent ).data( EntityTreeModel::CollectionRole ).value(); - QVERIFY( resourceRootCollection.isValid() ); - QVERIFY( resourceRootCollection.name() == "Local Notes" ); - QVERIFY( resourceRootCollection.contentMimeTypes() == ( QStringList() << Akonadi::Collection::mimeType() << "text/x-vnd.akonadi.note" ) ); - QVERIFY( resourceRootCollection.parentCollection() == Akonadi::Collection::root() ); - m_seenStructure.insert( resourceRootCollection.name(), QStringList() ); - return; - } - for ( int row = start; row <= end; ++row ) { - QModelIndex index = m_etm->index( row, column, parent ); - - Collection newCollection = index.data( EntityTreeModel::CollectionRole ).value(); - QString parentName = parent.data().toString(); - if ( newCollection.isValid() ) { - // This is a new collection in the resource. - QVERIFY( newCollection.contentMimeTypes() == ( QStringList() << Akonadi::Collection::mimeType() << "text/x-vnd.akonadi.note" ) ); - if ( !m_expectedStructure.isEmpty() ) { - QVERIFY( m_expectedStructure[ parentName ].contains( index.data().toString() ) ); - m_seenStructure[ parentName ].append( index.data().toString() ); - } else - m_seenNotes.append( index.data().toString() ); - } else { - Item newItem = index.data( EntityTreeModel::ItemRole ).value(); - QVERIFY( newItem.isValid() ); - QVERIFY( newItem.hasPayload() ); - KMime::Message::Ptr note = newItem.payload(); - - if ( !m_expectedStructure.isEmpty() ) { - QVERIFY( m_expectedStructure[ parentName ].contains( note->subject()->asUnicodeString() ) ); - m_seenStructure[ parentName ].append( note->subject()->asUnicodeString() ); - } else { - m_seenNotes.append( note->subject()->asUnicodeString() ); - } - } - } -} - -void NotesMigrationTest::testLocalKNotesMigration() -{ - m_expectedStructure.clear(); - m_seenStructure.clear(); - - m_expectedNotes << "Notes" << "2010-02-08 12:12" << "2010-02-08 12:29"; - - KNotesMigrator *migrator = new KNotesMigrator; - Q_UNUSED( migrator ) - - QTest::qWait( 2000 ); - - m_expectedNotes.sort(); - m_seenNotes.sort(); - - kDebug() << m_seenNotes << m_expectedNotes; - QVERIFY( m_seenNotes == m_expectedNotes ); -} - -QTEST_AKONADIMAIN( NotesMigrationTest, NoGUI ) diff -Nru kdepim-runtime-4.14.6/migration/tests/testnotesmigration.h kdepim-runtime-15.08.0/migration/tests/testnotesmigration.h --- kdepim-runtime-4.14.6/migration/tests/testnotesmigration.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/testnotesmigration.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -/* - Copyright 2010 Stephen Kelly - - 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 NOTESMIGRATIONTEST_H -#define NOTESMIGRATIONTEST_H - -#include - -#include -#include -#include -#include -#include - -namespace Akonadi -{ -class EntityTreeModel; -} - -using namespace Akonadi; - -class NotesMigrationTest : public QObject -{ - Q_OBJECT - -public: - NotesMigrationTest(QObject* parent = 0) - : QObject(parent) - {} - -protected Q_SLOTS: - void checkRowsInserted( const QModelIndex &parent, int start, int end ); - -private Q_SLOTS: - void initTestCase(); - void testKJotsBooksMigration(); - - void testLocalKNotesMigration(); - -private: - Akonadi::EntityTreeModel *m_etm; - - // Use by kjots. - QHash m_expectedStructure; - QHash m_seenStructure; - - // Used by notes. - QStringList m_expectedNotes; - QStringList m_seenNotes; - - -}; - -#endif diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/config-sqlite-db.xml kdepim-runtime-15.08.0/migration/tests/unittestenv/config-sqlite-db.xml --- kdepim-runtime-4.14.6/migration/tests/unittestenv/config-sqlite-db.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/config-sqlite-db.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ - - kdehome - xdgconfig - xdglocal - akonadi_knut_resource - true - sqlite - diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/kjots/f23552.book kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/kjots/f23552.book --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/kjots/f23552.book 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/kjots/f23552.book 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ - - - - - Book2 - 5 - false - 1 - - Page 1 - 4 - false - - -

book2 page 1 content

]]>
-
- - Page 2 - 6 - false - - -

book 2 page 2

-

]]>
-
- - Nested book - 8 - false - 1 - - nested page 1 - 7 - false - - -

nested page 1 content

]]>
-
- - nested page 2 - 9 - false - - -

nested page 2 content

]]>
-
-
-
-
diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/kjots/k21863.book kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/kjots/k21863.book --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/kjots/k21863.book 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/kjots/k21863.book 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ - - - - - rich content book - 11 - false - 1 - - rich content page 1 - 10 - false - - -

rich content 1

]]>
-
- - rich content page 2 - 12 - false - - -

More rich content page 2

]]>
-
-
-
diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/kjots/kde3_hu4mua.book kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/kjots/kde3_hu4mua.book --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/kjots/kde3_hu4mua.book 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/kjots/kde3_hu4mua.book 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ - - - - kde3_book3 - 9 - 1 - - kde3_book3 Page 1 - 10 - - - - diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/kjots/kde3_TDHwQa.book kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/kjots/kde3_TDHwQa.book --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/kjots/kde3_TDHwQa.book 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/kjots/kde3_TDHwQa.book 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ - - - - kde3_test1 - 2 - 1 - - kde3_book2 - 6 - 1 - - kde3_nested Page 1 - 7 - - - - - kde3_Page 1 - 3 - - - - kde3_Page 2 - 4 - - - - diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/kjots/N23552.book kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/kjots/N23552.book --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/kjots/N23552.book 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/kjots/N23552.book 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ - - - - - Something - 2 - false - 1 - - Page 1 - 1 - false - - -

Page 1 content

-

]]>
-
- - Page 2 - 3 - false - - -

Page 2 content

-

]]>
-
-
-
diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/knotes/notes/libkcal-2098450417.977 kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/knotes/notes/libkcal-2098450417.977 --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/knotes/notes/libkcal-2098450417.977 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/knotes/notes/libkcal-2098450417.977 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -[Display] -bgcolor=255,255,189 - -[General] -version=3.9 - -[WindowDisplay] -HideNote=true -desktop=1 -position=484,154 diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/knotes/notes/libkcal-297296717.52 kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/knotes/notes/libkcal-297296717.52 --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/knotes/notes/libkcal-297296717.52 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/knotes/notes/libkcal-297296717.52 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -[Display] -bgcolor=255,255,189 - -[General] -version=3.9 - -[WindowDisplay] -HideNote=true -desktop=1 -position=1195,158 diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/knotes/notes.ics kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/knotes/notes.ics --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/apps/knotes/notes.ics 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/apps/knotes/notes.ics 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -BEGIN:VCALENDAR -PRODID:-//K Desktop Environment//NONSGML libkcal 4.3//EN -VERSION:2.0 -BEGIN:VJOURNAL -DTSTAMP:20100208T161533Z -X-KDE-KNotes-BgColor:#ffffbd -X-KDE-KNotes-FgColor:#000000 -X-KDE-KNotes-RichText:false -CREATED:20100208T111228Z -UID:libkcal-297296717.52 -LAST-MODIFIED:20100208T112745Z -DESCRIPTION:xcvxcvx2010-02-08 12:13 -SUMMARY:2010-02-08 12:12 -BEGIN:VALARM -DESCRIPTION: -ACTION:DISPLAY -TRIGGER;VALUE=DATE-TIME:20100208T120000Z -END:VALARM -END:VJOURNAL -BEGIN:VJOURNAL -DTSTAMP:20100208T161533Z -X-KDE-KNotes-BgColor:#ffffbd -X-KDE-KNotes-FgColor:#000000 -X-KDE-KNotes-RichText:false -CREATED:20100208T112938Z -UID:libkcal-2098450417.977 -LAST-MODIFIED:20100208T161533Z -DESCRIPTION:Some kind of content -SUMMARY:2010-02-08 12:29 -END:VJOURNAL -END:VCALENDAR diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -[ProcessedDefaults] -defaultaddressbook=done -defaultcalendar=done -defaultnotebook=done diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -[General] -DataFile[$e]=$KDEHOME/testdata-res1.xml -FileWatchingEnabled=false - diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/kdebugrc kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/kdebugrc --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/kdebugrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/kdebugrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -DisableAll=false - -[0] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[264] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[5250] -InfoOutput=2 - -[7009] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[7011] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[7012] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[7014] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=0 -FatalFilename[$e]=kdebug.dbg -FatalOutput=0 -InfoFilename[$e]=kdebug.dbg -InfoOutput=0 -WarnFilename[$e]=kdebug.dbg -WarnOutput=0 - -[7021] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/kdedrc kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/kdedrc --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/kdedrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/kdedrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[General] -CheckSycoca=false -CheckFileStamps=false diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/kres-migratorrc kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/kres-migratorrc --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/kres-migratorrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/kres-migratorrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -[Migration] -Enabled=false diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/kresources/notes/stdrc kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/kresources/notes/stdrc --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/kresources/notes/stdrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/kresources/notes/stdrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -[$Version] -update_info=kolab-resource.upd:kolab-notes-resource-rename - -[General] -PassiveResourceKeys= -ResourceKeys=670EbuwOq8 -Standard=670EbuwOq8 - -[Resource_670EbuwOq8] -NotesURL[$e]=file://$KDEHOME/share/apps/knotes/notes.ics -ResourceIdentifier=670EbuwOq8 -ResourceIsActive=true -ResourceIsReadOnly=false -ResourceName=Notes -ResourceType=file diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/kwalletrc kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/kwalletrc --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/kwalletrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/kwalletrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -[Wallet] -Enabled=false diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/qttestrc kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/qttestrc --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/share/config/qttestrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/share/config/qttestrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -[Notification Messages] -WalletMigrate=false diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/testdata-res1.xml kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/testdata-res1.xml --- kdepim-runtime-4.14.6/migration/tests/unittestenv/kdehome/testdata-res1.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/kdehome/testdata-res1.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ - - - - - - - - - - - testmailbody - From: <test@user.tst> - \SEEN - \FLAGGED - \DRAFT - - - testmailbody1 - From: <test1@user.tst> - \FLAGGED - - - testmailbody2 - From: <test2@user.tst> - - - testmailbody3 - From: <test3@user.tst> - - - testmailbody4 - From: <test4@user.tst> - - - testmailbody5 - From: <test5@user.tst> - - - testmailbody6 - From: <test6@user.tst> - - - testmailbody7 - From: <test7@user.tst> - - - testmailbody8 - From: <test8@user.tst> - - - testmailbody9 - From: <test9@user.tst> - - - testmailbody10 - From: <test10@user.tst> - - - testmailbody11 - From: <test11@user.tst> - - - testmailbody12 - From: <test12@user.tst> - - - testmailbody13 - From: <test13@user.tst> - - - testmailbody14 - From: <test14@user.tst> - - - - diff -Nru kdepim-runtime-4.14.6/migration/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc kdepim-runtime-15.08.0/migration/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/migration/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/migration/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -[%General] -Driver=QSQLITE3 - -[Search] -Manager=Dummy diff -Nru kdepim-runtime-4.14.6/opensync/akonadi_opensync.cpp kdepim-runtime-15.08.0/opensync/akonadi_opensync.cpp --- kdepim-runtime-4.14.6/opensync/akonadi_opensync.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/opensync/akonadi_opensync.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,201 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 "akonadisink.h" -#include "datasink.h" - -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include - -static KComponentData *kcd = 0; -static QCoreApplication *app = 0; - -static int fakeArgc = 0; -static char** fakeArgv = 0; - -extern "C" -{ - -static void* akonadi_initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) -{ - osync_trace( TRACE_ENTRY, "%s(%p, %p, %p)", __func__, plugin, info, error ); - - if ( !app ) - app = new QCoreApplication( fakeArgc, fakeArgv ); - if ( !kcd ) - kcd = new KComponentData( "akonadi_opensync" ); - - // main sink - AkonadiSink *mainSink = new AkonadiSink(); - if ( !mainSink->initialize( plugin, info, error ) ) { - delete mainSink; - osync_trace( TRACE_EXIT_ERROR, "%s: NULL", __func__ ); - return 0; - } - - // object type sinks - const int numobjs = osync_plugin_info_num_objtypes( info ); - for ( int i = 0; i < numobjs; ++i ) { - OSyncObjTypeSink *sink = osync_plugin_info_nth_objtype( info, i ); - QString sinkName( osync_objtype_sink_get_name( sink ) ); - kDebug() << "###" << i << sinkName; - - DataSink *ds; - if ( sinkName == "event" ) - ds = new DataSink( DataSink::Calendar ); - else if ( sinkName == "contact" ) - ds = new DataSink( DataSink::Contacts ); - - if ( !ds->initialize( plugin, info, sink, error ) ) { - delete ds; - delete mainSink; - osync_trace( TRACE_EXIT_ERROR, "%s: NULL", __func__ ); - return 0; - } - } - - osync_trace( TRACE_EXIT, "%s: %p", __func__, mainSink ); - return mainSink; -} - -static osync_bool akonadi_discover(void *userdata, OSyncPluginInfo *info, OSyncError **error) -{ - osync_trace( TRACE_ENTRY, "%s(%p, %p, %p)", __func__, userdata, info, error ); - kDebug(); - - if ( !Akonadi::Control::start() ) - return false; - - // fetch all akonadi collections - Akonadi::CollectionFetchJob *job = new Akonadi::CollectionFetchJob( - Akonadi::Collection::root(), Akonadi::CollectionFetchJob::Recursive ); - if ( !job->exec() ) - return false; - - Akonadi::Collection::List cols = job->collections(); - kDebug() << "found" << cols.count() << "collections"; - - OSyncPluginConfig *config = osync_plugin_info_get_config( info ); - - Akonadi::MimeTypeChecker contactMimeChecker; - contactMimeChecker.addWantedMimeType( KABC::Addressee::mimeType() ); - Akonadi::MimeTypeChecker calendarMimeTypeChecker; - calendarMimeTypeChecker.addWantedMimeType( QLatin1String( "text/calendar" ) ); - - const int num_objtypes = osync_plugin_info_num_objtypes( info ); - for ( int i = 0; i < num_objtypes; ++i ) { - OSyncObjTypeSink *sink = osync_plugin_info_nth_objtype( info, i ); - foreach ( const Akonadi::Collection &col, cols ) { - kDebug() << "creating resource for" << col.name() << col.contentMimeTypes(); -// if ( !contactMimeChecker.isWantedCollection( col ) ) // ### TODO -// continue; - if ( col.contentMimeTypes().isEmpty() ) - continue; - - OSyncPluginResource *res = osync_plugin_resource_new( error ); - // TODO error handling? - osync_plugin_resource_enable( res, TRUE ); - osync_plugin_resource_set_name( res, col.name().toUtf8() ); // TODO: full path instead of the name - osync_plugin_resource_set_objtype( res, osync_objtype_sink_get_name( sink ) ); - osync_plugin_resource_set_url( res, col.url().url().toLatin1() ); - - QString formatName; - if ( calendarMimeChecker.isWantedCollection( col ) ) - formatName = "vevent20"; - else if ( contactMimeChecker.isWantedCollection( col ) ) - formatName = "vcard30"; - else - continue; // if the collection is not calendar or contact one, skip it - - /*OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env( info ); - OSyncObjFormat *format = osync_format_env_find_objformat( formatenv, formatName.toLatin1() ); - osync_plugin_resource_set_objformat( res, format );*/ - - osync_plugin_resource_add_objformat_sink( res, osync_objformat_sink_new( formatName.toLatin1(), error ) ); - - osync_plugin_config_add_resource( config, res ); - } - osync_objtype_sink_set_available( sink, TRUE ); - } - - osync_trace( TRACE_EXIT, "%s", __func__ ); - return TRUE; -} - -static void akonadi_finalize(void *userdata) -{ - osync_trace( TRACE_ENTRY, "%s(%p)", __func__, userdata ); - kDebug(); - AkonadiSink *sink = reinterpret_cast( userdata ); - delete sink; - delete kcd; - kcd = 0; - delete app; - app = 0; - osync_trace( TRACE_EXIT, "%s", __func__ ); -} - -KDE_EXPORT osync_bool get_sync_info(OSyncPluginEnv *env, OSyncError **error) -{ - osync_trace( TRACE_ENTRY, "%s(%p)", __func__, env ); - - OSyncPlugin *plugin = osync_plugin_new( error ); - if ( !plugin ) { - osync_trace( TRACE_EXIT_ERROR, "%s: Unable to register: %s", __func__, osync_error_print( error ) ); - return FALSE; - } - - osync_plugin_set_name( plugin, "akonadi-sync" ); - osync_plugin_set_longname( plugin, "Akonadi" ); - osync_plugin_set_description( plugin, "Plugin to synchronize with Akonadi" ); -// osync_plugin_set_config_type(plugin, OSYNC_PLUGIN_NO_CONFIGURATION); - osync_plugin_set_start_type( plugin, OSYNC_START_TYPE_PROCESS ); - - osync_plugin_set_initialize( plugin, akonadi_initialize ); - osync_plugin_set_finalize( plugin, akonadi_finalize ); - osync_plugin_set_discover( plugin, akonadi_discover ); - - osync_plugin_env_register_plugin( env, plugin ); - osync_plugin_unref( plugin ); - - osync_trace( TRACE_EXIT, "%s", __func__ ); - return TRUE; -} - -KDE_EXPORT int get_version(void) -{ - return 1; -} - -}// extern "C" diff -Nru kdepim-runtime-4.14.6/opensync/akonadisink.cpp kdepim-runtime-15.08.0/opensync/akonadisink.cpp --- kdepim-runtime-4.14.6/opensync/akonadisink.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/opensync/akonadisink.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 "akonadisink.h" - -#include - -#include - -AkonadiSink::AkonadiSink() : - SinkBase( Connect ) -{ -} - -AkonadiSink::~AkonadiSink() -{ -} - -bool AkonadiSink::initialize(OSyncPlugin * plugin, OSyncPluginInfo * info, OSyncError ** error) -{ - kDebug(); - OSyncObjTypeSink *sink = osync_objtype_main_sink_new( error ); - wrapSink( sink ); - osync_plugin_info_set_main_sink( info, sink ); - return true; -} - -void AkonadiSink::connect() -{ - osync_trace( TRACE_ENTRY, "%s(%p, %p)", __PRETTY_FUNCTION__, pluginInfo(), context() ); - kDebug(); - - if ( !Akonadi::Control::start() ) { - error( OSYNC_ERROR_NO_CONNECTION, "Could not start Akonadi." ); - osync_trace( TRACE_EXIT_ERROR, "%s: %s", __PRETTY_FUNCTION__, "Could not start Akonadi." ); - return; - } - - success(); - osync_trace( TRACE_EXIT, "%s", __PRETTY_FUNCTION__ ); -} - diff -Nru kdepim-runtime-4.14.6/opensync/akonadisink.h kdepim-runtime-15.08.0/opensync/akonadisink.h --- kdepim-runtime-4.14.6/opensync/akonadisink.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/opensync/akonadisink.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 AKONADISINK_H -#define AKONADISINK_H - -#include "sinkbase.h" - -/** - * Main sink, does nothing but ensure Akonadi is running. - */ -class AkonadiSink : public SinkBase -{ - Q_OBJECT - - public: - AkonadiSink(); - ~AkonadiSink(); - - bool initialize( OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error ); - - void connect(); -}; - -#endif diff -Nru kdepim-runtime-4.14.6/opensync/akonadi-sync kdepim-runtime-15.08.0/opensync/akonadi-sync --- kdepim-runtime-4.14.6/opensync/akonadi-sync 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/opensync/akonadi-sync 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ - - - - - 1 - - - vcard30 - - - contact - - - diff -Nru kdepim-runtime-4.14.6/opensync/CMakeLists.txt kdepim-runtime-15.08.0/opensync/CMakeLists.txt --- kdepim-runtime-4.14.6/opensync/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/opensync/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -include ( OpenSyncInternal ) -include ( OpenSyncPlugin ) - -LINK_DIRECTORIES( ${OPENSYNC_LIBRARY_DIRS} ${GLIB2_LIBRARY_DIRS} ) -INCLUDE_DIRECTORIES( ${OPENSYNC_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS} ${Boost_INCLUDE_DIR} ) - -set( akonadi_opensync_srcs - akonadi_opensync.cpp - sinkbase.cpp - akonadisink.cpp - datasink.cpp -) - -# for boost -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - -automoc4( akonadi_opensync_plugin akonadi_opensync_srcs ) -OPENSYNC_PLUGIN_ADD( akonadi_opensync_plugin ${akonadi_opensync_srcs} ) - -TARGET_LINK_LIBRARIES( akonadi_opensync_plugin - ${OPENSYNC_LIBRARIES} - ${GLIB2_LIBRARIES} - ${KDE4_KDECORE_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KCAL_LIBS} -) - -OPENSYNC_PLUGIN_INSTALL( akonadi_opensync_plugin ) -OPENSYNC_PLUGIN_CONFIG( akonadi-sync ) diff -Nru kdepim-runtime-4.14.6/opensync/datasink.cpp kdepim-runtime-15.08.0/opensync/datasink.cpp --- kdepim-runtime-4.14.6/opensync/datasink.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/opensync/datasink.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,433 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 "datasink.h" - -// calendar includes -#include -#include - -// contact includes -#include -#include - -// notes includes -// TODO - -#include -#include -#include - -using namespace Akonadi; - -typedef boost::shared_ptr IncidencePtr; - - -DataSink::DataSink( int type ) : - SinkBase( GetChanges | Commit | SyncDone ) -{ - m_type = type; -} - -DataSink::~DataSink() { - if ( m_hashtable ) - osync_hashtable_unref( m_hashtable ); -} - -bool DataSink::initialize(OSyncPlugin * plugin, OSyncPluginInfo * info, OSyncObjTypeSink *sink, OSyncError ** error) -{ - Q_UNUSED( plugin ); - Q_UNUSED( info ); - Q_UNUSED( error ); - - bool enabled = osync_objtype_sink_is_enabled( sink ); - if ( !enabled ) { - kDebug() << "sink is not enabled.."; - return false; - } - - QString configdir( osync_plugin_info_get_configdir( info ) ); - QString hashfile = QString( "%1/%2-hash.db" ).arg( configdir, osync_objtype_sink_get_name( sink ) ); - - m_hashtable = osync_hashtable_new( hashfile.toUtf8(), osync_objtype_sink_get_name( sink ), error ); - - if ( !osync_hashtable_load( m_hashtable, error ) ) { - osync_trace( TRACE_EXIT_ERROR, "%s: %s", __PRETTY_FUNCTION__, osync_error_print( error ) ); - return false; - } - - wrapSink( sink ); - - return true; -} - -Akonadi::Collection DataSink::collection() const -{ - OSyncPluginConfig *config = osync_plugin_info_get_config( pluginInfo() ); - Q_ASSERT( config ); - - const char *objtype = osync_objtype_sink_get_name( sink() ); - - OSyncPluginResource *res = osync_plugin_config_find_active_resource( config, objtype ); - - if ( !res ) { - error( OSYNC_ERROR_MISCONFIGURATION, i18n( "No active resource for type \"%1\" found", objtype ) ); - return Collection(); - } - - const KUrl url = KUrl( osync_plugin_resource_get_url( res ) ); - if ( url.isEmpty() ) { - error( OSYNC_ERROR_MISCONFIGURATION, i18n( "Url for object type \"%1\" is not configured.", objtype ) ); - return Collection(); - } - - return Collection::fromUrl( url ); -} - -void DataSink::getChanges() -{ - // ### broken in OpenSync, I don't get valid configuration here! -#if 1 - Collection col = collection(); - if ( !col.isValid() ) - return; -#else - Collection col( 409 ); -#endif - - OSyncError *oerror = 0; - - if ( osync_objtype_sink_get_slowsync( sink() ) ) { - kDebug() << "we're in the middle of slow-syncing..."; - osync_trace( TRACE_INTERNAL, "Got slow-sync, resetting hashtable" ); - if ( !osync_hashtable_slowsync( m_hashtable, &oerror ) ) { - warning( oerror ); - osync_trace( TRACE_EXIT_ERROR, "%s: %s", __PRETTY_FUNCTION__, osync_error_print( &oerror ) ); - return; - } - } - - ItemFetchJob *job = new ItemFetchJob( col ); - job->fetchScope().fetchFullPayload(); - - QObject::connect( job, SIGNAL(itemsReceived(Akonadi::Item::List)), this, SLOT(slotItemsReceived(Akonadi::Item::List)) ); - QObject::connect( job, SIGNAL(result(KJob*)), this, SLOT(slotGetChangesFinished(KJob*)) ); - - // FIXME give me a real eventloop please! - if ( !job->exec() ) { - error( OSYNC_ERROR_IO_ERROR, job->errorText() ); - return; - } -} - -void DataSink::slotItemsReceived( const Item::List &items ) -{ - kDebug() << "retrieved" << items.count() << "items"; - Q_FOREACH ( const Item& item, items ) { - //kDebug() << item.payloadData(); - reportChange( item ); - } -} - -void DataSink::reportChange( const Item& item ) -{ - OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env( pluginInfo() ); - OSyncObjFormat *format = osync_format_env_find_objformat( formatenv, formatName().toLatin1() ); - - OSyncError *error = 0; - - OSyncChange *change = osync_change_new( &error ); - if ( !change ) { - warning( error ); - return; - } - - osync_change_set_uid( change, QString::number( item.id() ).toLatin1() ); - - error = 0; - - OSyncData *odata = osync_data_new( item.payloadData().data(), item.payloadData().size(), format, &error ); - if ( !odata ) { - osync_change_unref( change ); - warning( error ); - return; - } - - osync_data_set_objtype( odata, osync_objtype_sink_get_name( sink() ) ); - - osync_change_set_data( change, odata ); - - kDebug() << item.id() << "DATA:" << osync_data_get_printable( odata ) << "\n" << "ORIG:" << item.payloadData().data(); - - osync_data_unref( odata ); - - osync_change_set_hash( change, QString::number( item.revision() ).toLatin1() ); - - OSyncChangeType changeType = osync_hashtable_get_changetype( m_hashtable, change ); - osync_change_set_changetype( change, changeType ); - - osync_hashtable_update_change( m_hashtable, change ); - -/* -kDebug() << "changeid:" << osync_change_get_uid( change ) - << "itemid:" << item.id() - << "revision:" << item.revision() - << "changetype:" << changeType - << "hash:" << osync_hashtable_get_hash( m_hashtable, osync_change_get_uid( change ) ) - << "objtype:" << osync_change_get_objtype( change ) - << "objform:" << osync_objformat_get_name( osync_change_get_objformat( change ) ) - << "sinkname:" << osync_objtype_sink_get_name( sink() ); -*/ - if ( changeType != OSYNC_CHANGE_TYPE_UNMODIFIED ) - osync_context_report_change( context(), change ); - - // perhaps this should be only called when an error has happened ie. never after _context_report_change()? - //osync_change_unref( change ); // if this gets called, we get broken pipes. any ideas? -} - -void DataSink::slotGetChangesFinished( KJob * ) -{ - OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env( pluginInfo() ); - OSyncObjFormat *format = osync_format_env_find_objformat( formatenv, formatName().toLatin1() ); - - // after the items have been processed, see what's been deleted and send them to opensync - OSyncError *error = 0; - OSyncList *u, *uids = osync_hashtable_get_deleted( m_hashtable ); - - for ( u = uids; u; u = u->next ) { - QString uid( (char *)u->data ); - kDebug() << "going to delete with uid:" << uid; - - OSyncChange *change = osync_change_new( &error ); - if ( !change ) { - warning( error ); - continue; - } - - osync_change_set_changetype( change, OSYNC_CHANGE_TYPE_DELETED ); - osync_change_set_uid( change, uid.toLatin1() ); - - error = 0; - OSyncData *data = osync_data_new( 0, 0, format, &error ); - if ( !data ) { - osync_change_unref( change ); - warning( error ); - continue; - } - - osync_data_set_objtype( data, osync_objtype_sink_get_name( sink() ) ); - osync_change_set_data( change, data ); - - osync_hashtable_update_change( m_hashtable, change ); - - osync_change_unref( change ); - } - osync_list_free( uids ); - - kDebug() << "got all changes.."; - success(); -} - -void DataSink::commit(OSyncChange *change) -{ - kDebug() << "change uid:" << osync_change_get_uid( change ); - kDebug() << "objtype:" << osync_change_get_objtype( change ); - kDebug() << "objform:" << osync_objformat_get_name( osync_change_get_objformat( change ) ); - - switch( osync_change_get_changetype( change ) ) { - case OSYNC_CHANGE_TYPE_ADDED: { - const Item item = createItem( change ); - osync_change_set_uid( change, QString::number( item.id() ).toLatin1() ); - osync_change_set_hash( change, QString::number( item.revision() ).toLatin1() ); - kDebug() << "ADDED:" << osync_change_get_uid( change ); - break; } - - case OSYNC_CHANGE_TYPE_MODIFIED: { - const Item item = modifyItem( change ); - osync_change_set_uid( change, QString::number( item.id() ).toLatin1() ); - osync_change_set_hash( change, QString::number( item.revision() ).toLatin1() ); - kDebug() << "MODIFIED:" << osync_change_get_uid( change ); - break; } - - case OSYNC_CHANGE_TYPE_DELETED: { - deleteItem( change ); - kDebug() << "DELETED:" << osync_change_get_uid( change ); - break; } - - case OSYNC_CHANGE_TYPE_UNMODIFIED: { - kDebug() << "UNMODIFIED"; - // should we do something here? - break; } - - default: - kDebug() << "got invalid changetype?"; - } - - osync_hashtable_update_change( m_hashtable, change ); - success(); -} - -const Item DataSink::createItem( OSyncChange *change ) -{ - Collection col = collection(); - if ( !col.isValid() ) // error handling - return Item(); - kDebug() << "cuid:" << osync_change_get_uid( change ); - - ItemCreateJob *job = new Akonadi::ItemCreateJob( createAkonadiItem( change ), col ); - - if ( !job->exec() ) - kDebug() << "creating an item failed"; - - return job->item(); // handle !job->exec in return too.. -} - -const Item DataSink::modifyItem( OSyncChange *change ) -{ - char *plain = 0; - osync_data_get_data( osync_change_get_data( change ), &plain, /*size*/0 ); - QString str = QString::fromUtf8( plain ); - - QString id = QString( osync_change_get_uid( change ) ); - Item item = fetchItem( id ); - if ( !item.isValid() ) // TODO proper error handling - return Item(); - - //event.setMimeType( "application/x-vnd.akonadi.calendar.event" ); - //Item newItem = createAkonadiItem( change ); - setPayload( &item, str ); - ItemModifyJob *modifyJob = new Akonadi::ItemModifyJob( item ); - if ( modifyJob->exec() ) { - kDebug() << "modification completed"; - return modifyJob->item(); - } else - kDebug() << "unable to modify"; - - return Item(); -} - -void DataSink::deleteItem( OSyncChange *change ) -{ - QString id = QString( osync_change_get_uid( change ) ); - Item item = fetchItem( id ); - if ( !item.isValid() ) // TODO proper error handling - return; - - kDebug() << "delete with id: " << item.id(); - /*ItemDeleteJob *job = new ItemDeleteJob( item ); - - if ( job->exec() ) { - kDebug() << "item deleted"; - } - else - kDebug() << "unable to delete item";*/ -} - -bool DataSink::setPayload( Item *item, const QString &str ) -{ - switch( m_type ) { - case Calendar: { - KCal::ICalFormat format; - KCal::Incidence *calEntry = format.fromString( str ); - - item->setMimeType( "application/x-vnd.akonadi.calendar.event" ); - item->setPayload( IncidencePtr( calEntry->clone() ) ); - - break; - } - case Contacts: { - KABC::VCardConverter converter; - KABC::Addressee vcard = converter.parseVCard( str.toUtf8() ); - kDebug() << vcard.uid() << vcard.name(); - - item->setMimeType( Addressee::mimeType() ); - item->setPayload( vcard ); - break; - } - case Notes: { - kDebug() << "notes"; - break; - } - default: - // should not happen - return false; - } - - return true; -} - -const Item DataSink::createAkonadiItem( OSyncChange *change ) -{ - char *plain = 0; - osync_data_get_data( osync_change_get_data( change ), &plain, /*size*/0 ); - QString str = QString::fromUtf8( plain ); - Akonadi::Item item; - setPayload( &item, str ); - return item; -} - -const QString DataSink::formatName() -{ - QString formatName; - switch( m_type ) { - case Calendar: - formatName = "vevent20"; - break; - case Contacts: - formatName = "vcard10"; - break; - case Notes: - formatName = "vnote10"; - break; - default: - kDebug() << "invalid datasink type"; - return QString(); - } - - return formatName; -} - -const Item DataSink::fetchItem( const QString& id ) -{ - ItemFetchJob *fetchJob = new ItemFetchJob( Item( id ) ); - fetchJob->fetchScope().fetchFullPayload(); - - if ( fetchJob->exec() ) { - foreach ( const Item &item, fetchJob->items() ) { - if ( QString::number( item.id() ) == id ) { - kDebug() << "got item"; - return item; - } - } - } - - // no such item found? - return Item(); -} - -void DataSink::syncDone() -{ - kDebug(); - OSyncError *error = 0; - osync_hashtable_save( m_hashtable, &error ); - - //TODO check for errors - success(); -} - diff -Nru kdepim-runtime-4.14.6/opensync/datasink.h kdepim-runtime-15.08.0/opensync/datasink.h --- kdepim-runtime-4.14.6/opensync/datasink.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/opensync/datasink.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 DATASINK_H -#define DATASINK_H - -#include "sinkbase.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -using namespace Akonadi; - -/** - * Base class for data sink classes, dealing with the type-independent stuff. - */ -class DataSink : public SinkBase -{ - Q_OBJECT - - public: - enum Type { Calendar = 0, Contacts, Notes }; - - DataSink( int type ); - ~DataSink(); - - bool initialize( OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncObjTypeSink *sink, OSyncError **error ); - - void getChanges(); - void commit( OSyncChange *change ); - void syncDone(); - - public slots: - void slotGetChangesFinished( KJob * ); - void slotItemsReceived( const Akonadi::Item::List & ); - - protected: - /** - * Returns the collection we are supposed to sync with. - */ - Akonadi::Collection collection() const; - - /** - * This reports the change back to opensync - */ - void reportChange( const Item& item, const QString& format ); - - /** - * Reimplement in subclass to provide data about changes to opensync. Note, that you must call DataSink::reportChange( Item, QString, int ) after you have organized data to be send to opensync. - */ - void reportChange( const Item & item ); - - /** - * Creates a new item based on the data given by opensync. - */ - const Item createItem( OSyncChange *change ); - /** - * Modified an item based on the data given by opensync. - */ - const Item modifyItem( OSyncChange *change ); - /** - * Deletes an item based on the data given by opensync. - */ - void deleteItem( OSyncChange *change ); - - private: - const Item createAkonadiItem( OSyncChange *change ); - const Item fetchItem( const QString& id ); - const QString formatName(); - bool setPayload( Item *item, const QString &str ); - - private: - OSyncHashTable *m_hashtable; - int m_type; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/opensync/sinkbase.cpp kdepim-runtime-15.08.0/opensync/sinkbase.cpp --- kdepim-runtime-4.14.6/opensync/sinkbase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/opensync/sinkbase.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,158 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 "sinkbase.h" -#include - -#define WRAP(X) \ - osync_trace( TRACE_ENTRY, "%s(%p, %p, %p)", __PRETTY_FUNCTION__, userdata, info, ctx ); \ - SinkBase *sink = reinterpret_cast( \ - osync_objtype_sink_get_userdata( osync_plugin_info_get_sink( info ) ) ); \ - sink->setContext( ctx ); \ - sink->setPluginInfo( info ); \ - sink->X; \ - osync_trace( TRACE_EXIT, "%s", __PRETTY_FUNCTION__ ); - -extern "C" -{ - -static void connect_wrapper( void *userdata, OSyncPluginInfo *info, OSyncContext *ctx ) -{ - WRAP( connect() ) -} - -static void disconnect_wrapper(void *userdata, OSyncPluginInfo *info, OSyncContext *ctx) -{ - WRAP( disconnect() ) -} - -static void get_changes_wrapper(void *userdata, OSyncPluginInfo *info, OSyncContext *ctx) -{ - WRAP( getChanges() ) -} - -static void commit_wrapper(void *userdata, OSyncPluginInfo *info, OSyncContext *ctx, OSyncChange *chg) -{ -kDebug() << "commitwrap"; - WRAP( commit( chg ) ) -} - -static void sync_done_wrapper(void *userdata, OSyncPluginInfo *info, OSyncContext *ctx) -{ - WRAP( syncDone() ) -} - -} // extern C - - -SinkBase::SinkBase( int features ) : - mContext( 0 ), - mSink( 0 ), - mPluginInfo( 0 ) -{ - mWrapedFunctions.connect = ( features & Connect ) ? connect_wrapper : 0; - mWrapedFunctions.disconnect = ( features & Disconnect ) ? disconnect_wrapper : 0; - mWrapedFunctions.get_changes = ( features & GetChanges ) ? get_changes_wrapper : 0; - mWrapedFunctions.commit = ( features & Commit ) ? commit_wrapper : 0; - mWrapedFunctions.write = ( features & Write ) ? 0 : 0; - mWrapedFunctions.committed_all = ( features & CommittedAll ) ? 0 : 0; - mWrapedFunctions.read = ( features & Read ) ? 0 : 0; - mWrapedFunctions.batch_commit = ( features & BatchCommit ) ? 0 : 0; - mWrapedFunctions.sync_done = ( features & SyncDone ) ? sync_done_wrapper : 0; -} - -SinkBase::~SinkBase() -{ - if ( mSink ) - osync_objtype_sink_unref( mSink ); -} - -void SinkBase::connect() -{ - Q_ASSERT( false ); -} - -void SinkBase::disconnect() -{ - Q_ASSERT( false ); -} - -void SinkBase::getChanges() -{ - Q_ASSERT( false ); -} - -void SinkBase::commit(OSyncChange * chg) -{ - Q_UNUSED( chg ); - Q_ASSERT( false ); -} - -void SinkBase::syncDone() -{ - Q_ASSERT( false ); -} - -void SinkBase::success() const -{ -kDebug(); - Q_ASSERT( mContext ); - osync_context_report_success( mContext ); - mContext = 0; -} - -void SinkBase::error(OSyncErrorType type, const QString &msg) const -{ -kDebug(); - Q_ASSERT( mContext ); - osync_context_report_error( mContext, type, msg.toUtf8() ); - mContext = 0; -} - -void SinkBase::warning(OSyncError * error) const -{ -kDebug(); - Q_ASSERT( mContext ); - osync_context_report_osyncwarning( mContext, error ); - osync_error_unref( &error ); -} - -void SinkBase::wrapSink(OSyncObjTypeSink * sink) -{ -kDebug(); - Q_ASSERT( sink ); - Q_ASSERT( mSink == 0 ); - mSink = sink; - - osync_objtype_sink_set_functions( sink, mWrapedFunctions, this ); -} - -void SinkBase::setPluginInfo(OSyncPluginInfo * info) -{ - Q_ASSERT( mPluginInfo == 0 || mPluginInfo == info ); - mPluginInfo = info; -} - -void SinkBase::setContext(OSyncContext * context) -{ - Q_ASSERT( mContext == 0 || context == mContext ); - // ### do I need to ref() that here? and then probably deref() the old one somewhere above? - mContext = context; -} - diff -Nru kdepim-runtime-4.14.6/opensync/sinkbase.h kdepim-runtime-15.08.0/opensync/sinkbase.h --- kdepim-runtime-4.14.6/opensync/sinkbase.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/opensync/sinkbase.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 SINKBASE_H -#define SINKBASE_H - -#include - -#include -#include -#include -#include -#include - -/** - * Base class providing wraping of OSyncObjTypeSink. - */ -class SinkBase : public QObject -{ - Q_OBJECT - public: - enum Feature { - Connect = 1, - Disconnect = 2, - GetChanges = 4, - Commit = 8, - Write = 16, - CommittedAll = 32, - Read = 64, - BatchCommit = 128, - SyncDone = 256 - }; - - SinkBase( int features ); - virtual ~SinkBase(); - - virtual void connect(); - virtual void disconnect(); - virtual void getChanges(); - virtual void commit( OSyncChange *chg ); - virtual void syncDone(); - - OSyncContext* context() const { return mContext; } - void setContext( OSyncContext *context ); - - OSyncPluginInfo *pluginInfo() const { return mPluginInfo; } - void setPluginInfo( OSyncPluginInfo *info ); - - protected: - void success() const; - void error( OSyncErrorType type, const QString &msg ) const; - void warning( OSyncError *error ) const; - void wrapSink( OSyncObjTypeSink *sink ); - - OSyncObjTypeSink* sink() const { return mSink; } - - private: - OSyncObjTypeSinkFunctions mWrapedFunctions; - mutable OSyncContext *mContext; - OSyncObjTypeSink *mSink; - OSyncPluginInfo *mPluginInfo; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_addressee.cpp kdepim-runtime-15.08.0/plugins/akonadi_serializer_addressee.cpp --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_addressee.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_addressee.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,249 +19,267 @@ #include "akonadi_serializer_addressee.h" -#include -#include -#include - -#include -#include - +#include +#include +#include + +#include +#include +#include #include using namespace Akonadi; //// ItemSerializerPlugin interface -bool SerializerPluginAddressee::deserialize( Item& item, const QByteArray& label, QIODevice& data, int version ) +bool SerializerPluginAddressee::deserialize(Item &item, const QByteArray &label, QIODevice &data, int version) { - Q_UNUSED( version ); + Q_UNUSED(version); - KABC::Addressee addr; - if ( label == Item::FullPayload ) { - addr = m_converter.parseVCard( data.readAll() ); - } else if ( label == Akonadi::ContactPart::Standard ) { - addr = m_converter.parseVCard( data.readAll() ); + KContacts::Addressee addr; + if (label == Item::FullPayload) { + addr = m_converter.parseVCard(data.readAll()); + } else if (label == Akonadi::ContactPart::Standard) { + addr = m_converter.parseVCard(data.readAll()); // remove pictures and sound - addr.setPhoto( KABC::Picture() ); - addr.setLogo( KABC::Picture() ); - addr.setSound( KABC::Sound() ); - } else if ( label == Akonadi::ContactPart::Lookup ) { - const KABC::Addressee temp = m_converter.parseVCard( data.readAll() ); + addr.setPhoto(KContacts::Picture()); + addr.setLogo(KContacts::Picture()); + addr.setSound(KContacts::Sound()); + } else if (label == Akonadi::ContactPart::Lookup) { + const KContacts::Addressee temp = m_converter.parseVCard(data.readAll()); // copy only uid, name and email addresses - addr.setUid( temp.uid() ); - addr.setPrefix( temp.prefix() ); - addr.setGivenName( temp.givenName() ); - addr.setAdditionalName( temp.additionalName() ); - addr.setFamilyName( temp.familyName() ); - addr.setSuffix( temp.suffix() ); - addr.setEmails( temp.emails() ); + addr.setUid(temp.uid()); + addr.setPrefix(temp.prefix()); + addr.setGivenName(temp.givenName()); + addr.setAdditionalName(temp.additionalName()); + addr.setFamilyName(temp.familyName()); + addr.setSuffix(temp.suffix()); + addr.setEmails(temp.emails()); } else { return false; } - if ( !addr.isEmpty() ) { - item.setPayload( addr ); + if (!addr.isEmpty()) { + item.setPayload(addr); } else { - kWarning( 5261 ) << "Empty addressee object!"; + qWarning() << "Empty addressee object!"; } return true; } -void SerializerPluginAddressee::serialize( const Item& item, const QByteArray& label, QIODevice& data, int &version ) +void SerializerPluginAddressee::serialize(const Item &item, const QByteArray &label, QIODevice &data, int &version) { - Q_UNUSED( version ); + Q_UNUSED(version); - if ( label != Item::FullPayload && label != Akonadi::ContactPart::Standard && label != Akonadi::ContactPart::Lookup ) + if (label != Item::FullPayload && label != Akonadi::ContactPart::Standard && label != Akonadi::ContactPart::Lookup) { return; + } - if ( !item.hasPayload() ) + if (!item.hasPayload()) { return; + } - KABC::Addressee addr, temp; + KContacts::Addressee addr, temp; - temp = item.payload(); + temp = item.payload(); - if ( label == Item::FullPayload ) { + if (label == Item::FullPayload) { addr = temp; - } else if ( label == Akonadi::ContactPart::Standard ) { + } else if (label == Akonadi::ContactPart::Standard) { addr = temp; // remove pictures and sound - addr.setPhoto( KABC::Picture() ); - addr.setLogo( KABC::Picture() ); - addr.setSound( KABC::Sound() ); - } else if ( label == Akonadi::ContactPart::Lookup ) { + addr.setPhoto(KContacts::Picture()); + addr.setLogo(KContacts::Picture()); + addr.setSound(KContacts::Sound()); + } else if (label == Akonadi::ContactPart::Lookup) { // copy only uid, name and email addresses - addr.setUid( temp.uid() ); - addr.setPrefix( temp.prefix() ); - addr.setGivenName( temp.givenName() ); - addr.setAdditionalName( temp.additionalName() ); - addr.setFamilyName( temp.familyName() ); - addr.setSuffix( temp.suffix() ); - addr.setEmails( temp.emails() ); + addr.setUid(temp.uid()); + addr.setPrefix(temp.prefix()); + addr.setGivenName(temp.givenName()); + addr.setAdditionalName(temp.additionalName()); + addr.setFamilyName(temp.familyName()); + addr.setSuffix(temp.suffix()); + addr.setEmails(temp.emails()); } - data.write( m_converter.createVCard( addr ) ); + data.write(m_converter.createVCard(addr)); } //// DifferencesAlgorithmInterface interface -static bool compareString( const QString &left, const QString &right ) +static bool compareString(const QString &left, const QString &right) { - if ( left.isEmpty() && right.isEmpty() ) - return true; - else - return left == right; + if (left.isEmpty() && right.isEmpty()) { + return true; + } else { + return left == right; + } } -static QString toString( const KABC::PhoneNumber &phoneNumber ) +static QString toString(const KContacts::PhoneNumber &phoneNumber) { - return phoneNumber.number(); + return phoneNumber.number(); } -static QString toString( const KABC::Address &address ) +static QString toString(const KContacts::Address &address) { - return address.toString(); + return address.toString(); } -static QString toString( const QString &value ) +static QString toString(const QString &value) { - return value; + return value; } template -static void compareList( Akonadi::AbstractDifferencesReporter *reporter, const QString &id, const QList &left, const QList &right ) +static void compareList(Akonadi::AbstractDifferencesReporter *reporter, const QString &id, const QList &left, const QList &right) { - for ( int i = 0; i < left.count(); ++i ) { - if ( !right.contains( left[ i ] ) ) - reporter->addProperty( AbstractDifferencesReporter::AdditionalLeftMode, id, toString( left[ i ] ), QString() ); - } + for (int i = 0; i < left.count(); ++i) { + if (!right.contains(left[ i ])) { + reporter->addProperty(AbstractDifferencesReporter::AdditionalLeftMode, id, toString(left[ i ]), QString()); + } + } - for ( int i = 0; i < right.count(); ++i ) { - if ( !left.contains( right[ i ] ) ) - reporter->addProperty( AbstractDifferencesReporter::AdditionalRightMode, id, QString(), toString( right[ i ] ) ); - } + for (int i = 0; i < right.count(); ++i) { + if (!left.contains(right[ i ])) { + reporter->addProperty(AbstractDifferencesReporter::AdditionalRightMode, id, QString(), toString(right[ i ])); + } + } } -void SerializerPluginAddressee::compare( Akonadi::AbstractDifferencesReporter *reporter, - const Akonadi::Item &leftItem, - const Akonadi::Item &rightItem ) +template +static void compareVector(Akonadi::AbstractDifferencesReporter *reporter, const QString &id, const QVector &left, const QVector &right) { - Q_ASSERT( reporter ); - Q_ASSERT( leftItem.hasPayload() ); - Q_ASSERT( rightItem.hasPayload() ); - - reporter->setLeftPropertyValueTitle( i18n( "Changed Contact" ) ); - reporter->setRightPropertyValueTitle( i18n( "Conflicting Contact" ) ); - - const KABC::Addressee leftContact = leftItem.payload(); - const KABC::Addressee rightContact = rightItem.payload(); - - if ( !compareString( leftContact.uid(), rightContact.uid() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::uidLabel(), - leftContact.uid(), rightContact.uid() ); - - if ( !compareString( leftContact.name(), rightContact.name() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::nameLabel(), - leftContact.name(), rightContact.name() ); - - if ( !compareString( leftContact.formattedName(), rightContact.formattedName() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::formattedNameLabel(), - leftContact.formattedName(), rightContact.formattedName() ); - - if ( !compareString( leftContact.familyName(), rightContact.familyName() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::familyNameLabel(), - leftContact.familyName(), rightContact.familyName() ); - - if ( !compareString( leftContact.givenName(), rightContact.givenName() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::givenNameLabel(), - leftContact.givenName(), rightContact.givenName() ); - - if ( !compareString( leftContact.additionalName(), rightContact.additionalName() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::additionalNameLabel(), - leftContact.additionalName(), rightContact.additionalName() ); - - if ( !compareString( leftContact.prefix(), rightContact.prefix() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::prefixLabel(), - leftContact.prefix(), rightContact.prefix() ); - - if ( !compareString( leftContact.suffix(), rightContact.suffix() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::suffixLabel(), - leftContact.suffix(), rightContact.suffix() ); - - if ( !compareString( leftContact.nickName(), rightContact.nickName() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::nickNameLabel(), - leftContact.nickName(), rightContact.nickName() ); - - if ( leftContact.birthday() != rightContact.birthday() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::birthdayLabel(), - leftContact.birthday().toString(), rightContact.birthday().toString() ); - - if ( !compareString( leftContact.mailer(), rightContact.mailer() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::mailerLabel(), - leftContact.mailer(), rightContact.mailer() ); - - if ( leftContact.timeZone() != rightContact.timeZone() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::timeZoneLabel(), - leftContact.timeZone().toString(), rightContact.timeZone().toString() ); - - if ( leftContact.geo() != rightContact.geo() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::geoLabel(), - leftContact.geo().toString(), rightContact.geo().toString() ); - - if ( !compareString( leftContact.title(), rightContact.title() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::titleLabel(), - leftContact.title(), rightContact.title() ); - - if ( !compareString( leftContact.role(), rightContact.role() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::roleLabel(), - leftContact.role(), rightContact.role() ); - - if ( !compareString( leftContact.organization(), rightContact.organization() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::organizationLabel(), - leftContact.organization(), rightContact.organization() ); - - if ( !compareString( leftContact.note(), rightContact.note() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::noteLabel(), - leftContact.note(), rightContact.note() ); - - if ( !compareString( leftContact.productId(), rightContact.productId() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::productIdLabel(), - leftContact.productId(), rightContact.productId() ); - - if ( !compareString( leftContact.sortString(), rightContact.sortString() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::sortStringLabel(), - leftContact.sortString(), rightContact.sortString() ); + for (int i = 0; i < left.count(); ++i) { + if (!right.contains(left[ i ])) { + reporter->addProperty(AbstractDifferencesReporter::AdditionalLeftMode, id, toString(left[ i ]), QString()); + } + } - if ( leftContact.secrecy() != rightContact.secrecy() ) { - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::secrecyLabel(), - leftContact.secrecy().toString(), rightContact.secrecy().toString() ); - } + for (int i = 0; i < right.count(); ++i) { + if (!left.contains(right[ i ])) { + reporter->addProperty(AbstractDifferencesReporter::AdditionalRightMode, id, QString(), toString(right[ i ])); + } + } +} - if ( leftContact.url() != rightContact.url() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, KABC::Addressee::urlLabel(), - leftContact.url().prettyUrl(), rightContact.url().prettyUrl() ); +void SerializerPluginAddressee::compare(Akonadi::AbstractDifferencesReporter *reporter, + const Akonadi::Item &leftItem, + const Akonadi::Item &rightItem) +{ + Q_ASSERT(reporter); + Q_ASSERT(leftItem.hasPayload()); + Q_ASSERT(rightItem.hasPayload()); + + reporter->setLeftPropertyValueTitle(i18n("Changed Contact")); + reporter->setRightPropertyValueTitle(i18n("Conflicting Contact")); + + const KContacts::Addressee leftContact = leftItem.payload(); + const KContacts::Addressee rightContact = rightItem.payload(); + + if (!compareString(leftContact.uid(), rightContact.uid())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::uidLabel(), + leftContact.uid(), rightContact.uid()); + + if (!compareString(leftContact.name(), rightContact.name())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::nameLabel(), + leftContact.name(), rightContact.name()); + + if (!compareString(leftContact.formattedName(), rightContact.formattedName())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::formattedNameLabel(), + leftContact.formattedName(), rightContact.formattedName()); + + if (!compareString(leftContact.familyName(), rightContact.familyName())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::familyNameLabel(), + leftContact.familyName(), rightContact.familyName()); + + if (!compareString(leftContact.givenName(), rightContact.givenName())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::givenNameLabel(), + leftContact.givenName(), rightContact.givenName()); + + if (!compareString(leftContact.additionalName(), rightContact.additionalName())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::additionalNameLabel(), + leftContact.additionalName(), rightContact.additionalName()); + + if (!compareString(leftContact.prefix(), rightContact.prefix())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::prefixLabel(), + leftContact.prefix(), rightContact.prefix()); + + if (!compareString(leftContact.suffix(), rightContact.suffix())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::suffixLabel(), + leftContact.suffix(), rightContact.suffix()); + + if (!compareString(leftContact.nickName(), rightContact.nickName())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::nickNameLabel(), + leftContact.nickName(), rightContact.nickName()); + + if (leftContact.birthday() != rightContact.birthday()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::birthdayLabel(), + leftContact.birthday().toString(), rightContact.birthday().toString()); + + if (!compareString(leftContact.mailer(), rightContact.mailer())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::mailerLabel(), + leftContact.mailer(), rightContact.mailer()); + + if (leftContact.timeZone() != rightContact.timeZone()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::timeZoneLabel(), + leftContact.timeZone().toString(), rightContact.timeZone().toString()); + + if (leftContact.geo() != rightContact.geo()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::geoLabel(), + leftContact.geo().toString(), rightContact.geo().toString()); + + if (!compareString(leftContact.title(), rightContact.title())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::titleLabel(), + leftContact.title(), rightContact.title()); + + if (!compareString(leftContact.role(), rightContact.role())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::roleLabel(), + leftContact.role(), rightContact.role()); + + if (!compareString(leftContact.organization(), rightContact.organization())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::organizationLabel(), + leftContact.organization(), rightContact.organization()); + + if (!compareString(leftContact.note(), rightContact.note())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::noteLabel(), + leftContact.note(), rightContact.note()); + + if (!compareString(leftContact.productId(), rightContact.productId())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::productIdLabel(), + leftContact.productId(), rightContact.productId()); + + if (!compareString(leftContact.sortString(), rightContact.sortString())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::sortStringLabel(), + leftContact.sortString(), rightContact.sortString()); + + if (leftContact.secrecy() != rightContact.secrecy()) { + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::secrecyLabel(), + leftContact.secrecy().toString(), rightContact.secrecy().toString()); + } - compareList( reporter, i18n( "Emails" ), leftContact.emails(), rightContact.emails() ); - compareList( reporter, i18n( "Phone Numbers" ), leftContact.phoneNumbers(), rightContact.phoneNumbers() ); - compareList( reporter, i18n( "Addresses" ), leftContact.addresses(), rightContact.addresses() ); + if (leftContact.url() != rightContact.url()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::urlLabel(), + leftContact.url().url().toDisplayString(), rightContact.url().url().toDisplayString()); + + compareList(reporter, i18n("Emails"), leftContact.emails(), rightContact.emails()); + compareVector(reporter, i18n("Phone Numbers"), leftContact.phoneNumbers(), rightContact.phoneNumbers()); + compareVector(reporter, i18n("Addresses"), leftContact.addresses(), rightContact.addresses()); - //TODO: logo/photo/custom entries + //TODO: logo/photo/custom entries } //// GidExtractorInterface -QString SerializerPluginAddressee::extractGid( const Item& item ) const +QString SerializerPluginAddressee::extractGid(const Item &item) const { - if ( !item.hasPayload() ) { - return QString(); - } - return item.payload().uid(); + if (!item.hasPayload()) { + return QString(); + } + return item.payload().uid(); } - -Q_EXPORT_PLUGIN2( akonadi_serializer_addressee, Akonadi::SerializerPluginAddressee ) - diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_addressee.desktop kdepim-runtime-15.08.0/plugins/akonadi_serializer_addressee.desktop --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_addressee.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_addressee.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -96,6 +96,6 @@ [Plugin] Type=text/vcard,text/directory -X-Akonadi-Class=legacy;default;KABC::Addressee; +X-Akonadi-Class=legacy;default;KContacts::Addressee; X-KDE-Library=akonadi_serializer_addressee X-KDE-ClassName=Akonadi::SerializerPluginAddressee diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_addressee.h kdepim-runtime-15.08.0/plugins/akonadi_serializer_addressee.h --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_addressee.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_addressee.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,35 +22,36 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include -namespace Akonadi { +namespace Akonadi +{ class SerializerPluginAddressee : public QObject, - public ItemSerializerPlugin, - public DifferencesAlgorithmInterface, - public GidExtractorInterface + public ItemSerializerPlugin, + public DifferencesAlgorithmInterface, + public GidExtractorInterface { Q_OBJECT - Q_INTERFACES( Akonadi::ItemSerializerPlugin ) - Q_INTERFACES( Akonadi::DifferencesAlgorithmInterface ) - Q_INTERFACES( Akonadi::GidExtractorInterface ) - - public: - bool deserialize( Item& item, const QByteArray& label, QIODevice& data, int version ); - void serialize( const Item& item, const QByteArray& label, QIODevice& data, int &version ); - - void compare( Akonadi::AbstractDifferencesReporter *reporter, - const Akonadi::Item &leftItem, - const Akonadi::Item &rightItem ); + Q_INTERFACES(Akonadi::ItemSerializerPlugin) + Q_INTERFACES(Akonadi::DifferencesAlgorithmInterface) + Q_INTERFACES(Akonadi::GidExtractorInterface) + Q_PLUGIN_METADATA(IID "org.kde.akonadi.SerializerPluginAddressee") +public: + bool deserialize(Item &item, const QByteArray &label, QIODevice &data, int version) Q_DECL_OVERRIDE; + void serialize(const Item &item, const QByteArray &label, QIODevice &data, int &version) Q_DECL_OVERRIDE; + + void compare(Akonadi::AbstractDifferencesReporter *reporter, + const Akonadi::Item &leftItem, + const Akonadi::Item &rightItem) Q_DECL_OVERRIDE; - QString extractGid( const Item& item ) const; + QString extractGid(const Item &item) const Q_DECL_OVERRIDE; - private: - KABC::VCardConverter m_converter; +private: + KContacts::VCardConverter m_converter; }; } diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_bookmark.cpp kdepim-runtime-15.08.0/plugins/akonadi_serializer_bookmark.cpp --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_bookmark.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_bookmark.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -/* - Copyright (c) 2007 Bruno Virlet - - 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 "akonadi_serializer_bookmark.h" - -#include -#include -#include -#include - -#include - - -using namespace Akonadi; - -#ifndef KIO_KBOOKMARK_METATYPE_DEFINED -Q_DECLARE_METATYPE( KBookmark ) -#endif - -bool SerializerPluginBookmark::deserialize( Item& item, const QByteArray& label, QIODevice& data, int version ) -{ - Q_UNUSED( version ); - - if ( label != Item::FullPayload ) - return false; - - KBookmark bk; - QMimeData *mimeData = new QMimeData(); - mimeData->setData( QString::fromLatin1( "application/x-xbel" ), data.readAll() ); - QDomDocument doc; - KBookmark::List bkl = KBookmark::List::fromMimeData( mimeData, doc ); - - if ( !bkl.isEmpty() ) - item.setPayload( bkl[0] ); - return true; -} - -void SerializerPluginBookmark::serialize( const Item& item, const QByteArray& label, QIODevice& data, int &version ) -{ - Q_UNUSED( version ); - - if ( label != Item::FullPayload ) - return; - - if ( item.mimeType() != QString::fromLatin1( "application/x-xbel" ) ) - return; - - KBookmark bk; - if ( item.hasPayload() ) - bk = item.payload(); - - QMimeData *mimeData = new QMimeData(); - bk.populateMimeData( mimeData ); - - data.write( mimeData->data( QString::fromLatin1( "application/x-xbel" ) ) ); - -} - -Q_EXPORT_PLUGIN2( akonadi_serializer_bookmark, SerializerPluginBookmark ) - diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_bookmark.desktop kdepim-runtime-15.08.0/plugins/akonadi_serializer_bookmark.desktop --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_bookmark.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_bookmark.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -[Misc] -Name=Bookmark serializer -Name[ar]=مسلسل العلامات -Name[bs]=Serializator oznaka -Name[ca]=Serialitzador d'adreces d'interès -Name[ca@valencia]=Serialitzador de punts -Name[da]=Serieordning af bogmærker -Name[de]=Lesezeichen-Serialisierung -Name[el]=Σειριακοποιητής σελιδοδεικτών -Name[en_GB]=Bookmark serialiser -Name[es]=Serializador de marcadores -Name[et]=Järjehoidjate jadasti -Name[fi]=Kirjanmerkkiserialisoija -Name[fr]=Sérialiseur de signets -Name[ga]=Srathóir leabharmharcanna -Name[gl]=Serializador de marcadores -Name[hu]=Könyvjelzőkezelő -Name[ia]=Divulgator partial de favoritos -Name[it]=Serializzatore dei segnalibri -Name[ja]=ブックマーク用シリアライザ -Name[kk]=Бетбелгі тізбектеуіші -Name[km]=ម៉ាស៊ីន​បោះពុម្ព​ចំណាំ -Name[ko]=책갈피 시리얼라이저 -Name[lt]=Žymelių serializatorius -Name[lv]=Grāmatzīmju serializētājs -Name[nb]=Bokmerkeserialisator -Name[nds]=Leesteken-Reegmoduul -Name[nl]=Bladwijzeradministratie -Name[nn]=Bokmerkeserialisator -Name[pa]=ਬੁੱਕਮਾਰਕ ਸੀਰੀਲਾਈਜ਼ਰ -Name[pl]=Szeregowanie zakładek -Name[pt]=Serializador do favorito -Name[pt_BR]=Serializador de favoritos -Name[ro]=Serializator semne de carte -Name[ru]=Сохранение закладок -Name[sk]=Serializátor záložiek -Name[sl]=Razvrščevalnik zaznamkov v zaporedje -Name[sr]=Серијализатор обележивача -Name[sr@ijekavian]=Серијализатор обиљеживача -Name[sr@ijekavianlatin]=Serijalizator obilježivača -Name[sr@latin]=Serijalizator obeleživača -Name[sv]=Bokmärkesserialisering -Name[tr]=Yer imi sıralandırıcı -Name[uk]=Серіалізатор закладок -Name[x-test]=xxBookmark serializerxx -Name[zh_CN]=书签序列转换器 -Name[zh_TW]=書籤序列器 -Comment=An Akonadi serializer plugin for bookmark objects -Comment[ar]=ملحق مسلسل اكوندا لكائنات العلامة -Comment[bs]=Akonadi dodatak serializatora za oznacene objekte -Comment[ca]=Un connector de serialització de l'Akonadi pels objectes d'adreces d'interès -Comment[ca@valencia]=Un connector de serialització de l'Akonadi pels objectes punts -Comment[da]=Et Akonadi-plugin til serieordning af bogmærkeobjekter -Comment[de]=Akonadi-Modul zur Serialisierung von Lesezeichen -Comment[el]=Ένα πρόσθετο σειριακοποιητή Akonadi για αντικείμενα σελιδοδεικτών -Comment[en_GB]=An Akonadi serialiser plugin for bookmark objects -Comment[es]=Un complemento serializador de Akonadi para objetos marcador -Comment[et]=Akonadi järjehoidjaobjektide jadastamisplugin -Comment[fi]=Akonadi-serialisoijaliitännäinen kirjanmerkkiobjekteille -Comment[fr]=Un module externe Akonadi pour la sérialisation des signets -Comment[ga]=Breiseán srathóra Akonadi le haghaidh leabharmharcanna -Comment[gl]=Engadido de serialización do Akonadi para obxectos marcador -Comment[hu]=Akonadi-modul könyvjelzők kezeléséhez -Comment[ia]=Un plug-in pro divulgator partial de Akonadi pro objectos favorite -Comment[it]=Un'estensione di Akonadi per la serializzazione dei segnalibri -Comment[ja]=ブックマークオブジェクトのための Akonadi シリアライザプラグイン -Comment[kk]=Akonadi бетбелгі нысандарының тізбектеуіш плагині -Comment[km]=កម្មវិធី​ជំនួយ​កម្មវិធី​បោះពុម្ព Akonadi សម្រាប់​វត្ថុ​ចំណាំ -Comment[ko]=책갈피 객체를 위한 Akonadi 시리얼라이저 플러그인 -Comment[lt]=Akonadi serializatoriaus įskiepis žymelių objektams -Comment[lv]=Akonadi grāmatzīmju serializēšanas spraudnis -Comment[nb]=Et Akonadi programtillegg for serialisering av bokmerke-objekter -Comment[nds]=Akonadi-Inreegmoduul för Leestekens -Comment[nl]=Een administratieplug-in voor Akonadi voor bladwijzers -Comment[nn]=Eit Akonadi-serialisatortillegg for bokmerkeobjekt -Comment[pa]=ਬੁੱਕਮਾਰਕ ਆਬਜੈਕਟਾਂ ਲਈ ਅਕੌਂਡੀ ਸੀਰੀਲਾਈਜ਼ਰ ਪਲੱਗਇਨ -Comment[pl]=Wtyczka Akonadi do szeregowania obiektów zakładek -Comment[pt]=Um 'plugin' de serialização do Akonadi para os objectos de favoritos -Comment[pt_BR]=Um plugin de serialização do Akonadi para os objetos dos favoritos -Comment[ro]=Modul de serializare Akonadi pentru obiecte „semn de carte” -Comment[ru]=Модуль сохранения закладок для Akonadi -Comment[sk]=Plugin serializátora Akonadi pre objekty záložiek -Comment[sl]=Akonadijev vstavek za razvrščanje predmetov zaznamkov v zaporedje -Comment[sr]=Аконадијев прикључак серијализатора за објекте обележивача -Comment[sr@ijekavian]=Аконадијев прикључак серијализатора за објекте обиљеживача -Comment[sr@ijekavianlatin]=Akonadijev priključak serijalizatora za objekte obilježivača -Comment[sr@latin]=Akonadijev priključak serijalizatora za objekte obeleživača -Comment[sv]=Ett insticksprogram till Akonadi för serialisering av bokmärkesobjekt -Comment[tr]=Yer imi nesneleri için bir Akonadi sıralandırıcısı -Comment[uk]=Додаток серіалізації Akonadi для об'єктів закладок -Comment[x-test]=xxAn Akonadi serializer plugin for bookmark objectsxx -Comment[zh_CN]=对书签对象进行序列转换的 Akonadi 插件 -Comment[zh_TW]=書籤物件的 Akonadi 序列器外掛程式 - -[Plugin] -Type=application/x-xbel -X-Akonadi-Class=legacy;default;KBookmark; -X-KDE-Library=akonadi_serializer_bookmark -X-KDE-ClassName=Akonadi::SerializerPluginBookmark diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_bookmark.h kdepim-runtime-15.08.0/plugins/akonadi_serializer_bookmark.h --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_bookmark.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_bookmark.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -/* - Copyright (c) 2007 Bruno Virlet - - 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_SERIALIZER_BOOKMARK_H__ -#define __AKONADI_SERIALIZER_BOOKMARK_H__ - -#include - -#include - -class QIODevice; -class QString; - -namespace Akonadi { - -class Item; - -class SerializerPluginBookmark : public QObject, public ItemSerializerPlugin -{ - Q_OBJECT - Q_INTERFACES( Akonadi::ItemSerializerPlugin ) - -public: - bool deserialize( Item& item, const QByteArray& label, QIODevice& data, int version ); - void serialize( const Item& item, const QByteArray& label, QIODevice& data, int &version ); -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_contactgroup.cpp kdepim-runtime-15.08.0/plugins/akonadi_serializer_contactgroup.cpp --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_contactgroup.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_contactgroup.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,14 +19,14 @@ #include "akonadi_serializer_contactgroup.h" -#include -#include -#include -#include - -#include -#include -#include +#include +#include +#include +#include + +#include +#include +#include #include @@ -34,101 +34,104 @@ //// ItemSerializerPlugin interface -bool SerializerPluginContactGroup::deserialize( Item& item, const QByteArray& label, QIODevice& data, int version ) +bool SerializerPluginContactGroup::deserialize(Item &item, const QByteArray &label, QIODevice &data, int version) { - Q_UNUSED( label ); - Q_UNUSED( version ); + Q_UNUSED(label); + Q_UNUSED(version); - KABC::ContactGroup contactGroup; + KContacts::ContactGroup contactGroup; - if ( !KABC::ContactGroupTool::convertFromXml( &data, contactGroup ) ) { - // TODO: error reporting - return false; - } + if (!KContacts::ContactGroupTool::convertFromXml(&data, contactGroup)) { + // TODO: error reporting + return false; + } - item.setPayload( contactGroup ); + item.setPayload(contactGroup); - return true; + return true; } -void SerializerPluginContactGroup::serialize( const Item& item, const QByteArray& label, QIODevice& data, int &version ) +void SerializerPluginContactGroup::serialize(const Item &item, const QByteArray &label, QIODevice &data, int &version) { - Q_UNUSED( label ); - Q_UNUSED( version ); + Q_UNUSED(label); + Q_UNUSED(version); - if ( !item.hasPayload() ) - return; + if (!item.hasPayload()) { + return; + } - KABC::ContactGroupTool::convertToXml( item.payload(), &data ); + KContacts::ContactGroupTool::convertToXml(item.payload(), &data); } //// DifferencesAlgorithmInterface interface -static bool compareString( const QString &left, const QString &right ) +static bool compareString(const QString &left, const QString &right) { - if ( left.isEmpty() && right.isEmpty() ) - return true; - else - return left == right; + if (left.isEmpty() && right.isEmpty()) { + return true; + } else { + return left == right; + } } -static QString toString( const KABC::Addressee &contact ) +static QString toString(const KContacts::Addressee &contact) { - return contact.fullEmail(); + return contact.fullEmail(); } template -static void compareList( AbstractDifferencesReporter *reporter, const QString &id, const QList &left, const QList &right ) +static void compareVector(AbstractDifferencesReporter *reporter, const QString &id, const QVector &left, const QVector &right) { - for ( int i = 0; i < left.count(); ++i ) { - if ( !right.contains( left[ i ] ) ) - reporter->addProperty( AbstractDifferencesReporter::AdditionalLeftMode, id, toString( left[ i ] ), QString() ); - } + for (int i = 0; i < left.count(); ++i) { + if (!right.contains(left[ i ])) { + reporter->addProperty(AbstractDifferencesReporter::AdditionalLeftMode, id, toString(left[ i ]), QString()); + } + } - for ( int i = 0; i < right.count(); ++i ) { - if ( !left.contains( right[ i ] ) ) - reporter->addProperty( AbstractDifferencesReporter::AdditionalRightMode, id, QString(), toString( right[ i ] ) ); - } + for (int i = 0; i < right.count(); ++i) { + if (!left.contains(right[ i ])) { + reporter->addProperty(AbstractDifferencesReporter::AdditionalRightMode, id, QString(), toString(right[ i ])); + } + } } -void SerializerPluginContactGroup::compare( Akonadi::AbstractDifferencesReporter *reporter, - const Akonadi::Item &leftItem, - const Akonadi::Item &rightItem ) +void SerializerPluginContactGroup::compare(Akonadi::AbstractDifferencesReporter *reporter, + const Akonadi::Item &leftItem, + const Akonadi::Item &rightItem) { - Q_ASSERT( reporter ); - Q_ASSERT( leftItem.hasPayload() ); - Q_ASSERT( rightItem.hasPayload() ); + Q_ASSERT(reporter); + Q_ASSERT(leftItem.hasPayload()); + Q_ASSERT(rightItem.hasPayload()); - reporter->setLeftPropertyValueTitle( i18n( "Changed Contact Group" ) ); - reporter->setRightPropertyValueTitle( i18n( "Conflicting Contact Group" ) ); + reporter->setLeftPropertyValueTitle(i18n("Changed Contact Group")); + reporter->setRightPropertyValueTitle(i18n("Conflicting Contact Group")); - const KABC::ContactGroup leftContactGroup = leftItem.payload(); - const KABC::ContactGroup rightContactGroup = rightItem.payload(); + const KContacts::ContactGroup leftContactGroup = leftItem.payload(); + const KContacts::ContactGroup rightContactGroup = rightItem.payload(); - if ( !compareString( leftContactGroup.name(), rightContactGroup.name() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Name" ), - leftContactGroup.name(), rightContactGroup.name() ); + if (!compareString(leftContactGroup.name(), rightContactGroup.name())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Name"), + leftContactGroup.name(), rightContactGroup.name()); - // using job->exec() is ok here, not a hot path - Akonadi::ContactGroupExpandJob *leftJob = new Akonadi::ContactGroupExpandJob( leftContactGroup ); - leftJob->exec(); + // using job->exec() is ok here, not a hot path + Akonadi::ContactGroupExpandJob *leftJob = new Akonadi::ContactGroupExpandJob(leftContactGroup); + leftJob->exec(); - Akonadi::ContactGroupExpandJob *rightJob = new Akonadi::ContactGroupExpandJob( rightContactGroup ); - rightJob->exec(); + Akonadi::ContactGroupExpandJob *rightJob = new Akonadi::ContactGroupExpandJob(rightContactGroup); + rightJob->exec(); - compareList( reporter, i18n( "Member" ), leftJob->contacts(), rightJob->contacts() ); + compareVector(reporter, i18n("Member"), leftJob->contacts(), rightJob->contacts()); } //// GidExtractorInterface -QString SerializerPluginContactGroup::extractGid( const Item &item ) const +QString SerializerPluginContactGroup::extractGid(const Item &item) const { - if ( !item.hasPayload() ) { - return QString(); - } - return item.payload().id(); + if (!item.hasPayload()) { + return QString(); + } + return item.payload().id(); } -Q_EXPORT_PLUGIN2( akonadi_serializer_contactgroup, Akonadi::SerializerPluginContactGroup ) +//Q_EXPORT_PLUGIN2( akonadi_serializer_contactgroup, Akonadi::SerializerPluginContactGroup ) -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_contactgroup.desktop kdepim-runtime-15.08.0/plugins/akonadi_serializer_contactgroup.desktop --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_contactgroup.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_contactgroup.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -94,6 +94,6 @@ [Plugin] Type=application/x-vnd.kde.contactgroup -X-Akonadi-Class=legacy;default;KABC::ContactGroup; +X-Akonadi-Class=legacy;default;KContacts::ContactGroup; X-KDE-Library=akonadi_serializer_contactgroup X-KDE-ClassName=Akonadi::SerializerPluginContactGroup diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_contactgroup.h kdepim-runtime-15.08.0/plugins/akonadi_serializer_contactgroup.h --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_contactgroup.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_contactgroup.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,37 +22,37 @@ #include -#include -#include -#include +#include +#include +#include -namespace Akonadi { +namespace Akonadi +{ /** * @since 4.2 */ class SerializerPluginContactGroup : public QObject, - public ItemSerializerPlugin, - public DifferencesAlgorithmInterface, - public GidExtractorInterface + public ItemSerializerPlugin, + public DifferencesAlgorithmInterface, + public GidExtractorInterface { - Q_OBJECT - Q_INTERFACES( Akonadi::ItemSerializerPlugin ) - Q_INTERFACES( Akonadi::DifferencesAlgorithmInterface ) - Q_INTERFACES( Akonadi::GidExtractorInterface ) - - public: - bool deserialize( Item& item, const QByteArray& label, QIODevice& data, int version ); - void serialize( const Item& item, const QByteArray& label, QIODevice& data, int &version ); - - void compare( Akonadi::AbstractDifferencesReporter *reporter, - const Akonadi::Item &leftItem, - const Akonadi::Item &rightItem ); + Q_OBJECT + Q_INTERFACES(Akonadi::ItemSerializerPlugin) + Q_INTERFACES(Akonadi::DifferencesAlgorithmInterface) + Q_INTERFACES(Akonadi::GidExtractorInterface) + Q_PLUGIN_METADATA(IID "org.kde.akonadi.SerializerPluginContactGroup") +public: + bool deserialize(Item &item, const QByteArray &label, QIODevice &data, int version) Q_DECL_OVERRIDE; + void serialize(const Item &item, const QByteArray &label, QIODevice &data, int &version) Q_DECL_OVERRIDE; + + void compare(Akonadi::AbstractDifferencesReporter *reporter, + const Akonadi::Item &leftItem, + const Akonadi::Item &rightItem) Q_DECL_OVERRIDE; - QString extractGid( const Item& item ) const; + QString extractGid(const Item &item) const Q_DECL_OVERRIDE; }; } #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_kalarm.cpp kdepim-runtime-15.08.0/plugins/akonadi_serializer_kalarm.cpp --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_kalarm.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_kalarm.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,80 +20,71 @@ #include "akonadi_serializer_kalarm.h" #include "kaeventformatter.h" +#include "akonadi_serializer_kalarm_debug.h" #include #include #include -#include -#include -#include +#include +#include +#include #include -#include #include using namespace Akonadi; using namespace KAlarmCal; - // Convert from backend data stream to a KAEvent, and set it into the item's payload. -bool SerializerPluginKAlarm::deserialize(Item& item, const QByteArray& label, QIODevice& data, int version) +bool SerializerPluginKAlarm::deserialize(Item &item, const QByteArray &label, QIODevice &data, int version) { Q_UNUSED(version); - if (label != Item::FullPayload) + if (label != Item::FullPayload) { return false; + } KCalCore::Incidence::Ptr i = mFormat.fromString(QString::fromUtf8(data.readAll())); - if (!i) - { - kWarning(5954) << "Failed to parse incidence!"; + if (!i) { + qCWarning(AKONADI_SERIALIZER_KALARM_LOG) << "Failed to parse incidence!"; data.seek(0); - kWarning(5954) << QString::fromUtf8(data.readAll()); + qCWarning(AKONADI_SERIALIZER_KALARM_LOG) << QString::fromUtf8(data.readAll()); return false; } - if (i->type() != KCalCore::Incidence::TypeEvent) - { - kWarning(5954) << "Incidence with uid" << i->uid() << "is not an Event!"; + if (i->type() != KCalCore::Incidence::TypeEvent) { + qCWarning(AKONADI_SERIALIZER_KALARM_LOG) << "Incidence with uid" << i->uid() << "is not an Event!"; data.seek(0); return false; } KAEvent event(i.staticCast()); const QString mime = CalEvent::mimeType(event.category()); - if (mime.isEmpty() || !event.isValid()) - { - kWarning(5954) << "Event with uid" << event.id() << "contains no usable alarms!"; + if (mime.isEmpty() || !event.isValid()) { + qCWarning(AKONADI_SERIALIZER_KALARM_LOG) << "Event with uid" << event.id() << "contains no usable alarms!"; data.seek(0); return false; } event.setItemId(item.id()); // Set additional event data contained in attributes - if (mRegistered.isEmpty()) - { + if (mRegistered.isEmpty()) { AttributeFactory::registerAttribute(); - mRegistered = QLatin1String("x"); // set to any non-null string + mRegistered = QStringLiteral("x"); // set to any non-null string } const EventAttribute dummy; - if (item.hasAttribute(dummy.type())) - { - Attribute* a = item.attribute(dummy.type()); - if (!a) - kError(5954) << "deserialize(): Event with uid" << event.id() << "contains null attribute"; - else - { - EventAttribute* evAttr = dynamic_cast(a); - if (!evAttr) - { + if (item.hasAttribute(dummy.type())) { + Attribute *a = item.attribute(dummy.type()); + if (!a) { + qCCritical(AKONADI_SERIALIZER_KALARM_LOG) << "deserialize(): Event with uid" << event.id() << "contains null attribute"; + } else { + EventAttribute *evAttr = dynamic_cast(a); + if (!evAttr) { // Registering EventAttribute doesn't work in the serializer // unless the application also registers it. This doesn't // matter unless the application uses KAEvent class. - kError(5954) << "deserialize(): Event with uid" << event.id() << "contains unknown type EventAttribute (application must call AttributeFactory::registerAttribute())"; - } - else - { + qCCritical(AKONADI_SERIALIZER_KALARM_LOG) << "deserialize(): Event with uid" << event.id() << "contains unknown type EventAttribute (application must call AttributeFactory::registerAttribute())"; + } else { KAEvent::CmdErrType err = evAttr->commandError(); event.setCommandError(err); } @@ -106,12 +97,13 @@ } // Convert an item's KAEvent payload to backend data stream. -void SerializerPluginKAlarm::serialize(const Item& item, const QByteArray& label, QIODevice& data, int& version) +void SerializerPluginKAlarm::serialize(const Item &item, const QByteArray &label, QIODevice &data, int &version) { Q_UNUSED(version); - if (label != Item::FullPayload || !item.hasPayload()) + if (label != Item::FullPayload || !item.hasPayload()) { return; + } const KAEvent e = item.payload(); KCalCore::Event::Ptr kcalEvent(new KCalCore::Event); e.updateKCalEvent(kcalEvent, KAEvent::UID_SET); @@ -125,9 +117,7 @@ data.write("\nEND:VCALENDAR"); } -#include - -void SerializerPluginKAlarm::compare(AbstractDifferencesReporter* reporter, const Item& left, const Item& right) +void SerializerPluginKAlarm::compare(AbstractDifferencesReporter *reporter, const Item &left, const Item &right) { Q_ASSERT(reporter); Q_ASSERT(left.hasPayload()); @@ -143,133 +133,183 @@ reporter->setRightPropertyValueTitle(i18nc("@title:column", "Conflicting Alarm")); reportDifference(reporter, KAEventFormatter::Id); - if (eventL.revision() != eventR.revision()) + if (eventL.revision() != eventR.revision()) { reportDifference(reporter, KAEventFormatter::Revision); - if (eventL.actionSubType() != eventR.actionSubType()) + } + if (eventL.actionSubType() != eventR.actionSubType()) { reportDifference(reporter, KAEventFormatter::AlarmType); - if (eventL.category() != eventR.category()) + } + if (eventL.category() != eventR.category()) { reportDifference(reporter, KAEventFormatter::AlarmCategory); - if (eventL.templateName() != eventR.templateName()) + } + if (eventL.templateName() != eventR.templateName()) { reportDifference(reporter, KAEventFormatter::TemplateName); - if (eventL.createdDateTime() != eventR.createdDateTime()) + } + if (eventL.createdDateTime() != eventR.createdDateTime()) { reportDifference(reporter, KAEventFormatter::CreatedTime); - if (eventL.startDateTime() != eventR.startDateTime()) + } + if (eventL.startDateTime() != eventR.startDateTime()) { reportDifference(reporter, KAEventFormatter::StartTime); - if (eventL.templateAfterTime() != eventR.templateAfterTime()) + } + if (eventL.templateAfterTime() != eventR.templateAfterTime()) { reportDifference(reporter, KAEventFormatter::TemplateAfterTime); - if (*eventL.recurrence() != *eventR.recurrence()) + } + if (*eventL.recurrence() != *eventR.recurrence()) { reportDifference(reporter, KAEventFormatter::Recurrence); - if (eventL.mainDateTime(true) != eventR.mainDateTime(true)) + } + if (eventL.mainDateTime(true) != eventR.mainDateTime(true)) { reportDifference(reporter, KAEventFormatter::NextRecurrence); - if (eventL.repetition() != eventR.repetition()) + } + if (eventL.repetition() != eventR.repetition()) { reportDifference(reporter, KAEventFormatter::SubRepetition); - if (eventL.repetition().interval() != eventR.repetition().interval()) + } + if (eventL.repetition().interval() != eventR.repetition().interval()) { reportDifference(reporter, KAEventFormatter::RepeatInterval); - if (eventL.repetition().count() != eventR.repetition().count()) + } + if (eventL.repetition().count() != eventR.repetition().count()) { reportDifference(reporter, KAEventFormatter::RepeatCount); - if (eventL.nextRepetition() != eventR.nextRepetition()) + } + if (eventL.nextRepetition() != eventR.nextRepetition()) { reportDifference(reporter, KAEventFormatter::NextRepetition); - if (eventL.holidaysExcluded() != eventR.holidaysExcluded()) + } + if (eventL.holidaysExcluded() != eventR.holidaysExcluded()) { reportDifference(reporter, KAEventFormatter::HolidaysExcluded); - if (eventL.workTimeOnly() != eventR.workTimeOnly()) + } + if (eventL.workTimeOnly() != eventR.workTimeOnly()) { reportDifference(reporter, KAEventFormatter::WorkTimeOnly); - if (eventL.lateCancel() != eventR.lateCancel()) + } + if (eventL.lateCancel() != eventR.lateCancel()) { reportDifference(reporter, KAEventFormatter::LateCancel); - if (eventL.autoClose() != eventR.autoClose()) + } + if (eventL.autoClose() != eventR.autoClose()) { reportDifference(reporter, KAEventFormatter::AutoClose); - if (eventL.copyToKOrganizer() != eventR.copyToKOrganizer()) + } + if (eventL.copyToKOrganizer() != eventR.copyToKOrganizer()) { reportDifference(reporter, KAEventFormatter::CopyKOrganizer); - if (eventL.enabled() != eventR.enabled()) + } + if (eventL.enabled() != eventR.enabled()) { reportDifference(reporter, KAEventFormatter::Enabled); - if (eventL.isReadOnly() != eventR.isReadOnly()) + } + if (eventL.isReadOnly() != eventR.isReadOnly()) { reportDifference(reporter, KAEventFormatter::ReadOnly); - if (eventL.toBeArchived() != eventR.toBeArchived()) + } + if (eventL.toBeArchived() != eventR.toBeArchived()) { reportDifference(reporter, KAEventFormatter::Archive); - if (eventL.customProperties() != eventR.customProperties()) + } + if (eventL.customProperties() != eventR.customProperties()) { reportDifference(reporter, KAEventFormatter::CustomProperties); - if (eventL.message() != eventR.message()) + } + if (eventL.message() != eventR.message()) { reportDifference(reporter, KAEventFormatter::MessageText); - if (eventL.fileName() != eventR.fileName()) + } + if (eventL.fileName() != eventR.fileName()) { reportDifference(reporter, KAEventFormatter::MessageFile); - if (eventL.fgColour() != eventR.fgColour()) + } + if (eventL.fgColour() != eventR.fgColour()) { reportDifference(reporter, KAEventFormatter::FgColour); - if (eventL.bgColour() != eventR.bgColour()) + } + if (eventL.bgColour() != eventR.bgColour()) { reportDifference(reporter, KAEventFormatter::BgColour); - if (eventL.font() != eventR.font()) + } + if (eventL.font() != eventR.font()) { reportDifference(reporter, KAEventFormatter::Font); - if (eventL.preAction() != eventR.preAction()) + } + if (eventL.preAction() != eventR.preAction()) { reportDifference(reporter, KAEventFormatter::PreAction); - if (eventL.cancelOnPreActionError() != eventR.cancelOnPreActionError()) + } + if ((eventL.extraActionOptions() & KAEvent::CancelOnPreActError) != (eventR.extraActionOptions() & KAEvent::CancelOnPreActError)) { reportDifference(reporter, KAEventFormatter::PreActionCancel); - if (eventL.dontShowPreActionError() != eventR.dontShowPreActionError()) + } + if ((eventL.extraActionOptions() & KAEvent::DontShowPreActError) != (eventR.extraActionOptions() & KAEvent::DontShowPreActError)) { reportDifference(reporter, KAEventFormatter::PreActionNoError); - if (eventL.postAction() != eventR.postAction()) + } + if (eventL.postAction() != eventR.postAction()) { reportDifference(reporter, KAEventFormatter::PostAction); - if (eventL.confirmAck() != eventR.confirmAck()) + } + if (eventL.confirmAck() != eventR.confirmAck()) { reportDifference(reporter, KAEventFormatter::ConfirmAck); - if (eventL.kmailSerialNumber() != eventR.kmailSerialNumber()) + } + if (eventL.kmailSerialNumber() != eventR.kmailSerialNumber()) { reportDifference(reporter, KAEventFormatter::KMailSerial); + } if (eventL.beep() != eventR.beep() - || eventL.speak() != eventR.speak() - || eventL.audioFile() != eventR.audioFile()) + || eventL.speak() != eventR.speak() + || eventL.audioFile() != eventR.audioFile()) { reportDifference(reporter, KAEventFormatter::Sound); - if (eventL.repeatSound() != eventR.repeatSound()) + } + if (eventL.repeatSound() != eventR.repeatSound()) { reportDifference(reporter, KAEventFormatter::SoundRepeat); - if (eventL.soundVolume() != eventR.soundVolume()) + } + if (eventL.soundVolume() != eventR.soundVolume()) { reportDifference(reporter, KAEventFormatter::SoundVolume); - if (eventL.fadeVolume() != eventR.fadeVolume()) + } + if (eventL.fadeVolume() != eventR.fadeVolume()) { reportDifference(reporter, KAEventFormatter::SoundFadeVolume); - if (eventL.fadeSeconds() != eventR.fadeSeconds()) + } + if (eventL.fadeSeconds() != eventR.fadeSeconds()) { reportDifference(reporter, KAEventFormatter::SoundFadeTime); - if (eventL.reminderMinutes() != eventR.reminderMinutes()) + } + if (eventL.reminderMinutes() != eventR.reminderMinutes()) { reportDifference(reporter, KAEventFormatter::Reminder); - if (eventL.reminderOnceOnly() != eventR.reminderOnceOnly()) + } + if (eventL.reminderOnceOnly() != eventR.reminderOnceOnly()) { reportDifference(reporter, KAEventFormatter::ReminderOnce); - if (eventL.deferred() != eventR.deferred()) + } + if (eventL.deferred() != eventR.deferred()) { reportDifference(reporter, KAEventFormatter::DeferralType); - if (eventL.deferDateTime() != eventR.deferDateTime()) + } + if (eventL.deferDateTime() != eventR.deferDateTime()) { reportDifference(reporter, KAEventFormatter::DeferralTime); - if (eventL.deferDefaultMinutes() != eventR.deferDefaultMinutes()) + } + if (eventL.deferDefaultMinutes() != eventR.deferDefaultMinutes()) { reportDifference(reporter, KAEventFormatter::DeferDefault); - if (eventL.deferDefaultDateOnly() != eventR.deferDefaultDateOnly()) + } + if (eventL.deferDefaultDateOnly() != eventR.deferDefaultDateOnly()) { reportDifference(reporter, KAEventFormatter::DeferDefaultDate); - if (eventL.command() != eventR.command()) + } + if (eventL.command() != eventR.command()) { reportDifference(reporter, KAEventFormatter::Command); - if (eventL.logFile() != eventR.logFile()) + } + if (eventL.logFile() != eventR.logFile()) { reportDifference(reporter, KAEventFormatter::LogFile); - if (eventL.commandXterm() != eventR.commandXterm()) + } + if (eventL.commandXterm() != eventR.commandXterm()) { reportDifference(reporter, KAEventFormatter::CommandXTerm); - if (eventL.emailSubject() != eventR.emailSubject()) + } + if (eventL.emailSubject() != eventR.emailSubject()) { reportDifference(reporter, KAEventFormatter::EmailSubject); - if (eventL.emailFromId() != eventR.emailFromId()) + } + if (eventL.emailFromId() != eventR.emailFromId()) { reportDifference(reporter, KAEventFormatter::EmailFromId); - if (eventL.emailAddresses() != eventR.emailAddresses()) + } + if (eventL.emailAddresses() != eventR.emailAddresses()) { reportDifference(reporter, KAEventFormatter::EmailTo); - if (eventL.emailBcc() != eventR.emailBcc()) + } + if (eventL.emailBcc() != eventR.emailBcc()) { reportDifference(reporter, KAEventFormatter::EmailBcc); - if (eventL.emailMessage() != eventR.emailMessage()) + } + if (eventL.emailMessage() != eventR.emailMessage()) { reportDifference(reporter, KAEventFormatter::EmailBody); - if (eventL.emailAttachments() != eventR.emailAttachments()) + } + if (eventL.emailAttachments() != eventR.emailAttachments()) { reportDifference(reporter, KAEventFormatter::EmailAttachments); + } - KLocale* locale = KGlobal::locale(); + KLocale *locale = KLocale::global(); reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18nc("@label", "Item revision"), locale->convertDigits(QString::number(left.revision()), locale->digitSet()), locale->convertDigits(QString::number(right.revision()), locale->digitSet())); } -void SerializerPluginKAlarm::reportDifference(AbstractDifferencesReporter* reporter, KAEventFormatter::Parameter id) +void SerializerPluginKAlarm::reportDifference(AbstractDifferencesReporter *reporter, KAEventFormatter::Parameter id) { - if (mValueL.isApplicable(id) || mValueR.isApplicable(id)) + if (mValueL.isApplicable(id) || mValueR.isApplicable(id)) { reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KAEventFormatter::label(id), mValueL.value(id), mValueR.value(id)); + } } -QString SerializerPluginKAlarm::extractGid(const Item& item) const +QString SerializerPluginKAlarm::extractGid(const Item &item) const { return item.hasPayload() ? item.payload().id() : QString(); } -Q_EXPORT_PLUGIN2(akonadi_serializer_kalarm, SerializerPluginKAlarm) - - -// vim: et sw=4: diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_kalarm_debug.cpp kdepim-runtime-15.08.0/plugins/akonadi_serializer_kalarm_debug.cpp --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_kalarm_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_kalarm_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 "akonadi_serializer_kalarm_debug.h" + +Q_LOGGING_CATEGORY(AKONADI_SERIALIZER_KALARM_LOG, "log_akonadi_serializer_kalarm") diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_kalarm_debug.h kdepim-runtime-15.08.0/plugins/akonadi_serializer_kalarm_debug.h --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_kalarm_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_kalarm_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,28 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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_SERIALIZER_KALARM_DEBUG_H +#define AKONADI_SERIALIZER_KALARM_DEBUG_H + +#include + +Q_DECLARE_LOGGING_CATEGORY(AKONADI_SERIALIZER_KALARM_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_kalarm.h kdepim-runtime-15.08.0/plugins/akonadi_serializer_kalarm.h --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_kalarm.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_kalarm.h 2015-08-10 21:01:02.000000000 +0000 @@ -23,44 +23,43 @@ #include "kaeventformatter.h" -#include -#include -#include -#include +#include +#include +#include +#include #include namespace Akonadi { - class Item; - class AbstractDifferencesReporter; +class Item; +class AbstractDifferencesReporter; } class SerializerPluginKAlarm : public QObject, - public Akonadi::ItemSerializerPlugin, - public Akonadi::DifferencesAlgorithmInterface, - public Akonadi::GidExtractorInterface + public Akonadi::ItemSerializerPlugin, + public Akonadi::DifferencesAlgorithmInterface, + public Akonadi::GidExtractorInterface { - Q_OBJECT - Q_INTERFACES(Akonadi::ItemSerializerPlugin) - Q_INTERFACES(Akonadi::DifferencesAlgorithmInterface) - Q_INTERFACES(Akonadi::GidExtractorInterface) - - public: - bool deserialize(Akonadi::Item& item, const QByteArray& label, QIODevice& data, int version); - void serialize(const Akonadi::Item& item, const QByteArray& label, QIODevice& data, int& version); - void compare(Akonadi::AbstractDifferencesReporter*, const Akonadi::Item& left, const Akonadi::Item& right); - QString extractGid(const Akonadi::Item& item) const; - - private: - void reportDifference(Akonadi::AbstractDifferencesReporter*, KAEventFormatter::Parameter); - - KCalCore::ICalFormat mFormat; - KAEventFormatter mValueL; - KAEventFormatter mValueR; - QString mRegistered; + Q_OBJECT + Q_INTERFACES(Akonadi::ItemSerializerPlugin) + Q_INTERFACES(Akonadi::DifferencesAlgorithmInterface) + Q_INTERFACES(Akonadi::GidExtractorInterface) + Q_PLUGIN_METADATA(IID "org.kde.akonadi.SerializerPluginKAlarm") +public: + bool deserialize(Akonadi::Item &item, const QByteArray &label, QIODevice &data, int version) Q_DECL_OVERRIDE; + void serialize(const Akonadi::Item &item, const QByteArray &label, QIODevice &data, int &version) Q_DECL_OVERRIDE; + void compare(Akonadi::AbstractDifferencesReporter *, const Akonadi::Item &left, const Akonadi::Item &right) Q_DECL_OVERRIDE; + QString extractGid(const Akonadi::Item &item) const Q_DECL_OVERRIDE; + +private: + void reportDifference(Akonadi::AbstractDifferencesReporter *, KAEventFormatter::Parameter); + + KCalCore::ICalFormat mFormat; + KAEventFormatter mValueL; + KAEventFormatter mValueR; + QString mRegistered; }; #endif // AKONADI_SERIALIZER_KALARM_H -// vim: et sw=4: diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_kcalcore.cpp kdepim-runtime-15.08.0/plugins/akonadi_serializer_kcalcore.cpp --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_kcalcore.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_kcalcore.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,124 +19,132 @@ #include "akonadi_serializer_kcalcore.h" -#include -#include -#include +#include +#include +#include #include #include #include -#include -#include +#include +#include #include +#include using namespace KCalCore; using namespace KCalUtils; using namespace Akonadi; +SerializerPluginKCalCore::SerializerPluginKCalCore() + : mTimeZones(new ICalTimeZones) +{ +} + //// ItemSerializerPlugin interface -bool SerializerPluginKCalCore::deserialize( Item &item, const QByteArray &label, - QIODevice &data, int version ) +bool SerializerPluginKCalCore::deserialize(Item &item, const QByteArray &label, + QIODevice &data, int version) { - Q_UNUSED( version ); + Q_UNUSED(version); + + if (label != Item::FullPayload) { + return false; + } + + qint32 type; + quint32 magic, incidenceVersion; + QDataStream input(&data); + input >> magic; + input >> incidenceVersion; + input >> type; + data.seek(0); + + Incidence::Ptr incidence; + + if (magic == IncidenceBase::magicSerializationIdentifier()) { + IncidenceBase::Ptr base; + switch (static_cast(type)) { + case KCalCore::Incidence::TypeEvent: { + base = Event::Ptr(new Event()); + break; + } + case KCalCore::Incidence::TypeTodo: { + base = Todo::Ptr(new Todo()); + break; + } + case KCalCore::Incidence::TypeJournal: { + base = Journal::Ptr(new Journal()); + break; + } + default: + break; + } + input >> base; + incidence = base.staticCast(); + } else { + // Use the old format + incidence = mFormat.readIncidence(data.readAll(), mTimeZones.data()); + } + + if (!incidence) { + qWarning() << "Failed to parse incidence! Item id = " << item.id() + << "Storage collection id " << item.storageCollectionId() + << "parentCollectionId = " << item.parentCollection().id(); + data.seek(0); + qWarning() << QString::fromUtf8(data.readAll()); + return false; + } - if ( label != Item::FullPayload ) { - return false; - } - - qint32 type; - quint32 magic, incidenceVersion; - QDataStream input( &data ); - input >> magic; - input >> incidenceVersion; - input >> type; - data.seek( 0 ); - - Incidence::Ptr incidence; - - if (magic == IncidenceBase::magicSerializationIdentifier()) { - IncidenceBase::Ptr base; - switch ( static_cast( type ) ) { - case KCalCore::Incidence::TypeEvent: { - base = Event::Ptr( new Event() ); - break; - } - case KCalCore::Incidence::TypeTodo: { - base = Todo::Ptr( new Todo() ); - break; - } - case KCalCore::Incidence::TypeJournal: { - base = Journal::Ptr( new Journal() ); - break; - } - default: - break; - } - input >> base; - incidence = base.staticCast(); - } else { - // Use the old format - incidence = mFormat.fromString( QString::fromUtf8( data.readAll() ) ); - } - - if ( !incidence ) { - kWarning( 5263 ) << "Failed to parse incidence! Item id = " << item.id() - << "Storage collection id " << item.storageCollectionId() - << "parentCollectionId = " << item.parentCollection().id(); - data.seek( 0 ); - kWarning( 5263 ) << QString::fromUtf8( data.readAll() ); - return false; - } - - item.setPayload( incidence ); - return true; -} - -void SerializerPluginKCalCore::serialize( const Item &item, - const QByteArray &label, - QIODevice &data, int &version ) -{ - Q_UNUSED( version ); - - if ( label != Item::FullPayload || !item.hasPayload() ) - return; - Incidence::Ptr i = item.payload(); - - // Using an env variable for now while testing - if (qgetenv("KCALCORE_BINARY_SERIALIZER") == QByteArray("1")) { - QDataStream output(&data); - IncidenceBase::Ptr base = i; - output << base; - } else { - // ### I guess this can be done without hardcoding stuff - data.write( "BEGIN:VCALENDAR\nPRODID:-//K Desktop Environment//NONSGML libkcal 4.3//EN\nVERSION:2.0\nX-KDE-ICAL-IMPLEMENTATION-VERSION:1.0\n" ); - data.write( mFormat.toRawString( i ) ); - data.write( "\nEND:VCALENDAR" ); - } + item.setPayload(incidence); + return true; +} + +void SerializerPluginKCalCore::serialize(const Item &item, + const QByteArray &label, + QIODevice &data, int &version) +{ + Q_UNUSED(version); + + if (label != Item::FullPayload || !item.hasPayload()) { + return; + } + Incidence::Ptr i = item.payload(); + + // Using an env variable for now while testing + if (qgetenv("KCALCORE_BINARY_SERIALIZER") == QByteArray("1")) { + QDataStream output(&data); + IncidenceBase::Ptr base = i; + output << base; + } else { + // ### I guess this can be done without hardcoding stuff + data.write("BEGIN:VCALENDAR\nPRODID:-//K Desktop Environment//NONSGML libkcal 4.3//EN\nVERSION:2.0\nX-KDE-ICAL-IMPLEMENTATION-VERSION:1.0\n"); + data.write(mFormat.toRawString(i)); + data.write("\nEND:VCALENDAR"); + } } //// DifferencesAlgorithmInterface -static bool compareString( const QString &left, const QString &right ) +static bool compareString(const QString &left, const QString &right) { - if ( left.isEmpty() && right.isEmpty() ) - return true; - else - return left == right; + if (left.isEmpty() && right.isEmpty()) { + return true; + } else { + return left == right; + } } -static QString toString( const Attendee::Ptr &attendee ) +static QString toString(const Attendee::Ptr &attendee) { - return attendee->name() + QLatin1Char( '<' ) + attendee->email() + QLatin1Char( '>' ); + return attendee->name() + QLatin1Char('<') + attendee->email() + QLatin1Char('>'); } -static QString toString( const Alarm::Ptr & ) +static QString toString(const Alarm::Ptr &) { - return QString(); + return QString(); } /* @@ -146,216 +154,217 @@ } */ -static QString toString( const Attachment::Ptr & ) +static QString toString(const Attachment::Ptr &) { - return QString(); + return QString(); } -static QString toString( const QDate &date ) +static QString toString(const QDate &date) { - return date.toString(); + return date.toString(); } -static QString toString( const KDateTime &dateTime ) +static QString toString(const KDateTime &dateTime) { - return dateTime.dateTime().toString(); + return dateTime.dateTime().toString(); } -static QString toString( const QString &str ) +static QString toString(const QString &str) { - return str; + return str; } -static QString toString( bool value ) +static QString toString(bool value) { - if ( value ) - return i18n( "Yes" ); - else - return i18n( "No" ); + if (value) { + return i18n("Yes"); + } else { + return i18n("No"); + } } template -static void compareList( AbstractDifferencesReporter *reporter, - const QString &id, - const C &left, - const C &right ) -{ - for ( typename C::const_iterator it = left.begin(), end = left.end() ; it != end ; ++it ) { - if ( !right.contains( *it ) ) - reporter->addProperty( AbstractDifferencesReporter::AdditionalLeftMode, id, toString( *it ), QString() ); - } +static void compareList(AbstractDifferencesReporter *reporter, + const QString &id, + const C &left, + const C &right) +{ + for (typename C::const_iterator it = left.begin(), end = left.end() ; it != end ; ++it) { + if (!right.contains(*it)) { + reporter->addProperty(AbstractDifferencesReporter::AdditionalLeftMode, id, toString(*it), QString()); + } + } - for ( typename C::const_iterator it = right.begin(), end = right.end() ; it != end ; ++it ) { - if ( !left.contains( *it ) ) - reporter->addProperty( AbstractDifferencesReporter::AdditionalRightMode, id, QString(), toString( *it ) ); - } + for (typename C::const_iterator it = right.begin(), end = right.end() ; it != end ; ++it) { + if (!left.contains(*it)) { + reporter->addProperty(AbstractDifferencesReporter::AdditionalRightMode, id, QString(), toString(*it)); + } + } } -static void compareIncidenceBase( AbstractDifferencesReporter *reporter, - const IncidenceBase::Ptr &left, - const IncidenceBase::Ptr &right ) +static void compareIncidenceBase(AbstractDifferencesReporter *reporter, + const IncidenceBase::Ptr &left, + const IncidenceBase::Ptr &right) { - compareList( reporter, i18n( "Attendees" ), left->attendees(), right->attendees() ); + compareList(reporter, i18n("Attendees"), left->attendees(), right->attendees()); - if ( !compareString( left->organizer()->fullName(), right->organizer()->fullName() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Organizer" ), - left->organizer()->fullName(), right->organizer()->fullName() ); + if (!compareString(left->organizer()->fullName(), right->organizer()->fullName())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Organizer"), + left->organizer()->fullName(), right->organizer()->fullName()); - if ( !compareString( left->uid(), right->uid() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "UID" ), - left->uid(), right->uid() ); + if (!compareString(left->uid(), right->uid())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("UID"), + left->uid(), right->uid()); - if ( left->allDay() != right->allDay() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Is all-day" ), - toString( left->allDay() ), toString( right->allDay() ) ); + if (left->allDay() != right->allDay()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Is all-day"), + toString(left->allDay()), toString(right->allDay())); - if ( left->hasDuration() != right->hasDuration() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Has duration" ), - toString( left->hasDuration() ), toString( right->hasDuration() ) ); + if (left->hasDuration() != right->hasDuration()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Has duration"), + toString(left->hasDuration()), toString(right->hasDuration())); - if ( left->duration() != right->duration() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Duration" ), - QString::number( left->duration().asSeconds() ), QString::number( right->duration().asSeconds() ) ); + if (left->duration() != right->duration()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Duration"), + QString::number(left->duration().asSeconds()), QString::number(right->duration().asSeconds())); } -static void compareIncidence( AbstractDifferencesReporter *reporter, - const Incidence::Ptr &left, - const Incidence::Ptr &right ) +static void compareIncidence(AbstractDifferencesReporter *reporter, + const Incidence::Ptr &left, + const Incidence::Ptr &right) { - if ( !compareString( left->description(), right->description() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Description" ), - left->description(), right->description() ); + if (!compareString(left->description(), right->description())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Description"), + left->description(), right->description()); - if ( !compareString( left->summary(), right->summary() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Summary" ), - left->summary(), right->summary() ); + if (!compareString(left->summary(), right->summary())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Summary"), + left->summary(), right->summary()); - if ( left->status() != right->status() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Status" ), - Stringify::incidenceStatus( left ), Stringify::incidenceStatus( right ) ); + if (left->status() != right->status()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Status"), + Stringify::incidenceStatus(left), Stringify::incidenceStatus(right)); - if ( left->secrecy() != right->secrecy() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Secrecy" ), - toString( left->secrecy() ), toString( right->secrecy() ) ); + if (left->secrecy() != right->secrecy()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Secrecy"), + toString(left->secrecy()), toString(right->secrecy())); - if ( left->priority() != right->priority() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Priority" ), - toString( left->priority() ), toString( right->priority() ) ); + if (left->priority() != right->priority()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Priority"), + toString(left->priority()), toString(right->priority())); - if ( !compareString( left->location(), right->location() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Location" ), - left->location(), right->location() ); + if (!compareString(left->location(), right->location())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Location"), + left->location(), right->location()); - compareList( reporter, i18n( "Categories" ), left->categories(), right->categories() ); - compareList( reporter, i18n( "Alarms" ), left->alarms(), right->alarms() ); - compareList( reporter, i18n( "Resources" ), left->resources(), right->resources() ); - compareList( reporter, i18n( "Attachments" ), left->attachments(), right->attachments() ); - compareList( reporter, i18n( "Exception Dates" ), left->recurrence()->exDates(), right->recurrence()->exDates() ); - compareList( reporter, i18n( "Exception Times" ), left->recurrence()->exDateTimes(), right->recurrence()->exDateTimes() ); - // TODO: recurrence dates and date/times, exrules, rrules + compareList(reporter, i18n("Categories"), left->categories(), right->categories()); + compareList(reporter, i18n("Alarms"), left->alarms(), right->alarms()); + compareList(reporter, i18n("Resources"), left->resources(), right->resources()); + compareList(reporter, i18n("Attachments"), left->attachments(), right->attachments()); + compareList(reporter, i18n("Exception Dates"), left->recurrence()->exDates(), right->recurrence()->exDates()); + compareList(reporter, i18n("Exception Times"), left->recurrence()->exDateTimes(), right->recurrence()->exDateTimes()); + // TODO: recurrence dates and date/times, exrules, rrules - if ( left->created() != right->created() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, - i18n( "Created" ), left->created().toString(), right->created().toString() ); + if (left->created() != right->created()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, + i18n("Created"), left->created().toString(), right->created().toString()); - if ( !compareString( left->relatedTo(), right->relatedTo() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, - i18n( "Related Uid" ), left->relatedTo(), right->relatedTo() ); + if (!compareString(left->relatedTo(), right->relatedTo())) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, + i18n("Related Uid"), left->relatedTo(), right->relatedTo()); } -static void compareEvent( AbstractDifferencesReporter *reporter, - const Event::Ptr &left, - const Event::Ptr &right ) +static void compareEvent(AbstractDifferencesReporter *reporter, + const Event::Ptr &left, + const Event::Ptr &right) { - if ( left->dtStart() != right->dtStart() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Start time" ), - left->dtStart().toString(), right->dtStart().toString() ); + if (left->dtStart() != right->dtStart()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Start time"), + left->dtStart().toString(), right->dtStart().toString()); - if ( left->hasEndDate() != right->hasEndDate() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Has End Date" ), - toString( left->hasEndDate() ), toString( right->hasEndDate() ) ); + if (left->hasEndDate() != right->hasEndDate()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Has End Date"), + toString(left->hasEndDate()), toString(right->hasEndDate())); - if ( left->dtEnd() != right->dtEnd() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "End Date" ), - left->dtEnd().toString(), right->dtEnd().toString() ); + if (left->dtEnd() != right->dtEnd()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("End Date"), + left->dtEnd().toString(), right->dtEnd().toString()); - // TODO: check transparency + // TODO: check transparency } -static void compareTodo( AbstractDifferencesReporter *reporter, - const Todo::Ptr &left, - const Todo::Ptr &right ) +static void compareTodo(AbstractDifferencesReporter *reporter, + const Todo::Ptr &left, + const Todo::Ptr &right) { - if ( left->hasStartDate() != right->hasStartDate() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Has Start Date" ), - toString( left->hasStartDate() ), toString( right->hasStartDate() ) ); + if (left->hasStartDate() != right->hasStartDate()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Has Start Date"), + toString(left->hasStartDate()), toString(right->hasStartDate())); - if ( left->hasDueDate() != right->hasDueDate() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Has Due Date" ), - toString( left->hasDueDate() ), toString( right->hasDueDate() ) ); + if (left->hasDueDate() != right->hasDueDate()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Has Due Date"), + toString(left->hasDueDate()), toString(right->hasDueDate())); - if ( left->dtDue() != right->dtDue() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Due Date" ), - left->dtDue().toString(), right->dtDue().toString() ); + if (left->dtDue() != right->dtDue()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Due Date"), + left->dtDue().toString(), right->dtDue().toString()); - if ( left->hasCompletedDate() != right->hasCompletedDate() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Has Complete Date" ), - toString( left->hasCompletedDate() ), toString( right->hasCompletedDate() ) ); + if (left->hasCompletedDate() != right->hasCompletedDate()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Has Complete Date"), + toString(left->hasCompletedDate()), toString(right->hasCompletedDate())); - if ( left->percentComplete() != right->percentComplete() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Complete" ), - QString::number( left->percentComplete() ), QString::number( right->percentComplete() ) ); + if (left->percentComplete() != right->percentComplete()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Complete"), + QString::number(left->percentComplete()), QString::number(right->percentComplete())); - if ( left->completed() != right->completed() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Completed" ), - toString( left->completed() ), toString( right->completed() ) ); + if (left->completed() != right->completed()) + reporter->addProperty(AbstractDifferencesReporter::ConflictMode, i18n("Completed"), + toString(left->completed()), toString(right->completed())); } -void SerializerPluginKCalCore::compare( Akonadi::AbstractDifferencesReporter *reporter, - const Akonadi::Item &leftItem, - const Akonadi::Item &rightItem ) +void SerializerPluginKCalCore::compare(Akonadi::AbstractDifferencesReporter *reporter, + const Akonadi::Item &leftItem, + const Akonadi::Item &rightItem) { - Q_ASSERT( reporter ); - Q_ASSERT( leftItem.hasPayload() ); - Q_ASSERT( rightItem.hasPayload() ); + Q_ASSERT(reporter); + Q_ASSERT(leftItem.hasPayload()); + Q_ASSERT(rightItem.hasPayload()); - const Incidence::Ptr leftIncidencePtr = leftItem.payload(); - const Incidence::Ptr rightIncidencePtr = rightItem.payload(); + const Incidence::Ptr leftIncidencePtr = leftItem.payload(); + const Incidence::Ptr rightIncidencePtr = rightItem.payload(); - if ( leftIncidencePtr->type() == Incidence::TypeEvent ) { - reporter->setLeftPropertyValueTitle( i18n( "Changed Event" ) ); - reporter->setRightPropertyValueTitle( i18n( "Conflicting Event" ) ); - } else if ( leftIncidencePtr->type() == Incidence::TypeTodo ) { - reporter->setLeftPropertyValueTitle( i18n( "Changed Todo" ) ); - reporter->setRightPropertyValueTitle( i18n( "Conflicting Todo" ) ); - } + if (leftIncidencePtr->type() == Incidence::TypeEvent) { + reporter->setLeftPropertyValueTitle(i18n("Changed Event")); + reporter->setRightPropertyValueTitle(i18n("Conflicting Event")); + } else if (leftIncidencePtr->type() == Incidence::TypeTodo) { + reporter->setLeftPropertyValueTitle(i18n("Changed Todo")); + reporter->setRightPropertyValueTitle(i18n("Conflicting Todo")); + } - compareIncidenceBase( reporter, leftIncidencePtr, rightIncidencePtr ); - compareIncidence( reporter, leftIncidencePtr, rightIncidencePtr ); + compareIncidenceBase(reporter, leftIncidencePtr, rightIncidencePtr); + compareIncidence(reporter, leftIncidencePtr, rightIncidencePtr); - const Event::Ptr leftEvent = leftIncidencePtr.dynamicCast() ; - const Event::Ptr rightEvent = rightIncidencePtr.dynamicCast() ; - if ( leftEvent && rightEvent ) { - compareEvent( reporter, leftEvent, rightEvent ); - } else { - const Todo::Ptr leftTodo = leftIncidencePtr.dynamicCast(); - const Todo::Ptr rightTodo = rightIncidencePtr.dynamicCast(); - if ( leftTodo && rightTodo ) { - compareTodo( reporter, leftTodo, rightTodo ); + const Event::Ptr leftEvent = leftIncidencePtr.dynamicCast() ; + const Event::Ptr rightEvent = rightIncidencePtr.dynamicCast() ; + if (leftEvent && rightEvent) { + compareEvent(reporter, leftEvent, rightEvent); + } else { + const Todo::Ptr leftTodo = leftIncidencePtr.dynamicCast(); + const Todo::Ptr rightTodo = rightIncidencePtr.dynamicCast(); + if (leftTodo && rightTodo) { + compareTodo(reporter, leftTodo, rightTodo); + } } - } } //// GidExtractorInterface -QString SerializerPluginKCalCore::extractGid( const Item &item ) const +QString SerializerPluginKCalCore::extractGid(const Item &item) const { - if ( !item.hasPayload() ) { - return QString(); - } - return item.payload()->instanceIdentifier(); + if (!item.hasPayload()) { + return QString(); + } + return item.payload()->instanceIdentifier(); } -Q_EXPORT_PLUGIN2( akonadi_serializer_kcalcore, SerializerPluginKCalCore ) - diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_kcalcore.h kdepim-runtime-15.08.0/plugins/akonadi_serializer_kcalcore.h --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_kcalcore.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_kcalcore.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,36 +22,40 @@ #include -#include -#include -#include +#include +#include +#include #include +#include -namespace Akonadi { +namespace Akonadi +{ class SerializerPluginKCalCore : public QObject, - public ItemSerializerPlugin, - public DifferencesAlgorithmInterface, - public GidExtractorInterface + public ItemSerializerPlugin, + public DifferencesAlgorithmInterface, + public GidExtractorInterface { Q_OBJECT - Q_INTERFACES( Akonadi::ItemSerializerPlugin ) - Q_INTERFACES( Akonadi::DifferencesAlgorithmInterface ) - Q_INTERFACES( Akonadi::GidExtractorInterface ) - - public: - bool deserialize( Item& item, const QByteArray& label, QIODevice& data, int version ); - void serialize( const Item& item, const QByteArray& label, QIODevice& data, int &version ); - - void compare( Akonadi::AbstractDifferencesReporter *reporter, - const Akonadi::Item &leftItem, - const Akonadi::Item &rightItem ); + Q_INTERFACES(Akonadi::ItemSerializerPlugin) + Q_INTERFACES(Akonadi::DifferencesAlgorithmInterface) + Q_INTERFACES(Akonadi::GidExtractorInterface) + Q_PLUGIN_METADATA(IID "org.kde.akonadi.SerializerPluginKCalCore") +public: + SerializerPluginKCalCore(); + bool deserialize(Item &item, const QByteArray &label, QIODevice &data, int version) Q_DECL_OVERRIDE; + void serialize(const Item &item, const QByteArray &label, QIODevice &data, int &version) Q_DECL_OVERRIDE; + + void compare(Akonadi::AbstractDifferencesReporter *reporter, + const Akonadi::Item &leftItem, + const Akonadi::Item &rightItem) Q_DECL_OVERRIDE; - QString extractGid( const Item &item ) const; + QString extractGid(const Item &item) const Q_DECL_OVERRIDE; - private: +private: KCalCore::ICalFormat mFormat; + QSharedPointer mTimeZones; }; } diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_kcal.cpp kdepim-runtime-15.08.0/plugins/akonadi_serializer_kcal.cpp --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_kcal.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_kcal.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,302 +0,0 @@ -/* - Copyright (c) 2007 Volker Krause - - 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 "akonadi_serializer_kcal.h" - -#include -#include - -#include -#include - -#include -#include - -#include - -#include - -typedef boost::shared_ptr IncidencePtr; - -using namespace Akonadi; - -//// ItemSerializerPlugin interface - -bool SerializerPluginKCal::deserialize(Item & item, const QByteArray & label, QIODevice & data, int version) -{ - Q_UNUSED( version ); - - if ( label != Item::FullPayload ) { - return false; - } - - KCal::Incidence* i = mFormat.fromString( QString::fromUtf8( data.readAll() ) ); - if ( !i ) { - kWarning( 5263 ) << "Failed to parse incidence!"; - data.seek( 0 ); - kWarning( 5263 ) << QString::fromUtf8( data.readAll() ); - return false; - } - item.setPayload( IncidencePtr( i ) ); - return true; -} - -void SerializerPluginKCal::serialize(const Item & item, const QByteArray & label, QIODevice & data, int &version) -{ - Q_UNUSED( version ); - - if ( label != Item::FullPayload || !item.hasPayload() ) - return; - IncidencePtr i = item.payload(); - // ### I guess this can be done without hardcoding stuff - data.write( "BEGIN:VCALENDAR\nPRODID:-//K Desktop Environment//NONSGML libkcal 3.2//EN\nVERSION:2.0\n" ); - data.write( mFormat.toString( i.get() ).toUtf8() ); - data.write( "\nEND:VCALENDAR" ); -} - -//// DifferencesAlgorithmInterface - -static bool compareString( const QString &left, const QString &right ) -{ - if ( left.isEmpty() && right.isEmpty() ) - return true; - else - return left == right; -} - -static QString toString( KCal::Attendee *attendee ) -{ - return attendee->name() + QLatin1Char( '<' ) + attendee->email() + QLatin1Char( '>' ); -} - -static QString toString( KCal::Alarm * ) -{ - return QString(); -} - -/* -static QString toString( KCal::Incidence * ) -{ - return QString(); -} -*/ - -static QString toString( KCal::Attachment * ) -{ - return QString(); -} - -static QString toString( const QDate &date ) -{ - return date.toString(); -} - -static QString toString( const KDateTime &dateTime ) -{ - return dateTime.dateTime().toString(); -} - -static QString toString( const QString &str ) -{ - return str; -} - -static QString toString( bool value ) -{ - if ( value ) - return i18n( "Yes" ); - else - return i18n( "No" ); -} - -template -static void compareList( AbstractDifferencesReporter *reporter, - const QString &id, - const QList &left, - const QList &right ) -{ - for ( int i = 0; i < left.count(); ++i ) { - if ( !right.contains( left[ i ] ) ) - reporter->addProperty( AbstractDifferencesReporter::AdditionalLeftMode, id, toString( left[ i ] ), QString() ); - } - - for ( int i = 0; i < right.count(); ++i ) { - if ( !left.contains( right[ i ] ) ) - reporter->addProperty( AbstractDifferencesReporter::AdditionalRightMode, id, QString(), toString( right[ i ] ) ); - } -} - -static void compareIncidenceBase( AbstractDifferencesReporter *reporter, - const KCal::IncidenceBase *left, - const KCal::IncidenceBase *right ) -{ - compareList( reporter, i18n( "Attendees" ), left->attendees(), right->attendees() ); - - if ( !compareString( left->organizer().fullName(), right->organizer().fullName() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Organizer" ), - left->organizer().fullName(), right->organizer().fullName() ); - - if ( !compareString( left->uid(), right->uid() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "UID" ), - left->uid(), right->uid() ); - - if ( left->allDay() != right->allDay() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Is all-day" ), - toString( left->allDay() ), toString( right->allDay() ) ); - - if ( left->hasDuration() != right->hasDuration() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Has duration" ), - toString( left->hasDuration() ), toString( right->hasDuration() ) ); - - if ( left->duration() != right->duration() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Duration" ), - QString::number( left->duration().asSeconds() ), QString::number( right->duration().asSeconds() ) ); -} - -static void compareIncidence( AbstractDifferencesReporter *reporter, - const KCal::Incidence *left, - const KCal::Incidence *right ) -{ - if ( !compareString( left->description(), right->description() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Description" ), - left->description(), right->description() ); - - if ( !compareString( left->summary(), right->summary() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Summary" ), - left->summary(), right->summary() ); - - if ( left->status() != right->status() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Status" ), - left->statusStr(), right->statusStr() ); - - if ( left->secrecy() != right->secrecy() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Secrecy" ), - toString( left->secrecy() ), toString( right->secrecy() ) ); - - if ( left->priority() != right->priority() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Priority" ), - toString( left->priority() ), toString( right->priority() ) ); - - if ( !compareString( left->location(), right->location() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Location" ), - left->location(), right->location() ); - - compareList( reporter, i18n( "Categories" ), left->categories(), right->categories() ); - compareList( reporter, i18n( "Alarms" ), left->alarms(), right->alarms() ); - compareList( reporter, i18n( "Resources" ), left->resources(), right->resources() ); - compareList( reporter, i18n( "Attachments" ), left->attachments(), right->attachments() ); - compareList( reporter, i18n( "Exception Dates" ), left->recurrence()->exDates(), right->recurrence()->exDates() ); - compareList( reporter, i18n( "Exception Times" ), left->recurrence()->exDateTimes(), right->recurrence()->exDateTimes() ); - // TODO: recurrence dates and date/times, exrules, rrules - - if ( left->created() != right->created() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, - i18n( "Created" ), left->created().toString(), right->created().toString() ); - - if ( !compareString( left->relatedToUid(), right->relatedToUid() ) ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, - i18n( "Related Uid" ), left->relatedToUid(), right->relatedToUid() ); -} - -static void compareEvent( AbstractDifferencesReporter *reporter, - const KCal::Event *left, - const KCal::Event *right ) -{ - - if ( left->dtStart() != right->dtStart() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Start time" ), - left->dtStart().toString(), right->dtStart().toString() ); - - if ( left->hasEndDate() != right->hasEndDate() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Has End Date" ), - toString( left->hasEndDate() ), toString( right->hasEndDate() ) ); - - if ( left->dtEnd() != right->dtEnd() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "End Date" ), - left->dtEnd().toString(), right->dtEnd().toString() ); - - // TODO: check transparency -} - -static void compareTodo( AbstractDifferencesReporter *reporter, - const KCal::Todo *left, - const KCal::Todo *right ) -{ - if ( left->hasStartDate() != right->hasStartDate() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Has Start Date" ), - toString( left->hasStartDate() ), toString( right->hasStartDate() ) ); - - if ( left->hasDueDate() != right->hasDueDate() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Has Due Date" ), - toString( left->hasDueDate() ), toString( right->hasDueDate() ) ); - - if ( left->dtDue() != right->dtDue() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Due Date" ), - left->dtDue().toString(), right->dtDue().toString() ); - - if ( left->hasCompletedDate() != right->hasCompletedDate() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Has Complete Date" ), - toString( left->hasCompletedDate() ), toString( right->hasCompletedDate() ) ); - - if ( left->percentComplete() != right->percentComplete() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Complete" ), - QString::number( left->percentComplete() ), QString::number( right->percentComplete() ) ); - - if ( left->completed() != right->completed() ) - reporter->addProperty( AbstractDifferencesReporter::ConflictMode, i18n( "Completed" ), - toString( left->completed() ), toString( right->completed() ) ); -} - -void SerializerPluginKCal::compare( Akonadi::AbstractDifferencesReporter *reporter, - const Akonadi::Item &leftItem, - const Akonadi::Item &rightItem ) -{ - Q_ASSERT( reporter ); - Q_ASSERT( leftItem.hasPayload() ); - Q_ASSERT( rightItem.hasPayload() ); - - const IncidencePtr leftIncidencePtr = leftItem.payload(); - const IncidencePtr rightIncidencePtr = rightItem.payload(); - - if ( leftIncidencePtr->type() == "Event" ) { - reporter->setLeftPropertyValueTitle( i18n( "Changed Event" ) ); - reporter->setRightPropertyValueTitle( i18n( "Conflicting Event" ) ); - } else if ( leftIncidencePtr->type() == "Todo" ) { - reporter->setLeftPropertyValueTitle( i18n( "Changed Todo" ) ); - reporter->setRightPropertyValueTitle( i18n( "Conflicting Todo" ) ); - } - - compareIncidenceBase( reporter, leftIncidencePtr.get(), rightIncidencePtr.get() ); - compareIncidence( reporter, leftIncidencePtr.get(), rightIncidencePtr.get() ); - - const KCal::Event *leftEvent = dynamic_cast( leftIncidencePtr.get() ); - const KCal::Event *rightEvent = dynamic_cast( rightIncidencePtr.get() ) ; - if ( leftEvent && rightEvent ) { - compareEvent( reporter, leftEvent, rightEvent ); - } else { - const KCal::Todo *leftTodo = dynamic_cast( leftIncidencePtr.get() ); - const KCal::Todo *rightTodo = dynamic_cast( rightIncidencePtr.get() ); - if ( leftTodo && rightTodo ) { - compareTodo( reporter, leftTodo, rightTodo ); - } - } -} - -Q_EXPORT_PLUGIN2( akonadi_serializer_kcal, SerializerPluginKCal ) - diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_kcal.desktop kdepim-runtime-15.08.0/plugins/akonadi_serializer_kcal.desktop --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_kcal.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_kcal.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -[Misc] -Name=Incidence Serializer -Name[ar]=مسلسل الحدث -Name[bs]=Seralizator događaja -Name[ca]=Serialitzador d'incidències -Name[ca@valencia]=Serialitzador d'incidències -Name[da]=Serieordning af hændelser -Name[de]=Ereignis-Serialisierung -Name[el]=Σειριακοποιητής περιστατικών -Name[en_GB]=Incidence Serialiser -Name[es]=Serializador de incidencias -Name[et]=Sündmuste jadasti -Name[fi]=Merkintäserialisoija -Name[fr]=Sérialiseur d'évènements -Name[ga]=Srathóir Imeachtaí -Name[gl]=Serializador de incidencias -Name[hu]=Eseménykezelő -Name[ia]=Divulgator partial de incidentias -Name[it]=Serializzatore occorrenze -Name[ja]=イベント用シリアライザ -Name[kk]=Істерді тізбектеуіші -Name[km]=Incidence Serializer -Name[ko]=사건 시리얼라이저 -Name[lt]=Įvykių serializatorius -Name[lv]=Notikumu serializētājs -Name[nb]=Forekomst-serialisering -Name[nds]=Begeefnis-Reegmoduul -Name[ne]=घटना मिलानकर्ता -Name[nl]=Agenda-item-administratie -Name[nn]=Hendingsserialisator -Name[pl]=Szeregowanie zdarzeń -Name[pt]=Serializador de Incidências -Name[pt_BR]=Serializador de incidências -Name[ro]=Serializator incidență -Name[ru]=Сохранение событий -Name[sk]=Serializátor výskytu -Name[sl]=Razvrščevalnik pojavitev v zaporedje -Name[sr]=Серијализатор случајева -Name[sr@ijekavian]=Серијализатор случајева -Name[sr@ijekavianlatin]=Serijalizator slučajeva -Name[sr@latin]=Serijalizator slučajeva -Name[sv]=Förekomstserialisering -Name[tr]=Olay Sıralandırıcısı -Name[uk]=Серіалізатор подій -Name[x-test]=xxIncidence Serializerxx -Name[zh_CN]=事件序列转换器 -Name[zh_TW]=頻率序列器 -Comment=An Akonadi serializer plugin for events, tasks and journal entries -Comment[ar]=ملحق مسلسل اكوندا لمدخلات الأحداث و المهمات و السّجل اليومي -Comment[bs]=Akonadi dodatak serializatora za događaje, zadatke i žurnal upise -Comment[ca]=Un connector de serialització de l'Akonadi pels objectes d'incidències -Comment[ca@valencia]=Un connector de serialització de l'Akonadi pels objectes d'incidències -Comment[da]=Et Akonadi-plugin til serieordning af hændelser, opgaver og journalindgange -Comment[de]=Akonadi-Modul zur Serialisierung von Ereignissen -Comment[el]=Ένα πρόσθετο σειριακοποιητή Akonadi για γεγονότα, εργασίες και καταχωρήσεις χρονικού -Comment[en_GB]=An Akonadi serialiser plugin for events, tasks and journal entries -Comment[es]=Un complemento serializador de Akonadi para eventos, tareas y entradas del diario -Comment[et]=Akonadi sündmuste, ülesannete ja päevikusissekannate jadastamisplugin -Comment[fi]=Akonadi-serialisoijaliitännäinen tapahtumia, tehtäviä ja päiväkirjamerkintöjä varten. -Comment[fr]=Un module externe Akonadi pour la sérialisation des évènements -Comment[ga]=Breiseán srathóra Akonadi le haghaidh imeachtaí, tascanna, agus iontrálacha dialainne -Comment[gl]=Un complemento de serialización do Akonadi para actividades, tarefas e entradas do diario -Comment[hu]=Akonadi-modul események, feladatok és naplóbejegyzések kezeléséhez -Comment[ia]=Un plug-in pro divulgator partial de Akonadi pro eventos, cargas e jornales -Comment[it]=Un'estensione di Akonadi per la serializzazione di eventi, attività e diari -Comment[ja]=イベント、タスク、日記のエントリのための Akonadi シリアライザプラグイン -Comment[kk]=Akonadi оқиға, тапсырма, күнделік жазуларының тізбектеуіш плагині -Comment[km]=កម្មវិធី​ជំនួយ​កម្មវិធី​បោះពុម្ព Akonadi សម្រាប់​ធាតុ​​ព្រឹត្តិការណ៍ ភារកិច្ច និង​ទិនានុប្បវត្តិ -Comment[ko]=행사, 작업, 저널 항목을 위한 Akonadi 시리얼라이저 플러그인 -Comment[lt]=Akonadi serializatoriaus įskiepis įvykiams, užduotims ir dienoraščio įrašams -Comment[lv]=Akonadi notikumu, uzdevumu un dienasgrāmatas ierakstu serializēšanas spraudnis -Comment[nb]=Et Akonadi programtillegg for serialisering av hendelser, gjøremål og dagboksnotater -Comment[nds]=Akonadi-Inreegmoduul för Begeefnissen, Opgaven un Daagbookindrääg -Comment[ne]=घटना, कार्य र जर्नल भौचरका लागि एउटा एकोनाडी मिलानकर्ता प्लगइन -Comment[nl]=Een administratieplug-in voor Akonadi voor evenementen, taken en journalen -Comment[nn]=Eit Akonadi-serialisatortillegg for hendingar, oppgåver og dagboktekstar -Comment[pa]=ਈਵੈਂਟ, ਟਾਸਕ ਅਤੇ ਜਰਨਲ ਐਂਟਰੀਆਂ ਲਈ ਅਕੌਂਡੀ ਸੀਰੀਲਾਈਜ਼ਰ ਪਲੱਗਇਨ -Comment[pl]=Wtyczka Akonadi do szeregowania zdarzeń, zadań i wpisów w dzienniku -Comment[pt]=Um 'plugin' de serialização do Akonadi para os eventos, tarefas e itens do diário -Comment[pt_BR]=Um plugin de serialização do Akonadi para os eventos, tarefas e entradas do diário -Comment[ro]=Modul de serializare Akonadi pentru evenimente, sarcini și întregistrări de agendă -Comment[ru]=Модуль сохранения событий, задач и записей дневника для Akonadi -Comment[sk]=Plugin serializátora Akonadi pre udalosti, úlohy a položky denníka -Comment[sl]=Akonadijev vstavek za razvrščanje predmetov pojavitev v zaporedje -Comment[sr]=Аконадијев прикључак серијализатора за догађаје, послове и уносе дневника -Comment[sr@ijekavian]=Аконадијев прикључак серијализатора за догађаје, послове и уносе дневника -Comment[sr@ijekavianlatin]=Akonadijev priključak serijalizatora za događaje, poslove i unose dnevnika -Comment[sr@latin]=Akonadijev priključak serijalizatora za događaje, poslove i unose dnevnika -Comment[sv]=Ett insticksprogram till Akonadi för serialisering av händelser, uppgifter och journalanteckningar -Comment[tr]=Olay, görev ve günlük nesneleri için bir Akonadi sıralandırıcısı -Comment[uk]="Додаток серіалізації Akonadi для подій, завдань і записів журналів" -Comment[x-test]=xxAn Akonadi serializer plugin for events, tasks and journal entriesxx -Comment[zh_CN]=对事项、任务和日记项进行序列转换的 Akonadi 插件 -Comment[zh_TW]=事件、工作與日誌項目物件的 Akonadi 序列器外掛程式 - -[Plugin] -Type=text/calendar,application/x-vnd.akonadi.note,application/x-vnd.kde.notes -X-Akonadi-Class=legacy;KCal::Incidence*; -X-KDE-Library=akonadi_serializer_kcal -X-KDE-ClassName=Akonadi::SerializerPluginKCal diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_kcal.h kdepim-runtime-15.08.0/plugins/akonadi_serializer_kcal.h --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_kcal.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_kcal.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -/* - Copyright (c) 2007 Volker Krause - - 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_SERIALIZER_KCAL_H -#define AKONADI_SERIALIZER_KCAL_H - -#include - -#include -#include -#include - -namespace Akonadi { - -class SerializerPluginKCal : public QObject, - public ItemSerializerPlugin, - public DifferencesAlgorithmInterface - -{ - Q_OBJECT - Q_INTERFACES( Akonadi::ItemSerializerPlugin ) - Q_INTERFACES( Akonadi::DifferencesAlgorithmInterface ) - - public: - bool deserialize( Item& item, const QByteArray& label, QIODevice& data, int version ); - void serialize( const Item& item, const QByteArray& label, QIODevice& data, int &version ); - - void compare( Akonadi::AbstractDifferencesReporter *reporter, - const Akonadi::Item &leftItem, - const Akonadi::Item &rightItem ); - private: - KCal::ICalFormat mFormat; -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_mail.cpp kdepim-runtime-15.08.0/plugins/akonadi_serializer_mail.cpp --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_mail.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_mail.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,219 +18,278 @@ */ #include "akonadi_serializer_mail.h" +#include "akonadi_serializer_mail_debug.h" #include +#include -#include #include #include -#include -#include +#include +#include #include using namespace Akonadi; using namespace KMime; -QString StringPool::sharedValue( const QString &value ) +QString StringPool::sharedValue(const QString &value) { QMutexLocker lock(&m_mutex); QSet::const_iterator it = m_pool.constFind(value); - if ( it != m_pool.constEnd() ) + if (it != m_pool.constEnd()) { return *it; + } m_pool.insert(value); return value; } -template static void parseAddrList( const QVarLengthArray &addrList, T *hdr, - int version, StringPool& pool ) +template +static void parseAddrList(const QVarLengthArray &addrList, T *hdr, + int version, StringPool &pool) { - hdr->clear(); - const int count = addrList.count(); - QVarLengthArray addr; - for ( int i = 0; i < count; ++i ) { - ImapParser::parseParenthesizedList( addrList[ i ], addr ); - if ( addr.count() != 4 ) { - kWarning( 5264 ) << "Error parsing envelope address field: " << addrList[ i ]; - continue; - } - KMime::Types::Mailbox addrField; - if ( version == 0 ) - addrField.setNameFrom7Bit( addr[0] ); - else if ( version == 1 ) - addrField.setName( pool.sharedValue( QString::fromUtf8( addr[0] ) ) ); - KMime::Types::AddrSpec addrSpec; - addrSpec.localPart = pool.sharedValue( QString::fromUtf8( addr[2] ) ); - addrSpec.domain = pool.sharedValue( QString::fromUtf8( addr[3] ) ); - addrField.setAddress( addrSpec ); - hdr->addAddress( addrField ); - } + hdr->clear(); + const int count = addrList.count(); + QVarLengthArray addr; + for (int i = 0; i < count; ++i) { + ImapParser::parseParenthesizedList(addrList[ i ], addr); + if (addr.count() != 4) { + qCWarning(AKONADI_SERIALIZER_MAIL_LOG) << "Error parsing envelope address field: " << addrList[ i ]; + continue; + } + KMime::Types::Mailbox addrField; + if (version == 0) { + addrField.setNameFrom7Bit(addr[0]); + } else if (version == 1) { + addrField.setName(pool.sharedValue(QString::fromUtf8(addr[0]))); + } + KMime::Types::AddrSpec addrSpec; + addrSpec.localPart = pool.sharedValue(QString::fromUtf8(addr[2])); + addrSpec.domain = pool.sharedValue(QString::fromUtf8(addr[3])); + addrField.setAddress(addrSpec); + hdr->addAddress(addrField); + } } +template +static void parseAddrList(QDataStream &stream, T *hdr, + int version, StringPool &pool) +{ + Q_UNUSED(version); + + hdr->clear(); + int count = 0; + stream >> count; + for (int i = 0; i < count; ++i) { + QString str; + KMime::Types::Mailbox mbox; + KMime::Types::AddrSpec addrSpec; + stream >> str; + mbox.setName(pool.sharedValue(str)); + stream >> str; + addrSpec.localPart = pool.sharedValue(str); + stream >> str; + addrSpec.domain = pool.sharedValue(str); + mbox.setAddress(addrSpec); -bool SerializerPluginMail::deserialize( Item& item, const QByteArray& label, QIODevice& data, int version ) + hdr->addAddress(mbox); + } +} + +bool SerializerPluginMail::deserialize(Item &item, const QByteArray &label, QIODevice &data, int version) { - if ( label != MessagePart::Body && label != MessagePart::Envelope && label != MessagePart::Header ) - return false; + if (label != MessagePart::Body && label != MessagePart::Envelope && label != MessagePart::Header) { + return false; + } KMime::Message::Ptr msg; - if ( !item.hasPayload() ) { + if (!item.hasPayload()) { Message *m = new Message(); - msg = KMime::Message::Ptr( m ); - item.setPayload( msg ); + msg = KMime::Message::Ptr(m); + item.setPayload(msg); } else { msg = item.payload(); } - QByteArray buffer = data.readAll(); - if ( buffer.isEmpty() ) - return true; - if ( label == MessagePart::Body ) { - msg->setContent( buffer ); - msg->parse(); - } else if ( label == MessagePart::Header ) { - if ( msg->body().isEmpty() && msg->contents().isEmpty() ) { - msg->setHead( buffer ); + if (label == MessagePart::Body) { + QByteArray buffer = data.readAll(); + if (buffer.isEmpty()) { + return true; + } + msg->setContent(buffer); msg->parse(); - } - } else if ( label == MessagePart::Envelope ) { - QVarLengthArray env; - ImapParser::parseParenthesizedList( buffer, env ); - if ( env.count() < 10 ) { - kWarning( 5264 ) << "Akonadi KMime Deserializer: Got invalid envelope: " << buffer; - return false; - } - Q_ASSERT( env.count() >= 10 ); - // date - msg->date()->from7BitString( env[0] ); - // subject - msg->subject()->from7BitString( env[1] ); - // from - QVarLengthArray addrList; - ImapParser::parseParenthesizedList( env[2], addrList ); - if ( !addrList.isEmpty() ) - parseAddrList( addrList, msg->from(), version, m_stringPool ); - // sender - ImapParser::parseParenthesizedList( env[3], addrList ); - if ( !addrList.isEmpty() ) - parseAddrList( addrList, msg->sender(), version, m_stringPool ); - // reply-to - ImapParser::parseParenthesizedList( env[4], addrList ); - if ( !addrList.isEmpty() ) - parseAddrList( addrList, msg->replyTo(), version, m_stringPool ); - // to - ImapParser::parseParenthesizedList( env[5], addrList ); - if ( !addrList.isEmpty() ) - parseAddrList( addrList, msg->to(), version, m_stringPool ); - // cc - ImapParser::parseParenthesizedList( env[6], addrList ); - if ( !addrList.isEmpty() ) - parseAddrList( addrList, msg->cc(), version, m_stringPool ); - // bcc - ImapParser::parseParenthesizedList( env[7], addrList ); - if ( !addrList.isEmpty() ) - parseAddrList( addrList, msg->bcc(), version, m_stringPool ); - // in-reply-to - msg->inReplyTo()->from7BitString( env[8] ); - // message id - msg->messageID()->from7BitString( env[9] ); - // references - if ( env.count() > 10 ) - msg->references()->from7BitString( env[10] ); + } else if (label == MessagePart::Header) { + QByteArray buffer = data.readAll(); + if (buffer.isEmpty()) { + return true; + } + if (msg->body().isEmpty() && msg->contents().isEmpty()) { + msg->setHead(buffer); + msg->parse(); + } + } else if (label == MessagePart::Envelope) { + if (version <= 1) { + QByteArray buffer = data.readAll(); + if (buffer.isEmpty()) { + return true; + } + QVarLengthArray env; + ImapParser::parseParenthesizedList(buffer, env); + if (env.count() < 10) { + qCWarning(AKONADI_SERIALIZER_MAIL_LOG) << "Akonadi KMime Deserializer: Got invalid envelope: " << buffer; + return false; + } + Q_ASSERT(env.count() >= 10); + // date + msg->date()->from7BitString(env[0]); + // subject + msg->subject()->from7BitString(env[1]); + // from + QVarLengthArray addrList; + ImapParser::parseParenthesizedList(env[2], addrList); + if (!addrList.isEmpty()) { + parseAddrList(addrList, msg->from(), version, m_stringPool); + } + // sender + ImapParser::parseParenthesizedList(env[3], addrList); + if (!addrList.isEmpty()) { + parseAddrList(addrList, msg->sender(), version, m_stringPool); + } + // reply-to + ImapParser::parseParenthesizedList(env[4], addrList); + if (!addrList.isEmpty()) { + parseAddrList(addrList, msg->replyTo(), version, m_stringPool); + } + // to + ImapParser::parseParenthesizedList(env[5], addrList); + if (!addrList.isEmpty()) { + parseAddrList(addrList, msg->to(), version, m_stringPool); + } + // cc + ImapParser::parseParenthesizedList(env[6], addrList); + if (!addrList.isEmpty()) { + parseAddrList(addrList, msg->cc(), version, m_stringPool); + } + // bcc + ImapParser::parseParenthesizedList(env[7], addrList); + if (!addrList.isEmpty()) { + parseAddrList(addrList, msg->bcc(), version, m_stringPool); + } + // in-reply-to + msg->inReplyTo()->from7BitString(env[8]); + // message id + msg->messageID()->from7BitString(env[9]); + // references + if (env.count() > 10) { + msg->references()->from7BitString(env[10]); + } + } else if (version == 2) { + QDataStream stream(&data); + QDateTime dt; + QString str; + + stream >> dt; + msg->date()->setDateTime(dt); + stream >> str; + msg->subject()->fromUnicodeString(str, "UTF-8"); + stream >> str; + msg->inReplyTo()->fromUnicodeString(str, "UTF-8"); + stream >> str; + msg->messageID()->fromUnicodeString(str, "UTF-8"); + stream >> str; + msg->references()->fromUnicodeString(str, "UTF-8"); + + parseAddrList(stream, msg->from(), version, m_stringPool); + parseAddrList(stream, msg->sender(), version, m_stringPool); + parseAddrList(stream, msg->replyTo(), version, m_stringPool); + parseAddrList(stream, msg->to(), version, m_stringPool); + parseAddrList(stream, msg->cc(), version, m_stringPool); + parseAddrList(stream, msg->bcc(), version, m_stringPool); + + if (stream.status() == QDataStream::ReadCorruptData || stream.status() == QDataStream::ReadPastEnd) { + qCWarning(AKONADI_SERIALIZER_MAIL_LOG) << "Akonadi KMime Deserializer: Got invalid envelope"; + return false; + } + } } return true; } -static QByteArray quoteImapListEntry( const QByteArray &b ) +template +static void serializeAddrList(QDataStream &stream, T *hdr) { - if ( b.isEmpty() ) - return "NIL"; - return ImapParser::quote( b ); -} - -static QByteArray buildImapList( const QList &list ) -{ - if ( list.isEmpty() ) - return "NIL"; - return QByteArray( "(" ) + ImapParser::join( list, " " ) + QByteArray( ")" ); -} - -template static QByteArray buildAddrStruct( T const *hdr ) -{ - QList addrList; - KMime::Types::Mailbox::List mb = hdr->mailboxes(); - foreach ( const KMime::Types::Mailbox &mbox, mb ) { - QList addrStruct; - addrStruct << quoteImapListEntry( mbox.name().toUtf8() ); - addrStruct << quoteImapListEntry( QByteArray() ); - addrStruct << quoteImapListEntry( mbox.addrSpec().localPart.toUtf8() ); - addrStruct << quoteImapListEntry( mbox.addrSpec().domain.toUtf8() ); - addrList << buildImapList( addrStruct ); - } - return buildImapList( addrList ); -} - -void SerializerPluginMail::serialize( const Item& item, const QByteArray& label, QIODevice& data, int &version ) -{ - version = 1; - - boost::shared_ptr m = item.payload< boost::shared_ptr >(); - if ( label == MessagePart::Body ) { - data.write( m->encodedContent() ); - } else if ( label == MessagePart::Envelope ) { - QList env; - env << quoteImapListEntry( m->date()->as7BitString( false ) ); - env << quoteImapListEntry( m->subject()->as7BitString( false ) ); - env << buildAddrStruct( m->from() ); - env << buildAddrStruct( m->sender() ); - env << buildAddrStruct( m->replyTo() ); - env << buildAddrStruct( m->to() ); - env << buildAddrStruct( m->cc() ); - env << buildAddrStruct( m->bcc() ); - env << quoteImapListEntry( m->inReplyTo()->as7BitString( false ) ); - env << quoteImapListEntry( m->messageID()->as7BitString( false ) ); - env << quoteImapListEntry( m->references()->as7BitString( false ) ); - data.write( buildImapList( env ) ); - } else if ( label == MessagePart::Header ) { - data.write( m->head() ); - } + KMime::Types::Mailbox::List mb = hdr->mailboxes(); + stream << mb.size(); + foreach (const KMime::Types::Mailbox &mbox, mb) { + stream << mbox.name() + << mbox.addrSpec().localPart + << mbox.addrSpec().domain; + } } -QSet SerializerPluginMail::parts( const Item &item ) const +void SerializerPluginMail::serialize(const Item &item, const QByteArray &label, QIODevice &data, int &version) { - QSet set; + version = 1; - if ( !item.hasPayload() ) { - return set; - } + boost::shared_ptr m = item.payload< boost::shared_ptr >(); + if (label == MessagePart::Body) { + data.write(m->encodedContent()); + } else if (label == MessagePart::Envelope) { + version = 2; + QDataStream stream(&data); + stream << m->date()->dateTime() + << m->subject()->asUnicodeString() + << m->inReplyTo()->asUnicodeString() + << m->messageID()->asUnicodeString() + << m->references()->asUnicodeString(); + serializeAddrList(stream, m->from()); + serializeAddrList(stream, m->sender()); + serializeAddrList(stream, m->replyTo()); + serializeAddrList(stream, m->to()); + serializeAddrList(stream, m->cc()); + serializeAddrList(stream, m->bcc()); + } else if (label == MessagePart::Header) { + data.write(m->head()); + } +} - KMime::Message::Ptr msg = item.payload(); - if ( !msg ) { - return set; - } +QSet SerializerPluginMail::parts(const Item &item) const +{ + QSet set; + + if (!item.hasPayload()) { + return set; + } - // FIXME: we really want "has any header" here, but the kmime api doesn't offer that yet - if ( msg->hasContent() || msg->hasHeader( "Message-ID" ) ) { - set << MessagePart::Envelope << MessagePart::Header; - if ( !msg->body().isEmpty() || !msg->contents().isEmpty() ) { - set << MessagePart::Body; + KMime::Message::Ptr msg = item.payload(); + if (!msg) { + return set; } - } - return set; + + // FIXME: we really want "has any header" here, but the kmime api doesn't offer that yet + if (msg->hasContent() || msg->hasHeader("Message-ID")) { + set << MessagePart::Envelope << MessagePart::Header; + if (!msg->body().isEmpty() || !msg->contents().isEmpty()) { + set << MessagePart::Body; + } + } + return set; } -QString SerializerPluginMail::extractGid(const Item& item) const +QString SerializerPluginMail::extractGid(const Item &item) const { - if (!item.hasPayload()) + if (!item.hasPayload()) { + return QString(); + } + const KMime::Message::Ptr msg = item.payload(); + KMime::Headers::MessageID *mid = msg->messageID(false); + if (mid) { + return mid->asUnicodeString(); + } else if (KMime::Headers::Base *uid = msg->headerByType("X-Akonotes-UID")) { + return uid->asUnicodeString(); + } return QString(); - const KMime::Message::Ptr msg = item.payload(); - KMime::Headers::MessageID *mid = msg->messageID( false ); - if (mid) - return mid->asUnicodeString(); - return QString(); } -Q_EXPORT_PLUGIN2( akonadi_serializer_mail, SerializerPluginMail ) - #include "moc_akonadi_serializer_mail.cpp" diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_mail_debug.cpp kdepim-runtime-15.08.0/plugins/akonadi_serializer_mail_debug.cpp --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_mail_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_mail_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 "akonadi_serializer_mail_debug.h" +Q_LOGGING_CATEGORY(AKONADI_SERIALIZER_MAIL_LOG, "log_akonadi_serializer_mail") + diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_mail_debug.h kdepim-runtime-15.08.0/plugins/akonadi_serializer_mail_debug.h --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_mail_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_mail_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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_SERIALIZER_MAIL_DEBUG_H +#define AKONADI_SERIALIZER_MAIL_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(AKONADI_SERIALIZER_MAIL_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_mail.h kdepim-runtime-15.08.0/plugins/akonadi_serializer_mail.h --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_mail.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_mail.h 2015-08-10 21:01:02.000000000 +0000 @@ -17,17 +17,17 @@ 02110-1301, USA. */ - #ifndef __AKONADI_SERIALIZER_MAIL_H__ #define __AKONADI_SERIALIZER_MAIL_H__ #include #include -#include -#include +#include +#include -namespace Akonadi { +namespace Akonadi +{ /** * Levare QString implicit sharing to decrease memory consumption. @@ -43,7 +43,7 @@ * to reuse it and leverage the implicit sharing. Otherwise * add the value to the pool and return it again. */ - QString sharedValue(const QString& value); + QString sharedValue(const QString &value); private: QMutex m_mutex; QSet m_pool; @@ -52,18 +52,17 @@ class SerializerPluginMail : public QObject, public ItemSerializerPlugin, public GidExtractorInterface { Q_OBJECT - Q_INTERFACES( Akonadi::ItemSerializerPlugin Akonadi::GidExtractorInterface) - + Q_INTERFACES(Akonadi::ItemSerializerPlugin Akonadi::GidExtractorInterface) + Q_PLUGIN_METADATA(IID "org.kde.akonadi.SerializerPluginMail") public: - bool deserialize( Item& item, const QByteArray& label, QIODevice& data, int version ); - void serialize( const Item& item, const QByteArray& label, QIODevice& data, int &version ); - QSet parts( const Item &item ) const; - QString extractGid(const Item& item) const; + bool deserialize(Item &item, const QByteArray &label, QIODevice &data, int version) Q_DECL_OVERRIDE; + void serialize(const Item &item, const QByteArray &label, QIODevice &data, int &version) Q_DECL_OVERRIDE; + QSet parts(const Item &item) const Q_DECL_OVERRIDE; + QString extractGid(const Item &item) const Q_DECL_OVERRIDE; private: StringPool m_stringPool; }; - } #endif diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_microblog.cpp kdepim-runtime-15.08.0/plugins/akonadi_serializer_microblog.cpp --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_microblog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_microblog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -/* - Copyright (C) 2009 Omat Holding B.V. - - 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 "akonadi_serializer_microblog.h" - -#include -#include - -#include - -using namespace Akonadi; -using namespace Microblog; - -bool SerializerPluginmicroblog::deserialize( Item& item, const QByteArray& label, QIODevice& data, int version ) -{ - Q_UNUSED( version ); - - if ( label != Item::FullPayload ) - return false; - - StatusItem status; - status.setData( data.readAll() ); - - item.setPayload( status ); - - return true; -} - -void SerializerPluginmicroblog::serialize( const Item& item, const QByteArray& label, QIODevice& data, int &version ) -{ - Q_UNUSED( version ); - - if ( label != Item::FullPayload || !item.hasPayload() ) - return; - - const StatusItem status = item.payload(); - data.write( status.data() ); -} - -QSet SerializerPluginmicroblog::parts( const Item &item ) const -{ - // only need to reimplement this when implementing partial serialization - // i.e. when using the "label" parameter of the other two methods - return ItemSerializerPlugin::parts( item ); -} - -Q_EXPORT_PLUGIN2( akonadi_serializer_microblog, Akonadi::SerializerPluginmicroblog ) - diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_microblog.desktop kdepim-runtime-15.08.0/plugins/akonadi_serializer_microblog.desktop --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_microblog.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_microblog.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -[Misc] -Name=Microblog Serializer -Name[ar]=مسلسل التدوين المصغر -Name[bs]=Siralizator mikrobloga -Name[ca]=Serialitzador de micro-blog -Name[ca@valencia]=Serialitzador de micro-blog -Name[da]=Serieordning af microblogs -Name[de]=Microblog-Serialisierung -Name[el]=Σειριακοποιητής Microblog -Name[en_GB]=Microblog Serialiser -Name[es]=Serializador de Microblog -Name[et]=Mikroblogi jadasti -Name[fi]=Microblog-serialisoija -Name[fr]=Sérialiseur de microblogues -Name[ga]=Srathóir Micreabhlagadóireachta -Name[gl]=Serializador de microblogues -Name[hu]=Microblog-leképező modul -Name[ia]=Divulgator partial de microblog -Name[it]=Serializzatore microblog -Name[ja]=マイクロブログ用シリアライザ -Name[kk]=Микроблог -Name[km]=Microblog Serializer -Name[ko]=마이크로블로그 시리얼라이저 -Name[lt]=Mikro dienoraščio serializatorius -Name[lv]=Mikroblogu serializētājs -Name[nb]=Mikroblogg-serialisator -Name[nds]=Lüttdaagbook-Reegmoduul -Name[nl]=Microblogadministratie -Name[nn]=Mikroblogg-serialisator -Name[pa]=ਮਾਈਕਰੋਬਲੌਗ ਸੀਰੀਅਲਾਈਜ਼ਰ -Name[pl]=Szeregowanie mikrobloga -Name[pt]=Serializador do Micro-blog -Name[pt_BR]=Serializador de microblog -Name[ro]=Serializator de microbloguri -Name[ru]=Сохранение записей микроблога -Name[sk]=Serializátor mikroblogu -Name[sl]=Razvrščevalnik mikroblogov v zaporedje -Name[sr]=Серијализатор микроблогова -Name[sr@ijekavian]=Серијализатор микроблогова -Name[sr@ijekavianlatin]=Serijalizator mikroblogova -Name[sr@latin]=Serijalizator mikroblogova -Name[sv]=Serialisering av mikroblogg -Name[tr]=Mini Günlük Sıralandırıcı -Name[uk]=Серіалізатор мікроблогів -Name[x-test]=xxMicroblog Serializerxx -Name[zh_CN]=微博客序列转换器 -Name[zh_TW]=Microblog 序列器 -Comment=An Akonadi serializer plugin for Microblog -Comment[ar]=ملحق مسلسل اكوندا للتدوين المصغر -Comment[bs]=Akonadi dodatak serializatora za Microblog -Comment[ca]=Un connector de serialització de l'Akonadi pels micro-blogs -Comment[ca@valencia]=Un connector de serialització de l'Akonadi pels micro-blogs -Comment[da]=Et Akonadi-plugin til serieordning af microblogs -Comment[de]=Akonadi-Modul zur Serialisierung von Microblog-Objekten -Comment[el]=Ένα πρόσθετο σειριακοποιητή Akonadi για το Microblog -Comment[en_GB]=An Akonadi serialiser plugin for Microblog -Comment[es]=Un complemento serializador de Akonadi para Microblog -Comment[et]=Akonadi mikroblogi jadastamisplugin -Comment[fi]=Akonadi-serialisoijaliitännäinen Microblogiin -Comment[fr]=Un module externe Akonadi pour la sérialisation de micro-blogs -Comment[ga]=Breiseán srathóra Akonadi le haghaidh micreabhlagadóireachta -Comment[gl]=Un engadido de serialización do Akonadi para Microblog -Comment[hu]=Akonadi-leképező modul a Microbloghoz -Comment[ia]=Un plug-in pro divulgator partial de Akonadi pro microblog -Comment[it]=Un'estensione di Akonadi per la serializzazione di microblog -Comment[ja]=マイクロブログのための Akonadi シリアライザプラグイン -Comment[kk]=Akonadi микроблогты тізбектеуіш плагині -Comment[km]=កម្មវិធី​ជំនួយ​​កម្មវិធី​ដាក់​លេខ​សៀរៀល Akonadi សម្រាប់ Microblog -Comment[ko]=마이크로블로그를 위한 Akonadi 시리얼라이저 플러그인 -Comment[lt]=Akonadi serializatoriaus įskiepis mikro dienoraščiui -Comment[lv]=Akonadi Microblog serializēšanas spraudnis -Comment[nb]=Et Akonadi programtillegg for serialisering av Microblog -Comment[nds]=Akonadi-Inreegmoduul för Lüttdaagböker -Comment[nl]=Een administratieplug-in voor Akonadi voor microblog -Comment[nn]=Eit Akonadi-serialisatortillegg for mikrobloggar -Comment[pa]=ਮਾਈਕਰੋਬਲੌਗ ਲਈ ਅਕੌਂਡੀ ਸੀਰੀਲਾਈਜ਼ਰ -Comment[pl]=Wtyczka Akonadi do szeregowania mikrobloga -Comment[pt]=Um 'plugin' de serialização do Akonadi para o Micro-blog -Comment[pt_BR]=Um plugin de serialização do Akonadi para microblog -Comment[ro]=Modul de serializare Akonadi pentru Microblog -Comment[ru]=Модуль сохранения записей микроблога для Akonadi -Comment[sk]=Plugin serializátora Akonadi pre mikroblog -Comment[sl]=Akonadijev vstavek za razvrščanje predmetov mikroblogov v zaporedje -Comment[sr]=Аконадијев прикључак серијализатора за микроблогове -Comment[sr@ijekavian]=Аконадијев прикључак серијализатора за микроблогове -Comment[sr@ijekavianlatin]=Akonadijev priključak serijalizatora za mikroblogove -Comment[sr@latin]=Akonadijev priključak serijalizatora za mikroblogove -Comment[sv]=Ett insticksprogram till Akonadi för serialisering av mikrobloggar -Comment[tr]=Mini günlükler için bir Akonadi sıralandırıcı -Comment[uk]=Додаток серіалізації Akonadi для об'єктів мікроблогів -Comment[x-test]=xxAn Akonadi serializer plugin for Microblogxx -Comment[zh_CN]=对微博客信息进行转换的 Akonadi 序列器 -Comment[zh_TW]=Microblog 的 Akonadi 序列器外掛程式 - -[Plugin] -Type=application/x-vnd.kde.microblog -X-Akonadi-Class=legacy;default;Microblog::StatusItem; -X-KDE-Library=akonadi_serializer_microblog -X-KDE-ClassName=Akonadi::SerializerPluginmicroblog diff -Nru kdepim-runtime-4.14.6/plugins/akonadi_serializer_microblog.h kdepim-runtime-15.08.0/plugins/akonadi_serializer_microblog.h --- kdepim-runtime-4.14.6/plugins/akonadi_serializer_microblog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/akonadi_serializer_microblog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - Copyright (C) 2009 Omat Holding B.V. - - 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_SERIALIZER_MICROBLOG_H -#define AKONADI_SERIALIZER_MICROBLOG_H - -#include - -#include - -namespace Akonadi { - -class SerializerPluginmicroblog : public QObject, public ItemSerializerPlugin -{ - Q_OBJECT - Q_INTERFACES( Akonadi::ItemSerializerPlugin ) - -public: - bool deserialize( Item& item, const QByteArray& label, QIODevice& data, int version ); - void serialize( const Item& item, const QByteArray& label, QIODevice& data, int &version ); - QSet parts( const Item &item ) const; -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/plugins/autotests/addresseeserializertest.cpp kdepim-runtime-15.08.0/plugins/autotests/addresseeserializertest.cpp --- kdepim-runtime-4.14.6/plugins/autotests/addresseeserializertest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/autotests/addresseeserializertest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,47 @@ +/* + Copyright (c) 2013 Christian Mollekopf + + 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 +#include +#include +#include + +using namespace Akonadi; + +class AddresseeSerializerTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void testGid() + { + const QString uid(QStringLiteral("uid")); + KContacts::Addressee addressee; + addressee.setUid(uid); + Akonadi::Item item; + item.setMimeType(addressee.mimeType()); + item.setPayload(addressee); + SerializerPluginAddressee plugin; + const QString gid = plugin.extractGid(item); + QCOMPARE(gid, uid); + } +}; + +QTEST_MAIN(AddresseeSerializerTest) + +#include "addresseeserializertest.moc" diff -Nru kdepim-runtime-4.14.6/plugins/autotests/CMakeLists.txt kdepim-runtime-15.08.0/plugins/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/plugins/autotests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/autotests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,33 @@ +include(ECMAddTests) + +find_package(Qt5Test CONFIG REQUIRED) + +set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) + + +include_directories( + ${kdepim-runtime_SOURCE_DIR}/plugins + ${kdepim-runtime_BINARY_DIR}/plugins + ${Boost_INCLUDE_DIR} +) + +# convenience macro to add akonadi qtestlib unit-tests +macro(add_akonadiplugin_test _source _libs _additionalSources) + set(_test ${_source}) + set(srcs ${_test} ${_additionalSources}) + + get_filename_component(_name ${_source} NAME_WE) + add_executable( ${_name} ${srcs} ) + add_test( ${_name} ${_name} ) + ecm_mark_as_test(akonadiplugin-${_name}) + + target_link_libraries(${_name} KF5::AkonadiCore KF5::AkonadiMime + Qt5::Test KF5::AkonadiPrivate KF5::I18n + KF5::AkonadiPrivate ${_libs}) +endmacro() + +# qtestlib unit tests +add_akonadiplugin_test(mailserializertest.cpp "KF5::Mime" "../akonadi_serializer_mail_debug.cpp") +add_akonadiplugin_test(mailserializerplugintest.cpp "KF5::Mime" "") +add_akonadiplugin_test(kcalcoreserializertest.cpp "KF5::CalendarCore" "") +add_akonadiplugin_test(addresseeserializertest.cpp "KF5::Contacts;KF5::AkonadiContact" "../akonadi_serializer_addressee.cpp") diff -Nru kdepim-runtime-4.14.6/plugins/autotests/kcalcoreserializertest.cpp kdepim-runtime-15.08.0/plugins/autotests/kcalcoreserializertest.cpp --- kdepim-runtime-4.14.6/plugins/autotests/kcalcoreserializertest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/autotests/kcalcoreserializertest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,133 @@ +/* + Copyright (c) 2009 Volker Krause + + 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 +#include +#include +#include + +using namespace Akonadi; +using namespace KCalCore; + +class KCalCoreSerializerTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void testEventSerialize_data() + { + QTest::addColumn("mimeType"); + QTest::newRow("specific") << "application/x-vnd.akonadi.calendar.event"; + QTest::newRow("generic") << "text/calendar"; + } + void testCharsets_data() + { + testEventSerialize_data(); + } + + void testEventSerialize() + { + QFETCH(QString, mimeType); + + QByteArray serialized = + "BEGIN:VCALENDAR\n" + "PRODID:-//K Desktop Environment//NONSGML libkcal 3.5//EN\n" + "VERSION:2.0\n" + "BEGIN:VEVENT\n" + "DTSTAMP:20070109T100625Z\n" + "ORGANIZER;CN=\"Volker Krause\":MAILTO:vkrause@kde.org\n" + "CREATED:20070109T100553Z\n" + "UID:libkcal-1135684253.945\n" + "SEQUENCE:1\n" + "LAST-MODIFIED:20070109T100625Z\n" + "SUMMARY:Test event\n" + "LOCATION:here\n" + "CLASS:PUBLIC\n" + "PRIORITY:5\n" + "CATEGORIES:KDE\n" + "DTSTART:20070109T183000Z\n" + "DTEND:20070109T225900Z\n" + "TRANSP:OPAQUE\n" + "BEGIN:VALARM\n" + "DESCRIPTION:\n" + "ACTION:DISPLAY\n" + "TRIGGER;VALUE=DURATION:-PT45M\n" + "END:VALARM\n" + "END:VEVENT\n" + "END:VCALENDAR\n"; + + // deserializing + Item item; + item.setMimeType(mimeType); + item.setPayloadFromData(serialized); + + QVERIFY(item.hasPayload()); + const Event::Ptr event = item.payload(); + QVERIFY(event != 0); + + QCOMPARE(event->summary(), QStringLiteral("Test event")); + QCOMPARE(event->location(), QStringLiteral("here")); + + // serializing + const QByteArray data = item.payloadData(); + QVERIFY(!data.isEmpty()); + } + + void testCharsets() + { + QFETCH(QString, mimeType); + + // 0 defaults to latin1. + //QT5 QVERIFY( QTextCodec::codecForCStrings() == 0 ); + + const QDate currentDate = QDate::currentDate(); + + Event::Ptr event = Event::Ptr(new Event()); + event->setUid(QStringLiteral("12345")); + event->setDtStart(KDateTime(currentDate)); + event->setDtEnd(KDateTime(currentDate.addDays(1))); + + // ü + const char latin1_umlaut[] = { static_cast(0xFC), '\0' }; + event->setSummary(QLatin1String(latin1_umlaut)); + + Item item; + item.setMimeType(mimeType); + item.setPayload(event); + + // Serializer the item, the serialization should be in UTF-8: + const char utf_umlaut[] = { static_cast(0xC3), static_cast(0XBC), '\0' }; + const QByteArray bytes = item.payloadData(); + QVERIFY(bytes.contains(utf_umlaut)); + QVERIFY(!bytes.contains(latin1_umlaut)); + + // Deserialize the data: + Item item2; + item2.setMimeType(mimeType); + item2.setPayloadFromData(bytes); + + Event::Ptr event2 = item2.payload(); + QVERIFY(event2 != 0); + QVERIFY(event2->summary().toUtf8() == QByteArray(utf_umlaut)); + QVERIFY(event2->summary().toLatin1() == QByteArray(latin1_umlaut)); + } +}; + +QTEST_MAIN(KCalCoreSerializerTest) + +#include "kcalcoreserializertest.moc" diff -Nru kdepim-runtime-4.14.6/plugins/autotests/mailserializerplugintest.cpp kdepim-runtime-15.08.0/plugins/autotests/mailserializerplugintest.cpp --- kdepim-runtime-4.14.6/plugins/autotests/mailserializerplugintest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/autotests/mailserializerplugintest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,95 @@ +/* + Copyright (c) 2007 Volker Krause + + 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 "mailserializerplugintest.h" + +#include +#include +#include +#include +#include + +QTEST_MAIN(MailSerializerPluginTest) + +using namespace Akonadi; +using namespace KMime; + +void MailSerializerPluginTest::testMailPlugin() +{ + QByteArray serialized = + "From: sender@test.org\n" + "Subject: Serializer Test\n" + "To: receiver@test.org\n" + "Date: Fri, 22 Jun 2007 17:24:24 +0000\n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain\n" + "\n" + "Body data."; + + // deserializing + Item item; + item.setMimeType(QStringLiteral("message/rfc822")); + item.setPayloadFromData(serialized); + + QVERIFY(item.hasPayload()); + KMime::Message::Ptr msg = item.payload(); + QVERIFY(msg != 0); + + QCOMPARE(msg->to()->asUnicodeString(), QStringLiteral("receiver@test.org")); + QCOMPARE(msg->body(), QByteArray("Body data.")); + + // serializing + QByteArray data = item.payloadData(); + QCOMPARE(data, serialized); +} + +void MailSerializerPluginTest::testMessageIntegrity() +{ + // A message that will be slightly modified if KMime::Content::assemble() is + // called. We want to avoid this, because it breaks signatures. + QByteArray serialized = + "from: sender@example.com\n" + "to: receiver@example.com\n" + "Subject: Serializer Test\n" + "Date: Thu, 30 Jul 2009 13:46:31 +0300\n" + "MIME-Version: 1.0\n" + "Content-type: text/plain; charset=us-ascii\n" + "\n" + "Bla bla bla."; + + // Deserialize. + Item item; + item.setMimeType(QStringLiteral("message/rfc822")); + item.setPayloadFromData(serialized); + + QVERIFY(item.hasPayload()); + KMime::Message::Ptr msg = item.payload(); + QVERIFY(msg != 0); + + qDebug() << "original data:" << serialized; + qDebug() << "message content:" << msg->encodedContent(); + QCOMPARE(msg->encodedContent(), serialized); + + // Serialize. + QByteArray data = item.payloadData(); + qDebug() << "original data:" << serialized; + qDebug() << "serialized data:" << data; + QCOMPARE(data, serialized); +} + diff -Nru kdepim-runtime-4.14.6/plugins/autotests/mailserializerplugintest.h kdepim-runtime-15.08.0/plugins/autotests/mailserializerplugintest.h --- kdepim-runtime-4.14.6/plugins/autotests/mailserializerplugintest.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/autotests/mailserializerplugintest.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,33 @@ +/* + Copyright (c) 2007 Volker Krause + + 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 MAILSERIALIZERPLUGINTEST_H +#define MAILSERIALIZERPLUGINTEST_H + +#include + +class MailSerializerPluginTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void testMailPlugin(); + void testMessageIntegrity(); +}; + +#endif diff -Nru kdepim-runtime-4.14.6/plugins/autotests/mailserializertest.cpp kdepim-runtime-15.08.0/plugins/autotests/mailserializertest.cpp --- kdepim-runtime-4.14.6/plugins/autotests/mailserializertest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/autotests/mailserializertest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,374 @@ +/* + Copyright (c) 2007 Volker Krause + + 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 "mailserializertest.h" + +#include "akonadi_serializer_mail.cpp" + +#include + +#include +#include + +QTEST_MAIN(MailSerializerTest) + +void MailSerializerTest::testEnvelopeDeserialize_data() +{ + QTest::addColumn("version"); + QTest::addColumn("data"); + QTest::addColumn("date"); + QTest::addColumn("subject"); + QTest::addColumn("from"); + QTest::addColumn("sender"); + QTest::addColumn("replyTo"); + QTest::addColumn("to"); + QTest::addColumn("cc"); + QTest::addColumn("bcc"); + QTest::addColumn("inReplyTo"); + QTest::addColumn("messageId"); + QTest::addColumn("references"); + + QTest::newRow("v1 - no references") + << 1 + << QByteArray("(\"Wed, 1 Feb 2006 13:37:19 UT\" \"IMPORTANT: Akonadi Test\" ((\"Tobias Koenig\" NIL \"tokoe\" \"kde.org\")) ((\"Tobias Koenig\" NIL \"tokoe\" \"kde.org\")) NIL ((\"Ingo Kloecker\" NIL \"kloecker\" \"kde.org\")) NIL NIL NIL <{7b55527e-77f4-489d-bf18-e805be96718c}@server.kde.org>)") + << QDateTime(QDate(2006, 2, 1), QTime(13, 37, 19), Qt::UTC) + << QString::fromUtf8("IMPORTANT: Akonadi Test") + << QString::fromUtf8("Tobias Koenig ") + << QString::fromUtf8("Tobias Koenig ") + << QString() + << QString::fromUtf8("Ingo Kloecker ") + << QString() << QString() << QString() + << QString::fromUtf8("<{7b55527e-77f4-489d-bf18-e805be96718c}@server.kde.org>") + << QString(); + + QTest::newRow("v1 - with references") + << 1 + << QByteArray("(\"Wed, 1 Feb 2006 13:37:19 UT\" \"IMPORTANT: Akonadi Test\" ((\"Tobias Koenig\" NIL \"tokoe\" \"kde.org\")) ((\"Tobias Koenig\" NIL \"tokoe\" \"kde.org\")) NIL ((\"Ingo Kloecker\" NIL \"kloecker\" \"kde.org\")) NIL NIL NIL <{7b55527e-77f4-489d-bf18-e805be96718c}@server.kde.org> \"<{8888827e-77f4-489d-bf18-e805be96718c}@server.kde.org> <{9999927e-77f4-489d-bf18-e805be96718c}@server.kde.org>\")") + << QDateTime(QDate(2006, 2, 1), QTime(13, 37, 19), Qt::UTC) + << QString::fromUtf8("IMPORTANT: Akonadi Test") + << QString::fromUtf8("Tobias Koenig ") + << QString::fromUtf8("Tobias Koenig ") + << QString() + << QString::fromUtf8("Ingo Kloecker ") + << QString() + << QString() + << QString() + << QString::fromUtf8("<{7b55527e-77f4-489d-bf18-e805be96718c}@server.kde.org>") + << QString::fromUtf8("<{8888827e-77f4-489d-bf18-e805be96718c}@server.kde.org> <{9999927e-77f4-489d-bf18-e805be96718c}@server.kde.org>"); + + QBuffer buffer; + buffer.open(QIODevice::WriteOnly); + QDataStream stream(&buffer); + stream << QDateTime(QDate(2015, 6, 29), QTime(23, 50, 10), Qt::UTC) + << QString::fromUtf8("Důležité: Testování Akonadi") + << QString::fromUtf8("<1234567.icameup@withthis>") + << QString::fromUtf8("<2849719.IhmDc3qecs@thor>") + << QString::fromUtf8("<1234567.icameup@withthis> <7654321.icameupwith@thistoo>") + << 1 << QString::fromUtf8("Daniel Vrátil") << QString::fromUtf8("dvratil") << QString::fromUtf8("kde.org") + << 1 << QString::fromUtf8("Daniel Vrátil") << QString::fromUtf8("dvratil") << QString::fromUtf8("kde.org") + << 0 + << 1 << QString::fromUtf8("Volker Krause") << QString::fromUtf8("vkrause") << QString::fromUtf8("kde.org") + << 0 + << 0; + + QTest::newRow("v2") + << 2 + << buffer.data() + << QDateTime(QDate(2015, 6, 29), QTime(23, 50, 10), Qt::UTC) + << QString::fromUtf8("Důležité: Testování Akonadi") + << QString::fromUtf8("Daniel Vrátil ") + << QString::fromUtf8("Daniel Vrátil ") + << QString() // reply to + << QString::fromUtf8("Volker Krause ") + << QString() // cc + << QString() // bcc + << QString::fromUtf8("<1234567.icameup@withthis>") + << QString::fromUtf8("<2849719.IhmDc3qecs@thor>") + << QString::fromUtf8("<1234567.icameup@withthis> <7654321.icameupwith@thistoo>"); +} + + +void MailSerializerTest::testEnvelopeDeserialize() +{ + QFETCH(int, version); + QFETCH(QByteArray, data); + QFETCH(QDateTime, date); + QFETCH(QString, subject); + QFETCH(QString, from); + QFETCH(QString, sender); + QFETCH(QString, replyTo); + QFETCH(QString, to); + QFETCH(QString, cc); + QFETCH(QString, bcc); + QFETCH(QString, inReplyTo); + QFETCH(QString, messageId); + QFETCH(QString, references); + + Item i; + i.setMimeType(QStringLiteral("message/rfc822")); + + SerializerPluginMail *serializer = new SerializerPluginMail(); + + // envelope + QBuffer buffer; + buffer.setData(data); + buffer.open(QIODevice::ReadOnly); + QBENCHMARK { + buffer.seek(0); + serializer->deserialize(i, MessagePart::Envelope, buffer, version); + } + QVERIFY(i.hasPayload()); + + KMime::Message::Ptr msg = i.payload(); + QCOMPARE(msg->date()->dateTime(), date); + QCOMPARE(msg->subject()->asUnicodeString(), subject); + QCOMPARE(msg->from()->asUnicodeString(), from); + QCOMPARE(msg->sender()->asUnicodeString(), sender); + QCOMPARE(msg->replyTo()->asUnicodeString(), replyTo); + QCOMPARE(msg->to()->asUnicodeString(), to); + QCOMPARE(msg->cc()->asUnicodeString(), cc); + QCOMPARE(msg->bcc()->asUnicodeString(), bcc); + QCOMPARE(msg->inReplyTo()->asUnicodeString(), inReplyTo); + QCOMPARE(msg->messageID()->asUnicodeString(), messageId); + QCOMPARE(msg->references()->asUnicodeString(), references); + + delete serializer; +} + +void MailSerializerTest::testEnvelopeSerialize_data() +{ + QTest::addColumn("date"); + QTest::addColumn("subject"); + QTest::addColumn("from"); + QTest::addColumn("sender"); + QTest::addColumn("replyTo"); + QTest::addColumn("to"); + QTest::addColumn("cc"); + QTest::addColumn("bcc"); + QTest::addColumn("inReplyTo"); + QTest::addColumn("messageId"); + QTest::addColumn("references"); + QTest::addColumn("data"); + + QBuffer buffer; + buffer.open(QIODevice::WriteOnly); + QDataStream stream(&buffer); + stream << QDateTime(QDate(2006, 2, 1), QTime(13, 37, 19), Qt::UTC) + << QString::fromUtf8("IMPORTANT: Akonadi Test") + << QString::fromUtf8("") + << QString::fromUtf8("<{7b55527e-77f4-489d-bf18-e805be96718c}@server.kde.org>") + << QString::fromUtf8("") + << 1 << QString::fromUtf8("Tobias Koenig") << QString::fromUtf8("tokoe") << QString::fromUtf8("kde.org") + << 1 << QString::fromUtf8("Tobias Koenig") << QString::fromUtf8("tokoe") << QString::fromUtf8("kde.org") + << 0 + << 1 << QString::fromUtf8("Ingo Kloecker") << QString::fromUtf8("kloecker") << QString::fromUtf8("kde.org") + << 0 + << 0; + QTest::newRow("") + << QDateTime(QDate(2006, 2, 1), QTime(13, 37, 19), Qt::UTC) + << QString::fromUtf8("IMPORTANT: Akonadi Test") + << QString::fromUtf8("Tobias Koenig ") + << QString::fromUtf8("Tobias Koenig ") + << QString() + << QString::fromUtf8("Ingo Kloecker ") + << QString() + << QString() + << QString() + << QString::fromUtf8("<{7b55527e-77f4-489d-bf18-e805be96718c}@server.kde.org>") + << QString() + << buffer.data(); +} + + +void MailSerializerTest::testEnvelopeSerialize() +{ + QFETCH(QDateTime, date); + QFETCH(QString, subject); + QFETCH(QString, from); + QFETCH(QString, sender); + QFETCH(QString, replyTo); + QFETCH(QString, to); + QFETCH(QString, cc); + QFETCH(QString, bcc); + QFETCH(QString, inReplyTo); + QFETCH(QString, messageId); + QFETCH(QString, references); + QFETCH(QByteArray, data); + + Item i; + i.setMimeType(QStringLiteral("message/rfc822")); + Message *msg = new Message(); + msg->date()->setDateTime(date); + msg->subject()->fromUnicodeString(subject, "UTF-8"); + msg->from()->fromUnicodeString(from, "UTF-8"); + msg->sender()->fromUnicodeString(sender, "UTF-8"); + msg->replyTo()->fromUnicodeString(replyTo, "UTF-8"); + msg->to()->fromUnicodeString(to, "UTF-8"); + msg->cc()->fromUnicodeString(cc, "UTF-8"); + msg->bcc()->fromUnicodeString(bcc, "UTF-8"); + msg->inReplyTo()->fromUnicodeString(inReplyTo, "UTF-8"); + msg->messageID()->fromUnicodeString(messageId, "UTF-8"); + msg->references()->fromUnicodeString(references, "UTF-8"); + i.setPayload(KMime::Message::Ptr(msg)); + + SerializerPluginMail *serializer = new SerializerPluginMail(); + + // envelope + QByteArray env; + QBuffer buffer; + buffer.setBuffer(&env); + buffer.open(QIODevice::ReadWrite); + int version = 0; + QBENCHMARK { + buffer.seek(0); + serializer->serialize(i, MessagePart::Envelope, buffer, version); + } + QCOMPARE(env, data); + + delete serializer; +} + +void MailSerializerTest::testParts() +{ + Item item; + item.setMimeType(QStringLiteral("message/rfc822")); + KMime::Message *m = new Message; + KMime::Message::Ptr msg(m); + item.setPayload(msg); + + SerializerPluginMail *serializer = new SerializerPluginMail(); + QVERIFY(serializer->parts(item).isEmpty()); + + msg->setHead("foo"); + QSet parts = serializer->parts(item); + QCOMPARE(parts.count(), 2); + QVERIFY(parts.contains(MessagePart::Envelope)); + QVERIFY(parts.contains(MessagePart::Header)); + + msg->setBody("bar"); + parts = serializer->parts(item); + QCOMPARE(parts.count(), 3); + QVERIFY(parts.contains(MessagePart::Envelope)); + QVERIFY(parts.contains(MessagePart::Header)); + QVERIFY(parts.contains(MessagePart::Body)); + + delete serializer; +} + +void MailSerializerTest::testHeaderFetch() +{ + Item i; + i.setMimeType(QStringLiteral("message/rfc822")); + + SerializerPluginMail *serializer = new SerializerPluginMail(); + + QByteArray headerData("From: David Johnson \n" + "To: kde-commits@kde.org\n" + "MIME-Version: 1.0\n" + "Date: Sun, 01 Feb 2009 06:25:22 +0000\n" + "Message-Id: <1233469522.741324.18468.nullmailer@svn.kde.org>\n" + "Subject: [kde-doc-english] KDE/kdeutils/kcalc\n"); + + QString expectedSubject = QString::fromUtf8("[kde-doc-english] KDE/kdeutils/kcalc"); + QString expectedFrom = QString::fromUtf8("David Johnson "); + QString expectedTo = QString::fromUtf8("kde-commits@kde.org"); + + // envelope + QBuffer buffer; + buffer.setData(headerData); + buffer.open(QIODevice::ReadOnly); + buffer.seek(0); + serializer->deserialize(i, MessagePart::Header, buffer, 0); + QVERIFY(i.hasPayload()); + + KMime::Message::Ptr msg = i.payload(); + QCOMPARE(msg->subject()->asUnicodeString(), expectedSubject); + QCOMPARE(msg->from()->asUnicodeString(), expectedFrom); + QCOMPARE(msg->to()->asUnicodeString(), expectedTo); + + delete serializer; +} + +void MailSerializerTest::testMultiDeserialize() +{ + // The Body part includes the Header. + // When serialization is done a second time, we should already have the header deserialized. + // We change the header data for the second deserialization (which is an unrealistic scenario) + // to demonstrate that it is not deserialized again. + + Item i; + i.setMimeType(QStringLiteral("message/rfc822")); + + SerializerPluginMail *serializer = new SerializerPluginMail(); + + QByteArray messageData("From: David Johnson \n" + "To: kde-commits@kde.org\n" + "MIME-Version: 1.0\n" + "Date: Sun, 01 Feb 2009 06:25:22 +0000\n" + "Subject: [kde-doc-english] KDE/kdeutils/kcalc\n" + "Content-Type: text/plain\n" + "\n" + "This is content"); + + QString expectedSubject = QString::fromUtf8("[kde-doc-english] KDE/kdeutils/kcalc"); + QString expectedFrom = QString::fromUtf8("David Johnson "); + QString expectedTo = QString::fromUtf8("kde-commits@kde.org"); + QByteArray expectedBody("This is content"); + + // envelope + QBuffer buffer; + buffer.setData(messageData); + buffer.open(QIODevice::ReadOnly); + buffer.seek(0); + serializer->deserialize(i, MessagePart::Body, buffer, 0); + QVERIFY(i.hasPayload()); + + KMime::Message::Ptr msg = i.payload(); + QCOMPARE(msg->subject()->asUnicodeString(), expectedSubject); + QCOMPARE(msg->from()->asUnicodeString(), expectedFrom); + QCOMPARE(msg->to()->asUnicodeString(), expectedTo); + QCOMPARE(msg->body(), expectedBody); + + buffer.close(); + + messageData = QByteArray("From: DIFFERENT CONTACT \n" + "To: kde-commits@kde.org\n" + "MIME-Version: 1.0\n" + "Date: Sun, 01 Feb 2009 06:25:22 +0000\n" + "Message-Id: <1233469522.741324.18468.nullmailer@svn.kde.org>\n" + "Subject: [kde-doc-english] KDE/kdeutils/kcalc\n" + "Content-Type: text/plain\n" + "\r\n" + "This is content"); + + buffer.setData(messageData); + buffer.open(QIODevice::ReadOnly); + buffer.seek(0); + + serializer->deserialize(i, MessagePart::Header, buffer, 0); + QVERIFY(i.hasPayload()); + + msg = i.payload(); + QCOMPARE(msg->subject()->asUnicodeString(), expectedSubject); + QCOMPARE(msg->from()->asUnicodeString(), expectedFrom); + QCOMPARE(msg->to()->asUnicodeString(), expectedTo); + + delete serializer; +} + diff -Nru kdepim-runtime-4.14.6/plugins/autotests/mailserializertest.h kdepim-runtime-15.08.0/plugins/autotests/mailserializertest.h --- kdepim-runtime-4.14.6/plugins/autotests/mailserializertest.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/autotests/mailserializertest.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,40 @@ +/* + Copyright (c) 2007 Volker Krause + + 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 MAILSERIALIZERTEST_H +#define MAILSERIALIZERTEST_H + +#include + +class MailSerializerTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void testEnvelopeDeserialize_data(); + void testEnvelopeDeserialize(); + + void testEnvelopeSerialize_data(); + void testEnvelopeSerialize(); + + void testParts(); + void testHeaderFetch(); + void testMultiDeserialize(); +}; + +#endif diff -Nru kdepim-runtime-4.14.6/plugins/CMakeLists.txt kdepim-runtime-15.08.0/plugins/CMakeLists.txt --- kdepim-runtime-4.14.6/plugins/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,74 +1,80 @@ +project(plugins) add_definitions( -DQT_NO_CAST_FROM_ASCII ) add_definitions( -DQT_NO_CAST_TO_ASCII ) -add_subdirectory( tests ) include_directories( ${Boost_INCLUDE_DIR} ) -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) -set(akonadi_serializer_addressee_PART_SRCS akonadi_serializer_addressee.cpp ) -kde4_add_plugin(akonadi_serializer_addressee ${SERIALIZER_TYPE} ${akonadi_serializer_addressee_PART_SRCS}) -target_link_libraries(akonadi_serializer_addressee ${KDE4_KDECORE_LIBS} ${KDEPIMLIBS_KABC_LIBS} ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_AKONADI_KABC_LIBS}) -install(TARGETS akonadi_serializer_addressee DESTINATION ${PLUGIN_INSTALL_DIR}) - -set(akonadi_serializer_mail_PART_SRCS akonadi_serializer_mail.cpp ) -kde4_add_plugin(akonadi_serializer_mail ${SERIALIZER_TYPE} ${akonadi_serializer_mail_PART_SRCS}) -target_link_libraries(akonadi_serializer_mail ${KDE4_KDECORE_LIBS} ${KDEPIMLIBS_KMIME_LIBS} ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_AKONADI_KMIME_LIBS} ${AKONADI_COMMON_LIBRARIES} ) -install(TARGETS akonadi_serializer_mail DESTINATION ${PLUGIN_INSTALL_DIR}) - -if(KDEPIMLIBS_KCAL_LIBRARY) -set(akonadi_serializer_kcal_SRCS akonadi_serializer_kcal.cpp) -kde4_add_plugin(akonadi_serializer_kcal ${SERIALIZER_TYPE} ${akonadi_serializer_kcal_SRCS}) -target_link_libraries(akonadi_serializer_kcal ${KDE4_KDECORE_LIBS} ${KDEPIMLIBS_KCAL_LIBS} ${KDEPIMLIBS_AKONADI_LIBS}) -install(TARGETS akonadi_serializer_kcal DESTINATION ${PLUGIN_INSTALL_DIR}) + + +if ("${CMAKE_SOURCE_DIR}" STREQUAL "${plugins_SOURCE_DIR}") + + set(KDEPIMLIBS_LIB_VERSION "4.75.0") + find_package(Qt5DBus ${KF5_VERSION} CONFIG REQUIRED) + find_package(KF5KDELibs4Support ${KF5_VERSION} CONFIG REQUIRED) + find_package(KF5Akonadi ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5Mime ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5Contacts ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5AlarmCalendar ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5CalendarCore ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5CalendarUtils ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5AkonadiContact ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) + find_package(KF5AkonadiMime ${KDEPIMLIBS_LIB_VERSION} CONFIG REQUIRED) endif() +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_serializer_plugins\") + + +set(akonadi_serializer_addressee_PART_SRCS akonadi_serializer_addressee.cpp ) +add_library(akonadi_serializer_addressee MODULE ${SERIALIZER_TYPE} ${akonadi_serializer_addressee_PART_SRCS}) +target_link_libraries(akonadi_serializer_addressee KF5::Contacts KF5::AkonadiCore KF5::AkonadiContact KF5::I18n) +install(TARGETS akonadi_serializer_addressee DESTINATION ${KDE_INSTALL_PLUGINDIR}) + +set(akonadi_serializer_mail_PART_SRCS akonadi_serializer_mail.cpp akonadi_serializer_mail_debug.cpp) +add_library(akonadi_serializer_mail MODULE ${SERIALIZER_TYPE} ${akonadi_serializer_mail_PART_SRCS}) +target_link_libraries(akonadi_serializer_mail KF5::Mime KF5::AkonadiCore KF5::AkonadiMime KF5::AkonadiPrivate Qt5::DBus ) +install(TARGETS akonadi_serializer_mail DESTINATION ${KDE_INSTALL_PLUGINDIR}) + set(akonadi_serializer_kcalcore_SRCS akonadi_serializer_kcalcore.cpp) -kde4_add_plugin(akonadi_serializer_kcalcore ${SERIALIZER_TYPE} ${akonadi_serializer_kcalcore_SRCS}) -target_link_libraries(akonadi_serializer_kcalcore ${KDE4_KDECORE_LIBS} ${KDEPIMLIBS_KCALUTILS_LIBS} ${KDEPIMLIBS_KCALCORE_LIBS} ${KDEPIMLIBS_AKONADI_LIBS}) -install(TARGETS akonadi_serializer_kcalcore DESTINATION ${PLUGIN_INSTALL_DIR}) - -set(akonadi_serializer_bookmark_SRCS akonadi_serializer_bookmark.cpp) -kde4_add_plugin(akonadi_serializer_bookmark ${SERIALIZER_TYPE} ${akonadi_serializer_bookmark_SRCS}) -target_link_libraries(akonadi_serializer_bookmark ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} ${KDEPIMLIBS_AKONADI_LIBS}) -install(TARGETS akonadi_serializer_bookmark DESTINATION ${PLUGIN_INSTALL_DIR}) +add_library(akonadi_serializer_kcalcore MODULE ${SERIALIZER_TYPE} ${akonadi_serializer_kcalcore_SRCS}) +target_link_libraries(akonadi_serializer_kcalcore KF5::CalendarUtils KF5::CalendarCore KF5::AkonadiCore) +install(TARGETS akonadi_serializer_kcalcore DESTINATION ${KDE_INSTALL_PLUGINDIR}) set(akonadi_serializer_contactgroup_PART_SRCS akonadi_serializer_contactgroup.cpp ) -kde4_add_plugin(akonadi_serializer_contactgroup ${SERIALIZER_TYPE} ${akonadi_serializer_contactgroup_PART_SRCS}) -target_link_libraries(akonadi_serializer_contactgroup ${KDE4_KDECORE_LIBS} ${KDEPIMLIBS_KABC_LIBS} ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_AKONADI_KABC_LIBS} ${KDEPIMLIBS_AKONADI_CONTACT_LIBS}) -install(TARGETS akonadi_serializer_contactgroup DESTINATION ${PLUGIN_INSTALL_DIR}) - -set( akonadi_serializer_microblog_SRCS akonadi_serializer_microblog.cpp ) -kde4_add_plugin(akonadi_serializer_microblog ${SERIALIZER_TYPE} ${akonadi_serializer_microblog_SRCS}) -target_link_libraries(akonadi_serializer_microblog ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTCORE_LIBRARY} ${KDE4_KDECORE_LIBS} ${QT_QTXML_LIBRARY} ${KDEPIMLIBS_KPIMUTILS_LIBS} ${KDEPIMLIBS_MICROBLOG_LIBS}) -install(TARGETS akonadi_serializer_microblog DESTINATION ${PLUGIN_INSTALL_DIR}) +add_library(akonadi_serializer_contactgroup MODULE ${SERIALIZER_TYPE} ${akonadi_serializer_contactgroup_PART_SRCS}) +target_link_libraries(akonadi_serializer_contactgroup KF5::Contacts KF5::AkonadiCore KF5::AkonadiContact KF5::I18n) +install(TARGETS akonadi_serializer_contactgroup DESTINATION ${KDE_INSTALL_PLUGINDIR}) -set(akonadi_serializer_kalarm_SRCS akonadi_serializer_kalarm.cpp kaeventformatter.cpp) -kde4_add_plugin(akonadi_serializer_kalarm ${SERIALIZER_TYPE} ${akonadi_serializer_kalarm_SRCS}) +set(akonadi_serializer_kalarm_SRCS akonadi_serializer_kalarm.cpp kaeventformatter.cpp akonadi_serializer_kalarm_debug.cpp) +add_library(akonadi_serializer_kalarm MODULE ${SERIALIZER_TYPE} ${akonadi_serializer_kalarm_SRCS}) target_link_libraries(akonadi_serializer_kalarm - ${KDEPIMLIBS_KALARMCAL_LIBS} - ${KDEPIMLIBS_KCALCORE_LIBS} - ${KDEPIMLIBS_KCALUTILS_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDE4_KDECORE_LIBS} - ${QT_QTGUI_LIBRARY} + KF5::AlarmCalendar + KF5::CalendarCore + KF5::CalendarUtils + KF5::AkonadiCore + + ) -install(TARGETS akonadi_serializer_kalarm DESTINATION ${PLUGIN_INSTALL_DIR}) +install(TARGETS akonadi_serializer_kalarm DESTINATION ${KDE_INSTALL_PLUGINDIR}) ########### install files ############### install( FILES akonadi_serializer_addressee.desktop akonadi_serializer_mail.desktop - akonadi_serializer_kcal.desktop akonadi_serializer_kcalcore.desktop - akonadi_serializer_bookmark.desktop akonadi_serializer_contactgroup.desktop - akonadi_serializer_microblog.desktop akonadi_serializer_kalarm.desktop -DESTINATION ${DATA_INSTALL_DIR}/akonadi/plugins/serializer) +DESTINATION ${KDE_INSTALL_DATADIR}/akonadi/plugins/serializer) + +if (BUILD_TESTING) + add_subdirectory( autotests ) +endif() + +if ("${CMAKE_BINARY_DIR}" STREQUAL "${plugins_BINARY_DIR}") + feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) +endif() diff -Nru kdepim-runtime-4.14.6/plugins/kaeventformatter.cpp kdepim-runtime-15.08.0/plugins/kaeventformatter.cpp --- kdepim-runtime-4.14.6/plugins/kaeventformatter.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/kaeventformatter.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -27,318 +27,314 @@ #include #include -#include #include -#include +#include static QString trueFalse(bool value); static QString number(unsigned long n); static QString minutes(int n); static QString minutesHoursDays(int minutes); -static QString dateTime(const KDateTime&); +static QString dateTime(const KDateTime &); -KAEventFormatter::KAEventFormatter(const KAEvent& e, bool falseForUnspecified) +KAEventFormatter::KAEventFormatter(const KAEvent &e, bool falseForUnspecified) : mEvent(e) { - if (falseForUnspecified) + if (falseForUnspecified) { mUnspecifiedValue = trueFalse(false); + } } QString KAEventFormatter::label(Parameter param) { - switch (param) - { - case Id: return i18nc("@label Unique identifier", "UID"); - case AlarmType: return i18nc("@label", "Alarm type"); - case AlarmCategory: return i18nc("@label", "Alarm status"); - case TemplateName: return i18nc("@label", "Template name"); - case CreatedTime: return i18nc("@label", "Creation time"); - case StartTime: return i18nc("@label", "Start time"); - case TemplateAfterTime: return i18nc("@label Start delay configured in an alarm template", "Template after time"); - case Recurs: return i18nc("@label", "Recurs"); - case Recurrence: return i18nc("@label", "Recurrence"); - case SubRepetition: return i18nc("@label", "Sub-repetition"); - case RepeatInterval: return i18nc("@label", "Sub-repetition interval"); - case RepeatCount: return i18nc("@label", "Sub-repetition count"); - case NextRepetition: return i18nc("@label", "Next sub-repetition"); - case WorkTimeOnly: return i18nc("@label", "Work time only"); - case HolidaysExcluded: return i18nc("@label", "Holidays excluded"); - case NextRecurrence: return i18nc("@label", "Next recurrence"); - case LateCancel: return i18nc("@label", "Late cancel"); - case AutoClose: return i18nc("@label Automatically close window", "Auto close"); - case CopyKOrganizer: return i18nc("@label", "Copy to KOrganizer"); - case Enabled: return i18nc("@label", "Enabled"); - case ReadOnly: return i18nc("@label", "Read-only"); - case Archive: return i18nc("@label Whether alarm should be archived", "Archive"); - case Revision: return i18nc("@label", "Revision"); - case CustomProperties: return i18nc("@label", "Custom properties"); - - case MessageText: return i18nc("@label", "Message text"); - case MessageFile: return i18nc("@label File to provide text for message", "Message file"); - case FgColour: return i18nc("@label", "Foreground color"); - case BgColour: return i18nc("@label", "Background color"); - case Font: return i18nc("@label", "Font"); - case PreAction: return i18nc("@label Shell command to execute before alarm", "Pre-alarm action"); - case PreActionCancel: return i18nc("@label", "Pre-alarm action cancel"); - case PreActionNoError: return i18nc("@label", "Pre-alarm action no error"); - case PostAction: return i18nc("@label Shell command to execute after alarm", "Post-alarm action"); - case ConfirmAck: return i18nc("@label", "Confirm acknowledgement"); - case KMailSerial: return i18nc("@label", "KMail serial number"); - case Sound: return i18nc("@label Audio method", "Sound"); - case SoundRepeat: return i18nc("@label Whether audio should repeat", "Sound repeat"); - case SoundVolume: return i18nc("@label", "Sound volume"); - case SoundFadeVolume: return i18nc("@label", "Sound fade volume"); - case SoundFadeTime: return i18nc("@label", "Sound fade time"); - case Reminder: return i18nc("@label Whether the alarm has a reminder", "Reminder"); - case ReminderOnce: return i18nc("@label Whether reminder is on first recurrence only", "Reminder once only"); - case DeferralType: return i18nc("@label Deferral type", "Deferral"); - case DeferralTime: return i18nc("@label", "Deferral time"); - case DeferDefault: return i18nc("@label Default deferral delay", "Deferral default"); - case DeferDefaultDate: return i18nc("@label Whether deferral time is date-only by default", "Deferral default date only"); - - case Command: return i18nc("@label A shell command", "Command"); - case LogFile: return i18nc("@label", "Log file"); - case CommandXTerm: return i18nc("@label Execute in terminal window", "Execute in terminal"); - - case EmailSubject: return i18nc("@label", "Email subject"); - case EmailFromId: return i18nc("@label Email address", "Email sender ID"); - case EmailTo: return i18nc("@label Email address", "Email to"); - case EmailBcc: return i18nc("@label true/false", "Email bcc"); - case EmailBody: return i18nc("@label", "Email body"); - case EmailAttachments: return i18nc("@label", "Email attachments"); + switch (param) { + case Id: return i18nc("@label Unique identifier", "UID"); + case AlarmType: return i18nc("@label", "Alarm type"); + case AlarmCategory: return i18nc("@label", "Alarm status"); + case TemplateName: return i18nc("@label", "Template name"); + case CreatedTime: return i18nc("@label", "Creation time"); + case StartTime: return i18nc("@label", "Start time"); + case TemplateAfterTime: return i18nc("@label Start delay configured in an alarm template", "Template after time"); + case Recurs: return i18nc("@label", "Recurs"); + case Recurrence: return i18nc("@label", "Recurrence"); + case SubRepetition: return i18nc("@label", "Sub-repetition"); + case RepeatInterval: return i18nc("@label", "Sub-repetition interval"); + case RepeatCount: return i18nc("@label", "Sub-repetition count"); + case NextRepetition: return i18nc("@label", "Next sub-repetition"); + case WorkTimeOnly: return i18nc("@label", "Work time only"); + case HolidaysExcluded: return i18nc("@label", "Holidays excluded"); + case NextRecurrence: return i18nc("@label", "Next recurrence"); + case LateCancel: return i18nc("@label", "Late cancel"); + case AutoClose: return i18nc("@label Automatically close window", "Auto close"); + case CopyKOrganizer: return i18nc("@label", "Copy to KOrganizer"); + case Enabled: return i18nc("@label", "Enabled"); + case ReadOnly: return i18nc("@label", "Read-only"); + case Archive: return i18nc("@label Whether alarm should be archived", "Archive"); + case Revision: return i18nc("@label", "Revision"); + case CustomProperties: return i18nc("@label", "Custom properties"); + + case MessageText: return i18nc("@label", "Message text"); + case MessageFile: return i18nc("@label File to provide text for message", "Message file"); + case FgColour: return i18nc("@label", "Foreground color"); + case BgColour: return i18nc("@label", "Background color"); + case Font: return i18nc("@label", "Font"); + case PreAction: return i18nc("@label Shell command to execute before alarm", "Pre-alarm action"); + case PreActionCancel: return i18nc("@label", "Pre-alarm action cancel"); + case PreActionNoError: return i18nc("@label", "Pre-alarm action no error"); + case PostAction: return i18nc("@label Shell command to execute after alarm", "Post-alarm action"); + case ConfirmAck: return i18nc("@label", "Confirm acknowledgement"); + case KMailSerial: return i18nc("@label", "KMail serial number"); + case Sound: return i18nc("@label Audio method", "Sound"); + case SoundRepeat: return i18nc("@label Whether audio should repeat", "Sound repeat"); + case SoundVolume: return i18nc("@label", "Sound volume"); + case SoundFadeVolume: return i18nc("@label", "Sound fade volume"); + case SoundFadeTime: return i18nc("@label", "Sound fade time"); + case Reminder: return i18nc("@label Whether the alarm has a reminder", "Reminder"); + case ReminderOnce: return i18nc("@label Whether reminder is on first recurrence only", "Reminder once only"); + case DeferralType: return i18nc("@label Deferral type", "Deferral"); + case DeferralTime: return i18nc("@label", "Deferral time"); + case DeferDefault: return i18nc("@label Default deferral delay", "Deferral default"); + case DeferDefaultDate: return i18nc("@label Whether deferral time is date-only by default", "Deferral default date only"); + + case Command: return i18nc("@label A shell command", "Command"); + case LogFile: return i18nc("@label", "Log file"); + case CommandXTerm: return i18nc("@label Execute in terminal window", "Execute in terminal"); + + case EmailSubject: return i18nc("@label", "Email subject"); + case EmailFromId: return i18nc("@label Email address", "Email sender ID"); + case EmailTo: return i18nc("@label Email address", "Email to"); + case EmailBcc: return i18nc("@label true/false", "Email bcc"); + case EmailBody: return i18nc("@label", "Email body"); + case EmailAttachments: return i18nc("@label", "Email attachments"); } return QString(); } bool KAEventFormatter::isApplicable(Parameter param) const { - switch (param) - { - case Id: - case AlarmType: - case AlarmCategory: - case CreatedTime: - case StartTime: - case Recurs: - case LateCancel: - case Enabled: - case ReadOnly: - case Archive: - case Revision: - case CustomProperties: - case CopyKOrganizer: - return true; - case TemplateName: - case TemplateAfterTime: - return mEvent.isTemplate(); - case Recurrence: - case RepeatCount: - case SubRepetition: - case WorkTimeOnly: - case HolidaysExcluded: - case NextRecurrence: - return mEvent.recurs(); - case RepeatInterval: - case NextRepetition: - return mEvent.repetition(); - case AutoClose: - return mEvent.lateCancel(); - - - case MessageText: - return mEvent.actionSubType() == KAEvent::MESSAGE; - case MessageFile: - return mEvent.actionSubType() == KAEvent::FILE; - case FgColour: - case BgColour: - case Font: - case PreAction: - case PostAction: - case ConfirmAck: - case KMailSerial: - case Reminder: - case DeferralType: - case DeferDefault: - return mEvent.actionTypes() & KAEvent::ACT_DISPLAY; - case ReminderOnce: - return mEvent.reminderMinutes() && mEvent.recurs(); - case DeferralTime: - return mEvent.deferred(); - case DeferDefaultDate: - return mEvent.deferDefaultMinutes() > 0; - case PreActionCancel: - case PreActionNoError: - return !mEvent.preAction().isEmpty(); - case Sound: - return mEvent.actionSubType() == KAEvent::MESSAGE || mEvent.actionSubType() == KAEvent::AUDIO; - case SoundRepeat: - return !mEvent.audioFile().isEmpty(); - case SoundVolume: - return mEvent.soundVolume() >= 0; - case SoundFadeVolume: - case SoundFadeTime: - return mEvent.fadeVolume() >= 0; - - case Command: - case LogFile: - case CommandXTerm: - return mEvent.actionSubType() == KAEvent::COMMAND; - - case EmailSubject: - case EmailFromId: - case EmailTo: - case EmailBcc: - case EmailBody: - case EmailAttachments: - return mEvent.actionSubType() == KAEvent::EMAIL; + switch (param) { + case Id: + case AlarmType: + case AlarmCategory: + case CreatedTime: + case StartTime: + case Recurs: + case LateCancel: + case Enabled: + case ReadOnly: + case Archive: + case Revision: + case CustomProperties: + case CopyKOrganizer: + return true; + case TemplateName: + case TemplateAfterTime: + return mEvent.isTemplate(); + case Recurrence: + case RepeatCount: + case SubRepetition: + case WorkTimeOnly: + case HolidaysExcluded: + case NextRecurrence: + return mEvent.recurs(); + case RepeatInterval: + case NextRepetition: + return mEvent.repetition(); + case AutoClose: + return mEvent.lateCancel(); + + case MessageText: + return mEvent.actionSubType() == KAEvent::MESSAGE; + case MessageFile: + return mEvent.actionSubType() == KAEvent::FILE; + case FgColour: + case BgColour: + case Font: + case PreAction: + case PostAction: + case ConfirmAck: + case KMailSerial: + case Reminder: + case DeferralType: + case DeferDefault: + return mEvent.actionTypes() & KAEvent::ACT_DISPLAY; + case ReminderOnce: + return mEvent.reminderMinutes() && mEvent.recurs(); + case DeferralTime: + return mEvent.deferred(); + case DeferDefaultDate: + return mEvent.deferDefaultMinutes() > 0; + case PreActionCancel: + case PreActionNoError: + return !mEvent.preAction().isEmpty(); + case Sound: + return mEvent.actionSubType() == KAEvent::MESSAGE || mEvent.actionSubType() == KAEvent::AUDIO; + case SoundRepeat: + return !mEvent.audioFile().isEmpty(); + case SoundVolume: + return mEvent.soundVolume() >= 0; + case SoundFadeVolume: + case SoundFadeTime: + return mEvent.fadeVolume() >= 0; + + case Command: + case LogFile: + case CommandXTerm: + return mEvent.actionSubType() == KAEvent::COMMAND; + + case EmailSubject: + case EmailFromId: + case EmailTo: + case EmailBcc: + case EmailBody: + case EmailAttachments: + return mEvent.actionSubType() == KAEvent::EMAIL; } return false; } QString KAEventFormatter::value(Parameter param) const { - switch (param) - { - case Id: return mEvent.id(); - case AlarmType: - switch (mEvent.actionSubType()) - { - case KAEvent::MESSAGE: return i18nc("@info/plain Alarm type", "Display (text)"); - case KAEvent::FILE: return i18nc("@info/plain Alarm type", "Display (file)"); - case KAEvent::COMMAND: return mEvent.commandDisplay() - ? i18nc("@info/plain Alarm type", "Display (command)") - : i18nc("@info/plain Alarm type", "Command"); - case KAEvent::EMAIL: return i18nc("@info/plain Alarm type", "Email"); - case KAEvent::AUDIO: return i18nc("@info/plain Alarm type", "Audio"); - } - break; - case AlarmCategory: - switch (mEvent.category()) - { - case CalEvent::ACTIVE: return i18nc("@info/plain Alarm type", "Active"); - case CalEvent::ARCHIVED: return i18nc("@info/plain Alarm type", "Archived"); - case CalEvent::TEMPLATE: return i18nc("@info/plain Alarm type", "Template"); - default: - break; - } + switch (param) { + case Id: return mEvent.id(); + case AlarmType: + switch (mEvent.actionSubType()) { + case KAEvent::MESSAGE: return i18nc("@info Alarm type", "Display (text)"); + case KAEvent::FILE: return i18nc("@info Alarm type", "Display (file)"); + case KAEvent::COMMAND: return mEvent.commandDisplay() + ? i18nc("@info Alarm type", "Display (command)") + : i18nc("@info Alarm type", "Command"); + case KAEvent::EMAIL: return i18nc("@info Alarm type", "Email"); + case KAEvent::AUDIO: return i18nc("@info Alarm type", "Audio"); + } + break; + case AlarmCategory: + switch (mEvent.category()) { + case CalEvent::ACTIVE: return i18nc("@info Alarm type", "Active"); + case CalEvent::ARCHIVED: return i18nc("@info Alarm type", "Archived"); + case CalEvent::TEMPLATE: return i18nc("@info Alarm type", "Template"); + default: break; - case TemplateName: return mEvent.templateName(); - case CreatedTime: return mEvent.createdDateTime().toUtc().toString(QLatin1String("%Y-%m-%d %H:%M:%SZ")); - case StartTime: return dateTime(mEvent.startDateTime().kDateTime()); - case TemplateAfterTime: return (mEvent.templateAfterTime() >= 0) ? number(mEvent.templateAfterTime()) : trueFalse(false); - case Recurs: return trueFalse(mEvent.recurs()); - case Recurrence: - { - if (mEvent.repeatAtLogin(true)) - return i18nc("@info/plain Repeat at login", "At login until %1", dateTime(mEvent.mainDateTime().kDateTime())); - KCalCore::Event::Ptr eptr(new KCalCore::Event); - mEvent.updateKCalEvent(eptr, KAEvent::UID_SET); - return KCalUtils::IncidenceFormatter::recurrenceString(eptr); } - case NextRecurrence: return dateTime(mEvent.mainDateTime().kDateTime()); - case SubRepetition: return trueFalse(mEvent.repetition()); - case RepeatInterval: return mEvent.repetitionText(true); - case RepeatCount: return mEvent.repetition() ? number(mEvent.repetition().count()) : QString(); - case NextRepetition: return mEvent.repetition() ? number(mEvent.nextRepetition()) : QString(); - case WorkTimeOnly: return trueFalse(mEvent.workTimeOnly()); - case HolidaysExcluded: return trueFalse(mEvent.holidaysExcluded()); - case LateCancel: return mEvent.lateCancel() ? minutesHoursDays(mEvent.lateCancel()) : trueFalse(false); - case AutoClose: return trueFalse(mEvent.lateCancel() ? mEvent.autoClose() : false); - case CopyKOrganizer: return trueFalse(mEvent.copyToKOrganizer()); - case Enabled: return trueFalse(mEvent.enabled()); - case ReadOnly: return trueFalse(mEvent.isReadOnly()); - case Archive: return trueFalse(mEvent.toBeArchived()); - case Revision: return number(mEvent.revision()); - case CustomProperties: - { - if (mEvent.customProperties().isEmpty()) - return QString(); - QString value; - for (QMap::ConstIterator it = mEvent.customProperties().constBegin(); it != mEvent.customProperties().constEnd(); ++it) - value += QString::fromLatin1(it.key()) + QLatin1String(":") + it.value() + QLatin1String(""); - return i18nc("@info/plain", "%1", value); + break; + case TemplateName: return mEvent.templateName(); + case CreatedTime: return mEvent.createdDateTime().toUtc().toString(QLatin1String("%Y-%m-%d %H:%M:%SZ")); + case StartTime: return dateTime(mEvent.startDateTime().kDateTime()); + case TemplateAfterTime: return (mEvent.templateAfterTime() >= 0) ? number(mEvent.templateAfterTime()) : trueFalse(false); + case Recurs: return trueFalse(mEvent.recurs()); + case Recurrence: { + if (mEvent.repeatAtLogin(true)) { + return i18nc("@info Repeat at login", "At login until %1", dateTime(mEvent.mainDateTime().kDateTime())); + } + KCalCore::Event::Ptr eptr(new KCalCore::Event); + mEvent.updateKCalEvent(eptr, KAEvent::UID_SET); + return KCalUtils::IncidenceFormatter::recurrenceString(eptr); + } + case NextRecurrence: return dateTime(mEvent.mainDateTime().kDateTime()); + case SubRepetition: return trueFalse(mEvent.repetition()); + case RepeatInterval: return mEvent.repetitionText(true); + case RepeatCount: return mEvent.repetition() ? number(mEvent.repetition().count()) : QString(); + case NextRepetition: return mEvent.repetition() ? number(mEvent.nextRepetition()) : QString(); + case WorkTimeOnly: return trueFalse(mEvent.workTimeOnly()); + case HolidaysExcluded: return trueFalse(mEvent.holidaysExcluded()); + case LateCancel: return mEvent.lateCancel() ? minutesHoursDays(mEvent.lateCancel()) : trueFalse(false); + case AutoClose: return trueFalse(mEvent.lateCancel() ? mEvent.autoClose() : false); + case CopyKOrganizer: return trueFalse(mEvent.copyToKOrganizer()); + case Enabled: return trueFalse(mEvent.enabled()); + case ReadOnly: return trueFalse(mEvent.isReadOnly()); + case Archive: return trueFalse(mEvent.toBeArchived()); + case Revision: return number(mEvent.revision()); + case CustomProperties: { + if (mEvent.customProperties().isEmpty()) { + return QString(); } + QString value; + for (QMap::ConstIterator it = mEvent.customProperties().constBegin(); it != mEvent.customProperties().constEnd(); ++it) { + value += QString::fromLatin1(it.key()) + QLatin1String(":") + it.value() + QLatin1String(""); + } + return i18nc("@info", "%1", value); + } - case MessageText: return (mEvent.actionSubType() == KAEvent::MESSAGE) ? mEvent.cleanText() : QString(); - case MessageFile: return (mEvent.actionSubType() == KAEvent::FILE) ? mEvent.cleanText() : QString(); - case FgColour: return mEvent.fgColour().name(); - case BgColour: return mEvent.bgColour().name(); - case Font: return mEvent.useDefaultFont() ? i18nc("@info/plain Using default font", "Default") : mEvent.font().toString(); - case PreActionCancel: return trueFalse(mEvent.cancelOnPreActionError()); - case PreActionNoError: return trueFalse(mEvent.dontShowPreActionError()); - case PreAction: return mEvent.preAction(); - case PostAction: return mEvent.postAction(); - case Reminder: return mEvent.reminderMinutes() ? minutesHoursDays(mEvent.reminderMinutes()) : trueFalse(false); - case ReminderOnce: return trueFalse(mEvent.reminderOnceOnly()); - case DeferralType: return mEvent.reminderDeferral() ? i18nc("@info/plain", "Reminder") : trueFalse(mEvent.deferred()); - case DeferralTime: return mEvent.deferred() ? dateTime(mEvent.deferDateTime().kDateTime()) : trueFalse(false); - case DeferDefault: return (mEvent.deferDefaultMinutes() > 0) ? minutes(mEvent.deferDefaultMinutes()) : trueFalse(false); - case DeferDefaultDate: return trueFalse(mEvent.deferDefaultDateOnly()); - case ConfirmAck: return trueFalse(mEvent.confirmAck()); - case KMailSerial: return mEvent.kmailSerialNumber() ? number(mEvent.kmailSerialNumber()) : trueFalse(false); - case Sound: return !mEvent.audioFile().isEmpty() ? mEvent.audioFile() - : mEvent.speak() ? i18nc("@info/plain", "Speak") - : mEvent.beep() ? i18nc("@info/plain", "Beep") : trueFalse(false); - case SoundRepeat: return trueFalse(mEvent.repeatSound()); - case SoundVolume: return mEvent.soundVolume() >= 0 - ? i18nc("@info/plain Percentage", "%1%%", static_cast(mEvent.soundVolume() * 100)) - : mUnspecifiedValue; - case SoundFadeVolume: return mEvent.fadeVolume() >= 0 - ? i18nc("@info/plain Percentage", "%1%%", static_cast(mEvent.fadeVolume() * 100)) - : mUnspecifiedValue; - case SoundFadeTime: return mEvent.fadeSeconds() - ? i18ncp("@info/plain", "1 Second", "%1 Seconds", mEvent.fadeSeconds()) - : mUnspecifiedValue; - - case Command: return (mEvent.actionSubType() == KAEvent::COMMAND) ? mEvent.cleanText() : QString(); - case LogFile: return mEvent.logFile(); - case CommandXTerm: return trueFalse(mEvent.commandXterm()); - - case EmailSubject: return mEvent.emailSubject(); - case EmailFromId: return (mEvent.actionSubType() == KAEvent::EMAIL) ? number(mEvent.emailFromId()) : QString(); - case EmailTo: return mEvent.emailAddresses(QLatin1String(", ")); - case EmailBcc: return trueFalse(mEvent.emailBcc()); - case EmailBody: return mEvent.emailMessage(); - case EmailAttachments: return mEvent.emailAttachments(QLatin1String(", ")); + case MessageText: return (mEvent.actionSubType() == KAEvent::MESSAGE) ? mEvent.cleanText() : QString(); + case MessageFile: return (mEvent.actionSubType() == KAEvent::FILE) ? mEvent.cleanText() : QString(); + case FgColour: return mEvent.fgColour().name(); + case BgColour: return mEvent.bgColour().name(); + case Font: return mEvent.useDefaultFont() ? i18nc("@info Using default font", "Default") : mEvent.font().toString(); + case PreActionCancel: return trueFalse(mEvent.extraActionOptions() & KAEvent::CancelOnPreActError); + case PreActionNoError: return trueFalse(mEvent.extraActionOptions() & KAEvent::CancelOnPreActError); + case PreAction: return mEvent.preAction(); + case PostAction: return mEvent.postAction(); + case Reminder: return mEvent.reminderMinutes() ? minutesHoursDays(mEvent.reminderMinutes()) : trueFalse(false); + case ReminderOnce: return trueFalse(mEvent.reminderOnceOnly()); + case DeferralType: return mEvent.reminderDeferral() ? i18nc("@info", "Reminder") : trueFalse(mEvent.deferred()); + case DeferralTime: return mEvent.deferred() ? dateTime(mEvent.deferDateTime().kDateTime()) : trueFalse(false); + case DeferDefault: return (mEvent.deferDefaultMinutes() > 0) ? minutes(mEvent.deferDefaultMinutes()) : trueFalse(false); + case DeferDefaultDate: return trueFalse(mEvent.deferDefaultDateOnly()); + case ConfirmAck: return trueFalse(mEvent.confirmAck()); + case KMailSerial: return mEvent.kmailSerialNumber() ? number(mEvent.kmailSerialNumber()) : trueFalse(false); + case Sound: return !mEvent.audioFile().isEmpty() ? mEvent.audioFile() + : mEvent.speak() ? i18nc("@info", "Speak") + : mEvent.beep() ? i18nc("@info", "Beep") : trueFalse(false); + case SoundRepeat: return trueFalse(mEvent.repeatSound()); + case SoundVolume: return mEvent.soundVolume() >= 0 + ? i18nc("@info Percentage", "%1%%", static_cast(mEvent.soundVolume() * 100)) + : mUnspecifiedValue; + case SoundFadeVolume: return mEvent.fadeVolume() >= 0 + ? i18nc("@info Percentage", "%1%%", static_cast(mEvent.fadeVolume() * 100)) + : mUnspecifiedValue; + case SoundFadeTime: return mEvent.fadeSeconds() + ? i18ncp("@info", "1 Second", "%1 Seconds", mEvent.fadeSeconds()) + : mUnspecifiedValue; + + case Command: return (mEvent.actionSubType() == KAEvent::COMMAND) ? mEvent.cleanText() : QString(); + case LogFile: return mEvent.logFile(); + case CommandXTerm: return trueFalse(mEvent.commandXterm()); + + case EmailSubject: return mEvent.emailSubject(); + case EmailFromId: return (mEvent.actionSubType() == KAEvent::EMAIL) ? number(mEvent.emailFromId()) : QString(); + case EmailTo: return mEvent.emailAddresses(QLatin1String(", ")); + case EmailBcc: return trueFalse(mEvent.emailBcc()); + case EmailBody: return mEvent.emailMessage(); + case EmailAttachments: return mEvent.emailAttachments(QLatin1String(", ")); } - return i18nc("@info/plain Error indication", "error!"); + return i18nc("@info Error indication", "error!"); } QString trueFalse(bool value) { - return value ? i18nc("@info/plain General purpose status indication: yes or no", "Yes") - : i18nc("@info/plain General purpose status indication: yes or no", "No"); + return value ? i18nc("@info General purpose status indication: yes or no", "Yes") + : i18nc("@info General purpose status indication: yes or no", "No"); } // Convert an integer to digits for the locale. // Do not use for date/time or monetary numbers (which have their own digit sets). QString number(unsigned long n) { - KLocale* locale = KGlobal::locale(); + KLocale *locale = KLocale::global(); return locale->convertDigits(QString::number(n), locale->digitSet()); } QString minutes(int n) { - return i18ncp("@info/plain", "1 Minute", "%1 Minutes", n); + return i18ncp("@info", "1 Minute", "%1 Minutes", n); } -QString dateTime(const KDateTime& dt) +QString dateTime(const KDateTime &dt) { - if (dt.isDateOnly()) + if (dt.isDateOnly()) { return dt.toString(QLatin1String("%Y-%m-%d %:Z")); - else + } else { return dt.toString(QLatin1String("%Y-%m-%d %H:%M %:Z")); + } } QString minutesHoursDays(int minutes) { - if (minutes % 60) - return i18ncp("@info/plain", "1 Minute", "%1 Minutes", minutes); - else if (minutes % 1440) - return i18ncp("@info/plain", "1 Hour", "%1 Hours", minutes/60); - else - return i18ncp("@info/plain", "1 Day", "%1 Days", minutes/1440); + if (minutes % 60) { + return i18ncp("@info", "1 Minute", "%1 Minutes", minutes); + } else if (minutes % 1440) { + return i18ncp("@info", "1 Hour", "%1 Hours", minutes / 60); + } else { + return i18ncp("@info", "1 Day", "%1 Days", minutes / 1440); + } } -// vim: et sw=4: diff -Nru kdepim-runtime-4.14.6/plugins/kaeventformatter.h kdepim-runtime-15.08.0/plugins/kaeventformatter.h --- kdepim-runtime-4.14.6/plugins/kaeventformatter.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/kaeventformatter.h 2015-08-10 21:01:02.000000000 +0000 @@ -29,84 +29,85 @@ class KAEventFormatter { - public: - // KAEvent parameter identifiers. - // Note that parameters stored in Akonadi attributes are not included. - enum Parameter - { - Id, - AlarmType, - AlarmCategory, - TemplateName, - CreatedTime, - StartTime, - TemplateAfterTime, - Recurs, // does the event recur? - Recurrence, - NextRecurrence, // next alarm time excluding repetitions, including reminder/deferral - SubRepetition, // is there a sub-repetition? - RepeatInterval, - RepeatCount, - NextRepetition, // next repetition count - LateCancel, - AutoClose, - WorkTimeOnly, - HolidaysExcluded, - CopyKOrganizer, - Enabled, - ReadOnly, - Archive, - Revision, - CustomProperties, - - MessageText, - MessageFile, - FgColour, - BgColour, - Font, - PreAction, - PreActionCancel, - PreActionNoError, - PostAction, - ConfirmAck, - KMailSerial, - Sound, - SoundRepeat, - SoundVolume, - SoundFadeVolume, - SoundFadeTime, - Reminder, - ReminderOnce, - DeferralType, - DeferralTime, - DeferDefault, - DeferDefaultDate, - - Command, - LogFile, - CommandXTerm, - - EmailSubject, - EmailFromId, - EmailTo, - EmailBcc, - EmailBody, - EmailAttachments - - }; - - KAEventFormatter() {} - KAEventFormatter(const KAEvent& e, bool falseForUnspecified); - bool isApplicable(Parameter) const; - QString value(Parameter) const; - const KAEvent& event() const { return mEvent; } - static QString label(Parameter); - - private: - KAEvent mEvent; - QString mUnspecifiedValue; +public: + // KAEvent parameter identifiers. + // Note that parameters stored in Akonadi attributes are not included. + enum Parameter { + Id, + AlarmType, + AlarmCategory, + TemplateName, + CreatedTime, + StartTime, + TemplateAfterTime, + Recurs, // does the event recur? + Recurrence, + NextRecurrence, // next alarm time excluding repetitions, including reminder/deferral + SubRepetition, // is there a sub-repetition? + RepeatInterval, + RepeatCount, + NextRepetition, // next repetition count + LateCancel, + AutoClose, + WorkTimeOnly, + HolidaysExcluded, + CopyKOrganizer, + Enabled, + ReadOnly, + Archive, + Revision, + CustomProperties, + + MessageText, + MessageFile, + FgColour, + BgColour, + Font, + PreAction, + PreActionCancel, + PreActionNoError, + PostAction, + ConfirmAck, + KMailSerial, + Sound, + SoundRepeat, + SoundVolume, + SoundFadeVolume, + SoundFadeTime, + Reminder, + ReminderOnce, + DeferralType, + DeferralTime, + DeferDefault, + DeferDefaultDate, + + Command, + LogFile, + CommandXTerm, + + EmailSubject, + EmailFromId, + EmailTo, + EmailBcc, + EmailBody, + EmailAttachments + + }; + + KAEventFormatter() {} + KAEventFormatter(const KAEvent &e, bool falseForUnspecified); + bool isApplicable(Parameter) const; + QString value(Parameter) const; + const KAEvent &event() const + { + return mEvent; + } + static QString label(Parameter); + +private: + KAEvent mEvent; + QString mUnspecifiedValue; }; #endif // KAEVENTFORMATTER_H -// vim: et sw=4: diff -Nru kdepim-runtime-4.14.6/plugins/tests/addresseeserializertest.cpp kdepim-runtime-15.08.0/plugins/tests/addresseeserializertest.cpp --- kdepim-runtime-4.14.6/plugins/tests/addresseeserializertest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/tests/addresseeserializertest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 -#include -#include -#include - -using namespace Akonadi; - -class AddresseeSerializerTest : public QObject -{ - Q_OBJECT - private slots: - void testGid() - { - const QString uid(QLatin1String("uid")); - KABC::Addressee addressee; - addressee.setUid(uid); - Akonadi::Item item; - item.setMimeType(addressee.mimeType()); - item.setPayload(addressee); - SerializerPluginAddressee plugin; - const QString gid = plugin.extractGid(item); - QCOMPARE(gid, uid); - } -}; - -QTEST_KDEMAIN( AddresseeSerializerTest, NoGUI ) - -#include "addresseeserializertest.moc" diff -Nru kdepim-runtime-4.14.6/plugins/tests/CMakeLists.txt kdepim-runtime-15.08.0/plugins/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/plugins/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - -include_directories( - ${kdepim-runtime_SOURCE_DIR}/plugins - ${kdepim-runtime_BINARY_DIR}/plugins - ${Boost_INCLUDE_DIR} -) - -# convenience macro to add akonadi qtestlib unit-tests -macro(add_akonadiplugin_test _source _libs _additionalSources) - set(_test ${_source}) - get_filename_component(_name ${_source} NAME_WE) - set(srcs ${_test} ${_additionalSources}) - kde4_add_unit_test(${_name} TESTNAME akonadiplugin-${_name} ${srcs}) - target_link_libraries(${_name} ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_AKONADI_KMIME_LIBS} ${KDE4_KDECORE_LIBS} - ${QT_QTGUI_LIBRARY} ${QT_QTTEST_LIBRARY} ${AKONADI_COMMON_LIBRARIES} - ${AKONADI_COMMON_LIBRARIES} ${_libs}) -endmacro() - -# qtestlib unit tests -add_akonadiplugin_test(mailserializertest.cpp "${KDEPIMLIBS_KMIME_LIBS}" "") -add_akonadiplugin_test(mailserializerplugintest.cpp "${KDEPIMLIBS_KMIME_LIBS}" "") - -add_akonadiplugin_test(kcalcoreserializertest.cpp "${KDEPIMLIBS_KCALCORE_LIBS}" "") - -add_akonadiplugin_test(addresseeserializertest.cpp "${KDEPIMLIBS_KABC_LIBS};${KDEPIMLIBS_AKONADI_KABC_LIBS}" "../akonadi_serializer_addressee.cpp") - -if (KDEPIMLIBS_KCAL_LIBS) - add_akonadiplugin_test(kcalserializertest.cpp "${KDEPIMLIBS_KCAL_LIBS}" "") -endif () diff -Nru kdepim-runtime-4.14.6/plugins/tests/kcalcoreserializertest.cpp kdepim-runtime-15.08.0/plugins/tests/kcalcoreserializertest.cpp --- kdepim-runtime-4.14.6/plugins/tests/kcalcoreserializertest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/tests/kcalcoreserializertest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,133 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 -#include -#include -#include - -using namespace Akonadi; -using namespace KCalCore; - -class KCalCoreSerializerTest : public QObject -{ - Q_OBJECT - private slots: - void testEventSerialize_data() - { - QTest::addColumn( "mimeType" ); - QTest::newRow( "specific" ) << "application/x-vnd.akonadi.calendar.event"; - QTest::newRow( "generic" ) << "text/calendar"; - } - void testCharsets_data() - { - testEventSerialize_data(); - } - - void testEventSerialize() - { - QFETCH( QString, mimeType ); - - QByteArray serialized = - "BEGIN:VCALENDAR\n" - "PRODID:-//K Desktop Environment//NONSGML libkcal 3.5//EN\n" - "VERSION:2.0\n" - "BEGIN:VEVENT\n" - "DTSTAMP:20070109T100625Z\n" - "ORGANIZER;CN=\"Volker Krause\":MAILTO:vkrause@kde.org\n" - "CREATED:20070109T100553Z\n" - "UID:libkcal-1135684253.945\n" - "SEQUENCE:1\n" - "LAST-MODIFIED:20070109T100625Z\n" - "SUMMARY:Test event\n" - "LOCATION:here\n" - "CLASS:PUBLIC\n" - "PRIORITY:5\n" - "CATEGORIES:KDE\n" - "DTSTART:20070109T183000Z\n" - "DTEND:20070109T225900Z\n" - "TRANSP:OPAQUE\n" - "BEGIN:VALARM\n" - "DESCRIPTION:\n" - "ACTION:DISPLAY\n" - "TRIGGER;VALUE=DURATION:-PT45M\n" - "END:VALARM\n" - "END:VEVENT\n" - "END:VCALENDAR\n"; - - // deserializing - Item item; - item.setMimeType( mimeType ); - item.setPayloadFromData( serialized ); - - QVERIFY( item.hasPayload() ); - const Event::Ptr event = item.payload(); - QVERIFY( event != 0 ); - - QCOMPARE( event->summary(), QLatin1String( "Test event" ) ); - QCOMPARE( event->location(), QLatin1String( "here" ) ); - - // serializing - const QByteArray data = item.payloadData(); - QVERIFY( !data.isEmpty() ); - } - - void testCharsets() - { - QFETCH( QString, mimeType ); - - // 0 defaults to latin1. - QVERIFY( QTextCodec::codecForCStrings() == 0 ); - - const QDate currentDate = QDate::currentDate(); - - Event::Ptr event = Event::Ptr( new Event() ); - event->setUid( QLatin1String("12345") ); - event->setDtStart( KDateTime( currentDate ) ); - event->setDtEnd( KDateTime( currentDate.addDays( 1 ) ) ); - - // ü - const char latin1_umlaut[] = { 0xFC, '\0' }; - event->setSummary( QLatin1String(latin1_umlaut) ); - - Item item; - item.setMimeType( mimeType ); - item.setPayload( event ); - - // Serializer the item, the serialization should be in UTF-8: - const char utf_umlaut[] = { 0xC3, 0XBC, '\0' }; - const QByteArray bytes = item.payloadData(); - QVERIFY( bytes.contains( utf_umlaut ) ); - QVERIFY( !bytes.contains( latin1_umlaut ) ); - - // Deserialize the data: - Item item2; - item2.setMimeType( mimeType ); - item2.setPayloadFromData( bytes ); - - Event::Ptr event2 = item2.payload(); - QVERIFY( event2 != 0 ); - QVERIFY( event2->summary().toUtf8() == QByteArray( utf_umlaut ) ); - QVERIFY( event2->summary().toLatin1() == QByteArray( latin1_umlaut ) ); - } -}; - -QTEST_KDEMAIN( KCalCoreSerializerTest, NoGUI ) - -#include "kcalcoreserializertest.moc" diff -Nru kdepim-runtime-4.14.6/plugins/tests/kcalserializertest.cpp kdepim-runtime-15.08.0/plugins/tests/kcalserializertest.cpp --- kdepim-runtime-4.14.6/plugins/tests/kcalserializertest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/tests/kcalserializertest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,135 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 -#include -#include -#include -#include - -using namespace Akonadi; -using namespace KCal; - -class KCalSerializerTest : public QObject -{ - Q_OBJECT - private slots: - void testEventSerialize_data() - { - QTest::addColumn( "mimeType" ); - QTest::newRow( "specific" ) << "application/x-vnd.akonadi.calendar.event"; - QTest::newRow( "generic" ) << "text/calendar"; - } - - void testCharsets_data() - { - testEventSerialize_data(); - } - - void testEventSerialize() - { - QFETCH( QString, mimeType ); - - QByteArray serialized = - "BEGIN:VCALENDAR\n" - "PRODID:-//K Desktop Environment//NONSGML libkcal 3.5//EN\n" - "VERSION:2.0\n" - "BEGIN:VEVENT\n" - "DTSTAMP:20070109T100625Z\n" - "ORGANIZER;CN=\"Volker Krause\":MAILTO:vkrause@kde.org\n" - "CREATED:20070109T100553Z\n" - "UID:libkcal-1135684253.945\n" - "SEQUENCE:1\n" - "LAST-MODIFIED:20070109T100625Z\n" - "SUMMARY:Test event\n" - "LOCATION:here\n" - "CLASS:PUBLIC\n" - "PRIORITY:5\n" - "CATEGORIES:KDE\n" - "DTSTART:20070109T183000Z\n" - "DTEND:20070109T225900Z\n" - "TRANSP:OPAQUE\n" - "BEGIN:VALARM\n" - "DESCRIPTION:\n" - "ACTION:DISPLAY\n" - "TRIGGER;VALUE=DURATION:-PT45M\n" - "END:VALARM\n" - "END:VEVENT\n" - "END:VCALENDAR\n"; - - // deserializing - Item item; - item.setMimeType( mimeType ); - item.setPayloadFromData( serialized ); - - QVERIFY( item.hasPayload() ); - const Event::Ptr event = item.payload(); - QVERIFY( event != 0 ); - - QCOMPARE( event->summary(), QLatin1String( "Test event" ) ); - QCOMPARE( event->location(), QLatin1String( "here" ) ); - - // serializing - const QByteArray data = item.payloadData(); - QVERIFY( !data.isEmpty() ); - } - - void testCharsets() - { - QFETCH( QString, mimeType ); - - // 0 defaults to latin1. - QVERIFY( QTextCodec::codecForCStrings() == 0 ); - - const QDate currentDate = QDate::currentDate(); - - Event::Ptr event = Event::Ptr( new Event() ); - event->setUid( QLatin1String("12345") ); - event->setDtStart( KDateTime( currentDate ) ); - event->setDtEnd( KDateTime( currentDate.addDays( 1 ) ) ); - - // ü - const char latin1_umlaut[] = { 0xFC, '\0' }; - event->setSummary( QLatin1String(latin1_umlaut) ); - - Item item; - item.setMimeType( mimeType ); - item.setPayload( event ); - - // Serializer the item, the serialization should be in UTF-8: - const char utf_umlaut[] = { 0xC3, 0XBC, '\0' }; - const QByteArray bytes = item.payloadData(); - QVERIFY( bytes.contains( utf_umlaut ) ); - QVERIFY( !bytes.contains( latin1_umlaut ) ); - - // Deserialize the data: - Item item2; - item2.setMimeType( mimeType ); - item2.setPayloadFromData( bytes ); - - Event::Ptr event2 = item2.payload(); - QVERIFY( event2 != 0 ); - QVERIFY( event2->summary().toUtf8() == QByteArray( utf_umlaut ) ); - QVERIFY( event2->summary().toLatin1() == QByteArray( latin1_umlaut ) ); - } -}; - -QTEST_KDEMAIN( KCalSerializerTest, NoGUI ) - -#include "kcalserializertest.moc" diff -Nru kdepim-runtime-4.14.6/plugins/tests/mailserializerplugintest.cpp kdepim-runtime-15.08.0/plugins/tests/mailserializerplugintest.cpp --- kdepim-runtime-4.14.6/plugins/tests/mailserializerplugintest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/tests/mailserializerplugintest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -/* - Copyright (c) 2007 Volker Krause - - 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 "mailserializerplugintest.h" - -#include -#include -#include - -#include - -QTEST_KDEMAIN( MailSerializerPluginTest, NoGUI ) - -using namespace Akonadi; -using namespace KMime; - -void MailSerializerPluginTest::testMailPlugin() -{ - QByteArray serialized = - "From: sender@test.org\n" - "Subject: Serializer Test\n" - "To: receiver@test.org\n" - "Date: Fri, 22 Jun 2007 17:24:24 +0000\n" - "MIME-Version: 1.0\n" - "Content-Type: text/plain\n" - "\n" - "Body data."; - - // deserializing - Item item; - item.setMimeType( QLatin1String("message/rfc822") ); - item.setPayloadFromData( serialized ); - - QVERIFY( item.hasPayload() ); - KMime::Message::Ptr msg = item.payload(); - QVERIFY( msg != 0 ); - - QCOMPARE( msg->to()->asUnicodeString(), QLatin1String( "receiver@test.org" ) ); - QCOMPARE( msg->body(), QByteArray( "Body data." ) ); - - // serializing - QByteArray data = item.payloadData(); - QCOMPARE( data, serialized ); -} - -void MailSerializerPluginTest::testMessageIntegrity() -{ - // A message that will be slightly modified if KMime::Content::assemble() is - // called. We want to avoid this, because it breaks signatures. - QByteArray serialized = - "from: sender@example.com\n" - "to: receiver@example.com\n" - "Subject: Serializer Test\n" - "Date: Thu, 30 Jul 2009 13:46:31 +0300\n" - "MIME-Version: 1.0\n" - "Content-type: text/plain; charset=us-ascii\n" - "\n" - "Bla bla bla."; - - // Deserialize. - Item item; - item.setMimeType( QLatin1String("message/rfc822") ); - item.setPayloadFromData( serialized ); - - QVERIFY( item.hasPayload() ); - KMime::Message::Ptr msg = item.payload(); - QVERIFY( msg != 0 ); - - kDebug() << "original data:" << serialized; - kDebug() << "message content:" << msg->encodedContent(); - QCOMPARE( msg->encodedContent(), serialized ); - - // Serialize. - QByteArray data = item.payloadData(); - kDebug() << "original data:" << serialized; - kDebug() << "serialized data:" << data; - QCOMPARE( data, serialized ); -} - diff -Nru kdepim-runtime-4.14.6/plugins/tests/mailserializerplugintest.h kdepim-runtime-15.08.0/plugins/tests/mailserializerplugintest.h --- kdepim-runtime-4.14.6/plugins/tests/mailserializerplugintest.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/tests/mailserializerplugintest.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -/* - Copyright (c) 2007 Volker Krause - - 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 MAILSERIALIZERPLUGINTEST_H -#define MAILSERIALIZERPLUGINTEST_H - -#include - -class MailSerializerPluginTest : public QObject -{ - Q_OBJECT - private slots: - void testMailPlugin(); - void testMessageIntegrity(); -}; - - -#endif diff -Nru kdepim-runtime-4.14.6/plugins/tests/mailserializertest.cpp kdepim-runtime-15.08.0/plugins/tests/mailserializertest.cpp --- kdepim-runtime-4.14.6/plugins/tests/mailserializertest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/tests/mailserializertest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,264 +0,0 @@ -/* - Copyright (c) 2007 Volker Krause - - 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 "mailserializertest.h" - -#include "akonadi_serializer_mail.cpp" - -#include - -#include - -QTEST_KDEMAIN( MailSerializerTest, NoGUI ) - -void MailSerializerTest::testEnvelopeDeserialize() -{ - Item i; - i.setMimeType( QLatin1String("message/rfc822") ); - - SerializerPluginMail *serializer = new SerializerPluginMail(); - - // envelope - QByteArray env( "(\"Wed, 1 Feb 2006 13:37:19 UT\" \"IMPORTANT: Akonadi Test\" ((\"Tobias Koenig\" NIL \"tokoe\" \"kde.org\")) ((\"Tobias Koenig\" NIL \"tokoe\" \"kde.org\")) NIL ((\"Ingo Kloecker\" NIL \"kloecker\" \"kde.org\")) NIL NIL NIL <{7b55527e-77f4-489d-bf18-e805be96718c}@server.kde.org>)" ); - QBuffer buffer; - buffer.setData( env ); - buffer.open( QIODevice::ReadOnly ); - buffer.seek( 0 ); - QBENCHMARK { - serializer->deserialize( i, MessagePart::Envelope, buffer, 0 ); - } - QVERIFY( i.hasPayload() ); - - KMime::Message::Ptr msg = i.payload(); - QCOMPARE( msg->subject()->asUnicodeString(), QString::fromUtf8( "IMPORTANT: Akonadi Test" ) ); - QCOMPARE( msg->from()->asUnicodeString(), QString::fromUtf8( "Tobias Koenig " ) ); - QCOMPARE( msg->to()->asUnicodeString(), QString::fromUtf8( "Ingo Kloecker " ) ); - - delete serializer; -} - -void MailSerializerTest::testEnvelopeDeserializeWithReferencesHeader() -{ - Item i; - i.setMimeType( QLatin1String("message/rfc822") ); - - SerializerPluginMail *serializer = new SerializerPluginMail(); - - // envelope - QByteArray env( "(\"Wed, 1 Feb 2006 13:37:19 UT\" \"IMPORTANT: Akonadi Test\" ((\"Tobias Koenig\" NIL \"tokoe\" \"kde.org\")) ((\"Tobias Koenig\" NIL \"tokoe\" \"kde.org\")) NIL ((\"Ingo Kloecker\" NIL \"kloecker\" \"kde.org\")) NIL NIL NIL <{7b55527e-77f4-489d-bf18-e805be96718c}@server.kde.org> \"<{8888827e-77f4-489d-bf18-e805be96718c}@server.kde.org> <{9999927e-77f4-489d-bf18-e805be96718c}@server.kde.org>\")" ); - QBuffer buffer; - buffer.setData( env ); - buffer.open( QIODevice::ReadOnly ); - buffer.seek( 0 ); - QBENCHMARK { - serializer->deserialize( i, MessagePart::Envelope, buffer, 1 ); - } - QVERIFY( i.hasPayload() ); - - KMime::Message::Ptr msg = i.payload(); - QCOMPARE( msg->subject()->asUnicodeString(), QString::fromUtf8( "IMPORTANT: Akonadi Test" ) ); - QCOMPARE( msg->from()->asUnicodeString(), QString::fromUtf8( "Tobias Koenig " ) ); - QCOMPARE( msg->to()->asUnicodeString(), QString::fromUtf8( "Ingo Kloecker " ) ); - QCOMPARE( msg->references()->asUnicodeString(), QString::fromUtf8( "<{8888827e-77f4-489d-bf18-e805be96718c}@server.kde.org> <{9999927e-77f4-489d-bf18-e805be96718c}@server.kde.org>" ) ); - - delete serializer; -} - -void MailSerializerTest::testEnvelopeSerialize() -{ - Item i; - i.setMimeType( QLatin1String("message/rfc822") ); - Message* msg = new Message(); - msg->date()->from7BitString( "Wed, 1 Feb 2006 13:37:19 UT" ); - msg->subject()->from7BitString( "IMPORTANT: Akonadi Test" ); - msg->from()->from7BitString( "Tobias Koenig " ); - msg->sender()->from7BitString( "Tobias Koenig " ); - msg->to()->from7BitString( "Ingo Kloecker " ); - msg->messageID()->from7BitString( "<{7b55527e-77f4-489d-bf18-e805be96718c}@server.kde.org>" ); - i.setPayload( KMime::Message::Ptr( msg ) ); - - SerializerPluginMail *serializer = new SerializerPluginMail(); - - // envelope - QByteArray expEnv( "(\"Wed, 01 Feb 2006 13:37:19 +0000\" \"IMPORTANT: Akonadi Test\" ((\"Tobias Koenig\" NIL \"tokoe\" \"kde.org\")) ((\"Tobias Koenig\" NIL \"tokoe\" \"kde.org\")) NIL ((\"Ingo Kloecker\" NIL \"kloecker\" \"kde.org\")) NIL NIL NIL \"<{7b55527e-77f4-489d-bf18-e805be96718c}@server.kde.org>\" NIL)" ); - QByteArray env; - QBuffer buffer; - buffer.setBuffer( &env ); - buffer.open( QIODevice::ReadWrite ); - int version = 0; - QBENCHMARK { - buffer.seek( 0 ); - serializer->serialize( i, MessagePart::Envelope, buffer, version ); - } - QCOMPARE( env, expEnv ); - - // envelop with references header - msg->references()->from7BitString( "<{8888827e-77f4-489d-bf18-e805be96718c}@server.kde.org>" ); - expEnv = QByteArray( "(\"Wed, 01 Feb 2006 13:37:19 +0000\" \"IMPORTANT: Akonadi Test\" ((\"Tobias Koenig\" NIL \"tokoe\" \"kde.org\")) ((\"Tobias Koenig\" NIL \"tokoe\" \"kde.org\")) NIL ((\"Ingo Kloecker\" NIL \"kloecker\" \"kde.org\")) NIL NIL NIL \"<{7b55527e-77f4-489d-bf18-e805be96718c}@server.kde.org>\" \"<{8888827e-77f4-489d-bf18-e805be96718c}@server.kde.org>\")" ); - - buffer.close(); - buffer.open( QIODevice::ReadWrite ); - buffer.seek( 0 ); - serializer->serialize( i, MessagePart::Envelope, buffer, version ); - QCOMPARE( env, expEnv ); - - // envelop with references header with multiple entries - msg->references()->from7BitString( "<{8888827e-77f4-489d-bf18-e805be96718c}@server.kde.org> <{9999927e-77f4-489d-bf18-e805be96718c}@server.kde.org>" ); - expEnv = QByteArray( "(\"Wed, 01 Feb 2006 13:37:19 +0000\" \"IMPORTANT: Akonadi Test\" ((\"Tobias Koenig\" NIL \"tokoe\" \"kde.org\")) ((\"Tobias Koenig\" NIL \"tokoe\" \"kde.org\")) NIL ((\"Ingo Kloecker\" NIL \"kloecker\" \"kde.org\")) NIL NIL NIL \"<{7b55527e-77f4-489d-bf18-e805be96718c}@server.kde.org>\" \"<{8888827e-77f4-489d-bf18-e805be96718c}@server.kde.org> <{9999927e-77f4-489d-bf18-e805be96718c}@server.kde.org>\")" ); - - buffer.close(); - buffer.open( QIODevice::ReadWrite ); - buffer.seek( 0 ); - serializer->serialize( i, MessagePart::Envelope, buffer, version ); - QCOMPARE( env, expEnv ); - - delete serializer; -} - -void MailSerializerTest::testParts() -{ - Item item; - item.setMimeType( QLatin1String("message/rfc822") ); - KMime::Message *m = new Message; - KMime::Message::Ptr msg( m ); - item.setPayload( msg ); - - SerializerPluginMail *serializer = new SerializerPluginMail(); - QVERIFY( serializer->parts( item ).isEmpty() ); - - msg->setHead( "foo" ); - QSet parts = serializer->parts( item ); - QCOMPARE( parts.count(), 2 ); - QVERIFY( parts.contains( MessagePart::Envelope ) ); - QVERIFY( parts.contains( MessagePart::Header ) ); - - msg->setBody( "bar" ); - parts = serializer->parts( item ); - QCOMPARE( parts.count(), 3 ); - QVERIFY( parts.contains( MessagePart::Envelope ) ); - QVERIFY( parts.contains( MessagePart::Header ) ); - QVERIFY( parts.contains( MessagePart::Body ) ); - - delete serializer; -} - -void MailSerializerTest::testHeaderFetch() -{ - Item i; - i.setMimeType( QLatin1String("message/rfc822") ); - - SerializerPluginMail *serializer = new SerializerPluginMail(); - - - QByteArray headerData( "From: David Johnson \n" - "To: kde-commits@kde.org\n" - "MIME-Version: 1.0\n" - "Date: Sun, 01 Feb 2009 06:25:22 +0000\n" - "Message-Id: <1233469522.741324.18468.nullmailer@svn.kde.org>\n" - "Subject: [kde-doc-english] KDE/kdeutils/kcalc\n" ); - - QString expectedSubject = QString::fromUtf8( "[kde-doc-english] KDE/kdeutils/kcalc" ); - QString expectedFrom = QString::fromUtf8( "David Johnson " ); - QString expectedTo = QString::fromUtf8( "kde-commits@kde.org" ); - - // envelope - QBuffer buffer; - buffer.setData( headerData ); - buffer.open( QIODevice::ReadOnly ); - buffer.seek( 0 ); - serializer->deserialize( i, MessagePart::Header, buffer, 0 ); - QVERIFY( i.hasPayload() ); - - KMime::Message::Ptr msg = i.payload(); - QCOMPARE( msg->subject()->asUnicodeString(), expectedSubject ); - QCOMPARE( msg->from()->asUnicodeString(), expectedFrom ); - QCOMPARE( msg->to()->asUnicodeString(), expectedTo ); - - delete serializer; -} - -void MailSerializerTest::testMultiDeserialize() -{ - // The Body part includes the Header. - // When serialization is done a second time, we should already have the header deserialized. - // We change the header data for the second deserialization (which is an unrealistic scenario) - // to demonstrate that it is not deserialized again. - - Item i; - i.setMimeType( QLatin1String("message/rfc822") ); - - SerializerPluginMail *serializer = new SerializerPluginMail(); - - - QByteArray messageData( "From: David Johnson \n" - "To: kde-commits@kde.org\n" - "MIME-Version: 1.0\n" - "Date: Sun, 01 Feb 2009 06:25:22 +0000\n" - "Subject: [kde-doc-english] KDE/kdeutils/kcalc\n" - "Content-Type: text/plain\n" - "\n" - "This is content" ); - - QString expectedSubject = QString::fromUtf8( "[kde-doc-english] KDE/kdeutils/kcalc" ); - QString expectedFrom = QString::fromUtf8( "David Johnson " ); - QString expectedTo = QString::fromUtf8( "kde-commits@kde.org" ); - QByteArray expectedBody( "This is content" ); - - // envelope - QBuffer buffer; - buffer.setData( messageData ); - buffer.open( QIODevice::ReadOnly ); - buffer.seek( 0 ); - serializer->deserialize( i, MessagePart::Body, buffer, 0 ); - QVERIFY( i.hasPayload() ); - - KMime::Message::Ptr msg = i.payload(); - QCOMPARE( msg->subject()->asUnicodeString(), expectedSubject ); - QCOMPARE( msg->from()->asUnicodeString(), expectedFrom ); - QCOMPARE( msg->to()->asUnicodeString(), expectedTo ); - QCOMPARE( msg->body(), expectedBody ); - - buffer.close(); - - messageData = QByteArray ( "From: DIFFERENT CONTACT \n" - "To: kde-commits@kde.org\n" - "MIME-Version: 1.0\n" - "Date: Sun, 01 Feb 2009 06:25:22 +0000\n" - "Message-Id: <1233469522.741324.18468.nullmailer@svn.kde.org>\n" - "Subject: [kde-doc-english] KDE/kdeutils/kcalc\n" - "Content-Type: text/plain\n" - "\r\n" - "This is content" ); - - buffer.setData( messageData ); - buffer.open( QIODevice::ReadOnly ); - buffer.seek( 0 ); - - serializer->deserialize( i, MessagePart::Header, buffer, 0 ); - QVERIFY( i.hasPayload() ); - - msg = i.payload(); - QCOMPARE( msg->subject()->asUnicodeString(), expectedSubject ); - QCOMPARE( msg->from()->asUnicodeString(), expectedFrom ); - QCOMPARE( msg->to()->asUnicodeString(), expectedTo ); - - delete serializer; -} - - diff -Nru kdepim-runtime-4.14.6/plugins/tests/mailserializertest.h kdepim-runtime-15.08.0/plugins/tests/mailserializertest.h --- kdepim-runtime-4.14.6/plugins/tests/mailserializertest.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/plugins/tests/mailserializertest.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -/* - Copyright (c) 2007 Volker Krause - - 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 MAILSERIALIZERTEST_H -#define MAILSERIALIZERTEST_H - -#include - -class MailSerializerTest : public QObject -{ - Q_OBJECT - private slots: - void testEnvelopeDeserialize(); - void testEnvelopeDeserializeWithReferencesHeader(); - void testEnvelopeSerialize(); - void testParts(); - void testHeaderFetch(); - void testMultiDeserialize(); -}; - - -#endif diff -Nru kdepim-runtime-4.14.6/qml/akonadi/AkonadiBreadcrumbNavigationView.qml kdepim-runtime-15.08.0/qml/akonadi/AkonadiBreadcrumbNavigationView.qml --- kdepim-runtime-4.14.6/qml/akonadi/AkonadiBreadcrumbNavigationView.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/akonadi/AkonadiBreadcrumbNavigationView.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,146 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 -import org.kde 4.5 -import org.kde.akonadi 4.5 - -Item { - id : _top - property alias breadcrumbComponentFactory : breadcrumbView.breadcrumbComponentFactory - - property int indentation : 35 - - property alias topDelegate : breadcrumbView.topDelegate - property alias breadcrumbDelegate : breadcrumbView.breadcrumbDelegate - property alias selectedItemDelegate : breadcrumbView.selectedItemDelegate - property alias childItemsDelegate : breadcrumbView.childItemsDelegate - property alias multipleSelectionText : breadcrumbView.multipleSelectionText - - property alias itemHeight : breadcrumbView.itemHeight - property alias _transitionSelect : breadcrumbView._transitionSelect - - property alias hasChildren : breadcrumbView.hasChildren - property alias hasSelection : breadcrumbView.hasSelection - property alias hasBreadcrumbs : breadcrumbView.hasBreadcrumbs - - property alias numBreadcrumbs : breadcrumbView.numBreadcrumbs - property alias numSelected : breadcrumbView.numSelected - - property alias breadcrumbSelectionModel : breadcrumbView.breadcrumbSelectionModel - property alias selectedItemSelectionModel : breadcrumbView.selectedItemSelectionModel - property alias childSelectionModel : breadcrumbView.childSelectionModel - - - property alias showCheckboxes : breadcrumbView.showCheckboxes - property alias checkable : breadcrumbView.checkable - property alias showUnread : breadcrumbView.showUnread - - property bool clickToBulkAction : true - - signal selectedClicked() - signal homeClicked() - - Item { - id :dragOverlay - anchors.fill : parent - } - - Connections { - target: breadcrumbView - onHomeClicked: homeClicked() - } - - BreadcrumbNavigationView { - id : breadcrumbView - anchors.fill : parent - - property bool showCheckboxes : false - property bool checkable : false - property bool showUnread : false - - topDelegate : Item { - clip: true - - MouseArea { - anchors.fill: parent - onClicked: { - breadcrumbView._transitionSelect = -1; - breadcrumbView.state = "before_select_home"; - } - } - Text { - id : textElement - x : 90 - width: parent.width - 48 - 50 - text : KDE.i18nc( "Go to the Home screen of the application", "Home") - color: "black" - } - } - - breadcrumbDelegate : CollectionDelegate { - indentation : _top.indentation - fullClickArea : true - dragParent : dragOverlay - height : itemHeight - checkModel : breadcrumbComponentFactory.qmlBreadcrumbCheckModel() - showUnread : breadcrumbView.showUnread - showCheckbox : breadcrumbView.showCheckboxes - checkable : breadcrumbView.checkable - onIndexSelected : { - breadcrumbTopLevel._transitionSelect = row; - breadcrumbTopLevel.state = "before_select_breadcrumb"; - } - } - - selectedItemDelegate : CollectionDelegate { - indentation : _top.indentation - height : itemHeight - dragParent : dragOverlay - selectedDelegate : true - checkModel : breadcrumbComponentFactory.qmlSelectedItemCheckModel() - showUnread : breadcrumbView.showUnread - showCheckbox : breadcrumbView.showCheckboxes - checkable : breadcrumbView.checkable - - MouseArea { - anchors.fill : _top.clickToBulkAction ? parent : undefined - onClicked : selectedClicked(); - } - } - - childItemsDelegate : CollectionDelegate { - indentation : _top.indentation - height : itemHeight - dragParent : dragOverlay - fullClickArea : true - showChildIndicator : true - checkModel : breadcrumbComponentFactory.qmlChildCheckModel() - showUnread : breadcrumbView.showUnread - showCheckbox : breadcrumbView.showCheckboxes - checkable : breadcrumbView.checkable - onIndexSelected : { - breadcrumbTopLevel._transitionSelect = row; - breadcrumbTopLevel.state = "before_select_child"; - } - } - } -} Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/akonadi/border_dot.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/akonadi/border_dot.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/akonadi/check.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/akonadi/check.png differ diff -Nru kdepim-runtime-4.14.6/qml/akonadi/CMakeLists.txt kdepim-runtime-15.08.0/qml/akonadi/CMakeLists.txt --- kdepim-runtime-4.14.6/qml/akonadi/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/akonadi/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -if (QT_QTDECLARATIVE_FOUND) -install(FILES - qmldir - collectionview.qml - AkonadiBreadcrumbNavigationView.qml - CollectionDelegate.qml - border_dot.png - check.png - sliderbackground.png - transparentplus.png - DESTINATION ${PLUGIN_INSTALL_DIR}/imports/org/kde/akonadi -) - -add_subdirectory( tests ) - -endif () diff -Nru kdepim-runtime-4.14.6/qml/akonadi/CollectionDelegate.qml kdepim-runtime-15.08.0/qml/akonadi/CollectionDelegate.qml --- kdepim-runtime-4.14.6/qml/akonadi/CollectionDelegate.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/akonadi/CollectionDelegate.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,217 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 -import org.kde 4.5 -import org.kde.akonadi 4.5 - -Item { - id: wrapper - clip: true - - property bool fullClickArea : false - property bool showChildIndicator : false - property bool selectedDelegate : false - property bool topItem : false - property bool showUnread : false - property bool showCheckbox : false - property bool checkable : false - property bool uncheckable : false - property bool alternatingRowColors : false - property int indentation : 0 - property real dragCheckThreshold : 0.5 - - property alias dragParent : dragTarget.parent - - property variant checkModel - - signal indexSelected(int row) - - x : indentation - width : ListView.view.width - indentation - - Rectangle { - // This is the same as anchors.fill : parent, but ParentAnimation only works - // if positional layouting is used instead of anchor layouting. - x : 0 - y : 0 - width : wrapper.width - height : wrapper.height - id : nestedItem - color : ( alternatingRowColors && model.index % 2 == 0 ) ? "#33ffffff" : "#00000000" - - Behavior on x { - id : dragFinishedBehavior - SequentialAnimation { - NumberAnimation { - easing.type: "OutQuad" - easing.amplitude: 100 - duration: 800 - } - ScriptAction { - script : { - nestedItem.parent = wrapper - nestedItem.y = 0 - dragFinishedBehavior.enabled = false - nestedItem.x = 0 - dragFinishedBehavior.enabled = true - } - } - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - if ( fullClickArea ) - { - if (topItem) - { - indexSelected(model.index); - return; - } - - if (showChildIndicator) - { - nestedItem.state = "before_select_child"; - } else if (!selectedDelegate) - nestedItem.state = "before_select_breadcrumb"; - indexSelected(model.index); - } - } - drag.target : (checkable || uncheckable) ? nestedItem : undefined - drag.axis : Drag.XAxis - drag.minimumX : uncheckable ? -nestedItem.width : wrapper.indentation - drag.maximumX : checkable ? nestedItem.width : wrapper.indentation - drag.onActiveChanged : { - if (!drag.active) { - if ((checkable && nestedItem.x > nestedItem.width * dragCheckThreshold) - || (uncheckable && nestedItem.x < nestedItem.width * dragCheckThreshold)) - { - // 8 is QItemSelectionModel::Toggle - checkModel.select(model.index, 8); - } - nestedItem.x = wrapper.indentation - } else { - var point = mapToItem(dragParent, nestedItem.x, nestedItem.y) - nestedItem.y = point.y - dragFinishedBehavior.enabled = false; - nestedItem.x = point.x + wrapper.indentation - dragFinishedBehavior.enabled = true; - nestedItem.parent = dragParent - // Using the state directly does not seem to work. -// nestedItem.state = "dragging" - } - } - } - Row { - id: topLayout - x: 10; y: 10; - height: 48 - width: parent.width - spacing: 10 - - Image { - id : checkbox - y : -10 - source : "check.png" - visible : wrapper.showCheckbox && model.checkOn; - } - - //Image { - // id: collectionIcon - // http://lists.trolltech.com/pipermail/qt-qml/2010-July/000668.html - // pixmap: KDE.iconToPixmap( model.decoration, height ); - // width: 48; height: 48 -// } - - Column { - height : parent.height - Text { - width: wrapper.width - 48 - 50 - text : model.display - color: (model.foreground != undefined ? model.foreground : "black") - //### requires a newer QML version - //wrapMode: "WrapAnywhere" // Needs the anchors.fill to work properly - } - - Text { - text : wrapper.showUnread && model.unreadCount > 0 ? KDE.i18n( "Unread: %1", model.unreadCount ) : "" - color: "#0C55BB" - font.pixelSize: 16 - } - Rectangle { - id: progressBar - color: "black" - width: parent.width - height: 7 - visible: (model.collectionSyncProgress != undefined && model.collectionSyncProgress != 0 && model.collectionSyncProgress != 100) - Rectangle { - color: "lightsteelblue" - x: 1 - y: 1 - height: 5 - width: ((parent.width * (model.collectionSyncProgress == 100 ? 0 : model.collectionSyncProgress)) / 100) - } - } - } - } - - Image { - width : height - anchors.right : nestedItem.right - anchors.rightMargin : 5 - anchors.verticalCenter : nestedItem.verticalCenter - opacity : ( showChildIndicator && breadcrumbComponentFactory.childCollectionHasChildren( model.index ) ) ? 1 : 0 - source: "transparentplus.png" - } - - states : [ - State { - name : "dragging" - ParentChange { id : dragTarget; target : nestedItem } - }, - State { - name : "before_select_child" - ParentChange { target : nestedItem; parent : selectedItemPlaceHolder; } - PropertyChanges { target : nestedItem; x : indentation; y : 0 } - }, - State { - name : "before_select_breadcrumb" - ParentChange { target : nestedItem; parent : selectedItemPlaceHolder; } - PropertyChanges { target : nestedItem; x : indentation; y : 0 } - } - ] - transitions : [ - Transition { - ParentAnimation { - target : nestedItem - NumberAnimation { - properties: "x,y"; - duration : 500 - easing.type: Easing.OutQuad; - } - } - } - ] - } -} - diff -Nru kdepim-runtime-4.14.6/qml/akonadi/collectionview.qml kdepim-runtime-15.08.0/qml/akonadi/collectionview.qml --- kdepim-runtime-4.14.6/qml/akonadi/collectionview.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/akonadi/collectionview.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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. -*/ - -import Qt 4.7 -import org.kde 4.5 - -/** Akonadi Collection List View - @param model: The collection model to display, ETM-based, filtered to only contain a flat collection list. - @param currentIndex: Index of the currently selected row. - */ -Item { - id: collectionListViewTopLevel - property alias model: collectionListView.model - property alias currentIndex: collectionListView.currentIndex - signal collectionSelected - - SystemPalette { id: palette; colorGroup: "Active" } - Component { - id: collectionViewDelegate - - Item { - id: wrapper - width: collectionListView.width - height : 68 - - Rectangle { - id: background - opacity: 0.25 - x: 1; y: 2; width: parent.width - 2; height: parent.height - 4 - border.color: palette.mid - radius: 5 - } - MouseArea { - anchors.fill: parent - onClicked: { - wrapper.ListView.view.currentIndex = model.index; - collectionListViewTopLevel.collectionSelected() - } - } - - Row { - id: topLayout - x: 10; y: 10; - height: collectionIcon.height; - width: parent.width - spacing: 10 - - Image { - id: collectionIcon - pixmap: KDE.iconToPixmap( model.decoration, height ); - width: 48; height: 48 - } - - Column { - height: collectionIcon.height - width: background.width - collectionIcon.width - 20 - spacing: 5 - Text { - text : model.display - } - } - } - } - } - - Component { - id: highlight - Rectangle { - color: palette.highlight - radius: 5 - } - } - - ListView - { - id: collectionListView - anchors.fill: parent - delegate : collectionViewDelegate - highlight: highlight - highlightFollowsCurrentItem: true - focus: true - clip: true - } -} diff -Nru kdepim-runtime-4.14.6/qml/akonadi/qmldir kdepim-runtime-15.08.0/qml/akonadi/qmldir --- kdepim-runtime-4.14.6/qml/akonadi/qmldir 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/akonadi/qmldir 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -CollectionView 4.5 collectionview.qml -CollectionDelegate 4.5 CollectionDelegate.qml -AkonadiBreadcrumbNavigationView 4.5 AkonadiBreadcrumbNavigationView.qml Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/akonadi/sliderbackground.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/akonadi/sliderbackground.png differ diff -Nru kdepim-runtime-4.14.6/qml/akonadi/tests/CMakeLists.txt kdepim-runtime-15.08.0/qml/akonadi/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/qml/akonadi/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/akonadi/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -set(akonadi_qml_test_srcs - qmltest.cpp -) - -kde4_add_executable(akonadi_qml_test ${akonadi_qml_test_srcs} ) - -target_link_libraries(akonadi_qml_test - ${QT_QTDECLARATIVE_LIBRARY} - ${KDEPIMLIBS_AKONADI_LIBS} -) - diff -Nru kdepim-runtime-4.14.6/qml/akonadi/tests/collectionviewtest.qml kdepim-runtime-15.08.0/qml/akonadi/tests/collectionviewtest.qml --- kdepim-runtime-4.14.6/qml/akonadi/tests/collectionviewtest.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/akonadi/tests/collectionviewtest.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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. -*/ - -import Qt 4.7 -import org.kde 4.5 -import org.kde.akonadi 4.5 - -Rectangle { - color: white - height: 480 - width: 800 - - CollectionView { - id: listView - anchors.fill: parent - model: collectionModel - } - Binding { - target: application - property: "collectionRow" - value: listView.currentIndex - } -} diff -Nru kdepim-runtime-4.14.6/qml/akonadi/tests/qmltest.cpp kdepim-runtime-15.08.0/qml/akonadi/tests/qmltest.cpp --- kdepim-runtime-4.14.6/qml/akonadi/tests/qmltest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/akonadi/tests/qmltest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ -/* -* This file is part of Akonadi -* -* Copyright 2010 Stephen Kelly -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; either -* version 2.1 of the License, or (at your option) any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -* 02110-1301 USA -*/ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -// #include - -#include -#include -#include -#include -#include -#include -#include -#include - - -class QmlTestWidget : public QWidget -{ - Q_OBJECT - Q_PROPERTY( int collectionRow READ selectedCollectionRow WRITE collectionRowSelected ) - -public: - QmlTestWidget( QWidget *parent = 0 ); - - public: - int selectedCollectionRow() const { return 0; } - void collectionRowSelected( int row ); - -}; - - - -QmlTestWidget::QmlTestWidget(QWidget* parent) - : QWidget(parent) -{ - - QHBoxLayout *mainLayout = new QHBoxLayout( this ); - - Akonadi::ChangeRecorder *changeRecorder = new Akonadi::ChangeRecorder(); - changeRecorder->setCollectionMonitored( Akonadi::Collection::root() ); - - Akonadi::EntityTreeModel *etm = new Akonadi::EntityTreeModel( changeRecorder ); - - Akonadi::EntityMimeTypeFilterModel *collectionFilter = new Akonadi::EntityMimeTypeFilterModel(); - collectionFilter->setHeaderGroup( Akonadi::EntityTreeModel::CollectionTreeHeaders ); - collectionFilter->setSourceModel( etm ); - collectionFilter->addMimeTypeInclusionFilter( Akonadi::Collection::mimeType() ); - -#if 0 - KDescendantsProxyModel *flatProxy = new KDescendantsProxyModel( this ); - flatProxy->setSourceModel( collectionFilter ); - flatProxy->setAncestorSeparator( QLatin1String(" / ") ); - flatProxy->setDisplayAncestorData( true ); -#endif - - QDeclarativeView *view = new QDeclarativeView( this ); - mainLayout->addWidget( view ); - - view->engine()->rootContext()->setContextProperty( QLatin1String("collectionModel"), QVariant::fromValue( static_cast( collectionFilter ) ) ); - view->engine()->rootContext()->setContextProperty( QLatin1String("application"), QVariant::fromValue( static_cast( this ) ) ); - view->setSource( QUrl( QLatin1String("collectionviewtest.qml") ) ); // TODO make this a command line argument so this test can be used for other qml components as well -} - -void QmlTestWidget::collectionRowSelected(int row) -{ - kDebug() << row; -} - -int main( int argc, char **argv ) -{ - const QByteArray& ba = QByteArray( "akonadi_qml" ); - const KLocalizedString name = ki18n( "Akonadi QML Test" ); - KAboutData aboutData( ba, ba, name, ba, name ); - KCmdLineArgs::init( argc, argv, &aboutData ); - KApplication app; - - QmlTestWidget testWidget; - testWidget.show(); - - return app.exec(); -} - -#include "qmltest.moc" Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/akonadi/transparentplus.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/akonadi/transparentplus.png differ diff -Nru kdepim-runtime-4.14.6/qml/CMakeLists.txt kdepim-runtime-15.08.0/qml/CMakeLists.txt --- kdepim-runtime-4.14.6/qml/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -add_definitions( -DQT_NO_CAST_FROM_ASCII ) -add_definitions( -DQT_NO_CAST_TO_ASCII ) - -add_subdirectory( kde ) -add_subdirectory( akonadi ) diff -Nru kdepim-runtime-4.14.6/qml/kde/BreadcrumbNavigationView.qml kdepim-runtime-15.08.0/qml/kde/BreadcrumbNavigationView.qml --- kdepim-runtime-4.14.6/qml/kde/BreadcrumbNavigationView.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/BreadcrumbNavigationView.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,548 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Item { - id: breadcrumbTopLevel - clip : true - - property variant breadcrumbComponentFactory - - property alias topDelegate : topButton.sourceComponent - property alias breadcrumbDelegate : breadcrumbsView.delegate - property alias selectedItemDelegate : selectedItemView.delegate - property alias childItemsDelegate : childItemsView.delegate - property alias multipleSelectionText : multipleSelectionMessage.text - - property int itemHeight : height / 7 - property int _transitionSelect : -1 - - property bool hasChildren : childItemsView.count > 0 - property bool hasSelection : selectedItemView.count > 0 - property bool hasBreadcrumbs : breadcrumbsView.count > 0 - - property alias numBreadcrumbs : breadcrumbsView.count - property alias numSelected : selectedItemView.count - - property variant breadcrumbSelectionModel : breadcrumbComponentFactory.qmlBreadcrumbSelectionModel(); - property variant selectedItemSelectionModel : breadcrumbComponentFactory.qmlSelectionModel(); - property variant childSelectionModel : breadcrumbComponentFactory.qmlChildSelectionModel(); - - signal childCollectionSelected(int row) - signal breadcrumbCollectionSelected(int row) - signal homeClicked() - - SystemPalette { id: palette; colorGroup: "Active" } - - Loader { - id : topButton - height : itemHeight - - anchors.top : parent.top - - anchors.left : parent.left - anchors.right : parent.right - - Image { - id : topRightDivider - source : "dividing-line.png" - anchors.top : parent.top - anchors.right : parent.right - anchors.bottom : parent.bottom - anchors.bottomMargin : breadcrumbTopLevel.hasBreadcrumbs ? 0 : 8 - fillMode : Image.TileVertically - opacity : breadcrumbTopLevel.hasSelection ? 1 : 0 - } - } - - ListView { - id : breadcrumbsView - model : breadcrumbComponentFactory.qmlBreadcrumbsModel(); - interactive : false - height : breadcrumbsView.count > 0 ? itemHeight : 0 - - property int selectedIndex : -1 - anchors.top : topButton.bottom - anchors.left : parent.left - anchors.right : parent.right - highlightFollowsCurrentItem : true - highlightRangeMode : ListView.StrictlyEnforceRange - preferredHighlightBegin : 0 - preferredHighlightEnd : height - onCountChanged : { - positionViewAtIndex(count - 1, ListView.Beginning) - } - Component.onCompleted : { - positionViewAtIndex(count - 1, ListView.Beginning) - } - } - - Item { - id : breadcrumbPlaceHolder - height : breadcrumbTopLevel.hasBreadcrumbs ? itemHeight : 0 - anchors.top : topButton.bottom - anchors.left : parent.left - anchors.right : parent.right - } - Image { - id : breadcrumbRightDivider - source : "dividing-line.png" - anchors.top : breadcrumbPlaceHolder.top - anchors.right : breadcrumbPlaceHolder.right - height : breadcrumbTopLevel.hasBreadcrumbs ? (itemHeight -8) : 0 - fillMode : Image.TileVertically - opacity : breadcrumbTopLevel.hasBreadcrumbs ? 1 : 0 - } - - ListView { - id : selectedItemView - interactive : false - - model : breadcrumbComponentFactory.qmlSelectedItemModel(); - height : itemHeight * selectedItemView.count - anchors.top : breadcrumbsView.bottom - anchors.left : parent.left - anchors.right : parent.right - - onCountChanged : { - if (selectedItemView.count > 1) - { - breadcrumbsView.visible = false; - breadcrumbPlaceHolder.visible = false; - selectedItemView.visible = false; - selectedItemPlaceHolder.visible = false; - childItemsView.visible = false; - favinfoOverlay.visible = true; - } - else - { - breadcrumbsView.visible = true; - breadcrumbPlaceHolder.visible = true; - selectedItemView.visible = true; - selectedItemPlaceHolder.visible = true; - childItemsView.visible = true; - favinfoOverlay.visible = false; - } - } - } - - Item { - id : selectedItemPlaceHolder - height : selectedItemView.count > 0 ? itemHeight : 0 - anchors.top : breadcrumbPlaceHolder.bottom - anchors.left : parent.left - anchors.right : parent.right - Item { - id : selectedPlaceHolderImages - anchors.fill : parent - opacity : (selectedItemView.count > 0) ? 1 : 0 - Image { - source : "dividing-line-horizontal.png" - fillMode : Image.TileHorizontally - anchors.top : parent.top - anchors.topMargin : -3 - anchors.right : topLine.left - anchors.left : parent.left - } - Image { - id : topLine - source : "list-line-top.png" - anchors.right : parent.right - anchors.top : parent.top - anchors.topMargin : -8 - } - } - } - - ListView { - id : childItemsView - clip : true - model : breadcrumbComponentFactory.qmlChildItemsModel(); - property bool shouldBeFlickable - - anchors.top : selectedItemPlaceHolder.bottom - anchors.bottom : breadcrumbTopLevel.bottom - anchors.left : parent.left - anchors.right : parent.right - - shouldBeFlickable : childItemsView.height < (itemHeight * childItemsView.count) - interactive : shouldBeFlickable - } - - Item { - id : childItemsViewPlaceHolder - anchors.top : selectedItemPlaceHolder.bottom - anchors.bottom : breadcrumbTopLevel.bottom - anchors.left : parent.left - anchors.right : parent.right - - - Image { - source : "dividing-line-horizontal.png" - fillMode : Image.TileHorizontally - anchors.right : parent.right - anchors.left : parent.left - anchors.top : parent.top - visible : selectedItemView.count > 1 ? false : true - } - - Image { - source : "dividing-line.png" - anchors.top : parent.top - anchors.right : parent.right - anchors.bottom : parent.bottom - fillMode : Image.TileVertically - } - Image { - source : "scrollable-top.png" - anchors.top : parent.top - anchors.right : parent.right - anchors.left : parent.left - fillMode : Image.TileHorizontally - opacity : childItemsView.shouldBeFlickable ? 1 : 0 - visible : selectedItemView.count > 1 ? false : true - } - Image { - source : "scrollable-bottom.png" - anchors.bottom : parent.bottom - anchors.right : parent.right - anchors.left : parent.left - fillMode : Image.TileHorizontally - opacity : childItemsView.shouldBeFlickable ? 1 : 0 - visible : selectedItemView.count > 1 ? false : true - } - } - - Item { - id : favinfoOverlay - anchors.top : topButton.bottom - anchors.bottom : parent.bottom - anchors.left : parent.left - anchors.right : parent.right - visible : false - - Text { - id : multipleSelectionMessage - font.italic : true - horizontalAlignment : Text.AlignHCenter - anchors.horizontalCenter : parent.horizontalCenter - - height : 30 - x : 20 - y : 50 - } - - Image { - source : "dividing-line-horizontal.png" - fillMode : Image.TileHorizontally - anchors.top : parent.top - anchors.right : parent.right - anchors.left : parent.left - } - - Image { - source : "dividing-line.png" - fillMode : Image.TileVertically - anchors.top : parent.top - anchors.right : parent.right - anchors.bottom : parent.bottom - } - - } - - function completeHomeSelection() { - selectedItemSelectionModel.clearSelection(); - homeClicked() - // TODO: Remove: - breadcrumbCollectionSelected(breadcrumbTopLevel._transitionSelect); - breadcrumbTopLevel._transitionSelect = -1; - breadcrumbTopLevel.state = "after_select_breadcrumb"; - breadcrumbTopLevel.state = ""; - } - - function completeChildSelection() { - childSelectionModel.select(breadcrumbTopLevel._transitionSelect, 3) - // TODO: Remove: - childCollectionSelected(breadcrumbTopLevel._transitionSelect); - breadcrumbTopLevel._transitionSelect = -1; - breadcrumbTopLevel.state = "after_select_child"; - breadcrumbTopLevel.state = ""; - } - - function completeBreadcrumbSelection() { - breadcrumbSelectionModel.select(breadcrumbTopLevel._transitionSelect, 3) - // TODO: Remove: - breadcrumbCollectionSelected(breadcrumbTopLevel._transitionSelect); - breadcrumbTopLevel._transitionSelect = -1; - breadcrumbTopLevel.state = "after_select_breadcrumb"; - breadcrumbTopLevel.state = ""; - } - - states : [ - State { - name : "before_select_home" - PropertyChanges { - target : breadcrumbsView - opacity : 0 - height : 0 - } - PropertyChanges { - target : breadcrumbPlaceHolder - opacity : 0 - height : 0 - } - PropertyChanges { - target : selectedItemView - opacity : 0 - height : 0 - } - PropertyChanges { - target : selectedItemPlaceHolder - opacity : 0 - height : 0 - } - PropertyChanges { - target : childItemsView - opacity : 0 - } - }, - State { - name : "before_select_child" - PropertyChanges { - target : topRightDivider - anchors.bottomMargin : 0 - opacity : 1 - } - PropertyChanges { - target : breadcrumbsView - height : itemHeight - anchors.topMargin : -itemHeight - opacity : 0 - } - PropertyChanges { - target : breadcrumbRightDivider - anchors.topMargin : -8 - height : 67 - opacity : 0 // { 1 } // selectedItemView.count > 0 ? 1 : 0 - } - PropertyChanges { - target : selectedItemPlaceHolder - anchors.topMargin : (breadcrumbsView.count == 0 && selectedItemView.count > 0) ? (itemHeight) : (breadcrumbsView.count == 0) ? 8 : 0 - height : itemHeight - opacity : 1 - } - - PropertyChanges { - target : selectedPlaceHolderImages - opacity : 1 - } - PropertyChanges { - target : childItemsView - opacity : 0 - } - }, - State { - name : "after_select_child" - PropertyChanges { - target : childItemsView - opacity : 0 - } - }, - State { - name : "before_select_breadcrumb" - PropertyChanges { - target : breadcrumbsView - height : { if (breadcrumbTopLevel._transitionSelect >= 0) itemHeight * ( breadcrumbTopLevel._transitionSelect + 1 ) } - anchors.bottomMargin : -itemHeight - opacity : 0.5 - } - PropertyChanges { - target : selectedItemView - anchors.topMargin : (application.selectedCollectionRow() + breadcrumbsView.count) * itemHeight; - opacity : 0 - } - PropertyChanges { - target : childItemsView - opacity : 0 - } - }, - State { - name : "after_select_breadcrumb" - PropertyChanges { - target : breadcrumbsView - contentY : breadcrumbsView.count > 1 ? itemHeight : 0 - } - PropertyChanges { - target : childItemsView - opacity : 0 - } - } - ] - - transitions : [ - Transition { - from : "*" - to : "before_select_home" - SequentialAnimation { - ParallelAnimation { - PropertyAnimation { - target : breadcrumbPlaceHolder - duration: 500 - easing.type: "OutQuad" - properties : "opacity,height" - } - PropertyAnimation { - target : breadcrumbsView - duration: 500 - easing.type: "OutQuad" - properties : "opacity,height" - } - PropertyAnimation { - target : selectedItemView - duration: 500 - easing.type: "OutQuad" - properties : "opacity,height" - } - PropertyAnimation { - target : selectedItemPlaceHolder - duration: 500 - easing.type: "OutQuad" - properties : "opacity,height" - } - PropertyAnimation { - target : childItemsView - duration: 500 - easing.type: "OutQuad" - properties : "height" - } - } - ScriptAction { - script: { completeHomeSelection(); } - } - } - }, - Transition { - from : "*" - to : "before_select_child" - SequentialAnimation { - ParallelAnimation { - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: topRightDivider - properties: "opacity,anchors.bottomMargin" - } - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: breadcrumbsView - properties: "height,anchors.topMargin,opacity" - } - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: breadcrumbRightDivider - properties: "height" - } - PropertyAnimation { - target : selectedItemPlaceHolder - duration: 500 - easing.type: "OutQuad" - properties : "anchors.topMargin,height,opacity" - } - PropertyAnimation { - target : selectedPlaceHolderImages - duration: 500 - easing.type: "OutQuad" - properties : "opacity" - } - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: childItemsView - properties: "opacity" - } - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: childItemsDelegate - properties: "itemBackground" - } - } - ScriptAction { - script: { completeChildSelection(); } - } - } - }, - Transition { - from : "after_select_child" - to : "" - NumberAnimation { - target: childItemsView - properties: "opacity" - } - NumberAnimation { - target: selectedItemView - properties: "opacity" - } - }, - Transition { - from : "*" - to : "before_select_breadcrumb" - SequentialAnimation { - ParallelAnimation { - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: breadcrumbsView - properties: "height,opacity" - } - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: selectedItemView - properties: "opacity,anchors.topMargin" - } - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: childItemsView - properties: "opacity" - } - } - ScriptAction { - script: { completeBreadcrumbSelection(); } - } - } - }, - Transition { - from : "after_select_breadcrumb" - to : "" - NumberAnimation { - duration: 500 - easing.type: "OutQuad" - target: childItemsView - properties: "opacity" - } - } - ] -} diff -Nru kdepim-runtime-4.14.6/qml/kde/CMakeLists.txt kdepim-runtime-15.08.0/qml/kde/CMakeLists.txt --- kdepim-runtime-4.14.6/qml/kde/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -if (QT_QTDECLARATIVE_FOUND) - -if (KDEQMLPLUGIN_STATIC) - set(LIBRARY_TYPE "STATIC") -else() - set(LIBRARY_TYPE) -endif () - -kde4_add_plugin( kdeqmlplugin ${LIBRARY_TYPE} WITH_PREFIX - kdeintegration.cpp - kdeintegrationplugin.cpp -) -target_link_libraries(kdeqmlplugin ${KDE4_KDEUI_LIBS} ${QT_QTDECLARATIVE_LIBRARY} ${QT_QTSCRIPT_LIBRARY}) - -if (KDEQMLPLUGIN_STATIC) - install( FILES qmldir_without_kdeqmlplugin DESTINATION ${PLUGIN_INSTALL_DIR}/imports/org/kde RENAME qmldir) -else() - install( FILES qmldir DESTINATION ${PLUGIN_INSTALL_DIR}/imports/org/kde ) -endif () - -install( FILES - BreadcrumbNavigationView.qml - SlideoutPanel.qml - SlideoutPanelContainer.qml - Dialog.qml - Flap.qml - Flap2.qml - dividing-line.png - dividing-line-horizontal.png - list-line-top.png - scrollable-bottom.png - scrollable-top.png - flap-collapsed-top.png - flap-collapsed-mid.png - flap-collapsed-bottom.png - flap-expanded-top.png - flap-expanded-mid.png - flap-expanded-bottom.png - DESTINATION ${PLUGIN_INSTALL_DIR}/imports/org/kde ) - -install( TARGETS kdeqmlplugin DESTINATION ${PLUGIN_INSTALL_DIR}/imports/org/kde ) - -#add_subdirectory(tests) - -endif () diff -Nru kdepim-runtime-4.14.6/qml/kde/Dialog.qml kdepim-runtime-15.08.0/qml/kde/Dialog.qml --- kdepim-runtime-4.14.6/qml/kde/Dialog.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/Dialog.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -/* - Copyright (C) 2010 Anselmo Lacerda Silveira de Melo - - 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. -*/ - -import Qt 4.7 - -Item { - id : _topLevel - - property alias content : expandFlap.contentArea - - property int contentWidth : expandFlap.width - 80 - - property int expandedPosition : 0 - property int expandedHeight : height - expandedPosition - - property real expandThreshold : 3/4 - - signal extensionChanged(real extension) - - function changeExtension(extension) - { - - } - -// signal expanded(variant obj) -// signal collapsed(variant obj) - - z: 100 - x : 0 - y : 0 - - function collapse() { - expandFlap.changeExtension(0.0) - } - - function expand() { - expandFlap.changeExtension(1.0) - } - - Flap2 { - id : expandFlap - x : -width - y : expandedPosition - leftBound : 0 - rightBound : 80 + contentWidth - height : expandedHeight - - contentWidth : _topLevel.contentWidth - - topBackgroundImage : "flap-expanded-top.png" - midBackgroundImage : "flap-expanded-mid.png" - bottomBackgroundImage : "flap-expanded-bottom.png" - - onExtensionChanged : { - expandFlap.changeExtension(extension) - } - } -} Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/dividing-line-horizontal.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/dividing-line-horizontal.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/dividing-line.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/dividing-line.png differ diff -Nru kdepim-runtime-4.14.6/qml/kde/Flap2.qml kdepim-runtime-15.08.0/qml/kde/Flap2.qml --- kdepim-runtime-4.14.6/qml/kde/Flap2.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/Flap2.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,110 +0,0 @@ -/* - Copyright (C) 2010 Anselmo Lacerda Silveira de Melo - - 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. -*/ - -import Qt 4.7 - -Rectangle { - id : flap_toplevel - property real leftBound - property real rightBound - - property alias topBackgroundImage : topImage.source - property alias midBackgroundImage : midImage.source - property alias bottomBackgroundImage : bottomImage.source - - property alias contentArea : _contentArea.data - property alias contentWidth : _contentArea.width - - color : "#00000000" - - width : draggedItem.width - - opacity : ( draggedItem.x - leftBound ) / (rightBound - leftBound) - - signal extensionChanged(real extension) - - function changeExtension(extension) - { - if (draggedItem.x != leftBound && draggedItem.x != rightBound) - return; - - draggedItem.x = ( extension * (rightBound - leftBound) ) + leftBound - } - - Item { - id : draggedItem - x : leftBound - y : 0 - - width : topImage.width - height : flap_toplevel.height - - onXChanged : { - if (x != leftBound && x != rightBound) - return; - - extensionChanged( ( x - leftBound ) / ( rightBound - leftBound ) ) - } - - Behavior on x { - PropertyAnimation { - duration: 300 - } - } - - Image { - id : topImage - anchors { - top : parent.top - left : parent.left - } - } - Image { - id : midImage - anchors { - top : topImage.bottom - left : parent.left - bottom : bottomImage.top - } - fillMode : Image.TileVertically - } - Image { - id : bottomImage - anchors { - bottom : parent.bottom - left : parent.left - } - } - - Item { - id : _contentArea - width : contentWidth - anchors { - top : parent.top - bottom : parent.bottom - right : parent.right - - leftMargin : 20 - topMargin : 20 - bottomMargin : 20 - rightMargin : 30 - } - } - } -} Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/flap-collapsed-bottom.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/flap-collapsed-bottom.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/flap-collapsed-mid.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/flap-collapsed-mid.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/flap-collapsed-top.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/flap-collapsed-top.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/flap-expanded-bottom.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/flap-expanded-bottom.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/flap-expanded-mid.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/flap-expanded-mid.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/flap-expanded-top.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/flap-expanded-top.png differ diff -Nru kdepim-runtime-4.14.6/qml/kde/Flap.qml kdepim-runtime-15.08.0/qml/kde/Flap.qml --- kdepim-runtime-4.14.6/qml/kde/Flap.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/Flap.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,161 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Rectangle { - id : flap_toplevel - property real leftBound - property real rightBound - property real threshold : 0.5 - property bool expander : false - - property alias topBackgroundImage : collapsed_top.source - property alias midBackgroundImage : collapsed_mid.source - property alias bottomBackgroundImage : collapsed_bottom.source - property alias contentArea : _contentArea.data - property string titleText - property string titleIcon - property int imageWidth : 36 - property alias contentWidth : _contentArea.width - - color : "#00000000" - - width : draggedItem.width - - opacity : expander ? ( draggedItem.x - rightBound) / (leftBound - rightBound) : ( draggedItem.x - leftBound ) / (rightBound - leftBound) - - signal extensionChanged(real extension) - - function changeExtension(extension) - { - if (draggedItem.x != leftBound && draggedItem.x != rightBound) - return; - - draggedItem.x = ( extension * (rightBound - leftBound) ) + leftBound - } - - Item { - id : draggedItem - x : leftBound - y : 0 - - width : collapsed_top.width - height : flap_toplevel.height - - onXChanged : { - if (x != leftBound && x != rightBound) - return; - - extensionChanged( ( x - leftBound ) / ( rightBound - leftBound ) ) - } - - // Bug here: http://bugreports.qt.nokia.com/browse/QTBUG-12295 - Behavior on x { - NumberAnimation { - easing.type: "OutQuad" - easing.amplitude: 100 - duration: 300 - } - } - - Image { - id : collapsed_top - anchors.top : parent.top - anchors.left : parent.left - } - Image { - id : collapsed_mid - anchors.top : collapsed_top.bottom - anchors.left : parent.left - fillMode : Image.TileVertically - anchors.bottom : collapsed_bottom.top - } - Image { - id : collapsed_bottom - anchors.bottom : parent.bottom - anchors.left : parent.left - } - Image { - id: titleImage - width: imageWidth - 4 - height: (titleIcon == '' ? 0 : width) - source: titleIcon - anchors.bottom : parent.bottom - anchors.right: parent.right - anchors.margins: 6 - } - - Text { - id: titleLabel - z : 100 - anchors.verticalCenter : parent.verticalCenter - anchors.horizontalCenter : parent.right - anchors.horizontalCenterOffset : -imageWidth / 2 - anchors.verticalCenterOffset : - titleImage.height / 2 - transformOrigin : Item.Center - rotation: -90 - - text: titleText - horizontalAlignment: "AlignHCenter" - verticalAlignment: "AlignVCenter" - } - - MouseArea { - id: mrDrag - - property bool active : drag.active - - anchors.top : collapsed_top.top - anchors.left : collapsed_top.left - anchors.bottom : collapsed_bottom.bottom - anchors.right : collapsed_bottom.right - - onReleased: { - if (draggedItem.x > leftBound + ( ( rightBound - leftBound ) * threshold ) ) - { - draggedItem.x = rightBound - } else { - draggedItem.x = leftBound - } - } - drag.target: parent; - drag.axis: "XAxis" - drag.minimumX: leftBound - drag.maximumX: rightBound - drag.filterChildren : true - - // This should be a mouse area so we don't block the - // the mouse events that should go to it's children - MouseArea { - id : _contentArea - anchors.top : parent.top - anchors.bottom : parent.bottom - anchors.right : parent.right - width : contentWidth - anchors.leftMargin : 20 - anchors.topMargin : 20 - anchors.bottomMargin : 20 - anchors.rightMargin : 30 - } - } - } -} diff -Nru kdepim-runtime-4.14.6/qml/kde/kdeintegration.cpp kdepim-runtime-15.08.0/qml/kde/kdeintegration.cpp --- kdepim-runtime-4.14.6/qml/kde/kdeintegration.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/kdeintegration.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,306 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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 "kdeintegration.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef _WIN32 -#include -#endif - -static QString translate( const KLocalizedString &msg, - const QScriptContext *context, const int start, bool plural = false ) -{ - KLocalizedString string( msg ); - const int numArgs = context->argumentCount(); - - for (int i = start; i < numArgs; ++i) { - const QVariant arg = context->argument(i).toVariant(); - - // numbers provided from javascript seem to arrive always as double, which does not work for plural handling - if ( i == start && plural ) { - string = string.subs( arg.toInt() ); - continue; - } - - switch ( arg.type() ) { - case QVariant::Char: - string = string.subs( arg.toChar() ); - break; - case QVariant::Int: - string = string.subs( arg.toInt() ); - break; - case QVariant::UInt: - string = string.subs( arg.toUInt() ); - break; - case QVariant::LongLong: - string = string.subs( arg.toLongLong() ); - break; - case QVariant::ULongLong: - string = string.subs( arg.toULongLong() ); - break; - case QVariant::Double: - string = string.subs( arg.toDouble() ); - break; - case QVariant::String: - string = string.subs( arg.toString() ); - break; - default: - kWarning() << "Unknown i18n argument type:" << arg; - } - - } - - return string.toString(); -} - -KDEIntegration::KDEIntegration( QObject *parent ) : QObject( parent ) -{ -} - -QScriptContext *KDEIntegration::getContext( const QScriptValue &v ) -{ - QScriptEngine *engine = v.engine(); - - if (!engine) { - return 0; - } - - QScriptContext *context = engine->currentContext(); - if (!context) { - return 0; - } - - return context; -} - -QString KDEIntegration::i18n( const QScriptValue &array ) -{ - QScriptContext *context = getContext(array); - - if (!context) { - kWarning() << "No context !"; - return QString(); - } - - if (context->argumentCount() < 1) { - // ## TODO: (new str): context->throwError(i18n("i18n() takes at least one argument")); - return QString(); - } - - KLocalizedString message = ki18n(context->argument(0).toString().toUtf8()); - return translate(message, context, 1); -} - - -QString KDEIntegration::i18nc( const QScriptValue &array ) -{ - QScriptContext *context = getContext(array); - - if (!context) { - kWarning() << "No context !"; - return QString(); - } - - if (context->argumentCount() < 2) { - kWarning() << "i18nc() takes at least two arguments"; - //### TODO (new str): context->throwError(i18n("i18nc() takes at least two arguments")); - return QString(); - } - - KLocalizedString message = ki18nc(context->argument(0).toString().toUtf8(), - context->argument(1).toString().toUtf8()); - - return translate(message, context, 2); -} - -QString KDEIntegration::i18np( const QScriptValue &array ) -{ - QScriptContext *context = getContext(array); - - if (!context) { - kWarning() << "No context !"; - return QString(); - } - - if (context->argumentCount() < 2) { - kWarning() << "i18np() takes at least two arguments"; - //### TODO (new str): context->throwError(i18n("i18np() takes at least two arguments")); - return QString(); - } - - KLocalizedString message = ki18np(context->argument(0).toString().toUtf8(), - context->argument(1).toString().toUtf8()); - - return translate(message, context, 2, true); -} - -QString KDEIntegration::i18ncp( const QScriptValue &array ) -{ - QScriptContext *context = getContext(array); - - if (!context) { - kWarning() << "No context !"; - return QString(); - } - - if (context->argumentCount() < 3) { - kWarning() << "i18ncp() takes at least three arguments"; - //### TODO (new str): context->throwError(i18n("i18ncp() takes at least three arguments")); - return QString(); - } - - KLocalizedString message = ki18ncp(context->argument(0).toString().toUtf8(), - context->argument(1).toString().toUtf8(), - context->argument(2).toString().toUtf8()); - - return translate(message, context, 3, true); -} - -QString KDEIntegration::iconPath( const QString &iconName, int iconSize ) -{ - return KIconLoader::global()->iconPath( iconName, -iconSize ); // yes, the minus there is correct... -} - -QPixmap KDEIntegration::iconToPixmap(const QIcon& icon, int size ) -{ - if ( icon.isNull() ) - return QPixmap(); - return icon.pixmap( size ); -} - -QString KDEIntegration::locate(const QString& type, const QString& filename) -{ - return KStandardDirs::locate( type.toLatin1(), filename ); -} - -qreal KDEIntegration::mm2px(qreal mm) -{ -#ifdef _WIN32 -//TODO: Cache value - HMONITOR mon = MonitorFromWindow(QApplication::desktop()->winId(), MONITOR_DEFAULTTONEAREST); - MONITORINFOEX moninfo; - moninfo.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(mon, &moninfo); - - long monitorWidthInPixel = moninfo.rcMonitor.right - moninfo.rcMonitor.left; - long monitorHeightinPixel = moninfo.rcMonitor.bottom - moninfo.rcMonitor.top; - - DISPLAY_DEVICE dd; - dd.cb = sizeof(DISPLAY_DEVICE); - EnumDisplayDevices(moninfo.szDevice, 0, &dd, 0); - - const QString deviceID = QString::fromUtf16( ( const unsigned short *)dd.DeviceID); - - QRegExp rx(QLatin1String("^MONITOR\\\\(\\w+)\\\\")); - - if (rx.indexIn(deviceID) != -1) { - const QString devID = rx.cap(1); - - const QString baseRegKey = - QLatin1String("SYSTEM\\CurrentControlSet\\Enum\\DISPLAY\\") + devID; - - HKEY registryHandle; - LONG res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - reinterpret_cast(baseRegKey.utf16()), - 0, - KEY_READ, - ®istryHandle); - if (res != ERROR_SUCCESS) { - RegCloseKey(registryHandle); - return mm * QApplication::desktop()->logicalDpiX() / 25.4; - } - - DWORD keyLength = 0; - res = RegQueryInfoKey(registryHandle, 0, 0, 0, 0, &keyLength, 0, 0, 0, 0, 0, 0); - if (res != ERROR_SUCCESS) { - RegCloseKey(registryHandle); - return mm * QApplication::desktop()->logicalDpiX() / 25.4; - } - - //Utf16 so 2 Bytes per Character - QByteArray buf(keyLength * 2, 0); - keyLength++; //keyLength including the terminating 0, which is already in a QByteArray - - res = RegEnumKeyEx(registryHandle, - 0, - reinterpret_cast(buf.data()), - &keyLength, - 0, - 0, - 0, - 0); - if (res != ERROR_SUCCESS) { - RegCloseKey(registryHandle); - return mm * QApplication::desktop()->logicalDpiX() / 25.4; - } - RegCloseKey(registryHandle); - - const QString guidString = QString::fromWCharArray(reinterpret_cast(buf.data())); - - const QString edidRegString = QLatin1String("SYSTEM\\CurrentControlSet\\Enum\\DISPLAY\\") - + devID + QLatin1String("\\") + guidString + QLatin1String("\\Device Parameters"); - RegOpenKeyEx(HKEY_LOCAL_MACHINE, reinterpret_cast(edidRegString.utf16()), - 0, KEY_READ, ®istryHandle); - - DWORD dataSize; - res = RegQueryValueEx(registryHandle, L"EDID", 0, 0, 0, &dataSize); - if (res != ERROR_SUCCESS) { - RegCloseKey(registryHandle); - return mm * QApplication::desktop()->logicalDpiX() / 25.4; - } - - QByteArray data(dataSize, 0); - res = RegQueryValueEx(registryHandle, L"EDID", 0, 0, - reinterpret_cast(data.data()), &dataSize); - RegCloseKey(registryHandle); - - const int monitorWidthInCM = data.at(21); - //int monitorHeightInCM = data.at(22); - - return (monitorWidthInPixel * mm) / (monitorWidthInCM * 10.0); - //int pixelPerMM = monitorHeightinPixel / (monitorHeightInCM * 10.0); - } -#endif - -#ifdef Q_WS_MAEMO_5 - // N900 (which is the only thing actually running Maemo5) reports 96 dpi while its screen actually has 267 dpi - return mm * 267 / 25.4; -#elif defined(MEEGO_EDITION_HARMATTAN) - // N9[50] (which is the only thing actually running Maemo6) reports 96 dpi as well while its screen actually has 251 dpi - return mm * 251 / 25.4; -#endif - return mm * QApplication::desktop()->logicalDpiX() / 25.4; -} - -#include "moc_kdeintegration.cpp" - diff -Nru kdepim-runtime-4.14.6/qml/kde/kdeintegration.h kdepim-runtime-15.08.0/qml/kde/kdeintegration.h --- kdepim-runtime-4.14.6/qml/kde/kdeintegration.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/kdeintegration.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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 KDEINTEGRATION_H -#define KDEINTEGRATION_H - -#include -#include -#include - -class QIcon; -class QPixmap; -class QScriptValue; -class QScriptContext; - -class KDEIntegration : public QObject -{ - Q_OBJECT - - public: - explicit KDEIntegration(QObject* parent = 0); - - public slots: - QString i18n( const QScriptValue &array ); - QString i18nc( const QScriptValue &array ); - QString i18np( const QScriptValue &array ); - QString i18ncp( const QScriptValue &array ); - - QString iconPath( const QString &iconName, int size ); - QPixmap iconToPixmap( const QIcon &icon, int size ); - - QString locate( const QString &type, const QString &filename ); - - /// convert millimeters into pixels - qreal mm2px( qreal mm ); - - private: - QScriptContext *getContext( const QScriptValue &v ); -}; - -#endif - diff -Nru kdepim-runtime-4.14.6/qml/kde/kdeintegrationplugin.cpp kdepim-runtime-15.08.0/qml/kde/kdeintegrationplugin.cpp --- kdepim-runtime-4.14.6/qml/kde/kdeintegrationplugin.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/kdeintegrationplugin.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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 "kdeintegrationplugin.h" -#include "kdeintegration.h" - -#include -#include -#include -#include - -KDEIntegrationPlugin::KDEIntegrationPlugin(QObject* parent) : QDeclarativeExtensionPlugin( parent ) -{ - qDebug() << Q_FUNC_INFO; - kDebug(); -} - -void KDEIntegrationPlugin::registerTypes(const char* uri) -{ - kDebug() << uri; -// qmlRegisterType( uri, 4, 5, "KDE" ); -} - -void KDEIntegrationPlugin::initializeEngine(QDeclarativeEngine *engine, const char* uri) -{ - kDebug() << engine << uri; - engine->rootContext()->setContextProperty( QLatin1String("KDE"), new KDEIntegration( engine ) ); -} - - -Q_EXPORT_PLUGIN2( kdeintegrationplugin, KDEIntegrationPlugin ) diff -Nru kdepim-runtime-4.14.6/qml/kde/kdeintegrationplugin.h kdepim-runtime-15.08.0/qml/kde/kdeintegrationplugin.h --- kdepim-runtime-4.14.6/qml/kde/kdeintegrationplugin.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/kdeintegrationplugin.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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 KDEDECLARATIVEEXTENSIONPLUGIN_H -#define KDEDECLARATIVEEXTENSIONPLUGIN_H - -#include -#include - -class KDE_EXPORT KDEIntegrationPlugin : public QDeclarativeExtensionPlugin -{ - Q_OBJECT - public: - explicit KDEIntegrationPlugin(QObject* parent = 0); - virtual void registerTypes(const char* uri); - virtual void initializeEngine(QDeclarativeEngine* engine, const char* uri); -}; - -#endif Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/list-line-top.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/list-line-top.png differ diff -Nru kdepim-runtime-4.14.6/qml/kde/qmldir kdepim-runtime-15.08.0/qml/kde/qmldir --- kdepim-runtime-4.14.6/qml/kde/qmldir 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/qmldir 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -plugin kdeqmlplugin -BreadcrumbNavigationView 4.5 BreadcrumbNavigationView.qml -CollectionDelegate 4.5 CollectionDelegate.qml -SlideoutPanel 4.5 SlideoutPanel.qml -SlideoutPanelContainer 4.5 SlideoutPanelContainer.qml -Flap 4.5 Flap.qml -Flap2 4.5 Flap2.qml -Dialog 4.5 Dialog.qml diff -Nru kdepim-runtime-4.14.6/qml/kde/qmldir_without_kdeqmlplugin kdepim-runtime-15.08.0/qml/kde/qmldir_without_kdeqmlplugin --- kdepim-runtime-4.14.6/qml/kde/qmldir_without_kdeqmlplugin 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/qmldir_without_kdeqmlplugin 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -BreadcrumbNavigationView 4.5 BreadcrumbNavigationView.qml -CollectionDelegate 4.5 CollectionDelegate.qml -SlideoutPanel 4.5 SlideoutPanel.qml -SlideoutPanelContainer 4.5 SlideoutPanelContainer.qml -Flap 4.5 Flap.qml -Flap2 4.5 Flap2.qml -Dialog 4.5 Dialog.qml Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/scrollable-bottom.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/scrollable-bottom.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/scrollable-top.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/scrollable-top.png differ diff -Nru kdepim-runtime-4.14.6/qml/kde/SlideoutPanelContainer.qml kdepim-runtime-15.08.0/qml/kde/SlideoutPanelContainer.qml --- kdepim-runtime-4.14.6/qml/kde/SlideoutPanelContainer.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/SlideoutPanelContainer.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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. -*/ - -import Qt 4.7 - -/** - * Container for a set of SlideoutPanels. - * It ensures that only one of them is expanded at any given time. - */ -Item { - id: _slideoutPanelContainer - - /** Margin of the panels regarding the container on the three sides where it is not docked to the edge. */ - property int margin: 20 - - /** Collapse all panels. */ - function collapseOthers(obj) - { - for ( var i = 0; i < children.length; ++i ) { - // Does not work: - // if (children[i] != obj) - if (!children[i].noCollapse) - children[i].collapse(); - } - } - - Component.onCompleted: - { - for ( var i = 0; i < children.length; ++i ) { - var panel = children[i]; - panel.expanded.connect( this, collapseOthers ); - panel.anchors.fill = _slideoutPanelContainer; - panel.anchors.rightMargin = margin; - panel.anchors.topMargin = margin; - panel.anchors.bottomMargin = margin; - /* - if ( i >= 1 ) { - var prevPanel = children[i - 1]; - panel.collapsedPosition = prevPanel.collapsedPosition + prevPanel.collapsedHeight - } */ - } - /* - // limit the height of the last panel to the available space - if ( children.length > 0 ) { - var lastPanel = children[ children.length - 1 ]; - if ( children.length > 1 ) { - var prevPanel = children[ children.length - 2 ]; - lastPanel.collapsedHeight = Math.min( lastPanel.collapsedHeight, height - prevPanel.collapsedPosition - prevPanel.collapsedHeight - lastPanel.anchors.topMargin - lastPanel.anchors.bottomMargin ); - } else { - lastPanel.collapsedHeight = Math.min( lastPanel.collapsedHeight, height - lastPanel.anchors.topMargin - lastPanel.anchors.bottomMargin ); - } - } */ - } -} diff -Nru kdepim-runtime-4.14.6/qml/kde/SlideoutPanel.qml kdepim-runtime-15.08.0/qml/kde/SlideoutPanel.qml --- kdepim-runtime-4.14.6/qml/kde/SlideoutPanel.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/SlideoutPanel.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,137 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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. -*/ - -import Qt 4.7 - -/** - * A container for arbitrary content that can be expanded via dragging from a screen edge. - * @param titleText Tab label in collapsed state - * @param tilteIcon Tab icon path in collapsed state - * @param handlePosition offset from the top for the tab handle in collapsed state - * @param handleWidth Tab height in collapsed state - * @param handleHeight Tab width in collapsed state - * @param dragThreshold Drag distance needed before expanding - * @param radius tab and panel corner radius - * @param contentWidth width of the content area in expanded state - * @signal expanded emitted when the panel is expanded - * @slot collapse collapses the panel - */ -Item { - - id : _topLevel - property alias titleText : collapseFlap.titleText - property alias titleIcon : collapseFlap.titleIcon - - property alias collapsedContent : collapseFlap.contentArea - property alias expandedContent : expandFlap.contentArea - - - // Compat. Remove these. - property alias content : expandFlap.contentArea - property int handlePosition : 0 - property int handleHeight : 160 - property int contentWidth : expandFlap.width - 40 - collapsedWidth //: expandFlap.contentWidth - - property int collapsedPosition : handlePosition - property int expandedPosition : 0 - - property int collapsedWidth : 36 - - property int collapsedHeight : handleHeight - property int expandedHeight : height - expandedPosition - - property real collapseThreshold : 1/4 - property real expandThreshold : 3/4 - - property bool noCollapse : false - - signal extensionChanged(real extension) - - function changeExtension(extension) - { - - } - - signal expanded(variant obj) - signal collapsed(variant obj) - - z: 100 - x : 0 - y : 0 - - function collapse() { - collapseFlap.changeExtension(0.0) - } - - function expand() { - collapseFlap.changeExtension(1.0) - } - - Flap { - id : collapseFlap - x : collapsedWidth - width - y : collapsedPosition - threshold : collapseThreshold - - leftBound : 0 - rightBound : width - collapsedWidth - - height : collapsedHeight - topBackgroundImage : "flap-collapsed-top.png" - midBackgroundImage : "flap-collapsed-mid.png" - bottomBackgroundImage : "flap-collapsed-bottom.png" - expander : true - - onExtensionChanged : { - if (extension == 1.0) - { - _topLevel.noCollapse = true; - _topLevel.z = 99; - expanded(parent); - _topLevel.noCollapse = false; - } - else if (extension == 0.0) { - _topLevel.z = 100; - collapsed(parent); - } - - expandFlap.changeExtension(extension) - } - } - - Flap { - id : expandFlap - x : -width - y : expandedPosition - leftBound : 0 - rightBound : 40 + contentWidth + collapsedWidth - height : expandedHeight - threshold : expandThreshold - - contentWidth : _topLevel.contentWidth // width - 40 - collapsedWidth - - topBackgroundImage : "flap-expanded-top.png" - midBackgroundImage : "flap-expanded-mid.png" - bottomBackgroundImage : "flap-expanded-bottom.png" - - onExtensionChanged : { - collapseFlap.changeExtension(extension) - } - } -} diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/actionstest.qml kdepim-runtime-15.08.0/qml/kde/tests/actionstest.qml --- kdepim-runtime-4.14.6/qml/kde/tests/actionstest.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/actionstest.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 as QML -import org.kde.pim.mobileui 4.5 as KPIM - -QML.Rectangle { - width : 800 - height : 500 - - KPIM.ActionMenuContainer { - x : 100 - y : 100 - width : 600 - height : 300 - id :myTree - actionItemHeight : 70 - actionItemWidth : 200 - actionItemSpacing : 2 - - KPIM.FakeAction { name : "quit" } - - KPIM.ActionList { - name : "file" - KPIM.ActionList { - name : "new" - KPIM.FakeAction { name : "new event" } - KPIM.FakeAction { name : "new alarm" } - KPIM.FakeAction { name : "new birthday" } - - } - KPIM.FakeAction { name : "import" } - KPIM.FakeAction { name : "export" } - } - - KPIM.ActionList { - name : "edit" - KPIM.FakeAction { name : "copy" } - KPIM.FakeAction { name : "move" } - KPIM.FakeAction { name : "cut" } - - } - - KPIM.ReorderList { - name : "reorder" - - delegate : QML.Component { - QML.Text { height : 20; text : model.index } - } - model : 15 - - } - - KPIM.ActionList { - name : "view" - KPIM.FakeAction { name : "month_view" } - KPIM.FakeAction { name : "day_view" } - KPIM.FakeAction { name : "week_view" } - KPIM.FakeAction { name : "hour_view" } - - } - - /* - KPIM.ActionList { - name : "view" - KPIM.ActionListItem { name : "month" } - KPIM.ActionListItem { name : "week" } - KPIM.ActionListItem { name : "day" } - } */ - /* - ActionList { - name : "view" - Action { "A" } - ActionList { - name : "B" - Action { "B1" } - Action { "B2" } - } - Action { - Action { "C" } - } - } */ - } - -} diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/behaviouronx.qml kdepim-runtime-15.08.0/qml/kde/tests/behaviouronx.qml --- kdepim-runtime-4.14.6/qml/kde/tests/behaviouronx.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/behaviouronx.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Rectangle { - width : 800 - height : 480 - - SliderComponent { - id : one - y : 30 - x : 50 - height : 100 - leftBound : 30 - rightBound : 130 - } -} diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/bindinggroupedproperties.qml kdepim-runtime-15.08.0/qml/kde/tests/bindinggroupedproperties.qml --- kdepim-runtime-4.14.6/qml/kde/tests/bindinggroupedproperties.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/bindinggroupedproperties.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -import Qt 4.7 - -Item { - width : 400 - height : 400 - Rectangle { - id : rectY - color : "yellow" - width : maY.containsMouse ? 200 : 100 - height : 100 - MouseArea { - id : maY - hoverEnabled : true - anchors.fill : parent - } - } - Rectangle { - id : rectR - color : "red" - width : 50 - height : 50 - //anchors.left : rectY.right - } - Binding { - target : rectR - property : "anchors.left" - value : rectY.right - } -} - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/collapsibilesections.qml kdepim-runtime-15.08.0/qml/kde/tests/collapsibilesections.qml --- kdepim-runtime-4.14.6/qml/kde/tests/collapsibilesections.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/collapsibilesections.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** 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 examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "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 Nokia Corporation and its Subsidiary(-ies) 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 -** OWNER 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." -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// This example shows how a ListView can be separated into sections using -// the ListView.section attached property. - -import Qt 4.7 - -//! [0] -Rectangle { - id: container - width: 200 - height: 250 - - ListModel { - id: animalsModel - ListElement { name: "Parrot"; size: "Small" } - ListElement { name: "Guinea pig"; size: "Small" } - ListElement { name: "Dog"; size: "Medium" } - ListElement { name: "Cat"; size: "Medium" } - ListElement { name: "Elephant"; size: "Large" } - } - - // The delegate for each section header - Component { - id: sectionHeading - Rectangle { - width: container.width - height: childrenRect.height - color: "lightsteelblue" - - Text { - text: section - font.bold: true - } - MouseArea { - anchors.fill : parent - onClicked: - { - if (myList.expanded.indexOf(section) != -1) { - myList.expanded = myList.expanded.replace(section + ",", "") - } - else { - myList.expanded += (section + ",") - } - } - } - } - } - Component { - id : itemDelegate - - Text { - clip :true - height : ListView.view.expanded.indexOf(model.size) > -1 ? 30 : 0 - text: name - } - } - ListView { - id : myList - property string expanded - - onExpandedChanged : - console.log("expanded" + expanded) - - anchors.fill: parent - model: animalsModel - delegate: itemDelegate - - section.property: "size" - section.criteria: ViewSection.FullString - section.delegate: sectionHeading - } -} -//! [0] - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/disconnect.qml kdepim-runtime-15.08.0/qml/kde/tests/disconnect.qml --- kdepim-runtime-4.14.6/qml/kde/tests/disconnect.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/disconnect.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Rectangle { - width : 200 - height : 200 - - SomeComponent { - x : 30 - y : 30 - width : 30 - height : 30 - id : blueRect - color : "blue" - - Rectangle { - x : 130 - y : 30 - width : 30 - height : 30 - color : "red" - - signal triggered() - - MouseArea { - anchors.fill : parent - onClicked : parent.triggered() - } - } - } -} \ No newline at end of file diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/dragitems-0.qml kdepim-runtime-15.08.0/qml/kde/tests/dragitems-0.qml --- kdepim-runtime-4.14.6/qml/kde/tests/dragitems-0.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/dragitems-0.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Rectangle { - width : 400 - height : 400 - - Rectangle { - id : dropRect - x : 130 - y : 30 - width : 90 - height : 150 - color : "green" - } - Rectangle { - x : 30 - y : 30 - width : 90 - height : 150 - id : blueRect - color : "blue" - - Rectangle { - x : 10 - y : 30 - width : 70 - height : 90 - color : "yellow" - - Rectangle { - id : placeholder - x : 20 - y : 30 - width : 30 - height : 30 -// clip : true - Rectangle { - id : targetRect - width : parent.width - height : parent.height - color : "lightsteelblue" - z : 10000 - - MouseArea { - anchors.fill : parent - - drag.target : targetRect - drag.axis : Drag.XAxis - drag.minimumX : 0 - drag.maximumX : 100 - } - } - } - } - } -} \ No newline at end of file diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/elementmodel.qml kdepim-runtime-15.08.0/qml/kde/tests/elementmodel.qml --- kdepim-runtime-4.14.6/qml/kde/tests/elementmodel.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/elementmodel.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Rectangle { - width : 500 - height : 500 - - VisualItemModel { - id : items - Rectangle { - id : top1 - width : 100 //ListView.view.width - height : 30 - color : "red" - MouseArea { - anchors.fill : parent - onClicked : { - myList.currentIndex = top1.VisualItemModel.index - } - } - } - Rectangle { - id : top2 - width : 100 //ListView.view.width - height : 30 - color : "green" - MouseArea { - anchors.fill : parent - onClicked : { - myList.currentIndex = top2.VisualItemModel.index - } - } - } - Rectangle { - id : top3 - width : 100 //ListView.view.width - height : 30 - color : "blue" - MouseArea { - anchors.fill : parent - onClicked : { - myList.currentIndex = top3.VisualItemModel.index - } - } - } - } - - Component { - id: highlightBar - Rectangle { - x : -10 - width: 120; height: 30 - color: "#66FFFF88" - y: myList.currentItem.y; - Behavior on y { NumberAnimation { duration : 100; easing.type : OutQuad } } - } - } - - ListView { - id : myList - x : 30 - y : 30 - width : 100 - height : 100 - model : items - focus : true - - delegate : Text { text : model.index; height : 30; width : ListView.view.width } - - highlight : highlightBar - } -} \ No newline at end of file diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/i18n.qml kdepim-runtime-15.08.0/qml/kde/tests/i18n.qml --- kdepim-runtime-4.14.6/qml/kde/tests/i18n.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/i18n.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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. -*/ - -import Qt 4.7 -import org.kde 4.5 - -Rectangle { - width: 100; height: 100; color: "blue" - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton - onClicked: { - console.log( "*** begin i18n test ***" ); - console.log( KDE.i18n( "single message" ) ); - console.log( KDE.i18n( "single message with arguments %1 %2", "bar", "foo" ) ); - console.log( KDE.i18n( "single message with arguments multiline %1 %2", - "bar", - "foo" ) ); - console.log( KDE.i18nc( "context", "message with context and \n to break our script" ) ); - console.log( KDE.i18nc( "context", "message with context and arguments %1 %2 %3", 5, 3.1415, "string" ) ); - console.log( KDE.i18np( "singular", "%1 plural", 1 ) ); - console.log( KDE.i18np( "singular", "%1 plural", 2 ) ); - console.log( KDE.i18np( "singular with arg %2", "%1 plural with arg %2", 1, "bla" ) ); - console.log( KDE.i18np( "singular with arg %2", "%1 plural with arg %2", 2, "bla" ) ); - console.log( KDE.i18ncp( "context", "singular", "%1 plural", 1 ) ); - console.log( KDE.i18ncp( "context", "singular", "%1 plural", 2 ) ); - console.log( KDE.i18ncp( "context", "singular with arg %2", "%1 plural with arg %2", 1, "bla" ) ); - console.log( KDE.i18ncp( "context", "singular with arg %2", "%1 plural with arg %2", 2, "bla" ) ); - console.log( "*** end i18n test ***" ); - } - } - Text { - text: KDE.i18n( "Click to run test!" ); - } - } diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/icons.qml kdepim-runtime-15.08.0/qml/kde/tests/icons.qml --- kdepim-runtime-4.14.6/qml/kde/tests/icons.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/icons.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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. -*/ - -import Qt 4.7 -import org.kde 4.5 - -Image { - width: 256; height: 256; - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton - onClicked: { - console.log( "*** begin icon path test ***" ); - console.log( "icon 4: " + KDE.iconPath( "akonadi", 4 ) ); - console.log( "icon 15: " + KDE.iconPath( "akonadi", 15 ) ); - console.log( "icon 32: " + KDE.iconPath( "akonadi", 32 ) ); - console.log( "icon 65: " + KDE.iconPath( "akonadi", 65 ) ); - console.log( "icon 1000: " + KDE.iconPath( "akonadi", 1000 ) ); - console.log( "*** end icon path test ***" ); - } - } - - source: KDE.iconPath( "akonadi", 256 ); - } diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/kstandarddirs.qml kdepim-runtime-15.08.0/qml/kde/tests/kstandarddirs.qml --- kdepim-runtime-4.14.6/qml/kde/tests/kstandarddirs.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/kstandarddirs.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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. -*/ - -import Qt 4.7 -import org.kde 4.5 - -Rectangle { - width: 256; height: 256; - MouseArea { - anchors.fill: parent - onClicked: { - console.log( "*** begin kstandarddirs test ***" ); - console.log( "share/apps/mobileui/top.png: " + KDE.locate( "data", "mobileui/top.png" ) ); - console.log( "*** end kstandarddirs test ***" ); - } - } -} diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/mm2px.qml kdepim-runtime-15.08.0/qml/kde/tests/mm2px.qml --- kdepim-runtime-4.14.6/qml/kde/tests/mm2px.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/mm2px.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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. -*/ - -import Qt 4.7 -import org.kde 4.5 - -Rectangle { - width: KDE.mm2px( 100 ) - height: KDE.mm2px( 100 ) - color: "lightsteelblue" - Rectangle { - width: KDE.mm2px( 40 ) - height: KDE.mm2px( 40 ) - x: KDE.mm2px( 20 ) - y: KDE.mm2px( 10 ) - color: "yellow" - } -} - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/MyItem.qml kdepim-runtime-15.08.0/qml/kde/tests/MyItem.qml --- kdepim-runtime-4.14.6/qml/kde/tests/MyItem.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/MyItem.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Rectangle { - width : 50 - height : 50 - - color : "blue" - - signal triggered(variant triggeredObject) - - MouseArea { - anchors.fill : parent - onClicked : { - parent.color = "green" - console.log("CLICK TRIGGERED " + parent) - triggered(parent) - } - } - -} \ No newline at end of file diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/propagateevent.qml kdepim-runtime-15.08.0/qml/kde/tests/propagateevent.qml --- kdepim-runtime-4.14.6/qml/kde/tests/propagateevent.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/propagateevent.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Rectangle { - width : 800 - height : 480 - - Flickable { - x : 400 - y : 0 - width : 100 - height : 350 - clip : true - flickableDirection: Flickable.VerticalFlick - contentHeight: myColumn.height; - - Column { - id : myColumn - Text { height : 20; width : 100; text : "a" } - Text { height : 20; width : 100; text : "b" } - Text { height : 20; width : 100; text : "c" } - Text { height : 20; width : 100; text : "d" } - Text { height : 20; width : 100; text : "e" } - Text { height : 20; width : 100; text : "f" } - Text { height : 20; width : 100; text : "g" } - Text { height : 20; width : 100; text : "h" } - Text { height : 20; width : 100; text : "i" } - Text { height : 20; width : 100; text : "j" } - Text { height : 20; width : 100; text : "k" } - Text { height : 20; width : 100; text : "l" } - Text { height : 20; width : 100; text : "m" } - Text { height : 20; width : 100; text : "n" } - Text { height : 20; width : 100; text : "o" } - Text { height : 20; width : 100; text : "p" } - Text { height : 20; width : 100; text : "q" } - Text { height : 20; width : 100; text : "r" } - Text { height : 20; width : 100; text : "s" } - Text { height : 20; width : 100; text : "t" } - Text { height : 20; width : 100; text : "u" } - Text { height : 20; width : 100; text : "v" } - Text { height : 20; width : 100; text : "w" } - Text { height : 20; width : 100; text : "x" } - Text { height : 20; width : 100; text : "y" } - Text { height : 20; width : 100; text : "z" } - } - } - - Rectangle { - x : 30 - y : 30 - color : "lightsteelblue" - width : 300 - height : 300 - - MouseArea { - id: mrDrag - anchors.fill: parent - - onClicked : { - mouse.accepted = false; - return; - } - - onReleased: { - if (!drag.active) - { - mouse.accepted = false; - return; - } - } - - Rectangle { - color : "yellow" - x : 50 - y : 50 - z : 1000 - width : 100 - height : 100 - - - MouseArea { - anchors.fill : parent - onClicked : { - console.log("Clicked"); - } - onPressed : { - console.log("P") - mouse.accepted = true - } - onPressAndHold : { - console.log("P AND H") - mouse.accepted = false - } - } - } - - drag.target: parent; - drag.axis: "XAxis" - drag.filterChildren : true - drag.minimumX: 30 - drag.maximumX: 430 - } - } - -} diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/001-change-opacity kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/001-change-opacity --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/001-change-opacity 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/001-change-opacity 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -diff --git a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -index 78b8bf1..44d789c 100644 ---- a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -+++ b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -@@ -320,7 +320,7 @@ Item { - target : breadcrumbRightDivider - anchors.topMargin : -8 - height : {console.log(itemHeight); 67} -- opacity : 0 -+ opacity : 1 - } - PropertyChanges { - target : selectedItemPlaceHolder diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/002-change-opacity-with-braces kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/002-change-opacity-with-braces --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/002-change-opacity-with-braces 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/002-change-opacity-with-braces 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -diff --git a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -index 78b8bf1..bc69a93 100644 ---- a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -+++ b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -@@ -320,7 +320,7 @@ Item { - target : breadcrumbRightDivider - anchors.topMargin : -8 - height : {console.log(itemHeight); 67} -- opacity : 0 -+ opacity : { 1 } - } - PropertyChanges { - target : selectedItemPlaceHolder diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/003-change-opacity-properly kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/003-change-opacity-properly --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/003-change-opacity-properly 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/003-change-opacity-properly 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -diff --git a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -index 78b8bf1..9bb900e 100644 ---- a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -+++ b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -@@ -320,7 +320,7 @@ Item { - target : breadcrumbRightDivider - anchors.topMargin : -8 - height : {console.log(itemHeight); 67} -- opacity : 0 -+ opacity : selectedItemView.count > 0 ? 1 : 0 - } - PropertyChanges { - target : selectedItemPlaceHolder diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/004-add-second-breadcrumbitem kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/004-add-second-breadcrumbitem --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/004-add-second-breadcrumbitem 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/004-add-second-breadcrumbitem 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -diff --git a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -index 78b8bf1..ab27d9d 100644 ---- a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -+++ b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -@@ -80,7 +80,7 @@ Item { - - ListView { - id : breadcrumbsView -- interactive : false -+ //interactive : false - height : breadcrumbsView.count > 0 ? itemHeight : 0 - - clip : true; -diff --git a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp -index ae44e36..0f363a9 100644 ---- a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp -+++ b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp -@@ -133,7 +133,7 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags f ) - QDeclarativeContext *context = m_declarativeView->engine()->rootContext(); - - m_bnf = new KBreadcrumbNavigationFactory(this); -- m_bnf->setBreadcrumbDepth(1); -+ m_bnf->setBreadcrumbDepth(2); - m_bnf->createBreadcrumbContext( m_treeModel, this ); - - widget->treeView()->setSelectionModel( m_bnf->selectionModel() ); diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/005-try-to-make-bottom-item-always-visible kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/005-try-to-make-bottom-item-always-visible --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/005-try-to-make-bottom-item-always-visible 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/005-try-to-make-bottom-item-always-visible 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -diff --git a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -index 1978b72..f4f23ae 100644 ---- a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -+++ b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -@@ -57,7 +57,7 @@ Item { - - ListView { - id : topButton -- interactive : false -+// interactive : false - height : itemHeight - - anchors.top : parent.top -@@ -92,6 +92,15 @@ Item { - highlightRangeMode : ListView.StrictlyEnforceRange - preferredHighlightBegin : 0 - preferredHighlightEnd : height -+ onCountChanged : { -+ console.log("count ###" + count); -+ console.log("BEFORE" + indexAt(0, 0) + " CurrentIndex:" + currentIndex); -+ positionViewAtIndex(count - 1, ListView.Beginning) -+ console.log("AFTER" + indexAt(0, 0) + " CurrentIndex:" + currentIndex); -+ // Select down to GMail > Inbox > Subfolder 4, flick inbox into view (it's below Gmail). Select inbox. Get: -+ // ASSERT: "!isEmpty()" in file ../../include/QtCore/../../../../src/qt/src/corelib/tools/qlist.h, line 269 -+ // Also note that the view does not reposition -+ } - } - - Item { -diff --git a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp -index ae44e36..0f363a9 100644 ---- a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp -+++ b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp -@@ -133,7 +133,7 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags f ) - QDeclarativeContext *context = m_declarativeView->engine()->rootContext(); - - m_bnf = new KBreadcrumbNavigationFactory(this); -- m_bnf->setBreadcrumbDepth(1); -+ m_bnf->setBreadcrumbDepth(2); - m_bnf->createBreadcrumbContext( m_treeModel, this ); - - widget->treeView()->setSelectionModel( m_bnf->selectionModel() ); diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/006-using-apply-range-helps-somewhat kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/006-using-apply-range-helps-somewhat --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/006-using-apply-range-helps-somewhat 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/006-using-apply-range-helps-somewhat 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -diff --git a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -index 1978b72..14a8042 100644 ---- a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -+++ b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml -@@ -57,7 +57,7 @@ Item { - - ListView { - id : topButton -- interactive : false -+// interactive : false - height : itemHeight - - anchors.top : parent.top -@@ -89,9 +89,20 @@ Item { - anchors.left : parent.left - anchors.right : parent.right - highlightFollowsCurrentItem : true -- highlightRangeMode : ListView.StrictlyEnforceRange -+ // If ApplyRange is used, it works when navigating down the tree, but when navigating up the -+ // breadcrumbs, the first item in the list is shown instead of the second. -+ highlightRangeMode : ListView.ApplyRange - preferredHighlightBegin : 0 - preferredHighlightEnd : height -+ onCountChanged : { -+ console.log("count ###" + count); -+ console.log("BEFORE" + indexAt(0, 0) + " CurrentIndex:" + currentIndex); -+ positionViewAtIndex(count - 1, ListView.Beginning) -+ console.log("AFTER" + indexAt(0, 0) + " CurrentIndex:" + currentIndex); -+ // Select down to GMail > Inbox > Subfolder 4, flick inbox into view (it's below Gmail). Select inbox. Get: -+ // ASSERT: "!isEmpty()" in file ../../include/QtCore/../../../../src/qt/src/corelib/tools/qlist.h, line 269 -+ // Also note that the view does not reposition -+ } - } - - Item { -diff --git a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp -index ae44e36..0f363a9 100644 ---- a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp -+++ b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp -@@ -133,7 +133,7 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags f ) - QDeclarativeContext *context = m_declarativeView->engine()->rootContext(); - - m_bnf = new KBreadcrumbNavigationFactory(this); -- m_bnf->setBreadcrumbDepth(1); -+ m_bnf->setBreadcrumbDepth(2); - m_bnf->createBreadcrumbContext( m_treeModel, this ); - - widget->treeView()->setSelectionModel( m_bnf->selectionModel() ); Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/backgroundtile.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/backgroundtile.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/border_dot.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/border_dot.png differ diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigationcontext.cpp kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigationcontext.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigationcontext.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigationcontext.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,397 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 "breadcrumbnavigationcontext.h" - -#include -#include - -#include "kselectionproxymodel.h" -#include "kbreadcrumbselectionmodel.h" -#include "kproxyitemselectionmodel.h" -#include "kmodelindexproxymapper.h" - -#include "breadcrumbnavigation.h" -#include "qmllistselectionmodel.h" -#include "checkableitemproxymodel.h" - -class QMLCheckableItemProxyModel : public CheckableItemProxyModel -{ -public: - enum MoreRoles { - CheckOn = Qt::UserRole + 3000 - }; - QMLCheckableItemProxyModel (QObject* parent = 0) - : CheckableItemProxyModel(parent) - { - } - - virtual void setSourceModel(QAbstractItemModel* sourceModel) - { - CheckableItemProxyModel::setSourceModel(sourceModel); - - QHash roles = roleNames(); - roles.insert( CheckOn, "checkOn" ); - setRoleNames(roles); - } - - virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const - { - if ( role == CheckOn ) - return (index.data(Qt::CheckStateRole) == Qt::Checked); - return CheckableItemProxyModel::data(index, role); - } - -}; - -class KBreadcrumbNavigationFactoryPrivate -{ - KBreadcrumbNavigationFactoryPrivate(KBreadcrumbNavigationFactory *qq) - : q_ptr(qq), - m_breadcrumbSelectionModel(0), - m_selectionModel(0), - m_childItemsSelectionModel(0), - m_breadcrumbModel(0), - m_selectedItemModel(0), - m_unfilteredChildItemsModel(0), - m_childItemsModel(0), - m_breadcrumbDepth(-1), - m_modelIndexProxyMapper(0), - m_checkModel(0), - m_qmlBreadcrumbSelectionModel(0), - m_qmlSelectedItemSelectionModel(0), - m_qmlChildSelectionModel(0), - m_qmlBreadcrumbCheckModel(0), - m_qmlSelectedItemCheckModel(0), - m_qmlChildCheckModel(0), - m_checkedItemsModel(0), - m_checkedItemsCheckModel(0), - m_qmlCheckedItemsCheckModel(0) - - { - - } - Q_DECLARE_PUBLIC(KBreadcrumbNavigationFactory) - KBreadcrumbNavigationFactory * const q_ptr; - - QItemSelectionModel *m_breadcrumbSelectionModel; - QItemSelectionModel *m_selectionModel; - QItemSelectionModel *m_childItemsSelectionModel; - - QMLListSelectionModel *m_qmlBreadcrumbSelectionModel; - QMLListSelectionModel *m_qmlSelectedItemSelectionModel; - QMLListSelectionModel *m_qmlChildSelectionModel; - - QAbstractItemModel *m_breadcrumbModel; - QAbstractItemModel *m_selectedItemModel; - QAbstractItemModel *m_unfilteredChildItemsModel; - QAbstractItemModel *m_childItemsModel; - int m_breadcrumbDepth; - KModelIndexProxyMapper *m_modelIndexProxyMapper; - - QItemSelectionModel *m_checkModel; - - QMLListSelectionModel *m_qmlBreadcrumbCheckModel; - QMLListSelectionModel *m_qmlSelectedItemCheckModel; - QMLListSelectionModel *m_qmlChildCheckModel; - - KSelectionProxyModel *m_checkedItemsModel; - QItemSelectionModel *m_checkedItemsCheckModel; - QMLListSelectionModel *m_qmlCheckedItemsCheckModel; - -}; - -KBreadcrumbNavigationFactory::KBreadcrumbNavigationFactory(QObject* parent) - : QObject(parent), d_ptr(new KBreadcrumbNavigationFactoryPrivate(this)) -{ - -} - -void KBreadcrumbNavigationFactory::createCheckableBreadcrumbContext(QAbstractItemModel* model, QObject* parent) -{ - Q_D(KBreadcrumbNavigationFactory); - - d->m_checkModel = new QItemSelectionModel( model, parent); - - QMLCheckableItemProxyModel *checkableProxy = new QMLCheckableItemProxyModel(this); - checkableProxy->setSourceModel( model ); - checkableProxy->setSelectionModel( d->m_checkModel ); - - createBreadcrumbContext(checkableProxy, parent); - - KLinkItemSelectionModel *breadcrumbLinkSelectionModel = new KLinkItemSelectionModel( d->m_breadcrumbModel, d->m_checkModel, parent); - KLinkItemSelectionModel *childLinkSelectionModel = new KLinkItemSelectionModel(d->m_childItemsModel, d->m_checkModel, parent); - KLinkItemSelectionModel *selectedItemLinkSelectionModel = new KLinkItemSelectionModel( d->m_selectedItemModel, d->m_checkModel, parent); - - d->m_qmlBreadcrumbCheckModel = new QMLListSelectionModel( breadcrumbLinkSelectionModel, parent); - d->m_qmlSelectedItemCheckModel = new QMLListSelectionModel( selectedItemLinkSelectionModel, parent); - d->m_qmlChildCheckModel = new QMLListSelectionModel( childLinkSelectionModel, parent); - - d->m_checkedItemsModel = new KSelectionProxyModel( d->m_checkModel, parent ); - d->m_checkedItemsModel->setFilterBehavior( KSelectionProxyModel::ExactSelection ); - d->m_checkedItemsModel->setSourceModel( checkableProxy ); - - d->m_checkedItemsCheckModel = new KLinkItemSelectionModel( d->m_checkedItemsModel, d->m_checkModel, parent); - - d->m_qmlCheckedItemsCheckModel = new QMLListSelectionModel( d->m_checkedItemsCheckModel, parent); - -} - -void KBreadcrumbNavigationFactory::createBreadcrumbContext(QAbstractItemModel *model, QObject* parent) -{ - Q_D(KBreadcrumbNavigationFactory); - - d->m_selectionModel = new QItemSelectionModel( model, parent ); - - KSelectionProxyModel *currentCollectionSelectionModel = new KSelectionProxyModel( d->m_selectionModel, parent ); - currentCollectionSelectionModel->setFilterBehavior( KSelectionProxyModel::ExactSelection ); - currentCollectionSelectionModel->setSourceModel( model ); - d->m_selectedItemModel = currentCollectionSelectionModel; - - KBreadcrumbSelectionModel *breadcrumbCollectionSelection - = new KBreadcrumbSelectionModel( d->m_selectionModel, KBreadcrumbSelectionModel::MakeBreadcrumbSelectionInOther, parent ); - breadcrumbCollectionSelection->setActualSelectionIncluded(false); - breadcrumbCollectionSelection->setBreadcrumbLength( d->m_breadcrumbDepth ); - - KBreadcrumbNavigationProxyModel *breadcrumbNavigationModel - = new KBreadcrumbNavigationProxyModel( breadcrumbCollectionSelection, parent ); - breadcrumbNavigationModel->setSourceModel( model ); - breadcrumbNavigationModel->setFilterBehavior( KSelectionProxyModel::ExactSelection ); - d->m_breadcrumbModel = getBreadcrumbNavigationModel(breadcrumbNavigationModel); - - KLinkItemSelectionModel *proxyBreadcrumbCollectionSelection - = new KLinkItemSelectionModel( d->m_breadcrumbModel, d->m_selectionModel, parent ); - - d->m_breadcrumbSelectionModel = new KForwardingItemSelectionModel( d->m_breadcrumbModel, - proxyBreadcrumbCollectionSelection, - KForwardingItemSelectionModel::Reverse, - parent ); - - // Breadcrumbs done. (phew!) - - KForwardingItemSelectionModel *oneway = new KForwardingItemSelectionModel( model, d->m_selectionModel, parent ); - - KNavigatingProxyModel *navigatingProxyModel = new KNavigatingProxyModel( oneway, parent ); - navigatingProxyModel->setSourceModel( model ); - d->m_unfilteredChildItemsModel = navigatingProxyModel; - - d->m_childItemsModel = getChildItemsModel(d->m_unfilteredChildItemsModel); - - d->m_childItemsSelectionModel = new KLinkItemSelectionModel( d->m_childItemsModel, d->m_selectionModel, parent ); - - d->m_modelIndexProxyMapper = new KModelIndexProxyMapper(model, d->m_childItemsModel, parent); - - // Navigation stuff for QML: - - d->m_qmlBreadcrumbSelectionModel = new QMLListSelectionModel( d->m_breadcrumbSelectionModel, parent ); - d->m_qmlSelectedItemSelectionModel = new QMLListSelectionModel( d->m_selectionModel, parent ); - d->m_qmlChildSelectionModel = new QMLListSelectionModel( d->m_childItemsSelectionModel, parent ); -} - -QItemSelectionModel* KBreadcrumbNavigationFactory::selectionModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_selectionModel; -} - -QAbstractItemModel* KBreadcrumbNavigationFactory::selectedItemModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_selectedItemModel; -} - -int KBreadcrumbNavigationFactory::breadcrumbDepth() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_breadcrumbDepth; -} - -void KBreadcrumbNavigationFactory::setBreadcrumbDepth(int depth) -{ - Q_D(KBreadcrumbNavigationFactory); - d->m_breadcrumbDepth = depth; -} - -QAbstractItemModel* KBreadcrumbNavigationFactory::breadcrumbItemModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_breadcrumbModel; -} - -QItemSelectionModel* KBreadcrumbNavigationFactory::breadcrumbSelectionModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_breadcrumbSelectionModel; -} - -QAbstractItemModel* KBreadcrumbNavigationFactory::childItemModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_childItemsModel; -} - -QAbstractItemModel* KBreadcrumbNavigationFactory::unfilteredChildItemModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_unfilteredChildItemsModel; -} - -QAbstractItemModel* KBreadcrumbNavigationFactory::getBreadcrumbNavigationModel(QAbstractItemModel* model) -{ - return model; -} - -QAbstractItemModel* KBreadcrumbNavigationFactory::getChildItemsModel(QAbstractItemModel* model) -{ - return model; -} - -QItemSelectionModel* KBreadcrumbNavigationFactory::childSelectionModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_childItemsSelectionModel; -} - -void KBreadcrumbNavigationFactory::selectBreadcrumb(int row) -{ - Q_D(KBreadcrumbNavigationFactory); - if ( row < 0 ) - { - d->m_selectionModel->clearSelection(); - return; - } - QModelIndex index = d->m_breadcrumbModel->index( row, 0 ); - d->m_breadcrumbSelectionModel->select( QItemSelection(index, index), QItemSelectionModel::Rows | QItemSelectionModel::ClearAndSelect ); -} - -void KBreadcrumbNavigationFactory::selectChild(int row) -{ - Q_D(KBreadcrumbNavigationFactory); - if ( row < 0 ) - { - d->m_selectionModel->clearSelection(); - return; - } - const QModelIndex index = d->m_childItemsModel->index( row, 0 ); - d->m_childItemsSelectionModel->select( QItemSelection(index, index), QItemSelectionModel::Rows | QItemSelectionModel::ClearAndSelect ); -} - -bool KBreadcrumbNavigationFactory::childCollectionHasChildren(int row) -{ - if ( row < 0 ) - return false; - - Q_D(KBreadcrumbNavigationFactory); - - static const int column = 0; - const QModelIndex idx = d->m_modelIndexProxyMapper->mapRightToLeft(d->m_childItemsModel->index(row, column)); - if (!idx.isValid()) - return false; - - return idx.model()->rowCount( idx ) > 0; -} - -QObject* KBreadcrumbNavigationFactory::qmlBreadcrumbSelectionModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_qmlBreadcrumbSelectionModel; -} - -QObject* KBreadcrumbNavigationFactory::qmlBreadcrumbsModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_breadcrumbModel; -} - -QObject* KBreadcrumbNavigationFactory::qmlChildItemsModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_childItemsModel; -} - -QObject* KBreadcrumbNavigationFactory::qmlChildSelectionModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_qmlChildSelectionModel; -} - -QObject* KBreadcrumbNavigationFactory::qmlSelectedItemModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_selectedItemModel; -} - -QObject* KBreadcrumbNavigationFactory::qmlSelectionModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_qmlSelectedItemSelectionModel; -} - -QObject* KBreadcrumbNavigationFactory::qmlBreadcrumbCheckModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_qmlBreadcrumbCheckModel; -} - -QObject* KBreadcrumbNavigationFactory::qmlChildCheckModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_qmlChildCheckModel; -} - -QObject* KBreadcrumbNavigationFactory::qmlSelectedItemCheckModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_qmlSelectedItemCheckModel; -} - -QItemSelectionModel* KBreadcrumbNavigationFactory::checkedItemsCheckModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_checkedItemsCheckModel; -} - -QAbstractItemModel* KBreadcrumbNavigationFactory::checkedItemsModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_checkedItemsModel; -} - -QItemSelectionModel* KBreadcrumbNavigationFactory::checkModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_checkModel; -} - -QObject* KBreadcrumbNavigationFactory::qmlCheckedItemsCheckModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_qmlCheckedItemsCheckModel; -} - -QObject* KBreadcrumbNavigationFactory::qmlCheckedItemsModel() const -{ - Q_D(const KBreadcrumbNavigationFactory); - return d->m_checkedItemsModel; -} - - - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigationcontext.h kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigationcontext.h --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigationcontext.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigationcontext.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 BREADCRUMBNAVIGATIONFACTORY_H -#define BREADCRUMBNAVIGATIONFACTORY_H - -#include - -class QAbstractItemModel; -class QItemSelectionModel; -class QDeclarativeContext; - - -class KBreadcrumbNavigationFactoryPrivate; - -class KBreadcrumbNavigationFactory : public QObject -{ - Q_OBJECT -public: - KBreadcrumbNavigationFactory(QObject* parent = 0); - - void createBreadcrumbContext(QAbstractItemModel *model, QObject* parent = 0); - void createCheckableBreadcrumbContext(QAbstractItemModel *model, QObject* parent = 0); - - void setBreadcrumbDepth(int depth); - int breadcrumbDepth() const; - - QItemSelectionModel *breadcrumbSelectionModel() const; - QItemSelectionModel *selectionModel() const; - QItemSelectionModel *childSelectionModel() const; - - QAbstractItemModel *breadcrumbItemModel() const; - QAbstractItemModel *selectedItemModel() const; - QAbstractItemModel *unfilteredChildItemModel() const; - QAbstractItemModel *childItemModel() const; - - QItemSelectionModel *checkModel() const; - QAbstractItemModel *checkedItemsModel() const; - QItemSelectionModel *checkedItemsCheckModel() const; - -public slots: - QObject* qmlBreadcrumbSelectionModel() const; - QObject* qmlSelectionModel() const; - QObject* qmlChildSelectionModel() const; - - QObject* qmlBreadcrumbCheckModel() const; - QObject* qmlSelectedItemCheckModel() const; - QObject* qmlChildCheckModel() const; - QObject* qmlCheckedItemsModel() const; - QObject* qmlCheckedItemsCheckModel() const; - - QObject* qmlBreadcrumbsModel() const; - QObject* qmlSelectedItemModel() const; - QObject* qmlChildItemsModel() const; - - void selectBreadcrumb( int row ); - void selectChild( int row ); - - bool childCollectionHasChildren( int row ); - -protected: - virtual QAbstractItemModel* getBreadcrumbNavigationModel(QAbstractItemModel *model); - virtual QAbstractItemModel* getChildItemsModel(QAbstractItemModel *model); - -private: - Q_DECLARE_PRIVATE(KBreadcrumbNavigationFactory) - KBreadcrumbNavigationFactoryPrivate * const d_ptr; - -}; - -#endif diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigation.cpp kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigation.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigation.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigation.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,185 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 "breadcrumbnavigation.h" - -#include - -KBreadcrumbNavigationProxyModel::KBreadcrumbNavigationProxyModel(QItemSelectionModel* selectionModel, QObject* parent) - : KSelectionProxyModel(selectionModel, parent) -{ - -} - -QVariant KBreadcrumbNavigationProxyModel::data(const QModelIndex& index, int role) const -{ - if (rowCount() > 2 && index.row() == 0 && role == Qt::DisplayRole) - { - QModelIndex sourceIndex = mapToSource(index); - QStringList dataList; - while (sourceIndex.isValid()) - { - dataList.prepend(sourceIndex.data().toString()); - sourceIndex = sourceIndex.parent(); - } - return dataList.join(" > "); - } - return KSelectionProxyModel::data(index, role); -} - -void KBreadcrumbNavigationProxyModel::setShowHiddenAscendantData(bool showHiddenAscendantData) -{ - m_showHiddenAscendantData = showHiddenAscendantData; -} - -bool KBreadcrumbNavigationProxyModel::showHiddenAscendantData() const -{ - return m_showHiddenAscendantData; -} - -KNavigatingProxyModel::KNavigatingProxyModel(KForwardingItemSelectionModel* selectionModel, QObject* parent) - : KSelectionProxyModel(selectionModel, parent), m_selectionModel(selectionModel) -{ -} - -void KNavigatingProxyModel::silentSelect(const QItemSelection& selection, QItemSelectionModel::SelectionFlags command) -{ - disconnect( m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), - this, SLOT(navigationSelectionChanged(QItemSelection,QItemSelection)) ); - m_selectionModel->select( selection, command); - connect( m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), - SLOT(navigationSelectionChanged(QItemSelection,QItemSelection)) ); -} - -void KNavigatingProxyModel::setSourceModel(QAbstractItemModel* sourceModel) -{ - connect( m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), - SLOT(navigationSelectionChanged(QItemSelection,QItemSelection)) ); - connect( m_selectionModel, SIGNAL(resetNavigation()), SLOT(updateNavigation()) ); - - disconnect(sourceModel, SIGNAL(modelReset()), this, SLOT(updateNavigation())); - disconnect(sourceModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(_sourceRowsInserted(QModelIndex,int,int))); - disconnect(sourceModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(_sourceRowsRemoved(QModelIndex,int,int))); - - KSelectionProxyModel::setSourceModel(sourceModel); - updateNavigation(); - - connect(sourceModel, SIGNAL(modelReset()), SLOT(updateNavigation())); - connect(sourceModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(_sourceRowsInserted(QModelIndex,int,int))); - connect(sourceModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SLOT(_sourceRowsRemoved(QModelIndex,int,int))); -} - -void KNavigatingProxyModel::_sourceRowsInserted(const QModelIndex& parent, int start, int end) -{ - if (filterBehavior() != ExactSelection || parent.isValid()) - return; - QItemSelection sel( sourceModel()->index(start, 0, parent), - sourceModel()->index(end, sourceModel()->columnCount(parent) - 1, parent)); - - silentSelect(sel, QItemSelectionModel::Select); -} - -void KNavigatingProxyModel::_sourceRowsRemoved(const QModelIndex& parent, int start, int end) -{ - if (filterBehavior() != ExactSelection || parent.isValid()) - return; - - m_selectionModel->select(QItemSelection( sourceModel()->index(start, 0, parent), - sourceModel()->index(end, sourceModel()->columnCount(parent), parent)), QItemSelectionModel::Deselect); - - if ( m_selectionModel->selection().isEmpty() ) - updateNavigation(); -} - -void KNavigatingProxyModel::navigationSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected) -{ - updateNavigation(); -} - -void KNavigatingProxyModel::updateNavigation() -{ - beginResetModel(); - if (!sourceModel()) - { - setFilterBehavior(KSelectionProxyModel::ChildrenOfExactSelection); - endResetModel(); - return; - } - - if (m_selectionModel->selection().isEmpty()) - { - setFilterBehavior(KSelectionProxyModel::ExactSelection); - QModelIndex top = sourceModel()->index(0, 0); - QModelIndex bottom = sourceModel()->index(sourceModel()->rowCount() - 1, 0); - silentSelect(QItemSelection(top, bottom), QItemSelectionModel::Select); - } else if (filterBehavior() != KSelectionProxyModel::ChildrenOfExactSelection) { - setFilterBehavior(KSelectionProxyModel::ChildrenOfExactSelection); - } - endResetModel(); -} - -KForwardingItemSelectionModel::KForwardingItemSelectionModel(QAbstractItemModel* model, QItemSelectionModel* selectionModel, QObject *parent) - : QItemSelectionModel(model, parent), m_selectionModel(selectionModel), m_direction(Forward) -{ - Q_ASSERT(model == selectionModel->model()); - connect(selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), - SLOT(navigationSelectionChanged(QItemSelection,QItemSelection))); -} - -KForwardingItemSelectionModel::KForwardingItemSelectionModel(QAbstractItemModel* model, QItemSelectionModel* selectionModel, Direction direction, QObject *parent) - : QItemSelectionModel(model, parent), m_selectionModel(selectionModel), m_direction(direction) -{ - Q_ASSERT(model == selectionModel->model()); - if (m_direction == Forward) - connect(selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), - SLOT(navigationSelectionChanged(QItemSelection,QItemSelection))); -} - -void KForwardingItemSelectionModel::select(const QModelIndex& index, QItemSelectionModel::SelectionFlags command) -{ - if (m_direction == Reverse) - m_selectionModel->select(index, command); - else - QItemSelectionModel::select(index, command); -} - -void KForwardingItemSelectionModel::select(const QItemSelection& selection, QItemSelectionModel::SelectionFlags command) -{ - if (m_direction == Reverse) - m_selectionModel->select(selection, command); - else - QItemSelectionModel::select(selection, command); -} - -void KForwardingItemSelectionModel::navigationSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected) -{ - // ### The KNavigatingProxyModel selects all top level items if there is 'no selection'. - // This slot is called when we newly get a selection, so we can unselect all. - if (selectedRows().size() == model()->rowCount()) - select(selected, ClearAndSelect); - else - select(selected, Select); - - select(deselected, Deselect); - if (selected == selection()) - resetNavigation(); -} - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigation.h kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigation.h --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigation.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/breadcrumbnavigation.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 BREADCRUMBNAVIGATION_H -#define BREADCRUMBNAVIGATION_H - -#include - -#include "kselectionproxymodel.h" - -// Copied from kdeui/tests/proxymodeltestapp/breadcrumbnavigationwidget -// A version of these might be somewhere stable in the future. - -class KBreadcrumbNavigationProxyModel : public KSelectionProxyModel -{ - Q_OBJECT -public: - KBreadcrumbNavigationProxyModel(QItemSelectionModel* selectionModel, QObject* parent = 0); - - void setShowHiddenAscendantData(bool showHiddenAscendantData); - bool showHiddenAscendantData() const; - - virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; - -private: - bool m_showHiddenAscendantData; - -}; - -class KForwardingItemSelectionModel; - -class KNavigatingProxyModel : public KSelectionProxyModel -{ - Q_OBJECT -public: - KNavigatingProxyModel(KForwardingItemSelectionModel* selectionModel, QObject* parent = 0); - - virtual void setSourceModel(QAbstractItemModel* sourceModel); - -private slots: - void updateNavigation(); - void navigationSelectionChanged( const QItemSelection &, const QItemSelection & ); - void _sourceRowsInserted( const QModelIndex &parent, int start, int end ); - void _sourceRowsRemoved( const QModelIndex &parent, int start, int end ); - -private: - void silentSelect(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command); - -private: - using KSelectionProxyModel::setFilterBehavior; - - KForwardingItemSelectionModel *m_selectionModel; - -}; - -class KForwardingItemSelectionModel : public QItemSelectionModel -{ - Q_OBJECT -public: - enum Direction - { - Forward, - Reverse - }; - KForwardingItemSelectionModel(QAbstractItemModel* model, QItemSelectionModel *selectionModel, QObject *parent = 0); - KForwardingItemSelectionModel(QAbstractItemModel* model, QItemSelectionModel *selectionModel, Direction direction, QObject *parent = 0); - - virtual void select(const QModelIndex& index, SelectionFlags command); - virtual void select(const QItemSelection& selection, SelectionFlags command); - -signals: - void resetNavigation(); - -private slots: - void navigationSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); - -private: - QItemSelectionModel *m_selectionModel; - Direction m_direction; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/BreadcrumbNavigationView.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,553 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Item { - id: breadcrumbTopLevel - clip : true - - property variant breadcrumbComponentFactory - - property alias topDelegate : topButton.delegate - property alias breadcrumbDelegate : breadcrumbsView.delegate - property alias selectedItemDelegate : selectedItemView.delegate - property alias childItemsDelegate : childItemsView.delegate - property alias multipleSelectionText : multipleSelectionMessage.text - - property int itemHeight : height / 7 - property int _transitionSelect : -1 - - property bool hasChildren : childItemsView.count > 0 - property bool hasSelection : selectedItemView.count > 0 - property bool hasBreadcrumbs : breadcrumbsView.count > 0 - - property alias numBreadcrumbs : breadcrumbsView.count - property alias numSelected : selectedItemView.count - - property variant breadcrumbSelectionModel : breadcrumbComponentFactory.qmlBreadcrumbSelectionModel(); - property variant selectedItemSelectionModel : breadcrumbComponentFactory.qmlSelectionModel(); - property variant childSelectionModel : breadcrumbComponentFactory.qmlChildSelectionModel(); - - signal childCollectionSelected(int row) - signal breadcrumbCollectionSelected(int row) - - SystemPalette { id: palette; colorGroup: "Active" } - ListModel { - id : topModel - ListElement { display : "Home" } - } - - ListView { - id : topButton - interactive : false - height : itemHeight - - anchors.top : parent.top - - anchors.left : parent.left - anchors.right : parent.right - model : topModel - - Image { - id : topRightDivider - source : "dividing-line.png" - anchors.top : parent.top - anchors.right : parent.right - anchors.bottom : parent.bottom - anchors.bottomMargin : breadcrumbTopLevel.hasBreadcrumbs ? 0 : 8 - fillMode : Image.TileVertically - opacity : breadcrumbTopLevel.hasSelection ? 1 : 0 - } - } - - ListView { - id : breadcrumbsView - model : breadcrumbComponentFactory.qmlBreadcrumbsModel(); - interactive : false - height : breadcrumbsView.count > 0 ? itemHeight : 0 - - clip : true; - property int selectedIndex : -1 - anchors.top : topButton.bottom - anchors.left : parent.left - anchors.right : parent.right - highlightFollowsCurrentItem : true - highlightRangeMode : ListView.StrictlyEnforceRange - preferredHighlightBegin : 0 - preferredHighlightEnd : height - onCountChanged : { - positionViewAtIndex(count - 1, ListView.Beginning) - } - Component.onCompleted : { - positionViewAtIndex(count - 1, ListView.Beginning) - } - } - - Item { - id : breadcrumbPlaceHolder - height : breadcrumbTopLevel.hasBreadcrumbs ? itemHeight : 0 - anchors.top : topButton.bottom - anchors.left : parent.left - anchors.right : parent.right - } - Image { - id : breadcrumbRightDivider - source : "dividing-line.png" - anchors.top : breadcrumbPlaceHolder.top - anchors.right : breadcrumbPlaceHolder.right - height : breadcrumbTopLevel.hasBreadcrumbs ? (itemHeight -8) : 0 - fillMode : Image.TileVertically - opacity : breadcrumbTopLevel.hasBreadcrumbs ? 1 : 0 - } - - ListView { - id : selectedItemView - interactive : false - - model : breadcrumbComponentFactory.qmlSelectedItemModel(); - height : itemHeight * selectedItemView.count - anchors.top : breadcrumbsView.bottom - anchors.left : parent.left - anchors.right : parent.right - - onCountChanged : { - if (selectedItemView.count > 1) - { - breadcrumbsView.visible = false; - breadcrumbPlaceHolder.visible = false; - selectedItemView.visible = false; - selectedItemPlaceHolder.visible = false; - childItemsView.visible = false; - favinfoOverlay.visible = true; - } - else - { - breadcrumbsView.visible = true; - breadcrumbPlaceHolder.visible = true; - selectedItemView.visible = true; - selectedItemPlaceHolder.visible = true; - childItemsView.visible = true; - favinfoOverlay.visible = false; - } - } - } - - Item { - id : selectedItemPlaceHolder - height : selectedItemView.count > 0 ? itemHeight : 0 - anchors.top : breadcrumbPlaceHolder.bottom - anchors.left : parent.left - anchors.right : parent.right - Item { - id : selectedPlaceHolderImages - anchors.fill : parent - opacity : (selectedItemView.count > 0) ? 1 : 0 - Image { - source : "dividing-line-horizontal.png" - fillMode : Image.TileHorizontally - anchors.top : parent.top - anchors.topMargin : -3 - anchors.right : topLine.left - anchors.left : parent.left - } - Image { - id : topLine - source : "list-line-top.png" - anchors.right : parent.right - anchors.top : parent.top - anchors.topMargin : -8 - } - } - } - - ListView { - id : childItemsView - model : breadcrumbComponentFactory.qmlChildItemsModel(); - property bool shouldBeFlickable - - clip : true - anchors.top : selectedItemPlaceHolder.bottom - anchors.bottom : breadcrumbTopLevel.bottom - anchors.left : parent.left - anchors.right : parent.right - - shouldBeFlickable : childItemsView.height < (itemHeight * childItemsView.count) - interactive : shouldBeFlickable - } - - Item { - id : childItemsViewPlaceHolder - anchors.top : selectedItemPlaceHolder.bottom - anchors.bottom : breadcrumbTopLevel.bottom - anchors.left : parent.left - anchors.right : parent.right - - - Image { - source : "dividing-line-horizontal.png" - fillMode : Image.TileHorizontally - anchors.right : parent.right - anchors.left : parent.left - anchors.top : parent.top - } - - Image { - source : "dividing-line.png" - anchors.top : parent.top - anchors.right : parent.right - anchors.bottom : parent.bottom - fillMode : Image.TileVertically - } - Image { - source : "scrollable-top.png" - anchors.top : parent.top - anchors.right : parent.right - anchors.left : parent.left - fillMode : Image.TileHorizontally - opacity : childItemsView.shouldBeFlickable ? 1 : 0 - } - Image { - source : "scrollable-bottom.png" - anchors.bottom : parent.bottom - anchors.right : parent.right - anchors.left : parent.left - fillMode : Image.TileHorizontally - opacity : childItemsView.shouldBeFlickable ? 1 : 0 - } - } - - Item { - id : favinfoOverlay - anchors.top : topButton.bottom - anchors.bottom : parent.bottom - anchors.left : parent.left - anchors.right : parent.right - visible : false - - Text { - id : multipleSelectionMessage - font.italic : true - horizontalAlignment : Text.AlignHCenter - anchors.horizontalCenter : parent.horizontalCenter - - height : 30 - x : 20 - y : 50 - } - - Image { - source : "dividing-line-horizontal.png" - fillMode : Image.TileHorizontally - anchors.top : parent.top - anchors.right : parent.right - anchors.left : parent.left - } - - Image { - source : "dividing-line.png" - fillMode : Image.TileVertically - anchors.top : parent.top - anchors.right : parent.right - anchors.bottom : parent.bottom - } - - } - - function completeHomeSelection() { - selectedItemSelectionModel.clearSelection(); - // TODO: Remove: - breadcrumbCollectionSelected(breadcrumbTopLevel._transitionSelect); - breadcrumbTopLevel._transitionSelect = -1; - breadcrumbTopLevel.state = "after_select_breadcrumb"; - breadcrumbTopLevel.state = ""; - } - - function completeChildSelection() { - childSelectionModel.select(breadcrumbTopLevel._transitionSelect, 3) - // TODO: Remove: - childCollectionSelected(breadcrumbTopLevel._transitionSelect); - breadcrumbTopLevel._transitionSelect = -1; - breadcrumbTopLevel.state = "after_select_child"; - breadcrumbTopLevel.state = ""; - } - - function completeBreadcrumbSelection() { - breadcrumbSelectionModel.select(breadcrumbTopLevel._transitionSelect, 3) - // TODO: Remove: - breadcrumbCollectionSelected(breadcrumbTopLevel._transitionSelect); - breadcrumbTopLevel._transitionSelect = -1; - breadcrumbTopLevel.state = "after_select_breadcrumb"; - breadcrumbTopLevel.state = ""; - } - - states : [ - State { - name : "before_select_home" - PropertyChanges { - target : breadcrumbsView - opacity : 0 - height : 0 - } - PropertyChanges { - target : breadcrumbPlaceHolder - opacity : 0 - height : 0 - } - PropertyChanges { - target : selectedItemView - opacity : 0 - height : 0 - } - PropertyChanges { - target : selectedItemPlaceHolder - opacity : 0 - height : 0 - } - PropertyChanges { - target : childItemsView - opacity : 0 - } - }, - State { - name : "before_select_child" - PropertyChanges { - target : topRightDivider - anchors.bottomMargin : 0 - opacity : 1 - } - PropertyChanges { - target : breadcrumbsView - height : itemHeight - anchors.topMargin : -itemHeight - opacity : 0 - } - PropertyChanges { - target : breadcrumbRightDivider - anchors.topMargin : -8 - height : {console.log(itemHeight); 67} - opacity : 0 // { 1 } // selectedItemView.count > 0 ? 1 : 0 - } - PropertyChanges { - target : selectedItemPlaceHolder - anchors.topMargin : (breadcrumbsView.count == 0 && selectedItemView.count > 0) ? (itemHeight) : (breadcrumbsView.count == 0) ? 8 : 0 - height : itemHeight - opacity : 1 - } - - PropertyChanges { - target : selectedPlaceHolderImages - opacity : 1 - } - PropertyChanges { - target : childItemsView - opacity : 0 - } - }, - State { - name : "after_select_child" - PropertyChanges { - target : childItemsView - opacity : 0 - } - }, - State { - name : "before_select_breadcrumb" - PropertyChanges { - target : breadcrumbsView - height : { if (breadcrumbTopLevel._transitionSelect >= 0) itemHeight * ( breadcrumbTopLevel._transitionSelect + 1 ) } - anchors.bottomMargin : -itemHeight - opacity : 0.5 - } - PropertyChanges { - target : selectedItemView - anchors.topMargin : (application.selectedCollectionRow() + breadcrumbsView.count) * itemHeight; - opacity : 0 - } - PropertyChanges { - target : childItemsView - opacity : 0 - } - }, - State { - name : "after_select_breadcrumb" - PropertyChanges { - target : breadcrumbsView - contentY : breadcrumbsView.count > 1 ? itemHeight : 0 - } - PropertyChanges { - target : childItemsView - opacity : 0 - } - } - ] - - transitions : [ - Transition { - from : "*" - to : "before_select_home" - SequentialAnimation { - ParallelAnimation { - PropertyAnimation { - target : breadcrumbPlaceHolder - duration: 500 - easing.type: "OutQuad" - properties : "opacity,height" - } - PropertyAnimation { - target : breadcrumbsView - duration: 500 - easing.type: "OutQuad" - properties : "opacity,height" - } - PropertyAnimation { - target : selectedItemView - duration: 500 - easing.type: "OutQuad" - properties : "opacity,height" - } - PropertyAnimation { - target : selectedItemPlaceHolder - duration: 500 - easing.type: "OutQuad" - properties : "opacity,height" - } - PropertyAnimation { - target : childItemsView - duration: 500 - easing.type: "OutQuad" - properties : "height" - } - } - ScriptAction { - script: { completeHomeSelection(); } - } - } - }, - Transition { - from : "*" - to : "before_select_child" - SequentialAnimation { - ParallelAnimation { - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: topRightDivider - properties: "opacity,anchors.bottomMargin" - } - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: breadcrumbsView - properties: "height,anchors.topMargin,opacity" - } - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: breadcrumbRightDivider - properties: "height" - } - PropertyAnimation { - target : selectedItemPlaceHolder - duration: 500 - easing.type: "OutQuad" - properties : "anchors.topMargin,height,opacity" - } - PropertyAnimation { - target : selectedPlaceHolderImages - duration: 500 - easing.type: "OutQuad" - properties : "opacity" - } - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: childItemsView - properties: "opacity" - } - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: childItemsDelegate - properties: "itemBackground" - } - } - ScriptAction { - script: { completeChildSelection(); } - } - } - }, - Transition { - from : "after_select_child" - to : "" - NumberAnimation { - target: childItemsView - properties: "opacity" - } - NumberAnimation { - target: selectedItemView - properties: "opacity" - } - ScriptAction { - script : {console.log("### " + selectedItemView.count + " " + selectedItemView.currentIndex); } - } - }, - Transition { - from : "*" - to : "before_select_breadcrumb" - SequentialAnimation { - ParallelAnimation { - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: breadcrumbsView - properties: "height,opacity" - } - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: selectedItemView - properties: "opacity,anchors.topMargin" - } - PropertyAnimation { - duration: 500 - easing.type: "OutQuad" - target: childItemsView - properties: "opacity" - } - } - ScriptAction { - script: { completeBreadcrumbSelection(); } - } - } - }, - Transition { - from : "after_select_breadcrumb" - to : "" - NumberAnimation { - duration: 500 - easing.type: "OutQuad" - target: childItemsView - properties: "opacity" - } - } - ] -} diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/checkableitemproxymodel.cpp kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/checkableitemproxymodel.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/checkableitemproxymodel.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/checkableitemproxymodel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,122 +0,0 @@ -/* - This file is part of KDE. - - Copyright (c) 2010 Stephen Kelly - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. -*/ - - -#include "checkableitemproxymodel.h" - -#include -#include - -class CheckableItemProxyModelPrivate -{ - Q_DECLARE_PUBLIC(CheckableItemProxyModel) - CheckableItemProxyModel *q_ptr; - - CheckableItemProxyModelPrivate(CheckableItemProxyModel *checkableModel) - : q_ptr(checkableModel), - m_itemSelectionModel(0) - { - - } - - QItemSelectionModel *m_itemSelectionModel; - - void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); - -}; - -CheckableItemProxyModel::CheckableItemProxyModel(QObject* parent) - : QSortFilterProxyModel(parent), d_ptr(new CheckableItemProxyModelPrivate(this)) -{ - -} - -void CheckableItemProxyModel::setSelectionModel(QItemSelectionModel* itemSelectionModel) -{ - Q_D(CheckableItemProxyModel); - d->m_itemSelectionModel = itemSelectionModel; - Q_ASSERT(sourceModel() ? d->m_itemSelectionModel->model() == sourceModel() : true); - connect(itemSelectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(selectionChanged(QItemSelection,QItemSelection))); -} - -Qt::ItemFlags CheckableItemProxyModel::flags(const QModelIndex& index) const -{ - return QSortFilterProxyModel::flags(index) | Qt::ItemIsUserCheckable; -} - -QVariant CheckableItemProxyModel::data(const QModelIndex& index, int role) const -{ - Q_D(const CheckableItemProxyModel); - - if (role == Qt::CheckStateRole) - { - if (!d->m_itemSelectionModel) - return Qt::Unchecked; - - return d->m_itemSelectionModel->selection().contains(mapToSource(index)) ? Qt::Checked : Qt::Unchecked; - } - return QSortFilterProxyModel::data(index, role); -} - -bool CheckableItemProxyModel::setData(const QModelIndex& index, const QVariant& value, int role) -{ - Q_D(CheckableItemProxyModel); - if (role == Qt::CheckStateRole) - { - if (!d->m_itemSelectionModel) - return false; - - Qt::CheckState state = static_cast(value.toInt()); - const QModelIndex srcIndex = mapToSource(index); - bool result = select(QItemSelection(srcIndex, srcIndex), state == Qt::Checked ? QItemSelectionModel::Select : QItemSelectionModel::Deselect); - qDebug() << "DC"; - emit dataChanged(srcIndex, srcIndex); - return result; - } - return QSortFilterProxyModel::setData(index, value, role); -} - -void CheckableItemProxyModel::setSourceModel(QAbstractItemModel* sourceModel) -{ - QSortFilterProxyModel::setSourceModel(sourceModel); - Q_ASSERT(d_ptr->m_itemSelectionModel ? d_ptr->m_itemSelectionModel->model() == sourceModel : true); -} - -void CheckableItemProxyModelPrivate::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) -{ - qDebug()<< "SEL CH" << selected << deselected; - Q_Q(CheckableItemProxyModel); - foreach (const QItemSelectionRange &range, q->mapSelectionFromSource(selected)) - q->dataChanged(range.topLeft(), range.bottomRight()); - foreach (const QItemSelectionRange &range, q->mapSelectionFromSource(deselected)) - q->dataChanged(range.topLeft(), range.bottomRight()); -} - -bool CheckableItemProxyModel::select(const QItemSelection& selection, QItemSelectionModel::SelectionFlags command) -{ - Q_D(CheckableItemProxyModel); - d->m_itemSelectionModel->select(selection, command); - return true; -} - - -#include "moc_checkableitemproxymodel.cpp" - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/checkableitemproxymodel.h kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/checkableitemproxymodel.h --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/checkableitemproxymodel.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/checkableitemproxymodel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -/* - This file is part of Akonadi. - - Copyright (c) 2010 Stephen Kelly - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. -*/ - -#ifndef CHECKABLEITEMPROXYMODEL_H -#define CHECKABLEITEMPROXYMODEL_H - -#include - -#include - -class QItemSelectionModel; - -class CheckableItemProxyModelPrivate; - -class CheckableItemProxyModel : public QSortFilterProxyModel -{ - Q_OBJECT -public: - CheckableItemProxyModel(QObject* parent = 0); - - void setSelectionModel(QItemSelectionModel *itemSelectionModel); - - /* reimp */ Qt::ItemFlags flags(const QModelIndex& index) const; - - /* reimp */ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; - - /* reimp */ bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); - - /* reimp */ void setSourceModel(QAbstractItemModel* sourceModel); - -protected: - virtual bool select( const QItemSelection &selection, QItemSelectionModel::SelectionFlags command ); - -private: - Q_DECLARE_PRIVATE(CheckableItemProxyModel) - CheckableItemProxyModelPrivate * const d_ptr; - - Q_PRIVATE_SLOT(d_func(), void selectionChanged(const QItemSelection &, const QItemSelection &) ) -}; - -#endif - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/cmake/FindQt4.cmake kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/cmake/FindQt4.cmake --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/cmake/FindQt4.cmake 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/cmake/FindQt4.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,1256 +0,0 @@ -# - Find QT 4 -# This module can be used to find Qt4. -# The most important issue is that the Qt4 qmake is available via the system path. -# This qmake is then used to detect basically everything else. -# This module defines a number of key variables and macros. -# The variable QT_USE_FILE is set which is the path to a CMake file that can be included -# to compile Qt 4 applications and libraries. It sets up the compilation -# environment for include directories, preprocessor defines and populates a -# QT_LIBRARIES variable. -# -# Typical usage could be something like: -# find_package(Qt4 4.4.3 COMPONENTS QtCore QtGui QtXml REQUIRED ) -# include(${QT_USE_FILE}) -# add_executable(myexe main.cpp) -# target_link_libraries(myexe ${QT_LIBRARIES}) -# -# The minimum required version can be specified using the standard find_package()-syntax -# (see example above). -# For compatibility with older versions of FindQt4.cmake it is also possible to -# set the variable QT_MIN_VERSION to the minimum required version of Qt4 before the -# find_package(Qt4) command. -# If both are used, the version used in the find_package() command overrides the -# one from QT_MIN_VERSION. -# -# When using the components argument, QT_USE_QT* variables are automatically set -# for the QT_USE_FILE to pick up. If one wishes to manually set them, the -# available ones to set include: -# QT_DONT_USE_QTCORE -# QT_DONT_USE_QTGUI -# QT_USE_QT3SUPPORT -# QT_USE_QTASSISTANT -# QT_USE_QAXCONTAINER -# QT_USE_QAXSERVER -# QT_USE_QTDESIGNER -# QT_USE_QTMOTIF -# QT_USE_QTMAIN -# QT_USE_QTMULTIMEDIA -# QT_USE_QTNETWORK -# QT_USE_QTNSPLUGIN -# QT_USE_QTOPENGL -# QT_USE_QTSQL -# QT_USE_QTXML -# QT_USE_QTSVG -# QT_USE_QTTEST -# QT_USE_QTUITOOLS -# QT_USE_QTDBUS -# QT_USE_QTSCRIPT -# QT_USE_QTASSISTANTCLIENT -# QT_USE_QTHELP -# QT_USE_QTWEBKIT -# QT_USE_QTXMLPATTERNS -# QT_USE_PHONON -# QT_USE_QTSCRIPTTOOLS -# QT_USE_QTDECLARATIVE -# -# QT_USE_IMPORTED_TARGETS -# If this variable is set to TRUE, FindQt4.cmake will create imported -# library targets for the various Qt libraries and set the -# library variables like QT_QTCORE_LIBRARY to point at these imported -# targets instead of the library file on disk. This provides much better -# handling of the release and debug versions of the Qt libraries and is -# also always backwards compatible, except for the case that dependencies -# of libraries are exported, these will then also list the names of the -# imported targets as dependency and not the file location on disk. This -# is much more flexible, but requires that FindQt4.cmake is executed before -# such an exported dependency file is processed. -# -# There are also some files that need processing by some Qt tools such as moc -# and uic. Listed below are macros that may be used to process those files. -# -# macro QT4_WRAP_CPP(outfiles inputfile ... OPTIONS ...) -# create moc code from a list of files containing Qt class with -# the Q_OBJECT declaration. Per-direcotry preprocessor definitions -# are also added. Options may be given to moc, such as those found -# when executing "moc -help". -# -# macro QT4_WRAP_UI(outfiles inputfile ... OPTIONS ...) -# create code from a list of Qt designer ui files. -# Options may be given to uic, such as those found -# when executing "uic -help" -# -# macro QT4_ADD_RESOURCES(outfiles inputfile ... OPTIONS ...) -# create code from a list of Qt resource files. -# Options may be given to rcc, such as those found -# when executing "rcc -help" -# -# macro QT4_GENERATE_MOC(inputfile outputfile ) -# creates a rule to run moc on infile and create outfile. -# Use this if for some reason QT4_WRAP_CPP() isn't appropriate, e.g. -# because you need a custom filename for the moc file or something similar. -# -# macro QT4_AUTOMOC(sourcefile1 sourcefile2 ... ) -# This macro is still experimental. -# It can be used to have moc automatically handled. -# So if you have the files foo.h and foo.cpp, and in foo.h a -# a class uses the Q_OBJECT macro, moc has to run on it. If you don't -# want to use QT4_WRAP_CPP() (which is reliable and mature), you can insert -# #include "foo.moc" -# in foo.cpp and then give foo.cpp as argument to QT4_AUTOMOC(). This will the -# scan all listed files at cmake-time for such included moc files and if it finds -# them cause a rule to be generated to run moc at build time on the -# accompanying header file foo.h. -# If a source file has the SKIP_AUTOMOC property set it will be ignored by this macro. -# -# macro QT4_ADD_DBUS_INTERFACE(outfiles interface basename) -# create a the interface header and implementation files with the -# given basename from the given interface xml file and add it to -# the list of sources. -# To disable generating a namespace header, set the source file property -# NO_NAMESPACE to TRUE on the interface file. -# To include a header in the interface header, set the source file property -# INCLUDE to the name of the header. -# To specify a class name to use, set the source file property CLASSNAME -# to the name of the class. -# -# macro QT4_ADD_DBUS_INTERFACES(outfiles inputfile ... ) -# create the interface header and implementation files -# for all listed interface xml files -# the name will be automatically determined from the name of the xml file -# To disable generating namespace headers, set the source file property -# NO_NAMESPACE to TRUE for these inputfiles. -# To include a header in the interface header, set the source file property -# INCLUDE to the name of the header. -# To specify a class name to use, set the source file property CLASSNAME -# to the name of the class. -# -# macro QT4_ADD_DBUS_ADAPTOR(outfiles xmlfile parentheader parentclassname [basename] [classname]) -# create a dbus adaptor (header and implementation file) from the xml file -# describing the interface, and add it to the list of sources. The adaptor -# forwards the calls to a parent class, defined in parentheader and named -# parentclassname. The name of the generated files will be -# adaptor.{cpp,h} where basename defaults to the basename of the xml file. -# If is provided, then it will be used as the classname of the -# adaptor itself. -# -# macro QT4_GENERATE_DBUS_INTERFACE( header [interfacename] OPTIONS ...) -# generate the xml interface file from the given header. -# If the optional argument interfacename is omitted, the name of the -# interface file is constructed from the basename of the header with -# the suffix .xml appended. -# Options may be given to qdbuscpp2xml, such as those found when executing "qdbuscpp2xml --help" -# -# macro QT4_CREATE_TRANSLATION( qm_files directories ... sources ... -# ts_files ... OPTIONS ...) -# out: qm_files -# in: directories sources ts_files -# options: flags to pass to lupdate, such as -extensions to specify -# extensions for a directory scan. -# generates commands to create .ts (vie lupdate) and .qm -# (via lrelease) - files from directories and/or sources. The ts files are -# created and/or updated in the source tree (unless given with full paths). -# The qm files are generated in the build tree. -# Updating the translations can be done by adding the qm_files -# to the source list of your library/executable, so they are -# always updated, or by adding a custom target to control when -# they get updated/generated. -# -# macro QT4_ADD_TRANSLATION( qm_files ts_files ... ) -# out: qm_files -# in: ts_files -# generates commands to create .qm from .ts - files. The generated -# filenames can be found in qm_files. The ts_files -# must exists and are not updated in any way. -# -# -# Below is a detailed list of variables that FindQt4.cmake sets. -# QT_FOUND If false, don't try to use Qt. -# QT4_FOUND If false, don't try to use Qt 4. -# -# QT_VERSION_MAJOR The major version of Qt found. -# QT_VERSION_MINOR The minor version of Qt found. -# QT_VERSION_PATCH The patch version of Qt found. -# -# QT_EDITION Set to the edition of Qt (i.e. DesktopLight) -# QT_EDITION_DESKTOPLIGHT True if QT_EDITION == DesktopLight -# QT_QTCORE_FOUND True if QtCore was found. -# QT_QTGUI_FOUND True if QtGui was found. -# QT_QT3SUPPORT_FOUND True if Qt3Support was found. -# QT_QTASSISTANT_FOUND True if QtAssistant was found. -# QT_QTASSISTANTCLIENT_FOUND True if QtAssistantClient was found. -# QT_QAXCONTAINER_FOUND True if QAxContainer was found (Windows only). -# QT_QAXSERVER_FOUND True if QAxServer was found (Windows only). -# QT_QTDBUS_FOUND True if QtDBus was found. -# QT_QTDESIGNER_FOUND True if QtDesigner was found. -# QT_QTDESIGNERCOMPONENTS True if QtDesignerComponents was found. -# QT_QTHELP_FOUND True if QtHelp was found. -# QT_QTMOTIF_FOUND True if QtMotif was found. -# QT_QTMULTIMEDIA_FOUND True if QtMultimedia was found (since Qt 4.6.0). -# QT_QTNETWORK_FOUND True if QtNetwork was found. -# QT_QTNSPLUGIN_FOUND True if QtNsPlugin was found. -# QT_QTOPENGL_FOUND True if QtOpenGL was found. -# QT_QTSQL_FOUND True if QtSql was found. -# QT_QTSVG_FOUND True if QtSvg was found. -# QT_QTSCRIPT_FOUND True if QtScript was found. -# QT_QTSCRIPTTOOLS_FOUND True if QtScriptTools was found. -# QT_QTTEST_FOUND True if QtTest was found. -# QT_QTUITOOLS_FOUND True if QtUiTools was found. -# QT_QTWEBKIT_FOUND True if QtWebKit was found. -# QT_QTXML_FOUND True if QtXml was found. -# QT_QTXMLPATTERNS_FOUND True if QtXmlPatterns was found. -# QT_PHONON_FOUND True if phonon was found. -# QT_QTDECLARATIVE_FOUND True if QtDeclarative was found. -# -# QT_MAC_USE_COCOA For Mac OS X, its whether Cocoa or Carbon is used. -# In general, this should not be used, but its useful -# when having platform specific code. -# -# QT_DEFINITIONS Definitions to use when compiling code that uses Qt. -# You do not need to use this if you include QT_USE_FILE. -# The QT_USE_FILE will also define QT_DEBUG and QT_NO_DEBUG -# to fit your current build type. Those are not contained -# in QT_DEFINITIONS. -# -# QT_INCLUDES List of paths to all include directories of -# Qt4 QT_INCLUDE_DIR and QT_QTCORE_INCLUDE_DIR are -# always in this variable even if NOTFOUND, -# all other INCLUDE_DIRS are -# only added if they are found. -# You do not need to use this if you include QT_USE_FILE. -# -# -# Include directories for the Qt modules are listed here. -# You do not need to use these variables if you include QT_USE_FILE. -# -# QT_INCLUDE_DIR Path to "include" of Qt4 -# QT_QT_INCLUDE_DIR Path to "include/Qt" -# QT_QT3SUPPORT_INCLUDE_DIR Path to "include/Qt3Support" -# QT_QTASSISTANT_INCLUDE_DIR Path to "include/QtAssistant" -# QT_QTASSISTANTCLIENT_INCLUDE_DIR Path to "include/QtAssistant" -# QT_QAXCONTAINER_INCLUDE_DIR Path to "include/ActiveQt" (Windows only) -# QT_QAXSERVER_INCLUDE_DIR Path to "include/ActiveQt" (Windows only) -# QT_QTCORE_INCLUDE_DIR Path to "include/QtCore" -# QT_QTDBUS_INCLUDE_DIR Path to "include/QtDBus" -# QT_QTDESIGNER_INCLUDE_DIR Path to "include/QtDesigner" -# QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR Path to "include/QtDesigner" -# QT_QTGUI_INCLUDE_DIR Path to "include/QtGui" -# QT_QTHELP_INCLUDE_DIR Path to "include/QtHelp" -# QT_QTMOTIF_INCLUDE_DIR Path to "include/QtMotif" -# QT_QTMULTIMEDIA_INCLUDE_DIR Path to "include/QtMultimedia" -# QT_QTNETWORK_INCLUDE_DIR Path to "include/QtNetwork" -# QT_QTNSPLUGIN_INCLUDE_DIR Path to "include/QtNsPlugin" -# QT_QTOPENGL_INCLUDE_DIR Path to "include/QtOpenGL" -# QT_QTSCRIPT_INCLUDE_DIR Path to "include/QtScript" -# QT_QTSQL_INCLUDE_DIR Path to "include/QtSql" -# QT_QTSVG_INCLUDE_DIR Path to "include/QtSvg" -# QT_QTTEST_INCLUDE_DIR Path to "include/QtTest" -# QT_QTWEBKIT_INCLUDE_DIR Path to "include/QtWebKit" -# QT_QTXML_INCLUDE_DIR Path to "include/QtXml" -# QT_QTXMLPATTERNS_INCLUDE_DIR Path to "include/QtXmlPatterns" -# QT_PHONON_INCLUDE_DIR Path to "include/phonon" -# QT_QTSCRIPTTOOLS_INCLUDE_DIR Path to "include/QtScriptTools" -# QT_QTDECLARATIVE_INCLUDE_DIR Path to "include/QtDeclarative" -# -# QT_BINARY_DIR Path to "bin" of Qt4 -# QT_LIBRARY_DIR Path to "lib" of Qt4 -# QT_PLUGINS_DIR Path to "plugins" for Qt4 -# QT_TRANSLATIONS_DIR Path to "translations" of Qt4 -# QT_DOC_DIR Path to "doc" of Qt4 -# QT_MKSPECS_DIR Path to "mkspecs" of Qt4 -# -# -# For every library of Qt, a QT_QTFOO_LIBRARY variable is defined, with the full path to the library. -# -# So there are the following variables: -# The Qt3Support library: QT_QT3SUPPORT_LIBRARY -# -# The QtAssistant library: QT_QTASSISTANT_LIBRARY -# -# The QtAssistantClient library: QT_QTASSISTANTCLIENT_LIBRARY -# -# The QAxServer library: QT_QAXSERVER_LIBRARY -# -# The QAxContainer library: QT_QAXCONTAINER_LIBRARY -# -# The QtCore library: QT_QTCORE_LIBRARY -# -# The QtDBus library: QT_QTDBUS_LIBRARY -# -# The QtDesigner library: QT_QTDESIGNER_LIBRARY -# -# The QtDesignerComponents library: QT_QTDESIGNERCOMPONENTS_LIBRARY -# -# The QtGui library: QT_QTGUI_LIBRARY -# -# The QtHelp library: QT_QTHELP_LIBRARY -# -# The QtMotif library: QT_QTMOTIF_LIBRARY -# -# The QtMultimedia library: QT_QTMULTIMEDIA_LIBRARY -# -# The QtNetwork library: QT_QTNETWORK_LIBRARY -# -# The QtNsPLugin library: QT_QTNSPLUGIN_LIBRARY -# -# The QtOpenGL library: QT_QTOPENGL_LIBRARY -# -# The QtScript library: QT_QTSCRIPT_LIBRARY -# -# The QtScriptTools library: QT_QTSCRIPTTOOLS_LIBRARY -# -# The QtSql library: QT_QTSQL_LIBRARY -# -# The QtSvg library: QT_QTSVG_LIBRARY -# -# The QtTest library: QT_QTTEST_LIBRARY -# -# The QtUiTools library: QT_QTUITOOLS_LIBRARY -# -# The QtWebKit library: QT_QTWEBKIT_LIBRARY -# -# The QtXml library: QT_QTXML_LIBRARY -# -# The QtXmlPatterns library: QT_QTXMLPATTERNS_LIBRARY -# -# The qtmain library for Windows QT_QTMAIN_LIBRARY -# -# The Phonon library: QT_PHONON_LIBRARY -# -# The QtDeclarative library: QT_QTDECLARATIVE_LIBRARY -# -# also defined, but NOT for general use are -# QT_MOC_EXECUTABLE Where to find the moc tool. -# QT_UIC_EXECUTABLE Where to find the uic tool. -# QT_UIC3_EXECUTABLE Where to find the uic3 tool. -# QT_RCC_EXECUTABLE Where to find the rcc tool -# QT_DBUSCPP2XML_EXECUTABLE Where to find the qdbuscpp2xml tool. -# QT_DBUSXML2CPP_EXECUTABLE Where to find the qdbusxml2cpp tool. -# QT_LUPDATE_EXECUTABLE Where to find the lupdate tool. -# QT_LRELEASE_EXECUTABLE Where to find the lrelease tool. -# QT_QCOLLECTIONGENERATOR_EXECUTABLE Where to find the qcollectiongenerator tool. -# QT_DESIGNER_EXECUTABLE Where to find the Qt designer tool. -# QT_LINGUIST_EXECUTABLE Where to find the Qt linguist tool. -# -# -# These are around for backwards compatibility -# they will be set -# QT_WRAP_CPP Set true if QT_MOC_EXECUTABLE is found -# QT_WRAP_UI Set true if QT_UIC_EXECUTABLE is found -# -# These variables do _NOT_ have any effect anymore (compared to FindQt.cmake) -# QT_MT_REQUIRED Qt4 is now always multithreaded -# -# These variables are set to "" Because Qt structure changed -# (They make no sense in Qt4) -# QT_QT_LIBRARY Qt-Library is now split - -# Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. -# See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. - -# Use FIND_PACKAGE( Qt4 COMPONENTS ... ) to enable modules -IF( Qt4_FIND_COMPONENTS ) - FOREACH( component ${Qt4_FIND_COMPONENTS} ) - STRING( TOUPPER ${component} _COMPONENT ) - SET( QT_USE_${_COMPONENT} 1 ) - ENDFOREACH( component ) - - # To make sure we don't use QtCore or QtGui when not in COMPONENTS - IF(NOT QT_USE_QTCORE) - SET( QT_DONT_USE_QTCORE 1 ) - ENDIF(NOT QT_USE_QTCORE) - - IF(NOT QT_USE_QTGUI) - SET( QT_DONT_USE_QTGUI 1 ) - ENDIF(NOT QT_USE_QTGUI) - -ENDIF( Qt4_FIND_COMPONENTS ) - -# If Qt3 has already been found, fail. -IF(QT_QT_LIBRARY) - IF(Qt4_FIND_REQUIRED) - MESSAGE( FATAL_ERROR "Qt3 and Qt4 cannot be used together in one project. If switching to Qt4, the CMakeCache.txt needs to be cleaned.") - ELSE(Qt4_FIND_REQUIRED) - IF(NOT Qt4_FIND_QUIETLY) - MESSAGE( STATUS "Qt3 and Qt4 cannot be used together in one project. If switching to Qt4, the CMakeCache.txt needs to be cleaned.") - ENDIF(NOT Qt4_FIND_QUIETLY) - RETURN() - ENDIF(Qt4_FIND_REQUIRED) -ENDIF(QT_QT_LIBRARY) - - -IF (QT4_QMAKE_FOUND AND Qt4::QtCore) - # Check already done in this cmake run, nothing more to do - RETURN() -ENDIF (QT4_QMAKE_FOUND AND Qt4::QtCore) - -# check that QT_NO_DEBUG is defined for release configurations -MACRO(QT_CHECK_FLAG_EXISTS FLAG VAR DOC) - IF(NOT ${VAR} MATCHES "${FLAG}") - SET(${VAR} "${${VAR}} ${FLAG}" - CACHE STRING "Flags used by the compiler during ${DOC} builds." FORCE) - ENDIF(NOT ${VAR} MATCHES "${FLAG}") -ENDMACRO(QT_CHECK_FLAG_EXISTS FLAG VAR) - -QT_CHECK_FLAG_EXISTS(-DQT_NO_DEBUG CMAKE_CXX_FLAGS_RELWITHDEBINFO "Release with Debug Info") -QT_CHECK_FLAG_EXISTS(-DQT_NO_DEBUG CMAKE_CXX_FLAGS_RELEASE "release") -QT_CHECK_FLAG_EXISTS(-DQT_NO_DEBUG CMAKE_CXX_FLAGS_MINSIZEREL "release minsize") - -INCLUDE(MacroPushRequiredVars) -INCLUDE(CheckSymbolExists) -INCLUDE(MacroAddFileDependencies) - -SET(QT_USE_FILE ${CMAKE_ROOT}/Modules/UseQt4.cmake) - -SET( QT_DEFINITIONS "") - -SET(QT4_INSTALLED_VERSION_TOO_OLD FALSE) - -# macro for asking qmake to process pro files -MACRO(QT_QUERY_QMAKE outvar invar) - IF(QT_QMAKE_EXECUTABLE) - FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmpQmake/tmp.pro - "message(CMAKE_MESSAGE<$$${invar}>)") - - # Invoke qmake with the tmp.pro program to get the desired - # information. Use the same variable for both stdout and stderr - # to make sure we get the output on all platforms. - EXECUTE_PROCESS(COMMAND ${QT_QMAKE_EXECUTABLE} - WORKING_DIRECTORY - ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmpQmake - OUTPUT_VARIABLE _qmake_query_output - RESULT_VARIABLE _qmake_result - ERROR_VARIABLE _qmake_query_output ) - - FILE(REMOVE_RECURSE - "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmpQmake") - - IF(_qmake_result) - MESSAGE(WARNING " querying qmake for ${invar}. qmake reported:\n${_qmake_query_output}") - ELSE(_qmake_result) - STRING(REGEX REPLACE ".*CMAKE_MESSAGE<([^>]*).*" "\\1" ${outvar} "${_qmake_query_output}") - ENDIF(_qmake_result) - - ENDIF(QT_QMAKE_EXECUTABLE) -ENDMACRO(QT_QUERY_QMAKE) - -GET_FILENAME_COMPONENT(qt_install_version "[HKEY_CURRENT_USER\\Software\\trolltech\\Versions;DefaultQtVersion]" NAME) -# check for qmake -# Debian uses qmake-qt4 -# macports' Qt uses qmake-mac -FIND_PROGRAM(QT_QMAKE_EXECUTABLE NAMES qmake qmake4 qmake-qt4 qmake-mac PATHS - "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\4.0.0;InstallDir]/bin" - "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\4.0.0;InstallDir]/bin" - "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\${qt_install_version};InstallDir]/bin" - $ENV{QTDIR}/bin -) - -IF (QT_QMAKE_EXECUTABLE) - - IF(QT_QMAKE_EXECUTABLE_LAST) - STRING(COMPARE NOTEQUAL "${QT_QMAKE_EXECUTABLE_LAST}" "${QT_QMAKE_EXECUTABLE}" QT_QMAKE_CHANGED) - ENDIF(QT_QMAKE_EXECUTABLE_LAST) - - SET(QT_QMAKE_EXECUTABLE_LAST "${QT_QMAKE_EXECUTABLE}" CACHE INTERNAL "" FORCE) - - SET(QT4_QMAKE_FOUND FALSE) - - EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE} ARGS "-query QT_VERSION" OUTPUT_VARIABLE QTVERSION) - - # check for qt3 qmake and then try and find qmake4 or qmake-qt4 in the path - IF("${QTVERSION}" MATCHES "Unknown") - SET(QT_QMAKE_EXECUTABLE NOTFOUND CACHE FILEPATH "" FORCE) - FIND_PROGRAM(QT_QMAKE_EXECUTABLE NAMES qmake4 qmake-qt4 PATHS - "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\4.0.0;InstallDir]/bin" - "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\4.0.0;InstallDir]/bin" - $ENV{QTDIR}/bin - ) - IF(QT_QMAKE_EXECUTABLE) - EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE} - ARGS "-query QT_VERSION" OUTPUT_VARIABLE QTVERSION) - ENDIF(QT_QMAKE_EXECUTABLE) - ENDIF("${QTVERSION}" MATCHES "Unknown") - - # check that we found the Qt4 qmake, Qt3 qmake output won't match here - STRING(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" qt_version_tmp "${QTVERSION}") - IF (qt_version_tmp) - - # we need at least version 4.0.0 - IF (NOT QT_MIN_VERSION) - SET(QT_MIN_VERSION "4.0.0") - ENDIF (NOT QT_MIN_VERSION) - - #now parse the parts of the user given version string into variables - STRING(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" req_qt_major_vers "${QT_MIN_VERSION}") - IF (NOT req_qt_major_vers) - MESSAGE( FATAL_ERROR "Invalid Qt version string given: \"${QT_MIN_VERSION}\", expected e.g. \"4.0.1\"") - ENDIF (NOT req_qt_major_vers) - - # now parse the parts of the user given version string into variables - STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" req_qt_major_vers "${QT_MIN_VERSION}") - STRING(REGEX REPLACE "^[0-9]+\\.([0-9])+\\.[0-9]+" "\\1" req_qt_minor_vers "${QT_MIN_VERSION}") - STRING(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" req_qt_patch_vers "${QT_MIN_VERSION}") - - # Suppport finding at least a particular version, for instance FIND_PACKAGE( Qt4 4.4.3 ) - # This implementation is a hack to avoid duplicating code and make sure we stay - # source-compatible with CMake 2.6.x - IF( Qt4_FIND_VERSION ) - SET( QT_MIN_VERSION ${Qt4_FIND_VERSION} ) - SET( req_qt_major_vers ${Qt4_FIND_VERSION_MAJOR} ) - SET( req_qt_minor_vers ${Qt4_FIND_VERSION_MINOR} ) - SET( req_qt_patch_vers ${Qt4_FIND_VERSION_PATCH} ) - ENDIF( Qt4_FIND_VERSION ) - - IF (NOT req_qt_major_vers EQUAL 4) - MESSAGE( FATAL_ERROR "Invalid Qt version string given: \"${QT_MIN_VERSION}\", major version 4 is required, e.g. \"4.0.1\"") - ENDIF (NOT req_qt_major_vers EQUAL 4) - - # and now the version string given by qmake - STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" QT_VERSION_MAJOR "${QTVERSION}") - STRING(REGEX REPLACE "^[0-9]+\\.([0-9])+\\.[0-9]+.*" "\\1" QT_VERSION_MINOR "${QTVERSION}") - STRING(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" QT_VERSION_PATCH "${QTVERSION}") - - # compute an overall version number which can be compared at once - MATH(EXPR req_vers "${req_qt_major_vers}*10000 + ${req_qt_minor_vers}*100 + ${req_qt_patch_vers}") - MATH(EXPR found_vers "${QT_VERSION_MAJOR}*10000 + ${QT_VERSION_MINOR}*100 + ${QT_VERSION_PATCH}") - - # Support finding *exactly* a particular version, for instance FIND_PACKAGE( Qt4 4.4.3 EXACT ) - IF( Qt4_FIND_VERSION_EXACT ) - IF(found_vers EQUAL req_vers) - SET( QT4_QMAKE_FOUND TRUE ) - ELSE(found_vers EQUAL req_vers) - SET( QT4_QMAKE_FOUND FALSE ) - IF (found_vers LESS req_vers) - SET(QT4_INSTALLED_VERSION_TOO_OLD TRUE) - ELSE (found_vers LESS req_vers) - SET(QT4_INSTALLED_VERSION_TOO_NEW TRUE) - ENDIF (found_vers LESS req_vers) - ENDIF(found_vers EQUAL req_vers) - ELSE( Qt4_FIND_VERSION_EXACT ) - IF (found_vers LESS req_vers) - SET(QT4_QMAKE_FOUND FALSE) - SET(QT4_INSTALLED_VERSION_TOO_OLD TRUE) - ELSE (found_vers LESS req_vers) - SET(QT4_QMAKE_FOUND TRUE) - ENDIF (found_vers LESS req_vers) - ENDIF( Qt4_FIND_VERSION_EXACT ) - ENDIF (qt_version_tmp) - -ENDIF (QT_QMAKE_EXECUTABLE) - -IF (QT4_QMAKE_FOUND) - - if (WIN32) - # get qt install dir - get_filename_component(_DIR ${QT_QMAKE_EXECUTABLE} PATH ) - get_filename_component(QT_INSTALL_DIR ${_DIR} PATH ) - endif (WIN32) - - # ask qmake for the library dir - # Set QT_LIBRARY_DIR - IF (NOT QT_LIBRARY_DIR OR QT_QMAKE_CHANGED) - EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE} - ARGS "-query QT_INSTALL_LIBS" - OUTPUT_VARIABLE QT_LIBRARY_DIR_TMP ) - # make sure we have / and not \ as qmake gives on windows - FILE(TO_CMAKE_PATH "${QT_LIBRARY_DIR_TMP}" QT_LIBRARY_DIR_TMP) - IF(EXISTS "${QT_LIBRARY_DIR_TMP}") - SET(QT_LIBRARY_DIR ${QT_LIBRARY_DIR_TMP} CACHE PATH "Qt library dir" FORCE) - ELSE(EXISTS "${QT_LIBRARY_DIR_TMP}") - MESSAGE("Warning: QT_QMAKE_EXECUTABLE reported QT_INSTALL_LIBS as ${QT_LIBRARY_DIR_TMP}") - MESSAGE("Warning: ${QT_LIBRARY_DIR_TMP} does NOT exist, Qt must NOT be installed correctly.") - ENDIF(EXISTS "${QT_LIBRARY_DIR_TMP}") - ENDIF(NOT QT_LIBRARY_DIR OR QT_QMAKE_CHANGED) - - IF (APPLE) - IF (EXISTS ${QT_LIBRARY_DIR}/QtCore.framework) - SET(QT_USE_FRAMEWORKS ON - CACHE BOOL "Set to ON if Qt build uses frameworks." FORCE) - ELSE (EXISTS ${QT_LIBRARY_DIR}/QtCore.framework) - SET(QT_USE_FRAMEWORKS OFF - CACHE BOOL "Set to ON if Qt build uses frameworks." FORCE) - ENDIF (EXISTS ${QT_LIBRARY_DIR}/QtCore.framework) - - MARK_AS_ADVANCED(QT_USE_FRAMEWORKS) - ENDIF (APPLE) - - # ask qmake for the binary dir - IF (QT_LIBRARY_DIR AND NOT QT_BINARY_DIR OR QT_QMAKE_CHANGED) - EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE} - ARGS "-query QT_INSTALL_BINS" - OUTPUT_VARIABLE qt_bins ) - # make sure we have / and not \ as qmake gives on windows - FILE(TO_CMAKE_PATH "${qt_bins}" qt_bins) - SET(QT_BINARY_DIR ${qt_bins} CACHE INTERNAL "" FORCE) - ENDIF (QT_LIBRARY_DIR AND NOT QT_BINARY_DIR OR QT_QMAKE_CHANGED) - - # ask qmake for the include dir - IF (QT_LIBRARY_DIR AND NOT QT_HEADERS_DIR OR QT_QMAKE_CHANGED) - EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE} - ARGS "-query QT_INSTALL_HEADERS" - OUTPUT_VARIABLE qt_headers ) - # make sure we have / and not \ as qmake gives on windows - FILE(TO_CMAKE_PATH "${qt_headers}" qt_headers) - SET(QT_HEADERS_DIR ${qt_headers} CACHE INTERNAL "" FORCE) - ENDIF (QT_LIBRARY_DIR AND NOT QT_HEADERS_DIR OR QT_QMAKE_CHANGED) - - - # ask qmake for the documentation directory - IF (QT_LIBRARY_DIR AND NOT QT_DOC_DIR OR QT_QMAKE_CHANGED) - EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE} - ARGS "-query QT_INSTALL_DOCS" - OUTPUT_VARIABLE qt_doc_dir ) - # make sure we have / and not \ as qmake gives on windows - FILE(TO_CMAKE_PATH "${qt_doc_dir}" qt_doc_dir) - SET(QT_DOC_DIR ${qt_doc_dir} CACHE PATH "The location of the Qt docs" FORCE) - ENDIF (QT_LIBRARY_DIR AND NOT QT_DOC_DIR OR QT_QMAKE_CHANGED) - - # ask qmake for the mkspecs directory - IF (QT_LIBRARY_DIR AND NOT QT_MKSPECS_DIR OR QT_QMAKE_CHANGED) - EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE} - ARGS "-query QMAKE_MKSPECS" - OUTPUT_VARIABLE qt_mkspecs_dirs ) - # do not replace : on windows as it might be a drive letter - # and windows should already use ; as a separator - IF(UNIX) - STRING(REPLACE ":" ";" qt_mkspecs_dirs "${qt_mkspecs_dirs}") - ENDIF(UNIX) - SET(QT_MKSPECS_DIR NOTFOUND) - FIND_PATH(QT_MKSPECS_DIR qconfig.pri PATHS ${qt_mkspecs_dirs} - DOC "The location of the Qt mkspecs containing qconfig.pri" - NO_DEFAULT_PATH ) - ENDIF (QT_LIBRARY_DIR AND NOT QT_MKSPECS_DIR OR QT_QMAKE_CHANGED) - - # ask qmake for the plugins directory - IF (QT_LIBRARY_DIR AND NOT QT_PLUGINS_DIR OR QT_QMAKE_CHANGED) - EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE} - ARGS "-query QT_INSTALL_PLUGINS" - OUTPUT_VARIABLE qt_plugins_dir ) - # make sure we have / and not \ as qmake gives on windows - FILE(TO_CMAKE_PATH "${qt_plugins_dir}" qt_plugins_dir) - SET(QT_PLUGINS_DIR ${qt_plugins_dir} CACHE PATH "The location of the Qt plugins" FORCE) - ENDIF (QT_LIBRARY_DIR AND NOT QT_PLUGINS_DIR OR QT_QMAKE_CHANGED) - - # ask qmake for the translations directory - IF (QT_LIBRARY_DIR AND NOT QT_TRANSLATIONS_DIR OR QT_QMAKE_CHANGED) - EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE} - ARGS "-query QT_INSTALL_TRANSLATIONS" - OUTPUT_VARIABLE qt_translations_dir ) - # make sure we have / and not \ as qmake gives on windows - FILE(TO_CMAKE_PATH "${qt_translations_dir}" qt_translations_dir) - SET(QT_TRANSLATIONS_DIR ${qt_translations_dir} CACHE PATH "The location of the Qt translations" FORCE) - ENDIF (QT_LIBRARY_DIR AND NOT QT_TRANSLATIONS_DIR OR QT_QMAKE_CHANGED) - - # Make variables changeble to the advanced user - MARK_AS_ADVANCED( QT_LIBRARY_DIR QT_DOC_DIR QT_MKSPECS_DIR - QT_PLUGINS_DIR QT_TRANSLATIONS_DIR) - - - ############################################# - # - # Find out what window system we're using - # - ############################################# - # Save required includes and required_flags variables - MACRO_PUSH_REQUIRED_VARS() - # Add QT_INCLUDE_DIR to CMAKE_REQUIRED_INCLUDES - SET(CMAKE_REQUIRED_INCLUDES "${CMAKE_REQUIRED_INCLUDES};${QT_HEADERS_DIR}") - # On Mac OS X when Qt has framework support, also add the framework path - IF( QT_USE_FRAMEWORKS ) - SET(CMAKE_REQUIRED_FLAGS "-F${QT_LIBRARY_DIR} ") - ENDIF( QT_USE_FRAMEWORKS ) - # Check for Window system symbols (note: only one should end up being set) - CHECK_SYMBOL_EXISTS(Q_WS_X11 "QtCore/qglobal.h" Q_WS_X11) - CHECK_SYMBOL_EXISTS(Q_WS_WIN "QtCore/qglobal.h" Q_WS_WIN) - CHECK_SYMBOL_EXISTS(Q_WS_QWS "QtCore/qglobal.h" Q_WS_QWS) - CHECK_SYMBOL_EXISTS(Q_WS_MAC "QtCore/qglobal.h" Q_WS_MAC) - IF(Q_WS_MAC) - IF(QT_QMAKE_CHANGED) - SET(QT_MAC_USE_COCOA "" CACHE BOOL "Use Cocoa on Mac" FORCE) - ENDIF(QT_QMAKE_CHANGED) - CHECK_SYMBOL_EXISTS(QT_MAC_USE_COCOA "QtCore/qconfig.h" QT_MAC_USE_COCOA) - ENDIF(Q_WS_MAC) - - IF (QT_QTCOPY_REQUIRED) - CHECK_SYMBOL_EXISTS(QT_IS_QTCOPY "QtCore/qglobal.h" QT_KDE_QT_COPY) - IF (NOT QT_IS_QTCOPY) - MESSAGE(FATAL_ERROR "qt-copy is required, but hasn't been found") - ENDIF (NOT QT_IS_QTCOPY) - ENDIF (QT_QTCOPY_REQUIRED) - - # Restore CMAKE_REQUIRED_INCLUDES+CMAKE_REQUIRED_FLAGS variables - MACRO_POP_REQUIRED_VARS() - # - ############################################# - - - - ######################################## - # - # Setting the INCLUDE-Variables - # - ######################################## - - SET(QT_MODULES QtCore QtGui Qt3Support QtSvg QtScript QtTest QtUiTools - QtHelp QtWebKit QtXmlPatterns QtNetwork QtMultimedia - QtNsPlugin QtOpenGL QtSql QtXml QtDesigner QtDBus QtScriptTools QtDeclarative) - - IF(Q_WS_X11) - SET(QT_MODULES ${QT_MODULES} QtMotif) - ENDIF(Q_WS_X11) - - IF(QT_QMAKE_CHANGED) - FOREACH(QT_MODULE ${QT_MODULES}) - STRING(TOUPPER ${QT_MODULE} _upper_qt_module) - SET(QT_${_upper_qt_module}_INCLUDE_DIR NOTFOUND) - SET(QT_${_upper_qt_module}_LIBRARY_RELEASE NOTFOUND) - SET(QT_${_upper_qt_module}_LIBRARY_DEBUG NOTFOUND) - ENDFOREACH(QT_MODULE) - SET(QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR NOTFOUND) - SET(QT_QTDESIGNERCOMPONENTS_LIBRARY_RELEASE NOTFOUND) - SET(QT_QTDESIGNERCOMPONENTS_LIBRARY_DEBUG NOTFOUND) - SET(QT_QTASSISTANTCLIENT_INCLUDE_DIR NOTFOUND) - SET(QT_QTASSISTANTCLIENT_LIBRARY_RELEASE NOTFOUND) - SET(QT_QTASSISTANTCLIENT_LIBRARY_DEBUG NOTFOUND) - SET(QT_QTASSISTANT_INCLUDE_DIR NOTFOUND) - SET(QT_QTASSISTANT_LIBRARY_RELEASE NOTFOUND) - SET(QT_QTASSISTANT_LIBRARY_DEBUG NOTFOUND) - SET(QT_QTCLUCENE_LIBRARY_RELEASE NOTFOUND) - SET(QT_QTCLUCENE_LIBRARY_DEBUG NOTFOUND) - SET(QT_QAXCONTAINER_INCLUDE_DIR NOTFOUND) - SET(QT_QAXCONTAINER_LIBRARY_RELEASE NOTFOUND) - SET(QT_QAXCONTAINER_LIBRARY_DEBUG NOTFOUND) - SET(QT_QAXSERVER_INCLUDE_DIR NOTFOUND) - SET(QT_QAXSERVER_LIBRARY_RELEASE NOTFOUND) - SET(QT_QAXSERVER_LIBRARY_DEBUG NOTFOUND) - IF(WIN32) - SET(QT_QTMAIN_LIBRARY_DEBUG NOTFOUND) - SET(QT_QTMAIN_LIBRARY_RELEASE NOTFOUND) - ENDIF(WIN32) - SET(QT_PHONON_INCLUDE_DIR NOTFOUND) - ENDIF(QT_QMAKE_CHANGED) - - FOREACH(QT_MODULE ${QT_MODULES}) - STRING(TOUPPER ${QT_MODULE} _upper_qt_module) - FIND_PATH(QT_${_upper_qt_module}_INCLUDE_DIR ${QT_MODULE} - PATHS - ${QT_HEADERS_DIR}/${QT_MODULE} - ${QT_LIBRARY_DIR}/${QT_MODULE}.framework/Headers - NO_DEFAULT_PATH - ) - ENDFOREACH(QT_MODULE) - - IF(WIN32) - SET(QT_MODULES ${QT_MODULES} QAxContainer QAxServer) - # Set QT_AXCONTAINER_INCLUDE_DIR and QT_AXSERVER_INCLUDE_DIR - FIND_PATH(QT_QAXCONTAINER_INCLUDE_DIR ActiveQt - PATHS - ${QT_HEADERS_DIR}/ActiveQt - NO_DEFAULT_PATH - ) - FIND_PATH(QT_QAXSERVER_INCLUDE_DIR ActiveQt - PATHS - ${QT_HEADERS_DIR}/ActiveQt - NO_DEFAULT_PATH - ) - ENDIF(WIN32) - - # Set QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR - FIND_PATH(QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR QDesignerComponents - PATHS - ${QT_HEADERS_DIR}/QtDesigner - ${QT_LIBRARY_DIR}/QtDesigner.framework/Headers - NO_DEFAULT_PATH - ) - - # Set QT_QTASSISTANT_INCLUDE_DIR - FIND_PATH(QT_QTASSISTANT_INCLUDE_DIR QtAssistant - PATHS - ${QT_HEADERS_DIR}/QtAssistant - ${QT_LIBRARY_DIR}/QtAssistant.framework/Headers - NO_DEFAULT_PATH - ) - - # Set QT_QTASSISTANTCLIENT_INCLUDE_DIR - FIND_PATH(QT_QTASSISTANTCLIENT_INCLUDE_DIR QAssistantClient - PATHS - ${QT_HEADERS_DIR}/QtAssistant - ${QT_LIBRARY_DIR}/QtAssistant.framework/Headers - NO_DEFAULT_PATH - ) - - # Set QT_QT_INCLUDE_DIR - FIND_PATH(QT_QT_INCLUDE_DIR qglobal.h - PATHS - ${QT_HEADERS_DIR}/Qt - ${QT_LIBRARY_DIR}/QtCore.framework/Headers - NO_DEFAULT_PATH - ) - - # Set QT_PHONON_INCLUDE_DIR - # Qt >= 4.5.3 (or kde-qt-4.5.2 which has the fix too) : Phonon/ClassName is inside include/phonon - # With previous versions of Qt, this could not work; upgrade Qt or use a standalone phonon - FIND_PATH(QT_PHONON_INCLUDE_DIR Phonon - PATHS - ${QT_HEADERS_DIR}/phonon - NO_DEFAULT_PATH - ) - SET(QT_MODULES ${QT_MODULES} phonon) - - # Set QT_INCLUDE_DIR by removine "/QtCore" in the string ${QT_QTCORE_INCLUDE_DIR} - IF( QT_QTCORE_INCLUDE_DIR AND NOT QT_INCLUDE_DIR) - IF (QT_USE_FRAMEWORKS) - SET(QT_INCLUDE_DIR ${QT_HEADERS_DIR}) - ELSE (QT_USE_FRAMEWORKS) - STRING( REGEX REPLACE "/QtCore$" "" qt4_include_dir ${QT_QTCORE_INCLUDE_DIR}) - SET( QT_INCLUDE_DIR ${qt4_include_dir} CACHE PATH "") - ENDIF (QT_USE_FRAMEWORKS) - ENDIF( QT_QTCORE_INCLUDE_DIR AND NOT QT_INCLUDE_DIR) - - IF( NOT QT_INCLUDE_DIR) - IF(Qt4_FIND_REQUIRED) - MESSAGE( FATAL_ERROR "Could NOT find QtCore header") - ENDIF(Qt4_FIND_REQUIRED) - ENDIF( NOT QT_INCLUDE_DIR) - - # Make variables changeble to the advanced user - MARK_AS_ADVANCED( QT_INCLUDE_DIR QT_QT_INCLUDE_DIR) - - # Set QT_INCLUDES - SET( QT_INCLUDES ${QT_QT_INCLUDE_DIR} ${QT_MKSPECS_DIR}/default ${QT_INCLUDE_DIR} ) - - - ####################################### - # - # Qt configuration - # - ####################################### - IF(EXISTS "${QT_MKSPECS_DIR}/qconfig.pri") - FILE(READ ${QT_MKSPECS_DIR}/qconfig.pri _qconfig_FILE_contents) - STRING(REGEX MATCH "QT_CONFIG[^\n]+" QT_QCONFIG "${_qconfig_FILE_contents}") - STRING(REGEX MATCH "CONFIG[^\n]+" QT_CONFIG "${_qconfig_FILE_contents}") - STRING(REGEX MATCH "EDITION[^\n]+" QT_EDITION "${_qconfig_FILE_contents}") - STRING(REGEX MATCH "QT_LIBINFIX[^\n]+" _qconfig_qt_libinfix "${_qconfig_FILE_contents}") - STRING(REGEX REPLACE "QT_LIBINFIX *= *([^\n]*)" "\\1" QT_LIBINFIX "${_qconfig_qt_libinfix}") - ENDIF(EXISTS "${QT_MKSPECS_DIR}/qconfig.pri") - IF("${QT_EDITION}" MATCHES "DesktopLight") - SET(QT_EDITION_DESKTOPLIGHT 1) - ENDIF("${QT_EDITION}" MATCHES "DesktopLight") - - ######################################## - # - # Setting the LIBRARY-Variables - # - ######################################## - - # find the libraries - FOREACH(QT_MODULE ${QT_MODULES}) - STRING(TOUPPER ${QT_MODULE} _upper_qt_module) - FIND_LIBRARY(QT_${_upper_qt_module}_LIBRARY_RELEASE - NAMES ${QT_MODULE}${QT_LIBINFIX} ${QT_MODULE}${QT_LIBINFIX}4 - PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH - ) - FIND_LIBRARY(QT_${_upper_qt_module}_LIBRARY_DEBUG - NAMES ${QT_MODULE}${QT_LIBINFIX}_debug ${QT_MODULE}${QT_LIBINFIX}d ${QT_MODULE}${QT_LIBINFIX}d4 - PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH - ) - ENDFOREACH(QT_MODULE) - - # QtUiTools not with other frameworks with binary installation (in /usr/lib) - IF(Q_WS_MAC AND QT_QTCORE_LIBRARY_RELEASE AND NOT QT_QTUITOOLS_LIBRARY_RELEASE) - FIND_LIBRARY(QT_QTUITOOLS_LIBRARY_RELEASE NAMES QtUiTools${QT_LIBINFIX} PATHS ${QT_LIBRARY_DIR}) - ENDIF(Q_WS_MAC AND QT_QTCORE_LIBRARY_RELEASE AND NOT QT_QTUITOOLS_LIBRARY_RELEASE) - - IF( NOT QT_QTCORE_LIBRARY_DEBUG AND NOT QT_QTCORE_LIBRARY_RELEASE ) - - # try dropping a hint if trying to use Visual Studio with Qt built by mingw - IF(QT_LIBRARY_DIR AND MSVC) - IF(EXISTS ${QT_LIBRARY_DIR}/libqtmain.a) - MESSAGE( FATAL_ERROR "It appears you're trying to use Visual Studio with Qt built by mingw") - ENDIF(EXISTS ${QT_LIBRARY_DIR}/libqtmain.a) - ENDIF(QT_LIBRARY_DIR AND MSVC) - - IF(Qt4_FIND_REQUIRED) - MESSAGE( FATAL_ERROR "Could NOT find QtCore. Check ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log for more details.") - ENDIF(Qt4_FIND_REQUIRED) - ENDIF( NOT QT_QTCORE_LIBRARY_DEBUG AND NOT QT_QTCORE_LIBRARY_RELEASE ) - - # Set QT_QTDESIGNERCOMPONENTS_LIBRARY - FIND_LIBRARY(QT_QTDESIGNERCOMPONENTS_LIBRARY_RELEASE NAMES QtDesignerComponents${QT_LIBINFIX} QtDesignerComponents${QT_LIBINFIX}4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - FIND_LIBRARY(QT_QTDESIGNERCOMPONENTS_LIBRARY_DEBUG NAMES QtDesignerComponents${QT_LIBINFIX}_debug QtDesignerComponents${QT_LIBINFIX}d QtDesignerComponents${QT_LIBINFIX}d4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - - # Set QT_QTMAIN_LIBRARY - IF(WIN32) - FIND_LIBRARY(QT_QTMAIN_LIBRARY_RELEASE NAMES qtmain${QT_LIBINFIX} PATHS ${QT_LIBRARY_DIR} - NO_DEFAULT_PATH) - FIND_LIBRARY(QT_QTMAIN_LIBRARY_DEBUG NAMES qtmain${QT_LIBINFIX}d PATHS ${QT_LIBRARY_DIR} - NO_DEFAULT_PATH) - ENDIF(WIN32) - - # Set QT_QTASSISTANTCLIENT_LIBRARY - FIND_LIBRARY(QT_QTASSISTANTCLIENT_LIBRARY_RELEASE NAMES QtAssistantClient${QT_LIBINFIX} QtAssistantClient${QT_LIBINFIX}4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - FIND_LIBRARY(QT_QTASSISTANTCLIENT_LIBRARY_DEBUG NAMES QtAssistantClient${QT_LIBINFIX}_debug QtAssistantClient${QT_LIBINFIX}d QtAssistantClient${QT_LIBINFIX}d4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - - # Set QT_QTASSISTANT_LIBRARY - FIND_LIBRARY(QT_QTASSISTANT_LIBRARY_RELEASE NAMES QtAssistantClient${QT_LIBINFIX} QtAssistantClient${QT_LIBINFIX}4 QtAssistant${QT_LIBINFIX} QtAssistant${QT_LIBINFIX}4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - FIND_LIBRARY(QT_QTASSISTANT_LIBRARY_DEBUG NAMES QtAssistantClient${QT_LIBINFIX}_debug QtAssistantClient${QT_LIBINFIX}d QtAssistantClient${QT_LIBINFIX}d4 QtAssistant${QT_LIBINFIX}_debug QtAssistant${QT_LIBINFIX}d4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - - # Set QT_QTHELP_LIBRARY - FIND_LIBRARY(QT_QTCLUCENE_LIBRARY_RELEASE NAMES QtCLucene${QT_LIBINFIX} QtCLucene${QT_LIBINFIX}4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - FIND_LIBRARY(QT_QTCLUCENE_LIBRARY_DEBUG NAMES QtCLucene${QT_LIBINFIX}_debug QtCLucene${QT_LIBINFIX}d QtCLucene${QT_LIBINFIX}d4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - # QtCLucene not with other frameworks with binary installation (in /usr/lib) - IF(Q_WS_MAC AND QT_QTCORE_LIBRARY_RELEASE AND NOT QT_QTCLUCENE_LIBRARY_RELEASE) - FIND_LIBRARY(QT_QTCLUCENE_LIBRARY_RELEASE NAMES QtCLucene${QT_LIBINFIX} PATHS ${QT_LIBRARY_DIR}) - ENDIF(Q_WS_MAC AND QT_QTCORE_LIBRARY_RELEASE AND NOT QT_QTCLUCENE_LIBRARY_RELEASE) - - ############################################ - # - # Check the existence of the libraries. - # - ############################################ - - # On OSX when Qt is found as framework, never use the imported targets for now, since - # in this case the handling of the framework directory currently does not work correctly. - IF(QT_USE_FRAMEWORKS) - SET(QT_USE_IMPORTED_TARGETS FALSE) - ENDIF(QT_USE_FRAMEWORKS) - - - MACRO (_QT4_ADJUST_LIB_VARS _camelCaseBasename) - - STRING(TOUPPER "${_camelCaseBasename}" basename) - - # The name of the imported targets, i.e. the prefix "Qt4::" must not change, - # since it is stored in EXPORT-files as name of a required library. If the name would change - # here, this would lead to the imported Qt4-library targets not being resolved by cmake anymore. - IF (QT_${basename}_LIBRARY_RELEASE OR QT_${basename}_LIBRARY_DEBUG) - - IF(NOT TARGET Qt4::${_camelCaseBasename}) - ADD_LIBRARY(Qt4::${_camelCaseBasename} UNKNOWN IMPORTED ) - - IF (QT_${basename}_LIBRARY_RELEASE) - SET_PROPERTY(TARGET Qt4::${_camelCaseBasename} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) - SET_PROPERTY(TARGET Qt4::${_camelCaseBasename} PROPERTY IMPORTED_LOCATION_RELEASE "${QT_${basename}_LIBRARY_RELEASE}" ) - ENDIF (QT_${basename}_LIBRARY_RELEASE) - - IF (QT_${basename}_LIBRARY_DEBUG) - SET_PROPERTY(TARGET Qt4::${_camelCaseBasename} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) - SET_PROPERTY(TARGET Qt4::${_camelCaseBasename} PROPERTY IMPORTED_LOCATION_DEBUG "${QT_${basename}_LIBRARY_DEBUG}" ) - ENDIF (QT_${basename}_LIBRARY_DEBUG) - ENDIF(NOT TARGET Qt4::${_camelCaseBasename}) - - # If QT_USE_IMPORTED_TARGETS is enabled, the QT_QTFOO_LIBRARY variables are set to point at these - # imported targets. This works better in general, and is also in almost all cases fully - # backward compatible. The only issue is when a project A which had this enabled then exports its - # libraries via export or EXPORT_LIBRARY_DEPENDENCIES(). In this case the libraries from project - # A will depend on the imported Qt targets, and the names of these imported targets will be stored - # in the dependency files on disk. This means when a project B then uses project A, these imported - # targets must be created again, otherwise e.g. "Qt4__QtCore" will be interpreted as name of a - # library file on disk, and not as a target, and linking will fail: - IF(QT_USE_IMPORTED_TARGETS) - SET(QT_${basename}_LIBRARY Qt4::${_camelCaseBasename} ) - SET(QT_${basename}_LIBRARIES Qt4::${_camelCaseBasename} ) - ELSE(QT_USE_IMPORTED_TARGETS) - - # if the release- as well as the debug-version of the library have been found: - IF (QT_${basename}_LIBRARY_DEBUG AND QT_${basename}_LIBRARY_RELEASE) - # if the generator supports configuration types then set - # optimized and debug libraries, or if the CMAKE_BUILD_TYPE has a value - IF (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) - SET(QT_${basename}_LIBRARY optimized ${QT_${basename}_LIBRARY_RELEASE} debug ${QT_${basename}_LIBRARY_DEBUG}) - ELSE(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) - # if there are no configuration types and CMAKE_BUILD_TYPE has no value - # then just use the release libraries - SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY_RELEASE} ) - ENDIF(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) - SET(QT_${basename}_LIBRARIES optimized ${QT_${basename}_LIBRARY_RELEASE} debug ${QT_${basename}_LIBRARY_DEBUG}) - ENDIF (QT_${basename}_LIBRARY_DEBUG AND QT_${basename}_LIBRARY_RELEASE) - - # if only the release version was found, set the debug variable also to the release version - IF (QT_${basename}_LIBRARY_RELEASE AND NOT QT_${basename}_LIBRARY_DEBUG) - SET(QT_${basename}_LIBRARY_DEBUG ${QT_${basename}_LIBRARY_RELEASE}) - SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY_RELEASE}) - SET(QT_${basename}_LIBRARIES ${QT_${basename}_LIBRARY_RELEASE}) - ENDIF (QT_${basename}_LIBRARY_RELEASE AND NOT QT_${basename}_LIBRARY_DEBUG) - - # if only the debug version was found, set the release variable also to the debug version - IF (QT_${basename}_LIBRARY_DEBUG AND NOT QT_${basename}_LIBRARY_RELEASE) - SET(QT_${basename}_LIBRARY_RELEASE ${QT_${basename}_LIBRARY_DEBUG}) - SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY_DEBUG}) - SET(QT_${basename}_LIBRARIES ${QT_${basename}_LIBRARY_DEBUG}) - ENDIF (QT_${basename}_LIBRARY_DEBUG AND NOT QT_${basename}_LIBRARY_RELEASE) - - # put the value in the cache: - SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY} CACHE STRING "The Qt ${basename} library" FORCE) - - ENDIF(QT_USE_IMPORTED_TARGETS) - -#message(STATUS "QT_${basename}_LIBRARY: ${QT_${basename}_LIBRARY}") - - SET(QT_${basename}_FOUND 1) - - ENDIF (QT_${basename}_LIBRARY_RELEASE OR QT_${basename}_LIBRARY_DEBUG) - - IF (QT_${basename}_INCLUDE_DIR) - #add the include directory to QT_INCLUDES - SET(QT_INCLUDES "${QT_${basename}_INCLUDE_DIR}" ${QT_INCLUDES}) - ENDIF (QT_${basename}_INCLUDE_DIR) - - # Make variables changeble to the advanced user - MARK_AS_ADVANCED(QT_${basename}_LIBRARY QT_${basename}_LIBRARY_RELEASE QT_${basename}_LIBRARY_DEBUG QT_${basename}_INCLUDE_DIR) - ENDMACRO (_QT4_ADJUST_LIB_VARS) - - - # Set QT_xyz_LIBRARY variable and add - # library include path to QT_INCLUDES - _QT4_ADJUST_LIB_VARS(QtCore) - _QT4_ADJUST_LIB_VARS(QtGui) - _QT4_ADJUST_LIB_VARS(Qt3Support) - _QT4_ADJUST_LIB_VARS(QtAssistant) - _QT4_ADJUST_LIB_VARS(QtAssistantClient) - _QT4_ADJUST_LIB_VARS(QtCLucene) - _QT4_ADJUST_LIB_VARS(QtDBus) - _QT4_ADJUST_LIB_VARS(QtDeclarative) - _QT4_ADJUST_LIB_VARS(QtDesigner) - _QT4_ADJUST_LIB_VARS(QtDesignerComponents) - _QT4_ADJUST_LIB_VARS(QtHelp) - _QT4_ADJUST_LIB_VARS(QtMultimedia) - _QT4_ADJUST_LIB_VARS(QtNetwork) - _QT4_ADJUST_LIB_VARS(QtNsPlugin) - _QT4_ADJUST_LIB_VARS(QtOpenGL) - _QT4_ADJUST_LIB_VARS(QtScript) - _QT4_ADJUST_LIB_VARS(QtScriptTools) - _QT4_ADJUST_LIB_VARS(QtSql) - _QT4_ADJUST_LIB_VARS(QtSvg) - _QT4_ADJUST_LIB_VARS(QtTest) - _QT4_ADJUST_LIB_VARS(QtUiTools) - _QT4_ADJUST_LIB_VARS(QtWebKit) - _QT4_ADJUST_LIB_VARS(QtXml) - _QT4_ADJUST_LIB_VARS(QtXmlPatterns) - _QT4_ADJUST_LIB_VARS(phonon) - - # platform dependent libraries - IF(Q_WS_X11) - _QT4_ADJUST_LIB_VARS(QtMotif) - ENDIF(Q_WS_X11) - IF(WIN32) - _QT4_ADJUST_LIB_VARS(qtmain) - _QT4_ADJUST_LIB_VARS(QAxServer) - _QT4_ADJUST_LIB_VARS(QAxContainer) - ENDIF(WIN32) - - # If Qt is installed as a framework, we need to add QT_QTCORE_LIBRARY here (which - # is the framework directory in that case), since this will make the cmake include_directories() - # command recognize that we need the framework flag with the respective directory (-F) - IF(QT_USE_FRAMEWORKS) - SET(QT_INCLUDES ${QT_INCLUDES} ${QT_QTCORE_LIBRARY} ) - SET(QT_INCLUDE_DIR ${QT_INCLUDE_DIR} ${QT_QTCORE_LIBRARY} ) - ENDIF(QT_USE_FRAMEWORKS) - - - - ####################################### - # - # Check the executables of Qt - # ( moc, uic, rcc ) - # - ####################################### - - - IF(QT_QMAKE_CHANGED) - SET(QT_UIC_EXECUTABLE NOTFOUND) - SET(QT_MOC_EXECUTABLE NOTFOUND) - SET(QT_UIC3_EXECUTABLE NOTFOUND) - SET(QT_RCC_EXECUTABLE NOTFOUND) - SET(QT_DBUSCPP2XML_EXECUTABLE NOTFOUND) - SET(QT_DBUSXML2CPP_EXECUTABLE NOTFOUND) - SET(QT_LUPDATE_EXECUTABLE NOTFOUND) - SET(QT_LRELEASE_EXECUTABLE NOTFOUND) - SET(QT_QCOLLECTIONGENERATOR_EXECUTABLE NOTFOUND) - SET(QT_DESIGNER_EXECUTABLE NOTFOUND) - SET(QT_LINGUIST_EXECUTABLE NOTFOUND) - ENDIF(QT_QMAKE_CHANGED) - - FIND_PROGRAM(QT_MOC_EXECUTABLE - NAMES moc-qt4 moc - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_UIC_EXECUTABLE - NAMES uic-qt4 uic - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_UIC3_EXECUTABLE - NAMES uic3 - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_RCC_EXECUTABLE - NAMES rcc - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_DBUSCPP2XML_EXECUTABLE - NAMES qdbuscpp2xml - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_DBUSXML2CPP_EXECUTABLE - NAMES qdbusxml2cpp - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_LUPDATE_EXECUTABLE - NAMES lupdate-qt4 lupdate - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_LRELEASE_EXECUTABLE - NAMES lrelease-qt4 lrelease - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_QCOLLECTIONGENERATOR_EXECUTABLE - NAMES qcollectiongenerator-qt4 qcollectiongenerator - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_DESIGNER_EXECUTABLE - NAMES designer-qt4 designer - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_LINGUIST_EXECUTABLE - NAMES linguist-qt4 linguist - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - IF (QT_MOC_EXECUTABLE) - SET(QT_WRAP_CPP "YES") - ENDIF (QT_MOC_EXECUTABLE) - - IF (QT_UIC_EXECUTABLE) - SET(QT_WRAP_UI "YES") - ENDIF (QT_UIC_EXECUTABLE) - - - - MARK_AS_ADVANCED( QT_UIC_EXECUTABLE QT_UIC3_EXECUTABLE QT_MOC_EXECUTABLE - QT_RCC_EXECUTABLE QT_DBUSXML2CPP_EXECUTABLE QT_DBUSCPP2XML_EXECUTABLE - QT_LUPDATE_EXECUTABLE QT_LRELEASE_EXECUTABLE QT_QCOLLECTIONGENERATOR_EXECUTABLE - QT_DESIGNER_EXECUTABLE QT_LINGUIST_EXECUTABLE) - - - # get the directory of the current file, used later on in the file - GET_FILENAME_COMPONENT( _qt4_current_dir "${CMAKE_CURRENT_LIST_FILE}" PATH) - - ###################################### - # - # Macros for building Qt files - # - ###################################### - - INCLUDE("${_qt4_current_dir}/Qt4Macros.cmake") - - - ###################################### - # - # decide if Qt got found - # - ###################################### - - # if the includes,libraries,moc,uic and rcc are found then we have it - IF( QT_LIBRARY_DIR AND QT_INCLUDE_DIR AND QT_MOC_EXECUTABLE AND - QT_UIC_EXECUTABLE AND QT_RCC_EXECUTABLE AND QT_QTCORE_LIBRARY) - SET( QT4_FOUND "YES" ) - IF( NOT Qt4_FIND_QUIETLY) - MESSAGE(STATUS "Found Qt-Version ${QTVERSION} (using ${QT_QMAKE_EXECUTABLE})") - ENDIF( NOT Qt4_FIND_QUIETLY) - ELSE( QT_LIBRARY_DIR AND QT_INCLUDE_DIR AND QT_MOC_EXECUTABLE AND - QT_UIC_EXECUTABLE AND QT_RCC_EXECUTABLE AND QT_QTCORE_LIBRARY) - SET( QT4_FOUND "NO") - SET(QT_QMAKE_EXECUTABLE "${QT_QMAKE_EXECUTABLE}-NOTFOUND" CACHE FILEPATH "Invalid qmake found" FORCE) - IF( Qt4_FIND_REQUIRED) - IF ( NOT QT_LIBRARY_DIR ) - MESSAGE(STATUS "Qt libraries NOT found!") - ENDIF(NOT QT_LIBRARY_DIR ) - IF ( NOT QT_INCLUDE_DIR ) - MESSAGE(STATUS "Qt includes NOT found!") - ENDIF( NOT QT_INCLUDE_DIR ) - IF ( NOT QT_MOC_EXECUTABLE ) - MESSAGE(STATUS "Qt's moc NOT found!") - ENDIF( NOT QT_MOC_EXECUTABLE ) - IF ( NOT QT_UIC_EXECUTABLE ) - MESSAGE(STATUS "Qt's uic NOT found!") - ENDIF( NOT QT_UIC_EXECUTABLE ) - IF ( NOT QT_RCC_EXECUTABLE ) - MESSAGE(STATUS "Qt's rcc NOT found!") - ENDIF( NOT QT_RCC_EXECUTABLE ) - MESSAGE( FATAL_ERROR "Qt libraries, includes, moc, uic or/and rcc NOT found!") - ENDIF( Qt4_FIND_REQUIRED) - ENDIF( QT_LIBRARY_DIR AND QT_INCLUDE_DIR AND QT_MOC_EXECUTABLE AND - QT_UIC_EXECUTABLE AND QT_RCC_EXECUTABLE AND QT_QTCORE_LIBRARY) - - SET(QT_FOUND ${QT4_FOUND}) - - - ############################################### - # - # configuration/system dependent settings - # - ############################################### - - INCLUDE("${_qt4_current_dir}/Qt4ConfigDependentSettings.cmake") - - - ####################################### - # - # compatibility settings - # - ####################################### - # Backwards compatibility for CMake1.4 and 1.2 - SET (QT_MOC_EXE ${QT_MOC_EXECUTABLE} ) - SET (QT_UIC_EXE ${QT_UIC_EXECUTABLE} ) - - SET( QT_QT_LIBRARY "") - -ELSE(QT4_QMAKE_FOUND) - - SET(QT_QMAKE_EXECUTABLE "${QT_QMAKE_EXECUTABLE}-NOTFOUND" CACHE FILEPATH "Invalid qmake found" FORCE) - - # The code below is overly complex to make sure we do not break compatibility with CMake 2.6.x - # For CMake 2.8, it should be simplified by getting rid of QT4_INSTALLED_VERSION_TOO_OLD and - # QT4_INSTALLED_VERSION_TOO_NEW - IF(Qt4_FIND_REQUIRED) - IF(QT4_INSTALLED_VERSION_TOO_OLD) - IF( Qt4_FIND_VERSION_EXACT ) - MESSAGE(FATAL_ERROR "The installed Qt version ${QTVERSION} is too old, version ${QT_MIN_VERSION} is required") - ELSE( Qt4_FIND_VERSION_EXACT ) - MESSAGE(FATAL_ERROR "The installed Qt version ${QTVERSION} is too old, at least version ${QT_MIN_VERSION} is required") - ENDIF( Qt4_FIND_VERSION_EXACT ) - ELSE(QT4_INSTALLED_VERSION_TOO_OLD) - IF( Qt4_FIND_VERSION_EXACT AND QT4_INSTALLED_VERSION_TOO_NEW ) - MESSAGE(FATAL_ERROR "The installed Qt version ${QTVERSION} is too new, version ${QT_MIN_VERSION} is required") - ELSE( Qt4_FIND_VERSION_EXACT AND QT4_INSTALLED_VERSION_TOO_NEW ) - MESSAGE( FATAL_ERROR "Qt qmake not found!") - ENDIF( Qt4_FIND_VERSION_EXACT AND QT4_INSTALLED_VERSION_TOO_NEW ) - ENDIF(QT4_INSTALLED_VERSION_TOO_OLD) - ELSE(Qt4_FIND_REQUIRED) - IF(QT4_INSTALLED_VERSION_TOO_OLD AND NOT Qt4_FIND_QUIETLY) - MESSAGE(STATUS "The installed Qt version ${QTVERSION} is too old, at least version ${QT_MIN_VERSION} is required") - ENDIF(QT4_INSTALLED_VERSION_TOO_OLD AND NOT Qt4_FIND_QUIETLY) - ENDIF(Qt4_FIND_REQUIRED) - -ENDIF (QT4_QMAKE_FOUND) - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/cmake/MacroPushRequiredVars.cmake kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/cmake/MacroPushRequiredVars.cmake --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/cmake/MacroPushRequiredVars.cmake 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/cmake/MacroPushRequiredVars.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -# this module defines two macros: -# MACRO_PUSH_REQUIRED_VARS() -# and -# MACRO_POP_REQUIRED_VARS() -# use these if you call cmake macros which use -# any of the CMAKE_REQUIRED_XXX variables -# -# Usage: -# MACRO_PUSH_REQUIRED_VARS() -# SET(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -DSOME_MORE_DEF) -# CHECK_FUNCTION_EXISTS(...) -# MACRO_POP_REQUIRED_VARS() - -# Copyright (c) 2006, Alexander Neundorf, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -MACRO(MACRO_PUSH_REQUIRED_VARS) - - IF(NOT DEFINED _PUSH_REQUIRED_VARS_COUNTER) - SET(_PUSH_REQUIRED_VARS_COUNTER 0) - ENDIF(NOT DEFINED _PUSH_REQUIRED_VARS_COUNTER) - - MATH(EXPR _PUSH_REQUIRED_VARS_COUNTER "${_PUSH_REQUIRED_VARS_COUNTER}+1") - - SET(_CMAKE_REQUIRED_INCLUDES_SAVE_${_PUSH_REQUIRED_VARS_COUNTER} ${CMAKE_REQUIRED_INCLUDES}) - SET(_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_PUSH_REQUIRED_VARS_COUNTER} ${CMAKE_REQUIRED_DEFINITIONS}) - SET(_CMAKE_REQUIRED_LIBRARIES_SAVE_${_PUSH_REQUIRED_VARS_COUNTER} ${CMAKE_REQUIRED_LIBRARIES}) - SET(_CMAKE_REQUIRED_FLAGS_SAVE_${_PUSH_REQUIRED_VARS_COUNTER} ${CMAKE_REQUIRED_FLAGS}) -ENDMACRO(MACRO_PUSH_REQUIRED_VARS) - -MACRO(MACRO_POP_REQUIRED_VARS) - -# don't pop more than we pushed - IF("${_PUSH_REQUIRED_VARS_COUNTER}" GREATER "0") - - SET(CMAKE_REQUIRED_INCLUDES ${_CMAKE_REQUIRED_INCLUDES_SAVE_${_PUSH_REQUIRED_VARS_COUNTER}}) - SET(CMAKE_REQUIRED_DEFINITIONS ${_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_PUSH_REQUIRED_VARS_COUNTER}}) - SET(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_SAVE_${_PUSH_REQUIRED_VARS_COUNTER}}) - SET(CMAKE_REQUIRED_FLAGS ${_CMAKE_REQUIRED_FLAGS_SAVE_${_PUSH_REQUIRED_VARS_COUNTER}}) - - MATH(EXPR _PUSH_REQUIRED_VARS_COUNTER "${_PUSH_REQUIRED_VARS_COUNTER}-1") - ENDIF("${_PUSH_REQUIRED_VARS_COUNTER}" GREATER "0") - -ENDMACRO(MACRO_POP_REQUIRED_VARS) - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/cmake/Qt4ConfigDependentSettings.cmake kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/cmake/Qt4ConfigDependentSettings.cmake --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/cmake/Qt4ConfigDependentSettings.cmake 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/cmake/Qt4ConfigDependentSettings.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,384 +0,0 @@ -# This file is included by FindQt4.cmake, don't include it directly. - -#============================================================================= -# Copyright 2005-2009 Kitware, Inc. -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distributed this file outside of CMake, substitute the full -# License text for the above reference.) - - -############################################### -# -# configuration/system dependent settings -# -############################################### - -# this check for X11 and threads may not be necessary, since it is not -# contained in the cmake version of FindQt4.cmake: - -# for unix add X11 stuff -IF(UNIX) - # on OS X X11 may not be required - IF (Q_WS_X11) - FIND_PACKAGE(X11 REQUIRED) - ENDIF (Q_WS_X11) - FIND_PACKAGE(Threads) - SET(QT_QTCORE_LIBRARY ${QT_QTCORE_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -ENDIF(UNIX) - - -# find dependencies for some Qt modules -# when doing builds against a static Qt, they are required -# when doing builds against a shared Qt, they are not required -# if a user needs the dependencies, and they couldn't be found, they can set -# the variables themselves. - -SET(QT_QTGUI_LIB_DEPENDENCIES "") -SET(QT_QTCORE_LIB_DEPENDENCIES "") -SET(QT_QTNETWORK_LIB_DEPENDENCIES "") -SET(QT_QTOPENGL_LIB_DEPENDENCIES "") -SET(QT_QTDBUS_LIB_DEPENDENCIES "") -SET(QT_QTHELP_LIB_DEPENDENCIES ${QT_QTCLUCENE_LIBRARY}) - - -IF(WIN32) - # On Windows, qconfig.pri has "static" for static library builds - IF(QT_CONFIG MATCHES "static") - SET(QT_IS_STATIC 1) - ENDIF(QT_CONFIG MATCHES "static") -ELSE(WIN32) - # On other platforms, check file extension to know if its static - IF(QT_QTCORE_LIBRARY_RELEASE) - GET_FILENAME_COMPONENT(qtcore_lib_ext "${QT_QTCORE_LIBRARY_RELEASE}" EXT) - IF("${qtcore_lib_ext}" STREQUAL "${CMAKE_STATIC_LIBRARY_SUFFIX}") - SET(QT_IS_STATIC 1) - ENDIF("${qtcore_lib_ext}" STREQUAL "${CMAKE_STATIC_LIBRARY_SUFFIX}") - ENDIF(QT_QTCORE_LIBRARY_RELEASE) - IF(QT_QTCORE_LIBRARY_DEBUG) - GET_FILENAME_COMPONENT(qtcore_lib_ext "${QT_QTCORE_LIBRARY_DEBUG}" EXT) - IF(${qtcore_lib_ext} STREQUAL ${CMAKE_STATIC_LIBRARY_SUFFIX}) - SET(QT_IS_STATIC 1) - ENDIF(${qtcore_lib_ext} STREQUAL ${CMAKE_STATIC_LIBRARY_SUFFIX}) - ENDIF(QT_QTCORE_LIBRARY_DEBUG) -ENDIF(WIN32) - -# build using shared Qt needs -DQT_DLL on Windows -IF(WIN32 AND NOT QT_IS_STATIC) - SET(QT_DEFINITIONS ${QT_DEFINITIONS} -DQT_DLL) -ENDIF(WIN32 AND NOT QT_IS_STATIC) - - -# QtOpenGL dependencies -QT_QUERY_QMAKE(QMAKE_LIBS_OPENGL "QMAKE_LIBS_OPENGL") -IF(Q_WS_MAC) -# On the Mac OpenGL is probably frameworks and QMAKE_LIBS_OPENGL can be e.g. "-framework OpenGL -framework AGL". -# The separate_arguments() call in the other branch makes "-framework;-OpenGL;-framework;-lAGL" appear in the -# linker command. So we need to protect the "-framework foo" as non-separatable strings. -# We do this by replacing the space after "-framework" with an underscore, then calling separate_arguments(), -# and then we replace the underscores again with spaces. So we get proper linker commands. Alex - STRING(REGEX REPLACE "-framework +" "-framework_" QMAKE_LIBS_OPENGL "${QMAKE_LIBS_OPENGL}") - SEPARATE_ARGUMENTS(QMAKE_LIBS_OPENGL) - STRING(REGEX REPLACE "-framework_" "-framework " QMAKE_LIBS_OPENGL "${QMAKE_LIBS_OPENGL}") -ELSE(Q_WS_MAC) - SEPARATE_ARGUMENTS(QMAKE_LIBS_OPENGL) -ENDIF(Q_WS_MAC) -SET (QT_QTOPENGL_LIB_DEPENDENCIES ${QT_QTOPENGL_LIB_DEPENDENCIES} ${QMAKE_LIBS_OPENGL}) - - -## system png -IF(QT_QCONFIG MATCHES "system-png") - FIND_LIBRARY(QT_PNG_LIBRARY NAMES png) - MARK_AS_ADVANCED(QT_PNG_LIBRARY) - IF(QT_PNG_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_PNG_LIBRARY}) - ENDIF(QT_PNG_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "system-png") - - -# for X11, get X11 library directory -IF(Q_WS_X11) - QT_QUERY_QMAKE(QMAKE_LIBDIR_X11 "QMAKE_LIBDIR_X11") -ENDIF(Q_WS_X11) - - -## X11 SM -IF(QT_QCONFIG MATCHES "x11sm") - # ask qmake where the x11 libs are - FIND_LIBRARY(QT_X11_SM_LIBRARY NAMES SM PATHS ${QMAKE_LIBDIR_X11}) - FIND_LIBRARY(QT_X11_ICE_LIBRARY NAMES ICE PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(QT_X11_SM_LIBRARY) - MARK_AS_ADVANCED(QT_X11_ICE_LIBRARY) - IF(QT_X11_SM_LIBRARY AND QT_X11_ICE_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_X11_SM_LIBRARY} ${QT_X11_ICE_LIBRARY}) - ENDIF(QT_X11_SM_LIBRARY AND QT_X11_ICE_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "x11sm") - - -## Xi -IF(QT_QCONFIG MATCHES "tablet") - FIND_LIBRARY(QT_XI_LIBRARY NAMES Xi PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(QT_XI_LIBRARY) - IF(QT_XI_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_XI_LIBRARY}) - ENDIF(QT_XI_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "tablet") - - -## Xrender -IF(QT_QCONFIG MATCHES "xrender") - FIND_LIBRARY(QT_XRENDER_LIBRARY NAMES Xrender PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(QT_XRENDER_LIBRARY) - IF(QT_XRENDER_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_XRENDER_LIBRARY}) - ENDIF(QT_XRENDER_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "xrender") - - -## Xrandr -IF(QT_QCONFIG MATCHES "xrandr") - FIND_LIBRARY(QT_XRANDR_LIBRARY NAMES Xrandr PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(QT_XRANDR_LIBRARY) - IF(QT_XRANDR_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_XRANDR_LIBRARY}) - ENDIF(QT_XRANDR_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "xrandr") - - -## Xcursor -IF(QT_QCONFIG MATCHES "xcursor") - FIND_LIBRARY(QT_XCURSOR_LIBRARY NAMES Xcursor PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(QT_XCURSOR_LIBRARY) - IF(QT_XCURSOR_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_XCURSOR_LIBRARY}) - ENDIF(QT_XCURSOR_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "xcursor") - - -## Xinerama -IF(QT_QCONFIG MATCHES "xinerama") - FIND_LIBRARY(QT_XINERAMA_LIBRARY NAMES Xinerama PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(QT_XINERAMA_LIBRARY) - IF(QT_XINERAMA_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_XINERAMA_LIBRARY}) - ENDIF(QT_XINERAMA_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "xinerama") - - -## Xfixes -IF(QT_QCONFIG MATCHES "xfixes") - FIND_LIBRARY(QT_XFIXES_LIBRARY NAMES Xfixes PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(QT_XFIXES_LIBRARY) - IF(QT_XFIXES_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_XFIXES_LIBRARY}) - ENDIF(QT_XFIXES_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "xfixes") - - -## system-freetype -IF(QT_QCONFIG MATCHES "system-freetype") - FIND_LIBRARY(QT_FREETYPE_LIBRARY NAMES freetype) - MARK_AS_ADVANCED(QT_FREETYPE_LIBRARY) - IF(QT_FREETYPE_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_FREETYPE_LIBRARY}) - ENDIF(QT_FREETYPE_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "system-freetype") - - -## fontconfig -IF(QT_QCONFIG MATCHES "fontconfig") - FIND_LIBRARY(QT_FONTCONFIG_LIBRARY NAMES fontconfig) - MARK_AS_ADVANCED(QT_FONTCONFIG_LIBRARY) - IF(QT_FONTCONFIG_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_FONTCONFIG_LIBRARY}) - ENDIF(QT_FONTCONFIG_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "fontconfig") - - -## system-zlib -IF(QT_QCONFIG MATCHES "system-zlib") - FIND_LIBRARY(QT_ZLIB_LIBRARY NAMES z) - MARK_AS_ADVANCED(QT_ZLIB_LIBRARY) - IF(QT_ZLIB_LIBRARY) - SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ${QT_ZLIB_LIBRARY}) - ENDIF(QT_ZLIB_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "system-zlib") - - -## openssl -IF(NOT Q_WS_WIN) - SET(_QT_NEED_OPENSSL 0) - IF(QT_VERSION_MINOR LESS 4 AND QT_QCONFIG MATCHES "openssl") - SET(_QT_NEED_OPENSSL 1) - ENDIF(QT_VERSION_MINOR LESS 4 AND QT_QCONFIG MATCHES "openssl") - IF(QT_VERSION_MINOR GREATER 3 AND QT_QCONFIG MATCHES "openssl-linked") - SET(_QT_NEED_OPENSSL 1) - ENDIF(QT_VERSION_MINOR GREATER 3 AND QT_QCONFIG MATCHES "openssl-linked") - IF(_QT_NEED_OPENSSL) - FIND_PACKAGE(OpenSSL) - IF(OPENSSL_LIBRARIES) - SET(QT_QTNETWORK_LIB_DEPENDENCIES ${QT_QTNETWORK_LIB_DEPENDENCIES} ${OPENSSL_LIBRARIES}) - ENDIF(OPENSSL_LIBRARIES) - ENDIF(_QT_NEED_OPENSSL) -ENDIF(NOT Q_WS_WIN) - - -## dbus -IF(QT_QCONFIG MATCHES "dbus") - - # if the dbus library isn't found, we'll assume its not required to build - # shared Qt on Linux doesn't require it - IF(NOT QT_DBUS_LIBRARY) - EXECUTE_PROCESS(COMMAND pkg-config --libs-only-L dbus-1 - OUTPUT_VARIABLE _dbus_query_output - RESULT_VARIABLE _dbus_result - ERROR_VARIABLE _dbus_query_output ) - - IF(_dbus_result MATCHES 0) - STRING(REPLACE "-L" "" _dbus_query_output "${_dbus_query_output}") - SEPARATE_ARGUMENTS(_dbus_query_output) - ELSE(_dbus_result MATCHES 0) - SET(_dbus_query_output) - ENDIF(_dbus_result MATCHES 0) - - FIND_LIBRARY(QT_DBUS_LIBRARY NAMES dbus-1 PATHS ${_dbus_query_output} ) - - IF(QT_DBUS_LIBRARY) - SET(QT_QTDBUS_LIB_DEPENDENCIES ${QT_QTDBUS_LIB_DEPENDENCIES} ${QT_DBUS_LIBRARY}) - ENDIF(QT_DBUS_LIBRARY) - - MARK_AS_ADVANCED(QT_DBUS_LIBRARY) - ENDIF(NOT QT_DBUS_LIBRARY) - -ENDIF(QT_QCONFIG MATCHES "dbus") - - -## glib -IF(QT_QCONFIG MATCHES "glib") - - # if the glib libraries aren't found, we'll assume its not required to build - # shared Qt on Linux doesn't require it - - # Qt 4.2.0+ uses glib-2.0 - IF(NOT QT_GLIB_LIBRARY OR NOT QT_GTHREAD_LIBRARY) - EXECUTE_PROCESS(COMMAND pkg-config --libs-only-L glib-2.0 gthread-2.0 - OUTPUT_VARIABLE _glib_query_output - RESULT_VARIABLE _glib_result - ERROR_VARIABLE _glib_query_output ) - - IF(_glib_result MATCHES 0) - STRING(REPLACE "-L" "" _glib_query_output "${_glib_query_output}") - SEPARATE_ARGUMENTS(_glib_query_output) - ELSE(_glib_result MATCHES 0) - SET(_glib_query_output) - ENDIF(_glib_result MATCHES 0) - - FIND_LIBRARY(QT_GLIB_LIBRARY NAMES glib-2.0 PATHS ${_glib_query_output} ) - FIND_LIBRARY(QT_GTHREAD_LIBRARY NAMES gthread-2.0 PATHS ${_glib_query_output} ) - - MARK_AS_ADVANCED(QT_GLIB_LIBRARY) - MARK_AS_ADVANCED(QT_GTHREAD_LIBRARY) - ENDIF(NOT QT_GLIB_LIBRARY OR NOT QT_GTHREAD_LIBRARY) - - IF(QT_GLIB_LIBRARY AND QT_GTHREAD_LIBRARY) - SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} - ${QT_GTHREAD_LIBRARY} ${QT_GLIB_LIBRARY}) - ENDIF(QT_GLIB_LIBRARY AND QT_GTHREAD_LIBRARY) - - - # Qt 4.5+ also links to gobject-2.0 - IF(QT_VERSION_MINOR GREATER 4) - IF(NOT QT_GOBJECT_LIBRARY) - EXECUTE_PROCESS(COMMAND pkg-config --libs-only-L gobject-2.0 - OUTPUT_VARIABLE _glib_query_output - RESULT_VARIABLE _glib_result - ERROR_VARIABLE _glib_query_output ) - - IF(_glib_result MATCHES 0) - STRING(REPLACE "-L" "" _glib_query_output "${_glib_query_output}") - SEPARATE_ARGUMENTS(_glib_query_output) - ELSE(_glib_result MATCHES 0) - SET(_glib_query_output) - ENDIF(_glib_result MATCHES 0) - - FIND_LIBRARY(QT_GOBJECT_LIBRARY NAMES gobject-2.0 PATHS ${_glib_query_output} ) - - MARK_AS_ADVANCED(QT_GOBJECT_LIBRARY) - ENDIF(NOT QT_GOBJECT_LIBRARY) - - IF(QT_GOBJECT_LIBRARY) - SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} - ${QT_GOBJECT_LIBRARY}) - ENDIF(QT_GOBJECT_LIBRARY) - ENDIF(QT_VERSION_MINOR GREATER 4) - -ENDIF(QT_QCONFIG MATCHES "glib") - - -## clock-monotonic, just see if we need to link with rt -IF(QT_QCONFIG MATCHES "clock-monotonic") - SET(CMAKE_REQUIRED_LIBRARIES_SAVE ${CMAKE_REQUIRED_LIBRARIES}) - SET(CMAKE_REQUIRED_LIBRARIES rt) - CHECK_SYMBOL_EXISTS(_POSIX_TIMERS "unistd.h;time.h" QT_POSIX_TIMERS) - SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_SAVE}) - IF(QT_POSIX_TIMERS) - FIND_LIBRARY(QT_RT_LIBRARY NAMES rt) - MARK_AS_ADVANCED(QT_RT_LIBRARY) - IF(QT_RT_LIBRARY) - SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ${QT_RT_LIBRARY}) - ENDIF(QT_RT_LIBRARY) - ENDIF(QT_POSIX_TIMERS) -ENDIF(QT_QCONFIG MATCHES "clock-monotonic") - - -IF(Q_WS_X11) - # X11 libraries Qt absolutely depends on - QT_QUERY_QMAKE(QT_LIBS_X11 "QMAKE_LIBS_X11") - SEPARATE_ARGUMENTS(QT_LIBS_X11) - FOREACH(QT_X11_LIB ${QT_LIBS_X11}) - STRING(REGEX REPLACE "-l" "" QT_X11_LIB "${QT_X11_LIB}") - SET(QT_TMP_STR "QT_X11_${QT_X11_LIB}_LIBRARY") - FIND_LIBRARY(${QT_TMP_STR} NAMES "${QT_X11_LIB}" PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(${QT_TMP_STR}) - IF(${QT_TMP_STR}) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${${QT_TMP_STR}}) - ENDIF(${QT_TMP_STR}) - ENDFOREACH(QT_X11_LIB) - - QT_QUERY_QMAKE(QT_LIBS_THREAD "QMAKE_LIBS_THREAD") - SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ${QT_LIBS_THREAD}) - - QT_QUERY_QMAKE(QMAKE_LIBS_DYNLOAD "QMAKE_LIBS_DYNLOAD") - SET (QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ${QMAKE_LIBS_DYNLOAD}) - -ENDIF(Q_WS_X11) - - -IF(Q_WS_WIN) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} imm32 winmm) - SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ws2_32) -ENDIF(Q_WS_WIN) - - -IF(Q_WS_MAC) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} "-framework Carbon") - - # Qt 4.0, 4.1, 4.2 use QuickTime - IF(QT_VERSION_MINOR LESS 3) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} "-framework QuickTime") - ENDIF(QT_VERSION_MINOR LESS 3) - - # Qt 4.2+ use AppKit - IF(QT_VERSION_MINOR GREATER 1) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} "-framework AppKit") - ENDIF(QT_VERSION_MINOR GREATER 1) - - SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} "-framework ApplicationServices") -ENDIF(Q_WS_MAC) - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/cmake/Qt4Macros.cmake kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/cmake/Qt4Macros.cmake --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/cmake/Qt4Macros.cmake 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/cmake/Qt4Macros.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,414 +0,0 @@ -# This file is included by FindQt4.cmake, don't include it directly. - -#============================================================================= -# Copyright 2005-2009 Kitware, Inc. -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distributed this file outside of CMake, substitute the full -# License text for the above reference.) - - -###################################### -# -# Macros for building Qt files -# -###################################### - - -MACRO (QT4_EXTRACT_OPTIONS _qt4_files _qt4_options) - SET(${_qt4_files}) - SET(${_qt4_options}) - SET(_QT4_DOING_OPTIONS FALSE) - FOREACH(_currentArg ${ARGN}) - IF ("${_currentArg}" STREQUAL "OPTIONS") - SET(_QT4_DOING_OPTIONS TRUE) - ELSE ("${_currentArg}" STREQUAL "OPTIONS") - IF(_QT4_DOING_OPTIONS) - LIST(APPEND ${_qt4_options} "${_currentArg}") - ELSE(_QT4_DOING_OPTIONS) - LIST(APPEND ${_qt4_files} "${_currentArg}") - ENDIF(_QT4_DOING_OPTIONS) - ENDIF ("${_currentArg}" STREQUAL "OPTIONS") - ENDFOREACH(_currentArg) -ENDMACRO (QT4_EXTRACT_OPTIONS) - - -# macro used to create the names of output files preserving relative dirs -MACRO (QT4_MAKE_OUTPUT_FILE infile prefix ext outfile ) - STRING(LENGTH ${CMAKE_CURRENT_BINARY_DIR} _binlength) - STRING(LENGTH ${infile} _infileLength) - SET(_checkinfile ${CMAKE_CURRENT_SOURCE_DIR}) - IF(_infileLength GREATER _binlength) - STRING(SUBSTRING "${infile}" 0 ${_binlength} _checkinfile) - IF(_checkinfile STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") - FILE(RELATIVE_PATH rel ${CMAKE_CURRENT_BINARY_DIR} ${infile}) - ELSE(_checkinfile STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") - FILE(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${infile}) - ENDIF(_checkinfile STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") - ELSE(_infileLength GREATER _binlength) - FILE(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${infile}) - ENDIF(_infileLength GREATER _binlength) - IF(WIN32 AND rel MATCHES "^[a-zA-Z]:") # absolute path - STRING(REGEX REPLACE "^([a-zA-Z]):(.*)$" "\\1_\\2" rel "${rel}") - ENDIF(WIN32 AND rel MATCHES "^[a-zA-Z]:") - SET(_outfile "${CMAKE_CURRENT_BINARY_DIR}/${rel}") - STRING(REPLACE ".." "__" _outfile ${_outfile}) - GET_FILENAME_COMPONENT(outpath ${_outfile} PATH) - GET_FILENAME_COMPONENT(_outfile ${_outfile} NAME_WE) - FILE(MAKE_DIRECTORY ${outpath}) - SET(${outfile} ${outpath}/${prefix}${_outfile}.${ext}) -ENDMACRO (QT4_MAKE_OUTPUT_FILE ) - - -MACRO (QT4_GET_MOC_FLAGS _moc_flags) - SET(${_moc_flags}) - GET_DIRECTORY_PROPERTY(_inc_DIRS INCLUDE_DIRECTORIES) - - FOREACH(_current ${_inc_DIRS}) - IF("${_current}" MATCHES ".framework/?$") - STRING(REGEX REPLACE "/[^/]+.framework" "" framework_path "${_current}") - SET(${_moc_flags} ${${_moc_flags}} "-F${framework_path}") - ELSE("${_current}" MATCHES ".framework/?$") - SET(${_moc_flags} ${${_moc_flags}} "-I${_current}") - ENDIF("${_current}" MATCHES ".framework/?$") - ENDFOREACH(_current ${_inc_DIRS}) - - GET_DIRECTORY_PROPERTY(_defines COMPILE_DEFINITIONS) - FOREACH(_current ${_defines}) - SET(${_moc_flags} ${${_moc_flags}} "-D${_current}") - ENDFOREACH(_current ${_defines}) - - IF(Q_WS_WIN) - SET(${_moc_flags} ${${_moc_flags}} -DWIN32) - ENDIF(Q_WS_WIN) - -ENDMACRO(QT4_GET_MOC_FLAGS) - - -# helper macro to set up a moc rule -MACRO (QT4_CREATE_MOC_COMMAND infile outfile moc_flags moc_options) - # For Windows, create a parameters file to work around command line length limit - IF (WIN32) - # Pass the parameters in a file. Set the working directory to - # be that containing the parameters file and reference it by - # just the file name. This is necessary because the moc tool on - # MinGW builds does not seem to handle spaces in the path to the - # file given with the @ syntax. - GET_FILENAME_COMPONENT(_moc_outfile_name "${outfile}" NAME) - GET_FILENAME_COMPONENT(_moc_outfile_dir "${outfile}" PATH) - IF(_moc_outfile_dir) - SET(_moc_working_dir WORKING_DIRECTORY ${_moc_outfile_dir}) - ENDIF(_moc_outfile_dir) - SET (_moc_parameters_file ${outfile}_parameters) - SET (_moc_parameters ${moc_flags} ${moc_options} -o "${outfile}" "${infile}") - FILE (REMOVE ${_moc_parameters_file}) - FOREACH(arg ${_moc_parameters}) - FILE (APPEND ${_moc_parameters_file} "${arg}\n") - ENDFOREACH(arg) - ADD_CUSTOM_COMMAND(OUTPUT ${outfile} - COMMAND ${QT_MOC_EXECUTABLE} @${_moc_outfile_name}_parameters - DEPENDS ${infile} - ${_moc_working_dir} - VERBATIM) - ELSE (WIN32) - ADD_CUSTOM_COMMAND(OUTPUT ${outfile} - COMMAND ${QT_MOC_EXECUTABLE} - ARGS ${moc_flags} ${moc_options} -o ${outfile} ${infile} - DEPENDS ${infile}) - ENDIF (WIN32) -ENDMACRO (QT4_CREATE_MOC_COMMAND) - - -MACRO (QT4_GENERATE_MOC infile outfile ) -# get include dirs and flags - QT4_GET_MOC_FLAGS(moc_flags) - GET_FILENAME_COMPONENT(abs_infile ${infile} ABSOLUTE) - QT4_CREATE_MOC_COMMAND(${abs_infile} ${outfile} "${moc_flags}" "") - SET_SOURCE_FILES_PROPERTIES(${outfile} PROPERTIES SKIP_AUTOMOC TRUE) # do not run automoc on this file - - MACRO_ADD_FILE_DEPENDENCIES(${abs_infile} ${outfile}) -ENDMACRO (QT4_GENERATE_MOC) - - -# QT4_WRAP_CPP(outfiles inputfile ... ) - -MACRO (QT4_WRAP_CPP outfiles ) - # get include dirs - QT4_GET_MOC_FLAGS(moc_flags) - QT4_EXTRACT_OPTIONS(moc_files moc_options ${ARGN}) - - FOREACH (it ${moc_files}) - GET_FILENAME_COMPONENT(it ${it} ABSOLUTE) - QT4_MAKE_OUTPUT_FILE(${it} moc_ cxx outfile) - QT4_CREATE_MOC_COMMAND(${it} ${outfile} "${moc_flags}" "${moc_options}") - SET(${outfiles} ${${outfiles}} ${outfile}) - ENDFOREACH(it) - -ENDMACRO (QT4_WRAP_CPP) - - -# QT4_WRAP_UI(outfiles inputfile ... ) - -MACRO (QT4_WRAP_UI outfiles ) - QT4_EXTRACT_OPTIONS(ui_files ui_options ${ARGN}) - - FOREACH (it ${ui_files}) - GET_FILENAME_COMPONENT(outfile ${it} NAME_WE) - GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE) - SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.h) - ADD_CUSTOM_COMMAND(OUTPUT ${outfile} - COMMAND ${QT_UIC_EXECUTABLE} - ARGS ${ui_options} -o ${outfile} ${infile} - MAIN_DEPENDENCY ${infile}) - SET(${outfiles} ${${outfiles}} ${outfile}) - ENDFOREACH (it) - -ENDMACRO (QT4_WRAP_UI) - - -# QT4_ADD_RESOURCES(outfiles inputfile ... ) - -MACRO (QT4_ADD_RESOURCES outfiles ) - QT4_EXTRACT_OPTIONS(rcc_files rcc_options ${ARGN}) - - FOREACH (it ${rcc_files}) - GET_FILENAME_COMPONENT(outfilename ${it} NAME_WE) - GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE) - GET_FILENAME_COMPONENT(rc_path ${infile} PATH) - SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${outfilename}.cxx) - # parse file for dependencies - # all files are absolute paths or relative to the location of the qrc file - FILE(READ "${infile}" _RC_FILE_CONTENTS) - STRING(REGEX MATCHALL "]*>" "" _RC_FILE "${_RC_FILE}") - STRING(REGEX MATCH "^/|([A-Za-z]:/)" _ABS_PATH_INDICATOR "${_RC_FILE}") - IF(NOT _ABS_PATH_INDICATOR) - SET(_RC_FILE "${rc_path}/${_RC_FILE}") - ENDIF(NOT _ABS_PATH_INDICATOR) - SET(_RC_DEPENDS ${_RC_DEPENDS} "${_RC_FILE}") - ENDFOREACH(_RC_FILE) - ADD_CUSTOM_COMMAND(OUTPUT ${outfile} - COMMAND ${QT_RCC_EXECUTABLE} - ARGS ${rcc_options} -name ${outfilename} -o ${outfile} ${infile} - MAIN_DEPENDENCY ${infile} - DEPENDS ${_RC_DEPENDS}) - SET(${outfiles} ${${outfiles}} ${outfile}) - ENDFOREACH (it) - -ENDMACRO (QT4_ADD_RESOURCES) - - -MACRO(QT4_ADD_DBUS_INTERFACE _sources _interface _basename) - GET_FILENAME_COMPONENT(_infile ${_interface} ABSOLUTE) - SET(_header ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.h) - SET(_impl ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.cpp) - SET(_moc ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.moc) - - GET_SOURCE_FILE_PROPERTY(_nonamespace ${_interface} NO_NAMESPACE) - IF ( _nonamespace ) - SET(_params -N -m) - ELSE ( _nonamespace ) - SET(_params -m) - ENDIF ( _nonamespace ) - - GET_SOURCE_FILE_PROPERTY(_classname ${_interface} CLASSNAME) - IF ( _classname ) - SET(_params ${_params} -c ${_classname}) - ENDIF ( _classname ) - - GET_SOURCE_FILE_PROPERTY(_include ${_interface} INCLUDE) - IF ( _include ) - SET(_params ${_params} -i ${_include}) - ENDIF ( _include ) - - ADD_CUSTOM_COMMAND(OUTPUT ${_impl} ${_header} - COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} ${_params} -p ${_basename} ${_infile} - DEPENDS ${_infile}) - - SET_SOURCE_FILES_PROPERTIES(${_impl} PROPERTIES SKIP_AUTOMOC TRUE) - - QT4_GENERATE_MOC(${_header} ${_moc}) - - SET(${_sources} ${${_sources}} ${_impl} ${_header} ${_moc}) - MACRO_ADD_FILE_DEPENDENCIES(${_impl} ${_moc}) - -ENDMACRO(QT4_ADD_DBUS_INTERFACE) - - -MACRO(QT4_ADD_DBUS_INTERFACES _sources) - FOREACH (_current_FILE ${ARGN}) - GET_FILENAME_COMPONENT(_infile ${_current_FILE} ABSOLUTE) - # get the part before the ".xml" suffix - STRING(REGEX REPLACE "(.*[/\\.])?([^\\.]+)\\.xml" "\\2" _basename ${_current_FILE}) - STRING(TOLOWER ${_basename} _basename) - QT4_ADD_DBUS_INTERFACE(${_sources} ${_infile} ${_basename}interface) - ENDFOREACH (_current_FILE) -ENDMACRO(QT4_ADD_DBUS_INTERFACES) - - -MACRO(QT4_GENERATE_DBUS_INTERFACE _header) # _customName OPTIONS -some -options ) - QT4_EXTRACT_OPTIONS(_customName _qt4_dbus_options ${ARGN}) - - GET_FILENAME_COMPONENT(_in_file ${_header} ABSOLUTE) - GET_FILENAME_COMPONENT(_basename ${_header} NAME_WE) - - IF (_customName) - SET(_target ${CMAKE_CURRENT_BINARY_DIR}/${_customName}) - ELSE (_customName) - SET(_target ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.xml) - ENDIF (_customName) - - ADD_CUSTOM_COMMAND(OUTPUT ${_target} - COMMAND ${QT_DBUSCPP2XML_EXECUTABLE} ${_qt4_dbus_options} ${_in_file} -o ${_target} - DEPENDS ${_in_file} - ) -ENDMACRO(QT4_GENERATE_DBUS_INTERFACE) - - -MACRO(QT4_ADD_DBUS_ADAPTOR _sources _xml_file _include _parentClass) # _optionalBasename _optionalClassName) - GET_FILENAME_COMPONENT(_infile ${_xml_file} ABSOLUTE) - - SET(_optionalBasename "${ARGV4}") - IF (_optionalBasename) - SET(_basename ${_optionalBasename} ) - ELSE (_optionalBasename) - STRING(REGEX REPLACE "(.*[/\\.])?([^\\.]+)\\.xml" "\\2adaptor" _basename ${_infile}) - STRING(TOLOWER ${_basename} _basename) - ENDIF (_optionalBasename) - - SET(_optionalClassName "${ARGV5}") - SET(_header ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.h) - SET(_impl ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.cpp) - SET(_moc ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.moc) - - IF(_optionalClassName) - ADD_CUSTOM_COMMAND(OUTPUT ${_impl} ${_header} - COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} -m -a ${_basename} -c ${_optionalClassName} -i ${_include} -l ${_parentClass} ${_infile} - DEPENDS ${_infile} - ) - ELSE(_optionalClassName) - ADD_CUSTOM_COMMAND(OUTPUT ${_impl} ${_header} - COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} -m -a ${_basename} -i ${_include} -l ${_parentClass} ${_infile} - DEPENDS ${_infile} - ) - ENDIF(_optionalClassName) - - QT4_GENERATE_MOC(${_header} ${_moc}) - SET_SOURCE_FILES_PROPERTIES(${_impl} PROPERTIES SKIP_AUTOMOC TRUE) - MACRO_ADD_FILE_DEPENDENCIES(${_impl} ${_moc}) - - SET(${_sources} ${${_sources}} ${_impl} ${_header} ${_moc}) -ENDMACRO(QT4_ADD_DBUS_ADAPTOR) - - -MACRO(QT4_AUTOMOC) - QT4_GET_MOC_FLAGS(_moc_INCS) - - SET(_matching_FILES ) - FOREACH (_current_FILE ${ARGN}) - - GET_FILENAME_COMPONENT(_abs_FILE ${_current_FILE} ABSOLUTE) - # if "SKIP_AUTOMOC" is set to true, we will not handle this file here. - # This is required to make uic work correctly: - # we need to add generated .cpp files to the sources (to compile them), - # but we cannot let automoc handle them, as the .cpp files don't exist yet when - # cmake is run for the very first time on them -> however the .cpp files might - # exist at a later run. at that time we need to skip them, so that we don't add two - # different rules for the same moc file - GET_SOURCE_FILE_PROPERTY(_skip ${_abs_FILE} SKIP_AUTOMOC) - - IF ( NOT _skip AND EXISTS ${_abs_FILE} ) - - FILE(READ ${_abs_FILE} _contents) - - GET_FILENAME_COMPONENT(_abs_PATH ${_abs_FILE} PATH) - - STRING(REGEX MATCHALL "# *include +[^ ]+\\.moc[\">]" _match "${_contents}") - IF(_match) - FOREACH (_current_MOC_INC ${_match}) - STRING(REGEX MATCH "[^ <\"]+\\.moc" _current_MOC "${_current_MOC_INC}") - - GET_FILENAME_COMPONENT(_basename ${_current_MOC} NAME_WE) - IF(EXISTS ${_abs_PATH}/${_basename}.hpp) - SET(_header ${_abs_PATH}/${_basename}.hpp) - ELSE(EXISTS ${_abs_PATH}/${_basename}.hpp) - SET(_header ${_abs_PATH}/${_basename}.h) - ENDIF(EXISTS ${_abs_PATH}/${_basename}.hpp) - SET(_moc ${CMAKE_CURRENT_BINARY_DIR}/${_current_MOC}) - QT4_CREATE_MOC_COMMAND(${_header} ${_moc} "${_moc_INCS}" "") - MACRO_ADD_FILE_DEPENDENCIES(${_abs_FILE} ${_moc}) - ENDFOREACH (_current_MOC_INC) - ENDIF(_match) - ENDIF ( NOT _skip AND EXISTS ${_abs_FILE} ) - ENDFOREACH (_current_FILE) -ENDMACRO(QT4_AUTOMOC) - - -MACRO(QT4_CREATE_TRANSLATION _qm_files) - QT4_EXTRACT_OPTIONS(_lupdate_files _lupdate_options ${ARGN}) - SET(_my_sources) - SET(_my_dirs) - SET(_my_tsfiles) - SET(_ts_pro) - FOREACH (_file ${_lupdate_files}) - GET_FILENAME_COMPONENT(_ext ${_file} EXT) - GET_FILENAME_COMPONENT(_abs_FILE ${_file} ABSOLUTE) - IF(_ext MATCHES "ts") - LIST(APPEND _my_tsfiles ${_abs_FILE}) - ELSE(_ext MATCHES "ts") - IF(NOT _ext) - LIST(APPEND _my_dirs ${_abs_FILE}) - ELSE(NOT _ext) - LIST(APPEND _my_sources ${_abs_FILE}) - ENDIF(NOT _ext) - ENDIF(_ext MATCHES "ts") - ENDFOREACH(_file) - FOREACH(_ts_file ${_my_tsfiles}) - IF(_my_sources) - # make a .pro file to call lupdate on, so we don't make our commands too - # long for some systems - GET_FILENAME_COMPONENT(_ts_name ${_ts_file} NAME_WE) - SET(_ts_pro ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_ts_name}_lupdate.pro) - SET(_pro_srcs) - FOREACH(_pro_src ${_my_sources}) - SET(_pro_srcs "${_pro_srcs} \"${_pro_src}\"") - ENDFOREACH(_pro_src ${_my_sources}) - FILE(WRITE ${_ts_pro} "SOURCES = ${_pro_srcs}") - ENDIF(_my_sources) - ADD_CUSTOM_COMMAND(OUTPUT ${_ts_file} - COMMAND ${QT_LUPDATE_EXECUTABLE} - ARGS ${_lupdate_options} ${_ts_pro} ${_my_dirs} -ts ${_ts_file} - DEPENDS ${_my_sources} ${_ts_pro}) - ENDFOREACH(_ts_file) - QT4_ADD_TRANSLATION(${_qm_files} ${_my_tsfiles}) -ENDMACRO(QT4_CREATE_TRANSLATION) - - -MACRO(QT4_ADD_TRANSLATION _qm_files) - FOREACH (_current_FILE ${ARGN}) - GET_FILENAME_COMPONENT(_abs_FILE ${_current_FILE} ABSOLUTE) - GET_FILENAME_COMPONENT(qm ${_abs_FILE} NAME_WE) - GET_SOURCE_FILE_PROPERTY(output_location ${_abs_FILE} OUTPUT_LOCATION) - IF(output_location) - FILE(MAKE_DIRECTORY "${output_location}") - SET(qm "${output_location}/${qm}.qm") - ELSE(output_location) - SET(qm "${CMAKE_CURRENT_BINARY_DIR}/${qm}.qm") - ENDIF(output_location) - - ADD_CUSTOM_COMMAND(OUTPUT ${qm} - COMMAND ${QT_LRELEASE_EXECUTABLE} - ARGS ${_abs_FILE} -qm ${qm} - DEPENDS ${_abs_FILE} - ) - SET(${_qm_files} ${${_qm_files}} ${qm}) - ENDFOREACH (_current_FILE) -ENDMACRO(QT4_ADD_TRANSLATION) diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/CMakeLists.txt kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/CMakeLists.txt --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -project(qmlbreadcrumbnavigation) - -cmake_minimum_required(VERSION 2.6) - -set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) - -# Not depending on KDE here for easier portability. -find_package(Qt4 REQUIRED) - -include_directories( - ${QT_INCLUDES} - ${QT_QTGUI_INCLUDE_DIR} - ${QT_QTSQL_INCLUDE_DIR} - ${QT_QTDECLARATIVE_INCLUDE_DIR} - ${PROJECT_BINARY_DIR} -) - -set(app_SRCS - breadcrumbnavigation.cpp - breadcrumbnavigationcontext.cpp - checkableitemproxymodel.cpp - dynamictreemodel.cpp - dynamictreewidget.cpp - qmllistselectionmodel.cpp - kresettingproxymodel.cpp - mainwindow.cpp - main.cpp - kselectionproxymodel.cpp - kbreadcrumbselectionmodel.cpp - kmodelindexproxymapper.cpp - kproxyitemselectionmodel.cpp -) - -set(app_qml_SRCS - mainview.qml - BreadcrumbNavigationView.qml - ListDelegate.qml -) - -FILE(GLOB _images "*png") -foreach( _image ${_images}) - execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${_image}" "${CMAKE_BINARY_DIR}") -endforeach() - - -foreach( qml_src ${app_qml_SRCS}) - execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/${qml_src}" "${CMAKE_BINARY_DIR}/${qml_src}") -endforeach() - -qt4_automoc( app_MOC_SRCS ${app_SRCS} ) - -add_executable(qml_nav - ${app_SRCS} -) - -target_link_libraries( - qml_nav - ${QT_QTCORE_LIBRARIES} - ${QT_QTGUI_LIBRARIES} - ${QT_QTDECLARATIVE_LIBRARIES} -) Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/currentindicator.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/currentindicator.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/dividing-line-horizontal.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/dividing-line-horizontal.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/dividing-line.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/dividing-line.png differ diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreemodel.cpp kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreemodel.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreemodel.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreemodel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,966 +0,0 @@ -/* - Copyright (c) 2009 Stephen Kelly - - 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 "dynamictreemodel.h" - -#include -#include -#include -#include - -#include - -#include - -// If DUMPTREE is defined, ModelInsertCommand dumps the tree of what it is inserting. -// #define DUMPTREE -#ifdef DUMPTREE -#include -#endif - -DynamicTreeModel::DynamicTreeModel(QObject *parent) - : QAbstractItemModel(parent), - nextId(1) -{ -} - -QModelIndex DynamicTreeModel::index(int row, int column, const QModelIndex &parent) const -{ -// if (column != 0) -// return QModelIndex(); - - if ( column < 0 || row < 0 ) - return QModelIndex(); - - QList > childIdColumns = m_childItems.value(parent.internalId()); - - - if (childIdColumns.size() == 0) - return QModelIndex(); - - if (column >= childIdColumns.size()) - return QModelIndex(); - - QList rowIds = childIdColumns.at(column); - - if ( row >= rowIds.size()) - return QModelIndex(); - - qint64 id = rowIds.at(row); - - return createIndex(row, column, reinterpret_cast(id)); - -} - -qint64 DynamicTreeModel::findParentId(qint64 searchId) const -{ - if (searchId <= 0) - return -1; - - QHashIterator > > i(m_childItems); - while (i.hasNext()) - { - i.next(); - QListIterator > j(i.value()); - while (j.hasNext()) - { - QList l = j.next(); - if (l.contains(searchId)) - { - return i.key(); - } - } - } - return -1; -} - -QModelIndex DynamicTreeModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - return QModelIndex(); - - qint64 searchId = index.internalId(); - qint64 parentId = findParentId(searchId); - // Will never happen for valid index, but what the hey... - if (parentId <= 0) - return QModelIndex(); - - qint64 grandParentId = findParentId(parentId); - if (grandParentId < 0) - grandParentId = 0; - - int column = 0; - QList childList = m_childItems.value(grandParentId).at(column); - - int row = childList.indexOf(parentId); - - return createIndex(row, column, reinterpret_cast(parentId)); - -} - -int DynamicTreeModel::rowCount(const QModelIndex &index ) const -{ - QList > cols = m_childItems.value(index.internalId()); - - if (cols.size() == 0 ) - return 0; - - if (index.column() > 0) - return 0; - - return cols.at(0).size(); -} - -int DynamicTreeModel::columnCount(const QModelIndex &index ) const -{ -// Q_UNUSED(index); - return m_childItems.value(index.internalId()).size(); -} - -static const char * const accounts[] = { - "GMail", - "Hotmail", - "KDE", - "Work", - "Squash", - "Cycling", - "Climbing", - "Mailing Lists" -}; - -QVariant DynamicTreeModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if ( DynamicTreeModelId == role ) - return index.internalId(); - - if (Qt::DisplayRole == role || Qt::EditRole == role) - { - if (!index.parent().isValid()) - { - if ( index.row() > ( sizeof accounts / sizeof *accounts ) - 1) - return "Account" + m_items.value(index.internalId()); - return QString(accounts[index.row()]); - } - if (index.row() == 1 && !index.parent().parent().isValid()) - return "Inbox"; - - return "Subfolder" + m_items.value(index.internalId()); - } - return QVariant(); -} - - -bool DynamicTreeModel::setData(const QModelIndex& index, const QVariant& value, int role) -{ - if (role == Qt::EditRole) - { - m_items[index.internalId()] = value.toString(); - dataChanged(index, index); - return true; - } - - return QAbstractItemModel::setData(index, value, role); -} - -void DynamicTreeModel::clear() -{ - beginResetModel(); - m_items.clear(); - m_childItems.clear(); - nextId = 1; - endResetModel(); -} - - -bool DynamicTreeModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int _column, const QModelIndex& parent) -{ - Q_UNUSED(action); - Q_UNUSED(_column); - QByteArray encoded = data->data(mimeTypes().first()); - - QHash > movedItems; - bool ok; - qint64 id; - int _row; - static const int column = 0; - QHash > >::const_iterator it; - foreach(const QByteArray &ba, encoded.split('\0')) - { - id = ba.toInt(&ok); - Q_ASSERT(ok); - - _row = -1; - for (it = m_childItems.constBegin(); it != m_childItems.constEnd(); ++it) - { - _row = it.value().first().indexOf(id); - if (_row < 0) - continue; - movedItems[createIndex(_row, column, reinterpret_cast(id)).parent()].append(_row); - break; - } - Q_ASSERT(_row >= 0); - if (_row < 0) - return false; - } - - const int destRow = row < 0 ? 0 : row; - const QList destPath = indexToPath(parent); - - QList srcPath; - QModelIndex srcParent; - QHash >::iterator src_parent_it = movedItems.begin(); - int startRow = 0; - int endRow = 0; - int nextMovedRow = 0; - - QList rowsMoved; - QList::iterator src_row_it; - QList::iterator rows_moved_end; - QList moveCommands; - - for ( ; src_parent_it != movedItems.end(); ++src_parent_it) - { - srcParent = src_parent_it.key(); - srcPath = indexToPath(srcParent); - - rowsMoved = src_parent_it.value(); - qSort(rowsMoved); - src_row_it = rowsMoved.begin(); - rows_moved_end = rowsMoved.end(); - startRow = *src_row_it; - endRow = startRow; - ++src_row_it; - - if (src_row_it == rows_moved_end) - { - moveCommands.prepend(getMoveCommand(srcPath, startRow, endRow)); - continue; - } - - for ( ; src_row_it != rows_moved_end; ++src_row_it) - { - nextMovedRow = *src_row_it; - - if (nextMovedRow == endRow + 1) - { - ++endRow; - } else { - Q_ASSERT(nextMovedRow > endRow + 1); - moveCommands.prepend(getMoveCommand(srcPath, startRow, endRow)); - startRow = nextMovedRow; - endRow = nextMovedRow; - - if ((src_row_it + 1) == rows_moved_end) - moveCommands.prepend(getMoveCommand(srcPath, startRow, endRow)); - - } - } - } - - QPersistentModelIndex destParent = parent; - QPersistentModelIndex destRowIndex = index(destRow, column, parent); - - ModelMoveCommand *firstCommand = moveCommands.takeFirst(); - firstCommand->setDestAncestors(indexToPath(parent)); - firstCommand->setDestRow(destRow); - firstCommand->doCommand(); - - if (!destRowIndex.isValid()) - destRowIndex = index(destRow, column, parent); - - Q_ASSERT(destRowIndex.isValid()); - int offset = firstCommand->endRow() - firstCommand->startRow() + 1; - foreach(ModelMoveCommand *moveCommand, moveCommands) - { - moveCommand->setDestAncestors(indexToPath(destParent)); - moveCommand->setDestRow(destRowIndex.row() + offset); - moveCommand->doCommand(); - offset = moveCommand->endRow() - moveCommand->startRow() + 1; - } - - return false; -} - -ModelMoveCommand* DynamicTreeModel::getMoveCommand(const QList &srcPath, int startRow, int endRow) -{ - ModelMoveCommand *moveCommand = new ModelMoveCommand(this, this); - moveCommand->setAncestorRowNumbers(srcPath); - moveCommand->setStartRow(startRow); - moveCommand->setEndRow(endRow); - return moveCommand; -} - -Qt::ItemFlags DynamicTreeModel::flags(const QModelIndex& index) const -{ - Qt::ItemFlags flags = QAbstractItemModel::flags(index); - if (index.isValid()) - return flags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable; - return flags; -} - -Qt::DropActions DynamicTreeModel::supportedDropActions() const -{ - return Qt::MoveAction; -} - -QStringList DynamicTreeModel::mimeTypes() const -{ - QStringList types; - types << QLatin1String("application/x-dynamictreemodel-itemlist"); - return types; -} - -QMimeData* DynamicTreeModel::mimeData(const QModelIndexList& indexes) const -{ - QMimeData *data = new QMimeData(); - QByteArray itemData; - QModelIndexList::const_iterator it = indexes.begin(); - const QModelIndexList::const_iterator end = indexes.end(); - while(it != end) - { - itemData.append(QByteArray::number(it->internalId())); - ++it; - if (it != end) - itemData.append('\0'); - } - data->setData(mimeTypes().first(), itemData); - return data; -} - -QList DynamicTreeModel::indexToPath(const QModelIndex &_idx) const -{ - QList list; - QModelIndex idx = _idx; - while (idx.isValid()) - { - list.prepend(idx.row()); - idx = idx.parent(); - } - return list; -} - -QModelIndexList DynamicTreeModel::match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const -{ - if (role != DynamicTreeModelId) - return QAbstractItemModel::match(start, role, value, hits, flags); - - qint64 id = value.toLongLong(); - - QHash > >::const_iterator it = m_childItems.constBegin(); - const QHash > >::const_iterator end = m_childItems.constEnd(); - - QList > items; - QList >::const_iterator itemIt; - QList >::const_iterator itemEnd; - int foundIndexRow; - for ( ; it != end; ++it) - { - items = it.value(); - itemEnd = items.constEnd(); - for (itemIt = items.constBegin(); itemIt != itemEnd; ++itemIt) - { - foundIndexRow = itemIt->indexOf(id); - if (foundIndexRow != -1) - { - static const int column = 0; - return QModelIndexList() << createIndex(foundIndexRow, column, reinterpret_cast(id)); - } - } - } - return QModelIndexList(); -} - -ModelChangeCommand::ModelChangeCommand( DynamicTreeModel *model, QObject *parent ) - : QObject(parent), m_model(model), m_startRow(-1), m_endRow(-1), m_numCols(1) -{ - -} - -QModelIndex ModelChangeCommand::findIndex(const QList &rows) const -{ - const int col = 0; - QModelIndex parent = QModelIndex(); - QListIterator i(rows); - while (i.hasNext()) - { - parent = m_model->index(i.next(), col, parent); - Q_ASSERT(parent.isValid()); - } - return parent; -} - -ModelInsertCommand::ModelInsertCommand(DynamicTreeModel *model, QObject *parent ) - : ModelChangeCommand(model, parent) -{ - -} - -QList ModelInsertCommand::tokenize(const QString& treeString) const -{ - QStringList parts = treeString.split("-"); - - QList tokens; - - const QStringList::const_iterator begin = parts.constBegin(); - const QStringList::const_iterator end = parts.constEnd(); - - QStringList::const_iterator it = begin; - ++it; - for (; it != end; ++it) - { - Token token; - if (it->trimmed().isEmpty()) - { - token.type = Token::Branch; - } else { - token.type = Token::Leaf; - token.content = *it; - } - tokens.append(token); - } - return tokens; -} - -void ModelInsertCommand::interpret(const QString& treeString) -{ - m_treeString = treeString; - - QList depths = getDepths(m_treeString); - - int size = 0; - qCount(depths, 0, size); - Q_ASSERT(size != 0); - - m_endRow = m_startRow + size - 1; -} - -QList ModelInsertCommand::getDepths(const QString& treeString) const -{ - int depth = 0; - QList depths; - -#ifdef DUMPTREE - int id = 1; -#endif - - QList tokens = tokenize(treeString); - while(!tokens.isEmpty()) - { - Token token = tokens.takeFirst(); - - if (token.type == Token::Branch) - { - ++depth; - continue; - } - Q_ASSERT(token.type == Token::Leaf); - - depths.append(depth); -#ifdef DUMPTREE - std::cout << "\""; - for (int i = 0; i <= depth; ++i) - std::cout << " -"; - std::cout << " " << id++ << "\"" << std::endl; -#endif - depth = 0; - } - - return depths; -} - -void ModelInsertCommand::doCommand() -{ - QModelIndex parent = findIndex(m_rowNumbers); - - if (!m_treeString.isEmpty()) - { - QList depths = getDepths(m_treeString); - - int size = 0; - qCount(depths, 0, size); - Q_ASSERT(size != 0); - m_endRow = m_startRow + size - 1; - } - m_model->beginInsertRows(parent, m_startRow, m_endRow); - if (!m_treeString.isEmpty()) - { - doInsertTree(parent); - } else { - qint64 parentId = parent.internalId(); - - for (int row = m_startRow; row <= m_endRow; row++) - { - for(int col = 0; col < m_numCols; col++ ) - { - if (m_model->m_childItems[parentId].size() <= col) - { - m_model->m_childItems[parentId].append(QList()); - } - qint64 id = m_model->newId(); - QString name = QString::number(id); - - m_model->m_items.insert(id, name); - m_model->m_childItems[parentId][col].insert(row, id); - - } - } - } - m_model->endInsertRows(); -} - -void ModelInsertCommand::doInsertTree(const QModelIndex &fragmentParent) -{ - static const int column = 0; - - QList depths = getDepths(m_treeString); - - qint64 fragmentParentIdentifier = fragmentParent.internalId(); - if (m_model->m_childItems[fragmentParentIdentifier].size() <= column) - m_model->m_childItems[fragmentParentIdentifier].append(QList()); - - QList::const_iterator it = depths.constBegin(); - const QList::const_iterator end = depths.constEnd(); - - QList recentParents; - recentParents.append(fragmentParentIdentifier); - - qint64 lastId = 0; - qint64 id; - QString name; - int depth = 0; - int row = m_startRow; - Q_ASSERT(*it == depth); - - QList rows; - rows.append(row); - - for( ; it != end; ++it) - { - id = m_model->newId(); - if (*it > depth) - { - Q_ASSERT(*it == depth + 1); - fragmentParentIdentifier = lastId; - if (recentParents.size() == *it) - recentParents.append(fragmentParentIdentifier); - else - recentParents[*it] = fragmentParentIdentifier; - - ++depth; - - } else if ( *it < depth ) - { - fragmentParentIdentifier = recentParents.at(*it); - depth = (*it); - } - - if (m_model->m_childItems[fragmentParentIdentifier].size() <= column) - { - m_model->m_childItems[fragmentParentIdentifier].append(QList()); - } - if (rows.size() == depth) - rows.append(0); - - m_model->m_items.insert(id, QString::number(id)); - m_model->m_childItems[fragmentParentIdentifier][column].insert(rows[depth]++, id); - lastId = id; - } -} - - -ModelInsertAndRemoveQueuedCommand::ModelInsertAndRemoveQueuedCommand(DynamicTreeModel* model, QObject* parent) - : ModelChangeCommand(model, parent) -{ - qRegisterMetaType("QModelIndex"); -} - -void ModelInsertAndRemoveQueuedCommand::queuedBeginInsertRows(const QModelIndex& parent, int start, int end) -{ - m_model->beginInsertRows(parent, start, end); -} - -void ModelInsertAndRemoveQueuedCommand::queuedEndInsertRows() -{ - m_model->endInsertRows(); -} - -void ModelInsertAndRemoveQueuedCommand::queuedBeginRemoveRows(const QModelIndex& parent, int start, int end) -{ - m_model->beginRemoveRows(parent, start, end); -} - -void ModelInsertAndRemoveQueuedCommand::queuedEndRemoveRows() -{ - m_model->endRemoveRows(); -} - -void ModelInsertAndRemoveQueuedCommand::purgeItem(qint64 parent) -{ - QList > childItemRows = m_model->m_childItems.value(parent); - - if (childItemRows.size() > 0) - { - for (int col = 0; col < m_numCols; col++) - { - QList childItems = childItemRows[col]; - foreach(qint64 item, childItems) - { - purgeItem(item); - m_model->m_childItems[parent][col].removeOne(item); - } - } - } - m_model->m_items.remove(parent); -} - -void ModelInsertAndRemoveQueuedCommand::doCommand() -{ - QModelIndex parent = findIndex(m_rowNumbers); - - connect (this, SIGNAL(beginInsertRows(QModelIndex,int,int)), SLOT(queuedBeginInsertRows(QModelIndex,int,int)), Qt::QueuedConnection); - connect (this, SIGNAL(endInsertRows()), SLOT(queuedEndInsertRows()), Qt::QueuedConnection); - connect (this, SIGNAL(beginRemoveRows(QModelIndex,int,int)), SLOT(queuedBeginRemoveRows(QModelIndex,int,int)), Qt::QueuedConnection); - connect (this, SIGNAL(endRemoveRows()), SLOT(queuedEndRemoveRows()), Qt::QueuedConnection); - - emit beginInsertRows(parent, m_startRow, m_endRow); -// m_model->beginInsertRows(parent, m_startRow, m_endRow); - qint64 parentId = parent.internalId(); - for (int row = m_startRow; row <= m_endRow; row++) - { - for(int col = 0; col < m_numCols; col++ ) - { - if (m_model->m_childItems[parentId].size() <= col) - { - m_model->m_childItems[parentId].append(QList()); - } - qint64 id = m_model->newId(); - QString name = QString::number(id); - - m_model->m_items.insert(id, name); - m_model->m_childItems[parentId][col].insert(row, id); - - } - } - - emit endInsertRows(); -// m_model->endInsertRows(); - - emit beginRemoveRows(parent, m_startRow, m_endRow); -// m_model->beginRemoveRows(parent, m_startRow, m_endRow); - for(int col = 0; col < m_numCols; col++ ) - { - QList childItems = m_model->m_childItems.value(parentId).value(col); - for (int row = m_startRow; row <= m_endRow; row++) - { - qint64 item = childItems[row]; - purgeItem(item); - m_model->m_childItems[parentId][col].removeOne(item); - } - } - emit endRemoveRows(); -// m_model->endRemoveRows(); - -} - -ModelRemoveCommand::ModelRemoveCommand(DynamicTreeModel *model, QObject *parent ) - : ModelChangeCommand(model, parent) -{ - -} - -void ModelRemoveCommand::doCommand() -{ - QModelIndex parent = findIndex(m_rowNumbers); - m_model->beginRemoveRows(parent, m_startRow, m_endRow); - qint64 parentId = parent.internalId(); - for(int col = 0; col < m_numCols; col++ ) - { - QList childItems = m_model->m_childItems.value(parentId).value(col); - for (int row = m_startRow; row <= m_endRow; row++) - { - qint64 item = childItems[row]; - purgeItem(item); - m_model->m_childItems[parentId][col].removeOne(item); - } - } - m_model->endRemoveRows(); -} - -void ModelRemoveCommand::purgeItem(qint64 parent) -{ - QList > childItemRows = m_model->m_childItems.value(parent); - - if (childItemRows.size() > 0) - { - for (int col = 0; col < m_numCols; col++) - { - QList childItems = childItemRows[col]; - foreach(qint64 item, childItems) - { - purgeItem(item); - m_model->m_childItems[parent][col].removeOne(item); - } - } - } - m_model->m_items.remove(parent); -} - - -ModelDataChangeCommand::ModelDataChangeCommand(DynamicTreeModel *model, QObject *parent) - : ModelChangeCommand(model, parent), m_startColumn(0) -{ - -} - -void ModelDataChangeCommand::doCommand() -{ - QModelIndex parent = findIndex(m_rowNumbers); - QModelIndex topLeft = m_model->index(m_startRow, m_startColumn, parent); - QModelIndex bottomRight = m_model->index(m_endRow, m_numCols - 1, parent); - - QList > childItems = m_model->m_childItems[parent.internalId()]; - - - for (int col = m_startColumn; col < m_startColumn + m_numCols; col++) - { - for (int row = m_startRow; row <= m_endRow; row++ ) - { - QString name = QString::number( m_model->newId() ); - m_model->m_items[childItems[col][row]] = name; - } - } - m_model->dataChanged(topLeft, bottomRight); -} - - -ModelMoveCommand::ModelMoveCommand(DynamicTreeModel *model, QObject *parent) -: ModelChangeCommand(model, parent) -{ - -} - -bool ModelMoveCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) -{ - return m_model->beginMoveRows(srcParent, srcStart, srcEnd, destParent, destRow); -} - -void ModelMoveCommand::doCommand() -{ - QModelIndex srcParent = findIndex(m_rowNumbers); - QModelIndex destParent = findIndex(m_destRowNumbers); - - if (!emitPreSignal(srcParent, m_startRow, m_endRow, destParent, m_destRow)) - { - return; - } - - for (int column = 0; column < m_numCols; ++column) - { - QList l = m_model->m_childItems.value(srcParent.internalId())[column].mid(m_startRow, m_endRow - m_startRow + 1 ); - - for (int i = m_startRow; i <= m_endRow ; i++) - { - m_model->m_childItems[srcParent.internalId()][column].removeAt(m_startRow); - } - int d; - if (m_destRow < m_startRow) - d = m_destRow; - else - { - if (srcParent == destParent) - d = m_destRow - (m_endRow - m_startRow + 1); - else - d = m_destRow - (m_endRow - m_startRow); - } - - foreach(const qint64 id, l) - { - - if (!m_model->m_childItems.contains(destParent.internalId())) - { - m_model->m_childItems[destParent.internalId()].append(QList()); - } - - m_model->m_childItems[destParent.internalId()][column].insert(d++, id); - } - } - - emitPostSignal(); -} - -void ModelMoveCommand::emitPostSignal() -{ - m_model->endMoveRows(); -} - - -ModelMoveLayoutChangeCommand::ModelMoveLayoutChangeCommand(DynamicTreeModel* model, QObject* parent): ModelMoveCommand(model, parent) -{ - -} - -ModelMoveLayoutChangeCommand::~ModelMoveLayoutChangeCommand() -{ - -} - -bool ModelMoveLayoutChangeCommand::emitPreSignal(const QModelIndex& srcParent, int srcStart, int srcEnd, const QModelIndex& destParent, int destRow) -{ - m_model->layoutAboutToBeChanged(); - - const int column = 0; - - for (int row = srcStart; row <= srcEnd; ++row) - { - m_beforeMoveList << m_model->index(row, column, srcParent); - } - - if (srcParent != destParent) - { - for (int row = srcEnd + 1; row < m_model->rowCount(srcParent); ++row) - { - m_beforeMoveList << m_model->index(row, column, srcParent); - } - for (int row = destRow; row < m_model->rowCount(destParent); ++row) - { - m_beforeMoveList << m_model->index(row, column, destParent); - } - } else { - if (destRow < srcStart) - { - for (int row = destRow; row < srcStart; ++row) - { - m_beforeMoveList << m_model->index(row, column, srcParent); - } - } else { - for (int row = srcStart + (srcEnd - srcStart + 1); row < destRow; ++row) - { - m_beforeMoveList << m_model->index(row, column, srcParent); - } - } - } - // We assume that the move was legal here. - return true; -} - -void ModelMoveLayoutChangeCommand::emitPostSignal() -{ - int srcStart = m_startRow; - int srcEnd = m_endRow; - int destRow = m_destRow; - - // Moving indexes may affect the m_rowNumbers and m_destRowNumbers. - // Instead of adjusting them programmatically, the test writer must specify them if they change. - - const QList sourceRowNumbers = m_endOfMoveSourceAncestors.isEmpty() ? m_rowNumbers : m_endOfMoveSourceAncestors; - QModelIndex srcParent = findIndex(sourceRowNumbers); - - const QList destRowNumbers = m_endOfMoveDestAncestors.isEmpty() ? m_destRowNumbers : m_endOfMoveDestAncestors; - QModelIndex destParent = findIndex(destRowNumbers); - - const int column = 0; - - QModelIndexList afterMoveList; - - if (srcParent != destParent) - { - for (int row = destRow; row <= (destRow + (srcEnd - srcStart)); ++row) - { - afterMoveList << m_model->index(row, column, destParent); - } - for (int row = srcStart; row < m_model->rowCount(srcParent); ++row) - { - afterMoveList << m_model->index(row, column, srcParent); - } - for (int row = destRow + (srcEnd - srcStart + 1); row < m_model->rowCount(destParent); ++row) - { - afterMoveList << m_model->index(row, column, destParent); - } - } else { - if (destRow < srcStart) - { - for (int row = srcStart; row <= srcEnd; ++row) - { - afterMoveList << m_model->index(destRow + (srcStart - row), column, destParent); - } - } else { - for (int row = srcStart; row <= srcEnd; ++row) - { - afterMoveList << m_model->index(destRow + (srcStart - row - 1), column, destParent); - } - } - if (destRow < srcStart) - { - for (int row = destRow + 1; row <= srcStart; ++row) - { - afterMoveList << m_model->index(row, column, srcParent); - } - } else { - for (int row = srcStart + (srcEnd - srcStart + 1); row < (srcStart + (destRow - srcEnd)); ++row) - { - afterMoveList << m_model->index(row - (srcEnd - srcStart + 1), column, srcParent); - } - } - } - - m_model->changePersistentIndexList(m_beforeMoveList, afterMoveList); - m_beforeMoveList.clear(); - m_model->layoutChanged(); - - -} - -ModelResetCommand::ModelResetCommand(DynamicTreeModel* model, QObject* parent) - : ModelChangeCommand(model, parent) -{ - -} - -ModelResetCommand::~ModelResetCommand() -{ - -} - -void ModelResetCommand::setInitialTree(const QString& treeString) -{ - m_treeString = treeString; -} - -void ModelResetCommand::doCommand() -{ - m_model->beginResetModel(); - bool blocked = m_model->blockSignals(true); - m_model->clear(); - if (!m_treeString.isEmpty()) - { - ModelInsertCommand *ins = new ModelInsertCommand(m_model); - ins->setStartRow(0); - ins->interpret(m_treeString); - ins->doCommand(); - } - m_model->blockSignals(blocked); - m_model->endResetModel(); -} - - - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreemodel.h kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreemodel.h --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreemodel.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreemodel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,334 +0,0 @@ -/* - Copyright (c) 2009 Stephen Kelly - - 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 DYNAMICTREEMODEL_H -#define DYNAMICTREEMODEL_H - -#include - -#include -#include - -#include - -#include "indexfinder.h" - -template class QList; - -class ModelMoveCommand; - -class DynamicTreeModel : public QAbstractItemModel -{ - Q_OBJECT -public: - enum Roles - { - DynamicTreeModelId = Qt::UserRole, - - LastRole - }; - - explicit DynamicTreeModel(QObject *parent = 0); - - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex &index) const; - int rowCount(const QModelIndex &index = QModelIndex()) const; - int columnCount(const QModelIndex &index = QModelIndex()) const; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); - - bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent); - Qt::ItemFlags flags(const QModelIndex& index) const; - Qt::DropActions supportedDropActions() const; - QStringList mimeTypes() const; - QMimeData* mimeData(const QModelIndexList& indexes) const; - QModelIndexList match(const QModelIndex& start, int role, const QVariant& value, int hits = 1, - Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith | Qt::MatchWrap)) const; - - - void clear(); - QList indexToPath(const QModelIndex &idx) const; - ModelMoveCommand* getMoveCommand(const QList &srcPath, int startRow, int endRow); - -protected slots: - - /** - Finds the parent id of the string with id @p searchId. - - Returns -1 if not found. - */ - qint64 findParentId(qint64 searchId) const; - -private: - QHash m_items; - QHash > > m_childItems; - qint64 nextId; - qint64 newId() { return nextId++; }; - - QModelIndex m_nextParentIndex; - int m_nextRow; - - int m_depth; - int maxDepth; - - friend class ModelInsertCommand; - friend class ModelInsertWithDescendantsCommand; - friend class ModelRemoveCommand; - friend class ModelDataChangeCommand; - friend class ModelMoveCommand; - friend class ModelMoveLayoutChangeCommand; - friend class ModelResetCommand; -// friend class ModelSortIndexCommand; - friend class ModelSortIndexLayoutChangeCommand; - friend class ModelInsertAndRemoveQueuedCommand; - -}; - - -class ModelChangeCommand : public QObject -{ - Q_OBJECT -public: - - ModelChangeCommand( DynamicTreeModel *model, QObject *parent = 0 ); - - virtual ~ModelChangeCommand() {} - - void setAncestorRowNumbers(const QList &rowNumbers) { m_rowNumbers = rowNumbers; } - QList srcAncestors() const { return m_rowNumbers; } - - QModelIndex findIndex(const QList &rows) const; - - void setStartRow(int row) { m_startRow = row; } - - void setEndRow(int row) { m_endRow = row; } - - void setNumCols(int cols) { m_numCols = cols; } - - virtual void doCommand() = 0; - - QModelIndex parentIndex() const { return findIndex(m_rowNumbers); } - int startRow() const { return m_startRow; } - int endRow() const { return m_endRow; } - -protected: - DynamicTreeModel* m_model; - QList m_rowNumbers; - int m_startRow; - int m_endRow; - int m_numCols; - -}; - -typedef QList ModelChangeCommandList; - -/** - @brief Inserts a sub tree into the dynamictreemodel. - - As an alternative to setStartRow and setEndRow, the interpret command may be used. - - The interpret command is used to set the structure of the subtree. - - For example, - @code - cmd = new ModelInsertCommand(m_model, this); - cmd->interpret( - "- A" - "- B" - "- - C" - "- D" - ); - @endcode - - Will emit an insert for 3 rows, the second of which will have a child row. The interpretation - string may be complex as long as it is valid. The text at the end of each row does not need to be consistent. - There is a define DUMPTREE to make this command print the tree it inserts for better readability. - - @code - cmd->interpret( - "- A" - "- - B" - "- - C" - "- - - C" - "- - C" - "- - - C" - "- - - C" - "- - C" - "- D" - "- - E" - "- - F" - ); - @endcode - - The string is valid if (depth of row (N + 1)) <= ( (depth of row N) + 1). For example, the following is invalid - because the depth of B is 2 and the depth of A is 0. - - @code - cmd->interpret( - "- A" - "- - - B" - "- - C" - @endcode -*/ -class ModelInsertCommand : public ModelChangeCommand -{ - Q_OBJECT - - struct Token - { - enum Type { Branch, Leaf }; - Type type; - QString content; - }; - -public: - - explicit ModelInsertCommand(DynamicTreeModel *model, QObject *parent = 0 ); - virtual ~ModelInsertCommand() {} - - void interpret(const QString &treeString); - - virtual void doCommand(); - void doInsertTree(const QModelIndex &parent); - -protected: - QList tokenize(const QString &treeString) const; - - QList getDepths(const QString &treeString) const; - - QString m_treeString; -}; - -class ModelInsertAndRemoveQueuedCommand : public ModelChangeCommand -{ - Q_OBJECT - -public: - - explicit ModelInsertAndRemoveQueuedCommand(DynamicTreeModel *model, QObject *parent = 0 ); - virtual ~ModelInsertAndRemoveQueuedCommand() {} - - virtual void doCommand(); - -signals: - void beginInsertRows(const QModelIndex &parent, int start, int end); - void endInsertRows(); - void beginRemoveRows(const QModelIndex &parent, int start, int end); - void endRemoveRows(); - -protected slots: - void queuedBeginInsertRows(const QModelIndex &parent, int start, int end); - void queuedEndInsertRows(); - void queuedBeginRemoveRows(const QModelIndex &parent, int start, int end); - void queuedEndRemoveRows(); - -protected: - void purgeItem(qint64 parent); -}; - -class ModelRemoveCommand : public ModelChangeCommand -{ - Q_OBJECT -public: - explicit ModelRemoveCommand(DynamicTreeModel *model, QObject *parent = 0 ); - virtual ~ModelRemoveCommand() {} - - virtual void doCommand(); - - void purgeItem(qint64 parent); -}; - -class ModelDataChangeCommand : public ModelChangeCommand -{ - Q_OBJECT -public: - explicit ModelDataChangeCommand(DynamicTreeModel *model, QObject *parent = 0); - - virtual ~ModelDataChangeCommand() {} - - virtual void doCommand(); - - void setStartColumn(int column) { m_startColumn = column; } - -protected: - int m_startColumn; -}; - -class ModelMoveCommand : public ModelChangeCommand -{ - Q_OBJECT -public: - explicit ModelMoveCommand(DynamicTreeModel *model, QObject *parent); - - virtual ~ModelMoveCommand() {} - - virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); - - virtual void doCommand(); - - virtual void emitPostSignal(); - - void setDestAncestors( const QList &rows ) { m_destRowNumbers = rows; } - QList destAncestors() const { return m_destRowNumbers; } - - void setDestRow(int row) { m_destRow = row; } - -protected: - QList m_destRowNumbers; - int m_destRow; -}; - -class ModelMoveLayoutChangeCommand : public ModelMoveCommand -{ - Q_OBJECT -public: - explicit ModelMoveLayoutChangeCommand(DynamicTreeModel* model, QObject* parent); - virtual ~ModelMoveLayoutChangeCommand(); - - virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); - - virtual void emitPostSignal(); - - void setEndOfMoveSourceAncestors(const QList &rows ) { m_endOfMoveSourceAncestors = rows; } - void setEndOfMoveDestAncestors(const QList &rows ) { m_endOfMoveDestAncestors = rows; } - -private: - QModelIndexList m_beforeMoveList; - QList m_endOfMoveSourceAncestors; - QList m_endOfMoveDestAncestors; - -}; - -class ModelResetCommand : public ModelChangeCommand -{ - Q_OBJECT -public: - ModelResetCommand(DynamicTreeModel* model, QObject* parent = 0); - virtual ~ModelResetCommand(); - - void setInitialTree(const QString &treeString); - - /* reimp */ void doCommand(); -private: - QString m_treeString; -}; - - -#endif diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreewidget.cpp kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreewidget.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreewidget.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreewidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,398 +0,0 @@ -/* - Copyright (c) 2009 Stephen Kelly - - 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 "dynamictreewidget.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "dynamictreemodel.h" - -static const char * const treePredefinesNames[] = { - "Flat List", - "Straight Line Tree", - "Dragon Teeth 1", - "Dragon Teeth 2", - "Random Tree 1" -}; - -static const char * const treePredefinesContent[] = { - " - 1" - " - 1" - " - 1" - " - 1" - " - 1" - " - 1" - " - 1" - " - 1" - " - 1" - " - 1" - " - 1" - " - 1" - " - 1" - " - 1" - " - 1" - " - 1", - - " - 1" - " - - 1" - " - - - 1" - " - - - - 1" - " - - - - - 1" - " - - - - - - 1" - " - - - - - - - 1" - " - - - - - - - - 1" - " - - - - - - - - - 1" - " - - - - - - - - - - 1" - " - - - - - - - - - - - 1" - " - - - - - - - - - - - - 1" - " - - - - - - - - - - - - - 1" - " - - - - - - - - - - - - - - 1" - " - - - - - - - - - - - - - - - 1" - " - - - - - - - - - - - - - - - - 1", - - " - 1" - " - - 1" - " - - - 1" - " - - - - 1" - " - 1" - " - - 1" - " - - - 1" - " - - - - 1" - " - 1" - " - - 1" - " - - - 1" - " - - - - 1" - " - 1" - " - - 1" - " - - - 1" - " - - - - 1", - - " - 1" - " - - 1" - " - - - 1" - " - - - - 1" - " - - - - - 1" - " - 1" - " - - 1" - " - - - 1" - " - - - - 1" - " - - - - - 1" - " - 1" - " - - 1" - " - - - 1" - " - - - - 1" - " - - - - - 1" - " - 1" - " - - 1" - " - - - 1" - " - - - - 1" - " - - - - - 1", - - " - 1" - " - 2" - " - - 3" - " - - - 4" - " - 5" - " - 6" - " - 7" - " - - 8" - " - - - 9" - " - - - 10" - " - - - - 11" - " - - - 12" - " - - - - 13" - " - 14" - " - 15" -}; - -static const char * const insertSubTreePredefinesNames[] = { - "Flat List", - "Straight Line Tree", - "Dragon Teeth 1", - "Dragon Teeth 2", - "Random Tree 1" -}; - -static const char * const insertSubTreePredefinesContent[] = { - " - 1\n" - " - 1\n" - " - 1\n" - " - 1\n", - - " - 1\n" - " - - 1\n" - " - - - 1\n" - " - - - - 1\n", - - " - 1\n" - " - - 1\n" - " - 1\n" - " - - 1\n", - - " - 1\n" - " - - 1\n" - " - - - 1\n" - " - 1\n" - " - - 1\n" - " - - - 1\n", - - " - 1\n" - " - 2\n" - " - - 3\n" - " - - - 4\n" - " - 5\n" -}; - -DynamicTreeWidget::DynamicTreeWidget(DynamicTreeModel *rootModel, QWidget* parent, Qt::WindowFlags f) - : QWidget(parent, f), m_dynamicTreeModel(rootModel) -{ - QTabWidget *tabWidget = new QTabWidget(this); - - QHBoxLayout *layout = new QHBoxLayout(this); - layout->addWidget(tabWidget); - - QWidget *editContainer = new QWidget(tabWidget); - QVBoxLayout *editLayout = new QVBoxLayout(editContainer); - - m_treePredefines = new QComboBox(editContainer); - for (uint i = 0; i < sizeof treePredefinesNames / sizeof *treePredefinesNames; ++i) - m_treePredefines->addItem(*(treePredefinesNames + i), *(treePredefinesContent + i)); - editLayout->addWidget(m_treePredefines); - connect(m_treePredefines, SIGNAL(currentIndexChanged(int)), SLOT(setTreePredefine(int))); - - m_textEdit = new QPlainTextEdit(editContainer); - editLayout->addWidget(m_textEdit); - - QWidget *viewContainer = new QWidget(tabWidget); - - QVBoxLayout *viewLayout = new QVBoxLayout(viewContainer); - - m_treeView = new QTreeView(tabWidget); - m_treeView->setModel(rootModel); - m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); - m_treeView->setDragDropMode(QAbstractItemView::InternalMove); - m_treeView->setDragEnabled(true); - m_treeView->setAcceptDrops(true); - m_treeView->setDropIndicatorShown(true); - m_treeView->viewport()->installEventFilter(this); - -// QPushButton *m_removeButton = new QPushButton("Remove", tabWidget); - -// connect(m_removeButton, SIGNAL(clicked(bool)), SLOT(removeSelected())); - -// m_insertSubTreePredefines = new QComboBox(this); -// for (uint i = 0; i < sizeof insertSubTreePredefinesNames / sizeof *insertSubTreePredefinesNames; ++i) -// m_insertSubTreePredefines->addItem(*(insertSubTreePredefinesNames + i), *(insertSubTreePredefinesContent + i)); -// editLayout->addWidget(m_insertSubTreePredefines); -// connect(m_insertSubTreePredefines, SIGNAL(currentIndexChanged(int)), SLOT(setInsertSubTreePredefine(int))); - -// m_insertPatternTextEdit = new QPlainTextEdit(tabWidget); -// m_insertPatternTextEdit->setMaximumHeight(100); - -// m_insertChildren = new QRadioButton("Insert Children", tabWidget); -// m_insertSiblingsAbove = new QRadioButton("Insert Siblings Above", tabWidget); -// m_insertSiblingsBelow = new QRadioButton("Insert Siblings Below", tabWidget); - -// m_insertChildren->setChecked(true); - -// QPushButton *m_insertButton = new QPushButton("Insert", tabWidget); - -// connect(m_insertButton, SIGNAL(clicked(bool)), SLOT(insertSelected())); - -// QPushButton *m_resetButton = new QPushButton("Reset", tabWidget); - -// connect(m_resetButton, SIGNAL(clicked(bool)), SLOT(resetModel())); - - viewLayout->addWidget(m_treeView); - -// viewLayout->addWidget(m_removeButton); - -// viewLayout->addWidget(m_insertSubTreePredefines); -// viewLayout->addWidget(m_insertPatternTextEdit); -// viewLayout->addWidget(m_insertChildren); -// viewLayout->addWidget(m_insertSiblingsAbove); -// viewLayout->addWidget(m_insertSiblingsBelow); -// viewLayout->addWidget(m_insertButton); -// viewLayout->addWidget(m_resetButton); - - tabWidget->addTab(editContainer, "Edit"); - tabWidget->addTab(viewContainer, "View"); - - tabWidget->setCurrentIndex(ViewTab); - - connect(tabWidget, SIGNAL(currentChanged(int)), SLOT(currentChanged(int))); - stringToModel( - " - 1" - " - 2" - " - - 3" - " - - 4" - " - - 5" - " - 6" - " - 7" - " - - 8" - " - - - 9" - " - - - 10" - " - - 11" - " - - 12" - " - 13" - " - 14" - " - 15" - " - - 16" - " - - - 17" - " - - - 18" - " - 19" - " - 20" - " - 21" - ); -} - -void DynamicTreeWidget::setInitialTree(const QString &treeString) -{ - stringToModel(treeString); -} - -void DynamicTreeWidget::currentChanged(int index) -{ - switch(index) - { - case EditTab: - m_textEdit->setPlainText(modelTreeToString(0, QModelIndex())); - break; - case ViewTab: - if (m_textEdit->document()->isModified()) - stringToModel(m_textEdit->toPlainText()); - m_textEdit->document()->setModified(false); - break; - } -} - -void DynamicTreeWidget::stringToModel(const QString &treeString) -{ - if (treeString.isEmpty()) - return; - - m_dynamicTreeModel->clear(); - ModelInsertCommand *command = new ModelInsertCommand(m_dynamicTreeModel); - command->setStartRow(0); - command->interpret(treeString); - command->doCommand(); - m_treeView->expandAll(); -} - -QString DynamicTreeWidget::modelTreeToString(int depth, const QModelIndex &parent) -{ - QString result; - QModelIndex idx; - static const int column = 0; - QString prefix; - - for (int i = 0; i <= depth; ++i) - prefix.append(" -"); - - for (int row = 0; row < m_dynamicTreeModel->rowCount(parent); ++row) - { - idx = m_dynamicTreeModel->index(row, column, parent); - result.append(prefix + " " + idx.data().toString() + "\n"); - if (m_dynamicTreeModel->hasChildren(idx)) - result.append(modelTreeToString(depth+1, idx)); - } - return result; -} - -void DynamicTreeWidget::removeSelected() -{ - QModelIndex parent; - ModelRemoveCommand *removeCommand = new ModelRemoveCommand(m_dynamicTreeModel, this); - QItemSelection selection = m_treeView->selectionModel()->selection(); - while (!selection.isEmpty()) - { - const QItemSelectionRange &range = selection.takeFirst(); // The selection model will take care of updating persistent indexes. - Q_ASSERT(range.isValid()); -// kDebug() << range.parent() << range.top() << range.bottom(); - removeCommand->setAncestorRowNumbers(m_dynamicTreeModel->indexToPath(range.parent())); - removeCommand->setStartRow(range.top()); - removeCommand->setEndRow(range.bottom()); - -// kDebug() << m_dynamicTreeModel->indexToPath(range.parent()); - - removeCommand->doCommand(); - } -} - -void DynamicTreeWidget::insertSelected() -{ - const QModelIndexList selectedRows = m_treeView->selectionModel()->selectedRows(); - - if (selectedRows.size() != 1) - return; - - const QModelIndex selectedRow = selectedRows.first(); - - ModelInsertCommand *ins = new ModelInsertCommand(m_dynamicTreeModel, this); - if (m_insertChildren->isChecked()) - { - ins->setAncestorRowNumbers(m_dynamicTreeModel->indexToPath(selectedRow)); - ins->setStartRow(0); - } else if (m_insertSiblingsAbove->isChecked()) - { - ins->setAncestorRowNumbers(m_dynamicTreeModel->indexToPath(selectedRow.parent())); - ins->setStartRow(selectedRow.row()); - } else { - Q_ASSERT(m_insertSiblingsBelow->isChecked()); - ins->setAncestorRowNumbers(m_dynamicTreeModel->indexToPath(selectedRow.parent())); - ins->setStartRow(selectedRow.row() + 1); - } - ins->interpret(m_insertPatternTextEdit->toPlainText()); - ins->doCommand(); -} - -void DynamicTreeWidget::resetModel() -{ - ModelResetCommand *resetCommand = new ModelResetCommand(m_dynamicTreeModel, this); - - resetCommand->setInitialTree(m_insertPatternTextEdit->toPlainText().trimmed()); - resetCommand->doCommand(); -} - -void DynamicTreeWidget::setTreePredefine(int index) -{ - stringToModel(m_treePredefines->itemData(index).toString()); - m_textEdit->setPlainText(modelTreeToString(0, QModelIndex())); -} - -void DynamicTreeWidget::setInsertSubTreePredefine(int index) -{ - m_insertPatternTextEdit->setPlainText(m_insertSubTreePredefines->itemData(index).toString()); -} - -bool DynamicTreeWidget::eventFilter(QObject* o, QEvent* e) -{ - - if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonDblClick || e->type() == QEvent::MouseButtonRelease) - return true; - return QObject::eventFilter( o, e); -} - - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreewidget.h kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreewidget.h --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreewidget.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/dynamictreewidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -/* - Copyright (c) 2009 Stephen Kelly - - 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 DYNAMICTREEWIDGET_H -#define DYNAMICTREEWIDGET_H - -#include - -class QModelIndex; - -class QComboBox; -class QPlainTextEdit; -class QTreeView; -class QRadioButton; - -class DynamicTreeModel; - -class DynamicTreeWidget : public QWidget -{ - Q_OBJECT -public: - DynamicTreeWidget(DynamicTreeModel *rootModel, QWidget* parent = 0, Qt::WindowFlags f = 0); - - void setInitialTree(const QString &treeString); - - DynamicTreeModel *model() const { return m_dynamicTreeModel; } - QTreeView *treeView() const { return m_treeView; } - QPlainTextEdit *textEdit() const { return m_textEdit; } - -private slots: - void currentChanged(int index); - void setTreePredefine(int index); - void setInsertSubTreePredefine(int index); - - void removeSelected(); - void insertSelected(); - void resetModel(); - -protected: - virtual bool eventFilter(QObject* , QEvent* ); - -private: - void stringToModel(const QString &treeString); - QString modelTreeToString(int depth, const QModelIndex &parent); - -private: - enum Tab { - EditTab, - ViewTab - }; - - QString m_initialString; - DynamicTreeModel *m_dynamicTreeModel; - QTreeView *m_treeView; - QPlainTextEdit *m_textEdit; - - QPlainTextEdit *m_insertPatternTextEdit; - QRadioButton *m_insertChildren; - QRadioButton *m_insertSiblingsAbove; - QRadioButton *m_insertSiblingsBelow; - QComboBox *m_insertSubTreePredefines; - QComboBox *m_treePredefines; -}; - -#endif Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/fuzz.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/fuzz.png differ diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/indexfinder.h kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/indexfinder.h --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/indexfinder.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/indexfinder.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -/* -Copyright (c) 2009 Stephen Kelly - -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 INDEXFINDER_H -#define INDEXFINDER_H - -#include - -class IndexFinder -{ - public: - IndexFinder(QList rows = QList()) : m_rows(rows), m_model(0) {} - - IndexFinder(QAbstractItemModel *model, QList rows = QList() ) - : m_rows(rows), m_model(model) - { - Q_ASSERT(model); - } - - QModelIndex getIndex() - { - if(!m_model) - return QModelIndex(); - static const int col = 0; - QModelIndex parent = QModelIndex(); - QListIterator i(m_rows); - while (i.hasNext()) - { - parent = m_model->index(i.next(), col, parent); - Q_ASSERT(parent.isValid()); - } - return parent; - } - - bool operator==( const IndexFinder &other ) const - { - return (m_rows == other.m_rows && m_model == other.m_model ); - } - - QList rows() const { return m_rows; } - void appendRow(int row) { m_rows.append(row); } - void setRows( const QList &rows ) { m_rows = rows; } - void setModel(QAbstractItemModel *model) { m_model = model; } - - private: - QList m_rows; - QAbstractItemModel *m_model; -}; - - -Q_DECLARE_METATYPE( IndexFinder ) - -#endif diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kbihash_p.h kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kbihash_p.h --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kbihash_p.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kbihash_p.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,401 +0,0 @@ -/* - - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 KBIHASH_P_H -#define KBIHASH_P_H - -#include -#include - -template class KBiHash; -template QDebug operator<<(QDebug out, const KBiHash &biHash); -template QDataStream &operator<<(QDataStream &out, const KBiHash &bihash); -template QDataStream &operator>>(QDataStream &in, KBiHash &biHash); - -/** - * @brief KBiHash provides a bi-directional hash container - * - * @note This class is designed to make mapping easier in proxy model implementations. - * - * @todo Figure out whether to discard this and use boost::bimap instead, submit it Qt or keep it here and make more direct use of QHashNode. - */ -template -class KBiHash -{ -public: - typedef T left_type; - typedef U right_type; - - template - class _iterator : public QHash::iterator - { - public: - explicit inline _iterator(void *data) : QHash::iterator(data) {} - /* implicit */ _iterator(const typename QHash::iterator it) - // Using internals here because I was too lazy to write my own iterator. - : QHash::iterator(reinterpret_cast(static_cast *>(it))) { } - - inline const W &value() const { - return QHash::iterator::value(); - } - inline const W &operator*() const { - return QHash::iterator::operator*(); - } - inline const W *operator->() const { - return QHash::iterator::operator->(); - } - - private: -#ifndef Q_CC_MSVC - using QHash::iterator::operator*; - using QHash::iterator::operator->; - using QHash::iterator::value; -#endif - }; - - typedef _iterator left_iterator; - typedef typename QHash::const_iterator left_const_iterator; - typedef _iterator right_iterator; - typedef typename QHash::const_iterator right_const_iterator; - - inline KBiHash() {} - inline KBiHash(const KBiHash &other) { - *this = other; - } - - static KBiHash fromHash(const QHash &hash) { - KBiHash biHash; - typename QHash::const_iterator it = hash.constBegin(); - const typename QHash::const_iterator end = hash.constEnd(); - for ( ; it != end; ++it) - biHash.insert(it.key(), it.value()); - return biHash; - } - - const KBiHash &operator=(const KBiHash &other) { - _leftToRight = other._leftToRight; _rightToLeft = other._rightToLeft; return *this; - } - - inline bool removeLeft(T t) { - const U u = _leftToRight.take(t); - return _rightToLeft.remove(u) != 0; - } - - inline bool removeRight(U u) { - const T t = _rightToLeft.take(u); - return _leftToRight.remove(t) != 0; - } - - inline U takeLeft(T t) { - const U u = _leftToRight.take(t); - _rightToLeft.remove(u); - return u; - } - - inline T takeRight(U u) { - const T t = _rightToLeft.take(u); - _leftToRight.remove(t); - return t; - } - - inline T rightToLeft(U u) const { - return _rightToLeft.value(u); - } - - inline U leftToRight(T t) const { - return _leftToRight.value(t); - } - - inline bool leftContains(T t) const { - return _leftToRight.contains(t); - } - - inline bool rightContains(U u) const { - return _rightToLeft.contains(u); - } - - inline int size() const { - return _leftToRight.size(); - } - - inline int count() const { - return _leftToRight.count(); - } - - inline int capacity() const { - return _leftToRight.capacity(); - } - - void reserve(int size) { - _leftToRight.reserve(size); _rightToLeft.reserve(size); - } - - inline void squeeze() { - _leftToRight.squeeze(); _rightToLeft.squeeze(); - } - - inline void detach() { - _leftToRight.detach(); _rightToLeft.detach(); - } - - inline bool isDetached() const { - return _leftToRight.isDetached(); - } - - inline void setSharable(bool sharable) { - _leftToRight.setSharable(sharable); _rightToLeft.setSharable(sharable); - } - - inline bool isSharedWith(const KBiHash &other) const { - return _leftToRight.isSharedWith(other._leftToRight) && _rightToLeft.isSharedWith(other._leftToRight); - } - - void clear() { - _leftToRight.clear(); _rightToLeft.clear(); - } - - QList leftValues() const { - return _leftToRight.keys(); - } - - QList rightValues() const { - return _rightToLeft.keys(); - } - - right_iterator eraseRight(right_iterator it) { - Q_ASSERT(it != rightEnd()); - _leftToRight.remove(it.value()); - return _rightToLeft.erase(it); - } - - left_iterator eraseLeft(left_iterator it) { - Q_ASSERT(it != leftEnd()); - _rightToLeft.remove(it.value()); - return _leftToRight.erase(it); - } - - left_iterator findLeft(T t) { - return _leftToRight.find(t); - } - - left_const_iterator findLeft(T t) const { - return _leftToRight.find(t); - } - - left_const_iterator constFindLeft(T t) const { - return _leftToRight.constFind(t); - } - - right_iterator findRight(U u) { - return _rightToLeft.find(u); - } - - right_const_iterator findRight(U u) const { - return _rightToLeft.find(u); - } - - right_const_iterator constFindRight(U u) const { - return _rightToLeft.find(u); - } - - left_iterator insert(T t, U u) { - // biHash.insert(5, 7); // creates 5->7 in _leftToRight and 7->5 in _rightToLeft - // biHash.insert(5, 9); // replaces 5->7 with 5->9 in _leftToRight and inserts 9->5 in _rightToLeft. - // The 7->5 in _rightToLeft would be dangling, so we remove it before insertion. - - // This means we need to hash u and t up to twice each. Could probably be done better using QHashNode. - - if (_leftToRight.contains(t)) - _rightToLeft.remove(_leftToRight.take(t)); - if (_rightToLeft.contains(u)) - _leftToRight.remove(_rightToLeft.take(u)); - - _rightToLeft.insert(u, t); - return _leftToRight.insert(t, u); - } - - KBiHash &intersect(const KBiHash &other) { - typename KBiHash::left_iterator it = leftBegin(); - while (it != leftEnd()) { - if (!other.leftContains(it.key())) - it = eraseLeft(it); - else - ++it; - } - return *this; - } - - KBiHash &subtract(const KBiHash &other) { - typename KBiHash::left_iterator it = leftBegin(); - while (it != leftEnd()) { - if (other._leftToRight.contains(it.key())) - it = eraseLeft(it); - else - ++it; - } - return *this; - } - - KBiHash &unite(const KBiHash &other) { - typename QHash::const_iterator it = other._leftToRight.constBegin(); - const typename QHash::const_iterator end = other._leftToRight.constEnd(); - while (it != end) { - const T key = it.key(); - if (!_leftToRight.contains(key)) - insert(key, it.value()); - ++it; - } - return *this; - } - - void updateRight(left_iterator it, U u) { - Q_ASSERT(it != leftEnd()); - const T key = it.key(); - _rightToLeft.remove(_leftToRight.value(key)); - _leftToRight[key] = u; - _rightToLeft[u] = key; - } - - void updateLeft(right_iterator it, T t) { - Q_ASSERT(it != rightEnd()); - const U key = it.key(); - _leftToRight.remove(_rightToLeft.value(key)); - _rightToLeft[key] = t; - _leftToRight[t] = key; - } - - inline bool isEmpty() const { - return _leftToRight.isEmpty(); - } - - const U operator[](const T &t) const { - return _leftToRight.operator[](t); - } - - bool operator==(const KBiHash &other) { - return _leftToRight.operator == (other._leftToRight); - } - - bool operator!=(const KBiHash &other) { - return _leftToRight.operator != (other._leftToRight); - } - - left_iterator toLeftIterator(right_iterator it) const { - Q_ASSERT(it != rightEnd()); - return _leftToRight.find(it.value()); - } - - right_iterator toRightIterator(left_iterator it) const { - Q_ASSERT(it != leftEnd()); - return _rightToLeft.find(it.value()); - } - - inline left_iterator leftBegin() { - return _leftToRight.begin(); - } - - inline left_iterator leftEnd() { - return _leftToRight.end(); - } - - inline left_const_iterator leftBegin() const { - return _leftToRight.begin(); - } - - inline left_const_iterator leftEnd() const { - return _leftToRight.end(); - } - - inline left_const_iterator leftConstBegin() const { - return _leftToRight.constBegin(); - } - - inline left_const_iterator leftConstEnd() const { - return _leftToRight.constEnd(); - } - - inline right_iterator rightBegin() { - return _rightToLeft.begin(); - } - - inline right_iterator rightEnd() { - return _rightToLeft.end(); - } - - inline right_const_iterator rightBegin() const { - return _rightToLeft.begin(); - } - - inline right_const_iterator rightEnd() const { - return _rightToLeft.end(); - } - inline right_const_iterator rightConstBegin() const { - return _rightToLeft.constBegin(); - } - - inline right_const_iterator rightConstEnd() const { - return _rightToLeft.constEnd(); - } - - friend QDataStream &operator<< (QDataStream &out, const KBiHash &bihash); - friend QDataStream &operator>> (QDataStream &in, KBiHash &biHash); - friend QDebug operator<< (QDebug out, const KBiHash &biHash); -private: - QHash _leftToRight; - QHash _rightToLeft; -}; - -template -QDataStream &operator<<(QDataStream &out, const KBiHash &biHash) -{ - return out << biHash._leftToRight; -} - -template -QDataStream &operator>>(QDataStream &in, KBiHash &biHash) -{ - QHash leftToRight; - in >> leftToRight; - typename QHash::const_iterator it = leftToRight.constBegin(); - const typename QHash::const_iterator end = leftToRight.constEnd(); - for (; it != end; ++it) - biHash.insert(it.key(), it.value()); - - return in; -} - -template -QDebug operator<<(QDebug out, const KBiHash &biHash) -{ - typename KBiHash::left_const_iterator it = biHash.leftConstBegin(); - - const typename KBiHash::left_const_iterator end = biHash.leftConstEnd(); - out << "KBiHash("; - for (; it != end; ++it) - out << "(" << it.key() << "<=>" << it.value() << ")"; - - out << ")"; - return out; -} - -#endif diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kbreadcrumbselectionmodel.cpp kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kbreadcrumbselectionmodel.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kbreadcrumbselectionmodel.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kbreadcrumbselectionmodel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,210 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 "kbreadcrumbselectionmodel.h" - - -class KBreadcrumbSelectionModelPrivate -{ - Q_DECLARE_PUBLIC(KBreadcrumbSelectionModel) - KBreadcrumbSelectionModel * const q_ptr; -public: - KBreadcrumbSelectionModelPrivate(KBreadcrumbSelectionModel *breadcrumbSelector, QItemSelectionModel *selectionModel, KBreadcrumbSelectionModel::BreadcrumbTarget direction) - : q_ptr(breadcrumbSelector), - m_includeActualSelection(true), - m_selectionDepth(-1), - m_showHiddenAscendantData(false), - m_selectionModel(selectionModel), - m_direction(direction), - m_ignoreCurrentChanged(false) - { - - } - - /** - Returns a selection containing the breadcrumbs for @p index - */ - QItemSelection getBreadcrumbSelection(const QModelIndex &index); - - /** - Returns a selection containing the breadcrumbs for @p selection - */ - QItemSelection getBreadcrumbSelection(const QItemSelection &selection); - -// void sourceSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); - - bool m_includeActualSelection; - int m_selectionDepth; - bool m_showHiddenAscendantData; - QItemSelectionModel *m_selectionModel; - KBreadcrumbSelectionModel::BreadcrumbTarget m_direction; - bool m_ignoreCurrentChanged; -}; - -KBreadcrumbSelectionModel::KBreadcrumbSelectionModel(QItemSelectionModel *selectionModel, QObject* parent) - : QItemSelectionModel(const_cast(selectionModel->model()), parent), - d_ptr(new KBreadcrumbSelectionModelPrivate(this, selectionModel, MakeBreadcrumbSelectionInSelf)) -{ -} - -KBreadcrumbSelectionModel::KBreadcrumbSelectionModel(QItemSelectionModel *selectionModel, BreadcrumbTarget direction, QObject* parent) - : QItemSelectionModel(const_cast(selectionModel->model()), parent), - d_ptr(new KBreadcrumbSelectionModelPrivate(this, selectionModel, direction)) -{ - if ( direction != MakeBreadcrumbSelectionInSelf) - connect(selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), - this, SLOT(sourceSelectionChanged(QItemSelection,QItemSelection))); -} - -KBreadcrumbSelectionModel::~KBreadcrumbSelectionModel() -{ - delete d_ptr; -} - -bool KBreadcrumbSelectionModel::isActualSelectionIncluded() const -{ - Q_D(const KBreadcrumbSelectionModel); - return d->m_includeActualSelection; -} - -void KBreadcrumbSelectionModel::setActualSelectionIncluded(bool includeActualSelection) -{ - Q_D(KBreadcrumbSelectionModel); - d->m_includeActualSelection = includeActualSelection; -} - -int KBreadcrumbSelectionModel::breadcrumbLength() const -{ - Q_D(const KBreadcrumbSelectionModel); - return d->m_selectionDepth; -} - -void KBreadcrumbSelectionModel::setBreadcrumbLength(int breadcrumbLength) -{ - Q_D(KBreadcrumbSelectionModel); - d->m_selectionDepth = breadcrumbLength; -} - -QItemSelection KBreadcrumbSelectionModelPrivate::getBreadcrumbSelection(const QModelIndex& index) -{ - QItemSelection breadcrumbSelection; - - if (m_includeActualSelection) - breadcrumbSelection.append(QItemSelectionRange(index)); - - QModelIndex parent = index.parent(); - int sumBreadcrumbs = 0; - bool includeAll = m_selectionDepth < 0; - while (parent.isValid() && (includeAll || sumBreadcrumbs < m_selectionDepth)) { - breadcrumbSelection.append(QItemSelectionRange(parent)); - parent = parent.parent(); - } - return breadcrumbSelection; -} - -QItemSelection KBreadcrumbSelectionModelPrivate::getBreadcrumbSelection(const QItemSelection& selection) -{ - QItemSelection breadcrumbSelection; - - if (m_includeActualSelection) - breadcrumbSelection = selection; - - QItemSelection::const_iterator it = selection.constBegin(); - const QItemSelection::const_iterator end = selection.constEnd(); - - for ( ; it != end; ++it) - { - QModelIndex parent = it->parent(); - int sumBreadcrumbs = 0; - bool includeAll = m_selectionDepth < 0; - while (parent.isValid() && (includeAll || sumBreadcrumbs < m_selectionDepth)) - { - breadcrumbSelection.append(QItemSelectionRange(parent)); - parent = parent.parent(); - ++sumBreadcrumbs; - } - } - return breadcrumbSelection; -} - -void KBreadcrumbSelectionModel::sourceSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected) -{ - Q_D(KBreadcrumbSelectionModel); - QItemSelection deselectedCrumbs = d->getBreadcrumbSelection(deselected); - QItemSelection selectedCrumbs = d->getBreadcrumbSelection(selected); - - QItemSelection removed = deselectedCrumbs; - foreach(const QItemSelectionRange &range, selectedCrumbs) - { - removed.removeAll(range); - } - - QItemSelection added = selectedCrumbs; - foreach(const QItemSelectionRange &range, deselectedCrumbs) - { - added.removeAll(range); - } - - if (!removed.isEmpty()) - { - QItemSelectionModel::select(removed, QItemSelectionModel::Deselect); - } - if (!added.isEmpty()) - { - QItemSelectionModel::select(added, QItemSelectionModel::Select); - } -} - -void KBreadcrumbSelectionModel::select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) -{ - Q_D(KBreadcrumbSelectionModel); - // When an item is removed, the current index is set to the top index in the model. - // That causes a selectionChanged signal with a selection which we do not want. - if ( d->m_ignoreCurrentChanged ) - { - d->m_ignoreCurrentChanged = false; - return; - } - if ( d->m_direction == MakeBreadcrumbSelectionInOther ) - { - d->m_selectionModel->select(d->getBreadcrumbSelection(index), command); - QItemSelectionModel::select(index, command); - } else { - d->m_selectionModel->select(index, command); - QItemSelectionModel::select(d->getBreadcrumbSelection(index), command); - } -} - -void KBreadcrumbSelectionModel::select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) -{ - Q_D(KBreadcrumbSelectionModel); - QItemSelection bcc = d->getBreadcrumbSelection(selection); - if ( d->m_direction == MakeBreadcrumbSelectionInOther ) - { - d->m_selectionModel->select(selection, command); - QItemSelectionModel::select(bcc, command); - } else { - d->m_selectionModel->select(bcc, command); - QItemSelectionModel::select(selection, command); - } -} - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kbreadcrumbselectionmodel.h kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kbreadcrumbselectionmodel.h --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kbreadcrumbselectionmodel.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kbreadcrumbselectionmodel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,162 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 KBREADCRUMBSPROXYMODEL_H -#define KBREADCRUMBSPROXYMODEL_H - -#include -#include - -class KBreadcrumbSelectionModelPrivate; - -/** - @class KBreadcrumbSelectionModel kbreadcrumbselectionmodel.h - - @brief Selects the parents of selected items to create breadcrumbs - - For example, if the tree is - @verbatim - - A - - B - - - C - - - D - - - - E - - - - - F - @endverbatim - - and E is selected, the selection can contain - - @verbatim - - B - - D - @endverbatim - - or - - @verbatim - - B - - D - - E - @endverbatim - - if isActualSelectionIncluded is true. - - The depth of the selection may also be set. For example if the breadcrumbLength is 1: - - @verbatim - - D - - E - @endverbatim - - And if breadcrumbLength is 2: - - @verbatim - - B - - D - - E - @endverbatim - - A KBreadcrumbsProxyModel with a breadcrumbLength of 0 and including the actual selection is - the same as a KSelectionProxyModel in the KSelectionProxyModel::ExactSelection configuration. - - @code - view1->setModel(rootModel); - - QItemSelectionModel *breadcrumbSelectionModel = new QItemSelectionModel(rootModel, this); - - KBreadcrumbSelectionModel *breadcrumbProxySelector = new KBreadcrumbSelectionModel(breadcrumbSelectionModel, rootModel, this); - - view1->setSelectionModel(breadcrumbProxySelector); - - KSelectionProxyModel *breadcrumbSelectionProxyModel = new KSelectionProxyModel( breadcrumbSelectionModel, this); - breadcrumbSelectionProxyModel->setSourceModel( rootModel ); - breadcrumbSelectionProxyModel->setFilterBehavior( KSelectionProxyModel::ExactSelection ); - - view2->setModel(breadcrumbSelectionProxyModel); - @endcode - - @image html kbreadcrumbselectionmodel.png "KBreadcrumbSelectionModel in several configurations" - - This can work in two directions. One option is for a single selection in the KBreadcrumbSelectionModel to invoke - the breadcrumb selection in its constructor argument. - - The other is for a selection in the itemselectionmodel in the constructor argument to cause a breadcrumb selection - in @p this. - - @since 4.5 - -*/ -class KBreadcrumbSelectionModel : public QItemSelectionModel -{ - Q_OBJECT -public: - enum BreadcrumbTarget - { - MakeBreadcrumbSelectionInOther, - MakeBreadcrumbSelectionInSelf - }; - - explicit KBreadcrumbSelectionModel(QItemSelectionModel *selectionModel, QObject* parent = 0); - KBreadcrumbSelectionModel(QItemSelectionModel *selectionModel, BreadcrumbTarget target, QObject* parent = 0); - virtual ~KBreadcrumbSelectionModel(); - - /** - Returns whether the actual selection in included in the proxy. - - The default is true. - */ - bool isActualSelectionIncluded() const; - - /** - Set whether the actual selection in included in the proxy to @p isActualSelectionIncluded. - */ - void setActualSelectionIncluded(bool isActualSelectionIncluded); - - /** - Returns the depth that the breadcrumb selection should go to. - */ - int breadcrumbLength() const; - - /** - Sets the depth that the breadcrumb selection should go to. - - If the @p breadcrumbLength is -1, all breadcrumbs are selected. - The default is -1 - */ - void setBreadcrumbLength(int breadcrumbLength); - - /* reimp */ void select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command); - - /* reimp */ void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command); - -private slots: - void sourceSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); - -protected: - KBreadcrumbSelectionModelPrivate * const d_ptr; -private: - //@cond PRIVATE - Q_DECLARE_PRIVATE(KBreadcrumbSelectionModel) - //@cond PRIVATE -}; - - -#endif diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kmodelindexproxymapper.cpp kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kmodelindexproxymapper.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kmodelindexproxymapper.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kmodelindexproxymapper.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,247 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 "kmodelindexproxymapper.h" - -#include -#include -#include -#include - -#include - -class KModelIndexProxyMapperPrivate -{ - KModelIndexProxyMapperPrivate(const QAbstractItemModel *leftModel, const QAbstractItemModel *rightModel, KModelIndexProxyMapper *qq) - : q_ptr(qq), m_leftModel(leftModel), m_rightModel(rightModel) - { - createProxyChain(); - } - - void createProxyChain(); - bool assertValid(); - - Q_DECLARE_PUBLIC(KModelIndexProxyMapper) - KModelIndexProxyMapper * const q_ptr; - - QList > m_proxyChainUp; - QList > m_proxyChainDown; - - QWeakPointer m_leftModel; - QWeakPointer m_rightModel; -}; - - -/* - - The idea here is that this selection model and proxySelectionModel might be in different parts of the - proxy chain. We need to build up to two chains of proxy models to create mappings between them. - - Example 1: - - Root model - | - / \ - Proxy 1 Proxy 3 - | | - Proxy 2 Proxy 4 - - Need Proxy 1 and Proxy 2 in one chain, and Proxy 3 and 4 in the other. - - Example 2: - - Root model - | - Proxy 1 - | - Proxy 2 - / \ - Proxy 3 Proxy 6 - | | - Proxy 4 Proxy 7 - | - Proxy 5 - - We first build the chain from 1 to 5, then start building the chain from 7 to 1. We stop when we find that proxy 2 is - already in the first chain. - - Stephen Kelly, 30 March 2010. -*/ - -void KModelIndexProxyMapperPrivate::createProxyChain() -{ - QWeakPointer targetModel = m_rightModel; - - if (!targetModel) - return; - - if (m_leftModel == targetModel) - return; - - QList > proxyChainDown; - QWeakPointer selectionTargetProxyModel = qobject_cast(targetModel.data()); - while( selectionTargetProxyModel ) - { - proxyChainDown.prepend( selectionTargetProxyModel ); - - selectionTargetProxyModel = qobject_cast(selectionTargetProxyModel.data()->sourceModel()); - - if (selectionTargetProxyModel.data() == m_leftModel.data()) - { - m_proxyChainDown = proxyChainDown; - return; - } - } - - QWeakPointer sourceModel = m_leftModel; - QWeakPointer sourceProxyModel = qobject_cast(sourceModel.data()); - - while(sourceProxyModel) - { - m_proxyChainUp.append(sourceProxyModel); - - sourceProxyModel = qobject_cast(sourceProxyModel.data()->sourceModel()); - - const int targetIndex = proxyChainDown.indexOf(sourceProxyModel); - - if (targetIndex != -1) - { - m_proxyChainDown = proxyChainDown.mid(targetIndex, proxyChainDown.size()); - return; - } - } - m_proxyChainDown = proxyChainDown; - Q_ASSERT(assertValid()); -} - -bool KModelIndexProxyMapperPrivate::assertValid() -{ - if ( m_proxyChainDown.isEmpty()) - { - Q_ASSERT( !m_proxyChainUp.isEmpty() ); - Q_ASSERT( m_proxyChainUp.last().data()->sourceModel() == m_rightModel.data() ); - } - else if ( m_proxyChainUp.isEmpty()) - { - Q_ASSERT( !m_proxyChainDown.isEmpty() ); - Q_ASSERT( m_proxyChainDown.first().data()->sourceModel() == m_leftModel.data() ); - } else { - Q_ASSERT( m_proxyChainDown.first().data()->sourceModel() == m_proxyChainUp.last().data()->sourceModel() ); - } - return true; -} - -KModelIndexProxyMapper::KModelIndexProxyMapper(const QAbstractItemModel* leftModel, const QAbstractItemModel* rightModel, QObject* parent) - : QObject(parent), d_ptr( new KModelIndexProxyMapperPrivate(leftModel, rightModel, this) ) -{ - -} - -QModelIndex KModelIndexProxyMapper::mapLeftToRight(const QModelIndex& index) const -{ - const QItemSelection selection = mapSelectionLeftToRight(QItemSelection(index, index)); - if (selection.isEmpty()) - return QModelIndex(); - - return selection.indexes().first(); -} - -QModelIndex KModelIndexProxyMapper::mapRightToLeft(const QModelIndex& index) const -{ - const QItemSelection selection = mapSelectionRightToLeft(QItemSelection(index, index)); - if (selection.isEmpty()) - return QModelIndex(); - - return selection.indexes().first(); -} - -QItemSelection KModelIndexProxyMapper::mapSelectionLeftToRight(const QItemSelection& selection) const -{ - Q_D(const KModelIndexProxyMapper); - - if (selection.isEmpty()) - return QItemSelection(); - - Q_ASSERT(selection.first().model() == d->m_leftModel.data()); - - QItemSelection seekSelection = selection; - QListIterator > iUp(d->m_proxyChainUp); - - while (iUp.hasNext()) - { - const QWeakPointer proxy = iUp.next(); - if (!proxy.data()) - return QItemSelection(); - seekSelection = proxy.data()->mapSelectionToSource(seekSelection); - } - - QListIterator > iDown(d->m_proxyChainDown); - - while (iDown.hasNext()) - { - const QWeakPointer proxy = iDown.next(); - if (!proxy.data()) - return QItemSelection(); - seekSelection = proxy.data()->mapSelectionFromSource(seekSelection); - } - - Q_ASSERT( ( !seekSelection.isEmpty() && seekSelection.first().model() == d->m_rightModel.data() ) || true ); - return seekSelection; -} - -QItemSelection KModelIndexProxyMapper::mapSelectionRightToLeft(const QItemSelection& selection) const -{ - Q_D(const KModelIndexProxyMapper); - - if (selection.isEmpty()) - return QItemSelection(); - - if (selection.first().model() != d->m_rightModel.data()) - qDebug() << selection.first().model() << d->m_rightModel.data(); - Q_ASSERT(selection.first().model() == d->m_rightModel.data()); - - QItemSelection seekSelection = selection; - QListIterator > iDown(d->m_proxyChainDown); - - iDown.toBack(); - while (iDown.hasPrevious()) - { - const QWeakPointer proxy = iDown.previous(); - if (!proxy.data()) - return QItemSelection(); - seekSelection = proxy.data()->mapSelectionToSource(seekSelection); - } - - QListIterator > iUp(d->m_proxyChainUp); - - iUp.toBack(); - while (iUp.hasPrevious()) - { - const QWeakPointer proxy = iUp.previous(); - if (!proxy.data()) - return QItemSelection(); - seekSelection = proxy.data()->mapSelectionFromSource(seekSelection); - } - - Q_ASSERT( ( !seekSelection.isEmpty() && seekSelection.first().model() == d->m_leftModel.data() ) || true ); - return seekSelection; -} - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kmodelindexproxymapper.h kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kmodelindexproxymapper.h --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kmodelindexproxymapper.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kmodelindexproxymapper.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,113 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 KMODELINDEXPROXYMAPPER_H -#define KMODELINDEXPROXYMAPPER_H - -#include - -class QAbstractItemModel; -class QModelIndex; -class QItemSelection; -class KModelIndexProxyMapperPrivate; - -/** - * @brief This class facilitates easy mapping of indexes and selections through proxy models. - * - * In a complex system of proxy models there can be a need to map indexes and selections between them, - * and sometimes to do so without knowledge of the path from one model to another. - * - * For example, - * - * @verbatim - * Root model - * | - * / \ - * Proxy 1 Proxy 3 - * | | - * Proxy 2 Proxy 4 - * @endverbatim - * - * If there is a need to map indexes between proxy 2 and proxy 4, a KModelIndexProxyMapper can be created - * to facilitate mapping of indexes between them. - * - * @code - * m_indexMapper = new KModelIndexProxyMapper(proxy2, proxy4, this); - * - * ... - * - * const QModelIndex proxy4Index = m_mapLeftToRight(proxy2->index(0, 0)); - * Q_ASSERT(proxy4Index.model() == proxy4); - * @endcode - * - * Note that the aim is to achieve black box connections so that there is no need for application code to - * know the structure of proxy models in the path between left and right and attempt to manually map them. - * - * @verbatim - * Root model - * | - * --------------- - * | Black Box | - * --------------- - * | | - * Proxy 2 Proxy 4 - * @endverbatim - * - * @author Stephen Kelly - * - */ -class KModelIndexProxyMapper : public QObject -{ - Q_OBJECT -public: - /** - * Constructor - */ - KModelIndexProxyMapper(const QAbstractItemModel *leftModel, const QAbstractItemModel *rightModel, QObject* parent = 0); - - /** - * Maps the @p index from the left model to the right model. - */ - QModelIndex mapLeftToRight(const QModelIndex &index) const; - - /** - * Maps the @p index from the right model to the left model. - */ - QModelIndex mapRightToLeft(const QModelIndex &index) const; - - /** - * Maps the @p selection from the left model to the right model. - */ - QItemSelection mapSelectionLeftToRight(const QItemSelection &selection) const; - - /** - * Maps the @p selection from the right model to the left model. - */ - QItemSelection mapSelectionRightToLeft(const QItemSelection &selection) const; - -private: - //@cond PRIVATE - Q_DECLARE_PRIVATE(KModelIndexProxyMapper) - KModelIndexProxyMapperPrivate * const d_ptr; - //@endcond -}; - -#endif diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kproxyitemselectionmodel.cpp kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kproxyitemselectionmodel.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kproxyitemselectionmodel.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kproxyitemselectionmodel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,256 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 "kproxyitemselectionmodel.h" - -#include - -class KLinkItemSelectionModelPrivate -{ -public: - KLinkItemSelectionModelPrivate(KLinkItemSelectionModel *proxySelectionModel, QAbstractItemModel *model, - QItemSelectionModel *selectionModel) - : q_ptr( proxySelectionModel ), m_model(model), m_linkedItemSelectionModel(selectionModel) - { - createProxyChain(); - } - - void createProxyChain(); - - bool assertValid(); - - Q_DECLARE_PUBLIC(KLinkItemSelectionModel) - KLinkItemSelectionModel * const q_ptr; - - QList m_proxyChainUp; - QList m_proxyChainDown; - - QAbstractItemModel *m_model; - QItemSelectionModel *m_linkedItemSelectionModel; - bool m_ignoreCurrentChanged; -}; - -/* - - The idea here is that this selection model and proxySelectionModel might be in different parts of the - proxy chain. We need to build up to two chains of proxy models to create mappings between them. - - Example 1: - - Root model - | - / \ - Proxy 1 Proxy 3 - | | - Proxy 2 Proxy 4 - - Need Proxy 1 and Proxy 2 in one chain, and Proxy 3 and 4 in the other. - - Example 2: - - Root model - | - Proxy 1 - | - Proxy 2 - / \ - Proxy 3 Proxy 6 - | | - Proxy 4 Proxy 7 - | - Proxy 5 - - We first build the chain from 1 to 5, then start building the chain from 7 to 1. We stop when we find that proxy 2 is - already in the first chain. - - Stephen Kelly, 30 March 2010. -*/ - -void KLinkItemSelectionModelPrivate::createProxyChain() -{ - const QAbstractItemModel *selectionTargetModel = m_linkedItemSelectionModel->model(); - - if (m_model == selectionTargetModel) - return; - - QList proxyChainDown; - - const QAbstractProxyModel *selectionTargetProxyModel = qobject_cast( selectionTargetModel ); - - while( selectionTargetProxyModel ) - { - proxyChainDown.prepend( selectionTargetProxyModel ); - - selectionTargetProxyModel = qobject_cast(selectionTargetProxyModel->sourceModel()); - - if ( selectionTargetProxyModel == m_model ) - { - m_proxyChainDown = proxyChainDown; - return; - } - } - - const QAbstractItemModel *sourceModel = m_model; - const QAbstractProxyModel *sourceProxyModel = qobject_cast( sourceModel ); - - while( sourceProxyModel ) - { - m_proxyChainUp.append( sourceProxyModel ); - - sourceProxyModel = qobject_cast(sourceProxyModel->sourceModel()); - - int targetIndex = proxyChainDown.indexOf(sourceProxyModel ); - - if ( targetIndex != -1 ) - { - m_proxyChainDown = proxyChainDown.mid(targetIndex + 1, proxyChainDown.size()); - return; - } - } - m_proxyChainDown = proxyChainDown; - Q_ASSERT(assertValid()); -} - -bool KLinkItemSelectionModelPrivate::assertValid() -{ - qDebug() << m_proxyChainDown << m_proxyChainUp; - if ( m_proxyChainDown.isEmpty()) - { - Q_ASSERT( !m_proxyChainUp.isEmpty() ); - Q_ASSERT( m_proxyChainUp.last()->sourceModel() == m_linkedItemSelectionModel->model() ); - } - else if ( m_proxyChainUp.isEmpty()) - { - Q_ASSERT( !m_proxyChainDown.isEmpty() ); - Q_ASSERT( m_proxyChainDown.first()->sourceModel() == m_model ); - } else { - Q_ASSERT( m_proxyChainDown.first()->sourceModel() == m_proxyChainUp.last()->sourceModel() ); - } - return true; -} - -KLinkItemSelectionModel::KLinkItemSelectionModel( QAbstractItemModel *model, QItemSelectionModel *proxySelector, QObject *parent) - : QItemSelectionModel(model, parent), - d_ptr(new KLinkItemSelectionModelPrivate(this, model, proxySelector)) -{ - connect(proxySelector, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(sourceSelectionChanged(QItemSelection,QItemSelection))); -} - -QItemSelection KLinkItemSelectionModel::mapSelectionFromSource(const QModelIndex& sourceIndex) const -{ - return mapSelectionFromSource(QItemSelection(sourceIndex, sourceIndex)); -} - -QItemSelection KLinkItemSelectionModel::mapSelectionFromSource(const QItemSelection& sourceSelection) const -{ - Q_D(const KLinkItemSelectionModel); - - QItemSelection seekSelection = sourceSelection; - QListIterator iUp(d->m_proxyChainUp); - - while (iUp.hasNext()) - { - const QAbstractProxyModel *proxy = iUp.next(); - seekSelection = proxy->mapSelectionToSource(seekSelection); - } - - QListIterator iDown(d->m_proxyChainDown); - - while (iDown.hasNext()) - { - const QAbstractProxyModel *proxy = iDown.next(); - seekSelection = proxy->mapSelectionFromSource(seekSelection); - } - - Q_ASSERT( ( !seekSelection.isEmpty() && seekSelection.first().model() == d->m_linkedItemSelectionModel->model() ) || true ); - return seekSelection; -} - -QItemSelection KLinkItemSelectionModel::mapSelectionToSource(const QModelIndex& sourceIndex) const -{ - return mapSelectionToSource(QItemSelection(sourceIndex, sourceIndex)); -} - -QItemSelection KLinkItemSelectionModel::mapSelectionToSource(const QItemSelection& proxySelection) const -{ - Q_D(const KLinkItemSelectionModel); - - QItemSelection seekSelection = proxySelection; - QListIterator iDown(d->m_proxyChainDown); - - iDown.toBack(); - while (iDown.hasPrevious()) - { - const QAbstractProxyModel *proxy = iDown.previous(); - seekSelection = proxy->mapSelectionToSource(seekSelection); - } - - QListIterator iUp(d->m_proxyChainUp); - - iUp.toBack(); - while (iUp.hasPrevious()) - { - const QAbstractProxyModel *proxy = iUp.previous(); - seekSelection = proxy->mapSelectionFromSource(seekSelection); - } - - Q_ASSERT( ( !seekSelection.isEmpty() && seekSelection.first().model() == d->m_model ) || true ); - return seekSelection; -} - -void KLinkItemSelectionModel::select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) -{ - Q_D(KLinkItemSelectionModel); - // When an item is removed, the current index is set to the top index in the model. - // That causes a selectionChanged signal with a selection which we do not want. - if ( d->m_ignoreCurrentChanged ) - { - return; - } - QItemSelectionModel::select(index, command); - if (index.isValid()) - d->m_linkedItemSelectionModel->select(mapSelectionFromSource(index), command); - else - { - d->m_linkedItemSelectionModel->clearSelection(); - } -} - -void KLinkItemSelectionModel::select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) -{ - Q_D(KLinkItemSelectionModel); - d->m_ignoreCurrentChanged = true; - QItemSelectionModel::select(selection, command); - d->m_linkedItemSelectionModel->select(mapSelectionFromSource(selection), command); - d->m_ignoreCurrentChanged = false; -} - -void KLinkItemSelectionModel::sourceSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected) -{ - QItemSelection mappedDeselection = mapSelectionToSource(deselected); - QItemSelection mappedSelection = mapSelectionToSource(selected); - - QItemSelectionModel::select(mappedDeselection, Deselect); - QItemSelectionModel::select(mappedSelection, Select); -} - - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kproxyitemselectionmodel.h kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kproxyitemselectionmodel.h --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kproxyitemselectionmodel.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kproxyitemselectionmodel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 KPROXYITEMSELECTIONMODEL_H -#define KPROXYITEMSELECTIONMODEL_H - -#include -#include - -class KLinkItemSelectionModelPrivate; - -/** - @brief Makes it possible to share a selection in multiple views which do not have the same source model - - Although multiple views can share the same QItemSelectionModel, the views then need to have the same source model. - - If there is a proxy model between the model and one of the views, or different proxy models in each, this class makes - it possible to share the selection between the views. - - @image html kproxyitemselectionmodel-simple.png "Sharing a QItemSelectionModel between views on the same model is trivial" - @image html kproxyitemselectionmodel-error.png "If a proxy model is used, it is no longer possible to share the QItemSelectionModel directly" - @image html kproxyitemselectionmodel-solution.png "A KProxyItemSelectionModel can be used to map the selection through the proxy model" - @image html kproxyitemselectionmodel-complex.png "Arbitrarily complex proxy configurations on the same root model can be used" - - @since 4.5 - -*/ -class KLinkItemSelectionModel : public QItemSelectionModel -{ - Q_OBJECT -public: - /** - Constructor. - */ - KLinkItemSelectionModel( QAbstractItemModel *targetModel, QItemSelectionModel *proxySelector, QObject *parent = 0); - - /* reimp */ void select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command); - /* reimp */ void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command); - -private: - /** - Maps the @p sourceIndex though the proxy models to a selection in the proxySelector - */ - QItemSelection mapSelectionFromSource( const QModelIndex &sourceIndex ) const; - QItemSelection mapSelectionFromSource( const QItemSelection &sourceSelection ) const; - QItemSelection mapSelectionToSource( const QModelIndex &sourceIndex ) const; - QItemSelection mapSelectionToSource( const QItemSelection &sourceSelection ) const; - -private slots: - void sourceSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); - -protected: - KLinkItemSelectionModelPrivate * const d_ptr; - -private: - Q_DECLARE_PRIVATE(KLinkItemSelectionModel) -}; - -#endif diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kresettingproxymodel.cpp kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kresettingproxymodel.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kresettingproxymodel.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kresettingproxymodel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 "kresettingproxymodel.h" - -KResettingProxyModel::KResettingProxyModel(QObject* parent) - : QSortFilterProxyModel(parent) -{ - -} - -void KResettingProxyModel::setSourceModel(QAbstractItemModel* sourceModel) -{ - connect(sourceModel, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), this, SLOT(slotBeginReset())); - connect(sourceModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(slotEndReset())); - connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(slotBeginReset())); - connect(sourceModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(slotEndReset())); - - QSortFilterProxyModel::setSourceModel(sourceModel); - disconnect(sourceModel, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), this, SLOT(_q_sourceRowsAboutToBeInserted(QModelIndex,int,int))); - disconnect(sourceModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(_q_sourceRowsInserted(QModelIndex,int,int))); - disconnect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(_q_sourceRowsAboutToBeRemoved(QModelIndex,int,int))); - disconnect(sourceModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(_q_sourceRowsRemoved(QModelIndex,int,int))); - -} - -void KResettingProxyModel::slotBeginReset() -{ - QMetaObject::invokeMethod(this, "_q_sourceAboutToBeReset", Qt::DirectConnection); -} - -void KResettingProxyModel::slotEndReset() -{ - QMetaObject::invokeMethod(this, "_q_sourceReset", Qt::DirectConnection); -} - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kresettingproxymodel.h kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kresettingproxymodel.h --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kresettingproxymodel.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kresettingproxymodel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 KRESETTINGPROXYMODEL -#define KRESETTINGPROXYMODEL - -#include - -/** - * This class is a workaround for buggy handling of insert/remove signals in QML: - * http://bugreports.qt.nokia.com/browse/QTBUG-11644 - */ -class KResettingProxyModel : public QSortFilterProxyModel -{ - Q_OBJECT -public: - KResettingProxyModel(QObject* parent = 0); - - virtual void setSourceModel(QAbstractItemModel* sourceModel); - -private slots: - void slotBeginReset(); - void slotEndReset(); - -}; - -#endif diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kselectionproxymodel.cpp kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kselectionproxymodel.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kselectionproxymodel.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kselectionproxymodel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,2314 +0,0 @@ -/* - Copyright (c) 2009 Stephen Kelly - - 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 "kselectionproxymodel.h" - -#include -#include -#include - -/** - Return true if @p idx is a descendant of one of the indexes in @p list. - Note that this returns false if @p list contains @p idx. -*/ -template -bool isDescendantOf(const QList &list, const QModelIndex &idx) -{ - if (!idx.isValid()) - return false; - - if (list.contains(idx)) - return false; - - QModelIndex parent = idx.parent(); - while (parent.isValid()) { - if (list.contains(parent)) - return true; - parent = parent.parent(); - } - return false; -} - -static bool isDescendantOf(const QModelIndex &ancestor, const QModelIndex &descendant) -{ - if (!descendant.isValid()) - return false; - - if (ancestor == descendant) - return false; - - QModelIndex parent = descendant.parent(); - while (parent.isValid()) { - if (parent == ancestor) - return true; - - parent = parent.parent(); - } - return false; -} - -static bool isDescendantOf(const QItemSelection &selection, const QModelIndex &descendant) -{ - if (!descendant.isValid()) - return false; - - if (selection.contains(descendant)) - return false; - - QModelIndex parent = descendant.parent(); - while (parent.isValid()) { - if (selection.contains(parent)) - return true; - - parent = parent.parent(); - } - return false; -} - -static bool isDescendantOf(const QItemSelectionRange &range, const QModelIndex &descendant) -{ - if (!descendant.isValid()) - return false; - - if (range.contains(descendant)) - return false; - - QModelIndex parent = descendant.parent(); - while (parent.isValid()) { - if (range.contains(parent)) - return true; - - parent = parent.parent(); - } - return false; -} - -static int _getRootListRow(const QList &rootAncestors, const QModelIndex &index) -{ - QModelIndex commonParent = index; - QModelIndex youngestAncestor; - - int firstCommonParent = -1; - int bestParentRow = -1; - while (commonParent.isValid()) { - youngestAncestor = commonParent; - commonParent = commonParent.parent(); - - for (int i = 0; i < rootAncestors.size(); ++i) { - const QModelIndexList ancestorList = rootAncestors.at(i); - - const int parentRow = ancestorList.indexOf(commonParent); - - if (parentRow < 0) - continue; - - if (parentRow > bestParentRow) { - firstCommonParent = i; - bestParentRow = parentRow; - } - } - - if (firstCommonParent >= 0) - break; - } - - // If @p list is non-empty, the invalid QModelIndex() will at least be found in ancestorList. - Q_ASSERT(firstCommonParent >= 0); - - const QModelIndexList firstAnsList = rootAncestors.at(firstCommonParent); - - const QModelIndex eldestSibling = firstAnsList.value(bestParentRow + 1); - - if (eldestSibling.isValid()) { - // firstCommonParent is a sibling of one of the ancestors of @p index. - // It is the first index to share a common parent with one of the ancestors of @p index. - if (eldestSibling.row() >= youngestAncestor.row()) - return firstCommonParent; - } - - int siblingOffset = 1; - - // The same commonParent might be common to several root indexes. - // If this is the last in the list, it's the only match. We instruct the model - // to insert the new index after it ( + siblingOffset). - if (rootAncestors.size() <= firstCommonParent + siblingOffset) { - return firstCommonParent + siblingOffset; - } - - // A - // - B - // - C - // - D - // - E - // F - // - // F is selected, then C then D. When inserting D into the model, the commonParent is B (the parent of C). - // The next existing sibling of B is F (in the proxy model). bestParentRow will then refer to an index on - // the level of a child of F (which doesn't exist - Boom!). If it doesn't exist, then we've already found - // the place to insert D - QModelIndexList ansList = rootAncestors.at(firstCommonParent + siblingOffset); - if (ansList.size() <= bestParentRow) { - return firstCommonParent + siblingOffset; - } - - QModelIndex nextParent = ansList.at(bestParentRow); - while (nextParent == commonParent) { - if (ansList.size() < bestParentRow + 1) - // If the list is longer, it means that at the end of it is a descendant of the new index. - // We insert the ancestors items first in that case. - break; - - const QModelIndex nextSibling = ansList.value(bestParentRow + 1); - - if (!nextSibling.isValid()) { - continue; - } - - if (youngestAncestor.row() <= nextSibling.row()) { - break; - } - - siblingOffset++; - - if (rootAncestors.size() <= firstCommonParent + siblingOffset) - break; - - ansList = rootAncestors.at(firstCommonParent + siblingOffset); - - // In the scenario above, E is selected after D, causing this loop to be entered, - // and requiring a similar result if the next sibling in the proxy model does not have children. - if (ansList.size() <= bestParentRow) { - break; - } - - nextParent = ansList.at(bestParentRow); - } - - return firstCommonParent + siblingOffset; -} - -/** - Determines the correct location to insert @p index into @p list. -*/ -template -static int getRootListRow(const QList &list, const QModelIndex &index) -{ - if (!index.isValid()) - return -1; - - if (list.isEmpty()) - return 0; - - // What's going on? - // Consider a tree like - // - // A - // - B - // - - C - // - - - D - // - E - // - F - // - - G - // - - - H - // - I - // - - J - // - K - // - // If D, E and J are already selected, and H is newly selected, we need to put H between E and J in the proxy model. - // To figure that out, we create a list for each already selected index of its ancestors. Then, - // we climb the ancestors of H until we reach an index with siblings which have a descendant - // selected (F above has siblings B, E and I which have descendants which are already selected). - // Those child indexes are traversed to find the right sibling to put F beside. - // - // i.e., new items are inserted in the expected location. - - QList rootAncestors; - foreach(const QModelIndex &root, list) { - QModelIndexList ancestors; - ancestors << root; - QModelIndex parent = root.parent(); - while (parent.isValid()) { - ancestors.prepend(parent); - parent = parent.parent(); - } - ancestors.prepend(QModelIndex()); - rootAncestors << ancestors; - } - return _getRootListRow(rootAncestors, index); -} - -/** - Returns a selection in which no descendants of selected indexes are also themselves selected. - For example, - @code - A - - B - C - D - @endcode - If A, B and D are selected in @p selection, the returned selection contains only A and D. -*/ -static QItemSelection getRootRanges(const QItemSelection &_selection) -{ - QItemSelection rootSelection; - QItemSelection selection = _selection; - QList::iterator it = selection.begin(); - while (it != selection.end()) { - if (!it->topLeft().parent().isValid()) - { - rootSelection.append(*it); - it = selection.erase(it); - } else - ++it; - } - - it = selection.begin(); - const QList::iterator end = selection.end(); - while ( it != end ) { - const QItemSelectionRange range = *it; - it = selection.erase(it); - - if (isDescendantOf(rootSelection, range.topLeft()) || isDescendantOf(selection, range.topLeft())) - continue; - - rootSelection << range; - } - return rootSelection; -} - -template -ForwardIterator kMaxElement(ForwardIterator it, ForwardIterator end) -{ - ForwardIterator result = it; - for ( ; it != end; ++it) - { - if (*result < *it) - result = it; - } - return result; -} -/** - */ -struct RangeLessThan -{ - bool operator()(const QItemSelectionRange &left, const QItemSelectionRange &right) - { - if (right.model() == left.model()) { - // parent has to be calculated, so we only do so once. - const QModelIndex topLeftParent = left.parent(); - const QModelIndex otherTopLeftParent = right.parent(); - if (topLeftParent == otherTopLeftParent) { - if (right.top() == left.top()) { - if (right.left() == left.left()) { - if (right.bottom() == left.bottom()) { - return left.right() < right.right(); - } - return left.bottom() < right.bottom(); - } - return left.left() < right.left(); - } - return left.top() < right.top(); - } - return topLeftParent < otherTopLeftParent; - } - return left.model() < right.model(); - } -}; - -static QItemSelection stableNormalizeSelection(QItemSelection selection) -{ - if (selection.size() <= 1) - return selection; - - QList::iterator it = selection.begin(); - - Q_ASSERT(it != selection.end()); - QList::iterator scout = it + 1; - while (scout != selection.end()) { - Q_ASSERT(it != selection.end()); - int bottom = it->bottom(); - while (scout != selection.end() && it->parent() == scout->parent() && bottom + 1 == scout->top()) { - bottom = scout->bottom(); - scout = selection.erase(scout); - } - if (bottom != it->bottom()) { - const QModelIndex topLeft = it->topLeft(); - *it = QItemSelectionRange(topLeft, topLeft.sibling(bottom, it->right())); - } - Q_ASSERT(it != scout); - if (scout == selection.end()) - break; - it = scout; - ++scout; - } - return selection; -} - -static QItemSelection normalizeSelection(QItemSelection selection) -{ - if (selection.size() <= 1) - return selection; - - RangeLessThan lt; - qSort(selection.begin(), selection.end(), lt); - return stableNormalizeSelection(selection); -} - - -KSelectionProxyModelPrivate::KSelectionProxyModelPrivate(KSelectionProxyModel* model, QItemSelectionModel* selectionModel) - : q_ptr(model), - m_startWithChildTrees(false), - m_omitChildren(false), - m_omitDescendants(false), - m_includeAllSelected(false), - m_rowsInserted(false), - m_rowsRemoved(false), - m_rowsMoved(false), - m_resetting(false), - m_ignoreNextLayoutAboutToBeChanged(false), - m_ignoreNextLayoutChanged(false), - m_selectionModel(selectionModel), - m_nextId(1) -{ - // QItemSelectionModel doesn't clear its selection when its model is reset so we do it manually here. - // Fixed in Qt 4.7: http://qt.gitorious.org/qt/qt/merge_requests/639 - QObject::connect(selectionModel->model(), SIGNAL(modelAboutToBeReset()), selectionModel, SLOT(clear())); -} - -void KSelectionProxyModelPrivate::emitContinuousRanges(const QModelIndex &sourceFirst, const QModelIndex &sourceLast, - const QModelIndex &proxyFirst, const QModelIndex &proxyLast) -{ - Q_Q(KSelectionProxyModel); - - const int proxyRangeSize = proxyLast.row() - proxyFirst.row(); - const int sourceRangeSize = sourceLast.row() - sourceFirst.row(); - - if (proxyRangeSize == sourceRangeSize) { - emit q->dataChanged(proxyFirst, proxyLast); - return; - } - - - // TODO: Loop to skip descendant ranges. -// int lastRow; -// -// const QModelIndex sourceHalfWay = sourceFirst.sibling(sourceFirst.row() + (sourceRangeSize / 2)); -// const QModelIndex proxyHalfWay = proxyFirst.sibling(proxyFirst.row() + (proxyRangeSize / 2)); -// const QModelIndex mappedSourceHalfway = q->mapToSource(proxyHalfWay); -// -// const int halfProxyRange = mappedSourceHalfway.row() - proxyFirst.row(); -// const int halfSourceRange = sourceHalfWay.row() - sourceFirst.row(); -// -// if (proxyRangeSize == sourceRangeSize) -// { -// emit q->dataChanged(proxyFirst, proxyLast.sibling(proxyFirst.row() + proxyRangeSize, proxyLast.column())); -// return; -// } - - emit q->dataChanged(proxyFirst, proxyLast); -} - -void KSelectionProxyModelPrivate::sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) -{ - Q_Q(KSelectionProxyModel); - - const QModelIndex proxyTopLeft = q->mapFromSource(topLeft); - const QModelIndex proxyBottomRight = q->mapFromSource(bottomRight); - - const QModelIndex proxyRangeParent = proxyTopLeft.parent(); - - if (!m_omitChildren && m_omitDescendants && m_startWithChildTrees && m_includeAllSelected) { - // ChildrenOfExactSelection - if (proxyTopLeft.isValid()) - emitContinuousRanges(topLeft, bottomRight, proxyTopLeft, proxyBottomRight); - return; - } - - if ((m_omitChildren && !m_startWithChildTrees && m_includeAllSelected) - || (!proxyRangeParent.isValid() && !m_startWithChildTrees)) { - // Exact selection and SubTreeRoots and SubTrees in top level - // Emit continuous ranges. - QList changedRows; - for (int row = topLeft.row(); row < bottomRight.row(); ++row) { - const QModelIndex index = q->sourceModel()->index(row, topLeft.column(), topLeft.parent()); - const int idx = m_rootIndexList.indexOf(index); - if (idx != -1) { - changedRows.append(idx); - } - } - if (changedRows.isEmpty()) - return; - int first = changedRows.first(); - int previous = first; - QList::const_iterator it = changedRows.constBegin(); - const QList::const_iterator end = changedRows.constEnd(); - for ( ; it != end; ++it) { - if (*it == previous + 1) { - ++previous; - } else { - const QModelIndex _top = q->index(first, topLeft.column()); - const QModelIndex _bottom = q->index(previous, bottomRight.column()); - emit q->dataChanged(_top, _bottom); - previous = first = *it; - } - } - if (first != previous) { - const QModelIndex _top = q->index(first, topLeft.column()); - const QModelIndex _bottom = q->index(previous, bottomRight.column()); - emit q->dataChanged(_top, _bottom); - } - return; - } - if (proxyRangeParent.isValid()) { - if (m_omitChildren && !m_startWithChildTrees && !m_includeAllSelected) - // SubTreeRoots - return; - if (!proxyTopLeft.isValid()) - return; - // SubTrees and SubTreesWithoutRoots - emit q->dataChanged(proxyTopLeft, proxyBottomRight); - return; - } - - if (m_startWithChildTrees && !m_omitChildren && !m_includeAllSelected && !m_omitDescendants) { - // SubTreesWithoutRoots - if (proxyTopLeft.isValid()) - emit q->dataChanged(proxyTopLeft, proxyBottomRight); - return; - } -} - -void KSelectionProxyModelPrivate::sourceLayoutAboutToBeChanged() -{ - Q_Q(KSelectionProxyModel); - - if (m_ignoreNextLayoutAboutToBeChanged) { - m_ignoreNextLayoutAboutToBeChanged = false; - return; - } - - if (!m_selectionModel->hasSelection()) - return; - - emit q->layoutAboutToBeChanged(); - - QPersistentModelIndex srcPersistentIndex; - foreach(const QPersistentModelIndex &proxyPersistentIndex, q->persistentIndexList()) { - m_proxyIndexes << proxyPersistentIndex; - Q_ASSERT(proxyPersistentIndex.isValid()); - srcPersistentIndex = q->mapToSource(proxyPersistentIndex); - Q_ASSERT(srcPersistentIndex.isValid()); - m_layoutChangePersistentIndexes << srcPersistentIndex; - } - - SourceProxyIndexMapping::left_const_iterator parentIt = m_mappedParents.leftConstBegin(); - const SourceProxyIndexMapping::left_const_iterator parentEnd = m_mappedParents.leftConstEnd(); - for ( ; parentIt != parentEnd; ++parentIt) { - m_sourcePersistentParents << parentIt.key(); - m_weakSourceParents << parentIt.key(); - m_sourceGrandParents << parentIt.key().parent(); - } - SourceProxyIndexMapping::left_const_iterator firstChildIt = m_mappedFirstChildren.leftConstBegin(); - const SourceProxyIndexMapping::left_const_iterator firstChildEnd = m_mappedFirstChildren.leftConstEnd(); - for ( ; firstChildIt != firstChildEnd; ++firstChildIt) { - m_sourcePersistentFirstChilds << firstChildIt.key(); - m_weakSourceFirstChilds << firstChildIt.key(); - m_sourceFirstChildParents << firstChildIt.key().parent(); - } - QList::const_iterator rootIt = m_rootIndexList.constBegin(); - const QList::const_iterator rootEnd = m_rootIndexList.constEnd(); - for ( ; rootIt != rootEnd; ++rootIt) { - m_weakRootIndexes << *rootIt; - m_weakRootParents << rootIt->parent(); - } -} - -void KSelectionProxyModelPrivate::refreshFirstChildMappings(QList &mappings) -{ - Q_Q(KSelectionProxyModel); - - QList::const_iterator it = mappings.constBegin(); - const QList::const_iterator end = mappings.constEnd(); - - for ( ; it != end; ++it) { - if (!it->isValid()) { - m_mappedFirstChildren.removeLeft(*it); - continue; - } - if (!it->parent().isValid()) - continue; - - Q_ASSERT(m_mappedFirstChildren.leftContains(*it)); - m_mappedFirstChildren.removeLeft(*it); - - int _newProxyRow = 0; - const int rootListRow = m_rootIndexList.indexOf(it->parent()); - for (int i = 0; i < rootListRow; ++i) - _newProxyRow += q->sourceModel()->rowCount(m_rootIndexList.at(i)); - - createFirstChildMapping(it->parent(), _newProxyRow); - } -} - -void KSelectionProxyModelPrivate::refreshParentMappings(QList &mappings) -{ - Q_Q(KSelectionProxyModel); - - const int lastSize = mappings.size(); - - QList::iterator it = mappings.begin(); - - while (it != mappings.end()) { - if (!it->isValid()) { - m_parentIds.removeRight(m_mappedParents.takeLeft(*it)); - it = mappings.erase(it); - continue; - } - if (it->parent().isValid() || m_mappedParents.leftContains(it->parent()) || m_rootIndexList.contains(*it)) { - const qint64 id = m_parentIds.takeRight(m_mappedParents.takeLeft(*it)); - const QModelIndex newProxyIndex = q->mapFromSource(*it); - m_mappedParents.insert(*it, newProxyIndex); - m_parentIds.insert(id, newProxyIndex); - - it = mappings.erase(it); - } else - ++it; - } - if (!mappings.isEmpty()) { - if (lastSize == mappings.size()) { - Q_ASSERT(!"Something went very wrong"); - return; - } - refreshParentMappings(mappings); - } -} - -void KSelectionProxyModelPrivate::sourceLayoutChanged() -{ - Q_Q(KSelectionProxyModel); - - if (m_ignoreNextLayoutChanged) { - m_ignoreNextLayoutChanged = false; - return; - } - - if (!m_selectionModel->hasSelection()) { - return; - } - - QList parentMappingsToUpdate; - for (int i = 0; i < m_sourcePersistentParents.size(); ++i) { - const QPersistentModelIndex persistentIndex = m_sourcePersistentParents.at(i); - const QModelIndex nonPersistentIndex = m_weakSourceParents.at(i); - if (persistentIndex.row() == nonPersistentIndex.row() - && persistentIndex.column() == nonPersistentIndex.column() - && persistentIndex.parent() == m_sourceGrandParents.at(i)) - continue; - - parentMappingsToUpdate << persistentIndex; - } - if (!parentMappingsToUpdate.isEmpty()) - refreshParentMappings(parentMappingsToUpdate); - - QList changedRoots; - QList::iterator rootIt = m_rootIndexList.begin(); - const QList::iterator rootEnd = m_rootIndexList.end(); - int rootPosition = 0; - while (rootIt != rootEnd) { - const QPersistentModelIndex persistentIndex = *rootIt; - const QModelIndex nonPersistentIndex = m_weakRootIndexes.at(rootPosition); - const QModelIndex weakParent = m_weakRootParents.at(rootPosition); - ++rootPosition; - if (persistentIndex.row() == nonPersistentIndex.row() - && persistentIndex.column() == nonPersistentIndex.column() - && persistentIndex.parent() == weakParent) { - ++rootIt; - continue; - } - - if (persistentIndex.isValid()) - changedRoots << persistentIndex; - - rootIt = m_rootIndexList.erase(rootIt); - } - foreach(const QPersistentModelIndex &idx, changedRoots) { - int row = getRootListRow(m_rootIndexList, idx); - m_rootIndexList.insert(row, idx); - } - - QList firstChildsToUpdate; - for (int i = 0; i < m_sourcePersistentFirstChilds.size(); ++i) { - const QPersistentModelIndex persistentIndex = m_sourcePersistentFirstChilds.at(i); - const QModelIndex nonPersistentIndex = m_weakSourceFirstChilds.at(i); - if (persistentIndex.row() == nonPersistentIndex.row() - && persistentIndex.column() == nonPersistentIndex.column() - && persistentIndex.parent() == m_sourceFirstChildParents.at(i)) - continue; - - firstChildsToUpdate << persistentIndex; - } - if (!firstChildsToUpdate.isEmpty()) - refreshFirstChildMappings(firstChildsToUpdate); - - for (int i = 0; i < m_proxyIndexes.size(); ++i) { - // Need to update m_mappedParents and m_mappedFirstChildren and m_parentIds before trying mapFromSource. - q->changePersistentIndex(m_proxyIndexes.at(i), q->mapFromSource(m_layoutChangePersistentIndexes.at(i))); - } - - m_layoutChangePersistentIndexes.clear(); - m_proxyIndexes.clear(); - - m_weakSourceParents.clear(); - m_weakSourceFirstChilds.clear(); - m_weakRootIndexes.clear(); - m_weakRootParents.clear(); - m_sourceFirstChildParents.clear(); - m_sourceGrandParents.clear(); - m_sourcePersistentParents.clear(); - m_sourcePersistentFirstChilds.clear(); - - emit q->layoutChanged(); -} - -void KSelectionProxyModelPrivate::resetInternalData() -{ - m_rootIndexList.clear(); - m_layoutChangePersistentIndexes.clear(); - m_proxyIndexes.clear(); - m_weakSourceParents.clear(); - m_weakSourceFirstChilds.clear(); - m_weakRootIndexes.clear(); - m_weakRootParents.clear(); - m_sourceFirstChildParents.clear(); - m_sourceGrandParents.clear(); - m_sourcePersistentParents.clear(); - m_sourcePersistentFirstChilds.clear(); - m_mappedParents.clear(); - m_parentIds.clear(); - m_mappedFirstChildren.clear(); - m_nextId = 1; -} - -void KSelectionProxyModelPrivate::sourceModelDestroyed() -{ - Q_Q(KSelectionProxyModel); - // There is very little we can do here. - resetInternalData(); - m_resetting = false; - q->endResetModel(); -} - -void KSelectionProxyModelPrivate::sourceModelAboutToBeReset() -{ - Q_Q(KSelectionProxyModel); - - // Deselecting an index in the selectionModel will cause it to - // be removed from m_rootIndexList, so we don't need to clear - // the list here manually. - // We also don't need to notify that an index is about to be removed. - m_selectionModel->clearSelection(); - - q->beginResetModel(); - m_resetting = true; -} - -void KSelectionProxyModelPrivate::sourceModelReset() -{ - Q_Q(KSelectionProxyModel); - - // No need to try to refill this. When the model is reset it doesn't have a meaningful selection anymore, - // but when it gets one we'll be notified anyway. - resetInternalData(); - m_resetting = false; - q->endResetModel(); -} - -int KSelectionProxyModelPrivate::getProxyInitialRow(const QModelIndex &parent) const -{ - Q_ASSERT(m_rootIndexList.contains(parent)); - - // The difficulty here is that parent and parent.parent() might both be in the m_rootIndexList. - - // - A - // - B - // - - C - // - - D - // - - - E - - // Consider that B and D are selected. The proxy model is: - - // - C - // - D - // - E - - // Then D gets a new child at 0. In that case we require adding F between D and E. - - // Consider instead that D gets removed. Then @p parent will be B. - - - Q_Q(const KSelectionProxyModel); - int parentPosition = m_rootIndexList.indexOf(parent); - - QModelIndex parentAbove; - - // If parentPosition == 0, then parent.parent() is not also in the model. (ordering is preserved) - while (parentPosition > 0) { - parentPosition--; - - parentAbove = m_rootIndexList.at(parentPosition); - Q_ASSERT(parentAbove.isValid()); - - int rows = q->sourceModel()->rowCount(parentAbove); - if (rows > 0) { - QModelIndex sourceIndexAbove = q->sourceModel()->index(rows - 1, 0, parentAbove); - Q_ASSERT(sourceIndexAbove.isValid()); - QModelIndex proxyChildAbove = q->mapFromSource(sourceIndexAbove); - Q_ASSERT(proxyChildAbove.isValid()); - return proxyChildAbove.row() + 1; - } - } - return 0; -} - -void KSelectionProxyModelPrivate::updateFirstChildMapping(const QModelIndex& parent, int offset) -{ - Q_Q(KSelectionProxyModel); - - static const int column = 0; - static const int row = 0; - - const QPersistentModelIndex srcIndex = q->sourceModel()->index(row, column, parent); - - const QPersistentModelIndex previousFirstChild = q->sourceModel()->index(offset, column, parent); - - SourceProxyIndexMapping::left_iterator it = m_mappedFirstChildren.findLeft(previousFirstChild); - if (it == m_mappedFirstChildren.leftEnd()) - return; - - Q_ASSERT(srcIndex.isValid()); - const QModelIndex proxyIndex = it.value(); - Q_ASSERT(proxyIndex.isValid()); - Q_ASSERT(proxyIndex.model() == q); - - m_mappedFirstChildren.eraseLeft(it); - - // The proxy index in the mapping has already been updated by the offset in updateInternalTopIndexes - // so we restore it by applying the reverse. - const QModelIndex newProxyIndex = q->createIndex(proxyIndex.row() - offset, proxyIndex.column()); - m_mappedFirstChildren.insert(srcIndex, newProxyIndex); -} - -QPair< int, int > KSelectionProxyModelPrivate::beginInsertRows(const QModelIndex& parent, int start, int end) const -{ - Q_Q(const KSelectionProxyModel); - - const QModelIndex proxyParent = q->mapFromSource(parent); - - if (!m_startWithChildTrees) { - // SubTrees - if (proxyParent.isValid()) - return qMakePair(start, end); - return qMakePair(-1, -1); - } - - if (!m_includeAllSelected && proxyParent.isValid()) { - // SubTreesWithoutRoots deeper than topLevel - return qMakePair(start, end); - } - - if (!m_rootIndexList.contains(parent)) - return qMakePair(-1, -1); - - const int proxyStartRow = getProxyInitialRow(parent) + start; - return qMakePair(proxyStartRow, proxyStartRow + (end - start)); -} - -void KSelectionProxyModelPrivate::sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end) -{ - Q_Q(KSelectionProxyModel); - - if (!m_selectionModel->hasSelection()) - return; - - if (m_omitChildren) - // ExactSelection and SubTreeRoots - return; - - // topLevel insertions can be ignored because topLevel items would need to be selected to affect the proxy. - if (!parent.isValid()) - return; - - QPair pair = beginInsertRows(parent, start, end); - if (pair.first == -1) - return; - - const QModelIndex proxyParent = m_startWithChildTrees ? QModelIndex() : q->mapFromSource(parent); - - m_rowsInserted = true; - q->beginInsertRows(proxyParent, pair.first, pair.second); -} - -void KSelectionProxyModelPrivate::endInsertRows(const QModelIndex& parent, int start, int end) -{ - Q_Q(const KSelectionProxyModel); - const QModelIndex proxyParent = q->mapFromSource(parent); - const int offset = end - start + 1; - - const bool isNewParent = (q->sourceModel()->rowCount(parent) == offset); - - if (m_startWithChildTrees && m_rootIndexList.contains(parent)) { - const int proxyInitialRow = getProxyInitialRow(parent); - Q_ASSERT(proxyInitialRow >= 0); - const int proxyStartRow = proxyInitialRow + start; - - updateInternalTopIndexes(proxyStartRow, offset); - if (isNewParent) - createFirstChildMapping(parent, proxyStartRow); - else if (start == 0) - // We already have a first child mapping, but what we have mapped is not the first child anymore - // so we need to update it. - updateFirstChildMapping(parent, end + 1); - } else { - Q_ASSERT(proxyParent.isValid()); - if (!isNewParent) - updateInternalIndexes(proxyParent, start, offset); - else - createParentMappings(parent.parent(), parent.row(), parent.row()); - } - createParentMappings(parent, start, end); -} - -void KSelectionProxyModelPrivate::sourceRowsInserted(const QModelIndex &parent, int start, int end) -{ - Q_Q(KSelectionProxyModel); - - if (!m_rowsInserted) - return; - m_rowsInserted = false; - endInsertRows(parent, start, end); - q->endInsertRows(); -} - -QPair KSelectionProxyModelPrivate::beginRemoveRows(const QModelIndex& parent, int start, int end) const -{ - Q_Q(const KSelectionProxyModel); - QPair pair = qMakePair(start, end); - - if (m_omitChildren && !m_startWithChildTrees && !m_includeAllSelected) { - // SubTreeRoots - if (m_rootIndexList.contains(parent) || isDescendantOf(m_rootIndexList, parent)) { - return qMakePair(-1, -1); - } - } - - const QModelIndex proxyParent = mapParentFromSource(parent); - - if (!m_includeAllSelected && !m_omitChildren) { - // SubTrees and SubTreesWithoutRoots - if (proxyParent.isValid()) { - return pair; - } - if (m_startWithChildTrees && m_rootIndexList.contains(parent)) { - // SubTreesWithoutRoots topLevel - const int proxyStartRow = getProxyInitialRow(parent) + start; - return qMakePair(proxyStartRow, proxyStartRow + (end - start)); - } - } - - if (m_includeAllSelected && m_startWithChildTrees) { - // ChildrenOfExactSelection - int position = m_rootIndexList.indexOf(parent); - if (position != -1) { - const int proxyStartRow = getProxyInitialRow(parent) + start; - int proxyEndRow = proxyStartRow + (end - start); - ++position; - while (m_rootIndexList.size() < position) { - const QModelIndex idx = m_rootIndexList.at(position); - if (isDescendantOf(parent, idx)) - proxyEndRow += q->sourceModel()->rowCount(idx); - else - break; - } - return qMakePair(proxyStartRow, proxyEndRow); - } - } - - QList::const_iterator rootIt = m_rootIndexList.constBegin(); - const QList::const_iterator rootEnd = m_rootIndexList.constEnd(); - int rootPosition = 0; - int rootStartRemove = -1; - int rootEndRemove = -1; - int siblingCount = 0; - - for ( ; rootIt != rootEnd; ++rootIt, ++rootPosition) { - if (m_omitChildren && m_includeAllSelected) { - // ExactSelection - if (parent == rootIt->parent() && rootIt->row() <= end && rootIt->row() >= start) { - if (rootStartRemove == -1) - rootStartRemove = rootPosition; - ++rootEndRemove; - } else { - if (rootStartRemove != -1) - break; - } - } else { - if (isDescendantOf(parent, *rootIt)) { - if (rootStartRemove == -1) - rootStartRemove = rootPosition; - ++rootEndRemove; - if (m_startWithChildTrees) - siblingCount += q->sourceModel()->rowCount(*rootIt); - } else { - if (rootStartRemove != -1) - break; - } - } - } - if (rootStartRemove != -1) { - return qMakePair(siblingCount + rootStartRemove, siblingCount + rootEndRemove); - } - - return qMakePair(-1, -1); -} - -void KSelectionProxyModelPrivate::sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) -{ - Q_Q(KSelectionProxyModel); - - if (!m_selectionModel->hasSelection()) - return; - - QPair pair = beginRemoveRows(parent, start, end); - if (pair.first == -1) - return; - - const QModelIndex proxyParent = mapParentFromSource(parent); - - m_rowsRemoved = true; - m_proxyRemoveRows = pair; - q->beginRemoveRows(proxyParent, pair.first, pair.second); -} - -void KSelectionProxyModelPrivate::endRemoveRows(const QModelIndex &sourceParent, int proxyStart, int proxyEnd) -{ - const QModelIndex proxyParent = mapParentFromSource(sourceParent); - - if (proxyParent.isValid()) - updateInternalIndexes(proxyParent, proxyEnd + 1, -1*(proxyEnd - proxyStart + 1)); - else - updateInternalTopIndexes(proxyEnd + 1, -1*(proxyEnd - proxyStart + 1)); - - { - SourceProxyIndexMapping::right_iterator it = m_mappedParents.rightBegin(); - - while (it != m_mappedParents.rightEnd()) { - if (!it.value().isValid()) { - m_parentIds.removeRight(it.key()); - it = m_mappedParents.eraseRight(it); - } else - ++it; - } - } - - { - // Depending on what is selected at the time, a single removal in the source could invalidate - // many mapped first child items at once. - - // - A - // - B - // - - C - // - - D - // - - - E - // - - - F - // - - - - G - // - - - - H - - // If D and F are selected, the proxy contains E, F, G, H. If B is then deleted E to H will - // be removed, including both first child mappings at E and G. - - SourceProxyIndexMapping::right_iterator it = m_mappedFirstChildren.rightBegin(); - - while (it != m_mappedFirstChildren.rightEnd()) { - if (!it.value().isValid()) - it = m_mappedFirstChildren.eraseRight(it); - else - ++it; - } - } - - QList::iterator rootIt = m_rootIndexList.begin(); - while (rootIt != m_rootIndexList.end()) { - if (!rootIt->isValid()) - rootIt = m_rootIndexList.erase(rootIt); - else - ++rootIt; - } -} - -void KSelectionProxyModelPrivate::sourceRowsRemoved(const QModelIndex &parent, int start, int end) -{ - Q_Q(KSelectionProxyModel); - Q_UNUSED(end) - - if (!m_selectionModel->hasSelection()) - return; - - if (!m_rowsRemoved) - return; - m_rowsRemoved = false; - - Q_ASSERT(m_proxyRemoveRows.first >= 0); - Q_ASSERT(m_proxyRemoveRows.second >= 0); - endRemoveRows(parent, m_proxyRemoveRows.first, m_proxyRemoveRows.second); - if (m_startWithChildTrees && start == 0 && q->sourceModel()->hasChildren(parent)) - // The private endRemoveRows call might remove the first child mapping for parent, so - // we create it again in that case. - createFirstChildMapping(parent, m_proxyRemoveRows.first); - - m_proxyRemoveRows = qMakePair(-1, -1); - q->endRemoveRows(); -} - -void KSelectionProxyModelPrivate::sourceRowsAboutToBeMoved(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) -{ - Q_Q(KSelectionProxyModel); - - // layout{,AboutToBe}Changed signals are emitted by QAIM for backward compatibility reasons when rows are moved. - // Processing them is expensive so we do our best to avoid them. - m_ignoreNextLayoutAboutToBeChanged = true; - - if (!m_selectionModel->hasSelection()) - return; - - const QPair removePair = beginRemoveRows(srcParent, srcStart, srcEnd); - const bool notifyRemove = removePair.first != -1; - - const QModelIndex proxyDestination = q->mapFromSource(destParent); - - // Notify insert if - // - The destParent is valid or m_startWithChildTrees and destParent is in rootIndexList - // - Not m_startWithChildTrees and we are moving elements of rootIndexList - - if (!m_startWithChildTrees) { -// if (m_rootIndexList.contains()) - { - - - } - } - -#if 0 - if (m_omitChildren && !m_startWithChildTrees && m_includeAllSelected) { - // ExactSelection - int row = srcStart; - int proxyStart = -1; - static const int column = 0; - for ( ; row < srcEnd; ++row) { - const QModelIndex idx = q->sourceModel()->index(row, column, srcParent); - proxyStart = m_rootIndexList.indexOf(idx); - if (proxyStart != -1) { - break; - } - } - if (proxyStart == -1) - return; - const int rangeStart = row; - row = srcEnd; - int proxyEnd = proxyStart; - for ( ; row > rangeStart; --row) { - const QModelIndex idx = q->sourceModel()->index(row, column, srcParent); - if (m_rootIndexList.contains(idx) || isDescendantOf(srcParent, idx)) { - proxyEnd = m_rootIndexList.indexOf(idx); - break; - } - } - // Figure out if destination is actually a change. - } -#endif - - - bool notifyDestination = proxyDestination.isValid(); - - if (proxyDestination.isValid() && (m_omitChildren || (m_startWithChildTrees && m_omitDescendants))) - notifyDestination = false; - - if (m_includeAllSelected && !m_startWithChildTrees) { - int destMoveRow = -1; - - QList::const_iterator it = m_rootIndexList.constBegin(); - const QList::const_iterator end = m_rootIndexList.constEnd(); - - int startMoveRow = -1; - int endMoveRow = -1; - int count = 0; - int row; - for ( ; it != end; ++it, ++count) { - row = it->row(); - if ((row >= srcStart && row <= srcEnd) && q->sourceModel()->parent(*it) == srcParent) { - if (startMoveRow == -1) { - startMoveRow = count; - endMoveRow = count; - - if (destMoveRow == -1) { - if (destParent.isValid()) - destMoveRow = getRootListRow(m_rootIndexList, destParent); - else - destMoveRow = it->row(); - } - } else - ++endMoveRow; - } else { - if (row < destRow && q->sourceModel()->parent(*it) == destParent) { - if (destMoveRow == -1) - if (destParent.isValid()) - destMoveRow = getRootListRow(m_rootIndexList, destParent); - else - destMoveRow = it->row(); - else - ++destMoveRow; - } - } - } - if (startMoveRow != -1 && (destMoveRow < startMoveRow || destMoveRow > endMoveRow)) { - Q_ASSERT(destMoveRow != -1); - q->beginMoveRows(QModelIndex(), startMoveRow, endMoveRow, QModelIndex(), destMoveRow); - m_rowsMoved = true; - } - return; - } - - const bool srcInModel = (!m_startWithChildTrees && isInModel(srcParent)) || (m_startWithChildTrees && m_rootIndexList.contains(srcParent)); - const bool destInModel = (!m_startWithChildTrees && isInModel(destParent)) || (m_startWithChildTrees && m_rootIndexList.contains(destParent)); - - if (srcInModel) { - if (destInModel) { - // The easy case. - const bool allowMove = q->beginMoveRows(q->mapFromSource(srcParent), srcStart, srcEnd, q->mapFromSource(destParent), destRow); - Q_UNUSED(allowMove); // prevent warning in release builds. - Q_ASSERT(allowMove); - m_rowsMoved = true; - } else { - // source is in the proxy, but dest isn't. - // Emit a remove - q->beginRemoveRows(srcParent, srcStart, srcEnd); - } - } else { - if (destInModel) { - // dest is in proxy, but source is not. - // Emit an insert - q->beginInsertRows(destParent, destRow, destRow + (srcEnd - srcStart)); - } - } -} - -void KSelectionProxyModelPrivate::sourceRowsMoved(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) -{ - Q_Q(KSelectionProxyModel); - - m_ignoreNextLayoutChanged = true; - - if (!m_selectionModel->hasSelection()) - return; - - if (m_rowsMoved) { - m_rowsMoved = false; - endRemoveRows(srcParent, srcStart, srcEnd); - endInsertRows(destParent, destRow, destRow + (srcEnd - srcStart)); - q->endMoveRows(); - return; - } - - if (m_rowsRemoved) - q->endRemoveRows(); - - if (m_rowsInserted) - q->endInsertRows(); -} - -void KSelectionProxyModelPrivate::removeSelectionFromProxy(const QItemSelection &selection) -{ - Q_Q(KSelectionProxyModel); - if (selection.isEmpty()) - return; - - q->rootSelectionAboutToBeRemoved(selection); - - foreach(const QItemSelectionRange range, selection) - removeRangeFromProxy(range); -} - -void KSelectionProxyModelPrivate::removeRangeFromProxy(const QItemSelectionRange &range) -{ - Q_Q(KSelectionProxyModel); - - const QModelIndex sourceTopLeft = range.topLeft(); - const QModelIndex proxyTopLeft = q->mapFromSource(sourceTopLeft); - const QModelIndex sourceBottomLeft = range.bottomRight().sibling(range.bottom(), 0); - const QModelIndex proxyBottomLeft = q->mapFromSource(sourceBottomLeft); - const QModelIndex proxyParent = proxyTopLeft.parent(); - const QModelIndex sourceParent = sourceTopLeft.parent(); - - if (m_startWithChildTrees) { - Q_ASSERT(sourceTopLeft.isValid()); - Q_ASSERT(sourceBottomLeft.isValid()); - const int startRootIdx = m_rootIndexList.indexOf(sourceTopLeft); - int endRootIdx = m_rootIndexList.indexOf(sourceBottomLeft); - QItemSelection extraRanges; - if (m_includeAllSelected) { - // It can happen that indexes of descendants get in between indexes which make up a range. - // We handle only the first contiguous block here and handle the rest later. - int idx = startRootIdx; - const int bottomIdx = endRootIdx; - const int rootListSize = m_rootIndexList.size(); - int next = idx + 1; - while (next <= bottomIdx) - { - if (next < rootListSize && m_rootIndexList.at(next).parent() == sourceParent) { - idx = next; - ++next; - } else - break; - } - endRootIdx = idx; - ++idx; - while (idx <= bottomIdx) - { - const QModelIndex index= m_rootIndexList.at(idx); - if (m_rootIndexList.at(idx).parent() == sourceParent) - extraRanges << QItemSelectionRange(index, index); - ++idx; - } - } - Q_ASSERT(endRootIdx != -1); - int childrenCount = q->sourceModel()->rowCount(sourceTopLeft); - for (int rootIdx = startRootIdx + 1; rootIdx <= endRootIdx; ++rootIdx) - { - childrenCount += q->sourceModel()->rowCount(m_rootIndexList.at(rootIdx)); - } - if (childrenCount == 0) - { - for (int rootIdx = startRootIdx; rootIdx <= endRootIdx; ++rootIdx) - { - const QModelIndex idx = m_rootIndexList.at(startRootIdx); - q->rootIndexAboutToBeRemoved(idx); - m_rootIndexList.removeOne(idx); - } - return; - } - if (!m_includeAllSelected) - { - ++endRootIdx; - for ( ; endRootIdx < m_rootIndexList.size(); ++endRootIdx) { - const QModelIndex idx = m_rootIndexList.at(endRootIdx); - if (isDescendantOf(sourceBottomLeft, idx)) - childrenCount += q->sourceModel()->rowCount(idx); - else - break; - } - --endRootIdx; - } - const int proxyStart = getTargetRow(startRootIdx); - int proxyEnd = proxyStart + childrenCount - 1; - q->beginRemoveRows(QModelIndex(), proxyStart, proxyEnd); - - for (int rootIdx = startRootIdx; rootIdx <= endRootIdx; ++rootIdx) - { - q->rootIndexAboutToBeRemoved(m_rootIndexList.at(startRootIdx)); - } - - removeParentMappings(QModelIndex(), proxyStart, proxyEnd); - removeFirstChildMappings(proxyStart, proxyEnd); - int numRemovedChildren = 0; - for (int rootIdx = startRootIdx; rootIdx <= endRootIdx; ++rootIdx) - { - const QModelIndex idx = m_rootIndexList.at(startRootIdx); - const int childCount = q->sourceModel()->rowCount(idx); - m_rootIndexList.removeAt(startRootIdx); - numRemovedChildren += childCount; - } - updateInternalTopIndexes(proxyEnd + 1, -1 * numRemovedChildren); - q->endRemoveRows(); - if (m_includeAllSelected) { - removeSelectionFromProxy(normalizeSelection(extraRanges)); - } - } else { - if (!proxyTopLeft.isValid()) - return; - const int height = range.height(); - q->beginRemoveRows(proxyParent, proxyTopLeft.row(), proxyTopLeft.row() + height - 1); - - // TODO: Do this conditionally if the signal is connected to anything. - for (int i = 0; i < height; ++i) - { - const QModelIndex idx = sourceTopLeft.sibling(range.top() + i, sourceTopLeft.column()); - q->rootIndexAboutToBeRemoved(idx); - } - - removeParentMappings(proxyParent, proxyTopLeft.row(), proxyTopLeft.row() + height - 1); - updateInternalIndexes(proxyParent, proxyTopLeft.row() + height, -1 * height); - - for (int i = 0; i < height; ++i) - { - const QModelIndex idx = sourceTopLeft.sibling(range.top() + i, sourceTopLeft.column()); - Q_ASSERT(idx.isValid()); - const bool b = m_rootIndexList.removeOne(idx); - Q_UNUSED(b) - Q_ASSERT(b); - } - - q->endRemoveRows(); - } -} - -void KSelectionProxyModelPrivate::selectionChanged(const QItemSelection &_selected, const QItemSelection &_deselected) -{ - Q_Q(KSelectionProxyModel); - - if (!q->sourceModel() || (_selected.isEmpty() && _deselected.isEmpty())) - return; - - // Any deselected indexes in the m_rootIndexList are removed. Then, any - // indexes in the selected range which are not a descendant of one of the already selected indexes - // are inserted into the model. - // - // All ranges from the selection model need to be split into individual rows. Ranges which are contiguous in - // the selection model may not be contiguous in the source model if there's a sort filter proxy model in the chain. - // - // Some descendants of deselected indexes may still be selected. The ranges in m_selectionModel->selection() - // are examined. If any of the ranges are descendants of one of the - // indexes in deselected, they are added to the ranges to be inserted into the model. - // - // The new indexes are inserted in sorted order. - - const QItemSelection selected = m_indexMapper->mapSelectionRightToLeft(_selected); - const QItemSelection deselected = m_indexMapper->mapSelectionRightToLeft(_deselected); - -#if QT_VERSION < 0x040800 - // The QItemSelectionModel sometimes doesn't remove deselected items from its selection - // Fixed in Qt 4.8 : http://qt.gitorious.org/qt/qt/merge_requests/2403 - QItemSelection reportedSelection = m_selectionModel->selection(); - reportedSelection.merge(deselected, QItemSelectionModel::Deselect); - QItemSelection fullSelection = m_indexMapper->mapSelectionRightToLeft(reportedSelection); -#else - QItemSelection fullSelection = m_indexMapper->mapSelectionRightToLeft(m_selectionModel->selection()); -#endif - - QItemSelection newRootRanges; - QItemSelection removedRootRanges; - if (!m_includeAllSelected) { - newRootRanges = getRootRanges(selected); - - QItemSelection existingSelection = fullSelection; - // What was selected before the selection was made. - existingSelection.merge(selected, QItemSelectionModel::Deselect); - - // This is similar to m_rootRanges, but that m_rootRanges at this point still contains the roots - // of deselected and existingRootRanges does not. - - const QItemSelection existingRootRanges = getRootRanges(existingSelection); - { - QMutableListIterator i(newRootRanges); - while (i.hasNext()) { - const QItemSelectionRange range = i.next(); - const QModelIndex topLeft = range.topLeft(); - if (isDescendantOf(existingRootRanges, topLeft)) { - i.remove(); - } - } - } - - QItemSelection exposedSelection; - { - QItemSelection deselectedRootRanges = getRootRanges(deselected); - QListIterator i(deselectedRootRanges); - while (i.hasNext()) { - const QItemSelectionRange range = i.next(); - const QModelIndex topLeft = range.topLeft(); - // Consider this: - // - // - A - // - - B - // - - - C - // - - - - D - // - // B and D were selected, then B was deselected and C was selected in one go. - if (!isDescendantOf(existingRootRanges, topLeft)) { - // B is topLeft and fullSelection contains D. - // B is not a descendant of D. - - // range is not a descendant of the selection, but maybe the selection is a descendant of range. - // no need to check selected here. That's already in newRootRanges. - // existingRootRanges and newRootRanges do not overlap. - foreach (const QItemSelectionRange &selectedRange, existingRootRanges) { - const QModelIndex selectedRangeTopLeft = selectedRange.topLeft(); - // existingSelection (and selectedRangeTopLeft) is D. - // D is a descendant of B, so when B was removed, D might have been exposed as a root. - if (isDescendantOf(range, selectedRangeTopLeft) - // But D is also a descendant of part of the new selection C, which is already set to be a new root - // so D would not be added to exposedSelection because C is in newRootRanges. - && !isDescendantOf(newRootRanges, selectedRangeTopLeft)) - exposedSelection.append(selectedRange); - } - removedRootRanges << range; - } - } - } - - QItemSelection obscuredRanges; - { - QListIterator i(existingRootRanges); - while (i.hasNext()) { - const QItemSelectionRange range = i.next(); - if (isDescendantOf(newRootRanges, range.topLeft())) - obscuredRanges << range; - } - } - removedRootRanges << getRootRanges(obscuredRanges); - newRootRanges << getRootRanges(exposedSelection); - } else { - removedRootRanges = deselected; - newRootRanges = selected; - } - - removeSelectionFromProxy(removedRootRanges); - - if (!m_selectionModel->hasSelection()) - { - Q_ASSERT(m_rootIndexList.isEmpty()); - Q_ASSERT(m_mappedFirstChildren.isEmpty()); - Q_ASSERT(m_mappedParents.isEmpty()); - Q_ASSERT(m_parentIds.isEmpty()); - } - - insertSelectionIntoProxy(newRootRanges); -} - -int KSelectionProxyModelPrivate::getTargetRow(int rootListRow) -{ - Q_Q(KSelectionProxyModel); - if (!m_startWithChildTrees) - return rootListRow; - - --rootListRow; - while (rootListRow >= 0) { - const QModelIndex idx = m_rootIndexList.at(rootListRow); - Q_ASSERT(idx.isValid()); - const int rowCount = q->sourceModel()->rowCount(idx); - if (rowCount > 0) { - static const int column = 0; - const QModelIndex srcIdx = q->sourceModel()->index(rowCount - 1, column, idx); - const QModelIndex proxyLastChild = q->mapFromSource(srcIdx); - return proxyLastChild.row() + 1; - } - --rootListRow; - } - return 0; -} - -void KSelectionProxyModelPrivate::insertSelectionIntoProxy(const QItemSelection &selection) -{ - Q_Q(KSelectionProxyModel); - - if (selection.isEmpty()) - return; - - foreach(const QModelIndex &newIndex, selection.indexes()) { - if (newIndex.column() > 0) - continue; - if (m_startWithChildTrees) { - const int rootListRow = getRootListRow(m_rootIndexList, newIndex); - Q_ASSERT(q->sourceModel() == newIndex.model()); - const int rowCount = q->sourceModel()->rowCount(newIndex); - const int startRow = getTargetRow(rootListRow); - - if (rowCount == 0) { - // Even if the newindex doesn't have any children to put into the model yet, - // We still need to make sure it's future children are inserted into the model. - m_rootIndexList.insert(rootListRow, newIndex); - if (!m_resetting) - emit q->rootIndexAdded(newIndex); - continue; - } - if (!m_resetting) - q->beginInsertRows(QModelIndex(), startRow, startRow + rowCount - 1); - Q_ASSERT(newIndex.isValid()); - m_rootIndexList.insert(rootListRow, newIndex); - emit q->rootIndexAdded(newIndex); - - int _start = 0; - for (int i = 0; i < rootListRow; ++i) - _start += q->sourceModel()->rowCount(m_rootIndexList.at(i)); - - updateInternalTopIndexes(_start, rowCount); - createFirstChildMapping(newIndex, _start); - createParentMappings(newIndex, 0, rowCount - 1); - - if (!m_resetting) { - q->endInsertRows(); - } - - } else { - const int row = getRootListRow(m_rootIndexList, newIndex); - if (!m_resetting) - q->beginInsertRows(QModelIndex(), row, row); - - Q_ASSERT(newIndex.isValid()); - m_rootIndexList.insert(row, newIndex); - emit q->rootIndexAdded(newIndex); - Q_ASSERT(m_rootIndexList.size() > row); - updateInternalIndexes(QModelIndex(), row, 1); - createParentMappings(newIndex.parent(), newIndex.row(), newIndex.row()); - - if (!m_resetting) { - q->endInsertRows(); - } - } - } - q->rootSelectionAdded(selection); -} - -bool KSelectionProxyModelPrivate::isInModel(const QModelIndex &sourceIndex) const -{ - if (m_rootIndexList.contains(sourceIndex)) { - if (m_startWithChildTrees) - return false; - return true; - } - - QModelIndex seekIndex = sourceIndex; - while (seekIndex.isValid()) { - if (m_rootIndexList.contains(seekIndex)) { - return true; - } - - seekIndex = seekIndex.parent(); - } - return false; -} - -KSelectionProxyModel::KSelectionProxyModel(QItemSelectionModel *selectionModel, QObject *parent) - : QAbstractProxyModel(parent), d_ptr(new KSelectionProxyModelPrivate(this, selectionModel)) -{ -} - -KSelectionProxyModel::~KSelectionProxyModel() -{ - delete d_ptr; -} - -void KSelectionProxyModel::setFilterBehavior(FilterBehavior behavior) -{ - Q_D(KSelectionProxyModel); - - beginResetModel(); - - d->m_filterBehavior = behavior; - - switch (behavior) { - case SubTrees: { - d->m_omitChildren = false; - d->m_omitDescendants = false; - d->m_startWithChildTrees = false; - d->m_includeAllSelected = false; - break; - } - case SubTreeRoots: { - d->m_omitChildren = true; - d->m_startWithChildTrees = false; - d->m_includeAllSelected = false; - break; - } - case SubTreesWithoutRoots: { - d->m_omitChildren = false; - d->m_omitDescendants = false; - d->m_startWithChildTrees = true; - d->m_includeAllSelected = false; - break; - } - case ExactSelection: { - d->m_omitChildren = true; - d->m_startWithChildTrees = false; - d->m_includeAllSelected = true; - break; - } - case ChildrenOfExactSelection: { - d->m_omitChildren = false; - d->m_omitDescendants = true; - d->m_startWithChildTrees = true; - d->m_includeAllSelected = true; - break; - } - } - d->resetInternalData(); - d->selectionChanged(d->m_selectionModel->selection(), QItemSelection()); - - endResetModel(); -} - -KSelectionProxyModel::FilterBehavior KSelectionProxyModel::filterBehavior() const -{ - Q_D(const KSelectionProxyModel); - return (KSelectionProxyModel::FilterBehavior)d->m_filterBehavior; -} - -void KSelectionProxyModel::setSourceModel(QAbstractItemModel *_sourceModel) -{ - Q_D(KSelectionProxyModel); - if (_sourceModel == sourceModel()) - return; - - connect(d->m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), - SLOT(selectionChanged(QItemSelection,QItemSelection))); - - beginResetModel(); - d->m_resetting = true; - - if (_sourceModel) { - disconnect(_sourceModel, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(sourceRowsAboutToBeInserted(QModelIndex,int,int))); - disconnect(_sourceModel, SIGNAL(rowsInserted(QModelIndex,int,int)), - this, SLOT(sourceRowsInserted(QModelIndex,int,int))); - disconnect(_sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(sourceRowsAboutToBeRemoved(QModelIndex,int,int))); - disconnect(_sourceModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), - this, SLOT(sourceRowsRemoved(QModelIndex,int,int))); -// disconnect(_sourceModel, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), -// this, SLOT(sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); -// disconnect(_sourceModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), -// this, SLOT(sourceRowsMoved(QModelIndex,int,int,QModelIndex,int))); - disconnect(_sourceModel, SIGNAL(modelAboutToBeReset()), - this, SLOT(sourceModelAboutToBeReset())); - disconnect(_sourceModel, SIGNAL(modelReset()), - this, SLOT(sourceModelReset())); - disconnect(_sourceModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), - this, SLOT(sourceDataChanged(QModelIndex,QModelIndex))); - disconnect(_sourceModel, SIGNAL(layoutAboutToBeChanged()), - this, SLOT(sourceLayoutAboutToBeChanged())); - disconnect(_sourceModel, SIGNAL(layoutChanged()), - this, SLOT(sourceLayoutChanged())); - disconnect(_sourceModel, SIGNAL(destroyed()), - this, SLOT(sourceModelDestroyed())); - } - - // Must be called before QAbstractProxyModel::setSourceModel because it emits some signals. - d->resetInternalData(); - QAbstractProxyModel::setSourceModel(_sourceModel); - if (_sourceModel) { - d->m_indexMapper = new KModelIndexProxyMapper(_sourceModel, d->m_selectionModel->model(), this); - if (d->m_selectionModel->hasSelection()) - d->selectionChanged(d->m_selectionModel->selection(), QItemSelection()); - - connect(_sourceModel, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), - SLOT(sourceRowsAboutToBeInserted(QModelIndex,int,int))); - connect(_sourceModel, SIGNAL(rowsInserted(QModelIndex,int,int)), - SLOT(sourceRowsInserted(QModelIndex,int,int))); - connect(_sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - SLOT(sourceRowsAboutToBeRemoved(QModelIndex,int,int))); - connect(_sourceModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), - SLOT(sourceRowsRemoved(QModelIndex,int,int))); -// connect(_sourceModel, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), -// SLOT(sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); -// connect(_sourceModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), -// SLOT(sourceRowsMoved(QModelIndex,int,int,QModelIndex,int))); - connect(_sourceModel, SIGNAL(modelAboutToBeReset()), - SLOT(sourceModelAboutToBeReset())); - connect(_sourceModel, SIGNAL(modelReset()), - SLOT(sourceModelReset())); - connect(_sourceModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), - SLOT(sourceDataChanged(QModelIndex,QModelIndex))); - connect(_sourceModel, SIGNAL(layoutAboutToBeChanged()), - SLOT(sourceLayoutAboutToBeChanged())); - connect(_sourceModel, SIGNAL(layoutChanged()), - SLOT(sourceLayoutChanged())); - connect(_sourceModel, SIGNAL(destroyed()), - SLOT(sourceModelDestroyed())); - } - - d->m_resetting = false; - endResetModel(); -} - -void KSelectionProxyModelPrivate::updateInternalTopIndexes(int start, int offset) -{ - Q_Q(KSelectionProxyModel); - - updateInternalIndexes(QModelIndex(), start, offset); - - SourceProxyIndexMapping::left_iterator firstChildIt = m_mappedFirstChildren.leftBegin(); - - for ( ; firstChildIt != m_mappedFirstChildren.leftEnd(); ++firstChildIt) { - const QModelIndex proxyIndex = firstChildIt.value(); - Q_ASSERT(proxyIndex.isValid()); - - if (proxyIndex.row() < start) - continue; - - const QModelIndex newProxyIndex = q->createIndex(proxyIndex.row() + offset, proxyIndex.column(), proxyIndex.internalPointer()); - - Q_ASSERT(newProxyIndex.isValid()); - m_mappedFirstChildren.updateRight(firstChildIt, newProxyIndex); - } -} - -void KSelectionProxyModelPrivate::updateInternalIndexes(const QModelIndex &parent, int start, int offset) -{ - Q_Q(KSelectionProxyModel); - - Q_ASSERT(start + offset >= 0); - - if (m_omitChildren || (m_omitDescendants && m_startWithChildTrees)) - return; - - SourceProxyIndexMapping::left_iterator mappedParentIt = m_mappedParents.leftBegin(); - - QHash updatedParentIds; - QHash updatedParents; - - for ( ; mappedParentIt != m_mappedParents.leftEnd(); ++mappedParentIt) { - const QModelIndex proxyIndex = mappedParentIt.value(); - Q_ASSERT(proxyIndex.isValid()); - - if (proxyIndex.row() < start) - continue; - - const QModelIndex proxyParent = proxyIndex.parent(); - - if (parent.isValid()) { - if (proxyParent != parent) - continue; - } else { - if (proxyParent.isValid()) - continue; - } - Q_ASSERT(m_parentIds.rightContains(proxyIndex)); - const qint64 key = m_parentIds.rightToLeft(proxyIndex); - - const QModelIndex newIndex = q->createIndex(proxyIndex.row() + offset, proxyIndex.column(), proxyIndex.internalPointer()); - - Q_ASSERT(newIndex.isValid()); - - updatedParentIds.insert(key, newIndex); - updatedParents.insert(mappedParentIt.key(), newIndex); - } - - { - QHash::const_iterator it = updatedParents.constBegin(); - const QHash::const_iterator end = updatedParents.constEnd(); - for ( ; it != end; ++it) - m_mappedParents.insert(it.key(), it.value()); - } - - { - QHash::const_iterator it = updatedParentIds.constBegin(); - const QHash::const_iterator end = updatedParentIds.constEnd(); - for ( ; it != end; ++it) - m_parentIds.insert(it.key(), it.value()); - } -} - -bool KSelectionProxyModelPrivate::parentAlreadyMapped(const QModelIndex &parent) const -{ - return m_mappedParents.leftContains(parent); -} - -bool KSelectionProxyModelPrivate::firstChildAlreadyMapped(const QModelIndex &firstChild) const -{ - return m_mappedFirstChildren.leftContains(firstChild); -} - -void KSelectionProxyModelPrivate::createFirstChildMapping(const QModelIndex& parent, int proxyRow) const -{ - Q_Q(const KSelectionProxyModel); - - static const int column = 0; - static const int row = 0; - - const QPersistentModelIndex srcIndex = q->sourceModel()->index(row, column, parent); - - if (firstChildAlreadyMapped(srcIndex)) - return; - - Q_ASSERT(srcIndex.isValid()); - m_mappedFirstChildren.insert(srcIndex, q->createIndex(proxyRow, column)); -} - -void KSelectionProxyModelPrivate::createParentMappings(const QModelIndex &parent, int start, int end) const -{ - if (m_omitChildren || (m_omitDescendants && m_startWithChildTrees)) - return; - - Q_Q(const KSelectionProxyModel); - - static const int column = 0; - - for (int row = start; row <= end; ++row) { - const QModelIndex srcIndex = q->sourceModel()->index(row, column, parent); - Q_ASSERT(srcIndex.isValid()); - if (!q->sourceModel()->hasChildren(srcIndex) || parentAlreadyMapped(srcIndex)) - continue; - - const QModelIndex proxyIndex = q->mapFromSource(srcIndex); - if (!proxyIndex.isValid()) - return; // If one of them is not mapped, its siblings won't be either - - const qint64 newId = m_nextId++; - m_parentIds.insert(newId, proxyIndex); - Q_ASSERT(srcIndex.isValid()); - m_mappedParents.insert(QPersistentModelIndex(srcIndex), proxyIndex); - } -} - -void KSelectionProxyModelPrivate::removeFirstChildMappings(int start, int end) -{ - SourceProxyIndexMapping::left_iterator it = m_mappedFirstChildren.leftBegin(); - - while (it != m_mappedFirstChildren.leftEnd()) { - const int row = it.value().row(); - if (row >= start && row <= end /*&& !parentAlreadyMapped(it->first)*/) { - it = m_mappedFirstChildren.eraseLeft(it); - } else - ++it; - } -} - -void KSelectionProxyModelPrivate::removeParentMappings(const QModelIndex &parent, int start, int end) -{ - Q_Q(KSelectionProxyModel); - - Q_ASSERT(parent.isValid() ? parent.model() == q : true); - - SourceProxyIndexMapping::right_iterator it = m_mappedParents.rightBegin(); - SourceProxyIndexMapping::right_iterator endIt = m_mappedParents.rightEnd(); - - typedef QPair Pair; - - QList pairs; - - QModelIndexList list; - - const bool flatList = m_omitChildren || (m_startWithChildTrees && m_omitDescendants); - - while (it != endIt) { - if (it.key().row() >= start && it.key().row() <= end) - { - const QModelIndex sourceParent = it.value(); - const QModelIndex proxyGrandParent = mapParentFromSource(sourceParent.parent()); - if (proxyGrandParent == parent) - { - if (!flatList) - // Due to recursive calls, we could have several iterators on the container - // when erase is called. That's safe accoring to the QHash::iterator docs though. - removeParentMappings(it.key(), 0, q->sourceModel()->rowCount(it.value()) - 1); - - m_parentIds.removeRight(it.key()); - it = m_mappedParents.eraseRight(it); - } else - ++it; - } else - ++it; - } -} - -QModelIndex KSelectionProxyModel::mapToSource(const QModelIndex &proxyIndex) const -{ - Q_D(const KSelectionProxyModel); - - if (!proxyIndex.isValid() || !sourceModel() || d->m_rootIndexList.isEmpty()) - return QModelIndex(); - - Q_ASSERT(proxyIndex.internalId() >= 0); - - if (proxyIndex.internalId() == 0) { - const int column = proxyIndex.column(); - if (!d->m_startWithChildTrees) - { - const QModelIndex idx = d->m_rootIndexList.at(proxyIndex.row()); - return idx.sibling(idx.row(), column); - } - - if (d->m_mappedFirstChildren.isEmpty()) - return QModelIndex(); - - SourceProxyIndexMapping::left_const_iterator it = d->m_mappedFirstChildren.leftConstBegin(); - const SourceProxyIndexMapping::left_const_iterator end = d->m_mappedFirstChildren.leftConstEnd(); - - SourceProxyIndexMapping::left_const_iterator result = end; - for ( ; it != end; ++it) { - if (it.value().row() <= proxyIndex.row()) { - if (result == end || it.value().row() > result.value().row()) - result = it; - } - } - - const QModelIndex proxyFirstChild = result.value(); - const QModelIndex sourceFirstChild = result.key(); - Q_ASSERT(proxyFirstChild.isValid()); - Q_ASSERT(proxyFirstChild.internalPointer() == 0); - Q_ASSERT(sourceFirstChild.isValid()); - return sourceFirstChild.sibling(proxyIndex.row() - proxyFirstChild.row(), column); - } - - const QModelIndex proxyParent = d->m_parentIds.leftToRight(proxyIndex.internalId()); - Q_ASSERT(proxyParent.isValid()); - const QModelIndex sourceParent = d->mapParentToSource(proxyParent); - Q_ASSERT(sourceParent.isValid()); - return sourceModel()->index(proxyIndex.row(), proxyIndex.column(), sourceParent); -} - -QModelIndex KSelectionProxyModel::mapFromSource(const QModelIndex &sourceIndex) const -{ - Q_D(const KSelectionProxyModel); - - if (!sourceModel() || !sourceIndex.isValid() || d->m_rootIndexList.isEmpty()) - return QModelIndex(); - - QModelIndex ancestor = sourceIndex.parent(); - QModelIndexList ancestorList; - while (ancestor.isValid()) - { - if (!d->parentAlreadyMapped(ancestor)) - ancestorList.prepend(ancestor); - else { - break; - } - ancestor = ancestor.parent(); - } - if (!ancestor.isValid()) - ancestorList.clear(); - - // sourceIndex can be mapped to the proxy. We just need to create mappings for its ancestors first. - for(int i = 0; i < ancestorList.size(); ++i) - { - const QModelIndex existingAncestor = d->mapParentFromSource(ancestor); - Q_ASSERT(existingAncestor.isValid()); - qint64 ansId = d->m_parentIds.rightToLeft(existingAncestor); - const QModelIndex newSourceParent = ancestorList.at(i); - const QModelIndex newProxyParent = createIndex(newSourceParent.row(), newSourceParent.column(), reinterpret_cast(ansId)); - - const qint64 newId = d->m_nextId++; - d->m_parentIds.insert(newId, newProxyParent); - d->m_mappedParents.insert(QPersistentModelIndex(newSourceParent), newProxyParent); - ancestor = newSourceParent; - } - - - const QModelIndex maybeMapped = d->mapParentFromSource(sourceIndex); - if (maybeMapped.isValid()) { -// Q_ASSERT((!d->m_startWithChildTrees && d->m_rootIndexList.contains(maybeMapped)) ? maybeMapped.row() < 0 : true ); - return maybeMapped; - } - - const int row = d->m_rootIndexList.indexOf(sourceIndex); - const QModelIndex sourceParent = sourceIndex.parent(); - if (row != -1) { - if (!d->m_startWithChildTrees) { - Q_ASSERT(d->m_rootIndexList.size() > row); - return createIndex(row, sourceIndex.column()); - } - if (!d->m_rootIndexList.contains(sourceParent)) - return QModelIndex(); - - const QModelIndex firstChild = sourceModel()->index(0, 0, sourceParent); - const QModelIndex firstProxyChild = d->mapRootFirstChildFromSource(firstChild); - - return createIndex(firstProxyChild.row() + sourceIndex.row(), sourceIndex.column()); - } - - const QModelIndex proxyParent = d->mapParentFromSource(sourceParent); - if (proxyParent.isValid()) { - const qint64 parentId = d->m_parentIds.rightToLeft(proxyParent); - static const int column = 0; - return createIndex(sourceIndex.row(), column, reinterpret_cast(parentId)); - } - - // Need rules for breaking the index -> parent -> mapToSource -> mapFromSource cylce. - - if (!d->m_startWithChildTrees) - return QModelIndex(); - - const QModelIndex firstChild = sourceModel()->index(0, 0, sourceParent); - const QModelIndex firstProxyChild = d->mapRootFirstChildFromSource(firstChild); - - if (!firstProxyChild.isValid()) - return QModelIndex(); - - return createIndex(firstProxyChild.row() + sourceIndex.row(), sourceIndex.column()); -} - -int KSelectionProxyModel::rowCount(const QModelIndex &index) const -{ - Q_D(const KSelectionProxyModel); - - if (!sourceModel() || index.column() > 0 || d->m_rootIndexList.isEmpty()) - return 0; - - if (!index.isValid()) { - if (!d->m_startWithChildTrees) - return d->m_rootIndexList.size(); - - SourceProxyIndexMapping::left_const_iterator begin = d->m_mappedFirstChildren.leftConstBegin(); - const SourceProxyIndexMapping::left_const_iterator end = d->m_mappedFirstChildren.leftConstEnd(); - if (begin == end) - return 0; - const SourceProxyIndexMapping::left_const_iterator result = kMaxElement(begin, end); - Q_ASSERT(result != end); - const QModelIndex proxyFirstChild = *result; - Q_ASSERT(proxyFirstChild.isValid()); - const QModelIndex sourceFirstChild = result.key(); - Q_ASSERT(sourceFirstChild.isValid()); - const QModelIndex sourceParent = sourceFirstChild.parent(); - Q_ASSERT(sourceParent.isValid()); - return sourceModel()->rowCount(sourceParent) + proxyFirstChild.row(); - } - - // index is valid - if (d->m_omitChildren || (d->m_startWithChildTrees && d->m_omitDescendants)) - return 0; - - QModelIndex sourceParent = d->mapParentToSource(index); - - if (!sourceParent.isValid() && sourceModel()->hasChildren(sourceParent)) { - sourceParent = mapToSource(index.parent()); - d->createParentMappings(sourceParent, 0, sourceModel()->rowCount(sourceParent) - 1); - sourceParent = d->mapParentToSource(index); - } - - if (!sourceParent.isValid()) - return 0; - - return sourceModel()->rowCount(sourceParent); -} - -QModelIndex KSelectionProxyModelPrivate::mapParentToSource(const QModelIndex &proxyParent) const -{ - return m_mappedParents.rightToLeft(proxyParent); -} - -QModelIndex KSelectionProxyModelPrivate::mapParentFromSource(const QModelIndex &sourceParent) const -{ - return m_mappedParents.leftToRight(sourceParent); -} - -QModelIndex KSelectionProxyModelPrivate::mapRootFirstChildToSource(const QModelIndex &proxyChild) const -{ - return m_mappedFirstChildren.rightToLeft(proxyChild); -} - -QModelIndex KSelectionProxyModelPrivate::mapRootFirstChildFromSource(const QModelIndex &sourceChild) const -{ - return m_mappedFirstChildren.leftToRight(sourceChild); -} - -static bool indexIsValid(bool startWithChildTrees, int row, const QList &rootIndexList, const SourceProxyIndexMapping &mappedFirstChildren) -{ - if (!startWithChildTrees) { - Q_ASSERT(rootIndexList.size() > row); - } else { - - Q_ASSERT(!mappedFirstChildren.isEmpty()); - SourceProxyIndexMapping::left_const_iterator it = mappedFirstChildren.leftConstBegin(); - const SourceProxyIndexMapping::left_const_iterator end = mappedFirstChildren.leftConstEnd(); - - SourceProxyIndexMapping::left_const_iterator result = end; - for ( ; it != end; ++it) - { - if (it->row() <= row) - { - if (result == end || result.value().row() < it.value().row()) - result = it; - } - } - Q_ASSERT(result != end); - const QModelIndex proxyFirstChild = result.value(); - const QModelIndex sourceFirstChild = result.key(); - Q_ASSERT(proxyFirstChild.isValid()); - Q_ASSERT(proxyFirstChild.internalPointer() == 0); - Q_ASSERT(sourceFirstChild.isValid()); - Q_ASSERT(sourceFirstChild.parent().isValid()); - Q_ASSERT(row <= proxyFirstChild.row() + sourceFirstChild.model()->rowCount(sourceFirstChild.parent())); - } - return true; -} - -QModelIndex KSelectionProxyModel::index(int row, int column, const QModelIndex &parent) const -{ - Q_D(const KSelectionProxyModel); - - if (!sourceModel() || d->m_rootIndexList.isEmpty() || !hasIndex(row, column, parent)) - return QModelIndex(); - - if (!parent.isValid()) { - Q_ASSERT(indexIsValid(d->m_startWithChildTrees, row, d->m_rootIndexList, d->m_mappedFirstChildren)); - return createIndex(row, column); - } else { - Q_ASSERT(d->m_startWithChildTrees ? true : d->m_parentIds.rightContains(parent)); - - const qint64 parentId = d->m_parentIds.rightToLeft(parent); - return createIndex(row, column, reinterpret_cast(parentId)); - } -} - -QModelIndex KSelectionProxyModel::parent(const QModelIndex &index) const -{ - Q_D(const KSelectionProxyModel); - - if (!sourceModel() || !index.isValid() || d->m_rootIndexList.isEmpty()) - return QModelIndex(); - - const qint64 parentId = index.internalId(); - - return d->m_parentIds.leftToRight(parentId); -} - -Qt::ItemFlags KSelectionProxyModel::flags(const QModelIndex &index) const -{ - if (!index.isValid() || !sourceModel()) - return QAbstractProxyModel::flags(index); - - const QModelIndex srcIndex = mapToSource(index); - Q_ASSERT(srcIndex.isValid()); - return sourceModel()->flags(srcIndex); -} - -QVariant KSelectionProxyModel::data(const QModelIndex & index, int role) const -{ - if (!sourceModel()) - return QVariant(); - - if (index.isValid()) { - const QModelIndex idx = mapToSource(index); - return idx.data(role); - } - return sourceModel()->data(index, role); -} - -QVariant KSelectionProxyModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (!sourceModel()) - return QVariant(); - return sourceModel()->headerData(section, orientation, role); -} - -QMimeData* KSelectionProxyModel::mimeData(const QModelIndexList & indexes) const -{ - if (!sourceModel()) - return QAbstractProxyModel::mimeData(indexes); - QModelIndexList sourceIndexes; - foreach(const QModelIndex& index, indexes) - sourceIndexes << mapToSource(index); - return sourceModel()->mimeData(sourceIndexes); -} - -QStringList KSelectionProxyModel::mimeTypes() const -{ - if (!sourceModel()) - return QAbstractProxyModel::mimeTypes(); - return sourceModel()->mimeTypes(); -} - -Qt::DropActions KSelectionProxyModel::supportedDropActions() const -{ - if (!sourceModel()) - return QAbstractProxyModel::supportedDropActions(); - return sourceModel()->supportedDropActions(); -} - -bool KSelectionProxyModel::hasChildren(const QModelIndex & parent) const -{ - Q_D(const KSelectionProxyModel); - - if (d->m_rootIndexList.isEmpty() || !sourceModel()) - return false; - - if (parent.isValid()) { - if (d->m_omitChildren || (d->m_startWithChildTrees && d->m_omitDescendants)) - return false; - return sourceModel()->hasChildren(mapToSource(parent)); - } - - if (!d->m_startWithChildTrees) - return true; - - return !d->m_mappedFirstChildren.isEmpty(); -} - -int KSelectionProxyModel::columnCount(const QModelIndex &index) const -{ - Q_D(const KSelectionProxyModel); - if (!sourceModel() || index.column() > 0 || d->m_rootIndexList.isEmpty()) - return 0; - return sourceModel()->columnCount(mapToSource(index)); -} - -QItemSelectionModel* KSelectionProxyModel::selectionModel() const -{ - Q_D(const KSelectionProxyModel); - return d->m_selectionModel; -} - -bool KSelectionProxyModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) -{ - Q_D(const KSelectionProxyModel); - if (!sourceModel() || d->m_rootIndexList.isEmpty()) - return false; - - if ((row == -1) && (column == -1)) - return sourceModel()->dropMimeData(data, action, -1, -1, mapToSource(parent)); - - int source_destination_row = -1; - int source_destination_column = -1; - QModelIndex source_parent; - - if (row == rowCount(parent)) { - source_parent = mapToSource(parent); - source_destination_row = sourceModel()->rowCount(source_parent); - } else { - const QModelIndex proxy_index = index(row, column, parent); - const QModelIndex source_index = mapToSource(proxy_index); - source_destination_row = source_index.row(); - source_destination_column = source_index.column(); - source_parent = source_index.parent(); - } - return sourceModel()->dropMimeData(data, action, source_destination_row, - source_destination_column, source_parent); -} - -QList KSelectionProxyModel::sourceRootIndexes() const -{ - Q_D(const KSelectionProxyModel); - return d->m_rootIndexList; -} - -QModelIndexList KSelectionProxyModel::match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const -{ - if (role < Qt::UserRole) - return QAbstractProxyModel::match(start, role, value, hits, flags); - - QModelIndexList list; - QModelIndex proxyIndex; - foreach(const QModelIndex &idx, sourceModel()->match(mapToSource(start), role, value, hits, flags)) { - proxyIndex = mapFromSource(idx); - if (proxyIndex.isValid()) - list << proxyIndex; - - } - return list; -} - -#include "moc_kselectionproxymodel.cpp" diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kselectionproxymodel.h kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kselectionproxymodel.h --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/kselectionproxymodel.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/kselectionproxymodel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,501 +0,0 @@ -/* - Copyright (c) 2009 Stephen Kelly - - 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 KSELECTIONPROXYMODEL_H -#define KSELECTIONPROXYMODEL_H - -#include -#include - - -#include "kmodelindexproxymapper.h" -#include "kbihash_p.h" - -typedef KBiHash SourceProxyIndexMapping; -typedef KBiHash ParentMapping; - -#define KDO(object) kDebug() << #object << object -#define SON(object) object->setObjectName(#object) - -class QItemSelectionModel; - -class KSelectionProxyModel; - -class KSelectionProxyModelPrivate -{ -public: - KSelectionProxyModelPrivate(KSelectionProxyModel *model, QItemSelectionModel *selectionModel); - - Q_DECLARE_PUBLIC(KSelectionProxyModel) - KSelectionProxyModel * const q_ptr; - - // A unique id is generated for each parent. It is used for the internalId of its children in the proxy - // This is used to store a unique id for QModelIndexes in the proxy which have children. - // If an index newly gets children it is added to this hash. If its last child is removed it is removed from this map. - // If this map contains an index, that index hasChildren(). This hash is populated when new rows are inserted in the - // source model, or a new selection is made. - mutable ParentMapping m_parentIds; - // This mapping maps indexes with children in the source to indexes with children in the proxy. - // The order of indexes in this list is not relevant. - mutable SourceProxyIndexMapping m_mappedParents; - - /** - Keeping Persistent indexes from this model in this model breaks in certain situations - such as after source insert, but before calling endInsertRows in this model. In such a state, - the persistent indexes are not updated, but the methods assume they are already uptodate. - - Instead of using persistentindexes for proxy indexes in m_mappedParents, we maintain them ourselves with this method. - - m_mappedParents and m_parentIds are affected. - - @p parent and @p start refer to the proxy model. Any rows >= @p start will be updated. - @p offset is the amount that affected indexes will be changed. - */ - void updateInternalIndexes(const QModelIndex &parent, int start, int offset); - - /** - * Updates stored indexes in the proxy. Any proxy row >= @p start is changed by @p offset. - * - * This is only called to update indexes in the top level of the proxy. Most commonly that is - * - * m_mappedParents, m_parentIds and m_mappedFirstChildren are affected. - */ - void updateInternalTopIndexes(int start, int offset); - - void updateFirstChildMapping(const QModelIndex& parent, int offset); - - /** - Creates mappings in m_parentIds and m_mappedParents between the source and the proxy. - - This is not recursive - */ - void createParentMappings(const QModelIndex &parent, int start, int end) const; - void createFirstChildMapping(const QModelIndex &parent, int proxyRow) const; - bool firstChildAlreadyMapped(const QModelIndex &firstChild) const; - bool parentAlreadyMapped(const QModelIndex &parent) const; - void removeFirstChildMappings(int start, int end); - void removeParentMappings(const QModelIndex &parent, int start, int end); - - /** - Given a QModelIndex in the proxy, return the corresponding QModelIndex in the source. - - This method works only if the index has children in the proxy model which already has a mapping from the source. - - This means that if the proxy is a flat list, this method will always return QModelIndex(). Additionally, it means that m_mappedParents is not populated automatically and must be populated manually. - - No new mapping is created by this method. - */ - QModelIndex mapParentToSource(const QModelIndex &proxyParent) const; - - /** - Given a QModelIndex in the source model, return the corresponding QModelIndex in the proxy. - - This method works only if the index has children in the proxy model which already has a mapping from the source. - - No new mapping is created by this method. - */ - QModelIndex mapParentFromSource(const QModelIndex &sourceParent) const; - QModelIndex mapRootFirstChildToSource(const QModelIndex &proxyParent) const; - QModelIndex mapRootFirstChildFromSource(const QModelIndex &sourceParent) const; - - // Only populated if m_startWithChildTrees. - - mutable SourceProxyIndexMapping m_mappedFirstChildren; - - // Source list is the selection in the source model. - QList m_rootIndexList; - - KModelIndexProxyMapper *m_indexMapper; - - QPair beginRemoveRows(const QModelIndex &parent, int start, int end) const; - QPair beginInsertRows(const QModelIndex &parent, int start, int end) const; - void endRemoveRows(const QModelIndex &sourceParent, int proxyStart, int proxyEnd); - void endInsertRows(const QModelIndex &parent, int start, int end); - - void sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end); - void sourceRowsInserted(const QModelIndex &parent, int start, int end); - void sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); - void sourceRowsRemoved(const QModelIndex &parent, int start, int end); - void sourceRowsAboutToBeMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destParent, int destRow); - void sourceRowsMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destParent, int destRow); - void sourceModelAboutToBeReset(); - void sourceModelReset(); - void sourceLayoutAboutToBeChanged(); - void sourceLayoutChanged(); - void emitContinuousRanges(const QModelIndex &sourceFirst, const QModelIndex &sourceLast, - const QModelIndex &proxyFirst, const QModelIndex &proxyLast); - void sourceDataChanged(const QModelIndex &topLeft , const QModelIndex &bottomRight); - - void refreshParentMappings(QList &mappings); - void refreshFirstChildMappings(QList &mappings); - - void removeSelectionFromProxy(const QItemSelection &selection); - void removeRangeFromProxy(const QItemSelectionRange &range); - - void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); - void sourceModelDestroyed(); - - void resetInternalData(); - - /** - When items are inserted or removed in the m_startWithChildTrees configuration, - this method helps find the startRow for use emitting the signals from the proxy. - */ - int getProxyInitialRow(const QModelIndex &parent) const; - - /** - If m_startWithChildTrees is true, this method returns the row in the proxy model to insert newIndex - items. - - This is a special case because the items above rootListRow in the list are not in the model, but - their children are. Those children must be counted. - - If m_startWithChildTrees is false, this method returns @p rootListRow. - */ - int getTargetRow(int rootListRow); - - /** - Inserts the indexes in @p list into the proxy model. - */ - void insertSelectionIntoProxy(const QItemSelection& selection); - - /** - Returns true if @p sourceIndex or one of its ascendants is already part of the proxy model. - */ - bool isInModel(const QModelIndex &sourceIndex) const; - - bool m_startWithChildTrees; - bool m_omitChildren; - bool m_omitDescendants; - bool m_includeAllSelected; - bool m_rowsInserted; - bool m_rowsRemoved; - QPair m_proxyRemoveRows; - bool m_rowsMoved; - bool m_resetting; - bool m_ignoreNextLayoutAboutToBeChanged; - bool m_ignoreNextLayoutChanged; - QItemSelectionModel * const m_selectionModel; - mutable qint64 m_nextId; - - int m_filterBehavior; - - QList m_layoutChangePersistentIndexes; - QModelIndexList m_proxyIndexes; - - QModelIndexList m_weakSourceParents; - QModelIndexList m_weakSourceFirstChilds; - QModelIndexList m_weakRootIndexes; - QModelIndexList m_weakRootParents; - QList m_sourceFirstChildParents; - QList m_sourceGrandParents; - QList m_sourcePersistentParents; - QList m_sourcePersistentFirstChilds; -}; - - -/** - @brief A Proxy Model which presents a subset of its source model to observers. - - The KSelectionProxyModel is most useful as a convenience for displaying the selection in one view in - another view. The selectionModel of the initial view is used to create a proxied model which is filtered - based on the configuration of this class. - - For example, when a user clicks a mail folder in one view in an email application, the contained emails - should be displayed in another view. - - This takes away the need for the developer to handle the selection between the views, including all the - mapToSource, mapFromSource and setRootIndex calls. - - @code - MyModel *sourceModel = new MyModel(this); - QTreeView *leftView = new QTreeView(this); - leftView->setModel(sourceModel); - - KSelectionProxyModel *selectionProxy = new KSelectionProxyModel(leftView->selectionModel(), this); - selectionProxy->setSourceModel(sourceModel); - - QTreeView *rightView = new QTreeView(this); - rightView->setModel(selectionProxy); - @endcode - - \image html selectionproxymodelsimpleselection.png "A Selection in one view creating a model for use with another view." - - The KSelectionProxyModel can handle complex selections. - - \image html selectionproxymodelmultipleselection.png "Non-contiguous selection creating a new simple model in a second view." - - The contents of the secondary view depends on the selection in the primary view, and the configuration of the proxy model. - See KSelectionProxyModel::setFilterBehavior for the different possible configurations. - - For example, if the filterBehavior is SubTrees, selecting another item in an already selected subtree has no effect. - - \image html selectionproxymodelmultipleselection-withdescendant.png "Selecting an item and its descendant." - - See the test application in KDE/kdelibs/kdeui/tests/proxymodeltestapp to try out the valid configurations. - - \image html kselectionproxymodel-testapp.png "KSelectionProxyModel test application" - - Obviously, the KSelectionProxyModel may be used in a view, or further processed with other proxy models. - See KAddressBook and AkonadiConsole in kdepim for examples which use a further KDescendantsProxyModel - and QSortFilterProxyModel on top of a KSelectionProxyModel. - - Additionally, this class can be used to programmatically choose some items from the source model to display in the view. For example, - this is how the Favourite Folder View in KMail works, and is also used in unit testing. - - See also: http://doc.trolltech.com/4.5/model-view-proxy-models.html - - @since 4.4 - @author Stephen Kelly - -*/ -class KSelectionProxyModel : public QAbstractProxyModel -{ - Q_OBJECT -public: - /** - ctor. - - @p selectionModel The selection model used to filter what is presented by the proxy. - */ - - explicit KSelectionProxyModel(QItemSelectionModel *selectionModel, QObject *parent = 0); - - /** - dtor - */ - virtual ~KSelectionProxyModel(); - - /** - reimp. - */ - virtual void setSourceModel(QAbstractItemModel * sourceModel); - - QItemSelectionModel *selectionModel() const; - - enum FilterBehavior { - SubTrees, - SubTreeRoots, - SubTreesWithoutRoots, - ExactSelection, - ChildrenOfExactSelection - }; - Q_ENUMS(FilterBehavior) - - /** - Set the filter behaviors of this model. - The filter behaviors of the model govern the content of the model based on the selection of the contained QItemSelectionModel. - - See kdeui/proxymodeltestapp to try out the different proxy model behaviors. - - The most useful behaviors are SubTrees, ExactSelection and ChildrenOfExactSelection. - - The default behavior is SubTrees. This means that this proxy model will contain the roots of the items in the source model. - Any descendants which are also selected have no additional effect. - For example if the source model is like: - - @verbatim - (root) - - A - - B - - C - - D - - E - - F - - G - - H - - I - - J - - K - - L - @endverbatim - - And A, B, C and D are selected, the proxy will contain: - - @verbatim - (root) - - A - - B - - C - - D - - E - - F - - G - @endverbatim - - That is, selecting 'D' or 'C' if 'B' is also selected has no effect. If 'B' is de-selected, then 'C' amd 'D' become top-level items: - - @verbatim - (root) - - A - - C - - D - - E - - F - - G - @endverbatim - - This is the behavior used by KJots when rendering books. - - If the behavior is set to SubTreeRoots, then the children of selected indexes are not part of the model. If 'A', 'B' and 'D' are selected, - - @verbatim - (root) - - A - - B - @endverbatim - - Note that although 'D' is selected, it is not part of the proxy model, because its parent 'B' is already selected. - - SubTreesWithoutRoots has the effect of not making the selected items part of the model, but making their children part of the model instead. If 'A', 'B' and 'I' are selected: - - @verbatim - (root) - - C - - D - - E - - F - - G - - J - - K - - L - @endverbatim - - Note that 'A' has no children, so selecting it has no outward effect on the model. - - ChildrenOfExactSelection causes the proxy model to contain the children of the selected indexes,but further descendants are omitted. - Additionally, if descendants of an already selected index are selected, their children are part of the proxy model. - For example, if 'A', 'B', 'D' and 'I' are selected: - - @verbatim - (root) - - C - - D - - E - - G - - J - - K - - L - @endverbatim - - This would be useful for example if showing containers (for example maildirs) in one view and their items in another. Sub-maildirs would still appear in the proxy, but - could be filtered out using a QSortfilterProxyModel. - - The ExactSelection behavior causes the selected items to be part of the proxy model, even if their ancestors are already selected, but children of selected items are not included. - - Again, if 'A', 'B', 'D' and 'I' are selected: - - @verbatim - (root) - - A - - B - - D - - I - @endverbatim - - This is the behavior used by the Favourite Folder View in KMail. - - */ - void setFilterBehavior(FilterBehavior behavior); - FilterBehavior filterBehavior() const; - - QModelIndex mapFromSource(const QModelIndex & sourceIndex) const; - QModelIndex mapToSource(const QModelIndex & proxyIndex) const; - - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; - virtual int rowCount(const QModelIndex & parent = QModelIndex()) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - - virtual QMimeData* mimeData(const QModelIndexList & indexes) const; - virtual QStringList mimeTypes() const; - virtual Qt::DropActions supportedDropActions() const; - virtual bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent); - - virtual bool hasChildren(const QModelIndex & parent = QModelIndex()) const; - virtual QModelIndex index(int, int, const QModelIndex& = QModelIndex()) const; - virtual QModelIndex parent(const QModelIndex&) const; - virtual int columnCount(const QModelIndex& = QModelIndex()) const; - - virtual QModelIndexList match(const QModelIndex& start, int role, const QVariant& value, int hits = 1, - Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith | Qt::MatchWrap)) const; - -Q_SIGNALS: -#if !defined(Q_MOC_RUN) -private: // Don't allow subclasses to emit these signals. -#endif - - /** - @internal - Emitted before @p removeRootIndex, an index in the sourceModel is removed from - the root selected indexes. This may be unrelated to rows removed from the model, - depending on configuration. - */ - void rootIndexAboutToBeRemoved(const QModelIndex &removeRootIndex); - - /** - @internal - Emitted when @p newIndex, an index in the sourceModel is added to the root selected - indexes. This may be unrelated to rows inserted to the model, - depending on configuration. - */ - void rootIndexAdded(const QModelIndex &newIndex); - - /** - @internal - Emitted before @p selection, a selection in the sourceModel, is removed from - the root selection. - */ - void rootSelectionAboutToBeRemoved(const QItemSelection &selection); - - /** - @internal - Emitted after @p selection, a selection in the sourceModel, is added to - the root selection. - */ - void rootSelectionAdded(const QItemSelection &selection); - -protected: - QList sourceRootIndexes() const; - -private: - Q_DECLARE_PRIVATE(KSelectionProxyModel) - //@cond PRIVATE - KSelectionProxyModelPrivate *d_ptr; - - Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeInserted(const QModelIndex &, int, int)) - Q_PRIVATE_SLOT(d_func(), void sourceRowsInserted(const QModelIndex &, int, int)) - Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeRemoved(const QModelIndex &, int, int)) - Q_PRIVATE_SLOT(d_func(), void sourceRowsRemoved(const QModelIndex &, int, int)) - Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)) - Q_PRIVATE_SLOT(d_func(), void sourceRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)) - Q_PRIVATE_SLOT(d_func(), void sourceModelAboutToBeReset()) - Q_PRIVATE_SLOT(d_func(), void sourceModelReset()) - Q_PRIVATE_SLOT(d_func(), void sourceLayoutAboutToBeChanged()) - Q_PRIVATE_SLOT(d_func(), void sourceLayoutChanged()) - Q_PRIVATE_SLOT(d_func(), void sourceDataChanged(const QModelIndex &, const QModelIndex &)) - Q_PRIVATE_SLOT(d_func(), void selectionChanged(const QItemSelection & selected, const QItemSelection & deselected)) - Q_PRIVATE_SLOT(d_func(), void sourceModelDestroyed()) - - - //@endcond - -}; - -#endif diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/ListDelegate.qml kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/ListDelegate.qml --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/ListDelegate.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/ListDelegate.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2010 Klarälvdalens Datakonsult AB, - * a KDAB Group company, info@kdab.net, - * author Stephen Kelly - * - * 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. - */ - -import Qt 4.7 - -Rectangle { - property alias text : _text.text; - property bool clickable : false - property bool isChild : false - property bool isSelected : false - property bool topItem : false - - property variant checkModel - - signal indexSelected(int row) - - color : "#00000000" - height: itemHeight; - width : ListView.view.width - - Item { - // This is the same as anchors.fill : parent, but ParentAnimation only works - // if positional layouting is used instead of anchor layouting. - x : 0 - y : 0 - width : parent.width - height : parent.height - id : nestedItem - - Text { - id : _text - anchors.verticalCenter : parent.verticalCenter; - anchors.horizontalCenter : parent.horizontalCenter; - text : model.display - } - - Image { - width : height - anchors.right : parent.right - anchors.rightMargin : 5 - anchors.verticalCenter : parent.verticalCenter - opacity : ( isChild && application.childCollectionHasChildren( model.index ) ) ? 1 : 0 - source: "transparentplus.png" - } - - MouseArea { - anchors.fill : parent - onClicked: { - if ( clickable ) - { - if (topItem) - { - indexSelected(model.index); - return; - } - - if (isChild) - { - nestedItem.state = "before_select_child"; - } else if (!isSelected) - nestedItem.state = "before_select_breadcrumb"; - indexSelected(model.index); - } - } - Rectangle { - width : height - height : 10 - anchors.left : parent.left - anchors.leftMargin : 5 - anchors.verticalCenter : parent.verticalCenter - color: model.checkOn ? "blue" : "white" - MouseArea { - anchors.fill : parent - onClicked : { - // 8 is QItemSelectionModel::Toggle - checkModel.select(model.index, 8); - } - } - } - } - - states : [ - State { - name : "before_select_child" - ParentChange { target : nestedItem; parent : selectedItemPlaceHolder; } - PropertyChanges { target : nestedItem; x : 0; y : 0 } - }, - State { - name : "before_select_breadcrumb" - ParentChange { target : nestedItem; parent : selectedItemPlaceHolder; } - PropertyChanges { target : nestedItem; x : 0; y : 0 } - } - ] - transitions : [ - Transition { - ParentAnimation { - target : nestedItem - NumberAnimation { - properties: "x,y"; - duration : 500 - easing.type: Easing.OutQuad; - } - } - } - ] - } -} \ No newline at end of file Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/list-line-top.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/list-line-top.png differ diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/main.cpp kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/main.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/main.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ - -#include - -#include "mainwindow.h" - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - - MainWindow mw; - mw.resize(640, 480); - mw.show(); - - return app.exec(); - -} - - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/mainview.qml kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/mainview.qml --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/mainview.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/mainview.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,98 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Rectangle { - color : "#f6f6f5" - anchors.fill : parent - - Image { - id : backgroundImage - width : parent.width - fillMode : Image.TileHorizontally - source : "backgroundtile.png" - } - - BreadcrumbNavigationView { - id : breadcrumbNavView - SystemPalette { id: palette; colorGroup: "Active" } - - breadcrumbComponentFactory : _breadcrumbNavigationFactory - - anchors.top : parent.top; - anchors.bottom : parent.bottom; - anchors.left : parent.left; - width : 200 - -// anchors.rightMargin : 20 - - topDelegate : ListDelegate - { - clickable : true - topItem : true - onIndexSelected : { - breadcrumbTopLevel._transitionSelect = -1; - breadcrumbTopLevel.state = "before_select_home"; - } - } - - breadcrumbDelegate : ListDelegate - { - clickable : true - checkModel : breadcrumbComponentFactory.qmlBreadcrumbCheckModel() - onIndexSelected : { - breadcrumbTopLevel._transitionSelect = row; - breadcrumbTopLevel.state = "before_select_breadcrumb"; - } - } - - selectedItemDelegate : ListDelegate - { - isSelected : true - checkModel : breadcrumbComponentFactory.qmlSelectedItemCheckModel() - } - - childItemsDelegate : ListDelegate - { - clickable : true - isChild : true - checkModel : breadcrumbComponentFactory.qmlChildCheckModel() - onIndexSelected : { - breadcrumbTopLevel._transitionSelect = row; - breadcrumbTopLevel.state = "before_select_child"; - } - } - } - - ListView { - anchors.top : breadcrumbNavView.top; - anchors.bottom : breadcrumbNavView.bottom; - anchors.left : breadcrumbNavView.right; - width : 100 - model : _breadcrumbNavigationFactory.qmlCheckedItemsModel(); - delegate: ListDelegate - { - height : 67 - checkModel : _breadcrumbNavigationFactory.qmlCheckedItemsCheckModel(); - } - } -} diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,170 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 "mainwindow.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "dynamictreemodel.h" -#include "dynamictreewidget.h" - -#include "breadcrumbnavigationcontext.h" -#include -#include -#include "kresettingproxymodel.h" -#include "qmllistselectionmodel.h" -#include "kselectionproxymodel.h" -#include "checkableitemproxymodel.h" - -MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags f ) - : QWidget(parent, f) -{ - QHBoxLayout *layout = new QHBoxLayout(this); - QSplitter *splitter = new QSplitter; - layout->addWidget(splitter); - - m_treeModel = new DynamicTreeModel(this); - - DynamicTreeWidget *widget = new DynamicTreeWidget(m_treeModel, splitter); - - QString initialTree; - if (qApp->arguments().size() == 2) - { - QString filename = qApp->arguments().at(1); - QFile f(filename); - if (f.open(QFile::ReadOnly)) - { - initialTree = f.readAll(); - } - f.close(); - } - if (initialTree.isEmpty()){ - initialTree = - "- 1" - "- - 1" - "- - 1" - "- - - 1" - "- - - - 1" - "- - - 1" - "- - - 1" - "- - - - 1" - "- - - - 1" - "- - - - - 1" - "- - - - - - 1" - "- - - - - 1" - "- - - - - -1" - "- - - - - - 1" - "- - - - - - - 1" - "- - - - - - - 1" - "- - - - - - 1" - "- - - - - 1" - "- - - - - 1" - "- - - - 1" - "- - - - 1" - "- - - 1" - "- - - 1" - "- - - 1" - "- - - 1" - "- - - 1" - "- - - 1" - "- - - 1" - "- - - 1" - "- - - 1" - "- - - 1" - "- - - 1" - "- - - 1" - "- - - - 1" - "- - - - 1" - "- - - - - 1" - "- - - - - - 1" - "- - - - - 1" - "- - - - - -1" - "- - - - - - 1" - "- - - - - - - 1" - "- - - - - - - 1" - "- - - - - - 1" - "- - - - - 1" - "- - - - - 1" - "- - - - 1" - "- - - - 1" - "- - - 1" - "- - - 1" - "- - - 1" - "- 1" - "- - 1" - "- - 1" - "- - 1" - "- - - 1" - "- - - 1" - "- - 1" - "- 1" - "- - 1" - "- - - 1" - "- - - 1" - "- - 1" - "- - 1" - "- - 1" - "- 1"; - } - - widget->setInitialTree(initialTree); - m_declarativeView = new QDeclarativeView(splitter); - - QDeclarativeContext *context = m_declarativeView->engine()->rootContext(); - - m_bnf = new KBreadcrumbNavigationFactory(this); - m_bnf->setBreadcrumbDepth(1); - m_bnf->createCheckableBreadcrumbContext( m_treeModel, this ); - - context->setContextProperty( "_breadcrumbNavigationFactory", m_bnf ); - -// widget->treeView()->setSelectionModel( m_bnf->selectionModel() ); - - context->setContextProperty( "application", QVariant::fromValue( static_cast( this ) ) ); - - m_declarativeView->setResizeMode( QDeclarativeView::SizeRootObjectToView ); - m_declarativeView->setSource( QUrl( "./mainview.qml" ) ); - - splitter->setSizes(QList() << 1 << 1); - -} - -bool MainWindow::childCollectionHasChildren( int row ) -{ - return m_bnf->childCollectionHasChildren(row); -} - -int MainWindow::selectedCollectionRow() -{ - const QModelIndexList list = m_bnf->selectionModel()->selectedRows(); - if (list.size() != 1) - return -1; - return list.first().row(); -} - - - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.h kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.h --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/mainwindow.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ - -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include -#include - -class QDeclarativeView; -class QTreeView; - -#include "dynamictreemodel.h" - -Q_DECLARE_METATYPE(QModelIndex) - -class KBreadcrumbNavigationFactory; - -class MainWindow : public QWidget -{ - Q_OBJECT -public: - MainWindow(QWidget* parent = 0, Qt::WindowFlags f = 0); - -public slots: - /** Returns whether or not the child collection at row @param row has children. */ - bool childCollectionHasChildren( int row ); - int selectedCollectionRow(); - -private: - QTreeView *m_treeView; - DynamicTreeModel *m_treeModel; - QDeclarativeView *m_declarativeView; - KBreadcrumbNavigationFactory *m_bnf; -}; - -#endif - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/qmllistselectionmodel.cpp kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/qmllistselectionmodel.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/qmllistselectionmodel.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/qmllistselectionmodel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 "qmllistselectionmodel.h" - -#include - -QMLListSelectionModel::QMLListSelectionModel(QItemSelectionModel *selectionModel, QObject* parent) - : QObject(parent), m_selectionModel(selectionModel) -{ - -} - -QMLListSelectionModel::QMLListSelectionModel(QAbstractItemModel* model, QObject* parent) - : QObject(parent), m_selectionModel(new QItemSelectionModel(model, this)) -{ - -} - -QItemSelectionModel* QMLListSelectionModel::selectionModel() const -{ - return m_selectionModel; -} - -QList< int > QMLListSelectionModel::selection() const -{ - QList< int > list; - const QModelIndexList indexes = m_selectionModel->selectedRows(); - foreach (const QModelIndex &index, indexes) - list << index.row(); - return list; -} - -void QMLListSelectionModel::select(int row, int command) -{ - qDebug() << row << command; - Q_ASSERT(row >= 0); - static const int column = 0; - const QModelIndex idx = m_selectionModel->model()->index(row, column); - Q_ASSERT(idx.isValid()); - qDebug() << idx << idx.data(); - QItemSelection sel(idx, idx); - QItemSelectionModel::SelectionFlags flags = static_cast(command); - m_selectionModel->select(sel, flags); - emit selectionChanged(); -} - -void QMLListSelectionModel::clearSelection() -{ - m_selectionModel->clearSelection(); - emit selectionChanged(); -} - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/qmllistselectionmodel.h kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/qmllistselectionmodel.h --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/qmllistselectionmodel.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/qmllistselectionmodel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 QMLLISTSELECTIONMODEL_H -#define QMLLISTSELECTIONMODEL_H - -#include - -class QMLListSelectionModel : public QObject -{ - Q_OBJECT - Q_PROPERTY(QList selection READ selection NOTIFY selectionChanged) -public: - enum SelectionFlag { - NoUpdate = 0x0000, - Clear = 0x0001, - Select = 0x0002, - Deselect = 0x0004, - Toggle = 0x0008, - Current = 0x0010, - Rows = 0x0020, - Columns = 0x0040, - SelectCurrent = Select | Current, - ToggleCurrent = Toggle | Current, - ClearAndSelect = Clear | Select - }; - //Q_DECLARE_FLAGS(SelectionFlags, SelectionFlag) - - explicit QMLListSelectionModel(QItemSelectionModel *selectionModel, QObject* parent = 0); - explicit QMLListSelectionModel(QAbstractItemModel *model, QObject* parent = 0); - - QItemSelectionModel* selectionModel() const; - - QList selection() const; - - -public slots: - void clearSelection(); - void select(int row, int command); - -signals: - void selectionChanged(); - -private: - QItemSelectionModel * const m_selectionModel; -}; - -#endif \ No newline at end of file Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/scrollable-bottom.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/scrollable-bottom.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/scrollable-top.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/scrollable-top.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/selected_bottom.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/selected_bottom.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/selected_top.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/selected_top.png differ diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/001-assert.patch kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/001-assert.patch --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/001-assert.patch 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/001-assert.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -diff --git a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainwindow.cpp b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainwindow.cpp -index 168c2ca..33a4e6b 100644 ---- a/runtime/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainwindow.cpp -+++ b/runtime/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainwindow.cpp -@@ -44,8 +44,8 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags f ) - m_model = new QStandardItemModel(this); - treeView->setModel(m_model); - -- appendRow(); -- appendRow(); -+// appendRow(); -+// appendRow(); - - m_declarativeView = new QDeclarativeView(splitter); - -@@ -58,8 +58,12 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags f ) - - splitter->setSizes(QList() << 1 << 1); - -+ QTimer::singleShot(0, this, SLOT(appendRow())); -+ QTimer::singleShot(1, this, SLOT(appendRow())); -+ QTimer::singleShot(2, this, SLOT(removeTopRow())); -+ - // QTimer::singleShot(4000, this, SLOT(removeBottomRow())); -- QTimer::singleShot(8000, this, SLOT(prependNewRow())); -+// QTimer::singleShot(8000, this, SLOT(prependNewRow())); - - } - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/FindQt4.cmake kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/FindQt4.cmake --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/FindQt4.cmake 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/FindQt4.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,1256 +0,0 @@ -# - Find QT 4 -# This module can be used to find Qt4. -# The most important issue is that the Qt4 qmake is available via the system path. -# This qmake is then used to detect basically everything else. -# This module defines a number of key variables and macros. -# The variable QT_USE_FILE is set which is the path to a CMake file that can be included -# to compile Qt 4 applications and libraries. It sets up the compilation -# environment for include directories, preprocessor defines and populates a -# QT_LIBRARIES variable. -# -# Typical usage could be something like: -# find_package(Qt4 4.4.3 COMPONENTS QtCore QtGui QtXml REQUIRED ) -# include(${QT_USE_FILE}) -# add_executable(myexe main.cpp) -# target_link_libraries(myexe ${QT_LIBRARIES}) -# -# The minimum required version can be specified using the standard find_package()-syntax -# (see example above). -# For compatibility with older versions of FindQt4.cmake it is also possible to -# set the variable QT_MIN_VERSION to the minimum required version of Qt4 before the -# find_package(Qt4) command. -# If both are used, the version used in the find_package() command overrides the -# one from QT_MIN_VERSION. -# -# When using the components argument, QT_USE_QT* variables are automatically set -# for the QT_USE_FILE to pick up. If one wishes to manually set them, the -# available ones to set include: -# QT_DONT_USE_QTCORE -# QT_DONT_USE_QTGUI -# QT_USE_QT3SUPPORT -# QT_USE_QTASSISTANT -# QT_USE_QAXCONTAINER -# QT_USE_QAXSERVER -# QT_USE_QTDESIGNER -# QT_USE_QTMOTIF -# QT_USE_QTMAIN -# QT_USE_QTMULTIMEDIA -# QT_USE_QTNETWORK -# QT_USE_QTNSPLUGIN -# QT_USE_QTOPENGL -# QT_USE_QTSQL -# QT_USE_QTXML -# QT_USE_QTSVG -# QT_USE_QTTEST -# QT_USE_QTUITOOLS -# QT_USE_QTDBUS -# QT_USE_QTSCRIPT -# QT_USE_QTASSISTANTCLIENT -# QT_USE_QTHELP -# QT_USE_QTWEBKIT -# QT_USE_QTXMLPATTERNS -# QT_USE_PHONON -# QT_USE_QTSCRIPTTOOLS -# QT_USE_QTDECLARATIVE -# -# QT_USE_IMPORTED_TARGETS -# If this variable is set to TRUE, FindQt4.cmake will create imported -# library targets for the various Qt libraries and set the -# library variables like QT_QTCORE_LIBRARY to point at these imported -# targets instead of the library file on disk. This provides much better -# handling of the release and debug versions of the Qt libraries and is -# also always backwards compatible, except for the case that dependencies -# of libraries are exported, these will then also list the names of the -# imported targets as dependency and not the file location on disk. This -# is much more flexible, but requires that FindQt4.cmake is executed before -# such an exported dependency file is processed. -# -# There are also some files that need processing by some Qt tools such as moc -# and uic. Listed below are macros that may be used to process those files. -# -# macro QT4_WRAP_CPP(outfiles inputfile ... OPTIONS ...) -# create moc code from a list of files containing Qt class with -# the Q_OBJECT declaration. Per-direcotry preprocessor definitions -# are also added. Options may be given to moc, such as those found -# when executing "moc -help". -# -# macro QT4_WRAP_UI(outfiles inputfile ... OPTIONS ...) -# create code from a list of Qt designer ui files. -# Options may be given to uic, such as those found -# when executing "uic -help" -# -# macro QT4_ADD_RESOURCES(outfiles inputfile ... OPTIONS ...) -# create code from a list of Qt resource files. -# Options may be given to rcc, such as those found -# when executing "rcc -help" -# -# macro QT4_GENERATE_MOC(inputfile outputfile ) -# creates a rule to run moc on infile and create outfile. -# Use this if for some reason QT4_WRAP_CPP() isn't appropriate, e.g. -# because you need a custom filename for the moc file or something similar. -# -# macro QT4_AUTOMOC(sourcefile1 sourcefile2 ... ) -# This macro is still experimental. -# It can be used to have moc automatically handled. -# So if you have the files foo.h and foo.cpp, and in foo.h a -# a class uses the Q_OBJECT macro, moc has to run on it. If you don't -# want to use QT4_WRAP_CPP() (which is reliable and mature), you can insert -# #include "foo.moc" -# in foo.cpp and then give foo.cpp as argument to QT4_AUTOMOC(). This will the -# scan all listed files at cmake-time for such included moc files and if it finds -# them cause a rule to be generated to run moc at build time on the -# accompanying header file foo.h. -# If a source file has the SKIP_AUTOMOC property set it will be ignored by this macro. -# -# macro QT4_ADD_DBUS_INTERFACE(outfiles interface basename) -# create a the interface header and implementation files with the -# given basename from the given interface xml file and add it to -# the list of sources. -# To disable generating a namespace header, set the source file property -# NO_NAMESPACE to TRUE on the interface file. -# To include a header in the interface header, set the source file property -# INCLUDE to the name of the header. -# To specify a class name to use, set the source file property CLASSNAME -# to the name of the class. -# -# macro QT4_ADD_DBUS_INTERFACES(outfiles inputfile ... ) -# create the interface header and implementation files -# for all listed interface xml files -# the name will be automatically determined from the name of the xml file -# To disable generating namespace headers, set the source file property -# NO_NAMESPACE to TRUE for these inputfiles. -# To include a header in the interface header, set the source file property -# INCLUDE to the name of the header. -# To specify a class name to use, set the source file property CLASSNAME -# to the name of the class. -# -# macro QT4_ADD_DBUS_ADAPTOR(outfiles xmlfile parentheader parentclassname [basename] [classname]) -# create a dbus adaptor (header and implementation file) from the xml file -# describing the interface, and add it to the list of sources. The adaptor -# forwards the calls to a parent class, defined in parentheader and named -# parentclassname. The name of the generated files will be -# adaptor.{cpp,h} where basename defaults to the basename of the xml file. -# If is provided, then it will be used as the classname of the -# adaptor itself. -# -# macro QT4_GENERATE_DBUS_INTERFACE( header [interfacename] OPTIONS ...) -# generate the xml interface file from the given header. -# If the optional argument interfacename is omitted, the name of the -# interface file is constructed from the basename of the header with -# the suffix .xml appended. -# Options may be given to qdbuscpp2xml, such as those found when executing "qdbuscpp2xml --help" -# -# macro QT4_CREATE_TRANSLATION( qm_files directories ... sources ... -# ts_files ... OPTIONS ...) -# out: qm_files -# in: directories sources ts_files -# options: flags to pass to lupdate, such as -extensions to specify -# extensions for a directory scan. -# generates commands to create .ts (vie lupdate) and .qm -# (via lrelease) - files from directories and/or sources. The ts files are -# created and/or updated in the source tree (unless given with full paths). -# The qm files are generated in the build tree. -# Updating the translations can be done by adding the qm_files -# to the source list of your library/executable, so they are -# always updated, or by adding a custom target to control when -# they get updated/generated. -# -# macro QT4_ADD_TRANSLATION( qm_files ts_files ... ) -# out: qm_files -# in: ts_files -# generates commands to create .qm from .ts - files. The generated -# filenames can be found in qm_files. The ts_files -# must exists and are not updated in any way. -# -# -# Below is a detailed list of variables that FindQt4.cmake sets. -# QT_FOUND If false, don't try to use Qt. -# QT4_FOUND If false, don't try to use Qt 4. -# -# QT_VERSION_MAJOR The major version of Qt found. -# QT_VERSION_MINOR The minor version of Qt found. -# QT_VERSION_PATCH The patch version of Qt found. -# -# QT_EDITION Set to the edition of Qt (i.e. DesktopLight) -# QT_EDITION_DESKTOPLIGHT True if QT_EDITION == DesktopLight -# QT_QTCORE_FOUND True if QtCore was found. -# QT_QTGUI_FOUND True if QtGui was found. -# QT_QT3SUPPORT_FOUND True if Qt3Support was found. -# QT_QTASSISTANT_FOUND True if QtAssistant was found. -# QT_QTASSISTANTCLIENT_FOUND True if QtAssistantClient was found. -# QT_QAXCONTAINER_FOUND True if QAxContainer was found (Windows only). -# QT_QAXSERVER_FOUND True if QAxServer was found (Windows only). -# QT_QTDBUS_FOUND True if QtDBus was found. -# QT_QTDESIGNER_FOUND True if QtDesigner was found. -# QT_QTDESIGNERCOMPONENTS True if QtDesignerComponents was found. -# QT_QTHELP_FOUND True if QtHelp was found. -# QT_QTMOTIF_FOUND True if QtMotif was found. -# QT_QTMULTIMEDIA_FOUND True if QtMultimedia was found (since Qt 4.6.0). -# QT_QTNETWORK_FOUND True if QtNetwork was found. -# QT_QTNSPLUGIN_FOUND True if QtNsPlugin was found. -# QT_QTOPENGL_FOUND True if QtOpenGL was found. -# QT_QTSQL_FOUND True if QtSql was found. -# QT_QTSVG_FOUND True if QtSvg was found. -# QT_QTSCRIPT_FOUND True if QtScript was found. -# QT_QTSCRIPTTOOLS_FOUND True if QtScriptTools was found. -# QT_QTTEST_FOUND True if QtTest was found. -# QT_QTUITOOLS_FOUND True if QtUiTools was found. -# QT_QTWEBKIT_FOUND True if QtWebKit was found. -# QT_QTXML_FOUND True if QtXml was found. -# QT_QTXMLPATTERNS_FOUND True if QtXmlPatterns was found. -# QT_PHONON_FOUND True if phonon was found. -# QT_QTDECLARATIVE_FOUND True if QtDeclarative was found. -# -# QT_MAC_USE_COCOA For Mac OS X, its whether Cocoa or Carbon is used. -# In general, this should not be used, but its useful -# when having platform specific code. -# -# QT_DEFINITIONS Definitions to use when compiling code that uses Qt. -# You do not need to use this if you include QT_USE_FILE. -# The QT_USE_FILE will also define QT_DEBUG and QT_NO_DEBUG -# to fit your current build type. Those are not contained -# in QT_DEFINITIONS. -# -# QT_INCLUDES List of paths to all include directories of -# Qt4 QT_INCLUDE_DIR and QT_QTCORE_INCLUDE_DIR are -# always in this variable even if NOTFOUND, -# all other INCLUDE_DIRS are -# only added if they are found. -# You do not need to use this if you include QT_USE_FILE. -# -# -# Include directories for the Qt modules are listed here. -# You do not need to use these variables if you include QT_USE_FILE. -# -# QT_INCLUDE_DIR Path to "include" of Qt4 -# QT_QT_INCLUDE_DIR Path to "include/Qt" -# QT_QT3SUPPORT_INCLUDE_DIR Path to "include/Qt3Support" -# QT_QTASSISTANT_INCLUDE_DIR Path to "include/QtAssistant" -# QT_QTASSISTANTCLIENT_INCLUDE_DIR Path to "include/QtAssistant" -# QT_QAXCONTAINER_INCLUDE_DIR Path to "include/ActiveQt" (Windows only) -# QT_QAXSERVER_INCLUDE_DIR Path to "include/ActiveQt" (Windows only) -# QT_QTCORE_INCLUDE_DIR Path to "include/QtCore" -# QT_QTDBUS_INCLUDE_DIR Path to "include/QtDBus" -# QT_QTDESIGNER_INCLUDE_DIR Path to "include/QtDesigner" -# QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR Path to "include/QtDesigner" -# QT_QTGUI_INCLUDE_DIR Path to "include/QtGui" -# QT_QTHELP_INCLUDE_DIR Path to "include/QtHelp" -# QT_QTMOTIF_INCLUDE_DIR Path to "include/QtMotif" -# QT_QTMULTIMEDIA_INCLUDE_DIR Path to "include/QtMultimedia" -# QT_QTNETWORK_INCLUDE_DIR Path to "include/QtNetwork" -# QT_QTNSPLUGIN_INCLUDE_DIR Path to "include/QtNsPlugin" -# QT_QTOPENGL_INCLUDE_DIR Path to "include/QtOpenGL" -# QT_QTSCRIPT_INCLUDE_DIR Path to "include/QtScript" -# QT_QTSQL_INCLUDE_DIR Path to "include/QtSql" -# QT_QTSVG_INCLUDE_DIR Path to "include/QtSvg" -# QT_QTTEST_INCLUDE_DIR Path to "include/QtTest" -# QT_QTWEBKIT_INCLUDE_DIR Path to "include/QtWebKit" -# QT_QTXML_INCLUDE_DIR Path to "include/QtXml" -# QT_QTXMLPATTERNS_INCLUDE_DIR Path to "include/QtXmlPatterns" -# QT_PHONON_INCLUDE_DIR Path to "include/phonon" -# QT_QTSCRIPTTOOLS_INCLUDE_DIR Path to "include/QtScriptTools" -# QT_QTDECLARATIVE_INCLUDE_DIR Path to "include/QtDeclarative" -# -# QT_BINARY_DIR Path to "bin" of Qt4 -# QT_LIBRARY_DIR Path to "lib" of Qt4 -# QT_PLUGINS_DIR Path to "plugins" for Qt4 -# QT_TRANSLATIONS_DIR Path to "translations" of Qt4 -# QT_DOC_DIR Path to "doc" of Qt4 -# QT_MKSPECS_DIR Path to "mkspecs" of Qt4 -# -# -# For every library of Qt, a QT_QTFOO_LIBRARY variable is defined, with the full path to the library. -# -# So there are the following variables: -# The Qt3Support library: QT_QT3SUPPORT_LIBRARY -# -# The QtAssistant library: QT_QTASSISTANT_LIBRARY -# -# The QtAssistantClient library: QT_QTASSISTANTCLIENT_LIBRARY -# -# The QAxServer library: QT_QAXSERVER_LIBRARY -# -# The QAxContainer library: QT_QAXCONTAINER_LIBRARY -# -# The QtCore library: QT_QTCORE_LIBRARY -# -# The QtDBus library: QT_QTDBUS_LIBRARY -# -# The QtDesigner library: QT_QTDESIGNER_LIBRARY -# -# The QtDesignerComponents library: QT_QTDESIGNERCOMPONENTS_LIBRARY -# -# The QtGui library: QT_QTGUI_LIBRARY -# -# The QtHelp library: QT_QTHELP_LIBRARY -# -# The QtMotif library: QT_QTMOTIF_LIBRARY -# -# The QtMultimedia library: QT_QTMULTIMEDIA_LIBRARY -# -# The QtNetwork library: QT_QTNETWORK_LIBRARY -# -# The QtNsPLugin library: QT_QTNSPLUGIN_LIBRARY -# -# The QtOpenGL library: QT_QTOPENGL_LIBRARY -# -# The QtScript library: QT_QTSCRIPT_LIBRARY -# -# The QtScriptTools library: QT_QTSCRIPTTOOLS_LIBRARY -# -# The QtSql library: QT_QTSQL_LIBRARY -# -# The QtSvg library: QT_QTSVG_LIBRARY -# -# The QtTest library: QT_QTTEST_LIBRARY -# -# The QtUiTools library: QT_QTUITOOLS_LIBRARY -# -# The QtWebKit library: QT_QTWEBKIT_LIBRARY -# -# The QtXml library: QT_QTXML_LIBRARY -# -# The QtXmlPatterns library: QT_QTXMLPATTERNS_LIBRARY -# -# The qtmain library for Windows QT_QTMAIN_LIBRARY -# -# The Phonon library: QT_PHONON_LIBRARY -# -# The QtDeclarative library: QT_QTDECLARATIVE_LIBRARY -# -# also defined, but NOT for general use are -# QT_MOC_EXECUTABLE Where to find the moc tool. -# QT_UIC_EXECUTABLE Where to find the uic tool. -# QT_UIC3_EXECUTABLE Where to find the uic3 tool. -# QT_RCC_EXECUTABLE Where to find the rcc tool -# QT_DBUSCPP2XML_EXECUTABLE Where to find the qdbuscpp2xml tool. -# QT_DBUSXML2CPP_EXECUTABLE Where to find the qdbusxml2cpp tool. -# QT_LUPDATE_EXECUTABLE Where to find the lupdate tool. -# QT_LRELEASE_EXECUTABLE Where to find the lrelease tool. -# QT_QCOLLECTIONGENERATOR_EXECUTABLE Where to find the qcollectiongenerator tool. -# QT_DESIGNER_EXECUTABLE Where to find the Qt designer tool. -# QT_LINGUIST_EXECUTABLE Where to find the Qt linguist tool. -# -# -# These are around for backwards compatibility -# they will be set -# QT_WRAP_CPP Set true if QT_MOC_EXECUTABLE is found -# QT_WRAP_UI Set true if QT_UIC_EXECUTABLE is found -# -# These variables do _NOT_ have any effect anymore (compared to FindQt.cmake) -# QT_MT_REQUIRED Qt4 is now always multithreaded -# -# These variables are set to "" Because Qt structure changed -# (They make no sense in Qt4) -# QT_QT_LIBRARY Qt-Library is now split - -# Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. -# See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. - -# Use FIND_PACKAGE( Qt4 COMPONENTS ... ) to enable modules -IF( Qt4_FIND_COMPONENTS ) - FOREACH( component ${Qt4_FIND_COMPONENTS} ) - STRING( TOUPPER ${component} _COMPONENT ) - SET( QT_USE_${_COMPONENT} 1 ) - ENDFOREACH( component ) - - # To make sure we don't use QtCore or QtGui when not in COMPONENTS - IF(NOT QT_USE_QTCORE) - SET( QT_DONT_USE_QTCORE 1 ) - ENDIF(NOT QT_USE_QTCORE) - - IF(NOT QT_USE_QTGUI) - SET( QT_DONT_USE_QTGUI 1 ) - ENDIF(NOT QT_USE_QTGUI) - -ENDIF( Qt4_FIND_COMPONENTS ) - -# If Qt3 has already been found, fail. -IF(QT_QT_LIBRARY) - IF(Qt4_FIND_REQUIRED) - MESSAGE( FATAL_ERROR "Qt3 and Qt4 cannot be used together in one project. If switching to Qt4, the CMakeCache.txt needs to be cleaned.") - ELSE(Qt4_FIND_REQUIRED) - IF(NOT Qt4_FIND_QUIETLY) - MESSAGE( STATUS "Qt3 and Qt4 cannot be used together in one project. If switching to Qt4, the CMakeCache.txt needs to be cleaned.") - ENDIF(NOT Qt4_FIND_QUIETLY) - RETURN() - ENDIF(Qt4_FIND_REQUIRED) -ENDIF(QT_QT_LIBRARY) - - -IF (QT4_QMAKE_FOUND AND Qt4::QtCore) - # Check already done in this cmake run, nothing more to do - RETURN() -ENDIF (QT4_QMAKE_FOUND AND Qt4::QtCore) - -# check that QT_NO_DEBUG is defined for release configurations -MACRO(QT_CHECK_FLAG_EXISTS FLAG VAR DOC) - IF(NOT ${VAR} MATCHES "${FLAG}") - SET(${VAR} "${${VAR}} ${FLAG}" - CACHE STRING "Flags used by the compiler during ${DOC} builds." FORCE) - ENDIF(NOT ${VAR} MATCHES "${FLAG}") -ENDMACRO(QT_CHECK_FLAG_EXISTS FLAG VAR) - -QT_CHECK_FLAG_EXISTS(-DQT_NO_DEBUG CMAKE_CXX_FLAGS_RELWITHDEBINFO "Release with Debug Info") -QT_CHECK_FLAG_EXISTS(-DQT_NO_DEBUG CMAKE_CXX_FLAGS_RELEASE "release") -QT_CHECK_FLAG_EXISTS(-DQT_NO_DEBUG CMAKE_CXX_FLAGS_MINSIZEREL "release minsize") - -INCLUDE(MacroPushRequiredVars) -INCLUDE(CheckSymbolExists) -INCLUDE(MacroAddFileDependencies) - -SET(QT_USE_FILE ${CMAKE_ROOT}/Modules/UseQt4.cmake) - -SET( QT_DEFINITIONS "") - -SET(QT4_INSTALLED_VERSION_TOO_OLD FALSE) - -# macro for asking qmake to process pro files -MACRO(QT_QUERY_QMAKE outvar invar) - IF(QT_QMAKE_EXECUTABLE) - FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmpQmake/tmp.pro - "message(CMAKE_MESSAGE<$$${invar}>)") - - # Invoke qmake with the tmp.pro program to get the desired - # information. Use the same variable for both stdout and stderr - # to make sure we get the output on all platforms. - EXECUTE_PROCESS(COMMAND ${QT_QMAKE_EXECUTABLE} - WORKING_DIRECTORY - ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmpQmake - OUTPUT_VARIABLE _qmake_query_output - RESULT_VARIABLE _qmake_result - ERROR_VARIABLE _qmake_query_output ) - - FILE(REMOVE_RECURSE - "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmpQmake") - - IF(_qmake_result) - MESSAGE(WARNING " querying qmake for ${invar}. qmake reported:\n${_qmake_query_output}") - ELSE(_qmake_result) - STRING(REGEX REPLACE ".*CMAKE_MESSAGE<([^>]*).*" "\\1" ${outvar} "${_qmake_query_output}") - ENDIF(_qmake_result) - - ENDIF(QT_QMAKE_EXECUTABLE) -ENDMACRO(QT_QUERY_QMAKE) - -GET_FILENAME_COMPONENT(qt_install_version "[HKEY_CURRENT_USER\\Software\\trolltech\\Versions;DefaultQtVersion]" NAME) -# check for qmake -# Debian uses qmake-qt4 -# macports' Qt uses qmake-mac -FIND_PROGRAM(QT_QMAKE_EXECUTABLE NAMES qmake qmake4 qmake-qt4 qmake-mac PATHS - "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\4.0.0;InstallDir]/bin" - "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\4.0.0;InstallDir]/bin" - "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\${qt_install_version};InstallDir]/bin" - $ENV{QTDIR}/bin -) - -IF (QT_QMAKE_EXECUTABLE) - - IF(QT_QMAKE_EXECUTABLE_LAST) - STRING(COMPARE NOTEQUAL "${QT_QMAKE_EXECUTABLE_LAST}" "${QT_QMAKE_EXECUTABLE}" QT_QMAKE_CHANGED) - ENDIF(QT_QMAKE_EXECUTABLE_LAST) - - SET(QT_QMAKE_EXECUTABLE_LAST "${QT_QMAKE_EXECUTABLE}" CACHE INTERNAL "" FORCE) - - SET(QT4_QMAKE_FOUND FALSE) - - EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE} ARGS "-query QT_VERSION" OUTPUT_VARIABLE QTVERSION) - - # check for qt3 qmake and then try and find qmake4 or qmake-qt4 in the path - IF("${QTVERSION}" MATCHES "Unknown") - SET(QT_QMAKE_EXECUTABLE NOTFOUND CACHE FILEPATH "" FORCE) - FIND_PROGRAM(QT_QMAKE_EXECUTABLE NAMES qmake4 qmake-qt4 PATHS - "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\4.0.0;InstallDir]/bin" - "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\4.0.0;InstallDir]/bin" - $ENV{QTDIR}/bin - ) - IF(QT_QMAKE_EXECUTABLE) - EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE} - ARGS "-query QT_VERSION" OUTPUT_VARIABLE QTVERSION) - ENDIF(QT_QMAKE_EXECUTABLE) - ENDIF("${QTVERSION}" MATCHES "Unknown") - - # check that we found the Qt4 qmake, Qt3 qmake output won't match here - STRING(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" qt_version_tmp "${QTVERSION}") - IF (qt_version_tmp) - - # we need at least version 4.0.0 - IF (NOT QT_MIN_VERSION) - SET(QT_MIN_VERSION "4.0.0") - ENDIF (NOT QT_MIN_VERSION) - - #now parse the parts of the user given version string into variables - STRING(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" req_qt_major_vers "${QT_MIN_VERSION}") - IF (NOT req_qt_major_vers) - MESSAGE( FATAL_ERROR "Invalid Qt version string given: \"${QT_MIN_VERSION}\", expected e.g. \"4.0.1\"") - ENDIF (NOT req_qt_major_vers) - - # now parse the parts of the user given version string into variables - STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" req_qt_major_vers "${QT_MIN_VERSION}") - STRING(REGEX REPLACE "^[0-9]+\\.([0-9])+\\.[0-9]+" "\\1" req_qt_minor_vers "${QT_MIN_VERSION}") - STRING(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" req_qt_patch_vers "${QT_MIN_VERSION}") - - # Suppport finding at least a particular version, for instance FIND_PACKAGE( Qt4 4.4.3 ) - # This implementation is a hack to avoid duplicating code and make sure we stay - # source-compatible with CMake 2.6.x - IF( Qt4_FIND_VERSION ) - SET( QT_MIN_VERSION ${Qt4_FIND_VERSION} ) - SET( req_qt_major_vers ${Qt4_FIND_VERSION_MAJOR} ) - SET( req_qt_minor_vers ${Qt4_FIND_VERSION_MINOR} ) - SET( req_qt_patch_vers ${Qt4_FIND_VERSION_PATCH} ) - ENDIF( Qt4_FIND_VERSION ) - - IF (NOT req_qt_major_vers EQUAL 4) - MESSAGE( FATAL_ERROR "Invalid Qt version string given: \"${QT_MIN_VERSION}\", major version 4 is required, e.g. \"4.0.1\"") - ENDIF (NOT req_qt_major_vers EQUAL 4) - - # and now the version string given by qmake - STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" QT_VERSION_MAJOR "${QTVERSION}") - STRING(REGEX REPLACE "^[0-9]+\\.([0-9])+\\.[0-9]+.*" "\\1" QT_VERSION_MINOR "${QTVERSION}") - STRING(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" QT_VERSION_PATCH "${QTVERSION}") - - # compute an overall version number which can be compared at once - MATH(EXPR req_vers "${req_qt_major_vers}*10000 + ${req_qt_minor_vers}*100 + ${req_qt_patch_vers}") - MATH(EXPR found_vers "${QT_VERSION_MAJOR}*10000 + ${QT_VERSION_MINOR}*100 + ${QT_VERSION_PATCH}") - - # Support finding *exactly* a particular version, for instance FIND_PACKAGE( Qt4 4.4.3 EXACT ) - IF( Qt4_FIND_VERSION_EXACT ) - IF(found_vers EQUAL req_vers) - SET( QT4_QMAKE_FOUND TRUE ) - ELSE(found_vers EQUAL req_vers) - SET( QT4_QMAKE_FOUND FALSE ) - IF (found_vers LESS req_vers) - SET(QT4_INSTALLED_VERSION_TOO_OLD TRUE) - ELSE (found_vers LESS req_vers) - SET(QT4_INSTALLED_VERSION_TOO_NEW TRUE) - ENDIF (found_vers LESS req_vers) - ENDIF(found_vers EQUAL req_vers) - ELSE( Qt4_FIND_VERSION_EXACT ) - IF (found_vers LESS req_vers) - SET(QT4_QMAKE_FOUND FALSE) - SET(QT4_INSTALLED_VERSION_TOO_OLD TRUE) - ELSE (found_vers LESS req_vers) - SET(QT4_QMAKE_FOUND TRUE) - ENDIF (found_vers LESS req_vers) - ENDIF( Qt4_FIND_VERSION_EXACT ) - ENDIF (qt_version_tmp) - -ENDIF (QT_QMAKE_EXECUTABLE) - -IF (QT4_QMAKE_FOUND) - - if (WIN32) - # get qt install dir - get_filename_component(_DIR ${QT_QMAKE_EXECUTABLE} PATH ) - get_filename_component(QT_INSTALL_DIR ${_DIR} PATH ) - endif (WIN32) - - # ask qmake for the library dir - # Set QT_LIBRARY_DIR - IF (NOT QT_LIBRARY_DIR OR QT_QMAKE_CHANGED) - EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE} - ARGS "-query QT_INSTALL_LIBS" - OUTPUT_VARIABLE QT_LIBRARY_DIR_TMP ) - # make sure we have / and not \ as qmake gives on windows - FILE(TO_CMAKE_PATH "${QT_LIBRARY_DIR_TMP}" QT_LIBRARY_DIR_TMP) - IF(EXISTS "${QT_LIBRARY_DIR_TMP}") - SET(QT_LIBRARY_DIR ${QT_LIBRARY_DIR_TMP} CACHE PATH "Qt library dir" FORCE) - ELSE(EXISTS "${QT_LIBRARY_DIR_TMP}") - MESSAGE("Warning: QT_QMAKE_EXECUTABLE reported QT_INSTALL_LIBS as ${QT_LIBRARY_DIR_TMP}") - MESSAGE("Warning: ${QT_LIBRARY_DIR_TMP} does NOT exist, Qt must NOT be installed correctly.") - ENDIF(EXISTS "${QT_LIBRARY_DIR_TMP}") - ENDIF(NOT QT_LIBRARY_DIR OR QT_QMAKE_CHANGED) - - IF (APPLE) - IF (EXISTS ${QT_LIBRARY_DIR}/QtCore.framework) - SET(QT_USE_FRAMEWORKS ON - CACHE BOOL "Set to ON if Qt build uses frameworks." FORCE) - ELSE (EXISTS ${QT_LIBRARY_DIR}/QtCore.framework) - SET(QT_USE_FRAMEWORKS OFF - CACHE BOOL "Set to ON if Qt build uses frameworks." FORCE) - ENDIF (EXISTS ${QT_LIBRARY_DIR}/QtCore.framework) - - MARK_AS_ADVANCED(QT_USE_FRAMEWORKS) - ENDIF (APPLE) - - # ask qmake for the binary dir - IF (QT_LIBRARY_DIR AND NOT QT_BINARY_DIR OR QT_QMAKE_CHANGED) - EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE} - ARGS "-query QT_INSTALL_BINS" - OUTPUT_VARIABLE qt_bins ) - # make sure we have / and not \ as qmake gives on windows - FILE(TO_CMAKE_PATH "${qt_bins}" qt_bins) - SET(QT_BINARY_DIR ${qt_bins} CACHE INTERNAL "" FORCE) - ENDIF (QT_LIBRARY_DIR AND NOT QT_BINARY_DIR OR QT_QMAKE_CHANGED) - - # ask qmake for the include dir - IF (QT_LIBRARY_DIR AND NOT QT_HEADERS_DIR OR QT_QMAKE_CHANGED) - EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE} - ARGS "-query QT_INSTALL_HEADERS" - OUTPUT_VARIABLE qt_headers ) - # make sure we have / and not \ as qmake gives on windows - FILE(TO_CMAKE_PATH "${qt_headers}" qt_headers) - SET(QT_HEADERS_DIR ${qt_headers} CACHE INTERNAL "" FORCE) - ENDIF (QT_LIBRARY_DIR AND NOT QT_HEADERS_DIR OR QT_QMAKE_CHANGED) - - - # ask qmake for the documentation directory - IF (QT_LIBRARY_DIR AND NOT QT_DOC_DIR OR QT_QMAKE_CHANGED) - EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE} - ARGS "-query QT_INSTALL_DOCS" - OUTPUT_VARIABLE qt_doc_dir ) - # make sure we have / and not \ as qmake gives on windows - FILE(TO_CMAKE_PATH "${qt_doc_dir}" qt_doc_dir) - SET(QT_DOC_DIR ${qt_doc_dir} CACHE PATH "The location of the Qt docs" FORCE) - ENDIF (QT_LIBRARY_DIR AND NOT QT_DOC_DIR OR QT_QMAKE_CHANGED) - - # ask qmake for the mkspecs directory - IF (QT_LIBRARY_DIR AND NOT QT_MKSPECS_DIR OR QT_QMAKE_CHANGED) - EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE} - ARGS "-query QMAKE_MKSPECS" - OUTPUT_VARIABLE qt_mkspecs_dirs ) - # do not replace : on windows as it might be a drive letter - # and windows should already use ; as a separator - IF(UNIX) - STRING(REPLACE ":" ";" qt_mkspecs_dirs "${qt_mkspecs_dirs}") - ENDIF(UNIX) - SET(QT_MKSPECS_DIR NOTFOUND) - FIND_PATH(QT_MKSPECS_DIR qconfig.pri PATHS ${qt_mkspecs_dirs} - DOC "The location of the Qt mkspecs containing qconfig.pri" - NO_DEFAULT_PATH ) - ENDIF (QT_LIBRARY_DIR AND NOT QT_MKSPECS_DIR OR QT_QMAKE_CHANGED) - - # ask qmake for the plugins directory - IF (QT_LIBRARY_DIR AND NOT QT_PLUGINS_DIR OR QT_QMAKE_CHANGED) - EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE} - ARGS "-query QT_INSTALL_PLUGINS" - OUTPUT_VARIABLE qt_plugins_dir ) - # make sure we have / and not \ as qmake gives on windows - FILE(TO_CMAKE_PATH "${qt_plugins_dir}" qt_plugins_dir) - SET(QT_PLUGINS_DIR ${qt_plugins_dir} CACHE PATH "The location of the Qt plugins" FORCE) - ENDIF (QT_LIBRARY_DIR AND NOT QT_PLUGINS_DIR OR QT_QMAKE_CHANGED) - - # ask qmake for the translations directory - IF (QT_LIBRARY_DIR AND NOT QT_TRANSLATIONS_DIR OR QT_QMAKE_CHANGED) - EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE} - ARGS "-query QT_INSTALL_TRANSLATIONS" - OUTPUT_VARIABLE qt_translations_dir ) - # make sure we have / and not \ as qmake gives on windows - FILE(TO_CMAKE_PATH "${qt_translations_dir}" qt_translations_dir) - SET(QT_TRANSLATIONS_DIR ${qt_translations_dir} CACHE PATH "The location of the Qt translations" FORCE) - ENDIF (QT_LIBRARY_DIR AND NOT QT_TRANSLATIONS_DIR OR QT_QMAKE_CHANGED) - - # Make variables changeble to the advanced user - MARK_AS_ADVANCED( QT_LIBRARY_DIR QT_DOC_DIR QT_MKSPECS_DIR - QT_PLUGINS_DIR QT_TRANSLATIONS_DIR) - - - ############################################# - # - # Find out what window system we're using - # - ############################################# - # Save required includes and required_flags variables - MACRO_PUSH_REQUIRED_VARS() - # Add QT_INCLUDE_DIR to CMAKE_REQUIRED_INCLUDES - SET(CMAKE_REQUIRED_INCLUDES "${CMAKE_REQUIRED_INCLUDES};${QT_HEADERS_DIR}") - # On Mac OS X when Qt has framework support, also add the framework path - IF( QT_USE_FRAMEWORKS ) - SET(CMAKE_REQUIRED_FLAGS "-F${QT_LIBRARY_DIR} ") - ENDIF( QT_USE_FRAMEWORKS ) - # Check for Window system symbols (note: only one should end up being set) - CHECK_SYMBOL_EXISTS(Q_WS_X11 "QtCore/qglobal.h" Q_WS_X11) - CHECK_SYMBOL_EXISTS(Q_WS_WIN "QtCore/qglobal.h" Q_WS_WIN) - CHECK_SYMBOL_EXISTS(Q_WS_QWS "QtCore/qglobal.h" Q_WS_QWS) - CHECK_SYMBOL_EXISTS(Q_WS_MAC "QtCore/qglobal.h" Q_WS_MAC) - IF(Q_WS_MAC) - IF(QT_QMAKE_CHANGED) - SET(QT_MAC_USE_COCOA "" CACHE BOOL "Use Cocoa on Mac" FORCE) - ENDIF(QT_QMAKE_CHANGED) - CHECK_SYMBOL_EXISTS(QT_MAC_USE_COCOA "QtCore/qconfig.h" QT_MAC_USE_COCOA) - ENDIF(Q_WS_MAC) - - IF (QT_QTCOPY_REQUIRED) - CHECK_SYMBOL_EXISTS(QT_IS_QTCOPY "QtCore/qglobal.h" QT_KDE_QT_COPY) - IF (NOT QT_IS_QTCOPY) - MESSAGE(FATAL_ERROR "qt-copy is required, but hasn't been found") - ENDIF (NOT QT_IS_QTCOPY) - ENDIF (QT_QTCOPY_REQUIRED) - - # Restore CMAKE_REQUIRED_INCLUDES+CMAKE_REQUIRED_FLAGS variables - MACRO_POP_REQUIRED_VARS() - # - ############################################# - - - - ######################################## - # - # Setting the INCLUDE-Variables - # - ######################################## - - SET(QT_MODULES QtCore QtGui Qt3Support QtSvg QtScript QtTest QtUiTools - QtHelp QtWebKit QtXmlPatterns QtNetwork QtMultimedia - QtNsPlugin QtOpenGL QtSql QtXml QtDesigner QtDBus QtScriptTools QtDeclarative) - - IF(Q_WS_X11) - SET(QT_MODULES ${QT_MODULES} QtMotif) - ENDIF(Q_WS_X11) - - IF(QT_QMAKE_CHANGED) - FOREACH(QT_MODULE ${QT_MODULES}) - STRING(TOUPPER ${QT_MODULE} _upper_qt_module) - SET(QT_${_upper_qt_module}_INCLUDE_DIR NOTFOUND) - SET(QT_${_upper_qt_module}_LIBRARY_RELEASE NOTFOUND) - SET(QT_${_upper_qt_module}_LIBRARY_DEBUG NOTFOUND) - ENDFOREACH(QT_MODULE) - SET(QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR NOTFOUND) - SET(QT_QTDESIGNERCOMPONENTS_LIBRARY_RELEASE NOTFOUND) - SET(QT_QTDESIGNERCOMPONENTS_LIBRARY_DEBUG NOTFOUND) - SET(QT_QTASSISTANTCLIENT_INCLUDE_DIR NOTFOUND) - SET(QT_QTASSISTANTCLIENT_LIBRARY_RELEASE NOTFOUND) - SET(QT_QTASSISTANTCLIENT_LIBRARY_DEBUG NOTFOUND) - SET(QT_QTASSISTANT_INCLUDE_DIR NOTFOUND) - SET(QT_QTASSISTANT_LIBRARY_RELEASE NOTFOUND) - SET(QT_QTASSISTANT_LIBRARY_DEBUG NOTFOUND) - SET(QT_QTCLUCENE_LIBRARY_RELEASE NOTFOUND) - SET(QT_QTCLUCENE_LIBRARY_DEBUG NOTFOUND) - SET(QT_QAXCONTAINER_INCLUDE_DIR NOTFOUND) - SET(QT_QAXCONTAINER_LIBRARY_RELEASE NOTFOUND) - SET(QT_QAXCONTAINER_LIBRARY_DEBUG NOTFOUND) - SET(QT_QAXSERVER_INCLUDE_DIR NOTFOUND) - SET(QT_QAXSERVER_LIBRARY_RELEASE NOTFOUND) - SET(QT_QAXSERVER_LIBRARY_DEBUG NOTFOUND) - IF(WIN32) - SET(QT_QTMAIN_LIBRARY_DEBUG NOTFOUND) - SET(QT_QTMAIN_LIBRARY_RELEASE NOTFOUND) - ENDIF(WIN32) - SET(QT_PHONON_INCLUDE_DIR NOTFOUND) - ENDIF(QT_QMAKE_CHANGED) - - FOREACH(QT_MODULE ${QT_MODULES}) - STRING(TOUPPER ${QT_MODULE} _upper_qt_module) - FIND_PATH(QT_${_upper_qt_module}_INCLUDE_DIR ${QT_MODULE} - PATHS - ${QT_HEADERS_DIR}/${QT_MODULE} - ${QT_LIBRARY_DIR}/${QT_MODULE}.framework/Headers - NO_DEFAULT_PATH - ) - ENDFOREACH(QT_MODULE) - - IF(WIN32) - SET(QT_MODULES ${QT_MODULES} QAxContainer QAxServer) - # Set QT_AXCONTAINER_INCLUDE_DIR and QT_AXSERVER_INCLUDE_DIR - FIND_PATH(QT_QAXCONTAINER_INCLUDE_DIR ActiveQt - PATHS - ${QT_HEADERS_DIR}/ActiveQt - NO_DEFAULT_PATH - ) - FIND_PATH(QT_QAXSERVER_INCLUDE_DIR ActiveQt - PATHS - ${QT_HEADERS_DIR}/ActiveQt - NO_DEFAULT_PATH - ) - ENDIF(WIN32) - - # Set QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR - FIND_PATH(QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR QDesignerComponents - PATHS - ${QT_HEADERS_DIR}/QtDesigner - ${QT_LIBRARY_DIR}/QtDesigner.framework/Headers - NO_DEFAULT_PATH - ) - - # Set QT_QTASSISTANT_INCLUDE_DIR - FIND_PATH(QT_QTASSISTANT_INCLUDE_DIR QtAssistant - PATHS - ${QT_HEADERS_DIR}/QtAssistant - ${QT_LIBRARY_DIR}/QtAssistant.framework/Headers - NO_DEFAULT_PATH - ) - - # Set QT_QTASSISTANTCLIENT_INCLUDE_DIR - FIND_PATH(QT_QTASSISTANTCLIENT_INCLUDE_DIR QAssistantClient - PATHS - ${QT_HEADERS_DIR}/QtAssistant - ${QT_LIBRARY_DIR}/QtAssistant.framework/Headers - NO_DEFAULT_PATH - ) - - # Set QT_QT_INCLUDE_DIR - FIND_PATH(QT_QT_INCLUDE_DIR qglobal.h - PATHS - ${QT_HEADERS_DIR}/Qt - ${QT_LIBRARY_DIR}/QtCore.framework/Headers - NO_DEFAULT_PATH - ) - - # Set QT_PHONON_INCLUDE_DIR - # Qt >= 4.5.3 (or kde-qt-4.5.2 which has the fix too) : Phonon/ClassName is inside include/phonon - # With previous versions of Qt, this could not work; upgrade Qt or use a standalone phonon - FIND_PATH(QT_PHONON_INCLUDE_DIR Phonon - PATHS - ${QT_HEADERS_DIR}/phonon - NO_DEFAULT_PATH - ) - SET(QT_MODULES ${QT_MODULES} phonon) - - # Set QT_INCLUDE_DIR by removine "/QtCore" in the string ${QT_QTCORE_INCLUDE_DIR} - IF( QT_QTCORE_INCLUDE_DIR AND NOT QT_INCLUDE_DIR) - IF (QT_USE_FRAMEWORKS) - SET(QT_INCLUDE_DIR ${QT_HEADERS_DIR}) - ELSE (QT_USE_FRAMEWORKS) - STRING( REGEX REPLACE "/QtCore$" "" qt4_include_dir ${QT_QTCORE_INCLUDE_DIR}) - SET( QT_INCLUDE_DIR ${qt4_include_dir} CACHE PATH "") - ENDIF (QT_USE_FRAMEWORKS) - ENDIF( QT_QTCORE_INCLUDE_DIR AND NOT QT_INCLUDE_DIR) - - IF( NOT QT_INCLUDE_DIR) - IF(Qt4_FIND_REQUIRED) - MESSAGE( FATAL_ERROR "Could NOT find QtCore header") - ENDIF(Qt4_FIND_REQUIRED) - ENDIF( NOT QT_INCLUDE_DIR) - - # Make variables changeble to the advanced user - MARK_AS_ADVANCED( QT_INCLUDE_DIR QT_QT_INCLUDE_DIR) - - # Set QT_INCLUDES - SET( QT_INCLUDES ${QT_QT_INCLUDE_DIR} ${QT_MKSPECS_DIR}/default ${QT_INCLUDE_DIR} ) - - - ####################################### - # - # Qt configuration - # - ####################################### - IF(EXISTS "${QT_MKSPECS_DIR}/qconfig.pri") - FILE(READ ${QT_MKSPECS_DIR}/qconfig.pri _qconfig_FILE_contents) - STRING(REGEX MATCH "QT_CONFIG[^\n]+" QT_QCONFIG "${_qconfig_FILE_contents}") - STRING(REGEX MATCH "CONFIG[^\n]+" QT_CONFIG "${_qconfig_FILE_contents}") - STRING(REGEX MATCH "EDITION[^\n]+" QT_EDITION "${_qconfig_FILE_contents}") - STRING(REGEX MATCH "QT_LIBINFIX[^\n]+" _qconfig_qt_libinfix "${_qconfig_FILE_contents}") - STRING(REGEX REPLACE "QT_LIBINFIX *= *([^\n]*)" "\\1" QT_LIBINFIX "${_qconfig_qt_libinfix}") - ENDIF(EXISTS "${QT_MKSPECS_DIR}/qconfig.pri") - IF("${QT_EDITION}" MATCHES "DesktopLight") - SET(QT_EDITION_DESKTOPLIGHT 1) - ENDIF("${QT_EDITION}" MATCHES "DesktopLight") - - ######################################## - # - # Setting the LIBRARY-Variables - # - ######################################## - - # find the libraries - FOREACH(QT_MODULE ${QT_MODULES}) - STRING(TOUPPER ${QT_MODULE} _upper_qt_module) - FIND_LIBRARY(QT_${_upper_qt_module}_LIBRARY_RELEASE - NAMES ${QT_MODULE}${QT_LIBINFIX} ${QT_MODULE}${QT_LIBINFIX}4 - PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH - ) - FIND_LIBRARY(QT_${_upper_qt_module}_LIBRARY_DEBUG - NAMES ${QT_MODULE}${QT_LIBINFIX}_debug ${QT_MODULE}${QT_LIBINFIX}d ${QT_MODULE}${QT_LIBINFIX}d4 - PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH - ) - ENDFOREACH(QT_MODULE) - - # QtUiTools not with other frameworks with binary installation (in /usr/lib) - IF(Q_WS_MAC AND QT_QTCORE_LIBRARY_RELEASE AND NOT QT_QTUITOOLS_LIBRARY_RELEASE) - FIND_LIBRARY(QT_QTUITOOLS_LIBRARY_RELEASE NAMES QtUiTools${QT_LIBINFIX} PATHS ${QT_LIBRARY_DIR}) - ENDIF(Q_WS_MAC AND QT_QTCORE_LIBRARY_RELEASE AND NOT QT_QTUITOOLS_LIBRARY_RELEASE) - - IF( NOT QT_QTCORE_LIBRARY_DEBUG AND NOT QT_QTCORE_LIBRARY_RELEASE ) - - # try dropping a hint if trying to use Visual Studio with Qt built by mingw - IF(QT_LIBRARY_DIR AND MSVC) - IF(EXISTS ${QT_LIBRARY_DIR}/libqtmain.a) - MESSAGE( FATAL_ERROR "It appears you're trying to use Visual Studio with Qt built by mingw") - ENDIF(EXISTS ${QT_LIBRARY_DIR}/libqtmain.a) - ENDIF(QT_LIBRARY_DIR AND MSVC) - - IF(Qt4_FIND_REQUIRED) - MESSAGE( FATAL_ERROR "Could NOT find QtCore. Check ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log for more details.") - ENDIF(Qt4_FIND_REQUIRED) - ENDIF( NOT QT_QTCORE_LIBRARY_DEBUG AND NOT QT_QTCORE_LIBRARY_RELEASE ) - - # Set QT_QTDESIGNERCOMPONENTS_LIBRARY - FIND_LIBRARY(QT_QTDESIGNERCOMPONENTS_LIBRARY_RELEASE NAMES QtDesignerComponents${QT_LIBINFIX} QtDesignerComponents${QT_LIBINFIX}4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - FIND_LIBRARY(QT_QTDESIGNERCOMPONENTS_LIBRARY_DEBUG NAMES QtDesignerComponents${QT_LIBINFIX}_debug QtDesignerComponents${QT_LIBINFIX}d QtDesignerComponents${QT_LIBINFIX}d4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - - # Set QT_QTMAIN_LIBRARY - IF(WIN32) - FIND_LIBRARY(QT_QTMAIN_LIBRARY_RELEASE NAMES qtmain${QT_LIBINFIX} PATHS ${QT_LIBRARY_DIR} - NO_DEFAULT_PATH) - FIND_LIBRARY(QT_QTMAIN_LIBRARY_DEBUG NAMES qtmain${QT_LIBINFIX}d PATHS ${QT_LIBRARY_DIR} - NO_DEFAULT_PATH) - ENDIF(WIN32) - - # Set QT_QTASSISTANTCLIENT_LIBRARY - FIND_LIBRARY(QT_QTASSISTANTCLIENT_LIBRARY_RELEASE NAMES QtAssistantClient${QT_LIBINFIX} QtAssistantClient${QT_LIBINFIX}4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - FIND_LIBRARY(QT_QTASSISTANTCLIENT_LIBRARY_DEBUG NAMES QtAssistantClient${QT_LIBINFIX}_debug QtAssistantClient${QT_LIBINFIX}d QtAssistantClient${QT_LIBINFIX}d4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - - # Set QT_QTASSISTANT_LIBRARY - FIND_LIBRARY(QT_QTASSISTANT_LIBRARY_RELEASE NAMES QtAssistantClient${QT_LIBINFIX} QtAssistantClient${QT_LIBINFIX}4 QtAssistant${QT_LIBINFIX} QtAssistant${QT_LIBINFIX}4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - FIND_LIBRARY(QT_QTASSISTANT_LIBRARY_DEBUG NAMES QtAssistantClient${QT_LIBINFIX}_debug QtAssistantClient${QT_LIBINFIX}d QtAssistantClient${QT_LIBINFIX}d4 QtAssistant${QT_LIBINFIX}_debug QtAssistant${QT_LIBINFIX}d4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - - # Set QT_QTHELP_LIBRARY - FIND_LIBRARY(QT_QTCLUCENE_LIBRARY_RELEASE NAMES QtCLucene${QT_LIBINFIX} QtCLucene${QT_LIBINFIX}4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - FIND_LIBRARY(QT_QTCLUCENE_LIBRARY_DEBUG NAMES QtCLucene${QT_LIBINFIX}_debug QtCLucene${QT_LIBINFIX}d QtCLucene${QT_LIBINFIX}d4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) - # QtCLucene not with other frameworks with binary installation (in /usr/lib) - IF(Q_WS_MAC AND QT_QTCORE_LIBRARY_RELEASE AND NOT QT_QTCLUCENE_LIBRARY_RELEASE) - FIND_LIBRARY(QT_QTCLUCENE_LIBRARY_RELEASE NAMES QtCLucene${QT_LIBINFIX} PATHS ${QT_LIBRARY_DIR}) - ENDIF(Q_WS_MAC AND QT_QTCORE_LIBRARY_RELEASE AND NOT QT_QTCLUCENE_LIBRARY_RELEASE) - - ############################################ - # - # Check the existence of the libraries. - # - ############################################ - - # On OSX when Qt is found as framework, never use the imported targets for now, since - # in this case the handling of the framework directory currently does not work correctly. - IF(QT_USE_FRAMEWORKS) - SET(QT_USE_IMPORTED_TARGETS FALSE) - ENDIF(QT_USE_FRAMEWORKS) - - - MACRO (_QT4_ADJUST_LIB_VARS _camelCaseBasename) - - STRING(TOUPPER "${_camelCaseBasename}" basename) - - # The name of the imported targets, i.e. the prefix "Qt4::" must not change, - # since it is stored in EXPORT-files as name of a required library. If the name would change - # here, this would lead to the imported Qt4-library targets not being resolved by cmake anymore. - IF (QT_${basename}_LIBRARY_RELEASE OR QT_${basename}_LIBRARY_DEBUG) - - IF(NOT TARGET Qt4::${_camelCaseBasename}) - ADD_LIBRARY(Qt4::${_camelCaseBasename} UNKNOWN IMPORTED ) - - IF (QT_${basename}_LIBRARY_RELEASE) - SET_PROPERTY(TARGET Qt4::${_camelCaseBasename} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) - SET_PROPERTY(TARGET Qt4::${_camelCaseBasename} PROPERTY IMPORTED_LOCATION_RELEASE "${QT_${basename}_LIBRARY_RELEASE}" ) - ENDIF (QT_${basename}_LIBRARY_RELEASE) - - IF (QT_${basename}_LIBRARY_DEBUG) - SET_PROPERTY(TARGET Qt4::${_camelCaseBasename} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) - SET_PROPERTY(TARGET Qt4::${_camelCaseBasename} PROPERTY IMPORTED_LOCATION_DEBUG "${QT_${basename}_LIBRARY_DEBUG}" ) - ENDIF (QT_${basename}_LIBRARY_DEBUG) - ENDIF(NOT TARGET Qt4::${_camelCaseBasename}) - - # If QT_USE_IMPORTED_TARGETS is enabled, the QT_QTFOO_LIBRARY variables are set to point at these - # imported targets. This works better in general, and is also in almost all cases fully - # backward compatible. The only issue is when a project A which had this enabled then exports its - # libraries via export or EXPORT_LIBRARY_DEPENDENCIES(). In this case the libraries from project - # A will depend on the imported Qt targets, and the names of these imported targets will be stored - # in the dependency files on disk. This means when a project B then uses project A, these imported - # targets must be created again, otherwise e.g. "Qt4__QtCore" will be interpreted as name of a - # library file on disk, and not as a target, and linking will fail: - IF(QT_USE_IMPORTED_TARGETS) - SET(QT_${basename}_LIBRARY Qt4::${_camelCaseBasename} ) - SET(QT_${basename}_LIBRARIES Qt4::${_camelCaseBasename} ) - ELSE(QT_USE_IMPORTED_TARGETS) - - # if the release- as well as the debug-version of the library have been found: - IF (QT_${basename}_LIBRARY_DEBUG AND QT_${basename}_LIBRARY_RELEASE) - # if the generator supports configuration types then set - # optimized and debug libraries, or if the CMAKE_BUILD_TYPE has a value - IF (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) - SET(QT_${basename}_LIBRARY optimized ${QT_${basename}_LIBRARY_RELEASE} debug ${QT_${basename}_LIBRARY_DEBUG}) - ELSE(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) - # if there are no configuration types and CMAKE_BUILD_TYPE has no value - # then just use the release libraries - SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY_RELEASE} ) - ENDIF(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) - SET(QT_${basename}_LIBRARIES optimized ${QT_${basename}_LIBRARY_RELEASE} debug ${QT_${basename}_LIBRARY_DEBUG}) - ENDIF (QT_${basename}_LIBRARY_DEBUG AND QT_${basename}_LIBRARY_RELEASE) - - # if only the release version was found, set the debug variable also to the release version - IF (QT_${basename}_LIBRARY_RELEASE AND NOT QT_${basename}_LIBRARY_DEBUG) - SET(QT_${basename}_LIBRARY_DEBUG ${QT_${basename}_LIBRARY_RELEASE}) - SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY_RELEASE}) - SET(QT_${basename}_LIBRARIES ${QT_${basename}_LIBRARY_RELEASE}) - ENDIF (QT_${basename}_LIBRARY_RELEASE AND NOT QT_${basename}_LIBRARY_DEBUG) - - # if only the debug version was found, set the release variable also to the debug version - IF (QT_${basename}_LIBRARY_DEBUG AND NOT QT_${basename}_LIBRARY_RELEASE) - SET(QT_${basename}_LIBRARY_RELEASE ${QT_${basename}_LIBRARY_DEBUG}) - SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY_DEBUG}) - SET(QT_${basename}_LIBRARIES ${QT_${basename}_LIBRARY_DEBUG}) - ENDIF (QT_${basename}_LIBRARY_DEBUG AND NOT QT_${basename}_LIBRARY_RELEASE) - - # put the value in the cache: - SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY} CACHE STRING "The Qt ${basename} library" FORCE) - - ENDIF(QT_USE_IMPORTED_TARGETS) - -#message(STATUS "QT_${basename}_LIBRARY: ${QT_${basename}_LIBRARY}") - - SET(QT_${basename}_FOUND 1) - - ENDIF (QT_${basename}_LIBRARY_RELEASE OR QT_${basename}_LIBRARY_DEBUG) - - IF (QT_${basename}_INCLUDE_DIR) - #add the include directory to QT_INCLUDES - SET(QT_INCLUDES "${QT_${basename}_INCLUDE_DIR}" ${QT_INCLUDES}) - ENDIF (QT_${basename}_INCLUDE_DIR) - - # Make variables changeble to the advanced user - MARK_AS_ADVANCED(QT_${basename}_LIBRARY QT_${basename}_LIBRARY_RELEASE QT_${basename}_LIBRARY_DEBUG QT_${basename}_INCLUDE_DIR) - ENDMACRO (_QT4_ADJUST_LIB_VARS) - - - # Set QT_xyz_LIBRARY variable and add - # library include path to QT_INCLUDES - _QT4_ADJUST_LIB_VARS(QtCore) - _QT4_ADJUST_LIB_VARS(QtGui) - _QT4_ADJUST_LIB_VARS(Qt3Support) - _QT4_ADJUST_LIB_VARS(QtAssistant) - _QT4_ADJUST_LIB_VARS(QtAssistantClient) - _QT4_ADJUST_LIB_VARS(QtCLucene) - _QT4_ADJUST_LIB_VARS(QtDBus) - _QT4_ADJUST_LIB_VARS(QtDeclarative) - _QT4_ADJUST_LIB_VARS(QtDesigner) - _QT4_ADJUST_LIB_VARS(QtDesignerComponents) - _QT4_ADJUST_LIB_VARS(QtHelp) - _QT4_ADJUST_LIB_VARS(QtMultimedia) - _QT4_ADJUST_LIB_VARS(QtNetwork) - _QT4_ADJUST_LIB_VARS(QtNsPlugin) - _QT4_ADJUST_LIB_VARS(QtOpenGL) - _QT4_ADJUST_LIB_VARS(QtScript) - _QT4_ADJUST_LIB_VARS(QtScriptTools) - _QT4_ADJUST_LIB_VARS(QtSql) - _QT4_ADJUST_LIB_VARS(QtSvg) - _QT4_ADJUST_LIB_VARS(QtTest) - _QT4_ADJUST_LIB_VARS(QtUiTools) - _QT4_ADJUST_LIB_VARS(QtWebKit) - _QT4_ADJUST_LIB_VARS(QtXml) - _QT4_ADJUST_LIB_VARS(QtXmlPatterns) - _QT4_ADJUST_LIB_VARS(phonon) - - # platform dependent libraries - IF(Q_WS_X11) - _QT4_ADJUST_LIB_VARS(QtMotif) - ENDIF(Q_WS_X11) - IF(WIN32) - _QT4_ADJUST_LIB_VARS(qtmain) - _QT4_ADJUST_LIB_VARS(QAxServer) - _QT4_ADJUST_LIB_VARS(QAxContainer) - ENDIF(WIN32) - - # If Qt is installed as a framework, we need to add QT_QTCORE_LIBRARY here (which - # is the framework directory in that case), since this will make the cmake include_directories() - # command recognize that we need the framework flag with the respective directory (-F) - IF(QT_USE_FRAMEWORKS) - SET(QT_INCLUDES ${QT_INCLUDES} ${QT_QTCORE_LIBRARY} ) - SET(QT_INCLUDE_DIR ${QT_INCLUDE_DIR} ${QT_QTCORE_LIBRARY} ) - ENDIF(QT_USE_FRAMEWORKS) - - - - ####################################### - # - # Check the executables of Qt - # ( moc, uic, rcc ) - # - ####################################### - - - IF(QT_QMAKE_CHANGED) - SET(QT_UIC_EXECUTABLE NOTFOUND) - SET(QT_MOC_EXECUTABLE NOTFOUND) - SET(QT_UIC3_EXECUTABLE NOTFOUND) - SET(QT_RCC_EXECUTABLE NOTFOUND) - SET(QT_DBUSCPP2XML_EXECUTABLE NOTFOUND) - SET(QT_DBUSXML2CPP_EXECUTABLE NOTFOUND) - SET(QT_LUPDATE_EXECUTABLE NOTFOUND) - SET(QT_LRELEASE_EXECUTABLE NOTFOUND) - SET(QT_QCOLLECTIONGENERATOR_EXECUTABLE NOTFOUND) - SET(QT_DESIGNER_EXECUTABLE NOTFOUND) - SET(QT_LINGUIST_EXECUTABLE NOTFOUND) - ENDIF(QT_QMAKE_CHANGED) - - FIND_PROGRAM(QT_MOC_EXECUTABLE - NAMES moc-qt4 moc - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_UIC_EXECUTABLE - NAMES uic-qt4 uic - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_UIC3_EXECUTABLE - NAMES uic3 - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_RCC_EXECUTABLE - NAMES rcc - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_DBUSCPP2XML_EXECUTABLE - NAMES qdbuscpp2xml - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_DBUSXML2CPP_EXECUTABLE - NAMES qdbusxml2cpp - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_LUPDATE_EXECUTABLE - NAMES lupdate-qt4 lupdate - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_LRELEASE_EXECUTABLE - NAMES lrelease-qt4 lrelease - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_QCOLLECTIONGENERATOR_EXECUTABLE - NAMES qcollectiongenerator-qt4 qcollectiongenerator - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_DESIGNER_EXECUTABLE - NAMES designer-qt4 designer - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - FIND_PROGRAM(QT_LINGUIST_EXECUTABLE - NAMES linguist-qt4 linguist - PATHS ${QT_BINARY_DIR} - NO_DEFAULT_PATH - ) - - IF (QT_MOC_EXECUTABLE) - SET(QT_WRAP_CPP "YES") - ENDIF (QT_MOC_EXECUTABLE) - - IF (QT_UIC_EXECUTABLE) - SET(QT_WRAP_UI "YES") - ENDIF (QT_UIC_EXECUTABLE) - - - - MARK_AS_ADVANCED( QT_UIC_EXECUTABLE QT_UIC3_EXECUTABLE QT_MOC_EXECUTABLE - QT_RCC_EXECUTABLE QT_DBUSXML2CPP_EXECUTABLE QT_DBUSCPP2XML_EXECUTABLE - QT_LUPDATE_EXECUTABLE QT_LRELEASE_EXECUTABLE QT_QCOLLECTIONGENERATOR_EXECUTABLE - QT_DESIGNER_EXECUTABLE QT_LINGUIST_EXECUTABLE) - - - # get the directory of the current file, used later on in the file - GET_FILENAME_COMPONENT( _qt4_current_dir "${CMAKE_CURRENT_LIST_FILE}" PATH) - - ###################################### - # - # Macros for building Qt files - # - ###################################### - - INCLUDE("${_qt4_current_dir}/Qt4Macros.cmake") - - - ###################################### - # - # decide if Qt got found - # - ###################################### - - # if the includes,libraries,moc,uic and rcc are found then we have it - IF( QT_LIBRARY_DIR AND QT_INCLUDE_DIR AND QT_MOC_EXECUTABLE AND - QT_UIC_EXECUTABLE AND QT_RCC_EXECUTABLE AND QT_QTCORE_LIBRARY) - SET( QT4_FOUND "YES" ) - IF( NOT Qt4_FIND_QUIETLY) - MESSAGE(STATUS "Found Qt-Version ${QTVERSION} (using ${QT_QMAKE_EXECUTABLE})") - ENDIF( NOT Qt4_FIND_QUIETLY) - ELSE( QT_LIBRARY_DIR AND QT_INCLUDE_DIR AND QT_MOC_EXECUTABLE AND - QT_UIC_EXECUTABLE AND QT_RCC_EXECUTABLE AND QT_QTCORE_LIBRARY) - SET( QT4_FOUND "NO") - SET(QT_QMAKE_EXECUTABLE "${QT_QMAKE_EXECUTABLE}-NOTFOUND" CACHE FILEPATH "Invalid qmake found" FORCE) - IF( Qt4_FIND_REQUIRED) - IF ( NOT QT_LIBRARY_DIR ) - MESSAGE(STATUS "Qt libraries NOT found!") - ENDIF(NOT QT_LIBRARY_DIR ) - IF ( NOT QT_INCLUDE_DIR ) - MESSAGE(STATUS "Qt includes NOT found!") - ENDIF( NOT QT_INCLUDE_DIR ) - IF ( NOT QT_MOC_EXECUTABLE ) - MESSAGE(STATUS "Qt's moc NOT found!") - ENDIF( NOT QT_MOC_EXECUTABLE ) - IF ( NOT QT_UIC_EXECUTABLE ) - MESSAGE(STATUS "Qt's uic NOT found!") - ENDIF( NOT QT_UIC_EXECUTABLE ) - IF ( NOT QT_RCC_EXECUTABLE ) - MESSAGE(STATUS "Qt's rcc NOT found!") - ENDIF( NOT QT_RCC_EXECUTABLE ) - MESSAGE( FATAL_ERROR "Qt libraries, includes, moc, uic or/and rcc NOT found!") - ENDIF( Qt4_FIND_REQUIRED) - ENDIF( QT_LIBRARY_DIR AND QT_INCLUDE_DIR AND QT_MOC_EXECUTABLE AND - QT_UIC_EXECUTABLE AND QT_RCC_EXECUTABLE AND QT_QTCORE_LIBRARY) - - SET(QT_FOUND ${QT4_FOUND}) - - - ############################################### - # - # configuration/system dependent settings - # - ############################################### - - INCLUDE("${_qt4_current_dir}/Qt4ConfigDependentSettings.cmake") - - - ####################################### - # - # compatibility settings - # - ####################################### - # Backwards compatibility for CMake1.4 and 1.2 - SET (QT_MOC_EXE ${QT_MOC_EXECUTABLE} ) - SET (QT_UIC_EXE ${QT_UIC_EXECUTABLE} ) - - SET( QT_QT_LIBRARY "") - -ELSE(QT4_QMAKE_FOUND) - - SET(QT_QMAKE_EXECUTABLE "${QT_QMAKE_EXECUTABLE}-NOTFOUND" CACHE FILEPATH "Invalid qmake found" FORCE) - - # The code below is overly complex to make sure we do not break compatibility with CMake 2.6.x - # For CMake 2.8, it should be simplified by getting rid of QT4_INSTALLED_VERSION_TOO_OLD and - # QT4_INSTALLED_VERSION_TOO_NEW - IF(Qt4_FIND_REQUIRED) - IF(QT4_INSTALLED_VERSION_TOO_OLD) - IF( Qt4_FIND_VERSION_EXACT ) - MESSAGE(FATAL_ERROR "The installed Qt version ${QTVERSION} is too old, version ${QT_MIN_VERSION} is required") - ELSE( Qt4_FIND_VERSION_EXACT ) - MESSAGE(FATAL_ERROR "The installed Qt version ${QTVERSION} is too old, at least version ${QT_MIN_VERSION} is required") - ENDIF( Qt4_FIND_VERSION_EXACT ) - ELSE(QT4_INSTALLED_VERSION_TOO_OLD) - IF( Qt4_FIND_VERSION_EXACT AND QT4_INSTALLED_VERSION_TOO_NEW ) - MESSAGE(FATAL_ERROR "The installed Qt version ${QTVERSION} is too new, version ${QT_MIN_VERSION} is required") - ELSE( Qt4_FIND_VERSION_EXACT AND QT4_INSTALLED_VERSION_TOO_NEW ) - MESSAGE( FATAL_ERROR "Qt qmake not found!") - ENDIF( Qt4_FIND_VERSION_EXACT AND QT4_INSTALLED_VERSION_TOO_NEW ) - ENDIF(QT4_INSTALLED_VERSION_TOO_OLD) - ELSE(Qt4_FIND_REQUIRED) - IF(QT4_INSTALLED_VERSION_TOO_OLD AND NOT Qt4_FIND_QUIETLY) - MESSAGE(STATUS "The installed Qt version ${QTVERSION} is too old, at least version ${QT_MIN_VERSION} is required") - ENDIF(QT4_INSTALLED_VERSION_TOO_OLD AND NOT Qt4_FIND_QUIETLY) - ENDIF(Qt4_FIND_REQUIRED) - -ENDIF (QT4_QMAKE_FOUND) - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/MacroPushRequiredVars.cmake kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/MacroPushRequiredVars.cmake --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/MacroPushRequiredVars.cmake 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/MacroPushRequiredVars.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -# this module defines two macros: -# MACRO_PUSH_REQUIRED_VARS() -# and -# MACRO_POP_REQUIRED_VARS() -# use these if you call cmake macros which use -# any of the CMAKE_REQUIRED_XXX variables -# -# Usage: -# MACRO_PUSH_REQUIRED_VARS() -# SET(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -DSOME_MORE_DEF) -# CHECK_FUNCTION_EXISTS(...) -# MACRO_POP_REQUIRED_VARS() - -# Copyright (c) 2006, Alexander Neundorf, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -MACRO(MACRO_PUSH_REQUIRED_VARS) - - IF(NOT DEFINED _PUSH_REQUIRED_VARS_COUNTER) - SET(_PUSH_REQUIRED_VARS_COUNTER 0) - ENDIF(NOT DEFINED _PUSH_REQUIRED_VARS_COUNTER) - - MATH(EXPR _PUSH_REQUIRED_VARS_COUNTER "${_PUSH_REQUIRED_VARS_COUNTER}+1") - - SET(_CMAKE_REQUIRED_INCLUDES_SAVE_${_PUSH_REQUIRED_VARS_COUNTER} ${CMAKE_REQUIRED_INCLUDES}) - SET(_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_PUSH_REQUIRED_VARS_COUNTER} ${CMAKE_REQUIRED_DEFINITIONS}) - SET(_CMAKE_REQUIRED_LIBRARIES_SAVE_${_PUSH_REQUIRED_VARS_COUNTER} ${CMAKE_REQUIRED_LIBRARIES}) - SET(_CMAKE_REQUIRED_FLAGS_SAVE_${_PUSH_REQUIRED_VARS_COUNTER} ${CMAKE_REQUIRED_FLAGS}) -ENDMACRO(MACRO_PUSH_REQUIRED_VARS) - -MACRO(MACRO_POP_REQUIRED_VARS) - -# don't pop more than we pushed - IF("${_PUSH_REQUIRED_VARS_COUNTER}" GREATER "0") - - SET(CMAKE_REQUIRED_INCLUDES ${_CMAKE_REQUIRED_INCLUDES_SAVE_${_PUSH_REQUIRED_VARS_COUNTER}}) - SET(CMAKE_REQUIRED_DEFINITIONS ${_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_PUSH_REQUIRED_VARS_COUNTER}}) - SET(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_SAVE_${_PUSH_REQUIRED_VARS_COUNTER}}) - SET(CMAKE_REQUIRED_FLAGS ${_CMAKE_REQUIRED_FLAGS_SAVE_${_PUSH_REQUIRED_VARS_COUNTER}}) - - MATH(EXPR _PUSH_REQUIRED_VARS_COUNTER "${_PUSH_REQUIRED_VARS_COUNTER}-1") - ENDIF("${_PUSH_REQUIRED_VARS_COUNTER}" GREATER "0") - -ENDMACRO(MACRO_POP_REQUIRED_VARS) - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/Qt4ConfigDependentSettings.cmake kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/Qt4ConfigDependentSettings.cmake --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/Qt4ConfigDependentSettings.cmake 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/Qt4ConfigDependentSettings.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,384 +0,0 @@ -# This file is included by FindQt4.cmake, don't include it directly. - -#============================================================================= -# Copyright 2005-2009 Kitware, Inc. -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distributed this file outside of CMake, substitute the full -# License text for the above reference.) - - -############################################### -# -# configuration/system dependent settings -# -############################################### - -# this check for X11 and threads may not be necessary, since it is not -# contained in the cmake version of FindQt4.cmake: - -# for unix add X11 stuff -IF(UNIX) - # on OS X X11 may not be required - IF (Q_WS_X11) - FIND_PACKAGE(X11 REQUIRED) - ENDIF (Q_WS_X11) - FIND_PACKAGE(Threads) - SET(QT_QTCORE_LIBRARY ${QT_QTCORE_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -ENDIF(UNIX) - - -# find dependencies for some Qt modules -# when doing builds against a static Qt, they are required -# when doing builds against a shared Qt, they are not required -# if a user needs the dependencies, and they couldn't be found, they can set -# the variables themselves. - -SET(QT_QTGUI_LIB_DEPENDENCIES "") -SET(QT_QTCORE_LIB_DEPENDENCIES "") -SET(QT_QTNETWORK_LIB_DEPENDENCIES "") -SET(QT_QTOPENGL_LIB_DEPENDENCIES "") -SET(QT_QTDBUS_LIB_DEPENDENCIES "") -SET(QT_QTHELP_LIB_DEPENDENCIES ${QT_QTCLUCENE_LIBRARY}) - - -IF(WIN32) - # On Windows, qconfig.pri has "static" for static library builds - IF(QT_CONFIG MATCHES "static") - SET(QT_IS_STATIC 1) - ENDIF(QT_CONFIG MATCHES "static") -ELSE(WIN32) - # On other platforms, check file extension to know if its static - IF(QT_QTCORE_LIBRARY_RELEASE) - GET_FILENAME_COMPONENT(qtcore_lib_ext "${QT_QTCORE_LIBRARY_RELEASE}" EXT) - IF("${qtcore_lib_ext}" STREQUAL "${CMAKE_STATIC_LIBRARY_SUFFIX}") - SET(QT_IS_STATIC 1) - ENDIF("${qtcore_lib_ext}" STREQUAL "${CMAKE_STATIC_LIBRARY_SUFFIX}") - ENDIF(QT_QTCORE_LIBRARY_RELEASE) - IF(QT_QTCORE_LIBRARY_DEBUG) - GET_FILENAME_COMPONENT(qtcore_lib_ext "${QT_QTCORE_LIBRARY_DEBUG}" EXT) - IF(${qtcore_lib_ext} STREQUAL ${CMAKE_STATIC_LIBRARY_SUFFIX}) - SET(QT_IS_STATIC 1) - ENDIF(${qtcore_lib_ext} STREQUAL ${CMAKE_STATIC_LIBRARY_SUFFIX}) - ENDIF(QT_QTCORE_LIBRARY_DEBUG) -ENDIF(WIN32) - -# build using shared Qt needs -DQT_DLL on Windows -IF(WIN32 AND NOT QT_IS_STATIC) - SET(QT_DEFINITIONS ${QT_DEFINITIONS} -DQT_DLL) -ENDIF(WIN32 AND NOT QT_IS_STATIC) - - -# QtOpenGL dependencies -QT_QUERY_QMAKE(QMAKE_LIBS_OPENGL "QMAKE_LIBS_OPENGL") -IF(Q_WS_MAC) -# On the Mac OpenGL is probably frameworks and QMAKE_LIBS_OPENGL can be e.g. "-framework OpenGL -framework AGL". -# The separate_arguments() call in the other branch makes "-framework;-OpenGL;-framework;-lAGL" appear in the -# linker command. So we need to protect the "-framework foo" as non-separatable strings. -# We do this by replacing the space after "-framework" with an underscore, then calling separate_arguments(), -# and then we replace the underscores again with spaces. So we get proper linker commands. Alex - STRING(REGEX REPLACE "-framework +" "-framework_" QMAKE_LIBS_OPENGL "${QMAKE_LIBS_OPENGL}") - SEPARATE_ARGUMENTS(QMAKE_LIBS_OPENGL) - STRING(REGEX REPLACE "-framework_" "-framework " QMAKE_LIBS_OPENGL "${QMAKE_LIBS_OPENGL}") -ELSE(Q_WS_MAC) - SEPARATE_ARGUMENTS(QMAKE_LIBS_OPENGL) -ENDIF(Q_WS_MAC) -SET (QT_QTOPENGL_LIB_DEPENDENCIES ${QT_QTOPENGL_LIB_DEPENDENCIES} ${QMAKE_LIBS_OPENGL}) - - -## system png -IF(QT_QCONFIG MATCHES "system-png") - FIND_LIBRARY(QT_PNG_LIBRARY NAMES png) - MARK_AS_ADVANCED(QT_PNG_LIBRARY) - IF(QT_PNG_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_PNG_LIBRARY}) - ENDIF(QT_PNG_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "system-png") - - -# for X11, get X11 library directory -IF(Q_WS_X11) - QT_QUERY_QMAKE(QMAKE_LIBDIR_X11 "QMAKE_LIBDIR_X11") -ENDIF(Q_WS_X11) - - -## X11 SM -IF(QT_QCONFIG MATCHES "x11sm") - # ask qmake where the x11 libs are - FIND_LIBRARY(QT_X11_SM_LIBRARY NAMES SM PATHS ${QMAKE_LIBDIR_X11}) - FIND_LIBRARY(QT_X11_ICE_LIBRARY NAMES ICE PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(QT_X11_SM_LIBRARY) - MARK_AS_ADVANCED(QT_X11_ICE_LIBRARY) - IF(QT_X11_SM_LIBRARY AND QT_X11_ICE_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_X11_SM_LIBRARY} ${QT_X11_ICE_LIBRARY}) - ENDIF(QT_X11_SM_LIBRARY AND QT_X11_ICE_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "x11sm") - - -## Xi -IF(QT_QCONFIG MATCHES "tablet") - FIND_LIBRARY(QT_XI_LIBRARY NAMES Xi PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(QT_XI_LIBRARY) - IF(QT_XI_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_XI_LIBRARY}) - ENDIF(QT_XI_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "tablet") - - -## Xrender -IF(QT_QCONFIG MATCHES "xrender") - FIND_LIBRARY(QT_XRENDER_LIBRARY NAMES Xrender PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(QT_XRENDER_LIBRARY) - IF(QT_XRENDER_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_XRENDER_LIBRARY}) - ENDIF(QT_XRENDER_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "xrender") - - -## Xrandr -IF(QT_QCONFIG MATCHES "xrandr") - FIND_LIBRARY(QT_XRANDR_LIBRARY NAMES Xrandr PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(QT_XRANDR_LIBRARY) - IF(QT_XRANDR_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_XRANDR_LIBRARY}) - ENDIF(QT_XRANDR_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "xrandr") - - -## Xcursor -IF(QT_QCONFIG MATCHES "xcursor") - FIND_LIBRARY(QT_XCURSOR_LIBRARY NAMES Xcursor PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(QT_XCURSOR_LIBRARY) - IF(QT_XCURSOR_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_XCURSOR_LIBRARY}) - ENDIF(QT_XCURSOR_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "xcursor") - - -## Xinerama -IF(QT_QCONFIG MATCHES "xinerama") - FIND_LIBRARY(QT_XINERAMA_LIBRARY NAMES Xinerama PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(QT_XINERAMA_LIBRARY) - IF(QT_XINERAMA_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_XINERAMA_LIBRARY}) - ENDIF(QT_XINERAMA_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "xinerama") - - -## Xfixes -IF(QT_QCONFIG MATCHES "xfixes") - FIND_LIBRARY(QT_XFIXES_LIBRARY NAMES Xfixes PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(QT_XFIXES_LIBRARY) - IF(QT_XFIXES_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_XFIXES_LIBRARY}) - ENDIF(QT_XFIXES_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "xfixes") - - -## system-freetype -IF(QT_QCONFIG MATCHES "system-freetype") - FIND_LIBRARY(QT_FREETYPE_LIBRARY NAMES freetype) - MARK_AS_ADVANCED(QT_FREETYPE_LIBRARY) - IF(QT_FREETYPE_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_FREETYPE_LIBRARY}) - ENDIF(QT_FREETYPE_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "system-freetype") - - -## fontconfig -IF(QT_QCONFIG MATCHES "fontconfig") - FIND_LIBRARY(QT_FONTCONFIG_LIBRARY NAMES fontconfig) - MARK_AS_ADVANCED(QT_FONTCONFIG_LIBRARY) - IF(QT_FONTCONFIG_LIBRARY) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_FONTCONFIG_LIBRARY}) - ENDIF(QT_FONTCONFIG_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "fontconfig") - - -## system-zlib -IF(QT_QCONFIG MATCHES "system-zlib") - FIND_LIBRARY(QT_ZLIB_LIBRARY NAMES z) - MARK_AS_ADVANCED(QT_ZLIB_LIBRARY) - IF(QT_ZLIB_LIBRARY) - SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ${QT_ZLIB_LIBRARY}) - ENDIF(QT_ZLIB_LIBRARY) -ENDIF(QT_QCONFIG MATCHES "system-zlib") - - -## openssl -IF(NOT Q_WS_WIN) - SET(_QT_NEED_OPENSSL 0) - IF(QT_VERSION_MINOR LESS 4 AND QT_QCONFIG MATCHES "openssl") - SET(_QT_NEED_OPENSSL 1) - ENDIF(QT_VERSION_MINOR LESS 4 AND QT_QCONFIG MATCHES "openssl") - IF(QT_VERSION_MINOR GREATER 3 AND QT_QCONFIG MATCHES "openssl-linked") - SET(_QT_NEED_OPENSSL 1) - ENDIF(QT_VERSION_MINOR GREATER 3 AND QT_QCONFIG MATCHES "openssl-linked") - IF(_QT_NEED_OPENSSL) - FIND_PACKAGE(OpenSSL) - IF(OPENSSL_LIBRARIES) - SET(QT_QTNETWORK_LIB_DEPENDENCIES ${QT_QTNETWORK_LIB_DEPENDENCIES} ${OPENSSL_LIBRARIES}) - ENDIF(OPENSSL_LIBRARIES) - ENDIF(_QT_NEED_OPENSSL) -ENDIF(NOT Q_WS_WIN) - - -## dbus -IF(QT_QCONFIG MATCHES "dbus") - - # if the dbus library isn't found, we'll assume its not required to build - # shared Qt on Linux doesn't require it - IF(NOT QT_DBUS_LIBRARY) - EXECUTE_PROCESS(COMMAND pkg-config --libs-only-L dbus-1 - OUTPUT_VARIABLE _dbus_query_output - RESULT_VARIABLE _dbus_result - ERROR_VARIABLE _dbus_query_output ) - - IF(_dbus_result MATCHES 0) - STRING(REPLACE "-L" "" _dbus_query_output "${_dbus_query_output}") - SEPARATE_ARGUMENTS(_dbus_query_output) - ELSE(_dbus_result MATCHES 0) - SET(_dbus_query_output) - ENDIF(_dbus_result MATCHES 0) - - FIND_LIBRARY(QT_DBUS_LIBRARY NAMES dbus-1 PATHS ${_dbus_query_output} ) - - IF(QT_DBUS_LIBRARY) - SET(QT_QTDBUS_LIB_DEPENDENCIES ${QT_QTDBUS_LIB_DEPENDENCIES} ${QT_DBUS_LIBRARY}) - ENDIF(QT_DBUS_LIBRARY) - - MARK_AS_ADVANCED(QT_DBUS_LIBRARY) - ENDIF(NOT QT_DBUS_LIBRARY) - -ENDIF(QT_QCONFIG MATCHES "dbus") - - -## glib -IF(QT_QCONFIG MATCHES "glib") - - # if the glib libraries aren't found, we'll assume its not required to build - # shared Qt on Linux doesn't require it - - # Qt 4.2.0+ uses glib-2.0 - IF(NOT QT_GLIB_LIBRARY OR NOT QT_GTHREAD_LIBRARY) - EXECUTE_PROCESS(COMMAND pkg-config --libs-only-L glib-2.0 gthread-2.0 - OUTPUT_VARIABLE _glib_query_output - RESULT_VARIABLE _glib_result - ERROR_VARIABLE _glib_query_output ) - - IF(_glib_result MATCHES 0) - STRING(REPLACE "-L" "" _glib_query_output "${_glib_query_output}") - SEPARATE_ARGUMENTS(_glib_query_output) - ELSE(_glib_result MATCHES 0) - SET(_glib_query_output) - ENDIF(_glib_result MATCHES 0) - - FIND_LIBRARY(QT_GLIB_LIBRARY NAMES glib-2.0 PATHS ${_glib_query_output} ) - FIND_LIBRARY(QT_GTHREAD_LIBRARY NAMES gthread-2.0 PATHS ${_glib_query_output} ) - - MARK_AS_ADVANCED(QT_GLIB_LIBRARY) - MARK_AS_ADVANCED(QT_GTHREAD_LIBRARY) - ENDIF(NOT QT_GLIB_LIBRARY OR NOT QT_GTHREAD_LIBRARY) - - IF(QT_GLIB_LIBRARY AND QT_GTHREAD_LIBRARY) - SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} - ${QT_GTHREAD_LIBRARY} ${QT_GLIB_LIBRARY}) - ENDIF(QT_GLIB_LIBRARY AND QT_GTHREAD_LIBRARY) - - - # Qt 4.5+ also links to gobject-2.0 - IF(QT_VERSION_MINOR GREATER 4) - IF(NOT QT_GOBJECT_LIBRARY) - EXECUTE_PROCESS(COMMAND pkg-config --libs-only-L gobject-2.0 - OUTPUT_VARIABLE _glib_query_output - RESULT_VARIABLE _glib_result - ERROR_VARIABLE _glib_query_output ) - - IF(_glib_result MATCHES 0) - STRING(REPLACE "-L" "" _glib_query_output "${_glib_query_output}") - SEPARATE_ARGUMENTS(_glib_query_output) - ELSE(_glib_result MATCHES 0) - SET(_glib_query_output) - ENDIF(_glib_result MATCHES 0) - - FIND_LIBRARY(QT_GOBJECT_LIBRARY NAMES gobject-2.0 PATHS ${_glib_query_output} ) - - MARK_AS_ADVANCED(QT_GOBJECT_LIBRARY) - ENDIF(NOT QT_GOBJECT_LIBRARY) - - IF(QT_GOBJECT_LIBRARY) - SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} - ${QT_GOBJECT_LIBRARY}) - ENDIF(QT_GOBJECT_LIBRARY) - ENDIF(QT_VERSION_MINOR GREATER 4) - -ENDIF(QT_QCONFIG MATCHES "glib") - - -## clock-monotonic, just see if we need to link with rt -IF(QT_QCONFIG MATCHES "clock-monotonic") - SET(CMAKE_REQUIRED_LIBRARIES_SAVE ${CMAKE_REQUIRED_LIBRARIES}) - SET(CMAKE_REQUIRED_LIBRARIES rt) - CHECK_SYMBOL_EXISTS(_POSIX_TIMERS "unistd.h;time.h" QT_POSIX_TIMERS) - SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_SAVE}) - IF(QT_POSIX_TIMERS) - FIND_LIBRARY(QT_RT_LIBRARY NAMES rt) - MARK_AS_ADVANCED(QT_RT_LIBRARY) - IF(QT_RT_LIBRARY) - SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ${QT_RT_LIBRARY}) - ENDIF(QT_RT_LIBRARY) - ENDIF(QT_POSIX_TIMERS) -ENDIF(QT_QCONFIG MATCHES "clock-monotonic") - - -IF(Q_WS_X11) - # X11 libraries Qt absolutely depends on - QT_QUERY_QMAKE(QT_LIBS_X11 "QMAKE_LIBS_X11") - SEPARATE_ARGUMENTS(QT_LIBS_X11) - FOREACH(QT_X11_LIB ${QT_LIBS_X11}) - STRING(REGEX REPLACE "-l" "" QT_X11_LIB "${QT_X11_LIB}") - SET(QT_TMP_STR "QT_X11_${QT_X11_LIB}_LIBRARY") - FIND_LIBRARY(${QT_TMP_STR} NAMES "${QT_X11_LIB}" PATHS ${QMAKE_LIBDIR_X11}) - MARK_AS_ADVANCED(${QT_TMP_STR}) - IF(${QT_TMP_STR}) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${${QT_TMP_STR}}) - ENDIF(${QT_TMP_STR}) - ENDFOREACH(QT_X11_LIB) - - QT_QUERY_QMAKE(QT_LIBS_THREAD "QMAKE_LIBS_THREAD") - SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ${QT_LIBS_THREAD}) - - QT_QUERY_QMAKE(QMAKE_LIBS_DYNLOAD "QMAKE_LIBS_DYNLOAD") - SET (QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ${QMAKE_LIBS_DYNLOAD}) - -ENDIF(Q_WS_X11) - - -IF(Q_WS_WIN) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} imm32 winmm) - SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ws2_32) -ENDIF(Q_WS_WIN) - - -IF(Q_WS_MAC) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} "-framework Carbon") - - # Qt 4.0, 4.1, 4.2 use QuickTime - IF(QT_VERSION_MINOR LESS 3) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} "-framework QuickTime") - ENDIF(QT_VERSION_MINOR LESS 3) - - # Qt 4.2+ use AppKit - IF(QT_VERSION_MINOR GREATER 1) - SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} "-framework AppKit") - ENDIF(QT_VERSION_MINOR GREATER 1) - - SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} "-framework ApplicationServices") -ENDIF(Q_WS_MAC) - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/Qt4Macros.cmake kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/Qt4Macros.cmake --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/Qt4Macros.cmake 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/cmake/Qt4Macros.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,414 +0,0 @@ -# This file is included by FindQt4.cmake, don't include it directly. - -#============================================================================= -# Copyright 2005-2009 Kitware, Inc. -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distributed this file outside of CMake, substitute the full -# License text for the above reference.) - - -###################################### -# -# Macros for building Qt files -# -###################################### - - -MACRO (QT4_EXTRACT_OPTIONS _qt4_files _qt4_options) - SET(${_qt4_files}) - SET(${_qt4_options}) - SET(_QT4_DOING_OPTIONS FALSE) - FOREACH(_currentArg ${ARGN}) - IF ("${_currentArg}" STREQUAL "OPTIONS") - SET(_QT4_DOING_OPTIONS TRUE) - ELSE ("${_currentArg}" STREQUAL "OPTIONS") - IF(_QT4_DOING_OPTIONS) - LIST(APPEND ${_qt4_options} "${_currentArg}") - ELSE(_QT4_DOING_OPTIONS) - LIST(APPEND ${_qt4_files} "${_currentArg}") - ENDIF(_QT4_DOING_OPTIONS) - ENDIF ("${_currentArg}" STREQUAL "OPTIONS") - ENDFOREACH(_currentArg) -ENDMACRO (QT4_EXTRACT_OPTIONS) - - -# macro used to create the names of output files preserving relative dirs -MACRO (QT4_MAKE_OUTPUT_FILE infile prefix ext outfile ) - STRING(LENGTH ${CMAKE_CURRENT_BINARY_DIR} _binlength) - STRING(LENGTH ${infile} _infileLength) - SET(_checkinfile ${CMAKE_CURRENT_SOURCE_DIR}) - IF(_infileLength GREATER _binlength) - STRING(SUBSTRING "${infile}" 0 ${_binlength} _checkinfile) - IF(_checkinfile STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") - FILE(RELATIVE_PATH rel ${CMAKE_CURRENT_BINARY_DIR} ${infile}) - ELSE(_checkinfile STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") - FILE(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${infile}) - ENDIF(_checkinfile STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") - ELSE(_infileLength GREATER _binlength) - FILE(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${infile}) - ENDIF(_infileLength GREATER _binlength) - IF(WIN32 AND rel MATCHES "^[a-zA-Z]:") # absolute path - STRING(REGEX REPLACE "^([a-zA-Z]):(.*)$" "\\1_\\2" rel "${rel}") - ENDIF(WIN32 AND rel MATCHES "^[a-zA-Z]:") - SET(_outfile "${CMAKE_CURRENT_BINARY_DIR}/${rel}") - STRING(REPLACE ".." "__" _outfile ${_outfile}) - GET_FILENAME_COMPONENT(outpath ${_outfile} PATH) - GET_FILENAME_COMPONENT(_outfile ${_outfile} NAME_WE) - FILE(MAKE_DIRECTORY ${outpath}) - SET(${outfile} ${outpath}/${prefix}${_outfile}.${ext}) -ENDMACRO (QT4_MAKE_OUTPUT_FILE ) - - -MACRO (QT4_GET_MOC_FLAGS _moc_flags) - SET(${_moc_flags}) - GET_DIRECTORY_PROPERTY(_inc_DIRS INCLUDE_DIRECTORIES) - - FOREACH(_current ${_inc_DIRS}) - IF("${_current}" MATCHES ".framework/?$") - STRING(REGEX REPLACE "/[^/]+.framework" "" framework_path "${_current}") - SET(${_moc_flags} ${${_moc_flags}} "-F${framework_path}") - ELSE("${_current}" MATCHES ".framework/?$") - SET(${_moc_flags} ${${_moc_flags}} "-I${_current}") - ENDIF("${_current}" MATCHES ".framework/?$") - ENDFOREACH(_current ${_inc_DIRS}) - - GET_DIRECTORY_PROPERTY(_defines COMPILE_DEFINITIONS) - FOREACH(_current ${_defines}) - SET(${_moc_flags} ${${_moc_flags}} "-D${_current}") - ENDFOREACH(_current ${_defines}) - - IF(Q_WS_WIN) - SET(${_moc_flags} ${${_moc_flags}} -DWIN32) - ENDIF(Q_WS_WIN) - -ENDMACRO(QT4_GET_MOC_FLAGS) - - -# helper macro to set up a moc rule -MACRO (QT4_CREATE_MOC_COMMAND infile outfile moc_flags moc_options) - # For Windows, create a parameters file to work around command line length limit - IF (WIN32) - # Pass the parameters in a file. Set the working directory to - # be that containing the parameters file and reference it by - # just the file name. This is necessary because the moc tool on - # MinGW builds does not seem to handle spaces in the path to the - # file given with the @ syntax. - GET_FILENAME_COMPONENT(_moc_outfile_name "${outfile}" NAME) - GET_FILENAME_COMPONENT(_moc_outfile_dir "${outfile}" PATH) - IF(_moc_outfile_dir) - SET(_moc_working_dir WORKING_DIRECTORY ${_moc_outfile_dir}) - ENDIF(_moc_outfile_dir) - SET (_moc_parameters_file ${outfile}_parameters) - SET (_moc_parameters ${moc_flags} ${moc_options} -o "${outfile}" "${infile}") - FILE (REMOVE ${_moc_parameters_file}) - FOREACH(arg ${_moc_parameters}) - FILE (APPEND ${_moc_parameters_file} "${arg}\n") - ENDFOREACH(arg) - ADD_CUSTOM_COMMAND(OUTPUT ${outfile} - COMMAND ${QT_MOC_EXECUTABLE} @${_moc_outfile_name}_parameters - DEPENDS ${infile} - ${_moc_working_dir} - VERBATIM) - ELSE (WIN32) - ADD_CUSTOM_COMMAND(OUTPUT ${outfile} - COMMAND ${QT_MOC_EXECUTABLE} - ARGS ${moc_flags} ${moc_options} -o ${outfile} ${infile} - DEPENDS ${infile}) - ENDIF (WIN32) -ENDMACRO (QT4_CREATE_MOC_COMMAND) - - -MACRO (QT4_GENERATE_MOC infile outfile ) -# get include dirs and flags - QT4_GET_MOC_FLAGS(moc_flags) - GET_FILENAME_COMPONENT(abs_infile ${infile} ABSOLUTE) - QT4_CREATE_MOC_COMMAND(${abs_infile} ${outfile} "${moc_flags}" "") - SET_SOURCE_FILES_PROPERTIES(${outfile} PROPERTIES SKIP_AUTOMOC TRUE) # do not run automoc on this file - - MACRO_ADD_FILE_DEPENDENCIES(${abs_infile} ${outfile}) -ENDMACRO (QT4_GENERATE_MOC) - - -# QT4_WRAP_CPP(outfiles inputfile ... ) - -MACRO (QT4_WRAP_CPP outfiles ) - # get include dirs - QT4_GET_MOC_FLAGS(moc_flags) - QT4_EXTRACT_OPTIONS(moc_files moc_options ${ARGN}) - - FOREACH (it ${moc_files}) - GET_FILENAME_COMPONENT(it ${it} ABSOLUTE) - QT4_MAKE_OUTPUT_FILE(${it} moc_ cxx outfile) - QT4_CREATE_MOC_COMMAND(${it} ${outfile} "${moc_flags}" "${moc_options}") - SET(${outfiles} ${${outfiles}} ${outfile}) - ENDFOREACH(it) - -ENDMACRO (QT4_WRAP_CPP) - - -# QT4_WRAP_UI(outfiles inputfile ... ) - -MACRO (QT4_WRAP_UI outfiles ) - QT4_EXTRACT_OPTIONS(ui_files ui_options ${ARGN}) - - FOREACH (it ${ui_files}) - GET_FILENAME_COMPONENT(outfile ${it} NAME_WE) - GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE) - SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.h) - ADD_CUSTOM_COMMAND(OUTPUT ${outfile} - COMMAND ${QT_UIC_EXECUTABLE} - ARGS ${ui_options} -o ${outfile} ${infile} - MAIN_DEPENDENCY ${infile}) - SET(${outfiles} ${${outfiles}} ${outfile}) - ENDFOREACH (it) - -ENDMACRO (QT4_WRAP_UI) - - -# QT4_ADD_RESOURCES(outfiles inputfile ... ) - -MACRO (QT4_ADD_RESOURCES outfiles ) - QT4_EXTRACT_OPTIONS(rcc_files rcc_options ${ARGN}) - - FOREACH (it ${rcc_files}) - GET_FILENAME_COMPONENT(outfilename ${it} NAME_WE) - GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE) - GET_FILENAME_COMPONENT(rc_path ${infile} PATH) - SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${outfilename}.cxx) - # parse file for dependencies - # all files are absolute paths or relative to the location of the qrc file - FILE(READ "${infile}" _RC_FILE_CONTENTS) - STRING(REGEX MATCHALL "]*>" "" _RC_FILE "${_RC_FILE}") - STRING(REGEX MATCH "^/|([A-Za-z]:/)" _ABS_PATH_INDICATOR "${_RC_FILE}") - IF(NOT _ABS_PATH_INDICATOR) - SET(_RC_FILE "${rc_path}/${_RC_FILE}") - ENDIF(NOT _ABS_PATH_INDICATOR) - SET(_RC_DEPENDS ${_RC_DEPENDS} "${_RC_FILE}") - ENDFOREACH(_RC_FILE) - ADD_CUSTOM_COMMAND(OUTPUT ${outfile} - COMMAND ${QT_RCC_EXECUTABLE} - ARGS ${rcc_options} -name ${outfilename} -o ${outfile} ${infile} - MAIN_DEPENDENCY ${infile} - DEPENDS ${_RC_DEPENDS}) - SET(${outfiles} ${${outfiles}} ${outfile}) - ENDFOREACH (it) - -ENDMACRO (QT4_ADD_RESOURCES) - - -MACRO(QT4_ADD_DBUS_INTERFACE _sources _interface _basename) - GET_FILENAME_COMPONENT(_infile ${_interface} ABSOLUTE) - SET(_header ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.h) - SET(_impl ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.cpp) - SET(_moc ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.moc) - - GET_SOURCE_FILE_PROPERTY(_nonamespace ${_interface} NO_NAMESPACE) - IF ( _nonamespace ) - SET(_params -N -m) - ELSE ( _nonamespace ) - SET(_params -m) - ENDIF ( _nonamespace ) - - GET_SOURCE_FILE_PROPERTY(_classname ${_interface} CLASSNAME) - IF ( _classname ) - SET(_params ${_params} -c ${_classname}) - ENDIF ( _classname ) - - GET_SOURCE_FILE_PROPERTY(_include ${_interface} INCLUDE) - IF ( _include ) - SET(_params ${_params} -i ${_include}) - ENDIF ( _include ) - - ADD_CUSTOM_COMMAND(OUTPUT ${_impl} ${_header} - COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} ${_params} -p ${_basename} ${_infile} - DEPENDS ${_infile}) - - SET_SOURCE_FILES_PROPERTIES(${_impl} PROPERTIES SKIP_AUTOMOC TRUE) - - QT4_GENERATE_MOC(${_header} ${_moc}) - - SET(${_sources} ${${_sources}} ${_impl} ${_header} ${_moc}) - MACRO_ADD_FILE_DEPENDENCIES(${_impl} ${_moc}) - -ENDMACRO(QT4_ADD_DBUS_INTERFACE) - - -MACRO(QT4_ADD_DBUS_INTERFACES _sources) - FOREACH (_current_FILE ${ARGN}) - GET_FILENAME_COMPONENT(_infile ${_current_FILE} ABSOLUTE) - # get the part before the ".xml" suffix - STRING(REGEX REPLACE "(.*[/\\.])?([^\\.]+)\\.xml" "\\2" _basename ${_current_FILE}) - STRING(TOLOWER ${_basename} _basename) - QT4_ADD_DBUS_INTERFACE(${_sources} ${_infile} ${_basename}interface) - ENDFOREACH (_current_FILE) -ENDMACRO(QT4_ADD_DBUS_INTERFACES) - - -MACRO(QT4_GENERATE_DBUS_INTERFACE _header) # _customName OPTIONS -some -options ) - QT4_EXTRACT_OPTIONS(_customName _qt4_dbus_options ${ARGN}) - - GET_FILENAME_COMPONENT(_in_file ${_header} ABSOLUTE) - GET_FILENAME_COMPONENT(_basename ${_header} NAME_WE) - - IF (_customName) - SET(_target ${CMAKE_CURRENT_BINARY_DIR}/${_customName}) - ELSE (_customName) - SET(_target ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.xml) - ENDIF (_customName) - - ADD_CUSTOM_COMMAND(OUTPUT ${_target} - COMMAND ${QT_DBUSCPP2XML_EXECUTABLE} ${_qt4_dbus_options} ${_in_file} -o ${_target} - DEPENDS ${_in_file} - ) -ENDMACRO(QT4_GENERATE_DBUS_INTERFACE) - - -MACRO(QT4_ADD_DBUS_ADAPTOR _sources _xml_file _include _parentClass) # _optionalBasename _optionalClassName) - GET_FILENAME_COMPONENT(_infile ${_xml_file} ABSOLUTE) - - SET(_optionalBasename "${ARGV4}") - IF (_optionalBasename) - SET(_basename ${_optionalBasename} ) - ELSE (_optionalBasename) - STRING(REGEX REPLACE "(.*[/\\.])?([^\\.]+)\\.xml" "\\2adaptor" _basename ${_infile}) - STRING(TOLOWER ${_basename} _basename) - ENDIF (_optionalBasename) - - SET(_optionalClassName "${ARGV5}") - SET(_header ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.h) - SET(_impl ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.cpp) - SET(_moc ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.moc) - - IF(_optionalClassName) - ADD_CUSTOM_COMMAND(OUTPUT ${_impl} ${_header} - COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} -m -a ${_basename} -c ${_optionalClassName} -i ${_include} -l ${_parentClass} ${_infile} - DEPENDS ${_infile} - ) - ELSE(_optionalClassName) - ADD_CUSTOM_COMMAND(OUTPUT ${_impl} ${_header} - COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} -m -a ${_basename} -i ${_include} -l ${_parentClass} ${_infile} - DEPENDS ${_infile} - ) - ENDIF(_optionalClassName) - - QT4_GENERATE_MOC(${_header} ${_moc}) - SET_SOURCE_FILES_PROPERTIES(${_impl} PROPERTIES SKIP_AUTOMOC TRUE) - MACRO_ADD_FILE_DEPENDENCIES(${_impl} ${_moc}) - - SET(${_sources} ${${_sources}} ${_impl} ${_header} ${_moc}) -ENDMACRO(QT4_ADD_DBUS_ADAPTOR) - - -MACRO(QT4_AUTOMOC) - QT4_GET_MOC_FLAGS(_moc_INCS) - - SET(_matching_FILES ) - FOREACH (_current_FILE ${ARGN}) - - GET_FILENAME_COMPONENT(_abs_FILE ${_current_FILE} ABSOLUTE) - # if "SKIP_AUTOMOC" is set to true, we will not handle this file here. - # This is required to make uic work correctly: - # we need to add generated .cpp files to the sources (to compile them), - # but we cannot let automoc handle them, as the .cpp files don't exist yet when - # cmake is run for the very first time on them -> however the .cpp files might - # exist at a later run. at that time we need to skip them, so that we don't add two - # different rules for the same moc file - GET_SOURCE_FILE_PROPERTY(_skip ${_abs_FILE} SKIP_AUTOMOC) - - IF ( NOT _skip AND EXISTS ${_abs_FILE} ) - - FILE(READ ${_abs_FILE} _contents) - - GET_FILENAME_COMPONENT(_abs_PATH ${_abs_FILE} PATH) - - STRING(REGEX MATCHALL "# *include +[^ ]+\\.moc[\">]" _match "${_contents}") - IF(_match) - FOREACH (_current_MOC_INC ${_match}) - STRING(REGEX MATCH "[^ <\"]+\\.moc" _current_MOC "${_current_MOC_INC}") - - GET_FILENAME_COMPONENT(_basename ${_current_MOC} NAME_WE) - IF(EXISTS ${_abs_PATH}/${_basename}.hpp) - SET(_header ${_abs_PATH}/${_basename}.hpp) - ELSE(EXISTS ${_abs_PATH}/${_basename}.hpp) - SET(_header ${_abs_PATH}/${_basename}.h) - ENDIF(EXISTS ${_abs_PATH}/${_basename}.hpp) - SET(_moc ${CMAKE_CURRENT_BINARY_DIR}/${_current_MOC}) - QT4_CREATE_MOC_COMMAND(${_header} ${_moc} "${_moc_INCS}" "") - MACRO_ADD_FILE_DEPENDENCIES(${_abs_FILE} ${_moc}) - ENDFOREACH (_current_MOC_INC) - ENDIF(_match) - ENDIF ( NOT _skip AND EXISTS ${_abs_FILE} ) - ENDFOREACH (_current_FILE) -ENDMACRO(QT4_AUTOMOC) - - -MACRO(QT4_CREATE_TRANSLATION _qm_files) - QT4_EXTRACT_OPTIONS(_lupdate_files _lupdate_options ${ARGN}) - SET(_my_sources) - SET(_my_dirs) - SET(_my_tsfiles) - SET(_ts_pro) - FOREACH (_file ${_lupdate_files}) - GET_FILENAME_COMPONENT(_ext ${_file} EXT) - GET_FILENAME_COMPONENT(_abs_FILE ${_file} ABSOLUTE) - IF(_ext MATCHES "ts") - LIST(APPEND _my_tsfiles ${_abs_FILE}) - ELSE(_ext MATCHES "ts") - IF(NOT _ext) - LIST(APPEND _my_dirs ${_abs_FILE}) - ELSE(NOT _ext) - LIST(APPEND _my_sources ${_abs_FILE}) - ENDIF(NOT _ext) - ENDIF(_ext MATCHES "ts") - ENDFOREACH(_file) - FOREACH(_ts_file ${_my_tsfiles}) - IF(_my_sources) - # make a .pro file to call lupdate on, so we don't make our commands too - # long for some systems - GET_FILENAME_COMPONENT(_ts_name ${_ts_file} NAME_WE) - SET(_ts_pro ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_ts_name}_lupdate.pro) - SET(_pro_srcs) - FOREACH(_pro_src ${_my_sources}) - SET(_pro_srcs "${_pro_srcs} \"${_pro_src}\"") - ENDFOREACH(_pro_src ${_my_sources}) - FILE(WRITE ${_ts_pro} "SOURCES = ${_pro_srcs}") - ENDIF(_my_sources) - ADD_CUSTOM_COMMAND(OUTPUT ${_ts_file} - COMMAND ${QT_LUPDATE_EXECUTABLE} - ARGS ${_lupdate_options} ${_ts_pro} ${_my_dirs} -ts ${_ts_file} - DEPENDS ${_my_sources} ${_ts_pro}) - ENDFOREACH(_ts_file) - QT4_ADD_TRANSLATION(${_qm_files} ${_my_tsfiles}) -ENDMACRO(QT4_CREATE_TRANSLATION) - - -MACRO(QT4_ADD_TRANSLATION _qm_files) - FOREACH (_current_FILE ${ARGN}) - GET_FILENAME_COMPONENT(_abs_FILE ${_current_FILE} ABSOLUTE) - GET_FILENAME_COMPONENT(qm ${_abs_FILE} NAME_WE) - GET_SOURCE_FILE_PROPERTY(output_location ${_abs_FILE} OUTPUT_LOCATION) - IF(output_location) - FILE(MAKE_DIRECTORY "${output_location}") - SET(qm "${output_location}/${qm}.qm") - ELSE(output_location) - SET(qm "${CMAKE_CURRENT_BINARY_DIR}/${qm}.qm") - ENDIF(output_location) - - ADD_CUSTOM_COMMAND(OUTPUT ${qm} - COMMAND ${QT_LRELEASE_EXECUTABLE} - ARGS ${_abs_FILE} -qm ${qm} - DEPENDS ${_abs_FILE} - ) - SET(${_qm_files} ${${_qm_files}} ${qm}) - ENDFOREACH (_current_FILE) -ENDMACRO(QT4_ADD_TRANSLATION) diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/CMakeLists.txt kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/CMakeLists.txt --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -project(qmlbreadcrumbnavigation) - -cmake_minimum_required(VERSION 2.6) - -set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) - -# Not depending on KDE here for easier portability. -find_package(Qt4 REQUIRED) - -include_directories( - ${QT_INCLUDES} - ${QT_QTGUI_INCLUDE_DIR} - ${QT_QTSQL_INCLUDE_DIR} - ${QT_QTDECLARATIVE_INCLUDE_DIR} - ${PROJECT_BINARY_DIR} -) - -set(app_SRCS - mainwindow.cpp - main.cpp -) - -set(app_qml_SRCS - mainview.qml -) - -foreach( qml_src ${app_qml_SRCS}) - execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/${qml_src}" "${CMAKE_BINARY_DIR}/${qml_src}") -endforeach() - -qt4_automoc( app_MOC_SRCS ${app_SRCS} ) - -add_executable(qml_nav - ${app_SRCS} -) - -target_link_libraries( - qml_nav - ${QT_QTCORE_LIBRARIES} - ${QT_QTGUI_LIBRARIES} - ${QT_QTDECLARATIVE_LIBRARIES} -) diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/main.cpp kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/main.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/main.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ - -#include - -#include "mainwindow.h" - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - - MainWindow mw; - mw.resize(640, 480); - mw.show(); - - return app.exec(); - -} - - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainview.qml kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainview.qml --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainview.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainview.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Rectangle { - color : "#f6f6f5" - anchors.fill : parent - property int itemHeight : 30 - - ListView { - height : itemHeight - anchors.centerIn : parent - model : myModel - width : 200 - clip : true - delegate : Component { - Text{ - height : itemHeight; - text : model.display - } - } - onCountChanged : { - console.log("%%" + count) - positionViewAtIndex(count - 1, ListView.Beginning) - } - Component.onCompleted : { - console.log("Completed"); - console.log("COUNT" + count) - positionViewAtIndex(count - 1, ListView.Beginning) - } - } -} diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainwindow.cpp kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainwindow.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainwindow.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainwindow.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,90 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 "mainwindow.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags f ) - : QWidget(parent, f) -{ - QHBoxLayout *layout = new QHBoxLayout(this); - QSplitter *splitter = new QSplitter; - layout->addWidget(splitter); - - QTreeView *treeView = new QTreeView(splitter); - - m_model = new QStandardItemModel(this); - treeView->setModel(m_model); - - appendRow(); - appendRow(); - - m_declarativeView = new QDeclarativeView(splitter); - - QDeclarativeContext *context = m_declarativeView->engine()->rootContext(); - - context->setContextProperty( "myModel", QVariant::fromValue( static_cast( m_model ) ) ); - - m_declarativeView->setResizeMode( QDeclarativeView::SizeRootObjectToView ); - m_declarativeView->setSource( QUrl( "./mainview.qml" ) ); - - splitter->setSizes(QList() << 1 << 1); - -// QTimer::singleShot(4000, this, SLOT(removeBottomRow())); - QTimer::singleShot(8000, this, SLOT(prependNewRow())); - -} - -static int sCount = 1; - -void MainWindow::appendRow() -{ - QStandardItem *item = new QStandardItem(QString::fromLatin1("Item %1").arg(sCount++)); - m_model->appendRow(item); -} - -void MainWindow::prependNewRow() -{ - QStandardItem *item = new QStandardItem(QString::fromLatin1("Item %1").arg(sCount++)); - m_model->insertRow(0, item); -} - -void MainWindow::removeTopRow() -{ - m_model->removeRow(0); -} - -void MainWindow::removeBottomRow() -{ - m_model->removeRow(1); -} - - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainwindow.h kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainwindow.h --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainwindow.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/simple/mainwindow.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 MAINWINDOW_H -#define MAINWINDOW_H - -#include -#include - -class QDeclarativeView; -class QTreeView; -class QStandardItemModel; - -class KBreadcrumbNavigationFactory; - -class MainWindow : public QWidget -{ - Q_OBJECT -public: - MainWindow(QWidget* parent = 0, Qt::WindowFlags f = 0); - -public slots: - void appendRow(); - void removeTopRow(); - void removeBottomRow(); - void prependNewRow(); - -private: - QTreeView *m_treeView; - QDeclarativeView *m_declarativeView; - QStandardItemModel *m_model; -}; - -#endif - Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/slideout-panel-background.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/slideout-panel-background.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/slideout-panel-handle.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/slideout-panel-handle.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/transparentplus.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/transparentplus.png differ diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/transparentplus.svg kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/transparentplus.svg --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/transparentplus.svg 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/transparentplus.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ - - - - - - - - - - - image/svg+xml - - - - - - - - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/tree_example kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/tree_example --- kdepim-runtime-4.14.6/qml/kde/tests/qmlbreadcrumbnavigation/tree_example 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qmlbreadcrumbnavigation/tree_example 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -- 1 -- - 1 -- - 1 -- 1 -- - 1 -- - 1 -- - - 1 -- - - - 1 -- - - 1 -- - - - 1 -- - - - 1 -- - - - - 1 -- - - - - 1 -- - - - - 1 -- - - - 1 -- - - 1 -- - - 1 -- - - - 1 -- - - - 1 - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/CMakeLists.txt kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/CMakeLists.txt --- kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -project(qml_moves) - -cmake_minimum_required(VERSION 2.6) - -set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) - -# Not depending on KDE here for easier portability. -find_package(Qt4 REQUIRED) - -include_directories( - ${QT_INCLUDES} - ${QT_QTGUI_INCLUDE_DIR} - ${QT_QTDECLARATIVE_INCLUDE_DIR} - ${PROJECT_BINARY_DIR} -) - -set(app_SRCS - dynamictreemodel.cpp - mainwindow.cpp - main.cpp -) - -set(app_qml_SRCS - mainview.qml -) - -foreach( qml_src ${app_qml_SRCS}) - execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/${qml_src}" "${CMAKE_BINARY_DIR}/${qml_src}") -endforeach() - -qt4_automoc( app_MOC_SRCS ${app_SRCS} ) - -add_executable(qml_moves - ${app_SRCS} -) - -target_link_libraries( - qml_moves - ${QT_QTCORE_LIBRARIES} - ${QT_QTGUI_LIBRARIES} - ${QT_QTDECLARATIVE_LIBRARIES} -) diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/dynamictreemodel.cpp kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/dynamictreemodel.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/dynamictreemodel.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/dynamictreemodel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1009 +0,0 @@ -/* - Copyright (c) 2009 Stephen Kelly - - 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 "dynamictreemodel.h" - -#include -#include -#include -#include - -#include - -#include - -// If DUMPTREE is defined, ModelInsertCommand dumps the tree of what it is inserting. -// #define DUMPTREE -#ifdef DUMPTREE -#include -#endif - -DynamicTreeModel::DynamicTreeModel(QObject *parent) - : QAbstractItemModel(parent), - nextId(1) -{ -} - -QModelIndex DynamicTreeModel::index(int row, int column, const QModelIndex &parent) const -{ -// if (column != 0) -// return QModelIndex(); - - if ( column < 0 || row < 0 ) - return QModelIndex(); - - QList > childIdColumns = m_childItems.value(parent.internalId()); - - const qint64 grandParent = findParentId(parent.internalId()); - if (grandParent >= 0) { - QList > parentTable = m_childItems.value(grandParent); - Q_ASSERT(parent.column() < parentTable.size()); - QList parentSiblings = parentTable.at(parent.column()); - Q_ASSERT(parent.row() < parentSiblings.size()); - } - - if (childIdColumns.size() == 0) - return QModelIndex(); - - if (column >= childIdColumns.size()) - return QModelIndex(); - - QList rowIds = childIdColumns.at(column); - - if ( row >= rowIds.size()) - return QModelIndex(); - - qint64 id = rowIds.at(row); - - return createIndex(row, column, reinterpret_cast(id)); - -} - -qint64 DynamicTreeModel::findParentId(qint64 searchId) const -{ - if (searchId <= 0) - return -1; - - QHashIterator > > i(m_childItems); - while (i.hasNext()) - { - i.next(); - QListIterator > j(i.value()); - while (j.hasNext()) - { - QList l = j.next(); - if (l.contains(searchId)) - { - return i.key(); - } - } - } - return -1; -} - -QModelIndex DynamicTreeModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - return QModelIndex(); - - qint64 searchId = index.internalId(); - qint64 parentId = findParentId(searchId); - // Will never happen for valid index, but what the hey... - if (parentId <= 0) - return QModelIndex(); - - qint64 grandParentId = findParentId(parentId); - if (grandParentId < 0) - grandParentId = 0; - - int column = 0; - QList childList = m_childItems.value(grandParentId).at(column); - - int row = childList.indexOf(parentId); - - return createIndex(row, column, reinterpret_cast(parentId)); - -} - -int DynamicTreeModel::rowCount(const QModelIndex &index ) const -{ - QList > cols = m_childItems.value(index.internalId()); - - if (cols.size() == 0 ) - return 0; - - if (index.column() > 0) - return 0; - - return cols.at(0).size(); -} - -int DynamicTreeModel::columnCount(const QModelIndex &index ) const -{ -// Q_UNUSED(index); - return m_childItems.value(index.internalId()).size(); -} - -QVariant DynamicTreeModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if ( DynamicTreeModelId == role ) - return index.internalId(); - - if (Qt::DisplayRole == role || Qt::EditRole == role) - { - return m_items.value(index.internalId()); - } - return QVariant(); -} - - -bool DynamicTreeModel::setData(const QModelIndex& index, const QVariant& value, int role) -{ - if (role == Qt::EditRole) - { - m_items[index.internalId()] = value.toString(); - dataChanged(index, index); - return true; - } - - return QAbstractItemModel::setData(index, value, role); -} - -void DynamicTreeModel::clear() -{ - beginResetModel(); - m_items.clear(); - m_childItems.clear(); - nextId = 1; - endResetModel(); -} - - -bool DynamicTreeModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int _column, const QModelIndex& parent) -{ - Q_UNUSED(action); - Q_UNUSED(_column); - QByteArray encoded = data->data(mimeTypes().first()); - - QHash > movedItems; - bool ok; - qint64 id; - int _row; - static const int column = 0; - QHash > >::const_iterator it; - foreach(const QByteArray &ba, encoded.split('\0')) - { - id = ba.toInt(&ok); - if (!ok) - qDebug() << ba; - Q_ASSERT(ok); - - _row = -1; - for (it = m_childItems.constBegin(); it != m_childItems.constEnd(); ++it) - { - _row = it.value().first().indexOf(id); - if (_row < 0) - continue; - movedItems[createIndex(_row, column, reinterpret_cast(id)).parent()].append(_row); - break; - } - Q_ASSERT(_row >= 0); - if (_row < 0) - return false; - } - - const int destRow = row < 0 ? 0 : row; - const QList destPath = indexToPath(parent); - - QList srcPath; - QModelIndex srcParent; - QHash >::iterator src_parent_it = movedItems.begin(); - int startRow = 0; - int endRow = 0; - int nextMovedRow = 0; - - QList rowsMoved; - QList::iterator src_row_it; - QList::iterator rows_moved_end; - QList moveCommands; - - for ( ; src_parent_it != movedItems.end(); ++src_parent_it) - { - srcParent = src_parent_it.key(); - srcPath = indexToPath(srcParent); - - rowsMoved = src_parent_it.value(); - qSort(rowsMoved); - src_row_it = rowsMoved.begin(); - rows_moved_end = rowsMoved.end(); - startRow = *src_row_it; - endRow = startRow; - ++src_row_it; - - if (src_row_it == rows_moved_end) - { - moveCommands.prepend(getMoveCommand(srcPath, startRow, endRow)); - continue; - } - - for ( ; src_row_it != rows_moved_end; ++src_row_it) - { - nextMovedRow = *src_row_it; - - if (nextMovedRow == endRow + 1) - { - ++endRow; - } else { - Q_ASSERT(nextMovedRow > endRow + 1); - moveCommands.prepend(getMoveCommand(srcPath, startRow, endRow)); - startRow = nextMovedRow; - endRow = nextMovedRow; - - if ((src_row_it + 1) == rows_moved_end) - moveCommands.prepend(getMoveCommand(srcPath, startRow, endRow)); - - } - } - } - - QPersistentModelIndex destParent = parent; - QPersistentModelIndex destRowIndex = index(destRow, column, parent); - - ModelMoveCommand *firstCommand = moveCommands.takeFirst(); - firstCommand->setDestAncestors(indexToPath(parent)); - firstCommand->setDestRow(destRow); - firstCommand->doCommand(); - - if (!destRowIndex.isValid()) - destRowIndex = index(destRow, column, parent); - - int offset = firstCommand->endRow() - firstCommand->startRow() + 1; - foreach(ModelMoveCommand *moveCommand, moveCommands) - { - moveCommand->setDestAncestors(indexToPath(destParent)); - moveCommand->setDestRow(destRowIndex.row() + offset); - moveCommand->doCommand(); - offset = moveCommand->endRow() - moveCommand->startRow() + 1; - } - - return false; -} - -ModelMoveCommand* DynamicTreeModel::getMoveCommand(const QList &srcPath, int startRow, int endRow) -{ - ModelMoveCommand *moveCommand = new ModelMoveCommand(this, this); - moveCommand->setAncestorRowNumbers(srcPath); - moveCommand->setStartRow(startRow); - moveCommand->setEndRow(endRow); - return moveCommand; -} - -Qt::ItemFlags DynamicTreeModel::flags(const QModelIndex& index) const -{ - Qt::ItemFlags flags = QAbstractItemModel::flags(index); - if (index.isValid()) - return flags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable; - return flags; -} - -Qt::DropActions DynamicTreeModel::supportedDropActions() const -{ - return Qt::MoveAction; -} - -QStringList DynamicTreeModel::mimeTypes() const -{ - QStringList types; - types << QLatin1String("application/x-dynamictreemodel-itemlist"); - return types; -} - -QMimeData* DynamicTreeModel::mimeData(const QModelIndexList& indexes) const -{ - QMimeData *data = new QMimeData(); - QByteArray itemData; - QModelIndexList::const_iterator it = indexes.begin(); - const QModelIndexList::const_iterator end = indexes.end(); - while(it != end) - { - itemData.append(QByteArray::number(it->internalId())); - ++it; - if (it != end) - itemData.append('\0'); - } - data->setData(mimeTypes().first(), itemData); - return data; -} - -QList DynamicTreeModel::indexToPath(const QModelIndex &_idx) const -{ - QList list; - QModelIndex idx = _idx; - while (idx.isValid()) - { - list.prepend(idx.row()); - idx = idx.parent(); - } - return list; -} - -QModelIndexList DynamicTreeModel::match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const -{ - if (role != DynamicTreeModelId) - return QAbstractItemModel::match(start, role, value, hits, flags); - - qint64 id = value.toLongLong(); - - QHash > >::const_iterator it = m_childItems.constBegin(); - const QHash > >::const_iterator end = m_childItems.constEnd(); - - QList > items; - QList >::const_iterator itemIt; - QList >::const_iterator itemEnd; - int foundIndexRow; - for ( ; it != end; ++it) - { - items = it.value(); - itemEnd = items.constEnd(); - for (itemIt = items.constBegin(); itemIt != itemEnd; ++itemIt) - { - foundIndexRow = itemIt->indexOf(id); - if (foundIndexRow != -1) - { - static const int column = 0; - return QModelIndexList() << createIndex(foundIndexRow, column, reinterpret_cast(id)); - } - } - } - return QModelIndexList(); -} - -ModelChangeCommand::ModelChangeCommand( DynamicTreeModel *model, QObject *parent ) - : QObject(parent), m_model(model), m_startRow(-1), m_endRow(-1), m_numCols(1) -{ - -} - -QModelIndex ModelChangeCommand::findIndex(const QList &rows) const -{ - const int col = 0; - QModelIndex parent = QModelIndex(); - QListIterator i(rows); - while (i.hasNext()) - { - parent = m_model->index(i.next(), col, parent); - Q_ASSERT(parent.isValid()); - } - return parent; -} - -ModelInsertCommand::ModelInsertCommand(DynamicTreeModel *model, QObject *parent ) - : ModelChangeCommand(model, parent) -{ - -} - -QList ModelInsertCommand::tokenize(const QString& treeString) const -{ - QStringList parts = treeString.split("-"); - - QList tokens; - - const QStringList::const_iterator begin = parts.constBegin(); - const QStringList::const_iterator end = parts.constEnd(); - - QStringList::const_iterator it = begin; - ++it; - for (; it != end; ++it) - { - Token token; - if (it->trimmed().isEmpty()) - { - token.type = Token::Branch; - } else { - token.type = Token::Leaf; - token.content = *it; - } - tokens.append(token); - } - return tokens; -} - -void ModelInsertCommand::interpret(const QString& treeString) -{ - m_treeString = treeString; - - QList depths = getDepths(m_treeString); - - int size = 0; - qCount(depths, 0, size); - Q_ASSERT(size != 0); - - m_endRow = m_startRow + size - 1; -} - -QList ModelInsertCommand::getDepths(const QString& treeString) const -{ - int depth = 0; - QList depths; - -#ifdef DUMPTREE - int id = 1; -#endif - - QList tokens = tokenize(treeString); - while(!tokens.isEmpty()) - { - Token token = tokens.takeFirst(); - - if (token.type == Token::Branch) - { - ++depth; - continue; - } - Q_ASSERT(token.type == Token::Leaf); - - depths.append(depth); -#ifdef DUMPTREE - std::cout << "\""; - for (int i = 0; i <= depth; ++i) - std::cout << " -"; - std::cout << " " << id++ << "\"" << std::endl; -#endif - depth = 0; - } - - return depths; -} - -void ModelInsertCommand::doCommand() -{ - QModelIndex parent = findIndex(m_rowNumbers); - - if (!m_treeString.isEmpty()) - { - QList depths = getDepths(m_treeString); - - int size = 0; - qCount(depths, 0, size); - Q_ASSERT(size != 0); - m_endRow = m_startRow + size - 1; - } - m_model->beginInsertRows(parent, m_startRow, m_endRow); - if (!m_treeString.isEmpty()) - { - doInsertTree(parent); - } else { - qint64 parentId = parent.internalId(); - - for (int row = m_startRow; row <= m_endRow; row++) - { - for(int col = 0; col < m_numCols; col++ ) - { - if (m_model->m_childItems[parentId].size() <= col) - { - m_model->m_childItems[parentId].append(QList()); - } - qint64 id = m_model->newId(); - QString name = QString::number(id); - - m_model->m_items.insert(id, name); - m_model->m_childItems[parentId][col].insert(row, id); - - } - } - } - m_model->endInsertRows(); -} - -void ModelInsertCommand::doInsertTree(const QModelIndex &fragmentParent) -{ - QList depths = getDepths(m_treeString); - - qint64 fragmentParentIdentifier = fragmentParent.internalId(); - - QList::const_iterator it = depths.constBegin(); - const QList::const_iterator end = depths.constEnd(); - - QList recentParents; - recentParents.append(fragmentParentIdentifier); - - qint64 lastId = 0; - qint64 id; - QString name; - int depth = 0; - int row = m_startRow; - Q_ASSERT(*it == depth); - - QList rows; - rows.append(row); - - for( ; it != end; ++it) - { - if (*it > depth) - { - Q_ASSERT(*it == depth + 1); - fragmentParentIdentifier = lastId; - if (recentParents.size() == *it) - recentParents.append(fragmentParentIdentifier); - else - recentParents[*it] = fragmentParentIdentifier; - - ++depth; - - } else if ( *it < depth ) - { - fragmentParentIdentifier = recentParents.at(*it); - depth = (*it); - } - - if (rows.size() == depth) - rows.append(0); - - id = m_model->newId(); - lastId = id; - for (int column = 0; column < m_numCols; ++column) { - if (m_model->m_childItems[fragmentParentIdentifier].size() <= column) - { - m_model->m_childItems[fragmentParentIdentifier].append(QList()); - } - m_model->m_items.insert(id, QString::number(id)); - m_model->m_childItems[fragmentParentIdentifier][column].insert(rows[depth], id); - if (column != m_numCols - 1) - id = m_model->newId(); - } - rows[depth]++; - } -} - - -ModelInsertAndRemoveQueuedCommand::ModelInsertAndRemoveQueuedCommand(DynamicTreeModel* model, QObject* parent) - : ModelChangeCommand(model, parent) -{ - qRegisterMetaType("QModelIndex"); -} - -void ModelInsertAndRemoveQueuedCommand::queuedBeginInsertRows(const QModelIndex& parent, int start, int end) -{ - m_model->beginInsertRows(parent, start, end); -} - -void ModelInsertAndRemoveQueuedCommand::queuedEndInsertRows() -{ - m_model->endInsertRows(); -} - -void ModelInsertAndRemoveQueuedCommand::queuedBeginRemoveRows(const QModelIndex& parent, int start, int end) -{ - m_model->beginRemoveRows(parent, start, end); -} - -void ModelInsertAndRemoveQueuedCommand::queuedEndRemoveRows() -{ - m_model->endRemoveRows(); -} - -void ModelInsertAndRemoveQueuedCommand::purgeItem(qint64 parent) -{ - QList > childItemRows = m_model->m_childItems.value(parent); - - if (childItemRows.size() > 0) - { - for (int col = 0; col < m_numCols; col++) - { - QList childItems = childItemRows[col]; - foreach(qint64 item, childItems) - { - purgeItem(item); - m_model->m_childItems[parent][col].removeOne(item); - } - } - } - m_model->m_items.remove(parent); -} - -void ModelInsertAndRemoveQueuedCommand::doCommand() -{ - QModelIndex parent = findIndex(m_rowNumbers); - - connect (this, SIGNAL(beginInsertRows(QModelIndex,int,int)), SLOT(queuedBeginInsertRows(QModelIndex,int,int)), Qt::QueuedConnection); - connect (this, SIGNAL(endInsertRows()), SLOT(queuedEndInsertRows()), Qt::QueuedConnection); - connect (this, SIGNAL(beginRemoveRows(QModelIndex,int,int)), SLOT(queuedBeginRemoveRows(QModelIndex,int,int)), Qt::QueuedConnection); - connect (this, SIGNAL(endRemoveRows()), SLOT(queuedEndRemoveRows()), Qt::QueuedConnection); - - emit beginInsertRows(parent, m_startRow, m_endRow); -// m_model->beginInsertRows(parent, m_startRow, m_endRow); - qint64 parentId = parent.internalId(); - for (int row = m_startRow; row <= m_endRow; row++) - { - for(int col = 0; col < m_numCols; col++ ) - { - if (m_model->m_childItems[parentId].size() <= col) - { - m_model->m_childItems[parentId].append(QList()); - } - qint64 id = m_model->newId(); - QString name = QString::number(id); - - m_model->m_items.insert(id, name); - m_model->m_childItems[parentId][col].insert(row, id); - - } - } - - emit endInsertRows(); -// m_model->endInsertRows(); - - emit beginRemoveRows(parent, m_startRow, m_endRow); -// m_model->beginRemoveRows(parent, m_startRow, m_endRow); - for(int col = 0; col < m_numCols; col++ ) - { - QList childItems = m_model->m_childItems.value(parentId).value(col); - for (int row = m_startRow; row <= m_endRow; row++) - { - qint64 item = childItems[row]; - purgeItem(item); - m_model->m_childItems[parentId][col].removeOne(item); - } - } - emit endRemoveRows(); -// m_model->endRemoveRows(); - -} - -ModelRemoveCommand::ModelRemoveCommand(DynamicTreeModel *model, QObject *parent ) - : ModelChangeCommand(model, parent) -{ - -} - -void ModelRemoveCommand::doCommand() -{ - QModelIndex parent = findIndex(m_rowNumbers); - m_model->beginRemoveRows(parent, m_startRow, m_endRow); - qint64 parentId = parent.internalId(); - for(int col = 0; col < m_numCols; col++ ) - { - QList childItems = m_model->m_childItems.value(parentId).value(col); - for (int row = m_startRow; row <= m_endRow; row++) - { - qint64 item = childItems[row]; - purgeItem(item); - m_model->m_childItems[parentId][col].removeOne(item); - } - } - m_model->endRemoveRows(); -} - -void ModelRemoveCommand::purgeItem(qint64 parent) -{ - QList > childItemRows = m_model->m_childItems.value(parent); - - if (childItemRows.size() > 0) - { - for (int col = 0; col < m_numCols; col++) - { - QList childItems = childItemRows[col]; - foreach(qint64 item, childItems) - { - purgeItem(item); - m_model->m_childItems[parent][col].removeOne(item); - } - } - } - m_model->m_items.remove(parent); -} - - -ModelDataChangeCommand::ModelDataChangeCommand(DynamicTreeModel *model, QObject *parent) - : ModelChangeCommand(model, parent), m_startColumn(0) -{ - -} - -void ModelDataChangeCommand::doCommand() -{ - QModelIndex parent = findIndex(m_rowNumbers); - QModelIndex topLeft = m_model->index(m_startRow, m_startColumn, parent); - QModelIndex bottomRight = m_model->index(m_endRow, m_numCols - 1, parent); - - QList > childItems = m_model->m_childItems[parent.internalId()]; - - - for (int col = m_startColumn; col < m_startColumn + m_numCols; col++) - { - for (int row = m_startRow; row <= m_endRow; row++ ) - { - QString name = QString::number( m_model->newId() ); - m_model->m_items[childItems[col][row]] = name; - } - } - m_model->dataChanged(topLeft, bottomRight); -} - - -ModelMoveCommand::ModelMoveCommand(DynamicTreeModel *model, QObject *parent) -: ModelChangeCommand(model, parent) -{ - -} - -bool ModelMoveCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow) -{ - return m_model->beginMoveRows(srcParent, srcStart, srcEnd, destParent, destRow); -} - -void ModelMoveCommand::doCommand() -{ - QModelIndex srcParent = findIndex(m_rowNumbers); - QModelIndex destParent = findIndex(m_destRowNumbers); - - if (!emitPreSignal(srcParent, m_startRow, m_endRow, destParent, m_destRow)) - { - return; - } - - for (int column = 0; column < m_numCols; ++column) - { - QList l = m_model->m_childItems.value(srcParent.internalId())[column].mid(m_startRow, m_endRow - m_startRow + 1 ); - - for (int i = m_startRow; i <= m_endRow ; i++) - { - m_model->m_childItems[srcParent.internalId()][column].removeAt(m_startRow); - } - int d; - if (m_destRow < m_startRow) - d = m_destRow; - else - { - if (srcParent == destParent) - d = m_destRow - (m_endRow - m_startRow + 1); - else - d = m_destRow - (m_endRow - m_startRow); - } - - foreach(const qint64 id, l) - { - - if (!m_model->m_childItems.contains(destParent.internalId())) - { - m_model->m_childItems[destParent.internalId()].append(QList()); - } - - m_model->m_childItems[destParent.internalId()][column].insert(d++, id); - } - } - - emitPostSignal(); -} - -void ModelMoveCommand::emitPostSignal() -{ - m_model->endMoveRows(); -} - - -ModelMoveLayoutChangeCommand::ModelMoveLayoutChangeCommand(DynamicTreeModel* model, QObject* parent): ModelMoveCommand(model, parent) -{ - -} - -ModelMoveLayoutChangeCommand::~ModelMoveLayoutChangeCommand() -{ - -} - -bool ModelMoveLayoutChangeCommand::emitPreSignal(const QModelIndex& srcParent, int srcStart, int srcEnd, const QModelIndex& destParent, int destRow) -{ - m_model->layoutAboutToBeChanged(); - - const int column = 0; - - for (int row = srcStart; row <= srcEnd; ++row) - { - m_beforeMoveList << m_model->index(row, column, srcParent); - } - - if (srcParent != destParent) - { - for (int row = srcEnd + 1; row < m_model->rowCount(srcParent); ++row) - { - m_beforeMoveList << m_model->index(row, column, srcParent); - } - for (int row = destRow; row < m_model->rowCount(destParent); ++row) - { - m_beforeMoveList << m_model->index(row, column, destParent); - } - } else { - if (destRow < srcStart) - { - for (int row = destRow; row < srcStart; ++row) - { - m_beforeMoveList << m_model->index(row, column, srcParent); - } - } else { - for (int row = srcStart + (srcEnd - srcStart + 1); row < destRow; ++row) - { - m_beforeMoveList << m_model->index(row, column, srcParent); - } - } - } - // We assume that the move was legal here. - return true; -} - -void ModelMoveLayoutChangeCommand::emitPostSignal() -{ - int srcStart = m_startRow; - int srcEnd = m_endRow; - int destRow = m_destRow; - - // Moving indexes may affect the m_rowNumbers and m_destRowNumbers. - // Instead of adjusting them programmatically, the test writer must specify them if they change. - - const QList sourceRowNumbers = m_endOfMoveSourceAncestors.isEmpty() ? m_rowNumbers : m_endOfMoveSourceAncestors; - QModelIndex srcParent = findIndex(sourceRowNumbers); - - const QList destRowNumbers = m_endOfMoveDestAncestors.isEmpty() ? m_destRowNumbers : m_endOfMoveDestAncestors; - QModelIndex destParent = findIndex(destRowNumbers); - - const int column = 0; - - QModelIndexList afterMoveList; - - if (srcParent != destParent) - { - for (int row = destRow; row <= (destRow + (srcEnd - srcStart)); ++row) - { - afterMoveList << m_model->index(row, column, destParent); - } - for (int row = srcStart; row < m_model->rowCount(srcParent); ++row) - { - afterMoveList << m_model->index(row, column, srcParent); - } - for (int row = destRow + (srcEnd - srcStart + 1); row < m_model->rowCount(destParent); ++row) - { - afterMoveList << m_model->index(row, column, destParent); - } - } else { - if (destRow < srcStart) - { - for (int row = srcStart; row <= srcEnd; ++row) - { - afterMoveList << m_model->index(destRow + (srcStart - row), column, destParent); - } - } else { - for (int row = srcStart; row <= srcEnd; ++row) - { - afterMoveList << m_model->index(destRow + (srcStart - row - 1), column, destParent); - } - } - if (destRow < srcStart) - { - for (int row = destRow + 1; row <= srcStart; ++row) - { - afterMoveList << m_model->index(row, column, srcParent); - } - } else { - for (int row = srcStart + (srcEnd - srcStart + 1); row < (srcStart + (destRow - srcEnd)); ++row) - { - afterMoveList << m_model->index(row - (srcEnd - srcStart + 1), column, srcParent); - } - } - } - - m_model->changePersistentIndexList(m_beforeMoveList, afterMoveList); - m_beforeMoveList.clear(); - m_model->layoutChanged(); - - -} - -ModelResetCommand::ModelResetCommand(DynamicTreeModel* model, QObject* parent) - : ModelChangeCommand(model, parent) -{ - -} - -ModelResetCommand::~ModelResetCommand() -{ - -} - -void ModelResetCommand::setInitialTree(const QString& treeString) -{ - m_treeString = treeString; -} - -void ModelResetCommand::doCommand() -{ - m_model->beginResetModel(); - bool blocked = m_model->blockSignals(true); - m_model->clear(); - if (!m_treeString.isEmpty()) - { - ModelInsertCommand *ins = new ModelInsertCommand(m_model); - ins->setStartRow(0); - ins->interpret(m_treeString); - ins->doCommand(); - } - m_model->blockSignals(blocked); - m_model->endResetModel(); -} - -ModelLayoutChangeCommand::ModelLayoutChangeCommand(DynamicTreeModel* model, QObject* parent) - : ModelChangeCommand(model, parent) -{ - -} - -ModelLayoutChangeCommand::~ModelLayoutChangeCommand() -{ - -} - -void ModelLayoutChangeCommand::setInitialTree(const QString& treeString) -{ - m_treeString = treeString; -} - -void ModelLayoutChangeCommand::setPersistentChanges(const QList< ModelLayoutChangeCommand::PersistentChange >& changes) -{ - m_changes = changes; -} - -void ModelLayoutChangeCommand::doCommand() -{ - m_model->layoutAboutToBeChanged(); - QModelIndexList oldList; - - foreach(const PersistentChange &change, m_changes) - { - const IndexFinder oldFinder(m_model, change.oldPath); - oldList << oldFinder.getIndex(); - } - - bool blocked = m_model->blockSignals(true); - m_model->clear(); - if (!m_treeString.isEmpty()) - { - ModelInsertCommand *ins = new ModelInsertCommand(m_model); - ins->setStartRow(0); - ins->interpret(m_treeString); - ins->doCommand(); - } - - QModelIndexList newList; - foreach(const PersistentChange &change, m_changes) - { - const IndexFinder newFinder(m_model, change.newPath); - newList << newFinder.getIndex(); - } - m_model->changePersistentIndexList(oldList, newList); - - m_model->blockSignals(blocked); - m_model->layoutChanged(); -} - - - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/dynamictreemodel.h kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/dynamictreemodel.h --- kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/dynamictreemodel.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/dynamictreemodel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,358 +0,0 @@ -/* - Copyright (c) 2009 Stephen Kelly - - 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 DYNAMICTREEMODEL_H -#define DYNAMICTREEMODEL_H - -#include - -#include -#include - -#include - -#include "indexfinder.h" - -template class QList; - -class ModelMoveCommand; - -class DynamicTreeModel : public QAbstractItemModel -{ - Q_OBJECT -public: - enum Roles - { - DynamicTreeModelId = Qt::UserRole, - - LastRole - }; - - explicit DynamicTreeModel(QObject *parent = 0); - - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex &index) const; - int rowCount(const QModelIndex &index = QModelIndex()) const; - int columnCount(const QModelIndex &index = QModelIndex()) const; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); - - bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent); - Qt::ItemFlags flags(const QModelIndex& index) const; - Qt::DropActions supportedDropActions() const; - QStringList mimeTypes() const; - QMimeData* mimeData(const QModelIndexList& indexes) const; - QModelIndexList match(const QModelIndex& start, int role, const QVariant& value, int hits = 1, - Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith | Qt::MatchWrap)) const; - - void clear(); - QList indexToPath(const QModelIndex &idx) const; - ModelMoveCommand* getMoveCommand(const QList &srcPath, int startRow, int endRow); - -protected slots: - - /** - Finds the parent id of the string with id @p searchId. - - Returns -1 if not found. - */ - qint64 findParentId(qint64 searchId) const; - -private: - QHash m_items; - QHash > > m_childItems; - qint64 nextId; - qint64 newId() { return nextId++; }; - - QModelIndex m_nextParentIndex; - int m_nextRow; - - int m_depth; - int maxDepth; - - friend class ModelInsertCommand; - friend class ModelInsertWithDescendantsCommand; - friend class ModelRemoveCommand; - friend class ModelDataChangeCommand; - friend class ModelMoveCommand; - friend class ModelMoveLayoutChangeCommand; - friend class ModelResetCommand; - friend class ModelLayoutChangeCommand; -// friend class ModelSortIndexCommand; - friend class ModelSortIndexLayoutChangeCommand; - friend class ModelInsertAndRemoveQueuedCommand; - -}; - - -class ModelChangeCommand : public QObject -{ - Q_OBJECT -public: - - ModelChangeCommand( DynamicTreeModel *model, QObject *parent = 0 ); - - virtual ~ModelChangeCommand() {} - - void setAncestorRowNumbers(const QList &rowNumbers) { m_rowNumbers = rowNumbers; } - QList srcAncestors() const { return m_rowNumbers; } - - QModelIndex findIndex(const QList &rows) const; - - void setStartRow(int row) { m_startRow = row; } - - void setEndRow(int row) { m_endRow = row; } - - void setNumCols(int cols) { m_numCols = cols; } - - virtual void doCommand() = 0; - - QModelIndex parentIndex() const { return findIndex(m_rowNumbers); } - int startRow() const { return m_startRow; } - int endRow() const { return m_endRow; } - -protected: - DynamicTreeModel* m_model; - QList m_rowNumbers; - int m_startRow; - int m_endRow; - int m_numCols; - -}; - -typedef QList ModelChangeCommandList; - -/** - @brief Inserts a sub tree into the dynamictreemodel. - - As an alternative to setStartRow and setEndRow, the interpret command may be used. - - The interpret command is used to set the structure of the subtree. - - For example, - @code - cmd = new ModelInsertCommand(m_model, this); - cmd->interpret( - "- A" - "- B" - "- - C" - "- D" - ); - @endcode - - Will emit an insert for 3 rows, the second of which will have a child row. The interpretation - string may be complex as long as it is valid. The text at the end of each row does not need to be consistent. - There is a define DUMPTREE to make this command print the tree it inserts for better readability. - - @code - cmd->interpret( - "- A" - "- - B" - "- - C" - "- - - C" - "- - C" - "- - - C" - "- - - C" - "- - C" - "- D" - "- - E" - "- - F" - ); - @endcode - - The string is valid if (depth of row (N + 1)) <= ( (depth of row N) + 1). For example, the following is invalid - because the depth of B is 2 and the depth of A is 0. - - @code - cmd->interpret( - "- A" - "- - - B" - "- - C" - @endcode -*/ -class ModelInsertCommand : public ModelChangeCommand -{ - Q_OBJECT - - struct Token - { - enum Type { Branch, Leaf }; - Type type; - QString content; - }; - -public: - - explicit ModelInsertCommand(DynamicTreeModel *model, QObject *parent = 0 ); - virtual ~ModelInsertCommand() {} - - void interpret(const QString &treeString); - - virtual void doCommand(); - void doInsertTree(const QModelIndex &parent); - -protected: - QList tokenize(const QString &treeString) const; - - QList getDepths(const QString &treeString) const; - - QString m_treeString; -}; - -class ModelInsertAndRemoveQueuedCommand : public ModelChangeCommand -{ - Q_OBJECT - -public: - - explicit ModelInsertAndRemoveQueuedCommand(DynamicTreeModel *model, QObject *parent = 0 ); - virtual ~ModelInsertAndRemoveQueuedCommand() {} - - virtual void doCommand(); - -signals: - void beginInsertRows(const QModelIndex &parent, int start, int end); - void endInsertRows(); - void beginRemoveRows(const QModelIndex &parent, int start, int end); - void endRemoveRows(); - -protected slots: - void queuedBeginInsertRows(const QModelIndex &parent, int start, int end); - void queuedEndInsertRows(); - void queuedBeginRemoveRows(const QModelIndex &parent, int start, int end); - void queuedEndRemoveRows(); - -protected: - void purgeItem(qint64 parent); -}; - -class ModelRemoveCommand : public ModelChangeCommand -{ - Q_OBJECT -public: - explicit ModelRemoveCommand(DynamicTreeModel *model, QObject *parent = 0 ); - virtual ~ModelRemoveCommand() {} - - virtual void doCommand(); - - void purgeItem(qint64 parent); -}; - -class ModelDataChangeCommand : public ModelChangeCommand -{ - Q_OBJECT -public: - explicit ModelDataChangeCommand(DynamicTreeModel *model, QObject *parent = 0); - - virtual ~ModelDataChangeCommand() {} - - virtual void doCommand(); - - void setStartColumn(int column) { m_startColumn = column; } - -protected: - int m_startColumn; -}; - -class ModelMoveCommand : public ModelChangeCommand -{ - Q_OBJECT -public: - explicit ModelMoveCommand(DynamicTreeModel *model, QObject *parent); - - virtual ~ModelMoveCommand() {} - - virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); - - virtual void doCommand(); - - virtual void emitPostSignal(); - - void setDestAncestors( const QList &rows ) { m_destRowNumbers = rows; } - QList destAncestors() const { return m_destRowNumbers; } - - void setDestRow(int row) { m_destRow = row; } - -protected: - QList m_destRowNumbers; - int m_destRow; -}; - -class ModelMoveLayoutChangeCommand : public ModelMoveCommand -{ - Q_OBJECT -public: - explicit ModelMoveLayoutChangeCommand(DynamicTreeModel* model, QObject* parent); - virtual ~ModelMoveLayoutChangeCommand(); - - virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); - - virtual void emitPostSignal(); - - void setEndOfMoveSourceAncestors(const QList &rows ) { m_endOfMoveSourceAncestors = rows; } - void setEndOfMoveDestAncestors(const QList &rows ) { m_endOfMoveDestAncestors = rows; } - -private: - QModelIndexList m_beforeMoveList; - QList m_endOfMoveSourceAncestors; - QList m_endOfMoveDestAncestors; - -}; - -class ModelResetCommand : public ModelChangeCommand -{ - Q_OBJECT -public: - ModelResetCommand(DynamicTreeModel* model, QObject* parent = 0); - virtual ~ModelResetCommand(); - - void setInitialTree(const QString &treeString); - - /* reimp */ void doCommand(); -private: - QString m_treeString; -}; - - -class ModelLayoutChangeCommand : public ModelChangeCommand -{ - Q_OBJECT -public: - ModelLayoutChangeCommand(DynamicTreeModel* model, QObject* parent = 0); - virtual ~ModelLayoutChangeCommand(); - - struct PersistentChange - { - QList oldPath; - QList newPath; - }; - - void setPersistentChanges(const QList &changes); - - void setInitialTree(const QString &treeString); - - /* reimp */ void doCommand(); -private: - QString m_treeString; - QList m_changes; -}; - - -#endif diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/indexfinder.h kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/indexfinder.h --- kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/indexfinder.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/indexfinder.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,84 +0,0 @@ -/* -Copyright (c) 2009 Stephen Kelly - -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 INDEXFINDER_H -#define INDEXFINDER_H - -#include - -class IndexFinder -{ - public: - IndexFinder(QList rows = QList()) : m_rows(rows), m_model(0) {} - - IndexFinder(const QAbstractItemModel *model, QList rows = QList() ) - : m_rows(rows), m_model(model) - { - Q_ASSERT(model); - } - - QModelIndex getIndex() const - { - if(!m_model) - return QModelIndex(); - static const int col = 0; - QModelIndex parent = QModelIndex(); - QListIterator i(m_rows); - while (i.hasNext()) - { - parent = m_model->index(i.next(), col, parent); - Q_ASSERT(parent.isValid()); - } - return parent; - } - - static IndexFinder indexToIndexFinder(const QModelIndex &_idx) - { - if (!_idx.isValid()) - return IndexFinder(); - - QList list; - QModelIndex idx = _idx; - while (idx.isValid()) - { - list.prepend(idx.row()); - idx = idx.parent(); - } - return IndexFinder(_idx.model(), list); - } - - bool operator==( const IndexFinder &other ) const - { - return (m_rows == other.m_rows && m_model == other.m_model ); - } - - QList rows() const { return m_rows; } - void appendRow(int row) { m_rows.append(row); } - void setRows( const QList &rows ) { m_rows = rows; } - void setModel(QAbstractItemModel *model) { m_model = model; } - - private: - QList m_rows; - const QAbstractItemModel * m_model; -}; - - -Q_DECLARE_METATYPE( IndexFinder ) - -#endif diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/main.cpp kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/main.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/main.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ - -#include - -#include "mainwindow.h" - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - - MainWindow mw; - mw.resize(640, 480); - mw.show(); - - return app.exec(); - -} - - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/mainview.qml kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/mainview.qml --- kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/mainview.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/mainview.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Rectangle { - color : "#f6f6f5" - anchors.fill : parent - width : 200 - - ListView { - anchors.fill : parent - width : 100 - model : _model - delegate: Text - { - height : 67 - text : model.display - } - - highlight : Rectangle { - opacity : .25 - width : parent.width - color : "blue" - } - } -} diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/mainwindow.cpp kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/mainwindow.cpp --- kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/mainwindow.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/mainwindow.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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 "mainwindow.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dynamictreemodel.h" - -MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags f ) - : QWidget(parent, f) -{ - QHBoxLayout *layout = new QHBoxLayout(this); - QSplitter *splitter = new QSplitter; - layout->addWidget(splitter); - - m_treeModel = new DynamicTreeModel(this); - ModelInsertCommand *insert = new ModelInsertCommand(m_treeModel, this); - insert->setStartRow(0); - insert->interpret( - "- 1" - "- 1" - "- 1" - "- 1" - "- 1" - ); - insert->doCommand(); - - QTreeView *view = new QTreeView(splitter); - view->setModel(m_treeModel); - - m_declarativeView = new QDeclarativeView(splitter); - - QDeclarativeContext *context = m_declarativeView->engine()->rootContext(); - - context->setContextProperty( "_model", m_treeModel ); - - context->setContextProperty( "application", QVariant::fromValue( static_cast( this ) ) ); - - m_declarativeView->setResizeMode( QDeclarativeView::SizeRootObjectToView ); - m_declarativeView->setSource( QUrl( "./mainview.qml" ) ); - - splitter->setSizes(QList() << 1 << 1); - QTimer::singleShot(2000, this, SLOT(doMove())); - -} - -void MainWindow::doMove() -{ - qDebug() << "MOV"; - ModelMoveCommand *command = new ModelMoveCommand(m_treeModel, this); - command->setStartRow(0); - command->setEndRow(0); - command->setDestRow(2); - command->doCommand(); -} - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/mainwindow.h kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/mainwindow.h --- kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/mainwindow.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/mainwindow.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ - -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include -#include - -class QDeclarativeView; -class QTreeView; - -#include "dynamictreemodel.h" - -Q_DECLARE_METATYPE(QModelIndex) - -class KBreadcrumbNavigationFactory; - -class MainWindow : public QWidget -{ - Q_OBJECT -public: - MainWindow(QWidget* parent = 0, Qt::WindowFlags f = 0); - -public slots: - void doMove(); - -private: - QTreeView *m_treeView; - DynamicTreeModel *m_treeModel; - QDeclarativeView *m_declarativeView; - KBreadcrumbNavigationFactory *m_bnf; -}; - -#endif - diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/qml_moves.pro kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/qml_moves.pro --- kdepim-runtime-4.14.6/qml/kde/tests/qml_moves/qml_moves.pro 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qml_moves/qml_moves.pro 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -###################################################################### -# Automatically generated by qmake (2.01a) Fri Dec 3 13:51:12 2010 -###################################################################### - -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += . - -QT += declarative - -# Input -HEADERS += dynamictreemodel.h indexfinder.h mainwindow.h -SOURCES += dynamictreemodel.cpp main.cpp mainwindow.cpp diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/qobject_sender.qml kdepim-runtime-15.08.0/qml/kde/tests/qobject_sender.qml --- kdepim-runtime-4.14.6/qml/kde/tests/qobject_sender.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/qobject_sender.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Rectangle { - width : 500 - height : 500 - - function resetOthersColors(clickedObject) - { - console.log("CLICKED OBJECT " + clickedObject) - for (var i = 0; i < children.length; ++i) - { - console.log("CHILD OBJECT " + children[i]) - if (children[i] == clickedObject) - continue; - children[i].color = "blue" - } - } - - MyItem { x: 100; y : 20 } - MyItem { x: 100; y : 80 } - MyItem { x: 100; y : 140 } - - Component.onCompleted : { - for (var i = 0; i < children.length; ++i) - { - children[i].triggered.connect(this, resetOthersColors) - } - } -} \ No newline at end of file diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/slideoutpaneltest.qml kdepim-runtime-15.08.0/qml/kde/tests/slideoutpaneltest.qml --- kdepim-runtime-4.14.6/qml/kde/tests/slideoutpaneltest.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/slideoutpaneltest.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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. -*/ - -import Qt 4.7 -import org.kde 4.5 - -Rectangle { - width: 800 - height: 480 - - color : "#00000000" - - SlideoutPanelContainer { - id: panelContainer - anchors.fill: parent - - SlideoutPanel { - id: folderPanel - titleText: KDE.i18n( "Folders" ) - handleHeight: 150 - content: [ - Rectangle { - color: "blue" - anchors.fill: parent - - Rectangle { - color : "yellow" - x : 300 - y : 100 - width : 100 - height : 100 - MouseArea { - anchors.fill : parent - onClicked : { - console.log("Clicked!"); - } - } - } - } - ] - } - - SlideoutPanel { - id: actionPanel - titleText: KDE.i18n( "Actions" ) - titleIcon: KDE.iconPath( "akonadi", 48 ); - handleHeight: 150 - collapsedPosition : 150 - expandedPosition : 25 - contentWidth: 200 - content: [ - Rectangle { - color: "red" - anchors.fill: parent - } - ] - } - - SlideoutPanel { - id: attachmentPanel - titleIcon: KDE.iconPath( "mail-attachment", 48 ); - collapsedPosition : 300 - expandedPosition : 50 - contentWidth: 100 - content: [ - Rectangle { - color: "green" - anchors.fill: parent - } - ] - } - } -} diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/SliderComponent.qml kdepim-runtime-15.08.0/qml/kde/tests/SliderComponent.qml --- kdepim-runtime-4.14.6/qml/kde/tests/SliderComponent.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/SliderComponent.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Item { - id : _topLevel - property real leftBound - property real rightBound - property real threshold : 0.5 - property bool expander - - Rectangle { - id : left - width : 10 - height : _topLevel.height - x : leftBound - width - 2 - y : _topLevel.y - color : "red" - } - - opacity : expander ? ( someRect.x - rightBound) / (leftBound - rightBound) : ( someRect.x - leftBound ) / (rightBound - leftBound) - - signal extensionChanged(real extension) - - function changeExtension(extension) - { - console.log("FOO " + someRect.x + " " + leftBound + " " + rightBound) - if (someRect.x != leftBound && someRect.x != rightBound) - return; - console.log("Changed") - someRect.x = ( extension * (rightBound - leftBound) ) + leftBound - } - - Rectangle { - id : someRect - x : leftBound - y : _topLevel.y - color : "lightsteelblue" - width : 100 - height : 100 - - onXChanged : { - if (x != leftBound && x != rightBound) - return; - - extensionChanged( ( x - leftBound ) / ( rightBound - leftBound ) ) - } - - Behavior on x { - NumberAnimation { - easing.type: "OutQuad" - easing.amplitude: 100 - duration: 300 - } - } - - MouseArea { - id: mrDrag - //property alias active : drag.active - anchors.fill: parent - onReleased: { - if (someRect.x > leftBound + ( ( rightBound - leftBound ) * threshold ) ) - { - someRect.x = rightBound - } else { - someRect.x = leftBound - } - } - drag.target: parent; - drag.axis: "XAxis" - drag.minimumX: leftBound - drag.maximumX: rightBound - } - } - - Rectangle { - id : right - width : 10 - height : _topLevel.height - x : rightBound + someRect.width + 2 - y : _topLevel.y - color : "red" - } - - Rectangle { - width : 1 - height : 10 - x : leftBound + ( ( rightBound - leftBound ) * threshold ) - y : _topLevel.y + _topLevel.height - color : "red" - } -} diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/SomeComponent.qml kdepim-runtime-15.08.0/qml/kde/tests/SomeComponent.qml --- kdepim-runtime-4.14.6/qml/kde/tests/SomeComponent.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/SomeComponent.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Rectangle { - x : 30 - y : 30 - width : 30 - height : 30 - id : blueRect - color : "blue" - - function mySlot() - { - console.log("Invoked"); - } - - function makeConnections() - { - for ( var i = 0; i < children.length; ++i ) { - children[i].triggered.disconnect(this, mySlot) - children[i].triggered.connect(this, mySlot) - } - } - - onChildrenChanged : makeConnections() - Component.onCompleted : makeConnections() -} \ No newline at end of file diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/synced_sliders.qml kdepim-runtime-15.08.0/qml/kde/tests/synced_sliders.qml --- kdepim-runtime-4.14.6/qml/kde/tests/synced_sliders.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/synced_sliders.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Rectangle { - width : 800 - height : 480 - - property real syncedExtension - - SliderComponent { - id : one - y : 30 - x : 50 - height : 100 - leftBound : 30 - rightBound : 130 - threshold : 0.2 - expander : true - - onExtensionChanged : { - two.changeExtension(extension) - } - } - SliderComponent { - id : two - y : 130 - x : 50 - - height : 100 - leftBound : 30 - rightBound : 430 - threshold : 0.7 - onExtensionChanged : { - one.changeExtension(extension) - } - } - -} diff -Nru kdepim-runtime-4.14.6/qml/kde/tests/transformorigin.qml kdepim-runtime-15.08.0/qml/kde/tests/transformorigin.qml --- kdepim-runtime-4.14.6/qml/kde/tests/transformorigin.qml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/tests/transformorigin.qml 1970-01-01 00:00:00.000000000 +0000 @@ -1,148 +0,0 @@ -/* - Copyright (C) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company, info@kdab.net, - author Stephen Kelly - - 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. -*/ - -import Qt 4.7 - -Rectangle { - width : 800 - height : 480 - - Grid { - x : 30 - y : 30 - columns : 3 - spacing : 30 - Rectangle { - height : children[0].height - width : children[0].width - border.color: "lightsteelblue" - border.width : 5 - Text { - height : 20 - text : "Something" - rotation : 30 - transformOrigin : Item.TopLeft - } - } - Rectangle { - height : children[0].height - width : children[0].width - border.color: "lightsteelblue" - border.width : 5 - - Text { - height : 20 - text : "Something" - rotation : 30 - transformOrigin : Item.Top - } - } - Rectangle { - height : children[0].height - width : children[0].width - border.color: "lightsteelblue" - border.width : 5 - - Text { - height : 20 - text : "Something" - rotation : 30 - transformOrigin : Item.TopRight - } - } - Rectangle { - height : children[0].height - width : children[0].width - border.color: "lightsteelblue" - border.width : 5 - Text { - height : 20 - text : "Something" - rotation : 30 - transformOrigin : Item.Left - } - } - Rectangle { - height : children[0].height - width : children[0].width - border.color: "lightsteelblue" - border.width : 5 - - Text { - height : 20 - text : "Something" - rotation : 30 - transformOrigin : Item.Center - } - } - Rectangle { - height : children[0].height - width : children[0].width - border.color: "lightsteelblue" - border.width : 5 - - Text { - height : 20 - text : "Something" - rotation : 30 - transformOrigin : Item.Right - } - } - Rectangle { - height : children[0].height - width : children[0].width - border.color: "lightsteelblue" - border.width : 5 - Text { - height : 20 - text : "Something" - rotation : 30 - transformOrigin : Item.BottomLeft - } - } - Rectangle { - height : children[0].height - width : children[0].width - border.color: "lightsteelblue" - border.width : 5 - - Text { - height : 20 - text : "Something" - rotation : 30 - transformOrigin : Item.Bottom - } - } - Rectangle { - height : children[0].height - width : children[0].width - border.color: "lightsteelblue" - border.width : 5 - - Text { - height : 20 - text : "Something" - rotation : -90 - transformOrigin : Item.BottomRight - } - } - } -} diff -Nru kdepim-runtime-4.14.6/qml/kde/transparentplus.svg kdepim-runtime-15.08.0/qml/kde/transparentplus.svg --- kdepim-runtime-4.14.6/qml/kde/transparentplus.svg 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/kde/transparentplus.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ - - - - - - - - - - - image/svg+xml - - - - - - - - diff -Nru kdepim-runtime-4.14.6/qml/Messages.sh kdepim-runtime-15.08.0/qml/Messages.sh --- kdepim-runtime-4.14.6/qml/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/qml/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -#! /bin/sh -$EXTRACTRC --ignore-no-input `find . -name '*.ui' -or -name '*.rc' -or -name '*.kcfg' -or -name '*.kcfg.cmake'` >> rc.cpp || exit 11 -$XGETTEXT -ktranslate `find . -name '*.cpp' -o -name '*.h' | grep -v '/tests/'` -o $podir/kdepim-runtime-qml.pot -if [ -e $podir/kdepim-runtime-qml.pot ]; then - extraparam="-j" -fi -$XGETTEXT -ktranslate `find . -name '*.qml' | grep -v '/tests/'` $extraparam -L Java -o $podir/kdepim-runtime-qml.pot -rm -f rc.cpp diff -Nru kdepim-runtime-4.14.6/resources/akonotes/akonotesresource.cpp kdepim-runtime-15.08.0/resources/akonotes/akonotesresource.cpp --- kdepim-runtime-4.14.6/resources/akonotes/akonotesresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/akonotes/akonotesresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,12 +20,10 @@ #include "akonotesresource.h" #include -#include -AkonotesResource::AkonotesResource( const QString &id ) - : MaildirResource( id ) +AkonotesResource::AkonotesResource(const QString &id) + : MaildirResource(id) { - KGlobal::locale()->insertCatalog( "akonadi_maildir_resource" ); } AkonotesResource::~AkonotesResource() @@ -34,17 +32,18 @@ QString AkonotesResource::itemMimeType() const { - return QLatin1String( "text/x-vnd.akonadi.note" ); + return QStringLiteral("text/x-vnd.akonadi.note"); } -void AkonotesResource::configure( WId windowId ) +void AkonotesResource::configure(WId windowId) { - MaildirResource::configure( windowId ); - synchronize(); // heavy to do it in the MaildirResource method, which already has sync on demand working properly + MaildirResource::configure(windowId); + synchronize(); // heavy to do it in the MaildirResource method, which already has sync on demand working properly } QString AkonotesResource::defaultResourceType() { - return QLatin1String("notes"); + return QStringLiteral("notes"); } +AKONADI_RESOURCE_MAIN(AkonotesResource) diff -Nru kdepim-runtime-4.14.6/resources/akonotes/akonotesresource.desktop kdepim-runtime-15.08.0/resources/akonotes/akonotesresource.desktop --- kdepim-runtime-4.14.6/resources/akonotes/akonotesresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/akonotes/akonotesresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -76,7 +76,7 @@ Comment[ro]=Încarcă o ierarhie de notițe dintr-un dosar maildir local Comment[ru]=Загрузка иерархии примечаний из локальной папки с почтой Comment[sk]=Načíta hierarchiu poznámok z miestneho priečinka maildir -Comment[sl]=Naloži hierarhijo notic iz krajevne poštne mape MailDir +Comment[sl]=Naloži hierarhijo sporočilc iz krajevne poštne mape MailDir Comment[sr]=Учитава хијерархију белешки из локалне мејлдир фасцикле Comment[sr@ijekavian]=Учитава хијерархију биљешки из локалне мејлдир фасцикле Comment[sr@ijekavianlatin]=Učitava hijerarhiju bilješki iz lokalne maildir fascikle @@ -94,4 +94,3 @@ X-Akonadi-MimeTypes=text/x-vnd.akonadi.note X-Akonadi-Capabilities=Resource,Notes X-Akonadi-Identifier=akonadi_akonotes_resource -X-Akonadi-LaunchMethod=AgentServer diff -Nru kdepim-runtime-4.14.6/resources/akonotes/akonotesresource.h kdepim-runtime-15.08.0/resources/akonotes/akonotesresource.h --- kdepim-runtime-4.14.6/resources/akonotes/akonotesresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/akonotes/akonotesresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,18 +24,16 @@ class AkonotesResource : public MaildirResource { - Q_OBJECT - - public: - explicit AkonotesResource( const QString &id ); + Q_OBJECT +public: + explicit AkonotesResource(const QString &id); ~AkonotesResource(); - virtual QString defaultResourceType(); + QString defaultResourceType() Q_DECL_OVERRIDE; public Q_SLOTS: - virtual void configure( WId windowId ); + void configure(WId windowId) Q_DECL_OVERRIDE; - protected: - virtual QString itemMimeType() const; +protected: + QString itemMimeType() const Q_DECL_OVERRIDE; }; - #endif diff -Nru kdepim-runtime-4.14.6/resources/akonotes/CMakeLists.txt kdepim-runtime-15.08.0/resources/akonotes/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/akonotes/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/akonotes/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -3,11 +3,11 @@ ${CMAKE_CURRENT_SOURCE_DIR}/../maildir ${CMAKE_CURRENT_BINARY_DIR}/../maildir ${CMAKE_CURRENT_SOURCE_DIR}/../maildir/libmaildir - ${QT_QTDBUS_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ) -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) + +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_akonotes_resource\") ########### next target ############### @@ -16,27 +16,26 @@ ../maildir/maildirresource.cpp ../maildir/configdialog.cpp ../maildir/retrieveitemsjob.cpp + ../maildir/maildirresource_debug.cpp akonotesresource.cpp - - main.cpp ) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/../maildir/maildirresource.kcfg org.kde.Akonadi.Maildir.Settings) -kde4_add_ui_files(akonotesresource_SRCS ../maildir/settings.ui) +ki18n_wrap_ui(akonotesresource_SRCS ../maildir/settings.ui) -kde4_add_kcfg_files(akonotesresource_SRCS ../maildir/settings.kcfgc) +kconfig_add_kcfg_files(akonotesresource_SRCS ../maildir/settings.kcfgc) -qt4_add_dbus_adaptor(akonotesresource_SRCS +qt5_add_dbus_adaptor(akonotesresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.Maildir.Settings.xml settings.h Akonadi_Maildir_Resource::MaildirSettings maildirsettingsadaptor MaildirSettingsAdaptor ) -install( FILES akonotesresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) +install( FILES akonotesresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) -kde4_add_plugin(akonadi_akonotes_resource ${akonotesresource_SRCS}) +add_executable(akonadi_akonotes_resource ${akonotesresource_SRCS}) -target_link_libraries(akonadi_akonotes_resource ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_AKONADI_KMIME_LIBS} maildir ${QT_QTDBUS_LIBRARY} ${KDE4_KIO_LIBS} ${KDEPIMLIBS_KMIME_LIBS} folderarchivesettings) +target_link_libraries(akonadi_akonotes_resource KF5::AkonadiCore KF5::AkonadiMime maildir KF5::Mime folderarchivesettings KF5::AkonadiAgentBase KF5::DBusAddons) -install(TARGETS akonadi_akonotes_resource DESTINATION ${PLUGIN_INSTALL_DIR}) +install(TARGETS akonadi_akonotes_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/akonotes/main.cpp kdepim-runtime-15.08.0/resources/akonotes/main.cpp --- kdepim-runtime-4.14.6/resources/akonotes/main.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/akonotes/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -/* - Copyright (c) 2007 Till Adam - - 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 "akonotesresource.h" - -#include - -AKONADI_AGENT_FACTORY( AkonotesResource, akonadi_akonotes_resource ) diff -Nru kdepim-runtime-4.14.6/resources/birthdays/birthdays_debug.cpp kdepim-runtime-15.08.0/resources/birthdays/birthdays_debug.cpp --- kdepim-runtime-4.14.6/resources/birthdays/birthdays_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/birthdays/birthdays_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 "birthdays_debug.h" +Q_LOGGING_CATEGORY(BIRTHDAYS_LOG, "log_birthdays") + diff -Nru kdepim-runtime-4.14.6/resources/birthdays/birthdays_debug.h kdepim-runtime-15.08.0/resources/birthdays/birthdays_debug.h --- kdepim-runtime-4.14.6/resources/birthdays/birthdays_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/birthdays/birthdays_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 BIRTHDAYS_DEBUG_H +#define BIRTHDAYS_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(BIRTHDAYS_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/birthdays/birthdaysresource.cpp kdepim-runtime-15.08.0/resources/birthdays/birthdaysresource.cpp --- kdepim-runtime-4.14.6/resources/birthdays/birthdaysresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/birthdays/birthdaysresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,329 +23,343 @@ #include "settingsadaptor.h" #include "configdialog.h" -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include -#include +#include -#include +#include -#include +#include "birthdays_debug.h" #include #include +#include + using namespace Akonadi; -using namespace KABC; +using namespace KContacts; using namespace KCalCore; - -BirthdaysResource::BirthdaysResource(const QString& id) : - ResourceBase( id ) +BirthdaysResource::BirthdaysResource(const QString &id) : + ResourceBase(id) { - new SettingsAdaptor( Settings::self() ); - QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ), - Settings::self(), QDBusConnection::ExportAdaptors ); - - setName( i18n( "Birthdays & Anniversaries" ) ); - - Monitor *monitor = new Monitor( this ); - monitor->setMimeTypeMonitored( Addressee::mimeType() ); - monitor->itemFetchScope().fetchFullPayload(); - connect( monitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)), - SLOT(contactChanged(Akonadi::Item)) ); - connect( monitor, SIGNAL(itemChanged(Akonadi::Item,QSet)), - SLOT(contactChanged(Akonadi::Item)) ); - connect( monitor, SIGNAL(itemRemoved(Akonadi::Item)), - SLOT(contactRemoved(Akonadi::Item)) ); + new SettingsAdaptor(Settings::self()); + QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"), + Settings::self(), QDBusConnection::ExportAdaptors); + + setName(i18n("Birthdays & Anniversaries")); + + Monitor *monitor = new Monitor(this); + monitor->setMimeTypeMonitored(Addressee::mimeType()); + monitor->itemFetchScope().fetchFullPayload(); + connect(monitor, &Monitor::itemAdded, this, &BirthdaysResource::contactChanged); + connect(monitor, &Monitor::itemChanged, this, &BirthdaysResource::contactChanged); + connect(monitor, &Monitor::itemRemoved, this, &BirthdaysResource::contactRemoved); - connect( this, SIGNAL(reloadConfiguration()), SLOT(doFullSearch()) ); + connect(this, &BirthdaysResource::reloadConfiguration, this, &BirthdaysResource::doFullSearch); } BirthdaysResource::~BirthdaysResource() { } -void BirthdaysResource::configure( WId windowId ) +void BirthdaysResource::configure(WId windowId) { - ConfigDialog dlg; - if ( windowId ) - KWindowSystem::setMainWindow( &dlg, windowId ); - if ( dlg.exec() ) { - emit configurationDialogAccepted(); - } else { - emit configurationDialogRejected(); - } - doFullSearch(); - synchronizeCollectionTree(); + ConfigDialog dlg; + if (windowId) { + KWindowSystem::setMainWindow(&dlg, windowId); + } + if (dlg.exec()) { + Q_EMIT configurationDialogAccepted(); + } else { + Q_EMIT configurationDialogRejected(); + } + doFullSearch(); + synchronizeCollectionTree(); } void BirthdaysResource::retrieveCollections() { - Collection c; - c.setParentCollection( Collection::root() ); - c.setRemoteId( QLatin1String("akonadi_birthdays_resource") ); - c.setName( name() ); - c.setContentMimeTypes( QStringList() << QLatin1String("application/x-vnd.akonadi.calendar.event") ); - c.setRights( Collection::ReadOnly ); - - EntityDisplayAttribute *attribute = c.attribute( Collection::AddIfMissing ); - attribute->setIconName( QLatin1String( "view-calendar-birthday" ) ); - - Collection::List list; - list << c; - collectionsRetrieved( list ); -} - -void BirthdaysResource::retrieveItems(const Akonadi::Collection& collection) -{ - Q_UNUSED( collection ); - itemsRetrievedIncremental( mPendingItems.values(), mDeletedItems.values() ); - mPendingItems.clear(); - mDeletedItems.clear(); -} - -bool BirthdaysResource::retrieveItem(const Akonadi::Item& item, const QSet< QByteArray > &parts) -{ - Q_UNUSED( parts ); - qint64 contactId = item.remoteId().mid( 1 ).toLongLong(); - ItemFetchJob *job = new ItemFetchJob( Item( contactId ), this ); - job->fetchScope().fetchFullPayload(); - connect( job, SIGNAL(result(KJob*)), SLOT(contactRetrieved(KJob*)) ); - return true; -} - -void BirthdaysResource::contactRetrieved(KJob* job) -{ - ItemFetchJob *fj = static_cast( job ); - if ( job->error() ) { - emit error( job->errorText() ); - cancelTask(); - } else if ( fj->items().count() != 1 ) { - cancelTask(); - } else { - KCalCore::Incidence::Ptr ev; - if ( currentItem().remoteId().startsWith( QLatin1Char('b') ) ) - ev = createBirthday( fj->items().first() ); - else if ( currentItem().remoteId().startsWith( QLatin1Char('a') ) ) - ev = createAnniversary( fj->items().first() ); - if ( !ev ) { - cancelTask(); - } else { - Item i( currentItem() ); - i.setPayload( ev ); - itemRetrieved( i ); - } - } -} - -void BirthdaysResource::contactChanged( const Akonadi::Item& item ) -{ - if ( !item.hasPayload() ) - return; - KABC::Addressee contact = item.payload(); - - if ( Settings::self()->filterOnCategories() ) { - bool hasCategory = false; - const QStringList categories = contact.categories(); - foreach ( const QString &cat, Settings::self()->filterCategories() ) { - if ( categories.contains( cat ) ) { - hasCategory = true; - break; - } - } - - if ( !hasCategory ) - return; - } - Event::Ptr event = createBirthday( item ); - if ( event ) { - addPendingEvent( event, QString::fromLatin1( "b%1" ).arg( item.id() ) ); - } else { - Item i( KCalCore::Event::eventMimeType() ); - i.setRemoteId( QString::fromLatin1( "b%1" ).arg( item.id() ) ); - mDeletedItems[ i.remoteId() ] = i; - } - - event = createAnniversary( item ); - if ( event ) { - addPendingEvent( event, QString::fromLatin1( "a%1" ).arg( item.id() ) ); - } else { - Item i( KCalCore::Event::eventMimeType() ); - i.setRemoteId( QString::fromLatin1( "a%1" ).arg( item.id() ) ); - mDeletedItems[ i.remoteId() ] = i; - } - synchronize(); + Collection c; + c.setParentCollection(Collection::root()); + c.setRemoteId(QStringLiteral("akonadi_birthdays_resource")); + c.setName(name()); + c.setContentMimeTypes(QStringList() << QStringLiteral("application/x-vnd.akonadi.calendar.event")); + c.setRights(Collection::ReadOnly); + + EntityDisplayAttribute *attribute = c.attribute(Collection::AddIfMissing); + attribute->setIconName(QStringLiteral("view-calendar-birthday")); + + Collection::List list; + list << c; + collectionsRetrieved(list); +} + +void BirthdaysResource::retrieveItems(const Akonadi::Collection &collection) +{ + Q_UNUSED(collection); + itemsRetrievedIncremental(Akonadi::valuesToVector(mPendingItems), Akonadi::valuesToVector(mDeletedItems)); + mPendingItems.clear(); + mDeletedItems.clear(); +} + +bool BirthdaysResource::retrieveItem(const Akonadi::Item &item, const QSet< QByteArray > &parts) +{ + Q_UNUSED(parts); + qint64 contactId = item.remoteId().mid(1).toLongLong(); + ItemFetchJob *job = new ItemFetchJob(Item(contactId), this); + job->fetchScope().fetchFullPayload(); + connect(job, &ItemFetchJob::result, this, &BirthdaysResource::contactRetrieved); + return true; } -void BirthdaysResource::addPendingEvent( const KCalCore::Event::Ptr &event, const QString &remoteId ) +void BirthdaysResource::contactRetrieved(KJob *job) { - KCalCore::Incidence::Ptr evptr( event ); - Item i( KCalCore::Event::eventMimeType() ); - i.setRemoteId( remoteId ); - i.setPayload( evptr ); - mPendingItems[ remoteId ] = i; + ItemFetchJob *fj = static_cast(job); + if (job->error()) { + Q_EMIT error(job->errorText()); + cancelTask(); + } else if (fj->items().count() != 1) { + cancelTask(); + } else { + KCalCore::Incidence::Ptr ev; + if (currentItem().remoteId().startsWith(QLatin1Char('b'))) { + ev = createBirthday(fj->items().at(0)); + } else if (currentItem().remoteId().startsWith(QLatin1Char('a'))) { + ev = createAnniversary(fj->items().at(0)); + } + if (!ev) { + cancelTask(); + } else { + Item i(currentItem()); + i.setPayload(ev); + itemRetrieved(i); + } + } } +void BirthdaysResource::contactChanged(const Akonadi::Item &item) +{ + if (!item.hasPayload()) { + return; + } + + KContacts::Addressee contact = item.payload(); + + if (Settings::self()->filterOnCategories()) { + bool hasCategory = false; + const QStringList categories = contact.categories(); + foreach (const QString &cat, Settings::self()->filterCategories()) { + if (categories.contains(cat)) { + hasCategory = true; + break; + } + } + + if (!hasCategory) { + return; + } + } + + Event::Ptr event = createBirthday(item); + if (event) { + addPendingEvent(event, QStringLiteral("b%1").arg(item.id())); + } else { + Item i(KCalCore::Event::eventMimeType()); + i.setRemoteId(QStringLiteral("b%1").arg(item.id())); + mDeletedItems[ i.remoteId() ] = i; + } + + event = createAnniversary(item); + if (event) { + addPendingEvent(event, QString::fromLatin1("a%1").arg(item.id())); + } else { + Item i(KCalCore::Event::eventMimeType()); + i.setRemoteId(QStringLiteral("a%1").arg(item.id())); + mDeletedItems[ i.remoteId() ] = i; + } + synchronize(); +} -void BirthdaysResource::contactRemoved( const Akonadi::Item& item ) +void BirthdaysResource::addPendingEvent(const KCalCore::Event::Ptr &event, const QString &remoteId) { - Item i( KCalCore::Event::eventMimeType() ); - i.setRemoteId( QString::fromLatin1( "b%1" ).arg( item.id() ) ); - mDeletedItems[ i.remoteId() ] = i; - i.setRemoteId( QString::fromLatin1( "a%1" ).arg( item.id() ) ); - mDeletedItems[ i.remoteId() ] = i; - synchronize(); + KCalCore::Incidence::Ptr evptr(event); + Item i(KCalCore::Event::eventMimeType()); + i.setRemoteId(remoteId); + i.setPayload(evptr); + mPendingItems[ remoteId ] = i; } +void BirthdaysResource::contactRemoved(const Akonadi::Item &item) +{ + Item i(KCalCore::Event::eventMimeType()); + i.setRemoteId(QStringLiteral("b%1").arg(item.id())); + mDeletedItems[ i.remoteId() ] = i; + i.setRemoteId(QStringLiteral("a%1").arg(item.id())); + mDeletedItems[ i.remoteId() ] = i; + synchronize(); +} void BirthdaysResource::doFullSearch() { - CollectionFetchJob *job = new CollectionFetchJob( Collection::root(), CollectionFetchJob::Recursive, this ); - connect( job, SIGNAL(collectionsReceived(Akonadi::Collection::List)), SLOT(listContacts(Akonadi::Collection::List)) ); + CollectionFetchJob *job = new CollectionFetchJob(Collection::root(), CollectionFetchJob::Recursive, this); + connect(job, &CollectionFetchJob::collectionsReceived, this, &BirthdaysResource::listContacts); } void BirthdaysResource::listContacts(const Akonadi::Collection::List &cols) { - MimeTypeChecker contactFilter; - contactFilter.addWantedMimeType( Addressee::mimeType() ); - foreach ( const Collection &col, cols ) { - if ( !contactFilter.isWantedCollection( col ) ) - continue; - ItemFetchJob *job = new ItemFetchJob( col, this ); - job->fetchScope().fetchFullPayload(); - connect( job, SIGNAL(itemsReceived(Akonadi::Item::List)), SLOT(createEvents(Akonadi::Item::List)) ); - } + MimeTypeChecker contactFilter; + contactFilter.addWantedMimeType(Addressee::mimeType()); + foreach (const Collection &col, cols) { + if (!contactFilter.isWantedCollection(col)) { + continue; + } + ItemFetchJob *job = new ItemFetchJob(col, this); + job->fetchScope().fetchFullPayload(); + connect(job, &ItemFetchJob::itemsReceived, this, &BirthdaysResource::createEvents); + } } void BirthdaysResource::createEvents(const Akonadi::Item::List &items) { - foreach ( const Item &item, items ) - contactChanged( item ); + foreach (const Item &item, items) { + contactChanged(item); + } } -KCalCore::Event::Ptr BirthdaysResource::createBirthday(const Akonadi::Item& contactItem) +KCalCore::Event::Ptr BirthdaysResource::createBirthday(const Akonadi::Item &contactItem) { - if ( !contactItem.hasPayload() ) - return KCalCore::Event::Ptr(); - KABC::Addressee contact = contactItem.payload(); - - const QString name = contact.realName().isEmpty() ? contact.nickName() : contact.realName(); - if ( name.isEmpty() ) { - kDebug() << "contact " << contact.uid() << contactItem.id() << " has no name, skipping."; - return KCalCore::Event::Ptr(); - } - - const QDate birthdate = contact.birthday().date(); - if ( birthdate.isValid() ) { - const QString summary = i18n( "%1's birthday", name ); + if (!contactItem.hasPayload()) { + return KCalCore::Event::Ptr(); + } + KContacts::Addressee contact = contactItem.payload(); - Event::Ptr ev = createEvent( birthdate ); - ev->setUid( contact.uid() + QLatin1String("_KABC_Birthday") ); + const QString name = contact.realName().isEmpty() ? contact.nickName() : contact.realName(); + if (name.isEmpty()) { + qCDebug(BIRTHDAYS_LOG) << "contact " << contact.uid() << contactItem.id() << " has no name, skipping."; + return KCalCore::Event::Ptr(); + } - ev->setCustomProperty( "KABC", "BIRTHDAY", QLatin1String("YES") ); - ev->setCustomProperty( "KABC", "UID-1", contact.uid() ); - ev->setCustomProperty( "KABC", "NAME-1", name ); - ev->setCustomProperty( "KABC", "EMAIL-1", contact.preferredEmail() ); - ev->setSummary( summary ); + const QDate birthdate = contact.birthday().date(); + if (birthdate.isValid()) { + const QString summary = i18n("%1's birthday", name); + + Event::Ptr ev = createEvent(birthdate); + ev->setUid(contact.uid() + QStringLiteral("_KABC_Birthday")); + + ev->setCustomProperty("KABC", "BIRTHDAY", QStringLiteral("YES")); + ev->setCustomProperty("KABC", "UID-1", contact.uid()); + ev->setCustomProperty("KABC", "NAME-1", name); + ev->setCustomProperty("KABC", "EMAIL-1", contact.preferredEmail()); + ev->setSummary(summary); - ev->setCategories( i18n( "Birthday" ) ); - return ev; - } - return KCalCore::Event::Ptr(); + checkForUnknownCategories(i18n("Birthday"), ev); + return ev; + } + return KCalCore::Event::Ptr(); } -KCalCore::Event::Ptr BirthdaysResource::createAnniversary(const Akonadi::Item& contactItem) +KCalCore::Event::Ptr BirthdaysResource::createAnniversary(const Akonadi::Item &contactItem) { - if ( !contactItem.hasPayload() ) - return KCalCore::Event::Ptr(); - KABC::Addressee contact = contactItem.payload(); + if (!contactItem.hasPayload()) { + return KCalCore::Event::Ptr(); + } + KContacts::Addressee contact = contactItem.payload(); - const QString name = contact.realName().isEmpty() ? contact.nickName() : contact.realName(); - if ( name.isEmpty() ) { - kDebug() << "contact " << contact.uid() << contactItem.id() << " has no name, skipping."; - return KCalCore::Event::Ptr(); - } + const QString name = contact.realName().isEmpty() ? contact.nickName() : contact.realName(); + if (name.isEmpty()) { + qCDebug(BIRTHDAYS_LOG) << "contact " << contact.uid() << contactItem.id() << " has no name, skipping."; + return KCalCore::Event::Ptr(); + } - const QString anniversary_string = contact.custom( QLatin1String("KADDRESSBOOK"), QLatin1String("X-Anniversary") ); - if ( anniversary_string.isEmpty() ) + const QString anniversary_string = contact.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-Anniversary")); + if (anniversary_string.isEmpty()) { + return KCalCore::Event::Ptr(); + } + const QDate anniversary = QDate::fromString(anniversary_string, Qt::ISODate); + if (anniversary.isValid()) { + const QString spouseName = contact.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-SpousesName")); + + QString summary; + if (!spouseName.isEmpty()) { + QString tname, temail; + KEmailAddress::extractEmailAddressAndName(spouseName, temail, tname); + tname = KEmailAddress::quoteNameIfNecessary(tname); + if ((tname[0] == QLatin1Char('"')) && (tname[tname.length() - 1] == QLatin1Char('"'))) { + tname.remove(0, 1); + tname.truncate(tname.length() - 1); + } + tname.remove(QLatin1Char('\\')); // remove escape chars + KContacts::Addressee spouse; + spouse.setNameFromString(tname); + QString name_2 = spouse.nickName(); + if (name_2.isEmpty()) { + name_2 = spouse.realName(); + } + summary = i18nc("insert names of both spouses", + "%1's & %2's anniversary", name, name_2); + } else { + summary = i18nc("only one spouse in addressbook, insert the name", + "%1's anniversary", name); + } + + Event::Ptr event = createEvent(anniversary); + event->setUid(contact.uid() + QStringLiteral("_KABC_Anniversary")); + event->setSummary(summary); + + event->setCustomProperty("KABC", "UID-1", contact.uid()); + event->setCustomProperty("KABC", "NAME-1", name); + event->setCustomProperty("KABC", "EMAIL-1", contact.fullEmail()); + event->setCustomProperty("KABC", "ANNIVERSARY", QStringLiteral("YES")); + // insert category + checkForUnknownCategories(i18n("Anniversary"), event); + return event; + } return KCalCore::Event::Ptr(); - const QDate anniversary = QDate::fromString( anniversary_string, Qt::ISODate ); - if ( anniversary.isValid() ) { - const QString spouseName = contact.custom( QLatin1String("KADDRESSBOOK"), QLatin1String("X-SpousesName") ); - - QString summary; - if ( !spouseName.isEmpty() ) { - QString tname, temail; - KPIMUtils::extractEmailAddressAndName( spouseName, temail, tname ); - tname = KPIMUtils::quoteNameIfNecessary( tname ); - if ( ( tname[0] == QLatin1Char('"') ) && ( tname[tname.length() - 1] == QLatin1Char('"') ) ) { - tname.remove( 0, 1 ); - tname.truncate( tname.length() - 1 ); - } - tname.remove( QLatin1Char('\\') ); // remove escape chars - KABC::Addressee spouse; - spouse.setNameFromString( tname ); - QString name_2 = spouse.nickName(); - if ( name_2.isEmpty() ) { - name_2 = spouse.realName(); - } - summary = i18nc( "insert names of both spouses", - "%1's & %2's anniversary", name, name_2 ); - } else { - summary = i18nc( "only one spouse in addressbook, insert the name", - "%1's anniversary", name ); +} + +KCalCore::Event::Ptr BirthdaysResource::createEvent(const QDate &date) +{ + Event::Ptr event(new Event()); + event->setDtStart(KDateTime(date, KDateTime::Spec(KDateTime::ClockTime))); + event->setDtEnd(KDateTime(date, KDateTime::Spec(KDateTime::ClockTime))); + event->setAllDay(true); + event->setTransparency(Event::Transparent); + + // Set the recurrence + Recurrence *recurrence = event->recurrence(); + recurrence->setStartDateTime(KDateTime(date, KDateTime::Spec(KDateTime::ClockTime))); + recurrence->setYearly(1); + if (date.month() == 2 && date.day() == 29) { + recurrence->addYearlyDay(60); + } + + // Set the alarm + event->clearAlarms(); + if (Settings::self()->enableAlarm()) { + Alarm::Ptr alarm = event->newAlarm(); + alarm->setType(Alarm::Display); + alarm->setText(event->summary()); + alarm->setTime(KDateTime(date, KDateTime::Spec(KDateTime::ClockTime))); + // N days before + alarm->setStartOffset(Duration(-Settings::self()->alarmDays(), Duration::Days)); + alarm->setEnabled(true); } - Event::Ptr event = createEvent( anniversary ); - event->setUid( contact.uid() + QLatin1String("_KABC_Anniversary") ); - event->setSummary( summary ); - - event->setCustomProperty( "KABC", "UID-1", contact.uid() ); - event->setCustomProperty( "KABC", "NAME-1", name ); - event->setCustomProperty( "KABC", "EMAIL-1", contact.fullEmail() ); - event->setCustomProperty( "KABC", "ANNIVERSARY", QLatin1String("YES") ); - // insert category - event->setCategories( i18n( "Anniversary" ) ); return event; - } - return KCalCore::Event::Ptr(); } -KCalCore::Event::Ptr BirthdaysResource::createEvent(const QDate& date) +void BirthdaysResource::checkForUnknownCategories(const QString &categoryToCheck, Event::Ptr &event) { - Event::Ptr event( new Event() ); - event->setDtStart( KDateTime( date, KDateTime::ClockTime ) ); - event->setDtEnd( KDateTime( date, KDateTime::ClockTime ) ); - event->setHasEndDate( true ); - event->setAllDay( true ); - event->setTransparency( Event::Transparent ); - - // Set the recurrence - Recurrence *recurrence = event->recurrence(); - recurrence->setStartDateTime( KDateTime( date, KDateTime::ClockTime ) ); - recurrence->setYearly( 1 ); - if ( date.month() == 2 && date.day() == 29 ) - recurrence->addYearlyDay( 60 ); - - // Set the alarm - event->clearAlarms(); - if ( Settings::self()->enableAlarm() ) { - Alarm::Ptr alarm = event->newAlarm(); - alarm->setType( Alarm::Display ); - alarm->setText( event->summary() ); - alarm->setTime( KDateTime( date, KDateTime::ClockTime ) ); - // N days before - alarm->setStartOffset( Duration( -Settings::self()->alarmDays(), Duration::Days ) ); - alarm->setEnabled( true ); - } - - return event; + Akonadi::TagCreateJob *tagCreateJob = new Akonadi::TagCreateJob(Akonadi::Tag(categoryToCheck), this); + tagCreateJob->setMergeIfExisting(true); + event->setCategories(categoryToCheck); } - -AKONADI_RESOURCE_MAIN( BirthdaysResource ) +AKONADI_RESOURCE_MAIN(BirthdaysResource) diff -Nru kdepim-runtime-4.14.6/resources/birthdays/birthdaysresource.desktop kdepim-runtime-15.08.0/resources/birthdays/birthdaysresource.desktop --- kdepim-runtime-4.14.6/resources/birthdays/birthdaysresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/birthdays/birthdaysresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,6 +1,7 @@ [Desktop Entry] Name=Birthdays & Anniversaries Name[ar]=أعياد الميلاد و الذكريات +Name[bg]=Рождени дни и годишнини Name[bs]=Rođendani i godišnjice Name[ca]=Dates de naixement i aniversaris Name[ca@valencia]=Dates de naixement i aniversaris diff -Nru kdepim-runtime-4.14.6/resources/birthdays/birthdaysresource.h kdepim-runtime-15.08.0/resources/birthdays/birthdaysresource.h --- kdepim-runtime-4.14.6/resources/birthdays/birthdaysresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/birthdays/birthdaysresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -21,9 +21,9 @@ #ifndef BIRTHDAYSRESOURCE_H #define BIRTHDAYSRESOURCE_H -#include +#include -#include +#include #include @@ -31,37 +31,38 @@ class BirthdaysResource : public Akonadi::ResourceBase, public Akonadi::AgentBase::Observer { - Q_OBJECT + Q_OBJECT - public: - BirthdaysResource( const QString &id ); +public: + explicit BirthdaysResource(const QString &id); ~BirthdaysResource(); - public Q_SLOTS: - virtual void configure( WId windowId ); +public Q_SLOTS: + void configure(WId windowId) Q_DECL_OVERRIDE; - protected: - void retrieveCollections(); - void retrieveItems( const Akonadi::Collection &collection ); - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - - private: - void addPendingEvent( const KCalCore::Event::Ptr &event, const QString &remoteId ); - - KCalCore::Event::Ptr createBirthday( const Akonadi::Item &contactItem ); - KCalCore::Event::Ptr createAnniversary( const Akonadi::Item &contactItem ); - KCalCore::Event::Ptr createEvent( const QDate &date ); +protected: + void retrieveCollections() Q_DECL_OVERRIDE; + void retrieveItems(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + bool retrieveItem(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + +private: + void addPendingEvent(const KCalCore::Event::Ptr &event, const QString &remoteId); + void checkForUnknownCategories(const QString &categoryToCheck, KCalCore::Event::Ptr &event); + + KCalCore::Event::Ptr createBirthday(const Akonadi::Item &contactItem); + KCalCore::Event::Ptr createAnniversary(const Akonadi::Item &contactItem); + KCalCore::Event::Ptr createEvent(const QDate &date); - private slots: +private Q_SLOTS: void doFullSearch(); - void listContacts( const Akonadi::Collection::List &cols ); - void createEvents( const Akonadi::Item::List &items ); + void listContacts(const Akonadi::Collection::List &cols); + void createEvents(const Akonadi::Item::List &items); - void contactChanged( const Akonadi::Item &item ); - void contactRemoved( const Akonadi::Item &item ); + void contactChanged(const Akonadi::Item &item); + void contactRemoved(const Akonadi::Item &item); - void contactRetrieved( KJob *job ); - private: + void contactRetrieved(KJob *job); +private: QHash mPendingItems; QHash mDeletedItems; }; diff -Nru kdepim-runtime-4.14.6/resources/birthdays/CMakeLists.txt kdepim-runtime-15.08.0/resources/birthdays/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/birthdays/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/birthdays/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,35 +1,38 @@ include_directories( ${Boost_INCLUDE_DIR} ) -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) + +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_birthdays_resource\") set( birthdayresource_srcs + birthdays_debug.cpp birthdaysresource.cpp configdialog.cpp ) -kde4_add_kcfg_files( birthdayresource_srcs settings.kcfgc ) +kconfig_add_kcfg_files( birthdayresource_srcs settings.kcfgc ) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/birthdaysresource.kcfg org.kde.Akonadi.Birthdays.Settings) -kde4_add_ui_files(birthdayresource_srcs configdialog.ui) +ki18n_wrap_ui(birthdayresource_srcs configdialog.ui) -qt4_add_dbus_adaptor(birthdayresource_srcs +qt5_add_dbus_adaptor(birthdayresource_srcs ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.Birthdays.Settings.xml settings.h Settings ) -kde4_add_executable(akonadi_birthdays_resource ${birthdayresource_srcs}) +add_executable(akonadi_birthdays_resource ${birthdayresource_srcs}) -if (Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_birthdays_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) set_target_properties(akonadi_birthdays_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.Birthdays") set_target_properties(akonadi_birthdays_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi Birthdays Resource") endif () target_link_libraries(akonadi_birthdays_resource - ${KDE4_KIO_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KABC_LIBS} - ${KDEPIMLIBS_KCALCORE_LIBS} - ${KDEPIMLIBS_KPIMUTILS_LIBS} + KF5::AkonadiCore + KF5::CalendarCore + KF5::Codecs + KF5::AkonadiAgentBase + KF5::Contacts + KF5::AkonadiWidgets ) -install( TARGETS akonadi_birthdays_resource ${INSTALL_TARGETS_DEFAULT_ARGS} ) -install( FILES birthdaysresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) +install( TARGETS akonadi_birthdays_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} ) +install( FILES birthdaysresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) diff -Nru kdepim-runtime-4.14.6/resources/birthdays/configdialog.cpp kdepim-runtime-15.08.0/resources/birthdays/configdialog.cpp --- kdepim-runtime-4.14.6/resources/birthdays/configdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/birthdays/configdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,23 +20,39 @@ #include "configdialog.h" #include "settings.h" - +#include #include - -#include - -ConfigDialog::ConfigDialog(QWidget* parent) - : KDialog( parent ) -{ - ui.setupUi( mainWidget() ); - setWindowIcon( KIcon( QLatin1String("view-calendar-birthday") ) ); - mManager = new KConfigDialogManager( this, Settings::self() ); - mManager->updateWidgets(); - ui.kcfg_AlarmDays->setSuffix( ki18np( " day", " days" ) ); - - connect( this, SIGNAL(okClicked()), SLOT(save()) ); - loadTags(); - readConfig(); +#include +#include +#include +#include + +ConfigDialog::ConfigDialog(QWidget *parent) + : QDialog(parent) +{ + QWidget *mainWidget = new QWidget(this); + + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); + okButton->setDefault(true); + okButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &ConfigDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &ConfigDialog::reject); + okButton->setDefault(true); + + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); + mainLayout->addWidget(buttonBox); + ui.setupUi(mainWidget); + setWindowIcon(QIcon::fromTheme(QStringLiteral("view-calendar-birthday"))); + mManager = new KConfigDialogManager(this, Settings::self()); + mManager->updateWidgets(); + ui.kcfg_AlarmDays->setSuffix(ki18np(" day", " days")); + + connect(okButton, &QPushButton::clicked, this, &ConfigDialog::save); + loadTags(); + readConfig(); } ConfigDialog::~ConfigDialog() @@ -52,24 +68,25 @@ void ConfigDialog::save() { - mManager->updateSettings(); + mManager->updateSettings(); - Settings::self()->setFilterCategories(ui.FilterCategories->tagToStringList()); - Settings::self()->writeConfig(); + Settings::self()->setFilterCategories(ui.FilterCategories->tagToStringList()); + Settings::self()->save(); } void ConfigDialog::readConfig() { - KConfigGroup group( KGlobal::config(), "ConfigDialog" ); - const QSize size = group.readEntry( "Size", QSize(600, 400) ); - if ( size.isValid() ) { - resize( size ); + KConfigGroup group(KSharedConfig::openConfig(), "ConfigDialog"); + const QSize size = group.readEntry("Size", QSize(600, 400)); + if (size.isValid()) { + resize(size); } } void ConfigDialog::writeConfig() { - KConfigGroup group( KGlobal::config(), "ConfigDialog" ); - group.writeEntry( "Size", size() ); + KConfigGroup group(KSharedConfig::openConfig(), "ConfigDialog"); + group.writeEntry("Size", size()); group.sync(); } + diff -Nru kdepim-runtime-4.14.6/resources/birthdays/configdialog.h kdepim-runtime-15.08.0/resources/birthdays/configdialog.h --- kdepim-runtime-4.14.6/resources/birthdays/configdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/birthdays/configdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -23,26 +23,26 @@ #include "ui_configdialog.h" -#include +#include class KConfigDialogManager; -class ConfigDialog : public KDialog +class ConfigDialog : public QDialog { - Q_OBJECT - public: - ConfigDialog( QWidget *parent = 0 ); + Q_OBJECT +public: + explicit ConfigDialog(QWidget *parent = Q_NULLPTR); ~ConfigDialog(); - private slots: +private Q_SLOTS: void save(); - private: +private: void loadTags(); void readConfig(); void writeConfig(); Ui::ConfigDialog ui; - KConfigDialogManager* mManager; + KConfigDialogManager *mManager; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/birthdays/configdialog.ui kdepim-runtime-15.08.0/resources/birthdays/configdialog.ui --- kdepim-runtime-4.14.6/resources/birthdays/configdialog.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/birthdays/configdialog.ui 2015-08-10 21:01:02.000000000 +0000 @@ -40,7 +40,7 @@
- + false @@ -97,12 +97,12 @@ Akonadi::TagSelectWidget QWidget -
akonadi/tagselectwidget.h
+
AkonadiWidgets/tagselectwidget.h
- KIntSpinBox + KPluralHandlingSpinBox QSpinBox -
knuminput.h
+
KPluralHandlingSpinBox
diff -Nru kdepim-runtime-4.14.6/resources/cmake/FindXsltproc.cmake kdepim-runtime-15.08.0/resources/cmake/FindXsltproc.cmake --- kdepim-runtime-4.14.6/resources/cmake/FindXsltproc.cmake 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/cmake/FindXsltproc.cmake 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,32 @@ +# Find xsltproc executable and provide a macro to generate D-Bus interfaces. +# +# The following variables are defined : +# XSLTPROC_EXECUTABLE - path to the xsltproc executable +# Xsltproc_FOUND - true if the program was found +# +find_program(XSLTPROC_EXECUTABLE xsltproc DOC "Path to the xsltproc executable") +mark_as_advanced(XSLTPROC_EXECUTABLE) + +if(XSLTPROC_EXECUTABLE) + set(Xsltproc_FOUND TRUE) + + # We depend on kdepimlibs, make sure it's found + if(NOT DEFINED KF5Akonadi_DATA_DIR) + find_package(KF5Akonadi REQUIRED) + endif() + + + # Macro to generate a D-Bus interface description from a KConfigXT file + macro(kcfg_generate_dbus_interface _kcfg _name) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml + COMMAND ${XSLTPROC_EXECUTABLE} --stringparam interfaceName ${_name} + ${KF5Akonadi_DATA_DIR}/kcfg2dbus.xsl + ${_kcfg} + > ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml + DEPENDS ${KF5Akonadi_DATA_DIR}/kcfg2dbus.xsl + ${_kcfg} + ) + endmacro() +endif() + diff -Nru kdepim-runtime-4.14.6/resources/CMakeLists.txt kdepim-runtime-15.08.0/resources/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,80 +1,94 @@ +project(resources) +cmake_minimum_required(VERSION 2.8.12) + +set(AKONADICALENDAR_LIB_VERSION "4.78.0") +set(KMBOX_LIB_VERSION "4.78.0") + + +find_package(KF5AkonadiCalendar ${AKONADICALENDAR_LIB_VERSION} CONFIG REQUIRED) +find_package(KF5Mbox ${KMBOX_LIB_VERSION} CONFIG REQUIRED) + +# Extra package +find_package(KF5GAPI "4.74.0" CONFIG) + -#add_definitions( -DQT_NO_CAST_FROM_ASCII ) -#add_definitions( -DQT_NO_CAST_TO_ASCII ) + +# Xsltproc +find_package(Xsltproc) +set_package_properties(Xsltproc PROPERTIES DESCRIPTION "XSLT processor from libxslt" TYPE REQUIRED PURPOSE "Required to generate D-Bus interfaces for all Akonadi resources.") + +# Libkolab +find_package(Libkolab 1.0 QUIET CONFIG) +set_package_properties(Libkolab PROPERTIES DESCRIPTION "libkolab" URL "http://mirror.kolabsys.com/pub/releases" TYPE OPTIONAL PURPOSE "The Kolab Format libraries are required to build the Kolab Groupware Resource") + +# Libkolabxml +find_package(Libkolabxml 1.0 QUIET CONFIG) +set_package_properties(Libkolabxml PROPERTIES DESCRIPTION "Kolabxml" URL "http://mirror.kolabsys.com/pub/releases" TYPE OPTIONAL PURPOSE "The Kolab XML Format Schema Definitions Library is required to build the Kolab Groupware Resource") include_directories( - ${kdepim-runtime_SOURCE_DIR}/libkdepim-copy - ${CMAKE_CURRENT_SOURCE_DIR}/shared - ${CMAKE_CURRENT_BINARY_DIR}/shared + ${CMAKE_CURRENT_SOURCE_DIR}/shared/singlefileresource/ + ${CMAKE_CURRENT_BINARY_DIR}/shared/singlefileresource/ + ${CMAKE_CURRENT_SOURCE_DIR}/folderarchivesettings/ ) -set( AKONADI_SINGLEFILERESOURCE_SHARED_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/shared/singlefileresourcebase.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/shared/singlefileresourceconfigdialogbase.cpp -) -if (KDEPIM_MOBILE_UI) -set( AKONADI_SINGLEFILERESOURCE_SHARED_UI - ${CMAKE_CURRENT_SOURCE_DIR}/shared/singlefileresourceconfigdialog_mobile.ui - ${CMAKE_CURRENT_SOURCE_DIR}/shared/singlefileresourceconfigdialog.ui -) -else () -set( AKONADI_SINGLEFILERESOURCE_SHARED_UI - ${CMAKE_CURRENT_SOURCE_DIR}/shared/singlefileresourceconfigdialog_desktop.ui - ${CMAKE_CURRENT_SOURCE_DIR}/shared/singlefileresourceconfigdialog.ui -) -endif () +# resource tests +macro( akonadi_add_resourcetest _testname _script ) + if ( ${EXECUTABLE_OUTPUT_PATH} ) + set( _exepath ${EXECUTABLE_OUTPUT_PATH} ) + else () + set( _exepath ${kdepim-runtime_BINARY_DIR}/resourcetester ) + endif () + if (WIN32) + set(_resourcetester ${_exepath}/resourcetester.bat) + else () + set(_resourcetester ${_exepath}/resourcetester) + endif () + if (UNIX) + set(_resourcetester ${_resourcetester}.shell) + endif () + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${_script} ${CMAKE_CURRENT_BINARY_DIR}/${_script} COPYONLY) + if (KDEPIM_RUN_ISOLATED_TESTS) + add_test( akonadi-mysql-db-${_testname} akonaditest -c ${kdepim-runtime_SOURCE_DIR}/resourcetester/tests/unittestenv/config-mysql-db.xml ${_resourcetester} -c ${CMAKE_CURRENT_BINARY_DIR}/${_script} ) + endif () +endmacro( akonadi_add_resourcetest ) -set( AKONADI_COLLECTIONATTRIBUTES_SHARED_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/shared/collectionannotationsattribute.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/shared/collectionflagsattribute.cpp -) -set( AKONADI_IMAPATTRIBUTES_SHARED_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/shared/imapaclattribute.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/shared/imapquotaattribute.cpp -) + +#add_definitions( -DQT_NO_CAST_FROM_ASCII ) +#add_definitions( -DQT_NO_CAST_TO_ASCII ) add_subdirectory( akonotes ) add_subdirectory( kalarm ) add_subdirectory( contacts ) -macro_optional_add_subdirectory( dav ) +add_subdirectory( dav ) add_subdirectory( ical ) add_subdirectory( imap ) -if (KDEPIMLIBS_KRESOURCES_LIBS) - add_subdirectory( kabc ) - add_subdirectory( kcal ) -endif() -macro_optional_add_subdirectory( kdeaccounts ) if (Libkolab_FOUND AND Libkolabxml_FOUND) - macro_optional_add_subdirectory( kolabproxy ) add_subdirectory( kolab ) endif() -macro_optional_add_subdirectory( localbookmarks ) - add_subdirectory( maildir ) -macro_optional_add_subdirectory( openxchange ) +add_subdirectory( openxchange ) add_subdirectory( pop3 ) -if( LibKGAPI2_FOUND ) +if( KF5GAPI_FOUND ) add_subdirectory( google ) # Disabled in KDE 4.14 - too many issues for stable release #add_subdirectory( gmail ) endif() -if( LibKFbAPI_FOUND ) - add_subdirectory( facebook ) -endif() - add_subdirectory( shared ) add_subdirectory( birthdays ) add_subdirectory( mixedmaildir ) -add_subdirectory( mailtransport_dummy ) add_subdirectory( mbox ) -add_subdirectory( nntp ) add_subdirectory( vcarddir ) add_subdirectory( icaldir ) add_subdirectory( vcard ) add_subdirectory( folderarchivesettings ) + +if ("${CMAKE_SOURCE_DIR}" STREQUAL "${resources_SOURCE_DIR}") + feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) +endif() + diff -Nru kdepim-runtime-4.14.6/resources/contacts/CMakeLists.txt kdepim-runtime-15.08.0/resources/contacts/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/contacts/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/contacts/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,36 +1,33 @@ -include_directories( - ${kdepim-runtime_SOURCE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} -) -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) add_subdirectory( wizard ) +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_contacts_resource\") + ########### next target ############### set( contactsresource_SRCS contactsresource.cpp settingsdialog.cpp + contacts_resources_debug.cpp ) -kde4_add_ui_files(contactsresource_SRCS settingsdialog.ui) -kde4_add_kcfg_files(contactsresource_SRCS settings.kcfgc) +ki18n_wrap_ui(contactsresource_SRCS settingsdialog.ui) +kconfig_add_kcfg_files(contactsresource_SRCS settings.kcfgc) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/contactsresource.kcfg org.kde.Akonadi.Contacts.Settings) -qt4_add_dbus_adaptor(contactsresource_SRCS +qt5_add_dbus_adaptor(contactsresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.Contacts.Settings.xml settings.h Akonadi_Contacts_Resource::ContactsResourceSettings contactsresourcesettingsadaptor ContactsResourceSettingsAdaptor ) -install( FILES contactsresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) +install( FILES contactsresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) -kde4_add_plugin(akonadi_contacts_resource ${contactsresource_SRCS}) +add_executable(akonadi_contacts_resource ${contactsresource_SRCS}) target_link_libraries(akonadi_contacts_resource - ${KDEPIMLIBS_AKONADI_LIBS} - ${QT_QTCORE_LIBRARY} - ${KDE4_KDECORE_LIBS} - ${KDEPIMLIBS_KABC_LIBS} - ${KDE4_KIO_LIBS} + KF5::AkonadiCore + KF5::AkonadiAgentBase + KF5::Contacts + KF5::DBusAddons ) -install(TARGETS akonadi_contacts_resource DESTINATION ${PLUGIN_INSTALL_DIR}) +install(TARGETS akonadi_contacts_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/contacts/contactsresource.cpp kdepim-runtime-15.08.0/resources/contacts/contactsresource.cpp --- kdepim-runtime-4.14.6/resources/contacts/contactsresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/contacts/contactsresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -27,508 +27,525 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include "contacts_resources_debug.h" + +#include using namespace Akonadi; using namespace Akonadi_Contacts_Resource; -ContactsResource::ContactsResource( const QString &id ) - : ResourceBase( id ), - mSettings( new ContactsResourceSettings( componentData().config() ) ) -{ - // setup the resource - new ContactsResourceSettingsAdaptor( mSettings ); - DBusConnectionPool::threadConnection().registerObject( QLatin1String( "/Settings" ), - mSettings, QDBusConnection::ExportAdaptors ); - - changeRecorder()->fetchCollection( true ); - changeRecorder()->itemFetchScope().fetchFullPayload( true ); - changeRecorder()->itemFetchScope().setAncestorRetrieval( ItemFetchScope::All ); - changeRecorder()->collectionFetchScope().setAncestorRetrieval( CollectionFetchScope::All ); +ContactsResource::ContactsResource(const QString &id) + : ResourceBase(id), + mSettings(new ContactsResourceSettings(componentData().config())) +{ + // setup the resource + new ContactsResourceSettingsAdaptor(mSettings); + KDBusConnectionPool::threadConnection().registerObject(QStringLiteral("/Settings"), + mSettings, QDBusConnection::ExportAdaptors); + + changeRecorder()->fetchCollection(true); + changeRecorder()->itemFetchScope().fetchFullPayload(true); + changeRecorder()->itemFetchScope().setAncestorRetrieval(ItemFetchScope::All); + changeRecorder()->collectionFetchScope().setAncestorRetrieval(CollectionFetchScope::All); - setHierarchicalRemoteIdentifiersEnabled( true ); + setHierarchicalRemoteIdentifiersEnabled(true); - mSupportedMimeTypes << KABC::Addressee::mimeType() << KABC::ContactGroup::mimeType() << Collection::mimeType(); + mSupportedMimeTypes << KContacts::Addressee::mimeType() << KContacts::ContactGroup::mimeType() << Collection::mimeType(); - if ( name().startsWith( QLatin1String( "akonadi_contacts_resource" ) ) ) - setName( i18n( "Personal Contacts" ) ); + if (name().startsWith(QLatin1String("akonadi_contacts_resource"))) { + setName(i18n("Personal Contacts")); + } - // Make sure we have a valid directory (XDG dirs want this very much). - initializeDirectory(mSettings->path()); + // Make sure we have a valid directory (XDG dirs want this very much). + initializeDirectory(mSettings->path()); - if ( mSettings->isConfigured() ) - synchronize(); + if (mSettings->isConfigured()) { + synchronize(); + } } ContactsResource::~ContactsResource() { - delete mSettings; + delete mSettings; } void ContactsResource::aboutToQuit() { } -void ContactsResource::configure( WId windowId ) +void ContactsResource::configure(WId windowId) { - QPointer dlg = new SettingsDialog( mSettings, windowId ); - if ( dlg->exec() ) { - mSettings->setIsConfigured( true ); - mSettings->writeConfig(); + QPointer dlg = new SettingsDialog(mSettings, windowId); + if (dlg->exec()) { + mSettings->setIsConfigured(true); + mSettings->save(); - clearCache(); - initializeDirectory( baseDirectoryPath() ); + clearCache(); + initializeDirectory(baseDirectoryPath()); - synchronize(); + synchronize(); - emit configurationDialogAccepted(); - } else { - emit configurationDialogRejected(); - } - delete dlg; + Q_EMIT configurationDialogAccepted(); + } else { + Q_EMIT configurationDialogRejected(); + } + delete dlg; } -Collection::List ContactsResource::createCollectionsForDirectory( const QDir &parentDirectory, const Collection &parentCollection ) const +Collection::List ContactsResource::createCollectionsForDirectory(const QDir &parentDirectory, const Collection &parentCollection) const { - Collection::List collections; + Collection::List collections; - QDir dir( parentDirectory ); - dir.setFilter( QDir::Dirs | QDir::NoDotAndDotDot | QDir::Readable ); - const QFileInfoList entries = dir.entryInfoList(); + QDir dir(parentDirectory); + dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Readable); + const QFileInfoList entries = dir.entryInfoList(); + collections.reserve(entries.count() * 2); - foreach ( const QFileInfo &entry, entries ) { - QDir subdir( entry.absoluteFilePath() ); + foreach (const QFileInfo &entry, entries) { + QDir subdir(entry.absoluteFilePath()); - Collection collection; - collection.setParentCollection( parentCollection ); - collection.setRemoteId( entry.fileName() ); - collection.setName( entry.fileName() ); - collection.setContentMimeTypes( mSupportedMimeTypes ); - collection.setRights( supportedRights( false ) ); + Collection collection; + collection.setParentCollection(parentCollection); + collection.setRemoteId(entry.fileName()); + collection.setName(entry.fileName()); + collection.setContentMimeTypes(mSupportedMimeTypes); + collection.setRights(supportedRights(false)); - collections << collection; - collections << createCollectionsForDirectory( subdir, collection ); - } + collections << collection; + collections << createCollectionsForDirectory(subdir, collection); + } - return collections; + return collections; } void ContactsResource::retrieveCollections() { - // create the resource collection - Collection resourceCollection; - resourceCollection.setParentCollection( Collection::root() ); - resourceCollection.setRemoteId( baseDirectoryPath() ); - resourceCollection.setName( name() ); - resourceCollection.setContentMimeTypes( mSupportedMimeTypes ); - resourceCollection.setRights( supportedRights( true ) ); + // create the resource collection + Collection resourceCollection; + resourceCollection.setParentCollection(Collection::root()); + resourceCollection.setRemoteId(baseDirectoryPath()); + resourceCollection.setName(name()); + resourceCollection.setContentMimeTypes(mSupportedMimeTypes); + resourceCollection.setRights(supportedRights(true)); - const QDir baseDir( baseDirectoryPath() ); + const QDir baseDir(baseDirectoryPath()); - Collection::List collections = createCollectionsForDirectory( baseDir, resourceCollection ); - collections.append( resourceCollection ); + Collection::List collections = createCollectionsForDirectory(baseDir, resourceCollection); + collections.append(resourceCollection); - collectionsRetrieved( collections ); + collectionsRetrieved(collections); } -void ContactsResource::retrieveItems( const Akonadi::Collection &collection ) +void ContactsResource::retrieveItems(const Akonadi::Collection &collection) { - QDir directory( directoryForCollection( collection ) ); - if ( !directory.exists() ) { - cancelTask( i18n( "Directory '%1' does not exists", collection.remoteId() ) ); - return; - } - - directory.setFilter( QDir::Files | QDir::Readable ); + QDir directory(directoryForCollection(collection)); + if (!directory.exists()) { + cancelTask(i18n("Directory '%1' does not exists", collection.remoteId())); + return; + } - Item::List items; + directory.setFilter(QDir::Files | QDir::Readable); - const QFileInfoList entries = directory.entryInfoList(); + Item::List items; - foreach ( const QFileInfo &entry, entries ) { - if ( entry.fileName() == QLatin1String("WARNING_README.txt") ) - continue; + const QFileInfoList entries = directory.entryInfoList(); - Item item; - item.setRemoteId( entry.fileName() ); + foreach (const QFileInfo &entry, entries) { + if (entry.fileName() == QLatin1String("WARNING_README.txt")) { + continue; + } + + Item item; + item.setRemoteId(entry.fileName()); + + if (entry.fileName().endsWith(QLatin1String(".vcf"))) { + item.setMimeType(KContacts::Addressee::mimeType()); + } else if (entry.fileName().endsWith(QLatin1String(".ctg"))) { + item.setMimeType(KContacts::ContactGroup::mimeType()); + } else { + cancelTask(i18n("Found file of unknown format: '%1'", entry.absoluteFilePath())); + return; + } - if ( entry.fileName().endsWith( QLatin1String( ".vcf" ) ) ) - item.setMimeType( KABC::Addressee::mimeType() ); - else if ( entry.fileName().endsWith( QLatin1String( ".ctg" ) ) ) - item.setMimeType( KABC::ContactGroup::mimeType() ); - else { - cancelTask( i18n( "Found file of unknown format: '%1'", entry.absoluteFilePath() ) ); - return; + items.append(item); } - items.append( item ); - } - - itemsRetrieved( items ); + itemsRetrieved(items); } -bool ContactsResource::retrieveItem( const Akonadi::Item &item, const QSet& ) +bool ContactsResource::retrieveItem(const Akonadi::Item &item, const QSet &) { - const QString filePath = directoryForCollection( item.parentCollection() ) + QDir::separator() + item.remoteId(); - - Item newItem( item ); + const QString filePath = directoryForCollection(item.parentCollection()) + QDir::separator() + item.remoteId(); - QFile file( filePath ); - if ( !file.open( QIODevice::ReadOnly ) ) { - cancelTask( i18n( "Unable to open file '%1'", filePath ) ); - return false; - } + Item newItem(item); - if ( filePath.endsWith( QLatin1String( ".vcf" ) ) ) { - KABC::VCardConverter converter; - - const QByteArray content = file.readAll(); - const KABC::Addressee contact = converter.parseVCard( content ); - if ( contact.isEmpty() ) { - cancelTask( i18n( "Found invalid contact in file '%1'", filePath ) ); - return false; + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) { + cancelTask(i18n("Unable to open file '%1'", filePath)); + return false; } - newItem.setPayload( contact ); - } else if ( filePath.endsWith( QLatin1String( ".ctg" ) ) ) { - KABC::ContactGroup group; - QString errorMessage; + if (filePath.endsWith(QLatin1String(".vcf"))) { + KContacts::VCardConverter converter; - if ( !KABC::ContactGroupTool::convertFromXml( &file, group, &errorMessage ) ) { - cancelTask( i18n( "Found invalid contact group in file '%1': %2", filePath, errorMessage ) ); - return false; - } + const QByteArray content = file.readAll(); + const KContacts::Addressee contact = converter.parseVCard(content); + if (contact.isEmpty()) { + cancelTask(i18n("Found invalid contact in file '%1'", filePath)); + return false; + } + + newItem.setPayload(contact); + } else if (filePath.endsWith(QLatin1String(".ctg"))) { + KContacts::ContactGroup group; + QString errorMessage; + + if (!KContacts::ContactGroupTool::convertFromXml(&file, group, &errorMessage)) { + cancelTask(i18n("Found invalid contact group in file '%1': %2", filePath, errorMessage)); + return false; + } - newItem.setPayload( group ); - } else { - cancelTask( i18n( "Found file of unknown format: '%1'", filePath ) ); - return false; - } + newItem.setPayload(group); + } else { + cancelTask(i18n("Found file of unknown format: '%1'", filePath)); + return false; + } - file.close(); + file.close(); - itemRetrieved( newItem ); + itemRetrieved(newItem); - return true; + return true; } -void ContactsResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ) +void ContactsResource::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) { - if ( mSettings->readOnly() ) { - cancelTask( i18n( "Trying to write to a read-only directory: '%1'", collection.remoteId() ) ); - return; - } + if (mSettings->readOnly()) { + cancelTask(i18n("Trying to write to a read-only directory: '%1'", collection.remoteId())); + return; + } - const QString directoryPath = directoryForCollection( collection ); + const QString directoryPath = directoryForCollection(collection); - Item newItem( item ); + Item newItem(item); - if ( item.hasPayload() ) { - const KABC::Addressee contact = item.payload(); + if (item.hasPayload()) { + const KContacts::Addressee contact = item.payload(); - const QString fileName = directoryPath + QDir::separator() + contact.uid() + QLatin1String(".vcf"); + const QString fileName = directoryPath + QDir::separator() + contact.uid() + QLatin1String(".vcf"); - KABC::VCardConverter converter; - const QByteArray content = converter.createVCard( contact ); + KContacts::VCardConverter converter; + const QByteArray content = converter.createVCard(contact); - QFile file( fileName ); - if ( !file.open( QIODevice::WriteOnly ) ) { - cancelTask( i18n( "Unable to write to file '%1': %2", fileName, file.errorString() ) ); - return; - } + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) { + cancelTask(i18n("Unable to write to file '%1': %2", fileName, file.errorString())); + return; + } - file.write( content ); - file.close(); + file.write(content); + file.close(); - newItem.setRemoteId( contact.uid() + QLatin1String(".vcf") ); + newItem.setRemoteId(contact.uid() + QLatin1String(".vcf")); - } else if ( item.hasPayload() ) { - const KABC::ContactGroup group = item.payload(); + } else if (item.hasPayload()) { + const KContacts::ContactGroup group = item.payload(); - const QString fileName = directoryPath + QDir::separator() + group.id() + QLatin1String(".ctg"); + const QString fileName = directoryPath + QDir::separator() + group.id() + QLatin1String(".ctg"); - QFile file( fileName ); - if ( !file.open( QIODevice::WriteOnly ) ) { - cancelTask( i18n( "Unable to write to file '%1': %2", fileName, file.errorString() ) ); - return; - } + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) { + cancelTask(i18n("Unable to write to file '%1': %2", fileName, file.errorString())); + return; + } - KABC::ContactGroupTool::convertToXml( group, &file ); + KContacts::ContactGroupTool::convertToXml(group, &file); - file.close(); + file.close(); - newItem.setRemoteId( group.id() + QLatin1String(".ctg") ); + newItem.setRemoteId(group.id() + QLatin1String(".ctg")); - } else { - kWarning() << "got item without (usable) payload, ignoring it"; - } + } else { + qCWarning(CONTACTSRESOURCES_LOG) << "got item without (usable) payload, ignoring it"; + } - changeCommitted( newItem ); + changeCommitted(newItem); } -void ContactsResource::itemChanged( const Akonadi::Item &item, const QSet& ) +void ContactsResource::itemChanged(const Akonadi::Item &item, const QSet &) { - if ( mSettings->readOnly() ) { - cancelTask( i18n( "Trying to write to a read-only file: '%1'", item.remoteId() ) ); - return; - } + if (mSettings->readOnly()) { + cancelTask(i18n("Trying to write to a read-only file: '%1'", item.remoteId())); + return; + } - Item newItem( item ); + Item newItem(item); - const QString fileName = directoryForCollection( item.parentCollection() ) + QDir::separator() + item.remoteId(); + const QString fileName = directoryForCollection(item.parentCollection()) + QDir::separator() + item.remoteId(); - if ( item.hasPayload() ) { - const KABC::Addressee contact = item.payload(); + if (item.hasPayload()) { + const KContacts::Addressee contact = item.payload(); - KABC::VCardConverter converter; - const QByteArray content = converter.createVCard( contact ); + KContacts::VCardConverter converter; + const QByteArray content = converter.createVCard(contact); - QFile file( fileName ); - if ( !file.open( QIODevice::WriteOnly ) ) { - cancelTask( i18n( "Unable to write to file '%1': %2", fileName, file.errorString() ) ); - return; - } - file.write( content ); - file.close(); + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) { + cancelTask(i18n("Unable to write to file '%1': %2", fileName, file.errorString())); + return; + } + file.write(content); + file.close(); - newItem.setRemoteId( item.remoteId() ); + newItem.setRemoteId(item.remoteId()); - } else if ( item.hasPayload() ) { - const KABC::ContactGroup group = item.payload(); + } else if (item.hasPayload()) { + const KContacts::ContactGroup group = item.payload(); - QFile file( fileName ); - if ( !file.open( QIODevice::WriteOnly ) ) { - cancelTask( i18n( "Unable to write to file '%1': %2", fileName, file.errorString() ) ); - return; - } + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) { + cancelTask(i18n("Unable to write to file '%1': %2", fileName, file.errorString())); + return; + } - KABC::ContactGroupTool::convertToXml( group, &file ); + KContacts::ContactGroupTool::convertToXml(group, &file); - file.close(); + file.close(); - newItem.setRemoteId( item.remoteId() ); + newItem.setRemoteId(item.remoteId()); - } else { - cancelTask( i18n( "Received item with unknown payload %1", item.mimeType() ) ); - return; - } + } else { + cancelTask(i18n("Received item with unknown payload %1", item.mimeType())); + return; + } - changeCommitted( newItem ); + changeCommitted(newItem); } -void ContactsResource::itemRemoved( const Akonadi::Item &item ) +void ContactsResource::itemRemoved(const Akonadi::Item &item) { - if ( mSettings->readOnly() ) { - cancelTask( i18n( "Trying to write to a read-only file: '%1'", item.remoteId() ) ); - return; - } + if (mSettings->readOnly()) { + cancelTask(i18n("Trying to write to a read-only file: '%1'", item.remoteId())); + return; + } - // If the parent collection has no valid remote id, the parent - // collection will be removed in a second, so stop here and remove - // all items in collectionRemoved(). - if ( item.parentCollection().remoteId().isEmpty() ) { - changeProcessed(); - return; - } + // If the parent collection has no valid remote id, the parent + // collection will be removed in a second, so stop here and remove + // all items in collectionRemoved(). + if (item.parentCollection().remoteId().isEmpty()) { + changeProcessed(); + return; + } - const QString fileName = directoryForCollection( item.parentCollection() ) + QDir::separator() + item.remoteId(); + const QString fileName = directoryForCollection(item.parentCollection()) + QDir::separator() + item.remoteId(); - if ( !QFile::remove( fileName ) ) { - cancelTask( i18n( "Unable to remove file '%1'", fileName ) ); - return; - } + if (!QFile::remove(fileName)) { + cancelTask(i18n("Unable to remove file '%1'", fileName)); + return; + } - changeProcessed(); + changeProcessed(); } -void ContactsResource::collectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection &parent ) +void ContactsResource::collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent) { - if ( mSettings->readOnly() ) { - cancelTask( i18n( "Trying to write to a read-only directory: '%1'", parent.remoteId() ) ); - return; - } + if (mSettings->readOnly()) { + cancelTask(i18n("Trying to write to a read-only directory: '%1'", parent.remoteId())); + return; + } - const QString dirName = directoryForCollection( parent ) + QDir::separator() + collection.name(); + const QString dirName = directoryForCollection(parent) + QDir::separator() + collection.name(); - if ( !QDir::root().mkpath( dirName ) ) { - cancelTask( i18n( "Unable to create folder '%1'.", dirName ) ); - return; - } + if (!QDir::root().mkpath(dirName)) { + cancelTask(i18n("Unable to create folder '%1'.", dirName)); + return; + } - initializeDirectory( dirName ); + initializeDirectory(dirName); - Collection newCollection( collection ); - newCollection.setRemoteId( collection.name() ); - changeCommitted( newCollection ); + Collection newCollection(collection); + newCollection.setRemoteId(collection.name()); + changeCommitted(newCollection); } -void ContactsResource::collectionChanged( const Akonadi::Collection &collection ) +void ContactsResource::collectionChanged(const Akonadi::Collection &collection) { - if ( mSettings->readOnly() ) { - cancelTask( i18n( "Trying to write to a read-only directory: '%1'", collection.remoteId() ) ); - return; - } + if (mSettings->readOnly()) { + cancelTask(i18n("Trying to write to a read-only directory: '%1'", collection.remoteId())); + return; + } - if ( collection.parentCollection() == Collection::root() ) { - if ( collection.name() != name() ) - setName( collection.name() ); - changeProcessed(); - return; - } + if (collection.parentCollection() == Collection::root()) { + if (collection.name() != name()) { + setName(collection.name()); + } + changeProcessed(); + return; + } - if ( collection.remoteId() == collection.name() ) { - changeProcessed(); - return; - } + if (collection.remoteId() == collection.name()) { + changeProcessed(); + return; + } - const QString dirName = directoryForCollection( collection ); + const QString dirName = directoryForCollection(collection); - QFileInfo oldDirectory( dirName ); - if ( !QDir::root().rename( dirName, oldDirectory.absolutePath() + QDir::separator() + collection.name() ) ) { - cancelTask( i18n( "Unable to rename folder '%1'.", collection.name() ) ); - return; - } - - Collection newCollection( collection ); - newCollection.setRemoteId( collection.name() ); - changeCommitted( newCollection ); + QFileInfo oldDirectory(dirName); + if (!QDir::root().rename(dirName, oldDirectory.absolutePath() + QDir::separator() + collection.name())) { + cancelTask(i18n("Unable to rename folder '%1'.", collection.name())); + return; + } + + Collection newCollection(collection); + newCollection.setRemoteId(collection.name()); + changeCommitted(newCollection); } /** * Removes a @p directory recursively. */ -static bool removeDirectory( const QDir &directory ) +static bool removeDirectory(const QDir &directory) { - const QFileInfoList infoList = - directory.entryInfoList( QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot ); + const QFileInfoList infoList = + directory.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); - foreach ( const QFileInfo &info, infoList ) { - if ( info.isDir() ) { - if ( !removeDirectory( QDir( info.absoluteFilePath() ) ) ) - return false; - } else { - if ( !QFile::remove( info.filePath() ) ) - return false; + foreach (const QFileInfo &info, infoList) { + if (info.isDir()) { + if (!removeDirectory(QDir(info.absoluteFilePath()))) { + return false; + } + } else { + if (!QFile::remove(info.filePath())) { + return false; + } + } } - } - if ( !QDir::root().rmdir( directory.absolutePath() ) ) - return false; + if (!QDir::root().rmdir(directory.absolutePath())) { + return false; + } - return true; + return true; } -void ContactsResource::collectionRemoved( const Akonadi::Collection &collection ) +void ContactsResource::collectionRemoved(const Akonadi::Collection &collection) { - if ( mSettings->readOnly() ) { - cancelTask( i18n( "Trying to write to a read-only directory: '%1'", collection.remoteId() ) ); - return; - } + if (mSettings->readOnly()) { + cancelTask(i18n("Trying to write to a read-only directory: '%1'", collection.remoteId())); + return; + } - if ( !removeDirectory( directoryForCollection( collection ) ) ) { - cancelTask( i18n( "Unable to delete folder '%1'.", collection.name() ) ); - return; - } + if (!removeDirectory(directoryForCollection(collection))) { + cancelTask(i18n("Unable to delete folder '%1'.", collection.name())); + return; + } - changeProcessed(); + changeProcessed(); } -void ContactsResource::itemMoved( const Akonadi::Item &item, const Akonadi::Collection &collectionSource, - const Akonadi::Collection &collectionDestination ) +void ContactsResource::itemMoved(const Akonadi::Item &item, const Akonadi::Collection &collectionSource, + const Akonadi::Collection &collectionDestination) { - const QString sourceFileName = directoryForCollection( collectionSource ) + QDir::separator() + item.remoteId(); - const QString targetFileName = directoryForCollection( collectionDestination ) + QDir::separator() + item.remoteId(); + const QString sourceFileName = directoryForCollection(collectionSource) + QDir::separator() + item.remoteId(); + const QString targetFileName = directoryForCollection(collectionDestination) + QDir::separator() + item.remoteId(); - if ( QFile::rename( sourceFileName, targetFileName ) ) - changeProcessed(); - else - cancelTask( i18n( "Unable to move file '%1' to '%2', '%2' already exists.", sourceFileName, targetFileName ) ); + if (QFile::rename(sourceFileName, targetFileName)) { + changeProcessed(); + } else { + cancelTask(i18n("Unable to move file '%1' to '%2', '%2' already exists.", sourceFileName, targetFileName)); + } } -void ContactsResource::collectionMoved( const Akonadi::Collection &collection, const Akonadi::Collection &collectionSource, - const Akonadi::Collection &collectionDestination ) +void ContactsResource::collectionMoved(const Akonadi::Collection &collection, const Akonadi::Collection &collectionSource, + const Akonadi::Collection &collectionDestination) { - const QString sourceDirectoryName = directoryForCollection( collectionSource ) + QDir::separator() + collection.remoteId(); - const QString targetDirectoryName = directoryForCollection( collectionDestination ) + QDir::separator() + collection.remoteId(); + const QString sourceDirectoryName = directoryForCollection(collectionSource) + QDir::separator() + collection.remoteId(); + const QString targetDirectoryName = directoryForCollection(collectionDestination) + QDir::separator() + collection.remoteId(); - if ( QFile::rename( sourceDirectoryName, targetDirectoryName ) ) - changeProcessed(); - else - cancelTask( i18n( "Unable to move directory '%1' to '%2', '%2' already exists.", sourceDirectoryName, targetDirectoryName ) ); + if (QFile::rename(sourceDirectoryName, targetDirectoryName)) { + changeProcessed(); + } else { + cancelTask(i18n("Unable to move directory '%1' to '%2', '%2' already exists.", sourceDirectoryName, targetDirectoryName)); + } } QString ContactsResource::baseDirectoryPath() const { - return mSettings->path(); + return mSettings->path(); } -void ContactsResource::initializeDirectory( const QString &path ) const +void ContactsResource::initializeDirectory(const QString &path) const { - QDir dir( path ); + QDir dir(path); - // if folder does not exists, create it - if ( !dir.exists() ) - QDir::root().mkpath( dir.absolutePath() ); + // if folder does not exists, create it + if (!dir.exists()) { + QDir::root().mkpath(dir.absolutePath()); + } - // check whether warning file is in place... - QFile file( dir.absolutePath() + QDir::separator() + QLatin1String("WARNING_README.txt") ); - if ( !file.exists() ) { - // ... if not, create it - file.open( QIODevice::WriteOnly ); - file.write( "Important Warning!!!\n\n" - "Don't create or copy vCards inside this folder manually, they are managed by the Akonadi framework!\n" ); - file.close(); - } + // check whether warning file is in place... + QFile file(dir.absolutePath() + QDir::separator() + QLatin1String("WARNING_README.txt")); + if (!file.exists()) { + // ... if not, create it + file.open(QIODevice::WriteOnly); + file.write("Important Warning!!!\n\n" + "Don't create or copy vCards inside this folder manually, they are managed by the Akonadi framework!\n"); + file.close(); + } } -Collection::Rights ContactsResource::supportedRights( bool isResourceCollection ) const +Collection::Rights ContactsResource::supportedRights(bool isResourceCollection) const { - Collection::Rights rights = Collection::ReadOnly; - - if ( !mSettings->readOnly() ) { - rights |= Collection::CanChangeItem; - rights |= Collection::CanCreateItem; - rights |= Collection::CanDeleteItem; - rights |= Collection::CanCreateCollection; - rights |= Collection::CanChangeCollection; + Collection::Rights rights = Collection::ReadOnly; - if ( !isResourceCollection ) - rights |= Collection::CanDeleteCollection; - } + if (!mSettings->readOnly()) { + rights |= Collection::CanChangeItem; + rights |= Collection::CanCreateItem; + rights |= Collection::CanDeleteItem; + rights |= Collection::CanCreateCollection; + rights |= Collection::CanChangeCollection; + + if (!isResourceCollection) { + rights |= Collection::CanDeleteCollection; + } + } - return rights; + return rights; } -QString ContactsResource::directoryForCollection( const Collection& collection ) const +QString ContactsResource::directoryForCollection(const Collection &collection) const { - if ( collection.remoteId().isEmpty() ) { - kWarning() << "Got incomplete ancestor chain:" << collection; - return QString(); - } + if (collection.remoteId().isEmpty()) { + qCWarning(CONTACTSRESOURCES_LOG) << "Got incomplete ancestor chain:" << collection; + return QString(); + } - if ( collection.parentCollection() == Collection::root() ) { - kWarning( collection.remoteId() != baseDirectoryPath() ) << "RID mismatch, is " << collection.remoteId() - << " expected " << baseDirectoryPath(); - return collection.remoteId(); - } + if (collection.parentCollection() == Collection::root()) { + if (collection.remoteId() != baseDirectoryPath()) + qCWarning(CONTACTSRESOURCES_LOG) << "RID mismatch, is " << collection.remoteId() + << " expected " << baseDirectoryPath(); + return collection.remoteId(); + } - const QString parentDirectory = directoryForCollection( collection.parentCollection() ); - if ( parentDirectory.isNull() ) // invalid, != isEmpty() here! - return QString(); + const QString parentDirectory = directoryForCollection(collection.parentCollection()); + if (parentDirectory.isNull()) { // invalid, != isEmpty() here! + return QString(); + } - QString directory = parentDirectory; - if ( !directory.endsWith( QLatin1Char('/') ) ) - directory += QDir::separator() + collection.remoteId(); - else - directory += collection.remoteId(); + QString directory = parentDirectory; + if (!directory.endsWith(QLatin1Char('/'))) { + directory += QDir::separator() + collection.remoteId(); + } else { + directory += collection.remoteId(); + } - return directory; + return directory; } -AKONADI_AGENT_FACTORY( ContactsResource, akonadi_contacts_resource ) - +AKONADI_RESOURCE_MAIN(ContactsResource) diff -Nru kdepim-runtime-4.14.6/resources/contacts/contactsresource.desktop kdepim-runtime-15.08.0/resources/contacts/contactsresource.desktop --- kdepim-runtime-4.14.6/resources/contacts/contactsresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/contacts/contactsresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -97,4 +97,3 @@ X-Akonadi-MimeTypes=text/directory,application/x-vnd.kde.contactgroup X-Akonadi-Capabilities=Resource X-Akonadi-Identifier=akonadi_contacts_resource -X-Akonadi-LaunchMethod=AgentServer diff -Nru kdepim-runtime-4.14.6/resources/contacts/contactsresource.h kdepim-runtime-15.08.0/resources/contacts/contactsresource.h --- kdepim-runtime-4.14.6/resources/contacts/contactsresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/contacts/contactsresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,61 +20,62 @@ #ifndef CONTACTSRESOURCE_H #define CONTACTSRESOURCE_H -#include +#include -#include -#include -#include -#include +#include +#include +#include +#include -namespace Akonadi_Contacts_Resource { +namespace Akonadi_Contacts_Resource +{ class ContactsResourceSettings; } class QDir; class ContactsResource : public Akonadi::ResourceBase, public Akonadi::AgentBase::ObserverV2 { - Q_OBJECT + Q_OBJECT - public: - ContactsResource( const QString &id ); +public: + explicit ContactsResource(const QString &id); ~ContactsResource(); - public Q_SLOTS: - virtual void configure( WId windowId ); - virtual void aboutToQuit(); - - protected Q_SLOTS: - void retrieveCollections(); - void retrieveItems( const Akonadi::Collection &collection ); - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - - protected: - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); - virtual void itemRemoved( const Akonadi::Item &item ); +public Q_SLOTS: + void configure(WId windowId) Q_DECL_OVERRIDE; + void aboutToQuit() Q_DECL_OVERRIDE; + +protected Q_SLOTS: + void retrieveCollections() Q_DECL_OVERRIDE; + void retrieveItems(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + bool retrieveItem(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + +protected: + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + void itemRemoved(const Akonadi::Item &item) Q_DECL_OVERRIDE; - virtual void collectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection &parent ); - virtual void collectionChanged( const Akonadi::Collection &collection ); + void collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent) Q_DECL_OVERRIDE; + void collectionChanged(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; // do not hide the other variant, use implementation from base class // which just forwards to the one above using Akonadi::AgentBase::ObserverV2::collectionChanged; - virtual void collectionRemoved( const Akonadi::Collection &collection ); + void collectionRemoved(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; - virtual void itemMoved( const Akonadi::Item &item, const Akonadi::Collection &collectionSource, - const Akonadi::Collection &collectionDestination ); - virtual void collectionMoved( const Akonadi::Collection &collection, const Akonadi::Collection &collectionSource, - const Akonadi::Collection &collectionDestination ); - - private: - Akonadi::Collection::List createCollectionsForDirectory( const QDir &parentDirectory, - const Akonadi::Collection &parentCollection ) const; + void itemMoved(const Akonadi::Item &item, const Akonadi::Collection &collectionSource, + const Akonadi::Collection &collectionDestination) Q_DECL_OVERRIDE; + void collectionMoved(const Akonadi::Collection &collection, const Akonadi::Collection &collectionSource, + const Akonadi::Collection &collectionDestination) Q_DECL_OVERRIDE; + +private: + Akonadi::Collection::List createCollectionsForDirectory(const QDir &parentDirectory, + const Akonadi::Collection &parentCollection) const; QString baseDirectoryPath() const; - void initializeDirectory( const QString &path ) const; - Akonadi::Collection::Rights supportedRights( bool isResourceCollection ) const; - QString directoryForCollection( const Akonadi::Collection& collection ) const; + void initializeDirectory(const QString &path) const; + Akonadi::Collection::Rights supportedRights(bool isResourceCollection) const; + QString directoryForCollection(const Akonadi::Collection &collection) const; - private: +private: QStringList mSupportedMimeTypes; Akonadi_Contacts_Resource::ContactsResourceSettings *mSettings; }; diff -Nru kdepim-runtime-4.14.6/resources/contacts/contacts_resources_debug.cpp kdepim-runtime-15.08.0/resources/contacts/contacts_resources_debug.cpp --- kdepim-runtime-4.14.6/resources/contacts/contacts_resources_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/contacts/contacts_resources_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2015 Laurent Montel + + 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 "contacts_resources_debug.h" +Q_LOGGING_CATEGORY(CONTACTSRESOURCES_LOG, "log_resources_contacts") + diff -Nru kdepim-runtime-4.14.6/resources/contacts/contacts_resources_debug.h kdepim-runtime-15.08.0/resources/contacts/contacts_resources_debug.h --- kdepim-runtime-4.14.6/resources/contacts/contacts_resources_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/contacts/contacts_resources_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2015 Laurent Montel + + 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 CONTACTS_RESOURCES_DEBUG_H +#define CONTACTS_RESOURCES_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(CONTACTSRESOURCES_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/contacts/settingsdialog.cpp kdepim-runtime-15.08.0/resources/contacts/settingsdialog.cpp --- kdepim-runtime-4.14.6/resources/contacts/settingsdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/contacts/settingsdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,33 +24,50 @@ #include #include - +#include +#include +#include +#include +#include +#include using namespace Akonadi; using namespace Akonadi_Contacts_Resource; -SettingsDialog::SettingsDialog( ContactsResourceSettings *settings, WId windowId ) - : KDialog(), - mSettings( settings ) -{ - ui.setupUi( mainWidget() ); - setWindowIcon( KIcon( QLatin1String("text-directory") ) ); - ui.kcfg_Path->setMode( KFile::LocalOnly | KFile::Directory ); - setButtons( Ok | Cancel ); +SettingsDialog::SettingsDialog(ContactsResourceSettings *settings, WId windowId) + : QDialog(), + mSettings(settings) +{ + QWidget *mainWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); + ui.setupUi(mainWidget); + setWindowIcon(QIcon::fromTheme(QStringLiteral("text-directory"))); + ui.kcfg_Path->setMode(KFile::LocalOnly | KFile::Directory); + + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + mOkButton = buttonBox->button(QDialogButtonBox::Ok); + mOkButton->setDefault(true); + mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &SettingsDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &SettingsDialog::reject); + mainLayout->addWidget(buttonBox); - if ( windowId ) - KWindowSystem::setMainWindow( this, windowId ); + if (windowId) { + KWindowSystem::setMainWindow(this, windowId); + } - connect( this, SIGNAL(okClicked()), SLOT(save()) ); + connect(mOkButton, &QPushButton::clicked, this, &SettingsDialog::save); - connect( ui.kcfg_Path, SIGNAL(textChanged(QString)), SLOT(validate()) ); - connect( ui.kcfg_ReadOnly, SIGNAL(toggled(bool)), SLOT(validate()) ); + connect(ui.kcfg_Path, &KUrlRequester::textChanged, this, &SettingsDialog::validate); + connect(ui.kcfg_ReadOnly, &QCheckBox::toggled, this, &SettingsDialog::validate); - QTimer::singleShot( 0, this, SLOT(validate()) ); + QTimer::singleShot(0, this, SLOT(validate())); - ui.kcfg_Path->setUrl( KUrl( mSettings->path() ) ); - mManager = new KConfigDialogManager( this, mSettings ); - mManager->updateWidgets(); - readConfig(); + ui.kcfg_Path->setUrl(QUrl::fromLocalFile(mSettings->path())); + mManager = new KConfigDialogManager(this, mSettings); + mManager->updateWidgets(); + readConfig(); } SettingsDialog::~SettingsDialog() @@ -60,41 +77,41 @@ void SettingsDialog::save() { - mManager->updateSettings(); - mSettings->setPath( ui.kcfg_Path->url().toLocalFile() ); - mSettings->writeConfig(); + mManager->updateSettings(); + mSettings->setPath(ui.kcfg_Path->url().toLocalFile()); + mSettings->save(); } void SettingsDialog::validate() { - const KUrl currentUrl = ui.kcfg_Path->url(); - if ( currentUrl.isEmpty() ) { - enableButton( Ok, false ); - return; - } - - const QFileInfo file( currentUrl.toLocalFile() ); - if ( file.exists() && !file.isWritable() ) { - ui.kcfg_ReadOnly->setEnabled( false ); - ui.kcfg_ReadOnly->setChecked( true ); - } else { - ui.kcfg_ReadOnly->setEnabled( true ); - } - enableButton( Ok, true ); + const QUrl currentUrl = ui.kcfg_Path->url(); + if (currentUrl.isEmpty()) { + mOkButton->setEnabled(false); + return; + } + + const QFileInfo file(currentUrl.toLocalFile()); + if (file.exists() && !file.isWritable()) { + ui.kcfg_ReadOnly->setEnabled(false); + ui.kcfg_ReadOnly->setChecked(true); + } else { + ui.kcfg_ReadOnly->setEnabled(true); + } + mOkButton->setEnabled(true); } void SettingsDialog::readConfig() { - KConfigGroup group( KGlobal::config(), "SettingsDialog" ); - const QSize size = group.readEntry( "Size", QSize(600, 400) ); - if ( size.isValid() ) { - resize( size ); + KConfigGroup group(KSharedConfig::openConfig(), "SettingsDialog"); + const QSize size = group.readEntry("Size", QSize(600, 400)); + if (size.isValid()) { + resize(size); } } void SettingsDialog::writeConfig() { - KConfigGroup group( KGlobal::config(), "SettingsDialog" ); - group.writeEntry( "Size", size() ); + KConfigGroup group(KSharedConfig::openConfig(), "SettingsDialog"); + group.writeEntry("Size", size()); group.sync(); } diff -Nru kdepim-runtime-4.14.6/resources/contacts/settingsdialog.h kdepim-runtime-15.08.0/resources/contacts/settingsdialog.h --- kdepim-runtime-4.14.6/resources/contacts/settingsdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/contacts/settingsdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,32 +22,35 @@ #include "ui_settingsdialog.h" -#include - -namespace Akonadi_Contacts_Resource { +#include +class QPushButton; +namespace Akonadi_Contacts_Resource +{ class ContactsResourceSettings; } class KConfigDialogManager; -namespace Akonadi { +namespace Akonadi +{ -class SettingsDialog : public KDialog +class SettingsDialog : public QDialog { - Q_OBJECT - public: - explicit SettingsDialog( Akonadi_Contacts_Resource::ContactsResourceSettings* settings, WId windowId ); + Q_OBJECT +public: + explicit SettingsDialog(Akonadi_Contacts_Resource::ContactsResourceSettings *settings, WId windowId); ~SettingsDialog(); - private Q_SLOTS: +private Q_SLOTS: void save(); void validate(); - private: +private: void readConfig(); void writeConfig(); Ui::SettingsDialog ui; - KConfigDialogManager* mManager; + KConfigDialogManager *mManager; Akonadi_Contacts_Resource::ContactsResourceSettings *mSettings; + QPushButton *mOkButton; }; } diff -Nru kdepim-runtime-4.14.6/resources/contacts/settings.kcfgc kdepim-runtime-15.08.0/resources/contacts/settings.kcfgc --- kdepim-runtime-4.14.6/resources/contacts/settings.kcfgc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/contacts/settings.kcfgc 2015-08-10 21:01:02.000000000 +0000 @@ -5,4 +5,4 @@ SetUserTexts=true Singleton=false GlobalEnums=true -Namespace=Akonadi_Contacts_Resource +NameSpace=Akonadi_Contacts_Resource diff -Nru kdepim-runtime-4.14.6/resources/contacts/wizard/CMakeLists.txt kdepim-runtime-15.08.0/resources/contacts/wizard/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/contacts/wizard/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/contacts/wizard/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -2,4 +2,4 @@ set(CONTACTS_DIRECTORY_DEFAULT_PATH "$HOME/.local/share/contacts/") configure_file(contactswizard.es.cmake ${CMAKE_CURRENT_BINARY_DIR}/contactswizard.es) -install ( FILES contactswizard.desktop ${CMAKE_CURRENT_BINARY_DIR}/contactswizard.es contactswizard.ui DESTINATION ${DATA_INSTALL_DIR}/akonadi/accountwizard/contacts/ ) +install ( FILES contactswizard.desktop ${CMAKE_CURRENT_BINARY_DIR}/contactswizard.es contactswizard.ui DESTINATION ${KDE_INSTALL_DATADIR}/akonadi/accountwizard/contacts/ ) diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davcollection.cpp kdepim-runtime-15.08.0/resources/dav/common/davcollection.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davcollection.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davcollection.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,68 +22,68 @@ { } -DavCollection::DavCollection( DavUtils::Protocol protocol, const QString &url, const QString &displayName, ContentTypes contentTypes ) - : mProtocol( protocol ), mUrl( url ), mDisplayName( displayName ), mContentTypes( contentTypes ), mPrivileges( DavUtils::All ) +DavCollection::DavCollection(DavUtils::Protocol protocol, const QString &url, const QString &displayName, ContentTypes contentTypes) + : mProtocol(protocol), mUrl(url), mDisplayName(displayName), mContentTypes(contentTypes), mPrivileges(DavUtils::All) { } -void DavCollection::setProtocol( DavUtils::Protocol protocol ) +void DavCollection::setProtocol(DavUtils::Protocol protocol) { - mProtocol = protocol; + mProtocol = protocol; } DavUtils::Protocol DavCollection::protocol() const { - return mProtocol; + return mProtocol; } -void DavCollection::setUrl( const QString &url ) +void DavCollection::setUrl(const QString &url) { - mUrl = url; + mUrl = url; } QString DavCollection::url() const { - return mUrl; + return mUrl; } -void DavCollection::setDisplayName( const QString &displayName ) +void DavCollection::setDisplayName(const QString &displayName) { - mDisplayName = displayName; + mDisplayName = displayName; } QString DavCollection::displayName() const { - return mDisplayName; + return mDisplayName; } -void DavCollection::setColor( const QColor &color ) +void DavCollection::setColor(const QColor &color) { - mColor = color; + mColor = color; } QColor DavCollection::color() const { - return mColor; + return mColor; } -void DavCollection::setContentTypes( ContentTypes contentTypes ) +void DavCollection::setContentTypes(ContentTypes contentTypes) { - mContentTypes = contentTypes; + mContentTypes = contentTypes; } DavCollection::ContentTypes DavCollection::contentTypes() const { - return mContentTypes; + return mContentTypes; } -void DavCollection::setPrivileges( DavUtils::Privileges privs ) +void DavCollection::setPrivileges(DavUtils::Privileges privs) { - mPrivileges = privs; + mPrivileges = privs; } DavUtils::Privileges DavCollection::privileges() const { - return mPrivileges; + return mPrivileges; } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davcollectiondeletejob.cpp kdepim-runtime-15.08.0/resources/dav/common/davcollectiondeletejob.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davcollectiondeletejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davcollectiondeletejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,43 +19,45 @@ #include "davcollectiondeletejob.h" #include -#include +#include +#include -DavCollectionDeleteJob::DavCollectionDeleteJob(const DavUtils::DavUrl &url, QObject *parent ) - : KJob( parent ), mUrl( url ) +DavCollectionDeleteJob::DavCollectionDeleteJob(const DavUtils::DavUrl &url, QObject *parent) + : KJob(parent), mUrl(url) { } void DavCollectionDeleteJob::start() { - KIO::DeleteJob *job = KIO::del( mUrl.url(), KIO::HideProgressInfo | KIO::DefaultFlags ); - job->addMetaData( QLatin1String("PropagateHttpHeader"), QLatin1String("true") ); - job->addMetaData( QLatin1String("cookies"), QLatin1String("none") ); - job->addMetaData( QLatin1String("no-auth-prompt"), QLatin1String("true") ); + KIO::DeleteJob *job = KIO::del(mUrl.url(), KIO::HideProgressInfo | KIO::DefaultFlags); + job->addMetaData(QStringLiteral("PropagateHttpHeader"), QStringLiteral("true")); + job->addMetaData(QStringLiteral("cookies"), QStringLiteral("none")); + job->addMetaData(QStringLiteral("no-auth-prompt"), QStringLiteral("true")); - connect( job, SIGNAL(result(KJob*)), this, SLOT(davJobFinished(KJob*)) ); + connect(job, &KIO::DeleteJob::result, this, &DavCollectionDeleteJob::davJobFinished); } -void DavCollectionDeleteJob::davJobFinished( KJob *job ) +void DavCollectionDeleteJob::davJobFinished(KJob *job) { - KIO::DeleteJob *deleteJob = qobject_cast( job ); + KIO::DeleteJob *deleteJob = qobject_cast(job); - if ( deleteJob->error() && deleteJob->error() != KIO::ERR_NO_CONTENT ) { - const int responseCode = deleteJob->queryMetaData( QLatin1String("responsecode") ).isEmpty() ? - 0 : - deleteJob->queryMetaData( QLatin1String("responsecode") ).toInt(); - - QString err; - if ( deleteJob->error() != KIO::ERR_SLAVE_DEFINED ) - err = KIO::buildErrorString( deleteJob->error(), deleteJob->errorText() ); - else - err = deleteJob->errorText(); - - setError( UserDefinedError + responseCode ); - setErrorText( i18n( "There was a problem with the request. The collection has not been deleted from the server.\n" - "%1 (%2).", err, responseCode ) ); - } + if (deleteJob->error() && deleteJob->error() != KIO::ERR_NO_CONTENT) { + const int responseCode = deleteJob->queryMetaData(QStringLiteral("responsecode")).isEmpty() ? + 0 : + deleteJob->queryMetaData(QStringLiteral("responsecode")).toInt(); + + QString err; + if (deleteJob->error() != KIO::ERR_SLAVE_DEFINED) { + err = KIO::buildErrorString(deleteJob->error(), deleteJob->errorText()); + } else { + err = deleteJob->errorText(); + } + + setError(UserDefinedError + responseCode); + setErrorText(i18n("There was a problem with the request. The collection has not been deleted from the server.\n" + "%1 (%2).", err, responseCode)); + } - emitResult(); + emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davcollectiondeletejob.h kdepim-runtime-15.08.0/resources/dav/common/davcollectiondeletejob.h --- kdepim-runtime-4.14.6/resources/dav/common/davcollectiondeletejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davcollectiondeletejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -30,30 +30,28 @@ */ class DavCollectionDeleteJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new DAV collection delete job. * * @param url The dav url of the collection to delete * @param parent The parent object. */ - explicit DavCollectionDeleteJob( const DavUtils::DavUrl &url, QObject *parent = 0 ); + explicit DavCollectionDeleteJob(const DavUtils::DavUrl &url, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - void start(); + void start() Q_DECL_OVERRIDE; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: DavUtils::DavUrl mUrl; }; #endif - - diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davcollection.h kdepim-runtime-15.08.0/resources/dav/common/davcollection.h --- kdepim-runtime-4.14.6/resources/dav/common/davcollection.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davcollection.h 2015-08-10 21:01:02.000000000 +0000 @@ -21,8 +21,8 @@ #include "davutils.h" -#include -#include +#include +#include #include /** @@ -33,24 +33,24 @@ */ class DavCollection { - public: +public: /** * Defines a list of DAV collection objects. */ - typedef QList List; + typedef QVector List; /** * Describes the possible content type of the DAV collection. */ enum ContentType { - Events = 1, ///< The collection can contain event DAV resources. - Todos = 2, ///< The collection can contain todo DAV resources. - Contacts = 4, ///< The collection can contain contact DAV resources. - FreeBusy = 8, ///< The collection can contain free/busy information. - Journal = 16, ///< The collection can contain journal DAV resources. - Calendar = 32 ///< The collection can contain anything calendar-related. + Events = 1, ///< The collection can contain event DAV resources. + Todos = 2, ///< The collection can contain todo DAV resources. + Contacts = 4, ///< The collection can contain contact DAV resources. + FreeBusy = 8, ///< The collection can contain free/busy information. + Journal = 16, ///< The collection can contain journal DAV resources. + Calendar = 32 ///< The collection can contain anything calendar-related. }; - Q_DECLARE_FLAGS( ContentTypes, ContentType ) + Q_DECLARE_FLAGS(ContentTypes, ContentType) /** * Creates an empty DAV collection. @@ -65,12 +65,12 @@ * @param displayName The display name of the collection. * @param contentTypes The possible content types of the collection. */ - DavCollection( DavUtils::Protocol protocol, const QString &url, const QString &displayName, ContentTypes contentTypes ); + DavCollection(DavUtils::Protocol protocol, const QString &url, const QString &displayName, ContentTypes contentTypes); /** * Sets the DAV @p protocol dialect the collection comes from. */ - void setProtocol( DavUtils::Protocol protocol ); + void setProtocol(DavUtils::Protocol protocol); /** * Returns the DAV protocol dialect the collection comes from. @@ -80,7 +80,7 @@ /** * Sets the @p url that identifies the collection. */ - void setUrl( const QString &url ); + void setUrl(const QString &url); /** * Returns the url that identifies the collection. @@ -90,7 +90,7 @@ /** * Sets the display @p name of the collection. */ - void setDisplayName( const QString &name ); + void setDisplayName(const QString &name); /** * Returns the display name of the collection. @@ -100,7 +100,7 @@ /** * Sets the color for this collection */ - void setColor( const QColor &color ); + void setColor(const QColor &color); /** * Return the color of the collection, or an empty string if @@ -111,7 +111,7 @@ /** * Sets the possible content @p types of the collection. */ - void setContentTypes( ContentTypes types ); + void setContentTypes(ContentTypes types); /** * Returns the possible content types of the collection. @@ -121,14 +121,14 @@ /** * Sets the privileges on this collection. */ - void setPrivileges( DavUtils::Privileges privs ); + void setPrivileges(DavUtils::Privileges privs); /** * Returns the privileges on this collection. */ DavUtils::Privileges privileges() const; - private: +private: DavUtils::Protocol mProtocol; QString mUrl; QString mDisplayName; @@ -137,6 +137,6 @@ DavUtils::Privileges mPrivileges; }; -Q_DECLARE_OPERATORS_FOR_FLAGS( DavCollection::ContentTypes ) - +Q_DECLARE_OPERATORS_FOR_FLAGS(DavCollection::ContentTypes) +Q_DECLARE_TYPEINFO(DavCollection, Q_MOVABLE_TYPE ); #endif diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davcollectionmodifyjob.cpp kdepim-runtime-15.08.0/resources/dav/common/davcollectionmodifyjob.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davcollectionmodifyjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davcollectionmodifyjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,138 +21,143 @@ #include "davutils.h" #include -#include -#include +#include +#include -DavCollectionModifyJob::DavCollectionModifyJob( const DavUtils::DavUrl &url, QObject *parent ) - : KJob( parent ), mUrl( url ) +DavCollectionModifyJob::DavCollectionModifyJob(const DavUtils::DavUrl &url, QObject *parent) + : KJob(parent), mUrl(url) { } -void DavCollectionModifyJob::setProperty( const QString &prop, const QString &value, const QString &ns ) +void DavCollectionModifyJob::setProperty(const QString &prop, const QString &value, const QString &ns) { - QDomElement propElement; + QDomElement propElement; - if ( ns.isEmpty() ) - propElement = mQuery.createElement( prop ); - else - propElement = mQuery.createElementNS( prop, ns ); + if (ns.isEmpty()) { + propElement = mQuery.createElement(prop); + } else { + propElement = mQuery.createElementNS(prop, ns); + } - const QDomText textElement = mQuery.createTextNode( value ); - propElement.appendChild( textElement ); + const QDomText textElement = mQuery.createTextNode(value); + propElement.appendChild(textElement); - mSetProperties << propElement; + mSetProperties << propElement; } -void DavCollectionModifyJob::removeProperty( const QString &prop, const QString &ns ) +void DavCollectionModifyJob::removeProperty(const QString &prop, const QString &ns) { - QDomElement propElement; + QDomElement propElement; - if ( ns.isEmpty() ) - propElement = mQuery.createElement( prop ); - else - propElement = mQuery.createElementNS( prop, ns ); + if (ns.isEmpty()) { + propElement = mQuery.createElement(prop); + } else { + propElement = mQuery.createElementNS(prop, ns); + } - mRemoveProperties << propElement; + mRemoveProperties << propElement; } void DavCollectionModifyJob::start() { - if ( mSetProperties.isEmpty() && mRemoveProperties.isEmpty() ) { - setError( UserDefinedError ); // no special meaning, for now at least - setErrorText( i18n( "No properties to change or remove" ) ); - emitResult(); - return; - } + if (mSetProperties.isEmpty() && mRemoveProperties.isEmpty()) { + setError(UserDefinedError); // no special meaning, for now at least + setErrorText(i18n("No properties to change or remove")); + emitResult(); + return; + } + + QDomDocument mQuery; + QDomElement propertyUpdateElement = mQuery.createElementNS(QStringLiteral("DAV:"), QStringLiteral("propertyupdate")); + mQuery.appendChild(propertyUpdateElement); + + if (!mSetProperties.isEmpty()) { + QDomElement setElement = mQuery.createElementNS(QStringLiteral("DAV:"), QStringLiteral("set")); + propertyUpdateElement.appendChild(setElement); + + QDomElement propElement = mQuery.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + setElement.appendChild(propElement); + + foreach (const QDomElement &element, mSetProperties) { + propElement.appendChild(element); + } + } - QDomDocument mQuery; - QDomElement propertyUpdateElement = mQuery.createElementNS( QLatin1String("DAV:"), QLatin1String("propertyupdate") ); - mQuery.appendChild( propertyUpdateElement ); - - if ( !mSetProperties.isEmpty() ) { - QDomElement setElement = mQuery.createElementNS( QLatin1String("DAV:"), QLatin1String("set") ); - propertyUpdateElement.appendChild( setElement ); - - QDomElement propElement = mQuery.createElementNS( QLatin1String("DAV:"), QLatin1String("prop") ); - setElement.appendChild( propElement ); - - foreach ( const QDomElement &element, mSetProperties ) - propElement.appendChild( element ); - } - - if ( !mRemoveProperties.isEmpty() ) { - QDomElement removeElement = mQuery.createElementNS( QLatin1String("DAV:"), QLatin1String("remove") ); - propertyUpdateElement.appendChild( removeElement ); - - QDomElement propElement = mQuery.createElementNS( QLatin1String("DAV:"), QLatin1String("prop") ); - removeElement.appendChild( propElement ); - - foreach ( const QDomElement &element, mSetProperties ) - propElement.appendChild( element ); - } - - KIO::DavJob *job = DavManager::self()->createPropPatchJob( mUrl.url(), mQuery ); - job->addMetaData( QLatin1String("PropagateHttpHeader"), QLatin1String("true") ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + if (!mRemoveProperties.isEmpty()) { + QDomElement removeElement = mQuery.createElementNS(QStringLiteral("DAV:"), QStringLiteral("remove")); + propertyUpdateElement.appendChild(removeElement); + + QDomElement propElement = mQuery.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + removeElement.appendChild(propElement); + + foreach (const QDomElement &element, mSetProperties) { + propElement.appendChild(element); + } + } + + KIO::DavJob *job = DavManager::self()->createPropPatchJob(mUrl.url(), mQuery); + job->addMetaData(QStringLiteral("PropagateHttpHeader"), QStringLiteral("true")); + connect(job, &KIO::DavJob::result, this, &DavCollectionModifyJob::davJobFinished); } -void DavCollectionModifyJob::davJobFinished( KJob *job ) +void DavCollectionModifyJob::davJobFinished(KJob *job) { - KIO::DavJob *davJob = qobject_cast( job ); - const int responseCode = davJob->queryMetaData( QLatin1String("responsecode") ).isEmpty() ? - 0 : - davJob->queryMetaData( QLatin1String("responsecode") ).toInt(); - - // KIO::DavJob does not set error() even if the HTTP status code is a 4xx or a 5xx - if ( davJob->error() || ( responseCode >= 400 && responseCode < 600 ) ) { - QString err; - if ( davJob->error() && davJob->error() != KIO::ERR_SLAVE_DEFINED ) - err = KIO::buildErrorString( davJob->error(), davJob->errorText() ); - else - err = davJob->errorText(); - - setError( UserDefinedError + responseCode ); - setErrorText( i18n( "There was a problem with the request. The item has not been modified on the server.\n" - "%1 (%2).", err, responseCode ) ); + KIO::DavJob *davJob = qobject_cast(job); + const int responseCode = davJob->queryMetaData(QStringLiteral("responsecode")).isEmpty() ? + 0 : + davJob->queryMetaData(QStringLiteral("responsecode")).toInt(); + + // KIO::DavJob does not set error() even if the HTTP status code is a 4xx or a 5xx + if (davJob->error() || (responseCode >= 400 && responseCode < 600)) { + QString err; + if (davJob->error() && davJob->error() != KIO::ERR_SLAVE_DEFINED) { + err = KIO::buildErrorString(davJob->error(), davJob->errorText()); + } else { + err = davJob->errorText(); + } + + setError(UserDefinedError + responseCode); + setErrorText(i18n("There was a problem with the request. The item has not been modified on the server.\n" + "%1 (%2).", err, responseCode)); - emitResult(); - return; - } + emitResult(); + return; + } - const QDomDocument response = davJob->response(); - QDomElement responseElement = DavUtils::firstChildElementNS( response.documentElement(), QLatin1String("DAV:"), QLatin1String("response") ); + const QDomDocument response = davJob->response(); + QDomElement responseElement = DavUtils::firstChildElementNS(response.documentElement(), QStringLiteral("DAV:"), QStringLiteral("response")); - bool hasError = false; - QString errorText; + bool hasError = false; + QString errorText; - // parse all propstats answers to get the eventual errors - const QDomNodeList propstats = responseElement.elementsByTagNameNS( QLatin1String("DAV:"), QLatin1String("propstat") ); - for ( uint i = 0; i < propstats.length(); ++i ) { - const QDomElement propstatElement = propstats.item( i ).toElement(); - const QDomElement statusElement = DavUtils::firstChildElementNS( propstatElement, QLatin1String("DAV:"), QLatin1String("status") ); - - const QString statusText = statusElement.text(); - if ( statusText.contains( QLatin1String("200") ) ) { - // Nothing special to do here, this indicates the success of the whole request - break; - } else { - // Generic error - hasError = true; - errorText = i18n( "There was an error when modifying the properties" ); + // parse all propstats answers to get the eventual errors + const QDomNodeList propstats = responseElement.elementsByTagNameNS(QStringLiteral("DAV:"), QStringLiteral("propstat")); + for (int i = 0; i < propstats.length(); ++i) { + const QDomElement propstatElement = propstats.item(i).toElement(); + const QDomElement statusElement = DavUtils::firstChildElementNS(propstatElement, QStringLiteral("DAV:"), QStringLiteral("status")); + + const QString statusText = statusElement.text(); + if (statusText.contains(QStringLiteral("200"))) { + // Nothing special to do here, this indicates the success of the whole request + break; + } else { + // Generic error + hasError = true; + errorText = i18n("There was an error when modifying the properties"); + } } - } - if ( hasError ) { - // Trying to get more information about the error - const QDomElement responseDescriptionElement = DavUtils::firstChildElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("responsedescription") ); - if ( !responseDescriptionElement.isNull() ) { - errorText.append( i18n( "\nThe server returned more information:\n" ) ); - errorText.append( responseDescriptionElement.text() ); - } + if (hasError) { + // Trying to get more information about the error + const QDomElement responseDescriptionElement = DavUtils::firstChildElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("responsedescription")); + if (!responseDescriptionElement.isNull()) { + errorText.append(i18n("\nThe server returned more information:\n")); + errorText.append(responseDescriptionElement.text()); + } - setError( UserDefinedError ); - setErrorText( errorText ); - } + setError(UserDefinedError); + setErrorText(errorText); + } - emitResult(); + emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davcollectionmodifyjob.h kdepim-runtime-15.08.0/resources/dav/common/davcollectionmodifyjob.h --- kdepim-runtime-4.14.6/resources/dav/common/davcollectionmodifyjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davcollectionmodifyjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -33,16 +33,16 @@ */ class DavCollectionModifyJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new dav collection modify job. * * @param url The DAV url that identifies the collection. * @param parent The parent object. */ - explicit DavCollectionModifyJob( const DavUtils::DavUrl &url, QObject *parent = 0 ); + explicit DavCollectionModifyJob(const DavUtils::DavUrl &url, QObject *parent = Q_NULLPTR); /** * Sets the property that shall be modified by the job. @@ -51,7 +51,7 @@ * @param value The value of the property. * @param ns The XML namespace that shall be used for the property name. */ - void setProperty( const QString &property, const QString &value, const QString &ns = QString() ); + void setProperty(const QString &property, const QString &value, const QString &ns = QString()); /** * Sets the property that shall be removed by the job. @@ -59,22 +59,22 @@ * @param property The name of the property. * @param ns The XML namespace that shall be used for the property name. */ - void removeProperty( const QString &property, const QString &ns ); + void removeProperty(const QString &property, const QString &ns); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; - private Q_SLOTS: - void davJobFinished( KJob *job ); +private Q_SLOTS: + void davJobFinished(KJob *job); - private: +private: DavUtils::DavUrl mUrl; QDomDocument mQuery; - QList mSetProperties; - QList mRemoveProperties; + QVector mSetProperties; + QVector mRemoveProperties; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davcollectionsfetchjob.cpp kdepim-runtime-15.08.0/resources/dav/common/davcollectionsfetchjob.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davcollectionsfetchjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davcollectionsfetchjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,285 +23,316 @@ #include "davprotocolbase.h" #include "davutils.h" -#include +#include #include -#include +#include +#include #include #include -DavCollectionsFetchJob::DavCollectionsFetchJob( const DavUtils::DavUrl &url, QObject *parent ) - : KJob( parent ), mUrl( url ), mSubJobCount( 0 ) +DavCollectionsFetchJob::DavCollectionsFetchJob(const DavUtils::DavUrl &url, QObject *parent) + : KJob(parent), mUrl(url), mSubJobCount(0) { } void DavCollectionsFetchJob::start() { - if ( DavManager::self()->davProtocol( mUrl.protocol() )->supportsPrincipals() ) { - DavPrincipalHomeSetsFetchJob *job = new DavPrincipalHomeSetsFetchJob( mUrl ); - connect( job, SIGNAL(result(KJob*)), SLOT(principalFetchFinished(KJob*)) ); - job->start(); - } else { - doCollectionsFetch( mUrl.url() ); - } + if (DavManager::self()->davProtocol(mUrl.protocol())->supportsPrincipals()) { + DavPrincipalHomeSetsFetchJob *job = new DavPrincipalHomeSetsFetchJob(mUrl); + connect(job, &DavPrincipalHomeSetsFetchJob::result, this, &DavCollectionsFetchJob::principalFetchFinished); + job->start(); + } else { + doCollectionsFetch(mUrl.url()); + } } DavCollection::List DavCollectionsFetchJob::collections() const { - return mCollections; + return mCollections; } DavUtils::DavUrl DavCollectionsFetchJob::davUrl() const { - return mUrl; + return mUrl; } -void DavCollectionsFetchJob::doCollectionsFetch( const KUrl &url ) +void DavCollectionsFetchJob::doCollectionsFetch(const KUrl &url) { - ++mSubJobCount; + ++mSubJobCount; - const QDomDocument collectionQuery = DavManager::self()->davProtocol( mUrl.protocol() )->collectionsQuery(); + const QDomDocument collectionQuery = DavManager::self()->davProtocol(mUrl.protocol())->collectionsQuery(); - KIO::DavJob *job = DavManager::self()->createPropFindJob( url, collectionQuery ); - connect( job, SIGNAL(result(KJob*)), SLOT(collectionsFetchFinished(KJob*)) ); - job->addMetaData( QLatin1String("PropagateHttpHeader"), QLatin1String("true") ); + KIO::DavJob *job = DavManager::self()->createPropFindJob(url, collectionQuery); + connect(job, &DavPrincipalHomeSetsFetchJob::result, this, &DavCollectionsFetchJob::collectionsFetchFinished); + job->addMetaData(QStringLiteral("PropagateHttpHeader"), QStringLiteral("true")); } -void DavCollectionsFetchJob::principalFetchFinished( KJob *job ) +void DavCollectionsFetchJob::principalFetchFinished(KJob *job) { - if ( job->error() ) { - // This may mean that the URL was not a principal URL. - // Retry as if it were a calendar URL. - kDebug() << job->errorText(); - doCollectionsFetch( mUrl.url() ); - return; - } - - const DavPrincipalHomeSetsFetchJob *davJob = qobject_cast( job ); - - const QStringList homeSets = davJob->homeSets(); - kDebug() << "Found " << homeSets.size() << " homesets"; - kDebug() << homeSets; - - if ( homeSets.isEmpty() ) { - // Same as above, retry as if it were a calendar URL. - doCollectionsFetch( mUrl.url() ); - return; - } - - foreach ( const QString &homeSet, homeSets ) { - KUrl url = mUrl.url(); - - if ( homeSet.startsWith( QLatin1Char('/') ) ) { - // homeSet is only a path, use request url to complete - url.setEncodedPath( homeSet.toLatin1() ); - } else { - // homeSet is a complete url - KUrl tmpUrl( homeSet ); - tmpUrl.setUser( url.user() ); - tmpUrl.setPass( url.pass() ); - url = tmpUrl; - } + const DavPrincipalHomeSetsFetchJob *davJob = qobject_cast(job); - doCollectionsFetch( url ); - } -} + if (davJob->error()) { + if ( davJob->latestResponseCode() ) { + // If we have a HTTP response code then this may mean that + // the URL was not a principal URL. Retry as if it were a calendar URL. + qDebug() << job->errorText(); + doCollectionsFetch(mUrl.url()); + } + else { + // Just give up here. + emitResult(); + } -void DavCollectionsFetchJob::collectionsFetchFinished( KJob *job ) -{ - KIO::DavJob *davJob = qobject_cast( job ); - const int responseCode = davJob->queryMetaData( QLatin1String("responsecode") ).isEmpty() ? - 0 : - davJob->queryMetaData( QLatin1String("responsecode") ).toInt(); - - // KIO::DavJob does not set error() even if the HTTP status code is a 4xx or a 5xx - if ( davJob->error() || ( responseCode >= 400 && responseCode < 600 ) ) { - if ( davJob->url() != mUrl.url() ) { - // Retry as if the initial URL was a calendar URL. - // We can end up here when retrieving a homeset on - // which a PROPFIND resulted in an error - doCollectionsFetch( mUrl.url() ); - --mSubJobCount; - return; + return; } - QString err; - if ( davJob->error() && davJob->error() != KIO::ERR_SLAVE_DEFINED ) - err = KIO::buildErrorString( davJob->error(), davJob->errorText() ); - else - err = davJob->errorText(); - - setError( UserDefinedError + responseCode ); - setErrorText( i18n( "There was a problem with the request.\n" - "%1 (%2).", err, responseCode ) ); - } - else { - // For use in the collectionDiscovered() signal - KUrl _jobUrl = mUrl.url(); - _jobUrl.setUser( QString() ); - const QString jobUrl = _jobUrl.prettyUrl(); - - //kDebug() << davJob->response().toString(); - - QByteArray resp( davJob->response().toByteArray() ); - QBuffer buffer( &resp ); - buffer.open( QIODevice::ReadOnly ); - - QXmlQuery xquery; - if ( !xquery.setFocus( &buffer ) ) { - setError( UserDefinedError ); - setErrorText( i18n( "Error setting focus for XQuery" ) ); + const QStringList homeSets = davJob->homeSets(); + qDebug() << "Found " << homeSets.size() << " homesets"; + qDebug() << homeSets; + + if (homeSets.isEmpty()) { + // Same as above, retry as if it were a calendar URL. + doCollectionsFetch(mUrl.url()); + return; } - xquery.setQuery( DavManager::self()->davProtocol( mUrl.protocol() )->collectionsXQuery() ); - if ( !xquery.isValid() ) { - setError( UserDefinedError ); - setErrorText( i18n( "Invalid XQuery submitted by DAV implementation" ) ); - } + foreach (const QString &homeSet, homeSets) { + KUrl url = mUrl.url(); + + if (homeSet.startsWith(QLatin1Char('/'))) { + // homeSet is only a path, use request url to complete + url.setEncodedPath(homeSet.toLatin1()); + } else { + // homeSet is a complete url + KUrl tmpUrl(homeSet); + tmpUrl.setUser(url.user()); + tmpUrl.setPass(url.pass()); + url = tmpUrl; + } - QString responsesStr; - xquery.evaluateTo( &responsesStr ); - responsesStr.prepend( QLatin1String("") ); - responsesStr.append( QLatin1String("") ); - - QDomDocument document; - if ( !document.setContent( responsesStr, true ) ) { - setError( UserDefinedError ); - setErrorText( i18n( "Invalid responses from backend" ) ); + doCollectionsFetch(url); } +} - if ( !error() ) { - /* - * Extract information from a document like the following: - * - * - * - * /caldav.php/test1.user/home/ - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * Test1 User - * - * - * - * - * - * - * HTTP/1.1 200 OK - * - * - * - */ - - const QDomElement responsesElement = document.documentElement(); - - QDomElement responseElement = DavUtils::firstChildElementNS( responsesElement, QLatin1String("DAV:"), QLatin1String("response") ); - while ( !responseElement.isNull() ) { - - QDomElement propstatElement; - - // check for the valid propstat, without giving up on first error - { - const QDomNodeList propstats = responseElement.elementsByTagNameNS( QLatin1String("DAV:"), QLatin1String("propstat") ); - for ( uint i = 0; i < propstats.length(); ++i ) { - const QDomElement propstatCandidate = propstats.item( i ).toElement(); - const QDomElement statusElement = DavUtils::firstChildElementNS( propstatCandidate, QLatin1String("DAV:"), QLatin1String("status") ); - if ( statusElement.text().contains( QLatin1String("200") ) ) { - propstatElement = propstatCandidate; - } - } +void DavCollectionsFetchJob::collectionsFetchFinished(KJob *job) +{ + KIO::DavJob *davJob = qobject_cast(job); + const int responseCode = davJob->queryMetaData(QStringLiteral("responsecode")).isEmpty() ? + 0 : + davJob->queryMetaData(QStringLiteral("responsecode")).toInt(); + + // KIO::DavJob does not set error() even if the HTTP status code is a 4xx or a 5xx + if (davJob->error() || (responseCode >= 400 && responseCode < 600)) { + if (davJob->url() != mUrl.url()) { + // Retry as if the initial URL was a calendar URL. + // We can end up here when retrieving a homeset on + // which a PROPFIND resulted in an error + doCollectionsFetch(mUrl.url()); + --mSubJobCount; + return; } - if ( propstatElement.isNull() ) { - responseElement = DavUtils::nextSiblingElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("response") ); - continue; + QString err; + if (davJob->error() && davJob->error() != KIO::ERR_SLAVE_DEFINED) { + err = KIO::buildErrorString(davJob->error(), davJob->errorText()); + } else { + err = davJob->errorText(); } - // extract url - const QDomElement hrefElement = DavUtils::firstChildElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("href") ); - if ( hrefElement.isNull() ) { - responseElement = DavUtils::nextSiblingElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("response") ); - continue; + setError(UserDefinedError + responseCode); + setErrorText(i18n("There was a problem with the request.\n" + "%1 (%2).", err, responseCode)); + } else { + // For use in the collectionDiscovered() signal + KUrl _jobUrl = mUrl.url(); + _jobUrl.setUser(QString()); + const QString jobUrl = _jobUrl.prettyUrl(); + + // Validate that we got a valid PROPFIND response + QDomElement rootElement = davJob->response().documentElement(); + if (rootElement.tagName().compare(QStringLiteral("multistatus"), Qt::CaseInsensitive) != 0) { + setError(UserDefinedError); + setErrorText(i18n("Invalid responses from backend")); + subjobFinished(); + return; } - QString href = hrefElement.text(); - if ( !href.endsWith( QLatin1Char('/') ) ) - href.append( QLatin1Char('/') ); - - KUrl url = davJob->url(); - url.setUser( QString() ); - if ( href.startsWith( QLatin1Char('/') ) ) { - // href is only a path, use request url to complete - url.setEncodedPath( href.toLatin1() ); - } else { - // href is a complete url - KUrl tmpUrl( href ); - url = tmpUrl; + QByteArray resp(davJob->response().toByteArray()); + QBuffer buffer(&resp); + buffer.open(QIODevice::ReadOnly); + + QXmlQuery xquery; + if (!xquery.setFocus(&buffer)) { + setError(UserDefinedError); + setErrorText(i18n("Error setting focus for XQuery")); + subjobFinished(); + return; } - // don't add this resource if it has already been detected - bool alreadySeen = false; - foreach ( const DavCollection &seen, mCollections ) { - if ( seen.url() == url.prettyUrl() ) - alreadySeen = true; - } - if ( alreadySeen ) { - responseElement = DavUtils::nextSiblingElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("response") ); - continue; + xquery.setQuery(DavManager::self()->davProtocol(mUrl.protocol())->collectionsXQuery()); + if (!xquery.isValid()) { + setError(UserDefinedError); + setErrorText(i18n("Invalid XQuery submitted by DAV implementation")); + subjobFinished(); + return; } - // extract display name - const QDomElement propElement = DavUtils::firstChildElementNS( propstatElement, QLatin1String("DAV:"), QLatin1String("prop") ); - const QDomElement displaynameElement = DavUtils::firstChildElementNS( propElement, QLatin1String("DAV:"), QLatin1String("displayname") ); - const QString displayName = displaynameElement.text(); - - // extract calendar color if provided - const QDomElement colorElement = DavUtils::firstChildElementNS( propElement, QLatin1String("http://apple.com/ns/ical/"), QLatin1String("calendar-color") ); - QColor color; - if ( !colorElement.isNull() ) { - QString colorValue = colorElement.text(); - if ( QColor::isValidColor( colorValue ) ) - color.setNamedColor( colorValue ); + QString responsesStr; + xquery.evaluateTo(&responsesStr); + responsesStr.prepend(QStringLiteral("")); + responsesStr.append(QStringLiteral("")); + + QDomDocument document; + if (!document.setContent(responsesStr, true)) { + setError(UserDefinedError); + setErrorText(i18n("Invalid responses from backend")); + subjobFinished(); + return; } - // extract allowed content types - const DavCollection::ContentTypes contentTypes = DavManager::self()->davProtocol( mUrl.protocol() )->collectionContentTypes( propstatElement ); + if (!error()) { + /* + * Extract information from a document like the following: + * + * + * + * /caldav.php/test1.user/home/ + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * Test1 User + * + * + * + * + * + * + * HTTP/1.1 200 OK + * + * + * + */ + + const QDomElement responsesElement = document.documentElement(); + + QDomElement responseElement = DavUtils::firstChildElementNS(responsesElement, QStringLiteral("DAV:"), QStringLiteral("response")); + while (!responseElement.isNull()) { + + QDomElement propstatElement; + + // check for the valid propstat, without giving up on first error + { + const QDomNodeList propstats = responseElement.elementsByTagNameNS(QStringLiteral("DAV:"), QStringLiteral("propstat")); + for (int i = 0; i < propstats.length(); ++i) { + const QDomElement propstatCandidate = propstats.item(i).toElement(); + const QDomElement statusElement = DavUtils::firstChildElementNS(propstatCandidate, QStringLiteral("DAV:"), QStringLiteral("status")); + if (statusElement.text().contains(QStringLiteral("200"))) { + propstatElement = propstatCandidate; + } + } + } + + if (propstatElement.isNull()) { + responseElement = DavUtils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response")); + continue; + } + + // extract url + const QDomElement hrefElement = DavUtils::firstChildElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("href")); + if (hrefElement.isNull()) { + responseElement = DavUtils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response")); + continue; + } + + QString href = hrefElement.text(); + if (!href.endsWith(QLatin1Char('/'))) { + href.append(QLatin1Char('/')); + } + + KUrl url = davJob->url(); + url.setUser(QString()); + if (href.startsWith(QLatin1Char('/'))) { + // href is only a path, use request url to complete + url.setEncodedPath(href.toLatin1()); + } else { + // href is a complete url + KUrl tmpUrl(href); + url = tmpUrl; + } + + // don't add this resource if it has already been detected + bool alreadySeen = false; + foreach (const DavCollection &seen, mCollections) { + if (seen.url() == url.prettyUrl()) { + alreadySeen = true; + } + } + if (alreadySeen) { + responseElement = DavUtils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response")); + continue; + } + + // extract display name + const QDomElement propElement = DavUtils::firstChildElementNS(propstatElement, QStringLiteral("DAV:"), QStringLiteral("prop")); + const QDomElement displaynameElement = DavUtils::firstChildElementNS(propElement, QStringLiteral("DAV:"), QStringLiteral("displayname")); + const QString displayName = displaynameElement.text(); + + // extract calendar color if provided + const QDomElement colorElement = DavUtils::firstChildElementNS(propElement, QStringLiteral("http://apple.com/ns/ical/"), QStringLiteral("calendar-color")); + QColor color; + if (!colorElement.isNull()) { + QString colorValue = colorElement.text(); + if (QColor::isValidColor(colorValue)) { + color.setNamedColor(colorValue); + } + } + + // extract allowed content types + const DavCollection::ContentTypes contentTypes = DavManager::self()->davProtocol(mUrl.protocol())->collectionContentTypes(propstatElement); + + DavCollection collection(mUrl.protocol(), url.prettyUrl(), displayName, contentTypes); + if (color.isValid()) { + collection.setColor(color); + } + + // extract privileges + const QDomElement currentPrivsElement = DavUtils::firstChildElementNS(propElement, QStringLiteral("DAV:"), QStringLiteral("current-user-privilege-set")); + if (currentPrivsElement.isNull()) { + // Assume that we have all privileges + collection.setPrivileges(DavUtils::All); + } else { + DavUtils::Privileges privileges = DavUtils::extractPrivileges(currentPrivsElement); + collection.setPrivileges(privileges); + } + + qDebug() << url.prettyUrl() << "PRIVS: " << collection.privileges(); + mCollections << collection; + Q_EMIT collectionDiscovered(mUrl.protocol(), url.prettyUrl(), jobUrl); - DavCollection collection( mUrl.protocol(), url.prettyUrl(), displayName, contentTypes ); - if ( color.isValid() ) - collection.setColor( color ); - - // extract privileges - const QDomElement currentPrivsElement = DavUtils::firstChildElementNS( propElement, QLatin1String("DAV:"), QLatin1String("current-user-privilege-set") ); - if ( currentPrivsElement.isNull() ) { - // Assume that we have all privileges - collection.setPrivileges( DavUtils::All ); - } else { - DavUtils::Privileges privileges = DavUtils::extractPrivileges( currentPrivsElement ); - collection.setPrivileges( privileges ); + responseElement = DavUtils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response")); + } } + } - kDebug() << url.prettyUrl() << "PRIVS: " << collection.privileges(); - mCollections << collection; - emit collectionDiscovered( mUrl.protocol(), url.prettyUrl(), jobUrl ); + subjobFinished(); +} - responseElement = DavUtils::nextSiblingElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("response") ); - } +void DavCollectionsFetchJob::subjobFinished() +{ + if (--mSubJobCount == 0) { + emitResult(); } - } - - if ( --mSubJobCount == 0 ) - emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davcollectionsfetchjob.h kdepim-runtime-15.08.0/resources/dav/common/davcollectionsfetchjob.h --- kdepim-runtime-4.14.6/resources/dav/common/davcollectionsfetchjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davcollectionsfetchjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -32,21 +32,21 @@ */ class DavCollectionsFetchJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new dav collections fetch job. * * @param url The DAV url of the DAV collection whose sub collections shall be fetched. * @param parent The parent object. */ - explicit DavCollectionsFetchJob( const DavUtils::DavUrl &url, QObject *parent = 0 ); + explicit DavCollectionsFetchJob(const DavUtils::DavUrl &url, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Returns the list of fetched DAV collections. @@ -58,21 +58,22 @@ */ DavUtils::DavUrl davUrl() const; - Q_SIGNALS: +Q_SIGNALS: /** * This signal is emitted every time a new collection has been discovered. * * @param collectionUrl The URL of the discovered collection * @param configuredUrl The URL given to the job */ - void collectionDiscovered( int protocol, const QString &collectionUrl, const QString &configuredUrl ); + void collectionDiscovered(int protocol, const QString &collectionUrl, const QString &configuredUrl); - private Q_SLOTS: - void principalFetchFinished( KJob* ); - void collectionsFetchFinished( KJob* ); - - private: - void doCollectionsFetch( const KUrl &url ); +private Q_SLOTS: + void principalFetchFinished(KJob *); + void collectionsFetchFinished(KJob *); + +private: + void doCollectionsFetch(const KUrl &url); + void subjobFinished(); DavUtils::DavUrl mUrl; DavCollection::List mCollections; diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davcollectionsmultifetchjob.cpp kdepim-runtime-15.08.0/resources/dav/common/davcollectionsmultifetchjob.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davcollectionsmultifetchjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davcollectionsmultifetchjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,43 +20,43 @@ #include "davcollectionsfetchjob.h" -DavCollectionsMultiFetchJob::DavCollectionsMultiFetchJob( const DavUtils::DavUrl::List &urls, QObject *parent ) - : KJob( parent ), mUrls( urls ), mSubJobCount( urls.size() ) +DavCollectionsMultiFetchJob::DavCollectionsMultiFetchJob(const DavUtils::DavUrl::List &urls, QObject *parent) + : KJob(parent), mUrls(urls), mSubJobCount(urls.size()) { } void DavCollectionsMultiFetchJob::start() { - if ( mUrls.isEmpty() ) - emitResult(); - - foreach ( const DavUtils::DavUrl &url, mUrls ) { - DavCollectionsFetchJob *job = new DavCollectionsFetchJob( url, this ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); - connect( job, SIGNAL(collectionDiscovered(int,QString,QString)), - SIGNAL(collectionDiscovered(int,QString,QString)) ); - job->start(); - } + if (mUrls.isEmpty()) { + emitResult(); + } + + foreach (const DavUtils::DavUrl &url, mUrls) { + DavCollectionsFetchJob *job = new DavCollectionsFetchJob(url, this); + connect(job, &DavCollectionsFetchJob::result, this, &DavCollectionsMultiFetchJob::davJobFinished); + connect(job, &DavCollectionsFetchJob::collectionDiscovered, this, &DavCollectionsMultiFetchJob::collectionDiscovered); + job->start(); + } } DavCollection::List DavCollectionsMultiFetchJob::collections() const { - return mCollections; + return mCollections; } -void DavCollectionsMultiFetchJob::davJobFinished( KJob *job ) +void DavCollectionsMultiFetchJob::davJobFinished(KJob *job) { - DavCollectionsFetchJob *fetchJob = qobject_cast( job ); - - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - } - else { - mCollections << fetchJob->collections(); - } + DavCollectionsFetchJob *fetchJob = qobject_cast(job); - if ( --mSubJobCount == 0 ) - emitResult(); + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + } else { + mCollections << fetchJob->collections(); + } + + if (--mSubJobCount == 0) { + emitResult(); + } } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davcollectionsmultifetchjob.h kdepim-runtime-15.08.0/resources/dav/common/davcollectionsmultifetchjob.h --- kdepim-runtime-4.14.6/resources/dav/common/davcollectionsmultifetchjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davcollectionsmultifetchjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -35,40 +35,40 @@ */ class DavCollectionsMultiFetchJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new dav collections multi fetch job. * * @param urls The list of DAV urls whose sub collections shall be fetched. * @param parent The parent object. */ - explicit DavCollectionsMultiFetchJob( const DavUtils::DavUrl::List &urls, QObject *parent = 0 ); + explicit DavCollectionsMultiFetchJob(const DavUtils::DavUrl::List &urls, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Returns the list of fetched DAV collections. */ DavCollection::List collections() const; - Q_SIGNALS: +Q_SIGNALS: /** * This signal is emitted every time a new collection has been discovered. * * @param collectionUrl The URL of the discovered collection * @param configuredUrl The URL given to the job */ - void collectionDiscovered( int protocol, const QString &collectionUrl, const QString &configuredUrl ); + void collectionDiscovered(int protocol, const QString &collectionUrl, const QString &configuredUrl); - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: DavUtils::DavUrl::List mUrls; DavCollection::List mCollections; uint mSubJobCount; diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davitem.cpp kdepim-runtime-15.08.0/resources/dav/common/davitem.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davitem.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davitem.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,72 +22,72 @@ { } -DavItem::DavItem( const QString &url, const QString &contentType, const QByteArray &data, const QString &etag ) - : mUrl( url ), mContentType( contentType ), mData( data ), mEtag( etag ) +DavItem::DavItem(const QString &url, const QString &contentType, const QByteArray &data, const QString &etag) + : mUrl(url), mContentType(contentType), mData(data), mEtag(etag) { } -void DavItem::setUrl( const QString &url ) +void DavItem::setUrl(const QString &url) { - mUrl = url; + mUrl = url; } QString DavItem::url() const { - return mUrl; + return mUrl; } -void DavItem::setContentType( const QString &contentType ) +void DavItem::setContentType(const QString &contentType) { - mContentType = contentType; + mContentType = contentType; } QString DavItem::contentType() const { - return mContentType; + return mContentType; } -void DavItem::setData( const QByteArray &data ) +void DavItem::setData(const QByteArray &data) { - mData = data; + mData = data; } QByteArray DavItem::data() const { - return mData; + return mData; } -void DavItem::setEtag( const QString &etag ) +void DavItem::setEtag(const QString &etag) { - mEtag = etag; + mEtag = etag; } QString DavItem::etag() const { - return mEtag; + return mEtag; } -QDataStream& operator<<( QDataStream &stream, const DavItem &item ) +QDataStream &operator<<(QDataStream &stream, const DavItem &item) { - stream << item.url(); - stream << item.contentType(); - stream << item.data(); - stream << item.etag(); + stream << item.url(); + stream << item.contentType(); + stream << item.data(); + stream << item.etag(); - return stream; + return stream; } -QDataStream& operator>>( QDataStream &stream, DavItem &item ) +QDataStream &operator>>(QDataStream &stream, DavItem &item) { - QString url, contentType, etag; - QByteArray data; + QString url, contentType, etag; + QByteArray data; - stream >> url; - stream >> contentType; - stream >> data; - stream >> etag; + stream >> url; + stream >> contentType; + stream >> data; + stream >> etag; - item = DavItem( url, contentType, data, etag ); + item = DavItem(url, contentType, data, etag); - return stream; + return stream; } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davitemcreatejob.cpp kdepim-runtime-15.08.0/resources/dav/common/davitemcreatejob.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davitemcreatejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davitemcreatejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,111 +23,112 @@ #include #include -#include +#include #include -DavItemCreateJob::DavItemCreateJob( const DavUtils::DavUrl &url, const DavItem &item, QObject *parent ) - : DavJobBase( parent ), mUrl( url ), mItem( item ), mRedirectCount( 0 ) +DavItemCreateJob::DavItemCreateJob(const DavUtils::DavUrl &url, const DavItem &item, QObject *parent) + : DavJobBase(parent), mUrl(url), mItem(item), mRedirectCount(0) { } void DavItemCreateJob::start() { - QString headers = QLatin1String("Content-Type: "); - headers += mItem.contentType(); - headers += QLatin1String("\r\n"); - headers += QLatin1String("If-None-Match: *"); - - KIO::StoredTransferJob *job = KIO::storedPut( mItem.data(), mUrl.url(), -1, KIO::HideProgressInfo | KIO::DefaultFlags ); - job->addMetaData( QLatin1String("PropagateHttpHeader"), QLatin1String("true") ); - job->addMetaData( QLatin1String("customHTTPHeader"), headers ); - job->addMetaData( QLatin1String("cookies"), QLatin1String("none") ); - job->addMetaData( QLatin1String("no-auth-prompt"), QLatin1String("true") ); - job->setRedirectionHandlingEnabled( false ); + QString headers = QStringLiteral("Content-Type: "); + headers += mItem.contentType(); + headers += QLatin1String("\r\n"); + headers += QLatin1String("If-None-Match: *"); + + KIO::StoredTransferJob *job = KIO::storedPut(mItem.data(), mUrl.url(), -1, KIO::HideProgressInfo | KIO::DefaultFlags); + job->addMetaData(QStringLiteral("PropagateHttpHeader"), QStringLiteral("true")); + job->addMetaData(QStringLiteral("customHTTPHeader"), headers); + job->addMetaData(QStringLiteral("cookies"), QStringLiteral("none")); + job->addMetaData(QStringLiteral("no-auth-prompt"), QStringLiteral("true")); + job->setRedirectionHandlingEnabled(false); - connect( job, SIGNAL(result(KJob*)), this, SLOT(davJobFinished(KJob*)) ); + connect(job, &KIO::StoredTransferJob::result, this, &DavItemCreateJob::davJobFinished); } DavItem DavItemCreateJob::item() const { - return mItem; + return mItem; } -void DavItemCreateJob::davJobFinished( KJob *job ) +void DavItemCreateJob::davJobFinished(KJob *job) { - KIO::StoredTransferJob *storedJob = qobject_cast( job ); - const int responseCode = storedJob->queryMetaData( QLatin1String("responsecode") ).isEmpty() ? - 0 : - storedJob->queryMetaData( QLatin1String("responsecode") ).toInt(); - - - if ( storedJob->error() ) { - QString err; - if ( storedJob->error() != KIO::ERR_SLAVE_DEFINED ) - err = KIO::buildErrorString( storedJob->error(), storedJob->errorText() ); - else - err = storedJob->errorText(); - - setLatestResponseCode( responseCode ); - setError( UserDefinedError + responseCode ); - setErrorText( i18n( "There was a problem with the request. The item has not been created on the server.\n" - "%1 (%2).", err, responseCode ) ); + KIO::StoredTransferJob *storedJob = qobject_cast(job); + const int responseCode = storedJob->queryMetaData(QStringLiteral("responsecode")).isEmpty() ? + 0 : + storedJob->queryMetaData(QStringLiteral("responsecode")).toInt(); + + if (storedJob->error()) { + QString err; + if (storedJob->error() != KIO::ERR_SLAVE_DEFINED) { + err = KIO::buildErrorString(storedJob->error(), storedJob->errorText()); + } else { + err = storedJob->errorText(); + } + + setLatestResponseCode(responseCode); + setError(UserDefinedError + responseCode); + setErrorText(i18n("There was a problem with the request. The item has not been created on the server.\n" + "%1 (%2).", err, responseCode)); - emitResult(); - return; - } + emitResult(); + return; + } - // The 'Location:' HTTP header is used to indicate the new URL - const QStringList allHeaders = storedJob->queryMetaData( QLatin1String("HTTP-Headers") ).split( QLatin1Char('\n') ); - QString location; - foreach ( const QString &header, allHeaders ) { - if ( header.startsWith( QLatin1String( "location:" ), Qt::CaseInsensitive ) ) - location = header.section( QLatin1Char(' '), 1 ); - } - - KUrl url; - if ( location.isEmpty() ) - url = storedJob->url(); - else if ( location.startsWith( QLatin1Char('/') ) ) { - url = storedJob->url(); - url.setEncodedPath( location.toLatin1() ); - } else - url = location; - - if ( responseCode == 301 || responseCode == 302 || responseCode == 307 || responseCode == 308 ) { - if ( mRedirectCount > 4 ) { - setLatestResponseCode( responseCode ); - setError( UserDefinedError + responseCode ); - emitResult(); + // The 'Location:' HTTP header is used to indicate the new URL + const QStringList allHeaders = storedJob->queryMetaData(QLatin1String("HTTP-Headers")).split(QLatin1Char('\n')); + QString location; + foreach (const QString &header, allHeaders) { + if (header.startsWith(QLatin1String("location:"), Qt::CaseInsensitive)) { + location = header.section(QLatin1Char(' '), 1); + } } - else { - KUrl itemUrl( url ); - itemUrl.setUser( mUrl.url().user() ); - itemUrl.setPassword( mUrl.url().password() ); - mUrl.setUrl( itemUrl ); - ++mRedirectCount; - start(); + KUrl url; + if (location.isEmpty()) { + url = storedJob->url(); + } else if (location.startsWith(QLatin1Char('/'))) { + url = storedJob->url(); + url.setEncodedPath(location.toLatin1()); + } else { + url = location; } - return; - } + if (responseCode == 301 || responseCode == 302 || responseCode == 307 || responseCode == 308) { + if (mRedirectCount > 4) { + setLatestResponseCode(responseCode); + setError(UserDefinedError + responseCode); + emitResult(); + } else { + KUrl itemUrl(url); + itemUrl.setUser(mUrl.url().user()); + itemUrl.setPassword(mUrl.url().password()); + mUrl.setUrl(itemUrl); + + ++mRedirectCount; + start(); + } + + return; + } - url.setUser( QString() ); - mItem.setUrl( url.prettyUrl() ); + url.setUser(QString()); + mItem.setUrl(url.prettyUrl()); - DavItemFetchJob *fetchJob = new DavItemFetchJob( mUrl, mItem ); - connect( fetchJob, SIGNAL(result(KJob*)), this, SLOT(itemRefreshed(KJob*)) ); - fetchJob->start(); + DavItemFetchJob *fetchJob = new DavItemFetchJob(mUrl, mItem); + connect(fetchJob, &DavItemFetchJob::result, this, &DavItemCreateJob::itemRefreshed); + fetchJob->start(); } -void DavItemCreateJob::itemRefreshed( KJob *job ) +void DavItemCreateJob::itemRefreshed(KJob *job) { - if ( !job->error() ) { - DavItemFetchJob *fetchJob = qobject_cast( job ); - mItem.setEtag( fetchJob->item().etag() ); - } - emitResult(); + if (!job->error()) { + DavItemFetchJob *fetchJob = qobject_cast(job); + mItem.setEtag(fetchJob->item().etag()); + } + emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davitemcreatejob.h kdepim-runtime-15.08.0/resources/dav/common/davitemcreatejob.h --- kdepim-runtime-4.14.6/resources/dav/common/davitemcreatejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davitemcreatejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -28,9 +28,9 @@ */ class DavItemCreateJob : public DavJobBase { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new dav item create job. * @@ -38,12 +38,12 @@ * @param item The item that shall be created. * @param parent The parent object. */ - DavItemCreateJob( const DavUtils::DavUrl &url, const DavItem &item, QObject *parent = 0 ); + DavItemCreateJob(const DavUtils::DavUrl &url, const DavItem &item, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Returns the created DAV item including the correct identifier url @@ -51,11 +51,11 @@ */ DavItem item() const; - private Q_SLOTS: - void davJobFinished( KJob* ); - void itemRefreshed( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); + void itemRefreshed(KJob *); - private: +private: DavUtils::DavUrl mUrl; DavItem mItem; int mRedirectCount; diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davitemdeletejob.cpp kdepim-runtime-15.08.0/resources/dav/common/davitemdeletejob.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davitemdeletejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davitemdeletejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,50 +18,82 @@ #include "davitemdeletejob.h" +#include "davitemfetchjob.h" #include "davmanager.h" #include -#include +#include +#include -DavItemDeleteJob::DavItemDeleteJob( const DavUtils::DavUrl &url, const DavItem &item, QObject *parent ) - : DavJobBase( parent ), mUrl( url ), mItem( item ) +DavItemDeleteJob::DavItemDeleteJob(const DavUtils::DavUrl &url, const DavItem &item, QObject *parent) + : DavJobBase(parent), mUrl(url), mItem(item) { } void DavItemDeleteJob::start() { - KIO::DeleteJob *job = KIO::del( mUrl.url(), KIO::HideProgressInfo | KIO::DefaultFlags ); - job->addMetaData( QLatin1String("PropagateHttpHeader"), QLatin1String("true") ); - job->addMetaData( QLatin1String("customHTTPHeader"), QLatin1String("If-Match: ") + mItem.etag() ); - job->addMetaData( QLatin1String("cookies"), QLatin1String("none") ); - job->addMetaData( QLatin1String("no-auth-prompt"), QLatin1String("true") ); - - connect( job, SIGNAL(result(KJob*)), this, SLOT(davJobFinished(KJob*)) ); -} - -void DavItemDeleteJob::davJobFinished( KJob *job ) -{ - KIO::DeleteJob *deleteJob = qobject_cast( job ); - - if ( deleteJob->error() && deleteJob->error() != KIO::ERR_NO_CONTENT ) { - const int responseCode = deleteJob->queryMetaData( QLatin1String("responsecode") ).isEmpty() ? - 0 : - deleteJob->queryMetaData( QLatin1String("responsecode") ).toInt(); - - if ( responseCode != 404 && responseCode != 410 ) { - QString err; - if ( deleteJob->error() != KIO::ERR_SLAVE_DEFINED ) - err = KIO::buildErrorString( deleteJob->error(), deleteJob->errorText() ); - else - err = deleteJob->errorText(); - - setLatestResponseCode( responseCode ); - setError( UserDefinedError + responseCode ); - setErrorText( i18n( "There was a problem with the request. The item has not been deleted from the server.\n" - "%1 (%2).", err, responseCode ) ); + KIO::DeleteJob *job = KIO::del(mUrl.url(), KIO::HideProgressInfo | KIO::DefaultFlags); + job->addMetaData(QStringLiteral("PropagateHttpHeader"), QStringLiteral("true")); + job->addMetaData(QStringLiteral("customHTTPHeader"), QStringLiteral("If-Match: ") + mItem.etag()); + job->addMetaData(QStringLiteral("cookies"), QStringLiteral("none")); + job->addMetaData(QStringLiteral("no-auth-prompt"), QStringLiteral("true")); + + connect(job, &KIO::DeleteJob::result, this, &DavItemDeleteJob::davJobFinished); +} + +DavItem DavItemDeleteJob::freshItem() const +{ + return mFreshItem; +} + +int DavItemDeleteJob::freshResponseCode() const +{ + return mFreshResponseCode; +} + +void DavItemDeleteJob::davJobFinished(KJob *job) +{ + KIO::DeleteJob *deleteJob = qobject_cast(job); + + if (deleteJob->error() && deleteJob->error() != KIO::ERR_NO_CONTENT) { + const int responseCode = deleteJob->queryMetaData(QStringLiteral("responsecode")).isEmpty() ? + 0 : + deleteJob->queryMetaData(QStringLiteral("responsecode")).toInt(); + + if (responseCode != 404 && responseCode != 410) { + QString err; + if (deleteJob->error() != KIO::ERR_SLAVE_DEFINED) { + err = KIO::buildErrorString(deleteJob->error(), deleteJob->errorText()); + } else { + err = deleteJob->errorText(); + } + + setLatestResponseCode(responseCode); + setError(UserDefinedError + responseCode); + setErrorText(i18n("There was a problem with the request. The item has not been deleted from the server.\n" + "%1 (%2).", err, responseCode)); + } + + if (hasConflict()) { + DavItemFetchJob *fetchJob = new DavItemFetchJob(mUrl, mItem); + connect(fetchJob, &DavItemFetchJob::result, this, &DavItemDeleteJob::conflictingItemFetched); + fetchJob->start(); + return; + } + } + + emitResult(); +} + +void DavItemDeleteJob::conflictingItemFetched(KJob *job) +{ + DavItemFetchJob *fetchJob = qobject_cast(job); + mFreshResponseCode = fetchJob->latestResponseCode(); + + if (!job->error()) { + mFreshItem = fetchJob->item(); } - } - emitResult(); + emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davitemdeletejob.h kdepim-runtime-15.08.0/resources/dav/common/davitemdeletejob.h --- kdepim-runtime-4.14.6/resources/dav/common/davitemdeletejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davitemdeletejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -28,9 +28,9 @@ */ class DavItemDeleteJob : public DavJobBase { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new dav item delete job. * @@ -38,19 +38,32 @@ * @param item The item that shall be deleted. * @param parent The parent object. */ - DavItemDeleteJob( const DavUtils::DavUrl &url, const DavItem &item, QObject *parent = 0 ); + DavItemDeleteJob(const DavUtils::DavUrl &url, const DavItem &item, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; - private Q_SLOTS: - void davJobFinished( KJob* ); + /** + * Returns the item that triggered the conflict, if any. + */ + DavItem freshItem() const; + + /** + * Returns the response code we got when fetching the fresh item. + */ + int freshResponseCode() const; + +private Q_SLOTS: + void davJobFinished(KJob *); + void conflictingItemFetched(KJob *); - private: +private: DavUtils::DavUrl mUrl; DavItem mItem; + DavItem mFreshItem; + int mFreshResponseCode; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davitemfetchjob.cpp kdepim-runtime-15.08.0/resources/dav/common/davitemfetchjob.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davitemfetchjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davitemfetchjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,72 +22,73 @@ #include #include -#include +#include #include -static QString etagFromHeaders( const QString &headers ) +static QString etagFromHeaders(const QString &headers) { - const QStringList allHeaders = headers.split( QLatin1Char('\n') ); + const QStringList allHeaders = headers.split(QLatin1Char('\n')); - QString etag; - foreach ( const QString &header, allHeaders ) { - if ( header.startsWith( QLatin1String( "etag:" ), Qt::CaseInsensitive ) ) - etag = header.section( QLatin1Char(' '), 1 ); - } + QString etag; + foreach (const QString &header, allHeaders) { + if (header.startsWith(QStringLiteral("etag:"), Qt::CaseInsensitive)) { + etag = header.section(QLatin1Char(' '), 1); + } + } - return etag; + return etag; } - -DavItemFetchJob::DavItemFetchJob( const DavUtils::DavUrl &url, const DavItem &item, QObject *parent ) - : KJob( parent ), mUrl( url ), mItem( item ) +DavItemFetchJob::DavItemFetchJob(const DavUtils::DavUrl &url, const DavItem &item, QObject *parent) + : DavJobBase(parent), mUrl(url), mItem(item) { } void DavItemFetchJob::start() { - KIO::StoredTransferJob *job = KIO::storedGet( mUrl.url(), KIO::Reload, KIO::HideProgressInfo | KIO::DefaultFlags ); - job->addMetaData( QLatin1String("PropagateHttpHeader"), QLatin1String("true") ); - // Work around a strange bug in Zimbra (seen at least on CE 5.0.18) : if the user-agent - // contains "Mozilla", some strange debug data is displayed in the shared calendars. - // This kinda mess up the events parsing... - job->addMetaData( QLatin1String("UserAgent"), QLatin1String("KDE DAV groupware client") ); - job->addMetaData( QLatin1String("cookies"), QLatin1String("none") ); - job->addMetaData( QLatin1String("no-auth-prompt"), QLatin1String("true") ); + KIO::StoredTransferJob *job = KIO::storedGet(mUrl.url(), KIO::Reload, KIO::HideProgressInfo | KIO::DefaultFlags); + job->addMetaData(QStringLiteral("PropagateHttpHeader"), QStringLiteral("true")); + // Work around a strange bug in Zimbra (seen at least on CE 5.0.18) : if the user-agent + // contains "Mozilla", some strange debug data is displayed in the shared calendars. + // This kinda mess up the events parsing... + job->addMetaData(QStringLiteral("UserAgent"), QStringLiteral("KDE DAV groupware client")); + job->addMetaData(QStringLiteral("cookies"), QStringLiteral("none")); + job->addMetaData(QStringLiteral("no-auth-prompt"), QStringLiteral("true")); - connect( job, SIGNAL(result(KJob*)), this, SLOT(davJobFinished(KJob*)) ); + connect(job, &KIO::StoredTransferJob::result, this, &DavItemFetchJob::davJobFinished); } DavItem DavItemFetchJob::item() const { - return mItem; + return mItem; } -void DavItemFetchJob::davJobFinished( KJob *job ) +void DavItemFetchJob::davJobFinished(KJob *job) { - KIO::StoredTransferJob *storedJob = qobject_cast( job ); - - if ( storedJob->error() ) { - const int responseCode = storedJob->queryMetaData( QLatin1String("responsecode") ).isEmpty() ? - 0 : - storedJob->queryMetaData( QLatin1String("responsecode") ).toInt(); - - QString err; - if ( storedJob->error() != KIO::ERR_SLAVE_DEFINED ) - err = KIO::buildErrorString( storedJob->error(), storedJob->errorText() ); - else - err = storedJob->errorText(); - - setError( UserDefinedError + responseCode ); - setErrorText( i18n( "There was a problem with the request.\n" - "%1 (%2).", err, responseCode ) ); - } else { - mItem.setData( storedJob->data() ); - mItem.setContentType( storedJob->queryMetaData( QLatin1String("content-type") ) ); - mItem.setEtag( etagFromHeaders( storedJob->queryMetaData( QLatin1String("HTTP-Headers") ) ) ); - } + KIO::StoredTransferJob *storedJob = qobject_cast(job); + const int responseCode = storedJob->queryMetaData(QStringLiteral("responsecode")).isEmpty() ? + 0 : + storedJob->queryMetaData(QStringLiteral("responsecode")).toInt(); + setLatestResponseCode(responseCode); + + if (storedJob->error()) { + QString err; + if (storedJob->error() != KIO::ERR_SLAVE_DEFINED) { + err = KIO::buildErrorString(storedJob->error(), storedJob->errorText()); + } else { + err = storedJob->errorText(); + } + + setError(UserDefinedError + responseCode); + setErrorText(i18n("There was a problem with the request.\n" + "%1 (%2).", err, responseCode)); + } else { + mItem.setData(storedJob->data()); + mItem.setContentType(storedJob->queryMetaData(QStringLiteral("content-type"))); + mItem.setEtag(etagFromHeaders(storedJob->queryMetaData(QStringLiteral("HTTP-Headers")))); + } - emitResult(); + emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davitemfetchjob.h kdepim-runtime-15.08.0/resources/dav/common/davitemfetchjob.h --- kdepim-runtime-4.14.6/resources/dav/common/davitemfetchjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davitemfetchjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,18 +20,17 @@ #define DAVITEMFETCHJOB_H #include "davitem.h" +#include "davjobbase.h" #include "davutils.h" -#include - /** * @short A job that fetches a DAV item from the DAV server. */ -class DavItemFetchJob : public KJob +class DavItemFetchJob : public DavJobBase { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new dav item fetch job. * @@ -39,22 +38,22 @@ * @param item The item that shall be fetched. * @param parent The parent object. */ - DavItemFetchJob( const DavUtils::DavUrl &url, const DavItem &item, QObject *parent = 0 ); + DavItemFetchJob(const DavUtils::DavUrl &url, const DavItem &item, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Returns the fetched item including current etag information. */ DavItem item() const; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: DavUtils::DavUrl mUrl; DavItem mItem; }; diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davitem.h kdepim-runtime-15.08.0/resources/dav/common/davitem.h --- kdepim-runtime-4.14.6/resources/dav/common/davitem.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davitem.h 2015-08-10 21:01:02.000000000 +0000 @@ -35,11 +35,11 @@ */ class DavItem { - public: +public: /** * Defines a list of DAV item objects. */ - typedef QList List; + typedef QVector List; /** * Creates an empty DAV item. @@ -54,12 +54,12 @@ * @param data The actual raw content data of the item. * @param etag The etag of the item. */ - DavItem( const QString &url, const QString &contentType, const QByteArray &data, const QString &etag ); + DavItem(const QString &url, const QString &contentType, const QByteArray &data, const QString &etag); /** * Sets the @p url that identifies the item. */ - void setUrl( const QString &url ); + void setUrl(const QString &url); /** * Returns the url that identifies the item. @@ -69,7 +69,7 @@ /** * Sets the content @p type of the item. */ - void setContentType( const QString &type ); + void setContentType(const QString &type); /** * Returns the content type of the item. @@ -79,7 +79,7 @@ /** * Sets the raw content @p data of the item. */ - void setData( const QByteArray &data ); + void setData(const QByteArray &data); /** * Returns the raw content data of the item. @@ -89,21 +89,21 @@ /** * Sets the @p etag of the item. */ - void setEtag( const QString &etag ); + void setEtag(const QString &etag); /** * Returns the etag of the item. */ QString etag() const; - private: +private: QString mUrl; QString mContentType; QByteArray mData; QString mEtag; }; -QDataStream& operator<<( QDataStream &out, const DavItem &item ); -QDataStream& operator>>( QDataStream &in, DavItem &item); - +QDataStream &operator<<(QDataStream &out, const DavItem &item); +QDataStream &operator>>(QDataStream &in, DavItem &item); +Q_DECLARE_TYPEINFO(DavItem, Q_MOVABLE_TYPE ); #endif diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davitemmodifyjob.cpp kdepim-runtime-15.08.0/resources/dav/common/davitemmodifyjob.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davitemmodifyjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davitemmodifyjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,92 +22,123 @@ #include "davmanager.h" #include -#include +#include -DavItemModifyJob::DavItemModifyJob( const DavUtils::DavUrl &url, const DavItem &item, QObject *parent ) - : DavJobBase( parent ), mUrl( url ), mItem( item ) +DavItemModifyJob::DavItemModifyJob(const DavUtils::DavUrl &url, const DavItem &item, QObject *parent) + : DavJobBase(parent), mUrl(url), mItem(item), mFreshResponseCode(0) { } void DavItemModifyJob::start() { - QString headers = QLatin1String("Content-Type: "); - headers += mItem.contentType(); - headers += QLatin1String("\r\n"); - headers += QLatin1String("If-Match: ") + mItem.etag(); - - KIO::StoredTransferJob *job = KIO::storedPut( mItem.data(), mUrl.url(), -1, KIO::HideProgressInfo | KIO::DefaultFlags ); - job->addMetaData( QLatin1String("PropagateHttpHeader"), QLatin1String("true") ); - job->addMetaData( QLatin1String("customHTTPHeader"), headers ); - job->addMetaData( QLatin1String("cookies"), QLatin1String("none") ); - job->addMetaData( QLatin1String("no-auth-prompt"), QLatin1String("true") ); + QString headers = QLatin1String("Content-Type: "); + headers += mItem.contentType(); + headers += QLatin1String("\r\n"); + headers += QLatin1String("If-Match: ") + mItem.etag(); + + KIO::StoredTransferJob *job = KIO::storedPut(mItem.data(), mUrl.url(), -1, KIO::HideProgressInfo | KIO::DefaultFlags); + job->addMetaData(QStringLiteral("PropagateHttpHeader"), QStringLiteral("true")); + job->addMetaData(QStringLiteral("customHTTPHeader"), headers); + job->addMetaData(QStringLiteral("cookies"), QStringLiteral("none")); + job->addMetaData(QStringLiteral("no-auth-prompt"), QStringLiteral("true")); - connect( job, SIGNAL(result(KJob*)), this, SLOT(davJobFinished(KJob*)) ); + connect(job, &KIO::StoredTransferJob::result, this, &DavItemModifyJob::davJobFinished); } DavItem DavItemModifyJob::item() const { - return mItem; + return mItem; } -void DavItemModifyJob::davJobFinished( KJob *job ) +DavItem DavItemModifyJob::freshItem() const { - KIO::StoredTransferJob *storedJob = qobject_cast( job ); + return mFreshItem; +} - if ( storedJob->error() ) { - const int responseCode = storedJob->queryMetaData( QLatin1String("responsecode") ).isEmpty() ? - 0 : - storedJob->queryMetaData( QLatin1String("responsecode") ).toInt(); +int DavItemModifyJob::freshResponseCode() const +{ + return mFreshResponseCode; +} - QString err; - if ( storedJob->error() != KIO::ERR_SLAVE_DEFINED ) - err = KIO::buildErrorString( storedJob->error(), storedJob->errorText() ); - else - err = storedJob->errorText(); +void DavItemModifyJob::davJobFinished(KJob *job) +{ + KIO::StoredTransferJob *storedJob = qobject_cast(job); - setLatestResponseCode( responseCode ); - setError( UserDefinedError + responseCode ); - setErrorText( i18n( "There was a problem with the request. The item was not modified on the server.\n" - "%1 (%2).", err, responseCode ) ); + if (storedJob->error()) { + const int responseCode = storedJob->queryMetaData(QLatin1String("responsecode")).isEmpty() ? + 0 : + storedJob->queryMetaData(QLatin1String("responsecode")).toInt(); + + QString err; + if (storedJob->error() != KIO::ERR_SLAVE_DEFINED) { + err = KIO::buildErrorString(storedJob->error(), storedJob->errorText()); + } else { + err = storedJob->errorText(); + } + + setLatestResponseCode(responseCode); + setError(UserDefinedError + responseCode); + setErrorText(i18n("There was a problem with the request. The item was not modified on the server.\n" + "%1 (%2).", err, responseCode)); + + if (hasConflict()) { + DavItemFetchJob *fetchJob = new DavItemFetchJob(mUrl, mItem); + connect(fetchJob, &DavItemFetchJob::result, this, &DavItemModifyJob::conflictingItemFetched); + fetchJob->start(); + } else { + emitResult(); + } + + return; + } + + // The 'Location:' HTTP header is used to indicate the new URL + const QStringList allHeaders = storedJob->queryMetaData(QLatin1String("HTTP-Headers")).split(QLatin1Char('\n')); + QString location; + foreach (const QString &header, allHeaders) { + if (header.startsWith(QLatin1String("location:"), Qt::CaseInsensitive)) { + location = header.section(QLatin1Char(' '), 1); + } + } + + KUrl url; + if (location.isEmpty()) { + url = storedJob->url(); + } else if (location.startsWith(QLatin1Char('/'))) { + url = storedJob->url(); + url.setEncodedPath(location.toLatin1()); + } else { + url = location; + } + + url.setUser(QString()); + mItem.setUrl(url.prettyUrl()); + + DavItemFetchJob *fetchJob = new DavItemFetchJob(mUrl, mItem); + connect(fetchJob, &DavItemFetchJob::result, this, &DavItemModifyJob::itemRefreshed); + fetchJob->start(); +} +void DavItemModifyJob::itemRefreshed(KJob *job) +{ + if (!job->error()) { + DavItemFetchJob *fetchJob = qobject_cast(job); + mItem.setEtag(fetchJob->item().etag()); + } else { + mItem.setEtag(QString()); + } emitResult(); - return; - } +} + +void DavItemModifyJob::conflictingItemFetched(KJob *job) +{ + DavItemFetchJob *fetchJob = qobject_cast(job); + mFreshResponseCode = fetchJob->latestResponseCode(); - // The 'Location:' HTTP header is used to indicate the new URL - const QStringList allHeaders = storedJob->queryMetaData( QLatin1String("HTTP-Headers") ).split( QLatin1Char('\n') ); - QString location; - foreach ( const QString &header, allHeaders ) { - if ( header.startsWith( QLatin1String( "location:" ), Qt::CaseInsensitive ) ) - location = header.section( QLatin1Char(' '), 1 ); - } - - KUrl url; - if ( location.isEmpty() ) - url = storedJob->url(); - else if ( location.startsWith( QLatin1Char('/') ) ) { - url = storedJob->url(); - url.setEncodedPath( location.toLatin1() ); - } else - url = location; - - url.setUser( QString() ); - mItem.setUrl( url.prettyUrl() ); - - DavItemFetchJob *fetchJob = new DavItemFetchJob( mUrl, mItem ); - connect( fetchJob, SIGNAL(result(KJob*)), this, SLOT(itemRefreshed(KJob*)) ); - fetchJob->start(); -} - -void DavItemModifyJob::itemRefreshed( KJob *job ) -{ - if ( !job->error() ) { - DavItemFetchJob *fetchJob = qobject_cast( job ); - mItem.setEtag( fetchJob->item().etag() ); - } - else { - mItem.setEtag( QString() ); - } - emitResult(); + if (!job->error()) { + mFreshItem = fetchJob->item(); + } + + emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davitemmodifyjob.h kdepim-runtime-15.08.0/resources/dav/common/davitemmodifyjob.h --- kdepim-runtime-4.14.6/resources/dav/common/davitemmodifyjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davitemmodifyjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -28,9 +28,9 @@ */ class DavItemModifyJob : public DavJobBase { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new dav item modify job. * @@ -38,25 +38,38 @@ * @param item The item that shall be modified. * @param parent The parent object. */ - DavItemModifyJob( const DavUtils::DavUrl &url, const DavItem &item, QObject *parent = 0 ); + DavItemModifyJob(const DavUtils::DavUrl &url, const DavItem &item, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Returns the modified item including the updated etag information. */ DavItem item() const; - private Q_SLOTS: - void davJobFinished( KJob* ); - void itemRefreshed( KJob* ); + /** + * Returns the item that triggered the conflict, if any. + */ + DavItem freshItem() const; + + /** + * Returns the response code we got when fetching the fresh item. + */ + int freshResponseCode() const; + +private Q_SLOTS: + void davJobFinished(KJob *); + void itemRefreshed(KJob *); + void conflictingItemFetched(KJob *); - private: +private: DavUtils::DavUrl mUrl; DavItem mItem; + DavItem mFreshItem; + int mFreshResponseCode; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davitemsfetchjob.cpp kdepim-runtime-15.08.0/resources/dav/common/davitemsfetchjob.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davitemsfetchjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davitemsfetchjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,134 +20,136 @@ #include "davitemsfetchjob.h" #include "davmanager.h" #include "davmultigetprotocol.h" - +#include #include -#include +#include +#include -DavItemsFetchJob::DavItemsFetchJob( const DavUtils::DavUrl &collectionUrl, const QStringList &urls, QObject *parent ) - : KJob( parent ), mCollectionUrl( collectionUrl ), mUrls( urls ) +DavItemsFetchJob::DavItemsFetchJob(const DavUtils::DavUrl &collectionUrl, const QStringList &urls, QObject *parent) + : KJob(parent), mCollectionUrl(collectionUrl), mUrls(urls) { } void DavItemsFetchJob::start() { - const DavMultigetProtocol *protocol = - dynamic_cast( DavManager::self()->davProtocol( mCollectionUrl.protocol() ) ); - if ( !protocol ) { - setError( UserDefinedError ); - setErrorText( i18n( "Protocol for the collection does not support MULTIGET" ) ); - emitResult(); - return; - } + const DavMultigetProtocol *protocol = + dynamic_cast(DavManager::self()->davProtocol(mCollectionUrl.protocol())); + if (!protocol) { + setError(UserDefinedError); + setErrorText(i18n("Protocol for the collection does not support MULTIGET")); + emitResult(); + return; + } - const QDomDocument report = protocol->itemsReportQuery( mUrls ); - KIO::DavJob *job = DavManager::self()->createReportJob( mCollectionUrl.url(), report, QLatin1String( "0" ) ); - job->addMetaData( QLatin1String("PropagateHttpHeader"), QLatin1String("true") ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(davJobFinished(KJob*)) ); + const QDomDocument report = protocol->itemsReportQuery(mUrls); + KIO::DavJob *job = DavManager::self()->createReportJob(mCollectionUrl.url(), report, QStringLiteral("0")); + job->addMetaData(QStringLiteral("PropagateHttpHeader"), QStringLiteral("true")); + connect(job, &KIO::DavJob::result, this, &DavItemsFetchJob::davJobFinished); } DavItem::List DavItemsFetchJob::items() const { - return mItems.values(); + return Akonadi::valuesToVector(mItems); } -DavItem DavItemsFetchJob::item( const QString &url ) const +DavItem DavItemsFetchJob::item(const QString &url) const { - return mItems.value( url ); + return mItems.value(url); } -void DavItemsFetchJob::davJobFinished( KJob *job ) +void DavItemsFetchJob::davJobFinished(KJob *job) { - KIO::DavJob *davJob = qobject_cast( job ); - const int responseCode = davJob->queryMetaData( QLatin1String("responsecode") ).isEmpty() ? - 0 : - davJob->queryMetaData( QLatin1String("responsecode") ).toInt(); - - // KIO::DavJob does not set error() even if the HTTP status code is a 4xx or a 5xx - if ( davJob->error() || ( responseCode >= 400 && responseCode < 600 ) ) { - QString err; - if ( davJob->error() && davJob->error() != KIO::ERR_SLAVE_DEFINED ) - err = KIO::buildErrorString( davJob->error(), davJob->errorText() ); - else - err = davJob->errorText(); - - setError( UserDefinedError + responseCode ); - setErrorText( i18n( "There was a problem with the request.\n" - "%1 (%2).", err, responseCode ) ); - - emitResult(); - return; - } - - const DavMultigetProtocol *protocol = - static_cast( DavManager::self()->davProtocol( mCollectionUrl.protocol() ) ); - - const QDomDocument document = davJob->response(); - const QDomElement documentElement = document.documentElement(); - - QDomElement responseElement = DavUtils::firstChildElementNS( documentElement, QLatin1String("DAV:"), QLatin1String("response") ); + KIO::DavJob *davJob = qobject_cast(job); + const int responseCode = davJob->queryMetaData(QStringLiteral("responsecode")).isEmpty() ? + 0 : + davJob->queryMetaData(QStringLiteral("responsecode")).toInt(); + + // KIO::DavJob does not set error() even if the HTTP status code is a 4xx or a 5xx + if (davJob->error() || (responseCode >= 400 && responseCode < 600)) { + QString err; + if (davJob->error() && davJob->error() != KIO::ERR_SLAVE_DEFINED) { + err = KIO::buildErrorString(davJob->error(), davJob->errorText()); + } else { + err = davJob->errorText(); + } + + setError(UserDefinedError + responseCode); + setErrorText(i18n("There was a problem with the request.\n" + "%1 (%2).", err, responseCode)); - while ( !responseElement.isNull() ) { - QDomElement propstatElement = DavUtils::firstChildElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("propstat") ); - - if ( propstatElement.isNull() ) { - responseElement = DavUtils::nextSiblingElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("response") ); - continue; - } - - // Check for errors - const QDomElement statusElement = DavUtils::firstChildElementNS( propstatElement, QLatin1String("DAV:"), QLatin1String("status") ); - if ( !statusElement.text().contains( QLatin1String("200") ) ) { - responseElement = DavUtils::nextSiblingElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("response") ); - continue; + emitResult(); + return; } - const QDomElement propElement = DavUtils::firstChildElementNS( propstatElement, QLatin1String("DAV:"), QLatin1String("prop") ); + const DavMultigetProtocol *protocol = + static_cast(DavManager::self()->davProtocol(mCollectionUrl.protocol())); - DavItem item; + const QDomDocument document = davJob->response(); + const QDomElement documentElement = document.documentElement(); - // extract path - const QDomElement hrefElement = DavUtils::firstChildElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("href") ); - const QString href = hrefElement.text(); - - KUrl url = davJob->url(); - url.setUser( QString() ); - if ( href.startsWith( QLatin1Char('/') ) ) { - // href is only a path, use request url to complete - url.setEncodedPath( href.toLatin1() ); - } else { - // href is a complete url - KUrl tmpUrl( href ); - url = tmpUrl; - } + QDomElement responseElement = DavUtils::firstChildElementNS(documentElement, QStringLiteral("DAV:"), QStringLiteral("response")); - item.setUrl( url.prettyUrl() ); + while (!responseElement.isNull()) { + QDomElement propstatElement = DavUtils::firstChildElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("propstat")); + + if (propstatElement.isNull()) { + responseElement = DavUtils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response")); + continue; + } + + // Check for errors + const QDomElement statusElement = DavUtils::firstChildElementNS(propstatElement, QStringLiteral("DAV:"), QStringLiteral("status")); + if (!statusElement.text().contains(QLatin1String("200"))) { + responseElement = DavUtils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response")); + continue; + } + + const QDomElement propElement = DavUtils::firstChildElementNS(propstatElement, QStringLiteral("DAV:"), QStringLiteral("prop")); + + DavItem item; + + // extract path + const QDomElement hrefElement = DavUtils::firstChildElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("href")); + const QString href = hrefElement.text(); + + KUrl url = davJob->url(); + url.setUser(QString()); + if (href.startsWith(QLatin1Char('/'))) { + // href is only a path, use request url to complete + url.setEncodedPath(href.toLatin1()); + } else { + // href is a complete url + KUrl tmpUrl(href); + url = tmpUrl; + } + + item.setUrl(url.prettyUrl()); + + // extract etag + const QDomElement getetagElement = DavUtils::firstChildElementNS(propElement, QStringLiteral("DAV:"), QStringLiteral("getetag")); + item.setEtag(getetagElement.text()); + + // extract content + const QDomElement dataElement = DavUtils::firstChildElementNS(propElement, + protocol->responseNamespace(), + protocol->dataTagName()); + + if (dataElement.isNull()) { + responseElement = DavUtils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response")); + continue; + } + + const QByteArray data = dataElement.firstChild().toText().data().toUtf8(); + if (data.isEmpty()) { + responseElement = DavUtils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response")); + continue; + } - // extract etag - const QDomElement getetagElement = DavUtils::firstChildElementNS( propElement, QLatin1String("DAV:"), QLatin1String("getetag") ); - item.setEtag( getetagElement.text() ); - - // extract content - const QDomElement dataElement = DavUtils::firstChildElementNS( propElement, - protocol->responseNamespace(), - protocol->dataTagName() ); - - if ( dataElement.isNull() ) { - responseElement = DavUtils::nextSiblingElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("response") ); - continue; - } + item.setData(data); - const QByteArray data = dataElement.firstChild().toText().data().toUtf8(); - if ( data.isEmpty() ) { - responseElement = DavUtils::nextSiblingElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("response") ); - continue; + mItems.insert(item.url(), item); + responseElement = DavUtils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response")); } - item.setData( data ); - - mItems.insert( item.url(), item ); - responseElement = DavUtils::nextSiblingElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("response") ); - } - - emitResult(); + emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davitemsfetchjob.h kdepim-runtime-15.08.0/resources/dav/common/davitemsfetchjob.h --- kdepim-runtime-4.14.6/resources/dav/common/davitemsfetchjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davitemsfetchjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -33,9 +33,9 @@ */ class DavItemsFetchJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new items fetch job. * @@ -43,12 +43,12 @@ * @param urls The list of urls to fetch * @param parent The parent object */ - DavItemsFetchJob( const DavUtils::DavUrl &collectionUrl, const QStringList &urls, QObject *parent = 0 ); + DavItemsFetchJob(const DavUtils::DavUrl &collectionUrl, const QStringList &urls, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Returns the list of fetched items @@ -58,12 +58,12 @@ /** * Return the item found at @p url */ - DavItem item( const QString &url ) const; + DavItem item(const QString &url) const; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: DavUtils::DavUrl mCollectionUrl; QStringList mUrls; QMap mItems; diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davitemslistjob.cpp kdepim-runtime-15.08.0/resources/dav/common/davitemslistjob.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davitemslistjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davitemslistjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,181 +23,182 @@ #include "davutils.h" #include -#include +#include +#include #include -#include -DavItemsListJob::DavItemsListJob( const DavUtils::DavUrl &url, QObject *parent ) - : KJob( parent ), mUrl( url ), mSubJobCount( 0 ) +DavItemsListJob::DavItemsListJob(const DavUtils::DavUrl &url, QObject *parent) + : KJob(parent), mUrl(url), mSubJobCount(0) { } -void DavItemsListJob::setContentMimeTypes( const QStringList &types ) +void DavItemsListJob::setContentMimeTypes(const QStringList &types) { - mMimeTypes = types; + mMimeTypes = types; } void DavItemsListJob::start() { - const DavProtocolBase *protocol = DavManager::self()->davProtocol( mUrl.protocol() ); - Q_ASSERT( protocol ); - QListIterator it( protocol->itemsQueries() ); - int queryIndex = 0; - - while ( it.hasNext() ) { - const QDomDocument props = it.next(); - const QString mimeType = protocol->mimeTypeForQuery( queryIndex ); - - if ( mMimeTypes.isEmpty() || mMimeTypes.contains( mimeType ) ) { - ++mSubJobCount; - if ( protocol->useReport() ) { - KIO::DavJob *job = DavManager::self()->createReportJob( mUrl.url(), props ); - job->addMetaData( QLatin1String("PropagateHttpHeader"), QLatin1String("true") ); - job->setProperty( "davType", QLatin1String("report") ); - job->setProperty( "itemsMimeType", mimeType ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(davJobFinished(KJob*)) ); - } else { - KIO::DavJob *job = DavManager::self()->createPropFindJob( mUrl.url(), props ); - job->addMetaData( QLatin1String("PropagateHttpHeader"), QLatin1String("true") ); - job->setProperty( "davType", QLatin1String("propFind") ); - job->setProperty( "itemsMimeType", mimeType ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(davJobFinished(KJob*)) ); - } - } + const DavProtocolBase *protocol = DavManager::self()->davProtocol(mUrl.protocol()); + Q_ASSERT(protocol); + QVectorIterator it(protocol->itemsQueries()); + int queryIndex = 0; + + while (it.hasNext()) { + const QDomDocument props = it.next(); + const QString mimeType = protocol->mimeTypeForQuery(queryIndex); + + if (mMimeTypes.isEmpty() || mMimeTypes.contains(mimeType)) { + ++mSubJobCount; + if (protocol->useReport()) { + KIO::DavJob *job = DavManager::self()->createReportJob(mUrl.url(), props); + job->addMetaData(QStringLiteral("PropagateHttpHeader"), QStringLiteral("true")); + job->setProperty("davType", QStringLiteral("report")); + job->setProperty("itemsMimeType", mimeType); + connect(job, &KIO::DavJob::result, this, &DavItemsListJob::davJobFinished); + } else { + KIO::DavJob *job = DavManager::self()->createPropFindJob(mUrl.url(), props); + job->addMetaData(QStringLiteral("PropagateHttpHeader"), QStringLiteral("true")); + job->setProperty("davType", QStringLiteral("propFind")); + job->setProperty("itemsMimeType", mimeType); + connect(job, &KIO::DavJob::result, this, &DavItemsListJob::davJobFinished); + } + } - ++queryIndex; - } + ++queryIndex; + } } DavItem::List DavItemsListJob::items() const { - return mItems; + return mItems; } -void DavItemsListJob::davJobFinished( KJob *job ) +void DavItemsListJob::davJobFinished(KJob *job) { - KIO::DavJob *davJob = qobject_cast( job ); - const int responseCode = davJob->queryMetaData( QLatin1String("responsecode") ).isEmpty() ? - 0 : - davJob->queryMetaData( QLatin1String("responsecode") ).toInt(); - - // KIO::DavJob does not set error() even if the HTTP status code is a 4xx or a 5xx - if ( davJob->error() || ( responseCode >= 400 && responseCode < 600 ) ) { - QString err; - if ( davJob->error() && davJob->error() != KIO::ERR_SLAVE_DEFINED ) - err = KIO::buildErrorString( davJob->error(), davJob->errorText() ); - else - err = davJob->errorText(); - - setError( UserDefinedError + responseCode ); - setErrorText( i18n( "There was a problem with the request.\n" - "%1 (%2).", err, responseCode ) ); - } - else { - /* - * Extract data from a document like the following: - * - * - * - * /caldav.php/test1.user/home/KOrganizer-166749289.780.ics - * - * - * "b4bbea0278f4f63854c4167a7656024a" - * - * HTTP/1.1 200 OK - * - * - * - * /caldav.php/test1.user/home/KOrganizer-399416366.464.ics - * - * - * "52eb129018398a7da4f435b2bc4c6cd5" - * - * HTTP/1.1 200 OK - * - * - * - */ - - const QString itemsMimeType = job->property( "itemsMimeType" ).toString(); - const QDomDocument document = davJob->response(); - const QDomElement documentElement = document.documentElement(); - - QDomElement responseElement = DavUtils::firstChildElementNS( documentElement, QLatin1String("DAV:"), QLatin1String("response") ); - while ( !responseElement.isNull() ) { - - QDomElement propstatElement; - - // check for the valid propstat, without giving up on first error - { - const QDomNodeList propstats = responseElement.elementsByTagNameNS( QLatin1String("DAV:"), QLatin1String("propstat") ); - for ( uint i = 0; i < propstats.length(); ++i ) { - const QDomElement propstatCandidate = propstats.item( i ).toElement(); - const QDomElement statusElement = DavUtils::firstChildElementNS( propstatCandidate, QLatin1String("DAV:"), QLatin1String("status") ); - if ( statusElement.text().contains( QLatin1String("200") ) ) { - propstatElement = propstatCandidate; - } + KIO::DavJob *davJob = qobject_cast(job); + const int responseCode = davJob->queryMetaData(QStringLiteral("responsecode")).isEmpty() ? + 0 : + davJob->queryMetaData(QStringLiteral("responsecode")).toInt(); + + // KIO::DavJob does not set error() even if the HTTP status code is a 4xx or a 5xx + if (davJob->error() || (responseCode >= 400 && responseCode < 600)) { + QString err; + if (davJob->error() && davJob->error() != KIO::ERR_SLAVE_DEFINED) { + err = KIO::buildErrorString(davJob->error(), davJob->errorText()); + } else { + err = davJob->errorText(); } - } - if ( propstatElement.isNull() ) { - responseElement = DavUtils::nextSiblingElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("response") ); - continue; - } - - const QDomElement propElement = DavUtils::firstChildElementNS( propstatElement, QLatin1String("DAV:"), QLatin1String("prop") ); - - // check whether it is a dav collection ... - const QDomElement resourcetypeElement = DavUtils::firstChildElementNS( propElement, QLatin1String("DAV:"), QLatin1String("resourcetype") ); - if ( !responseElement.isNull() ) { - const QDomElement collectionElement = DavUtils::firstChildElementNS( resourcetypeElement, QLatin1String("DAV:"), QLatin1String("collection") ); - if ( !collectionElement.isNull() ) { - responseElement = DavUtils::nextSiblingElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("response") ); - continue; - } - } + setError(UserDefinedError + responseCode); + setErrorText(i18n("There was a problem with the request.\n" + "%1 (%2).", err, responseCode)); + } else { + /* + * Extract data from a document like the following: + * + * + * + * /caldav.php/test1.user/home/KOrganizer-166749289.780.ics + * + * + * "b4bbea0278f4f63854c4167a7656024a" + * + * HTTP/1.1 200 OK + * + * + * + * /caldav.php/test1.user/home/KOrganizer-399416366.464.ics + * + * + * "52eb129018398a7da4f435b2bc4c6cd5" + * + * HTTP/1.1 200 OK + * + * + * + */ + + const QString itemsMimeType = job->property("itemsMimeType").toString(); + const QDomDocument document = davJob->response(); + const QDomElement documentElement = document.documentElement(); + + QDomElement responseElement = DavUtils::firstChildElementNS(documentElement, QStringLiteral("DAV:"), QStringLiteral("response")); + while (!responseElement.isNull()) { + + QDomElement propstatElement; + + // check for the valid propstat, without giving up on first error + { + const QDomNodeList propstats = responseElement.elementsByTagNameNS(QStringLiteral("DAV:"), QStringLiteral("propstat")); + for (int i = 0; i < propstats.length(); ++i) { + const QDomElement propstatCandidate = propstats.item(i).toElement(); + const QDomElement statusElement = DavUtils::firstChildElementNS(propstatCandidate, QStringLiteral("DAV:"), QStringLiteral("status")); + if (statusElement.text().contains(QStringLiteral("200"))) { + propstatElement = propstatCandidate; + } + } + } + + if (propstatElement.isNull()) { + responseElement = DavUtils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response")); + continue; + } + + const QDomElement propElement = DavUtils::firstChildElementNS(propstatElement, QStringLiteral("DAV:"), QStringLiteral("prop")); + + // check whether it is a dav collection ... + const QDomElement resourcetypeElement = DavUtils::firstChildElementNS(propElement, QStringLiteral("DAV:"), QStringLiteral("resourcetype")); + if (!responseElement.isNull()) { + const QDomElement collectionElement = DavUtils::firstChildElementNS(resourcetypeElement, QStringLiteral("DAV:"), QStringLiteral("collection")); + if (!collectionElement.isNull()) { + responseElement = DavUtils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response")); + continue; + } + } + + // ... if not it is an item + DavItem item; + item.setContentType(itemsMimeType); + + // extract path + const QDomElement hrefElement = DavUtils::firstChildElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("href")); + const QString href = hrefElement.text(); + + KUrl url = davJob->url(); + url.setUser(QString()); + if (href.startsWith(QLatin1Char('/'))) { + // href is only a path, use request url to complete + url.setEncodedPath(href.toLatin1()); + } else { + // href is a complete url + KUrl tmpUrl(href); + url = tmpUrl; + } + + QString itemUrl = url.prettyUrl(); + if (mSeenUrls.contains(itemUrl)) { + responseElement = DavUtils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response")); + continue; + } + + mSeenUrls << itemUrl; + item.setUrl(itemUrl); - // ... if not it is an item - DavItem item; - item.setContentType( itemsMimeType ); - - // extract path - const QDomElement hrefElement = DavUtils::firstChildElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("href") ); - const QString href = hrefElement.text(); - - KUrl url = davJob->url(); - url.setUser( QString() ); - if ( href.startsWith( QLatin1Char('/') ) ) { - // href is only a path, use request url to complete - url.setEncodedPath( href.toLatin1() ); - } else { - // href is a complete url - KUrl tmpUrl( href ); - url = tmpUrl; - } - - QString itemUrl = url.prettyUrl(); - if ( mSeenUrls.contains( itemUrl ) ) { - responseElement = DavUtils::nextSiblingElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("response" )); - continue; - } - - mSeenUrls << itemUrl; - item.setUrl( itemUrl ); + // extract etag + const QDomElement getetagElement = DavUtils::firstChildElementNS(propElement, QStringLiteral("DAV:"), QStringLiteral("getetag")); - // extract etag - const QDomElement getetagElement = DavUtils::firstChildElementNS( propElement, QLatin1String("DAV:"), QLatin1String("getetag") ); + item.setEtag(getetagElement.text()); - item.setEtag( getetagElement.text() ); + mItems << item; - mItems << item; - - responseElement = DavUtils::nextSiblingElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("response") ); + responseElement = DavUtils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response")); + } } - } - if ( --mSubJobCount == 0 ) - emitResult(); + if (--mSubJobCount == 0) { + emitResult(); + } } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davitemslistjob.h kdepim-runtime-15.08.0/resources/dav/common/davitemslistjob.h --- kdepim-runtime-4.14.6/resources/dav/common/davitemslistjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davitemslistjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -32,16 +32,16 @@ */ class DavItemsListJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new dav items list job. * * @param url The url of the DAV collection. * @param parent The parent object. */ - explicit DavItemsListJob( const DavUtils::DavUrl &url, QObject *parent = 0 ); + explicit DavItemsListJob(const DavUtils::DavUrl &url, QObject *parent = Q_NULLPTR); /** * Limits the mime types of the items requested. @@ -50,22 +50,22 @@ * * @param types The list of mime types to include */ - void setContentMimeTypes( const QStringList &types ); + void setContentMimeTypes(const QStringList &types); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Returns the list of items including identifier url and etag information. */ DavItem::List items() const; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: DavUtils::DavUrl mUrl; QStringList mMimeTypes; DavItem::List mItems; diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davjobbase.cpp kdepim-runtime-15.08.0/resources/dav/common/davjobbase.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davjobbase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davjobbase.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,67 +18,64 @@ #include "davjobbase.h" -DavJobBase::DavJobBase( QObject *parent ) - : KJob( parent ), mLatestResponseCode( 0 ) +DavJobBase::DavJobBase(QObject *parent) + : KJob(parent), mLatestResponseCode(0) { } unsigned int DavJobBase::latestResponseCode() const { - return mLatestResponseCode; + return mLatestResponseCode; } bool DavJobBase::canRetryLater() const { - bool ret = false; + bool ret = false; - // Be explicit and readable by splitting the if/else if clauses + // Be explicit and readable by splitting the if/else if clauses - if ( latestResponseCode() == 0 && error() ) { - // Likely a timeout or a connection failure. - ret = true; - } - else if ( latestResponseCode() == 401 ) { - // Authentication required - ret = true; - } - else if ( latestResponseCode() == 402 ) { - // Payment required - ret = true; - } - else if ( latestResponseCode() == 407 ) { - // Proxy authentication required - ret = true; - } - else if ( latestResponseCode() == 408 ) { - // Request timeout - ret = true; - } - else if ( latestResponseCode() == 423 ) { - // Locked - ret = true; - } - else if ( latestResponseCode() == 429 ) { - // Too many requests - ret = true; - } - else if ( latestResponseCode() >= 501 && latestResponseCode() <= 504 ) { - // Various server-side errors - ret = true; - } - else if ( latestResponseCode() == 507 ) { - // Insufficient storage - ret = true; - } - else if ( latestResponseCode() == 511 ) { - // Network authentication required - ret = true; - } + if (latestResponseCode() == 0 && error()) { + // Likely a timeout or a connection failure. + ret = true; + } else if (latestResponseCode() == 401) { + // Authentication required + ret = true; + } else if (latestResponseCode() == 402) { + // Payment required + ret = true; + } else if (latestResponseCode() == 407) { + // Proxy authentication required + ret = true; + } else if (latestResponseCode() == 408) { + // Request timeout + ret = true; + } else if (latestResponseCode() == 423) { + // Locked + ret = true; + } else if (latestResponseCode() == 429) { + // Too many requests + ret = true; + } else if (latestResponseCode() >= 501 && latestResponseCode() <= 504) { + // Various server-side errors + ret = true; + } else if (latestResponseCode() == 507) { + // Insufficient storage + ret = true; + } else if (latestResponseCode() == 511) { + // Network authentication required + ret = true; + } - return ret; + return ret; } -void DavJobBase::setLatestResponseCode( unsigned int code ) +bool DavJobBase::hasConflict() const { - mLatestResponseCode = code; + return latestResponseCode() == 412; } + +void DavJobBase::setLatestResponseCode(unsigned int code) +{ + mLatestResponseCode = code; +} + diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davjobbase.h kdepim-runtime-15.08.0/resources/dav/common/davjobbase.h --- kdepim-runtime-4.14.6/resources/dav/common/davjobbase.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davjobbase.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,10 +26,10 @@ */ class DavJobBase : public KJob { - Q_OBJECT + Q_OBJECT - public: - explicit DavJobBase( QObject *parent = 0 ); +public: + explicit DavJobBase(QObject *parent = Q_NULLPTR); /** * Get the latest response code. @@ -60,7 +60,12 @@ */ bool canRetryLater() const; - protected: + /** + * Check if the job failed because of a conflict + */ + bool hasConflict() const; + +protected: /** * Sets the latest response code received. * @@ -69,9 +74,9 @@ * * @param code The code to set, should be a valid HTTP response code or zero. */ - void setLatestResponseCode( unsigned int code ); + void setLatestResponseCode(unsigned int code); - private: +private: unsigned int mLatestResponseCode; }; diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davmanager.cpp kdepim-runtime-15.08.0/resources/dav/common/davmanager.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davmanager.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davmanager.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,11 +23,11 @@ #include "groupdavprotocol.h" #include -#include +#include #include -DavManager* DavManager::mSelf = 0; +DavManager *DavManager::mSelf = Q_NULLPTR; DavManager::DavManager() { @@ -35,86 +35,89 @@ DavManager::~DavManager() { - QMapIterator it( mProtocols ); - while ( it.hasNext() ) { - it.next(); - delete it.value(); - } + QMapIterator it(mProtocols); + while (it.hasNext()) { + it.next(); + delete it.value(); + } } -DavManager* DavManager::self() +DavManager *DavManager::self() { - if ( !mSelf ) - mSelf = new DavManager(); + if (!mSelf) { + mSelf = new DavManager(); + } - return mSelf; + return mSelf; } -KIO::DavJob* DavManager::createPropFindJob( const KUrl &url, const QDomDocument &document, const QString &depth ) const +KIO::DavJob *DavManager::createPropFindJob(const KUrl &url, const QDomDocument &document, const QString &depth) const { - KIO::DavJob *job = KIO::davPropFind( url, document, depth, KIO::HideProgressInfo | KIO::DefaultFlags ); + KIO::DavJob *job = KIO::davPropFind(url, document, depth, KIO::HideProgressInfo | KIO::DefaultFlags); - // workaround needed, Depth: header doesn't seem to be correctly added - const QString header = QLatin1String("Content-Type: text/xml\r\nDepth: ") + depth; - job->addMetaData( QLatin1String("customHTTPHeader"), header ); - job->addMetaData( QLatin1String("cookies"), QLatin1String("none") ); - job->addMetaData( QLatin1String("no-auth-prompt"), QLatin1String("true") ); - job->setProperty( "extraDavDepth", QVariant::fromValue( depth ) ); + // workaround needed, Depth: header doesn't seem to be correctly added + const QString header = QLatin1String("Content-Type: text/xml\r\nDepth: ") + depth; + job->addMetaData(QStringLiteral("customHTTPHeader"), header); + job->addMetaData(QStringLiteral("cookies"), QStringLiteral("none")); + job->addMetaData(QStringLiteral("no-auth-prompt"), QStringLiteral("true")); + job->setProperty("extraDavDepth", QVariant::fromValue(depth)); - return job; + return job; } -KIO::DavJob* DavManager::createReportJob( const KUrl &url, const QDomDocument &document, const QString &depth ) const +KIO::DavJob *DavManager::createReportJob(const KUrl &url, const QDomDocument &document, const QString &depth) const { - KIO::DavJob *job = KIO::davReport( url, document.toString(), depth, KIO::HideProgressInfo | KIO::DefaultFlags ); + KIO::DavJob *job = KIO::davReport(url, document.toString(), depth, KIO::HideProgressInfo | KIO::DefaultFlags); - // workaround needed, Depth: header doesn't seem to be correctly added - const QString header = QLatin1String("Content-Type: text/xml\r\nDepth: ") + depth; - job->addMetaData( QLatin1String("customHTTPHeader"), header ); - job->addMetaData( QLatin1String("cookies"), QLatin1String("none") ); - job->addMetaData( QLatin1String("no-auth-prompt"), QLatin1String("true") ); - job->setProperty( "extraDavDepth", QVariant::fromValue( depth ) ); + // workaround needed, Depth: header doesn't seem to be correctly added + const QString header = QLatin1String("Content-Type: text/xml\r\nDepth: ") + depth; + job->addMetaData(QStringLiteral("customHTTPHeader"), header); + job->addMetaData(QStringLiteral("cookies"), QStringLiteral("none")); + job->addMetaData(QStringLiteral("no-auth-prompt"), QStringLiteral("true")); + job->setProperty("extraDavDepth", QVariant::fromValue(depth)); - return job; + return job; } -KIO::DavJob* DavManager::createPropPatchJob( const KUrl &url, const QDomDocument &document ) const +KIO::DavJob *DavManager::createPropPatchJob(const KUrl &url, const QDomDocument &document) const { - KIO::DavJob *job = KIO::davPropPatch( url, document, KIO::HideProgressInfo | KIO::DefaultFlags ); - const QString header = QLatin1String("Content-Type: text/xml"); - job->addMetaData( QLatin1String("customHTTPHeader"), header ); - job->addMetaData( QLatin1String("cookies"), QLatin1String("none") ); - job->addMetaData( QLatin1String("no-auth-prompt"), QLatin1String("true") ); - return job; + KIO::DavJob *job = KIO::davPropPatch(url, document, KIO::HideProgressInfo | KIO::DefaultFlags); + const QString header = QLatin1String("Content-Type: text/xml"); + job->addMetaData(QStringLiteral("customHTTPHeader"), header); + job->addMetaData(QStringLiteral("cookies"), QStringLiteral("none")); + job->addMetaData(QStringLiteral("no-auth-prompt"), QStringLiteral("true")); + return job; } -const DavProtocolBase* DavManager::davProtocol( DavUtils::Protocol protocol ) +const DavProtocolBase *DavManager::davProtocol(DavUtils::Protocol protocol) { - if ( createProtocol( protocol ) ) - return mProtocols[ protocol ]; - else - return 0; + if (createProtocol(protocol)) { + return mProtocols[ protocol ]; + } else { + return Q_NULLPTR; + } } -bool DavManager::createProtocol( DavUtils::Protocol protocol ) +bool DavManager::createProtocol(DavUtils::Protocol protocol) { - if ( mProtocols.contains( protocol ) ) - return true; + if (mProtocols.contains(protocol)) { + return true; + } - switch( protocol ) { + switch (protocol) { case DavUtils::CalDav: - mProtocols.insert( DavUtils::CalDav, new CaldavProtocol() ); - break; + mProtocols.insert(DavUtils::CalDav, new CaldavProtocol()); + break; case DavUtils::CardDav: - mProtocols.insert( DavUtils::CardDav, new CarddavProtocol() ); - break; + mProtocols.insert(DavUtils::CardDav, new CarddavProtocol()); + break; case DavUtils::GroupDav: - mProtocols.insert( DavUtils::GroupDav, new GroupdavProtocol() ); - break; + mProtocols.insert(DavUtils::GroupDav, new GroupdavProtocol()); + break; default: - kError() << "Unknown protocol: " << static_cast( protocol ); - return false; - } + qCritical() << "Unknown protocol: " << static_cast(protocol); + return false; + } - return true; + return true; } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davmanager.h kdepim-runtime-15.08.0/resources/dav/common/davmanager.h --- kdepim-runtime-4.14.6/resources/dav/common/davmanager.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davmanager.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,7 +26,8 @@ class DavProtocolBase; -namespace KIO { +namespace KIO +{ class DavJob; } @@ -43,7 +44,7 @@ */ class DavManager { - public: +public: /** * Destroys the DAV manager. */ @@ -52,7 +53,7 @@ /** * Returns the global instance of the DAV manager. */ - static DavManager* self(); + static DavManager *self(); /** * Returns a preconfigured DAV PROPFIND job. @@ -61,7 +62,7 @@ * @param document The query XML document. * @param depth The Depth: value to send in the HTTP request */ - KIO::DavJob* createPropFindJob( const KUrl &url, const QDomDocument &document, const QString &depth = QLatin1String( "1" ) ) const; + KIO::DavJob *createPropFindJob(const KUrl &url, const QDomDocument &document, const QString &depth = QLatin1String("1")) const; /** * Returns a preconfigured DAV REPORT job. @@ -70,7 +71,7 @@ * @param document The query XML document. * @param depth The Depth: value to send in the HTTP request */ - KIO::DavJob* createReportJob( const KUrl &url, const QDomDocument &document, const QString &depth = QLatin1String( "1" ) ) const; + KIO::DavJob *createReportJob(const KUrl &url, const QDomDocument &document, const QString &depth = QLatin1String("1")) const; /** * Returns a preconfigured DAV PROPPATCH job. @@ -78,14 +79,14 @@ * @param url The target url of the job. * @param document The query XML document. */ - KIO::DavJob* createPropPatchJob( const KUrl &url, const QDomDocument &document ) const; + KIO::DavJob *createPropPatchJob(const KUrl &url, const QDomDocument &document) const; /** * Returns the DAV protocol dialect object for the given DAV @p protocol. */ - const DavProtocolBase* davProtocol( DavUtils::Protocol protocol ); + const DavProtocolBase *davProtocol(DavUtils::Protocol protocol); - private: +private: /** * Creates a new DAV manager. */ @@ -94,11 +95,11 @@ /** * Creates a new protocol. */ - bool createProtocol( DavUtils::Protocol protocol ); + bool createProtocol(DavUtils::Protocol protocol); - typedef QMap protocolsMap; + typedef QMap protocolsMap; protocolsMap mProtocols; - static DavManager* mSelf; + static DavManager *mSelf; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davmultigetprotocol.h kdepim-runtime-15.08.0/resources/dav/common/davmultigetprotocol.h --- kdepim-runtime-4.14.6/resources/dav/common/davmultigetprotocol.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davmultigetprotocol.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,7 +26,7 @@ */ class DavMultigetProtocol : public DavProtocolBase { - public: +public: /** * Destroys the DAV protocol */ @@ -36,7 +36,7 @@ * Returns the XML document that represents a MULTIGET DAV query to * list all DAV resources with the given @p urls. */ - virtual QDomDocument itemsReportQuery( const QStringList &urls ) const = 0; + virtual QDomDocument itemsReportQuery(const QStringList &urls) const = 0; /** * Returns the namespace used by protocol-specific elements found in responses. diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davprincipalhomesetsfetchjob.cpp kdepim-runtime-15.08.0/resources/dav/common/davprincipalhomesetsfetchjob.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davprincipalhomesetsfetchjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davprincipalhomesetsfetchjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,198 +22,203 @@ #include "davprotocolbase.h" #include -#include +#include +#include -DavPrincipalHomeSetsFetchJob::DavPrincipalHomeSetsFetchJob( const DavUtils::DavUrl &url, QObject *parent ) - : KJob( parent ), mUrl( url ) +DavPrincipalHomeSetsFetchJob::DavPrincipalHomeSetsFetchJob(const DavUtils::DavUrl &url, QObject *parent) + : DavJobBase(parent), mUrl(url) { } void DavPrincipalHomeSetsFetchJob::start() { - fetchHomeSets( false ); + fetchHomeSets(false); } -void DavPrincipalHomeSetsFetchJob::fetchHomeSets( bool homeSetsOnly ) +void DavPrincipalHomeSetsFetchJob::fetchHomeSets(bool homeSetsOnly) { - QDomDocument document; + QDomDocument document; - QDomElement propfindElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("propfind") ); - document.appendChild( propfindElement ); + QDomElement propfindElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("propfind")); + document.appendChild(propfindElement); - QDomElement propElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("prop") ); - propfindElement.appendChild( propElement ); + QDomElement propElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + propfindElement.appendChild(propElement); - const QString homeSet = DavManager::self()->davProtocol( mUrl.protocol() )->principalHomeSet(); - const QString homeSetNS = DavManager::self()->davProtocol( mUrl.protocol() )->principalHomeSetNS(); - propElement.appendChild( document.createElementNS( homeSetNS, homeSet ) ); - - if ( !homeSetsOnly ) { - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("current-user-principal" )) ); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("principal-URL") ) ); - } - - KIO::DavJob *job = DavManager::self()->createPropFindJob( mUrl.url(), document, QLatin1String("0") ); - job->addMetaData( QLatin1String("PropagateHttpHeader"),QLatin1String("true") ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + const QString homeSet = DavManager::self()->davProtocol(mUrl.protocol())->principalHomeSet(); + const QString homeSetNS = DavManager::self()->davProtocol(mUrl.protocol())->principalHomeSetNS(); + propElement.appendChild(document.createElementNS(homeSetNS, homeSet)); + + if (!homeSetsOnly) { + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("current-user-principal"))); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("principal-URL"))); + } + + KIO::DavJob *job = DavManager::self()->createPropFindJob(mUrl.url(), document, QStringLiteral("0")); + job->addMetaData(QStringLiteral("PropagateHttpHeader"), QStringLiteral("true")); + connect(job, &KIO::DavJob::result, this, &DavPrincipalHomeSetsFetchJob::davJobFinished); } QStringList DavPrincipalHomeSetsFetchJob::homeSets() const { - return mHomeSets; + return mHomeSets; } -void DavPrincipalHomeSetsFetchJob::davJobFinished( KJob *job ) +void DavPrincipalHomeSetsFetchJob::davJobFinished(KJob *job) { - KIO::DavJob *davJob = qobject_cast( job ); - const int responseCode = davJob->queryMetaData( QLatin1String("responsecode") ).isEmpty() ? - 0 : - davJob->queryMetaData( QLatin1String("responsecode") ).toInt(); - - // KIO::DavJob does not set error() even if the HTTP status code is a 4xx or a 5xx - if ( davJob->error() || ( responseCode >= 400 && responseCode < 600 ) ) { - QString err; - if ( davJob->error() && davJob->error() != KIO::ERR_SLAVE_DEFINED ) - err = KIO::buildErrorString( davJob->error(), davJob->errorText() ); - else - err = davJob->errorText(); - - setError( UserDefinedError + responseCode ); - setErrorText( i18n( "There was a problem with the request.\n" - "%1 (%2).", err, responseCode ) ); - - emitResult(); - return; - } - - /* - * Extract information from a document like the following (if no homeset is defined) : - * - * - * - * /dav/ - * - * HTTP/1.1 200 OK - * - * - * /principals/users/gdacoin/ - * - * - * - * - * HTTP/1.1 404 Not Found - * - * - * - * - * - * - * - * - * Or like this (if the homeset is defined): - * - * - * - * - * /principals/users/greg%40kamago.net/ - * - * - * - * /greg%40kamago.net/ - * - * - * HTTP/1.1 200 OK - * - * - * - */ - - const QString homeSet = DavManager::self()->davProtocol( mUrl.protocol() )->principalHomeSet(); - const QString homeSetNS = DavManager::self()->davProtocol( mUrl.protocol() )->principalHomeSetNS(); - QString nextRoundHref; // The content of the href element that will be used if no homeset was found. - // This is either given by current-user-principal or by principal-URL. - - const QDomDocument document = davJob->response(); - const QDomElement multistatusElement = document.documentElement(); - - QDomElement responseElement = DavUtils::firstChildElementNS( multistatusElement, QLatin1String("DAV:"), QLatin1String("response") ); - while ( !responseElement.isNull() ) { - - QDomElement propstatElement; - - // check for the valid propstat, without giving up on first error - { - const QDomNodeList propstats = responseElement.elementsByTagNameNS( QLatin1String("DAV:"), QLatin1String("propstat") ); - for ( uint i = 0; i < propstats.length(); ++i ) { - const QDomElement propstatCandidate = propstats.item( i ).toElement(); - const QDomElement statusElement = DavUtils::firstChildElementNS( propstatCandidate, QLatin1String("DAV:"), QLatin1String("status") ); - if ( statusElement.text().contains( QLatin1String("200") ) ) { - propstatElement = propstatCandidate; + KIO::DavJob *davJob = qobject_cast(job); + const int responseCode = davJob->queryMetaData(QStringLiteral("responsecode")).isEmpty() ? + 0 : + davJob->queryMetaData(QStringLiteral("responsecode")).toInt(); + + // KIO::DavJob does not set error() even if the HTTP status code is a 4xx or a 5xx + if (davJob->error() || (responseCode >= 400 && responseCode < 600)) { + QString err; + if (davJob->error() && davJob->error() != KIO::ERR_SLAVE_DEFINED) { + err = KIO::buildErrorString(davJob->error(), davJob->errorText()); + } else { + err = davJob->errorText(); } - } - } - if ( propstatElement.isNull() ) { - responseElement = DavUtils::nextSiblingElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("response") ); - continue; + setLatestResponseCode( responseCode ); + setError(UserDefinedError + responseCode); + setErrorText(i18n("There was a problem with the request.\n" + "%1 (%2).", err, responseCode)); + + emitResult(); + return; } - // extract home sets - const QDomElement propElement = DavUtils::firstChildElementNS( propstatElement, QLatin1String("DAV:"), QLatin1String("prop") ); - const QDomElement homeSetElement = DavUtils::firstChildElementNS( propElement, homeSetNS, homeSet ); - - if ( !homeSetElement.isNull() ) { - QDomElement hrefElement = DavUtils::firstChildElementNS( homeSetElement, QLatin1String("DAV:"), QLatin1String("href") ); - - while ( !hrefElement.isNull() ) { - const QString href = hrefElement.text(); - if ( !mHomeSets.contains( href ) ) - mHomeSets << href; + /* + * Extract information from a document like the following (if no homeset is defined) : + * + * + * + * /dav/ + * + * HTTP/1.1 200 OK + * + * + * /principals/users/gdacoin/ + * + * + * + * + * HTTP/1.1 404 Not Found + * + * + * + * + * + * + * + * + * Or like this (if the homeset is defined): + * + * + * + * + * /principals/users/greg%40kamago.net/ + * + * + * + * /greg%40kamago.net/ + * + * + * HTTP/1.1 200 OK + * + * + * + */ + + const QString homeSet = DavManager::self()->davProtocol(mUrl.protocol())->principalHomeSet(); + const QString homeSetNS = DavManager::self()->davProtocol(mUrl.protocol())->principalHomeSetNS(); + QString nextRoundHref; // The content of the href element that will be used if no homeset was found. + // This is either given by current-user-principal or by principal-URL. + + const QDomDocument document = davJob->response(); + const QDomElement multistatusElement = document.documentElement(); + + QDomElement responseElement = DavUtils::firstChildElementNS(multistatusElement, QStringLiteral("DAV:"), QStringLiteral("response")); + while (!responseElement.isNull()) { + + QDomElement propstatElement; + + // check for the valid propstat, without giving up on first error + { + const QDomNodeList propstats = responseElement.elementsByTagNameNS(QLatin1String("DAV:"), QStringLiteral("propstat")); + for (int i = 0; i < propstats.length(); ++i) { + const QDomElement propstatCandidate = propstats.item(i).toElement(); + const QDomElement statusElement = DavUtils::firstChildElementNS(propstatCandidate, QStringLiteral("DAV:"), QStringLiteral("status")); + if (statusElement.text().contains(QLatin1String("200"))) { + propstatElement = propstatCandidate; + } + } + } - hrefElement = DavUtils::nextSiblingElementNS( hrefElement, QLatin1String("DAV:"), QLatin1String("href") ); - } - } - else { - // Trying to get the principal url, given either by current-user-principal or principal-URL - QDomElement urlHolder = DavUtils::firstChildElementNS( propElement, QLatin1String("DAV:"), QLatin1String("current-user-principal") ); - if ( urlHolder.isNull() ) - urlHolder = DavUtils::firstChildElementNS( propElement, QLatin1String("DAV:"), QLatin1String("principal-URL") ); - - if ( !urlHolder.isNull() ) { - // Getting the href that will be used for the next round - QDomElement hrefElement = DavUtils::firstChildElementNS( urlHolder, QLatin1String("DAV:"), QLatin1String("href") ); - if ( !hrefElement.isNull() ) - nextRoundHref = hrefElement.text(); - } - } + if (propstatElement.isNull()) { + responseElement = DavUtils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response")); + continue; + } - responseElement = DavUtils::nextSiblingElementNS( responseElement, QLatin1String("DAV:"), QLatin1String("response") ); - } + // extract home sets + const QDomElement propElement = DavUtils::firstChildElementNS(propstatElement, QStringLiteral("DAV:"), QStringLiteral("prop")); + const QDomElement homeSetElement = DavUtils::firstChildElementNS(propElement, homeSetNS, homeSet); + + if (!homeSetElement.isNull()) { + QDomElement hrefElement = DavUtils::firstChildElementNS(homeSetElement, QStringLiteral("DAV:"), QStringLiteral("href")); + + while (!hrefElement.isNull()) { + const QString href = hrefElement.text(); + if (!mHomeSets.contains(href)) { + mHomeSets << href; + } + + hrefElement = DavUtils::nextSiblingElementNS(hrefElement, QStringLiteral("DAV:"), QStringLiteral("href")); + } + } else { + // Trying to get the principal url, given either by current-user-principal or principal-URL + QDomElement urlHolder = DavUtils::firstChildElementNS(propElement, QStringLiteral("DAV:"), QStringLiteral("current-user-principal")); + if (urlHolder.isNull()) { + urlHolder = DavUtils::firstChildElementNS(propElement, QStringLiteral("DAV:"), QStringLiteral("principal-URL")); + } + + if (!urlHolder.isNull()) { + // Getting the href that will be used for the next round + QDomElement hrefElement = DavUtils::firstChildElementNS(urlHolder, QStringLiteral("DAV:"), QStringLiteral("href")); + if (!hrefElement.isNull()) { + nextRoundHref = hrefElement.text(); + } + } + } - /* - * Now either we got one or more homesets, or we got an href for the next round - * or nothing can be found by this job. - * If we have homesets, we're done here and can notify the caller. - * Else we must ensure that we have an href for the next round. - */ - if ( !mHomeSets.isEmpty() || nextRoundHref.isEmpty() ) { - emitResult(); - } else { - KUrl nextRoundUrl( mUrl.url() ); - - if ( nextRoundHref.startsWith( QLatin1Char('/') ) ) { - // nextRoundHref is only a path, use request url to complete - nextRoundUrl.setEncodedPath( nextRoundHref.toLatin1() ); - } else { - // href is a complete url - KUrl tmpUrl( nextRoundHref ); - nextRoundUrl = tmpUrl; - nextRoundUrl.setUser( mUrl.url().user() ); - nextRoundUrl.setPass( mUrl.url().pass() ); + responseElement = DavUtils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response")); } - mUrl.setUrl( nextRoundUrl ); - // And one more round, fetching only homesets - fetchHomeSets( true ); - } + /* + * Now either we got one or more homesets, or we got an href for the next round + * or nothing can be found by this job. + * If we have homesets, we're done here and can notify the caller. + * Else we must ensure that we have an href for the next round. + */ + if (!mHomeSets.isEmpty() || nextRoundHref.isEmpty()) { + emitResult(); + } else { + KUrl nextRoundUrl(mUrl.url()); + + if (nextRoundHref.startsWith(QLatin1Char('/'))) { + // nextRoundHref is only a path, use request url to complete + nextRoundUrl.setEncodedPath(nextRoundHref.toLatin1()); + } else { + // href is a complete url + KUrl tmpUrl(nextRoundHref); + nextRoundUrl = tmpUrl; + nextRoundUrl.setUser(mUrl.url().user()); + nextRoundUrl.setPass(mUrl.url().pass()); + } + + mUrl.setUrl(nextRoundUrl); + // And one more round, fetching only homesets + fetchHomeSets(true); + } } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davprincipalhomesetsfetchjob.h kdepim-runtime-15.08.0/resources/dav/common/davprincipalhomesetsfetchjob.h --- kdepim-runtime-4.14.6/resources/dav/common/davprincipalhomesetsfetchjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davprincipalhomesetsfetchjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -19,6 +19,7 @@ #ifndef DAVPRINCIPALHOMESETSFETCHJOB_H #define DAVPRINCIPALHOMESETSFETCHJOB_H +#include "davjobbase.h" #include "davutils.h" #include @@ -28,46 +29,46 @@ /** * @short A job that fetches home sets for a principal. */ -class DavPrincipalHomeSetsFetchJob : public KJob +class DavPrincipalHomeSetsFetchJob : public DavJobBase { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new dav principals home sets fetch job. * * @param url The DAV url of the DAV principal. * @param parent The parent object. */ - explicit DavPrincipalHomeSetsFetchJob( const DavUtils::DavUrl &url, QObject *parent = 0 ); + explicit DavPrincipalHomeSetsFetchJob(const DavUtils::DavUrl &url, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Returns the found home sets. */ QStringList homeSets() const; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: /** * Start the fetch process. - * + * * There may be two rounds necessary if the first request * does not returns the home sets, but only the current-user-principal * or the principal-URL. The bool flag is here to prevent requesting * those last two on each request, as they are only fetched in * the first round. - * + * * @param fetchHomeSetsOnly If set to true the request will not include * the current-user-principal and principal-URL props. */ - void fetchHomeSets( bool fetchHomeSetsOnly ); + void fetchHomeSets(bool fetchHomeSetsOnly); DavUtils::DavUrl mUrl; QStringList mHomeSets; diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davprincipalsearchjob.cpp kdepim-runtime-15.08.0/resources/dav/common/davprincipalsearchjob.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davprincipalsearchjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davprincipalsearchjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,350 +20,360 @@ #include "davmanager.h" +#include #include -#include -#include +#include -DavPrincipalSearchJob::DavPrincipalSearchJob( const DavUtils::DavUrl& url, DavPrincipalSearchJob::FilterType type, - const QString& filter, QObject* parent ) - : KJob( parent ), mUrl( url ), mType( type), mFilter( filter ), mPrincipalPropertySearchSubJobCount( 0 ), - mPrincipalPropertySearchSubJobSuccessful( false ) +DavPrincipalSearchJob::DavPrincipalSearchJob(const DavUtils::DavUrl &url, DavPrincipalSearchJob::FilterType type, + const QString &filter, QObject *parent) + : KJob(parent), mUrl(url), mType(type), mFilter(filter), mPrincipalPropertySearchSubJobCount(0), + mPrincipalPropertySearchSubJobSuccessful(false) { } -void DavPrincipalSearchJob::fetchProperty( const QString& name, const QString& ns ) +void DavPrincipalSearchJob::fetchProperty(const QString &name, const QString &ns) { - QString propNamespace = ns; - if ( propNamespace.isEmpty() ) - propNamespace = QLatin1String("DAV:"); + QString propNamespace = ns; + if (propNamespace.isEmpty()) { + propNamespace = QStringLiteral("DAV:"); + } - mFetchProperties << QPair( propNamespace, name ); + mFetchProperties << QPair(propNamespace, name); } DavUtils::DavUrl DavPrincipalSearchJob::davUrl() const { - return mUrl; + return mUrl; } void DavPrincipalSearchJob::start() { - /* - * The first step is to try to locate the URL that contains the principals. - * This is done with a PROPFIND request and a XML like this: - * - * - * - * - * - * - */ - QDomDocument query; - - QDomElement propfind = query.createElementNS( QLatin1String("DAV:"), QLatin1String("propfind") ); - query.appendChild( propfind ); - - QDomElement prop = query.createElementNS( QLatin1String("DAV:"), QLatin1String("prop" )); - propfind.appendChild( prop ); - - QDomElement principalCollectionSet = query.createElementNS( QLatin1String("DAV:"), QLatin1String("principal-collection-set") ); - prop.appendChild( principalCollectionSet ); - - KIO::DavJob *job = DavManager::self()->createPropFindJob( mUrl.url(), query ); - job->addMetaData( QLatin1String("PropagateHttpHeader"), QLatin1String("true") ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(principalCollectionSetSearchFinished(KJob*)) ); - job->start(); + /* + * The first step is to try to locate the URL that contains the principals. + * This is done with a PROPFIND request and a XML like this: + * + * + * + * + * + * + */ + QDomDocument query; + + QDomElement propfind = query.createElementNS(QStringLiteral("DAV:"), QStringLiteral("propfind")); + query.appendChild(propfind); + + QDomElement prop = query.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + propfind.appendChild(prop); + + QDomElement principalCollectionSet = query.createElementNS(QStringLiteral("DAV:"), QStringLiteral("principal-collection-set")); + prop.appendChild(principalCollectionSet); + + KIO::DavJob *job = DavManager::self()->createPropFindJob(mUrl.url(), query); + job->addMetaData(QStringLiteral("PropagateHttpHeader"), QStringLiteral("true")); + connect(job, &KIO::DavJob::result, this, &DavPrincipalSearchJob::principalCollectionSetSearchFinished); + job->start(); } -void DavPrincipalSearchJob::principalCollectionSetSearchFinished( KJob* job ) +void DavPrincipalSearchJob::principalCollectionSetSearchFinished(KJob *job) { - KIO::DavJob *davJob = qobject_cast( job ); - const int responseCode = davJob->queryMetaData( QLatin1String("responsecode") ).isEmpty() ? - 0 : - davJob->queryMetaData( QLatin1String("responsecode") ).toInt(); - - // KIO::DavJob does not set error() even if the HTTP status code is a 4xx or a 5xx - if ( davJob->error() || ( responseCode >= 400 && responseCode < 600 ) ) { - QString err; - if ( davJob->error() && davJob->error() != KIO::ERR_SLAVE_DEFINED ) - err = KIO::buildErrorString( davJob->error(), davJob->errorText() ); - else - err = davJob->errorText(); - - setError( UserDefinedError + responseCode ); - setErrorText( i18n( "There was a problem with the request.\n" - "%1 (%2).", err, responseCode ) ); - - emitResult(); - return; - } - - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } - - /* - * Extract information from a document like the following: - * - * - * - * - * http://www.example.com/papers/ - * - * - * - * http://www.example.com/acl/users/ - * http://www.example.com/acl/groups/ - * - * - * HTTP/1.1 200 OK - * - * - * - */ - - QDomDocument document = davJob->response(); - QDomElement documentElement = document.documentElement(); - - QDomElement responseElement = DavUtils::firstChildElementNS( documentElement, QLatin1String("DAV:"), QLatin1String("response") ); - if ( responseElement.isNull() ) { - emitResult(); - return; - } - - // check for the valid propstat, without giving up on first error - QDomElement propstatElement; - { - const QDomNodeList propstats = responseElement.elementsByTagNameNS( QLatin1String("DAV:"), QLatin1String("propstat")); - for ( uint i = 0; i < propstats.length(); ++i ) { - const QDomElement propstatCandidate = propstats.item( i ).toElement(); - const QDomElement statusElement = DavUtils::firstChildElementNS( propstatCandidate, QLatin1String("DAV:"), QLatin1String("status") ); - if ( statusElement.text().contains( QLatin1String("200") ) ) { - propstatElement = propstatCandidate; - } - } - } - - if ( propstatElement.isNull() ) { - emitResult(); - return; - } - - QDomElement propElement = DavUtils::firstChildElementNS( propstatElement, QLatin1String("DAV:"), QLatin1String("prop") ); - if ( propElement.isNull() ) { - emitResult(); - return; - } - - QDomElement principalCollectionSetElement = DavUtils::firstChildElementNS( propElement, QLatin1String("DAV:"), QLatin1String("principal-collection-set") ); - if ( principalCollectionSetElement.isNull() ) { - emitResult(); - return; - } - - QDomNodeList hrefNodes = principalCollectionSetElement.elementsByTagNameNS( QLatin1String("DAV:"), QLatin1String("href") ); - for ( int i = 0; i < hrefNodes.size(); ++i ) { - QDomElement hrefElement = hrefNodes.at( i ).toElement(); - QString href = hrefElement.text(); - - KUrl url = mUrl.url(); - if ( href.startsWith( QLatin1Char('/') ) ) { - // href is only a path, use request url to complete - url.setEncodedPath( href.toLatin1() ); - } else { - // href is a complete url - KUrl tmpUrl( href ); - tmpUrl.setUser( url.user() ); - tmpUrl.setPass( url.pass() ); - url = tmpUrl; - } - - QDomDocument principalPropertySearchQuery; - buildReportQuery( principalPropertySearchQuery ); - KIO::DavJob *reportJob = DavManager::self()->createReportJob( url, principalPropertySearchQuery ); - reportJob->addMetaData( QLatin1String("PropagateHttpHeader"), QLatin1String("true") ); - connect( reportJob, SIGNAL(result(KJob*)), this, SLOT(principalPropertySearchFinished(KJob*)) ); - ++mPrincipalPropertySearchSubJobCount; - reportJob->start(); - } + KIO::DavJob *davJob = qobject_cast(job); + const int responseCode = davJob->queryMetaData(QStringLiteral("responsecode")).isEmpty() ? + 0 : + davJob->queryMetaData(QStringLiteral("responsecode")).toInt(); + + // KIO::DavJob does not set error() even if the HTTP status code is a 4xx or a 5xx + if (davJob->error() || (responseCode >= 400 && responseCode < 600)) { + QString err; + if (davJob->error() && davJob->error() != KIO::ERR_SLAVE_DEFINED) { + err = KIO::buildErrorString(davJob->error(), davJob->errorText()); + } else { + err = davJob->errorText(); + } + + setError(UserDefinedError + responseCode); + setErrorText(i18n("There was a problem with the request.\n" + "%1 (%2).", err, responseCode)); + + emitResult(); + return; + } + + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } + + /* + * Extract information from a document like the following: + * + * + * + * + * http://www.example.com/papers/ + * + * + * + * http://www.example.com/acl/users/ + * http://www.example.com/acl/groups/ + * + * + * HTTP/1.1 200 OK + * + * + * + */ + + QDomDocument document = davJob->response(); + QDomElement documentElement = document.documentElement(); + + QDomElement responseElement = DavUtils::firstChildElementNS(documentElement, QStringLiteral("DAV:"), QStringLiteral("response")); + if (responseElement.isNull()) { + emitResult(); + return; + } + + // check for the valid propstat, without giving up on first error + QDomElement propstatElement; + { + const QDomNodeList propstats = responseElement.elementsByTagNameNS(QStringLiteral("DAV:"), QStringLiteral("propstat")); + for (int i = 0; i < propstats.length(); ++i) { + const QDomElement propstatCandidate = propstats.item(i).toElement(); + const QDomElement statusElement = DavUtils::firstChildElementNS(propstatCandidate, QStringLiteral("DAV:"), QStringLiteral("status")); + if (statusElement.text().contains(QStringLiteral("200"))) { + propstatElement = propstatCandidate; + } + } + } + + if (propstatElement.isNull()) { + emitResult(); + return; + } + + QDomElement propElement = DavUtils::firstChildElementNS(propstatElement, QStringLiteral("DAV:"), QStringLiteral("prop")); + if (propElement.isNull()) { + emitResult(); + return; + } + + QDomElement principalCollectionSetElement = DavUtils::firstChildElementNS(propElement, QStringLiteral("DAV:"), QStringLiteral("principal-collection-set")); + if (principalCollectionSetElement.isNull()) { + emitResult(); + return; + } + + QDomNodeList hrefNodes = principalCollectionSetElement.elementsByTagNameNS(QStringLiteral("DAV:"), QStringLiteral("href")); + for (int i = 0; i < hrefNodes.size(); ++i) { + QDomElement hrefElement = hrefNodes.at(i).toElement(); + QString href = hrefElement.text(); + + KUrl url = mUrl.url(); + if (href.startsWith(QLatin1Char('/'))) { + // href is only a path, use request url to complete + url.setEncodedPath(href.toLatin1()); + } else { + // href is a complete url + KUrl tmpUrl(href); + tmpUrl.setUser(url.user()); + tmpUrl.setPass(url.pass()); + url = tmpUrl; + } + + QDomDocument principalPropertySearchQuery; + buildReportQuery(principalPropertySearchQuery); + KIO::DavJob *reportJob = DavManager::self()->createReportJob(url, principalPropertySearchQuery); + reportJob->addMetaData(QStringLiteral("PropagateHttpHeader"), QStringLiteral("true")); + connect(reportJob, &KIO::DavJob::result, this, &DavPrincipalSearchJob::principalPropertySearchFinished); + ++mPrincipalPropertySearchSubJobCount; + reportJob->start(); + } } -void DavPrincipalSearchJob::principalPropertySearchFinished( KJob* job ) +void DavPrincipalSearchJob::principalPropertySearchFinished(KJob *job) { - --mPrincipalPropertySearchSubJobCount; + --mPrincipalPropertySearchSubJobCount; + + if (job->error() && !mPrincipalPropertySearchSubJobSuccessful) { + setError(job->error()); + setErrorText(job->errorText()); + if (mPrincipalPropertySearchSubJobCount == 0) { + emitResult(); + } + return; + } + + KIO::DavJob *davJob = qobject_cast(job); - if ( job->error() && !mPrincipalPropertySearchSubJobSuccessful ) { - setError( job->error() ); - setErrorText( job->errorText() ); - if ( mPrincipalPropertySearchSubJobCount == 0 ) - emitResult(); - return; - } - - KIO::DavJob *davJob = qobject_cast( job ); - - const int responseCode = davJob->queryMetaData( QLatin1String("responsecode") ).toInt(); - - if ( responseCode > 499 && responseCode < 600 && !mPrincipalPropertySearchSubJobSuccessful ) { - // Server-side error, unrecoverable - setError( UserDefinedError ); - setErrorText( i18n( "The server encountered an error that prevented it from completing your request" ) ); - if ( mPrincipalPropertySearchSubJobCount == 0 ) - emitResult(); - return; - } else if ( responseCode > 399 && responseCode < 500 && !mPrincipalPropertySearchSubJobSuccessful ) { - // User-side error - QString extraMessage; - if ( responseCode == 401 ) - extraMessage = i18n( "Invalid username/password" ); - else if ( responseCode == 403 ) - extraMessage = i18n( "Access forbidden" ); - else if ( responseCode == 404 ) - extraMessage = i18n( "Resource not found" ); - else - extraMessage = i18n( "HTTP error" ); - - setError( UserDefinedError ); - setErrorText( i18n( "There was a problem with the request.\n" - "%1 (%2).", extraMessage, responseCode ) ); - if ( mPrincipalPropertySearchSubJobCount == 0 ) - emitResult(); - return; - } - - if ( !mPrincipalPropertySearchSubJobSuccessful ) { - setError( 0 ); // nope, everything went fine - mPrincipalPropertySearchSubJobSuccessful = true; - } - - /* - * Extract infos from a document like the following: - * - * - * - * http://www.example.com/users/jdoe - * - * - * John Doe - * - * HTTP/1.1 200 OK - * - * - */ - - const QDomDocument document = davJob->response(); - const QDomElement documentElement = document.documentElement(); - - QDomElement responseElement = DavUtils::firstChildElementNS( documentElement, QLatin1String("DAV:"), QLatin1String("response") ); - if ( responseElement.isNull() ) { - if ( mPrincipalPropertySearchSubJobCount == 0 ) - emitResult(); - return; - } - - // check for the valid propstat, without giving up on first error - QDomElement propstatElement; - { - const QDomNodeList propstats = responseElement.elementsByTagNameNS( QLatin1String("DAV:"), QLatin1String("propstat") ); - for ( uint i = 0; i < propstats.length(); ++i ) { - const QDomElement propstatCandidate = propstats.item( i ).toElement(); - const QDomElement statusElement = DavUtils::firstChildElementNS( propstatCandidate, QLatin1String("DAV:"), QLatin1String("status") ); - if ( statusElement.text().contains( QLatin1String("200") ) ) { - propstatElement = propstatCandidate; - } - } - } - - if ( propstatElement.isNull() ) { - if ( mPrincipalPropertySearchSubJobCount == 0 ) - emitResult(); - return; - } - - QDomElement propElement = DavUtils::firstChildElementNS( propstatElement, QLatin1String("DAV:"), QLatin1String("prop" )); - if ( propElement.isNull() ) { - if ( mPrincipalPropertySearchSubJobCount == 0 ) - emitResult(); - return; - } - - // All requested properties are now under propElement, so let's find them - typedef QPair PropertyPair; - foreach ( const PropertyPair &fetchProperty, mFetchProperties ) { - QDomNodeList fetchNodes = propElement.elementsByTagNameNS( fetchProperty.first, fetchProperty.second ); - for ( int i = 0; i < fetchNodes.size(); ++i ) { - QDomElement fetchElement = fetchNodes.at( i ).toElement(); - Result result; - result.propertyNamespace = fetchProperty.first; - result.property = fetchProperty.second; - result.value = fetchElement.text(); - mResults << result; + const int responseCode = davJob->queryMetaData(QStringLiteral("responsecode")).toInt(); + + if (responseCode > 499 && responseCode < 600 && !mPrincipalPropertySearchSubJobSuccessful) { + // Server-side error, unrecoverable + setError(UserDefinedError); + setErrorText(i18n("The server encountered an error that prevented it from completing your request")); + if (mPrincipalPropertySearchSubJobCount == 0) { + emitResult(); + } + return; + } else if (responseCode > 399 && responseCode < 500 && !mPrincipalPropertySearchSubJobSuccessful) { + // User-side error + QString extraMessage; + if (responseCode == 401) { + extraMessage = i18n("Invalid username/password"); + } else if (responseCode == 403) { + extraMessage = i18n("Access forbidden"); + } else if (responseCode == 404) { + extraMessage = i18n("Resource not found"); + } else { + extraMessage = i18n("HTTP error"); + } + + setError(UserDefinedError); + setErrorText(i18n("There was a problem with the request.\n" + "%1 (%2).", extraMessage, responseCode)); + if (mPrincipalPropertySearchSubJobCount == 0) { + emitResult(); + } + return; + } + + if (!mPrincipalPropertySearchSubJobSuccessful) { + setError(0); // nope, everything went fine + mPrincipalPropertySearchSubJobSuccessful = true; + } + + /* + * Extract infos from a document like the following: + * + * + * + * http://www.example.com/users/jdoe + * + * + * John Doe + * + * HTTP/1.1 200 OK + * + * + */ + + const QDomDocument document = davJob->response(); + const QDomElement documentElement = document.documentElement(); + + QDomElement responseElement = DavUtils::firstChildElementNS(documentElement, QStringLiteral("DAV:"), QStringLiteral("response")); + if (responseElement.isNull()) { + if (mPrincipalPropertySearchSubJobCount == 0) { + emitResult(); + } + return; + } + + // check for the valid propstat, without giving up on first error + QDomElement propstatElement; + { + const QDomNodeList propstats = responseElement.elementsByTagNameNS(QStringLiteral("DAV:"), QStringLiteral("propstat")); + const int propStatsEnd(propstats.length()); + for (int i = 0; i < propStatsEnd; ++i) { + const QDomElement propstatCandidate = propstats.item(i).toElement(); + const QDomElement statusElement = DavUtils::firstChildElementNS(propstatCandidate, QStringLiteral("DAV:"), QStringLiteral("status")); + if (statusElement.text().contains(QStringLiteral("200"))) { + propstatElement = propstatCandidate; + } + } + } + + if (propstatElement.isNull()) { + if (mPrincipalPropertySearchSubJobCount == 0) { + emitResult(); + } + return; + } + + QDomElement propElement = DavUtils::firstChildElementNS(propstatElement, QStringLiteral("DAV:"), QStringLiteral("prop")); + if (propElement.isNull()) { + if (mPrincipalPropertySearchSubJobCount == 0) { + emitResult(); + } + return; + } + + // All requested properties are now under propElement, so let's find them + typedef QPair PropertyPair; + foreach (const PropertyPair &fetchProperty, mFetchProperties) { + QDomNodeList fetchNodes = propElement.elementsByTagNameNS(fetchProperty.first, fetchProperty.second); + for (int i = 0; i < fetchNodes.size(); ++i) { + QDomElement fetchElement = fetchNodes.at(i).toElement(); + Result result; + result.propertyNamespace = fetchProperty.first; + result.property = fetchProperty.second; + result.value = fetchElement.text(); + mResults << result; + } } - } - if ( mPrincipalPropertySearchSubJobCount == 0 ) - emitResult(); + if (mPrincipalPropertySearchSubJobCount == 0) { + emitResult(); + } } QList< DavPrincipalSearchJob::Result > DavPrincipalSearchJob::results() const { - return mResults; + return mResults; } -void DavPrincipalSearchJob::buildReportQuery( QDomDocument& query ) +void DavPrincipalSearchJob::buildReportQuery(QDomDocument &query) { - /* - * Build a document like the following, where XXX will - * be replaced by the properties the user want to fetch: - * - * - * - * - * - * - * - * FILTER - * - * - * XXX - * - * - */ - - QDomElement principalPropertySearch = query.createElementNS( QLatin1String("DAV:"), QLatin1String("principal-property-search") ); - query.appendChild( principalPropertySearch ); - - QDomElement propertySearch = query.createElementNS( QLatin1String("DAV:"), QLatin1String("property-search") ); - principalPropertySearch.appendChild( propertySearch ); - - QDomElement prop = query.createElementNS( QLatin1String("DAV:"), QLatin1String("prop") ); - propertySearch.appendChild( prop ); - - if ( mType == DisplayName ) { - QDomElement displayName = query.createElementNS( QLatin1String("DAV:"), QLatin1String("displayname") ); - prop.appendChild( displayName ); - } - else if ( mType == EmailAddress ) { - QDomElement calendarUserAddressSet = query.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("calendar-user-address-set") ); - prop.appendChild( calendarUserAddressSet ); - //QDomElement hrefElement = query.createElementNS( "DAV:", "href" ); - //prop.appendChild( hrefElement ); - } - - QDomElement match = query.createElementNS( QLatin1String("DAV:"), QLatin1String("match") ); - propertySearch.appendChild( match ); - - QDomText propFilter = query.createTextNode( mFilter ); - match.appendChild( propFilter ); - - prop = query.createElementNS( QLatin1String("DAV:"), QLatin1String("prop") ); - principalPropertySearch.appendChild( prop ); - - typedef QPair PropertyPair; - foreach ( const PropertyPair &fetchProperty, mFetchProperties ) { - QDomElement elem = query.createElementNS( fetchProperty.first, fetchProperty.second ); - prop.appendChild( elem ); - } + /* + * Build a document like the following, where XXX will + * be replaced by the properties the user want to fetch: + * + * + * + * + * + * + * + * FILTER + * + * + * XXX + * + * + */ + + QDomElement principalPropertySearch = query.createElementNS(QStringLiteral("DAV:"), QStringLiteral("principal-property-search")); + query.appendChild(principalPropertySearch); + + QDomElement propertySearch = query.createElementNS(QStringLiteral("DAV:"), QStringLiteral("property-search")); + principalPropertySearch.appendChild(propertySearch); + + QDomElement prop = query.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + propertySearch.appendChild(prop); + + if (mType == DisplayName) { + QDomElement displayName = query.createElementNS(QStringLiteral("DAV:"), QStringLiteral("displayname")); + prop.appendChild(displayName); + } else if (mType == EmailAddress) { + QDomElement calendarUserAddressSet = query.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("calendar-user-address-set")); + prop.appendChild(calendarUserAddressSet); + //QDomElement hrefElement = query.createElementNS( "DAV:", "href" ); + //prop.appendChild( hrefElement ); + } + + QDomElement match = query.createElementNS(QStringLiteral("DAV:"), QStringLiteral("match")); + propertySearch.appendChild(match); + + QDomText propFilter = query.createTextNode(mFilter); + match.appendChild(propFilter); + + prop = query.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + principalPropertySearch.appendChild(prop); + + typedef QPair PropertyPair; + foreach (const PropertyPair &fetchProperty, mFetchProperties) { + QDomElement elem = query.createElementNS(fetchProperty.first, fetchProperty.second); + prop.appendChild(elem); + } } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davprincipalsearchjob.h kdepim-runtime-15.08.0/resources/dav/common/davprincipalsearchjob.h --- kdepim-runtime-4.14.6/resources/dav/common/davprincipalsearchjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davprincipalsearchjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -37,26 +37,26 @@ */ class DavPrincipalSearchJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Types of search that are supported by this job. * DisplayName will match on the DAV displayname property. * EmailAddress will match on the CalDav calendar-user-address-set property. */ enum FilterType { - DisplayName, - EmailAddress + DisplayName, + EmailAddress }; /** * Simple struct to hold the search job results */ struct Result { - QString propertyNamespace; - QString property; - QString value; + QString propertyNamespace; + QString property; + QString value; }; /** @@ -67,7 +67,7 @@ * @param filter The filter that will be used to match the displayname attribute. * @param parent The parent object. */ - explicit DavPrincipalSearchJob( const DavUtils::DavUrl &url, FilterType type, const QString &filter, QObject *parent = 0 ); + explicit DavPrincipalSearchJob(const DavUtils::DavUrl &url, FilterType type, const QString &filter, QObject *parent = Q_NULLPTR); /** * Add a new property to fetch from the server. @@ -75,12 +75,12 @@ * @param name The name of the property. * @param ns The namespace of this property, defaults to 'DAV:'. */ - void fetchProperty( const QString &name, const QString &ns = QString() ); + void fetchProperty(const QString &name, const QString &ns = QString()); /** * Starts the job */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Return the DavUrl used by this job @@ -92,14 +92,14 @@ */ QList results() const; - private slots: - void principalCollectionSetSearchFinished( KJob *job ); - void principalPropertySearchFinished( KJob *job ); +private Q_SLOTS: + void principalCollectionSetSearchFinished(KJob *job); + void principalPropertySearchFinished(KJob *job); - private: - void buildReportQuery( QDomDocument &query ); +private: + void buildReportQuery(QDomDocument &query); - private: +private: DavUtils::DavUrl mUrl; FilterType mType; QString mFilter; diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davprotocolbase.cpp kdepim-runtime-15.08.0/resources/dav/common/davprotocolbase.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davprotocolbase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davprotocolbase.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,10 +24,10 @@ QString DavProtocolBase::principalHomeSet() const { - return QString(); + return QString(); } QString DavProtocolBase::principalHomeSetNS() const { - return QString(); + return QString(); } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davprotocolbase.h kdepim-runtime-15.08.0/resources/dav/common/davprotocolbase.h --- kdepim-runtime-4.14.6/resources/dav/common/davprotocolbase.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davprotocolbase.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,7 +24,6 @@ #include #include - /** * @short Base class for various DAV groupware dialects. * @@ -38,7 +37,7 @@ */ class DavProtocolBase { - public: +public: /** * Destroys the dav protocol base. */ @@ -98,19 +97,19 @@ * Returns a list of XML documents that represent DAV queries to * list all available DAV resources inside a specific DAV collection. */ - virtual QList itemsQueries() const = 0; + virtual QVector itemsQueries() const = 0; /** * Returns the mime type of items fetched by query at index @p index * in the list return by @ref itemsQueries(). */ - virtual QString mimeTypeForQuery( int index ) const = 0; + virtual QString mimeTypeForQuery(int index) const = 0; /** * Returns the possible content types for the collection that * is described by the passed @p propstat element of a PROPFIND result. */ - virtual DavCollection::ContentTypes collectionContentTypes( const QDomElement &propstat ) const = 0; + virtual DavCollection::ContentTypes collectionContentTypes(const QDomElement &propstat) const = 0; /** * Returns the mimetype that shall be used for contact DAV resources. diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davutils.cpp kdepim-runtime-15.08.0/resources/dav/common/davutils.cpp --- kdepim-runtime-4.14.6/resources/dav/common/davutils.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davutils.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,344 +22,347 @@ #include "davprotocolattribute.h" #include "davprotocolbase.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include typedef QSharedPointer IncidencePtr; -QDomElement DavUtils::firstChildElementNS( const QDomElement &parent, const QString &namespaceUri, const QString &tagName ) +QDomElement DavUtils::firstChildElementNS(const QDomElement &parent, const QString &namespaceUri, const QString &tagName) { - for ( QDomNode child = parent.firstChild(); !child.isNull(); child = child.nextSibling() ) { - if ( child.isElement() ) { - const QDomElement elt = child.toElement(); - if ( tagName.isEmpty() || ( elt.tagName() == tagName && elt.namespaceURI() == namespaceUri ) ) - return elt; + for (QDomNode child = parent.firstChild(); !child.isNull(); child = child.nextSibling()) { + if (child.isElement()) { + const QDomElement elt = child.toElement(); + if (tagName.isEmpty() || (elt.tagName() == tagName && elt.namespaceURI() == namespaceUri)) { + return elt; + } + } } - } - return QDomElement(); + return QDomElement(); } -QDomElement DavUtils::nextSiblingElementNS( const QDomElement &element, const QString &namespaceUri, const QString &tagName ) +QDomElement DavUtils::nextSiblingElementNS(const QDomElement &element, const QString &namespaceUri, const QString &tagName) { - for ( QDomNode sib = element.nextSibling(); !sib.isNull(); sib = sib.nextSibling() ) { - if ( sib.isElement() ) { - const QDomElement elt = sib.toElement(); - if ( tagName.isEmpty() || ( elt.tagName() == tagName && elt.namespaceURI() == namespaceUri ) ) - return elt; + for (QDomNode sib = element.nextSibling(); !sib.isNull(); sib = sib.nextSibling()) { + if (sib.isElement()) { + const QDomElement elt = sib.toElement(); + if (tagName.isEmpty() || (elt.tagName() == tagName && elt.namespaceURI() == namespaceUri)) { + return elt; + } + } } - } - return QDomElement(); + return QDomElement(); } -DavUtils::Privileges DavUtils::extractPrivileges( const QDomElement &element ) +DavUtils::Privileges DavUtils::extractPrivileges(const QDomElement &element) { - Privileges final = None; - QDomElement privElement = firstChildElementNS( element, QLatin1String("DAV:"), QLatin1String("privilege")); + Privileges final = None; + QDomElement privElement = firstChildElementNS(element, QStringLiteral("DAV:"), QStringLiteral("privilege")); - while ( !privElement.isNull() ) { - QDomElement child = privElement.firstChildElement(); + while (!privElement.isNull()) { + QDomElement child = privElement.firstChildElement(); - while ( !child.isNull() ) { - final |= parsePrivilege( child ); - child = child.nextSiblingElement(); - } + while (!child.isNull()) { + final |= parsePrivilege(child); + child = child.nextSiblingElement(); + } - privElement = DavUtils::nextSiblingElementNS( privElement, QLatin1String("DAV:"), QLatin1String("privilege") ); - } + privElement = DavUtils::nextSiblingElementNS(privElement, QStringLiteral("DAV:"), QStringLiteral("privilege")); + } - return final; + return final; } -DavUtils::Privileges DavUtils::parsePrivilege( const QDomElement &element ) +DavUtils::Privileges DavUtils::parsePrivilege(const QDomElement &element) { - Privileges final = None; + Privileges final = None; - if ( !element.childNodes().isEmpty() ) { - // This is an aggregate privilege, parse each of its children - QDomElement child = element.firstChildElement(); - while ( !child.isNull() ) { - final |= parsePrivilege( child ); - child = child.nextSiblingElement(); + if (!element.childNodes().isEmpty()) { + // This is an aggregate privilege, parse each of its children + QDomElement child = element.firstChildElement(); + while (!child.isNull()) { + final |= parsePrivilege(child); + child = child.nextSiblingElement(); + } + } else { + // This is a normal privilege + const QString privname = element.localName(); + + if (privname == QLatin1String("read")) { + final |= DavUtils::Read; + } else if (privname == QLatin1String("write")) { + final |= DavUtils::Write; + } else if (privname == QLatin1String("write-properties")) { + final |= DavUtils::WriteProperties; + } else if (privname == QLatin1String("write-content")) { + final |= DavUtils::WriteContent; + } else if (privname == QLatin1String("unlock")) { + final |= DavUtils::Unlock; + } else if (privname == QLatin1String("read-acl")) { + final |= DavUtils::ReadAcl; + } else if (privname == QLatin1String("read-current-user-privilege-set")) { + final |= DavUtils::ReadCurrentUserPrivilegeSet; + } else if (privname == QLatin1String("write-acl")) { + final |= DavUtils::WriteAcl; + } else if (privname == QLatin1String("bind")) { + final |= DavUtils::Bind; + } else if (privname == QLatin1String("unbind")) { + final |= DavUtils::Unbind; + } else if (privname == QLatin1String("all")) { + final |= DavUtils::All; + } } - } - else { - // This is a normal privilege - const QString privname = element.localName(); - - if ( privname == QLatin1String("read") ) - final |= DavUtils::Read; - else if ( privname == QLatin1String("write") ) - final |= DavUtils::Write; - else if ( privname == QLatin1String("write-properties") ) - final |= DavUtils::WriteProperties; - else if ( privname == QLatin1String("write-content") ) - final |= DavUtils::WriteContent; - else if ( privname == QLatin1String("unlock") ) - final |= DavUtils::Unlock; - else if ( privname == QLatin1String("read-acl") ) - final |= DavUtils::ReadAcl; - else if ( privname == QLatin1String("read-current-user-privilege-set") ) - final |= DavUtils::ReadCurrentUserPrivilegeSet; - else if ( privname == QLatin1String("write-acl") ) - final |= DavUtils::WriteAcl; - else if ( privname == QLatin1String("bind") ) - final |= DavUtils::Bind; - else if ( privname == QLatin1String("unbind") ) - final |= DavUtils::Unbind; - else if ( privname == QLatin1String("all") ) - final |= DavUtils::All; - } - return final; + return final; } DavUtils::DavUrl::DavUrl() - : mProtocol( CalDav ) + : mProtocol(CalDav) { } -DavUtils::DavUrl::DavUrl( const KUrl &url, DavUtils::Protocol protocol ) - : mUrl( url ), mProtocol( protocol ) +DavUtils::DavUrl::DavUrl(const KUrl &url, DavUtils::Protocol protocol) + : mUrl(url), mProtocol(protocol) { } -void DavUtils::DavUrl::setUrl( const KUrl &url ) +void DavUtils::DavUrl::setUrl(const KUrl &url) { - mUrl = url; + mUrl = url; } KUrl DavUtils::DavUrl::url() const { - return mUrl; + return mUrl; } -void DavUtils::DavUrl::setProtocol( DavUtils::Protocol protocol ) +void DavUtils::DavUrl::setProtocol(DavUtils::Protocol protocol) { - mProtocol = protocol; + mProtocol = protocol; } DavUtils::Protocol DavUtils::DavUrl::protocol() const { - return mProtocol; + return mProtocol; } -QLatin1String DavUtils::protocolName( DavUtils::Protocol protocol ) +QLatin1String DavUtils::protocolName(DavUtils::Protocol protocol) { - QLatin1String protocolName( "" ); + QLatin1String protocolName(""); - switch( protocol ) { + switch (protocol) { case DavUtils::CalDav: - protocolName = QLatin1String( "CalDav" ); - break; + protocolName = QLatin1String("CalDav"); + break; case DavUtils::CardDav: - protocolName = QLatin1String( "CardDav" ); - break; + protocolName = QLatin1String("CardDav"); + break; case DavUtils::GroupDav: - protocolName = QLatin1String( "GroupDav" ); - break; - } + protocolName = QLatin1String("GroupDav"); + break; + } - return protocolName; + return protocolName; } -QString DavUtils::translatedProtocolName( DavUtils::Protocol protocol ) +QString DavUtils::translatedProtocolName(DavUtils::Protocol protocol) { - QString protocolName; + QString protocolName; - switch( protocol ) { + switch (protocol) { case DavUtils::CalDav: - protocolName = i18n( "CalDav" ); - break; + protocolName = i18n("CalDav"); + break; case DavUtils::CardDav: - protocolName = i18n( "CardDav" ); - break; + protocolName = i18n("CardDav"); + break; case DavUtils::GroupDav: - protocolName = i18n( "GroupDav" ); - break; - } + protocolName = i18n("GroupDav"); + break; + } - return protocolName; + return protocolName; } -DavUtils::Protocol DavUtils::protocolByName( const QString &name ) +DavUtils::Protocol DavUtils::protocolByName(const QString &name) { - DavUtils::Protocol protocol = DavUtils::CalDav; + DavUtils::Protocol protocol = DavUtils::CalDav; - if ( name == QLatin1String("CalDav") ) { - protocol = DavUtils::CalDav; - } else if ( name == QLatin1String("CardDav") ) { - protocol = DavUtils::CardDav; - } else if ( name == QLatin1String("GroupDav") ) { - protocol = DavUtils::GroupDav; - } else { - kError() << "Unexpected protocol name : " << name; - } + if (name == QLatin1String("CalDav")) { + protocol = DavUtils::CalDav; + } else if (name == QLatin1String("CardDav")) { + protocol = DavUtils::CardDav; + } else if (name == QLatin1String("GroupDav")) { + protocol = DavUtils::GroupDav; + } else { + qCritical() << "Unexpected protocol name : " << name; + } - return protocol; + return protocol; } -DavUtils::Protocol DavUtils::protocolByTranslatedName( const QString &name ) +DavUtils::Protocol DavUtils::protocolByTranslatedName(const QString &name) { - DavUtils::Protocol protocol; + DavUtils::Protocol protocol = DavUtils::CalDav; - if ( name == i18n( "CalDav" ) ) { - protocol = DavUtils::CalDav; - } else if ( name == i18n( "CardDav" ) ) { - protocol = DavUtils::CardDav; - } else if ( name == i18n( "GroupDav" ) ) { - protocol = DavUtils::GroupDav; - } + if (name == i18n("CalDav")) { + protocol = DavUtils::CalDav; + } else if (name == i18n("CardDav")) { + protocol = DavUtils::CardDav; + } else if (name == i18n("GroupDav")) { + protocol = DavUtils::GroupDav; + } - return protocol; + return protocol; } QString DavUtils::createUniqueId() { - qint64 time = QDateTime::currentMSecsSinceEpoch() / 1000; - int r = qrand() % 1000; - QString id = QLatin1String( "R" ) + QString::number( r ); - QString uid = QString::number( time ) + QLatin1String( "." ) + id; - return uid; -} - -DavItem DavUtils::createDavItem( const Akonadi::Item &item, const Akonadi::Collection &collection, const Akonadi::Item::List &dependentItems ) -{ - QByteArray rawData; - QString mimeType; - KUrl url; - DavItem davItem; - const QString basePath = collection.remoteId(); - - if ( item.hasPayload() ) { - const KABC::Addressee contact = item.payload(); - const QString fileName = createUniqueId(); - - url = KUrl( basePath + fileName + QLatin1String(".vcf") ); - - const DavProtocolAttribute *protoAttr = collection.attribute(); - if ( protoAttr ) { - mimeType = - DavManager::self()->davProtocol( - DavUtils::Protocol( protoAttr->davProtocol() ) )->contactsMimeType(); - } else { - mimeType = KABC::Addressee::mimeType(); - } + qint64 time = QDateTime::currentMSecsSinceEpoch() / 1000; + int r = qrand() % 1000; + QString id = QLatin1String("R") + QString::number(r); + QString uid = QString::number(time) + QLatin1String(".") + id; + return uid; +} + +DavItem DavUtils::createDavItem(const Akonadi::Item &item, const Akonadi::Collection &collection, const Akonadi::Item::List &dependentItems) +{ + QByteArray rawData; + QString mimeType; + KUrl url; + DavItem davItem; + const QString basePath = collection.remoteId(); + + if (item.hasPayload()) { + const KContacts::Addressee contact = item.payload(); + const QString fileName = createUniqueId(); + + url = KUrl(basePath + fileName + QLatin1String(".vcf")); + + const DavProtocolAttribute *protoAttr = collection.attribute(); + if (protoAttr) { + mimeType = + DavManager::self()->davProtocol( + DavUtils::Protocol(protoAttr->davProtocol()))->contactsMimeType(); + } else { + mimeType = KContacts::Addressee::mimeType(); + } + + KContacts::VCardConverter converter; + // rawData is already UTF-8 + rawData = converter.exportVCard(contact, KContacts::VCardConverter::v3_0); + } else if (item.hasPayload()) { + const KCalCore::MemoryCalendar::Ptr calendar(new KCalCore::MemoryCalendar(KDateTime::LocalZone)); + calendar->addIncidence(item.payload()); + foreach (const Akonadi::Item &dependentItem, dependentItems) { + calendar->addIncidence(dependentItem.payload()); + } + + const QString fileName = createUniqueId(); - KABC::VCardConverter converter; - // rawData is already UTF-8 - rawData = converter.exportVCard( contact, KABC::VCardConverter::v3_0 ); - } else if ( item.hasPayload() ) { - const KCalCore::MemoryCalendar::Ptr calendar( new KCalCore::MemoryCalendar( KDateTime::LocalZone ) ); - calendar->addIncidence( item.payload() ); - foreach ( const Akonadi::Item &dependentItem, dependentItems ) { - calendar->addIncidence( dependentItem.payload() ); + url = KUrl(basePath + fileName + QLatin1String(".ics")); + mimeType = QLatin1String("text/calendar"); + + KCalCore::ICalFormat formatter; + rawData = formatter.toString(calendar, QString()).toUtf8(); } - const QString fileName = createUniqueId(); + davItem.setContentType(mimeType); + davItem.setData(rawData); + davItem.setUrl(url.prettyUrl()); + davItem.setEtag(item.remoteRevision()); - url = KUrl( basePath + fileName + QLatin1String(".ics") ); - mimeType = QLatin1String("text/calendar"); + return davItem; +} - KCalCore::ICalFormat formatter; - rawData = formatter.toString( calendar, QString() ).toUtf8(); - } - - davItem.setContentType( mimeType ); - davItem.setData( rawData ); - davItem.setUrl( url.prettyUrl() ); - davItem.setEtag( item.remoteRevision() ); - - return davItem; -} - -bool DavUtils::parseDavData( const DavItem &source, Akonadi::Item &target, Akonadi::Item::List &extraItems ) -{ - const QString data = QString::fromUtf8( source.data() ); - - if ( target.mimeType() == KABC::Addressee::mimeType() ) { - KABC::VCardConverter converter; - const KABC::Addressee contact = converter.parseVCard( source.data() ); - - if ( contact.isEmpty() ) - return false; - - target.setPayloadFromData( source.data() ); - } else { - KCalCore::ICalFormat formatter; - const KCalCore::MemoryCalendar::Ptr calendar( new KCalCore::MemoryCalendar( KDateTime::LocalZone ) ); - formatter.fromString( calendar, data ); - KCalCore::Incidence::List incidences = calendar->incidences(); - - if ( incidences.isEmpty() ) - return false; - - // All items must have the same uid in a single object. - // Find the main VEVENT (if that's indeed what we have, - // could be a VTODO or a VJOURNAL but that doesn't matter) - // and then apply the recurrence exceptions - IncidencePtr mainIncidence; - KCalCore::Incidence::List exceptions; - - foreach ( const IncidencePtr &incidence, incidences ) { - if ( incidence->hasRecurrenceId() ) { - kDebug() << "Exception found with ID" << incidence->instanceIdentifier(); - exceptions << incidence; - } - else { - mainIncidence = incidence; - } - } +bool DavUtils::parseDavData(const DavItem &source, Akonadi::Item &target, Akonadi::Item::List &extraItems) +{ + const QString data = QString::fromUtf8(source.data()); - if ( !mainIncidence ) - return false; + if (target.mimeType() == KContacts::Addressee::mimeType()) { + KContacts::VCardConverter converter; + const KContacts::Addressee contact = converter.parseVCard(source.data()); - foreach ( const IncidencePtr &exception, exceptions ) { - if ( exception->status() == KCalCore::Incidence::StatusCanceled ) { - KDateTime exDateTime = exception->recurrenceId(); - mainIncidence->recurrence()->addExDateTime( exDateTime ); - } - else { - // The exception remote id will contain a fragment pointing to - // its instance identifier to distinguish it from the main - // event. - QString rid = target.remoteId() + QLatin1String( "#" ) + exception->instanceIdentifier(); - kDebug() << "Extra incidence at" << rid; - Akonadi::Item extraItem = target; - extraItem.setRemoteId( rid ); - extraItem.setRemoteRevision( source.etag() ); - extraItem.setMimeType( exception->mimeType() ); - extraItem.setPayload( exception ); - extraItems << extraItem; - } - } + if (contact.isEmpty()) { + return false; + } - target.setPayload( mainIncidence ); - // fix mime type for CalDAV collections - target.setMimeType( mainIncidence->mimeType() ); - - /* - foreach ( const IncidencePtr &incidence, incidences ) { - QString rid = item.remoteId() + QLatin1String( "#" ) + incidence->instanceIdentifier(); - Akonadi::Item extraItem = item; - extraItem.setRemoteId( rid ); - extraItem.setRemoteRevision( davItem.etag() ); - extraItem.setMimeType( incidence->mimeType() ); - extraItem.setPayload( incidence ); - items << extraItem; + target.setPayloadFromData(source.data()); + } else { + KCalCore::ICalFormat formatter; + const KCalCore::MemoryCalendar::Ptr calendar(new KCalCore::MemoryCalendar(KDateTime::LocalZone)); + formatter.fromString(calendar, data); + KCalCore::Incidence::List incidences = calendar->incidences(); + + if (incidences.isEmpty()) { + return false; + } + + // All items must have the same uid in a single object. + // Find the main VEVENT (if that's indeed what we have, + // could be a VTODO or a VJOURNAL but that doesn't matter) + // and then apply the recurrence exceptions + IncidencePtr mainIncidence; + KCalCore::Incidence::List exceptions; + + foreach (const IncidencePtr &incidence, incidences) { + if (incidence->hasRecurrenceId()) { + qDebug() << "Exception found with ID" << incidence->instanceIdentifier(); + exceptions << incidence; + } else { + mainIncidence = incidence; + } + } + + if (!mainIncidence) { + return false; + } + + foreach (const IncidencePtr &exception, exceptions) { + if (exception->status() == KCalCore::Incidence::StatusCanceled) { + KDateTime exDateTime = exception->recurrenceId(); + mainIncidence->recurrence()->addExDateTime(exDateTime); + } else { + // The exception remote id will contain a fragment pointing to + // its instance identifier to distinguish it from the main + // event. + QString rid = target.remoteId() + QLatin1String("#") + exception->instanceIdentifier(); + qDebug() << "Extra incidence at" << rid; + Akonadi::Item extraItem = target; + extraItem.setRemoteId(rid); + extraItem.setRemoteRevision(source.etag()); + extraItem.setMimeType(exception->mimeType()); + extraItem.setPayload(exception); + extraItems << extraItem; + } + } + + target.setPayload(mainIncidence); + // fix mime type for CalDAV collections + target.setMimeType(mainIncidence->mimeType()); + + /* + foreach ( const IncidencePtr &incidence, incidences ) { + QString rid = item.remoteId() + QLatin1String( "#" ) + incidence->instanceIdentifier(); + Akonadi::Item extraItem = item; + extraItem.setRemoteId( rid ); + extraItem.setRemoteRevision( davItem.etag() ); + extraItem.setMimeType( incidence->mimeType() ); + extraItem.setPayload( incidence ); + items << extraItem; + } + */ } - */ - } - return true; + return true; } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/davutils.h kdepim-runtime-15.08.0/resources/dav/common/davutils.h --- kdepim-runtime-4.14.6/resources/dav/common/davutils.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/davutils.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,12 +24,13 @@ #include -#include +#include class DavItem; -namespace Akonadi { - class Collection; - class Item; +namespace Akonadi +{ +class Collection; +class Item; } /** @@ -37,19 +38,19 @@ */ namespace DavUtils { - /** - * Describes the DAV protocol dialect. - */ - enum Protocol { +/** + * Describes the DAV protocol dialect. + */ +enum Protocol { CalDav = 0, ///< The CalDav protocol as defined in http://caldav.calconnect.org CardDav, ///< The CardDav protocol as defined in http://carddav.calconnect.org GroupDav ///< The GroupDav protocol as defined in http://www.groupdav.org - }; +}; - /** - * Describes the DAV privileges on a resource (see RFC3744) - */ - enum Privilege { +/** + * Describes the DAV privileges on a resource (see RFC3744) + */ +enum Privilege { None = 0x0, Read = 0x1, Write = 0x2, @@ -62,118 +63,118 @@ Bind = 0x100, Unbind = 0x200, All = 0x400 - }; - Q_DECLARE_FLAGS( Privileges, Privilege ) - Q_DECLARE_OPERATORS_FOR_FLAGS( Privileges ) - - /** - * Returns the untranslated name of the given DAV @p protocol dialect. - */ - QLatin1String protocolName( Protocol protocol ); - - /** - * Returns the i18n'ed name of the given DAV @p protocol dialect. - */ - QString translatedProtocolName( Protocol protocol ); - - /** - * Returns the protocol matching the given name. This is the opposite of - * DavUtils::protocolName(). - */ - Protocol protocolByName( const QString &name ); - - /** - * Returns the protocol matching the given i18n'ed @p name. This is the opposite - * of DavUtils::translatedProtocolName(). - */ - Protocol protocolByTranslatedName( const QString &name ); - - /** - * @short A helper class to combine url and protocol of a DAV url. - */ - class DavUrl - { - public: - /** - * Defines a list of DAV url objects. - */ - typedef QList List; - - /** - * Creates an empty DAV url. - */ - DavUrl(); - - /** - * Creates a new DAV url. - * - * @param url The url that identifies the DAV object. - * @param protocol The DAV protocol dialect that is used to retrieve the DAV object. - */ - DavUrl( const KUrl &url, Protocol protocol ); - - /** - * Sets the @p url that identifies the DAV object. - */ - void setUrl( const KUrl &url ); - - /** - * Returns the url that identifies the DAV object. - */ - KUrl url() const; - - /** - * Sets the DAV @p protocol dialect that is used to retrieve the DAV object. - */ - void setProtocol( Protocol protocol ); - - /** - * Returns the DAV protocol dialect that is used to retrieve the DAV object. - */ - Protocol protocol() const; - - private: - KUrl mUrl; - Protocol mProtocol; - }; - - /** - * Returns the first child element of @p parent that has the given @p tagName and is part of the @p namespaceUri. - */ - QDomElement firstChildElementNS( const QDomElement &parent, const QString &namespaceUri, const QString &tagName ); - - /** - * Returns the next sibling element of @p element that has the given @p tagName and is part of the @p namespaceUri. - */ - QDomElement nextSiblingElementNS( const QDomElement &element, const QString &namespaceUri, const QString &tagName ); - - /** - * Extracts privileges from @p element. The tags are expected to be first level children of @p element. - */ - Privileges extractPrivileges( const QDomElement &element ); - - /** - * Parses a single tag and returns the final Privileges. - */ - Privileges parsePrivilege( const QDomElement &element ); - - /** - * Creates a unique identifier that can be used as a file name to upload the dav item - */ - QString createUniqueId(); - - /** - * Creates a new DavItem from the Akonadi::Item @p item. - * - * The returned item will have no payload (DavItem::data() will return an empty - * QByteArray) if the @p item payload is not recognized. - */ - DavItem createDavItem( const Akonadi::Item &item, const Akonadi::Collection &collection, const Akonadi::Item::List &dependentItems = Akonadi::Item::List() ); - - /** - * Parses the DAV data contained in @p source and puts it in @p target and @extraItems. - */ - bool parseDavData( const DavItem &source, Akonadi::Item &target, Akonadi::Item::List &extraItems ); -} +}; +Q_DECLARE_FLAGS(Privileges, Privilege) +Q_DECLARE_OPERATORS_FOR_FLAGS(Privileges) + +/** + * Returns the untranslated name of the given DAV @p protocol dialect. + */ +QLatin1String protocolName(Protocol protocol); + +/** + * Returns the i18n'ed name of the given DAV @p protocol dialect. + */ +QString translatedProtocolName(Protocol protocol); + +/** + * Returns the protocol matching the given name. This is the opposite of + * DavUtils::protocolName(). + */ +Protocol protocolByName(const QString &name); + +/** + * Returns the protocol matching the given i18n'ed @p name. This is the opposite + * of DavUtils::translatedProtocolName(). + */ +Protocol protocolByTranslatedName(const QString &name); + +/** + * @short A helper class to combine url and protocol of a DAV url. + */ +class DavUrl +{ +public: + /** + * Defines a list of DAV url objects. + */ + typedef QVector List; + + /** + * Creates an empty DAV url. + */ + DavUrl(); + + /** + * Creates a new DAV url. + * + * @param url The url that identifies the DAV object. + * @param protocol The DAV protocol dialect that is used to retrieve the DAV object. + */ + DavUrl(const KUrl &url, Protocol protocol); + + /** + * Sets the @p url that identifies the DAV object. + */ + void setUrl(const KUrl &url); + + /** + * Returns the url that identifies the DAV object. + */ + KUrl url() const; + + /** + * Sets the DAV @p protocol dialect that is used to retrieve the DAV object. + */ + void setProtocol(Protocol protocol); + + /** + * Returns the DAV protocol dialect that is used to retrieve the DAV object. + */ + Protocol protocol() const; + +private: + KUrl mUrl; + Protocol mProtocol; +}; +/** + * Returns the first child element of @p parent that has the given @p tagName and is part of the @p namespaceUri. + */ +QDomElement firstChildElementNS(const QDomElement &parent, const QString &namespaceUri, const QString &tagName); + +/** + * Returns the next sibling element of @p element that has the given @p tagName and is part of the @p namespaceUri. + */ +QDomElement nextSiblingElementNS(const QDomElement &element, const QString &namespaceUri, const QString &tagName); + +/** + * Extracts privileges from @p element. The tags are expected to be first level children of @p element. + */ +Privileges extractPrivileges(const QDomElement &element); + +/** + * Parses a single tag and returns the final Privileges. + */ +Privileges parsePrivilege(const QDomElement &element); + +/** + * Creates a unique identifier that can be used as a file name to upload the dav item + */ +QString createUniqueId(); + +/** + * Creates a new DavItem from the Akonadi::Item @p item. + * + * The returned item will have no payload (DavItem::data() will return an empty + * QByteArray) if the @p item payload is not recognized. + */ +DavItem createDavItem(const Akonadi::Item &item, const Akonadi::Collection &collection, const Akonadi::Item::List &dependentItems = Akonadi::Item::List()); + +/** + * Parses the DAV data contained in @p source and puts it in @p target and @extraItems. + */ +bool parseDavData(const DavItem &source, Akonadi::Item &target, Akonadi::Item::List &extraItems); +} +Q_DECLARE_TYPEINFO(DavUtils::DavUrl, Q_MOVABLE_TYPE ); #endif diff -Nru kdepim-runtime-4.14.6/resources/dav/common/etagcache.cpp kdepim-runtime-15.08.0/resources/dav/common/etagcache.cpp --- kdepim-runtime-4.14.6/resources/dav/common/etagcache.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/etagcache.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,80 +18,82 @@ #include "etagcache.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include #include EtagCache::EtagCache() { } -void EtagCache::sync( const Akonadi::Collection &collection ) +void EtagCache::sync(const Akonadi::Collection &collection) { - Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( collection ); - job->fetchScope().fetchFullPayload( false ); // We only need the remote id and the revision - connect( job, SIGNAL(result(KJob*)), this, SLOT(onItemFetchJobFinished(KJob*)) ); - job->start(); + Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob(collection); + job->fetchScope().fetchFullPayload(false); // We only need the remote id and the revision + connect(job, &Akonadi::ItemFetchJob::result, this, &EtagCache::onItemFetchJobFinished); + job->start(); } -void EtagCache::setEtag( const QString &remoteId, const QString &etag ) +void EtagCache::setEtag(const QString &remoteId, const QString &etag) { - mCache[ remoteId ] = etag; + mCache[ remoteId ] = etag; - if ( mChangedRemoteIds.contains( remoteId ) ) - mChangedRemoteIds.remove( remoteId ); + if (mChangedRemoteIds.contains(remoteId)) { + mChangedRemoteIds.remove(remoteId); + } } -bool EtagCache::contains( const QString &remoteId ) +bool EtagCache::contains(const QString &remoteId) { - return mCache.contains( remoteId ); + return mCache.contains(remoteId); } -bool EtagCache::etagChanged( const QString &remoteId, const QString &refEtag ) +bool EtagCache::etagChanged(const QString &remoteId, const QString &refEtag) { - return mCache.value( remoteId ) != refEtag; + return mCache.value(remoteId) != refEtag; } -void EtagCache::markAsChanged( const QString &remoteId ) +void EtagCache::markAsChanged(const QString &remoteId) { - mChangedRemoteIds.insert( remoteId ); + mChangedRemoteIds.insert(remoteId); } -bool EtagCache::isOutOfDate( const QString &remoteId ) const +bool EtagCache::isOutOfDate(const QString &remoteId) const { - return mChangedRemoteIds.contains( remoteId ); + return mChangedRemoteIds.contains(remoteId); } -void EtagCache::removeEtag( const QString &remoteId ) +void EtagCache::removeEtag(const QString &remoteId) { - mChangedRemoteIds.remove( remoteId ); - mCache.remove( remoteId ); + mChangedRemoteIds.remove(remoteId); + mCache.remove(remoteId); } QStringList EtagCache::etags() const { - return mCache.keys(); + return mCache.keys(); } QStringList EtagCache::changedRemoteIds() const { - return mChangedRemoteIds.toList(); + return mChangedRemoteIds.toList(); } -void EtagCache::onItemFetchJobFinished( KJob *job ) +void EtagCache::onItemFetchJobFinished(KJob *job) { - if ( job->error() ) - return; + if (job->error()) { + return; + } - const Akonadi::ItemFetchJob *fetchJob = qobject_cast( job ); - const Akonadi::Item::List items = fetchJob->items(); + const Akonadi::ItemFetchJob *fetchJob = qobject_cast(job); + const Akonadi::Item::List items = fetchJob->items(); - foreach ( const Akonadi::Item &item, items ) { - if ( !mCache.contains( item.remoteId() ) ) - mCache[item.remoteId()] = item.remoteRevision(); - } + foreach (const Akonadi::Item &item, items) { + if (!mCache.contains(item.remoteId())) { + mCache[item.remoteId()] = item.remoteRevision(); + } + } } diff -Nru kdepim-runtime-4.14.6/resources/dav/common/etagcache.h kdepim-runtime-15.08.0/resources/dav/common/etagcache.h --- kdepim-runtime-4.14.6/resources/dav/common/etagcache.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/common/etagcache.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,11 +20,13 @@ #define ETAGCACHE_H #include +#include #include #include -namespace Akonadi { - class Collection; +namespace Akonadi +{ +class Collection; } class KJob; @@ -39,9 +41,9 @@ */ class EtagCache : public QObject { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new etag cache. */ @@ -50,41 +52,41 @@ /** * Populates the cache with the items found in @p collection. */ - void sync( const Akonadi::Collection &collection ); + void sync(const Akonadi::Collection &collection); /** * Sets the ETag for the remote ID. If the remote ID is marked as * changed (is contained in the return of changedRemoteIds), remove * it from the changed list. */ - void setEtag( const QString &remoteId, const QString &etag ); + void setEtag(const QString &remoteId, const QString &etag); /** * Checks if the given item is in the cache */ - bool contains( const QString &remoteId ); + bool contains(const QString &remoteId); /** * Check if the known ETag for the remote ID is equal to @p refEtag and, if not, * mark it as changed. */ - bool etagChanged( const QString &remoteId, const QString &refEtag ); + bool etagChanged(const QString &remoteId, const QString &refEtag); /** * Mark an item as changed in the backend. */ - void markAsChanged( const QString &remoteId ); + void markAsChanged(const QString &remoteId); /** * Returns true if the remote ID is marked as changed (is contained in the * return of changedRemoteIds) */ - bool isOutOfDate( const QString &remoteId ) const; + bool isOutOfDate(const QString &remoteId) const; /** * Removes the entry for item with remote ID @p remoteId. */ - void removeEtag( const QString &remoteId ); + void removeEtag(const QString &remoteId); /** * Returns the list of all etags. @@ -97,10 +99,10 @@ */ QStringList changedRemoteIds() const; - private Q_SLOTS: - void onItemFetchJobFinished( KJob *job ); +private Q_SLOTS: + void onItemFetchJobFinished(KJob *job); - private: +private: QMap mCache; QSet mChangedRemoteIds; }; diff -Nru kdepim-runtime-4.14.6/resources/dav/protocols/caldavprotocol.cpp kdepim-runtime-15.08.0/resources/dav/protocols/caldavprotocol.cpp --- kdepim-runtime-4.14.6/resources/dav/protocols/caldavprotocol.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/protocols/caldavprotocol.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,9 +20,9 @@ #include "davutils.h" #include -#include -#include -#include +#include +#include +#include #include #include @@ -30,344 +30,345 @@ CaldavProtocol::CaldavProtocol() { - // Only fetch items for the last 3 months - QString startTime = QDateTime::currentDateTimeUtc().addMonths( -3 ).toString( "yyyyMMddTHHMMssZ" ); + // Only fetch items for the last 3 months + QString startTime = QDateTime::currentDateTimeUtc().addMonths(-3).toString("yyyyMMddTHHMMssZ"); - /* - * Create a document like the following: - * - * - * - * - * - * - * - * - * - * - * - * - */ - { - QDomDocument document; - - QDomElement queryElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("calendar-query") ); - document.appendChild( queryElement ); - - QDomElement propElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("prop") ); - queryElement.appendChild( propElement ); - - QDomElement getetagElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("getetag") ); - propElement.appendChild( getetagElement ); - - QDomElement getRTypeElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("resourcetype") ); - propElement.appendChild( getRTypeElement ); - - QDomElement filterElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("filter") ); - queryElement.appendChild( filterElement ); - - QDomElement compfilterElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("comp-filter") ); - - QDomAttr nameAttribute = document.createAttribute( QLatin1String("name") ); - nameAttribute.setValue( QLatin1String("VCALENDAR") ); - compfilterElement.setAttributeNode( nameAttribute ); - filterElement.appendChild( compfilterElement ); - - QDomElement subcompfilterElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("comp-filter") ); - nameAttribute = document.createAttribute( QLatin1String("name") ); - nameAttribute.setValue( QLatin1String("VEVENT") ); - subcompfilterElement.setAttributeNode( nameAttribute ); - - QDomElement timeRangeElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("time-range") ); - QDomAttr startAttribute = document.createAttribute( QLatin1String("start") ); - startAttribute.setValue( startTime ); - timeRangeElement.setAttributeNode( startAttribute ); - subcompfilterElement.appendChild( timeRangeElement ); - - compfilterElement.appendChild( subcompfilterElement ); - - mItemsQueries << document; - mItemsMimeTypes << KCalCore::Event::eventMimeType(); - } - - /* - * Create a document like the following: - * - * - * - * - * - * - * - * - * - * - * - * - */ - { - QDomDocument document; - - QDomElement queryElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("calendar-query") ); - document.appendChild( queryElement ); - - QDomElement propElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("prop") ); - queryElement.appendChild( propElement ); - - QDomElement getetagElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("getetag") ); - propElement.appendChild( getetagElement ); - - QDomElement getRTypeElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("resourcetype") ); - propElement.appendChild( getRTypeElement ); - - QDomElement filterElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("filter") ); - queryElement.appendChild( filterElement ); - - QDomElement compfilterElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("comp-filter") ); - - QDomAttr nameAttribute = document.createAttribute( QLatin1String("name") ); - nameAttribute.setValue( QLatin1String("VCALENDAR") ); - compfilterElement.setAttributeNode( nameAttribute ); - filterElement.appendChild( compfilterElement ); - - QDomElement subcompfilterElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("comp-filter") ); - nameAttribute = document.createAttribute( QLatin1String("name") ); - nameAttribute.setValue( QLatin1String("VTODO") ); - subcompfilterElement.setAttributeNode( nameAttribute ); - - QDomElement timeRangeElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("time-range") ); - QDomAttr startAttribute = document.createAttribute( QLatin1String("start") ); - startAttribute.setValue( startTime ); - timeRangeElement.setAttributeNode( startAttribute ); - subcompfilterElement.appendChild( timeRangeElement ); - - compfilterElement.appendChild( subcompfilterElement ); - - mItemsQueries << document; - mItemsMimeTypes << KCalCore::Todo::todoMimeType(); - } - - /* - * Create a document like the following: - * - * - * - * - * - * - * - * - * - * - * - * - */ - { - QDomDocument document; - - QDomElement queryElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("calendar-query") ); - document.appendChild( queryElement ); - - QDomElement propElement = document.createElementNS( QLatin1String("DAV:"),QLatin1String( "prop") ); - queryElement.appendChild( propElement ); - - QDomElement getetagElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("getetag") ); - propElement.appendChild( getetagElement ); - - QDomElement getRTypeElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("resourcetype") ); - propElement.appendChild( getRTypeElement ); - - QDomElement filterElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("filter") ); - queryElement.appendChild( filterElement ); - - QDomElement compfilterElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("comp-filter") ); - - QDomAttr nameAttribute = document.createAttribute( QLatin1String("name") ); - nameAttribute.setValue( QLatin1String("VCALENDAR") ); - compfilterElement.setAttributeNode( nameAttribute ); - filterElement.appendChild( compfilterElement ); - - QDomElement subcompfilterElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("comp-filter") ); - nameAttribute = document.createAttribute( QLatin1String("name") ); - nameAttribute.setValue( QLatin1String("VJOURNAL") ); - subcompfilterElement.setAttributeNode( nameAttribute ); - - QDomElement timeRangeElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("time-range") ); - QDomAttr startAttribute = document.createAttribute( QLatin1String("start") ); - startAttribute.setValue( startTime ); - timeRangeElement.setAttributeNode( startAttribute ); - subcompfilterElement.appendChild( timeRangeElement ); - - compfilterElement.appendChild( subcompfilterElement ); - - mItemsQueries << document; - mItemsMimeTypes << KCalCore::Journal::journalMimeType(); - } + /* + * Create a document like the following: + * + * + * + * + * + * + * + * + * + * + * + * + */ + { + QDomDocument document; + + QDomElement queryElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("calendar-query")); + document.appendChild(queryElement); + + QDomElement propElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + queryElement.appendChild(propElement); + + QDomElement getetagElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("getetag")); + propElement.appendChild(getetagElement); + + QDomElement getRTypeElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("resourcetype")); + propElement.appendChild(getRTypeElement); + + QDomElement filterElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("filter")); + queryElement.appendChild(filterElement); + + QDomElement compfilterElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("comp-filter")); + + QDomAttr nameAttribute = document.createAttribute(QStringLiteral("name")); + nameAttribute.setValue(QStringLiteral("VCALENDAR")); + compfilterElement.setAttributeNode(nameAttribute); + filterElement.appendChild(compfilterElement); + + QDomElement subcompfilterElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("comp-filter")); + nameAttribute = document.createAttribute(QStringLiteral("name")); + nameAttribute.setValue(QStringLiteral("VEVENT")); + subcompfilterElement.setAttributeNode(nameAttribute); + + QDomElement timeRangeElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("time-range")); + QDomAttr startAttribute = document.createAttribute(QStringLiteral("start")); + startAttribute.setValue(startTime); + timeRangeElement.setAttributeNode(startAttribute); + subcompfilterElement.appendChild(timeRangeElement); + + compfilterElement.appendChild(subcompfilterElement); + + mItemsQueries << document; + mItemsMimeTypes << KCalCore::Event::eventMimeType(); + } + + /* + * Create a document like the following: + * + * + * + * + * + * + * + * + * + * + * + * + */ + { + QDomDocument document; + + QDomElement queryElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("calendar-query")); + document.appendChild(queryElement); + + QDomElement propElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + queryElement.appendChild(propElement); + + QDomElement getetagElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("getetag")); + propElement.appendChild(getetagElement); + + QDomElement getRTypeElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("resourcetype")); + propElement.appendChild(getRTypeElement); + + QDomElement filterElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("filter")); + queryElement.appendChild(filterElement); + + QDomElement compfilterElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("comp-filter")); + + QDomAttr nameAttribute = document.createAttribute(QStringLiteral("name")); + nameAttribute.setValue(QStringLiteral("VCALENDAR")); + compfilterElement.setAttributeNode(nameAttribute); + filterElement.appendChild(compfilterElement); + + QDomElement subcompfilterElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("comp-filter")); + nameAttribute = document.createAttribute(QStringLiteral("name")); + nameAttribute.setValue(QStringLiteral("VTODO")); + subcompfilterElement.setAttributeNode(nameAttribute); + + QDomElement timeRangeElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("time-range")); + QDomAttr startAttribute = document.createAttribute(QStringLiteral("start")); + startAttribute.setValue(startTime); + timeRangeElement.setAttributeNode(startAttribute); + subcompfilterElement.appendChild(timeRangeElement); + + compfilterElement.appendChild(subcompfilterElement); + + mItemsQueries << document; + mItemsMimeTypes << KCalCore::Todo::todoMimeType(); + } + + /* + * Create a document like the following: + * + * + * + * + * + * + * + * + * + * + * + * + */ + { + QDomDocument document; + + QDomElement queryElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("calendar-query")); + document.appendChild(queryElement); + + QDomElement propElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + queryElement.appendChild(propElement); + + QDomElement getetagElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("getetag")); + propElement.appendChild(getetagElement); + + QDomElement getRTypeElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("resourcetype")); + propElement.appendChild(getRTypeElement); + + QDomElement filterElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("filter")); + queryElement.appendChild(filterElement); + + QDomElement compfilterElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("comp-filter")); + + QDomAttr nameAttribute = document.createAttribute(QStringLiteral("name")); + nameAttribute.setValue(QStringLiteral("VCALENDAR")); + compfilterElement.setAttributeNode(nameAttribute); + filterElement.appendChild(compfilterElement); + + QDomElement subcompfilterElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("comp-filter")); + nameAttribute = document.createAttribute(QStringLiteral("name")); + nameAttribute.setValue(QStringLiteral("VJOURNAL")); + subcompfilterElement.setAttributeNode(nameAttribute); + + QDomElement timeRangeElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("time-range")); + QDomAttr startAttribute = document.createAttribute(QStringLiteral("start")); + startAttribute.setValue(startTime); + timeRangeElement.setAttributeNode(startAttribute); + subcompfilterElement.appendChild(timeRangeElement); + + compfilterElement.appendChild(subcompfilterElement); + + mItemsQueries << document; + mItemsMimeTypes << KCalCore::Journal::journalMimeType(); + } } bool CaldavProtocol::supportsPrincipals() const { - return true; + return true; } bool CaldavProtocol::useReport() const { - return true; + return true; } bool CaldavProtocol::useMultiget() const { - return true; + return true; } QString CaldavProtocol::principalHomeSet() const { - return QLatin1String( "calendar-home-set" ); + return QStringLiteral("calendar-home-set"); } QString CaldavProtocol::principalHomeSetNS() const { - return QLatin1String( "urn:ietf:params:xml:ns:caldav" ); + return QStringLiteral("urn:ietf:params:xml:ns:caldav"); } QDomDocument CaldavProtocol::collectionsQuery() const { - QDomDocument document; + QDomDocument document; - QDomElement propfindElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("propfind") ); - document.appendChild( propfindElement ); + QDomElement propfindElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("propfind")); + document.appendChild(propfindElement); - QDomElement propElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("prop") ); - propfindElement.appendChild( propElement ); + QDomElement propElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + propfindElement.appendChild(propElement); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("displayname") ) ); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("resourcetype" )) ); - propElement.appendChild( document.createElementNS( QLatin1String("http://apple.com/ns/ical/"), QLatin1String("calendar-color") ) ); - propElement.appendChild( document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("supported-calendar-component-set") ) ); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("current-user-privilege-set") ) ); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("displayname"))); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("resourcetype"))); + propElement.appendChild(document.createElementNS(QStringLiteral("http://apple.com/ns/ical/"), QStringLiteral("calendar-color"))); + propElement.appendChild(document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("supported-calendar-component-set"))); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("current-user-privilege-set"))); - return document; + return document; } QString CaldavProtocol::collectionsXQuery() const { - //const QString query( "//*[local-name()='calendar' and namespace-uri()='urn:ietf:params:xml:ns:caldav']/ancestor::*[local-name()='prop' and namespace-uri()='DAV:']/*[local-name()='supported-calendar-component-set' and namespace-uri()='urn:ietf:params:xml:ns:caldav']/*[local-name()='comp' and namespace-uri()='urn:ietf:params:xml:ns:caldav' and (@name='VTODO' or @name='VEVENT')]/ancestor::*[local-name()='response' and namespace-uri()='DAV:']" ); - const QString query( QLatin1String("//*[local-name()='calendar' and namespace-uri()='urn:ietf:params:xml:ns:caldav']/ancestor::*[local-name()='prop' and namespace-uri()='DAV:']/ancestor::*[local-name()='response' and namespace-uri()='DAV:']") ); + //const QString query( "//*[local-name()='calendar' and namespace-uri()='urn:ietf:params:xml:ns:caldav']/ancestor::*[local-name()='prop' and namespace-uri()='DAV:']/*[local-name()='supported-calendar-component-set' and namespace-uri()='urn:ietf:params:xml:ns:caldav']/*[local-name()='comp' and namespace-uri()='urn:ietf:params:xml:ns:caldav' and (@name='VTODO' or @name='VEVENT')]/ancestor::*[local-name()='response' and namespace-uri()='DAV:']" ); + const QString query(QStringLiteral("//*[local-name()='calendar' and namespace-uri()='urn:ietf:params:xml:ns:caldav']/ancestor::*[local-name()='prop' and namespace-uri()='DAV:']/ancestor::*[local-name()='response' and namespace-uri()='DAV:']")); - return query; + return query; } -QList CaldavProtocol::itemsQueries() const +QVector CaldavProtocol::itemsQueries() const { - return mItemsQueries; + return mItemsQueries; } -QString CaldavProtocol::mimeTypeForQuery( int index ) const +QString CaldavProtocol::mimeTypeForQuery(int index) const { - return mItemsMimeTypes.at( index ); + return mItemsMimeTypes.at(index); } -QDomDocument CaldavProtocol::itemsReportQuery( const QStringList &urls ) const +QDomDocument CaldavProtocol::itemsReportQuery(const QStringList &urls) const { - QDomDocument document; + QDomDocument document; - QDomElement multigetElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("calendar-multiget") ); - document.appendChild( multigetElement ); + QDomElement multigetElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("calendar-multiget")); + document.appendChild(multigetElement); - QDomElement propElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("prop") ); - multigetElement.appendChild( propElement ); + QDomElement propElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + multigetElement.appendChild(propElement); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"),QLatin1String("getetag") ) ); - propElement.appendChild( document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("calendar-data") ) ); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("getetag"))); + propElement.appendChild(document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("calendar-data"))); - foreach ( const QString &url, urls ) { - QDomElement hrefElement = document.createElementNS(QLatin1String( "DAV:"), QLatin1String("href") ); - const KUrl pathUrl( url ); + foreach (const QString &url, urls) { + QDomElement hrefElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("href")); + const KUrl pathUrl(url); - const QDomText textNode = document.createTextNode( pathUrl.encodedPathAndQuery() ); - hrefElement.appendChild( textNode ); + const QDomText textNode = document.createTextNode(pathUrl.encodedPathAndQuery()); + hrefElement.appendChild(textNode); - multigetElement.appendChild( hrefElement ); - } + multigetElement.appendChild(hrefElement); + } - return document; + return document; } QString CaldavProtocol::responseNamespace() const { - return QLatin1String("urn:ietf:params:xml:ns:caldav"); + return QStringLiteral("urn:ietf:params:xml:ns:caldav"); } QString CaldavProtocol::dataTagName() const { - return QLatin1String("calendar-data"); + return QStringLiteral("calendar-data"); } -DavCollection::ContentTypes CaldavProtocol::collectionContentTypes( const QDomElement &propstatElement ) const +DavCollection::ContentTypes CaldavProtocol::collectionContentTypes(const QDomElement &propstatElement) const { - /* - * Extract the content type information from a propstat like the following - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * Test1 User - * - * HTTP/1.1 200 OK - * - */ - - const QDomElement propElement = DavUtils::firstChildElementNS( propstatElement, QLatin1String("DAV:"), QLatin1String("prop") ); - const QDomElement supportedcomponentElement = DavUtils::firstChildElementNS( propElement, QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("supported-calendar-component-set") ); - - DavCollection::ContentTypes contentTypes; - QDomElement compElement = DavUtils::firstChildElementNS( supportedcomponentElement, QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("comp") ); - - /* - * Assign the content-type if the server didn't return anything. - * According to RFC4791, §5.2.3: - * In the absence of this property, the server MUST accept all - * component types, and the client can assume that all component - * types are accepted. - */ - if ( compElement.isNull() ) { - contentTypes |= DavCollection::Calendar; - contentTypes |= DavCollection::Events; - contentTypes |= DavCollection::Todos; - contentTypes |= DavCollection::FreeBusy; - contentTypes |= DavCollection::Journal; - } - - while ( !compElement.isNull() ) { - const QString type = compElement.attribute( QLatin1String("name") ).toLower(); - if ( type == QLatin1String( "vcalendar" ) ) - contentTypes |= DavCollection::Calendar; - else if ( type == QLatin1String( "vevent" ) ) - contentTypes |= DavCollection::Events; - else if ( type == QLatin1String( "vtodo" ) ) - contentTypes |= DavCollection::Todos; - else if ( type == QLatin1String( "vfreebusy" ) ) - contentTypes |= DavCollection::FreeBusy; - else if ( type == QLatin1String( "vjournal" ) ) - contentTypes |= DavCollection::Journal; + /* + * Extract the content type information from a propstat like the following + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * Test1 User + * + * HTTP/1.1 200 OK + * + */ + + const QDomElement propElement = DavUtils::firstChildElementNS(propstatElement, QStringLiteral("DAV:"), QStringLiteral("prop")); + const QDomElement supportedcomponentElement = DavUtils::firstChildElementNS(propElement, QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("supported-calendar-component-set")); + + DavCollection::ContentTypes contentTypes; + QDomElement compElement = DavUtils::firstChildElementNS(supportedcomponentElement, QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("comp")); + + /* + * Assign the content-type if the server didn't return anything. + * According to RFC4791, §5.2.3: + * In the absence of this property, the server MUST accept all + * component types, and the client can assume that all component + * types are accepted. + */ + if (compElement.isNull()) { + contentTypes |= DavCollection::Calendar; + contentTypes |= DavCollection::Events; + contentTypes |= DavCollection::Todos; + contentTypes |= DavCollection::FreeBusy; + contentTypes |= DavCollection::Journal; + } + + while (!compElement.isNull()) { + const QString type = compElement.attribute(QStringLiteral("name")).toLower(); + if (type == QLatin1String("vcalendar")) { + contentTypes |= DavCollection::Calendar; + } else if (type == QLatin1String("vevent")) { + contentTypes |= DavCollection::Events; + } else if (type == QLatin1String("vtodo")) { + contentTypes |= DavCollection::Todos; + } else if (type == QLatin1String("vfreebusy")) { + contentTypes |= DavCollection::FreeBusy; + } else if (type == QLatin1String("vjournal")) { + contentTypes |= DavCollection::Journal; + } - compElement = DavUtils::nextSiblingElementNS( compElement, QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("comp") ); - } + compElement = DavUtils::nextSiblingElementNS(compElement, QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("comp")); + } - return contentTypes; + return contentTypes; } QString CaldavProtocol::contactsMimeType() const { - return QString(); // will never be called for this protocol + return QString(); // will never be called for this protocol } diff -Nru kdepim-runtime-4.14.6/resources/dav/protocols/caldavprotocol.h kdepim-runtime-15.08.0/resources/dav/protocols/caldavprotocol.h --- kdepim-runtime-4.14.6/resources/dav/protocols/caldavprotocol.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/protocols/caldavprotocol.h 2015-08-10 21:01:02.000000000 +0000 @@ -23,26 +23,26 @@ class CaldavProtocol : public DavMultigetProtocol { - public: +public: CaldavProtocol(); - virtual bool supportsPrincipals() const; - virtual bool useReport() const; - virtual bool useMultiget() const; - virtual QString principalHomeSet() const; - virtual QString principalHomeSetNS() const; - virtual QDomDocument collectionsQuery() const; - virtual QString collectionsXQuery() const; - virtual QList itemsQueries() const; - virtual QString mimeTypeForQuery( int index ) const; - virtual QDomDocument itemsReportQuery( const QStringList &urls ) const; - virtual QString responseNamespace() const; - virtual QString dataTagName() const; + bool supportsPrincipals() const Q_DECL_OVERRIDE; + bool useReport() const Q_DECL_OVERRIDE; + bool useMultiget() const Q_DECL_OVERRIDE; + QString principalHomeSet() const Q_DECL_OVERRIDE; + QString principalHomeSetNS() const Q_DECL_OVERRIDE; + QDomDocument collectionsQuery() const Q_DECL_OVERRIDE; + QString collectionsXQuery() const Q_DECL_OVERRIDE; + QVector itemsQueries() const Q_DECL_OVERRIDE; + QString mimeTypeForQuery(int index) const Q_DECL_OVERRIDE; + QDomDocument itemsReportQuery(const QStringList &urls) const Q_DECL_OVERRIDE; + QString responseNamespace() const Q_DECL_OVERRIDE; + QString dataTagName() const Q_DECL_OVERRIDE; - virtual DavCollection::ContentTypes collectionContentTypes( const QDomElement &propstat ) const; - virtual QString contactsMimeType() const; + DavCollection::ContentTypes collectionContentTypes(const QDomElement &propstat) const Q_DECL_OVERRIDE; + QString contactsMimeType() const Q_DECL_OVERRIDE; - private: - QList mItemsQueries; +private: + QVector mItemsQueries; QStringList mItemsMimeTypes; }; diff -Nru kdepim-runtime-4.14.6/resources/dav/protocols/carddavprotocol.cpp kdepim-runtime-15.08.0/resources/dav/protocols/carddavprotocol.cpp --- kdepim-runtime-4.14.6/resources/dav/protocols/carddavprotocol.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/protocols/carddavprotocol.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,131 +18,131 @@ #include "carddavprotocol.h" -#include +#include #include #include CarddavProtocol::CarddavProtocol() { - QDomDocument document; + QDomDocument document; - QDomElement propfindElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("propfind") ); - document.appendChild( propfindElement ); + QDomElement propfindElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("propfind")); + document.appendChild(propfindElement); - QDomElement propElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("prop") ); - propfindElement.appendChild( propElement ); + QDomElement propElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + propfindElement.appendChild(propElement); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("displayname") ) ); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("resourcetype") ) ); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("getetag") ) ); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("displayname"))); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("resourcetype"))); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("getetag"))); - mItemsQueries << document; - mItemsMimeTypes << KABC::Addressee::mimeType(); + mItemsQueries << document; + mItemsMimeTypes << KContacts::Addressee::mimeType(); } bool CarddavProtocol::supportsPrincipals() const { - return true; + return true; } bool CarddavProtocol::useReport() const { - return false; + return false; } bool CarddavProtocol::useMultiget() const { - return true; + return true; } QString CarddavProtocol::principalHomeSet() const { - return QLatin1String( "addressbook-home-set" ); + return QStringLiteral("addressbook-home-set"); } QString CarddavProtocol::principalHomeSetNS() const { - return QLatin1String( "urn:ietf:params:xml:ns:carddav" ); + return QStringLiteral("urn:ietf:params:xml:ns:carddav"); } QDomDocument CarddavProtocol::collectionsQuery() const { - QDomDocument document; + QDomDocument document; - QDomElement propfindElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("propfind") ); - document.appendChild( propfindElement ); + QDomElement propfindElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("propfind")); + document.appendChild(propfindElement); - QDomElement propElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("prop") ); - propfindElement.appendChild( propElement ); + QDomElement propElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + propfindElement.appendChild(propElement); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("displayname") ) ); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("resourcetype") ) ); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("displayname"))); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("resourcetype"))); - return document; + return document; } QString CarddavProtocol::collectionsXQuery() const { - const QString query( QLatin1String("//*[local-name()='addressbook' and namespace-uri()='urn:ietf:params:xml:ns:carddav']/ancestor::*[local-name()='response' and namespace-uri()='DAV:']") ); + const QString query(QStringLiteral("//*[local-name()='addressbook' and namespace-uri()='urn:ietf:params:xml:ns:carddav']/ancestor::*[local-name()='response' and namespace-uri()='DAV:']")); - return query; + return query; } -QList CarddavProtocol::itemsQueries() const +QVector CarddavProtocol::itemsQueries() const { - return mItemsQueries; + return mItemsQueries; } -QString CarddavProtocol::mimeTypeForQuery( int index ) const +QString CarddavProtocol::mimeTypeForQuery(int index) const { - return mItemsMimeTypes.at( index ); + return mItemsMimeTypes.at(index); } -QDomDocument CarddavProtocol::itemsReportQuery( const QStringList &urls ) const +QDomDocument CarddavProtocol::itemsReportQuery(const QStringList &urls) const { - QDomDocument document; + QDomDocument document; - QDomElement multigetElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:carddav"), QLatin1String("addressbook-multiget") ); - document.appendChild( multigetElement ); + QDomElement multigetElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:carddav"), QStringLiteral("addressbook-multiget")); + document.appendChild(multigetElement); - QDomElement propElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("prop") ); - multigetElement.appendChild( propElement ); + QDomElement propElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + multigetElement.appendChild(propElement); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("getetag") ) ); - QDomElement addressDataElement = document.createElementNS( QLatin1String("urn:ietf:params:xml:ns:carddav"), QLatin1String("address-data") ); - addressDataElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("allprop") ) ); - propElement.appendChild( addressDataElement ); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("getetag"))); + QDomElement addressDataElement = document.createElementNS(QStringLiteral("urn:ietf:params:xml:ns:carddav"), QStringLiteral("address-data")); + addressDataElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("allprop"))); + propElement.appendChild(addressDataElement); - foreach ( const QString &url, urls ) { - QDomElement hrefElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("href") ); - const KUrl pathUrl( url ); + foreach (const QString &url, urls) { + QDomElement hrefElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("href")); + const KUrl pathUrl(url); - const QDomText textNode = document.createTextNode( pathUrl.encodedPathAndQuery() ); - hrefElement.appendChild( textNode ); + const QDomText textNode = document.createTextNode(pathUrl.encodedPathAndQuery()); + hrefElement.appendChild(textNode); - multigetElement.appendChild( hrefElement ); - } + multigetElement.appendChild(hrefElement); + } - return document; + return document; } QString CarddavProtocol::responseNamespace() const { - return QLatin1String("urn:ietf:params:xml:ns:carddav"); + return QStringLiteral("urn:ietf:params:xml:ns:carddav"); } QString CarddavProtocol::dataTagName() const { - return QLatin1String("address-data"); + return QStringLiteral("address-data"); } -DavCollection::ContentTypes CarddavProtocol::collectionContentTypes( const QDomElement& ) const +DavCollection::ContentTypes CarddavProtocol::collectionContentTypes(const QDomElement &) const { - return DavCollection::Contacts; + return DavCollection::Contacts; } QString CarddavProtocol::contactsMimeType() const { - return QLatin1String( "text/vcard" ); + return QStringLiteral("text/vcard"); } diff -Nru kdepim-runtime-4.14.6/resources/dav/protocols/carddavprotocol.h kdepim-runtime-15.08.0/resources/dav/protocols/carddavprotocol.h --- kdepim-runtime-4.14.6/resources/dav/protocols/carddavprotocol.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/protocols/carddavprotocol.h 2015-08-10 21:01:02.000000000 +0000 @@ -23,26 +23,26 @@ class CarddavProtocol : public DavMultigetProtocol { - public: +public: CarddavProtocol(); - virtual bool supportsPrincipals() const; - virtual bool useReport() const; - virtual bool useMultiget() const; - virtual QString principalHomeSet() const; - virtual QString principalHomeSetNS() const; - virtual QDomDocument collectionsQuery() const; - virtual QString collectionsXQuery() const; - virtual QList itemsQueries() const; - virtual QString mimeTypeForQuery( int index ) const; - virtual QDomDocument itemsReportQuery( const QStringList &urls ) const; - virtual QString responseNamespace() const; - virtual QString dataTagName() const; + bool supportsPrincipals() const Q_DECL_OVERRIDE; + bool useReport() const Q_DECL_OVERRIDE; + bool useMultiget() const Q_DECL_OVERRIDE; + QString principalHomeSet() const Q_DECL_OVERRIDE; + QString principalHomeSetNS() const Q_DECL_OVERRIDE; + QDomDocument collectionsQuery() const Q_DECL_OVERRIDE; + QString collectionsXQuery() const Q_DECL_OVERRIDE; + QVector itemsQueries() const Q_DECL_OVERRIDE; + QString mimeTypeForQuery(int index) const Q_DECL_OVERRIDE; + QDomDocument itemsReportQuery(const QStringList &urls) const Q_DECL_OVERRIDE; + QString responseNamespace() const Q_DECL_OVERRIDE; + QString dataTagName() const Q_DECL_OVERRIDE; - virtual DavCollection::ContentTypes collectionContentTypes( const QDomElement &propstat ) const; - virtual QString contactsMimeType() const; + DavCollection::ContentTypes collectionContentTypes(const QDomElement &propstat) const Q_DECL_OVERRIDE; + QString contactsMimeType() const Q_DECL_OVERRIDE; - private: - QList mItemsQueries; +private: + QVector mItemsQueries; QStringList mItemsMimeTypes; }; diff -Nru kdepim-runtime-4.14.6/resources/dav/protocols/groupdavprotocol.cpp kdepim-runtime-15.08.0/resources/dav/protocols/groupdavprotocol.cpp --- kdepim-runtime-4.14.6/resources/dav/protocols/groupdavprotocol.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/protocols/groupdavprotocol.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,105 +24,108 @@ GroupdavProtocol::GroupdavProtocol() { - QDomDocument document; + QDomDocument document; - QDomElement propfindElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("propfind") ); - document.appendChild( propfindElement ); + QDomElement propfindElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("propfind")); + document.appendChild(propfindElement); - QDomElement propElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("prop") ); - propfindElement.appendChild( propElement ); + QDomElement propElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + propfindElement.appendChild(propElement); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("displayname") ) ); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("resourcetype" )) ); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("getetag") ) ); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("displayname"))); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("resourcetype"))); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("getetag"))); - mItemsQueries << document; + mItemsQueries << document; } bool GroupdavProtocol::supportsPrincipals() const { - return false; + return false; } bool GroupdavProtocol::useReport() const { - return false; + return false; } bool GroupdavProtocol::useMultiget() const { - return false; + return false; } QDomDocument GroupdavProtocol::collectionsQuery() const { - QDomDocument document; + QDomDocument document; - QDomElement propfindElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("propfind") ); - document.appendChild( propfindElement ); + QDomElement propfindElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("propfind")); + document.appendChild(propfindElement); - QDomElement propElement = document.createElementNS( QLatin1String("DAV:"), QLatin1String("prop") ); - propfindElement.appendChild( propElement ); + QDomElement propElement = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("prop")); + propfindElement.appendChild(propElement); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("displayname") ) ); - propElement.appendChild( document.createElementNS( QLatin1String("DAV:"), QLatin1String("resourcetype") ) ); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("displayname"))); + propElement.appendChild(document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("resourcetype"))); - return document; + return document; } QString GroupdavProtocol::collectionsXQuery() const { - const QString query( QLatin1String("//*[(local-name()='vevent-collection' or local-name()='vtodo-collection' or local-name()='vcard-collection') and namespace-uri()='http://groupdav.org/']/ancestor::*[local-name()='response' and namespace-uri()='DAV:']") ); + const QString query(QStringLiteral("//*[(local-name()='vevent-collection' or local-name()='vtodo-collection' or local-name()='vcard-collection') and namespace-uri()='http://groupdav.org/']/ancestor::*[local-name()='response' and namespace-uri()='DAV:']")); - return query; + return query; } -QList GroupdavProtocol::itemsQueries() const +QVector GroupdavProtocol::itemsQueries() const { - return mItemsQueries; + return mItemsQueries; } -QString GroupdavProtocol::mimeTypeForQuery( int index ) const +QString GroupdavProtocol::mimeTypeForQuery(int index) const { - return QString(); + return QString(); } -DavCollection::ContentTypes GroupdavProtocol::collectionContentTypes( const QDomElement &propstatElement ) const +DavCollection::ContentTypes GroupdavProtocol::collectionContentTypes(const QDomElement &propstatElement) const { - /* - * Extract the content type information from a propstat like the following - * - * - * HTTP/1.1 200 OK - * - * Tasks - * - * - * - * - * Sat, 30 Jan 2010 17:52:41 -0100 - * - * - */ + /* + * Extract the content type information from a propstat like the following + * + * + * HTTP/1.1 200 OK + * + * Tasks + * + * + * + * + * Sat, 30 Jan 2010 17:52:41 -0100 + * + * + */ - const QDomElement propElement = DavUtils::firstChildElementNS( propstatElement, QLatin1String("DAV:"), QLatin1String("prop") ); - const QDomElement resourcetypeElement = DavUtils::firstChildElementNS( propElement, QLatin1String("DAV:"), QLatin1String("resourcetype") ); + const QDomElement propElement = DavUtils::firstChildElementNS(propstatElement, QStringLiteral("DAV:"), QStringLiteral("prop")); + const QDomElement resourcetypeElement = DavUtils::firstChildElementNS(propElement, QStringLiteral("DAV:"), QStringLiteral("resourcetype")); - DavCollection::ContentTypes contentTypes; + DavCollection::ContentTypes contentTypes; - if ( !DavUtils::firstChildElementNS( resourcetypeElement, QLatin1String("http://groupdav.org/"), QLatin1String("vevent-collection") ).isNull() ) - contentTypes |= DavCollection::Events; + if (!DavUtils::firstChildElementNS(resourcetypeElement, QStringLiteral("http://groupdav.org/"), QStringLiteral("vevent-collection")).isNull()) { + contentTypes |= DavCollection::Events; + } - if ( !DavUtils::firstChildElementNS( resourcetypeElement, QLatin1String("http://groupdav.org/"), QLatin1String("vtodo-collection") ).isNull() ) - contentTypes |= DavCollection::Todos; + if (!DavUtils::firstChildElementNS(resourcetypeElement, QStringLiteral("http://groupdav.org/"), QStringLiteral("vtodo-collection")).isNull()) { + contentTypes |= DavCollection::Todos; + } - if ( !DavUtils::firstChildElementNS( resourcetypeElement, QLatin1String("http://groupdav.org/"), QLatin1String("vcard-collection") ).isNull() ) - contentTypes |= DavCollection::Contacts; + if (!DavUtils::firstChildElementNS(resourcetypeElement, QStringLiteral("http://groupdav.org/"), QStringLiteral("vcard-collection")).isNull()) { + contentTypes |= DavCollection::Contacts; + } - return contentTypes; + return contentTypes; } QString GroupdavProtocol::contactsMimeType() const { - return QLatin1String( "text/x-vcard" ); + return QStringLiteral("text/x-vcard"); } diff -Nru kdepim-runtime-4.14.6/resources/dav/protocols/groupdavprotocol.h kdepim-runtime-15.08.0/resources/dav/protocols/groupdavprotocol.h --- kdepim-runtime-4.14.6/resources/dav/protocols/groupdavprotocol.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/protocols/groupdavprotocol.h 2015-08-10 21:01:02.000000000 +0000 @@ -23,21 +23,21 @@ class GroupdavProtocol : public DavProtocolBase { - public: +public: GroupdavProtocol(); - virtual bool supportsPrincipals() const; - virtual bool useReport() const; - virtual bool useMultiget() const; - virtual QDomDocument collectionsQuery() const; - virtual QString collectionsXQuery() const; - virtual QList itemsQueries() const; - virtual QString mimeTypeForQuery( int index ) const; + bool supportsPrincipals() const Q_DECL_OVERRIDE; + bool useReport() const Q_DECL_OVERRIDE; + bool useMultiget() const Q_DECL_OVERRIDE; + QDomDocument collectionsQuery() const Q_DECL_OVERRIDE; + QString collectionsXQuery() const Q_DECL_OVERRIDE; + QVector itemsQueries() const Q_DECL_OVERRIDE; + QString mimeTypeForQuery(int index) const Q_DECL_OVERRIDE; - virtual DavCollection::ContentTypes collectionContentTypes( const QDomElement &propstat ) const; - virtual QString contactsMimeType() const; + DavCollection::ContentTypes collectionContentTypes(const QDomElement &propstat) const Q_DECL_OVERRIDE; + QString contactsMimeType() const Q_DECL_OVERRIDE; - private: - QList mItemsQueries; +private: + QVector mItemsQueries; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/CMakeLists.txt kdepim-runtime-15.08.0/resources/dav/resource/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/dav/resource/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,23 +1,20 @@ project(davgroupware) -if (QT_QTXMLPATTERNS_LIBRARY) +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_davgroupware_resource\") + +#if (QT_QTXMLPATTERNS_LIBRARY) if(WIN32) - set(LIB_INSTALL_DIR ${LIB_INSTALL_DIR} - RUNTIME DESTINATION ${BIN_INSTALL_DIR} - LIBRARY DESTINATION ${LIB_INSTALL_DIR} - ARCHIVE DESTINATION ${LIB_INSTALL_DIR} ) + set(LIB_INSTALL_DIR ${KDE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${KDE_INSTALL_BINDIR} + LIBRARY DESTINATION ${KDE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${KDE_INSTALL_LIBDIR} ) endif() include_directories( - ${KDE4_INCLUDES} - ${KDEPIMLIBS_INCLUDE_DIRS} ../common/ ../protocols/ ) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - - ########### next target ############### set( davgroupwareresource_SRCS @@ -45,7 +42,7 @@ ../protocols/caldavprotocol.cpp ../protocols/carddavprotocol.cpp ../protocols/groupdavprotocol.cpp - + davresource_debug.cpp configdialog.cpp davfreebusyhandler.cpp davgroupwareresource.cpp @@ -59,49 +56,47 @@ if(${AccountsQt_FOUND} AND ${SignOnQt_FOUND}) include_directories(${ACCOUNTSQT_INCLUDE_DIRS} ${SIGNONQT_INCLUDE_DIRS}) add_definitions(-DHAVE_ACCOUNTS) - set(davgroupwareresource_SRCS ../../shared/getcredentialsjob.cpp ${davgroupwareresource_SRCS}) + set(davgroupwareresource_SRCS ../../shared/singlefileresource/getcredentialsjob.cpp ${davgroupwareresource_SRCS}) endif() - install( FILES davgroupwareresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) - install( FILES davgroupwareprovider.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR} ) + install( FILES davgroupwareresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) + install( FILES davgroupwareprovider.desktop DESTINATION ${KDE_INSTALL_KSERVICETYPES5DIR} ) file( GLOB providersFiles "../services/*.desktop" ) - install( FILES ${providersFiles} DESTINATION "${SERVICES_INSTALL_DIR}/akonadi/davgroupware-providers" ) + install( FILES ${providersFiles} DESTINATION "${KDE_INSTALL_KSERVICES5DIR}/akonadi/davgroupware-providers" ) - kde4_add_kcfg_files(davgroupwareresource_SRCS settingsbase.kcfgc) - kde4_add_ui_files(davgroupwareresource_SRCS configdialog.ui urlconfigurationdialog.ui searchdialog.ui) + kconfig_add_kcfg_files(davgroupwareresource_SRCS settingsbase.kcfgc) + ki18n_wrap_ui(davgroupwareresource_SRCS configdialog.ui urlconfigurationdialog.ui searchdialog.ui) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/davgroupwareresource.kcfg org.kde.Akonadi.davGroupware.Settings) - qt4_add_dbus_adaptor(davgroupwareresource_SRCS + qt5_add_dbus_adaptor(davgroupwareresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.davGroupware.Settings.xml settings.h Settings ) - kde4_add_executable(akonadi_davgroupware_resource RUN_UNINSTALLED ${davgroupwareresource_SRCS}) + add_executable(akonadi_davgroupware_resource ${davgroupwareresource_SRCS}) - if (Q_WS_MAC) + if( APPLE ) set_target_properties(akonadi_davgroupware_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../../Info.plist.template) set_target_properties(akonadi_davgroupware_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.davGroupware") set_target_properties(akonadi_davgroupware_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi davGroupware Resource") endif () target_link_libraries(akonadi_davgroupware_resource - ${QT_QTCORE_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ${QT_QTXML_LIBRARY} - ${QT_QTXMLPATTERNS_LIBRARY} - ${KDE4_KDECORE_LIBS} - ${KDE4_KIO_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_AKONADI_CALENDAR_LIBS} - ${KDEPIMLIBS_KABC_LIBS} - ${KDEPIMLIBS_KCALCORE_LIBS}) + Qt5::XmlPatterns + KF5::Contacts + KF5::AkonadiCalendar + KF5::KIOCore + KF5::AkonadiAgentBase + KF5::AkonadiCore + KF5::Wallet + KF5::CalendarCore) if(${AccountsQt_FOUND} AND ${SignOnQt_FOUND}) target_link_libraries(akonadi_davgroupware_resource ${ACCOUNTSQT_LIBRARIES} ${SIGNONQT_LIBRARIES}) endif() - install(TARGETS akonadi_davgroupware_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) -else() - add_feature_info("Davgroupware resource" QT_QTXMLPATTERNS_LIBRARY "The QtXmlPatterns library was not found. It is needed for building the davgroupware resource.") -endif() + install(TARGETS akonadi_davgroupware_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) +#else() +# add_feature_info("Davgroupware resource" QT_QTXMLPATTERNS_LIBRARY "The QtXmlPatterns library was not found. It is needed for building the davgroupware resource.") +#endif() diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/configdialog.cpp kdepim-runtime-15.08.0/resources/dav/resource/configdialog.cpp --- kdepim-runtime-4.14.6/resources/dav/resource/configdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/configdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,256 +23,295 @@ #include #include -#include +#include #include #include #include #include -#include -#include - -ConfigDialog::ConfigDialog( QWidget *parent ) - : KDialog( parent ) -{ - mUi.setupUi( mainWidget() ); - setWindowIcon( KIcon( QLatin1String("folder-remote") ) ); - - mModel = new QStandardItemModel(); - QStringList headers; - headers << i18n( "Protocol" ) << i18n( "URL" ); - mModel->setHorizontalHeaderLabels( headers ); - - mUi.configuredUrls->setModel( mModel ); - mUi.configuredUrls->setRootIsDecorated( false ); +#include +#include +#include +#include + +ConfigDialog::ConfigDialog(QWidget *parent) + : QDialog(parent) +{ + QWidget *mainWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); + mUi.setupUi(mainWidget); + setWindowIcon(QIcon::fromTheme(QStringLiteral("folder-remote"))); + + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + mOkButton = buttonBox->button(QDialogButtonBox::Ok); + mOkButton->setDefault(true); + mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::rejected, this, &ConfigDialog::onCancelClicked); + mainLayout->addWidget(buttonBox); + + mModel = new QStandardItemModel(); + QStringList headers; + headers << i18n("Protocol") << i18n("URL"); + mModel->setHorizontalHeaderLabels(headers); + + mUi.configuredUrls->setModel(mModel); + mUi.configuredUrls->setRootIsDecorated(false); + + foreach (const DavUtils::DavUrl &url, Settings::self()->configuredDavUrls()) { + KUrl displayUrl = url.url(); + displayUrl.setUser(QString()); + addModelRow(DavUtils::translatedProtocolName(url.protocol()), displayUrl.prettyUrl()); + } - foreach ( const DavUtils::DavUrl &url, Settings::self()->configuredDavUrls() ) { - KUrl displayUrl = url.url(); - displayUrl.setUser( QString() ); - addModelRow( DavUtils::translatedProtocolName( url.protocol() ), displayUrl.prettyUrl() ); - } + mManager = new KConfigDialogManager(this, Settings::self()); + mManager->updateWidgets(); - mManager = new KConfigDialogManager( this, Settings::self() ); - mManager->updateWidgets(); + connect(mUi.kcfg_displayName, &KLineEdit::textChanged, this, &ConfigDialog::checkUserInput); + connect(mUi.configuredUrls->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(checkConfiguredUrlsButtonsState())); + connect(mUi.configuredUrls, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(onEditButtonClicked())); + + connect(mUi.addButton, &QPushButton::clicked, this, &ConfigDialog::onAddButtonClicked); + connect(mUi.searchButton, &QPushButton::clicked, this, &ConfigDialog::onSearchButtonClicked); + connect(mUi.removeButton, &QPushButton::clicked, this, &ConfigDialog::onRemoveButtonClicked); + connect(mUi.editButton, &QPushButton::clicked, this, &ConfigDialog::onEditButtonClicked); - connect( mUi.kcfg_displayName, SIGNAL(textChanged(QString)), this, SLOT(checkUserInput()) ); - connect( mUi.configuredUrls->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), - this, SLOT(checkConfiguredUrlsButtonsState()) ); + connect(mOkButton, &QPushButton::clicked, this, &ConfigDialog::onOkClicked); - connect( mUi.addButton, SIGNAL(clicked()), this, SLOT(onAddButtonClicked()) ); - connect( mUi.searchButton, SIGNAL(clicked()), this, SLOT(onSearchButtonClicked()) ); - connect( mUi.removeButton, SIGNAL(clicked()), this, SLOT(onRemoveButtonClicked()) ); - connect( mUi.editButton, SIGNAL(clicked()), this, SLOT(onEditButtonClicked()) ); + checkUserInput(); + readConfig(); +} - connect( this, SIGNAL(okClicked()), this, SLOT(onOkClicked()) ); - connect( this, SIGNAL(cancelClicked()), this, SLOT(onCancelClicked()) ); +ConfigDialog::~ConfigDialog() +{ + writeConfig(); +} - checkUserInput(); +void ConfigDialog::readConfig() +{ + KConfigGroup grp(KSharedConfig::openConfig(), "ConfigDialog"); + const QSize size = grp.readEntry("Size", QSize(300, 200)); + if (size.isValid()) { + resize(size); + } } -ConfigDialog::~ConfigDialog() +void ConfigDialog::writeConfig() { + KConfigGroup grp(KSharedConfig::openConfig(), "ConfigDialog"); + grp.writeEntry("Size", size()); + grp.sync(); } -void ConfigDialog::setPassword(const QString& password) +void ConfigDialog::setPassword(const QString &password) { - mUi.password->setText( password ); + mUi.password->setText(password); } void ConfigDialog::checkUserInput() { - checkConfiguredUrlsButtonsState(); + checkConfiguredUrlsButtonsState(); - if ( !mUi.kcfg_displayName->text().isEmpty() && !( mModel->invisibleRootItem()->rowCount() == 0 ) ) - enableButtonOk( true ); - else - enableButtonOk( false ); + if (!mUi.kcfg_displayName->text().trimmed().isEmpty() && !(mModel->invisibleRootItem()->rowCount() == 0)) { + mOkButton->setEnabled(true); + } else { + mOkButton->setEnabled(false); + } } void ConfigDialog::onAddButtonClicked() { - QPointer dlg = new UrlConfigurationDialog( this ); - dlg->setDefaultUsername( mUi.kcfg_defaultUsername->text() ); - dlg->setDefaultPassword( mUi.password->text() ); - const int result = dlg->exec(); - - if ( result == QDialog::Accepted && !dlg.isNull() ) { - if ( Settings::self()->urlConfiguration( DavUtils::Protocol( dlg->protocol() ), dlg->remoteUrl() ) ) { - KMessageBox::error( this, i18n( "Another configuration entry already uses the same URL/protocol couple.\n" - "Please use a different URL" ) ); - } else { - Settings::UrlConfiguration *urlConfig = new Settings::UrlConfiguration(); - - urlConfig->mUrl = dlg->remoteUrl(); - if ( dlg->useDefaultCredentials() ) { - urlConfig->mUser = QLatin1String("$default$"); - } else { - urlConfig->mUser = dlg->username(); - urlConfig->mPassword = dlg->password(); - } - urlConfig->mProtocol = dlg->protocol(); - - Settings::self()->newUrlConfiguration( urlConfig ); - - const QString protocolName = DavUtils::translatedProtocolName( dlg->protocol() ); + QPointer dlg = new UrlConfigurationDialog(this); + dlg->setDefaultUsername(mUi.kcfg_defaultUsername->text()); + dlg->setDefaultPassword(mUi.password->text()); + const int result = dlg->exec(); + + if (result == QDialog::Accepted && !dlg.isNull()) { + if (Settings::self()->urlConfiguration(DavUtils::Protocol(dlg->protocol()), dlg->remoteUrl())) { + KMessageBox::error(this, i18n("Another configuration entry already uses the same URL/protocol couple.\n" + "Please use a different URL")); + } else { + Settings::UrlConfiguration *urlConfig = new Settings::UrlConfiguration(); - addModelRow( protocolName, dlg->remoteUrl() ); - mAddedUrls << QPair( dlg->remoteUrl(), DavUtils::Protocol( dlg->protocol() ) ); - checkUserInput(); + urlConfig->mUrl = dlg->remoteUrl(); + if (dlg->useDefaultCredentials()) { + urlConfig->mUser = QStringLiteral("$default$"); + } else { + urlConfig->mUser = dlg->username(); + urlConfig->mPassword = dlg->password(); + } + urlConfig->mProtocol = dlg->protocol(); + + Settings::self()->newUrlConfiguration(urlConfig); + + const QString protocolName = DavUtils::translatedProtocolName(dlg->protocol()); + + addModelRow(protocolName, dlg->remoteUrl()); + mAddedUrls << QPair(dlg->remoteUrl(), DavUtils::Protocol(dlg->protocol())); + checkUserInput(); + } } - } - delete dlg; + delete dlg; } void ConfigDialog::onSearchButtonClicked() { - QPointer dlg = new SearchDialog( this ); - dlg->setUsername( mUi.kcfg_defaultUsername->text() ); - dlg->setPassword( mUi.password->text() ); - const int result = dlg->exec(); - - if ( result == QDialog::Accepted && !dlg.isNull() ) { - QStringList results = dlg->selection(); - foreach ( const QString &result, results ) { - QStringList split = result.split( QLatin1Char('|') ); - DavUtils::Protocol protocol = DavUtils::protocolByName( split.at( 0 ) ); - if ( !Settings::self()->urlConfiguration( protocol, split.at( 1 ) ) ) { - Settings::UrlConfiguration *urlConfig = new Settings::UrlConfiguration(); - - urlConfig->mUrl = split.at( 1 ); - if ( dlg->useDefaultCredentials() ) { - urlConfig->mUser = QLatin1String("$default$"); - } else { - urlConfig->mUser = dlg->username(); - urlConfig->mPassword = dlg->password(); + QPointer dlg = new SearchDialog(this); + dlg->setUsername(mUi.kcfg_defaultUsername->text()); + dlg->setPassword(mUi.password->text()); + const int result = dlg->exec(); + + if (result == QDialog::Accepted && !dlg.isNull()) { + const QStringList results = dlg->selection(); + foreach (const QString &result, results) { + const QStringList split = result.split(QLatin1Char('|')); + DavUtils::Protocol protocol = DavUtils::protocolByName(split.at(0)); + if (!Settings::self()->urlConfiguration(protocol, split.at(1))) { + Settings::UrlConfiguration *urlConfig = new Settings::UrlConfiguration(); + + urlConfig->mUrl = split.at(1); + if (dlg->useDefaultCredentials()) { + urlConfig->mUser = QStringLiteral("$default$"); + } else { + urlConfig->mUser = dlg->username(); + urlConfig->mPassword = dlg->password(); + } + urlConfig->mProtocol = protocol; + + Settings::self()->newUrlConfiguration(urlConfig); + + addModelRow(DavUtils::translatedProtocolName(protocol), split.at(1)); + mAddedUrls << QPair(split.at(1), protocol); + checkUserInput(); + } } - urlConfig->mProtocol = protocol; - - Settings::self()->newUrlConfiguration( urlConfig ); - - addModelRow( DavUtils::translatedProtocolName( protocol ), split.at( 1 ) ); - mAddedUrls << QPair( split.at( 1 ), protocol ); - checkUserInput(); - } } - } - delete dlg; + delete dlg; } void ConfigDialog::onRemoveButtonClicked() { - const QModelIndexList indexes = mUi.configuredUrls->selectionModel()->selectedRows(); - if ( indexes.size() == 0 ) - return; + const QModelIndexList indexes = mUi.configuredUrls->selectionModel()->selectedRows(); + if (indexes.size() == 0) { + return; + } - QString proto = mModel->index( indexes.at( 0 ).row(), 0 ).data().toString(); - QString url = mModel->index( indexes.at( 0 ).row(), 1 ).data().toString(); + QString proto = mModel->index(indexes.at(0).row(), 0).data().toString(); + QString url = mModel->index(indexes.at(0).row(), 1).data().toString(); - mRemovedUrls << QPair( url, DavUtils::protocolByTranslatedName( proto ) ); - mModel->removeRow( indexes.at( 0 ).row() ); + mRemovedUrls << QPair(url, DavUtils::protocolByTranslatedName(proto)); + mModel->removeRow(indexes.at(0).row()); - checkUserInput(); + checkUserInput(); } void ConfigDialog::onEditButtonClicked() { - const QModelIndexList indexes = mUi.configuredUrls->selectionModel()->selectedRows(); - if ( indexes.size() == 0 ) - return; - - const int row = indexes.at( 0 ).row(); - const QString proto = mModel->index( row, 0 ).data().toString(); - const QString url = mModel->index( row, 1 ).data().toString(); - - Settings::UrlConfiguration *urlConfig = Settings::self()->urlConfiguration( DavUtils::protocolByTranslatedName( proto ), url ); - if ( !urlConfig ) - return; - - QPointer dlg = new UrlConfigurationDialog( this ); - dlg->setRemoteUrl( urlConfig->mUrl ); - dlg->setProtocol( DavUtils::Protocol( urlConfig->mProtocol ) ); - - if ( urlConfig->mUser == QLatin1String( "$default$" ) ) { - dlg->setUseDefaultCredentials( true ); - } else { - dlg->setUseDefaultCredentials( false ); - dlg->setUsername( urlConfig->mUser ); - dlg->setPassword( urlConfig->mPassword ); - } - dlg->setDefaultUsername( mUi.kcfg_defaultUsername->text() ); - dlg->setDefaultPassword( mUi.password->text() ); - - const int result = dlg->exec(); - - if ( result == QDialog::Accepted && !dlg.isNull() ) { - Settings::self()->removeUrlConfiguration( DavUtils::protocolByTranslatedName( proto ), url ); - Settings::UrlConfiguration *urlConfigAccepted = new Settings::UrlConfiguration(); - urlConfigAccepted->mUrl = dlg->remoteUrl(); - if ( dlg->useDefaultCredentials() ) { - urlConfigAccepted->mUser = QLatin1String("$default$"); + const QModelIndexList indexes = mUi.configuredUrls->selectionModel()->selectedRows(); + if (indexes.size() == 0) { + return; + } + + const int row = indexes.at(0).row(); + const QString proto = mModel->index(row, 0).data().toString(); + const QString url = mModel->index(row, 1).data().toString(); + + Settings::UrlConfiguration *urlConfig = Settings::self()->urlConfiguration(DavUtils::protocolByTranslatedName(proto), url); + if (!urlConfig) { + return; + } + + QPointer dlg = new UrlConfigurationDialog(this); + dlg->setRemoteUrl(urlConfig->mUrl); + dlg->setProtocol(DavUtils::Protocol(urlConfig->mProtocol)); + + if (urlConfig->mUser == QLatin1String("$default$")) { + dlg->setUseDefaultCredentials(true); } else { - urlConfigAccepted->mUser = dlg->username(); - urlConfigAccepted->mPassword = dlg->password(); + dlg->setUseDefaultCredentials(false); + dlg->setUsername(urlConfig->mUser); + dlg->setPassword(urlConfig->mPassword); } - urlConfigAccepted->mProtocol = dlg->protocol(); - Settings::self()->newUrlConfiguration( urlConfigAccepted ); + dlg->setDefaultUsername(mUi.kcfg_defaultUsername->text()); + dlg->setDefaultPassword(mUi.password->text()); - mModel->removeRow( row ); - insertModelRow( row, DavUtils::translatedProtocolName( dlg->protocol() ), dlg->remoteUrl() ); - } - delete dlg; + const int result = dlg->exec(); + + if (result == QDialog::Accepted && !dlg.isNull()) { + Settings::self()->removeUrlConfiguration(DavUtils::protocolByTranslatedName(proto), url); + Settings::UrlConfiguration *urlConfigAccepted = new Settings::UrlConfiguration(); + urlConfigAccepted->mUrl = dlg->remoteUrl(); + if (dlg->useDefaultCredentials()) { + urlConfigAccepted->mUser = QStringLiteral("$default$"); + } else { + urlConfigAccepted->mUser = dlg->username(); + urlConfigAccepted->mPassword = dlg->password(); + } + urlConfigAccepted->mProtocol = dlg->protocol(); + Settings::self()->newUrlConfiguration(urlConfigAccepted); + + mModel->removeRow(row); + insertModelRow(row, DavUtils::translatedProtocolName(dlg->protocol()), dlg->remoteUrl()); + } + delete dlg; } void ConfigDialog::onOkClicked() { - typedef QPair UrlPair; - foreach ( const UrlPair &url, mRemovedUrls ) - Settings::self()->removeUrlConfiguration( url.second, url.first ); + typedef QPair UrlPair; + foreach (const UrlPair &url, mRemovedUrls) { + Settings::self()->removeUrlConfiguration(url.second, url.first); + } - mManager->updateSettings(); - Settings::self()->setDefaultPassword( mUi.password->text() ); + mManager->updateSettings(); + Settings::self()->setDefaultPassword(mUi.password->text()); + accept(); } void ConfigDialog::onCancelClicked() { - mRemovedUrls.clear(); + mRemovedUrls.clear(); - typedef QPair UrlPair; - foreach ( const UrlPair &url, mAddedUrls ) - Settings::self()->removeUrlConfiguration( url.second, url.first ); + typedef QPair UrlPair; + foreach (const UrlPair &url, mAddedUrls) { + Settings::self()->removeUrlConfiguration(url.second, url.first); + } + reject(); } void ConfigDialog::checkConfiguredUrlsButtonsState() { - const bool enabled = mUi.configuredUrls->selectionModel()->hasSelection(); + const bool enabled = mUi.configuredUrls->selectionModel()->hasSelection(); - mUi.removeButton->setEnabled( enabled ); - mUi.editButton->setEnabled( enabled ); + mUi.removeButton->setEnabled(enabled); + mUi.editButton->setEnabled(enabled); } -void ConfigDialog::addModelRow( const QString &protocol, const QString &url ) +void ConfigDialog::addModelRow(const QString &protocol, const QString &url) { - insertModelRow( -1, protocol, url ); + insertModelRow(-1, protocol, url); } -void ConfigDialog::insertModelRow( int index, const QString &protocol, const QString &url ) +void ConfigDialog::insertModelRow(int index, const QString &protocol, const QString &url) { - QStandardItem *rootItem = mModel->invisibleRootItem(); - QList items; + QStandardItem *rootItem = mModel->invisibleRootItem(); + QList items; - QStandardItem *protocolStandardItem = new QStandardItem( protocol ); - protocolStandardItem->setEditable( false ); - items << protocolStandardItem; + QStandardItem *protocolStandardItem = new QStandardItem(protocol); + protocolStandardItem->setEditable(false); + items << protocolStandardItem; - QStandardItem *urlStandardItem = new QStandardItem( url ); - urlStandardItem->setEditable( false ); - items << urlStandardItem; + QStandardItem *urlStandardItem = new QStandardItem(url); + urlStandardItem->setEditable(false); + items << urlStandardItem; - if ( index == -1 ) - rootItem->appendRow( items ); - else - rootItem->insertRow( index, items ); + if (index == -1) { + rootItem->appendRow(items); + } else { + rootItem->insertRow(index, items); + } } diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/configdialog.h kdepim-runtime-15.08.0/resources/dav/resource/configdialog.h --- kdepim-runtime-4.14.6/resources/dav/resource/configdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/configdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -23,26 +23,26 @@ #include "davutils.h" -#include +#include #include #include #include - +class QPushButton; class KConfigDialogManager; class QStandardItemModel; -class ConfigDialog : public KDialog +class ConfigDialog : public QDialog { - Q_OBJECT + Q_OBJECT - public: - explicit ConfigDialog( QWidget *parent = 0 ); +public: + explicit ConfigDialog(QWidget *parent = Q_NULLPTR); virtual ~ConfigDialog(); - void setPassword( const QString &password ); + void setPassword(const QString &password); - private Q_SLOTS: +private Q_SLOTS: void checkUserInput(); void onAddButtonClicked(); void onSearchButtonClicked(); @@ -52,15 +52,18 @@ void onOkClicked(); void onCancelClicked(); - private: - void addModelRow( const QString &protocol, const QString &url ); - void insertModelRow( int index, const QString &protocol, const QString &url ); +private: + void readConfig(); + void writeConfig(); + void addModelRow(const QString &protocol, const QString &url); + void insertModelRow(int index, const QString &protocol, const QString &url); Ui::ConfigDialog mUi; KConfigDialogManager *mManager; QList< QPair > mAddedUrls; QList< QPair > mRemovedUrls; QStandardItemModel *mModel; + QPushButton *mOkButton; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/configdialog.ui kdepim-runtime-15.08.0/resources/dav/resource/configdialog.ui --- kdepim-runtime-4.14.6/resources/dav/resource/configdialog.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/configdialog.ui 2015-08-10 21:01:02.000000000 +0000 @@ -49,6 +49,9 @@ + + Never + 5 @@ -172,7 +175,7 @@ - + Add @@ -186,14 +189,14 @@ - + Remove - + Edit @@ -223,11 +226,6 @@ - KPushButton - QPushButton -
kpushbutton.h
-
- KLineEdit QLineEdit
klineedit.h
diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/davfreebusyhandler.cpp kdepim-runtime-15.08.0/resources/dav/resource/davfreebusyhandler.cpp --- kdepim-runtime-4.14.6/resources/dav/resource/davfreebusyhandler.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/davfreebusyhandler.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -25,195 +25,205 @@ #include #include -#include +#include #include #include +#include "davresource_debug.h" -DavFreeBusyHandler::DavFreeBusyHandler( QObject* parent ) - : QObject( parent ), mNextRequestId( 0 ) +DavFreeBusyHandler::DavFreeBusyHandler(QObject *parent) + : QObject(parent), mNextRequestId(0) { } -void DavFreeBusyHandler::canHandleFreeBusy( const QString& email ) +void DavFreeBusyHandler::canHandleFreeBusy(const QString &email) { - DavUtils::DavUrl::List urls = Settings::self()->configuredDavUrls(); - foreach ( const DavUtils::DavUrl &url, urls ) { - if ( url.protocol() == DavUtils::CalDav ) { - ++mRequestsTracker[email].handlingJobCount; - DavPrincipalSearchJob *job = new DavPrincipalSearchJob( url, DavPrincipalSearchJob::EmailAddress, email ); - job->setProperty( "email", QVariant::fromValue( email ) ); - job->setProperty( "url", QVariant::fromValue( url.url().url() ) ); - job->fetchProperty( QLatin1String("schedule-inbox-URL"), QLatin1String("urn:ietf:params:xml:ns:caldav") ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(onPrincipalSearchJobFinished(KJob*)) ); - job->start(); + DavUtils::DavUrl::List urls = Settings::self()->configuredDavUrls(); + foreach (const DavUtils::DavUrl &url, urls) { + if (url.protocol() == DavUtils::CalDav) { + ++mRequestsTracker[email].handlingJobCount; + DavPrincipalSearchJob *job = new DavPrincipalSearchJob(url, DavPrincipalSearchJob::EmailAddress, email); + job->setProperty("email", QVariant::fromValue(email)); + job->setProperty("url", QVariant::fromValue(url.url().url())); + job->fetchProperty(QStringLiteral("schedule-inbox-URL"), QStringLiteral("urn:ietf:params:xml:ns:caldav")); + connect(job, &DavPrincipalSearchJob::result, this, &DavFreeBusyHandler::onPrincipalSearchJobFinished); + job->start(); + } } - } } -void DavFreeBusyHandler::retrieveFreeBusy( const QString& email, const KDateTime& start, const KDateTime& end ) +void DavFreeBusyHandler::retrieveFreeBusy(const QString &email, const KDateTime &start, const KDateTime &end) { - if ( !mPrincipalScheduleOutbox.contains( email ) ) { - emit freeBusyRetrieved( email, QString(), false, - i18n( "No schedule-outbox found for %1", email ) ); - return; - } - - KCalCore::FreeBusy::Ptr fb( new KCalCore::FreeBusy( start, end ) ); - KCalCore::Attendee::Ptr att( new KCalCore::Attendee( QString(), email ) ); - fb->addAttendee( att ); - - KCalCore::ICalFormat formatter; - QByteArray fbData = formatter.createScheduleMessage( fb, KCalCore::iTIPRequest ).toUtf8(); - - foreach ( const QString &outbox, mPrincipalScheduleOutbox[email] ) { - ++mRequestsTracker[email].retrievalJobCount; - uint requestId = mNextRequestId++; - - KUrl url( outbox ); - KIO::StoredTransferJob *job = KIO::storedHttpPost( fbData, url ); - job->addMetaData( QLatin1String("content-type"), QLatin1String("text/calendar") ); - job->setProperty( "email", QVariant::fromValue( email ) ); - job->setProperty( "request-id", QVariant::fromValue( requestId ) ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(onRetrieveFreeBusyJobFinished(KJob*)) ); - job->start(); - } + if (!mPrincipalScheduleOutbox.contains(email)) { + Q_EMIT freeBusyRetrieved(email, QString(), false, + i18n("No schedule-outbox found for %1", email)); + return; + } + + KCalCore::FreeBusy::Ptr fb(new KCalCore::FreeBusy(start, end)); + KCalCore::Attendee::Ptr att(new KCalCore::Attendee(QString(), email)); + fb->addAttendee(att); + + KCalCore::ICalFormat formatter; + QByteArray fbData = formatter.createScheduleMessage(fb, KCalCore::iTIPRequest).toUtf8(); + + foreach (const QString &outbox, mPrincipalScheduleOutbox[email]) { + ++mRequestsTracker[email].retrievalJobCount; + uint requestId = mNextRequestId++; + + KUrl url(outbox); + KIO::StoredTransferJob *job = KIO::storedHttpPost(fbData, url); + job->addMetaData(QStringLiteral("content-type"), QStringLiteral("text/calendar")); + job->setProperty("email", QVariant::fromValue(email)); + job->setProperty("request-id", QVariant::fromValue(requestId)); + connect(job, &DavPrincipalSearchJob::result, this, &DavFreeBusyHandler::onRetrieveFreeBusyJobFinished); + job->start(); + } } -void DavFreeBusyHandler::onPrincipalSearchJobFinished( KJob* job ) +void DavFreeBusyHandler::onPrincipalSearchJobFinished(KJob *job) { - QString email = job->property( "email" ).toString(); - int handlingJobCount = --mRequestsTracker[email].handlingJobCount; + QString email = job->property("email").toString(); + int handlingJobCount = --mRequestsTracker[email].handlingJobCount; - if ( job->error() ) { - if ( handlingJobCount == 0 && !mRequestsTracker[email].handlingJobSuccessful ) - emit handlesFreeBusy( email, false ); - return; - } - - DavPrincipalSearchJob *davJob = qobject_cast( job ); - QList results = davJob->results(); - - if ( results.isEmpty() ) { - if ( handlingJobCount == 0 && !mRequestsTracker[email].handlingJobSuccessful ) - emit handlesFreeBusy( email, false ); - return; - } - - mRequestsTracker[email].handlingJobSuccessful = true; - - foreach ( const DavPrincipalSearchJob::Result &result, results ) { - kDebug() << result.value; - KUrl url( davJob->property( "url" ).toString() ); - if ( result.value.startsWith( QLatin1Char('/') ) ) { - // href is only a path, use request url to complete - url.setEncodedPath( result.value.toLatin1() ); - } else { - // href is a complete url - KUrl tmpUrl( result.value ); - url = tmpUrl; + if (job->error()) { + if (handlingJobCount == 0 && !mRequestsTracker[email].handlingJobSuccessful) { + Q_EMIT handlesFreeBusy(email, false); + } + return; } - if ( !mPrincipalScheduleOutbox[email].contains( url.url() ) ) - mPrincipalScheduleOutbox[email] << url.url(); - } + DavPrincipalSearchJob *davJob = qobject_cast(job); + QList results = davJob->results(); + + if (results.isEmpty()) { + if (handlingJobCount == 0 && !mRequestsTracker[email].handlingJobSuccessful) { + Q_EMIT handlesFreeBusy(email, false); + } + return; + } - if ( handlingJobCount == 0 ) - emit handlesFreeBusy( email, true ); + mRequestsTracker[email].handlingJobSuccessful = true; + + foreach (const DavPrincipalSearchJob::Result &result, results) { + qCDebug(DAVRESOURCE_LOG) << result.value; + KUrl url(davJob->property("url").toString()); + if (result.value.startsWith(QLatin1Char('/'))) { + // href is only a path, use request url to complete + url.setEncodedPath(result.value.toLatin1()); + } else { + // href is a complete url + KUrl tmpUrl(result.value); + url = tmpUrl; + } + + if (!mPrincipalScheduleOutbox[email].contains(url.url())) { + mPrincipalScheduleOutbox[email] << url.url(); + } + } + + if (handlingJobCount == 0) { + Q_EMIT handlesFreeBusy(email, true); + } } -void DavFreeBusyHandler::onRetrieveFreeBusyJobFinished( KJob* job ) +void DavFreeBusyHandler::onRetrieveFreeBusyJobFinished(KJob *job) { - QString email = job->property( "email" ).toString(); - uint requestId = job->property( "request-id" ).toUInt(); - int retrievalJobCount = --mRequestsTracker[email].retrievalJobCount; - - if ( job->error() ) { - if ( retrievalJobCount == 0 && !mRequestsTracker[email].retrievalJobSuccessful ) - emit( freeBusyRetrieved( email, QString(), false, job->errorString() ) ); - return; - } - - /* - * Extract info from a document like the following: - * - * - * - * - * mailto:wilfredo@example.com - * - * 2.0;Success - * BEGIN:VCALENDAR - * VERSION:2.0 - * PRODID:-//Example Corp.//CalDAV Server//EN - * METHOD:REPLY - * BEGIN:VFREEBUSY - * UID:4FD3AD926350 - * DTSTAMP:20090602T200733Z - * DTSTART:20090602T000000Z - * DTEND:20090604T000000Z - * ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com - * ATTENDEE;CN="Wilfredo Sanchez Vega":mailto:wilfredo@example.com - * FREEBUSY;FBTYPE=BUSY:20090602T110000Z/20090602T120000Z - * FREEBUSY;FBTYPE=BUSY:20090603T170000Z/20090603T180000Z - * END:VFREEBUSY - * END:VCALENDAR - * - * - * - * - * mailto:mike@example.org - * - * 3.7;Invalid calendar user - * - * - */ - - KIO::StoredTransferJob *postJob = qobject_cast( job ); - QDomDocument response; - response.setContent( postJob->data(), true ); - - QDomElement scheduleResponse = response.documentElement(); - - // We are only expecting one response tag - QDomElement responseElement = DavUtils::firstChildElementNS( scheduleResponse, QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("response") ); - if ( responseElement.isNull() ) { - if ( retrievalJobCount == 0 && !mRequestsTracker[email].retrievalJobSuccessful ) - emit( freeBusyRetrieved( email, QString(), false, i18n( "Invalid response from the server" ) ) ); - return; - } - - // We can load directly the calendar-data and use its content to create - // an incidence base that will give us everything we need to test - // the success - QDomElement calendarDataElement = DavUtils::firstChildElementNS( responseElement, QLatin1String("urn:ietf:params:xml:ns:caldav"), QLatin1String("calendar-data") ); - if ( calendarDataElement.isNull() ) { - if ( retrievalJobCount == 0 && !mRequestsTracker[email].retrievalJobSuccessful ) - emit( freeBusyRetrieved( email, QString(), false, i18n( "Invalid response from the server" ) ) ); - return; - } - - QString rawData = calendarDataElement.text(); - - KCalCore::ICalFormat format; - KCalCore::FreeBusy::Ptr fb = format.parseFreeBusy( rawData ); - if ( fb.isNull() ) { - if ( retrievalJobCount == 0 && !mRequestsTracker[email].retrievalJobSuccessful ) - emit( freeBusyRetrieved( email, QString(), false, i18n( "Unable to parse free-busy data received" ) ) ); - return; - } + QString email = job->property("email").toString(); + uint requestId = job->property("request-id").toUInt(); + int retrievalJobCount = --mRequestsTracker[email].retrievalJobCount; + + if (job->error()) { + if (retrievalJobCount == 0 && !mRequestsTracker[email].retrievalJobSuccessful) { + emit(freeBusyRetrieved(email, QString(), false, job->errorString())); + } + return; + } - // We're safe now - mRequestsTracker[email].retrievalJobSuccessful = true; + /* + * Extract info from a document like the following: + * + * + * + * + * mailto:wilfredo@example.com + * + * 2.0;Success + * BEGIN:VCALENDAR + * VERSION:2.0 + * PRODID:-//Example Corp.//CalDAV Server//EN + * METHOD:REPLY + * BEGIN:VFREEBUSY + * UID:4FD3AD926350 + * DTSTAMP:20090602T200733Z + * DTSTART:20090602T000000Z + * DTEND:20090604T000000Z + * ORGANIZER;CN="Cyrus Daboo":mailto:cyrus@example.com + * ATTENDEE;CN="Wilfredo Sanchez Vega":mailto:wilfredo@example.com + * FREEBUSY;FBTYPE=BUSY:20090602T110000Z/20090602T120000Z + * FREEBUSY;FBTYPE=BUSY:20090603T170000Z/20090603T180000Z + * END:VFREEBUSY + * END:VCALENDAR + * + * + * + * + * mailto:mike@example.org + * + * 3.7;Invalid calendar user + * + * + */ + + KIO::StoredTransferJob *postJob = qobject_cast(job); + QDomDocument response; + response.setContent(postJob->data(), true); + + QDomElement scheduleResponse = response.documentElement(); + + // We are only expecting one response tag + QDomElement responseElement = DavUtils::firstChildElementNS(scheduleResponse, QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("response")); + if (responseElement.isNull()) { + if (retrievalJobCount == 0 && !mRequestsTracker[email].retrievalJobSuccessful) { + emit(freeBusyRetrieved(email, QString(), false, i18n("Invalid response from the server"))); + } + return; + } + + // We can load directly the calendar-data and use its content to create + // an incidence base that will give us everything we need to test + // the success + QDomElement calendarDataElement = DavUtils::firstChildElementNS(responseElement, QStringLiteral("urn:ietf:params:xml:ns:caldav"), QStringLiteral("calendar-data")); + if (calendarDataElement.isNull()) { + if (retrievalJobCount == 0 && !mRequestsTracker[email].retrievalJobSuccessful) { + emit(freeBusyRetrieved(email, QString(), false, i18n("Invalid response from the server"))); + } + return; + } + + QString rawData = calendarDataElement.text(); + + KCalCore::ICalFormat format; + KCalCore::FreeBusy::Ptr fb = format.parseFreeBusy(rawData); + if (fb.isNull()) { + if (retrievalJobCount == 0 && !mRequestsTracker[email].retrievalJobSuccessful) { + emit(freeBusyRetrieved(email, QString(), false, i18n("Unable to parse free-busy data received"))); + } + return; + } + + // We're safe now + mRequestsTracker[email].retrievalJobSuccessful = true; // fb->clearAttendees(); - if ( mRequestsTracker[email].resultingFreeBusy[requestId].isNull() ) - mRequestsTracker[email].resultingFreeBusy[requestId] = fb; - else - mRequestsTracker[email].resultingFreeBusy[requestId]->merge( fb ); - - if ( retrievalJobCount == 0 ) { - QString fbStr = format.createScheduleMessage( mRequestsTracker[email].resultingFreeBusy[requestId], - KCalCore::iTIPRequest ); - emit freeBusyRetrieved( email, fbStr, true, QString() ); - } + if (mRequestsTracker[email].resultingFreeBusy[requestId].isNull()) { + mRequestsTracker[email].resultingFreeBusy[requestId] = fb; + } else { + mRequestsTracker[email].resultingFreeBusy[requestId]->merge(fb); + } + + if (retrievalJobCount == 0) { + QString fbStr = format.createScheduleMessage(mRequestsTracker[email].resultingFreeBusy[requestId], + KCalCore::iTIPRequest); + Q_EMIT freeBusyRetrieved(email, fbStr, true, QString()); + } } diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/davfreebusyhandler.h kdepim-runtime-15.08.0/resources/dav/resource/davfreebusyhandler.h --- kdepim-runtime-4.14.6/resources/dav/resource/davfreebusyhandler.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/davfreebusyhandler.h 2015-08-10 21:01:02.000000000 +0000 @@ -33,20 +33,20 @@ */ class DavFreeBusyHandler : public QObject { - Q_OBJECT + Q_OBJECT - public: +public: /** * Constructs a new DavFreeBusyHandler */ - explicit DavFreeBusyHandler( QObject *parent = 0 ); + explicit DavFreeBusyHandler(QObject *parent = Q_NULLPTR); /** * Checks if the free-busy info for @p email can be handled * * @param email The email address of the contact. */ - void canHandleFreeBusy( const QString &email ); + void canHandleFreeBusy(const QString &email); /** * Retrieve the free-busy info for @p email between @p start and @p end @@ -55,40 +55,40 @@ * @param start The start of the free-busy period to report * @param end The end of the free-busy period to report */ - void retrieveFreeBusy( const QString &email, const KDateTime &start, const KDateTime &end ); + void retrieveFreeBusy(const QString &email, const KDateTime &start, const KDateTime &end); - signals: +Q_SIGNALS: /** * Emitted once we know if the free-busy info for @p email * can be handled or not. */ - void handlesFreeBusy( const QString &email, bool handles ); + void handlesFreeBusy(const QString &email, bool handles); /** * Emitted once the free-busy has been retrieved */ - void freeBusyRetrieved( const QString &email, const QString &freeBusy, bool success, const QString &errorText ); + void freeBusyRetrieved(const QString &email, const QString &freeBusy, bool success, const QString &errorText); - private slots: - void onPrincipalSearchJobFinished( KJob *job ); - void onRetrieveFreeBusyJobFinished( KJob *job ); +private Q_SLOTS: + void onPrincipalSearchJobFinished(KJob *job); + void onRetrieveFreeBusyJobFinished(KJob *job); - private: +private: /** * Simple struct to track the state of requests */ struct RequestTracker { - RequestTracker() - : handlingJobCount( 0 ), handlingJobSuccessful( false ), - retrievalJobCount( 0 ), retrievalJobSuccessful( false ) - { - } - - int handlingJobCount; - bool handlingJobSuccessful; - int retrievalJobCount; - bool retrievalJobSuccessful; - QMap resultingFreeBusy; + RequestTracker() + : handlingJobCount(0), handlingJobSuccessful(false), + retrievalJobCount(0), retrievalJobSuccessful(false) + { + } + + int handlingJobCount; + bool handlingJobSuccessful; + int retrievalJobCount; + bool retrievalJobSuccessful; + QMap resultingFreeBusy; }; QMap mRequestsTracker; diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/davgroupwareprovider.desktop kdepim-runtime-15.08.0/resources/dav/resource/davgroupwareprovider.desktop --- kdepim-runtime-4.14.6/resources/dav/resource/davgroupwareprovider.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/davgroupwareprovider.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -9,7 +9,7 @@ Name[de]=DAV-Groupware-Ressource-Anbieter Name[el]=Πάροχος πόρου DAV groupware Name[en_GB]=DAV Groupware resource provider -Name[es]=Proveedor de recurso de trabajo en grupo DAV +Name[es]=Proveedor de recurso de colaboración DAV Name[et]=DAV grupitöö ressursi pakkuja Name[fi]=DAV-työryhmäresurssitarjoaja Name[fr]=Fournisseur de ressources pour logiciels de collaboration DAV @@ -66,3 +66,7 @@ [PropertyDef::X-DavGroupware-GroupDavPath] Type=QString + +[PropertyDef::X-DavGroupware-Provider] +Type=QString + diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/davgroupwareresource.cpp kdepim-runtime-15.08.0/resources/dav/resource/davgroupwareresource.cpp --- kdepim-runtime-4.14.6/resources/dav/resource/davgroupwareresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/davgroupwareresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -36,28 +36,29 @@ #include "settingsadaptor.h" #include "setupwizard.h" -#include -#include -#include +#include +#include +#include #include -#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include "davresource_debug.h" #include #include @@ -66,486 +67,497 @@ typedef QSharedPointer IncidencePtr; -DavGroupwareResource::DavGroupwareResource( const QString &id ) - : ResourceBase( id ), FreeBusyProviderBase(), mSyncErrorNotified( false ) +DavGroupwareResource::DavGroupwareResource(const QString &id) + : ResourceBase(id), FreeBusyProviderBase(), mSyncErrorNotified(false) { - AttributeFactory::registerAttribute(); - AttributeFactory::registerAttribute(); + AttributeFactory::registerAttribute(); + AttributeFactory::registerAttribute(); + + setNeedsNetwork(true); + + mDavCollectionRoot.setParentCollection(Collection::root()); + mDavCollectionRoot.setName(identifier()); + mDavCollectionRoot.setRemoteId(identifier()); + mDavCollectionRoot.setContentMimeTypes(QStringList() << Collection::mimeType()); + mDavCollectionRoot.setRights(Collection::CanCreateCollection | Collection::CanDeleteCollection | Collection::CanChangeCollection); - setNeedsNetwork( true ); + EntityDisplayAttribute *attribute = mDavCollectionRoot.attribute(Collection::AddIfMissing); + attribute->setIconName(QStringLiteral("folder-remote")); + + int refreshInterval = Settings::self()->refreshInterval(); + if (refreshInterval == 0) { + refreshInterval = -1; + } - mDavCollectionRoot.setParentCollection( Collection::root() ); - mDavCollectionRoot.setName( identifier() ); - mDavCollectionRoot.setRemoteId( identifier() ); - mDavCollectionRoot.setContentMimeTypes( QStringList() << Collection::mimeType() ); - mDavCollectionRoot.setRights( Collection::CanCreateCollection | Collection::CanDeleteCollection | Collection::CanChangeCollection ); - - EntityDisplayAttribute *attribute = mDavCollectionRoot.attribute( Collection::AddIfMissing ); - attribute->setIconName( QLatin1String( "folder-remote" ) ); - - int refreshInterval = Settings::self()->refreshInterval(); - if ( refreshInterval == 0 ) - refreshInterval = -1; - - Akonadi::CachePolicy cachePolicy; - cachePolicy.setInheritFromParent( false ); - cachePolicy.setSyncOnDemand( false ); - cachePolicy.setCacheTimeout( -1 ); - cachePolicy.setIntervalCheckTime( refreshInterval ); - cachePolicy.setLocalParts( QStringList() << QLatin1String( "ALL" ) ); - mDavCollectionRoot.setCachePolicy( cachePolicy ); - - changeRecorder()->fetchCollection( true ); - changeRecorder()->collectionFetchScope().setAncestorRetrieval( Akonadi::CollectionFetchScope::All ); - changeRecorder()->itemFetchScope().fetchFullPayload( true ); - changeRecorder()->itemFetchScope().setAncestorRetrieval( ItemFetchScope::All ); - - Settings::self()->setWinId( winIdForDialogs() ); - Settings::self()->setResourceIdentifier( identifier() ); - - mFreeBusyHandler = new DavFreeBusyHandler( this ); - connect( mFreeBusyHandler, SIGNAL(handlesFreeBusy(QString,bool)), this, SLOT(onHandlesFreeBusy(QString,bool)) ); - connect( mFreeBusyHandler, SIGNAL(freeBusyRetrieved(QString,QString,bool,QString)), this, SLOT(onFreeBusyRetrieved(QString,QString,bool,QString)) ); + Akonadi::CachePolicy cachePolicy; + cachePolicy.setInheritFromParent(false); + cachePolicy.setSyncOnDemand(false); + cachePolicy.setCacheTimeout(-1); + cachePolicy.setIntervalCheckTime(refreshInterval); + cachePolicy.setLocalParts(QStringList() << QStringLiteral("ALL")); + mDavCollectionRoot.setCachePolicy(cachePolicy); - connect(this, SIGNAL(reloadConfiguration()), this, SLOT(onReloadConfig())); + changeRecorder()->fetchCollection(true); + changeRecorder()->collectionFetchScope().setAncestorRetrieval(Akonadi::CollectionFetchScope::All); + changeRecorder()->itemFetchScope().fetchFullPayload(true); + changeRecorder()->itemFetchScope().setAncestorRetrieval(ItemFetchScope::All); - scheduleCustomTask( this, "createInitialCache", QVariant(), ResourceBase::AfterChangeReplay ); + Settings::self()->setWinId(winIdForDialogs()); + Settings::self()->setResourceIdentifier(identifier()); + + mFreeBusyHandler = new DavFreeBusyHandler(this); + connect(mFreeBusyHandler, &DavFreeBusyHandler::handlesFreeBusy, this, &DavGroupwareResource::onHandlesFreeBusy); + connect(mFreeBusyHandler, &DavFreeBusyHandler::freeBusyRetrieved, this, &DavGroupwareResource::onFreeBusyRetrieved); + + connect(this, &DavGroupwareResource::reloadConfiguration, this, &DavGroupwareResource::onReloadConfig); + + scheduleCustomTask(this, "createInitialCache", QVariant(), ResourceBase::AfterChangeReplay); } DavGroupwareResource::~DavGroupwareResource() { - delete mFreeBusyHandler; + delete mFreeBusyHandler; } -void DavGroupwareResource::collectionRemoved( const Akonadi::Collection &collection ) +void DavGroupwareResource::collectionRemoved(const Akonadi::Collection &collection) { - kDebug() << "Removing collection " << collection.remoteId(); + qCDebug(DAVRESOURCE_LOG) << "Removing collection " << collection.remoteId(); - if ( !configurationIsValid() ) { - return; - } + if (!configurationIsValid()) { + return; + } - const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl( collection.remoteId() ); + const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl(collection.remoteId()); - DavCollectionDeleteJob *job = new DavCollectionDeleteJob( davUrl ); - job->setProperty( "collection", QVariant::fromValue( collection ) ); - connect( job, SIGNAL(result(KJob*)), SLOT(onCollectionRemovedFinished(KJob*)) ); - job->start(); + DavCollectionDeleteJob *job = new DavCollectionDeleteJob(davUrl); + job->setProperty("collection", QVariant::fromValue(collection)); + connect(job, &DavCollectionDeleteJob::result, this, &DavGroupwareResource::onCollectionRemovedFinished); + job->start(); } void DavGroupwareResource::cleanup() { - Settings::self()->cleanup(); - Akonadi::AgentBase::cleanup(); + Settings::self()->cleanup(); + Akonadi::AgentBase::cleanup(); } KDateTime DavGroupwareResource::lastCacheUpdate() const { - return KDateTime::currentLocalDateTime(); + return KDateTime::currentLocalDateTime(); } -void DavGroupwareResource::canHandleFreeBusy( const QString& email ) const +void DavGroupwareResource::canHandleFreeBusy(const QString &email) const { - if ( !isOnline() ) - handlesFreeBusy( email, false ); - else - mFreeBusyHandler->canHandleFreeBusy( email ); + if (!isOnline()) { + handlesFreeBusy(email, false); + } else { + mFreeBusyHandler->canHandleFreeBusy(email); + } } -void DavGroupwareResource::onHandlesFreeBusy( const QString &email, bool handles ) +void DavGroupwareResource::onHandlesFreeBusy(const QString &email, bool handles) { - handlesFreeBusy( email, handles ); + handlesFreeBusy(email, handles); } -void DavGroupwareResource::retrieveFreeBusy( const QString& email, const KDateTime& start, const KDateTime& end ) +void DavGroupwareResource::retrieveFreeBusy(const QString &email, const KDateTime &start, const KDateTime &end) { - if ( !isOnline() ) - freeBusyRetrieved( email, QString(), false, i18n( "Unable to retrieve free-busy info while offline" ) ); - else - mFreeBusyHandler->retrieveFreeBusy( email, start, end ); + if (!isOnline()) { + freeBusyRetrieved(email, QString(), false, i18n("Unable to retrieve free-busy info while offline")); + } else { + mFreeBusyHandler->retrieveFreeBusy(email, start, end); + } } -void DavGroupwareResource::onFreeBusyRetrieved( const QString& email, const QString& freeBusy, bool success, const QString &errorText ) +void DavGroupwareResource::onFreeBusyRetrieved(const QString &email, const QString &freeBusy, bool success, const QString &errorText) { - freeBusyRetrieved( email, freeBusy, success, errorText ); + freeBusyRetrieved(email, freeBusy, success, errorText); } -void DavGroupwareResource::configure( WId windowId ) +void DavGroupwareResource::configure(WId windowId) { - Settings::self()->setWinId( windowId ); + Settings::self()->setWinId(windowId); - // On the initial configuration we start the setup wizard - if ( Settings::self()->configuredDavUrls().isEmpty() ) { - SetupWizard wizard; + // On the initial configuration we start the setup wizard + if (Settings::self()->configuredDavUrls().isEmpty()) { + SetupWizard wizard; - if ( windowId ) - KWindowSystem::setMainWindow( &wizard, windowId ); + if (windowId) { + KWindowSystem::setMainWindow(&wizard, windowId); + } - const int result = wizard.exec(); - if ( result == QDialog::Accepted ) { - const SetupWizard::Url::List urls = wizard.urls(); - foreach ( const SetupWizard::Url &url, urls ) { - Settings::UrlConfiguration *urlConfig = new Settings::UrlConfiguration(); + const int result = wizard.exec(); + if (result == QDialog::Accepted) { + const SetupWizard::Url::List urls = wizard.urls(); + foreach (const SetupWizard::Url &url, urls) { + Settings::UrlConfiguration *urlConfig = new Settings::UrlConfiguration(); - urlConfig->mUrl = url.url; - urlConfig->mProtocol = url.protocol; - urlConfig->mUser = url.userName; - urlConfig->mPassword = wizard.field( QLatin1String("credentialsPassword") ).toString(); + urlConfig->mUrl = url.url; + urlConfig->mProtocol = url.protocol; + urlConfig->mUser = url.userName; + urlConfig->mPassword = wizard.field(QStringLiteral("credentialsPassword")).toString(); - Settings::self()->newUrlConfiguration( urlConfig ); - } + Settings::self()->newUrlConfiguration(urlConfig); + } - if ( !urls.isEmpty() ) - Settings::self()->setDisplayName( wizard.displayName() ); + if (!urls.isEmpty()) { + Settings::self()->setDisplayName(wizard.displayName()); + } - QString defaultUser = wizard.field( QLatin1String("credentialsUserName") ).toString(); - if ( !defaultUser.isEmpty() ) { - Settings::self()->setDefaultUsername( defaultUser ); - Settings::self()->setDefaultPassword( wizard.field( QLatin1String("credentialsPassword") ).toString() ); - } + QString defaultUser = wizard.field(QStringLiteral("credentialsUserName")).toString(); + if (!defaultUser.isEmpty()) { + Settings::self()->setDefaultUsername(defaultUser); + Settings::self()->setDefaultPassword(wizard.field(QStringLiteral("credentialsPassword")).toString()); + } + } } - } - // continue with the normal config dialog - ConfigDialog dialog; + // continue with the normal config dialog + ConfigDialog dialog; - if ( windowId ) - KWindowSystem::setMainWindow( &dialog, windowId ); + if (windowId) { + KWindowSystem::setMainWindow(&dialog, windowId); + } - if ( !Settings::self()->defaultUsername().isEmpty() ) - dialog.setPassword( Settings::self()->defaultPassword() ); + if (!Settings::self()->defaultUsername().isEmpty()) { + dialog.setPassword(Settings::self()->defaultPassword()); + } - const int result = dialog.exec(); + const int result = dialog.exec(); - if ( result == QDialog::Accepted ) { - Settings::self()->setSettingsVersion( 3 ); - Settings::self()->writeConfig(); - synchronize(); - emit configurationDialogAccepted(); - } else { - emit configurationDialogRejected(); - } + if (result == QDialog::Accepted) { + Settings::self()->setSettingsVersion(3); + Settings::self()->save(); + synchronize(); + Q_EMIT configurationDialogAccepted(); + } else { + Q_EMIT configurationDialogRejected(); + } } void DavGroupwareResource::retrieveCollections() { - kDebug() << "Retrieving collections list"; - mSyncErrorNotified = false; + qCDebug(DAVRESOURCE_LOG) << "Retrieving collections list"; + mSyncErrorNotified = false; - if ( !configurationIsValid() ) { - return; - } + if (!configurationIsValid()) { + return; + } - emit status( Running, i18n( "Fetching collections" ) ); + Q_EMIT status(Running, i18n("Fetching collections")); - DavCollectionsMultiFetchJob *job = new DavCollectionsMultiFetchJob( Settings::self()->configuredDavUrls() ); - connect( job, SIGNAL(result(KJob*)), SLOT(onRetrieveCollectionsFinished(KJob*)) ); - connect( job, SIGNAL(collectionDiscovered(int,QString,QString)), - SLOT(onCollectionDiscovered(int,QString,QString)) ); - job->start(); + DavCollectionsMultiFetchJob *job = new DavCollectionsMultiFetchJob(Settings::self()->configuredDavUrls()); + connect(job, &DavCollectionDeleteJob::result, this, &DavGroupwareResource::onRetrieveCollectionsFinished); + connect(job, &DavCollectionsMultiFetchJob::collectionDiscovered, this, &DavGroupwareResource::onCollectionDiscovered); + job->start(); } -void DavGroupwareResource::retrieveItems( const Akonadi::Collection &collection ) +void DavGroupwareResource::retrieveItems(const Akonadi::Collection &collection) { - kDebug() << "Retrieving items for collection " << collection.remoteId(); + qCDebug(DAVRESOURCE_LOG) << "Retrieving items for collection " << collection.remoteId(); - if ( !configurationIsValid() ) { - return; - } + if (!configurationIsValid()) { + return; + } - // As the resource root collection contains mime types for items we must - // work around the fact that Akonadi will rightfully try to retrieve items - // from it. So just return an empty list - if ( collection.remoteId() == identifier() ) { - itemsRetrievalDone(); - return; - } + // As the resource root collection contains mime types for items we must + // work around the fact that Akonadi will rightfully try to retrieve items + // from it. So just return an empty list + if (collection.remoteId() == identifier()) { + itemsRetrievalDone(); + return; + } - const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl( collection.remoteId() ); + const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl(collection.remoteId()); - if ( !davUrl.url().isValid() ) { - kError() << "Can't find a configured URL, collection.remoteId() is " << collection.remoteId(); - cancelTask( i18n( "Asked to retrieve items for an unknown collection: %1", collection.remoteId() ) ); - //Q_ASSERT_X( false, "DavGroupwareResource::retrieveItems", "Url is invalid" ); - return; - } + if (!davUrl.url().isValid()) { + qCCritical(DAVRESOURCE_LOG) << "Can't find a configured URL, collection.remoteId() is " << collection.remoteId(); + cancelTask(i18n("Asked to retrieve items for an unknown collection: %1", collection.remoteId())); + //Q_ASSERT_X( false, "DavGroupwareResource::retrieveItems", "Url is invalid" ); + return; + } - DavItemsListJob *job = new DavItemsListJob( davUrl ); - job->setProperty( "collection", QVariant::fromValue( collection ) ); - job->setContentMimeTypes( collection.contentMimeTypes() ); - connect( job, SIGNAL(result(KJob*)), SLOT(onRetrieveItemsFinished(KJob*)) ); - job->start(); + DavItemsListJob *job = new DavItemsListJob(davUrl); + job->setProperty("collection", QVariant::fromValue(collection)); + job->setContentMimeTypes(collection.contentMimeTypes()); + connect(job, &DavCollectionDeleteJob::result, this, &DavGroupwareResource::onRetrieveItemsFinished); + job->start(); } -bool DavGroupwareResource::retrieveItem( const Akonadi::Item &item, const QSet& ) +bool DavGroupwareResource::retrieveItem(const Akonadi::Item &item, const QSet &) { - kDebug() << "Retrieving single item. Remote id = " << item.remoteId(); + qCDebug(DAVRESOURCE_LOG) << "Retrieving single item. Remote id = " << item.remoteId(); - if ( !configurationIsValid() ) { - return false; - } + if (!configurationIsValid()) { + return false; + } - const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl( item.parentCollection().remoteId(), item.remoteId() ); - if ( !davUrl.url().isValid() ) { - cancelTask(); - return false; - } + const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl(item.parentCollection().remoteId(), item.remoteId()); + if (!davUrl.url().isValid()) { + cancelTask(); + return false; + } - DavItem davItem; - davItem.setUrl( item.remoteId() ); - davItem.setContentType( QLatin1String("text/calendar") ); - davItem.setEtag( item.remoteRevision() ); + DavItem davItem; + davItem.setUrl(item.remoteId()); + davItem.setContentType(QStringLiteral("text/calendar")); + davItem.setEtag(item.remoteRevision()); - DavItemFetchJob *job = new DavItemFetchJob( davUrl, davItem ); - job->setProperty( "item", QVariant::fromValue( item ) ); - connect( job, SIGNAL(result(KJob*)), SLOT(onRetrieveItemFinished(KJob*)) ); - job->start(); + DavItemFetchJob *job = new DavItemFetchJob(davUrl, davItem); + job->setProperty("item", QVariant::fromValue(item)); + connect(job, &DavCollectionDeleteJob::result, this, &DavGroupwareResource::onRetrieveItemFinished); + job->start(); - return true; + return true; } -void DavGroupwareResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ) +void DavGroupwareResource::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) { - kDebug() << "Received notification for added item. Local id = " - << item.id() << ". Remote id = " << item.remoteId() - << ". Collection remote id = " << collection.remoteId(); + qCDebug(DAVRESOURCE_LOG) << "Received notification for added item. Local id = " + << item.id() << ". Remote id = " << item.remoteId() + << ". Collection remote id = " << collection.remoteId(); - if ( !configurationIsValid() ) { - return; - } + if (!configurationIsValid()) { + return; + } - if ( collection.remoteId().isEmpty() ) { - kError() << "Invalid remote id for collection " << collection.id() << " = " << collection.remoteId(); - cancelTask( i18n( "Invalid collection for item %1.", item.id() ) ); - return; - } + if (collection.remoteId().isEmpty()) { + qCCritical(DAVRESOURCE_LOG) << "Invalid remote id for collection " << collection.id() << " = " << collection.remoteId(); + cancelTask(i18n("Invalid collection for item %1.", item.id())); + return; + } - DavItem davItem = DavUtils::createDavItem( item, collection ); - if ( davItem.data().isEmpty() ) { - kError() << "Item " << item.id() << " doesn't has a valid payload"; - cancelTask(); - return; - } + DavItem davItem = DavUtils::createDavItem(item, collection); + if (davItem.data().isEmpty()) { + qCCritical(DAVRESOURCE_LOG) << "Item " << item.id() << " doesn't has a valid payload"; + cancelTask(); + return; + } - QString urlStr = davItem.url(); - const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl( collection.remoteId(), urlStr ); - kDebug() << "Item " << item.id() << " will be put to " << urlStr; + QString urlStr = davItem.url(); + const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl(collection.remoteId(), urlStr); + qCDebug(DAVRESOURCE_LOG) << "Item " << item.id() << " will be put to " << urlStr; - DavItemCreateJob *job = new DavItemCreateJob( davUrl, davItem ); - job->setProperty( "collection", QVariant::fromValue( collection ) ); - job->setProperty( "item", QVariant::fromValue( item ) ); - connect( job, SIGNAL(result(KJob*)), SLOT(onItemAddedFinished(KJob*)) ); - job->start(); + DavItemCreateJob *job = new DavItemCreateJob(davUrl, davItem); + job->setProperty("collection", QVariant::fromValue(collection)); + job->setProperty("item", QVariant::fromValue(item)); + connect(job, &DavCollectionDeleteJob::result, this, &DavGroupwareResource::onItemAddedFinished); + job->start(); } -void DavGroupwareResource::itemChanged( const Akonadi::Item &item, const QSet& ) +void DavGroupwareResource::itemChanged(const Akonadi::Item &item, const QSet &) { - kDebug() << "Received notification for changed item. Local id = " << item.id() - << ". Remote id = " << item.remoteId(); + qCDebug(DAVRESOURCE_LOG) << "Received notification for changed item. Local id = " << item.id() + << ". Remote id = " << item.remoteId(); - if ( !configurationIsValid() ) { - return; - } - - QString ridBase = item.remoteId(); - if ( ridBase.contains( QChar( '#' ) ) ) - ridBase.truncate( ridBase.indexOf( QChar( '#' ) ) ); + if (!configurationIsValid()) { + return; + } - Akonadi::Item::List extraItems; - foreach ( const QString &rid, mEtagCache.etags() ) { - if ( rid.startsWith( ridBase ) && rid != item.remoteId() ) { - Akonadi::Item extraItem; - extraItem.setRemoteId( rid ); - extraItems << extraItem; + QString ridBase = item.remoteId(); + if (ridBase.contains(QChar('#'))) { + ridBase.truncate(ridBase.indexOf(QChar('#'))); } - } - if ( extraItems.isEmpty() ) { - doItemChange( item ); - } - else { - Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( extraItems ); - job->setCollection( item.parentCollection() ); - job->fetchScope().fetchFullPayload(); - job->setProperty( "item", QVariant::fromValue( item ) ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(onItemChangePrepared(KJob*)) ); - } -} + Akonadi::Item::List extraItems; + foreach (const QString &rid, mEtagCache.etags()) { + if (rid.startsWith(ridBase) && rid != item.remoteId()) { + Akonadi::Item extraItem; + extraItem.setRemoteId(rid); + extraItems << extraItem; + } + } -void DavGroupwareResource::onItemChangePrepared( KJob *job ) -{ - Akonadi::ItemFetchJob *fetchJob = qobject_cast( job ); - Akonadi::Item item = job->property( "item" ).value(); - doItemChange( item, fetchJob->items() ); + if (extraItems.isEmpty()) { + doItemChange(item); + } else { + Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob(extraItems); + job->setCollection(item.parentCollection()); + job->fetchScope().fetchFullPayload(); + job->setProperty("item", QVariant::fromValue(item)); + connect(job, &DavCollectionDeleteJob::result, this, &DavGroupwareResource::onItemChangePrepared); + } } -void DavGroupwareResource::doItemChange( const Akonadi::Item &item, const Akonadi::Item::List &dependentItems ) +void DavGroupwareResource::onItemChangePrepared(KJob *job) { - DavItem davItem = DavUtils::createDavItem( item, item.parentCollection(), dependentItems ); - if ( davItem.data().isEmpty() ) { - cancelTask(); - return; - } - - QString url = item.remoteId(); - if ( url.contains( QChar( '#' ) ) ) - url.truncate( url.indexOf( QChar( '#' ) ) ); - const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl( item.parentCollection().remoteId(), url ); - - // We have to re-set the URL as it's not necessarily valid after createDavItem() - davItem.setUrl( url ); - davItem.setEtag( item.remoteRevision() ); - - DavItemModifyJob *modJob = new DavItemModifyJob( davUrl, davItem ); - modJob->setProperty( "item", QVariant::fromValue( item ) ); - modJob->setProperty( "dependentItems", QVariant::fromValue( dependentItems ) ); - connect( modJob, SIGNAL(result(KJob*)), SLOT(onItemChangedFinished(KJob*)) ); - modJob->start(); + Akonadi::ItemFetchJob *fetchJob = qobject_cast(job); + Akonadi::Item item = job->property("item").value(); + doItemChange(item, fetchJob->items()); } -void DavGroupwareResource::itemRemoved( const Akonadi::Item &item ) +void DavGroupwareResource::doItemChange(const Akonadi::Item &item, const Akonadi::Item::List &dependentItems) { - if ( !configurationIsValid() ) { - return; - } + DavItem davItem = DavUtils::createDavItem(item, item.parentCollection(), dependentItems); + if (davItem.data().isEmpty()) { + qCCritical(DAVRESOURCE_LOG) << "Item " << item.id() << " doesn't has a valid payload"; + cancelTask(); + return; + } - QString ridBase = item.remoteId(); - if ( ridBase.contains( QChar( '#' ) ) ) { - // A bit tricky: we must remove an incidence contained in a resource - // containing multiple ones. - ridBase.truncate( ridBase.indexOf( QChar( '#' ) ) ); + QString url = item.remoteId(); + if (url.contains(QChar('#'))) { + url.truncate(url.indexOf(QChar('#'))); + } + const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl(item.parentCollection().remoteId(), url); - Akonadi::Item::List extraItems; - foreach ( const QString &rid, mEtagCache.etags() ) { - if ( rid.startsWith( ridBase ) && rid != item.remoteId() ) { - Akonadi::Item extraItem; - extraItem.setRemoteId( rid ); - extraItems << extraItem; - } - } - - if ( extraItems.isEmpty() ) { - // Urrrr? - // Well, just delete the item. - doItemRemoval( item ); - } - else { - Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( extraItems ); - job->setCollection( item.parentCollection() ); - job->fetchScope().fetchFullPayload(); - job->setProperty( "item", QVariant::fromValue( item ) ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(onItemRemovalPrepared(KJob*)) ); - } - } - else { - // easy as pie: just remove everything at the URL. - doItemRemoval( item ); - } -} - -void DavGroupwareResource::onItemRemovalPrepared( KJob *job ) -{ - Akonadi::ItemFetchJob *fetchJob = qobject_cast( job ); - Akonadi::Item item = job->property( "item" ).value(); - Akonadi::Item::List keptItems = fetchJob->items(); - - if ( keptItems.isEmpty() ) { - // Urrrr? Not again! - doItemRemoval( item ); - } - else { - Akonadi::Item mainItem; - Akonadi::Item::List extraItems; - QString ridBase = item.remoteId(); - ridBase.truncate( ridBase.indexOf( QChar( '#' ) ) ); + // We have to re-set the URL as it's not necessarily valid after createDavItem() + davItem.setUrl(url); + davItem.setEtag(item.remoteRevision()); - foreach ( const Akonadi::Item &kept, keptItems ) { - if ( kept.remoteId() == ridBase && extraItems.isEmpty() ) - mainItem = kept; - else - extraItems << kept; - } - - if ( !mainItem.hasPayload() ) - mainItem = extraItems.takeFirst(); - - const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl( item.parentCollection().remoteId(), ridBase ); - - DavItem davItem = DavUtils::createDavItem( mainItem, mainItem.parentCollection(), extraItems ); - davItem.setUrl( ridBase ); - davItem.setEtag( item.remoteRevision() ); - - DavItemModifyJob *modJob = new DavItemModifyJob( davUrl, davItem ); - modJob->setProperty( "item", QVariant::fromValue( mainItem ) ); - modJob->setProperty( "dependentItems", QVariant::fromValue( extraItems ) ); - modJob->setProperty( "isRemoval", QVariant::fromValue( true ) ); - modJob->setProperty( "removedItem", QVariant::fromValue( item ) ); - connect( modJob, SIGNAL(result(KJob*)), SLOT(onItemChangedFinished(KJob*)) ); + DavItemModifyJob *modJob = new DavItemModifyJob(davUrl, davItem); + modJob->setProperty("item", QVariant::fromValue(item)); + modJob->setProperty("dependentItems", QVariant::fromValue(dependentItems)); + connect(modJob, &DavCollectionDeleteJob::result, this, &DavGroupwareResource::onItemChangedFinished); modJob->start(); - } } -void DavGroupwareResource::doItemRemoval( const Akonadi::Item &item ) +void DavGroupwareResource::itemRemoved(const Akonadi::Item &item) { - const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl( item.parentCollection().remoteId(), item.remoteId() ); - - DavItem davItem; - davItem.setUrl( item.remoteId() ); - davItem.setEtag( item.remoteRevision() ); - - DavItemDeleteJob *job = new DavItemDeleteJob( davUrl, davItem ); - job->setProperty( "item", QVariant::fromValue( item ) ); - job->setProperty( "collection", QVariant::fromValue( item.parentCollection() ) ); - connect( job, SIGNAL(result(KJob*)), SLOT(onItemRemovedFinished(KJob*)) ); - job->start(); -} + if (!configurationIsValid()) { + return; + } -void DavGroupwareResource::doSetOnline( bool online ) + QString ridBase = item.remoteId(); + if (ridBase.contains(QChar('#'))) { + // A bit tricky: we must remove an incidence contained in a resource + // containing multiple ones. + ridBase.truncate(ridBase.indexOf(QChar('#'))); + + Akonadi::Item::List extraItems; + foreach (const QString &rid, mEtagCache.etags()) { + if (rid.startsWith(ridBase) && rid != item.remoteId()) { + Akonadi::Item extraItem; + extraItem.setRemoteId(rid); + extraItems << extraItem; + } + } + + if (extraItems.isEmpty()) { + // Urrrr? + // Well, just delete the item. + doItemRemoval(item); + } else { + Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob(extraItems); + job->setCollection(item.parentCollection()); + job->fetchScope().fetchFullPayload(); + job->setProperty("item", QVariant::fromValue(item)); + connect(job, &DavCollectionDeleteJob::result, this, &DavGroupwareResource::onItemRemovalPrepared); + } + } else { + // easy as pie: just remove everything at the URL. + doItemRemoval(item); + } +} + +void DavGroupwareResource::onItemRemovalPrepared(KJob *job) +{ + Akonadi::ItemFetchJob *fetchJob = qobject_cast(job); + Akonadi::Item item = job->property("item").value(); + Akonadi::Item::List keptItems = fetchJob->items(); + + if (keptItems.isEmpty()) { + // Urrrr? Not again! + doItemRemoval(item); + } else { + Akonadi::Item mainItem; + Akonadi::Item::List extraItems; + QString ridBase = item.remoteId(); + ridBase.truncate(ridBase.indexOf(QChar('#'))); + + foreach (const Akonadi::Item &kept, keptItems) { + if (kept.remoteId() == ridBase && extraItems.isEmpty()) { + mainItem = kept; + } else { + extraItems << kept; + } + } + + if (!mainItem.hasPayload()) { + mainItem = extraItems.takeFirst(); + } + + const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl(item.parentCollection().remoteId(), ridBase); + + DavItem davItem = DavUtils::createDavItem(mainItem, mainItem.parentCollection(), extraItems); + davItem.setUrl(ridBase); + davItem.setEtag(item.remoteRevision()); + + DavItemModifyJob *modJob = new DavItemModifyJob(davUrl, davItem); + modJob->setProperty("item", QVariant::fromValue(mainItem)); + modJob->setProperty("dependentItems", QVariant::fromValue(extraItems)); + modJob->setProperty("isRemoval", QVariant::fromValue(true)); + modJob->setProperty("removedItem", QVariant::fromValue(item)); + connect(modJob, &DavItemModifyJob::result, this, &DavGroupwareResource::onItemChangedFinished); + modJob->start(); + } +} + +void DavGroupwareResource::doItemRemoval(const Akonadi::Item &item) +{ + const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl(item.parentCollection().remoteId(), item.remoteId()); + + DavItem davItem; + davItem.setUrl(item.remoteId()); + davItem.setEtag(item.remoteRevision()); + + DavItemDeleteJob *job = new DavItemDeleteJob(davUrl, davItem); + job->setProperty("item", QVariant::fromValue(item)); + job->setProperty("collection", QVariant::fromValue(item.parentCollection())); + connect(job, &DavCollectionDeleteJob::result, this, &DavGroupwareResource::onItemRemovedFinished); + job->start(); +} + +void DavGroupwareResource::doSetOnline(bool online) { - kDebug() << "Resource changed online status to" << online; + qCDebug(DAVRESOURCE_LOG) << "Resource changed online status to" << online; - if ( online ) { - synchronize(); - } + if (online) { + synchronize(); + } - ResourceBase::doSetOnline( online ); + ResourceBase::doSetOnline(online); } void DavGroupwareResource::createInitialCache() { - // Get all the items fetched by this resource - Akonadi::RecursiveItemFetchJob *job = new Akonadi::RecursiveItemFetchJob( mDavCollectionRoot, QStringList() ); - job->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(onCreateInitialCacheReady(KJob*)) ); - job->start(); + // Get all the items fetched by this resource + Akonadi::RecursiveItemFetchJob *job = new Akonadi::RecursiveItemFetchJob(mDavCollectionRoot, QStringList()); + job->fetchScope().setAncestorRetrieval(Akonadi::ItemFetchScope::Parent); + connect(job, &DavCollectionDeleteJob::result, this, &DavGroupwareResource::onCreateInitialCacheReady); + job->start(); } -void DavGroupwareResource::onCreateInitialCacheReady( KJob *job ) +void DavGroupwareResource::onCreateInitialCacheReady(KJob *job) { - Akonadi::RecursiveItemFetchJob *fetchJob = qobject_cast( job ); + Akonadi::RecursiveItemFetchJob *fetchJob = qobject_cast(job); - foreach ( const Akonadi::Item &item, fetchJob->items() ) { - const QString rid = item.remoteId(); - if ( rid.isEmpty() ) - continue; + foreach (const Akonadi::Item &item, fetchJob->items()) { + const QString rid = item.remoteId(); + if (rid.isEmpty()) { + continue; + } - const QString colRid = item.parentCollection().remoteId(); - if ( colRid.isEmpty() ) - continue; + const QString colRid = item.parentCollection().remoteId(); + if (colRid.isEmpty()) { + continue; + } - const QString etag = item.remoteRevision(); - if ( etag.isEmpty() ) - continue; + const QString etag = item.remoteRevision(); + if (etag.isEmpty()) { + continue; + } - mEtagCache.setEtag( rid, etag ); + mEtagCache.setEtag(rid, etag); - if ( !mItemsRidCache.contains( colRid ) ) - mItemsRidCache.insert( colRid, QSet() ); + if (!mItemsRidCache.contains(colRid)) { + mItemsRidCache.insert(colRid, QSet()); + } - mItemsRidCache[colRid].insert( rid ); - } + mItemsRidCache[colRid].insert(rid); + } - taskDone(); + taskDone(); } void DavGroupwareResource::onReloadConfig() @@ -554,470 +566,641 @@ synchronize(); } -void DavGroupwareResource::onCollectionRemovedFinished( KJob *job ) +void DavGroupwareResource::onCollectionRemovedFinished(KJob *job) { - if ( job->error() ) { - cancelTask( i18n( "Unable to remove collection: %1", job->errorText() ) ); - return; - } - - Akonadi::Collection collection = job->property( "collection" ).value(); - if ( mItemsRidCache.contains( collection.remoteId() ) ) { - foreach ( const QString &rid, mItemsRidCache.value( collection.remoteId() ) ) { - mEtagCache.removeEtag( rid ); + if (job->error()) { + cancelTask(i18n("Unable to remove collection: %1", job->errorText())); + return; } - mItemsRidCache.remove( collection.remoteId() ); - } - changeProcessed(); -} - -void DavGroupwareResource::onRetrieveCollectionsFinished( KJob *job ) -{ - const DavCollectionsMultiFetchJob *fetchJob = qobject_cast( job ); - - if ( job->error() ) { - kWarning() << "Unable to fetch collections" << job->error() << job->errorText(); - cancelTask( i18n( "Unable to retrieve collections: %1", job->errorText() ) ); - mSyncErrorNotified = true; - return; - } - - Akonadi::Collection::List collections; - collections << mDavCollectionRoot; - QSet seenCollectionsUrls; - - const DavCollection::List davCollections = fetchJob->collections(); - - foreach ( const DavCollection &davCollection, davCollections ) { - if ( seenCollectionsUrls.contains( davCollection.url() ) ) - continue; - else - seenCollectionsUrls.insert( davCollection.url() ); - if ( !mItemsRidCache.contains( davCollection.url() ) ) - mItemsRidCache.insert( davCollection.url(), QSet() ); - - Akonadi::Collection collection; - collection.setParentCollection( mDavCollectionRoot ); - collection.setRemoteId( davCollection.url() ); - collection.setName( collection.remoteId() ); - - if ( !davCollection.displayName().isEmpty() ) { - EntityDisplayAttribute *attr = collection.attribute( Collection::AddIfMissing ); - attr->setDisplayName( davCollection.displayName() ); + Akonadi::Collection collection = job->property("collection").value(); + if (mItemsRidCache.contains(collection.remoteId())) { + foreach (const QString &rid, mItemsRidCache.value(collection.remoteId())) { + mEtagCache.removeEtag(rid); + } + mItemsRidCache.remove(collection.remoteId()); } - - QStringList mimeTypes; - mimeTypes << Collection::mimeType(); - - const DavCollection::ContentTypes contentTypes = davCollection.contentTypes(); - if ( contentTypes & DavCollection::Calendar ) - mimeTypes << QLatin1String( "text/calendar" ); - - if ( contentTypes & DavCollection::Events ) - mimeTypes << KCalCore::Event::eventMimeType(); - - if ( contentTypes & DavCollection::Todos ) - mimeTypes << KCalCore::Todo::todoMimeType(); - - if ( contentTypes & DavCollection::Contacts ) - mimeTypes << KABC::Addressee::mimeType(); - - if ( contentTypes & DavCollection::FreeBusy ) - mimeTypes << KCalCore::FreeBusy::freeBusyMimeType(); - - if ( contentTypes & DavCollection::Journal ) - mimeTypes << KCalCore::Journal::journalMimeType(); - - collection.setContentMimeTypes( mimeTypes ); - setCollectionIcon( collection /*by-ref*/ ); - - DavProtocolAttribute *protoAttr = collection.attribute( Collection::AddIfMissing ); - protoAttr->setDavProtocol( davCollection.protocol() ); - - DavUtils::Privileges privileges = davCollection.privileges(); - Akonadi::Collection::Rights rights; - - if ( privileges & DavUtils::All || privileges & DavUtils::Write ) - rights |= Akonadi::Collection::AllRights; - - if ( privileges & DavUtils::WriteContent ) - rights |= Akonadi::Collection::CanChangeItem; - - if ( privileges & DavUtils::Bind ) - rights |= Akonadi::Collection::CanCreateItem; - - if ( privileges & DavUtils::Unbind ) - rights |= Akonadi::Collection::CanDeleteItem; - - if ( privileges == DavUtils::Read ) - rights |= Akonadi::Collection::ReadOnly; - - - collection.setRights( rights ); - mEtagCache.sync( collection ); - collections << collection; - } - - foreach ( const QString &rid, mItemsRidCache.keys() ) { - if ( !seenCollectionsUrls.contains( rid ) ) { - foreach ( const QString &itemRid, mItemsRidCache[rid] ) { - mEtagCache.removeEtag( itemRid ); - } - mItemsRidCache.remove( rid ); - } - } - - collectionsRetrieved( collections ); -} - -void DavGroupwareResource::onRetrieveItemsFinished( KJob *job ) -{ - if ( job->error() ) { - if ( mSyncErrorNotified ) { - cancelTask(); - } - else { - cancelTask( i18n( "Unable to retrieve items: %1", job->errorText() ) ); - mSyncErrorNotified = true; - } - return; - } - - const Collection collection = job->property( "collection" ).value(); - const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl( collection.remoteId() ); - const bool protocolSupportsMultiget = DavManager::self()->davProtocol( davUrl.protocol() )->useMultiget(); - - const DavItemsListJob *listJob = qobject_cast( job ); - - Akonadi::Item::List changedItems; - QSet seenRids; - QStringList changedRids; - - const DavItem::List davItems = listJob->items(); - foreach ( const DavItem &davItem, davItems ) { - seenRids.insert( davItem.url() ); - - Akonadi::Item item; - item.setParentCollection( collection ); - item.setRemoteId( davItem.url() ); - item.setMimeType( davItem.contentType() ); - item.setRemoteRevision( davItem.etag() ); - - if ( mEtagCache.etagChanged( item.remoteId(), davItem.etag() ) ) { - mEtagCache.markAsChanged( item.remoteId() ); - changedRids << item.remoteId(); - changedItems << item; - - // Only clear the payload (and therefor trigger a refetch from the backend) if we - // do not use multiget, because in this case we fetch the complete payload - // some lines below already. - if ( !protocolSupportsMultiget ) { - kDebug() << "Outdated item " << item.remoteId() << " (etag = " << davItem.etag() << ")"; - item.clearPayload(); - } - } - } - - QSet removedRids = mItemsRidCache[collection.remoteId()]; - mItemsRidCache[collection.remoteId()] = seenRids; - removedRids.subtract( seenRids ); - foreach ( const QString &rmd, removedRids ) { - Akonadi::Item item; - item.setParentCollection( collection ); - item.setRemoteId( rmd ); - mEtagCache.removeEtag( rmd ); - - // Use a job to delete items as itemsRetrievedIncremental seem to choke - // when many items are given with just their RID. - Akonadi::ItemDeleteJob *deleteJob = new Akonadi::ItemDeleteJob( item ); - deleteJob->start(); - } - - - // If the protocol supports multiget then deviate from the expected behavior - // and fetch all items with payload now instead of waiting for Akonadi to - // request it item by item in retrieveItem(). - // This allows the resource to use the multiget query and let it be nice - // to the remote server : only one request for n items instead of n requests. - if ( protocolSupportsMultiget && !changedRids.isEmpty() ) { - DavItemsFetchJob *fetchJob = new DavItemsFetchJob( davUrl, changedRids ); - connect( fetchJob, SIGNAL(result(KJob*)), this, SLOT(onMultigetFinished(KJob*)) ); - fetchJob->setProperty( "items", QVariant::fromValue( changedItems ) ); - fetchJob->start(); - // delay the call of itemsRetrieved() to onMultigetFinished() - } else { - itemsRetrievedIncremental( changedItems, Akonadi::Item::List() ); - } + changeProcessed(); } -void DavGroupwareResource::onMultigetFinished( KJob *job ) +void DavGroupwareResource::onRetrieveCollectionsFinished(KJob *job) { - if ( job->error() ) { - if ( mSyncErrorNotified ) { - cancelTask(); - } - else { - cancelTask( i18n( "Unable to retrieve items: %1", job->errorText() ) ); - mSyncErrorNotified = true; - } - return; - } + const DavCollectionsMultiFetchJob *fetchJob = qobject_cast(job); - const Akonadi::Item::List origItems = job->property( "items" ).value(); - const DavItemsFetchJob *davJob = qobject_cast( job ); - - Akonadi::Item::List items; - foreach ( Akonadi::Item item, origItems ) { //krazy:exclude=foreach non-const is intended here - const DavItem davItem = davJob->item( item.remoteId() ); - - // No data was retrieved for this item, maybe because it is not out of date - if ( davItem.data().isEmpty() ) { - if ( !mEtagCache.isOutOfDate( item.remoteId() ) ) + if (job->error()) { + qCWarning(DAVRESOURCE_LOG) << "Unable to fetch collections" << job->error() << job->errorText(); + cancelTask(i18n("Unable to retrieve collections: %1", job->errorText())); + mSyncErrorNotified = true; + return; + } + + Akonadi::Collection::List collections; + collections << mDavCollectionRoot; + QSet seenCollectionsUrls; + + const DavCollection::List davCollections = fetchJob->collections(); + + foreach (const DavCollection &davCollection, davCollections) { + if (seenCollectionsUrls.contains(davCollection.url())) { + continue; + } else { + seenCollectionsUrls.insert(davCollection.url()); + } + + if (!mItemsRidCache.contains(davCollection.url())) { + mItemsRidCache.insert(davCollection.url(), QSet()); + } + + Akonadi::Collection collection; + collection.setParentCollection(mDavCollectionRoot); + collection.setRemoteId(davCollection.url()); + collection.setName(collection.remoteId()); + + if (!davCollection.displayName().isEmpty()) { + EntityDisplayAttribute *attr = collection.attribute(Collection::AddIfMissing); + attr->setDisplayName(davCollection.displayName()); + } + + QStringList mimeTypes; + mimeTypes << Collection::mimeType(); + + const DavCollection::ContentTypes contentTypes = davCollection.contentTypes(); + if (contentTypes & DavCollection::Calendar) { + mimeTypes << QStringLiteral("text/calendar"); + } + + if (contentTypes & DavCollection::Events) { + mimeTypes << KCalCore::Event::eventMimeType(); + } + + if (contentTypes & DavCollection::Todos) { + mimeTypes << KCalCore::Todo::todoMimeType(); + } + + if (contentTypes & DavCollection::Contacts) { + mimeTypes << KContacts::Addressee::mimeType(); + } + + if (contentTypes & DavCollection::FreeBusy) { + mimeTypes << KCalCore::FreeBusy::freeBusyMimeType(); + } + + if (contentTypes & DavCollection::Journal) { + mimeTypes << KCalCore::Journal::journalMimeType(); + } + + collection.setContentMimeTypes(mimeTypes); + setCollectionIcon(collection /*by-ref*/); + + DavProtocolAttribute *protoAttr = collection.attribute(Collection::AddIfMissing); + protoAttr->setDavProtocol(davCollection.protocol()); + + DavUtils::Privileges privileges = davCollection.privileges(); + Akonadi::Collection::Rights rights; + + if (privileges & DavUtils::All || privileges & DavUtils::Write) { + rights |= Akonadi::Collection::AllRights; + } + + if (privileges & DavUtils::WriteContent) { + rights |= Akonadi::Collection::CanChangeItem; + } + + if (privileges & DavUtils::Bind) { + rights |= Akonadi::Collection::CanCreateItem; + } + + if (privileges & DavUtils::Unbind) { + rights |= Akonadi::Collection::CanDeleteItem; + } + + if (privileges == DavUtils::Read) { + rights |= Akonadi::Collection::ReadOnly; + } + + collection.setRights(rights); + mEtagCache.sync(collection); + collections << collection; + } + + foreach (const QString &rid, mItemsRidCache.keys()) { + if (!seenCollectionsUrls.contains(rid)) { + foreach (const QString &itemRid, mItemsRidCache[rid]) { + mEtagCache.removeEtag(itemRid); + } + mItemsRidCache.remove(rid); + } + } + + collectionsRetrieved(collections); +} + +void DavGroupwareResource::onRetrieveItemsFinished(KJob *job) +{ + if (job->error()) { + if (mSyncErrorNotified) { + cancelTask(); + } else { + cancelTask(i18n("Unable to retrieve items: %1", job->errorText())); + mSyncErrorNotified = true; + } + return; + } + + const Collection collection = job->property("collection").value(); + const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl(collection.remoteId()); + const bool protocolSupportsMultiget = DavManager::self()->davProtocol(davUrl.protocol())->useMultiget(); + + const DavItemsListJob *listJob = qobject_cast(job); + + Akonadi::Item::List changedItems; + QSet seenRids; + QStringList changedRids; + + const DavItem::List davItems = listJob->items(); + foreach (const DavItem &davItem, davItems) { + seenRids.insert(davItem.url()); + + Akonadi::Item item; + item.setParentCollection(collection); + item.setRemoteId(davItem.url()); + item.setMimeType(davItem.contentType()); + item.setRemoteRevision(davItem.etag()); + + if (mEtagCache.etagChanged(item.remoteId(), davItem.etag())) { + mEtagCache.markAsChanged(item.remoteId()); + changedRids << item.remoteId(); + changedItems << item; + + // Only clear the payload (and therefor trigger a refetch from the backend) if we + // do not use multiget, because in this case we fetch the complete payload + // some lines below already. + if (!protocolSupportsMultiget) { + qCDebug(DAVRESOURCE_LOG) << "Outdated item " << item.remoteId() << " (etag = " << davItem.etag() << ")"; + item.clearPayload(); + } + } + } + + QSet removedRids = mItemsRidCache[collection.remoteId()]; + mItemsRidCache[collection.remoteId()] = seenRids; + removedRids.subtract(seenRids); + foreach (const QString &rmd, removedRids) { + Akonadi::Item item; + item.setParentCollection(collection); + item.setRemoteId(rmd); + mEtagCache.removeEtag(rmd); + + // Use a job to delete items as itemsRetrievedIncremental seem to choke + // when many items are given with just their RID. + Akonadi::ItemDeleteJob *deleteJob = new Akonadi::ItemDeleteJob(item); + deleteJob->start(); + } + + // If the protocol supports multiget then deviate from the expected behavior + // and fetch all items with payload now instead of waiting for Akonadi to + // request it item by item in retrieveItem(). + // This allows the resource to use the multiget query and let it be nice + // to the remote server : only one request for n items instead of n requests. + if (protocolSupportsMultiget && !changedRids.isEmpty()) { + DavItemsFetchJob *fetchJob = new DavItemsFetchJob(davUrl, changedRids); + connect(fetchJob, &DavItemsFetchJob::result, this, &DavGroupwareResource::onMultigetFinished); + fetchJob->setProperty("items", QVariant::fromValue(changedItems)); + fetchJob->start(); + // delay the call of itemsRetrieved() to onMultigetFinished() + } else { + itemsRetrievedIncremental(changedItems, Akonadi::Item::List()); + } +} + +void DavGroupwareResource::onMultigetFinished(KJob *job) +{ + if (job->error()) { + if (mSyncErrorNotified) { + cancelTask(); + } else { + cancelTask(i18n("Unable to retrieve items: %1", job->errorText())); + mSyncErrorNotified = true; + } + return; + } + + const Akonadi::Item::List origItems = job->property("items").value(); + const DavItemsFetchJob *davJob = qobject_cast(job); + + Akonadi::Item::List items; + foreach (Akonadi::Item item, origItems) { //krazy:exclude=foreach non-const is intended here + const DavItem davItem = davJob->item(item.remoteId()); + + // No data was retrieved for this item, maybe because it is not out of date + if (davItem.data().isEmpty()) { + if (!mEtagCache.isOutOfDate(item.remoteId())) { + items << item; + } + continue; + } + + Akonadi::Item::List extraItems; + if (!DavUtils::parseDavData(davItem, item, extraItems)) { + continue; + } + + // update etag + item.setRemoteRevision(davItem.etag()); + mEtagCache.setEtag(item.remoteId(), davItem.etag()); items << item; - continue; + foreach (const Akonadi::Item &extraItem, extraItems) { + mEtagCache.setEtag(extraItem.remoteId(), davItem.etag()); + items << extraItem; + } } - Akonadi::Item::List extraItems; - if ( !DavUtils::parseDavData( davItem, item, extraItems ) ) - continue; - - // update etag - item.setRemoteRevision( davItem.etag() ); - mEtagCache.setEtag( item.remoteId(), davItem.etag() ); - items << item; - foreach ( const Akonadi::Item &extraItem, extraItems ) { - mEtagCache.setEtag( extraItem.remoteId(), davItem.etag() ); - items << extraItem; - } - } - - itemsRetrievedIncremental( items, Akonadi::Item::List() ); + itemsRetrievedIncremental(items, Akonadi::Item::List()); } -void DavGroupwareResource::onRetrieveItemFinished( KJob *job ) +void DavGroupwareResource::onRetrieveItemFinished(KJob *job) { - onItemFetched( job, ItemUpdateAdd ); + onItemFetched(job, ItemUpdateAdd); } -void DavGroupwareResource::onItemRefreshed( KJob* job ) +void DavGroupwareResource::onItemRefreshed(KJob *job) { - ItemFetchUpdateType update = ItemUpdateChange; - if ( job->property( "isRemoval" ).isValid() && job->property( "isRemoval" ).toBool() ) - update = ItemUpdateNone; + ItemFetchUpdateType update = ItemUpdateChange; + if (job->property("isRemoval").isValid() && job->property("isRemoval").toBool()) { + update = ItemUpdateNone; + } - onItemFetched( job, update ); + onItemFetched(job, update); } -void DavGroupwareResource::onItemFetched( KJob* job, ItemFetchUpdateType updateType ) +void DavGroupwareResource::onItemFetched(KJob *job, ItemFetchUpdateType updateType) { - if ( job->error() ) { - if ( mSyncErrorNotified ) { - cancelTask(); - } - else { - cancelTask( i18n( "Unable to retrieve item: %1", job->errorText() ) ); - mSyncErrorNotified = true; + if (job->error()) { + if (mSyncErrorNotified) { + cancelTask(); + } else { + cancelTask(i18n("Unable to retrieve item: %1", job->errorText())); + mSyncErrorNotified = true; + } + return; } - return; - } - - const DavItemFetchJob *fetchJob = qobject_cast( job ); - const DavItem davItem = fetchJob->item(); - Akonadi::Item item = fetchJob->property( "item" ).value(); - - Akonadi::Item::List extraItems; - if ( !DavUtils::parseDavData( davItem, item, extraItems ) ) - return; - - // update etag - item.setRemoteRevision( davItem.etag() ); - mEtagCache.setEtag( item.remoteId(), davItem.etag() ); - - if ( !extraItems.isEmpty() ) { - for ( int i = 0; i < extraItems.size(); ++i ) - mEtagCache.setEtag( extraItems.at( i ).remoteId(), davItem.etag() ); - Akonadi::ItemModifyJob *j = new Akonadi::ItemModifyJob( extraItems ); - j->setIgnorePayload( true ); - } + const DavItemFetchJob *fetchJob = qobject_cast(job); + const DavItem davItem = fetchJob->item(); + Akonadi::Item item = fetchJob->property("item").value(); - if ( updateType == ItemUpdateChange ) - changeCommitted( item ); - else if ( updateType == ItemUpdateAdd ) - itemRetrieved( item ); -} - -void DavGroupwareResource::onItemAddedFinished( KJob *job ) -{ - const DavItemCreateJob *createJob = qobject_cast( job ); - const DavItem davItem = createJob->item(); - Akonadi::Item item = createJob->property( "item" ).value(); - item.setRemoteId( davItem.url() ); - - if ( createJob->error() ) { - kError() << "Error when uploading item:" << createJob->error() << createJob->errorString(); - if ( createJob->canRetryLater() ) { - retryAfterFailure(createJob->errorString()); - } - else { - cancelTask( i18n( "Unable to add item: %1", createJob->errorString() ) ); + Akonadi::Item::List extraItems; + if (!DavUtils::parseDavData(davItem, item, extraItems)) { + return; } - return; - } - Akonadi::Collection collection = createJob->property( "collection" ).value(); - mItemsRidCache[collection.remoteId()].insert( davItem.url() ); + // update etag + item.setRemoteRevision(davItem.etag()); + mEtagCache.setEtag(item.remoteId(), davItem.etag()); - if ( davItem.etag().isEmpty() ) { - const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl( item.parentCollection().remoteId(), item.remoteId() ); - DavItemFetchJob *fetchJob = new DavItemFetchJob( davUrl, davItem ); - fetchJob->setProperty( "item", QVariant::fromValue( item ) ); - connect( fetchJob, SIGNAL(result(KJob*)), SLOT(onItemRefreshed(KJob*)) ); - fetchJob->start(); - } else { - item.setRemoteRevision( davItem.etag() ); - mEtagCache.setEtag( davItem.url(), davItem.etag() ); - changeCommitted( item ); - } + if (!extraItems.isEmpty()) { + for (int i = 0; i < extraItems.size(); ++i) { + mEtagCache.setEtag(extraItems.at(i).remoteId(), davItem.etag()); + } + + Akonadi::ItemModifyJob *j = new Akonadi::ItemModifyJob(extraItems); + j->setIgnorePayload(true); + } + + if (updateType == ItemUpdateChange) { + changeCommitted(item); + } else if (updateType == ItemUpdateAdd) { + itemRetrieved(item); + } +} + +void DavGroupwareResource::onItemAddedFinished(KJob *job) +{ + const DavItemCreateJob *createJob = qobject_cast(job); + const DavItem davItem = createJob->item(); + Akonadi::Item item = createJob->property("item").value(); + item.setRemoteId(davItem.url()); + + if (createJob->error()) { + qCCritical(DAVRESOURCE_LOG) << "Error when uploading item:" << createJob->error() << createJob->errorString(); + if (createJob->canRetryLater()) { + retryAfterFailure(createJob->errorString()); + } else { + cancelTask(i18n("Unable to add item: %1", createJob->errorString())); + } + return; + } + + Akonadi::Collection collection = createJob->property("collection").value(); + mItemsRidCache[collection.remoteId()].insert(davItem.url()); + + if (davItem.etag().isEmpty()) { + const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl(item.parentCollection().remoteId(), item.remoteId()); + DavItemFetchJob *fetchJob = new DavItemFetchJob(davUrl, davItem); + fetchJob->setProperty("item", QVariant::fromValue(item)); + connect(fetchJob, &DavItemsFetchJob::result, this, &DavGroupwareResource::onItemRefreshed); + fetchJob->start(); + } else { + item.setRemoteRevision(davItem.etag()); + mEtagCache.setEtag(davItem.url(), davItem.etag()); + changeCommitted(item); + } +} + +void DavGroupwareResource::onItemChangedFinished(KJob *job) +{ + const DavItemModifyJob *modifyJob = qobject_cast(job); + const DavItem davItem = modifyJob->item(); + Akonadi::Item item = modifyJob->property("item").value(); + Akonadi::Item::List dependentItems = modifyJob->property("dependentItems").value(); + bool isRemoval = modifyJob->property("isRemoval").isValid() && modifyJob->property("isRemoval").toBool(); + + if (modifyJob->error()) { + qCCritical(DAVRESOURCE_LOG) << "Error when uploading item:" << modifyJob->error() << modifyJob->errorString(); + if (modifyJob->hasConflict()) { + handleConflict(item, dependentItems, modifyJob->freshItem(), isRemoval, modifyJob->freshResponseCode()); + } else if (modifyJob->canRetryLater()) { + retryAfterFailure(modifyJob->errorString()); + } else { + cancelTask(i18n("Unable to change item: %1", modifyJob->errorString())); + } + return; + } + + if (isRemoval) { + Akonadi::Item removedItem = job->property("removedItem").value(); + mEtagCache.removeEtag(removedItem.remoteId()); + mItemsRidCache[removedItem.parentCollection().remoteId()].remove(removedItem.remoteId()); + changeProcessed(); + } + + if (davItem.etag().isEmpty()) { + const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl(item.parentCollection().remoteId(), item.remoteId()); + DavItemFetchJob *fetchJob = new DavItemFetchJob(davUrl, davItem); + fetchJob->setProperty("item", QVariant::fromValue(item)); + fetchJob->setProperty("dependentItems", QVariant::fromValue(dependentItems)); + fetchJob->setProperty("isRemoval", QVariant::fromValue(isRemoval)); + connect(fetchJob, &DavItemsFetchJob::result, this, &DavGroupwareResource::onItemRefreshed); + fetchJob->start(); + } else { + if (!isRemoval) { + item.setRemoteRevision(davItem.etag()); + mEtagCache.setEtag(davItem.url(), davItem.etag()); + changeCommitted(item); + } + + if (!dependentItems.isEmpty()) { + for (int i = 0; i < dependentItems.size(); ++i) { + dependentItems[i].setRemoteRevision(davItem.etag()); + mEtagCache.setEtag(dependentItems.at(i).remoteId(), davItem.etag()); + } + + Akonadi::ItemModifyJob *j = new Akonadi::ItemModifyJob(dependentItems); + j->setIgnorePayload(true); + } + } +} + +void DavGroupwareResource::onDeletedItemRecreated(KJob *job) +{ + const DavItemCreateJob *createJob = qobject_cast(job); + const DavItem davItem = createJob->item(); + Akonadi::Item item = createJob->property("item").value(); + Akonadi::Item::List dependentItems = createJob->property("dependentItems").value(); + + if (davItem.etag().isEmpty()) { + const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl(item.parentCollection().remoteId(), item.remoteId()); + DavItemFetchJob *fetchJob = new DavItemFetchJob(davUrl, davItem); + fetchJob->setProperty("item", QVariant::fromValue(item)); + fetchJob->setProperty("dependentItems", QVariant::fromValue(dependentItems)); + connect(fetchJob, &DavItemFetchJob::result, this, &DavGroupwareResource::onItemRefreshed); + fetchJob->start(); + } else { + item.setRemoteRevision(davItem.etag()); + mEtagCache.setEtag(davItem.url(), davItem.etag()); + changeCommitted(item); + + if (!dependentItems.isEmpty()) { + for (int i = 0; i < dependentItems.size(); ++i) { + dependentItems[i].setRemoteRevision(davItem.etag()); + mEtagCache.setEtag(dependentItems.at(i).remoteId(), davItem.etag()); + } + + Akonadi::ItemModifyJob *j = new Akonadi::ItemModifyJob(dependentItems); + j->setIgnorePayload(true); + } + } +} + +void DavGroupwareResource::onItemRemovedFinished(KJob *job) +{ + if (job->error()) { + const DavItemDeleteJob *deleteJob = qobject_cast(job); + + if (deleteJob->hasConflict()) { + // Use a shortcut here as we don't show a conflict dialog to the user. + handleConflict(Akonadi::Item(), Akonadi::Item::List(), deleteJob->freshItem(), true, 0); + } else if (deleteJob->canRetryLater()) { + retryAfterFailure(job->errorString()); + } else { + cancelTask(i18n("Unable to remove item: %1", job->errorString())); + } + } else { + Akonadi::Item item = job->property("item").value(); + Akonadi::Collection collection = job->property("collection").value(); + mItemsRidCache[collection.remoteId()].remove(item.remoteId()); + mEtagCache.removeEtag(item.remoteId()); + changeProcessed(); + } +} + +void DavGroupwareResource::onCollectionDiscovered(int protocol, const QString &collection, const QString &config) +{ + Settings::self()->addCollectionUrlMapping(DavUtils::Protocol(protocol), collection, config); +} + +void DavGroupwareResource::onEtagChanged(const QString &itemUrl, const QString &etag) +{ + mEtagCache.setEtag(itemUrl, etag); +} + +void DavGroupwareResource::handleConflict(const Item &lI, const Item::List &localDependentItems, const DavItem &rI, bool isLocalRemoval, int responseCode) +{ + Akonadi::Item localItem(lI); + Akonadi::Item remoteItem, tmpRemoteItem; // The tmp* vars are here to store the result of the parseDavData() call + Akonadi::Item::List remoteDependentItems, tmpRemoteDependentItems; // as we have no idea which item triggered the conflict. + qCDebug(DAVRESOURCE_LOG) << "Fresh response code is" << responseCode; + bool isRemoteRemoval = (responseCode == 404 || responseCode == 410); + + if (!isRemoteRemoval) { + if (!DavUtils::parseDavData(rI, tmpRemoteItem, tmpRemoteDependentItems)) { + // TODO: set a more correct error message here + cancelTask(i18n("Unable to change item: %1", QStringLiteral("conflict resolution failed"))); + return; + // TODO: we can end up here if the remote item was deleted + } + + // Now try to find the item that really triggered the conflict + Akonadi::Item::List allRemoteItems; allRemoteItems << tmpRemoteItem << tmpRemoteDependentItems; + foreach (const Akonadi::Item &tmpItem, allRemoteItems) { + if (tmpItem.payloadData() != localItem.payloadData()) { + if (remoteItem.isValid()) { + // Oops, we can only manage one changed item at this stage, sorry... + // TODO: make this translatable + cancelTask(i18n("Unable to change item: %1", QStringLiteral("more than one item was changed in the backend"))); + return; + } + remoteItem = tmpItem; + } else { + remoteDependentItems << tmpItem; + } + } + } + + if (isLocalRemoval) { + // TODO: implement with the configurable strategy + /* + * Here by default we don't delete an event that was modified in the backend, and + * instead we just abort the current task. + * Also, trigger an immediate sync to refresh the item. + */ + qCDebug(DAVRESOURCE_LOG) << "Local removal conflict"; + // TODO: make this translatable + cancelTask(i18n("Unable to remove item: %1", QStringLiteral("it was changed in the backend in the meantime"))); + synchronize(); + } else if (isRemoteRemoval) { + // TODO: implement with the configurable strategy + /* + * Here also it is a bit tricky to clear the item in the local cache as the resource + * will not get notified if the user chooses to delete the item and abandon the local + * modification. For the time being let's just re-upload the changed item. + */ + qCDebug(DAVRESOURCE_LOG) << "Remote removal conflict"; + Akonadi::Collection collection = localItem.parentCollection(); + DavItem davItem = DavUtils::createDavItem(localItem, collection, localDependentItems); + + QString urlStr = localItem.remoteId(); + if (urlStr.contains(QChar('#'))) { + urlStr.truncate(urlStr.indexOf(QChar('#'))); + } + davItem.setUrl(urlStr); + const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl(collection.remoteId(), urlStr); + + DavItemCreateJob *job = new DavItemCreateJob(davUrl, davItem); + job->setProperty("item", QVariant::fromValue(localItem)); + job->setProperty("dependentItems", QVariant::fromValue(localDependentItems)); + connect(job, SIGNAL(result(KJob*)), SLOT(onDeletedItemRecreated(KJob*))); + job->start(); + } else { + const QString remoteEtag = rI.etag(); + + localItem.setRemoteRevision(remoteEtag); + changeCommitted(localItem); + + // Update the ETag cache in all cases as the new ETag will have to be used + // later for any update or deletion + mEtagCache.setEtag(rI.url(), remoteEtag); + + // The first step is to fire a first modify job that will replace the item currently + // in the local cache with the one that was found in the backend. + Akonadi::Item updatedItem(localItem); + updatedItem.setPayloadFromData(remoteItem.payloadData()); + updatedItem.setRemoteRevision(remoteEtag); + Akonadi::ItemModifyJob *j = new Akonadi::ItemModifyJob(updatedItem); + j->setIgnorePayload(false); + j->start(); + + // So now we have in the cache what's in the backend but the user is not aware + // that behind the scenes something terrible is happening. Well, nearly... + // To notify him of this, and due to the way the conflict handler works, we have + // to re-attempt a modification to revert the modify job that was just fired. + // So yes, we are effectively re-submitting the client-provided content, but + // with a revision that will trigger the conflict dialog. + // The only problem is that the user will see that we update the item before + // the conflict dialog has time to display (if it's not behind the application + // window). + localItem.setRevision(0); + j = new Akonadi::ItemModifyJob(localItem); + j->setIgnorePayload(false); + connect(j, SIGNAL(result(KJob*)), this, SLOT(onConflictModifyJobFinished(KJob*))); + j->start(); + + // Hopefully for the dependent items everything will be fine. Right? + // Not so sure in fact. + if (!remoteDependentItems.isEmpty()) { + for (int i = 0; i < remoteDependentItems.size(); ++i) { + remoteDependentItems[i].setRemoteRevision(remoteEtag); + mEtagCache.setEtag(remoteDependentItems.at(i).remoteId(), remoteEtag); + } + + Akonadi::ItemModifyJob *j = new Akonadi::ItemModifyJob(remoteDependentItems); + j->setIgnorePayload(true); + } + } +} + +void DavGroupwareResource::onConflictModifyJobFinished(KJob *job) +{ + Akonadi::ItemModifyJob *j = qobject_cast(job); + if (j->error()) { + qCCritical(DAVRESOURCE_LOG) << "Conflict update failed: " << job->errorText(); + // TODO: what do we do now? We just committed an item that's in a weird state... + } } -void DavGroupwareResource::onItemChangedFinished( KJob *job ) +bool DavGroupwareResource::configurationIsValid() { - const DavItemModifyJob *modifyJob = qobject_cast( job ); - const DavItem davItem = modifyJob->item(); - Akonadi::Item item = modifyJob->property( "item" ).value(); - Akonadi::Item::List dependentItems = modifyJob->property( "dependentItems" ).value(); - bool isRemoval = modifyJob->property( "isRemoval" ).isValid() && modifyJob->property( "isRemoval" ).toBool(); - - if ( modifyJob->error() ) { - kError() << "Error when uploading item:" << modifyJob->error() << modifyJob->errorString(); - if ( modifyJob->canRetryLater() ) { - retryAfterFailure(modifyJob->errorString()); + if (Settings::self()->configuredDavUrls().empty()) { + Q_EMIT status(NotConfigured, i18n("The resource is not configured yet")); + cancelTask(i18n("The resource is not configured yet")); + return false; } - else { - cancelTask( i18n( "Unable to change item: %1", modifyJob->errorString() ) ); - } - return; - } - - if ( isRemoval ) { - Akonadi::Item removedItem = job->property( "removedItem" ).value(); - mEtagCache.removeEtag( removedItem.remoteId() ); - mItemsRidCache[removedItem.parentCollection().remoteId()].remove( removedItem.remoteId() ); - changeProcessed(); - } - if ( davItem.etag().isEmpty() ) { - const DavUtils::DavUrl davUrl = Settings::self()->davUrlFromCollectionUrl( item.parentCollection().remoteId(), item.remoteId() ); - DavItemFetchJob *fetchJob = new DavItemFetchJob( davUrl, davItem ); - fetchJob->setProperty( "item", QVariant::fromValue( item ) ); - fetchJob->setProperty( "dependentItems", QVariant::fromValue( dependentItems ) ); - fetchJob->setProperty( "isRemoval", QVariant::fromValue( isRemoval ) ); - connect( fetchJob, SIGNAL(result(KJob*)), SLOT(onItemRefreshed(KJob*)) ); - fetchJob->start(); - } else { - if ( !isRemoval ) { - item.setRemoteRevision( davItem.etag() ); - mEtagCache.setEtag( davItem.url(), davItem.etag() ); - changeCommitted( item ); - } - - if ( !dependentItems.isEmpty() ) { - for ( int i = 0; i < dependentItems.size(); ++i ) { - dependentItems[i].setRemoteRevision( davItem.etag() ); - mEtagCache.setEtag( dependentItems.at( i ).remoteId(), davItem.etag() ); - } - - Akonadi::ItemModifyJob *j = new Akonadi::ItemModifyJob( dependentItems ); - j->setIgnorePayload( true ); - } - } -} - -void DavGroupwareResource::onItemRemovedFinished( KJob *job ) -{ - if ( job->error() ) { - const DavItemDeleteJob *deleteJob = qobject_cast( job ); - - if ( deleteJob->canRetryLater() ) { - retryAfterFailure(job->errorString()); - } - else { - cancelTask( i18n( "Unable to remove item: %1", job->errorString() ) ); - } - } - else { - Akonadi::Item item = job->property( "item" ).value(); - Akonadi::Collection collection = job->property( "collection" ).value(); - mItemsRidCache[collection.remoteId()].remove( item.remoteId() ); - mEtagCache.removeEtag( item.remoteId() ); - changeProcessed(); - } -} + int newICT = Settings::self()->refreshInterval(); + if (newICT == 0) { + newICT = -1; + } -void DavGroupwareResource::onCollectionDiscovered( int protocol, const QString &collection, const QString &config ) -{ - Settings::self()->addCollectionUrlMapping( DavUtils::Protocol( protocol ), collection, config ); -} + if (newICT != mDavCollectionRoot.cachePolicy().intervalCheckTime()) { + Akonadi::CachePolicy cachePolicy = mDavCollectionRoot.cachePolicy(); + cachePolicy.setIntervalCheckTime(newICT); -void DavGroupwareResource::onEtagChanged(const QString& itemUrl, const QString& etag) -{ - mEtagCache.setEtag( itemUrl, etag ); -} + mDavCollectionRoot.setCachePolicy(cachePolicy); + } -bool DavGroupwareResource::configurationIsValid() -{ - if ( Settings::self()->configuredDavUrls().empty() ) { - emit status( NotConfigured, i18n( "The resource is not configured yet" ) ); - cancelTask( i18n( "The resource is not configured yet" ) ); - return false; - } - - int newICT = Settings::self()->refreshInterval(); - if ( newICT == 0 ) - newICT = -1; - - if ( newICT != mDavCollectionRoot.cachePolicy().intervalCheckTime() ) { - Akonadi::CachePolicy cachePolicy = mDavCollectionRoot.cachePolicy(); - cachePolicy.setIntervalCheckTime( newICT ); - - mDavCollectionRoot.setCachePolicy( cachePolicy ); - } - - if ( !Settings::self()->displayName().isEmpty() ) { - EntityDisplayAttribute *attribute = mDavCollectionRoot.attribute( Collection::AddIfMissing ); - attribute->setDisplayName( Settings::self()->displayName() ); - setName( Settings::self()->displayName() ); - } + if (!Settings::self()->displayName().isEmpty()) { + EntityDisplayAttribute *attribute = mDavCollectionRoot.attribute(Collection::AddIfMissing); + attribute->setDisplayName(Settings::self()->displayName()); + setName(Settings::self()->displayName()); + } - return true; + return true; } void DavGroupwareResource::retryAfterFailure(const QString &errorMessage) { - emit status(Broken, errorMessage); - deferTask(); - setTemporaryOffline(Settings::self()->refreshInterval() <= 0 ? 300 : Settings::self()->refreshInterval() * 60); + Q_EMIT status(Broken, errorMessage); + deferTask(); + setTemporaryOffline(Settings::self()->refreshInterval() <= 0 ? 300 : Settings::self()->refreshInterval() * 60); } /*static*/ -void DavGroupwareResource::setCollectionIcon( Akonadi::Collection &collection ) +void DavGroupwareResource::setCollectionIcon(Akonadi::Collection &collection) { - const QStringList mimeTypes = collection.contentMimeTypes(); - if ( mimeTypes.count() == 1 ) { - QHash mapping; - mapping.insert( KCalCore::Event::eventMimeType(), QLatin1String( "view-calendar" ) ); - mapping.insert( KCalCore::Todo::todoMimeType(), QLatin1String( "view-calendar-tasks" ) ); - mapping.insert( KCalCore::Journal::journalMimeType(), QLatin1String( "view-pim-journal" ) ); - mapping.insert( KABC::Addressee::mimeType(), QLatin1String( "view-pim-contacts" ) ); + const QStringList mimeTypes = collection.contentMimeTypes(); + if (mimeTypes.count() == 1) { + QHash mapping; + mapping.insert(KCalCore::Event::eventMimeType(), QStringLiteral("view-calendar")); + mapping.insert(KCalCore::Todo::todoMimeType(), QStringLiteral("view-calendar-tasks")); + mapping.insert(KCalCore::Journal::journalMimeType(), QStringLiteral("view-pim-journal")); + mapping.insert(KContacts::Addressee::mimeType(), QStringLiteral("view-pim-contacts")); - if ( mapping.contains( mimeTypes.first() ) ) { - EntityDisplayAttribute *attribute = collection.attribute( Collection::AddIfMissing ); - attribute->setIconName( mapping.value( mimeTypes.first() ) ); + if (mapping.contains(mimeTypes.first())) { + EntityDisplayAttribute *attribute = collection.attribute(Collection::AddIfMissing); + attribute->setIconName(mapping.value(mimeTypes.first())); + } } - } } -AKONADI_RESOURCE_MAIN( DavGroupwareResource ) +AKONADI_RESOURCE_MAIN(DavGroupwareResource) diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/davgroupwareresource.desktop kdepim-runtime-15.08.0/resources/dav/resource/davgroupwareresource.desktop --- kdepim-runtime-4.14.6/resources/dav/resource/davgroupwareresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/davgroupwareresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -7,7 +7,7 @@ Name[de]=DAV-Groupware-Ressource Name[el]=Πόρος DAV groupware Name[en_GB]=DAV groupware resource -Name[es]=Recurso de trabajo en grupo DAV +Name[es]=Recurso de colaboración DAV Name[et]=DAV grupitöö ressurss Name[fi]=DAV-työryhmäresurssi Name[fr]=Ressource pour logiciels de collaboration DAV @@ -69,6 +69,7 @@ Comment[pt_BR]="Recurso para gerenciar calendários e livros de endereços por DAV (CalDAV, GroupDAV)" Comment[ru]="Источники данных для управления календарями и адресными книгами DAV (CalDAV, GroupDAV)" Comment[sk]="Zdroj na správu DAV kalendárov a adresárov kontaktov (CalDAV, GroupDAV)" +Comment[sl]=»Vir za upravljanje koledarjev in imenikov DAV (CalDAV, GroupDAV)« Comment[sr]="Ресурс за управљање ДАВ календарима и адресарима (калДАВ, групДАВ)" Comment[sr@ijekavian]="Ресурс за управљање ДАВ календарима и адресарима (калДАВ, групДАВ)" Comment[sr@ijekavianlatin]="Resurs za upravljanje DAV kalendarima i adresarima (CalDAV, GroupDAV)" diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/davgroupwareresource.h kdepim-runtime-15.08.0/resources/dav/resource/davgroupwareresource.h --- kdepim-runtime-4.14.6/resources/dav/resource/davgroupwareresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/davgroupwareresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -21,7 +21,7 @@ #include "etagcache.h" -#include +#include #include class DavFreeBusyHandler; @@ -32,57 +32,57 @@ #include class DavGroupwareResource : public Akonadi::ResourceBase, - public Akonadi::AgentBase::Observer, - public Akonadi::FreeBusyProviderBase + public Akonadi::AgentBase::Observer, + public Akonadi::FreeBusyProviderBase { - Q_OBJECT + Q_OBJECT - public: - explicit DavGroupwareResource( const QString &id ); +public: + explicit DavGroupwareResource(const QString &id); ~DavGroupwareResource(); - virtual void collectionRemoved( const Akonadi::Collection &collection ); - virtual void cleanup(); + void collectionRemoved(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void cleanup() Q_DECL_OVERRIDE; - virtual KDateTime lastCacheUpdate() const; - virtual void canHandleFreeBusy( const QString &email ) const; - virtual void retrieveFreeBusy( const QString &email, const KDateTime &start, const KDateTime &end ); - - public Q_SLOTS: - virtual void configure( WId windowId ); - - protected Q_SLOTS: - void retrieveCollections(); - void retrieveItems( const Akonadi::Collection &collection ); - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - - protected: - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); - virtual void itemRemoved( const Akonadi::Item &item ); - virtual void doSetOnline( bool online ); + KDateTime lastCacheUpdate() const Q_DECL_OVERRIDE; + void canHandleFreeBusy(const QString &email) const Q_DECL_OVERRIDE; + void retrieveFreeBusy(const QString &email, const KDateTime &start, const KDateTime &end) Q_DECL_OVERRIDE; + +public Q_SLOTS: + void configure(WId windowId) Q_DECL_OVERRIDE; + +protected Q_SLOTS: + void retrieveCollections() Q_DECL_OVERRIDE; + void retrieveItems(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + bool retrieveItem(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + +protected: + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + void itemRemoved(const Akonadi::Item &item) Q_DECL_OVERRIDE; + void doSetOnline(bool online) Q_DECL_OVERRIDE; - private: +private: enum ItemFetchUpdateType { - ItemUpdateNone, - ItemUpdateAdd, - ItemUpdateChange + ItemUpdateNone, + ItemUpdateAdd, + ItemUpdateChange }; - private Q_SLOTS: +private Q_SLOTS: void createInitialCache(); - void onCreateInitialCacheReady( KJob* ); + void onCreateInitialCacheReady(KJob *); void onReloadConfig(); - void onCollectionRemovedFinished( KJob* ); + void onCollectionRemovedFinished(KJob *); - void onHandlesFreeBusy( const QString &email, bool handles ); - void onFreeBusyRetrieved( const QString &email, const QString &freeBusy, bool success, const QString &errorText ); + void onHandlesFreeBusy(const QString &email, bool handles); + void onFreeBusyRetrieved(const QString &email, const QString &freeBusy, bool success, const QString &errorText); - void onRetrieveCollectionsFinished( KJob* ); - void onRetrieveItemsFinished( KJob* ); - void onMultigetFinished( KJob* ); - void onRetrieveItemFinished( KJob* ); + void onRetrieveCollectionsFinished(KJob *); + void onRetrieveItemsFinished(KJob *); + void onMultigetFinished(KJob *); + void onRetrieveItemFinished(KJob *); /** * Called when a new item has been fetched from the backend. * @@ -90,21 +90,29 @@ * @param updateType The type of update that triggered this call. The task notification sent * sent to Akonadi will depend on this flag. */ - void onItemFetched( KJob* job, ItemFetchUpdateType updateType ); - void onItemRefreshed( KJob* job ); + void onItemFetched(KJob *job, ItemFetchUpdateType updateType); + void onItemRefreshed(KJob *job); - void onItemAddedFinished( KJob* ); - void onItemChangePrepared( KJob* ); - void onItemChangedFinished( KJob* ); - void onItemRemovalPrepared( KJob* ); - void onItemRemovedFinished( KJob* ); - - void onCollectionDiscovered( int protocol, const QString &collectionUrl, const QString &configuredUrl ); - void onEtagChanged( const QString &itemUrl, const QString &etag ); - - private: - void doItemChange( const Akonadi::Item &item, const Akonadi::Item::List &dependentItems = Akonadi::Item::List() ); - void doItemRemoval( const Akonadi::Item &item ); + void onItemAddedFinished(KJob *); + void onItemChangePrepared(KJob *); + void onItemChangedFinished(KJob *); + void onItemRemovalPrepared(KJob *); + void onItemRemovedFinished(KJob *); + + void onCollectionDiscovered(int protocol, const QString &collectionUrl, const QString &configuredUrl); + void onEtagChanged(const QString &itemUrl, const QString &etag); + void onConflictModifyJobFinished(KJob *job); + void onDeletedItemRecreated(KJob *job); + +private: + void doItemChange(const Akonadi::Item &item, const Akonadi::Item::List &dependentItems = Akonadi::Item::List()); + void doItemRemoval(const Akonadi::Item &item); + void handleConflict(const Akonadi::Item &localItem, + const Akonadi::Item::List &localDependentItems, + const DavItem &remoteItem, + bool isLocalRemoval, + int responseCode + ); bool configurationIsValid(); void retryAfterFailure(const QString &errorMessage); @@ -112,7 +120,7 @@ /** * Collections which only support one mime type have an icon indicating what they support. */ - static void setCollectionIcon( Akonadi::Collection &collection ); + static void setCollectionIcon(Akonadi::Collection &collection); Akonadi::Collection mDavCollectionRoot; EtagCache mEtagCache; diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/davprotocolattribute.cpp kdepim-runtime-15.08.0/resources/dav/resource/davprotocolattribute.cpp --- kdepim-runtime-4.14.6/resources/dav/resource/davprotocolattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/davprotocolattribute.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,38 +18,38 @@ #include "davprotocolattribute.h" -DavProtocolAttribute::DavProtocolAttribute( int protocol ) - : mDavProtocol( protocol ) +DavProtocolAttribute::DavProtocolAttribute(int protocol) + : mDavProtocol(protocol) { } int DavProtocolAttribute::davProtocol() const { - return mDavProtocol; + return mDavProtocol; } -void DavProtocolAttribute::setDavProtocol( int protocol ) +void DavProtocolAttribute::setDavProtocol(int protocol) { - mDavProtocol = protocol; + mDavProtocol = protocol; } -Akonadi::Attribute* DavProtocolAttribute::clone() const +Akonadi::Attribute *DavProtocolAttribute::clone() const { - return new DavProtocolAttribute( mDavProtocol ); + return new DavProtocolAttribute(mDavProtocol); } QByteArray DavProtocolAttribute::type() const { - static const QByteArray sType( "davprotocol" ); + static const QByteArray sType("davprotocol"); return sType; } QByteArray DavProtocolAttribute::serialized() const { - return QByteArray::number( mDavProtocol ); + return QByteArray::number(mDavProtocol); } -void DavProtocolAttribute::deserialize( const QByteArray &data ) +void DavProtocolAttribute::deserialize(const QByteArray &data) { - mDavProtocol = data.toInt(); + mDavProtocol = data.toInt(); } diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/davprotocolattribute.h kdepim-runtime-15.08.0/resources/dav/resource/davprotocolattribute.h --- kdepim-runtime-4.14.6/resources/dav/resource/davprotocolattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/davprotocolattribute.h 2015-08-10 21:01:02.000000000 +0000 @@ -19,24 +19,24 @@ #ifndef DAVPROTOCOLATTRIBUTE_H #define DAVPROTOCOLATTRIBUTE_H -#include +#include #include class DavProtocolAttribute : public Akonadi::Attribute { - public: - explicit DavProtocolAttribute( int protocol = 0 ); +public: + explicit DavProtocolAttribute(int protocol = 0); - void setDavProtocol( int protocol ); + void setDavProtocol(int protocol); int davProtocol() const; - virtual Akonadi::Attribute* clone() const; - virtual QByteArray type() const; - virtual QByteArray serialized() const; - virtual void deserialize( const QByteArray &data ); + Akonadi::Attribute *clone() const Q_DECL_OVERRIDE; + QByteArray type() const Q_DECL_OVERRIDE; + QByteArray serialized() const Q_DECL_OVERRIDE; + void deserialize(const QByteArray &data) Q_DECL_OVERRIDE; - private: +private: int mDavProtocol; }; diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/davresource_debug.cpp kdepim-runtime-15.08.0/resources/dav/resource/davresource_debug.cpp --- kdepim-runtime-4.14.6/resources/dav/resource/davresource_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/davresource_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 "davresource_debug.h" +Q_LOGGING_CATEGORY(DAVRESOURCE_LOG, "log_davresource") + diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/davresource_debug.h kdepim-runtime-15.08.0/resources/dav/resource/davresource_debug.h --- kdepim-runtime-4.14.6/resources/dav/resource/davresource_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/davresource_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 DAVRESOURCE_DEBUG_H +#define DAVRESOURCE_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(DAVRESOURCE_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/searchdialog.cpp kdepim-runtime-15.08.0/resources/dav/resource/searchdialog.cpp --- kdepim-runtime-4.14.6/resources/dav/resource/searchdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/searchdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,29 +24,41 @@ #include "davprotocolbase.h" #include "davutils.h" -#include -#include +#include "davresource_debug.h" +#include #include #include +#include -#include +#include +#include +#include + +SearchDialog::SearchDialog(QWidget *parent) + : QDialog(parent), mModel(new QStandardItemModel(this)), mSubJobCount(0) +{ + QWidget *mainWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); + mUi.setupUi(mainWidget); + mUi.credentialsGroup->setVisible(false); + mUi.searchResults->setModel(mModel); + + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); + okButton->setDefault(true); + okButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &SearchDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &SearchDialog::reject); + mainLayout->addWidget(buttonBox); + buttonBox->button(QDialogButtonBox::Ok)->setText(i18n("Add Selected Items")); + + connect(mUi.searchUrl, &KLineEdit::textChanged, this, &SearchDialog::checkUserInput); + connect(mUi.searchParam, &KLineEdit::textChanged, this, &SearchDialog::checkUserInput); + connect(mUi.searchButton, &QPushButton::clicked, this, &SearchDialog::search); -SearchDialog::SearchDialog( QWidget *parent ) - : KDialog( parent ), mModel( new QStandardItemModel( this ) ), mSubJobCount( 0 ) -{ - mUi.setupUi( mainWidget() ); - mUi.credentialsGroup->setVisible( false ); - mUi.searchResults->setModel( mModel ); - - setButtonFocus( KDialog::None ); - setDefaultButton( KDialog::None ); - setButtonText( KDialog::Ok, i18n( "Add selected items" ) ); - - connect( mUi.searchUrl, SIGNAL(textChanged(QString)), this, SLOT(checkUserInput()) ); - connect( mUi.searchParam, SIGNAL(textChanged(QString)), this, SLOT(checkUserInput()) ); - connect( mUi.searchButton, SIGNAL(clicked()), this, SLOT(search()) ); - - checkUserInput(); + checkUserInput(); } SearchDialog::~SearchDialog() @@ -55,139 +67,146 @@ bool SearchDialog::useDefaultCredentials() const { - return mUi.useDefaultCreds->isChecked(); + return mUi.useDefaultCreds->isChecked(); } -void SearchDialog::setUsername( const QString& user ) +void SearchDialog::setUsername(const QString &user) { - mUi.username->setText( user ); + mUi.username->setText(user); } QString SearchDialog::username() const { - return mUi.username->text(); + return mUi.username->text(); } -void SearchDialog::setPassword( const QString& password ) +void SearchDialog::setPassword(const QString &password) { - mUi.password->setText( password ); + mUi.password->setText(password); } QString SearchDialog::password() const { - return mUi.password->text(); + return mUi.password->text(); } QStringList SearchDialog::selection() const { - QModelIndexList indexes = mUi.searchResults->selectionModel()->selectedIndexes(); - QStringList ret; - foreach ( const QModelIndex &index, indexes ) { - kError() << "SELECTED DATA: " << index.data( Qt::UserRole + 1 ).toString(); - ret << index.data( Qt::UserRole + 1 ).toString(); - } - return ret; + QModelIndexList indexes = mUi.searchResults->selectionModel()->selectedIndexes(); + QStringList ret; + ret.reserve(indexes.count()); + foreach (const QModelIndex &index, indexes) { + qCritical() << "SELECTED DATA: " << index.data(Qt::UserRole + 1).toString(); + ret << index.data(Qt::UserRole + 1).toString(); + } + return ret; } void SearchDialog::checkUserInput() { - if ( mUi.searchUrl->text().isEmpty() || mUi.searchParam->text().isEmpty() ) - mUi.searchButton->setEnabled( false ); - else - mUi.searchButton->setEnabled( true ); + if (mUi.searchUrl->text().isEmpty() || mUi.searchParam->text().isEmpty()) { + mUi.searchButton->setEnabled(false); + } else { + mUi.searchButton->setEnabled(true); + } } void SearchDialog::search() { - mUi.searchResults->setEnabled( false ); - mModel->clear(); - DavPrincipalSearchJob::FilterType filter; + mUi.searchResults->setEnabled(false); + mModel->clear(); + DavPrincipalSearchJob::FilterType filter; - if ( mUi.searchType->currentIndex() == 0 ) - filter = DavPrincipalSearchJob::DisplayName; - else - filter = DavPrincipalSearchJob::EmailAddress; + if (mUi.searchType->currentIndex() == 0) { + filter = DavPrincipalSearchJob::DisplayName; + } else { + filter = DavPrincipalSearchJob::EmailAddress; + } - KUrl url( mUi.searchUrl->text() ); - url.setUser( mUi.username->text() ); - url.setPassword( mUi.password->text() ); - DavUtils::DavUrl davUrl; - davUrl.setUrl( url ); + KUrl url(mUi.searchUrl->text()); + url.setUser(mUi.username->text()); + url.setPassword(mUi.password->text()); + DavUtils::DavUrl davUrl; + davUrl.setUrl(url); - DavPrincipalSearchJob *job = new DavPrincipalSearchJob( davUrl, filter, mUi.searchParam->text() ); + DavPrincipalSearchJob *job = new DavPrincipalSearchJob(davUrl, filter, mUi.searchParam->text()); - const DavProtocolBase *proto = DavManager::self()->davProtocol( DavUtils::CalDav ); - job->fetchProperty( proto->principalHomeSet(), proto->principalHomeSetNS() ); + const DavProtocolBase *proto = DavManager::self()->davProtocol(DavUtils::CalDav); + job->fetchProperty(proto->principalHomeSet(), proto->principalHomeSetNS()); - proto = DavManager::self()->davProtocol( DavUtils::CardDav ); - job->fetchProperty( proto->principalHomeSet(), proto->principalHomeSetNS() ); + proto = DavManager::self()->davProtocol(DavUtils::CardDav); + job->fetchProperty(proto->principalHomeSet(), proto->principalHomeSetNS()); - connect( job, SIGNAL(result(KJob*)), this, SLOT(onSearchJobFinished(KJob*)) ); - job->start(); + connect(job, &DavPrincipalSearchJob::result, this, &SearchDialog::onSearchJobFinished); + job->start(); } -void SearchDialog::onSearchJobFinished( KJob* job ) +void SearchDialog::onSearchJobFinished(KJob *job) { - if ( job->error() ) { - KMessageBox::error( this, i18n( "An error occurred when executing search:\n%1", job->errorText() ) ); - return; - } + if (job->error()) { + KMessageBox::error(this, i18n("An error occurred when executing search:\n%1", job->errorText())); + return; + } - DavPrincipalSearchJob *davJob = qobject_cast( job ); - QList results = davJob->results(); + DavPrincipalSearchJob *davJob = qobject_cast(job); + QList results = davJob->results(); - const DavProtocolBase *caldav = DavManager::self()->davProtocol( DavUtils::CalDav ); - DavUtils::DavUrl davUrl = davJob->davUrl(); - KUrl url = davUrl.url(); + const DavProtocolBase *caldav = DavManager::self()->davProtocol(DavUtils::CalDav); + DavUtils::DavUrl davUrl = davJob->davUrl(); + KUrl url = davUrl.url(); + + foreach (const DavPrincipalSearchJob::Result &result, results) { + if (result.value.startsWith(QLatin1Char('/'))) { + url.setPath(result.value); + } else { + KUrl tmp(result.value); + tmp.setUser(url.user()); + tmp.setPassword(url.password()); + url = tmp; + } + davUrl.setUrl(url); + + if (result.property == caldav->principalHomeSet()) { + davUrl.setProtocol(DavUtils::CalDav); + } else { + davUrl.setProtocol(DavUtils::CardDav); + } + + DavCollectionsFetchJob *fetchJob = new DavCollectionsFetchJob(davUrl); + connect(fetchJob, &DavCollectionsFetchJob::result, this, &SearchDialog::onCollectionsFetchJobFinished); + fetchJob->start(); + ++mSubJobCount; + } +} - foreach ( const DavPrincipalSearchJob::Result &result, results ) { - if ( result.value.startsWith( QLatin1Char('/') ) ) { - url.setPath( result.value ); - } else { - KUrl tmp( result.value ); - tmp.setUser( url.user() ); - tmp.setPassword( url.password() ); - url = tmp; - } - davUrl.setUrl( url ); - - if ( result.property == caldav->principalHomeSet() ) - davUrl.setProtocol( DavUtils::CalDav ); - else - davUrl.setProtocol( DavUtils::CardDav ); - - DavCollectionsFetchJob *fetchJob = new DavCollectionsFetchJob( davUrl ); - connect( fetchJob, SIGNAL(result(KJob*)), this, SLOT(onCollectionsFetchJobFinished(KJob*)) ); - fetchJob->start(); - ++mSubJobCount; - } -} - -void SearchDialog::onCollectionsFetchJobFinished( KJob* job ) -{ - --mSubJobCount; - - if ( mSubJobCount == 0 ) - mUi.searchResults->setEnabled( true ); - - if ( job->error() ) { - if ( mSubJobCount == 0 ) - KMessageBox::error( this, i18n( "An error occurred when executing search:\n%1", job->errorText() ) ); - return; - } - - DavCollectionsFetchJob *davJob = qobject_cast( job ); - DavCollection::List collections = davJob->collections(); - - foreach ( const DavCollection &collection, collections ) { - QStandardItem *item = new QStandardItem( collection.displayName() ); - QString data( DavUtils::protocolName( collection.protocol() ) + QLatin1Char('|') + collection.url() ); - item->setData( data, Qt::UserRole + 1 ); - item->setToolTip( collection.url() ); - if ( collection.protocol() == DavUtils::CalDav ) - item->setIcon( KIcon( QLatin1String("view-calendar") ) ); - else - item->setIcon( KIcon( QLatin1String("view-pim-contacts" )) ); - mModel->appendRow( item ); - } +void SearchDialog::onCollectionsFetchJobFinished(KJob *job) +{ + --mSubJobCount; + + if (mSubJobCount == 0) { + mUi.searchResults->setEnabled(true); + } + + if (job->error()) { + if (mSubJobCount == 0) { + KMessageBox::error(this, i18n("An error occurred when executing search:\n%1", job->errorText())); + } + return; + } + + DavCollectionsFetchJob *davJob = qobject_cast(job); + DavCollection::List collections = davJob->collections(); + + foreach (const DavCollection &collection, collections) { + QStandardItem *item = new QStandardItem(collection.displayName()); + QString data(DavUtils::protocolName(collection.protocol()) + QLatin1Char('|') + collection.url()); + item->setData(data, Qt::UserRole + 1); + item->setToolTip(collection.url()); + if (collection.protocol() == DavUtils::CalDav) { + item->setIcon(QIcon::fromTheme(QStringLiteral("view-calendar"))); + } else { + item->setIcon(QIcon::fromTheme(QStringLiteral("view-pim-contacts"))); + } + mModel->appendRow(item); + } } diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/searchdialog.h kdepim-runtime-15.08.0/resources/dav/resource/searchdialog.h --- kdepim-runtime-4.14.6/resources/dav/resource/searchdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/searchdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -1,16 +1,16 @@ /* * Copyright (c) 2011 Grégory Oestreicher - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @@ -21,36 +21,36 @@ #include "ui_searchdialog.h" -#include +#include class KJob; class QStandardItemModel; -class SearchDialog : public KDialog +class SearchDialog : public QDialog { - Q_OBJECT + Q_OBJECT - public: - explicit SearchDialog( QWidget *parent = 0 ); +public: + explicit SearchDialog(QWidget *parent = Q_NULLPTR); virtual ~SearchDialog(); bool useDefaultCredentials() const; - void setUsername( const QString &user ); + void setUsername(const QString &user); QString username() const; - void setPassword( const QString &password ); + void setPassword(const QString &password); QString password() const; QStringList selection() const; - private Q_SLOTS: +private Q_SLOTS: void checkUserInput(); void search(); - void onSearchJobFinished( KJob *job ); - void onCollectionsFetchJobFinished( KJob *job ); + void onSearchJobFinished(KJob *job); + void onCollectionsFetchJobFinished(KJob *job); - private: +private: Ui::SearchDialog mUi; QStandardItemModel *mModel; int mSubJobCount; diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/settings.cpp kdepim-runtime-15.08.0/resources/dav/resource/settings.cpp --- kdepim-runtime-4.14.6/resources/dav/resource/settings.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/settings.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,16 +23,14 @@ #include "settingsadaptor.h" #ifdef HAVE_ACCOUNTS -#include "../shared/getcredentialsjob.h" +#include "../../shared/singlefileresource/getcredentialsjob.h" #endif #include -#include -#include -#include +#include "davresource_debug.h" #include -#include -#include +#include + #include #include @@ -41,200 +39,223 @@ #include #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include #ifdef HAVE_ACCOUNTS #include #include +#include #endif class SettingsHelper { - public: +public: SettingsHelper() - : q( 0 ) + : q(Q_NULLPTR) { } ~SettingsHelper() { - delete q; + delete q; } Settings *q; }; -K_GLOBAL_STATIC( SettingsHelper, s_globalSettings ) +Q_GLOBAL_STATIC(SettingsHelper, s_globalSettings) Settings::UrlConfiguration::UrlConfiguration() { } -Settings::UrlConfiguration::UrlConfiguration( const QString &serialized ) +Settings::UrlConfiguration::UrlConfiguration(const QString &serialized) { - const QStringList splitString = serialized.split( QLatin1Char('|') ); + const QStringList splitString = serialized.split(QLatin1Char('|')); - if ( splitString.size() == 3 ) { - mUrl = splitString.at( 2 ); - mProtocol = DavUtils::protocolByName( splitString.at( 1 ) ); - mUser = splitString.at( 0 ); - } + if (splitString.size() == 3) { + mUrl = splitString.at(2); + mProtocol = DavUtils::protocolByName(splitString.at(1)); + mUser = splitString.at(0); + } } QString Settings::UrlConfiguration::serialize() { - QString serialized = mUser; - serialized.append( QLatin1Char('|') ).append( DavUtils::protocolName( DavUtils::Protocol( mProtocol ) ) ); - serialized.append( QLatin1Char('|') ).append( mUrl ); - return serialized; + QString serialized = mUser; + serialized.append(QLatin1Char('|')).append(DavUtils::protocolName(DavUtils::Protocol(mProtocol))); + serialized.append(QLatin1Char('|')).append(mUrl); + return serialized; } Settings *Settings::self() { - if ( !s_globalSettings->q ) { - new Settings; - s_globalSettings->q->readConfig(); - } + if (!s_globalSettings->q) { + new Settings; + s_globalSettings->q->load(); + } - return s_globalSettings->q; + return s_globalSettings->q; } Settings::Settings() - : SettingsBase(), mWinId( 0 ) + : SettingsBase(), mWinId(0) { #ifdef HAVE_ACCOUNTS - m_manager = 0; + m_manager = 0; #endif - Q_ASSERT( !s_globalSettings->q ); - s_globalSettings->q = this; + Q_ASSERT(!s_globalSettings->q); + s_globalSettings->q = this; - new SettingsAdaptor( this ); - QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ), this, - QDBusConnection::ExportAdaptors | QDBusConnection::ExportScriptableContents ); + new SettingsAdaptor(this); + QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"), this, + QDBusConnection::ExportAdaptors | QDBusConnection::ExportScriptableContents); - if ( settingsVersion() == 1 ) - updateToV2(); + if (settingsVersion() == 1) { + updateToV2(); + } - if ( settingsVersion() == 2 ) - updateToV3(); + if (settingsVersion() == 2) { + updateToV3(); + } } Settings::~Settings() { - QMapIterator it( mUrls ); - while ( it.hasNext() ) { - it.next(); - delete it.value(); - } + QMapIterator it(mUrls); + while (it.hasNext()) { + it.next(); + delete it.value(); + } } -void Settings::setWinId( WId winId ) +void Settings::setWinId(WId winId) { - mWinId = winId; + mWinId = winId; } void Settings::cleanup() { - QFile cacheFile( mCollectionsUrlsMappingCache ); - cacheFile.remove(); + KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), mWinId); + if (wallet && wallet->isOpen()) { + if (wallet->hasFolder(KWallet::Wallet::PasswordFolder())) { + wallet->setFolder(KWallet::Wallet::PasswordFolder()); + const QString entry = mResourceIdentifier + QLatin1Char(',') + QStringLiteral("$default$"); + wallet->removeEntry(entry); + } + delete wallet; + } + QFile cacheFile(mCollectionsUrlsMappingCache); + cacheFile.remove(); } -void Settings::setResourceIdentifier(const QString& identifier) +void Settings::setResourceIdentifier(const QString &identifier) { - mResourceIdentifier = identifier; + mResourceIdentifier = identifier; } -void Settings::setDefaultPassword( const QString &password ) +void Settings::setDefaultPassword(const QString &password) { - savePassword( mResourceIdentifier, QLatin1String("$default$"), password ); + savePassword(mResourceIdentifier, QStringLiteral("$default$"), password); } QString Settings::defaultPassword() { - return loadPassword( mResourceIdentifier, QLatin1String("$default$") ); + return loadPassword(mResourceIdentifier, QStringLiteral("$default$")); } DavUtils::DavUrl::List Settings::configuredDavUrls() { - if ( mUrls.isEmpty() ) - buildUrlsList(); - DavUtils::DavUrl::List davUrls; - QMapIterator it( mUrls ); + if (mUrls.isEmpty()) { + buildUrlsList(); + } + DavUtils::DavUrl::List davUrls; + davUrls.reserve(mUrls.count()); + QMapIterator it(mUrls); - while ( it.hasNext() ) { - it.next(); - QStringList split = it.key().split( QLatin1Char(',') ); - davUrls << configuredDavUrl( DavUtils::protocolByName( split.at( 1 ) ), split.at( 0 ) ); - } + while (it.hasNext()) { + it.next(); + QStringList split = it.key().split(QLatin1Char(',')); + davUrls << configuredDavUrl(DavUtils::protocolByName(split.at(1)), split.at(0)); + } - return davUrls; + return davUrls; } -DavUtils::DavUrl Settings::configuredDavUrl( DavUtils::Protocol proto, const QString &searchUrl, const QString &finalUrl ) +DavUtils::DavUrl Settings::configuredDavUrl(DavUtils::Protocol proto, const QString &searchUrl, const QString &finalUrl) { - if ( mUrls.isEmpty() ) - buildUrlsList(); + if (mUrls.isEmpty()) { + buildUrlsList(); + } - KUrl fullUrl; + KUrl fullUrl; - if ( !finalUrl.isEmpty() ) - fullUrl = finalUrl; - else - fullUrl = searchUrl; + if (!finalUrl.isEmpty()) { + fullUrl = finalUrl; + } else { + fullUrl = searchUrl; + } - const QString user = username( proto, searchUrl ); - fullUrl.setUser( user ); - fullUrl.setPassword( password( proto, searchUrl ) ); + const QString user = username(proto, searchUrl); + fullUrl.setUser(user); + fullUrl.setPassword(password(proto, searchUrl)); - return DavUtils::DavUrl( fullUrl, proto ); + return DavUtils::DavUrl(fullUrl, proto); } -DavUtils::DavUrl Settings::davUrlFromCollectionUrl( const QString &collectionUrl, const QString &finalUrl ) +DavUtils::DavUrl Settings::davUrlFromCollectionUrl(const QString &collectionUrl, const QString &finalUrl) { - if ( mCollectionsUrlsMapping.isEmpty() ) - loadMappings(); + if (mCollectionsUrlsMapping.isEmpty()) { + loadMappings(); + } - DavUtils::DavUrl davUrl; - QString targetUrl = finalUrl.isEmpty() ? collectionUrl : finalUrl; + DavUtils::DavUrl davUrl; + QString targetUrl = finalUrl.isEmpty() ? collectionUrl : finalUrl; - if ( mCollectionsUrlsMapping.contains( collectionUrl ) ) { - QStringList split = mCollectionsUrlsMapping[ collectionUrl ].split( QLatin1Char(',') ); - if ( split.size() == 2 ) - davUrl = configuredDavUrl( DavUtils::protocolByName( split.at( 1 ) ), split.at( 0 ), targetUrl ); - } + if (mCollectionsUrlsMapping.contains(collectionUrl)) { + QStringList split = mCollectionsUrlsMapping[ collectionUrl ].split(QLatin1Char(',')); + if (split.size() == 2) { + davUrl = configuredDavUrl(DavUtils::protocolByName(split.at(1)), split.at(0), targetUrl); + } + } - return davUrl; + return davUrl; } -void Settings::addCollectionUrlMapping( DavUtils::Protocol proto, const QString &collectionUrl, const QString &configuredUrl ) +void Settings::addCollectionUrlMapping(DavUtils::Protocol proto, const QString &collectionUrl, const QString &configuredUrl) { - if ( mCollectionsUrlsMapping.isEmpty() ) - loadMappings(); + if (mCollectionsUrlsMapping.isEmpty()) { + loadMappings(); + } - QString value = configuredUrl + QLatin1Char(',') + DavUtils::protocolName( proto ); - mCollectionsUrlsMapping.insert( collectionUrl, value ); + QString value = configuredUrl + QLatin1Char(',') + DavUtils::protocolName(proto); + mCollectionsUrlsMapping.insert(collectionUrl, value); - // Update the cache now - //QMap tmp( mCollectionsUrlsMapping ); - QFile cacheFile( mCollectionsUrlsMappingCache ); - if ( cacheFile.open( QIODevice::WriteOnly ) ) { - QDataStream cache( &cacheFile ); - cache.setVersion( QDataStream::Qt_4_7 ); - cache << mCollectionsUrlsMapping; - cacheFile.close(); - } + // Update the cache now + //QMap tmp( mCollectionsUrlsMapping ); + QFile cacheFile(mCollectionsUrlsMappingCache); + if (cacheFile.open(QIODevice::WriteOnly)) { + QDataStream cache(&cacheFile); + cache.setVersion(QDataStream::Qt_4_7); + cache << mCollectionsUrlsMapping; + cacheFile.close(); + } } -QStringList Settings::mappedCollections( DavUtils::Protocol proto, const QString &configuredUrl ) +QStringList Settings::mappedCollections(DavUtils::Protocol proto, const QString &configuredUrl) { - if ( mCollectionsUrlsMapping.isEmpty() ) - loadMappings(); + if (mCollectionsUrlsMapping.isEmpty()) { + loadMappings(); + } - QString value = configuredUrl + QLatin1Char(',') + DavUtils::protocolName( proto ); - return mCollectionsUrlsMapping.keys( value ); + QString value = configuredUrl + QLatin1Char(',') + DavUtils::protocolName(proto); + return mCollectionsUrlsMapping.keys(value); } void Settings::reloadConfig() @@ -247,41 +268,44 @@ loadMappings(); } -void Settings::newUrlConfiguration( Settings::UrlConfiguration *urlConfig ) +void Settings::newUrlConfiguration(Settings::UrlConfiguration *urlConfig) { - QString key = urlConfig->mUrl + QLatin1Char(',') + DavUtils::protocolName( DavUtils::Protocol( urlConfig->mProtocol ) ); + QString key = urlConfig->mUrl + QLatin1Char(',') + DavUtils::protocolName(DavUtils::Protocol(urlConfig->mProtocol)); - if ( mUrls.contains( key ) ) { - removeUrlConfiguration( DavUtils::Protocol( urlConfig->mProtocol ), urlConfig->mUrl ); - } + if (mUrls.contains(key)) { + removeUrlConfiguration(DavUtils::Protocol(urlConfig->mProtocol), urlConfig->mUrl); + } - mUrls[ key ] = urlConfig; - if ( urlConfig->mUser != QLatin1String( "$default$" ) ) - savePassword( key, urlConfig->mUser, urlConfig->mPassword ); - updateRemoteUrls(); + mUrls[ key ] = urlConfig; + if (urlConfig->mUser != QStringLiteral("$default$")) { + savePassword(key, urlConfig->mUser, urlConfig->mPassword); + } + updateRemoteUrls(); } -void Settings::removeUrlConfiguration( DavUtils::Protocol proto, const QString &url ) +void Settings::removeUrlConfiguration(DavUtils::Protocol proto, const QString &url) { - QString key = url + QLatin1Char(',') + DavUtils::protocolName( proto ); + QString key = url + QLatin1Char(',') + DavUtils::protocolName(proto); - if ( !mUrls.contains( key ) ) - return; + if (!mUrls.contains(key)) { + return; + } - delete mUrls[ key ]; - mUrls.remove( key ); - updateRemoteUrls(); + delete mUrls[ key ]; + mUrls.remove(key); + updateRemoteUrls(); } -Settings::UrlConfiguration * Settings::urlConfiguration( DavUtils::Protocol proto, const QString &url ) +Settings::UrlConfiguration *Settings::urlConfiguration(DavUtils::Protocol proto, const QString &url) { - QString key = url + QLatin1Char(',') + DavUtils::protocolName( proto ); + QString key = url + QLatin1Char(',') + DavUtils::protocolName(proto); - UrlConfiguration *ret = 0; - if ( mUrls.contains( key ) ) - ret = mUrls[ key ]; + UrlConfiguration *ret = Q_NULLPTR; + if (mUrls.contains(key)) { + ret = mUrls[ key ]; + } - return ret; + return ret; } // DavUtils::Protocol Settings::protocol( const QString &url ) const @@ -292,237 +316,254 @@ // return DavUtils::CalDav; // } -QString Settings::username( DavUtils::Protocol proto, const QString &url ) const +QString Settings::username(DavUtils::Protocol proto, const QString &url) const { - QString key = url + QLatin1Char(',') + DavUtils::protocolName( proto ); + QString key = url + QLatin1Char(',') + DavUtils::protocolName(proto); - if ( mUrls.contains( key ) ) - if ( mUrls[ key ]->mUser == QLatin1String( "$default$" ) ) - return defaultUsername(); + if (mUrls.contains(key)) + if (mUrls[ key ]->mUser == QLatin1String("$default$")) { + return defaultUsername(); + } #ifdef HAVE_ACCOUNTS - else if ( mUrls[ key ]->mUser == QLatin1String( "$accounts$" ) ) - return accountsUsername(); + else if (mUrls[ key ]->mUser == QLatin1String("$accounts$")) { + return accountsUsername(); + } #endif - else - return mUrls[ key ]->mUser; - else - return QString(); -} - -QString Settings::password(DavUtils::Protocol proto, const QString& url) -{ - QString key = url + QLatin1Char(',') + DavUtils::protocolName( proto ); - - if ( mUrls.contains( key ) ) - if ( mUrls[ key ]->mUser == QLatin1String( "$default$" ) ) - return defaultPassword(); - else - return mUrls[ key ]->mPassword; - else - return QString(); + else { + return mUrls[ key ]->mUser; + } + else { + return QString(); + } +} + +QString Settings::password(DavUtils::Protocol proto, const QString &url) +{ + QString key = url + QLatin1Char(',') + DavUtils::protocolName(proto); + + if (mUrls.contains(key)) + if (mUrls[ key ]->mUser == QLatin1String("$default$")) { + return defaultPassword(); + } else { + return mUrls[ key ]->mPassword; + } + else { + return QString(); + } } #ifdef HAVE_ACCOUNTS void Settings::importFromAccounts() { - kDebug(); - Accounts::AccountId id = accountId(); - kDebug() << "Account Id: " << id; - - if ( !m_manager ) { - m_manager = new Accounts::Manager( this ); - } - - if ( !m_manager->accountList().contains( id ) ) { - return; - } + qCDebug(DAVRESOURCE_LOG); + Accounts::AccountId id = accountId(); + qCDebug(DAVRESOURCE_LOG) << "Account Id: " << id; - removeAccountsDisabledServices(); - addAccountsEnabledServices(); + if (!m_manager) { + m_manager = new Accounts::Manager(this); + } + + if (!m_manager->accountList().contains(id)) { + return; + } + + removeAccountsDisabledServices(); + addAccountsEnabledServices(); - setSettingsVersion( 3 ); - writeConfig(); + setSettingsVersion(3); + writeConfig(); } void Settings::addAccountsEnabledServices() { - kDebug(); - Accounts::Account *acc = m_manager->account( accountId() ); - QStringList enabledServices = accountServices(); - kDebug() << "Enabled" << enabledServices; - foreach( QString serviceType, enabledServices ) { - Accounts::ServiceList services = acc->services( serviceType ); - foreach( const Accounts::Service &service, services ) { - configureAccountService( acc, service ); + qCDebug(DAVRESOURCE_LOG); + Accounts::Account *acc = m_manager->account(accountId()); + QStringList enabledServices = accountServices(); + qCDebug(DAVRESOURCE_LOG) << "Enabled" << enabledServices; + foreach (QString serviceType, enabledServices) { + Accounts::ServiceList services = acc->services(serviceType); + foreach (const Accounts::Service &service, services) { + configureAccountService(acc, service); + } } - } } void Settings::removeAccountsDisabledServices() { - kDebug(); - QStringList urls = remoteUrls(); - for (int i = 0; i < urls.size(); ++i) { - if ( !urls.at( i ).startsWith( "$accounts$" ) ) { - continue; - } + qCDebug(DAVRESOURCE_LOG); + QStringList urls = remoteUrls(); + for (int i = 0; i < urls.size(); ++i) { + if (!urls.at(i).startsWith("$accounts$")) { + continue; + } - if (urls.at( i ).contains( "carddav" ) - && accountServices().contains( "dav-contacts" )) { - continue; - } - if (urls.at( i ).contains( "caldav" ) - && accountServices().contains( "dav-calendar" )) { - continue; - } + if (urls.at(i).contains("carddav") + && accountServices().contains("dav-contacts")) { + continue; + } + if (urls.at(i).contains("caldav") + && accountServices().contains("dav-calendar")) { + continue; + } - urls.removeAt( i ); - } + urls.removeAt(i); + } - setRemoteUrls( urls ); + setRemoteUrls(urls); } -void Settings::configureAccountService(Accounts::Account *acc, const Accounts::Service& service) +void Settings::configureAccountService(Accounts::Account *acc, const Accounts::Service &service) { - kDebug() << "Configuring service: " << service.name(); + qCDebug(DAVRESOURCE_LOG) << "Configuring service: " << service.name(); - acc->selectService(); - QString domain = acc->valueAsString( "dav/scheme" ) + "://" + acc->valueAsString( "dav/host" ); - acc->selectService( service ); + acc->selectService(); + QString domain = acc->valueAsString("dav/scheme") + "://" + acc->valueAsString("dav/host"); + acc->selectService(service); - QString type; - if ( service.serviceType() == "dav-contacts" ) { - type = "CardDav"; - } else { - type = "CalDav"; - } + QString type; + if (service.serviceType() == "dav-contacts") { + type = "CardDav"; + } else { + type = "CalDav"; + } - QString url = "$accounts$|" + type + "|" + domain + acc->valueAsString("dav/path"); - kDebug() << url; - acc->selectService(); + QString url = "$accounts$|" + type + "|" + domain + acc->valueAsString("dav/path"); + qCDebug(DAVRESOURCE_LOG) << url; + acc->selectService(); - QStringList urls = remoteUrls(); - foreach ( const QString &serializedUrl, urls ) { - if ( url == serializedUrl ) { - kDebug() << "Url already configured"; - return; + QStringList urls = remoteUrls(); + foreach (const QString &serializedUrl, urls) { + if (url == serializedUrl) { + qCDebug(DAVRESOURCE_LOG) << "Url already configured"; + return; + } } - } - kDebug() << "Adding url"; - urls.append( url ); - setRemoteUrls( urls ); + qCDebug(DAVRESOURCE_LOG) << "Adding url"; + urls.append(url); + setRemoteUrls(urls); } #endif void Settings::buildUrlsList() { - foreach ( const QString &serializedUrl, remoteUrls() ) { - UrlConfiguration *urlConfig = new UrlConfiguration( serializedUrl ); - QString key = urlConfig->mUrl + QLatin1Char(',') + DavUtils::protocolName( DavUtils::Protocol( urlConfig->mProtocol ) ); - QString pass = loadPassword( key, urlConfig->mUser ); - if ( !pass.isNull() ) { - urlConfig->mPassword = pass; - mUrls[ key ] = urlConfig; + foreach (const QString &serializedUrl, remoteUrls()) { + UrlConfiguration *urlConfig = new UrlConfiguration(serializedUrl); + QString key = urlConfig->mUrl + QLatin1Char(',') + DavUtils::protocolName(DavUtils::Protocol(urlConfig->mProtocol)); + QString pass = loadPassword(key, urlConfig->mUser); + if (!pass.isNull()) { + urlConfig->mPassword = pass; + mUrls[ key ] = urlConfig; + } } - } } void Settings::loadMappings() { - QString collectionsMappingCacheBase = QString::fromLatin1( "akonadi-davgroupware/%1_c2u.dat" ).arg( KApplication::applicationName() ); - mCollectionsUrlsMappingCache = KStandardDirs::locateLocal( "data", collectionsMappingCacheBase ); - QFile collectionsMappingsCache( mCollectionsUrlsMappingCache ); - - if ( collectionsMappingsCache.exists() ) { - if ( collectionsMappingsCache.open( QIODevice::ReadOnly ) ) { - QDataStream cache( &collectionsMappingsCache ); - cache >> mCollectionsUrlsMapping; - collectionsMappingsCache.close(); - } - } else if ( !collectionsUrlsMappings().isEmpty() ) { - QByteArray rawMappings = QByteArray::fromBase64( collectionsUrlsMappings().toLatin1() ); - QDataStream stream( &rawMappings, QIODevice::ReadOnly ); - stream >> mCollectionsUrlsMapping; - setCollectionsUrlsMappings( QString() ); - } + QString collectionsMappingCacheBase = QStringLiteral("akonadi-davgroupware/%1_c2u.dat").arg(KApplication::applicationName()); + mCollectionsUrlsMappingCache = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + collectionsMappingCacheBase ; + QFile collectionsMappingsCache(mCollectionsUrlsMappingCache); + + if (collectionsMappingsCache.exists()) { + if (collectionsMappingsCache.open(QIODevice::ReadOnly)) { + QDataStream cache(&collectionsMappingsCache); + cache >> mCollectionsUrlsMapping; + collectionsMappingsCache.close(); + } + } else if (!collectionsUrlsMappings().isEmpty()) { + QByteArray rawMappings = QByteArray::fromBase64(collectionsUrlsMappings().toLatin1()); + QDataStream stream(&rawMappings, QIODevice::ReadOnly); + stream >> mCollectionsUrlsMapping; + setCollectionsUrlsMappings(QString()); + } } void Settings::updateRemoteUrls() { - QStringList newUrls; + QStringList newUrls; + newUrls.reserve(mUrls.count()); - QMapIterator it( mUrls ); - while ( it.hasNext() ) { - it.next(); - newUrls << it.value()->serialize(); - } + QMapIterator it(mUrls); + while (it.hasNext()) { + it.next(); + newUrls << it.value()->serialize(); + } - setRemoteUrls( newUrls ); + setRemoteUrls(newUrls); } -void Settings::savePassword( const QString &key, const QString &user, const QString &password ) +void Settings::savePassword(const QString &key, const QString &user, const QString &password) { - QString entry = key + QLatin1Char(',') + user; - mPasswordsCache[entry] = password; + QString entry = key + QLatin1Char(',') + user; + mPasswordsCache[entry] = password; - KWallet::Wallet *wallet = KWallet::Wallet::openWallet( KWallet::Wallet::NetworkWallet(), mWinId ); - if ( !wallet ) - return; + KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), mWinId); + if (!wallet) { + return; + } - if ( !wallet->hasFolder( KWallet::Wallet::PasswordFolder() ) ) - wallet->createFolder( KWallet::Wallet::PasswordFolder() ); + if (!wallet->hasFolder(KWallet::Wallet::PasswordFolder())) { + wallet->createFolder(KWallet::Wallet::PasswordFolder()); + } - if ( !wallet->setFolder( KWallet::Wallet::PasswordFolder() ) ) - return; + if (!wallet->setFolder(KWallet::Wallet::PasswordFolder())) { + return; + } - wallet->writePassword( entry, password ); + wallet->writePassword(entry, password); } -QString Settings::loadPassword( const QString &key, const QString &user ) +QString Settings::loadPassword(const QString &key, const QString &user) { - QString entry; - QString pass; + QString entry; + QString pass; - if ( user == QLatin1String( "$default$" ) ) - entry = mResourceIdentifier + QLatin1Char(',') + user; + if (user == QLatin1String("$default$")) { + entry = mResourceIdentifier + QLatin1Char(',') + user; + } #ifdef HAVE_ACCOUNTS - else if (user == QLatin1String( "$accounts$" )) - return loadPasswordFromAccounts(); + else if (user == QLatin1String("$accounts$")) { + return loadPasswordFromAccounts(); + } #endif - else - entry = key + QLatin1Char(',') + user; + else { + entry = key + QLatin1Char(',') + user; + } + + if (mPasswordsCache.contains(entry)) { + return mPasswordsCache[entry]; + } - if ( mPasswordsCache.contains( entry ) ) - return mPasswordsCache[entry]; + KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), mWinId); + if (wallet) { + if (!wallet->hasFolder(KWallet::Wallet::PasswordFolder())) { + wallet->createFolder(KWallet::Wallet::PasswordFolder()); + } - KWallet::Wallet *wallet = KWallet::Wallet::openWallet( KWallet::Wallet::NetworkWallet(), mWinId ); - if ( wallet ) { - if ( !wallet->hasFolder( KWallet::Wallet::PasswordFolder() ) ) - wallet->createFolder( KWallet::Wallet::PasswordFolder() ); - - if ( wallet->setFolder( KWallet::Wallet::PasswordFolder() ) ) { - if ( !wallet->hasEntry( entry ) ) { - pass = promptForPassword( user ); - wallet->writePassword( entry, pass ); - } else { - wallet->readPassword( entry, pass ); - } - } - } + if (wallet->setFolder(KWallet::Wallet::PasswordFolder())) { + if (!wallet->hasEntry(entry)) { + pass = promptForPassword(user); + wallet->writePassword(entry, pass); + } else { + wallet->readPassword(entry, pass); + } + } + } - if ( pass.isNull() && !KWallet::Wallet::isEnabled() ) - pass = promptForPassword( user ); + if (pass.isNull() && !KWallet::Wallet::isEnabled()) { + pass = promptForPassword(user); + } - if ( !pass.isNull() ) - mPasswordsCache[entry] = pass; + if (!pass.isNull()) { + mPasswordsCache[entry] = pass; + } - return pass; + return pass; } #ifdef HAVE_ACCOUNTS QString Settings::loadPasswordFromAccounts() { - kDebug() << "Getting credentials for: " << accountId(); + qCDebug(DAVRESOURCE_LOG) << "Getting credentials for: " << accountId(); GetCredentialsJob *job = new GetCredentialsJob(accountId()); job->exec(); @@ -531,94 +572,106 @@ QString Settings::accountsUsername() const { - kDebug() << "Getting credentials for: " << accountId(); + qCDebug(DAVRESOURCE_LOG) << "Getting credentials for: " << accountId(); GetCredentialsJob *job = new GetCredentialsJob(accountId()); job->exec(); - kDebug() << "Got some: " << job->credentialsData(); + qCDebug(DAVRESOURCE_LOG) << "Got some: " << job->credentialsData(); return job->credentialsData().value("UserName").toString(); } #endif -QString Settings::promptForPassword( const QString &user ) +QString Settings::promptForPassword(const QString &user) { - QPointer dlg = new KDialog(); - QString password; + QPointer dlg = new QDialog(); + QString password; - QWidget *mainWidget = new QWidget( dlg ); - QVBoxLayout *vLayout = new QVBoxLayout(); - mainWidget->setLayout( vLayout ); - QLabel *label = new QLabel( i18n( "A password is required for user %1", - ( user == QLatin1String( "$default$" ) ? defaultUsername() : user ) ), - mainWidget - ); - vLayout->addWidget( label ); - QHBoxLayout *hLayout = new QHBoxLayout(); - label = new QLabel( i18n( "Password: " ), mainWidget ); - hLayout->addWidget( label ); - KLineEdit *lineEdit = new KLineEdit(); - lineEdit->setPasswordMode( true ); - hLayout->addWidget( lineEdit ); - vLayout->addLayout( hLayout ); - dlg->setMainWidget( mainWidget ); - lineEdit->setFocus(); - - const int result = dlg->exec(); - - if ( result == QDialog::Accepted && !dlg.isNull() ) { - password = lineEdit->text(); - } + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help); + QVBoxLayout *mainLayout = new QVBoxLayout; + dlg->setLayout(mainLayout); + QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); + okButton->setDefault(true); + okButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, dlg.data(), &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, dlg.data(), &QDialog::reject); + + QWidget *mainWidget = new QWidget(dlg); + mainLayout->addWidget(mainWidget); + mainLayout->addWidget(buttonBox); + QVBoxLayout *vLayout = new QVBoxLayout(); + mainWidget->setLayout(vLayout); + QLabel *label = new QLabel(i18n("A password is required for user %1", + (user == QLatin1String("$default$") ? defaultUsername() : user)), + mainWidget + ); + vLayout->addWidget(label); + QHBoxLayout *hLayout = new QHBoxLayout(); + label = new QLabel(i18n("Password: "), mainWidget); + hLayout->addWidget(label); + KLineEdit *lineEdit = new KLineEdit(); + lineEdit->setPasswordMode(true); + hLayout->addWidget(lineEdit); + vLayout->addLayout(hLayout); + lineEdit->setFocus(); - delete dlg; - return password; + const int result = dlg->exec(); + + if (result == QDialog::Accepted && !dlg.isNull()) { + password = lineEdit->text(); + } + + delete dlg; + return password; } void Settings::updateToV2() { - // Take the first URL that was configured to get the username that - // has the most chances being the default + // Take the first URL that was configured to get the username that + // has the most chances being the default + + QStringList urls = remoteUrls(); + if (urls.isEmpty()) { + return; + } + + QString urlConfigStr = urls.at(0); + UrlConfiguration urlConfig(urlConfigStr); + QRegExp regexp(QLatin1Char('^') + urlConfig.mUser); - QStringList urls = remoteUrls(); - if ( urls.isEmpty() ) - return; - - QString urlConfigStr = urls.at( 0 ); - UrlConfiguration urlConfig( urlConfigStr ); - QRegExp regexp( QLatin1Char('^') + urlConfig.mUser ); - - QMutableStringListIterator it( urls ); - while ( it.hasNext() ) { - it.next(); - it.value().replace( regexp, QLatin1String( "$default$" ) ); - } - - setDefaultUsername( urlConfig.mUser ); - QString key = urlConfig.mUrl + QLatin1Char(',') + DavUtils::protocolName( DavUtils::Protocol( urlConfig.mProtocol ) ); - QString pass = loadPassword( key, urlConfig.mUser ); - if ( !pass.isNull() ) - setDefaultPassword( pass ); - setRemoteUrls( urls ); - setSettingsVersion( 2 ); - writeConfig(); + QMutableStringListIterator it(urls); + while (it.hasNext()) { + it.next(); + it.value().replace(regexp, QStringLiteral("$default$")); + } + + setDefaultUsername(urlConfig.mUser); + QString key = urlConfig.mUrl + QLatin1Char(',') + DavUtils::protocolName(DavUtils::Protocol(urlConfig.mProtocol)); + QString pass = loadPassword(key, urlConfig.mUser); + if (!pass.isNull()) { + setDefaultPassword(pass); + } + setRemoteUrls(urls); + setSettingsVersion(2); + save(); } void Settings::updateToV3() { - QStringList updatedUrls; + QStringList updatedUrls; - foreach ( const QString &url, remoteUrls() ) { - QStringList splitUrl = url.split( QLatin1Char('|') ); + foreach (const QString &url, remoteUrls()) { + QStringList splitUrl = url.split(QLatin1Char('|')); - if ( splitUrl.size() == 3 ) { - DavUtils::Protocol protocol = DavUtils::protocolByTranslatedName( splitUrl.at( 1 ) ); - splitUrl[1] = DavUtils::protocolName( protocol ); - updatedUrls << splitUrl.join( QLatin1String("|") ); + if (splitUrl.size() == 3) { + DavUtils::Protocol protocol = DavUtils::protocolByTranslatedName(splitUrl.at(1)); + splitUrl[1] = DavUtils::protocolName(protocol); + updatedUrls << splitUrl.join(QStringLiteral("|")); + } } - } - setRemoteUrls( updatedUrls ); - setSettingsVersion( 3 ); - writeConfig(); + setRemoteUrls(updatedUrls); + setSettingsVersion(3); + save(); } diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/settings.h kdepim-runtime-15.08.0/resources/dav/resource/settings.h --- kdepim-runtime-4.14.6/resources/dav/resource/settings.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/settings.h 2015-08-10 21:01:02.000000000 +0000 @@ -29,23 +29,24 @@ #include #ifdef HAVE_ACCOUNTS -namespace Accounts { - class Service; - class Account; - class Manager; +namespace Accounts +{ +class Service; +class Account; +class Manager; }; #endif class Settings : public SettingsBase { - Q_OBJECT + Q_OBJECT - public: +public: class UrlConfiguration { - public: + public: UrlConfiguration(); - explicit UrlConfiguration( const QString &serialized ); + explicit UrlConfiguration(const QString &serialized); /** * Serializes the object. @@ -63,12 +64,12 @@ Settings(); virtual ~Settings(); - static Settings* self(); - void setWinId( WId wid ); + static Settings *self(); + void setWinId(WId wid); void cleanup(); - void setResourceIdentifier( const QString &identifier ); - void setDefaultPassword( const QString &password ); + void setResourceIdentifier(const QString &identifier); + void setDefaultPassword(const QString &password); QString defaultPassword(); DavUtils::DavUrl::List configuredDavUrls(); @@ -77,27 +78,27 @@ * Creates and returns the DavUrl that corresponds to the configuration for searchUrl. * If finalUrl is supplied, then it will be used in the returned object instead of the searchUrl. */ - DavUtils::DavUrl configuredDavUrl( DavUtils::Protocol protocol, const QString &searchUrl, const QString &finalUrl = QString() ); + DavUtils::DavUrl configuredDavUrl(DavUtils::Protocol protocol, const QString &searchUrl, const QString &finalUrl = QString()); - /** - * Creates and return the DavUrl from the configured URL that has a mapping with @p collectionUrl. - * If @p finalUrl is supplied it will be used in the returned object, else @p collectionUrl will - * be used. - * If no configured URL can be found the returned DavUrl will have an empty url(). - */ - DavUtils::DavUrl davUrlFromCollectionUrl( const QString &collectionUrl, const QString &finalUrl = QString() ); + /** + * Creates and return the DavUrl from the configured URL that has a mapping with @p collectionUrl. + * If @p finalUrl is supplied it will be used in the returned object, else @p collectionUrl will + * be used. + * If no configured URL can be found the returned DavUrl will have an empty url(). + */ + DavUtils::DavUrl davUrlFromCollectionUrl(const QString &collectionUrl, const QString &finalUrl = QString()); /** * Add a new mapping between the collection URL, as seen on the backend, and the * URL configured by the user. A mapping here means that the collectionUrl has * been discovered by a DavCollectionsFetchJob on the configuredUrl. */ - void addCollectionUrlMapping( DavUtils::Protocol protocol, const QString &collectionUrl, const QString &configuredUrl ); + void addCollectionUrlMapping(DavUtils::Protocol protocol, const QString &collectionUrl, const QString &configuredUrl); /** * Returns the collections URLs mapped behing @p configuredUrl and @p protocol. */ - QStringList mappedCollections( DavUtils::Protocol protocol, const QString &configuredUrl ); + QStringList mappedCollections(DavUtils::Protocol protocol, const QString &configuredUrl); /** * Reloads the resource configuration taking into account any new modification @@ -108,15 +109,15 @@ */ void reloadConfig(); - void newUrlConfiguration( UrlConfiguration *urlConfig ); - void removeUrlConfiguration( DavUtils::Protocol protocol, const QString &url ); - UrlConfiguration * urlConfiguration( DavUtils::Protocol protocol, const QString &url ); + void newUrlConfiguration(UrlConfiguration *urlConfig); + void removeUrlConfiguration(DavUtils::Protocol protocol, const QString &url); + UrlConfiguration *urlConfiguration(DavUtils::Protocol protocol, const QString &url); //DavUtils::Protocol protocol( const QString &url ) const; - QString username( DavUtils::Protocol protocol, const QString &url ) const; - QString password( DavUtils::Protocol protocol, const QString &url ); + QString username(DavUtils::Protocol protocol, const QString &url) const; + QString password(DavUtils::Protocol protocol, const QString &url); - private: +private: #ifdef HAVE_ACCOUNTS void addAccountsEnabledServices(); void removeAccountsDisabledServices(); @@ -128,9 +129,9 @@ void buildUrlsList(); void loadMappings(); void updateRemoteUrls(); - void savePassword( const QString &key, const QString &user, const QString &password ); - QString loadPassword( const QString &key, const QString &user ); - QString promptForPassword( const QString &user ); + void savePassword(const QString &key, const QString &user, const QString &password); + QString loadPassword(const QString &key, const QString &user); + QString promptForPassword(const QString &user); void updateToV2(); void updateToV3(); @@ -140,11 +141,11 @@ Accounts::Manager *m_manager; #endif QString mResourceIdentifier; - QMap mUrls; + QMap mUrls; QMap mPasswordsCache; QString mCollectionsUrlsMappingCache; QMap mCollectionsUrlsMapping; - QList mToDeleteUrlConfigs; + QList mToDeleteUrlConfigs; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/setupwizard.cpp kdepim-runtime-15.08.0/resources/dav/resource/setupwizard.cpp --- kdepim-runtime-4.14.6/resources/dav/resource/setupwizard.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/setupwizard.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,516 +20,542 @@ #include "davcollectionsmultifetchjob.h" -#include -#include +#include +#include #include #include #include -#include +#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -enum GroupwareServers -{ - Citadel, - DAVical, - eGroupware, - OpenGroupware, - ScalableOGo, - Scalix, - Zarafa, - Zimbra +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum GroupwareServers { + Citadel, + DAVical, + eGroupware, + OpenGroupware, + ScalableOGo, + Scalix, + Zarafa, + Zimbra }; -static QString settingsToUrl( const QWizard *wizard, const QString &protocol ) +static QString settingsToUrl(const QWizard *wizard, const QString &protocol) { - QString desktopFilePath = wizard->property( "providerDesktopFilePath" ).toString(); - if ( desktopFilePath.isEmpty() ) - return QString(); - - KService::Ptr service = KService::serviceByStorageId( desktopFilePath ); - if ( !service ) - return QString(); - - QStringList supportedProtocols = service->property( QLatin1String("X-DavGroupware-SupportedProtocols") ).toStringList(); - if ( !supportedProtocols.contains( protocol ) ) - return QString(); - - QString pathPattern; - - QString pathPropertyName( QLatin1String("X-DavGroupware-") + protocol + QLatin1String("Path") ); - if ( service->property( pathPropertyName ).isNull() ) - return QString(); - - pathPattern.append( service->property( pathPropertyName ).toString() + QLatin1Char('/') ); - - QString username = wizard->field( QLatin1String("credentialsUserName") ).toString(); - QString localPart( username ); - localPart.remove( QRegExp( QLatin1String("@.*$") ) ); - pathPattern.replace( QLatin1String("$user$"), username ); - pathPattern.replace( QLatin1String("$localpart$"), localPart ); - - QString localPath = wizard->field( QLatin1String("installationPath") ).toString(); - if ( !localPath.isEmpty() ) { - if ( !localPath.startsWith( QLatin1Char('/') ) ) - pathPattern.prepend( QLatin1Char('/') + localPath ); - else - pathPattern.prepend( localPath ); - } - - QUrl url; - - if ( !wizard->property( "usePredefinedProvider" ).isNull() ) { - if ( service->property( QLatin1String("X-DavGroupware-ProviderUsesSSL") ).toBool() ) - url.setScheme( QLatin1String("https") ); - else - url.setScheme( QLatin1String("http") ); - - QString hostPropertyName( QLatin1String("X-DavGroupware-") + protocol + QLatin1String("Host") ); - if ( service->property( hostPropertyName ).isNull() ) - return QString(); - - url.setHost( service->property( hostPropertyName ).toString() ); - url.setPath( pathPattern ); - } else { - if ( wizard->field( QLatin1String("connectionUseSecureConnection") ).toBool() ) - url.setScheme( QLatin1String("https") ); - else - url.setScheme( QLatin1String("http") ); - - QString host = wizard->field( QLatin1String("connectionHost") ).toString(); - if ( host.isEmpty() ) - return QString(); - QStringList hostParts = host.split( QLatin1Char(':') ); - url.setHost( hostParts.at( 0 ) ); - url.setPath( pathPattern ); - - if ( hostParts.size() == 2 ) { - int port = hostParts.at( 1 ).toInt(); - if ( port ) - url.setPort( port ); + QString desktopFilePath = wizard->property("providerDesktopFilePath").toString(); + if (desktopFilePath.isEmpty()) { + return QString(); } - } - return url.toString(); + KService::Ptr service = KService::serviceByStorageId(desktopFilePath); + if (!service) { + return QString(); + } + + QStringList supportedProtocols = service->property(QStringLiteral("X-DavGroupware-SupportedProtocols")).toStringList(); + if (!supportedProtocols.contains(protocol)) { + return QString(); + } + + QString pathPattern; + + QString pathPropertyName(QStringLiteral("X-DavGroupware-") + protocol + QStringLiteral("Path")); + if (service->property(pathPropertyName).isNull()) { + return QString(); + } + + pathPattern.append(service->property(pathPropertyName).toString() + QLatin1Char('/')); + + QString username = wizard->field(QStringLiteral("credentialsUserName")).toString(); + QString localPart(username); + localPart.remove(QRegExp(QStringLiteral("@.*$"))); + pathPattern.replace(QStringLiteral("$user$"), username); + pathPattern.replace(QStringLiteral("$localpart$"), localPart); + QString providerName; + if (!service->property("X-DavGroupware-Provider").isNull()) { + providerName = service->property("X-DavGroupware-Provider").toString(); + } + QString localPath = wizard->field(QStringLiteral("installationPath")).toString(); + if (!localPath.isEmpty()) { + if (providerName == QLatin1String("davical")) { + if (!localPath.endsWith(QLatin1Char('/'))) { + pathPattern.append(localPath + QLatin1Char('/')); + } else { + pathPattern.append(localPath); + } + } else { + if (!localPath.startsWith(QLatin1Char('/'))) { + pathPattern.prepend(QLatin1Char('/') + localPath); + } else { + pathPattern.prepend(localPath); + } + } + } + QUrl url; + + if (!wizard->property("usePredefinedProvider").isNull()) { + if (service->property(QStringLiteral("X-DavGroupware-ProviderUsesSSL")).toBool()) { + url.setScheme(QStringLiteral("https")); + } else { + url.setScheme(QStringLiteral("http")); + } + + QString hostPropertyName(QStringLiteral("X-DavGroupware-") + protocol + QStringLiteral("Host")); + if (service->property(hostPropertyName).isNull()) { + return QString(); + } + + url.setHost(service->property(hostPropertyName).toString()); + url.setPath(pathPattern); + } else { + if (wizard->field(QStringLiteral("connectionUseSecureConnection")).toBool()) { + url.setScheme(QStringLiteral("https")); + } else { + url.setScheme(QStringLiteral("http")); + } + + QString host = wizard->field(QStringLiteral("connectionHost")).toString(); + if (host.isEmpty()) { + return QString(); + } + QStringList hostParts = host.split(QLatin1Char(':')); + url.setHost(hostParts.at(0)); + url.setPath(pathPattern); + + if (hostParts.size() == 2) { + int port = hostParts.at(1).toInt(); + if (port) { + url.setPort(port); + } + } + } + return url.toString(); } /* * SetupWizard */ -SetupWizard::SetupWizard( QWidget *parent ) - : QWizard( parent ) +SetupWizard::SetupWizard(QWidget *parent) + : QWizard(parent) { - setWindowTitle( i18n( "DAV groupware configuration wizard" ) ); - setWindowIcon( KIcon( QLatin1String("folder-remote") ) ); - setPage( W_CredentialsPage, new CredentialsPage ); - setPage( W_PredefinedProviderPage, new PredefinedProviderPage ); - setPage( W_ServerTypePage, new ServerTypePage ); - setPage( W_ConnectionPage, new ConnectionPage ); - setPage( W_CheckPage, new CheckPage ); + setWindowTitle(i18n("DAV groupware configuration wizard")); + setWindowIcon(QIcon::fromTheme(QStringLiteral("folder-remote"))); + setPage(W_CredentialsPage, new CredentialsPage); + setPage(W_PredefinedProviderPage, new PredefinedProviderPage); + setPage(W_ServerTypePage, new ServerTypePage); + setPage(W_ConnectionPage, new ConnectionPage); + setPage(W_CheckPage, new CheckPage); } QString SetupWizard::displayName() const { - QString desktopFilePath = property( "providerDesktopFilePath" ).toString(); - if ( desktopFilePath.isEmpty() ) - return QString(); - - KService::Ptr service = KService::serviceByStorageId( desktopFilePath ); - if ( !service ) - return QString(); + QString desktopFilePath = property("providerDesktopFilePath").toString(); + if (desktopFilePath.isEmpty()) { + return QString(); + } - return service->name(); + KService::Ptr service = KService::serviceByStorageId(desktopFilePath); + if (!service) { + return QString(); + } + + return service->name(); } SetupWizard::Url::List SetupWizard::urls() const { - Url::List urls; + Url::List urls; - QString desktopFilePath = property( "providerDesktopFilePath" ).toString(); - if ( desktopFilePath.isEmpty() ) - return urls; + QString desktopFilePath = property("providerDesktopFilePath").toString(); + if (desktopFilePath.isEmpty()) { + return urls; + } - KService::Ptr service = KService::serviceByStorageId( desktopFilePath ); - if ( !service ) - return urls; + KService::Ptr service = KService::serviceByStorageId(desktopFilePath); + if (!service) { + return urls; + } - QStringList supportedProtocols = service->property( QLatin1String("X-DavGroupware-SupportedProtocols") ).toStringList(); - foreach ( const QString &protocol, supportedProtocols ) { - Url url; - - if ( protocol == QLatin1String("CalDav") ) - url.protocol = DavUtils::CalDav; - else if ( protocol == QLatin1String("CardDav") ) - url.protocol = DavUtils::CardDav; - else if ( protocol == QLatin1String("GroupDav") ) - url.protocol = DavUtils::GroupDav; - else - return urls; - - QString urlStr = settingsToUrl( this, protocol ); - - if ( !urlStr.isEmpty() ) { - url.url = urlStr; - url.userName = QLatin1String( "$default$" ); - urls << url; + QStringList supportedProtocols = service->property(QStringLiteral("X-DavGroupware-SupportedProtocols")).toStringList(); + foreach (const QString &protocol, supportedProtocols) { + Url url; + + if (protocol == QLatin1String("CalDav")) { + url.protocol = DavUtils::CalDav; + } else if (protocol == QLatin1String("CardDav")) { + url.protocol = DavUtils::CardDav; + } else if (protocol == QLatin1String("GroupDav")) { + url.protocol = DavUtils::GroupDav; + } else { + return urls; + } + + QString urlStr = settingsToUrl(this, protocol); + + if (!urlStr.isEmpty()) { + url.url = urlStr; + url.userName = QStringLiteral("$default$"); + urls << url; + } } - } - return urls; + return urls; } /* * CredentialsPage */ -CredentialsPage::CredentialsPage( QWidget *parent ) - : QWizardPage( parent ) +CredentialsPage::CredentialsPage(QWidget *parent) + : QWizardPage(parent) { - setTitle( i18n( "Login Credentials" ) ); - setSubTitle( i18n( "Enter your credentials to login to the groupware server" ) ); + setTitle(i18n("Login Credentials")); + setSubTitle(i18n("Enter your credentials to login to the groupware server")); - QFormLayout *layout = new QFormLayout( this ); + QFormLayout *layout = new QFormLayout(this); - mUserName = new KLineEdit; - layout->addRow( i18n( "User" ), mUserName ); - registerField( QLatin1String("credentialsUserName*"), mUserName ); - - mPassword = new KLineEdit; - mPassword->setPasswordMode( true ); - layout->addRow( i18n( "Password" ), mPassword ); - registerField( QLatin1String("credentialsPassword*"), mPassword ); + mUserName = new KLineEdit; + layout->addRow(i18n("User"), mUserName); + registerField(QStringLiteral("credentialsUserName*"), mUserName); + + mPassword = new KLineEdit; + mPassword->setPasswordMode(true); + layout->addRow(i18n("Password"), mPassword); + registerField(QStringLiteral("credentialsPassword*"), mPassword); } int CredentialsPage::nextId() const { - QString userName = field( QLatin1String("credentialsUserName") ).toString(); - if ( userName.endsWith( QLatin1String( "@yahoo.com" ) ) ) { - KService::List offers; - offers = KServiceTypeTrader::self()->query( QLatin1String("DavGroupwareProvider"), QLatin1String("Name == 'Yahoo!'") ); - if ( offers.isEmpty() ) - return SetupWizard::W_ServerTypePage; - - wizard()->setProperty( "usePredefinedProvider", true ); - wizard()->setProperty( "predefinedProviderName", offers.at( 0 )->name() ); - wizard()->setProperty( "providerDesktopFilePath", offers.at( 0 )->entryPath() ); - return SetupWizard::W_PredefinedProviderPage; - } else { - return SetupWizard::W_ServerTypePage; - } + QString userName = field(QStringLiteral("credentialsUserName")).toString(); + if (userName.endsWith(QStringLiteral("@yahoo.com"))) { + KService::List offers; + offers = KServiceTypeTrader::self()->query(QStringLiteral("DavGroupwareProvider"), QStringLiteral("Name == 'Yahoo!'")); + if (offers.isEmpty()) { + return SetupWizard::W_ServerTypePage; + } + + wizard()->setProperty("usePredefinedProvider", true); + wizard()->setProperty("predefinedProviderName", offers.at(0)->name()); + wizard()->setProperty("providerDesktopFilePath", offers.at(0)->entryPath()); + return SetupWizard::W_PredefinedProviderPage; + } else { + return SetupWizard::W_ServerTypePage; + } } /* * PredefinedProviderPage */ -PredefinedProviderPage::PredefinedProviderPage( QWidget* parent ) - : QWizardPage( parent ) +PredefinedProviderPage::PredefinedProviderPage(QWidget *parent) + : QWizardPage(parent) { - setTitle( i18n( "Predefined provider found" ) ); - setSubTitle( i18n( "Select if you want to use the auto-detected provider" ) ); + setTitle(i18n("Predefined provider found")); + setSubTitle(i18n("Select if you want to use the auto-detected provider")); - QVBoxLayout *layout = new QVBoxLayout( this ); + QVBoxLayout *layout = new QVBoxLayout(this); - mLabel = new QLabel; - layout->addWidget( mLabel ); + mLabel = new QLabel; + layout->addWidget(mLabel); - mProviderGroup = new QButtonGroup( this ); - mProviderGroup->setExclusive( true ); + mProviderGroup = new QButtonGroup(this); + mProviderGroup->setExclusive(true); - mUseProvider = new QRadioButton; - mProviderGroup->addButton( mUseProvider ); - mUseProvider->setChecked( true ); - layout->addWidget( mUseProvider ); + mUseProvider = new QRadioButton; + mProviderGroup->addButton(mUseProvider); + mUseProvider->setChecked(true); + layout->addWidget(mUseProvider); - mDontUseProvider = new QRadioButton( i18n( "No, choose another server" ) ); - mProviderGroup->addButton( mDontUseProvider ); - layout->addWidget( mDontUseProvider ); + mDontUseProvider = new QRadioButton(i18n("No, choose another server")); + mProviderGroup->addButton(mDontUseProvider); + layout->addWidget(mDontUseProvider); } void PredefinedProviderPage::initializePage() { - mLabel->setText( i18n( "Based on the email address you used as a login, this wizard\n" + mLabel->setText(i18n("Based on the email address you used as a login, this wizard\n" "can configure automatically an account for %1 services.\n" - "Do you wish to do so?", wizard()->property( "predefinedProviderName" ).toString() ) ); + "Do you wish to do so?", wizard()->property("predefinedProviderName").toString())); - mUseProvider->setText( i18n( "Yes, use %1 as provider", wizard()->property( "predefinedProviderName" ).toString() ) ); + mUseProvider->setText(i18n("Yes, use %1 as provider", wizard()->property("predefinedProviderName").toString())); } int PredefinedProviderPage::nextId() const { - if ( mUseProvider->isChecked() ) { - return SetupWizard::W_CheckPage; - } - else { - wizard()->setProperty( "usePredefinedProvider", QVariant() ); - wizard()->setProperty( "providerDesktopFilePath", QVariant() ); - return SetupWizard::W_ServerTypePage; - } + if (mUseProvider->isChecked()) { + return SetupWizard::W_CheckPage; + } else { + wizard()->setProperty("usePredefinedProvider", QVariant()); + wizard()->setProperty("providerDesktopFilePath", QVariant()); + return SetupWizard::W_ServerTypePage; + } } /* * ServerTypePage */ -bool compareServiceOffers( QPair off1, QPair off2 ) +bool compareServiceOffers(QPair off1, QPair off2) { - return off1.first.toLower() < off2.first.toLower(); + return off1.first.toLower() < off2.first.toLower(); } -ServerTypePage::ServerTypePage( QWidget *parent ) - : QWizardPage( parent ) +ServerTypePage::ServerTypePage(QWidget *parent) + : QWizardPage(parent) { - setTitle( i18n( "Groupware Server" ) ); - setSubTitle( i18n( "Select the groupware server the resource shall be configured for" ) ); - - mProvidersCombo = new QComboBox( this ); - KService::List providers; - KServiceTypeTrader *trader = KServiceTypeTrader::self(); - providers = trader->query( QLatin1String("DavGroupwareProvider") ); - QList< QPair > offers; - foreach ( const KService::Ptr &provider, providers ) { - offers.append( QPair( provider->name(), provider->entryPath() ) ); - } - qSort( offers.begin(), offers.end(), compareServiceOffers ); - QListIterator< QPair > it( offers ); - while ( it.hasNext() ) { - QPair p = it.next(); - mProvidersCombo->addItem( p.first, p.second ); - } - registerField( QLatin1String("provider"), mProvidersCombo, "currentText" ); - - QVBoxLayout *layout = new QVBoxLayout( this ); - - mServerGroup = new QButtonGroup( this ); - mServerGroup->setExclusive( true ); - - QRadioButton *button; - - QHBoxLayout *hLayout = new QHBoxLayout; - button = new QRadioButton( i18n( "Use one of those servers:" ) ); - registerField( QLatin1String("templateConfiguration"), button ); - mServerGroup->addButton( button ); - mServerGroup->setId( button, 0 ); - button->setChecked( true ); - hLayout->addWidget( button ); - hLayout->addWidget( mProvidersCombo ); - hLayout->addStretch( 1 ); - layout->addLayout( hLayout ); - - button = new QRadioButton( i18n( "Configure the resource manually" ) ); - connect( button, SIGNAL(toggled(bool)), - this, SLOT(manualConfigToggled(bool)) ); - registerField( QLatin1String("manualConfiguration"), button ); - mServerGroup->addButton( button ); - mServerGroup->setId( button, 1 ); - layout->addWidget( button ); + setTitle(i18n("Groupware Server")); + setSubTitle(i18n("Select the groupware server the resource shall be configured for")); + + mProvidersCombo = new QComboBox(this); + KService::List providers; + KServiceTypeTrader *trader = KServiceTypeTrader::self(); + providers = trader->query(QStringLiteral("DavGroupwareProvider")); + QList< QPair > offers; + offers.reserve(providers.count()); + foreach (const KService::Ptr &provider, providers) { + offers.append(QPair(provider->name(), provider->entryPath())); + } + qSort(offers.begin(), offers.end(), compareServiceOffers); + QListIterator< QPair > it(offers); + while (it.hasNext()) { + QPair p = it.next(); + mProvidersCombo->addItem(p.first, p.second); + } + registerField(QStringLiteral("provider"), mProvidersCombo, "currentText"); + + QVBoxLayout *layout = new QVBoxLayout(this); + + mServerGroup = new QButtonGroup(this); + mServerGroup->setExclusive(true); - layout->addStretch( 1 ); + QRadioButton *button; + + QHBoxLayout *hLayout = new QHBoxLayout; + button = new QRadioButton(i18n("Use one of those servers:")); + registerField(QStringLiteral("templateConfiguration"), button); + mServerGroup->addButton(button); + mServerGroup->setId(button, 0); + button->setChecked(true); + hLayout->addWidget(button); + hLayout->addWidget(mProvidersCombo); + hLayout->addStretch(1); + layout->addLayout(hLayout); + + button = new QRadioButton(i18n("Configure the resource manually")); + connect(button, &QRadioButton::toggled, this, &ServerTypePage::manualConfigToggled); + registerField(QStringLiteral("manualConfiguration"), button); + mServerGroup->addButton(button); + mServerGroup->setId(button, 1); + layout->addWidget(button); + + layout->addStretch(1); } -void ServerTypePage::manualConfigToggled( bool state ) +void ServerTypePage::manualConfigToggled(bool state) { - setFinalPage( state ); - wizard()->button( QWizard::NextButton )->setEnabled( !state ); + setFinalPage(state); + wizard()->button(QWizard::NextButton)->setEnabled(!state); } bool ServerTypePage::validatePage() { - QVariant desktopFilePath = mProvidersCombo->itemData( mProvidersCombo->currentIndex() ); - if ( desktopFilePath.isNull() ) { - return false; - } - else { - wizard()->setProperty( "providerDesktopFilePath", desktopFilePath ); - return true; - } + QVariant desktopFilePath = mProvidersCombo->itemData(mProvidersCombo->currentIndex()); + if (desktopFilePath.isNull()) { + return false; + } else { + wizard()->setProperty("providerDesktopFilePath", desktopFilePath); + return true; + } } /* * ConnectionPage */ -ConnectionPage::ConnectionPage( QWidget *parent ) - : QWizardPage( parent ), mPreviewLayout( 0 ), mCalDavUrlPreview( 0 ), mCardDavUrlPreview( 0 ), mGroupDavUrlPreview( 0 ) +ConnectionPage::ConnectionPage(QWidget *parent) + : QWizardPage(parent), mPreviewLayout(Q_NULLPTR), mCalDavUrlPreview(Q_NULLPTR), mCardDavUrlPreview(Q_NULLPTR), mGroupDavUrlPreview(Q_NULLPTR) { - setTitle( i18n( "Connection" ) ); - setSubTitle( i18n( "Enter the connection information for the groupware server" ) ); + setTitle(i18n("Connection")); + setSubTitle(i18n("Enter the connection information for the groupware server")); - mLayout = new QFormLayout; - setLayout(mLayout); - QRegExp hostnameRegexp( QLatin1String("^[a-z0-9][.a-z0-9-]*[a-z0-9](?::[0-9]+)?$") ); - mHost = new KLineEdit; - registerField( QLatin1String("connectionHost*"), mHost ); - mHost->setValidator( new QRegExpValidator( hostnameRegexp, this ) ); - mLayout->addRow( i18n( "Host" ), mHost ); - - mPath = new KLineEdit; - mLayout->addRow( i18n( "Installation path" ), mPath ); - registerField( QLatin1String("installationPath"), mPath ); - - mUseSecureConnection = new QCheckBox( i18n( "Use secure connection" ) ); - mUseSecureConnection->setChecked( true ); - registerField( QLatin1String("connectionUseSecureConnection"), mUseSecureConnection ); - mLayout->addRow( QString(), mUseSecureConnection ); - - connect( mHost, SIGNAL(textChanged(QString)), this, SLOT(urlElementChanged()) ); - connect( mPath, SIGNAL(textChanged(QString)), this, SLOT(urlElementChanged()) ); - connect( mUseSecureConnection, SIGNAL(toggled(bool)), this, SLOT(urlElementChanged()) ); + mLayout = new QFormLayout; + setLayout(mLayout); + QRegExp hostnameRegexp(QStringLiteral("^[a-z0-9][.a-z0-9-]*[a-z0-9](?::[0-9]+)?$")); + mHost = new KLineEdit; + registerField(QStringLiteral("connectionHost*"), mHost); + mHost->setValidator(new QRegExpValidator(hostnameRegexp, this)); + mLayout->addRow(i18n("Host"), mHost); + + mPath = new KLineEdit; + mLayout->addRow(i18n("Installation path"), mPath); + registerField(QStringLiteral("installationPath"), mPath); + + mUseSecureConnection = new QCheckBox(i18n("Use secure connection")); + mUseSecureConnection->setChecked(true); + registerField(QStringLiteral("connectionUseSecureConnection"), mUseSecureConnection); + mLayout->addRow(QString(), mUseSecureConnection); + + connect(mHost, &KLineEdit::textChanged, this, &ConnectionPage::urlElementChanged); + connect(mPath, &KLineEdit::textChanged, this, &ConnectionPage::urlElementChanged); + connect(mUseSecureConnection, &QCheckBox::toggled, this, &ConnectionPage::urlElementChanged); } void ConnectionPage::initializePage() { - KService::Ptr service = KService::serviceByStorageId( wizard()->property( "providerDesktopFilePath" ).toString() ); - if ( !service ) - return; - - QString providerInstallationPath = service->property( QLatin1String("X-DavGroupware-InstallationPath") ).toString(); - if ( !providerInstallationPath.isEmpty() ) - mPath->setText( providerInstallationPath ); - - QStringList supportedProtocols = service->property( QLatin1String("X-DavGroupware-SupportedProtocols") ).toStringList(); - - mPreviewLayout = new QFormLayout; - mLayout->addRow( mPreviewLayout ); - - if ( supportedProtocols.contains( QLatin1String("CalDav") ) ) { - mCalDavUrlLabel = new QLabel( i18n( "Final URL (CalDav)" ) ); - mCalDavUrlPreview = new QLabel; - mPreviewLayout->addRow( mCalDavUrlLabel, mCalDavUrlPreview ); - } - if ( supportedProtocols.contains( QLatin1String("CardDav") ) ) { - mCardDavUrlLabel = new QLabel( i18n( "Final URL (CardDav)" ) ); - mCardDavUrlPreview = new QLabel; - mPreviewLayout->addRow( mCardDavUrlLabel, mCardDavUrlPreview ); - } - if ( supportedProtocols.contains( QLatin1String("GroupDav") ) ) { - mGroupDavUrlLabel = new QLabel( i18n( "Final URL (GroupDav)" ) ); - mGroupDavUrlPreview = new QLabel; - mPreviewLayout->addRow( mGroupDavUrlLabel, mGroupDavUrlPreview ); - } + KService::Ptr service = KService::serviceByStorageId(wizard()->property("providerDesktopFilePath").toString()); + if (!service) { + return; + } + + QString providerInstallationPath = service->property(QStringLiteral("X-DavGroupware-InstallationPath")).toString(); + if (!providerInstallationPath.isEmpty()) { + mPath->setText(providerInstallationPath); + } + + QStringList supportedProtocols = service->property(QStringLiteral("X-DavGroupware-SupportedProtocols")).toStringList(); + + mPreviewLayout = new QFormLayout; + mLayout->addRow(mPreviewLayout); + + if (supportedProtocols.contains(QStringLiteral("CalDav"))) { + mCalDavUrlLabel = new QLabel(i18n("Final URL (CalDav)")); + mCalDavUrlPreview = new QLabel; + mPreviewLayout->addRow(mCalDavUrlLabel, mCalDavUrlPreview); + } + if (supportedProtocols.contains(QStringLiteral("CardDav"))) { + mCardDavUrlLabel = new QLabel(i18n("Final URL (CardDav)")); + mCardDavUrlPreview = new QLabel; + mPreviewLayout->addRow(mCardDavUrlLabel, mCardDavUrlPreview); + } + if (supportedProtocols.contains(QStringLiteral("GroupDav"))) { + mGroupDavUrlLabel = new QLabel(i18n("Final URL (GroupDav)")); + mGroupDavUrlPreview = new QLabel; + mPreviewLayout->addRow(mGroupDavUrlLabel, mGroupDavUrlPreview); + } } void ConnectionPage::cleanupPage() { - delete mPreviewLayout; + delete mPreviewLayout; - if ( mCalDavUrlPreview ) { - delete mCalDavUrlLabel; - delete mCalDavUrlPreview; - mCalDavUrlPreview = 0; - } - - if ( mCardDavUrlPreview ) { - delete mCardDavUrlLabel; - delete mCardDavUrlPreview; - mCardDavUrlPreview = 0; - } - - if ( mGroupDavUrlPreview ) { - delete mGroupDavUrlLabel; - delete mGroupDavUrlPreview; - mGroupDavUrlPreview = 0; - } + if (mCalDavUrlPreview) { + delete mCalDavUrlLabel; + delete mCalDavUrlPreview; + mCalDavUrlPreview = Q_NULLPTR; + } + + if (mCardDavUrlPreview) { + delete mCardDavUrlLabel; + delete mCardDavUrlPreview; + mCardDavUrlPreview = Q_NULLPTR; + } - QWizardPage::cleanupPage(); + if (mGroupDavUrlPreview) { + delete mGroupDavUrlLabel; + delete mGroupDavUrlPreview; + mGroupDavUrlPreview = Q_NULLPTR; + } + + QWizardPage::cleanupPage(); } void ConnectionPage::urlElementChanged() { - if ( mHost->text().isEmpty() ) { - if ( mCalDavUrlPreview ) - mCalDavUrlPreview->setText( QLatin1String("-") ); - if ( mCardDavUrlPreview ) - mCardDavUrlPreview->setText( QLatin1String("-") ); - if ( mGroupDavUrlPreview ) - mGroupDavUrlPreview->setText( QLatin1String("-") ); - } else { - if ( mCalDavUrlPreview ) - mCalDavUrlPreview->setText( settingsToUrl( this->wizard(), QLatin1String("CalDav") ) ); - if ( mCardDavUrlPreview ) - mCardDavUrlPreview->setText( settingsToUrl( this->wizard(), QLatin1String("CardDav") ) ); - if ( mGroupDavUrlPreview ) - mGroupDavUrlPreview->setText( settingsToUrl( this->wizard(), QLatin1String("GroupDav") ) ); - } + if (mHost->text().isEmpty()) { + if (mCalDavUrlPreview) { + mCalDavUrlPreview->setText(QStringLiteral("-")); + } + if (mCardDavUrlPreview) { + mCardDavUrlPreview->setText(QStringLiteral("-")); + } + if (mGroupDavUrlPreview) { + mGroupDavUrlPreview->setText(QStringLiteral("-")); + } + } else { + if (mCalDavUrlPreview) { + mCalDavUrlPreview->setText(settingsToUrl(this->wizard(), QStringLiteral("CalDav"))); + } + if (mCardDavUrlPreview) { + mCardDavUrlPreview->setText(settingsToUrl(this->wizard(), QStringLiteral("CardDav"))); + } + if (mGroupDavUrlPreview) { + mGroupDavUrlPreview->setText(settingsToUrl(this->wizard(), QStringLiteral("GroupDav"))); + } + } } /* * CheckPage */ -CheckPage::CheckPage( QWidget *parent ) - : QWizardPage( parent ) +CheckPage::CheckPage(QWidget *parent) + : QWizardPage(parent) { - setTitle( i18n( "Test Connection" ) ); - setSubTitle( i18n( "You can test now whether the groupware server can be accessed with the current configuration" ) ); - setFinalPage( true ); + setTitle(i18n("Test Connection")); + setSubTitle(i18n("You can test now whether the groupware server can be accessed with the current configuration")); + setFinalPage(true); - QVBoxLayout *layout = new QVBoxLayout( this ); + QVBoxLayout *layout = new QVBoxLayout(this); - QPushButton *button = new QPushButton( i18n( "Test Connection" ) ); - layout->addWidget( button ); + QPushButton *button = new QPushButton(i18n("Test Connection")); + layout->addWidget(button); - mStatusLabel = new KTextBrowser; - layout->addWidget( mStatusLabel ); + mStatusLabel = new QTextBrowser; + layout->addWidget(mStatusLabel); - connect( button, SIGNAL(clicked()), SLOT(checkConnection()) ); + connect(button, &QRadioButton::clicked, this, &CheckPage::checkConnection); } void CheckPage::checkConnection() { - mStatusLabel->clear(); - - DavUtils::DavUrl::List davUrls; + mStatusLabel->clear(); - // convert list of SetupWizard::Url to list of DavUtils::DavUrl - const SetupWizard::Url::List urls = static_cast( wizard() )->urls(); - foreach ( const SetupWizard::Url &url, urls ) { - DavUtils::DavUrl davUrl; - davUrl.setProtocol( url.protocol ); + DavUtils::DavUrl::List davUrls; - KUrl serverUrl( url.url ); - serverUrl.setUser( wizard()->field( QLatin1String("credentialsUserName") ).toString() ); - serverUrl.setPass( wizard()->field( QLatin1String("credentialsPassword") ).toString() ); - davUrl.setUrl( serverUrl ); + // convert list of SetupWizard::Url to list of DavUtils::DavUrl + const SetupWizard::Url::List urls = static_cast(wizard())->urls(); + foreach (const SetupWizard::Url &url, urls) { + DavUtils::DavUrl davUrl; + davUrl.setProtocol(url.protocol); + + KUrl serverUrl(url.url); + serverUrl.setUser(wizard()->field(QStringLiteral("credentialsUserName")).toString()); + serverUrl.setPass(wizard()->field(QStringLiteral("credentialsPassword")).toString()); + davUrl.setUrl(serverUrl); - davUrls << davUrl; - } - - // start the dav collections fetch job to test connectivity - DavCollectionsMultiFetchJob *job = new DavCollectionsMultiFetchJob( davUrls, this ); - connect( job, SIGNAL(result(KJob*)), SLOT(onFetchDone(KJob*)) ); - job->start(); -} - -void CheckPage::onFetchDone( KJob *job ) -{ - QString msg; - QPixmap icon; + davUrls << davUrl; + } - if ( job->error() ) { - msg = i18n( "An error occurred: %1",job->errorText()); - icon = KIcon( QLatin1String("dialog-close") ).pixmap( 16, 16 ); - } else { - msg = i18n( "Connected successfully" ); - icon = KIcon( QLatin1String("dialog-ok-apply") ).pixmap( 16, 16 ); - } + // start the dav collections fetch job to test connectivity + DavCollectionsMultiFetchJob *job = new DavCollectionsMultiFetchJob(davUrls, this); + connect(job, &DavCollectionsMultiFetchJob::result, this, &CheckPage::onFetchDone); + job->start(); +} + +void CheckPage::onFetchDone(KJob *job) +{ + QString msg; + QPixmap icon; + + if (job->error()) { + msg = i18n("An error occurred: %1", job->errorText()); + icon = QIcon::fromTheme(QStringLiteral("dialog-close")).pixmap(16, 16); + } else { + msg = i18n("Connected successfully"); + icon = QIcon::fromTheme(QStringLiteral("dialog-ok-apply")).pixmap(16, 16); + } - mStatusLabel->setHtml( QString::fromLatin1( " %1" ).arg( msg ) ); - mStatusLabel->document()->addResource( QTextDocument::ImageResource, QUrl( QLatin1String("icon") ), QVariant( icon ) ); + mStatusLabel->setHtml(QStringLiteral(" %1").arg(msg)); + mStatusLabel->document()->addResource(QTextDocument::ImageResource, QUrl(QStringLiteral("icon")), QVariant(icon)); } diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/setupwizard.h kdepim-runtime-15.08.0/resources/dav/resource/setupwizard.h --- kdepim-runtime-4.14.6/resources/dav/resource/setupwizard.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/setupwizard.h 2015-08-10 21:01:02.000000000 +0000 @@ -21,13 +21,13 @@ #include "davutils.h" -#include -#include +#include +#include #include class KJob; class KLineEdit; -class KTextBrowser; +class QTextBrowser; class QButtonGroup; class QCheckBox; @@ -38,22 +38,22 @@ class SetupWizard : public QWizard { - Q_OBJECT + Q_OBJECT - public: - explicit SetupWizard( QWidget *parent = 0 ); +public: + explicit SetupWizard(QWidget *parent = Q_NULLPTR); enum { - W_CredentialsPage, - W_PredefinedProviderPage, - W_ServerTypePage, - W_ConnectionPage, - W_CheckPage + W_CredentialsPage, + W_PredefinedProviderPage, + W_ServerTypePage, + W_ConnectionPage, + W_CheckPage }; class Url { - public: + public: typedef QList List; DavUtils::Protocol protocol; @@ -68,13 +68,13 @@ class PredefinedProviderPage : public QWizardPage { - public: - PredefinedProviderPage( QWidget* parent = 0 ); +public: + explicit PredefinedProviderPage(QWidget *parent = Q_NULLPTR); - virtual void initializePage(); - virtual int nextId() const; + void initializePage() Q_DECL_OVERRIDE; + int nextId() const Q_DECL_OVERRIDE; - private: +private: QLabel *mLabel; QButtonGroup *mProviderGroup; QRadioButton *mUseProvider; @@ -83,46 +83,46 @@ class CredentialsPage : public QWizardPage { - public: - CredentialsPage( QWidget *parent = 0 ); - virtual int nextId() const; +public: + explicit CredentialsPage(QWidget *parent = Q_NULLPTR); + int nextId() const Q_DECL_OVERRIDE; - private: +private: KLineEdit *mUserName; KLineEdit *mPassword; }; class ServerTypePage : public QWizardPage { - Q_OBJECT + Q_OBJECT - public: - ServerTypePage( QWidget *parent = 0 ); +public: + explicit ServerTypePage(QWidget *parent = Q_NULLPTR); - virtual bool validatePage(); + bool validatePage() Q_DECL_OVERRIDE; - private slots: - void manualConfigToggled( bool toggled ); +private Q_SLOTS: + void manualConfigToggled(bool toggled); - private: +private: QButtonGroup *mServerGroup; QComboBox *mProvidersCombo; }; class ConnectionPage : public QWizardPage { - Q_OBJECT + Q_OBJECT - public: - ConnectionPage( QWidget *parent = 0 ); +public: + explicit ConnectionPage(QWidget *parent = Q_NULLPTR); - virtual void initializePage(); - virtual void cleanupPage(); + void initializePage() Q_DECL_OVERRIDE; + void cleanupPage() Q_DECL_OVERRIDE; - private slots: +private Q_SLOTS: void urlElementChanged(); - private: +private: QFormLayout *mLayout; KLineEdit *mHost; KLineEdit *mPath; @@ -138,17 +138,17 @@ class CheckPage : public QWizardPage { - Q_OBJECT + Q_OBJECT - public: - CheckPage( QWidget *parent = 0 ); +public: + explicit CheckPage(QWidget *parent = Q_NULLPTR); - private Q_SLOTS: +private Q_SLOTS: void checkConnection(); - void onFetchDone( KJob* ); + void onFetchDone(KJob *); - private: - KTextBrowser *mStatusLabel; +private: + QTextBrowser *mStatusLabel; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/urlconfigurationdialog.cpp kdepim-runtime-15.08.0/resources/dav/resource/urlconfigurationdialog.cpp --- kdepim-runtime-4.14.6/resources/dav/resource/urlconfigurationdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/urlconfigurationdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,233 +24,273 @@ #include "settings.h" #include +#include -#include -#include +#include +#include +#include +#include + +UrlConfigurationDialog::UrlConfigurationDialog(QWidget *parent) + : QDialog(parent) +{ + QWidget *mainWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); + mUi.setupUi(mainWidget); + mUi.credentialsGroup->setVisible(false); + + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + mOkButton = buttonBox->button(QDialogButtonBox::Ok); + mOkButton->setDefault(true); + mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &UrlConfigurationDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &UrlConfigurationDialog::reject); + mainLayout->addWidget(buttonBox); + + mModel = new QStandardItemModel(); + initModel(); + + mUi.discoveredUrls->setModel(mModel); + mUi.discoveredUrls->setRootIsDecorated(false); + connect(mModel, &QStandardItemModel::dataChanged, this, &UrlConfigurationDialog::onModelDataChanged); + + connect(mUi.remoteProtocol, &KButtonGroup::changed, this, &UrlConfigurationDialog::onConfigChanged); + connect(mUi.remoteUrl, &KLineEdit::textChanged, this, &UrlConfigurationDialog::onConfigChanged); + connect(mUi.useDefaultCreds, &QRadioButton::toggled, this, &UrlConfigurationDialog::onConfigChanged); + connect(mUi.username, &KLineEdit::textChanged, this, &UrlConfigurationDialog::onConfigChanged); + connect(mUi.password, &KLineEdit::textChanged, this, &UrlConfigurationDialog::onConfigChanged); -UrlConfigurationDialog::UrlConfigurationDialog( QWidget *parent ) - : KDialog( parent ) -{ - mUi.setupUi( mainWidget() ); - mUi.credentialsGroup->setVisible( false ); - - mModel = new QStandardItemModel(); - initModel(); - - mUi.discoveredUrls->setModel( mModel ); - mUi.discoveredUrls->setRootIsDecorated( false ); - connect( mModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), - this, SLOT(onModelDataChanged(QModelIndex,QModelIndex)) ); + connect(mUi.fetchButton, &QPushButton::clicked, this, &UrlConfigurationDialog::onFetchButtonClicked); + connect(mOkButton, &QPushButton::clicked, this, &UrlConfigurationDialog::onOkButtonClicked); - connect( mUi.remoteProtocol, SIGNAL(changed(int)), this, SLOT(onConfigChanged()) ); - connect( mUi.remoteUrl, SIGNAL(textChanged(QString)), this, SLOT(onConfigChanged()) ); - connect( mUi.useDefaultCreds, SIGNAL(toggled(bool)), this, SLOT(onConfigChanged()) ); - connect( mUi.username, SIGNAL(textChanged(QString)), this, SLOT(onConfigChanged()) ); - connect( mUi.password, SIGNAL(textChanged(QString)), this, SLOT(onConfigChanged()) ); + checkUserInput(); + readConfig(); +} - connect( mUi.fetchButton, SIGNAL(clicked()), this, SLOT(onFetchButtonClicked()) ); - connect( this, SIGNAL(okClicked()), this, SLOT(onOkButtonClicked()) ); +UrlConfigurationDialog::~UrlConfigurationDialog() +{ + writeConfig(); +} - checkUserInput(); +void UrlConfigurationDialog::readConfig() +{ + KConfigGroup grp(KSharedConfig::openConfig(), "UrlConfigurationDialog"); + const QSize size = grp.readEntry("Size", QSize(300, 200)); + if (size.isValid()) { + resize(size); + } } -UrlConfigurationDialog::~UrlConfigurationDialog() +void UrlConfigurationDialog::writeConfig() { + KConfigGroup grp(KSharedConfig::openConfig(), "UrlConfigurationDialog"); + grp.writeEntry("Size", size()); + grp.sync(); } DavUtils::Protocol UrlConfigurationDialog::protocol() const { - return DavUtils::Protocol( mUi.remoteProtocol->selected() ); + return DavUtils::Protocol(mUi.remoteProtocol->selected()); } -void UrlConfigurationDialog::setProtocol( DavUtils::Protocol protocol ) +void UrlConfigurationDialog::setProtocol(DavUtils::Protocol protocol) { - mUi.remoteProtocol->setSelected( protocol ); + mUi.remoteProtocol->setSelected(protocol); } QString UrlConfigurationDialog::remoteUrl() const { - return mUi.remoteUrl->text(); + return mUi.remoteUrl->text(); } -void UrlConfigurationDialog::setRemoteUrl( const QString &url ) +void UrlConfigurationDialog::setRemoteUrl(const QString &url) { - mUi.remoteUrl->setText( url ); + mUi.remoteUrl->setText(url); } bool UrlConfigurationDialog::useDefaultCredentials() const { - return mUi.useDefaultCreds->isChecked(); + return mUi.useDefaultCreds->isChecked(); } -void UrlConfigurationDialog::setUseDefaultCredentials( bool defaultCreds ) +void UrlConfigurationDialog::setUseDefaultCredentials(bool defaultCreds) { - if ( defaultCreds ) - mUi.useDefaultCreds->setChecked( true ); - else - mUi.useSpecificCreds->setChecked( true ); + if (defaultCreds) { + mUi.useDefaultCreds->setChecked(true); + } else { + mUi.useSpecificCreds->setChecked(true); + } } QString UrlConfigurationDialog::username() const { - if ( mUi.useDefaultCreds->isChecked() ) - return mDefaultUsername; - else - return mUi.username->text(); + if (mUi.useDefaultCreds->isChecked()) { + return mDefaultUsername; + } else { + return mUi.username->text(); + } } -void UrlConfigurationDialog::setDefaultUsername( const QString &userName ) +void UrlConfigurationDialog::setDefaultUsername(const QString &userName) { - mDefaultUsername = userName; + mDefaultUsername = userName; } -void UrlConfigurationDialog::setUsername( const QString &userName ) +void UrlConfigurationDialog::setUsername(const QString &userName) { - mUi.username->setText( userName ); + mUi.username->setText(userName); } QString UrlConfigurationDialog::password() const { - if ( mUi.useDefaultCreds->isChecked() ) - return mDefaultPassword; - else - return mUi.password->text(); + if (mUi.useDefaultCreds->isChecked()) { + return mDefaultPassword; + } else { + return mUi.password->text(); + } } -void UrlConfigurationDialog::setDefaultPassword( const QString &password ) +void UrlConfigurationDialog::setDefaultPassword(const QString &password) { - mDefaultPassword = password; + mDefaultPassword = password; } -void UrlConfigurationDialog::setPassword(const QString& password) +void UrlConfigurationDialog::setPassword(const QString &password) { - mUi.password->setText( password ); + mUi.password->setText(password); } void UrlConfigurationDialog::onConfigChanged() { - initModel(); - mUi.fetchButton->setEnabled( false ); - enableButtonOk( false ); - checkUserInput(); + initModel(); + mUi.fetchButton->setEnabled(false); + mOkButton->setEnabled(false); + checkUserInput(); } void UrlConfigurationDialog::checkUserInput() { - if ( !mUi.remoteUrl->text().isEmpty() && checkUserAuthInput() ) { - mUi.fetchButton->setEnabled( true ); - if ( mModel->rowCount() > 0 ) - enableButtonOk( true ); - } else { - mUi.fetchButton->setEnabled( false ); - enableButtonOk( false ); - } + if (!mUi.remoteUrl->text().trimmed().isEmpty() && checkUserAuthInput()) { + mUi.fetchButton->setEnabled(true); + if (mModel->rowCount() > 0) { + mOkButton->setEnabled(true); + } + } else { + mUi.fetchButton->setEnabled(false); + mOkButton->setEnabled(false); + } } void UrlConfigurationDialog::onFetchButtonClicked() { - mUi.discoveredUrls->setEnabled( false ); - initModel(); - - if ( !remoteUrl().endsWith( QLatin1Char( '/' ) ) ) - setRemoteUrl( remoteUrl() + QLatin1Char( '/' ) ); - - if ( !remoteUrl().startsWith( QLatin1String( "https://" ) ) && !remoteUrl().startsWith( QLatin1String( "http://" ) ) ) - setRemoteUrl( QString( "https://" ) + remoteUrl() ); + mUi.discoveredUrls->setEnabled(false); + initModel(); - KUrl url( mUi.remoteUrl->text() ); - if ( mUi.useDefaultCreds->isChecked() ) { - url.setUser( mDefaultUsername ); - url.setPassword( mDefaultPassword ); - } else { - url.setUser( username() ); - url.setPassword( password() ); - } - - DavUtils::DavUrl davUrl( url, protocol() ); - DavCollectionsFetchJob *job = new DavCollectionsFetchJob( davUrl ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(onCollectionsFetchDone(KJob*)) ); - job->start(); + if (!remoteUrl().endsWith(QLatin1Char('/'))) { + setRemoteUrl(remoteUrl() + QLatin1Char('/')); + } + + if (!remoteUrl().startsWith(QStringLiteral("https://")) && !remoteUrl().startsWith(QStringLiteral("http://"))) { + setRemoteUrl(QString("https://") + remoteUrl()); + } + + KUrl url(mUi.remoteUrl->text()); + if (mUi.useDefaultCreds->isChecked()) { + url.setUser(mDefaultUsername); + url.setPassword(mDefaultPassword); + } else { + url.setUser(username()); + url.setPassword(password()); + } + + DavUtils::DavUrl davUrl(url, protocol()); + DavCollectionsFetchJob *job = new DavCollectionsFetchJob(davUrl); + connect(job, &DavCollectionsFetchJob::result, this, &UrlConfigurationDialog::onCollectionsFetchDone); + job->start(); } void UrlConfigurationDialog::onOkButtonClicked() { - if ( !remoteUrl().endsWith( QLatin1Char( '/' ) ) ) - setRemoteUrl( remoteUrl() + QLatin1Char( '/' ) ); + if (!remoteUrl().endsWith(QLatin1Char('/'))) { + setRemoteUrl(remoteUrl() + QLatin1Char('/')); + } } -void UrlConfigurationDialog::onCollectionsFetchDone( KJob *job ) +void UrlConfigurationDialog::onCollectionsFetchDone(KJob *job) { - mUi.discoveredUrls->setEnabled( true ); + mUi.discoveredUrls->setEnabled(true); - if ( job->error() ) { - KMessageBox::error( this, job->errorText() ); - return; - } + if (job->error()) { + KMessageBox::error(this, job->errorText()); + return; + } - DavCollectionsFetchJob *davJob = qobject_cast( job ); + DavCollectionsFetchJob *davJob = qobject_cast(job); - const DavCollection::List collections = davJob->collections(); + const DavCollection::List collections = davJob->collections(); - foreach ( const DavCollection &collection, collections ) - addModelRow( collection.displayName(), collection.url() ); + foreach (const DavCollection &collection, collections) { + addModelRow(collection.displayName(), collection.url()); + } - checkUserInput(); + checkUserInput(); } -void UrlConfigurationDialog::onModelDataChanged( const QModelIndex &topLeft, const QModelIndex& ) +void UrlConfigurationDialog::onModelDataChanged(const QModelIndex &topLeft, const QModelIndex &) { - // Actually only the display name can be changed, so no stricts checks are required - const QString newName = topLeft.data().toString(); - const QString url = topLeft.sibling( topLeft.row(), 1 ).data().toString(); + // Actually only the display name can be changed, so no stricts checks are required + const QString newName = topLeft.data().toString(); + const QString url = topLeft.sibling(topLeft.row(), 1).data().toString(); - KUrl fullUrl( url ); - fullUrl.setUser( username() ); - fullUrl.setPassword( password() ); + KUrl fullUrl(url); + fullUrl.setUser(username()); + fullUrl.setPassword(password()); - DavUtils::DavUrl davUrl( fullUrl, protocol() ); - DavCollectionModifyJob *job = new DavCollectionModifyJob( davUrl ); - job->setProperty( QLatin1String("displayname"), newName ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(onChangeDisplayNameFinished(KJob*)) ); - job->start(); - mUi.discoveredUrls->setEnabled( false ); + DavUtils::DavUrl davUrl(fullUrl, protocol()); + DavCollectionModifyJob *job = new DavCollectionModifyJob(davUrl); + job->setProperty(QStringLiteral("displayname"), newName); + connect(job, &DavCollectionModifyJob::result, this, &UrlConfigurationDialog::onChangeDisplayNameFinished); + job->start(); + mUi.discoveredUrls->setEnabled(false); } -void UrlConfigurationDialog::onChangeDisplayNameFinished( KJob *job ) +void UrlConfigurationDialog::onChangeDisplayNameFinished(KJob *job) { - if ( job->error() ) { - KMessageBox::error( this, job->errorText() ); - } + if (job->error()) { + KMessageBox::error(this, job->errorText()); + } - onFetchButtonClicked(); + onFetchButtonClicked(); } void UrlConfigurationDialog::initModel() { - mModel->clear(); - QStringList headers; - headers << i18n( "Display name" ) << i18n( "URL" ); - mModel->setHorizontalHeaderLabels( headers ); + mModel->clear(); + QStringList headers; + headers << i18n("Display name") << i18n("URL"); + mModel->setHorizontalHeaderLabels(headers); } bool UrlConfigurationDialog::checkUserAuthInput() { - return ( mUi.useDefaultCreds->isChecked() || !( mUi.username->text().isEmpty() || mUi.password->text().isEmpty() ) ); + return (mUi.useDefaultCreds->isChecked() || !(mUi.username->text().isEmpty() || mUi.password->text().isEmpty())); } -void UrlConfigurationDialog::addModelRow( const QString &displayName, const QString &url ) +void UrlConfigurationDialog::addModelRow(const QString &displayName, const QString &url) { - QStandardItem *rootItem = mModel->invisibleRootItem(); + QStandardItem *rootItem = mModel->invisibleRootItem(); - QList items; + QList items; - QStandardItem *displayNameStandardItem = new QStandardItem( displayName ); - displayNameStandardItem->setEditable( true ); - items << displayNameStandardItem; + QStandardItem *displayNameStandardItem = new QStandardItem(displayName); + displayNameStandardItem->setEditable(true); + items << displayNameStandardItem; - QStandardItem *urlStandardItem = new QStandardItem( url ); - urlStandardItem->setEditable( false ); - items << urlStandardItem; + QStandardItem *urlStandardItem = new QStandardItem(url); + urlStandardItem->setEditable(false); + items << urlStandardItem; - rootItem->appendRow( items ); + rootItem->appendRow(items); } diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/urlconfigurationdialog.h kdepim-runtime-15.08.0/resources/dav/resource/urlconfigurationdialog.h --- kdepim-runtime-4.14.6/resources/dav/resource/urlconfigurationdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/urlconfigurationdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,54 +24,58 @@ #include "davutils.h" #include +#include class KJob; class QModelIndex; class QStandardItemModel; - -class UrlConfigurationDialog : public KDialog +class QPushButton; +class UrlConfigurationDialog : public QDialog { - Q_OBJECT + Q_OBJECT - public: - explicit UrlConfigurationDialog( QWidget *parent = 0 ); +public: + explicit UrlConfigurationDialog(QWidget *parent = Q_NULLPTR); ~UrlConfigurationDialog(); DavUtils::Protocol protocol() const; - void setProtocol( DavUtils::Protocol protocol ); + void setProtocol(DavUtils::Protocol protocol); QString remoteUrl() const; - void setRemoteUrl( const QString &url ); + void setRemoteUrl(const QString &url); bool useDefaultCredentials() const; - void setUseDefaultCredentials( bool defaultCreds ); + void setUseDefaultCredentials(bool defaultCreds); QString username() const; - void setDefaultUsername( const QString &name ); - void setUsername( const QString &name ); + void setDefaultUsername(const QString &name); + void setUsername(const QString &name); QString password() const; - void setDefaultPassword( const QString &password ); - void setPassword( const QString &password ); + void setDefaultPassword(const QString &password); + void setPassword(const QString &password); - private Q_SLOTS: +private Q_SLOTS: void onConfigChanged(); void checkUserInput(); void onFetchButtonClicked(); void onOkButtonClicked(); - void onCollectionsFetchDone( KJob *job ); - void onModelDataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight ); - void onChangeDisplayNameFinished( KJob *job ); + void onCollectionsFetchDone(KJob *job); + void onModelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void onChangeDisplayNameFinished(KJob *job); - private: +private: void initModel(); bool checkUserAuthInput(); - void addModelRow( const QString &displayName, const QString &url ); + void addModelRow(const QString &displayName, const QString &url); + void writeConfig(); + void readConfig(); Ui::UrlConfigurationDialog mUi; QStandardItemModel *mModel; QString mDefaultUsername; QString mDefaultPassword; + QPushButton *mOkButton; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/dav/resource/urlconfigurationdialog.ui kdepim-runtime-15.08.0/resources/dav/resource/urlconfigurationdialog.ui --- kdepim-runtime-4.14.6/resources/dav/resource/urlconfigurationdialog.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/resource/urlconfigurationdialog.ui 2015-08-10 21:01:02.000000000 +0000 @@ -168,7 +168,7 @@
- + Fetch @@ -205,11 +205,6 @@ 1 - KPushButton - QPushButton -
kpushbutton.h
-
- KLineEdit QLineEdit
klineedit.h
diff -Nru kdepim-runtime-4.14.6/resources/dav/services/davical.desktop kdepim-runtime-15.08.0/resources/dav/services/davical.desktop --- kdepim-runtime-4.14.6/resources/dav/services/davical.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/services/davical.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -46,5 +46,7 @@ Type=Service X-KDE-ServiceTypes=DavGroupwareProvider +X-DavGroupware-Provider=davical X-DavGroupware-SupportedProtocols=CalDav X-DavGroupware-CalDavPath=/caldav.php + diff -Nru kdepim-runtime-4.14.6/resources/dav/services/owncloud.desktop kdepim-runtime-15.08.0/resources/dav/services/owncloud.desktop --- kdepim-runtime-4.14.6/resources/dav/services/owncloud.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/services/owncloud.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,6 @@ [Desktop Entry] Name=ownCloud +Name[bg]=ownCloud Name[bs]=ownCloud Name[ca]=ownCloud Name[ca@valencia]=ownCloud diff -Nru kdepim-runtime-4.14.6/resources/dav/services/owncloud-pre5.desktop kdepim-runtime-15.08.0/resources/dav/services/owncloud-pre5.desktop --- kdepim-runtime-4.14.6/resources/dav/services/owncloud-pre5.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/dav/services/owncloud-pre5.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,6 @@ [Desktop Entry] Name=ownCloud (< 5.0) +Name[bg]=ownCloud (< 5.0) Name[bs]=ownCloud (< 5.0) Name[ca]=ownCloud (< 5.0) Name[ca@valencia]=ownCloud (< 5.0) @@ -27,6 +28,7 @@ Name[pt_BR]=ownCloud (< 5.0) Name[ru]=ownCloud (< 5.0) Name[sk]=ownCloud (< 5.0) +Name[sl]=ownCloud (< 5.0) Name[sr]=Оунклауд (< 5.0) Name[sr@ijekavian]=Оунклауд (< 5.0) Name[sr@ijekavianlatin]=ownCloud (< 5.0) diff -Nru kdepim-runtime-4.14.6/resources/facebook/akonadi_facebook_resource.notifyrc kdepim-runtime-15.08.0/resources/facebook/akonadi_facebook_resource.notifyrc --- kdepim-runtime-4.14.6/resources/facebook/akonadi_facebook_resource.notifyrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/akonadi_facebook_resource.notifyrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,236 +0,0 @@ -[Global] -Comment=Akonadi's Facebook integration -Comment[bs]=Akonadi Facebook integracija -Comment[ca]=Integració de Facebook amb Akonadi -Comment[ca@valencia]=Integració de Facebook amb Akonadi -Comment[cs]=Integrace Facebooku do Akonadi -Comment[da]=Akonadis Facebook-integration -Comment[de]=Facebook-Integration für Akonadi -Comment[el]=Ενσωμάτωση του Facebook στο Akonadi -Comment[en_GB]=Akonadi's Facebook integration -Comment[es]=Integración de Facebook con Akonadi -Comment[et]=Akonadi Facebooki lõimimine -Comment[fi]=Akonadin Facebook-integraatio -Comment[fr]=Intégration de Facebook avec Akonadi -Comment[gl]=Integración do Akonadi no Facebook -Comment[hu]=Az Akonadi Facebook integrációja -Comment[ia]=Indegration de Facebook de Akonadi -Comment[it]=Integrazione con Facebook di Akonadi -Comment[kk]=Akonadi-дің Facebook-пен бірігуі -Comment[ko]=Akonadi Facebook 통합 -Comment[lt]=Akonadi Facebook integracija -Comment[mr]=आकोनाडीचे फेसबूकशी एकीकरण -Comment[nb]=Akonadi Facebook-integrering -Comment[nds]=Akonadi sien Facebook-Koppelsteed -Comment[nl]=Facebook-integratie van Akonadi -Comment[pl]=Integracja Facebooka z Akonadi -Comment[pt]=Integração do Facebook com o Akonadi -Comment[pt_BR]=Integração com o Facebook do Akonadi -Comment[ru]=Интеграция Akonadi с Facebook -Comment[sk]=Akonadi Facebook integrácia -Comment[sr]=Уклапање Фејсбука у Аконади -Comment[sr@ijekavian]=Уклапање Фејсбука у Аконади -Comment[sr@ijekavianlatin]=Uklapanje Facebooka u Akonadi -Comment[sr@latin]=Uklapanje Facebooka u Akonadi -Comment[sv]=Akonadi integrering med Facebook -Comment[tr]=Akonadi Facebook bütünleştirmesi -Comment[uk]=Інтеграція Akonadi з Facebook -Comment[x-test]=xxAkonadi's Facebook integrationxx -Comment[zh_CN]=Akonadi Facebook 整合 -Comment[zh_TW]=Akonadi Facebook 整合 -Name=Facebook Resource -Name[bs]=Facebook resurs -Name[ca]=Recurs de Facebook -Name[ca@valencia]=Recurs de Facebook -Name[cs]=Zdroj Facebooku -Name[da]=Facebook-ressource -Name[de]=Facebook-Ressource -Name[el]=Πόρος Facebook -Name[en_GB]=Facebook Resource -Name[es]=Recurso de Facebook -Name[et]=Facebooki ressurss -Name[fi]=Facebook-resurssi -Name[fr]=Ressource Facebook -Name[gl]=Recurso do Facebook -Name[hu]=Facebook erőforrás -Name[ia]=Ressource de Facebook -Name[it]=Risorsa Facebook -Name[kk]=Facebook ресурсы -Name[ko]=Facebook 자원 -Name[lt]=Facebook resursas -Name[nb]=Facebook-ressurs -Name[nds]=Facebook-Ressource -Name[nl]=Facebook-hulpmiddel -Name[pl]=Zasób Facebooka -Name[pt]=Recurso do Facebook -Name[pt_BR]=Recurso do Facebook -Name[ru]=Источник данных Facebook -Name[sk]=Facebook zdroj -Name[sr]=Ресурс Фејсбука -Name[sr@ijekavian]=Ресурс Фејсбука -Name[sr@ijekavianlatin]=Resurs Facebooka -Name[sr@latin]=Resurs Facebooka -Name[sv]=Facebook-resurs -Name[tr]=Facebook Kaynağı -Name[uk]=Ресурс Facebook -Name[x-test]=xxFacebook Resourcexx -Name[zh_CN]=Facebook 资源 -Name[zh_TW]=Facebook 資源 -IconName=kde - -[Context/Application] -Name=Facebook -Name[bs]=Facebook -Name[ca]=Facebook -Name[ca@valencia]=Facebook -Name[cs]=Facebook -Name[da]=Facebook -Name[de]=Facebook -Name[el]=Facebook -Name[en_GB]=Facebook -Name[es]=Facebook -Name[et]=Facebook -Name[fi]=Facebook -Name[fr]=Facebook -Name[gl]=Facebook -Name[hu]=Facebook -Name[ia]=Facebook -Name[it]=Facebook -Name[kk]=Facebook -Name[ko]=Facebook -Name[lt]=Facebook -Name[nb]=Facebook -Name[nds]=Facebook -Name[nl]=Facebook -Name[nn]=Facebook -Name[pl]=Facebook -Name[pt]=Facebook -Name[pt_BR]=Facebook -Name[ru]=Facebook -Name[sk]=Facebook -Name[sr]=Фејсбук -Name[sr@ijekavian]=Фејсбук -Name[sr@ijekavianlatin]=Facebook -Name[sr@latin]=Facebook -Name[sv]=Facebook -Name[tr]=Facebook -Name[ug]=فېيىسبۇك(Facebook) -Name[uk]=Facebook -Name[x-test]=xxFacebookxx -Name[zh_CN]=Facebook -Name[zh_TW]=Facebook -Comment=Notification coming from Facebook -Comment[bs]=Poruka koju je poslao Facebook -Comment[ca]=Notificació provinent de Facebook -Comment[ca@valencia]=Notificació provinent de Facebook -Comment[da]=Notifikation fra Facebook -Comment[de]=Benachrichtigungen von Facebook -Comment[el]=Η ειδοποίηση προέρχεαι από το Facebook -Comment[en_GB]=Notification coming from Facebook -Comment[es]=Notificación originada desde Facebook -Comment[et]=Facebooki märguanne -Comment[fi]=Facebookista saapuva ilmoitus -Comment[fr]=Notification provenant de Facebook -Comment[gl]=Notificación entrante desde o Facebook -Comment[hu]=Értesítés érkezik a Facebookról -Comment[ia]=Notification in arrivata ex Facebook -Comment[it]=Notifica proveniente da Facebook -Comment[kk]=Facebook-тан келетін құлақтандырулар -Comment[ko]=Facebook에서 보낸 알림 -Comment[lt]=Pranešimas iš Facebook -Comment[nb]=Varsling som kommer fra Facebook -Comment[nds]=Bescheed vun Facebook -Comment[nl]=Melding uit Facebook -Comment[pl]=Powiadomienia przychodzące z Facebooka -Comment[pt]=Notificação proveniente do Facebook -Comment[pt_BR]=Notificação originada do Facebook -Comment[ru]=Поступило уведомление из Facebook -Comment[sk]=Upozornenie prichádzajúce z Facebooku -Comment[sr]=Обавештење са Фејсбука -Comment[sr@ijekavian]=Обавештење са Фејсбука -Comment[sr@ijekavianlatin]=Obaveštenje sa Facebooka -Comment[sr@latin]=Obaveštenje sa Facebooka -Comment[sv]=Underrättelse som kommer från Facebook -Comment[tr]=Facebook'tan gelen bilgilendirme -Comment[uk]="Сповіщення, що надходять з Facebook" -Comment[x-test]=xxNotification coming from Facebookxx -Comment[zh_CN]=来自 Facebook 的通知 -Comment[zh_TW]=從 Facebook 來的通知 - -[Event/facebookNotification] -Name=New Facebook notification -Name[bs]=Nova Facebook poruka -Name[ca]=Notificació nova de Facebook -Name[ca@valencia]=Notificació nova de Facebook -Name[da]=Ny Facebook-notifikation -Name[de]=Neue Facebook-Benachrichtigung -Name[el]=Νέα ειδοποίηση Facebook -Name[en_GB]=New Facebook notification -Name[es]=Nueva notificación de Facebook -Name[et]=Uus Facebooki märguanne -Name[fi]=Uusi Facebook-ilmoitus -Name[fr]=Nouvelle notification Facebook -Name[gl]=Nova notificación do Facebook -Name[hu]=Új Facebook értesítés -Name[ia]=Nove notification de Facebook -Name[it]=Nuova notifica Facebook -Name[kk]=Жаңа Facebook құлақтандыруы -Name[ko]=새 Facebook 알림 -Name[lt]=Naujas Facebook pranešimas -Name[nb]=Ny Facebook-varsling -Name[nds]=Nieg Facebook-Bescheed -Name[nl]=Nieuwe Facebook-melding -Name[pl]=Nowe powiadomienie na Facebooku -Name[pt]=Nova notificação do Facebook -Name[pt_BR]=Nova notificação do Facebook -Name[ru]=Новое уведомление из Facebook -Name[sk]=Nové upozornenie Facebooku -Name[sr]=Ново обавештење са Фејсбука -Name[sr@ijekavian]=Ново обавештење са Фејсбука -Name[sr@ijekavianlatin]=Novo obaveštenje sa Facebooka -Name[sr@latin]=Novo obaveštenje sa Facebooka -Name[sv]=Ny underrättelse från Facebook -Name[tr]=Yeni Facebook bildirimi -Name[uk]=Нове сповіщення з Facebook -Name[x-test]=xxNew Facebook notificationxx -Name[zh_CN]=新 Facebook 通知 -Name[zh_TW]=新的 Facebook 通知器 -Comment=You have new Facebook notification -Comment[bs]=Imate novu Facebook poruku -Comment[ca]=Teniu una notificació nova al Facebook -Comment[ca@valencia]=Teniu una notificació nova al Facebook -Comment[da]=Du har en ny Facebook-notifikation -Comment[de]=Sie haben eine Facebook-Benachrichtigungen -Comment[el]=Έχετε νέα ειδοποίηση στο Facebook -Comment[en_GB]=You have new Facebook notification -Comment[es]=Usted tiene una nueva notificación de Facebook -Comment[et]=Sul on uus Facebooki märguanne -Comment[fi]=Sinulle on uusi Facebook-ilmoitus -Comment[fr]=Vous avez une nouvelle notification Facebook -Comment[gl]=Ten unha nova notificación do Facebook -Comment[hu]=Új Facebook értesítése van -Comment[ia]=Tu ha nove notificationes de Facebook -Comment[it]=Hai una nuova notifica da Facebook -Comment[kk]=Жаңа Facebook құлақтандыруы келді -Comment[ko]=새 Facebook 알림이 있음 -Comment[lt]=Turite naują Facebook pranešimą -Comment[nb]=Du har ny Facebook-varsling -Comment[nds]=Du hest en nieg Facebook-Bescheed -Comment[nl]=Er is een nieuwe Facebook-melding -Comment[pl]=Masz nowe powiadomienie na Facebooku -Comment[pt]=Tem uma notificação nova do Facebook -Comment[pt_BR]=Você tem uma nova notificação do Facebook -Comment[ru]=Вы получили уведомление из Facebook -Comment[sk]=Máte nové upozornenie Facebooku -Comment[sr]=Имате ново обавештење са Фејсбука -Comment[sr@ijekavian]=Имате ново обавештење са Фејсбука -Comment[sr@ijekavianlatin]=Imate novo obaveštenje sa Facebooka -Comment[sr@latin]=Imate novo obaveštenje sa Facebooka -Comment[sv]=Det finns en ny underrättelse från Facebook -Comment[tr]=Yeni Facebook bildiriminiz var -Comment[uk]=Вам надійшло сповіщення з Facebook -Comment[x-test]=xxYou have new Facebook notificationxx -Comment[zh_CN]=您有新的 Facebook 通知 -Comment[zh_TW]=您有新的 Facebook 通知 -Contexts=Application -Action=Popup diff -Nru kdepim-runtime-4.14.6/resources/facebook/CMakeLists.txt kdepim-runtime-15.08.0/resources/facebook/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/facebook/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -project(facebookresource) -include_directories(${LibKFbAPI_INCLUDE_DIR}) -include_directories(${QJSON_INCLUDE_DIR} ${qjson_INCLUDE_DIR}) -if(${AccountsQt_FOUND} AND ${SignOnQt_FOUND}) - include_directories(${ACCOUNTSQT_INCLUDE_DIRS} ${SIGNONQT_INCLUDE_DIRS}) - add_definitions(-DHAVE_ACCOUNTS) - set(facebookresource_SRCS ../shared/getcredentialsjob.cpp) -endif() - -set(facebookresource_SRCS - facebookresource.cpp - facebookresource_events.cpp - facebookresource_friends.cpp - facebookresource_notes.cpp - facebookresource_posts.cpp - facebookresource_notifications.cpp - settings.cpp - settingsdialog.cpp - timestampattribute.cpp - ${facebookresource_SRCS} -) - -install(FILES facebookresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents") -install(FILES akonadi_facebook_resource.notifyrc DESTINATION "${DATA_INSTALL_DIR}/akonadi_facebook_resource") - -kde4_add_ui_files(facebookresource_SRCS settingsdialog.ui) -kde4_add_kcfg_files(facebookresource_SRCS settingsbase.kcfgc) - -kcfg_generate_dbus_interface( - ${CMAKE_CURRENT_SOURCE_DIR}/settingsbase.kcfg - org.kde.Akonadi.Facebook.Settings -) - -qt4_add_dbus_adaptor(facebookresource_SRCS - ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.Facebook.Settings.xml - settings.h - Settings -) - -kde4_add_executable(akonadi_facebook_resource RUN_UNINSTALLED ${facebookresource_SRCS}) - -if(Q_WS_MAC) - set_target_properties( - akonadi_facebook_resource PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.template - ) - set_target_properties( - akonadi_facebook_resource PROPERTIES - MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.Facebook" - ) - set_target_properties( - akonadi_facebook_resource PROPERTIES - MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi Facebook Resource" - ) -endif() - -include_directories(${Boost_INCLUDE_DIR}) - -target_link_libraries(akonadi_facebook_resource - ${KDEPIMLIBS_AKONADI_SOCIALUTILS_LIBS} - ${KDEPIMLIBS_AKONADI_NOTES_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KABC_LIBS} - ${KDEPIMLIBS_KCALCORE_LIBS} - ${QT_QTCORE_LIBRARY} - ${QT_QTGUI_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ${QJSON_LIBRARIES} - ${KDE4_KDECORE_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${LibKFbAPI_LIBRARY} -) - -if(${AccountsQt_FOUND} AND ${SignOnQt_FOUND}) - target_link_libraries(akonadi_facebook_resource - ${ACCOUNTSQT_LIBRARIES} - ${SIGNONQT_LIBRARIES}) -endif() - -add_subdirectory(icons) -add_subdirectory(serializer) - -install(TARGETS akonadi_facebook_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/facebook/facebookresource.cpp kdepim-runtime-15.08.0/resources/facebook/facebookresource.cpp --- kdepim-runtime-4.14.6/resources/facebook/facebookresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/facebookresource.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,426 +0,0 @@ -/* - Copyright 2010, 2011 Thomas McGuire - Copyright 2011 Roeland Jago Douma - Copyright 2012 Martin Klapetek - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "facebookresource.h" -#include "settings.h" -#include "settingsdialog.h" -#include "timestampattribute.h" -#ifdef HAVE_ACCOUNTS -#include "../shared/getcredentialsjob.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include //krazy:exclude=camelcase wait for kdepimlibs 4.11 - -#include - -using namespace Akonadi; - -FacebookResource::FacebookResource( const QString &id ) - : ResourceBase( id ) -{ - AttributeFactory::registerAttribute(); - setNeedsNetwork( true ); - setObjectName( QLatin1String( "FacebookResource" ) ); - resetState(); - Settings::self()->setResourceId( identifier() ); - - connect( this, SIGNAL(abortRequested()), - this, SLOT(slotAbortRequested()) ); - connect( this, SIGNAL(reloadConfiguration()), SLOT(configurationChanged()) ); - - changeRecorder()->fetchCollection( true ); - changeRecorder()->itemFetchScope().fetchFullPayload( true ); - - AttributeFactory::registerAttribute(); -} - -FacebookResource::~FacebookResource() -{ - Settings::self()->writeConfig(); -} - -void FacebookResource::configurationChanged() -{ -#ifdef HAVE_ACCOUNTS - if ( Settings::self()->accountId() ) { - configureByAccount( Settings::self()->accountId() ); - } -#endif - Settings::self()->writeConfig(); - synchronize(); -} - -#ifdef HAVE_ACCOUNTS -void FacebookResource::configureByAccount( int accountId ) -{ - kDebug() << "Starting credentials job"; - GetCredentialsJob *gc = new GetCredentialsJob( accountId, this ); - connect(gc, SIGNAL(finished(KJob*)), SLOT(slotGetCredentials(KJob*))); - gc->start(); -} - -void FacebookResource::slotGetCredentials(KJob *job) -{ - if (job->error()) { - return;// We will get kDebug from within the job if it fails - } - - GetCredentialsJob *gJob = qobject_cast(job); - const QVariantMap data = gJob->credentialsData(); - const QString accessToken = data.value(QLatin1String("AccessToken")).toString(); - Settings::self()->setAccessToken(accessToken); - - synchronize(); -} - -#endif -void FacebookResource::aboutToQuit() -{ - slotAbortRequested(); -} - -void FacebookResource::abort() -{ - resetState(); - cancelTask(); -} - -void FacebookResource::abortWithError( const QString &errorMessage, bool authFailure ) -{ - resetState(); - cancelTask( errorMessage ); - - // This doesn't work, why? - if ( authFailure ) { - emit status( Broken, i18n( "Unable to login to Facebook, authentication failure." ) ); - } -} - -void FacebookResource::resetState() -{ - mIdle = true; - mNumFriends = -1; - mNumPhotosFetched = 0; - mCurrentJobs.clear(); - mExistingFriends.clear(); - mNewOrChangedFriends.clear(); - mPendingFriends.clear(); -} - -void FacebookResource::slotAbortRequested() -{ - if ( !mIdle ) { - foreach ( const QPointer &job, mCurrentJobs ) { - kDebug() << "Killing current job:" << job; - job->kill( KJob::Quietly ); - } - abort(); - } -} - -void FacebookResource::configure( WId windowId ) -{ - const QPointer settingsDialog( new SettingsDialog( this, windowId ) ); - if ( settingsDialog->exec() == QDialog::Accepted ) { - emit configurationDialogAccepted(); - } else { - emit configurationDialogRejected(); - } - - delete settingsDialog; -} - -void FacebookResource::retrieveItems( const Akonadi::Collection &collection ) -{ - Q_ASSERT( mIdle ); - - if ( collection.remoteId() == friendsRID ) { - mIdle = false; - emit status( Running, i18n( "Preparing sync of friends list." ) ); - emit percent( 0 ); - ItemFetchJob * const fetchJob = new ItemFetchJob( collection ); - fetchJob->fetchScope().fetchAttribute(); - fetchJob->fetchScope().fetchFullPayload( false ); - mCurrentJobs << fetchJob; - connect( fetchJob, SIGNAL(result(KJob*)), this, SLOT(initialItemFetchFinished(KJob*)) ); - } else if ( collection.remoteId() == eventsRID ) { - mIdle = false; - emit status( Running, i18n( "Preparing sync of events list." ) ); - emit percent( 0 ); - KFbAPI::AllEventsListJob * const listJob = - new KFbAPI::AllEventsListJob( Settings::self()->accessToken(), this ); - listJob->setLowerLimit( KDateTime::fromString( Settings::self()->lowerLimit(), QLatin1String("%Y-%m-%d") ) ); - mCurrentJobs << listJob; - connect( listJob, SIGNAL(result(KJob*)), this, SLOT(eventListFetched(KJob*)) ); - listJob->start(); - } else if ( collection.remoteId() == notesRID ) { - mIdle = false; - emit status( Running, i18n( "Preparing sync of notes list." ) ); - emit percent( 0 ); - KFbAPI::AllNotesListJob * const notesJob = - new KFbAPI::AllNotesListJob( Settings::self()->accessToken(), this ); - notesJob->setLowerLimit( KDateTime::fromString( Settings::self()->lowerLimit(), QLatin1String("%Y-%m-%d") ) ); - mCurrentJobs << notesJob; - connect( notesJob, SIGNAL(result(KJob*)), this, SLOT(noteListFetched(KJob*)) ); - notesJob->start(); - } else if ( collection.remoteId() == postsRID ) { - mIdle = false; - emit status( Running, i18n( "Preparing sync of posts." ) ); - emit percent( 0 ); - KFbAPI::AllPostsListJob * const postsJob = - new KFbAPI::AllPostsListJob( Settings::self()->accessToken(), this ); - postsJob->setLowerLimit( - KDateTime::fromString( - KDateTime::currentLocalDateTime().addDays( -3 ).toString(), QLatin1String("%Y-%m-%d") ) ); - mCurrentJobs << postsJob; - connect( postsJob, SIGNAL(result(KJob*)), this, SLOT(postsListFetched(KJob*)) ); - postsJob->start(); - } else if ( collection.remoteId() == notificationsRID ) { - mIdle = false; - emit status( Running, i18n( "Preparing sync of notifications." ) ); - emit percent( 0 ); - KFbAPI::NotificationsListJob * const notificationsJob = - new KFbAPI::NotificationsListJob( Settings::self()->accessToken(), this ); - mCurrentJobs << notificationsJob; - connect( notificationsJob, SIGNAL(result(KJob*)), this, SLOT(notificationsListFetched(KJob*)) ); - notificationsJob->start(); - } else { - // This can not happen - Q_ASSERT( !"Unknown Collection" ); - cancelTask(); - } -} - -bool FacebookResource::retrieveItem( const Akonadi::Item &item, const QSet &parts ) -{ - Q_UNUSED( parts ); - - kDebug() << item.mimeType(); - - if ( item.mimeType() == KABC::Addressee::mimeType() ) { - // TODO: Is this ever called?? - mIdle = false; - KFbAPI::FriendJob * const friendJob = - new KFbAPI::FriendJob( item.remoteId(), Settings::self()->accessToken(), this ); - mCurrentJobs << friendJob; - friendJob->setProperty( "Item", QVariant::fromValue( item ) ); - connect( friendJob, SIGNAL(result(KJob*)), this, SLOT(friendJobFinished(KJob*)) ); - friendJob->start(); - } else if ( item.mimeType() == Akonadi::NoteUtils::noteMimeType() ) { - mIdle = false; - KFbAPI::NoteJob * const noteJob = - new KFbAPI::NoteJob( item.remoteId(), Settings::self()->accessToken(), this ); - mCurrentJobs << noteJob; - noteJob->setProperty( "Item", QVariant::fromValue( item ) ); - connect( noteJob, SIGNAL(result(KJob*)), this, SLOT(noteJobFinished(KJob*)) ); - noteJob->start(); - } else if( item.mimeType() == QLatin1String("text/x-vnd.akonadi.socialfeeditem") ) { - mIdle = false; - KFbAPI::PostJob * const postJob = - new KFbAPI::PostJob( item.remoteId(), Settings::self()->accessToken(), this ); - mCurrentJobs << postJob; - postJob->setProperty( "Item", QVariant::fromValue( item ) ); - connect( postJob, SIGNAL(result(KJob*)), this, SLOT(postJobFinished(KJob*)) ); - postJob->start(); - } else if ( item.mimeType() == QLatin1String("text/x-vnd.akonadi.socialnotification") ) { - //FIXME: Need to figure out how to fetch single notification - kDebug() << "Notifications listjob"; - } - return true; -} - -void FacebookResource::retrieveCollections() -{ - Collection::List collections; - if (Settings::self()->accountServices().contains(QLatin1String("facebook-contacts"))) { - Collection friends; - friends.setRemoteId( friendsRID ); - friends.setName( i18nc( "@title: addressbook name", "Friends on Facebook" ) ); - friends.setParentCollection( Akonadi::Collection::root() ); - friends.setContentMimeTypes( QStringList() << KABC::Addressee::mimeType() ); - friends.setRights( Collection::ReadOnly ); - EntityDisplayAttribute * const friendsDisplayAttribute = new EntityDisplayAttribute(); - friendsDisplayAttribute->setIconName( QLatin1String("facebookresource") ); - friends.addAttribute( friendsDisplayAttribute ); - collections << friends; - } - - if (Settings::self()->accountServices().contains(QLatin1String("facebook-events"))) { - Collection events; - events.setRemoteId( eventsRID ); - events.setName( i18nc( "@title: events collection title", "Events on Facebook" ) ); - events.setParentCollection( Akonadi::Collection::root() ); - events.setContentMimeTypes( QStringList() << QLatin1String("text/calendar") << eventMimeType ); - events.setRights( Collection::ReadOnly ); - EntityDisplayAttribute * const evendDisplayAttribute = new EntityDisplayAttribute(); - evendDisplayAttribute->setIconName( QLatin1String("facebookresource") ); - events.addAttribute( evendDisplayAttribute ); - collections << events; - } - - if (Settings::self()->accountServices().contains(QLatin1String("facebook-notes"))) { - Collection notes; - notes.setRemoteId( notesRID ); - notes.setName( i18nc( "@title: notes collection", "Notes on Facebook" ) ); - notes.setParentCollection( Akonadi::Collection::root() ); - notes.setContentMimeTypes( QStringList() << Akonadi::NoteUtils::noteMimeType() ); - notes.setRights( Collection::ReadOnly ); - EntityDisplayAttribute * const notesDisplayAttribute = new EntityDisplayAttribute(); - notesDisplayAttribute->setIconName( QLatin1String("facebookresource") ); - notes.addAttribute( notesDisplayAttribute ); - collections << notes; - } - - if (Settings::self()->accountServices().contains(QLatin1String("facebook-feed"))) { - Collection posts; - posts.setRemoteId( postsRID ); - posts.setName( i18nc( "@title: posts collection", "Posts on Facebook" ) ); - posts.setParentCollection( Akonadi::Collection::root() ); - posts.setContentMimeTypes( QStringList() << QLatin1String("text/x-vnd.akonadi.socialfeeditem") ); - posts.setRights( Collection::CanCreateItem ); - EntityDisplayAttribute * const postsDisplayAttribute = new EntityDisplayAttribute(); - postsDisplayAttribute->setIconName( QLatin1String("facebookresource") ); - //facebook's max post length is 63206 as of September 2012 - //(Facebook ... Face Boo K ... hex(FACE) – K ... 64206 – 1000 = 63206)...don't ask me. - SocialNetworkAttributes * const socialAttributes = - new SocialNetworkAttributes( Settings::self()->userName(), - QLatin1String( "Facebook" ), - true, - 63206 ); - posts.addAttribute( postsDisplayAttribute ); - posts.addAttribute( socialAttributes ); - collections << posts; - } - - if (Settings::self()->accountServices().contains(QLatin1String("facebook-notifications"))) { - Collection notifications; - notifications.setRemoteId( notificationsRID ); - notifications.setName( i18nc( "@title: notifications collection", "Notifications on Facebook" ) ); - notifications.setParentCollection( Akonadi::Collection::root() ); - notifications.setContentMimeTypes( QStringList() << QLatin1String("text/x-vnd.akonadi.socialnotification") ); - notifications.setRights( Collection::ReadOnly ); - EntityDisplayAttribute * const notificationsDisplayAttribute = new EntityDisplayAttribute(); - notificationsDisplayAttribute->setIconName( QLatin1String("facebookresource") ); - notifications.addAttribute( notificationsDisplayAttribute ); - collections << notifications; - } - - collectionsRetrieved( collections ); -} - -void FacebookResource::itemRemoved( const Akonadi::Item &item ) -{ - if ( item.mimeType() == QLatin1String("text/x-vnd.akonadi.note") ) { - mIdle = false; - KFbAPI::FacebookDeleteJob * const deleteJob = - new KFbAPI::FacebookDeleteJob( item.remoteId(), - Settings::self()->accessToken(), - this ); - mCurrentJobs << deleteJob; - deleteJob->setProperty( "Item", QVariant::fromValue( item ) ); - connect( deleteJob, SIGNAL(result(KJob*)), this, SLOT(deleteJobFinished(KJob*)) ); - deleteJob->start(); - } else { - // Shouldn't happen, all other items are read-only - Q_ASSERT( !"Unable to delete item, not ours." ); - cancelTask(); - } -} - -void FacebookResource::deleteJobFinished( KJob *job ) -{ - Q_ASSERT( !mIdle ); - Q_ASSERT( mCurrentJobs.indexOf( job ) != -1 ); - mCurrentJobs.removeAll( job ); - if ( job->error() ) { - abortWithError( i18n( "Unable to delete note from server: %1", job->errorText() ) ); - } else { - const Item item = job->property( "Item" ).value(); - changeCommitted( item ); - resetState(); - } -} - -void FacebookResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ) -{ - if ( collection.remoteId() == notesRID ) { - if ( item.hasPayload() ) { - const KMime::Message::Ptr note = item.payload(); - const QString subject = note->subject()->asUnicodeString(); - const QString message = QString::fromUtf8(note->body()); - - mIdle = false; - KFbAPI::NoteAddJob * const addJob = - new KFbAPI::NoteAddJob( subject, message, Settings::self()->accessToken(), this ); - mCurrentJobs << addJob; - addJob->setProperty( "Item", QVariant::fromValue( item ) ); - connect( addJob, SIGNAL(result(KJob*)), this, SLOT(noteAddJobFinished(KJob*)) ); - addJob->start(); - } else { - Q_ASSERT( !"Note has wrong mimetype." ); - cancelTask(); - } - } else if ( collection.remoteId() == postsRID ) { - kDebug() << "Adding new status"; - QString message; - if ( item.hasPayload() ) { - message = item.payload().message(); - mIdle = false; - } else if ( item.hasPayload() ) { - message = item.payload().postText(); - mIdle = false; - } - - KFbAPI::PostAddJob * const addJob = - new KFbAPI::PostAddJob( message, Settings::self()->accessToken(), this ); - mCurrentJobs << addJob; - addJob->setProperty( "Item", QVariant::fromValue( item ) ); - connect( addJob, SIGNAL(result(KJob*)), this, SLOT(postAddJobFinished(KJob*)) ); - addJob->start(); - - } else { - Q_ASSERT( !"Can not add this type of item!" ); - cancelTask(); - } -} - -AKONADI_RESOURCE_MAIN( FacebookResource ) diff -Nru kdepim-runtime-4.14.6/resources/facebook/facebookresource.desktop kdepim-runtime-15.08.0/resources/facebook/facebookresource.desktop --- kdepim-runtime-4.14.6/resources/facebook/facebookresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/facebookresource.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -[Desktop Entry] -Name=Facebook -Name[bs]=Facebook -Name[ca]=Facebook -Name[ca@valencia]=Facebook -Name[cs]=Facebook -Name[da]=Facebook -Name[de]=Facebook -Name[el]=Facebook -Name[en_GB]=Facebook -Name[es]=Facebook -Name[et]=Facebook -Name[fi]=Facebook -Name[fr]=Facebook -Name[gl]=Facebook -Name[hu]=Facebook -Name[ia]=Facebook -Name[it]=Facebook -Name[kk]=Facebook -Name[ko]=Facebook -Name[lt]=Facebook -Name[nb]=Facebook -Name[nds]=Facebook -Name[nl]=Facebook -Name[nn]=Facebook -Name[pl]=Facebook -Name[pt]=Facebook -Name[pt_BR]=Facebook -Name[ru]=Facebook -Name[sk]=Facebook -Name[sr]=Фејсбук -Name[sr@ijekavian]=Фејсбук -Name[sr@ijekavianlatin]=Facebook -Name[sr@latin]=Facebook -Name[sv]=Facebook -Name[tr]=Facebook -Name[ug]=فېيىسبۇك(Facebook) -Name[uk]=Facebook -Name[x-test]=xxFacebookxx -Name[zh_CN]=Facebook -Name[zh_TW]=Facebook -Comment=Makes your Facebook data available in KDE -Comment[bs]=Čini vaše Facebook podatke dostupnim u KDE -Comment[ca]=Fa que les vostres dades de Facebook estiguin disponibles al KDE -Comment[ca@valencia]=Fa que les vostres dades de Facebook estiguen disponibles al KDE -Comment[cs]=Zpřístupňuje váš Facebook v KDE -Comment[da]=Gør dine Facebook-data tilgængelige i KDE -Comment[de]=Stellt Ihre Facebook-Daten in KDE zur Verfügung -Comment[el]=Κάνει τα δεδομένα σας στο Facebook διαθέσιμα στο KDE -Comment[en_GB]=Makes your Facebook data available in KDE -Comment[es]=Hace que sus datos de Facebook estén disponibles en KDE -Comment[et]=Oma Facebooki andmete kättesaadavaks tegemine KDE-s -Comment[fi]=Tuo Facebook-tietosi KDE:ssa käytettäviksi -Comment[fr]=Permet d'accéder à vos données Facebook depuis KDE -Comment[gl]=Pon os seus datos do Facebook a disposición do KDE -Comment[hu]=Elérhetővé teszi a Facebook adatait a KDE-ben -Comment[ia]=face que tu datos de Facebook es disponibile in KDE -Comment[it]=Rende disponibile i tuoi dati Facebook in KDE -Comment[kk]=Facebook деректеріңізді KDE-де қол жетімді қылу -Comment[ko]=KDE에서 Facebook 데이터 사용 -Comment[lt]=Padaro Jūsų Facebook duomenis pasiekiamus KDE -Comment[nb]=Gjør dine Facebook-data tilgjengelige i KDE -Comment[nds]=Maakt Dien Facebook-Daten binnen KDE verföögbor -Comment[nl]=Maakt uw Facebook gegevens beschikbaar in KDE -Comment[pl]=Umożliwia dostęp do danych Facebooka z KDE -Comment[pt]=Disponibiliza os seus dados do Facebook no KDE -Comment[pt_BR]=Disponibiliza os seus dados do Facebook no KDE -Comment[ru]=Передаёт в KDE ваши данные Facebook -Comment[sk]=Sprístupní vaše Facebook dáta v KDE -Comment[sr]=Чини ваше податке са Фејсбука доступнима под КДЕ‑ом -Comment[sr@ijekavian]=Чини ваше податке са Фејсбука доступнима под КДЕ‑ом -Comment[sr@ijekavianlatin]=Čini vaše podatke sa Facebooka dostupnima pod KDE‑om -Comment[sr@latin]=Čini vaše podatke sa Facebooka dostupnima pod KDE‑om -Comment[sv]=Gör data från Facebook tillgänglig i KDE -Comment[tr]=Facebook verilerinizi KDE içinde kullanılabilir yapar -Comment[ug]=فېيىسبۇكدىكى سانلىق-مەلۇماتلىرىڭىزنى KDE دا ئىشلەيدىغان قىلىدۇ -Comment[uk]=Робить доступними дані Facebook у KDE -Comment[x-test]=xxMakes your Facebook data available in KDExx -Comment[zh_CN]=使得您的 Facebook 数据在 KDE 中可用 -Comment[zh_TW]=透過 Akonadi 將您在 Facebook 上的資料與 KDE 同步。 -Type=AkonadiResource -Exec=akonadi_facebook_resource -Icon=facebookresource -X-Akonadi-Custom-KAccounts=facebook-contacts,facebook-feed,facebook-events,facebook-notes,facebook-notifications -X-Akonadi-MimeTypes=text/directory,text/calendar,application/x-vnd.akonadi.calendar.event,application/x-vnd.akonadi.note,text/x-vnd.akonadi.socialfeeditem,text/x-vnd.akonadi.socialnotification -X-Akonadi-Capabilities=Resource -X-Akonadi-Identifier=akonadi_facebook_resource diff -Nru kdepim-runtime-4.14.6/resources/facebook/facebookresource_events.cpp kdepim-runtime-15.08.0/resources/facebook/facebookresource_events.cpp --- kdepim-runtime-4.14.6/resources/facebook/facebookresource_events.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/facebookresource_events.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -/* - Copyright 2010, 2011 Thomas McGuire - Copyright 2011 Roeland Jago Douma - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "facebookresource.h" -#include "settings.h" -#include "settingsdialog.h" -#include "timestampattribute.h" - -#include -#include - -#include -#include -#include -#include -#include - -using namespace Akonadi; - -void FacebookResource::eventListFetched( KJob *job ) -{ - Q_ASSERT( !mIdle ); - Q_ASSERT( mCurrentJobs.indexOf( job ) != -1 ); - KFbAPI::AllEventsListJob * const listJob = qobject_cast( job ); - Q_ASSERT( listJob ); - mCurrentJobs.removeAll( job ); - - if ( listJob->error() ) { - abortWithError( i18n( "Unable to get events from server: %1", listJob->errorString() ), - listJob->error() == KFbAPI::FacebookJob::AuthenticationProblem ); - } else { - QStringList eventIds; - foreach ( const KFbAPI::EventInfo &event, listJob->allEvents() ) { - eventIds.append( event.id() ); - } - if ( eventIds.isEmpty() ) { - itemsRetrievalDone(); - finishEventsFetching(); - return; - } - KFbAPI::EventJob * const eventJob = - new KFbAPI::EventJob( eventIds, Settings::self()->accessToken(), this ); - mCurrentJobs << eventJob; - connect( eventJob, SIGNAL(result(KJob*)), this, SLOT(detailedEventListJobFinished(KJob*)) ); - eventJob->start(); - } - - listJob->deleteLater(); -} - -void FacebookResource::detailedEventListJobFinished( KJob *job ) -{ - Q_ASSERT( !mIdle ); - Q_ASSERT( mCurrentJobs.indexOf( job ) != -1 ); - KFbAPI::EventJob * const eventJob = qobject_cast( job ); - Q_ASSERT( eventJob ); - mCurrentJobs.removeAll( job ); - - if ( job->error() ) { - abortWithError( i18n( "Unable to get list of events from server: %1", eventJob->errorText() ) ); - } else { - setItemStreamingEnabled( true ); - - Item::List eventItems; - foreach ( const KFbAPI::EventInfo &eventInfo, eventJob->eventInfo() ) { - if (eventInfo.id().isEmpty()) { - //skip invalid events - continue; - } - Item event; - event.setRemoteId( eventInfo.id() ); - event.setPayload( eventInfo.asEvent() ); - event.setMimeType( eventMimeType ); - eventItems.append( event ); - } - itemsRetrieved( eventItems ); - itemsRetrievalDone(); - finishEventsFetching(); - } - - eventJob->deleteLater(); -} - -void FacebookResource::finishEventsFetching() -{ - emit percent( 100 ); - // TODO: Use an actual number here - emit status( Idle, i18n( "All events fetched from server." ) ); - resetState(); -} diff -Nru kdepim-runtime-4.14.6/resources/facebook/facebookresource_friends.cpp kdepim-runtime-15.08.0/resources/facebook/facebookresource_friends.cpp --- kdepim-runtime-4.14.6/resources/facebook/facebookresource_friends.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/facebookresource_friends.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,260 +0,0 @@ -/* - Copyright 2010, 2011 Thomas McGuire - Copyright 2011 Roeland Jago Douma - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "facebookresource.h" -#include "settings.h" -#include "settingsdialog.h" -#include "timestampattribute.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - -using namespace Akonadi; - -void FacebookResource::initialItemFetchFinished( KJob *job ) -{ - Q_ASSERT( !mIdle ); - Q_ASSERT( mCurrentJobs.indexOf( job ) != -1 ); - ItemFetchJob * const itemFetchJob = dynamic_cast( job ); - Q_ASSERT( itemFetchJob ); - mCurrentJobs.removeAll( job ); - - if ( itemFetchJob->error() ) { - abortWithError( i18n( "Unable to get list of existing friends from the Akonadi server: %1", - itemFetchJob->errorString() ) ); - } else { - foreach ( const Item &item, itemFetchJob->items() ) { - if ( item.hasAttribute() ) { - mExistingFriends.insert( item.remoteId(), - item.attribute()->timeStamp() ); - } - } - - setItemStreamingEnabled( true ); - KFbAPI::FriendListJob * const friendListJob = - new KFbAPI::FriendListJob( Settings::self()->accessToken(), this ); - mCurrentJobs << friendListJob; - connect( friendListJob, SIGNAL(result(KJob*)), this, SLOT(friendListJobFinished(KJob*)) ); - emit status( Running, i18n( "Retrieving friends list." ) ); - emit percent( 2 ); - friendListJob->start(); - } - - itemFetchJob->deleteLater(); -} - -void FacebookResource::friendListJobFinished( KJob *job ) -{ - Q_ASSERT( !mIdle ); - Q_ASSERT( mCurrentJobs.indexOf( job ) != -1 ); - KFbAPI::FriendListJob * const friendListJob = dynamic_cast( job ); - Q_ASSERT( friendListJob ); - mCurrentJobs.removeAll( job ); - - if ( friendListJob->error() ) { - abortWithError( i18n( "Unable to get list of friends from server: %1", - friendListJob->errorText() ), - friendListJob->error() == KFbAPI::FacebookJob::AuthenticationProblem ); - } else { - - // Figure out which items are new or changed - foreach ( const KFbAPI::UserInfo &user, friendListJob->friends() ) { -#if 0 // Bah, Facebook's timestamp doesn't seem to get updated when a user's profile changes :( - // See http://bugs.developers.facebook.net/show_bug.cgi?id=15475 - const KDateTime stampOfExisting = mExistingFriends.value( user->id(), KDateTime() ); - if ( !stampOfExisting.isValid() ) { - kDebug() << "Friend" << user->id() << user->name() << "is new!"; - mNewOrChangedFriends.append( user ); - } else if ( user->updatedTime() > stampOfExisting ) { - kDebug() << "Friend" << user->id() << user->name() << "is updated!"; - mNewOrChangedFriends.append( user ); - } else { - //kDebug() << "Friend" << user->id() << user->name() << "is old."; - } -#else - mNewOrChangedFriends.append( user ); -#endif - } - - // Delete items that are in the Akonadi DB but no on FB - Item::List removedItems; - foreach ( const QString &friendId, mExistingFriends.keys() ) { //krazy:exclude=foreach - bool found = false; - foreach ( const KFbAPI::UserInfo &user, friendListJob->friends() ) { - if ( user.id() == friendId ) { - found = true; - break; - } - } - if ( !found ) { - kDebug() << friendId << "is no longer your friend :("; - Item removedItem; - removedItem.setRemoteId( friendId ); - removedItems.append( removedItem ); - } - } - itemsRetrievedIncremental( Item::List(), removedItems ); - - if ( mNewOrChangedFriends.isEmpty() ) { - finishFriendFetching(); - } else { - emit status( Running, i18n( "Retrieving friends' details." ) ); - emit percent( 5 ); - fetchNewOrChangedFriends(); - } - } - - friendListJob->deleteLater(); -} - -void FacebookResource::fetchNewOrChangedFriends() -{ - QStringList mewOrChangedFriendIds; - Q_FOREACH ( const KFbAPI::UserInfo &user, mNewOrChangedFriends ) { - mewOrChangedFriendIds.append( user.id() ); - } - KFbAPI::FriendJob * const friendJob = - new KFbAPI::FriendJob( mewOrChangedFriendIds, Settings::self()->accessToken(), this ); - mCurrentJobs << friendJob; - connect( friendJob, SIGNAL(result(KJob*)), this, SLOT(detailedFriendListJobFinished(KJob*)) ); - friendJob->start(); -} - -void FacebookResource::detailedFriendListJobFinished( KJob *job ) -{ - Q_ASSERT( !mIdle ); - Q_ASSERT( mCurrentJobs.indexOf( job ) != -1 ); - KFbAPI::FriendJob * const friendJob = dynamic_cast( job ); - Q_ASSERT( friendJob ); - mCurrentJobs.removeAll( job ); - - if ( friendJob->error() ) { - abortWithError( i18n( "Unable to retrieve friends' information from server: %1", - friendJob->errorText() ) ); - } else { - mPendingFriends = friendJob->friendInfo(); - mNumFriends = mPendingFriends.size(); - emit status( Running, i18n( "Retrieving friends' photos." ) ); - emit percent( 10 ); - fetchPhotos(); - } - - friendJob->deleteLater(); -} - -void FacebookResource::fetchPhotos() -{ - mIdle = false; - mNumPhotosFetched = 0; - Q_FOREACH ( const KFbAPI::UserInfo &f, mPendingFriends ) { - KFbAPI::PhotoJob * const photoJob = - new KFbAPI::PhotoJob( f.id(), Settings::self()->accessToken(), this ); - mCurrentJobs << photoJob; - photoJob->setProperty( "friend", QVariant::fromValue( f ) ); - connect( photoJob, SIGNAL(result(KJob*)), this, SLOT(photoJobFinished(KJob*)) ); - photoJob->start(); - } -} - -void FacebookResource::finishFriendFetching() -{ - Q_ASSERT( mCurrentJobs.size() == 0 ); - - mPendingFriends.clear(); - emit percent( 100 ); - if ( mNumFriends > 0 ) { - emit status( Idle, i18np( "Updated one friend from the server.", - "Updated %1 friends from the server.", mNumFriends ) ); - } else { - emit status( Idle, i18n( "Finished, no friends needed to be updated." ) ); - } - resetState(); -} - -void FacebookResource::photoJobFinished( KJob *job ) -{ - Q_ASSERT( !mIdle ); - Q_ASSERT( mCurrentJobs.indexOf( job ) != -1 ); - KFbAPI::PhotoJob * const photoJob = dynamic_cast( job ); - Q_ASSERT( photoJob ); - const KFbAPI::UserInfo user = job->property( "friend" ).value(); - mCurrentJobs.removeOne( job ); - - if ( photoJob->error() ) { - abortWithError( i18n( "Unable to retrieve friends' photo from server: %1", - photoJob->errorText() ) ); - } else { - // Create Item - KABC::Addressee addressee = user.toAddressee(); - addressee.setPhoto( KABC::Picture( photoJob->photo() ) ); - Item newUser; - newUser.setRemoteId( user.id() ); - newUser.setMimeType( QLatin1String("text/directory") ); - newUser.setPayload( addressee ); - TimeStampAttribute * const timeStampAttribute = new TimeStampAttribute(); - timeStampAttribute->setTimeStamp( user.updatedTime() ); - newUser.addAttribute( timeStampAttribute ); - - itemsRetrievedIncremental( Item::List() << newUser, Item::List() ); - mNumPhotosFetched++; - - if ( mNumPhotosFetched != mNumFriends ) { - const int alreadyDownloadedFriends = mNumPhotosFetched; - const float percentageDone = alreadyDownloadedFriends / ( float )mNumFriends * 100.0f; - emit percent( 10 + percentageDone * 0.9f ); - } else { - itemsRetrievalDone(); - finishFriendFetching(); - } - } - - photoJob->deleteLater(); -} - -void FacebookResource::friendJobFinished( KJob *job ) -{ - Q_ASSERT( !mIdle ); - Q_ASSERT( mCurrentJobs.indexOf( job ) != -1 ); - KFbAPI::FriendJob * const friendJob = dynamic_cast( job ); - Q_ASSERT( friendJob ); - Q_ASSERT( friendJob->friendInfo().size() == 1 ); - mCurrentJobs.removeAll( job ); - - if ( friendJob->error() ) { - abortWithError( i18n( "Unable to get information about friend from server: %1", - friendJob->errorText() ) ); - } else { - Item user = friendJob->property( "Item" ).value(); - user.setPayload( friendJob->friendInfo().first().toAddressee() ); - // TODO: What about picture here? - itemRetrieved( user ); - resetState(); - } - - friendJob->deleteLater(); -} diff -Nru kdepim-runtime-4.14.6/resources/facebook/facebookresource.h kdepim-runtime-15.08.0/resources/facebook/facebookresource.h --- kdepim-runtime-4.14.6/resources/facebook/facebookresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/facebookresource.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,145 +0,0 @@ -/* - Copyright 2010, 2011 Thomas McGuire - Copyright 2011 Roeland Jago Douma - Copyright 2012 Martin Klapetek - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 FACEBOOK_FACEBOOKRESOURCE_H -#define FACEBOOK_FACEBOOKRESOURCE_H - -#include -#include -#include - -#include - -#include -#include - -class KStatusNotifierItem; - -static const QLatin1String notificationsRID( "notifications" ); -static const QLatin1String friendsRID( "friends" ); -static const QLatin1String eventsRID( "events" ); -static const QLatin1String eventMimeType( "application/x-vnd.akonadi.calendar.event" ); -static const QLatin1String notesRID( "notes" ); -static const QLatin1String postsRID( "posts" ); - -class FacebookResource : public Akonadi::ResourceBase, - public Akonadi::AgentBase::Observer -{ - Q_OBJECT - - public: - explicit FacebookResource( const QString &id ); - ~FacebookResource(); - - using ResourceBase::synchronize; - - public Q_SLOTS: - void configure( WId windowId ); -#ifdef HAVE_ACCOUNTS - void configureByAccount( int accountId ); - void slotGetCredentials(KJob *job); -#endif - protected Q_SLOTS: - void retrieveCollections(); - void retrieveItems( const Akonadi::Collection &col ); - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - - void itemRemoved( const Akonadi::Item &item ); - void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - - protected: - void aboutToQuit(); - - private Q_SLOTS: - - void slotAbortRequested(); - void configurationChanged(); - void friendListJobFinished( KJob *job ); - void friendJobFinished( KJob *job ); - void photoJobFinished( KJob *job ); - void detailedFriendListJobFinished( KJob *job ); - void initialItemFetchFinished( KJob *job ); - void eventListFetched( KJob *job ); - void detailedEventListJobFinished( KJob *job ); - void noteListFetched( KJob *job ); - void noteJobFinished( KJob *job ); - void noteAddJobFinished( KJob *job ); - void postJobFinished( KJob *job ); - void postsListFetched( KJob *job ); - void postAddJobFinished( KJob *job ); - void notificationsListFetched( KJob *job ); - void notificationSNIActivated(bool active, const QPoint &position); - void notificationLinkActivated(); - void notificationMarkAsReadJobFinished(KJob *job); - void notificationCollectionFetchJobFinished(KJob *job); - void markNotificationsAsReadTriggered(); - void hideNotificationsSNITriggered(); - - void deleteJobFinished( KJob *job ); - - private: - void fetchPhotos(); - void resetState(); - void abortWithError( const QString &errorMessage, bool authFailure = false ); - void abort(); - - enum FormattingStringType { - FacebookComment = 0, - FacebookLike = 1 - }; - QString formatI18nString( FormattingStringType type, int n ); - - enum FbNotificationPresentation { - KSNIonly = 0, - KSNIandKNotification = 1 - }; - - void displayNotificationsToUser(FbNotificationPresentation displayType); - - void fetchNewOrChangedFriends(); - void finishFriendFetching(); - void finishEventsFetching(); - void finishNotesFetching(); - void finishPostsFetching(); - void finishNotificationsFetching(); - Akonadi::SocialFeedItem convertToSocialFeedItem( const KFbAPI::PostInfo &postinfo ); - - // Friends that are already stored on the Akonadi server - QMap mExistingFriends; - - // Pending new/changed friends we still need to download - QList mPendingFriends; - - QList mNewOrChangedFriends; - - QList mDisplayedNotifications; - - // Total number of new & changed friends - int mNumFriends; - int mNumPhotosFetched; - - bool mIdle; - QList< QPointer > mCurrentJobs; - - QPointer mNotificationSNI; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/facebook/facebookresource_notes.cpp kdepim-runtime-15.08.0/resources/facebook/facebookresource_notes.cpp --- kdepim-runtime-4.14.6/resources/facebook/facebookresource_notes.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/facebookresource_notes.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -/* - Copyright 2010, 2011 Thomas McGuire - Copyright 2011 Roeland Jago Douma - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "facebookresource.h" -#include "settings.h" -#include "settingsdialog.h" -#include "timestampattribute.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - -using namespace Akonadi; - -void FacebookResource::noteListFetched( KJob *job ) -{ - Q_ASSERT( !mIdle ); - KFbAPI::AllNotesListJob * const listJob = dynamic_cast( job ); - Q_ASSERT( listJob ); - mCurrentJobs.removeAll( job ); - - if ( listJob->error() ) { - abortWithError( i18n( "Unable to get notes from server: %1", listJob->errorString() ), - listJob->error() == KFbAPI::FacebookJob::AuthenticationProblem ); - } else { - setItemStreamingEnabled( true ); - - Item::List noteItems; - foreach ( const KFbAPI::NoteInfo ¬eInfo, listJob->allNotes() ) { - Item note; - note.setRemoteId( noteInfo.id() ); - note.setPayload( noteInfo.asNote() ); - note.setSize( noteInfo.asNote()->size() ); - note.setMimeType( QLatin1String("text/x-vnd.akonadi.note") ); - noteItems.append( note ); - } - - itemsRetrieved( noteItems ); - itemsRetrievalDone(); - finishNotesFetching(); - } - - listJob->deleteLater(); -} - -void FacebookResource::finishNotesFetching() -{ - emit percent( 100 ); - emit status( Idle, i18n( "All notes fetched from server." ) ); - resetState(); -} - -void FacebookResource::noteJobFinished( KJob *job ) -{ - Q_ASSERT( !mIdle ); - Q_ASSERT( mCurrentJobs.indexOf( job ) != -1 ); - KFbAPI::NoteJob * const noteJob = dynamic_cast( job ); - Q_ASSERT( noteJob ); - Q_ASSERT( noteJob->noteInfo().size() == 1 ); - mCurrentJobs.removeAll( job ); - - if ( noteJob->error() ) { - abortWithError( i18n( "Unable to get information about note from server: %1", - noteJob->errorText() ) ); - } else { - Item note = noteJob->property( "Item" ).value(); - note.setPayload( noteJob->noteInfo().first().asNote() ); - itemRetrieved( note ); - resetState(); - } - - noteJob->deleteLater(); -} - -void FacebookResource::noteAddJobFinished( KJob *job ) -{ - Q_ASSERT( !mIdle ); - Q_ASSERT( mCurrentJobs.indexOf( job ) != -1 ); - KFbAPI::NoteAddJob * const addJob = dynamic_cast( job ); - Q_ASSERT( addJob ); - mCurrentJobs.removeAll( job ); - - if ( job->error() ) { - abortWithError( i18n( "Unable to get upload note to server: %1", job->errorText() ) ); - } else { - Item note = addJob->property( "Item" ).value(); - note.setRemoteId( addJob->property( "id" ).value() ); - changeCommitted( note ); - resetState(); - } - - addJob->deleteLater(); -} diff -Nru kdepim-runtime-4.14.6/resources/facebook/facebookresource_notifications.cpp kdepim-runtime-15.08.0/resources/facebook/facebookresource_notifications.cpp --- kdepim-runtime-4.14.6/resources/facebook/facebookresource_notifications.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/facebookresource_notifications.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,397 +0,0 @@ -/* - Copyright 2012 Martin Klapetek - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "facebookresource.h" -#include "settings.h" -#include "timestampattribute.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace Akonadi; - -void FacebookResource::notificationsListFetched( KJob *job ) -{ - Q_ASSERT( !mIdle ); - KFbAPI::NotificationsListJob * const listJob = dynamic_cast( job ); - Q_ASSERT( listJob ); - mCurrentJobs.removeAll( job ); - - if ( listJob->error() ) { - abortWithError( i18n( "Unable to get notifications from server: %1", listJob->errorString() ), - listJob->error() == KFbAPI::FacebookJob::AuthenticationProblem ); - } else { - setItemStreamingEnabled( true ); - - Item::List notificationItems; - - //clear any notifications cached for display - mDisplayedNotifications.clear(); - - KSharedConfigPtr knotificationHistory = KSharedConfig::openConfig(QLatin1String("facebook-notificationsrc")); - - Q_FOREACH ( const KFbAPI::NotificationInfo ¬ificationInfo, listJob->notifications() ) { - Item notification; - notification.setRemoteId( notificationInfo.id() ); - notification.setMimeType( QLatin1String("text/x-vnd.akonadi.socialnotification") ); - notification.setPayload( notificationInfo ); - notificationItems.append( notification ); - - if (Settings::self()->displayNotifications()) { - if (notificationInfo.unread()) { - mDisplayedNotifications.append(notificationInfo); - } else { - //if the notification is marked as read, remove it from saved notifications - //to keep it small - knotificationHistory->deleteGroup(notificationInfo.id()); - } - } - } - - if (Settings::self()->displayNotifications()) { - displayNotificationsToUser(FacebookResource::KSNIandKNotification); - } - - itemsRetrieved( notificationItems ); - itemsRetrievalDone(); - finishNotificationsFetching(); - } - - listJob->deleteLater(); -} - -void FacebookResource::finishNotificationsFetching() -{ - emit percent( 100 ); - emit status( Idle, i18n( "All notifications fetched from server." ) ); - resetState(); -} - -void FacebookResource::displayNotificationsToUser(FbNotificationPresentation displayType) -{ - if (mDisplayedNotifications.isEmpty()) { - //if we have no notifications to process, quit - if (!mNotificationSNI.isNull()) { - //also check if the SNI exists, destroy if it is - mNotificationSNI.data()->deleteLater(); - } - return; - } - - if (mNotificationSNI.isNull()) { - mNotificationSNI = new KStatusNotifierItem(this); - mNotificationSNI->setCategory(KStatusNotifierItem::Communications); - mNotificationSNI->setIconByName(QLatin1String("facebookresource")); - mNotificationSNI->setAttentionIconByName(QLatin1String("facebookresource")); - mNotificationSNI->setStandardActionsEnabled(false); - - connect(mNotificationSNI.data(), SIGNAL(activateRequested(bool,QPoint)), - this, SLOT(notificationSNIActivated(bool,QPoint))); - } - - mNotificationSNI->setContextMenu(0); - - //the menu is deleted by SNI whenever we set new context menu - //and/or when the SNI is destroyed - KMenu *contextMenu = new KMenu(); - contextMenu->addTitle(i18n("Facebook Notifications")); - - //use separate config file for the displayed notifications - KSharedConfigPtr knotificationHistory = KSharedConfig::openConfig(QLatin1String("facebook-notificationsrc")); - - //the logic here is - we want to display KNotification for each batch of Facebook notifications - //only once (KNotification will just show the newest not-yet-displayed with "...and N more" appended), - //but on the SNI tooltip we want to show always the newest three, so different strings must be constructed - int tooltipCount = 0; - int notificationCount = 0; - - QString sniTooltip = QLatin1String("
    "); - QString notificationString; - - Q_FOREACH (const KFbAPI::NotificationInfo ¬ification, mDisplayedNotifications) { - - //**** Process KNotification first - - //The KNotification plasmoid shows max 4 lines of text, so unfortunately we need to limit this - //to only one notification being displayed in the notification and then add the "...and N more" - //but this "N more" means "N more notifications that were not displayed before", - //so we need to count how many new notifications we got using the notificationCount var - if (displayType == FacebookResource::KSNIandKNotification) { - KConfigGroup notificationConfig = knotificationHistory->group(notification.id()); - - //this is true if this notification was already in KNotification before - bool skip = false; - - //if we don't have any Facebook notifications to show yet - if (notificationString.isEmpty()) { - - //check if we have stored config for this notification - if (notificationConfig.isValid()) { - //now check if the stored notification has changed or not - if (notificationConfig.readEntry(QLatin1String("updatedTime")) == notification.updatedTimeString()) { - //if it was not changed, just skip it - skip = true; - } - } - - //if the config group does not exist, skip == false and we continue - if (!skip) { - notificationString.append(notification.title()); - notificationString.append(QLatin1String("\n")); - - notificationCount++; - notificationConfig.writeEntry(QLatin1String("updatedTime"), notification.updatedTimeString()); - } else { - kDebug() << "Skipping notification" << notification.id(); - } - } - } - - //**** Process KStatusNotifierItem entries - - //include only up to 3 notifications in the KNotification/SNI tooltip - if (tooltipCount < 3) { - sniTooltip.append(QString::fromLatin1("
  • %1
  • ").arg(notification.title())); - tooltipCount++; - } - - //create for each notification a qaction to put in SNI; - //set the link as property for fast access to it, id is used to remove it - //from the SNI menu - QAction *action = new QAction(notification.title().simplified(), contextMenu); - action->setProperty("notificationLink", notification.link()); - action->setProperty("notificationId", notification.id()); - action->setToolTip(i18nc("@info:tooltip", "Open browser")); - connect(action, SIGNAL(triggered(bool)), - this, SLOT(notificationLinkActivated())); - contextMenu->addAction(action); - } - - sniTooltip = sniTooltip.append(QLatin1String("
")); - - notificationString.append(i18ncp("This string is appended to a Facebook notification displayed " - "in KNotification, indicating how many more notifications " - "were received, but are not displayed. So the KNotification " - "meaning will be 'You have X new Facebook notifications, here's the " - "first one and then there are Y more", - "...and one more", - "...and %1 more", - mDisplayedNotifications.size() - notificationCount)); - - //save which notifications are being displayed in KNotification - knotificationHistory->sync(); - - contextMenu->addSeparator(); - - QAction *dismissAll = new QAction(i18n("Mark all notifications as read"), contextMenu); - connect(dismissAll, SIGNAL(triggered(bool)), - this, SLOT(markNotificationsAsReadTriggered())); - - contextMenu->addAction(dismissAll); - - QAction *hideSNI = new QAction(i18n("Hide"), contextMenu); - connect(hideSNI, SIGNAL(triggered(bool)), - this, SLOT(hideNotificationsSNITriggered())); - - contextMenu->addAction(hideSNI); - - //if we have more than 3 notifications, append "...and N more" at the end of the string - if (mDisplayedNotifications.size() > 3) { - sniTooltip.append(i18ncp("This string is appended at the end of Facebook notifications " - "displayed in the system notifications, indicating there are more " - "notifications, which are not displayed.", - "...and 1 more", - "...and %1 more", - mDisplayedNotifications.size() - 3)); - } - - if (displayType == FacebookResource::KSNIandKNotification && !notificationString.isEmpty()) { - //create the system notification - KNotification *notification = new KNotification(QLatin1String("facebookNotification"), KNotification::CloseOnTimeout); - notification->setTitle(i18np("New Facebook Notification", - "%1 New Facebook Notifications", - mDisplayedNotifications.size())); - notification->setText(notificationString); - //we need to manually create the KAboutData because KGlobal::mainComponent() returns - //the name with appended resource id, ie "akonadi_facebook_resource_72" - //this in turn causes KNotification to not find the .notifyrc file - //so we must set it manually to the name of the .notifyrc file - KAboutData aboutData("akonadi_facebook_resource", 0, KLocalizedString(), 0); - notification->setComponentData(KComponentData(aboutData)); - notification->sendEvent(); - } - - mNotificationSNI->setStatus(KStatusNotifierItem::NeedsAttention); - mNotificationSNI->setContextMenu(contextMenu); - - //if we're handling just one notification, show its text directly in the tooltip, - //otherwise show the tooltip string built above - if (mDisplayedNotifications.size() == 1) { - mNotificationSNI->setProperty("notificationLink", mDisplayedNotifications.first().link()); - mNotificationSNI->setToolTip(QLatin1String("facebookresource"), - mDisplayedNotifications.first().title(), - QString()); - } else { - mNotificationSNI->setToolTip(QLatin1String("facebookresource"), - i18np("You have one new Facebook notification", - "You have %1 new Facebook notifications", - mDisplayedNotifications.size()), - sniTooltip); - } -} - -void FacebookResource::notificationSNIActivated(bool active, const QPoint &point) -{ - Q_UNUSED(active); - - KStatusNotifierItem *sni = qobject_cast(sender()); - - Q_ASSERT(sni); - if (!sni) { - return; - } - - //this property is set only in case we're handling single notification - QUrl link = sni->property("notificationLink").toUrl(); - - if (link.isEmpty()) { - //this^ means we have multiple notifications and we should show the menu - sni->contextMenu()->popup(point); - //The SNI is not deleted in this branch, here's what happens in here: - // - the context menu opens - // - user clicks one of the notifications - // - this notification is removed from the cached list (mDisplayedNotifications) - // - displayNotificationsToUser(..) is called - // - this checks if mDisplayedNotifications is empty, if yes, the SNI is deleted. - } else { - //if we're handling single notification, open the browser and destroy the SNI as it's useful no more - KToolInvocation::invokeBrowser(link.toString()); - sni->deleteLater(); - } -} - -void FacebookResource::notificationLinkActivated() -{ - QUrl link = sender()->property("notificationLink").toUrl(); - QString id = sender()->property("notificationId").toString(); - - //remove the notification from cached notifications - //so it does not reappear in the menu - QMutableListIterator i(mDisplayedNotifications); - while (i.hasNext()) { - if (i.next().id() == id) { - i.remove(); - } - } - - //open the browser with the link - if (!link.isEmpty()) { - KToolInvocation::invokeBrowser(link.toString()); - } - - //mark the notification as read on the server - KFbAPI::NotificationsMarkReadJob * const markNotificationJob = - new KFbAPI::NotificationsMarkReadJob(id, Settings::self()->accessToken(), this); - - mCurrentJobs << markNotificationJob; - connect(markNotificationJob, SIGNAL(result(KJob*)), - this, SLOT(notificationMarkAsReadJobFinished(KJob*))); - - markNotificationJob->start(); - - //trigger reupdate of the SNI - displayNotificationsToUser(FacebookResource::KSNIonly); -} - -void FacebookResource::notificationMarkAsReadJobFinished(KJob *job) -{ - if (job->error()) { - kWarning() << job->errorString() << job->errorText(); - } - - mCurrentJobs.removeAll( job ); - - //only refetch the notifications if there are no more jobs running - if (mCurrentJobs.isEmpty()) { - //refetch notifications - Collection notifications; - notifications.setRemoteId(notificationsRID); - CollectionFetchJob *collectionJob = new CollectionFetchJob(notifications, CollectionFetchJob::Base, this); - - connect(collectionJob, SIGNAL(result(KJob*)), - this, SLOT(notificationCollectionFetchJobFinished(KJob*))); - } - - job->deleteLater(); -} - -void FacebookResource::notificationCollectionFetchJobFinished(KJob *job) -{ - CollectionFetchJob *collectionJob = qobject_cast(job); - - Q_FOREACH(const Akonadi::Collection &collection, collectionJob->collections()) { - if (collection.remoteId() == notificationsRID) { - synchronizeCollection(collection.id()); - //there is only one notifications collection, bail out if it was found - break; - } - } -} - -void FacebookResource::markNotificationsAsReadTriggered() -{ - for (int i = 0; i < mDisplayedNotifications.size(); i++) { - KFbAPI::NotificationsMarkReadJob * const markNotificationJob = - new KFbAPI::NotificationsMarkReadJob(mDisplayedNotifications.at(i).id(), - Settings::self()->accessToken(), - this); - - mCurrentJobs << markNotificationJob; - connect(markNotificationJob, SIGNAL(result(KJob*)), - this, SLOT(notificationMarkAsReadJobFinished(KJob*))); - - markNotificationJob->start(); - } -} - -void FacebookResource::hideNotificationsSNITriggered() -{ - Q_ASSERT(!mNotificationSNI.isNull()); - - if (!mNotificationSNI.isNull()) { - mNotificationSNI->setStatus(KStatusNotifierItem::Passive); - } -} diff -Nru kdepim-runtime-4.14.6/resources/facebook/facebookresource_posts.cpp kdepim-runtime-15.08.0/resources/facebook/facebookresource_posts.cpp --- kdepim-runtime-4.14.6/resources/facebook/facebookresource_posts.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/facebookresource_posts.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,208 +0,0 @@ -/* - Copyright (C) 2012 Martin Klapetek - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "facebookresource.h" -#include "settings.h" -#include "settingsdialog.h" -#include "timestampattribute.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -using namespace Akonadi; - -void FacebookResource::postsListFetched( KJob *job ) -{ - Q_ASSERT( !mIdle ); - KFbAPI::AllPostsListJob * const listJob = dynamic_cast( job ); - Q_ASSERT( listJob ); - mCurrentJobs.removeAll( job ); - - if ( listJob->error() ) { - abortWithError( i18n( "Unable to get posts from server: %1", listJob->errorString() ), - listJob->error() == KFbAPI::FacebookJob::AuthenticationProblem ); - } else { - setItemStreamingEnabled( true ); - - Item::List postItems; - kDebug() << "Going into foreach"; - Q_FOREACH ( const KFbAPI::PostInfo &postInfo, listJob->allPosts() ) { - Item post; - post.setRemoteId( postInfo.id() ); - post.setMimeType( QLatin1String("text/x-vnd.akonadi.socialfeeditem") ); - post.setPayload( convertToSocialFeedItem( postInfo ) ); - postItems.append( post ); - } - - itemsRetrieved( postItems ); - itemsRetrievalDone(); - finishPostsFetching(); - } - - listJob->deleteLater(); -} - -void FacebookResource::finishPostsFetching() -{ - emit percent( 100 ); - emit status( Idle, i18n( "All posts fetched from server." ) ); - resetState(); -} - -void FacebookResource::postJobFinished( KJob *job ) -{ - Q_ASSERT( !mIdle ); - Q_ASSERT( mCurrentJobs.indexOf( job ) != -1 ); - KFbAPI::PostJob * const postJob = dynamic_cast( job ); - Q_ASSERT( postJob ); - Q_ASSERT( postJob->postInfo().size() == 1 ); - mCurrentJobs.removeAll( job ); - - if ( postJob->error() ) { - abortWithError( i18n( "Unable to get information about post from server: %1", - postJob->errorText() ) ); - } else { - Item post = postJob->property( "Item" ).value(); - post.setPayload( convertToSocialFeedItem( postJob->postInfo().first() ) ); - itemRetrieved( post ); - resetState(); - } - - postJob->deleteLater(); -} - -SocialFeedItem FacebookResource::convertToSocialFeedItem( const KFbAPI::PostInfo &postinfo ) -{ - SocialFeedItem item; - item.setPostId( postinfo.id() ); - item.setPostText( postinfo.message().isEmpty() ? postinfo.story() : postinfo.message() ); - item.setPostLink( postinfo.link() ); - item.setPostLinkTitle( postinfo.name() ); - item.setPostImageUrl( postinfo.pictureUrl() ); - item.setPostTime( postinfo.createdTimeString(), QLatin1String( "%Y-%m-%dT%H:%M:%S%z" ) ); - - QString infoString; - - qlonglong commentsCount = postinfo.commentsMap().value( QLatin1String("count") ).toLongLong(); - qlonglong likesCount = postinfo.likesMap().value( QLatin1String("count") ).toLongLong(); - - if ( commentsCount > 0 && likesCount > 0 ) { - infoString = - i18nc( "This is a string putting together two previously translated strings, " - "resulting form is eg '1 comment, 3 likes'. " - "Main purpose of this is to give the ability to change the " - "comma delimiter to something more appropriate for some languages.", - "%1, %2", - formatI18nString( FacebookResource::FacebookComment, commentsCount ), - formatI18nString( FacebookResource::FacebookLike, likesCount ) ); - } else if ( commentsCount > 0 && likesCount == 0 ) { - infoString = formatI18nString( FacebookResource::FacebookComment, commentsCount ); - } else if ( commentsCount == 0 && likesCount > 0 ) { - infoString = formatI18nString( FacebookResource::FacebookLike, likesCount ); - } - -// QList replies; -// -// Q_FOREACH ( const QVariant &listItem, postinfo.commentsMap().value( "data" ).toList() ) { -// QVariantMap listItemMap = listItem.toMap(); -// Akonadi::PostReply postReply; -// postReply.replyText = listItemMap.value( "message" ).toString(); -// postReply.replyId = listItemMap.value( "id" ).toString(); -// postReply.postId = postinfo.id(); -// postReply.userId = listItemMap.value( "from" ).toMap().value( "id" ).toString(); -// postReply.userName = listItemMap.value( "from" ).toMap().value( "name" ).toString(); -// -// replies.append( postReply ); -// } -// -// item.setPostReplies( replies ); - - item.setPostInfo( infoString ); - - KFbAPI::UserInfo user = postinfo.from(); - - item.setUserId( user.id() ); - if ( user.username().isEmpty() ) { - item.setUserName( user.id() ); - } else { - item.setUserName( user.username() ); - } - item.setUserDisplayName( user.name() ); - item.setNetworkString( - i18nc( "This string is used in a sentence " - "'Some Name on Facebook: Just had lunch.', " - "so should be translated in such form. " - "This string is defined by the resource and " - "the whole sentence is composed in the UI.", - "on Facebook" ) ); - item.setAvatarUrl( - QString::fromLatin1( "https://graph.facebook.com/%1/picture?type=square" ).arg( user.id() ) ); - -// item.setItemSourceMap( QJson::QObjectHelper::qobject2qvariant( postinfo.data() ) ); - - return item; -} - -void FacebookResource::postAddJobFinished( KJob *job ) -{ - Q_ASSERT( !mIdle ); - Q_ASSERT( mCurrentJobs.indexOf( job ) != -1 ); - KFbAPI::PostAddJob * const addJob = dynamic_cast( job ); - Q_ASSERT( addJob ); - mCurrentJobs.removeAll( job ); - - if ( job->error() ) { - abortWithError( i18n( "Unable to post the status to server: %1", job->errorText() ) ); - } else { - Item post = addJob->property( "Item" ).value(); - //we fill in a random fake id to prevent duplicates - this post would be in the collection twice - //once the resource syncs again, filling a random id guarantees that this Item will be removed - //with the next sync and will be replaced by the real item from the server - post.setRemoteId( QLatin1String("non-existing-id") ); - changeCommitted( post ); - resetState(); - kDebug() << "Status posted to server"; - } - - addJob->deleteLater(); -} - -QString FacebookResource::formatI18nString( FormattingStringType type, int n ) -{ - switch ( type ) { - case FacebookResource::FacebookComment: - return i18ncp( "Text denoting how many comments given post have", - "1 comment", "%1 comments", n ); - case FacebookResource::FacebookLike: - return i18ncp( "Text denoting how many 'facebook likes' given post have", - "1 like", "%1 likes", n ); - } - - return QString(); -} diff -Nru kdepim-runtime-4.14.6/resources/facebook/icons/CMakeLists.txt kdepim-runtime-15.08.0/resources/facebook/icons/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/facebook/icons/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/icons/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -kde4_install_icons(${ICON_INSTALL_DIR}) Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/facebook/icons/hi16-apps-facebookresource.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/facebook/icons/hi16-apps-facebookresource.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/facebook/icons/hi22-apps-facebookresource.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/facebook/icons/hi22-apps-facebookresource.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/facebook/icons/hi32-apps-facebookresource.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/facebook/icons/hi32-apps-facebookresource.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/facebook/icons/hi48-apps-facebookresource.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/facebook/icons/hi48-apps-facebookresource.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/facebook/icons/hisc-apps-facebookresource.sgvz and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/facebook/icons/hisc-apps-facebookresource.sgvz differ diff -Nru kdepim-runtime-4.14.6/resources/facebook/Info.plist.template kdepim-runtime-15.08.0/resources/facebook/Info.plist.template --- kdepim-runtime-4.14.6/resources/facebook/Info.plist.template 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/Info.plist.template 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - CSResourcesFileMapped - - LSRequiresCarbon - - LSUIElement - 1 - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - - diff -Nru kdepim-runtime-4.14.6/resources/facebook/Messages.sh kdepim-runtime-15.08.0/resources/facebook/Messages.sh --- kdepim-runtime-4.14.6/resources/facebook/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -#! /usr/bin/env bash -$EXTRACTRC `find . -name '*.ui' -o -name '*.kcfg'` >> rc.cpp || exit 11 -$XGETTEXT *.cpp -o $podir/akonadi_facebook_resource.pot -rm -f rc.cpp diff -Nru kdepim-runtime-4.14.6/resources/facebook/serializer/akonadi_serializer_socialnotification.cpp kdepim-runtime-15.08.0/resources/facebook/serializer/akonadi_serializer_socialnotification.cpp --- kdepim-runtime-4.14.6/resources/facebook/serializer/akonadi_serializer_socialnotification.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/serializer/akonadi_serializer_socialnotification.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ -/* - Copyright (C) 2012 Martin Klapetek - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "akonadi_serializer_socialnotification.h" - -#include -#include -#include - -#include - -#include -#include -#include - -#include - -using namespace Akonadi; - -bool SerializerPluginSocialNotification::deserialize( Item &item, const QByteArray &label, - QIODevice &data, int version ) -{ - Q_UNUSED( version ) - - if ( label != Item::FullPayload ) { - return false; - } - - KFbAPI::NotificationInfo object; - - //FIXME: Use QJson::QObjectHelper::qvariant2qobject( item.toMap(), postInfo.data() ); - QJson::Parser parser; - QVariantMap map = parser.parse( data.readAll() ).toMap(); - - object.setId( map[QLatin1String("id")].toString() ); - object.setFrom( map[QLatin1String("from")].toMap() ); - object.setTo( map[QLatin1String("to")].toMap() ); - object.setCreatedTimeString( map[QLatin1String("created_time")].toString() ); - object.setUpdatedTimeString( map[QLatin1String("updated_time")].toString() ); - object.setTitle( map[QLatin1String("title")].toString() ); - object.setMessage( map[QLatin1String("message")].toString() ); - object.setLink( map[QLatin1String("link")].toUrl() ); - object.setApplication( map[QLatin1String("application")].toMap() ); - object.setUnread( map[QLatin1String("unread")].toBool() ); - - item.setMimeType( QLatin1String("text/x-vnd.akonadi.socialnotification") ); - item.setPayload< KFbAPI::NotificationInfo >( object ); - - return true; -} - -void SerializerPluginSocialNotification::serialize( const Item &item, const QByteArray &label, - QIODevice &data, int &version ) -{ - Q_UNUSED( label ) - Q_UNUSED( version ) - - if ( !item.hasPayload< KFbAPI::NotificationInfo >() ) { - return; - } - - KFbAPI::NotificationInfo notificationInfo = item.payload< KFbAPI::NotificationInfo >(); - - QVariantMap map; - - map[QLatin1String("id")] = notificationInfo.id(); - - QVariantMap fromMap; - if ( !notificationInfo.from().id().isEmpty() ) { - fromMap[QLatin1String("name")] = notificationInfo.from().name(); - fromMap[QLatin1String("id")] = notificationInfo.from().id(); - } - - map[QLatin1String("from")] = fromMap; - - QVariantMap toMap; - if ( !notificationInfo.to().id().isEmpty() ) { - toMap[QLatin1String("name")] = notificationInfo.to().name(); - toMap[QLatin1String("id")] = notificationInfo.to().id(); - } - - map[QLatin1String("to")] = toMap; - map[QLatin1String("created_time")] = notificationInfo.createdTimeString(); - map[QLatin1String("updated_time")] = notificationInfo.updatedTimeString(); - map[QLatin1String("title")] = notificationInfo.title(); - map[QLatin1String("message")] = notificationInfo.message(); - map[QLatin1String("link")] = notificationInfo.link(); - - QVariantMap appMap; - if ( !notificationInfo.application().id().isEmpty() ) { - appMap[QLatin1String("name")] = notificationInfo.application().name(); - appMap[QLatin1String("id")] = notificationInfo.application().id(); - } - - map[QLatin1String("app")] = appMap; - map[QLatin1String("unread")] = notificationInfo.unread(); - - QJson::Serializer serializer; - - data.write( serializer.serialize( map ) ); -} - -Q_EXPORT_PLUGIN2( akonadi_serializer_socialnotification, - Akonadi::SerializerPluginSocialNotification ) diff -Nru kdepim-runtime-4.14.6/resources/facebook/serializer/akonadi_serializer_socialnotification.desktop kdepim-runtime-15.08.0/resources/facebook/serializer/akonadi_serializer_socialnotification.desktop --- kdepim-runtime-4.14.6/resources/facebook/serializer/akonadi_serializer_socialnotification.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/serializer/akonadi_serializer_socialnotification.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,84 +0,0 @@ -[Misc] -Name=Facebook Notification Serializer -Name[bs]=Serializator Facebook poruka -Name[ca]=Serialitzador de notificacions de Facebook -Name[ca@valencia]=Serialitzador de notificacions de Facebook -Name[cs]=Řadič upomínek Facebooku -Name[da]=Facebook-notifikation-serializer -Name[de]=Facebook-Benachrichtigungs-Serialisierung -Name[el]=Σειριακοποιητής ειδοποιήσεων Facebook -Name[en_GB]=Facebook Notification Serializer -Name[es]=Serializador de notificaciones de Facebook -Name[et]=Facebooki märguannete jadasti -Name[fi]=Facebookin ilmoitusten serialisoija -Name[fr]=Sérialiseur de notifications Facebook -Name[gl]=Serialización de notificacións do Facebook -Name[hu]=Facebook értesítés leképező -Name[ia]=Facebook Notification Serializer (Divulgator partial de notification de Facebook) -Name[it]=Serializzatore di notifiche da Facebook -Name[kk]=Facebook құлақтандыруды тізбектеуі -Name[ko]=Facebook 알림 시리얼라이저 -Name[lt]=Facebook pranešimų serializatorius -Name[nb]=Facebook varslings-serialisator -Name[nds]=Facebook-Bescheed-Reegmoduul -Name[nl]=Serialisator van Facebook-meldingen -Name[pl]=Program szeregujący powiadomienia na Facebooku -Name[pt]=Serialização das Notificações do Facebook -Name[pt_BR]=Serialização das notificações do Facebook -Name[ru]=Сохранение уведомлений Facebook -Name[sk]=Serializátor upozornení Facebook -Name[sr]=Серијализатор обавештења са Фејсбука -Name[sr@ijekavian]=Серијализатор обавештења са Фејсбука -Name[sr@ijekavianlatin]=Serijalizator obaveštenja sa Facebooka -Name[sr@latin]=Serijalizator obaveštenja sa Facebooka -Name[sv]=Serialisering av underrättelser från Facebook -Name[tr]=Facebook Bildirim Sıralandırıcısı -Name[ug]=فېيىسبۇك ئۇقتۇرۇشىنى تىزغۇچ -Name[uk]=Серіалізатор сповіщень Facebook -Name[x-test]=xxFacebook Notification Serializerxx -Name[zh_CN]=Facebook 通知序列化器 -Name[zh_TW]=Facebook 通知序列器 -Comment=An Akonadi serializer plugin for Facebook notifications -Comment[bs]=Akonadi dodatak serializatora za Facebook poruke -Comment[ca]=Un connector de serialització de l'Akonadi per a les notificacions de Facebook -Comment[ca@valencia]=Un connector de serialització de l'Akonadi per a les notificacions de Facebook -Comment[cs]=Modul Akonadi pro seřazování upomínek Facebooku -Comment[da]=Et Akonadi-serializerplugin til Facebook-notifikationer -Comment[de]=Akonadi-Modul zur Serialisierung von Facebook-Benachrichtigungen -Comment[el]=Ένα πρόσθετο σειριακοποιητή Akonadi για ειδοποιήσεις στο Facebook -Comment[en_GB]=An Akonadi serializer plugin for Facebook notifications -Comment[es]=Un complemento serializador de Akonadi para notificaciones de Facebook -Comment[et]=Akonadi Facebooki märguannete jadastamisplugin -Comment[fi]=Akonadi-serialisoijaliitännäinen Facebookin ilmoituksille -Comment[fr]=Un module externe Akonadi pour la sérialisation des notifications Facebook -Comment[gl]=Un complemento de serialización do Akonadi para notificacións do Facebook -Comment[hu]=Akonadi-leképező modul a Facebook értesítésekhez -Comment[ia]=Un plug-in pro divulgator partial de Akonadi pro notificationes de Facebook -Comment[it]=Un'estensione di Akonadi per la serializzazione delle notifiche di Facebook -Comment[kk]=Akonadi-дің Facebook құлақтандырулар тізбектеуіш плагині -Comment[ko]=Facebook 알림을 위한 Akonadi 시리얼라이저 플러그인 -Comment[lt]=Akonadi serializatoriaus įskiepis Facebook pranešimams -Comment[nb]=Et Akonadi programtillegg for serialisering av Facebook-varslinger -Comment[nds]=Akonadi-Inreegmoduul för Facebook-Bescheden -Comment[nl]=Een Akonadi serialisatorplug-in voor Facebook-meldingen -Comment[pl]=Wtyczka Akonadi do szeregowania powiadomień Facebooka -Comment[pt]=Um 'plugin' de serialização do Akonadi para as notificações do Facebook -Comment[pt_BR]=Plugin de serialização do Akonadi para as notificações do Facebook -Comment[ru]=Модуль сохранения уведомлений Facebook для Akonadi -Comment[sk]=Plugin serializátora Akonadi pre objekty Facebook -Comment[sr]=Аконадијев прикључак серијализатора за обавештења са Фејсбука -Comment[sr@ijekavian]=Аконадијев прикључак серијализатора за обавештења са Фејсбука -Comment[sr@ijekavianlatin]=Akonadijev priključak serijalizatora za obaveštenja sa Facebooka -Comment[sr@latin]=Akonadijev priključak serijalizatora za obaveštenja sa Facebooka -Comment[sv]=Ett Akonadi serialiseringsinsticksprogram för underrättelser från Facebook -Comment[tr]=Facebook bildirileri için bir Akonadi sıralandırıcı eklentisi -Comment[uk]=Додаток серіалізації даних Akonadi для сповіщень Facebook -Comment[x-test]=xxAn Akonadi serializer plugin for Facebook notificationsxx -Comment[zh_CN]=对 Facebook 提醒进行序列转换的 Akonadi 插件 -Comment[zh_TW]=Facebook 通知的 Akonadi 序列器外掛程式 - -[Plugin] -Type=text/x-vnd.akonadi.socialnotification -X-Akonadi-Class=KFbAPI::NotificationInfo; -X-KDE-Library=akonadi_serializer_socialnotification -X-KDE-ClassName=Akonadi::SerializerPluginSocialNotification diff -Nru kdepim-runtime-4.14.6/resources/facebook/serializer/akonadi_serializer_socialnotification.h kdepim-runtime-15.08.0/resources/facebook/serializer/akonadi_serializer_socialnotification.h --- kdepim-runtime-4.14.6/resources/facebook/serializer/akonadi_serializer_socialnotification.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/serializer/akonadi_serializer_socialnotification.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -/* - Copyright (C) 2012 Martin Klapetek - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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_SERIALIZER_SOCIALNOTIFICATION_H -#define AKONADI_SERIALIZER_SOCIALNOTIFICATION_H - -#include -#include - -namespace Akonadi { - -class SerializerPluginSocialNotification : public QObject, public ItemSerializerPlugin -{ - Q_OBJECT - Q_INTERFACES( Akonadi::ItemSerializerPlugin ) - - public: - bool deserialize( Item &item, const QByteArray &label, QIODevice &data, int version ); - void serialize( const Item &item, const QByteArray &label, QIODevice &data, int &version ); -}; - -} - -#endif // AKONADI_SERIALIZER_SOCIALNOTIFICATION_H diff -Nru kdepim-runtime-4.14.6/resources/facebook/serializer/CMakeLists.txt kdepim-runtime-15.08.0/resources/facebook/serializer/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/facebook/serializer/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/serializer/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -project(facebook-notifications-serializer) - -include_directories(${KDE4_INCLUDES} ${KDEPIMLIBS_INCLUDE_DIRS}) - -set(akonadi_serializer_socialnotification_SRCS - akonadi_serializer_socialnotification.cpp -) - -kde4_add_plugin(akonadi_serializer_socialnotification ${akonadi_serializer_socialnotification_SRCS}) - -target_link_libraries(akonadi_serializer_socialnotification - ${KDE4_AKONADI_LIBS} - ${QT_QTCORE_LIBRARY} - ${KDE4_KDECORE_LIBS} - ${LibKFbAPI_LIBRARY} - ${qjson_LIBRARIES} # for Debian - ${QJSON_LIBRARIES} - ${QJSON_LIBRARY} -) - -install( - TARGETS akonadi_serializer_socialnotification - DESTINATION ${PLUGIN_INSTALL_DIR} -) - -install( - FILES akonadi_serializer_socialnotification.desktop - DESTINATION ${DATA_INSTALL_DIR}/akonadi/plugins/serializer -) - -install( - FILES x-vnd.akonadi.socialnotification.xml - DESTINATION ${XDG_MIME_INSTALL_DIR} -) - -update_xdg_mimetypes(${XDG_MIME_INSTALL_DIR}) diff -Nru kdepim-runtime-4.14.6/resources/facebook/serializer/x-vnd.akonadi.socialnotification.xml kdepim-runtime-15.08.0/resources/facebook/serializer/x-vnd.akonadi.socialnotification.xml --- kdepim-runtime-4.14.6/resources/facebook/serializer/x-vnd.akonadi.socialnotification.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/serializer/x-vnd.akonadi.socialnotification.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ - - - - - - Akonadi Social Notification - - \ No newline at end of file diff -Nru kdepim-runtime-4.14.6/resources/facebook/settingsbase.kcfg kdepim-runtime-15.08.0/resources/facebook/settingsbase.kcfg --- kdepim-runtime-4.14.6/resources/facebook/settingsbase.kcfg 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/settingsbase.kcfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ - - - - - - - - - - 2000-01-01 - - - - - - - - - true - - - diff -Nru kdepim-runtime-4.14.6/resources/facebook/settingsbase.kcfgc kdepim-runtime-15.08.0/resources/facebook/settingsbase.kcfgc --- kdepim-runtime-4.14.6/resources/facebook/settingsbase.kcfgc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/settingsbase.kcfgc 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -File=settingsbase.kcfg -ClassName=SettingsBase -Mutators=true -ItemAccessors=true -SetUserTexts=true -Singleton=false -GlobalEnums=true diff -Nru kdepim-runtime-4.14.6/resources/facebook/settings.cpp kdepim-runtime-15.08.0/resources/facebook/settings.cpp --- kdepim-runtime-4.14.6/resources/facebook/settings.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/settings.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/* - Copyright 2010 Thomas McGuire - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "settings.h" -#include "settingsadaptor.h" - - -class SettingsHelper -{ - public: - SettingsHelper() : q( 0 ) {} - ~SettingsHelper() { - delete q; - q = 0; - } - Settings *q; -}; - -K_GLOBAL_STATIC( SettingsHelper, s_globalSettings ) - -Settings *Settings::self() -{ - if ( !s_globalSettings->q ) { - new Settings; - s_globalSettings->q->readConfig(); - } - return s_globalSettings->q; -} - -Settings::Settings() -{ - Q_ASSERT( !s_globalSettings->q ); - s_globalSettings->q = this; - - new SettingsAdaptor( this ); - QDBusConnection::sessionBus().registerObject( - QLatin1String( "/Settings" ), - this, - QDBusConnection::ExportAdaptors | QDBusConnection::ExportScriptableContents ); -} - -void Settings::setWindowId( WId id ) -{ - mWinId = id; -} - -void Settings::setResourceId( const QString &resourceIdentifier ) -{ - mResourceId = resourceIdentifier; -} - -QString Settings::apiKey() const -{ - return QLatin1String("9c41511dae89d7dfb4cde6be07365475"); -} - -QString Settings::appID() const -{ - return QLatin1String("175243235841602"); -} - -QString Settings::appSecret() const -{ - return QLatin1String("57b6eadd130bb9ecff7dcb701558833d"); -} diff -Nru kdepim-runtime-4.14.6/resources/facebook/settingsdialog.cpp kdepim-runtime-15.08.0/resources/facebook/settingsdialog.cpp --- kdepim-runtime-4.14.6/resources/facebook/settingsdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/settingsdialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,226 +0,0 @@ -/* - Copyright 2010 Thomas McGuire - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "settingsdialog.h" -#include "facebookresource.h" -#include "settings.h" -#include "akonadi-version.h" - -#include -#include - -#include -#include -#include - -using namespace Akonadi; - -SettingsDialog::SettingsDialog( FacebookResource *parentResource, WId parentWindow ) - : KDialog(), - mParentResource( parentResource ), - mTriggerSync( false ) -{ - KWindowSystem::setMainWindow( this, parentWindow ); - setButtons( Ok|Cancel|User1 ); - setButtonText( User1, i18n( "About" ) ); - setButtonIcon( User1, KIcon( QLatin1String("help-about") ) ); - setWindowIcon( KIcon( QLatin1String("facebookresource") ) ); - setWindowTitle( i18n( "Facebook Settings" ) ); - - setupWidgets(); - loadSettings(); -} - -SettingsDialog::~SettingsDialog() -{ - if ( mTriggerSync ) { - mParentResource->synchronize(); - } -} - -void SettingsDialog::setupWidgets() -{ - QWidget * const page = new QWidget( this ); - setupUi( page ); - setMainWidget( page ); - updateAuthenticationWidgets(); - updateUserName(); - connect( resetButton, SIGNAL(clicked(bool)), this, SLOT(resetAuthentication()) ); - connect( authenticateButton, SIGNAL(clicked(bool)), this, SLOT(showAuthenticationDialog()) ); -} - -void SettingsDialog::showAuthenticationDialog() -{ - QStringList permissions; - permissions << QLatin1String("offline_access") - << QLatin1String("friends_birthday") - << QLatin1String("friends_website") - << QLatin1String("friends_location") - << QLatin1String("friends_work_history") - << QLatin1String("friends_relationships") - << QLatin1String("manage_notifications") - << QLatin1String("publish_actions") - << QLatin1String("read_stream") - << QLatin1String("user_events") - << QLatin1String("user_notes"); - KFbAPI::AuthenticationDialog * const authDialog = new KFbAPI::AuthenticationDialog( this ); - authDialog->setAppId( Settings::self()->appID() ); - authDialog->setPermissions( permissions ); - connect( authDialog, SIGNAL(authenticated(QString)), - this, SLOT(authenticationDone(QString)) ); - connect( authDialog, SIGNAL(canceled()), - this, SLOT(authenticationCanceled()) ); - authenticateButton->setEnabled( false ); - authDialog->start(); -} - -void SettingsDialog::authenticationCanceled() -{ - authenticateButton->setEnabled( true ); -} - -void SettingsDialog::authenticationDone( const QString &accessToken ) -{ - if ( Settings::self()->accessToken() != accessToken && !accessToken.isEmpty() ) { - mTriggerSync = true; - } - Settings::self()->setAccessToken( accessToken ); - updateAuthenticationWidgets(); - updateUserName(); -} - -void SettingsDialog::updateAuthenticationWidgets() -{ - if ( Settings::self()->accessToken().isEmpty() ) { - authenticationStack->setCurrentIndex( 0 ); - } else { - authenticationStack->setCurrentIndex( 1 ); - if ( Settings::self()->userName().isEmpty() ) { - authenticationLabel->setText( i18n( "Authenticated." ) ); - } else { - authenticationLabel->setText( i18n( "Authenticated as %1.", - Settings::self()->userName() ) ); - } - } -} - -void SettingsDialog::resetAuthentication() -{ - Settings::self()->setAccessToken( QString() ); - Settings::self()->setUserName( QString() ); - updateAuthenticationWidgets(); -} - -void SettingsDialog::updateUserName() -{ - if ( Settings::self()->userName().isEmpty() && ! Settings::self()->accessToken().isEmpty() ) { - KFbAPI::UserInfoJob * const job = - new KFbAPI::UserInfoJob( Settings::self()->accessToken(), this ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(userInfoJobDone(KJob*)) ); - job->start(); - } -} - -void SettingsDialog::userInfoJobDone( KJob *job ) -{ - KFbAPI::UserInfoJob * const userInfoJob = dynamic_cast( job ); - Q_ASSERT( userInfoJob ); - if ( !userInfoJob->error() ) { - Settings::self()->setUserName( userInfoJob->userInfo().name() ); - updateAuthenticationWidgets(); - } else { - kWarning() << "Can't get user info: " << userInfoJob->errorText(); - } -} - -void SettingsDialog::loadSettings() -{ - if ( mParentResource->name() == mParentResource->identifier() ) { - mParentResource->setName( i18n( "Facebook" ) ); - } - - nameEdit->setText( mParentResource->name() ); - nameEdit->setFocus(); - enableNotificationsCheckBox->setChecked( Settings::self()->displayNotifications() ); - -} - -void SettingsDialog::saveSettings() -{ - mParentResource->setName( nameEdit->text() ); - Settings::self()->setDisplayNotifications( enableNotificationsCheckBox->isChecked() ); - if ( !Settings::self()->accountId() ) { - QStringList services; - services << QLatin1String("facebook-contacts") - << QLatin1String("facebook-feed") - << QLatin1String("facebook-events") - << QLatin1String("facebook-notes") - << QLatin1String("facebook-notifications"); - Settings::self()->setAccountServices(services); - } - Settings::self()->writeConfig(); -} - -void SettingsDialog::slotButtonClicked( int button ) -{ - switch( button ) { - case Ok: - saveSettings(); - accept(); - break; - case Cancel: - reject(); - return; - case User1: - { - KAboutData aboutData( - QByteArray( "akonadi_facebook_resource" ), - QByteArray(), - ki18n( "Akonadi Facebook Resource" ), - QByteArray( AKONADI_VERSION ), - ki18n( "Makes your friends, events, notes, posts and messages on Facebook " - "available in KDE via Akonadi." ), - KAboutData::License_GPL_V2, - ki18n( "Copyright (C) 2010,2011,2012,2013 Akonadi Facebook Resource Developers" ) ); - - aboutData.addAuthor( ki18n( "Martin Klapetek" ), - ki18n( "Developer" ), "mklapetek@kde.org" ); - - aboutData.addAuthor( ki18n( "Thomas McGuire" ), - ki18n( "Past Maintainer" ), "mcguire@kde.org" ); - - aboutData.addAuthor( ki18n( "Roeland Jago Douma" ), - ki18n( "Past Developer" ), "unix@rullzer.com" ); - - aboutData.addCredit( ki18n( "Till Adam" ), - ki18n( "MacOS Support" ), "adam@kde.org" ); - - aboutData.setProgramIconName( QLatin1String("facebookresource") ); - aboutData.setTranslator( ki18nc( "NAME OF TRANSLATORS", "Your names" ), - ki18nc( "EMAIL OF TRANSLATORS", "Your emails" ) ); - - KAboutApplicationDialog *dialog = new KAboutApplicationDialog( &aboutData, this ); - dialog->setAttribute( Qt::WA_DeleteOnClose, true ); - dialog->show(); - break; - } - } -} - diff -Nru kdepim-runtime-4.14.6/resources/facebook/settingsdialog.h kdepim-runtime-15.08.0/resources/facebook/settingsdialog.h --- kdepim-runtime-4.14.6/resources/facebook/settingsdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/settingsdialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -/* - Copyright 2010 Thomas McGuire - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 FACEBOOK_SETTINGSDIALOG_H -#define FACEBOOK_SETTINGSDIALOG_H - -#include "ui_settingsdialog.h" - -class FacebookResource; -class KJob; - -class SettingsDialog : public KDialog, private Ui::SettingsDialog -{ - Q_OBJECT - - public: - SettingsDialog( FacebookResource *parentResource, WId parentWindow ); - ~SettingsDialog(); - - private slots: - virtual void slotButtonClicked( int button ); - void resetAuthentication(); - void showAuthenticationDialog(); - void authenticationDone( const QString &accessToken ); - void authenticationCanceled(); - void userInfoJobDone( KJob *job ); - - private: - void setupWidgets(); - void loadSettings(); - void saveSettings(); - void updateAuthenticationWidgets(); - void updateUserName(); - - FacebookResource *mParentResource; - bool mTriggerSync; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/facebook/settingsdialog.ui kdepim-runtime-15.08.0/resources/facebook/settingsdialog.ui --- kdepim-runtime-4.14.6/resources/facebook/settingsdialog.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/settingsdialog.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,181 +0,0 @@ - - - SettingsDialog - - - - 0 - 0 - 427 - 132 - - - - - - - - - Your Internet Service Provider gave you a <em>user name</em> which is used to authenticate you with their servers. It usually is the first part of your email address (the part before <em>@</em>). - - - Account &name: - - - nameEdit - - - - - - - Name displayed in the list of accounts - - - Account name: This defines the name displayed in the account list. - - - - - - - - - 1 - - - - - 0 - - - - - - - Not yet authenticated with Facebook. - - - - - - - Authenticate... - - - - - - - - - - true - - - - In order to access your Facebook data in KDE, you need to authenticate this application with Facebook. To do so, click the above button and follow the instructions on the screen. - - - true - - - - - - - Qt::Vertical - - - - 20 - 54 - - - - - - - - - - - - QFormLayout::ExpandingFieldsGrow - - - - - TextLabel - - - - - - - Reset - - - - - - - Display Facebook notifications: - - - - - - - Enabled - - - true - - - - - - - - - Qt::Vertical - - - - 20 - 102 - - - - - - - - - - - - Qt::Vertical - - - - 20 - 34 - - - - - - - - - KLineEdit - QLineEdit -
klineedit.h
- 1 -
-
- - -
diff -Nru kdepim-runtime-4.14.6/resources/facebook/settings.h kdepim-runtime-15.08.0/resources/facebook/settings.h --- kdepim-runtime-4.14.6/resources/facebook/settings.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/settings.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -/* - Copyright 2010 Thomas McGuire - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 FACEBOOK_SETTINGS_H -#define FACEBOOK_SETTINGS_H - -#include "settingsbase.h" - -#include - -class Settings : public SettingsBase -{ - Q_OBJECT - Q_CLASSINFO( "D-Bus Interface", "org.kde.Akonadi.Facebook.ExtendedSettings" ) - public: - Settings(); - void setWindowId( WId id ); - void setResourceId( const QString &resourceIdentifier ); - static Settings *self(); - - QString appID() const; - QString apiKey() const; - QString appSecret() const; - - private: - WId mWinId; - QString mResourceId; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/facebook/timestampattribute.cpp kdepim-runtime-15.08.0/resources/facebook/timestampattribute.cpp --- kdepim-runtime-4.14.6/resources/facebook/timestampattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/timestampattribute.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -/* - Copyright 2011 Thomas McGuire - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "timestampattribute.h" - -TimeStampAttribute::TimeStampAttribute() -{ -} - -Akonadi::Attribute *TimeStampAttribute::clone() const -{ - TimeStampAttribute * const attribute = new TimeStampAttribute(); - attribute->setTimeStamp( mTimeStamp ); - return attribute; -} - -void TimeStampAttribute::deserialize( const QByteArray &data ) -{ - const QString timeStamp = QString::fromUtf8( data ); - mTimeStamp = KDateTime::fromString( timeStamp ); -} - -QByteArray TimeStampAttribute::serialized() const -{ - return mTimeStamp.toString().toUtf8(); -} - -QByteArray TimeStampAttribute::type() const -{ - return "FACEBOOK_TIMESTAMP"; -} - -void TimeStampAttribute::setTimeStamp( const KDateTime &dateTime ) -{ - mTimeStamp = dateTime; -} - -KDateTime TimeStampAttribute::timeStamp() const -{ - return mTimeStamp; -} diff -Nru kdepim-runtime-4.14.6/resources/facebook/timestampattribute.h kdepim-runtime-15.08.0/resources/facebook/timestampattribute.h --- kdepim-runtime-4.14.6/resources/facebook/timestampattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/facebook/timestampattribute.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* - Copyright 2011 Thomas McGuire - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 FACEBOOK_TIMESTAMPATTRIBUTE_H -#define FACEBOOK_TIMESTAMPATTRIBUTE_H - -#include -#include - -class TimeStampAttribute : public Akonadi::Attribute -{ - public: - TimeStampAttribute(); - virtual Attribute * clone() const; - virtual void deserialize( const QByteArray &data ); - virtual QByteArray serialized() const; - virtual QByteArray type() const; - void setTimeStamp( const KDateTime &dateTime ); - KDateTime timeStamp() const; - private: - KDateTime mTimeStamp; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/folderarchivesettings/autotests/CMakeLists.txt kdepim-runtime-15.08.0/resources/folderarchivesettings/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/folderarchivesettings/autotests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/folderarchivesettings/autotests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -3,8 +3,11 @@ macro( folderarchive_kmail _source ) set( _test ${_source} ../folderarchiveaccountinfo.cpp ) get_filename_component( _name ${_source} NAME_WE ) - kde4_add_unit_test( ${_name} TESTNAME folderarchive-${_name} ${_test} ) - target_link_libraries( ${_name} ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} ${KDE4_KDEUI_LIBS} ${KDEPIMLIBS_AKONADI_LIBS}) + add_executable( ${_name} ${_test} ) + add_test( ${_name} ${_name} ) + ecm_mark_as_test(folderararchive-${_name}) + + target_link_libraries( ${_name} Qt5::Test Qt5::Core KF5::AkonadiCore KF5::ConfigCore) endmacro() folderarchive_kmail(folderarchiveaccountinfotest.cpp) diff -Nru kdepim-runtime-4.14.6/resources/folderarchivesettings/autotests/folderarchiveaccountinfotest.cpp kdepim-runtime-15.08.0/resources/folderarchivesettings/autotests/folderarchiveaccountinfotest.cpp --- kdepim-runtime-4.14.6/resources/folderarchivesettings/autotests/folderarchiveaccountinfotest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/folderarchivesettings/autotests/folderarchiveaccountinfotest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -17,10 +17,9 @@ #include "folderarchiveaccountinfotest.h" #include "../folderarchiveaccountinfo.h" -#include -#include -#include - +#include +#include +#include FolderArchiveAccountInfoTest::FolderArchiveAccountInfoTest(QObject *parent) : QObject(parent) @@ -51,24 +50,24 @@ QVERIFY(!info.isValid()); info.setArchiveTopLevel(Akonadi::Collection(42).id()); QVERIFY(!info.isValid()); - info.setInstanceName(QLatin1String("FOO")); + info.setInstanceName(QStringLiteral("FOO")); QVERIFY(info.isValid()); } void FolderArchiveAccountInfoTest::shouldRestoreFromSettings() { FolderArchiveAccountInfo info; - info.setInstanceName(QLatin1String("FOO1")); + info.setInstanceName(QStringLiteral("FOO1")); info.setArchiveTopLevel(Akonadi::Collection(42).id()); info.setFolderArchiveType(FolderArchiveAccountInfo::FolderByMonths); info.setEnabled(true); info.setKeepExistingStructure(true); - KConfigGroup grp(KGlobal::config(), "testsettings"); + KConfigGroup grp(KSharedConfig::openConfig(), "testsettings"); info.writeConfig(grp); FolderArchiveAccountInfo restoreInfo(grp); QCOMPARE(info, restoreInfo); } -QTEST_KDEMAIN(FolderArchiveAccountInfoTest, NoGUI) +QTEST_MAIN(FolderArchiveAccountInfoTest) diff -Nru kdepim-runtime-4.14.6/resources/folderarchivesettings/autotests/folderarchiveaccountinfotest.h kdepim-runtime-15.08.0/resources/folderarchivesettings/autotests/folderarchiveaccountinfotest.h --- kdepim-runtime-4.14.6/resources/folderarchivesettings/autotests/folderarchiveaccountinfotest.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/folderarchivesettings/autotests/folderarchiveaccountinfotest.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,12 +20,11 @@ #include - class FolderArchiveAccountInfoTest : public QObject { Q_OBJECT public: - explicit FolderArchiveAccountInfoTest(QObject *parent = 0); + explicit FolderArchiveAccountInfoTest(QObject *parent = Q_NULLPTR); ~FolderArchiveAccountInfoTest(); private Q_SLOTS: @@ -34,7 +33,5 @@ void shouldRestoreFromSettings(); }; - - #endif // FOLDERARCHIVEACCOUNTINFOTEST_H diff -Nru kdepim-runtime-4.14.6/resources/folderarchivesettings/CMakeLists.txt kdepim-runtime-15.08.0/resources/folderarchivesettings/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/folderarchivesettings/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/folderarchivesettings/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,13 +1,8 @@ project(folderarchivesettings) -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${KDEPIMLIBS_INCLUDE_DIR} -) -include(KDE4Defaults) +add_definitions(-DTRANSLATION_DOMAIN=\"libfolderarchivesettings\") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}") set(folderarchivesettings_SRCS folderarchivesettingpage.cpp @@ -15,17 +10,21 @@ folderarchiveaccountinfo.cpp ) -kde4_add_library(folderarchivesettings ${LIBRARY_TYPE} ${folderarchivesettings_SRCS} ) +add_library(folderarchivesettings ${folderarchivesettings_SRCS} ) +generate_export_header(folderarchivesettings BASE_NAME folderarchivesettings) target_link_libraries(folderarchivesettings - ${KDEPIMLIBS_KMIME_LIBS} - ${AKONADI_COMMON_LIBRARIES} - ${QT_QTGUI_LIBRARY} - ${KDEPIMLIBS_AKONADI_LIBS} +PRIVATE + KF5::Mime + KF5::AkonadiCore + KF5::AkonadiWidgets + KF5::ConfigCore ) -set_target_properties(folderarchivesettings PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} ) +set_target_properties(folderarchivesettings PROPERTIES VERSION ${KDEPIMRUNTIME_LIB_VERSION} SOVERSION ${KDEPIMRUNTIME_LIB_SOVERSION} ) -install(TARGETS folderarchivesettings ${INSTALL_TARGETS_DEFAULT_ARGS}) -add_subdirectory(autotests) +install(TARGETS folderarchivesettings ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) +if (BUILD_TESTING) + add_subdirectory(autotests) +endif() diff -Nru kdepim-runtime-4.14.6/resources/folderarchivesettings/folderarchiveaccountinfo.cpp kdepim-runtime-15.08.0/resources/folderarchivesettings/folderarchiveaccountinfo.cpp --- kdepim-runtime-4.14.6/resources/folderarchivesettings/folderarchiveaccountinfo.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/folderarchivesettings/folderarchiveaccountinfo.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -97,31 +97,32 @@ void FolderArchiveAccountInfo::readConfig(const KConfigGroup &config) { - mInstanceName = config.readEntry(QLatin1String("instanceName")); - mArchiveTopLevelCollectionId = config.readEntry(QLatin1String("topLevelCollectionId"), -1); + mInstanceName = config.readEntry(QStringLiteral("instanceName")); + mArchiveTopLevelCollectionId = config.readEntry(QStringLiteral("topLevelCollectionId"), -1); mArchiveType = static_cast(config.readEntry("folderArchiveType", (int)UniqueFolder)); mEnabled = config.readEntry("enabled", false); mKeepExistingStructure = config.readEntry("keepExistingStructure", false); } -void FolderArchiveAccountInfo::writeConfig(KConfigGroup &config ) +void FolderArchiveAccountInfo::writeConfig(KConfigGroup &config) { - config.writeEntry(QLatin1String("instanceName"), mInstanceName); - if (mArchiveTopLevelCollectionId>-1) - config.writeEntry(QLatin1String("topLevelCollectionId"), mArchiveTopLevelCollectionId); - else - config.deleteEntry(QLatin1String("topLevelCollectionId")); + config.writeEntry(QStringLiteral("instanceName"), mInstanceName); + if (mArchiveTopLevelCollectionId > -1) { + config.writeEntry(QStringLiteral("topLevelCollectionId"), mArchiveTopLevelCollectionId); + } else { + config.deleteEntry(QStringLiteral("topLevelCollectionId")); + } - config.writeEntry(QLatin1String("folderArchiveType"), (int)mArchiveType); - config.writeEntry(QLatin1String("enabled"), mEnabled); + config.writeEntry(QStringLiteral("folderArchiveType"), (int)mArchiveType); + config.writeEntry(QStringLiteral("enabled"), mEnabled); config.writeEntry("keepExistingStructure", mKeepExistingStructure); } -bool FolderArchiveAccountInfo::operator==( const FolderArchiveAccountInfo& other ) const +bool FolderArchiveAccountInfo::operator==(const FolderArchiveAccountInfo &other) const { return (mInstanceName == other.instanceName()) - && (mArchiveTopLevelCollectionId == other.archiveTopLevel()) - && (mArchiveType == other.folderArchiveType()) - && (mEnabled == other.enabled()) - && (mKeepExistingStructure == other.keepExistingStructure()); + && (mArchiveTopLevelCollectionId == other.archiveTopLevel()) + && (mArchiveType == other.folderArchiveType()) + && (mEnabled == other.enabled()) + && (mKeepExistingStructure == other.keepExistingStructure()); } diff -Nru kdepim-runtime-4.14.6/resources/folderarchivesettings/folderarchiveaccountinfo.h kdepim-runtime-15.08.0/resources/folderarchivesettings/folderarchiveaccountinfo.h --- kdepim-runtime-4.14.6/resources/folderarchivesettings/folderarchiveaccountinfo.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/folderarchivesettings/folderarchiveaccountinfo.h 2015-08-10 21:01:02.000000000 +0000 @@ -19,7 +19,7 @@ #define FOLDERARCHIVEACCOUNTINFO_H #include -#include +#include class FolderArchiveAccountInfo { @@ -51,10 +51,10 @@ void setKeepExistingStructure(bool b); bool keepExistingStructure() const; - void writeConfig(KConfigGroup &config ); + void writeConfig(KConfigGroup &config); void readConfig(const KConfigGroup &config); - bool operator==( const FolderArchiveAccountInfo& other ) const; + bool operator==(const FolderArchiveAccountInfo &other) const; private: FolderArchiveAccountInfo::FolderArchiveType mArchiveType; diff -Nru kdepim-runtime-4.14.6/resources/folderarchivesettings/folderarchivesettingpage.cpp kdepim-runtime-15.08.0/resources/folderarchivesettings/folderarchivesettingpage.cpp --- kdepim-runtime-4.14.6/resources/folderarchivesettings/folderarchivesettingpage.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/folderarchivesettings/folderarchivesettingpage.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,12 +19,11 @@ #include "folderarchiveaccountinfo.h" #include "folderarchiveutil.h" -#include +#include #include -#include -#include +#include #include #include @@ -36,8 +35,6 @@ #include #include -static const KCatalogLoader loader( QLatin1String("libfolderarchivesettings") ); - FolderArchiveComboBox::FolderArchiveComboBox(QWidget *parent) : QComboBox(parent) { @@ -76,17 +73,17 @@ FolderArchiveSettingPage::FolderArchiveSettingPage(const QString &instanceName, QWidget *parent) : QWidget(parent), mInstanceName(instanceName), - mInfo(0) + mInfo(Q_NULLPTR) { QVBoxLayout *lay = new QVBoxLayout; mEnabled = new QCheckBox(i18n("Enable")); - connect(mEnabled, SIGNAL(toggled(bool)), this, SLOT(slotEnableChanged(bool))); + connect(mEnabled, &QCheckBox::toggled, this, &FolderArchiveSettingPage::slotEnableChanged); lay->addWidget(mEnabled); QHBoxLayout *hbox = new QHBoxLayout; QLabel *lab = new QLabel(i18nc( - "@label:chooser for the folder that messages will be archived under", - "Archive into:")); + "@label:chooser for the folder that messages will be archived under", + "Archive into:")); hbox->addWidget(lab); mArchiveFolder = new Akonadi::CollectionRequester; mArchiveFolder->setMimeTypeFilter(QStringList() << KMime::Message::mimeType()); @@ -151,12 +148,12 @@ mInfo->writeConfig(grp); //Update cache from KMail - const QString kmailInterface = QLatin1String("org.kde.kmail"); + const QString kmailInterface = QStringLiteral("org.kde.kmail"); QDBusReply reply = QDBusConnection::sessionBus().interface()->isServiceRegistered(kmailInterface); if (!reply.isValid() || !reply.value()) { return; } - QDBusInterface kmail(kmailInterface, QLatin1String("/KMail"), QLatin1String("org.kde.kmail.kmail")); - kmail.asyncCall(QLatin1String("reloadFolderArchiveConfig")); + QDBusInterface kmail(kmailInterface, QStringLiteral("/KMail"), QStringLiteral("org.kde.kmail.kmail")); + kmail.asyncCall(QStringLiteral("reloadFolderArchiveConfig")); } diff -Nru kdepim-runtime-4.14.6/resources/folderarchivesettings/folderarchivesettingpage.h kdepim-runtime-15.08.0/resources/folderarchivesettings/folderarchivesettingpage.h --- kdepim-runtime-4.14.6/resources/folderarchivesettings/folderarchivesettingpage.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/folderarchivesettings/folderarchivesettingpage.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,7 +24,8 @@ #include class QCheckBox; -namespace Akonadi { +namespace Akonadi +{ class CollectionRequester; } @@ -32,7 +33,7 @@ { Q_OBJECT public: - explicit FolderArchiveComboBox(QWidget *parent = 0); + explicit FolderArchiveComboBox(QWidget *parent = Q_NULLPTR); ~FolderArchiveComboBox(); void setType(FolderArchiveAccountInfo::FolderArchiveType type); @@ -47,7 +48,7 @@ { Q_OBJECT public: - explicit FolderArchiveSettingPage(const QString &instanceName, QWidget *parent=0); + explicit FolderArchiveSettingPage(const QString &instanceName, QWidget *parent = Q_NULLPTR); ~FolderArchiveSettingPage(); void loadSettings(); diff -Nru kdepim-runtime-4.14.6/resources/folderarchivesettings/folderarchivesettings_export.h kdepim-runtime-15.08.0/resources/folderarchivesettings/folderarchivesettings_export.h --- kdepim-runtime-4.14.6/resources/folderarchivesettings/folderarchivesettings_export.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/folderarchivesettings/folderarchivesettings_export.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2007 David Faure - - 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 FOLDERARCHIVESETTINGS_EXPORT_H -#define FOLDERARCHIVESETTINGS_EXPORT_H - -/* needed for KDE_EXPORT and KDE_IMPORT macros */ -#include - -#ifndef FOLDERARCHIVESETTINGS_EXPORT -# if defined(KDEPIM_STATIC_LIBS) - /* No export/import for static libraries */ -# define FOLDERARCHIVESETTINGS_EXPORT -# elif defined(MAKE_FOLDERARCHIVESETTINGS_LIB) - /* We are building this library */ -# define FOLDERARCHIVESETTINGS_EXPORT KDE_EXPORT -# else - /* We are using this library */ -# define FOLDERARCHIVESETTINGS_EXPORT KDE_IMPORT -# endif -#endif - -#endif diff -Nru kdepim-runtime-4.14.6/resources/folderarchivesettings/folderarchiveutil.cpp kdepim-runtime-15.08.0/resources/folderarchivesettings/folderarchiveutil.cpp --- kdepim-runtime-4.14.6/resources/folderarchivesettings/folderarchiveutil.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/folderarchivesettings/folderarchiveutil.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,10 +21,10 @@ QString FolderArchiveUtil::groupConfigPattern() { - return QLatin1String("FolderArchiveAccount "); + return QStringLiteral("FolderArchiveAccount "); } QString FolderArchiveUtil::configFileName() { - return QLatin1String("foldermailarchiverc"); + return QStringLiteral("foldermailarchiverc"); } diff -Nru kdepim-runtime-4.14.6/resources/folderarchivesettings/folderarchiveutil.h kdepim-runtime-15.08.0/resources/folderarchivesettings/folderarchiveutil.h --- kdepim-runtime-4.14.6/resources/folderarchivesettings/folderarchiveutil.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/folderarchivesettings/folderarchiveutil.h 2015-08-10 21:01:02.000000000 +0000 @@ -19,7 +19,8 @@ #define FOLDERARCHIVEUTIL_H #include -namespace FolderArchive { +namespace FolderArchive +{ namespace FolderArchiveUtil { QString groupConfigPattern(); @@ -27,5 +28,4 @@ } } - #endif // FOLDERARCHIVEUTIL_H diff -Nru kdepim-runtime-4.14.6/resources/gmail/CMakeLists.txt kdepim-runtime-15.08.0/resources/gmail/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/gmail/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,21 +1,18 @@ -add_subdirectory(saslplugin) +# REACTIVATE IT +#add_subdirectory(saslplugin) add_definitions( -DQT_NO_CAST_FROM_ASCII ) add_definitions( -DQT_NO_CAST_TO_ASCII ) - +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_gmail_resource\") include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/../imap ${CMAKE_CURRENT_BINARY_DIR}/../imap - ${LibKGAPI2_INCLUDE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} - ${QJSON_INCLUDE_DIR} - ${qjson_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../folderarchivesettings/ ) -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) + ########### next target ############### @@ -33,27 +30,22 @@ gmailchangeitemslabelstask.cpp ) -kde4_add_ui_files(gmailresource_SRCS gmailconfigdialog.ui) -#kde4_add_kcfg_files(gmailresource_SRCS settingsbase.kcfgc) +ki18n_wrap_ui(gmailresource_SRCS gmailconfigdialog.ui) +#kconfig_add_kcfg_files(gmailresource_SRCS settingsbase.kcfgc) -kde4_add_executable(akonadi_gmail_resource ${gmailresource_SRCS}) +add_executable(akonadi_gmail_resource ${gmailresource_SRCS}) target_link_libraries(akonadi_gmail_resource - ${KDEPIMLIBS_AKONADI_LIBS} - ${QT_QTDBUS_LIBRARY} - ${QT_QTCORE_LIBRARY} - ${QT_QTGUI_LIBRARY} - ${QT_QTNETWORK_LIBRARY} - ${KDEPIMLIBS_KIMAP_LIBS} - ${KDEPIMLIBS_MAILTRANSPORT_LIBS} - ${KDE4_KIO_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${KDEPIMLIBS_AKONADI_KMIME_LIBS} - ${KDEPIMLIBS_KPIMIDENTITIES_LIBS} - ${LibKGAPI2_LIBRARY} - ${QJSON_LIBRARIES} + KF5::AkonadiCore + KF5::IMAP + KF5::MailTransport + KF5::KIOCore + KF5::Mime + KF5::AkonadiMime + KF5::IdentityManagement + KF5::GAPICore imapresource folderarchivesettings ) -install(FILES gmailresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents") -install(TARGETS akonadi_gmail_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(FILES gmailresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents") +install(TARGETS akonadi_gmail_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailchangeitemslabelstask.cpp kdepim-runtime-15.08.0/resources/gmail/gmailchangeitemslabelstask.cpp --- kdepim-runtime-4.14.6/resources/gmail/gmailchangeitemslabelstask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailchangeitemslabelstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,10 +19,9 @@ #include "gmailchangeitemslabelstask.h" -#include -#include -#include - +#include +#include +#include GmailChangeItemsLabelsTask::GmailChangeItemsLabelsTask(ResourceStateInterface::Ptr resource, QObject *parent) : ChangeItemsFlagsTask(resource, parent) @@ -46,7 +45,7 @@ if (!addedFlags().isEmpty()) { triggerAppendFlagsJob(session); } else if (!removedFlags().isEmpty()) { - triggerRemoveFlagsJob(session); + triggerRemoveFlagsJob(session); } else { changeProcessed(); } diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailconfigdialog.cpp kdepim-runtime-15.08.0/resources/gmail/gmailconfigdialog.cpp --- kdepim-runtime-4.14.6/resources/gmail/gmailconfigdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailconfigdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -25,13 +25,13 @@ #include -#include -#include +#include +#include -#include +#include -#include -#include +#include +#include #include #include @@ -40,9 +40,11 @@ #include #include +#include +#include GmailConfigDialog::GmailConfigDialog(GmailResource *resource, WId parent) - : KDialog() + : QDialog() , m_parentResource(resource) , m_ui(new Ui::GmailConfigDialog) , m_subscriptionsChanged(false) @@ -50,22 +52,34 @@ { m_parentResource->settings()->setWinId(parent); - m_ui->setupUi(mainWidget()); + QWidget *mainWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); + m_ui->setupUi(mainWidget); m_folderArchiveSettingPage = new FolderArchiveSettingPage(resource->identifier()); m_ui->tabWidget->addTab(m_folderArchiveSettingPage, i18n("Folder Archive")); - m_ui->checkInterval->setSuffix( ki18np( " minute", " minutes" ) ); - m_ui->checkInterval->setRange( Akonadi::ResourceSettings::self()->minimumCheckInterval(), 10000, 1 ); - - - m_identityManager = new KPIMIdentities::IdentityManager( false, this, "mIdentityManager" ); - m_identityCombobox = new KPIMIdentities::IdentityCombo( m_identityManager, this ); - m_ui->identityLabel->setBuddy( m_identityCombobox ); - m_ui->identityLayout->addWidget( m_identityCombobox, 1 ); - m_ui->identityLabel->setBuddy( m_identityCombobox ); + m_ui->checkInterval->setSuffix(ki18np(" minute", " minutes")); + m_ui->checkInterval->setRange(Akonadi::ResourceSettings::self()->minimumCheckInterval(), 10000); + m_ui->checkInterval->setSingleStep(1); + + m_identityManager = new KIdentityManagement::IdentityManager(false, this, "mIdentityManager"); + m_identityCombobox = new KIdentityManagement::IdentityCombo(m_identityManager, this); + m_ui->identityLabel->setBuddy(m_identityCombobox); + m_ui->identityLayout->addWidget(m_identityCombobox, 1); + m_ui->identityLabel->setBuddy(m_identityCombobox); + + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + mOkButton = buttonBox->button(QDialogButtonBox::Ok); + mOkButton->setDefault(true); + mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + mainLayout->addWidget(buttonBox); connect(m_ui->subscriptionEnabled, SIGNAL(toggled(bool)), - this, SLOT(slotSubcriptionCheckboxChanged()) ); + this, SLOT(slotSubcriptionCheckboxChanged())); connect(m_ui->subscriptionButton, SIGNAL(clicked(bool)), this, SLOT(slotManageSubscriptions())); @@ -75,7 +89,7 @@ this, SLOT(slotAuthenticate())); connect(m_ui->useDefaultIdentityCheck, SIGNAL(toggled(bool)), - this, SLOT(slotIdentityCheckboxChanged())); + this, SLOT(slotIdentityCheckboxChanged())); connect(m_ui->enableMailCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotMailCheckboxChanged())); @@ -88,9 +102,9 @@ slotIdentityCheckboxChanged(); //connect(this, SIGNAL(applyClicked()), - //this, SLOT(applySettings()) ); - connect(this, SIGNAL(okClicked()), - this, SLOT(applySettings()) ); + //this, SLOT(applySettings()) ); + connect(mOkButton, SIGNAL(clicked()), + this, SLOT(applySettings())); } GmailConfigDialog::~GmailConfigDialog() @@ -123,7 +137,7 @@ m_folderArchiveSettingPage->writeSettings(); m_parentResource->setName(m_ui->usernameLabel->text()); - GmailSettings *settings = static_cast(m_parentResource->settings()); + GmailSettings *settings = static_cast(m_parentResource->settings()); settings->setImapServer(QLatin1String("imap.gmail.com")); settings->setImapPort(993); settings->setUserName(m_account->accountName()); @@ -145,10 +159,10 @@ settings->setIntervalCheckEnabled(m_ui->enableMailCheckBox->isChecked()); if (m_ui->enableMailCheckBox->isChecked()) { - settings->setIntervalCheckTime( m_ui->checkInterval->value() ); + settings->setIntervalCheckTime(m_ui->checkInterval->value()); } - settings->writeConfig(); + settings->save(); if (m_oldResourceName != m_account->accountName() && !m_account->accountName().isEmpty()) { settings->renameRootCollection(m_account->accountName()); @@ -161,7 +175,7 @@ m_ui->usernameLabel->setText(m_parentResource->name()); m_oldResourceName = m_parentResource->name(); - GmailSettings *settings = static_cast(m_parentResource->settings()); + GmailSettings *settings = static_cast(m_parentResource->settings()); m_account = KGAPI2::AccountPtr(new KGAPI2::Account); if (!m_parentResource->name().startsWith(m_parentResource->defaultName())) { @@ -173,7 +187,7 @@ bool rejected = false; const QString accessToken = settings->password(&rejected); const QString refreshToken = settings->refreshToken(&rejected); - if ( rejected ) { + if (rejected) { //m_ui->password->setEnabled( false ); KMessageBox::information(0, i18n("Could not access KWallet. If you want to use Gmail resource, you have to activate it.")); } else { @@ -193,9 +207,9 @@ m_ui->disconnectedModeEnabled->setChecked(settings->disconnectedModeEnabled()); m_ui->useDefaultIdentityCheck->setChecked(settings->useDefaultIdentity()); - if (!m_ui->useDefaultIdentityCheck->isChecked()) + if (!m_ui->useDefaultIdentityCheck->isChecked()) { m_identityCombobox->setCurrentIdentity(settings->accountIdentity()); - + } m_ui->autoExpungeCheck->setChecked(settings->automaticExpungeEnabled()); } @@ -203,7 +217,7 @@ void GmailConfigDialog::slotComplete() { const bool ok = (m_account || !m_account->accountName().isEmpty()); - button(KDialog::Ok)->setEnabled(ok); + mOkButton->setEnabled(ok); } void GmailConfigDialog::slotManageSubscriptions() @@ -218,9 +232,9 @@ account.setEncryptionMode(KIMAP::LoginJob::SslV3); account.setAuthenticationMode(KIMAP::LoginJob::XOAuth2); - QPointer subscriptions = new SubscriptionDialog( this ); - subscriptions->setCaption(i18n("Serverside Subscription")); - subscriptions->setWindowIcon(KIcon(QLatin1String("network-server"))); + QPointer subscriptions = new SubscriptionDialog(this); + subscriptions->setWindowTitle(i18n("Serverside Subscription")); + subscriptions->setWindowIcon(QIcon::fromTheme(QLatin1String("network-server"))); subscriptions->connectAccount(account, m_account->accessToken()); m_subscriptionsChanged = subscriptions->isSubscriptionChanged(); @@ -232,7 +246,7 @@ void GmailConfigDialog::slotAuthenticate() { - GmailSettings *settings = static_cast(m_parentResource->settings()); + GmailSettings *settings = static_cast(m_parentResource->settings()); settings->clearCachedPassword(); settings->storeAccount(KGAPI2::AccountPtr()); settings->requestAccount(true); @@ -253,7 +267,7 @@ m_ui->authenticateButton->setVisible(false); } - GmailSettings *settings = static_cast(m_parentResource->settings()); + GmailSettings *settings = static_cast(m_parentResource->settings()); settings->storeAccount(m_account); slotComplete(); } diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailconfigdialog.h kdepim-runtime-15.08.0/resources/gmail/gmailconfigdialog.h --- kdepim-runtime-4.14.6/resources/gmail/gmailconfigdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailconfigdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,24 +20,24 @@ #ifndef GMAILSETUPSERVER_H #define GMAILSETUPSERVER_H -#include +#include -#include +#include namespace Ui { class GmailConfigDialog; } -namespace KPIMIdentities +namespace KIdentityManagement { class IdentityCombo; class IdentityManager; } - +class QPushButton; class GmailResource; class FolderArchiveSettingPage; -class GmailConfigDialog : public KDialog +class GmailConfigDialog : public QDialog { Q_OBJECT @@ -68,12 +68,12 @@ Ui::GmailConfigDialog *m_ui; bool m_subscriptionsChanged; bool m_shouldClearCache; - KPIMIdentities::IdentityManager *m_identityManager; - KPIMIdentities::IdentityCombo *m_identityCombobox; + KIdentityManagement::IdentityManager *m_identityManager; + KIdentityManagement::IdentityCombo *m_identityCombobox; QString m_oldResourceName; KGAPI2::AccountPtr m_account; FolderArchiveSettingPage *m_folderArchiveSettingPage; - + QPushButton *mOkButton; }; #endif // GMAILSETUPSERVER_H diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailconfigdialog.ui kdepim-runtime-15.08.0/resources/gmail/gmailconfigdialog.ui --- kdepim-runtime-4.14.6/resources/gmail/gmailconfigdialog.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailconfigdialog.ui 2015-08-10 21:01:02.000000000 +0000 @@ -50,7 +50,7 @@
- + Change... @@ -62,7 +62,7 @@
- + Authenticate @@ -104,19 +104,13 @@ - + 15 5 - - - - - - @@ -158,7 +152,7 @@
- + Select folders to synchronize... @@ -228,14 +222,9 @@ - KPushButton - QPushButton -
kpushbutton.h
-
- - KIntNumInput - QWidget -
knuminput.h
+ KPluralHandlingSpinBox + QSpinBox +
kpluralhandlingspinbox.h
diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmaillabelattribute.cpp kdepim-runtime-15.08.0/resources/gmail/gmaillabelattribute.cpp --- kdepim-runtime-4.14.6/resources/gmail/gmaillabelattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmaillabelattribute.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -30,7 +30,6 @@ { } - GmailLabelAttribute::~GmailLabelAttribute() { } diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmaillabelattribute.h kdepim-runtime-15.08.0/resources/gmail/gmaillabelattribute.h --- kdepim-runtime-4.14.6/resources/gmail/gmaillabelattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmaillabelattribute.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,7 +20,7 @@ #ifndef GMAILLABELATTRIBUTE_H #define GMAILLABELATTRIBUTE_H -#include +#include #include class GmailLabelAttribute : public Akonadi::Attribute @@ -44,7 +44,7 @@ void deserialize(const QByteArray &data); QByteArray serialized() const; - Akonadi::Attribute* clone() const; + Akonadi::Attribute *clone() const; QByteArray type() const; private: diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmaillinkitemstask.cpp kdepim-runtime-15.08.0/resources/gmail/gmaillinkitemstask.cpp --- kdepim-runtime-4.14.6/resources/gmail/gmaillinkitemstask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmaillinkitemstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,13 +22,13 @@ #include "gmailretrieveitemstask.h" #include "gmailsettings.h" -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include @@ -59,7 +59,6 @@ deleteLater(); } - void GmailLinkItemsTask::linkItem(const QString &remoteId, const QVector &labels) { mLinkMap.insert(remoteId, labels); @@ -70,7 +69,6 @@ } } - void GmailLinkItemsTask::onRetrievalDone() { Q_EMIT status(Akonadi::AgentBase::Running, i18n("Linking emails to labels")); @@ -121,11 +119,11 @@ void GmailLinkItemsTask::onLabelResolved(KJob *job) { Akonadi::CollectionPathResolver *resolver - = qobject_cast(job); + = qobject_cast(job); const QString collectionName = resolver->property(COLLECTION_NAME_PROPERTY).toString(); const QByteArray label = resolver->property(LABEL_PROPERTY).toByteArray(); if (resolver->error() && resolver->collection() < 0) { - kWarning() << "Failed to resolve collection ID for path" << collectionName << ":" << resolver->errorString(); + qWarning() << "Failed to resolve collection ID for path" << collectionName << ":" << resolver->errorString(); return; } const Akonadi::Collection collection(resolver->collection()); @@ -171,7 +169,7 @@ return; } - Akonadi::ItemFetchJob *fetchJob = qobject_cast(job); + Akonadi::ItemFetchJob *fetchJob = qobject_cast(job); QMap toLink; QMap toUnlink; diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmaillinkitemstask.h kdepim-runtime-15.08.0/resources/gmail/gmaillinkitemstask.h --- kdepim-runtime-4.14.6/resources/gmail/gmaillinkitemstask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmaillinkitemstask.h 2015-08-10 21:01:02.000000000 +0000 @@ -23,7 +23,7 @@ #include #include -#include +#include class GmailResource; class GmailRetrieveItemsTask; diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailmessagehelper.cpp kdepim-runtime-15.08.0/resources/gmail/gmailmessagehelper.cpp --- kdepim-runtime-4.14.6/resources/gmail/gmailmessagehelper.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailmessagehelper.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -28,76 +28,75 @@ } - Akonadi::Item GmailMessageHelper::createItemFromMessage(KMime::Message::Ptr message, - const qint64 uid, - const qint64 size, - const QList &attrs, - const QList &flags, - const KIMAP::FetchJob::FetchScope &scope, - bool &ok) const + const qint64 uid, + const qint64 size, + const QList &attrs, + const QList &flags, + const KIMAP::FetchJob::FetchScope &scope, + bool &ok) const { Akonadi::Item item = MessageHelper::createItemFromMessage(message, uid, size, attrs, flags, scope, ok); if (!ok) { - kWarning() << "Failed to read imap message"; + qWarning() << "Failed to read imap message"; return item; } Q_FOREACH (const KIMAP::MessageAttribute &attr, attrs) { if (attr.first == "X-GM-LABELS") { - if (mTask) { - QVector labels; + if (mTask) { + QVector labels; - QByteArray labelStr = attr.second.toByteArray(); - int lastPos = 0; - bool isQuoted = false; - int i = 0; - while (i < labelStr.size()) { - if (labelStr[i] == '(') { - lastPos = i; - i++; - continue; - } - - if (labelStr[i] == '\"') { - lastPos = i; - isQuoted = true; - i++; - } - - if (isQuoted) { - while (labelStr[i] != '\"') { - if (i == labelStr.size()) { - // huh? Broken string? - break; - } - i++; - } - QByteArray mid = labelStr.mid(lastPos + 1, i - lastPos - 1).trimmed(); - if (!mid.isEmpty() && mid != "\\\\All") { - labels.append(mid.replace("\\\\", "\\")); - } - isQuoted = false; - lastPos = i; - } else { - if (labelStr[i] == ' ' || labelStr[i] == ')') { - QByteArray mid = labelStr.mid(lastPos + 1, i - lastPos - 1).trimmed(); - if (!mid.isEmpty() && mid != "\\\\All") { - labels.append(mid.replace("\\\\", "\\")); - } - lastPos = i; - } - } - ++i; - } - if (!labels.isEmpty()) { - GmailRetrieveItemsTask *task = qobject_cast(mTask); - Q_ASSERT(task); - task->linkItem(item.remoteId(), labels); - } - } + QByteArray labelStr = attr.second.toByteArray(); + int lastPos = 0; + bool isQuoted = false; + int i = 0; + while (i < labelStr.size()) { + if (labelStr[i] == '(') { + lastPos = i; + i++; + continue; + } + + if (labelStr[i] == '\"') { + lastPos = i; + isQuoted = true; + i++; + } + + if (isQuoted) { + while (labelStr[i] != '\"') { + if (i == labelStr.size()) { + // huh? Broken string? + break; + } + i++; + } + QByteArray mid = labelStr.mid(lastPos + 1, i - lastPos - 1).trimmed(); + if (!mid.isEmpty() && mid != "\\\\All") { + labels.append(mid.replace("\\\\", "\\")); + } + isQuoted = false; + lastPos = i; + } else { + if (labelStr[i] == ' ' || labelStr[i] == ')') { + QByteArray mid = labelStr.mid(lastPos + 1, i - lastPos - 1).trimmed(); + if (!mid.isEmpty() && mid != "\\\\All") { + labels.append(mid.replace("\\\\", "\\")); + } + lastPos = i; + } + } + ++i; + } + if (!labels.isEmpty()) { + GmailRetrieveItemsTask *task = qobject_cast(mTask); + Q_ASSERT(task); + task->linkItem(item.remoteId(), labels); + } + } } else if (attr.first == "X-GM-THRID") { - // TODO: Store thread information + // TODO: Store thread information } else if (attr.first == "X-GM-MSGID") { item.setGid(attr.second.toString()); } diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailmessagehelper.h kdepim-runtime-15.08.0/resources/gmail/gmailmessagehelper.h --- kdepim-runtime-4.14.6/resources/gmail/gmailmessagehelper.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailmessagehelper.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,7 +22,7 @@ #include -#include +#include class ResourceTask; @@ -31,13 +31,13 @@ public: GmailMessageHelper(const Akonadi::Collection &collection, ResourceTask *currentTask); - virtual Akonadi::Item createItemFromMessage (KMime::Message::Ptr message, - const qint64 uid, - const qint64 size, - const QList &attrs, - const QList &flags, - const KIMAP::FetchJob::FetchScope &scope, - bool &ok) const; + virtual Akonadi::Item createItemFromMessage(KMime::Message::Ptr message, + const qint64 uid, + const qint64 size, + const QList &attrs, + const QList &flags, + const KIMAP::FetchJob::FetchScope &scope, + bool &ok) const; private: Akonadi::Collection mCollection; diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailpasswordrequester.cpp kdepim-runtime-15.08.0/resources/gmail/gmailpasswordrequester.cpp --- kdepim-runtime-4.14.6/resources/gmail/gmailpasswordrequester.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailpasswordrequester.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,12 +21,12 @@ #include "gmailsettings.h" #include "gmailresource.h" -#include -#include +#include +#include -#include +#include -#include +#include /** * See https://developers.google.com/gmail/xoauth2_protocol for protocol documentation @@ -48,7 +48,7 @@ connect(mResource->settings(), SIGNAL(accountRequestCompleted(KGAPI2::AccountPtr,bool)), this, SLOT(onAuthFinished(KGAPI2::AccountPtr,bool)), Qt::UniqueConnection); - static_cast(mResource->settings())->requestAccount(true); + static_cast(mResource->settings())->requestAccount(true); } else { QMetaObject::invokeMethod(this, "done", Qt::QueuedConnection, Q_ARG(int, PasswordRetrieved), @@ -58,22 +58,22 @@ bool GmailPasswordRequester::isTokenExpired(const QString &serverError) { - QJson::Parser parser; - QString base64Error = serverError.mid(7, serverError.length() - 9); const QByteArray decoded = QByteArray::fromBase64(base64Error.toLatin1()); - bool ok = false; - const QVariant json = parser.parse(decoded, &ok); - if (!ok) { + QJsonDocument document = QJsonDocument::fromJson(decoded); + if (document.isNull()) { + return false; + } + const QVariant json = document.toVariant(); + if (!json.isValid()) { return false; } - const QVariantMap map = json.toMap(); if (map[QLatin1String("status")].toString().toInt() == KGAPI2::Unauthorized) { return true; } - kDebug() << "Gmail Auth error:" << json; + qDebug() << "Gmail Auth error:" << json; return false; } diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailpasswordrequester.h kdepim-runtime-15.08.0/resources/gmail/gmailpasswordrequester.h --- kdepim-runtime-4.14.6/resources/gmail/gmailpasswordrequester.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailpasswordrequester.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,12 +22,12 @@ #include -#include +#include class GmailResource; class GmailPasswordRequester : public PasswordRequesterInterface { - Q_OBJECT + Q_OBJECT public: GmailPasswordRequester(GmailResource *resource, QObject *parent); diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailresource.cpp kdepim-runtime-15.08.0/resources/gmail/gmailresource.cpp --- kdepim-runtime-4.14.6/resources/gmail/gmailresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -31,24 +31,23 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include #include -#include +#include GmailResource::GmailResource(const QString &id) - : ImapResourceBase(id) - , m_settings(0) + : ImapResourceBase(id) + , m_settings(0) { - KGlobal::locale()->insertCatalog(QLatin1String("akonadi_imap_resource")); setSeparatorCharacter(QLatin1Char('/')); m_pool->setPasswordRequester(new GmailPasswordRequester(this, m_pool)); @@ -70,29 +69,28 @@ return m_settings; } - QString GmailResource::defaultName() const { return i18n("Gmail Resource"); } -KDialog *GmailResource::createConfigureDialog(WId windowId) +QDialog *GmailResource::createConfigureDialog(WId windowId) { GmailConfigDialog *dlg = new GmailConfigDialog(this, windowId); KWindowSystem::setMainWindow(dlg, windowId); - dlg->setWindowIcon(KIcon(QLatin1String("network-server"))); - connect(dlg, SIGNAL(finished(int)), this, SLOT(onConfigurationDone(int)));; + dlg->setWindowIcon(QIcon::fromTheme(QLatin1String("network-server"))); + connect(dlg, &QDialog::finished, this, &GmailResource::onConfigurationDone);; return dlg; } void GmailResource::onConfigurationDone(int result) { - GmailConfigDialog *dlg = qobject_cast(sender()); + GmailConfigDialog *dlg = qobject_cast(sender()); if (result) { - if ( dlg->shouldClearCache() ) { + if (dlg->shouldClearCache()) { clearCache(); } - settings()->writeConfig(); + settings()->save(); } dlg->deleteLater(); } @@ -133,13 +131,13 @@ { Akonadi::CollectionFetchJob *fetch = new Akonadi::CollectionFetchJob(rootCollection(), Akonadi::CollectionFetchJob::FirstLevel, this); - connect(fetch, SIGNAL(finished(KJob*)), - this, SLOT(onUpdateTrashFolderCollectionsRetrieved(KJob*))); + connect(fetch, &KJob::finished, + this, &GmailResource::onUpdateTrashFolderCollectionsRetrieved); } void GmailResource::onUpdateTrashFolderCollectionsRetrieved(KJob *job) { - Akonadi::CollectionFetchJob *fetch = qobject_cast(job); + Akonadi::CollectionFetchJob *fetch = qobject_cast(job); if (job->error()) { kError() << fetch->errorString(); return; @@ -164,7 +162,7 @@ void GmailResource::retrieveItems(const Akonadi::Collection &col) { - kDebug() << col.id() << col.remoteId() << col.name(); + qDebug() << col.id() << col.remoteId() << col.name(); // We can't sync the virtual collections - instead we get ID of "All Mail" and // we schedule it's sync // @@ -198,14 +196,14 @@ return; } - Akonadi::CollectionFetchJob *fetch = qobject_cast(job); + Akonadi::CollectionFetchJob *fetch = qobject_cast(job); if (fetch->collections().count() != 1) { - kWarning() << "Got" << fetch->collections().count() << "collections, expected only one!"; + qWarning() << "Got" << fetch->collections().count() << "collections, expected only one!"; cancelTask(); return; } - synchronizeCollection(fetch->collections().first().id()); + synchronizeCollection(fetch->collections().at(0).id()); itemsRetrievalDone(); } @@ -213,7 +211,7 @@ void GmailResource::itemsLinked(const Akonadi::Item::List &items, const Akonadi::Collection &collection) { if (!collection.hasAttribute()) { - kWarning() << "Collection is missing GmailLabelAttribute! IMPOSSIBRU!"; + qWarning() << "Collection is missing GmailLabelAttribute! IMPOSSIBRU!"; cancelTask(); return; } @@ -227,7 +225,7 @@ void GmailResource::itemsUnlinked(const Akonadi::Item::List &items, const Akonadi::Collection &collection) { if (!collection.hasAttribute()) { - kWarning() << "Collection is missing GmailLabelAttribute! IMPOSSIBRU!"; + qWarning() << "Collection is missing GmailLabelAttribute! IMPOSSIBRU!"; cancelTask(); return; } diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailresource.desktop kdepim-runtime-15.08.0/resources/gmail/gmailresource.desktop --- kdepim-runtime-4.14.6/resources/gmail/gmailresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,15 +1,18 @@ [Desktop Entry] Name=Gmail -Name[bs]=Gmail +Name[bg]=Gmail Name[ca]=Gmail Name[da]=Gmail Name[de]=Gmail +Name[el]=Gmail Name[en_GB]=Gmail Name[es]=Gmail Name[et]=Gmail Name[fi]=Gmail Name[fr]=Gmail +Name[gl]=Gmail Name[hu]=Gmail +Name[ia]=Gmail Name[it]=Gmail Name[ko]=GMail Name[nb]=Gmail @@ -20,6 +23,7 @@ Name[pt_BR]=Gmail Name[ru]=Gmail Name[sk]=Gmail +Name[sl]=Gmail Name[sr]=Г‑мејл Name[sr@ijekavian]=Г‑мејл Name[sr@ijekavianlatin]=GMail @@ -28,17 +32,20 @@ Name[tr]=Gmail Name[uk]=Gmail Name[x-test]=xxGmailxx +Name[zh_CN]=Gmail Name[zh_TW]=Gmail Comment=Connects to your Gmail account -Comment[bs]=Povezuje se na vaš Gmail nalog +Comment[bg]=Свързване към вашата сметка в Google Comment[ca]=Connecta amb el vostre compte de Gmail Comment[da]=Forbinder til din Gmail-konto Comment[de]=Verbindet mit Ihrem Gmail-Konto +Comment[el]=Σύνδεση με τον λογαριασμό σας στο Gmail Comment[en_GB]=Connects to your Gmail account Comment[es]=Conecta a su cuenta Gmail Comment[et]=Ühendumine Gmaili kontoga Comment[fi]=Yhdistää Gmail-tiliin Comment[fr]=Se connecte à votre compte Gmail +Comment[gl]=Conecta á súa conta de Gmail Comment[hu]=Csatlakozik a Gmail fiókjához Comment[it]=Connette al tuo account Gmail Comment[ko]=내 GMail 계정에 연결 @@ -50,14 +57,16 @@ Comment[pt_BR]=Conecta-o a sua conta do Gmail Comment[ru]=Подключение к учётной записи Gmail Comment[sk]=Pripojí k vášmu Gmail účtu +Comment[sl]=Poveže se z vašim računom za Gmail Comment[sr]=Повезивање са налогом на Г‑мејлу Comment[sr@ijekavian]=Повезивање са налогом на Г‑мејлу Comment[sr@ijekavianlatin]=Povezivanje sa nalogom na GMailu Comment[sr@latin]=Povezivanje sa nalogom na GMailu Comment[sv]=Ansluter till ditt Gmail-konto -Comment[tr]=Gmail hesabınıza bağlanır +Comment[tr]=Gmail hesabına bağlanır Comment[uk]=Встановлює з’єднання з вашим обліковим записом Gmail Comment[x-test]=xxConnects to your Gmail accountxx +Comment[zh_CN]=连接到您的 Gmail 账户 Comment[zh_TW]=連線到您的 Gmail 帳號 Type=AkonadiResource Exec=akonadi_gmail_resource diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailresource.h kdepim-runtime-15.08.0/resources/gmail/gmailresource.h --- kdepim-runtime-4.14.6/resources/gmail/gmailresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,7 +22,7 @@ #include -#include +#include class GmailSettings; @@ -36,13 +36,13 @@ explicit GmailResource(const QString &id); ~GmailResource(); + QDialog *createConfigureDialog(WId windowId); Akonadi::Collection allMailCollection() const; Akonadi::Collection rootCollection() const; - KDialog *createConfigureDialog (WId windowId); QString defaultName() const; - ResourceStateInterface::Ptr createResourceState (const TaskArguments &args); + ResourceStateInterface::Ptr createResourceState(const TaskArguments &args); void retrieveCollections(); void retrieveItems(const Akonadi::Collection &col); @@ -63,6 +63,4 @@ mutable GmailSettings *m_settings; }; - - #endif // GMAILRESOURCE_H diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailresourcestate.cpp kdepim-runtime-15.08.0/resources/gmail/gmailresourcestate.cpp --- kdepim-runtime-4.14.6/resources/gmail/gmailresourcestate.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailresourcestate.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -44,5 +44,5 @@ MessageHelper::Ptr GmailResourceState::messageHelper() const { return MessageHelper::Ptr(new GmailMessageHelper(collection(), - qobject_cast(mTask))); + qobject_cast(mTask))); } diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailresourcestate.h kdepim-runtime-15.08.0/resources/gmail/gmailresourcestate.h --- kdepim-runtime-4.14.6/resources/gmail/gmailresourcestate.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailresourcestate.h 2015-08-10 21:01:02.000000000 +0000 @@ -28,7 +28,7 @@ class GmailResourceState : public ResourceState { public: - explicit GmailResourceState (GmailResource *resource, const TaskArguments &arguments); + explicit GmailResourceState(GmailResource *resource, const TaskArguments &arguments); void setCurrentTask(ResourceTask *task); ResourceTask *currentTask() const; diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailretrievecollectionstask.cpp kdepim-runtime-15.08.0/resources/gmail/gmailretrievecollectionstask.cpp --- kdepim-runtime-4.14.6/resources/gmail/gmailretrievecollectionstask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailretrievecollectionstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,24 +23,23 @@ #include #include -#include -#include +#include +#include #include -#include +#include #include - #include GmailRetrieveCollectionsTask::GmailRetrieveCollectionsTask(ResourceStateInterface::Ptr resource, - QObject *parent) + QObject *parent) : RetrieveCollectionsTask(resource, parent) { } void GmailRetrieveCollectionsTask::onMailBoxesReceived(const QList &descriptors, - const QList > &flags) + const QList > &flags) { Akonadi::Collection &rootCollection = m_reportedCollections[QString()]; Akonadi::EntityDisplayAttribute *attr = rootCollection.attribute(Akonadi::Entity::AddIfMissing); @@ -55,7 +54,7 @@ // skip phantom mailboxes contained in LSUB but not LIST if (isSubscriptionEnabled() && !m_fullReportedCollections.contains(descriptor.name)) { - kDebug() << "Got phantom mailbox: " << descriptor.name; + qDebug() << "Got phantom mailbox: " << descriptor.name; continue; } @@ -68,7 +67,7 @@ * folder. We should re-enable it at some point so that people can't * complain, but until then the folder will not be synced. */ - if (boxName == QLatin1String("[Gmail]/Chats")) { + if (boxName == QLatin1String("[Gmail]/Chats")) { continue; } @@ -77,14 +76,14 @@ QString parentPath; QString currentPath; - for (int j = 0, partsCnt = pathParts.count(); j < partsCnt; ++j ) { + for (int j = 0, partsCnt = pathParts.count(); j < partsCnt; ++j) { const bool isDummy = j != pathParts.size() - 1; const QString pathPart = pathParts.at(j); currentPath += separatorCharacter() + pathPart; if (m_reportedCollections.contains(currentPath)) { if (m_dummyCollections.contains(currentPath) && !isDummy) { - kDebug() << "Received the real collection for a dummy one : " << currentPath; + qDebug() << "Received the real collection for a dummy one : " << currentPath; //set the correct attributes for the collection, eg. noselect needs to be removed Akonadi::Collection c = m_reportedCollections.value(currentPath); c.setContentMimeTypes(contentTypes); @@ -162,7 +161,7 @@ // If this folder is a noselect folder, make some special settings. if (currentFlags.contains("\\noselect")) { - kDebug() << "Dummy collection created: " << currentPath; + qDebug() << "Dummy collection created: " << currentPath; c.addAttribute(new NoSelectAttribute(true)); c.setContentMimeTypes(QStringList() << Akonadi::Collection::mimeType()); c.setRights(Akonadi::Collection::ReadOnly); @@ -173,19 +172,18 @@ // If this folder is a noinferiors folder, it is not allowed to create subfolders inside. if (currentFlags.contains("\\noinferiors")) { - //kDebug() << "Noinferiors: " << currentPath; + //qDebug() << "Noinferiors: " << currentPath; c.addAttribute(new NoInferiorsAttribute(true)); c.setRights(c.rights() & ~Akonadi::Collection::CanCreateCollection); } - kDebug() << currentPath << currentFlags; + qDebug() << currentPath << currentFlags; // Special treating of Gmail system collections (and INBOX) if (currentPath == QLatin1String("/INBOX") || - currentFlags.contains("\\drafts") || - currentFlags.contains("\\important") || - currentFlags.contains("\\sent") || - currentFlags.contains("\\flagged")) - { + currentFlags.contains("\\drafts") || + currentFlags.contains("\\important") || + currentFlags.contains("\\sent") || + currentFlags.contains("\\flagged")) { // Keep [Gmail] in remoteID, so that we can reference them correctly // even though they have different parent in Akonadi c.setRemoteId(currentPath); @@ -193,9 +191,9 @@ c.setParentCollection(m_reportedCollections.value(QString())); // None of these can actually have subcollections, cannot be modified and // cannot be removed. - c.setRights( c.rights() & ~Akonadi::Collection::CanDeleteCollection - & ~Akonadi::Collection::CanChangeCollection - & ~Akonadi::Collection::CanCreateCollection ); + c.setRights(c.rights() & ~Akonadi::Collection::CanDeleteCollection + & ~Akonadi::Collection::CanChangeCollection + & ~Akonadi::Collection::CanCreateCollection); } // I am the king of non-generic code! @@ -241,7 +239,6 @@ // Remove the [Gmail] folder. We inserted it only to get remoteIDs for it's subcollections right // FIXME GMAIL: Don't hardcode this, try to have some detection or at least a constant - m_reportedCollections.remove( separatorCharacter() + QLatin1String( "[Gmail]" ) ); + m_reportedCollections.remove(separatorCharacter() + QLatin1String("[Gmail]")); } - diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailretrieveitemstask.cpp kdepim-runtime-15.08.0/resources/gmail/gmailretrieveitemstask.cpp --- kdepim-runtime-4.14.6/resources/gmail/gmailretrieveitemstask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailretrieveitemstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,15 +22,14 @@ #include -#include -#include - +#include +#include GmailRetrieveItemsTask::GmailRetrieveItemsTask(ResourceStateInterface::Ptr resource, QObject *parent) : RetrieveItemsTask(resource, parent) { - kDebug(); - dynamic_cast(resource.get())->setCurrentTask(this); + qDebug(); + dynamic_cast(resource.get())->setCurrentTask(this); } GmailRetrieveItemsTask::~GmailRetrieveItemsTask() @@ -39,12 +38,12 @@ } BatchFetcher *GmailRetrieveItemsTask::createBatchFetcher(MessageHelper::Ptr messageHelper, - const KIMAP::ImapSet &set, - const KIMAP::FetchJob::FetchScope &scope, - int batchSize, - KIMAP::Session *session) + const KIMAP::ImapSet &set, + const KIMAP::FetchJob::FetchScope &scope, + int batchSize, + KIMAP::Session *session) { - kDebug(); + qDebug(); KIMAP::FetchJob::FetchScope gmailScope = scope; BatchFetcher *batchFetcher = new BatchFetcher(messageHelper, set, gmailScope, batchSize, session); batchFetcher->setGmailExtensionsEnabled(true); diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailretrieveitemstask.h kdepim-runtime-15.08.0/resources/gmail/gmailretrieveitemstask.h --- kdepim-runtime-4.14.6/resources/gmail/gmailretrieveitemstask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailretrieveitemstask.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,7 +22,7 @@ #include -#include +#include class GmailRetrieveItemsTask : public RetrieveItemsTask { diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailsettings.cpp kdepim-runtime-15.08.0/resources/gmail/gmailsettings.cpp --- kdepim-runtime-4.14.6/resources/gmail/gmailsettings.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailsettings.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -25,19 +25,17 @@ #include using KWallet::Wallet; - -#include -#include +#include #include #include -#include -#include -#include +#include +#include +#include -#include -#include +#include +#include GmailSettings::GmailSettings(WId winId) : Settings(winId) @@ -62,7 +60,6 @@ return QLatin1String("mdT1DjzohxN3npUUzkENT0gO"); } - void GmailSettings::clearCachedPassword() { mAccount = KGAPI2::AccountPtr(); @@ -70,7 +67,7 @@ void GmailSettings::cleanup() { - Wallet* wallet = Wallet::openWallet(Wallet::NetworkWallet(), m_winId); + Wallet *wallet = Wallet::openWallet(Wallet::NetworkWallet(), m_winId); if (wallet && wallet->isOpen()) { if (wallet->hasFolder(QLatin1String("gmail"))) { wallet->setFolder(QLatin1String("gmail")); @@ -110,8 +107,8 @@ } KGAPI2::AuthJob *authJob = new KGAPI2::AuthJob(mAccount, apiKey(), secretKey(), this); - connect(authJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(onAuthFinished(KGAPI2::Job*))); + connect(authJob, &KGAPI2::Job::finished, + this, &GmailSettings::onAuthFinished); mActiveAuthJob = authJob; } else { if (mAccount) { @@ -132,7 +129,7 @@ return; } - KGAPI2::AuthJob *auth = qobject_cast(job); + KGAPI2::AuthJob *auth = qobject_cast(job); const KGAPI2::AccountPtr account = auth->account(); storeAccount(account); setImapServer(QLatin1String("imap.gmail.com")); @@ -140,13 +137,12 @@ Q_EMIT accountRequestCompleted(account, false); } - void GmailSettings::onWalletOpened(bool success) { if (!success) { emit passwordRequestCompleted(QString(), true); } else { - Wallet *wallet = qobject_cast( sender() ); + Wallet *wallet = qobject_cast(sender()); bool passwordNotStoredInWallet = true; if (wallet && wallet->hasFolder(QLatin1String("gmail"))) { loadAccountFromKWallet(); @@ -171,18 +167,18 @@ *userRejected = false; } - Wallet* wallet = Wallet::openWallet(Wallet::NetworkWallet(), m_winId); + Wallet *wallet = Wallet::openWallet(Wallet::NetworkWallet(), m_winId); if (wallet && wallet->isOpen()) { if (wallet->hasFolder(QLatin1String("gmail"))) { wallet->setFolder(QLatin1String("gmail")); QMap map; wallet->readMap(config()->name(), map); mAccount = KGAPI2::AccountPtr(new KGAPI2::Account(map[QLatin1String("accountName")], - map[QLatin1String("accessToken")], - map[QLatin1String("refreshToken")], - QList() << QUrl(QLatin1String("https://mail.google.com")) - << KGAPI2::Account::accountInfoScopeUrl() - << KGAPI2::Account::accountInfoEmailScopeUrl())); + map[QLatin1String("accessToken")], + map[QLatin1String("refreshToken")], + QList() << QUrl(QLatin1String("https://mail.google.com")) + << KGAPI2::Account::accountInfoScopeUrl() + << KGAPI2::Account::accountInfoEmailScopeUrl())); } else { wallet->createFolder(QLatin1String("gmail")); mAccount = KGAPI2::AccountPtr(); @@ -197,7 +193,7 @@ void GmailSettings::saveAccountToKWallet() { - Wallet* wallet = Wallet::openWallet(Wallet::NetworkWallet(), m_winId); + Wallet *wallet = Wallet::openWallet(Wallet::NetworkWallet(), m_winId); if (wallet && wallet->isOpen()) { if (!wallet->hasFolder(QLatin1String("gmail"))) { wallet->createFolder(QLatin1String("gmail")); @@ -208,12 +204,11 @@ map[QLatin1String("accessToken")] = mAccount->accessToken(); map[QLatin1String("refreshToken")] = mAccount->refreshToken(); wallet->writeMap(config()->name(), map); - kDebug() << "Wallet save: " << wallet->sync(); + qDebug() << "Wallet save: " << wallet->sync(); } delete wallet; } - QString GmailSettings::accountName(bool *userRejected) const { if (!mAccount) { @@ -238,8 +233,9 @@ if (!mAccount) { loadAccountFromKWallet(userRejected); } - if (mAccount) + if (mAccount) { return mAccount->accessToken(); + } return QString(); } @@ -272,10 +268,9 @@ saveAccountToKWallet(); } - void GmailSettings::loadAccount(ImapAccount *account) const { - kDebug() << userName(); + qDebug() << userName(); account->setServer(QLatin1String("imap.gmail.com")); account->setPort(993); @@ -285,7 +280,7 @@ account->setEncryptionMode(KIMAP::LoginJob::SslV3); account->setAuthenticationMode(KIMAP::LoginJob::XOAuth2); - account->setTimeout( sessionTimeout() ); + account->setTimeout(sessionTimeout()); } void GmailSettings::storeAccount(const KGAPI2::AccountPtr &account) diff -Nru kdepim-runtime-4.14.6/resources/gmail/gmailsettings.h kdepim-runtime-15.08.0/resources/gmail/gmailsettings.h --- kdepim-runtime-4.14.6/resources/gmail/gmailsettings.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/gmailsettings.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,9 +22,10 @@ #include -#include +#include -namespace KGAPI2 { +namespace KGAPI2 +{ class Job; class AuthJob; } @@ -34,7 +35,7 @@ class GmailSettings : public Settings { - Q_OBJECT + Q_OBJECT public: explicit GmailSettings(WId wid = 0); diff -Nru kdepim-runtime-4.14.6/resources/gmail/saslplugin/CMakeLists.txt kdepim-runtime-15.08.0/resources/gmail/saslplugin/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/gmail/saslplugin/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/saslplugin/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -3,8 +3,8 @@ add_definitions(-D_POSIX_SOURCE) -include_directories(${SASL2_INCLUDE_DIR} - ${SASL2_INCLUDE_DIR}/sasl) +include_directories(${Sasl2_INCLUDE_DIRS} + ${Sasl2_INCLUDE_DIR}/sasl) set(kdexoauth2sasl_SRCS plugin_common.c @@ -12,7 +12,12 @@ xoauth2plugin_init.c ) -kde4_add_library(kdexoauth2 SHARED ${kdexoauth2sasl_SRCS}) -set_target_properties(kdexoauth2 PROPERTIES SOVERSION 3 VERSION 3.0.0) +if(Sasl2_FOUND) + set(kdexoauth2sasl_EXTRA_LIBS ${Sasl2_LIBRARIES}) +endif() -install(TARGETS kdexoauth2 DESTINATION ${LIB_INSTALL_DIR}/sasl2) + +add_library(kdexoauth2 SHARED ${kdexoauth2sasl_SRCS} ${kdexoauth2sasl_EXTRA_LIBS}) +set_target_properties(kdexoauth2 PROPERTIES SOVERSION 4 VERSION 4.0.0) + +install(TARGETS kdexoauth2 DESTINATION ${KDE_INSTALL_LIBDIR}/sasl2) diff -Nru kdepim-runtime-4.14.6/resources/gmail/saslplugin/config.h kdepim-runtime-15.08.0/resources/gmail/saslplugin/config.h --- kdepim-runtime-4.14.6/resources/gmail/saslplugin/config.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/saslplugin/config.h 2015-08-10 21:01:02.000000000 +0000 @@ -1,7 +1,6 @@ /* config.h. Generated by configure. */ /* config.h.in. Generated from configure.in by autoheader. */ - /* acconfig.h - autoheader configuration input */ /* * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. @@ -46,7 +45,6 @@ #ifndef CONFIG_H #define CONFIG_H - /* Runtime config file location */ #define CONFIGDIR "/usr/lib/sasl2:/etc/sasl2" @@ -54,22 +52,22 @@ /* #undef DLSYM_NEEDS_UNDERSCORE */ /* Should we build a shared plugin (via dlopen) library? */ -#define DO_DLOPEN +#define DO_DLOPEN /* should we support sasl_checkapop? */ -#define DO_SASL_CHECKAPOP +#define DO_SASL_CHECKAPOP /* should we support setpass() for SRP? */ /* #undef DO_SRP_SETPASS */ /* should we mutex-wrap calls into the GSS library? */ -#define GSS_USE_MUTEXES +#define GSS_USE_MUTEXES /* Enable 'alwaystrue' password verifier? */ /* #undef HAVE_ALWAYSTRUE */ /* Include support for Courier's authdaemond? */ -#define HAVE_AUTHDAEMON +#define HAVE_AUTHDAEMON /* Define to 1 if you have the header file. */ /* #undef HAVE_DES_H */ @@ -91,7 +89,7 @@ #define HAVE_FCNTL_H 1 /* Do we have a getaddrinfo? */ -#define HAVE_GETADDRINFO +#define HAVE_GETADDRINFO /* Define to 1 if you have the `getdomainname' function. */ #define HAVE_GETDOMAINNAME 1 @@ -100,7 +98,7 @@ #define HAVE_GETHOSTNAME 1 /* Do we have a getnameinfo() function? */ -#define HAVE_GETNAMEINFO +#define HAVE_GETNAMEINFO /* Define to 1 if you have the `getpwnam' function. */ #define HAVE_GETPWNAM 1 @@ -109,23 +107,23 @@ #define HAVE_GETSPNAM 1 /* do we have getsubopt()? */ -#define HAVE_GETSUBOPT +#define HAVE_GETSUBOPT /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 /* Define if you have the gssapi.h header file */ -#define HAVE_GSSAPI_H +#define HAVE_GSSAPI_H /* Define to 1 if you have the `gsskrb5_register_acceptor_identity' function. */ /* #undef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY */ /* Define if your GSSAPI implimentation defines GSS_C_NT_HOSTBASED_SERVICE */ -#define HAVE_GSS_C_NT_HOSTBASED_SERVICE +#define HAVE_GSS_C_NT_HOSTBASED_SERVICE /* Define if your GSSAPI implimentation defines GSS_C_NT_USER_NAME */ -#define HAVE_GSS_C_NT_USER_NAME +#define HAVE_GSS_C_NT_USER_NAME /* Define to 1 if you have the `inet_aton' function. */ #define HAVE_INET_ATON 1 @@ -173,7 +171,7 @@ /* #undef HAVE_NDIR_H */ /* Do we have OpenSSL? */ -#define HAVE_OPENSSL +#define HAVE_OPENSSL /* Use OPIE for server-side OTP? */ /* #undef HAVE_OPIE */ @@ -191,7 +189,7 @@ /* #undef HAVE_PWCHECK */ /* Include support for saslauthd? */ -#define HAVE_SASLAUTHD +#define HAVE_SASLAUTHD /* Define to 1 if you have the header file. */ #define HAVE_SECURITY_PAM_APPL_H 1 @@ -200,7 +198,7 @@ #define HAVE_SELECT 1 /* Does the system have snprintf()? */ -#define HAVE_SNPRINTF +#define HAVE_SNPRINTF /* Does sockaddr have an sa_len? */ /* #undef HAVE_SOCKADDR_SA_LEN */ @@ -209,13 +207,13 @@ #define HAVE_SOCKET 1 /* Do we have a socklen_t? */ -#define HAVE_SOCKLEN_T +#define HAVE_SOCKLEN_T /* Do we have SQLite support? */ /* #undef HAVE_SQLITE */ /* Is there an ss_family in sockaddr_storage? */ -#define HAVE_SS_FAMILY +#define HAVE_SS_FAMILY /* Define to 1 if you have the header file. */ #define HAVE_STDARG_H 1 @@ -251,7 +249,7 @@ #define HAVE_STRTOL 1 /* Do we have struct sockaddr_stroage? */ -#define HAVE_STRUCT_SOCKADDR_STORAGE +#define HAVE_STRUCT_SOCKADDR_STORAGE /* Define to 1 if you have the header file. */ #define HAVE_SYSEXITS_H 1 @@ -298,7 +296,7 @@ /* #undef HAVE_VARARGS_H */ /* Does the system have vsnprintf()? */ -#define HAVE_VSNPRINTF +#define HAVE_VSNPRINTF /* define if your compiler has __attribute__ */ /* #undef HAVE___ATTRIBUTE__ */ @@ -346,7 +344,7 @@ #define RETSIGTYPE void /* Use BerkeleyDB for SASLdb */ -#define SASL_BERKELEYDB +#define SASL_BERKELEYDB /* Path to default SASLdb database */ #define SASL_DB_PATH "/etc/sasldb2" @@ -373,7 +371,7 @@ /* #undef STATIC_DIGESTMD5 */ /* Link GSSAPI Staticly */ -#define STATIC_GSSAPIV2 +#define STATIC_GSSAPIV2 /* User KERBEROS_V4 Staticly */ /* #undef STATIC_KERBEROS4 */ @@ -424,16 +422,16 @@ #define VERSION "2.1.23" /* Use DES */ -#define WITH_DES +#define WITH_DES /* Linking against dmalloc? */ /* #undef WITH_DMALLOC */ /* Use internal RC4 implementation? */ -#define WITH_RC4 +#define WITH_RC4 /* Use OpenSSL DES Implementation */ -#define WITH_SSL_DES +#define WITH_SSL_DES /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ @@ -448,9 +446,6 @@ /* Define to `int' if does not define. */ /* #undef pid_t */ - - - /* Create a struct iovec if we need one */ #if !defined(_WIN32) && !defined(HAVE_SYS_UIO_H) /* (win32 is handled in sasl.h) */ @@ -517,29 +512,29 @@ #endif /* HAVE_SOCKLEN_T */ #ifndef HAVE_STRUCT_SOCKADDR_STORAGE -#define _SS_MAXSIZE 128 /* Implementation specific max size */ -#define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr)) +#define _SS_MAXSIZE 128 /* Implementation specific max size */ +#define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr)) struct sockaddr_storage { - struct sockaddr ss_sa; - char __ss_pad2[_SS_PADSIZE]; + struct sockaddr ss_sa; + char __ss_pad2[_SS_PADSIZE]; }; # define ss_family ss_sa.sa_family #endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ #ifndef AF_INET6 /* Define it to something that should never appear */ -#define AF_INET6 AF_MAX +#define AF_INET6 AF_MAX #endif #ifndef HAVE_GETADDRINFO -#define getaddrinfo sasl_getaddrinfo -#define freeaddrinfo sasl_freeaddrinfo -#define gai_strerror sasl_gai_strerror +#define getaddrinfo sasl_getaddrinfo +#define freeaddrinfo sasl_freeaddrinfo +#define gai_strerror sasl_gai_strerror #endif #ifndef HAVE_GETNAMEINFO -#define getnameinfo sasl_getnameinfo +#define getnameinfo sasl_getnameinfo #endif #if !defined(HAVE_GETNAMEINFO) || !defined(HAVE_GETADDRINFO) diff -Nru kdepim-runtime-4.14.6/resources/gmail/saslplugin/plugin_common.c kdepim-runtime-15.08.0/resources/gmail/saslplugin/plugin_common.c --- kdepim-runtime-4.14.6/resources/gmail/saslplugin/plugin_common.c 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/saslplugin/plugin_common.c 2015-08-10 21:01:02.000000000 +0000 @@ -2,7 +2,7 @@ * Rob Siemborski * $Id: plugin_common.c,v 1.22 2011/09/01 14:12:18 mel Exp $ */ -/* +/* * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,7 +10,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in @@ -20,7 +20,7 @@ * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any other legal - * details, please contact + * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue @@ -76,10 +76,10 @@ /* translate IPv4 mapped IPv6 address to IPv4 address */ static void sockaddr_unmapped( #ifdef IN6_IS_ADDR_V4MAPPED - struct sockaddr *sa, socklen_t *len + struct sockaddr *sa, socklen_t *len #else - struct sockaddr *sa __attribute__((unused)), - socklen_t *len __attribute__((unused)) + struct sockaddr *sa __attribute__((unused)), + socklen_t *len __attribute__((unused)) #endif ) { @@ -89,11 +89,13 @@ uint32_t addr; int port; - if (sa->sa_family != AF_INET6) - return; + if (sa->sa_family != AF_INET6) { + return; + } sin6 = (struct sockaddr_in6 *)sa; - if (!IN6_IS_ADDR_V4MAPPED((&sin6->sin6_addr))) - return; + if (!IN6_IS_ADDR_V4MAPPED((&sin6->sin6_addr))) { + return; + } sin4 = (struct sockaddr_in *)sa; addr = *(uint32_t *)&sin6->sin6_addr.s6_addr[12]; port = sin6->sin6_port; @@ -111,46 +113,51 @@ } int _plug_ipfromstring(const sasl_utils_t *utils, const char *addr, - struct sockaddr *out, socklen_t outlen) + struct sockaddr *out, socklen_t outlen) { int i, j; socklen_t len; struct sockaddr_storage ss; struct addrinfo hints, *ai = NULL; char hbuf[NI_MAXHOST]; - - if(!utils || !addr || !out) { - if(utils) PARAMERROR( utils ); - return SASL_BADPARAM; + + if (!utils || !addr || !out) { + if (utils) { + PARAMERROR(utils); + } + return SASL_BADPARAM; } /* Parse the address */ for (i = 0; addr[i] != '\0' && addr[i] != ';'; i++) { - if (i >= NI_MAXHOST) { - if(utils) PARAMERROR( utils ); - return SASL_BADPARAM; - } - hbuf[i] = addr[i]; + if (i >= NI_MAXHOST) { + if (utils) { + PARAMERROR(utils); + } + return SASL_BADPARAM; + } + hbuf[i] = addr[i]; } hbuf[i] = '\0'; - if (addr[i] == ';') - i++; + if (addr[i] == ';') { + i++; + } /* XXX/FIXME: Do we need this check? */ for (j = i; addr[j] != '\0'; j++) - if (!isdigit((int)(addr[j]))) { - PARAMERROR( utils ); - return SASL_BADPARAM; - } + if (!isdigit((int)(addr[j]))) { + PARAMERROR(utils); + return SASL_BADPARAM; + } memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; - if (getaddrinfo(hbuf, &addr[i], &hints, &ai) != 0) { - PARAMERROR( utils ); - return SASL_BADPARAM; + if (getaddrinfo(hbuf, &addr[i], &hints, &ai) != 0) { + PARAMERROR(utils); + return SASL_BADPARAM; } len = ai->ai_addrlen; @@ -158,8 +165,8 @@ freeaddrinfo(ai); sockaddr_unmapped((struct sockaddr *)&ss, &len); if (outlen < len) { - PARAMERROR( utils ); - return SASL_BUFOVER; + PARAMERROR(utils); + return SASL_BUFOVER; } memcpy(out, &ss, len); @@ -168,46 +175,49 @@ } int _plug_iovec_to_buf(const sasl_utils_t *utils, const struct iovec *vec, - unsigned numiov, buffer_info_t **output) + unsigned numiov, buffer_info_t **output) { unsigned i; int ret; buffer_info_t *out; char *pos; - if(!utils || !vec || !output) { - if(utils) PARAMERROR( utils ); - return SASL_BADPARAM; - } - - if(!(*output)) { - *output = utils->malloc(sizeof(buffer_info_t)); - if(!*output) { - MEMERROR(utils); - return SASL_NOMEM; - } - memset(*output,0,sizeof(buffer_info_t)); + if (!utils || !vec || !output) { + if (utils) { + PARAMERROR(utils); + } + return SASL_BADPARAM; + } + + if (!(*output)) { + *output = utils->malloc(sizeof(buffer_info_t)); + if (!*output) { + MEMERROR(utils); + return SASL_NOMEM; + } + memset(*output, 0, sizeof(buffer_info_t)); } out = *output; - + out->curlen = 0; - for(i=0; icurlen += vec[i].iov_len; + for (i = 0; i < numiov; i++) { + out->curlen += vec[i].iov_len; + } ret = _plug_buf_alloc(utils, &out->data, &out->reallen, out->curlen); - if(ret != SASL_OK) { - MEMERROR(utils); - return SASL_NOMEM; + if (ret != SASL_OK) { + MEMERROR(utils); + return SASL_NOMEM; } - + memset(out->data, 0, out->reallen); pos = out->data; - - for(i=0; imalloc(newlen); - if (*rwbuf == NULL) { - *curlen = 0; - MEMERROR(utils); - return SASL_NOMEM; - } - *curlen = newlen; - } else if(*rwbuf && *curlen < newlen) { - size_t needed = 2*(*curlen); - - while(needed < newlen) - needed *= 2; - - *rwbuf = utils->realloc(*rwbuf, needed); - if (*rwbuf == NULL) { - *curlen = 0; - MEMERROR(utils); - return SASL_NOMEM; - } - *curlen = needed; - } + if (!utils || !rwbuf || !curlen) { + PARAMERROR(utils); + return SASL_BADPARAM; + } + + if (!(*rwbuf)) { + *rwbuf = utils->malloc(newlen); + if (*rwbuf == NULL) { + *curlen = 0; + MEMERROR(utils); + return SASL_NOMEM; + } + *curlen = newlen; + } else if (*rwbuf && *curlen < newlen) { + size_t needed = 2 * (*curlen); + + while (needed < newlen) { + needed *= 2; + } + + *rwbuf = utils->realloc(*rwbuf, needed); + if (*rwbuf == NULL) { + *curlen = 0; + MEMERROR(utils); + return SASL_NOMEM; + } + *curlen = needed; + } return SASL_OK; } /* copy a string */ -int _plug_strdup(const sasl_utils_t * utils, const char *in, - char **out, int *outlen) +int _plug_strdup(const sasl_utils_t *utils, const char *in, + char **out, int *outlen) { - size_t len = strlen(in); + size_t len = strlen(in); - if(!utils || !in || !out) { - if(utils) PARAMERROR(utils); - return SASL_BADPARAM; - } + if (!utils || !in || !out) { + if (utils) { + PARAMERROR(utils); + } + return SASL_BADPARAM; + } - *out = utils->malloc(len + 1); - if (!*out) { - MEMERROR(utils); - return SASL_NOMEM; - } + *out = utils->malloc(len + 1); + if (!*out) { + MEMERROR(utils); + return SASL_NOMEM; + } - strcpy((char *) *out, in); + strcpy((char *) *out, in); - if (outlen) - *outlen = len; + if (outlen) { + *outlen = len; + } - return SASL_OK; + return SASL_OK; } void _plug_free_string(const sasl_utils_t *utils, char **str) { - size_t len; + size_t len; - if (!utils || !str || !(*str)) return; + if (!utils || !str || !(*str)) { + return; + } - len = strlen(*str); + len = strlen(*str); - utils->erasebuffer(*str, len); - utils->free(*str); + utils->erasebuffer(*str, len); + utils->free(*str); - *str=NULL; + *str = NULL; } -void _plug_free_secret(const sasl_utils_t *utils, sasl_secret_t **secret) +void _plug_free_secret(const sasl_utils_t *utils, sasl_secret_t **secret) { - if(!utils || !secret || !(*secret)) return; + if (!utils || !secret || !(*secret)) { + return; + } utils->erasebuffer((char *)(*secret)->data, (*secret)->len); utils->free(*secret); *secret = NULL; } -/* - * Trys to find the prompt with the lookingfor id in the prompt list +/* + * Tries to find the prompt with the lookingfor id in the prompt list * Returns it if found. NULL otherwise */ sasl_interact_t *_plug_find_prompt(sasl_interact_t **promptlist, - unsigned int lookingfor) + unsigned int lookingfor) { sasl_interact_t *prompt; if (promptlist && *promptlist) { - for (prompt = *promptlist; prompt->id != SASL_CB_LIST_END; ++prompt) { - if (prompt->id==lookingfor) - return prompt; - } + for (prompt = *promptlist; prompt->id != SASL_CB_LIST_END; ++prompt) { + if (prompt->id == lookingfor) { + return prompt; + } + } } return NULL; @@ -319,7 +338,7 @@ * Retrieve the simple string given by the callback id. */ int _plug_get_simple(const sasl_utils_t *utils, unsigned int id, int required, - const char **result, sasl_interact_t **prompt_need) + const char **result, sasl_interact_t **prompt_need) { int ret = SASL_FAIL; @@ -332,34 +351,36 @@ /* see if we were given the result in the prompt */ prompt = _plug_find_prompt(prompt_need, id); if (prompt != NULL) { - /* We prompted, and got.*/ - - if (required && !prompt->result) { - SETERROR(utils, "Unexpectedly missing a prompt result"); - return SASL_BADPARAM; - } + /* We prompted, and got.*/ + + if (required && !prompt->result) { + SETERROR(utils, "Unexpectedly missing a prompt result"); + return SASL_BADPARAM; + } - *result = prompt->result; - return SASL_OK; + *result = prompt->result; + return SASL_OK; } - + /* Try to get the callback... */ ret = utils->getcallback(utils->conn, id, (sasl_callback_ft *)&simple_cb, &simple_context); - if (ret == SASL_FAIL && !required) - return SASL_OK; + if (ret == SASL_FAIL && !required) { + return SASL_OK; + } if (ret == SASL_OK && simple_cb) { - ret = simple_cb(simple_context, id, result, NULL); - if (ret != SASL_OK) - return ret; - - if (required && !*result) { - PARAMERROR(utils); - return SASL_BADPARAM; - } + ret = simple_cb(simple_context, id, result, NULL); + if (ret != SASL_OK) { + return ret; + } + + if (required && !*result) { + PARAMERROR(utils); + return SASL_BADPARAM; + } } - + return ret; } @@ -367,7 +388,7 @@ * Retrieve the user password. */ int _plug_get_password(const sasl_utils_t *utils, sasl_secret_t **password, - unsigned int *iscopy, sasl_interact_t **prompt_need) + unsigned int *iscopy, sasl_interact_t **prompt_need) { int ret = SASL_FAIL; sasl_getsecret_t *pass_cb; @@ -380,43 +401,44 @@ /* see if we were given the password in the prompt */ prompt = _plug_find_prompt(prompt_need, SASL_CB_PASS); if (prompt != NULL) { - /* We prompted, and got.*/ - - if (!prompt->result) { - SETERROR(utils, "Unexpectedly missing a prompt result"); - return SASL_BADPARAM; - } - - /* copy what we got into a secret_t */ - *password = (sasl_secret_t *) utils->malloc(sizeof(sasl_secret_t) + - prompt->len + 1); - if (!*password) { - MEMERROR(utils); - return SASL_NOMEM; - } - - (*password)->len=prompt->len; - memcpy((*password)->data, prompt->result, prompt->len); - (*password)->data[(*password)->len]=0; + /* We prompted, and got.*/ + + if (!prompt->result) { + SETERROR(utils, "Unexpectedly missing a prompt result"); + return SASL_BADPARAM; + } + + /* copy what we got into a secret_t */ + *password = (sasl_secret_t *) utils->malloc(sizeof(sasl_secret_t) + + prompt->len + 1); + if (!*password) { + MEMERROR(utils); + return SASL_NOMEM; + } + + (*password)->len = prompt->len; + memcpy((*password)->data, prompt->result, prompt->len); + (*password)->data[(*password)->len] = 0; - *iscopy = 1; + *iscopy = 1; - return SASL_OK; + return SASL_OK; } /* Try to get the callback... */ ret = utils->getcallback(utils->conn, SASL_CB_PASS, - (sasl_callback_ft *)&pass_cb, &pass_context); + (sasl_callback_ft *)&pass_cb, &pass_context); if (ret == SASL_OK && pass_cb) { - ret = pass_cb(utils->conn, pass_context, SASL_CB_PASS, password); - if (ret != SASL_OK) - return ret; - - if (!*password) { - PARAMERROR(utils); - return SASL_BADPARAM; - } + ret = pass_cb(utils->conn, pass_context, SASL_CB_PASS, password); + if (ret != SASL_OK) { + return ret; + } + + if (!*password) { + PARAMERROR(utils); + return SASL_BADPARAM; + } } return ret; @@ -426,8 +448,8 @@ * Retrieve the string given by the challenge prompt id. */ int _plug_challenge_prompt(const sasl_utils_t *utils, unsigned int id, - const char *challenge, const char *promptstr, - const char **result, sasl_interact_t **prompt_need) + const char *challenge, const char *promptstr, + const char **result, sasl_interact_t **prompt_need) { int ret = SASL_FAIL; sasl_chalprompt_t *chalprompt_cb; @@ -439,31 +461,32 @@ /* see if we were given the password in the prompt */ prompt = _plug_find_prompt(prompt_need, id); if (prompt != NULL) { - /* We prompted, and got.*/ - - if (!prompt->result) { - SETERROR(utils, "Unexpectedly missing a prompt result"); - return SASL_BADPARAM; - } - - *result = prompt->result; - return SASL_OK; + /* We prompted, and got.*/ + + if (!prompt->result) { + SETERROR(utils, "Unexpectedly missing a prompt result"); + return SASL_BADPARAM; + } + + *result = prompt->result; + return SASL_OK; } /* Try to get the callback... */ ret = utils->getcallback(utils->conn, id, - (sasl_callback_ft *)&chalprompt_cb, &chalprompt_context); + (sasl_callback_ft *)&chalprompt_cb, &chalprompt_context); if (ret == SASL_OK && chalprompt_cb) { - ret = chalprompt_cb(chalprompt_context, id, - challenge, promptstr, NULL, result, NULL); - if (ret != SASL_OK) - return ret; - - if (!*result) { - PARAMERROR(utils); - return SASL_BADPARAM; - } + ret = chalprompt_cb(chalprompt_context, id, + challenge, promptstr, NULL, result, NULL); + if (ret != SASL_OK) { + return ret; + } + + if (!*result) { + PARAMERROR(utils); + return SASL_BADPARAM; + } } return ret; @@ -473,7 +496,7 @@ * Retrieve the client realm. */ int _plug_get_realm(const sasl_utils_t *utils, const char **availrealms, - const char **realm, sasl_interact_t **prompt_need) + const char **realm, sasl_interact_t **prompt_need) { int ret = SASL_FAIL; sasl_getrealm_t *realm_cb; @@ -485,32 +508,33 @@ /* see if we were given the result in the prompt */ prompt = _plug_find_prompt(prompt_need, SASL_CB_GETREALM); if (prompt != NULL) { - /* We prompted, and got.*/ - - if (!prompt->result) { - SETERROR(utils, "Unexpectedly missing a prompt result"); - return SASL_BADPARAM; - } + /* We prompted, and got.*/ + + if (!prompt->result) { + SETERROR(utils, "Unexpectedly missing a prompt result"); + return SASL_BADPARAM; + } - *realm = prompt->result; - return SASL_OK; + *realm = prompt->result; + return SASL_OK; } /* Try to get the callback... */ ret = utils->getcallback(utils->conn, SASL_CB_GETREALM, - (sasl_callback_ft *)&realm_cb, &realm_context); + (sasl_callback_ft *)&realm_cb, &realm_context); if (ret == SASL_OK && realm_cb) { - ret = realm_cb(realm_context, SASL_CB_GETREALM, availrealms, realm); - if (ret != SASL_OK) - return ret; - - if (!*realm) { - PARAMERROR(utils); - return SASL_BADPARAM; - } + ret = realm_cb(realm_context, SASL_CB_GETREALM, availrealms, realm); + if (ret != SASL_OK) { + return ret; + } + + if (!*realm) { + PARAMERROR(utils); + return SASL_BADPARAM; + } } - + return ret; } @@ -518,83 +542,93 @@ * Make the requested prompts. (prompt==NULL means we don't want it) */ int _plug_make_prompts(const sasl_utils_t *utils, - sasl_interact_t **prompts_res, - const char *user_prompt, const char *user_def, - const char *auth_prompt, const char *auth_def, - const char *pass_prompt, const char *pass_def, - const char *echo_chal, - const char *echo_prompt, const char *echo_def, - const char *realm_chal, - const char *realm_prompt, const char *realm_def) + sasl_interact_t **prompts_res, + const char *user_prompt, const char *user_def, + const char *auth_prompt, const char *auth_def, + const char *pass_prompt, const char *pass_def, + const char *echo_chal, + const char *echo_prompt, const char *echo_def, + const char *realm_chal, + const char *realm_prompt, const char *realm_def) { int num = 1; int alloc_size; sasl_interact_t *prompts; - if (user_prompt) num++; - if (auth_prompt) num++; - if (pass_prompt) num++; - if (echo_prompt) num++; - if (realm_prompt) num++; + if (user_prompt) { + num++; + } + if (auth_prompt) { + num++; + } + if (pass_prompt) { + num++; + } + if (echo_prompt) { + num++; + } + if (realm_prompt) { + num++; + } if (num == 1) { - SETERROR( utils, "make_prompts() called with no actual prompts" ); - return SASL_FAIL; + SETERROR(utils, "make_prompts() called with no actual prompts"); + return SASL_FAIL; } - alloc_size = sizeof(sasl_interact_t)*num; + alloc_size = sizeof(sasl_interact_t) * num; prompts = utils->malloc(alloc_size); if (!prompts) { - MEMERROR( utils ); - return SASL_NOMEM; + MEMERROR(utils); + return SASL_NOMEM; } memset(prompts, 0, alloc_size); - + *prompts_res = prompts; if (user_prompt) { - (prompts)->id = SASL_CB_USER; - (prompts)->challenge = "Authorization Name"; - (prompts)->prompt = user_prompt; - (prompts)->defresult = user_def; + (prompts)->id = SASL_CB_USER; + (prompts)->challenge = "Authorization Name"; + (prompts)->prompt = user_prompt; + (prompts)->defresult = user_def; - prompts++; + prompts++; } if (auth_prompt) { - (prompts)->id = SASL_CB_AUTHNAME; - (prompts)->challenge = "Authentication Name"; - (prompts)->prompt = auth_prompt; - (prompts)->defresult = auth_def; + (prompts)->id = SASL_CB_AUTHNAME; + (prompts)->challenge = "Authentication Name"; + (prompts)->prompt = auth_prompt; + (prompts)->defresult = auth_def; - prompts++; + prompts++; } if (pass_prompt) { - (prompts)->id = SASL_CB_PASS; - (prompts)->challenge = "Password"; - (prompts)->prompt = pass_prompt; - (prompts)->defresult = pass_def; + (prompts)->id = SASL_CB_PASS; + (prompts)->challenge = "Password"; + (prompts)->prompt = pass_prompt; + (prompts)->defresult = pass_def; - prompts++; + prompts++; } if (echo_prompt) { - (prompts)->id = SASL_CB_ECHOPROMPT; - (prompts)->challenge = echo_chal; - (prompts)->prompt = echo_prompt; - (prompts)->defresult = echo_def; + (prompts)->id = SASL_CB_ECHOPROMPT; + (prompts)->challenge = echo_chal; + (prompts)->prompt = echo_prompt; + (prompts)->defresult = echo_def; - prompts++; + prompts++; } if (realm_prompt) { - (prompts)->id = SASL_CB_GETREALM; - (prompts)->challenge = realm_chal; - (prompts)->prompt = realm_prompt; - (prompts)->defresult = realm_def; + (prompts)->id = SASL_CB_GETREALM; + (prompts)->challenge = realm_chal; + (prompts)->prompt = realm_prompt; + (prompts)->defresult = realm_def; - prompts++; + prompts++; } /* add the ending one */ @@ -607,7 +641,7 @@ } void _plug_decode_init(decode_context_t *text, - const sasl_utils_t *utils, unsigned int in_maxbuf) + const sasl_utils_t *utils, unsigned int in_maxbuf) { memset(text, 0, sizeof(decode_context_t)); @@ -621,288 +655,298 @@ * using decode_pkt() to decode individual packets. */ int _plug_decode(decode_context_t *text, - const char *input, unsigned inputlen, - char **output, /* output buffer */ - unsigned *outputsize, /* current size of output buffer */ - unsigned *outputlen, /* length of data in output buffer */ - int (*decode_pkt)(void *rock, - const char *input, unsigned inputlen, - char **output, unsigned *outputlen), - void *rock) + const char *input, unsigned inputlen, + char **output, /* output buffer */ + unsigned *outputsize, /* current size of output buffer */ + unsigned *outputlen, /* length of data in output buffer */ + int (*decode_pkt)(void *rock, + const char *input, unsigned inputlen, + char **output, unsigned *outputlen), + void *rock) { unsigned int tocopy; unsigned diff; char *tmp; unsigned tmplen; int ret; - + *outputlen = 0; while (inputlen) { /* more input */ - if (text->needsize) { /* need to get the rest of the 4-byte size */ + if (text->needsize) { /* need to get the rest of the 4-byte size */ + + /* copy as many bytes (up to 4) as we have into size buffer */ + tocopy = (inputlen > text->needsize) ? text->needsize : inputlen; + memcpy(text->sizebuf + 4 - text->needsize, input, tocopy); + text->needsize -= tocopy; + + input += tocopy; + inputlen -= tocopy; + + if (!text->needsize) { /* we have the entire 4-byte size */ + memcpy(&(text->size), text->sizebuf, 4); + text->size = ntohl(text->size); + + if (!text->size) { /* should never happen */ + return SASL_FAIL; + } + + if (text->size > text->in_maxbuf) { + text->utils->log(NULL, SASL_LOG_ERR, + "encoded packet size too big (%d > %d)", + text->size, text->in_maxbuf); + return SASL_FAIL; + } + + if (!text->buffer) { + text->buffer = text->utils->malloc(text->in_maxbuf); + } + if (text->buffer == NULL) { + return SASL_NOMEM; + } + + text->cursize = 0; + } else { + /* We do NOT have the entire 4-byte size... + * wait for more data */ + return SASL_OK; + } + } + + diff = text->size - text->cursize; /* bytes needed for full packet */ + + if (inputlen < diff) { /* not a complete packet, need more input */ + memcpy(text->buffer + text->cursize, input, inputlen); + text->cursize += inputlen; + return SASL_OK; + } + + /* copy the rest of the packet */ + memcpy(text->buffer + text->cursize, input, diff); + input += diff; + inputlen -= diff; + + /* decode the packet (no need to free tmp) */ + ret = decode_pkt(rock, text->buffer, text->size, &tmp, &tmplen); + if (ret != SASL_OK) { + return ret; + } + + /* append the decoded packet to the output */ + ret = _plug_buf_alloc(text->utils, output, outputsize, + *outputlen + tmplen + 1); /* +1 for NUL */ + if (ret != SASL_OK) { + return ret; + } - /* copy as many bytes (up to 4) as we have into size buffer */ - tocopy = (inputlen > text->needsize) ? text->needsize : inputlen; - memcpy(text->sizebuf + 4 - text->needsize, input, tocopy); - text->needsize -= tocopy; - - input += tocopy; - inputlen -= tocopy; - - if (!text->needsize) { /* we have the entire 4-byte size */ - memcpy(&(text->size), text->sizebuf, 4); - text->size = ntohl(text->size); - - if (!text->size) /* should never happen */ - return SASL_FAIL; - - if (text->size > text->in_maxbuf) { - text->utils->log(NULL, SASL_LOG_ERR, - "encoded packet size too big (%d > %d)", - text->size, text->in_maxbuf); - return SASL_FAIL; - } - - if (!text->buffer) - text->buffer = text->utils->malloc(text->in_maxbuf); - if (text->buffer == NULL) return SASL_NOMEM; - - text->cursize = 0; - } else { - /* We do NOT have the entire 4-byte size... - * wait for more data */ - return SASL_OK; - } - } - - diff = text->size - text->cursize; /* bytes needed for full packet */ - - if (inputlen < diff) { /* not a complete packet, need more input */ - memcpy(text->buffer + text->cursize, input, inputlen); - text->cursize += inputlen; - return SASL_OK; - } - - /* copy the rest of the packet */ - memcpy(text->buffer + text->cursize, input, diff); - input += diff; - inputlen -= diff; - - /* decode the packet (no need to free tmp) */ - ret = decode_pkt(rock, text->buffer, text->size, &tmp, &tmplen); - if (ret != SASL_OK) return ret; - - /* append the decoded packet to the output */ - ret = _plug_buf_alloc(text->utils, output, outputsize, - *outputlen + tmplen + 1); /* +1 for NUL */ - if (ret != SASL_OK) return ret; - - memcpy(*output + *outputlen, tmp, tmplen); - *outputlen += tmplen; + memcpy(*output + *outputlen, tmp, tmplen); + *outputlen += tmplen; - /* protect stupid clients */ - *(*output + *outputlen) = '\0'; + /* protect stupid clients */ + *(*output + *outputlen) = '\0'; - /* reset for the next packet */ - text->needsize = 4; + /* reset for the next packet */ + text->needsize = 4; } - return SASL_OK; + return SASL_OK; } void _plug_decode_free(decode_context_t *text) { - if (text->buffer) text->utils->free(text->buffer); + if (text->buffer) { + text->utils->free(text->buffer); + } } /* returns the realm we should pretend to be in */ int _plug_parseuser(const sasl_utils_t *utils, - char **user, char **realm, const char *user_realm, - const char *serverFQDN, const char *input) + char **user, char **realm, const char *user_realm, + const char *serverFQDN, const char *input) { int ret; char *r; - if(!user || !serverFQDN) { - PARAMERROR( utils ); - return SASL_BADPARAM; + if (!user || !serverFQDN) { + PARAMERROR(utils); + return SASL_BADPARAM; } r = strchr(input, '@'); if (!r) { - /* hmmm, the user didn't specify a realm */ - if(user_realm && user_realm[0]) { - ret = _plug_strdup(utils, user_realm, realm, NULL); - } else { - /* Default to serverFQDN */ - ret = _plug_strdup(utils, serverFQDN, realm, NULL); - } - - if (ret == SASL_OK) { - ret = _plug_strdup(utils, input, user, NULL); - } + /* hmmm, the user didn't specify a realm */ + if (user_realm && user_realm[0]) { + ret = _plug_strdup(utils, user_realm, realm, NULL); + } else { + /* Default to serverFQDN */ + ret = _plug_strdup(utils, serverFQDN, realm, NULL); + } + + if (ret == SASL_OK) { + ret = _plug_strdup(utils, input, user, NULL); + } } else { - r++; - ret = _plug_strdup(utils, r, realm, NULL); - *--r = '\0'; - *user = utils->malloc(r - input + 1); - if (*user) { - strncpy(*user, input, r - input +1); - } else { - MEMERROR( utils ); - ret = SASL_NOMEM; - } - *r = '@'; + r++; + ret = _plug_strdup(utils, r, realm, NULL); + *--r = '\0'; + *user = utils->malloc(r - input + 1); + if (*user) { + strncpy(*user, input, r - input + 1); + } else { + MEMERROR(utils); + ret = SASL_NOMEM; + } + *r = '@'; } return ret; } int _plug_make_fulluser(const sasl_utils_t *utils, - char **fulluser, - const char * useronly, - const char *realm) + char **fulluser, + const char *useronly, + const char *realm) { - if(!fulluser || !useronly || !realm) { - PARAMERROR( utils ); - return (SASL_BADPARAM); + if (!fulluser || !useronly || !realm) { + PARAMERROR(utils); + return (SASL_BADPARAM); } - *fulluser = utils->malloc (strlen(useronly) + strlen(realm) + 2); + *fulluser = utils->malloc(strlen(useronly) + strlen(realm) + 2); if (*fulluser == NULL) { - MEMERROR( utils ); - return (SASL_NOMEM); + MEMERROR(utils); + return (SASL_NOMEM); } - strcpy (*fulluser, useronly); - strcat (*fulluser, "@"); - strcat (*fulluser, realm); + strcpy(*fulluser, useronly); + strcat(*fulluser, "@"); + strcat(*fulluser, realm); return (SASL_OK); } -char * _plug_get_error_message (const sasl_utils_t *utils, +char *_plug_get_error_message(const sasl_utils_t *utils, #ifdef WIN32 - DWORD error + DWORD error #else - int error + int error #endif - ) + ) { - char * return_value; + char *return_value; #ifdef WIN32 LPVOID lpMsgBuf; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - error, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ - (LPTSTR) &lpMsgBuf, - 0, - NULL + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ + (LPTSTR) &lpMsgBuf, + 0, + NULL ); - if (_plug_strdup (utils, lpMsgBuf, &return_value, NULL) != SASL_OK) { - return_value = NULL; + if (_plug_strdup(utils, lpMsgBuf, &return_value, NULL) != SASL_OK) { + return_value = NULL; } - LocalFree( lpMsgBuf ); + LocalFree(lpMsgBuf); #else /* !WIN32 */ - if (_plug_strdup (utils, strerror(error), &return_value, NULL) != SASL_OK) { - return_value = NULL; + if (_plug_strdup(utils, strerror(error), &return_value, NULL) != SASL_OK) { + return_value = NULL; } #endif /* WIN32 */ return (return_value); } -void _plug_snprintf_os_info (char * osbuf, int osbuf_len) +void _plug_snprintf_os_info(char *osbuf, int osbuf_len) { #ifdef WIN32 OSVERSIONINFOEX versioninfo; char *sysname; -/* : - DWORD dwOSVersionInfoSize; - DWORD dwMajorVersion; - DWORD dwMinorVersion; - DWORD dwBuildNumber; - TCHAR szCSDVersion[ 128 ]; -//Only NT SP 6 and later - WORD wServicePackMajor; - WORD wServicePackMinor; - WORD wSuiteMask; - BYTE wProductType; - */ + /* : + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + TCHAR szCSDVersion[ 128 ]; + //Only NT SP 6 and later + WORD wServicePackMajor; + WORD wServicePackMinor; + WORD wSuiteMask; + BYTE wProductType; + */ - versioninfo.dwOSVersionInfoSize = sizeof (versioninfo); + versioninfo.dwOSVersionInfoSize = sizeof(versioninfo); sysname = "Unknown Windows"; - if (GetVersionEx ((OSVERSIONINFO *) &versioninfo) == FALSE) { - snprintf(osbuf, osbuf_len, "%s", sysname); - goto SKIP_OS_INFO; + if (GetVersionEx((OSVERSIONINFO *) &versioninfo) == FALSE) { + snprintf(osbuf, osbuf_len, "%s", sysname); + goto SKIP_OS_INFO; } switch (versioninfo.dwPlatformId) { - case VER_PLATFORM_WIN32s: /* Win32s on Windows 3.1 */ - sysname = "Win32s on Windows 3.1"; -/* I can't test if dwBuildNumber has any meaning on Win32s */ - break; - - case VER_PLATFORM_WIN32_WINDOWS: /* 95/98/ME */ - switch (versioninfo.dwMinorVersion) { - case 0: - sysname = "Windows 95"; - break; - case 10: - sysname = "Windows 98"; - break; - case 90: - sysname = "Windows Me"; - break; - default: - sysname = "Unknown Windows 9X/ME series"; - break; - } -/* Clear the high order word, as it contains major/minor version */ - versioninfo.dwBuildNumber &= 0xFFFF; - break; - - case VER_PLATFORM_WIN32_NT: /* NT/2000/XP/.NET */ - if (versioninfo.dwMinorVersion > 99) { - } else { - switch (versioninfo.dwMajorVersion * 100 + versioninfo.dwMinorVersion) { - case 351: - sysname = "Windows NT 3.51"; - break; - case 400: - sysname = "Windows NT 4.0"; - break; - case 500: - sysname = "Windows 2000"; - break; - case 501: - sysname = "Windows XP/.NET"; /* or Windows .NET Server */ - break; - default: - sysname = "Unknown Windows NT series"; - break; - } - } - break; + case VER_PLATFORM_WIN32s: /* Win32s on Windows 3.1 */ + sysname = "Win32s on Windows 3.1"; + /* I can't test if dwBuildNumber has any meaning on Win32s */ + break; + + case VER_PLATFORM_WIN32_WINDOWS: /* 95/98/ME */ + switch (versioninfo.dwMinorVersion) { + case 0: + sysname = "Windows 95"; + break; + case 10: + sysname = "Windows 98"; + break; + case 90: + sysname = "Windows Me"; + break; + default: + sysname = "Unknown Windows 9X/ME series"; + break; + } + /* Clear the high order word, as it contains major/minor version */ + versioninfo.dwBuildNumber &= 0xFFFF; + break; + + case VER_PLATFORM_WIN32_NT: /* NT/2000/XP/.NET */ + if (versioninfo.dwMinorVersion > 99) { + } else { + switch (versioninfo.dwMajorVersion * 100 + versioninfo.dwMinorVersion) { + case 351: + sysname = "Windows NT 3.51"; + break; + case 400: + sysname = "Windows NT 4.0"; + break; + case 500: + sysname = "Windows 2000"; + break; + case 501: + sysname = "Windows XP/.NET"; /* or Windows .NET Server */ + break; + default: + sysname = "Unknown Windows NT series"; + break; + } + } + break; - default: - break; + default: + break; } snprintf(osbuf, osbuf_len, - "%s %s (Build %u)", - sysname, - versioninfo.szCSDVersion, - versioninfo.dwBuildNumber - ); + "%s %s (Build %u)", + sysname, + versioninfo.szCSDVersion, + versioninfo.dwBuildNumber + ); SKIP_OS_INFO: ; @@ -916,10 +960,10 @@ } #if defined(WIN32) -unsigned int plug_sleep (unsigned int seconds) +unsigned int plug_sleep(unsigned int seconds) { - long dwSec = seconds*1000; - Sleep (dwSec); + long dwSec = seconds * 1000; + Sleep(dwSec); return 0; } #endif diff -Nru kdepim-runtime-4.14.6/resources/gmail/saslplugin/plugin_common.h kdepim-runtime-15.08.0/resources/gmail/saslplugin/plugin_common.h --- kdepim-runtime-4.14.6/resources/gmail/saslplugin/plugin_common.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/saslplugin/plugin_common.h 2015-08-10 21:01:02.000000000 +0000 @@ -3,7 +3,7 @@ * Rob Siemborski * $Id: plugin_common.h,v 1.21 2006/01/17 12:18:21 mel Exp $ */ -/* +/* * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -11,7 +11,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in @@ -21,7 +21,7 @@ * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any other legal - * details, please contact + * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue @@ -70,44 +70,44 @@ #endif #define SASL_CLIENT_PLUG_INIT( x ) \ -extern sasl_client_plug_init_t x##_client_plug_init; \ -PLUG_API int sasl_client_plug_init(const sasl_utils_t *utils, \ - int maxversion, int *out_version, \ - sasl_client_plug_t **pluglist, \ - int *plugcount) { \ + extern sasl_client_plug_init_t x##_client_plug_init; \ + PLUG_API int sasl_client_plug_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_client_plug_t **pluglist, \ + int *plugcount) { \ return x##_client_plug_init(utils, maxversion, out_version, \ - pluglist, plugcount); \ -} + pluglist, plugcount); \ + } #define SASL_SERVER_PLUG_INIT( x ) \ -extern sasl_server_plug_init_t x##_server_plug_init; \ -PLUG_API int sasl_server_plug_init(const sasl_utils_t *utils, \ - int maxversion, int *out_version, \ - sasl_server_plug_t **pluglist, \ - int *plugcount) { \ + extern sasl_server_plug_init_t x##_server_plug_init; \ + PLUG_API int sasl_server_plug_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_server_plug_t **pluglist, \ + int *plugcount) { \ return x##_server_plug_init(utils, maxversion, out_version, \ - pluglist, plugcount); \ -} + pluglist, plugcount); \ + } #define SASL_AUXPROP_PLUG_INIT( x ) \ -extern sasl_auxprop_init_t x##_auxprop_plug_init; \ -PLUG_API int sasl_auxprop_plug_init(const sasl_utils_t *utils, \ - int maxversion, int *out_version, \ - sasl_auxprop_plug_t **plug, \ - const char *plugname) {\ + extern sasl_auxprop_init_t x##_auxprop_plug_init; \ + PLUG_API int sasl_auxprop_plug_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_auxprop_plug_t **plug, \ + const char *plugname) {\ return x##_auxprop_plug_init(utils, maxversion, out_version, \ plug, plugname); \ -} + } #define SASL_CANONUSER_PLUG_INIT( x ) \ -extern sasl_canonuser_init_t x##_canonuser_plug_init; \ -PLUG_API int sasl_canonuser_init(const sasl_utils_t *utils, \ - int maxversion, int *out_version, \ - sasl_canonuser_plug_t **plug, \ - const char *plugname) {\ + extern sasl_canonuser_init_t x##_canonuser_plug_init; \ + PLUG_API int sasl_canonuser_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_canonuser_plug_t **plug, \ + const char *plugname) {\ return x##_canonuser_plug_init(utils, maxversion, out_version, \ - plug, plugname); \ -} + plug, plugname); \ + } /* note: msg cannot include additional variables, so if you want to * do a printf-format string, then you need to call seterror yourself */ @@ -126,8 +126,7 @@ #endif #ifndef SASLINT_H -typedef struct buffer_info -{ +typedef struct buffer_info { char *data; unsigned curlen; /* Current length of data in buffer */ unsigned reallen; /* total length of buffer (>= curlen) */ @@ -139,81 +138,81 @@ #endif int _plug_ipfromstring(const sasl_utils_t *utils, const char *addr, - struct sockaddr *out, socklen_t outlen); + struct sockaddr *out, socklen_t outlen); int _plug_iovec_to_buf(const sasl_utils_t *utils, const struct iovec *vec, - unsigned numiov, buffer_info_t **output); + unsigned numiov, buffer_info_t **output); int _plug_buf_alloc(const sasl_utils_t *utils, char **rwbuf, - unsigned *curlen, unsigned newlen); -int _plug_strdup(const sasl_utils_t * utils, const char *in, - char **out, int *outlen); + unsigned *curlen, unsigned newlen); +int _plug_strdup(const sasl_utils_t *utils, const char *in, + char **out, int *outlen); void _plug_free_string(const sasl_utils_t *utils, char **str); void _plug_free_secret(const sasl_utils_t *utils, sasl_secret_t **secret); #define _plug_get_userid(utils, result, prompt_need) \ - _plug_get_simple(utils, SASL_CB_USER, 0, result, prompt_need) + _plug_get_simple(utils, SASL_CB_USER, 0, result, prompt_need) #define _plug_get_authid(utils, result, prompt_need) \ - _plug_get_simple(utils, SASL_CB_AUTHNAME, 1, result, prompt_need) + _plug_get_simple(utils, SASL_CB_AUTHNAME, 1, result, prompt_need) int _plug_get_simple(const sasl_utils_t *utils, unsigned int id, int required, - const char **result, sasl_interact_t **prompt_need); + const char **result, sasl_interact_t **prompt_need); int _plug_get_password(const sasl_utils_t *utils, sasl_secret_t **secret, - unsigned int *iscopy, sasl_interact_t **prompt_need); + unsigned int *iscopy, sasl_interact_t **prompt_need); int _plug_challenge_prompt(const sasl_utils_t *utils, unsigned int id, - const char *challenge, const char *promptstr, - const char **result, sasl_interact_t **prompt_need); + const char *challenge, const char *promptstr, + const char **result, sasl_interact_t **prompt_need); int _plug_get_realm(const sasl_utils_t *utils, const char **availrealms, - const char **realm, sasl_interact_t **prompt_need); + const char **realm, sasl_interact_t **prompt_need); int _plug_make_prompts(const sasl_utils_t *utils, - sasl_interact_t **prompts_res, - const char *user_prompt, const char *user_def, - const char *auth_prompt, const char *auth_def, - const char *pass_prompt, const char *pass_def, - const char *echo_chal, - const char *echo_prompt, const char *echo_def, - const char *realm_chal, - const char *realm_prompt, const char *realm_def); + sasl_interact_t **prompts_res, + const char *user_prompt, const char *user_def, + const char *auth_prompt, const char *auth_def, + const char *pass_prompt, const char *pass_def, + const char *echo_chal, + const char *echo_prompt, const char *echo_def, + const char *realm_chal, + const char *realm_prompt, const char *realm_def); typedef struct decode_context { const sasl_utils_t *utils; - unsigned int needsize; /* How much of the 4-byte size do we need? */ - char sizebuf[4]; /* Buffer to accumulate the 4-byte size */ - unsigned int size; /* Absolute size of the encoded packet */ - char *buffer; /* Buffer to accumulate an encoded packet */ - unsigned int cursize; /* Amount of packet data in the buffer */ - unsigned int in_maxbuf; /* Maximum allowed size of an incoming encoded packet */ + unsigned int needsize; /* How much of the 4-byte size do we need? */ + char sizebuf[4]; /* Buffer to accumulate the 4-byte size */ + unsigned int size; /* Absolute size of the encoded packet */ + char *buffer; /* Buffer to accumulate an encoded packet */ + unsigned int cursize; /* Amount of packet data in the buffer */ + unsigned int in_maxbuf; /* Maximum allowed size of an incoming encoded packet */ } decode_context_t; void _plug_decode_init(decode_context_t *text, - const sasl_utils_t *utils, unsigned int in_maxbuf); + const sasl_utils_t *utils, unsigned int in_maxbuf); int _plug_decode(decode_context_t *text, - const char *input, unsigned inputlen, - char **output, unsigned *outputsize, unsigned *outputlen, - int (*decode_pkt)(void *rock, - const char *input, unsigned inputlen, - char **output, unsigned *outputlen), - void *rock); + const char *input, unsigned inputlen, + char **output, unsigned *outputsize, unsigned *outputlen, + int (*decode_pkt)(void *rock, + const char *input, unsigned inputlen, + char **output, unsigned *outputlen), + void *rock); void _plug_decode_free(decode_context_t *text); int _plug_parseuser(const sasl_utils_t *utils, - char **user, char **realm, const char *user_realm, - const char *serverFQDN, const char *input); + char **user, char **realm, const char *user_realm, + const char *serverFQDN, const char *input); int _plug_make_fulluser(const sasl_utils_t *utils, - char **fulluser, const char * useronly, const char *realm); + char **fulluser, const char *useronly, const char *realm); -char * _plug_get_error_message (const sasl_utils_t *utils, +char *_plug_get_error_message(const sasl_utils_t *utils, #ifdef WIN32 - DWORD error + DWORD error #else - int error + int error #endif - ); -void _plug_snprintf_os_info (char * osbuf, int osbuf_len); + ); +void _plug_snprintf_os_info(char *osbuf, int osbuf_len); #ifdef __cplusplus } diff -Nru kdepim-runtime-4.14.6/resources/gmail/saslplugin/xoauth2plugin.c kdepim-runtime-15.08.0/resources/gmail/saslplugin/xoauth2plugin.c --- kdepim-runtime-4.14.6/resources/gmail/saslplugin/xoauth2plugin.c 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/saslplugin/xoauth2plugin.c 2015-08-10 21:01:02.000000000 +0000 @@ -42,7 +42,6 @@ static const char plugin_id[] = "$Id: plain.c,v 1.64 2004/09/08 11:06:11 mel Exp $"; - /***************************** Client Section *****************************/ typedef struct client_context { @@ -125,7 +124,7 @@ } /* if there are prompts not filled in */ - if ((auth_result == SASL_INTERACT) ||(token_result == SASL_INTERACT)) { + if ((auth_result == SASL_INTERACT) || (token_result == SASL_INTERACT)) { /* make the prompt list */ result = _plug_make_prompts(utils, prompt_need, @@ -158,11 +157,11 @@ /* https://developers.google.com/gmail/xoauth2_protocol#the_sasl_xoauth2_mechanism */ *clientoutlen = 5 /* user=*/ - + ((authid && *authid) ? strlen(authid) : 0) /* %s */ - + 1 /* \001 */ - + 12 /* auth=Bearer{space} */ - + ((token && *token) ? strlen(token) : 0) /* %s */ - + 2; /* \001\001 */ + + ((authid && *authid) ? strlen(authid) : 0) /* %s */ + + 1 /* \001 */ + + 12 /* auth=Bearer{space} */ + + ((token && *token) ? strlen(token) : 0) /* %s */ + + 2; /* \001\001 */ /* remember the extra NUL on the end for stupid clients */ result = _plug_buf_alloc(params->utils, &(context->out_buf), @@ -203,8 +202,7 @@ utils->free(context); } -static sasl_client_plug_t xoauth2_client_plugins[] = -{ +static sasl_client_plug_t xoauth2_client_plugins[] = { { "XOAUTH2", /* mech_name */ 0, /* max_ssf */ diff -Nru kdepim-runtime-4.14.6/resources/gmail/saslplugin/xoauth2plugin_init.c kdepim-runtime-15.08.0/resources/gmail/saslplugin/xoauth2plugin_init.c --- kdepim-runtime-4.14.6/resources/gmail/saslplugin/xoauth2plugin_init.c 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/gmail/saslplugin/xoauth2plugin_init.c 2015-08-10 21:01:02.000000000 +0000 @@ -39,12 +39,11 @@ #endif #ifdef WIN32 -BOOL APIENTRY DllMain( HANDLE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved) +BOOL APIENTRY DllMain(HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved) { - switch (ul_reason_for_call) - { + switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: @@ -55,4 +54,4 @@ } #endif -SASL_CLIENT_PLUG_INIT( xoauth2 ) +SASL_CLIENT_PLUG_INIT(xoauth2) diff -Nru kdepim-runtime-4.14.6/resources/google/calendar/calendarresource.cpp kdepim-runtime-15.08.0/resources/google/calendar/calendarresource.cpp --- kdepim-runtime-4.14.6/resources/google/calendar/calendarresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/calendar/calendarresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,62 +20,62 @@ #include "settings.h" #include "settingsdialog.h" -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include +#include #include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include +#include #define ROOT_COLLECTION_REMOTEID QLatin1String("RootCollection") #define CALENDARS_PROPERTY "_KGAPI2CalendarPtr" #define TASK_PROPERTY "_KGAPI2::TaskPtr" -Q_DECLARE_METATYPE( KGAPI2::ObjectsList ) -Q_DECLARE_METATYPE( KGAPI2::TaskPtr ) +Q_DECLARE_METATYPE(KGAPI2::ObjectsList) +Q_DECLARE_METATYPE(KGAPI2::TaskPtr) using namespace Akonadi; using namespace KGAPI2; -CalendarResource::CalendarResource( const QString &id ): - GoogleResource( id ) +CalendarResource::CalendarResource(const QString &id): + GoogleResource(id) { AttributeFactory::registerAttribute< DefaultReminderAttribute >(); - KGlobal::locale()->insertCatalog( QLatin1String("akonadi_google_resource") ); updateResourceName(); } @@ -88,18 +88,18 @@ return Settings::self(); } -int CalendarResource::runConfigurationDialog( WId windowId ) +int CalendarResource::runConfigurationDialog(WId windowId) { - QScopedPointer settingsDialog( new SettingsDialog( accountManager(), windowId, this ) ); - settingsDialog->setWindowIcon( KIcon( QLatin1String("im-google") ) ); + QScopedPointer settingsDialog(new SettingsDialog(accountManager(), windowId, this)); + settingsDialog->setWindowIcon(QIcon::fromTheme(QStringLiteral("im-google"))); - return settingsDialog->exec(); + return settingsDialog->exec(); } void CalendarResource::updateResourceName() { const QString accountName = Settings::self()->account(); - setName( i18nc( "%1 is account name (user@gmail.com)", "Google Calendars and Tasks (%1)", accountName.isEmpty() ? i18n( "not configured" ) : accountName ) ); + setName(i18nc("%1 is account name (user@gmail.com)", "Google Calendars and Tasks (%1)", accountName.isEmpty() ? i18n("not configured") : accountName)); } QList< QUrl > CalendarResource::scopes() const @@ -111,423 +111,407 @@ return scopes; } - -void CalendarResource::retrieveItems( const Akonadi::Collection &collection ) +void CalendarResource::retrieveItems(const Akonadi::Collection &collection) { - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } // https://bugs.kde.org/show_bug.cgi?id=308122: we can only request changes in // max. last 25 days, otherwise we get an error. int lastSyncDelta = -1; - if ( !collection.remoteRevision().isEmpty() ) { + if (!collection.remoteRevision().isEmpty()) { lastSyncDelta = QDateTime::currentDateTimeUtc().toTime_t() - collection.remoteRevision().toUInt(); } - KGAPI2::Job *job = 0; - if ( collection.contentMimeTypes().contains( KCalCore::Event::eventMimeType() ) ) { - EventFetchJob *fetchJob = new EventFetchJob( collection.remoteId(), account(), this ); - if ( lastSyncDelta > -1 && lastSyncDelta < 25 * 24 * 3600 ) { - fetchJob->setFetchOnlyUpdated( collection.remoteRevision().toULongLong() ); - } - if ( !Settings::self()->eventsSince().isEmpty() ) { - const QDate date = QDate::fromString( Settings::self()->eventsSince(), Qt::ISODate ); - fetchJob->setTimeMin( QDateTime( date ).toTime_t() ); + KGAPI2::Job *job = Q_NULLPTR; + if (collection.contentMimeTypes().contains(KCalCore::Event::eventMimeType())) { + EventFetchJob *fetchJob = new EventFetchJob(collection.remoteId(), account(), this); + if (lastSyncDelta > -1 && lastSyncDelta < 25 * 24 * 3600) { + fetchJob->setFetchOnlyUpdated(collection.remoteRevision().toULongLong()); + } + if (!Settings::self()->eventsSince().isEmpty()) { + const QDate date = QDate::fromString(Settings::self()->eventsSince(), Qt::ISODate); + fetchJob->setTimeMin(QDateTime(date).toTime_t()); } job = fetchJob; - } else if ( collection.contentMimeTypes().contains( KCalCore::Todo::todoMimeType() ) ) { - TaskFetchJob *fetchJob = new TaskFetchJob( collection.remoteId(), account(), this ); - if ( lastSyncDelta > -1 && lastSyncDelta < 25 * 25 * 3600 ) { - fetchJob->setFetchOnlyUpdated( collection.remoteRevision().toULongLong() ); + } else if (collection.contentMimeTypes().contains(KCalCore::Todo::todoMimeType())) { + TaskFetchJob *fetchJob = new TaskFetchJob(collection.remoteId(), account(), this); + if (lastSyncDelta > -1 && lastSyncDelta < 25 * 25 * 3600) { + fetchJob->setFetchOnlyUpdated(collection.remoteRevision().toULongLong()); } job = fetchJob; } else { - itemsRetrieved( Item::List() ); + itemsRetrieved(Item::List()); return; } - job->setProperty( COLLECTION_PROPERTY, QVariant::fromValue( collection ) ); - connect( job, SIGNAL(progress(KGAPI2::Job*,int,int)), - this, SLOT(emitPercent(KGAPI2::Job*,int,int)) ); - connect( job, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotItemsRetrieved(KGAPI2::Job*)) ); + job->setProperty(COLLECTION_PROPERTY, QVariant::fromValue(collection)); + connect(job, &KGAPI2::Job::progress, this, &CalendarResource::emitPercent); + connect(job, &KGAPI2::Job::finished, this, &CalendarResource::slotItemsRetrieved); } void CalendarResource::retrieveCollections() { - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } - CalendarFetchJob *fetchJob = new CalendarFetchJob( account(), this ); - connect( fetchJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotCalendarsRetrieved(KGAPI2::Job*)) ); + CalendarFetchJob *fetchJob = new CalendarFetchJob(account(), this); + connect(fetchJob, &EventFetchJob::finished, this, &CalendarResource::slotCalendarsRetrieved); } -void CalendarResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ) +void CalendarResource::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) { - if ( ( !collection.contentMimeTypes().contains( KCalCore::Event::eventMimeType() ) && - !collection.contentMimeTypes().contains( KCalCore::Todo::todoMimeType() ) ) || - ( !canPerformTask( item, KCalCore::Event::eventMimeType() ) && - !canPerformTask( item, KCalCore::Todo::todoMimeType() ) ) ) { + if ((!collection.contentMimeTypes().contains(KCalCore::Event::eventMimeType()) && + !collection.contentMimeTypes().contains(KCalCore::Todo::todoMimeType())) || + (!canPerformTask(item, KCalCore::Event::eventMimeType()) && + !canPerformTask(item, KCalCore::Todo::todoMimeType()))) { return; } - if ( collection.parentCollection() == Akonadi::Collection::root() ) { - cancelTask( i18n( "The top-level collection cannot contain any tasks or events" ) ); + if (collection.parentCollection() == Akonadi::Collection::root()) { + cancelTask(i18n("The top-level collection cannot contain any tasks or events")); return; } - KGAPI2::Job *job = 0; - if ( item.hasPayload() ) { + KGAPI2::Job *job = Q_NULLPTR; + if (item.hasPayload()) { KCalCore::Event::Ptr event = item.payload(); - EventPtr kevent( new Event( *event ) ); - kevent->setUid( QLatin1String("") ); + EventPtr kevent(new Event(*event)); + kevent->setUid(QLatin1String("")); - job = new EventCreateJob( kevent, collection.remoteId(), account(), this ); + job = new EventCreateJob(kevent, collection.remoteId(), account(), this); - } else if ( item.hasPayload() ) { + } else if (item.hasPayload()) { KCalCore::Todo::Ptr todo = item.payload(); - TaskPtr ktodo( new Task( *todo ) ); - ktodo->setUid( QLatin1String("") ); + TaskPtr ktodo(new Task(*todo)); + ktodo->setUid(QLatin1String("")); - if ( !ktodo->relatedTo( KCalCore::Incidence::RelTypeParent ).isEmpty() ) { + if (!ktodo->relatedTo(KCalCore::Incidence::RelTypeParent).isEmpty()) { Akonadi::Item parentItem; - parentItem.setGid( ktodo->relatedTo( KCalCore::Incidence::RelTypeParent ) ); + parentItem.setGid(ktodo->relatedTo(KCalCore::Incidence::RelTypeParent)); - ItemFetchJob *fetchJob = new ItemFetchJob( parentItem, this ); - fetchJob->setProperty( ITEM_PROPERTY, QVariant::fromValue( item ) ); - fetchJob->setProperty( TASK_PROPERTY, QVariant::fromValue( ktodo ) ); + ItemFetchJob *fetchJob = new ItemFetchJob(parentItem, this); + fetchJob->setProperty(ITEM_PROPERTY, QVariant::fromValue(item)); + fetchJob->setProperty(TASK_PROPERTY, QVariant::fromValue(ktodo)); - connect( fetchJob, SIGNAL(finished(KJob*)), - this, SLOT(slotTaskAddedSearchFinished(KJob*)) ); + connect(fetchJob, &ItemFetchJob::finished, this, &CalendarResource::slotTaskAddedSearchFinished); return; } else { - job = new TaskCreateJob( ktodo, collection.remoteId(), account(), this ); + job = new TaskCreateJob(ktodo, collection.remoteId(), account(), this); } } else { - cancelTask( i18n( "Invalid payload type" ) ); + cancelTask(i18n("Invalid payload type")); return; } - job->setProperty( ITEM_PROPERTY, QVariant::fromValue( item ) ); - connect( job, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotCreateJobFinished(KGAPI2::Job*)) ); + job->setProperty(ITEM_PROPERTY, QVariant::fromValue(item)); + connect(job, &EventCreateJob::finished, this, &CalendarResource::slotCreateJobFinished); } -void CalendarResource::itemChanged( const Akonadi::Item &item, - const QSet< QByteArray > &partIdentifiers ) +void CalendarResource::itemChanged(const Akonadi::Item &item, + const QSet< QByteArray > &partIdentifiers) { - Q_UNUSED( partIdentifiers ); + Q_UNUSED(partIdentifiers); - if ( !canPerformTask( item, KCalCore::Event::eventMimeType() ) && - !canPerformTask( item, KCalCore::Todo::todoMimeType() ) ) { + if (!canPerformTask(item, KCalCore::Event::eventMimeType()) && + !canPerformTask(item, KCalCore::Todo::todoMimeType())) { return; } - KGAPI2::Job *job = 0; - if ( item.hasPayload() ) { + KGAPI2::Job *job = Q_NULLPTR; + if (item.hasPayload()) { KCalCore::Event::Ptr event = item.payload(); - EventPtr kevent( new Event( *event ) ); - kevent->setUid( item.remoteId() ); + EventPtr kevent(new Event(*event)); + kevent->setUid(item.remoteId()); - job = new EventModifyJob( kevent, item.parentCollection().remoteId(), account(), this ); - connect( job, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + job = new EventModifyJob(kevent, item.parentCollection().remoteId(), account(), this); + connect(job, &EventCreateJob::finished, this, &CalendarResource::slotGenericJobFinished); - } else if ( item.hasPayload() ) { + } else if (item.hasPayload()) { KCalCore::Todo::Ptr todo = item.payload(); - TaskPtr ktodo( new Task( *todo ) ); - QString parentUid = todo->relatedTo( KCalCore::Incidence::RelTypeParent ); - job = new TaskMoveJob( item.remoteId(), item.parentCollection().remoteId(), parentUid, account(), this ); - job->setProperty( ITEM_PROPERTY, QVariant::fromValue( item ) ); - connect( job, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotModifyTaskReparentFinished(KGAPI2::Job*)) ); + TaskPtr ktodo(new Task(*todo)); + QString parentUid = todo->relatedTo(KCalCore::Incidence::RelTypeParent); + job = new TaskMoveJob(item.remoteId(), item.parentCollection().remoteId(), parentUid, account(), this); + job->setProperty(ITEM_PROPERTY, QVariant::fromValue(item)); + connect(job, &EventCreateJob::finished, this, &CalendarResource::slotModifyTaskReparentFinished); } else { - cancelTask( i18n( "Invalid payload type" ) ); + cancelTask(i18n("Invalid payload type")); return; } - job->setProperty( ITEM_PROPERTY, QVariant::fromValue( item ) ); + job->setProperty(ITEM_PROPERTY, QVariant::fromValue(item)); } -void CalendarResource::itemRemoved( const Akonadi::Item &item ) +void CalendarResource::itemRemoved(const Akonadi::Item &item) { - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } - if ( item.mimeType() == KCalCore::Event::eventMimeType() ) { - KGAPI2::Job *job = new EventDeleteJob( item.remoteId(), item.parentCollection().remoteId(), account(), this ); - job->setProperty( ITEM_PROPERTY, QVariant::fromValue( item ) ); - connect( job, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + if (item.mimeType() == KCalCore::Event::eventMimeType()) { + KGAPI2::Job *job = new EventDeleteJob(item.remoteId(), item.parentCollection().remoteId(), account(), this); + job->setProperty(ITEM_PROPERTY, QVariant::fromValue(item)); + connect(job, &EventCreateJob::finished, this, &CalendarResource::slotGenericJobFinished); - } else if ( item.mimeType() == KCalCore::Todo::todoMimeType() ) { + } else if (item.mimeType() == KCalCore::Todo::todoMimeType()) { /* Google always automatically removes tasks with all their subtasks. In KOrganizer * by default we only remove the item we are given. For this reason we have to first * fetch all tasks, find all sub-tasks for the task being removed and detach them * from the task. Only then the task can be safely removed. */ - ItemFetchJob *fetchJob = new ItemFetchJob( item.parentCollection() ); - fetchJob->setAutoDelete( true ); - fetchJob->fetchScope().fetchFullPayload( true ); - fetchJob->setProperty( ITEM_PROPERTY, qVariantFromValue( item ) ); - connect( fetchJob, SIGNAL(finished(KJob*)), - this, SLOT(slotRemoveTaskFetchJobFinished(KJob*)) ); + ItemFetchJob *fetchJob = new ItemFetchJob(item.parentCollection()); + fetchJob->setAutoDelete(true); + fetchJob->fetchScope().fetchFullPayload(true); + fetchJob->setProperty(ITEM_PROPERTY, qVariantFromValue(item)); + connect(fetchJob, &ItemFetchJob::finished, this, &CalendarResource::slotRemoveTaskFetchJobFinished); fetchJob->start(); } else { - cancelTask( i18n( "Invalid payload type. Expected event or todo, got %1", item.mimeType() ) ); + cancelTask(i18n("Invalid payload type. Expected event or todo, got %1", item.mimeType())); } } -void CalendarResource::itemMoved( const Item &item, - const Collection &collectionSource, - const Collection &collectionDestination ) +void CalendarResource::itemMoved(const Item &item, + const Collection &collectionSource, + const Collection &collectionDestination) { - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } - if ( collectionDestination.parentCollection() == Akonadi::Collection::root() ) { - cancelTask( i18n( "The top-level collection cannot contain any tasks or events" ) ); + if (collectionDestination.parentCollection() == Akonadi::Collection::root()) { + cancelTask(i18n("The top-level collection cannot contain any tasks or events")); return; } - if ( item.mimeType() != KCalCore::Event::eventMimeType() ) { - cancelTask( i18n( "Moving tasks between task lists is not supported" ) ); + if (item.mimeType() != KCalCore::Event::eventMimeType()) { + cancelTask(i18n("Moving tasks between task lists is not supported")); return; } - KGAPI2::Job *job = new EventMoveJob( item.remoteId(), collectionSource.remoteId(), - collectionDestination.remoteId(), account(), - this ); - job->setProperty( ITEM_PROPERTY, QVariant::fromValue( item ) ); - connect( job, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + KGAPI2::Job *job = new EventMoveJob(item.remoteId(), collectionSource.remoteId(), + collectionDestination.remoteId(), account(), + this); + job->setProperty(ITEM_PROPERTY, QVariant::fromValue(item)); + connect(job, &EventCreateJob::finished, this, &CalendarResource::slotGenericJobFinished); } -void CalendarResource::collectionAdded( const Collection &collection, const Collection &parent ) +void CalendarResource::collectionAdded(const Collection &collection, const Collection &parent) { - Q_UNUSED( parent ) + Q_UNUSED(parent) - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } KGAPI2::Job *job; - if ( collection.contentMimeTypes().contains( KCalCore::Event::eventMimeType() ) ) { - CalendarPtr calendar( new Calendar() ); - calendar->setTitle( collection.displayName() ); - calendar->setEditable( true ); - job = new CalendarCreateJob( calendar, account(), this ); - - } if ( collection.contentMimeTypes().contains( KCalCore::Todo::todoMimeType() ) ) { - TaskListPtr taskList( new TaskList() ); - taskList->setTitle( collection.displayName() ); + if (collection.contentMimeTypes().contains(KCalCore::Event::eventMimeType())) { + CalendarPtr calendar(new Calendar()); + calendar->setTitle(collection.displayName()); + calendar->setEditable(true); + job = new CalendarCreateJob(calendar, account(), this); + + } if (collection.contentMimeTypes().contains(KCalCore::Todo::todoMimeType())) { + TaskListPtr taskList(new TaskList()); + taskList->setTitle(collection.displayName()); - job = new TaskListCreateJob( taskList, account(), this ); + job = new TaskListCreateJob(taskList, account(), this); } else { - cancelTask( i18n( "Unknown collection mimetype" ) ); + cancelTask(i18n("Unknown collection mimetype")); return; } - job->setProperty( COLLECTION_PROPERTY, QVariant::fromValue( collection ) ); - connect( job, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + job->setProperty(COLLECTION_PROPERTY, QVariant::fromValue(collection)); + connect(job, &KGAPI2::Job::finished, this, &CalendarResource::slotGenericJobFinished); } -void CalendarResource::collectionChanged( const Collection &collection ) +void CalendarResource::collectionChanged(const Collection &collection) { - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } KGAPI2::Job *job; - if ( collection.contentMimeTypes().contains( KCalCore::Event::eventMimeType() ) ) { - CalendarPtr calendar( new Calendar() ); - calendar->setUid( collection.remoteId() ); - calendar->setTitle( collection.displayName() ); - calendar->setEditable( true ); - job = new CalendarModifyJob( calendar, account(), this ); - - } if ( collection.contentMimeTypes().contains( KCalCore::Todo::todoMimeType() ) ) { - TaskListPtr taskList( new TaskList() ); - taskList->setUid( collection.remoteId() ); - taskList->setTitle( collection.displayName() ); - job = new TaskListModifyJob( taskList, account(), this ); + if (collection.contentMimeTypes().contains(KCalCore::Event::eventMimeType())) { + CalendarPtr calendar(new Calendar()); + calendar->setUid(collection.remoteId()); + calendar->setTitle(collection.displayName()); + calendar->setEditable(true); + job = new CalendarModifyJob(calendar, account(), this); + + } if (collection.contentMimeTypes().contains(KCalCore::Todo::todoMimeType())) { + TaskListPtr taskList(new TaskList()); + taskList->setUid(collection.remoteId()); + taskList->setTitle(collection.displayName()); + job = new TaskListModifyJob(taskList, account(), this); } else { - cancelTask( i18n( "Unknown collection mimetype" ) ); + cancelTask(i18n("Unknown collection mimetype")); return; } - job->setProperty( COLLECTION_PROPERTY, QVariant::fromValue( collection ) ); - connect( job, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + job->setProperty(COLLECTION_PROPERTY, QVariant::fromValue(collection)); + connect(job, &KGAPI2::Job::finished, this, &CalendarResource::slotGenericJobFinished); } -void CalendarResource::collectionRemoved( const Collection &collection ) +void CalendarResource::collectionRemoved(const Collection &collection) { - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } KGAPI2::Job *job; - if ( collection.contentMimeTypes().contains( KCalCore::Event::eventMimeType() ) ) { - job = new CalendarDeleteJob( collection.remoteId(), account(), this ); + if (collection.contentMimeTypes().contains(KCalCore::Event::eventMimeType())) { + job = new CalendarDeleteJob(collection.remoteId(), account(), this); - } if ( collection.contentMimeTypes().contains( KCalCore::Todo::todoMimeType() ) ) { - job = new TaskListDeleteJob( collection.remoteId(), account(), this ); + } if (collection.contentMimeTypes().contains(KCalCore::Todo::todoMimeType())) { + job = new TaskListDeleteJob(collection.remoteId(), account(), this); } else { - cancelTask( i18n( "Unknown collection mimetype" ) ); + cancelTask(i18n("Unknown collection mimetype")); return; } - job->setProperty( COLLECTION_PROPERTY, QVariant::fromValue( collection ) ); - connect( job, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + job->setProperty(COLLECTION_PROPERTY, QVariant::fromValue(collection)); + connect(job, &KGAPI2::Job::finished, this, &CalendarResource::slotGenericJobFinished); } -void CalendarResource::slotCalendarsRetrieved( KGAPI2::Job *job ) +void CalendarResource::slotCalendarsRetrieved(KGAPI2::Job *job) { - if ( !handleError( job ) ) { + if (!handleError(job)) { return; } - CalendarFetchJob *calendarJob = qobject_cast(job); + CalendarFetchJob *calendarJob = qobject_cast(job); ObjectsList objects = calendarJob->items(); calendarJob->deleteLater(); - TaskListFetchJob *fetchJob = new TaskListFetchJob( job->account(), this ); - fetchJob->setProperty( CALENDARS_PROPERTY, QVariant::fromValue( objects ) ); - connect( fetchJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotCollectionsRetrieved(KGAPI2::Job*)) ); + TaskListFetchJob *fetchJob = new TaskListFetchJob(job->account(), this); + fetchJob->setProperty(CALENDARS_PROPERTY, QVariant::fromValue(objects)); + connect(fetchJob, &EventFetchJob::finished, this, &CalendarResource::slotCollectionsRetrieved); } - -void CalendarResource::slotCollectionsRetrieved( KGAPI2::Job *job ) +void CalendarResource::slotCollectionsRetrieved(KGAPI2::Job *job) { - if ( !handleError( job ) ) { + if (!handleError(job)) { return; } - TaskListFetchJob *fetchJob = qobject_cast( job ); - ObjectsList calendars = fetchJob->property( CALENDARS_PROPERTY ).value(); + TaskListFetchJob *fetchJob = qobject_cast(job); + ObjectsList calendars = fetchJob->property(CALENDARS_PROPERTY).value(); ObjectsList taskLists = fetchJob->items(); CachePolicy cachePolicy; - if ( Settings::self()->enableIntervalCheck() ) { - cachePolicy.setInheritFromParent( false ); - cachePolicy.setIntervalCheckTime( Settings::self()->intervalCheckTime() ); + if (Settings::self()->enableIntervalCheck()) { + cachePolicy.setInheritFromParent(false); + cachePolicy.setIntervalCheckTime(Settings::self()->intervalCheckTime()); } m_rootCollection = Collection(); - m_rootCollection.setContentMimeTypes( QStringList() << Collection::mimeType() ); - m_rootCollection.setRemoteId( ROOT_COLLECTION_REMOTEID ); - m_rootCollection.setName( fetchJob->account()->accountName() ); - m_rootCollection.setParentCollection( Collection::root() ); - m_rootCollection.setRights( Collection::CanCreateCollection ); - m_rootCollection.setCachePolicy( cachePolicy ); - - EntityDisplayAttribute *attr = m_rootCollection.attribute( Entity::AddIfMissing ); - attr->setDisplayName( fetchJob->account()->accountName() ); - attr->setIconName( QLatin1String( "im-google" ) ); + m_rootCollection.setContentMimeTypes(QStringList() << Collection::mimeType()); + m_rootCollection.setRemoteId(ROOT_COLLECTION_REMOTEID); + m_rootCollection.setName(fetchJob->account()->accountName()); + m_rootCollection.setParentCollection(Collection::root()); + m_rootCollection.setRights(Collection::CanCreateCollection); + m_rootCollection.setCachePolicy(cachePolicy); + + EntityDisplayAttribute *attr = m_rootCollection.attribute(Entity::AddIfMissing); + attr->setDisplayName(fetchJob->account()->accountName()); + attr->setIconName(QStringLiteral("im-google")); m_collections[ ROOT_COLLECTION_REMOTEID ] = m_rootCollection; const QStringList activeCalendars = Settings::self()->calendars(); - Q_FOREACH( const ObjectPtr &object, calendars ) { + Q_FOREACH (const ObjectPtr &object, calendars) { const CalendarPtr &calendar = object.dynamicCast(); - if ( !activeCalendars.contains( calendar->uid() ) ) { + if (!activeCalendars.contains(calendar->uid())) { continue; } Collection collection; - collection.setContentMimeTypes( QStringList() << KCalCore::Event::eventMimeType() ); - collection.setName( calendar->uid() ); - collection.setParentCollection( m_rootCollection ); - collection.setRemoteId( calendar->uid() ); - if ( calendar->editable() ) { - collection.setRights( Collection::CanChangeCollection | - Collection::CanCreateItem | - Collection::CanChangeItem | - Collection::CanDeleteItem ); + collection.setContentMimeTypes(QStringList() << KCalCore::Event::eventMimeType()); + collection.setName(calendar->uid()); + collection.setParentCollection(m_rootCollection); + collection.setRemoteId(calendar->uid()); + if (calendar->editable()) { + collection.setRights(Collection::CanChangeCollection | + Collection::CanCreateItem | + Collection::CanChangeItem | + Collection::CanDeleteItem); } else { - collection.setRights( 0 ); + collection.setRights(Q_NULLPTR); } - EntityDisplayAttribute *attr = collection.attribute( Entity::AddIfMissing ); - attr->setDisplayName( calendar->title() ); - attr->setIconName( QLatin1String("view-calendar") ); + EntityDisplayAttribute *attr = collection.attribute(Entity::AddIfMissing); + attr->setDisplayName(calendar->title()); + attr->setIconName(QLatin1String("view-calendar")); - DefaultReminderAttribute *reminderAttr = collection.attribute( Entity::AddIfMissing ); - reminderAttr->setReminders( calendar->defaultReminders() ); + DefaultReminderAttribute *reminderAttr = collection.attribute(Entity::AddIfMissing); + reminderAttr->setReminders(calendar->defaultReminders()); // Block email reminders, since Google sends them for us - BlockAlarmsAttribute *blockAlarms = collection.attribute( Entity::AddIfMissing ); - blockAlarms->blockAlarmType( KCalCore::Alarm::Audio, false ); - blockAlarms->blockAlarmType( KCalCore::Alarm::Display, false ); - blockAlarms->blockAlarmType( KCalCore::Alarm::Procedure, false ); + BlockAlarmsAttribute *blockAlarms = collection.attribute(Entity::AddIfMissing); + blockAlarms->blockAlarmType(KCalCore::Alarm::Audio, false); + blockAlarms->blockAlarmType(KCalCore::Alarm::Display, false); + blockAlarms->blockAlarmType(KCalCore::Alarm::Procedure, false); m_collections[ collection.remoteId() ] = collection; } const QStringList activeTaskLists = Settings::self()->taskLists(); - Q_FOREACH( const ObjectPtr &object, taskLists ) { + Q_FOREACH (const ObjectPtr &object, taskLists) { const TaskListPtr &taskList = object.dynamicCast(); - if ( !activeTaskLists.contains( taskList->uid() ) ) { + if (!activeTaskLists.contains(taskList->uid())) { continue; } Collection collection; - collection.setContentMimeTypes( QStringList() << KCalCore::Todo::todoMimeType() ); - collection.setName( taskList->uid() ); - collection.setParentCollection( m_rootCollection ); - collection.setRemoteId( taskList->uid() ); - collection.setRights( Collection::CanChangeCollection | - Collection::CanCreateItem | - Collection::CanChangeItem | - Collection::CanDeleteItem ); - - EntityDisplayAttribute *attr = collection.attribute( Entity::AddIfMissing ); - attr->setDisplayName( taskList->title() ); - attr->setIconName( QLatin1String("view-pim-tasks") ); + collection.setContentMimeTypes(QStringList() << KCalCore::Todo::todoMimeType()); + collection.setName(taskList->uid()); + collection.setParentCollection(m_rootCollection); + collection.setRemoteId(taskList->uid()); + collection.setRights(Collection::CanChangeCollection | + Collection::CanCreateItem | + Collection::CanChangeItem | + Collection::CanDeleteItem); + + EntityDisplayAttribute *attr = collection.attribute(Entity::AddIfMissing); + attr->setDisplayName(taskList->title()); + attr->setIconName(QStringLiteral("view-pim-tasks")); m_collections[ collection.remoteId() ] = collection; } - collectionsRetrieved( m_collections.values() ); + collectionsRetrieved(Akonadi::valuesToVector(m_collections)); job->deleteLater(); } -void CalendarResource::slotItemsRetrieved( KGAPI2::Job *job ) +void CalendarResource::slotItemsRetrieved(KGAPI2::Job *job) { - if ( !handleError( job ) ) { + if (!handleError(job)) { return; } Item::List changedItems, removedItems; - Collection collection = job->property( COLLECTION_PROPERTY ).value(); + Collection collection = job->property(COLLECTION_PROPERTY).value(); DefaultReminderAttribute *attr = collection.attribute(); bool isIncremental = false; - ObjectsList objects = qobject_cast( job )->items(); - if ( collection.contentMimeTypes().contains( KCalCore::Event::eventMimeType() ) ) { + ObjectsList objects = qobject_cast(job)->items(); + if (collection.contentMimeTypes().contains(KCalCore::Event::eventMimeType())) { QMap< QString, EventPtr > recurrentEvents; - isIncremental = ( qobject_cast( job )->fetchOnlyUpdated() > 0 ); + isIncremental = (qobject_cast(job)->fetchOnlyUpdated() > 0); /* Step 1: Find all recurrent events and move them to a separate map */ int i = 0; while (i < objects.length()) { EventPtr event = objects.at(i).dynamicCast(); - if ( event->recurs() && !event->deleted() ) { - recurrentEvents.insert( event->uid(), event ); + if (event->recurs() && !event->deleted()) { + recurrentEvents.insert(event->uid(), event); objects.removeAt(i); } else { i++; @@ -535,33 +519,33 @@ } /* Step 2: Process all remaining events */ - Q_FOREACH( const ObjectPtr &object, objects ) { + Q_FOREACH (const ObjectPtr &object, objects) { EventPtr event = object.dynamicCast(); /* If current event is related to a recurrent event stored in the map then * take the original recurrent event, set date of the current event as an * exception and continue. We will process content of the map later. */ - if ( recurrentEvents.contains( event->uid() ) ) { - EventPtr rEvent = recurrentEvents.value( event->uid() ); - rEvent->recurrence()->addExDate( event->dtStart().date() ); + if (recurrentEvents.contains(event->uid())) { + EventPtr rEvent = recurrentEvents.value(event->uid()); + rEvent->recurrence()->addExDate(event->dtStart().date()); continue; } - if ( event->useDefaultReminders() && attr ) { - KCalCore::Alarm::List alarms = attr->alarms( event.data() ); - Q_FOREACH ( KCalCore::Alarm::Ptr alarm, alarms ) { - event->addAlarm( alarm ); + if (event->useDefaultReminders() && attr) { + KCalCore::Alarm::List alarms = attr->alarms(event.data()); + Q_FOREACH (const KCalCore::Alarm::Ptr &alarm, alarms) { + event->addAlarm(alarm); } } Item item; - item.setMimeType( KCalCore::Event::eventMimeType() ); - item.setParentCollection( collection ); - item.setRemoteId( event->uid() ); - item.setRemoteRevision( event->etag() ); - item.setPayload( event.dynamicCast() ); + item.setMimeType(KCalCore::Event::eventMimeType()); + item.setParentCollection(collection); + item.setRemoteId(event->uid()); + item.setRemoteRevision(event->etag()); + item.setPayload(event.dynamicCast()); - if ( event->deleted() ) { + if (event->deleted()) { removedItems << item; } else { changedItems << item; @@ -569,33 +553,33 @@ } /* Step 3: Now process the recurrent events */ - Q_FOREACH ( const EventPtr &event, recurrentEvents.values() ) { + Q_FOREACH (const EventPtr &event, recurrentEvents) { Item item; - item.setRemoteId( event->uid() ); - item.setRemoteRevision( event->etag() ); - item.setPayload< KCalCore::Event::Ptr >( event.dynamicCast() ); - item.setMimeType( KCalCore::Event::eventMimeType() ); - item.setParentCollection( collection ); + item.setRemoteId(event->uid()); + item.setRemoteRevision(event->etag()); + item.setPayload< KCalCore::Event::Ptr >(event.dynamicCast()); + item.setMimeType(KCalCore::Event::eventMimeType()); + item.setParentCollection(collection); changedItems << item; } - } else if ( collection.contentMimeTypes().contains( KCalCore::Todo::todoMimeType() ) ) { + } else if (collection.contentMimeTypes().contains(KCalCore::Todo::todoMimeType())) { - isIncremental = ( qobject_cast( job )->fetchOnlyUpdated() > 0 ); + isIncremental = (qobject_cast(job)->fetchOnlyUpdated() > 0); - Q_FOREACH( const ObjectPtr &object, objects ) { + Q_FOREACH (const ObjectPtr &object, objects) { TaskPtr task = object.dynamicCast(); Item item; - item.setMimeType( KCalCore::Todo::todoMimeType() ); - item.setParentCollection( collection ); - item.setRemoteId( task->uid() ); - item.setRemoteRevision( task->etag() ); - item.setPayload( task.dynamicCast() ); + item.setMimeType(KCalCore::Todo::todoMimeType()); + item.setParentCollection(collection); + item.setRemoteId(task->uid()); + item.setRemoteRevision(task->etag()); + item.setPayload(task.dynamicCast()); - if ( task->deleted() ) { + if (task->deleted()) { removedItems << item; } else { changedItems << item; @@ -603,164 +587,159 @@ } } - if ( isIncremental ) { - itemsRetrievedIncremental( changedItems, removedItems ); + if (isIncremental) { + itemsRetrievedIncremental(changedItems, removedItems); } else { - itemsRetrieved( changedItems ); + itemsRetrieved(changedItems); } - collection.setRemoteRevision( QString::number( KDateTime::currentUtcDateTime().toTime_t() ) ); - new CollectionModifyJob( collection, this ); + collection.setRemoteRevision(QString::number(KDateTime::currentUtcDateTime().toTime_t())); + new CollectionModifyJob(collection, this); job->deleteLater(); } -void CalendarResource::slotModifyTaskReparentFinished( KGAPI2::Job *job ) +void CalendarResource::slotModifyTaskReparentFinished(KGAPI2::Job *job) { - if ( !handleError( job ) ) { + if (!handleError(job)) { return; } - Item item = job->property( ITEM_PROPERTY ).value(); + Item item = job->property(ITEM_PROPERTY).value(); KCalCore::Todo::Ptr todo = item.payload(); - TaskPtr ktodo( new Task( *todo.data() ) ); + TaskPtr ktodo(new Task(*todo.data())); - job = new TaskModifyJob( ktodo, item.parentCollection().remoteId(), job->account(), this ); - job->setProperty( ITEM_PROPERTY, QVariant::fromValue( item ) ); - connect( job, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + job = new TaskModifyJob(ktodo, item.parentCollection().remoteId(), job->account(), this); + job->setProperty(ITEM_PROPERTY, QVariant::fromValue(item)); + connect(job, &KGAPI2::Job::finished, this, &CalendarResource::slotGenericJobFinished); } -void CalendarResource::slotRemoveTaskFetchJobFinished( KJob *job ) +void CalendarResource::slotRemoveTaskFetchJobFinished(KJob *job) { - if ( job->error() ) { - cancelTask( i18n( "Failed to delete task: %1", job->errorString() ) ); + if (job->error()) { + cancelTask(i18n("Failed to delete task: %1", job->errorString())); return; } - ItemFetchJob *fetchJob = qobject_cast( job ); - Item removedItem = fetchJob->property( ITEM_PROPERTY ).value(); + ItemFetchJob *fetchJob = qobject_cast(job); + Item removedItem = fetchJob->property(ITEM_PROPERTY).value(); Item::List detachItems; Item::List items = fetchJob->items(); - Q_FOREACH ( Item item, items ) { //krazy:exclude=foreach - if( !item.hasPayload() ) { - kDebug() << "Item " << item.remoteId() << " does not have Todo payload"; + Q_FOREACH (Item item, items) { //krazy:exclude=foreach + if (!item.hasPayload()) { + qDebug() << "Item " << item.remoteId() << " does not have Todo payload"; continue; } KCalCore::Todo::Ptr todo = item.payload(); /* If this item is child of the item we want to remove then add it to detach list */ - if ( todo->relatedTo( KCalCore::Incidence::RelTypeParent ) == removedItem.remoteId() ) { - todo->setRelatedTo( QString(), KCalCore::Incidence::RelTypeParent ); - item.setPayload( todo ); + if (todo->relatedTo(KCalCore::Incidence::RelTypeParent) == removedItem.remoteId()) { + todo->setRelatedTo(QString(), KCalCore::Incidence::RelTypeParent); + item.setPayload(todo); detachItems << item; } } /* If there are no items do detach, then delete the task right now */ - if ( detachItems.isEmpty() ) { - slotDoRemoveTask( job ); + if (detachItems.isEmpty()) { + slotDoRemoveTask(job); return; } /* Send modify request to detach all the sub-tasks from the task that is about to be * removed. */ - ItemModifyJob *modifyJob = new ItemModifyJob( detachItems ); - modifyJob->setProperty( ITEM_PROPERTY, QVariant::fromValue( removedItem ) ); - modifyJob->setAutoDelete( true ); - connect( modifyJob, SIGNAL(finished(KJob*)), - this, SLOT(slotDoRemoveTask(KJob*)) ); + ItemModifyJob *modifyJob = new ItemModifyJob(detachItems); + modifyJob->setProperty(ITEM_PROPERTY, QVariant::fromValue(removedItem)); + modifyJob->setAutoDelete(true); + connect(modifyJob, &ItemModifyJob::finished, this, &CalendarResource::slotDoRemoveTask); } -void CalendarResource::slotDoRemoveTask( KJob *job ) +void CalendarResource::slotDoRemoveTask(KJob *job) { - if ( job->error() ) { - cancelTask( i18n( "Failed to delete task: %1", job->errorString() ) ); + if (job->error()) { + cancelTask(i18n("Failed to delete task: %1", job->errorString())); return; } // Make sure account is still valid - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } - Item item = job->property( ITEM_PROPERTY ).value< Item >(); + Item item = job->property(ITEM_PROPERTY).value< Item >(); /* Now finally we can safely remove the task we wanted to */ - TaskDeleteJob *deleteJob = new TaskDeleteJob( item.remoteId(), item.parentCollection().remoteId(), account(), this); - deleteJob->setProperty( ITEM_PROPERTY, QVariant::fromValue( item ) ); - connect( deleteJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + TaskDeleteJob *deleteJob = new TaskDeleteJob(item.remoteId(), item.parentCollection().remoteId(), account(), this); + deleteJob->setProperty(ITEM_PROPERTY, QVariant::fromValue(item)); + connect(deleteJob, &TaskDeleteJob::finished, this, &CalendarResource::slotGenericJobFinished); } -void CalendarResource::slotTaskAddedSearchFinished( KJob *job ) +void CalendarResource::slotTaskAddedSearchFinished(KJob *job) { - ItemFetchJob *fetchJob = qobject_cast( job ); - Item item = job->property( ITEM_PROPERTY ).value(); - TaskPtr task = job->property( TASK_PROPERTY ).value(); + ItemFetchJob *fetchJob = qobject_cast(job); + Item item = job->property(ITEM_PROPERTY).value(); + TaskPtr task = job->property(TASK_PROPERTY).value(); Item::List items = fetchJob->items(); - kDebug() << "Parent query returned" << items.count() << "results"; + qDebug() << "Parent query returned" << items.count() << "results"; const QString tasksListId = item.parentCollection().remoteId(); // Make sure account is still valid - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } KGAPI2::Job *newJob; // The parent is not known, so give up and just store the item in Google // without the information about parent. - if ( items.count() == 0 ) { - task->setRelatedTo( QString(), KCalCore::Incidence::RelTypeParent ); - newJob = new TaskCreateJob( task, tasksListId, account(), this ); + if (items.count() == 0) { + task->setRelatedTo(QString(), KCalCore::Incidence::RelTypeParent); + newJob = new TaskCreateJob(task, tasksListId, account(), this); } else { Item matchedItem = items.first(); - task->setRelatedTo( matchedItem.remoteId(), KCalCore::Incidence::RelTypeParent ); - TaskCreateJob *createJob = new TaskCreateJob( task, tasksListId, account(), this ); - createJob->setParentItem( matchedItem.remoteId() ); + task->setRelatedTo(matchedItem.remoteId(), KCalCore::Incidence::RelTypeParent); + TaskCreateJob *createJob = new TaskCreateJob(task, tasksListId, account(), this); + createJob->setParentItem(matchedItem.remoteId()); newJob = createJob; } - newJob->setProperty( ITEM_PROPERTY, QVariant::fromValue( item ) ); - connect( newJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotCreateJobFinished(KGAPI2::Job*)) ); + newJob->setProperty(ITEM_PROPERTY, QVariant::fromValue(item)); + connect(newJob, &KGAPI2::Job::finished, this, &CalendarResource::slotCreateJobFinished); } - -void CalendarResource::slotCreateJobFinished( KGAPI2::Job *job ) +void CalendarResource::slotCreateJobFinished(KGAPI2::Job *job) { - if ( !handleError( job ) ) { + if (!handleError(job)) { return; } - Item item = job->property( ITEM_PROPERTY ).value(); + Item item = job->property(ITEM_PROPERTY).value(); - CreateJob *createJob = qobject_cast(job); + CreateJob *createJob = qobject_cast(job); ObjectsList objects = createJob->items(); - Q_ASSERT( objects.count() > 0 ); + Q_ASSERT(objects.count() > 0); - if ( item.mimeType() == KCalCore::Event::eventMimeType() ) { + if (item.mimeType() == KCalCore::Event::eventMimeType()) { EventPtr event = objects.first().dynamicCast(); - item.setRemoteId( event->uid() ); - item.setRemoteRevision( event->etag() ); - item.setGid( event->uid() ); - changeCommitted( item ); - item.setPayload( event.dynamicCast() ); - new ItemModifyJob( item, this ); - } else if ( item.mimeType() == KCalCore::Todo::todoMimeType() ) { + item.setRemoteId(event->uid()); + item.setRemoteRevision(event->etag()); + item.setGid(event->uid()); + changeCommitted(item); + item.setPayload(event.dynamicCast()); + new ItemModifyJob(item, this); + } else if (item.mimeType() == KCalCore::Todo::todoMimeType()) { TaskPtr task = objects.first().dynamicCast(); - item.setRemoteId( task->uid() ); - item.setRemoteRevision( task->etag() ); - item.setGid( task->uid() ); - changeCommitted( item ); - item.setPayload( task.dynamicCast() ); - new ItemModifyJob( item, this ); + item.setRemoteId(task->uid()); + item.setRemoteRevision(task->etag()); + item.setGid(task->uid()); + changeCommitted(item); + item.setPayload(task.dynamicCast()); + new ItemModifyJob(item, this); } } -AKONADI_RESOURCE_MAIN( CalendarResource ) +AKONADI_RESOURCE_MAIN(CalendarResource) diff -Nru kdepim-runtime-4.14.6/resources/google/calendar/calendarresource.h kdepim-runtime-15.08.0/resources/google/calendar/calendarresource.h --- kdepim-runtime-4.14.6/resources/google/calendar/calendarresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/calendar/calendarresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,49 +20,50 @@ #include "common/googleresource.h" -#include -#include +#include +#include class CalendarResource : public GoogleResource { - Q_OBJECT - public: - explicit CalendarResource( const QString &id ); + Q_OBJECT +public: + explicit CalendarResource(const QString &id); ~CalendarResource(); - public: - virtual GoogleSettings *settings() const; - virtual QList< QUrl > scopes() const; - - protected Q_SLOTS: - virtual void retrieveCollections(); - virtual void retrieveItems( const Akonadi::Collection &collection ); - - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet< QByteArray >& partIdentifiers ); - virtual void itemRemoved( const Akonadi::Item &item ); - virtual void itemMoved( const Akonadi::Item &item, - const Akonadi::Collection &collectionSource, - const Akonadi::Collection &collectionDestination ); - - virtual void collectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection &parent ); - virtual void collectionChanged( const Akonadi::Collection &collection ); - virtual void collectionRemoved( const Akonadi::Collection &collection ); - - void slotItemsRetrieved( KGAPI2::Job *job ); - void slotCollectionsRetrieved( KGAPI2::Job *job ); - void slotCalendarsRetrieved( KGAPI2::Job *job ); - void slotRemoveTaskFetchJobFinished( KJob *job ); - void slotDoRemoveTask( KJob *job ); - void slotModifyTaskReparentFinished( KGAPI2::Job *job ); - void slotTaskAddedSearchFinished( KJob * ); - void slotCreateJobFinished( KGAPI2::Job *job ); - - protected: - virtual int runConfigurationDialog( WId windowId ); - virtual void updateResourceName(); +public: + using GoogleResource::collectionChanged; // So we don't trigger -Woverloaded-virtual + GoogleSettings *settings() const Q_DECL_OVERRIDE; + QList< QUrl > scopes() const Q_DECL_OVERRIDE; + +protected Q_SLOTS: + void retrieveCollections() Q_DECL_OVERRIDE; + void retrieveItems(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &item, const QSet< QByteArray > &partIdentifiers) Q_DECL_OVERRIDE; + void itemRemoved(const Akonadi::Item &item) Q_DECL_OVERRIDE; + void itemMoved(const Akonadi::Item &item, + const Akonadi::Collection &collectionSource, + const Akonadi::Collection &collectionDestination) Q_DECL_OVERRIDE; + + void collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent) Q_DECL_OVERRIDE; + void collectionChanged(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void collectionRemoved(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + + void slotItemsRetrieved(KGAPI2::Job *job); + void slotCollectionsRetrieved(KGAPI2::Job *job); + void slotCalendarsRetrieved(KGAPI2::Job *job); + void slotRemoveTaskFetchJobFinished(KJob *job); + void slotDoRemoveTask(KJob *job); + void slotModifyTaskReparentFinished(KGAPI2::Job *job); + void slotTaskAddedSearchFinished(KJob *); + void slotCreateJobFinished(KGAPI2::Job *job); + +protected: + int runConfigurationDialog(WId windowId) Q_DECL_OVERRIDE; + void updateResourceName() Q_DECL_OVERRIDE; - private: +private: QMap m_collections; Akonadi::Collection m_rootCollection; diff -Nru kdepim-runtime-4.14.6/resources/google/calendar/CMakeLists.txt kdepim-runtime-15.08.0/resources/google/calendar/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/google/calendar/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/calendar/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,8 +1,6 @@ -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}") -include_directories(${QJSON_INCLUDE_DIR} - ${qjson_INCLUDE_DIR} -) +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_googlecalendar_resource\") + set(calendarresource_SRCS calendarresource.cpp @@ -16,21 +14,21 @@ ${accounts_SRCS} ) -kde4_add_kcfg_files(calendarresource_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/settingsbase.kcfgc) +kconfig_add_kcfg_files(calendarresource_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/settingsbase.kcfgc) kcfg_generate_dbus_interface( ${CMAKE_CURRENT_SOURCE_DIR}/settingsbase.kcfg org.kde.Akonadi.GoogleCalendar.Settings ) -qt4_add_dbus_adaptor(calendarresource_SRCS +qt5_add_dbus_adaptor(calendarresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.GoogleCalendar.Settings.xml ${CMAKE_CURRENT_SOURCE_DIR}/settings.h Settings ) -kde4_add_executable(akonadi_googlecalendar_resource RUN_UNINSTALLED ${calendarresource_SRCS}) +add_executable(akonadi_googlecalendar_resource ${calendarresource_SRCS}) -if(Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_googlecalendar_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../../Info.plist.template ) @@ -46,20 +44,15 @@ target_link_libraries(akonadi_googlecalendar_resource - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_AKONADI_CALENDAR_LIBS} - ${KDEPIMLIBS_KCALCORE_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${QT_QTCORE_LIBRARY} - ${QT_QTGUI_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ${QT_QTNETWORK_LIBRARY} - ${KDE4_KDECORE_LIBS} - ${KDE4_KDEWEBKIT_LIBS} - ${QJSON_LIBRARIES} - ${QJSON_LIBRARY} # for Mac OSX - ${qjson_LIBRARY} # for Debian - ${LibKGAPI2_LIBRARY} + KF5::AkonadiCore + KF5::CalendarCore + KF5::AkonadiCalendar + KF5::Mime + KF5::GAPICalendar + KF5::GAPICore + KF5::GAPITasks + KF5::AkonadiAgentBase + KF5::Wallet ) if(${AccountsQt_FOUND} AND ${SignOnQt_FOUND}) @@ -69,9 +62,9 @@ endif() -install(TARGETS akonadi_googlecalendar_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(TARGETS akonadi_googlecalendar_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install( FILES googlecalendarresource.desktop - DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" + DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) diff -Nru kdepim-runtime-4.14.6/resources/google/calendar/defaultreminderattribute.cpp kdepim-runtime-15.08.0/resources/google/calendar/defaultreminderattribute.cpp --- kdepim-runtime-4.14.6/resources/google/calendar/defaultreminderattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/calendar/defaultreminderattribute.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,11 +18,9 @@ #include "defaultreminderattribute.h" #include +#include -#include -#include - -#include +#include using namespace KGAPI2; @@ -33,35 +31,40 @@ Akonadi::Attribute *DefaultReminderAttribute::clone() const { DefaultReminderAttribute *attr = new DefaultReminderAttribute(); - attr->setReminders( m_reminders ); + attr->setReminders(m_reminders); return attr; } -void DefaultReminderAttribute::setReminders( const RemindersList &reminders ) +void DefaultReminderAttribute::setReminders(const RemindersList &reminders) { m_reminders = reminders; } -void DefaultReminderAttribute::deserialize( const QByteArray &data ) +void DefaultReminderAttribute::deserialize(const QByteArray &data) { - QJson::Parser parser; + QJsonDocument json = QJsonDocument::fromJson(data); + if (json.isNull()) { + return; + } + + QVariant var = json.toVariant(); QVariantList list; - list = parser.parse( data ).toList(); - Q_FOREACH( const QVariant & l, list ) { + list = var.toList(); + Q_FOREACH (const QVariant &l, list) { QVariantMap reminder = l.toMap(); - KGAPI2::ReminderPtr rem( new KGAPI2::Reminder ); + KGAPI2::ReminderPtr rem(new KGAPI2::Reminder); - if ( reminder[QLatin1String("type")].toString() == QLatin1String("display") ) { - rem->setType( KCalCore::Alarm::Display ); - } else if ( reminder[QLatin1String("type")].toString() == QLatin1String("email") ) { - rem->setType( KCalCore::Alarm::Email ); + if (reminder[QLatin1String("type")].toString() == QLatin1String("display")) { + rem->setType(KCalCore::Alarm::Display); + } else if (reminder[QLatin1String("type")].toString() == QLatin1String("email")) { + rem->setType(KCalCore::Alarm::Email); } - KCalCore::Duration offset( reminder[QLatin1String("time")].toInt(), KCalCore::Duration::Seconds ); - rem->setStartOffset( offset ); + KCalCore::Duration offset(reminder[QLatin1String("time")].toInt(), KCalCore::Duration::Seconds); + rem->setStartOffset(offset); m_reminders << rem; } @@ -70,13 +73,14 @@ QByteArray DefaultReminderAttribute::serialized() const { QVariantList list; + list.reserve(m_reminders.count()); - Q_FOREACH( const ReminderPtr & rem, m_reminders ) { + Q_FOREACH (const ReminderPtr &rem, m_reminders) { QVariantMap reminder; - if ( rem->type() == KCalCore::Alarm::Display ) { + if (rem->type() == KCalCore::Alarm::Display) { reminder[QLatin1String("type")] = QLatin1String("display"); - } else if ( rem->type() == KCalCore::Alarm::Email ) { + } else if (rem->type() == KCalCore::Alarm::Email) { reminder[QLatin1String("type")] = QLatin1String("email"); } @@ -84,22 +88,21 @@ list << reminder; } - - QJson::Serializer serializer; - return serializer.serialize( list ); + QJsonDocument serialized = QJsonDocument::fromVariant(list); + return serialized.toJson(); } -KCalCore::Alarm::List DefaultReminderAttribute::alarms( KCalCore::Incidence *incidence ) const +KCalCore::Alarm::List DefaultReminderAttribute::alarms(KCalCore::Incidence *incidence) const { KCalCore::Alarm::List alarms; - - Q_FOREACH( const ReminderPtr & reminder, m_reminders ) { - KCalCore::Alarm::Ptr alarm( new KCalCore::Alarm( incidence ) ); - - alarm->setType( reminder->type() ); - alarm->setTime( incidence->dtStart() ); - alarm->setStartOffset( reminder->startOffset() ); - alarm->setEnabled( true ); + alarms.reserve(m_reminders.count()); + Q_FOREACH (const ReminderPtr &reminder, m_reminders) { + KCalCore::Alarm::Ptr alarm(new KCalCore::Alarm(incidence)); + + alarm->setType(reminder->type()); + alarm->setTime(incidence->dtStart()); + alarm->setStartOffset(reminder->startOffset()); + alarm->setEnabled(true); alarms << alarm; } @@ -109,7 +112,7 @@ QByteArray DefaultReminderAttribute::type() const { - static const QByteArray sType( "defaultReminders" ); + static const QByteArray sType("defaultReminders"); return sType; } diff -Nru kdepim-runtime-4.14.6/resources/google/calendar/defaultreminderattribute.h kdepim-runtime-15.08.0/resources/google/calendar/defaultreminderattribute.h --- kdepim-runtime-4.14.6/resources/google/calendar/defaultreminderattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/calendar/defaultreminderattribute.h 2015-08-10 21:01:02.000000000 +0000 @@ -18,27 +18,27 @@ #ifndef GOOGLE_CALENDAR_DEFAULTREMINDERATTRIBUTE_H #define GOOGLE_CALENDAR_DEFAULTREMINDERATTRIBUTE_H -#include +#include -#include +#include #include #include class DefaultReminderAttribute : public Akonadi::Attribute { - public: - explicit DefaultReminderAttribute( ); +public: + explicit DefaultReminderAttribute(); - Attribute *clone() const; - void deserialize( const QByteArray &data ); - QByteArray serialized() const; - QByteArray type() const; + Attribute *clone() const Q_DECL_OVERRIDE; + void deserialize(const QByteArray &data) Q_DECL_OVERRIDE; + QByteArray serialized() const Q_DECL_OVERRIDE; + QByteArray type() const Q_DECL_OVERRIDE; - void setReminders( const KGAPI2::RemindersList &reminders ); - KCalCore::Alarm::List alarms( KCalCore::Incidence *incidence ) const; + void setReminders(const KGAPI2::RemindersList &reminders); + KCalCore::Alarm::List alarms(KCalCore::Incidence *incidence) const; - private: +private: KGAPI2::RemindersList m_reminders; }; diff -Nru kdepim-runtime-4.14.6/resources/google/calendar/googlecalendarresource.desktop kdepim-runtime-15.08.0/resources/google/calendar/googlecalendarresource.desktop --- kdepim-runtime-4.14.6/resources/google/calendar/googlecalendarresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/calendar/googlecalendarresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,6 @@ [Desktop Entry] Name=Google Calendars and Tasks +Name[bg]=Календари и задачи в Google Name[bs]=Google kalendari i zadaće Name[ca]=Calendaris i tasques de Google Name[ca@valencia]=Calendaris i tasques de Google @@ -41,6 +42,7 @@ Name[zh_CN]=Google 日历和任务 Name[zh_TW]=Google 行事曆與工作 Comment=Access your Google Calendars and Tasks from KDE +Comment[bg]=Достъп до календарите и задачите ви в Google от KDE Comment[bs]=Pristupite svojim Google kalendaru i zadacima iz KDE Comment[ca]=Accediu als calendaris i tasques de Google des del KDE Comment[ca@valencia]=Accediu als calendaris i tasques de Google des del KDE diff -Nru kdepim-runtime-4.14.6/resources/google/calendar/settings.cpp kdepim-runtime-15.08.0/resources/google/calendar/settings.cpp --- kdepim-runtime-4.14.6/resources/google/calendar/settings.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/calendar/settings.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,47 +18,46 @@ #include "settings.h" #include "settingsadaptor.h" -#include #include #include class SettingsHelper { - public: - SettingsHelper() : q( 0 ) +public: + SettingsHelper() : q(Q_NULLPTR) { } ~SettingsHelper() { - delete q; - q = 0; + delete q; + q = Q_NULLPTR; } Settings *q; }; -K_GLOBAL_STATIC( SettingsHelper, s_globalSettings ) +Q_GLOBAL_STATIC(SettingsHelper, s_globalSettings) Settings::Settings(): GoogleSettings() { - Q_ASSERT( !s_globalSettings->q ); - s_globalSettings->q = this; + Q_ASSERT(!s_globalSettings->q); + s_globalSettings->q = this; - new SettingsAdaptor( this ); - QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ), this, - QDBusConnection::ExportAdaptors | QDBusConnection::ExportScriptableContents ); + new SettingsAdaptor(this); + QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"), this, + QDBusConnection::ExportAdaptors | QDBusConnection::ExportScriptableContents); } Settings *Settings::self() { - if ( !s_globalSettings->q ) { - new Settings; - s_globalSettings->q->readConfig(); - } + if (!s_globalSettings->q) { + new Settings; + s_globalSettings->q->load(); + } - return s_globalSettings->q; + return s_globalSettings->q; } diff -Nru kdepim-runtime-4.14.6/resources/google/calendar/settingsdialog.cpp kdepim-runtime-15.08.0/resources/google/calendar/settingsdialog.cpp --- kdepim-runtime-4.14.6/resources/google/calendar/settingsdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/calendar/settingsdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,83 +18,75 @@ #include "settingsdialog.h" #include "settings.h" -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include using namespace KGAPI2; - -SettingsDialog::SettingsDialog( GoogleAccountManager *accountManager, WId windowId, GoogleResource *parent ): - GoogleSettingsDialog( accountManager, windowId, parent ) +SettingsDialog::SettingsDialog(GoogleAccountManager *accountManager, WId windowId, GoogleResource *parent): + GoogleSettingsDialog(accountManager, windowId, parent) { - connect( this, SIGNAL(accepted()), - this, SLOT(saveSettings()) ); - connect( this, SIGNAL(currentAccountChanged(QString)), - this, SLOT(slotCurrentAccountChanged(QString)) ); - + connect(this, &SettingsDialog::currentAccountChanged, this, &SettingsDialog::slotCurrentAccountChanged); - m_calendarsBox = new QGroupBox( i18n( "Calendars" ), this ); - mainWidget()->layout()->addWidget( m_calendarsBox ); + m_calendarsBox = new QGroupBox(i18n("Calendars"), this); + mainLayout()->addWidget(m_calendarsBox); - QVBoxLayout *vbox = new QVBoxLayout( m_calendarsBox ); + QVBoxLayout *vbox = new QVBoxLayout(m_calendarsBox); - m_calendarsList = new KListWidget( m_calendarsBox ); - vbox->addWidget( m_calendarsList, 1 ); + m_calendarsList = new QListWidget(m_calendarsBox); + vbox->addWidget(m_calendarsList, 1); - m_reloadCalendarsBtn = new KPushButton( KIcon( QLatin1String("view-refresh") ), i18n( "Reload" ), m_calendarsBox ); - vbox->addWidget( m_reloadCalendarsBtn ); - connect( m_reloadCalendarsBtn, SIGNAL(clicked(bool)), - this, SLOT(slotReloadCalendars()) ); + m_reloadCalendarsBtn = new QPushButton(QIcon::fromTheme(QStringLiteral("view-refresh")), i18n("Reload"), m_calendarsBox); + vbox->addWidget(m_reloadCalendarsBtn); + connect(m_reloadCalendarsBtn, &QPushButton::clicked, this, &SettingsDialog::slotReloadCalendars); QHBoxLayout *hbox = new QHBoxLayout; - vbox->addLayout( hbox ); + vbox->addLayout(hbox); - m_eventsLimitLabel = new QLabel( i18nc( "Followed by a date picker widget", "&Fetch only new events since" ), this ); - hbox->addWidget( m_eventsLimitLabel ); + m_eventsLimitLabel = new QLabel(i18nc("Followed by a date picker widget", "&Fetch only new events since"), this); + hbox->addWidget(m_eventsLimitLabel); - m_eventsLimitCombo = new KDateComboBox( this ); - m_eventsLimitLabel->setBuddy( m_eventsLimitCombo ); - m_eventsLimitCombo->setMaximumDate( QDate::currentDate() ); - m_eventsLimitCombo->setMinimumDate( QDate::fromString( QLatin1String( "2000-01-01" ), Qt::ISODate ) ); - m_eventsLimitCombo->setOptions( KDateComboBox::EditDate | KDateComboBox::SelectDate | - KDateComboBox::DatePicker | KDateComboBox::WarnOnInvalid ); - if( Settings::self()->eventsSince().isEmpty() ) { - const QString ds = QString::fromLatin1( "%1-01-01" ).arg( QString::number( QDate::currentDate().year() - 3 ) ); - m_eventsLimitCombo->setDate( QDate::fromString( ds, Qt::ISODate ) ); + m_eventsLimitCombo = new KDateComboBox(this); + m_eventsLimitLabel->setBuddy(m_eventsLimitCombo); + m_eventsLimitCombo->setMaximumDate(QDate::currentDate()); + m_eventsLimitCombo->setMinimumDate(QDate::fromString(QStringLiteral("2000-01-01"), Qt::ISODate)); + m_eventsLimitCombo->setOptions(KDateComboBox::EditDate | KDateComboBox::SelectDate | + KDateComboBox::DatePicker | KDateComboBox::WarnOnInvalid); + if (Settings::self()->eventsSince().isEmpty()) { + const QString ds = QStringLiteral("%1-01-01").arg(QString::number(QDate::currentDate().year() - 3)); + m_eventsLimitCombo->setDate(QDate::fromString(ds, Qt::ISODate)); } else { - m_eventsLimitCombo->setDate( QDate::fromString( Settings::self()->eventsSince(), Qt::ISODate ) ); + m_eventsLimitCombo->setDate(QDate::fromString(Settings::self()->eventsSince(), Qt::ISODate)); } - hbox->addWidget( m_eventsLimitCombo ); + hbox->addWidget(m_eventsLimitCombo); - m_taskListsBox = new QGroupBox( i18n( "Tasklists" ), this ); - mainWidget()->layout()->addWidget( m_taskListsBox ); + m_taskListsBox = new QGroupBox(i18n("Tasklists"), this); + mainLayout()->addWidget(m_taskListsBox); - vbox = new QVBoxLayout( m_taskListsBox ); + vbox = new QVBoxLayout(m_taskListsBox); - m_taskListsList = new KListWidget( m_taskListsBox ); - vbox->addWidget( m_taskListsList, 1 ); + m_taskListsList = new QListWidget(m_taskListsBox); + vbox->addWidget(m_taskListsList, 1); - m_reloadTaskListsBtn = new KPushButton( KIcon( QLatin1String("view-refresh") ), i18n( "Reload" ), m_taskListsBox ); - vbox->addWidget( m_reloadTaskListsBtn ); - connect( m_reloadTaskListsBtn, SIGNAL(clicked(bool)), - this, SLOT(slotReloadTaskLists()) ); + m_reloadTaskListsBtn = new QPushButton(QIcon::fromTheme(QStringLiteral("view-refresh")), i18n("Reload"), m_taskListsBox); + vbox->addWidget(m_reloadTaskListsBtn); + connect(m_reloadTaskListsBtn, &QPushButton::clicked, this, &SettingsDialog::slotReloadTaskLists); } SettingsDialog::~SettingsDialog() @@ -104,47 +96,46 @@ void SettingsDialog::saveSettings() { const AccountPtr account = currentAccount(); - if ( !currentAccount() ) { - Settings::self()->setAccount( QString() ); - Settings::self()->setCalendars( QStringList() ); - Settings::self()->setTaskLists( QStringList() ); - Settings::self()->setEventsSince( QString() ); - Settings::self()->writeConfig(); + if (!currentAccount()) { + Settings::self()->setAccount(QString()); + Settings::self()->setCalendars(QStringList()); + Settings::self()->setTaskLists(QStringList()); + Settings::self()->setEventsSince(QString()); + Settings::self()->save(); return; } - Settings::self()->setAccount( account->accountName() ); + Settings::self()->setAccount(account->accountName()); QStringList calendars; - for ( int i = 0; i < m_calendarsList->count(); i++ ) { - QListWidgetItem *item = m_calendarsList->item( i ); + for (int i = 0; i < m_calendarsList->count(); i++) { + QListWidgetItem *item = m_calendarsList->item(i); - if ( item->checkState() == Qt::Checked ) { - calendars.append( item->data( Qt::UserRole ).toString() ); + if (item->checkState() == Qt::Checked) { + calendars.append(item->data(Qt::UserRole).toString()); } } - Settings::self()->setCalendars( calendars ); - if ( m_eventsLimitCombo->isValid() ) { - Settings::self()->setEventsSince( m_eventsLimitCombo->date().toString( Qt::ISODate ) ); + Settings::self()->setCalendars(calendars); + if (m_eventsLimitCombo->isValid()) { + Settings::self()->setEventsSince(m_eventsLimitCombo->date().toString(Qt::ISODate)); } QStringList taskLists; - for ( int i = 0; i < m_taskListsList->count(); i++ ) { - QListWidgetItem *item = m_taskListsList->item( i ); + for (int i = 0; i < m_taskListsList->count(); i++) { + QListWidgetItem *item = m_taskListsList->item(i); - if ( item->checkState() == Qt::Checked ) { - taskLists.append( item->data( Qt::UserRole ).toString() ); + if (item->checkState() == Qt::Checked) { + taskLists.append(item->data(Qt::UserRole).toString()); } } - Settings::self()->setTaskLists( taskLists ); - + Settings::self()->setTaskLists(taskLists); - Settings::self()->writeConfig(); + Settings::self()->save(); } -void SettingsDialog::slotCurrentAccountChanged( const QString &accountName ) +void SettingsDialog::slotCurrentAccountChanged(const QString &accountName) { - if ( accountName.isEmpty() ) { + if (accountName.isEmpty()) { return; } @@ -155,84 +146,82 @@ void SettingsDialog::slotReloadCalendars() { const AccountPtr account = currentAccount(); - if ( !account ) { + if (!account) { return; } - CalendarFetchJob *fetchJob = new CalendarFetchJob( account, this ); - connect( fetchJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotCalendarsRetrieved(KGAPI2::Job*)) ); + CalendarFetchJob *fetchJob = new CalendarFetchJob(account, this); + connect(fetchJob, &CalendarFetchJob::finished, this, &SettingsDialog::slotCalendarsRetrieved); - m_calendarsBox->setDisabled( true ); + m_calendarsBox->setDisabled(true); m_calendarsList->clear(); } void SettingsDialog::slotReloadTaskLists() { const AccountPtr account = currentAccount(); - if ( !account ) { + if (!account) { return; } - TaskListFetchJob *fetchJob = new TaskListFetchJob( account, this ); - connect( fetchJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotTaskListsRetrieved(KGAPI2::Job*)) ); + TaskListFetchJob *fetchJob = new TaskListFetchJob(account, this); + connect(fetchJob, &CalendarFetchJob::finished, this, &SettingsDialog::slotTaskListsRetrieved); - m_taskListsBox->setDisabled( true ); + m_taskListsBox->setDisabled(true); m_taskListsList->clear(); } -void SettingsDialog::slotCalendarsRetrieved( Job *job ) +void SettingsDialog::slotCalendarsRetrieved(Job *job) { - if ( !handleError( job ) || !currentAccount() ) { - m_calendarsBox->setEnabled( true ); + if (!handleError(job) || !currentAccount()) { + m_calendarsBox->setEnabled(true); return; } - FetchJob *fetchJob = qobject_cast(job); + FetchJob *fetchJob = qobject_cast(job); ObjectsList objects = fetchJob->items(); QStringList activeCalendars; - if ( currentAccount()->accountName() == Settings::self()->account() ) { + if (currentAccount()->accountName() == Settings::self()->account()) { activeCalendars = Settings::self()->calendars(); } - Q_FOREACH( const ObjectPtr &object, objects ) { + Q_FOREACH (const ObjectPtr &object, objects) { CalendarPtr calendar = object.dynamicCast(); - QListWidgetItem *item = new QListWidgetItem( calendar->title() ); - item->setData( Qt::UserRole, calendar->uid() ); - item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable ); - item->setCheckState( ( activeCalendars.isEmpty() || activeCalendars.contains( calendar->uid() ) ) ? Qt::Checked : Qt::Unchecked ); - m_calendarsList->addItem( item ); + QListWidgetItem *item = new QListWidgetItem(calendar->title()); + item->setData(Qt::UserRole, calendar->uid()); + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable); + item->setCheckState((activeCalendars.isEmpty() || activeCalendars.contains(calendar->uid())) ? Qt::Checked : Qt::Unchecked); + m_calendarsList->addItem(item); } - m_calendarsBox->setEnabled( true ); + m_calendarsBox->setEnabled(true); } -void SettingsDialog::slotTaskListsRetrieved( Job *job ) +void SettingsDialog::slotTaskListsRetrieved(Job *job) { - if ( !handleError( job ) || !currentAccount() ) { - m_taskListsBox->setEnabled( true ); + if (!handleError(job) || !currentAccount()) { + m_taskListsBox->setEnabled(true); return; } - FetchJob *fetchJob = qobject_cast(job); + FetchJob *fetchJob = qobject_cast(job); ObjectsList objects = fetchJob->items(); QStringList activeTaskLists; - if ( currentAccount()->accountName() == Settings::self()->account()) { + if (currentAccount()->accountName() == Settings::self()->account()) { activeTaskLists = Settings::self()->taskLists(); } - Q_FOREACH( const ObjectPtr &object, objects ) { + Q_FOREACH (const ObjectPtr &object, objects) { TaskListPtr taskList = object.dynamicCast(); - QListWidgetItem *item = new QListWidgetItem( taskList->title() ); - item->setData( Qt::UserRole, taskList->uid() ); - item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable ); - item->setCheckState( ( activeTaskLists.isEmpty() || activeTaskLists.contains( taskList->uid() ) ) ? Qt::Checked : Qt::Unchecked ); - m_taskListsList->addItem( item ); + QListWidgetItem *item = new QListWidgetItem(taskList->title()); + item->setData(Qt::UserRole, taskList->uid()); + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable); + item->setCheckState((activeTaskLists.isEmpty() || activeTaskLists.contains(taskList->uid())) ? Qt::Checked : Qt::Unchecked); + m_taskListsList->addItem(item); } - m_taskListsBox->setEnabled( true ); + m_taskListsBox->setEnabled(true); } diff -Nru kdepim-runtime-4.14.6/resources/google/calendar/settingsdialog.h kdepim-runtime-15.08.0/resources/google/calendar/settingsdialog.h --- kdepim-runtime-4.14.6/resources/google/calendar/settingsdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/calendar/settingsdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,37 +20,37 @@ #include "common/googlesettingsdialog.h" -class KListWidget; +class QListWidget; class QLabel; class KDateComboBox; class SettingsDialog : public GoogleSettingsDialog { - Q_OBJECT - public: - explicit SettingsDialog( GoogleAccountManager *accountManager, WId windowId, GoogleResource *parent ); + Q_OBJECT +public: + explicit SettingsDialog(GoogleAccountManager *accountManager, WId windowId, GoogleResource *parent); ~SettingsDialog(); - private Q_SLOTS: +private Q_SLOTS: void slotReloadCalendars(); void slotReloadTaskLists(); - void slotCurrentAccountChanged( const QString &accountName ); + void slotCurrentAccountChanged(const QString &accountName); - void slotTaskListsRetrieved( KGAPI2::Job *job ); - void slotCalendarsRetrieved( KGAPI2::Job *job ); + void slotTaskListsRetrieved(KGAPI2::Job *job); + void slotCalendarsRetrieved(KGAPI2::Job *job); - void saveSettings(); + void saveSettings() Q_DECL_OVERRIDE; - private: +private: QGroupBox *m_calendarsBox; - KListWidget *m_calendarsList; - KPushButton *m_reloadCalendarsBtn; + QListWidget *m_calendarsList; + QPushButton *m_reloadCalendarsBtn; QLabel *m_eventsLimitLabel; KDateComboBox *m_eventsLimitCombo; QGroupBox *m_taskListsBox; - KListWidget *m_taskListsList; - KPushButton *m_reloadTaskListsBtn; + QListWidget *m_taskListsList; + QPushButton *m_reloadTaskListsBtn; }; diff -Nru kdepim-runtime-4.14.6/resources/google/calendar/settings.h kdepim-runtime-15.08.0/resources/google/calendar/settings.h --- kdepim-runtime-4.14.6/resources/google/calendar/settings.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/calendar/settings.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,9 +22,9 @@ class Settings: public GoogleSettings { - Q_OBJECT - Q_CLASSINFO( "D-Bus Interface", "org.kde.Akonadi.GoogleCalendar.ExtendedSettings" ) - public: + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.Akonadi.GoogleCalendar.ExtendedSettings") +public: Settings(); static Settings *self(); diff -Nru kdepim-runtime-4.14.6/resources/google/CMakeLists.txt kdepim-runtime-15.08.0/resources/google/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/google/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,4 +1,4 @@ -include_directories(${LibKGAPI2_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) add_definitions( -DQT_NO_CAST_FROM_ASCII ) add_definitions( -DQT_NO_CAST_TO_ASCII ) @@ -7,9 +7,9 @@ if(${AccountsQt_FOUND} AND ${SignOnQt_FOUND}) include_directories(${ACCOUNTSQT_INCLUDE_DIRS} ${SIGNONQT_INCLUDE_DIRS} ../) add_definitions(-DHAVE_ACCOUNTS) - set(accounts_SRCS ../../shared/getcredentialsjob.cpp) + set(accounts_SRCS ../../shared/singlefileresource/getcredentialsjob.cpp) endif() -macro_optional_add_subdirectory(calendar) -macro_optional_add_subdirectory(contacts) +add_subdirectory(calendar) +add_subdirectory(contacts) diff -Nru kdepim-runtime-4.14.6/resources/google/common/googleaccountmanager.cpp kdepim-runtime-15.08.0/resources/google/common/googleaccountmanager.cpp --- kdepim-runtime-4.14.6/resources/google/common/googleaccountmanager.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/common/googleaccountmanager.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,18 +21,18 @@ #include -#include -#include -#include +#include +#include +#include -#include +#include #define WALLET_FOLDER QLatin1String("Akonadi Google") using namespace KGAPI2; -GoogleAccountManager::GoogleAccountManager( QObject* parent ): - QObject( parent ), +GoogleAccountManager::GoogleAccountManager(QObject *parent): + QObject(parent), m_isReady(false) { QMetaObject::invokeMethod(this, "initManager", Qt::QueuedConnection); @@ -55,49 +55,47 @@ // FIXME: Don't use synchronous wallet // With asynchronous wallet however we are unable to read any data from it // in when slotWalletOpened() is called on walletOpened() signal - m_wallet = KWallet::Wallet::openWallet( KWallet::Wallet::NetworkWallet(), - 0, KWallet::Wallet::Synchronous ); - slotWalletOpened( m_wallet != 0 ); + m_wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), + 0, KWallet::Wallet::Synchronous); + slotWalletOpened(m_wallet != Q_NULLPTR); // connect( m_wallet, SIGNAL(walletOpened(bool)), // this, SLOT(slotWalletOpened(bool)) ); - if ( m_wallet ) { - connect( m_wallet, SIGNAL(folderUpdated(QString)), - this, SLOT(slotFolderUpdated(QString)) ); - connect( m_wallet, SIGNAL(walletClosed()), - this, SLOT(slotWalletClosed()) ); + if (m_wallet) { + connect(m_wallet.data(), &KWallet::Wallet::folderUpdated, this, &GoogleAccountManager::slotFolderUpdated); + connect(m_wallet.data(), &KWallet::Wallet::walletClosed, this, &GoogleAccountManager::slotWalletClosed); } } -void GoogleAccountManager::slotWalletOpened( bool success ) +void GoogleAccountManager::slotWalletOpened(bool success) { - if ( !success ) { - kWarning() << "Failed to open wallet"; - Q_EMIT managerReady( false ); + if (!success) { + qWarning() << "Failed to open wallet"; + Q_EMIT managerReady(false); return; } - if ( !m_wallet->hasFolder( WALLET_FOLDER ) ) { - if ( !m_wallet->createFolder( WALLET_FOLDER ) ) { - kWarning() << "Failed to create KWallet folder " << WALLET_FOLDER; - Q_EMIT managerReady( false ); + if (!m_wallet->hasFolder(WALLET_FOLDER)) { + if (!m_wallet->createFolder(WALLET_FOLDER)) { + qWarning() << "Failed to create KWallet folder " << WALLET_FOLDER; + Q_EMIT managerReady(false); return; } } - if ( !m_wallet->setFolder( WALLET_FOLDER ) ) { - kWarning() << "Failed to open KWallet folder" << WALLET_FOLDER; - Q_EMIT managerReady( false ); + if (!m_wallet->setFolder(WALLET_FOLDER)) { + qWarning() << "Failed to open KWallet folder" << WALLET_FOLDER; + Q_EMIT managerReady(false); return; } // Populate the cache now QStringList accountNames = m_wallet->entryList(); - Q_FOREACH( const QString &accountName, accountNames ) { - m_accounts[accountName] = findAccountInWallet( accountName ); + Q_FOREACH (const QString &accountName, accountNames) { + m_accounts[accountName] = findAccountInWallet(accountName); } m_isReady = true; - Q_EMIT managerReady( true ); + Q_EMIT managerReady(true); } void GoogleAccountManager::slotWalletClosed() @@ -106,55 +104,55 @@ delete m_wallet; } -void GoogleAccountManager::slotFolderUpdated(const QString& folder) +void GoogleAccountManager::slotFolderUpdated(const QString &folder) { // We are interested only in the "Akonadi Google" folder - if ( folder != WALLET_FOLDER ) { + if (folder != WALLET_FOLDER) { return; } QStringList walletEntries = m_wallet->entryList(); - Q_FOREACH( const AccountPtr &account, m_accounts ) { - AccountPtr changedAccount = findAccountInWallet( account->accountName() ); - if ( changedAccount.isNull() ) { - walletEntries.removeOne( account->accountName() ); - m_accounts.remove( account->accountName() ); - Q_EMIT accountRemoved( account->accountName() ); + Q_FOREACH (const AccountPtr &account, m_accounts) { + AccountPtr changedAccount = findAccountInWallet(account->accountName()); + if (changedAccount.isNull()) { + walletEntries.removeOne(account->accountName()); + m_accounts.remove(account->accountName()); + Q_EMIT accountRemoved(account->accountName()); continue; } - if (( account->accessToken() != changedAccount->accessToken() ) || - ( account->refreshToken() != changedAccount->refreshToken() ) || - ( account->scopes() != changedAccount->scopes() )) { + if ((account->accessToken() != changedAccount->accessToken()) || + (account->refreshToken() != changedAccount->refreshToken()) || + (account->scopes() != changedAccount->scopes())) { - walletEntries.removeOne( account->accountName() ); + walletEntries.removeOne(account->accountName()); m_accounts[account->accountName()] = changedAccount; - Q_EMIT accountChanged( changedAccount ); + Q_EMIT accountChanged(changedAccount); } } - Q_FOREACH( const QString &accountName, walletEntries ) { - const AccountPtr newAccount = findAccountInWallet( accountName ); + Q_FOREACH (const QString &accountName, walletEntries) { + const AccountPtr newAccount = findAccountInWallet(accountName); m_accounts[newAccount->accountName()] = newAccount; - Q_EMIT accountAdded( newAccount ); + Q_EMIT accountAdded(newAccount); } } -AccountPtr GoogleAccountManager::findAccount( const QString& accountName ) const +AccountPtr GoogleAccountManager::findAccount(const QString &accountName) const { - if ( !m_isReady ) { - kWarning() << "Manager is not ready!"; + if (!m_isReady) { + qWarning() << "Manager is not ready!"; return AccountPtr(); } - if ( m_accounts.contains( accountName ) ) { + if (m_accounts.contains(accountName)) { return m_accounts[accountName]; } - AccountPtr account = findAccountInWallet( accountName ); - if ( account.isNull() ) { + AccountPtr account = findAccountInWallet(accountName); + if (account.isNull()) { return AccountPtr(); } @@ -162,48 +160,50 @@ return account; } -AccountPtr GoogleAccountManager::findAccountInWallet(const QString& accountName) const +AccountPtr GoogleAccountManager::findAccountInWallet(const QString &accountName) const { - if ( !m_wallet->entryList().contains( accountName ) ) { - kDebug() << "Account" << accountName << "not found in KWallet"; + if (!m_wallet->entryList().contains(accountName)) { + qDebug() << "Account" << accountName << "not found in KWallet"; return AccountPtr(); } QMap map; - m_wallet->readMap( accountName, map ); + m_wallet->readMap(accountName, map); - const QStringList scopes = map[QLatin1String( "scopes" )].split( QLatin1Char(','), QString::SkipEmptyParts ); + const QStringList scopes = map[QLatin1String("scopes")].split(QLatin1Char(','), QString::SkipEmptyParts); QList scopeUrls; - Q_FOREACH( const QString &scope, scopes ) { - scopeUrls << QUrl( scope ); - } - AccountPtr account( new Account( accountName, - map[QLatin1String( "accessToken" )], - map[QLatin1String( "refreshToken" )], - scopeUrls ) ); + scopeUrls.reserve(scopes.count()); + Q_FOREACH (const QString &scope, scopes) { + scopeUrls << QUrl(scope); + } + AccountPtr account(new Account(accountName, + map[QLatin1String("accessToken")], + map[QLatin1String("refreshToken")], + scopeUrls)); return account; } -bool GoogleAccountManager::storeAccount(const AccountPtr& account) +bool GoogleAccountManager::storeAccount(const AccountPtr &account) { - if ( !m_isReady ) { - kWarning() << "Manager is not ready!"; + if (!m_isReady) { + qWarning() << "Manager is not ready!"; return false; } QStringList scopes; const QList urlScopes = account->scopes(); - Q_FOREACH(const QUrl &url, urlScopes) { + scopes.reserve(urlScopes.count()); + Q_FOREACH (const QUrl &url, urlScopes) { scopes << url.toString(); } QMap map; - map[QLatin1String( "accessToken" )] = account->accessToken(); - map[QLatin1String( "refreshToken" )] = account->refreshToken(); - map[QLatin1String( "scopes" )] = scopes.join(QLatin1String(",")); + map[QLatin1String("accessToken")] = account->accessToken(); + map[QLatin1String("refreshToken")] = account->refreshToken(); + map[QLatin1String("scopes")] = scopes.join(QLatin1String(",")); - if ( m_wallet->writeMap( account->accountName(), map) == 0 ) { + if (m_wallet->writeMap(account->accountName(), map) == 0) { m_accounts[account->accountName()] = account; return true; } @@ -211,30 +211,30 @@ return false; } -bool GoogleAccountManager::removeAccount(const QString& accountName) +bool GoogleAccountManager::removeAccount(const QString &accountName) { - if ( !m_isReady ) { - kWarning() << "Manager is not ready"; + if (!m_isReady) { + qWarning() << "Manager is not ready"; return false; } - if ( !m_accounts.contains( accountName ) ) { + if (!m_accounts.contains(accountName)) { return true; } - if (m_wallet->removeEntry( accountName ) != 0) { - kWarning() << "Failed to remove account from KWallet"; + if (m_wallet->removeEntry(accountName) != 0) { + qWarning() << "Failed to remove account from KWallet"; return false; } - m_accounts.remove( accountName ); + m_accounts.remove(accountName); return true; } AccountsList GoogleAccountManager::listAccounts() const { - if ( !m_isReady ) { - kWarning() << "Manager is not ready"; + if (!m_isReady) { + qWarning() << "Manager is not ready"; return AccountsList(); } diff -Nru kdepim-runtime-4.14.6/resources/google/common/googleaccountmanager.h kdepim-runtime-15.08.0/resources/google/common/googleaccountmanager.h --- kdepim-runtime-4.14.6/resources/google/common/googleaccountmanager.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/common/googleaccountmanager.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,43 +24,45 @@ #include #include -#include +#include +#include -namespace KWallet { - class Wallet; +namespace KWallet +{ +class Wallet; } class GoogleAccountManager : public QObject { Q_OBJECT - public: - explicit GoogleAccountManager( QObject* parent = 0 ); +public: + explicit GoogleAccountManager(QObject *parent = Q_NULLPTR); virtual ~GoogleAccountManager(); bool isReady() const; - bool storeAccount( const KGAPI2::AccountPtr &account ); - KGAPI2::AccountPtr findAccount( const QString &accountName ) const; - bool removeAccount( const QString &accountName ); + bool storeAccount(const KGAPI2::AccountPtr &account); + KGAPI2::AccountPtr findAccount(const QString &accountName) const; + bool removeAccount(const QString &accountName); KGAPI2::AccountsList listAccounts() const; void cleanup(const QString &accountName); - Q_SIGNALS: - void managerReady( bool ready ); - void accountAdded( const KGAPI2::AccountPtr &account ); - void accountChanged( const KGAPI2::AccountPtr &account ); - void accountRemoved( const QString &accountName ); +Q_SIGNALS: + void managerReady(bool ready); + void accountAdded(const KGAPI2::AccountPtr &account); + void accountChanged(const KGAPI2::AccountPtr &account); + void accountRemoved(const QString &accountName); - private Q_SLOTS: +private Q_SLOTS: void initManager(); - void slotWalletOpened( bool success ); + void slotWalletOpened(bool success); void slotWalletClosed(); - void slotFolderUpdated( const QString &folder ); - KGAPI2::AccountPtr findAccountInWallet( const QString &accountName ) const; + void slotFolderUpdated(const QString &folder); + KGAPI2::AccountPtr findAccountInWallet(const QString &accountName) const; - private: +private: bool m_isReady; QPointer m_wallet; mutable QMap m_accounts; diff -Nru kdepim-runtime-4.14.6/resources/google/common/googleresource.cpp kdepim-runtime-15.08.0/resources/google/common/googleresource.cpp --- kdepim-runtime-4.14.6/resources/google/common/googleresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/common/googleresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,56 +18,51 @@ #include "googleresource.h" #include "googlesettings.h" -#include -#include -#include - -#include -#include - -#include -#include -#include -#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include #ifdef HAVE_ACCOUNTS -#include "shared/getcredentialsjob.h" +#include "../../shared/singlefileresource/getcredentialsjob.h" #endif #define ACCESS_TOKEN_PROPERTY "AccessToken" -Q_DECLARE_METATYPE( KGAPI2::Job* ) +Q_DECLARE_METATYPE(KGAPI2::Job *) using namespace KGAPI2; using namespace Akonadi; -GoogleResource::GoogleResource( const QString &id ): - ResourceBase( id ), +GoogleResource::GoogleResource(const QString &id): + ResourceBase(id), AgentBase::ObserverV2(), m_isConfiguring(false) { - KGlobal::locale()->insertCatalog( QLatin1String("akonadi_google_resource") ); - connect( this, SIGNAL(abortRequested()), - this, SLOT(slotAbortRequested()) ); - connect( this, SIGNAL(reloadConfiguration()), - this, SLOT(reloadConfig()) ); - - setNeedsNetwork( true ); - - changeRecorder()->itemFetchScope().fetchFullPayload( true ); - changeRecorder()->itemFetchScope().setAncestorRetrieval( ItemFetchScope::All ); - changeRecorder()->fetchCollection( true ); - changeRecorder()->collectionFetchScope().setAncestorRetrieval( CollectionFetchScope::All ); - - m_accountMgr = new GoogleAccountManager( this ); - connect( m_accountMgr, SIGNAL(accountChanged(KGAPI2::AccountPtr)), - this, SLOT(slotAccountChanged(KGAPI2::AccountPtr)) ); - connect( m_accountMgr, SIGNAL(accountRemoved(QString)), - this, SLOT(slotAccountRemoved(QString)) ); - connect( m_accountMgr, SIGNAL(managerReady(bool)), - this, SLOT(slotAccountManagerReady(bool)) ); + //QT5 KLocalizedString::global()->insertCatalog( QStringLiteral("akonadi_google_resource") ); + connect(this, &GoogleResource::abortRequested, this, &GoogleResource::slotAbortRequested); + connect(this, &GoogleResource::reloadConfiguration, this, &GoogleResource::reloadConfig); + + setNeedsNetwork(true); + + changeRecorder()->itemFetchScope().fetchFullPayload(true); + changeRecorder()->itemFetchScope().setAncestorRetrieval(ItemFetchScope::All); + changeRecorder()->fetchCollection(true); + changeRecorder()->collectionFetchScope().setAncestorRetrieval(CollectionFetchScope::All); + + m_accountMgr = new GoogleAccountManager(this); + connect(m_accountMgr, &GoogleAccountManager::accountChanged, this, &GoogleResource::slotAccountChanged); + connect(m_accountMgr, &GoogleAccountManager::accountRemoved, this, &GoogleResource::slotAccountRemoved); + connect(m_accountMgr, &GoogleAccountManager::managerReady, this, &GoogleResource::slotAccountManagerReady); - emit status( NotConfigured, i18n( "Waiting for KWallet..." ) ); + Q_EMIT status(NotConfigured, i18n("Waiting for KWallet...")); } GoogleResource::~GoogleResource() @@ -77,6 +72,7 @@ void GoogleResource::cleanup() { accountManager()->cleanup(settings()->account()); + Akonadi::AgentBase::cleanup(); } AccountPtr GoogleResource::account() const @@ -96,7 +92,7 @@ void GoogleResource::abort() { - cancelTask( i18n( "Aborted" ) ); + cancelTask(i18n("Aborted")); } void GoogleResource::slotAbortRequested() @@ -104,291 +100,288 @@ abort(); } -void GoogleResource::configure( WId windowId ) +void GoogleResource::configure(WId windowId) { - if ( !m_accountMgr->isReady() || m_isConfiguring ) { - emit configurationDialogAccepted(); + if (!m_accountMgr->isReady() || m_isConfiguring) { + Q_EMIT configurationDialogAccepted(); return; } m_isConfiguring = true; - if ( runConfigurationDialog( windowId ) == KDialog::Accepted ) { + if (runConfigurationDialog(windowId) == QDialog::Accepted) { updateResourceName(); - emit configurationDialogAccepted(); + Q_EMIT configurationDialogAccepted(); - m_account = accountManager()->findAccount( settings()->account() ); - if ( m_account.isNull() ) { - emit status( NotConfigured, i18n( "Configured account does not exist" ) ); + m_account = accountManager()->findAccount(settings()->account()); + if (m_account.isNull()) { + Q_EMIT status(NotConfigured, i18n("Configured account does not exist")); m_isConfiguring = false; return; } - emit status( Idle, i18nc( "@info:status", "Ready" ) ); + Q_EMIT status(Idle, i18nc("@info:status", "Ready")); synchronize(); } else { updateResourceName(); - emit configurationDialogRejected(); + Q_EMIT configurationDialogRejected(); } m_isConfiguring = false; } -void GoogleResource::updateAccountToken( const AccountPtr &account, KGAPI2::Job *restartJob ) +void GoogleResource::updateAccountToken(const AccountPtr &account, KGAPI2::Job *restartJob) { - if ( accountId() > 0 ) { - configureKAccounts( accountId(), restartJob ); - } else if ( !settings()->account().isEmpty() ) { - AuthJob *authJob = new AuthJob( account, settings()->clientId(), settings()->clientSecret(), this ); - authJob->setProperty( JOB_PROPERTY, QVariant::fromValue( restartJob ) ); - connect( authJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotAuthJobFinished(KGAPI2::Job*)) ); + if (accountId() > 0) { + configureKAccounts(accountId(), restartJob); + } else if (!settings()->account().isEmpty()) { + AuthJob *authJob = new AuthJob(account, settings()->clientId(), settings()->clientSecret(), this); + authJob->setProperty(JOB_PROPERTY, QVariant::fromValue(restartJob)); + connect(authJob, &AuthJob::finished, this, &GoogleResource::slotAuthJobFinished); } } - void GoogleResource::reloadConfig() { const QString accountName = settings()->account(); - if ( accountId() > 0 ) { - if ( !configureKAccounts( accountId() ) ) { - emit status( Broken ); + if (accountId() > 0) { + if (!configureKAccounts(accountId())) { + Q_EMIT status(Broken); return; } - } else if ( !accountName.isEmpty() ) { - if ( !configureKGAPIAccount( m_accountMgr->findAccount( accountName ) ) ) { - emit status( NotConfigured, i18n( "Configured account does not exist" ) ); + } else if (!accountName.isEmpty()) { + if (!configureKGAPIAccount(m_accountMgr->findAccount(accountName))) { + Q_EMIT status(NotConfigured, i18n("Configured account does not exist")); return; } } else { - emit status( NotConfigured ); + Q_EMIT status(NotConfigured); return; } - emit status( Idle, i18nc( "@info:status", "Ready" ) ); + Q_EMIT status(Idle, i18nc("@info:status", "Ready")); } -bool GoogleResource::configureKAccounts( int accountId, KGAPI2::Job *restartJob ) +bool GoogleResource::configureKAccounts(int accountId, KGAPI2::Job *restartJob) { - if ( accountId == 0 ) { + if (accountId == 0) { return false; } #ifdef HAVE_ACCOUNTS - GetCredentialsJob *gc = new GetCredentialsJob( accountId, this ); - gc->setProperty( JOB_PROPERTY, QVariant::fromValue( restartJob ) ); - connect( gc, SIGNAL(finished(KJob*)), this, SLOT(slotKAccountsCredentialsReceived(KJob*)) ); + GetCredentialsJob *gc = new GetCredentialsJob(accountId, this); + gc->setProperty(JOB_PROPERTY, QVariant::fromValue(restartJob)); + connect(gc, &GetCredentialsJob::finished, this, &GoogleResource::slotKAccountsCredentialsReceived); gc->start(); // SUCKS! return true; #else - Q_UNUSED( restartJob ); + Q_UNUSED(restartJob); return false; #endif } #ifdef HAVE_ACCOUNTS -void GoogleResource::slotKAccountsCredentialsReceived( KJob *job ) +void GoogleResource::slotKAccountsCredentialsReceived(KJob *job) { - if ( job->error() ) { - emit status( Broken ); + if (job->error()) { + Q_EMIT status(Broken); // FIXME: Fallback to KGAPI account? return; } - GetCredentialsJob *gc = qobject_cast( job ); + GetCredentialsJob *gc = qobject_cast(job); const QVariantMap data = gc->credentialsData(); - const QString accessToken = data.value( QLatin1String( "AccessToken" ) ).toString(); + const QString accessToken = data.value(QStringLiteral("AccessToken")).toString(); // Createa temporary account that we use to fetch full user name - KGAPI2::AccountPtr account( new KGAPI2::Account ); - account->setAccessToken( accessToken ); - account->setScopes( scopes() ); + KGAPI2::AccountPtr account(new KGAPI2::Account); + account->setAccessToken(accessToken); + account->setScopes(scopes()); KGAPI2::Job *otherJob = 0; - if ( !job->property( JOB_PROPERTY ).isNull() ) { - otherJob = job->property( JOB_PROPERTY ).value(); + if (!job->property(JOB_PROPERTY).isNull()) { + otherJob = job->property(JOB_PROPERTY).value(); } - if ( settings()->accountName().isEmpty() ) { - account->setAccountName( i18n( "Unknown Account" ) ); - AccountInfoFetchJob *aiJob = new AccountInfoFetchJob( account, this ); - aiJob->setProperty( ACCESS_TOKEN_PROPERTY, accessToken ); - if ( otherJob ) { - aiJob->setProperty( JOB_PROPERTY, QVariant::fromValue( otherJob ) ); + if (settings()->accountName().isEmpty()) { + account->setAccountName(i18n("Unknown Account")); + AccountInfoFetchJob *aiJob = new AccountInfoFetchJob(account, this); + aiJob->setProperty(ACCESS_TOKEN_PROPERTY, accessToken); + if (otherJob) { + aiJob->setProperty(JOB_PROPERTY, QVariant::fromValue(otherJob)); } - connect( aiJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotKAccountsAccountInfoReceived(KGAPI2::Job*)) ); + connect(aiJob, &AccountInfoFetchJob::finished, this, &GoogleResource::slotKAccountsAccountInfoReceived); } else { - m_account = AccountPtr( new Account( settings()->accountName(), - accessToken ) ); - finishKAccountsAuthentication( otherJob ); + m_account = AccountPtr(new Account(settings()->accountName(), + accessToken)); + finishKAccountsAuthentication(otherJob); } } -void GoogleResource::slotKAccountsAccountInfoReceived( KGAPI2::Job *job ) +void GoogleResource::slotKAccountsAccountInfoReceived(KGAPI2::Job *job) { - if ( !handleError( job ) ) { - emit error( job->errorString() ); - cancelTask( i18n( "Failed to refresh tokens") ); + if (!handleError(job)) { + Q_EMIT error(job->errorString()); + cancelTask(i18n("Failed to refresh tokens")); return; } - AccountInfoFetchJob *aiJob = qobject_cast( job ); - Q_ASSERT( aiJob ); + AccountInfoFetchJob *aiJob = qobject_cast(job); + Q_ASSERT(aiJob); aiJob->deleteLater(); const AccountPtr account = job->account(); - if ( aiJob->items().count() != 1 ) { - kWarning() << "AccountInfoFetchJob returned unexpected amount of results"; - emit error( i18n( "Invalid reply" ) ); - cancelTask( i18n( "Failed to refresh tokens") ); + if (aiJob->items().count() != 1) { + qWarning() << "AccountInfoFetchJob returned unexpected amount of results"; + Q_EMIT error(i18n("Invalid reply")); + cancelTask(i18n("Failed to refresh tokens")); return; } - AccountInfoPtr info = aiJob->items().first().dynamicCast(); - settings()->setAccountName( info->email() ); - m_account = AccountPtr( new Account( info->email(), - aiJob->property( ACCESS_TOKEN_PROPERTY ).toString() ) ); + AccountInfoPtr info = aiJob->items().at(0).dynamicCast(); + settings()->setAccountName(info->email()); + m_account = AccountPtr(new Account(info->email(), + aiJob->property(ACCESS_TOKEN_PROPERTY).toString())); settings()->writeConfig(); KGAPI2::Job *otherJob = 0; - if ( job->property( JOB_PROPERTY ).isNull() ) { - otherJob = job->property( JOB_PROPERTY ).value(); + if (job->property(JOB_PROPERTY).isNull()) { + otherJob = job->property(JOB_PROPERTY).value(); } - finishKAccountsAuthentication( otherJob ); + finishKAccountsAuthentication(otherJob); } -void GoogleResource::finishKAccountsAuthentication( KGAPI2::Job *job ) +void GoogleResource::finishKAccountsAuthentication(KGAPI2::Job *job) { updateResourceName(); - emit status( Idle, i18nc( "@info:status", "Ready" ) ); + Q_EMIT status(Idle, i18nc("@info:status", "Ready")); - if ( job ) { - job->setAccount( m_account ); + if (job) { + job->setAccount(m_account); job->restart(); } else { - synchronize(); + synchronize(); } } #endif // HAVE_ACCOUNTS -bool GoogleResource::configureKGAPIAccount( const AccountPtr &account ) +bool GoogleResource::configureKGAPIAccount(const AccountPtr &account) { m_account = account; return !m_account.isNull(); } -void GoogleResource::slotAccountManagerReady( bool ready ) +void GoogleResource::slotAccountManagerReady(bool ready) { // If the resource have already been configured for KAccounts, then use that - if ( accountId() > 0 ) { + if (accountId() > 0) { return; } - kDebug() << ready; - if ( !ready ) { - emit status( Broken, i18n( "Can't access KWallet" ) ); + qDebug() << ready; + if (!ready) { + Q_EMIT status(Broken, i18n("Can't access KWallet")); return; } const QString accountName = settings()->account(); - if ( accountName.isEmpty() ) { - emit status( NotConfigured ); + if (accountName.isEmpty()) { + Q_EMIT status(NotConfigured); return; } - m_account = m_accountMgr->findAccount( accountName ); - if ( m_account.isNull() ) { - emit status( NotConfigured, i18n( "Configured account does not exist" ) ); + m_account = m_accountMgr->findAccount(accountName); + if (m_account.isNull()) { + Q_EMIT status(NotConfigured, i18n("Configured account does not exist")); return; } - emit status( Idle, i18nc( "@info:status", "Ready" ) ); + Q_EMIT status(Idle, i18nc("@info:status", "Ready")); synchronize(); } -void GoogleResource::slotAccountChanged( const AccountPtr &account ) +void GoogleResource::slotAccountChanged(const AccountPtr &account) { // We don't care when using KAccounts - if ( accountId() > 0 ) { + if (accountId() > 0) { return; } m_account = account; } -void GoogleResource::slotAccountRemoved( const QString &accountName ) +void GoogleResource::slotAccountRemoved(const QString &accountName) { // We don't care when using KAccounts - if ( accountId() > 0 ) { + if (accountId() > 0) { return; } - if ( m_account && m_account->accountName() != accountName ) { + if (m_account && m_account->accountName() != accountName) { return; } - emit status( NotConfigured, i18n( "Configured account has been removed" ) ); + Q_EMIT status(NotConfigured, i18n("Configured account has been removed")); m_account.clear(); settings()->setAccount(QString()); } -bool GoogleResource::handleError( KGAPI2::Job *job ) +bool GoogleResource::handleError(KGAPI2::Job *job) { - if (( job->error() == KGAPI2::NoError ) || ( job->error() == KGAPI2::OK )) { + if ((job->error() == KGAPI2::NoError) || (job->error() == KGAPI2::OK)) { return true; } - if ( job->error() == KGAPI2::Unauthorized ) { - kDebug() << job << job->errorString(); + if (job->error() == KGAPI2::Unauthorized) { + qDebug() << job << job->errorString(); const QList resourceScopes = scopes(); - Q_FOREACH(const QUrl &scope, resourceScopes) { - if ( !m_account->scopes().contains( scope ) ) { - m_account->addScope( scope ); + Q_FOREACH (const QUrl &scope, resourceScopes) { + if (!m_account->scopes().contains(scope)) { + m_account->addScope(scope); } } - updateAccountToken( m_account, job ); + updateAccountToken(m_account, job); return false; } - cancelTask( job->errorString() ); + cancelTask(job->errorString()); job->deleteLater(); return false; } bool GoogleResource::canPerformTask() { - if ( !m_account && accountId() == 0 ) { - cancelTask( i18nc( "@info:status", "Resource is not configured" ) ); - emit status( NotConfigured, i18nc( "@info:status", "Resource is not configured" ) ); + if (!m_account && accountId() == 0) { + cancelTask(i18nc("@info:status", "Resource is not configured")); + Q_EMIT status(NotConfigured, i18nc("@info:status", "Resource is not configured")); return false; } return true; } -void GoogleResource::slotAuthJobFinished( KGAPI2::Job *job ) +void GoogleResource::slotAuthJobFinished(KGAPI2::Job *job) { - kDebug(); + qDebug(); - if ( job->error() != KGAPI2::NoError ) { - cancelTask( i18n( "Failed to refresh tokens" ) ); + if (job->error() != KGAPI2::NoError) { + cancelTask(i18n("Failed to refresh tokens")); return; } - AuthJob *authJob = qobject_cast( job ); + AuthJob *authJob = qobject_cast(job); m_account = authJob->account(); - if ( !m_accountMgr->storeAccount( m_account ) ) { - kWarning() << "Failed to store account in KWallet"; + if (!m_accountMgr->storeAccount(m_account)) { + qWarning() << "Failed to store account in KWallet"; } - KGAPI2::Job *otherJob = job->property( JOB_PROPERTY ).value(); - if ( otherJob ) { + KGAPI2::Job *otherJob = job->property(JOB_PROPERTY).value(); + if (otherJob) { otherJob->setAccount(m_account); otherJob->restart(); } @@ -396,40 +389,40 @@ job->deleteLater(); } -void GoogleResource::slotGenericJobFinished( KGAPI2::Job *job ) +void GoogleResource::slotGenericJobFinished(KGAPI2::Job *job) { - if ( !handleError( job ) ) { + if (!handleError(job)) { return; } - const Item item = job->property( ITEM_PROPERTY ).value(); - const Collection collection = job->property( COLLECTION_PROPERTY ).value(); - if ( item.isValid() ) { - changeCommitted( item ); - } else if ( collection.isValid() ) { - changeCommitted( collection ); + const Item item = job->property(ITEM_PROPERTY).value(); + const Collection collection = job->property(COLLECTION_PROPERTY).value(); + if (item.isValid()) { + changeCommitted(item); + } else if (collection.isValid()) { + changeCommitted(collection); } else { taskDone(); } - emit status( Idle, i18nc( "@info:status", "Ready" ) ); + Q_EMIT status(Idle, i18nc("@info:status", "Ready")); job->deleteLater(); } -void GoogleResource::emitPercent( KGAPI2::Job *job, int processedItems, int totalItems ) +void GoogleResource::emitPercent(KGAPI2::Job *job, int processedItems, int totalItems) { - Q_UNUSED( job ); + Q_UNUSED(job); - emit percent( ( ( float ) processedItems / ( float ) totalItems ) * 100 ); + Q_EMIT percent(((float) processedItems / (float) totalItems) * 100); } -bool GoogleResource::retrieveItem( const Item &item, const QSet< QByteArray > &parts ) +bool GoogleResource::retrieveItem(const Item &item, const QSet< QByteArray > &parts) { - Q_UNUSED( parts ); + Q_UNUSED(parts); /* We don't support fetching parts, the item is already fully stored. */ - itemRetrieved( item ); + itemRetrieved(item); return true; } diff -Nru kdepim-runtime-4.14.6/resources/google/common/googleresource.h kdepim-runtime-15.08.0/resources/google/common/googleresource.h --- kdepim-runtime-4.14.6/resources/google/common/googleresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/common/googleresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -18,16 +18,16 @@ #ifndef GOOGLERESOURCE_H #define GOOGLERESOURCE_H -#include -#include +#include +#include -#include +#include #include "googleaccountmanager.h" -#include +#include -#include +#include #define ITEM_PROPERTY "_AkonadiItem" #define ITEMLIST_PROPERTY "_AkonadiItemList" @@ -42,57 +42,58 @@ class GoogleSettings; class GoogleResource : public Akonadi::ResourceBase, - public Akonadi::AgentBase::ObserverV2 + public Akonadi::AgentBase::ObserverV2 { Q_OBJECT - public: - explicit GoogleResource( const QString &id ); +public: + explicit GoogleResource(const QString &id); virtual ~GoogleResource(); - virtual GoogleSettings* settings() const = 0; + virtual GoogleSettings *settings() const = 0; virtual QList scopes() const = 0; - void cleanup(); + void cleanup() Q_DECL_OVERRIDE; public Q_SLOTS: - virtual void configure( WId windowId ); + void configure(WId windowId) Q_DECL_OVERRIDE; void reloadConfig(); - protected Q_SLOTS: - virtual bool retrieveItem( const Akonadi::Item &item, const QSet< QByteArray > &parts ); +protected Q_SLOTS: + bool retrieveItem(const Akonadi::Item &item, const QSet< QByteArray > &parts) Q_DECL_OVERRIDE; - bool handleError( KGAPI2::Job *job ); + bool handleError(KGAPI2::Job *job); - virtual void slotAuthJobFinished( KGAPI2::Job *job ); - virtual void slotGenericJobFinished( KGAPI2::Job *job ); + virtual void slotAuthJobFinished(KGAPI2::Job *job); + virtual void slotGenericJobFinished(KGAPI2::Job *job); - void emitPercent( KGAPI2::Job* job, int processedCount, int totalCount ); + void emitPercent(KGAPI2::Job *job, int processedCount, int totalCount); virtual void slotAbortRequested(); - virtual void slotAccountManagerReady( bool success ); - virtual void slotAccountChanged( const KGAPI2::AccountPtr &account ); - virtual void slotAccountRemoved( const QString &accountName ); + virtual void slotAccountManagerReady(bool success); + virtual void slotAccountChanged(const KGAPI2::AccountPtr &account); + virtual void slotAccountRemoved(const QString &accountName); #ifdef HAVE_ACCOUNTS - void slotKAccountsCredentialsReceived( KJob *job ); - void slotKAccountsAccountInfoReceived( KGAPI2::Job *job ); - void finishKAccountsAuthentication( KGAPI2::Job* job ); + void slotKAccountsCredentialsReceived(KJob *job); + void slotKAccountsAccountInfoReceived(KGAPI2::Job *job); + void finishKAccountsAuthentication(KGAPI2::Job *job); #endif // HAVE_ACCOUNTS - protected: - bool configureKAccounts( int accountId, KGAPI2::Job *restartJob = 0 ); - bool configureKGAPIAccount( const KGAPI2::AccountPtr &account ); - void updateAccountToken( const KGAPI2::AccountPtr &account, KGAPI2::Job *restartJob = 0 ); +protected: + bool configureKAccounts(int accountId, KGAPI2::Job *restartJob = Q_NULLPTR); + bool configureKGAPIAccount(const KGAPI2::AccountPtr &account); + void updateAccountToken(const KGAPI2::AccountPtr &account, KGAPI2::Job *restartJob = Q_NULLPTR); template - bool canPerformTask( const Akonadi::Item &item, const QString &mimeType = QString() ) { - if ( item.isValid() && !item.hasPayload()) { - cancelTask( i18n( "Invalid item payload." ) ); + bool canPerformTask(const Akonadi::Item &item, const QString &mimeType = QString()) + { + if (item.isValid() && !item.hasPayload()) { + cancelTask(i18n("Invalid item payload.")); return false; - } else if ( item.isValid() && mimeType != item.mimeType() ) { - cancelTask( i18n( "Invalid payload mimetype. Expected %1, found %2", mimeType, item.mimeType() ) ); + } else if (item.isValid() && mimeType != item.mimeType()) { + cancelTask(i18n("Invalid payload mimetype. Expected %1, found %2", mimeType, item.mimeType())); return false; } @@ -109,16 +110,14 @@ */ int accountId() const; + GoogleAccountManager *accountManager() const; - GoogleAccountManager* accountManager() const; + void aboutToQuit() Q_DECL_OVERRIDE; - virtual void aboutToQuit(); - - - virtual int runConfigurationDialog( WId windowId ) = 0; + virtual int runConfigurationDialog(WId windowId) = 0; virtual void updateResourceName() = 0; - private: +private: void abort(); bool m_isConfiguring; diff -Nru kdepim-runtime-4.14.6/resources/google/common/googlesettings.cpp kdepim-runtime-15.08.0/resources/google/common/googlesettings.cpp --- kdepim-runtime-4.14.6/resources/google/common/googlesettings.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/common/googlesettings.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -25,20 +25,20 @@ QString GoogleSettings::clientId() const { - return QLatin1String("554041944266.apps.googleusercontent.com"); + return QStringLiteral("554041944266.apps.googleusercontent.com"); } QString GoogleSettings::clientSecret() const { - return QLatin1String("mdT1DjzohxN3npUUzkENT0gO"); + return QStringLiteral("mdT1DjzohxN3npUUzkENT0gO"); } -void GoogleSettings::setWindowId( WId id ) +void GoogleSettings::setWindowId(WId id) { m_winId = id; } -void GoogleSettings::setResourceId( const QString &resourceIdentificator ) +void GoogleSettings::setResourceId(const QString &resourceIdentificator) { m_resourceId = resourceIdentificator; } @@ -48,8 +48,8 @@ return SettingsBase::account(); } -void GoogleSettings::setAccount( const QString &account ) +void GoogleSettings::setAccount(const QString &account) { - SettingsBase::setAccount( account ); + SettingsBase::setAccount(account); } diff -Nru kdepim-runtime-4.14.6/resources/google/common/googlesettingsdialog.cpp kdepim-runtime-15.08.0/resources/google/common/googlesettingsdialog.cpp --- kdepim-runtime-4.14.6/resources/google/common/googlesettingsdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/common/googlesettingsdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,89 +21,104 @@ #include "googleresource.h" #include "settings.h" -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include -#include -#include - -Q_DECLARE_METATYPE( KGAPI2::Job* ) +Q_DECLARE_METATYPE(KGAPI2::Job *) using namespace KGAPI2; -GoogleSettingsDialog::GoogleSettingsDialog( GoogleAccountManager *accountManager, WId wId, GoogleResource *parent ): - KDialog(), - m_parentResource( parent ), - m_accountManager( accountManager ) -{ - KWindowSystem::setMainWindow( this, wId ); - setButtons( Ok | Cancel ); - - connect( this, SIGNAL(accepted()), - this, SLOT(slotSaveSettings()) ); - - QWidget *widget = new QWidget( this ); - QVBoxLayout *mainLayout = new QVBoxLayout( widget ); - setMainWidget( widget ); - - m_accGroupBox = new QGroupBox( i18n( "Accounts" ), this ); - mainLayout->addWidget( m_accGroupBox ); - QHBoxLayout *accLayout = new QHBoxLayout( m_accGroupBox ); - - m_accComboBox = new KComboBox( m_accGroupBox ); - accLayout->addWidget( m_accComboBox, 1 ); - connect( m_accComboBox, SIGNAL(currentIndexChanged(QString)), - this, SIGNAL(currentAccountChanged(QString)) ); - - m_addAccButton = new KPushButton( KIcon( QLatin1String("list-add-user") ), i18n( "&Add" ), m_accGroupBox ); - accLayout->addWidget( m_addAccButton ); - connect( m_addAccButton, SIGNAL(clicked(bool)), - this, SLOT(slotAddAccountClicked()) ); - - m_removeAccButton = new KPushButton( KIcon( QLatin1String("list-remove-user") ), i18n( "&Remove" ), m_accGroupBox ); - accLayout->addWidget( m_removeAccButton ); - connect( m_removeAccButton, SIGNAL(clicked(bool)), - this, SLOT(slotRemoveAccountClicked()) ); - - QGroupBox *refreshBox = new QGroupBox( i18n( "Refresh" ), this ); - mainLayout->addWidget( refreshBox ); - QGridLayout *refreshLayout = new QGridLayout( refreshBox ); - - m_enableRefresh = new QCheckBox( i18n( "Enable interval refresh" ), refreshBox ); - m_enableRefresh->setChecked( Settings::self()->enableIntervalCheck() ); - refreshLayout->addWidget( m_enableRefresh, 0, 0, 1, 2 ); - - QLabel *label = new QLabel( i18n( "Refresh interval:" ) ); - refreshLayout->addWidget( label, 1, 0 ); - m_refreshSpinBox = new KIntSpinBox( 10, 720, 1, 30, this, 10 ); - m_refreshSpinBox->setSuffix( ki18np( " minute", " minutes" ) ); - m_refreshSpinBox->setEnabled( Settings::self()->enableIntervalCheck() ); - refreshLayout->addWidget( m_refreshSpinBox, 1, 1 ); - connect( m_enableRefresh, SIGNAL(toggled(bool)), - m_refreshSpinBox, SLOT(setEnabled(bool)) ); +GoogleSettingsDialog::GoogleSettingsDialog(GoogleAccountManager *accountManager, WId wId, GoogleResource *parent): + QDialog(), + m_parentResource(parent), + m_accountManager(accountManager) +{ + KWindowSystem::setMainWindow(this, wId); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + QVBoxLayout *topLayout = new QVBoxLayout; + setLayout(topLayout); + QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); + okButton->setDefault(true); + okButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &GoogleSettingsDialog::slotSaveSettings); + connect(buttonBox, &QDialogButtonBox::rejected, this, &GoogleSettingsDialog::reject); + + QWidget *widget = new QWidget(this); + topLayout->addWidget(widget); + topLayout->addWidget(buttonBox); + QVBoxLayout *mainLayout = new QVBoxLayout(widget); + m_mainLayout = mainLayout; + + m_accGroupBox = new QGroupBox(i18n("Accounts"), this); + mainLayout->addWidget(m_accGroupBox); + QHBoxLayout *accLayout = new QHBoxLayout(m_accGroupBox); + + m_accComboBox = new KComboBox(m_accGroupBox); + accLayout->addWidget(m_accComboBox, 1); + connect(m_accComboBox, static_cast(&KComboBox::currentIndexChanged), this, &GoogleSettingsDialog::currentAccountChanged); + + m_addAccButton = new QPushButton(QIcon::fromTheme(QStringLiteral("list-add-user")), i18n("&Add"), m_accGroupBox); + accLayout->addWidget(m_addAccButton); + connect(m_addAccButton, &QPushButton::clicked, this, &GoogleSettingsDialog::slotAddAccountClicked); + + m_removeAccButton = new QPushButton(QIcon::fromTheme(QStringLiteral("list-remove-user")), i18n("&Remove"), m_accGroupBox); + accLayout->addWidget(m_removeAccButton); + connect(m_removeAccButton, &QPushButton::clicked, this, &GoogleSettingsDialog::slotRemoveAccountClicked); + + QGroupBox *refreshBox = new QGroupBox(i18n("Refresh"), this); + mainLayout->addWidget(refreshBox); + QGridLayout *refreshLayout = new QGridLayout(refreshBox); + + m_enableRefresh = new QCheckBox(i18n("Enable interval refresh"), refreshBox); + m_enableRefresh->setChecked(Settings::self()->enableIntervalCheck()); + refreshLayout->addWidget(m_enableRefresh, 0, 0, 1, 2); + + QLabel *label = new QLabel(i18n("Refresh interval:")); + refreshLayout->addWidget(label, 1, 0); + m_refreshSpinBox = new KPluralHandlingSpinBox(this); + m_refreshSpinBox->setMaximum(720); + m_refreshSpinBox->setMinimum(10); + m_refreshSpinBox->setSingleStep(1); + m_refreshSpinBox->setValue(30); + m_refreshSpinBox->setDisplayIntegerBase(10); + m_refreshSpinBox->setSuffix(ki18np(" minute", " minutes")); + m_refreshSpinBox->setEnabled(Settings::self()->enableIntervalCheck()); + refreshLayout->addWidget(m_refreshSpinBox, 1, 1); + connect(m_enableRefresh, &QCheckBox::toggled, m_refreshSpinBox, &KPluralHandlingSpinBox::setEnabled); - if ( m_enableRefresh->isEnabled() ) { - m_refreshSpinBox->setValue( Settings::self()->intervalCheckTime() ); + if (m_enableRefresh->isEnabled()) { + m_refreshSpinBox->setValue(Settings::self()->intervalCheckTime()); } - QMetaObject::invokeMethod( this, "reloadAccounts", Qt::QueuedConnection ); + QMetaObject::invokeMethod(this, "reloadAccounts", Qt::QueuedConnection); } GoogleSettingsDialog::~GoogleSettingsDialog() { } +QVBoxLayout *GoogleSettingsDialog::mainLayout() const +{ + return m_mainLayout; +} + GoogleAccountManager *GoogleSettingsDialog::accountManager() const { return m_accountManager; @@ -111,133 +126,131 @@ KGAPI2::AccountPtr GoogleSettingsDialog::currentAccount() const { - return m_accountManager->findAccount( m_accComboBox->currentText() ); + return m_accountManager->findAccount(m_accComboBox->currentText()); } void GoogleSettingsDialog::reloadAccounts() { - disconnect( m_accComboBox, SIGNAL(currentIndexChanged(QString)), - this, SIGNAL(currentAccountChanged(QString)) ); + disconnect(m_accComboBox, SIGNAL(currentIndexChanged(QString)), + this, SIGNAL(currentAccountChanged(QString))); m_accComboBox->clear(); const AccountsList accounts = m_accountManager->listAccounts(); - Q_FOREACH( const AccountPtr &account, accounts ) { - m_accComboBox->addItem( account->accountName() ); + Q_FOREACH (const AccountPtr &account, accounts) { + m_accComboBox->addItem(account->accountName()); } - int index = m_accComboBox->findText( m_parentResource->settings()->account(), Qt::MatchExactly ); - if ( index > -1 ) { - m_accComboBox->setCurrentIndex( index ); + int index = m_accComboBox->findText(m_parentResource->settings()->account(), Qt::MatchExactly); + if (index > -1) { + m_accComboBox->setCurrentIndex(index); } - disconnect( m_accComboBox, SIGNAL(currentIndexChanged(QString)), - this, SIGNAL(currentAccountChanged(QString)) ); + disconnect(m_accComboBox, SIGNAL(currentIndexChanged(QString)), + this, SIGNAL(currentAccountChanged(QString))); - Q_EMIT currentAccountChanged( m_accComboBox->currentText() ); + Q_EMIT currentAccountChanged(m_accComboBox->currentText()); } void GoogleSettingsDialog::slotAddAccountClicked() { - AccountPtr account( new Account() ); + AccountPtr account(new Account()); // FIXME: We need a proper API for this - account->addScope( Account::contactsScopeUrl() ); - account->addScope( Account::calendarScopeUrl() ); - account->addScope( Account::tasksScopeUrl() ); - account->addScope( Account::accountInfoEmailScopeUrl() ); - account->addScope( Account::accountInfoScopeUrl() ); - - AuthJob *authJob = new AuthJob( account, - m_parentResource->settings()->clientId(), - m_parentResource->settings()->clientSecret() ); - connect( authJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotAccountAuthenticated(KGAPI2::Job*)) ); + account->addScope(Account::contactsScopeUrl()); + account->addScope(Account::calendarScopeUrl()); + account->addScope(Account::tasksScopeUrl()); + account->addScope(Account::accountInfoEmailScopeUrl()); + account->addScope(Account::accountInfoScopeUrl()); + + AuthJob *authJob = new AuthJob(account, + m_parentResource->settings()->clientId(), + m_parentResource->settings()->clientSecret()); + connect(authJob, &AuthJob::finished, this, &GoogleSettingsDialog::slotAccountAuthenticated); } void GoogleSettingsDialog::slotRemoveAccountClicked() { const AccountPtr account = currentAccount(); - if ( !account ) { + if (!account) { return; } - if ( KMessageBox::warningYesNo( + if (KMessageBox::warningYesNo( this, - i18n( "Do you really want to revoke access to account %1?" - "

This will revoke access to all resources using this account!

", - account->accountName() ), - i18n( "Revoke Access?" ), + i18n("Do you really want to revoke access to account %1?" + "

This will revoke access to all resources using this account!

", + account->accountName()), + i18n("Revoke Access?"), KStandardGuiItem::yes(), KStandardGuiItem::no(), QString(), - KMessageBox::Dangerous ) != KMessageBox::Yes ) { + KMessageBox::Dangerous) != KMessageBox::Yes) { return; } - m_accountManager->removeAccount( account->accountName() ); + m_accountManager->removeAccount(account->accountName()); reloadAccounts(); } -void GoogleSettingsDialog::slotAccountAuthenticated( Job *job ) +void GoogleSettingsDialog::slotAccountAuthenticated(Job *job) { - AuthJob *authJob = qobject_cast(job); + AuthJob *authJob = qobject_cast(job); const AccountPtr account = authJob->account(); - if ( !m_accountManager->storeAccount( account ) ) { - kWarning() << "Failed to add account to KWallet"; + if (!m_accountManager->storeAccount(account)) { + qWarning() << "Failed to add account to KWallet"; } reloadAccounts(); } -bool GoogleSettingsDialog::handleError( Job *job ) +bool GoogleSettingsDialog::handleError(Job *job) { - if (( job->error() == KGAPI2::NoError ) || ( job->error() == KGAPI2::OK )) { + if ((job->error() == KGAPI2::NoError) || (job->error() == KGAPI2::OK)) { return true; } - if ( job->error() == KGAPI2::Unauthorized ) { - kDebug() << job << job->errorString(); + if (job->error() == KGAPI2::Unauthorized) { + qDebug() << job << job->errorString(); const AccountPtr account = currentAccount(); const QList resourceScopes = m_parentResource->scopes(); - Q_FOREACH(const QUrl &scope, resourceScopes) { - if ( !account->scopes().contains( scope ) ) { - account->addScope( scope ); + Q_FOREACH (const QUrl &scope, resourceScopes) { + if (!account->scopes().contains(scope)) { + account->addScope(scope); } } - AuthJob *authJob = new AuthJob( account, m_parentResource->settings()->clientId(), - m_parentResource->settings()->clientSecret(), this ); - authJob->setProperty( JOB_PROPERTY, QVariant::fromValue( job ) ); - connect( authJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotAuthJobFinished(KGAPI2::Job*)) ); + AuthJob *authJob = new AuthJob(account, m_parentResource->settings()->clientId(), + m_parentResource->settings()->clientSecret(), this); + authJob->setProperty(JOB_PROPERTY, QVariant::fromValue(job)); + connect(authJob, &AuthJob::finished, this, &GoogleSettingsDialog::slotAuthJobFinished); return false; } - KMessageBox::sorry( this, job->errorString() ); + KMessageBox::sorry(this, job->errorString()); job->deleteLater(); return false; } -void GoogleSettingsDialog::slotAuthJobFinished( Job *job ) +void GoogleSettingsDialog::slotAuthJobFinished(Job *job) { - kDebug(); + qDebug(); - if ( job->error() != KGAPI2::NoError ) { - KMessageBox::sorry( this, job->errorString() ); + if (job->error() != KGAPI2::NoError) { + KMessageBox::sorry(this, job->errorString()); return; } - AuthJob *authJob = qobject_cast( job ); + AuthJob *authJob = qobject_cast(job); const AccountPtr account = authJob->account(); - if ( !m_accountManager->storeAccount( account ) ) { - kWarning() << "Failed to store account in KWallet"; + if (!m_accountManager->storeAccount(account)) { + qWarning() << "Failed to store account in KWallet"; } - KGAPI2::Job *otherJob = job->property( JOB_PROPERTY ).value(); - otherJob->setAccount( account ); + KGAPI2::Job *otherJob = job->property(JOB_PROPERTY).value(); + otherJob->setAccount(account); otherJob->restart(); job->deleteLater(); @@ -245,8 +258,10 @@ void GoogleSettingsDialog::slotSaveSettings() { - Settings::self()->setEnableIntervalCheck( m_enableRefresh->isChecked() ); - Settings::self()->setIntervalCheckTime( m_refreshSpinBox->value() ); + Settings::self()->setEnableIntervalCheck(m_enableRefresh->isChecked()); + Settings::self()->setIntervalCheckTime(m_refreshSpinBox->value()); saveSettings(); + accept(); } + diff -Nru kdepim-runtime-4.14.6/resources/google/common/googlesettingsdialog.h kdepim-runtime-15.08.0/resources/google/common/googlesettingsdialog.h --- kdepim-runtime-4.14.6/resources/google/common/googlesettingsdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/common/googlesettingsdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -18,9 +18,9 @@ #ifndef GOOGLESETTINGSDIALOG_H #define GOOGLESETTINGSDIALOG_H -#include +#include -#include +#include namespace KGAPI2 { @@ -34,47 +34,50 @@ class QGroupBox; class KComboBox; class QCheckBox; -class KIntSpinBox; +class KPluralHandlingSpinBox; +class QPushButton; +class QVBoxLayout; - -class GoogleSettingsDialog : public KDialog +class GoogleSettingsDialog : public QDialog { Q_OBJECT - public: - explicit GoogleSettingsDialog( GoogleAccountManager *accountManager, WId wId, GoogleResource *parent ); +public: + explicit GoogleSettingsDialog(GoogleAccountManager *accountManager, WId wId, GoogleResource *parent); virtual ~GoogleSettingsDialog(); - GoogleAccountManager* accountManager() const; + GoogleAccountManager *accountManager() const; KGAPI2::AccountPtr currentAccount() const; - public Q_SLOTS: +public Q_SLOTS: void reloadAccounts(); - Q_SIGNALS: - void currentAccountChanged( const QString &accountName ); +Q_SIGNALS: + void currentAccountChanged(const QString &accountName); - protected: - bool handleError( KGAPI2::Job *job ); +protected: + bool handleError(KGAPI2::Job *job); virtual void saveSettings() = 0; + QVBoxLayout *mainLayout() const; - private Q_SLOTS: +private Q_SLOTS: void slotSaveSettings(); void slotAddAccountClicked(); void slotRemoveAccountClicked(); - void slotAuthJobFinished( KGAPI2::Job *job ); - void slotAccountAuthenticated( KGAPI2::Job *job ); + void slotAuthJobFinished(KGAPI2::Job *job); + void slotAccountAuthenticated(KGAPI2::Job *job); - private: +private: GoogleResource *m_parentResource; GoogleAccountManager *m_accountManager; QGroupBox *m_accGroupBox; - KPushButton *m_addAccButton; - KPushButton *m_removeAccButton; + QPushButton *m_addAccButton; + QPushButton *m_removeAccButton; KComboBox *m_accComboBox; QCheckBox *m_enableRefresh; - KIntSpinBox *m_refreshSpinBox; + KPluralHandlingSpinBox *m_refreshSpinBox; + QVBoxLayout *m_mainLayout; }; diff -Nru kdepim-runtime-4.14.6/resources/google/common/googlesettings.h kdepim-runtime-15.08.0/resources/google/common/googlesettings.h --- kdepim-runtime-4.14.6/resources/google/common/googlesettings.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/common/googlesettings.h 2015-08-10 21:01:02.000000000 +0000 @@ -15,7 +15,6 @@ along with this program. If not, see . */ - #ifndef GOOGLESETTINGS_H #define GOOGLESETTINGS_H @@ -33,12 +32,12 @@ */ class GoogleSettings: public SettingsBase { - Q_OBJECT + Q_OBJECT - public: +public: GoogleSettings(); - void setWindowId( WId id ); - void setResourceId( const QString &resourceIdentifier ); + void setWindowId(WId id); + void setResourceId(const QString &resourceIdentifier); QString appId() const; @@ -48,11 +47,10 @@ virtual QString account() const; virtual void setAccount(const QString &account); - private: +private: WId m_winId; QString m_resourceId; }; - #endif // GOOGLESETTINGS_H diff -Nru kdepim-runtime-4.14.6/resources/google/contacts/CMakeLists.txt kdepim-runtime-15.08.0/resources/google/contacts/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/google/contacts/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/contacts/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,4 +1,5 @@ -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}") + +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_googlecontacts_resource\") set(contactsresource_SRCS contactsresource.cpp @@ -11,21 +12,21 @@ ${accounts_SRCS} ) -kde4_add_kcfg_files(contactsresource_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/settingsbase.kcfgc) +kconfig_add_kcfg_files(contactsresource_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/settingsbase.kcfgc) kcfg_generate_dbus_interface( ${CMAKE_CURRENT_SOURCE_DIR}/settingsbase.kcfg org.kde.Akonadi.GoogleContacts.Settings ) -qt4_add_dbus_adaptor(contactsresource_SRCS +qt5_add_dbus_adaptor(contactsresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.GoogleContacts.Settings.xml ${CMAKE_CURRENT_SOURCE_DIR}/settings.h Settings ) -kde4_add_executable(akonadi_googlecontacts_resource RUN_UNINSTALLED ${contactsresource_SRCS}) +add_executable(akonadi_googlecontacts_resource ${contactsresource_SRCS}) -if(Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_googlecontacts_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../../Info.plist.template ) @@ -39,14 +40,13 @@ target_link_libraries(akonadi_googlecontacts_resource - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KABC_LIBS} - ${QT_QTCORE_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ${QT_QTNETWORK_LIBRARY} - ${KDE4_KDECORE_LIBS} - ${KDE4_KIO_LIBS} - ${LibKGAPI2_LIBRARY} + KF5::AkonadiCore + KF5::Contacts + KF5::KIOCore + KF5::GAPICore + KF5::GAPIContacts + KF5::AkonadiAgentBase + KF5::Wallet ) if(${AccountsQt_FOUND} AND ${SignOnQt_FOUND}) @@ -55,9 +55,9 @@ ${SIGNONQT_LIBRARIES}) endif() -install(TARGETS akonadi_googlecontacts_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(TARGETS akonadi_googlecontacts_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install( FILES googlecontactsresource.desktop - DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" + DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) diff -Nru kdepim-runtime-4.14.6/resources/google/contacts/contactsresource.cpp kdepim-runtime-15.08.0/resources/google/contacts/contactsresource.cpp --- kdepim-runtime-4.14.6/resources/google/contacts/contactsresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/contacts/contactsresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,50 +19,52 @@ #include "settingsdialog.h" #include "settings.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MYCONTACTS_REMOTEID QLatin1String( "MyContacts" ) -#define OTHERCONTACTS_REMOTEID QLatin1String( "OtherContacts" ) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define MYCONTACTS_REMOTEID QStringLiteral( "MyContacts" ) +#define OTHERCONTACTS_REMOTEID QStringLiteral( "OtherContacts" ) -Q_DECLARE_METATYPE( KGAPI2::Job * ) -Q_DECLARE_METATYPE( QList ) +Q_DECLARE_METATYPE(KGAPI2::Job *) +Q_DECLARE_METATYPE(QList) using namespace Akonadi; using namespace KGAPI2; -ContactsResource::ContactsResource( const QString &id ): - GoogleResource( id ) +ContactsResource::ContactsResource(const QString &id): + GoogleResource(id) { updateResourceName(); } @@ -76,19 +78,19 @@ return Settings::self(); } -int ContactsResource::runConfigurationDialog( WId windowId ) +int ContactsResource::runConfigurationDialog(WId windowId) { - QScopedPointer settingsDialog( new SettingsDialog( accountManager(), windowId, this ) ); - settingsDialog->setWindowIcon( KIcon( QLatin1String("im-google") ) ); + QScopedPointer settingsDialog(new SettingsDialog(accountManager(), windowId, this)); + settingsDialog->setWindowIcon(QIcon::fromTheme(QStringLiteral("im-google"))); - return settingsDialog->exec(); + return settingsDialog->exec(); } void ContactsResource::updateResourceName() { const QString accountName = Settings::self()->account(); - setName( i18nc( "%1 is account name (user@gmail.com)", "Google Contacts (%1)", accountName.isEmpty() ? i18n( "not configured" ) : accountName ) ); + setName(i18nc("%1 is account name (user@gmail.com)", "Google Contacts (%1)", accountName.isEmpty() ? i18n("not configured") : accountName)); } QList< QUrl > ContactsResource::scopes() const @@ -99,366 +101,347 @@ return scopes; } -void ContactsResource::retrieveItems( const Collection &collection ) +void ContactsResource::retrieveItems(const Collection &collection) { - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } // All items are only in top-level collection and Other Contacts collection - if ( ( collection.remoteId() != m_rootCollection.remoteId() ) && - ( collection.remoteId() != OTHERCONTACTS_REMOTEID ) ) { + if ((collection.remoteId() != m_rootCollection.remoteId()) && + (collection.remoteId() != OTHERCONTACTS_REMOTEID)) { itemsRetrievalDone(); return; } - ContactFetchJob *fetchJob = new ContactFetchJob( account(), this ); - fetchJob->setProperty( COLLECTION_PROPERTY, QVariant::fromValue( collection ) ); - fetchJob->setFetchDeleted( true ); - if ( !collection.remoteRevision().isEmpty() ) { - fetchJob->setFetchOnlyUpdated( collection.remoteRevision().toLongLong() ); + ContactFetchJob *fetchJob = new ContactFetchJob(account(), this); + fetchJob->setProperty(COLLECTION_PROPERTY, QVariant::fromValue(collection)); + fetchJob->setFetchDeleted(true); + if (!collection.remoteRevision().isEmpty()) { + fetchJob->setFetchOnlyUpdated(collection.remoteRevision().toLongLong()); } - connect( fetchJob, SIGNAL(progress(KGAPI2::Job*,int,int)), - this, SLOT(emitPercent(KGAPI2::Job*,int,int)) ); - connect( fetchJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotItemsRetrieved(KGAPI2::Job*)) ); + connect(fetchJob, &ContactFetchJob::progress, this, &ContactsResource::emitPercent); + connect(fetchJob, &ContactFetchJob::finished, this, &ContactsResource::slotItemsRetrieved); } -void ContactsResource::retrieveContactsPhotos( const QVariant &arguments ) +void ContactsResource::retrieveContactsPhotos(const QVariant &arguments) { - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } const QVariantMap map = arguments.toMap(); - const Collection collection = map[ QLatin1String("collection") ].value(); - ItemFetchJob *itemFetchJob = new ItemFetchJob( collection, this ); - itemFetchJob->setProperty( "modifiedItems", map[ QLatin1String("modifiedItems") ] ); + const Collection collection = map[ QStringLiteral("collection") ].value(); + ItemFetchJob *itemFetchJob = new ItemFetchJob(collection, this); + itemFetchJob->setProperty("modifiedItems", map[ QStringLiteral("modifiedItems") ]); itemFetchJob->fetchScope().fetchFullPayload(true); - connect( itemFetchJob, SIGNAL(finished(KJob*)), - this, SLOT(slotUpdatePhotosItemsRetrieved(KJob*)) ); - emit status( Running, i18nc( "@info:status", "Retrieving photos" ) ); + connect(itemFetchJob, &ItemFetchJob::finished, this, &ContactsResource::slotUpdatePhotosItemsRetrieved); + Q_EMIT status(Running, i18nc("@info:status", "Retrieving photos")); } void ContactsResource::retrieveCollections() { - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } - ContactsGroupFetchJob *fetchJob = new ContactsGroupFetchJob( account(), this ); - connect( fetchJob, SIGNAL(progress(KGAPI2::Job*,int,int)), - this, SLOT(emitPercent(KGAPI2::Job*,int,int)) ); - connect( fetchJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotCollectionsRetrieved(KGAPI2::Job*)) ); + ContactsGroupFetchJob *fetchJob = new ContactsGroupFetchJob(account(), this); + connect(fetchJob, &ContactFetchJob::progress, this, &ContactsResource::emitPercent); + connect(fetchJob, &ContactFetchJob::finished, this, &ContactsResource::slotCollectionsRetrieved); } -void ContactsResource::itemAdded( const Item &item, const Collection &collection ) +void ContactsResource::itemAdded(const Item &item, const Collection &collection) { - if ( !canPerformTask( item, KABC::Addressee::mimeType() ) ) { + if (!canPerformTask(item, KContacts::Addressee::mimeType())) { return; } - KABC::Addressee addressee = item.payload< KABC::Addressee >(); - ContactPtr contact( new Contact( addressee ) ); + KContacts::Addressee addressee = item.payload< KContacts::Addressee >(); + ContactPtr contact(new Contact(addressee)); /* If the contact has been moved into My Contacts group then modify the membership */ - if ( collection.remoteId() == MYCONTACTS_REMOTEID ) { - contact->addGroup( QString::fromLatin1( "http://www.google.com/m8/feeds/groups/%1/base/6" ).arg( QString::fromLatin1( QUrl::toPercentEncoding( account()->accountName() ) ) ) ); + if (collection.remoteId() == MYCONTACTS_REMOTEID) { + contact->addGroup(QString::fromLatin1("http://www.google.com/m8/feeds/groups/%1/base/6").arg(QString::fromLatin1(QUrl::toPercentEncoding(account()->accountName())))); } /* If the contact has been moved to Other Contacts then remove all groups */ - if ( collection.remoteId() == OTHERCONTACTS_REMOTEID ) { + if (collection.remoteId() == OTHERCONTACTS_REMOTEID) { contact->clearGroups(); } - ContactCreateJob *createJob = new ContactCreateJob( contact, account(), this ); - createJob->setProperty( ITEM_PROPERTY, QVariant::fromValue( item ) ); - connect( createJob, SIGNAL(progress(KGAPI2::Job*,int,int)), - this, SLOT(emitPercent(KGAPI2::Job*,int,int)) ); - connect( createJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotCreateJobFinished(KGAPI2::Job*)) ); + ContactCreateJob *createJob = new ContactCreateJob(contact, account(), this); + createJob->setProperty(ITEM_PROPERTY, QVariant::fromValue(item)); + connect(createJob, &ContactCreateJob::progress, this, &ContactsResource::emitPercent); + connect(createJob, &ContactCreateJob::finished, this, &ContactsResource::slotCreateJobFinished); } -void ContactsResource::itemChanged( const Item &item, const QSet< QByteArray > &partIdentifiers ) +void ContactsResource::itemChanged(const Item &item, const QSet< QByteArray > &partIdentifiers) { - Q_UNUSED( partIdentifiers ); + Q_UNUSED(partIdentifiers); - if ( !canPerformTask( item, KABC::Addressee::mimeType() ) ) { + if (!canPerformTask(item, KContacts::Addressee::mimeType())) { return; } - KABC::Addressee addressee = item.payload< KABC::Addressee >(); - ContactPtr contact( new Contact( addressee ) ); + KContacts::Addressee addressee = item.payload< KContacts::Addressee >(); + ContactPtr contact(new Contact(addressee)); - if ( item.parentCollection().remoteId() == MYCONTACTS_REMOTEID ) { - contact->addGroup( QString::fromLatin1( "http://www.google.com/m8/feeds/groups/%1/base/6" ).arg( QString::fromLatin1( QUrl::toPercentEncoding( account()->accountName() ) ) ) ); + if (item.parentCollection().remoteId() == MYCONTACTS_REMOTEID) { + contact->addGroup(QString::fromLatin1("http://www.google.com/m8/feeds/groups/%1/base/6").arg(QString::fromLatin1(QUrl::toPercentEncoding(account()->accountName())))); } - ContactModifyJob *modifyJob = new ContactModifyJob( contact, account(), this ); - modifyJob->setProperty( ITEM_PROPERTY, QVariant::fromValue( item ) ); - connect( modifyJob, SIGNAL(progress(KGAPI2::Job*,int,int)), - this, SLOT(emitPercent(KGAPI2::Job*,int,int)) ); - connect( modifyJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + ContactModifyJob *modifyJob = new ContactModifyJob(contact, account(), this); + modifyJob->setProperty(ITEM_PROPERTY, QVariant::fromValue(item)); + connect(modifyJob, &ContactModifyJob::progress, this, &ContactsResource::emitPercent); + connect(modifyJob, &ContactModifyJob::finished, this, &ContactsResource::slotGenericJobFinished); } -void ContactsResource::itemMoved( const Item &item, const Collection &collectionSource, - const Collection &collectionDestination ) +void ContactsResource::itemMoved(const Item &item, const Collection &collectionSource, + const Collection &collectionDestination) { - if ( !canPerformTask( item, KABC::Addressee::mimeType() ) ) { + if (!canPerformTask(item, KContacts::Addressee::mimeType())) { return; } - KABC::Addressee addressee = item.payload< KABC::Addressee >(); - ContactPtr contact( new Contact( addressee ) ); + KContacts::Addressee addressee = item.payload< KContacts::Addressee >(); + ContactPtr contact(new Contact(addressee)); // MyContacts -> OtherContacts - if ( collectionSource.remoteId() == MYCONTACTS_REMOTEID && - collectionDestination.remoteId() == OTHERCONTACTS_REMOTEID ) { - contact->removeGroup( QString::fromLatin1( "http://www.google.com/m8/feeds/groups/%1/base/6" ).arg( QString::fromLatin1( QUrl::toPercentEncoding( account()->accountName() ) ) ) ); + if (collectionSource.remoteId() == MYCONTACTS_REMOTEID && + collectionDestination.remoteId() == OTHERCONTACTS_REMOTEID) { + contact->removeGroup(QString::fromLatin1("http://www.google.com/m8/feeds/groups/%1/base/6").arg(QString::fromLatin1(QUrl::toPercentEncoding(account()->accountName())))); // OtherContacts -> MyContacts - } else if ( collectionSource.remoteId() == OTHERCONTACTS_REMOTEID && - collectionDestination.remoteId() == MYCONTACTS_REMOTEID ) { - contact->addGroup( QString::fromLatin1( "http://www.google.com/m8/feeds/groups/%1/base/6" ).arg( QString::fromLatin1( QUrl::toPercentEncoding( account()->accountName() ) ) ) ); + } else if (collectionSource.remoteId() == OTHERCONTACTS_REMOTEID && + collectionDestination.remoteId() == MYCONTACTS_REMOTEID) { + contact->addGroup(QString::fromLatin1("http://www.google.com/m8/feeds/groups/%1/base/6").arg(QString::fromLatin1(QUrl::toPercentEncoding(account()->accountName())))); } else { - cancelTask( i18n( "Invalid source or destination collection" ) ); + cancelTask(i18n("Invalid source or destination collection")); return; } - ContactModifyJob *modifyJob = new ContactModifyJob( contact, account(), this ); - modifyJob->setProperty( ITEM_PROPERTY, QVariant::fromValue( item ) ); - connect( modifyJob, SIGNAL(progress(KGAPI2::Job*,int,int)), - this, SLOT(emitPercent(KGAPI2::Job*,int,int)) ); - connect( modifyJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + ContactModifyJob *modifyJob = new ContactModifyJob(contact, account(), this); + modifyJob->setProperty(ITEM_PROPERTY, QVariant::fromValue(item)); + connect(modifyJob, &ContactModifyJob::progress, this, &ContactsResource::emitPercent); + connect(modifyJob, &ContactModifyJob::finished, this, &ContactsResource::slotGenericJobFinished); } -void ContactsResource::itemRemoved( const Item &item ) +void ContactsResource::itemRemoved(const Item &item) { - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } - ContactDeleteJob *deleteJob = new ContactDeleteJob( item.remoteId(), account(), this ); - deleteJob->setProperty( ITEM_PROPERTY, QVariant::fromValue( item ) ); - connect( deleteJob, SIGNAL(progress(KGAPI2::Job*,int,int)), - this, SLOT(emitPercent(KGAPI2::Job*,int,int)) ); - connect( deleteJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + ContactDeleteJob *deleteJob = new ContactDeleteJob(item.remoteId(), account(), this); + deleteJob->setProperty(ITEM_PROPERTY, QVariant::fromValue(item)); + connect(deleteJob, &ContactDeleteJob::progress, this, &ContactsResource::emitPercent); + connect(deleteJob, &ContactDeleteJob::finished, this, &ContactsResource::slotGenericJobFinished); - emit status( Running, i18nc( "@info:status", "Removing contact" ) ); + Q_EMIT status(Running, i18nc("@info:status", "Removing contact")); } -void ContactsResource::itemLinked( const Item &item, const Collection &collection ) +void ContactsResource::itemLinked(const Item &item, const Collection &collection) { - if ( !canPerformTask( item, KABC::Addressee::mimeType() ) ) { + if (!canPerformTask(item, KContacts::Addressee::mimeType())) { return; } - KABC::Addressee addressee = item.payload(); - ContactPtr contact( new Contact( addressee ) ); + KContacts::Addressee addressee = item.payload(); + ContactPtr contact(new Contact(addressee)); - contact->addGroup( collection.remoteId() ); + contact->addGroup(collection.remoteId()); - ContactModifyJob *modifyJob = new ContactModifyJob( contact, account(), this ); - connect( modifyJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + ContactModifyJob *modifyJob = new ContactModifyJob(contact, account(), this); + connect(modifyJob, &ContactModifyJob::finished, this, &ContactsResource::slotGenericJobFinished); } -void ContactsResource::itemUnlinked( const Item &item, const Collection &collection ) +void ContactsResource::itemUnlinked(const Item &item, const Collection &collection) { - if ( !canPerformTask( item, KABC::Addressee::mimeType() ) ) { + if (!canPerformTask(item, KContacts::Addressee::mimeType())) { return; } - KABC::Addressee addressee = item.payload(); - ContactPtr contact( new Contact( addressee ) ); + KContacts::Addressee addressee = item.payload(); + ContactPtr contact(new Contact(addressee)); - contact->removeGroup( collection.remoteId() ); + contact->removeGroup(collection.remoteId()); - ContactModifyJob *modifyJob = new ContactModifyJob( contact, account(), this ); - modifyJob->setProperty( ITEM_PROPERTY, QVariant::fromValue( item ) ); - connect( modifyJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + ContactModifyJob *modifyJob = new ContactModifyJob(contact, account(), this); + modifyJob->setProperty(ITEM_PROPERTY, QVariant::fromValue(item)); + connect(modifyJob, &ContactModifyJob::finished, this, &ContactsResource::slotGenericJobFinished); } -void ContactsResource::collectionAdded( const Akonadi::Collection &collection, - const Akonadi::Collection &parent ) +void ContactsResource::collectionAdded(const Akonadi::Collection &collection, + const Akonadi::Collection &parent) { - Q_UNUSED( parent ); + Q_UNUSED(parent); - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } - ContactsGroupPtr group( new ContactsGroup ); - group->setTitle( collection.name() ); - group->setIsSystemGroup( false ); + ContactsGroupPtr group(new ContactsGroup); + group->setTitle(collection.name()); + group->setIsSystemGroup(false); - ContactsGroupCreateJob *createJob = new ContactsGroupCreateJob( group, account(), this ); - createJob->setProperty( COLLECTION_PROPERTY, QVariant::fromValue( collection ) ); - connect( createJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotCreateJobFinished(KGAPI2::Job*)) ); + ContactsGroupCreateJob *createJob = new ContactsGroupCreateJob(group, account(), this); + createJob->setProperty(COLLECTION_PROPERTY, QVariant::fromValue(collection)); + connect(createJob, &ContactCreateJob::finished, this, &ContactsResource::slotCreateJobFinished); } -void ContactsResource::collectionChanged( const Akonadi::Collection &collection ) +void ContactsResource::collectionChanged(const Akonadi::Collection &collection) { - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } - ContactsGroupPtr group( new ContactsGroup() ); - group->setId( collection.remoteId() ); + ContactsGroupPtr group(new ContactsGroup()); + group->setId(collection.remoteId()); - group->setTitle( collection.displayName() ); + group->setTitle(collection.displayName()); - ContactsGroupModifyJob *modifyJob = new ContactsGroupModifyJob( group, account(), this ); - modifyJob->setProperty( COLLECTION_PROPERTY, QVariant::fromValue( collection ) ); - connect( modifyJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + ContactsGroupModifyJob *modifyJob = new ContactsGroupModifyJob(group, account(), this); + modifyJob->setProperty(COLLECTION_PROPERTY, QVariant::fromValue(collection)); + connect(modifyJob, &ContactModifyJob::finished, this, &ContactsResource::slotGenericJobFinished); } -void ContactsResource::collectionRemoved( const Akonadi::Collection &collection ) +void ContactsResource::collectionRemoved(const Akonadi::Collection &collection) { - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } - ContactsGroupDeleteJob *deleteJob = new ContactsGroupDeleteJob( collection.remoteId(), account(), this ); - deleteJob->setProperty( COLLECTION_PROPERTY, QVariant::fromValue( collection ) ); - connect( deleteJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + ContactsGroupDeleteJob *deleteJob = new ContactsGroupDeleteJob(collection.remoteId(), account(), this); + deleteJob->setProperty(COLLECTION_PROPERTY, QVariant::fromValue(collection)); + connect(deleteJob, &ContactDeleteJob::finished, this, &ContactsResource::slotGenericJobFinished); } - -void ContactsResource::slotCollectionsRetrieved( KGAPI2::Job *job ) +void ContactsResource::slotCollectionsRetrieved(KGAPI2::Job *job) { - if ( !handleError( job ) ) { + if (!handleError(job)) { return; } - ContactsGroupFetchJob *fetchJob = qobject_cast( job ); + ContactsGroupFetchJob *fetchJob = qobject_cast(job); const ObjectsList objects = fetchJob->items(); CachePolicy cachePolicy; - if ( Settings::self()->enableIntervalCheck() ) { - cachePolicy.setInheritFromParent( false ); - cachePolicy.setIntervalCheckTime( Settings::self()->intervalCheckTime() ); + if (Settings::self()->enableIntervalCheck()) { + cachePolicy.setInheritFromParent(false); + cachePolicy.setIntervalCheckTime(Settings::self()->intervalCheckTime()); } m_rootCollection = Collection(); - m_rootCollection.setContentMimeTypes( QStringList() << Collection::virtualMimeType() - << KABC::Addressee::mimeType() ); - m_rootCollection.setRemoteId( MYCONTACTS_REMOTEID ); - m_rootCollection.setName( fetchJob->account()->accountName() ); - m_rootCollection.setParentCollection( Collection::root() ); - m_rootCollection.setCachePolicy( cachePolicy ); - m_rootCollection.setRights( Collection::CanCreateCollection | - Collection::CanCreateItem | - Collection::CanChangeItem | - Collection::CanDeleteItem); - - EntityDisplayAttribute *attr = m_rootCollection.attribute( Entity::AddIfMissing ); - attr->setDisplayName( fetchJob->account()->accountName() ); - attr->setIconName( QLatin1String( "im-google" ) ); + m_rootCollection.setContentMimeTypes(QStringList() << Collection::virtualMimeType() + << KContacts::Addressee::mimeType()); + m_rootCollection.setRemoteId(MYCONTACTS_REMOTEID); + m_rootCollection.setName(fetchJob->account()->accountName()); + m_rootCollection.setParentCollection(Collection::root()); + m_rootCollection.setCachePolicy(cachePolicy); + m_rootCollection.setRights(Collection::CanCreateCollection | + Collection::CanCreateItem | + Collection::CanChangeItem | + Collection::CanDeleteItem); + + EntityDisplayAttribute *attr = m_rootCollection.attribute(Entity::AddIfMissing); + attr->setDisplayName(fetchJob->account()->accountName()); + attr->setIconName(QStringLiteral("im-google")); m_collections[ MYCONTACTS_REMOTEID ] = m_rootCollection; - foreach( const ObjectPtr & object, objects ) { + foreach (const ObjectPtr &object, objects) { const ContactsGroupPtr group = object.dynamicCast(); QString realName = group->title(); - if ( group->isSystemGroup() ) { - if ( group->title().contains( QLatin1String( "Coworkers" ) ) ) { - realName = i18nc( "Name of a group of contacts", "Coworkers" ); - } else if ( group->title().contains( QLatin1String( "Friends" ) ) ) { - realName = i18nc( "Name of a group of contacts", "Friends" ); - } else if ( group->title().contains( QLatin1String( "Family" ) ) ) { - realName = i18nc( "Name of a group of contacts", "Family" ); - } else if ( group->title().contains( QLatin1String( "My Contacts" ) ) ) { + if (group->isSystemGroup()) { + if (group->title().contains(QStringLiteral("Coworkers"))) { + realName = i18nc("Name of a group of contacts", "Coworkers"); + } else if (group->title().contains(QStringLiteral("Friends"))) { + realName = i18nc("Name of a group of contacts", "Friends"); + } else if (group->title().contains(QStringLiteral("Family"))) { + realName = i18nc("Name of a group of contacts", "Family"); + } else if (group->title().contains(QStringLiteral("My Contacts"))) { // Yes, skip My Contacts group, we store "My Contacts" in root collection continue; } } else { - if ( group->title().contains( QLatin1String( "Other Contacts" ) ) ) { - realName = i18nc( "Name of a group of contacts", "Other Contacts" ); + if (group->title().contains(QStringLiteral("Other Contacts"))) { + realName = i18nc("Name of a group of contacts", "Other Contacts"); } } Collection collection; - collection.setContentMimeTypes( QStringList() << KABC::Addressee::mimeType() ); - collection.setName( group->id() ); - collection.setParentCollection( m_rootCollection ); - collection.setRights( Collection::CanLinkItem | - Collection::CanUnlinkItem | - Collection::CanChangeItem ); - if ( !group->isSystemGroup() ) { - collection.setRights( collection.rights() | - Collection::CanChangeCollection | - Collection::CanDeleteCollection ); + collection.setContentMimeTypes(QStringList() << KContacts::Addressee::mimeType()); + collection.setName(group->id()); + collection.setParentCollection(m_rootCollection); + collection.setRights(Collection::CanLinkItem | + Collection::CanUnlinkItem | + Collection::CanChangeItem); + if (!group->isSystemGroup()) { + collection.setRights(collection.rights() | + Collection::CanChangeCollection | + Collection::CanDeleteCollection); } - collection.setRemoteId( group->id() ); - collection.setVirtual( true ); + collection.setRemoteId(group->id()); + collection.setVirtual(true); - EntityDisplayAttribute *attr = collection.attribute( Entity::AddIfMissing ); - attr->setDisplayName( realName ); - attr->setIconName( QLatin1String("view-pim-contacts") ); + EntityDisplayAttribute *attr = collection.attribute(Entity::AddIfMissing); + attr->setDisplayName(realName); + attr->setIconName(QStringLiteral("view-pim-contacts")); m_collections[ collection.remoteId() ] = collection; } Collection otherCollection; - otherCollection.setContentMimeTypes( QStringList() << KABC::Addressee::mimeType() ); - otherCollection.setName( i18n( "Other Contacts" ) ); - otherCollection.setParentCollection( m_rootCollection ); - otherCollection.setRights( Collection::CanCreateItem | - Collection::CanChangeItem | - Collection::CanDeleteItem ); - otherCollection.setRemoteId( OTHERCONTACTS_REMOTEID ); - - attr = otherCollection.attribute( Entity::AddIfMissing ); - attr->setDisplayName( i18n( "Other Contacts" ) ); - attr->setIconName( QLatin1String("view-pim-contacts") ); + otherCollection.setContentMimeTypes(QStringList() << KContacts::Addressee::mimeType()); + otherCollection.setName(i18n("Other Contacts")); + otherCollection.setParentCollection(m_rootCollection); + otherCollection.setRights(Collection::CanCreateItem | + Collection::CanChangeItem | + Collection::CanDeleteItem); + otherCollection.setRemoteId(OTHERCONTACTS_REMOTEID); + + attr = otherCollection.attribute(Entity::AddIfMissing); + attr->setDisplayName(i18n("Other Contacts")); + attr->setIconName(QStringLiteral("view-pim-contacts")); m_collections[ OTHERCONTACTS_REMOTEID ] = otherCollection; - collectionsRetrieved( m_collections.values() ); + collectionsRetrieved(Akonadi::valuesToVector(m_collections)); job->deleteLater(); } -void ContactsResource::slotItemsRetrieved( KGAPI2::Job *job ) +void ContactsResource::slotItemsRetrieved(KGAPI2::Job *job) { - if ( !handleError( job ) ) { + if (!handleError(job)) { return; } - ContactFetchJob *fetchJob = qobject_cast( job ); + ContactFetchJob *fetchJob = qobject_cast(job); const ObjectsList objects = fetchJob->items(); - Collection collection = fetchJob->property( COLLECTION_PROPERTY ).value(); + Collection collection = fetchJob->property(COLLECTION_PROPERTY).value(); Item::List changedItems, removedItems; QMap groupsMap; QList changedPhotos; - foreach( const ObjectPtr & object, objects ) { + foreach (const ObjectPtr &object, objects) { const ContactPtr contact = object.dynamicCast(); - if ( ( ( collection.remoteId() == OTHERCONTACTS_REMOTEID ) && !contact->groups().isEmpty() ) || - ( ( collection.remoteId() == MYCONTACTS_REMOTEID ) && contact->groups().isEmpty() ) ) { + if (((collection.remoteId() == OTHERCONTACTS_REMOTEID) && !contact->groups().isEmpty()) || + ((collection.remoteId() == MYCONTACTS_REMOTEID) && contact->groups().isEmpty())) { continue; } Item item; - item.setMimeType( KABC::Addressee::mimeType() ); - item.setParentCollection( m_collections[MYCONTACTS_REMOTEID] ); - item.setRemoteId( contact->uid() ); - item.setRemoteRevision( contact->etag() ); - item.setPayload( *contact.dynamicCast() ); + item.setMimeType(KContacts::Addressee::mimeType()); + item.setParentCollection(m_collections[MYCONTACTS_REMOTEID]); + item.setRemoteId(contact->uid()); + item.setRemoteRevision(contact->etag()); + item.setPayload(*contact.dynamicCast()); - if ( contact->deleted() ) { + if (contact->deleted()) { removedItems << item; } else { changedItems << item; @@ -466,112 +449,109 @@ } const QStringList groups = contact->groups(); - foreach( const QString & group, groups ) { + foreach (const QString &group, groups) { groupsMap[group] << item; } } - itemsRetrievedIncremental( changedItems, removedItems ); + itemsRetrievedIncremental(changedItems, removedItems); QMap::ConstIterator iter; - for ( iter = groupsMap.constBegin(); iter != groupsMap.constEnd(); ++iter ) { - new LinkJob( m_collections[iter.key()], iter.value(), this ); + for (iter = groupsMap.constBegin(); iter != groupsMap.constEnd(); ++iter) { + new LinkJob(m_collections[iter.key()], iter.value(), this); } QVariantMap map; - map[QLatin1String("collection")] = QVariant::fromValue(collection); - map[QLatin1String("modifiedItems")] = QVariant::fromValue(changedPhotos); - scheduleCustomTask( this, "retrieveContactsPhotos", map ); + map[QStringLiteral("collection")] = QVariant::fromValue(collection); + map[QStringLiteral("modifiedItems")] = QVariant::fromValue(changedPhotos); + scheduleCustomTask(this, "retrieveContactsPhotos", map); - collection.setRemoteRevision( QString::number( KDateTime::currentUtcDateTime().toTime_t() ) ); - new CollectionModifyJob( collection, this ); + collection.setRemoteRevision(QString::number(KDateTime::currentUtcDateTime().toTime_t())); + new CollectionModifyJob(collection, this); job->deleteLater(); } -void ContactsResource::slotUpdatePhotosItemsRetrieved( KJob *job ) +void ContactsResource::slotUpdatePhotosItemsRetrieved(KJob *job) { - ItemFetchJob *fetchJob = qobject_cast(job); + ItemFetchJob *fetchJob = qobject_cast(job); const Item::List items = fetchJob->items(); - const QList modifiedItems = fetchJob->property( "modifiedItems" ).value< QList >(); + const QList modifiedItems = fetchJob->property("modifiedItems").value< QList >(); ContactsList contacts; - foreach( const Item &item, items ) { - if ( modifiedItems.contains( item.remoteId() )) { - const KABC::Addressee addressee = item.payload(); - const ContactPtr contact( new Contact( addressee ) ); + foreach (const Item &item, items) { + if (modifiedItems.contains(item.remoteId())) { + const KContacts::Addressee addressee = item.payload(); + const ContactPtr contact(new Contact(addressee)); contacts << contact; } } // Make sure account is still valid - if ( !canPerformTask() ) { + if (!canPerformTask()) { return; } - ContactFetchPhotoJob *photoJob = new ContactFetchPhotoJob( contacts, account(), this ); - photoJob->setProperty( ITEMLIST_PROPERTY, QVariant::fromValue( items ) ); - photoJob->setProperty( "processedItems", 0 ); - connect( photoJob, SIGNAL(photoFetched(KGAPI2::Job*,KGAPI2::ContactPtr)), - this, SLOT(slotUpdatePhotoFinished(KGAPI2::Job*,KGAPI2::ContactPtr)) ); - connect( photoJob, SIGNAL(finished(KGAPI2::Job*)), - this, SLOT(slotGenericJobFinished(KGAPI2::Job*)) ); + ContactFetchPhotoJob *photoJob = new ContactFetchPhotoJob(contacts, account(), this); + photoJob->setProperty(ITEMLIST_PROPERTY, QVariant::fromValue(items)); + photoJob->setProperty("processedItems", 0); + connect(photoJob, &ContactFetchPhotoJob::photoFetched, this, &ContactsResource::slotUpdatePhotoFinished); + connect(photoJob, &ContactFetchPhotoJob::finished, this, &ContactsResource::slotGenericJobFinished); } -void ContactsResource::slotUpdatePhotoFinished( KGAPI2::Job *job, const ContactPtr &contact ) +void ContactsResource::slotUpdatePhotoFinished(KGAPI2::Job *job, const ContactPtr &contact) { - Item::List items = job->property( ITEMLIST_PROPERTY ).value(); + Item::List items = job->property(ITEMLIST_PROPERTY).value(); - int processedItems = job->property( "processedItems" ).toInt(); + int processedItems = job->property("processedItems").toInt(); processedItems++; - job->setProperty( "processedItems", processedItems ); - emitPercent( job, processedItems, items.count() ); + job->setProperty("processedItems", processedItems); + emitPercent(job, processedItems, items.count()); - foreach( Item item, items ) { - if ( item.remoteId() == contact->uid() ) { - item.setPayload( *contact.dynamicCast() ); - new ItemModifyJob( item, this ); + foreach (Item item, items) { + if (item.remoteId() == contact->uid()) { + item.setPayload(*contact.dynamicCast()); + new ItemModifyJob(item, this); return; } } } -void ContactsResource::slotCreateJobFinished( KGAPI2::Job* job ) +void ContactsResource::slotCreateJobFinished(KGAPI2::Job *job) { - if ( !handleError( job ) ) { + if (!handleError(job)) { return; } - Item item = job->property( ITEM_PROPERTY ).value(); - Collection collection = job->property( COLLECTION_PROPERTY ).value(); - if ( item.isValid() ) { - ContactCreateJob *createJob = qobject_cast( job ); - Q_ASSERT( createJob->items().count() == 1); - ContactPtr contact = createJob->items().first().dynamicCast(); + Item item = job->property(ITEM_PROPERTY).value(); + Collection collection = job->property(COLLECTION_PROPERTY).value(); + if (item.isValid()) { + ContactCreateJob *createJob = qobject_cast(job); + Q_ASSERT(createJob->items().count() == 1); + ContactPtr contact = createJob->items().at(0).dynamicCast(); - item.setRemoteId( contact->uid() ); - item.setRemoteRevision( contact->etag() ); - changeCommitted( item ); - } else if ( collection.isValid() ) { - ContactsGroupCreateJob *createJob = qobject_cast( job ); - Q_ASSERT( createJob->items().count() == 1); - ContactsGroupPtr group = createJob->items().first().dynamicCast(); + item.setRemoteId(contact->uid()); + item.setRemoteRevision(contact->etag()); + changeCommitted(item); + } else if (collection.isValid()) { + ContactsGroupCreateJob *createJob = qobject_cast(job); + Q_ASSERT(createJob->items().count() == 1); + ContactsGroupPtr group = createJob->items().at(0).dynamicCast(); - collection.setRemoteId( group->id() ); - collection.setContentMimeTypes( QStringList() << KABC::Addressee::mimeType() ); + collection.setRemoteId(group->id()); + collection.setContentMimeTypes(QStringList() << KContacts::Addressee::mimeType()); - EntityDisplayAttribute *attr = collection.attribute( Entity::AddIfMissing ); - attr->setDisplayName( group->title() ); - attr->setIconName( QLatin1String("view-pim-contacts") ); + EntityDisplayAttribute *attr = collection.attribute(Entity::AddIfMissing); + attr->setDisplayName(group->title()); + attr->setIconName(QStringLiteral("view-pim-contacts")); m_collections[ collection.remoteId() ] = collection; - changeCommitted( collection ); + changeCommitted(collection); } job->deleteLater(); } - -AKONADI_RESOURCE_MAIN( ContactsResource ) +AKONADI_RESOURCE_MAIN(ContactsResource) diff -Nru kdepim-runtime-4.14.6/resources/google/contacts/contactsresource.h kdepim-runtime-15.08.0/resources/google/contacts/contactsresource.h --- kdepim-runtime-4.14.6/resources/google/contacts/contactsresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/contacts/contactsresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,8 +20,8 @@ #include "common/googleresource.h" -#include -#include +#include +#include class GoogleSettings; namespace KGAPI2 @@ -34,44 +34,44 @@ { Q_OBJECT - public: - explicit ContactsResource( const QString &id ); +public: + using GoogleResource::collectionChanged; // So we don't trigger -Woverloaded-virtual + explicit ContactsResource(const QString &id); ~ContactsResource(); - protected Q_SLOTS: - virtual void retrieveCollections(); +protected Q_SLOTS: + void retrieveCollections() Q_DECL_OVERRIDE; + void retrieveItems(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + virtual void retrieveContactsPhotos(const QVariant &argument); + + void itemRemoved(const Akonadi::Item &item) Q_DECL_OVERRIDE; + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &item, const QSet< QByteArray > &partIdentifiers) Q_DECL_OVERRIDE; + void itemMoved(const Akonadi::Item &item, const Akonadi::Collection &collectionSource, + const Akonadi::Collection &collectionDestination) Q_DECL_OVERRIDE; + + void collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent) Q_DECL_OVERRIDE; + void collectionChanged(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void collectionRemoved(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + + void itemLinked(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void itemUnlinked(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + + void slotItemsRetrieved(KGAPI2::Job *job); + void slotCollectionsRetrieved(KGAPI2::Job *job); + + void slotUpdatePhotosItemsRetrieved(KJob *job); + void slotUpdatePhotoFinished(KGAPI2::Job *job, const KGAPI2::ContactPtr &contact); + + void slotCreateJobFinished(KGAPI2::Job *job); + + GoogleSettings *settings() const Q_DECL_OVERRIDE; + int runConfigurationDialog(WId windowId) Q_DECL_OVERRIDE; + void updateResourceName() Q_DECL_OVERRIDE; + QList< QUrl > scopes() const Q_DECL_OVERRIDE; - virtual void retrieveItems( const Akonadi::Collection &collection ); - virtual void retrieveContactsPhotos( const QVariant &argument ); - - virtual void itemRemoved( const Akonadi::Item &item ); - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet< QByteArray > &partIdentifiers ); - virtual void itemMoved( const Akonadi::Item &item, const Akonadi::Collection &collectionSource, - const Akonadi::Collection &collectionDestination ); - - virtual void collectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection &parent ); - virtual void collectionChanged( const Akonadi::Collection &collection ); - virtual void collectionRemoved( const Akonadi::Collection &collection ); - - virtual void itemLinked( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemUnlinked( const Akonadi::Item &item, const Akonadi::Collection &collection ); - - void slotItemsRetrieved( KGAPI2::Job *job ); - void slotCollectionsRetrieved( KGAPI2::Job *job ); - - void slotUpdatePhotosItemsRetrieved( KJob *job ); - void slotUpdatePhotoFinished( KGAPI2::Job *job, const KGAPI2::ContactPtr &contact ); - - void slotCreateJobFinished( KGAPI2::Job *job ); - - virtual GoogleSettings *settings() const; - virtual int runConfigurationDialog( WId windowId ); - virtual void updateResourceName(); - virtual QList< QUrl > scopes() const; - - private: +private: QMap m_collections; Akonadi::Collection m_rootCollection; diff -Nru kdepim-runtime-4.14.6/resources/google/contacts/googlecontactsresource.desktop kdepim-runtime-15.08.0/resources/google/contacts/googlecontactsresource.desktop --- kdepim-runtime-4.14.6/resources/google/contacts/googlecontactsresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/contacts/googlecontactsresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,6 @@ [Desktop Entry] Name=Google Contacts +Name[bg]=Контакти в Google Name[bs]=Google kontakti Name[ca]=Contactes de Google Name[ca@valencia]=Contactes de Google @@ -43,6 +44,7 @@ Name[zh_CN]=Google 联系人 Name[zh_TW]=Google 聯絡人 Comment=Access your Google Contacts from KDE +Comment[bg]=Достъп до контактите ви в Google от KDE Comment[bs]=Pristupite svojim Google kontaktima iz KDE Comment[ca]=Accediu als contactes de Google des del KDE Comment[ca@valencia]=Accediu als contactes de Google des del KDE diff -Nru kdepim-runtime-4.14.6/resources/google/contacts/settings.cpp kdepim-runtime-15.08.0/resources/google/contacts/settings.cpp --- kdepim-runtime-4.14.6/resources/google/contacts/settings.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/contacts/settings.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,46 +18,44 @@ #include "settings.h" #include "settingsadaptor.h" -#include - #include class SettingsHelper { - public: - SettingsHelper() : q( 0 ) +public: + SettingsHelper() : q(Q_NULLPTR) { } ~SettingsHelper() { - delete q; - q = 0; + delete q; + q = Q_NULLPTR; } Settings *q; }; -K_GLOBAL_STATIC( SettingsHelper, s_globalSettings ) +Q_GLOBAL_STATIC(SettingsHelper, s_globalSettings) Settings::Settings(): GoogleSettings() { - Q_ASSERT( !s_globalSettings->q ); - s_globalSettings->q = this; + Q_ASSERT(!s_globalSettings->q); + s_globalSettings->q = this; - new SettingsAdaptor( this ); - QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ), this, - QDBusConnection::ExportAdaptors | QDBusConnection::ExportScriptableContents ); + new SettingsAdaptor(this); + QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"), this, + QDBusConnection::ExportAdaptors | QDBusConnection::ExportScriptableContents); } Settings *Settings::self() { - if ( !s_globalSettings->q ) { - new Settings; - s_globalSettings->q->readConfig(); - } + if (!s_globalSettings->q) { + new Settings; + s_globalSettings->q->load(); + } - return s_globalSettings->q; + return s_globalSettings->q; } diff -Nru kdepim-runtime-4.14.6/resources/google/contacts/settingsdialog.cpp kdepim-runtime-15.08.0/resources/google/contacts/settingsdialog.cpp --- kdepim-runtime-4.14.6/resources/google/contacts/settingsdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/contacts/settingsdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,20 +18,18 @@ #include "settingsdialog.h" #include "settings.h" -#include -#include -#include +#include +#include +#include -#include -#include +#include +#include using namespace KGAPI2; -SettingsDialog::SettingsDialog( GoogleAccountManager *accountMgr, WId windowId, GoogleResource *parent ): - GoogleSettingsDialog( accountMgr, windowId, parent ) +SettingsDialog::SettingsDialog(GoogleAccountManager *accountMgr, WId windowId, GoogleResource *parent): + GoogleSettingsDialog(accountMgr, windowId, parent) { - connect( this, SIGNAL(accepted()), - this, SLOT(saveSettings()) ); } SettingsDialog::~SettingsDialog() @@ -41,12 +39,12 @@ void SettingsDialog::saveSettings() { const AccountPtr account = currentAccount(); - if ( !account ) { - Settings::self()->setAccount( QString() ); - Settings::self()->writeConfig(); + if (!account) { + Settings::self()->setAccount(QString()); + Settings::self()->save(); return; } - Settings::self()->setAccount( account->accountName() ); - Settings::self()->writeConfig(); + Settings::self()->setAccount(account->accountName()); + Settings::self()->save(); } diff -Nru kdepim-runtime-4.14.6/resources/google/contacts/settingsdialog.h kdepim-runtime-15.08.0/resources/google/contacts/settingsdialog.h --- kdepim-runtime-4.14.6/resources/google/contacts/settingsdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/contacts/settingsdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,13 +24,13 @@ class SettingsDialog : public GoogleSettingsDialog { - Q_OBJECT - public: - explicit SettingsDialog( GoogleAccountManager *accountMgr, WId windowId, GoogleResource *parent ); + Q_OBJECT +public: + explicit SettingsDialog(GoogleAccountManager *accountMgr, WId windowId, GoogleResource *parent); ~SettingsDialog(); - private Q_SLOTS: - void saveSettings(); +private Q_SLOTS: + void saveSettings() Q_DECL_OVERRIDE; }; diff -Nru kdepim-runtime-4.14.6/resources/google/contacts/settings.h kdepim-runtime-15.08.0/resources/google/contacts/settings.h --- kdepim-runtime-4.14.6/resources/google/contacts/settings.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/google/contacts/settings.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,9 +22,9 @@ class Settings: public GoogleSettings { - Q_OBJECT - Q_CLASSINFO( "D-Bus Interface", "org.kde.Akonadi.GoogleContacts.ExtendedSettings" ) - public: + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.Akonadi.GoogleContacts.ExtendedSettings") +public: Settings(); static Settings *self(); diff -Nru kdepim-runtime-4.14.6/resources/ical/autotests/CMakeLists.txt kdepim-runtime-15.08.0/resources/ical/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/ical/autotests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/autotests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,4 @@ +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ical-empty.xml ${CMAKE_CURRENT_BINARY_DIR}/ical-empty.xml COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ical-step1.xml ${CMAKE_CURRENT_BINARY_DIR}/ical-step1.xml COPYONLY) + +akonadi_add_resourcetest( ical icaltest.es ) diff -Nru kdepim-runtime-4.14.6/resources/ical/autotests/event.ical kdepim-runtime-15.08.0/resources/ical/autotests/event.ical --- kdepim-runtime-4.14.6/resources/ical/autotests/event.ical 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/autotests/event.ical 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,26 @@ +BEGIN:VCALENDAR +PRODID:-//K Desktop Environment//NONSGML libkcal 3.5//EN +VERSION:2.0 +BEGIN:VEVENT +DTSTAMP:20070109T100625Z +ORGANIZER;CN=Volker Krause:MAILTO:vkrause@kde.org +CREATED:20070109T100553Z +UID:libkcal-1135684253.945 +SEQUENCE:1 +LAST-MODIFIED:20070109T100625Z +SUMMARY:Test event +LOCATION:here +CLASS:PUBLIC +PRIORITY:5 +CATEGORIES:KDE +DTSTART:20070109T183000Z +DTEND:20070109T225900Z +TRANSP:OPAQUE +BEGIN:VALARM +DESCRIPTION: +ACTION:DISPLAY +TRIGGER;VALUE=DURATION:-PT45M +END:VALARM +END:VEVENT +END:VCALENDAR + diff -Nru kdepim-runtime-4.14.6/resources/ical/autotests/ical-empty.xml kdepim-runtime-15.08.0/resources/ical/autotests/ical-empty.xml --- kdepim-runtime-4.14.6/resources/ical/autotests/ical-empty.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/autotests/ical-empty.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,6 @@ + + + ("newical.ics" "office-calendar") + wcdW + + diff -Nru kdepim-runtime-4.14.6/resources/ical/autotests/ical-step1.xml kdepim-runtime-15.08.0/resources/ical/autotests/ical-step1.xml --- kdepim-runtime-4.14.6/resources/ical/autotests/ical-step1.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/autotests/ical-step1.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,52 @@ + + + ("newical.ics" "office-calendar") + wcdW + + BEGIN:VCALENDAR +PRODID:-//K Desktop Environment//NONSGML libkcal 3.2//EN +VERSION:2.0 +BEGIN:VEVENT +DTSTAMP:20090412T123141Z +ORGANIZER;CN="Volker Krause":MAILTO:vkrause@kde.org +CREATED:20070109T100553Z +UID:libkcal-1135684253.945 +SEQUENCE:1 +LAST-MODIFIED:20070109T100625Z +SUMMARY:Test event +LOCATION:here +PRIORITY:5 +CATEGORIES:KDE +DTSTART:20070109T183000Z +DTEND:20070109T225900Z +TRANSP:OPAQUE +BEGIN:VALARM +DESCRIPTION: +ACTION:DISPLAY +TRIGGER;VALUE=DURATION:-PT45M +END:VALARM +END:VEVENT + +END:VCALENDAR + + + BEGIN:VCALENDAR +PRODID:-//K Desktop Environment//NONSGML libkcal 3.2//EN +VERSION:2.0 +BEGIN:VTODO +DTSTAMP:20090412T123141Z +ORGANIZER:MAILTO:vkrause@kde.org +CREATED:20040505T094143Z +UID:libkcal-1506191911.958 +LAST-MODIFIED:20040512T133925Z +SUMMARY:Add a demo task to this file +PRIORITY:3 +DUE;VALUE=DATE:20090101 +COMPLETED:20090101T133925Z +PERCENT-COMPLETE:100 +END:VTODO + +END:VCALENDAR + + + diff -Nru kdepim-runtime-4.14.6/resources/ical/autotests/icaltest.es kdepim-runtime-15.08.0/resources/ical/autotests/icaltest.es --- kdepim-runtime-4.14.6/resources/ical/autotests/icaltest.es 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/autotests/icaltest.es 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,31 @@ +Resource.setType( "akonadi_ical_resource" ); +Resource.setPathOption( "Path", "newical.ics" ); +Resource.create(); + +XmlOperations.setXmlFile( "ical-empty.xml" ); +XmlOperations.setRootCollections( Resource.identifier() ); +XmlOperations.setCollectionKey( "None" ); +XmlOperations.ignoreCollectionField( "Name" ); // name is the resource identifier and thus unpredictable +XmlOperations.setNormalizeRemoteIds( true ); +XmlOperations.assertEqual(); + +// item creation +var i1 = ItemTest.newInstance(); +i1.setParentCollection( Resource.identifier() ); +i1.setMimeType( "text/calendar" ); +i1.setPayloadFromFile( "event.ical" ); +i1.create(); + +var i2 = ItemTest.newInstance(); +i2.setParentCollection( Resource.identifier() ); +i2.setMimeType( "text/calendar" ); +i2.setPayloadFromFile( "task.ical" ); +i2.create(); + +Resource.recreate(); + +XmlOperations.setXmlFile( "ical-step1.xml" ); +XmlOperations.setRootCollections( Resource.identifier() ); +XmlOperations.ignoreCollectionField( "None" ); +XmlOperations.assertEqual(); + diff -Nru kdepim-runtime-4.14.6/resources/ical/autotests/task.ical kdepim-runtime-15.08.0/resources/ical/autotests/task.ical --- kdepim-runtime-4.14.6/resources/ical/autotests/task.ical 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/autotests/task.ical 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,16 @@ +BEGIN:VCALENDAR +PRODID:-//K Desktop Environment//NONSGML libkcal 3.5//EN +VERSION:2.0 +BEGIN:VTODO +DTSTAMP:20090101T154017Z +ORGANIZER:MAILTO:vkrause@kde.org +CREATED:20040505T094143Z +UID:libkcal-1506191911.958 +LAST-MODIFIED:20040512T133925Z +SUMMARY:Add a demo task to this file +PRIORITY:3 +DUE;VALUE=DATE:20090101 +COMPLETED:20090101T133925Z +PERCENT-COMPLETE:100 +END:VTODO +END:VCALENDAR diff -Nru kdepim-runtime-4.14.6/resources/ical/CMakeLists.txt kdepim-runtime-15.08.0/resources/ical/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/ical/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,44 +1,46 @@ include_directories( ${kdepim-runtime_SOURCE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/shared ) -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) + +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_ical_resource\") + add_subdirectory( wizard ) add_subdirectory( notes ) -add_subdirectory( tests ) + +if(BUILD_TESTING) + add_subdirectory( autotests ) +endif() ########### next target ############### add_definitions( -DSETTINGS_NAMESPACE=Akonadi_ICal_Resource ) set( icalresource_SRCS - ${AKONADI_SINGLEFILERESOURCE_SHARED_SOURCES} + icalresource.cpp shared/icalresourcebase.cpp shared/icalresource.cpp - icalresourceplugin.cpp ) -install( FILES icalresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) +install( FILES icalresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) -kde4_add_ui_files(icalresource_SRCS ${AKONADI_SINGLEFILERESOURCE_SHARED_UI}) -kde4_add_kcfg_files(icalresource_SRCS settings.kcfgc) +kconfig_add_kcfg_files(icalresource_SRCS settings.kcfgc) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/icalresource.kcfg org.kde.Akonadi.ICal.Settings) -qt4_add_dbus_adaptor(icalresource_SRCS +qt5_add_dbus_adaptor(icalresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.ICal.Settings.xml settings.h Akonadi_ICal_Resource::Settings icalsettingsadaptor ICalSettingsAdaptor ) -kde4_add_plugin(akonadi_ical_resource ${icalresource_SRCS}) +add_executable(akonadi_ical_resource ${icalresource_SRCS}) -if (Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_ical_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) set_target_properties(akonadi_ical_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.ICal") set_target_properties(akonadi_ical_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi ICal Resource") endif () -target_link_libraries(akonadi_ical_resource ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTDBUS_LIBRARY} ${KDE4_KIO_LIBS} ${KDEPIMLIBS_KCALCORE_LIBS}) +target_link_libraries(akonadi_ical_resource KF5::AkonadiCore KF5::KIOCore KF5::CalendarCore KF5::AkonadiAgentBase akonadi-singlefileresource KF5::DBusAddons) -install(TARGETS akonadi_ical_resource DESTINATION ${PLUGIN_INSTALL_DIR}) +install(TARGETS akonadi_ical_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/ical/icalresource.cpp kdepim-runtime-15.08.0/resources/ical/icalresource.cpp --- kdepim-runtime-4.14.6/resources/ical/icalresource.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/icalresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* + Copyright (c) 2015 Daniel Vrátil + + 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 "shared/icalresource.h" + +AKONADI_RESOURCE_MAIN(ICalResource) diff -Nru kdepim-runtime-4.14.6/resources/ical/icalresource.desktop kdepim-runtime-15.08.0/resources/ical/icalresource.desktop --- kdepim-runtime-4.14.6/resources/ical/icalresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/icalresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -102,4 +102,3 @@ X-Akonadi-MimeTypes=text/calendar,application/x-vnd.akonadi.calendar.event,application/x-vnd.akonadi.calendar.todo,application/x-vnd.akonadi.calendar.journal,application/x-vnd.akonadi.calendar.freebusy X-Akonadi-Capabilities=Resource X-Akonadi-Identifier=akonadi_ical_resource -X-Akonadi-LaunchMethod=AgentServer diff -Nru kdepim-runtime-4.14.6/resources/ical/icalresourceplugin.cpp kdepim-runtime-15.08.0/resources/ical/icalresourceplugin.cpp --- kdepim-runtime-4.14.6/resources/ical/icalresourceplugin.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/icalresourceplugin.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -/* - Copyright (c) 2010 Bertjan Broeksema - - 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 "icalresource.h" - -#include - -#include - -/** We need to put this in a separate file because the notes plugin inherits the - ical plugin and we'd get a multiple definition of `qt_plugin_instance' - if we put the line below in icalresource.cpp. Now we can compile it only for - the ical resource - */ -AKONADI_AGENT_FACTORY( ICalResource, akonadi_ical_resource ) - diff -Nru kdepim-runtime-4.14.6/resources/ical/notes/CMakeLists.txt kdepim-runtime-15.08.0/resources/ical/notes/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/ical/notes/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/notes/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,11 +1,10 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../shared ${kdepim-runtime_SOURCE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ) -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) + ########### next target ############### @@ -13,23 +12,21 @@ add_definitions( -DSETTINGS_NAMESPACE=Akonadi_Aknotes_Resource ) set( notesresource_SRCS - ${AKONADI_SINGLEFILERESOURCE_SHARED_SOURCES} ../shared/icalresourcebase.cpp ../shared/icalresource.cpp notesresource.cpp ) -install( FILES notesresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) +install( FILES notesresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) -kde4_add_ui_files(notesresource_SRCS ${AKONADI_SINGLEFILERESOURCE_SHARED_UI}) -kde4_add_kcfg_files(notesresource_SRCS settings.kcfgc) +kconfig_add_kcfg_files(notesresource_SRCS settings.kcfgc) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/notesresource.kcfg org.kde.Akonadi.Notes.Settings) -qt4_add_dbus_adaptor(notesresource_SRCS +qt5_add_dbus_adaptor(notesresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.Notes.Settings.xml settings.h Akonadi_Aknotes_Resource::Settings icalsettingsadaptor ICalSettingsAdaptor ) -kde4_add_plugin(akonadi_notes_resource ${notesresource_SRCS}) +add_executable(akonadi_notes_resource ${notesresource_SRCS}) -target_link_libraries(akonadi_notes_resource ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTDBUS_LIBRARY} ${KDE4_KIO_LIBS} ${KDEPIMLIBS_KCALCORE_LIBS}) +target_link_libraries(akonadi_notes_resource KF5::AkonadiCore KF5::KIOCore KF5::CalendarCore KF5::AkonadiAgentBase KF5::DBusAddons akonadi-singlefileresource) -install(TARGETS akonadi_notes_resource DESTINATION ${PLUGIN_INSTALL_DIR}) +install(TARGETS akonadi_notes_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/ical/notes/notesresource.cpp kdepim-runtime-15.08.0/resources/ical/notes/notesresource.cpp --- kdepim-runtime-4.14.6/resources/ical/notes/notesresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/notes/notesresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,27 +19,25 @@ #include "notesresource.h" -#include +#include -#include +#include -#include -#include #include -#include +#include using namespace Akonadi; using namespace KCalCore; -static QLatin1String sNotesType( "application/x-vnd.kde.notes" ); +static const QLatin1String sNotesType("application/x-vnd.kde.notes"); -NotesResource::NotesResource( const QString &id ) - : ICalResource( id, allMimeTypes(), QLatin1String("knotes") ) +NotesResource::NotesResource(const QString &id) + : ICalResource(id, allMimeTypes(), QStringLiteral("knotes")) { - KConfigSkeleton::ItemPath *item = static_cast( mSettings->findItem( QLatin1String("Path") ) ); - if ( item ) { - item->setDefaultValue( KGlobal::dirs()->saveLocation( "data", QLatin1String("knotes/") ) + QLatin1String("notes.ics") ); - } + KConfigSkeleton::ItemPath *item = static_cast(mSettings->findItem(QLatin1String("Path"))); + if (item) { + item->setDefaultValue(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QLatin1String("knotes/")); + } } NotesResource::~NotesResource() @@ -51,10 +49,9 @@ return QStringList() << sNotesType; } -QString NotesResource::mimeType( const KCalCore::IncidenceBase::Ptr & ) const +QString NotesResource::mimeType(const KCalCore::IncidenceBase::Ptr &) const { - return sNotesType; + return sNotesType; } -AKONADI_AGENT_FACTORY( NotesResource, akonadi_notes_resource ) - +AKONADI_RESOURCE_MAIN(NotesResource) diff -Nru kdepim-runtime-4.14.6/resources/ical/notes/notesresource.desktop kdepim-runtime-15.08.0/resources/ical/notes/notesresource.desktop --- kdepim-runtime-4.14.6/resources/ical/notes/notesresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/notes/notesresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -44,7 +44,6 @@ Name[ne]=टिपोट Name[nl]=Notities Name[nn]=Notat -Name[oc]=Nòtas Name[pa]=ਨੋਟਿਸ Name[pl]=Notatki Name[pt]=Notas @@ -53,7 +52,7 @@ Name[ru]=Заметки Name[se]=Nohtat Name[sk]=Poznámky -Name[sl]=Notice +Name[sl]=Sporočilca Name[sq]=Shënimet Name[sr]=Белешке Name[sr@ijekavian]=Биљешке @@ -108,7 +107,7 @@ Comment[ro]=Încarcă date dintr-un fișier cu note Comment[ru]=Загрузка данных из файла заметок Comment[sk]=Načíta dáta zo súboru poznámok -Comment[sl]=Naloži podatke iz datoteke z noticami +Comment[sl]=Naloži podatke iz datoteke s sporočilci Comment[sr]=Учитава податке из фајла белешки Comment[sr@ijekavian]=Учитава податке из фајла биљешки Comment[sr@ijekavianlatin]=Učitava podatke iz fajla bilješki @@ -126,4 +125,3 @@ X-Akonadi-MimeTypes=application/x-vnd.kde.notes X-Akonadi-Capabilities=Resource X-Akonadi-Identifier=akonadi_notes_resource -X-Akonadi-LaunchMethod=AgentServer diff -Nru kdepim-runtime-4.14.6/resources/ical/notes/notesresource.h kdepim-runtime-15.08.0/resources/ical/notes/notesresource.h --- kdepim-runtime-4.14.6/resources/ical/notes/notesresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/notes/notesresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,22 +24,22 @@ class NotesResource : public ICalResource { - Q_OBJECT + Q_OBJECT - public: - explicit NotesResource( const QString &id ); +public: + explicit NotesResource(const QString &id); ~NotesResource(); - protected: +protected: /** Returns the Akonadi specific @c text/calendar sub MIME type of the given @p incidence. */ - virtual QString mimeType( const KCalCore::IncidenceBase::Ptr &incidence ) const; + QString mimeType(const KCalCore::IncidenceBase::Ptr &incidence) const Q_DECL_OVERRIDE; /** Returns a list of all calendar component sub MIME types. */ - virtual QStringList allMimeTypes() const; + QStringList allMimeTypes() const Q_DECL_OVERRIDE; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/ical/notes/settings.kcfgc kdepim-runtime-15.08.0/resources/ical/notes/settings.kcfgc --- kdepim-runtime-4.14.6/resources/ical/notes/settings.kcfgc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/notes/settings.kcfgc 2015-08-10 21:01:02.000000000 +0000 @@ -6,4 +6,4 @@ Singleton=false #IncludeFiles= GlobalEnums=true -Namespace=Akonadi_Aknotes_Resource +NameSpace=Akonadi_Aknotes_Resource diff -Nru kdepim-runtime-4.14.6/resources/ical/settings.kcfgc kdepim-runtime-15.08.0/resources/ical/settings.kcfgc --- kdepim-runtime-4.14.6/resources/ical/settings.kcfgc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/settings.kcfgc 2015-08-10 21:01:02.000000000 +0000 @@ -6,5 +6,5 @@ Singleton=false #IncludeFiles= GlobalEnums=true -Namespace=Akonadi_ICal_Resource +NameSpace=Akonadi_ICal_Resource diff -Nru kdepim-runtime-4.14.6/resources/ical/shared/icalresourcebase.cpp kdepim-runtime-15.08.0/resources/ical/shared/icalresourcebase.cpp --- kdepim-runtime-4.14.6/resources/ical/shared/icalresourcebase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/shared/icalresourcebase.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,154 +22,151 @@ #include "icalsettingsadaptor.h" #include "singlefileresourceconfigdialog.h" -#include +#include -#include -#include -#include -#include - -#include -#include -#include +#include +#include +#include +#include + +#include +#include using namespace Akonadi; using namespace KCalCore; using namespace SETTINGS_NAMESPACE; -ICalResourceBase::ICalResourceBase( const QString &id ) - : SingleFileResource( id ) +ICalResourceBase::ICalResourceBase(const QString &id) + : SingleFileResource(id) { - KGlobal::locale()->insertCatalog( QLatin1String("akonadi_ical_resource") ); } -void ICalResourceBase::initialise( const QStringList &mimeTypes, const QString &icon ) +void ICalResourceBase::initialise(const QStringList &mimeTypes, const QString &icon) { - setSupportedMimetypes( mimeTypes, icon ); - new ICalSettingsAdaptor( mSettings ); - DBusConnectionPool::threadConnection().registerObject( QLatin1String( "/Settings" ), - mSettings, QDBusConnection::ExportAdaptors ); + setSupportedMimetypes(mimeTypes, icon); + new ICalSettingsAdaptor(mSettings); + KDBusConnectionPool::threadConnection().registerObject(QStringLiteral("/Settings"), + mSettings, QDBusConnection::ExportAdaptors); } ICalResourceBase::~ICalResourceBase() { } -bool ICalResourceBase::retrieveItem( const Akonadi::Item &item, - const QSet &parts ) +bool ICalResourceBase::retrieveItem(const Akonadi::Item &item, + const QSet &parts) { - kDebug( 5251 ) << "Item:" << item.url(); + qDebug() << "Item:" << item.url(); - if ( !mCalendar ) { - kError() << "akonadi_ical_resource: Calendar not loaded"; - emit error( i18n( "Calendar not loaded.") ); - return false; - } + if (!mCalendar) { + qCritical() << "akonadi_ical_resource: Calendar not loaded"; + Q_EMIT error(i18n("Calendar not loaded.")); + return false; + } - return doRetrieveItem( item, parts ); + return doRetrieveItem(item, parts); } void ICalResourceBase::aboutToQuit() { - if ( !mSettings->readOnly() ) { - writeFile(); - } - mSettings->writeConfig(); + if (!mSettings->readOnly()) { + writeFile(); + } + mSettings->save(); } -void ICalResourceBase::customizeConfigDialog( SingleFileResourceConfigDialog *dlg ) +void ICalResourceBase::customizeConfigDialog(SingleFileResourceConfigDialog *dlg) { #ifndef KDEPIM_MOBILE_UI - dlg->setFilter( QLatin1String("text/calendar") ); + dlg->setFilter(QStringLiteral("text/calendar")); #else - dlg->setFilter( QLatin1String("*.ics *.vcs") ); + dlg->setFilter(QStringLiteral("*.ics *.vcs")); #endif - dlg->setCaption( i18n( "Select Calendar" ) ); + dlg->setWindowTitle(i18n("Select Calendar")); +} + +bool ICalResourceBase::readFromFile(const QString &fileName) +{ + mCalendar = KCalCore::MemoryCalendar::Ptr(new KCalCore::MemoryCalendar(QLatin1String("UTC"))); + mFileStorage = KCalCore::FileStorage::Ptr(new KCalCore::FileStorage(mCalendar, fileName, + new KCalCore::ICalFormat())); + const bool result = mFileStorage->load(); + if (!result) { + qCritical() << "akonadi_ical_resource: Error loading file " << fileName; + } + + return result; +} + +void ICalResourceBase::itemRemoved(const Akonadi::Item &item) +{ + if (!mCalendar) { + qCritical() << "akonadi_ical_resource: mCalendar is 0!"; + cancelTask(i18n("Calendar not loaded.")); + return; + } + + Incidence::Ptr i = mCalendar->instance(item.remoteId()); + if (i) { + if (!mCalendar->deleteIncidence(i)) { + qCritical() << "akonadi_ical_resource: Can't delete incidence with instance identifier " + << item.remoteId() << "; item.id() = " << item.id(); + cancelTask(); + return; + } + } else { + qCritical() << "akonadi_ical_resource: itemRemoved(): Can't find incidence with instance identifier " + << item.remoteId() << "; item.id() = " << item.id(); + } + scheduleWrite(); + changeProcessed(); } -bool ICalResourceBase::readFromFile( const QString &fileName ) +void ICalResourceBase::retrieveItems(const Akonadi::Collection &col) { - mCalendar = KCalCore::MemoryCalendar::Ptr( new KCalCore::MemoryCalendar( QLatin1String( "UTC" ) ) ); - mFileStorage = KCalCore::FileStorage::Ptr( new KCalCore::FileStorage( mCalendar, fileName, - new KCalCore::ICalFormat() ) ); - const bool result = mFileStorage->load(); - if ( !result ) { - kError() << "akonadi_ical_resource: Error loading file " << fileName; - } - - return result; -} - -void ICalResourceBase::itemRemoved( const Akonadi::Item &item ) -{ - if ( !mCalendar ) { - kError() << "akonadi_ical_resource: mCalendar is 0!"; - cancelTask( i18n( "Calendar not loaded." ) ); - return; - } - - Incidence::Ptr i = mCalendar->instance( item.remoteId() ); - if ( i ) { - if ( !mCalendar->deleteIncidence( i ) ) { - kError() << "akonadi_ical_resource: Can't delete incidence with instance identifier " - << item.remoteId() << "; item.id() = " << item.id(); - cancelTask(); - return; - } - } else { - kError() << "akonadi_ical_resource: itemRemoved(): Can't find incidence with instance identifier " - << item.remoteId() << "; item.id() = " << item.id(); - } - scheduleWrite(); - changeProcessed(); -} - -void ICalResourceBase::retrieveItems( const Akonadi::Collection &col ) -{ - reloadFile(); - if ( mCalendar ) { - doRetrieveItems( col ); - } else { - kError() << "akonadi_ical_resource: retrieveItems(): mCalendar is 0!"; - } -} - -bool ICalResourceBase::writeToFile( const QString &fileName ) -{ - if ( !mCalendar ) { - kError() << "akonadi_ical_resource: writeToFile() mCalendar is 0!"; - return false; - } - - KCalCore::FileStorage *fileStorage = mFileStorage.data(); - if ( fileName != mFileStorage->fileName() ) { - fileStorage = new KCalCore::FileStorage( mCalendar, - fileName, - new KCalCore::ICalFormat() ); - } - - bool success = true; - if ( !fileStorage->save() ) { - kError() << QLatin1String("akonadi_ical_resource: Failed to save calendar to file ") + fileName; - emit error( i18n( "Failed to save calendar file to %1", fileName ) ); - success = false; - } - - if ( fileStorage != mFileStorage.data() ) { - delete fileStorage; - } + reloadFile(); + if (mCalendar) { + doRetrieveItems(col); + } else { + qCritical() << "akonadi_ical_resource: retrieveItems(): mCalendar is 0!"; + } +} - return success; +bool ICalResourceBase::writeToFile(const QString &fileName) +{ + if (!mCalendar) { + qCritical() << "akonadi_ical_resource: writeToFile() mCalendar is 0!"; + return false; + } + + KCalCore::FileStorage *fileStorage = mFileStorage.data(); + if (fileName != mFileStorage->fileName()) { + fileStorage = new KCalCore::FileStorage(mCalendar, + fileName, + new KCalCore::ICalFormat()); + } + + bool success = true; + if (!fileStorage->save()) { + qCritical() << QStringLiteral("akonadi_ical_resource: Failed to save calendar to file ") + fileName; + Q_EMIT error(i18n("Failed to save calendar file to %1", fileName)); + success = false; + } + + if (fileStorage != mFileStorage.data()) { + delete fileStorage; + } + + return success; } KCalCore::MemoryCalendar::Ptr ICalResourceBase::calendar() const { - return mCalendar; + return mCalendar; } KCalCore::FileStorage::Ptr ICalResourceBase::fileStorage() const { - return mFileStorage; + return mFileStorage; } - diff -Nru kdepim-runtime-4.14.6/resources/ical/shared/icalresourcebase.h kdepim-runtime-15.08.0/resources/ical/shared/icalresourcebase.h --- kdepim-runtime-4.14.6/resources/ical/shared/icalresourcebase.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/shared/icalresourcebase.h 2015-08-10 21:01:02.000000000 +0000 @@ -27,32 +27,31 @@ #include #include - class ICalResourceBase : public Akonadi::SingleFileResource { - Q_OBJECT + Q_OBJECT - public: - explicit ICalResourceBase( const QString &id ); +public: + explicit ICalResourceBase(const QString &id); ~ICalResourceBase(); - protected Q_SLOTS: - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - void retrieveItems( const Akonadi::Collection &col ); +protected Q_SLOTS: + bool retrieveItem(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + void retrieveItems(const Akonadi::Collection &col) Q_DECL_OVERRIDE; - protected: +protected: enum CheckType { CheckForAdded, CheckForChanged }; - void initialise( const QStringList &mimeTypes, const QString &icon ); - bool readFromFile( const QString &fileName ); - bool writeToFile( const QString &fileName ); + void initialise(const QStringList &mimeTypes, const QString &icon); + bool readFromFile(const QString &fileName) Q_DECL_OVERRIDE; + bool writeToFile(const QString &fileName) Q_DECL_OVERRIDE; /** * Customize the configuration dialog before it is displayed. */ - virtual void customizeConfigDialog( Akonadi::SingleFileResourceConfigDialog* dlg ); + void customizeConfigDialog(Akonadi::SingleFileResourceConfigDialog *dlg) Q_DECL_OVERRIDE; - virtual void aboutToQuit(); + void aboutToQuit() Q_DECL_OVERRIDE; /** * Retrieve an incidence from the calendar, and set it into a new item's payload. @@ -60,13 +59,13 @@ * @param item the incidence ID to retrieve is provided by @c item.remoteId() * @return true if item retrieved, false if not. */ - virtual bool doRetrieveItem( const Akonadi::Item &item, const QSet &parts ) = 0; + virtual bool doRetrieveItem(const Akonadi::Item &item, const QSet &parts) = 0; /** * Retrieve all incidences from the calendar, and set each into a new item's payload. * Retrieval of the items should be signalled by calling @p itemsRetrieved(). */ - virtual void doRetrieveItems( const Akonadi::Collection &col ) = 0; + virtual void doRetrieveItems(const Akonadi::Collection &col) = 0; /** * To be called at the start of derived class implementations of itemAdded() @@ -76,9 +75,9 @@ * false if a check failed, in which case itemAdded() or itemChanged() * should stop processing. */ - template bool checkItemAddedChanged( const Akonadi::Item &item, CheckType type ); + template bool checkItemAddedChanged(const Akonadi::Item &item, CheckType type); - virtual void itemRemoved( const Akonadi::Item &item ); + void itemRemoved(const Akonadi::Item &item) Q_DECL_OVERRIDE; /** Return the local calendar. */ KCalCore::MemoryCalendar::Ptr calendar() const; @@ -86,26 +85,26 @@ /** Return the calendar file storage. */ KCalCore::FileStorage::Ptr fileStorage() const; - private: +private: KCalCore::MemoryCalendar::Ptr mCalendar; KCalCore::FileStorage::Ptr mFileStorage; }; template -bool ICalResourceBase::checkItemAddedChanged( const Akonadi::Item &item, CheckType type ) +bool ICalResourceBase::checkItemAddedChanged(const Akonadi::Item &item, CheckType type) { - if ( !mCalendar ) { - cancelTask( i18n( "Calendar not loaded." ) ); - return false; - } - if ( !item.hasPayload() ) { - QString msg = ( type == CheckForAdded ) - ? i18n( "Unable to retrieve added item %1.", item.id() ) - : i18n( "Unable to retrieve modified item %1.", item.id() ); - cancelTask( msg ); - return false; - } - return true; + if (!mCalendar) { + cancelTask(i18n("Calendar not loaded.")); + return false; + } + if (!item.hasPayload()) { + QString msg = (type == CheckForAdded) + ? i18n("Unable to retrieve added item %1.", item.id()) + : i18n("Unable to retrieve modified item %1.", item.id()); + cancelTask(msg); + return false; + } + return true; } #endif diff -Nru kdepim-runtime-4.14.6/resources/ical/shared/icalresource.cpp kdepim-runtime-15.08.0/resources/ical/shared/icalresource.cpp --- kdepim-runtime-4.14.6/resources/ical/shared/icalresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/shared/icalresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,135 +20,135 @@ #include "icalresource.h" -#include -#include +#include +#include -#include -#include +#include +#include using namespace Akonadi; using namespace KCalCore; -ICalResource::ICalResource( const QString &id ) - : ICalResourceBase( id ) +ICalResource::ICalResource(const QString &id) + : ICalResourceBase(id) { - QStringList mimeTypes; - mimeTypes << QLatin1String( "text/calendar" ); - mimeTypes += allMimeTypes(); - initialise( mimeTypes, QLatin1String("office-calendar") ); + QStringList mimeTypes; + mimeTypes << QStringLiteral("text/calendar"); + mimeTypes += allMimeTypes(); + initialise(mimeTypes, QStringLiteral("office-calendar")); } -ICalResource::ICalResource( const QString &id, const QStringList &mimeTypes, const QString& icon ) - : ICalResourceBase( id ) +ICalResource::ICalResource(const QString &id, const QStringList &mimeTypes, const QString &icon) + : ICalResourceBase(id) { - initialise( mimeTypes, icon ); + initialise(mimeTypes, icon); } ICalResource::~ICalResource() { } -bool ICalResource::doRetrieveItem( const Akonadi::Item &item, const QSet &parts ) +bool ICalResource::doRetrieveItem(const Akonadi::Item &item, const QSet &parts) { - Q_UNUSED( parts ); - const QString rid = item.remoteId(); - Incidence::Ptr incidence = calendar()->instance( rid ); - if ( !incidence ) { - kError() << "akonadi_ical_resource: Can't find incidence with uid " - << rid << "; item.id() = " << item.id(); - emit error( i18n( "Incidence with uid '%1' not found.", rid ) ); - return false; - } - - Incidence::Ptr incidencePtr( incidence->clone() ); - - Item i = item; - i.setMimeType( incidencePtr->mimeType() ); - i.setPayload( incidencePtr ); - itemRetrieved( i ); - return true; -} - -void ICalResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection& ) -{ - if ( !checkItemAddedChanged( item, CheckForAdded ) ) { - return; - } - - Incidence::Ptr i = item.payload(); - if ( !calendar()->addIncidence( Incidence::Ptr( i->clone() ) ) ) { - kError() << "akonadi_ical_resource: Error adding incidence with uid " - << i->uid() << "; item.id() " << item.id() << i->recurrenceId(); - cancelTask(); - return; - } - - Item it( item ); - it.setRemoteId( i->instanceIdentifier() ); - scheduleWrite(); - changeCommitted( it ); -} - -void ICalResource::itemChanged( const Akonadi::Item &item, - const QSet &parts ) -{ - Q_UNUSED( parts ) - - if ( !checkItemAddedChanged( item, CheckForChanged ) ) { - return; - } - - Incidence::Ptr payload = item.payload(); - Incidence::Ptr incidence = calendar()->instance( item.remoteId() ); - if ( !incidence ) { - // not in the calendar yet, should not happen -> add it - calendar()->addIncidence( Incidence::Ptr( payload->clone() ) ); - } else { - // make sure any observer the resource might have installed gets properly notified - incidence->startUpdates(); - - if ( incidence->type() == payload->type() ) { - // IncidenceBase::operator= calls virtual method assign, so it's safe. - *incidence.staticCast().data() = *payload.data(); - incidence->updated(); - incidence->endUpdates(); + Q_UNUSED(parts); + const QString rid = item.remoteId(); + Incidence::Ptr incidence = calendar()->instance(rid); + if (!incidence) { + qCritical() << "akonadi_ical_resource: Can't find incidence with uid " + << rid << "; item.id() = " << item.id(); + Q_EMIT error(i18n("Incidence with uid '%1' not found.", rid)); + return false; + } + + Incidence::Ptr incidencePtr(incidence->clone()); + + Item i = item; + i.setMimeType(incidencePtr->mimeType()); + i.setPayload(incidencePtr); + itemRetrieved(i); + return true; +} + +void ICalResource::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &) +{ + if (!checkItemAddedChanged(item, CheckForAdded)) { + return; + } + + Incidence::Ptr i = item.payload(); + if (!calendar()->addIncidence(Incidence::Ptr(i->clone()))) { + //qCritical() << "akonadi_ical_resource: Error adding incidence with uid " + // << i->uid() << "; item.id() " << item.id() << i->recurrenceId(); + cancelTask(); + return; + } + + Item it(item); + it.setRemoteId(i->instanceIdentifier()); + scheduleWrite(); + changeCommitted(it); +} + +void ICalResource::itemChanged(const Akonadi::Item &item, + const QSet &parts) +{ + Q_UNUSED(parts) + + if (!checkItemAddedChanged(item, CheckForChanged)) { + return; + } + + Incidence::Ptr payload = item.payload(); + Incidence::Ptr incidence = calendar()->instance(item.remoteId()); + if (!incidence) { + // not in the calendar yet, should not happen -> add it + calendar()->addIncidence(Incidence::Ptr(payload->clone())); } else { - incidence->endUpdates(); - kWarning() << "akonadi_ical_resource: Item changed incidence type. Replacing it."; + // make sure any observer the resource might have installed gets properly notified + incidence->startUpdates(); - calendar()->deleteIncidence( incidence ); - calendar()->addIncidence( Incidence::Ptr( payload->clone() ) ); + if (incidence->type() == payload->type()) { + // IncidenceBase::operator= calls virtual method assign, so it's safe. + *incidence.staticCast().data() = *payload.data(); + incidence->updated(); + incidence->endUpdates(); + } else { + incidence->endUpdates(); + qWarning() << "akonadi_ical_resource: Item changed incidence type. Replacing it."; + + calendar()->deleteIncidence(incidence); + calendar()->addIncidence(Incidence::Ptr(payload->clone())); + } } - } - scheduleWrite(); - changeCommitted( item ); -} - -void ICalResource::doRetrieveItems( const Akonadi::Collection & col ) -{ - Q_UNUSED( col ); - Incidence::List incidences = calendar()->incidences(); - Item::List items; - foreach ( const Incidence::Ptr &incidence, incidences ) { - Item item ( incidence->mimeType() ); - item.setRemoteId( incidence->instanceIdentifier() ); - item.setPayload( Incidence::Ptr( incidence->clone() ) ); - items << item; - } - itemsRetrieved( items ); + scheduleWrite(); + changeCommitted(item); } -QStringList ICalResource::allMimeTypes() const +void ICalResource::doRetrieveItems(const Akonadi::Collection &col) { - return QStringList() << KCalCore::Event::eventMimeType() - << KCalCore::Todo::todoMimeType() - << KCalCore::Journal::journalMimeType() - << KCalCore::FreeBusy::freeBusyMimeType(); + Q_UNUSED(col); + Incidence::List incidences = calendar()->incidences(); + Item::List items; + items.reserve(incidences.count()); + foreach (const Incidence::Ptr &incidence, incidences) { + Item item(incidence->mimeType()); + item.setRemoteId(incidence->instanceIdentifier()); + item.setPayload(Incidence::Ptr(incidence->clone())); + items << item; + } + itemsRetrieved(items); } -QString ICalResource::mimeType( const IncidenceBase::Ptr &incidence ) const +QStringList ICalResource::allMimeTypes() const { - return incidence->mimeType(); + return QStringList() << KCalCore::Event::eventMimeType() + << KCalCore::Todo::todoMimeType() + << KCalCore::Journal::journalMimeType() + << KCalCore::FreeBusy::freeBusyMimeType(); } +QString ICalResource::mimeType(const IncidenceBase::Ptr &incidence) const +{ + return incidence->mimeType(); +} diff -Nru kdepim-runtime-4.14.6/resources/ical/shared/icalresource.h kdepim-runtime-15.08.0/resources/ical/shared/icalresource.h --- kdepim-runtime-4.14.6/resources/ical/shared/icalresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/shared/icalresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -23,34 +23,34 @@ #include "icalresourcebase.h" -#include +#include class ICalResource : public ICalResourceBase { - Q_OBJECT + Q_OBJECT - public: - explicit ICalResource( const QString &id ); +public: + explicit ICalResource(const QString &id); ~ICalResource(); - protected: +protected: /** * Constructor for derived classes. * @param mimeTypes mimeTypes to be handled by the resource. * @param icon icon name to use. */ - ICalResource( const QString &id, const QStringList &mimeTypes, const QString& icon ); + ICalResource(const QString &id, const QStringList &mimeTypes, const QString &icon); - virtual bool doRetrieveItem( const Akonadi::Item &item, const QSet &parts ); - virtual void doRetrieveItems( const Akonadi::Collection &col ); + bool doRetrieveItem(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + void doRetrieveItems(const Akonadi::Collection &col) Q_DECL_OVERRIDE; - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection& ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; /** Returns the Akonadi specific @c text/calendar sub MIME type of the given @p incidence. */ - virtual QString mimeType( const KCalCore::IncidenceBase::Ptr &incidence ) const; + virtual QString mimeType(const KCalCore::IncidenceBase::Ptr &incidence) const; /** Returns a list of all calendar component sub MIME types. diff -Nru kdepim-runtime-4.14.6/resources/ical/tests/CMakeLists.txt kdepim-runtime-15.08.0/resources/ical/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/ical/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ical-empty.xml ${CMAKE_CURRENT_BINARY_DIR}/ical-empty.xml COPYONLY) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ical-step1.xml ${CMAKE_CURRENT_BINARY_DIR}/ical-step1.xml COPYONLY) - -akonadi_add_resourcetest( ical icaltest.es ) diff -Nru kdepim-runtime-4.14.6/resources/ical/tests/event.ical kdepim-runtime-15.08.0/resources/ical/tests/event.ical --- kdepim-runtime-4.14.6/resources/ical/tests/event.ical 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/tests/event.ical 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -BEGIN:VCALENDAR -PRODID:-//K Desktop Environment//NONSGML libkcal 3.5//EN -VERSION:2.0 -BEGIN:VEVENT -DTSTAMP:20070109T100625Z -ORGANIZER;CN=Volker Krause:MAILTO:vkrause@kde.org -CREATED:20070109T100553Z -UID:libkcal-1135684253.945 -SEQUENCE:1 -LAST-MODIFIED:20070109T100625Z -SUMMARY:Test event -LOCATION:here -CLASS:PUBLIC -PRIORITY:5 -CATEGORIES:KDE -DTSTART:20070109T183000Z -DTEND:20070109T225900Z -TRANSP:OPAQUE -BEGIN:VALARM -DESCRIPTION: -ACTION:DISPLAY -TRIGGER;VALUE=DURATION:-PT45M -END:VALARM -END:VEVENT -END:VCALENDAR - diff -Nru kdepim-runtime-4.14.6/resources/ical/tests/ical-empty.xml kdepim-runtime-15.08.0/resources/ical/tests/ical-empty.xml --- kdepim-runtime-4.14.6/resources/ical/tests/ical-empty.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/tests/ical-empty.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ - - - ("newical.ics" "office-calendar") - wcdW - - diff -Nru kdepim-runtime-4.14.6/resources/ical/tests/ical-step1.xml kdepim-runtime-15.08.0/resources/ical/tests/ical-step1.xml --- kdepim-runtime-4.14.6/resources/ical/tests/ical-step1.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/tests/ical-step1.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ - - - ("newical.ics" "office-calendar") - wcdW - - BEGIN:VCALENDAR -PRODID:-//K Desktop Environment//NONSGML libkcal 3.2//EN -VERSION:2.0 -BEGIN:VEVENT -DTSTAMP:20090412T123141Z -ORGANIZER;CN="Volker Krause":MAILTO:vkrause@kde.org -CREATED:20070109T100553Z -UID:libkcal-1135684253.945 -SEQUENCE:1 -LAST-MODIFIED:20070109T100625Z -SUMMARY:Test event -LOCATION:here -PRIORITY:5 -CATEGORIES:KDE -DTSTART:20070109T183000Z -DTEND:20070109T225900Z -TRANSP:OPAQUE -BEGIN:VALARM -DESCRIPTION: -ACTION:DISPLAY -TRIGGER;VALUE=DURATION:-PT45M -END:VALARM -END:VEVENT - -END:VCALENDAR - - - BEGIN:VCALENDAR -PRODID:-//K Desktop Environment//NONSGML libkcal 3.2//EN -VERSION:2.0 -BEGIN:VTODO -DTSTAMP:20090412T123141Z -ORGANIZER:MAILTO:vkrause@kde.org -CREATED:20040505T094143Z -UID:libkcal-1506191911.958 -LAST-MODIFIED:20040512T133925Z -SUMMARY:Add a demo task to this file -PRIORITY:3 -DUE;VALUE=DATE:20090101 -COMPLETED:20090101T133925Z -PERCENT-COMPLETE:100 -END:VTODO - -END:VCALENDAR - - - diff -Nru kdepim-runtime-4.14.6/resources/ical/tests/icaltest.es kdepim-runtime-15.08.0/resources/ical/tests/icaltest.es --- kdepim-runtime-4.14.6/resources/ical/tests/icaltest.es 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/tests/icaltest.es 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -Resource.setType( "akonadi_ical_resource" ); -Resource.setPathOption( "Path", "newical.ics" ); -Resource.create(); - -XmlOperations.setXmlFile( "ical-empty.xml" ); -XmlOperations.setRootCollections( Resource.identifier() ); -XmlOperations.setCollectionKey( "None" ); -XmlOperations.ignoreCollectionField( "Name" ); // name is the resource identifier and thus unpredictable -XmlOperations.setNormalizeRemoteIds( true ); -XmlOperations.assertEqual(); - -// item creation -var i1 = ItemTest.newInstance(); -i1.setParentCollection( Resource.identifier() ); -i1.setMimeType( "text/calendar" ); -i1.setPayloadFromFile( "event.ical" ); -i1.create(); - -var i2 = ItemTest.newInstance(); -i2.setParentCollection( Resource.identifier() ); -i2.setMimeType( "text/calendar" ); -i2.setPayloadFromFile( "task.ical" ); -i2.create(); - -Resource.recreate(); - -XmlOperations.setXmlFile( "ical-step1.xml" ); -XmlOperations.setRootCollections( Resource.identifier() ); -XmlOperations.ignoreCollectionField( "None" ); -XmlOperations.assertEqual(); - diff -Nru kdepim-runtime-4.14.6/resources/ical/tests/task.ical kdepim-runtime-15.08.0/resources/ical/tests/task.ical --- kdepim-runtime-4.14.6/resources/ical/tests/task.ical 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/tests/task.ical 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -BEGIN:VCALENDAR -PRODID:-//K Desktop Environment//NONSGML libkcal 3.5//EN -VERSION:2.0 -BEGIN:VTODO -DTSTAMP:20090101T154017Z -ORGANIZER:MAILTO:vkrause@kde.org -CREATED:20040505T094143Z -UID:libkcal-1506191911.958 -LAST-MODIFIED:20040512T133925Z -SUMMARY:Add a demo task to this file -PRIORITY:3 -DUE;VALUE=DATE:20090101 -COMPLETED:20090101T133925Z -PERCENT-COMPLETE:100 -END:VTODO -END:VCALENDAR diff -Nru kdepim-runtime-4.14.6/resources/ical/wizard/CMakeLists.txt kdepim-runtime-15.08.0/resources/ical/wizard/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/ical/wizard/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/ical/wizard/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,4 +1,4 @@ set(ICAL_FILE_DEFAULT_PATH "$HOME/.local/share/korganizer/calendar.ics") configure_file(icalwizard.es.cmake ${CMAKE_CURRENT_BINARY_DIR}/icalwizard.es) -install ( FILES icalwizard.desktop ${CMAKE_CURRENT_BINARY_DIR}/icalwizard.es icalwizard.ui DESTINATION ${DATA_INSTALL_DIR}/akonadi/accountwizard/ical ) +install ( FILES icalwizard.desktop ${CMAKE_CURRENT_BINARY_DIR}/icalwizard.es icalwizard.ui DESTINATION ${KDE_INSTALL_DATADIR}/akonadi/accountwizard/ical ) diff -Nru kdepim-runtime-4.14.6/resources/icaldir/CMakeLists.txt kdepim-runtime-15.08.0/resources/icaldir/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/icaldir/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/icaldir/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,30 +1,26 @@ -include_directories( - ${kdepim-runtime_SOURCE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} -) -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_icaldir_resource\") ########### next target ############### set( icaldirresource_SRCS icaldirresource.cpp - ../shared/dirsettingsdialog.cpp + dirsettingsdialog.cpp ) -kde4_add_ui_files(icaldirresource_SRCS settingsdialog.ui) -kde4_add_kcfg_files(icaldirresource_SRCS settings.kcfgc) +ki18n_wrap_ui(icaldirresource_SRCS settingsdialog.ui) +kconfig_add_kcfg_files(icaldirresource_SRCS settings.kcfgc) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/icaldirresource.kcfg org.kde.Akonadi.ICalDirectory.Settings) -qt4_add_dbus_adaptor(icaldirresource_SRCS +qt5_add_dbus_adaptor(icaldirresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.ICalDirectory.Settings.xml settings.h Settings ) -install( FILES icaldirresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) +install( FILES icaldirresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) -kde4_add_executable(akonadi_icaldir_resource ${icaldirresource_SRCS}) +add_executable(akonadi_icaldir_resource ${icaldirresource_SRCS}) -if (Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_icaldir_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) set_target_properties(akonadi_icaldir_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.ICalDirectory") set_target_properties(akonadi_icaldir_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi ICalDirectory Resource") @@ -32,11 +28,10 @@ target_link_libraries(akonadi_icaldir_resource - ${KDEPIMLIBS_AKONADI_LIBS} - ${QT_QTCORE_LIBRARY} - ${KDE4_KDECORE_LIBS} - ${KDEPIMLIBS_KCALCORE_LIBS} - ${KDE4_KIO_LIBS} + KF5::AkonadiCore + KF5::AkonadiAgentBase + KF5::CalendarCore + KF5::KIOCore ) -install(TARGETS akonadi_icaldir_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(TARGETS akonadi_icaldir_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/icaldir/dirsettingsdialog.cpp kdepim-runtime-15.08.0/resources/icaldir/dirsettingsdialog.cpp --- kdepim-runtime-4.14.6/resources/icaldir/dirsettingsdialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/icaldir/dirsettingsdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,93 @@ +/* + Copyright (c) 2009 Tobias Koenig + + 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 "dirsettingsdialog.h" + +#include "settings.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +using namespace Akonadi; + +SettingsDialog::SettingsDialog(WId windowId) + : QDialog() +{ + QWidget *mainWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); + ui.setupUi(mainWidget); + ui.kcfg_Path->setMode(KFile::LocalOnly | KFile::Directory); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + mOkButton = buttonBox->button(QDialogButtonBox::Ok); + mOkButton->setDefault(true); + mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &SettingsDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &SettingsDialog::reject); + mainLayout->addWidget(buttonBox); + + if (windowId) { + KWindowSystem::setMainWindow(this, windowId); + } + + connect(mOkButton, &QPushButton::clicked, this, &SettingsDialog::save); + + connect(ui.kcfg_Path, &KUrlRequester::textChanged, this, &SettingsDialog::validate); + connect(ui.kcfg_ReadOnly, &QCheckBox::toggled, this, &SettingsDialog::validate); + + QTimer::singleShot(0, this, SLOT(validate())); + + ui.kcfg_Path->setUrl(QUrl::fromLocalFile(Settings::self()->path())); + ui.kcfg_AutosaveInterval->setSuffix(ki18np(" minute", " minutes")); + mManager = new KConfigDialogManager(this, Settings::self()); + mManager->updateWidgets(); +} + +void SettingsDialog::save() +{ + mManager->updateSettings(); + Settings::self()->setPath(ui.kcfg_Path->url().toLocalFile()); + Settings::self()->save(); +} + +void SettingsDialog::validate() +{ + const QUrl currentUrl = ui.kcfg_Path->url(); + if (currentUrl.isEmpty()) { + mOkButton->setEnabled(false); + return; + } + + const QFileInfo file(currentUrl.toLocalFile()); + if (file.exists() && !file.isWritable()) { + ui.kcfg_ReadOnly->setEnabled(false); + ui.kcfg_ReadOnly->setChecked(true); + } else { + ui.kcfg_ReadOnly->setEnabled(true); + } + mOkButton->setEnabled(true); +} diff -Nru kdepim-runtime-4.14.6/resources/icaldir/dirsettingsdialog.h kdepim-runtime-15.08.0/resources/icaldir/dirsettingsdialog.h --- kdepim-runtime-4.14.6/resources/icaldir/dirsettingsdialog.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/icaldir/dirsettingsdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,51 @@ +/* + Copyright (c) 2009 Tobias Koenig + + 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 DIRSETTINGSDIALOG_H +#define DIRSETTINGSDIALOG_H + +#include "ui_settingsdialog.h" + +#include +#include + +class KConfigDialogManager; + +namespace Akonadi +{ + +class SettingsDialog : public QDialog +{ + Q_OBJECT +public: + explicit SettingsDialog(WId windowId); + +private Q_SLOTS: + void save(); + void validate(); + +private: + Ui::SettingsDialog ui; + KConfigDialogManager *mManager; + QPushButton *mOkButton; +}; + +} + +#endif diff -Nru kdepim-runtime-4.14.6/resources/icaldir/icaldirresource.cpp kdepim-runtime-15.08.0/resources/icaldir/icaldirresource.cpp --- kdepim-runtime-4.14.6/resources/icaldir/icaldirresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/icaldir/icaldirresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,15 +22,18 @@ #include "icaldirresource.h" #include "settingsadaptor.h" -#include "../shared/dirsettingsdialog.h" +#include "dirsettingsdialog.h" -#include -#include -#include +#include +#include +#include #include #include #include +#include +#include +#include #include #include @@ -39,52 +42,53 @@ using namespace Akonadi; using namespace KCalCore; -static Incidence::Ptr readFromFile( const QString &fileName, const QString &expectedIdentifier ) +static Incidence::Ptr readFromFile(const QString &fileName, const QString &expectedIdentifier) { - MemoryCalendar::Ptr calendar = MemoryCalendar::Ptr( new MemoryCalendar( QLatin1String( "UTC" ) ) ); - FileStorage::Ptr fileStorage = FileStorage::Ptr( new FileStorage( calendar, fileName, new ICalFormat() ) ); + MemoryCalendar::Ptr calendar = MemoryCalendar::Ptr(new MemoryCalendar(QStringLiteral("UTC"))); + FileStorage::Ptr fileStorage = FileStorage::Ptr(new FileStorage(calendar, fileName, new ICalFormat())); - Incidence::Ptr incidence; - if ( fileStorage->load() ) { - Incidence::List incidences = calendar->incidences(); - if ( incidences.count() == 1 && incidences.first()->instanceIdentifier() == expectedIdentifier ) - incidence = incidences.first(); - } else { - kError() << "Error loading file " << fileName; - } + Incidence::Ptr incidence; + if (fileStorage->load()) { + Incidence::List incidences = calendar->incidences(); + if (incidences.count() == 1 && incidences.first()->instanceIdentifier() == expectedIdentifier) { + incidence = incidences.first(); + } + } else { + qCritical() << "Error loading file " << fileName; + } - return incidence; + return incidence; } -static bool writeToFile( const QString &fileName, Incidence::Ptr &incidence ) +static bool writeToFile(const QString &fileName, Incidence::Ptr &incidence) { - if ( !incidence ) { - kError() << "incidence is 0!"; - return false; - } - - MemoryCalendar::Ptr calendar = MemoryCalendar::Ptr( new MemoryCalendar( QLatin1String( "UTC" ) ) ); - FileStorage::Ptr fileStorage = FileStorage::Ptr( new FileStorage( calendar, fileName, new ICalFormat() ) ); - calendar->addIncidence( incidence ); - Q_ASSERT( calendar->incidences().count() == 1 ); + if (!incidence) { + qCritical() << "incidence is 0!"; + return false; + } - const bool success = fileStorage->save(); - if ( !success ) { - kError() << "Failed to save calendar to file " + fileName; - } + MemoryCalendar::Ptr calendar = MemoryCalendar::Ptr(new MemoryCalendar(QStringLiteral("UTC"))); + FileStorage::Ptr fileStorage = FileStorage::Ptr(new FileStorage(calendar, fileName, new ICalFormat())); + calendar->addIncidence(incidence); + Q_ASSERT(calendar->incidences().count() == 1); + + const bool success = fileStorage->save(); + if (!success) { + qCritical() << "Failed to save calendar to file " + fileName; + } - return success; + return success; } -ICalDirResource::ICalDirResource( const QString &id ) - : ResourceBase( id ) +ICalDirResource::ICalDirResource(const QString &id) + : ResourceBase(id) { - // setup the resource - new SettingsAdaptor( Settings::self() ); - QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ), - Settings::self(), QDBusConnection::ExportAdaptors ); + // setup the resource + new SettingsAdaptor(Settings::self()); + QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"), + Settings::self(), QDBusConnection::ExportAdaptors); - changeRecorder()->itemFetchScope().fetchFullPayload(); + changeRecorder()->itemFetchScope().fetchFullPayload(); } ICalDirResource::~ICalDirResource() @@ -93,214 +97,219 @@ void ICalDirResource::aboutToQuit() { - Settings::self()->writeConfig(); + Settings::self()->save(); } -void ICalDirResource::configure( WId windowId ) +void ICalDirResource::configure(WId windowId) { - SettingsDialog dlg( windowId ); - dlg.setWindowIcon( KIcon( "text-calendar" ) ); - if ( dlg.exec() ) { - initializeICalDirectory(); - loadIncidences(); + SettingsDialog dlg(windowId); + dlg.setWindowIcon(QIcon::fromTheme("text-calendar")); + if (dlg.exec()) { + initializeICalDirectory(); + loadIncidences(); - synchronize(); + synchronize(); - emit configurationDialogAccepted(); - } else { - emit configurationDialogRejected(); - } + Q_EMIT configurationDialogAccepted(); + } else { + Q_EMIT configurationDialogRejected(); + } } bool ICalDirResource::loadIncidences() { - mIncidences.clear(); + mIncidences.clear(); - QDirIterator it( iCalDirectoryName() ); - while ( it.hasNext() ) { - it.next(); - if ( it.fileName() != "." && it.fileName() != ".." && it.fileName() != "WARNING_README.txt" ) { - const KCalCore::Incidence::Ptr incidence = readFromFile( it.filePath(), it.fileName() ); - if ( incidence ) { - mIncidences.insert( incidence->instanceIdentifier(), incidence ); - } + QDirIterator it(iCalDirectoryName()); + while (it.hasNext()) { + it.next(); + if (it.fileName() != "." && it.fileName() != ".." && it.fileName() != "WARNING_README.txt") { + const KCalCore::Incidence::Ptr incidence = readFromFile(it.filePath(), it.fileName()); + if (incidence) { + mIncidences.insert(incidence->instanceIdentifier(), incidence); + } + } } - } - emit status( Idle ); - return true; + Q_EMIT status(Idle); + return true; } -bool ICalDirResource::retrieveItem( const Akonadi::Item &item, const QSet& ) +bool ICalDirResource::retrieveItem(const Akonadi::Item &item, const QSet &) { - const QString remoteId = item.remoteId(); - if ( !mIncidences.contains( remoteId ) ) { - emit error( i18n( "Incidence with uid '%1' not found.", remoteId ) ); - return false; - } + const QString remoteId = item.remoteId(); + if (!mIncidences.contains(remoteId)) { + Q_EMIT error(i18n("Incidence with uid '%1' not found.", remoteId)); + return false; + } - Item newItem( item ); - newItem.setPayload( mIncidences.value( remoteId ) ); - itemRetrieved( newItem ); + Item newItem(item); + newItem.setPayload(mIncidences.value(remoteId)); + itemRetrieved(newItem); - return true; + return true; } -void ICalDirResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection& ) +void ICalDirResource::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &) { - if ( Settings::self()->readOnly() ) { - emit error( i18n( "Trying to write to a read-only directory: '%1'", iCalDirectoryName() ) ); - cancelTask(); - return; - } - - KCalCore::Incidence::Ptr incidence; - if ( item.hasPayload() ) - incidence = item.payload(); - - if ( incidence ) { - // add it to the cache... - mIncidences.insert( incidence->instanceIdentifier(), incidence ); + if (Settings::self()->readOnly()) { + Q_EMIT error(i18n("Trying to write to a read-only directory: '%1'", iCalDirectoryName())); + cancelTask(); + return; + } - // ... and write it through to the file system - const bool success = writeToFile( iCalDirectoryFileName( incidence->instanceIdentifier() ), incidence ); + KCalCore::Incidence::Ptr incidence; + if (item.hasPayload()) { + incidence = item.payload(); + } - if ( success ) { - // report everything ok - Item newItem( item ); - newItem.setRemoteId( incidence->instanceIdentifier() ); - changeCommitted( newItem ); + if (incidence) { + // add it to the cache... + mIncidences.insert(incidence->instanceIdentifier(), incidence); + + // ... and write it through to the file system + const bool success = writeToFile(iCalDirectoryFileName(incidence->instanceIdentifier()), incidence); + + if (success) { + // report everything ok + Item newItem(item); + newItem.setRemoteId(incidence->instanceIdentifier()); + changeCommitted(newItem); + } else { + cancelTask(); + } } else { - cancelTask(); + changeProcessed(); } - } else { - changeProcessed(); - } } -void ICalDirResource::itemChanged( const Akonadi::Item &item, const QSet& ) +void ICalDirResource::itemChanged(const Akonadi::Item &item, const QSet &) { - if ( Settings::self()->readOnly() ) { - emit error( i18n( "Trying to write to a read-only directory: '%1'", iCalDirectoryName() ) ); - cancelTask(); - return; - } + if (Settings::self()->readOnly()) { + Q_EMIT error(i18n("Trying to write to a read-only directory: '%1'", iCalDirectoryName())); + cancelTask(); + return; + } - KCalCore::Incidence::Ptr incidence; - if ( item.hasPayload() ) - incidence = item.payload(); + KCalCore::Incidence::Ptr incidence; + if (item.hasPayload()) { + incidence = item.payload(); + } - if ( incidence ) { - // change it in the cache... - mIncidences.insert( incidence->instanceIdentifier(), incidence ); + if (incidence) { + // change it in the cache... + mIncidences.insert(incidence->instanceIdentifier(), incidence); + + // ... and write it through to the file system + const bool success = writeToFile(iCalDirectoryFileName(incidence->instanceIdentifier()), incidence); + + if (success) { + Item newItem(item); + newItem.setRemoteId(incidence->instanceIdentifier()); + changeCommitted(newItem); + } else { + cancelTask(); + } + } else { + changeProcessed(); + } +} - // ... and write it through to the file system - const bool success = writeToFile( iCalDirectoryFileName( incidence->instanceIdentifier() ), incidence ); +void ICalDirResource::itemRemoved(const Akonadi::Item &item) +{ + if (Settings::self()->readOnly()) { + Q_EMIT error(i18n("Trying to write to a read-only directory: '%1'", iCalDirectoryName())); + cancelTask(); + return; + } - if ( success ) { - Item newItem( item ); - newItem.setRemoteId( incidence->instanceIdentifier() ); - changeCommitted( newItem ); - } else { - cancelTask(); + // remove it from the cache... + if (mIncidences.contains(item.remoteId())) { + mIncidences.remove(item.remoteId()); } - } else { + + // ... and remove it from the file system + QFile::remove(iCalDirectoryFileName(item.remoteId())); + changeProcessed(); - } } -void ICalDirResource::itemRemoved( const Akonadi::Item &item ) +void ICalDirResource::retrieveCollections() { - if ( Settings::self()->readOnly() ) { - emit error( i18n( "Trying to write to a read-only directory: '%1'", iCalDirectoryName() ) ); - cancelTask(); - return; - } + Collection c; + c.setParentCollection(Collection::root()); + c.setRemoteId(iCalDirectoryName()); + c.setName(name()); + + QStringList mimetypes; + mimetypes << KCalCore::Event::eventMimeType() << KCalCore::Todo::todoMimeType() << KCalCore::Journal::journalMimeType() << "text/calendar"; + c.setContentMimeTypes(mimetypes); - // remove it from the cache... - if ( mIncidences.contains( item.remoteId() ) ) - mIncidences.remove( item.remoteId() ); + if (Settings::self()->readOnly()) { + c.setRights(Collection::CanChangeCollection); + } else { + Collection::Rights rights = Collection::ReadOnly; + rights |= Collection::CanChangeItem; + rights |= Collection::CanCreateItem; + rights |= Collection::CanDeleteItem; + rights |= Collection::CanChangeCollection; + c.setRights(rights); + } - // ... and remove it from the file system - QFile::remove( iCalDirectoryFileName( item.remoteId() ) ); + EntityDisplayAttribute *attr = c.attribute(Collection::AddIfMissing); + attr->setDisplayName(i18n("Calendar Folder")); + attr->setIconName("office-calendar"); - changeProcessed(); + Collection::List list; + list << c; + collectionsRetrieved(list); } -void ICalDirResource::retrieveCollections() +void ICalDirResource::retrieveItems(const Akonadi::Collection &) { - Collection c; - c.setParentCollection( Collection::root() ); - c.setRemoteId( iCalDirectoryName() ); - c.setName( name() ); - - QStringList mimetypes; - mimetypes << KCalCore::Event::eventMimeType() << KCalCore::Todo::todoMimeType() << KCalCore::Journal::journalMimeType() << "text/calendar"; - c.setContentMimeTypes( mimetypes ); - - if ( Settings::self()->readOnly() ) { - c.setRights( Collection::CanChangeCollection ); - } else { - Collection::Rights rights = Collection::ReadOnly; - rights |= Collection::CanChangeItem; - rights |= Collection::CanCreateItem; - rights |= Collection::CanDeleteItem; - rights |= Collection::CanChangeCollection; - c.setRights( rights ); - } - - EntityDisplayAttribute* attr = c.attribute( Collection::AddIfMissing ); - attr->setDisplayName( i18n( "Calendar Folder" ) ); - attr->setIconName( "office-calendar" ); - - Collection::List list; - list << c; - collectionsRetrieved( list ); -} - -void ICalDirResource::retrieveItems( const Akonadi::Collection& ) -{ - loadIncidences(); - Item::List items; - - foreach ( const KCalCore::Incidence::Ptr &incidence, mIncidences ) { - Item item; - item.setRemoteId( incidence->instanceIdentifier() ); - item.setMimeType( incidence->mimeType() ); - items.append( item ); - } + loadIncidences(); + Item::List items; + items.reserve(mIncidences.count()); + + foreach (const KCalCore::Incidence::Ptr &incidence, mIncidences) { + Item item; + item.setRemoteId(incidence->instanceIdentifier()); + item.setMimeType(incidence->mimeType()); + items.append(item); + } - itemsRetrieved( items ); + itemsRetrieved(items); } QString ICalDirResource::iCalDirectoryName() const { - return Settings::self()->path(); + return Settings::self()->path(); } -QString ICalDirResource::iCalDirectoryFileName( const QString &file ) const +QString ICalDirResource::iCalDirectoryFileName(const QString &file) const { - return Settings::self()->path() + QDir::separator() + file; + return Settings::self()->path() + QDir::separator() + file; } void ICalDirResource::initializeICalDirectory() const { - QDir dir( iCalDirectoryName() ); + QDir dir(iCalDirectoryName()); + + // if folder does not exists, create it + if (!dir.exists()) { + QDir::root().mkpath(dir.absolutePath()); + } - // if folder does not exists, create it - if ( !dir.exists() ) - QDir::root().mkpath( dir.absolutePath() ); - - // check whether warning file is in place... - QFile file( dir.absolutePath() + QDir::separator() + "WARNING_README.txt" ); - if ( !file.exists() ) { - // ... if not, create it - file.open( QIODevice::WriteOnly ); - file.write( "Important Warning!!!\n\n" - "Don't create or copy files inside this folder manually, they are managed by the Akonadi framework!\n" ); - file.close(); - } + // check whether warning file is in place... + QFile file(dir.absolutePath() + QDir::separator() + "WARNING_README.txt"); + if (!file.exists()) { + // ... if not, create it + file.open(QIODevice::WriteOnly); + file.write("Important Warning!!!\n\n" + "Don't create or copy files inside this folder manually, they are managed by the Akonadi framework!\n"); + file.close(); + } } -AKONADI_RESOURCE_MAIN( ICalDirResource ) +AKONADI_RESOURCE_MAIN(ICalDirResource) diff -Nru kdepim-runtime-4.14.6/resources/icaldir/icaldirresource.desktop kdepim-runtime-15.08.0/resources/icaldir/icaldirresource.desktop --- kdepim-runtime-4.14.6/resources/icaldir/icaldirresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/icaldir/icaldirresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,6 @@ [Desktop Entry] Name=ICal Calendar Folder +Name[bg]=Календарна папка iCal Name[bs]=ICal kalendarska datoteka Name[ca]=Carpeta de calendari ICal Name[ca@valencia]=Carpeta de calendari ICal @@ -67,6 +68,7 @@ Comment[pt_BR]="Fornece acesso aos itens do calendário, cada um armazenado em um único arquivo na pasta indicada" Comment[ru]="Обеспечивает доступ к элементам календаря, каждый из которых хранится в отдельном файле в указанном каталоге" Comment[sk]="Poskytuje prístup do položiek kalendára, každá uložená v jednom súbore v danom adresári" +Comment[sl]=»Nudi dostop do koledarskih vnosov, ki so shranjeni vsak posebej v svoji datoteki, v dani mapi« Comment[sr]="Омогућава приступ календарским ставкама, складиштеним у по једном фајлу у датој фасцикли" Comment[sr@ijekavian]="Омогућава приступ календарским ставкама, складиштеним у по једном фајлу у датој фасцикли" Comment[sr@ijekavianlatin]="Omogućava pristup kalendarskim stavkama, skladištenim u po jednom fajlu u datoj fascikli" diff -Nru kdepim-runtime-4.14.6/resources/icaldir/icaldirresource.h kdepim-runtime-15.08.0/resources/icaldir/icaldirresource.h --- kdepim-runtime-4.14.6/resources/icaldir/icaldirresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/icaldir/icaldirresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -21,7 +21,7 @@ #ifndef ICALDIRRESOURCE_H #define ICALDIRRESOURCE_H -#include +#include #include @@ -29,33 +29,33 @@ class ICalDirResource : public Akonadi::ResourceBase, public Akonadi::AgentBase::Observer { - Q_OBJECT + Q_OBJECT - public: - explicit ICalDirResource( const QString &id ); +public: + explicit ICalDirResource(const QString &id); ~ICalDirResource(); - public Q_SLOTS: - virtual void configure( WId windowId ); - virtual void aboutToQuit(); - - protected Q_SLOTS: - void retrieveCollections(); - void retrieveItems( const Akonadi::Collection &col ); - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - - protected: - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); - virtual void itemRemoved( const Akonadi::Item &item ); +public Q_SLOTS: + void configure(WId windowId) Q_DECL_OVERRIDE; + void aboutToQuit() Q_DECL_OVERRIDE; + +protected Q_SLOTS: + void retrieveCollections() Q_DECL_OVERRIDE; + void retrieveItems(const Akonadi::Collection &col) Q_DECL_OVERRIDE; + bool retrieveItem(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + +protected: + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + void itemRemoved(const Akonadi::Item &item) Q_DECL_OVERRIDE; - private: +private: bool loadIncidences(); QString iCalDirectoryName() const; - QString iCalDirectoryFileName( const QString &file ) const; + QString iCalDirectoryFileName(const QString &file) const; void initializeICalDirectory() const; - private: +private: QHash mIncidences; }; diff -Nru kdepim-runtime-4.14.6/resources/icaldir/settingsdialog.ui kdepim-runtime-15.08.0/resources/icaldir/settingsdialog.ui --- kdepim-runtime-4.14.6/resources/icaldir/settingsdialog.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/icaldir/settingsdialog.ui 2015-08-10 21:01:02.000000000 +0000 @@ -11,7 +11,7 @@ - + 0 @@ -122,7 +122,7 @@ - + 1 @@ -167,15 +167,9 @@ - KIntSpinBox + KPluralHandlingSpinBox QSpinBox -
knuminput.h
-
- - KTabWidget - QTabWidget -
ktabwidget.h
- 1 +
KPluralHandlingSpinBox
KUrlRequester diff -Nru kdepim-runtime-4.14.6/resources/imap/addcollectiontask.cpp kdepim-runtime-15.08.0/resources/imap/addcollectiontask.cpp --- kdepim-runtime-4.14.6/resources/imap/addcollectiontask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/addcollectiontask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,18 +23,19 @@ #include "collectionannotationsattribute.h" -#include -#include +#include "imapresource_debug.h" +#include "imapresource_debug.h" +#include #include #include #include #include -#include +#include -AddCollectionTask::AddCollectionTask( ResourceStateInterface::Ptr resource, QObject *parent ) - : ResourceTask( DeferIfNoSession, resource, parent ), m_pendingJobs( 0 ), m_session(0) +AddCollectionTask::AddCollectionTask(ResourceStateInterface::Ptr resource, QObject *parent) + : ResourceTask(DeferIfNoSession, resource, parent), m_pendingJobs(0), m_session(Q_NULLPTR) { } @@ -42,115 +43,117 @@ { } -void AddCollectionTask::doStart( KIMAP::Session *session ) +void AddCollectionTask::doStart(KIMAP::Session *session) { - if ( parentCollection().remoteId().isEmpty() ) { - emitError( i18n( "Cannot add IMAP folder '%1' for a non-existing parent folder '%2'.", - collection().name(), - parentCollection().name() ) ); - changeProcessed(); - return; - } + if (parentCollection().remoteId().isEmpty()) { + qCWarning(IMAPRESOURCE_LOG) << "Parent collection has no remote id, aborting." << collection().name() << parentCollection().name(); + emitError(i18n("Cannot add IMAP folder '%1' for a non-existing parent folder '%2'.", + collection().name(), + parentCollection().name())); + changeProcessed(); + return; + } - const QChar separator = separatorCharacter(); - m_pendingJobs = 0; - m_session = session; - m_collection = collection(); - m_collection.setName( m_collection.name().replace( separator, QString() ) ); - m_collection.setRemoteId( separator + m_collection.name() ); + const QChar separator = separatorCharacter(); + m_pendingJobs = 0; + m_session = session; + m_collection = collection(); + m_collection.setName(m_collection.name().replace(separator, QString())); + m_collection.setRemoteId(separator + m_collection.name()); - QString newMailBox = mailBoxForCollection( parentCollection() ); + QString newMailBox = mailBoxForCollection(parentCollection()); - if ( !newMailBox.isEmpty() ) - newMailBox += separator; + if (!newMailBox.isEmpty()) { + newMailBox += separator; + } - newMailBox += m_collection.name(); + newMailBox += m_collection.name(); - kDebug( 5327 ) << "New folder: " << newMailBox; + qCDebug(IMAPRESOURCE_LOG) << "New folder: " << newMailBox; - KIMAP::CreateJob *job = new KIMAP::CreateJob( session ); - job->setMailBox( newMailBox ); + KIMAP::CreateJob *job = new KIMAP::CreateJob(session); + job->setMailBox(newMailBox); - connect( job, SIGNAL(result(KJob*)), - this, SLOT(onCreateDone(KJob*)) ); + connect(job, &KIMAP::CreateJob::result, this, &AddCollectionTask::onCreateDone); - job->start(); + job->start(); } - -void AddCollectionTask::onCreateDone( KJob *job ) +void AddCollectionTask::onCreateDone(KJob *job) { - if ( job->error() ) { - emitError( i18n( "Failed to create the folder '%1' on the IMAP server. ", - m_collection.name() ) ); - cancelTask( job->errorString() ); - } else { - // Automatically subscribe to newly created mailbox - KIMAP::CreateJob *create = static_cast( job ); + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Failed to create folder on server: " << job->errorString(); + emitError(i18n("Failed to create the folder '%1' on the IMAP server. ", + m_collection.name())); + cancelTask(job->errorString()); + } else { + // Automatically subscribe to newly created mailbox + KIMAP::CreateJob *create = static_cast(job); - KIMAP::SubscribeJob *subscribe = new KIMAP::SubscribeJob( create->session() ); - subscribe->setMailBox( create->mailBox() ); + KIMAP::SubscribeJob *subscribe = new KIMAP::SubscribeJob(create->session()); + subscribe->setMailBox(create->mailBox()); - connect( subscribe, SIGNAL(result(KJob*)), - this, SLOT(onSubscribeDone(KJob*)) ); + connect(subscribe, &KIMAP::SubscribeJob::result, this, &AddCollectionTask::onSubscribeDone); - subscribe->start(); - } + subscribe->start(); + } } -void AddCollectionTask::onSubscribeDone( KJob *job ) +void AddCollectionTask::onSubscribeDone(KJob *job) { - if ( job->error() && isSubscriptionEnabled() ) { - emitWarning( i18n( "Failed to subscribe to the folder '%1' on the IMAP server. " - "It will disappear on next sync. Use the subscription dialog to overcome that", - m_collection.name() ) ); - } - - const Akonadi::CollectionAnnotationsAttribute *attribute = m_collection.attribute(); - if ( !attribute || !serverSupportsAnnotations() ) { - // we are finished - changeCommitted( m_collection ); - synchronizeCollectionTree(); - return; - } - - const QMap annotations = attribute->annotations(); - - foreach ( const QByteArray &entry, annotations.keys() ) { //krazy:exclude=foreach - KIMAP::SetMetaDataJob *job = new KIMAP::SetMetaDataJob( m_session ); - if ( serverCapabilities().contains( QLatin1String("METADATA") ) ) { - job->setServerCapability( KIMAP::MetaDataJobBase::Metadata ); - } else { - job->setServerCapability( KIMAP::MetaDataJobBase::Annotatemore ); + if (job->error() && isSubscriptionEnabled()) { + qCWarning(IMAPRESOURCE_LOG) << "Failed to subscribe to the new folder: " << job->errorString(); + emitWarning(i18n("Failed to subscribe to the folder '%1' on the IMAP server. " + "It will disappear on next sync. Use the subscription dialog to overcome that", + m_collection.name())); } - job->setMailBox( mailBoxForCollection( m_collection ) ); - if ( !entry.startsWith( "/shared" ) && !entry.startsWith( "/private" ) ) { - //Support for legacy annotations that don't include the prefix - job->addMetaData( QByteArray("/shared") + entry, annotations[entry] ); - } else { - job->addMetaData( entry, annotations[entry] ); + const Akonadi::CollectionAnnotationsAttribute *attribute = m_collection.attribute(); + if (!attribute || !serverSupportsAnnotations()) { + // we are finished + changeCommitted(m_collection); + synchronizeCollectionTree(); + return; } - connect( job, SIGNAL(result(KJob*)), - this, SLOT(onSetMetaDataDone(KJob*)) ); + const QMap annotations = attribute->annotations(); - m_pendingJobs++; + foreach (const QByteArray &entry, annotations.keys()) { //krazy:exclude=foreach + KIMAP::SetMetaDataJob *job = new KIMAP::SetMetaDataJob(m_session); + if (serverCapabilities().contains(QLatin1String("METADATA"))) { + job->setServerCapability(KIMAP::MetaDataJobBase::Metadata); + } else { + job->setServerCapability(KIMAP::MetaDataJobBase::Annotatemore); + } + job->setMailBox(mailBoxForCollection(m_collection)); + + if (!entry.startsWith("/shared") && !entry.startsWith("/private")) { + //Support for legacy annotations that don't include the prefix + job->addMetaData(QByteArray("/shared") + entry, annotations[entry]); + } else { + job->addMetaData(entry, annotations[entry]); + } - job->start(); - } + connect(job, &KIMAP::SetMetaDataJob::result, this, &AddCollectionTask::onSetMetaDataDone); + + m_pendingJobs++; + + job->start(); + } } -void AddCollectionTask::onSetMetaDataDone( KJob *job ) +void AddCollectionTask::onSetMetaDataDone(KJob *job) { - if ( job->error() ) { - emitWarning( i18n( "Failed to write some annotations for '%1' on the IMAP server. %2", - collection().name(), job->errorText() ) ); - } + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Failed to write annotations: " << job->errorString(); + emitWarning(i18n("Failed to write some annotations for '%1' on the IMAP server. %2", + collection().name(), job->errorText())); + } - m_pendingJobs--; + m_pendingJobs--; - if ( m_pendingJobs == 0 ) - changeCommitted( m_collection ); + if (m_pendingJobs == 0) { + changeCommitted(m_collection); + } } diff -Nru kdepim-runtime-4.14.6/resources/imap/addcollectiontask.h kdepim-runtime-15.08.0/resources/imap/addcollectiontask.h --- kdepim-runtime-4.14.6/resources/imap/addcollectiontask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/addcollectiontask.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,30 +24,31 @@ #include "resourcetask.h" -namespace KIMAP { +namespace KIMAP +{ class Session; } class AddCollectionTask : public ResourceTask { - Q_OBJECT + Q_OBJECT public: - explicit AddCollectionTask( ResourceStateInterface::Ptr resource, QObject *parent = 0 ); - virtual ~AddCollectionTask(); + explicit AddCollectionTask(ResourceStateInterface::Ptr resource, QObject *parent = Q_NULLPTR); + virtual ~AddCollectionTask(); -private slots: - void onCreateDone( KJob *job ); - void onSubscribeDone( KJob *job ); - void onSetMetaDataDone( KJob *job ); +private Q_SLOTS: + void onCreateDone(KJob *job); + void onSubscribeDone(KJob *job); + void onSetMetaDataDone(KJob *job); protected: - virtual void doStart( KIMAP::Session *session ); + void doStart(KIMAP::Session *session) Q_DECL_OVERRIDE; private: - Akonadi::Collection m_collection; - uint m_pendingJobs; - KIMAP::Session *m_session; + Akonadi::Collection m_collection; + uint m_pendingJobs; + KIMAP::Session *m_session; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/additemtask.cpp kdepim-runtime-15.08.0/resources/imap/additemtask.cpp --- kdepim-runtime-4.14.6/resources/imap/additemtask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/additemtask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,8 +23,9 @@ #include -#include -#include +#include "imapresource_debug.h" +#include "imapresource_debug.h" +#include #include #include @@ -36,8 +37,8 @@ #include "uidnextattribute.h" -AddItemTask::AddItemTask( ResourceStateInterface::Ptr resource, QObject *parent ) - : ResourceTask( DeferIfNoSession, resource, parent ) +AddItemTask::AddItemTask(ResourceStateInterface::Ptr resource, QObject *parent) + : ResourceTask(DeferIfNoSession, resource, parent) { } @@ -46,169 +47,168 @@ { } -void AddItemTask::doStart( KIMAP::Session *session ) +void AddItemTask::doStart(KIMAP::Session *session) { - if ( !item().hasPayload() ) { - changeProcessed(); - return; - } + if (!item().hasPayload()) { + changeProcessed(); + return; + } - const QString mailBox = mailBoxForCollection( collection() ); - if ( mailBox.isEmpty() ) { - kWarning() << "Trying to append message to invalid mailbox, this will fail. Id: " << parentCollection().id(); - } + const QString mailBox = mailBoxForCollection(collection()); + if (mailBox.isEmpty()) { + qCWarning(IMAPRESOURCE_LOG) << "Trying to append message to invalid mailbox, this will fail. Id: " << parentCollection().id(); + } - kDebug( 5327 ) << "Got notification about item added for local id " << item().id() << " and remote id " << item().remoteId(); + qCDebug(IMAPRESOURCE_LOG) << "Got notification about item added for local id " << item().id() << " and remote id " << item().remoteId(); - // save message to the server. - KMime::Message::Ptr msg = item().payload(); - m_messageId = msg->messageID()->asUnicodeString().toUtf8(); + // save message to the server. + KMime::Message::Ptr msg = item().payload(); + m_messageId = msg->messageID()->asUnicodeString().toUtf8(); - KIMAP::AppendJob *job = new KIMAP::AppendJob( session ); - job->setMailBox( mailBox ); - job->setContent( msg->encodedContent( true ) ); - job->setFlags( fromAkonadiToSupportedImapFlags( item().flags().toList(), collection() ) ); - job->setInternalDate( msg->date()->dateTime() ); - connect( job, SIGNAL(result(KJob*)), SLOT(onAppendMessageDone(KJob*)) ); - job->start(); + KIMAP::AppendJob *job = new KIMAP::AppendJob(session); + job->setMailBox(mailBox); + job->setContent(msg->encodedContent(true)); + job->setFlags(fromAkonadiToSupportedImapFlags(item().flags().toList(), collection())); + job->setInternalDate(msg->date()->dateTime()); + connect(job, &KIMAP::AppendJob::result, this, &AddItemTask::onAppendMessageDone); + job->start(); } - -void AddItemTask::onAppendMessageDone( KJob *job ) +void AddItemTask::onAppendMessageDone(KJob *job) { - KIMAP::AppendJob *append = qobject_cast( job ); - - if ( append->error() ) { - kWarning() << append->errorString(); - cancelTask( append->errorString() ); - return; - } - - qint64 uid = append->uid(); - - if ( uid > 0 ) { - // We got it directly if UIDPLUS is supported... - applyFoundUid( uid ); + KIMAP::AppendJob *append = qobject_cast(job); - } else { - // ... otherwise prepare searching for the message - KIMAP::Session *session = append->session(); - const QString mailBox = append->mailBox(); - - if ( session->selectedMailBox() != mailBox ) { - KIMAP::SelectJob *select = new KIMAP::SelectJob( session ); - select->setMailBox( mailBox ); + if (append->error()) { + qCWarning(IMAPRESOURCE_LOG) << append->errorString(); + cancelTask(append->errorString()); + return; + } - connect( select, SIGNAL(result(KJob*)), - this, SLOT(onPreSearchSelectDone(KJob*)) ); + qint64 uid = append->uid(); - select->start(); + if (uid > 0) { + // We got it directly if UIDPLUS is supported... + applyFoundUid(uid); } else { - triggerSearchJob( session ); + // ... otherwise prepare searching for the message + KIMAP::Session *session = append->session(); + const QString mailBox = append->mailBox(); + + if (session->selectedMailBox() != mailBox) { + KIMAP::SelectJob *select = new KIMAP::SelectJob(session); + select->setMailBox(mailBox); + + connect(select, SIGNAL(result(KJob*)), + this, SLOT(onPreSearchSelectDone(KJob*))); + + select->start(); + + } else { + triggerSearchJob(session); + } } - } } -void AddItemTask::onPreSearchSelectDone( KJob *job ) +void AddItemTask::onPreSearchSelectDone(KJob *job) { - if ( job->error() ) { - kWarning() << job->errorString(); - cancelTask( job->errorString() ); - } else { - KIMAP::SelectJob *select = static_cast( job ); - triggerSearchJob( select->session() ); - } + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << job->errorString(); + cancelTask(job->errorString()); + } else { + KIMAP::SelectJob *select = static_cast(job); + triggerSearchJob(select->session()); + } } -void AddItemTask::triggerSearchJob( KIMAP::Session *session ) +void AddItemTask::triggerSearchJob(KIMAP::Session *session) { - KIMAP::SearchJob *search = new KIMAP::SearchJob( session ); + KIMAP::SearchJob *search = new KIMAP::SearchJob(session); - search->setUidBased( true ); - search->setSearchLogic( KIMAP::SearchJob::And ); + search->setUidBased(true); + search->setSearchLogic(KIMAP::SearchJob::And); - if ( !m_messageId.isEmpty() ) { - QByteArray header = "Message-ID "; - header+= m_messageId; + if (!m_messageId.isEmpty()) { + QByteArray header = "Message-ID "; + header += m_messageId; - search->addSearchCriteria( KIMAP::SearchJob::Header, header ); - } else { - search->addSearchCriteria( KIMAP::SearchJob::New ); + search->addSearchCriteria(KIMAP::SearchJob::Header, header); + } else { + search->addSearchCriteria(KIMAP::SearchJob::New); - UidNextAttribute *uidNext = collection().attribute(); - if ( !uidNext ) { - cancelTask( i18n( "Could not determine the UID for the newly created message on the server" ) ); - search->deleteLater(); - return; - } - KIMAP::ImapInterval interval( uidNext->uidNext() ); + UidNextAttribute *uidNext = collection().attribute(); + if (!uidNext) { + cancelTask(i18n("Could not determine the UID for the newly created message on the server")); + search->deleteLater(); + return; + } + KIMAP::ImapInterval interval(uidNext->uidNext()); - search->addSearchCriteria( KIMAP::SearchJob::Uid, interval.toImapSequence() ); - } + search->addSearchCriteria(KIMAP::SearchJob::Uid, interval.toImapSequence()); + } - connect( search, SIGNAL(result(KJob*)), - this, SLOT(onSearchDone(KJob*)) ); + connect(search, SIGNAL(result(KJob*)), + this, SLOT(onSearchDone(KJob*))); - search->start(); + search->start(); } -void AddItemTask::onSearchDone( KJob *job ) +void AddItemTask::onSearchDone(KJob *job) { - if ( job->error() ) { - kWarning() << job->errorString(); - cancelTask( job->errorString() ); - return; - } + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << job->errorString(); + cancelTask(job->errorString()); + return; + } - KIMAP::SearchJob *search = static_cast( job ); + KIMAP::SearchJob *search = static_cast(job); - qint64 uid = 0; - if ( search->results().count() == 1 ) - uid = search->results().first(); + qint64 uid = 0; + if (search->results().count() == 1) { + uid = search->results().at(0); + } - applyFoundUid( uid ); + applyFoundUid(uid); } -void AddItemTask::applyFoundUid( qint64 uid ) +void AddItemTask::applyFoundUid(qint64 uid) { - Akonadi::Item i = item(); + Akonadi::Item i = item(); - // if we didn't manage to get a valid UID from the server, use a random RID instead - // this will make ItemSync clean up the mess during the next sync (while empty RIDs are protected as not yet existing on the server) - if ( uid > 0 ) - i.setRemoteId( QString::number( uid ) ); - else - i.setRemoteId( QUuid::createUuid() ); - kDebug( 5327 ) << "Setting remote ID to " << i.remoteId() << " for item with local id " << i.id(); - - changeCommitted( i ); + // if we didn't manage to get a valid UID from the server, use a random RID instead + // this will make ItemSync clean up the mess during the next sync (while empty RIDs are protected as not yet existing on the server) + if (uid > 0) { + i.setRemoteId(QString::number(uid)); + } else { + i.setRemoteId(QUuid::createUuid().toString()); + } + qCDebug(IMAPRESOURCE_LOG) << "Setting remote ID to " << i.remoteId() << " for item with local id " << i.id(); - Akonadi::Collection c = collection(); + changeCommitted(i); - // Get the current uid next value and store it - UidNextAttribute *uidAttr = 0; - int oldNextUid = 0; - if ( c.hasAttribute( "uidnext" ) ) { - uidAttr = static_cast( c.attribute( "uidnext" ) ); - oldNextUid = uidAttr->uidNext(); - } + Akonadi::Collection c = collection(); - // If the uid we just got back is the expected next one of the box - // then update the property to the probable next uid to keep the cache in sync. - // If not something happened in our back, so we don't update and a refetch will - // happen at some point. - if ( uid==oldNextUid ) { - if ( uidAttr==0 ) { - uidAttr = new UidNextAttribute( uid+1 ); - c.addAttribute( uidAttr ); - } else { - uidAttr->setUidNext( uid+1 ); + // Get the current uid next value and store it + UidNextAttribute *uidAttr = Q_NULLPTR; + int oldNextUid = 0; + if (c.hasAttribute("uidnext")) { + uidAttr = static_cast(c.attribute("uidnext")); + oldNextUid = uidAttr->uidNext(); } - applyCollectionChanges( c ); - } -} - + // If the uid we just got back is the expected next one of the box + // then update the property to the probable next uid to keep the cache in sync. + // If not something happened in our back, so we don't update and a refetch will + // happen at some point. + if (uid == oldNextUid) { + if (uidAttr == Q_NULLPTR) { + uidAttr = new UidNextAttribute(uid + 1); + c.addAttribute(uidAttr); + } else { + uidAttr->setUidNext(uid + 1); + } + applyCollectionChanges(c); + } +} diff -Nru kdepim-runtime-4.14.6/resources/imap/additemtask.h kdepim-runtime-15.08.0/resources/imap/additemtask.h --- kdepim-runtime-4.14.6/resources/imap/additemtask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/additemtask.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,25 +26,25 @@ class AddItemTask : public ResourceTask { - Q_OBJECT + Q_OBJECT public: - explicit AddItemTask( ResourceStateInterface::Ptr resource, QObject *parent = 0 ); - virtual ~AddItemTask(); + explicit AddItemTask(ResourceStateInterface::Ptr resource, QObject *parent = Q_NULLPTR); + virtual ~AddItemTask(); -private slots: - void onAppendMessageDone( KJob *job ); - void onPreSearchSelectDone( KJob *job ); - void onSearchDone( KJob *job ); +private Q_SLOTS: + void onAppendMessageDone(KJob *job); + void onPreSearchSelectDone(KJob *job); + void onSearchDone(KJob *job); protected: - virtual void doStart( KIMAP::Session *session ); + void doStart(KIMAP::Session *session) Q_DECL_OVERRIDE; private: - void triggerSearchJob( KIMAP::Session *session ); - void applyFoundUid( qint64 uid ); + void triggerSearchJob(KIMAP::Session *session); + void applyFoundUid(qint64 uid); - QByteArray m_messageId; + QByteArray m_messageId; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/CMakeLists.txt kdepim-runtime-15.08.0/resources/imap/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/imap/autotests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,49 @@ +kde_enable_exceptions() +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) + +include(ECMMarkAsTest) + +find_package(Qt5Test CONFIG REQUIRED) + + +# if kdepimlibs was built without -DKDE4_BUILD_TESTS, kimaptest doesn't exist. +find_path(KIMAPTEST_INCLUDE_DIR NAMES KF5/kimaptest/fakeserver.h) +find_library(KIMAPTEST_LIBRARY NAMES kimaptest) + +MESSAGE( STATUS "KIMAPTEST_INCLUDE_DIR :${KIMAPTEST_INCLUDE_DIR}") +MESSAGE( STATUS "KIMAPTEST_LIBRARY :${KIMAPTEST_LIBRARY}") + +if(KIMAPTEST_INCLUDE_DIR AND KIMAPTEST_LIBRARY) + MACRO(IMAP_RESOURCE_UNIT_TESTS) + FOREACH(_testname ${ARGN}) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/..) + add_executable( ${_testname} ${_testname}.cpp dummypasswordrequester.cpp dummyresourcestate.cpp imaptestbase.cpp ) + add_test( ${_testname} ${_testname} ) + ecm_mark_as_test(imap-${_testname}) + + target_link_libraries(${_testname} + KF5::IMAP Qt5::Gui Qt5::Core ${KIMAPTEST_LIBRARY} Qt5::Test imapresource akonadi-singlefileresource) + add_definitions(-DTEST_DATA="\\"${CMAKE_CURRENT_SOURCE_DIR}\\"") + ENDFOREACH(_testname) + ENDMACRO(IMAP_RESOURCE_UNIT_TESTS) + + IMAP_RESOURCE_UNIT_TESTS( + testresourcetask + testsessionpool + + testaddcollectiontask + testadditemtask + testchangecollectiontask + testchangeitemtask + testexpungecollectiontask + testmovecollectiontask + testmoveitemstask + testremovecollectionrecursivetask + testretrievecollectionmetadatatask + testretrievecollectionstask + testretrieveitemtask + testretrieveitemstask + ) + +endif() + diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/dummypasswordrequester.cpp kdepim-runtime-15.08.0/resources/imap/autotests/dummypasswordrequester.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/dummypasswordrequester.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/dummypasswordrequester.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,83 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "dummypasswordrequester.h" + +#include + +#include + +DummyPasswordRequester::DummyPasswordRequester(QObject *parent) + : PasswordRequesterInterface(parent) +{ + for (int i = 0; i < 10; ++i) { + m_expectedCalls << StandardRequest; + m_results << PasswordRetrieved; + } +} + +QString DummyPasswordRequester::password() const +{ + return m_password; +} + +void DummyPasswordRequester::setPassword(const QString &password) +{ + m_password = password; +} + +void DummyPasswordRequester::setScenario(const QList &expectedCalls, + const QList &results) +{ + Q_ASSERT(expectedCalls.size() == results.size()); + + m_expectedCalls = expectedCalls; + m_results = results; +} + +void DummyPasswordRequester::setDelays(const QList &delays) +{ + m_delays = delays; +} + +void DummyPasswordRequester::requestPassword(RequestType request, + const QString &/*serverError*/) +{ + QVERIFY2(!m_expectedCalls.isEmpty(), QString::fromLatin1("Got unexpected call: %1").arg(request).toUtf8().constData()); + QCOMPARE((int)request, (int)m_expectedCalls.takeFirst()); + + int delay = 20; + if (!m_delays.isEmpty()) { + delay = m_delays.takeFirst(); + } + + QTimer::singleShot(delay, this, SLOT(emitResult())); +} + +void DummyPasswordRequester::emitResult() +{ + ResultType result = m_results.takeFirst(); + + if (result == PasswordRetrieved) { + Q_EMIT done(result, m_password); + } else { + Q_EMIT done(result); + } +} + diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/dummypasswordrequester.h kdepim-runtime-15.08.0/resources/imap/autotests/dummypasswordrequester.h --- kdepim-runtime-4.14.6/resources/imap/autotests/dummypasswordrequester.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/dummypasswordrequester.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,53 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef DUMMYPASSWORDREQUESTER_H +#define DUMMYPASSWORDREQUESTER_H + +#include "passwordrequesterinterface.h" + +class DummyPasswordRequester : public PasswordRequesterInterface +{ + Q_OBJECT +public: + DummyPasswordRequester(QObject *parent = Q_NULLPTR); + + QString password() const; + void setPassword(const QString &password); + + void setScenario(const QList &expectedCalls, + const QList &results); + void setDelays(const QList &delays); + +public: + virtual void requestPassword(RequestType request = StandardRequest, + const QString &serverError = QString()); + +private Q_SLOTS: + void emitResult(); + +private: + QString m_password; + QList m_expectedCalls; + QList m_results; + QList m_delays; +}; + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/dummyresourcestate.cpp kdepim-runtime-15.08.0/resources/imap/autotests/dummyresourcestate.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/dummyresourcestate.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/dummyresourcestate.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,434 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Ottens + + 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 "dummyresourcestate.h" +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QVector) +Q_DECLARE_METATYPE(QString); +Q_DECLARE_METATYPE(TagListAndMembers); + +DummyResourceState::DummyResourceState() + : m_automaticExpunge(true), m_subscriptionEnabled(true), + m_disconnectedMode(true), m_intervalCheckTime(-1) +{ + qRegisterMetaType >(); + qRegisterMetaType >(); + qRegisterMetaType(); +} + +DummyResourceState::~DummyResourceState() +{ + +} + +void DummyResourceState::setUserName(const QString &name) +{ + m_userName = name; +} + +QString DummyResourceState::userName() const +{ + return m_userName; +} + +void DummyResourceState::setResourceName(const QString &name) +{ + m_resourceName = name; +} + +QString DummyResourceState::resourceName() const +{ + return m_resourceName; +} + +void DummyResourceState::setResourceIdentifier(const QString &identifier) +{ + m_resourceIdentifier = identifier; +} + +QString DummyResourceState::resourceIdentifier() const +{ + return m_resourceIdentifier; +} + +void DummyResourceState::setServerCapabilities(const QStringList &capabilities) +{ + m_capabilities = capabilities; +} + +QStringList DummyResourceState::serverCapabilities() const +{ + return m_capabilities; +} + +void DummyResourceState::setServerNamespaces(const QList &namespaces) +{ + m_namespaces = namespaces; +} + +QList DummyResourceState::serverNamespaces() const +{ + return m_namespaces; +} + +QList DummyResourceState::personalNamespaces() const +{ + return QList(); +} + +QList DummyResourceState::userNamespaces() const +{ + return QList(); +} + +QList DummyResourceState::sharedNamespaces() const +{ + return QList(); +} + +void DummyResourceState::setAutomaticExpungeEnagled(bool enabled) +{ + m_automaticExpunge = enabled; +} + +bool DummyResourceState::isAutomaticExpungeEnabled() const +{ + return m_automaticExpunge; +} + +void DummyResourceState::setSubscriptionEnabled(bool enabled) +{ + m_subscriptionEnabled = enabled; +} + +bool DummyResourceState::isSubscriptionEnabled() const +{ + return m_subscriptionEnabled; +} + +void DummyResourceState::setDisconnectedModeEnabled(bool enabled) +{ + m_disconnectedMode = enabled; +} + +bool DummyResourceState::isDisconnectedModeEnabled() const +{ + return m_disconnectedMode; +} + +void DummyResourceState::setIntervalCheckTime(int interval) +{ + m_intervalCheckTime = interval; +} + +int DummyResourceState::intervalCheckTime() const +{ + return m_intervalCheckTime; +} + +void DummyResourceState::setCollection(const Akonadi::Collection &collection) +{ + m_collection = collection; +} + +Akonadi::Collection DummyResourceState::collection() const +{ + return m_collection; +} + +void DummyResourceState::setItem(const Akonadi::Item &item) +{ + m_items.clear(); + m_items << item; +} + +Akonadi::Item DummyResourceState::item() const +{ + return m_items.first(); +} + +Akonadi::Item::List DummyResourceState::items() const +{ + return m_items; +} + +void DummyResourceState::setParentCollection(const Akonadi::Collection &collection) +{ + m_parentCollection = collection; +} + +Akonadi::Collection DummyResourceState::parentCollection() const +{ + return m_parentCollection; +} + +void DummyResourceState::setSourceCollection(const Akonadi::Collection &collection) +{ + m_sourceCollection = collection; +} + +Akonadi::Collection DummyResourceState::sourceCollection() const +{ + return m_sourceCollection; +} + +void DummyResourceState::setTargetCollection(const Akonadi::Collection &collection) +{ + m_targetCollection = collection; +} + +Akonadi::Collection DummyResourceState::targetCollection() const +{ + return m_targetCollection; +} + +void DummyResourceState::setParts(const QSet &parts) +{ + m_parts = parts; +} + +QSet DummyResourceState::parts() const +{ + return m_parts; +} + +void DummyResourceState::setTag(const Akonadi::Tag &tag) +{ + m_tag = tag; +} + +Akonadi::Tag DummyResourceState::tag() const +{ + return m_tag; +} + +void DummyResourceState::setAddedTags(const QSet &addedTags) +{ + m_addedTags = addedTags; +} + +QSet DummyResourceState::addedTags() const +{ + return m_addedTags; +} + +void DummyResourceState::setRemovedTags(const QSet &removedTags) +{ + m_removedTags = removedTags; +} + +QSet DummyResourceState::removedTags() const +{ + return m_removedTags; +} + +Akonadi::Relation::List DummyResourceState::addedRelations() const +{ + return Akonadi::Relation::List(); +} + +Akonadi::Relation::List DummyResourceState::removedRelations() const +{ + return Akonadi::Relation::List(); +} + +QString DummyResourceState::rootRemoteId() const +{ + return QStringLiteral("root-id"); +} + +void DummyResourceState::setIdleCollection(const Akonadi::Collection &collection) +{ + recordCall("setIdleCollection", QVariant::fromValue(collection)); +} + +void DummyResourceState::applyCollectionChanges(const Akonadi::Collection &collection) +{ + recordCall("applyCollectionChanges", QVariant::fromValue(collection)); +} + +void DummyResourceState::collectionAttributesRetrieved(const Akonadi::Collection &collection) +{ + recordCall("collectionAttributesRetrieved", QVariant::fromValue(collection)); +} + +void DummyResourceState::itemRetrieved(const Akonadi::Item &item) +{ + recordCall("itemRetrieved", QVariant::fromValue(item)); +} + +void DummyResourceState::itemsRetrieved(const Akonadi::Item::List &items) +{ + recordCall("itemsRetrieved", QVariant::fromValue(items)); +} + +void DummyResourceState::itemsRetrievedIncremental(const Akonadi::Item::List &changed, const Akonadi::Item::List &removed) +{ + Q_UNUSED(removed) + + recordCall("itemsRetrievedIncremental", QVariant::fromValue(changed)); +} + +void DummyResourceState::itemsRetrievalDone() +{ + recordCall("itemsRetrievalDone"); +} + +void DummyResourceState::setTotalItems(int) +{ + +} + +QSet< QByteArray > DummyResourceState::addedFlags() const +{ + return QSet(); +} + +QSet< QByteArray > DummyResourceState::removedFlags() const +{ + return QSet(); +} + +void DummyResourceState::itemChangeCommitted(const Akonadi::Item &item) +{ + recordCall("itemChangeCommitted", QVariant::fromValue(item)); +} + +void DummyResourceState::itemsChangesCommitted(const Akonadi::Item::List &items) +{ + recordCall("itemsChangesCommitted", QVariant::fromValue(items)); +} + +void DummyResourceState::collectionsRetrieved(const Akonadi::Collection::List &collections) +{ + recordCall("collectionsRetrieved", QVariant::fromValue(collections)); +} + +void DummyResourceState::collectionChangeCommitted(const Akonadi::Collection &collection) +{ + recordCall("collectionChangeCommitted", QVariant::fromValue(collection)); +} + +void DummyResourceState::tagsRetrieved(const Akonadi::Tag::List &tags, const QHash &items) +{ + recordCall("tagsRetrieved", QVariant::fromValue(qMakePair(tags, items))); +} + +void DummyResourceState::relationsRetrieved(const Akonadi::Relation::List &relations) +{ + recordCall("relationsRetrieved", QVariant::fromValue(relations)); +} + +void DummyResourceState::tagChangeCommitted(const Akonadi::Tag &tag) +{ + recordCall("tagChangeCommitted", QVariant::fromValue(tag)); +} + +void DummyResourceState::changeProcessed() +{ + recordCall("changeProcessed"); +} + +void DummyResourceState::searchFinished(const QVector &result, bool isRid) +{ + recordCall("searchFinished", QVariant::fromValue(result)); +} + +void DummyResourceState::cancelTask(const QString &errorString) +{ + recordCall("cancelTask", QVariant::fromValue(errorString)); +} + +void DummyResourceState::deferTask() +{ + recordCall("deferTask"); +} + +void DummyResourceState::restartItemRetrieval(Akonadi::Entity::Id col) +{ + recordCall("restartItemRetrieval", QVariant::fromValue(col)); +} + +void DummyResourceState::taskDone() +{ + recordCall("taskDone"); +} + +void DummyResourceState::emitError(const QString &message) +{ + recordCall("emitError", QVariant::fromValue(message)); +} + +void DummyResourceState::emitWarning(const QString &message) +{ + recordCall("emitWarning", QVariant::fromValue(message)); +} + +void DummyResourceState::emitPercent(int percent) +{ + // FIXME: Many tests need to be updated for this to be uncommented out. + // recordCall( "emitPercent", QVariant::fromValue(percent) ); +} + +void DummyResourceState::synchronizeCollectionTree() +{ + recordCall("synchronizeCollectionTree"); +} + +void DummyResourceState::scheduleConnectionAttempt() +{ + recordCall("scheduleConnectionAttempt"); +} + +void DummyResourceState::showInformationDialog(const QString &message, const QString &, const QString &) +{ + recordCall("showInformationDialog", QVariant::fromValue(message)); +} + +QList< QPair > DummyResourceState::calls() const +{ + return m_calls; +} + +QChar DummyResourceState::separatorCharacter() const +{ + return m_separator; +} + +void DummyResourceState::setSeparatorCharacter(const QChar &separator) +{ + m_separator = separator; +} + +void DummyResourceState::recordCall(const QByteArray callName, const QVariant ¶meter) +{ + m_calls << QPair(callName, parameter); +} + +int DummyResourceState::batchSize() const +{ + return 10; +} + +MessageHelper::Ptr DummyResourceState::messageHelper() const +{ + return MessageHelper::Ptr(new MessageHelper()); +} diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/dummyresourcestate.h kdepim-runtime-15.08.0/resources/imap/autotests/dummyresourcestate.h --- kdepim-runtime-4.14.6/resources/imap/autotests/dummyresourcestate.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/dummyresourcestate.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,183 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Ottens + + 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 DUMMYRESOURCESTATE_H +#define DUMMYRESOURCESTATE_H + +#include +#include + +#include "resourcestateinterface.h" + +typedef QPair > TagListAndMembers; + +class DummyResourceState : public ResourceStateInterface +{ +public: + typedef boost::shared_ptr Ptr; + + explicit DummyResourceState(); + ~DummyResourceState(); + + void setUserName(const QString &name); + virtual QString userName() const; + + void setResourceName(const QString &name); + virtual QString resourceName() const; + + void setResourceIdentifier(const QString &identifier); + virtual QString resourceIdentifier() const; + + void setServerCapabilities(const QStringList &capabilities); + virtual QStringList serverCapabilities() const; + + void setServerNamespaces(const QList &namespaces); + virtual QList serverNamespaces() const; + virtual QList personalNamespaces() const; + virtual QList userNamespaces() const; + virtual QList sharedNamespaces() const; + + void setAutomaticExpungeEnagled(bool enabled); + virtual bool isAutomaticExpungeEnabled() const; + + void setSubscriptionEnabled(bool enabled); + virtual bool isSubscriptionEnabled() const; + void setDisconnectedModeEnabled(bool enabled); + virtual bool isDisconnectedModeEnabled() const; + void setIntervalCheckTime(int interval); + virtual int intervalCheckTime() const; + + void setCollection(const Akonadi::Collection &collection); + virtual Akonadi::Collection collection() const; + void setItem(const Akonadi::Item &item); + virtual Akonadi::Item item() const; + virtual Akonadi::Item::List items() const; + + void setParentCollection(const Akonadi::Collection &collection); + virtual Akonadi::Collection parentCollection() const; + + void setSourceCollection(const Akonadi::Collection &collection); + virtual Akonadi::Collection sourceCollection() const; + void setTargetCollection(const Akonadi::Collection &collection); + virtual Akonadi::Collection targetCollection() const; + + void setParts(const QSet &parts); + virtual QSet parts() const; + + void setTag(const Akonadi::Tag &tag); + virtual Akonadi::Tag tag() const; + void setAddedTags(const QSet &addedTags); + virtual QSet addedTags() const; + void setRemovedTags(const QSet &removedTags); + virtual QSet removedTags() const; + + virtual Akonadi::Relation::List addedRelations() const; + virtual Akonadi::Relation::List removedRelations() const; + + virtual QString rootRemoteId() const; + + virtual void setIdleCollection(const Akonadi::Collection &collection); + virtual void applyCollectionChanges(const Akonadi::Collection &collection); + + virtual void collectionAttributesRetrieved(const Akonadi::Collection &collection); + + virtual void itemRetrieved(const Akonadi::Item &item); + + virtual void itemsRetrieved(const Akonadi::Item::List &items); + virtual void itemsRetrievedIncremental(const Akonadi::Item::List &changed, const Akonadi::Item::List &removed); + virtual void itemsRetrievalDone(); + + virtual void setTotalItems(int); + + virtual QSet< QByteArray > addedFlags() const; + virtual QSet< QByteArray > removedFlags() const; + + virtual void itemChangeCommitted(const Akonadi::Item &item); + virtual void itemsChangesCommitted(const Akonadi::Item::List &items); + + virtual void collectionsRetrieved(const Akonadi::Collection::List &collections); + + virtual void collectionChangeCommitted(const Akonadi::Collection &collection); + + virtual void tagsRetrieved(const Akonadi::Tag::List &tags, const QHash &); + virtual void relationsRetrieved(const Akonadi::Relation::List &tags); + virtual void tagChangeCommitted(const Akonadi::Tag &tag); + + virtual void searchFinished(const QVector &result, bool isRid = true); + + virtual void changeProcessed(); + + virtual void cancelTask(const QString &errorString); + virtual void deferTask(); + virtual void restartItemRetrieval(Akonadi::Collection::Id col); + virtual void taskDone(); + + virtual void emitError(const QString &message); + virtual void emitWarning(const QString &message); + virtual void emitPercent(int percent); + + virtual void synchronizeCollectionTree(); + virtual void scheduleConnectionAttempt(); + + virtual QChar separatorCharacter() const; + virtual void setSeparatorCharacter(const QChar &separator); + + virtual void showInformationDialog(const QString &message, const QString &title, const QString &dontShowAgainName); + + virtual int batchSize() const; + + virtual MessageHelper::Ptr messageHelper() const; + + QList< QPair > calls() const; + +private: + void recordCall(const QByteArray callName, const QVariant ¶meter = QVariant()); + + QString m_userName; + QString m_resourceName; + QString m_resourceIdentifier; + QStringList m_capabilities; + QList m_namespaces; + + bool m_automaticExpunge; + bool m_subscriptionEnabled; + bool m_disconnectedMode; + int m_intervalCheckTime; + QChar m_separator; + + Akonadi::Collection m_collection; + Akonadi::Item::List m_items; + + Akonadi::Collection m_parentCollection; + + Akonadi::Collection m_sourceCollection; + Akonadi::Collection m_targetCollection; + + QSet m_parts; + + Akonadi::Tag m_tag; + QSet m_addedTags; + QSet m_removedTags; + + QList< QPair > m_calls; +}; + +#endif diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/imaptestbase.cpp kdepim-runtime-15.08.0/resources/imap/autotests/imaptestbase.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/imaptestbase.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/imaptestbase.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,138 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" +#include +#include + +ImapTestBase::ImapTestBase(QObject *parent) + : QObject(parent) +{ + +} + +QString ImapTestBase::defaultUserName() const +{ + return QStringLiteral("test@kdab.com"); +} + +QString ImapTestBase::defaultPassword() const +{ + return QStringLiteral("foobar"); +} + +ImapAccount *ImapTestBase::createDefaultAccount() const +{ + ImapAccount *account = new ImapAccount; + + account->setServer(QLatin1String("127.0.0.1")); + account->setPort(5989); + account->setUserName(defaultUserName()); + account->setSubscriptionEnabled(true); + account->setEncryptionMode(KIMAP::LoginJob::Unencrypted); + account->setAuthenticationMode(KIMAP::LoginJob::ClearText); + + return account; +} + +DummyPasswordRequester *ImapTestBase::createDefaultRequester() +{ + DummyPasswordRequester *requester = new DummyPasswordRequester(this); + requester->setPassword(defaultPassword()); + return requester; +} + +void ImapTestBase::setupTestCase() +{ + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); +} + +QList ImapTestBase::defaultAuthScenario() const +{ + QList scenario; + + scenario << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in"; + + return scenario; +} + +QList ImapTestBase::defaultPoolConnectionScenario(const QList &customCapabilities) const +{ + QList scenario; + + QByteArray caps = "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE"; + Q_FOREACH (const QByteArray &cap, customCapabilities) { + caps += " " + cap; + } + + scenario << defaultAuthScenario() + << "C: A000002 CAPABILITY" + << caps + << "S: A000002 OK Completed"; + + return scenario; +} + +bool ImapTestBase::waitForSignal(QObject *obj, const char *member, int timeout) const +{ + QEventLoop loop; + QTimer timer; + + connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); + + QSignalSpy spy(obj, member); + connect(obj, member, &loop, SLOT(quit())); + + timer.setSingleShot(true); + timer.start(timeout); + loop.exec(); + timer.stop(); + + return spy.count() == 1; +} + +Akonadi::Collection ImapTestBase::createCollectionChain(const QString &remoteId) const +{ + QChar separator = remoteId.length() > 0 ? remoteId.at(0) : QLatin1Char('/'); + + Akonadi::Collection parent(1); + parent.setRemoteId(QLatin1String("root-id")); + parent.setParentCollection(Akonadi::Collection::root()); + Akonadi::Entity::Id id = 2; + + Akonadi::Collection collection = parent; + + const QStringList collections = remoteId.split(separator, QString::SkipEmptyParts); + Q_FOREACH (const QString &colId, collections) { + collection = Akonadi::Collection(id); + collection.setRemoteId(separator + colId); + collection.setParentCollection(parent); + + parent = collection; + id++; + } + + return collection; +} + diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/imaptestbase.h kdepim-runtime-15.08.0/resources/imap/autotests/imaptestbase.h --- kdepim-runtime-4.14.6/resources/imap/autotests/imaptestbase.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/imaptestbase.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,62 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef IMAPTESTBASE_H +#define IMAPTESTBASE_H + +#include + +#include + +#include "dummypasswordrequester.h" +#include "dummyresourcestate.h" +#include "imapaccount.h" +#include "resourcetask.h" +#include "sessionpool.h" + +Q_DECLARE_METATYPE(ImapAccount *) +Q_DECLARE_METATYPE(DummyPasswordRequester *) +Q_DECLARE_METATYPE(DummyResourceState::Ptr) +Q_DECLARE_METATYPE(KIMAP::Session *) +Q_DECLARE_METATYPE(QVariant) + +class ImapTestBase : public QObject +{ + Q_OBJECT + +public: + ImapTestBase(QObject *parent = Q_NULLPTR); + +protected: + QString defaultUserName() const; + QString defaultPassword() const; + ImapAccount *createDefaultAccount() const; + DummyPasswordRequester *createDefaultRequester(); + QList defaultAuthScenario() const; + QList defaultPoolConnectionScenario(const QList &customCapabilities = QList()) const; + + bool waitForSignal(QObject *obj, const char *member, int timeout = 500) const; + + Akonadi::Collection createCollectionChain(const QString &remoteId) const; + +private Q_SLOTS: + void setupTestCase(); +}; + +#endif diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/testaddcollectiontask.cpp kdepim-runtime-15.08.0/resources/imap/autotests/testaddcollectiontask.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/testaddcollectiontask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/testaddcollectiontask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,182 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" + +#include "addcollectiontask.h" +#include +#include + +class TestAddCollectionTask : public ImapTestBase +{ + Q_OBJECT + +private Q_SLOTS: + void shouldCreateAndSubscribe_data() + { + QTest::addColumn("parentCollection"); + QTest::addColumn("collection"); + QTest::addColumn< QList >("scenario"); + QTest::addColumn("callNames"); + QTest::addColumn("collectionName"); + QTest::addColumn("remoteId"); + + Akonadi::Collection parentCollection; + Akonadi::Collection collection; + QList scenario; + QStringList callNames; + + parentCollection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection = Akonadi::Collection(4); + collection.setName(QLatin1String("Bar")); + collection.setParentCollection(parentCollection); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 CREATE \"INBOX/Foo/Bar\"" + << "S: A000003 OK create done" + << "C: A000004 SUBSCRIBE \"INBOX/Foo/Bar\"" + << "S: A000004 OK subscribe done"; + + callNames.clear(); + callNames << QStringLiteral("collectionChangeCommitted") << QStringLiteral("synchronizeCollectionTree"); + + QTest::newRow("trivial case") << parentCollection << collection << scenario << callNames + << collection.name() << "/Bar"; + + parentCollection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection = Akonadi::Collection(4); + collection.setName(QLatin1String("Bar/Baz")); + collection.setParentCollection(parentCollection); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 CREATE \"INBOX/Foo/BarBaz\"" + << "S: A000003 OK create done" + << "C: A000004 SUBSCRIBE \"INBOX/Foo/BarBaz\"" + << "S: A000004 OK subscribe done"; + + callNames.clear(); + callNames << QStringLiteral("collectionChangeCommitted") << QStringLiteral("synchronizeCollectionTree"); + + QTest::newRow("folder with invalid separator") << parentCollection << collection << scenario + << callNames << "BarBaz" << "/BarBaz"; + + parentCollection = createCollectionChain(QLatin1String(".INBOX")); + collection = Akonadi::Collection(3); + collection.setName(QLatin1String("Foo")); + collection.setParentCollection(parentCollection); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 CREATE \"INBOX.Foo\"" + << "S: A000003 OK create done" + << "C: A000004 SUBSCRIBE \"INBOX.Foo\"" + << "S: A000004 OK subscribe done"; + callNames.clear(); + callNames << QStringLiteral("collectionChangeCommitted") << QStringLiteral("synchronizeCollectionTree"); + + QTest::newRow("folder with non-standard separator") << parentCollection << collection << scenario + << callNames << "Foo" << ".Foo"; + + parentCollection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection = Akonadi::Collection(4); + collection.setName(QLatin1String("Bar")); + collection.setParentCollection(parentCollection); + Akonadi::CollectionAnnotationsAttribute *attr = collection.attribute(Akonadi::Collection::AddIfMissing); + QMap annotations; + annotations.insert("/shared/vendor/foobar/foo", "value"); + attr->setAnnotations(annotations); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 CREATE \"INBOX/Foo/Bar\"" + << "S: A000003 OK create done" + << "C: A000004 SUBSCRIBE \"INBOX/Foo/Bar\"" + << "S: A000004 OK subscribe done" + << "C: A000005 SETMETADATA \"INBOX/Foo/Bar\" (\"/shared/vendor/foobar/foo\" \"value\")" + << "S: A000005 OK SETMETADATA complete"; + + callNames.clear(); + callNames << QStringLiteral("collectionChangeCommitted"); + + QTest::newRow("folder with annotations") << parentCollection << collection << scenario << callNames + << collection.name() << "/Bar"; + } + + void shouldCreateAndSubscribe() + { + QFETCH(Akonadi::Collection, parentCollection); + QFETCH(Akonadi::Collection, collection); + QFETCH(QList, scenario); + QFETCH(QStringList, callNames); + QFETCH(QString, collectionName); + QFETCH(QString, remoteId); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(1); + + pool.setPasswordRequester(createDefaultRequester()); + QVERIFY(pool.connect(createDefaultAccount())); + QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int,QString)))); + + DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); + state->setParentCollection(parentCollection); + state->setCollection(collection); + if (collection.hasAttribute()) { + state->setServerCapabilities(QStringList() << "METADATA"); + } + AddCollectionTask *task = new AddCollectionTask(state); + task->start(&pool); + + QTRY_COMPARE(state->calls().count(), callNames.size()); + for (int i = 0; i < callNames.size(); i++) { + QString command = QString::fromUtf8(state->calls().at(i).first); + QVariant parameter = state->calls().at(i).second; + + if (command == QLatin1String("cancelTask") && callNames[i] != QLatin1String("cancelTask")) { + qDebug() << "Got a cancel:" << parameter.toString(); + } + + if (command == QLatin1String("collectionChangeCommitted")) { + QCOMPARE(parameter.value().name(), collectionName); + QCOMPARE(parameter.value().remoteId().right(collectionName.length()), + collectionName); + QCOMPARE(parameter.value().remoteId(), remoteId); + } + + QCOMPARE(command, callNames[i]); + + if (command == QLatin1String("cancelTask")) { + QVERIFY(!parameter.toString().isEmpty()); + } + } + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } +}; + +QTEST_GUILESS_MAIN(TestAddCollectionTask) + +#include "testaddcollectiontask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/testadditemtask.cpp kdepim-runtime-15.08.0/resources/imap/autotests/testadditemtask.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/testadditemtask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/testadditemtask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,179 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" + +#include "additemtask.h" + +#include "uidnextattribute.h" + +#include + +class TestAddItemTask : public ImapTestBase +{ + Q_OBJECT + +private Q_SLOTS: + void shouldAppendMessage_data() + { + QTest::addColumn("item"); + QTest::addColumn("collection"); + QTest::addColumn< QList >("scenario"); + QTest::addColumn("callNames"); + + Akonadi::Collection collection; + Akonadi::Item item; + QString messageContent; + QList scenario; + QStringList callNames; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + UidNextAttribute *uidNext = new UidNextAttribute; + uidNext->setUidNext(63); + collection.addAttribute(uidNext); + + item = Akonadi::Item(2); + item.setParentCollection(collection); + + KMime::Message::Ptr message(new KMime::Message); + + messageContent = QLatin1String("From: ervin\nTo: someone\nSubject: foo\n\nSpeechless..."); + + message->setContent(messageContent.toUtf8()); + message->parse(); + item.setPayload(message); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 APPEND \"INBOX/Foo\" {55}\r\n" + message->encodedContent(true) + << "S: A000003 OK append done [ APPENDUID 1239890035 66 ]"; + + callNames.clear(); + callNames << QStringLiteral("itemChangeCommitted"); + + QTest::newRow("trivial case") << item << collection << scenario << callNames; + + message = KMime::Message::Ptr(new KMime::Message); + + messageContent = QLatin1String("From: ervin\nTo: someone\nSubject: foo\nMessage-ID: <42.4242.foo@bar.org>\n\nSpeechless..."); + + message->setContent(messageContent.toUtf8()); + message->parse(); + item.setPayload(message); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 APPEND \"INBOX/Foo\" {90}\r\n" + message->encodedContent(true) + << "S: A000003 OK append done" + << "C: A000004 SELECT \"INBOX/Foo\"" + << "S: A000004 OK select done" + << "C: A000005 UID SEARCH HEADER Message-ID <42.4242.foo@bar.org>" + << "S: * SEARCH 66" + << "S: A000005 OK search done"; + + callNames.clear(); + callNames << QStringLiteral("itemChangeCommitted"); + + QTest::newRow("no APPENDUID, message contained Message-ID") << item << collection << scenario << callNames; + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 APPEND \"INBOX/Foo\" {90}\r\n" + message->encodedContent(true) + << "S: A000003 OK append done" + << "C: A000004 SELECT \"INBOX/Foo\"" + << "S: A000004 OK select done" + << "C: A000005 UID SEARCH HEADER Message-ID <42.4242.foo@bar.org>" + << "S: * SEARCH 65 66" + << "S: A000005 OK search done"; + callNames.clear(); + callNames << QStringLiteral("itemChangeCommitted"); + QTest::newRow("no APPENDUID, message contained non-unique Message-ID") << item << collection << scenario << callNames; + + message = KMime::Message::Ptr(new KMime::Message); + + messageContent = QLatin1String("From: ervin\nTo: someone\nSubject: foo\n\nSpeechless..."); + + message->setContent(messageContent.toUtf8()); + message->parse(); + item.setPayload(message); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 APPEND \"INBOX/Foo\" {55}\r\n" + message->encodedContent(true) + << "S: A000003 OK append done" + << "C: A000004 SELECT \"INBOX/Foo\"" + << "S: A000004 OK select done" + << "C: A000005 UID SEARCH NEW UID 63:*" + << "S: * SEARCH 66" + << "S: A000005 OK search done"; + + callNames.clear(); + callNames << QStringLiteral("itemChangeCommitted"); + + QTest::newRow("no APPENDUID, message didn't contain Message-ID") << item << collection << scenario << callNames; + } + + void shouldAppendMessage() + { + QFETCH(Akonadi::Item, item); + QFETCH(Akonadi::Collection, collection); + QFETCH(QList, scenario); + QFETCH(QStringList, callNames); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(1); + + pool.setPasswordRequester(createDefaultRequester()); + QVERIFY(pool.connect(createDefaultAccount())); + QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int,QString)))); + + DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); + state->setCollection(collection); + state->setItem(item); + AddItemTask *task = new AddItemTask(state); + task->start(&pool); + + QTRY_COMPARE(state->calls().count(), callNames.size()); + for (int i = 0; i < callNames.size(); i++) { + QString command = QString::fromUtf8(state->calls().at(i).first); + QVariant parameter = state->calls().at(i).second; + + if (command == QLatin1String("cancelTask") && callNames[i] != QLatin1String("cancelTask")) { + qDebug() << "Got a cancel:" << parameter.toString(); + } + + QCOMPARE(command, callNames[i]); + + if (command == QLatin1String("cancelTask")) { + QVERIFY(!parameter.toString().isEmpty()); + } + } + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } +}; + +QTEST_GUILESS_MAIN(TestAddItemTask) + +#include "testadditemtask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/testchangecollectiontask.cpp kdepim-runtime-15.08.0/resources/imap/autotests/testchangecollectiontask.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/testchangecollectiontask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/testchangecollectiontask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,244 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" + +#include "changecollectiontask.h" + +#include "collectionannotationsattribute.h" +#include "imapaclattribute.h" + +Q_DECLARE_METATYPE(QSet) + +class TestChangeCollectionTask : public ImapTestBase +{ + Q_OBJECT + +private Q_SLOTS: + void shouldUpdateMetadataAclAndName_data() + { + QTest::addColumn("collection"); + QTest::addColumn< QSet >("parts"); + QTest::addColumn< QList >("scenario"); + QTest::addColumn("callNames"); + QTest::addColumn("collectionName"); + QTest::addColumn("caps"); + + Akonadi::Collection collection; + QSet parts; + QList scenario; + QStringList callNames; + QStringList caps; + + collection = createCollectionChain(QLatin1String("/Foo")); + collection.setName(QLatin1String("Bar")); + collection.setRights(Akonadi::Collection::AllRights); + + Akonadi::ImapAclAttribute *acls = new Akonadi::ImapAclAttribute; + QMap rights; + // Old rights + rights["test@kdab.com"] = KIMAP::Acl::rightsFromString("lrswipckxtda"); + rights["foo@kde.org"] = KIMAP::Acl::rightsFromString("lrswipcda"); + acls->setRights(rights); + + // New rights + rights["test@kdab.com"] = KIMAP::Acl::rightsFromString("lrswipckxtda"); + rights["foo@kde.org"] = KIMAP::Acl::rightsFromString("lrswipcda"); + acls->setRights(rights); + collection.addAttribute(acls); + + Akonadi::CollectionAnnotationsAttribute *annotationsAttr = new Akonadi::CollectionAnnotationsAttribute; + QMap annotations; + annotations["/vendor/kolab/folder-test"] = "false"; + annotations["/vendor/kolab/folder-test2"] = "true"; + annotationsAttr->setAnnotations(annotations); + collection.addAttribute(annotationsAttr); + + parts << "NAME" << "AccessRights" << "imapacl" << "collectionannotations"; + + caps << "ACL" << "ANNOTATEMORE"; + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SETACL \"Foo\" \"test@kdab.com\" \"lrswipckxtda\"" + << "S: A000003 OK acl changed" + << "C: A000004 SETANNOTATION \"Foo\" \"/vendor/kolab/folder-test\" (\"value.shared\" \"false\")" + << "S: A000004 OK annotations changed" + << "C: A000005 SETANNOTATION \"Foo\" \"/vendor/kolab/folder-test2\" (\"value.shared\" \"true\")" + << "S: A000005 OK annotations changed" + << "C: A000006 SETACL \"Foo\" \"foo@kde.org\" \"lrswipcda\"" + << "S: A000006 OK acl changed" + << "C: A000007 SETACL \"Foo\" \"test@kdab.com\" \"lrswipckxtda\"" + << "S: A000007 OK acl changed" + << "C: A000008 RENAME \"Foo\" \"Bar\"" + << "S: A000008 OK rename done" + << "C: A000009 SUBSCRIBE \"Bar\"" + << "S: A000009 OK mailbox subscribed"; + + callNames.clear(); + callNames << QStringLiteral("collectionChangeCommitted"); + + QTest::newRow("complete case") << collection << parts << scenario << callNames << collection.name() << caps; + + caps.clear(); + caps << "ACL"; + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SETACL \"Foo\" \"test@kdab.com\" \"lrswipckxtda\"" + << "S: A000003 OK acl changed" + << "C: A000004 SETACL \"Foo\" \"foo@kde.org\" \"lrswipcda\"" + << "S: A000004 OK acl changed" + << "C: A000005 SETACL \"Foo\" \"test@kdab.com\" \"lrswipckxtda\"" + << "S: A000005 OK acl changed" + << "C: A000006 RENAME \"Foo\" \"Bar\"" + << "S: A000006 OK rename done" + << "C: A000007 SUBSCRIBE \"Bar\"" + << "S: A000007 OK mailbox subscribed"; + QTest::newRow("no ANNOTATEMORE support") << collection << parts << scenario << callNames << collection.name() << caps; + + collection = createCollectionChain(QLatin1String("/Foo")); + collection.setName(QLatin1String("Bar/Baz")); + caps.clear(); + caps << "ACL" << "ANNOTATEMORE"; + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 RENAME \"Foo\" \"BarBaz\"" + << "S: A000003 OK rename done" + << "C: A000004 SUBSCRIBE \"BarBaz\"" + << "S: A000004 OK mailbox subscribed"; + parts.clear(); + parts << "NAME"; + callNames.clear(); + callNames << QStringLiteral("collectionChangeCommitted"); + QTest::newRow("rename with invalid separator") << collection << parts << scenario << callNames + << "BarBaz" << caps; + + collection = createCollectionChain(QLatin1String(".INBOX.Foo")); + collection.setName(QLatin1String("Bar")); + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 RENAME \"INBOX.Foo\" \"INBOX.Bar\"" + << "S: A000003 OK rename done" + << "C: A000004 SUBSCRIBE \"INBOX.Bar\"" + << "S: A000004 OK mailbox subscribed"; + QTest::newRow("rename with non-standard separator") << collection << parts << scenario << callNames + << "Bar" << caps; + + collection = createCollectionChain(QLatin1String("/Foo")); + collection.setName(QLatin1String("Bar")); + collection.setRights(Akonadi::Collection::AllRights); + + acls = new Akonadi::ImapAclAttribute; + // Old rights + rights["test@kdab.com"] = KIMAP::Acl::rightsFromString("lrswipckxtda"); + rights["foo@kde.org"] = KIMAP::Acl::rightsFromString("lrswipcda"); + acls->setRights(rights); + + // New rights + rights["test@kdab.com"] = KIMAP::Acl::rightsFromString("lrswipckxtda"); + rights["foo@kde.org"] = KIMAP::Acl::rightsFromString("lrswipcda"); + acls->setRights(rights); + collection.addAttribute(acls); + + annotationsAttr = new Akonadi::CollectionAnnotationsAttribute; + annotations["/vendor/kolab/folder-test"] = "false"; + annotations["/vendor/kolab/folder-test2"] = "true"; + annotationsAttr->setAnnotations(annotations); + collection.addAttribute(annotationsAttr); + + parts << "NAME" << "AccessRights" << "imapacl" << "collectionannotations"; + + caps << "ACL" << "METADATA"; + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SETACL \"Foo\" \"test@kdab.com\" \"lrswipckxtda\"" + << "S: A000003 OK acl changed" + << "C: A000004 SETMETADATA \"Foo\" (\"/shared/vendor/kolab/folder-test\" \"false\")" + << "S: A000004 OK SETMETADATA complete" + << "C: A000005 SETMETADATA \"Foo\" (\"/shared/vendor/kolab/folder-test2\" \"true\")" + << "S: A000005 OK SETMETADATA complete" + << "C: A000006 SETACL \"Foo\" \"foo@kde.org\" \"lrswipcda\"" + << "S: A000006 OK acl changed" + << "C: A000007 SETACL \"Foo\" \"test@kdab.com\" \"lrswipckxtda\"" + << "S: A000007 OK acl changed" + << "C: A000008 RENAME \"Foo\" \"Bar\"" + << "S: A000008 OK rename done" + << "C: A000009 SUBSCRIBE \"Bar\"" + << "S: A000009 OK mailbox subscribed"; + QTest::newRow("complete case METADATA") << collection << parts << scenario << callNames << collection.name() << caps; + } + + void shouldUpdateMetadataAclAndName() + { + QFETCH(Akonadi::Collection, collection); + QFETCH(QSet, parts); + QFETCH(QList, scenario); + QFETCH(QStringList, callNames); + QFETCH(QString, collectionName); + QFETCH(QStringList, caps); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(1); + + pool.setPasswordRequester(createDefaultRequester()); + QVERIFY(pool.connect(createDefaultAccount())); + QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int,QString)))); + + DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); + state->setUserName(defaultUserName()); + state->setServerCapabilities(caps); + state->setCollection(collection); + state->setParts(parts); + ChangeCollectionTask *task = new ChangeCollectionTask(state); + task->start(&pool); + + QTRY_COMPARE(state->calls().count(), callNames.size()); + for (int i = 0; i < callNames.size(); i++) { + QString command = QString::fromUtf8(state->calls().at(i).first); + QVariant parameter = state->calls().at(i).second; + + if (command == QLatin1String("cancelTask") && callNames[i] != QLatin1String("cancelTask")) { + qDebug() << "Got a cancel:" << parameter.toString(); + } + + QCOMPARE(command, callNames[i]); + + if (command == QLatin1String("cancelTask")) { + QVERIFY(!parameter.toString().isEmpty()); + } + if (command == QLatin1String("collectionChangeCommitted")) { + QCOMPARE(parameter.value().name(), collectionName); + QCOMPARE(parameter.value().remoteId().right(collectionName.length()), + collectionName); + } + } + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } +}; + +QTEST_GUILESS_MAIN(TestChangeCollectionTask) + +#include "testchangecollectiontask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/testchangeitemtask.cpp kdepim-runtime-15.08.0/resources/imap/autotests/testchangeitemtask.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/testchangeitemtask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/testchangeitemtask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,214 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" + +#include "changeitemtask.h" +#include "uidnextattribute.h" + +#include + +Q_DECLARE_METATYPE(QSet) + +class TestChangeItemTask : public ImapTestBase +{ + Q_OBJECT + +private Q_SLOTS: + void shouldAppendMessage_data() + { + QTest::addColumn("item"); + QTest::addColumn< QSet >("parts"); + QTest::addColumn< QList >("scenario"); + QTest::addColumn("callNames"); + + Akonadi::Collection collection; + Akonadi::Item item; + QSet parts; + QString messageContent; + QList scenario; + QStringList callNames; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.addAttribute(new UidNextAttribute(65)); + item = Akonadi::Item(2); + item.setParentCollection(collection); + item.setRemoteId("5"); + + KMime::Message::Ptr message(new KMime::Message); + + messageContent = "From: ervin\nTo: someone\nSubject: foo\n\nSpeechless..."; + + message->setContent(messageContent.toUtf8()); + message->parse(); + item.setPayload(message); + + parts.clear(); + parts << "PLD:RFC822"; + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 APPEND \"INBOX/Foo\" {55}\r\n" + message->encodedContent(true) + << "S: A000003 OK append done [ APPENDUID 1239890035 65 ]" + << "C: A000004 SELECT \"INBOX/Foo\"" + << "S: A000004 OK select done" + << "C: A000005 UID STORE 5 +FLAGS (\\Deleted)" + << "S: A000005 OK store done"; + + callNames.clear(); + callNames << "applyCollectionChanges" << "itemChangeCommitted"; + + QTest::newRow("modifying mail content") << item << parts << scenario << callNames; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.addAttribute(new UidNextAttribute(65)); + item = Akonadi::Item(2); + item.setParentCollection(collection); + item.setRemoteId("5"); + + message = KMime::Message::Ptr(new KMime::Message); + + messageContent = "From: ervin\nTo: someone\nSubject: foo\nMessage-ID: <42.4242.foo@bar.org>\n\nSpeechless..."; + + message->setContent(messageContent.toUtf8()); + message->parse(); + item.setPayload(message); + + parts.clear(); + parts << "PLD:RFC822"; + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 APPEND \"INBOX/Foo\" {90}\r\n" + message->encodedContent(true) + << "S: A000003 OK append done" + << "C: A000004 SELECT \"INBOX/Foo\"" + << "S: A000004 OK select done" + << "C: A000005 UID SEARCH HEADER Message-ID <42.4242.foo@bar.org>" + << "S: * SEARCH 65" + << "S: A000005 OK search done" + << "C: A000006 UID STORE 5 +FLAGS (\\Deleted)" + << "S: A000006 OK store done"; + + callNames.clear(); + callNames << "applyCollectionChanges" << "itemChangeCommitted"; + + QTest::newRow("modifying mail content, no APPENDUID, message has Message-ID") << item << parts << scenario << callNames; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.addAttribute(new UidNextAttribute(65)); + item = Akonadi::Item(2); + item.setParentCollection(collection); + item.setRemoteId("5"); + + message = KMime::Message::Ptr(new KMime::Message); + + messageContent = "From: ervin\nTo: someone\nSubject: foo\n\nSpeechless..."; + + message->setContent(messageContent.toUtf8()); + message->parse(); + item.setPayload(message); + + parts.clear(); + parts << "PLD:RFC822"; + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 APPEND \"INBOX/Foo\" {55}\r\n" + message->encodedContent(true) + << "S: A000003 OK append done" + << "C: A000004 SELECT \"INBOX/Foo\"" + << "S: A000004 OK select done" + << "C: A000005 UID SEARCH NEW UID 65:*" + << "S: * SEARCH 65" + << "S: A000005 OK search done" + << "C: A000006 UID STORE 5 +FLAGS (\\Deleted)" + << "S: A000006 OK store done"; + + callNames.clear(); + callNames << "applyCollectionChanges" << "itemChangeCommitted"; + + QTest::newRow("modifying mail content, no APPENDUID, message has no Message-ID") << item << parts << scenario << callNames; + + // collection unchanged for this test + // item only gets a set of flags + item.setFlags(QSet() << "\\Foo"); + + parts.clear(); + parts << "FLAGS"; + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 UID STORE 5 FLAGS (\\Foo)" + << "S: A000004 OK store done"; + + callNames.clear(); + callNames << "changeProcessed"; + + QTest::newRow("modifying mail flags") << item << parts << scenario << callNames; + } + + void shouldAppendMessage() + { + QFETCH(Akonadi::Item, item); + QFETCH(QSet, parts); + QFETCH(QList, scenario); + QFETCH(QStringList, callNames); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(1); + + pool.setPasswordRequester(createDefaultRequester()); + QVERIFY(pool.connect(createDefaultAccount())); + QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int,QString)))); + + DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); + state->setParts(parts); + state->setItem(item); + ChangeItemTask *task = new ChangeItemTask(state); + task->start(&pool); + + QTRY_COMPARE(state->calls().count(), callNames.size()); + for (int i = 0; i < callNames.size(); i++) { + QString command = QString::fromUtf8(state->calls().at(i).first); + QVariant parameter = state->calls().at(i).second; + + if (command == "cancelTask" && callNames[i] != "cancelTask") { + qDebug() << "Got a cancel:" << parameter.toString(); + } + + QCOMPARE(command, callNames[i]); + + if (command == "cancelTask") { + QVERIFY(!parameter.toString().isEmpty()); + } + } + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } +}; + +QTEST_GUILESS_MAIN(TestChangeItemTask) + +#include "testchangeitemtask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/testexpungecollectiontask.cpp kdepim-runtime-15.08.0/resources/imap/autotests/testexpungecollectiontask.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/testexpungecollectiontask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/testexpungecollectiontask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,127 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" + +#include "expungecollectiontask.h" + +class TestExpungeCollectionTask : public ImapTestBase +{ + Q_OBJECT + +private Q_SLOTS: + void shouldDeleteMailBox_data() + { + QTest::addColumn("collection"); + QTest::addColumn< QList >("scenario"); + QTest::addColumn("callNames"); + + Akonadi::Collection collection; + QSet parts; + QString messageContent; + QList scenario; + QStringList callNames; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 EXPUNGE" + << "S: A000004 OK expunge done"; + + callNames.clear(); + callNames << "taskDone"; + + QTest::newRow("normal case") << collection << scenario << callNames; + + // We keep the same collection + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 NO select failed"; + + callNames.clear(); + callNames << "cancelTask"; + + QTest::newRow("select failed") << collection << scenario << callNames; + + // We keep the same collection + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 EXPUNGE" + << "S: A000004 NO expunge failed"; + + callNames.clear(); + callNames << "cancelTask"; + + QTest::newRow("expunge failed") << collection << scenario << callNames; + } + + void shouldDeleteMailBox() + { + QFETCH(Akonadi::Collection, collection); + QFETCH(QList, scenario); + QFETCH(QStringList, callNames); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(1); + + pool.setPasswordRequester(createDefaultRequester()); + QVERIFY(pool.connect(createDefaultAccount())); + QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int,QString)))); + + DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); + state->setCollection(collection); + ExpungeCollectionTask *task = new ExpungeCollectionTask(state); + task->start(&pool); + + QTRY_COMPARE(state->calls().count(), callNames.size()); + for (int i = 0; i < callNames.size(); i++) { + QString command = QString::fromUtf8(state->calls().at(i).first); + QVariant parameter = state->calls().at(i).second; + + if (command == "cancelTask" && callNames[i] != "cancelTask") { + qDebug() << "Got a cancel:" << parameter.toString(); + } + + QCOMPARE(command, callNames[i]); + + if (command == "cancelTask") { + QVERIFY(!parameter.toString().isEmpty()); + } + } + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } +}; + +QTEST_GUILESS_MAIN(TestExpungeCollectionTask) + +#include "testexpungecollectiontask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/testmovecollectiontask.cpp kdepim-runtime-15.08.0/resources/imap/autotests/testmovecollectiontask.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/testmovecollectiontask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/testmovecollectiontask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,195 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" + +#include "movecollectiontask.h" + +class TestMoveCollectionTask : public ImapTestBase +{ + Q_OBJECT + +private Q_SLOTS: + void shouldRenameMailBox_data() + { + QTest::addColumn("collection"); + QTest::addColumn("source"); + QTest::addColumn("target"); + QTest::addColumn< QList >("scenario"); + QTest::addColumn("callNames"); + + Akonadi::Collection root; + Akonadi::Collection inbox; + Akonadi::Collection collection; + Akonadi::Collection source; + Akonadi::Collection target; + QList scenario; + QStringList callNames; + + root = createCollectionChain(QString()); + inbox = createCollectionChain(QLatin1String("/INBOX")); + + source = Akonadi::Collection(3); + source.setRemoteId(QLatin1String("/Foo")); + source.setParentCollection(inbox); + + collection = Akonadi::Collection(10); + collection.setRemoteId(QLatin1String("/Baz")); + collection.setParentCollection(source); + + target = Akonadi::Collection(4); + target.setRemoteId(QLatin1String("/Bar")); + target.setParentCollection(inbox); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 RENAME \"INBOX/Foo/Baz\" \"INBOX/Bar/Baz\"" + << "S: A000003 OK rename done" + << "C: A000004 SUBSCRIBE \"INBOX/Bar/Baz\"" + << "S: A000004 OK subscribe done"; + + callNames.clear(); + callNames << "collectionChangeCommitted"; + + QTest::newRow("moving mailbox") << collection << source << target << scenario << callNames; + + { + const Akonadi::Collection toplevel = createCollectionChain(QLatin1String("/Bar")); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 RENAME \"Bar\" \"INBOX/Bar\"" + << "S: A000003 OK rename done" + << "C: A000004 SUBSCRIBE \"INBOX/Bar\"" + << "S: A000004 OK subscribe done"; + + callNames.clear(); + callNames << "collectionChangeCommitted"; + + QTest::newRow("move mailbox from toplevel") << toplevel << root << inbox << scenario << callNames; + } + + { + const Akonadi::Collection toplevel = createCollectionChain(QLatin1String("/INBOX/Bar")); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 RENAME \"INBOX/Bar\" \"Bar\"" + << "S: A000003 OK rename done" + << "C: A000004 SUBSCRIBE \"Bar\"" + << "S: A000004 OK subscribe done"; + + callNames.clear(); + callNames << "collectionChangeCommitted"; + + QTest::newRow("move mailbox to toplevel") << toplevel << inbox << root << scenario << callNames; + } + + // Same collections + // The scenario changes though + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 RENAME \"INBOX/Foo/Baz\" \"INBOX/Bar/Baz\"" + << "S: A000003 OK rename done" + << "C: A000004 SUBSCRIBE \"INBOX/Bar/Baz\"" + << "S: A000004 NO subscribe failed"; + + callNames.clear(); + callNames << "emitWarning" << "collectionChangeCommitted"; + + QTest::newRow("moving mailbox, subscribe fails") << collection << source << target << scenario << callNames; + + inbox = createCollectionChain(QLatin1String(".INBOX")); + + source = Akonadi::Collection(3); + source.setRemoteId(QLatin1String(".Foo")); + source.setParentCollection(inbox); + + collection = Akonadi::Collection(10); + collection.setRemoteId(QLatin1String(".Baz")); + collection.setParentCollection(source); + + target = Akonadi::Collection(4); + target.setRemoteId(QLatin1String(".Bar")); + target.setParentCollection(inbox); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 RENAME \"INBOX.Foo.Baz\" \"INBOX.Bar.Baz\"" + << "S: A000003 OK rename done" + << "C: A000004 SUBSCRIBE \"INBOX.Bar.Baz\"" + << "S: A000004 OK subscribe done"; + + callNames.clear(); + callNames << "collectionChangeCommitted"; + + QTest::newRow("moving mailbox with non-standard separators") << collection << source << target << scenario << callNames; + } + + void shouldRenameMailBox() + { + QFETCH(Akonadi::Collection, collection); + QFETCH(Akonadi::Collection, source); + QFETCH(Akonadi::Collection, target); + QFETCH(QList, scenario); + QFETCH(QStringList, callNames); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(1); + + pool.setPasswordRequester(createDefaultRequester()); + QVERIFY(pool.connect(createDefaultAccount())); + QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int,QString)))); + + DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); + state->setCollection(collection); + state->setSourceCollection(source); + state->setTargetCollection(target); + MoveCollectionTask *task = new MoveCollectionTask(state); + task->start(&pool); + + QTRY_COMPARE(state->calls().count(), callNames.size()); + for (int i = 0; i < callNames.size(); i++) { + QString command = QString::fromUtf8(state->calls().at(i).first); + QVariant parameter = state->calls().at(i).second; + + if (command == "cancelTask" && callNames[i] != "cancelTask") { + qDebug() << "Got a cancel:" << parameter.toString(); + } + + QCOMPARE(command, callNames[i]); + + if (command == "cancelTask") { + QVERIFY(!parameter.toString().isEmpty()); + } + } + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } +}; + +QTEST_GUILESS_MAIN(TestMoveCollectionTask) + +#include "testmovecollectiontask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/testmoveitemstask.cpp kdepim-runtime-15.08.0/resources/imap/autotests/testmoveitemstask.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/testmoveitemstask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/testmoveitemstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,254 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" + +#include "moveitemstask.h" +#include "uidnextattribute.h" + +#include + +Q_DECLARE_METATYPE(QSet) + +class TestMoveItemsTask : public ImapTestBase +{ + Q_OBJECT + +private Q_SLOTS: + void shouldCopyAndDeleteMessage_data() + { + QTest::addColumn("item"); + QTest::addColumn("source"); + QTest::addColumn("target"); + QTest::addColumn< QList >("scenario"); + QTest::addColumn("callNames"); + + Akonadi::Item item; + Akonadi::Collection inbox; + Akonadi::Collection source; + Akonadi::Collection target; + QList scenario; + QStringList callNames; + + item = Akonadi::Item(1); + item.setRemoteId("5"); + + KMime::Message::Ptr message(new KMime::Message); + + QString messageContent = "From: ervin\nTo: someone\nSubject: foo\n\nSpeechless..."; + + message->setContent(messageContent.toUtf8()); + message->parse(); + item.setPayload(message); + + inbox = createCollectionChain(QLatin1String("/INBOX")); + source = Akonadi::Collection(3); + source.setRemoteId("/Foo"); + source.setParentCollection(inbox); + target = Akonadi::Collection(4); + target.setRemoteId("/Bar"); + target.setParentCollection(inbox); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 UID COPY 5 \"INBOX/Bar\"" + << "S: A000004 OK copy [ COPYUID 1239890035 5 65 ]" + << "C: A000005 UID STORE 5 +FLAGS (\\Deleted)" + << "S: A000005 OK store done"; + + callNames.clear(); + callNames << "itemsChangesCommitted"; + + QTest::newRow("moving mail") << item << source << target << scenario << callNames; + + // Same item and collections + // The scenario changes though + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 UID COPY 5 \"INBOX/Bar\"" + << "S: A000004 OK copy [ COPYUID 1239890035 5 65 ]" + << "C: A000005 UID STORE 5 +FLAGS (\\Deleted)" + << "S: A000005 NO store failed"; + + callNames.clear(); + callNames << "emitWarning" << "itemsChangesCommitted"; + + QTest::newRow("moving mail, store fails") << item << source << target << scenario << callNames; + + item = Akonadi::Item(1); + item.setRemoteId("5"); + + message = KMime::Message::Ptr(new KMime::Message); + + messageContent = "From: ervin\nTo: someone\nSubject: foo\nMessage-ID: <42.4242.foo@bar.org>\n\nSpeechless..."; + + message->setContent(messageContent.toUtf8()); + message->parse(); + item.setPayload(message); + + source = Akonadi::Collection(3); + source.setRemoteId("/Foo"); + source.setParentCollection(inbox); + source.addAttribute(new UidNextAttribute(42)); + target = Akonadi::Collection(3); + target.setRemoteId("/Bar"); + target.setParentCollection(inbox); + target.addAttribute(new UidNextAttribute(65)); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 UID COPY 5 \"INBOX/Bar\"" + << "S: A000004 OK copy done" + << "C: A000005 UID STORE 5 +FLAGS (\\Deleted)" + << "S: A000005 OK store done" + << "C: A000006 SELECT \"INBOX/Bar\"" + << "S: A000006 OK select done" + << "C: A000007 UID SEARCH (HEADER Message-ID <42.4242.foo@bar.org>)" + << "S: * SEARCH 65" + << "S: A000007 OK search done"; + + callNames.clear(); + callNames << "itemsChangesCommitted" << "applyCollectionChanges"; + + QTest::newRow("moving mail, no COPYUID, message had Message-ID") << item << source << target << scenario << callNames; + + item = Akonadi::Item(1); + item.setRemoteId("5"); + + message = KMime::Message::Ptr(new KMime::Message); + + messageContent = "From: ervin\nTo: someone\nSubject: foo\n\nSpeechless..."; + + message->setContent(messageContent.toUtf8()); + message->parse(); + item.setPayload(message); + + source = Akonadi::Collection(3); + source.setRemoteId("/Foo"); + source.setParentCollection(inbox); + source.addAttribute(new UidNextAttribute(42)); + target = Akonadi::Collection(4); + target.setRemoteId("/Bar"); + target.setParentCollection(inbox); + target.addAttribute(new UidNextAttribute(65)); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 UID COPY 5 \"INBOX/Bar\"" + << "S: A000004 OK copy done" + << "C: A000005 UID STORE 5 +FLAGS (\\Deleted)" + << "S: A000005 OK store done" + << "C: A000006 SELECT \"INBOX/Bar\"" + << "S: A000006 OK select done" + << "C: A000007 UID SEARCH NEW UID 65:*" + << "S: * SEARCH 65" + << "S: A000007 OK search done"; + + callNames.clear(); + callNames << "itemsChangesCommitted" << "applyCollectionChanges"; + + QTest::newRow("moving mail, no COPYUID, message didn't have Message-ID") << item << source << target << scenario << callNames; + + item = Akonadi::Item(1); + item.setRemoteId("5"); + message = KMime::Message::Ptr(new KMime::Message); + messageContent = "From: ervin\nTo: someone\nSubject: foo\nMessage-ID: <42.4242.foo@bar.org>\n\nSpeechless..."; + message->setContent(messageContent.toUtf8()); + message->parse(); + item.setPayload(message); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 UID COPY 5 \"INBOX/Bar\"" + << "S: A000004 OK copy done" + << "C: A000005 UID STORE 5 +FLAGS (\\Deleted)" + << "S: A000005 OK store done" + << "C: A000006 SELECT \"INBOX/Bar\"" + << "S: A000006 OK select done" + << "C: A000007 UID SEARCH (HEADER Message-ID <42.4242.foo@bar.org>)" + << "S: * SEARCH 61 65" + << "S: A000007 OK search done"; + + callNames.clear(); + callNames << "itemsChangesCommitted" << "applyCollectionChanges"; + + QTest::newRow("moving mail, no COPYUID, message didn't have unique Message-ID, but last one matches old uidnext") << item << source << target << scenario << callNames; + } + + void shouldCopyAndDeleteMessage() + { + QFETCH(Akonadi::Item, item); + QFETCH(Akonadi::Collection, source); + QFETCH(Akonadi::Collection, target); + QFETCH(QList, scenario); + QFETCH(QStringList, callNames); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(1); + + pool.setPasswordRequester(createDefaultRequester()); + QVERIFY(pool.connect(createDefaultAccount())); + QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int,QString)))); + + DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); + state->setItem(item); + state->setSourceCollection(source); + state->setTargetCollection(target); + MoveItemsTask *task = new MoveItemsTask(state); + task->start(&pool); + + QTRY_COMPARE(state->calls().count(), callNames.size()); + for (int i = 0; i < callNames.size(); i++) { + QString command = QString::fromUtf8(state->calls().at(i).first); + QVariant parameter = state->calls().at(i).second; + + if (command == "cancelTask" && callNames[i] != "cancelTask") { + qDebug() << "Got a cancel:" << parameter.toString(); + } + + QCOMPARE(command, callNames[i]); + + if (command == "cancelTask") { + QVERIFY(!parameter.toString().isEmpty()); + } + } + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } +}; + +QTEST_GUILESS_MAIN(TestMoveItemsTask) + +#include "testmoveitemstask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/testremovecollectionrecursivetask.cpp kdepim-runtime-15.08.0/resources/imap/autotests/testremovecollectionrecursivetask.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/testremovecollectionrecursivetask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/testremovecollectionrecursivetask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,247 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" + +#include "removecollectionrecursivetask.h" + +class TestRemoveCollectionRecursiveTask : public ImapTestBase +{ + Q_OBJECT + + void shouldDeleteMailBoxRecursive_data() + { + QTest::addColumn("collection"); + QTest::addColumn< QList >("scenario"); + QTest::addColumn("callNames"); + + Akonadi::Collection collection; + QList scenario; + QStringList callNames; + + collection = createCollectionChain(QLatin1String("/INBOX/test1")); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 LSUB \"\" *" + << "S: * LSUB ( \\HasChildren ) / INBOX" + << "S: * LSUB ( \\HasChildren ) / INBOX/test1" + << "S: * LSUB ( ) / INBOX/test1/test2" + << "S: A000003 OK Completed ( 0.000 secs 26 calls )" + << "C: A000004 SELECT \"INBOX/test1/test2\"" + << "S: * FLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen )" + << "S: * OK [ PERMANENTFLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen \\* ) ]" + << "S: * 1 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UNSEEN 1 ]" + << "S: * OK [ UIDVALIDITY 1292857898 ]" + << "S: * OK [ UIDNEXT 2 ]" + << "S: A000004 OK Completed [ READ-WRITE ]" + << "C: A000005 STORE 1:* +FLAGS (\\DELETED)" + << "S: * 1 FETCH ( FLAGS (\\Deleted) ) " + << "S: A000005 OK Completed" + << "C: A000006 EXPUNGE" + << "S: * 1 EXPUNGE" + << "S: * 0 EXISTS" + << "S: * 0 RECENT" + << "S: A000006 OK Completed" + << "C: A000007 CLOSE" + << "S: A000007 OK Completed" + << "C: A000008 DELETE \"INBOX/test1/test2\"" + << "S: * 0 EXISTS" + << "S: * 0 RECENT" + << "S: A000008 OK Completed" + << "C: A000009 SELECT \"INBOX/test1\"" + << "S: * FLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen )" + << "S: * OK [ PERMANENTFLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen \\* ) ]" + << "S: * 1 EXISTS" + << "S: * 1 RECENT" + << "S: * OK [ UIDVALIDITY 1292857888 ]" + << "S: * OK [ UIDNEXT 2 ]" + << "S: A000009 OK Completed [ READ-WRITE ]" + << "C: A000010 STORE 1:* +FLAGS (\\DELETED)" + << "S: * 1 FETCH ( FLAGS (\\Recent \\Deleted \\Seen) )" + << "S: A000010 OK Completed" + << "C: A000011 EXPUNGE" + << "S: * 1 EXPUNGE" + << "S: * 0 EXISTS" + << "S: * 0 RECENT" + << "S: A000011 OK Completed" + << "C: A000012 CLOSE" + << "S: A000012 OK Completed" + << "C: A000013 DELETE \"INBOX/test1\"" + << "S: * 0 EXISTS" + << "S: * 0 RECENT" + << "S: A000013 OK Completed"; + callNames.clear(); + callNames << "changeProcessed"; + + QTest::newRow("normal case") << collection << scenario << callNames; + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 LSUB \"\" *" + << "S: * LSUB ( \\HasChildren ) / INBOX" + << "S: * LSUB ( \\HasChildren ) / INBOX/test1" + << "S: * LSUB ( ) / INBOX/test1/test2" + << "S: A000003 OK Completed ( 0.000 secs 26 calls )"; + collection.setRemoteId("/test1"); + collection.setParentCollection(Akonadi::Collection::root()); + callNames.clear(); + callNames << "changeProcessed" << "emitWarning" << "synchronizeCollectionTree"; + QTest::newRow("invalid collection") << collection << scenario << callNames; + + collection = createCollectionChain(QLatin1String(".INBOX.test1")); + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 LSUB \"\" *" + << "S: * LSUB ( \\HasChildren ) . INBOX" + << "S: * LSUB ( \\HasChildren ) . INBOX.test1" + << "S: * LSUB ( ) . INBOX.test1.test2" + << "S: A000003 OK Completed ( 0.000 secs 26 calls )" + << "C: A000004 SELECT \"INBOX.test1.test2\"" + << "S: * FLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen )" + << "S: * OK [ PERMANENTFLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen \\* ) ]" + << "S: * 1 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UNSEEN 1 ]" + << "S: * OK [ UIDVALIDITY 1292857898 ]" + << "S: * OK [ UIDNEXT 2 ]" + << "S: A000004 OK Completed [ READ-WRITE ]" + << "C: A000005 STORE 1:* +FLAGS (\\DELETED)" + << "S: * 1 FETCH ( FLAGS (\\Deleted) ) " + << "S: A000005 OK Completed" + << "C: A000006 EXPUNGE" + << "S: * 1 EXPUNGE" + << "S: * 0 EXISTS" + << "S: * 0 RECENT" + << "S: A000006 OK Completed" + << "C: A000007 CLOSE" + << "S: A000007 OK Completed" + << "C: A000008 DELETE \"INBOX.test1.test2\"" + << "S: * 0 EXISTS" + << "S: * 0 RECENT" + << "S: A000008 OK Completed" + << "C: A000009 SELECT \"INBOX.test1\"" + << "S: * FLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen )" + << "S: * OK [ PERMANENTFLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen \\* ) ]" + << "S: * 1 EXISTS" + << "S: * 1 RECENT" + << "S: * OK [ UIDVALIDITY 1292857888 ]" + << "S: * OK [ UIDNEXT 2 ]" + << "S: A000009 OK Completed [ READ-WRITE ]" + << "C: A000010 STORE 1:* +FLAGS (\\DELETED)" + << "S: * 1 FETCH ( FLAGS (\\Recent \\Deleted \\Seen) )" + << "S: A000010 OK Completed" + << "C: A000011 EXPUNGE" + << "S: * 1 EXPUNGE" + << "S: * 0 EXISTS" + << "S: * 0 RECENT" + << "S: A000011 OK Completed" + << "C: A000012 CLOSE" + << "S: A000012 OK Completed" + << "C: A000013 DELETE \"INBOX.test1\"" + << "S: * 0 EXISTS" + << "S: * 0 RECENT" + << "S: A000013 OK Completed"; + callNames.clear(); + callNames << "changeProcessed"; + QTest::newRow("non-standard separator") << collection << scenario << callNames; + + collection = createCollectionChain(QLatin1String(".INBOX.test1")); + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 LSUB \"\" *" + << "S: * LSUB ( \\HasChildren ) . INBOX" + << "S: * LSUB ( \\HasChildren ) . INBOX.test1" + << "S: * LSUB ( ) . INBOX.test1.test2" + << "S: A000003 OK Completed ( 0.000 secs 26 calls )" + << "C: A000004 SELECT \"INBOX.test1.test2\"" + << "S: * FLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen )" + << "S: * OK [ PERMANENTFLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen \\* ) ]" + << "S: * 1 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UNSEEN 1 ]" + << "S: * OK [ UIDVALIDITY 1292857898 ]" + << "S: * OK [ UIDNEXT 2 ]" + << "S: A000004 OK Completed [ READ-WRITE ]" + << "C: A000005 STORE 1:* +FLAGS (\\DELETED)" + << "S: * 1 FETCH ( FLAGS (\\Deleted) ) " + << "S: A000005 OK Completed" + << "C: A000006 EXPUNGE" + << "S: * 1 EXPUNGE" + << "S: * 0 EXISTS" + << "S: * 0 RECENT" + << "S: A000006 OK Completed" + << "C: A000007 CLOSE" + << "S: A000007 NO Close failed"; + callNames.clear(); + callNames << "changeProcessed" << "emitWarning" << "synchronizeCollectionTree"; + QTest::newRow("close failed") << collection << scenario << callNames; + } + + void shouldDeleteMailBoxRecursive() + { + QFETCH(Akonadi::Collection, collection); + QFETCH(QList, scenario); + QFETCH(QStringList, callNames); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(1); + + pool.setPasswordRequester(createDefaultRequester()); + QVERIFY(pool.connect(createDefaultAccount())); + QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int,QString)))); + + DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); + state->setCollection(collection); + RemoveCollectionRecursiveTask *task = new RemoveCollectionRecursiveTask(state); + task->start(&pool); + QEventLoop loop; + connect(task, &RemoveCollectionRecursiveTask::destroyed, &loop, &QEventLoop::quit); + loop.exec(); + + QCOMPARE(state->calls().count(), callNames.size()); + for (int i = 0; i < callNames.size(); i++) { + QString command = QString::fromUtf8(state->calls().at(i).first); + QVariant parameter = state->calls().at(i).second; + + if (command == "cancelTask" && callNames[i] != "cancelTask") { + qDebug() << "Got a cancel:" << parameter.toString(); + } + + QCOMPARE(command, callNames[i]); + + if (command == "cancelTask") { + QVERIFY(!parameter.toString().isEmpty()); + } + } + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } +}; + +QTEST_GUILESS_MAIN(TestRemoveCollectionRecursiveTask) + +#include "testremovecollectionrecursivetask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/testresourcetask.cpp kdepim-runtime-15.08.0/resources/imap/autotests/testresourcetask.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/testresourcetask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/testresourcetask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,173 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" +#include +#include "resourcetask.h" +#include + +Q_DECLARE_METATYPE(ResourceTask::ActionIfNoSession) + +class DummyResourceTask : public ResourceTask +{ +public: + explicit DummyResourceTask(ActionIfNoSession action, ResourceStateInterface::Ptr resource, QObject *parent = Q_NULLPTR) + : ResourceTask(action, resource, parent) + { + + } + + void doStart(KIMAP::Session */*session*/) + { + cancelTask("Dummy task"); + } +}; + +class TestResourceTask : public ImapTestBase +{ + Q_OBJECT + +private Q_SLOTS: + void shouldRequestSession_data() + { + QTest::addColumn("state"); + QTest::addColumn< QList >("scenario"); + QTest::addColumn("shouldConnect"); + QTest::addColumn("shouldRequestSession"); + QTest::addColumn("actionIfNoSession"); + QTest::addColumn("callNames"); + QTest::addColumn("firstCallParameter"); + + DummyResourceState::Ptr state; + QList scenario; + QStringList callNames; + + state = DummyResourceState::Ptr(new DummyResourceState); + scenario.clear(); + scenario << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in" + << "C: A000002 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" + << "S: A000002 OK Completed"; + callNames.clear(); + callNames << "cancelTask"; + QTest::newRow("normal case") << state << scenario + << true << false + << ResourceTask::DeferIfNoSession + << callNames << QVariant("Dummy task"); + + state = DummyResourceState::Ptr(new DummyResourceState); + callNames.clear(); + callNames << "deferTask"; + QTest::newRow("all sessions allocated (defer)") << state << scenario + << true << true + << ResourceTask::DeferIfNoSession + << callNames << QVariant(); + + state = DummyResourceState::Ptr(new DummyResourceState); + callNames.clear(); + callNames << "cancelTask"; + QTest::newRow("all sessions allocated (cancel)") << state << scenario + << true << true + << ResourceTask::CancelIfNoSession + << callNames << QVariant(); + + state = DummyResourceState::Ptr(new DummyResourceState); + scenario.clear(); + callNames.clear(); + callNames << "deferTask" << "scheduleConnectionAttempt"; + QTest::newRow("disconnected pool (defer)") << state << scenario + << false << false + << ResourceTask::DeferIfNoSession + << callNames << QVariant(); + + state = DummyResourceState::Ptr(new DummyResourceState); + scenario.clear(); + callNames.clear(); + callNames << "cancelTask" << "scheduleConnectionAttempt"; + QTest::newRow("disconnected pool (cancel)") << state << scenario + << false << false + << ResourceTask::CancelIfNoSession + << callNames << QVariant(); + } + + void shouldRequestSession() + { + QFETCH(DummyResourceState::Ptr, state); + QFETCH(QList, scenario); + QFETCH(bool, shouldConnect); + QFETCH(bool, shouldRequestSession); + QFETCH(ResourceTask::ActionIfNoSession, actionIfNoSession); + QFETCH(QStringList, callNames); + QFETCH(QVariant, firstCallParameter); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(1); + + if (shouldConnect) { + QSignalSpy poolSpy(&pool, SIGNAL(connectDone(int,QString))); + + pool.setPasswordRequester(createDefaultRequester()); + QVERIFY(pool.connect(createDefaultAccount())); + + QTRY_COMPARE(poolSpy.count(), 1); + QCOMPARE(poolSpy.at(0).at(0).toInt(), (int)SessionPool::NoError); + } + + if (shouldRequestSession) { + QSignalSpy requestSpy(&pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString))); + pool.requestSession(); + QTRY_COMPARE(requestSpy.count(), 1); + } + + QSignalSpy sessionSpy(&pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString))); + DummyResourceTask *task = new DummyResourceTask(actionIfNoSession, state); + task->start(&pool); + + if (shouldConnect) { + QTRY_COMPARE(sessionSpy.count(), 1); + } else { + //We want to ensure the signal isn't emitted, so we have to wait + QTest::qWait(500); + QCOMPARE(sessionSpy.count(), 0); + } + + QCOMPARE(state->calls().count(), callNames.size()); + for (int i = 0; i < callNames.size(); i++) { + QString command = QString::fromUtf8(state->calls().at(i).first); + QCOMPARE(command, callNames[i]); + } + + if (firstCallParameter.toString() == "Dummy task") { + QCOMPARE(state->calls().first().second, firstCallParameter); + } + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } +}; + +QTEST_GUILESS_MAIN(TestResourceTask) + +#include "testresourcetask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/testretrievecollectionmetadatatask.cpp kdepim-runtime-15.08.0/resources/imap/autotests/testretrievecollectionmetadatatask.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/testretrievecollectionmetadatatask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/testretrievecollectionmetadatatask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,324 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" + +#include "retrievecollectionmetadatatask.h" + +#include +#include +#include "collectionannotationsattribute.h" +#include "imapaclattribute.h" +#include "imapquotaattribute.h" +#include "noselectattribute.h" +#include + +typedef QMap QBYTEARRAYMAP; + +Q_DECLARE_METATYPE(Akonadi::Collection::Rights) +Q_DECLARE_METATYPE(QBYTEARRAYMAP) + +class TestRetrieveCollectionMetadataTask : public ImapTestBase +{ + Q_OBJECT + +private Q_SLOTS: + + void initTestCase() + { + Akonadi::AttributeFactory::registerAttribute(); + Akonadi::AttributeFactory::registerAttribute(); + } + + void shouldCollectionRetrieveMetadata_data() + { + QTest::addColumn("collection"); + QTest::addColumn("capabilities"); + QTest::addColumn< QList >("scenario"); + QTest::addColumn("callNames"); + QTest::addColumn("expectedRights"); + QTest::addColumn("expectedAnnotations"); + + Akonadi::Collection collection; + QStringList capabilities; + QList scenario; + QStringList callNames; + QMap expectedAnnotations; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.setRights(0); + + capabilities.clear(); + capabilities << "ANNOTATEMORE" << "ACL" << "QUOTA"; + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 GETANNOTATION \"INBOX/Foo\" \"*\" \"value.shared\"" + << "S: * ANNOTATION INBOX/Foo /vendor/kolab/folder-test ( value.shared true )" + << "S: A000003 OK annotations retrieved" + << "C: A000004 MYRIGHTS \"INBOX/Foo\"" + << "S: * MYRIGHTS \"INBOX/Foo\" lrswipkxtecda" + << "S: A000004 OK rights retrieved" + << "C: A000005 GETQUOTAROOT \"INBOX/Foo\"" + << "S: * QUOTAROOT INBOX/Foo user/foo" + << "S: * QUOTA user/foo ( )" + << "S: A000005 OK quota retrieved" + << "C: A000006 GETACL \"INBOX/Foo\"" + << "S: * ACL INBOX/Foo foo@kde.org lrswipcda" + << "S: A000006 OK acl retrieved"; + + callNames.clear(); + callNames << "collectionAttributesRetrieved"; + + expectedAnnotations.clear(); + expectedAnnotations.insert("/shared/vendor/kolab/folder-test", "true"); + + Akonadi::Collection::Rights rights = Akonadi::Collection::AllRights; + QTest::newRow("first listing, connected IMAP") << collection << capabilities << scenario + << callNames << rights << expectedAnnotations; + + // + // Test that if the parent collection doesn't allow renaming in its ACL, the child mailbox + // can't be renamed, i.e. doesn't have the CanChangeCollection flag. + // + Akonadi::Collection parentCollection = createCollectionChain(QLatin1String("/INBOX")); + QMap rightsMap; + rightsMap.insert("Hans", KIMAP::Acl::Lookup | KIMAP::Acl::Read | KIMAP::Acl::KeepSeen | + KIMAP::Acl::Write | KIMAP::Acl::Insert | KIMAP::Acl::Post | + KIMAP::Acl::Delete); + Akonadi::ImapAclAttribute *aclAttribute = new Akonadi::ImapAclAttribute(); + aclAttribute->setRights(rightsMap); + parentCollection.addAttribute(aclAttribute); + collection.setParentCollection(parentCollection); + rights = Akonadi::Collection::AllRights; + rights &= ~Akonadi::Collection::CanChangeCollection; + QTest::newRow("parent without create rights") << collection << capabilities << scenario + << callNames << rights << expectedAnnotations; + + // + // Test that if the parent collection is a noselect folder, the child mailbox will not have + // rename (CanChangeCollection) permission. + // + parentCollection = createCollectionChain(QLatin1String("/INBOX")); + NoSelectAttribute *noSelectAttribute = new NoSelectAttribute(); + parentCollection.addAttribute(noSelectAttribute); + collection.setParentCollection(parentCollection); + QTest::newRow("parent wit noselect") << collection << capabilities << scenario + << callNames << rights << expectedAnnotations; + parentCollection.removeAttribute(); + + // + // Test that the rights are properly set on the resulting collection if the mailbox doesn't + // have full rights. + // + collection.setParentCollection(createCollectionChain(QLatin1String("/INBOX"))); + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 GETANNOTATION \"INBOX/Foo\" \"*\" \"value.shared\"" + << "S: * ANNOTATION INBOX/Foo /vendor/kolab/folder-test ( value.shared true )" + << "S: A000003 OK annotations retrieved" + << "C: A000004 MYRIGHTS \"INBOX/Foo\"" + << "S: * MYRIGHTS \"INBOX/Foo\" wi" + << "S: A000004 OK rights retrieved" + << "C: A000005 GETQUOTAROOT \"INBOX/Foo\"" + << "S: * QUOTAROOT INBOX/Foo user/foo" + << "S: * QUOTA user/foo ( )" + << "S: A000005 OK quota retrieved"; + rights = Akonadi::Collection::CanCreateItem | Akonadi::Collection::CanChangeItem | + Akonadi::Collection::CanChangeCollection; + QTest::newRow("only some rights") << collection << capabilities << scenario + << callNames << rights << expectedAnnotations; + + // + // Test that a warning is issued if the insert rights of a folder have been revoked on the server. + // + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.setParentCollection(createCollectionChain(QLatin1String("/INBOX"))); + //We use the aclattribute to determine if a collection already has acl's or not + collection.addAttribute(new Akonadi::ImapAclAttribute()); + collection.setRights(Akonadi::Collection::CanCreateItem); + + capabilities.clear(); + capabilities << "ANNOTATEMORE" << "ACL" << "QUOTA"; + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 GETANNOTATION \"INBOX/Foo\" \"*\" \"value.shared\"" + << "S: * ANNOTATION INBOX/Foo /vendor/kolab/folder-test ( value.shared true )" + << "S: A000003 OK annotations retrieved" + << "C: A000004 MYRIGHTS \"INBOX/Foo\"" + << "S: * MYRIGHTS \"INBOX/Foo\" w" + << "S: A000004 OK rights retrieved" + << "C: A000005 GETQUOTAROOT \"INBOX/Foo\"" + << "S: * QUOTAROOT INBOX/Foo user/foo" + << "S: * QUOTA user/foo ( )" + << "S: A000005 OK quota retrieved"; + + callNames.clear(); + callNames << "showInformationDialog"; + callNames << "collectionAttributesRetrieved"; + + rights = Akonadi::Collection::CanChangeItem | Akonadi::Collection::CanChangeCollection; + QTest::newRow("revoked rights") << collection << capabilities << scenario + << callNames << rights << expectedAnnotations; + + // + // Test that NoInferiors overrides acl rights and disallows creating new mailboxes + // + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.setParentCollection(createCollectionChain(QString())); + collection.setRemoteId("/INBOX"); + collection.setRights(Akonadi::Collection::AllRights); + collection.addAttribute(new NoInferiorsAttribute(true)); + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 GETANNOTATION \"INBOX\" \"*\" \"value.shared\"" + << "S: * ANNOTATION INBOX /vendor/kolab/folder-test ( value.shared true )" + << "S: A000003 OK annotations retrieved" + << "C: A000004 MYRIGHTS \"INBOX\"" + << "S: * MYRIGHTS \"INBOX\" wk" + << "S: A000004 OK rights retrieved" + << "C: A000005 GETQUOTAROOT \"INBOX\"" + << "S: * QUOTAROOT INBOX user" + << "S: * QUOTA user ( )" + << "S: A000005 OK quota retrieved"; + + callNames.clear(); + callNames << "collectionAttributesRetrieved"; + + rights = Akonadi::Collection::CanChangeItem | Akonadi::Collection::CanChangeCollection; + + QTest::newRow("noinferiors") << collection << capabilities << scenario + << callNames << rights << expectedAnnotations; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.setRights(0); + + capabilities.clear(); + capabilities << "METADATA" << "ACL" << "QUOTA"; + + expectedAnnotations.clear(); + expectedAnnotations.insert("/shared/vendor/kolab/folder-test", "true"); + expectedAnnotations.insert("/shared/vendor/kolab/folder-test2", ""); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 GETMETADATA (DEPTH infinity) \"INBOX/Foo\" (/shared)" + << "S: * METADATA \"INBOX/Foo\" (/shared/vendor/kolab/folder-test \"true\")" + << "S: * METADATA \"INBOX/Foo\" (/shared/vendor/kolab/folder-test2 \"NIL\")" + << "S: * METADATA \"INBOX/Foo\" (/shared/vendor/cmu/cyrus-imapd/lastupdate \"true\")" + << "S: A000003 OK GETMETADATA complete" + << "C: A000004 MYRIGHTS \"INBOX/Foo\"" + << "S: * MYRIGHTS \"INBOX/Foo\" lrswipkxtecda" + << "S: A000004 OK rights retrieved" + << "C: A000005 GETQUOTAROOT \"INBOX/Foo\"" + << "S: * QUOTAROOT INBOX/Foo user/Foo" + << "S: * QUOTA user/Foo ( )" + << "S: A000005 OK quota retrieved" + << "C: A000006 GETACL \"INBOX/Foo\"" + << "S: * ACL INBOX/Foo foo@kde.org lrswipcda" + << "S: A000006 OK acl retrieved"; + + callNames.clear(); + callNames << "collectionAttributesRetrieved"; + + rights = Akonadi::Collection::AllRights; + QTest::newRow("METADATA") << collection << capabilities << scenario + << callNames << rights << expectedAnnotations; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.setRights(0); + + capabilities.clear(); + expectedAnnotations.clear(); + + callNames.clear(); + callNames << "collectionAttributesRetrieved"; + + rights = 0; + + scenario.clear(); + scenario << defaultPoolConnectionScenario(); + + QTest::newRow("no capabilities") << collection << capabilities << scenario + << callNames << rights << expectedAnnotations; + } + + void shouldCollectionRetrieveMetadata() + { + QFETCH(Akonadi::Collection, collection); + QFETCH(QStringList, capabilities); + QFETCH(QList, scenario); + QFETCH(QStringList, callNames); + QFETCH(Akonadi::Collection::Rights, expectedRights); + QFETCH(QBYTEARRAYMAP, expectedAnnotations); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(1); + + pool.setPasswordRequester(createDefaultRequester()); + QVERIFY(pool.connect(createDefaultAccount())); + QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int,QString)))); + + DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); + state->setCollection(collection); + state->setServerCapabilities(capabilities); + state->setUserName("Hans"); + RetrieveCollectionMetadataTask *task = new RetrieveCollectionMetadataTask(state); + + task->start(&pool); + + QTRY_COMPARE(state->calls().count(), callNames.size()); + for (int i = 0; i < callNames.size(); i++) { + QString command = QString::fromUtf8(state->calls().at(i).first); + QVariant parameter = state->calls().at(i).second; + + if (command == "cancelTask" && callNames[i] != "cancelTask") { + qDebug() << "Got a cancel:" << parameter.toString(); + } + + QCOMPARE(command, callNames[i]); + + if (command == "cancelTask") { + QVERIFY(!parameter.toString().isEmpty()); + } + + if (command == "collectionAttributesRetrieved") { + Akonadi::Collection collection = parameter.value(); + QCOMPARE(collection.rights(), expectedRights); + + if (!expectedAnnotations.isEmpty()) { + QVERIFY(collection.hasAttribute()); + QCOMPARE(collection.attribute()->annotations(), expectedAnnotations); + } + } + } + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } +}; + +QTEST_GUILESS_MAIN(TestRetrieveCollectionMetadataTask) + +#include "testretrievecollectionmetadatatask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/testretrievecollectionstask.cpp kdepim-runtime-15.08.0/resources/imap/autotests/testretrievecollectionstask.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/testretrievecollectionstask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/testretrievecollectionstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,480 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" + +#include "retrievecollectionstask.h" +#include "noselectattribute.h" +#include + +#include +#include +#include +#include + +class TestRetrieveCollectionsTask : public ImapTestBase +{ + Q_OBJECT +public: + TestRetrieveCollectionsTask(QObject *parent = Q_NULLPTR) + : ImapTestBase(parent), m_nextCollectionId(1) + { + } + +private Q_SLOTS: + void shouldListCollections_data() + { + QTest::addColumn("expectedCollections"); + QTest::addColumn< QList >("scenario"); + QTest::addColumn("callNames"); + QTest::addColumn("isSubscriptionEnabled"); + QTest::addColumn("isDisconnectedModeEnabled"); + QTest::addColumn("intervalCheckTime"); + QTest::addColumn("separator"); + + Akonadi::Collection collection; + + Akonadi::Collection::List expectedCollections; + QList scenario; + QStringList callNames; + bool isSubscriptionEnabled; + bool isDisconnectedModeEnabled; + int intervalCheckTime; + + expectedCollections.clear(); + expectedCollections << createRootCollection() + << createCollection("/", "INBOX") + << createCollection("/", "INBOX/Calendar") + << createCollection("/", "INBOX/Calendar/Private") + << createCollection("/", "INBOX/Archives"); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 LIST \"\" *" + << "S: * LIST ( \\HasChildren ) / INBOX" + << "S: * LIST ( \\HasChildren ) / INBOX/Calendar" + << "S: * LIST ( ) / INBOX/Calendar/Private" + << "S: * LIST ( ) / INBOX/Archives" + << "S: A000003 OK list done"; + + callNames.clear(); + callNames << "setIdleCollection" << "collectionsRetrieved"; + + isSubscriptionEnabled = false; + isDisconnectedModeEnabled = false; + intervalCheckTime = -1; + + QTest::newRow("first listing, connected IMAP") << expectedCollections << scenario << callNames + << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime + << QChar('/'); + + expectedCollections.clear(); + expectedCollections << createRootCollection(true, 5) + << createCollection("/", "INBOX") + << createCollection("/", "INBOX/Calendar") + << createCollection("/", "INBOX/Calendar/Private") + << createCollection("/", "INBOX/Archives"); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 LIST \"\" *" + << "S: * LIST ( \\HasChildren ) / INBOX" + << "S: * LIST ( \\HasChildren ) / INBOX/Calendar" + << "S: * LIST ( ) / INBOX/Calendar/Private" + << "S: * LIST ( ) / INBOX/Archives" + << "S: A000003 OK list done"; + + callNames.clear(); + callNames << "setIdleCollection" << "collectionsRetrieved"; + + isSubscriptionEnabled = false; + isDisconnectedModeEnabled = true; + intervalCheckTime = 5; + + QTest::newRow("first listing, disconnected IMAP") << expectedCollections << scenario << callNames + << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime + << QChar('/'); + + expectedCollections.clear(); + expectedCollections << createRootCollection(true, 5) + << createCollection("/", "INBOX") + << createCollection("/", "INBOX/Archives"); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 LIST \"\" *" + << "S: * LIST ( \\HasChildren ) / INBOX" + << "S: * LIST ( \\HasChildren ) / INBOX/" + << "S: * LIST ( \\HasChildren ) / INBOX/Archives" + << "S: A000003 OK list done"; + + callNames.clear(); + callNames << "setIdleCollection" << "collectionsRetrieved"; + + isSubscriptionEnabled = false; + isDisconnectedModeEnabled = true; + intervalCheckTime = 5; + + QTest::newRow("first listing, spurious INBOX/ (BR: 25342)") << expectedCollections << scenario << callNames + << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime + << QChar('/'); + + expectedCollections.clear(); + expectedCollections << createRootCollection() + << createCollection("/", "INBOX") + << createCollection("/", "INBOX/Calendar", true) + << createCollection("/", "INBOX/Calendar/Private") + << createCollection("/", "INBOX/Archives"); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 LIST \"\" *" + << "S: * LIST ( \\HasChildren ) / INBOX" + << "S: * LIST ( ) / INBOX/Calendar/Private" + << "S: * LIST ( ) / INBOX/Archives" + << "S: A000003 OK list done"; + + callNames.clear(); + callNames << "setIdleCollection" << "collectionsRetrieved"; + + isSubscriptionEnabled = false; + isDisconnectedModeEnabled = false; + intervalCheckTime = -1; + + QTest::newRow("auto-insert missing nodes in the tree") << expectedCollections << scenario << callNames + << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime + << QChar('/'); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 LIST \"\" *" + << "S: * LIST ( ) / INBOX/Archives" + << "S: * LIST ( ) / INBOX/Calendar/Private" + << "S: * LIST ( \\HasChildren ) / INBOX" + << "S: A000003 OK list done"; + + callNames.clear(); + callNames << "setIdleCollection" << "collectionsRetrieved"; + + isSubscriptionEnabled = false; + isDisconnectedModeEnabled = false; + intervalCheckTime = -1; + + QTest::newRow("auto-insert missing nodes in the tree (reverse order)") + << expectedCollections << scenario << callNames + << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime + << QChar('/'); + + expectedCollections.clear(); + expectedCollections << createRootCollection() + << createCollection("/", "INBOX") + << createCollection("/", "INBOX/Calendar") + << createCollection("/", "INBOX/Calendar/Private"); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 LIST \"\" *" + << "S: * LIST ( ) / INBOX/Unsubscribed" + << "S: * LIST ( ) / INBOX/Calendar" + << "S: * LIST ( ) / INBOX/Calendar/Private" + << "S: * LIST ( \\HasChildren ) / INBOX" + << "S: A000003 OK list done" + << "C: A000004 LSUB \"\" *" + << "S: * LSUB ( \\HasChildren ) / INBOX" + << "S: * LSUB ( ) / INBOX/SubscribedButNotExisting" + << "S: * LSUB ( ) / INBOX/Calendar" + << "S: * LSUB ( ) / INBOX/Calendar/Private" + << "S: A000004 OK list done"; + + callNames.clear(); + callNames << "setIdleCollection" << "collectionsRetrieved"; + + isSubscriptionEnabled = true; + isDisconnectedModeEnabled = false; + intervalCheckTime = -1; + + QTest::newRow("subscription enabled") << expectedCollections << scenario << callNames + << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime + << QChar('/'); + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 LIST \"\" *" + << "S: * LIST ( ) / INBOX/Unsubscribed" + << "S: * LIST ( ) / INBOX/Calendar" + << "S: * LIST ( ) / INBOX/Calendar/Private" + << "S: * LIST ( \\HasChildren ) / INBOX" + << "S: A000003 OK list done" + << "C: A000004 LSUB \"\" *" + << "S: * LSUB ( \\HasChildren ) / Inbox" + << "S: * LSUB ( ) / Inbox/SubscribedButNotExisting" + << "S: * LSUB ( ) / Inbox/Calendar" + << "S: * LSUB ( ) / Inbox/Calendar/Private" + << "S: A000004 OK list done"; + + callNames.clear(); + callNames << "setIdleCollection" << "collectionsRetrieved"; + + isSubscriptionEnabled = true; + isDisconnectedModeEnabled = false; + intervalCheckTime = -1; + + QTest::newRow("subscription enabled, case insensitive inbox") << expectedCollections << scenario << callNames + << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime + << QChar('/'); + + expectedCollections.clear(); + expectedCollections << createRootCollection() + << createCollection("/", "INBOX", false, true) + << createCollection("/", "Archive"); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 LIST \"\" *" + << "S: * LIST ( \\Noinferiors ) / INBOX" + << "S: * LIST ( ) / Archive" + << "S: A000003 OK list done"; + + callNames.clear(); + callNames << "setIdleCollection" << "collectionsRetrieved"; + + isSubscriptionEnabled = false; + isDisconnectedModeEnabled = false; + intervalCheckTime = -1; + + QTest::newRow("Noinferiors") << expectedCollections << scenario << callNames + << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime + << QChar('/'); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 LIST \"\" *" + << "S: * LIST ( ) . INBOX" + << "S: * LIST ( ) . INBOX.Foo" + << "S: * LIST ( ) . INBOX.Bar" + << "S: A000003 OK list done"; + callNames.clear(); + callNames << "setIdleCollection" << "collectionsRetrieved"; + + expectedCollections.clear(); + expectedCollections << createRootCollection() + << createCollection(".", "INBOX") + << createCollection(".", "INBOX.Foo") + << createCollection(".", "INBOX.Bar"); + isSubscriptionEnabled = false; + isDisconnectedModeEnabled = false; + intervalCheckTime = -1; + + QTest::newRow("non-standard separators") << expectedCollections << scenario << callNames + << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime + << QChar('.'); + } + + void shouldListCollections() + { + QFETCH(Akonadi::Collection::List, expectedCollections); + QFETCH(QList, scenario); + QFETCH(QStringList, callNames); + QFETCH(bool, isSubscriptionEnabled); + QFETCH(bool, isDisconnectedModeEnabled); + QFETCH(int, intervalCheckTime); + QFETCH(QChar, separator); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(1); + + pool.setPasswordRequester(createDefaultRequester()); + QVERIFY(pool.connect(createDefaultAccount())); + QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int,QString)))); + + DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); + state->setResourceName("resource"); + state->setSubscriptionEnabled(isSubscriptionEnabled); + state->setDisconnectedModeEnabled(isDisconnectedModeEnabled); + state->setIntervalCheckTime(intervalCheckTime); + + RetrieveCollectionsTask *task = new RetrieveCollectionsTask(state); + task->start(&pool); + + Akonadi::Collection::List collections; + + QTRY_COMPARE(state->calls().count(), callNames.size()); + for (int i = 0; i < callNames.size(); i++) { + QString command = QString::fromUtf8(state->calls().at(i).first); + QVariant parameter = state->calls().at(i).second; + + if (command == "cancelTask" && callNames[i] != "cancelTask") { + qDebug() << "Got a cancel:" << parameter.toString(); + } + + QCOMPARE(command, callNames[i]); + + if (command == "cancelTask") { + QVERIFY(!parameter.toString().isEmpty()); + } else if (command == "collectionsRetrieved") { + collections += parameter.value(); + } + } + + QCOMPARE(state->separatorCharacter(), separator); + + QVERIFY(server.isAllScenarioDone()); + compareCollectionLists(collections, expectedCollections); + + server.quit(); + } + +private: + qint64 m_nextCollectionId; + + Akonadi::Collection createRootCollection(bool isDisconnectedImap = false, int intervalCheck = -1) + { + // Root + Akonadi::Collection collection = Akonadi::Collection(m_nextCollectionId++); + collection.setName("resource"); + collection.setRemoteId("root-id"); + collection.setContentMimeTypes(QStringList(Akonadi::Collection::mimeType())); + collection.setParentCollection(Akonadi::Collection::root()); + collection.addAttribute(new NoSelectAttribute(true)); + + Akonadi::CachePolicy policy; + policy.setInheritFromParent(false); + policy.setSyncOnDemand(true); + + if (isDisconnectedImap) { + policy.setLocalParts(QStringList() << Akonadi::MessagePart::Envelope + << Akonadi::MessagePart::Header + << Akonadi::MessagePart::Body); + policy.setCacheTimeout(-1); + } else { + policy.setLocalParts(QStringList() << Akonadi::MessagePart::Envelope + << Akonadi::MessagePart::Header); + policy.setCacheTimeout(60); + } + + policy.setIntervalCheckTime(intervalCheck); + + collection.setCachePolicy(policy); + + return collection; + } + + Akonadi::Collection createCollection(const QString &separator, const QString &path, bool isNoSelect = false, bool isNoInferiors = false) + { + // No path? That's the root of this resource then + if (path.isEmpty()) { + return createRootCollection(); + } + + QStringList pathParts = path.split(separator); + + const QString pathPart = pathParts.takeLast(); + const QString parentPath = pathParts.join(separator); + + // Here we should likely reuse already produced collections if possible to be 100% accurate + // but in the tests we check only a limited amount of properties (namely remote id and name). + const Akonadi::Collection parentCollection = createCollection(separator, parentPath); + + Akonadi::Collection collection(m_nextCollectionId++); + collection.setName(pathPart); + collection.setRemoteId(separator + pathPart); + + collection.setParentCollection(parentCollection); + collection.setContentMimeTypes(QStringList() << "message/rfc822" << Akonadi::Collection::mimeType()); + + // If the folder is the Inbox, make some special settings. + if (pathPart.compare(QLatin1String("INBOX") , Qt::CaseInsensitive) == 0) { + Akonadi::EntityDisplayAttribute *attr = new Akonadi::EntityDisplayAttribute; + attr->setDisplayName(i18n("Inbox")); + attr->setIconName("mail-folder-inbox"); + collection.addAttribute(attr); + } + + // If the folder is the user top-level folder, mark it as well, even although it is not officially noted in the RFC + if ((pathPart.compare(QLatin1String("user") , Qt::CaseInsensitive) == 0) && isNoSelect) { + Akonadi::EntityDisplayAttribute *attr = new Akonadi::EntityDisplayAttribute; + attr->setDisplayName(i18n("Shared Folders")); + attr->setIconName("x-mail-distribution-list"); + collection.addAttribute(attr); + } + + // If this folder is a noselect folder, make some special settings. + if (isNoSelect) { + collection.addAttribute(new NoSelectAttribute(true)); + collection.setContentMimeTypes(QStringList() << Akonadi::Collection::mimeType()); + collection.setRights(Akonadi::Collection::ReadOnly); + } + + if (isNoInferiors) { + collection.addAttribute(new NoInferiorsAttribute(true)); + collection.setRights(collection.rights() & ~Akonadi::Collection::CanCreateCollection); + } + + return collection; + } + + void compareCollectionLists(const Akonadi::Collection::List &resultList, + const Akonadi::Collection::List &expectedList) + { + for (int i = 0; i < expectedList.size(); i++) { + Akonadi::Collection expected = expectedList[i]; + bool found = false; + + for (int j = 0; j < resultList.size(); j++) { + Akonadi::Collection result = resultList[j]; + + if (result.remoteId() == expected.remoteId()) { + found = true; + + QVERIFY(!result.name().isEmpty()); + + QCOMPARE(result.name(), expected.name()); + QCOMPARE(result.contentMimeTypes(), expected.contentMimeTypes()); + QCOMPARE(result.rights(), expected.rights()); + if (expected.parentCollection() == Akonadi::Collection::root()) { + QCOMPARE(result.parentCollection(), expected.parentCollection()); + } else { + QCOMPARE(result.parentCollection().remoteId(), expected.parentCollection().remoteId()); + } + + QCOMPARE(result.cachePolicy().inheritFromParent(), expected.cachePolicy().inheritFromParent()); + QCOMPARE(result.cachePolicy().syncOnDemand(), expected.cachePolicy().syncOnDemand()); + QCOMPARE(result.cachePolicy().localParts(), expected.cachePolicy().localParts()); + QCOMPARE(result.cachePolicy().cacheTimeout(), expected.cachePolicy().cacheTimeout()); + QCOMPARE(result.cachePolicy().intervalCheckTime(), expected.cachePolicy().intervalCheckTime()); + + QCOMPARE(result.hasAttribute(), expected.hasAttribute()); + QCOMPARE(result.hasAttribute(), expected.hasAttribute()); + + break; + } + } + + QVERIFY2(found, QString::fromLatin1("%1 not found!").arg(expected.remoteId()).toUtf8().constData()); + } + + QCOMPARE(resultList.size(), expectedList.size()); + } +}; + +QTEST_GUILESS_MAIN(TestRetrieveCollectionsTask) + +#include "testretrievecollectionstask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/testretrieveitemstask.cpp kdepim-runtime-15.08.0/resources/imap/autotests/testretrieveitemstask.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/testretrieveitemstask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/testretrieveitemstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,611 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" + +#include "retrieveitemstask.h" +#include "uidnextattribute.h" +#include +#include + +#include +#include +#include + +class TestRetrieveItemsTask : public ImapTestBase +{ + Q_OBJECT + +private Q_SLOTS: + void shouldIntrospectCollection_data() + { + QTest::addColumn("collection"); + QTest::addColumn< QList >("scenario"); + QTest::addColumn("callNames"); + + Akonadi::Collection collection; + QList scenario; + QStringList callNames; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 EXPUNGE" + << "S: A000004 OK expunge done" + << "C: A000005 SELECT \"INBOX/Foo\"" + << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" + << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" + << "S: * 1 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UIDVALIDITY 1149151135 ]" + << "S: * OK [ UIDNEXT 9 ]" + << "S: A000005 OK select done" + << "C: A000006 UID SEARCH UID 1:9" + << "S: * SEARCH 1 2 3 4 5 6 7 8 9" + << "S: A000006 OK search done" + << "C: A000007 UID FETCH 1:9 (RFC822.SIZE INTERNALDATE " + "BODY.PEEK[HEADER] " + "FLAGS UID)" + << "S: * 1 FETCH ( FLAGS (\\Seen) UID 7 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " + "RFC822.SIZE 75 BODY[HEADER] {69}\r\n" + "From: Foo \r\n" + "To: Bar \r\n" + "Subject: Test Mail\r\n" + "\r\n" + " )" + << "S: A000007 OK fetch done"; + + callNames.clear(); + callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone" ; + + QTest::newRow("first listing, connected IMAP") << collection << scenario << callNames; + + Akonadi::CachePolicy policy; + policy.setLocalParts(QStringList() << Akonadi::MessagePart::Envelope + << Akonadi::MessagePart::Header + << Akonadi::MessagePart::Body); + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); + collection.setCachePolicy(policy); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 EXPUNGE" + << "S: A000004 OK expunge done" + << "C: A000005 SELECT \"INBOX/Foo\"" + << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" + << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" + << "S: * 1 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UIDVALIDITY 1149151135 ]" + << "S: * OK [ UIDNEXT 9 ]" + << "S: A000005 OK select done" + << "C: A000006 UID SEARCH UID 1:9" + << "S: * SEARCH 1 2 3 4 5 6 7 8 9" + << "S: A000006 OK search done" + << "C: A000007 UID FETCH 1:9 (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)" + << "S: * 1 FETCH ( FLAGS (\\Seen) UID 7 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " + "RFC822.SIZE 75 BODY[] {75}\r\n" + "From: Foo \r\n" + "To: Bar \r\n" + "Subject: Test Mail\r\n" + "\r\n" + "Test\r\n" + " )" + << "S: A000007 OK fetch done"; + + callNames.clear(); + callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone"; + + QTest::newRow("first listing, disconnected IMAP") << collection << scenario << callNames; + + Akonadi::CollectionStatistics stats; + stats.setCount(1); + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); + collection.attribute(Akonadi::Collection::AddIfMissing)->setUidNext(9); + collection.setCachePolicy(policy); + collection.setStatistics(stats); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 EXPUNGE" + << "S: A000004 OK expunge done" + << "C: A000005 SELECT \"INBOX/Foo\"" + << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" + << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" + << "S: * 1 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UIDVALIDITY 1149151135 ]" + << "S: * OK [ UIDNEXT 9 ]" + << "S: A000005 OK select done" + << "C: A000006 UID SEARCH UID 1:9" + << "S: * SEARCH 1 2 3 4 5 6 7 8 9" + << "S: A000006 OK search done" + << "C: A000007 UID FETCH 1:9 (FLAGS UID)" + << "S: * 1 FETCH ( FLAGS (\\Seen) UID 7 )" + << "S: A000007 OK fetch done"; + + callNames.clear(); + callNames << "itemsRetrievedIncremental" << "applyCollectionChanges" << "itemsRetrievedIncremental" << "itemsRetrievalDone"; + + //Disabled test since the flag sync is disabled if CONDSTORE is not supported +// QTest::newRow( "second listing, checking for flag changes" ) << collection << scenario << callNames; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); + collection.setCachePolicy(policy); + stats.setCount(1); + collection.setStatistics(stats); + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 EXPUNGE" + << "S: A000004 OK expunge done" + << "C: A000005 SELECT \"INBOX/Foo\"" + << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" + << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" + << "S: * 0 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UIDVALIDITY 1149151135 ]" + << "S: * OK [ UIDNEXT 9 ]" + << "S: A000005 OK select done"; + + callNames.clear(); + callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone"; + + QTest::newRow("third listing, full sync, empty folder") << collection << scenario << callNames; + + collection.attribute(Akonadi::Collection::AddIfMissing)->setUidNext(8); + stats.setCount(4); + collection.setStatistics(stats); + collection.attribute(Akonadi::Entity::AddIfMissing)->setHighestModSeq(123456788); + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 EXPUNGE" + << "S: A000004 OK expunge done" + << "C: A000005 SELECT \"INBOX/Foo\"" + << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" + << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" + << "S: * 5 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UIDVALIDITY 1149151135 ]" + << "S: * OK [ UIDNEXT 9 ]" + << "S: * OK [ HIGHESTMODSEQ 123456789 ]" + << "S: A000005 OK select done" + << "C: A000006 UID SEARCH UID 8:9" + << "S: * SEARCH 8 9" + << "S: A000006 OK search done" + << "C: A000007 UID FETCH 8:9 (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)" + << "S: * 5 FETCH ( FLAGS (\\Seen) UID 9 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " + "RFC822.SIZE 75 BODY[] {75}\r\n" + "From: Foo \r\n" + "To: Bar \r\n" + "Subject: Test Mail\r\n" + "\r\n" + "Test\r\n" + " )" + << "S: A000007 OK fetch done" + << "C: A000008 UID SEARCH UID 1:7" + << "S: * SEARCH 1 2 3 4 5 6 7" + << "S: A000008 OK search done" + << "C: A000009 UID FETCH 1:7 (FLAGS UID)" + << "S: * 1 FETCH" + << "S: * 2 FETCH" + << "S: * 3 FETCH" + << "S: * 4 FETCH" + << "S: A000009 OK fetch done"; + + callNames.clear(); + callNames << "itemsRetrievedIncremental" << "applyCollectionChanges" << "itemsRetrievedIncremental" << "itemsRetrievalDone"; + + //We know no messages have been removed, so we can do an incremental update + QTest::newRow("uidnext changed, fetch new messages incrementally") << collection << scenario << callNames; + + collection.attribute(Akonadi::Collection::AddIfMissing)->setUidNext(8); + stats.setCount(5); + collection.setStatistics(stats); + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 EXPUNGE" + << "S: A000004 OK expunge done" + << "C: A000005 SELECT \"INBOX/Foo\"" + << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" + << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" + << "S: * 5 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UIDVALIDITY 1149151135 ]" + << "S: * OK [ UIDNEXT 9 ]" + << "S: * OK [ HIGHESTMODSEQ 123456789 ]" + << "S: A000005 OK select done" + << "C: A000006 UID SEARCH UID 8:9" + << "S: * SEARCH 8 9" + << "S: A000006 OK search done" + << "C: A000007 UID FETCH 8:9 (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)" + << "S: * 4 FETCH ( FLAGS (\\Seen) UID 8 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " + "RFC822.SIZE 75 BODY[] {75}\r\n" + "From: Foo \r\n" + "To: Bar \r\n" + "Subject: Test Mail\r\n" + "\r\n" + "Test\r\n" + " )" + << "S: * 5 FETCH ( FLAGS (\\Seen) UID 9 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " + "RFC822.SIZE 75 BODY[] {75}\r\n" + "From: Foo \r\n" + "To: Bar \r\n" + "Subject: Test Mail\r\n" + "\r\n" + "Test\r\n" + " )" + << "S: A000007 OK fetch done" + << "C: A000008 UID SEARCH UID 1:7" + << "S: * SEARCH 1 2 3 4 5 6 7" + << "S: A000008 OK search done" + << "C: A000009 UID FETCH 1:7 (FLAGS UID)" + << "S: * 1 FETCH" + << "S: * 2 FETCH" + << "S: * 3 FETCH" + << "S: A000009 OK fetch done"; + + callNames.clear(); + callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone"; + + //A new message has been added and an old one removed, we can't do an incremental update + QTest::newRow("uidnext changed, fetch new messages and list flags") << collection << scenario << callNames; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); + collection.setCachePolicy(policy); + collection.attribute(Akonadi::Collection::AddIfMissing)->setUidNext(9); + collection.attribute(Akonadi::Entity::AddIfMissing)->setHighestModSeq(123456789); + stats.setCount(5); + collection.setStatistics(stats); + scenario.clear(); + scenario << defaultPoolConnectionScenario(QList() << "CONDSTORE") + << "C: A000003 SELECT \"INBOX/Foo\" (CONDSTORE)" + << "S: A000003 OK select done" + << "C: A000004 EXPUNGE" + << "S: A000004 OK expunge DONE" + << "C: A000005 SELECT \"INBOX/Foo\" (CONDSTORE)" + << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" + << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" + << "S: * 5 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UIDVALIDITY 1149151135 ]" + << "S: * OK [ UIDNEXT 9 ]" + << "S: * OK [ HIGHESTMODSEQ 123456789 ]" + << "S: A000005 OK select done"; + callNames.clear(); + callNames << "applyCollectionChanges" << "itemsRetrievedIncremental" << "itemsRetrievalDone"; + + //No flags have changed + QTest::newRow("highestmodseq test") << collection << scenario << callNames; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); + collection.setCachePolicy(policy); + collection.attribute(Akonadi::Collection::AddIfMissing)->setUidNext(9); + collection.attribute(Akonadi::Entity::AddIfMissing)->setHighestModSeq(123456788); + stats.setCount(5); + collection.setStatistics(stats); + scenario.clear(); + scenario << defaultPoolConnectionScenario(QList() << "CONDSTORE") + << "C: A000003 SELECT \"INBOX/Foo\" (CONDSTORE)" + << "S: A000003 OK select done" + << "C: A000004 EXPUNGE" + << "S: A000004 OK expunge DONE" + << "C: A000005 SELECT \"INBOX/Foo\" (CONDSTORE)" + << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" + << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" + << "S: * 5 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UIDVALIDITY 1149151135 ]" + << "S: * OK [ UIDNEXT 9 ]" + << "S: * OK [ HIGHESTMODSEQ 123456789 ]" + << "S: A000005 OK select done" + << "C: A000006 UID FETCH 1:9 (FLAGS UID) (CHANGEDSINCE 123456788)" + << "S: * 5 FETCH ( UID 8 FLAGS () )" + << "S: A000006 OK fetch done"; + callNames.clear(); + callNames << "itemsRetrievedIncremental" << "applyCollectionChanges" << "itemsRetrievedIncremental" << "itemsRetrievalDone"; + + //fetch only changed flags + QTest::newRow("changedsince test") << collection << scenario << callNames; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.setCachePolicy(policy); + collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); + collection.attribute(Akonadi::Collection::AddIfMissing)->setUidNext(9); + collection.attribute(Akonadi::Entity::AddIfMissing)->setHighestModSeq(123456788); + stats.setCount(5); + collection.setStatistics(stats); + scenario.clear(); + scenario << defaultPoolConnectionScenario(QList() << "XYMHIGHESTMODSEQ") + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 EXPUNGE" + << "S: A000004 OK expunge DONE" + << "C: A000005 SELECT \"INBOX/Foo\"" + << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" + << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" + << "S: * 5 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UIDVALIDITY 1149151135 ]" + << "S: * OK [ UIDNEXT 9 ]" + << "S: * OK [ HIGHESTMODSEQ 123456789 ]" + << "S: A000005 OK select done"; + //Disabled since the flag sync is disabled if CONDSTORE is not supported +// << "C: A000006 UID SEARCH UID 1:9" +// << "S: * SEARCH 1 2 3 4 5 6 7 8 9" +// << "S: A000006 OK search done" +// << "C: A000007 UID FETCH 1:9 (FLAGS UID)" +// << "S: * 5 FETCH ( UID 8 FLAGS () )" +// << "S: A000007 OK fetch done"; + callNames.clear(); + + //Disabled since the flag sync is disabled if CONDSTORE is not supported + callNames << /*"itemsRetrievedIncremental" << */"applyCollectionChanges" << "itemsRetrievedIncremental" << "itemsRetrievalDone"; + + //Don't rely on yahoos highestmodseq implementation + QTest::newRow("yahoo highestmodseq test") << collection << scenario << callNames; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.attribute(Akonadi::Collection::AddIfMissing)->setUidNext(9); + collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(3); + collection.setCachePolicy(policy); + stats.setCount(1); + collection.setStatistics(stats); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 EXPUNGE" + << "S: A000004 OK expunge done" + << "C: A000005 SELECT \"INBOX/Foo\"" + << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" + << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" + << "S: * 1 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UIDVALIDITY 1149151135 ]" + << "S: * OK [ UIDNEXT 9 ]" + << "S: A000005 OK select done" + << "C: A000006 UID SEARCH UID 1:4294967295" + << "S: * SEARCH 1 2 3 4 5 6 7 8 9" + << "S: A000006 OK search done" + << "C: A000007 UID FETCH 1:9 (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)" + << "S: * 1 FETCH ( FLAGS (\\Seen) UID 2321 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " + "RFC822.SIZE 75 BODY[] {75}\r\n" + "From: Foo \r\n" + "To: Bar \r\n" + "Subject: Test Mail\r\n" + "\r\n" + "Test\r\n" + " )" + << "S: A000007 OK fetch done"; + + callNames.clear(); + callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone"; + + QTest::newRow("uidvalidity changed") << collection << scenario << callNames; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.attribute(Akonadi::Collection::AddIfMissing)->setUidNext(105); + collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); + collection.setCachePolicy(policy); + stats.setCount(104); + collection.setStatistics(stats); + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 EXPUNGE" + << "S: A000004 OK expunge done" + << "C: A000005 SELECT \"INBOX/Foo\"" + << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" + << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" + << "S: * 119 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UIDVALIDITY 1149151135 ]" + << "S: * OK [ UIDNEXT 120 ]" + << "S: A000005 OK select done" + << "C: A000006 UID SEARCH UID 105:120" + //We asked for until 120 but only 119 is available (120 is uidnext) + << "S: * SEARCH 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119" + << "S: A000006 OK search done" + << "C: A000007 UID FETCH 105:114 (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)" + << "S: * 1 FETCH ( FLAGS (\\Seen) UID 105 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " + "RFC822.SIZE 75 BODY[] {75}\r\n" + "From: Foo \r\n" + "To: Bar \r\n" + "Subject: Test Mail\r\n" + "\r\n" + "Test\r\n" + " )" + //9 more would follow but are excluded for clarity + << "S: A000007 OK fetch done" + << "C: A000008 UID FETCH 115:119 (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)" + << "S: * 1 FETCH ( FLAGS (\\Seen) UID 115 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " + "RFC822.SIZE 75 BODY[] {75}\r\n" + "From: Foo \r\n" + "To: Bar \r\n" + "Subject: Test Mail\r\n" + "\r\n" + "Test\r\n" + " )" + //4 more would follow but are excluded for clarity + << "S: A000008 OK fetch done" + << "C: A000009 UID SEARCH UID 1:104" + << "S: * SEARCH 1 2 99 100" + << "S: A000009 OK search done" + << "C: A000010 UID FETCH 1:2,99:100 (FLAGS UID)" + << "S: * 1 FETCH ( FLAGS (\\Seen) UID 1 )" + //3 more would follow but are excluded for clarity + << "S: A000010 OK fetch done"; + + callNames.clear(); + callNames << "itemsRetrievedIncremental" << "itemsRetrievedIncremental" << "itemsRetrievedIncremental" << "applyCollectionChanges" << "itemsRetrievedIncremental" << "itemsRetrievalDone"; + + QTest::newRow("test batch processing") << collection << scenario << callNames; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); + collection.setCachePolicy(policy); + collection.attribute(Akonadi::Collection::AddIfMissing)->setUidNext(9); + collection.attribute(Akonadi::Entity::AddIfMissing)->setHighestModSeq(123456789); + stats.setCount(5); + collection.setStatistics(stats); + scenario.clear(); + scenario << defaultPoolConnectionScenario(QList() << "CONDSTORE") + << "C: A000003 SELECT \"INBOX/Foo\" (CONDSTORE)" + << "S: A000003 OK select done" + << "C: A000004 EXPUNGE" + << "S: A000004 OK expunge DONE" + << "C: A000005 SELECT \"INBOX/Foo\" (CONDSTORE)" + << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" + << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" + << "S: * 4 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UIDVALIDITY 1149151135 ]" + << "S: * OK [ UIDNEXT 9 ]" + << "S: * OK [ HIGHESTMODSEQ 123456789 ]" + << "S: A000005 OK select done" + << "C: A000006 UID SEARCH UID 1:9" + << "S: * SEARCH 1 2 3 4" + << "S: A000006 OK search done" + << "C: A000007 UID FETCH 1:4 (FLAGS UID)" + << "S: * 1 FETCH ( FLAGS (\\Seen) UID 1 )" + << "S: * 2 FETCH ( FLAGS (\\Seen) UID 2 )" + << "S: * 3 FETCH ( FLAGS (\\Seen) UID 3 )" + << "S: * 4 FETCH ( FLAGS (\\Seen) UID 4 )" + << "S: A000007 OK fetch done"; + callNames.clear(); + callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone"; + + //fetch only changed flags + QTest::newRow("remote message deleted") << collection << scenario << callNames; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); + collection.setCachePolicy(policy); + collection.attribute(Akonadi::Collection::AddIfMissing)->setUidNext(-1); + collection.attribute(Akonadi::Entity::AddIfMissing)->setHighestModSeq(123456789); + stats.setCount(0); + collection.setStatistics(stats); + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 EXPUNGE" + << "S: A000004 OK expunge done" + << "C: A000005 SELECT \"INBOX/Foo\"" + << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" + << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" + << "S: * 1 EXISTS" + << "S: * 0 RECENT" + << "S: * OK [ UIDVALIDITY 1149151135 ]" + << "S: A000005 OK select done" + << "C: A000006 UID SEARCH UID 1:4294967295" + << "S: * SEARCH 1 2 3 4 5 6 7 8 9" + << "S: A000006 OK search done" + << "C: A000007 UID FETCH 1:9 (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)" + << "S: * 1 FETCH ( FLAGS (\\Seen) UID 2321 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " + "RFC822.SIZE 75 BODY[] {75}\r\n" + "From: Foo \r\n" + "To: Bar \r\n" + "Subject: Test Mail\r\n" + "\r\n" + "Test\r\n" + " )" + << "S: A000007 OK fetch done"; + + callNames.clear(); + callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone" ; + + QTest::newRow("missing uidnext") << collection << scenario << callNames; + + } + + void shouldIntrospectCollection() + { + QFETCH(Akonadi::Collection, collection); + QFETCH(QList, scenario); + QFETCH(QStringList, callNames); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(1); + + pool.setPasswordRequester(createDefaultRequester()); + QVERIFY(pool.connect(createDefaultAccount())); + QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int,QString)))); + + DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); + state->setServerCapabilities(pool.serverCapabilities()); + state->setCollection(collection); + + RetrieveItemsTask *task = new RetrieveItemsTask(state); + task->setFetchMissingItemBodies(false); + task->start(&pool); + + QTRY_COMPARE(state->calls().count(), callNames.size()); + qDebug() << state->calls(); + for (int i = 0; i < callNames.size(); i++) { + QString command = QString::fromUtf8(state->calls().at(i).first); + QVariant parameter = state->calls().at(i).second; + + if (command == "cancelTask" && callNames[i] != "cancelTask") { + qDebug() << "Got a cancel:" << parameter.toString(); + } + + QCOMPARE(command, callNames[i]); + + if (command == "cancelTask") { + QVERIFY(!parameter.toString().isEmpty()); + } + } + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } +}; + +QTEST_GUILESS_MAIN(TestRetrieveItemsTask) + +#include "testretrieveitemstask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/testretrieveitemtask.cpp kdepim-runtime-15.08.0/resources/imap/autotests/testretrieveitemtask.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/testretrieveitemtask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/testretrieveitemtask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,126 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" + +#include "retrieveitemtask.h" + +class TestRetrieveItemTask : public ImapTestBase +{ + Q_OBJECT + +private Q_SLOTS: + void shouldFetchMessage_data() + { + QTest::addColumn("item"); + QTest::addColumn("message"); + QTest::addColumn< QList >("scenario"); + QTest::addColumn("callName"); + + Akonadi::Collection collection; + Akonadi::Item item; + QString message; + QList scenario; + + collection = createCollectionChain(QLatin1String("/INBOX/Foo")); + item = Akonadi::Item(2); + item.setParentCollection(collection); + item.setRemoteId("42"); + + message = "From: ervin\nTo: someone\nSubject: foo\n\nSpeechless..."; + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 UID FETCH 42 (BODY.PEEK[] UID)" + << "S: * 10 FETCH (UID 42 BODY[] \"From: ervin\nTo: someone\nSubject: foo\n\nSpeechless...\")" + << "S: A000004 OK fetch done"; + QTest::newRow("normal case") << item << message << scenario << "itemRetrieved"; + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 NO select fail"; + QTest::newRow("select fail") << item << message << scenario << "cancelTask"; + + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"INBOX/Foo\"" + << "S: A000003 OK select done" + << "C: A000004 UID FETCH 42 (BODY.PEEK[] UID)" + << "S: A000004 NO fetch failed"; + QTest::newRow("fetch fail") << item << message << scenario << "cancelTask"; + } + + void shouldFetchMessage() + { + QFETCH(Akonadi::Item, item); + QFETCH(QString, message); + QFETCH(QList, scenario); + QFETCH(QString, callName); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(1); + + pool.setPasswordRequester(createDefaultRequester()); + QVERIFY(pool.connect(createDefaultAccount())); + QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int,QString)))); + + DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); + state->setItem(item); + RetrieveItemTask *task = new RetrieveItemTask(state); + task->start(&pool); + + QTRY_COMPARE(state->calls().count(), 1); + + QString command = QString::fromUtf8(state->calls().first().first); + if (command == "cancelTask" && callName != "cancelTask") { + qDebug() << "Got a cancel:" << state->calls().first().second.toString(); + } + QCOMPARE(command, callName); + + QVariant parameter = state->calls().first().second; + + if (callName == "itemRetrieved") { + QCOMPARE(parameter.value().id(), item.id()); + QCOMPARE(parameter.value().remoteId(), item.remoteId()); + + QString payload = parameter.value().payload()->encodedContent(); + + QCOMPARE(payload, message); + + } else if (callName == "cancelTask") { + QVERIFY(!parameter.toString().isEmpty()); + } else { + QFAIL(QString("Unexpected call type: %1").arg(callName).toUtf8().constData()); + } + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } +}; + +QTEST_GUILESS_MAIN(TestRetrieveItemTask) + +#include "testretrieveitemtask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/autotests/testsessionpool.cpp kdepim-runtime-15.08.0/resources/imap/autotests/testsessionpool.cpp --- kdepim-runtime-4.14.6/resources/imap/autotests/testsessionpool.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/autotests/testsessionpool.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,780 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" +#include +#include + +class TestSessionPool : public ImapTestBase +{ + Q_OBJECT + +private Q_SLOTS: + void shouldPrepareFirstSessionOnConnect_data() + { + QTest::addColumn("account"); + QTest::addColumn("requester"); + QTest::addColumn< QList >("scenario"); + QTest::addColumn("password"); + QTest::addColumn("errorCode"); + QTest::addColumn("capabilities"); + + ImapAccount *account = 0; + DummyPasswordRequester *requester = 0; + QList scenario; + QString password; + QStringList capabilities; + + account = createDefaultAccount(); + requester = createDefaultRequester(); + scenario.clear(); + scenario << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in" + << "C: A000002 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 NAMESPACE UIDPLUS IDLE" + << "S: A000002 OK Completed" + << "C: A000003 NAMESPACE" + << "S: * NAMESPACE ( (\"INBOX/\" \"/\") ) ( (\"user/\" \"/\") ) ( (\"\" \"/\") )" + << "S: A000003 OK Completed"; + password = "foobar"; + int errorCode = SessionPool::NoError; + capabilities.clear(); + capabilities << "IMAP4" << "IMAP4REV1" << "NAMESPACE" << "UIDPLUS" << "IDLE"; + QTest::newRow("normal case") << account << requester << scenario + << password << errorCode << capabilities; + + account = createDefaultAccount(); + requester = createDefaultRequester(); + scenario.clear(); + scenario << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in" + << "C: A000002 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" + << "S: A000002 OK Completed"; + password = "foobar"; + errorCode = SessionPool::NoError; + capabilities.clear(); + capabilities << "IMAP4" << "IMAP4REV1" << "UIDPLUS" << "IDLE"; + QTest::newRow("no NAMESPACE support") << account << requester << scenario + << password << errorCode << capabilities; + + account = createDefaultAccount(); + requester = createDefaultRequester(); + scenario.clear(); + scenario << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in" + << "C: A000002 CAPABILITY" + << "S: * CAPABILITY IMAP4 IDLE" + << "S: A000002 OK Completed" + << "C: A000003 LOGOUT"; + password = "foobar"; + errorCode = SessionPool::IncompatibleServerError; + capabilities.clear(); + QTest::newRow("incompatible server") << account << requester << scenario + << password << errorCode << capabilities; + + QList requests; + QList results; + + account = createDefaultAccount(); + requester = createDefaultRequester(); + requests.clear(); + results.clear(); + requests << DummyPasswordRequester::StandardRequest << DummyPasswordRequester::WrongPasswordRequest; + results << DummyPasswordRequester::PasswordRetrieved << DummyPasswordRequester::UserRejected; + requester->setScenario(requests, results); + scenario.clear(); + scenario << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 NO Login failed" + << "C: A000002 LOGOUT"; + password = "foobar"; + errorCode = SessionPool::LoginFailError; + capabilities.clear(); + QTest::newRow("login fail, user reject password entry") << account << requester << scenario + << password << errorCode << capabilities; + + account = createDefaultAccount(); + requester = createDefaultRequester(); + requests.clear(); + results.clear(); + requests << DummyPasswordRequester::StandardRequest << DummyPasswordRequester::WrongPasswordRequest; + results << DummyPasswordRequester::PasswordRetrieved << DummyPasswordRequester::PasswordRetrieved; + requester->setScenario(requests, results); + scenario.clear(); + scenario << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 NO Login failed" + << "C: A000002 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000002 OK Login succeeded" + << "C: A000003 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" + << "S: A000003 OK Completed"; + password = "foobar"; + errorCode = SessionPool::NoError; + capabilities.clear(); + capabilities << "IMAP4" << "IMAP4REV1" << "UIDPLUS" << "IDLE"; + QTest::newRow("login fail, user provide new password") << account << requester << scenario + << password << errorCode << capabilities; + + account = createDefaultAccount(); + requester = createDefaultRequester(); + requests.clear(); + results.clear(); + requests << DummyPasswordRequester::StandardRequest << DummyPasswordRequester::WrongPasswordRequest; + results << DummyPasswordRequester::PasswordRetrieved << DummyPasswordRequester::EmptyPasswordEntered; + requester->setScenario(requests, results); + scenario.clear(); + scenario << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 NO Login failed" + << "C: A000002 LOGOUT"; + password = "foobar"; + errorCode = SessionPool::LoginFailError; + capabilities.clear(); + QTest::newRow("login fail, user provided empty password") << account << requester << scenario + << password << errorCode << capabilities; + + account = createDefaultAccount(); + requester = createDefaultRequester(); + requests.clear(); + results.clear(); + requests << DummyPasswordRequester::StandardRequest << DummyPasswordRequester::WrongPasswordRequest; + results << DummyPasswordRequester::PasswordRetrieved << DummyPasswordRequester::ReconnectNeeded; + requester->setScenario(requests, results); + scenario.clear(); + scenario << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 NO Login failed" + << "C: A000002 LOGOUT"; + password = "foobar"; + errorCode = SessionPool::ReconnectNeededError; + capabilities.clear(); + QTest::newRow("login fail, user change the settings") << account << requester << scenario + << password << errorCode << capabilities; + } + + void shouldPrepareFirstSessionOnConnect() + { + QFETCH(ImapAccount *, account); + QFETCH(DummyPasswordRequester *, requester); + QFETCH(QList, scenario); + QFETCH(QString, password); + QFETCH(int, errorCode); + QFETCH(QStringList, capabilities); + + QSignalSpy requesterSpy(requester, SIGNAL(done(int,QString))); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(2); + + QVERIFY(!pool.isConnected()); + + QSignalSpy poolSpy(&pool, SIGNAL(connectDone(int,QString))); + + pool.setPasswordRequester(requester); + QVERIFY(pool.connect(account)); + + QTest::qWait(200); + QVERIFY(requesterSpy.count() > 0); + if (requesterSpy.count() == 1) { + QCOMPARE(requesterSpy.at(0).at(0).toInt(), 0); + QCOMPARE(requesterSpy.at(0).at(1).toString(), password); + } + + QCOMPARE(poolSpy.count(), 1); + QCOMPARE(poolSpy.at(0).at(0).toInt(), errorCode); + if (errorCode == SessionPool::NoError) { + QVERIFY(pool.isConnected()); + } else { + QVERIFY(!pool.isConnected()); + } + + QCOMPARE(pool.serverCapabilities(), capabilities); + QVERIFY(pool.serverNamespaces().isEmpty()); + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } + + void shouldManageSeveralSessions() + { + FakeServer server; + server.addScenario(QList() + << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in" + << "C: A000002 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 NAMESPACE UIDPLUS IDLE" + << "S: A000002 OK Completed" + << "C: A000003 NAMESPACE" + << "S: * NAMESPACE ( (\"INBOX/\" \"/\") ) ( (\"user/\" \"/\") ) ( (\"\" \"/\") )" + << "S: A000003 OK Completed" + ); + + server.addScenario(QList() + << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in" + ); + + server.startAndWait(); + + ImapAccount *account = createDefaultAccount(); + DummyPasswordRequester *requester = createDefaultRequester(); + + QSignalSpy requesterSpy(requester, SIGNAL(done(int,QString))); + + SessionPool pool(2); + pool.setPasswordRequester(requester); + + QSignalSpy connectSpy(&pool, SIGNAL(connectDone(int,QString))); + QSignalSpy sessionSpy(&pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString))); + + // Before connect we can't get any session + qint64 requestId = pool.requestSession(); + QCOMPARE(requestId, qint64(-1)); + + // Initial connect should trigger only a password request and a connect + QVERIFY(pool.connect(account)); + QTest::qWait(100); + QCOMPARE(requesterSpy.count(), 1); + QCOMPARE(connectSpy.count(), 1); + QCOMPARE(sessionSpy.count(), 0); + + // Requesting a first session shouldn't create a new one, + // only sessionRequestDone is emitted right away + requestId = pool.requestSession(); + QCOMPARE(requestId, qint64(1)); + QTest::qWait(100); + QCOMPARE(requesterSpy.count(), 1); + QCOMPARE(connectSpy.count(), 1); + QCOMPARE(sessionSpy.count(), 1); + + QCOMPARE(sessionSpy.at(0).at(0).toLongLong(), requestId); + QVERIFY(sessionSpy.at(0).at(1).value() != 0); + QCOMPARE(sessionSpy.at(0).at(2).toInt(), 0); + QCOMPARE(sessionSpy.at(0).at(3).toString(), QString()); + + // Requesting an extra session should create a new one + // So for instance password will be requested + requestId = pool.requestSession(); + QCOMPARE(requestId, qint64(2)); + QTest::qWait(100); + QCOMPARE(requesterSpy.count(), 2); + QCOMPARE(connectSpy.count(), 1); + QCOMPARE(sessionSpy.count(), 2); + + QCOMPARE(sessionSpy.at(1).at(0).toLongLong(), requestId); + QVERIFY(sessionSpy.at(1).at(1).value() != 0); + // Should be different sessions... + QVERIFY(sessionSpy.at(0).at(1).value() != sessionSpy.at(1).at(1).value()); + QCOMPARE(sessionSpy.at(1).at(2).toInt(), 0); + QCOMPARE(sessionSpy.at(1).at(3).toString(), QString()); + + // Requesting yet another session should fail as we reached the + // maximum pool size, and they're all reserved + requestId = pool.requestSession(); + QCOMPARE(requestId, qint64(3)); + QTest::qWait(100); + QCOMPARE(requesterSpy.count(), 2); + QCOMPARE(connectSpy.count(), 1); + QCOMPARE(sessionSpy.count(), 3); + + QCOMPARE(sessionSpy.at(2).at(0).toLongLong(), requestId); + QVERIFY(sessionSpy.at(2).at(1).value() == 0); + QCOMPARE(sessionSpy.at(2).at(2).toInt(), (int)SessionPool::NoAvailableSessionError); + QVERIFY(!sessionSpy.at(2).at(3).toString().isEmpty()); + + // OTOH, if we release one now, and then request another one + // it should succeed without even creating a new session + KIMAP::Session *session = sessionSpy.at(0).at(1).value(); + pool.releaseSession(session); + requestId = pool.requestSession(); + QCOMPARE(requestId, qint64(4)); + QTest::qWait(100); + QCOMPARE(requesterSpy.count(), 2); + QCOMPARE(connectSpy.count(), 1); + QCOMPARE(sessionSpy.count(), 4); + + QCOMPARE(sessionSpy.at(3).at(0).toLongLong(), requestId); + // Only one session was available, so that should be the one we get gack + QVERIFY(sessionSpy.at(3).at(1).value() == session); + QCOMPARE(sessionSpy.at(3).at(2).toInt(), 0); + QCOMPARE(sessionSpy.at(3).at(3).toString(), QString()); + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } + + void shouldNotifyConnectionLost() + { + FakeServer server; + server.addScenario(QList() + << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in" + << "C: A000002 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" + << "S: A000002 OK Completed" + << "C: A000003 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" + << "X" + ); + + server.startAndWait(); + + ImapAccount *account = createDefaultAccount(); + DummyPasswordRequester *requester = createDefaultRequester(); + + SessionPool pool(1); + pool.setPasswordRequester(requester); + + QSignalSpy connectSpy(&pool, SIGNAL(connectDone(int,QString))); + QSignalSpy sessionSpy(&pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString))); + QSignalSpy lostSpy(&pool, SIGNAL(connectionLost(KIMAP::Session*))); + + // Initial connect should trigger only a password request and a connect + QVERIFY(pool.connect(account)); + QTest::qWait(100); + QCOMPARE(connectSpy.count(), 1); + QCOMPARE(sessionSpy.count(), 0); + + qint64 requestId = pool.requestSession(); + QTest::qWait(100); + QCOMPARE(sessionSpy.count(), 1); + + QCOMPARE(sessionSpy.at(0).at(0).toLongLong(), requestId); + KIMAP::Session *s = sessionSpy.at(0).at(1).value(); + + KIMAP::CapabilitiesJob *job = new KIMAP::CapabilitiesJob(s); + job->start(); + QTest::qWait(100); + QCOMPARE(lostSpy.count(), 1); + // FIXME extracting the pointer value form QVariant crashes + // QCOMPARE(lostSpy.at(0).at(0).value(), s); + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } + + void shouldNotifyOnDisconnect_data() + { + QTest::addColumn< QList >("scenario"); + QTest::addColumn("termination"); + + QList scenario; + + scenario.clear(); + scenario << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in" + << "C: A000002 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" + << "S: A000002 OK Completed" + << "C: A000003 LOGOUT"; + + QTest::newRow("logout session") << scenario << (int)SessionPool::LogoutSession; + + scenario.clear(); + scenario << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in" + << "C: A000002 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" + << "S: A000002 OK Completed"; + + QTest::newRow("close session") << scenario << (int)SessionPool::CloseSession; + } + + void shouldNotifyOnDisconnect() + { + QFETCH(QList, scenario); + QFETCH(int, termination); + + FakeServer server; + server.addScenario(scenario); + + server.startAndWait(); + + ImapAccount *account = createDefaultAccount(); + DummyPasswordRequester *requester = createDefaultRequester(); + + SessionPool pool(1); + pool.setPasswordRequester(requester); + + QSignalSpy disconnectSpy(&pool, SIGNAL(disconnectDone())); + + // Initial connect should trigger only a password request and a connect + QVERIFY(pool.connect(account)); + QTest::qWait(100); + + QCOMPARE(disconnectSpy.count(), 0); + pool.disconnect((SessionPool::SessionTermination) termination); + QTest::qWait(100); + QCOMPARE(disconnectSpy.count(), 1); + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } + + void shouldCleanupOnClosingDuringLogin_data() + { + QTest::addColumn< QList >("scenario"); + + { + QList scenario; + scenario << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\""; + + QTest::newRow("during login") << scenario; + } + { + QList scenario; + scenario << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in" + << "C: A000002 CAPABILITY"; + + QTest::newRow("during capability") << scenario; + } + { + QList scenario; + scenario << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in" + << "C: A000002 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 NAMESPACE UIDPLUS IDLE" + << "S: A000002 OK Completed" + << "C: A000003 NAMESPACE"; + QTest::newRow("during namespace") << scenario; + } + } + + void shouldCleanupOnClosingDuringLogin() + { + QFETCH(QList, scenario); + + FakeServer server; + server.addScenario(scenario); + + server.startAndWait(); + + ImapAccount *account = createDefaultAccount(); + DummyPasswordRequester *requester = createDefaultRequester(); + + SessionPool pool(1); + pool.setPasswordRequester(requester); + + QSignalSpy connectSpy(&pool, SIGNAL(connectDone(int,QString))); + QSignalSpy sessionSpy(&pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString))); + QSignalSpy lostSpy(&pool, SIGNAL(connectionLost(KIMAP::Session*))); + + // Initial connect should trigger only a password request and a connect + QVERIFY(pool.connect(account)); + QTest::qWait(100); + QCOMPARE(connectSpy.count(), 0); // Login not done yet + QWeakPointer session = qFindChild(&pool); + QVERIFY(session.data()); + QCOMPARE(sessionSpy.count(), 0); + + pool.disconnect(SessionPool::CloseSession); + + QTest::qWait(100); + QCOMPARE(connectSpy.count(), 1); // We're informed that connect failed + QCOMPARE(connectSpy.at(0).at(0).toInt(), int(SessionPool::CancelledError)); + QCOMPARE(lostSpy.count(), 0); // We're not supposed to know the session pointer, so no connectionLost emitted + + // Make the session->deleteLater work, it can't happen in qWait (nested event loop) + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + + QVERIFY(session.isNull()); + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } + + void shouldHonorCancelRequest() + { + FakeServer server; + server.addScenario(QList() + << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in" + << "C: A000002 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" + << "S: A000002 OK Completed" + << "C: A000003 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" + << "X" + ); + + server.startAndWait(); + + ImapAccount *account = createDefaultAccount(); + DummyPasswordRequester *requester = createDefaultRequester(); + + SessionPool pool(1); + pool.setPasswordRequester(requester); + + QSignalSpy connectSpy(&pool, SIGNAL(connectDone(int,QString))); + QSignalSpy sessionSpy(&pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString))); + QSignalSpy lostSpy(&pool, SIGNAL(connectionLost(KIMAP::Session*))); + + // Initial connect should trigger only a password request and a connect + QVERIFY(pool.connect(account)); + QTest::qWait(100); + QCOMPARE(connectSpy.count(), 1); + QCOMPARE(sessionSpy.count(), 0); + + qint64 requestId = pool.requestSession(); + + // Cancel the request + pool.cancelSessionRequest(requestId); + + // The request should not be processed anymore + QTest::qWait(100); + QCOMPARE(sessionSpy.count(), 0); + } + + void shouldBeDisconnectedOnAllSessionLost() + { + FakeServer server; + server.addScenario(QList() + << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in" + << "C: A000002 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 IDLE" + << "S: A000002 OK Completed" + << "C: A000003 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" + << "X" + ); + + server.addScenario(QList() + << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in" + << "C: A000002 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" + << "X" + ); + + server.startAndWait(); + + ImapAccount *account = createDefaultAccount(); + DummyPasswordRequester *requester = createDefaultRequester(); + + SessionPool pool(2); + pool.setPasswordRequester(requester); + + QSignalSpy sessionSpy(&pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString))); + + // Initial connect should trigger only a password request and a connect + QVERIFY(pool.connect(account)); + QTest::qWait(100); + + // We should be connected now + QVERIFY(pool.isConnected()); + + // Ask for a session + pool.requestSession(); + QTest::qWait(100); + QCOMPARE(sessionSpy.count(), 1); + QVERIFY(sessionSpy.at(0).at(1).value() != 0); + + // Still connected obviously + QVERIFY(pool.isConnected()); + + // Ask for a second session + pool.requestSession(); + QTest::qWait(100); + QCOMPARE(sessionSpy.count(), 2); + QVERIFY(sessionSpy.at(1).at(1).value() != 0); + + // Still connected of course + QVERIFY(pool.isConnected()); + + KIMAP::Session *session1 = sessionSpy.at(0).at(1).value(); + KIMAP::Session *session2 = sessionSpy.at(1).at(1).value(); + + // Prepare for session disconnects + QSignalSpy lostSpy(&pool, SIGNAL(connectionLost(KIMAP::Session*))); + + // Make the first session drop + KIMAP::CapabilitiesJob *job = new KIMAP::CapabilitiesJob(session1); + job->start(); + QTest::qWait(100); + QCOMPARE(lostSpy.count(), 1); + // FIXME extracting the pointer value form QVariant crashes + // QCOMPARE(lostSpy.at(0).at(0).value(), session1); + + // We're still connected (one session being alive) + QVERIFY(pool.isConnected()); + + // Make the second session drop + job = new KIMAP::CapabilitiesJob(session2); + job->start(); + QTest::qWait(100); + QCOMPARE(lostSpy.count(), 2); + // FIXME extracting the pointer value form QVariant crashes + // QCOMPARE(lostSpy.at(1).at(0).value(), session2); + + // We're not connected anymore! All sessions dropped! + QVERIFY(!pool.isConnected()); + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } + + void shouldHandleDisconnectDuringPasswordRequest() + { + ImapAccount *account = createDefaultAccount(); + + // This requester will delay the second reply by a second + DummyPasswordRequester *requester = createDefaultRequester(); + requester->setDelays(QList() << 20 << 1000); + QSignalSpy requesterSpy(requester, SIGNAL(done(int,QString))); + + FakeServer server; + + server.addScenario(QList() + << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in" + << "C: A000002 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 IDLE" + << "S: A000002 OK Completed" + << "C: A000003 CAPABILITY" + << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" + << "X" + ); + + server.startAndWait(); + + // The connect should work nicely + SessionPool pool(2); + + QVERIFY(!pool.isConnected()); + + QSignalSpy poolSpy(&pool, SIGNAL(connectDone(int,QString))); + QSignalSpy sessionSpy(&pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString))); + QSignalSpy lostSpy(&pool, SIGNAL(connectionLost(KIMAP::Session*))); + + pool.setPasswordRequester(requester); + QVERIFY(pool.connect(account)); + + QTest::qWait(100); + QCOMPARE(requesterSpy.count(), 1); + + QCOMPARE(poolSpy.count(), 1); + QCOMPARE(poolSpy.at(0).at(0).toInt(), (int)SessionPool::NoError); + QVERIFY(pool.isConnected()); + + // Ask for the session we just created + pool.requestSession(); + QTest::qWait(100); + QCOMPARE(sessionSpy.count(), 1); + QVERIFY(sessionSpy.at(0).at(1).value() != 0); + + KIMAP::Session *session = sessionSpy.at(0).at(1).value(); + + // Ask for the second session, the password requested will never reply + // and we'll get a disconnect in parallel (by triggering the capability + // job on the first session + // Done this way to simulate a disconnect during a password request + + // Ask for the extra session, and make sure the call is placed by waiting + // just a bit (but not too long so that the requester didn't reply yet, + // we set the reply timeout to 1000 earlier in this test) + pool.requestSession(); + QTest::qWait(100); + QCOMPARE(requesterSpy.count(), 1); // Requester didn't reply yet + QCOMPARE(sessionSpy.count(), 1); + + // Make the first (and only) session drop while we wait for the requester + // to reply + KIMAP::CapabilitiesJob *job = new KIMAP::CapabilitiesJob(session); + job->start(); + QTest::qWait(100); + QCOMPARE(lostSpy.count(), 1); + // FIXME extracting the pointer value form QVariant crashes + // QCOMPARE(lostSpy.at(0).at(0).value(), session); + + // The requester didn't reply yet + QCOMPARE(requesterSpy.count(), 1); + QCOMPARE(sessionSpy.count(), 1); + + // Now wait the remaining time to get the session creation to fail + QTest::qWait(1000); + QCOMPARE(requesterSpy.count(), 2); + QCOMPARE(sessionSpy.count(), 2); + QCOMPARE(sessionSpy.at(1).at(2).toInt(), (int)SessionPool::LoginFailError); + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } + + void shouldNotifyFailureToConnect() + { + // This tests what happens when we can't connect to the server, e.g. due to being offline. + // In this test we just use 0.0.0.0 as an invalid server IP, instead. + ImapAccount *account = createDefaultAccount(); + account->setServer("0.0.0.0"); // so that the connexion fails + DummyPasswordRequester *requester = createDefaultRequester(); + QList requests; + QList results; + // I don't want to see "WrongPasswordRequest". A password popup is annoying when we're offline or the server is down. + requests << DummyPasswordRequester::StandardRequest; + results << DummyPasswordRequester::PasswordRetrieved; + requester->setScenario(requests, results); + + QSignalSpy requesterSpy(requester, SIGNAL(done(int,QString))); + SessionPool pool(2); + QSignalSpy connectDoneSpy(&pool, SIGNAL(connectDone(int,QString))); + QSignalSpy lostSpy(&pool, SIGNAL(connectionLost(KIMAP::Session*))); + QVERIFY(!pool.isConnected()); + pool.setPasswordRequester(requester); + pool.connect(account); + QVERIFY(!pool.isConnected()); + QTRY_COMPARE(requesterSpy.count(), requests.count()); + QTRY_COMPARE(connectDoneSpy.count(), 1); + QCOMPARE(connectDoneSpy.at(0).at(0).toInt(), (int)SessionPool::CouldNotConnectError); + QCOMPARE(lostSpy.count(), 0); // don't want this, it makes the resource reconnect immediately (and fail, and reconnect, and so on...) + } + +}; + +QTEST_GUILESS_MAIN(TestSessionPool) + +#include "testsessionpool.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/batchfetcher.cpp kdepim-runtime-15.08.0/resources/imap/batchfetcher.cpp --- kdepim-runtime-4.14.6/resources/imap/batchfetcher.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/batchfetcher.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,25 +19,26 @@ #include "batchfetcher.h" +#include "imapresource_debug.h" #include - +#include "imapresource_debug.h" BatchFetcher::BatchFetcher(MessageHelper::Ptr messageHelper, const KIMAP::ImapSet &set, const KIMAP::FetchJob::FetchScope &scope, int batchSize, KIMAP::Session *session) : KJob(session), - m_currentSet(set), - m_scope(scope), - m_session(session), - m_batchSize(batchSize), - m_uidBased(false), - m_fetchedItemsInCurrentBatch(0), - m_messageHelper(messageHelper), - m_fetchInProgress(false), - m_continuationRequested(false), - m_gmailEnabled(false), - m_searchInChunks(false) + m_currentSet(set), + m_scope(scope), + m_session(session), + m_batchSize(batchSize), + m_uidBased(false), + m_fetchedItemsInCurrentBatch(0), + m_messageHelper(messageHelper), + m_fetchInProgress(false), + m_continuationRequested(false), + m_gmailEnabled(false), + m_searchInChunks(false) { } @@ -74,8 +75,8 @@ //Search in chunks also Exchange can handle const KIMAP::ImapInterval::Id firstUidToSearch = m_searchUidInterval.begin(); const KIMAP::ImapInterval::Id lastUidToSearch = m_searchInChunks - ? qMin(firstUidToSearch + maxAmountOfUidToSearchInOneTime - 1, m_searchUidInterval.end()) - : m_searchUidInterval.end(); + ? qMin(firstUidToSearch + maxAmountOfUidToSearchInOneTime - 1, m_searchUidInterval.end()) + : m_searchUidInterval.end(); //Prepare next chunk const KIMAP::ImapInterval::Id intervalBegin = lastUidToSearch + 1; @@ -90,23 +91,23 @@ KIMAP::SearchJob *search = new KIMAP::SearchJob(m_session); search->setUidBased(true); search->setTerm(KIMAP::Term(KIMAP::Term::Uid, KIMAP::ImapSet(firstUidToSearch, lastUidToSearch))); - connect(search, SIGNAL(result(KJob*)), this, SLOT(onUidSearchDone(KJob*))); + connect(search, &KIMAP::SearchJob::result, this, &BatchFetcher::onUidSearchDone); search->start(); } else { fetchNextBatch(); } } -void BatchFetcher::onUidSearchDone(KJob* job) +void BatchFetcher::onUidSearchDone(KJob *job) { if (job->error()) { - kWarning() << "Search job failed: " << job->errorString(); + qCWarning(IMAPRESOURCE_LOG) << "Search job failed: " << job->errorString(); setError(KJob::UserDefinedError); emitResult(); return; } - KIMAP::SearchJob *search = static_cast(job); + KIMAP::SearchJob *search = static_cast(job); m_uidBased = search->isUidBased(); m_currentSet.add(search->results()); @@ -123,14 +124,14 @@ m_continuationRequested = false; Q_ASSERT(m_batchSize > 0); if (m_currentSet.isEmpty()) { - kDebug(5327) << "fetch complete"; + qCDebug(IMAPRESOURCE_LOG) << "fetch complete"; emitResult(); return; } KIMAP::FetchJob *fetch = new KIMAP::FetchJob(m_session); if (m_scope.changedSince != 0) { - kDebug(5327) << "Fetching all messages in one batch."; + qCDebug(IMAPRESOURCE_LOG) << "Fetching all messages in one batch."; fetch->setSequenceSet(m_currentSet); m_currentSet = KIMAP::ImapSet(); } else { @@ -142,7 +143,7 @@ Q_FOREACH (const KIMAP::ImapInterval &interval, m_currentSet.intervals()) { if (!interval.hasDefinedEnd()) { //If we get an interval without a defined end we simply fetch everything - kDebug(5327) << "Received interval without defined end, fetching everything in one batch"; + qCDebug(IMAPRESOURCE_LOG) << "Received interval without defined end, fetching everything in one batch"; toFetch.add(interval); newSet = KIMAP::ImapSet(); break; @@ -161,7 +162,7 @@ newSet.add(interval); } } - kDebug(5327) << "Fetching " << toFetch.intervals().size() << " intervals"; + qCDebug(IMAPRESOURCE_LOG) << "Fetching " << toFetch.intervals().size() << " intervals"; fetch->setSequenceSet(toFetch); m_currentSet = newSet; } @@ -170,17 +171,17 @@ fetch->setScope(m_scope); fetch->setGmailExtensionsEnabled(m_gmailEnabled); connect(fetch, SIGNAL(headersReceived(QString, - QMap, - QMap, - QMap, - QMap, - QMap)), + QMap, + QMap, + QMap, + QMap, + QMap)), this, SLOT(onHeadersReceived(QString, - QMap, - QMap, - QMap, - QMap, - QMap)) ); + QMap, + QMap, + QMap, + QMap, + QMap))); connect(fetch, SIGNAL(result(KJob*)), this, SLOT(onHeadersFetchDone(KJob*))); m_fetchInProgress = true; @@ -194,12 +195,11 @@ const QMap &flags, const QMap &messages) { - KIMAP::FetchJob *fetch = static_cast( sender() ); - Q_ASSERT( fetch ); + KIMAP::FetchJob *fetch = static_cast(sender()); Akonadi::Item::List addedItems; foreach (qint64 number, uids.keys()) { //krazy:exclude=foreach - //kDebug( 5327 ) << "Flags: " << i.flags(); + //qDebug( 5327 ) << "Flags: " << i.flags(); bool ok; const Akonadi::Item item = m_messageHelper->createItemFromMessage(messages[number], uids[number], sizes[number], attrs.values(number), flags[number], fetch->scope(), ok); if (ok) { @@ -207,17 +207,17 @@ addedItems << item; } } -// kDebug() << addedItems.size(); +// qCDebug(IMAPRESOURCE_LOG) << addedItems.size(); if (!addedItems.isEmpty()) { - emit itemsRetrieved(addedItems); + Q_EMIT itemsRetrieved(addedItems); } } -void BatchFetcher::onHeadersFetchDone( KJob *job ) +void BatchFetcher::onHeadersFetchDone(KJob *job) { m_fetchInProgress = false; if (job->error()) { - kWarning() << "Fetch job failed " << job->errorString(); + qCWarning(IMAPRESOURCE_LOG) << "Fetch job failed " << job->errorString(); setError(KJob::UserDefinedError); emitResult(); return; diff -Nru kdepim-runtime-4.14.6/resources/imap/batchfetcher.h kdepim-runtime-15.08.0/resources/imap/batchfetcher.h --- kdepim-runtime-4.14.6/resources/imap/batchfetcher.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/batchfetcher.h 2015-08-10 21:01:02.000000000 +0000 @@ -31,7 +31,8 @@ * A job that retrieves a set of messages in reverse-ordered batches. * After each batch fetchNextBatch() needs to be called (for throttling the download speed) */ -class BatchFetcher : public KJob { +class BatchFetcher : public KJob +{ Q_OBJECT public: BatchFetcher(MessageHelper::Ptr messageHelper, @@ -40,7 +41,7 @@ int batchSize, KIMAP::Session *session); virtual ~BatchFetcher(); - virtual void start(); + void start() Q_DECL_OVERRIDE; void fetchNextBatch(); void setUidBased(bool); void setSearchUids(const KIMAP::ImapInterval &); @@ -57,7 +58,7 @@ const QMap &flags, const QMap &messages); void onHeadersFetchDone(KJob *job); - void onUidSearchDone(KJob* job); + void onUidSearchDone(KJob *job); private: //Batch fetching @@ -75,5 +76,4 @@ bool m_searchInChunks; }; - #endif // BATCHFETCHER_H diff -Nru kdepim-runtime-4.14.6/resources/imap/changecollectiontask.cpp kdepim-runtime-15.08.0/resources/imap/changecollectiontask.cpp --- kdepim-runtime-4.14.6/resources/imap/changecollectiontask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/changecollectiontask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,15 +26,18 @@ #include #include #include +#include #include "collectionannotationsattribute.h" #include "imapaclattribute.h" #include "imapquotaattribute.h" +#include "imapresource_debug.h" #include +#include "imapresource_debug.h" -ChangeCollectionTask::ChangeCollectionTask( ResourceStateInterface::Ptr resource, QObject *parent ) - : ResourceTask( DeferIfNoSession, resource, parent ), m_pendingJobs(0) +ChangeCollectionTask::ChangeCollectionTask(ResourceStateInterface::Ptr resource, QObject *parent) + : ResourceTask(DeferIfNoSession, resource, parent), m_pendingJobs(0) { } @@ -42,253 +45,265 @@ { } -void ChangeCollectionTask::doStart( KIMAP::Session *session ) +void ChangeCollectionTask::syncEnabledState(bool enable) { - if ( collection().remoteId().isEmpty() ) { - emitError( i18n( "Cannot modify IMAP folder '%1', it does not exist on the server.", - collection().name() ) ); - changeProcessed(); - return; - } - - m_collection = collection(); - m_pendingJobs = 0; - - if ( parts().contains( "AccessRights" ) ) { - Akonadi::ImapAclAttribute *aclAttribute = collection().attribute(); - - if ( aclAttribute==0 ) { - emitWarning( i18n( "ACLs for '%1' need to be retrieved from the IMAP server first. Skipping ACL change", - collection().name() ) ); - } else { - KIMAP::Acl::Rights imapRights = aclAttribute->rights()[userName().toUtf8()]; - Akonadi::Collection::Rights newRights = collection().rights(); + m_syncEnabledState = enable; +} - if ( newRights & Akonadi::Collection::CanChangeItem ) { - imapRights|= KIMAP::Acl::Write; - } else { - imapRights&= ~KIMAP::Acl::Write; - } - - if ( newRights & Akonadi::Collection::CanCreateItem ) { - imapRights|= KIMAP::Acl::Insert; - } else { - imapRights&= ~KIMAP::Acl::Insert; - } - - if ( newRights & Akonadi::Collection::CanDeleteItem ) { - imapRights|= KIMAP::Acl::DeleteMessage; - } else { - imapRights&= ~KIMAP::Acl::DeleteMessage; - } - - if ( newRights & ( Akonadi::Collection::CanChangeCollection | Akonadi::Collection::CanCreateCollection ) ) { - imapRights|= KIMAP::Acl::CreateMailbox; - imapRights|= KIMAP::Acl::Create; - } else { - imapRights&= ~KIMAP::Acl::CreateMailbox; - imapRights&= ~KIMAP::Acl::Create; - } - - if ( newRights & Akonadi::Collection::CanDeleteCollection ) { - imapRights|= KIMAP::Acl::DeleteMailbox; - } else { - imapRights&= ~KIMAP::Acl::DeleteMailbox; - } - - if ( ( newRights & Akonadi::Collection::CanDeleteItem ) - && ( newRights & Akonadi::Collection::CanDeleteCollection ) ) { - imapRights|= KIMAP::Acl::Delete; - } else { - imapRights&= ~KIMAP::Acl::Delete; - } - - kDebug( 5327 ) << "imapRights:" << imapRights - << "newRights:" << newRights; - - KIMAP::SetAclJob *job = new KIMAP::SetAclJob( session ); - job->setMailBox( mailBoxForCollection( collection() ) ); - job->setRights( KIMAP::SetAclJob::Change, imapRights ); - job->setIdentifier( userName().toUtf8() ); - - connect( job, SIGNAL(result(KJob*)), - this, SLOT(onSetAclDone(KJob*)) ); - - job->start(); - - m_pendingJobs++; - } - } - - if ( parts().contains( "collectionannotations" ) && serverSupportsAnnotations() ) { - Akonadi::CollectionAnnotationsAttribute *annotationsAttribute = - collection().attribute(); - - if ( annotationsAttribute ) { // No annotations it seems... server is lieing to us? - QMap annotations = annotationsAttribute->annotations(); - kDebug( 5327 ) << "All annotations: " << annotations; - - foreach ( const QByteArray &entry, annotations.keys() ) { //krazy:exclude=foreach - KIMAP::SetMetaDataJob *job = new KIMAP::SetMetaDataJob( session ); - if ( serverCapabilities().contains( QLatin1String("METADATA") ) ) { - job->setServerCapability( KIMAP::MetaDataJobBase::Metadata ); - } else { - job->setServerCapability( KIMAP::MetaDataJobBase::Annotatemore ); - } - job->setMailBox( mailBoxForCollection( collection() ) ); +void ChangeCollectionTask::doStart(KIMAP::Session *session) +{ + if (collection().remoteId().isEmpty()) { + emitError(i18n("Cannot modify IMAP folder '%1', it does not exist on the server.", + collection().name())); + changeProcessed(); + return; + } + + m_collection = collection(); + m_pendingJobs = 0; - if ( !entry.startsWith( "/shared" ) && !entry.startsWith( "/private" ) ) { - //Support for legacy annotations that don't include the prefix - job->addMetaData( QByteArray("/shared") + entry, annotations[entry] ); + if (parts().contains("AccessRights")) { + Akonadi::ImapAclAttribute *aclAttribute = collection().attribute(); + + if (aclAttribute == Q_NULLPTR) { + emitWarning(i18n("ACLs for '%1' need to be retrieved from the IMAP server first. Skipping ACL change", + collection().name())); } else { - job->addMetaData( entry, annotations[entry] ); - } + KIMAP::Acl::Rights imapRights = aclAttribute->rights()[userName().toUtf8()]; + Akonadi::Collection::Rights newRights = collection().rights(); - kDebug( 5327 ) << "Job got entry:" << entry << "value:" << annotations[entry]; + if (newRights & Akonadi::Collection::CanChangeItem) { + imapRights |= KIMAP::Acl::Write; + } else { + imapRights &= ~KIMAP::Acl::Write; + } + + if (newRights & Akonadi::Collection::CanCreateItem) { + imapRights |= KIMAP::Acl::Insert; + } else { + imapRights &= ~KIMAP::Acl::Insert; + } + + if (newRights & Akonadi::Collection::CanDeleteItem) { + imapRights |= KIMAP::Acl::DeleteMessage; + } else { + imapRights &= ~KIMAP::Acl::DeleteMessage; + } + + if (newRights & (Akonadi::Collection::CanChangeCollection | Akonadi::Collection::CanCreateCollection)) { + imapRights |= KIMAP::Acl::CreateMailbox; + imapRights |= KIMAP::Acl::Create; + } else { + imapRights &= ~KIMAP::Acl::CreateMailbox; + imapRights &= ~KIMAP::Acl::Create; + } + + if (newRights & Akonadi::Collection::CanDeleteCollection) { + imapRights |= KIMAP::Acl::DeleteMailbox; + } else { + imapRights &= ~KIMAP::Acl::DeleteMailbox; + } + + if ((newRights & Akonadi::Collection::CanDeleteItem) + && (newRights & Akonadi::Collection::CanDeleteCollection)) { + imapRights |= KIMAP::Acl::Delete; + } else { + imapRights &= ~KIMAP::Acl::Delete; + } + + qCDebug(IMAPRESOURCE_LOG) << "imapRights:" << imapRights + << "newRights:" << newRights; + + KIMAP::SetAclJob *job = new KIMAP::SetAclJob(session); + job->setMailBox(mailBoxForCollection(collection())); + job->setRights(KIMAP::SetAclJob::Change, imapRights); + job->setIdentifier(userName().toUtf8()); - connect( job, SIGNAL(result(KJob*)), - this, SLOT(onSetMetaDataDone(KJob*)) ); + connect(job, &KIMAP::SetAclJob::result, this, &ChangeCollectionTask::onSetAclDone); - job->start(); + job->start(); - m_pendingJobs++; - } + m_pendingJobs++; + } } - } - if ( parts().contains( "imapacl" ) ) { - Akonadi::ImapAclAttribute *aclAttribute = collection().attribute(); + if (parts().contains("collectionannotations") && serverSupportsAnnotations()) { + Akonadi::CollectionAnnotationsAttribute *annotationsAttribute = + collection().attribute(); + + if (annotationsAttribute) { // No annotations it seems... server is lieing to us? + QMap annotations = annotationsAttribute->annotations(); + qCDebug(IMAPRESOURCE_LOG) << "All annotations: " << annotations; + + foreach (const QByteArray &entry, annotations.keys()) { //krazy:exclude=foreach + KIMAP::SetMetaDataJob *job = new KIMAP::SetMetaDataJob(session); + if (serverCapabilities().contains(QStringLiteral("METADATA"))) { + job->setServerCapability(KIMAP::MetaDataJobBase::Metadata); + } else { + job->setServerCapability(KIMAP::MetaDataJobBase::Annotatemore); + } + job->setMailBox(mailBoxForCollection(collection())); + + if (!entry.startsWith("/shared") && !entry.startsWith("/private")) { + //Support for legacy annotations that don't include the prefix + job->addMetaData(QByteArray("/shared") + entry, annotations[entry]); + } else { + job->addMetaData(entry, annotations[entry]); + } + + qCDebug(IMAPRESOURCE_LOG) << "Job got entry:" << entry << "value:" << annotations[entry]; - if ( aclAttribute ) { - const QMap rights = aclAttribute->rights(); - const QMap oldRights = aclAttribute->oldRights(); - const QList oldIds = oldRights.keys(); - const QList ids = rights.keys(); + connect(job, &KIMAP::SetMetaDataJob::result, this, &ChangeCollectionTask::onSetMetaDataDone); - // remove all ACL entries that have been deleted - foreach ( const QByteArray &oldId, oldIds ) { - if ( !ids.contains( oldId ) ) { - KIMAP::SetAclJob *job = new KIMAP::SetAclJob( session ); - job->setMailBox( mailBoxForCollection( collection() ) ); - job->setIdentifier( oldId ); - job->setRights( KIMAP::SetAclJob::Remove, oldRights[oldId] ); + job->start(); - connect( job, SIGNAL(result(KJob*)), - this, SLOT(onSetAclDone(KJob*)) ); + m_pendingJobs++; + } + } + } - job->start(); + if (parts().contains("imapacl")) { + Akonadi::ImapAclAttribute *aclAttribute = collection().attribute(); - m_pendingJobs++; + if (aclAttribute) { + const QMap rights = aclAttribute->rights(); + const QMap oldRights = aclAttribute->oldRights(); + const QList oldIds = oldRights.keys(); + const QList ids = rights.keys(); + + // remove all ACL entries that have been deleted + foreach (const QByteArray &oldId, oldIds) { + if (!ids.contains(oldId)) { + KIMAP::SetAclJob *job = new KIMAP::SetAclJob(session); + job->setMailBox(mailBoxForCollection(collection())); + job->setIdentifier(oldId); + job->setRights(KIMAP::SetAclJob::Remove, oldRights[oldId]); + + connect(job, &KIMAP::SetAclJob::result, this, &ChangeCollectionTask::onSetAclDone); + + job->start(); + + m_pendingJobs++; + } + } + + foreach (const QByteArray &id, ids) { + KIMAP::SetAclJob *job = new KIMAP::SetAclJob(session); + job->setMailBox(mailBoxForCollection(collection())); + job->setIdentifier(id); + job->setRights(KIMAP::SetAclJob::Change, rights[id]); + + connect(job, &KIMAP::SetAclJob::result, this, &ChangeCollectionTask::onSetAclDone); + + job->start(); + + m_pendingJobs++; + } } - } + } - foreach ( const QByteArray &id, ids ) { - KIMAP::SetAclJob *job = new KIMAP::SetAclJob( session ); - job->setMailBox( mailBoxForCollection( collection() ) ); - job->setIdentifier( id ); - job->setRights( KIMAP::SetAclJob::Change, rights[id] ); + // Check if we need to rename the mailbox + // This one goes last on purpose, we don't want the previous jobs + // we triggered to act on the wrong mailbox name + if (parts().contains("NAME")) { + const QChar separator = separatorCharacter(); + m_collection.setName(m_collection.name().replace(separator, QString())); + m_collection.setRemoteId(separator + m_collection.name()); + + const QString oldMailBox = mailBoxForCollection(collection()); + const QString newMailBox = mailBoxForCollection(m_collection); + + if (oldMailBox != newMailBox) { + KIMAP::RenameJob *renameJob = new KIMAP::RenameJob(session); + renameJob->setSourceMailBox(oldMailBox); + renameJob->setDestinationMailBox(newMailBox); + connect(renameJob, &KIMAP::RenameJob::result, this, &ChangeCollectionTask::onRenameDone); - connect( job, SIGNAL(result(KJob*)), - this, SLOT(onSetAclDone(KJob*)) ); + renameJob->start(); - job->start(); + m_pendingJobs++; + } + } + if (m_syncEnabledState && isSubscriptionEnabled() && parts().contains("ENABLED")) { + if (collection().enabled()) { + KIMAP::SubscribeJob *job = new KIMAP::SubscribeJob(session); + job->setMailBox(mailBoxForCollection(collection())); + connect(job, &KIMAP::SubscribeJob::result, this, &ChangeCollectionTask::onSubscribeDone); + job->start(); + } else { + KIMAP::UnsubscribeJob *job = new KIMAP::UnsubscribeJob(session); + job->setMailBox(mailBoxForCollection(collection())); + connect(job, &KIMAP::UnsubscribeJob::result, this, &ChangeCollectionTask::onSubscribeDone); + job->start(); + } m_pendingJobs++; - } } - } - // Check if we need to rename the mailbox - // This one goes last on purpose, we don't want the previous jobs - // we triggered to act on the wrong mailbox name - if ( parts().contains( "NAME" ) ) { - const QChar separator = separatorCharacter(); - m_collection.setName( m_collection.name().replace( separator, QString() ) ); - m_collection.setRemoteId( separator + m_collection.name() ); - - const QString oldMailBox = mailBoxForCollection( collection() ); - const QString newMailBox = mailBoxForCollection( m_collection ); - - if ( oldMailBox != newMailBox ) { - KIMAP::RenameJob *renameJob = new KIMAP::RenameJob( session ); - renameJob->setSourceMailBox( oldMailBox ); - renameJob->setDestinationMailBox( newMailBox ); - connect( renameJob, SIGNAL(result(KJob*)), - this, SLOT(onRenameDone(KJob*)) ); - - renameJob->start(); - - m_pendingJobs++; - } - } - - // we scheduled no change on the server side, probably we got only - // unsupported part, so just declare the task done - if ( m_pendingJobs == 0 ) { - changeCommitted( collection() ); - } + // we scheduled no change on the server side, probably we got only + // unsupported part, so just declare the task done + if (m_pendingJobs == 0) { + changeCommitted(collection()); + } } -void ChangeCollectionTask::onRenameDone( KJob *job ) +void ChangeCollectionTask::onRenameDone(KJob *job) { - if ( job->error() ) { - const QString prevRid = collection().remoteId(); - Q_ASSERT( !prevRid.isEmpty() ); + if (job->error()) { + const QString prevRid = collection().remoteId(); + Q_ASSERT(!prevRid.isEmpty()); - emitWarning( i18n( "Failed to rename the folder, restoring folder list." ) ); + emitWarning(i18n("Failed to rename the folder, restoring folder list.")); - m_collection.setName( prevRid.mid( 1 ) ); - m_collection.setRemoteId( prevRid ); + m_collection.setName(prevRid.mid(1)); + m_collection.setRemoteId(prevRid); - endTaskIfNeeded(); - } else { - KIMAP::RenameJob *renameJob = static_cast( job ); - KIMAP::SubscribeJob *subscribeJob = new KIMAP::SubscribeJob( renameJob->session() ); - subscribeJob->setMailBox( renameJob->destinationMailBox() ); - connect( subscribeJob, SIGNAL(result(KJob*)), - this, SLOT(onSubscribeDone(KJob*)) ); - subscribeJob->start(); - } + endTaskIfNeeded(); + } else { + KIMAP::RenameJob *renameJob = static_cast(job); + KIMAP::SubscribeJob *subscribeJob = new KIMAP::SubscribeJob(renameJob->session()); + subscribeJob->setMailBox(renameJob->destinationMailBox()); + connect(subscribeJob, &KIMAP::SubscribeJob::result, this, &ChangeCollectionTask::onSubscribeDone); + subscribeJob->start(); + } } -void ChangeCollectionTask::onSubscribeDone( KJob *job ) +void ChangeCollectionTask::onSubscribeDone(KJob *job) { - if ( job->error() && isSubscriptionEnabled() ) { - emitWarning( i18n( "Failed to subscribe to the renamed folder '%1' on the IMAP server. " - "It will disappear on next sync. Use the subscription dialog to overcome that", - m_collection.name() ) ); - } + if (job->error() && isSubscriptionEnabled()) { + emitWarning(i18n("Failed to subscribe to the renamed folder '%1' on the IMAP server. " + "It will disappear on next sync. Use the subscription dialog to overcome that", + m_collection.name())); + } - endTaskIfNeeded(); + endTaskIfNeeded(); } -void ChangeCollectionTask::onSetAclDone( KJob *job ) +void ChangeCollectionTask::onSetAclDone(KJob *job) { - if ( job->error() ) { - emitWarning( i18n( "Failed to write some ACLs for '%1' on the IMAP server. %2", - collection().name(), job->errorText() ) ); - } + if (job->error()) { + emitWarning(i18n("Failed to write some ACLs for '%1' on the IMAP server. %2", + collection().name(), job->errorText())); + } - endTaskIfNeeded(); + endTaskIfNeeded(); } -void ChangeCollectionTask::onSetMetaDataDone( KJob *job ) +void ChangeCollectionTask::onSetMetaDataDone(KJob *job) { - if ( job->error() ) { - emitWarning( i18n( "Failed to write some annotations for '%1' on the IMAP server. %2", - collection().name(), job->errorText() ) ); - } + if (job->error()) { + emitWarning(i18n("Failed to write some annotations for '%1' on the IMAP server. %2", + collection().name(), job->errorText())); + } - endTaskIfNeeded(); + endTaskIfNeeded(); } void ChangeCollectionTask::endTaskIfNeeded() { - if ( --m_pendingJobs == 0 ) { - // the others have ended, we're done, the next one can go - changeCommitted( m_collection ); - } + if (--m_pendingJobs == 0) { + // the others have ended, we're done, the next one can go + changeCommitted(m_collection); + } } - - diff -Nru kdepim-runtime-4.14.6/resources/imap/changecollectiontask.h kdepim-runtime-15.08.0/resources/imap/changecollectiontask.h --- kdepim-runtime-4.14.6/resources/imap/changecollectiontask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/changecollectiontask.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,26 +26,29 @@ class ChangeCollectionTask : public ResourceTask { - Q_OBJECT + Q_OBJECT public: - explicit ChangeCollectionTask( ResourceStateInterface::Ptr resource, QObject *parent = 0 ); - virtual ~ChangeCollectionTask(); + explicit ChangeCollectionTask(ResourceStateInterface::Ptr resource, QObject *parent = Q_NULLPTR); + virtual ~ChangeCollectionTask(); -private slots: - void onRenameDone( KJob *job ); - void onSubscribeDone( KJob *job ); - void onSetAclDone( KJob *job ); - void onSetMetaDataDone( KJob *job ); + void syncEnabledState(bool); + +private Q_SLOTS: + void onRenameDone(KJob *job); + void onSubscribeDone(KJob *job); + void onSetAclDone(KJob *job); + void onSetMetaDataDone(KJob *job); protected: - virtual void doStart( KIMAP::Session *session ); + void doStart(KIMAP::Session *session) Q_DECL_OVERRIDE; private: - void endTaskIfNeeded(); + void endTaskIfNeeded(); - int m_pendingJobs; - Akonadi::Collection m_collection; + int m_pendingJobs; + Akonadi::Collection m_collection; + bool m_syncEnabledState; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/changeitemsflagstask.cpp kdepim-runtime-15.08.0/resources/imap/changeitemsflagstask.cpp --- kdepim-runtime-4.14.6/resources/imap/changeitemsflagstask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/changeitemsflagstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -17,15 +17,16 @@ 02110-1301, USA. */ - #include "changeitemsflagstask.h" #include #include #include +#include "imapresource_debug.h" +#include "imapresource_debug.h" -ChangeItemsFlagsTask::ChangeItemsFlagsTask( ResourceStateInterface::Ptr resource, QObject* parent ): - ResourceTask( ResourceTask::DeferIfNoSession, resource, parent ), +ChangeItemsFlagsTask::ChangeItemsFlagsTask(ResourceStateInterface::Ptr resource, QObject *parent): + ResourceTask(ResourceTask::DeferIfNoSession, resource, parent), m_processedItems(0) { @@ -35,119 +36,119 @@ { } -void ChangeItemsFlagsTask::doStart(KIMAP::Session* session) +void ChangeItemsFlagsTask::doStart(KIMAP::Session *session) { - const QString mailBox = mailBoxForCollection( items().first().parentCollection() ); - kDebug(5327) << mailBox; + const QString mailBox = mailBoxForCollection(items().at(0).parentCollection()); + qCDebug(IMAPRESOURCE_LOG) << mailBox; - if ( session->selectedMailBox() != mailBox ) { - KIMAP::SelectJob *select = new KIMAP::SelectJob( session ); - select->setMailBox( mailBox ); + if (session->selectedMailBox() != mailBox) { + KIMAP::SelectJob *select = new KIMAP::SelectJob(session); + select->setMailBox(mailBox); - connect( select, SIGNAL(result(KJob*)), - this, SLOT(onSelectDone(KJob*)) ); + connect(select, SIGNAL(result(KJob*)), + this, SLOT(onSelectDone(KJob*))); - select->start(); + select->start(); - } else { - if ( !addedFlags().isEmpty() ) { - triggerAppendFlagsJob( session ); - } else if ( !removedFlags().isEmpty() ) { - triggerRemoveFlagsJob( session ); } else { - kDebug(5327) << "nothing to do"; - changeProcessed(); + if (!addedFlags().isEmpty()) { + triggerAppendFlagsJob(session); + } else if (!removedFlags().isEmpty()) { + triggerRemoveFlagsJob(session); + } else { + qCDebug(IMAPRESOURCE_LOG) << "nothing to do"; + changeProcessed(); + } } - } } -void ChangeItemsFlagsTask::onSelectDone(KJob* job) +void ChangeItemsFlagsTask::onSelectDone(KJob *job) { - if ( job->error() ) { - kWarning() << "Select failed: " << job->errorString(); - cancelTask( job->errorString() ); - } else { - KIMAP::SelectJob *select = static_cast( job ); - kDebug(5327) << addedFlags(); - if ( !addedFlags().isEmpty() ) { - triggerAppendFlagsJob( select->session() ); - } else if ( !removedFlags().isEmpty() ) { - triggerRemoveFlagsJob( select->session() ); + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Select failed: " << job->errorString(); + cancelTask(job->errorString()); } else { - kDebug(5327) << "nothing to do"; - changeProcessed(); + KIMAP::SelectJob *select = static_cast(job); + qCDebug(IMAPRESOURCE_LOG) << addedFlags(); + if (!addedFlags().isEmpty()) { + triggerAppendFlagsJob(select->session()); + } else if (!removedFlags().isEmpty()) { + triggerRemoveFlagsJob(select->session()); + } else { + qCDebug(IMAPRESOURCE_LOG) << "nothing to do"; + changeProcessed(); + } } - } } -KIMAP::StoreJob* ChangeItemsFlagsTask::prepareJob( KIMAP::Session *session ) +KIMAP::StoreJob *ChangeItemsFlagsTask::prepareJob(KIMAP::Session *session) { - KIMAP::ImapSet set; - const Akonadi::Item::List &allItems = items(); - // Split the request to multiple smaller requests of 2000 UIDs each - various IMAP - // servers have various limits on maximum size of a request - // 2000 is a random number that sounds like a good compromise between performance - // and functionality (i.e. 2000 UIDs should be supported by any server out there) - for (int i = 0, count = qMin(2000, allItems.count() - m_processedItems); i < count; ++i) { - set.add( allItems[m_processedItems].remoteId().toLong() ); - ++m_processedItems; - } + KIMAP::ImapSet set; + const Akonadi::Item::List &allItems = items(); + // Split the request to multiple smaller requests of 2000 UIDs each - various IMAP + // servers have various limits on maximum size of a request + // 2000 is a random number that sounds like a good compromise between performance + // and functionality (i.e. 2000 UIDs should be supported by any server out there) + for (int i = 0, count = qMin(2000, allItems.count() - m_processedItems); i < count; ++i) { + set.add(allItems[m_processedItems].remoteId().toLong()); + ++m_processedItems; + } - KIMAP::StoreJob *store = new KIMAP::StoreJob( session ); - store->setUidBased( true ); - store->setSequenceSet( set ); + KIMAP::StoreJob *store = new KIMAP::StoreJob(session); + store->setUidBased(true); + store->setSequenceSet(set); - return store; + return store; } -void ChangeItemsFlagsTask::triggerAppendFlagsJob(KIMAP::Session* session) +void ChangeItemsFlagsTask::triggerAppendFlagsJob(KIMAP::Session *session) { - KIMAP::StoreJob *store = prepareJob( session ); - store->setFlags( fromAkonadiToSupportedImapFlags( addedFlags().toList(), items().first().parentCollection() ) ); - store->setMode( KIMAP::StoreJob::AppendFlags ); - connect( store, SIGNAL(result(KJob*)), SLOT(onAppendFlagsDone(KJob*)) ); - store->start(); + KIMAP::StoreJob *store = prepareJob(session); + store->setFlags(fromAkonadiToSupportedImapFlags(addedFlags().toList(), items().at(0).parentCollection())); + store->setMode(KIMAP::StoreJob::AppendFlags); + connect(store, &KIMAP::StoreJob::result, this, &ChangeItemsFlagsTask::onAppendFlagsDone); + store->start(); } -void ChangeItemsFlagsTask::triggerRemoveFlagsJob(KIMAP::Session* session) +void ChangeItemsFlagsTask::triggerRemoveFlagsJob(KIMAP::Session *session) { - KIMAP::StoreJob *store = prepareJob( session ); - store->setFlags( fromAkonadiToSupportedImapFlags( removedFlags().toList(), items().first().parentCollection() ) ); - store->setMode( KIMAP::StoreJob::RemoveFlags ); - connect( store, SIGNAL(result(KJob*)), SLOT(onRemoveFlagsDone(KJob*)) ); - store->start(); + KIMAP::StoreJob *store = prepareJob(session); + store->setFlags(fromAkonadiToSupportedImapFlags(removedFlags().toList(), items().at(0).parentCollection())); + store->setMode(KIMAP::StoreJob::RemoveFlags); + connect(store, &KIMAP::StoreJob::result, this, &ChangeItemsFlagsTask::onRemoveFlagsDone); + store->start(); } -void ChangeItemsFlagsTask::onAppendFlagsDone(KJob* job) +void ChangeItemsFlagsTask::onAppendFlagsDone(KJob *job) { - if ( job->error() ) { - kWarning() << "Flag append failed: " << job->errorString(); - cancelTask( job->errorString() ); - } else { - KIMAP::Session *session = qobject_cast(job)->session(); - if ( m_processedItems < items().count() ) { - triggerAppendFlagsJob( session ); - } else if ( removedFlags().isEmpty() ) { - changeProcessed(); + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Flag append failed: " << job->errorString(); + cancelTask(job->errorString()); } else { - kDebug(5327) << removedFlags(); - m_processedItems = 0; - triggerRemoveFlagsJob( session ); + KIMAP::Session *session = qobject_cast(job)->session(); + if (m_processedItems < items().count()) { + triggerAppendFlagsJob(session); + } else if (removedFlags().isEmpty()) { + changeProcessed(); + } else { + qCDebug(IMAPRESOURCE_LOG) << removedFlags(); + m_processedItems = 0; + triggerRemoveFlagsJob(session); + } } - } } -void ChangeItemsFlagsTask::onRemoveFlagsDone(KJob* job) +void ChangeItemsFlagsTask::onRemoveFlagsDone(KJob *job) { - if ( job->error() ) { - kWarning() << "Flag remove failed: " << job->errorString(); - cancelTask( job->errorString() ); - } else { - if ( m_processedItems < items().count() ) { - triggerRemoveFlagsJob( qobject_cast(job)->session() ); + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Flag remove failed: " << job->errorString(); + cancelTask(job->errorString()); } else { - changeProcessed(); + if (m_processedItems < items().count()) { + triggerRemoveFlagsJob(qobject_cast(job)->session()); + } else { + changeProcessed(); + } } - } } diff -Nru kdepim-runtime-4.14.6/resources/imap/changeitemsflagstask.h kdepim-runtime-15.08.0/resources/imap/changeitemsflagstask.h --- kdepim-runtime-4.14.6/resources/imap/changeitemsflagstask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/changeitemsflagstask.h 2015-08-10 21:01:02.000000000 +0000 @@ -17,39 +17,39 @@ 02110-1301, USA. */ - #ifndef CHANGEITEMSFLAGSTASK_H #define CHANGEITEMSFLAGSTASK_H #include "resourcetask.h" -namespace KIMAP { +namespace KIMAP +{ class StoreJob; } class ChangeItemsFlagsTask : public ResourceTask { - Q_OBJECT + Q_OBJECT public: - explicit ChangeItemsFlagsTask( ResourceStateInterface::Ptr resource, QObject* parent = 0 ); - virtual ~ChangeItemsFlagsTask(); + explicit ChangeItemsFlagsTask(ResourceStateInterface::Ptr resource, QObject *parent = Q_NULLPTR); + virtual ~ChangeItemsFlagsTask(); protected Q_SLOTS: - void onSelectDone( KJob *job ); - void onAppendFlagsDone( KJob *job ); - void onRemoveFlagsDone( KJob *job ); + void onSelectDone(KJob *job); + void onAppendFlagsDone(KJob *job); + void onRemoveFlagsDone(KJob *job); protected: - KIMAP::StoreJob* prepareJob( KIMAP::Session *session ); + KIMAP::StoreJob *prepareJob(KIMAP::Session *session); - virtual void doStart( KIMAP::Session* session ); + void doStart(KIMAP::Session *session) Q_DECL_OVERRIDE; - virtual void triggerAppendFlagsJob( KIMAP::Session *session ); - virtual void triggerRemoveFlagsJob( KIMAP::Session *session ); + virtual void triggerAppendFlagsJob(KIMAP::Session *session); + virtual void triggerRemoveFlagsJob(KIMAP::Session *session); protected: - int m_processedItems; + int m_processedItems; }; diff -Nru kdepim-runtime-4.14.6/resources/imap/changeitemtask.cpp kdepim-runtime-15.08.0/resources/imap/changeitemtask.cpp --- kdepim-runtime-4.14.6/resources/imap/changeitemtask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/changeitemtask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,8 +21,10 @@ #include "changeitemtask.h" -#include -#include +#include "imapresource_debug.h" +#include "imapresource_debug.h" + +#include #include #include @@ -35,8 +37,8 @@ #include "imapflags.h" #include "uidnextattribute.h" -ChangeItemTask::ChangeItemTask( ResourceStateInterface::Ptr resource, QObject *parent ) - : ResourceTask( DeferIfNoSession, resource, parent ), m_session( 0 ), m_oldUid( 0 ), m_newUid( 0 ) +ChangeItemTask::ChangeItemTask(ResourceStateInterface::Ptr resource, QObject *parent) + : ResourceTask(DeferIfNoSession, resource, parent), m_session(Q_NULLPTR), m_oldUid(0), m_newUid(0) { } @@ -45,259 +47,251 @@ { } -void ChangeItemTask::doStart( KIMAP::Session *session ) +void ChangeItemTask::doStart(KIMAP::Session *session) { - m_session = session; + m_session = session; - const QString mailBox = mailBoxForCollection( item().parentCollection() ); - m_oldUid = item().remoteId().toLongLong(); - kDebug(5327) << mailBox << m_oldUid << parts(); + const QString mailBox = mailBoxForCollection(item().parentCollection()); + m_oldUid = item().remoteId().toLongLong(); + qCDebug(IMAPRESOURCE_LOG) << mailBox << m_oldUid << parts(); - if ( parts().contains( "PLD:RFC822" ) ) { - if ( !item().hasPayload() ) { - kWarning() << "Payload changed, no payload available."; - changeProcessed(); - return; - } + if (parts().contains("PLD:RFC822")) { + if (!item().hasPayload()) { + qCWarning(IMAPRESOURCE_LOG) << "Payload changed, no payload available."; + changeProcessed(); + return; + } + + // save message to the server. + KMime::Message::Ptr msg = item().payload(); + m_messageId = msg->messageID()->asUnicodeString().toUtf8(); - // save message to the server. - KMime::Message::Ptr msg = item().payload(); - m_messageId = msg->messageID()->asUnicodeString().toUtf8(); + KIMAP::AppendJob *job = new KIMAP::AppendJob(session); - KIMAP::AppendJob *job = new KIMAP::AppendJob( session ); + job->setMailBox(mailBox); + job->setContent(msg->encodedContent(true)); + const QList flags = fromAkonadiToSupportedImapFlags(item().flags().toList(), item().parentCollection()); + job->setFlags(flags); + qCDebug(IMAPRESOURCE_LOG) << "Appending new message: " << flags; - job->setMailBox( mailBox ); - job->setContent( msg->encodedContent( true ) ); - const QList flags = fromAkonadiToSupportedImapFlags( item().flags().toList(), item().parentCollection() ); - job->setFlags( flags ); - kDebug(5327) << "Appending new message: " << flags; + connect(job, &KIMAP::AppendJob::result, this, &ChangeItemTask::onAppendMessageDone); - connect( job, SIGNAL(result(KJob*)), - this, SLOT(onAppendMessageDone(KJob*)) ); + job->start(); - job->start(); + } else if (parts().contains("FLAGS")) { - } else if ( parts().contains( "FLAGS" ) ) { + if (session->selectedMailBox() != mailBox) { + KIMAP::SelectJob *select = new KIMAP::SelectJob(session); + select->setMailBox(mailBox); - if ( session->selectedMailBox() != mailBox ) { - KIMAP::SelectJob *select = new KIMAP::SelectJob( session ); - select->setMailBox( mailBox ); + connect(select, &KIMAP::SelectJob::result, this, &ChangeItemTask::onPreStoreSelectDone); - connect( select, SIGNAL(result(KJob*)), - this, SLOT(onPreStoreSelectDone(KJob*)) ); + select->start(); - select->start(); + } else { + triggerStoreJob(); + } } else { - triggerStoreJob(); + qCDebug(IMAPRESOURCE_LOG) << "Nothing to do"; + changeProcessed(); } - - } else { - kDebug(5327) << "Nothing to do"; - changeProcessed(); - } } -void ChangeItemTask::onPreStoreSelectDone( KJob *job ) +void ChangeItemTask::onPreStoreSelectDone(KJob *job) { - if ( job->error() ) { - kWarning() << "Select failed: " << job->errorString(); - cancelTask( job->errorString() ); - } else { - triggerStoreJob(); - } + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Select failed: " << job->errorString(); + cancelTask(job->errorString()); + } else { + triggerStoreJob(); + } } void ChangeItemTask::triggerStoreJob() { - QList flags = fromAkonadiToSupportedImapFlags( item().flags().toList(), item().parentCollection() ); - kDebug(5327) << flags; + QList flags = fromAkonadiToSupportedImapFlags(item().flags().toList(), item().parentCollection()); + qCDebug(IMAPRESOURCE_LOG) << flags; - KIMAP::StoreJob *store = new KIMAP::StoreJob( m_session ); + KIMAP::StoreJob *store = new KIMAP::StoreJob(m_session); - store->setUidBased( true ); - store->setSequenceSet( KIMAP::ImapSet( m_oldUid ) ); - store->setFlags( flags ); - store->setMode( KIMAP::StoreJob::SetFlags ); + store->setUidBased(true); + store->setSequenceSet(KIMAP::ImapSet(m_oldUid)); + store->setFlags(flags); + store->setMode(KIMAP::StoreJob::SetFlags); - connect( store, SIGNAL(result(KJob*)), - this, SLOT(onStoreFlagsDone(KJob*)) ); + connect(store, &KIMAP::StoreJob::result, this, &ChangeItemTask::onStoreFlagsDone); - store->start(); + store->start(); } -void ChangeItemTask::onStoreFlagsDone( KJob *job ) +void ChangeItemTask::onStoreFlagsDone(KJob *job) { - if ( job->error() ) { - kWarning() << "Flag store failed: " << job->errorString(); - cancelTask( job->errorString() ); - } else { - changeProcessed(); - } + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Flag store failed: " << job->errorString(); + cancelTask(job->errorString()); + } else { + changeProcessed(); + } } -void ChangeItemTask::onAppendMessageDone( KJob *job ) +void ChangeItemTask::onAppendMessageDone(KJob *job) { - if ( job->error() ) { - kWarning() << "Append failed: " << job->errorString(); - cancelTask( job->errorString() ); - return; - } + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Append failed: " << job->errorString(); + cancelTask(job->errorString()); + return; + } - KIMAP::AppendJob *append = qobject_cast( job ); + KIMAP::AppendJob *append = qobject_cast(job); - m_newUid = append->uid(); + m_newUid = append->uid(); - // OK it's a content change, so we've to mark the old version as deleted - // remember, you can't modify messages in IMAP mailboxes so that's really - // add+remove all the time. + // OK it's a content change, so we've to mark the old version as deleted + // remember, you can't modify messages in IMAP mailboxes so that's really + // add+remove all the time. - // APPEND does not require a SELECT, so we could be anywhere right now - if ( m_session->selectedMailBox() != append->mailBox() ) { - KIMAP::SelectJob *select = new KIMAP::SelectJob( m_session ); - select->setMailBox( append->mailBox() ); + // APPEND does not require a SELECT, so we could be anywhere right now + if (m_session->selectedMailBox() != append->mailBox()) { + KIMAP::SelectJob *select = new KIMAP::SelectJob(m_session); + select->setMailBox(append->mailBox()); - connect( select, SIGNAL(result(KJob*)), - this, SLOT(onPreDeleteSelectDone(KJob*)) ); + connect(select, &KIMAP::SelectJob::result, this, &ChangeItemTask::onPreDeleteSelectDone); - select->start(); + select->start(); - } else { - if ( m_newUid > 0 ) { - triggerDeleteJob(); } else { - triggerSearchJob(); + if (m_newUid > 0) { + triggerDeleteJob(); + } else { + triggerSearchJob(); + } } - } } -void ChangeItemTask::onPreDeleteSelectDone( KJob *job ) +void ChangeItemTask::onPreDeleteSelectDone(KJob *job) { - if ( job->error() ) { - kWarning() << "PreDelete select failed: " << job->errorString(); - if ( m_newUid > 0 ) { - recordNewUid(); - } else { - cancelTask( job->errorString() ); - } - } else { - if ( m_newUid > 0 ) { - triggerDeleteJob(); + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "PreDelete select failed: " << job->errorString(); + if (m_newUid > 0) { + recordNewUid(); + } else { + cancelTask(job->errorString()); + } } else { - triggerSearchJob(); + if (m_newUid > 0) { + triggerDeleteJob(); + } else { + triggerSearchJob(); + } } - } } void ChangeItemTask::triggerSearchJob() { - KIMAP::SearchJob *search = new KIMAP::SearchJob( m_session ); + KIMAP::SearchJob *search = new KIMAP::SearchJob(m_session); - search->setUidBased( true ); - search->setSearchLogic( KIMAP::SearchJob::And ); + search->setUidBased(true); + search->setSearchLogic(KIMAP::SearchJob::And); - if ( !m_messageId.isEmpty() ) { - QByteArray header = "Message-ID "; - header+= m_messageId; + if (!m_messageId.isEmpty()) { + QByteArray header = "Message-ID "; + header += m_messageId; - search->addSearchCriteria( KIMAP::SearchJob::Header, header ); - } else { - search->addSearchCriteria( KIMAP::SearchJob::New ); + search->addSearchCriteria(KIMAP::SearchJob::Header, header); + } else { + search->addSearchCriteria(KIMAP::SearchJob::New); - UidNextAttribute *uidNext = item().parentCollection().attribute(); - if ( !uidNext ) { - kWarning() << "Failed to determine new uid."; - cancelTask( i18n( "Could not determine the UID for the newly created message on the server" ) ); - search->deleteLater(); - return; - } - KIMAP::ImapInterval interval( uidNext->uidNext() ); + UidNextAttribute *uidNext = item().parentCollection().attribute(); + if (!uidNext) { + qCWarning(IMAPRESOURCE_LOG) << "Failed to determine new uid."; + cancelTask(i18n("Could not determine the UID for the newly created message on the server")); + search->deleteLater(); + return; + } + KIMAP::ImapInterval interval(uidNext->uidNext()); - search->addSearchCriteria( KIMAP::SearchJob::Uid, interval.toImapSequence() ); - } + search->addSearchCriteria(KIMAP::SearchJob::Uid, interval.toImapSequence()); + } - connect( search, SIGNAL(result(KJob*)), - this, SLOT(onSearchDone(KJob*)) ); + connect(search, &KIMAP::SearchJob::result, this, &ChangeItemTask::onSearchDone); - search->start(); + search->start(); } -void ChangeItemTask::onSearchDone( KJob *job ) +void ChangeItemTask::onSearchDone(KJob *job) { - if ( job->error() ) { - kWarning() << "Search failed: " << job->errorString(); - cancelTask( job->errorString() ); - return; - } + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Search failed: " << job->errorString(); + cancelTask(job->errorString()); + return; + } - KIMAP::SearchJob *search = static_cast( job ); + KIMAP::SearchJob *search = static_cast(job); - if ( search->results().count()!=1 ) { - kWarning() << "Failed to determine new uid."; - cancelTask( i18n( "Could not determine the UID for the newly created message on the server" ) ); - return; - } + if (search->results().count() != 1) { + qCWarning(IMAPRESOURCE_LOG) << "Failed to determine new uid."; + cancelTask(i18n("Could not determine the UID for the newly created message on the server")); + return; + } - m_newUid = search->results().first(); - triggerDeleteJob(); + m_newUid = search->results().at(0); + triggerDeleteJob(); } void ChangeItemTask::triggerDeleteJob() { - KIMAP::StoreJob *store = new KIMAP::StoreJob( m_session ); + KIMAP::StoreJob *store = new KIMAP::StoreJob(m_session); - store->setUidBased( true ); - store->setSequenceSet( KIMAP::ImapSet( m_oldUid ) ); - store->setFlags( QList() << ImapFlags::Deleted ); - store->setMode( KIMAP::StoreJob::AppendFlags ); + store->setUidBased(true); + store->setSequenceSet(KIMAP::ImapSet(m_oldUid)); + store->setFlags(QList() << ImapFlags::Deleted); + store->setMode(KIMAP::StoreJob::AppendFlags); - connect( store, SIGNAL(result(KJob*)), - this, SLOT(onDeleteDone(KJob*)) ); + connect(store, &KIMAP::StoreJob::result, this, &ChangeItemTask::onDeleteDone); - store->start(); + store->start(); } -void ChangeItemTask::onDeleteDone( KJob */*job*/ ) +void ChangeItemTask::onDeleteDone(KJob */*job*/) { - recordNewUid(); + recordNewUid(); } void ChangeItemTask::recordNewUid() { - Q_ASSERT( m_newUid > 0 ); + Q_ASSERT(m_newUid > 0); - Akonadi::Item i = item(); - Akonadi::Collection c = i.parentCollection(); + Akonadi::Item i = item(); + Akonadi::Collection c = i.parentCollection(); - // Get the current uid next value and store it - UidNextAttribute *uidAttr = 0; - int oldNextUid = 0; - if ( c.hasAttribute( "uidnext" ) ) { - uidAttr = static_cast( c.attribute( "uidnext" ) ); - oldNextUid = uidAttr->uidNext(); - } - - // If the uid we just got back is the expected next one of the box - // then update the property to the probable next uid to keep the cache in sync. - // If not something happened in our back, so we don't update and a refetch will - // happen at some point. - if ( m_newUid==oldNextUid ) { - if ( uidAttr==0 ) { - uidAttr = new UidNextAttribute( m_newUid+1 ); - c.addAttribute( uidAttr ); - } else { - uidAttr->setUidNext( m_newUid+1 ); + // Get the current uid next value and store it + UidNextAttribute *uidAttr = Q_NULLPTR; + int oldNextUid = 0; + if (c.hasAttribute("uidnext")) { + uidAttr = static_cast(c.attribute("uidnext")); + oldNextUid = uidAttr->uidNext(); } - applyCollectionChanges( c ); - } - - const QString remoteId = QString::number( m_newUid ); - kDebug( 5327 ) << "Setting remote ID to " << remoteId << " for item with local id " << i.id(); - i.setRemoteId( remoteId ); + // If the uid we just got back is the expected next one of the box + // then update the property to the probable next uid to keep the cache in sync. + // If not something happened in our back, so we don't update and a refetch will + // happen at some point. + if (m_newUid == oldNextUid) { + if (uidAttr == Q_NULLPTR) { + uidAttr = new UidNextAttribute(m_newUid + 1); + c.addAttribute(uidAttr); + } else { + uidAttr->setUidNext(m_newUid + 1); + } - changeCommitted( i ); -} + applyCollectionChanges(c); + } + const QString remoteId = QString::number(m_newUid); + qCDebug(IMAPRESOURCE_LOG) << "Setting remote ID to " << remoteId << " for item with local id " << i.id(); + i.setRemoteId(remoteId); + changeCommitted(i); +} diff -Nru kdepim-runtime-4.14.6/resources/imap/changeitemtask.h kdepim-runtime-15.08.0/resources/imap/changeitemtask.h --- kdepim-runtime-4.14.6/resources/imap/changeitemtask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/changeitemtask.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,36 +26,36 @@ class ChangeItemTask : public ResourceTask { - Q_OBJECT + Q_OBJECT public: - explicit ChangeItemTask( ResourceStateInterface::Ptr resource, QObject *parent = 0 ); - virtual ~ChangeItemTask(); + explicit ChangeItemTask(ResourceStateInterface::Ptr resource, QObject *parent = Q_NULLPTR); + virtual ~ChangeItemTask(); -private slots: - void onAppendMessageDone( KJob *job ); +private Q_SLOTS: + void onAppendMessageDone(KJob *job); - void onPreStoreSelectDone( KJob *job ); - void onStoreFlagsDone( KJob *job ); + void onPreStoreSelectDone(KJob *job); + void onStoreFlagsDone(KJob *job); - void onPreDeleteSelectDone( KJob *job ); - void onSearchDone( KJob *job ); - void onDeleteDone( KJob *job ); + void onPreDeleteSelectDone(KJob *job); + void onSearchDone(KJob *job); + void onDeleteDone(KJob *job); protected: - virtual void doStart( KIMAP::Session *session ); + void doStart(KIMAP::Session *session) Q_DECL_OVERRIDE; private: - void triggerStoreJob(); - void triggerSearchJob(); - void triggerDeleteJob(); - - void recordNewUid(); - - KIMAP::Session *m_session; - QByteArray m_messageId; - qint64 m_oldUid; - qint64 m_newUid; + void triggerStoreJob(); + void triggerSearchJob(); + void triggerDeleteJob(); + + void recordNewUid(); + + KIMAP::Session *m_session; + QByteArray m_messageId; + qint64 m_oldUid; + qint64 m_newUid; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/CMakeLists.txt kdepim-runtime-15.08.0/resources/imap/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/imap/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,19 +1,9 @@ -include_directories( - ${kdepim-runtime_SOURCE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} - ${Boost_INCLUDE_DIR} -) - -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - -option(IMAPRESOURCE_NO_SOLID "Disable the use of solid in the imap resource" FALSE) -if(IMAPRESOURCE_NO_SOLID) - add_definitions( -DIMAPRESOURCE_NO_SOLID=1 ) -endif() +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_imap_resource\") ########### next target ############### set( imapresource_LIB_SRCS + imapresource_debug.cpp addcollectiontask.cpp additemtask.cpp batchfetcher.cpp @@ -40,39 +30,38 @@ retrieveitemstask.cpp searchtask.cpp sessionpool.cpp - timestampattribute.cpp uidvalidityattribute.cpp uidnextattribute.cpp settings.cpp subscriptiondialog.cpp imapidlemanager.cpp resourcestate.cpp + collectionmetadatahelper.cpp + replacemessagejob.cpp + tracer.cpp ${AKONADI_COLLECTIONATTRIBUTES_SHARED_SOURCES} ${AKONADI_IMAPATTRIBUTES_SHARED_SOURCES} ) + + kcfg_generate_dbus_interface( ${CMAKE_CURRENT_SOURCE_DIR}/imapresource.kcfg org.kde.Akonadi.Imap.Settings ) -kde4_add_kcfg_files(imapresource_LIB_SRCS settingsbase.kcfgc) +kconfig_add_kcfg_files(imapresource_LIB_SRCS settingsbase.kcfgc) -qt4_add_dbus_adaptor( imapresource_LIB_SRCS +qt5_add_dbus_adaptor( imapresource_LIB_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.Imap.Settings.xml settings.h Settings ) - - -qt4_generate_dbus_interface( ${CMAKE_CURRENT_SOURCE_DIR}/imapresourcebase.h org.kde.Akonadi.Imap.Resource.xml OPTIONS -a ) -qt4_add_dbus_adaptor( imapresource_LIB_SRCS +qt5_generate_dbus_interface( ${CMAKE_CURRENT_SOURCE_DIR}/imapresourcebase.h org.kde.Akonadi.Imap.Resource.xml OPTIONS -a ) +qt5_add_dbus_adaptor( imapresource_LIB_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.Imap.Resource.xml imapresourcebase.h ImapResourceBase ) -kde4_add_library(imapresource STATIC ${imapresource_LIB_SRCS}) +add_library(imapresource STATIC ${imapresource_LIB_SRCS}) -target_link_libraries(imapresource ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTDBUS_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${KDEPIMLIBS_KIMAP_LIBS} ${KDEPIMLIBS_MAILTRANSPORT_LIBS} ${KDE4_KIO_LIBS} ${KDEPIMLIBS_KMIME_LIBS} ${KDEPIMLIBS_AKONADI_KMIME_LIBS} ${KDEPIMLIBS_KPIMIDENTITIES_LIBS}) +target_link_libraries(imapresource KF5::AkonadiCore KF5::IMAP KF5::MailTransport KF5::KIOCore KF5::Mime KF5::AkonadiMime KF5::IdentityManagement KF5::AkonadiAgentBase KF5::I18n) -if( NOT IMAPRESOURCE_NO_SOLID) - target_link_libraries(imapresource ${KDE4_SOLID_LIBS}) -endif() ########### next target ############### set( akonadi_imap_resource_SRCS @@ -84,40 +73,38 @@ serverinfodialog.cpp ) -install( FILES imapresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) +install( FILES imapresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) if (KDEPIM_MOBILE_UI) -kde4_add_ui_files(akonadi_imap_resource_SRCS setupserverview_mobile.ui) +ki18n_wrap_ui(akonadi_imap_resource_SRCS setupserverview_mobile.ui) else () -kde4_add_ui_files(akonadi_imap_resource_SRCS setupserverview_desktop.ui) +ki18n_wrap_ui(akonadi_imap_resource_SRCS setupserverview_desktop.ui) endif () -kde4_add_ui_files(akonadi_imap_resource_SRCS serverinfo.ui) - - +ki18n_wrap_ui(akonadi_imap_resource_SRCS serverinfo.ui) if (RUNTIME_PLUGINS_STATIC) add_definitions(-DMAIL_SERIALIZER_PLUGIN_STATIC) endif () -kde4_add_executable(akonadi_imap_resource ${akonadi_imap_resource_SRCS}) +add_executable(akonadi_imap_resource ${akonadi_imap_resource_SRCS}) -if (Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_imap_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) set_target_properties(akonadi_imap_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.Imap") set_target_properties(akonadi_imap_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi IMAP Resource") endif () -target_link_libraries(akonadi_imap_resource ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTDBUS_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${KDEPIMLIBS_KIMAP_LIBS} ${KDEPIMLIBS_MAILTRANSPORT_LIBS} ${KDE4_KIO_LIBS} ${KDEPIMLIBS_KMIME_LIBS} ${KDEPIMLIBS_AKONADI_KMIME_LIBS} ${KDEPIMLIBS_KPIMIDENTITIES_LIBS} imapresource folderarchivesettings) +target_link_libraries(akonadi_imap_resource KF5::AkonadiCore KF5::AkonadiWidgets KF5::IMAP KF5::MailTransport KF5::KIOCore KF5::Mime KF5::AkonadiMime KF5::IdentityManagement imapresource folderarchivesettings KF5::I18n akonadi-singlefileresource) if (RUNTIME_PLUGINS_STATIC) target_link_libraries(akonadi_imap_resource akonadi_serializer_mail) endif () -if( NOT IMAPRESOURCE_NO_SOLID) -target_link_libraries(akonadi_imap_resource ${KDE4_SOLID_LIBS}) -endif() - -install(TARGETS akonadi_imap_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(TARGETS akonadi_imap_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) add_subdirectory( wizard ) -add_subdirectory( tests ) + +if(BUILD_TESTING) + add_subdirectory( autotests ) + add_subdirectory( tests ) +endif() diff -Nru kdepim-runtime-4.14.6/resources/imap/collectionmetadatahelper.cpp kdepim-runtime-15.08.0/resources/imap/collectionmetadatahelper.cpp --- kdepim-runtime-4.14.6/resources/imap/collectionmetadatahelper.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/collectionmetadatahelper.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,88 @@ +/* + Copyright (c) 2014 Christian Mollekopf + + 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 "collectionmetadatahelper.h" +#include + +Akonadi::Collection::Rights CollectionMetadataHelper::convertRights(const KIMAP::Acl::Rights imapRights, KIMAP::Acl::Rights parentRights) +{ + Akonadi::Collection::Rights newRights = Akonadi::Collection::ReadOnly; + + // For renaming, the parent folder needs to have the CreateMailbox or Create permission. + // We map renaming to CanChangeCollection here, which is not entirely correct, but we have no + // CanRenameCollection flag. + if (parentRights & KIMAP::Acl::CreateMailbox || + parentRights & KIMAP::Acl::Create) { + newRights |= Akonadi::Collection::CanChangeCollection; + } + + if (imapRights & KIMAP::Acl::Write) { + newRights |= Akonadi::Collection::CanChangeItem; + } + + if (imapRights & KIMAP::Acl::Insert) { + newRights |= Akonadi::Collection::CanCreateItem; + } + + if (imapRights & (KIMAP::Acl::DeleteMessage | KIMAP::Acl::Delete)) { + newRights |= Akonadi::Collection::CanDeleteItem; + } + + if (imapRights & (KIMAP::Acl::CreateMailbox | KIMAP::Acl::Create)) { + newRights |= Akonadi::Collection::CanCreateCollection; + } + + if (imapRights & (KIMAP::Acl::DeleteMailbox | KIMAP::Acl::Delete)) { + newRights |= Akonadi::Collection::CanDeleteCollection; + } + return newRights; +} + +bool CollectionMetadataHelper::applyRights(Akonadi::Collection &collection, const KIMAP::Acl::Rights imapRights, KIMAP::Acl::Rights parentRights) +{ + Akonadi::Collection::Rights newRights = convertRights(imapRights, parentRights); + + if (collection.hasAttribute("noinferiors")) { + newRights &= ~Akonadi::Collection::CanCreateCollection; + } + + if (collection.parentCollection().hasAttribute("noselect")) { + newRights &= ~Akonadi::Collection::CanChangeCollection; + } + + //This can result in false positives for new collections with defaults access rights. + //The caller needs to handles those. + bool accessRevoked = false; + if ((collection.rights() & Akonadi::Collection::CanCreateItem) && + !(newRights & Akonadi::Collection::CanCreateItem)) { + // write access revoked + accessRevoked = true; + } + + // kDebug(5327) << collection.remoteId() + // << "imapRights:" << imapRights + // << "newRights:" << newRights + // << "oldRights:" << collection.rights(); + + if (newRights != collection.rights()) { + collection.setRights(newRights); + } + return accessRevoked; +} + diff -Nru kdepim-runtime-4.14.6/resources/imap/collectionmetadatahelper.h kdepim-runtime-15.08.0/resources/imap/collectionmetadatahelper.h --- kdepim-runtime-4.14.6/resources/imap/collectionmetadatahelper.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/collectionmetadatahelper.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,32 @@ +/* + Copyright (c) 2014 Christian Mollekopf + + 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 COLLECTIONMETADATAHELPER_H +#define COLLECTIONMETADATAHELPER_H + +#include +#include + +class CollectionMetadataHelper +{ +public: + static Akonadi::Collection::Rights convertRights(const KIMAP::Acl::Rights imapRights, KIMAP::Acl::Rights parentRights); + static bool applyRights(Akonadi::Collection &collection, const KIMAP::Acl::Rights imapRights, KIMAP::Acl::Rights parentRights); +}; + +#endif diff -Nru kdepim-runtime-4.14.6/resources/imap/expungecollectiontask.cpp kdepim-runtime-15.08.0/resources/imap/expungecollectiontask.cpp --- kdepim-runtime-4.14.6/resources/imap/expungecollectiontask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/expungecollectiontask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,8 +21,10 @@ #include "expungecollectiontask.h" -#include -#include +#include "imapresource_debug.h" +#include "imapresource_debug.h" + +#include #include #include @@ -30,8 +32,8 @@ #include "noselectattribute.h" -ExpungeCollectionTask::ExpungeCollectionTask( ResourceStateInterface::Ptr resource, QObject *parent ) - : ResourceTask( CancelIfNoSession, resource, parent ) +ExpungeCollectionTask::ExpungeCollectionTask(ResourceStateInterface::Ptr resource, QObject *parent) + : ResourceTask(CancelIfNoSession, resource, parent) { } @@ -40,62 +42,58 @@ { } -void ExpungeCollectionTask::doStart( KIMAP::Session *session ) +void ExpungeCollectionTask::doStart(KIMAP::Session *session) { - // Prevent expunging items from noselect folders. - if ( collection().hasAttribute( "noselect" ) ) { - NoSelectAttribute* noselect = static_cast( collection().attribute( "noselect" ) ); - if ( noselect->noSelect() ) { - kDebug( 5327 ) << "No Select folder"; - taskDone(); - return; + // Prevent expunging items from noselect folders. + if (collection().hasAttribute("noselect")) { + NoSelectAttribute *noselect = static_cast(collection().attribute("noselect")); + if (noselect->noSelect()) { + qCDebug(IMAPRESOURCE_LOG) << "No Select folder"; + taskDone(); + return; + } } - } - const QString mailBox = mailBoxForCollection( collection() ); + const QString mailBox = mailBoxForCollection(collection()); - if ( session->selectedMailBox() != mailBox ) { - KIMAP::SelectJob *select = new KIMAP::SelectJob( session ); - select->setMailBox( mailBox ); + if (session->selectedMailBox() != mailBox) { + KIMAP::SelectJob *select = new KIMAP::SelectJob(session); + select->setMailBox(mailBox); - connect( select, SIGNAL(result(KJob*)), - this, SLOT(onSelectDone(KJob*)) ); + connect(select, &KIMAP::SelectJob::result, this, &ExpungeCollectionTask::onSelectDone); - select->start(); + select->start(); - } else { - triggerExpungeJob( session ); - } + } else { + triggerExpungeJob(session); + } } -void ExpungeCollectionTask::onSelectDone( KJob *job ) +void ExpungeCollectionTask::onSelectDone(KJob *job) { - if ( job->error() ) { - cancelTask( job->errorString() ); - } else { - KIMAP::SelectJob *select = static_cast( job ); - triggerExpungeJob( select->session() ); - } + if (job->error()) { + cancelTask(job->errorString()); + } else { + KIMAP::SelectJob *select = static_cast(job); + triggerExpungeJob(select->session()); + } } -void ExpungeCollectionTask::triggerExpungeJob( KIMAP::Session *session ) +void ExpungeCollectionTask::triggerExpungeJob(KIMAP::Session *session) { - KIMAP::ExpungeJob *expunge = new KIMAP::ExpungeJob( session ); + KIMAP::ExpungeJob *expunge = new KIMAP::ExpungeJob(session); - connect( expunge, SIGNAL(result(KJob*)), - this, SLOT(onExpungeDone(KJob*)) ); + connect(expunge, &KIMAP::ExpungeJob::result, this, &ExpungeCollectionTask::onExpungeDone); - expunge->start(); + expunge->start(); } -void ExpungeCollectionTask::onExpungeDone( KJob *job ) +void ExpungeCollectionTask::onExpungeDone(KJob *job) { - if ( job->error() ) { - cancelTask( job->errorString() ); - } else { - taskDone(); - } + if (job->error()) { + cancelTask(job->errorString()); + } else { + taskDone(); + } } - - diff -Nru kdepim-runtime-4.14.6/resources/imap/expungecollectiontask.h kdepim-runtime-15.08.0/resources/imap/expungecollectiontask.h --- kdepim-runtime-4.14.6/resources/imap/expungecollectiontask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/expungecollectiontask.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,21 +26,21 @@ class ExpungeCollectionTask : public ResourceTask { - Q_OBJECT + Q_OBJECT public: - explicit ExpungeCollectionTask( ResourceStateInterface::Ptr resource, QObject *parent = 0 ); - virtual ~ExpungeCollectionTask(); + explicit ExpungeCollectionTask(ResourceStateInterface::Ptr resource, QObject *parent = Q_NULLPTR); + virtual ~ExpungeCollectionTask(); -private slots: - void onSelectDone( KJob *job ); - void onExpungeDone( KJob *job ); +private Q_SLOTS: + void onSelectDone(KJob *job); + void onExpungeDone(KJob *job); protected: - virtual void doStart( KIMAP::Session *session ); + void doStart(KIMAP::Session *session) Q_DECL_OVERRIDE; private: - void triggerExpungeJob( KIMAP::Session *session ); + void triggerExpungeJob(KIMAP::Session *session); }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/highestmodseqattribute.cpp kdepim-runtime-15.08.0/resources/imap/highestmodseqattribute.cpp --- kdepim-runtime-4.14.6/resources/imap/highestmodseqattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/highestmodseqattribute.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,13 +21,13 @@ #include -HighestModSeqAttribute::HighestModSeqAttribute( qint64 highestModSequence ): +HighestModSeqAttribute::HighestModSeqAttribute(qint64 highestModSequence): Akonadi::Attribute(), - m_highestModSeq( highestModSequence ) + m_highestModSeq(highestModSequence) { } -void HighestModSeqAttribute::setHighestModSeq( qint64 highestModSequence ) +void HighestModSeqAttribute::setHighestModSeq(qint64 highestModSequence) { m_highestModSeq = highestModSequence; } @@ -37,23 +37,23 @@ return m_highestModSeq; } -Akonadi::Attribute* HighestModSeqAttribute::clone() const +Akonadi::Attribute *HighestModSeqAttribute::clone() const { - return new HighestModSeqAttribute( m_highestModSeq ); + return new HighestModSeqAttribute(m_highestModSeq); } QByteArray HighestModSeqAttribute::type() const { - static const QByteArray sType( "highestmodseq" ); + static const QByteArray sType("highestmodseq"); return sType; } -void HighestModSeqAttribute::deserialize( const QByteArray &data ) +void HighestModSeqAttribute::deserialize(const QByteArray &data) { m_highestModSeq = data.toLongLong(); } QByteArray HighestModSeqAttribute::serialized() const { - return QByteArray::number( m_highestModSeq ); + return QByteArray::number(m_highestModSeq); } diff -Nru kdepim-runtime-4.14.6/resources/imap/highestmodseqattribute.h kdepim-runtime-15.08.0/resources/imap/highestmodseqattribute.h --- kdepim-runtime-4.14.6/resources/imap/highestmodseqattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/highestmodseqattribute.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,21 +20,21 @@ #ifndef HIGHESTMODSEQATTRIBUTE_H #define HIGHESTMODSEQATTRIBUTE_H -#include +#include class HighestModSeqAttribute : public Akonadi::Attribute { - public: - explicit HighestModSeqAttribute( qint64 highestModSequence = -1 ); - void setHighestModSeq( qint64 highestModSequence ); +public: + explicit HighestModSeqAttribute(qint64 highestModSequence = -1); + void setHighestModSeq(qint64 highestModSequence); qint64 highestModSequence() const; - virtual void deserialize(const QByteArray& data); - virtual QByteArray serialized() const; - virtual Akonadi::Attribute* clone() const; - virtual QByteArray type() const; + void deserialize(const QByteArray &data) Q_DECL_OVERRIDE; + QByteArray serialized() const Q_DECL_OVERRIDE; + Akonadi::Attribute *clone() const Q_DECL_OVERRIDE; + QByteArray type() const Q_DECL_OVERRIDE; - private: +private: qint64 m_highestModSeq; }; diff -Nru kdepim-runtime-4.14.6/resources/imap/imapaccount.cpp kdepim-runtime-15.08.0/resources/imap/imapaccount.cpp --- kdepim-runtime-4.14.6/resources/imap/imapaccount.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/imapaccount.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,11 +26,11 @@ #include "imapaccount.h" ImapAccount::ImapAccount() - : m_port( 0 ), - m_timeout( 30 ), - m_encryption( KIMAP::LoginJob::Unencrypted ), - m_authentication( KIMAP::LoginJob::ClearText ), - m_subscriptionEnabled( false ) + : m_port(0), + m_timeout(30), + m_encryption(KIMAP::LoginJob::Unencrypted), + m_authentication(KIMAP::LoginJob::ClearText), + m_subscriptionEnabled(false) { } @@ -38,72 +38,72 @@ { } -void ImapAccount::setServer( const QString &server ) +void ImapAccount::setServer(const QString &server) { - m_server = server; + m_server = server; } QString ImapAccount::server() const { - return m_server; + return m_server; } -void ImapAccount::setPort( quint16 port ) +void ImapAccount::setPort(quint16 port) { - m_port = port; + m_port = port; } quint16 ImapAccount::port() const { - return m_port; + return m_port; } -void ImapAccount::setUserName( const QString &userName ) +void ImapAccount::setUserName(const QString &userName) { - m_userName = userName; + m_userName = userName; } QString ImapAccount::userName() const { - return m_userName; + return m_userName; } -void ImapAccount::setEncryptionMode( KIMAP::LoginJob::EncryptionMode mode) +void ImapAccount::setEncryptionMode(KIMAP::LoginJob::EncryptionMode mode) { - m_encryption = mode; + m_encryption = mode; } KIMAP::LoginJob::EncryptionMode ImapAccount::encryptionMode() const { - return m_encryption; + return m_encryption; } -void ImapAccount::setAuthenticationMode( KIMAP::LoginJob::AuthenticationMode mode) +void ImapAccount::setAuthenticationMode(KIMAP::LoginJob::AuthenticationMode mode) { - m_authentication = mode; + m_authentication = mode; } KIMAP::LoginJob::AuthenticationMode ImapAccount::authenticationMode() const { - return m_authentication; + return m_authentication; } -void ImapAccount::setSubscriptionEnabled( bool enabled ) +void ImapAccount::setSubscriptionEnabled(bool enabled) { - m_subscriptionEnabled = enabled; + m_subscriptionEnabled = enabled; } bool ImapAccount::isSubscriptionEnabled() const { - return m_subscriptionEnabled; + return m_subscriptionEnabled; } void ImapAccount::setTimeout(int timeout) { - m_timeout = timeout; + m_timeout = timeout; } int ImapAccount::timeout() const { - return m_timeout; + return m_timeout; } diff -Nru kdepim-runtime-4.14.6/resources/imap/imapaccount.h kdepim-runtime-15.08.0/resources/imap/imapaccount.h --- kdepim-runtime-4.14.6/resources/imap/imapaccount.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/imapaccount.h 2015-08-10 21:01:02.000000000 +0000 @@ -31,39 +31,39 @@ class ImapAccount { public: - explicit ImapAccount(); - ~ImapAccount(); + explicit ImapAccount(); + ~ImapAccount(); - void setServer( const QString &server ); - QString server() const; + void setServer(const QString &server); + QString server() const; - void setPort( quint16 port ); - quint16 port() const; + void setPort(quint16 port); + quint16 port() const; - void setUserName( const QString &userName ); - QString userName() const; + void setUserName(const QString &userName); + QString userName() const; - void setEncryptionMode( KIMAP::LoginJob::EncryptionMode mode ); - KIMAP::LoginJob::EncryptionMode encryptionMode() const; + void setEncryptionMode(KIMAP::LoginJob::EncryptionMode mode); + KIMAP::LoginJob::EncryptionMode encryptionMode() const; - void setAuthenticationMode( KIMAP::LoginJob::AuthenticationMode mode ); - KIMAP::LoginJob::AuthenticationMode authenticationMode() const; + void setAuthenticationMode(KIMAP::LoginJob::AuthenticationMode mode); + KIMAP::LoginJob::AuthenticationMode authenticationMode() const; - void setSubscriptionEnabled( bool enabled ); - bool isSubscriptionEnabled() const; + void setSubscriptionEnabled(bool enabled); + bool isSubscriptionEnabled() const; - void setTimeout( int timeout ); - int timeout() const; + void setTimeout(int timeout); + int timeout() const; private: - QString m_name; - QString m_server; - quint16 m_port; - QString m_userName; - int m_timeout; - KIMAP::LoginJob::EncryptionMode m_encryption; - KIMAP::LoginJob::AuthenticationMode m_authentication; - bool m_subscriptionEnabled; + QString m_name; + QString m_server; + quint16 m_port; + QString m_userName; + int m_timeout; + KIMAP::LoginJob::EncryptionMode m_encryption; + KIMAP::LoginJob::AuthenticationMode m_authentication; + bool m_subscriptionEnabled; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/imapflags.cpp kdepim-runtime-15.08.0/resources/imap/imapflags.cpp --- kdepim-runtime-4.14.6/resources/imap/imapflags.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/imapflags.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,7 +20,7 @@ #include "imapflags.h" -const char* ImapFlags::Seen = "\\Seen"; -const char* ImapFlags::Deleted = "\\Deleted"; -const char* ImapFlags::Answered = "\\Answered"; -const char* ImapFlags::Flagged = "\\Flagged"; +const char *ImapFlags::Seen = "\\Seen"; +const char *ImapFlags::Deleted = "\\Deleted"; +const char *ImapFlags::Answered = "\\Answered"; +const char *ImapFlags::Flagged = "\\Flagged"; diff -Nru kdepim-runtime-4.14.6/resources/imap/imapflags.h kdepim-runtime-15.08.0/resources/imap/imapflags.h --- kdepim-runtime-4.14.6/resources/imap/imapflags.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/imapflags.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,25 +26,25 @@ */ namespace ImapFlags { - /** - * The flag for a message being seen (i.e. opened by user). - */ - extern const char* Seen; +/** + * The flag for a message being seen (i.e. opened by user). + */ +extern const char *Seen; - /** - * The flag for a message being deleted by the user. - */ - extern const char* Deleted; +/** + * The flag for a message being deleted by the user. + */ +extern const char *Deleted; - /** - * The flag for a message being replied to by the user. - */ - extern const char* Answered; +/** + * The flag for a message being replied to by the user. + */ +extern const char *Answered; - /** - * The flag for a message being marked as flagged. - */ - extern const char* Flagged; +/** + * The flag for a message being marked as flagged. + */ +extern const char *Flagged; } diff -Nru kdepim-runtime-4.14.6/resources/imap/imapidlemanager.cpp kdepim-runtime-15.08.0/resources/imap/imapidlemanager.cpp --- kdepim-runtime-4.14.6/resources/imap/imapidlemanager.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/imapidlemanager.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -25,7 +25,8 @@ #include "imapidlemanager.h" -#include +#include "imapresource_debug.h" +#include "imapresource_debug.h" #include #include @@ -36,150 +37,139 @@ #include "imapresource.h" #include "sessionpool.h" -ImapIdleManager::ImapIdleManager( ResourceStateInterface::Ptr state, - SessionPool *pool, ImapResourceBase *parent ) - : QObject( parent ), m_sessionRequestId( 0 ), m_pool( pool ), m_session( 0 ), - m_idle( 0 ), m_resource( parent ), m_state( state ), - m_lastMessageCount( -1 ), m_lastRecentCount( -1 ) -{ - connect( pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString)), - this, SLOT(onSessionRequestDone(qint64,KIMAP::Session*,int,QString)) ); - m_sessionRequestId = m_pool->requestSession(); +ImapIdleManager::ImapIdleManager(ResourceStateInterface::Ptr state, + SessionPool *pool, ImapResourceBase *parent) + : QObject(parent), m_sessionRequestId(0), m_pool(pool), m_session(Q_NULLPTR), + m_idle(Q_NULLPTR), m_resource(parent), m_state(state), + m_lastMessageCount(-1), m_lastRecentCount(-1) +{ + connect(pool, &SessionPool::sessionRequestDone, this, &ImapIdleManager::onSessionRequestDone); + m_sessionRequestId = m_pool->requestSession(); } ImapIdleManager::~ImapIdleManager() { - stop(); - if ( m_pool ) { - if ( m_sessionRequestId ) { - m_pool->cancelSessionRequest( m_sessionRequestId ); - } - if ( m_session ) { - m_pool->releaseSession( m_session ); + stop(); + if (m_pool) { + if (m_sessionRequestId) { + m_pool->cancelSessionRequest(m_sessionRequestId); + } + if (m_session) { + m_pool->releaseSession(m_session); + } } - } } void ImapIdleManager::stop() { - if ( m_idle ) { - m_idle->stop(); - disconnect(m_idle, 0, this, 0); - m_idle = 0; - } - if ( m_pool ) { - disconnect(m_pool, 0, this, 0); - } + if (m_idle) { + m_idle->stop(); + disconnect(m_idle, Q_NULLPTR, this, Q_NULLPTR); + m_idle = Q_NULLPTR; + } + if (m_pool) { + disconnect(m_pool, Q_NULLPTR, this, Q_NULLPTR); + } } KIMAP::Session *ImapIdleManager::session() const { - return m_session; + return m_session; } void ImapIdleManager::reconnect() { - kDebug() << "attempting to reconnect IDLE session"; - if ( m_session == 0 && m_pool->isConnected() && m_sessionRequestId == 0 ) - m_sessionRequestId = m_pool->requestSession(); + qCDebug(IMAPRESOURCE_LOG) << "attempting to reconnect IDLE session"; + if (m_session == Q_NULLPTR && m_pool->isConnected() && m_sessionRequestId == 0) { + m_sessionRequestId = m_pool->requestSession(); + } +} + +void ImapIdleManager::onSessionRequestDone(qint64 requestId, KIMAP::Session *session, + int errorCode, const QString &/*errorString*/) +{ + if (requestId != m_sessionRequestId || session == Q_NULLPTR || errorCode != SessionPool::NoError) { + return; + } + + m_session = session; + m_sessionRequestId = 0; + + connect(m_pool, &SessionPool::connectionLost, this, &ImapIdleManager::onConnectionLost); + connect(m_pool, &SessionPool::disconnectDone, this, &ImapIdleManager::onPoolDisconnect); + + KIMAP::SelectJob *select = new KIMAP::SelectJob(m_session); + select->setMailBox(m_state->mailBoxForCollection(m_state->collection())); + connect(select, &KIMAP::SelectJob::result, this, &ImapIdleManager::onSelectDone); + select->start(); + + m_idle = new KIMAP::IdleJob(m_session); + connect(m_idle.data(), &KIMAP::IdleJob::mailBoxStats, this, &ImapIdleManager::onStatsReceived); + connect(m_idle.data(), &KIMAP::IdleJob::mailBoxMessageFlagsChanged, this, &ImapIdleManager::onFlagsChanged); + connect(m_idle.data(), &KIMAP::IdleJob::result, this, &ImapIdleManager::onIdleStopped); + m_idle->start(); } -void ImapIdleManager::onSessionRequestDone( qint64 requestId, KIMAP::Session *session, - int errorCode, const QString &/*errorString*/ ) +void ImapIdleManager::onConnectionLost(KIMAP::Session *session) { - if ( requestId!=m_sessionRequestId || session==0 || errorCode!=SessionPool::NoError ) { - return; - } - - m_session = session; - m_sessionRequestId = 0; - - connect( m_pool, SIGNAL(connectionLost(KIMAP::Session*)), - this, SLOT(onConnectionLost(KIMAP::Session*)) ); - connect( m_pool, SIGNAL(disconnectDone()), - this, SLOT(onPoolDisconnect()) ); - - - KIMAP::SelectJob *select = new KIMAP::SelectJob( m_session ); - select->setMailBox( m_state->mailBoxForCollection( m_state->collection() ) ); - connect( select, SIGNAL(result(KJob*)), - this, SLOT(onSelectDone(KJob*)) ); - select->start(); - - m_idle = new KIMAP::IdleJob( m_session ); - connect( m_idle, SIGNAL(mailBoxStats(KIMAP::IdleJob*,QString,int,int)), - this, SLOT(onStatsReceived(KIMAP::IdleJob*,QString,int,int)) ); - connect( m_idle, SIGNAL(mailBoxMessageFlagsChanged(KIMAP::IdleJob*,qint64)), - this, SLOT(onFlagsChanged(KIMAP::IdleJob*)) ); - connect( m_idle, SIGNAL(result(KJob*)), - this, SLOT(onIdleStopped()) ); - m_idle->start(); -} - -void ImapIdleManager::onConnectionLost( KIMAP::Session *session ) -{ - if ( session == m_session ) { - // Our session becomes invalid, so get ride of - // the pointer, we don't need to release it once the - // task is done - m_session = 0; - QMetaObject::invokeMethod( this, "reconnect", Qt::QueuedConnection ); - } + if (session == m_session) { + // Our session becomes invalid, so get ride of + // the pointer, we don't need to release it once the + // task is done + m_session = Q_NULLPTR; + QMetaObject::invokeMethod(this, "reconnect", Qt::QueuedConnection); + } } void ImapIdleManager::onPoolDisconnect() { - // All the sessions in the pool we used changed, - // so get ride of the pointer, we don't need to - // release our session anymore - m_pool = 0; + // All the sessions in the pool we used changed, + // so get ride of the pointer, we don't need to + // release our session anymore + m_pool = Q_NULLPTR; } -void ImapIdleManager::onSelectDone( KJob *job ) +void ImapIdleManager::onSelectDone(KJob *job) { - KIMAP::SelectJob *select = static_cast( job ); + KIMAP::SelectJob *select = static_cast(job); - m_lastMessageCount = select->messageCount(); - m_lastRecentCount = select->recentCount(); + m_lastMessageCount = select->messageCount(); + m_lastRecentCount = select->recentCount(); } void ImapIdleManager::onIdleStopped() { - kDebug( 5327 ) << "IDLE dropped maybe we should reconnect?"; - m_idle = 0; - if ( m_session ) { - kDebug( 5327 ) << "Restarting the IDLE session!"; - m_idle = new KIMAP::IdleJob( m_session ); - connect( m_idle, SIGNAL(mailBoxStats(KIMAP::IdleJob*,QString,int,int)), - this, SLOT(onStatsReceived(KIMAP::IdleJob*,QString,int,int)) ); - connect( m_idle, SIGNAL(result(KJob*)), - this, SLOT(onIdleStopped()) ); - m_idle->start(); - } + qCDebug(IMAPRESOURCE_LOG) << "IDLE dropped maybe we should reconnect?"; + m_idle = Q_NULLPTR; + if (m_session) { + qCDebug(IMAPRESOURCE_LOG) << "Restarting the IDLE session!"; + m_idle = new KIMAP::IdleJob(m_session); + connect(m_idle.data(), &KIMAP::IdleJob::mailBoxStats, this, &ImapIdleManager::onStatsReceived); + connect(m_idle.data(), &KIMAP::IdleJob::result, this, &ImapIdleManager::onIdleStopped); + m_idle->start(); + } } void ImapIdleManager::onStatsReceived(KIMAP::IdleJob *job, const QString &mailBox, int messageCount, int recentCount) { - kDebug( 5327 ) << "IDLE stats received:" << job << mailBox << messageCount << recentCount; - kDebug( 5327 ) << "Cached information:" << m_state->collection().remoteId() << m_state->collection().id() - << m_lastMessageCount << m_lastRecentCount; - - // It seems we're not in sync with the cache, resync is needed - if ( messageCount!=m_lastMessageCount || recentCount!=m_lastRecentCount ) { - m_lastMessageCount = messageCount; - m_lastRecentCount = recentCount; + qCDebug(IMAPRESOURCE_LOG) << "IDLE stats received:" << job << mailBox << messageCount << recentCount; + qCDebug(IMAPRESOURCE_LOG) << "Cached information:" << m_state->collection().remoteId() << m_state->collection().id() + << m_lastMessageCount << m_lastRecentCount; + + // It seems we're not in sync with the cache, resync is needed + if (messageCount != m_lastMessageCount || recentCount != m_lastRecentCount) { + m_lastMessageCount = messageCount; + m_lastRecentCount = recentCount; - kDebug( 5327 ) << "Resync needed for" << mailBox << m_state->collection().id(); - m_resource->synchronizeCollection( m_state->collection().id() ); - } + qCDebug(IMAPRESOURCE_LOG) << "Resync needed for" << mailBox << m_state->collection().id(); + m_resource->synchronizeCollection(m_state->collection().id()); + } } -void ImapIdleManager::onFlagsChanged( KIMAP::IdleJob *job ) +void ImapIdleManager::onFlagsChanged(KIMAP::IdleJob *job) { - kDebug( 5327 ) << "IDLE flags changed in" << m_session->selectedMailBox(); - m_resource->synchronizeCollection( m_state->collection().id() ); + qCDebug(IMAPRESOURCE_LOG) << "IDLE flags changed in" << m_session->selectedMailBox(); + m_resource->synchronizeCollection(m_state->collection().id()); } - - diff -Nru kdepim-runtime-4.14.6/resources/imap/imapidlemanager.h kdepim-runtime-15.08.0/resources/imap/imapidlemanager.h --- kdepim-runtime-4.14.6/resources/imap/imapidlemanager.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/imapidlemanager.h 2015-08-10 21:01:02.000000000 +0000 @@ -28,15 +28,15 @@ #include "resourcestateinterface.h" -#include +#include #include #include namespace KIMAP { - class IdleJob; - class Session; +class IdleJob; +class Session; } class ImapResourceBase; @@ -46,37 +46,37 @@ class ImapIdleManager : public QObject { - Q_OBJECT + Q_OBJECT public: - ImapIdleManager( ResourceStateInterface::Ptr state, SessionPool *pool, ImapResourceBase *parent ); - ~ImapIdleManager(); - void stop(); - - KIMAP::Session *session() const; - -private slots: - void onConnectionLost( KIMAP::Session *session ); - void onPoolDisconnect(); - - void onSessionRequestDone( qint64 requestId, KIMAP::Session *session, - int errorCode, const QString &errorString ); - void onSelectDone( KJob *job ); - void onIdleStopped(); - void onStatsReceived( KIMAP::IdleJob *job, const QString &mailBox, - int messageCount, int recentCount ); - void onFlagsChanged( KIMAP::IdleJob *job ); - void reconnect(); + ImapIdleManager(ResourceStateInterface::Ptr state, SessionPool *pool, ImapResourceBase *parent); + ~ImapIdleManager(); + void stop(); + + KIMAP::Session *session() const; + +private Q_SLOTS: + void onConnectionLost(KIMAP::Session *session); + void onPoolDisconnect(); + + void onSessionRequestDone(qint64 requestId, KIMAP::Session *session, + int errorCode, const QString &errorString); + void onSelectDone(KJob *job); + void onIdleStopped(); + void onStatsReceived(KIMAP::IdleJob *job, const QString &mailBox, + int messageCount, int recentCount); + void onFlagsChanged(KIMAP::IdleJob *job); + void reconnect(); private: - qint64 m_sessionRequestId; - SessionPool *m_pool; - KIMAP::Session *m_session; - QPointer m_idle; - ImapResourceBase *m_resource; - ResourceStateInterface::Ptr m_state; - qint64 m_lastMessageCount; - qint64 m_lastRecentCount; + qint64 m_sessionRequestId; + SessionPool *m_pool; + KIMAP::Session *m_session; + QPointer m_idle; + ImapResourceBase *m_resource; + ResourceStateInterface::Ptr m_state; + qint64 m_lastMessageCount; + qint64 m_lastRecentCount; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/imapresourcebase.cpp kdepim-runtime-15.08.0/resources/imap/imapresourcebase.cpp --- kdepim-runtime-4.14.6/resources/imap/imapresourcebase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/imapresourcebase.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -28,29 +28,30 @@ #include #include -#include -#include -#include +#include +#include "imapresource_debug.h" +#include + #include -#include +#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include "collectionannotationsattribute.h" #include "collectionflagsattribute.h" #include "imapaclattribute.h" #include "imapquotaattribute.h" #include "noselectattribute.h" -#include "timestampattribute.h" #include "uidvalidityattribute.h" #include "uidnextattribute.h" #include "highestmodseqattribute.h" @@ -93,456 +94,448 @@ using namespace Akonadi; -ImapResourceBase::ImapResourceBase( const QString &id ) - : ResourceBase( id ), - m_pool( new SessionPool( 2, this ) ), - mSubscriptions( 0 ), - m_idle( 0 ), - m_settings( 0 ) -{ - QTimer::singleShot( 0, this, SLOT(updateResourceName()) ); - - connect( m_pool, SIGNAL(connectDone(int,QString)), - this, SLOT(onConnectDone(int,QString)) ); - connect( m_pool, SIGNAL(connectionLost(KIMAP::Session*)), - this, SLOT(onConnectionLost(KIMAP::Session*)) ); - - Akonadi::AttributeFactory::registerAttribute(); - Akonadi::AttributeFactory::registerAttribute(); - Akonadi::AttributeFactory::registerAttribute(); - Akonadi::AttributeFactory::registerAttribute(); - Akonadi::AttributeFactory::registerAttribute(); - - Akonadi::AttributeFactory::registerAttribute(); - Akonadi::AttributeFactory::registerAttribute(); - - Akonadi::AttributeFactory::registerAttribute(); - Akonadi::AttributeFactory::registerAttribute(); - - // For QMetaObject::invokeMethod() - qRegisterMetaType >(); - - changeRecorder()->fetchCollection( true ); - changeRecorder()->collectionFetchScope().setAncestorRetrieval( CollectionFetchScope::All ); - changeRecorder()->collectionFetchScope().setIncludeStatistics( true ); - changeRecorder()->itemFetchScope().fetchFullPayload( true ); - changeRecorder()->itemFetchScope().setAncestorRetrieval( ItemFetchScope::All ); - changeRecorder()->itemFetchScope().setFetchModificationTime( false ); - //(Andras) disable now, as tokoe reported problems with it and the mail filter: changeRecorder()->fetchChangedOnly( true ); - - setHierarchicalRemoteIdentifiersEnabled( true ); - setItemTransactionMode( ItemSync::MultipleTransactions ); // we can recover from incomplete syncs, so we can use a faster mode - ItemFetchScope scope( changeRecorder()->itemFetchScope() ); - scope.fetchFullPayload( false ); - scope.setAncestorRetrieval( ItemFetchScope::None ); - setItemSynchronizationFetchScope( scope ); - setDisableAutomaticItemDeliveryDone( true ); - setItemSyncBatchSize( 100 ); - - connect( this, SIGNAL(reloadConfiguration()), SLOT(reconnect()) ); - - - m_statusMessageTimer = new QTimer( this ); - m_statusMessageTimer->setSingleShot( true ); - connect( m_statusMessageTimer, SIGNAL(timeout()), SLOT(clearStatusMessage()) ); - connect( this, SIGNAL(error(QString)), SLOT(showError(QString)) ); +ImapResourceBase::ImapResourceBase(const QString &id) + : ResourceBase(id), + m_pool(new SessionPool(2, this)), + m_settings(Q_NULLPTR), + mSubscriptions(Q_NULLPTR), + m_idle(Q_NULLPTR) +{ + QTimer::singleShot(0, this, SLOT(updateResourceName())); + + connect(m_pool, SIGNAL(connectDone(int,QString)), + this, SLOT(onConnectDone(int,QString))); + connect(m_pool, SIGNAL(connectionLost(KIMAP::Session*)), + this, SLOT(onConnectionLost(KIMAP::Session*))); + + Akonadi::AttributeFactory::registerAttribute(); + Akonadi::AttributeFactory::registerAttribute(); + Akonadi::AttributeFactory::registerAttribute(); + Akonadi::AttributeFactory::registerAttribute(); + + Akonadi::AttributeFactory::registerAttribute(); + Akonadi::AttributeFactory::registerAttribute(); + + Akonadi::AttributeFactory::registerAttribute(); + Akonadi::AttributeFactory::registerAttribute(); + + // For QMetaObject::invokeMethod() + qRegisterMetaType >(); + + changeRecorder()->fetchCollection(true); + changeRecorder()->collectionFetchScope().setAncestorRetrieval(CollectionFetchScope::All); + changeRecorder()->collectionFetchScope().setIncludeStatistics(true); + changeRecorder()->itemFetchScope().fetchFullPayload(true); + changeRecorder()->itemFetchScope().setAncestorRetrieval(ItemFetchScope::All); + changeRecorder()->itemFetchScope().setFetchModificationTime(false); +//(Andras) disable now, as tokoe reported problems with it and the mail filter: changeRecorder()->fetchChangedOnly( true ); + + setHierarchicalRemoteIdentifiersEnabled(true); + setItemTransactionMode(ItemSync::MultipleTransactions); // we can recover from incomplete syncs, so we can use a faster mode + ItemFetchScope scope(changeRecorder()->itemFetchScope()); + scope.fetchFullPayload(false); + scope.setAncestorRetrieval(ItemFetchScope::None); + setItemSynchronizationFetchScope(scope); + setDisableAutomaticItemDeliveryDone(true); + setItemSyncBatchSize(100); + + connect(this, SIGNAL(reloadConfiguration()), SLOT(reconnect())); + + m_statusMessageTimer = new QTimer(this); + m_statusMessageTimer->setSingleShot(true); + connect(m_statusMessageTimer, SIGNAL(timeout()), SLOT(clearStatusMessage())); + connect(this, SIGNAL(error(QString)), SLOT(showError(QString))); - QMetaObject::invokeMethod( this, "delayedInit", Qt::QueuedConnection ); + QMetaObject::invokeMethod(this, "delayedInit", Qt::QueuedConnection); } void ImapResourceBase::delayedInit() { - settings(); // make sure the D-Bus settings interface is up - new ImapResourceBaseAdaptor( this ); - setNeedsNetwork( needsNetwork() ); - - // Migration issue: trash folder had ID in config, but didn't have SpecialCollections attribute, fix that. - if (!settings()->trashCollectionMigrated()) { - const Akonadi::Collection::Id trashCollection = settings()->trashCollection(); - if (trashCollection != -1) { - Collection attributeCollection(trashCollection); - SpecialCollections::setSpecialCollectionType("trash", attributeCollection); + settings(); // make sure the D-Bus settings interface is up + new ImapResourceBaseAdaptor(this); + setNeedsNetwork(needsNetwork()); + + // Migration issue: trash folder had ID in config, but didn't have SpecialCollections attribute, fix that. + if (!settings()->trashCollectionMigrated()) { + const Akonadi::Collection::Id trashCollection = settings()->trashCollection(); + if (trashCollection != -1) { + Collection attributeCollection(trashCollection); + SpecialCollections::setSpecialCollectionType("trash", attributeCollection); + } + settings()->setTrashCollectionMigrated(true); } - settings()->setTrashCollectionMigrated(true); - } } - ImapResourceBase::~ImapResourceBase() { - //Destroy everything that could cause callbacks immediately, otherwise the callbacks can result in a crash. + //Destroy everything that could cause callbacks immediately, otherwise the callbacks can result in a crash. - if ( m_idle ) { - delete m_idle; - m_idle = 0; - } + if (m_idle) { + delete m_idle; + m_idle = Q_NULLPTR; + } - Q_FOREACH (ResourceTask* task, m_taskList) { - delete task; - } - m_taskList.clear(); + Q_FOREACH (ResourceTask *task, m_taskList) { + delete task; + } + m_taskList.clear(); - delete m_pool; - delete m_settings; + delete m_pool; + delete m_settings; } void ImapResourceBase::aboutToQuit() { - //TODO the resource would ideally have to signal when it's done with logging out etc, before the destructor gets called - if ( m_idle ) { - m_idle->stop(); - } - - Q_FOREACH (ResourceTask* task, m_taskList) { - task->kill(); - } + //TODO the resource would ideally have to signal when it's done with logging out etc, before the destructor gets called + if (m_idle) { + m_idle->stop(); + } + + Q_FOREACH (ResourceTask *task, m_taskList) { + task->kill(); + } - m_pool->disconnect(); + m_pool->disconnect(); } void ImapResourceBase::updateResourceName() { - if ( name() == identifier() ) { - const QString agentType = AgentManager::self()->instance( identifier() ).type().identifier(); - const QString agentsrcFile = KGlobal::dirs()->localxdgconfdir() + QLatin1String("akonadi/agentsrc"); - - const QSettings agentsrc( agentsrcFile, QSettings::IniFormat ); - const int instanceCounter = agentsrc.value( - QString::fromLatin1( "InstanceCounters/%1/InstanceCounter" ).arg( agentType ), - -1 ).toInt(); - - if ( instanceCounter > 0 ) { - setName( QString("%1 %2").arg(defaultName()).arg(instanceCounter) ); - } else { - setName( defaultName() ); + if (name() == identifier()) { + const QString agentType = AgentManager::self()->instance(identifier()).type().identifier(); + const QString agentsrcFile = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1Char('/') + QLatin1String("akonadi/agentsrc"); + + const QSettings agentsrc(agentsrcFile, QSettings::IniFormat); + const int instanceCounter = agentsrc.value( + QStringLiteral("InstanceCounters/%1/InstanceCounter").arg(agentType), + -1).toInt(); + + if (instanceCounter > 0) { + setName(QString("%1 %2").arg(defaultName()).arg(instanceCounter)); + } else { + setName(defaultName()); + } } - } } - // ----------------------------------------------------------------------------- -void ImapResourceBase::configure( WId windowId ) +void ImapResourceBase::configure(WId windowId) { - if ( createConfigureDialog( windowId )->exec() == QDialog::Accepted ) { - emit configurationDialogAccepted(); - reconnect(); - } else { - emit configurationDialogRejected(); - } + if (createConfigureDialog(windowId)->exec() == QDialog::Accepted) { + Q_EMIT configurationDialogAccepted(); + reconnect(); + } else { + Q_EMIT configurationDialogRejected(); + } } // ---------------------------------------------------------------------------------- -void ImapResourceBase::startConnect( const QVariant& ) +void ImapResourceBase::startConnect(const QVariant &) { - if ( settings()->imapServer().isEmpty() ) { - setOnline( false ); - emit status( NotConfigured, i18n( "No server configured yet." ) ); - taskDone(); - return; - } - - m_pool->disconnect(); // reset all state, delete any old account - ImapAccount *account = new ImapAccount; - settings()->loadAccount( account ); - - const bool result = m_pool->connect( account ); - Q_ASSERT( result ); - Q_UNUSED( result ); + if (settings()->imapServer().isEmpty()) { + setOnline(false); + Q_EMIT status(NotConfigured, i18n("No server configured yet.")); + taskDone(); + return; + } + + m_pool->disconnect(); // reset all state, delete any old account + ImapAccount *account = new ImapAccount; + settings()->loadAccount(account); + + const bool result = m_pool->connect(account); + Q_ASSERT(result); + Q_UNUSED(result); } int ImapResourceBase::configureSubscription(qlonglong windowId) { - if (mSubscriptions) - return 0; + if (mSubscriptions) { + return 0; + } + + if (!m_pool->account()) { + return -2; + } + const QString password = settings()->password(); + if (password.isEmpty()) { + return -1; + } - if ( !m_pool->account() ) - return -2; - const QString password = settings()->password(); - if ( password.isEmpty() ) - return -1; - - mSubscriptions = new SubscriptionDialog( 0, SubscriptionDialog::AllowToEnableSubscription ); - if(windowId) { -#ifndef Q_WS_WIN - KWindowSystem::setMainWindow( mSubscriptions, windowId ); + mSubscriptions = new SubscriptionDialog(Q_NULLPTR, SubscriptionDialog::AllowToEnableSubscription); + if (windowId) { +#ifndef Q_OS_WIN + KWindowSystem::setMainWindow(mSubscriptions, windowId); #else - KWindowSystem::setMainWindow( mSubscriptions, (HWND)windowId ); + KWindowSystem::setMainWindow(mSubscriptions, (HWND)windowId); #endif - } - mSubscriptions->setCaption( i18nc( "@title:window", "Serverside Subscription" ) ); - mSubscriptions->setWindowIcon( KIcon( QLatin1String("network-server") ) ); - mSubscriptions->connectAccount( *m_pool->account(), password ); - mSubscriptions->setSubscriptionEnabled( settings()->subscriptionEnabled() ); - - if ( mSubscriptions->exec() ) { - settings()->setSubscriptionEnabled( mSubscriptions->subscriptionEnabled() ); - settings()->writeConfig(); - emit configurationDialogAccepted(); - reconnect(); - } - delete mSubscriptions; - - return 0; -} - -void ImapResourceBase::onConnectDone( int errorCode, const QString &errorString ) -{ - switch ( errorCode ) { - case SessionPool::NoError: - setOnline( true ); - taskDone(); - emit status( Idle, i18n( "Connection established." ) ); - - synchronizeCollectionTree(); - break; - - case SessionPool::PasswordRequestError: - case SessionPool::EncryptionError: - case SessionPool::LoginFailError: - case SessionPool::CapabilitiesTestError: - case SessionPool::IncompatibleServerError: - setOnline( false ); - emit status( Broken, errorString ); - cancelTask(); - return; - - case SessionPool::CouldNotConnectError: - emit status( Idle, i18n( "Server is not available." ) ); - deferTask(); - setTemporaryOffline((m_pool->account() && m_pool->account()->timeout() > 0) ? m_pool->account()->timeout() : 300); - return; - - case SessionPool::ReconnectNeededError: - reconnect(); - return; - - case SessionPool::NoAvailableSessionError: - kFatal() << "Shouldn't happen"; - return; - case SessionPool::CancelledError: - kWarning() << "Session login cancelled"; - return; - } -} - -void ImapResourceBase::onConnectionLost( KIMAP::Session */*session*/ ) -{ - if ( !m_pool->isConnected() ) { - reconnect(); - } + } + mSubscriptions->setWindowTitle(i18nc("@title:window", "Serverside Subscription")); + mSubscriptions->setWindowIcon(QIcon::fromTheme(QStringLiteral("network-server"))); + mSubscriptions->connectAccount(*m_pool->account(), password); + mSubscriptions->setSubscriptionEnabled(settings()->subscriptionEnabled()); + + if (mSubscriptions->exec()) { + settings()->setSubscriptionEnabled(mSubscriptions->subscriptionEnabled()); + settings()->save(); + Q_EMIT configurationDialogAccepted(); + reconnect(); + } + delete mSubscriptions; + + return 0; +} + +void ImapResourceBase::onConnectDone(int errorCode, const QString &errorString) +{ + switch (errorCode) { + case SessionPool::NoError: + setOnline(true); + taskDone(); + Q_EMIT status(Idle, i18n("Connection established.")); + + synchronizeCollectionTree(); + break; + + case SessionPool::PasswordRequestError: + case SessionPool::EncryptionError: + case SessionPool::LoginFailError: + case SessionPool::CapabilitiesTestError: + case SessionPool::IncompatibleServerError: + setOnline(false); + Q_EMIT status(Broken, errorString); + cancelTask(); + return; + + case SessionPool::CouldNotConnectError: + Q_EMIT status(Idle, i18n("Server is not available.")); + deferTask(); + setTemporaryOffline((m_pool->account() && m_pool->account()->timeout() > 0) ? m_pool->account()->timeout() : 300); + return; + + case SessionPool::ReconnectNeededError: + reconnect(); + return; + + case SessionPool::NoAvailableSessionError: + qFatal("Shouldn't happen"); + return; + case SessionPool::CancelledError: + qCWarning(IMAPRESOURCE_LOG) << "Session login cancelled"; + return; + } +} + +void ImapResourceBase::onConnectionLost(KIMAP::Session */*session*/) +{ + if (!m_pool->isConnected()) { + reconnect(); + } } ResourceStateInterface::Ptr ImapResourceBase::createResourceState(const TaskArguments &args) { - return ResourceStateInterface::Ptr(new ResourceState(this, args)); + return ResourceStateInterface::Ptr(new ResourceState(this, args)); } Settings *ImapResourceBase::settings() const { - if (m_settings == 0) { - m_settings = new Settings; - } + if (m_settings == Q_NULLPTR) { + m_settings = new Settings; + } - return m_settings; + return m_settings; } - // ---------------------------------------------------------------------------------- -bool ImapResourceBase::retrieveItem( const Akonadi::Item &item, const QSet &parts ) +bool ImapResourceBase::retrieveItem(const Akonadi::Item &item, const QSet &parts) { - // The collection name is empty here... - //emit status( AgentBase::Running, i18nc( "@info:status", "Retrieving item in '%1'", item.parentCollection().name() ) ); + // The collection name is empty here... + //emit status( AgentBase::Running, i18nc( "@info:status", "Retrieving item in '%1'", item.parentCollection().name() ) ); - RetrieveItemTask *task = new RetrieveItemTask( createResourceState(TaskArguments(item, parts)), this ); - task->start( m_pool ); - queueTask( task ); - return true; + RetrieveItemTask *task = new RetrieveItemTask(createResourceState(TaskArguments(item, parts)), this); + task->start(m_pool); + queueTask(task); + return true; } -void ImapResourceBase::itemAdded( const Item &item, const Collection &collection ) +void ImapResourceBase::itemAdded(const Item &item, const Collection &collection) { - emit status( AgentBase::Running, i18nc( "@info:status", "Adding item in '%1'", collection.name() ) ); + Q_EMIT status(AgentBase::Running, i18nc("@info:status", "Adding item in '%1'", collection.name())); - startTask(new AddItemTask( createResourceState(TaskArguments(item, collection)), this )); + startTask(new AddItemTask(createResourceState(TaskArguments(item, collection)), this)); } -void ImapResourceBase::itemChanged( const Item &item, const QSet &parts ) +void ImapResourceBase::itemChanged(const Item &item, const QSet &parts) { - emit status( AgentBase::Running, i18nc( "@info:status", "Updating item in '%1'", item.parentCollection().name() ) ); + Q_EMIT status(AgentBase::Running, i18nc("@info:status", "Updating item in '%1'", item.parentCollection().name())); - startTask(new ChangeItemTask( createResourceState(TaskArguments(item, parts)), this )); + startTask(new ChangeItemTask(createResourceState(TaskArguments(item, parts)), this)); } -void ImapResourceBase::itemsFlagsChanged( const Item::List& items, const QSet< QByteArray >& addedFlags, - const QSet< QByteArray >& removedFlags ) +void ImapResourceBase::itemsFlagsChanged(const Item::List &items, const QSet< QByteArray > &addedFlags, + const QSet< QByteArray > &removedFlags) { - emit status( AgentBase::Running, i18nc( "@info:status", "Updating items" ) ); + Q_EMIT status(AgentBase::Running, i18nc("@info:status", "Updating items")); - startTask(new ChangeItemsFlagsTask( createResourceState(TaskArguments(items, addedFlags, removedFlags)), this )); + startTask(new ChangeItemsFlagsTask(createResourceState(TaskArguments(items, addedFlags, removedFlags)), this)); } -void ImapResourceBase::itemsRemoved( const Akonadi::Item::List &items ) +void ImapResourceBase::itemsRemoved(const Akonadi::Item::List &items) { - const QString mailBox = ResourceStateInterface::mailBoxForCollection( items.first().parentCollection(), false ); - if ( mailBox.isEmpty() ) { - // this item will be removed soon by its parent collection - changeProcessed(); - return; - } + const QString mailBox = ResourceStateInterface::mailBoxForCollection(items.first().parentCollection(), false); + if (mailBox.isEmpty()) { + // this item will be removed soon by its parent collection + changeProcessed(); + return; + } - emit status( AgentBase::Running, i18nc( "@info:status", "Removing items" ) ); + Q_EMIT status(AgentBase::Running, i18nc("@info:status", "Removing items")); - startTask(new ChangeItemsFlagsTask( createResourceState(TaskArguments(items, QSet() << ImapFlags::Deleted, QSet())), this )); + startTask(new ChangeItemsFlagsTask(createResourceState(TaskArguments(items, QSet() << ImapFlags::Deleted, QSet())), this)); } -void ImapResourceBase::itemsMoved( const Akonadi::Item::List &items, const Akonadi::Collection &source, - const Akonadi::Collection &destination ) +void ImapResourceBase::itemsMoved(const Akonadi::Item::List &items, const Akonadi::Collection &source, + const Akonadi::Collection &destination) { - if ( items.first().parentCollection() != destination ) { // should have been set by the server - kWarning() << "Collections don't match: destination=" << destination.id() - << "; items parent=" << items.first().parentCollection().id() - << "; source collection=" << source.id(); - //Q_ASSERT( false ); - //TODO: Find out why this happens - cancelTask(); - return; - } + if (items.first().parentCollection() != destination) { // should have been set by the server + qCWarning(IMAPRESOURCE_LOG) << "Collections don't match: destination=" << destination.id() + << "; items parent=" << items.first().parentCollection().id() + << "; source collection=" << source.id(); + //Q_ASSERT( false ); + //TODO: Find out why this happens + cancelTask(); + return; + } - emit status( AgentBase::Running, i18nc( "@info:status", "Moving items from '%1' to '%2'", source.name(), destination.name() ) ); + Q_EMIT status(AgentBase::Running, i18nc("@info:status", "Moving items from '%1' to '%2'", source.name(), destination.name())); - startTask(new MoveItemsTask( createResourceState(TaskArguments(items, source, destination)), this )); + startTask(new MoveItemsTask(createResourceState(TaskArguments(items, source, destination)), this)); } - - // ---------------------------------------------------------------------------------- void ImapResourceBase::retrieveCollections() { - emit status( AgentBase::Running, i18nc( "@info:status", "Retrieving folders" ) ); + Q_EMIT status(AgentBase::Running, i18nc("@info:status", "Retrieving folders")); - startTask(new RetrieveCollectionsTask( createResourceState(TaskArguments()), this )); + startTask(new RetrieveCollectionsTask(createResourceState(TaskArguments()), this)); } -void ImapResourceBase::retrieveCollectionAttributes( const Akonadi::Collection &col ) +void ImapResourceBase::retrieveCollectionAttributes(const Akonadi::Collection &col) { - emit status( AgentBase::Running, i18nc( "@info:status", "Retrieving extra folder information for '%1'", col.name() ) ); - startTask(new RetrieveCollectionMetadataTask( createResourceState(TaskArguments(col)), this )); + Q_EMIT status(AgentBase::Running, i18nc("@info:status", "Retrieving extra folder information for '%1'", col.name())); + startTask(new RetrieveCollectionMetadataTask(createResourceState(TaskArguments(col)), this)); } -void ImapResourceBase::retrieveItems( const Collection &col ) +void ImapResourceBase::retrieveItems(const Collection &col) { - synchronizeCollectionAttributes(col.id()); + synchronizeCollectionAttributes(col.id()); + + setItemStreamingEnabled(true); - setItemStreamingEnabled( true ); + RetrieveItemsTask *task = new RetrieveItemsTask(createResourceState(TaskArguments(col)), this); + connect(task, SIGNAL(status(int,QString)), SIGNAL(status(int,QString))); + connect(this, SIGNAL(retrieveNextItemSyncBatch(int)), task, SLOT(onReadyForNextBatch(int))); + startTask(task); - RetrieveItemsTask *task = new RetrieveItemsTask( createResourceState(TaskArguments(col)), this); - connect(task, SIGNAL(status(int,QString)), SIGNAL(status(int,QString))); - connect(this, SIGNAL(retrieveNextItemSyncBatch(int)), task, SLOT(onReadyForNextBatch(int))); - startTask(task); } -void ImapResourceBase::collectionAdded( const Collection & collection, const Collection &parent ) +void ImapResourceBase::collectionAdded(const Collection &collection, const Collection &parent) { - emit status( AgentBase::Running, i18nc( "@info:status", "Creating folder '%1'", collection.name() ) ); - startTask(new AddCollectionTask( createResourceState(TaskArguments(collection, parent)), this )); + Q_EMIT status(AgentBase::Running, i18nc("@info:status", "Creating folder '%1'", collection.name())); + startTask(new AddCollectionTask(createResourceState(TaskArguments(collection, parent)), this)); } -void ImapResourceBase::collectionChanged( const Collection &collection, const QSet &parts ) +void ImapResourceBase::collectionChanged(const Collection &collection, const QSet &parts) { - emit status( AgentBase::Running, i18nc( "@info:status", "Updating folder '%1'", collection.name() ) ); - startTask(new ChangeCollectionTask( createResourceState(TaskArguments(collection, parts)), this )); + Q_EMIT status(AgentBase::Running, i18nc("@info:status", "Updating folder '%1'", collection.name())); + startTask(new ChangeCollectionTask(createResourceState(TaskArguments(collection, parts)), this)); } -void ImapResourceBase::collectionRemoved( const Collection &collection ) +void ImapResourceBase::collectionRemoved(const Collection &collection) { - //TODO Move this to the task - const QString mailBox = ResourceStateInterface::mailBoxForCollection( collection, false ); - if ( mailBox.isEmpty() ) { - // this collection will be removed soon by its parent collection - changeProcessed(); - return; - } - emit status( AgentBase::Running, i18nc( "@info:status", "Removing folder '%1'", collection.name() ) ); + //TODO Move this to the task + const QString mailBox = ResourceStateInterface::mailBoxForCollection(collection, false); + if (mailBox.isEmpty()) { + // this collection will be removed soon by its parent collection + changeProcessed(); + return; + } + Q_EMIT status(AgentBase::Running, i18nc("@info:status", "Removing folder '%1'", collection.name())); - startTask(new RemoveCollectionRecursiveTask( createResourceState(TaskArguments(collection)), this )); + startTask(new RemoveCollectionRecursiveTask(createResourceState(TaskArguments(collection)), this)); } -void ImapResourceBase::collectionMoved( const Akonadi::Collection &collection, const Akonadi::Collection &source, - const Akonadi::Collection &destination ) +void ImapResourceBase::collectionMoved(const Akonadi::Collection &collection, const Akonadi::Collection &source, + const Akonadi::Collection &destination) { - emit status( AgentBase::Running, i18nc( "@info:status", "Moving folder '%1' from '%2' to '%3'", - collection.name(), source.name(), destination.name() ) ); - startTask(new MoveCollectionTask( createResourceState(TaskArguments(collection, source, destination)), this )); + Q_EMIT status(AgentBase::Running, i18nc("@info:status", "Moving folder '%1' from '%2' to '%3'", + collection.name(), source.name(), destination.name())); + startTask(new MoveCollectionTask(createResourceState(TaskArguments(collection, source, destination)), this)); } - - -void ImapResourceBase::addSearch(const QString& query, const QString& queryLanguage, const Collection& resultCollection) +void ImapResourceBase::addSearch(const QString &query, const QString &queryLanguage, const Collection &resultCollection) { } -void ImapResourceBase::removeSearch(const Collection& resultCollection) +void ImapResourceBase::removeSearch(const Collection &resultCollection) { } -void ImapResourceBase::search( const QString &query, const Collection &collection ) +void ImapResourceBase::search(const QString &query, const Collection &collection) { - QVariantMap arg; - arg[QLatin1String("query")] = query; - arg[QLatin1String("collection")] = QVariant::fromValue( collection ); - scheduleCustomTask( this, "doSearch", arg ); + QVariantMap arg; + arg[QLatin1String("query")] = query; + arg[QLatin1String("collection")] = QVariant::fromValue(collection); + scheduleCustomTask(this, "doSearch", arg); } -void ImapResourceBase::doSearch( const QVariant &arg ) +void ImapResourceBase::doSearch(const QVariant &arg) { - const QVariantMap map = arg.toMap(); - const QString query = map[QLatin1String("query")].toString(); - const Collection collection = map[QLatin1String("collection")].value(); + const QVariantMap map = arg.toMap(); + const QString query = map[QLatin1String("query")].toString(); + const Collection collection = map[QLatin1String("collection")].value(); - emit status( AgentBase::Running, i18nc( "@info:status", "Searching..." ) ); - startTask(new SearchTask( createResourceState(TaskArguments(collection)), query, this )); + Q_EMIT status(AgentBase::Running, i18nc("@info:status", "Searching...")); + startTask(new SearchTask(createResourceState(TaskArguments(collection)), query, this)); } - // ----- // ---------------------------------------------------------------------------------- void ImapResourceBase::scheduleConnectionAttempt() { - // block all other tasks, until we are connected - scheduleCustomTask( this, "startConnect", QVariant(), ResourceBase::Prepend ); + // block all other tasks, until we are connected + scheduleCustomTask(this, "startConnect", QVariant(), ResourceBase::Prepend); } void ImapResourceBase::doSetOnline(bool online) { -#ifndef IMAPRESOURCE_NO_SOLID - kDebug() << "online=" << online; -#endif - if ( !online ) { - Q_FOREACH(ResourceTask* task, m_taskList) { - task->kill(); - delete task; + qCDebug(IMAPRESOURCE_LOG) << "online=" << online; + if (!online) { + Q_FOREACH (ResourceTask *task, m_taskList) { + task->kill(); + delete task; + } + m_taskList.clear(); + m_pool->cancelPasswordRequests(); + if (m_pool->isConnected()) { + m_pool->disconnect(); + } + if (m_idle) { + m_idle->stop(); + delete m_idle; + m_idle = Q_NULLPTR; + } + settings()->clearCachedPassword(); + } else if (online && !m_pool->isConnected()) { + scheduleConnectionAttempt(); } - m_taskList.clear(); - m_pool->cancelPasswordRequests(); - if (m_pool->isConnected()) { - m_pool->disconnect(); - } - if (m_idle) { - m_idle->stop(); - delete m_idle; - m_idle = 0; - } - settings()->clearCachedPassword(); - } else if ( online && !m_pool->isConnected() ) { - scheduleConnectionAttempt(); - } - ResourceBase::doSetOnline( online ); + ResourceBase::doSetOnline(online); } QChar ImapResourceBase::separatorCharacter() const @@ -550,175 +543,171 @@ return m_separatorCharacter; } -void ImapResourceBase::setSeparatorCharacter( const QChar &separator ) +void ImapResourceBase::setSeparatorCharacter(const QChar &separator) { m_separatorCharacter = separator; } bool ImapResourceBase::needsNetwork() const { - const QString hostName = settings()->imapServer().section( QLatin1Char(':'), 0, 0 ); - // ### is there a better way to do this? - if ( hostName == QLatin1String( "127.0.0.1" ) || - hostName == QLatin1String( "localhost" ) || - hostName == QHostInfo::localHostName() ) { - return false; - } - return true; + const QString hostName = settings()->imapServer().section(QLatin1Char(':'), 0, 0); + // ### is there a better way to do this? + if (hostName == QLatin1String("127.0.0.1") || + hostName == QLatin1String("localhost") || + hostName == QHostInfo::localHostName()) { + return false; + } + return true; } void ImapResourceBase::reconnect() { - setNeedsNetwork( needsNetwork() ); - setOnline( false ); // we are not connected initially - setOnline( true ); + setNeedsNetwork(needsNetwork()); + setOnline(false); // we are not connected initially + setOnline(true); } - - // ---------------------------------------------------------------------------------- void ImapResourceBase::startIdleIfNeeded() { - if ( !m_idle ) { - startIdle(); - } + if (!m_idle) { + startIdle(); + } } void ImapResourceBase::startIdle() { - delete m_idle; - m_idle = 0; - - if ( !m_pool->serverCapabilities().contains( QLatin1String("IDLE") ) ) - return; - - //Without password we don't even have to try - if (settings()->password().isEmpty()) { - return; - } - - const QStringList ridPath = settings()->idleRidPath(); - if ( ridPath.size() < 2 ) - return; - - Collection c, p; - p.setParentCollection( Collection::root() ); - for ( int i = ridPath.size() - 1; i > 0; --i ) { - p.setRemoteId( ridPath.at( i ) ); - c.setParentCollection( p ); - p = c; - } - c.setRemoteId( ridPath.first() ); - - Akonadi::CollectionFetchScope scope; - scope.setResource( identifier() ); - scope.setAncestorRetrieval( Akonadi::CollectionFetchScope::All ); - - Akonadi::CollectionFetchJob *fetch - = new Akonadi::CollectionFetchJob( c, Akonadi::CollectionFetchJob::Base, this ); - fetch->setFetchScope( scope ); - - connect( fetch, SIGNAL(result(KJob*)), - this, SLOT(onIdleCollectionFetchDone(KJob*)) ); -} - -void ImapResourceBase::onIdleCollectionFetchDone( KJob *job ) -{ - if (job->error()) { - kWarning() << "CollectionFetch for idling failed." - << "error=" << job->error() - << ", errorString=" << job->errorString(); - return; - } - Akonadi::CollectionFetchJob *fetch = static_cast(job); - //Can be empty if collection is not subscribed locally - if (!fetch->collections().isEmpty()) { - m_idle = new ImapIdleManager( createResourceState(TaskArguments(fetch->collections().first())), m_pool, this ); - } -} + delete m_idle; + m_idle = Q_NULLPTR; + if (!m_pool->serverCapabilities().contains(QLatin1String("IDLE"))) { + return; + } + //Without password we don't even have to try + if (settings()->password().isEmpty()) { + return; + } -// ---------------------------------------------------------------------------------- + const QStringList ridPath = settings()->idleRidPath(); + if (ridPath.size() < 2) { + return; + } -void ImapResourceBase::requestManualExpunge( qint64 collectionId ) -{ - if ( !settings()->automaticExpungeEnabled() ) { - Collection collection( collectionId ); + Collection c, p; + p.setParentCollection(Collection::root()); + for (int i = ridPath.size() - 1; i > 0; --i) { + p.setRemoteId(ridPath.at(i)); + c.setParentCollection(p); + p = c; + } + c.setRemoteId(ridPath.first()); Akonadi::CollectionFetchScope scope; - scope.setResource( identifier() ); - scope.setAncestorRetrieval( Akonadi::CollectionFetchScope::All ); - scope.setIncludeUnsubscribed( true ); + scope.setResource(identifier()); + scope.setAncestorRetrieval(Akonadi::CollectionFetchScope::All); Akonadi::CollectionFetchJob *fetch - = new Akonadi::CollectionFetchJob( collection, - Akonadi::CollectionFetchJob::Base, - this ); - fetch->setFetchScope( scope ); + = new Akonadi::CollectionFetchJob(c, Akonadi::CollectionFetchJob::Base, this); + fetch->setFetchScope(scope); - connect( fetch, SIGNAL(result(KJob*)), - this, SLOT(onExpungeCollectionFetchDone(KJob*)) ); - } + connect(fetch, SIGNAL(result(KJob*)), + this, SLOT(onIdleCollectionFetchDone(KJob*))); +} + +void ImapResourceBase::onIdleCollectionFetchDone(KJob *job) +{ + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "CollectionFetch for idling failed." + << "error=" << job->error() + << ", errorString=" << job->errorString(); + return; + } + Akonadi::CollectionFetchJob *fetch = static_cast(job); + //Can be empty if collection is not subscribed locally + if (!fetch->collections().isEmpty()) { + delete m_idle; + m_idle = new ImapIdleManager(createResourceState(TaskArguments(fetch->collections().at(0))), m_pool, this); + } } -void ImapResourceBase::onExpungeCollectionFetchDone( KJob *job ) +// ---------------------------------------------------------------------------------- + +void ImapResourceBase::requestManualExpunge(qint64 collectionId) { - if ( job->error() == 0 ) { - Akonadi::CollectionFetchJob *fetch = static_cast( job ); - Akonadi::Collection collection = fetch->collections().first(); + if (!settings()->automaticExpungeEnabled()) { + Collection collection(collectionId); - scheduleCustomTask( this, "triggerCollectionExpunge", - QVariant::fromValue( collection ) ); + Akonadi::CollectionFetchScope scope; + scope.setResource(identifier()); + scope.setAncestorRetrieval(Akonadi::CollectionFetchScope::All); + scope.setIncludeUnsubscribed(true); + + Akonadi::CollectionFetchJob *fetch + = new Akonadi::CollectionFetchJob(collection, + Akonadi::CollectionFetchJob::Base, + this); + fetch->setFetchScope(scope); - } else { - kWarning() << "CollectionFetch for expunge failed." - << "error=" << job->error() - << ", errorString=" << job->errorString(); - } + connect(fetch, &KJob::result, + this, &ImapResourceBase::onExpungeCollectionFetchDone); + } } -void ImapResourceBase::triggerCollectionExpunge( const QVariant &collectionVariant ) +void ImapResourceBase::onExpungeCollectionFetchDone(KJob *job) { - const Collection collection = collectionVariant.value(); + if (job->error() == 0) { + Akonadi::CollectionFetchJob *fetch = static_cast(job); + Akonadi::Collection collection = fetch->collections().at(0); + + scheduleCustomTask(this, "triggerCollectionExpunge", + QVariant::fromValue(collection)); - ExpungeCollectionTask *task = new ExpungeCollectionTask( createResourceState(TaskArguments(collection)), this ); - task->start( m_pool ); - queueTask( task ); + } else { + qCWarning(IMAPRESOURCE_LOG) << "CollectionFetch for expunge failed." + << "error=" << job->error() + << ", errorString=" << job->errorString(); + } } +void ImapResourceBase::triggerCollectionExpunge(const QVariant &collectionVariant) +{ + const Collection collection = collectionVariant.value(); + ExpungeCollectionTask *task = new ExpungeCollectionTask(createResourceState(TaskArguments(collection)), this); + task->start(m_pool); + queueTask(task); +} // ---------------------------------------------------------------------------------- void ImapResourceBase::abortActivity() { - if ( !m_taskList.isEmpty() ) { - m_pool->disconnect( SessionPool::CloseSession ); - scheduleConnectionAttempt(); - } + if (!m_taskList.isEmpty()) { + m_pool->disconnect(SessionPool::CloseSession); + scheduleConnectionAttempt(); + } } -void ImapResourceBase::queueTask( ResourceTask *task ) +void ImapResourceBase::queueTask(ResourceTask *task) { - connect( task, SIGNAL(destroyed(QObject*)), - this, SLOT(taskDestroyed(QObject*)) ); - m_taskList << task; + connect(task, &QObject::destroyed, + this, &ImapResourceBase::taskDestroyed); + m_taskList << task; } -void ImapResourceBase::startTask( ResourceTask* task ) +void ImapResourceBase::startTask(ResourceTask *task) { - task->start(m_pool); - queueTask(task); + task->start(m_pool); + queueTask(task); } -void ImapResourceBase::taskDestroyed( QObject *task ) +void ImapResourceBase::taskDestroyed(QObject *task) { - m_taskList.removeAll( static_cast( task ) ); + m_taskList.removeAll(static_cast(task)); } - QStringList ImapResourceBase::serverCapabilities() const { return m_pool->serverCapabilities(); @@ -731,36 +720,37 @@ QString ImapResourceBase::dumpResourceToString() const { - QString ret; - Q_FOREACH(ResourceTask* task, m_taskList) { - if (!ret.isEmpty()) - ret += QLatin1String(", "); - ret += QLatin1String(task->metaObject()->className()); - } - return QLatin1String("IMAP tasks: ") + ret; + QString ret; + Q_FOREACH (ResourceTask *task, m_taskList) { + if (!ret.isEmpty()) { + ret += QLatin1String(", "); + } + ret += QLatin1String(task->metaObject()->className()); + } + return QLatin1String("IMAP tasks: ") + ret; } -void ImapResourceBase::showError( const QString &message ) +void ImapResourceBase::showError(const QString &message) { - emit status( Akonadi::AgentBase::Idle, message ); - m_statusMessageTimer->start( 1000*10 ); + Q_EMIT status(Akonadi::AgentBase::Idle, message); + m_statusMessageTimer->start(1000 * 10); } void ImapResourceBase::clearStatusMessage() { - emit status( Akonadi::AgentBase::Idle, QString() ); + Q_EMIT status(Akonadi::AgentBase::Idle, QString()); } void ImapResourceBase::modifyCollection(const Collection &col) { Akonadi::CollectionModifyJob *modJob = new Akonadi::CollectionModifyJob(col, this); - connect(modJob, SIGNAL(result(KJob*)), this, SLOT(onCollectionModifyDone(KJob*))); + connect(modJob, &KJob::result, this, &ImapResourceBase::onCollectionModifyDone); } -void ImapResourceBase::onCollectionModifyDone(KJob* job) +void ImapResourceBase::onCollectionModifyDone(KJob *job) { if (job->error()) { - kWarning() << "Failed to modify collection: " << job->errorString(); + qCWarning(IMAPRESOURCE_LOG) << "Failed to modify collection: " << job->errorString(); } } diff -Nru kdepim-runtime-4.14.6/resources/imap/imapresourcebase.h kdepim-runtime-15.08.0/resources/imap/imapresourcebase.h --- kdepim-runtime-4.14.6/resources/imap/imapresourcebase.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/imapresourcebase.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,9 +26,9 @@ #ifndef RESOURCES_IMAP_IMAPRESOURCEBASE_H #define RESOURCES_IMAP_IMAPRESOURCEBASE_H -#include -#include -#include +#include +#include +#include #include #include "resourcestateinterface.h" #include "resourcestate.h" @@ -38,7 +38,7 @@ class ResourceTask; namespace KIMAP { - class Session; +class Session; } class ImapIdleManager; @@ -48,124 +48,122 @@ class Settings; class ImapResourceBase : public Akonadi::ResourceBase, - public Akonadi::AgentBase::ObserverV3, - public Akonadi::AgentSearchInterface + public Akonadi::AgentBase::ObserverV4, + public Akonadi::AgentSearchInterface { - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "org.kde.Akonadi.ImapResourceBase") + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.Akonadi.ImapResourceBase") protected: - using Akonadi::AgentBase::Observer::collectionChanged; + using Akonadi::AgentBase::Observer::collectionChanged; public: - explicit ImapResourceBase( const QString &id ); - ~ImapResourceBase(); + explicit ImapResourceBase(const QString &id); + ~ImapResourceBase(); - virtual KDialog *createConfigureDialog( WId windowId ) = 0; + virtual QDialog *createConfigureDialog(WId windowId) = 0; - void cleanup(); + void cleanup() Q_DECL_OVERRIDE; - virtual Settings* settings() const; + virtual Settings *settings() const; public Q_SLOTS: - virtual void configure( WId windowId ); + void configure(WId windowId) Q_DECL_OVERRIDE; - // DBus methods - Q_SCRIPTABLE void requestManualExpunge( qint64 collectionId ); - Q_SCRIPTABLE int configureSubscription( qlonglong windowId = 0 ); - Q_SCRIPTABLE QStringList serverCapabilities() const; + // DBus methods + Q_SCRIPTABLE void requestManualExpunge(qint64 collectionId); + Q_SCRIPTABLE int configureSubscription(qlonglong windowId = 0); + Q_SCRIPTABLE QStringList serverCapabilities() const; - // pseudo-virtual called by ResourceBase - QString dumpResourceToString() const; + // pseudo-virtual called by ResourceBase + QString dumpResourceToString() const Q_DECL_OVERRIDE; protected Q_SLOTS: - void startIdleIfNeeded(); - void startIdle(); + void startIdleIfNeeded(); + void startIdle(); - void abortActivity(); + void abortActivity() Q_DECL_OVERRIDE; - virtual void retrieveCollections(); - void retrieveCollectionAttributes( const Akonadi::Collection &col ); + void retrieveCollections() Q_DECL_OVERRIDE; + void retrieveCollectionAttributes(const Akonadi::Collection &col) Q_DECL_OVERRIDE; - virtual void retrieveItems( const Akonadi::Collection &col ); - virtual bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); + void retrieveItems(const Akonadi::Collection &col) Q_DECL_OVERRIDE; + bool retrieveItem(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; protected: - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); - virtual void itemsFlagsChanged( const Akonadi::Item::List &items, const QSet &addedFlags, const QSet &removedFlags ); - virtual void itemsRemoved( const Akonadi::Item::List &items ); - virtual void itemsMoved( const Akonadi::Item::List &item, const Akonadi::Collection &source, - const Akonadi::Collection &destination ); + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + void itemsFlagsChanged(const Akonadi::Item::List &items, const QSet &addedFlags, const QSet &removedFlags) Q_DECL_OVERRIDE; + void itemsRemoved(const Akonadi::Item::List &items) Q_DECL_OVERRIDE; + virtual void itemsMoved(const Akonadi::Item::List &item, const Akonadi::Collection &source, + const Akonadi::Collection &destination) Q_DECL_OVERRIDE; + + void collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent) Q_DECL_OVERRIDE; + void collectionChanged(const Akonadi::Collection &collection, const QSet &parts) Q_DECL_OVERRIDE; + void collectionRemoved(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + virtual void collectionMoved(const Akonadi::Collection &collection, const Akonadi::Collection &source, + const Akonadi::Collection &destination) Q_DECL_OVERRIDE; + + void addSearch(const QString &query, const QString &queryLanguage, const Akonadi::Collection &resultCollection) Q_DECL_OVERRIDE; + void removeSearch(const Akonadi::Collection &resultCollection) Q_DECL_OVERRIDE; + void search(const QString &query, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + + void doSetOnline(bool online) Q_DECL_OVERRIDE; + QChar separatorCharacter() const; + void setSeparatorCharacter(const QChar &separator); - virtual void collectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection &parent ); - virtual void collectionChanged( const Akonadi::Collection &collection, const QSet &parts ); - virtual void collectionRemoved( const Akonadi::Collection &collection ); - virtual void collectionMoved( const Akonadi::Collection &collection, const Akonadi::Collection &source, - const Akonadi::Collection &destination ); + void aboutToQuit() Q_DECL_OVERRIDE; - virtual void addSearch( const QString &query, const QString &queryLanguage, const Akonadi::Collection &resultCollection ); - virtual void removeSearch( const Akonadi::Collection &resultCollection ); - virtual void search( const QString &query, const Akonadi::Collection &collection ); + virtual ResourceStateInterface::Ptr createResourceState(const TaskArguments &); + virtual QString defaultName() const = 0; - virtual void doSetOnline(bool online); - - QChar separatorCharacter() const; - void setSeparatorCharacter( const QChar &separator ); - - virtual void aboutToQuit(); - - virtual ResourceStateInterface::Ptr createResourceState(const TaskArguments &); - virtual QString defaultName() const = 0; +protected Q_SLOTS: + void delayedInit(); private Q_SLOTS: - void doSearch( const QVariant &arg ); - - void reconnect(); - - void scheduleConnectionAttempt(); - void startConnect( const QVariant & ); // the parameter is necessary, since this method is used by the task scheduler - void onConnectDone( int errorCode, const QString &errorMessage ); - void onConnectionLost( KIMAP::Session *session ); - + void doSearch(const QVariant &arg); - void onIdleCollectionFetchDone( KJob *job ); + void reconnect(); - void onExpungeCollectionFetchDone( KJob *job ); - void triggerCollectionExpunge( const QVariant &collectionVariant ); + void scheduleConnectionAttempt(); + void startConnect(const QVariant &); // the parameter is necessary, since this method is used by the task scheduler + void onConnectDone(int errorCode, const QString &errorMessage); + void onConnectionLost(KIMAP::Session *session); + void onIdleCollectionFetchDone(KJob *job); - void taskDestroyed( QObject *task ); + void onExpungeCollectionFetchDone(KJob *job); + void triggerCollectionExpunge(const QVariant &collectionVariant); - void showError( const QString &message ); - void clearStatusMessage(); + void taskDestroyed(QObject *task); - void updateResourceName(); + void showError(const QString &message); + void clearStatusMessage(); - void onCollectionModifyDone( KJob *job ); + void updateResourceName(); - void delayedInit(); + void onCollectionModifyDone(KJob *job); protected: - //Starts and queues a task - void startTask( ResourceTask *task ); - void queueTask( ResourceTask *task ); - SessionPool *m_pool; + //Starts and queues a task + void startTask(ResourceTask *task); + void queueTask(ResourceTask *task); + SessionPool *m_pool; + mutable Settings *m_settings; private: - friend class ResourceState; + friend class ResourceState; - bool needsNetwork() const; - void modifyCollection(const Akonadi::Collection &); + bool needsNetwork() const; + void modifyCollection(const Akonadi::Collection &); - friend class ImapIdleManager; + friend class ImapIdleManager; - QList m_taskList; //used to be able to kill tasks - QPointer mSubscriptions; - ImapIdleManager *m_idle; - QTimer *m_statusMessageTimer; - QChar m_separatorCharacter; - mutable Settings *m_settings; + QList m_taskList; //used to be able to kill tasks + QPointer mSubscriptions; + ImapIdleManager *m_idle; + QTimer *m_statusMessageTimer; + QChar m_separatorCharacter; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/imapresource.cpp kdepim-runtime-15.08.0/resources/imap/imapresource.cpp --- kdepim-runtime-4.14.6/resources/imap/imapresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/imapresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,20 +24,23 @@ */ #include "imapresource.h" + #include "setupserver.h" #include "settings.h" #include "sessionpool.h" #include "settingspasswordrequester.h" #include "sessionuiproxy.h" +#include "tracer.h" +#include #include #include -ImapResource::ImapResource( const QString &id ) - : ImapResourceBase( id ) +ImapResource::ImapResource(const QString &id) + : ImapResourceBase(id) { - m_pool->setPasswordRequester( new SettingsPasswordRequester( this, m_pool ) ); - m_pool->setSessionUiProxy( SessionUiProxy::Ptr( new SessionUiProxy ) ); + m_pool->setPasswordRequester(new SettingsPasswordRequester(this, m_pool)); + m_pool->setSessionUiProxy(SessionUiProxy::Ptr(new SessionUiProxy)); } ImapResource::~ImapResource() @@ -46,32 +49,32 @@ QString ImapResource::defaultName() const { - return i18n( "IMAP Account" ); + return i18n("IMAP Account"); } - -KDialog* ImapResource::createConfigureDialog(WId windowId) +QDialog *ImapResource::createConfigureDialog(WId windowId) { - SetupServer *dlg = new SetupServer( this, windowId ); - KWindowSystem::setMainWindow( dlg, windowId ); - dlg->setWindowIcon( KIcon( QLatin1String("network-server") ) ); - connect(dlg, SIGNAL(finished(int)), this, SLOT(onConfigurationDone(int)));; - return dlg; + SetupServer *dlg = new SetupServer(this, windowId); + KWindowSystem::setMainWindow(dlg, windowId); + dlg->setWindowIcon(QIcon::fromTheme(QStringLiteral("network-server"))); + connect(dlg, &SetupServer::finished, this, &ImapResource::onConfigurationDone); + return dlg; } void ImapResource::onConfigurationDone(int result) { - SetupServer *dlg = qobject_cast(sender()); - if (result) { - if ( dlg->shouldClearCache() ) { - clearCache(); + SetupServer *dlg = qobject_cast(sender()); + if (result) { + if (dlg->shouldClearCache()) { + clearCache(); + } + settings()->save(); } - settings()->writeConfig(); - } - dlg->deleteLater(); + dlg->deleteLater(); } void ImapResource::cleanup() { settings()->cleanup(); + Akonadi::AgentBase::cleanup(); } diff -Nru kdepim-runtime-4.14.6/resources/imap/imapresource_debug.cpp kdepim-runtime-15.08.0/resources/imap/imapresource_debug.cpp --- kdepim-runtime-4.14.6/resources/imap/imapresource_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/imapresource_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2015 Laurent Montel + + 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 "imapresource_debug.h" +Q_LOGGING_CATEGORY(IMAPRESOURCE_LOG, "log_imapresource") + diff -Nru kdepim-runtime-4.14.6/resources/imap/imapresource_debug.h kdepim-runtime-15.08.0/resources/imap/imapresource_debug.h --- kdepim-runtime-4.14.6/resources/imap/imapresource_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/imapresource_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2015 Laurent Montel + + 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 IMAPRESOURCE_DEBUG_H +#define IMAPRESOURCE_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(IMAPRESOURCE_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/imap/imapresource.desktop kdepim-runtime-15.08.0/resources/imap/imapresource.desktop --- kdepim-runtime-4.14.6/resources/imap/imapresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/imapresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -81,7 +81,7 @@ Comment[ro]=Se conectează la un server de poștă IMAP Comment[ru]=Подключение к почтовому серверу IMAP Comment[sk]=Pripojí sa na IMAP poštový server -Comment[sl]=Povezava z e-poštnim strežnikom IMAP +Comment[sl]=Poveže se z e-poštnim strežnikom IMAP Comment[sr]=Повезује се на ИМАП сервер е‑поште Comment[sr@ijekavian]=Повезује се на ИМАП сервер е‑поште Comment[sr@ijekavianlatin]=Povezuje se na IMAP server e‑pošte diff -Nru kdepim-runtime-4.14.6/resources/imap/imapresource.h kdepim-runtime-15.08.0/resources/imap/imapresource.h --- kdepim-runtime-4.14.6/resources/imap/imapresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/imapresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -31,20 +31,20 @@ class ImapResource : public ImapResourceBase { Q_OBJECT - Q_CLASSINFO( "D-Bus Interface", "org.kde.Akonadi.Imap.Resource" ) + Q_CLASSINFO("D-Bus Interface", "org.kde.Akonadi.Imap.Resource") public: - explicit ImapResource( const QString &id ); + explicit ImapResource(const QString &id); virtual ~ImapResource(); - virtual KDialog *createConfigureDialog ( WId windowId ); - virtual void cleanup(); + QDialog *createConfigureDialog(WId windowId) Q_DECL_OVERRIDE; + void cleanup() Q_DECL_OVERRIDE; protected: - virtual QString defaultName() const; + virtual QString defaultName() const Q_DECL_OVERRIDE; private Q_SLOTS: - void onConfigurationDone( int result ); + void onConfigurationDone(int result); }; diff -Nru kdepim-runtime-4.14.6/resources/imap/imapresource.kcfg kdepim-runtime-15.08.0/resources/imap/imapresource.kcfg --- kdepim-runtime-4.14.6/resources/imap/imapresource.kcfg 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/imapresource.kcfg 2015-08-10 21:01:02.000000000 +0000 @@ -98,6 +98,10 @@ + + + 1 + kmail-vacation.siv diff -Nru kdepim-runtime-4.14.6/resources/imap/messagehelper.cpp kdepim-runtime-15.08.0/resources/imap/messagehelper.cpp --- kdepim-runtime-4.14.6/resources/imap/messagehelper.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/messagehelper.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,18 +22,20 @@ #include "resourcetask.h" +#include "imapresource_debug.h" + MessageHelper::~MessageHelper() { } Akonadi::Item MessageHelper::createItemFromMessage(KMime::Message::Ptr message, - const qint64 uid, - const qint64 size, - const QList &attrs, - const QList &flags, - const KIMAP::FetchJob::FetchScope &scope, - bool &ok) const + const qint64 uid, + const qint64 size, + const QList &attrs, + const QList &flags, + const KIMAP::FetchJob::FetchScope &scope, + bool &ok) const { Q_UNUSED(attrs); @@ -44,7 +46,7 @@ i.setFlags(Akonadi::Item::Flags::fromList(ResourceTask::toAkonadiFlags(flags))); } else { if (!message) { - kWarning() << "Got empty message: " << uid; + qCWarning(IMAPRESOURCE_LOG) << "Got empty message: " << uid; ok = false; return Akonadi::Item(); } @@ -52,7 +54,7 @@ if (message->body().isEmpty() && (scope.mode == KIMAP::FetchJob::FetchScope::Full || scope.mode == KIMAP::FetchJob::FetchScope::Content)) { // In that case put a space in as body so that it gets cached // otherwise we'll wrongly believe the body part is missing from the cache - message->setBody( " " ); + message->setBody(" "); } i.setRemoteId(QString::number(uid)); i.setMimeType(KMime::Message::mimeType()); diff -Nru kdepim-runtime-4.14.6/resources/imap/messagehelper.h kdepim-runtime-15.08.0/resources/imap/messagehelper.h --- kdepim-runtime-4.14.6/resources/imap/messagehelper.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/messagehelper.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,23 +20,24 @@ #ifndef MESSAGEHELPER_H #define MESSAGEHELPER_H -#include +#include #include -#include +#include #include -class MessageHelper { +class MessageHelper +{ public: typedef boost::shared_ptr Ptr; virtual ~MessageHelper(); virtual Akonadi::Item createItemFromMessage(KMime::Message::Ptr message, - const qint64 uid, - const qint64 size, - const QList &attrs, - const QList &flags, - const KIMAP::FetchJob::FetchScope &scope, - bool &ok) const; + const qint64 uid, + const qint64 size, + const QList &attrs, + const QList &flags, + const KIMAP::FetchJob::FetchScope &scope, + bool &ok) const; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/movecollectiontask.cpp kdepim-runtime-15.08.0/resources/imap/movecollectiontask.cpp --- kdepim-runtime-4.14.6/resources/imap/movecollectiontask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/movecollectiontask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,8 +21,8 @@ #include "movecollectiontask.h" -#include -#include +#include "imapresource_debug.h" +#include #include #include @@ -31,8 +31,8 @@ #include -MoveCollectionTask::MoveCollectionTask( ResourceStateInterface::Ptr resource, QObject *parent ) - : ResourceTask( DeferIfNoSession, resource, parent ) +MoveCollectionTask::MoveCollectionTask(ResourceStateInterface::Ptr resource, QObject *parent) + : ResourceTask(DeferIfNoSession, resource, parent) { } @@ -41,114 +41,109 @@ { } -void MoveCollectionTask::doStart( KIMAP::Session *session ) +void MoveCollectionTask::doStart(KIMAP::Session *session) { - if ( collection().remoteId().isEmpty() ) { - emitError( i18n( "Cannot move IMAP folder '%1', it does not exist on the server.", - collection().name() ) ); - changeProcessed(); - return; - } + if (collection().remoteId().isEmpty()) { + emitError(i18n("Cannot move IMAP folder '%1', it does not exist on the server.", + collection().name())); + changeProcessed(); + return; + } - if ( sourceCollection().remoteId().isEmpty() ) { - emitError( i18n( "Cannot move IMAP folder '%1' out of '%2', '%2' does not exist on the server.", - collection().name(), - sourceCollection().name() ) ); - changeProcessed(); - return; - } + if (sourceCollection().remoteId().isEmpty()) { + emitError(i18n("Cannot move IMAP folder '%1' out of '%2', '%2' does not exist on the server.", + collection().name(), + sourceCollection().name())); + changeProcessed(); + return; + } - if ( targetCollection().remoteId().isEmpty() ) { - emitError( i18n( "Cannot move IMAP folder '%1' to '%2', '%2' does not exist on the server.", - collection().name(), - sourceCollection().name() ) ); - changeProcessed(); - return; - } + if (targetCollection().remoteId().isEmpty()) { + emitError(i18n("Cannot move IMAP folder '%1' to '%2', '%2' does not exist on the server.", + collection().name(), + sourceCollection().name())); + changeProcessed(); + return; + } - if ( session->selectedMailBox() != mailBoxForCollection( collection() ) ) { - doRename( session ); - return; - } + if (session->selectedMailBox() != mailBoxForCollection(collection())) { + doRename(session); + return; + } - // Some IMAP servers don't allow moving an opened mailbox, so make sure - // it's not opened (https://bugs.kde.org/show_bug.cgi?id=324932) by examining - // a non-existent mailbox. We don't use CLOSE in order not to trigger EXPUNGE - KIMAP::SelectJob *examine = new KIMAP::SelectJob( session ); - examine->setOpenReadOnly( true ); // use EXAMINE instead of SELECT - examine->setMailBox( QString::fromLatin1( "IMAP Resource non existing folder %1" ).arg( QUuid::createUuid().toString() ) ); - connect( examine, SIGNAL(result(KJob*)), - this, SLOT(onExamineDone(KJob*)) ); - examine->start(); + // Some IMAP servers don't allow moving an opened mailbox, so make sure + // it's not opened (https://bugs.kde.org/show_bug.cgi?id=324932) by examining + // a non-existent mailbox. We don't use CLOSE in order not to trigger EXPUNGE + KIMAP::SelectJob *examine = new KIMAP::SelectJob(session); + examine->setOpenReadOnly(true); // use EXAMINE instead of SELECT + examine->setMailBox(QString::fromLatin1("IMAP Resource non existing folder %1").arg(QUuid::createUuid().toString())); + connect(examine, &KIMAP::SelectJob::result, this, &MoveCollectionTask::onExamineDone); + examine->start(); } -void MoveCollectionTask::onExamineDone( KJob* job ) +void MoveCollectionTask::onExamineDone(KJob *job) { - // We deliberately ignore any error here, because the SelectJob will always fail - // when examining a non-existent mailbox + // We deliberately ignore any error here, because the SelectJob will always fail + // when examining a non-existent mailbox - KIMAP::SelectJob *examine = static_cast( job ); - doRename( examine->session() ); + KIMAP::SelectJob *examine = static_cast(job); + doRename(examine->session()); } -QString MoveCollectionTask::mailBoxForCollections( const Akonadi::Collection& parent, const Akonadi::Collection& child ) const +QString MoveCollectionTask::mailBoxForCollections(const Akonadi::Collection &parent, const Akonadi::Collection &child) const { - const QString parentMailbox = mailBoxForCollection( parent ); - if ( parentMailbox.isEmpty() ) { - return child.remoteId().mid(1); //Strip separator on toplevel mailboxes - } - return parentMailbox + child.remoteId(); + const QString parentMailbox = mailBoxForCollection(parent); + if (parentMailbox.isEmpty()) { + return child.remoteId().mid(1); //Strip separator on toplevel mailboxes + } + return parentMailbox + child.remoteId(); } -void MoveCollectionTask::doRename( KIMAP::Session *session ) +void MoveCollectionTask::doRename(KIMAP::Session *session) { - // collection.remoteId() already includes the separator - const QString oldMailBox = mailBoxForCollections( sourceCollection(), collection() ); - const QString newMailBox = mailBoxForCollections( targetCollection(), collection() ); + // collection.remoteId() already includes the separator + const QString oldMailBox = mailBoxForCollections(sourceCollection(), collection()); + const QString newMailBox = mailBoxForCollections(targetCollection(), collection()); - if ( oldMailBox != newMailBox ) { - KIMAP::RenameJob *job = new KIMAP::RenameJob( session ); - job->setSourceMailBox( oldMailBox ); - job->setDestinationMailBox( newMailBox ); + if (oldMailBox != newMailBox) { + KIMAP::RenameJob *job = new KIMAP::RenameJob(session); + job->setSourceMailBox(oldMailBox); + job->setDestinationMailBox(newMailBox); - connect( job, SIGNAL(result(KJob*)), - this, SLOT(onRenameDone(KJob*)) ); + connect(job, &KIMAP::RenameJob::result, this, &MoveCollectionTask::onRenameDone); - job->start(); + job->start(); - } else { - changeProcessed(); - } + } else { + changeProcessed(); + } } -void MoveCollectionTask::onRenameDone( KJob *job ) +void MoveCollectionTask::onRenameDone(KJob *job) { - if ( job->error() ) { - cancelTask( job->errorString() ); - } else { - // Automatically subscribe to the new mailbox name - KIMAP::RenameJob *rename = static_cast( job ); + if (job->error()) { + cancelTask(job->errorString()); + } else { + // Automatically subscribe to the new mailbox name + KIMAP::RenameJob *rename = static_cast(job); - KIMAP::SubscribeJob *subscribe = new KIMAP::SubscribeJob( rename->session() ); - subscribe->setMailBox( rename->destinationMailBox() ); + KIMAP::SubscribeJob *subscribe = new KIMAP::SubscribeJob(rename->session()); + subscribe->setMailBox(rename->destinationMailBox()); - connect( subscribe, SIGNAL(result(KJob*)), - this, SLOT(onSubscribeDone(KJob*)) ); + connect(subscribe, &KIMAP::SubscribeJob::result, this, &MoveCollectionTask::onSubscribeDone); - subscribe->start(); - } + subscribe->start(); + } } -void MoveCollectionTask::onSubscribeDone( KJob *job ) +void MoveCollectionTask::onSubscribeDone(KJob *job) { - if ( job->error() ) { - emitWarning( i18n( "Failed to subscribe to the folder '%1' on the IMAP server. " - "It will disappear on next sync. Use the subscription dialog to overcome that", - collection().name() ) ); - } + if (job->error()) { + emitWarning(i18n("Failed to subscribe to the folder '%1' on the IMAP server. " + "It will disappear on next sync. Use the subscription dialog to overcome that", + collection().name())); + } - changeCommitted( collection() ); + changeCommitted(collection()); } - - diff -Nru kdepim-runtime-4.14.6/resources/imap/movecollectiontask.h kdepim-runtime-15.08.0/resources/imap/movecollectiontask.h --- kdepim-runtime-4.14.6/resources/imap/movecollectiontask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/movecollectiontask.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,25 +26,25 @@ class MoveCollectionTask : public ResourceTask { - Q_OBJECT + Q_OBJECT public: - explicit MoveCollectionTask( ResourceStateInterface::Ptr resource, QObject *parent = 0 ); - virtual ~MoveCollectionTask(); + explicit MoveCollectionTask(ResourceStateInterface::Ptr resource, QObject *parent = Q_NULLPTR); + virtual ~MoveCollectionTask(); -private slots: - void onExamineDone( KJob *job ); - void onRenameDone( KJob *job ); - void onSubscribeDone( KJob *job ); +private Q_SLOTS: + void onExamineDone(KJob *job); + void onRenameDone(KJob *job); + void onSubscribeDone(KJob *job); protected: - virtual void doStart( KIMAP::Session *session ); + void doStart(KIMAP::Session *session) Q_DECL_OVERRIDE; private: - void doRename( KIMAP::Session *session ); - QString mailBoxForCollections( const Akonadi::Collection &parent, const Akonadi::Collection &child ) const; + void doRename(KIMAP::Session *session); + QString mailBoxForCollections(const Akonadi::Collection &parent, const Akonadi::Collection &child) const; - Akonadi::Collection m_collection; + Akonadi::Collection m_collection; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/moveitemstask.cpp kdepim-runtime-15.08.0/resources/imap/moveitemstask.cpp --- kdepim-runtime-4.14.6/resources/imap/moveitemstask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/moveitemstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,8 +23,8 @@ #include -#include -#include +#include "imapresource_debug.h" +#include #include #include @@ -37,8 +37,8 @@ #include "imapflags.h" #include "uidnextattribute.h" -MoveItemsTask::MoveItemsTask( ResourceStateInterface::Ptr resource, QObject *parent ) - : ResourceTask( DeferIfNoSession, resource, parent ) +MoveItemsTask::MoveItemsTask(ResourceStateInterface::Ptr resource, QObject *parent) + : ResourceTask(DeferIfNoSession, resource, parent) { } @@ -47,272 +47,267 @@ { } -void MoveItemsTask::doStart( KIMAP::Session *session ) +void MoveItemsTask::doStart(KIMAP::Session *session) { - if ( item().remoteId().isEmpty() ) { - kWarning() << "Failed: messages has no rid"; - emitError( i18n( "Cannot move message, it does not exist on the server." ) ); - changeProcessed(); - return; - } - - if ( sourceCollection().remoteId().isEmpty() ) { - kWarning() << "Failed: source collection has no rid"; - emitError( i18n( "Cannot move message out of '%1', '%1' does not exist on the server.", - sourceCollection().name() ) ); - changeProcessed(); - return; - } - - if ( targetCollection().remoteId().isEmpty() ) { - kWarning() << "Failed: target collection has no rid"; - emitError( i18n( "Cannot move message to '%1', '%1' does not exist on the server.", - targetCollection().name() ) ); - changeProcessed(); - return; - } - - const QString oldMailBox = mailBoxForCollection( sourceCollection() ); - const QString newMailBox = mailBoxForCollection( targetCollection() ); - - if ( oldMailBox == newMailBox ) { - kDebug() << "Nothing to do, same mailbox"; - changeProcessed(); - return; - } - - if ( session->selectedMailBox() != oldMailBox ) { - KIMAP::SelectJob *select = new KIMAP::SelectJob( session ); - - select->setMailBox( oldMailBox ); - connect( select, SIGNAL(result(KJob*)), - this, SLOT(onSelectDone(KJob*)) ); - - select->start(); - } else { - triggerCopyJob( session ); - } -} - -void MoveItemsTask::onSelectDone( KJob *job ) -{ - if ( job->error() ) { - kWarning() << "Select failed: " << job->errorString(); - cancelTask( job->errorString() ); - - } else { - KIMAP::SelectJob *select = static_cast( job ); - triggerCopyJob( select->session() ); - } -} - -void MoveItemsTask::triggerCopyJob( KIMAP::Session *session ) -{ - const QString newMailBox = mailBoxForCollection( targetCollection() ); - - KIMAP::ImapSet set; - - // save message id, might be needed later to search for the - // resulting message uid. - foreach ( const Akonadi::Item &item, items() ) { - try { - KMime::Message::Ptr msg = item.payload(); - const QByteArray messageId = msg->messageID()->asUnicodeString().toUtf8(); - if ( !messageId.isEmpty() ) { - m_messageIds.insert( item.id(), messageId ); - } + if (item().remoteId().isEmpty()) { + qCWarning(IMAPRESOURCE_LOG) << "Failed: messages has no rid"; + emitError(i18n("Cannot move message, it does not exist on the server.")); + changeProcessed(); + return; + } - set.add( item.remoteId().toLong() ); - } catch ( Akonadi::PayloadException e ) { - kWarning() << "Copy failed, payload exception " << item.id() << item.remoteId(); - cancelTask( i18n( "Failed to copy item, it has no message payload. Remote id: %1", item.remoteId() ) ); + if (sourceCollection().remoteId().isEmpty()) { + qCWarning(IMAPRESOURCE_LOG) << "Failed: source collection has no rid"; + emitError(i18n("Cannot move message out of '%1', '%1' does not exist on the server.", + sourceCollection().name())); + changeProcessed(); return; } - } - KIMAP::CopyJob *copy = new KIMAP::CopyJob( session ); + if (targetCollection().remoteId().isEmpty()) { + qCWarning(IMAPRESOURCE_LOG) << "Failed: target collection has no rid"; + emitError(i18n("Cannot move message to '%1', '%1' does not exist on the server.", + targetCollection().name())); + changeProcessed(); + return; + } - copy->setUidBased( true ); - copy->setSequenceSet( set ); - copy->setMailBox( newMailBox ); + const QString oldMailBox = mailBoxForCollection(sourceCollection()); + const QString newMailBox = mailBoxForCollection(targetCollection()); - connect( copy, SIGNAL(result(KJob*)), - this, SLOT(onCopyDone(KJob*)) ); + if (oldMailBox == newMailBox) { + qCDebug(IMAPRESOURCE_LOG) << "Nothing to do, same mailbox"; + changeProcessed(); + return; + } + + if (session->selectedMailBox() != oldMailBox) { + KIMAP::SelectJob *select = new KIMAP::SelectJob(session); + + select->setMailBox(oldMailBox); + connect(select, &KIMAP::SelectJob::result, this, &MoveItemsTask::onSelectDone); + + select->start(); + } else { + triggerCopyJob(session); + } +} - copy->start(); +void MoveItemsTask::onSelectDone(KJob *job) +{ + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Select failed: " << job->errorString(); + cancelTask(job->errorString()); - m_oldSet = set; + } else { + KIMAP::SelectJob *select = static_cast(job); + triggerCopyJob(select->session()); + } } -void MoveItemsTask::onCopyDone( KJob *job ) +void MoveItemsTask::triggerCopyJob(KIMAP::Session *session) { - if ( job->error() ) { - kWarning() << job->errorString(); - cancelTask( job->errorString() ); + const QString newMailBox = mailBoxForCollection(targetCollection()); - } else { - KIMAP::CopyJob *copy = static_cast( job ); + KIMAP::ImapSet set; - m_newUids = imapSetToList( copy->resultingUids() ); + // save message id, might be needed later to search for the + // resulting message uid. + foreach (const Akonadi::Item &item, items()) { + try { + KMime::Message::Ptr msg = item.payload(); + const QByteArray messageId = msg->messageID()->asUnicodeString().toUtf8(); + if (!messageId.isEmpty()) { + m_messageIds.insert(item.id(), messageId); + } + + set.add(item.remoteId().toLong()); + } catch (const Akonadi::PayloadException &e) { + qCWarning(IMAPRESOURCE_LOG) << "Copy failed, payload exception " << item.id() << item.remoteId(); + cancelTask(i18n("Failed to copy item, it has no message payload. Remote id: %1", item.remoteId())); + return; + } + } + + KIMAP::CopyJob *copy = new KIMAP::CopyJob(session); - // Mark the old one ready for deletion - KIMAP::StoreJob *store = new KIMAP::StoreJob( copy->session() ); + copy->setUidBased(true); + copy->setSequenceSet(set); + copy->setMailBox(newMailBox); - store->setUidBased( true ); - store->setSequenceSet( m_oldSet ); - store->setFlags( QList() << ImapFlags::Deleted ); - store->setMode( KIMAP::StoreJob::AppendFlags ); + connect(copy, &KIMAP::CopyJob::result, this, &MoveItemsTask::onCopyDone); - connect( store, SIGNAL(result(KJob*)), - this, SLOT(onStoreFlagsDone(KJob*)) ); + copy->start(); - store->start(); - } + m_oldSet = set; } -void MoveItemsTask::onStoreFlagsDone( KJob *job ) +void MoveItemsTask::onCopyDone(KJob *job) { - if ( job->error() ) { - kWarning() << "Failed to mark message as deleted on source server: " << job->errorString(); - emitWarning( i18n( "Failed to mark the message from '%1' for deletion on the IMAP server. " - "It will reappear on next sync.", - sourceCollection().name() ) ); - } + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << job->errorString(); + cancelTask(job->errorString()); - if ( !m_newUids.isEmpty() ) { - recordNewUid(); - } else { - // Let's go for a search to find the new UID :-) + } else { + KIMAP::CopyJob *copy = static_cast(job); + + m_newUids = imapSetToList(copy->resultingUids()); + + // Mark the old one ready for deletion + KIMAP::StoreJob *store = new KIMAP::StoreJob(copy->session()); - // We did a copy we're very likely not in the right mailbox - KIMAP::StoreJob *store = static_cast( job ); - KIMAP::SelectJob *select = new KIMAP::SelectJob( store->session() ); - select->setMailBox( mailBoxForCollection( targetCollection() ) ); + store->setUidBased(true); + store->setSequenceSet(m_oldSet); + store->setFlags(QList() << ImapFlags::Deleted); + store->setMode(KIMAP::StoreJob::AppendFlags); - connect( select, SIGNAL(result(KJob*)), - this, SLOT(onPreSearchSelectDone(KJob*)) ); + connect(store, &KIMAP::StoreJob::result, this, &MoveItemsTask::onStoreFlagsDone); - select->start(); - } + store->start(); + } } -void MoveItemsTask::onPreSearchSelectDone( KJob *job ) +void MoveItemsTask::onStoreFlagsDone(KJob *job) { - if ( job->error() ) { - kWarning() << "Select failed: " << job->errorString(); - cancelTask( job->errorString() ); - return; - } + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Failed to mark message as deleted on source server: " << job->errorString(); + emitWarning(i18n("Failed to mark the message from '%1' for deletion on the IMAP server. " + "It will reappear on next sync.", + sourceCollection().name())); + } - KIMAP::SelectJob *select = static_cast( job ); - KIMAP::SearchJob *search = new KIMAP::SearchJob( select->session() ); + if (!m_newUids.isEmpty()) { + recordNewUid(); + } else { + // Let's go for a search to find the new UID :-) - search->setUidBased( true ); + // We did a copy we're very likely not in the right mailbox + KIMAP::StoreJob *store = static_cast(job); + KIMAP::SelectJob *select = new KIMAP::SelectJob(store->session()); + select->setMailBox(mailBoxForCollection(targetCollection())); - if ( !m_messageIds.isEmpty() ) { - search->setSearchLogic( KIMAP::SearchJob::Or ); + connect(select, &KIMAP::SelectJob::result, this, &MoveItemsTask::onPreSearchSelectDone); - foreach ( const QByteArray &messageId, m_messageIds ) { - QByteArray header = "Message-ID "; - header+= messageId; - search->addSearchCriteria( KIMAP::SearchJob::Header, header ); + select->start(); } - } else { - search->setSearchLogic( KIMAP::SearchJob::And ); - search->addSearchCriteria( KIMAP::SearchJob::New ); +} - UidNextAttribute *uidNext = targetCollection().attribute(); - if ( !uidNext ) { - cancelTask( i18n( "Could not determine the UID for the newly created message on the server" ) ); - search->deleteLater(); - return; +void MoveItemsTask::onPreSearchSelectDone(KJob *job) +{ + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Select failed: " << job->errorString(); + cancelTask(job->errorString()); + return; } - KIMAP::ImapInterval interval( uidNext->uidNext() ); - search->addSearchCriteria( KIMAP::SearchJob::Uid, interval.toImapSequence() ); - } + KIMAP::SelectJob *select = static_cast(job); + KIMAP::SearchJob *search = new KIMAP::SearchJob(select->session()); + + search->setUidBased(true); - connect( search, SIGNAL(result(KJob*)), - this, SLOT(onSearchDone(KJob*)) ); + if (!m_messageIds.isEmpty()) { + search->setSearchLogic(KIMAP::SearchJob::Or); + + foreach (const QByteArray &messageId, m_messageIds) { + QByteArray header = "Message-ID "; + header += messageId; + search->addSearchCriteria(KIMAP::SearchJob::Header, header); + } + } else { + search->setSearchLogic(KIMAP::SearchJob::And); + search->addSearchCriteria(KIMAP::SearchJob::New); - search->start(); + UidNextAttribute *uidNext = targetCollection().attribute(); + if (!uidNext) { + cancelTask(i18n("Could not determine the UID for the newly created message on the server")); + search->deleteLater(); + return; + } + KIMAP::ImapInterval interval(uidNext->uidNext()); + + search->addSearchCriteria(KIMAP::SearchJob::Uid, interval.toImapSequence()); + } + + connect(search, &KIMAP::SearchJob::result, this, &MoveItemsTask::onSearchDone); + + search->start(); } -void MoveItemsTask::onSearchDone( KJob *job ) +void MoveItemsTask::onSearchDone(KJob *job) { - if ( job->error() ) { - kWarning() << "Search failed: " << job->errorString(); - cancelTask( job->errorString() ); - return; - } + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Search failed: " << job->errorString(); + cancelTask(job->errorString()); + return; + } - KIMAP::SearchJob *search = static_cast( job ); - m_newUids = search->results(); + KIMAP::SearchJob *search = static_cast(job); + m_newUids = search->results(); - recordNewUid(); + recordNewUid(); } void MoveItemsTask::recordNewUid() { - // Create the item resulting of the operation, since at that point - // the first part of the move succeeded - QList oldUids = imapSetToList( m_oldSet ); - - Akonadi::Item::List newItems; - for (int i = 0; i < oldUids.count(); ++i) { - const QString oldUid = QString::number( oldUids.at( i ) ); - Akonadi::Item item; - Q_FOREACH ( const Akonadi::Item &it, items() ) { - if ( it.remoteId() == oldUid ) { - item = it; - break; + // Create the item resulting of the operation, since at that point + // the first part of the move succeeded + QList oldUids = imapSetToList(m_oldSet); + + Akonadi::Item::List newItems; + for (int i = 0; i < oldUids.count(); ++i) { + const QString oldUid = QString::number(oldUids.at(i)); + Akonadi::Item item; + Q_FOREACH (const Akonadi::Item &it, items()) { + if (it.remoteId() == oldUid) { + item = it; + break; + } } - } - Q_ASSERT ( item.isValid() ); + Q_ASSERT(item.isValid()); - // Update the item content with the new UID from the copy - // if we didn't manage to get a valid UID from the server, use a random RID instead - // this will make ItemSync clean up the mess during the next sync (while empty RIDs are protected as not yet existing on the server) - if ( m_newUids.count() <= i ) { - item.setRemoteId( QUuid::createUuid() ); - } else { - item.setRemoteId( QString::number( m_newUids.at( i ) ) ); + // Update the item content with the new UID from the copy + // if we didn't manage to get a valid UID from the server, use a random RID instead + // this will make ItemSync clean up the mess during the next sync (while empty RIDs are protected as not yet existing on the server) + if (m_newUids.count() <= i) { + item.setRemoteId(QUuid::createUuid().toString()); + } else { + item.setRemoteId(QString::number(m_newUids.at(i))); + } + newItems << item; } - newItems << item; - } - changesCommitted( newItems ); + changesCommitted(newItems); - Akonadi::Collection c = targetCollection(); + Akonadi::Collection c = targetCollection(); - // Get the current uid next value and store it - UidNextAttribute *uidAttr = 0; - int oldNextUid = 0; - if ( c.hasAttribute( "uidnext" ) ) { - uidAttr = static_cast( c.attribute( "uidnext" ) ); - oldNextUid = uidAttr->uidNext(); - } - - // If the uid we just got back is the expected next one of the box - // then update the property to the probable next uid to keep the cache in sync. - // If not something happened in our back, so we don't update and a refetch will - // happen at some point. - if ( !m_newUids.isEmpty() && m_newUids.last() == oldNextUid ) { - if ( uidAttr == 0 ) { - uidAttr = new UidNextAttribute( m_newUids.last() + 1 ); - c.addAttribute( uidAttr ); - } else { - uidAttr->setUidNext( m_newUids.last() + 1 ); + // Get the current uid next value and store it + UidNextAttribute *uidAttr = Q_NULLPTR; + int oldNextUid = 0; + if (c.hasAttribute("uidnext")) { + uidAttr = static_cast(c.attribute("uidnext")); + oldNextUid = uidAttr->uidNext(); } - applyCollectionChanges( c ); - } + // If the uid we just got back is the expected next one of the box + // then update the property to the probable next uid to keep the cache in sync. + // If not something happened in our back, so we don't update and a refetch will + // happen at some point. + if (!m_newUids.isEmpty() && m_newUids.last() == oldNextUid) { + if (uidAttr == Q_NULLPTR) { + uidAttr = new UidNextAttribute(m_newUids.last() + 1); + c.addAttribute(uidAttr); + } else { + uidAttr->setUidNext(m_newUids.last() + 1); + } + + applyCollectionChanges(c); + } } -QList< qint64 > MoveItemsTask::imapSetToList(const KIMAP::ImapSet& set) +QList< qint64 > MoveItemsTask::imapSetToList(const KIMAP::ImapSet &set) { QList list; - foreach ( const KIMAP::ImapInterval &interval, set.intervals() ) { + foreach (const KIMAP::ImapInterval &interval, set.intervals()) { for (qint64 i = interval.begin(); i <= interval.end(); ++i) { list << i; } @@ -321,6 +316,3 @@ return list; } - - - diff -Nru kdepim-runtime-4.14.6/resources/imap/moveitemstask.h kdepim-runtime-15.08.0/resources/imap/moveitemstask.h --- kdepim-runtime-4.14.6/resources/imap/moveitemstask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/moveitemstask.h 2015-08-10 21:01:02.000000000 +0000 @@ -28,31 +28,31 @@ class MoveItemsTask : public ResourceTask { - Q_OBJECT + Q_OBJECT public: - explicit MoveItemsTask( ResourceStateInterface::Ptr resource, QObject *parent = 0 ); - virtual ~MoveItemsTask(); + explicit MoveItemsTask(ResourceStateInterface::Ptr resource, QObject *parent = Q_NULLPTR); + virtual ~MoveItemsTask(); -private slots: - void onSelectDone( KJob *job ); - void onCopyDone( KJob *job ); - void onStoreFlagsDone( KJob *job ); +private Q_SLOTS: + void onSelectDone(KJob *job); + void onCopyDone(KJob *job); + void onStoreFlagsDone(KJob *job); - void onPreSearchSelectDone( KJob *job ); - void onSearchDone( KJob *job ); + void onPreSearchSelectDone(KJob *job); + void onSearchDone(KJob *job); protected: - virtual void doStart( KIMAP::Session *session ); + void doStart(KIMAP::Session *session) Q_DECL_OVERRIDE; private: - void triggerCopyJob( KIMAP::Session *session ); - void recordNewUid(); - QList imapSetToList( const KIMAP::ImapSet &set ); - - KIMAP::ImapSet m_oldSet; - QList m_newUids; - QMap m_messageIds; + void triggerCopyJob(KIMAP::Session *session); + void recordNewUid(); + QList imapSetToList(const KIMAP::ImapSet &set); + + KIMAP::ImapSet m_oldSet; + QList m_newUids; + QMap m_messageIds; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/noinferiorsattribute.cpp kdepim-runtime-15.08.0/resources/imap/noinferiorsattribute.cpp --- kdepim-runtime-4.14.6/resources/imap/noinferiorsattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/noinferiorsattribute.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -16,19 +16,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - #include "noinferiorsattribute.h" #include -#include +#include -NoInferiorsAttribute::NoInferiorsAttribute( bool noInferiors ) -: mNoInferiors( noInferiors ) +NoInferiorsAttribute::NoInferiorsAttribute(bool noInferiors) + : mNoInferiors(noInferiors) { } -void NoInferiorsAttribute::setNoInferiors( bool noInferiors ) +void NoInferiorsAttribute::setNoInferiors(bool noInferiors) { mNoInferiors = noInferiors; } @@ -40,21 +39,21 @@ QByteArray NoInferiorsAttribute::type() const { - static const QByteArray sType( "noinferiors" ); + static const QByteArray sType("noinferiors"); return sType; } -Akonadi::Attribute* NoInferiorsAttribute::clone() const +Akonadi::Attribute *NoInferiorsAttribute::clone() const { - return new NoInferiorsAttribute( mNoInferiors ); + return new NoInferiorsAttribute(mNoInferiors); } QByteArray NoInferiorsAttribute::serialized() const { - return mNoInferiors ? QByteArray::number( 1 ) : QByteArray::number( 0 ); + return mNoInferiors ? QByteArray::number(1) : QByteArray::number(0); } -void NoInferiorsAttribute::deserialize( const QByteArray &data ) +void NoInferiorsAttribute::deserialize(const QByteArray &data) { - mNoInferiors = ( data.toInt() == 0 ) ? false : true; + mNoInferiors = (data.toInt() == 0) ? false : true; } diff -Nru kdepim-runtime-4.14.6/resources/imap/noinferiorsattribute.h kdepim-runtime-15.08.0/resources/imap/noinferiorsattribute.h --- kdepim-runtime-4.14.6/resources/imap/noinferiorsattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/noinferiorsattribute.h 2015-08-10 21:01:02.000000000 +0000 @@ -16,22 +16,21 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - #ifndef NOINFERIORSATTRIBUTE_H #define NOINFERIORSATTRIBUTE_H -#include +#include class NoInferiorsAttribute : public Akonadi::Attribute { public: - explicit NoInferiorsAttribute( bool noInferiors = false ); - void setNoInferiors( bool noInferiors ); + explicit NoInferiorsAttribute(bool noInferiors = false); + void setNoInferiors(bool noInferiors); bool noInferiors() const; - virtual QByteArray type() const; - virtual Attribute* clone() const; - virtual QByteArray serialized() const; - virtual void deserialize( const QByteArray &data ); + QByteArray type() const Q_DECL_OVERRIDE; + Attribute *clone() const Q_DECL_OVERRIDE; + QByteArray serialized() const Q_DECL_OVERRIDE; + void deserialize(const QByteArray &data) Q_DECL_OVERRIDE; private: bool mNoInferiors; diff -Nru kdepim-runtime-4.14.6/resources/imap/noselectattribute.cpp kdepim-runtime-15.08.0/resources/imap/noselectattribute.cpp --- kdepim-runtime-4.14.6/resources/imap/noselectattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/noselectattribute.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,14 +21,14 @@ #include -#include +#include -NoSelectAttribute::NoSelectAttribute( bool noSelect ) - : mNoSelect( noSelect ) +NoSelectAttribute::NoSelectAttribute(bool noSelect) + : mNoSelect(noSelect) { } -void NoSelectAttribute::setNoSelect( bool noSelect ) +void NoSelectAttribute::setNoSelect(bool noSelect) { mNoSelect = noSelect; } @@ -40,21 +40,21 @@ QByteArray NoSelectAttribute::type() const { - static const QByteArray sType( "noselect" ); + static const QByteArray sType("noselect"); return sType; } -Akonadi::Attribute* NoSelectAttribute::clone() const +Akonadi::Attribute *NoSelectAttribute::clone() const { - return new NoSelectAttribute( mNoSelect ); + return new NoSelectAttribute(mNoSelect); } QByteArray NoSelectAttribute::serialized() const { - return mNoSelect ? QByteArray::number( 1 ) : QByteArray::number( 0 ); + return mNoSelect ? QByteArray::number(1) : QByteArray::number(0); } -void NoSelectAttribute::deserialize( const QByteArray &data ) +void NoSelectAttribute::deserialize(const QByteArray &data) { - mNoSelect = ( data.toInt() == 0 ) ? false : true; + mNoSelect = (data.toInt() == 0) ? false : true; } diff -Nru kdepim-runtime-4.14.6/resources/imap/noselectattribute.h kdepim-runtime-15.08.0/resources/imap/noselectattribute.h --- kdepim-runtime-4.14.6/resources/imap/noselectattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/noselectattribute.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,18 +20,18 @@ #ifndef NOSELECTATTRIBUTE_H #define NOSELECTATTRIBUTE_H -#include +#include class NoSelectAttribute : public Akonadi::Attribute { public: - explicit NoSelectAttribute( bool noSelect = false ); - void setNoSelect( bool noSelect ); + explicit NoSelectAttribute(bool noSelect = false); + void setNoSelect(bool noSelect); bool noSelect() const; - virtual QByteArray type() const; - virtual Attribute* clone() const; - virtual QByteArray serialized() const; - virtual void deserialize( const QByteArray &data ); + QByteArray type() const Q_DECL_OVERRIDE; + Attribute *clone() const Q_DECL_OVERRIDE; + QByteArray serialized() const Q_DECL_OVERRIDE; + void deserialize(const QByteArray &data) Q_DECL_OVERRIDE; private: bool mNoSelect; diff -Nru kdepim-runtime-4.14.6/resources/imap/passwordrequesterinterface.cpp kdepim-runtime-15.08.0/resources/imap/passwordrequesterinterface.cpp --- kdepim-runtime-4.14.6/resources/imap/passwordrequesterinterface.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/passwordrequesterinterface.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,8 +21,8 @@ #include "passwordrequesterinterface.h" -PasswordRequesterInterface::PasswordRequesterInterface( QObject *parent ) - : QObject( parent ) +PasswordRequesterInterface::PasswordRequesterInterface(QObject *parent) + : QObject(parent) { } diff -Nru kdepim-runtime-4.14.6/resources/imap/passwordrequesterinterface.h kdepim-runtime-15.08.0/resources/imap/passwordrequesterinterface.h --- kdepim-runtime-4.14.6/resources/imap/passwordrequesterinterface.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/passwordrequesterinterface.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,32 +26,32 @@ class PasswordRequesterInterface : public QObject { - Q_OBJECT - Q_ENUMS( ResultType RequestType ) + Q_OBJECT + Q_ENUMS(ResultType RequestType) public: - enum ResultType { - PasswordRetrieved, - ReconnectNeeded, - UserRejected, - EmptyPasswordEntered - }; - - enum RequestType { - StandardRequest, - WrongPasswordRequest - }; + enum ResultType { + PasswordRetrieved, + ReconnectNeeded, + UserRejected, + EmptyPasswordEntered + }; + + enum RequestType { + StandardRequest, + WrongPasswordRequest + }; protected: - PasswordRequesterInterface( QObject *parent = 0 ); + explicit PasswordRequesterInterface(QObject *parent = Q_NULLPTR); public: - virtual void requestPassword( RequestType request = StandardRequest, - const QString &serverError = QString() ) = 0; - virtual void cancelPasswordRequests(); + virtual void requestPassword(RequestType request = StandardRequest, + const QString &serverError = QString()) = 0; + virtual void cancelPasswordRequests(); -signals: - void done( int resultType, const QString &password = QString() ); +Q_SIGNALS: + void done(int resultType, const QString &password = QString()); }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/removecollectionrecursivetask.cpp kdepim-runtime-15.08.0/resources/imap/removecollectionrecursivetask.cpp --- kdepim-runtime-4.14.6/resources/imap/removecollectionrecursivetask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/removecollectionrecursivetask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,19 +21,21 @@ #include "removecollectionrecursivetask.h" -#include +#include #include #include #include #include #include -#include - -Q_DECLARE_METATYPE( KIMAP::DeleteJob* ) - -RemoveCollectionRecursiveTask::RemoveCollectionRecursiveTask( ResourceStateInterface::Ptr resource, QObject *parent ) - : ResourceTask( CancelIfNoSession, resource, parent ), - mSession( 0 ), mFolderFound( false ) +#include +#include "imapresource_debug.h" +#include "imapresource_debug.h" + +Q_DECLARE_METATYPE(KIMAP::DeleteJob *) + +RemoveCollectionRecursiveTask::RemoveCollectionRecursiveTask(ResourceStateInterface::Ptr resource, QObject *parent) + : ResourceTask(CancelIfNoSession, resource, parent), + mSession(Q_NULLPTR), mFolderFound(false) { } @@ -41,130 +43,129 @@ { } -void RemoveCollectionRecursiveTask::doStart( KIMAP::Session *session ) +void RemoveCollectionRecursiveTask::doStart(KIMAP::Session *session) { - mSession = session; + mSession = session; - mFolderFound = false; - KIMAP::ListJob *listJob = new KIMAP::ListJob( session ); - listJob->setIncludeUnsubscribed( !isSubscriptionEnabled() ); - listJob->setQueriedNamespaces( serverNamespaces() ); - connect( listJob, SIGNAL(mailBoxesReceived(QList,QList >)), - this, SLOT(onMailBoxesReceived(QList,QList >)) ); - connect( listJob, SIGNAL(result(KJob*)), SLOT(onJobDone(KJob*)) ); - listJob->start(); + mFolderFound = false; + KIMAP::ListJob *listJob = new KIMAP::ListJob(session); + listJob->setIncludeUnsubscribed(!isSubscriptionEnabled()); + listJob->setQueriedNamespaces(serverNamespaces()); + connect(listJob, &KIMAP::ListJob::mailBoxesReceived, + this, &RemoveCollectionRecursiveTask::onMailBoxesReceived); + connect(listJob, &KIMAP::ListJob::result, this, &RemoveCollectionRecursiveTask::onJobDone); + listJob->start(); } -void RemoveCollectionRecursiveTask::onMailBoxesReceived( const QList< KIMAP::MailBoxDescriptor > &descriptors, - const QList< QList >& ) +void RemoveCollectionRecursiveTask::onMailBoxesReceived(const QList< KIMAP::MailBoxDescriptor > &descriptors, + const QList< QList > &) { - const QString mailBox = mailBoxForCollection( collection() ); + const QString mailBox = mailBoxForCollection(collection()); - // We have to delete the deepest-nested folders first, so - // we use a map here that has the level of nesting as key. - QMultiMap foldersToDelete; + // We have to delete the deepest-nested folders first, so + // we use a map here that has the level of nesting as key. + QMultiMap foldersToDelete; - for ( int i = 0; i < descriptors.size(); ++i ) { - const KIMAP::MailBoxDescriptor descriptor = descriptors[ i ]; + for (int i = 0; i < descriptors.size(); ++i) { + const KIMAP::MailBoxDescriptor descriptor = descriptors[ i ]; - if ( descriptor.name == mailBox || descriptor.name.startsWith( mailBox + descriptor.separator ) ) { // a sub folder to delete - const QStringList pathParts = descriptor.name.split( descriptor.separator ); - foldersToDelete.insert( pathParts.count(), descriptor ); + if (descriptor.name == mailBox || descriptor.name.startsWith(mailBox + descriptor.separator)) { // a sub folder to delete + const QStringList pathParts = descriptor.name.split(descriptor.separator); + foldersToDelete.insert(pathParts.count(), descriptor); + } } - } - if ( foldersToDelete.isEmpty() ) { - return; - } + if (foldersToDelete.isEmpty()) { + return; + } - mFolderFound = true; + mFolderFound = true; - // Now start the actual deletion work - mFolderIterator.reset( new QMapIterator( foldersToDelete ) ); - mFolderIterator->toBack(); // we start with largest nesting value first + // Now start the actual deletion work + mFolderIterator.reset(new QMapIterator(foldersToDelete)); + mFolderIterator->toBack(); // we start with largest nesting value first - deleteNextMailbox(); + deleteNextMailbox(); } void RemoveCollectionRecursiveTask::deleteNextMailbox() { - if ( !mFolderIterator->hasPrevious() ) { - changeProcessed(); // finish the job - return; - } - - mFolderIterator->previous(); - const KIMAP::MailBoxDescriptor &descriptor = mFolderIterator->value(); - kDebug() << descriptor.name; - - // first select the mailbox - KIMAP::SelectJob *selectJob = new KIMAP::SelectJob( mSession ); - selectJob->setMailBox( descriptor.name ); - connect( selectJob, SIGNAL(result(KJob*)), SLOT(onJobDone(KJob*)) ); - selectJob->start(); - - // mark all items as deleted - // This step shouldn't be required, but apparently some servers don't allow deleting, non empty mailboxes (although they should). - KIMAP::ImapSet allItems; - allItems.add( KIMAP::ImapInterval( 1, 0 ) ); // means 1:* - KIMAP::StoreJob *storeJob = new KIMAP::StoreJob( mSession ); - storeJob->setSequenceSet( allItems ); - storeJob->setFlags( KIMAP::MessageFlags() << Akonadi::MessageFlags::Deleted ); - storeJob->setMode( KIMAP::StoreJob::AppendFlags ); - // The result is explicitly ignored, since this can fail in the case of an empty folder - storeJob->start(); - - // Some IMAP servers don't allow deleting an opened mailbox, so make sure - // it's not opened (https://bugs.kde.org/show_bug.cgi?id=324932). CLOSE will - // also trigger EXPUNGE to take care of the messages deleted above - KIMAP::CloseJob *closeJob = new KIMAP::CloseJob( mSession ); - closeJob->setProperty( "folderDescriptor", descriptor.name ); - connect( closeJob, SIGNAL(result(KJob*)), SLOT(onCloseJobDone(KJob*)) ); - closeJob->start(); -} - -void RemoveCollectionRecursiveTask::onCloseJobDone( KJob* job ) -{ - if ( job->error() ) { - changeProcessed(); - kDebug( 5327 ) << "Failed to close the folder, resync the folder tree"; - emitWarning( i18n( "Failed to delete the folder, restoring folder list." ) ); - synchronizeCollectionTree(); - } else { - KIMAP::DeleteJob *deleteJob = new KIMAP::DeleteJob( mSession ); - deleteJob->setMailBox( job->property( "folderDescriptor" ).toString() ); - connect( deleteJob, SIGNAL(result(KJob*)), SLOT(onDeleteJobDone(KJob*)) ); - deleteJob->start(); - } + if (!mFolderIterator->hasPrevious()) { + changeProcessed(); // finish the job + return; + } + + mFolderIterator->previous(); + const KIMAP::MailBoxDescriptor &descriptor = mFolderIterator->value(); + qCDebug(IMAPRESOURCE_LOG) << descriptor.name; + + // first select the mailbox + KIMAP::SelectJob *selectJob = new KIMAP::SelectJob(mSession); + selectJob->setMailBox(descriptor.name); + connect(selectJob, &KIMAP::SelectJob::result, this, &RemoveCollectionRecursiveTask::onJobDone); + selectJob->start(); + + // mark all items as deleted + // This step shouldn't be required, but apparently some servers don't allow deleting, non empty mailboxes (although they should). + KIMAP::ImapSet allItems; + allItems.add(KIMAP::ImapInterval(1, 0)); // means 1:* + KIMAP::StoreJob *storeJob = new KIMAP::StoreJob(mSession); + storeJob->setSequenceSet(allItems); + storeJob->setFlags(KIMAP::MessageFlags() << Akonadi::MessageFlags::Deleted); + storeJob->setMode(KIMAP::StoreJob::AppendFlags); + // The result is explicitly ignored, since this can fail in the case of an empty folder + storeJob->start(); + + // Some IMAP servers don't allow deleting an opened mailbox, so make sure + // it's not opened (https://bugs.kde.org/show_bug.cgi?id=324932). CLOSE will + // also trigger EXPUNGE to take care of the messages deleted above + KIMAP::CloseJob *closeJob = new KIMAP::CloseJob(mSession); + closeJob->setProperty("folderDescriptor", descriptor.name); + connect(closeJob, &KIMAP::CloseJob::result, this, &RemoveCollectionRecursiveTask::onCloseJobDone); + closeJob->start(); +} + +void RemoveCollectionRecursiveTask::onCloseJobDone(KJob *job) +{ + if (job->error()) { + changeProcessed(); + qCDebug(IMAPRESOURCE_LOG) << "Failed to close the folder, resync the folder tree"; + emitWarning(i18n("Failed to delete the folder, restoring folder list.")); + synchronizeCollectionTree(); + } else { + KIMAP::DeleteJob *deleteJob = new KIMAP::DeleteJob(mSession); + deleteJob->setMailBox(job->property("folderDescriptor").toString()); + connect(deleteJob, &KIMAP::DeleteJob::result, this, &RemoveCollectionRecursiveTask::onDeleteJobDone); + deleteJob->start(); + } } +void RemoveCollectionRecursiveTask::onDeleteJobDone(KJob *job) +{ + if (job->error()) { + changeProcessed(); -void RemoveCollectionRecursiveTask::onDeleteJobDone( KJob* job ) -{ - if ( job->error() ) { - changeProcessed(); - - kDebug( 5327 ) << "Failed to delete the folder, resync the folder tree"; - emitWarning( i18n( "Failed to delete the folder, restoring folder list." ) ); - synchronizeCollectionTree(); - } else { - deleteNextMailbox(); - } + qCDebug(IMAPRESOURCE_LOG) << "Failed to delete the folder, resync the folder tree"; + emitWarning(i18n("Failed to delete the folder, restoring folder list.")); + synchronizeCollectionTree(); + } else { + deleteNextMailbox(); + } } -void RemoveCollectionRecursiveTask::onJobDone( KJob* job ) +void RemoveCollectionRecursiveTask::onJobDone(KJob *job) { - if ( job->error() ) { - changeProcessed(); + if (job->error()) { + changeProcessed(); - kDebug( 5327 ) << "Failed to delete the folder, resync the folder tree"; - emitWarning( i18n( "Failed to delete the folder, restoring folder list." ) ); - synchronizeCollectionTree(); - } else if ( !mFolderFound ) { - changeProcessed(); - kDebug( 5327 ) << "Failed to find the folder to be deleted, resync the folder tree"; - emitWarning( i18n( "Failed to find the folder to be deleted, restoring folder list." ) ); - synchronizeCollectionTree(); - } + qCDebug(IMAPRESOURCE_LOG) << "Failed to delete the folder, resync the folder tree"; + emitWarning(i18n("Failed to delete the folder, restoring folder list.")); + synchronizeCollectionTree(); + } else if (!mFolderFound) { + changeProcessed(); + qCDebug(IMAPRESOURCE_LOG) << "Failed to find the folder to be deleted, resync the folder tree"; + emitWarning(i18n("Failed to find the folder to be deleted, restoring folder list.")); + synchronizeCollectionTree(); + } } diff -Nru kdepim-runtime-4.14.6/resources/imap/removecollectionrecursivetask.h kdepim-runtime-15.08.0/resources/imap/removecollectionrecursivetask.h --- kdepim-runtime-4.14.6/resources/imap/removecollectionrecursivetask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/removecollectionrecursivetask.h 2015-08-10 21:01:02.000000000 +0000 @@ -28,29 +28,29 @@ class RemoveCollectionRecursiveTask : public ResourceTask { - Q_OBJECT + Q_OBJECT public: - explicit RemoveCollectionRecursiveTask( ResourceStateInterface::Ptr resource, QObject *parent = 0 ); - virtual ~RemoveCollectionRecursiveTask(); + explicit RemoveCollectionRecursiveTask(ResourceStateInterface::Ptr resource, QObject *parent = Q_NULLPTR); + virtual ~RemoveCollectionRecursiveTask(); -private slots: - void onMailBoxesReceived( const QList &descriptors, - const QList< QList > &flags ); - void onCloseJobDone( KJob *job ); - void onDeleteJobDone( KJob *job ); - void onJobDone( KJob *job ); +private Q_SLOTS: + void onMailBoxesReceived(const QList &descriptors, + const QList< QList > &flags); + void onCloseJobDone(KJob *job); + void onDeleteJobDone(KJob *job); + void onJobDone(KJob *job); protected: - virtual void doStart( KIMAP::Session *session ); + void doStart(KIMAP::Session *session) Q_DECL_OVERRIDE; private: - void deleteNextMailbox(); + void deleteNextMailbox(); - KIMAP::Session *mSession; - bool mFolderFound; + KIMAP::Session *mSession; + bool mFolderFound; - QScopedPointer< QMapIterator > mFolderIterator; + QScopedPointer< QMapIterator > mFolderIterator; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/replacemessagejob.cpp kdepim-runtime-15.08.0/resources/imap/replacemessagejob.cpp --- kdepim-runtime-4.14.6/resources/imap/replacemessagejob.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/replacemessagejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,184 @@ +/* + Copyright (c) 2014 Christian Mollekopf + + 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 "replacemessagejob.h" + +#include +#include +#include +#include +#include +#include "imapresource_debug.h" +#include + +#include "imapflags.h" + +ReplaceMessageJob::ReplaceMessageJob(const KMime::Message::Ptr &msg, KIMAP::Session *session, const QString &mailbox, qint64 uidNext, KIMAP::ImapSet oldUids, QObject *parent) + : KJob(parent), + mSession(session), + mMessage(msg), + mMailbox(mailbox), + mUidNext(uidNext), + mOldUids(oldUids), + mNewUid(-1), + mMessageId(msg->messageID()->asUnicodeString().toUtf8()) +{ +} + +void ReplaceMessageJob::start() +{ + KIMAP::AppendJob *job = new KIMAP::AppendJob(mSession); + job->setMailBox(mMailbox); + job->setContent(mMessage->encodedContent(true)); + job->setInternalDate(mMessage->date()->dateTime()); + connect(job, SIGNAL(result(KJob*)), SLOT(onAppendMessageDone(KJob*))); + job->start(); +} + +void ReplaceMessageJob::onAppendMessageDone(KJob *job) +{ + KIMAP::AppendJob *append = qobject_cast(job); + + if (append->error()) { + qCWarning(IMAPRESOURCE_LOG) << append->errorString(); + setError(KJob::UserDefinedError); + emitResult(); + return; + } + + // We get it directly if UIDPLUS is supported... + mNewUid = append->uid(); + + if (mNewUid > 0 && mOldUids.isEmpty()) { + //We have the uid an no message to delete, we're done + emitResult(); + return; + } + + if (mSession->selectedMailBox() != mMailbox) { + //For search and delete we need to select the right mailbox first + KIMAP::SelectJob *select = new KIMAP::SelectJob(mSession); + select->setMailBox(mMailbox); + connect(select, SIGNAL(result(KJob*)), this, SLOT(onSelectDone(KJob*))); + select->start(); + } else { + if (mNewUid > 0) { + triggerDeleteJobIfNecessary(); + } else { + triggerSearchJob(); + } + } +} + +void ReplaceMessageJob::onSelectDone(KJob *job) +{ + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << job->errorString(); + setError(KJob::UserDefinedError); + emitResult(); + } else { + if (mNewUid > 0) { + triggerDeleteJobIfNecessary(); + } else { + triggerSearchJob(); + } + } +} + +void ReplaceMessageJob::triggerSearchJob() +{ + KIMAP::SearchJob *search = new KIMAP::SearchJob(mSession); + + search->setUidBased(true); + search->setSearchLogic(KIMAP::SearchJob::And); + + if (!mMessageId.isEmpty()) { + QByteArray header = "Message-ID "; + header += mMessageId; + + search->addSearchCriteria(KIMAP::SearchJob::Header, header); + } else { + search->addSearchCriteria(KIMAP::SearchJob::New); + + if (mUidNext < 0) { + qCWarning(IMAPRESOURCE_LOG) << "Could not determine the UID for the newly created message on the server"; + search->deleteLater(); + setError(KJob::UserDefinedError); + emitResult(); + return; + } + search->addSearchCriteria(KIMAP::SearchJob::Uid, KIMAP::ImapInterval(mUidNext).toImapSequence()); + } + + connect(search, SIGNAL(result(KJob*)), + this, SLOT(onSearchDone(KJob*))); + + search->start(); +} + +void ReplaceMessageJob::onSearchDone(KJob *job) +{ + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << job->errorString(); + setError(KJob::UserDefinedError); + emitResult(); + return; + } + + KIMAP::SearchJob *search = static_cast(job); + + if (search->results().count() == 1) { + mNewUid = search->results().at(0); + } else { + qCWarning(IMAPRESOURCE_LOG) << "Failed to find uid for message. Got 0 or too many results: " << search->results().count(); + setError(KJob::UserDefinedError); + emitResult(); + return; + } + triggerDeleteJobIfNecessary(); +} + +void ReplaceMessageJob::triggerDeleteJobIfNecessary() +{ + if (mOldUids.isEmpty()) { + //Nothing to do, we're done + emitResult(); + } else { + KIMAP::StoreJob *store = new KIMAP::StoreJob(mSession); + store->setUidBased(true); + store->setSequenceSet(mOldUids); + store->setFlags(QList() << ImapFlags::Deleted); + store->setMode(KIMAP::StoreJob::AppendFlags); + connect(store, SIGNAL(result(KJob*)), this, SLOT(onDeleteDone(KJob*))); + store->start(); + } +} + +void ReplaceMessageJob::onDeleteDone(KJob *job) +{ + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << job->errorString(); + } + emitResult(); +} + +qint64 ReplaceMessageJob::newUid() const +{ + return mNewUid; +} diff -Nru kdepim-runtime-4.14.6/resources/imap/replacemessagejob.h kdepim-runtime-15.08.0/resources/imap/replacemessagejob.h --- kdepim-runtime-4.14.6/resources/imap/replacemessagejob.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/replacemessagejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,62 @@ +/* + Copyright (c) 2014 Christian Mollekopf + + 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 REPLACEMESSAGEJOB_H +#define REPLACEMESSAGEJOB_H + +#include +#include +#include +#include + +/** + * This job appends a message, marks the old one as deleted, and returns the uid of the appended message. + */ +class ReplaceMessageJob : public KJob +{ + Q_OBJECT +public: + ReplaceMessageJob(const KMime::Message::Ptr &msg, KIMAP::Session *session, const QString &mailbox, qint64 uidNext = -1, KIMAP::ImapSet oldUids = KIMAP::ImapSet(), QObject *parent = 0); + + qint64 newUid() const; + + void start(); + +private: + void triggerSearchJob(); + void triggerDeleteJobIfNecessary(); + +private Q_SLOTS: + void onAppendMessageDone(KJob *job); + void onSelectDone(KJob *job); + void onSearchDone(KJob *job); + void onDeleteDone(KJob *job); + +private: + KIMAP::Session *mSession; + const KMime::Message::Ptr mMessage; + const QString mMailbox; + qint64 mUidNext; + KIMAP::ImapSet mOldUids; + qint64 mNewUid; + const QByteArray mMessageId; +}; + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/imap/resourcestate.cpp kdepim-runtime-15.08.0/resources/imap/resourcestate.cpp --- kdepim-runtime-4.14.6/resources/imap/resourcestate.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/resourcestate.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,14 +26,15 @@ #include "sessionpool.h" #include "settings.h" #include "noselectattribute.h" -#include "timestampattribute.h" -#include +#include +#include #include +#include "imapresource_debug.h" -ResourceState::ResourceState( ImapResourceBase *resource, const TaskArguments &args ) - : m_resource( resource ), - m_arguments( args ) +ResourceState::ResourceState(ImapResourceBase *resource, const TaskArguments &args) + : m_resource(resource), + m_arguments(args) { } @@ -45,282 +46,271 @@ QString ResourceState::userName() const { - return m_resource->m_pool->account()->userName(); + return m_resource->m_pool->account()->userName(); } QString ResourceState::resourceName() const { - return m_resource->name(); + return m_resource->name(); +} + +QString ResourceState::resourceIdentifier() const +{ + return m_resource->identifier(); } QStringList ResourceState::serverCapabilities() const { - return m_resource->m_pool->serverCapabilities(); + return m_resource->m_pool->serverCapabilities(); } QList ResourceState::serverNamespaces() const { - return m_resource->m_pool->serverNamespaces(); + return m_resource->m_pool->serverNamespaces(); +} + +QList ResourceState::personalNamespaces() const +{ + return m_resource->m_pool->serverNamespaces(SessionPool::Personal); +} + +QList ResourceState::userNamespaces() const +{ + return m_resource->m_pool->serverNamespaces(SessionPool::User); +} + +QList ResourceState::sharedNamespaces() const +{ + return m_resource->m_pool->serverNamespaces(SessionPool::Shared); } bool ResourceState::isAutomaticExpungeEnabled() const { - return m_resource->settings()->automaticExpungeEnabled(); + return m_resource->settings()->automaticExpungeEnabled(); } bool ResourceState::isSubscriptionEnabled() const { - return m_resource->settings()->subscriptionEnabled(); + return m_resource->settings()->subscriptionEnabled(); } bool ResourceState::isDisconnectedModeEnabled() const { - return m_resource->settings()->disconnectedModeEnabled(); + return m_resource->settings()->disconnectedModeEnabled(); } int ResourceState::intervalCheckTime() const { - if ( m_resource->settings()->intervalCheckEnabled() ) - return m_resource->settings()->intervalCheckTime(); - else - return -1; // -1 for never + if (m_resource->settings()->intervalCheckEnabled()) { + return m_resource->settings()->intervalCheckTime(); + } else { + return -1; // -1 for never + } } Akonadi::Collection ResourceState::collection() const { - return m_arguments.collection; + return m_arguments.collection; } Akonadi::Item ResourceState::item() const { - if (m_arguments.items.count() > 1) { - kWarning() << "Called item() while state holds multiple items!"; - } + if (m_arguments.items.count() > 1) { + qCWarning(IMAPRESOURCE_LOG) << "Called item() while state holds multiple items!"; + } - return m_arguments.items.first(); + return m_arguments.items.first(); } Akonadi::Item::List ResourceState::items() const { - return m_arguments.items; + return m_arguments.items; } Akonadi::Collection ResourceState::parentCollection() const { - return m_arguments.parentCollection; + return m_arguments.parentCollection; } Akonadi::Collection ResourceState::sourceCollection() const { - return m_arguments.sourceCollection; + return m_arguments.sourceCollection; } Akonadi::Collection ResourceState::targetCollection() const { - return m_arguments.targetCollection; + return m_arguments.targetCollection; } QSet ResourceState::parts() const { - return m_arguments.parts; + return m_arguments.parts; } QSet ResourceState::addedFlags() const { - return m_arguments.addedFlags; + return m_arguments.addedFlags; } QSet ResourceState::removedFlags() const { - return m_arguments.removedFlags; + return m_arguments.removedFlags; } -QString ResourceState::rootRemoteId() const +Akonadi::Tag ResourceState::tag() const { - return m_resource->settings()->rootRemoteId(); + return m_arguments.tag; } -void ResourceState::setIdleCollection( const Akonadi::Collection &collection ) +QSet ResourceState::addedTags() const { - QStringList ridPath; - - Akonadi::Collection curCol = collection; - while ( curCol != Akonadi::Collection::root() && !curCol.remoteId().isEmpty() ) { - ridPath.append( curCol.remoteId() ); - curCol = curCol.parentCollection(); - } - - m_resource->settings()->setIdleRidPath( ridPath ); - m_resource->settings()->writeConfig(); + return m_arguments.addedTags; } -void ResourceState::applyCollectionChanges( const Akonadi::Collection &collection ) +QSet ResourceState::removedTags() const { - m_resource->modifyCollection(collection); + return m_arguments.removedTags; } -void ResourceState::collectionAttributesRetrieved( const Akonadi::Collection &collection ) +Akonadi::Relation::List ResourceState::addedRelations() const { - m_resource->collectionAttributesRetrieved( collection ); + return m_arguments.addedRelations; } -void ResourceState::itemRetrieved( const Akonadi::Item &item ) +Akonadi::Relation::List ResourceState::removedRelations() const { - m_resource->itemRetrieved( item ); + return m_arguments.removedRelations; } -void ResourceState::itemsRetrieved( const Akonadi::Item::List &items ) +QString ResourceState::rootRemoteId() const { - m_resource->itemsRetrieved( items ); + return m_resource->settings()->rootRemoteId(); } -void ResourceState::itemsRetrievedIncremental( const Akonadi::Item::List &changed, const Akonadi::Item::List &removed ) +void ResourceState::setIdleCollection(const Akonadi::Collection &collection) { - m_resource->itemsRetrievedIncremental( changed, removed ); + QStringList ridPath; + + Akonadi::Collection curCol = collection; + while (curCol != Akonadi::Collection::root() && !curCol.remoteId().isEmpty()) { + ridPath.append(curCol.remoteId()); + curCol = curCol.parentCollection(); + } + + m_resource->settings()->setIdleRidPath(ridPath); + m_resource->settings()->save(); } -void ResourceState::itemsRetrievalDone() +void ResourceState::applyCollectionChanges(const Akonadi::Collection &collection) { - m_resource->itemsRetrievalDone(); - emitPercent(100); + m_resource->modifyCollection(collection); } -void ResourceState::setTotalItems(int items) +void ResourceState::collectionAttributesRetrieved(const Akonadi::Collection &collection) { - m_resource->setTotalItems(items); + m_resource->collectionAttributesRetrieved(collection); } -void ResourceState::itemChangeCommitted( const Akonadi::Item &item ) +void ResourceState::itemRetrieved(const Akonadi::Item &item) { - m_resource->changeCommitted( item ); + m_resource->itemRetrieved(item); } -void ResourceState::itemsChangesCommitted(const Akonadi::Item::List& items) +void ResourceState::itemsRetrieved(const Akonadi::Item::List &items) { - m_resource->changesCommitted( items ); + m_resource->itemsRetrieved(items); } -void ResourceState::collectionsRetrieved( const Akonadi::Collection::List &collections ) +void ResourceState::itemsRetrievedIncremental(const Akonadi::Item::List &changed, const Akonadi::Item::List &removed) { - m_resource->collectionsRetrieved( collections ); + m_resource->itemsRetrievedIncremental(changed, removed); +} - if ( m_resource->settings()->retrieveMetadataOnFolderListing() ) { - QStringList oldMailBoxes = m_resource->settings()->knownMailBoxes(); - QStringList newMailBoxes; +void ResourceState::itemsRetrievalDone() +{ + m_resource->itemsRetrievalDone(); + emitPercent(100); +} - foreach ( const Akonadi::Collection &c, collections ) { - const QString mailBox = mailBoxForCollection( c ); +void ResourceState::setTotalItems(int items) +{ + m_resource->setTotalItems(items); +} - if ( !c.hasAttribute() - && !oldMailBoxes.contains( mailBox ) ) { - m_resource->synchronizeCollectionAttributes(c.id()); - } +void ResourceState::itemChangeCommitted(const Akonadi::Item &item) +{ + m_resource->changeCommitted(item); +} - newMailBoxes << mailBox; - } +void ResourceState::itemsChangesCommitted(const Akonadi::Item::List &items) +{ + m_resource->changesCommitted(items); +} - m_resource->settings()->setKnownMailBoxes( newMailBoxes ); - } +void ResourceState::collectionsRetrieved(const Akonadi::Collection::List &collections) +{ + m_resource->collectionsRetrieved(collections); + m_resource->startIdleIfNeeded(); +} - m_resource->startIdleIfNeeded(); +void ResourceState::collectionChangeCommitted(const Akonadi::Collection &collection) +{ + m_resource->changeCommitted(collection); } -void ResourceState::collectionChangeCommitted( const Akonadi::Collection &collection ) +void ResourceState::tagChangeCommitted(const Akonadi::Tag &tag) { - m_resource->changeCommitted( collection ); + m_resource->changeCommitted(tag); } void ResourceState::changeProcessed() { - m_resource->changeProcessed(); + m_resource->changeProcessed(); } -void ResourceState::searchFinished( const QVector &result, bool isRid ) +void ResourceState::searchFinished(const QVector &result, bool isRid) { - m_resource->searchFinished( result, isRid ? Akonadi::AgentSearchInterface::Rid : - Akonadi::AgentSearchInterface::Uid ); + m_resource->searchFinished(result, isRid ? Akonadi::AgentSearchInterface::Rid : + Akonadi::AgentSearchInterface::Uid); } - -void ResourceState::cancelTask( const QString &errorString ) +void ResourceState::cancelTask(const QString &errorString) { - m_resource->cancelTask( errorString ); - - // We get here in case of some error during the task. In such a case that can have - // been provoked by the fact that some of the metadata we had was wrong (most notably - // ACL and we took a wrong decision. - // So reset the timestamp of all the collections involved in the task, and also - // remove them from the "known mailboxes" list so that we get a chance to refresh - // the metadata about them ASAP. - - Akonadi::Collection::List collections; - collections << m_arguments.collection - << m_arguments.parentCollection - << m_arguments.sourceCollection - << m_arguments.targetCollection; - - foreach ( const Akonadi::Item &item, m_arguments.items ) { - if ( item.isValid() && item.parentCollection().isValid() ) { - collections << item.parentCollection(); - } - } - - if ( m_arguments.collection.isValid() && m_arguments.collection.parentCollection().isValid() ) { - collections << m_arguments.collection.parentCollection(); - } - - const QStringList oldMailBoxes = m_resource->settings()->knownMailBoxes(); - QStringList newMailBoxes = oldMailBoxes; - - foreach ( const Akonadi::Collection &collection, collections ) { - if ( collection.isValid() - && collection.hasAttribute() ) { - - Akonadi::Collection c = collection; - c.removeAttribute(); - - m_resource->modifyCollection( c ); - newMailBoxes.removeAll( mailBoxForCollection( c ) ); - } - } - - if ( oldMailBoxes.size()!=newMailBoxes.size() ) { - m_resource->settings()->setKnownMailBoxes( newMailBoxes ); - } + m_resource->cancelTask(errorString); } void ResourceState::deferTask() { - m_resource->deferTask(); + m_resource->deferTask(); } void ResourceState::restartItemRetrieval(Akonadi::Collection::Id col) { - //This ensures the collection fetch job is rerun (it isn't when using deferTask) - //The task will be appended - //TODO: deferTask should rerun the collectionfetchjob - m_resource->synchronizeCollection(col); - cancelTask("Restarting item retrieval."); + //This ensures the collection fetch job is rerun (it isn't when using deferTask) + //The task will be appended + //TODO: deferTask should rerun the collectionfetchjob + m_resource->synchronizeCollection(col); + cancelTask("Restarting item retrieval."); } void ResourceState::taskDone() { - m_resource->taskDone(); + m_resource->taskDone(); } -void ResourceState::emitError( const QString &message ) +void ResourceState::emitError(const QString &message) { - emit m_resource->error( message ); + Q_EMIT m_resource->error(message); } -void ResourceState::emitWarning( const QString &message ) +void ResourceState::emitWarning(const QString &message) { - emit m_resource->warning( message ); + Q_EMIT m_resource->warning(message); } -void ResourceState::emitPercent( int percent ) +void ResourceState::emitPercent(int percent) { - emit m_resource->percent( percent ); + Q_EMIT m_resource->percent(percent); } void ResourceState::synchronizeCollection(Akonadi::Entity::Id id) @@ -330,35 +320,45 @@ void ResourceState::synchronizeCollectionTree() { - m_resource->synchronizeCollectionTree(); + m_resource->synchronizeCollectionTree(); } void ResourceState::scheduleConnectionAttempt() { - m_resource->scheduleConnectionAttempt(); + m_resource->scheduleConnectionAttempt(); } QChar ResourceState::separatorCharacter() const { - return m_resource->separatorCharacter(); + return m_resource->separatorCharacter(); } -void ResourceState::setSeparatorCharacter( const QChar &separator ) +void ResourceState::setSeparatorCharacter(const QChar &separator) { - m_resource->setSeparatorCharacter( separator ); + m_resource->setSeparatorCharacter(separator); } -void ResourceState::showInformationDialog( const QString &message, const QString &title, const QString &dontShowAgainName ) +void ResourceState::showInformationDialog(const QString &message, const QString &title, const QString &dontShowAgainName) { - KMessageBox::information( 0, message, title, dontShowAgainName ); + KMessageBox::information(Q_NULLPTR, message, title, dontShowAgainName); } int ResourceState::batchSize() const { - return m_resource->itemSyncBatchSize(); + return m_resource->itemSyncBatchSize(); } MessageHelper::Ptr ResourceState::messageHelper() const { - return MessageHelper::Ptr(new MessageHelper()); + return MessageHelper::Ptr(new MessageHelper()); +} + +void ResourceState::tagsRetrieved(const Akonadi::Tag::List &tags, const QHash &tagMembers) +{ + m_resource->tagsRetrieved(tags, tagMembers); +} + +void ResourceState::relationsRetrieved(const Akonadi::Relation::List &relations) +{ + m_resource->relationsRetrieved(relations); } diff -Nru kdepim-runtime-4.14.6/resources/imap/resourcestate.h kdepim-runtime-15.08.0/resources/imap/resourcestate.h --- kdepim-runtime-4.14.6/resources/imap/resourcestate.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/resourcestate.h 2015-08-10 21:01:02.000000000 +0000 @@ -28,110 +28,134 @@ class ImapResourceBase; struct TaskArguments { - TaskArguments(){} + TaskArguments() {} TaskArguments(const Akonadi::Item &_item): items(Akonadi::Item::List() << _item) {} TaskArguments(const Akonadi::Item &_item, const Akonadi::Collection &_collection): collection(_collection), items(Akonadi::Item::List() << _item) {} TaskArguments(const Akonadi::Item &_item, const QSet &_parts): items(Akonadi::Item::List() << _item), parts(_parts) {} TaskArguments(const Akonadi::Item::List &_items): items(_items) {} TaskArguments(const Akonadi::Item::List &_items, const QSet &_addedFlags, const QSet &_removedFlags): items(_items), addedFlags(_addedFlags), removedFlags(_removedFlags) {} - TaskArguments(const Akonadi::Item::List &_items, const Akonadi::Collection &_sourceCollection, const Akonadi::Collection &_targetCollection): items(_items), sourceCollection(_sourceCollection), targetCollection(_targetCollection){} - TaskArguments(const Akonadi::Collection &_collection): collection(_collection){} - TaskArguments(const Akonadi::Collection &_collection, const Akonadi::Collection &_parentCollection): collection(_collection), parentCollection(_parentCollection){} - TaskArguments(const Akonadi::Collection &_collection, const Akonadi::Collection &_sourceCollection, const Akonadi::Collection &_targetCollection): collection(_collection), sourceCollection(_sourceCollection), targetCollection(_targetCollection){} - TaskArguments(const Akonadi::Collection &_collection, const QSet &_parts): collection(_collection), parts(_parts){} + TaskArguments(const Akonadi::Item::List &_items, const Akonadi::Collection &_sourceCollection, const Akonadi::Collection &_targetCollection): items(_items), sourceCollection(_sourceCollection), targetCollection(_targetCollection) {} + TaskArguments(const Akonadi::Item::List &_items, const QSet &_addedTags, const QSet &_removedTags): items(_items), addedTags(_addedTags), removedTags(_removedTags) {} + TaskArguments(const Akonadi::Item::List &_items, const Akonadi::Relation::List &_addedRelations, const Akonadi::Relation::List &_removedRelations): items(_items), addedRelations(_addedRelations), removedRelations(_removedRelations) {} + TaskArguments(const Akonadi::Collection &_collection): collection(_collection) {} + TaskArguments(const Akonadi::Collection &_collection, const Akonadi::Collection &_parentCollection): collection(_collection), parentCollection(_parentCollection) {} + TaskArguments(const Akonadi::Collection &_collection, const Akonadi::Collection &_sourceCollection, const Akonadi::Collection &_targetCollection): collection(_collection), sourceCollection(_sourceCollection), targetCollection(_targetCollection) {} + TaskArguments(const Akonadi::Collection &_collection, const QSet &_parts): collection(_collection), parts(_parts) {} + TaskArguments(const Akonadi::Tag &_tag) : tag(_tag) {} Akonadi::Collection collection; Akonadi::Item::List items; Akonadi::Collection parentCollection; //only used as parent of a collection Akonadi::Collection sourceCollection; Akonadi::Collection targetCollection; + Akonadi::Tag tag; QSet parts; QSet addedFlags; QSet removedFlags; + QSet addedTags; + QSet removedTags; + Akonadi::Relation::List addedRelations; + Akonadi::Relation::List removedRelations; }; class ResourceState : public ResourceStateInterface { public: - explicit ResourceState( ImapResourceBase *resource, const TaskArguments &arguments ); + explicit ResourceState(ImapResourceBase *resource, const TaskArguments &arguments); public: - ~ResourceState(); + ~ResourceState(); - virtual QString userName() const; - virtual QString resourceName() const; - virtual QStringList serverCapabilities() const; - virtual QList serverNamespaces() const; + QString userName() const Q_DECL_OVERRIDE; + QString resourceName() const Q_DECL_OVERRIDE; + QString resourceIdentifier() const Q_DECL_OVERRIDE; + QStringList serverCapabilities() const Q_DECL_OVERRIDE; + QList serverNamespaces() const Q_DECL_OVERRIDE; + QList personalNamespaces() const Q_DECL_OVERRIDE; + QList userNamespaces() const Q_DECL_OVERRIDE; + QList sharedNamespaces() const Q_DECL_OVERRIDE; - virtual bool isAutomaticExpungeEnabled() const; - virtual bool isSubscriptionEnabled() const; - virtual bool isDisconnectedModeEnabled() const; - virtual int intervalCheckTime() const; + bool isAutomaticExpungeEnabled() const Q_DECL_OVERRIDE; + bool isSubscriptionEnabled() const Q_DECL_OVERRIDE; + bool isDisconnectedModeEnabled() const Q_DECL_OVERRIDE; + int intervalCheckTime() const Q_DECL_OVERRIDE; - virtual Akonadi::Collection collection() const; - virtual Akonadi::Item item() const; - virtual Akonadi::Item::List items() const; + Akonadi::Collection collection() const Q_DECL_OVERRIDE; + Akonadi::Item item() const Q_DECL_OVERRIDE; + Akonadi::Item::List items() const Q_DECL_OVERRIDE; - virtual Akonadi::Collection parentCollection() const; + Akonadi::Collection parentCollection() const Q_DECL_OVERRIDE; - virtual Akonadi::Collection sourceCollection() const; - virtual Akonadi::Collection targetCollection() const; + Akonadi::Collection sourceCollection() const Q_DECL_OVERRIDE; + Akonadi::Collection targetCollection() const Q_DECL_OVERRIDE; - virtual QSet parts() const; - virtual QSet addedFlags() const; - virtual QSet removedFlags() const; + QSet parts() const Q_DECL_OVERRIDE; + QSet addedFlags() const Q_DECL_OVERRIDE; + QSet removedFlags() const Q_DECL_OVERRIDE; - virtual QString rootRemoteId() const; + Akonadi::Tag tag() const Q_DECL_OVERRIDE; + QSet addedTags() const Q_DECL_OVERRIDE; + QSet removedTags() const Q_DECL_OVERRIDE; - virtual void setIdleCollection( const Akonadi::Collection &collection ); - virtual void applyCollectionChanges( const Akonadi::Collection &collection ); + Akonadi::Relation::List addedRelations() const Q_DECL_OVERRIDE; + Akonadi::Relation::List removedRelations() const Q_DECL_OVERRIDE; - virtual void collectionAttributesRetrieved( const Akonadi::Collection &collection ); + QString rootRemoteId() const Q_DECL_OVERRIDE; - virtual void itemRetrieved( const Akonadi::Item &item ); + void setIdleCollection(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void applyCollectionChanges(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; - virtual void itemsRetrieved( const Akonadi::Item::List &items ); - virtual void itemsRetrievedIncremental( const Akonadi::Item::List &changed, const Akonadi::Item::List &removed ); - virtual void itemsRetrievalDone(); + void collectionAttributesRetrieved(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; - virtual void setTotalItems(int); + void itemRetrieved(const Akonadi::Item &item) Q_DECL_OVERRIDE; - virtual void itemChangeCommitted( const Akonadi::Item &item ); - virtual void itemsChangesCommitted(const Akonadi::Item::List& items); + void itemsRetrieved(const Akonadi::Item::List &items) Q_DECL_OVERRIDE; + void itemsRetrievedIncremental(const Akonadi::Item::List &changed, const Akonadi::Item::List &removed) Q_DECL_OVERRIDE; + void itemsRetrievalDone() Q_DECL_OVERRIDE; - virtual void collectionsRetrieved( const Akonadi::Collection::List &collections ); + void setTotalItems(int) Q_DECL_OVERRIDE; - virtual void collectionChangeCommitted( const Akonadi::Collection &collection ); + void itemChangeCommitted(const Akonadi::Item &item) Q_DECL_OVERRIDE; + void itemsChangesCommitted(const Akonadi::Item::List &items) Q_DECL_OVERRIDE; - virtual void changeProcessed(); + void collectionsRetrieved(const Akonadi::Collection::List &collections) Q_DECL_OVERRIDE; - virtual void searchFinished( const QVector &result, bool isRid = true ); + void tagsRetrieved(const Akonadi::Tag::List &tags, const QHash &) Q_DECL_OVERRIDE; + void relationsRetrieved(const Akonadi::Relation::List &tags) Q_DECL_OVERRIDE; - virtual void cancelTask( const QString &errorString ); - virtual void deferTask(); - virtual void restartItemRetrieval(Akonadi::Collection::Id col); - virtual void taskDone(); + void collectionChangeCommitted(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; - virtual void emitError( const QString &message ); - virtual void emitWarning( const QString &message ); + void tagChangeCommitted(const Akonadi::Tag &tag) Q_DECL_OVERRIDE; - virtual void emitPercent( int percent ); + void changeProcessed() Q_DECL_OVERRIDE; - virtual void synchronizeCollection(Akonadi::Collection::Id); - virtual void synchronizeCollectionTree(); - virtual void scheduleConnectionAttempt(); + void searchFinished(const QVector &result, bool isRid = true) Q_DECL_OVERRIDE; - virtual QChar separatorCharacter() const; - virtual void setSeparatorCharacter( const QChar &separator ); + void cancelTask(const QString &errorString) Q_DECL_OVERRIDE; + void deferTask() Q_DECL_OVERRIDE; + void restartItemRetrieval(Akonadi::Collection::Id col) Q_DECL_OVERRIDE; + void taskDone() Q_DECL_OVERRIDE; - virtual void showInformationDialog( const QString &message, const QString &title, const QString &dontShowAgainName ); + void emitError(const QString &message) Q_DECL_OVERRIDE; + void emitWarning(const QString &message) Q_DECL_OVERRIDE; - virtual int batchSize() const; + void emitPercent(int percent) Q_DECL_OVERRIDE; - virtual MessageHelper::Ptr messageHelper() const; + virtual void synchronizeCollection(Akonadi::Collection::Id); + void synchronizeCollectionTree() Q_DECL_OVERRIDE; + void scheduleConnectionAttempt() Q_DECL_OVERRIDE; + + QChar separatorCharacter() const Q_DECL_OVERRIDE; + void setSeparatorCharacter(const QChar &separator) Q_DECL_OVERRIDE; + + void showInformationDialog(const QString &message, const QString &title, const QString &dontShowAgainName) Q_DECL_OVERRIDE; + + int batchSize() const Q_DECL_OVERRIDE; + + MessageHelper::Ptr messageHelper() const Q_DECL_OVERRIDE; private: - ImapResourceBase *m_resource; - const TaskArguments m_arguments; + ImapResourceBase *m_resource; + const TaskArguments m_arguments; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/resourcestateinterface.cpp kdepim-runtime-15.08.0/resources/imap/resourcestateinterface.cpp --- kdepim-runtime-4.14.6/resources/imap/resourcestateinterface.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/resourcestateinterface.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,32 +20,36 @@ */ #include "resourcestateinterface.h" +#include "imapresource_debug.h" ResourceStateInterface::~ResourceStateInterface() { } -QString ResourceStateInterface::mailBoxForCollection( const Akonadi::Collection &collection, bool showWarnings ) +QString ResourceStateInterface::mailBoxForCollection(const Akonadi::Collection &collection, bool showWarnings) { - if ( collection.remoteId().isEmpty() ) { //This should never happen, investigate why a collection without remoteId made it this far - if ( showWarnings ) - kWarning() << "Got incomplete ancestor chain due to empty remoteId:" << collection; - return QString(); - } - - if ( collection.parentCollection() == Akonadi::Collection::root() ) { - /*if ( showWarnings ) - kWarning( collection.remoteId() != rootRemoteId() ) << "RID mismatch, is " << collection.remoteId() << " expected " << rootRemoteId(); - */ - return QLatin1String( "" ); // see below, this intentionally not just QString()! - } - const QString parentMailbox = mailBoxForCollection( collection.parentCollection() ); - if ( parentMailbox.isNull() ) // invalid, != isEmpty() here! - return QString(); - - const QString mailbox = parentMailbox + collection.remoteId(); - if ( parentMailbox.isEmpty() ) - return mailbox.mid( 1 ); // strip of the separator on top-level mailboxes - return mailbox; + if (collection.remoteId().isEmpty()) { //This should never happen, investigate why a collection without remoteId made it this far + if (showWarnings) { + qCWarning(IMAPRESOURCE_LOG) << "Got incomplete ancestor chain due to empty remoteId:" << collection; + } + return QString(); + } + + if (collection.parentCollection() == Akonadi::Collection::root()) { + /*if ( showWarnings && collection.remoteId() != rootRemoteId()) + qCWarning(IMAPRESOURCE_LOG) << "RID mismatch, is " << collection.remoteId() << " expected " << rootRemoteId(); + */ + return QStringLiteral(""); // see below, this intentionally not just QString()! + } + const QString parentMailbox = mailBoxForCollection(collection.parentCollection()); + if (parentMailbox.isNull()) { // invalid, != isEmpty() here! + return QString(); + } + + const QString mailbox = parentMailbox + collection.remoteId(); + if (parentMailbox.isEmpty()) { + return mailbox.mid(1); // strip of the separator on top-level mailboxes + } + return mailbox; } diff -Nru kdepim-runtime-4.14.6/resources/imap/resourcestateinterface.h kdepim-runtime-15.08.0/resources/imap/resourcestateinterface.h --- kdepim-runtime-4.14.6/resources/imap/resourcestateinterface.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/resourcestateinterface.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,8 +24,8 @@ #include -#include -#include +#include +#include #include @@ -35,81 +35,96 @@ class ResourceStateInterface { public: - typedef boost::shared_ptr Ptr; + typedef boost::shared_ptr Ptr; - virtual ~ResourceStateInterface(); + virtual ~ResourceStateInterface(); - virtual QString userName() const = 0; - virtual QString resourceName() const = 0; - virtual QStringList serverCapabilities() const = 0; - virtual QList serverNamespaces() const = 0; + virtual QString userName() const = 0; + virtual QString resourceName() const = 0; + virtual QString resourceIdentifier() const = 0; + virtual QStringList serverCapabilities() const = 0; + virtual QList serverNamespaces() const = 0; + virtual QList personalNamespaces() const = 0; + virtual QList userNamespaces() const = 0; + virtual QList sharedNamespaces() const = 0; - virtual bool isAutomaticExpungeEnabled() const = 0; - virtual bool isSubscriptionEnabled() const = 0; - virtual bool isDisconnectedModeEnabled() const = 0; - virtual int intervalCheckTime() const = 0; + virtual bool isAutomaticExpungeEnabled() const = 0; + virtual bool isSubscriptionEnabled() const = 0; + virtual bool isDisconnectedModeEnabled() const = 0; + virtual int intervalCheckTime() const = 0; - virtual Akonadi::Collection collection() const = 0; - virtual Akonadi::Item item() const = 0; - virtual Akonadi::Item::List items() const = 0; + virtual Akonadi::Collection collection() const = 0; + virtual Akonadi::Item item() const = 0; + virtual Akonadi::Item::List items() const = 0; - virtual Akonadi::Collection parentCollection() const = 0; + virtual Akonadi::Collection parentCollection() const = 0; - virtual Akonadi::Collection sourceCollection() const = 0; - virtual Akonadi::Collection targetCollection() const = 0; + virtual Akonadi::Collection sourceCollection() const = 0; + virtual Akonadi::Collection targetCollection() const = 0; - virtual QSet parts() const = 0; - virtual QSet addedFlags() const = 0; - virtual QSet removedFlags() const = 0; + virtual QSet parts() const = 0; + virtual QSet addedFlags() const = 0; + virtual QSet removedFlags() const = 0; - virtual QString rootRemoteId() const = 0; - static QString mailBoxForCollection( const Akonadi::Collection &collection, bool showWarnings = true ); + virtual Akonadi::Tag tag() const = 0; + virtual QSet addedTags() const = 0; + virtual QSet removedTags() const = 0; - virtual void setIdleCollection( const Akonadi::Collection &collection ) = 0; - virtual void applyCollectionChanges( const Akonadi::Collection &collection ) = 0; + virtual QString rootRemoteId() const = 0; + static QString mailBoxForCollection(const Akonadi::Collection &collection, bool showWarnings = true); - virtual void itemRetrieved( const Akonadi::Item &item ) = 0; + virtual void setIdleCollection(const Akonadi::Collection &collection) = 0; + virtual void applyCollectionChanges(const Akonadi::Collection &collection) = 0; - virtual void itemsRetrieved( const Akonadi::Item::List &items ) = 0; - virtual void itemsRetrievedIncremental( const Akonadi::Item::List &changed, - const Akonadi::Item::List &removed ) = 0; - virtual void itemsRetrievalDone() = 0; + virtual void itemRetrieved(const Akonadi::Item &item) = 0; - virtual void setTotalItems(int) = 0; + virtual void itemsRetrieved(const Akonadi::Item::List &items) = 0; + virtual void itemsRetrievedIncremental(const Akonadi::Item::List &changed, + const Akonadi::Item::List &removed) = 0; + virtual void itemsRetrievalDone() = 0; - virtual void itemChangeCommitted( const Akonadi::Item &item ) = 0; - virtual void itemsChangesCommitted( const Akonadi::Item::List &items ) = 0; + virtual void setTotalItems(int) = 0; - virtual void collectionsRetrieved( const Akonadi::Collection::List &collections ) = 0; - virtual void collectionAttributesRetrieved( const Akonadi::Collection &collection ) = 0; + virtual void itemChangeCommitted(const Akonadi::Item &item) = 0; + virtual void itemsChangesCommitted(const Akonadi::Item::List &items) = 0; - virtual void collectionChangeCommitted( const Akonadi::Collection &collection ) = 0; + virtual void collectionsRetrieved(const Akonadi::Collection::List &collections) = 0; + virtual void collectionAttributesRetrieved(const Akonadi::Collection &collection) = 0; - virtual void changeProcessed() = 0; + virtual void collectionChangeCommitted(const Akonadi::Collection &collection) = 0; - virtual void searchFinished( const QVector &result, bool isRid = true ) = 0; + virtual void tagChangeCommitted(const Akonadi::Tag &tag) = 0; - virtual void cancelTask( const QString &errorString ) = 0; - virtual void deferTask() = 0; - virtual void restartItemRetrieval(Akonadi::Collection::Id col) = 0; - virtual void taskDone() = 0; + virtual void changeProcessed() = 0; - virtual void emitError( const QString &message ) = 0; - virtual void emitWarning( const QString &message ) = 0; - virtual void emitPercent( int percent ) = 0; + virtual void searchFinished(const QVector &result, bool isRid = true) = 0; - virtual void synchronizeCollectionTree() = 0; - virtual void scheduleConnectionAttempt() = 0; + virtual void cancelTask(const QString &errorString) = 0; + virtual void deferTask() = 0; + virtual void restartItemRetrieval(Akonadi::Collection::Id col) = 0; + virtual void taskDone() = 0; - virtual QChar separatorCharacter() const = 0; - virtual void setSeparatorCharacter( const QChar &separator ) = 0; + virtual void emitError(const QString &message) = 0; + virtual void emitWarning(const QString &message) = 0; + virtual void emitPercent(int percent) = 0; - virtual void showInformationDialog( const QString &message, const QString &title, const QString &dontShowAgainName ) = 0; + virtual void synchronizeCollectionTree() = 0; + virtual void scheduleConnectionAttempt() = 0; - virtual int batchSize() const = 0; + virtual QChar separatorCharacter() const = 0; + virtual void setSeparatorCharacter(const QChar &separator) = 0; - virtual MessageHelper::Ptr messageHelper() const = 0; + virtual void showInformationDialog(const QString &message, const QString &title, const QString &dontShowAgainName) = 0; + virtual int batchSize() const = 0; + + virtual MessageHelper::Ptr messageHelper() const = 0; + + virtual void tagsRetrieved(const Akonadi::Tag::List &tags, const QHash &) = 0; + virtual void relationsRetrieved(const Akonadi::Relation::List &tags) = 0; + + virtual Akonadi::Relation::List addedRelations() const = 0; + virtual Akonadi::Relation::List removedRelations() const = 0; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/resourcetask.cpp kdepim-runtime-15.08.0/resources/imap/resourcetask.cpp --- kdepim-runtime-4.14.6/resources/imap/resourcetask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/resourcetask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,511 +21,550 @@ #include "resourcetask.h" -#include +#include -#include +#include +#include "imapresource_debug.h" #include "collectionflagsattribute.h" +#include #include "imapflags.h" #include "sessionpool.h" #include "resourcestateinterface.h" +#include "tracer.h" -ResourceTask::ResourceTask( ActionIfNoSession action, ResourceStateInterface::Ptr resource, QObject *parent ) - : QObject( parent ), - m_pool( 0 ), - m_sessionRequestId( 0 ), - m_session( 0 ), - m_actionIfNoSession( action ), - m_resource( resource ), - mCancelled( false ) +ResourceTask::ResourceTask(ActionIfNoSession action, ResourceStateInterface::Ptr resource, QObject *parent) + : QObject(parent), + m_pool(Q_NULLPTR), + m_sessionRequestId(0), + m_session(Q_NULLPTR), + m_actionIfNoSession(action), + m_resource(resource), + mCancelled(false) { } ResourceTask::~ResourceTask() { - if ( m_pool ) { - if ( m_sessionRequestId ) - m_pool->cancelSessionRequest( m_sessionRequestId ); - if ( m_session ) - m_pool->releaseSession( m_session ); - } + if (m_pool) { + if (m_sessionRequestId) { + m_pool->cancelSessionRequest(m_sessionRequestId); + } + if (m_session) { + m_pool->releaseSession(m_session); + } + } } -void ResourceTask::start( SessionPool *pool ) +void ResourceTask::start(SessionPool *pool) { - m_pool = pool; - connect( m_pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString)), - this, SLOT(onSessionRequested(qint64,KIMAP::Session*,int,QString)) ); - - m_sessionRequestId = m_pool->requestSession(); - - if ( m_sessionRequestId <= 0 ) { - m_sessionRequestId = 0; - - switch ( m_actionIfNoSession ) { - case CancelIfNoSession: - kDebug() << "Cancelling this request. Probably there is no connection."; - m_resource->cancelTask( i18n( "There is currently no connection to the IMAP server." ) ); - break; - - case DeferIfNoSession: - kDebug() << "Defering this request. Probably there is no connection."; - m_resource->deferTask(); - break; + Trace() << metaObject()->className(); + m_pool = pool; + connect(m_pool, &SessionPool::sessionRequestDone, + this, &ResourceTask::onSessionRequested); + + m_sessionRequestId = m_pool->requestSession(); + + if (m_sessionRequestId <= 0) { + m_sessionRequestId = 0; + + switch (m_actionIfNoSession) { + case CancelIfNoSession: + qCDebug(IMAPRESOURCE_LOG) << "Cancelling this request. Probably there is no connection."; + m_resource->cancelTask(i18n("There is currently no connection to the IMAP server.")); + break; + + case DeferIfNoSession: + qCDebug(IMAPRESOURCE_LOG) << "Defering this request. Probably there is no connection."; + m_resource->deferTask(); + break; + } + + // In this case we were likely disconnect, try to get the resource online + m_resource->scheduleConnectionAttempt(); + deleteLater(); } - - // In this case we were likely disconnect, try to get the resource online - m_resource->scheduleConnectionAttempt(); - deleteLater(); - } } -void ResourceTask::onSessionRequested( qint64 requestId, KIMAP::Session *session, - int errorCode, const QString &/*errorString*/ ) +void ResourceTask::onSessionRequested(qint64 requestId, KIMAP::Session *session, + int errorCode, const QString &/*errorString*/) { - if ( requestId!=m_sessionRequestId ) { - // Not for us, ignore - return; - } + if (requestId != m_sessionRequestId) { + // Not for us, ignore + return; + } - disconnect( m_pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString)), - this, SLOT(onSessionRequested(qint64,KIMAP::Session*,int,QString)) ); - m_sessionRequestId = 0; + disconnect(m_pool, &SessionPool::sessionRequestDone, + this, &ResourceTask::onSessionRequested); + m_sessionRequestId = 0; - if ( errorCode!=SessionPool::NoError ) { - switch ( m_actionIfNoSession ) { - case CancelIfNoSession: - kDebug() << "Cancelling this request. Probably there is no more session available."; - m_resource->cancelTask( i18n( "There is currently no session to the IMAP server available." ) ); - break; + if (errorCode != SessionPool::NoError) { + switch (m_actionIfNoSession) { + case CancelIfNoSession: + qCDebug(IMAPRESOURCE_LOG) << "Cancelling this request. Probably there is no more session available."; + m_resource->cancelTask(i18n("There is currently no session to the IMAP server available.")); + break; + + case DeferIfNoSession: + qCDebug(IMAPRESOURCE_LOG) << "Defering this request. Probably there is no more session available."; + m_resource->deferTask(); + break; + } - case DeferIfNoSession: - kDebug() << "Defering this request. Probably there is no more session available."; - m_resource->deferTask(); - break; + deleteLater(); + return; } - deleteLater(); - return; - } + m_session = session; - m_session = session; + if (errorCode != SessionPool::NoError) { + Trace() << "Error on: " << metaObject()->className(); + switch (m_actionIfNoSession) { + case CancelIfNoSession: + qCDebug(IMAPRESOURCE_LOG) << "Cancelling this request. Probably there is no more session available."; + m_resource->cancelTask(i18n("There is currently no session to the IMAP server available.")); + break; + + case DeferIfNoSession: + qCDebug(IMAPRESOURCE_LOG) << "Defering this request. Probably there is no more session available."; + m_resource->deferTask(); + break; + } - connect( m_pool, SIGNAL(connectionLost(KIMAP::Session*)), - this, SLOT(onConnectionLost(KIMAP::Session*)) ); - connect( m_pool, SIGNAL(disconnectDone()), - this, SLOT(onPoolDisconnect()) ); + deleteLater(); + return; + } - doStart( m_session ); -} + m_session = session; -void ResourceTask::onConnectionLost( KIMAP::Session *session ) -{ - if ( session == m_session ) { - // Our session becomes invalid, so get rid of - // the pointer, we don't need to release it once the - // task is done - m_session = 0; - cancelTask( i18n( "Connection lost" ) ); - } + connect(m_pool, &SessionPool::connectionLost, + this, &ResourceTask::onConnectionLost); + connect(m_pool, &SessionPool::disconnectDone, + this, &ResourceTask::onPoolDisconnect); + + Trace() << "starting: " << metaObject()->className(); + doStart(m_session); +} + +void ResourceTask::onConnectionLost(KIMAP::Session *session) +{ + if (session == m_session) { + // Our session becomes invalid, so get rid of + // the pointer, we don't need to release it once the + // task is done + m_session = Q_NULLPTR; + Trace() << metaObject()->className(); + cancelTask(i18n("Connection lost")); + } } void ResourceTask::onPoolDisconnect() { - // All the sessions in the pool we used changed, - // so get rid of the pointer, we don't need to - // release our session anymore - m_pool = 0; + // All the sessions in the pool we used changed, + // so get rid of the pointer, we don't need to + // release our session anymore + m_pool = Q_NULLPTR; - cancelTask( i18n( "Connection lost" ) ); + Trace() << metaObject()->className(); + cancelTask(i18n("Connection lost")); } QString ResourceTask::userName() const { - return m_resource->userName(); + return m_resource->userName(); } QString ResourceTask::resourceName() const { - return m_resource->resourceName(); + return m_resource->resourceName(); } QStringList ResourceTask::serverCapabilities() const { - return m_resource->serverCapabilities(); + return m_resource->serverCapabilities(); } QList ResourceTask::serverNamespaces() const { - return m_resource->serverNamespaces(); + return m_resource->serverNamespaces(); } bool ResourceTask::isAutomaticExpungeEnabled() const { - return m_resource->isAutomaticExpungeEnabled(); + return m_resource->isAutomaticExpungeEnabled(); } bool ResourceTask::isSubscriptionEnabled() const { - return m_resource->isSubscriptionEnabled(); + return m_resource->isSubscriptionEnabled(); } bool ResourceTask::isDisconnectedModeEnabled() const { - return m_resource->isDisconnectedModeEnabled(); + return m_resource->isDisconnectedModeEnabled(); } int ResourceTask::intervalCheckTime() const { - return m_resource->intervalCheckTime(); + return m_resource->intervalCheckTime(); } static Akonadi::Collection detatchCollection(const Akonadi::Collection &collection) { - //HACK: Attributes are accessed via a const function, and the implicitly shared private pointer thus doesn't detach. - //We force a detach to avoid surprises. (RetrieveItemsTask used to write back the collection changes, even though the task was canceled) - //Once this is fixed this function can go away. - Akonadi::Collection col = collection; - col.setId(col.id()); - return col; + //HACK: Attributes are accessed via a const function, and the implicitly shared private pointer thus doesn't detach. + //We force a detach to avoid surprises. (RetrieveItemsTask used to write back the collection changes, even though the task was canceled) + //Once this is fixed this function can go away. + Akonadi::Collection col = collection; + col.setId(col.id()); + return col; } Akonadi::Collection ResourceTask::collection() const { - return detatchCollection(m_resource->collection()); + return detatchCollection(m_resource->collection()); } Akonadi::Item ResourceTask::item() const { - return m_resource->item(); + return m_resource->item(); } Akonadi::Item::List ResourceTask::items() const { - return m_resource->items(); + return m_resource->items(); } Akonadi::Collection ResourceTask::parentCollection() const { - return detatchCollection(m_resource->parentCollection()); + return detatchCollection(m_resource->parentCollection()); } Akonadi::Collection ResourceTask::sourceCollection() const { - return detatchCollection(m_resource->sourceCollection()); + return detatchCollection(m_resource->sourceCollection()); } Akonadi::Collection ResourceTask::targetCollection() const { - return detatchCollection(m_resource->targetCollection()); + return detatchCollection(m_resource->targetCollection()); } QSet ResourceTask::parts() const { - return m_resource->parts(); + return m_resource->parts(); } QSet< QByteArray > ResourceTask::addedFlags() const { - return m_resource->addedFlags(); + return m_resource->addedFlags(); } QSet< QByteArray > ResourceTask::removedFlags() const { - return m_resource->removedFlags(); + return m_resource->removedFlags(); } QString ResourceTask::rootRemoteId() const { - return m_resource->rootRemoteId(); + return m_resource->rootRemoteId(); } -QString ResourceTask::mailBoxForCollection( const Akonadi::Collection &collection ) const +QString ResourceTask::mailBoxForCollection(const Akonadi::Collection &collection) const { - return m_resource->mailBoxForCollection( collection ); + return m_resource->mailBoxForCollection(collection); } -void ResourceTask::setIdleCollection( const Akonadi::Collection &collection ) +void ResourceTask::setIdleCollection(const Akonadi::Collection &collection) { - if (!mCancelled) { - m_resource->setIdleCollection( collection ); - } + if (!mCancelled) { + m_resource->setIdleCollection(collection); + } } -void ResourceTask::applyCollectionChanges( const Akonadi::Collection &collection ) +void ResourceTask::applyCollectionChanges(const Akonadi::Collection &collection) { - if (!mCancelled) { - m_resource->applyCollectionChanges( collection ); - } + if (!mCancelled) { + m_resource->applyCollectionChanges(collection); + } } -void ResourceTask::itemRetrieved( const Akonadi::Item &item ) +void ResourceTask::itemRetrieved(const Akonadi::Item &item) { - if (!mCancelled) { - m_resource->itemRetrieved( item ); - emitPercent(100); - } - deleteLater(); + if (!mCancelled) { + m_resource->itemRetrieved(item); + emitPercent(100); + } + deleteLater(); } -void ResourceTask::itemsRetrieved( const Akonadi::Item::List &items ) +void ResourceTask::itemsRetrieved(const Akonadi::Item::List &items) { - if (!mCancelled) { - m_resource->itemsRetrieved( items ); - } + if (!mCancelled) { + m_resource->itemsRetrieved(items); + } } -void ResourceTask::itemsRetrievedIncremental( const Akonadi::Item::List &changed, - const Akonadi::Item::List &removed ) +void ResourceTask::itemsRetrievedIncremental(const Akonadi::Item::List &changed, + const Akonadi::Item::List &removed) { - if (!mCancelled) { - m_resource->itemsRetrievedIncremental( changed, removed ); - } + if (!mCancelled) { + m_resource->itemsRetrievedIncremental(changed, removed); + } } void ResourceTask::itemsRetrievalDone() { - if (!mCancelled) { - m_resource->itemsRetrievalDone(); - } - deleteLater(); + if (!mCancelled) { + m_resource->itemsRetrievalDone(); + } + deleteLater(); } void ResourceTask::setTotalItems(int totalItems) { - if (!mCancelled) { - m_resource->setTotalItems(totalItems); - } + if (!mCancelled) { + m_resource->setTotalItems(totalItems); + } } -void ResourceTask::changeCommitted( const Akonadi::Item &item ) +void ResourceTask::changeCommitted(const Akonadi::Item &item) { - if (!mCancelled) { - m_resource->itemChangeCommitted( item ); - } - deleteLater(); + if (!mCancelled) { + m_resource->itemChangeCommitted(item); + } + deleteLater(); } -void ResourceTask::changesCommitted(const Akonadi::Item::List& items) +void ResourceTask::changesCommitted(const Akonadi::Item::List &items) { - if (!mCancelled) { - m_resource->itemsChangesCommitted( items ); - } - deleteLater(); + if (!mCancelled) { + m_resource->itemsChangesCommitted(items); + } + deleteLater(); } -void ResourceTask::searchFinished( const QVector &result, bool isRid ) +void ResourceTask::searchFinished(const QVector &result, bool isRid) { - if (!mCancelled) { - m_resource->searchFinished( result, isRid ); - } - deleteLater(); + if (!mCancelled) { + m_resource->searchFinished(result, isRid); + } + deleteLater(); } -void ResourceTask::collectionsRetrieved( const Akonadi::Collection::List &collections ) +void ResourceTask::collectionsRetrieved(const Akonadi::Collection::List &collections) { - if (!mCancelled) { - m_resource->collectionsRetrieved( collections ); - } - deleteLater(); + if (!mCancelled) { + m_resource->collectionsRetrieved(collections); + } + deleteLater(); +} + +void ResourceTask::collectionAttributesRetrieved(const Akonadi::Collection &col) +{ + if (!mCancelled) { + m_resource->collectionAttributesRetrieved(col); + } + deleteLater(); } -void ResourceTask::collectionAttributesRetrieved(const Akonadi::Collection& col) +void ResourceTask::changeCommitted(const Akonadi::Collection &collection) { - if (!mCancelled) { - m_resource->collectionAttributesRetrieved( col ); - } - deleteLater(); + if (!mCancelled) { + m_resource->collectionChangeCommitted(collection); + } + deleteLater(); } -void ResourceTask::changeCommitted( const Akonadi::Collection &collection ) +void ResourceTask::changeCommitted(const Akonadi::Tag &tag) { - if (!mCancelled) { - m_resource->collectionChangeCommitted( collection ); - } - deleteLater(); + if (!mCancelled) { + m_resource->tagChangeCommitted(tag); + } + deleteLater(); } void ResourceTask::changeProcessed() { - if (!mCancelled) { - m_resource->changeProcessed(); - } - deleteLater(); + if (!mCancelled) { + m_resource->changeProcessed(); + } + deleteLater(); } -void ResourceTask::cancelTask( const QString &errorString ) -{ - if (!mCancelled) { - mCancelled = true; - m_resource->cancelTask( errorString ); - } - deleteLater(); +void ResourceTask::cancelTask(const QString &errorString) +{ + qCDebug(IMAPRESOURCE_LOG) << "Cancel task: " << errorString; + if (!mCancelled) { + mCancelled = true; + m_resource->cancelTask(errorString); + } + deleteLater(); } void ResourceTask::deferTask() { - if (!mCancelled) { - mCancelled = true; - m_resource->deferTask(); - } - deleteLater(); + if (!mCancelled) { + mCancelled = true; + m_resource->deferTask(); + } + deleteLater(); } void ResourceTask::restartItemRetrieval(Akonadi::Entity::Id col) { - if (!mCancelled) { - m_resource->restartItemRetrieval(col); - } - deleteLater(); + if (!mCancelled) { + m_resource->restartItemRetrieval(col); + } + deleteLater(); } void ResourceTask::taskDone() { - m_resource->taskDone(); - deleteLater(); + m_resource->taskDone(); + deleteLater(); } -void ResourceTask::emitPercent( int percent ) +void ResourceTask::emitPercent(int percent) { - m_resource->emitPercent( percent ); + m_resource->emitPercent(percent); } -void ResourceTask::emitError( const QString &message ) +void ResourceTask::emitError(const QString &message) { - m_resource->emitError( message ); + m_resource->emitError(message); } -void ResourceTask::emitWarning( const QString &message ) +void ResourceTask::emitWarning(const QString &message) { - m_resource->emitWarning( message ); + m_resource->emitWarning(message); } void ResourceTask::synchronizeCollectionTree() { - m_resource->synchronizeCollectionTree(); + m_resource->synchronizeCollectionTree(); } -void ResourceTask::showInformationDialog( const QString &message, const QString &title, const QString &dontShowAgainName ) +void ResourceTask::showInformationDialog(const QString &message, const QString &title, const QString &dontShowAgainName) { - m_resource->showInformationDialog( message, title, dontShowAgainName ); + m_resource->showInformationDialog(message, title, dontShowAgainName); } -QList ResourceTask::fromAkonadiToSupportedImapFlags( const QList &flags, - const Akonadi::Collection &collection ) +QList ResourceTask::fromAkonadiToSupportedImapFlags(const QList &flags, + const Akonadi::Collection &collection) { - QList imapFlags = fromAkonadiFlags( flags ); + QList imapFlags = fromAkonadiFlags(flags); - const Akonadi::CollectionFlagsAttribute *flagAttr = collection.attribute(); - // the server does not support arbitrary flags, so filter out those it can't handle - if ( flagAttr && !flagAttr->flags().isEmpty() && !flagAttr->flags().contains( "\\*" ) ) { - for ( QList< QByteArray >::iterator it = imapFlags.begin(); it != imapFlags.end(); ) { - if ( flagAttr->flags().contains( *it ) ) { - ++it; - } else { - kDebug() << "Server does not support flag" << *it; - it = imapFlags.erase( it ); - } + const Akonadi::CollectionFlagsAttribute *flagAttr = collection.attribute(); + // the server does not support arbitrary flags, so filter out those it can't handle + if (flagAttr && !flagAttr->flags().isEmpty() && !flagAttr->flags().contains("\\*")) { + for (QList< QByteArray >::iterator it = imapFlags.begin(); it != imapFlags.end();) { + if (flagAttr->flags().contains(*it)) { + ++it; + } else { + qCDebug(IMAPRESOURCE_LOG) << "Server does not support flag" << *it; + it = imapFlags.erase(it); + } + } } - } - return imapFlags; + return imapFlags; } -QList ResourceTask::fromAkonadiFlags( const QList &flags ) +QList ResourceTask::fromAkonadiFlags(const QList &flags) { - QList newFlags; + QList newFlags; - foreach ( const QByteArray &oldFlag, flags ) { - if ( oldFlag == Akonadi::MessageFlags::Seen ) { - newFlags.append( ImapFlags::Seen ); - } else if ( oldFlag == Akonadi::MessageFlags::Deleted ) { - newFlags.append( ImapFlags::Deleted ); - } else if ( oldFlag == Akonadi::MessageFlags::Answered || oldFlag == Akonadi::MessageFlags::Replied ) { - newFlags.append( ImapFlags::Answered ); - } else if ( oldFlag == Akonadi::MessageFlags::Flagged ) { - newFlags.append( ImapFlags::Flagged ); - } else { - newFlags.append( oldFlag ); + foreach (const QByteArray &oldFlag, flags) { + if (oldFlag == Akonadi::MessageFlags::Seen) { + newFlags.append(ImapFlags::Seen); + } else if (oldFlag == Akonadi::MessageFlags::Deleted) { + newFlags.append(ImapFlags::Deleted); + } else if (oldFlag == Akonadi::MessageFlags::Answered || oldFlag == Akonadi::MessageFlags::Replied) { + newFlags.append(ImapFlags::Answered); + } else if (oldFlag == Akonadi::MessageFlags::Flagged) { + newFlags.append(ImapFlags::Flagged); + } else { + newFlags.append(oldFlag); + } } - } - return newFlags; + return newFlags; } -QList ResourceTask::toAkonadiFlags( const QList &flags ) +QList ResourceTask::toAkonadiFlags(const QList &flags) { - QList newFlags; + QList newFlags; - foreach ( const QByteArray &oldFlag, flags ) { - if ( oldFlag == ImapFlags::Seen ) { - newFlags.append( Akonadi::MessageFlags::Seen ); - } else if ( oldFlag == ImapFlags::Deleted ) { - newFlags.append( Akonadi::MessageFlags::Deleted ); - } else if ( oldFlag == ImapFlags::Answered ) { - newFlags.append( Akonadi::MessageFlags::Answered ); - } else if ( oldFlag == ImapFlags::Flagged ) { - newFlags.append( Akonadi::MessageFlags::Flagged ); - } else if ( oldFlag.isEmpty() ) { - // filter out empty flags, to avoid isNull/isEmpty confusions higher up - continue; - } else { - newFlags.append( oldFlag ); + foreach (const QByteArray &oldFlag, flags) { + if (oldFlag == ImapFlags::Seen) { + newFlags.append(Akonadi::MessageFlags::Seen); + } else if (oldFlag == ImapFlags::Deleted) { + newFlags.append(Akonadi::MessageFlags::Deleted); + } else if (oldFlag == ImapFlags::Answered) { + newFlags.append(Akonadi::MessageFlags::Answered); + } else if (oldFlag == ImapFlags::Flagged) { + newFlags.append(Akonadi::MessageFlags::Flagged); + } else if (oldFlag.isEmpty()) { + // filter out empty flags, to avoid isNull/isEmpty confusions higher up + continue; + } else { + newFlags.append(oldFlag); + } } - } - return newFlags; + return newFlags; } void ResourceTask::kill() { - kDebug(); - cancelTask(i18n("killed")); + Trace() << metaObject()->className(); + qCDebug(IMAPRESOURCE_LOG); + cancelTask(i18n("killed")); } const QChar ResourceTask::separatorCharacter() const { - const QChar separator = m_resource->separatorCharacter(); - if ( !separator.isNull() ) { - return separator; - } else { - //If we request the separator before first folder listing, then try to guess - //the separator: - //If we create a toplevel folder, assume the separator to be '/'. This is not perfect, but detecting the right - //IMAP separator is not straightforward for toplevel folders, and fixes bug 292418 and maybe other, where - //subfolders end up with remote id's starting with "i" (the first letter of imap:// ...) - - QString remoteId; - // We don't always have parent collection set (for example for CollectionChangeTask), - // in such cases however we can use current collection's remoteId to get the separator - const Akonadi::Collection parent = parentCollection(); - if ( parent.isValid() ) { - remoteId = parent.remoteId(); + const QChar separator = m_resource->separatorCharacter(); + if (!separator.isNull()) { + return separator; } else { - remoteId = collection().remoteId(); + //If we request the separator before first folder listing, then try to guess + //the separator: + //If we create a toplevel folder, assume the separator to be '/'. This is not perfect, but detecting the right + //IMAP separator is not straightforward for toplevel folders, and fixes bug 292418 and maybe other, where + //subfolders end up with remote id's starting with "i" (the first letter of imap:// ...) + + QString remoteId; + // We don't always have parent collection set (for example for CollectionChangeTask), + // in such cases however we can use current collection's remoteId to get the separator + const Akonadi::Collection parent = parentCollection(); + if (parent.isValid()) { + remoteId = parent.remoteId(); + } else { + remoteId = collection().remoteId(); + } + return ((remoteId != rootRemoteId()) && !remoteId.isEmpty()) ? remoteId.at(0) : QLatin1Char('/'); } - return ( ( remoteId != rootRemoteId() ) && !remoteId.isEmpty() ) ? remoteId.at( 0 ) : QLatin1Char('/'); - } } -void ResourceTask::setSeparatorCharacter( const QChar& separator ) +void ResourceTask::setSeparatorCharacter(const QChar &separator) { - m_resource->setSeparatorCharacter( separator ); + m_resource->setSeparatorCharacter(separator); } bool ResourceTask::serverSupportsAnnotations() const { - return serverCapabilities().contains( QLatin1String( "METADATA" ) ) - || serverCapabilities().contains( QLatin1String( "ANNOTATEMORE" ) ); + return serverCapabilities().contains(QStringLiteral("METADATA")) + || serverCapabilities().contains(QStringLiteral("ANNOTATEMORE")); } bool ResourceTask::serverSupportsCondstore() const { // Don't enable CONDSTORE for GMail (X-GM-EXT-1 is a GMail-specific capability) // because it breaks changes synchronization when using labels. - return serverCapabilities().contains( QLatin1String( "CONDSTORE" ) ) && - !serverCapabilities().contains( QLatin1String( "X-GM-EXT-1" ) ); + return serverCapabilities().contains(QStringLiteral("CONDSTORE")) && + !serverCapabilities().contains(QStringLiteral("X-GM-EXT-1")); } int ResourceTask::batchSize() const @@ -537,3 +576,18 @@ { return m_resource; } + +KIMAP::Acl::Rights ResourceTask::myRights(const Akonadi::Collection &col) +{ + Akonadi::ImapAclAttribute *aclAttribute = col.attribute(); + if (aclAttribute) { + //HACK, only return myrights if they are available + if (aclAttribute->myRights() != KIMAP::Acl::None) { + return aclAttribute->myRights(); + } else { + //This should be removed after 4.14, and myrights should be always used. + return aclAttribute->rights().value(userName().toUtf8()); + } + } + return KIMAP::Acl::None; +} diff -Nru kdepim-runtime-4.14.6/resources/imap/resourcetask.h kdepim-runtime-15.08.0/resources/imap/resourcetask.h --- kdepim-runtime-4.14.6/resources/imap/resourcetask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/resourcetask.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,141 +24,145 @@ #include -#include -#include +#include +#include #include +#include #include "resourcestateinterface.h" namespace KIMAP { - class Session; +class Session; } class SessionPool; class ResourceTask : public QObject { - Q_OBJECT - Q_ENUMS( ActionIfNoSession ) + Q_OBJECT + Q_ENUMS(ActionIfNoSession) public: - enum ActionIfNoSession { - CancelIfNoSession, - DeferIfNoSession - }; + enum ActionIfNoSession { + CancelIfNoSession, + DeferIfNoSession + }; - explicit ResourceTask( ActionIfNoSession action, ResourceStateInterface::Ptr resource, QObject *parent = 0 ); - virtual ~ResourceTask(); + explicit ResourceTask(ActionIfNoSession action, ResourceStateInterface::Ptr resource, QObject *parent = Q_NULLPTR); + virtual ~ResourceTask(); - void start( SessionPool *pool ); + void start(SessionPool *pool); - void kill(); + void kill(); - static QList fromAkonadiToSupportedImapFlags( const QList &flags, const Akonadi::Collection &collection ); + static QList fromAkonadiToSupportedImapFlags(const QList &flags, const Akonadi::Collection &collection); - static QList toAkonadiFlags( const QList &flags ); + static QList toAkonadiFlags(const QList &flags); Q_SIGNALS: - void status( int status, const QString &message = QString() ); + void status(int status, const QString &message = QString()); protected: - virtual void doStart( KIMAP::Session *session ) = 0; + virtual void doStart(KIMAP::Session *session) = 0; protected: - QString userName() const; - QString resourceName() const; - QStringList serverCapabilities() const; - QList serverNamespaces() const; + QString userName() const; + QString resourceName() const; + QStringList serverCapabilities() const; + QList serverNamespaces() const; - bool isAutomaticExpungeEnabled() const; - bool isSubscriptionEnabled() const; - bool isDisconnectedModeEnabled() const; - int intervalCheckTime() const; + bool isAutomaticExpungeEnabled() const; + bool isSubscriptionEnabled() const; + bool isDisconnectedModeEnabled() const; + int intervalCheckTime() const; - Akonadi::Collection collection() const; - Akonadi::Item item() const; - Akonadi::Item::List items() const; + Akonadi::Collection collection() const; + Akonadi::Item item() const; + Akonadi::Item::List items() const; - Akonadi::Collection parentCollection() const; + Akonadi::Collection parentCollection() const; - Akonadi::Collection sourceCollection() const; - Akonadi::Collection targetCollection() const; + Akonadi::Collection sourceCollection() const; + Akonadi::Collection targetCollection() const; - QSet parts() const; - QSet addedFlags() const; - QSet removedFlags() const; + QSet parts() const; + QSet addedFlags() const; + QSet removedFlags() const; - QString rootRemoteId() const; - QString mailBoxForCollection( const Akonadi::Collection &collection ) const; + QString rootRemoteId() const; + QString mailBoxForCollection(const Akonadi::Collection &collection) const; - void setIdleCollection( const Akonadi::Collection &collection ); - void applyCollectionChanges( const Akonadi::Collection &collection ); + void setIdleCollection(const Akonadi::Collection &collection); + void applyCollectionChanges(const Akonadi::Collection &collection); - void itemRetrieved( const Akonadi::Item &item ); + void itemRetrieved(const Akonadi::Item &item); - void itemsRetrieved( const Akonadi::Item::List &items ); - void itemsRetrievedIncremental( const Akonadi::Item::List &changed, - const Akonadi::Item::List &removed ); - void itemsRetrievalDone(); + void itemsRetrieved(const Akonadi::Item::List &items); + void itemsRetrievedIncremental(const Akonadi::Item::List &changed, + const Akonadi::Item::List &removed); + void itemsRetrievalDone(); - void setTotalItems(int); + void setTotalItems(int); - void changeCommitted( const Akonadi::Item &item ); - void changesCommitted( const Akonadi::Item::List &items ); + void changeCommitted(const Akonadi::Item &item); + void changesCommitted(const Akonadi::Item::List &items); - void collectionsRetrieved( const Akonadi::Collection::List &collections ); + void collectionsRetrieved(const Akonadi::Collection::List &collections); - void collectionAttributesRetrieved( const Akonadi::Collection &col ); + void collectionAttributesRetrieved(const Akonadi::Collection &col); - void changeCommitted( const Akonadi::Collection &collection ); + void changeCommitted(const Akonadi::Collection &collection); - void changeProcessed(); + void changeCommitted(const Akonadi::Tag &tag); - void searchFinished( const QVector &result, bool isRid = true ); + void changeProcessed(); - void cancelTask( const QString &errorString ); - void deferTask(); - void restartItemRetrieval(Akonadi::Collection::Id col); - void taskDone(); - void emitPercent( int percent ); - void emitError( const QString &message ); - void emitWarning( const QString &message ); + void searchFinished(const QVector &result, bool isRid = true); - void synchronizeCollectionTree(); + void cancelTask(const QString &errorString); + void deferTask(); + void restartItemRetrieval(Akonadi::Collection::Id col); + void taskDone(); + void emitPercent(int percent); + void emitError(const QString &message); + void emitWarning(const QString &message); - void showInformationDialog( const QString &message, const QString &title, const QString &dontShowAgainName ); + void synchronizeCollectionTree(); - const QChar separatorCharacter() const; - void setSeparatorCharacter( const QChar &separator ); + void showInformationDialog(const QString &message, const QString &title, const QString &dontShowAgainName); - virtual bool serverSupportsAnnotations() const; - virtual bool serverSupportsCondstore() const; + const QChar separatorCharacter() const; + void setSeparatorCharacter(const QChar &separator); - int batchSize() const; + virtual bool serverSupportsAnnotations() const; + virtual bool serverSupportsCondstore() const; - ResourceStateInterface::Ptr resourceState(); + int batchSize() const; -private: + ResourceStateInterface::Ptr resourceState(); + + KIMAP::Acl::Rights myRights(const Akonadi::Collection &); - static QList fromAkonadiFlags( const QList &flags ); +private: -private slots: - void onSessionRequested( qint64 requestId, KIMAP::Session *session, - int errorCode, const QString &errorString ); - void onConnectionLost( KIMAP::Session *session ); - void onPoolDisconnect(); + static QList fromAkonadiFlags(const QList &flags); +private Q_SLOTS: + void onSessionRequested(qint64 requestId, KIMAP::Session *session, + int errorCode, const QString &errorString); + void onConnectionLost(KIMAP::Session *session); + void onPoolDisconnect(); private: - SessionPool *m_pool; - qint64 m_sessionRequestId; + SessionPool *m_pool; + qint64 m_sessionRequestId; - KIMAP::Session *m_session; - ActionIfNoSession m_actionIfNoSession; - ResourceStateInterface::Ptr m_resource; - bool mCancelled; + KIMAP::Session *m_session; + ActionIfNoSession m_actionIfNoSession; + ResourceStateInterface::Ptr m_resource; + bool mCancelled; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/retrievecollectionmetadatatask.cpp kdepim-runtime-15.08.0/resources/imap/retrievecollectionmetadatatask.cpp --- kdepim-runtime-4.14.6/resources/imap/retrievecollectionmetadatatask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/retrievecollectionmetadatatask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -29,19 +29,22 @@ #include #include #include -#include +#include -#include -#include +#include "imapresource_debug.h" +#include "imapresource_debug.h" + +#include +#include #include "collectionannotationsattribute.h" #include "imapaclattribute.h" #include "imapquotaattribute.h" #include "noselectattribute.h" -#include "timestampattribute.h" +#include "collectionmetadatahelper.h" -RetrieveCollectionMetadataTask::RetrieveCollectionMetadataTask( ResourceStateInterface::Ptr resource, QObject *parent ) - : ResourceTask( CancelIfNoSession, resource, parent ), - m_pendingMetaDataJobs( 0 ) +RetrieveCollectionMetadataTask::RetrieveCollectionMetadataTask(ResourceStateInterface::Ptr resource, QObject *parent) + : ResourceTask(CancelIfNoSession, resource, parent), + m_pendingMetaDataJobs(0) { } @@ -49,268 +52,241 @@ { } -void RetrieveCollectionMetadataTask::doStart( KIMAP::Session *session ) +void RetrieveCollectionMetadataTask::doStart(KIMAP::Session *session) { - kDebug( 5327 ) << collection().remoteId(); + qCDebug(IMAPRESOURCE_LOG) << collection().remoteId(); - // Prevent fetching metadata from noselect folders. - if ( collection().hasAttribute( "noselect" ) ) { - NoSelectAttribute* noselect = static_cast( collection().attribute( "noselect" ) ); - if ( noselect->noSelect() ) { - kDebug( 5327 ) << "No Select folder"; - endTaskIfNeeded(); - return; - } - } - - m_collection = collection(); - const QString mailBox = mailBoxForCollection( m_collection ); - const QStringList capabilities = serverCapabilities(); - - m_pendingMetaDataJobs = 0; - - // First get the annotations from the mailbox if it's supported - if ( capabilities.contains( QLatin1String("METADATA") ) || capabilities.contains( QLatin1String("ANNOTATEMORE") ) ) { - KIMAP::GetMetaDataJob *meta = new KIMAP::GetMetaDataJob( session ); - meta->setMailBox( mailBox ); - if ( capabilities.contains( QLatin1String("METADATA") ) ) { - meta->setServerCapability( KIMAP::MetaDataJobBase::Metadata ); - meta->addRequestedEntry( "/shared" ); - meta->setDepth( KIMAP::GetMetaDataJob::AllLevels ); - } else { - meta->setServerCapability( KIMAP::MetaDataJobBase::Annotatemore ); - meta->addEntry( "*", "value.shared" ); - } - connect( meta, SIGNAL(result(KJob*)), SLOT(onGetMetaDataDone(KJob*)) ); - m_pendingMetaDataJobs++; - meta->start(); - } - - // Get the ACLs from the mailbox if it's supported - if ( capabilities.contains( QLatin1String("ACL") ) ) { - KIMAP::GetAclJob *acl = new KIMAP::GetAclJob( session ); - acl->setMailBox( mailBox ); - connect( acl, SIGNAL(result(KJob*)), SLOT(onGetAclDone(KJob*)) ); - m_pendingMetaDataJobs++; - acl->start(); - - KIMAP::MyRightsJob *rights = new KIMAP::MyRightsJob( session ); - rights->setMailBox( mailBox ); - connect( rights, SIGNAL(result(KJob*)), SLOT(onRightsReceived(KJob*)) ); - m_pendingMetaDataJobs++; - rights->start(); - } - - // Get the QUOTA info from the mailbox if it's supported - if ( capabilities.contains( QLatin1String("QUOTA") ) ) { - KIMAP::GetQuotaRootJob *quota = new KIMAP::GetQuotaRootJob( session ); - quota->setMailBox( mailBox ); - connect( quota, SIGNAL(result(KJob*)), SLOT(onQuotasReceived(KJob*)) ); - m_pendingMetaDataJobs++; - quota->start(); - } - - // the server does not have any of the capabilities needed to get extra info, so this - // step is done here - if ( m_pendingMetaDataJobs == 0 ) { - endTaskIfNeeded(); - } + // Prevent fetching metadata from noselect folders. + if (collection().hasAttribute("noselect")) { + NoSelectAttribute *noselect = static_cast(collection().attribute("noselect")); + if (noselect->noSelect()) { + qCDebug(IMAPRESOURCE_LOG) << "No Select folder"; + endTaskIfNeeded(); + return; + } + } + + m_session = session; + m_collection = collection(); + const QString mailBox = mailBoxForCollection(m_collection); + const QStringList capabilities = serverCapabilities(); + + m_pendingMetaDataJobs = 0; + + // First get the annotations from the mailbox if it's supported + if (capabilities.contains(QLatin1String("METADATA")) || capabilities.contains(QLatin1String("ANNOTATEMORE"))) { + KIMAP::GetMetaDataJob *meta = new KIMAP::GetMetaDataJob(session); + meta->setMailBox(mailBox); + if (capabilities.contains(QLatin1String("METADATA"))) { + meta->setServerCapability(KIMAP::MetaDataJobBase::Metadata); + meta->addRequestedEntry("/shared"); + meta->setDepth(KIMAP::GetMetaDataJob::AllLevels); + } else { + meta->setServerCapability(KIMAP::MetaDataJobBase::Annotatemore); + meta->addEntry("*", "value.shared"); + } + connect(meta, SIGNAL(result(KJob*)), SLOT(onGetMetaDataDone(KJob*))); + m_pendingMetaDataJobs++; + meta->start(); + } + + // Get the ACLs from the mailbox if it's supported + if (capabilities.contains(QLatin1String("ACL"))) { + KIMAP::MyRightsJob *rights = new KIMAP::MyRightsJob(session); + rights->setMailBox(mailBox); + connect(rights, SIGNAL(result(KJob*)), SLOT(onRightsReceived(KJob*))); + m_pendingMetaDataJobs++; + rights->start(); + } + + // Get the QUOTA info from the mailbox if it's supported + if (capabilities.contains(QLatin1String("QUOTA"))) { + KIMAP::GetQuotaRootJob *quota = new KIMAP::GetQuotaRootJob(session); + quota->setMailBox(mailBox); + connect(quota, SIGNAL(result(KJob*)), SLOT(onQuotasReceived(KJob*))); + m_pendingMetaDataJobs++; + quota->start(); + } + + // the server does not have any of the capabilities needed to get extra info, so this + // step is done here + if (m_pendingMetaDataJobs == 0) { + endTaskIfNeeded(); + } } -void RetrieveCollectionMetadataTask::onGetMetaDataDone( KJob *job ) +void RetrieveCollectionMetadataTask::onGetMetaDataDone(KJob *job) { - m_pendingMetaDataJobs--; - if ( job->error() ) { - kWarning() << "Get metadata failed: " << job->errorString(); - endTaskIfNeeded(); - return; // Well, no metadata for us then... - } + m_pendingMetaDataJobs--; + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Get metadata failed: " << job->errorString(); + endTaskIfNeeded(); + return; // Well, no metadata for us then... + } - KIMAP::GetMetaDataJob *meta = qobject_cast( job ); - QMap rawAnnotations = meta->allMetaData(); + KIMAP::GetMetaDataJob *meta = qobject_cast(job); + QMap rawAnnotations = meta->allMetaData(); - // filter out unused and annoying Cyrus annotation /vendor/cmu/cyrus-imapd/lastupdate - // which contains the current date and time and thus constantly changes for no good - // reason which triggers a change notification and thus a bunch of Akonadi operations - rawAnnotations.remove( "/shared/vendor/cmu/cyrus-imapd/lastupdate" ); - rawAnnotations.remove( "/private/vendor/cmu/cyrus-imapd/lastupdate" ); - - // Store the mailbox metadata - Akonadi::CollectionAnnotationsAttribute *annotationsAttribute = - m_collection.attribute( Akonadi::Collection::AddIfMissing ); - const QMap oldAnnotations = annotationsAttribute->annotations(); - if ( oldAnnotations != rawAnnotations ) { - annotationsAttribute->setAnnotations( rawAnnotations ); - } + // filter out unused and annoying Cyrus annotation /vendor/cmu/cyrus-imapd/lastupdate + // which contains the current date and time and thus constantly changes for no good + // reason which triggers a change notification and thus a bunch of Akonadi operations + rawAnnotations.remove("/shared/vendor/cmu/cyrus-imapd/lastupdate"); + rawAnnotations.remove("/private/vendor/cmu/cyrus-imapd/lastupdate"); + + // Store the mailbox metadata + Akonadi::CollectionAnnotationsAttribute *annotationsAttribute = + m_collection.attribute(Akonadi::Collection::AddIfMissing); + const QMap oldAnnotations = annotationsAttribute->annotations(); + if (oldAnnotations != rawAnnotations) { + annotationsAttribute->setAnnotations(rawAnnotations); + } - endTaskIfNeeded(); + endTaskIfNeeded(); } -void RetrieveCollectionMetadataTask::onGetAclDone( KJob *job ) +void RetrieveCollectionMetadataTask::onGetAclDone(KJob *job) { - m_pendingMetaDataJobs--; - if ( job->error() ) { - kWarning() << "GetACL failed: " << job->errorString(); - endTaskIfNeeded(); - return; // Well, no metadata for us then... - } + m_pendingMetaDataJobs--; + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "GetACL failed: " << job->errorString(); + endTaskIfNeeded(); + return; // Well, no metadata for us then... + } - KIMAP::GetAclJob *acl = qobject_cast( job ); + KIMAP::GetAclJob *acl = qobject_cast(job); - // Store the mailbox ACLs - Akonadi::ImapAclAttribute *aclAttribute - = m_collection.attribute( Akonadi::Collection::AddIfMissing ); - const QMap oldRights = aclAttribute->rights(); - if ( oldRights != acl->allRights() ) { - aclAttribute->setRights( acl->allRights() ); - } + // Store the mailbox ACLs + Akonadi::ImapAclAttribute *const aclAttribute + = m_collection.attribute(Akonadi::Collection::AddIfMissing); + const QMap oldRights = aclAttribute->rights(); + if (oldRights != acl->allRights()) { + aclAttribute->setRights(acl->allRights()); + } - endTaskIfNeeded(); + endTaskIfNeeded(); } -void RetrieveCollectionMetadataTask::onRightsReceived( KJob *job ) +void RetrieveCollectionMetadataTask::onRightsReceived(KJob *job) { - m_pendingMetaDataJobs--; - if ( job->error() ) { - kWarning() << "MyRights failed: " << job->errorString(); - endTaskIfNeeded(); - return; // Well, no metadata for us then... - } + m_pendingMetaDataJobs--; + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "MyRights failed: " << job->errorString(); + endTaskIfNeeded(); + return; // Well, no metadata for us then... + } + + KIMAP::MyRightsJob *rightsJob = qobject_cast(job); - KIMAP::MyRightsJob *rightsJob = qobject_cast( job ); + const KIMAP::Acl::Rights imapRights = rightsJob->rights(); - Akonadi::ImapAclAttribute * const parentAclAttribute = - collection().parentCollection().attribute(); - KIMAP::Acl::Rights parentRights = 0; - if ( parentAclAttribute ) { - parentRights = parentAclAttribute->rights()[userName().toUtf8()]; - } - - KIMAP::Acl::Rights imapRights = rightsJob->rights(); - Akonadi::Collection::Rights newRights = Akonadi::Collection::ReadOnly; - - // For renaming, the parent folder needs to have the CreateMailbox or Create permission. - // We map renaming to CanChangeCollection here, which is not entirely correct, but we have no - // CanRenameCollection flag. - // If the ACL of the parent folder hasn't been retrieved yet, allow changing, since we don't know - // better. If the parent folder is a noselect folder though, don't allow it, since for those we have - // no CreateMailbox right. - if ( ( !parentAclAttribute && !collection().parentCollection().hasAttribute( "noselect" ) ) || - parentRights & KIMAP::Acl::CreateMailbox || - parentRights & KIMAP::Acl::Create ) { - newRights|= Akonadi::Collection::CanChangeCollection; - } - - if ( imapRights & KIMAP::Acl::Write ) { - newRights|= Akonadi::Collection::CanChangeItem; - } - - if ( imapRights & KIMAP::Acl::Insert ) { - newRights|= Akonadi::Collection::CanCreateItem; - } - - if ( imapRights & ( KIMAP::Acl::DeleteMessage | KIMAP::Acl::Delete ) ) { - newRights|= Akonadi::Collection::CanDeleteItem; - } - - if ( !m_collection.hasAttribute( "noinferiors" ) && imapRights & ( KIMAP::Acl::CreateMailbox | KIMAP::Acl::Create ) ) { - newRights|= Akonadi::Collection::CanCreateCollection; - } - - if ( imapRights & ( KIMAP::Acl::DeleteMailbox | KIMAP::Acl::Delete ) ) { - newRights|= Akonadi::Collection::CanDeleteCollection; - } + //Default value in case we have nothing better available + KIMAP::Acl::Rights parentRights = KIMAP::Acl::CreateMailbox | KIMAP::Acl::Create; -// kDebug( 5327 ) << collection.remoteId() + //FIXME I don't think we have the parent's acl's available + if (collection().parentCollection().attribute()) { + parentRights = myRights(collection().parentCollection()); + } + +// qCDebug(IMAPRESOURCE_LOG) << collection.remoteId() // << "imapRights:" << imapRights // << "newRights:" << newRights // << "oldRights:" << collection.rights(); - const bool isNewCollection = !m_collection.hasAttribute(); - if ( (m_collection.rights() & Akonadi::Collection::CanCreateItem) && - !(newRights & Akonadi::Collection::CanCreateItem) && - !isNewCollection ) { - // write access revoked - const QString collectionName = m_collection.displayName(); - - showInformationDialog( i18n( "

Your access rights to folder %1 have been restricted, " - "it will no longer be possible to add messages to this folder.

", - collectionName ), - i18n( "Access rights revoked" ), QLatin1String("ShowRightsRevokedWarning") ); - } - - if ( newRights != m_collection.rights() ) { - m_collection.setRights( newRights ); - } + const bool isNewCollection = !m_collection.hasAttribute(); + const bool accessRevoked = CollectionMetadataHelper::applyRights(m_collection, imapRights, parentRights); + if (accessRevoked && !isNewCollection) { + // write access revoked + const QString collectionName = m_collection.displayName(); + + showInformationDialog(i18n("

Your access rights to folder %1 have been restricted, " + "it will no longer be possible to add messages to this folder.

", + collectionName), + i18n("Access rights revoked"), QStringLiteral("ShowRightsRevokedWarning")); + } + + // Store the mailbox ACLs + Akonadi::ImapAclAttribute *aclAttribute + = m_collection.attribute(Akonadi::Collection::AddIfMissing); + const KIMAP::Acl::Rights oldRights = aclAttribute->myRights(); + if (oldRights != imapRights) { + aclAttribute->setMyRights(imapRights); + } - endTaskIfNeeded(); + //The a right is required to list acl's + if (imapRights & KIMAP::Acl::Admin) { + KIMAP::GetAclJob *acl = new KIMAP::GetAclJob(m_session); + acl->setMailBox(mailBoxForCollection(m_collection)); + connect(acl, SIGNAL(result(KJob*)), SLOT(onGetAclDone(KJob*))); + m_pendingMetaDataJobs++; + acl->start(); + } + + endTaskIfNeeded(); } -void RetrieveCollectionMetadataTask::onQuotasReceived( KJob *job ) +void RetrieveCollectionMetadataTask::onQuotasReceived(KJob *job) { - m_pendingMetaDataJobs--; - if ( job->error() ) { - kWarning() << "Quota retrieval failed: " << job->errorString(); - endTaskIfNeeded(); - return; // Well, no metadata for us then... - } + m_pendingMetaDataJobs--; + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Quota retrieval failed: " << job->errorString(); + endTaskIfNeeded(); + return; // Well, no metadata for us then... + } + + KIMAP::GetQuotaRootJob *quotaJob = qobject_cast(job); + const QString &mailBox = mailBoxForCollection(m_collection); + + QList newRoots = quotaJob->roots(); + QList< QMap > newLimits; + QList< QMap > newUsages; + qint64 newCurrent = -1; + qint64 newMax = -1; + newLimits.reserve(newRoots.count()); + newUsages.reserve(newRoots.count()); + + foreach (const QByteArray &root, newRoots) { + newLimits << quotaJob->allLimits(root); + newUsages << quotaJob->allUsages(root); + + const QString &decodedRoot = QString::fromUtf8(KIMAP::decodeImapFolderName(root)); + + if (newRoots.size() == 1 || decodedRoot == mailBox) { + newCurrent = newUsages.last()["STORAGE"] * 1024; + newMax = newLimits.last()["STORAGE"] * 1024; + } + } - KIMAP::GetQuotaRootJob *quotaJob = qobject_cast( job ); - const QString &mailBox = mailBoxForCollection( m_collection ); + // Store the mailbox IMAP Quotas + Akonadi::ImapQuotaAttribute *imapQuotaAttribute + = m_collection.attribute(Akonadi::Collection::AddIfMissing); + const QList oldRoots = imapQuotaAttribute->roots(); + const QList< QMap > oldLimits = imapQuotaAttribute->limits(); + const QList< QMap > oldUsages = imapQuotaAttribute->usages(); + + if (oldRoots != newRoots + || oldLimits != newLimits + || oldUsages != newUsages) { + imapQuotaAttribute->setQuotas(newRoots, newLimits, newUsages); + } - QList newRoots = quotaJob->roots(); - QList< QMap > newLimits; - QList< QMap > newUsages; - qint64 newCurrent = -1; - qint64 newMax = -1; - - foreach ( const QByteArray &root, newRoots ) { - newLimits << quotaJob->allLimits( root ); - newUsages << quotaJob->allUsages( root ); - - const QString &decodedRoot = QString::fromUtf8( KIMAP::decodeImapFolderName( root ) ); - - if ( newRoots.size() == 1 || decodedRoot == mailBox ) { - newCurrent = newUsages.last()["STORAGE"] * 1024; - newMax = newLimits.last()["STORAGE"] * 1024; - } - } - - // Store the mailbox IMAP Quotas - Akonadi::ImapQuotaAttribute *imapQuotaAttribute - = m_collection.attribute( Akonadi::Collection::AddIfMissing ); - const QList oldRoots = imapQuotaAttribute->roots(); - const QList< QMap > oldLimits = imapQuotaAttribute->limits(); - const QList< QMap > oldUsages = imapQuotaAttribute->usages(); - - if ( oldRoots != newRoots - || oldLimits != newLimits - || oldUsages != newUsages ) { - imapQuotaAttribute->setQuotas( newRoots, newLimits, newUsages ); - } - - // Store the collection Quota - Akonadi::CollectionQuotaAttribute *quotaAttribute - = m_collection.attribute( Akonadi::Collection::AddIfMissing ); - qint64 oldCurrent = quotaAttribute->currentValue(); - qint64 oldMax = quotaAttribute->maximumValue(); - - if ( oldCurrent != newCurrent - || oldMax != newMax ) { - quotaAttribute->setCurrentValue( newCurrent ); - quotaAttribute->setMaximumValue( newMax ); - } + // Store the collection Quota + Akonadi::CollectionQuotaAttribute *quotaAttribute + = m_collection.attribute(Akonadi::Collection::AddIfMissing); + qint64 oldCurrent = quotaAttribute->currentValue(); + qint64 oldMax = quotaAttribute->maximumValue(); + + if (oldCurrent != newCurrent + || oldMax != newMax) { + quotaAttribute->setCurrentValue(newCurrent); + quotaAttribute->setMaximumValue(newMax); + } - endTaskIfNeeded(); + endTaskIfNeeded(); } void RetrieveCollectionMetadataTask::endTaskIfNeeded() { - if ( m_pendingMetaDataJobs <= 0 ) { - const uint currentTimestamp = QDateTime::currentDateTime().toTime_t(); - TimestampAttribute *attr = m_collection.attribute( Akonadi::Collection::AddIfMissing ); - attr->setTimestamp( currentTimestamp ); - - collectionAttributesRetrieved( m_collection ); - } + if (m_pendingMetaDataJobs <= 0) { + collectionAttributesRetrieved(m_collection); + } } diff -Nru kdepim-runtime-4.14.6/resources/imap/retrievecollectionmetadatatask.h kdepim-runtime-15.08.0/resources/imap/retrievecollectionmetadatatask.h --- kdepim-runtime-4.14.6/resources/imap/retrievecollectionmetadatatask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/retrievecollectionmetadatatask.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,27 +26,28 @@ class RetrieveCollectionMetadataTask : public ResourceTask { - Q_OBJECT + Q_OBJECT public: - explicit RetrieveCollectionMetadataTask( ResourceStateInterface::Ptr resource, QObject *parent = 0 ); - virtual ~RetrieveCollectionMetadataTask(); + explicit RetrieveCollectionMetadataTask(ResourceStateInterface::Ptr resource, QObject *parent = Q_NULLPTR); + virtual ~RetrieveCollectionMetadataTask(); -private slots: - void onGetMetaDataDone( KJob *job ); - void onGetAclDone( KJob *job ); - void onRightsReceived( KJob *job ); - void onQuotasReceived( KJob *job ); +private Q_SLOTS: + void onGetMetaDataDone(KJob *job); + void onGetAclDone(KJob *job); + void onRightsReceived(KJob *job); + void onQuotasReceived(KJob *job); protected: - virtual void doStart( KIMAP::Session *session ); + void doStart(KIMAP::Session *session) Q_DECL_OVERRIDE; private: - void endTaskIfNeeded(); + void endTaskIfNeeded(); - int m_pendingMetaDataJobs; + int m_pendingMetaDataJobs; - Akonadi::Collection m_collection; + Akonadi::Collection m_collection; + KIMAP::Session *m_session; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/retrievecollectionstask.cpp kdepim-runtime-15.08.0/resources/imap/retrievecollectionstask.cpp --- kdepim-runtime-4.14.6/resources/imap/retrievecollectionstask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/retrievecollectionstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,17 +24,18 @@ #include "noselectattribute.h" #include "noinferiorsattribute.h" -#include -#include -#include +#include +#include +#include +#include #include -#include -#include +#include "imapresource_debug.h" +#include -RetrieveCollectionsTask::RetrieveCollectionsTask( ResourceStateInterface::Ptr resource, QObject *parent ) - : ResourceTask( CancelIfNoSession, resource, parent ) +RetrieveCollectionsTask::RetrieveCollectionsTask(ResourceStateInterface::Ptr resource, QObject *parent) + : ResourceTask(CancelIfNoSession, resource, parent) { } @@ -42,195 +43,193 @@ { } -void RetrieveCollectionsTask::doStart( KIMAP::Session *session ) +void RetrieveCollectionsTask::doStart(KIMAP::Session *session) { - Akonadi::Collection root; - root.setName( resourceName() ); - root.setRemoteId( rootRemoteId() ); - root.setContentMimeTypes( QStringList( Akonadi::Collection::mimeType() ) ); - root.setParentCollection( Akonadi::Collection::root() ); - root.addAttribute( new NoSelectAttribute( true ) ); - - Akonadi::CachePolicy policy; - policy.setInheritFromParent( false ); - policy.setSyncOnDemand( true ); - - QStringList localParts; - localParts << QLatin1String(Akonadi::MessagePart::Envelope) - << QLatin1String(Akonadi::MessagePart::Header); - int cacheTimeout = 60; - - if ( isDisconnectedModeEnabled() ) { - // For disconnected mode we also cache the body - // and we keep all data indifinitely - localParts << QLatin1String(Akonadi::MessagePart::Body); - cacheTimeout = -1; - } - - policy.setLocalParts( localParts ); - policy.setCacheTimeout( cacheTimeout ); - policy.setIntervalCheckTime( intervalCheckTime() ); - - root.setCachePolicy( policy ); - - m_reportedCollections.insert( QString(), root ); - - // this is ugly, but the result of LSUB is unfortunately not a sub-set of LIST - // it also contains subscribed but currently not available (eg. deleted) mailboxes - // so we need to use both and exclude mailboxes in LSUB but not in LIST - if ( isSubscriptionEnabled() ) { - KIMAP::ListJob *fullListJob = new KIMAP::ListJob( session ); - fullListJob->setIncludeUnsubscribed( true ); - fullListJob->setQueriedNamespaces( serverNamespaces() ); - connect( fullListJob, SIGNAL(mailBoxesReceived(QList,QList >)), - this, SLOT(onFullMailBoxesReceived(QList,QList >)) ); - connect( fullListJob, SIGNAL(result(KJob*)), SLOT(onFullMailBoxesReceiveDone(KJob*)) ); - fullListJob->start(); - } - - KIMAP::ListJob *listJob = new KIMAP::ListJob( session ); - listJob->setIncludeUnsubscribed( !isSubscriptionEnabled() ); - listJob->setQueriedNamespaces( serverNamespaces() ); - connect( listJob, SIGNAL(mailBoxesReceived(QList,QList >)), - this, SLOT(onMailBoxesReceived(QList,QList >)) ); - connect( listJob, SIGNAL(result(KJob*)), SLOT(onMailBoxesReceiveDone(KJob*)) ); - listJob->start(); -} - -void RetrieveCollectionsTask::onMailBoxesReceived( const QList< KIMAP::MailBoxDescriptor > &descriptors, - const QList< QList > &flags ) -{ - QStringList contentTypes; - contentTypes << KMime::Message::mimeType() << Akonadi::Collection::mimeType(); - - if ( !descriptors.isEmpty() ) { - // This is still not optimal way of getting the separator, but it's better - // than guessing every time from RID of parent collection - setSeparatorCharacter( descriptors.first().separator ); - } - - for ( int i=0; i(); - - m_dummyCollections.remove( currentPath ); - m_reportedCollections.remove( currentPath ); - m_reportedCollections.insert( currentPath, c ); + Akonadi::Collection root; + root.setName(resourceName()); + root.setRemoteId(rootRemoteId()); + root.setContentMimeTypes(QStringList(Akonadi::Collection::mimeType())); + root.setParentCollection(Akonadi::Collection::root()); + root.addAttribute(new NoSelectAttribute(true)); + + Akonadi::CachePolicy policy; + policy.setInheritFromParent(false); + policy.setSyncOnDemand(true); + + QStringList localParts; + localParts << QLatin1String(Akonadi::MessagePart::Envelope) + << QLatin1String(Akonadi::MessagePart::Header); + int cacheTimeout = 60; + + if (isDisconnectedModeEnabled()) { + // For disconnected mode we also cache the body + // and we keep all data indifinitely + localParts << QLatin1String(Akonadi::MessagePart::Body); + cacheTimeout = -1; + } + + policy.setLocalParts(localParts); + policy.setCacheTimeout(cacheTimeout); + policy.setIntervalCheckTime(intervalCheckTime()); + + root.setCachePolicy(policy); + + m_reportedCollections.insert(QString(), root); + + // this is ugly, but the result of LSUB is unfortunately not a sub-set of LIST + // it also contains subscribed but currently not available (eg. deleted) mailboxes + // so we need to use both and exclude mailboxes in LSUB but not in LIST + if (isSubscriptionEnabled()) { + KIMAP::ListJob *fullListJob = new KIMAP::ListJob(session); + fullListJob->setIncludeUnsubscribed(true); + fullListJob->setQueriedNamespaces(serverNamespaces()); + connect(fullListJob, &KIMAP::ListJob::mailBoxesReceived, + this, &RetrieveCollectionsTask::onFullMailBoxesReceived); + connect(fullListJob, &KIMAP::ListJob::result, this, &RetrieveCollectionsTask::onFullMailBoxesReceiveDone); + fullListJob->start(); + } + + KIMAP::ListJob *listJob = new KIMAP::ListJob(session); + listJob->setIncludeUnsubscribed(!isSubscriptionEnabled()); + listJob->setQueriedNamespaces(serverNamespaces()); + connect(listJob, &KIMAP::ListJob::mailBoxesReceived, + this, &RetrieveCollectionsTask::onMailBoxesReceived); + connect(listJob, &KIMAP::ListJob::result, this, &RetrieveCollectionsTask::onMailBoxesReceiveDone); + listJob->start(); +} + +void RetrieveCollectionsTask::onMailBoxesReceived(const QList< KIMAP::MailBoxDescriptor > &descriptors, + const QList< QList > &flags) +{ + QStringList contentTypes; + contentTypes << KMime::Message::mimeType() << Akonadi::Collection::mimeType(); + + if (!descriptors.isEmpty()) { + // This is still not optimal way of getting the separator, but it's better + // than guessing every time from RID of parent collection + setSeparatorCharacter(descriptors.first().separator); + } + + for (int i = 0; i < descriptors.size(); ++i) { + KIMAP::MailBoxDescriptor descriptor = descriptors[i]; + // skip phantom mailboxes contained in LSUB but not LIST + if (isSubscriptionEnabled() && !m_fullReportedCollections.contains(descriptor.name)) { + qCDebug(IMAPRESOURCE_LOG) << "Got phantom mailbox: " << descriptor.name; + continue; } - parentPath = currentPath; - continue; - } - - const QList currentFlags = isDummy ? ( QList() << "\\noselect" ) : flags[i]; - - Akonadi::Collection c; - c.setName( pathPart ); - c.setRemoteId( separator + pathPart ); - const Akonadi::Collection parentCollection = m_reportedCollections.value( parentPath ); - c.setParentCollection( parentCollection ); - c.setContentMimeTypes( contentTypes ); - - // If the folder is the Inbox, make some special settings. - if ( currentPath.compare( separator + QLatin1String( "INBOX" ) , Qt::CaseInsensitive ) == 0 ) { - Akonadi::EntityDisplayAttribute *attr = c.attribute( Akonadi::Collection::AddIfMissing ); - attr->setDisplayName( i18n( "Inbox" ) ); - attr->setIconName( QLatin1String("mail-folder-inbox") ); - setIdleCollection( c ); - } - - // If the folder is the user top-level folder, mark it as well, even although it is not officially noted in the RFC - if ( currentPath == ( separator + QLatin1String( "user" ) ) && currentFlags.contains( "\\noselect" ) ) { - Akonadi::EntityDisplayAttribute *attr = c.attribute( Akonadi::Collection::AddIfMissing ); - attr->setDisplayName( i18n( "Shared Folders" ) ); - attr->setIconName( QLatin1String("x-mail-distribution-list") ); - } - - // If this folder is a noselect folder, make some special settings. - if ( currentFlags.contains( "\\noselect" ) ) { - kDebug() << "Dummy collection created: " << currentPath; - c.addAttribute( new NoSelectAttribute( true ) ); - c.setContentMimeTypes( QStringList() << Akonadi::Collection::mimeType() ); - c.setRights( Akonadi::Collection::ReadOnly ); - } else { - // remove the noselect attribute explicitly, in case we had set it before (eg. for non-subscribed non-leaf folders) - c.removeAttribute(); - } - - // If this folder is a noinferiors folder, it is not allowed to create subfolders inside. - if ( currentFlags.contains( "\\noinferiors" ) ) { - //kDebug() << "Noinferiors: " << currentPath; - c.addAttribute( new NoInferiorsAttribute( true ) ); - c.setRights( c.rights() & ~Akonadi::Collection::CanCreateCollection ); - } - - m_reportedCollections.insert( currentPath, c ); - - if ( isDummy ) { - m_dummyCollections.insert( currentPath, c ); - } - - parentPath = currentPath; - } - } -} - -void RetrieveCollectionsTask::onMailBoxesReceiveDone( KJob* job ) -{ - if ( job->error() ) { - cancelTask( job->errorString() ); - } else { - collectionsRetrieved( m_reportedCollections.values() ); - } -} - -void RetrieveCollectionsTask::onFullMailBoxesReceived( const QList< KIMAP::MailBoxDescriptor >& descriptors, - const QList< QList< QByteArray > >& flags ) -{ - Q_UNUSED( flags ); - foreach ( const KIMAP::MailBoxDescriptor &descriptor, descriptors ) { - m_fullReportedCollections.insert( descriptor.name ); - } -} - -void RetrieveCollectionsTask::onFullMailBoxesReceiveDone(KJob* job) -{ - if ( job->error() ) { - cancelTask( job->errorString() ); - } + + const QString separator = descriptor.separator; + Q_ASSERT(separator.size() == 1); // that's what the spec says + + const QString boxName = descriptor.name.endsWith(separator) + ? descriptor.name.left(descriptor.name.size() - 1) + : descriptor.name; + + const QStringList pathParts = boxName.split(separator); + + QString parentPath; + QString currentPath; + + for (int j = 0; j < pathParts.size(); ++j) { + const bool isDummy = j != pathParts.size() - 1; + const QString pathPart = pathParts.at(j); + currentPath += separator + pathPart; + + if (m_reportedCollections.contains(currentPath)) { + if (m_dummyCollections.contains(currentPath) && !isDummy) { + qCDebug(IMAPRESOURCE_LOG) << "Received the real collection for a dummy one : " << currentPath; + + //set the correct attributes for the collection, eg. noselect needs to be removed + Akonadi::Collection c = m_reportedCollections.value(currentPath); + c.setContentMimeTypes(contentTypes); + c.setRights(Akonadi::Collection::AllRights); + c.removeAttribute(); + + m_dummyCollections.remove(currentPath); + m_reportedCollections.remove(currentPath); + m_reportedCollections.insert(currentPath, c); + + } + parentPath = currentPath; + continue; + } + + const QList currentFlags = isDummy ? (QList() << "\\noselect") : flags[i]; + + Akonadi::Collection c; + c.setName(pathPart); + c.setRemoteId(separator + pathPart); + const Akonadi::Collection parentCollection = m_reportedCollections.value(parentPath); + c.setParentCollection(parentCollection); + c.setContentMimeTypes(contentTypes); + + // If the folder is the Inbox, make some special settings. + if (currentPath.compare(separator + QLatin1String("INBOX") , Qt::CaseInsensitive) == 0) { + Akonadi::EntityDisplayAttribute *attr = c.attribute(Akonadi::Collection::AddIfMissing); + attr->setDisplayName(i18n("Inbox")); + attr->setIconName(QLatin1String("mail-folder-inbox")); + setIdleCollection(c); + } + + // If the folder is the user top-level folder, mark it as well, even although it is not officially noted in the RFC + if (currentPath == (separator + QLatin1String("user")) && currentFlags.contains("\\noselect")) { + Akonadi::EntityDisplayAttribute *attr = c.attribute(Akonadi::Collection::AddIfMissing); + attr->setDisplayName(i18n("Shared Folders")); + attr->setIconName(QLatin1String("x-mail-distribution-list")); + } + + // If this folder is a noselect folder, make some special settings. + if (currentFlags.contains("\\noselect")) { + qCDebug(IMAPRESOURCE_LOG) << "Dummy collection created: " << currentPath; + c.addAttribute(new NoSelectAttribute(true)); + c.setContentMimeTypes(QStringList() << Akonadi::Collection::mimeType()); + c.setRights(Akonadi::Collection::ReadOnly); + } else { + // remove the noselect attribute explicitly, in case we had set it before (eg. for non-subscribed non-leaf folders) + c.removeAttribute(); + } + + // If this folder is a noinferiors folder, it is not allowed to create subfolders inside. + if (currentFlags.contains("\\noinferiors")) { + //qCDebug(IMAPRESOURCE_LOG) << "Noinferiors: " << currentPath; + c.addAttribute(new NoInferiorsAttribute(true)); + c.setRights(c.rights() & ~Akonadi::Collection::CanCreateCollection); + } + + m_reportedCollections.insert(currentPath, c); + + if (isDummy) { + m_dummyCollections.insert(currentPath, c); + } + + parentPath = currentPath; + } + } } +void RetrieveCollectionsTask::onMailBoxesReceiveDone(KJob *job) +{ + if (job->error()) { + cancelTask(job->errorString()); + } else { + collectionsRetrieved(Akonadi::valuesToVector(m_reportedCollections)); + } +} + +void RetrieveCollectionsTask::onFullMailBoxesReceived(const QList< KIMAP::MailBoxDescriptor > &descriptors, + const QList< QList< QByteArray > > &flags) +{ + Q_UNUSED(flags); + foreach (const KIMAP::MailBoxDescriptor &descriptor, descriptors) { + m_fullReportedCollections.insert(descriptor.name); + } +} +void RetrieveCollectionsTask::onFullMailBoxesReceiveDone(KJob *job) +{ + if (job->error()) { + cancelTask(job->errorString()); + } +} diff -Nru kdepim-runtime-4.14.6/resources/imap/retrievecollectionstask.h kdepim-runtime-15.08.0/resources/imap/retrievecollectionstask.h --- kdepim-runtime-4.14.6/resources/imap/retrievecollectionstask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/retrievecollectionstask.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,7 +22,7 @@ #ifndef RETRIEVECOLLECTIONSTASK_H #define RETRIEVECOLLECTIONSTASK_H -#include +#include #include @@ -30,26 +30,26 @@ class RetrieveCollectionsTask : public ResourceTask { - Q_OBJECT + Q_OBJECT public: - explicit RetrieveCollectionsTask( ResourceStateInterface::Ptr resource, QObject *parent = 0 ); - virtual ~RetrieveCollectionsTask(); + explicit RetrieveCollectionsTask(ResourceStateInterface::Ptr resource, QObject *parent = Q_NULLPTR); + virtual ~RetrieveCollectionsTask(); -private slots: - void onMailBoxesReceived( const QList &descriptors, - const QList< QList > &flags ); - void onMailBoxesReceiveDone( KJob *job ); - void onFullMailBoxesReceived( const QList &descriptors, const QList > &flags ); - void onFullMailBoxesReceiveDone( KJob *job ); +private Q_SLOTS: + void onMailBoxesReceived(const QList &descriptors, + const QList< QList > &flags); + void onMailBoxesReceiveDone(KJob *job); + void onFullMailBoxesReceived(const QList &descriptors, const QList > &flags); + void onFullMailBoxesReceiveDone(KJob *job); protected: - virtual void doStart( KIMAP::Session *session ); + void doStart(KIMAP::Session *session) Q_DECL_OVERRIDE; protected: - QHash m_reportedCollections; - QHash m_dummyCollections; - QSet m_fullReportedCollections; + QHash m_reportedCollections; + QHash m_dummyCollections; + QSet m_fullReportedCollections; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/retrieveitemstask.cpp kdepim-runtime-15.08.0/resources/imap/retrieveitemstask.cpp --- kdepim-runtime-4.14.6/resources/imap/retrieveitemstask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/retrieveitemstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -30,16 +30,21 @@ #include "messagehelper.h" #include "batchfetcher.h" -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include -#include -#include +#include "imapresource_debug.h" +#include "imapresource_debug.h" + +#include "imapresource_debug.h" +#include "imapresource_debug.h" + +#include #include #include @@ -49,12 +54,12 @@ RetrieveItemsTask::RetrieveItemsTask(ResourceStateInterface::Ptr resource, QObject *parent) : ResourceTask(CancelIfNoSession, resource, parent), - m_session(0), - m_fetchedMissingBodies(-1), - m_fetchMissingBodies(false), - m_batchFetcher(0), - m_uidBasedFetch(true), - m_flagsChanged(false) + m_session(Q_NULLPTR), + m_fetchedMissingBodies(-1), + m_fetchMissingBodies(false), + m_batchFetcher(Q_NULLPTR), + m_uidBasedFetch(true), + m_flagsChanged(false) { } @@ -73,9 +78,9 @@ emitPercent(0); // Prevent fetching items from noselect folders. if (collection().hasAttribute("noselect")) { - NoSelectAttribute* noselect = static_cast(collection().attribute("noselect")); + NoSelectAttribute *noselect = static_cast(collection().attribute("noselect")); if (noselect->noSelect()) { - kDebug(5327) << "No Select folder"; + qCDebug(IMAPRESOURCE_LOG) << "No Select folder"; itemsRetrievalDone(); return; } @@ -85,24 +90,24 @@ const Akonadi::Collection col = collection(); if (m_fetchMissingBodies && col.cachePolicy() - .localParts().contains( QLatin1String(Akonadi::MessagePart::Body))) { //disconnected mode, make sure we really have the body cached + .localParts().contains(QLatin1String(Akonadi::MessagePart::Body))) { //disconnected mode, make sure we really have the body cached Akonadi::Session *session = new Akonadi::Session(resourceName().toLatin1() + "_body_checker", this); Akonadi::ItemFetchJob *fetchJob = new Akonadi::ItemFetchJob(col, session); fetchJob->fetchScope().setCheckForCachedPayloadPartsOnly(); fetchJob->fetchScope().fetchPayloadPart(Akonadi::MessagePart::Body); fetchJob->fetchScope().setFetchModificationTime(false); - connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(fetchItemsWithoutBodiesDone(KJob*))); - connect(fetchJob, SIGNAL(result(KJob*)), session, SLOT(deleteLater())); + connect(fetchJob, &Akonadi::ItemFetchJob::result, this, &RetrieveItemsTask::fetchItemsWithoutBodiesDone); + connect(fetchJob, &Akonadi::ItemFetchJob::result, session, &Akonadi::Session::deleteLater); } else { startRetrievalTasks(); } } -BatchFetcher* RetrieveItemsTask::createBatchFetcher(MessageHelper::Ptr messageHelper, - const KIMAP::ImapSet &set, - const KIMAP::FetchJob::FetchScope &scope, - int batchSize, KIMAP::Session* session) +BatchFetcher *RetrieveItemsTask::createBatchFetcher(MessageHelper::Ptr messageHelper, + const KIMAP::ImapSet &set, + const KIMAP::FetchJob::FetchScope &scope, + int batchSize, KIMAP::Session *session) { return new BatchFetcher(messageHelper, set, scope, batchSize, session); } @@ -111,21 +116,21 @@ { QList uids; if (job->error()) { - kWarning() << job->errorString(); + qCWarning(IMAPRESOURCE_LOG) << job->errorString(); cancelTask(job->errorString()); return; } else { int i = 0; - Akonadi::ItemFetchJob *fetch = static_cast(job); - Q_FOREACH(const Akonadi::Item &item, fetch->items()) { + Akonadi::ItemFetchJob *fetch = static_cast(job); + Q_FOREACH (const Akonadi::Item &item, fetch->items()) { if (!item.cachedPayloadParts().contains(Akonadi::MessagePart::Body)) { - kWarning() << "Item " << item.id() << " is missing the payload! Cached payloads: " << item.cachedPayloadParts(); + qCWarning(IMAPRESOURCE_LOG) << "Item " << item.id() << " is missing the payload! Cached payloads: " << item.cachedPayloadParts(); uids.append(item.remoteId().toInt()); i++; } } if (i > 0) { - kWarning() << "Number of items missing the body: " << i; + qCWarning(IMAPRESOURCE_LOG) << "Number of items missing the body: " << i; } } onFetchItemsWithoutBodiesDone(uids); @@ -137,16 +142,15 @@ startRetrievalTasks(); } - void RetrieveItemsTask::startRetrievalTasks() { const QString mailBox = mailBoxForCollection(collection()); - kDebug(5327) << "Starting retrieval for " << mailBox; + qCDebug(IMAPRESOURCE_LOG) << "Starting retrieval for " << mailBox; m_time.start(); // Now is the right time to expunge the messages marked \\Deleted from this mailbox. // We assume that we can only expunge if we can delete items (correct would be to check for "e" ACL right). - if (isAutomaticExpungeEnabled() && (collection().rights() & Akonadi::Collection::CanDeleteItem)) { + if (isAutomaticExpungeEnabled() && (!serverCapabilities().contains(QLatin1String("ACL")) || (myRights(collection()) & KIMAP::Acl::Expunge))) { if (m_session->selectedMailBox() != mailBox) { triggerPreExpungeSelect(mailBox); } else { @@ -163,18 +167,18 @@ KIMAP::SelectJob *select = new KIMAP::SelectJob(m_session); select->setMailBox(mailBox); select->setCondstoreEnabled(serverSupportsCondstore()); - connect(select, SIGNAL(result(KJob*)), - this, SLOT(onPreExpungeSelectDone(KJob*))); + connect(select, &KJob::result, + this, &RetrieveItemsTask::onPreExpungeSelectDone); select->start(); } void RetrieveItemsTask::onPreExpungeSelectDone(KJob *job) { if (job->error()) { - kWarning() << job->errorString(); + qCWarning(IMAPRESOURCE_LOG) << job->errorString(); cancelTask(job->errorString()); } else { - KIMAP::SelectJob *select = static_cast(job); + KIMAP::SelectJob *select = static_cast(job); triggerExpunge(select->mailBox()); } } @@ -182,8 +186,8 @@ void RetrieveItemsTask::triggerExpunge(const QString &mailBox) { KIMAP::ExpungeJob *expunge = new KIMAP::ExpungeJob(m_session); - connect(expunge, SIGNAL(result(KJob*)), - this, SLOT(onExpungeDone(KJob*))); + connect(expunge, &KJob::result, + this, &RetrieveItemsTask::onExpungeDone); expunge->start(); } @@ -192,11 +196,11 @@ // We can ignore the error, we just had a wrong expunge so some old messages will just reappear. // TODO we should probably hide messages that are marked as deleted (skipping will not work because we rely on the message count) if (job->error()) { - kWarning() << "Expunge failed: " << job->errorString(); + qCWarning(IMAPRESOURCE_LOG) << "Expunge failed: " << job->errorString(); } // Except for network errors. if (job->error() && m_session->state() == KIMAP::Session::Disconnected) { - cancelTask( job->errorString() ); + cancelTask(job->errorString()); return; } @@ -210,20 +214,20 @@ KIMAP::SelectJob *select = new KIMAP::SelectJob(m_session); select->setMailBox(mailBox); select->setCondstoreEnabled(serverSupportsCondstore()); - connect( select, SIGNAL(result(KJob*)), - this, SLOT(onFinalSelectDone(KJob*)) ); + connect(select, &KJob::result, + this, &RetrieveItemsTask::onFinalSelectDone); select->start(); } void RetrieveItemsTask::onFinalSelectDone(KJob *job) { if (job->error()) { - kWarning() << job->errorString(); + qCWarning(IMAPRESOURCE_LOG) << job->errorString(); cancelTask(job->errorString()); return; } - KIMAP::SelectJob *select = qobject_cast(job); + KIMAP::SelectJob *select = qobject_cast(job); const QString mailBox = select->mailBox(); const int messageCount = select->messageCount(); @@ -235,7 +239,7 @@ //This is known to happen with Courier IMAP. A better solution would be to issue STATUS in case UIDNEXT is not delivered on select, //but that would have to be implemented in KIMAP first. See Bug 338186. if (nextUid < 0) { - kWarning() << "Server bug: Your IMAP Server delivered an invalid UIDNEXT value. This is a known problem with Courier IMAP."; + qCWarning(IMAPRESOURCE_LOG) << "Server bug: Your IMAP Server delivered an invalid UIDNEXT value. This is a known problem with Courier IMAP."; nextUid = 0; } @@ -250,12 +254,12 @@ // Get the current uid validity value and store it int oldUidValidity = 0; if (!col.hasAttribute("uidvalidity")) { - UidValidityAttribute* currentUidValidity = new UidValidityAttribute(uidValidity); + UidValidityAttribute *currentUidValidity = new UidValidityAttribute(uidValidity); col.addAttribute(currentUidValidity); modifyNeeded = true; } else { - UidValidityAttribute* currentUidValidity = - static_cast(col.attribute("uidvalidity" )); + UidValidityAttribute *currentUidValidity = + static_cast(col.attribute("uidvalidity")); oldUidValidity = currentUidValidity->uidValidity(); if (oldUidValidity != uidValidity) { currentUidValidity->setUidValidity(uidValidity); @@ -266,7 +270,7 @@ // Get the current uid next value and store it int oldNextUid = 0; if (nextUid > 0) { //this can fail with faulty servers that don't deliver uidnext - if (UidNextAttribute* currentNextUid = col.attribute()) { + if (UidNextAttribute *currentNextUid = col.attribute()) { oldNextUid = currentNextUid->uidNext(); if (oldNextUid != nextUid) { currentNextUid->setUidNext(nextUid); @@ -285,7 +289,7 @@ modifyNeeded = true; } else { Akonadi::CollectionFlagsAttribute *flagsAttribute = - static_cast(col.attribute("collectionflags")); + static_cast(col.attribute("collectionflags")); const QList oldFlags = flagsAttribute->flags(); if (oldFlags != flags) { flagsAttribute->setFlags(flags); @@ -317,7 +321,7 @@ } m_highestModseq = oldHighestModSeq; - if ( modifyNeeded ) { + if (modifyNeeded) { m_modifiedCollection = col; } @@ -325,17 +329,17 @@ scope.parts.clear(); scope.mode = KIMAP::FetchJob::FetchScope::FullHeaders; - if ( col.cachePolicy() - .localParts().contains( QLatin1String(Akonadi::MessagePart::Body) ) ) { + if (col.cachePolicy() + .localParts().contains(QLatin1String(Akonadi::MessagePart::Body))) { scope.mode = KIMAP::FetchJob::FetchScope::Full; } const qint64 realMessageCount = col.statistics().count(); - kDebug(5327) << "Starting message retrieval. Elapsed(ms): " << m_time.elapsed(); - kDebug(5327) << "MessageCount: " << messageCount << "Local message count: " << realMessageCount; - kDebug(5327) << "UidNext: " << nextUid << "Local UidNext: "<< oldNextUid; - kDebug(5327) << "HighestModSeq: " << highestModSeq << "Local HighestModSeq: "<< oldHighestModSeq; + qCDebug(IMAPRESOURCE_LOG) << "Starting message retrieval. Elapsed(ms): " << m_time.elapsed(); + qCDebug(IMAPRESOURCE_LOG) << "MessageCount: " << messageCount << "Local message count: " << realMessageCount; + qCDebug(IMAPRESOURCE_LOG) << "UidNext: " << nextUid << "Local UidNext: " << oldNextUid; + qCDebug(IMAPRESOURCE_LOG) << "HighestModSeq: " << highestModSeq << "Local HighestModSeq: " << oldHighestModSeq; /* * A synchronization has 3 mandatory steps: @@ -349,7 +353,7 @@ * have been deleted remotely, if we locally have messages that were not yet uploaded. * We cannot differentiate that from remotely removed messages, so we have to do a full flag * listing in that case. This can be optimized once we support QRESYNC and therefore have a way - * to determine wether messages have been removed. + * to determine whether messages have been removed. */ if (messageCount == 0) { @@ -357,27 +361,27 @@ //If no messages are present on the server, clear local cash and finish m_incremental = false; if (realMessageCount > 0) { - kDebug( 5327 ) << "No messages present so we are done, deleting local messages."; + qCDebug(IMAPRESOURCE_LOG) << "No messages present so we are done, deleting local messages."; itemsRetrieved(Akonadi::Item::List()); } else { - kDebug( 5327 ) << "No messages present so we are done"; + qCDebug(IMAPRESOURCE_LOG) << "No messages present so we are done"; } taskComplete(); - } else if (oldUidValidity != uidValidity) { + } else if (oldUidValidity != uidValidity || nextUid <= 0) { //If uidvalidity has changed our local cache is worthless and has to be refetched completely - if (oldUidValidity != 0) { - kDebug( 5327 ) << "UIDVALIDITY check failed (" << oldUidValidity << "|" - << uidValidity << ") refetching " << mailBox; - } else { - kDebug( 5327 ) << "Fetching complete mailbox " << mailBox; + if (oldUidValidity != 0 && oldUidValidity != uidValidity) { + qCDebug(IMAPRESOURCE_LOG) << "UIDVALIDITY check failed (" << oldUidValidity << "|" << uidValidity << ")"; } - + if (nextUid <= 0) { + qCDebug(IMAPRESOURCE_LOG) << "Invalid UIDNEXT"; + } + qCDebug(IMAPRESOURCE_LOG) << "Fetching complete mailbox " << mailBox; setTotalItems(messageCount); - retrieveItems(KIMAP::ImapSet(1, nextUid), scope, false, true); + retrieveItems(KIMAP::ImapSet(1, 0), scope, false, true); } else if (nextUid <= 0) { //This is a compatibilty codepath for Courier IMAP. It probably introduces problems, but at least it syncs. //Since we don't have uidnext available, we simply use the messagecount. This will miss simultaneously added/removed messages. - kDebug() << "Running courier imap compatiblity codepath"; + //qCDebug(IMAPRESOURCE_LOG) << "Running courier imap compatibility codepath"; if (messageCount > realMessageCount) { //Get new messages retrieveItems(KIMAP::ImapSet(realMessageCount + 1, messageCount), scope, false, false); @@ -404,7 +408,7 @@ //New messages are available, but we know no messages have been removed. //Fetch new messages, and then check for changed flags and removed messages //We can make an incremental update and use modseq. - kDebug( 5327 ) << "Incrementally fetching new messages: UidNext: " << nextUid << " Old UidNext: " << oldNextUid << " message count " << messageCount << realMessageCount; + qCDebug(IMAPRESOURCE_LOG) << "Incrementally fetching new messages: UidNext: " << nextUid << " Old UidNext: " << oldNextUid << " message count " << messageCount << realMessageCount; setTotalItems(qMax(1ll, messageCount - realMessageCount)); m_flagsChanged = !(highestModSeq == oldHighestModSeq); retrieveItems(KIMAP::ImapSet(qMax(1, oldNextUid), nextUid), scope, true, true); @@ -413,13 +417,13 @@ //New messages are available, but not enough to justify the difference between the local and remote message count. //This can be triggered if we i.e. clear the local cache, but the keep the annotations. //If we didn't catch this case, we end up inserting flags only for every missing message. - kWarning() << "Detected inconsistency in local cache, we're missing some messages. Server: " << messageCount << " Local: "<< realMessageCount; - kWarning() << "Refetching complete mailbox."; + qCWarning(IMAPRESOURCE_LOG) << "Detected inconsistency in local cache, we're missing some messages. Server: " << messageCount << " Local: " << realMessageCount; + qCWarning(IMAPRESOURCE_LOG) << "Refetching complete mailbox."; setTotalItems(messageCount); - retrieveItems(KIMAP::ImapSet(1, nextUid), scope, false, true); + retrieveItems(KIMAP::ImapSet(1, 0), scope, false, true); } else if (nextUid > oldNextUid) { //New messages are available. Fetch new messages, and then check for changed flags and removed messages - kDebug( 5327 ) << "Fetching new messages: UidNext: " << nextUid << " Old UidNext: " << oldNextUid; + qCDebug(IMAPRESOURCE_LOG) << "Fetching new messages: UidNext: " << nextUid << " Old UidNext: " << oldNextUid; setTotalItems(messageCount); retrieveItems(KIMAP::ImapSet(qMax(1, oldNextUid), nextUid), scope, false, true); } else if (messageCount == realMessageCount && oldNextUid == nextUid) { @@ -433,7 +437,7 @@ //Instead we only sync flags when new messages are available or removed and skip this step. //WARNING: This sacrifices consistency as we will not detect flag changes until a new message enters the mailbox. if (m_incremental && !serverSupportsCondstore()) { - kDebug(5327) << "Avoiding flag sync due to missing CONDSTORE support"; + qCDebug(IMAPRESOURCE_LOG) << "Avoiding flag sync due to missing CONDSTORE support"; taskComplete(); return; } @@ -443,8 +447,8 @@ //Error recovery: //We didn't detect any new messages based on the uid, but according to the message count there are new ones. //Our local cache is invalid and has to be refetched. - kWarning() << "Detected inconsistency in local cache, we're missing some messages. Server: " << messageCount << " Local: "<< realMessageCount; - kWarning() << "Refetching complete mailbox."; + qCWarning(IMAPRESOURCE_LOG) << "Detected inconsistency in local cache, we're missing some messages. Server: " << messageCount << " Local: " << realMessageCount; + qCWarning(IMAPRESOURCE_LOG) << "Refetching complete mailbox."; setTotalItems(messageCount); retrieveItems(KIMAP::ImapSet(1, nextUid), scope, false, true); } else { @@ -457,7 +461,7 @@ } } -void RetrieveItemsTask::retrieveItems(const KIMAP::ImapSet& set, const KIMAP::FetchJob::FetchScope &scope, bool incremental, bool uidBased) +void RetrieveItemsTask::retrieveItems(const KIMAP::ImapSet &set, const KIMAP::FetchJob::FetchScope &scope, bool incremental, bool uidBased) { Q_ASSERT(set.intervals().size() == 1); @@ -469,7 +473,7 @@ if (m_uidBasedFetch && set.intervals().size() == 1) { m_batchFetcher->setSearchUids(set.intervals().front()); } - m_batchFetcher->setProperty("alreadyFetched", set.intervals().first().begin()); + m_batchFetcher->setProperty("alreadyFetched", set.intervals().at(0).begin()); connect(m_batchFetcher, SIGNAL(itemsRetrieved(Akonadi::Item::List)), this, SLOT(onItemsRetrieved(Akonadi::Item::List))); connect(m_batchFetcher, SIGNAL(result(KJob*)), @@ -497,16 +501,16 @@ if (m_fetchedMissingBodies != -1) { const QString mailBox = mailBoxForCollection(collection()); m_fetchedMissingBodies += addedItems.count(); - emit status(Akonadi::AgentBase::Running, - i18nc( "@info:status", "Fetching missing mail bodies in %3: %1/%2", m_fetchedMissingBodies, m_messageUidsMissingBody.count(), mailBox)); + Q_EMIT status(Akonadi::AgentBase::Running, + i18nc("@info:status", "Fetching missing mail bodies in %3: %1/%2", m_fetchedMissingBodies, m_messageUidsMissingBody.count(), mailBox)); } } void RetrieveItemsTask::onRetrievalDone(KJob *job) { - m_batchFetcher = 0; + m_batchFetcher = Q_NULLPTR; if (job->error()) { - kWarning() << job->errorString(); + qCWarning(IMAPRESOURCE_LOG) << job->errorString(); cancelTask(job->errorString()); m_fetchedMissingBodies = -1; return; @@ -529,42 +533,42 @@ listFlagsForImapSet(KIMAP::ImapSet(1, alreadyFetchedBegin - 1)); } -void RetrieveItemsTask::listFlagsForImapSet(const KIMAP::ImapSet& set) +void RetrieveItemsTask::listFlagsForImapSet(const KIMAP::ImapSet &set) { - kDebug(5327) << "Listing flags " << set.intervals().first().begin() << set.intervals().first().end(); - kDebug(5327) << "Starting flag retrieval. Elapsed(ms): " << m_time.elapsed(); + qCDebug(IMAPRESOURCE_LOG) << "Listing flags " << set.intervals().at(0).begin() << set.intervals().at(0).end(); + qCDebug(IMAPRESOURCE_LOG) << "Starting flag retrieval. Elapsed(ms): " << m_time.elapsed(); + + KIMAP::FetchJob::FetchScope scope; + scope.parts.clear(); + scope.mode = KIMAP::FetchJob::FetchScope::Flags; + // Only use changeSince when doing incremental listings, + // otherwise we would overwrite our local data with an incomplete dataset + if (m_incremental && serverSupportsCondstore()) { + scope.changedSince = m_highestModseq; + if (!m_flagsChanged) { + qCDebug(IMAPRESOURCE_LOG) << "No flag changes."; + taskComplete(); + return; + } + } - KIMAP::FetchJob::FetchScope scope; - scope.parts.clear(); - scope.mode = KIMAP::FetchJob::FetchScope::Flags; - // Only use changeSince when doing incremental listings, - // otherwise we would overwrite our local data with an incomplete dataset - if(m_incremental && serverSupportsCondstore()) { - scope.changedSince = m_highestModseq; - if (!m_flagsChanged) { - kDebug(5327) << "No flag changes."; - taskComplete(); - return; - } - } - - m_batchFetcher = createBatchFetcher(resourceState()->messageHelper(), set, scope, 10 * batchSize(), m_session); - m_batchFetcher->setUidBased(m_uidBasedFetch); - if (m_uidBasedFetch && scope.changedSince == 0 && set.intervals().size() == 1) { - m_batchFetcher->setSearchUids(set.intervals().front()); - } - connect(m_batchFetcher, SIGNAL(itemsRetrieved(Akonadi::Item::List)), - this, SLOT(onItemsRetrieved(Akonadi::Item::List))); - connect(m_batchFetcher, SIGNAL(result(KJob*)), - this, SLOT(onFlagsFetchDone(KJob*))); - m_batchFetcher->start(); + m_batchFetcher = createBatchFetcher(resourceState()->messageHelper(), set, scope, 10 * batchSize(), m_session); + m_batchFetcher->setUidBased(m_uidBasedFetch); + if (m_uidBasedFetch && scope.changedSince == 0 && set.intervals().size() == 1) { + m_batchFetcher->setSearchUids(set.intervals().front()); + } + connect(m_batchFetcher, SIGNAL(itemsRetrieved(Akonadi::Item::List)), + this, SLOT(onItemsRetrieved(Akonadi::Item::List))); + connect(m_batchFetcher, SIGNAL(result(KJob*)), + this, SLOT(onFlagsFetchDone(KJob*))); + m_batchFetcher->start(); } void RetrieveItemsTask::onFlagsFetchDone(KJob *job) { - m_batchFetcher = 0; - if ( job->error() ) { - kWarning() << job->errorString(); + m_batchFetcher = Q_NULLPTR; + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << job->errorString(); cancelTask(job->errorString()); } else { taskComplete(); @@ -574,7 +578,7 @@ void RetrieveItemsTask::taskComplete() { if (m_modifiedCollection.isValid()) { - kDebug(5327) << "Applying collection changes"; + qCDebug(IMAPRESOURCE_LOG) << "Applying collection changes"; applyCollectionChanges(m_modifiedCollection); } if (m_incremental) { @@ -583,8 +587,7 @@ // Akonadi knows we did incremental fetch that came up with no changes itemsRetrievedIncremental(Akonadi::Item::List(), Akonadi::Item::List()); } - kDebug(5327) << "Retrieval complete. Elapsed(ms): " << m_time.elapsed(); + qCDebug(IMAPRESOURCE_LOG) << "Retrieval complete. Elapsed(ms): " << m_time.elapsed(); itemsRetrievalDone(); } -#include "retrieveitemstask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/retrieveitemstask.h kdepim-runtime-15.08.0/resources/imap/retrieveitemstask.h --- kdepim-runtime-4.14.6/resources/imap/retrieveitemstask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/retrieveitemstask.h 2015-08-10 21:01:02.000000000 +0000 @@ -28,46 +28,47 @@ #include "resourcetask.h" class BatchFetcher; -namespace Akonadi { - class Session; +namespace Akonadi +{ +class Session; } class RetrieveItemsTask : public ResourceTask { - Q_OBJECT + Q_OBJECT public: - explicit RetrieveItemsTask(ResourceStateInterface::Ptr resource, QObject *parent = 0); + explicit RetrieveItemsTask(ResourceStateInterface::Ptr resource, QObject *parent = Q_NULLPTR); virtual ~RetrieveItemsTask(); void setFetchMissingItemBodies(bool enabled); -public slots: +public Q_SLOTS: void onFetchItemsWithoutBodiesDone(const QList &items); void onReadyForNextBatch(int size); -private slots: +private Q_SLOTS: void fetchItemsWithoutBodiesDone(KJob *job); void onPreExpungeSelectDone(KJob *job); void onExpungeDone(KJob *job); void onFinalSelectDone(KJob *job); void onItemsRetrieved(const Akonadi::Item::List &addedItems); void onRetrievalDone(KJob *job); - void onFlagsFetchDone( KJob *job ); + void onFlagsFetchDone(KJob *job); protected: - virtual void doStart(KIMAP::Session *session); + void doStart(KIMAP::Session *session) Q_DECL_OVERRIDE; - virtual BatchFetcher* createBatchFetcher(MessageHelper::Ptr messageHelper, const KIMAP::ImapSet &set, - const KIMAP::FetchJob::FetchScope &scope, int batchSize, - KIMAP::Session *session); + virtual BatchFetcher *createBatchFetcher(MessageHelper::Ptr messageHelper, const KIMAP::ImapSet &set, + const KIMAP::FetchJob::FetchScope &scope, int batchSize, + KIMAP::Session *session); private: void startRetrievalTasks(); void triggerPreExpungeSelect(const QString &mailBox); void triggerExpunge(const QString &mailBox); void triggerFinalSelect(const QString &mailBox); - void retrieveItems(const KIMAP::ImapSet& set, const KIMAP::FetchJob::FetchScope &scope, bool incremental = false, bool uidBased = false); - void listFlagsForImapSet(const KIMAP::ImapSet& set); + void retrieveItems(const KIMAP::ImapSet &set, const KIMAP::FetchJob::FetchScope &scope, bool incremental = false, bool uidBased = false); + void listFlagsForImapSet(const KIMAP::ImapSet &set); void taskComplete(); KIMAP::Session *m_session; diff -Nru kdepim-runtime-4.14.6/resources/imap/retrieveitemtask.cpp kdepim-runtime-15.08.0/resources/imap/retrieveitemtask.cpp --- kdepim-runtime-4.14.6/resources/imap/retrieveitemtask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/retrieveitemtask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,15 +22,17 @@ #include "retrieveitemtask.h" #include "messagehelper.h" -#include -#include +#include "imapresource_debug.h" +#include "imapresource_debug.h" -#include +#include + +#include #include #include -RetrieveItemTask::RetrieveItemTask( ResourceStateInterface::Ptr resource, QObject *parent ) - : ResourceTask( CancelIfNoSession, resource, parent ), m_session( 0 ), m_uid( 0 ), m_messageReceived( false ) +RetrieveItemTask::RetrieveItemTask(ResourceStateInterface::Ptr resource, QObject *parent) + : ResourceTask(CancelIfNoSession, resource, parent), m_session(Q_NULLPTR), m_uid(0), m_messageReceived(false) { } @@ -39,110 +41,107 @@ { } -void RetrieveItemTask::doStart( KIMAP::Session *session ) +void RetrieveItemTask::doStart(KIMAP::Session *session) { - m_session = session; + m_session = session; - const QString mailBox = mailBoxForCollection( item().parentCollection() ); - m_uid = item().remoteId().toLongLong(); + const QString mailBox = mailBoxForCollection(item().parentCollection()); + m_uid = item().remoteId().toLongLong(); - if ( m_uid == 0 ) { - kWarning() << "Remote id is " << item().remoteId(); - cancelTask( i18n("Remote id is empty or invalid") ); - return; - } - - if ( session->selectedMailBox() != mailBox ) { - KIMAP::SelectJob *select = new KIMAP::SelectJob( m_session ); - select->setMailBox( mailBox ); - connect( select, SIGNAL(result(KJob*)), - this, SLOT(onSelectDone(KJob*)) ); - select->start(); - } else { - triggerFetchJob(); - } -} - -void RetrieveItemTask::onSelectDone( KJob *job ) -{ - if ( job->error() ) { - cancelTask( job->errorString() ); - } else { - triggerFetchJob(); - } + if (m_uid == 0) { + qCWarning(IMAPRESOURCE_LOG) << "Remote id is " << item().remoteId(); + cancelTask(i18n("Remote id is empty or invalid")); + return; + } + + if (session->selectedMailBox() != mailBox) { + KIMAP::SelectJob *select = new KIMAP::SelectJob(m_session); + select->setMailBox(mailBox); + connect(select, SIGNAL(result(KJob*)), + this, SLOT(onSelectDone(KJob*))); + select->start(); + } else { + triggerFetchJob(); + } +} + +void RetrieveItemTask::onSelectDone(KJob *job) +{ + if (job->error()) { + cancelTask(job->errorString()); + } else { + triggerFetchJob(); + } } void RetrieveItemTask::triggerFetchJob() { - KIMAP::FetchJob *fetch = new KIMAP::FetchJob( m_session ); - KIMAP::FetchJob::FetchScope scope; - fetch->setUidBased( true ); - fetch->setSequenceSet( KIMAP::ImapSet( m_uid ) ); - scope.parts.clear();// = parts.toList(); - scope.mode = KIMAP::FetchJob::FetchScope::Content; - fetch->setScope( scope ); - connect( fetch, SIGNAL(messagesReceived(QString, - QMap, - QMap, - QMap)), - this, SLOT(onMessagesReceived(QString, - QMap, - QMap, - QMap)) ); - //TODO: Handle parts retrieval - //connect( fetch, SIGNAL(partsReceived(QString,QMap,QMap)), - // this, SLOT(onPartsReceived(QString,QMap,QMap)) ); - connect( fetch, SIGNAL(result(KJob*)), - this, SLOT(onContentFetchDone(KJob*)) ); - fetch->start(); -} - -void RetrieveItemTask::onMessagesReceived( const QString &mailBox, - const QMap &uids, - const QMap &attrs, - const QMap &messages ) -{ - Q_UNUSED( mailBox ); - - KIMAP::FetchJob *fetch = qobject_cast( sender() ); - Q_ASSERT( fetch!=0 ); - Q_ASSERT( uids.size()==1 ); - Q_ASSERT( messages.size()==1 ); - - Akonadi::Item i = item(); - - kDebug( 5327 ) << "MESSAGE from Imap server" << item().remoteId(); - Q_ASSERT( item().isValid() ); - - const qint64 number = uids.keys().first(); - bool ok; - const Akonadi::Item remoteItem = resourceState()->messageHelper()->createItemFromMessage(messages[number], uids[number], 0, attrs.values(number), QList(), fetch->scope(), ok); - if (!ok) { - kWarning() << "Failed to retrieve message " << uids[number]; - cancelTask( i18n( "No message retrieved, failed to read the message." ) ); - return; - } - i.setMimeType(remoteItem.mimeType()); - i.setPayload(remoteItem.payload()); - foreach (const QByteArray &flag, remoteItem.flags()) { - i.setFlag(flag); - } - - kDebug( 5327 ) << "Has Payload: " << i.hasPayload(); - - m_messageReceived = true; - itemRetrieved( i ); -} - -void RetrieveItemTask::onContentFetchDone( KJob *job ) -{ - if ( job->error() ) { - cancelTask( job->errorString() ); - } else if ( !m_messageReceived ) { - cancelTask( i18n( "No message retrieved, server reply was empty." ) ); - } + KIMAP::FetchJob *fetch = new KIMAP::FetchJob(m_session); + KIMAP::FetchJob::FetchScope scope; + fetch->setUidBased(true); + fetch->setSequenceSet(KIMAP::ImapSet(m_uid)); + scope.parts.clear();// = parts.toList(); + scope.mode = KIMAP::FetchJob::FetchScope::Content; + fetch->setScope(scope); + connect(fetch, SIGNAL(messagesReceived(QString, + QMap, + QMap, + QMap)), + this, SLOT(onMessagesReceived(QString, + QMap, + QMap, + QMap))); + //TODO: Handle parts retrieval + //connect( fetch, SIGNAL(partsReceived(QString,QMap,QMap)), + // this, SLOT(onPartsReceived(QString,QMap,QMap)) ); + connect(fetch, SIGNAL(result(KJob*)), + this, SLOT(onContentFetchDone(KJob*))); + fetch->start(); +} + +void RetrieveItemTask::onMessagesReceived(const QString &mailBox, + const QMap &uids, + const QMap &attrs, + const QMap &messages) +{ + Q_UNUSED(mailBox); + + KIMAP::FetchJob *fetch = qobject_cast(sender()); + Q_ASSERT(fetch != 0); + Q_ASSERT(uids.size() == 1); + Q_ASSERT(messages.size() == 1); + + Akonadi::Item i = item(); + + qCDebug(IMAPRESOURCE_LOG) << "MESSAGE from Imap server" << item().remoteId(); + Q_ASSERT(item().isValid()); + + const qint64 number = uids.cbegin().key(); + bool ok; + const Akonadi::Item remoteItem = resourceState()->messageHelper()->createItemFromMessage(messages[number], uids[number], 0, attrs.values(number), QList(), fetch->scope(), ok); + if (!ok) { + qCWarning(IMAPRESOURCE_LOG) << "Failed to retrieve message " << uids[number]; + cancelTask(i18n("No message retrieved, failed to read the message.")); + return; + } + i.setMimeType(remoteItem.mimeType()); + i.setPayload(remoteItem.payload()); + foreach (const QByteArray &flag, remoteItem.flags()) { + i.setFlag(flag); + } + + qCDebug(IMAPRESOURCE_LOG) << "Has Payload: " << i.hasPayload(); + + m_messageReceived = true; + itemRetrieved(i); +} + +void RetrieveItemTask::onContentFetchDone(KJob *job) +{ + if (job->error()) { + cancelTask(job->errorString()); + } else if (!m_messageReceived) { + cancelTask(i18n("No message retrieved, server reply was empty.")); + } } - - - diff -Nru kdepim-runtime-4.14.6/resources/imap/retrieveitemtask.h kdepim-runtime-15.08.0/resources/imap/retrieveitemtask.h --- kdepim-runtime-4.14.6/resources/imap/retrieveitemtask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/retrieveitemtask.h 2015-08-10 21:01:02.000000000 +0000 @@ -28,29 +28,29 @@ class RetrieveItemTask : public ResourceTask { - Q_OBJECT + Q_OBJECT public: - explicit RetrieveItemTask( ResourceStateInterface::Ptr resource, QObject *parent = 0 ); - virtual ~RetrieveItemTask(); + explicit RetrieveItemTask(ResourceStateInterface::Ptr resource, QObject *parent = Q_NULLPTR); + virtual ~RetrieveItemTask(); -private slots: - void onSelectDone( KJob *job ); - void onMessagesReceived( const QString &mailBox, - const QMap &uids, - const QMap &attrs, - const QMap &messages ); - void onContentFetchDone( KJob *job ); +private Q_SLOTS: + void onSelectDone(KJob *job); + void onMessagesReceived(const QString &mailBox, + const QMap &uids, + const QMap &attrs, + const QMap &messages); + void onContentFetchDone(KJob *job); protected: - virtual void doStart( KIMAP::Session *session ); + void doStart(KIMAP::Session *session) Q_DECL_OVERRIDE; private: - void triggerFetchJob(); + void triggerFetchJob(); - KIMAP::Session *m_session; - qint64 m_uid; - bool m_messageReceived; + KIMAP::Session *m_session; + qint64 m_uid; + bool m_messageReceived; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/searchtask.cpp kdepim-runtime-15.08.0/resources/imap/searchtask.cpp --- kdepim-runtime-4.14.6/resources/imap/searchtask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/searchtask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,15 +23,16 @@ #include #include #include -#include +#include #include #include +#include "imapresource_debug.h" -Q_DECLARE_METATYPE( KIMAP::Session* ) +Q_DECLARE_METATYPE(KIMAP::Session *) -SearchTask::SearchTask( ResourceStateInterface::Ptr state, const QString &query, QObject *parent) - : ResourceTask( ResourceTask::DeferIfNoSession, state, parent) - , m_query( query ) +SearchTask::SearchTask(ResourceStateInterface::Ptr state, const QString &query, QObject *parent) + : ResourceTask(ResourceTask::DeferIfNoSession, state, parent) + , m_query(query) { } @@ -39,36 +40,37 @@ { } -void SearchTask::doStart( KIMAP::Session *session ) +void SearchTask::doStart(KIMAP::Session *session) { - kDebug() << collection().remoteId(); + qCDebug(IMAPRESOURCE_LOG) << collection().remoteId(); - const QString mailbox = mailBoxForCollection( collection() ); - if ( session->selectedMailBox() == mailbox ) { - doSearch( session ); + const QString mailbox = mailBoxForCollection(collection()); + if (session->selectedMailBox() == mailbox) { + doSearch(session); return; } - KIMAP::SelectJob *select = new KIMAP::SelectJob( session ); - select->setMailBox( mailbox ); - connect( select, SIGNAL(finished(KJob*)), - this, SLOT(onSelectDone(KJob*)) ); + KIMAP::SelectJob *select = new KIMAP::SelectJob(session); + select->setMailBox(mailbox); + connect(select, &KJob::finished, + this, &SearchTask::onSelectDone); select->start(); } -void SearchTask::onSelectDone( KJob *job ) +void SearchTask::onSelectDone(KJob *job) { - if ( job->error() ) { - searchFinished( QVector() ); - cancelTask( job->errorText() ); + if (job->error()) { + searchFinished(QVector()); + cancelTask(job->errorText()); return; } - doSearch( qobject_cast( job )->session() ); + doSearch(qobject_cast(job)->session()); } -static KIMAP::Term::Relation mapRelation(Akonadi::SearchTerm::Relation relation) { - if (relation == Akonadi::SearchTerm::RelAnd){ +static KIMAP::Term::Relation mapRelation(Akonadi::SearchTerm::Relation relation) +{ + if (relation == Akonadi::SearchTerm::RelAnd) { return KIMAP::Term::And; } return KIMAP::Term::Or; @@ -88,136 +90,136 @@ } else { const Akonadi::EmailSearchTerm::EmailSearchField field = Akonadi::EmailSearchTerm::fromKey(term.key()); switch (field) { - case Akonadi::EmailSearchTerm::Message: - return KIMAP::Term(KIMAP::Term::Text, term.value().toString()).setNegated(term.isNegated()); - case Akonadi::EmailSearchTerm::Body: - return KIMAP::Term(KIMAP::Term::Body, term.value().toString()).setNegated(term.isNegated()); - case Akonadi::EmailSearchTerm::Headers: - //FIXME + case Akonadi::EmailSearchTerm::Message: + return KIMAP::Term(KIMAP::Term::Text, term.value().toString()).setNegated(term.isNegated()); + case Akonadi::EmailSearchTerm::Body: + return KIMAP::Term(KIMAP::Term::Body, term.value().toString()).setNegated(term.isNegated()); + case Akonadi::EmailSearchTerm::Headers: + //FIXME // return KIMAP::Term(KIMAP::Term::Header, term.value()).setNegated(term.isNegated()); + break; + case Akonadi::EmailSearchTerm::ByteSize: { + int value = term.value().toInt(); + switch (term.condition()) { + case Akonadi::SearchTerm::CondGreaterOrEqual: + value--; + case Akonadi::SearchTerm::CondGreaterThan: + return KIMAP::Term(KIMAP::Term::Larger, value).setNegated(term.isNegated()); + case Akonadi::SearchTerm::CondLessOrEqual: + value++; + case Akonadi::SearchTerm::CondLessThan: + return KIMAP::Term(KIMAP::Term::Smaller, value).setNegated(term.isNegated()); + case Akonadi::SearchTerm::CondEqual: + return KIMAP::Term(KIMAP::Term::And, QVector() << KIMAP::Term(KIMAP::Term::Smaller, value + 1) << KIMAP::Term(KIMAP::Term::Larger, value + 1)).setNegated(term.isNegated()); + case Akonadi::SearchTerm::CondContains: + qCDebug(IMAPRESOURCE_LOG) << " invalid condition for ByteSize"; break; - case Akonadi::EmailSearchTerm::ByteSize: { - int value = term.value().toInt(); - switch (term.condition()) { - case Akonadi::SearchTerm::CondGreaterOrEqual: - value--; - case Akonadi::SearchTerm::CondGreaterThan: - return KIMAP::Term(KIMAP::Term::Larger, value).setNegated(term.isNegated()); - case Akonadi::SearchTerm::CondLessOrEqual: - value++; - case Akonadi::SearchTerm::CondLessThan: - return KIMAP::Term(KIMAP::Term::Smaller, value).setNegated(term.isNegated()); - case Akonadi::SearchTerm::CondEqual: - return KIMAP::Term(KIMAP::Term::And, QVector() << KIMAP::Term(KIMAP::Term::Smaller, value + 1) << KIMAP::Term(KIMAP::Term::Larger, value + 1)).setNegated(term.isNegated()); - case Akonadi::SearchTerm::CondContains: - kDebug()<<" invalid condition for ByteSize"; - break; - } } + } + break; + case Akonadi::EmailSearchTerm::HeaderOnlyDate: + case Akonadi::EmailSearchTerm::HeaderDate: { + QDate value = term.value().toDateTime().date(); + switch (term.condition()) { + case Akonadi::SearchTerm::CondGreaterOrEqual: + value = value.addDays(-1); + case Akonadi::SearchTerm::CondGreaterThan: + return KIMAP::Term(KIMAP::Term::SentSince, value).setNegated(term.isNegated()); + case Akonadi::SearchTerm::CondLessOrEqual: + value = value.addDays(1); + case Akonadi::SearchTerm::CondLessThan: + return KIMAP::Term(KIMAP::Term::SentBefore, value).setNegated(term.isNegated()); + case Akonadi::SearchTerm::CondEqual: + return KIMAP::Term(KIMAP::Term::SentOn, value).setNegated(term.isNegated()); + case Akonadi::SearchTerm::CondContains: + qCDebug(IMAPRESOURCE_LOG) << " invalid condition for Date"; break; - case Akonadi::EmailSearchTerm::HeaderOnlyDate: - case Akonadi::EmailSearchTerm::HeaderDate: { - QDate value = term.value().toDateTime().date(); - switch (term.condition()) { - case Akonadi::SearchTerm::CondGreaterOrEqual: - value = value.addDays(-1); - case Akonadi::SearchTerm::CondGreaterThan: - return KIMAP::Term(KIMAP::Term::SentSince, value).setNegated(term.isNegated()); - case Akonadi::SearchTerm::CondLessOrEqual: - value = value.addDays(1); - case Akonadi::SearchTerm::CondLessThan: - return KIMAP::Term(KIMAP::Term::SentBefore, value).setNegated(term.isNegated()); - case Akonadi::SearchTerm::CondEqual: - return KIMAP::Term(KIMAP::Term::SentOn, value).setNegated(term.isNegated()); - case Akonadi::SearchTerm::CondContains: - kDebug()<<" invalid condition for Date"; - break; - } - } - case Akonadi::EmailSearchTerm::Subject: - return KIMAP::Term(KIMAP::Term::Subject, term.value().toString()).setNegated(term.isNegated()); - case Akonadi::EmailSearchTerm::HeaderFrom: - return KIMAP::Term(KIMAP::Term::From, term.value().toString()).setNegated(term.isNegated()); - case Akonadi::EmailSearchTerm::HeaderTo: - return KIMAP::Term(KIMAP::Term::To, term.value().toString()).setNegated(term.isNegated()); - case Akonadi::EmailSearchTerm::HeaderCC: - return KIMAP::Term(KIMAP::Term::Cc, term.value().toString()).setNegated(term.isNegated()); - case Akonadi::EmailSearchTerm::HeaderBCC: - return KIMAP::Term(KIMAP::Term::Bcc, term.value().toString()).setNegated(term.isNegated()); - case Akonadi::EmailSearchTerm::MessageStatus: - if (term.value().toString() == QString::fromLatin1(Akonadi::MessageFlags::Flagged)) { - return KIMAP::Term(KIMAP::Term::Flagged).setNegated(term.isNegated()); - } - if (term.value().toString() == QString::fromLatin1(Akonadi::MessageFlags::Deleted)) { - return KIMAP::Term(KIMAP::Term::Deleted).setNegated(term.isNegated()); - } - if (term.value().toString() == QString::fromLatin1(Akonadi::MessageFlags::Replied)) { - return KIMAP::Term(KIMAP::Term::Answered).setNegated(term.isNegated()); - } - if (term.value().toString() == QString::fromLatin1(Akonadi::MessageFlags::Seen)) { - return KIMAP::Term(KIMAP::Term::Seen).setNegated(term.isNegated()); - } - break; - case Akonadi::EmailSearchTerm::MessageTag: - break; - case Akonadi::EmailSearchTerm::HeaderReplyTo: - break; - case Akonadi::EmailSearchTerm::HeaderOrganization: - break; - case Akonadi::EmailSearchTerm::HeaderListId: - break; - case Akonadi::EmailSearchTerm::HeaderResentFrom: - break; - case Akonadi::EmailSearchTerm::HeaderXLoop: - break; - case Akonadi::EmailSearchTerm::HeaderXMailingList: - break; - case Akonadi::EmailSearchTerm::HeaderXSpamFlag: - break; - case Akonadi::EmailSearchTerm::Unknown: - default: - kWarning() << "unknown term " << term.key(); + } + } + case Akonadi::EmailSearchTerm::Subject: + return KIMAP::Term(KIMAP::Term::Subject, term.value().toString()).setNegated(term.isNegated()); + case Akonadi::EmailSearchTerm::HeaderFrom: + return KIMAP::Term(KIMAP::Term::From, term.value().toString()).setNegated(term.isNegated()); + case Akonadi::EmailSearchTerm::HeaderTo: + return KIMAP::Term(KIMAP::Term::To, term.value().toString()).setNegated(term.isNegated()); + case Akonadi::EmailSearchTerm::HeaderCC: + return KIMAP::Term(KIMAP::Term::Cc, term.value().toString()).setNegated(term.isNegated()); + case Akonadi::EmailSearchTerm::HeaderBCC: + return KIMAP::Term(KIMAP::Term::Bcc, term.value().toString()).setNegated(term.isNegated()); + case Akonadi::EmailSearchTerm::MessageStatus: + if (term.value().toString() == QString::fromLatin1(Akonadi::MessageFlags::Flagged)) { + return KIMAP::Term(KIMAP::Term::Flagged).setNegated(term.isNegated()); + } + if (term.value().toString() == QString::fromLatin1(Akonadi::MessageFlags::Deleted)) { + return KIMAP::Term(KIMAP::Term::Deleted).setNegated(term.isNegated()); + } + if (term.value().toString() == QString::fromLatin1(Akonadi::MessageFlags::Replied)) { + return KIMAP::Term(KIMAP::Term::Answered).setNegated(term.isNegated()); + } + if (term.value().toString() == QString::fromLatin1(Akonadi::MessageFlags::Seen)) { + return KIMAP::Term(KIMAP::Term::Seen).setNegated(term.isNegated()); + } + break; + case Akonadi::EmailSearchTerm::MessageTag: + break; + case Akonadi::EmailSearchTerm::HeaderReplyTo: + break; + case Akonadi::EmailSearchTerm::HeaderOrganization: + break; + case Akonadi::EmailSearchTerm::HeaderListId: + break; + case Akonadi::EmailSearchTerm::HeaderResentFrom: + break; + case Akonadi::EmailSearchTerm::HeaderXLoop: + break; + case Akonadi::EmailSearchTerm::HeaderXMailingList: + break; + case Akonadi::EmailSearchTerm::HeaderXSpamFlag: + break; + case Akonadi::EmailSearchTerm::Unknown: + default: + qCWarning(IMAPRESOURCE_LOG) << "unknown term " << term.key(); } } return KIMAP::Term(); } -void SearchTask::doSearch( KIMAP::Session *session ) +void SearchTask::doSearch(KIMAP::Session *session) { - kDebug() << m_query; + qCDebug(IMAPRESOURCE_LOG) << m_query; - Akonadi::SearchQuery query = Akonadi::SearchQuery::fromJSON( m_query.toLatin1() ); - KIMAP::SearchJob *searchJob = new KIMAP::SearchJob( session ); - searchJob->setUidBased( true ); + Akonadi::SearchQuery query = Akonadi::SearchQuery::fromJSON(m_query.toLatin1()); + KIMAP::SearchJob *searchJob = new KIMAP::SearchJob(session); + searchJob->setUidBased(true); KIMAP::Term term = recursiveEmailTermMapping(query.term()); if (term.isNull()) { - kWarning() << "failed to translate query " << m_query; - searchFinished( QVector() ); - cancelTask( "Invalid search" ); + qCWarning(IMAPRESOURCE_LOG) << "failed to translate query " << m_query; + searchFinished(QVector()); + cancelTask("Invalid search"); return; } searchJob->setTerm(term); - connect( searchJob, SIGNAL(finished(KJob*)), - this, SLOT(onSearchDone(KJob*)) ); + connect(searchJob, &KJob::finished, + this, &SearchTask::onSearchDone); searchJob->start(); } -void SearchTask::onSearchDone( KJob* job ) +void SearchTask::onSearchDone(KJob *job) { - if ( job->error() ) { - kWarning() << "Failed to execute search " << job->errorString(); - kDebug() << m_query; - searchFinished( QVector() ); - cancelTask( job->errorString() ); + if (job->error()) { + qCWarning(IMAPRESOURCE_LOG) << "Failed to execute search " << job->errorString(); + qCDebug(IMAPRESOURCE_LOG) << m_query; + searchFinished(QVector()); + cancelTask(job->errorString()); return; } - KIMAP::SearchJob *searchJob = qobject_cast( job ); + KIMAP::SearchJob *searchJob = qobject_cast(job); const QList result = searchJob->results(); - kDebug() << result.count() << "matches"; + qCDebug(IMAPRESOURCE_LOG) << result.count() << "matches"; - searchFinished( result.toVector() ); + searchFinished(result.toVector()); taskDone(); } diff -Nru kdepim-runtime-4.14.6/resources/imap/searchtask.h kdepim-runtime-15.08.0/resources/imap/searchtask.h --- kdepim-runtime-4.14.6/resources/imap/searchtask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/searchtask.h 2015-08-10 21:01:02.000000000 +0000 @@ -27,19 +27,19 @@ class SearchTask : public ResourceTask { Q_OBJECT - public: - SearchTask( ResourceStateInterface::Ptr state, const QString &query, QObject *parent ); +public: + SearchTask(ResourceStateInterface::Ptr state, const QString &query, QObject *parent); ~SearchTask(); - protected: - virtual void doStart( KIMAP::Session *session ); +protected: + void doStart(KIMAP::Session *session) Q_DECL_OVERRIDE; - private Q_SLOTS: - void onSelectDone( KJob *job ); - void onSearchDone( KJob *job ); +private Q_SLOTS: + void onSelectDone(KJob *job); + void onSearchDone(KJob *job); - private: - void doSearch( KIMAP::Session *session ); +private: + void doSearch(KIMAP::Session *session); QString m_query; diff -Nru kdepim-runtime-4.14.6/resources/imap/serverinfodialog.cpp kdepim-runtime-15.08.0/resources/imap/serverinfodialog.cpp --- kdepim-runtime-4.14.6/resources/imap/serverinfodialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/serverinfodialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,21 +23,31 @@ #include "ui_serverinfo.h" #include +#include +#include +#include +#include ServerInfoDialog::ServerInfoDialog(ImapResourceBase *parentResource, QWidget *parent) - : KDialog(parent) + : QDialog(parent) { - setCaption( - i18nc( "@title:window Dialog title for dialog showing information about a server", - "Server Info" ) ); - setButtons( KDialog::Close ); - setAttribute( Qt::WA_DeleteOnClose ); + setWindowTitle( + i18nc("@title:window Dialog title for dialog showing information about a server", + "Server Info")); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + QWidget *w = new QWidget; + mainLayout->addWidget(w); + connect(buttonBox, &QDialogButtonBox::accepted, this, &ServerInfoDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &ServerInfoDialog::reject); + setAttribute(Qt::WA_DeleteOnClose); mServerInfoWidget = new Ui::ServerInfo(); - mServerInfoWidget->setupUi( this ); - setMainWidget( mServerInfoWidget->serverInfo ); + mServerInfoWidget->setupUi(w); + mainLayout->addWidget(buttonBox); mServerInfoWidget->serverInfo->setPlainText( - parentResource->serverCapabilities().join( QLatin1String( "\n" ) ) ); + parentResource->serverCapabilities().join(QLatin1String("\n"))); } ServerInfoDialog::~ServerInfoDialog() diff -Nru kdepim-runtime-4.14.6/resources/imap/serverinfodialog.h kdepim-runtime-15.08.0/resources/imap/serverinfodialog.h --- kdepim-runtime-4.14.6/resources/imap/serverinfodialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/serverinfodialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -21,14 +21,15 @@ #ifndef SERVERINFODIALOG_H #define SERVERINFODIALOG_H -#include +#include class ImapResourceBase; -namespace Ui { +namespace Ui +{ class ServerInfo; } -class ServerInfoDialog : public KDialog +class ServerInfoDialog : public QDialog { Q_OBJECT public: diff -Nru kdepim-runtime-4.14.6/resources/imap/sessionpool.cpp kdepim-runtime-15.08.0/resources/imap/sessionpool.cpp --- kdepim-runtime-4.14.6/resources/imap/sessionpool.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/sessionpool.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,8 +24,8 @@ #include #include -#include -#include +#include "imapresource_debug.h" +#include #include #include @@ -36,498 +36,520 @@ qint64 SessionPool::m_requestCounter = 0; -SessionPool::SessionPool( int maxPoolSize, QObject *parent ) - : QObject( parent ), - m_maxPoolSize( maxPoolSize ), - m_account( 0 ), - m_passwordRequester( 0 ), - m_initialConnectDone( false ), - m_pendingInitialSession( 0 ) +SessionPool::SessionPool(int maxPoolSize, QObject *parent) + : QObject(parent), + m_maxPoolSize(maxPoolSize), + m_account(Q_NULLPTR), + m_passwordRequester(Q_NULLPTR), + m_initialConnectDone(false), + m_pendingInitialSession(Q_NULLPTR) { } SessionPool::~SessionPool() { - disconnect( CloseSession ); + disconnect(CloseSession); } PasswordRequesterInterface *SessionPool::passwordRequester() const { - return m_passwordRequester; + return m_passwordRequester; } -void SessionPool::setPasswordRequester( PasswordRequesterInterface *requester ) +void SessionPool::setPasswordRequester(PasswordRequesterInterface *requester) { - delete m_passwordRequester; + delete m_passwordRequester; - m_passwordRequester = requester; - m_passwordRequester->setParent( this ); - QObject::connect( m_passwordRequester, SIGNAL(done(int,QString)), - this, SLOT(onPasswordRequestDone(int,QString)) ); + m_passwordRequester = requester; + m_passwordRequester->setParent(this); + QObject::connect(m_passwordRequester, SIGNAL(done(int,QString)), + this, SLOT(onPasswordRequestDone(int,QString))); } void SessionPool::cancelPasswordRequests() { - m_passwordRequester->cancelPasswordRequests(); + m_passwordRequester->cancelPasswordRequests(); } KIMAP::SessionUiProxy::Ptr SessionPool::sessionUiProxy() const { - return m_sessionUiProxy; + return m_sessionUiProxy; } -void SessionPool::setSessionUiProxy( KIMAP::SessionUiProxy::Ptr proxy ) +void SessionPool::setSessionUiProxy(KIMAP::SessionUiProxy::Ptr proxy) { - m_sessionUiProxy = proxy; + m_sessionUiProxy = proxy; } bool SessionPool::isConnected() const { - return m_initialConnectDone; + return m_initialConnectDone; +} + +bool SessionPool::connect(ImapAccount *account) +{ + if (m_account) { + return false; + } + + m_account = account; + if (m_account->authenticationMode() == KIMAP::LoginJob::GSSAPI) { + // for GSSAPI we don't have to ask for username/password, because it uses session wide tickets + QMetaObject::invokeMethod(this, "onPasswordRequestDone", Qt::QueuedConnection, + Q_ARG(int, PasswordRequesterInterface::PasswordRetrieved), + Q_ARG(QString, QString())); + } else { + m_passwordRequester->requestPassword(); + } + + return true; } -bool SessionPool::connect( ImapAccount *account ) +void SessionPool::disconnect(SessionTermination termination) { - if ( m_account ) { - return false; - } - - m_account = account; - if ( m_account->authenticationMode() == KIMAP::LoginJob::GSSAPI ) { - // for GSSAPI we don't have to ask for username/password, because it uses session wide tickets - QMetaObject::invokeMethod( this, "onPasswordRequestDone", Qt::QueuedConnection, - Q_ARG( int, PasswordRequesterInterface::PasswordRetrieved ), - Q_ARG( QString, QString() ) ); - } else { - m_passwordRequester->requestPassword(); - } - - return true; -} - -void SessionPool::disconnect( SessionTermination termination ) -{ - if ( !m_account ) { - return; - } - - foreach ( KIMAP::Session *s, m_unusedPool + m_reservedPool + m_connectingPool ) { - killSession( s, termination ); - } - m_unusedPool.clear(); - m_reservedPool.clear(); - m_connectingPool.clear(); - m_pendingInitialSession = 0; - m_passwordRequester->cancelPasswordRequests(); - - delete m_account; - m_account = 0; - m_namespaces.clear(); - m_capabilities.clear(); + if (!m_account) { + return; + } - m_initialConnectDone = false; - emit disconnectDone(); + foreach (KIMAP::Session *s, m_unusedPool + m_reservedPool + m_connectingPool) { + killSession(s, termination); + } + m_unusedPool.clear(); + m_reservedPool.clear(); + m_connectingPool.clear(); + m_pendingInitialSession = Q_NULLPTR; + m_passwordRequester->cancelPasswordRequests(); + + delete m_account; + m_account = Q_NULLPTR; + m_namespaces.clear(); + m_capabilities.clear(); + + m_initialConnectDone = false; + Q_EMIT disconnectDone(); } qint64 SessionPool::requestSession() { - if ( !m_initialConnectDone ) { - return -1; - } + if (!m_initialConnectDone) { + return -1; + } - qint64 requestNumber = ++m_requestCounter; + qint64 requestNumber = ++m_requestCounter; - // The queue was empty, so trigger the processing - if ( m_pendingRequests.isEmpty() ) { - QTimer::singleShot( 0, this, SLOT(processPendingRequests()) ); - } + // The queue was empty, so trigger the processing + if (m_pendingRequests.isEmpty()) { + QTimer::singleShot(0, this, SLOT(processPendingRequests())); + } - m_pendingRequests << requestNumber; + m_pendingRequests << requestNumber; - return requestNumber; + return requestNumber; } -void SessionPool::cancelSessionRequest( qint64 id ) +void SessionPool::cancelSessionRequest(qint64 id) { - Q_ASSERT( id > 0 ); - m_pendingRequests.removeAll( id ); + Q_ASSERT(id > 0); + m_pendingRequests.removeAll(id); } -void SessionPool::releaseSession( KIMAP::Session *session ) +void SessionPool::releaseSession(KIMAP::Session *session) { - if ( m_reservedPool.contains( session ) ) { - m_reservedPool.removeAll( session ); - m_unusedPool << session; - } + if (m_reservedPool.contains(session)) { + m_reservedPool.removeAll(session); + m_unusedPool << session; + } } ImapAccount *SessionPool::account() const { - return m_account; + return m_account; } QStringList SessionPool::serverCapabilities() const { - return m_capabilities; + return m_capabilities; } QList SessionPool::serverNamespaces() const { - return m_namespaces; + return m_namespaces; } -void SessionPool::killSession( KIMAP::Session *session, SessionTermination termination ) +QList SessionPool::serverNamespaces(Namespace ns) const { - QObject::disconnect( session, SIGNAL(stateChanged(KIMAP::Session::State,KIMAP::Session::State)), - this, SLOT(onSessionStateChanged(KIMAP::Session::State,KIMAP::Session::State)) ); - m_unusedPool.removeAll( session ); - m_reservedPool.removeAll( session ); - m_connectingPool.removeAll( session ); - - if ( session->state() != KIMAP::Session::Disconnected && termination == LogoutSession ) { - KIMAP::LogoutJob *logout = new KIMAP::LogoutJob( session ); - QObject::connect( logout, SIGNAL(result(KJob*)), - session, SLOT(deleteLater()) ); - logout->start(); - } else { - session->close(); - session->deleteLater(); - } + switch (ns) { + case Personal: + return m_personalNamespaces; + case User: + return m_userNamespaces; + case Shared: + return m_sharedNamespaces; + default: + break; + } + Q_ASSERT(false); + return QList(); } -void SessionPool::declareSessionReady( KIMAP::Session *session ) +void SessionPool::killSession(KIMAP::Session *session, SessionTermination termination) { - //This can happen if we happen to disconnect while capabilities and namespace are being retrieved, - //resulting in us keeping a dangling pointer to a deleted session - if (!m_connectingPool.contains( session )) { - kWarning() << "Tried to declare a removed session ready"; - return; - } - - m_pendingInitialSession = 0; - - if ( !m_initialConnectDone ) { - m_initialConnectDone = true; - emit connectDone(); - } - - m_connectingPool.removeAll( session ); - - if ( m_pendingRequests.isEmpty() ) { - m_unusedPool << session; - } else { - m_reservedPool << session; - emit sessionRequestDone( m_pendingRequests.takeFirst(), session ); - - if ( !m_pendingRequests.isEmpty() ) { - QTimer::singleShot( 0, this, SLOT(processPendingRequests()) ); - } - } -} - -void SessionPool::cancelSessionCreation( KIMAP::Session *session, int errorCode, - const QString &errorMessage ) -{ - m_pendingInitialSession = 0; - - QString msg; - if ( m_account ) { - msg = i18n( "Could not connect to the IMAP-server %1.\n%2", m_account->server(), errorMessage ); - } else { - // Can happen when we lose all ready connections while trying to establish - // a new connection, for example. - msg = i18n( "Could not connect to the IMAP server.\n%1", errorMessage ); - } - - if ( !m_initialConnectDone ) { - disconnect(); // kills all sessions, including \a session - } else { - killSession( session, LogoutSession ); - if ( !m_pendingRequests.isEmpty() ) { - emit sessionRequestDone( m_pendingRequests.takeFirst(), 0, errorCode, errorMessage ); - if ( !m_pendingRequests.isEmpty() ) { - QTimer::singleShot( 0, this, SLOT(processPendingRequests()) ); - } - } - } - //Always emit this at the end. This can call SessionPool::disconnect via ImapResource. - emit connectDone( errorCode, msg ); + if (!m_unusedPool.contains(session) && !m_reservedPool.contains(session) && !m_connectingPool.contains(session)) { + qCWarning(IMAPRESOURCE_LOG) << "Unmanaged session" << session; + Q_ASSERT(false); + return; + } + QObject::disconnect(session, SIGNAL(stateChanged(KIMAP::Session::State,KIMAP::Session::State)), + this, SLOT(onSessionStateChanged(KIMAP::Session::State,KIMAP::Session::State))); + m_unusedPool.removeAll(session); + m_reservedPool.removeAll(session); + m_connectingPool.removeAll(session); + + if (session->state() != KIMAP::Session::Disconnected && termination == LogoutSession) { + KIMAP::LogoutJob *logout = new KIMAP::LogoutJob(session); + QObject::connect(logout, &KJob::result, + session, &QObject::deleteLater); + logout->start(); + } else { + session->close(); + session->deleteLater(); + } } -void SessionPool::processPendingRequests() +void SessionPool::declareSessionReady(KIMAP::Session *session) { - if ( !m_unusedPool.isEmpty() ) { - // We have a session ready to give out - KIMAP::Session *session = m_unusedPool.takeFirst(); - m_reservedPool << session; - if ( !m_pendingRequests.isEmpty() ) { - emit sessionRequestDone( m_pendingRequests.takeFirst(), session ); - if ( !m_pendingRequests.isEmpty() ) { - QTimer::singleShot( 0, this, SLOT(processPendingRequests()) ); - } - } - } else if ( m_unusedPool.size() + m_reservedPool.size() < m_maxPoolSize ) { - // We didn't reach the max pool size yet so create a new one - m_passwordRequester->requestPassword(); - - } else { - // No session available, and max pool size reached - if ( !m_pendingRequests.isEmpty() ) { - emit sessionRequestDone( - m_pendingRequests.takeFirst(), 0, NoAvailableSessionError, - i18n( "Could not create another extra connection to the IMAP-server %1.", - m_account->server() ) ); - if ( !m_pendingRequests.isEmpty() ) { - QTimer::singleShot( 0, this, SLOT(processPendingRequests()) ); - } - } - } -} - -void SessionPool::onPasswordRequestDone( int resultType, const QString &password ) -{ - QString errorMessage; - - if ( !m_account ) { - // it looks like the connection was lost while we were waiting - // for the password, we should fail all the pending requests and stop there - foreach ( int request, m_pendingRequests ) { - emit sessionRequestDone( request, 0, - LoginFailError, i18n( "Disconnected from server during login." ) ); - } - return; - } - - switch ( resultType ) { - case PasswordRequesterInterface::PasswordRetrieved: - // All is fine - break; - case PasswordRequesterInterface::ReconnectNeeded: - Q_ASSERT( m_pendingInitialSession != 0 ); - cancelSessionCreation( m_pendingInitialSession, ReconnectNeededError, errorMessage ); - return; - case PasswordRequesterInterface::UserRejected: - errorMessage = i18n( "Could not read the password: user rejected wallet access" ); - if ( m_pendingInitialSession ) { - cancelSessionCreation( m_pendingInitialSession, LoginFailError, errorMessage ); + //This can happen if we happen to disconnect while capabilities and namespace are being retrieved, + //resulting in us keeping a dangling pointer to a deleted session + if (!m_connectingPool.contains(session)) { + qCWarning(IMAPRESOURCE_LOG) << "Tried to declare a removed session ready"; + return; + } + + m_pendingInitialSession = Q_NULLPTR; + + if (!m_initialConnectDone) { + m_initialConnectDone = true; + Q_EMIT connectDone(); + } + + m_connectingPool.removeAll(session); + + if (m_pendingRequests.isEmpty()) { + m_unusedPool << session; } else { - emit connectDone( PasswordRequestError, errorMessage ); + m_reservedPool << session; + Q_EMIT sessionRequestDone(m_pendingRequests.takeFirst(), session); + + if (!m_pendingRequests.isEmpty()) { + QTimer::singleShot(0, this, SLOT(processPendingRequests())); + } } - return; - case PasswordRequesterInterface::EmptyPasswordEntered: - errorMessage = i18n( "Empty password" ); - if ( m_pendingInitialSession ) { - cancelSessionCreation( m_pendingInitialSession, LoginFailError, errorMessage ); +} + +void SessionPool::cancelSessionCreation(KIMAP::Session *session, int errorCode, + const QString &errorMessage) +{ + m_pendingInitialSession = Q_NULLPTR; + + QString msg; + if (m_account) { + msg = i18n("Could not connect to the IMAP-server %1.\n%2", m_account->server(), errorMessage); + } else { + // Can happen when we lose all ready connections while trying to establish + // a new connection, for example. + msg = i18n("Could not connect to the IMAP server.\n%1", errorMessage); + } + + if (!m_initialConnectDone) { + disconnect(); // kills all sessions, including \a session } else { - emit connectDone( PasswordRequestError, errorMessage ); + killSession(session, LogoutSession); + if (!m_pendingRequests.isEmpty()) { + Q_EMIT sessionRequestDone(m_pendingRequests.takeFirst(), Q_NULLPTR, errorCode, errorMessage); + if (!m_pendingRequests.isEmpty()) { + QTimer::singleShot(0, this, SLOT(processPendingRequests())); + } + } } - return; - } + //AlwaysQ_EMIT this at the end. This can call SessionPool::disconnect via ImapResource. + Q_EMIT connectDone(errorCode, msg); +} + +void SessionPool::processPendingRequests() +{ + if (!m_unusedPool.isEmpty()) { + // We have a session ready to give out + KIMAP::Session *session = m_unusedPool.takeFirst(); + m_reservedPool << session; + if (!m_pendingRequests.isEmpty()) { + Q_EMIT sessionRequestDone(m_pendingRequests.takeFirst(), session); + if (!m_pendingRequests.isEmpty()) { + QTimer::singleShot(0, this, SLOT(processPendingRequests())); + } + } + } else if (m_unusedPool.size() + m_reservedPool.size() < m_maxPoolSize) { + // We didn't reach the max pool size yet so create a new one + m_passwordRequester->requestPassword(); - if ( m_account->encryptionMode() != KIMAP::LoginJob::Unencrypted && !QSslSocket::supportsSsl() ) { - kWarning() << "Crypto not supported!"; - emit connectDone( EncryptionError, - i18n( "You requested TLS/SSL to connect to %1, but your " - "system does not seem to be set up for that.", m_account->server() ) ); - disconnect(); - return; - } - - KIMAP::Session *session = 0; - if ( m_pendingInitialSession ) { - session = m_pendingInitialSession; - } else { - session = new KIMAP::Session( m_account->server(), m_account->port(), this ); - QObject::connect(session, SIGNAL(destroyed(QObject*)), this, SLOT(onSessionDestroyed(QObject*))); - session->setUiProxy( m_sessionUiProxy ); - session->setTimeout( m_account->timeout() ); - m_connectingPool << session; - } - - QObject::connect( session, SIGNAL(stateChanged(KIMAP::Session::State,KIMAP::Session::State)), - this, SLOT(onSessionStateChanged(KIMAP::Session::State,KIMAP::Session::State)) ); - - KIMAP::LoginJob *loginJob = new KIMAP::LoginJob( session ); - loginJob->setUserName( m_account->userName() ); - loginJob->setPassword( password ); - loginJob->setEncryptionMode( m_account->encryptionMode() ); - loginJob->setAuthenticationMode( m_account->authenticationMode() ); - - QObject::connect( loginJob, SIGNAL(result(KJob*)), - this, SLOT(onLoginDone(KJob*)) ); - loginJob->start(); -} - -void SessionPool::onLoginDone( KJob *job ) -{ - KIMAP::LoginJob *login = static_cast( job ); - //Can happen if we disonnected meanwhile - if (!m_connectingPool.contains(login->session())) { - emit connectDone( CancelledError, i18n( "Disconnected from server during login.") ); - return; - } - - if ( job->error() == 0 ) { - if ( m_initialConnectDone ) { - declareSessionReady( login->session() ); } else { - // On initial connection we ask for capabilities - KIMAP::CapabilitiesJob *capJob = new KIMAP::CapabilitiesJob( login->session() ); - QObject::connect( capJob, SIGNAL(result(KJob*)), SLOT(onCapabilitiesTestDone(KJob*)) ); - capJob->start(); - } - } else { - if ( job->error() == KIMAP::LoginJob::ERR_COULD_NOT_CONNECT ) { - if ( m_account ) { - cancelSessionCreation( login->session(), - CouldNotConnectError, - i18n( "Could not connect to the IMAP-server %1.\n%2", - m_account->server(), job->errorString() ) ); - } else { - // Can happen when we loose all ready connections while trying to login. - cancelSessionCreation( login->session(), - CouldNotConnectError, - i18n( "Could not connect to the IMAP-server.\n%1", - job->errorString() ) ); - } + // No session available, and max pool size reached + if (!m_pendingRequests.isEmpty()) { + Q_EMIT sessionRequestDone( + m_pendingRequests.takeFirst(), Q_NULLPTR, NoAvailableSessionError, + i18n("Could not create another extra connection to the IMAP-server %1.", + m_account->server())); + if (!m_pendingRequests.isEmpty()) { + QTimer::singleShot(0, this, SLOT(processPendingRequests())); + } + } + } +} + +void SessionPool::onPasswordRequestDone(int resultType, const QString &password) +{ + QString errorMessage; + + if (!m_account) { + // it looks like the connection was lost while we were waiting + // for the password, we should fail all the pending requests and stop there + foreach (int request, m_pendingRequests) { + Q_EMIT sessionRequestDone(request, Q_NULLPTR, + LoginFailError, i18n("Disconnected from server during login.")); + } + return; + } + + switch (resultType) { + case PasswordRequesterInterface::PasswordRetrieved: + // All is fine + break; + case PasswordRequesterInterface::ReconnectNeeded: + Q_ASSERT(m_pendingInitialSession != 0); + cancelSessionCreation(m_pendingInitialSession, ReconnectNeededError, errorMessage); + return; + case PasswordRequesterInterface::UserRejected: + errorMessage = i18n("Could not read the password: user rejected wallet access"); + if (m_pendingInitialSession) { + cancelSessionCreation(m_pendingInitialSession, LoginFailError, errorMessage); + } else { + Q_EMIT connectDone(PasswordRequestError, errorMessage); + } + return; + case PasswordRequesterInterface::EmptyPasswordEntered: + errorMessage = i18n("Empty password"); + if (m_pendingInitialSession) { + cancelSessionCreation(m_pendingInitialSession, LoginFailError, errorMessage); + } else { + Q_EMIT connectDone(PasswordRequestError, errorMessage); + } + return; + } + + if (m_account->encryptionMode() != KIMAP::LoginJob::Unencrypted && !QSslSocket::supportsSsl()) { + qCWarning(IMAPRESOURCE_LOG) << "Crypto not supported!"; + Q_EMIT connectDone(EncryptionError, + i18n("You requested TLS/SSL to connect to %1, but your " + "system does not seem to be set up for that.", m_account->server())); + disconnect(); + return; + } + + KIMAP::Session *session = Q_NULLPTR; + if (m_pendingInitialSession) { + session = m_pendingInitialSession; + } else { + session = new KIMAP::Session(m_account->server(), m_account->port(), this); + QObject::connect(session, SIGNAL(destroyed(QObject*)), this, SLOT(onSessionDestroyed(QObject*))); + session->setUiProxy(m_sessionUiProxy); + session->setTimeout(m_account->timeout()); + m_connectingPool << session; + } + + QObject::connect(session, SIGNAL(stateChanged(KIMAP::Session::State,KIMAP::Session::State)), + this, SLOT(onSessionStateChanged(KIMAP::Session::State,KIMAP::Session::State))); + + KIMAP::LoginJob *loginJob = new KIMAP::LoginJob(session); + loginJob->setUserName(m_account->userName()); + loginJob->setPassword(password); + loginJob->setEncryptionMode(m_account->encryptionMode()); + loginJob->setAuthenticationMode(m_account->authenticationMode()); + + QObject::connect(loginJob, SIGNAL(result(KJob*)), + this, SLOT(onLoginDone(KJob*))); + loginJob->start(); +} + +void SessionPool::onLoginDone(KJob *job) +{ + KIMAP::LoginJob *login = static_cast(job); + //Can happen if we disonnected meanwhile + if (!m_connectingPool.contains(login->session())) { + Q_EMIT connectDone(CancelledError, i18n("Disconnected from server during login.")); + return; + } + + if (job->error() == 0) { + if (m_initialConnectDone) { + declareSessionReady(login->session()); + } else { + // On initial connection we ask for capabilities + KIMAP::CapabilitiesJob *capJob = new KIMAP::CapabilitiesJob(login->session()); + QObject::connect(capJob, &KIMAP::CapabilitiesJob::result, this, &SessionPool::onCapabilitiesTestDone); + capJob->start(); + } } else { - // Connection worked, but login failed -> ask for a different password or ssl settings. - m_pendingInitialSession = login->session(); - m_passwordRequester->requestPassword( PasswordRequesterInterface::WrongPasswordRequest, - job->errorString() ); - } - } -} - -void SessionPool::onCapabilitiesTestDone( KJob *job ) -{ - KIMAP::CapabilitiesJob *capJob = qobject_cast( job ); - //Can happen if we disonnected meanwhile - if (!m_connectingPool.contains(capJob->session())) { - emit connectDone( CancelledError, i18n( "Disconnected from server during login.") ); - return; - } - - if ( job->error() ) { - if ( m_account ) { - cancelSessionCreation( capJob->session(), - CapabilitiesTestError, - i18n( "Could not test the capabilities supported by the " - "IMAP server %1.\n%2", - m_account->server(), job->errorString() ) ); + if (job->error() == KIMAP::LoginJob::ERR_COULD_NOT_CONNECT) { + if (m_account) { + cancelSessionCreation(login->session(), + CouldNotConnectError, + i18n("Could not connect to the IMAP-server %1.\n%2", + m_account->server(), job->errorString())); + } else { + // Can happen when we loose all ready connections while trying to login. + cancelSessionCreation(login->session(), + CouldNotConnectError, + i18n("Could not connect to the IMAP-server.\n%1", + job->errorString())); + } + } else { + // Connection worked, but login failed -> ask for a different password or ssl settings. + m_pendingInitialSession = login->session(); + m_passwordRequester->requestPassword(PasswordRequesterInterface::WrongPasswordRequest, + job->errorString()); + } + } +} + +void SessionPool::onCapabilitiesTestDone(KJob *job) +{ + KIMAP::CapabilitiesJob *capJob = qobject_cast(job); + //Can happen if we disonnected meanwhile + if (!m_connectingPool.contains(capJob->session())) { + Q_EMIT connectDone(CancelledError, i18n("Disconnected from server during login.")); + return; + } + + if (job->error()) { + if (m_account) { + cancelSessionCreation(capJob->session(), + CapabilitiesTestError, + i18n("Could not test the capabilities supported by the " + "IMAP server %1.\n%2", + m_account->server(), job->errorString())); + } else { + // Can happen when we loose all ready connections while trying to check capabilities. + cancelSessionCreation(capJob->session(), + CapabilitiesTestError, + i18n("Could not test the capabilities supported by the " + "IMAP server.\n%1", job->errorString())); + } + return; + } + + m_capabilities = capJob->capabilities(); + QStringList expected; + expected << QStringLiteral("IMAP4REV1"); + + QStringList missing; + foreach (const QString &capability, expected) { + if (!m_capabilities.contains(capability)) { + missing << capability; + } + } + + if (!missing.isEmpty()) { + cancelSessionCreation(capJob->session(), + IncompatibleServerError, + i18n("Cannot use the IMAP server %1, " + "some mandatory capabilities are missing: %2. " + "Please ask your sysadmin to upgrade the server.", + m_account->server(), + missing.join(QLatin1String(", ")))); + return; + } + + // If the extension is supported, grab the namespaces from the server + if (m_capabilities.contains(QLatin1String("NAMESPACE"))) { + KIMAP::NamespaceJob *nsJob = new KIMAP::NamespaceJob(capJob->session()); + QObject::connect(nsJob, &KIMAP::NamespaceJob::result, this, &SessionPool::onNamespacesTestDone); + nsJob->start(); + return; } else { - // Can happen when we loose all ready connections while trying to check capabilities. - cancelSessionCreation( capJob->session(), - CapabilitiesTestError, - i18n( "Could not test the capabilities supported by the " - "IMAP server.\n%1", job->errorString() ) ); - } - return; - } - - m_capabilities = capJob->capabilities(); - QStringList expected; - expected << QLatin1String("IMAP4REV1"); - - QStringList missing; - foreach ( const QString &capability, expected ) { - if ( !m_capabilities.contains( capability ) ) { - missing << capability; - } - } - - if ( !missing.isEmpty() ) { - cancelSessionCreation( capJob->session(), - IncompatibleServerError, - i18n( "Cannot use the IMAP server %1, " - "some mandatory capabilities are missing: %2. " - "Please ask your sysadmin to upgrade the server.", - m_account->server(), - missing.join( QLatin1String(", ") ) ) ); - return; - } - - // If the extension is supported, grab the namespaces from the server - if ( m_capabilities.contains( QLatin1String("NAMESPACE") ) ) { - KIMAP::NamespaceJob *nsJob = new KIMAP::NamespaceJob( capJob->session() ); - QObject::connect( nsJob, SIGNAL(result(KJob*)), SLOT(onNamespacesTestDone(KJob*)) ); - nsJob->start(); - return; - } else { - declareSessionReady( capJob->session() ); - } -} - -void SessionPool::onNamespacesTestDone( KJob *job ) -{ - KIMAP::NamespaceJob *nsJob = qobject_cast( job ); - // Can happen if we disconnect meanwhile - if (!m_connectingPool.contains(nsJob->session())) { - emit connectDone( CancelledError, i18n( "Disconnected from server during login.") ); - return; - } - - if ( nsJob->containsEmptyNamespace() ) { - // When we got the empty namespace here, we assume that the other - // ones can be freely ignored and that the server will give us all - // the mailboxes if we list from the empty namespace itself... + declareSessionReady(capJob->session()); + } +} - m_namespaces.clear(); +void SessionPool::onNamespacesTestDone(KJob *job) +{ + KIMAP::NamespaceJob *nsJob = qobject_cast(job); + // Can happen if we disconnect meanwhile + if (!m_connectingPool.contains(nsJob->session())) { + Q_EMIT connectDone(CancelledError, i18n("Disconnected from server during login.")); + return; + } + + if (nsJob->containsEmptyNamespace()) { + // When we got the empty namespace here, we assume that the other + // ones can be freely ignored and that the server will give us all + // the mailboxes if we list from the empty namespace itself... - } else { - // ... otherwise we assume that we have to list explicitly each - // namespace - - m_namespaces = nsJob->personalNamespaces() + - nsJob->userNamespaces() + - nsJob->sharedNamespaces(); - } + m_namespaces.clear(); + + } else { + // ... otherwise we assume that we have to list explicitly each + // namespace - declareSessionReady( nsJob->session() ); + m_namespaces = nsJob->personalNamespaces() + + nsJob->userNamespaces() + + nsJob->sharedNamespaces(); + } + + declareSessionReady(nsJob->session()); } void SessionPool::onSessionStateChanged(KIMAP::Session::State newState, KIMAP::Session::State oldState) { - if (newState == KIMAP::Session::Disconnected && oldState != KIMAP::Session::Disconnected) { - onConnectionLost(); - } + if (newState == KIMAP::Session::Disconnected && oldState != KIMAP::Session::Disconnected) { + onConnectionLost(); + } } void SessionPool::onConnectionLost() { - KIMAP::Session *session = static_cast( sender() ); + KIMAP::Session *session = static_cast(sender()); - m_unusedPool.removeAll( session ); - m_reservedPool.removeAll( session ); - m_connectingPool.removeAll( session ); + m_unusedPool.removeAll(session); + m_reservedPool.removeAll(session); + m_connectingPool.removeAll(session); - if ( m_unusedPool.isEmpty() && m_reservedPool.isEmpty() ) { - m_passwordRequester->cancelPasswordRequests(); - delete m_account; - m_account = 0; - m_namespaces.clear(); - m_capabilities.clear(); + if (m_unusedPool.isEmpty() && m_reservedPool.isEmpty()) { + m_passwordRequester->cancelPasswordRequests(); + delete m_account; + m_account = Q_NULLPTR; + m_namespaces.clear(); + m_capabilities.clear(); - m_initialConnectDone = false; - } + m_initialConnectDone = false; + } - emit connectionLost( session ); + Q_EMIT connectionLost(session); - session->deleteLater(); - if ( session == m_pendingInitialSession ) - m_pendingInitialSession = 0; + session->deleteLater(); + if (session == m_pendingInitialSession) { + m_pendingInitialSession = Q_NULLPTR; + } } void SessionPool::onSessionDestroyed(QObject *object) { - //Safety net for bugs that cause dangling session pointers - KIMAP::Session *session = static_cast(object); - if (m_unusedPool.contains(session) || m_reservedPool.contains(session) || m_connectingPool.contains(session)) { - kWarning() << "Session destroyed while still in pool" << session; - m_unusedPool.removeAll(session); - m_reservedPool.removeAll(session); - m_connectingPool.removeAll(session); - Q_ASSERT(false); - } + //Safety net for bugs that cause dangling session pointers + KIMAP::Session *session = static_cast(object); + if (m_unusedPool.contains(session) || m_reservedPool.contains(session) || m_connectingPool.contains(session)) { + qCWarning(IMAPRESOURCE_LOG) << "Session destroyed while still in pool" << session; + m_unusedPool.removeAll(session); + m_reservedPool.removeAll(session); + m_connectingPool.removeAll(session); + Q_ASSERT(false); + } } diff -Nru kdepim-runtime-4.14.6/resources/imap/sessionpool.h kdepim-runtime-15.08.0/resources/imap/sessionpool.h --- kdepim-runtime-4.14.6/resources/imap/sessionpool.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/sessionpool.h 2015-08-10 21:01:02.000000000 +0000 @@ -31,7 +31,7 @@ namespace KIMAP { - class MailBoxDescriptor; +class MailBoxDescriptor; } class ImapAccount; @@ -39,92 +39,101 @@ class SessionPool : public QObject { - Q_OBJECT - Q_ENUMS( ConnectError ) + Q_OBJECT + Q_ENUMS(ConnectError) public: - enum ErrorCodes { - NoError, - PasswordRequestError, - ReconnectNeededError, - EncryptionError, - LoginFailError, - CapabilitiesTestError, - IncompatibleServerError, - NoAvailableSessionError, - CouldNotConnectError, - CancelledError - }; - - enum SessionTermination { - LogoutSession, - CloseSession - }; - - explicit SessionPool( int maxPoolSize, QObject *parent = 0 ); - ~SessionPool(); - - PasswordRequesterInterface *passwordRequester() const; - void setPasswordRequester( PasswordRequesterInterface *requester ); - void cancelPasswordRequests(); - - KIMAP::SessionUiProxy::Ptr sessionUiProxy() const; - void setSessionUiProxy( KIMAP::SessionUiProxy::Ptr proxy ); - - bool isConnected() const; - bool connect( ImapAccount *account ); - void disconnect( SessionTermination termination = LogoutSession ); - - qint64 requestSession(); - void cancelSessionRequest( qint64 id ); - void releaseSession( KIMAP::Session *session ); - - ImapAccount *account() const; - QStringList serverCapabilities() const; - QList serverNamespaces() const; - -signals: - void connectionLost( KIMAP::Session *session ); - - void sessionRequestDone( qint64 requestNumber, KIMAP::Session *session, - int errorCode = NoError, const QString &errorString = QString() ); - void connectDone( int errorCode = NoError, const QString &errorString = QString() ); - void disconnectDone(); - -private slots: - void processPendingRequests(); - - void onPasswordRequestDone(int resultType, const QString &password); - void onLoginDone( KJob *job ); - void onCapabilitiesTestDone( KJob *job ); - void onNamespacesTestDone( KJob *job ); + enum ErrorCodes { + NoError, + PasswordRequestError, + ReconnectNeededError, + EncryptionError, + LoginFailError, + CapabilitiesTestError, + IncompatibleServerError, + NoAvailableSessionError, + CouldNotConnectError, + CancelledError + }; + + enum SessionTermination { + LogoutSession, + CloseSession + }; + + explicit SessionPool(int maxPoolSize, QObject *parent = Q_NULLPTR); + ~SessionPool(); + + PasswordRequesterInterface *passwordRequester() const; + void setPasswordRequester(PasswordRequesterInterface *requester); + void cancelPasswordRequests(); + + KIMAP::SessionUiProxy::Ptr sessionUiProxy() const; + void setSessionUiProxy(KIMAP::SessionUiProxy::Ptr proxy); + + bool isConnected() const; + bool connect(ImapAccount *account); + void disconnect(SessionTermination termination = LogoutSession); + + qint64 requestSession(); + void cancelSessionRequest(qint64 id); + void releaseSession(KIMAP::Session *session); + + ImapAccount *account() const; + QStringList serverCapabilities() const; + QList serverNamespaces() const; + enum Namespace { + Personal, + User, + Shared + }; + QList serverNamespaces(Namespace) const; + +Q_SIGNALS: + void connectionLost(KIMAP::Session *session); + + void sessionRequestDone(qint64 requestNumber, KIMAP::Session *session, + int errorCode = NoError, const QString &errorString = QString()); + void connectDone(int errorCode = NoError, const QString &errorString = QString()); + void disconnectDone(); + +private Q_SLOTS: + void processPendingRequests(); + + void onPasswordRequestDone(int resultType, const QString &password); + void onLoginDone(KJob *job); + void onCapabilitiesTestDone(KJob *job); + void onNamespacesTestDone(KJob *job); - void onSessionStateChanged(KIMAP::Session::State newState, KIMAP::Session::State oldState); - void onSessionDestroyed(QObject*); + void onSessionStateChanged(KIMAP::Session::State newState, KIMAP::Session::State oldState); + void onSessionDestroyed(QObject *); private: - void onConnectionLost(); - void killSession( KIMAP::Session *session, SessionTermination termination ); - void declareSessionReady( KIMAP::Session *session ); - void cancelSessionCreation( KIMAP::Session *session, int errorCode, const QString &errorString ); - - static qint64 m_requestCounter; - - int m_maxPoolSize; - ImapAccount *m_account; - PasswordRequesterInterface *m_passwordRequester; - KIMAP::SessionUiProxy::Ptr m_sessionUiProxy; - - bool m_initialConnectDone; - KIMAP::Session *m_pendingInitialSession; - - QList m_pendingRequests; - QList m_connectingPool; // in preparation - QList m_unusedPool; // ready to be used - QList m_reservedPool; // currently used - - QStringList m_capabilities; - QList m_namespaces; + void onConnectionLost(); + void killSession(KIMAP::Session *session, SessionTermination termination); + void declareSessionReady(KIMAP::Session *session); + void cancelSessionCreation(KIMAP::Session *session, int errorCode, const QString &errorString); + + static qint64 m_requestCounter; + + int m_maxPoolSize; + ImapAccount *m_account; + PasswordRequesterInterface *m_passwordRequester; + KIMAP::SessionUiProxy::Ptr m_sessionUiProxy; + + bool m_initialConnectDone; + KIMAP::Session *m_pendingInitialSession; + + QList m_pendingRequests; + QList m_connectingPool; // in preparation + QList m_unusedPool; // ready to be used + QList m_reservedPool; // currently used + + QStringList m_capabilities; + QList m_namespaces; + QList m_personalNamespaces; + QList m_userNamespaces; + QList m_sharedNamespaces; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/sessionuiproxy.h kdepim-runtime-15.08.0/resources/imap/sessionuiproxy.h --- kdepim-runtime-4.14.6/resources/imap/sessionuiproxy.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/sessionuiproxy.h 2015-08-10 21:01:02.000000000 +0000 @@ -25,15 +25,16 @@ #include #include - -class SessionUiProxy : public KIMAP::SessionUiProxy { - public: - bool ignoreSslError( const KSslErrorUiData &errorData ) { - if ( KIO::SslUi::askIgnoreSslErrors( errorData, KIO::SslUi::RecallAndStoreRules) ) { - return true; - } else { - return false; - } +class SessionUiProxy : public KIMAP::SessionUiProxy +{ +public: + bool ignoreSslError(const KSslErrorUiData &errorData) Q_DECL_OVERRIDE { + if (KIO::SslUi::askIgnoreSslErrors(errorData, KIO::SslUi::RecallAndStoreRules)) + { + return true; + } else { + return false; + } } }; diff -Nru kdepim-runtime-4.14.6/resources/imap/settings.cpp kdepim-runtime-15.08.0/resources/imap/settings.cpp --- kdepim-runtime-4.14.6/resources/imap/settings.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/settings.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,14 +26,15 @@ #include using KWallet::Wallet; -#include +#include #include +#include "imapresource_debug.h" #include -#include -#include -#include +#include +#include +#include /** * Maps the enum used to represent authentication in MailTransport (kdepimlibs) @@ -42,43 +43,43 @@ * @return the corresponding KIMAP auth value. * @note will cause fatal error if there is no mapping, so be careful not to pass invalid auth options (e.g., APOP) to this function. */ -KIMAP::LoginJob::AuthenticationMode Settings::mapTransportAuthToKimap( MailTransport::Transport::EnumAuthenticationType::type authType ) +KIMAP::LoginJob::AuthenticationMode Settings::mapTransportAuthToKimap(MailTransport::Transport::EnumAuthenticationType::type authType) { - // typedef these for readability - typedef MailTransport::Transport::EnumAuthenticationType MTAuth; - typedef KIMAP::LoginJob KIAuth; - switch ( authType ) { + // typedef these for readability + typedef MailTransport::Transport::EnumAuthenticationType MTAuth; + typedef KIMAP::LoginJob KIAuth; + switch (authType) { case MTAuth::ANONYMOUS: - return KIAuth::Anonymous; + return KIAuth::Anonymous; case MTAuth::PLAIN: - return KIAuth::Plain; + return KIAuth::Plain; case MTAuth::NTLM: - return KIAuth::NTLM; + return KIAuth::NTLM; case MTAuth::LOGIN: - return KIAuth::Login; + return KIAuth::Login; case MTAuth::GSSAPI: - return KIAuth::GSSAPI; + return KIAuth::GSSAPI; case MTAuth::DIGEST_MD5: - return KIAuth::DigestMD5; + return KIAuth::DigestMD5; case MTAuth::CRAM_MD5: - return KIAuth::CramMD5; + return KIAuth::CramMD5; case MTAuth::CLEAR: - return KIAuth::ClearText; + return KIAuth::ClearText; default: - kFatal() << "mapping from Transport::EnumAuthenticationType -> KIMAP::LoginJob::AuthenticationMode not possible"; - } - return KIAuth::ClearText; // dummy value, shouldn't get here. + qFatal("mapping from Transport::EnumAuthenticationType -> KIMAP::LoginJob::AuthenticationMode not possible"); + } + return KIAuth::ClearText; // dummy value, shouldn't get here. } -Settings::Settings( WId winId ) : SettingsBase(), m_winId( winId ) +Settings::Settings(WId winId) : SettingsBase(), m_winId(winId) { - readConfig(); + load(); - new SettingsAdaptor( this ); - QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ), this, QDBusConnection::ExportAdaptors | QDBusConnection::ExportScriptableContents ); + new SettingsAdaptor(this); + QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"), this, QDBusConnection::ExportAdaptors | QDBusConnection::ExportScriptableContents); } -void Settings::setWinId( WId winId ) +void Settings::setWinId(WId winId) { m_winId = winId; } @@ -90,11 +91,11 @@ void Settings::cleanup() { - Wallet* wallet = Wallet::openWallet( Wallet::NetworkWallet(), m_winId ); - if ( wallet && wallet->isOpen() ) { - if ( wallet->hasFolder( QLatin1String("imap") ) ) { - wallet->setFolder( QLatin1String("imap") ); - wallet->removeEntry( config()->name() ); + Wallet *wallet = Wallet::openWallet(Wallet::NetworkWallet(), m_winId); + if (wallet && wallet->isOpen()) { + if (wallet->hasFolder(QStringLiteral("imap"))) { + wallet->setFolder(QStringLiteral("imap")); + wallet->removeEntry(config()->name()); } delete wallet; } @@ -102,83 +103,85 @@ void Settings::requestPassword() { - if ( !m_password.isEmpty() || - ( mapTransportAuthToKimap( (MailTransport::TransportBase::EnumAuthenticationType::type)authentication() ) == KIMAP::LoginJob::GSSAPI ) ) { - emit passwordRequestCompleted( m_password, false ); - } else { - Wallet *wallet = Wallet::openWallet( Wallet::NetworkWallet(), m_winId, Wallet::Asynchronous ); - if ( wallet ) { - connect( wallet, SIGNAL(walletOpened(bool)), - this, SLOT(onWalletOpened(bool)) ); + if (!m_password.isEmpty() || + (mapTransportAuthToKimap((MailTransport::TransportBase::EnumAuthenticationType::type)authentication()) == KIMAP::LoginJob::GSSAPI)) { + Q_EMIT passwordRequestCompleted(m_password, false); } else { - QMetaObject::invokeMethod( this, "onWalletOpened", Qt::QueuedConnection, Q_ARG(bool, true) ); + Wallet *wallet = Wallet::openWallet(Wallet::NetworkWallet(), m_winId, Wallet::Asynchronous); + if (wallet) { + connect(wallet, SIGNAL(walletOpened(bool)), + this, SLOT(onWalletOpened(bool))); + } else { + QMetaObject::invokeMethod(this, "onWalletOpened", Qt::QueuedConnection, Q_ARG(bool, true)); + } } - } } -void Settings::onWalletOpened( bool success ) +void Settings::onWalletOpened(bool success) { - if ( !success ) { - emit passwordRequestCompleted( QString(), true ); - } else { - Wallet *wallet = qobject_cast( sender() ); - bool passwordNotStoredInWallet = true; - if ( wallet && wallet->hasFolder( QLatin1String("imap") ) ) { - wallet->setFolder( QLatin1String("imap") ); - wallet->readPassword( config()->name(), m_password ); - passwordNotStoredInWallet = false; - } - if ( passwordNotStoredInWallet || m_password.isEmpty() ) - requestManualAuth(); - else - emit passwordRequestCompleted( m_password, passwordNotStoredInWallet ); - - if ( wallet ) { - wallet->deleteLater(); + if (!success) { + Q_EMIT passwordRequestCompleted(QString(), true); + } else { + Wallet *wallet = qobject_cast(sender()); + bool passwordNotStoredInWallet = true; + if (wallet && wallet->hasFolder(QStringLiteral("imap"))) { + wallet->setFolder(QStringLiteral("imap")); + wallet->readPassword(config()->name(), m_password); + passwordNotStoredInWallet = false; + } + if (passwordNotStoredInWallet || m_password.isEmpty()) { + requestManualAuth(); + } else { + Q_EMIT passwordRequestCompleted(m_password, passwordNotStoredInWallet); + } + + if (wallet) { + wallet->deleteLater(); + } } - } } void Settings::requestManualAuth() { - KPasswordDialog *dlg = new KPasswordDialog( 0 ); - dlg->setModal( true ); - dlg->setPrompt( i18n( "Please enter password for user '%1' on IMAP server '%2'.", - userName(), imapServer() ) ); - dlg->setAttribute( Qt::WA_DeleteOnClose ); - connect( dlg, SIGNAL(finished(int)), this, SLOT(onDialogFinished(int)) ); - dlg->show(); -} - -void Settings::onDialogFinished( int result ) -{ - if ( result == QDialog::Accepted ) { - KPasswordDialog *dlg = qobject_cast( sender() ); - setPassword( dlg->password() ); - emit passwordRequestCompleted( dlg->password(), false ); - } else { - emit passwordRequestCompleted( QString(), true ); - } + KPasswordDialog *dlg = new KPasswordDialog(Q_NULLPTR); + dlg->setModal(true); + dlg->setPrompt(i18n("Please enter password for user '%1' on IMAP server '%2'.", + userName(), imapServer())); + dlg->setAttribute(Qt::WA_DeleteOnClose); + connect(dlg, &KPasswordDialog::finished, this, &Settings::onDialogFinished); + dlg->show(); +} + +void Settings::onDialogFinished(int result) +{ + if (result == QDialog::Accepted) { + KPasswordDialog *dlg = qobject_cast(sender()); + setPassword(dlg->password()); + Q_EMIT passwordRequestCompleted(dlg->password(), false); + } else { + Q_EMIT passwordRequestCompleted(QString(), true); + } } QString Settings::password(bool *userRejected) const { - if ( userRejected != 0 ) { - *userRejected = false; + if (userRejected != Q_NULLPTR) { + *userRejected = false; } - if ( !m_password.isEmpty() || - ( mapTransportAuthToKimap( (MailTransport::TransportBase::EnumAuthenticationType::type)authentication() ) == KIMAP::LoginJob::GSSAPI ) ) - return m_password; - Wallet* wallet = Wallet::openWallet( Wallet::NetworkWallet(), m_winId ); - if ( wallet && wallet->isOpen() ) { - if ( wallet->hasFolder( QLatin1String("imap") ) ) { - wallet->setFolder( QLatin1String("imap") ); - wallet->readPassword( config()->name(), m_password ); - } else { - wallet->createFolder( QLatin1String("imap") ); - } - } else if ( userRejected != 0 ) { + if (!m_password.isEmpty() || + (mapTransportAuthToKimap((MailTransport::TransportBase::EnumAuthenticationType::type)authentication()) == KIMAP::LoginJob::GSSAPI)) { + return m_password; + } + Wallet *wallet = Wallet::openWallet(Wallet::NetworkWallet(), m_winId); + if (wallet && wallet->isOpen()) { + if (wallet->hasFolder(QStringLiteral("imap"))) { + wallet->setFolder(QStringLiteral("imap")); + wallet->readPassword(config()->name(), m_password); + } else { + wallet->createFolder(QStringLiteral("imap")); + } + } else if (userRejected != Q_NULLPTR) { *userRejected = true; } delete wallet; @@ -187,143 +190,149 @@ QString Settings::sieveCustomPassword(bool *userRejected) const { - if ( userRejected != 0 ) { - *userRejected = false; + if (userRejected != Q_NULLPTR) { + *userRejected = false; } - if ( !m_customSievePassword.isEmpty() ) - return m_customSievePassword; + if (!m_customSievePassword.isEmpty()) { + return m_customSievePassword; + } - Wallet* wallet = Wallet::openWallet( Wallet::NetworkWallet(), m_winId ); - if ( wallet && wallet->isOpen() ) { - if ( wallet->hasFolder( QLatin1String("imap") ) ) { - wallet->setFolder( QLatin1String("imap") ); - wallet->readPassword( QLatin1String("custom_sieve_") + config()->name(), m_customSievePassword ); - } else { - wallet->createFolder( QLatin1String("imap") ); - } - } else if ( userRejected != 0 ) { + Wallet *wallet = Wallet::openWallet(Wallet::NetworkWallet(), m_winId); + if (wallet && wallet->isOpen()) { + if (wallet->hasFolder(QStringLiteral("imap"))) { + wallet->setFolder(QStringLiteral("imap")); + wallet->readPassword(QStringLiteral("custom_sieve_") + config()->name(), m_customSievePassword); + } else { + wallet->createFolder(QStringLiteral("imap")); + } + } else if (userRejected != Q_NULLPTR) { *userRejected = true; } delete wallet; return m_customSievePassword; } -void Settings::setSieveCustomPassword(const QString & password) +void Settings::setSieveCustomPassword(const QString &password) { - if (m_customSievePassword == password) + if (m_customSievePassword == password) { return; + } m_customSievePassword = password; - Wallet* wallet = Wallet::openWallet( Wallet::NetworkWallet(), m_winId ); - if ( wallet && wallet->isOpen() ) { - if ( !wallet->hasFolder( QLatin1String("imap") ) ) - wallet->createFolder( QLatin1String("imap") ); - wallet->setFolder( QLatin1String("imap") ); - wallet->writePassword( QLatin1String("custom_sieve_") + config()->name(), password ); - kDebug() << "Wallet save: " << wallet->sync(); + Wallet *wallet = Wallet::openWallet(Wallet::NetworkWallet(), m_winId); + if (wallet && wallet->isOpen()) { + if (!wallet->hasFolder(QStringLiteral("imap"))) { + wallet->createFolder(QStringLiteral("imap")); + } + wallet->setFolder(QStringLiteral("imap")); + wallet->writePassword(QLatin1String("custom_sieve_") + config()->name(), password); + qCDebug(IMAPRESOURCE_LOG) << "Wallet save: " << wallet->sync(); } delete wallet; } -void Settings::setPassword( const QString & password ) +void Settings::setPassword(const QString &password) { - if ( password == m_password ) + if (password == m_password) { return; + } - if ( mapTransportAuthToKimap( (MailTransport::TransportBase::EnumAuthenticationType::type)authentication() ) == KIMAP::LoginJob::GSSAPI ) + if (mapTransportAuthToKimap((MailTransport::TransportBase::EnumAuthenticationType::type)authentication()) == KIMAP::LoginJob::GSSAPI) { return; + } m_password = password; - Wallet* wallet = Wallet::openWallet( Wallet::NetworkWallet(), m_winId ); - if ( wallet && wallet->isOpen() ) { - if ( !wallet->hasFolder( QLatin1String("imap") ) ) - wallet->createFolder( QLatin1String("imap") ); - wallet->setFolder( QLatin1String("imap") ); - wallet->writePassword( config()->name(), password ); - kDebug() << "Wallet save: " << wallet->sync(); + Wallet *wallet = Wallet::openWallet(Wallet::NetworkWallet(), m_winId); + if (wallet && wallet->isOpen()) { + if (!wallet->hasFolder(QStringLiteral("imap"))) { + wallet->createFolder(QStringLiteral("imap")); + } + wallet->setFolder(QStringLiteral("imap")); + wallet->writePassword(config()->name(), password); + qCDebug(IMAPRESOURCE_LOG) << "Wallet save: " << wallet->sync(); } delete wallet; } -void Settings::loadAccount( ImapAccount *account ) const +void Settings::loadAccount(ImapAccount *account) const { - account->setServer( imapServer() ); - if ( imapPort()>=0 ) { - account->setPort( imapPort() ); - } - - account->setUserName( userName() ); - account->setSubscriptionEnabled( subscriptionEnabled() ); - - const QString encryption = safety(); - if ( encryption == QLatin1String("SSL") ) { - account->setEncryptionMode( KIMAP::LoginJob::AnySslVersion ); - } else if ( encryption == QLatin1String("STARTTLS") ) { - //KIMAP confused TLS and STARTTLS, TlsV1 really means "use STARTTLS" - account->setEncryptionMode( KIMAP::LoginJob::TlsV1 ); - } else { - account->setEncryptionMode( KIMAP::LoginJob::Unencrypted ); - } - - //Some SSL Server fail to advertise an ssl version they support (AnySslVersion), - //we therefore allow overriding this in the config - //(so we don't have to make the UI unnecessarily complex for properly working servers). - const QString overrideEncryptionMode = overrideEncryption(); - if (!overrideEncryptionMode.isEmpty()) { - kWarning() << "Overriding encryption mode with: " << overrideEncryptionMode; - if ( overrideEncryptionMode == QLatin1String("SSLV2") ) { - account->setEncryptionMode( KIMAP::LoginJob::SslV2 ); - } else if ( overrideEncryptionMode == QLatin1String("SSLV3") ) { - account->setEncryptionMode( KIMAP::LoginJob::SslV3 ); - } else if ( overrideEncryptionMode == QLatin1String("TLSV1") ) { - account->setEncryptionMode( KIMAP::LoginJob::SslV3_1 ); - } else if ( overrideEncryptionMode == QLatin1String("SSL") ) { - account->setEncryptionMode( KIMAP::LoginJob::AnySslVersion ); - } else if ( overrideEncryptionMode == QLatin1String("STARTTLS") ) { - account->setEncryptionMode( KIMAP::LoginJob::TlsV1 ); - } else if ( overrideEncryptionMode == QLatin1String("UNENCRYPTED") ) { - account->setEncryptionMode( KIMAP::LoginJob::Unencrypted ); + account->setServer(imapServer()); + if (imapPort() >= 0) { + account->setPort(imapPort()); + } + + account->setUserName(userName()); + account->setSubscriptionEnabled(subscriptionEnabled()); + + const QString encryption = safety(); + if (encryption == QLatin1String("SSL")) { + account->setEncryptionMode(KIMAP::LoginJob::AnySslVersion); + } else if (encryption == QLatin1String("STARTTLS")) { + //KIMAP confused TLS and STARTTLS, TlsV1 really means "use STARTTLS" + account->setEncryptionMode(KIMAP::LoginJob::TlsV1); } else { - kWarning() << "Tried to force invalid encryption mode: " << overrideEncryptionMode; + account->setEncryptionMode(KIMAP::LoginJob::Unencrypted); } - } - account->setAuthenticationMode( - mapTransportAuthToKimap( - (MailTransport::TransportBase::EnumAuthenticationType::type) authentication() - ) - ); + //Some SSL Server fail to advertise an ssl version they support (AnySslVersion), + //we therefore allow overriding this in the config + //(so we don't have to make the UI unnecessarily complex for properly working servers). + const QString overrideEncryptionMode = overrideEncryption(); + if (!overrideEncryptionMode.isEmpty()) { + qCWarning(IMAPRESOURCE_LOG) << "Overriding encryption mode with: " << overrideEncryptionMode; + if (overrideEncryptionMode == QLatin1String("SSLV2")) { + account->setEncryptionMode(KIMAP::LoginJob::SslV2); + } else if (overrideEncryptionMode == QLatin1String("SSLV3")) { + account->setEncryptionMode(KIMAP::LoginJob::SslV3); + } else if (overrideEncryptionMode == QLatin1String("TLSV1")) { + account->setEncryptionMode(KIMAP::LoginJob::SslV3_1); + } else if (overrideEncryptionMode == QLatin1String("SSL")) { + account->setEncryptionMode(KIMAP::LoginJob::AnySslVersion); + } else if (overrideEncryptionMode == QLatin1String("STARTTLS")) { + account->setEncryptionMode(KIMAP::LoginJob::TlsV1); + } else if (overrideEncryptionMode == QLatin1String("UNENCRYPTED")) { + account->setEncryptionMode(KIMAP::LoginJob::Unencrypted); + } else { + qCWarning(IMAPRESOURCE_LOG) << "Tried to force invalid encryption mode: " << overrideEncryptionMode; + } + } - account->setTimeout( sessionTimeout() ); + account->setAuthenticationMode( + mapTransportAuthToKimap( + (MailTransport::TransportBase::EnumAuthenticationType::type) authentication() + ) + ); + + account->setTimeout(sessionTimeout()); } QString Settings::rootRemoteId() const { - return QLatin1String("imap://") + userName() + QLatin1Char('@') + imapServer() + QLatin1Char('/'); + return QStringLiteral("imap://") + userName() + QLatin1Char('@') + imapServer() + QLatin1Char('/'); } -void Settings::renameRootCollection( const QString &newName ) +void Settings::renameRootCollection(const QString &newName) { - Akonadi::Collection rootCollection; - rootCollection.setRemoteId( rootRemoteId() ); - Akonadi::CollectionFetchJob *fetchJob = - new Akonadi::CollectionFetchJob( rootCollection, Akonadi::CollectionFetchJob::Base ); - fetchJob->setProperty( "collectionName", newName ); - connect( fetchJob, SIGNAL(result(KJob*)), - this, SLOT(onRootCollectionFetched(KJob*)) ); -} - -void Settings::onRootCollectionFetched( KJob *job ) -{ - const QString newName = job->property( "collectionName" ).toString(); - Q_ASSERT( !newName.isEmpty() ); - Akonadi::CollectionFetchJob *fetchJob = static_cast( job ); - if ( fetchJob->collections().size() == 1 ) { - Akonadi::Collection rootCollection = fetchJob->collections().first(); - rootCollection.setName( newName ); - new Akonadi::CollectionModifyJob( rootCollection ); - // We don't care about the result here, nothing we can/should do if the renaming fails - } + Akonadi::Collection rootCollection; + rootCollection.setRemoteId(rootRemoteId()); + Akonadi::CollectionFetchJob *fetchJob = + new Akonadi::CollectionFetchJob(rootCollection, Akonadi::CollectionFetchJob::Base); + fetchJob->setProperty("collectionName", newName); + connect(fetchJob, &KJob::result, + this, &Settings::onRootCollectionFetched); +} + +void Settings::onRootCollectionFetched(KJob *job) +{ + const QString newName = job->property("collectionName").toString(); + Q_ASSERT(!newName.isEmpty()); + Akonadi::CollectionFetchJob *fetchJob = static_cast(job); + if (fetchJob->collections().size() == 1) { + Akonadi::Collection rootCollection = fetchJob->collections().at(0); + rootCollection.setName(newName); + new Akonadi::CollectionModifyJob(rootCollection); + // We don't care about the result here, nothing we can/should do if the renaming fails + } } diff -Nru kdepim-runtime-4.14.6/resources/imap/settings.h kdepim-runtime-15.08.0/resources/imap/settings.h --- kdepim-runtime-4.14.6/resources/imap/settings.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/settings.h 2015-08-10 21:01:02.000000000 +0000 @@ -31,39 +31,39 @@ class Settings : public SettingsBase { - Q_OBJECT - Q_CLASSINFO( "D-Bus Interface", "org.kde.Akonadi.Imap.Wallet" ) + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.Akonadi.Imap.Wallet") public: - static KIMAP::LoginJob::AuthenticationMode mapTransportAuthToKimap( MailTransport::Transport::EnumAuthenticationType::type authType ); + static KIMAP::LoginJob::AuthenticationMode mapTransportAuthToKimap(MailTransport::Transport::EnumAuthenticationType::type authType); - explicit Settings( WId = 0 ); - void setWinId( WId ); + explicit Settings(WId = 0); + void setWinId(WId); virtual void requestPassword(); virtual void requestManualAuth(); - virtual void loadAccount( ImapAccount *account ) const; + virtual void loadAccount(ImapAccount *account) const; QString rootRemoteId() const; - virtual void renameRootCollection( const QString &newName ); + virtual void renameRootCollection(const QString &newName); virtual void clearCachedPassword(); virtual void cleanup(); -signals: - void passwordRequestCompleted( const QString &password, bool userRejected ); +Q_SIGNALS: + void passwordRequestCompleted(const QString &password, bool userRejected); -public slots: - Q_SCRIPTABLE virtual QString password( bool *userRejected = 0 ) const; - Q_SCRIPTABLE virtual void setPassword( const QString &password ); - Q_SCRIPTABLE virtual void setSieveCustomPassword(const QString & password); - Q_SCRIPTABLE virtual QString sieveCustomPassword( bool *userRejected = 0 ) const; - -protected slots: - virtual void onWalletOpened( bool success ); - virtual void onDialogFinished( int result ); +public Q_SLOTS: + Q_SCRIPTABLE virtual QString password(bool *userRejected = Q_NULLPTR) const; + Q_SCRIPTABLE virtual void setPassword(const QString &password); + Q_SCRIPTABLE virtual void setSieveCustomPassword(const QString &password); + Q_SCRIPTABLE virtual QString sieveCustomPassword(bool *userRejected = Q_NULLPTR) const; + +protected Q_SLOTS: + virtual void onWalletOpened(bool success); + virtual void onDialogFinished(int result); - void onRootCollectionFetched( KJob *job ); + void onRootCollectionFetched(KJob *job); protected: WId m_winId; diff -Nru kdepim-runtime-4.14.6/resources/imap/settingspasswordrequester.cpp kdepim-runtime-15.08.0/resources/imap/settingspasswordrequester.cpp --- kdepim-runtime-4.14.6/resources/imap/settingspasswordrequester.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/settingspasswordrequester.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,122 +21,137 @@ #include "settingspasswordrequester.h" -#include -#include -#include +#include +#include +#include #include #include +#include "imapresource_debug.h" +#include +#include +#include +#include #include "imapresourcebase.h" #include "settings.h" -SettingsPasswordRequester::SettingsPasswordRequester( ImapResourceBase *resource, QObject *parent ) - : PasswordRequesterInterface( parent ), m_resource( resource ), m_requestDialog( 0 ), m_settingsDialog( 0 ) +SettingsPasswordRequester::SettingsPasswordRequester(ImapResourceBase *resource, QObject *parent) + : PasswordRequesterInterface(parent), m_resource(resource), m_requestDialog(Q_NULLPTR), m_settingsDialog(Q_NULLPTR) { } SettingsPasswordRequester::~SettingsPasswordRequester() { - cancelPasswordRequests(); + cancelPasswordRequests(); } -void SettingsPasswordRequester::requestPassword( RequestType request, const QString &serverError ) +void SettingsPasswordRequester::requestPassword(RequestType request, const QString &serverError) { - if ( request == WrongPasswordRequest ) { - QMetaObject::invokeMethod( this, "askUserInput", Qt::QueuedConnection, Q_ARG(QString, serverError) ); - } else { - connect( m_resource->settings(), SIGNAL(passwordRequestCompleted(QString,bool)), - this, SLOT(onPasswordRequestCompleted(QString,bool)) ); - m_resource->settings()->requestPassword(); - } -} - -void SettingsPasswordRequester::askUserInput( const QString &serverError ) -{ - // the credentials were not ok, allow to retry or change password - if ( m_requestDialog ) { - kDebug() << "Password request dialog is already open"; - return; - } - QWidget *parent = QWidget::find(m_resource->winIdForDialogs()); - QString text = i18n( "The server for account \"%2\" refused the supplied username and password. " - "Do you want to go to the settings, have another attempt " - "at logging in, or do nothing?\n\n" - "%1", serverError, m_resource->name() ); - KDialog *dialog = new KDialog(parent, Qt::Dialog); - dialog->setCaption(i18n( "Could Not Authenticate" )); - dialog->setButtons(KDialog::Yes|KDialog::No|KDialog::Cancel); - dialog->setDefaultButton(KDialog::Yes); - dialog->setButtonText(KDialog::Yes, i18n( "Account Settings" )); - dialog->setButtonText(KDialog::No, i18nc( "Input username/password manually and not store them", "Try Again" )); - dialog->setAttribute(Qt::WA_DeleteOnClose); - connect(dialog, SIGNAL(buttonClicked(KDialog::ButtonCode)), this, SLOT(onButtonClicked(KDialog::ButtonCode))); - connect(dialog, SIGNAL(destroyed(QObject*)), this, SLOT(onDialogDestroyed())); - m_requestDialog = dialog; - KWindowSystem::setMainWindow(dialog, m_resource->winIdForDialogs()); - bool checkboxResult = false; - KMessageBox::createKMessageBox(dialog, QMessageBox::Information, - text, QStringList(), - QString(), - &checkboxResult, KMessageBox::NoExec); - dialog->show(); + if (request == WrongPasswordRequest) { + QMetaObject::invokeMethod(this, "askUserInput", Qt::QueuedConnection, Q_ARG(QString, serverError)); + } else { + connect(m_resource->settings(), &Settings::passwordRequestCompleted, + this, &SettingsPasswordRequester::onPasswordRequestCompleted); + m_resource->settings()->requestPassword(); + } +} + +void SettingsPasswordRequester::askUserInput(const QString &serverError) +{ + // the credentials were not ok, allow to retry or change password + if (m_requestDialog) { + qCDebug(IMAPRESOURCE_LOG) << "Password request dialog is already open"; + return; + } + QWidget *parent = QWidget::find(m_resource->winIdForDialogs()); + QString text = i18n("The server for account \"%2\" refused the supplied username and password. " + "Do you want to go to the settings, have another attempt " + "at logging in, or do nothing?\n\n" + "%1", serverError, m_resource->name()); + QDialog *dialog = new QDialog(parent, Qt::Dialog); + dialog->setWindowTitle(i18n("Could Not Authenticate")); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::No | QDialogButtonBox::Yes); + buttonBox->button(QDialogButtonBox::Yes)->setDefault(true); + + buttonBox->button(QDialogButtonBox::Yes)->setText(i18n("Account Settings")); + buttonBox->button(QDialogButtonBox::No)->setText(i18nc("Input username/password manually and not store them", "Try Again")); + dialog->setAttribute(Qt::WA_DeleteOnClose); + connect(buttonBox->button(QDialogButtonBox::Yes), &QPushButton::clicked, this, &SettingsPasswordRequester::slotYesClicked); + connect(buttonBox->button(QDialogButtonBox::No), &QPushButton::clicked, this, &SettingsPasswordRequester::slotNoClicked); + connect(buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &SettingsPasswordRequester::slotCancelClicked); + + connect(dialog, &QDialog::destroyed, this, &SettingsPasswordRequester::onDialogDestroyed); + m_requestDialog = dialog; + KWindowSystem::setMainWindow(dialog, m_resource->winIdForDialogs()); + bool checkboxResult = false; + KMessageBox::createKMessageBox(dialog, buttonBox, QMessageBox::Information, + text, QStringList(), + QString(), + &checkboxResult, KMessageBox::NoExec); + dialog->show(); } void SettingsPasswordRequester::onDialogDestroyed() { - m_requestDialog = 0; + m_requestDialog = Q_NULLPTR; } -void SettingsPasswordRequester::onButtonClicked(KDialog::ButtonCode result) +void SettingsPasswordRequester::slotNoClicked() { - if ( result == KDialog::Yes ) { - if (!m_settingsDialog) { - KDialog *dialog = m_resource->createConfigureDialog(m_resource->winIdForDialogs()); - connect(dialog, SIGNAL(finished(int)), this, SLOT(onSettingsDialogFinished(int))); - m_settingsDialog = dialog; - dialog->show(); - } - } else if ( result == KDialog::No ) { - connect( m_resource->settings(), SIGNAL(passwordRequestCompleted(QString,bool)), - this, SLOT(onPasswordRequestCompleted(QString,bool)) ); + connect(m_resource->settings(), &Settings::passwordRequestCompleted, + this, &SettingsPasswordRequester::onPasswordRequestCompleted); m_resource->settings()->requestManualAuth(); - } else { - emit done( UserRejected ); - } - m_requestDialog = 0; + m_requestDialog = Q_NULLPTR; +} + +void SettingsPasswordRequester::slotYesClicked() +{ + if (!m_settingsDialog) { + QDialog *dialog = m_resource->createConfigureDialog(m_resource->winIdForDialogs()); + connect(dialog, &QDialog::finished, this, &SettingsPasswordRequester::onSettingsDialogFinished); + m_settingsDialog = dialog; + dialog->show(); + } + m_requestDialog = Q_NULLPTR; +} + +void SettingsPasswordRequester::slotCancelClicked() +{ + Q_EMIT done(UserRejected); + m_requestDialog = Q_NULLPTR; } void SettingsPasswordRequester::onSettingsDialogFinished(int result) { - m_settingsDialog = 0; - if (result == QDialog::Accepted) { - emit done( ReconnectNeeded ); - } else { - emit done( UserRejected ); - } + m_settingsDialog = Q_NULLPTR; + if (result == QDialog::Accepted) { + Q_EMIT done(ReconnectNeeded); + } else { + Q_EMIT done(UserRejected); + } } void SettingsPasswordRequester::cancelPasswordRequests() { - if (m_requestDialog) { - if (m_requestDialog->close()) { - m_requestDialog = 0; + if (m_requestDialog) { + if (m_requestDialog->close()) { + m_requestDialog = Q_NULLPTR; + } } - } } -void SettingsPasswordRequester::onPasswordRequestCompleted( const QString &password, bool userRejected ) +void SettingsPasswordRequester::onPasswordRequestCompleted(const QString &password, bool userRejected) { - disconnect( m_resource->settings(), SIGNAL(passwordRequestCompleted(QString,bool)), - this, SLOT(onPasswordRequestCompleted(QString,bool)) ); + disconnect(m_resource->settings(), &Settings::passwordRequestCompleted, + this, &SettingsPasswordRequester::onPasswordRequestCompleted); - if ( userRejected ) { - emit done( UserRejected ); - } else if ( password.isEmpty() && (m_resource->settings()->authentication() != MailTransport::Transport::EnumAuthenticationType::GSSAPI) ) { - emit done( EmptyPasswordEntered ); - } else { - emit done( PasswordRetrieved, password ); - } + if (userRejected) { + Q_EMIT done(UserRejected); + } else if (password.isEmpty() && (m_resource->settings()->authentication() != MailTransport::Transport::EnumAuthenticationType::GSSAPI)) { + Q_EMIT done(EmptyPasswordEntered); + } else { + Q_EMIT done(PasswordRetrieved, password); + } } diff -Nru kdepim-runtime-4.14.6/resources/imap/settingspasswordrequester.h kdepim-runtime-15.08.0/resources/imap/settingspasswordrequester.h --- kdepim-runtime-4.14.6/resources/imap/settingspasswordrequester.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/settingspasswordrequester.h 2015-08-10 21:01:02.000000000 +0000 @@ -23,33 +23,35 @@ #define SETTINGSPASSWORDREQUESTER_H #include -#include +#include class ImapResourceBase; class SettingsPasswordRequester : public PasswordRequesterInterface { - Q_OBJECT + Q_OBJECT public: - explicit SettingsPasswordRequester( ImapResourceBase *resource, QObject *parent = 0 ); - virtual ~SettingsPasswordRequester(); + explicit SettingsPasswordRequester(ImapResourceBase *resource, QObject *parent = Q_NULLPTR); + virtual ~SettingsPasswordRequester(); - virtual void requestPassword( RequestType request = StandardRequest, - const QString &serverError = QString() ); - virtual void cancelPasswordRequests(); - -private slots: - void askUserInput( const QString &serverError ); - void onPasswordRequestCompleted( const QString &password, bool userRejected ); - void onButtonClicked(KDialog::ButtonCode); - void onDialogDestroyed(); - void onSettingsDialogFinished(int result); + virtual void requestPassword(RequestType request = StandardRequest, + const QString &serverError = QString()) Q_DECL_OVERRIDE; + void cancelPasswordRequests() Q_DECL_OVERRIDE; + +private Q_SLOTS: + void askUserInput(const QString &serverError); + void onPasswordRequestCompleted(const QString &password, bool userRejected); + void onDialogDestroyed(); + void slotCancelClicked(); + void slotYesClicked(); + void slotNoClicked(); + void onSettingsDialogFinished(int result); private: - ImapResourceBase *m_resource; - KDialog *m_requestDialog; - KDialog *m_settingsDialog; + ImapResourceBase *m_resource; + QDialog *m_requestDialog; + QDialog *m_settingsDialog; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/setupserver.cpp kdepim-runtime-15.08.0/resources/imap/setupserver.cpp --- kdepim-runtime-4.14.6/resources/imap/setupserver.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/setupserver.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -32,31 +32,30 @@ #include "settings.h" #include "imapresource.h" #include "serverinfodialog.h" -#include "resources/folderarchivesettings/folderarchivesettingpage.h" - +#include "folderarchivesettingpage.h" #include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include -#include -#include +#include +#include #include #include -#ifndef IMAPRESOURCE_NO_SOLID +#include "imapresource_debug.h" #include -#endif -#include -#include +#include +#include +#include #include "imapaccount.h" #include "subscriptiondialog.h" @@ -69,174 +68,174 @@ #include "ui_serverinfo.h" /** static helper functions **/ -static QString authenticationModeString( MailTransport::Transport::EnumAuthenticationType::type mode ) +static QString authenticationModeString(MailTransport::Transport::EnumAuthenticationType::type mode) { - switch ( mode ) { + switch (mode) { case MailTransport::Transport::EnumAuthenticationType::LOGIN: - return QLatin1String("LOGIN"); + return QStringLiteral("LOGIN"); case MailTransport::Transport::EnumAuthenticationType::PLAIN: - return QLatin1String("PLAIN"); + return QStringLiteral("PLAIN"); case MailTransport::Transport::EnumAuthenticationType::CRAM_MD5: - return QLatin1String("CRAM-MD5"); + return QStringLiteral("CRAM-MD5"); case MailTransport::Transport::EnumAuthenticationType::DIGEST_MD5: - return QLatin1String("DIGEST-MD5"); + return QStringLiteral("DIGEST-MD5"); case MailTransport::Transport::EnumAuthenticationType::GSSAPI: - return QLatin1String("GSSAPI"); + return QStringLiteral("GSSAPI"); case MailTransport::Transport::EnumAuthenticationType::NTLM: - return QLatin1String("NTLM"); + return QStringLiteral("NTLM"); case MailTransport::Transport::EnumAuthenticationType::CLEAR: - return i18nc( "Authentication method", "Clear text" ); + return i18nc("Authentication method", "Clear text"); case MailTransport::Transport::EnumAuthenticationType::ANONYMOUS: - return i18nc( "Authentication method", "Anonymous" ); + return i18nc("Authentication method", "Anonymous"); default: - break; - } - return QString(); -} - -static void setCurrentAuthMode( QComboBox* authCombo, MailTransport::Transport::EnumAuthenticationType::type authtype ) -{ - kDebug() << "setting authcombo: " << authenticationModeString( authtype ); - int index = authCombo->findData( authtype ); - if ( index == -1 ) - kWarning() << "desired authmode not in the combo"; - kDebug() << "found corresponding index: " << index << "with data" << authenticationModeString( (MailTransport::Transport::EnumAuthenticationType::type) authCombo->itemData( index ).toInt() ); - authCombo->setCurrentIndex( index ); - MailTransport::Transport::EnumAuthenticationType::type t = (MailTransport::Transport::EnumAuthenticationType::type) authCombo->itemData( authCombo->currentIndex() ).toInt(); - kDebug() << "selected auth mode:" << authenticationModeString( t ); - Q_ASSERT( t == authtype ); -} - -static MailTransport::Transport::EnumAuthenticationType::type getCurrentAuthMode( QComboBox* authCombo ) -{ - MailTransport::Transport::EnumAuthenticationType::type authtype = (MailTransport::Transport::EnumAuthenticationType::type) authCombo->itemData( authCombo->currentIndex() ).toInt(); - kDebug() << "current auth mode: " << authenticationModeString( authtype ); - return authtype; -} - -static void addAuthenticationItem( QComboBox* authCombo, MailTransport::Transport::EnumAuthenticationType::type authtype ) -{ - kDebug() << "adding auth item " << authenticationModeString( authtype ); - authCombo->addItem( authenticationModeString( authtype ), QVariant( authtype ) ); -} - -SetupServer::SetupServer( ImapResourceBase *parentResource, WId parent ) - : KDialog(), m_parentResource( parentResource ), m_ui(new Ui::SetupServerView), m_serverTest(0), - m_subscriptionsChanged(false), m_shouldClearCache(false), mValidator( this ) -{ - m_parentResource->settings()->setWinId( parent ); - m_ui->setupUi( mainWidget() ); - m_folderArchiveSettingPage = new FolderArchiveSettingPage(m_parentResource->identifier()); - m_ui->tabWidget->addTab(m_folderArchiveSettingPage, i18n("Folder Archive")); - m_ui->safeImapGroup->setId( m_ui->noRadio, KIMAP::LoginJob::Unencrypted ); - m_ui->safeImapGroup->setId( m_ui->sslRadio, KIMAP::LoginJob::AnySslVersion ); - m_ui->safeImapGroup->setId( m_ui->tlsRadio, KIMAP::LoginJob::TlsV1 ); - - connect( m_ui->noRadio, SIGNAL(toggled(bool)), - this, SLOT(slotSafetyChanged()) ); - connect( m_ui->sslRadio, SIGNAL(toggled(bool)), - this, SLOT(slotSafetyChanged()) ); - connect( m_ui->tlsRadio, SIGNAL(toggled(bool)), - this, SLOT(slotSafetyChanged()) ); - - m_ui->testInfo->hide(); - m_ui->testProgress->hide(); - m_ui->accountName->setFocus(); - m_ui->checkInterval->setSuffix( ki18np( " minute", " minutes" ) ); - m_ui->checkInterval->setRange( Akonadi::ResourceSettings::self()->minimumCheckInterval(), 10000, 1 ); - - // regex for evaluating a valid server name/ip - mValidator.setRegExp( QRegExp( QLatin1String("[A-Za-z0-9-_:.]*") ) ); - m_ui->imapServer->setValidator( &mValidator ); - - m_ui->folderRequester->setMimeTypeFilter( - QStringList() << KMime::Message::mimeType() ); - m_ui->folderRequester->setAccessRightsFilter( Akonadi::Collection::CanChangeItem | Akonadi::Collection::CanCreateItem | Akonadi::Collection::CanDeleteItem ); - m_ui->folderRequester->changeCollectionDialogOptions( Akonadi::CollectionDialog::AllowToCreateNewChildCollection ); - m_identityManager = new KPIMIdentities::IdentityManager( false, this, "mIdentityManager" ); - m_identityCombobox = new KPIMIdentities::IdentityCombo( m_identityManager, this ); - m_ui->identityLabel->setBuddy( m_identityCombobox ); - m_ui->identityLayout->addWidget( m_identityCombobox, 1 ); - m_ui->identityLabel->setBuddy( m_identityCombobox ); - - - connect( m_ui->testButton, SIGNAL(pressed()), SLOT(slotTest()) ); - - connect( m_ui->imapServer, SIGNAL(textChanged(QString)), - SLOT(slotTestChanged()) ); - connect( m_ui->imapServer, SIGNAL(textChanged(QString)), - SLOT(slotComplete()) ); - connect( m_ui->userName, SIGNAL(textChanged(QString)), - SLOT(slotComplete()) ); - connect( m_ui->subscriptionEnabled, SIGNAL(toggled(bool)), this, SLOT(slotSubcriptionCheckboxChanged()) ); - connect( m_ui->subscriptionButton, SIGNAL(pressed()), SLOT(slotManageSubscriptions()) ); - - connect( m_ui->managesieveCheck, SIGNAL(toggled(bool)), - SLOT(slotEnableWidgets()) ); - connect( m_ui->sameConfigCheck, SIGNAL(toggled(bool)), - SLOT(slotEnableWidgets()) ); - - - connect( m_ui->useDefaultIdentityCheck, SIGNAL(toggled(bool)), this, SLOT(slotIdentityCheckboxChanged()) ); - connect( m_ui->enableMailCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotMailCheckboxChanged()) ); - connect( m_ui->safeImapGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotEncryptionRadioChanged()) ); - connect( m_ui->customSieveGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotCustomSieveChanged()) ); - connect( m_ui->showServerInfo, SIGNAL(pressed()), this, SLOT(slotShowServerInfo()) ); - - readSettings(); - slotTestChanged(); - slotComplete(); - slotCustomSieveChanged(); -#ifndef IMAPRESOURCE_NO_SOLID - connect( Solid::Networking::notifier(), - SIGNAL(statusChanged(Solid::Networking::Status)), - SLOT(slotTestChanged()) ); -#endif - connect( this, SIGNAL(applyClicked()), - SLOT(applySettings()) ); - connect( this, SIGNAL(okClicked()), - SLOT(applySettings()) ); + break; + } + return QString(); +} + +static void setCurrentAuthMode(QComboBox *authCombo, MailTransport::Transport::EnumAuthenticationType::type authtype) +{ + qCDebug(IMAPRESOURCE_LOG) << "setting authcombo: " << authenticationModeString(authtype); + int index = authCombo->findData(authtype); + if (index == -1) { + qCWarning(IMAPRESOURCE_LOG) << "desired authmode not in the combo"; + } + qCDebug(IMAPRESOURCE_LOG) << "found corresponding index: " << index << "with data" << authenticationModeString((MailTransport::Transport::EnumAuthenticationType::type) authCombo->itemData(index).toInt()); + authCombo->setCurrentIndex(index); + MailTransport::Transport::EnumAuthenticationType::type t = (MailTransport::Transport::EnumAuthenticationType::type) authCombo->itemData(authCombo->currentIndex()).toInt(); + qCDebug(IMAPRESOURCE_LOG) << "selected auth mode:" << authenticationModeString(t); + Q_ASSERT(t == authtype); +} + +static MailTransport::Transport::EnumAuthenticationType::type getCurrentAuthMode(QComboBox *authCombo) +{ + MailTransport::Transport::EnumAuthenticationType::type authtype = (MailTransport::Transport::EnumAuthenticationType::type) authCombo->itemData(authCombo->currentIndex()).toInt(); + qCDebug(IMAPRESOURCE_LOG) << "current auth mode: " << authenticationModeString(authtype); + return authtype; +} + +static void addAuthenticationItem(QComboBox *authCombo, MailTransport::Transport::EnumAuthenticationType::type authtype) +{ + qCDebug(IMAPRESOURCE_LOG) << "adding auth item " << authenticationModeString(authtype); + authCombo->addItem(authenticationModeString(authtype), QVariant(authtype)); +} + +SetupServer::SetupServer(ImapResourceBase *parentResource, WId parent) + : QDialog(), m_parentResource(parentResource), m_ui(new Ui::SetupServerView), m_serverTest(Q_NULLPTR), + m_subscriptionsChanged(false), m_shouldClearCache(false), mValidator(this) +{ + m_parentResource->settings()->setWinId(parent); + QWidget *mainWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + mOkButton = buttonBox->button(QDialogButtonBox::Ok); + mOkButton->setDefault(true); + mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &SetupServer::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &SetupServer::reject); + mainLayout->addWidget(buttonBox); + + m_ui->setupUi(mainWidget); + m_folderArchiveSettingPage = new FolderArchiveSettingPage(m_parentResource->identifier()); + m_ui->tabWidget->addTab(m_folderArchiveSettingPage, i18n("Folder Archive")); + m_ui->safeImapGroup->setId(m_ui->noRadio, KIMAP::LoginJob::Unencrypted); + m_ui->safeImapGroup->setId(m_ui->sslRadio, KIMAP::LoginJob::AnySslVersion); + m_ui->safeImapGroup->setId(m_ui->tlsRadio, KIMAP::LoginJob::TlsV1); + + connect(m_ui->noRadio, &QRadioButton::toggled, this, &SetupServer::slotSafetyChanged); + connect(m_ui->sslRadio, &QRadioButton::toggled, this, &SetupServer::slotSafetyChanged); + connect(m_ui->tlsRadio, &QRadioButton::toggled, this, &SetupServer::slotSafetyChanged); + + m_ui->testInfo->hide(); + m_ui->testProgress->hide(); + m_ui->accountName->setFocus(); + m_ui->checkInterval->setSuffix(ki18np(" minute", " minutes")); + m_ui->checkInterval->setMinimum(Akonadi::ResourceSettings::self()->minimumCheckInterval()); + m_ui->checkInterval->setMaximum(10000); + m_ui->checkInterval->setSingleStep(1); + + // regex for evaluating a valid server name/ip + mValidator.setRegExp(QRegExp(QLatin1String("[A-Za-z0-9-_:.]*"))); + m_ui->imapServer->setValidator(&mValidator); + + m_ui->folderRequester->setMimeTypeFilter( + QStringList() << KMime::Message::mimeType()); + m_ui->folderRequester->setAccessRightsFilter(Akonadi::Collection::CanChangeItem | Akonadi::Collection::CanCreateItem | Akonadi::Collection::CanDeleteItem); + m_ui->folderRequester->changeCollectionDialogOptions(Akonadi::CollectionDialog::AllowToCreateNewChildCollection); + m_identityManager = new KIdentityManagement::IdentityManager(false, this, "mIdentityManager"); + m_identityCombobox = new KIdentityManagement::IdentityCombo(m_identityManager, this); + m_ui->identityLabel->setBuddy(m_identityCombobox); + m_ui->identityLayout->addWidget(m_identityCombobox, 1); + m_ui->identityLabel->setBuddy(m_identityCombobox); + + connect(m_ui->testButton, &QPushButton::pressed, this, &SetupServer::slotTest); + + connect(m_ui->imapServer, &KLineEdit::textChanged, this, &SetupServer::slotTestChanged); + connect(m_ui->imapServer, &KLineEdit::textChanged, this, &SetupServer::slotComplete); + connect(m_ui->userName, &KLineEdit::textChanged, this, &SetupServer::slotComplete); + connect(m_ui->subscriptionEnabled, &QCheckBox::toggled, this, &SetupServer::slotSubcriptionCheckboxChanged); + connect(m_ui->subscriptionButton, &QPushButton::pressed, this, &SetupServer::slotManageSubscriptions); + + connect(m_ui->managesieveCheck, &QCheckBox::toggled, this, &SetupServer::slotEnableWidgets); + connect(m_ui->sameConfigCheck, &QCheckBox::toggled, this, &SetupServer::slotEnableWidgets); + + connect(m_ui->useDefaultIdentityCheck, &QCheckBox::toggled, this, &SetupServer::slotIdentityCheckboxChanged); + connect(m_ui->enableMailCheckBox, &QCheckBox::toggled, this, &SetupServer::slotMailCheckboxChanged); + connect(m_ui->safeImapGroup, static_cast(&QButtonGroup::buttonClicked), this, &SetupServer::slotEncryptionRadioChanged); + connect(m_ui->customSieveGroup, static_cast(&QButtonGroup::buttonClicked), this, &SetupServer::slotCustomSieveChanged); + connect(m_ui->showServerInfo, &QPushButton::pressed, this, &SetupServer::slotShowServerInfo); + + readSettings(); + slotTestChanged(); + slotComplete(); + slotCustomSieveChanged(); + connect(Solid::Networking::notifier(), + SIGNAL(statusChanged(Solid::Networking::Status)), + SLOT(slotTestChanged())); + connect(mOkButton, &QPushButton::clicked, this, &SetupServer::applySettings); } SetupServer::~SetupServer() { - delete m_ui; + delete m_ui; } bool SetupServer::shouldClearCache() const { - return m_shouldClearCache; + return m_shouldClearCache; } void SetupServer::slotSubcriptionCheckboxChanged() { - m_ui->subscriptionButton->setEnabled( m_ui->subscriptionEnabled->isChecked() ); + m_ui->subscriptionButton->setEnabled(m_ui->subscriptionEnabled->isChecked()); } void SetupServer::slotIdentityCheckboxChanged() { - m_identityCombobox->setEnabled( !m_ui->useDefaultIdentityCheck->isChecked() ); + m_identityCombobox->setEnabled(!m_ui->useDefaultIdentityCheck->isChecked()); } void SetupServer::slotMailCheckboxChanged() { - m_ui->checkInterval->setEnabled( m_ui->enableMailCheckBox->isChecked() ); + m_ui->checkInterval->setEnabled(m_ui->enableMailCheckBox->isChecked()); } void SetupServer::slotEncryptionRadioChanged() { - // TODO these really should be defined somewhere else - switch ( m_ui->safeImapGroup->checkedId() ) { + // TODO these really should be defined somewhere else + switch (m_ui->safeImapGroup->checkedId()) { case KIMAP::LoginJob::Unencrypted: case KIMAP::LoginJob::TlsV1: - m_ui->portSpin->setValue( 143 ); - break; + m_ui->portSpin->setValue(143); + break; case KIMAP::LoginJob::AnySslVersion: - m_ui->portSpin->setValue( 993 ); - break; - default: - kFatal() << "Shouldn't happen"; - } + m_ui->portSpin->setValue(993); + break; + default: + qFatal("Shouldn't happen"); + } } void SetupServer::slotCustomSieveChanged() @@ -244,7 +243,7 @@ QAbstractButton *checkedButton = m_ui->customSieveGroup->checkedButton(); if (checkedButton == m_ui->imapUserPassword || - checkedButton == m_ui->noAuthentification ) { + checkedButton == m_ui->noAuthentification) { m_ui->customUsername->setEnabled(false); m_ui->customPassword->setEnabled(false); } else if (checkedButton == m_ui->customUserPassword) { @@ -255,406 +254,419 @@ void SetupServer::applySettings() { - m_folderArchiveSettingPage->writeSettings(); - m_shouldClearCache = ( m_parentResource->settings()->imapServer() != m_ui->imapServer->text() ) - || ( m_parentResource->settings()->userName() != m_ui->userName->text() ); - - m_parentResource->setName( m_ui->accountName->text() ); - - m_parentResource->settings()->setImapServer( m_ui->imapServer->text() ); - m_parentResource->settings()->setImapPort( m_ui->portSpin->value() ); - m_parentResource->settings()->setUserName( m_ui->userName->text() ); - QString encryption; - switch ( m_ui->safeImapGroup->checkedId() ) { - case KIMAP::LoginJob::Unencrypted : - encryption = QLatin1String("None"); - break; - case KIMAP::LoginJob::AnySslVersion: - encryption = QLatin1String("SSL"); - break; - case KIMAP::LoginJob::TlsV1: - encryption = QLatin1String("STARTTLS"); - break; - default: - kFatal() << "Shouldn't happen"; - } - m_parentResource->settings()->setSafety( encryption ); - MailTransport::Transport::EnumAuthenticationType::type authtype = getCurrentAuthMode( m_ui->authenticationCombo ); - kDebug() << "saving IMAP auth mode: " << authenticationModeString( authtype ); - m_parentResource->settings()->setAuthentication( authtype ); - m_parentResource->settings()->setPassword( m_ui->password->text() ); - m_parentResource->settings()->setSubscriptionEnabled( m_ui->subscriptionEnabled->isChecked() ); - m_parentResource->settings()->setIntervalCheckTime( m_ui->checkInterval->value() ); - m_parentResource->settings()->setDisconnectedModeEnabled( m_ui->disconnectedModeEnabled->isChecked() ); - - m_parentResource->settings()->setSieveSupport( m_ui->managesieveCheck->isChecked() ); - m_parentResource->settings()->setSieveReuseConfig( m_ui->sameConfigCheck->isChecked() ); - m_parentResource->settings()->setSievePort( m_ui->sievePortSpin->value() ); - m_parentResource->settings()->setSieveAlternateUrl( m_ui->alternateURL->text() ); - m_parentResource->settings()->setSieveVacationFilename( m_vacationFileName ); - - m_parentResource->settings()->setTrashCollection( m_ui->folderRequester->collection().id() ); - Akonadi::Collection trash = m_ui->folderRequester->collection(); - Akonadi::SpecialMailCollections::self()->registerCollection(Akonadi::SpecialMailCollections::Trash, trash); - Akonadi::EntityDisplayAttribute *attribute = trash.attribute( Akonadi::Entity::AddIfMissing ); - attribute->setIconName( QLatin1String( "user-trash" ) ); - new Akonadi::CollectionModifyJob( trash ); - if (mOldTrash != trash) { - Akonadi::SpecialMailCollections::self()->unregisterCollection(mOldTrash); - } - - m_parentResource->settings()->setAutomaticExpungeEnabled( m_ui->autoExpungeCheck->isChecked() ); - m_parentResource->settings()->setUseDefaultIdentity( m_ui->useDefaultIdentityCheck->isChecked() ); - - if ( !m_ui->useDefaultIdentityCheck->isChecked() ) - m_parentResource->settings()->setAccountIdentity( m_identityCombobox->currentIdentity() ); - - m_parentResource->settings()->setIntervalCheckEnabled( m_ui->enableMailCheckBox->isChecked() ); - if ( m_ui->enableMailCheckBox->isChecked() ) - m_parentResource->settings()->setIntervalCheckTime( m_ui->checkInterval->value() ); - - m_parentResource->settings()->setSieveCustomUsername(m_ui->customUsername->text()); - - QAbstractButton *checkedButton = m_ui->customSieveGroup->checkedButton(); - - if (checkedButton == m_ui->imapUserPassword) { - m_parentResource->settings()->setSieveCustomAuthentification(QLatin1String("ImapUserPassword")); - } else if (checkedButton == m_ui->noAuthentification) { - m_parentResource->settings()->setSieveCustomAuthentification(QLatin1String("NoAuthentification")); - } else if (checkedButton == m_ui->customUserPassword) { - m_parentResource->settings()->setSieveCustomAuthentification(QLatin1String("CustomUserPassword")); - } - - m_parentResource->settings()->setSieveCustomPassword( m_ui->customPassword->text() ); - - m_parentResource->settings()->writeConfig(); - kDebug() << "wrote" << m_ui->imapServer->text() << m_ui->userName->text() << m_ui->safeImapGroup->checkedId(); - - if ( m_oldResourceName != m_ui->accountName->text() && !m_ui->accountName->text().isEmpty() ) { - m_parentResource->settings()->renameRootCollection( m_ui->accountName->text() ); - } + m_folderArchiveSettingPage->writeSettings(); + m_shouldClearCache = (m_parentResource->settings()->imapServer() != m_ui->imapServer->text()) + || (m_parentResource->settings()->userName() != m_ui->userName->text()); + + m_parentResource->setName(m_ui->accountName->text()); + + m_parentResource->settings()->setImapServer(m_ui->imapServer->text()); + m_parentResource->settings()->setImapPort(m_ui->portSpin->value()); + m_parentResource->settings()->setUserName(m_ui->userName->text()); + QString encryption; + switch (m_ui->safeImapGroup->checkedId()) { + case KIMAP::LoginJob::Unencrypted : + encryption = QLatin1String("None"); + break; + case KIMAP::LoginJob::AnySslVersion: + encryption = QLatin1String("SSL"); + break; + case KIMAP::LoginJob::TlsV1: + encryption = QLatin1String("STARTTLS"); + break; + default: + qFatal("Shouldn't happen"); + } + m_parentResource->settings()->setSafety(encryption); + MailTransport::Transport::EnumAuthenticationType::type authtype = getCurrentAuthMode(m_ui->authenticationCombo); + qCDebug(IMAPRESOURCE_LOG) << "saving IMAP auth mode: " << authenticationModeString(authtype); + m_parentResource->settings()->setAuthentication(authtype); + m_parentResource->settings()->setPassword(m_ui->password->text()); + m_parentResource->settings()->setSubscriptionEnabled(m_ui->subscriptionEnabled->isChecked()); + m_parentResource->settings()->setIntervalCheckTime(m_ui->checkInterval->value()); + m_parentResource->settings()->setDisconnectedModeEnabled(m_ui->disconnectedModeEnabled->isChecked()); + + MailTransport::Transport::EnumAuthenticationType::type alternateAuthtype = getCurrentAuthMode(m_ui->authenticationAlternateCombo); + qCDebug(IMAPRESOURCE_LOG) << "saving Alternate server sieve auth mode: " << authenticationModeString(alternateAuthtype); + m_parentResource->settings()->setAlternateAuthentication(alternateAuthtype); + m_parentResource->settings()->setSieveSupport(m_ui->managesieveCheck->isChecked()); + m_parentResource->settings()->setSieveReuseConfig(m_ui->sameConfigCheck->isChecked()); + m_parentResource->settings()->setSievePort(m_ui->sievePortSpin->value()); + m_parentResource->settings()->setSieveAlternateUrl(m_ui->alternateURL->text()); + m_parentResource->settings()->setSieveVacationFilename(m_vacationFileName); + + m_parentResource->settings()->setTrashCollection(m_ui->folderRequester->collection().id()); + Akonadi::Collection trash = m_ui->folderRequester->collection(); + Akonadi::SpecialMailCollections::self()->registerCollection(Akonadi::SpecialMailCollections::Trash, trash); + Akonadi::EntityDisplayAttribute *attribute = trash.attribute(Akonadi::Entity::AddIfMissing); + attribute->setIconName(QLatin1String("user-trash")); + new Akonadi::CollectionModifyJob(trash); + if (mOldTrash != trash) { + Akonadi::SpecialMailCollections::self()->unregisterCollection(mOldTrash); + } + + m_parentResource->settings()->setAutomaticExpungeEnabled(m_ui->autoExpungeCheck->isChecked()); + m_parentResource->settings()->setUseDefaultIdentity(m_ui->useDefaultIdentityCheck->isChecked()); + + if (!m_ui->useDefaultIdentityCheck->isChecked()) { + m_parentResource->settings()->setAccountIdentity(m_identityCombobox->currentIdentity()); + } + + m_parentResource->settings()->setIntervalCheckEnabled(m_ui->enableMailCheckBox->isChecked()); + if (m_ui->enableMailCheckBox->isChecked()) { + m_parentResource->settings()->setIntervalCheckTime(m_ui->checkInterval->value()); + } + + m_parentResource->settings()->setSieveCustomUsername(m_ui->customUsername->text()); + + QAbstractButton *checkedButton = m_ui->customSieveGroup->checkedButton(); + + if (checkedButton == m_ui->imapUserPassword) { + m_parentResource->settings()->setSieveCustomAuthentification(QLatin1String("ImapUserPassword")); + } else if (checkedButton == m_ui->noAuthentification) { + m_parentResource->settings()->setSieveCustomAuthentification(QLatin1String("NoAuthentification")); + } else if (checkedButton == m_ui->customUserPassword) { + m_parentResource->settings()->setSieveCustomAuthentification(QLatin1String("CustomUserPassword")); + } + + m_parentResource->settings()->setSieveCustomPassword(m_ui->customPassword->text()); + + m_parentResource->settings()->save(); + qCDebug(IMAPRESOURCE_LOG) << "wrote" << m_ui->imapServer->text() << m_ui->userName->text() << m_ui->safeImapGroup->checkedId(); + + if (m_oldResourceName != m_ui->accountName->text() && !m_ui->accountName->text().isEmpty()) { + m_parentResource->settings()->renameRootCollection(m_ui->accountName->text()); + } } void SetupServer::readSettings() { - m_folderArchiveSettingPage->loadSettings(); - m_ui->accountName->setText( m_parentResource->name() ); - m_oldResourceName = m_ui->accountName->text(); - - KUser* currentUser = new KUser(); - KEMailSettings esetting; - - m_ui->imapServer->setText( - !m_parentResource->settings()->imapServer().isEmpty() ? m_parentResource->settings()->imapServer() : - esetting.getSetting( KEMailSettings::InServer ) ); - - m_ui->portSpin->setValue( m_parentResource->settings()->imapPort() ); - - m_ui->userName->setText( - !m_parentResource->settings()->userName().isEmpty() ? m_parentResource->settings()->userName() : - currentUser->loginName() ); - - const QString safety = m_parentResource->settings()->safety(); - int i = 0; - if ( safety == QLatin1String( "SSL" ) ) - i = KIMAP::LoginJob::AnySslVersion; - else if ( safety == QLatin1String( "STARTTLS" ) ) - i = KIMAP::LoginJob::TlsV1; - else - i = KIMAP::LoginJob::Unencrypted; - - QAbstractButton* safetyButton = m_ui->safeImapGroup->button( i ); - if ( safetyButton ) - safetyButton->setChecked( true ); - - populateDefaultAuthenticationOptions(); - i = m_parentResource->settings()->authentication(); - kDebug() << "read IMAP auth mode: " << authenticationModeString( (MailTransport::Transport::EnumAuthenticationType::type) i ); - setCurrentAuthMode( m_ui->authenticationCombo, (MailTransport::Transport::EnumAuthenticationType::type) i ); - - bool rejected = false; - const QString password = m_parentResource->settings()->password( &rejected ); - if ( rejected ) { - m_ui->password->setEnabled( false ); - KMessageBox::information( 0, i18n( "Could not access KWallet. " - "If you want to store the password permanently then you have to " - "activate it. If you do not " - "want to use KWallet, check the box below, but note that you will be " - "prompted for your password when needed." ), - i18n( "Do not use KWallet" ), QLatin1String("warning_kwallet_disabled") ); - } else { - m_ui->password->insert( password ); - } - - m_ui->subscriptionEnabled->setChecked( m_parentResource->settings()->subscriptionEnabled() ); - - m_ui->checkInterval->setValue( m_parentResource->settings()->intervalCheckTime() ); - m_ui->disconnectedModeEnabled->setChecked( m_parentResource->settings()->disconnectedModeEnabled() ); - - m_ui->managesieveCheck->setChecked( m_parentResource->settings()->sieveSupport() ); - m_ui->sameConfigCheck->setChecked( m_parentResource->settings()->sieveReuseConfig() ); - m_ui->sievePortSpin->setValue( m_parentResource->settings()->sievePort() ); - m_ui->alternateURL->setText( m_parentResource->settings()->sieveAlternateUrl() ); - m_vacationFileName = m_parentResource->settings()->sieveVacationFilename(); - - - Akonadi::Collection trashCollection( m_parentResource->settings()->trashCollection() ); - if ( trashCollection.isValid() ) { - Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob( trashCollection,Akonadi::CollectionFetchJob::Base,this ); - connect( fetchJob, SIGNAL(collectionsReceived(Akonadi::Collection::List)), - this, SLOT(targetCollectionReceived(Akonadi::Collection::List)) ); - } else { - Akonadi::SpecialMailCollectionsRequestJob *requestJob = new Akonadi::SpecialMailCollectionsRequestJob( this ); - connect ( requestJob, SIGNAL(result(KJob*)), - this, SLOT(localFolderRequestJobFinished(KJob*)) ); - requestJob->requestDefaultCollection( Akonadi::SpecialMailCollections::Trash ); - requestJob->start(); - } - - m_ui->useDefaultIdentityCheck->setChecked( m_parentResource->settings()->useDefaultIdentity() ); - if ( !m_ui->useDefaultIdentityCheck->isChecked() ) - m_identityCombobox->setCurrentIdentity( m_parentResource->settings()->accountIdentity() ); - - m_ui->enableMailCheckBox->setChecked( m_parentResource->settings()->intervalCheckEnabled() ); - if ( m_ui->enableMailCheckBox->isChecked() ) - m_ui->checkInterval->setValue( m_parentResource->settings()->intervalCheckTime() ); - else - m_ui->checkInterval->setEnabled( false ); - - m_ui->autoExpungeCheck->setChecked( m_parentResource->settings()->automaticExpungeEnabled() ); - - if ( m_vacationFileName.isEmpty() ) - m_vacationFileName = QLatin1String("kmail-vacation.siv"); - - m_ui->customUsername->setText(m_parentResource->settings()->sieveCustomUsername()); - - m_ui->customPassword->setText(m_parentResource->settings()->sieveCustomPassword()); - - - const QString sieverCustomAuth(m_parentResource->settings()->sieveCustomAuthentification()); - if (sieverCustomAuth == QLatin1String("ImapUserPassword")) - m_ui->imapUserPassword->setChecked(true); - else if (sieverCustomAuth == QLatin1String("NoAuthentification")) - m_ui->noAuthentification->setChecked(true); - else if (sieverCustomAuth == QLatin1String("CustomUserPassword")) - m_ui->customUserPassword->setChecked(true); + m_folderArchiveSettingPage->loadSettings(); + m_ui->accountName->setText(m_parentResource->name()); + m_oldResourceName = m_ui->accountName->text(); + + KUser *currentUser = new KUser(); + KEMailSettings esetting; + + m_ui->imapServer->setText( + !m_parentResource->settings()->imapServer().isEmpty() ? m_parentResource->settings()->imapServer() : + esetting.getSetting(KEMailSettings::InServer)); + + m_ui->portSpin->setValue(m_parentResource->settings()->imapPort()); + + m_ui->userName->setText( + !m_parentResource->settings()->userName().isEmpty() ? m_parentResource->settings()->userName() : + currentUser->loginName()); + + const QString safety = m_parentResource->settings()->safety(); + int i = 0; + if (safety == QLatin1String("SSL")) { + i = KIMAP::LoginJob::AnySslVersion; + } else if (safety == QLatin1String("STARTTLS")) { + i = KIMAP::LoginJob::TlsV1; + } else { + i = KIMAP::LoginJob::Unencrypted; + } + + QAbstractButton *safetyButton = m_ui->safeImapGroup->button(i); + if (safetyButton) { + safetyButton->setChecked(true); + } + + populateDefaultAuthenticationOptions(); + i = m_parentResource->settings()->authentication(); + qCDebug(IMAPRESOURCE_LOG) << "read IMAP auth mode: " << authenticationModeString((MailTransport::Transport::EnumAuthenticationType::type) i); + setCurrentAuthMode(m_ui->authenticationCombo, (MailTransport::Transport::EnumAuthenticationType::type) i); + + i = m_parentResource->settings()->alternateAuthentication(); + setCurrentAuthMode(m_ui->authenticationAlternateCombo, (MailTransport::Transport::EnumAuthenticationType::type) i); + + bool rejected = false; + const QString password = m_parentResource->settings()->password(&rejected); + if (rejected) { + m_ui->password->setEnabled(false); + KMessageBox::information(Q_NULLPTR, i18n("Could not access KWallet. " + "If you want to store the password permanently then you have to " + "activate it. If you do not " + "want to use KWallet, check the box below, but note that you will be " + "prompted for your password when needed."), + i18n("Do not use KWallet"), QStringLiteral("warning_kwallet_disabled")); + } else { + m_ui->password->insert(password); + } + + m_ui->subscriptionEnabled->setChecked(m_parentResource->settings()->subscriptionEnabled()); + + m_ui->checkInterval->setValue(m_parentResource->settings()->intervalCheckTime()); + m_ui->disconnectedModeEnabled->setChecked(m_parentResource->settings()->disconnectedModeEnabled()); - delete currentUser; + m_ui->managesieveCheck->setChecked(m_parentResource->settings()->sieveSupport()); + m_ui->sameConfigCheck->setChecked(m_parentResource->settings()->sieveReuseConfig()); + m_ui->sievePortSpin->setValue(m_parentResource->settings()->sievePort()); + m_ui->alternateURL->setText(m_parentResource->settings()->sieveAlternateUrl()); + m_vacationFileName = m_parentResource->settings()->sieveVacationFilename(); + + Akonadi::Collection trashCollection(m_parentResource->settings()->trashCollection()); + if (trashCollection.isValid()) { + Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(trashCollection, Akonadi::CollectionFetchJob::Base, this); + connect(fetchJob, &Akonadi::CollectionFetchJob::collectionsReceived, this, &SetupServer::targetCollectionReceived); + } else { + Akonadi::SpecialMailCollectionsRequestJob *requestJob = new Akonadi::SpecialMailCollectionsRequestJob(this); + connect(requestJob, &Akonadi::SpecialMailCollectionsRequestJob::result, this, &SetupServer::localFolderRequestJobFinished); + requestJob->requestDefaultCollection(Akonadi::SpecialMailCollections::Trash); + requestJob->start(); + } + + m_ui->useDefaultIdentityCheck->setChecked(m_parentResource->settings()->useDefaultIdentity()); + if (!m_ui->useDefaultIdentityCheck->isChecked()) { + m_identityCombobox->setCurrentIdentity(m_parentResource->settings()->accountIdentity()); + } + + m_ui->enableMailCheckBox->setChecked(m_parentResource->settings()->intervalCheckEnabled()); + if (m_ui->enableMailCheckBox->isChecked()) { + m_ui->checkInterval->setValue(m_parentResource->settings()->intervalCheckTime()); + } else { + m_ui->checkInterval->setEnabled(false); + } + + m_ui->autoExpungeCheck->setChecked(m_parentResource->settings()->automaticExpungeEnabled()); + + if (m_vacationFileName.isEmpty()) { + m_vacationFileName = QLatin1String("kmail-vacation.siv"); + } + + m_ui->customUsername->setText(m_parentResource->settings()->sieveCustomUsername()); + + m_ui->customPassword->setText(m_parentResource->settings()->sieveCustomPassword()); + + const QString sieverCustomAuth(m_parentResource->settings()->sieveCustomAuthentification()); + if (sieverCustomAuth == QLatin1String("ImapUserPassword")) { + m_ui->imapUserPassword->setChecked(true); + } else if (sieverCustomAuth == QLatin1String("NoAuthentification")) { + m_ui->noAuthentification->setChecked(true); + } else if (sieverCustomAuth == QLatin1String("CustomUserPassword")) { + m_ui->customUserPassword->setChecked(true); + } + + delete currentUser; } void SetupServer::slotTest() { - kDebug() << m_ui->imapServer->text(); + qCDebug(IMAPRESOURCE_LOG) << m_ui->imapServer->text(); - m_ui->testButton->setEnabled( false ); - m_ui->safeImap->setEnabled( false ); - m_ui->authenticationCombo->setEnabled( false ); + m_ui->testButton->setEnabled(false); + m_ui->safeImap->setEnabled(false); + m_ui->authenticationCombo->setEnabled(false); - m_ui->testInfo->clear(); - m_ui->testInfo->hide(); + m_ui->testInfo->clear(); + m_ui->testInfo->hide(); - delete m_serverTest; - m_serverTest = new MailTransport::ServerTest( this ); + delete m_serverTest; + m_serverTest = new MailTransport::ServerTest(this); #ifndef QT_NO_CURSOR - qApp->setOverrideCursor( Qt::BusyCursor ); + qApp->setOverrideCursor(Qt::BusyCursor); #endif - const QString server = m_ui->imapServer->text(); - const int port = m_ui->portSpin->value(); - kDebug() << "server: " << server << "port: " << port; - - m_serverTest->setServer( server ); - - if ( port != 143 && port != 993 ) { - m_serverTest->setPort( MailTransport::Transport::EnumEncryption::None, port ); - m_serverTest->setPort( MailTransport::Transport::EnumEncryption::SSL, port ); - } + const QString server = m_ui->imapServer->text(); + const int port = m_ui->portSpin->value(); + qCDebug(IMAPRESOURCE_LOG) << "server: " << server << "port: " << port; + + m_serverTest->setServer(server); + + if (port != 143 && port != 993) { + m_serverTest->setPort(MailTransport::Transport::EnumEncryption::None, port); + m_serverTest->setPort(MailTransport::Transport::EnumEncryption::SSL, port); + } - m_serverTest->setProtocol( QLatin1String("imap") ); - m_serverTest->setProgressBar( m_ui->testProgress ); - connect( m_serverTest, SIGNAL(finished(QList)), - SLOT(slotFinished(QList)) ); - enableButtonOk( false ); - m_serverTest->start(); + m_serverTest->setProtocol(QLatin1String("imap")); + m_serverTest->setProgressBar(m_ui->testProgress); + connect(m_serverTest, &MailTransport::ServerTest::finished, this, &SetupServer::slotFinished); + mOkButton->setEnabled(false); + m_serverTest->start(); } -void SetupServer::slotFinished( const QList &testResult ) +void SetupServer::slotFinished(const QList &testResult) { - kDebug() << testResult; + qCDebug(IMAPRESOURCE_LOG) << testResult; #ifndef QT_NO_CURSOR - qApp->restoreOverrideCursor(); + qApp->restoreOverrideCursor(); #endif - enableButtonOk( true ); + mOkButton->setEnabled(true); - using namespace MailTransport; + using namespace MailTransport; + + if (!m_serverTest->isNormalPossible() && !m_serverTest->isSecurePossible()) { + KMessageBox::sorry(this, i18n("Unable to connect to the server, please verify the server address.")); + } - if ( !m_serverTest->isNormalPossible() && !m_serverTest->isSecurePossible() ) - KMessageBox::sorry( this, i18n( "Unable to connect to the server, please verify the server address." ) ); + m_ui->testInfo->show(); - m_ui->testInfo->show(); + m_ui->sslRadio->setEnabled(testResult.contains(Transport::EnumEncryption::SSL)); + m_ui->tlsRadio->setEnabled(testResult.contains(Transport::EnumEncryption::TLS)); + m_ui->noRadio->setEnabled(testResult.contains(Transport::EnumEncryption::None)); + + QString text; + if (testResult.contains(Transport::EnumEncryption::TLS)) { + m_ui->tlsRadio->setChecked(true); + text = i18n("TLS is supported and recommended."); + } else if (testResult.contains(Transport::EnumEncryption::SSL)) { + m_ui->sslRadio->setChecked(true); + text = i18n("SSL is supported and recommended."); + } else if (testResult.contains(Transport::EnumEncryption::None)) { + m_ui->noRadio->setChecked(true); + text = i18n("No security is supported. It is not " + "recommended to connect to this server."); + } else { + text = i18n("It is not possible to use this server."); + } + m_ui->testInfo->setText(text); - m_ui->sslRadio->setEnabled( testResult.contains( Transport::EnumEncryption::SSL ) ); - m_ui->tlsRadio->setEnabled( testResult.contains( Transport::EnumEncryption::TLS ) ); - m_ui->noRadio->setEnabled( testResult.contains( Transport::EnumEncryption::None ) ); - - QString text; - if ( testResult.contains( Transport::EnumEncryption::TLS ) ) { - m_ui->tlsRadio->setChecked( true ); - text = i18n( "TLS is supported and recommended." ); - } else if ( testResult.contains( Transport::EnumEncryption::SSL ) ) { - m_ui->sslRadio->setChecked( true ); - text = i18n( "SSL is supported and recommended." ); - } else if ( testResult.contains( Transport::EnumEncryption::None ) ) { - m_ui->noRadio->setChecked( true ); - text = i18n( "No security is supported. It is not " - "recommended to connect to this server." ); - } else { - text = i18n( "It is not possible to use this server." ); - } - m_ui->testInfo->setText( text ); - - m_ui->testButton->setEnabled( true ); - m_ui->safeImap->setEnabled( true ); - m_ui->authenticationCombo->setEnabled( true ); - slotEncryptionRadioChanged(); - slotSafetyChanged(); + m_ui->testButton->setEnabled(true); + m_ui->safeImap->setEnabled(true); + m_ui->authenticationCombo->setEnabled(true); + slotEncryptionRadioChanged(); + slotSafetyChanged(); } void SetupServer::slotTestChanged() { - delete m_serverTest; - m_serverTest = 0; - slotSafetyChanged(); - - // do not use imapConnectionPossible, as the data is not yet saved. - m_ui->testButton->setEnabled( true /* TODO Global::connectionPossible() || - m_ui->imapServer->text() == "localhost"*/ ); + delete m_serverTest; + m_serverTest = Q_NULLPTR; + slotSafetyChanged(); + + // do not use imapConnectionPossible, as the data is not yet saved. + m_ui->testButton->setEnabled(true /* TODO Global::connectionPossible() || + m_ui->imapServer->text() == "localhost"*/); } void SetupServer::slotEnableWidgets() { - const bool haveSieve = m_ui->managesieveCheck->isChecked(); - const bool reuseConfig = m_ui->sameConfigCheck->isChecked(); + const bool haveSieve = m_ui->managesieveCheck->isChecked(); + const bool reuseConfig = m_ui->sameConfigCheck->isChecked(); - m_ui->sameConfigCheck->setEnabled( haveSieve ); - m_ui->sievePortSpin->setEnabled( haveSieve && reuseConfig ); - m_ui->alternateURL->setEnabled( haveSieve && !reuseConfig ); - m_ui->authentification->setEnabled( haveSieve && !reuseConfig ); + m_ui->sameConfigCheck->setEnabled(haveSieve); + m_ui->sievePortSpin->setEnabled(haveSieve); + m_ui->alternateURL->setEnabled(haveSieve && !reuseConfig); + m_ui->authentification->setEnabled(haveSieve && !reuseConfig); } void SetupServer::slotComplete() { - const bool ok = !m_ui->imapServer->text().isEmpty() && !m_ui->userName->text().isEmpty(); - button( KDialog::Ok )->setEnabled( ok ); + const bool ok = !m_ui->imapServer->text().isEmpty() && !m_ui->userName->text().isEmpty(); + mOkButton->setEnabled(ok); } void SetupServer::slotSafetyChanged() { - if ( m_serverTest == 0 ) { - kDebug() << "serverTest null"; - m_ui->noRadio->setEnabled( true ); - m_ui->sslRadio->setEnabled( true ); - m_ui->tlsRadio->setEnabled( true ); - - m_ui->authenticationCombo->setEnabled( true ); - return; - } - - QList protocols; - - switch ( m_ui->safeImapGroup->checkedId() ) { - case KIMAP::LoginJob::Unencrypted : - kDebug() << "safeImapGroup: unencrypted"; - protocols = m_serverTest->normalProtocols(); - break; - case KIMAP::LoginJob::AnySslVersion: - protocols = m_serverTest->secureProtocols(); - kDebug() << "safeImapGroup: SSL"; - break; - case KIMAP::LoginJob::TlsV1: - protocols = m_serverTest->tlsProtocols(); - kDebug() << "safeImapGroup: starttls"; - break; - default: - kFatal() << "Shouldn't happen"; - } - - m_ui->authenticationCombo->clear(); - addAuthenticationItem( m_ui->authenticationCombo, MailTransport::Transport::EnumAuthenticationType::CLEAR ); - foreach ( int prot, protocols ) { - addAuthenticationItem( m_ui->authenticationCombo, (MailTransport::Transport::EnumAuthenticationType::type) prot ); - } - if ( protocols.size() > 0 ) - setCurrentAuthMode( m_ui->authenticationCombo, (MailTransport::Transport::EnumAuthenticationType::type) protocols.first() ); - else - kDebug() << "no authmodes found"; + if (m_serverTest == Q_NULLPTR) { + qCDebug(IMAPRESOURCE_LOG) << "serverTest null"; + m_ui->noRadio->setEnabled(true); + m_ui->sslRadio->setEnabled(true); + m_ui->tlsRadio->setEnabled(true); + + m_ui->authenticationCombo->setEnabled(true); + return; + } + + QList protocols; + + switch (m_ui->safeImapGroup->checkedId()) { + case KIMAP::LoginJob::Unencrypted : + qCDebug(IMAPRESOURCE_LOG) << "safeImapGroup: unencrypted"; + protocols = m_serverTest->normalProtocols(); + break; + case KIMAP::LoginJob::AnySslVersion: + protocols = m_serverTest->secureProtocols(); + qCDebug(IMAPRESOURCE_LOG) << "safeImapGroup: SSL"; + break; + case KIMAP::LoginJob::TlsV1: + protocols = m_serverTest->tlsProtocols(); + qCDebug(IMAPRESOURCE_LOG) << "safeImapGroup: starttls"; + break; + default: + qFatal("Shouldn't happen"); + } + + m_ui->authenticationCombo->clear(); + addAuthenticationItem(m_ui->authenticationCombo, MailTransport::Transport::EnumAuthenticationType::CLEAR); + foreach (int prot, protocols) { + addAuthenticationItem(m_ui->authenticationCombo, (MailTransport::Transport::EnumAuthenticationType::type) prot); + } + if (protocols.size() > 0) { + setCurrentAuthMode(m_ui->authenticationCombo, (MailTransport::Transport::EnumAuthenticationType::type) protocols.first()); + } else { + qCDebug(IMAPRESOURCE_LOG) << "no authmodes found"; + } } void SetupServer::slotManageSubscriptions() { - kDebug() << "manage subscripts"; - ImapAccount account; + qCDebug(IMAPRESOURCE_LOG) << "manage subscripts"; + ImapAccount account; - account.setServer( m_ui->imapServer->text() ); - account.setPort( m_ui->portSpin->value() ); + account.setServer(m_ui->imapServer->text()); + account.setPort(m_ui->portSpin->value()); - account.setUserName( m_ui->userName->text() ); - account.setSubscriptionEnabled( m_ui->subscriptionEnabled->isChecked() ); + account.setUserName(m_ui->userName->text()); + account.setSubscriptionEnabled(m_ui->subscriptionEnabled->isChecked()); - account.setEncryptionMode( - static_cast( m_ui->safeImapGroup->checkedId() ) - ); + account.setEncryptionMode( + static_cast(m_ui->safeImapGroup->checkedId()) + ); - account.setAuthenticationMode( Settings::mapTransportAuthToKimap( getCurrentAuthMode( m_ui->authenticationCombo ) ) ); + account.setAuthenticationMode(Settings::mapTransportAuthToKimap(getCurrentAuthMode(m_ui->authenticationCombo))); - QPointer subscriptions = new SubscriptionDialog( this ); - subscriptions->setCaption( i18n( "Serverside Subscription" ) ); - subscriptions->setWindowIcon( KIcon( QLatin1String("network-server") ) ); - subscriptions->connectAccount( account, m_ui->password->text() ); - m_subscriptionsChanged = subscriptions->isSubscriptionChanged(); + QPointer subscriptions = new SubscriptionDialog(this); + subscriptions->setWindowTitle(i18n("Serverside Subscription")); + subscriptions->setWindowIcon(QIcon::fromTheme(QStringLiteral("network-server"))); + subscriptions->connectAccount(account, m_ui->password->text()); + m_subscriptionsChanged = subscriptions->isSubscriptionChanged(); - subscriptions->exec(); - delete subscriptions; + subscriptions->exec(); + delete subscriptions; - m_ui->subscriptionEnabled->setChecked( account.isSubscriptionEnabled() ); + m_ui->subscriptionEnabled->setChecked(account.isSubscriptionEnabled()); } void SetupServer::slotShowServerInfo() { - ServerInfoDialog *dialog = new ServerInfoDialog(m_parentResource, this); - dialog->show(); + ServerInfoDialog *dialog = new ServerInfoDialog(m_parentResource, this); + dialog->show(); } -void SetupServer::targetCollectionReceived( const Akonadi::Collection::List &collections ) +void SetupServer::targetCollectionReceived(const Akonadi::Collection::List &collections) { - m_ui->folderRequester->setCollection( collections.first() ); - mOldTrash = collections.first(); + m_ui->folderRequester->setCollection(collections.first()); + mOldTrash = collections.first(); } -void SetupServer::localFolderRequestJobFinished( KJob *job ) +void SetupServer::localFolderRequestJobFinished(KJob *job) { - if ( !job->error() ) { - Akonadi::Collection targetCollection = Akonadi::SpecialMailCollections::self()->defaultCollection( Akonadi::SpecialMailCollections::Trash ); - Q_ASSERT( targetCollection.isValid() ); - m_ui->folderRequester->setCollection( targetCollection ); - mOldTrash = targetCollection; - } + if (!job->error()) { + Akonadi::Collection targetCollection = Akonadi::SpecialMailCollections::self()->defaultCollection(Akonadi::SpecialMailCollections::Trash); + Q_ASSERT(targetCollection.isValid()); + m_ui->folderRequester->setCollection(targetCollection); + mOldTrash = targetCollection; + } } void SetupServer::populateDefaultAuthenticationOptions() { - m_ui->authenticationCombo->clear(); - addAuthenticationItem( m_ui->authenticationCombo, MailTransport::Transport::EnumAuthenticationType::CLEAR); - addAuthenticationItem( m_ui->authenticationCombo, MailTransport::Transport::EnumAuthenticationType::LOGIN ); - addAuthenticationItem( m_ui->authenticationCombo, MailTransport::Transport::EnumAuthenticationType::PLAIN ); - addAuthenticationItem( m_ui->authenticationCombo, MailTransport::Transport::EnumAuthenticationType::CRAM_MD5 ); - addAuthenticationItem( m_ui->authenticationCombo, MailTransport::Transport::EnumAuthenticationType::DIGEST_MD5 ); - addAuthenticationItem( m_ui->authenticationCombo, MailTransport::Transport::EnumAuthenticationType::NTLM ); - addAuthenticationItem( m_ui->authenticationCombo, MailTransport::Transport::EnumAuthenticationType::GSSAPI ); - addAuthenticationItem( m_ui->authenticationCombo, MailTransport::Transport::EnumAuthenticationType::ANONYMOUS ); + populateDefaultAuthenticationOptions(m_ui->authenticationCombo); + populateDefaultAuthenticationOptions(m_ui->authenticationAlternateCombo); } - - - +void SetupServer::populateDefaultAuthenticationOptions(QComboBox *combo) +{ + combo->clear(); + addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::CLEAR); + addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::LOGIN); + addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::PLAIN); + addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::CRAM_MD5); + addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::DIGEST_MD5); + addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::NTLM); + addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::GSSAPI); + addAuthenticationItem(combo, MailTransport::Transport::EnumAuthenticationType::ANONYMOUS); +} diff -Nru kdepim-runtime-4.14.6/resources/imap/setupserver.h kdepim-runtime-15.08.0/resources/imap/setupserver.h --- kdepim-runtime-4.14.6/resources/imap/setupserver.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/setupserver.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,12 +22,13 @@ #define SETUPSERVER_H #include -#include -#include +#include +#include #include #include - +class QPushButton; +class QComboBox; namespace Ui { class SetupServerView; @@ -37,7 +38,7 @@ { class ServerTest; } -namespace KPIMIdentities +namespace KIdentityManagement { class IdentityCombo; class IdentityManager; @@ -50,64 +51,66 @@ * These contain the account settings * @author Tom Albers */ -class SetupServer : public KDialog +class SetupServer : public QDialog { - Q_OBJECT + Q_OBJECT public: - /** - * Constructor - * @param parentResource The resource this dialog belongs to - * @param parent Parent WId - */ - SetupServer( ImapResourceBase *parentResource, WId parent ); - - /** - * Destructor - */ - ~SetupServer(); - - bool shouldClearCache() const; - -private slots: - /** - * Call this if you want the settings saved from this page. - */ - void applySettings(); - void slotIdentityCheckboxChanged(); - void slotMailCheckboxChanged(); - void slotEncryptionRadioChanged(); - void slotSubcriptionCheckboxChanged(); - void slotShowServerInfo(); + /** + * Constructor + * @param parentResource The resource this dialog belongs to + * @param parent Parent WId + */ + SetupServer(ImapResourceBase *parentResource, WId parent); + + /** + * Destructor + */ + ~SetupServer(); + + bool shouldClearCache() const; + +private Q_SLOTS: + /** + * Call this if you want the settings saved from this page. + */ + void applySettings(); + void slotIdentityCheckboxChanged(); + void slotMailCheckboxChanged(); + void slotEncryptionRadioChanged(); + void slotSubcriptionCheckboxChanged(); + void slotShowServerInfo(); private: - void readSettings(); - void populateDefaultAuthenticationOptions(); + void readSettings(); + void populateDefaultAuthenticationOptions(); - ImapResourceBase *m_parentResource; - Ui::SetupServerView *m_ui; - MailTransport::ServerTest *m_serverTest; - bool m_subscriptionsChanged; - bool m_shouldClearCache; - QString m_vacationFileName; - KPIMIdentities::IdentityManager *m_identityManager; - KPIMIdentities::IdentityCombo *m_identityCombobox; - QString m_oldResourceName; - QRegExpValidator mValidator; - Akonadi::Collection mOldTrash; - FolderArchiveSettingPage *m_folderArchiveSettingPage; - -private slots: - void slotTest(); - void slotFinished(const QList &testResult ); - void slotCustomSieveChanged(); - - void slotTestChanged(); - void slotComplete(); - void slotSafetyChanged(); - void slotManageSubscriptions(); - void slotEnableWidgets(); - void targetCollectionReceived(const Akonadi::Collection::List &collections ); - void localFolderRequestJobFinished( KJob *job ); + ImapResourceBase *m_parentResource; + Ui::SetupServerView *m_ui; + MailTransport::ServerTest *m_serverTest; + bool m_subscriptionsChanged; + bool m_shouldClearCache; + QString m_vacationFileName; + KIdentityManagement::IdentityManager *m_identityManager; + KIdentityManagement::IdentityCombo *m_identityCombobox; + QString m_oldResourceName; + QRegExpValidator mValidator; + Akonadi::Collection mOldTrash; + FolderArchiveSettingPage *m_folderArchiveSettingPage; + QPushButton *mOkButton; + +private Q_SLOTS: + void slotTest(); + void slotFinished(const QList &testResult); + void slotCustomSieveChanged(); + + void slotTestChanged(); + void slotComplete(); + void slotSafetyChanged(); + void slotManageSubscriptions(); + void slotEnableWidgets(); + void targetCollectionReceived(const Akonadi::Collection::List &collections); + void localFolderRequestJobFinished(KJob *job); + void populateDefaultAuthenticationOptions(QComboBox *combo); }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/setupserverview_desktop.ui kdepim-runtime-15.08.0/resources/imap/setupserverview_desktop.ui --- kdepim-runtime-4.14.6/resources/imap/setupserverview_desktop.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/setupserverview_desktop.ui 2015-08-10 21:01:02.000000000 +0000 @@ -6,8 +6,8 @@ 0 0 - 454 - 518 + 467 + 540 @@ -36,9 +36,9 @@
- - true - + + true + @@ -47,7 +47,7 @@ Indicate the IMAP server. If you want to connect to a non-standard port for a specific encryption scheme, you can add ":port" to indicate that. For example: "imap.foo.com:144". - IMAP Server: + I&MAP Server: imapServer @@ -56,9 +56,9 @@ - - true - + + true + @@ -67,7 +67,7 @@ The username. - Username: + &Username: userName @@ -76,9 +76,9 @@ - - true - + + true + @@ -99,10 +99,9 @@ QLineEdit::Password - - true - - + + true +
@@ -138,18 +137,12 @@
- - - 1 - + 0 - - - - - + + 1 @@ -212,7 +205,7 @@
- + 65535 @@ -225,16 +218,15 @@ - Alternate URL: + Alternate Server: - - true - - + + true + @@ -245,14 +237,11 @@ Authentication - - - - QLineEdit::Password + + + + true - - true - @@ -265,41 +254,30 @@
- - - - Password: - - - - - - - Username: - - - - Username and Password + &Username and Password customSieveGroup - - - - true - + + + + QLineEdit::Password + + + true + - IMAP Username and Password + I&MAP Username and Password true @@ -309,6 +287,75 @@ + + + + Password: + + + + + + + Username: + + + + + + + + + Authentication: + + + + + + + + Clear text + + + + + LOGIN + + + + + PLAIN + + + + + CRAM-MD5 + + + + + DIGEST-MD5 + + + + + NTLM + + + + + GSSAPI + + + + + Anonymous + + + + + + @@ -348,7 +395,7 @@ - + false @@ -432,7 +479,7 @@ - + Auto Detect @@ -518,42 +565,42 @@ - Clear text + Clear text - LOGIN + LOGIN - PLAIN + PLAIN - CRAM-MD5 + CRAM-MD5 - DIGEST-MD5 + DIGEST-MD5 - NTLM + NTLM - GSSAPI + GSSAPI - Anonymous + Anonymous @@ -623,24 +670,14 @@ 1 - KPushButton - QPushButton -
kpushbutton.h
-
- - KIntSpinBox + KPluralHandlingSpinBox QSpinBox -
knuminput.h
-
- - KIntNumInput - QWidget -
knuminput.h
+
kpluralhandlingspinbox.h
Akonadi::CollectionRequester QFrame -
Akonadi/CollectionRequester
+
AkonadiWidgets/CollectionRequester
1
diff -Nru kdepim-runtime-4.14.6/resources/imap/setupserverview_mobile.ui kdepim-runtime-15.08.0/resources/imap/setupserverview_mobile.ui --- kdepim-runtime-4.14.6/resources/imap/setupserverview_mobile.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/setupserverview_mobile.ui 2015-08-10 21:01:02.000000000 +0000 @@ -95,7 +95,7 @@
- + Auto Detect @@ -228,42 +228,42 @@ - Clear text + Clear text - LOGIN + LOGIN - PLAIN + PLAIN - CRAM-MD5 + CRAM-MD5 - DIGEST-MD5 + DIGEST-MD5 - NTLM + NTLM - GSSAPI + GSSAPI - Anonymous + Anonymous @@ -288,19 +288,13 @@ - + 1 0 - - minutes - - - -
@@ -320,7 +314,7 @@
- + false @@ -426,7 +420,7 @@ - + 65535 @@ -462,14 +456,9 @@ - KIntSpinBox + KPluralHandlingSpinBox QSpinBox -
knuminput.h
-
- - KPushButton - QPushButton -
kpushbutton.h
+
KPluralHandlingSpinBox
KLineEdit @@ -478,14 +467,9 @@ 1 - KIntNumInput - QWidget -
knuminput.h
-
- Akonadi::CollectionRequester QFrame -
Akonadi/CollectionRequester
+
AkonadiWidgets/CollectionRequester
1
diff -Nru kdepim-runtime-4.14.6/resources/imap/subscriptiondialog.cpp kdepim-runtime-15.08.0/resources/imap/subscriptiondialog.cpp --- kdepim-runtime-4.14.6/resources/imap/subscriptiondialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/subscriptiondialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,14 +22,16 @@ #include "subscriptiondialog.h" #include -#include -#include -#include -#include - -#include -#include -#include +#include +#include +#include +#include + +#include "imapresource_debug.h" +#include +#include + +#include #include #include @@ -38,429 +40,428 @@ #include "imapaccount.h" #include "sessionuiproxy.h" +#include +#include +#include #ifndef KDEPIM_MOBILE_UI -#include -#include -#include +#include +#include +#include #else -#include -#include +#include +#include #include +#include class CheckableFilterProxyModel : public QSortFilterProxyModel { public: - CheckableFilterProxyModel( QObject *parent = 0 ) - : QSortFilterProxyModel( parent ) { } + explicit CheckableFilterProxyModel(QObject *parent = Q_NULLPTR) + : QSortFilterProxyModel(parent) { } protected: - /*reimp*/ bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const - { - QModelIndex sourceIndex = sourceModel()->index( sourceRow, 0, sourceParent ); - return sourceModel()->flags(sourceIndex) & Qt::ItemIsUserCheckable; - } + /*reimp*/ bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const + { + QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent); + return sourceModel()->flags(sourceIndex) & Qt::ItemIsUserCheckable; + } }; - #endif +SubscriptionDialog::SubscriptionDialog(QWidget *parent, SubscriptionDialog::SubscriptionDialogOptions option) + : QDialog(parent), + m_session(Q_NULLPTR), + m_subscriptionChanged(false), + m_lineEdit(Q_NULLPTR), + m_filter(new SubscriptionFilterProxyModel(this)), + m_model(new QStandardItemModel(this)) +{ + setModal(true); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + QVBoxLayout *topLayout = new QVBoxLayout; + setLayout(topLayout); + QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); + okButton->setDefault(true); + okButton->setShortcut(Qt::CTRL | Qt::Key_Return); + mUser1Button = new QPushButton; + buttonBox->addButton(mUser1Button, QDialogButtonBox::ActionRole); + connect(buttonBox, &QDialogButtonBox::accepted, this, &SubscriptionDialog::slotAccepted); + connect(buttonBox, &QDialogButtonBox::rejected, this, &SubscriptionDialog::reject); + + mUser1Button->setText(i18nc("@action:button", "Reload &List")); + mUser1Button->setEnabled(false); + connect(mUser1Button, &QPushButton::clicked, this, &SubscriptionDialog::onReloadRequested); + + QWidget *mainWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; + mainWidget->setLayout(mainLayout); + topLayout->addWidget(mainWidget); + topLayout->addWidget(buttonBox); + + m_enableSubscription = new QCheckBox(i18nc("@option:check", + "Enable server-side subscriptions")); + mainLayout->addWidget(m_enableSubscription); - -SubscriptionDialog::SubscriptionDialog( QWidget *parent, SubscriptionDialog::SubscriptionDialogOptions option ) - : KDialog( parent ), - m_session( 0 ), - m_subscriptionChanged( false ), - m_lineEdit( 0 ), - m_filter( new SubscriptionFilterProxyModel( this ) ), - m_model( new QStandardItemModel( this ) ) -{ - setModal( true ); - setButtons( Ok | Cancel | User1 ); - - setButtonText( User1, i18nc( "@action:button", "Reload &List" ) ); - enableButton( User1, false ); - connect( this, SIGNAL(user1Clicked()), - this, SLOT(onReloadRequested()) ); - - QWidget *mainWidget = new QWidget( this ); - QVBoxLayout *mainLayout = new QVBoxLayout; - mainWidget->setLayout( mainLayout ); - setMainWidget( mainWidget ); - - m_enableSubscription = new QCheckBox( i18nc( "@option:check", - "Enable server-side subscriptions" ) ); - mainLayout->addWidget( m_enableSubscription ); - - QHBoxLayout *filterBarLayout = new QHBoxLayout; - mainLayout->addLayout( filterBarLayout ); + QHBoxLayout *filterBarLayout = new QHBoxLayout; + mainLayout->addLayout(filterBarLayout); #ifndef KDEPIM_MOBILE_UI - filterBarLayout->addWidget( new QLabel( i18nc( "@label search for a subscription", - "Search:" ) ) ); + filterBarLayout->addWidget(new QLabel(i18nc("@label search for a subscription", + "Search:"))); #endif - m_lineEdit = new KLineEdit( mainWidget ); - m_lineEdit->setClearButtonShown( true ); - connect( m_lineEdit, SIGNAL(textChanged(QString)), - this, SLOT(slotSearchPattern(QString)) ); - filterBarLayout->addWidget( m_lineEdit ); - m_lineEdit->setFocus(); + m_lineEdit = new QLineEdit(mainWidget); + m_lineEdit->setClearButtonEnabled(true); + connect(m_lineEdit, &QLineEdit::textChanged, this, &SubscriptionDialog::slotSearchPattern); + filterBarLayout->addWidget(m_lineEdit); + m_lineEdit->setFocus(); #ifndef KDEPIM_MOBILE_UI - QCheckBox *checkBox = new QCheckBox( i18nc( "@option:check", "Subscribed only" ), mainWidget ); - connect( checkBox, SIGNAL(stateChanged(int)), - m_filter, SLOT(setIncludeCheckedOnly(int)) ); - filterBarLayout->addWidget( checkBox ); - - m_treeView = new QTreeView( mainWidget ); - m_treeView->header()->hide(); - m_filter->setSourceModel( m_model ); - m_treeView->setModel( m_filter ); - mainLayout->addWidget( m_treeView ); + QCheckBox *checkBox = new QCheckBox(i18nc("@option:check", "Subscribed only"), mainWidget); + connect(checkBox, SIGNAL(stateChanged(int)), + m_filter, SLOT(setIncludeCheckedOnly(int))); + + filterBarLayout->addWidget(checkBox); + + m_treeView = new QTreeView(mainWidget); + m_treeView->header()->hide(); + m_filter->setSourceModel(m_model); + m_treeView->setModel(m_filter); + mainLayout->addWidget(m_treeView); #else - m_lineEdit->hide(); - connect( m_lineEdit, SIGNAL(textChanged(QString)), - this, SLOT(onMobileLineEditChanged(QString)) ); + m_lineEdit->hide(); + connect(m_lineEdit, &QLineEdit::textChanged, this, &SubscriptionDialog::onMobileLineEditChanged); - m_listView = new QListView( mainWidget ); + m_listView = new QListView(mainWidget); - KDescendantsProxyModel *flatModel = new KDescendantsProxyModel( m_listView ); - flatModel->setDisplayAncestorData( true ); - flatModel->setAncestorSeparator( QLatin1String("/") ); - flatModel->setSourceModel( m_model ); + KDescendantsProxyModel *flatModel = new KDescendantsProxyModel(m_listView); + flatModel->setDisplayAncestorData(true); + flatModel->setAncestorSeparator(QStringLiteral("/")); + flatModel->setSourceModel(m_model); - CheckableFilterProxyModel *checkableModel = new CheckableFilterProxyModel( m_listView ); - checkableModel->setSourceModel( flatModel ); + CheckableFilterProxyModel *checkableModel = new CheckableFilterProxyModel(m_listView); + checkableModel->setSourceModel(flatModel); - m_filter->setSourceModel( checkableModel ); + m_filter->setSourceModel(checkableModel); - m_listView->setModel( m_filter ); - mainLayout->addWidget( m_listView ); + m_listView->setModel(m_filter); + mainLayout->addWidget(m_listView); - // We want to get all the keyboard input all the time - grabKeyboard(); + // We want to get all the keyboard input all the time + grabKeyboard(); #endif - connect( m_model, SIGNAL(itemChanged(QStandardItem*)), - this, SLOT(onItemChanged(QStandardItem*)) ); + connect(m_model, &QStandardItemModel::itemChanged, this, &SubscriptionDialog::onItemChanged); - if ( option & SubscriptionDialog::AllowToEnableSubscription ) { + if (option & SubscriptionDialog::AllowToEnableSubscription) { #ifndef KDEPIM_MOBILE_UI - connect( m_enableSubscription, SIGNAL(clicked(bool)), m_treeView, SLOT(setEnabled(bool)) ); + connect(m_enableSubscription, &QCheckBox::clicked, m_treeView, &QTreeView::setEnabled); #else - connect( m_enableSubscription, SIGNAL(clicked(bool)), m_listView, SLOT(setEnabled(bool)) ); + connect(m_enableSubscription, &QCheckBox::clicked, m_listView, &QListView::setEnabled); #endif - } else { - m_enableSubscription->hide(); - } - readConfig(); + } else { + m_enableSubscription->hide(); + } + readConfig(); } SubscriptionDialog::~SubscriptionDialog() { - writeConfig(); + writeConfig(); } void SubscriptionDialog::slotSearchPattern(const QString &pattern) { #ifndef KDEPIM_MOBILE_UI - m_treeView->expandAll(); + m_treeView->expandAll(); #endif - m_filter->setSearchPattern(pattern); + m_filter->setSearchPattern(pattern); } void SubscriptionDialog::readConfig() { - KConfigGroup group( KGlobal::config(), "SubscriptionDialog" ); + KConfigGroup group(KSharedConfig::openConfig(), "SubscriptionDialog"); - const QSize size = group.readEntry( "Size", QSize() ); - if ( size.isValid() ) { - resize( size ); - } else { - resize( 500, 300 ); - } + const QSize size = group.readEntry("Size", QSize()); + if (size.isValid()) { + resize(size); + } else { + resize(500, 300); + } } void SubscriptionDialog::writeConfig() { - KConfigGroup group( KGlobal::config(), "SubscriptionDialog" ); - group.writeEntry( "Size", size() ); - group.sync(); + KConfigGroup group(KSharedConfig::openConfig(), "SubscriptionDialog"); + group.writeEntry("Size", size()); + group.sync(); } - -void SubscriptionDialog::setSubscriptionEnabled( bool enabled ) +void SubscriptionDialog::setSubscriptionEnabled(bool enabled) { - m_enableSubscription->setChecked( enabled ); + m_enableSubscription->setChecked(enabled); #ifndef KDEPIM_MOBILE_UI - m_treeView->setEnabled( enabled ); + m_treeView->setEnabled(enabled); #else - m_listView->setEnabled( enabled ); + m_listView->setEnabled(enabled); #endif } bool SubscriptionDialog::subscriptionEnabled() const { - return m_enableSubscription->isChecked(); + return m_enableSubscription->isChecked(); } - -void SubscriptionDialog::connectAccount( const ImapAccount &account, const QString &password ) +void SubscriptionDialog::connectAccount(const ImapAccount &account, const QString &password) { - m_session = new KIMAP::Session( account.server(), account.port(), this ); - m_session->setUiProxy( SessionUiProxy::Ptr( new SessionUiProxy ) ); + m_session = new KIMAP::Session(account.server(), account.port(), this); + m_session->setUiProxy(SessionUiProxy::Ptr(new SessionUiProxy)); - KIMAP::LoginJob *login = new KIMAP::LoginJob( m_session ); - login->setUserName( account.userName() ); - login->setPassword( password ); - login->setEncryptionMode( account.encryptionMode() ); - login->setAuthenticationMode( account.authenticationMode() ); + KIMAP::LoginJob *login = new KIMAP::LoginJob(m_session); + login->setUserName(account.userName()); + login->setPassword(password); + login->setEncryptionMode(account.encryptionMode()); + login->setAuthenticationMode(account.authenticationMode()); - connect( login, SIGNAL(result(KJob*)), - this, SLOT(onLoginDone(KJob*)) ); - login->start(); + connect(login, &KIMAP::LoginJob::result, this, &SubscriptionDialog::onLoginDone); + login->start(); } bool SubscriptionDialog::isSubscriptionChanged() const { - return m_subscriptionChanged; + return m_subscriptionChanged; } -void SubscriptionDialog::onLoginDone( KJob *job ) +void SubscriptionDialog::onLoginDone(KJob *job) { - if ( !job->error() ) { - onReloadRequested(); - } + if (!job->error()) { + onReloadRequested(); + } } void SubscriptionDialog::onReloadRequested() { - enableButton( User1, false ); - m_itemsMap.clear(); - m_model->clear(); - - // we need a connection - if ( !m_session - || m_session->state() != KIMAP::Session::Authenticated ) { - kWarning() << "SubscriptionDialog - got no connection"; - enableButton( User1, true ); - return; - } - - KIMAP::ListJob *list = new KIMAP::ListJob( m_session ); - list->setIncludeUnsubscribed( true ); - connect( list, SIGNAL(mailBoxesReceived(QList,QList >)), - this, SLOT(onMailBoxesReceived(QList,QList >)) ); - connect( list, SIGNAL(result(KJob*)), this, SLOT(onFullListingDone(KJob*)) ); - list->start(); -} - -void SubscriptionDialog::onMailBoxesReceived( const QList &mailBoxes, - const QList< QList > &flags ) -{ - const int numberOfMailBoxes( mailBoxes.size() ); - for ( int i = 0; isetCheckable( isCheckable ); - } - - } else if ( !parentPath.isEmpty() ) { - Q_ASSERT( m_itemsMap.contains( parentPath ) ); - - QStandardItem *parentItem = m_itemsMap[parentPath]; - - QStandardItem *item = new QStandardItem( pathPart ); - item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); - item->setCheckable( isCheckable ); - item->setData( currentPath.mid( 1 ), PathRole ); - parentItem->appendRow( item ); - m_itemsMap[currentPath] = item; - - } else { - QStandardItem *item = new QStandardItem( pathPart ); - item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); - item->setCheckable( isCheckable ); - item->setData( currentPath.mid( 1 ), PathRole ); - m_model->appendRow( item ); - m_itemsMap[currentPath] = item; - } - - parentPath = currentPath; + mUser1Button->setEnabled(false); + m_itemsMap.clear(); + m_model->clear(); + + // we need a connection + if (!m_session + || m_session->state() != KIMAP::Session::Authenticated) { + qCWarning(IMAPRESOURCE_LOG) << "SubscriptionDialog - got no connection"; + mUser1Button->setEnabled(true); + return; } - } -} -void SubscriptionDialog::onFullListingDone( KJob *job ) -{ - if ( job->error() ) { - enableButton( User1, true ); - return; - } + KIMAP::ListJob *list = new KIMAP::ListJob(m_session); + list->setIncludeUnsubscribed(true); + connect(list, &KIMAP::ListJob::mailBoxesReceived, this, &SubscriptionDialog::onMailBoxesReceived); + connect(list, &KIMAP::ListJob::result, this, &SubscriptionDialog::onFullListingDone); + list->start(); +} + +void SubscriptionDialog::onMailBoxesReceived(const QList &mailBoxes, + const QList< QList > &flags) +{ + const int numberOfMailBoxes(mailBoxes.size()); + for (int i = 0; i < numberOfMailBoxes; i++) { + KIMAP::MailBoxDescriptor mailBox = mailBoxes[i]; + + const QStringList pathParts = mailBox.name.split(mailBox.separator); + const QString separator = mailBox.separator; + Q_ASSERT(separator.size() == 1); // that's what the spec says + + QString parentPath; + QString currentPath; + const int numberOfPath(pathParts.size()); + for (int j = 0; j < pathParts.size(); ++j) { + const bool isDummy = (j != (numberOfPath - 1)); + const bool isCheckable = !isDummy && !flags[i].contains("\\noselect"); + + const QString pathPart = pathParts.at(j); + currentPath += separator + pathPart; + + if (m_itemsMap.contains(currentPath)) { + if (!isDummy) { + QStandardItem *item = m_itemsMap[currentPath]; + item->setCheckable(isCheckable); + } + + } else if (!parentPath.isEmpty()) { + Q_ASSERT(m_itemsMap.contains(parentPath)); + + QStandardItem *parentItem = m_itemsMap[parentPath]; + + QStandardItem *item = new QStandardItem(pathPart); + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + item->setCheckable(isCheckable); + item->setData(currentPath.mid(1), PathRole); + parentItem->appendRow(item); + m_itemsMap[currentPath] = item; + + } else { + QStandardItem *item = new QStandardItem(pathPart); + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + item->setCheckable(isCheckable); + item->setData(currentPath.mid(1), PathRole); + m_model->appendRow(item); + m_itemsMap[currentPath] = item; + } - KIMAP::ListJob *list = new KIMAP::ListJob( m_session ); - list->setIncludeUnsubscribed( false ); - connect( list, SIGNAL(mailBoxesReceived(QList,QList >)), - this, SLOT(onSubscribedMailBoxesReceived(QList,QList >)) ); - connect( list, SIGNAL(result(KJob*)), this, SLOT(onReloadDone(KJob*)) ); - list->start(); + parentPath = currentPath; + } + } } -void SubscriptionDialog::onSubscribedMailBoxesReceived( const QList &mailBoxes, - const QList< QList > &flags ) +void SubscriptionDialog::onFullListingDone(KJob *job) { - Q_UNUSED( flags ); - const int numberOfMailBoxes( mailBoxes.size() ); - for ( int i = 0; ierror()) { + mUser1Button->setEnabled(true); + return; + } - if ( m_itemsMap.contains( descriptor ) ) { - QStandardItem *item = m_itemsMap[mailBox.separator + mailBox.name]; - item->setCheckState( Qt::Checked ); - item->setData( Qt::Checked, InitialStateRole ); + KIMAP::ListJob *list = new KIMAP::ListJob(m_session); + list->setIncludeUnsubscribed(false); + connect(list, &KIMAP::ListJob::mailBoxesReceived, this, &SubscriptionDialog::onSubscribedMailBoxesReceived); + connect(list, &KIMAP::ListJob::result, this, &SubscriptionDialog::onReloadDone); + list->start(); +} + +void SubscriptionDialog::onSubscribedMailBoxesReceived(const QList &mailBoxes, + const QList< QList > &flags) +{ + Q_UNUSED(flags); + const int numberOfMailBoxes(mailBoxes.size()); + for (int i = 0; i < numberOfMailBoxes; ++i) { + KIMAP::MailBoxDescriptor mailBox = mailBoxes.at(i); + QString descriptor = mailBox.separator + mailBox.name; + + if (m_itemsMap.contains(descriptor)) { + QStandardItem *item = m_itemsMap[mailBox.separator + mailBox.name]; + item->setCheckState(Qt::Checked); + item->setData(Qt::Checked, InitialStateRole); + } } - } } -void SubscriptionDialog::onReloadDone( KJob *job ) +void SubscriptionDialog::onReloadDone(KJob *job) { - Q_UNUSED( job ); - enableButton( User1, true ); + Q_UNUSED(job); + mUser1Button->setEnabled(true); } -void SubscriptionDialog::onItemChanged( QStandardItem *item ) +void SubscriptionDialog::onItemChanged(QStandardItem *item) { - QFont font = item->font(); - font.setBold( item->checkState()!=item->data( InitialStateRole ).toInt() ); - item->setFont( font ); + QFont font = item->font(); + font.setBold(item->checkState() != item->data(InitialStateRole).toInt()); + item->setFont(font); } -void SubscriptionDialog::slotButtonClicked( int button ) +void SubscriptionDialog::slotAccepted() { - if ( button == KDialog::Ok ) { applyChanges(); accept(); - } else { - KDialog::slotButtonClicked( button ); - } } void SubscriptionDialog::applyChanges() { - QList items = m_itemsMap.values(); + QList items = m_itemsMap.values(); - while ( !items.isEmpty() ) { - QStandardItem *item = items.takeFirst(); + while (!items.isEmpty()) { + QStandardItem *item = items.takeFirst(); - if ( item->checkState()!=item->data( InitialStateRole ).toInt() ) { - if ( item->checkState() == Qt::Checked ) { - kDebug() << "Subscribing" << item->data( PathRole ); - KIMAP::SubscribeJob *subscribe = new KIMAP::SubscribeJob( m_session ); - subscribe->setMailBox( item->data( PathRole ).toString() ); - subscribe->exec(); - } else { - kDebug() << "Unsubscribing" << item->data( PathRole ); - KIMAP::UnsubscribeJob *unsubscribe = new KIMAP::UnsubscribeJob( m_session ); - unsubscribe->setMailBox( item->data( PathRole ).toString() ); - unsubscribe->exec(); - } + if (item->checkState() != item->data(InitialStateRole).toInt()) { + if (item->checkState() == Qt::Checked) { + qCDebug(IMAPRESOURCE_LOG) << "Subscribing" << item->data(PathRole); + KIMAP::SubscribeJob *subscribe = new KIMAP::SubscribeJob(m_session); + subscribe->setMailBox(item->data(PathRole).toString()); + subscribe->exec(); + } else { + qCDebug(IMAPRESOURCE_LOG) << "Unsubscribing" << item->data(PathRole); + KIMAP::UnsubscribeJob *unsubscribe = new KIMAP::UnsubscribeJob(m_session); + unsubscribe->setMailBox(item->data(PathRole).toString()); + unsubscribe->exec(); + } - m_subscriptionChanged = true; + m_subscriptionChanged = true; + } } - } } -SubscriptionFilterProxyModel::SubscriptionFilterProxyModel( QObject* parent ) - : KRecursiveFilterProxyModel( parent ), m_checkedOnly( false ) +SubscriptionFilterProxyModel::SubscriptionFilterProxyModel(QObject *parent) + : KRecursiveFilterProxyModel(parent), m_checkedOnly(false) { } -void SubscriptionFilterProxyModel::setSearchPattern( const QString &pattern ) +void SubscriptionFilterProxyModel::setSearchPattern(const QString &pattern) { - if(m_pattern != pattern) { - m_pattern = pattern; - invalidate(); - } + if (m_pattern != pattern) { + m_pattern = pattern; + invalidate(); + } } -void SubscriptionFilterProxyModel::setIncludeCheckedOnly( bool checkedOnly ) +void SubscriptionFilterProxyModel::setIncludeCheckedOnly(bool checkedOnly) { - if (m_checkedOnly != checkedOnly) { - m_checkedOnly = checkedOnly; - invalidate(); - } + if (m_checkedOnly != checkedOnly) { + m_checkedOnly = checkedOnly; + invalidate(); + } } -void SubscriptionFilterProxyModel::setIncludeCheckedOnly( int checkedOnlyState ) +void SubscriptionFilterProxyModel::setIncludeCheckedOnly(int checkedOnlyState) { - m_checkedOnly = (checkedOnlyState == Qt::Checked); - invalidate(); + m_checkedOnly = (checkedOnlyState == Qt::Checked); + invalidate(); } bool SubscriptionFilterProxyModel::acceptRow(int sourceRow, const QModelIndex &sourceParent) const { - QModelIndex sourceIndex = sourceModel()->index( sourceRow, 0, sourceParent ); + QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent); - const bool checked = sourceIndex.data(Qt::CheckStateRole).toInt()==Qt::Checked; + const bool checked = sourceIndex.data(Qt::CheckStateRole).toInt() == Qt::Checked; - if ( m_checkedOnly && !checked ) { - return false; - } else if ( !m_pattern.isEmpty() ) { - const QString text = sourceIndex.data(Qt::DisplayRole).toString(); - return text.contains( m_pattern, Qt::CaseInsensitive ); - } else { - return true; - } + if (m_checkedOnly && !checked) { + return false; + } else if (!m_pattern.isEmpty()) { + const QString text = sourceIndex.data(Qt::DisplayRole).toString(); + return text.contains(m_pattern, Qt::CaseInsensitive); + } else { + return true; + } } -void SubscriptionDialog::onMobileLineEditChanged( const QString &text ) +void SubscriptionDialog::onMobileLineEditChanged(const QString &text) { - if ( !text.isEmpty() && !m_lineEdit->isVisible() ) { - m_lineEdit->show(); - m_lineEdit->setFocus(); - m_lineEdit->grabKeyboard(); // Now the line edit runs the show - } else if ( text.isEmpty() && m_lineEdit->isVisible() ) { - m_lineEdit->hide(); - grabKeyboard(); // Line edit gone, so let's get all the events for us again + if (!text.isEmpty() && !m_lineEdit->isVisible()) { + m_lineEdit->show(); + m_lineEdit->setFocus(); + m_lineEdit->grabKeyboard(); // Now the line edit runs the show + } else if (text.isEmpty() && m_lineEdit->isVisible()) { + m_lineEdit->hide(); + grabKeyboard(); // Line edit gone, so let's get all the events for us again } } -void SubscriptionDialog::keyPressEvent( QKeyEvent *event ) +void SubscriptionDialog::keyPressEvent(QKeyEvent *event) { #ifndef KDEPIM_MOBILE_UI - KDialog::keyPressEvent( event ); + QDialog::keyPressEvent(event); #else - static bool isSendingEvent = false; + static bool isSendingEvent = false; - if ( !isSendingEvent - && !event->text().isEmpty() - && !m_lineEdit->isVisible() ) { - isSendingEvent = true; - QCoreApplication::sendEvent( m_lineEdit, event ); - isSendingEvent = false; - } else { - KDialog::keyPressEvent( event ); - } + if (!isSendingEvent + && !event->text().isEmpty() + && !m_lineEdit->isVisible()) { + isSendingEvent = true; + QCoreApplication::sendEvent(m_lineEdit, event); + isSendingEvent = false; + } else { + QDialog::keyPressEvent(event); + } #endif } diff -Nru kdepim-runtime-4.14.6/resources/imap/subscriptiondialog.h kdepim-runtime-15.08.0/resources/imap/subscriptiondialog.h --- kdepim-runtime-4.14.6/resources/imap/subscriptiondialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/subscriptiondialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,7 +22,7 @@ #ifndef SUBSCRIPTIONDIALOG_H #define SUBSCRIPTIONDIALOG_H -#include +#include #include #include @@ -33,92 +33,92 @@ class QStandardItemModel; class QStandardItem; -class KLineEdit; +class QLineEdit; class QCheckBox; class ImapAccount; class QTreeView; class QListView; - +class QPushButton; class SubscriptionFilterProxyModel : public KRecursiveFilterProxyModel { - Q_OBJECT + Q_OBJECT public: - explicit SubscriptionFilterProxyModel( QObject* parent = 0 ); + explicit SubscriptionFilterProxyModel(QObject *parent = Q_NULLPTR); -public slots: - void setSearchPattern( const QString &pattern ); - void setIncludeCheckedOnly( bool checkedOnly ); - void setIncludeCheckedOnly( int checkedOnlyState ); +public Q_SLOTS: + void setSearchPattern(const QString &pattern); + void setIncludeCheckedOnly(bool checkedOnly); + void setIncludeCheckedOnly(int checkedOnlyState); protected: - /*reimp*/ bool acceptRow(int sourceRow, const QModelIndex &sourceParent) const; + /*reimp*/ bool acceptRow(int sourceRow, const QModelIndex &sourceParent) const Q_DECL_OVERRIDE; private: - QString m_pattern; - bool m_checkedOnly; + QString m_pattern; + bool m_checkedOnly; }; - -class SubscriptionDialog : public KDialog +class SubscriptionDialog : public QDialog { - Q_OBJECT + Q_OBJECT public: - enum Roles { - InitialStateRole = Qt::UserRole + 1, - PathRole - }; - enum SubscriptionDialogOption { - None = 0, - AllowToEnableSubscription = 1 - }; - Q_DECLARE_FLAGS( SubscriptionDialogOptions, SubscriptionDialogOption ) - - explicit SubscriptionDialog( QWidget *parent = 0, SubscriptionDialog::SubscriptionDialogOptions option = SubscriptionDialog::None ); - ~SubscriptionDialog(); - - void connectAccount( const ImapAccount &account, const QString &password ); - bool isSubscriptionChanged() const; - void setSubscriptionEnabled( bool enabled ); - bool subscriptionEnabled() const; - -private slots: - void onLoginDone( KJob *job ); - void onReloadRequested(); - void onMailBoxesReceived( const QList &mailBoxes, - const QList< QList > &flags ); - void onFullListingDone( KJob *job ); - void onSubscribedMailBoxesReceived( const QList &mailBoxes, - const QList< QList > &flags ); - void onReloadDone( KJob *job ); - void onItemChanged( QStandardItem *item ); - void onMobileLineEditChanged( const QString &text ); + enum Roles { + InitialStateRole = Qt::UserRole + 1, + PathRole + }; + enum SubscriptionDialogOption { + None = 0, + AllowToEnableSubscription = 1 + }; + Q_DECLARE_FLAGS(SubscriptionDialogOptions, SubscriptionDialogOption) + + explicit SubscriptionDialog(QWidget *parent = Q_NULLPTR, SubscriptionDialog::SubscriptionDialogOptions option = SubscriptionDialog::None); + ~SubscriptionDialog(); + + void connectAccount(const ImapAccount &account, const QString &password); + bool isSubscriptionChanged() const; + void setSubscriptionEnabled(bool enabled); + bool subscriptionEnabled() const; + +private Q_SLOTS: + void onLoginDone(KJob *job); + void onReloadRequested(); + void onMailBoxesReceived(const QList &mailBoxes, + const QList< QList > &flags); + void onFullListingDone(KJob *job); + void onSubscribedMailBoxesReceived(const QList &mailBoxes, + const QList< QList > &flags); + void onReloadDone(KJob *job); + void onItemChanged(QStandardItem *item); + void onMobileLineEditChanged(const QString &text); - void slotSearchPattern(const QString &pattern); + void slotSearchPattern(const QString &pattern); protected: - /* reimp */ void keyPressEvent( QKeyEvent *event ); + /* reimp */ void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; -protected slots: - void slotButtonClicked( int button ); +protected Q_SLOTS: + void slotAccepted(); private: - void readConfig(); - void writeConfig(); - void applyChanges(); + void readConfig(); + void writeConfig(); + void applyChanges(); - KIMAP::Session *m_session; - bool m_subscriptionChanged; + KIMAP::Session *m_session; + bool m_subscriptionChanged; #ifndef KDEPIM_MOBILE_UI - QTreeView *m_treeView; + QTreeView *m_treeView; #else - QListView* m_listView; + QListView *m_listView; #endif - KLineEdit *m_lineEdit; - QCheckBox *m_enableSubscription; - SubscriptionFilterProxyModel *m_filter; - QStandardItemModel *m_model; - QMap m_itemsMap; + QLineEdit *m_lineEdit; + QCheckBox *m_enableSubscription; + SubscriptionFilterProxyModel *m_filter; + QStandardItemModel *m_model; + QMap m_itemsMap; + QPushButton *mUser1Button; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/CMakeLists.txt kdepim-runtime-15.08.0/resources/imap/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/imap/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,53 +1,15 @@ +kde_enable_exceptions() set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) -# if kdepimlibs was built without -DKDE4_BUILD_TESTS, kimaptest doesn't exist. -find_path(KIMAPTEST_INCLUDE_DIR NAMES kimaptest/fakeserver.h) -find_library(KIMAPTEST_LIBRARY NAMES kimaptest) - -if(KIMAPTEST_INCLUDE_DIR AND KIMAPTEST_LIBRARY) - MACRO(IMAP_RESOURCE_UNIT_TESTS) - FOREACH(_testname ${ARGN}) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/..) - kde4_add_unit_test(${_testname} TESTNAME imap-${_testname} NOGUI ${_testname}.cpp - dummypasswordrequester.cpp - dummyresourcestate.cpp - imaptestbase.cpp - ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}") - target_link_libraries(${_testname} ${KDE4_KDECORE_LIBS} - ${KDEPIMLIBS_KIMAP_LIBS} ${KDEPIMLIBS_KIMAP_LIBS} ${KIMAPTEST_LIBRARY} ${QT_QTTEST_LIBRARY} imapresource) - add_definitions(-DTEST_DATA="\\"${CMAKE_CURRENT_SOURCE_DIR}\\"") - ENDFOREACH(_testname) - ENDMACRO(IMAP_RESOURCE_UNIT_TESTS) - - IMAP_RESOURCE_UNIT_TESTS( - testresourcetask - testsessionpool - - testaddcollectiontask - testadditemtask - testchangecollectiontask - testchangeitemtask - testexpungecollectiontask - testmovecollectiontask - testmoveitemstask - testremovecollectionrecursivetask - testretrievecollectionmetadatatask - testretrievecollectionstask - testretrieveitemtask - testretrieveitemstask - ) - -endif() - set(testsubscriptiondialog_SRCS testsubscriptiondialog.cpp ../imapaccount.cpp ../subscriptiondialog.cpp + ../imapresource_debug.cpp ) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/..) -kde4_add_executable(testsubscriptiondialog ${testsubscriptiondialog_SRCS}) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}") -target_link_libraries(testsubscriptiondialog ${KDE4_KIO_LIBS} ${KDEPIMLIBS_KIMAP_LIBS} ${KDEPIMLIBS_KMIME_LIBS}) +add_executable(testsubscriptiondialog ${testsubscriptiondialog_SRCS}) + +target_link_libraries(testsubscriptiondialog KF5::KIOCore KF5::IMAP KF5::Mime KF5::ItemModels Qt5::Widgets KF5::I18n KF5::KIOWidgets KF5::AkonadiCore KF5::MailTransport) diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/dummypasswordrequester.cpp kdepim-runtime-15.08.0/resources/imap/tests/dummypasswordrequester.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/dummypasswordrequester.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/dummypasswordrequester.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "dummypasswordrequester.h" - -#include - -#include - -DummyPasswordRequester::DummyPasswordRequester( QObject *parent) - : PasswordRequesterInterface(parent) -{ - for ( int i=0; i<10; ++i ) { - m_expectedCalls << StandardRequest; - m_results << PasswordRetrieved; - } -} - -QString DummyPasswordRequester::password() const -{ - return m_password; -} - -void DummyPasswordRequester::setPassword( const QString &password ) -{ - m_password = password; -} - -void DummyPasswordRequester::setScenario( const QList &expectedCalls, - const QList &results ) -{ - Q_ASSERT( expectedCalls.size() == results.size() ); - - m_expectedCalls = expectedCalls; - m_results = results; -} - -void DummyPasswordRequester::setDelays( const QList &delays ) -{ - m_delays = delays; -} - -void DummyPasswordRequester::requestPassword( RequestType request, - const QString &/*serverError*/ ) -{ - QVERIFY2( !m_expectedCalls.isEmpty(), QString::fromLatin1( "Got unexpected call: %1" ).arg( request ).toUtf8().constData() ); - QCOMPARE( (int)request, (int)m_expectedCalls.takeFirst() ); - - int delay = 20; - if ( !m_delays.isEmpty() ) { - delay = m_delays.takeFirst(); - } - - QTimer::singleShot( delay, this, SLOT(emitResult()) ); -} - -void DummyPasswordRequester::emitResult() -{ - ResultType result = m_results.takeFirst(); - - if ( result == PasswordRetrieved ) { - emit done( result, m_password ); - } else { - emit done( result ); - } -} - diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/dummypasswordrequester.h kdepim-runtime-15.08.0/resources/imap/tests/dummypasswordrequester.h --- kdepim-runtime-4.14.6/resources/imap/tests/dummypasswordrequester.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/dummypasswordrequester.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef DUMMYPASSWORDREQUESTER_H -#define DUMMYPASSWORDREQUESTER_H - -#include "passwordrequesterinterface.h" - -class DummyPasswordRequester : public PasswordRequesterInterface -{ - Q_OBJECT -public: - DummyPasswordRequester( QObject *parent = 0 ); - - QString password() const; - void setPassword( const QString &password ); - - void setScenario( const QList &expectedCalls, - const QList &results ); - void setDelays( const QList &delays ); - -public: - virtual void requestPassword( RequestType request = StandardRequest, - const QString &serverError = QString() ); - -private slots: - void emitResult(); - -private: - QString m_password; - QList m_expectedCalls; - QList m_results; - QList m_delays; -}; - -#endif - diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/dummyresourcestate.cpp kdepim-runtime-15.08.0/resources/imap/tests/dummyresourcestate.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/dummyresourcestate.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/dummyresourcestate.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,352 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company - Author: Kevin Ottens - - 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 "dummyresourcestate.h" - -Q_DECLARE_METATYPE(QList) -Q_DECLARE_METATYPE(QVector) - -DummyResourceState::DummyResourceState() - : m_automaticExpunge( true ), m_subscriptionEnabled( true ), - m_disconnectedMode( true ), m_intervalCheckTime( -1 ) -{ - qRegisterMetaType >(); - qRegisterMetaType >(); -} - -DummyResourceState::~DummyResourceState() -{ - -} - -void DummyResourceState::setUserName( const QString &name ) -{ - m_userName = name; -} - -QString DummyResourceState::userName() const -{ - return m_userName; -} - -void DummyResourceState::setResourceName( const QString &name ) -{ - m_resourceName = name; -} - -QString DummyResourceState::resourceName() const -{ - return m_resourceName; -} - -void DummyResourceState::setServerCapabilities( const QStringList &capabilities ) -{ - m_capabilities = capabilities; -} - -QStringList DummyResourceState::serverCapabilities() const -{ - return m_capabilities; -} - -void DummyResourceState::setServerNamespaces( const QList &namespaces ) -{ - m_namespaces = namespaces; -} - -QList DummyResourceState::serverNamespaces() const -{ - return m_namespaces; -} - -void DummyResourceState::setAutomaticExpungeEnagled( bool enabled ) -{ - m_automaticExpunge = enabled; -} - -bool DummyResourceState::isAutomaticExpungeEnabled() const -{ - return m_automaticExpunge; -} - -void DummyResourceState::setSubscriptionEnabled( bool enabled ) -{ - m_subscriptionEnabled = enabled; -} - -bool DummyResourceState::isSubscriptionEnabled() const -{ - return m_subscriptionEnabled; -} - -void DummyResourceState::setDisconnectedModeEnabled( bool enabled ) -{ - m_disconnectedMode = enabled; -} - -bool DummyResourceState::isDisconnectedModeEnabled() const -{ - return m_disconnectedMode; -} - -void DummyResourceState::setIntervalCheckTime( int interval ) -{ - m_intervalCheckTime = interval; -} - -int DummyResourceState::intervalCheckTime() const -{ - return m_intervalCheckTime; -} - -void DummyResourceState::setCollection( const Akonadi::Collection &collection ) -{ - m_collection = collection; -} - -Akonadi::Collection DummyResourceState::collection() const -{ - return m_collection; -} - -void DummyResourceState::setItem( const Akonadi::Item &item ) -{ - m_items.clear(); - m_items << item; -} - -Akonadi::Item DummyResourceState::item() const -{ - return m_items.first(); -} - -Akonadi::Item::List DummyResourceState::items() const -{ - return m_items; -} - -void DummyResourceState::setParentCollection( const Akonadi::Collection &collection ) -{ - m_parentCollection = collection; -} - -Akonadi::Collection DummyResourceState::parentCollection() const -{ - return m_parentCollection; -} - -void DummyResourceState::setSourceCollection( const Akonadi::Collection &collection ) -{ - m_sourceCollection = collection; -} - -Akonadi::Collection DummyResourceState::sourceCollection() const -{ - return m_sourceCollection; -} - -void DummyResourceState::setTargetCollection( const Akonadi::Collection &collection ) -{ - m_targetCollection = collection; -} - -Akonadi::Collection DummyResourceState::targetCollection() const -{ - return m_targetCollection; -} - -void DummyResourceState::setParts( const QSet &parts ) -{ - m_parts = parts; -} - -QSet DummyResourceState::parts() const -{ - return m_parts; -} - -QString DummyResourceState::rootRemoteId() const -{ - return QLatin1String("root-id"); -} - -void DummyResourceState::setIdleCollection( const Akonadi::Collection &collection ) -{ - recordCall( "setIdleCollection", QVariant::fromValue( collection ) ); -} - -void DummyResourceState::applyCollectionChanges( const Akonadi::Collection &collection ) -{ - recordCall( "applyCollectionChanges", QVariant::fromValue( collection ) ); -} - -void DummyResourceState::collectionAttributesRetrieved( const Akonadi::Collection &collection ) -{ - recordCall( "collectionAttributesRetrieved", QVariant::fromValue( collection ) ); -} - -void DummyResourceState::itemRetrieved( const Akonadi::Item &item ) -{ - recordCall( "itemRetrieved", QVariant::fromValue(item) ); -} - -void DummyResourceState::itemsRetrieved( const Akonadi::Item::List &items ) -{ - recordCall( "itemsRetrieved", QVariant::fromValue( items ) ); -} - -void DummyResourceState::itemsRetrievedIncremental( const Akonadi::Item::List &changed, const Akonadi::Item::List &removed ) -{ - Q_UNUSED( removed ) - - recordCall( "itemsRetrievedIncremental", QVariant::fromValue( changed ) ); -} - -void DummyResourceState::itemsRetrievalDone() -{ - recordCall( "itemsRetrievalDone" ); -} - -void DummyResourceState::setTotalItems(int) -{ - -} - -QSet< QByteArray > DummyResourceState::addedFlags() const -{ - return QSet(); -} - -QSet< QByteArray > DummyResourceState::removedFlags() const -{ - return QSet(); -} - -void DummyResourceState::itemChangeCommitted( const Akonadi::Item &item ) -{ - recordCall( "itemChangeCommitted", QVariant::fromValue( item ) ); -} - -void DummyResourceState::itemsChangesCommitted( const Akonadi::Item::List &items ) -{ - recordCall( "itemsChangesCommitted", QVariant::fromValue( items ) ); -} - -void DummyResourceState::collectionsRetrieved( const Akonadi::Collection::List &collections ) -{ - recordCall( "collectionsRetrieved", QVariant::fromValue( collections ) ); -} - -void DummyResourceState::collectionChangeCommitted( const Akonadi::Collection &collection ) -{ - recordCall( "collectionChangeCommitted", QVariant::fromValue( collection ) ); -} - -void DummyResourceState::changeProcessed() -{ - recordCall( "changeProcessed" ); -} - -void DummyResourceState::searchFinished( const QVector &result, bool isRid ) -{ - recordCall( "searchFinished", QVariant::fromValue( result ) ); -} - -void DummyResourceState::cancelTask( const QString &errorString ) -{ - recordCall( "cancelTask", QVariant::fromValue(errorString) ); -} - -void DummyResourceState::deferTask() -{ - recordCall( "deferTask" ); -} - -void DummyResourceState::restartItemRetrieval(Akonadi::Entity::Id col) -{ - recordCall( "restartItemRetrieval", QVariant::fromValue(col) ); -} - -void DummyResourceState::taskDone() -{ - recordCall( "taskDone" ); -} - -void DummyResourceState::emitError( const QString &message ) -{ - recordCall( "emitError", QVariant::fromValue(message) ); -} - -void DummyResourceState::emitWarning( const QString &message ) -{ - recordCall( "emitWarning", QVariant::fromValue(message) ); -} - -void DummyResourceState::emitPercent( int percent ) -{ - // FIXME: Many tests need to be updated for this to be uncommented out. - // recordCall( "emitPercent", QVariant::fromValue(percent) ); -} - -void DummyResourceState::synchronizeCollectionTree() -{ - recordCall( "synchronizeCollectionTree" ); -} - -void DummyResourceState::scheduleConnectionAttempt() -{ - recordCall( "scheduleConnectionAttempt" ); -} - -void DummyResourceState::showInformationDialog( const QString &message, const QString&, const QString& ) -{ - recordCall( "showInformationDialog", QVariant::fromValue( message ) ); -} - -QList< QPair > DummyResourceState::calls() const -{ - return m_calls; -} - -QChar DummyResourceState::separatorCharacter() const -{ - return m_separator; -} - -void DummyResourceState::setSeparatorCharacter( const QChar &separator ) -{ - m_separator = separator; -} - -void DummyResourceState::recordCall( const QByteArray callName, const QVariant ¶meter ) -{ - m_calls << QPair( callName, parameter ); -} - -int DummyResourceState::batchSize() const -{ - return 10; -} - -MessageHelper::Ptr DummyResourceState::messageHelper() const -{ - return MessageHelper::Ptr(new MessageHelper()); -} diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/dummyresourcestate.h kdepim-runtime-15.08.0/resources/imap/tests/dummyresourcestate.h --- kdepim-runtime-4.14.6/resources/imap/tests/dummyresourcestate.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/dummyresourcestate.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company - Author: Kevin Ottens - - 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 DUMMYRESOURCESTATE_H -#define DUMMYRESOURCESTATE_H - -#include -#include - -#include "resourcestateinterface.h" - -class DummyResourceState : public ResourceStateInterface -{ -public: - typedef boost::shared_ptr Ptr; - - explicit DummyResourceState(); - ~DummyResourceState(); - - void setUserName( const QString &name ); - virtual QString userName() const; - - void setResourceName( const QString &name ); - virtual QString resourceName() const; - - void setServerCapabilities( const QStringList &capabilities ); - virtual QStringList serverCapabilities() const; - - void setServerNamespaces( const QList &namespaces ); - virtual QList serverNamespaces() const; - - void setAutomaticExpungeEnagled( bool enabled ); - virtual bool isAutomaticExpungeEnabled() const; - - void setSubscriptionEnabled( bool enabled ); - virtual bool isSubscriptionEnabled() const; - void setDisconnectedModeEnabled( bool enabled ); - virtual bool isDisconnectedModeEnabled() const; - void setIntervalCheckTime( int interval ); - virtual int intervalCheckTime() const; - - - void setCollection( const Akonadi::Collection &collection ); - virtual Akonadi::Collection collection() const; - void setItem( const Akonadi::Item &item ); - virtual Akonadi::Item item() const; - virtual Akonadi::Item::List items() const; - - void setParentCollection( const Akonadi::Collection &collection ); - virtual Akonadi::Collection parentCollection() const; - - void setSourceCollection( const Akonadi::Collection &collection ); - virtual Akonadi::Collection sourceCollection() const; - void setTargetCollection( const Akonadi::Collection &collection ); - virtual Akonadi::Collection targetCollection() const; - - void setParts( const QSet &parts ); - virtual QSet parts() const; - - virtual QString rootRemoteId() const; - - virtual void setIdleCollection( const Akonadi::Collection &collection ); - virtual void applyCollectionChanges( const Akonadi::Collection &collection ); - - virtual void collectionAttributesRetrieved( const Akonadi::Collection &collection ); - - virtual void itemRetrieved( const Akonadi::Item &item ); - - virtual void itemsRetrieved( const Akonadi::Item::List &items ); - virtual void itemsRetrievedIncremental( const Akonadi::Item::List &changed, const Akonadi::Item::List &removed ); - virtual void itemsRetrievalDone(); - - virtual void setTotalItems(int); - - virtual QSet< QByteArray > addedFlags() const; - virtual QSet< QByteArray > removedFlags() const; - - virtual void itemChangeCommitted( const Akonadi::Item &item ); - virtual void itemsChangesCommitted(const Akonadi::Item::List& items); - - virtual void collectionsRetrieved( const Akonadi::Collection::List &collections ); - - virtual void collectionChangeCommitted( const Akonadi::Collection &collection ); - - virtual void searchFinished( const QVector &result, bool isRid = true ); - - virtual void changeProcessed(); - - virtual void cancelTask( const QString &errorString ); - virtual void deferTask(); - virtual void restartItemRetrieval(Akonadi::Collection::Id col); - virtual void taskDone(); - - virtual void emitError( const QString &message ); - virtual void emitWarning( const QString &message ); - virtual void emitPercent( int percent ); - - virtual void synchronizeCollectionTree(); - virtual void scheduleConnectionAttempt(); - - virtual QChar separatorCharacter() const; - virtual void setSeparatorCharacter( const QChar &separator ); - - virtual void showInformationDialog( const QString &message, const QString &title, const QString &dontShowAgainName ); - - virtual int batchSize() const; - - virtual MessageHelper::Ptr messageHelper() const; - - QList< QPair > calls() const; - -private: - void recordCall( const QByteArray callName, const QVariant ¶meter = QVariant() ); - - QString m_userName; - QString m_resourceName; - QStringList m_capabilities; - QList m_namespaces; - - bool m_automaticExpunge; - bool m_subscriptionEnabled; - bool m_disconnectedMode; - int m_intervalCheckTime; - QChar m_separator; - - Akonadi::Collection m_collection; - Akonadi::Item::List m_items; - - Akonadi::Collection m_parentCollection; - - Akonadi::Collection m_sourceCollection; - Akonadi::Collection m_targetCollection; - - QSet m_parts; - - QList< QPair > m_calls; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/imaptestbase.cpp kdepim-runtime-15.08.0/resources/imap/tests/imaptestbase.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/imaptestbase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/imaptestbase.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,137 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "imaptestbase.h" - -ImapTestBase::ImapTestBase( QObject *parent ) - : QObject( parent ) -{ - -} - -QString ImapTestBase::defaultUserName() const -{ - return QLatin1String("test@kdab.com"); -} - -QString ImapTestBase::defaultPassword() const -{ - return QLatin1String("foobar"); -} - -ImapAccount *ImapTestBase::createDefaultAccount() const -{ - ImapAccount *account = new ImapAccount; - - account->setServer( QLatin1String("127.0.0.1") ); - account->setPort( 5989 ); - account->setUserName( defaultUserName() ); - account->setSubscriptionEnabled( true ); - account->setEncryptionMode( KIMAP::LoginJob::Unencrypted ); - account->setAuthenticationMode( KIMAP::LoginJob::ClearText ); - - return account; -} - -DummyPasswordRequester *ImapTestBase::createDefaultRequester() -{ - DummyPasswordRequester *requester = new DummyPasswordRequester( this ); - requester->setPassword( defaultPassword() ); - return requester; -} - -void ImapTestBase::setupTestCase() -{ - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); -} - -QList ImapTestBase::defaultAuthScenario() const -{ - QList scenario; - - scenario << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in"; - - return scenario; -} - -QList ImapTestBase::defaultPoolConnectionScenario( const QList &customCapabilities ) const -{ - QList scenario; - - QByteArray caps = "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE"; - Q_FOREACH ( const QByteArray &cap, customCapabilities ) { - caps += " " + cap; - } - - scenario << defaultAuthScenario() - << "C: A000002 CAPABILITY" - << caps - << "S: A000002 OK Completed"; - - return scenario; -} - -bool ImapTestBase::waitForSignal( QObject *obj, const char *member, int timeout ) const -{ - QEventLoop loop; - QTimer timer; - - connect( &timer, SIGNAL(timeout()), &loop, SLOT(quit()) ); - - QSignalSpy spy( obj, member ); - connect( obj, member, &loop, SLOT(quit()) ); - - timer.setSingleShot( true ); - timer.start( timeout ); - loop.exec(); - timer.stop(); - - return spy.count()==1; -} - -Akonadi::Collection ImapTestBase::createCollectionChain( const QString &remoteId ) const -{ - QChar separator = remoteId.length() > 0 ? remoteId.at(0) : QLatin1Char('/'); - - Akonadi::Collection parent( 1 ); - parent.setRemoteId( QLatin1String("root-id") ); - parent.setParentCollection( Akonadi::Collection::root() ); - Akonadi::Entity::Id id = 2; - - Akonadi::Collection collection = parent; - - const QStringList collections = remoteId.split( separator, QString::SkipEmptyParts ); - Q_FOREACH ( const QString &colId, collections ) { - collection = Akonadi::Collection( id ); - collection.setRemoteId( separator + colId ); - collection.setParentCollection( parent ); - - parent = collection; - id++; - } - - return collection; -} - - diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/imaptestbase.h kdepim-runtime-15.08.0/resources/imap/tests/imaptestbase.h --- kdepim-runtime-4.14.6/resources/imap/tests/imaptestbase.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/imaptestbase.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef IMAPTESTBASE_H -#define IMAPTESTBASE_H - -#include - -#include - -#include "dummypasswordrequester.h" -#include "dummyresourcestate.h" -#include "imapaccount.h" -#include "resourcetask.h" -#include "sessionpool.h" - -Q_DECLARE_METATYPE(ImapAccount*) -Q_DECLARE_METATYPE(DummyPasswordRequester*) -Q_DECLARE_METATYPE(DummyResourceState::Ptr) -Q_DECLARE_METATYPE(KIMAP::Session*) -Q_DECLARE_METATYPE(QVariant) - -class ImapTestBase : public QObject -{ - Q_OBJECT - -public: - ImapTestBase( QObject *parent = 0 ); - -protected: - QString defaultUserName() const; - QString defaultPassword() const; - ImapAccount *createDefaultAccount() const; - DummyPasswordRequester *createDefaultRequester(); - QList defaultAuthScenario() const; - QList defaultPoolConnectionScenario( const QList &customCapabilities = QList() ) const; - - bool waitForSignal( QObject *obj, const char *member, int timeout = 500 ) const; - - Akonadi::Collection createCollectionChain( const QString &remoteId ) const; - -private slots: - void setupTestCase(); -}; - -// Taken from Qt 5: -#if QT_VERSION < 0x050000 - -// Will try to wait for the expression to become true while allowing event processing -#define QTRY_VERIFY(__expr) \ -do { \ - const int __step = 50; \ - const int __timeout = 5000; \ - if ( !( __expr ) ) { \ - QTest::qWait( 0 ); \ - } \ - for ( int __i = 0; __i < __timeout && !( __expr ); __i += __step ) { \ - QTest::qWait( __step ); \ - } \ - QVERIFY( __expr ); \ -} while ( 0 ) - -// Will try to wait for the comparison to become successful while allowing event processing -#define QTRY_COMPARE(__expr, __expected) \ -do { \ - const int __step = 50; \ - const int __timeout = 5000; \ - if ( ( __expr ) != ( __expected ) ) { \ - QTest::qWait( 0 ); \ - } \ - for ( int __i = 0; __i < __timeout && ( ( __expr ) != ( __expected ) ); __i += __step ) { \ - QTest::qWait( __step ); \ - } \ - QCOMPARE( __expr, __expected ); \ -} while ( 0 ) - -#endif - -#endif diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/testaddcollectiontask.cpp kdepim-runtime-15.08.0/resources/imap/tests/testaddcollectiontask.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/testaddcollectiontask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/testaddcollectiontask.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,181 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "imaptestbase.h" - -#include "addcollectiontask.h" -#include - -class TestAddCollectionTask : public ImapTestBase -{ - Q_OBJECT - -private slots: - void shouldCreateAndSubscribe_data() - { - QTest::addColumn( "parentCollection" ); - QTest::addColumn( "collection" ); - QTest::addColumn< QList >( "scenario" ); - QTest::addColumn( "callNames" ); - QTest::addColumn( "collectionName" ); - QTest::addColumn( "remoteId" ); - - Akonadi::Collection parentCollection; - Akonadi::Collection collection; - QList scenario; - QStringList callNames; - - parentCollection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection = Akonadi::Collection( 4 ); - collection.setName( QLatin1String("Bar") ); - collection.setParentCollection( parentCollection ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 CREATE \"INBOX/Foo/Bar\"" - << "S: A000003 OK create done" - << "C: A000004 SUBSCRIBE \"INBOX/Foo/Bar\"" - << "S: A000004 OK subscribe done"; - - callNames.clear(); - callNames << QLatin1String("collectionChangeCommitted") << QLatin1String("synchronizeCollectionTree"); - - QTest::newRow( "trivial case" ) << parentCollection << collection << scenario << callNames - << collection.name() << "/Bar"; - - parentCollection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection = Akonadi::Collection( 4 ); - collection.setName( QLatin1String("Bar/Baz") ); - collection.setParentCollection( parentCollection ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 CREATE \"INBOX/Foo/BarBaz\"" - << "S: A000003 OK create done" - << "C: A000004 SUBSCRIBE \"INBOX/Foo/BarBaz\"" - << "S: A000004 OK subscribe done"; - - callNames.clear(); - callNames << QLatin1String("collectionChangeCommitted") << QLatin1String("synchronizeCollectionTree"); - - QTest::newRow( "folder with invalid separator" ) << parentCollection << collection << scenario - << callNames << "BarBaz" << "/BarBaz"; - - parentCollection = createCollectionChain( QLatin1String(".INBOX") ); - collection = Akonadi::Collection( 3 ); - collection.setName ( QLatin1String("Foo") ); - collection.setParentCollection( parentCollection ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 CREATE \"INBOX.Foo\"" - << "S: A000003 OK create done" - << "C: A000004 SUBSCRIBE \"INBOX.Foo\"" - << "S: A000004 OK subscribe done"; - callNames.clear(); - callNames << QLatin1String("collectionChangeCommitted") << QLatin1String("synchronizeCollectionTree"); - - QTest::newRow( "folder with non-standard separator") << parentCollection << collection << scenario - << callNames << "Foo" << ".Foo"; - - parentCollection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection = Akonadi::Collection( 4 ); - collection.setName( QLatin1String("Bar") ); - collection.setParentCollection( parentCollection ); - Akonadi::CollectionAnnotationsAttribute *attr = collection.attribute( Akonadi::Collection::AddIfMissing ); - QMap annotations; - annotations.insert( "/shared/vendor/foobar/foo", "value" ); - attr->setAnnotations( annotations ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 CREATE \"INBOX/Foo/Bar\"" - << "S: A000003 OK create done" - << "C: A000004 SUBSCRIBE \"INBOX/Foo/Bar\"" - << "S: A000004 OK subscribe done" - << "C: A000005 SETMETADATA \"INBOX/Foo/Bar\" (\"/shared/vendor/foobar/foo\" {5}\r\nvalue)" - << "S: A000005 OK SETMETADATA complete"; - - callNames.clear(); - callNames << QLatin1String("collectionChangeCommitted"); - - QTest::newRow( "folder with annotations" ) << parentCollection << collection << scenario << callNames - << collection.name() << "/Bar"; - } - - void shouldCreateAndSubscribe() - { - QFETCH( Akonadi::Collection, parentCollection ); - QFETCH( Akonadi::Collection, collection ); - QFETCH( QList, scenario ); - QFETCH( QStringList, callNames ); - QFETCH( QString, collectionName ); - QFETCH( QString, remoteId ); - - FakeServer server; - server.setScenario( scenario ); - server.startAndWait(); - - SessionPool pool( 1 ); - - pool.setPasswordRequester( createDefaultRequester() ); - QVERIFY( pool.connect( createDefaultAccount() ) ); - QVERIFY( waitForSignal( &pool, SIGNAL(connectDone(int,QString)) ) ); - - DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); - state->setParentCollection( parentCollection ); - state->setCollection( collection ); - if (collection.hasAttribute()) { - state->setServerCapabilities( QStringList() << "METADATA" ); - } - AddCollectionTask *task = new AddCollectionTask( state ); - task->start( &pool ); - - QTRY_COMPARE( state->calls().count(), callNames.size() ); - for ( int i = 0; i < callNames.size(); i++ ) { - QString command = QString::fromUtf8( state->calls().at( i ).first ); - QVariant parameter = state->calls().at( i ).second; - - if ( command==QLatin1String("cancelTask") && callNames[i]!=QLatin1String("cancelTask") ) { - kDebug() << "Got a cancel:" << parameter.toString(); - } - - if ( command == QLatin1String("collectionChangeCommitted") ) { - QCOMPARE( parameter.value().name(), collectionName ); - QCOMPARE( parameter.value().remoteId().right( collectionName.length() ), - collectionName ); - QCOMPARE( parameter.value().remoteId(), remoteId ); - } - - QCOMPARE( command, callNames[i] ); - - if ( command == QLatin1String("cancelTask") ) { - QVERIFY( !parameter.toString().isEmpty() ); - } - } - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } -}; - -QTEST_KDEMAIN_CORE( TestAddCollectionTask ) - -#include "testaddcollectiontask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/testadditemtask.cpp kdepim-runtime-15.08.0/resources/imap/tests/testadditemtask.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/testadditemtask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/testadditemtask.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,184 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "imaptestbase.h" - -#include "additemtask.h" - -#include "uidnextattribute.h" - -#include - -class TestAddItemTask : public ImapTestBase -{ - Q_OBJECT - -private slots: - void shouldAppendMessage_data() - { - QTest::addColumn( "item" ); - QTest::addColumn( "collection" ); - QTest::addColumn< QList >( "scenario" ); - QTest::addColumn( "callNames" ); - - Akonadi::Collection collection; - Akonadi::Item item; - QString messageContent; - QList scenario; - QStringList callNames; - - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - UidNextAttribute *uidNext = new UidNextAttribute; - uidNext->setUidNext( 63 ); - collection.addAttribute( uidNext ); - - item = Akonadi::Item( 2 ); - item.setParentCollection( collection ); - - KMime::Message::Ptr message(new KMime::Message); - - messageContent = QLatin1String("From: ervin\nTo: someone\nSubject: foo\n\nSpeechless..."); - - message->setContent( messageContent.toUtf8() ); - message->parse(); - item.setPayload( message ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 APPEND \"INBOX/Foo\" {55}\r\n"+message->encodedContent(true) - << "S: A000003 OK append done [ APPENDUID 1239890035 66 ]"; - - callNames.clear(); - callNames << QLatin1String("itemChangeCommitted"); - - QTest::newRow( "trivial case" ) << item << collection << scenario << callNames; - - - - message = KMime::Message::Ptr( new KMime::Message ); - - messageContent = QLatin1String("From: ervin\nTo: someone\nSubject: foo\nMessage-ID: <42.4242.foo@bar.org>\n\nSpeechless..."); - - message->setContent( messageContent.toUtf8() ); - message->parse(); - item.setPayload( message ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 APPEND \"INBOX/Foo\" {90}\r\n"+message->encodedContent(true) - << "S: A000003 OK append done" - << "C: A000004 SELECT \"INBOX/Foo\"" - << "S: A000004 OK select done" - << "C: A000005 UID SEARCH HEADER Message-ID <42.4242.foo@bar.org>" - << "S: * SEARCH 66" - << "S: A000005 OK search done"; - - callNames.clear(); - callNames << QLatin1String("itemChangeCommitted"); - - QTest::newRow( "no APPENDUID, message contained Message-ID" ) << item << collection << scenario << callNames; - - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 APPEND \"INBOX/Foo\" {90}\r\n"+message->encodedContent(true) - << "S: A000003 OK append done" - << "C: A000004 SELECT \"INBOX/Foo\"" - << "S: A000004 OK select done" - << "C: A000005 UID SEARCH HEADER Message-ID <42.4242.foo@bar.org>" - << "S: * SEARCH 65 66" - << "S: A000005 OK search done"; - callNames.clear(); - callNames << QLatin1String("itemChangeCommitted"); - QTest::newRow( "no APPENDUID, message contained non-unique Message-ID" ) << item << collection << scenario << callNames; - - - - message = KMime::Message::Ptr( new KMime::Message ); - - messageContent = QLatin1String("From: ervin\nTo: someone\nSubject: foo\n\nSpeechless..."); - - message->setContent( messageContent.toUtf8() ); - message->parse(); - item.setPayload(message); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 APPEND \"INBOX/Foo\" {55}\r\n"+message->encodedContent(true) - << "S: A000003 OK append done" - << "C: A000004 SELECT \"INBOX/Foo\"" - << "S: A000004 OK select done" - << "C: A000005 UID SEARCH NEW UID 63:*" - << "S: * SEARCH 66" - << "S: A000005 OK search done"; - - callNames.clear(); - callNames << QLatin1String("itemChangeCommitted"); - - QTest::newRow( "no APPENDUID, message didn't contain Message-ID" ) << item << collection << scenario << callNames; - } - - void shouldAppendMessage() - { - QFETCH( Akonadi::Item, item ); - QFETCH( Akonadi::Collection, collection ); - QFETCH( QList, scenario ); - QFETCH( QStringList, callNames ); - - FakeServer server; - server.setScenario( scenario ); - server.startAndWait(); - - SessionPool pool( 1 ); - - pool.setPasswordRequester( createDefaultRequester() ); - QVERIFY( pool.connect( createDefaultAccount() ) ); - QVERIFY( waitForSignal( &pool, SIGNAL(connectDone(int,QString)) ) ); - - DummyResourceState::Ptr state = DummyResourceState::Ptr( new DummyResourceState ); - state->setCollection( collection ); - state->setItem( item ); - AddItemTask *task = new AddItemTask( state ); - task->start( &pool ); - - QTRY_COMPARE( state->calls().count(), callNames.size() ); - for ( int i = 0; i < callNames.size(); i++ ) { - QString command = QString::fromUtf8( state->calls().at( i ).first ); - QVariant parameter = state->calls().at( i ).second; - - if ( command == QLatin1String("cancelTask") && callNames[i] != QLatin1String("cancelTask") ) { - kDebug() << "Got a cancel:" << parameter.toString(); - } - - QCOMPARE( command, callNames[i] ); - - if ( command == QLatin1String("cancelTask") ) { - QVERIFY( !parameter.toString().isEmpty() ); - } - } - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } -}; - -QTEST_KDEMAIN_CORE( TestAddItemTask ) - -#include "testadditemtask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/testchangecollectiontask.cpp kdepim-runtime-15.08.0/resources/imap/tests/testchangecollectiontask.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/testchangecollectiontask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/testchangecollectiontask.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,244 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "imaptestbase.h" - -#include "changecollectiontask.h" - -#include "collectionannotationsattribute.h" -#include "imapaclattribute.h" - -Q_DECLARE_METATYPE( QSet ) - -class TestChangeCollectionTask : public ImapTestBase -{ - Q_OBJECT - -private slots: - void shouldUpdateMetadataAclAndName_data() - { - QTest::addColumn( "collection" ); - QTest::addColumn< QSet >( "parts" ); - QTest::addColumn< QList >( "scenario" ); - QTest::addColumn( "callNames" ); - QTest::addColumn( "collectionName" ); - QTest::addColumn( "caps" ); - - Akonadi::Collection collection; - QSet parts; - QList scenario; - QStringList callNames; - QStringList caps; - - collection = createCollectionChain( QLatin1String("/Foo") ); - collection.setName( QLatin1String("Bar") ); - collection.setRights( Akonadi::Collection::AllRights ); - - Akonadi::ImapAclAttribute *acls = new Akonadi::ImapAclAttribute; - QMap rights; - // Old rights - rights["test@kdab.com"] = KIMAP::Acl::rightsFromString( "lrswipckxtda" ); - rights["foo@kde.org"] = KIMAP::Acl::rightsFromString( "lrswipcda" ); - acls->setRights( rights ); - - // New rights - rights["test@kdab.com"] = KIMAP::Acl::rightsFromString( "lrswipckxtda" ); - rights["foo@kde.org"] = KIMAP::Acl::rightsFromString( "lrswipcda" ); - acls->setRights( rights ); - collection.addAttribute( acls ); - - Akonadi::CollectionAnnotationsAttribute *annotationsAttr = new Akonadi::CollectionAnnotationsAttribute; - QMap annotations; - annotations["/vendor/kolab/folder-test"] = "false"; - annotations["/vendor/kolab/folder-test2"] = "true"; - annotationsAttr->setAnnotations( annotations ); - collection.addAttribute( annotationsAttr ); - - parts << "NAME" << "AccessRights" << "imapacl" << "collectionannotations"; - - caps << "ACL" << "ANNOTATEMORE"; - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SETACL \"Foo\" \"test@kdab.com\" \"lrswipckxtda\"" - << "S: A000003 OK acl changed" - << "C: A000004 SETANNOTATION \"Foo\" \"/vendor/kolab/folder-test\" (\"value.shared\" \"false\")" - << "S: A000004 OK annotations changed" - << "C: A000005 SETANNOTATION \"Foo\" \"/vendor/kolab/folder-test2\" (\"value.shared\" \"true\")" - << "S: A000005 OK annotations changed" - << "C: A000006 SETACL \"Foo\" \"foo@kde.org\" \"lrswipcda\"" - << "S: A000006 OK acl changed" - << "C: A000007 SETACL \"Foo\" \"test@kdab.com\" \"lrswipckxtda\"" - << "S: A000007 OK acl changed" - << "C: A000008 RENAME \"Foo\" \"Bar\"" - << "S: A000008 OK rename done" - << "C: A000009 SUBSCRIBE \"Bar\"" - << "S: A000009 OK mailbox subscribed"; - - callNames.clear(); - callNames << QLatin1String("collectionChangeCommitted"); - - QTest::newRow( "complete case" ) << collection << parts << scenario << callNames << collection.name() << caps; - - caps.clear(); - caps << "ACL"; - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SETACL \"Foo\" \"test@kdab.com\" \"lrswipckxtda\"" - << "S: A000003 OK acl changed" - << "C: A000004 SETACL \"Foo\" \"foo@kde.org\" \"lrswipcda\"" - << "S: A000004 OK acl changed" - << "C: A000005 SETACL \"Foo\" \"test@kdab.com\" \"lrswipckxtda\"" - << "S: A000005 OK acl changed" - << "C: A000006 RENAME \"Foo\" \"Bar\"" - << "S: A000006 OK rename done" - << "C: A000007 SUBSCRIBE \"Bar\"" - << "S: A000007 OK mailbox subscribed"; - QTest::newRow( "no ANNOTATEMORE support" ) << collection << parts << scenario << callNames << collection.name() << caps; - - collection = createCollectionChain( QLatin1String("/Foo") ); - collection.setName( QLatin1String("Bar/Baz") ); - caps.clear(); - caps << "ACL" << "ANNOTATEMORE"; - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 RENAME \"Foo\" \"BarBaz\"" - << "S: A000003 OK rename done" - << "C: A000004 SUBSCRIBE \"BarBaz\"" - << "S: A000004 OK mailbox subscribed"; - parts.clear(); - parts << "NAME"; - callNames.clear(); - callNames << QLatin1String("collectionChangeCommitted"); - QTest::newRow( "rename with invalid separator" ) << collection << parts << scenario << callNames - << "BarBaz" << caps; - - collection = createCollectionChain( QLatin1String(".INBOX.Foo") ); - collection.setName( QLatin1String("Bar") ); - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 RENAME \"INBOX.Foo\" \"INBOX.Bar\"" - << "S: A000003 OK rename done" - << "C: A000004 SUBSCRIBE \"INBOX.Bar\"" - << "S: A000004 OK mailbox subscribed"; - QTest::newRow( "rename with non-standard separator" ) << collection << parts << scenario << callNames - << "Bar" << caps; - - collection = createCollectionChain( QLatin1String("/Foo") ); - collection.setName( QLatin1String("Bar") ); - collection.setRights( Akonadi::Collection::AllRights ); - - acls = new Akonadi::ImapAclAttribute; - // Old rights - rights["test@kdab.com"] = KIMAP::Acl::rightsFromString( "lrswipckxtda" ); - rights["foo@kde.org"] = KIMAP::Acl::rightsFromString( "lrswipcda" ); - acls->setRights( rights ); - - // New rights - rights["test@kdab.com"] = KIMAP::Acl::rightsFromString( "lrswipckxtda" ); - rights["foo@kde.org"] = KIMAP::Acl::rightsFromString( "lrswipcda" ); - acls->setRights( rights ); - collection.addAttribute( acls ); - - annotationsAttr = new Akonadi::CollectionAnnotationsAttribute; - annotations["/vendor/kolab/folder-test"] = "false"; - annotations["/vendor/kolab/folder-test2"] = "true"; - annotationsAttr->setAnnotations( annotations ); - collection.addAttribute( annotationsAttr ); - - parts << "NAME" << "AccessRights" << "imapacl" << "collectionannotations"; - - caps << "ACL" << "METADATA"; - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SETACL \"Foo\" \"test@kdab.com\" \"lrswipckxtda\"" - << "S: A000003 OK acl changed" - << "C: A000004 SETMETADATA \"Foo\" (\"/shared/vendor/kolab/folder-test\" {5}\r\nfalse)" - << "S: A000004 OK SETMETADATA complete" - << "C: A000005 SETMETADATA \"Foo\" (\"/shared/vendor/kolab/folder-test2\" {4}\r\ntrue)" - << "S: A000005 OK SETMETADATA complete" - << "C: A000006 SETACL \"Foo\" \"foo@kde.org\" \"lrswipcda\"" - << "S: A000006 OK acl changed" - << "C: A000007 SETACL \"Foo\" \"test@kdab.com\" \"lrswipckxtda\"" - << "S: A000007 OK acl changed" - << "C: A000008 RENAME \"Foo\" \"Bar\"" - << "S: A000008 OK rename done" - << "C: A000009 SUBSCRIBE \"Bar\"" - << "S: A000009 OK mailbox subscribed"; - QTest::newRow( "complete case METADATA" ) << collection << parts << scenario << callNames << collection.name() << caps; - } - - void shouldUpdateMetadataAclAndName() - { - QFETCH( Akonadi::Collection, collection ); - QFETCH( QSet, parts ); - QFETCH( QList, scenario ); - QFETCH( QStringList, callNames ); - QFETCH( QString, collectionName ); - QFETCH( QStringList, caps ); - - FakeServer server; - server.setScenario( scenario ); - server.startAndWait(); - - SessionPool pool( 1 ); - - pool.setPasswordRequester( createDefaultRequester() ); - QVERIFY( pool.connect( createDefaultAccount() ) ); - QVERIFY( waitForSignal( &pool, SIGNAL(connectDone(int,QString)) ) ); - - DummyResourceState::Ptr state = DummyResourceState::Ptr( new DummyResourceState ); - state->setUserName( defaultUserName() ); - state->setServerCapabilities( caps ); - state->setCollection( collection ); - state->setParts( parts ); - ChangeCollectionTask *task = new ChangeCollectionTask( state ); - task->start( &pool ); - - QTRY_COMPARE( state->calls().count(), callNames.size() ); - for ( int i = 0; i < callNames.size(); i++ ) { - QString command = QString::fromUtf8(state->calls().at( i ).first); - QVariant parameter = state->calls().at( i ).second; - - if ( command == QLatin1String("cancelTask") && callNames[i] != QLatin1String("cancelTask") ) { - kDebug() << "Got a cancel:" << parameter.toString(); - } - - QCOMPARE( command, callNames[i] ); - - if ( command == QLatin1String("cancelTask") ) { - QVERIFY( !parameter.toString().isEmpty() ); - } - if ( command == QLatin1String("collectionChangeCommitted") ) { - QCOMPARE( parameter.value().name(), collectionName ); - QCOMPARE( parameter.value().remoteId().right( collectionName.length() ), - collectionName ); - } - } - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } -}; - -QTEST_KDEMAIN_CORE( TestChangeCollectionTask ) - -#include "testchangecollectiontask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/testchangeitemtask.cpp kdepim-runtime-15.08.0/resources/imap/tests/testchangeitemtask.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/testchangeitemtask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/testchangeitemtask.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,218 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "imaptestbase.h" - -#include "changeitemtask.h" -#include "uidnextattribute.h" - -#include - -Q_DECLARE_METATYPE(QSet) - -class TestChangeItemTask : public ImapTestBase -{ - Q_OBJECT - -private slots: - void shouldAppendMessage_data() - { - QTest::addColumn( "item" ); - QTest::addColumn< QSet >( "parts" ); - QTest::addColumn< QList >( "scenario" ); - QTest::addColumn( "callNames" ); - - Akonadi::Collection collection; - Akonadi::Item item; - QSet parts; - QString messageContent; - QList scenario; - QStringList callNames; - - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection.addAttribute( new UidNextAttribute( 65 ) ); - item = Akonadi::Item( 2 ); - item.setParentCollection( collection ); - item.setRemoteId( "5" ); - - KMime::Message::Ptr message( new KMime::Message ); - - messageContent = "From: ervin\nTo: someone\nSubject: foo\n\nSpeechless..."; - - message->setContent( messageContent.toUtf8() ); - message->parse(); - item.setPayload( message ); - - parts.clear(); - parts << "PLD:RFC822"; - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 APPEND \"INBOX/Foo\" {55}\r\n"+message->encodedContent(true) - << "S: A000003 OK append done [ APPENDUID 1239890035 65 ]" - << "C: A000004 SELECT \"INBOX/Foo\"" - << "S: A000004 OK select done" - << "C: A000005 UID STORE 5 +FLAGS (\\Deleted)" - << "S: A000005 OK store done"; - - callNames.clear(); - callNames << "applyCollectionChanges" << "itemChangeCommitted"; - - QTest::newRow( "modifying mail content" ) << item << parts << scenario << callNames; - - - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection.addAttribute( new UidNextAttribute( 65 ) ); - item = Akonadi::Item( 2 ); - item.setParentCollection( collection ); - item.setRemoteId( "5" ); - - message = KMime::Message::Ptr( new KMime::Message ); - - messageContent = "From: ervin\nTo: someone\nSubject: foo\nMessage-ID: <42.4242.foo@bar.org>\n\nSpeechless..."; - - message->setContent( messageContent.toUtf8() ); - message->parse(); - item.setPayload( message ); - - parts.clear(); - parts << "PLD:RFC822"; - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 APPEND \"INBOX/Foo\" {90}\r\n"+message->encodedContent(true) - << "S: A000003 OK append done" - << "C: A000004 SELECT \"INBOX/Foo\"" - << "S: A000004 OK select done" - << "C: A000005 UID SEARCH HEADER Message-ID <42.4242.foo@bar.org>" - << "S: * SEARCH 65" - << "S: A000005 OK search done" - << "C: A000006 UID STORE 5 +FLAGS (\\Deleted)" - << "S: A000006 OK store done"; - - callNames.clear(); - callNames << "applyCollectionChanges" << "itemChangeCommitted"; - - QTest::newRow( "modifying mail content, no APPENDUID, message has Message-ID" ) << item << parts << scenario << callNames; - - - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection.addAttribute( new UidNextAttribute( 65 )); - item = Akonadi::Item( 2 ); - item.setParentCollection( collection ); - item.setRemoteId( "5" ); - - message = KMime::Message::Ptr( new KMime::Message ); - - messageContent = "From: ervin\nTo: someone\nSubject: foo\n\nSpeechless..."; - - message->setContent( messageContent.toUtf8() ); - message->parse(); - item.setPayload( message ); - - parts.clear(); - parts << "PLD:RFC822"; - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 APPEND \"INBOX/Foo\" {55}\r\n"+message->encodedContent(true) - << "S: A000003 OK append done" - << "C: A000004 SELECT \"INBOX/Foo\"" - << "S: A000004 OK select done" - << "C: A000005 UID SEARCH NEW UID 65:*" - << "S: * SEARCH 65" - << "S: A000005 OK search done" - << "C: A000006 UID STORE 5 +FLAGS (\\Deleted)" - << "S: A000006 OK store done"; - - callNames.clear(); - callNames << "applyCollectionChanges" << "itemChangeCommitted"; - - QTest::newRow( "modifying mail content, no APPENDUID, message has no Message-ID" ) << item << parts << scenario << callNames; - - - - // collection unchanged for this test - // item only gets a set of flags - item.setFlags( QSet() << "\\Foo" ); - - parts.clear(); - parts << "FLAGS"; - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 UID STORE 5 FLAGS (\\Foo)" - << "S: A000004 OK store done"; - - callNames.clear(); - callNames << "changeProcessed"; - - QTest::newRow( "modifying mail flags" ) << item << parts << scenario << callNames; - } - - void shouldAppendMessage() - { - QFETCH( Akonadi::Item, item ); - QFETCH( QSet, parts ); - QFETCH( QList, scenario ); - QFETCH( QStringList, callNames ); - - FakeServer server; - server.setScenario( scenario ); - server.startAndWait(); - - SessionPool pool( 1 ); - - pool.setPasswordRequester( createDefaultRequester() ); - QVERIFY( pool.connect( createDefaultAccount() ) ); - QVERIFY( waitForSignal( &pool, SIGNAL(connectDone(int,QString)) ) ); - - DummyResourceState::Ptr state = DummyResourceState::Ptr( new DummyResourceState ); - state->setParts( parts ); - state->setItem( item ); - ChangeItemTask *task = new ChangeItemTask( state ); - task->start( &pool ); - - QTRY_COMPARE( state->calls().count(), callNames.size() ); - for ( int i = 0; i < callNames.size(); i++ ) { - QString command = QString::fromUtf8(state->calls().at( i ).first); - QVariant parameter = state->calls().at( i ).second; - - if ( command == "cancelTask" && callNames[i] != "cancelTask" ) { - kDebug() << "Got a cancel:" << parameter.toString(); - } - - QCOMPARE( command, callNames[i] ); - - if ( command == "cancelTask" ) { - QVERIFY( !parameter.toString().isEmpty() ); - } - } - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } -}; - -QTEST_KDEMAIN_CORE( TestChangeItemTask ) - -#include "testchangeitemtask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/testexpungecollectiontask.cpp kdepim-runtime-15.08.0/resources/imap/tests/testexpungecollectiontask.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/testexpungecollectiontask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/testexpungecollectiontask.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,128 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "imaptestbase.h" - -#include "expungecollectiontask.h" - -class TestExpungeCollectionTask : public ImapTestBase -{ - Q_OBJECT - -private slots: - void shouldDeleteMailBox_data() - { - QTest::addColumn( "collection" ); - QTest::addColumn< QList >( "scenario" ); - QTest::addColumn( "callNames" ); - - Akonadi::Collection collection; - QSet parts; - QString messageContent; - QList scenario; - QStringList callNames; - - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 EXPUNGE" - << "S: A000004 OK expunge done"; - - callNames.clear(); - callNames << "taskDone"; - - QTest::newRow( "normal case" ) << collection << scenario << callNames; - - - // We keep the same collection - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 NO select failed"; - - callNames.clear(); - callNames << "cancelTask"; - - QTest::newRow( "select failed" ) << collection << scenario << callNames; - - // We keep the same collection - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 EXPUNGE" - << "S: A000004 NO expunge failed"; - - callNames.clear(); - callNames << "cancelTask"; - - QTest::newRow( "expunge failed" ) << collection << scenario << callNames; - } - - void shouldDeleteMailBox() - { - QFETCH( Akonadi::Collection, collection ); - QFETCH( QList, scenario ); - QFETCH( QStringList, callNames ); - - FakeServer server; - server.setScenario( scenario ); - server.startAndWait(); - - SessionPool pool( 1 ); - - pool.setPasswordRequester( createDefaultRequester() ); - QVERIFY( pool.connect( createDefaultAccount() ) ); - QVERIFY( waitForSignal( &pool, SIGNAL(connectDone(int,QString)) ) ); - - DummyResourceState::Ptr state = DummyResourceState::Ptr( new DummyResourceState ); - state->setCollection( collection ); - ExpungeCollectionTask *task = new ExpungeCollectionTask( state ); - task->start( &pool ); - - QTRY_COMPARE( state->calls().count(), callNames.size() ); - for ( int i = 0; i < callNames.size(); i++ ) { - QString command = QString::fromUtf8(state->calls().at( i ).first); - QVariant parameter = state->calls().at( i ).second; - - if ( command == "cancelTask" && callNames[i] != "cancelTask" ) { - kDebug() << "Got a cancel:" << parameter.toString(); - } - - QCOMPARE( command, callNames[i] ); - - if ( command == "cancelTask" ) { - QVERIFY( !parameter.toString().isEmpty() ); - } - } - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } -}; - -QTEST_KDEMAIN_CORE( TestExpungeCollectionTask ) - -#include "testexpungecollectiontask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/testmovecollectiontask.cpp kdepim-runtime-15.08.0/resources/imap/tests/testmovecollectiontask.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/testmovecollectiontask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/testmovecollectiontask.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,197 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "imaptestbase.h" - -#include "movecollectiontask.h" - -class TestMoveCollectionTask : public ImapTestBase -{ - Q_OBJECT - -private slots: - void shouldRenameMailBox_data() - { - QTest::addColumn( "collection" ); - QTest::addColumn( "source" ); - QTest::addColumn( "target" ); - QTest::addColumn< QList >( "scenario" ); - QTest::addColumn( "callNames" ); - - Akonadi::Collection root; - Akonadi::Collection inbox; - Akonadi::Collection collection; - Akonadi::Collection source; - Akonadi::Collection target; - QList scenario; - QStringList callNames; - - root = createCollectionChain( QString() ); - inbox = createCollectionChain( QLatin1String("/INBOX") ); - - source = Akonadi::Collection( 3 ); - source.setRemoteId( QLatin1String("/Foo") ); - source.setParentCollection( inbox ); - - collection = Akonadi::Collection( 10 ); - collection.setRemoteId( QLatin1String("/Baz") ); - collection.setParentCollection( source ); - - target = Akonadi::Collection( 4 ); - target.setRemoteId( QLatin1String("/Bar") ); - target.setParentCollection( inbox ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 RENAME \"INBOX/Foo/Baz\" \"INBOX/Bar/Baz\"" - << "S: A000003 OK rename done" - << "C: A000004 SUBSCRIBE \"INBOX/Bar/Baz\"" - << "S: A000004 OK subscribe done"; - - callNames.clear(); - callNames << "collectionChangeCommitted"; - - QTest::newRow( "moving mailbox" ) << collection << source << target << scenario << callNames; - - { - const Akonadi::Collection toplevel = createCollectionChain( QLatin1String("/Bar") ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 RENAME \"Bar\" \"INBOX/Bar\"" - << "S: A000003 OK rename done" - << "C: A000004 SUBSCRIBE \"INBOX/Bar\"" - << "S: A000004 OK subscribe done"; - - callNames.clear(); - callNames << "collectionChangeCommitted"; - - QTest::newRow( "move mailbox from toplevel" ) << toplevel << root << inbox << scenario << callNames; - } - - { - const Akonadi::Collection toplevel = createCollectionChain( QLatin1String("/INBOX/Bar") ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 RENAME \"INBOX/Bar\" \"Bar\"" - << "S: A000003 OK rename done" - << "C: A000004 SUBSCRIBE \"Bar\"" - << "S: A000004 OK subscribe done"; - - callNames.clear(); - callNames << "collectionChangeCommitted"; - - QTest::newRow( "move mailbox to toplevel" ) << toplevel << inbox << root << scenario << callNames; - } - - // Same collections - // The scenario changes though - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 RENAME \"INBOX/Foo/Baz\" \"INBOX/Bar/Baz\"" - << "S: A000003 OK rename done" - << "C: A000004 SUBSCRIBE \"INBOX/Bar/Baz\"" - << "S: A000004 NO subscribe failed"; - - callNames.clear(); - callNames << "emitWarning" << "collectionChangeCommitted"; - - QTest::newRow( "moving mailbox, subscribe fails" ) << collection << source << target << scenario << callNames; - - - - inbox = createCollectionChain( QLatin1String(".INBOX") ); - - source = Akonadi::Collection( 3 ); - source.setRemoteId( QLatin1String(".Foo") ); - source.setParentCollection( inbox ); - - collection = Akonadi::Collection( 10 ); - collection.setRemoteId( QLatin1String(".Baz") ); - collection.setParentCollection( source ); - - target = Akonadi::Collection( 4 ); - target.setRemoteId( QLatin1String(".Bar") ); - target.setParentCollection( inbox ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 RENAME \"INBOX.Foo.Baz\" \"INBOX.Bar.Baz\"" - << "S: A000003 OK rename done" - << "C: A000004 SUBSCRIBE \"INBOX.Bar.Baz\"" - << "S: A000004 OK subscribe done"; - - callNames.clear(); - callNames << "collectionChangeCommitted"; - - QTest::newRow( "moving mailbox with non-standard separators" ) << collection << source << target << scenario << callNames; - } - - void shouldRenameMailBox() - { - QFETCH( Akonadi::Collection, collection ); - QFETCH( Akonadi::Collection, source ); - QFETCH( Akonadi::Collection, target ); - QFETCH( QList, scenario ); - QFETCH( QStringList, callNames ); - - FakeServer server; - server.setScenario( scenario ); - server.startAndWait(); - - SessionPool pool( 1 ); - - pool.setPasswordRequester( createDefaultRequester() ); - QVERIFY( pool.connect( createDefaultAccount() ) ); - QVERIFY( waitForSignal( &pool, SIGNAL(connectDone(int,QString)) ) ); - - DummyResourceState::Ptr state = DummyResourceState::Ptr( new DummyResourceState ); - state->setCollection( collection ); - state->setSourceCollection( source ); - state->setTargetCollection( target ); - MoveCollectionTask *task = new MoveCollectionTask( state ); - task->start( &pool ); - - QTRY_COMPARE( state->calls().count(), callNames.size() ); - for ( int i = 0; i < callNames.size(); i++ ) { - QString command = QString::fromUtf8(state->calls().at( i ).first); - QVariant parameter = state->calls().at( i ).second; - - if ( command == "cancelTask" && callNames[i] != "cancelTask" ) { - kDebug() << "Got a cancel:" << parameter.toString(); - } - - QCOMPARE( command, callNames[i] ); - - if ( command == "cancelTask" ) { - QVERIFY( !parameter.toString().isEmpty() ); - } - } - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } -}; - -QTEST_KDEMAIN_CORE( TestMoveCollectionTask ) - -#include "testmovecollectiontask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/testmoveitemstask.cpp kdepim-runtime-15.08.0/resources/imap/tests/testmoveitemstask.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/testmoveitemstask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/testmoveitemstask.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,263 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "imaptestbase.h" - -#include "moveitemstask.h" -#include "uidnextattribute.h" - -#include - -Q_DECLARE_METATYPE(QSet) - -class TestMoveItemsTask : public ImapTestBase -{ - Q_OBJECT - -private slots: - void shouldCopyAndDeleteMessage_data() - { - QTest::addColumn( "item" ); - QTest::addColumn( "source" ); - QTest::addColumn( "target" ); - QTest::addColumn< QList >( "scenario" ); - QTest::addColumn( "callNames" ); - - Akonadi::Item item; - Akonadi::Collection inbox; - Akonadi::Collection source; - Akonadi::Collection target; - QList scenario; - QStringList callNames; - - item = Akonadi::Item( 1 ); - item.setRemoteId( "5" ); - - KMime::Message::Ptr message(new KMime::Message); - - QString messageContent = "From: ervin\nTo: someone\nSubject: foo\n\nSpeechless..."; - - message->setContent( messageContent.toUtf8() ); - message->parse(); - item.setPayload(message); - - inbox = createCollectionChain( QLatin1String("/INBOX") ); - source = Akonadi::Collection( 3 ); - source.setRemoteId( "/Foo" ); - source.setParentCollection( inbox ); - target = Akonadi::Collection( 4 ); - target.setRemoteId( "/Bar" ); - target.setParentCollection( inbox ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 UID COPY 5 \"INBOX/Bar\"" - << "S: A000004 OK copy [ COPYUID 1239890035 5 65 ]" - << "C: A000005 UID STORE 5 +FLAGS (\\Deleted)" - << "S: A000005 OK store done"; - - callNames.clear(); - callNames << "itemsChangesCommitted"; - - QTest::newRow( "moving mail" ) << item << source << target << scenario << callNames; - - - - - // Same item and collections - // The scenario changes though - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 UID COPY 5 \"INBOX/Bar\"" - << "S: A000004 OK copy [ COPYUID 1239890035 5 65 ]" - << "C: A000005 UID STORE 5 +FLAGS (\\Deleted)" - << "S: A000005 NO store failed"; - - callNames.clear(); - callNames << "emitWarning" << "itemsChangesCommitted"; - - QTest::newRow( "moving mail, store fails" ) << item << source << target << scenario << callNames; - - - - item = Akonadi::Item( 1 ); - item.setRemoteId( "5" ); - - message = KMime::Message::Ptr( new KMime::Message ); - - messageContent = "From: ervin\nTo: someone\nSubject: foo\nMessage-ID: <42.4242.foo@bar.org>\n\nSpeechless..."; - - message->setContent( messageContent.toUtf8() ); - message->parse(); - item.setPayload( message ); - - source = Akonadi::Collection( 3 ); - source.setRemoteId( "/Foo" ); - source.setParentCollection( inbox ); - source.addAttribute( new UidNextAttribute( 42 ) ); - target = Akonadi::Collection( 3 ); - target.setRemoteId( "/Bar" ); - target.setParentCollection( inbox ); - target.addAttribute( new UidNextAttribute( 65 ) ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 UID COPY 5 \"INBOX/Bar\"" - << "S: A000004 OK copy done" - << "C: A000005 UID STORE 5 +FLAGS (\\Deleted)" - << "S: A000005 OK store done" - << "C: A000006 SELECT \"INBOX/Bar\"" - << "S: A000006 OK select done" - << "C: A000007 UID SEARCH (HEADER Message-ID <42.4242.foo@bar.org>)" - << "S: * SEARCH 65" - << "S: A000007 OK search done"; - - callNames.clear(); - callNames << "itemsChangesCommitted" << "applyCollectionChanges"; - - QTest::newRow( "moving mail, no COPYUID, message had Message-ID" ) << item << source << target << scenario << callNames; - - - - - item = Akonadi::Item( 1 ); - item.setRemoteId( "5" ); - - message = KMime::Message::Ptr( new KMime::Message ); - - messageContent = "From: ervin\nTo: someone\nSubject: foo\n\nSpeechless..."; - - message->setContent( messageContent.toUtf8() ); - message->parse(); - item.setPayload( message ); - - source = Akonadi::Collection( 3 ); - source.setRemoteId( "/Foo" ); - source.setParentCollection( inbox ); - source.addAttribute( new UidNextAttribute( 42 ) ); - target = Akonadi::Collection( 4 ); - target.setRemoteId( "/Bar" ); - target.setParentCollection( inbox ); - target.addAttribute( new UidNextAttribute( 65 ) ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 UID COPY 5 \"INBOX/Bar\"" - << "S: A000004 OK copy done" - << "C: A000005 UID STORE 5 +FLAGS (\\Deleted)" - << "S: A000005 OK store done" - << "C: A000006 SELECT \"INBOX/Bar\"" - << "S: A000006 OK select done" - << "C: A000007 UID SEARCH NEW UID 65:*" - << "S: * SEARCH 65" - << "S: A000007 OK search done"; - - callNames.clear(); - callNames << "itemsChangesCommitted" << "applyCollectionChanges"; - - QTest::newRow( "moving mail, no COPYUID, message didn't have Message-ID" ) << item << source << target << scenario << callNames; - - - item = Akonadi::Item( 1 ); - item.setRemoteId( "5" ); - message = KMime::Message::Ptr(new KMime::Message); - messageContent = "From: ervin\nTo: someone\nSubject: foo\nMessage-ID: <42.4242.foo@bar.org>\n\nSpeechless..."; - message->setContent( messageContent.toUtf8() ); - message->parse(); - item.setPayload( message ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 UID COPY 5 \"INBOX/Bar\"" - << "S: A000004 OK copy done" - << "C: A000005 UID STORE 5 +FLAGS (\\Deleted)" - << "S: A000005 OK store done" - << "C: A000006 SELECT \"INBOX/Bar\"" - << "S: A000006 OK select done" - << "C: A000007 UID SEARCH (HEADER Message-ID <42.4242.foo@bar.org>)" - << "S: * SEARCH 61 65" - << "S: A000007 OK search done"; - - callNames.clear(); - callNames << "itemsChangesCommitted" << "applyCollectionChanges"; - - QTest::newRow( "moving mail, no COPYUID, message didn't have unique Message-ID, but last one matches old uidnext" ) << item << source << target << scenario << callNames; - } - - void shouldCopyAndDeleteMessage() - { - QFETCH( Akonadi::Item, item ); - QFETCH( Akonadi::Collection, source ); - QFETCH( Akonadi::Collection, target ); - QFETCH( QList, scenario ); - QFETCH( QStringList, callNames ); - - FakeServer server; - server.setScenario( scenario ); - server.startAndWait(); - - SessionPool pool( 1 ); - - pool.setPasswordRequester( createDefaultRequester() ); - QVERIFY( pool.connect( createDefaultAccount() ) ); - QVERIFY( waitForSignal( &pool, SIGNAL(connectDone(int,QString)) ) ); - - DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); - state->setItem( item ); - state->setSourceCollection( source ); - state->setTargetCollection( target ); - MoveItemsTask *task = new MoveItemsTask( state ); - task->start( &pool ); - - QTRY_COMPARE( state->calls().count(), callNames.size() ); - for ( int i = 0; i < callNames.size(); i++ ) { - QString command = QString::fromUtf8(state->calls().at( i ).first); - QVariant parameter = state->calls().at( i ).second; - - if ( command == "cancelTask" && callNames[i] != "cancelTask" ) { - kDebug() << "Got a cancel:" << parameter.toString(); - } - - QCOMPARE( command, callNames[i] ); - - if ( command == "cancelTask" ) { - QVERIFY( !parameter.toString().isEmpty() ); - } - } - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } -}; - -QTEST_KDEMAIN_CORE( TestMoveItemsTask ) - -#include "testmoveitemstask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/testremovecollectionrecursivetask.cpp kdepim-runtime-15.08.0/resources/imap/tests/testremovecollectionrecursivetask.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/testremovecollectionrecursivetask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/testremovecollectionrecursivetask.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,247 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "imaptestbase.h" - -#include "removecollectionrecursivetask.h" - -class TestRemoveCollectionRecursiveTask : public ImapTestBase -{ - Q_OBJECT - - void shouldDeleteMailBoxRecursive_data() - { - QTest::addColumn( "collection" ); - QTest::addColumn< QList >( "scenario" ); - QTest::addColumn( "callNames" ); - - Akonadi::Collection collection; - QList scenario; - QStringList callNames; - - collection = createCollectionChain( QLatin1String("/INBOX/test1") ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 LSUB \"\" *" - << "S: * LSUB ( \\HasChildren ) / INBOX" - << "S: * LSUB ( \\HasChildren ) / INBOX/test1" - << "S: * LSUB ( ) / INBOX/test1/test2" - << "S: A000003 OK Completed ( 0.000 secs 26 calls )" - << "C: A000004 SELECT \"INBOX/test1/test2\"" - << "S: * FLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen )" - << "S: * OK [ PERMANENTFLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen \\* ) ]" - << "S: * 1 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UNSEEN 1 ]" - << "S: * OK [ UIDVALIDITY 1292857898 ]" - << "S: * OK [ UIDNEXT 2 ]" - << "S: A000004 OK Completed [ READ-WRITE ]" - << "C: A000005 STORE 1:* +FLAGS (\\DELETED)" - << "S: * 1 FETCH ( FLAGS (\\Deleted) ) " - << "S: A000005 OK Completed" - << "C: A000006 EXPUNGE" - << "S: * 1 EXPUNGE" - << "S: * 0 EXISTS" - << "S: * 0 RECENT" - << "S: A000006 OK Completed" - << "C: A000007 CLOSE" - << "S: A000007 OK Completed" - << "C: A000008 DELETE \"INBOX/test1/test2\"" - << "S: * 0 EXISTS" - << "S: * 0 RECENT" - << "S: A000008 OK Completed" - << "C: A000009 SELECT \"INBOX/test1\"" - << "S: * FLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen )" - << "S: * OK [ PERMANENTFLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen \\* ) ]" - << "S: * 1 EXISTS" - << "S: * 1 RECENT" - << "S: * OK [ UIDVALIDITY 1292857888 ]" - << "S: * OK [ UIDNEXT 2 ]" - << "S: A000009 OK Completed [ READ-WRITE ]" - << "C: A000010 STORE 1:* +FLAGS (\\DELETED)" - << "S: * 1 FETCH ( FLAGS (\\Recent \\Deleted \\Seen) )" - << "S: A000010 OK Completed" - << "C: A000011 EXPUNGE" - << "S: * 1 EXPUNGE" - << "S: * 0 EXISTS" - << "S: * 0 RECENT" - << "S: A000011 OK Completed" - << "C: A000012 CLOSE" - << "S: A000012 OK Completed" - << "C: A000013 DELETE \"INBOX/test1\"" - << "S: * 0 EXISTS" - << "S: * 0 RECENT" - << "S: A000013 OK Completed"; - callNames.clear(); - callNames << "changeProcessed"; - - QTest::newRow( "normal case" ) << collection << scenario << callNames; - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 LSUB \"\" *" - << "S: * LSUB ( \\HasChildren ) / INBOX" - << "S: * LSUB ( \\HasChildren ) / INBOX/test1" - << "S: * LSUB ( ) / INBOX/test1/test2" - << "S: A000003 OK Completed ( 0.000 secs 26 calls )"; - collection.setRemoteId( "/test1" ); - collection.setParentCollection( Akonadi::Collection::root() ); - callNames.clear(); - callNames << "changeProcessed" << "emitWarning" << "synchronizeCollectionTree"; - QTest::newRow( "invalid collection" ) << collection << scenario << callNames; - - collection = createCollectionChain( QLatin1String(".INBOX.test1") ); - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 LSUB \"\" *" - << "S: * LSUB ( \\HasChildren ) . INBOX" - << "S: * LSUB ( \\HasChildren ) . INBOX.test1" - << "S: * LSUB ( ) . INBOX.test1.test2" - << "S: A000003 OK Completed ( 0.000 secs 26 calls )" - << "C: A000004 SELECT \"INBOX.test1.test2\"" - << "S: * FLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen )" - << "S: * OK [ PERMANENTFLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen \\* ) ]" - << "S: * 1 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UNSEEN 1 ]" - << "S: * OK [ UIDVALIDITY 1292857898 ]" - << "S: * OK [ UIDNEXT 2 ]" - << "S: A000004 OK Completed [ READ-WRITE ]" - << "C: A000005 STORE 1:* +FLAGS (\\DELETED)" - << "S: * 1 FETCH ( FLAGS (\\Deleted) ) " - << "S: A000005 OK Completed" - << "C: A000006 EXPUNGE" - << "S: * 1 EXPUNGE" - << "S: * 0 EXISTS" - << "S: * 0 RECENT" - << "S: A000006 OK Completed" - << "C: A000007 CLOSE" - << "S: A000007 OK Completed" - << "C: A000008 DELETE \"INBOX.test1.test2\"" - << "S: * 0 EXISTS" - << "S: * 0 RECENT" - << "S: A000008 OK Completed" - << "C: A000009 SELECT \"INBOX.test1\"" - << "S: * FLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen )" - << "S: * OK [ PERMANENTFLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen \\* ) ]" - << "S: * 1 EXISTS" - << "S: * 1 RECENT" - << "S: * OK [ UIDVALIDITY 1292857888 ]" - << "S: * OK [ UIDNEXT 2 ]" - << "S: A000009 OK Completed [ READ-WRITE ]" - << "C: A000010 STORE 1:* +FLAGS (\\DELETED)" - << "S: * 1 FETCH ( FLAGS (\\Recent \\Deleted \\Seen) )" - << "S: A000010 OK Completed" - << "C: A000011 EXPUNGE" - << "S: * 1 EXPUNGE" - << "S: * 0 EXISTS" - << "S: * 0 RECENT" - << "S: A000011 OK Completed" - << "C: A000012 CLOSE" - << "S: A000012 OK Completed" - << "C: A000013 DELETE \"INBOX.test1\"" - << "S: * 0 EXISTS" - << "S: * 0 RECENT" - << "S: A000013 OK Completed"; - callNames.clear(); - callNames << "changeProcessed"; - QTest::newRow( "non-standard separator" ) << collection << scenario << callNames; - - collection = createCollectionChain( QLatin1String(".INBOX.test1") ); - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 LSUB \"\" *" - << "S: * LSUB ( \\HasChildren ) . INBOX" - << "S: * LSUB ( \\HasChildren ) . INBOX.test1" - << "S: * LSUB ( ) . INBOX.test1.test2" - << "S: A000003 OK Completed ( 0.000 secs 26 calls )" - << "C: A000004 SELECT \"INBOX.test1.test2\"" - << "S: * FLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen )" - << "S: * OK [ PERMANENTFLAGS ( \\Answered \\Flagged \\Draft \\Deleted \\Seen \\* ) ]" - << "S: * 1 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UNSEEN 1 ]" - << "S: * OK [ UIDVALIDITY 1292857898 ]" - << "S: * OK [ UIDNEXT 2 ]" - << "S: A000004 OK Completed [ READ-WRITE ]" - << "C: A000005 STORE 1:* +FLAGS (\\DELETED)" - << "S: * 1 FETCH ( FLAGS (\\Deleted) ) " - << "S: A000005 OK Completed" - << "C: A000006 EXPUNGE" - << "S: * 1 EXPUNGE" - << "S: * 0 EXISTS" - << "S: * 0 RECENT" - << "S: A000006 OK Completed" - << "C: A000007 CLOSE" - << "S: A000007 NO Close failed"; - callNames.clear(); - callNames << "changeProcessed" << "emitWarning" << "synchronizeCollectionTree"; - QTest::newRow( "close failed" ) << collection << scenario << callNames; - } - - void shouldDeleteMailBoxRecursive() - { - QFETCH( Akonadi::Collection, collection ); - QFETCH( QList, scenario ); - QFETCH( QStringList, callNames ); - - FakeServer server; - server.setScenario( scenario ); - server.startAndWait(); - - SessionPool pool( 1 ); - - pool.setPasswordRequester( createDefaultRequester() ); - QVERIFY( pool.connect( createDefaultAccount() ) ); - QVERIFY( waitForSignal( &pool, SIGNAL(connectDone(int,QString)) ) ); - - DummyResourceState::Ptr state = DummyResourceState::Ptr( new DummyResourceState ); - state->setCollection( collection ); - RemoveCollectionRecursiveTask *task = new RemoveCollectionRecursiveTask( state ); - task->start( &pool ); - QEventLoop loop; - connect( task, SIGNAL(destroyed(QObject*)), &loop, SLOT(quit()) ); - loop.exec(); - - QCOMPARE( state->calls().count(), callNames.size() ); - for ( int i = 0; i < callNames.size(); i++ ) { - QString command = QString::fromUtf8(state->calls().at( i ).first); - QVariant parameter = state->calls().at( i ).second; - - if ( command == "cancelTask" && callNames[i] != "cancelTask" ) { - kDebug() << "Got a cancel:" << parameter.toString(); - } - - QCOMPARE( command, callNames[i] ); - - if ( command == "cancelTask" ) { - QVERIFY( !parameter.toString().isEmpty() ); - } - } - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } -}; - -QTEST_KDEMAIN_CORE( TestRemoveCollectionRecursiveTask ) - -#include "testremovecollectionrecursivetask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/testresourcetask.cpp kdepim-runtime-15.08.0/resources/imap/tests/testresourcetask.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/testresourcetask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/testresourcetask.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,178 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "imaptestbase.h" - -#include "resourcetask.h" - -Q_DECLARE_METATYPE( ResourceTask::ActionIfNoSession ) - -class DummyResourceTask : public ResourceTask -{ -public: - explicit DummyResourceTask( ActionIfNoSession action, ResourceStateInterface::Ptr resource, QObject *parent = 0 ) - : ResourceTask( action, resource, parent ) - { - - } - - void doStart( KIMAP::Session */*session*/ ) - { - cancelTask( "Dummy task" ); - } -}; - - -class TestResourceTask : public ImapTestBase -{ - Q_OBJECT - -private slots: - void shouldRequestSession_data() - { - QTest::addColumn( "state" ); - QTest::addColumn< QList >( "scenario" ); - QTest::addColumn( "shouldConnect" ); - QTest::addColumn( "shouldRequestSession" ); - QTest::addColumn( "actionIfNoSession" ); - QTest::addColumn( "callNames" ); - QTest::addColumn( "firstCallParameter" ); - - DummyResourceState::Ptr state; - QList scenario; - QStringList callNames; - - state = DummyResourceState::Ptr( new DummyResourceState ); - scenario.clear(); - scenario << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in" - << "C: A000002 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" - << "S: A000002 OK Completed"; - callNames.clear(); - callNames << "cancelTask"; - QTest::newRow( "normal case" ) << state << scenario - << true << false - << ResourceTask::DeferIfNoSession - << callNames << QVariant( "Dummy task" ); - - - state = DummyResourceState::Ptr( new DummyResourceState ); - callNames.clear(); - callNames << "deferTask"; - QTest::newRow( "all sessions allocated (defer)" ) << state << scenario - << true << true - << ResourceTask::DeferIfNoSession - << callNames << QVariant(); - - - state = DummyResourceState::Ptr( new DummyResourceState ); - callNames.clear(); - callNames << "cancelTask"; - QTest::newRow( "all sessions allocated (cancel)" ) << state << scenario - << true << true - << ResourceTask::CancelIfNoSession - << callNames << QVariant(); - - - state = DummyResourceState::Ptr( new DummyResourceState ); - scenario.clear(); - callNames.clear(); - callNames << "deferTask" << "scheduleConnectionAttempt"; - QTest::newRow( "disconnected pool (defer)" ) << state << scenario - << false << false - << ResourceTask::DeferIfNoSession - << callNames << QVariant(); - - - state = DummyResourceState::Ptr( new DummyResourceState ); - scenario.clear(); - callNames.clear(); - callNames << "cancelTask" << "scheduleConnectionAttempt"; - QTest::newRow( "disconnected pool (cancel)" ) << state << scenario - << false << false - << ResourceTask::CancelIfNoSession - << callNames << QVariant(); - } - - void shouldRequestSession() - { - QFETCH( DummyResourceState::Ptr, state ); - QFETCH( QList, scenario ); - QFETCH( bool, shouldConnect ); - QFETCH( bool, shouldRequestSession ); - QFETCH( ResourceTask::ActionIfNoSession, actionIfNoSession ); - QFETCH( QStringList, callNames ); - QFETCH( QVariant, firstCallParameter ); - - FakeServer server; - server.setScenario( scenario ); - server.startAndWait(); - - SessionPool pool( 1 ); - - if ( shouldConnect ) { - QSignalSpy poolSpy( &pool, SIGNAL(connectDone(int,QString)) ); - - pool.setPasswordRequester( createDefaultRequester() ); - QVERIFY( pool.connect( createDefaultAccount() ) ); - - QTRY_COMPARE( poolSpy.count(), 1 ); - QCOMPARE( poolSpy.at( 0 ).at( 0 ).toInt(), (int)SessionPool::NoError ); - } - - - if ( shouldRequestSession ) { - QSignalSpy requestSpy( &pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString)) ); - pool.requestSession(); - QTRY_COMPARE( requestSpy.count(), 1 ); - } - - QSignalSpy sessionSpy( &pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString)) ); - DummyResourceTask *task = new DummyResourceTask( actionIfNoSession, state ); - task->start( &pool ); - - if ( shouldConnect ) { - QTRY_COMPARE( sessionSpy.count(), 1 ); - } else { - //We want to ensure the signal isn't emitted, so we have to wait - QTest::qWait( 500 ); - QCOMPARE( sessionSpy.count(), 0 ); - } - - QCOMPARE( state->calls().count(), callNames.size() ); - for ( int i = 0; i < callNames.size(); i++ ) { - QString command = QString::fromUtf8(state->calls().at( i ).first); - QCOMPARE( command, callNames[i] ); - } - - if ( firstCallParameter.toString() == "Dummy task" ) { - QCOMPARE( state->calls().first().second, firstCallParameter ); - } - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } -}; - -QTEST_KDEMAIN_CORE( TestResourceTask ) - -#include "testresourcetask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/testretrievecollectionmetadatatask.cpp kdepim-runtime-15.08.0/resources/imap/tests/testretrievecollectionmetadatatask.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/testretrievecollectionmetadatatask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/testretrievecollectionmetadatatask.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,342 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "imaptestbase.h" - -#include "retrievecollectionmetadatatask.h" - -#include -#include -#include "collectionannotationsattribute.h" -#include "imapaclattribute.h" -#include "imapquotaattribute.h" -#include "noselectattribute.h" -#include "timestampattribute.h" -#include - -typedef QMap QBYTEARRAYMAP; - -Q_DECLARE_METATYPE( Akonadi::Collection::Rights ) -Q_DECLARE_METATYPE( QBYTEARRAYMAP ) - -class TestRetrieveCollectionMetadataTask : public ImapTestBase -{ - Q_OBJECT - -private slots: - - void initTestCase() - { - Akonadi::AttributeFactory::registerAttribute(); - Akonadi::AttributeFactory::registerAttribute(); - } - - void shouldCollectionRetrieveMetadata_data() - { - QTest::addColumn( "collection" ); - QTest::addColumn( "capabilities" ); - QTest::addColumn< QList >( "scenario" ); - QTest::addColumn( "callNames" ); - QTest::addColumn( "expectedRights" ); - QTest::addColumn( "expectedAnnotations" ); - - Akonadi::Collection collection; - QStringList capabilities; - QList scenario; - QStringList callNames; - QMap expectedAnnotations; - - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection.setRights( 0 ); - collection.addAttribute( new TimestampAttribute( QDateTime::currentDateTime().toTime_t() ) ); - - capabilities.clear(); - capabilities << "ANNOTATEMORE" << "ACL" << "QUOTA"; - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 GETANNOTATION \"INBOX/Foo\" \"*\" \"value.shared\"" - << "S: * ANNOTATION INBOX/Foo /vendor/kolab/folder-test ( value.shared true )" - << "S: A000003 OK annotations retrieved" - << "C: A000004 GETACL \"INBOX/Foo\"" - << "S: * ACL INBOX/Foo foo@kde.org lrswipcda" - << "S: A000004 OK acl retrieved" - << "C: A000005 MYRIGHTS \"INBOX/Foo\"" - << "S: * MYRIGHTS \"INBOX/Foo\" lrswipkxtecda" - << "S: A000005 OK rights retrieved" - << "C: A000006 GETQUOTAROOT \"INBOX/Foo\"" - << "S: * QUOTAROOT INBOX/Foo user/foo" - << "S: * QUOTA user/foo ( )" - << "S: A000006 OK quota retrieved"; - - callNames.clear(); - callNames << "collectionAttributesRetrieved"; - - expectedAnnotations.clear(); - expectedAnnotations.insert( "/shared/vendor/kolab/folder-test", "true" ); - - Akonadi::Collection::Rights rights = Akonadi::Collection::AllRights; - QTest::newRow( "first listing, connected IMAP" ) << collection << capabilities << scenario - << callNames << rights << expectedAnnotations; - - // - // Test that if the parent collection doesn't allow renaming in its ACL, the child mailbox - // can't be renamed, i.e. doesn't have the CanChangeCollection flag. - // - Akonadi::Collection parentCollection = createCollectionChain( QLatin1String("/INBOX") ); - QMap rightsMap; - rightsMap.insert( "Hans", KIMAP::Acl::Lookup | KIMAP::Acl::Read | KIMAP::Acl::KeepSeen | - KIMAP::Acl::Write | KIMAP::Acl::Insert | KIMAP::Acl::Post | - KIMAP::Acl::Delete ); - Akonadi::ImapAclAttribute *aclAttribute = new Akonadi::ImapAclAttribute(); - aclAttribute->setRights( rightsMap ); - parentCollection.addAttribute( aclAttribute ); - collection.setParentCollection( parentCollection ); - collection.removeAttribute(); - rights = Akonadi::Collection::AllRights; - rights &= ~Akonadi::Collection::CanChangeCollection; - QTest::newRow( "parent without create rights" ) << collection << capabilities << scenario - << callNames << rights << expectedAnnotations; - - // - // Test that if the parent collection is a noselect folder, the child mailbox will not have - // rename (CanChangeCollection) permission. - // - parentCollection = createCollectionChain( QLatin1String("/INBOX") ); - NoSelectAttribute *noSelectAttribute = new NoSelectAttribute(); - parentCollection.addAttribute( noSelectAttribute ); - collection.setParentCollection( parentCollection ); - QTest::newRow( "parent wit noselect" ) << collection << capabilities << scenario - << callNames << rights << expectedAnnotations; - parentCollection.removeAttribute(); - - // - // Test that the rights are properly set on the resulting collection if the mailbox doesn't - // have full rights. - // - collection.setParentCollection( createCollectionChain( QLatin1String("/INBOX") ) ); - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 GETANNOTATION \"INBOX/Foo\" \"*\" \"value.shared\"" - << "S: * ANNOTATION INBOX/Foo /vendor/kolab/folder-test ( value.shared true )" - << "S: A000003 OK annotations retrieved" - << "C: A000004 GETACL \"INBOX/Foo\"" - << "S: * ACL INBOX/Foo foo@kde.org wi" - << "S: A000004 OK acl retrieved" - << "C: A000005 MYRIGHTS \"INBOX/Foo\"" - << "S: * MYRIGHTS \"INBOX/Foo\" wi" - << "S: A000005 OK rights retrieved" - << "C: A000006 GETQUOTAROOT \"INBOX/Foo\"" - << "S: * QUOTAROOT INBOX/Foo user/foo" - << "S: * QUOTA user/foo ( )" - << "S: A000006 OK quota retrieved"; - rights = Akonadi::Collection::CanCreateItem | Akonadi::Collection::CanChangeItem | - Akonadi::Collection::CanChangeCollection; - QTest::newRow( "only some rights" ) << collection << capabilities << scenario - << callNames << rights << expectedAnnotations; - - // - // Test that a warning is issued if the insert rights of a folder have been revoked on the server. - // - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection.addAttribute( new TimestampAttribute( QDateTime::currentDateTime().toTime_t() ) ); - collection.setParentCollection( parentCollection ); - collection.setRights( Akonadi::Collection::CanCreateItem ); - - capabilities.clear(); - capabilities << "ANNOTATEMORE" << "ACL" << "QUOTA"; - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 GETANNOTATION \"INBOX/Foo\" \"*\" \"value.shared\"" - << "S: * ANNOTATION INBOX/Foo /vendor/kolab/folder-test ( value.shared true )" - << "S: A000003 OK annotations retrieved" - << "C: A000004 GETACL \"INBOX/Foo\"" - << "S: * ACL INBOX/Foo foo@kde.org wi" - << "S: A000004 OK acl retrieved" - << "C: A000005 MYRIGHTS \"INBOX/Foo\"" - << "S: * MYRIGHTS \"INBOX/Foo\" w" - << "S: A000005 OK rights retrieved" - << "C: A000006 GETQUOTAROOT \"INBOX/Foo\"" - << "S: * QUOTAROOT INBOX/Foo user/foo" - << "S: * QUOTA user/foo ( )" - << "S: A000006 OK quota retrieved"; - - callNames.clear(); - callNames << "showInformationDialog"; - callNames << "collectionAttributesRetrieved"; - - rights = Akonadi::Collection::CanChangeItem | Akonadi::Collection::CanChangeCollection; - QTest::newRow( "revoked rights" ) << collection << capabilities << scenario - << callNames << rights << expectedAnnotations; - - // - // Test that NoInferiors overrides acl rights and disallows creating new mailboxes - // - collection.setParentCollection( createCollectionChain( QString() ) ); - collection.setRemoteId( "/INBOX" ); - collection.setRights( Akonadi::Collection::AllRights ); - collection.addAttribute( new NoInferiorsAttribute( true ) ); - collection.removeAttribute(); - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 GETANNOTATION \"INBOX\" \"*\" \"value.shared\"" - << "S: * ANNOTATION INBOX /vendor/kolab/folder-test ( value.shared true )" - << "S: A000003 OK annotations retrieved" - << "C: A000004 GETACL \"INBOX\"" - << "S: * ACL INBOX foo@kde.org wik" - << "S: A000004 OK acl retrieved" - << "C: A000005 MYRIGHTS \"INBOX\"" - << "S: * MYRIGHTS \"INBOX\" wk" - << "S: A000005 OK rights retrieved" - << "C: A000006 GETQUOTAROOT \"INBOX\"" - << "S: * QUOTAROOT INBOX user" - << "S: * QUOTA user ( )" - << "S: A000006 OK quota retrieved"; - - callNames.clear(); - callNames << "collectionAttributesRetrieved"; - - rights = Akonadi::Collection::CanChangeItem | Akonadi::Collection::CanChangeCollection; - - QTest::newRow( "noinferiors" ) << collection << capabilities << scenario - << callNames << rights << expectedAnnotations; - - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection.setRights( 0 ); - collection.removeAttribute(); - - capabilities.clear(); - capabilities << "METADATA" << "ACL" << "QUOTA"; - - expectedAnnotations.clear(); - expectedAnnotations.insert( "/shared/vendor/kolab/folder-test", "true" ); - expectedAnnotations.insert( "/shared/vendor/kolab/folder-test2", "" ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 GETMETADATA (DEPTH infinity) \"INBOX/Foo\" (/shared)" - << "S: * METADATA \"INBOX/Foo\" (/shared/vendor/kolab/folder-test \"true\")" - << "S: * METADATA \"INBOX/Foo\" (/shared/vendor/kolab/folder-test2 \"NIL\")" - << "S: * METADATA \"INBOX/Foo\" (/shared/vendor/cmu/cyrus-imapd/lastupdate \"true\")" - << "S: A000003 OK GETMETADATA complete" - << "C: A000004 GETACL \"INBOX/Foo\"" - << "S: * ACL INBOX/Foo foo@kde.org lrswipcda" - << "S: A000004 OK acl retrieved" - << "C: A000005 MYRIGHTS \"INBOX/Foo\"" - << "S: * MYRIGHTS \"INBOX/Foo\" lrswipkxtecda" - << "S: A000005 OK rights retrieved" - << "C: A000006 GETQUOTAROOT \"INBOX/Foo\"" - << "S: * QUOTAROOT INBOX/Foo user/Foo" - << "S: * QUOTA user/Foo ( )" - << "S: A000006 OK quota retrieved"; - - callNames.clear(); - callNames << "collectionAttributesRetrieved"; - - rights = Akonadi::Collection::AllRights; - QTest::newRow( "METADATA" ) << collection << capabilities << scenario - << callNames << rights << expectedAnnotations; - - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection.setRights( 0 ); - collection.addAttribute( new TimestampAttribute( QDateTime::currentDateTime().toTime_t() ) ); - - capabilities.clear(); - expectedAnnotations.clear(); - - callNames.clear(); - callNames << "collectionAttributesRetrieved"; - - rights = 0; - - scenario.clear(); - scenario << defaultPoolConnectionScenario(); - - QTest::newRow( "no capabilities" ) << collection << capabilities << scenario - << callNames << rights << expectedAnnotations; - } - - void shouldCollectionRetrieveMetadata() - { - QFETCH( Akonadi::Collection, collection ); - QFETCH( QStringList, capabilities ); - QFETCH( QList, scenario ); - QFETCH( QStringList, callNames ); - QFETCH( Akonadi::Collection::Rights, expectedRights ); - QFETCH( QBYTEARRAYMAP, expectedAnnotations ); - - FakeServer server; - server.setScenario( scenario ); - server.startAndWait(); - - SessionPool pool( 1 ); - - pool.setPasswordRequester( createDefaultRequester() ); - QVERIFY( pool.connect( createDefaultAccount() ) ); - QVERIFY( waitForSignal( &pool, SIGNAL(connectDone(int,QString)) ) ); - - DummyResourceState::Ptr state = DummyResourceState::Ptr( new DummyResourceState ); - state->setCollection( collection ); - state->setServerCapabilities( capabilities ); - state->setUserName( "Hans" ); - RetrieveCollectionMetadataTask *task = new RetrieveCollectionMetadataTask( state ); - - task->start( &pool ); - - QTRY_COMPARE( state->calls().count(), callNames.size() ); - for ( int i = 0; i < callNames.size(); i++ ) { - QString command = QString::fromUtf8(state->calls().at( i ).first); - QVariant parameter = state->calls().at( i ).second; - - if ( command == "cancelTask" && callNames[i] != "cancelTask" ) { - kDebug() << "Got a cancel:" << parameter.toString(); - } - - QCOMPARE( command, callNames[i] ); - - if ( command == "cancelTask" ) { - QVERIFY( !parameter.toString().isEmpty() ); - } - - if ( command == "collectionAttributesRetrieved" ) { - Akonadi::Collection collection = parameter.value(); - QCOMPARE( collection.rights(), expectedRights ); - QVERIFY( collection.hasAttribute() ); - - const qint64 timestamp = collection.attribute()->timestamp(); - const qint64 currentTimestamp = QDateTime::currentDateTime().toTime_t(); - QVERIFY( qAbs( currentTimestamp - timestamp ) < 5 ); - - if ( !expectedAnnotations.isEmpty() ) { - QVERIFY( collection.hasAttribute() ); - QCOMPARE( collection.attribute()->annotations(), expectedAnnotations ); - } - } - } - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } -}; - -QTEST_KDEMAIN_CORE( TestRetrieveCollectionMetadataTask ) - -#include "testretrievecollectionmetadatatask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/testretrievecollectionstask.cpp kdepim-runtime-15.08.0/resources/imap/tests/testretrievecollectionstask.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/testretrievecollectionstask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/testretrievecollectionstask.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,491 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "imaptestbase.h" - -#include "retrievecollectionstask.h" -#include "noselectattribute.h" -#include - -#include -#include -#include - -class TestRetrieveCollectionsTask : public ImapTestBase -{ - Q_OBJECT -public: - TestRetrieveCollectionsTask( QObject *parent = 0 ) - : ImapTestBase( parent ), m_nextCollectionId( 1 ) - { - } - -private slots: - void shouldListCollections_data() - { - QTest::addColumn( "expectedCollections" ); - QTest::addColumn< QList >( "scenario" ); - QTest::addColumn( "callNames" ); - QTest::addColumn( "isSubscriptionEnabled" ); - QTest::addColumn( "isDisconnectedModeEnabled" ); - QTest::addColumn( "intervalCheckTime" ); - QTest::addColumn( "separator" ); - - Akonadi::Collection collection; - - Akonadi::Collection::List expectedCollections; - QList scenario; - QStringList callNames; - bool isSubscriptionEnabled; - bool isDisconnectedModeEnabled; - int intervalCheckTime; - - expectedCollections.clear(); - expectedCollections << createRootCollection() - << createCollection( "/", "INBOX" ) - << createCollection( "/", "INBOX/Calendar" ) - << createCollection( "/", "INBOX/Calendar/Private" ) - << createCollection( "/", "INBOX/Archives" ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 LIST \"\" *" - << "S: * LIST ( \\HasChildren ) / INBOX" - << "S: * LIST ( \\HasChildren ) / INBOX/Calendar" - << "S: * LIST ( ) / INBOX/Calendar/Private" - << "S: * LIST ( ) / INBOX/Archives" - << "S: A000003 OK list done"; - - callNames.clear(); - callNames << "setIdleCollection" << "collectionsRetrieved"; - - isSubscriptionEnabled = false; - isDisconnectedModeEnabled = false; - intervalCheckTime = -1; - - QTest::newRow( "first listing, connected IMAP" ) << expectedCollections << scenario << callNames - << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime - << QChar('/'); - - - - expectedCollections.clear(); - expectedCollections << createRootCollection( true, 5 ) - << createCollection( "/", "INBOX" ) - << createCollection( "/", "INBOX/Calendar" ) - << createCollection( "/", "INBOX/Calendar/Private" ) - << createCollection( "/", "INBOX/Archives" ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 LIST \"\" *" - << "S: * LIST ( \\HasChildren ) / INBOX" - << "S: * LIST ( \\HasChildren ) / INBOX/Calendar" - << "S: * LIST ( ) / INBOX/Calendar/Private" - << "S: * LIST ( ) / INBOX/Archives" - << "S: A000003 OK list done"; - - callNames.clear(); - callNames << "setIdleCollection" << "collectionsRetrieved"; - - isSubscriptionEnabled = false; - isDisconnectedModeEnabled = true; - intervalCheckTime = 5; - - QTest::newRow( "first listing, disconnected IMAP" ) << expectedCollections << scenario << callNames - << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime - << QChar('/'); - - - - expectedCollections.clear(); - expectedCollections << createRootCollection( true, 5 ) - << createCollection( "/", "INBOX" ) - << createCollection( "/", "INBOX/Archives" ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 LIST \"\" *" - << "S: * LIST ( \\HasChildren ) / INBOX" - << "S: * LIST ( \\HasChildren ) / INBOX/" - << "S: * LIST ( \\HasChildren ) / INBOX/Archives" - << "S: A000003 OK list done"; - - callNames.clear(); - callNames << "setIdleCollection" << "collectionsRetrieved"; - - isSubscriptionEnabled = false; - isDisconnectedModeEnabled = true; - intervalCheckTime = 5; - - QTest::newRow( "first listing, spurious INBOX/ (BR: 25342)" ) << expectedCollections << scenario << callNames - << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime - << QChar('/'); - - - expectedCollections.clear(); - expectedCollections << createRootCollection() - << createCollection( "/", "INBOX" ) - << createCollection( "/", "INBOX/Calendar", true ) - << createCollection( "/", "INBOX/Calendar/Private" ) - << createCollection( "/", "INBOX/Archives" ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 LIST \"\" *" - << "S: * LIST ( \\HasChildren ) / INBOX" - << "S: * LIST ( ) / INBOX/Calendar/Private" - << "S: * LIST ( ) / INBOX/Archives" - << "S: A000003 OK list done"; - - callNames.clear(); - callNames << "setIdleCollection" << "collectionsRetrieved"; - - isSubscriptionEnabled = false; - isDisconnectedModeEnabled = false; - intervalCheckTime = -1; - - QTest::newRow( "auto-insert missing nodes in the tree" ) << expectedCollections << scenario << callNames - << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime - << QChar('/'); - - - - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 LIST \"\" *" - << "S: * LIST ( ) / INBOX/Archives" - << "S: * LIST ( ) / INBOX/Calendar/Private" - << "S: * LIST ( \\HasChildren ) / INBOX" - << "S: A000003 OK list done"; - - callNames.clear(); - callNames << "setIdleCollection" << "collectionsRetrieved"; - - isSubscriptionEnabled = false; - isDisconnectedModeEnabled = false; - intervalCheckTime = -1; - - QTest::newRow( "auto-insert missing nodes in the tree (reverse order)" ) - << expectedCollections << scenario << callNames - << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime - << QChar('/'); - - - - expectedCollections.clear(); - expectedCollections << createRootCollection() - << createCollection( "/", "INBOX" ) - << createCollection( "/", "INBOX/Calendar" ) - << createCollection( "/", "INBOX/Calendar/Private" ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 LIST \"\" *" - << "S: * LIST ( ) / INBOX/Unsubscribed" - << "S: * LIST ( ) / INBOX/Calendar" - << "S: * LIST ( ) / INBOX/Calendar/Private" - << "S: * LIST ( \\HasChildren ) / INBOX" - << "S: A000003 OK list done" - << "C: A000004 LSUB \"\" *" - << "S: * LSUB ( \\HasChildren ) / INBOX" - << "S: * LSUB ( ) / INBOX/SubscribedButNotExisting" - << "S: * LSUB ( ) / INBOX/Calendar" - << "S: * LSUB ( ) / INBOX/Calendar/Private" - << "S: A000004 OK list done"; - - callNames.clear(); - callNames << "setIdleCollection" << "collectionsRetrieved"; - - isSubscriptionEnabled = true; - isDisconnectedModeEnabled = false; - intervalCheckTime = -1; - - QTest::newRow( "subscription enabled" ) << expectedCollections << scenario << callNames - << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime - << QChar('/'); - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 LIST \"\" *" - << "S: * LIST ( ) / INBOX/Unsubscribed" - << "S: * LIST ( ) / INBOX/Calendar" - << "S: * LIST ( ) / INBOX/Calendar/Private" - << "S: * LIST ( \\HasChildren ) / INBOX" - << "S: A000003 OK list done" - << "C: A000004 LSUB \"\" *" - << "S: * LSUB ( \\HasChildren ) / Inbox" - << "S: * LSUB ( ) / Inbox/SubscribedButNotExisting" - << "S: * LSUB ( ) / Inbox/Calendar" - << "S: * LSUB ( ) / Inbox/Calendar/Private" - << "S: A000004 OK list done"; - - callNames.clear(); - callNames << "setIdleCollection" << "collectionsRetrieved"; - - isSubscriptionEnabled = true; - isDisconnectedModeEnabled = false; - intervalCheckTime = -1; - - QTest::newRow( "subscription enabled, case insensitive inbox" ) << expectedCollections << scenario << callNames - << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime - << QChar('/'); - - expectedCollections.clear(); - expectedCollections << createRootCollection() - << createCollection( "/", "INBOX", false, true ) - << createCollection( "/", "Archive" ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 LIST \"\" *" - << "S: * LIST ( \\Noinferiors ) / INBOX" - << "S: * LIST ( ) / Archive" - << "S: A000003 OK list done"; - - callNames.clear(); - callNames << "setIdleCollection" << "collectionsRetrieved"; - - isSubscriptionEnabled = false; - isDisconnectedModeEnabled = false; - intervalCheckTime = -1; - - QTest::newRow( "Noinferiors" ) << expectedCollections << scenario << callNames - << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime - << QChar('/'); - - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 LIST \"\" *" - << "S: * LIST ( ) . INBOX" - << "S: * LIST ( ) . INBOX.Foo" - << "S: * LIST ( ) . INBOX.Bar" - << "S: A000003 OK list done"; - callNames.clear(); - callNames << "setIdleCollection" << "collectionsRetrieved"; - - expectedCollections.clear(); - expectedCollections << createRootCollection() - << createCollection( ".", "INBOX" ) - << createCollection( ".", "INBOX.Foo" ) - << createCollection( ".", "INBOX.Bar" ); - isSubscriptionEnabled = false; - isDisconnectedModeEnabled = false; - intervalCheckTime = -1; - - QTest::newRow( "non-standard separators" ) << expectedCollections << scenario << callNames - << isSubscriptionEnabled << isDisconnectedModeEnabled << intervalCheckTime - << QChar('.'); - } - - void shouldListCollections() - { - QFETCH( Akonadi::Collection::List, expectedCollections ); - QFETCH( QList, scenario ); - QFETCH( QStringList, callNames ); - QFETCH( bool, isSubscriptionEnabled ); - QFETCH( bool, isDisconnectedModeEnabled ); - QFETCH( int, intervalCheckTime ); - QFETCH( QChar, separator ); - - FakeServer server; - server.setScenario( scenario ); - server.startAndWait(); - - SessionPool pool( 1 ); - - pool.setPasswordRequester( createDefaultRequester() ); - QVERIFY( pool.connect( createDefaultAccount() ) ); - QVERIFY( waitForSignal( &pool, SIGNAL(connectDone(int,QString)) ) ); - - DummyResourceState::Ptr state = DummyResourceState::Ptr( new DummyResourceState ); - state->setResourceName( "resource" ); - state->setSubscriptionEnabled( isSubscriptionEnabled ); - state->setDisconnectedModeEnabled( isDisconnectedModeEnabled ); - state->setIntervalCheckTime( intervalCheckTime ); - - RetrieveCollectionsTask *task = new RetrieveCollectionsTask( state ); - task->start( &pool ); - - Akonadi::Collection::List collections; - - QTRY_COMPARE( state->calls().count(), callNames.size() ); - for ( int i = 0; i < callNames.size(); i++ ) { - QString command = QString::fromUtf8(state->calls().at( i ).first); - QVariant parameter = state->calls().at( i ).second; - - if ( command=="cancelTask" && callNames[i]!="cancelTask" ) { - kDebug() << "Got a cancel:" << parameter.toString(); - } - - QCOMPARE( command, callNames[i] ); - - if ( command == "cancelTask" ) { - QVERIFY( !parameter.toString().isEmpty() ); - } else if ( command == "collectionsRetrieved" ) { - collections+= parameter.value(); - } - } - - QCOMPARE( state->separatorCharacter(), separator ); - - QVERIFY( server.isAllScenarioDone() ); - compareCollectionLists( collections, expectedCollections ); - - server.quit(); - } - -private: - qint64 m_nextCollectionId; - - Akonadi::Collection createRootCollection( bool isDisconnectedImap = false, int intervalCheck = -1 ) - { - // Root - Akonadi::Collection collection = Akonadi::Collection( m_nextCollectionId++ ); - collection.setName( "resource" ); - collection.setRemoteId( "root-id" ); - collection.setContentMimeTypes( QStringList( Akonadi::Collection::mimeType() ) ); - collection.setParentCollection( Akonadi::Collection::root() ); - collection.addAttribute( new NoSelectAttribute( true ) ); - - Akonadi::CachePolicy policy; - policy.setInheritFromParent( false ); - policy.setSyncOnDemand( true ); - - if ( isDisconnectedImap ) { - policy.setLocalParts( QStringList() << Akonadi::MessagePart::Envelope - << Akonadi::MessagePart::Header - << Akonadi::MessagePart::Body ); - policy.setCacheTimeout( -1 ); - } else { - policy.setLocalParts( QStringList() << Akonadi::MessagePart::Envelope - << Akonadi::MessagePart::Header ); - policy.setCacheTimeout( 60 ); - } - - policy.setIntervalCheckTime( intervalCheck ); - - collection.setCachePolicy( policy ); - - return collection; - } - - Akonadi::Collection createCollection( const QString &separator, const QString &path, bool isNoSelect = false, bool isNoInferiors = false ) - { - // No path? That's the root of this resource then - if ( path.isEmpty() ) { - return createRootCollection(); - } - - QStringList pathParts = path.split( separator ); - - const QString pathPart = pathParts.takeLast(); - const QString parentPath = pathParts.join( separator ); - - // Here we should likely reuse already produced collections if possible to be 100% accurate - // but in the tests we check only a limited amount of properties (namely remote id and name). - const Akonadi::Collection parentCollection = createCollection( separator, parentPath ); - - - Akonadi::Collection collection( m_nextCollectionId++ ); - collection.setName( pathPart ); - collection.setRemoteId( separator + pathPart ); - - collection.setParentCollection( parentCollection ); - collection.setContentMimeTypes( QStringList() << "message/rfc822" << Akonadi::Collection::mimeType() ); - - // If the folder is the Inbox, make some special settings. - if ( pathPart.compare( QLatin1String( "INBOX" ) , Qt::CaseInsensitive ) == 0 ) { - Akonadi::EntityDisplayAttribute *attr = new Akonadi::EntityDisplayAttribute; - attr->setDisplayName( i18n( "Inbox" ) ); - attr->setIconName( "mail-folder-inbox" ); - collection.addAttribute( attr ); - } - - // If the folder is the user top-level folder, mark it as well, even although it is not officially noted in the RFC - if ( ( pathPart.compare( QLatin1String( "user" ) , Qt::CaseInsensitive ) == 0) && isNoSelect ) { - Akonadi::EntityDisplayAttribute *attr = new Akonadi::EntityDisplayAttribute; - attr->setDisplayName( i18n( "Shared Folders" ) ); - attr->setIconName( "x-mail-distribution-list" ); - collection.addAttribute( attr ); - } - - // If this folder is a noselect folder, make some special settings. - if ( isNoSelect ) { - collection.addAttribute( new NoSelectAttribute( true ) ); - collection.setContentMimeTypes( QStringList() << Akonadi::Collection::mimeType() ); - collection.setRights( Akonadi::Collection::ReadOnly ); - } - - if ( isNoInferiors ) { - collection.addAttribute( new NoInferiorsAttribute( true ) ); - collection.setRights( collection.rights() & ~Akonadi::Collection::CanCreateCollection ); - } - - return collection; - } - - void compareCollectionLists( const Akonadi::Collection::List &resultList, - const Akonadi::Collection::List &expectedList ) - { - for ( int i = 0; i< expectedList.size(); i++ ) { - Akonadi::Collection expected = expectedList[i]; - bool found = false; - - for ( int j = 0; j < resultList.size(); j++ ) { - Akonadi::Collection result = resultList[j]; - - if ( result.remoteId() == expected.remoteId() ) { - found = true; - - QVERIFY( !result.name().isEmpty() ); - - QCOMPARE( result.name(), expected.name() ); - QCOMPARE( result.contentMimeTypes(), expected.contentMimeTypes() ); - QCOMPARE( result.rights(), expected.rights() ); - if ( expected.parentCollection() == Akonadi::Collection::root() ) { - QCOMPARE( result.parentCollection(), expected.parentCollection() ); - } else { - QCOMPARE( result.parentCollection().remoteId(), expected.parentCollection().remoteId() ); - } - - QCOMPARE( result.cachePolicy().inheritFromParent(), expected.cachePolicy().inheritFromParent() ); - QCOMPARE( result.cachePolicy().syncOnDemand(), expected.cachePolicy().syncOnDemand() ); - QCOMPARE( result.cachePolicy().localParts(), expected.cachePolicy().localParts() ); - QCOMPARE( result.cachePolicy().cacheTimeout(), expected.cachePolicy().cacheTimeout() ); - QCOMPARE( result.cachePolicy().intervalCheckTime(), expected.cachePolicy().intervalCheckTime() ); - - QCOMPARE( result.hasAttribute(), expected.hasAttribute() ); - QCOMPARE( result.hasAttribute(), expected.hasAttribute() ); - - break; - } - } - - QVERIFY2( found, QString( "%1 not found!" ).arg(expected.remoteId() ).toUtf8() ); - } - - QCOMPARE( resultList.size(), expectedList.size() ); - } -}; - -QTEST_KDEMAIN_CORE( TestRetrieveCollectionsTask ) - -#include "testretrievecollectionstask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/testretrieveitemstask.cpp kdepim-runtime-15.08.0/resources/imap/tests/testretrieveitemstask.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/testretrieveitemstask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/testretrieveitemstask.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,613 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "imaptestbase.h" - -#include "retrieveitemstask.h" -#include "uidnextattribute.h" -#include -#include - -#include -#include -#include - -class TestRetrieveItemsTask : public ImapTestBase -{ - Q_OBJECT - -private slots: - void shouldIntrospectCollection_data() - { - QTest::addColumn( "collection" ); - QTest::addColumn< QList >( "scenario" ); - QTest::addColumn( "callNames" ); - - Akonadi::Collection collection; - QList scenario; - QStringList callNames; - - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 EXPUNGE" - << "S: A000004 OK expunge done" - << "C: A000005 SELECT \"INBOX/Foo\"" - << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" - << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" - << "S: * 1 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UIDVALIDITY 1149151135 ]" - << "S: * OK [ UIDNEXT 9 ]" - << "S: A000005 OK select done" - << "C: A000006 UID SEARCH UID 1:9" - << "S: * SEARCH 1 2 3 4 5 6 7 8 9" - << "S: A000006 OK search done" - << "C: A000007 UID FETCH 1:9 (RFC822.SIZE INTERNALDATE " - "BODY.PEEK[HEADER] " - "FLAGS UID)" - << "S: * 1 FETCH ( FLAGS (\\Seen) UID 7 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " - "RFC822.SIZE 75 BODY[HEADER] {69}\r\n" - "From: Foo \r\n" - "To: Bar \r\n" - "Subject: Test Mail\r\n" - "\r\n" - " )" - << "S: A000007 OK fetch done"; - - callNames.clear(); - callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone" ; - - - QTest::newRow( "first listing, connected IMAP" ) << collection << scenario << callNames; - - Akonadi::CachePolicy policy; - policy.setLocalParts( QStringList() << Akonadi::MessagePart::Envelope - << Akonadi::MessagePart::Header - << Akonadi::MessagePart::Body ); - - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); - collection.setCachePolicy( policy ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 EXPUNGE" - << "S: A000004 OK expunge done" - << "C: A000005 SELECT \"INBOX/Foo\"" - << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" - << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" - << "S: * 1 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UIDVALIDITY 1149151135 ]" - << "S: * OK [ UIDNEXT 9 ]" - << "S: A000005 OK select done" - << "C: A000006 UID SEARCH UID 1:9" - << "S: * SEARCH 1 2 3 4 5 6 7 8 9" - << "S: A000006 OK search done" - << "C: A000007 UID FETCH 1:9 (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)" - << "S: * 1 FETCH ( FLAGS (\\Seen) UID 7 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " - "RFC822.SIZE 75 BODY[] {75}\r\n" - "From: Foo \r\n" - "To: Bar \r\n" - "Subject: Test Mail\r\n" - "\r\n" - "Test\r\n" - " )" - << "S: A000007 OK fetch done"; - - callNames.clear(); - callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone"; - - QTest::newRow( "first listing, disconnected IMAP" ) << collection << scenario << callNames; - - - Akonadi::CollectionStatistics stats; - stats.setCount( 1 ); - - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); - collection.attribute( Akonadi::Collection::AddIfMissing )->setUidNext(9); - collection.setCachePolicy( policy ); - collection.setStatistics( stats ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 EXPUNGE" - << "S: A000004 OK expunge done" - << "C: A000005 SELECT \"INBOX/Foo\"" - << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" - << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" - << "S: * 1 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UIDVALIDITY 1149151135 ]" - << "S: * OK [ UIDNEXT 9 ]" - << "S: A000005 OK select done" - << "C: A000006 UID SEARCH UID 1:9" - << "S: * SEARCH 1 2 3 4 5 6 7 8 9" - << "S: A000006 OK search done" - << "C: A000007 UID FETCH 1:9 (FLAGS UID)" - << "S: * 1 FETCH ( FLAGS (\\Seen) UID 7 )" - << "S: A000007 OK fetch done"; - - callNames.clear(); - callNames << "itemsRetrievedIncremental" << "applyCollectionChanges" << "itemsRetrievedIncremental" << "itemsRetrievalDone"; - - //Disabled test since the flag sync is disabled if CONDSTORE is not supported -// QTest::newRow( "second listing, checking for flag changes" ) << collection << scenario << callNames; - - - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); - collection.setCachePolicy( policy ); - stats.setCount( 1 ); - collection.setStatistics( stats ); - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 EXPUNGE" - << "S: A000004 OK expunge done" - << "C: A000005 SELECT \"INBOX/Foo\"" - << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" - << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" - << "S: * 0 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UIDVALIDITY 1149151135 ]" - << "S: * OK [ UIDNEXT 9 ]" - << "S: A000005 OK select done"; - - callNames.clear(); - callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone"; - - QTest::newRow( "third listing, full sync, empty folder" ) << collection << scenario << callNames; - - collection.attribute( Akonadi::Collection::AddIfMissing )->setUidNext( 8 ); - stats.setCount( 4 ); - collection.setStatistics( stats ); - collection.attribute( Akonadi::Entity::AddIfMissing )->setHighestModSeq( 123456788 ); - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 EXPUNGE" - << "S: A000004 OK expunge done" - << "C: A000005 SELECT \"INBOX/Foo\"" - << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" - << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" - << "S: * 5 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UIDVALIDITY 1149151135 ]" - << "S: * OK [ UIDNEXT 9 ]" - << "S: * OK [ HIGHESTMODSEQ 123456789 ]" - << "S: A000005 OK select done" - << "C: A000006 UID SEARCH UID 8:9" - << "S: * SEARCH 8 9" - << "S: A000006 OK search done" - << "C: A000007 UID FETCH 8:9 (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)" - << "S: * 5 FETCH ( FLAGS (\\Seen) UID 9 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " - "RFC822.SIZE 75 BODY[] {75}\r\n" - "From: Foo \r\n" - "To: Bar \r\n" - "Subject: Test Mail\r\n" - "\r\n" - "Test\r\n" - " )" - << "S: A000007 OK fetch done" - << "C: A000008 UID SEARCH UID 1:7" - << "S: * SEARCH 1 2 3 4 5 6 7" - << "S: A000008 OK search done" - << "C: A000009 UID FETCH 1:7 (FLAGS UID)" - << "S: * 1 FETCH" - << "S: * 2 FETCH" - << "S: * 3 FETCH" - << "S: * 4 FETCH" - << "S: A000009 OK fetch done"; - - callNames.clear(); - callNames << "itemsRetrievedIncremental" << "applyCollectionChanges" << "itemsRetrievedIncremental"<< "itemsRetrievalDone"; - - //We know no messages have been removed, so we can do an incremental update - QTest::newRow( "uidnext changed, fetch new messages incrementally" ) << collection << scenario << callNames; - - collection.attribute( Akonadi::Collection::AddIfMissing )->setUidNext( 8 ); - stats.setCount( 5 ); - collection.setStatistics( stats ); - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 EXPUNGE" - << "S: A000004 OK expunge done" - << "C: A000005 SELECT \"INBOX/Foo\"" - << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" - << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" - << "S: * 5 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UIDVALIDITY 1149151135 ]" - << "S: * OK [ UIDNEXT 9 ]" - << "S: * OK [ HIGHESTMODSEQ 123456789 ]" - << "S: A000005 OK select done" - << "C: A000006 UID SEARCH UID 8:9" - << "S: * SEARCH 8 9" - << "S: A000006 OK search done" - << "C: A000007 UID FETCH 8:9 (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)" - << "S: * 4 FETCH ( FLAGS (\\Seen) UID 8 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " - "RFC822.SIZE 75 BODY[] {75}\r\n" - "From: Foo \r\n" - "To: Bar \r\n" - "Subject: Test Mail\r\n" - "\r\n" - "Test\r\n" - " )" - << "S: * 5 FETCH ( FLAGS (\\Seen) UID 9 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " - "RFC822.SIZE 75 BODY[] {75}\r\n" - "From: Foo \r\n" - "To: Bar \r\n" - "Subject: Test Mail\r\n" - "\r\n" - "Test\r\n" - " )" - << "S: A000007 OK fetch done" - << "C: A000008 UID SEARCH UID 1:7" - << "S: * SEARCH 1 2 3 4 5 6 7" - << "S: A000008 OK search done" - << "C: A000009 UID FETCH 1:7 (FLAGS UID)" - << "S: * 1 FETCH" - << "S: * 2 FETCH" - << "S: * 3 FETCH" - << "S: A000009 OK fetch done"; - - callNames.clear(); - callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone"; - - //A new message has been added and an old one removed, we can't do an incremental update - QTest::newRow( "uidnext changed, fetch new messages and list flags" ) << collection << scenario << callNames; - - - collection = createCollectionChain(QLatin1String("/INBOX/Foo") ); - collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); - collection.setCachePolicy( policy ); - collection.attribute( Akonadi::Collection::AddIfMissing )->setUidNext( 9 ); - collection.attribute( Akonadi::Entity::AddIfMissing )->setHighestModSeq( 123456789 ); - stats.setCount( 5 ); - collection.setStatistics( stats ); - scenario.clear(); - scenario << defaultPoolConnectionScenario( QList() << "CONDSTORE" ) - << "C: A000003 SELECT \"INBOX/Foo\" (CONDSTORE)" - << "S: A000003 OK select done" - << "C: A000004 EXPUNGE" - << "S: A000004 OK expunge DONE" - << "C: A000005 SELECT \"INBOX/Foo\" (CONDSTORE)" - << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" - << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" - << "S: * 5 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UIDVALIDITY 1149151135 ]" - << "S: * OK [ UIDNEXT 9 ]" - << "S: * OK [ HIGHESTMODSEQ 123456789 ]" - << "S: A000005 OK select done"; - callNames.clear(); - callNames << "applyCollectionChanges" << "itemsRetrievedIncremental" << "itemsRetrievalDone"; - - //No flags have changed - QTest::newRow( "highestmodseq test" ) << collection << scenario << callNames; - - collection = createCollectionChain(QLatin1String("/INBOX/Foo") ); - collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); - collection.setCachePolicy( policy ); - collection.attribute( Akonadi::Collection::AddIfMissing )->setUidNext( 9 ); - collection.attribute( Akonadi::Entity::AddIfMissing )->setHighestModSeq( 123456788 ); - stats.setCount( 5 ); - collection.setStatistics( stats ); - scenario.clear(); - scenario << defaultPoolConnectionScenario( QList() << "CONDSTORE" ) - << "C: A000003 SELECT \"INBOX/Foo\" (CONDSTORE)" - << "S: A000003 OK select done" - << "C: A000004 EXPUNGE" - << "S: A000004 OK expunge DONE" - << "C: A000005 SELECT \"INBOX/Foo\" (CONDSTORE)" - << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" - << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" - << "S: * 5 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UIDVALIDITY 1149151135 ]" - << "S: * OK [ UIDNEXT 9 ]" - << "S: * OK [ HIGHESTMODSEQ 123456789 ]" - << "S: A000005 OK select done" - << "C: A000006 UID FETCH 1:9 (FLAGS UID) (CHANGEDSINCE 123456788)" - << "S: * 5 FETCH ( UID 8 FLAGS () )" - << "S: A000006 OK fetch done"; - callNames.clear(); - callNames << "itemsRetrievedIncremental" << "applyCollectionChanges" << "itemsRetrievedIncremental" << "itemsRetrievalDone"; - - //fetch only changed flags - QTest::newRow( "changedsince test" ) << collection << scenario << callNames; - - collection = createCollectionChain(QLatin1String("/INBOX/Foo") ); - collection.setCachePolicy( policy ); - collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); - collection.attribute( Akonadi::Collection::AddIfMissing )->setUidNext( 9 ); - collection.attribute( Akonadi::Entity::AddIfMissing )->setHighestModSeq( 123456788 ); - stats.setCount( 5 ); - collection.setStatistics( stats ); - scenario.clear(); - scenario << defaultPoolConnectionScenario( QList() << "XYMHIGHESTMODSEQ" ) - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 EXPUNGE" - << "S: A000004 OK expunge DONE" - << "C: A000005 SELECT \"INBOX/Foo\"" - << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" - << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" - << "S: * 5 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UIDVALIDITY 1149151135 ]" - << "S: * OK [ UIDNEXT 9 ]" - << "S: * OK [ HIGHESTMODSEQ 123456789 ]" - << "S: A000005 OK select done"; - //Disabled since the flag sync is disabled if CONDSTORE is not supported -// << "C: A000006 UID SEARCH UID 1:9" -// << "S: * SEARCH 1 2 3 4 5 6 7 8 9" -// << "S: A000006 OK search done" -// << "C: A000007 UID FETCH 1:9 (FLAGS UID)" -// << "S: * 5 FETCH ( UID 8 FLAGS () )" -// << "S: A000007 OK fetch done"; - callNames.clear(); - - //Disabled since the flag sync is disabled if CONDSTORE is not supported - callNames << /*"itemsRetrievedIncremental" << */"applyCollectionChanges" << "itemsRetrievedIncremental" << "itemsRetrievalDone"; - - //Don't rely on yahoos highestmodseq implementation - QTest::newRow( "yahoo highestmodseq test" ) << collection << scenario << callNames; - - - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection.attribute( Akonadi::Collection::AddIfMissing )->setUidNext( 9 ); - collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(3); - collection.setCachePolicy( policy ); - stats.setCount( 1 ); - collection.setStatistics( stats ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 EXPUNGE" - << "S: A000004 OK expunge done" - << "C: A000005 SELECT \"INBOX/Foo\"" - << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" - << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" - << "S: * 1 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UIDVALIDITY 1149151135 ]" - << "S: * OK [ UIDNEXT 9 ]" - << "S: A000005 OK select done" - << "C: A000006 UID SEARCH UID 1:9" - << "S: * SEARCH 1 2 3 4 5 6 7 8 9" - << "S: A000006 OK search done" - << "C: A000007 UID FETCH 1:9 (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)" - << "S: * 1 FETCH ( FLAGS (\\Seen) UID 2321 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " - "RFC822.SIZE 75 BODY[] {75}\r\n" - "From: Foo \r\n" - "To: Bar \r\n" - "Subject: Test Mail\r\n" - "\r\n" - "Test\r\n" - " )" - << "S: A000007 OK fetch done"; - - callNames.clear(); - callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone"; - - QTest::newRow( "uidvalidity changed" ) << collection << scenario << callNames; - - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - collection.attribute(Akonadi::Collection::AddIfMissing)->setUidNext(105); - collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); - collection.setCachePolicy( policy ); - stats.setCount(104); - collection.setStatistics( stats ); - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 EXPUNGE" - << "S: A000004 OK expunge done" - << "C: A000005 SELECT \"INBOX/Foo\"" - << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" - << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" - << "S: * 119 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UIDVALIDITY 1149151135 ]" - << "S: * OK [ UIDNEXT 120 ]" - << "S: A000005 OK select done" - << "C: A000006 UID SEARCH UID 105:120" - //We asked for until 120 but only 119 is available (120 is uidnext) - << "S: * SEARCH 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119" - << "S: A000006 OK search done" - << "C: A000007 UID FETCH 105:114 (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)" - << "S: * 1 FETCH ( FLAGS (\\Seen) UID 105 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " - "RFC822.SIZE 75 BODY[] {75}\r\n" - "From: Foo \r\n" - "To: Bar \r\n" - "Subject: Test Mail\r\n" - "\r\n" - "Test\r\n" - " )" - //9 more would follow but are excluded for clarity - << "S: A000007 OK fetch done" - << "C: A000008 UID FETCH 115:119 (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)" - << "S: * 1 FETCH ( FLAGS (\\Seen) UID 115 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " - "RFC822.SIZE 75 BODY[] {75}\r\n" - "From: Foo \r\n" - "To: Bar \r\n" - "Subject: Test Mail\r\n" - "\r\n" - "Test\r\n" - " )" - //4 more would follow but are excluded for clarity - << "S: A000008 OK fetch done" - << "C: A000009 UID SEARCH UID 1:104" - << "S: * SEARCH 1 2 99 100" - << "S: A000009 OK search done" - << "C: A000010 UID FETCH 1:2,99:100 (FLAGS UID)" - << "S: * 1 FETCH ( FLAGS (\\Seen) UID 1 )" - //3 more would follow but are excluded for clarity - << "S: A000010 OK fetch done"; - - callNames.clear(); - callNames << "itemsRetrievedIncremental" << "itemsRetrievedIncremental" << "itemsRetrievedIncremental" << "applyCollectionChanges" << "itemsRetrievedIncremental" << "itemsRetrievalDone"; - - QTest::newRow( "test batch processing" ) << collection << scenario << callNames; - - collection = createCollectionChain(QLatin1String("/INBOX/Foo") ); - collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); - collection.setCachePolicy( policy ); - collection.attribute( Akonadi::Collection::AddIfMissing )->setUidNext( 9 ); - collection.attribute( Akonadi::Entity::AddIfMissing )->setHighestModSeq( 123456789 ); - stats.setCount( 5 ); - collection.setStatistics( stats ); - scenario.clear(); - scenario << defaultPoolConnectionScenario( QList() << "CONDSTORE" ) - << "C: A000003 SELECT \"INBOX/Foo\" (CONDSTORE)" - << "S: A000003 OK select done" - << "C: A000004 EXPUNGE" - << "S: A000004 OK expunge DONE" - << "C: A000005 SELECT \"INBOX/Foo\" (CONDSTORE)" - << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" - << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" - << "S: * 4 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UIDVALIDITY 1149151135 ]" - << "S: * OK [ UIDNEXT 9 ]" - << "S: * OK [ HIGHESTMODSEQ 123456789 ]" - << "S: A000005 OK select done" - << "C: A000006 UID SEARCH UID 1:9" - << "S: * SEARCH 1 2 3 4" - << "S: A000006 OK search done" - << "C: A000007 UID FETCH 1:4 (FLAGS UID)" - << "S: * 1 FETCH ( FLAGS (\\Seen) UID 1 )" - << "S: * 2 FETCH ( FLAGS (\\Seen) UID 2 )" - << "S: * 3 FETCH ( FLAGS (\\Seen) UID 3 )" - << "S: * 4 FETCH ( FLAGS (\\Seen) UID 4 )" - << "S: A000007 OK fetch done"; - callNames.clear(); - callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone"; - - //fetch only changed flags - QTest::newRow( "remote message deleted" ) << collection << scenario << callNames; - - collection = createCollectionChain(QLatin1String("/INBOX/Foo") ); - collection.attribute(Akonadi::Entity::AddIfMissing)->setUidValidity(1149151135); - collection.setCachePolicy( policy ); - collection.attribute( Akonadi::Collection::AddIfMissing )->setUidNext( -1 ); - collection.attribute( Akonadi::Entity::AddIfMissing )->setHighestModSeq( 123456789 ); - stats.setCount( 0 ); - collection.setStatistics( stats ); - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 EXPUNGE" - << "S: A000004 OK expunge done" - << "C: A000005 SELECT \"INBOX/Foo\"" - << "S: * FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)" - << "S: * OK [ PERMANENTFLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen) ]" - << "S: * 9 EXISTS" - << "S: * 0 RECENT" - << "S: * OK [ UIDVALIDITY 1149151135 ]" - << "S: A000005 OK select done" - << "C: A000006 FETCH 1:9 (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)" - << "S: * 1 FETCH ( FLAGS (\\Seen) UID 2321 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " - "RFC822.SIZE 75 BODY[] {75}\r\n" - "From: Foo \r\n" - "To: Bar \r\n" - "Subject: Test Mail\r\n" - "\r\n" - "Test\r\n" - " )" - << "S: A000006 OK fetch done"; - - callNames.clear(); - callNames << "itemsRetrieved" << "applyCollectionChanges" << "itemsRetrievalDone" ; - - QTest::newRow( "missing uidnext" ) << collection << scenario << callNames; - - } - - void shouldIntrospectCollection() - { - QFETCH( Akonadi::Collection, collection ); - QFETCH( QList, scenario ); - QFETCH( QStringList, callNames ); - - FakeServer server; - server.setScenario( scenario ); - server.startAndWait(); - - SessionPool pool( 1 ); - - pool.setPasswordRequester( createDefaultRequester() ); - QVERIFY( pool.connect( createDefaultAccount() ) ); - QVERIFY( waitForSignal( &pool, SIGNAL(connectDone(int,QString)) ) ); - - DummyResourceState::Ptr state = DummyResourceState::Ptr( new DummyResourceState ); - state->setServerCapabilities( pool.serverCapabilities() ); - state->setCollection( collection ); - - RetrieveItemsTask *task = new RetrieveItemsTask( state ); - task->setFetchMissingItemBodies( false ); - task->start( &pool ); - - QTRY_COMPARE( state->calls().count(), callNames.size() ); - kDebug() << state->calls(); - for ( int i = 0; i < callNames.size(); i++ ) { - QString command = QString::fromUtf8(state->calls().at( i ).first); - QVariant parameter = state->calls().at( i ).second; - - if ( command == "cancelTask" && callNames[i] != "cancelTask" ) { - kDebug() << "Got a cancel:" << parameter.toString(); - } - - QCOMPARE( command, callNames[i] ); - - if ( command == "cancelTask" ) { - QVERIFY( !parameter.toString().isEmpty() ); - } - } - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } -}; - -QTEST_KDEMAIN_CORE( TestRetrieveItemsTask ) - -#include "testretrieveitemstask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/testretrieveitemtask.cpp kdepim-runtime-15.08.0/resources/imap/tests/testretrieveitemtask.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/testretrieveitemtask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/testretrieveitemtask.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "imaptestbase.h" - -#include "retrieveitemtask.h" - -class TestRetrieveItemTask : public ImapTestBase -{ - Q_OBJECT - -private slots: - void shouldFetchMessage_data() - { - QTest::addColumn( "item" ); - QTest::addColumn( "message" ); - QTest::addColumn< QList >( "scenario" ); - QTest::addColumn( "callName" ); - - Akonadi::Collection collection; - Akonadi::Item item; - QString message; - QList scenario; - - collection = createCollectionChain( QLatin1String("/INBOX/Foo") ); - item = Akonadi::Item( 2 ); - item.setParentCollection( collection ); - item.setRemoteId( "42" ); - - message = "From: ervin\nTo: someone\nSubject: foo\n\nSpeechless..."; - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 UID FETCH 42 (BODY.PEEK[] UID)" - << "S: * 10 FETCH (UID 42 BODY[] \"From: ervin\nTo: someone\nSubject: foo\n\nSpeechless...\")" - << "S: A000004 OK fetch done"; - QTest::newRow( "normal case" ) << item << message << scenario << "itemRetrieved"; - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 NO select fail"; - QTest::newRow( "select fail" ) << item << message << scenario << "cancelTask"; - - scenario.clear(); - scenario << defaultPoolConnectionScenario() - << "C: A000003 SELECT \"INBOX/Foo\"" - << "S: A000003 OK select done" - << "C: A000004 UID FETCH 42 (BODY.PEEK[] UID)" - << "S: A000004 NO fetch failed"; - QTest::newRow( "fetch fail" ) << item << message << scenario << "cancelTask"; - } - - void shouldFetchMessage() - { - QFETCH( Akonadi::Item, item ); - QFETCH( QString, message ); - QFETCH( QList, scenario ); - QFETCH( QString, callName ); - - FakeServer server; - server.setScenario( scenario ); - server.startAndWait(); - - SessionPool pool( 1 ); - - pool.setPasswordRequester( createDefaultRequester() ); - QVERIFY( pool.connect( createDefaultAccount() ) ); - QVERIFY( waitForSignal( &pool, SIGNAL(connectDone(int,QString)) ) ); - - DummyResourceState::Ptr state = DummyResourceState::Ptr( new DummyResourceState ); - state->setItem( item ); - RetrieveItemTask *task = new RetrieveItemTask( state ); - task->start( &pool ); - - QTRY_COMPARE( state->calls().count(), 1 ); - - QString command = QString::fromUtf8(state->calls().first().first); - if ( command == "cancelTask" && callName != "cancelTask" ) { - kDebug() << "Got a cancel:" << state->calls().first().second.toString(); - } - QCOMPARE( command, callName ); - - QVariant parameter = state->calls().first().second; - - if ( callName == "itemRetrieved" ) { - QCOMPARE( parameter.value().id(), item.id() ); - QCOMPARE( parameter.value().remoteId(), item.remoteId() ); - - QString payload = parameter.value().payload()->encodedContent(); - - QCOMPARE( payload, message ); - - } else if ( callName == "cancelTask" ) { - QVERIFY( !parameter.toString().isEmpty() ); - } else { - QFAIL( QString( "Unexpected call type: %1" ).arg( callName ).toUtf8().constData() ); - } - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } -}; - -QTEST_KDEMAIN_CORE( TestRetrieveItemTask ) - -#include "testretrieveitemtask.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/testsessionpool.cpp kdepim-runtime-15.08.0/resources/imap/tests/testsessionpool.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/testsessionpool.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/testsessionpool.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,794 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Ottens - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or ( at your option ) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "imaptestbase.h" - -#include - -class TestSessionPool : public ImapTestBase -{ - Q_OBJECT - -private slots: - void shouldPrepareFirstSessionOnConnect_data() - { - QTest::addColumn( "account" ); - QTest::addColumn( "requester" ); - QTest::addColumn< QList >( "scenario" ); - QTest::addColumn( "password" ); - QTest::addColumn( "errorCode" ); - QTest::addColumn( "capabilities" ); - - ImapAccount *account = 0; - DummyPasswordRequester *requester = 0; - QList scenario; - QString password; - QStringList capabilities; - - account = createDefaultAccount(); - requester = createDefaultRequester(); - scenario.clear(); - scenario << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in" - << "C: A000002 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 NAMESPACE UIDPLUS IDLE" - << "S: A000002 OK Completed" - << "C: A000003 NAMESPACE" - << "S: * NAMESPACE ( (\"INBOX/\" \"/\") ) ( (\"user/\" \"/\") ) ( (\"\" \"/\") )" - << "S: A000003 OK Completed"; - password = "foobar"; - int errorCode = SessionPool::NoError; - capabilities.clear(); - capabilities << "IMAP4" << "IMAP4REV1" << "NAMESPACE" << "UIDPLUS" << "IDLE"; - QTest::newRow( "normal case" ) << account << requester << scenario - << password << errorCode << capabilities; - - - account = createDefaultAccount(); - requester = createDefaultRequester(); - scenario.clear(); - scenario << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in" - << "C: A000002 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" - << "S: A000002 OK Completed"; - password = "foobar"; - errorCode = SessionPool::NoError; - capabilities.clear(); - capabilities << "IMAP4" << "IMAP4REV1" << "UIDPLUS" << "IDLE"; - QTest::newRow( "no NAMESPACE support" ) << account << requester << scenario - << password << errorCode << capabilities; - - - account = createDefaultAccount(); - requester = createDefaultRequester(); - scenario.clear(); - scenario << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in" - << "C: A000002 CAPABILITY" - << "S: * CAPABILITY IMAP4 IDLE" - << "S: A000002 OK Completed" - << "C: A000003 LOGOUT"; - password = "foobar"; - errorCode = SessionPool::IncompatibleServerError; - capabilities.clear(); - QTest::newRow( "incompatible server" ) << account << requester << scenario - << password << errorCode << capabilities; - - - QList requests; - QList results; - - account = createDefaultAccount(); - requester = createDefaultRequester(); - requests.clear(); - results.clear(); - requests << DummyPasswordRequester::StandardRequest << DummyPasswordRequester::WrongPasswordRequest; - results << DummyPasswordRequester::PasswordRetrieved << DummyPasswordRequester::UserRejected; - requester->setScenario( requests, results ); - scenario.clear(); - scenario << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 NO Login failed" - << "C: A000002 LOGOUT"; - password = "foobar"; - errorCode = SessionPool::LoginFailError; - capabilities.clear(); - QTest::newRow( "login fail, user reject password entry" ) << account << requester << scenario - << password << errorCode << capabilities; - - account = createDefaultAccount(); - requester = createDefaultRequester(); - requests.clear(); - results.clear(); - requests << DummyPasswordRequester::StandardRequest << DummyPasswordRequester::WrongPasswordRequest; - results << DummyPasswordRequester::PasswordRetrieved << DummyPasswordRequester::PasswordRetrieved; - requester->setScenario( requests, results ); - scenario.clear(); - scenario << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 NO Login failed" - << "C: A000002 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000002 OK Login succeeded" - << "C: A000003 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" - << "S: A000003 OK Completed"; - password = "foobar"; - errorCode = SessionPool::NoError; - capabilities.clear(); - capabilities << "IMAP4" << "IMAP4REV1" << "UIDPLUS" << "IDLE"; - QTest::newRow( "login fail, user provide new password" ) << account << requester << scenario - << password << errorCode << capabilities; - - account = createDefaultAccount(); - requester = createDefaultRequester(); - requests.clear(); - results.clear(); - requests << DummyPasswordRequester::StandardRequest << DummyPasswordRequester::WrongPasswordRequest; - results << DummyPasswordRequester::PasswordRetrieved << DummyPasswordRequester::EmptyPasswordEntered; - requester->setScenario( requests, results ); - scenario.clear(); - scenario << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 NO Login failed" - << "C: A000002 LOGOUT"; - password = "foobar"; - errorCode = SessionPool::LoginFailError; - capabilities.clear(); - QTest::newRow( "login fail, user provided empty password" ) << account << requester << scenario - << password << errorCode << capabilities; - - account = createDefaultAccount(); - requester = createDefaultRequester(); - requests.clear(); - results.clear(); - requests << DummyPasswordRequester::StandardRequest << DummyPasswordRequester::WrongPasswordRequest; - results << DummyPasswordRequester::PasswordRetrieved << DummyPasswordRequester::ReconnectNeeded; - requester->setScenario( requests, results ); - scenario.clear(); - scenario << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 NO Login failed" - << "C: A000002 LOGOUT"; - password = "foobar"; - errorCode = SessionPool::ReconnectNeededError; - capabilities.clear(); - QTest::newRow( "login fail, user change the settings" ) << account << requester << scenario - << password << errorCode << capabilities; - } - - - void shouldPrepareFirstSessionOnConnect() - { - QFETCH( ImapAccount*, account ); - QFETCH( DummyPasswordRequester*, requester ); - QFETCH( QList, scenario ); - QFETCH( QString, password ); - QFETCH( int, errorCode ); - QFETCH( QStringList, capabilities ); - - QSignalSpy requesterSpy( requester, SIGNAL(done(int,QString)) ); - - FakeServer server; - server.setScenario( scenario ); - server.startAndWait(); - - SessionPool pool( 2 ); - - QVERIFY( !pool.isConnected() ); - - QSignalSpy poolSpy( &pool, SIGNAL(connectDone(int,QString)) ); - - pool.setPasswordRequester( requester ); - QVERIFY( pool.connect( account ) ); - - QTest::qWait( 200 ); - QVERIFY( requesterSpy.count()>0 ); - if ( requesterSpy.count() == 1 ) { - QCOMPARE( requesterSpy.at( 0 ).at( 0 ).toInt(), 0 ); - QCOMPARE( requesterSpy.at( 0 ).at( 1 ).toString(), password ); - } - - QCOMPARE( poolSpy.count(), 1 ); - QCOMPARE( poolSpy.at( 0 ).at( 0 ).toInt(), errorCode ); - if ( errorCode == SessionPool::NoError ) { - QVERIFY( pool.isConnected() ); - } else { - QVERIFY( !pool.isConnected() ); - } - - QCOMPARE( pool.serverCapabilities(), capabilities ); - QVERIFY( pool.serverNamespaces().isEmpty() ); - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } - - void shouldManageSeveralSessions() - { - FakeServer server; - server.addScenario( QList() - << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in" - << "C: A000002 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 NAMESPACE UIDPLUS IDLE" - << "S: A000002 OK Completed" - << "C: A000003 NAMESPACE" - << "S: * NAMESPACE ( (\"INBOX/\" \"/\") ) ( (\"user/\" \"/\") ) ( (\"\" \"/\") )" - << "S: A000003 OK Completed" - ); - - server.addScenario( QList() - << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in" - ); - - server.startAndWait(); - - - - ImapAccount *account = createDefaultAccount(); - DummyPasswordRequester *requester = createDefaultRequester(); - - QSignalSpy requesterSpy( requester, SIGNAL(done(int,QString)) ); - - SessionPool pool( 2 ); - pool.setPasswordRequester( requester ); - - QSignalSpy connectSpy( &pool, SIGNAL(connectDone(int,QString)) ); - QSignalSpy sessionSpy( &pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString)) ); - - - // Before connect we can't get any session - qint64 requestId = pool.requestSession(); - QCOMPARE( requestId, qint64(-1) ); - - - // Initial connect should trigger only a password request and a connect - QVERIFY( pool.connect( account ) ); - QTest::qWait( 100 ); - QCOMPARE( requesterSpy.count(), 1 ); - QCOMPARE( connectSpy.count(), 1 ); - QCOMPARE( sessionSpy.count(), 0 ); - - - // Requesting a first session shouldn't create a new one, - // only sessionRequestDone is emitted right away - requestId = pool.requestSession(); - QCOMPARE( requestId, qint64( 1 ) ); - QTest::qWait( 100 ); - QCOMPARE( requesterSpy.count(), 1 ); - QCOMPARE( connectSpy.count(), 1 ); - QCOMPARE( sessionSpy.count(), 1 ); - - QCOMPARE( sessionSpy.at( 0 ).at( 0 ).toLongLong(), requestId ); - QVERIFY( sessionSpy.at( 0 ).at( 1 ).value() != 0 ); - QCOMPARE( sessionSpy.at( 0 ).at( 2 ).toInt(), 0 ); - QCOMPARE( sessionSpy.at( 0 ).at( 3 ).toString(), QString() ); - - - // Requesting an extra session should create a new one - // So for instance password will be requested - requestId = pool.requestSession(); - QCOMPARE( requestId, qint64( 2 ) ); - QTest::qWait( 100 ); - QCOMPARE( requesterSpy.count(), 2 ); - QCOMPARE( connectSpy.count(), 1 ); - QCOMPARE( sessionSpy.count(), 2 ); - - QCOMPARE( sessionSpy.at( 1 ).at( 0 ).toLongLong(), requestId ); - QVERIFY( sessionSpy.at( 1 ).at( 1 ).value() != 0 ); - // Should be different sessions... - QVERIFY( sessionSpy.at( 0 ).at( 1 ).value() != sessionSpy.at( 1 ).at( 1 ).value() ); - QCOMPARE( sessionSpy.at( 1 ).at( 2 ).toInt(), 0 ); - QCOMPARE( sessionSpy.at( 1 ).at( 3 ).toString(), QString() ); - - - // Requesting yet another session should fail as we reached the - // maximum pool size, and they're all reserved - requestId = pool.requestSession(); - QCOMPARE( requestId, qint64( 3 ) ); - QTest::qWait( 100 ); - QCOMPARE( requesterSpy.count(), 2 ); - QCOMPARE( connectSpy.count(), 1 ); - QCOMPARE( sessionSpy.count(), 3 ); - - QCOMPARE( sessionSpy.at( 2 ).at( 0 ).toLongLong(), requestId ); - QVERIFY( sessionSpy.at( 2 ).at( 1 ).value()==0 ); - QCOMPARE( sessionSpy.at( 2 ).at( 2 ).toInt(), (int)SessionPool::NoAvailableSessionError ); - QVERIFY( !sessionSpy.at( 2 ).at( 3 ).toString().isEmpty() ); - - - // OTOH, if we release one now, and then request another one - // it should succeed without even creating a new session - KIMAP::Session *session = sessionSpy.at( 0 ).at( 1 ).value(); - pool.releaseSession( session ); - requestId = pool.requestSession(); - QCOMPARE( requestId, qint64( 4 ) ); - QTest::qWait( 100 ); - QCOMPARE( requesterSpy.count(), 2 ); - QCOMPARE( connectSpy.count(), 1 ); - QCOMPARE( sessionSpy.count(), 4 ); - - QCOMPARE( sessionSpy.at( 3 ).at( 0 ).toLongLong(), requestId ); - // Only one session was available, so that should be the one we get gack - QVERIFY( sessionSpy.at( 3 ).at( 1 ).value() == session ); - QCOMPARE( sessionSpy.at( 3 ).at( 2 ).toInt(), 0 ); - QCOMPARE( sessionSpy.at( 3 ).at( 3 ).toString(), QString() ); - - - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } - - void shouldNotifyConnectionLost() - { - FakeServer server; - server.addScenario( QList() - << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in" - << "C: A000002 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" - << "S: A000002 OK Completed" - << "C: A000003 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" - << "X" - ); - - server.startAndWait(); - - ImapAccount *account = createDefaultAccount(); - DummyPasswordRequester *requester = createDefaultRequester(); - - SessionPool pool( 1 ); - pool.setPasswordRequester( requester ); - - QSignalSpy connectSpy( &pool, SIGNAL(connectDone(int,QString)) ); - QSignalSpy sessionSpy( &pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString)) ); - QSignalSpy lostSpy( &pool, SIGNAL(connectionLost(KIMAP::Session*)) ); - - - // Initial connect should trigger only a password request and a connect - QVERIFY( pool.connect( account ) ); - QTest::qWait( 100 ); - QCOMPARE( connectSpy.count(), 1 ); - QCOMPARE( sessionSpy.count(), 0 ); - - qint64 requestId = pool.requestSession(); - QTest::qWait( 100 ); - QCOMPARE( sessionSpy.count(), 1 ); - - QCOMPARE( sessionSpy.at( 0 ).at( 0 ).toLongLong(), requestId ); - KIMAP::Session *s = sessionSpy.at( 0 ).at( 1 ).value(); - - KIMAP::CapabilitiesJob *job = new KIMAP::CapabilitiesJob( s ); - job->start(); - QTest::qWait( 100 ); - QCOMPARE( lostSpy.count(), 1 ); - QCOMPARE( lostSpy.at( 0 ).at( 0 ).value(), s ); - - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } - - void shouldNotifyOnDisconnect_data() - { - QTest::addColumn< QList >( "scenario" ); - QTest::addColumn( "termination" ); - - QList scenario; - - scenario.clear(); - scenario << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in" - << "C: A000002 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" - << "S: A000002 OK Completed" - << "C: A000003 LOGOUT"; - - QTest::newRow( "logout session" ) << scenario << (int)SessionPool::LogoutSession; - - scenario.clear(); - scenario << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in" - << "C: A000002 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" - << "S: A000002 OK Completed"; - - QTest::newRow( "close session" ) << scenario << (int)SessionPool::CloseSession; - } - - void shouldNotifyOnDisconnect() - { - QFETCH( QList, scenario ); - QFETCH( int, termination ); - - FakeServer server; - server.addScenario( scenario ); - - server.startAndWait(); - - ImapAccount *account = createDefaultAccount(); - DummyPasswordRequester *requester = createDefaultRequester(); - - SessionPool pool( 1 ); - pool.setPasswordRequester( requester ); - - QSignalSpy disconnectSpy( &pool, SIGNAL(disconnectDone()) ); - - - // Initial connect should trigger only a password request and a connect - QVERIFY( pool.connect( account ) ); - QTest::qWait( 100 ); - - QCOMPARE( disconnectSpy.count(), 0 ); - pool.disconnect( (SessionPool::SessionTermination) termination ); - QTest::qWait( 100 ); - QCOMPARE( disconnectSpy.count(), 1 ); - - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } - - void shouldCleanupOnClosingDuringLogin_data() - { - QTest::addColumn< QList >( "scenario" ); - - { - QList scenario; - scenario << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\""; - - QTest::newRow( "during login" ) << scenario; - } - { - QList scenario; - scenario << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in" - << "C: A000002 CAPABILITY"; - - QTest::newRow( "during capability" ) << scenario; - } - { - QList scenario; - scenario << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in" - << "C: A000002 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 NAMESPACE UIDPLUS IDLE" - << "S: A000002 OK Completed" - << "C: A000003 NAMESPACE"; - QTest::newRow( "during namespace" ) << scenario; - } - } - - void shouldCleanupOnClosingDuringLogin() - { - QFETCH( QList, scenario ); - - FakeServer server; - server.addScenario(scenario); - - server.startAndWait(); - - ImapAccount *account = createDefaultAccount(); - DummyPasswordRequester *requester = createDefaultRequester(); - - SessionPool pool( 1 ); - pool.setPasswordRequester( requester ); - - QSignalSpy connectSpy( &pool, SIGNAL(connectDone(int,QString)) ); - QSignalSpy sessionSpy( &pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString)) ); - QSignalSpy lostSpy( &pool, SIGNAL(connectionLost(KIMAP::Session*)) ); - - // Initial connect should trigger only a password request and a connect - QVERIFY( pool.connect( account ) ); - QTest::qWait( 100 ); - QCOMPARE( connectSpy.count(), 0 ); // Login not done yet - QWeakPointer session = qFindChild( &pool ); - QVERIFY( session.data() ); - QCOMPARE( sessionSpy.count(), 0 ); - - pool.disconnect( SessionPool::CloseSession ); - - QTest::qWait( 100 ); - QCOMPARE( connectSpy.count(), 1 ); // We're informed that connect failed - QCOMPARE( connectSpy.at( 0 ).at( 0 ).toInt(), int(SessionPool::CancelledError) ); - QCOMPARE( lostSpy.count(), 0 ); // We're not supposed to know the session pointer, so no connectionLost emitted - - // Make the session->deleteLater work, it can't happen in qWait (nested event loop) - QCoreApplication::sendPostedEvents( 0, QEvent::DeferredDelete); - - QVERIFY( session.isNull() ); - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } - - void shouldHonorCancelRequest() - { - FakeServer server; - server.addScenario( QList() - << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in" - << "C: A000002 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" - << "S: A000002 OK Completed" - << "C: A000003 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" - << "X" - ); - - server.startAndWait(); - - ImapAccount *account = createDefaultAccount(); - DummyPasswordRequester *requester = createDefaultRequester(); - - SessionPool pool( 1 ); - pool.setPasswordRequester( requester ); - - QSignalSpy connectSpy( &pool, SIGNAL(connectDone(int,QString)) ); - QSignalSpy sessionSpy( &pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString)) ); - QSignalSpy lostSpy( &pool, SIGNAL(connectionLost(KIMAP::Session*)) ); - - // Initial connect should trigger only a password request and a connect - QVERIFY( pool.connect( account ) ); - QTest::qWait( 100 ); - QCOMPARE( connectSpy.count(), 1 ); - QCOMPARE( sessionSpy.count(), 0 ); - - qint64 requestId = pool.requestSession(); - - // Cancel the request - pool.cancelSessionRequest( requestId ); - - // The request should not be processed anymore - QTest::qWait( 100 ); - QCOMPARE( sessionSpy.count(), 0 ); - } - - void shouldBeDisconnectedOnAllSessionLost() - { - FakeServer server; - server.addScenario( QList() - << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in" - << "C: A000002 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 IDLE" - << "S: A000002 OK Completed" - << "C: A000003 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" - << "X" - ); - - server.addScenario( QList() - << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in" - << "C: A000002 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" - << "X" - ); - - server.startAndWait(); - - ImapAccount *account = createDefaultAccount(); - DummyPasswordRequester *requester = createDefaultRequester(); - - SessionPool pool( 2 ); - pool.setPasswordRequester( requester ); - - QSignalSpy sessionSpy( &pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString)) ); - - // Initial connect should trigger only a password request and a connect - QVERIFY( pool.connect( account ) ); - QTest::qWait( 100 ); - - // We should be connected now - QVERIFY( pool.isConnected() ); - - // Ask for a session - pool.requestSession(); - QTest::qWait( 100 ); - QCOMPARE( sessionSpy.count(), 1 ); - QVERIFY( sessionSpy.at( 0 ).at( 1 ).value() != 0 ); - - // Still connected obviously - QVERIFY( pool.isConnected() ); - - // Ask for a second session - pool.requestSession(); - QTest::qWait( 100 ); - QCOMPARE( sessionSpy.count(), 2 ); - QVERIFY( sessionSpy.at( 1 ).at( 1 ).value() != 0 ); - - // Still connected of course - QVERIFY( pool.isConnected() ); - - KIMAP::Session *session1 = sessionSpy.at( 0 ).at( 1 ).value(); - KIMAP::Session *session2 = sessionSpy.at( 1 ).at( 1 ).value(); - - // Prepare for session disconnects - QSignalSpy lostSpy( &pool, SIGNAL(connectionLost(KIMAP::Session*)) ); - - // Make the first session drop - KIMAP::CapabilitiesJob *job = new KIMAP::CapabilitiesJob( session1 ); - job->start(); - QTest::qWait( 100 ); - QCOMPARE( lostSpy.count(), 1 ); - QCOMPARE( lostSpy.at( 0 ).at( 0 ).value(), session1 ); - - // We're still connected (one session being alive) - QVERIFY( pool.isConnected() ); - - // Make the second session drop - job = new KIMAP::CapabilitiesJob( session2 ); - job->start(); - QTest::qWait( 100 ); - QCOMPARE( lostSpy.count(), 2 ); - QCOMPARE( lostSpy.at( 1 ).at( 0 ).value(), session2 ); - - // We're not connected anymore! All sessions dropped! - QVERIFY( !pool.isConnected() ); - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } - - void shouldHandleDisconnectDuringPasswordRequest() - { - ImapAccount *account = createDefaultAccount(); - - // This requester will delay the second reply by a second - DummyPasswordRequester *requester = createDefaultRequester(); - requester->setDelays( QList() << 20 << 1000 ); - QSignalSpy requesterSpy( requester, SIGNAL(done(int,QString)) ); - - FakeServer server; - - server.addScenario( QList() - << FakeServer::greeting() - << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" - << "S: A000001 OK User Logged in" - << "C: A000002 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 IDLE" - << "S: A000002 OK Completed" - << "C: A000003 CAPABILITY" - << "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE" - << "X" - ); - - server.startAndWait(); - - // The connect should work nicely - SessionPool pool( 2 ); - - QVERIFY( !pool.isConnected() ); - - QSignalSpy poolSpy( &pool, SIGNAL(connectDone(int,QString)) ); - QSignalSpy sessionSpy( &pool, SIGNAL(sessionRequestDone(qint64,KIMAP::Session*,int,QString)) ); - QSignalSpy lostSpy( &pool, SIGNAL(connectionLost(KIMAP::Session*)) ); - - pool.setPasswordRequester( requester ); - QVERIFY( pool.connect( account ) ); - - QTest::qWait( 100 ); - QCOMPARE( requesterSpy.count(), 1 ); - - QCOMPARE( poolSpy.count(), 1 ); - QCOMPARE( poolSpy.at( 0 ).at( 0 ).toInt(), (int)SessionPool::NoError ); - QVERIFY( pool.isConnected() ); - - // Ask for the session we just created - pool.requestSession(); - QTest::qWait( 100 ); - QCOMPARE( sessionSpy.count(), 1 ); - QVERIFY( sessionSpy.at( 0 ).at( 1 ).value() != 0 ); - - KIMAP::Session *session = sessionSpy.at( 0 ).at( 1 ).value(); - - // Ask for the second session, the password requested will never reply - // and we'll get a disconnect in parallel (by triggering the capability - // job on the first session - // Done this way to simulate a disconnect during a password request - - // Ask for the extra session, and make sure the call is placed by waiting - // just a bit (but not too long so that the requester didn't reply yet, - // we set the reply timeout to 1000 earlier in this test) - pool.requestSession(); - QTest::qWait( 100 ); - QCOMPARE( requesterSpy.count(), 1 ); // Requester didn't reply yet - QCOMPARE( sessionSpy.count(), 1 ); - - // Make the first (and only) session drop while we wait for the requester - // to reply - KIMAP::CapabilitiesJob *job = new KIMAP::CapabilitiesJob( session ); - job->start(); - QTest::qWait( 100 ); - QCOMPARE( lostSpy.count(), 1 ); - QCOMPARE( lostSpy.at( 0 ).at( 0 ).value(), session ); - - // The requester didn't reply yet - QCOMPARE( requesterSpy.count(), 1 ); - QCOMPARE( sessionSpy.count(), 1 ); - - // Now wait the remaining time to get the session creation to fail - QTest::qWait( 1000 ); - QCOMPARE( requesterSpy.count(), 2 ); - QCOMPARE( sessionSpy.count(), 2 ); - QCOMPARE( sessionSpy.at( 1 ).at( 2 ).toInt(), (int)SessionPool::LoginFailError ); - - QVERIFY( server.isAllScenarioDone() ); - - server.quit(); - } - - void shouldNotifyFailureToConnect() - { - // This tests what happens when we can't connect to the server, e.g. due to being offline. - // In this test we just use 0.0.0.0 as an invalid server IP, instead. - ImapAccount *account = createDefaultAccount(); - account->setServer( "0.0.0.0" ); // so that the connexion fails - DummyPasswordRequester *requester = createDefaultRequester(); - QList requests; - QList results; - // I don't want to see "WrongPasswordRequest". A password popup is annoying when we're offline or the server is down. - requests << DummyPasswordRequester::StandardRequest; - results << DummyPasswordRequester::PasswordRetrieved; - requester->setScenario( requests, results ); - - QSignalSpy requesterSpy( requester, SIGNAL(done(int,QString)) ); - SessionPool pool( 2 ); - QSignalSpy connectDoneSpy( &pool, SIGNAL(connectDone(int,QString)) ); - QSignalSpy lostSpy( &pool, SIGNAL(connectionLost(KIMAP::Session*)) ); - QVERIFY( !pool.isConnected() ); - pool.setPasswordRequester( requester ); - pool.connect( account ); - QVERIFY( !pool.isConnected() ); - QTRY_COMPARE( requesterSpy.count(), requests.count() ); - QTRY_COMPARE( connectDoneSpy.count(), 1 ); - QCOMPARE( connectDoneSpy.at( 0 ).at( 0 ).toInt(), (int)SessionPool::CouldNotConnectError ); - QCOMPARE( lostSpy.count(), 0 ); // don't want this, it makes the resource reconnect immediately (and fail, and reconnect, and so on...) - } - -}; - -QTEST_KDEMAIN_CORE( TestSessionPool ) - -#include "testsessionpool.moc" diff -Nru kdepim-runtime-4.14.6/resources/imap/tests/testsubscriptiondialog.cpp kdepim-runtime-15.08.0/resources/imap/tests/testsubscriptiondialog.cpp --- kdepim-runtime-4.14.6/resources/imap/tests/testsubscriptiondialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tests/testsubscriptiondialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,41 +19,41 @@ #include #include -#include +#include #include "imapaccount.h" #include "subscriptiondialog.h" -int main( int argc, char **argv ) +int main(int argc, char **argv) { - QApplication app( argc, argv ); + QApplication app(argc, argv); - if ( app.arguments().size() < 5 ) { - qWarning( "Not enough parameters, expecting: " ); - return 1; - } + if (app.arguments().size() < 5) { + qWarning("Not enough parameters, expecting: "); + return 1; + } - QString server = app.arguments().at( 1 ); - int port = app.arguments().at( 2 ).toInt(); - QString user = app.arguments().at( 3 ); - QString password = app.arguments().at( 4 ); + QString server = app.arguments().at(1); + int port = app.arguments().at(2).toInt(); + QString user = app.arguments().at(3); + QString password = app.arguments().at(4); - qDebug() << "Querying:" << server << port << user << password; - qDebug(); + qDebug() << "Querying:" << server << port << user << password; + qDebug(); - ImapAccount account; - account.setServer( server ); - account.setPort( port ); - account.setUserName( user ); + ImapAccount account; + account.setServer(server); + account.setPort(port); + account.setUserName(user); - SubscriptionDialog *dialog = new SubscriptionDialog(); - dialog->connectAccount( account, password ); + SubscriptionDialog *dialog = new SubscriptionDialog(); + dialog->connectAccount(account, password); - dialog->show(); + dialog->show(); - int retcode = app.exec(); + int retcode = app.exec(); - qDebug() << "Subscription changed?" << dialog->isSubscriptionChanged(); + qDebug() << "Subscription changed?" << dialog->isSubscriptionChanged(); - return retcode; + return retcode; } diff -Nru kdepim-runtime-4.14.6/resources/imap/timestampattribute.cpp kdepim-runtime-15.08.0/resources/imap/timestampattribute.cpp --- kdepim-runtime-4.14.6/resources/imap/timestampattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/timestampattribute.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -/* - Copyright (c) 2010 Klarälvdalens Datakonsult AB, - a KDAB Group company - Author: Kevin Ottens - - 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 "timestampattribute.h" - -#include - -#include - -TimestampAttribute::TimestampAttribute( uint timestamp ) - : mTimestamp( timestamp ) -{ -} - -void TimestampAttribute::setTimestamp( uint timestamp ) -{ - mTimestamp = timestamp; -} - -uint TimestampAttribute::timestamp() const -{ - return mTimestamp; -} - -QByteArray TimestampAttribute::type() const -{ - static const QByteArray sType( "timestamp" ); - return sType; -} - -Akonadi::Attribute *TimestampAttribute::clone() const -{ - return new TimestampAttribute( mTimestamp ); -} - -QByteArray TimestampAttribute::serialized() const -{ - return QByteArray::number( mTimestamp ); -} - -void TimestampAttribute::deserialize( const QByteArray &data ) -{ - mTimestamp = data.toInt(); -} diff -Nru kdepim-runtime-4.14.6/resources/imap/timestampattribute.h kdepim-runtime-15.08.0/resources/imap/timestampattribute.h --- kdepim-runtime-4.14.6/resources/imap/timestampattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/timestampattribute.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - Copyright (c) 2010 Klarlvdalens Datakonsult AB, - a KDAB Group company - Author: Kevin Ottens - - 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 TIMESTAMPATTRIBUTE_H -#define TIMESTAMPATTRIBUTE_H - -#include - -class TimestampAttribute : public Akonadi::Attribute -{ -public: - explicit TimestampAttribute( uint timestamp = 0 ); - void setTimestamp( uint timestamp ); - uint timestamp() const; - virtual QByteArray type() const; - virtual Attribute *clone() const; - virtual QByteArray serialized() const; - virtual void deserialize( const QByteArray &data ); - -private: - uint mTimestamp; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/imap/tracer.cpp kdepim-runtime-15.08.0/resources/imap/tracer.cpp --- kdepim-runtime-4.14.6/resources/imap/tracer.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tracer.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,63 @@ +#include "tracer.h" +#include "imapresource_debug.h" + +#include +#include +#include +#include +#include + +class DebugStream: public QIODevice +{ +public: + QString m_location; + DebugStream() + : QIODevice() + { + open(WriteOnly); + } + virtual ~DebugStream() {}; + + bool isSequential() const + { + return true; + } + qint64 readData(char *, qint64) + { + return 0; /* eof */ + } + qint64 readLineData(char *, qint64) + { + return 0; /* eof */ + } + qint64 writeData(const char *data, qint64 len) + { + const QByteArray buf = QByteArray::fromRawData(data, len); + if (!qgetenv("IMAP_TRACE").isEmpty()) { + // qt_message_output(QtDebugMsg, buf.trimmed().constData()); + std::cout << buf.trimmed().constData() << std::endl; + } + return len; + } +private: + Q_DISABLE_COPY(DebugStream) +}; + +QDebug debugStream(int line, const char *file, const char *function) +{ + static DebugStream stream; + QDebug debug(&stream); + + static QByteArray programName; + if (programName.isEmpty()) { + if (QCoreApplication::instance()) { + programName = QCoreApplication::instance()->applicationName().toLocal8Bit(); + } else { + programName = ""; + } + } + + debug << QString("Trace:%1(%2) %3:").arg(QString::fromLatin1(programName)).arg(unsigned(getpid())).arg(function) /* << file << ":" << line */; + + return debug; +} diff -Nru kdepim-runtime-4.14.6/resources/imap/tracer.h kdepim-runtime-15.08.0/resources/imap/tracer.h --- kdepim-runtime-4.14.6/resources/imap/tracer.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/tracer.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,7 @@ +#pragma once + +#include "imapresource_debug.h" + +QDebug debugStream(int line, const char *file, const char *function); + +#define Trace() debugStream(__LINE__, __FILE__, Q_FUNC_INFO) diff -Nru kdepim-runtime-4.14.6/resources/imap/uidnextattribute.cpp kdepim-runtime-15.08.0/resources/imap/uidnextattribute.cpp --- kdepim-runtime-4.14.6/resources/imap/uidnextattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/uidnextattribute.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,14 +21,14 @@ #include -#include +#include -UidNextAttribute::UidNextAttribute( int uidnext ) - : mUidNext( uidnext ) +UidNextAttribute::UidNextAttribute(int uidnext) + : mUidNext(uidnext) { } -void UidNextAttribute::setUidNext( int uidnext ) +void UidNextAttribute::setUidNext(int uidnext) { mUidNext = uidnext; } @@ -40,21 +40,21 @@ QByteArray UidNextAttribute::type() const { - static const QByteArray sType( "uidnext" ); + static const QByteArray sType("uidnext"); return sType; } -Akonadi::Attribute* UidNextAttribute::clone() const +Akonadi::Attribute *UidNextAttribute::clone() const { - return new UidNextAttribute( mUidNext ); + return new UidNextAttribute(mUidNext); } QByteArray UidNextAttribute::serialized() const { - return QByteArray::number( mUidNext ); + return QByteArray::number(mUidNext); } -void UidNextAttribute::deserialize( const QByteArray &data ) +void UidNextAttribute::deserialize(const QByteArray &data) { mUidNext = data.toInt(); } diff -Nru kdepim-runtime-4.14.6/resources/imap/uidnextattribute.h kdepim-runtime-15.08.0/resources/imap/uidnextattribute.h --- kdepim-runtime-4.14.6/resources/imap/uidnextattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/uidnextattribute.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,18 +20,18 @@ #ifndef UIDNEXTATTRIBUTE_H #define UIDNEXTATTRIBUTE_H -#include +#include class UidNextAttribute : public Akonadi::Attribute { public: - explicit UidNextAttribute( int uidnext = 0 ); - void setUidNext( int uidnext ); + explicit UidNextAttribute(int uidnext = 0); + void setUidNext(int uidnext); int uidNext() const; - virtual QByteArray type() const; - virtual Attribute* clone() const; - virtual QByteArray serialized() const; - virtual void deserialize( const QByteArray &data ); + QByteArray type() const Q_DECL_OVERRIDE; + Attribute *clone() const Q_DECL_OVERRIDE; + QByteArray serialized() const Q_DECL_OVERRIDE; + void deserialize(const QByteArray &data) Q_DECL_OVERRIDE; private: int mUidNext; diff -Nru kdepim-runtime-4.14.6/resources/imap/uidvalidityattribute.cpp kdepim-runtime-15.08.0/resources/imap/uidvalidityattribute.cpp --- kdepim-runtime-4.14.6/resources/imap/uidvalidityattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/uidvalidityattribute.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,14 +21,14 @@ #include -#include +#include -UidValidityAttribute::UidValidityAttribute( int uidvalidity ) - : mUidValidity( uidvalidity ) +UidValidityAttribute::UidValidityAttribute(int uidvalidity) + : mUidValidity(uidvalidity) { } -void UidValidityAttribute::setUidValidity( int uidvalidity ) +void UidValidityAttribute::setUidValidity(int uidvalidity) { mUidValidity = uidvalidity; } @@ -40,21 +40,21 @@ QByteArray UidValidityAttribute::type() const { - static const QByteArray sType( "uidvalidity" ); + static const QByteArray sType("uidvalidity"); return sType; } -Akonadi::Attribute* UidValidityAttribute::clone() const +Akonadi::Attribute *UidValidityAttribute::clone() const { - return new UidValidityAttribute( mUidValidity ); + return new UidValidityAttribute(mUidValidity); } QByteArray UidValidityAttribute::serialized() const { - return QByteArray::number( mUidValidity ); + return QByteArray::number(mUidValidity); } -void UidValidityAttribute::deserialize( const QByteArray &data ) +void UidValidityAttribute::deserialize(const QByteArray &data) { mUidValidity = data.toInt(); } diff -Nru kdepim-runtime-4.14.6/resources/imap/uidvalidityattribute.h kdepim-runtime-15.08.0/resources/imap/uidvalidityattribute.h --- kdepim-runtime-4.14.6/resources/imap/uidvalidityattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/uidvalidityattribute.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,18 +20,18 @@ #ifndef UIDVALIDITYATTRIBUTE_H #define UIDVALIDITYATTRIBUTE_H -#include +#include class UidValidityAttribute : public Akonadi::Attribute { public: - explicit UidValidityAttribute( int uidvalidity = 0 ); - void setUidValidity( int uidvalidity ); + explicit UidValidityAttribute(int uidvalidity = 0); + void setUidValidity(int uidvalidity); int uidValidity() const; - virtual QByteArray type() const; - virtual Attribute* clone() const; - virtual QByteArray serialized() const; - virtual void deserialize( const QByteArray &data ); + QByteArray type() const Q_DECL_OVERRIDE; + Attribute *clone() const Q_DECL_OVERRIDE; + QByteArray serialized() const Q_DECL_OVERRIDE; + void deserialize(const QByteArray &data) Q_DECL_OVERRIDE; private: int mUidValidity; diff -Nru kdepim-runtime-4.14.6/resources/imap/wizard/CMakeLists.txt kdepim-runtime-15.08.0/resources/imap/wizard/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/imap/wizard/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/imap/wizard/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,2 +1,2 @@ -install ( FILES imapwizard.desktop imapwizard.es imapwizard.ui DESTINATION ${DATA_INSTALL_DIR}/akonadi/accountwizard/imap ) +install ( FILES imapwizard.desktop imapwizard.es imapwizard.ui DESTINATION ${KDE_INSTALL_DATADIR}/akonadi/accountwizard/imap ) diff -Nru kdepim-runtime-4.14.6/resources/kabc/CMakeLists.txt kdepim-runtime-15.08.0/resources/kabc/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/kabc/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kabc/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -add_definitions( - -DKRESOURCES_DEPRECATED= - -DKABC_DEPRECATED= - -DKCAL_DEPRECATED= -) -# This one won't be needed when CMake 2.8.13 is depended on. -add_definitions( - -DKRESOURCES_DEPRECATED_EXPORT=KRESOURCES_EXPORT - -DKABC_DEPRECATED_EXPORT=KABC_EXPORT - -DKCAL_DEPRECATED_EXPORT=KCAL_EXPORT -) - -include_directories( - ${kdepim-runtime_SOURCE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} -) - -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - - -########### next target ############### - -set( kabcresource_SRCS - kabcresource.cpp - kresourceassistant.cpp -) - -install( FILES kabcresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) - - -kde4_add_executable(akonadi_kabc_resource ${kabcresource_SRCS}) - -if (Q_WS_MAC) - set_target_properties(akonadi_kabc_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) - set_target_properties(akonadi_kabc_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.KABC") - set_target_properties(akonadi_kabc_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi KABC Resource") -endif () - -target_link_libraries(akonadi_kabc_resource ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${KDE4_KDECORE_LIBS} ${KDEPIMLIBS_KABC_LIBS} ${KDE4_KIO_LIBS}) - -install(TARGETS akonadi_kabc_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/kabc/kabcresource.cpp kdepim-runtime-15.08.0/resources/kabc/kabcresource.cpp --- kdepim-runtime-4.14.6/resources/kabc/kabcresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kabc/kabcresource.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,896 +0,0 @@ -/* - Copyright (c) 2008 Kevin Krammer - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "kabcresource.h" - -#include "kresourceassistant.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -typedef QMap UidToResourceMap; - -using namespace Akonadi; - -using KABC::Resource; - -class KABCResource::ErrorHandler : public KABC::ErrorHandler -{ - public: - explicit ErrorHandler( KABCResource* parent ) - : mParent( parent ) {} - - virtual void error( const QString &message ) { - mLastError = message; - emit mParent->error( message ); - } - - public: - KABCResource *mParent; - - QString mLastError; -}; - -// workaround to access protected method -class KABCResource::AddressBook : public KABC::AddressBook -{ - public: - AddressBook() {} - - KRES::Manager *getResourceManager() - { - return resourceManager(); - } -}; - -KABCResource::KABCResource( const QString &id ) - : ResourceBase( id ), - mAddressBook( new AddressBook() ), - mBaseResource( 0 ), - mFolderResource( 0 ), - mErrorHandler( new ErrorHandler( this ) ), - mFullItemRetrieve( false ), - mDelayedSaveTimer( new QTimer( this ) ), - mContactGroupMimeChecker( new MimeTypeChecker() ) -{ - KGlobal::locale()->insertCatalog( QLatin1String( "akonadi_kresourceassistant" ) ); - - mAddressBook->setErrorHandler( mErrorHandler ); - connect( this, SIGNAL(reloadConfiguration()), SLOT(reloadConfiguration()) ); - - connect( mAddressBook, SIGNAL(addressBookChanged(AddressBook*)), - this, SLOT(addressBookChanged()) ); - - connect( mDelayedSaveTimer, SIGNAL(timeout()), - this, SLOT(delayedSaveAddressBook()) ); - - changeRecorder()->itemFetchScope().fetchFullPayload(); - changeRecorder()->fetchCollection( true ); - - mDelayedSaveTimer->setSingleShot( true ); - - mContactGroupMimeChecker->addWantedMimeType( KABC::ContactGroup::mimeType() ); -} - -KABCResource::~KABCResource() -{ - delete mAddressBook; - delete mContactGroupMimeChecker; -} - -void KABCResource::configure( WId windowId ) -{ - KRES::Manager *manager = mAddressBook->getResourceManager(); - - if ( mBaseResource != 0 ) { - emit status( Running, - i18nc( "@info:status", "Changing address book plugin configuration" ) ); - QPointer dlg = new KRES::ConfigDialog( 0, QLatin1String( "contact" ), mBaseResource ); - if ( windowId ) { - KWindowSystem::setMainWindow( dlg, windowId ); - } - dlg->setWindowIcon( KIcon( "text-directory" ) ); - int stat = dlg->exec(); - delete dlg; - - if ( stat == QDialog::Accepted ) { - setName( mBaseResource->resourceName() ); - manager->writeConfig( KGlobal::config().data() ); - emit configurationDialogAccepted(); - } else { - emit configurationDialogRejected(); - } - - emit status( Idle, QString() ); - // TODO: need to react on name changes, but do we need to react on data changes? - // as a workaround lets sync the collection tree - synchronizeCollectionTree(); - return; - } - - emit status( Running, - i18nc( "@info:status", "Acquiring address book plugin configuration" ) ); - QPointer kresAssistant = new KResourceAssistant( QLatin1String( "Contact" ) ); - KWindowSystem::setMainWindow( kresAssistant, windowId ); - - connect( kresAssistant, SIGNAL(error(QString)), - this, SIGNAL(error(QString)) ); - - int stat = kresAssistant->exec(); - if ( stat != QDialog::Accepted ) { - emit status( NotConfigured, i18nc( "@info:status", "No KDE address book plugin configured yet" ) ); - emit configurationDialogRejected(); - delete kresAssistant; - return; - } - - emit configurationDialogAccepted(); - KABC::Resource *resource = dynamic_cast( kresAssistant->resource() ); - Q_ASSERT( resource != 0 ); - - delete kresAssistant; - setResourcePointers( resource ); - - mBaseResource->setAddressBook( mAddressBook ); - - manager->writeConfig( KGlobal::config().data() ); - - mAddressBook->addResource( mBaseResource ); - - if ( !openConfiguration() ) { - const QString message = - i18nc( "@info:status", - "Initialization based on newly created configuration failed." ); - emit error( message ); - emit status( NotConfigured, message ); - return; - } - - if ( !mAddressBook->asyncLoad() ) { - const QString message = i18nc( "@info:status", "Loading of address book failed." ); - emit error( message ); - emit status( Broken, message ); - return; - } - - emit status( Running, i18nc( "@info:status", "Loading address book" ) ); -} - -void KABCResource::retrieveCollections() -{ - kDebug(); - if ( mBaseResource == 0 ) { - kError() << "No KABC resource"; - - const QString message = i18nc( "@info:status", "No KDE address book plugin configured yet" ); - emit error( message ); - - emit status( NotConfigured, message ); - return; - } - - Collection topLevelCollection; - topLevelCollection.setParentCollection( Collection::root() ); - topLevelCollection.setRemoteId( mBaseResource->identifier() ); - topLevelCollection.setName( mBaseResource->resourceName() ); - - EntityDisplayAttribute* attr = - topLevelCollection.attribute( Collection::AddIfMissing ); - attr->setDisplayName( mBaseResource->resourceName() ); - attr->setIconName( QLatin1String( "office-address-book" ) ); - - QStringList mimeTypes; - mimeTypes << KABC::Addressee::mimeType(); - - QStringList topLevelMimeTypes = mimeTypes; - topLevelMimeTypes << KABC::ContactGroup::mimeType(); - - if ( mFolderResource != 0 ) { - topLevelMimeTypes << Collection::mimeType(); - } - - Collection::Rights readOnlyRights; - - Collection::Rights readWriteRights; - readWriteRights |= Collection::CanCreateItem; - readWriteRights |= Collection::CanChangeItem; - readWriteRights |= Collection::CanDeleteItem; - topLevelCollection.setContentMimeTypes( topLevelMimeTypes ); - topLevelCollection.setRights( mBaseResource->readOnly() ? readOnlyRights : readWriteRights ); - - Collection::List list; - list << topLevelCollection; - - if ( mFolderResource != 0 ) { - const QStringList subResources = mFolderResource->subresources(); - kDebug() << "subResources" << subResources; - foreach ( const QString &subResource, subResources ) { - Collection childCollection; - childCollection.setParentCollection( topLevelCollection ); - childCollection.setRemoteId( subResource ); - childCollection.setName( mFolderResource->subresourceLabel( subResource ) ); - childCollection.setContentMimeTypes( mimeTypes ); - bool readOnly = !mFolderResource->subresourceWritable( subResource ); - childCollection.setRights( readOnly ? readOnlyRights : readWriteRights ); - - attr = childCollection.attribute( Collection::AddIfMissing ); - attr->setDisplayName( childCollection.name() ); - attr->setIconName( QLatin1String( "office-address-book" ) ); - - list << childCollection; - } - } - - collectionsRetrieved( list ); -} - -void KABCResource::retrieveItems( const Akonadi::Collection &col ) -{ - kDebug() << "full items:" << mFullItemRetrieve; - const UidToResourceMap uidToResourceMap = - mFolderResource != 0 ? mFolderResource->uidToResourceMap() : UidToResourceMap(); - - Item::List items; - - // check for each addressee whether there is a sub resource mapping. - // if there is a mapping, skip it if the mapping does not equal the collection's - // remoteId. - // if there is none, skip it if the collection is not the top level collection - KABC::AddressBook::const_iterator addrIt = mAddressBook->constBegin(); - KABC::AddressBook::const_iterator addrEndIt = mAddressBook->constEnd(); - for ( ; addrIt != addrEndIt; ++addrIt ) { - UidToResourceMap::const_iterator findIt = uidToResourceMap.find( addrIt->uid() ); - if ( findIt != uidToResourceMap.end() ) { - if ( findIt.value() != col.remoteId() ) - continue; - } else { - if ( col.parentCollection() != Collection::root() ) - continue; - } - - Item item; - item.setRemoteId( addrIt->uid() ); - item.setMimeType( KABC::Addressee::mimeType() ); - if ( mFullItemRetrieve ) item.setPayload( *addrIt ); - items.append( item ); - } - - QList distLists = mBaseResource->allDistributionLists(); - foreach ( const KABC::DistributionList *list, distLists ) { - Item item; - item.setRemoteId( list->identifier() ); - item.setMimeType( KABC::ContactGroup::mimeType() ); - - if ( mFullItemRetrieve ) { - item.setPayload( contactGroupFromDistList( list ) ); - } - - items.append( item ); - } - - mFullItemRetrieve = false; - - itemsRetrieved( items ); -} - -bool KABCResource::retrieveItem( const Akonadi::Item &item, const QSet &parts ) -{ - kDebug() << "item id=" << item.id() << ", remoteId=" << item.remoteId() - << "mimeType=" << item.mimeType() << "part=" << parts; - Q_UNUSED( parts ); - const QString rid = item.remoteId(); - - if ( mContactGroupMimeChecker->isWantedItem( item ) ) { - KABC::DistributionList *list = - mAddressBook->findDistributionListByIdentifier( rid ); - if ( list == 0 ) { - kError() << "No distributionlist with identifier" << rid; - emit error( i18nc( "@info:status", - "Request for data of a specific distribution list failed " - "because there is no such list" ) ); - return false; - } - - Item i( item ); - i.setPayload( contactGroupFromDistList( list ) ); - itemRetrieved( i ); - } else { - KABC::Addressee addressee = mAddressBook->findByUid( item.remoteId() ); - if ( addressee.isEmpty() ) { - kError() << "No addressee with uid" << rid; - emit error( i18nc( "@info:status", - "Request for data of a specific address book entry failed " - "because there is no such entry" ) ); - return false; - } - - Item i( item ); - i.setPayload( addressee ); - itemRetrieved( i ); - } - return true; -} - -void KABCResource::aboutToQuit() -{ - saveAddressBook(); -} - -void KABCResource::doSetOnline( bool online ) -{ - kDebug() << "online" << online << "resource" << (void*) mBaseResource; - - if ( online ) { - reloadConfiguration(); - } else { - closeConfiguration(); - } - - ResourceBase::doSetOnline( online ); -} - -void KABCResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection& col ) -{ - kDebug() << "item id=" << item.id() << ", remoteId=" << item.remoteId() - << "mimeType=" << item.mimeType(); - // KABC::Resource only has one collection and - // KABC::ResourceABC does not have API for setting the storage sub resource - Q_UNUSED( col ); - - if ( mBaseResource == 0 ) { - kError() << "Resource not fully operational yet"; - emit status( NotConfigured, i18nc( "@info:status", "No KDE address book plugin configured yet" ) ); - return; - } - - kDebug() << "item.hasPayload() " << item.hasPayload(); - kDebug() << "item.hasPayload() " << item.hasPayload(); - if ( item.hasPayload() ) { - KABC::Addressee addressee = item.payload(); - - if ( addressee.uid().isEmpty() ) - addressee.setUid( KRandom::randomString( 10 ) ); - - addressee.setResource( mBaseResource ); - mAddressBook->insertAddressee( addressee ); - - // TODO: proper error reporting - if ( scheduleSaveAddressBook() ) { - Item i( item ); - i.setRemoteId( addressee.uid() ); - i.setPayload( addressee ); - - changeCommitted( i ); - return; - } - } else if ( item.hasPayload() ) { - KABC::ContactGroup contactGroup = item.payload(); - - if ( contactGroup.id().isEmpty() ) - contactGroup.setId( KRandom::randomString( 10 ) ); - - // also inserts list into resource - distListFromContactGroup( contactGroup ); - - // TODO: proper error reporting - if ( scheduleSaveAddressBook() ) { - Item i( item ); - i.setRemoteId( contactGroup.id() ); - i.setPayload( contactGroup ); - - changeCommitted( i ); - return; - } - } - - changeProcessed(); -} - -void KABCResource::itemChanged( const Akonadi::Item &item, const QSet& parts ) -{ - kDebug() << "item id=" << item.id() << ", remoteId=" << item.remoteId() - << "mimeType=" << item.mimeType(); - // we store the whole addressee/contactgroup anyway - Q_UNUSED( parts ); - - if ( mBaseResource == 0 ) { - kError() << "Resource not fully operational yet"; - emit status( NotConfigured, i18nc( "@info:status", "No KDE address book plugin configured yet" ) ); - return; - } - - kDebug() << "item.hasPayload() " << item.hasPayload(); - kDebug() << "item.hasPayload() " << item.hasPayload(); - if ( item.hasPayload() ) { - KABC::Addressee addressee = item.payload(); - Q_ASSERT( !addressee.uid().isEmpty() ); - - addressee.setResource( mBaseResource ); - mAddressBook->insertAddressee( addressee ); - - // TODO: proper error reporting - if ( scheduleSaveAddressBook() ) { - changeCommitted( item ); - return; - } - } else if ( item.hasPayload() ) { - KABC::ContactGroup contactGroup = item.payload(); - Q_ASSERT( !contactGroup.id().isEmpty() ); - - KABC::DistributionList *list = - mAddressBook->findDistributionListByIdentifier( contactGroup.id() ); - if ( list == 0 ) { - // TODO: rather report an error? - - // also inserts list into resource - distListFromContactGroup( contactGroup ); - } else { - // TODO: might be better to update the already existing instance - mBaseResource->removeDistributionList( list ); - delete list; - - // also inserts list into resource - distListFromContactGroup( contactGroup ); - } - - // TODO: proper error reporting - if ( scheduleSaveAddressBook() ) { - changeCommitted( item ); - return; - } - } - - changeProcessed(); -} - -void KABCResource::itemRemoved( const Akonadi::Item &item ) -{ - kDebug() << "item id=" << item.id() << ", remoteId=" << item.remoteId() - << "mimeType=" << item.mimeType(); - - if ( mBaseResource == 0 ) { - kError() << "Resource not fully operational yet"; - emit status( NotConfigured, i18nc( "@info:status", "No KDE address book plugin configured yet" ) ); - return; - } - - if ( mContactGroupMimeChecker->isWantedItem( item ) ) { - KABC::DistributionList *list = - mAddressBook->findDistributionListByIdentifier( item.remoteId() ); - if ( list != 0 ) { - mAddressBook->removeDistributionList( list ); - delete list; - - // TODO: proper error reporting - if ( scheduleSaveAddressBook() ) { - changeCommitted( item ); - return; - } - } - } else { - KABC::Addressee addressee = mAddressBook->findByUid( item.remoteId() ); - if ( !addressee.isEmpty() ) { - mAddressBook->removeAddressee( addressee ); - // TODO: proper error reporting - if ( scheduleSaveAddressBook() ) { - changeCommitted( item ); - return; - } - } - } - changeProcessed(); -} - -void KABCResource::collectionChanged( const Akonadi::Collection &collection ) -{ - kDebug() << "collection.name=" << collection.name() - << ", resource name=" << mBaseResource->resourceName(); - - if ( mBaseResource == 0 ) { - kError() << "Resource not fully operational yet"; - emit status( NotConfigured, i18nc( "@info:status", "No KDE address book plugin configured yet" ) ); - return; - } - - if ( collection.parentCollection() == Collection::root() ) { - const QString newName = collection.displayName(); - - if ( newName != mBaseResource->resourceName() ) { - mBaseResource->setResourceName( newName ); - setName( newName ); - mAddressBook->getResourceManager()->writeConfig( KGlobal::config().data() ); - } - } else - kWarning() << "Got collection change for a sub resource which we cannot change"; - - changeCommitted( collection ); -} - -void KABCResource::setResourcePointers( KABC::Resource *resource ) -{ - mBaseResource = resource; - mFolderResource = dynamic_cast( resource ); - - if ( mBaseResource != 0 ) - mBaseResource->setAddressBook( mAddressBook ); -} - -bool KABCResource::openConfiguration() -{ - if ( mBaseResource != 0 ) { - if ( !mBaseResource->isOpen() ) { - if ( !mBaseResource->open() ) { - kError() << "Opening resource" << mBaseResource->identifier() << "failed"; - return false; - } - } - - connect( mBaseResource, SIGNAL(loadingError(Resource*,QString)), - this, SLOT(loadingError(Resource*,QString)) ); - - connect( mBaseResource, SIGNAL(loadingFinished(Resource*)), - this, SLOT(initialLoadingFinished(Resource*)) ); - - if ( mFolderResource != 0 ) { - connect( mFolderResource, - SIGNAL(signalSubresourceAdded(KABC::ResourceABC*,QString,QString)), - this, SLOT(subResourceAdded(KABC::ResourceABC*,QString,QString)) ); - - connect( mFolderResource, - SIGNAL(signalSubresourceRemoved(KABC::ResourceABC*,QString,QString)), - this, SLOT(subResourceRemoved(KABC::ResourceABC*,QString,QString)) ); - - connect( mFolderResource, - SIGNAL(signalSubresourceChanged(KABC::ResourceABC*,QString,QString)), - this, SLOT(subResourceChanged(KABC::ResourceABC*,QString,QString)) ); - } - - - // do not react on addressbook changes until we have finished its initial loading - mAddressBook->blockSignals( true ); - - setName( mBaseResource->resourceName() ); - } - - return true; -} - -void KABCResource::closeConfiguration() -{ - mDelayedSaveTimer->stop(); - - // do not react on addressbook changes until we have finished its initial loading - mAddressBook->blockSignals( true ); - - if ( mBaseResource != 0 ) { - disconnect( mBaseResource, SIGNAL(loadingError(Resource*,QString)), - this, SLOT(loadingError(Resource*,QString)) ); - - disconnect( mBaseResource, SIGNAL(loadingFinished(Resource*)), - this, SLOT(initialLoadingFinished(Resource*)) ); - - if ( mFolderResource != 0 ) { - disconnect( mFolderResource, - SIGNAL(signalSubresourceAdded(KABC::ResourceABC*,QString,QString)), - this, SLOT(subResourceAdded(KABC::ResourceABC*,QString,QString)) ); - - disconnect( mFolderResource, - SIGNAL(signalSubresourceRemoved(KABC::ResourceABC*,QString,QString)), - this, SLOT(subResourceRemoved(KABC::ResourceABC*,QString,QString)) ); - - disconnect( mFolderResource, - SIGNAL(signalSubresourceChanged(KABC::ResourceABC*,QString,QString)), - this, SLOT(subResourceChanged(KABC::ResourceABC*,QString,QString)) ); - } - - if ( mBaseResource->isOpen() ) - mBaseResource->close(); - } -} - -bool KABCResource::saveAddressBook() -{ - mDelayedSaveTimer->stop(); - - if ( !mBaseResource || mBaseResource->readOnly() ) - return false; - - mErrorHandler->mLastError.clear(); - - KABC::Ticket *ticket = mAddressBook->requestSaveTicket(); - if ( ticket == 0 ) { - kError() << "Could not get address book save ticket"; - emit error( i18nc( "@info:status", - "Request for saving the address book failed. " - "Probably locked by another application" ) ); - return false; - } - - if ( !mAddressBook->save( ticket ) ) { - kError() << "Saving failed: " << mErrorHandler->mLastError; - mAddressBook->releaseSaveTicket( ticket ); - return false; - } - - kDebug() << "Saving succeeded"; - return true; -} - -bool KABCResource::scheduleSaveAddressBook() -{ - if ( !mBaseResource || mBaseResource->readOnly() ) - return false; - - if ( !mDelayedSaveTimer->isActive() ) - mDelayedSaveTimer->start( 5000 ); - - return true; -} - -void KABCResource::loadingError( KABC::Resource *resource, const QString &message ) -{ - Q_UNUSED( resource ); - - kError() << "Loading error: " << message; - emit error( message ); - emit status( Broken, message ); -} - -void KABCResource::initialLoadingFinished( KABC::Resource *resource ) -{ - kDebug() << resource; - Q_ASSERT( mBaseResource != 0 ); - Q_ASSERT( resource == mBaseResource ); - - - disconnect( mBaseResource, SIGNAL(loadingFinished(Resource*)), - this, SLOT(initialLoadingFinished(Resource*)) ); - - emit status( Idle, QString() ); - - mAddressBook->blockSignals( false ); - - // Let Akonadi retrieve all items but only the base information, no payloads yet - mFullItemRetrieve = false; - synchronize(); -} - -void KABCResource::addressBookChanged() -{ - kDebug(); - if ( mDelayedSaveTimer->isActive() ) { - // TODO should record changes for delayed saving - kError() << "Delayed saving scheduled when resource changed. We might have lost changes"; - mDelayedSaveTimer->stop(); - } - // FIXME: there must be a better way to do this - mFullItemRetrieve = true; - synchronize(); -} - -void KABCResource::subResourceAdded( KABC::ResourceABC *resource, - const QString &type, const QString &subResource ) -{ - Q_UNUSED( resource ); - Q_UNUSED( type ); - kDebug() << "subResource" << subResource; - Q_ASSERT( resource == mFolderResource ); - Q_ASSERT( type.toLower() == QLatin1String( "contact" ) ); - Q_ASSERT( !subResource.isEmpty() ); - - // synchronizeCollectionTree just in case the resource does not make - // the address book emit addressBookChanged() - synchronizeCollectionTree(); -} - -void KABCResource::subResourceRemoved( KABC::ResourceABC *resource, - const QString &type, const QString &subResource ) -{ - Q_UNUSED( resource ); - Q_UNUSED( type ); - kDebug() << "subResource" << subResource; - Q_ASSERT( resource == mFolderResource ); - Q_ASSERT( type.toLower() == QLatin1String( "contact" ) ); - Q_ASSERT( !subResource.isEmpty() ); - - // synchronizeCollectionTree just in case the resource does not make - // the address book emit addressBookChanged() - synchronizeCollectionTree(); -} - -void KABCResource::subResourceChanged( KABC::ResourceABC *resource, - const QString &type, const QString &subResource ) -{ - Q_UNUSED( resource ); - Q_UNUSED( type ); - kDebug() << "subResource" << subResource; - Q_ASSERT( resource == mFolderResource ); - Q_ASSERT( type.toLower() == QLatin1String( "contact" ) ); - Q_ASSERT( !subResource.isEmpty() ); - - // synchronizeCollectionTree just in case the resource does not make - // the address book emit addressBookChanged() - synchronizeCollectionTree(); -} - -void KABCResource::reloadConfiguration() -{ - if ( mDelayedSaveTimer->isActive() ) { - if ( !saveAddressBook() ) { - kError() << "Saving of address book failed:" << mErrorHandler->mLastError; - } - } - closeConfiguration(); - - KGlobal::config()->reparseConfiguration(); - - if ( KGlobal::config()->groupList().isEmpty() ) { - emit status( NotConfigured, i18nc( "@info:status", "No KDE address book plugin configured yet" ) ); - return; - } - - Q_ASSERT( KGlobal::config().data() != 0); - - KRES::Manager *manager = mAddressBook->getResourceManager(); - manager->readConfig( KGlobal::config().data() ); - - KRES::Resource *resource = manager->standardResource(); - if ( resource != 0 ) { - if ( resource->type().toLower() == QLatin1String( "akonadi" ) ) { - kError() << "Resource config points to an Akonadi bridge resource"; - emit status( NotConfigured, i18nc( "@info:status", "No KDE address book plugin configured yet" ) ); - return; - } - } - - setResourcePointers( manager->standardResource() ); - if ( mBaseResource == 0 ) { - emit status( NotConfigured, i18nc( "@info:status", "No KDE address book plugin configured yet" ) ); - return; - } - - if ( !isOnline() ) - return; - - if ( !openConfiguration() ) { - kError() << "openConfiguration() failed"; - - const QString message = i18nc( "@info:status", "Initialization based on stored configuration failed." ); - emit error( message ); - emit status( Broken, message ); - return; - } - - if ( !mAddressBook->asyncLoad() ) { - kError() << "asyncLoad() failed"; - - const QString message = i18nc( "@info:status", "Loading of address book failed." ); - emit error( message ); - emit status( Broken, message ); - return; - } - - emit status( Running, i18nc( "@info:status", "Loading address book" ) ); -} - -void KABCResource::delayedSaveAddressBook() -{ - if ( !saveAddressBook() ) { - kError() << "Saving failed, rescheduling delayed save. Error was: " - << mErrorHandler->mLastError; - if ( !scheduleSaveAddressBook() ) { - kError() << "Scheduling failed as well, giving up"; - } - } -} - -KABC::DistributionList *KABCResource::distListFromContactGroup( const KABC::ContactGroup& contactGroup ) -{ - KABC::DistributionList *list = - new KABC::DistributionList( mBaseResource, contactGroup.id(), contactGroup.name() ); - - for ( unsigned int refIndex = 0; refIndex < contactGroup.contactReferenceCount(); ++refIndex ) { - const KABC::ContactGroup::ContactReference &reference = contactGroup.contactReference( refIndex ); - - KABC::Addressee addressee = mBaseResource->findByUid( reference.uid() ); - if ( addressee.isEmpty() ) { - addressee.setUid( reference.uid() ); - // TODO any way to set a good name? - } - - // TODO how to handle ContactGroup::ContactReference custom fields? - - list->insertEntry( addressee, reference.preferredEmail() ); - } - - for ( unsigned int dataIndex = 0; dataIndex < contactGroup.dataCount(); ++dataIndex ) { - const KABC::ContactGroup::Data &data = contactGroup.data( dataIndex ); - - KABC::Addressee addressee; - addressee.setName( data.name() ); - addressee.insertEmail( data.email() ); - - // TODO how to handle ContactGroup::Data custom fields? - - list->insertEntry( addressee ); - } - - return list; -} - -KABC::ContactGroup KABCResource::contactGroupFromDistList( const KABC::DistributionList* list ) const -{ - kDebug() << "name=" << list->name() << ", identifier=" << list->identifier() - << ", entries.count=" << list->entries().count(); - - KABC::ContactGroup contactGroup( list->name() ); - contactGroup.setId( list->identifier() ); - - const KABC::DistributionList::Entry::List entries = list->entries(); - foreach ( const KABC::DistributionList::Entry &entry, entries ) { - const KABC::Addressee addressee = entry.addressee(); - const QString email = entry.email(); - if ( addressee.isEmpty() ) { - if ( email.isEmpty() ) - continue; - - KABC::ContactGroup::Data data( email, email ); - contactGroup.append( data ); - } else { - const KABC::Addressee baseAddressee = mBaseResource->findByUid( addressee.uid() ); - if ( baseAddressee.isEmpty() ) { - KABC::ContactGroup::Data data( email, email ); - // TODO: transer custom fields? - contactGroup.append( data ); - } else { - KABC::ContactGroup::ContactReference reference( addressee.uid() ); - reference.setPreferredEmail( email ); - // TODO: transer custom fields? - contactGroup.append( reference ); - } - } - } - - return contactGroup; -} - -AKONADI_RESOURCE_MAIN( KABCResource ) - - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/kabc/kabcresource.desktop kdepim-runtime-15.08.0/resources/kabc/kabcresource.desktop --- kdepim-runtime-4.14.6/resources/kabc/kabcresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kabc/kabcresource.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -[Desktop Entry] -Name=KDE Address Book (traditional) -Name[ar]=دفتر عناوين كدي (التقليدي) -Name[bs]=KDE adresad (tradicionalno) -Name[ca]=Llibreta d'adreces del KDE (tradicional) -Name[ca@valencia]=Llibreta d'adreces del KDE (tradicional) -Name[cs]=Kniha adres KDE (tradiční) -Name[da]=KDE's adressebog (traditionel) -Name[de]=KDE-Adressbuch (herkömmlich) -Name[el]=Βιβλίο διευθύνσεων του KDE (παραδοσιακό) -Name[en_GB]=KDE Address Book (traditional) -Name[es]=Libreta de direcciones de KDE (tradicional) -Name[et]=KDE aadressiraamat (traditsiooniline) -Name[fi]=KDE:n osoitekirja (perinteinen) -Name[fr]=Carnet d'adresses KDE (traditionnel) -Name[ga]=Leabhar Seoltaí KDE (traidisiúnta) -Name[gl]=Caderno de Enderezos do KDE (tradicional) -Name[hu]=KDE címjegyzék (hagyományos) -Name[ia]=Adressario KDE (traditional) -Name[it]=Rubrica indirizzi di KDE (tradizionale) -Name[ja]=KDE アドレス帳 (従来のタイプ) -Name[kk]=KDE адрестік кітапшасы (дәстүрлі) -Name[km]=សៀវភៅ​អាសយដ្ឋាន KDE (បុរាណ) -Name[ko]=KDE 주소록 (이전 버전) -Name[lt]=KDE adresų knygelė (tradicinė) -Name[lv]=KDE adrešu grāmata (tradicionālā) -Name[nb]=KDE-adressebok (tradisjonell) -Name[nds]=KDE-Adressbook (normaal) -Name[nl]=Adresboek van KDE (traditioneel) -Name[nn]=KDE-adressebok (tradisjonell) -Name[pa]=KDE ਐਡਰੈੱਸ ਬੁੱਕ (ਪੁਰਾਣੀ) -Name[pl]=Książka adresowa KDE (tradycyjna) -Name[pt]=Livro de Endereços do KDE (tradicional) -Name[pt_BR]=Livro de endereços do KDE (tradicional) -Name[ro]=Carte de adrese KDE (tradițională) -Name[ru]=Адресная книга KDE (традиционный источник) -Name[sk]=KDE adresár (tradičný) -Name[sl]=KDE-jev imenik (tradicionalni) -Name[sr]=КДЕ‑ов адресар (традиционални) -Name[sr@ijekavian]=КДЕ‑ов адресар (традиционални) -Name[sr@ijekavianlatin]=KDE‑ov adresar (tradicionalni) -Name[sr@latin]=KDE‑ov adresar (tradicionalni) -Name[sv]=KDE:s adressbok (traditionell) -Name[tr]=KDE Adres Defteri (geleneksel) -Name[uk]=Адресна книга KDE (традиційна) -Name[x-test]=xxKDE Address Book (traditional)xx -Name[zh_CN]=KDE 地址簿(传统) -Name[zh_TW]=KDE 通訊錄(傳統) -Comment=Loads data from a traditional KDE address book resource -Comment[ar]=تحمل البيانات من موارد دفتر عنوان كدي التقليدي -Comment[bs]=Učitava podatke iz tradicionalog KDE izvora adresara -Comment[ca]=Carrega les dades des d'un recurs de llibreta d'adreces tradicional del KDE -Comment[ca@valencia]=Carrega dades des d'un recurs de llibreta d'adreces tradicional del KDE -Comment[cs]=Načítá data ze zdroje tradiční Knihy adres KDE -Comment[da]=Indlæser data fra en traditionel KDE adressebogsressource -Comment[de]=Lädt Daten aus einer herkömmlichen KDE-Adressbuch-Ressource -Comment[el]=Φόρτωση δεδομένων από έναν παραδοσιακό πόρο βιβλίου διευθύνσεων του KDE -Comment[en_GB]=Loads data from a traditional KDE address book resource -Comment[es]=Carga datos desde un recurso tradicional de libreta de direcciones de KDE -Comment[et]=Andmete laadimine traditsioonilisest KDE aadressiraamatu ressursist -Comment[fi]=Noutaa tietoa KDE:n perinteisestä osoitekirjaresurssista -Comment[fr]=Charge des données depuis un carnet traditionnel d'adresses KDE -Comment[ga]=Breiseán a luchtaíonn sonraí ó acmhainn thraidisiúnta leabhair seoltaí KDE -Comment[gl]=Carga datos desde un recurso de caderno de enderezos do KDE -Comment[hu]=Adatbetöltés egy hagyományos KDE címjegyzékből -Comment[ia]=Lege datos de un ressource de un adressario KDE traditional -Comment[it]=Carica dati da una tradizionale risorsa rubrica di KDE -Comment[ja]=従来の KDE アドレス帳リソースからデータを読み込みます -Comment[kk]=Дәстүрлі KDE адрестік кітапшасынан деректі алып береді -Comment[km]=ផ្ទុក​ទិន្នន័យ​ពី​ធនធាន​សៀវភៅ​អាសយដ្ឋាន KDE បុរាណ -Comment[ko]=이전 버전 KDE 주소록 자원에서 데이터를 불러옵니다 -Comment[lt]=Įkels duomenis iš tradicinės KDE adresų knygos resurso -Comment[lv]=Ielādē datus no tradicionālā KDE adrešu grāmatas resursa -Comment[nb]=Laster data fra en tradisjonell KDE adressebok-ressurs -Comment[nds]=Laadt Daten ut en normaal KDE-Adressbookressource -Comment[nl]=Laadt gegevens van een traditionele KDE adresboekbron -Comment[nn]=Lastar data frå tradisjonelle KDE-adressebokressursar -Comment[pl]=Wczytuje dane z tradycyjnych zasobów książki adresowej KDE -Comment[pt]=Carrega os dados de um recurso de livro de endereços tradicional do KDE -Comment[pt_BR]=Carrega os dados do tradicional recurso do livro de endereços do KDE -Comment[ru]=Загрузка данных из простой адресной книги KDE -Comment[sk]=Načíta dáta z prechodného KDE zdroja adresára -Comment[sl]=Naloži podatke iz tradicionalnega KDE-jevega imenika -Comment[sr]=Учитава податке из традиционалног КДЕ‑овог ресурса адресара -Comment[sr@ijekavian]=Учитава податке из традиционалног КДЕ‑овог ресурса адресара -Comment[sr@ijekavianlatin]=Učitava podatke iz tradicionalnog KDE‑ovog resursa adresara -Comment[sr@latin]=Učitava podatke iz tradicionalnog KDE‑ovog resursa adresara -Comment[sv]=Laddar data från en traditionell adressboksresurs i KDE -Comment[tr]=Geleneksel KDE adres defteri kaynağından veri yükler -Comment[uk]=Завантажує дані зі звичайного ресурсу адресної книги для KDE -Comment[x-test]=xxLoads data from a traditional KDE address book resourcexx -Comment[zh_CN]=从传统 KDE 地址簿资源载入数据 -Comment[zh_TW]=從傳統 KDE 通訊錄資源載入資料 -Type=AkonadiResource -Exec=akonadi_kabc_resource -Icon=text-directory - -X-Akonadi-MimeTypes=text/directory,application/x-vnd.kde.contactgroup -X-Akonadi-Capabilities=Resource -X-Akonadi-Identifier=akonadi_kabc_resource diff -Nru kdepim-runtime-4.14.6/resources/kabc/kabcresource.h kdepim-runtime-15.08.0/resources/kabc/kabcresource.h --- kdepim-runtime-4.14.6/resources/kabc/kabcresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kabc/kabcresource.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -/* - Copyright (c) 2008 Kevin Krammer - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef KABCRESOURCE -#define KABCRESOURCE - -#include - -namespace KABC { - class ContactGroup; - class DistributionList; - class Resource; - class ResourceABC; -} - -namespace Akonadi { - class MimeTypeChecker; -} - -class QTimer; - -class KABCResource : public Akonadi::ResourceBase, public Akonadi::AgentBase::Observer -{ - Q_OBJECT - - public: - explicit KABCResource( const QString &id ); - virtual ~KABCResource(); - - public Q_SLOTS: - virtual void configure( WId windowId ); - - protected Q_SLOTS: - void retrieveCollections(); - void retrieveItems( const Akonadi::Collection &col ); - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - - protected: - virtual void aboutToQuit(); - - virtual void doSetOnline( bool online ); - - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); - virtual void itemRemoved( const Akonadi::Item &item ); - - virtual void collectionChanged( const Akonadi::Collection &collection ); - - private: - class AddressBook; - AddressBook *mAddressBook; - KABC::Resource *mBaseResource; - KABC::ResourceABC *mFolderResource; - - class ErrorHandler; - ErrorHandler *mErrorHandler; - - bool mFullItemRetrieve; - - QTimer *mDelayedSaveTimer; - - Akonadi::MimeTypeChecker *mContactGroupMimeChecker; - - private: - void setResourcePointers( KABC::Resource *resource ); - - bool openConfiguration(); - - void closeConfiguration(); - - bool saveAddressBook(); - - bool scheduleSaveAddressBook(); - - KABC::DistributionList *distListFromContactGroup( const KABC::ContactGroup& contactGroup ); - - KABC::ContactGroup contactGroupFromDistList( const KABC::DistributionList* list ) const; - - typedef KABC::Resource Resource; - - private Q_SLOTS: - void loadingError( Resource *resource, const QString &message ); - void initialLoadingFinished( Resource *resource ); - - void addressBookChanged(); - - void subResourceAdded( KABC::ResourceABC *resource, - const QString &type, const QString &subResource ); - void subResourceRemoved( KABC::ResourceABC *resource, - const QString &type, const QString &subResource ); - - void subResourceChanged( KABC::ResourceABC *resource, - const QString &type, const QString &subResource ); - - void reloadConfiguration(); - - void delayedSaveAddressBook(); -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/kabc/kresourceassistant.cpp kdepim-runtime-15.08.0/resources/kabc/kresourceassistant.cpp --- kdepim-runtime-4.14.6/resources/kabc/kresourceassistant.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kabc/kresourceassistant.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,400 +0,0 @@ -/* - Copyright (c) 2008 Kevin Krammer - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "kresourceassistant.h" - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - - -static bool isBlackListed( const QString &name ) -{ - static const QSet blackList = QSet() << "akonadi" << "file" << "dir" << "net" << "localdir"; - return blackList.contains( name ); -} - -class CompatibilityIntroductionLabel : public QWidget -{ - public: - explicit CompatibilityIntroductionLabel( QWidget *parent ) - : QWidget( parent ) - { - QVBoxLayout *mainLayout = new QVBoxLayout( this ); - mainLayout->setSpacing( KDialog::spacingHint() ); - mainLayout->setMargin( KDialog::marginHint() ); - - const QString introduction = - i18nc( "@info", - "Introduction" - "This assistant will guide you through the necessary " - "steps to use a traditional KDE resource plugin to populate " - "a folder of your Akonadi personal information setup with data " - "otherwise not yet accessible through native Akonadi " - "resources." - "The setup process consists of three steps:" - "" - "Step 1: Selecting a plugin suitable for the kind of data " - "source you want to add;" - "Step 2: Providing the selected plugin with information on " - "where to find and how to access the data;" - "Step 3: Naming the resulting data source so you can easily " - "identify it in any application presenting you a choice of " - "which data to process." ); - - QLabel *label = new QLabel( this ); - label->setWordWrap( true ); - label->setText( introduction ); - - mainLayout->addWidget( label ); - mainLayout->addStretch(); - } -}; - -class KResourceDescriptionLabel : public QWidget -{ - public: - KResourceDescriptionLabel( const QString &type, const QString &desc, QWidget *parent) - : QWidget( parent ), mType( type ) - { - QVBoxLayout *mainLayout = new QVBoxLayout( this ); - mainLayout->setSpacing( KDialog::spacingHint() ); - - QLabel *label = new QLabel( desc, this ); - label->setWordWrap( true ); - mainLayout->addWidget( label ); - - mainLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding ) ); - } - - public: - const QString mType; -}; - -class KResourceCreationWidget : public QWidget -{ - public: - KResourceCreationWidget( const QString &familyName, KRES::Factory *factory, QWidget *parent ) - : QWidget( parent ), mFamilyName( familyName ), - mFactory( factory ), mResource( 0 ), mPageWidget( 0 ) - { - QVBoxLayout *mainLayout = new QVBoxLayout( this ); - mainLayout->setSpacing( KDialog::spacingHint() ); - mainLayout->setMargin( KDialog::marginHint() ); - - mPageWidget = new KPageWidget( this ); - mPageWidget->setFaceType( KPageView::Tree ); - - mainLayout->addWidget( mPageWidget ); - - mTypes = mFactory->typeNames(); - - // Filter-out types for which we have a native akonadi resource - foreach( const QString &type, mTypes ) { - if ( isBlackListed( type ) ) - mTypes.removeAll( type ); - } - - foreach ( const QString &type, mTypes ) { - QString description = mFactory->typeDescription( type ); - if ( description.isEmpty() ) - description = i18nc( "@info", "No description available" ); - - QWidget *label = new KResourceDescriptionLabel( type, description, mPageWidget ); - mPageWidget->addPage( label, mFactory->typeName( type ) ); - } - } - - void createResource() - { - KResourceDescriptionLabel *label = - static_cast( mPageWidget->currentPage()->widget() ); - - if ( mResource != 0 && mResource->type() == label->mType ) - return; - - delete mResource; - mResource = mFactory->resource( label->mType ); - - mResource->setResourceName( mFamilyName ); - } - - public: - QString mFamilyName; - QStringList mTypes; - - KRES::Factory *mFactory; - KRES::Resource *mResource; - - KPageWidget *mPageWidget; -}; - -class KResourcePluginConfigWidget : public QGroupBox -{ - public: - KResourcePluginConfigWidget( const QString &type, KRES::Factory *factory, QWidget *parent) - : QGroupBox( parent ), mPluginWidget( 0 ) - { - setTitle( i18nc( "@title:group", "%1 Plugin Settings", factory->typeName( type ) ) ); - - QVBoxLayout *mainLayout = new QVBoxLayout( this ); - mPluginWidget = factory->configWidget( type, this ); - if ( mPluginWidget == 0 ) { - kError() << "No plugin configuration widget for resource type" << type; - QLabel *label = new QLabel( i18nc( "@info", "No plugin specific configuration available" ), this ); - label->setAlignment( Qt::AlignHCenter ); - mainLayout->addWidget( label ); - } else - mainLayout->addWidget( mPluginWidget ); - - mainLayout->addStretch(); - } - - public: - KRES::ConfigWidget *mPluginWidget; -}; - -class KResourceConfigWidget : public QWidget -{ - public: - KResourceConfigWidget( const QStringList &types, KRES::Factory *factory, QWidget *parent ) - : QWidget( parent ), mStackWidget( 0 ) - { - QVBoxLayout *mainLayout = new QVBoxLayout( this ); - mainLayout->setSpacing( KDialog::spacingHint() ); - mainLayout->setMargin( KDialog::marginHint() ); - - mStackWidget = new QStackedWidget( this ); - - mainLayout->addWidget( mStackWidget ); - - foreach ( const QString &type, types ) { - KResourcePluginConfigWidget *configWidget = - new KResourcePluginConfigWidget( type, factory, mStackWidget ); - mStackWidget->addWidget( configWidget ); - mStackedWidgets.insert( type, configWidget ); - - if ( configWidget->mPluginWidget != 0 ) { - connect( configWidget->mPluginWidget, SIGNAL(setReadOnly(bool)), - parent, SLOT(setReadOnly(bool)) ); - } - } - } - - void loadSettings( KRES::Resource *resource ) - { - KResourcePluginConfigWidget *widget = mStackedWidgets[ resource->type() ]; - Q_ASSERT( widget != 0 ); - - if ( widget->mPluginWidget != 0 ) - widget->mPluginWidget->loadSettings( resource ); - mStackWidget->setCurrentWidget( widget ); - } - - void saveSettings( KRES::Resource *resource ) - { - KResourcePluginConfigWidget *widget = mStackedWidgets[ resource->type() ]; - Q_ASSERT( widget != 0 ); - - if ( widget->mPluginWidget != 0 ) - widget->mPluginWidget->saveSettings( resource ); - } - - public: - QStackedWidget *mStackWidget; - QMap mStackedWidgets; -}; - -class KResourceFolderConfigWidget : public QWidget -{ - public: - KResourceFolderConfigWidget( const QString &familyName, QWidget *parent ) - : QWidget( parent ), mName( 0 ), mReadOnly( 0 ) - { - QVBoxLayout *mainLayout = new QVBoxLayout( this ); - mainLayout->setSpacing( KDialog::spacingHint() ); - - // TODO probably add Akonadi related options - const QString helpText = - i18nc( "@info", - "The settings on this page allow you to customize how the " - "data from the plugin will fit into your personal information " - "setup." ); - - QLabel *helpLabel = new QLabel( this ); - helpLabel->setWordWrap( true ); - helpLabel->setText( helpText ); - - mainLayout->addWidget( helpLabel ); - - QGroupBox *generalGroup = new QGroupBox( this ); - QGridLayout *generalLayout = new QGridLayout( generalGroup ); - generalLayout->setMargin( KDialog::marginHint() ); - generalLayout->setSpacing( KDialog::spacingHint() ); - - generalGroup->setTitle( i18nc( "@title:group general resource settings", - "%1 Folder Settings", - familyName ) ); - - QLabel *nameLabel = new QLabel( i18nc( "@label resource name", "Name:" ), - generalGroup ); - generalLayout->addWidget( nameLabel, 0, 0 ); - - mName = new KLineEdit( generalGroup ); - generalLayout->addWidget( mName, 0, 1 ); - - mReadOnly = new QCheckBox( i18nc( "@option:check if resource is read-only", - "Read-only" ), - generalGroup ); - generalLayout->addWidget( mReadOnly, 1, 0, 1, 2 ); - - mReadOnly->setChecked( false ); - - mainLayout->addWidget( generalGroup ); - mainLayout->addStretch(); - - connect( mName, SIGNAL(textChanged(QString)), - parent, SLOT(slotNameChanged(QString)) ); - } - - public: - KLineEdit *mName; - QCheckBox *mReadOnly; -}; - -class KResourceAssistant::Private -{ - public: - explicit Private( KResourceAssistant *parent ) - : mParent( parent ), mFactory( 0 ), mCreationWidget( 0 ), - mConfigWidget( 0 ), mFolderWidget( 0 ), - mLastPage( 0 ) - { - } - - public: - KResourceAssistant *mParent; - - KRES::Factory *mFactory; - - KResourceCreationWidget *mCreationWidget; - KResourceConfigWidget *mConfigWidget; - KResourceFolderConfigWidget *mFolderWidget; - - KPageWidgetItem *mLastPage; - - public: - void setReadOnly( bool readOnly ) - { - mFolderWidget->mReadOnly->setChecked( readOnly ); - } - - void slotNameChanged( const QString &text ); -}; - -KResourceAssistant::KResourceAssistant( const QString& resourceFamily, QWidget *parent ) - : KAssistantDialog( parent ), d( new Private( this ) ) -{ - // TODO they are most likely already defined somewhere - QMap familyNames; - familyNames[ QLatin1String( "contact" ) ] = - i18nc( "@title user visible resource type", "Address Book" ); - familyNames[ QLatin1String( "calendar" ) ] = - i18nc( "@title user visible resource type", "Calendar" ); - - const QString familyName = familyNames[ resourceFamily.toLower() ]; - - setModal( true ); - setCaption( i18nc( "@title:window", "KDE Compatibility Assistant" ) ); - setWindowIcon( KIcon( "text-directory" ) ); - - QWidget *introPage = new CompatibilityIntroductionLabel( this ); - addPage( introPage, QLatin1String( " " ) ); - - d->mFactory = KRES::Factory::self( resourceFamily.toLower() ); - - d->mCreationWidget = new KResourceCreationWidget( familyName, d->mFactory, this ); - addPage( d->mCreationWidget, i18nc( "@title assistant dialog step", - "Step 1: Select a KDE resource plugin" ) ); - - d->mConfigWidget = - new KResourceConfigWidget( d->mCreationWidget->mTypes, d->mFactory, this ); - addPage( d->mConfigWidget, i18nc( "@title assistant dialog step", - "Step 2: Configure the selected KDE resource plugin" ) ); - - d->mFolderWidget = new KResourceFolderConfigWidget( familyName, this ); - d->mLastPage = addPage( d->mFolderWidget, i18nc( "@title assistant dialog step", - "Step 3: Choose target folder properties" ) ); -} - -KResourceAssistant::~KResourceAssistant() -{ - delete d; -} - -KRES::Resource *KResourceAssistant::resource() -{ - return d->mCreationWidget->mResource; -} - -void KResourceAssistant::back() -{ - KPageWidgetItem *item = currentPage(); - if ( item->widget() == d->mConfigWidget ) { - d->mConfigWidget->saveSettings( d->mCreationWidget->mResource ); - } - - KAssistantDialog::back(); -} - -void KResourceAssistant::next() -{ - KPageWidgetItem *item = currentPage(); - if ( item->widget() == d->mCreationWidget ) { - d->mCreationWidget->createResource(); - - d->mConfigWidget->loadSettings( d->mCreationWidget->mResource ); - } else if ( item->widget() == d->mConfigWidget ) { - d->mConfigWidget->saveSettings( d->mCreationWidget->mResource ); - d->setReadOnly( d->mCreationWidget->mResource->readOnly() ); - const QString resourceName = d->mCreationWidget->mResource->resourceName(); - d->mFolderWidget->mName->setText( resourceName ); - } - - KAssistantDialog::next(); -} - -void KResourceAssistant::Private::slotNameChanged( const QString &text ) -{ - - mParent->setValid( mLastPage, !text.isEmpty() ); - mCreationWidget->mResource->setResourceName( text ); -} - -#include "moc_kresourceassistant.cpp" -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/kabc/kresourceassistant.h kdepim-runtime-15.08.0/resources/kabc/kresourceassistant.h --- kdepim-runtime-4.14.6/resources/kabc/kresourceassistant.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kabc/kresourceassistant.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* - Copyright (c) 2008 Kevin Krammer - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef KRESOURCEASSISTANT -#define KRESOURCEASSISTANT - -#include - -namespace KRES { - class Resource; -} - -class KResourceAssistant : public KAssistantDialog -{ - Q_OBJECT - - public: - explicit KResourceAssistant( const QString& resourceFamily, QWidget *parent = 0 ); - - virtual ~KResourceAssistant(); - - KRES::Resource *resource(); - - Q_SIGNALS: - void error( const QString& message ); - - public Q_SLOTS: - virtual void back(); - virtual void next(); - - private: - class Private; - Private *d; - - Q_PRIVATE_SLOT( d, void setReadOnly( bool ) ) - Q_PRIVATE_SLOT( d, void slotNameChanged( const QString& ) ) -}; - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/kabc/Messages.sh kdepim-runtime-15.08.0/resources/kabc/Messages.sh --- kdepim-runtime-4.14.6/resources/kabc/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kabc/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -#! /usr/bin/env bash -$XGETTEXT kabcresource.cpp -o $podir/akonadi_kabc_resource.pot -$XGETTEXT kresourceassistant.cpp -o $podir/akonadi_kresourceassistant.pot diff -Nru kdepim-runtime-4.14.6/resources/kalarm/CMakeLists.txt kdepim-runtime-15.08.0/resources/kalarm/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/kalarm/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,2 +1,3 @@ +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_kalarm_resource\") add_subdirectory(kalarm) add_subdirectory(kalarmdir) diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarm/CMakeLists.txt kdepim-runtime-15.08.0/resources/kalarm/kalarm/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/kalarm/kalarm/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarm/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,49 +1,48 @@ include_directories( - ${QT_QTDBUS_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../shared ${CMAKE_CURRENT_SOURCE_DIR}/../../ical/shared ) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}") + ########### next target ############### -add_definitions(-DKDE_DEFAULT_DEBUG_AREA=5952) add_definitions(-DSETTINGS_NAMESPACE=Akonadi_KAlarm_Resource) set(kalarmresource_SRCS - ${AKONADI_SINGLEFILERESOURCE_SHARED_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../ical/shared/icalresourcebase.cpp kalarmresource.cpp + kalarmresource_debug.cpp ../shared/kalarmresourcecommon.cpp ../shared/alarmtyperadiowidget.cpp ) -install(FILES kalarmresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents") +install(FILES kalarmresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents") -kde4_add_ui_files(kalarmresource_SRCS ../shared/alarmtyperadiowidget.ui ${AKONADI_SINGLEFILERESOURCE_SHARED_UI}) -kde4_add_kcfg_files(kalarmresource_SRCS settings.kcfgc) +ki18n_wrap_ui(kalarmresource_SRCS ../shared/alarmtyperadiowidget.ui) +kconfig_add_kcfg_files(kalarmresource_SRCS settings.kcfgc) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/kalarmresource.kcfg org.kde.Akonadi.KAlarm.Settings) -qt4_add_dbus_adaptor(kalarmresource_SRCS +qt5_add_dbus_adaptor(kalarmresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.KAlarm.Settings.xml settings.h Akonadi_KAlarm_Resource::Settings icalsettingsadaptor ICalSettingsAdaptor) add_custom_target(kalarm_resource_xml ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.KAlarm.Settings.xml) -kde4_add_plugin(akonadi_kalarm_resource ${kalarmresource_SRCS}) +add_executable(akonadi_kalarm_resource ${kalarmresource_SRCS}) -if (Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_kalarm_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) set_target_properties(akonadi_kalarm_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.KAlarm") set_target_properties(akonadi_kalarm_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi KAlarm Resource") endif () target_link_libraries(akonadi_kalarm_resource - ${KDEPIMLIBS_KALARMCAL_LIBS} - ${KDEPIMLIBS_AKONADI_KCAL_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KCALCORE_LIBS} - ${KDE4_KIO_LIBS} - ${QT_QTDBUS_LIBRARY} + KF5::AlarmCalendar + KF5::AkonadiCore + KF5::CalendarCore + KF5::KIOCore + KF5::AkonadiAgentBase + KF5::DBusAddons + akonadi-singlefileresource ) -install(TARGETS akonadi_kalarm_resource DESTINATION ${PLUGIN_INSTALL_DIR}) +install(TARGETS akonadi_kalarm_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarm/kalarmresource.cpp kdepim-runtime-15.08.0/resources/kalarm/kalarm/kalarmresource.cpp --- kdepim-runtime-4.14.6/resources/kalarm/kalarm/kalarmresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarm/kalarmresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -27,24 +27,24 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -#include -#include +#include +#include -#include -#include +#include +#include "kalarmresource_debug.h" using namespace Akonadi; using namespace Akonadi_KAlarm_Resource; using namespace KAlarmCal; using KAlarmResourceCommon::errorMessage; -KAlarmResource::KAlarmResource(const QString& id) +KAlarmResource::KAlarmResource(const QString &id) : ICalResourceBase(id), mCompatibility(KACalendar::Incompatible), mFileCompatibility(KACalendar::Incompatible), @@ -53,10 +53,10 @@ mHaveReadFile(false), mFetchedAttributes(false) { - kDebug() << id; + qCDebug(KALARMRESOURCE_LOG) << id; KAlarmResourceCommon::initialise(this); - initialise(mSettings->alarmTypes(), QLatin1String("kalarm")); - connect(mSettings, SIGNAL(configChanged()), SLOT(settingsChanged())); + initialise(mSettings->alarmTypes(), QStringLiteral("kalarm")); + connect(mSettings, &Settings::configChanged, this, &KAlarmResource::settingsChanged); // Start a job to fetch the collection attributes fetchCollection(SLOT(collectionFetchResult(KJob*))); @@ -69,7 +69,7 @@ /****************************************************************************** * Customize the configuration dialog before it is displayed. */ -void KAlarmResource::customizeConfigDialog(SingleFileResourceConfigDialog* dlg) +void KAlarmResource::customizeConfigDialog(SingleFileResourceConfigDialog *dlg) { ICalResourceBase::customizeConfigDialog(dlg); #ifdef KDEPIM_MOBILE_UI @@ -78,36 +78,36 @@ mTypeSelector = new AlarmTypeRadioWidget(dlg); const QStringList types = mSettings->alarmTypes(); CalEvent::Type alarmType = CalEvent::ACTIVE; - if (!types.isEmpty()) + if (!types.isEmpty()) { alarmType = CalEvent::type(types[0]); + } mTypeSelector->setAlarmType(alarmType); dlg->appendWidget(mTypeSelector); dlg->setMonitorEnabled(false); QString title; - switch (alarmType) - { - case CalEvent::ACTIVE: - title = i18nc("@title:window", "Select Active Alarm Calendar"); - break; - case CalEvent::ARCHIVED: - title = i18nc("@title:window", "Select Archived Alarm Calendar"); - break; - case CalEvent::TEMPLATE: - title = i18nc("@title:window", "Select Alarm Template Calendar"); - break; - default: - return; + switch (alarmType) { + case CalEvent::ACTIVE: + title = i18nc("@title:window", "Select Active Alarm Calendar"); + break; + case CalEvent::ARCHIVED: + title = i18nc("@title:window", "Select Archived Alarm Calendar"); + break; + case CalEvent::TEMPLATE: + title = i18nc("@title:window", "Select Alarm Template Calendar"); + break; + default: + return; } - dlg->setCaption(title); + dlg->setWindowTitle(title); } /****************************************************************************** * Save extra settings after the configuration dialog has been accepted. */ -void KAlarmResource::configDialogAcceptedActions(SingleFileResourceConfigDialog*) +void KAlarmResource::configDialogAcceptedActions(SingleFileResourceConfigDialog *) { mSettings->setAlarmTypes(CalEvent::mimeTypes(mTypeSelector->alarmType())); - mSettings->writeConfig(); + mSettings->save(); } /****************************************************************************** @@ -115,7 +115,7 @@ */ void KAlarmResource::retrieveCollections() { - kDebug(); + qCDebug(KALARMRESOURCE_LOG); mSupportedMimetypes = mSettings->alarmTypes(); ICalResourceBase::retrieveCollections(); fetchCollection(SLOT(collectionFetchResult(KJob*))); @@ -125,38 +125,33 @@ * Called when the collection fetch job completes. * Check the calendar file's compatibility status if pending. */ -void KAlarmResource::collectionFetchResult(KJob* j) +void KAlarmResource::collectionFetchResult(KJob *j) { - if (j->error()) - { + if (j->error()) { // An error occurred. Note that if it's a new resource, it will complain // about an invalid collection if the collection has not yet been created. - kDebug() << "Error: " << j->errorString(); - } - else - { + qCDebug(KALARMRESOURCE_LOG) << "Error: " << j->errorString(); + } else { bool firstTime = !mFetchedAttributes; mFetchedAttributes = true; - CollectionFetchJob* job = static_cast(j); + CollectionFetchJob *job = static_cast(j); const Collection::List collections = job->collections(); - if (collections.isEmpty()) - kDebug() << "Error: resource's collection not found"; - else - { + if (collections.isEmpty()) { + qCDebug(KALARMRESOURCE_LOG) << "Error: resource's collection not found"; + } else { // Check whether calendar file format needs to be updated - kDebug() << "Fetched collection"; - const Collection& c(collections[0]); - if (firstTime && mSettings->path().isEmpty()) - { + qCDebug(KALARMRESOURCE_LOG) << "Fetched collection"; + const Collection &c(collections[0]); + if (firstTime && mSettings->path().isEmpty()) { // Initialising a resource which seems to have no stored // settings config file. Recreate the settings. - static Collection::Rights writableRights = Collection::CanChangeItem | Collection::CanCreateItem | Collection::CanDeleteItem; - kDebug() << "Recreating config for remote id:" << c.remoteId(); + static const Collection::Rights writableRights = Collection::CanChangeItem | Collection::CanCreateItem | Collection::CanDeleteItem; + qCDebug(KALARMRESOURCE_LOG) << "Recreating config for remote id:" << c.remoteId(); mSettings->setPath(c.remoteId()); mSettings->setDisplayName(c.name()); mSettings->setAlarmTypes(c.contentMimeTypes()); mSettings->setReadOnly((c.rights() & writableRights) != writableRights); - mSettings->writeConfig(); + mSettings->save(); synchronize(); // tell the server to use the new config } checkFileCompatibility(c, true); @@ -172,22 +167,21 @@ * The file is always local; loading from the network is done automatically if * needed. */ -bool KAlarmResource::readFromFile(const QString& fileName) +bool KAlarmResource::readFromFile(const QString &fileName) { - kDebug() << fileName; + qCDebug(KALARMRESOURCE_LOG) << fileName; //TODO Notify user if error occurs on next line - if (!ICalResourceBase::readFromFile(fileName)) + if (!ICalResourceBase::readFromFile(fileName)) { return false; - if (calendar()->incidences().isEmpty()) - { + } + if (calendar()->incidences().isEmpty()) { // It's a new file. Set up the KAlarm custom property. KACalendar::setKAlarmVersion(calendar()); } mFileCompatibility = KAlarmResourceCommon::getCompatibility(fileStorage(), mFileVersion); mHaveReadFile = true; - if (mFetchedAttributes) - { + if (mFetchedAttributes) { // The old calendar file version and compatibility have been read from // the database. Check if the file format needs to be converted. checkFileCompatibility(); @@ -204,30 +198,29 @@ * If 'createAttribute' is true, the CompatibilityAttribute will be created if * it does not already exist. */ -void KAlarmResource::checkFileCompatibility(const Collection& collection, bool createAttribute) +void KAlarmResource::checkFileCompatibility(const Collection &collection, bool createAttribute) { if (collection.isValid() - && collection.hasAttribute()) - { + && collection.hasAttribute()) { // Update our note of the calendar version and compatibility - const CompatibilityAttribute* attr = collection.attribute(); + const CompatibilityAttribute *attr = collection.attribute(); mCompatibility = attr->compatibility(); mVersion = attr->version(); createAttribute = false; } if (mHaveReadFile - && (createAttribute - || mFileCompatibility != mCompatibility || mFileVersion != mVersion)) - { + && (createAttribute + || mFileCompatibility != mCompatibility || mFileVersion != mVersion)) { // The actual file's version and compatibility are different from // those in the Akonadi database, so update the database attributes. mCompatibility = mFileCompatibility; mVersion = mFileVersion; const Collection c(collection); - if (c.isValid()) + if (c.isValid()) { KAlarmResourceCommon::setCollectionCompatibility(c, mCompatibility, mVersion); - else + } else { fetchCollection(SLOT(setCompatibility(KJob*))); + } } } @@ -235,26 +228,26 @@ * Called when a collection fetch job completes. * Set the compatibility attribute for the collection. */ -void KAlarmResource::setCompatibility(KJob* j) +void KAlarmResource::setCompatibility(KJob *j) { - CollectionFetchJob* job = static_cast(j); - if (j->error()) - kDebug() << "Error: " << j->errorString(); - else if (job->collections().isEmpty()) - kDebug() << "Error: resource's collection not found"; - else + CollectionFetchJob *job = static_cast(j); + if (j->error()) { + qCDebug(KALARMRESOURCE_LOG) << "Error: " << j->errorString(); + } else if (job->collections().isEmpty()) { + qCDebug(KALARMRESOURCE_LOG) << "Error: resource's collection not found"; + } else { KAlarmResourceCommon::setCollectionCompatibility(job->collections()[0], mCompatibility, mVersion); + } } /****************************************************************************** * Reimplemented to write data to the given file. * The file is always local. */ -bool KAlarmResource::writeToFile(const QString& fileName) +bool KAlarmResource::writeToFile(const QString &fileName) { - kDebug() << fileName; - if (calendar()->incidences().isEmpty()) - { + qCDebug(KALARMRESOURCE_LOG) << fileName; + if (calendar()->incidences().isEmpty()) { // It's an empty file. Set up the KAlarm custom property. KACalendar::setKAlarmVersion(calendar()); } @@ -267,31 +260,28 @@ * Set the event into a new item's payload, and signal its retrieval by calling * itemRetrieved(newitem). */ -bool KAlarmResource::doRetrieveItem(const Akonadi::Item& item, const QSet& parts) +bool KAlarmResource::doRetrieveItem(const Akonadi::Item &item, const QSet &parts) { Q_UNUSED(parts); const QString rid = item.remoteId(); const KCalCore::Event::Ptr kcalEvent = calendar()->event(rid); - if (!kcalEvent) - { - kWarning() << "Event not found:" << rid; - emit error(errorMessage(KAlarmResourceCommon::UidNotFound, rid)); + if (!kcalEvent) { + qCWarning(KALARMRESOURCE_LOG) << "Event not found:" << rid; + Q_EMIT error(errorMessage(KAlarmResourceCommon::UidNotFound, rid)); return false; } - if (kcalEvent->alarms().isEmpty()) - { - kWarning() << "KCalCore::Event has no alarms:" << rid; - emit error(errorMessage(KAlarmResourceCommon::EventNoAlarms, rid)); + if (kcalEvent->alarms().isEmpty()) { + qCWarning(KALARMRESOURCE_LOG) << "KCalCore::Event has no alarms:" << rid; + Q_EMIT error(errorMessage(KAlarmResourceCommon::EventNoAlarms, rid)); return false; } KAEvent event(kcalEvent); const QString mime = CalEvent::mimeType(event.category()); - if (mime.isEmpty()) - { - kWarning() << "KAEvent has no alarms:" << rid; - emit error(errorMessage(KAlarmResourceCommon::EventNoAlarms, rid)); + if (mime.isEmpty()) { + qCWarning(KALARMRESOURCE_LOG) << "KAEvent has no alarms:" << rid; + Q_EMIT error(errorMessage(KAlarmResourceCommon::EventNoAlarms, rid)); return false; } event.setCompatibility(mCompatibility); @@ -307,16 +297,16 @@ */ void KAlarmResource::settingsChanged() { - kDebug(); + qCDebug(KALARMRESOURCE_LOG); const QStringList mimeTypes = mSettings->alarmTypes(); - if (mimeTypes != mSupportedMimetypes) + if (mimeTypes != mSupportedMimetypes) { mSupportedMimetypes = mimeTypes; + } - if (mSettings->updateStorageFormat()) - { + if (mSettings->updateStorageFormat()) { // This is a flag to request that the backend calendar storage format should // be updated to the current KAlarm format. - kDebug() << "Update storage format"; + qCDebug(KALARMRESOURCE_LOG) << "Update storage format"; fetchCollection(SLOT(updateFormat(KJob*))); } } @@ -325,60 +315,55 @@ * Called when a collection fetch job completes. * Update the backend calendar storage format to the current KAlarm format. */ -void KAlarmResource::updateFormat(KJob* j) +void KAlarmResource::updateFormat(KJob *j) { - CollectionFetchJob* job = static_cast(j); - if (j->error()) - kDebug() << "Error: " << j->errorString(); - else if (job->collections().isEmpty()) - kDebug() << "Error: resource's collection not found"; - else - { + CollectionFetchJob *job = static_cast(j); + if (j->error()) { + qCDebug(KALARMRESOURCE_LOG) << "Error: " << j->errorString(); + } else if (job->collections().isEmpty()) { + qCDebug(KALARMRESOURCE_LOG) << "Error: resource's collection not found"; + } else { const Collection c(job->collections()[0]); - if (c.hasAttribute()) - { - const CompatibilityAttribute* attr = c.attribute(); - if (attr->compatibility() != mCompatibility) - kDebug()<<"Compatibility changed:"<"<compatibility(); + if (c.hasAttribute()) { + const CompatibilityAttribute *attr = c.attribute(); + if (attr->compatibility() != mCompatibility) { + qCDebug(KALARMRESOURCE_LOG) << "Compatibility changed:" << mCompatibility << "->" << attr->compatibility(); + } } - switch (mCompatibility) - { - case KACalendar::Current: - kWarning() << "Already current storage format"; - break; - case KACalendar::Incompatible: - default: - kWarning() << "Incompatible storage format: compat=" << mCompatibility; + switch (mCompatibility) { + case KACalendar::Current: + qCWarning(KALARMRESOURCE_LOG) << "Already current storage format"; + break; + case KACalendar::Incompatible: + default: + qCWarning(KALARMRESOURCE_LOG) << "Incompatible storage format: compat=" << mCompatibility; + break; + case KACalendar::Converted: + case KACalendar::Convertible: { + if (mSettings->readOnly()) { + qCWarning(KALARMRESOURCE_LOG) << "Cannot update storage format for a read-only resource"; break; - case KACalendar::Converted: - case KACalendar::Convertible: - { - if (mSettings->readOnly()) - { - kWarning() << "Cannot update storage format for a read-only resource"; - break; - } - // Update the backend storage format to the current KAlarm format - const QString filename = fileStorage()->fileName(); - kDebug() << "Updating storage for" << filename; - KACalendar::setKAlarmVersion(fileStorage()->calendar()); - if (!writeToFile(filename)) - { - kWarning() << "Error updating calendar storage format"; - break; - } - // Prevent a new file read being triggered by writeToFile(), which - // would replace the current Collection by a new one. - mCurrentHash = calculateHash(filename); - - mCompatibility = mFileCompatibility = KACalendar::Current; - mVersion = mFileVersion = KACalendar::CurrentFormat; - KAlarmResourceCommon::setCollectionCompatibility(c, mCompatibility, 0); + } + // Update the backend storage format to the current KAlarm format + const QString filename = fileStorage()->fileName(); + qCDebug(KALARMRESOURCE_LOG) << "Updating storage for" << filename; + KACalendar::setKAlarmVersion(fileStorage()->calendar()); + if (!writeToFile(filename)) { + qCWarning(KALARMRESOURCE_LOG) << "Error updating calendar storage format"; break; } + // Prevent a new file read being triggered by writeToFile(), which + // would replace the current Collection by a new one. + mCurrentHash = calculateHash(filename); + + mCompatibility = mFileCompatibility = KACalendar::Current; + mVersion = mFileVersion = KACalendar::CurrentFormat; + KAlarmResourceCommon::setCollectionCompatibility(c, mCompatibility, 0); + break; + } } mSettings->setUpdateStorageFormat(false); - mSettings->writeConfig(); + mSettings->save(); } } @@ -387,22 +372,21 @@ * Store the event in the calendar, and set its Akonadi remote ID to the * KAEvent's UID. */ -void KAlarmResource::itemAdded(const Akonadi::Item& item, const Akonadi::Collection&) +void KAlarmResource::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &) { - if (!checkItemAddedChanged(item, CheckForAdded)) + if (!checkItemAddedChanged(item, CheckForAdded)) { return; - if (mCompatibility != KACalendar::Current) - { - kWarning() << "Calendar not in current format"; + } + if (mCompatibility != KACalendar::Current) { + qCWarning(KALARMRESOURCE_LOG) << "Calendar not in current format"; cancelTask(errorMessage(KAlarmResourceCommon::NotCurrentFormat)); return; } const KAEvent event = item.payload(); KCalCore::Event::Ptr kcalEvent(new KCalCore::Event); event.updateKCalEvent(kcalEvent, KAEvent::UID_SET); - if (!calendar()->addIncidence(kcalEvent)) - { - kError() << "Error adding event with id" << event.id() << ", item id" << item.id(); + if (!calendar()->addIncidence(kcalEvent)) { + qCritical() << "Error adding event with id" << event.id() << ", item id" << item.id(); cancelTask(errorMessage(KAlarmResourceCommon::CalendarAdd, event.id())); return; } @@ -417,51 +401,45 @@ * Called when an item has been changed. * Store the changed event in the calendar, and delete the original event. */ -void KAlarmResource::itemChanged(const Akonadi::Item& item, const QSet& parts) +void KAlarmResource::itemChanged(const Akonadi::Item &item, const QSet &parts) { Q_UNUSED(parts) - if (!checkItemAddedChanged(item, CheckForChanged)) + if (!checkItemAddedChanged(item, CheckForChanged)) { return; + } QString errorMsg; - if (mCompatibility != KACalendar::Current) - { - kWarning() << "Calendar not in current format"; + if (mCompatibility != KACalendar::Current) { + qCWarning(KALARMRESOURCE_LOG) << "Calendar not in current format"; cancelTask(errorMessage(KAlarmResourceCommon::NotCurrentFormat)); return; } const KAEvent event = KAlarmResourceCommon::checkItemChanged(item, errorMsg); - if (!event.isValid()) - { - if (errorMsg.isEmpty()) + if (!event.isValid()) { + if (errorMsg.isEmpty()) { changeProcessed(); - else + } else { cancelTask(errorMsg); + } return; } KCalCore::Incidence::Ptr incidence = calendar()->incidence(item.remoteId()); - if (incidence) - { - if (incidence->isReadOnly()) - { - kWarning() << "Event is read only:" << event.id(); + if (incidence) { + if (incidence->isReadOnly()) { + qCWarning(KALARMRESOURCE_LOG) << "Event is read only:" << event.id(); cancelTask(errorMessage(KAlarmResourceCommon::EventReadOnly, event.id())); return; } - if (incidence->type() == KCalCore::Incidence::TypeEvent) - { + if (incidence->type() == KCalCore::Incidence::TypeEvent) { calendar()->deleteIncidence(incidence); // it's not an Event incidence.clear(); - } - else - { + } else { KCalCore::Event::Ptr ev(incidence.staticCast()); event.updateKCalEvent(ev, KAEvent::UID_SET); calendar()->setModified(true); } } - if (!incidence) - { + if (!incidence) { // not in the calendar yet, should not happen -> add it KCalCore::Event::Ptr kcalEvent(new KCalCore::Event); event.updateKCalEvent(kcalEvent, KAEvent::UID_SET); @@ -475,7 +453,7 @@ * Called when a collection has been changed. * Determine the calendar file's storage format. */ -void KAlarmResource::collectionChanged(const Akonadi::Collection& collection) +void KAlarmResource::collectionChanged(const Akonadi::Collection &collection) { ICalResourceBase::collectionChanged(collection); @@ -494,9 +472,9 @@ * payload have changed, or the Item has any new Attributes, the Akonadi * storage is updated. */ -void KAlarmResource::doRetrieveItems(const Akonadi::Collection& collection) +void KAlarmResource::doRetrieveItems(const Akonadi::Collection &collection) { - kDebug(); + qCDebug(KALARMRESOURCE_LOG); // Set the collection's compatibility status KAlarmResourceCommon::setCollectionCompatibility(collection, mCompatibility, mVersion); @@ -504,19 +482,16 @@ // Retrieve events from the calendar const KCalCore::Event::List events = calendar()->events(); Item::List items; - foreach (const KCalCore::Event::Ptr& kcalEvent, events) - { - if (kcalEvent->alarms().isEmpty()) - { - kWarning() << "KCalCore::Event has no alarms:" << kcalEvent->uid(); + foreach (const KCalCore::Event::Ptr &kcalEvent, events) { + if (kcalEvent->alarms().isEmpty()) { + qCWarning(KALARMRESOURCE_LOG) << "KCalCore::Event has no alarms:" << kcalEvent->uid(); continue; // ignore events without alarms } const KAEvent event(kcalEvent); const QString mime = CalEvent::mimeType(event.category()); - if (mime.isEmpty()) - { - kWarning() << "KAEvent has no alarms:" << event.id(); + if (mime.isEmpty()) { + qCWarning(KALARMRESOURCE_LOG) << "KAEvent has no alarms:" << event.id(); continue; // event has no usable alarms } @@ -531,15 +506,12 @@ /****************************************************************************** * Execute a CollectionFetchJob to fetch details of this resource's collection. */ -CollectionFetchJob* KAlarmResource::fetchCollection(const char* slot) +CollectionFetchJob *KAlarmResource::fetchCollection(const char *slot) { - CollectionFetchJob* job = new CollectionFetchJob(Collection::root(), CollectionFetchJob::FirstLevel); + CollectionFetchJob *job = new CollectionFetchJob(Collection::root(), CollectionFetchJob::FirstLevel); job->fetchScope().setResource(identifier()); connect(job, SIGNAL(result(KJob*)), slot); return job; } -AKONADI_AGENT_FACTORY(KAlarmResource, akonadi_kalarm_resource) - - -// vim: et sw=4: +AKONADI_RESOURCE_MAIN(KAlarmResource) diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarm/kalarmresource_debug.cpp kdepim-runtime-15.08.0/resources/kalarm/kalarm/kalarmresource_debug.cpp --- kdepim-runtime-4.14.6/resources/kalarm/kalarm/kalarmresource_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarm/kalarmresource_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 "kalarmresource_debug.h" +Q_LOGGING_CATEGORY(KALARMRESOURCE_LOG, "log_kalarmresource") + diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarm/kalarmresource_debug.h kdepim-runtime-15.08.0/resources/kalarm/kalarm/kalarmresource_debug.h --- kdepim-runtime-4.14.6/resources/kalarm/kalarm/kalarmresource_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarm/kalarmresource_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 KALARMRESOURCE_DEBUG_H +#define KALARMRESOURCE_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(KALARMRESOURCE_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarm/kalarmresource.desktop kdepim-runtime-15.08.0/resources/kalarm/kalarm/kalarmresource.desktop --- kdepim-runtime-4.14.6/resources/kalarm/kalarm/kalarmresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarm/kalarmresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,6 @@ [Desktop Entry] Name=KAlarm Calendar File +Name[bg]=Календарен файл на KAlarm Name[bs]=KAlarm Kalendar Datoteka Name[ca]=Fitxer de calendari del KAlarm Name[ca@valencia]=Fitxer de calendari del KAlarm @@ -45,6 +46,7 @@ Name[zh_CN]=KAlarm 日历文件 Name[zh_TW]=KAlarm 行事曆檔案 Comment=Loads data from a KAlarm calendar file +Comment[bg]=Зареждане на данни от календарен файл KAlarm Comment[bs]=Učitava podatke iz KAlarm kalendar datoteke Comment[ca]=Carrega les dades des d'un fitxer de calendari del KAlarm Comment[ca@valencia]=Carrega dades des d'un fitxer de calendari del KAlarm @@ -94,4 +96,3 @@ X-Akonadi-MimeTypes=application/x-vnd.kde.alarm,application/x-vnd.kde.alarm.active,application/x-vnd.kde.alarm.archived,application/x-vnd.kde.alarm.template X-Akonadi-Capabilities=Resource X-Akonadi-Identifier=akonadi_kalarm_resource -X-Akonadi-LaunchMethod=AgentServer diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarm/kalarmresource.h kdepim-runtime-15.08.0/resources/kalarm/kalarm/kalarmresource.h --- kdepim-runtime-4.14.6/resources/kalarm/kalarm/kalarmresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarm/kalarmresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -29,51 +29,53 @@ using namespace KAlarmCal; class KJob; -namespace Akonadi { class CollectionFetchJob; } +namespace Akonadi +{ +class CollectionFetchJob; +} class AlarmTypeRadioWidget; class KAlarmResource : public ICalResourceBase { - Q_OBJECT - public: - explicit KAlarmResource(const QString& id); - virtual ~KAlarmResource(); - - protected: - /** - * Customize the configuration dialog before it is displayed. - */ - virtual void customizeConfigDialog(Akonadi::SingleFileResourceConfigDialog*); - virtual void configDialogAcceptedActions(Akonadi::SingleFileResourceConfigDialog*); - - virtual void doRetrieveItems(const Akonadi::Collection&); - virtual bool doRetrieveItem(const Akonadi::Item&, const QSet& parts); - virtual bool readFromFile(const QString& fileName); - virtual bool writeToFile(const QString& fileName); - virtual void itemAdded(const Akonadi::Item&, const Akonadi::Collection&); - virtual void itemChanged(const Akonadi::Item&, const QSet& parts); - virtual void collectionChanged(const Akonadi::Collection&); - virtual void retrieveCollections(); - - private Q_SLOTS: - void settingsChanged(); - void collectionFetchResult(KJob*); - void updateFormat(KJob*); - void setCompatibility(KJob*); - - private: - void checkFileCompatibility(const Akonadi::Collection& = Akonadi::Collection(), bool createAttribute = false); - Akonadi::CollectionFetchJob* fetchCollection(const char* slot); - - AlarmTypeRadioWidget* mTypeSelector; - KACalendar::Compat mCompatibility; - KACalendar::Compat mFileCompatibility; // calendar file compatibility found by readFromFile() - int mVersion; // calendar format version - int mFileVersion; // calendar format version found by readFromFile() - bool mHaveReadFile; // the calendar file has been read - bool mFetchedAttributes; // attributes have been fetched after initialisation + Q_OBJECT +public: + explicit KAlarmResource(const QString &id); + virtual ~KAlarmResource(); + +protected: + /** + * Customize the configuration dialog before it is displayed. + */ + void customizeConfigDialog(Akonadi::SingleFileResourceConfigDialog *) Q_DECL_OVERRIDE; + void configDialogAcceptedActions(Akonadi::SingleFileResourceConfigDialog *) Q_DECL_OVERRIDE; + + void doRetrieveItems(const Akonadi::Collection &) Q_DECL_OVERRIDE; + bool doRetrieveItem(const Akonadi::Item &, const QSet &parts) Q_DECL_OVERRIDE; + bool readFromFile(const QString &fileName) Q_DECL_OVERRIDE; + bool writeToFile(const QString &fileName) Q_DECL_OVERRIDE; + void itemAdded(const Akonadi::Item &, const Akonadi::Collection &) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &, const QSet &parts) Q_DECL_OVERRIDE; + void collectionChanged(const Akonadi::Collection &) Q_DECL_OVERRIDE; + void retrieveCollections() Q_DECL_OVERRIDE; + +private Q_SLOTS: + void settingsChanged(); + void collectionFetchResult(KJob *); + void updateFormat(KJob *); + void setCompatibility(KJob *); + +private: + void checkFileCompatibility(const Akonadi::Collection & = Akonadi::Collection(), bool createAttribute = false); + Akonadi::CollectionFetchJob *fetchCollection(const char *slot); + + AlarmTypeRadioWidget *mTypeSelector; + KACalendar::Compat mCompatibility; + KACalendar::Compat mFileCompatibility; // calendar file compatibility found by readFromFile() + int mVersion; // calendar format version + int mFileVersion; // calendar format version found by readFromFile() + bool mHaveReadFile; // the calendar file has been read + bool mFetchedAttributes; // attributes have been fetched after initialisation }; #endif -// vim: et sw=4: diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarm/settings.kcfgc kdepim-runtime-15.08.0/resources/kalarm/kalarm/settings.kcfgc --- kdepim-runtime-4.14.6/resources/kalarm/kalarm/settings.kcfgc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarm/settings.kcfgc 2015-08-10 21:01:02.000000000 +0000 @@ -6,5 +6,5 @@ Singleton=false #IncludeFiles= GlobalEnums=true -Namespace=Akonadi_KAlarm_Resource +NameSpace=Akonadi_KAlarm_Resource diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/autoqpointer.h kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/autoqpointer.h --- kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/autoqpointer.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/autoqpointer.h 2015-08-10 21:01:02.000000000 +0000 @@ -23,7 +23,6 @@ #include - /** * A QPointer which when destructed, deletes the object it points to. * @@ -32,15 +31,25 @@ template class AutoQPointer : public QPointer { - public: - AutoQPointer() : QPointer() {} - AutoQPointer(T* p) : QPointer(p) {} - AutoQPointer(const QPointer& p) : QPointer(p) {} - ~AutoQPointer() { delete this->data(); } - AutoQPointer& operator=(const AutoQPointer& p) { QPointer::operator=(p); return *this; } - AutoQPointer& operator=(T* p) { QPointer::operator=(p); return *this; } +public: + AutoQPointer() : QPointer() {} + AutoQPointer(T *p) : QPointer(p) {} + AutoQPointer(const QPointer &p) : QPointer(p) {} + ~AutoQPointer() + { + delete this->data(); + } + AutoQPointer &operator=(const AutoQPointer &p) + { + QPointer::operator=(p); + return *this; + } + AutoQPointer &operator=(T *p) + { + QPointer::operator=(p); + return *this; + } }; #endif // AUTOQPOINTER_H -// vim: et sw=4: diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/CMakeLists.txt kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,45 +1,43 @@ include_directories( - ${QT_QTDBUS_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../shared ) ########### next target ############### -add_definitions(-DKDE_DEFAULT_DEBUG_AREA=5953) add_definitions(-DSETTINGS_NAMESPACE=Akonadi_KAlarm_Dir_Resource) set(kalarmdirresource_SRCS + kalarmdirresource_debug.cpp settingsdialog.cpp kalarmdirresource.cpp ../shared/kalarmresourcecommon.cpp ../shared/alarmtypewidget.cpp ) -install(FILES kalarmdirresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents") +install(FILES kalarmdirresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents") -kde4_add_ui_files(kalarmdirresource_SRCS settingsdialog.ui ../shared/alarmtypewidget.ui) -kde4_add_kcfg_files(kalarmdirresource_SRCS settings.kcfgc) +ki18n_wrap_ui(kalarmdirresource_SRCS settingsdialog.ui ../shared/alarmtypewidget.ui) +kconfig_add_kcfg_files(kalarmdirresource_SRCS settings.kcfgc) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/kalarmdirresource.kcfg org.kde.Akonadi.KAlarmDir.Settings) -qt4_add_dbus_adaptor(kalarmdirresource_SRCS +qt5_add_dbus_adaptor(kalarmdirresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.KAlarmDir.Settings.xml settings.h Akonadi_KAlarm_Dir_Resource::Settings kalarmdirsettingsadaptor KAlarmDirSettingsAdaptor) add_custom_target(kalarmdir_resource_xml ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.KAlarmDir.Settings.xml) -kde4_add_plugin(akonadi_kalarm_dir_resource ${kalarmdirresource_SRCS}) +add_executable(akonadi_kalarm_dir_resource ${kalarmdirresource_SRCS}) -if (Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_kalarm_dir_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) set_target_properties(akonadi_kalarm_dir_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.KAlarmDir") set_target_properties(akonadi_kalarm_dir_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi KAlarm Directory Resource") endif () target_link_libraries(akonadi_kalarm_dir_resource - ${KDEPIMLIBS_KALARMCAL_LIBS} - ${KDEPIMLIBS_AKONADI_KCAL_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KCALCORE_LIBS} - ${KDE4_KIO_LIBS} - ${QT_QTDBUS_LIBRARY} + KF5::AlarmCalendar + KF5::AkonadiCore + KF5::CalendarCore + KF5::AkonadiAgentBase + KF5::DBusAddons ) -install(TARGETS akonadi_kalarm_dir_resource DESTINATION ${PLUGIN_INSTALL_DIR}) +install(TARGETS akonadi_kalarm_dir_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/kalarmdirresource.cpp kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/kalarmdirresource.cpp --- kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/kalarmdirresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/kalarmdirresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,54 +24,52 @@ #include "kalarmdirresource.h" #include "kalarmresourcecommon.h" #include "autoqpointer.h" - #include "kalarmdirsettingsadaptor.h" #include "settingsdialog.h" #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include +#include #include #include #include #include #include +#include "kalarmdirresource_debug.h" using namespace Akonadi; using namespace KCalCore; using namespace Akonadi_KAlarm_Dir_Resource; using KAlarmResourceCommon::errorMessage; -static bool isFileValid(const QString& file); +static bool isFileValid(const QString &file); static const char warningFile[] = "WARNING_README.txt"; #define DEBUG_DATA \ -kDebug()<<"ID:Files:"; \ -foreach (const QString& id, mEvents.uniqueKeys()) { kDebug()<itemFetchScope().fetchFullPayload(); changeRecorder()->fetchCollection(true); - connect(KDirWatch::self(), SIGNAL(created(QString)), SLOT(fileCreated(QString))); - connect(KDirWatch::self(), SIGNAL(dirty(QString)), SLOT(fileChanged(QString))); - connect(KDirWatch::self(), SIGNAL(deleted(QString)), SLOT(fileDeleted(QString))); + connect(KDirWatch::self(), &KDirWatch::created, this, &KAlarmDirResource::fileCreated); + connect(KDirWatch::self(), &KDirWatch::dirty, this, &KAlarmDirResource::fileChanged); + connect(KDirWatch::self(), &KDirWatch::deleted, this, &KAlarmDirResource::fileDeleted); // Find the collection which this resource manages - CollectionFetchJob* job = new CollectionFetchJob(Collection::root(), CollectionFetchJob::FirstLevel); + CollectionFetchJob *job = new CollectionFetchJob(Collection::root(), CollectionFetchJob::FirstLevel); job->fetchScope().setResource(identifier()); - connect(job, SIGNAL(result(KJob*)), SLOT(collectionFetchResult(KJob*))); + connect(job, &CollectionFetchJob::result, this, &KAlarmDirResource::collectionFetchResult); QTimer::singleShot(0, this, SLOT(loadFiles())); } @@ -110,63 +108,57 @@ void KAlarmDirResource::aboutToQuit() { - mSettings->writeConfig(); + mSettings->save(); } /****************************************************************************** * Called when the collection fetch job completes. * Check the calendar files' compatibility statuses if pending. */ -void KAlarmDirResource::collectionFetchResult(KJob* j) +void KAlarmDirResource::collectionFetchResult(KJob *j) { - kDebug(); - if (j->error()) - kError() << "CollectionFetchJob error: " << j->errorString(); - else - { - CollectionFetchJob* job = static_cast(j); + qCDebug(KALARMDIRRESOURCE_LOG); + if (j->error()) { + qCritical() << "CollectionFetchJob error: " << j->errorString(); + } else { + CollectionFetchJob *job = static_cast(j); Collection::List collections = job->collections(); int count = collections.count(); - kDebug() << "Count:" << count; - if (!count) - kError() << "Cannot retrieve this resource's collection"; - else - { - if (count > 1) - kError() << "Multiple collections for this resource:" << count; - Collection& c(collections[0]); - kDebug() << "Id:" << c.id() << ", remote id:" << c.remoteId(); - if (!mCollectionFetched) - { + qCDebug(KALARMDIRRESOURCE_LOG) << "Count:" << count; + if (!count) { + qCritical() << "Cannot retrieve this resource's collection"; + } else { + if (count > 1) { + qCritical() << "Multiple collections for this resource:" << count; + } + Collection &c(collections[0]); + qCDebug(KALARMDIRRESOURCE_LOG) << "Id:" << c.id() << ", remote id:" << c.remoteId(); + if (!mCollectionFetched) { bool recreate = mSettings->path().isEmpty(); - if (!recreate) - { + if (!recreate) { // Remote ID could be path or URL, depending on which version // of Akonadi created it. QString rid = c.remoteId(); - KUrl url(mSettings->path()); + QUrl url = QUrl::fromLocalFile(mSettings->path()); if (!url.isLocalFile() - || (rid != url.toLocalFile() && rid != url.url() && rid != url.prettyUrl())) - { - kError() << "Collection remote ID does not match settings: changing settings"; + || (rid != url.toLocalFile() && rid != url.url() && rid != url.toDisplayString())) { + qCritical() << "Collection remote ID does not match settings: changing settings"; recreate = true; } } - if (recreate) - { + if (recreate) { // Initialising a resource which seems to have no stored // settings config file. Recreate the settings. - static Collection::Rights writableRights = Collection::CanChangeItem | Collection::CanCreateItem | Collection::CanDeleteItem; - kDebug() << "Recreating config for remote id:" << c.remoteId(); + static const Collection::Rights writableRights = Collection::CanChangeItem | Collection::CanCreateItem | Collection::CanDeleteItem; + qCDebug(KALARMDIRRESOURCE_LOG) << "Recreating config for remote id:" << c.remoteId(); mSettings->setPath(c.remoteId()); mSettings->setDisplayName(c.name()); mSettings->setAlarmTypes(c.contentMimeTypes()); mSettings->setReadOnly((c.rights() & writableRights) != writableRights); - mSettings->writeConfig(); + mSettings->save(); } mCollectionId = c.id(); - if (recreate) - { + if (recreate) { // Load items from the backend files now that their location is known loadFiles(true); } @@ -178,8 +170,7 @@ } } mCollectionFetched = true; - if (mWaitingToRetrieve) - { + if (mWaitingToRetrieve) { mWaitingToRetrieve = false; retrieveCollections(); } @@ -187,7 +178,7 @@ void KAlarmDirResource::configure(WId windowId) { - kDebug(); + qCDebug(KALARMDIRRESOURCE_LOG); // Keep note of the old configuration settings QString path = mSettings->path(); QString name = mSettings->displayName(); @@ -199,27 +190,20 @@ // the dialogue is still open. It prevents double deletion (both on // deletion of parent, and on return from this function). AutoQPointer dlg = new SettingsDialog(windowId, mSettings); - if (dlg->exec()) - { - if (path.isEmpty()) - { + if (dlg->exec()) { + if (path.isEmpty()) { // Creating a new resource clearCache(); // this deletes any existing collection loadFiles(true); synchronizeCollectionTree(); - } - else if (mSettings->path() != path) - { + } else if (mSettings->path() != path) { // Directory path change is not allowed for existing resources - emit configurationDialogRejected(); + Q_EMIT configurationDialogRejected(); return; - } - else - { + } else { bool modify = false; Collection c(mCollectionId); - if (mSettings->alarmTypes() != types) - { + if (mSettings->alarmTypes() != types) { // Settings have changed which might affect the alarm configuration initializeDirectory(); // should only be needed for new resource, but just in case ... CalEvent::Types newTypes = CalEvent::types(mSettings->alarmTypes()); @@ -229,25 +213,21 @@ modify = true; } if (mSettings->readOnly() != readOnly - || mSettings->displayName() != name) - { + || mSettings->displayName() != name) { // Need to change the collection's rights or name c.setRemoteId(directoryName()); setNameRights(c); modify = true; } - if (modify) - { + if (modify) { // Update the Akonadi server with the changes - CollectionModifyJob* job = new CollectionModifyJob(c); - connect(job, SIGNAL(result(KJob*)), SLOT(jobDone(KJob*))); + CollectionModifyJob *job = new CollectionModifyJob(c); + connect(job, &CollectionFetchJob::result, this, &KAlarmDirResource::jobDone); } } - emit configurationDialogAccepted(); - } - else - { - emit configurationDialogRejected(); + Q_EMIT configurationDialogAccepted(); + } else { + Q_EMIT configurationDialogRejected(); } } @@ -257,51 +237,43 @@ */ void KAlarmDirResource::changeAlarmTypes(CalEvent::Types removed) { -DEBUG_DATA; + DEBUG_DATA; const QString dirPath = directoryName(); - kDebug() << dirPath; + qCDebug(KALARMDIRRESOURCE_LOG) << dirPath; const QDir dir(dirPath); // Read and parse each file in turn QDirIterator it(dir); - while (it.hasNext()) - { + while (it.hasNext()) { it.next(); int removeIfInvalid = 0; QString fileEventId; const QString file = it.fileName(); - if (!isFileValid(file)) + if (!isFileValid(file)) { continue; + } QHash::iterator fit = mFileEventIds.find(file); - if (fit != mFileEventIds.end()) - { + if (fit != mFileEventIds.end()) { // The file is in the existing file list fileEventId = fit.value(); QHash::ConstIterator it = mEvents.constFind(fileEventId); - if (it != mEvents.constEnd()) - { + if (it != mEvents.constEnd()) { // And its event is in the existing events list - const EventFile& data = it.value(); - if (data.files[0] == file) - { + const EventFile &data = it.value(); + if (data.files[0] == file) { // It's the file for a used event - if (data.event.category() & removed) - { + if (data.event.category() & removed) { // The event's type is no longer wanted, so remove it deleteItem(data.event); removeEvent(data.event.id(), false); } continue; - } - else - { + } else { // The file's event is not currently used - load the // file and use its event if appropriate. removeIfInvalid = 0x03; // remove from mEvents and mFileEventIds } - } - else - { + } else { // The file's event isn't in the list of current valid // events - this shouldn't ever happen removeIfInvalid = 0x01; // remove from mFileEventIds @@ -310,18 +282,20 @@ // Load the file and use its event if appropriate. const QString path = filePath(file); - if (QFileInfo(path).isFile()) - { - if (createItemAndIndex(path, file)) + if (QFileInfo(path).isFile()) { + if (createItemAndIndex(path, file)) { continue; + } } // The event wasn't wanted, so remove from lists - if (removeIfInvalid & 0x01) + if (removeIfInvalid & 0x01) { mFileEventIds.erase(fit); - if (removeIfInvalid & 0x02) + } + if (removeIfInvalid & 0x02) { removeEventFile(fileEventId, file); + } } -DEBUG_DATA; + DEBUG_DATA; setCompatibility(); } @@ -335,68 +309,63 @@ */ void KAlarmDirResource::settingsChanged() { - kDebug(); + qCDebug(KALARMDIRRESOURCE_LOG); const QString display = mSettings->displayName(); - if (display != name()) + if (display != name()) { setName(display); + } const QString dirPath = mSettings->path(); - if (!dirPath.isEmpty()) - { + if (!dirPath.isEmpty()) { const bool monitoring = KDirWatch::self()->contains(dirPath); - if (monitoring && !mSettings->monitorFiles()) + if (monitoring && !mSettings->monitorFiles()) { KDirWatch::self()->removeDir(dirPath); - else if (!monitoring && mSettings->monitorFiles()) + } else if (!monitoring && mSettings->monitorFiles()) { KDirWatch::self()->addDir(dirPath, KDirWatch::WatchFiles); + } #if 0 - if (mSettings->monitorFiles() && !monitor) - { + if (mSettings->monitorFiles() && !monitor) { // Settings have changed which might affect the alarm configuration -kDebug()<<"Monitored changed"; + qCDebug(KALARMDIRRESOURCE_LOG) << "Monitored changed"; loadFiles(true); // synchronizeCollectionTree(); } #endif } - if (mSettings->updateStorageFormat()) - { + if (mSettings->updateStorageFormat()) { // This is a flag to request that the backend calendar storage format should // be updated to the current KAlarm format. KACalendar::Compat okCompat(KACalendar::Current | KACalendar::Convertible); - if (mCompatibility & ~okCompat) - kWarning() << "Either incompatible storage format or nothing to update"; - else if (mSettings->readOnly()) - kWarning() << "Cannot update storage format for a read-only resource"; - else - { + if (mCompatibility & ~okCompat) { + qCWarning(KALARMDIRRESOURCE_LOG) << "Either incompatible storage format or nothing to update"; + } else if (mSettings->readOnly()) { + qCWarning(KALARMDIRRESOURCE_LOG) << "Cannot update storage format for a read-only resource"; + } else { // Update the backend storage format to the current KAlarm format bool ok = true; - for (QHash::iterator it = mEvents.begin(); it != mEvents.end(); ++it) - { - KAEvent& event = it.value().event; - if (event.compatibility() == KACalendar::Convertible) - { - if (writeToFile(event)) + for (QHash::iterator it = mEvents.begin(); it != mEvents.end(); ++it) { + KAEvent &event = it.value().event; + if (event.compatibility() == KACalendar::Convertible) { + if (writeToFile(event)) { event.setCompatibility(KACalendar::Current); - else - { - kWarning() << "Error updating storage format for event id" << event.id(); + } else { + qCWarning(KALARMDIRRESOURCE_LOG) << "Error updating storage format for event id" << event.id(); ok = false; } } } - if (ok) - { + if (ok) { mCompatibility = KACalendar::Current; mVersion = KACalendar::CurrentFormat; const Collection c(mCollectionId); - if (c.isValid()) + if (c.isValid()) { KAlarmResourceCommon::setCollectionCompatibility(c, mCompatibility, mVersion); + } } } mSettings->setUpdateStorageFormat(false); - mSettings->writeConfig(); + mSettings->save(); } } @@ -407,9 +376,10 @@ bool KAlarmDirResource::loadFiles(bool sync) { const QString dirPath = directoryName(); - if (dirPath.isEmpty()) + if (dirPath.isEmpty()) { return false; - kDebug() << dirPath; + } + qCDebug(KALARMDIRRESOURCE_LOG) << dirPath; const QDir dir(dirPath); // Create the directory if it doesn't exist. @@ -422,83 +392,78 @@ // Set the resource display name to the configured name, else the directory // name, if not already set. QString display = mSettings->displayName(); - if (display.isEmpty() && (name().isEmpty() || name() == identifier())) + if (display.isEmpty() && (name().isEmpty() || name() == identifier())) { display = dir.dirName(); - if (!display.isEmpty()) + } + if (!display.isEmpty()) { setName(display); + } // Read and parse each file in turn QDirIterator it(dir); - while (it.hasNext()) - { + while (it.hasNext()) { it.next(); const QString file = it.fileName(); - if (isFileValid(file)) - { + if (isFileValid(file)) { const QString path = filePath(file); - if (QFileInfo(path).isFile()) - { + if (QFileInfo(path).isFile()) { const KAEvent event = loadFile(path, file); - if (event.isValid()) - { + if (event.isValid()) { addEventFile(event, file); mFileEventIds.insert(file, event.id()); } } } } -DEBUG_DATA; + DEBUG_DATA; setCompatibility(false); // don't write compatibility - no collection exists yet - if (mSettings->monitorFiles()) - { + if (mSettings->monitorFiles()) { // Monitor the directory for changes to the files - if (!KDirWatch::self()->contains(dirPath)) + if (!KDirWatch::self()->contains(dirPath)) { KDirWatch::self()->addDir(dirPath, KDirWatch::WatchFiles); + } } - if (sync) - { + if (sync) { // Ensure the Akonadi server is updated with the current list of events synchronize(); } - emit status(Idle); + Q_EMIT status(Idle); return true; } /****************************************************************************** * Load and parse data a single file in the directory. */ -KAEvent KAlarmDirResource::loadFile(const QString& path, const QString& file) +KAEvent KAlarmDirResource::loadFile(const QString &path, const QString &file) { - kDebug() << path; + qCDebug(KALARMDIRRESOURCE_LOG) << path; MemoryCalendar::Ptr calendar(new MemoryCalendar(QLatin1String("UTC"))); FileStorage::Ptr fileStorage(new FileStorage(calendar, path, new ICalFormat())); - if (!fileStorage->load()) - { - kWarning() << "Error loading" << path; + if (!fileStorage->load()) { + qCWarning(KALARMDIRRESOURCE_LOG) << "Error loading" << path; return KAEvent(); } const Event::List events = calendar->events(); - if ( events.isEmpty() ) - { - kDebug() << "Empty calendar in file" << path; + if (events.isEmpty()) { + qCDebug(KALARMDIRRESOURCE_LOG) << "Empty calendar in file" << path; return KAEvent(); } - if (events.count() > 1) - { - kWarning() << "Deleting" << events.count() - 1 << "excess events found in file" << path; - for (int i = 1; i < events.count(); ++i) + if (events.count() > 1) { + qCWarning(KALARMDIRRESOURCE_LOG) << "Deleting" << events.count() - 1 << "excess events found in file" << path; + for (int i = 1; i < events.count(); ++i) { calendar->deleteEvent(events[i]); + } } const Event::Ptr kcalEvent(events[0]); - if (kcalEvent->uid() != file) - kWarning() << "File" << path << ": event id differs from file name"; - if (kcalEvent->alarms().isEmpty()) - { - kWarning() << "File" << path << ": event contains no alarms"; + if (kcalEvent->uid() != file) { + qCWarning(KALARMDIRRESOURCE_LOG) << "File" << path << ": event id differs from file name"; + } + if (kcalEvent->alarms().isEmpty()) { + qCWarning(KALARMDIRRESOURCE_LOG) << "File" << path << ": event contains no alarms"; return KAEvent(); } // Convert event in memory to current KAlarm format if possible @@ -506,14 +471,12 @@ KACalendar::Compat compat = KAlarmResourceCommon::getCompatibility(fileStorage, version); KAEvent event(kcalEvent); const QString mime = CalEvent::mimeType(event.category()); - if (mime.isEmpty()) - { - kWarning() << "KAEvent has no usable alarms:" << event.id(); + if (mime.isEmpty()) { + qCWarning(KALARMDIRRESOURCE_LOG) << "KAEvent has no usable alarms:" << event.id(); return KAEvent(); } - if (!mSettings->alarmTypes().contains(mime)) - { - kWarning() << "KAEvent has wrong alarm type for resource:" << mime; + if (!mSettings->alarmTypes().contains(mime)) { + qCWarning(KALARMDIRRESOURCE_LOG) << "KAEvent has wrong alarm type for resource:" << mime; return KAEvent(); } event.setCompatibility(compat); @@ -525,15 +488,13 @@ * event ID. * Reply = new event, or invalid if none. */ -KAEvent KAlarmDirResource::loadNextFile(const QString& eventId, const QString& file) +KAEvent KAlarmDirResource::loadNextFile(const QString &eventId, const QString &file) { QString nextFile = file; - while (!nextFile.isEmpty()) - { + while (!nextFile.isEmpty()) { // There is another file with the same ID - load it const KAEvent event = loadFile(filePath(nextFile), nextFile); - if (event.isValid()) - { + if (event.isValid()) { addEventFile(event, nextFile); mFileEventIds.insert(nextFile, event.id()); return event; @@ -550,14 +511,13 @@ * Set the event into a new item's payload, and signal its retrieval by calling * itemRetrieved(newitem). */ -bool KAlarmDirResource::retrieveItem(const Akonadi::Item& item, const QSet&) +bool KAlarmDirResource::retrieveItem(const Akonadi::Item &item, const QSet &) { const QString rid = item.remoteId(); QHash::ConstIterator it = mEvents.constFind(rid); - if (it == mEvents.constEnd()) - { - kWarning() << "Event not found:" << rid; - emit error(errorMessage(KAlarmResourceCommon::UidNotFound, rid)); + if (it == mEvents.constEnd()) { + qCWarning(KALARMDIRRESOURCE_LOG) << "Event not found:" << rid; + Q_EMIT error(errorMessage(KAlarmResourceCommon::UidNotFound, rid)); return false; } @@ -571,25 +531,27 @@ * Called when an item has been added to the collection. * Store the event in a file, and set its Akonadi remote ID to the KAEvent's UID. */ -void KAlarmDirResource::itemAdded(const Akonadi::Item& item, const Akonadi::Collection&) +void KAlarmDirResource::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &) { - kDebug() << item.id(); - if (cancelIfReadOnly()) + qCDebug(KALARMDIRRESOURCE_LOG) << item.id(); + if (cancelIfReadOnly()) { return; + } KAEvent event; - if (item.hasPayload()) + if (item.hasPayload()) { event = item.payload(); - if (!event.isValid()) - { + } + if (!event.isValid()) { changeProcessed(); return; } event.setCompatibility(KACalendar::Current); setCompatibility(); - if (!writeToFile(event)) + if (!writeToFile(event)) { return; + } addEventFile(event, event.id()); @@ -603,54 +565,54 @@ * Called when an item has been changed. * Store the changed event in a file. */ -void KAlarmDirResource::itemChanged(const Akonadi::Item& item, const QSet&) +void KAlarmDirResource::itemChanged(const Akonadi::Item &item, const QSet &) { - kDebug() << item.id() << ", remote ID:" << item.remoteId(); - if (cancelIfReadOnly()) + qCDebug(KALARMDIRRESOURCE_LOG) << item.id() << ", remote ID:" << item.remoteId(); + if (cancelIfReadOnly()) { return; + } QHash::iterator it = mEvents.find(item.remoteId()); - if (it != mEvents.end()) - { - if (it.value().event.isReadOnly()) - { - kWarning() << "Event is read only:" << item.remoteId(); + if (it != mEvents.end()) { + if (it.value().event.isReadOnly()) { + qCWarning(KALARMDIRRESOURCE_LOG) << "Event is read only:" << item.remoteId(); cancelTask(errorMessage(KAlarmResourceCommon::EventReadOnly, item.remoteId())); return; } - if (it.value().event.compatibility() != KACalendar::Current) - { - kWarning() << "Event not in current format:" << item.remoteId(); + if (it.value().event.compatibility() != KACalendar::Current) { + qCWarning(KALARMDIRRESOURCE_LOG) << "Event not in current format:" << item.remoteId(); cancelTask(errorMessage(KAlarmResourceCommon::EventNotCurrentFormat, item.remoteId())); return; } } KAEvent event; - if (item.hasPayload()) - event = item.payload(); - if (!event.isValid()) - { + if (item.hasPayload()) { + event = item.payload(); + } + if (!event.isValid()) { changeProcessed(); return; } #if 0 QString errorMsg; KAEvent event = KAlarmResourceCommon::checkItemChanged(item, errorMsg); - if (!event.isValid()) - { - if (errorMsg.isEmpty()) + if (!event.isValid()) { + if (errorMsg.isEmpty()) { changeProcessed(); - else + } else { cancelTask(errorMsg); + } return; } #endif event.setCompatibility(KACalendar::Current); - if (mCompatibility != KACalendar::Current) + if (mCompatibility != KACalendar::Current) { setCompatibility(); + } - if (!writeToFile(event)) + if (!writeToFile(event)) { return; + } it.value().event = event; @@ -661,11 +623,12 @@ * Called when an item has been deleted. * Delete the item's file. */ -void KAlarmDirResource::itemRemoved(const Akonadi::Item& item) +void KAlarmDirResource::itemRemoved(const Akonadi::Item &item) { - kDebug() << item.id(); - if (cancelIfReadOnly()) + qCDebug(KALARMDIRRESOURCE_LOG) << item.id(); + if (cancelIfReadOnly()) { return; + } QString nextFile; removeEvent(item.remoteId(), true); @@ -676,34 +639,33 @@ /****************************************************************************** * Remove an event from the indexes, and optionally delete its file. */ -void KAlarmDirResource::removeEvent(const QString& eventId, bool deleteFile) +void KAlarmDirResource::removeEvent(const QString &eventId, bool deleteFile) { QString file = eventId; QString nextFile; QHash::iterator it = mEvents.find(eventId); - if (it != mEvents.end()) - { + if (it != mEvents.end()) { file = it.value().files[0]; nextFile = removeEventFile(eventId, file); mFileEventIds.remove(file); -DEBUG_DATA; + DEBUG_DATA; } - if (deleteFile) + if (deleteFile) { QFile::remove(filePath(file)); + } loadNextFile(eventId, nextFile); // load any other file with the same event ID } /****************************************************************************** -* If the resource is read-only, cancel the task and emit an error. +* If the resource is read-only, cancel the task andQ_EMIT an error. * Reply = true if cancelled. */ bool KAlarmDirResource::cancelIfReadOnly() { - if (mSettings->readOnly()) - { - kWarning() << "Calendar is read-only:" << directoryName(); - emit error(i18nc("@info", "Trying to write to a read-only calendar: '%1'", directoryName())); + if (mSettings->readOnly()) { + qCWarning(KALARMDIRRESOURCE_LOG) << "Calendar is read-only:" << directoryName(); + Q_EMIT error(i18nc("@info", "Trying to write to a read-only calendar: '%1'", directoryName())); cancelTask(); return true; } @@ -713,16 +675,15 @@ /****************************************************************************** * Write an event to a file. The file name is the event's id. */ -bool KAlarmDirResource::writeToFile(const KAEvent& event) +bool KAlarmDirResource::writeToFile(const KAEvent &event) { Event::Ptr kcalEvent(new Event); event.updateKCalEvent(kcalEvent, KAEvent::UID_SET); MemoryCalendar::Ptr calendar(new MemoryCalendar(QLatin1String("UTC"))); KACalendar::setKAlarmVersion(calendar); // set the KAlarm custom property - if (!calendar->addIncidence(kcalEvent)) - { - kError() << "Error adding event with id" << event.id(); - emit error(errorMessage(KAlarmResourceCommon::CalendarAdd, event.id())); + if (!calendar->addIncidence(kcalEvent)) { + qCritical() << "Error adding event with id" << event.id(); + Q_EMIT error(errorMessage(KAlarmResourceCommon::CalendarAdd, event.id())); cancelTask(); return false; } @@ -730,11 +691,10 @@ mChangedFiles += event.id(); // suppress KDirWatch processing for this write const QString path = filePath(event.id()); - kDebug() << event.id() << " File:" << path; + qCDebug(KALARMDIRRESOURCE_LOG) << event.id() << " File:" << path; FileStorage::Ptr fileStorage(new FileStorage(calendar, path, new ICalFormat())); - if (!fileStorage->save()) - { - emit error(i18nc("@info", "Failed to save event file: %1", path)); + if (!fileStorage->save()) { + Q_EMIT error(i18nc("@info", "Failed to save event file: %1", path)); cancelTask(); return false; } @@ -747,15 +707,14 @@ void KAlarmDirResource::retrieveCollections() { QString rid = mSettings->path(); - if (!mCollectionFetched && rid.isEmpty()) - { + if (!mCollectionFetched && rid.isEmpty()) { // The resource config seems to be missing. Execute this function // once the collection config has been set up. mWaitingToRetrieve = true; return; } - kDebug(); + qCDebug(KALARMDIRRESOURCE_LOG); Collection c; c.setParentCollection(Collection::root()); c.setRemoteId(rid); @@ -774,20 +733,17 @@ * Set the collection's name and rights. * It is the caller's responsibility to notify the Akonadi server. */ -void KAlarmDirResource::setNameRights(Collection& c) +void KAlarmDirResource::setNameRights(Collection &c) { - kDebug(); + qCDebug(KALARMDIRRESOURCE_LOG); const QString display = mSettings->displayName(); c.setName(display.isEmpty() ? name() : display); - EntityDisplayAttribute* attr = c.attribute(Collection::AddIfMissing); + EntityDisplayAttribute *attr = c.attribute(Collection::AddIfMissing); attr->setDisplayName(name()); attr->setIconName(QLatin1String("kalarm")); - if (mSettings->readOnly()) - { + if (mSettings->readOnly()) { c.setRights(Collection::CanChangeCollection); - } - else - { + } else { Collection::Rights rights = Collection::ReadOnly; rights |= Collection::CanChangeItem; rights |= Collection::CanCreateItem; @@ -795,7 +751,7 @@ rights |= Collection::CanChangeCollection; c.setRights(rights); } - kDebug()<<"end"; + qCDebug(KALARMDIRRESOURCE_LOG) << "end"; } /****************************************************************************** @@ -808,10 +764,10 @@ * payload have changed, or the Item has any new Attributes, the Akonadi * storage is updated. */ -void KAlarmDirResource::retrieveItems(const Akonadi::Collection& collection) +void KAlarmDirResource::retrieveItems(const Akonadi::Collection &collection) { mCollectionId = collection.id(); // note the one and only collection for this resource - kDebug() << "Collection id:" << mCollectionId; + qCDebug(KALARMDIRRESOURCE_LOG) << "Collection id:" << mCollectionId; // Set the collection's compatibility status KAlarmResourceCommon::setCollectionCompatibility(collection, mCompatibility, mVersion); @@ -821,17 +777,16 @@ // Retrieve events Item::List items; - foreach (const EventFile& data, mEvents) - { - const KAEvent& event = data.event; + foreach (const EventFile &data, mEvents) { + const KAEvent &event = data.event; const QString mime = CalEvent::mimeType(event.category()); - if (mime.isEmpty()) - { - kWarning() << "KAEvent has no alarms:" << event.id(); + if (mime.isEmpty()) { + qCWarning(KALARMDIRRESOURCE_LOG) << "KAEvent has no alarms:" << event.id(); continue; // event has no usable alarms } - if (!mimeTypes.contains(mime)) - continue; // restrict alarms returned to the defined types + if (!mimeTypes.contains(mime)) { + continue; // restrict alarms returned to the defined types + } Item item(mime); item.setRemoteId(event.id()); @@ -846,18 +801,18 @@ * Called when the collection has been changed. * Set its display name if that has changed. */ -void KAlarmDirResource::collectionChanged(const Akonadi::Collection& collection) +void KAlarmDirResource::collectionChanged(const Akonadi::Collection &collection) { - kDebug(); + qCDebug(KALARMDIRRESOURCE_LOG); // If the collection has a new display name, set the resource's display // name the same, and save to the settings. const QString newName = collection.displayName(); - if (!newName.isEmpty() && newName != name()) + if (!newName.isEmpty() && newName != name()) { setName(newName); - if (newName != mSettings->displayName()) - { + } + if (newName != mSettings->displayName()) { mSettings->setDisplayName(newName); - mSettings->writeConfig(); + mSettings->save(); } changeCommitted(collection); @@ -866,69 +821,59 @@ /****************************************************************************** * Called when a file has been created in the directory. */ -void KAlarmDirResource::fileCreated(const QString& path) +void KAlarmDirResource::fileCreated(const QString &path) { - kDebug() << path; - if (path == directoryName()) - { + qCDebug(KALARMDIRRESOURCE_LOG) << path; + if (path == directoryName()) { // The directory has been created. Load all files in it, and // tell the Akonadi server to create an Item for each event. loadFiles(true); - foreach (const EventFile& data, mEvents) - { + foreach (const EventFile &data, mEvents) { createItem(data.event); } - } - else - { + } else { const QString file = fileName(path); int i = mChangedFiles.indexOf(file); - if (i >= 0) - mChangedFiles.removeAt(i); // the file was updated by this resource - else if (isFileValid(file)) - { - if (createItemAndIndex(path, file)) + if (i >= 0) { + mChangedFiles.removeAt(i); // the file was updated by this resource + } else if (isFileValid(file)) { + if (createItemAndIndex(path, file)) { setCompatibility(); -DEBUG_DATA; + } + DEBUG_DATA; } } } - /****************************************************************************** * Called when a file has changed in the directory. */ -void KAlarmDirResource::fileChanged(const QString& path) +void KAlarmDirResource::fileChanged(const QString &path) { - if (path != directoryName()) - { - kDebug() << path; + if (path != directoryName()) { + qCDebug(KALARMDIRRESOURCE_LOG) << path; const QString file = fileName(path); int i = mChangedFiles.indexOf(file); - if (i >= 0) - mChangedFiles.removeAt(i); // the file was updated by this resource - else if (isFileValid(file)) - { + if (i >= 0) { + mChangedFiles.removeAt(i); // the file was updated by this resource + } else if (isFileValid(file)) { QString nextFile, oldId; KAEvent oldEvent; const KAEvent event = loadFile(path, file); // Get the file's old event ID QHash::iterator fit = mFileEventIds.find(file); - if (fit != mFileEventIds.end()) - { + if (fit != mFileEventIds.end()) { oldId = fit.value(); - if (event.id() != oldId) - { + if (event.id() != oldId) { // The file's event ID has changed - remove the old event nextFile = removeEventFile(oldId, file, &oldEvent); - if (event.isValid()) + if (event.isValid()) { fit.value() = event.id(); - else + } else { mFileEventIds.erase(fit); + } } - } - else if (event.isValid()) - { + } else if (event.isValid()) { // The file didn't contain an event before. Save details of the new event. mFileEventIds.insert(file, event.id()); } @@ -938,17 +883,17 @@ setCompatibility(); // Tell the Akonadi server to amend the Item for the event - if (event.id() != oldId) - { - if (e.isValid()) + if (event.id() != oldId) { + if (e.isValid()) { modifyItem(e); - else + } else { deleteItem(oldEvent); + } createItem(event); // create a new Item for the new event ID - } - else + } else { modifyItem(event); -DEBUG_DATA; + } + DEBUG_DATA; } } } @@ -956,29 +901,24 @@ /****************************************************************************** * Called when a file has been deleted in the directory. */ -void KAlarmDirResource::fileDeleted(const QString& path) +void KAlarmDirResource::fileDeleted(const QString &path) { - kDebug() << path; - if (path == directoryName()) - { + qCDebug(KALARMDIRRESOURCE_LOG) << path; + if (path == directoryName()) { // The directory has been deleted mEvents.clear(); mFileEventIds.clear(); // Tell the Akonadi server to delete all Items in the collection Collection c(mCollectionId); - ItemDeleteJob* job = new ItemDeleteJob(c); - connect(job, SIGNAL(result(KJob*)), SLOT(jobDone(KJob*))); - } - else - { + ItemDeleteJob *job = new ItemDeleteJob(c); + connect(job, &CollectionFetchJob::result, this, &KAlarmDirResource::jobDone); + } else { // A single file has been deleted const QString file = fileName(path); - if (isFileValid(file)) - { + if (isFileValid(file)) { QHash::iterator fit = mFileEventIds.find(file); - if (fit != mFileEventIds.end()) - { + if (fit != mFileEventIds.end()) { QString eventId = fit.value(); KAEvent event; QString nextFile = removeEventFile(eventId, file, &event); @@ -987,17 +927,14 @@ KAEvent e = loadNextFile(eventId, nextFile); // load any other file with the same event ID setCompatibility(); - if (e.isValid()) - { + if (e.isValid()) { // Tell the Akonadi server to amend the Item for the event modifyItem(e); - } - else - { + } else { // Tell the Akonadi server to delete the Item for the event deleteItem(event); } -DEBUG_DATA; + DEBUG_DATA; } } } @@ -1007,14 +944,12 @@ * Tell the Akonadi server to create an Item for a given file's event, and add * it to the indexes. */ -bool KAlarmDirResource::createItemAndIndex(const QString& path, const QString& file) +bool KAlarmDirResource::createItemAndIndex(const QString &path, const QString &file) { const KAEvent event = loadFile(path, file); - if (event.isValid()) - { + if (event.isValid()) { // Tell the Akonadi server to create an Item for the event - if (createItem(event)) - { + if (createItem(event)) { addEventFile(event, file); mFileEventIds.insert(file, event.id()); @@ -1027,63 +962,62 @@ /****************************************************************************** * Tell the Akonadi server to create an Item for a given event. */ -bool KAlarmDirResource::createItem(const KAEvent& event) +bool KAlarmDirResource::createItem(const KAEvent &event) { Item item; - if (!event.setItemPayload(item, mSettings->alarmTypes())) - { - kWarning() << "Invalid mime type for collection"; + if (!event.setItemPayload(item, mSettings->alarmTypes())) { + qCWarning(KALARMDIRRESOURCE_LOG) << "Invalid mime type for collection"; return false; } Collection c(mCollectionId); item.setParentCollection(c); item.setRemoteId(event.id()); - ItemCreateJob* job = new ItemCreateJob(item, c); - connect(job, SIGNAL(result(KJob*)), SLOT(jobDone(KJob*))); + ItemCreateJob *job = new ItemCreateJob(item, c); + connect(job, &CollectionFetchJob::result, this, &KAlarmDirResource::jobDone); return true; } /****************************************************************************** * Tell the Akonadi server to amend the Item for a given event. */ -bool KAlarmDirResource::modifyItem(const KAEvent& event) +bool KAlarmDirResource::modifyItem(const KAEvent &event) { Item item; - if (!event.setItemPayload(item, mSettings->alarmTypes())) - { - kWarning() << "Invalid mime type for collection"; + if (!event.setItemPayload(item, mSettings->alarmTypes())) { + qCWarning(KALARMDIRRESOURCE_LOG) << "Invalid mime type for collection"; return false; } Collection c(mCollectionId); item.setParentCollection(c); item.setRemoteId(event.id()); - ItemModifyJob* job = new ItemModifyJob(item); + ItemModifyJob *job = new ItemModifyJob(item); job->disableRevisionCheck(); - connect(job, SIGNAL(result(KJob*)), SLOT(jobDone(KJob*))); + connect(job, &CollectionFetchJob::result, this, &KAlarmDirResource::jobDone); return true; } /****************************************************************************** * Tell the Akonadi server to delete the Item for a given event. */ -void KAlarmDirResource::deleteItem(const KAEvent& event) +void KAlarmDirResource::deleteItem(const KAEvent &event) { Item item(CalEvent::mimeType(event.category())); Collection c(mCollectionId); item.setParentCollection(c); item.setRemoteId(event.id()); - ItemDeleteJob* job = new ItemDeleteJob(item); - connect(job, SIGNAL(result(KJob*)), SLOT(jobDone(KJob*))); + ItemDeleteJob *job = new ItemDeleteJob(item); + connect(job, &CollectionFetchJob::result, this, &KAlarmDirResource::jobDone); } /****************************************************************************** * Called when a collection or item job has completed. * Checks for any error. */ -void KAlarmDirResource::jobDone(KJob* j) +void KAlarmDirResource::jobDone(KJob *j) { - if (j->error()) - kError() << j->metaObject()->className() << "error:" << j->errorString(); + if (j->error()) { + qCritical() << j->metaObject()->className() << "error:" << j->errorString(); + } } /****************************************************************************** @@ -1092,21 +1026,19 @@ */ void KAlarmDirResource::initializeDirectory() const { - kDebug(); + qCDebug(KALARMDIRRESOURCE_LOG); const QDir dir(directoryName()); const QString dirPath = dir.absolutePath(); // If folder does not exist, create it - if (!dir.exists()) - { - kDebug() << "Creating" << dirPath; + if (!dir.exists()) { + qCDebug(KALARMDIRRESOURCE_LOG) << "Creating" << dirPath; QDir::root().mkpath(dirPath); } // Check whether warning file is in place... QFile file(dirPath + QDir::separator() + warningFile); - if (!file.exists()) - { + if (!file.exists()) { // ... if not, create it file.open(QIODevice::WriteOnly); file.write("Important Warning!!!\n" @@ -1121,7 +1053,7 @@ return mSettings->path(); } -QString KAlarmDirResource::filePath(const QString& file) const +QString KAlarmDirResource::filePath(const QString &file) const { return mSettings->path() + QDir::separator() + file; } @@ -1129,13 +1061,15 @@ /****************************************************************************** * Strip the directory path from a file name. */ -QString KAlarmDirResource::fileName(const QString& path) const +QString KAlarmDirResource::fileName(const QString &path) const { const QFileInfo fi(path); - if (fi.isDir() || fi.isBundle()) + if (fi.isDir() || fi.isBundle()) { return QString(); - if (fi.path() == mSettings->path()) + } + if (fi.path() == mSettings->path()) { return fi.fileName(); + } return path; } @@ -1149,45 +1083,42 @@ const KACalendar::Compat oldCompatibility = mCompatibility; const int oldVersion = mVersion; - if (mEvents.isEmpty()) + if (mEvents.isEmpty()) { mCompatibility = KACalendar::Current; - else - { + } else { mCompatibility = KACalendar::Unknown; - foreach (const EventFile& data, mEvents) - { - const KAEvent& event = data.event; + foreach (const EventFile &data, mEvents) { + const KAEvent &event = data.event; mCompatibility |= event.compatibility(); - if ((mCompatibility & AllCompat) == AllCompat) + if ((mCompatibility & AllCompat) == AllCompat) { break; + } } } mVersion = (mCompatibility == KACalendar::Current) ? KACalendar::CurrentFormat : KACalendar::MixedFormat; - if (writeAttr && (mCompatibility != oldCompatibility || mVersion != oldVersion)) - { + if (writeAttr && (mCompatibility != oldCompatibility || mVersion != oldVersion)) { const Collection c(mCollectionId); - if (c.isValid()) + if (c.isValid()) { KAlarmResourceCommon::setCollectionCompatibility(c, mCompatibility, mVersion); + } } } /****************************************************************************** * Add an event/file combination to the mEvents map. */ -void KAlarmDirResource::addEventFile(const KAEvent& event, const QString& file) +void KAlarmDirResource::addEventFile(const KAEvent &event, const QString &file) { - if (event.isValid()) - { + if (event.isValid()) { QHash::iterator it = mEvents.find(event.id()); - if (it != mEvents.end()) - { - EventFile& data = it.value(); + if (it != mEvents.end()) { + EventFile &data = it.value(); data.event = event; data.files.removeAll(file); // in case it isn't the first file data.files.prepend(file); - } - else + } else { mEvents.insert(event.id(), EventFile(event, QStringList(file))); + } } } @@ -1195,20 +1126,21 @@ * Remove an event ID/file combination from the mEvents map. * Reply = next file with the same event ID. */ -QString KAlarmDirResource::removeEventFile(const QString& eventId, const QString& file, KAEvent* event) +QString KAlarmDirResource::removeEventFile(const QString &eventId, const QString &file, KAEvent *event) { QHash::iterator it = mEvents.find(eventId); - if (it != mEvents.end()) - { - if (event) + if (it != mEvents.end()) { + if (event) { *event = it.value().event; + } it.value().files.removeAll(file); - if (!it.value().files.isEmpty()) + if (!it.value().files.isEmpty()) { return it.value().files[0]; + } mEvents.erase(it); - } - else if (event) + } else if (event) { *event = KAEvent(); + } return QString(); } @@ -1216,14 +1148,11 @@ * Check whether a file is to be ignored. * Reply = false if file is to be ignored. */ -bool isFileValid(const QString& file) +bool isFileValid(const QString &file) { return !file.isEmpty() - && !file.startsWith(QLatin1Char('.')) && !file.endsWith(QLatin1Char('~')) - && file != QLatin1String(warningFile); + && !file.startsWith(QLatin1Char('.')) && !file.endsWith(QLatin1Char('~')) + && file != QLatin1String(warningFile); } -AKONADI_AGENT_FACTORY(KAlarmDirResource, akonadi_kalarm_dir_resource) - - -// vim: et sw=4: +AKONADI_RESOURCE_MAIN(KAlarmDirResource) diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/kalarmdirresource_debug.cpp kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/kalarmdirresource_debug.cpp --- kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/kalarmdirresource_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/kalarmdirresource_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 "kalarmdirresource_debug.h" +Q_LOGGING_CATEGORY(KALARMDIRRESOURCE_LOG, "log_kalarmdirresource") + diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/kalarmdirresource_debug.h kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/kalarmdirresource_debug.h --- kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/kalarmdirresource_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/kalarmdirresource_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 KALARMDIRRESOURCE_DEBUG_H +#define KALARMDIRRESOURCE_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(KALARMDIRRESOURCE_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/kalarmdirresource.desktop kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/kalarmdirresource.desktop --- kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/kalarmdirresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/kalarmdirresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,6 @@ [Desktop Entry] Name=KAlarm Directory +Name[bg]=Папка за KAlarm Name[bs]=KAlarm direktorij Name[ca]=Directori del KAlarm Name[ca@valencia]=Directori del KAlarm @@ -42,6 +43,7 @@ Name[zh_CN]=KAlarm 目录 Name[zh_TW]=KAlarm 目錄 Comment=Loads data from a local KAlarm folder +Comment[bg]=Зареждане на данни от локална папка KAlarm Comment[bs]=Čita podatke iz lokalnog KAlarm direktorija Comment[ca]=Carrega les dades des d'una carpeta KAlarm local Comment[ca@valencia]=Carrega dades des d'una carpeta KAlarm local @@ -89,4 +91,3 @@ X-Akonadi-MimeTypes=application/x-vnd.kde.alarm,application/x-vnd.kde.alarm.active,application/x-vnd.kde.alarm.archived,application/x-vnd.kde.alarm.template X-Akonadi-Capabilities=Resource X-Akonadi-Identifier=akonadi_kalarm_dir_resource -X-Akonadi-LaunchMethod=AgentServer diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/kalarmdirresource.h kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/kalarmdirresource.h --- kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/kalarmdirresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/kalarmdirresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,82 +24,86 @@ #include -#include +#include #include -namespace Akonadi_KAlarm_Dir_Resource { class Settings; } +namespace Akonadi_KAlarm_Dir_Resource +{ +class Settings; +} using namespace KAlarmCal; class KAlarmDirResource : public Akonadi::ResourceBase, public Akonadi::AgentBase::Observer { - Q_OBJECT - public: - explicit KAlarmDirResource(const QString& id); - ~KAlarmDirResource(); - - public Q_SLOTS: - virtual void configure(WId windowId); - virtual void aboutToQuit(); - - protected Q_SLOTS: - void retrieveCollections(); - void retrieveItems(const Akonadi::Collection&); - bool retrieveItem(const Akonadi::Item&, const QSet& parts); - - protected: - virtual void collectionChanged(const Akonadi::Collection&); - virtual void itemAdded(const Akonadi::Item&, const Akonadi::Collection&); - virtual void itemChanged(const Akonadi::Item&, const QSet& parts); - virtual void itemRemoved(const Akonadi::Item&); - - private Q_SLOTS: - void settingsChanged(); - void fileCreated(const QString& path); - void fileChanged(const QString& path); - void fileDeleted(const QString& path); - void loadFiles() { loadFiles(true); } - void collectionFetchResult(KJob*); - void jobDone(KJob*); - - private: - void changeAlarmTypes(CalEvent::Types removed); - bool loadFiles(bool sync); - KAEvent loadFile(const QString& path, const QString& file); - KAEvent loadNextFile(const QString& eventId, const QString& file); - QString directoryName() const; - QString filePath(const QString& file) const; - QString fileName(const QString& path) const; - void initializeDirectory() const; - void setNameRights(Akonadi::Collection&); - bool cancelIfReadOnly(); - bool writeToFile(const KAEvent&); - void setCompatibility(bool writeAttr = true); - void removeEvent(const QString& eventId, bool deleteFile); - void addEventFile(const KAEvent&, const QString& file); - QString removeEventFile(const QString& eventId, const QString& file, KAEvent* = 0); - bool createItemAndIndex(const QString& path, const QString& file); - bool createItem(const KAEvent&); - bool modifyItem(const KAEvent&); - void deleteItem(const KAEvent&); - - struct EventFile // data to be indexed by event ID - { - EventFile() {} - EventFile(const KAEvent& e, const QStringList& f) : event(e), files(f) {} - KAEvent event; - QStringList files; // files containing this event ID, in-use one first - }; - QHash mEvents; // cached alarms and file names, indexed by ID - QHash mFileEventIds; // alarm IDs, indexed by file name - Akonadi_KAlarm_Dir_Resource::Settings* mSettings; - Akonadi::Collection::Id mCollectionId; // ID of this resource's collection - KACalendar::Compat mCompatibility; - int mVersion; // calendar format version - QStringList mChangedFiles; // files being written to - bool mCollectionFetched; // mCollectionId has been initialised - bool mWaitingToRetrieve; // retrieveCollections() needs to be called + Q_OBJECT +public: + explicit KAlarmDirResource(const QString &id); + ~KAlarmDirResource(); + +public Q_SLOTS: + void configure(WId windowId) Q_DECL_OVERRIDE; + void aboutToQuit() Q_DECL_OVERRIDE; + +protected Q_SLOTS: + void retrieveCollections() Q_DECL_OVERRIDE; + void retrieveItems(const Akonadi::Collection &) Q_DECL_OVERRIDE; + bool retrieveItem(const Akonadi::Item &, const QSet &parts) Q_DECL_OVERRIDE; + +protected: + void collectionChanged(const Akonadi::Collection &) Q_DECL_OVERRIDE; + void itemAdded(const Akonadi::Item &, const Akonadi::Collection &) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &, const QSet &parts) Q_DECL_OVERRIDE; + void itemRemoved(const Akonadi::Item &) Q_DECL_OVERRIDE; + +private Q_SLOTS: + void settingsChanged(); + void fileCreated(const QString &path); + void fileChanged(const QString &path); + void fileDeleted(const QString &path); + void loadFiles() + { + loadFiles(true); + } + void collectionFetchResult(KJob *); + void jobDone(KJob *); + +private: + void changeAlarmTypes(CalEvent::Types removed); + bool loadFiles(bool sync); + KAEvent loadFile(const QString &path, const QString &file); + KAEvent loadNextFile(const QString &eventId, const QString &file); + QString directoryName() const; + QString filePath(const QString &file) const; + QString fileName(const QString &path) const; + void initializeDirectory() const; + void setNameRights(Akonadi::Collection &); + bool cancelIfReadOnly(); + bool writeToFile(const KAEvent &); + void setCompatibility(bool writeAttr = true); + void removeEvent(const QString &eventId, bool deleteFile); + void addEventFile(const KAEvent &, const QString &file); + QString removeEventFile(const QString &eventId, const QString &file, KAEvent * = Q_NULLPTR); + bool createItemAndIndex(const QString &path, const QString &file); + bool createItem(const KAEvent &); + bool modifyItem(const KAEvent &); + void deleteItem(const KAEvent &); + + struct EventFile { // data to be indexed by event ID + EventFile() {} + EventFile(const KAEvent &e, const QStringList &f) : event(e), files(f) {} + KAEvent event; + QStringList files; // files containing this event ID, in-use one first + }; + QHash mEvents; // cached alarms and file names, indexed by ID + QHash mFileEventIds; // alarm IDs, indexed by file name + Akonadi_KAlarm_Dir_Resource::Settings *mSettings; + Akonadi::Collection::Id mCollectionId; // ID of this resource's collection + KACalendar::Compat mCompatibility; + int mVersion; // calendar format version + QStringList mChangedFiles; // files being written to + bool mCollectionFetched; // mCollectionId has been initialised + bool mWaitingToRetrieve; // retrieveCollections() needs to be called }; #endif -// vim: et sw=4: diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/settingsdialog.cpp kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/settingsdialog.cpp --- kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/settingsdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/settingsdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,40 +26,56 @@ #include #include +#include #include +#include +#include +#include namespace Akonadi_KAlarm_Dir_Resource { -SettingsDialog::SettingsDialog(WId windowId, Settings* settings) - : KDialog(), - mSettings(settings), - mReadOnlySelected(false) -{ - ui.setupUi(mainWidget()); +SettingsDialog::SettingsDialog(WId windowId, Settings *settings) + : QDialog(), + mSettings(settings), + mReadOnlySelected(false) +{ + QWidget *mainWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); + ui.setupUi(mainWidget); mTypeSelector = new AlarmTypeWidget(ui.tab, ui.tabLayout); - ui.ktabwidget->setTabBarHidden(true); + ui.ktabwidget->tabBar()->hide(); ui.kcfg_Path->setMode(KFile::LocalOnly | KFile::Directory); - setButtons(Ok | Cancel); - setCaption(i18nc("@title", "Configure Calendar")); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + mOkButton = buttonBox->button(QDialogButtonBox::Ok); + mOkButton->setDefault(true); + mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &SettingsDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &SettingsDialog::reject); + mainLayout->addWidget(buttonBox); + setWindowTitle(i18nc("@title", "Configure Calendar")); - if (windowId) + if (windowId) { KWindowSystem::setMainWindow(this, windowId); + } // Make directory path read-only if the resource already exists - KUrl path(mSettings->path()); + QUrl path = QUrl::fromLocalFile(mSettings->path()); ui.kcfg_Path->setUrl(path); - if (!path.isEmpty()) + if (!path.isEmpty()) { ui.kcfg_Path->setEnabled(false); + } mTypeSelector->setAlarmTypes(CalEvent::types(mSettings->alarmTypes())); mManager = new KConfigDialogManager(this, mSettings); mManager->updateWidgets(); - connect(this, SIGNAL(okClicked()), SLOT(save())); - connect(ui.kcfg_Path, SIGNAL(textChanged(QString)), SLOT(textChanged())); - connect(ui.kcfg_ReadOnly, SIGNAL(clicked(bool)), SLOT(readOnlyClicked(bool))); - connect(mTypeSelector, SIGNAL(changed()), SLOT(validate())); + connect(mOkButton, &QPushButton::clicked, this, &SettingsDialog::save); + connect(ui.kcfg_Path, &KUrlRequester::textChanged, this, &SettingsDialog::textChanged); + connect(ui.kcfg_ReadOnly, &QCheckBox::clicked, this, &SettingsDialog::readOnlyClicked); + connect(mTypeSelector, &AlarmTypeWidget::changed, this, &SettingsDialog::validate); QTimer::singleShot(0, this, SLOT(validate())); } @@ -69,7 +85,7 @@ mManager->updateSettings(); mSettings->setPath(ui.kcfg_Path->url().toLocalFile()); mSettings->setAlarmTypes(CalEvent::mimeTypes(mTypeSelector->alarmTypes())); - mSettings->writeConfig(); + mSettings->save(); } void SettingsDialog::readOnlyClicked(bool set) @@ -81,8 +97,7 @@ { bool oldReadOnly = ui.kcfg_ReadOnly->isEnabled(); validate(); - if (ui.kcfg_ReadOnly->isEnabled() && !oldReadOnly) - { + if (ui.kcfg_ReadOnly->isEnabled() && !oldReadOnly) { // If read-only was only set earlier by validating the input path, // and the path is now ok to be read-write, clear the read-only status. ui.kcfg_ReadOnly->setChecked(mReadOnlySelected); @@ -93,43 +108,37 @@ { bool enableOk = false; // At least one alarm type must be selected - if (mTypeSelector->alarmTypes() != CalEvent::EMPTY) - { + if (mTypeSelector->alarmTypes() != CalEvent::EMPTY) { // The entered URL must be valid and local - const KUrl currentUrl = ui.kcfg_Path->url(); - if (currentUrl.isEmpty()) + const QUrl currentUrl = ui.kcfg_Path->url(); + if (currentUrl.isEmpty()) { ui.kcfg_ReadOnly->setEnabled(true); - else if (currentUrl.isLocalFile()) - { + } else if (currentUrl.isLocalFile()) { QFileInfo file(currentUrl.toLocalFile()); // It must either be an existing directory, or in a writable // directory, and it must not be an existing file. - if (file.exists()) - { - if (file.isDir()) - enableOk = true; // it's an existing directory - } - else - { + if (file.exists()) { + if (file.isDir()) { + enableOk = true; // it's an existing directory + } + } else { // Specified directory doesn't already exist. // Find the first level of parent directory which exists, // and check that it is writable. - for ( ; ; ) - { + for (; ;) { file.setFile(file.dir().absolutePath()); // get parent dir's file info - if (file.exists()) - { - if (file.isDir() && file.isWritable()) - enableOk = true; // it's possible to create the directory + if (file.exists()) { + if (file.isDir() && file.isWritable()) { + enableOk = true; // it's possible to create the directory + } break; } } } } } - enableButton(Ok, enableOk); + mOkButton->setEnabled(enableOk); } } -// vim: et sw=4: diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/settingsdialog.h kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/settingsdialog.h --- kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/settingsdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/settingsdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -27,8 +27,8 @@ #include -#include - +#include +class QPushButton; using namespace KAlarmCal; class KConfigDialogManager; @@ -39,30 +39,30 @@ class Settings; -class SettingsDialog : public KDialog +class SettingsDialog : public QDialog { - Q_OBJECT - public: - SettingsDialog(WId windowId, Settings*); - void setAlarmTypes(CalEvent::Types); - CalEvent::Types alarmTypes() const; - - private Q_SLOTS: - void save(); - void validate(); - void textChanged(); - void readOnlyClicked(bool); - - private: - Ui::SettingsDialog ui; - AlarmTypeWidget* mTypeSelector; - KConfigDialogManager* mManager; - Akonadi_KAlarm_Dir_Resource::Settings* mSettings; - bool mReadOnlySelected; // read-only was set by user (not by validate()) + Q_OBJECT +public: + SettingsDialog(WId windowId, Settings *); + void setAlarmTypes(CalEvent::Types); + CalEvent::Types alarmTypes() const; + +private Q_SLOTS: + void save(); + void validate(); + void textChanged(); + void readOnlyClicked(bool); + +private: + Ui::SettingsDialog ui; + AlarmTypeWidget *mTypeSelector; + QPushButton *mOkButton; + KConfigDialogManager *mManager; + Akonadi_KAlarm_Dir_Resource::Settings *mSettings; + bool mReadOnlySelected; // read-only was set by user (not by validate()) }; } #endif // KALARMDIR_SETTINGSDIALOG_H -// vim: et sw=4: diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/settingsdialog.ui kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/settingsdialog.ui --- kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/settingsdialog.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/settingsdialog.ui 2015-08-10 21:01:02.000000000 +0000 @@ -17,7 +17,7 @@ - + 0 @@ -132,12 +132,6 @@ - KTabWidget - QTabWidget -
ktabwidget.h
- 1 -
- KLineEdit QLineEdit
klineedit.h
diff -Nru kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/settings.kcfgc kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/settings.kcfgc --- kdepim-runtime-4.14.6/resources/kalarm/kalarmdir/settings.kcfgc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/kalarmdir/settings.kcfgc 2015-08-10 21:01:02.000000000 +0000 @@ -5,4 +5,4 @@ SetUserTexts=true Singleton=false GlobalEnums=true -Namespace=Akonadi_KAlarm_Dir_Resource +NameSpace=Akonadi_KAlarm_Dir_Resource diff -Nru kdepim-runtime-4.14.6/resources/kalarm/shared/alarmtyperadiowidget.cpp kdepim-runtime-15.08.0/resources/kalarm/shared/alarmtyperadiowidget.cpp --- kdepim-runtime-4.14.6/resources/kalarm/shared/alarmtyperadiowidget.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/shared/alarmtyperadiowidget.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,8 +21,7 @@ #include "alarmtyperadiowidget.h" - -AlarmTypeRadioWidget::AlarmTypeRadioWidget(QWidget* parent) +AlarmTypeRadioWidget::AlarmTypeRadioWidget(QWidget *parent) : Akonadi::SingleFileValidatingWidget(parent) { ui.setupUi(this); @@ -31,37 +30,39 @@ mButtonGroup->addButton(ui.activeRadio); mButtonGroup->addButton(ui.archivedRadio); mButtonGroup->addButton(ui.templateRadio); - connect(ui.activeRadio, SIGNAL(toggled(bool)), SIGNAL(changed())); - connect(ui.archivedRadio, SIGNAL(toggled(bool)), SIGNAL(changed())); - connect(ui.templateRadio, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(ui.activeRadio, &QRadioButton::toggled, this, &AlarmTypeRadioWidget::changed); + connect(ui.archivedRadio, &QRadioButton::toggled, this, &AlarmTypeRadioWidget::changed); + connect(ui.templateRadio, &QRadioButton::toggled, this, &AlarmTypeRadioWidget::changed); } void AlarmTypeRadioWidget::setAlarmType(CalEvent::Type type) { - switch (type) - { - case CalEvent::ACTIVE: - ui.activeRadio->setChecked(true); - break; - case CalEvent::ARCHIVED: - ui.archivedRadio->setChecked(true); - break; - case CalEvent::TEMPLATE: - ui.templateRadio->setChecked(true); - break; - default: - break; + switch (type) { + case CalEvent::ACTIVE: + ui.activeRadio->setChecked(true); + break; + case CalEvent::ARCHIVED: + ui.archivedRadio->setChecked(true); + break; + case CalEvent::TEMPLATE: + ui.templateRadio->setChecked(true); + break; + default: + break; } } CalEvent::Type AlarmTypeRadioWidget::alarmType() const { - if (ui.activeRadio->isChecked()) + if (ui.activeRadio->isChecked()) { return CalEvent::ACTIVE; - if (ui.archivedRadio->isChecked()) + } + if (ui.archivedRadio->isChecked()) { return CalEvent::ARCHIVED; - if (ui.templateRadio->isChecked()) + } + if (ui.templateRadio->isChecked()) { return CalEvent::TEMPLATE; + } return CalEvent::EMPTY; } @@ -70,4 +71,3 @@ return static_cast(mButtonGroup->checkedButton()); } -// vim: et sw=4: diff -Nru kdepim-runtime-4.14.6/resources/kalarm/shared/alarmtyperadiowidget.h kdepim-runtime-15.08.0/resources/kalarm/shared/alarmtyperadiowidget.h --- kdepim-runtime-4.14.6/resources/kalarm/shared/alarmtyperadiowidget.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/shared/alarmtyperadiowidget.h 2015-08-10 21:01:02.000000000 +0000 @@ -33,18 +33,17 @@ class AlarmTypeRadioWidget : public Akonadi::SingleFileValidatingWidget { - Q_OBJECT - public: - explicit AlarmTypeRadioWidget(QWidget* parent = 0); - void setAlarmType(CalEvent::Type); - CalEvent::Type alarmType() const; - virtual bool validate() const; + Q_OBJECT +public: + explicit AlarmTypeRadioWidget(QWidget *parent = Q_NULLPTR); + void setAlarmType(CalEvent::Type); + CalEvent::Type alarmType() const; + bool validate() const Q_DECL_OVERRIDE; - private: - Ui::AlarmTypeRadioWidget ui; - QButtonGroup* mButtonGroup; +private: + Ui::AlarmTypeRadioWidget ui; + QButtonGroup *mButtonGroup; }; #endif // ALARMTYPERADIOWIDGET_H -// vim: et sw=4: diff -Nru kdepim-runtime-4.14.6/resources/kalarm/shared/alarmtypewidget.cpp kdepim-runtime-15.08.0/resources/kalarm/shared/alarmtypewidget.cpp --- kdepim-runtime-4.14.6/resources/kalarm/shared/alarmtypewidget.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/shared/alarmtypewidget.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,37 +21,41 @@ #include "alarmtypewidget.h" - -AlarmTypeWidget::AlarmTypeWidget(QWidget* parent, QLayout* layout) +AlarmTypeWidget::AlarmTypeWidget(QWidget *parent, QLayout *layout) : QWidget() { ui.setupUi(parent); layout->addWidget(ui.groupBox); - connect(ui.activeCheckBox, SIGNAL(toggled(bool)), SIGNAL(changed())); - connect(ui.archivedCheckBox, SIGNAL(toggled(bool)), SIGNAL(changed())); - connect(ui.templateCheckBox, SIGNAL(toggled(bool)), SIGNAL(changed())); + connect(ui.activeCheckBox, &QCheckBox::toggled, this, &AlarmTypeWidget::changed); + connect(ui.archivedCheckBox, &QCheckBox::toggled, this, &AlarmTypeWidget::changed); + connect(ui.templateCheckBox, &QCheckBox::toggled, this, &AlarmTypeWidget::changed); } void AlarmTypeWidget::setAlarmTypes(CalEvent::Types types) { - if (types & CalEvent::ACTIVE) + if (types & CalEvent::ACTIVE) { ui.activeCheckBox->setChecked(true); - if (types & CalEvent::ARCHIVED) + } + if (types & CalEvent::ARCHIVED) { ui.archivedCheckBox->setChecked(true); - if (types & CalEvent::TEMPLATE) + } + if (types & CalEvent::TEMPLATE) { ui.templateCheckBox->setChecked(true); + } } CalEvent::Types AlarmTypeWidget::alarmTypes() const { CalEvent::Types types = CalEvent::EMPTY; - if (ui.activeCheckBox->isChecked()) + if (ui.activeCheckBox->isChecked()) { types |= CalEvent::ACTIVE; - if (ui.archivedCheckBox->isChecked()) + } + if (ui.archivedCheckBox->isChecked()) { types |= CalEvent::ARCHIVED; - if (ui.templateCheckBox->isChecked()) + } + if (ui.templateCheckBox->isChecked()) { types |= CalEvent::TEMPLATE; + } return types; } -// vim: et sw=4: diff -Nru kdepim-runtime-4.14.6/resources/kalarm/shared/alarmtypewidget.h kdepim-runtime-15.08.0/resources/kalarm/shared/alarmtypewidget.h --- kdepim-runtime-4.14.6/resources/kalarm/shared/alarmtypewidget.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/shared/alarmtypewidget.h 2015-08-10 21:01:02.000000000 +0000 @@ -30,19 +30,18 @@ class AlarmTypeWidget : public QWidget { - Q_OBJECT - public: - AlarmTypeWidget(QWidget* parent, QLayout* layout); - void setAlarmTypes(CalEvent::Types); - CalEvent::Types alarmTypes() const; + Q_OBJECT +public: + AlarmTypeWidget(QWidget *parent, QLayout *layout); + void setAlarmTypes(CalEvent::Types); + CalEvent::Types alarmTypes() const; - signals: - void changed(); +Q_SIGNALS: + void changed(); - private: - Ui::AlarmTypeWidget ui; +private: + Ui::AlarmTypeWidget ui; }; #endif // ALARMTYPEWIDGET_H -// vim: et sw=4: diff -Nru kdepim-runtime-4.14.6/resources/kalarm/shared/kalarmresourcecommon.cpp kdepim-runtime-15.08.0/resources/kalarm/shared/kalarmresourcecommon.cpp --- kdepim-runtime-4.14.6/resources/kalarm/shared/kalarmresourcecommon.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/shared/kalarmresourcecommon.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,33 +24,32 @@ #include #include -#include -#include +#include +#include -#include -#include +#include +#include -#include -#include -#include +#include + +#include +#include using namespace Akonadi; using namespace KCalCore; using namespace KAlarmCal; - class Private : public QObject { - Q_OBJECT - public: - Private(QObject* parent) : QObject(parent) {} - static Private* mInstance; + Q_OBJECT +public: + Private(QObject *parent) : QObject(parent) {} + static Private *mInstance; - private slots: - void modifyCollectionJobDone(KJob*); +private Q_SLOTS: + void modifyCollectionJobDone(KJob *); }; -Private* Private::mInstance = 0; - +Private *Private::mInstance = Q_NULLPTR; namespace KAlarmResourceCommon { @@ -58,37 +57,35 @@ /****************************************************************************** * Perform common initialisation for KAlarm resources. */ -void initialise(QObject* parent) +void initialise(QObject *parent) { // Create an object which can receive signals. - if (!Private::mInstance) + if (!Private::mInstance) { Private::mInstance = new Private(parent); + } // Set a default start-of-day time for date-only alarms. - KAEvent::setStartOfDay(QTime(0,0,0)); + KAEvent::setStartOfDay(QTime(0, 0, 0)); AttributeFactory::registerAttribute(); AttributeFactory::registerAttribute(); - - KGlobal::locale()->insertCatalog(QLatin1String("akonadi_kalarm_resource")); } /****************************************************************************** * Find the compatibility of an existing calendar file, and convert it in * memory to the current KAlarm format (if possible). */ -KACalendar::Compat getCompatibility(const FileStorage::Ptr& fileStorage, int& version) +KACalendar::Compat getCompatibility(const FileStorage::Ptr &fileStorage, int &version) { QString versionString; version = KACalendar::updateVersion(fileStorage, versionString); - switch (version) - { - case KACalendar::IncompatibleFormat: - return KACalendar::Incompatible; // calendar is not in KAlarm format, or is in a future format - case KACalendar::CurrentFormat: - return KACalendar::Current; // calendar is in the current format - default: - return KACalendar::Convertible; // calendar is in an out of date format + switch (version) { + case KACalendar::IncompatibleFormat: + return KACalendar::Incompatible; // calendar is not in KAlarm format, or is in a future format + case KACalendar::CurrentFormat: + return KACalendar::Current; // calendar is in the current format + default: + return KACalendar::Convertible; // calendar is in an out of date format } } @@ -97,12 +94,13 @@ * The caller should signal its retrieval by calling itemRetrieved(newitem). * NOTE: the caller must set the event's compatibility beforehand. */ -Item retrieveItem(const Akonadi::Item& item, KAEvent& event) +Item retrieveItem(const Akonadi::Item &item, KAEvent &event) { QString mime = CalEvent::mimeType(event.category()); event.setItemId(item.id()); - if (item.hasAttribute()) + if (item.hasAttribute()) { event.setCommandError(item.attribute()->commandError()); + } Item newItem = item; newItem.setMimeType(mime); @@ -116,16 +114,15 @@ * = invalid if error, in which case errorMsg contains the error message * (which will be empty if the KAEvent is simply invalid). */ -KAEvent checkItemChanged(const Akonadi::Item& item, QString& errorMsg) +KAEvent checkItemChanged(const Akonadi::Item &item, QString &errorMsg) { KAEvent event; - if (item.hasPayload()) + if (item.hasPayload()) { event = item.payload(); - if (event.isValid()) - { - if (item.remoteId() != event.id()) - { - kWarning() << "Item ID" << item.remoteId() << "differs from payload ID" << event.id(); + } + if (event.isValid()) { + if (item.remoteId() != event.id()) { + qWarning() << "Item ID" << item.remoteId() << "differs from payload ID" << event.id(); errorMsg = i18nc("@info", "Item ID %1 differs from payload ID %2.", item.remoteId(), event.id()); return KAEvent(); } @@ -142,47 +139,45 @@ * are written by the application. This avoids the resource and application * overwriting each other's changes if they attempt simultaneous updates. */ -void setCollectionCompatibility(const Collection& collection, KACalendar::Compat compatibility, int version) +void setCollectionCompatibility(const Collection &collection, KACalendar::Compat compatibility, int version) { - kDebug() << collection.id() << "->" << compatibility << version; + qDebug() << collection.id() << "->" << compatibility << version; // Update the CompatibilityAttribute value only. // Note that we can't supply 'collection' to CollectionModifyJob since // that may also contain the CollectionAttribute value, which is read-only // for the resource. So create a new Collection instance and only set a // value for CompatibilityAttribute. Collection col(collection.id()); - if (!collection.isValid()) - { + if (!collection.isValid()) { col.setParentCollection(collection.parentCollection()); col.setRemoteId(collection.remoteId()); } - CompatibilityAttribute* attr = col.attribute(Collection::AddIfMissing); + CompatibilityAttribute *attr = col.attribute(Collection::AddIfMissing); attr->setCompatibility(compatibility); attr->setVersion(version); Q_ASSERT(Private::mInstance); - CollectionModifyJob* job = new CollectionModifyJob(col, Private::mInstance->parent()); + CollectionModifyJob *job = new CollectionModifyJob(col, Private::mInstance->parent()); Private::mInstance->connect(job, SIGNAL(result(KJob*)), SLOT(modifyCollectionJobDone(KJob*))); } /****************************************************************************** * Return an error message common to more than one resource. */ -QString errorMessage(ErrorCode code, const QString& param) +QString errorMessage(ErrorCode code, const QString ¶m) { - switch (code) - { - case UidNotFound: - return i18nc("@info", "Event with uid '%1' not found.", param); - case NotCurrentFormat: - return i18nc("@info", "Calendar is not in current KAlarm format."); - case EventNotCurrentFormat: - return i18nc("@info", "Event with uid '%1' is not in current KAlarm format.", param); - case EventNoAlarms: - return i18nc("@info", "Event with uid '%1' contains no usable alarms.", param); - case EventReadOnly: - return i18nc("@info", "Event with uid '%1' is read only", param); - case CalendarAdd: - return i18nc("@info", "Failed to add event with uid '%1' to calendar", param); + switch (code) { + case UidNotFound: + return i18nc("@info", "Event with uid '%1' not found.", param); + case NotCurrentFormat: + return i18nc("@info", "Calendar is not in current KAlarm format."); + case EventNotCurrentFormat: + return i18nc("@info", "Event with uid '%1' is not in current KAlarm format.", param); + case EventNoAlarms: + return i18nc("@info", "Event with uid '%1' contains no usable alarms.", param); + case EventReadOnly: + return i18nc("@info", "Event with uid '%1' is read only", param); + case CalendarAdd: + return i18nc("@info", "Failed to add event with uid '%1' to calendar", param); } return QString(); } @@ -192,16 +187,14 @@ /****************************************************************************** * Called when a collection modification job has completed, to report any error. */ -void Private::modifyCollectionJobDone(KJob* j) +void Private::modifyCollectionJobDone(KJob *j) { - kDebug(); - if (j->error()) - { - Collection collection = static_cast(j)->collection(); - kError() << "Error: collection id" << collection.id() << ":" << j->errorString(); + qDebug(); + if (j->error()) { + Collection collection = static_cast(j)->collection(); + qCritical() << "Error: collection id" << collection.id() << ":" << j->errorString(); } } #include "kalarmresourcecommon.moc" -// vim: et sw=4: diff -Nru kdepim-runtime-4.14.6/resources/kalarm/shared/kalarmresourcecommon.h kdepim-runtime-15.08.0/resources/kalarm/shared/kalarmresourcecommon.h --- kdepim-runtime-4.14.6/resources/kalarm/shared/kalarmresourcecommon.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kalarm/shared/kalarmresourcecommon.h 2015-08-10 21:01:02.000000000 +0000 @@ -27,34 +27,36 @@ #include -namespace KCalCore { class FileStorage; } -namespace Akonadi { - class Collection; - class Item; +namespace KCalCore +{ +class FileStorage; +} +namespace Akonadi +{ +class Collection; +class Item; } using namespace KAlarmCal; namespace KAlarmResourceCommon { - void initialise(QObject* parent); +void initialise(QObject *parent); // void customizeConfigDialog(SingleFileResourceConfigDialog*); - KACalendar::Compat getCompatibility(const KCalCore::FileStorage::Ptr&, int& version); - Akonadi::Item retrieveItem(const Akonadi::Item&, KAEvent&); - KAEvent checkItemChanged(const Akonadi::Item&, QString& errorMsg); - void setCollectionCompatibility(const Akonadi::Collection&, KACalendar::Compat, int version); - - enum ErrorCode - { - UidNotFound, - NotCurrentFormat, - EventNotCurrentFormat, - EventNoAlarms, - EventReadOnly, - CalendarAdd - }; - QString errorMessage(ErrorCode, const QString& param = QString()); +KACalendar::Compat getCompatibility(const KCalCore::FileStorage::Ptr &, int &version); +Akonadi::Item retrieveItem(const Akonadi::Item &, KAEvent &); +KAEvent checkItemChanged(const Akonadi::Item &, QString &errorMsg); +void setCollectionCompatibility(const Akonadi::Collection &, KACalendar::Compat, int version); + +enum ErrorCode { + UidNotFound, + NotCurrentFormat, + EventNotCurrentFormat, + EventNoAlarms, + EventReadOnly, + CalendarAdd +}; +QString errorMessage(ErrorCode, const QString ¶m = QString()); } #endif // KALARMRESOURCECOMMON_H -// vim: et sw=4: diff -Nru kdepim-runtime-4.14.6/resources/kcal/CMakeLists.txt kdepim-runtime-15.08.0/resources/kcal/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/kcal/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kcal/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -add_definitions( - -DKRESOURCES_DEPRECATED= - -DKABC_DEPRECATED= - -DKCAL_DEPRECATED= -) -# This one won't be needed when CMake 2.8.13 is depended on. -add_definitions( - -DKRESOURCES_DEPRECATED_EXPORT=KRESOURCES_EXPORT - -DKABC_DEPRECATED_EXPORT=KABC_EXPORT - -DKCAL_DEPRECATED_EXPORT=KCAL_EXPORT -) - -include_directories( - ${kdepim-runtime_SOURCE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} - ${Boost_INCLUDE_DIR} -) - -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - - -########### next target ############### - -set( kcalresource_SRCS - kcalresource.cpp - ../kabc/kresourceassistant.cpp -) - -install( FILES kcalresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) - - -kde4_add_executable(akonadi_kcal_resource ${kcalresource_SRCS}) - -target_link_libraries(akonadi_kcal_resource ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_AKONADI_KCAL_LIBS} ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${KDE4_KDECORE_LIBS} ${KDEPIMLIBS_KCAL_LIBS} ${KDE4_KIO_LIBS}) - -install(TARGETS akonadi_kcal_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/kcal/kcalresource.cpp kdepim-runtime-15.08.0/resources/kcal/kcalresource.cpp --- kdepim-runtime-4.14.6/resources/kcal/kcalresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kcal/kcalresource.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,695 +0,0 @@ -/* - Copyright (c) 2008-2009 Kevin Krammer - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "kcalresource.h" -#include "resources/kabc/kresourceassistant.h" - -#include -#include -#include - -#include - -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include - -typedef boost::shared_ptr IncidencePtr; - -using namespace Akonadi; - -static const char progName[] = "KCalResource"; -static const char progVersion[] = "0.9"; - -KCalResource::KCalResource( const QString &id ) - : ResourceBase( id ), - mManager( new KCal::CalendarResourceManager( QLatin1String( "calendar" ) ) ), - mResource( 0 ), - mMimeVisitor( new IncidenceMimeTypeVisitor() ), - mFullItemRetrieve( false ), - mDelayedSaveTimer( new QTimer( this ) ), - mIncidenceAssigner( new KCal::AssignmentVisitor() ) -{ - KGlobal::locale()->insertCatalog( QLatin1String( "akonadi_kresourceassistant" ) ); - - // setup for UID generation - const QString prodId = QLatin1String( "-//Akonadi//NONSGML KDE Compatibility Resource %1//EN" ); - KCal::CalFormat::setApplication( QLatin1String( progName ), prodId.arg( progVersion ) ); - - connect( this, SIGNAL(reloadConfiguration()), SLOT(reloadConfig()) ); - - connect( mDelayedSaveTimer, SIGNAL(timeout()), this, SLOT(delayedSaveCalendar()) ); - - changeRecorder()->itemFetchScope().fetchFullPayload(); - changeRecorder()->fetchCollection( true ); - - mDelayedSaveTimer->setSingleShot( true ); -} - -KCalResource::~KCalResource() -{ - delete mMimeVisitor; - delete mIncidenceAssigner; -} - -void KCalResource::configure( WId windowId ) -{ - if ( mResource != 0 ) { - emit status( Running, - i18nc( "@info:status", "Changing calendar plugin configuration" ) ); - KRES::ConfigDialog dlg( 0, QLatin1String( "calendar" ), mResource ); - if ( windowId ) - KWindowSystem::setMainWindow( &dlg, windowId ); - if ( dlg.exec() ) { - setName( mResource->resourceName() ); - mManager->writeConfig( KGlobal::config().data() ); - - emit configurationDialogAccepted(); - } else { - emit configurationDialogRejected(); - } - - emit status( Idle, QString() ); - // TODO: need to react on name changes, but do we need to react on data changes? - // as a workaround lets sync the collection tree - synchronizeCollectionTree(); - return; - } - - emit status( Running, - i18nc( "@info:status", "Acquiring calendar plugin configuration" ) ); - - KResourceAssistant kresAssistant( QLatin1String( "Calendar" ) ); - KWindowSystem::setMainWindow( &kresAssistant, windowId ); - - connect( &kresAssistant, SIGNAL(error(QString)), - this, SIGNAL(error(QString)) ); - - if ( kresAssistant.exec() != QDialog::Accepted ) { - emit status( NotConfigured, i18nc( "@info:status", "No KDE calendar plugin configured yet" ) ); - emit configurationDialogRejected(); - return; - } - - emit configurationDialogAccepted(); - - mResource = dynamic_cast( kresAssistant.resource() ); - Q_ASSERT( mResource != 0 ); - - mManager->add( mResource ); - mManager->writeConfig( KGlobal::config().data() ); - - if ( !openConfiguration() ) { - const QString message = i18nc( "@info:status", "Initialization based on newly created configuration failed." ); - emit error( message ); - emit status( NotConfigured, message ); - return; - } - - emit status( Running, i18nc( "@info:status", "Loading calendar" ) ); - - // signals emitted by initialLoadingFinished() or loadingError() - if ( !mResource->load() ) { - kError() << "Resource::load() failed"; - } -} - -void KCalResource::retrieveCollections() -{ - kDebug(); - if ( mResource == 0 ) { - kError() << "No KCal resource"; - - const QString message = i18nc( "@info:status", "No KDE calendar plugin configured yet" ); - emit error( message ); - - emit status( NotConfigured, message ); - return; - } - - Collection topLevelCollection; - topLevelCollection.setParentCollection( Collection::root() ); - topLevelCollection.setRemoteId( mResource->identifier() ); - topLevelCollection.setName( mResource->resourceName() ); - - EntityDisplayAttribute* attr = - topLevelCollection.attribute( Collection::AddIfMissing ); - attr->setDisplayName( mResource->resourceName() ); - attr->setIconName( QLatin1String( "office-calendar" ) ); - - QStringList mimeTypes; - mimeTypes << QLatin1String( "text/calendar" ); - mimeTypes += mMimeVisitor->allMimeTypes(); - - Collection::Rights readOnlyRights; - - Collection::Rights readWriteRights; - readWriteRights |= Collection::CanCreateItem; - readWriteRights |= Collection::CanChangeItem; - readWriteRights |= Collection::CanDeleteItem; - - if ( mResource->canHaveSubresources() ) { - mimeTypes << Collection::mimeType(); - - readWriteRights |= Collection::CanCreateCollection; - readWriteRights |= Collection::CanChangeCollection; - readWriteRights |= Collection::CanDeleteCollection; - } - - topLevelCollection.setContentMimeTypes( mimeTypes ); - topLevelCollection.setRights( mResource->readOnly() ? readOnlyRights : readWriteRights ); - - Collection::List list; - list << topLevelCollection; - - const QStringList subResources = mResource->subresources(); - kDebug() << "subResources" << subResources; - foreach ( const QString &subResource, subResources ) { - // TODO check with KOrganizer how it handles subresources - Collection childCollection; - childCollection.setParentCollection( topLevelCollection ); - childCollection.setRemoteId( subResource ); - childCollection.setName( mResource->labelForSubresource( subResource ) ); - - attr = childCollection.attribute( Collection::AddIfMissing ); - attr->setDisplayName( childCollection.name() ); - - const QString type = mResource->subresourceType( subResource ); - - if ( !type.isEmpty() ) { - QStringList childMimeTypes( Collection::mimeType() ); - childMimeTypes << QLatin1String( "application/x-vnd.akonadi.calendar." ) + type; - childCollection.setContentMimeTypes( childMimeTypes ); - - if ( type == QLatin1String( "journal" ) ) - attr->setIconName( QLatin1String( "view-pim-journal" ) ); - else if ( type == QLatin1String( "todo" ) ) - attr->setIconName( QLatin1String( "view-pim-tasks" ) ); - else - attr->setIconName( QLatin1String( "office-calendar" ) ); - } else { - attr->setIconName( QLatin1String( "office-calendar" ) ); - childCollection.setContentMimeTypes( mimeTypes ); - } - - // TODO we have no API for adding incidences to specific sub resources, so we should - // not tell Akonadi adding that items is allowed - childCollection.setRights( mResource->readOnly() ? readOnlyRights : readWriteRights ); - - list << childCollection; - } - - collectionsRetrieved( list ); -} - -void KCalResource::retrieveItems( const Akonadi::Collection &collection ) -{ - kDebug(); - if ( mResource == 0 ) { - kError() << "No KCal resource"; - - const QString message = i18nc( "@info:status", "No KDE calendar plugin configured yet" ); - emit error( message ); - - emit status( NotConfigured, message ); - return; - } - - Item::List items; - - const KCal::Incidence::List incidenceList = mResource->rawIncidences(); - foreach ( KCal::Incidence *incidence, incidenceList ) { - const QString subResource = mResource->subresourceIdentifier( incidence ); - if ( subResource == collection.remoteId() || - ( subResource.isEmpty() && collection.parentCollection() == Collection::root() ) ) { - Item item( mMimeVisitor->mimeType( incidence ) ); - item.setRemoteId( incidence->uid() ); - if ( mFullItemRetrieve ) - item.setPayload( IncidencePtr( incidence->clone() ) ); - items << item; - } - } - - itemsRetrieved( items ); -} - -bool KCalResource::retrieveItem( const Akonadi::Item &item, const QSet &parts ) -{ - kDebug() << "item id=" << item.id() << ", remoteId=" << item.remoteId() - << "mimeType=" << item.mimeType() << "parts=" << parts; - - if ( mResource == 0 ) { - kError() << "No KCal resource"; - - const QString message = i18nc( "@info:status", "No KDE calendar plugin configured yet" ); - emit error( message ); - - emit status( NotConfigured, message ); - return false; - } - - const QString rid = item.remoteId(); - - KCal::Incidence *incidence = mResource->incidence( rid ); - if ( incidence == 0 ) { - kError() << "No incidence with uid" << rid; - emit error( i18nc( "@info:status", - "Request for data of a specific calendar entry failed " - "because there is no such entry" ) ); - return false; - } - - Item i( item ); - i.setMimeType( mMimeVisitor->mimeType( incidence ) ); - i.setPayload( IncidencePtr( incidence->clone() ) ); - itemRetrieved( i ); - - return true; -} - -void KCalResource::aboutToQuit() -{ - mManager->writeConfig( KGlobal::config().data() ); - - if ( mResource ) - mResource->save(); -} - -void KCalResource::doSetOnline( bool online ) -{ - kDebug() << "online=" << online << ", isOnline=" << isOnline(); - if ( online ) - reloadConfig(); - else - closeConfiguration(); - - ResourceBase::doSetOnline( online ); -} - -void KCalResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection& collection ) -{ - kDebug() << "item id=" << item.id() << ", remoteId=" << item.remoteId() - << "mimeType=" << item.mimeType(); - - if ( mResource == 0 ) { - kError() << "Resource not fully operational yet"; - emit status( NotConfigured, i18nc( "@info:status", "No KDE calendar plugin configured yet" ) ); - return; - } - - Q_UNUSED( collection ); - - if ( item.hasPayload() ) { - IncidencePtr incidencePtr = item.payload(); - if ( incidencePtr->uid().isEmpty() ) { - const QString uid = KCal::CalFormat::createUniqueId(); - incidencePtr->setUid( uid ); - } - - KCal::Incidence *incidence = incidencePtr->clone(); - if ( mResource->addIncidence( incidence ) ) { - Item newItem( item ); - newItem.setRemoteId( incidencePtr->uid() ); - newItem.setPayload( incidencePtr ); - if ( !mResource->save( incidence ) ) { - kError() << "Failed to save incidence" << incidence->uid(); - // resource error emitted by savingError() - } - changeCommitted( newItem ); - return; - } - - kError() << "Failed to add incidence to resource"; - } - - changeProcessed(); -} - -void KCalResource::itemChanged( const Akonadi::Item &item, const QSet& parts ) -{ - kDebug() << "item id=" << item.id() << ", remoteId=" << item.remoteId() - << "mimeType=" << item.mimeType() << "parts=" << parts; - - if ( mResource == 0 ) { - kError() << "Resource not fully operational yet"; - emit status( NotConfigured, i18nc( "@info:status", "No KDE calendar plugin configured yet" ) ); - return; - } - - if ( item.hasPayload() ) { - IncidencePtr incidencePtr = item.payload(); - - KCal::Incidence *incidence = mResource->incidence( incidencePtr->uid() ); - if ( incidence == 0 ) { - incidence = incidencePtr->clone(); - if ( mResource->addIncidence( incidence ) ) { - if ( !mResource->save( incidence ) ) { - kError() << "Failed to save incidence" << incidence->uid(); - // resource error emitted by savingError() - } - changeCommitted( item ); - return; - } - - kError() << "Failed to add incidence to resource"; - } else { - // make sure any observer the resource might have installed gets properly notified - incidence->startUpdates(); - bool assignResult = mIncidenceAssigner->assign( incidence, incidencePtr.get() ); - if ( assignResult ) - incidence->updated(); - incidence->endUpdates(); - - if ( !assignResult ) { - kWarning() << "Item changed incidence type. Replacing it."; - - mResource->deleteIncidence( incidence ); - mResource->addIncidence( incidencePtr->clone() ); - scheduleSaveCalendar(); - } else { - if ( !mResource->save( incidence ) ) { - kError() << "Failed to save incidence" << incidence->uid(); - // resource error emitted by savingError() - } - } - changeCommitted( item ); - return; - } - } - - changeProcessed(); -} - -void KCalResource::itemRemoved( const Akonadi::Item &item ) -{ - kDebug() << "item id=" << item.id() << ", remoteId=" << item.remoteId(); - - if ( mResource == 0 ) { - kError() << "Resource not fully operational yet"; - emit status( NotConfigured, i18nc( "@info:status", "No KDE calendar plugin configured yet" ) ); - return; - } - - KCal::Incidence *incidence = mResource->incidence( item.remoteId() ); - if ( incidence != 0 && mResource->deleteIncidence( incidence ) ) { - if ( !mResource->save( incidence ) ) { - kError() << "Failed to save incidence" << incidence->uid(); - // resource error emitted by savingError() - } - changeCommitted( item ); - return; - } - - changeProcessed(); -} - -void KCalResource::collectionAdded( const Akonadi::Collection &collection, - const Akonadi::Collection &parent ) -{ - kDebug() << "collection id=" << collection.id() << ", remoteId=" << collection.remoteId() << ", name=" << collection.name() - << ", parent id=" << parent.id() << ", remoteId=" << parent.remoteId(); - - if ( mResource == 0 ) { - kError() << "Resource not fully operational yet"; - emit status( NotConfigured, i18nc( "@info:status", "No KDE calendar plugin configured yet" ) ); - return; - } - - if ( mResource->addSubresource( collection.name(), parent.remoteId() ) ) { - // result delivered by signalSubresourceAdded(). how do we best relate this? - changeCommitted( collection ); - return; - } - - changeProcessed(); -} - -void KCalResource::collectionChanged( const Akonadi::Collection &collection ) -{ - kDebug() << "collection id=" << collection.id() << ", remoteId=" << collection.remoteId(); - - if ( mResource == 0 ) { - kError() << "Resource not fully operational yet"; - emit status( NotConfigured, i18nc( "@info:status", "No KDE calendar plugin configured yet" ) ); - return; - } - - // currently only changing the top level collection's name supported - if ( collection.parentCollection() == Collection::root() ) { - const QString newName = collection.displayName(); - - if ( newName != mResource->resourceName() ) { - mResource->setResourceName( newName ); - setName( newName ); - changeCommitted( collection ); - // TODO save config - return; - } - } - - changeProcessed(); -} - -void KCalResource::collectionRemoved( const Akonadi::Collection &collection ) -{ - kDebug() << "collection id=" << collection.id() << ", remoteId=" << collection.remoteId(); - - if ( mResource == 0 ) { - kError() << "Resource not fully operational yet"; - emit status( NotConfigured, i18nc( "@info:status", "No KDE calendar plugin configured yet" ) ); - return; - } - - // currently only removing sub resource supported - const QStringList subResources = mResource->subresources(); - if ( subResources.contains( collection.remoteId() ) ) { - if ( mResource->removeSubresource( collection.remoteId() ) ) { - changeCommitted( collection ); - scheduleSaveCalendar(); - return; - } - } - - changeProcessed(); -} - -bool KCalResource::openConfiguration() -{ - if ( mResource != 0 ) { - if ( !mResource->isOpen() ) { - if ( !mResource->open() ) { - kError() << "Opening resource" << mResource->identifier() << "failed"; - return false; - } - } - - connect( mResource, SIGNAL(resourceLoaded(ResourceCalendar*)), - this, SLOT(initialLoadingFinished(ResourceCalendar*)) ); - connect( mResource, SIGNAL(resourceLoadError(ResourceCalendar*,QString)), - this, SLOT(loadingError(ResourceCalendar*,QString)) ); - - setName( mResource->resourceName() ); - } - - return true; -} - -void KCalResource::closeConfiguration() -{ - mDelayedSaveTimer->stop(); - - if ( mResource != 0 ) { - if ( mResource->isOpen() ) - mResource->close(); - - disconnect( mResource, SIGNAL(resourceLoadError(ResourceCalendar*,QString)), - this, SLOT(loadingError(ResourceCalendar*,QString)) ); - disconnect( mResource, SIGNAL(resourceSaveError(ResourceCalendar*,QString)), - this, SLOT(savingError(ResourceCalendar*,QString)) ); - disconnect( mResource, SIGNAL(resourceChanged(ResourceCalendar*)), - this, SLOT(resourceChanged(ResourceCalendar*)) ); - } -} - -bool KCalResource::saveCalendar() -{ - kDebug(); - mDelayedSaveTimer->stop(); - - if ( !mResource || mResource->readOnly() ) - return false; - - if ( !mResource->save() ) { - kError() << "Saving failed"; - // resource error emitted by savingError() - return false; - } - - kDebug() << "Saving succeeded"; - return true; -} - -bool KCalResource::scheduleSaveCalendar() -{ - if ( !mResource || mResource->readOnly() ) - return false; - - if ( !mDelayedSaveTimer->isActive() ) - mDelayedSaveTimer->start( 5000 ); - - return true; -} - -void KCalResource::reloadConfig() -{ - kDebug() << "resource=" << (void*) mResource; - if ( mResource != 0 ) { - if ( !mResource->save() ) { - kError() << "Saving of calendar failed"; - } - } - closeConfiguration(); - - KGlobal::config()->reparseConfiguration(); - - if ( KGlobal::config()->groupList().isEmpty() ) { - emit status( NotConfigured, i18nc( "@info:status", "No KDE calendar plugin configured yet" ) ); - return; - } - - Q_ASSERT( KGlobal::config().data() != 0); - - mManager->readConfig( KGlobal::config().data() ); - - mResource = mManager->standardResource(); - if ( mResource != 0 ) { - if ( mResource->type().toLower() == QLatin1String( "akonadi" ) ) { - kError() << "Resource config points to an Akonadi bridge resource"; - emit status( NotConfigured, i18nc( "@info:status", "No KDE calendar plugin configured yet" ) ); - return; - } - } - - if ( mResource == 0 ) { - emit status( NotConfigured, i18nc( "@info:status", "No KDE calendar plugin configured yet" ) ); - return; - } - - if ( !isOnline() ) - return; - - if ( !openConfiguration() ) { - kError() << "openConfiguration() failed"; - - const QString message = i18nc( "@info:status", "Initialization based on stored configuration failed." ); - emit error( message ); - emit status( NotConfigured, message ); - return; - } - - emit status( Running, i18nc( "@info:status", "Loading calendar" ) ); - - // signals emitted by initialLoadingFinished() or loadingError() - if ( !mResource->load() ) { - kError() << "Resource::load() failed"; - } -} - -void KCalResource::initialLoadingFinished( ResourceCalendar *resource ) -{ - Q_UNUSED( resource ); - Q_ASSERT( resource == mResource ); - - kDebug(); - - disconnect( mResource, SIGNAL(resourceLoaded(ResourceCalendar*)), - this, SLOT(initialLoadingFinished(ResourceCalendar*)) ); - - connect( mResource, SIGNAL(resourceChanged(ResourceCalendar*)), - this, SLOT(resourceChanged(ResourceCalendar*)) ); - - emit status( Idle, QString() ); - mFullItemRetrieve = false; - synchronize(); -} - -void KCalResource::resourceChanged( ResourceCalendar *resource ) -{ - Q_UNUSED( resource ); - Q_ASSERT( resource == mResource ); - - kDebug(); - if ( mDelayedSaveTimer->isActive() ) { - // TODO should record changes for delayed saving - kError() << "Delayed saving scheduled when resource changed. We might have lost changes"; - mDelayedSaveTimer->stop(); - } - - mFullItemRetrieve = true; - synchronize(); -} - -void KCalResource::loadingError( ResourceCalendar *resource, const QString &message ) -{ - Q_UNUSED( resource ); - Q_ASSERT( resource == mResource ); - - kError() << "Loading error: " << message; - const QString statusMessage = - i18nc( "@info:status", "Loading of calendar failed: %1", message ); - - emit error( statusMessage ); - emit status( Broken, statusMessage ); -} - -void KCalResource::savingError( ResourceCalendar *resource, const QString &message ) -{ - Q_UNUSED( resource ); - Q_ASSERT( resource == mResource ); - - kError() << "Saving error: " << message; - const QString statusMessage = - i18nc( "@info:status", "Saving of calendar failed: %1", message ); - - emit error( statusMessage ); - emit status( Broken, statusMessage ); -} - -void KCalResource::delayedSaveCalendar() -{ - if ( !saveCalendar() ) { - kError() << "Saving failed, rescheduling delayed save"; - if ( !scheduleSaveCalendar() ) { - kError() << "Scheduling failed as well, giving up"; - } - } -} - -AKONADI_RESOURCE_MAIN( KCalResource ) - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/kcal/kcalresource.desktop kdepim-runtime-15.08.0/resources/kcal/kcalresource.desktop --- kdepim-runtime-4.14.6/resources/kcal/kcalresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kcal/kcalresource.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -[Desktop Entry] -Name=KDE Calendar (traditional) -Name[ar]=تقويم كدي (تقليدي) -Name[bs]=KDE kalendar (tradicionalno) -Name[ca]=Calendari del KDE (tradicional) -Name[ca@valencia]=Calendari del KDE (tradicional) -Name[cs]=KDE kalendář (tradiční) -Name[da]=KDE-kalender (traditionel) -Name[de]=KDE-Kalender (herkömmlich) -Name[el]=Ημερολόγιο KDE (παραδοσιακό) -Name[en_GB]=KDE Calendar (traditional) -Name[es]=Calendario de KDE (tradicional) -Name[et]=KDE kalender (traditsiooniline) -Name[fi]=KDE:n kalenteri (perinteinen) -Name[fr]=Agenda KDE (traditionnel) -Name[ga]=Féilire KDE (traidisiúnta) -Name[gl]=Calendario do KDE (tradicional) -Name[hu]=KDE naptár (hagyományos) -Name[ia]=Calendario KDE (traditional) -Name[it]=Calendario di KDE (tradizionale) -Name[ja]=KDE カレンダー (従来のタイプ) -Name[kk]=KDE күнтісзбесі (дәстүрлі) -Name[km]=ប្រតិទិន KDE (បុរាណ) -Name[ko]=KDE 달력 (이전 버전) -Name[lt]=KDE kalendorius (tradicinis) -Name[lv]=KDE kalendārs (tradicionāls) -Name[nb]=KDE-kalender (tradisjonell) -Name[nds]=KDE-Kalenner (normaal) -Name[nl]=Agenda van KDE (traditioneel) -Name[nn]=KDE-kalender (tradisjonell) -Name[pa]=KDE ਕੈਲੰਡਰ (ਪੁਰਾਣਾ) -Name[pl]=Wtyczka kalendarza KDE (tradycyjna) -Name[pt]=Calendário do KDE (tradicional) -Name[pt_BR]=Calendário do KDE (tradicional) -Name[ro]=Calendar KDE (tradițional) -Name[ru]=Календарь KDE (традиционный источник) -Name[sk]=KDE kalendár (tradičný) -Name[sl]=KDE-jev koledar (tradicionalni) -Name[sr]=КДЕ‑ов календар (традиционални) -Name[sr@ijekavian]=КДЕ‑ов календар (традиционални) -Name[sr@ijekavianlatin]=KDE‑ov kalendar (tradicionalni) -Name[sr@latin]=KDE‑ov kalendar (tradicionalni) -Name[sv]=KDE:s kalender (traditionell) -Name[tr]=KDE Takvimi (geleneksel) -Name[uk]=Календар KDE (традиційний) -Name[x-test]=xxKDE Calendar (traditional)xx -Name[zh_CN]=KDE 日历(传统) -Name[zh_TW]=KDE 行事曆(傳統) -Comment=Loads data from a traditional KDE calendar resource -Comment[ar]=تحمل البيانات من موارد تقويم كدي التقليدي -Comment[bs]=Učitava podatke iz tradicionalog KDE izvora kalendara -Comment[ca]=Carregar les dades des d'un recurs de calendari tradicional del KDE -Comment[ca@valencia]=Carregar dades des d'un recurs de calendari tradicional del KDE -Comment[cs]=Načítá data z tradičního kalendáře KDE -Comment[da]=Indlæser data fra en traditionel KDE kalenderressource -Comment[de]=Lädt Daten aus einer herkömmlichen KDE-Kalender-Ressource -Comment[el]=Φόρτωση δεδομένων από έναν παραδοσιακό πόρο ημερολογίου του KDE -Comment[en_GB]=Loads data from a traditional KDE calendar resource -Comment[es]=Carga datos desde un recurso tradicional de Calendario de KDE -Comment[et]=Andmete laadimine traditsioonilisest KDE kalendri ressursist -Comment[fi]=Noutaa tietoa KDE:n perinteisestä kalenteriresurssista -Comment[fr]=Charge des données depuis un agenda KDE traditionnel -Comment[ga]=Breiseán a luchtaíonn sonraí ó acmhainn thraidisiúnta fhéilire KDE -Comment[gl]=Carga datos desde un recurso de calendario tradicional do KDE -Comment[hu]=Adatbetöltés egy hagyományos KDE naptárerőforrásból -Comment[ia]=Lege datos de un ressource de un calendario KDE traditional -Comment[it]=Carica dati da una tradizionale risorsa calendario di KDE -Comment[ja]=従来の KDE カレンダーリソースからデータを読み込みます -Comment[kk]=Дәстүрлі KDE күнтізбесінен деректі алып береді -Comment[km]=ផ្ទុក​ទិន្នន័យ​ពី​ធនធាន​ប្រតិទិន KDE បុរាណ -Comment[ko]=이전 버전의 KDE 달력 자원에서 데이터를 불러옵니다 -Comment[lt]=Įkelia duomenis iš tradicinio KDE kalendoriaus resurso -Comment[lv]=Ielādē datus no tradicionālā KDE kalendāra resursa -Comment[nb]=Laster data fra en tradisjonell KDE-kalenderresurs -Comment[nds]=Laadt Daten ut en normaal KDE-Kalennerressource -Comment[nl]=Laadt gegevens van een traditioneel KDE agendabron -Comment[nn]=Lastar data frå tradisjonelle KDE-kalenderressursar -Comment[pl]=Wczytuje dane z tradycyjnego zasobu kalendarza KDE -Comment[pt]=Carrega os dados de um recurso de calendário tradicional do KDE -Comment[pt_BR]=Carrega os dados do tradicional recurso de calendário do KDE -Comment[ro]=Încarcă date dintr-o resursă de calendar KDE tradițională -Comment[ru]=Загрузка данных из источника календаря KDE -Comment[sk]=Načíta dáta z prechodného KDE zdroja kalendára -Comment[sl]=Naloži podatke iz tradicionalnega KDE-jevega koledarja -Comment[sr]=Учитава податке из традиционалног КДЕ‑овог ресурса календара -Comment[sr@ijekavian]=Учитава податке из традиционалног КДЕ‑овог ресурса календара -Comment[sr@ijekavianlatin]=Učitava podatke iz tradicionalnog KDE‑ovog resursa kalendara -Comment[sr@latin]=Učitava podatke iz tradicionalnog KDE‑ovog resursa kalendara -Comment[sv]=Laddar data från en traditionell kalenderresurs i KDE -Comment[tr]=Geleneksel KDE takvim kaynağından veri yükler -Comment[uk]=Завантажує дані зі звичайного ресурсу календаря для KDE -Comment[x-test]=xxLoads data from a traditional KDE calendar resourcexx -Comment[zh_CN]=从传统 KDE 日历资源载入数据 -Comment[zh_TW]=從傳統 KDE 行事曆資源載入資料 -Type=AkonadiResource -Exec=akonadi_kcal_resource -Icon=text-calendar - -X-Akonadi-MimeTypes=text/calendar,application/x-vnd.akonadi.calendar.event,application/x-vnd.akonadi.calendar.todo,application/x-vnd.akonadi.calendar.journal,application/x-vnd.akonadi.calendar.freebusy -X-Akonadi-Capabilities=Resource -X-Akonadi-Identifier=akonadi_kcal_resource diff -Nru kdepim-runtime-4.14.6/resources/kcal/kcalresource.h kdepim-runtime-15.08.0/resources/kcal/kcalresource.h --- kdepim-runtime-4.14.6/resources/kcal/kcalresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kcal/kcalresource.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ -/* - Copyright (c) 2008-2009 Kevin Krammer - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef KCALRESOURCE -#define KCALRESOURCE - -#include - -namespace KRES { - template class Manager; -} - -namespace KCal { - class AssignmentVisitor; - class ResourceCalendar; - - typedef KRES::Manager CalendarResourceManager; -} - -namespace Akonadi { - class IncidenceMimeTypeVisitor; -} - -class QTimer; - -class KCalResource : public Akonadi::ResourceBase, public Akonadi::AgentBase::Observer -{ - Q_OBJECT - - public: - KCalResource( const QString &id ); - virtual ~KCalResource(); - - public Q_SLOTS: - virtual void configure( WId windowId ); - - protected Q_SLOTS: - void retrieveCollections(); - void retrieveItems( const Akonadi::Collection &collection ); - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - - protected: - virtual void aboutToQuit(); - - virtual void doSetOnline( bool online ); - - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); - virtual void itemRemoved( const Akonadi::Item &item ); - - virtual void collectionAdded( const Akonadi::Collection &collection, - const Akonadi::Collection &parent ); - - virtual void collectionChanged( const Akonadi::Collection &collection ); - - virtual void collectionRemoved( const Akonadi::Collection &collection ); - - private: - KCal::CalendarResourceManager *mManager; - KCal::ResourceCalendar *mResource; - Akonadi::IncidenceMimeTypeVisitor *mMimeVisitor; - - bool mFullItemRetrieve; - - QTimer *mDelayedSaveTimer; - - KCal::AssignmentVisitor *mIncidenceAssigner; - - private: - bool openConfiguration(); - void closeConfiguration(); - - bool saveCalendar(); - - bool scheduleSaveCalendar(); - - typedef KCal::ResourceCalendar ResourceCalendar; - - private Q_SLOTS: - void reloadConfig(); - - void initialLoadingFinished( ResourceCalendar *resource ); - - void resourceChanged( ResourceCalendar *resource ); - - void loadingError( ResourceCalendar *resource, const QString &message ); - - void savingError( ResourceCalendar *resource, const QString &message ); - - void delayedSaveCalendar(); -}; - -#endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/kcal/Messages.sh kdepim-runtime-15.08.0/resources/kcal/Messages.sh --- kdepim-runtime-4.14.6/resources/kcal/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kcal/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -#! /usr/bin/env bash -$XGETTEXT *.cpp -o $podir/akonadi_kcal_resource.pot diff -Nru kdepim-runtime-4.14.6/resources/kdeaccounts/CMakeLists.txt kdepim-runtime-15.08.0/resources/kdeaccounts/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/kdeaccounts/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kdeaccounts/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -include_directories( - ${kdepim-runtime_SOURCE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} -) - -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - -########### next target ############### - -set( kdeaccountsresource_SRCS - ${AKONADI_SINGLEFILERESOURCE_SHARED_SOURCES} - kdeaccountsresource.cpp -) - -install( FILES kdeaccountsresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) - -kde4_add_ui_files(kdeaccountsresource_SRCS ${AKONADI_SINGLEFILERESOURCE_SHARED_UI}) -kde4_add_kcfg_files(kdeaccountsresource_SRCS settings.kcfgc) -kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/kdeaccountsresource.kcfg org.kde.Akonadi.KDEAccounts.Settings) -qt4_add_dbus_adaptor(kdeaccountsresource_SRCS - ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.KDEAccounts.Settings.xml settings.h Settings -) - -kde4_add_executable(akonadi_kdeaccounts_resource ${kdeaccountsresource_SRCS}) - -if (Q_WS_MAC) - set_target_properties(akonadi_kdeaccounts_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) - set_target_properties(akonadi_kdeaccounts_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.KDEAccounts") - set_target_properties(akonadi_kdeaccounts_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi KDEAccounts Resource") -endif () - -target_link_libraries(akonadi_kdeaccounts_resource ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${KDE4_KDECORE_LIBS} ${KDEPIMLIBS_KABC_LIBS} ${KDE4_KIO_LIBS}) - -install(TARGETS akonadi_kdeaccounts_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/kdeaccounts/kdeaccountsresource.cpp kdepim-runtime-15.08.0/resources/kdeaccounts/kdeaccountsresource.cpp --- kdepim-runtime-4.14.6/resources/kdeaccounts/kdeaccountsresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kdeaccounts/kdeaccountsresource.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,168 +0,0 @@ -/* - Copyright (c) 2010 Tobias Koenig - - 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 "kdeaccountsresource.h" - -#include "settingsadaptor.h" -#include "singlefileresourceconfigdialog.h" - -#include - -#include -#include -#include - - -using namespace Akonadi; - -KDEAccountsResource::KDEAccountsResource( const QString &id ) - : SingleFileResource( id ) -{ - setSupportedMimetypes( QStringList() << KABC::Addressee::mimeType(), QLatin1String("kde") ); - - setName( i18n( "KDE Accounts" ) ); - - new SettingsAdaptor( mSettings ); - DBusConnectionPool::threadConnection().registerObject( QLatin1String( "/Settings" ), - mSettings, QDBusConnection::ExportAdaptors ); -} - -KDEAccountsResource::~KDEAccountsResource() -{ - mContacts.clear(); -} - -bool KDEAccountsResource::retrieveItem( const Akonadi::Item &item, const QSet& ) -{ - const QString remoteId = item.remoteId(); - if ( !mContacts.contains( remoteId ) ) { - cancelTask( i18n( "Contact with uid '%1' not found.", remoteId ) ); - return false; - } - - Item newItem( item ); - newItem.setPayload( mContacts.value( remoteId ) ); - itemRetrieved( newItem ); - - return true; -} - -void KDEAccountsResource::customizeConfigDialog( SingleFileResourceConfigDialog* dlg ) -{ - dlg->setWindowIcon( KIcon( QLatin1String("kde") ) ); - dlg->setCaption( i18n( "Select KDE Accounts File" ) ); -} - -void KDEAccountsResource::configDialogAcceptedActions( SingleFileResourceConfigDialog* ) -{ - // We can't hide the GUI element but we can enforce that the - // resource is read-only - mSettings->setReadOnly( true ); - mSettings->writeConfig(); -} - -void KDEAccountsResource::itemAdded( const Akonadi::Item&, const Akonadi::Collection& ) -{ - cancelTask( i18n( "KDE Accounts file is read-only" ) ); -} - -void KDEAccountsResource::itemChanged( const Akonadi::Item&, const QSet& ) -{ - cancelTask( i18n( "KDE Accounts file is read-only" ) ); -} - -void KDEAccountsResource::itemRemoved( const Akonadi::Item& ) -{ - cancelTask( i18n( "KDE Accounts file is read-only" ) ); -} - -void KDEAccountsResource::retrieveItems( const Akonadi::Collection &collection ) -{ - // KDEAccounts does not support folders so we can safely ignore the collection - Q_UNUSED( collection ); - - Akonadi::Item::List items; - ContactsMap::const_iterator end(mContacts.constEnd()); - for ( ContactsMap::const_iterator it = mContacts.constBegin(); it != end; ++it ) { - Item item; - item.setRemoteId( it.key() ); - item.setMimeType( KABC::Addressee::mimeType() ); - item.setPayload( it.value() ); - items.append( item ); - } - - itemsRetrieved( items ); -} - -bool KDEAccountsResource::readFromFile( const QString &fileName ) -{ - mContacts.clear(); - - QFile file( KUrl( fileName ).toLocalFile() ); - if ( !file.open( QIODevice::ReadOnly ) ) { - emit status( Broken, i18n( "Unable to open KDE accounts file '%1'.", fileName ) ); - return false; - } - - while ( !file.atEnd() ) { - QString line = QString::fromUtf8( file.readLine() ); - // We have a line like the following now, which consists of a nickname, - // the full name and an email address - // 'tokoe Tobias Koenig tokoe@kde.org' - - // remove all leading, trailing and duplicated white spaces - line = line.trimmed().simplified(); - if (line.isEmpty()) { - continue; - } - - QStringList parts = line.split( QLatin1Char( ' ' ) ); - if ( parts.count() < 3 ) { - kWarning() << "Failed to parse line \"" << line << "\", invalid format"; - continue; - } - - // The first part is the nick name, the last one the email address and - // everything else in between the full name - const QString nickName = parts.takeFirst(); - const QString email = parts.takeLast(); - const QString fullName = parts.join( QLatin1String( " " ) ); - - KABC::Addressee contact; - contact.setNickName( nickName ); - contact.setNameFromString( fullName ); - contact.setOrganization( i18n( "KDE Project" ) ); - contact.insertCategory( i18n( "KDE Developer" ) ); - contact.insertEmail( email ); - - mContacts.insert( nickName, contact ); - } - - return true; -} - -bool KDEAccountsResource::writeToFile( const QString& ) -{ - Q_ASSERT( false ); // this method should never be called - - return false; -} - -AKONADI_RESOURCE_MAIN( KDEAccountsResource ) - diff -Nru kdepim-runtime-4.14.6/resources/kdeaccounts/kdeaccountsresource.desktop kdepim-runtime-15.08.0/resources/kdeaccounts/kdeaccountsresource.desktop --- kdepim-runtime-4.14.6/resources/kdeaccounts/kdeaccountsresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kdeaccounts/kdeaccountsresource.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -[Desktop Entry] -Name=KDE Accounts -Name[bs]=KDE nalozi -Name[ca]=Comptes del KDE -Name[ca@valencia]=Comptes del KDE -Name[cs]=Účty KDE -Name[da]=KDE-konti -Name[de]=KDE-Zugänge -Name[el]=Λογαριασμοί KDE -Name[en_GB]=KDE Accounts -Name[es]=Cuentas de KDE -Name[et]=KDE kontod -Name[fi]=KDE-tilit -Name[fr]=Comptes KDE -Name[ga]=Cuntais KDE -Name[gl]=Contas do KDE -Name[hu]=KDE azonosítók -Name[ia]=Contos KDE -Name[it]=Account KDE -Name[ja]=KDE アカウント -Name[kk]=KDE тіркелгілері -Name[km]=គណនី KDE -Name[ko]=KDE 연락처 -Name[lt]=KDE paskyros -Name[lv]=KDE konti -Name[nb]=KDE-kontoer -Name[nds]=KDE-Kontos -Name[nl]=KDE-accounts -Name[nn]=KDE-kontoar -Name[pa]=KDE ਅਕਾਊਂਟ -Name[pl]=Konta KDE -Name[pt]=Contas do KDE -Name[pt_BR]=Contas do KDE -Name[ro]=Conturi KDE -Name[ru]=Учётные записи KDE -Name[sk]=KDE účty -Name[sl]=KDE-jevi računi -Name[sr]=КДЕ налози -Name[sr@ijekavian]=КДЕ налози -Name[sr@ijekavianlatin]=KDE nalozi -Name[sr@latin]=KDE nalozi -Name[sv]=KDE-konton -Name[tr]=KDE Hesapları -Name[ug]=KDE ھېساباتى -Name[uk]=Облікові записи KDE -Name[x-test]=xxKDE Accountsxx -Name[zh_CN]=KDE 账户 -Name[zh_TW]=KDE 帳號 -Comment=Loads contacts from the KDE accounts file -Comment[bs]=Učitava kontakte s KDE datoteke naloga -Comment[ca]=Carrega contactes des d'un fitxer de comptes del KDE -Comment[ca@valencia]=Carrega contactes des d'un fitxer de comptes del KDE -Comment[da]=Indlæser kontakter fra KDE-konti-filen -Comment[de]=Lädt Kontakte aus der KDE-Zugangsdatei -Comment[el]=Φόρτωση επαφών από ένα αρχείο λογαριασμών KDE -Comment[en_GB]=Loads contacts from the KDE accounts file -Comment[es]=Cargar contactos desde el archivo de cuentas de KDE -Comment[et]=Kontaktide laadimine KDE kontode failist -Comment[fi]=Lataa yhteystiedot KDE:n tilitiedostosta -Comment[fr]=Charge les contacts depuis le fichier de comptes KDE -Comment[ga]=Luchtaíonn sé seo teagmhálacha ón chomhad cuntas KDE -Comment[gl]=Carga contactos desde un ficheiro de contas do KDE -Comment[hu]=Adatok betöltése a KDE azonosítófájlból -Comment[ia]=Lege contactos de un file de un conto KDE -Comment[it]=Carica contatti dal file degli account KDE -Comment[ja]=KDE アカウントファイルから連絡先を読み込みます -Comment[kk]=KDE тіркелгілер файлынан контакттарды алып береді -Comment[km]=ផ្ទុក​ទំនាក់ទំនង​ពី​ឯកសារគណនី​របស់ KDE -Comment[ko]=KDE 연락처 파일에서 데이터를 가져옵니다 -Comment[lt]=Įkelia kontaktus iš KDE paskyros failo -Comment[lv]=Ielādē datus no KDE kontu faila -Comment[nb]=Laster kontakter fra KDE-kontofila -Comment[nds]=Laadt Kontakten ut de KDE-Kontendatei -Comment[nl]=Laadt contactpersonen uit het bestand met KDE-accounts -Comment[nn]=Lastar inn kontaktar frå ei KDE-kontofil -Comment[pl]=Wczytuje kontakty z pliku kontaktów KDE -Comment[pt]=Carrega os dados do ficheiro de contas do KDE -Comment[pt_BR]=Carrega os contatos a partir do arquivo de contas do KDE -Comment[ro]=Încarcă date din fișierul cu conturi KDE -Comment[ru]=Загрузка контактов из файла контактов KDE -Comment[sk]=Načíta kontakty zo súboru KDE účtov -Comment[sl]=Naloži stike iz datoteke KDE-jevih računov -Comment[sr]=Учитава контакте из фајла КДЕ налога -Comment[sr@ijekavian]=Учитава контакте из фајла КДЕ налога -Comment[sr@ijekavianlatin]=Učitava kontakte iz fajla KDE naloga -Comment[sr@latin]=Učitava kontakte iz fajla KDE naloga -Comment[sv]=Laddar kontakter från KDE:s kontofil -Comment[tr]=KDE hesap dosyasından kişileri yükler -Comment[uk]=Завантаження контактів з файла облікових записів KDE -Comment[x-test]=xxLoads contacts from the KDE accounts filexx -Comment[zh_CN]=从 KDE 账户文件中装入联系人 -Comment[zh_TW]=從 KDE 帳號檔載入聯絡人 -Type=AkonadiResource -Exec=akonadi_kdeaccounts_resource -Icon=kde - -X-Akonadi-MimeTypes=text/directory -X-Akonadi-Capabilities=Resource -X-Akonadi-Identifier=akonadi_kdeaccounts_resource diff -Nru kdepim-runtime-4.14.6/resources/kdeaccounts/kdeaccountsresource.h kdepim-runtime-15.08.0/resources/kdeaccounts/kdeaccountsresource.h --- kdepim-runtime-4.14.6/resources/kdeaccounts/kdeaccountsresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kdeaccounts/kdeaccountsresource.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -/* - Copyright (c) 2010 Tobias Koenig - - 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 KDEACCOUNTSRESOURCE_H -#define KDEACCOUNTSRESOURCE_H - -#include "singlefileresource.h" -#include "settings.h" - -#include - -class KDEAccountsResource : public Akonadi::SingleFileResource -{ - Q_OBJECT - - public: - KDEAccountsResource( const QString &id ); - ~KDEAccountsResource(); - - protected Q_SLOTS: - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - void retrieveItems( const Akonadi::Collection &collection ); - - protected: - /** - * Customize the configuration dialog before it is displayed. - */ - virtual void customizeConfigDialog( Akonadi::SingleFileResourceConfigDialog* dlg ); - - /* - * Do stuff when the configuration dialog has been accepted, before - * reloadFile() is called. - */ - virtual void configDialogAcceptedActions( Akonadi::SingleFileResourceConfigDialog* dlg ); - - bool readFromFile( const QString &fileName ); - bool writeToFile( const QString &fileName ); - - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); - virtual void itemRemoved( const Akonadi::Item &item ); - - private: - typedef QMap ContactsMap; - ContactsMap mContacts; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/kdeaccounts/kdeaccountsresource.kcfg kdepim-runtime-15.08.0/resources/kdeaccounts/kdeaccountsresource.kcfg --- kdepim-runtime-4.14.6/resources/kdeaccounts/kdeaccountsresource.kcfg 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kdeaccounts/kdeaccountsresource.kcfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - true - - - - true - - - diff -Nru kdepim-runtime-4.14.6/resources/kdeaccounts/Messages.sh kdepim-runtime-15.08.0/resources/kdeaccounts/Messages.sh --- kdepim-runtime-4.14.6/resources/kdeaccounts/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kdeaccounts/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -#! /usr/bin/env bash -$EXTRACTRC `find . -name \*.ui` `find . -name \*.kcfg` >> rc.cpp || exit 11 -$XGETTEXT *.cpp -o $podir/akonadi_kdeaccounts_resource.pot diff -Nru kdepim-runtime-4.14.6/resources/kdeaccounts/settings.kcfgc kdepim-runtime-15.08.0/resources/kdeaccounts/settings.kcfgc --- kdepim-runtime-4.14.6/resources/kdeaccounts/settings.kcfgc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kdeaccounts/settings.kcfgc 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -File=kdeaccountsresource.kcfg -ClassName=Settings -Mutators=true -ItemAccessors=true -SetUserTexts=true -Singleton=false -GlobalEnums=true Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/kolab/64-apps-kolab.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/kolab/64-apps-kolab.png differ diff -Nru kdepim-runtime-4.14.6/resources/kolab/CMakeLists.txt kdepim-runtime-15.08.0/resources/kolab/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/kolab/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,17 +1,15 @@ include_directories( - ${kdepim-runtime_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../imap ${CMAKE_CURRENT_BINARY_DIR}/../imap - ${QT_QTDBUS_INCLUDE_DIR} - ${Boost_INCLUDE_DIR} - ${Libkolab_INCLUDES} ${Libkolabxml_INCLUDES} + ${Libkolab_INCLUDES} ) add_definitions( -DQT_NO_CAST_FROM_ASCII ) add_definitions( -DQT_NO_CAST_TO_ASCII ) -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_imap_resource\") + ########### next target ############### @@ -25,37 +23,53 @@ kolabresourcestate.cpp kolabhelpers.cpp kolabmessagehelper.cpp + kolabaddtagtask.cpp + kolabchangetagtask.cpp + kolabremovetagtask.cpp + kolabretrievetagstask.cpp + kolabsettings.cpp + tagchangehelper.cpp + kolabrelationresourcetask.cpp + kolabchangeitemsrelationstask.cpp + kolabchangeitemstagstask.cpp + updatemessagejob.cpp + kolabresource_debug.cpp ) -kde4_add_kcfg_files(kolabresource_SRCS ../imap/settingsbase.kcfgc) +kconfig_add_kcfg_files(kolabresource_SRCS ../imap/settingsbase.kcfgc) if (KDEPIM_MOBILE_UI) -kde4_add_ui_files(kolabresource_SRCS ../imap/setupserverview_mobile.ui) +ki18n_wrap_ui(kolabresource_SRCS ../imap/setupserverview_mobile.ui) else () -kde4_add_ui_files(kolabresource_SRCS ../imap/setupserverview_desktop.ui) +ki18n_wrap_ui(kolabresource_SRCS ../imap/setupserverview_desktop.ui) endif () -kde4_add_ui_files(kolabresource_SRCS ../imap/serverinfo.ui) +ki18n_wrap_ui(kolabresource_SRCS ../imap/serverinfo.ui) +add_executable(akonadi_kolab_resource ${kolabresource_SRCS}) -kde4_add_executable(akonadi_kolab_resource ${kolabresource_SRCS}) target_link_libraries(akonadi_kolab_resource - ${KDEPIMLIBS_AKONADI_LIBS} - ${QT_QTDBUS_LIBRARY} - ${QT_QTCORE_LIBRARY} - ${QT_QTGUI_LIBRARY} - ${QT_QTNETWORK_LIBRARY} - ${KDEPIMLIBS_KIMAP_LIBS} - ${KDEPIMLIBS_MAILTRANSPORT_LIBS} - ${KDE4_KIO_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${KDEPIMLIBS_AKONADI_KMIME_LIBS} - ${KDEPIMLIBS_KPIMIDENTITIES_LIBS} + KF5::AkonadiCore + KF5::IMAP + KF5::MailTransport + KF5::Mime + KF5::AkonadiMime + KF5::AkonadiCalendar + KF5::AkonadiWidgets + KF5::IdentityManagement imapresource folderarchivesettings - ${Libkolab_LIBRARIES} ${Libkolabxml_LIBRARIES} - ${KDEPIMLIBS_KABC_LIBS} - ${KDEPIMLIBS_KCALCORE_LIBS} + ${Libkolab_LIBRARIES} + KF5::Contacts + KF5::CalendarCore + akonadi-singlefileresource ) -install(FILES kolabresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents") -install(TARGETS akonadi_kolab_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(FILES kolabresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents") +install(TARGETS akonadi_kolab_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) +ecm_install_icons(ICONS 64-apps-kolab.png + DESTINATION share/icons) + +if (BUILD_TESTING) + #add_subdirectory(tests) +endif() +add_subdirectory(wizard) diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabaddtagtask.cpp kdepim-runtime-15.08.0/resources/kolab/kolabaddtagtask.cpp --- kdepim-runtime-4.14.6/resources/kolab/kolabaddtagtask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabaddtagtask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,194 @@ +/* + Copyright (c) 2014 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Krammer + + 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 "kolabaddtagtask.h" +#include "kolabresource_debug.h" +#include "../imap/uidnextattribute.h" + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +KolabAddTagTask::KolabAddTagTask(ResourceStateInterface::Ptr resource, QObject *parent) + : KolabRelationResourceTask(resource, parent) +{ +} + +void KolabAddTagTask::startRelationTask(KIMAP::Session *session) +{ + qCDebug(KOLABRESOURCE_LOG) << "converted tag"; + + const QLatin1String productId("Akonadi-Kolab-Resource"); + const KMime::Message::Ptr message = Kolab::KolabObjectWriter::writeTag(resourceState()->tag(), QStringList(), Kolab::KolabV3, productId); + mMessageId = message->messageID()->asUnicodeString().toUtf8(); + + KIMAP::AppendJob *job = new KIMAP::AppendJob(session); + job->setMailBox(mailBoxForCollection(relationCollection())); + job->setContent(message->encodedContent(true)); + job->setInternalDate(message->date()->dateTime()); + connect(job, SIGNAL(result(KJob*)), SLOT(onAppendMessageDone(KJob*))); + job->start(); +} + +void KolabAddTagTask::applyFoundUid(qint64 uid) +{ + Akonadi::Tag tag = resourceState()->tag(); + + //If we failed to get the remoteid the tag remains local only + if (uid > 0) { + tag.setRemoteId(QByteArray::number(uid)); + } + + qCDebug(KOLABRESOURCE_LOG) << "comitting new tag"; + changeCommitted(tag); + + Akonadi::Collection c = relationCollection(); + + // Get the current uid next value and store it + UidNextAttribute *uidAttr = 0; + int oldNextUid = 0; + if (c.hasAttribute("uidnext")) { + uidAttr = static_cast(c.attribute("uidnext")); + oldNextUid = uidAttr->uidNext(); + } + + // If the uid we just got back is the expected next one of the box + // then update the property to the probable next uid to keep the cache in sync. + // If not something happened in our back, so we don't update and a refetch will + // happen at some point. + if (uid == oldNextUid) { + if (uidAttr == 0) { + uidAttr = new UidNextAttribute(uid + 1); + c.addAttribute(uidAttr); + } else { + uidAttr->setUidNext(uid + 1); + } + + applyCollectionChanges(c); + } +} + +void KolabAddTagTask::triggerSearchJob(KIMAP::Session *session) +{ + KIMAP::SearchJob *search = new KIMAP::SearchJob(session); + + search->setUidBased(true); + search->setSearchLogic(KIMAP::SearchJob::And); + + if (!mMessageId.isEmpty()) { + QByteArray header = "Message-ID "; + header += mMessageId; + + search->addSearchCriteria(KIMAP::SearchJob::Header, header); + } else { + search->addSearchCriteria(KIMAP::SearchJob::New); + + UidNextAttribute *uidNext = relationCollection().attribute(); + if (!uidNext) { + cancelTask(i18n("Could not determine the UID for the newly created message on the server")); + search->deleteLater(); + return; + } + KIMAP::ImapInterval interval(uidNext->uidNext()); + + search->addSearchCriteria(KIMAP::SearchJob::Uid, interval.toImapSequence()); + } + + connect(search, SIGNAL(result(KJob*)), + this, SLOT(onSearchDone(KJob*))); + + search->start(); +} + +void KolabAddTagTask::onAppendMessageDone(KJob *job) + +{ + KIMAP::AppendJob *append = qobject_cast(job); + + if (append->error()) { + qCWarning(KOLABRESOURCE_LOG) << append->errorString(); + cancelTask(append->errorString()); + return; + } + + qint64 uid = append->uid(); + qCDebug(KOLABRESOURCE_LOG) << "appended message with uid: " << uid; + + if (uid > 0) { + // We got it directly if UIDPLUS is supported... + applyFoundUid(uid); + + } else { + // ... otherwise prepare searching for the message + KIMAP::Session *session = append->session(); + const QString mailBox = append->mailBox(); + + if (session->selectedMailBox() != mailBox) { + KIMAP::SelectJob *select = new KIMAP::SelectJob(session); + select->setMailBox(mailBox); + + connect(select, SIGNAL(result(KJob*)), + this, SLOT(onPreSearchSelectDone(KJob*))); + + select->start(); + + } else { + triggerSearchJob(session); + } + } +} + +void KolabAddTagTask::onPreSearchSelectDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << job->errorString(); + cancelTask(job->errorString()); + } else { + KIMAP::SelectJob *select = static_cast(job); + triggerSearchJob(select->session()); + } +} + +void KolabAddTagTask::onSearchDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << job->errorString(); + cancelTask(job->errorString()); + return; + } + + KIMAP::SearchJob *search = static_cast(job); + + qint64 uid = 0; + if (search->results().count() == 1) { + uid = search->results().at(0); + } + + applyFoundUid(uid); +} diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabaddtagtask.h kdepim-runtime-15.08.0/resources/kolab/kolabaddtagtask.h --- kdepim-runtime-4.14.6/resources/kolab/kolabaddtagtask.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabaddtagtask.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,49 @@ +/* + Copyright (c) 2014 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Krammer + + 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 KOLABADDTAGTASK_H +#define KOLABADDTAGTASK_H + +#include "kolabrelationresourcetask.h" + +class KolabAddTagTask : public KolabRelationResourceTask +{ + Q_OBJECT +public: + explicit KolabAddTagTask(ResourceStateInterface::Ptr resource, QObject *parent = 0); + +protected: + virtual void startRelationTask(KIMAP::Session *session); + +private: + QByteArray mMessageId; + +private: + void applyFoundUid(qint64 uid); + void triggerSearchJob(KIMAP::Session *session); + +private slots: + void onAppendMessageDone(KJob *job); + void onPreSearchSelectDone(KJob *job); + void onSearchDone(KJob *job); +}; + +#endif // KOLABADDTAGTASK_H diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabchangeitemsrelationstask.cpp kdepim-runtime-15.08.0/resources/kolab/kolabchangeitemsrelationstask.cpp --- kdepim-runtime-4.14.6/resources/kolab/kolabchangeitemsrelationstask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabchangeitemsrelationstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,206 @@ +/* + Copyright (c) 2014 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Krammer + + 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 "kolabchangeitemsrelationstask.h" +#include "kolabresource_debug.h" +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tracer.h" +#include "kolabhelpers.h" + +KolabChangeItemsRelationsTask::KolabChangeItemsRelationsTask(ResourceStateInterface::Ptr resource, QObject *parent) + : KolabRelationResourceTask(resource, parent) +{ +} + +void KolabChangeItemsRelationsTask::startRelationTask(KIMAP::Session *session) +{ + Trace(); + mSession = session; + mAddedRelations = resourceState()->addedRelations(); + mRemovedRelations = resourceState()->removedRelations(); + + processNextRelation(); +} + +void KolabChangeItemsRelationsTask::processNextRelation() +{ + Trace() << mAddedRelations.size() << mRemovedRelations.size(); + Akonadi::Relation relation; + if (!mAddedRelations.isEmpty()) { + relation = mAddedRelations.takeFirst(); + mAdding = true; + } else if (!mRemovedRelations.isEmpty()) { + relation = mRemovedRelations.takeFirst(); + mAdding = false; + } else { + Trace() << "Processing done"; + changeProcessed(); + return; + } + Trace() << "Processing " << (mAdding ? " add " : " remove ") << relation; + + //We have to fetch it again in case it changed since the notification was emitted (which is likely) + //Otherwise we get an empty remoteid for new tags that were immediately applied on an item + Akonadi::RelationFetchJob *fetch = new Akonadi::RelationFetchJob(relation); + connect(fetch, SIGNAL(result(KJob*)), this, SLOT(onRelationFetchDone(KJob*))); +} + +void KolabChangeItemsRelationsTask::onRelationFetchDone(KJob *job) +{ + Trace(); + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "RelatonFetch failed: " << job->errorString(); + processNextRelation(); + return; + } + + const Akonadi::Relation::List relations = static_cast(job)->relations(); + if (relations.size() != 1) { + qCWarning(KOLABRESOURCE_LOG) << "Invalid number of relations retrieved: " << relations.size(); + processNextRelation(); + return; + } + + Akonadi::Relation relation = relations.first(); + if (mAdding) { + addRelation(relation); + } else { + removeRelation(relation); + } +} + +void KolabChangeItemsRelationsTask::addRelation(const Akonadi::Relation &relation) +{ + Akonadi::ItemFetchJob *fetchJob = new Akonadi::ItemFetchJob(Akonadi::Item::List() << relation.left() << relation.right()); + fetchJob->fetchScope().setCacheOnly(true); + fetchJob->fetchScope().setAncestorRetrieval(Akonadi::ItemFetchScope::All); + fetchJob->fetchScope().setFetchGid(true); + fetchJob->fetchScope().fetchFullPayload(true); + fetchJob->setProperty("relation", QVariant::fromValue(relation)); + connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(onItemsFetched(KJob*))); +} + +void KolabChangeItemsRelationsTask::onItemsFetched(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "Failed to fetch items for relation: " << job->errorString(); + processNextRelation(); + return; + } + Akonadi::ItemFetchJob *fetchJob = static_cast(job); + if (fetchJob->items().size() != 2) { + qCWarning(KOLABRESOURCE_LOG) << "Invalid number of items retrieved: " << fetchJob->items().size(); + processNextRelation(); + return; + } + + const Akonadi::Item::List items = fetchJob->items(); + const Akonadi::Relation relation = job->property("relation").value(); + Akonadi::Item leftItem = items[0] == relation.left() ? items[0] : items[1]; + Akonadi::Item rightItem = items[0] == relation.right() ? items[0] : items[1]; + const QString left = KolabHelpers::createMemberUrl(leftItem, resourceState()->userName()); + const QString right = KolabHelpers::createMemberUrl(rightItem, resourceState()->userName()); + if (left.isEmpty() || right.isEmpty()) { + qCWarning(KOLABRESOURCE_LOG) << "Failed to add relation, invalid member: " << left << " : " << right; + processNextRelation(); + return; + } + QStringList members; + members.reserve(2); + members << left << right; + + const QLatin1String productId("Akonadi-Kolab-Resource"); + const KMime::Message::Ptr message = Kolab::KolabObjectWriter::writeRelation(relation, members, Kolab::KolabV3, productId); + + KIMAP::AppendJob *appendJob = new KIMAP::AppendJob(mSession); + appendJob->setMailBox(mailBoxForCollection(relationCollection())); + appendJob->setContent(message->encodedContent(true)); + appendJob->setInternalDate(message->date()->dateTime()); + connect(appendJob, SIGNAL(result(KJob*)), SLOT(onChangeCommitted(KJob*))); + appendJob->start(); +} + +void KolabChangeItemsRelationsTask::removeRelation(const Akonadi::Relation &relation) +{ + Trace(); + mCurrentRelation = relation; + const QString mailBox = mailBoxForCollection(relationCollection()); + + if (mSession->selectedMailBox() != mailBox) { + KIMAP::SelectJob *select = new KIMAP::SelectJob(mSession); + select->setMailBox(mailBox); + + connect(select, SIGNAL(result(KJob*)), this, SLOT(onSelectDone(KJob*))); + + select->start(); + } else { + triggerStoreJob(); + } +} + +void KolabChangeItemsRelationsTask::onSelectDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "Failed to select mailbox: " << job->errorString(); + cancelTask(job->errorString()); + } else { + triggerStoreJob(); + } +} + +void KolabChangeItemsRelationsTask::triggerStoreJob() +{ + KIMAP::ImapSet set; + set.add(mCurrentRelation.remoteId().toLong()); + + Trace() << set.toImapSequenceSet(); + + KIMAP::StoreJob *store = new KIMAP::StoreJob(mSession); + store->setUidBased(true); + store->setSequenceSet(set); + store->setFlags(QList() << ImapFlags::Deleted); + store->setMode(KIMAP::StoreJob::AppendFlags); + connect(store, SIGNAL(result(KJob*)), SLOT(onChangeCommitted(KJob*))); + store->start(); +} + +void KolabChangeItemsRelationsTask::onChangeCommitted(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "Error while storing change"; + cancelTask(job->errorString()); + } else { + processNextRelation(); + } +} + diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabchangeitemsrelationstask.h kdepim-runtime-15.08.0/resources/kolab/kolabchangeitemsrelationstask.h --- kdepim-runtime-4.14.6/resources/kolab/kolabchangeitemsrelationstask.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabchangeitemsrelationstask.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,56 @@ +/* + Copyright (c) 2014 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Krammer + + 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 KOLABCHANGEITEMSRELATIONSTASK_H +#define KOLABCHANGEITEMSRELATIONSTASK_H + +#include "kolabrelationresourcetask.h" + +class KolabChangeItemsRelationsTask : public KolabRelationResourceTask +{ + Q_OBJECT +public: + explicit KolabChangeItemsRelationsTask(ResourceStateInterface::Ptr resource, QObject *parent = 0); + +protected: + virtual void startRelationTask(KIMAP::Session *session); + +private Q_SLOTS: + void onRelationFetchDone(KJob *job); + + void addRelation(const Akonadi::Relation &relation); + void onItemsFetched(KJob *job); + void removeRelation(const Akonadi::Relation &relation); + void onSelectDone(KJob *job); + void triggerStoreJob(); + void onChangeCommitted(KJob *job); + +private: + void processNextRelation(); + + KIMAP::Session *mSession; + Akonadi::Relation::List mAddedRelations; + Akonadi::Relation::List mRemovedRelations; + Akonadi::Relation mCurrentRelation; + bool mAdding; +}; + +#endif diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabchangeitemstagstask.cpp kdepim-runtime-15.08.0/resources/kolab/kolabchangeitemstagstask.cpp --- kdepim-runtime-4.14.6/resources/kolab/kolabchangeitemstagstask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabchangeitemstagstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,141 @@ +/* + Copyright (c) 2014 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Krammer + + 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 "kolabchangeitemstagstask.h" +#include "kolabresource_debug.h" +#include "tagchangehelper.h" + +#include +#include +#include + +KolabChangeItemsTagsTask::KolabChangeItemsTagsTask(ResourceStateInterface::Ptr resource, QSharedPointer tagConverter, QObject *parent) + : KolabRelationResourceTask(resource, parent) + , mTagConverter(tagConverter) +{ +} + +void KolabChangeItemsTagsTask::startRelationTask(KIMAP::Session *session) +{ + mSession = session; + + //It's entierly possible that we don't have an rid yet + + // compile a set of changed tags + Q_FOREACH (const Akonadi::Tag &tag, resourceState()->addedTags()) { + mChangedTags.append(tag); + } + Q_FOREACH (const Akonadi::Tag &tag, resourceState()->removedTags()) { + mChangedTags.append(tag); + } + qCDebug(KOLABRESOURCE_LOG) << mChangedTags; + + processNextTag(); +} + +void KolabChangeItemsTagsTask::processNextTag() +{ + if (mChangedTags.isEmpty()) { + changeProcessed(); + return; + } + + // "take first" + const Akonadi::Tag tag = mChangedTags.takeFirst(); + + //We have to fetch it again in case it changed since the notification was emitted (which is likely) + //Otherwise we get an empty remoteid for new tags that were immediately applied on an item + Akonadi::TagFetchJob *fetch = new Akonadi::TagFetchJob(tag); + connect(fetch, SIGNAL(result(KJob*)), this, SLOT(onTagFetchDone(KJob*))); +} + +void KolabChangeItemsTagsTask::onTagFetchDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "TagFetch failed: " << job->errorString(); + // TODO: we could continue for the other tags? + cancelTask(job->errorString()); + return; + } + + const Akonadi::Tag::List tags = static_cast(job)->tags(); + if (tags.size() != 1) { + qCWarning(KOLABRESOURCE_LOG) << "Invalid number of tags retrieved: " << tags.size(); + // TODO: we could continue for the other tags? + cancelTask(job->errorString()); + return; + } + + Akonadi::ItemFetchJob *fetch = new Akonadi::ItemFetchJob(tags.first()); + fetch->fetchScope().setCacheOnly(true); + fetch->fetchScope().setAncestorRetrieval(Akonadi::ItemFetchScope::All); + fetch->fetchScope().setFetchGid(true); + fetch->fetchScope().fetchFullPayload(true); + fetch->setProperty("tag", QVariant::fromValue(tags.first())); + connect(fetch, SIGNAL(result(KJob*)), this, SLOT(onItemsFetchDone(KJob*))); +} + +void KolabChangeItemsTagsTask::onItemsFetchDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "ItemFetch failed: " << job->errorString(); + // TODO: we could continue for the other tags? + cancelTask(job->errorString()); + return; + } + + const Akonadi::Item::List items = static_cast(job)->items(); + qCDebug(KOLABRESOURCE_LOG) << items.size(); + + TagChangeHelper *changeHelper = new TagChangeHelper(this); + + connect(changeHelper, SIGNAL(applyCollectionChanges(Akonadi::Collection)), + this, SLOT(onApplyCollectionChanged(Akonadi::Collection))); + connect(changeHelper, SIGNAL(cancelTask(QString)), this, SLOT(onCancelTask(QString))); + connect(changeHelper, SIGNAL(changeCommitted()), this, SLOT(onChangeCommitted())); + + const Akonadi::Tag tag = job->property("tag").value(); + { + qCDebug(KOLABRESOURCE_LOG) << "Writing " << tag.name() << " with " << items.size() << " members to the server: "; + foreach (const Akonadi::Item &item, items) { + qCDebug(KOLABRESOURCE_LOG) << "member(localid, remoteid): " << item.id() << item.remoteId(); + } + } + Q_ASSERT(tag.isValid()); + changeHelper->start(tag, mTagConverter->createMessage(tag, items, resourceState()->userName()), mSession); +} + +void KolabChangeItemsTagsTask::onApplyCollectionChanged(const Akonadi::Collection &collection) +{ + mRelationCollection = collection; + applyCollectionChanges(collection); +} + +void KolabChangeItemsTagsTask::onCancelTask(const QString &errorText) +{ + // TODO: we could continue for the other tags? + cancelTask(errorText); +} + +void KolabChangeItemsTagsTask::onChangeCommitted() +{ + processNextTag(); +} diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabchangeitemstagstask.h kdepim-runtime-15.08.0/resources/kolab/kolabchangeitemstagstask.h --- kdepim-runtime-4.14.6/resources/kolab/kolabchangeitemstagstask.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabchangeitemstagstask.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,54 @@ +/* + Copyright (c) 2014 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Krammer + + 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 KOLABCHANGEITEMSTAGSTASK_H +#define KOLABCHANGEITEMSTAGSTASK_H + +#include "kolabrelationresourcetask.h" +#include "tagchangehelper.h" + +class KolabChangeItemsTagsTask : public KolabRelationResourceTask +{ + Q_OBJECT +public: + explicit KolabChangeItemsTagsTask(ResourceStateInterface::Ptr resource, QSharedPointer tagConverter, QObject *parent = 0); + +protected: + virtual void startRelationTask(KIMAP::Session *session); + +private: + KIMAP::Session *mSession; + QList mChangedTags; + QSharedPointer mTagConverter; + +private: + void processNextTag(); + +private Q_SLOTS: + void onItemsFetchDone(KJob *job); + void onTagFetchDone(KJob *job); + + void onApplyCollectionChanged(const Akonadi::Collection &collection); + void onCancelTask(const QString &errorText); + void onChangeCommitted(); +}; + +#endif // KOLABCHANGEITEMSTAGSTASK_H diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabchangetagtask.cpp kdepim-runtime-15.08.0/resources/kolab/kolabchangetagtask.cpp --- kdepim-runtime-4.14.6/resources/kolab/kolabchangetagtask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabchangetagtask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,82 @@ +/* + Copyright (c) 2014 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Krammer + + 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 "kolabchangetagtask.h" +#include "kolabresource_debug.h" +#include "tagchangehelper.h" + +#include +#include + +KolabChangeTagTask::KolabChangeTagTask(ResourceStateInterface::Ptr resource, QSharedPointer tagConverter, QObject *parent) + : KolabRelationResourceTask(resource, parent) + , mSession(0) + , mTagConverter(tagConverter) +{ +} + +void KolabChangeTagTask::startRelationTask(KIMAP::Session *session) +{ + mSession = session; + + Akonadi::ItemFetchJob *fetch = new Akonadi::ItemFetchJob(resourceState()->tag()); + fetch->fetchScope().setCacheOnly(true); + fetch->fetchScope().setFetchGid(true); + fetch->fetchScope().setAncestorRetrieval(Akonadi::ItemFetchScope::All); + fetch->fetchScope().fetchFullPayload(true); + connect(fetch, SIGNAL(result(KJob*)), this, SLOT(onItemsFetchDone(KJob*))); +} + +void KolabChangeTagTask::onItemsFetchDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "ItemFetch failed: " << job->errorString(); + cancelTask(job->errorString()); + return; + } + + const Akonadi::Item::List items = static_cast(job)->items(); + + TagChangeHelper *changeHelper = new TagChangeHelper(this); + + connect(changeHelper, SIGNAL(applyCollectionChanges(Akonadi::Collection)), + this, SLOT(onApplyCollectionChanged(Akonadi::Collection))); + connect(changeHelper, SIGNAL(cancelTask(QString)), this, SLOT(onCancelTask(QString))); + connect(changeHelper, SIGNAL(changeCommitted()), this, SLOT(onChangeCommitted())); + + changeHelper->start(resourceState()->tag(), mTagConverter->createMessage(resourceState()->tag(), items, resourceState()->userName()), mSession); +} + +void KolabChangeTagTask::onApplyCollectionChanged(const Akonadi::Collection &collection) +{ + mRelationCollection = collection; + applyCollectionChanges(collection); +} + +void KolabChangeTagTask::onCancelTask(const QString &errorText) +{ + cancelTask(errorText); +} + +void KolabChangeTagTask::onChangeCommitted() +{ + changeProcessed(); +} diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabchangetagtask.h kdepim-runtime-15.08.0/resources/kolab/kolabchangetagtask.h --- kdepim-runtime-4.14.6/resources/kolab/kolabchangetagtask.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabchangetagtask.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,49 @@ +/* + Copyright (c) 2014 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Krammer + + 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 KOLABCHANGETAGTASK_H +#define KOLABCHANGETAGTASK_H + +#include "kolabrelationresourcetask.h" +#include "tagchangehelper.h" + +class KolabChangeTagTask : public KolabRelationResourceTask +{ + Q_OBJECT +public: + explicit KolabChangeTagTask(ResourceStateInterface::Ptr resource, QSharedPointer tagConverter, QObject *parent = 0); + +protected: + virtual void startRelationTask(KIMAP::Session *session); + +private: + KIMAP::Session *mSession; + QSharedPointer mTagConverter; + +private Q_SLOTS: + void onItemsFetchDone(KJob *job); + + void onApplyCollectionChanged(const Akonadi::Collection &collection); + void onCancelTask(const QString &errorText); + void onChangeCommitted(); +}; + +#endif // KOLABCHANGETAGTASK_H diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabhelpers.cpp kdepim-runtime-15.08.0/resources/kolab/kolabhelpers.cpp --- kdepim-runtime-4.14.6/resources/kolab/kolabhelpers.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabhelpers.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,14 +18,17 @@ */ #include "kolabhelpers.h" +#include "kolabresource_debug.h" #include #include -#include -#include -#include +#include +#include +#include #include #include #include +#include +#include "tracer.h" bool KolabHelpers::checkForErrors(const Akonadi::Item &item) { @@ -40,11 +43,71 @@ errorMsg.append(QLatin1String("\n")); } - kWarning() << "Error on item with id: " << item.id() << " remote id: " << item.remoteId() << ":\n" << errorMsg; + qCWarning(KOLABRESOURCE_LOG) << "Error on item with id: " << item.id() << " remote id: " << item.remoteId() << ":\n" << errorMsg; Kolab::ErrorHandler::instance().clear(); return true; } +Akonadi::Item getErrorItem(Kolab::FolderType folderType, const QString &remoteId) +{ + //TODO set title, text and icon + Akonadi::Item item; + item.setRemoteId(remoteId); + switch (folderType) { + case Kolab::EventType: { + KCalCore::Event::Ptr event(new KCalCore::Event); + //FIXME Use message creation date time + event->setDtStart(KDateTime::currentUtcDateTime()); + event->setSummary(i18n("Corrupt Event")); + event->setDescription(i18n("Event could not be read. Delete this event to remove it from the server.")); + item.setMimeType(KCalCore::Event::eventMimeType()); + item.setPayload(event); + } + break; + case Kolab::TaskType: { + KCalCore::Todo::Ptr task(new KCalCore::Todo); + //FIXME Use message creation date time + task->setDtStart(KDateTime::currentUtcDateTime()); + task->setSummary(i18n("Corrupt Task")); + task->setDescription(i18n("Task could not be read. Delete this task to remove it from the server.")); + item.setMimeType(KCalCore::Todo::todoMimeType()); + item.setPayload(task); + } + break; + case Kolab::JournalType: { + KCalCore::Journal::Ptr journal(new KCalCore::Journal); + //FIXME Use message creation date time + journal->setDtStart(KDateTime::currentUtcDateTime()); + journal->setSummary(i18n("Corrupt journal")); + journal->setDescription(i18n("Journal could not be read. Delete this journal to remove it from the server.")); + item.setMimeType(KCalCore::Journal::journalMimeType()); + item.setPayload(journal); + } + break; + case Kolab::ContactType: { + KContacts::Addressee addressee; + addressee.setName(i18n("Corrupt Contact")); + addressee.setNote(i18n("Contact could not be read. Delete this contact to remove it from the server.")); + item.setMimeType(KContacts::Addressee::mimeType()); + item.setPayload(addressee); + } + break; + case Kolab::NoteType: { + Akonadi::NoteUtils::NoteMessageWrapper note; + note.setTitle(i18n("Corrupt Note")); + note.setText(i18n("Note could not be read. Delete this note to remove it from the server.")); + item.setPayload(Akonadi::NoteUtils::noteMimeType()); + item.setPayload(note.message()); + } + break; + case Kolab::MailType: + //We don't convert mails, so that should never fail. + default: + qCWarning(KOLABRESOURCE_LOG) << "unhandled folder type: " << folderType; + } + return item; +} + Akonadi::Item KolabHelpers::translateFromImap(Kolab::FolderType folderType, const Akonadi::Item &imapItem, bool &ok) { //Avoid trying to convert imap messages @@ -58,7 +121,7 @@ return Akonadi::Item(); } if (!imapItem.hasPayload()) { - kWarning() << "Payload is not a MessagePtr!"; + qCWarning(KOLABRESOURCE_LOG) << "Payload is not a MessagePtr!"; Q_ASSERT(false); ok = false; return Akonadi::Item(); @@ -67,88 +130,84 @@ const KMime::Message::Ptr payload = imapItem.payload(); const Kolab::KolabObjectReader reader(payload); if (checkForErrors(imapItem)) { - //By not delivering items we cannot translate, they are simply deleted from local storage - ok = false; - return Akonadi::Item(); + ok = true; + //We return an error object so the sync keeps working, and we can clean up the mess by simply deleting the object in the application. + return getErrorItem(folderType, imapItem.remoteId()); } switch (reader.getType()) { - case Kolab::EventObject: - case Kolab::TodoObject: - case Kolab::JournalObject: - { - const KCalCore::Incidence::Ptr incidencePtr = reader.getIncidence(); - if (!incidencePtr) { - kWarning() << "Failed to read incidence."; - ok = false; - return Akonadi::Item(); - } - Akonadi::Item newItem(incidencePtr->mimeType()); - newItem.setPayload(incidencePtr); - newItem.setRemoteId(imapItem.remoteId()); - newItem.setGid(incidencePtr->instanceIdentifier()); - return newItem; + case Kolab::EventObject: + case Kolab::TodoObject: + case Kolab::JournalObject: { + const KCalCore::Incidence::Ptr incidencePtr = reader.getIncidence(); + if (!incidencePtr) { + qCWarning(KOLABRESOURCE_LOG) << "Failed to read incidence."; + ok = false; + return Akonadi::Item(); } - break; - case Kolab::NoteObject: - { - const KMime::Message::Ptr note = reader.getNote(); - if (!note) { - kWarning() << "Failed to read note."; - ok = false; - return Akonadi::Item(); - } - Akonadi::Item newItem(QLatin1String("text/x-vnd.akonadi.note")); - newItem.setPayload(note); - newItem.setRemoteId(imapItem.remoteId()); - const Akonadi::NoteUtils::NoteMessageWrapper wrapper(note); - newItem.setGid(wrapper.uid()); - return newItem; - } - break; - case Kolab::ContactObject: - { - Akonadi::Item newItem(KABC::Addressee::mimeType()); - newItem.setPayload(reader.getContact()); - newItem.setRemoteId(imapItem.remoteId()); - newItem.setGid(reader.getContact().uid()); - return newItem; - } - break; - case Kolab::DistlistObject: - { - KABC::ContactGroup contactGroup = reader.getDistlist(); - - QList toAdd; - for (uint index = 0; index < contactGroup.contactReferenceCount(); ++index) { - const KABC::ContactGroup::ContactReference& reference = contactGroup.contactReference(index); - KABC::ContactGroup::ContactReference ref; - ref.setGid(reference.uid()); //libkolab set a gid with setUid() - toAdd << ref; - } - contactGroup.removeAllContactReferences(); - foreach (const KABC::ContactGroup::ContactReference &ref, toAdd) { - contactGroup.append(ref); - } - - Akonadi::Item newItem(KABC::ContactGroup::mimeType()); - newItem.setPayload(contactGroup); - newItem.setRemoteId(imapItem.remoteId()); - newItem.setGid(contactGroup.id()); - return newItem; + Akonadi::Item newItem(incidencePtr->mimeType()); + newItem.setPayload(incidencePtr); + newItem.setRemoteId(imapItem.remoteId()); + newItem.setGid(incidencePtr->instanceIdentifier()); + return newItem; + } + break; + case Kolab::NoteObject: { + const KMime::Message::Ptr note = reader.getNote(); + if (!note) { + qCWarning(KOLABRESOURCE_LOG) << "Failed to read note."; + ok = false; + return Akonadi::Item(); } + Akonadi::Item newItem(QLatin1String("text/x-vnd.akonadi.note")); + newItem.setPayload(note); + newItem.setRemoteId(imapItem.remoteId()); + const Akonadi::NoteUtils::NoteMessageWrapper wrapper(note); + newItem.setGid(wrapper.uid()); + return newItem; + } + break; + case Kolab::ContactObject: { + Akonadi::Item newItem(KContacts::Addressee::mimeType()); + newItem.setPayload(reader.getContact()); + newItem.setRemoteId(imapItem.remoteId()); + newItem.setGid(reader.getContact().uid()); + return newItem; + } + break; + case Kolab::DistlistObject: { + KContacts::ContactGroup contactGroup = reader.getDistlist(); + + QList toAdd; + for (uint index = 0; index < contactGroup.contactReferenceCount(); ++index) { + const KContacts::ContactGroup::ContactReference &reference = contactGroup.contactReference(index); + KContacts::ContactGroup::ContactReference ref; + ref.setGid(reference.uid()); //libkolab set a gid with setUid() + toAdd << ref; + } + contactGroup.removeAllContactReferences(); + foreach (const KContacts::ContactGroup::ContactReference &ref, toAdd) { + contactGroup.append(ref); + } + + Akonadi::Item newItem(KContacts::ContactGroup::mimeType()); + newItem.setPayload(contactGroup); + newItem.setRemoteId(imapItem.remoteId()); + newItem.setGid(contactGroup.id()); + return newItem; + } + break; + default: + qCWarning(KOLABRESOURCE_LOG) << "Object type not handled"; + ok = false; break; - default: - kWarning() << "Object type not handled"; - ok = false; - break; } - return Akonadi::Item(); + return Akonadi::Item(); } Akonadi::Item::List KolabHelpers::translateToImap(const Akonadi::Item::List &items, bool &ok) { Akonadi::Item::List imapItems; - Q_FOREACH(const Akonadi::Item &item, items) { + Q_FOREACH (const Akonadi::Item &item, items) { bool translationOk = true; imapItems << translateToImap(item, translationOk); if (!translationOk) { @@ -158,16 +217,16 @@ return imapItems; } -static KABC::ContactGroup convertToGidOnly(const KABC::ContactGroup &contactGroup) +static KContacts::ContactGroup convertToGidOnly(const KContacts::ContactGroup &contactGroup) { - QList toAdd; - for ( uint index = 0; index < contactGroup.contactReferenceCount(); ++index ) { - const KABC::ContactGroup::ContactReference& reference = contactGroup.contactReference( index ); + QList toAdd; + for (uint index = 0; index < contactGroup.contactReferenceCount(); ++index) { + const KContacts::ContactGroup::ContactReference &reference = contactGroup.contactReference(index); QString gid; if (!reference.gid().isEmpty()) { gid = reference.gid(); } else { - // WARNING: this is an ugly hack for backwards compatiblity. Normally this codepath shouldn't be hit. + // WARNING: this is an ugly hack for backwards compatibility. Normally this codepath shouldn't be hit. // Replace all references with real data-sets // Hopefully all resources are available during saving, so we can look up // in the addressbook to get name+email from the UID. @@ -183,17 +242,17 @@ if (items.count() != 1) { continue; } - const KABC::Addressee addressee = job->items().first().payload(); + const KContacts::Addressee addressee = job->items().at(0).payload(); gid = addressee.uid(); } - KABC::ContactGroup::ContactReference ref; + KContacts::ContactGroup::ContactReference ref; ref.setUid(gid); //libkolab expects a gid for uid() toAdd << ref; } - KABC::ContactGroup gidOnlyContactGroup = contactGroup; + KContacts::ContactGroup gidOnlyContactGroup = contactGroup; gidOnlyContactGroup.removeAllContactReferences(); - foreach ( const KABC::ContactGroup::ContactReference &ref, toAdd ) { - gidOnlyContactGroup.append( ref ); + foreach (const KContacts::ContactGroup::ContactReference &ref, toAdd) { + gidOnlyContactGroup.append(ref); } return gidOnlyContactGroup; } @@ -209,75 +268,73 @@ const QLatin1String productId("Akonadi-Kolab-Resource"); //Everthing stays the same, except mime type and payload Akonadi::Item imapItem = item; - imapItem.setMimeType( QLatin1String("message/rfc822") ); - switch(getKolabTypeFromMimeType(item.mimeType())) { + imapItem.setMimeType(QLatin1String("message/rfc822")); + try { + switch (getKolabTypeFromMimeType(item.mimeType())) { case Kolab::EventObject: case Kolab::TodoObject: - case Kolab::JournalObject: - { - Q_ASSERT(item.hasPayload()); - kDebug() << "converted event"; + case Kolab::JournalObject: { + qCDebug(KOLABRESOURCE_LOG) << "converted event"; const KMime::Message::Ptr message = Kolab::KolabObjectWriter::writeIncidence( - item.payload(), - Kolab::KolabV3, productId, QLatin1String("UTC") ); - imapItem.setPayload( message ); + item.payload(), + Kolab::KolabV3, productId, QStringLiteral("UTC")); + imapItem.setPayload(message); } break; - case Kolab::NoteObject: - { - Q_ASSERT(item.hasPayload()); - kDebug() << "converted note"; + case Kolab::NoteObject: { + qCDebug(KOLABRESOURCE_LOG) << "converted note"; const KMime::Message::Ptr message = Kolab::KolabObjectWriter::writeNote( - item.payload(), Kolab::KolabV3, productId); - imapItem.setPayload( message ); + item.payload(), Kolab::KolabV3, productId); + imapItem.setPayload(message); } break; - case Kolab::ContactObject: - { - Q_ASSERT(item.hasPayload()); - kDebug() << "converted contact"; + case Kolab::ContactObject: { + qCDebug(KOLABRESOURCE_LOG) << "converted contact"; const KMime::Message::Ptr message = Kolab::KolabObjectWriter::writeContact( - item.payload(), Kolab::KolabV3, productId); - imapItem.setPayload( message ); + item.payload(), Kolab::KolabV3, productId); + imapItem.setPayload(message); } break; - case Kolab::DistlistObject: - { - Q_ASSERT(item.hasPayload()); - const KABC::ContactGroup contactGroup = convertToGidOnly(item.payload()); - kDebug() << "converted distlist"; + case Kolab::DistlistObject: { + const KContacts::ContactGroup contactGroup = convertToGidOnly(item.payload()); + qCDebug(KOLABRESOURCE_LOG) << "converted distlist"; const KMime::Message::Ptr message = Kolab::KolabObjectWriter::writeDistlist( - contactGroup, Kolab::KolabV3, productId); - imapItem.setPayload( message ); + contactGroup, Kolab::KolabV3, productId); + imapItem.setPayload(message); } break; default: - kWarning() << "object type not handled: " << item.id() << item.mimeType(); + qCWarning(KOLABRESOURCE_LOG) << "object type not handled: " << item.id() << item.mimeType(); ok = false; return Akonadi::Item(); + } + } catch (const Akonadi::PayloadException &e) { + qCWarning(KOLABRESOURCE_LOG) << "The item contains the wrong or no payload: " << item.id() << item.mimeType(); + qCWarning(KOLABRESOURCE_LOG) << e.what(); + return Akonadi::Item(); } if (checkForErrors(item)) { - kWarning() << "an error occured while trying to translate the item to the kolab format: " << item.id(); + qCWarning(KOLABRESOURCE_LOG) << "an error occurred while trying to translate the item to the kolab format: " << item.id(); ok = false; return Akonadi::Item(); } return imapItem; } -QByteArray KolabHelpers::kolabTypeForMimeType( const QStringList &contentMimeTypes ) +QByteArray KolabHelpers::kolabTypeForMimeType(const QStringList &contentMimeTypes) { - if (contentMimeTypes.contains(KABC::Addressee::mimeType())) { + if (contentMimeTypes.contains(KContacts::Addressee::mimeType())) { return "contact"; - } else if (contentMimeTypes.contains( KCalCore::Event::eventMimeType())) { + } else if (contentMimeTypes.contains(KCalCore::Event::eventMimeType())) { return "event"; - } else if (contentMimeTypes.contains( KCalCore::Todo::todoMimeType())) { + } else if (contentMimeTypes.contains(KCalCore::Todo::todoMimeType())) { return "task"; - } else if (contentMimeTypes.contains( KCalCore::Journal::journalMimeType())) { + } else if (contentMimeTypes.contains(KCalCore::Journal::journalMimeType())) { return "journal"; } else if (contentMimeTypes.contains(QLatin1String("application/x-vnd.akonadi.note")) || - contentMimeTypes.contains(QLatin1String("text/x-vnd.akonadi.note"))) { + contentMimeTypes.contains(QLatin1String("text/x-vnd.akonadi.note"))) { return "note"; } return QByteArray(); @@ -291,9 +348,9 @@ return Kolab::TodoObject; } else if (type == KCalCore::Journal::journalMimeType()) { return Kolab::JournalObject; - } else if (type == KABC::Addressee::mimeType()) { + } else if (type == KContacts::Addressee::mimeType()) { return Kolab::ContactObject; - } else if (type == KABC::ContactGroup::mimeType()) { + } else if (type == KContacts::ContactGroup::mimeType()) { return Kolab::DistlistObject; } else if (type == QLatin1String("text/x-vnd.akonadi.note") || type == QLatin1String("application/x-vnd.akonadi.note")) { @@ -302,45 +359,65 @@ return Kolab::InvalidObject; } +QString KolabHelpers::getMimeType(Kolab::FolderType type) +{ + switch (type) { + case Kolab::MailType: + return KMime::Message::mimeType(); + case Kolab::ConfigurationType: + return QLatin1String(KOLAB_TYPE_RELATION); + default: + qCDebug(KOLABRESOURCE_LOG) << "unhandled folder type: " << type; + } + return QString(); +} + QStringList KolabHelpers::getContentMimeTypes(Kolab::FolderType type) { QStringList contentTypes; contentTypes << Akonadi::Collection::mimeType(); switch (type) { - case Kolab::EventType: - case Kolab::TaskType: - case Kolab::JournalType: - contentTypes << KCalCore::Incidence::mimeTypes(); - break; - case Kolab::ContactType: - contentTypes << KABC::Addressee::mimeType() << KABC::ContactGroup::mimeType(); - break; - case Kolab::NoteType: - contentTypes << QLatin1String("text/x-vnd.akonadi.note") << QLatin1String("application/x-vnd.akonadi.note"); - break; - case Kolab::MailType: - contentTypes << KMime::Message::mimeType(); - break; - default: - kDebug() << "unhandled folder type: " << type; + case Kolab::EventType: + contentTypes << KCalCore::Event().mimeType(); + break; + case Kolab::TaskType: + contentTypes << KCalCore::Todo().mimeType(); + break; + case Kolab::JournalType: + contentTypes << KCalCore::Journal().mimeType(); + break; + case Kolab::ContactType: + contentTypes << KContacts::Addressee::mimeType() << KContacts::ContactGroup::mimeType(); + break; + case Kolab::NoteType: + contentTypes << QStringLiteral("text/x-vnd.akonadi.note") << QStringLiteral("application/x-vnd.akonadi.note"); + break; + case Kolab::MailType: + contentTypes << KMime::Message::mimeType(); + break; + case Kolab::ConfigurationType: + contentTypes << QLatin1String(KOLAB_TYPE_RELATION); + break; + default: + break; } return contentTypes; } -Kolab::FolderType KolabHelpers::folderTypeFromString(const QByteArray& folderTypeName) +Kolab::FolderType KolabHelpers::folderTypeFromString(const QByteArray &folderTypeName) { - return Kolab::folderTypeFromString( std::string(folderTypeName.data(), folderTypeName.size()) ); + return Kolab::folderTypeFromString(std::string(folderTypeName.data(), folderTypeName.size())); } QByteArray KolabHelpers::getFolderTypeAnnotation(const QMap< QByteArray, QByteArray > &annotations) { if (annotations.contains("/shared" KOLAB_FOLDER_TYPE_ANNOTATION)) { - return annotations.value( "/shared" KOLAB_FOLDER_TYPE_ANNOTATION); + return annotations.value("/shared" KOLAB_FOLDER_TYPE_ANNOTATION); } return annotations.value(KOLAB_FOLDER_TYPE_ANNOTATION); } -void KolabHelpers::setFolderTypeAnnotation(QMap< QByteArray, QByteArray >& annotations, const QByteArray& value) +void KolabHelpers::setFolderTypeAnnotation(QMap< QByteArray, QByteArray > &annotations, const QByteArray &value) { annotations["/shared" KOLAB_FOLDER_TYPE_ANNOTATION] = value; } @@ -348,20 +425,20 @@ QString KolabHelpers::getIcon(Kolab::FolderType type) { switch (type) { - case Kolab::EventType: - case Kolab::TaskType: - case Kolab::JournalType: - return QLatin1String("view-calendar"); - case Kolab::ContactType: - return QLatin1String("view-pim-contacts"); - case Kolab::NoteType: - return QLatin1String("view-pim-notes"); - case Kolab::MailType: - case Kolab::ConfigurationType: - case Kolab::FreebusyType: - case Kolab::FileType: - default: - break; + case Kolab::EventType: + case Kolab::TaskType: + case Kolab::JournalType: + return QStringLiteral("view-calendar"); + case Kolab::ContactType: + return QStringLiteral("view-pim-contacts"); + case Kolab::NoteType: + return QStringLiteral("view-pim-notes"); + case Kolab::MailType: + case Kolab::ConfigurationType: + case Kolab::FreebusyType: + case Kolab::FileType: + default: + break; } return QString(); } @@ -369,19 +446,57 @@ bool KolabHelpers::isHandledType(Kolab::FolderType type) { switch (type) { - case Kolab::EventType: - case Kolab::TaskType: - case Kolab::JournalType: - case Kolab::ContactType: - case Kolab::NoteType: - case Kolab::MailType: - return true; - case Kolab::ConfigurationType: - case Kolab::FreebusyType: - case Kolab::FileType: - default: - break; + case Kolab::EventType: + case Kolab::TaskType: + case Kolab::JournalType: + case Kolab::ContactType: + case Kolab::NoteType: + case Kolab::MailType: + return true; + case Kolab::ConfigurationType: + case Kolab::FreebusyType: + case Kolab::FileType: + default: + break; } return false; } +QList KolabHelpers::ancestorChain(const Akonadi::Collection &col) +{ + Q_ASSERT(col.isValid()); + if (col.parentCollection() == Akonadi::Collection::root() || col == Akonadi::Collection::root() || !col.isValid()) { + return QList(); + } + QList ancestors = ancestorChain(col.parentCollection()); + Q_ASSERT(!col.remoteId().isEmpty()); + ancestors << col.remoteId().toLatin1().mid(1); //We strip the first character which is always the separator + return ancestors; +} + +QString KolabHelpers::createMemberUrl(const Akonadi::Item &item, const QString &user) +{ + Trace() << item.id() << item.mimeType() << item.gid() << item.hasPayload(); + Kolab::RelationMember member; + if (item.mimeType() == KMime::Message::mimeType()) { + if (!item.hasPayload()) { + qCWarning(KOLABRESOURCE_LOG) << "Email without payload, failed to add to tag: " << item.id() << item.remoteId(); + return QString(); + } + KMime::Message::Ptr msg = item.payload(); + member.uid = item.remoteId().toLong(); + member.user = user; + member.subject = msg->subject()->asUnicodeString(); + member.messageId = msg->messageID()->asUnicodeString(); + member.date = msg->date()->asUnicodeString(); + member.mailbox = ancestorChain(item.parentCollection()); + } else { + if (item.gid().isEmpty()) { + qCWarning(KOLABRESOURCE_LOG) << "Groupware object without GID, failed to add to tag: " << item.id() << item.remoteId(); + return QString(); + } + member.gid = item.gid(); + } + return Kolab::generateMemberUrl(member); +} + diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabhelpers.h kdepim-runtime-15.08.0/resources/kolab/kolabhelpers.h --- kdepim-runtime-4.14.6/resources/kolab/kolabhelpers.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabhelpers.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,25 +20,29 @@ #ifndef KOLABHELPERS_H #define KOLABHELPERS_H -#include +#include #include //libkolab #include //libkolab -class KolabHelpers { +class KolabHelpers +{ public: static bool checkForErrors(const Akonadi::Item &affectedItem); static Akonadi::Item translateFromImap(Kolab::FolderType folderType, const Akonadi::Item &item, bool &ok); static Akonadi::Item::List translateToImap(const Akonadi::Item::List &items, bool &ok); static Akonadi::Item translateToImap(const Akonadi::Item &item, bool &ok); - static Kolab::FolderType folderTypeFromString( const QByteArray &folderTypeName ); - static QByteArray getFolderTypeAnnotation( const QMap &annotations); - static void setFolderTypeAnnotation( QMap &annotations, const QByteArray &value); + static Kolab::FolderType folderTypeFromString(const QByteArray &folderTypeName); + static QByteArray getFolderTypeAnnotation(const QMap &annotations); + static void setFolderTypeAnnotation(QMap &annotations, const QByteArray &value); static Kolab::ObjectType getKolabTypeFromMimeType(const QString &type); - static QByteArray kolabTypeForMimeType( const QStringList &contentMimeTypes ); + static QByteArray kolabTypeForMimeType(const QStringList &contentMimeTypes); static QStringList getContentMimeTypes(Kolab::FolderType type); static QString getIcon(Kolab::FolderType type); //Returns true if the folder type shouldn't be ignored static bool isHandledType(Kolab::FolderType type); + static QString getMimeType(Kolab::FolderType type); + static QList ancestorChain(const Akonadi::Collection &col); + static QString createMemberUrl(const Akonadi::Item &item, const QString &user); }; -#endif \ No newline at end of file +#endif diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabmessagehelper.cpp kdepim-runtime-15.08.0/resources/kolab/kolabmessagehelper.cpp --- kdepim-runtime-4.14.6/resources/kolab/kolabmessagehelper.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabmessagehelper.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,7 +23,7 @@ #include //libkolab #include "kolabhelpers.h" - +#include "kolabresource_debug.h" KolabMessageHelper::KolabMessageHelper(const Akonadi::Collection &col) : mCollection(col) @@ -37,16 +37,16 @@ } Akonadi::Item KolabMessageHelper::createItemFromMessage(KMime::Message::Ptr message, - const qint64 uid, - const qint64 size, - const QList &attrs, - const QList &flags, - const KIMAP::FetchJob::FetchScope &scope, - bool &ok) const + const qint64 uid, + const qint64 size, + const QList &attrs, + const QList &flags, + const KIMAP::FetchJob::FetchScope &scope, + bool &ok) const { const Akonadi::Item item = MessageHelper::createItemFromMessage(message, uid, size, attrs, flags, scope, ok); if (!ok) { - kWarning() << "Failed to read imap message"; + qCWarning(KOLABRESOURCE_LOG) << "Failed to read imap message"; return item; } Kolab::FolderType folderType = Kolab::MailType; diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabmessagehelper.h kdepim-runtime-15.08.0/resources/kolab/kolabmessagehelper.h --- kdepim-runtime-4.14.6/resources/kolab/kolabmessagehelper.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabmessagehelper.h 2015-08-10 21:01:02.000000000 +0000 @@ -21,19 +21,20 @@ #define KOLABMESSAGEHELPER_H #include -#include +#include -class KolabMessageHelper : public MessageHelper { +class KolabMessageHelper : public MessageHelper +{ public: explicit KolabMessageHelper(const Akonadi::Collection &collection); virtual ~KolabMessageHelper(); virtual Akonadi::Item createItemFromMessage(KMime::Message::Ptr message, - const qint64 uid, - const qint64 size, - const QList &attrs, - const QList &flags, - const KIMAP::FetchJob::FetchScope &scope, - bool &ok) const; + const qint64 uid, + const qint64 size, + const QList &attrs, + const QList &flags, + const KIMAP::FetchJob::FetchScope &scope, + bool &ok) const; private: Akonadi::Collection mCollection; diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabrelationresourcetask.cpp kdepim-runtime-15.08.0/resources/kolab/kolabrelationresourcetask.cpp --- kdepim-runtime-4.14.6/resources/kolab/kolabrelationresourcetask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabrelationresourcetask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,138 @@ +/* + Copyright (c) 2014 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Krammer + + 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 "kolabrelationresourcetask.h" +#include "kolabresource_debug.h" +#include "kolabhelpers.h" + +#include +#include +#include +#include +#include + +#include + +KolabRelationResourceTask::KolabRelationResourceTask(ResourceStateInterface::Ptr resource, QObject *parent) + : ResourceTask(DeferIfNoSession, resource, parent) + , mImapSession(0) +{ +} + +Akonadi::Collection KolabRelationResourceTask::relationCollection() const +{ + return mRelationCollection; +} + +void KolabRelationResourceTask::doStart(KIMAP::Session *session) +{ + mImapSession = session; + + // need to find the configuration collection. + + Akonadi::Collection topLevelCollection; + topLevelCollection.setRemoteId(rootRemoteId()); + topLevelCollection.setParentCollection(Akonadi::Collection::root()); + + Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(topLevelCollection, Akonadi::CollectionFetchJob::Recursive); + fetchJob->fetchScope().setResource(resourceState()->resourceIdentifier()); + fetchJob->fetchScope().setContentMimeTypes(QStringList() << KolabHelpers::getMimeType(Kolab::ConfigurationType)); + fetchJob->fetchScope().setAncestorRetrieval(Akonadi::CollectionFetchScope::All); + fetchJob->fetchScope().setListFilter(Akonadi::CollectionFetchScope::NoFilter); + connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(onCollectionFetchResult(KJob*))); +} + +void KolabRelationResourceTask::onCollectionFetchResult(KJob *job) +{ + if (job->error() == 0) { + Akonadi::CollectionFetchJob *fetchJob = qobject_cast(job); + Q_ASSERT(fetchJob != 0); + + Q_FOREACH (const Akonadi::Collection &collection, fetchJob->collections()) { + const QString mailBox = mailBoxForCollection(collection); + if (!mailBox.isEmpty()) { + mRelationCollection = collection; + startRelationTask(mImapSession); + return; + } + } + } + + qCDebug(KOLABRESOURCE_LOG) << "Couldn't find collection for relations, creating one."; + + const QChar separator = separatorCharacter(); + mRelationCollection = Akonadi::Collection(); + mRelationCollection.setName(QStringLiteral("Configuration")); + mRelationCollection.setContentMimeTypes(QStringList() << KolabHelpers::getMimeType(Kolab::ConfigurationType)); + mRelationCollection.setRemoteId(separator + mRelationCollection.name()); + const QString newMailBox = QStringLiteral("Configuration"); + KIMAP::CreateJob *imapCreateJob = new KIMAP::CreateJob(mImapSession); + imapCreateJob->setMailBox(newMailBox); + connect(imapCreateJob, SIGNAL(result(KJob*)), + this, SLOT(onCreateDone(KJob*))); + imapCreateJob->start(); +} + +void KolabRelationResourceTask::onCreateDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "Failed to create configuration folder: " << job->errorString(); + cancelTask(i18n("Failed to create configuration folder on server")); + return; + } + + KIMAP::SetMetaDataJob *setMetadataJob = new KIMAP::SetMetaDataJob(mImapSession); + if (serverCapabilities().contains(QLatin1String("METADATA"))) { + setMetadataJob->setServerCapability(KIMAP::MetaDataJobBase::Metadata); + } else { + setMetadataJob->setServerCapability(KIMAP::MetaDataJobBase::Annotatemore); + } + setMetadataJob->setMailBox(QStringLiteral("Configuration")); + setMetadataJob->addMetaData("/shared/vendor/kolab/folder-type", "configuration.default"); + connect(setMetadataJob, SIGNAL(result(KJob*)), + this, SLOT(onSetMetaDataDone(KJob*))); + setMetadataJob->start(); +} + +void KolabRelationResourceTask::onSetMetaDataDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "Failed to write annotations: " << job->errorString(); + cancelTask(i18n("Failed to write some annotations for '%1' on the IMAP server. %2", + collection().name(), job->errorText())); + return; + } + + Akonadi::CollectionCreateJob *createJob = new Akonadi::CollectionCreateJob(mRelationCollection, this); + connect(createJob, SIGNAL(result(KJob*)), this, SLOT(onLocalCreateDone(KJob*))); +} + +void KolabRelationResourceTask::onLocalCreateDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "Failed to create local folder: " << job->errorString(); + cancelTask(i18n("Failed to create configuration folder")); + return; + } + mRelationCollection = static_cast(job)->collection(); + startRelationTask(mImapSession); +} + diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabrelationresourcetask.h kdepim-runtime-15.08.0/resources/kolab/kolabrelationresourcetask.h --- kdepim-runtime-4.14.6/resources/kolab/kolabrelationresourcetask.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabrelationresourcetask.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,56 @@ +/* + Copyright (c) 2014 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Krammer + + 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 KOLABRELATIONRESOURCETASK_H +#define KOLABRELATIONRESOURCETASK_H + +#include + +class KolabRelationResourceTask : public ResourceTask +{ + Q_OBJECT +public: + explicit KolabRelationResourceTask(ResourceStateInterface::Ptr resource, QObject *parent = 0); + + Akonadi::Collection relationCollection() const; + + using ResourceTask::mailBoxForCollection; + using ResourceTask::resourceState; + +protected: + Akonadi::Collection mRelationCollection; + +protected: + virtual void doStart(KIMAP::Session *session); + + virtual void startRelationTask(KIMAP::Session *session) = 0; + +private: + KIMAP::Session *mImapSession; + +private Q_SLOTS: + void onCollectionFetchResult(KJob *job); + void onCreateDone(KJob *job); + void onSetMetaDataDone(KJob *job); + void onLocalCreateDone(KJob *job); +}; + +#endif // KOLABRELATIONRESOURCETASK_H diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabremovetagtask.cpp kdepim-runtime-15.08.0/resources/kolab/kolabremovetagtask.cpp --- kdepim-runtime-4.14.6/resources/kolab/kolabremovetagtask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabremovetagtask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,97 @@ +/* + Copyright (c) 2014 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Krammer + + 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 "kolabremovetagtask.h" +#include "kolabresource_debug.h" +#include + +#include +#include +#include +#include "tracer.h" + +KolabRemoveTagTask::KolabRemoveTagTask(ResourceStateInterface::Ptr resource, QObject *parent) + : KolabRelationResourceTask(resource, parent) +{ +} + +void KolabRemoveTagTask::startRelationTask(KIMAP::Session *session) +{ + // The imap specs do not allow for a single message to be deleted. We can only + // set the \Deleted flag. The message will actually be deleted when EXPUNGE will + // be issued on the next retrieveItems(). + + const QString mailBox = mailBoxForCollection(relationCollection()); + + Trace() << mailBox; + qCDebug(KOLABRESOURCE_LOG) << "Deleting tag " << resourceState()->tag().name() << " from " << mailBox; + + if (session->selectedMailBox() != mailBox) { + KIMAP::SelectJob *select = new KIMAP::SelectJob(session); + select->setMailBox(mailBox); + + connect(select, SIGNAL(result(KJob*)), + this, SLOT(onSelectDone(KJob*))); + + select->start(); + + } else { + triggerStoreJob(session); + } +} + +void KolabRemoveTagTask::triggerStoreJob(KIMAP::Session *session) +{ + KIMAP::ImapSet set; + set.add(resourceState()->tag().remoteId().toLong()); + Trace() << set.toImapSequenceSet(); + + KIMAP::StoreJob *store = new KIMAP::StoreJob(session); + store->setUidBased(true); + store->setSequenceSet(set); + store->setFlags(QList() << ImapFlags::Deleted); + store->setMode(KIMAP::StoreJob::AppendFlags); + connect(store, SIGNAL(result(KJob*)), SLOT(onStoreFlagsDone(KJob*))); + store->start(); +} + +void KolabRemoveTagTask::onSelectDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "Failed to select mailbox: " << job->errorString(); + cancelTask(job->errorString()); + } else { + KIMAP::SelectJob *select = static_cast(job); + triggerStoreJob(select->session()); + } +} + +void KolabRemoveTagTask::onStoreFlagsDone(KJob *job) +{ + Trace(); + //TODO use UID EXPUNGE if available + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "Failed to append flags: " << job->errorString(); + cancelTask(job->errorString()); + } else { + changeProcessed(); + } +} diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabremovetagtask.h kdepim-runtime-15.08.0/resources/kolab/kolabremovetagtask.h --- kdepim-runtime-4.14.6/resources/kolab/kolabremovetagtask.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabremovetagtask.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,44 @@ +/* + Copyright (c) 2014 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Krammer + + 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 KOLABREMOVETAGTASK_H +#define KOLABREMOVETAGTASK_H + +#include "kolabrelationresourcetask.h" + +class KolabRemoveTagTask : public KolabRelationResourceTask +{ + Q_OBJECT +public: + explicit KolabRemoveTagTask(ResourceStateInterface::Ptr resource, QObject *parent = 0); + +protected: + virtual void startRelationTask(KIMAP::Session *session); + +private: + void triggerStoreJob(KIMAP::Session *session); + +private Q_SLOTS: + void onSelectDone(KJob *job); + void onStoreFlagsDone(KJob *job); +}; + +#endif // KOLABREMOVETAGTASK_H diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabresource.cpp kdepim-runtime-15.08.0/resources/kolab/kolabresource.cpp --- kdepim-runtime-4.14.6/resources/kolab/kolabresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,26 +19,38 @@ #include "kolabresource.h" +#include "kolabresource_debug.h" +#include "setupserver.h" #include #include -#include #include #include +#include +#include +#include #include -#include -#include -#include +#include -#include "kolabretrievecollectionstask.h" +#include "kolabretrievetagstask.h" #include "kolabresourcestate.h" #include "kolabhelpers.h" +#include "kolabsettings.h" +#include "kolabaddtagtask.h" +#include "kolabchangeitemstagstask.h" +#include "kolabchangeitemsrelationstask.h" +#include "kolabchangetagtask.h" +#include "kolabremovetagtask.h" +#include "kolabretrievecollectionstask.h" +#include "kolabretrievetagstask.h" +#include "tracer.h" -KolabResource::KolabResource(const QString& id) - :ImapResource(id) +KolabResource::KolabResource(const QString &id) + : ImapResource(id) { - //Load translations from imap resource - KGlobal::locale()->insertCatalog(QLatin1String("akonadi_imap_resource")); + //Ensure we have up-to date metadata before attempting to sync folder + setScheduleAttributeSyncBeforeItemSync(true); + setKeepLocalCollectionChanges(QSet() << "ENTITYDISPLAY" << Akonadi::BlockAlarmsAttribute().type()); } KolabResource::~KolabResource() @@ -46,11 +58,36 @@ } +Settings *KolabResource::settings() const +{ + if (m_settings == 0) { + m_settings = new KolabSettings; + } + + return m_settings; +} + +void KolabResource::delayedInit() +{ + ImapResource::delayedInit(); + settings()->setRetrieveMetadataOnFolderListing(false); + Q_ASSERT(!settings()->retrieveMetadataOnFolderListing()); +} + QString KolabResource::defaultName() const { return i18n("Kolab Resource"); } +QDialog *KolabResource::createConfigureDialog(WId windowId) +{ + SetupServer *dlg = new SetupServer(this, windowId); + KWindowSystem::setMainWindow(dlg, windowId); + dlg->setWindowIcon(QIcon::fromTheme(QStringLiteral("kolab"))); + connect(dlg, SIGNAL(finished(int)), this, SLOT(onConfigurationDone(int)));; + return dlg; +} + ResourceStateInterface::Ptr KolabResource::createResourceState(const TaskArguments &args) { return ResourceStateInterface::Ptr(new KolabResourceState(this, args)); @@ -58,87 +95,47 @@ void KolabResource::retrieveCollections() { + Trace(); emit status(AgentBase::Running, i18nc("@info:status", "Retrieving folders")); - setKeepLocalCollectionChanges(QSet() << "CONTENTMIMETYPES" << "AccessRights"); startTask(new KolabRetrieveCollectionsTask(createResourceState(TaskArguments()), this)); + synchronizeTags(); + synchronizeRelations(); } -void KolabResource::retrieveItems(const Akonadi::Collection &col) -{ - //The collection that we receive was fetched when the task was scheduled, it is therefore possible that it is outdated. - //We refetch the collection since we rely on up-to-date annotations. - //FIXME: because this is async and not part of the resourcetask, it can't be killed. ResourceBase should just provide an up-to date copy of the collection. - Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(col, Akonadi::CollectionFetchJob::Base, this); - fetchJob->fetchScope().setAncestorRetrieval(Akonadi::CollectionFetchScope::All); - fetchJob->fetchScope().setIncludeStatistics(true); - fetchJob->fetchScope().setIncludeUnsubscribed(true); - connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(onItemRetrievalCollectionFetchDone(KJob*))); -} - -void KolabResource::onItemRetrievalCollectionFetchDone(KJob *job) -{ - if (job->error()) { - kWarning() << "Failed to retrieve collection before RetrieveItemsTask: " << job->errorString(); - cancelTask(i18n("Failed to retrieve items.")); - return; - } - - Akonadi::CollectionFetchJob *fetchJob = static_cast(job); - Q_ASSERT(fetchJob->collections().size() == 1); - const Akonadi::Collection col = fetchJob->collections().first(); - - //This is the only part that differs form the imap resource: We make sure the annotations are up-to date before synchronizing - //HACK avoid infinite recursions, the metadatatask should be scheduled at most once per retrieveItemsJob - static QSet updatedCollections; - if (!updatedCollections.contains(col.id()) && - (!col.attribute() || - col.attribute()->timestamp() < QDateTime::currentDateTime().addSecs(-60).toTime_t())) { - updatedCollections.insert(col.id()); - synchronizeCollectionAttributes(col.id()); - deferTask(); - return; - } - updatedCollections.remove(col.id()); - - setItemStreamingEnabled(true); - - RetrieveItemsTask *task = new RetrieveItemsTask( createResourceState(TaskArguments(col)), this); - connect(task, SIGNAL(status(int,QString)), SIGNAL(status(int,QString))); - connect(this, SIGNAL(retrieveNextItemSyncBatch(int)), task, SLOT(onReadyForNextBatch(int))); - startTask(task); -} - -void KolabResource::itemAdded(const Akonadi::Item& item, const Akonadi::Collection& collection) +void KolabResource::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) { + Trace() << item.id() << collection.id(); bool ok = true; const Akonadi::Item imapItem = KolabHelpers::translateToImap(item, ok); if (!ok) { - kWarning() << "Failed to convert item"; + qCWarning(KOLABRESOURCE_LOG) << "Failed to convert item"; cancelTask(); return; } ImapResource::itemAdded(imapItem, collection); } -void KolabResource::itemChanged(const Akonadi::Item& item, const QSet< QByteArray >& parts) +void KolabResource::itemChanged(const Akonadi::Item &item, const QSet< QByteArray > &parts) { + Trace() << item.id() << parts; bool ok = true; const Akonadi::Item imapItem = KolabHelpers::translateToImap(item, ok); if (!ok) { - kWarning() << "Failed to convert item"; + qCWarning(KOLABRESOURCE_LOG) << "Failed to convert item"; cancelTask(); return; } ImapResource::itemChanged(imapItem, parts); } -void KolabResource::itemsMoved(const Akonadi::Item::List& items, const Akonadi::Collection& source, const Akonadi::Collection& destination) +void KolabResource::itemsMoved(const Akonadi::Item::List &items, const Akonadi::Collection &source, const Akonadi::Collection &destination) { + Trace() << items.size() << source.id() << destination.id(); bool ok = true; const Akonadi::Item::List imapItems = KolabHelpers::translateToImap(items, ok); if (!ok) { - kWarning() << "Failed to convert item"; + qCWarning(KOLABRESOURCE_LOG) << "Failed to convert item"; cancelTask(); return; } @@ -147,6 +144,7 @@ static Akonadi::Collection updateAnnotations(const Akonadi::Collection &collection) { + Trace() << collection.id(); //Set the annotations on new folders const QByteArray kolabType = KolabHelpers::kolabTypeForMimeType(collection.contentMimeTypes()); if (!kolabType.isEmpty()) { @@ -160,8 +158,9 @@ return collection; } -void KolabResource::collectionAdded(const Akonadi::Collection& collection, const Akonadi::Collection& parent) +void KolabResource::collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent) { + Trace() << collection.id() << parent.id(); //Set the annotations on new folders const Akonadi::Collection col = updateAnnotations(collection); //TODO we need to save the collections as well if the annotations have changed @@ -169,12 +168,67 @@ ImapResource::collectionAdded(col, parent); } -void KolabResource::collectionChanged(const Akonadi::Collection& collection, const QSet< QByteArray >& parts) +void KolabResource::collectionChanged(const Akonadi::Collection &collection, const QSet< QByteArray > &parts) { + Trace() << collection.id() << parts; //Update annotations if necessary const Akonadi::Collection col = updateAnnotations(collection); //TODO we need to save the collections as well if the annotations have changed - ImapResource::collectionChanged(col, parts); + emit status(AgentBase::Running, i18nc("@info:status", "Updating folder '%1'", collection.name())); + ChangeCollectionTask *task = new ChangeCollectionTask(createResourceState(TaskArguments(collection, parts)), this); + task->syncEnabledState(true); + startTask(task); +} + +void KolabResource::tagAdded(const Akonadi::Tag &tag) +{ + Trace() << tag.id(); + KolabAddTagTask *task = new KolabAddTagTask(createResourceState(TaskArguments(tag)), this); + startTask(task); +} + +void KolabResource::tagChanged(const Akonadi::Tag &tag) +{ + Trace() << tag.id(); + KolabChangeTagTask *task = new KolabChangeTagTask(createResourceState(TaskArguments(tag)), QSharedPointer(new TagConverter), this); + startTask(task); +} + +void KolabResource::tagRemoved(const Akonadi::Tag &tag) +{ + Trace() << tag.id(); + KolabRemoveTagTask *task = new KolabRemoveTagTask(createResourceState(TaskArguments(tag)), this); + startTask(task); +} + +void KolabResource::itemsTagsChanged(const Akonadi::Item::List &items, const QSet &addedTags, const QSet &removedTags) +{ + Trace() << items.size() << addedTags.size() << removedTags.size(); + KolabChangeItemsTagsTask *task = new KolabChangeItemsTagsTask(createResourceState(TaskArguments(items, addedTags, removedTags)), QSharedPointer(new TagConverter), this); + startTask(task); +} + +void KolabResource::retrieveTags() +{ + Trace(); + KolabRetrieveTagTask *task = new KolabRetrieveTagTask(createResourceState(TaskArguments()), KolabRetrieveTagTask::RetrieveTags, this); + startTask(task); +} + +void KolabResource::retrieveRelations() +{ + Trace(); + KolabRetrieveTagTask *task = new KolabRetrieveTagTask(createResourceState(TaskArguments()), KolabRetrieveTagTask::RetrieveRelations, this); + startTask(task); +} + +void KolabResource::itemsRelationsChanged(const Akonadi::Item::List &items, + const Akonadi::Relation::List &addedRelations, + const Akonadi::Relation::List &removedRelations) +{ + Trace() << items.size() << addedRelations.size() << removedRelations.size(); + KolabChangeItemsRelationsTask *task = new KolabChangeItemsRelationsTask(createResourceState(TaskArguments(items, addedRelations, removedRelations))); + startTask(task); } -AKONADI_RESOURCE_MAIN( KolabResource ) +AKONADI_RESOURCE_MAIN(KolabResource) diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabresource_debug.cpp kdepim-runtime-15.08.0/resources/kolab/kolabresource_debug.cpp --- kdepim-runtime-4.14.6/resources/kolab/kolabresource_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabresource_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2015 Laurent Montel + + 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 "kolabresource_debug.h" +Q_LOGGING_CATEGORY(KOLABRESOURCE_LOG, "log_kolabresource") + diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabresource_debug.h kdepim-runtime-15.08.0/resources/kolab/kolabresource_debug.h --- kdepim-runtime-4.14.6/resources/kolab/kolabresource_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabresource_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2015 Laurent Montel + + 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 KOLABRESOURCE_DEBUG_H +#define KOLABRESOURCE_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(KOLABRESOURCE_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabresource.desktop kdepim-runtime-15.08.0/resources/kolab/kolabresource.desktop --- kdepim-runtime-4.14.6/resources/kolab/kolabresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -9,7 +9,7 @@ Name[de]=Kolab Groupware-Server Name[el]=Εξυπηρετητής Groupware Kolab Name[en_GB]=Kolab Groupware Server -Name[es]=Servidor de trabajo en grupo Kolab +Name[es]=Servidor de colaboración Kolab Name[et]=Kolabi grupitöö server Name[fi]=Kolab-työryhmäpalvelin Name[fr]=Serveur de logiciels de collaboration Kolab @@ -46,15 +46,16 @@ Name[zh_CN]=Kolab 群件服务器 Name[zh_TW]=Kolab 群組伺服器 Comment=Provides access to Kolab groupware folders and e-mail on a Kolab IMAP Server. -Comment[bs]=Omogućava pristup Kolab grupnim direktorijima i elektronskoj pošti na Kolab IMAP serveru Comment[ca]=Proporciona accés a les carpetes i al correu electrònic del treball en grup Kolab en un servidor IMAP del Kolab. Comment[da]=Giver adgang til Kolab groupware-mapper og e-mail på en Kolab IMAP-server. Comment[de]=Ermöglicht den Zugriff auf Kolab-Groupware-Ordner auf einem Kolab-IMAP-Server. +Comment[el]=Προσφέρει πρόσβαση σε φακέλους Kolab groupware και ηλ.αλληλογραφία σε έναν εξυπηρετητή Kolab IMAP. Comment[en_GB]=Provides access to Kolab groupware folders and e-mail on a Kolab IMAP Server. -Comment[es]=Proporciona acceso a carpetas de trabajo en grupo de Kolab y correo en un servidor IMAP Kolab. +Comment[es]=Proporciona acceso a carpetas de colaboración de Kolab y correo en un servidor IMAP Kolab. Comment[et]=Ligipääsu tagamine Kolabi grupitöökaustadele ja kirjadele Kolabi IMAP serveris. Comment[fi]=Tarjoaa pääsyn Kolab-työryhmäkansioihin ja sähköpostiin Kolab IMAP-palvelimella. Comment[fr]=Fournit l'accès aux dossiers et aux courriels du logiciel de collaboration Kolab sur un serveur IMAP. +Comment[gl]=Fornece acceso aos cartafoles de traballo en grupo de Kolab dun servidor de IMAP. Comment[hu]=Hozzáférést biztosít a Kolab csoportmunka-mappákhoz és e-mailekhez egy Kolab IMAP kiszolgálón. Comment[it]=Fornisce l'accesso a cartelle e messaggi di posta di groupware Kolab su un server Kolab IMAP. Comment[ko]=Kolab 그룹웨어 폴더 및 Kolab IMAP 서버에 접근합니다 @@ -65,14 +66,16 @@ Comment[pt]=Oferece o acesso às pastas de 'groupware' e de e-mail num servidor IMAP do Kolab. Comment[pt_BR]=Fornece acesso as pastas groupware Kolab em de e-mail em um servidor IMAP Kolab. Comment[sk]=Poskytuje prístup k priečinkom Kolab groupware a e-mailu na Kolab IMAP serveri. +Comment[sl]=Omogoča dostop do Kolabovih map za skupinsko delo na strežniku IMAP. Comment[sr]=Омогућава приступ Колабовим групверским фасциклама и е‑пошти на Колабовом ИМАП серверу. Comment[sr@ijekavian]=Омогућава приступ Колабовим групверским фасциклама и е‑пошти на Колабовом ИМАП серверу. Comment[sr@ijekavianlatin]=Omogućava pristup Kolabovim grupverskim fasciklama i e‑pošti na Kolabovom IMAP serveru. Comment[sr@latin]=Omogućava pristup Kolabovim grupverskim fasciklama i e‑pošti na Kolabovom IMAP serveru. Comment[sv]=Ger tillgång till Kolab grupprogramkorgar och e-post på en Kolab IMAP-server. -Comment[tr]=Bir Kolab IMAP Sunucusu üzerinde Kolab groupware klasörlerine ve e-postaya erişim sağlar. +Comment[tr]=Kolab grup yazılımı klasörlerine ve Kolab IMAP Sunucusu'na erişim sağlar Comment[uk]=Надає доступ до тек групової роботи та електронної пошти на серверів IMAP Kolab. Comment[x-test]=xxProvides access to Kolab groupware folders and e-mail on a Kolab IMAP Server.xx +Comment[zh_CN]=提供了对 Kolab 群件文件夹 和 Kolab IMAP 服务器上的电子邮件的访问功能。 Comment[zh_TW]=提供存取某 Kolab IMAP 伺服器上的 Kolab 群組資料夾與電子郵件 Type=AkonadiResource Exec=akonadi_kolab_resource diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabresource.h kdepim-runtime-15.08.0/resources/kolab/kolabresource.h --- kdepim-runtime-4.14.6/resources/kolab/kolabresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -33,27 +33,40 @@ explicit KolabResource(const QString &id); ~KolabResource(); + QDialog *createConfigureDialog(WId windowId) Q_DECL_OVERRIDE; + Settings *settings() const Q_DECL_OVERRIDE; + protected Q_SLOTS: - virtual void retrieveCollections(); - virtual void retrieveItems(const Akonadi::Collection& col); + void retrieveCollections() Q_DECL_OVERRIDE; + void delayedInit(); protected: - virtual ResourceStateInterface::Ptr createResourceState(const TaskArguments &); + ResourceStateInterface::Ptr createResourceState(const TaskArguments &) Q_DECL_OVERRIDE; - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); - virtual void itemsMoved( const Akonadi::Item::List &item, const Akonadi::Collection &source, - const Akonadi::Collection &destination ); + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + void itemsMoved(const Akonadi::Item::List &item, const Akonadi::Collection &source, + const Akonadi::Collection &destination) Q_DECL_OVERRIDE; //itemsRemoved and itemsFlags changed do not require translation, because they don't use the payload - virtual void collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent); - virtual void collectionChanged(const Akonadi::Collection &collection, const QSet &parts); + void collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent) Q_DECL_OVERRIDE; + void collectionChanged(const Akonadi::Collection &collection, const QSet &parts) Q_DECL_OVERRIDE; //collectionRemoved & collectionMoved do not require adjustments since they don't change the annotations - virtual QString defaultName() const; + void tagAdded(const Akonadi::Tag &tag) Q_DECL_OVERRIDE; + void tagChanged(const Akonadi::Tag &tag) Q_DECL_OVERRIDE; + void tagRemoved(const Akonadi::Tag &tag) Q_DECL_OVERRIDE; + void itemsTagsChanged(const Akonadi::Item::List &items, const QSet &addedTags, const QSet &removedTags) Q_DECL_OVERRIDE; + + void itemsRelationsChanged(const Akonadi::Item::List &items, + const Akonadi::Relation::List &addedRelations, + const Akonadi::Relation::List &removedRelations) Q_DECL_OVERRIDE; + + QString defaultName() const Q_DECL_OVERRIDE; private Q_SLOTS: - void onItemRetrievalCollectionFetchDone(KJob *job); + void retrieveTags(); + void retrieveRelations(); }; #endif diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabresourcestate.cpp kdepim-runtime-15.08.0/resources/kolab/kolabresourcestate.cpp --- kdepim-runtime-4.14.6/resources/kolab/kolabresourcestate.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabresourcestate.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,26 +24,22 @@ #include #include +#include +#include #include -#include -#include #include +#include "kolabresource_debug.h" - -KolabResourceState::KolabResourceState(ImapResource* resource, const TaskArguments& arguments) +KolabResourceState::KolabResourceState(ImapResource *resource, const TaskArguments &arguments) : ResourceState(resource, arguments) { } -void KolabResourceState::collectionAttributesRetrieved(const Akonadi::Collection& collection) +static Akonadi::Collection processAnnotations(const Akonadi::Collection &collection) { - if (!collection.isValid() && collection.remoteId().isEmpty()) { - ResourceState::collectionAttributesRetrieved(collection); - return; - } - Akonadi::Collection col = collection; - if (col.attribute()) { + if (collection.attribute()) { + Akonadi::Collection col = collection; const QMap rawAnnotations = col.attribute()->annotations(); const QByteArray type = KolabHelpers::getFolderTypeAnnotation(rawAnnotations); const Kolab::FolderType folderType = KolabHelpers::folderTypeFromString(type); @@ -51,7 +47,7 @@ const QString icon = KolabHelpers::getIcon(folderType); if (!icon.isEmpty()) { - kDebug() << " setting icon " << icon; + // qCDebug(KOLABRESOURCE_LOG) << " setting icon " << icon; Akonadi::EntityDisplayAttribute *attr = col.attribute(Akonadi::Collection::AddIfMissing); attr->setIconName(icon); } @@ -68,14 +64,39 @@ col.setCachePolicy(cachePolicy); } } + if (folderType == Kolab::ConfigurationType) { + //we want to hide this folder from indexing and display, but still have the data available locally. + col.setEnabled(false); + col.setShouldList(Akonadi::Collection::ListSync, true); + } if (!KolabHelpers::isHandledType(folderType)) { //If we don't handle the folder, make sure we don't download the messages col.attribute(Akonadi::Entity::AddIfMissing); } + return col; } + return collection; +} + +void KolabResourceState::collectionAttributesRetrieved(const Akonadi::Collection &collection) +{ + if (!collection.isValid() && collection.remoteId().isEmpty()) { + ResourceState::collectionAttributesRetrieved(collection); + return; + } + const Akonadi::Collection col = processAnnotations(collection); ResourceState::collectionAttributesRetrieved(col); } +void KolabResourceState::collectionsRetrieved(const Akonadi::Collection::List &collections) +{ + Akonadi::Collection::List modifiedCollections; + Q_FOREACH (const Akonadi::Collection &col, collections) { + modifiedCollections << processAnnotations(col); + } + ResourceState::collectionsRetrieved(modifiedCollections); +} + MessageHelper::Ptr KolabResourceState::messageHelper() const { return MessageHelper::Ptr(new KolabMessageHelper(collection())); diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabresourcestate.h kdepim-runtime-15.08.0/resources/kolab/kolabresourcestate.h --- kdepim-runtime-4.14.6/resources/kolab/kolabresourcestate.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabresourcestate.h 2015-08-10 21:01:02.000000000 +0000 @@ -27,10 +27,11 @@ class KolabResourceState : public ::ResourceState { public: - explicit KolabResourceState(ImapResource* resource, const TaskArguments& arguments); + explicit KolabResourceState(ImapResource *resource, const TaskArguments &arguments); private: - virtual void collectionAttributesRetrieved(const Akonadi::Collection& collection); + virtual void collectionAttributesRetrieved(const Akonadi::Collection &collection); + virtual void collectionsRetrieved(const Akonadi::Collection::List &collections); virtual MessageHelper::Ptr messageHelper() const; }; diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabretrievecollectionstask.cpp kdepim-runtime-15.08.0/resources/kolab/kolabretrievecollectionstask.cpp --- kdepim-runtime-4.14.6/resources/kolab/kolabretrievecollectionstask.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabretrievecollectionstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,25 +22,179 @@ #include "kolabretrievecollectionstask.h" #include "kolabhelpers.h" +#include "tracer.h" +#include "kolabresource_debug.h" #include #include #include +#include +#include +#include +#include -#include -#include +#include +#include #include +#include +#include +#include #include +#include -#include -#include +static bool isNamespaceFolder(const QString &path, const QList &namespaces, bool matchCompletePath = false) +{ + Q_FOREACH (const KIMAP::MailBoxDescriptor &desc, namespaces) { + if (path.startsWith(desc.name.left(desc.name.size() - 1))) { //Namespace ends with path separator and pathPart doesn't + if (!matchCompletePath || path.size() - desc.name.size() <= 1) { //We want to match only for the complete path + return true; + } + } + } + return false; +} + +RetrieveMetadataJob::RetrieveMetadataJob(KIMAP::Session *session, const QStringList &mailboxes, const QStringList &serverCapabilities, const QSet &requestedMetadata, const QString &separator, const QList &sharedNamespace, const QList &userNamespace, QObject *parent) + : KJob(parent) + , mJobs(0) + , mRequestedMetadata(requestedMetadata) + , mServerCapabilities(serverCapabilities) + , mMailboxes(mailboxes) + , mSession(session) + , mSeparator(separator) + , mSharedNamespace(sharedNamespace) + , mUserNamespace(userNamespace) +{ + +} + +void RetrieveMetadataJob::start() +{ + Trace(); + //Fill the map with empty entires so we set the mimetype to mail if no metadata is retrieved + Q_FOREACH (const QString &mailbox, mMailboxes) { + mMetadata.insert(mailbox, QMap()); + } + + if (mServerCapabilities.contains(QLatin1String("METADATA")) || mServerCapabilities.contains(QLatin1String("ANNOTATEMORE"))) { + QSet toplevelMailboxes; + Q_FOREACH (const QString &mailbox, mMailboxes) { + const QStringList parts = mailbox.split(mSeparator); + if (!parts.isEmpty()) { + if (isNamespaceFolder(mailbox, mUserNamespace) && parts.length() >= 2) { + // Other Users can be too big to request with a single command so we request Other Users//* + toplevelMailboxes << parts.at(0) + mSeparator + parts.at(1) + mSeparator; + } else if (!isNamespaceFolder(mailbox, mSharedNamespace)) { + toplevelMailboxes << parts.first(); + } + } + } + Q_FOREACH (const KIMAP::MailBoxDescriptor &desc, mSharedNamespace) { + toplevelMailboxes << desc.name; + } + //TODO perhaps exclude the shared and other users namespaces by listing only toplevel (with %), and then only getting metadata of the toplevel folders. + Q_FOREACH (const QString &mailbox, toplevelMailboxes) { + { + KIMAP::GetMetaDataJob *meta = new KIMAP::GetMetaDataJob(mSession); + meta->setMailBox(mailbox + QLatin1String("*")); + if (mServerCapabilities.contains(QLatin1String("METADATA"))) { + meta->setServerCapability(KIMAP::MetaDataJobBase::Metadata); + } else { + meta->setServerCapability(KIMAP::MetaDataJobBase::Annotatemore); + } + meta->setDepth(KIMAP::GetMetaDataJob::AllLevels); + Q_FOREACH (const QByteArray &requestedEntry, mRequestedMetadata) { + meta->addRequestedEntry(requestedEntry); + } + connect(meta, SIGNAL(result(KJob*)), SLOT(onGetMetaDataDone(KJob*))); + mJobs++; + meta->start(); + } + } + } + + // Get the ACLs from the mailbox if it's supported + if (mServerCapabilities.contains(QLatin1String("ACL"))) { + + Q_FOREACH (const QString &mailbox, mMailboxes) { + // "Shared Folders" is not a valid mailbox, so we have to skip the ACL request for this folder + if (isNamespaceFolder(mailbox, mSharedNamespace, true)) { + continue; + } + KIMAP::MyRightsJob *rights = new KIMAP::MyRightsJob(mSession); + rights->setMailBox(mailbox); + connect(rights, SIGNAL(result(KJob*)), SLOT(onRightsReceived(KJob*))); + mJobs++; + rights->start(); + } + } + checkDone(); +} + +void RetrieveMetadataJob::onGetMetaDataDone(KJob *job) +{ + mJobs--; + KIMAP::GetMetaDataJob *meta = static_cast(job); + if (job->error()) { + qCDebug(KOLABRESOURCE_LOG) << "No metadata for for mailbox: " << meta->mailBox(); + if (!isNamespaceFolder(meta->mailBox(), mSharedNamespace)) { + qCWarning(KOLABRESOURCE_LOG) << "Get metadata failed: " << job->errorString(); + //We ignore the error to avoid failing the complete sync. We can run into this when trying to retrieve rights for non-existing mailboxes. + } + checkDone(); + return; + } -KolabRetrieveCollectionsTask::KolabRetrieveCollectionsTask(ResourceStateInterface::Ptr resource, QObject* parent) - : ResourceTask(CancelIfNoSession, resource, parent), - mJobs(0) + const QHash > metadata = meta->allMetaDataForMailboxes(); + Q_FOREACH (const QString &folder, metadata.keys()) { + mMetadata.insert(folder, metadata.value(folder)); + } + checkDone(); +} + +void RetrieveMetadataJob::onRightsReceived(KJob *job) { + mJobs--; + KIMAP::MyRightsJob *rights = static_cast(job); + if (job->error()) { + qCDebug(KOLABRESOURCE_LOG) << "No rights for mailbox: " << rights->mailBox(); + if (!isNamespaceFolder(rights->mailBox(), mSharedNamespace)) { + qCWarning(KOLABRESOURCE_LOG) << "MyRights failed: " << job->errorString(); + //We ignore the error to avoid failing the complete sync. We can run into this when trying to retrieve rights for non-existing mailboxes. + } + checkDone(); + return; + } + const KIMAP::Acl::Rights imapRights = rights->rights(); + mRights.insert(rights->mailBox(), imapRights); + checkDone(); +} + +void RetrieveMetadataJob::checkDone() +{ + if (!mJobs) { + Trace() << "done"; + qCDebug(KOLABRESOURCE_LOG) << "done"; + emitResult(); + } +} + +KolabRetrieveCollectionsTask::KolabRetrieveCollectionsTask(ResourceStateInterface::Ptr resource, QObject *parent) + : ResourceTask(CancelIfNoSession, resource, parent) + , mJobs(0) + , mSession(Q_NULLPTR) + , cContentMimeTypes("CONTENTMIMETYPES") + , cAccessRights("AccessRights") + , cImapAcl("imapacl") + , cCollectionAnnotations("collectionannotations") + , cDefaultKeepLocalChanges(QSet() << cContentMimeTypes << cAccessRights << cImapAcl << cCollectionAnnotations) + , cDefaultMimeTypes(QStringList() << Akonadi::Collection::mimeType() << QStringLiteral("application/x-kolab-objects")) + , cCollectionOnlyContentMimeTypes(QStringList() << Akonadi::Collection::mimeType()) +{ + mRequestedMetadata << "/shared/vendor/kolab/folder-type"; + mRequestedMetadata << "/private/vendor/kolab/folder-type"; } KolabRetrieveCollectionsTask::~KolabRetrieveCollectionsTask() @@ -50,6 +204,11 @@ void KolabRetrieveCollectionsTask::doStart(KIMAP::Session *session) { + Trace(); + qCDebug(KOLABRESOURCE_LOG) << "Starting collection retrieval"; + mTime.start(); + mSession = session; + Akonadi::Collection root; root.setName(resourceName()); root.setRemoteId(rootRemoteId()); @@ -64,7 +223,7 @@ QStringList localParts; localParts << QLatin1String(Akonadi::MessagePart::Envelope) - << QLatin1String(Akonadi::MessagePart::Header); + << QLatin1String(Akonadi::MessagePart::Header); int cacheTimeout = 60; if (isDisconnectedModeEnabled()) { @@ -82,14 +241,15 @@ mMailCollections.insert(QString(), root); + Trace() << "subscription enabled: " << isSubscriptionEnabled(); //jobs are serialized by the session if (isSubscriptionEnabled()) { KIMAP::ListJob *fullListJob = new KIMAP::ListJob(session); fullListJob->setOption(KIMAP::ListJob::NoOption); fullListJob->setQueriedNamespaces(serverNamespaces()); - connect( fullListJob, SIGNAL(mailBoxesReceived(QList,QList >)), - this, SLOT(onFullMailBoxesReceived(QList,QList >)) ); - connect( fullListJob, SIGNAL(result(KJob*)), SLOT(onFullMailBoxesReceiveDone(KJob*))); + connect(fullListJob, SIGNAL(mailBoxesReceived(QList,QList >)), + this, SLOT(onFullMailBoxesReceived(QList,QList >))); + connect(fullListJob, SIGNAL(result(KJob*)), SLOT(onFullMailBoxesReceiveDone(KJob*))); mJobs++; fullListJob->start(); } @@ -105,18 +265,11 @@ } void KolabRetrieveCollectionsTask::onMailBoxesReceived(const QList< KIMAP::MailBoxDescriptor > &descriptors, - const QList< QList > &flags) + const QList< QList > &flags) { - for (int i=0; i ¤tFlags) +void KolabRetrieveCollectionsTask::setAttributes(Akonadi::Collection &c, const QStringList &pathParts, const QString &path) +{ + + CollectionIdentificationAttribute *attr = c.attribute(Akonadi::Collection::AddIfMissing); + attr->setIdentifier(path.toLatin1()); + + // If the folder is a other users folder block all alarms from default + if (isNamespaceFolder(path, resourceState()->userNamespaces())) { + Akonadi::BlockAlarmsAttribute *attr = c.attribute(Akonadi::Collection::AddIfMissing); + attr->blockEverything(true); + } + + // If the folder is a other users top-level folder mark it accordingly + if (pathParts.size() == 1 && isNamespaceFolder(path, resourceState()->userNamespaces())) { + Akonadi::EntityDisplayAttribute *attr = c.attribute(Akonadi::Collection::AddIfMissing); + attr->setDisplayName(i18n("Other Users")); + attr->setIconName(QLatin1String("x-mail-distribution-list")); + } + + //Mark user folders for searching + if (pathParts.size() >= 2 && isNamespaceFolder(path, resourceState()->userNamespaces())) { + CollectionIdentificationAttribute *attr = c.attribute(Akonadi::Collection::AddIfMissing); + if (pathParts.size() == 2) { + attr->setCollectionNamespace("usertoplevel"); + } else { + attr->setCollectionNamespace("user"); + } + } + + // If the folder is a shared folders top-level folder mark it accordingly + if (pathParts.size() == 1 && isNamespaceFolder(path, resourceState()->sharedNamespaces())) { + Akonadi::EntityDisplayAttribute *attr = c.attribute(Akonadi::Collection::AddIfMissing); + attr->setDisplayName(i18n("Shared Folders")); + attr->setIconName(QLatin1String("x-mail-distribution-list")); + } + + //Mark shared folders for searching + if (pathParts.size() >= 2 && isNamespaceFolder(path, resourceState()->sharedNamespaces())) { + CollectionIdentificationAttribute *attr = c.attribute(Akonadi::Collection::AddIfMissing); + attr->setCollectionNamespace("shared"); + } + +} + +void KolabRetrieveCollectionsTask::createCollection(const QString &mailbox, const QList ¤tFlags, bool isSubscribed) { const QString separator = separatorCharacter(); Q_ASSERT(separator.size() == 1); - const QString boxName = mailbox.endsWith( separator ) - ? mailbox.left( mailbox.size()-1 ) - : mailbox; - const QStringList pathParts = boxName.split( separator ); + const QString boxName = mailbox.endsWith(separator) + ? mailbox.left(mailbox.size() - 1) + : mailbox; + const QStringList pathParts = boxName.split(separator); const QString pathPart = pathParts.last(); Akonadi::Collection c; @@ -159,14 +359,16 @@ if (mMailCollections.contains(mailbox)) { c = mMailCollections.value(mailbox); } - c.setName( pathPart ); - c.setRemoteId( separator + pathPart ); + c.setName(pathPart); + c.setRemoteId(separator + pathPart); const QStringList parentPath = pathParts.mid(0, pathParts.size() - 1); const Akonadi::Collection parentCollection = getOrCreateParent(parentPath.join(separator)); c.setParentCollection(parentCollection); //TODO get from ResourceState, and add KMime::Message::mimeType() for the normal imap resource by default //We add a dummy mimetype, otherwise the itemsync doesn't even work (action is disabled and resourcebase aborts the operation) - c.setContentMimeTypes(QStringList() << Akonadi::Collection::mimeType() << QLatin1String("application/x-kolab-objects")); + c.setContentMimeTypes(cDefaultMimeTypes); + c.setKeepLocalChanges(cDefaultKeepLocalChanges); + //assume LRS, until myrights is executed if (serverCapabilities().contains(QLatin1String("ACL"))) { c.setRights(Akonadi::Collection::ReadOnly); @@ -174,6 +376,8 @@ c.setRights(Akonadi::Collection::AllRights); } + setAttributes(c, pathParts, mailbox); + // If the folder is the Inbox, make some special settings. if (pathParts.size() == 1 && pathPart.compare(QLatin1String("inbox") , Qt::CaseInsensitive) == 0) { Akonadi::EntityDisplayAttribute *attr = c.attribute(Akonadi::Collection::AddIfMissing); @@ -182,18 +386,11 @@ setIdleCollection(c); } - // If the folder is the user top-level folder, mark it as well, although it is not officially noted in the RFC - if (pathParts.size() == 1 && pathPart == QLatin1String("user") && currentFlags.contains("\\noselect")) { - Akonadi::EntityDisplayAttribute *attr = c.attribute(Akonadi::Collection::AddIfMissing); - attr->setDisplayName(i18n("Shared Folders")); - attr->setIconName(QLatin1String("x-mail-distribution-list")); - } - // If this folder is a noselect folder, make some special settings. if (currentFlags.contains("\\noselect")) { c.addAttribute(new NoSelectAttribute(true)); - c.setContentMimeTypes(QStringList() << Akonadi::Collection::mimeType()); - c.setRights( Akonadi::Collection::ReadOnly ); + c.setContentMimeTypes(cCollectionOnlyContentMimeTypes); + c.setRights(Akonadi::Collection::ReadOnly); } else { // remove the noselect attribute explicitly, in case we had set it before (eg. for non-subscribed non-leaf folders) c.removeAttribute(); @@ -201,23 +398,106 @@ // If this folder is a noinferiors folder, it is not allowed to create subfolders inside. if (currentFlags.contains("\\noinferiors")) { - //kDebug() << "Noinferiors: " << currentPath; + //qCDebug(KOLABRESOURCE_LOG) << "Noinferiors: " << currentPath; c.addAttribute(new NoInferiorsAttribute(true)); c.setRights(c.rights() & ~Akonadi::Collection::CanCreateCollection); } + c.setEnabled(isSubscribed); - kDebug() << "creating collection " << mailbox << " with parent " << parentPath; + // qCDebug(KOLABRESOURCE_LOG) << "creating collection " << mailbox << " with parent " << parentPath; mMailCollections.insert(mailbox, c); - //This is no longer required - mSubscribedMailboxes.remove(mailbox); } -void KolabRetrieveCollectionsTask::onMailBoxesReceiveDone(KJob* job) +void KolabRetrieveCollectionsTask::onMailBoxesReceiveDone(KJob *job) +{ + Trace(); + qCDebug(KOLABRESOURCE_LOG) << "All mailboxes received: " << mTime.elapsed(); + qCDebug(KOLABRESOURCE_LOG) << "in total: " << mMailCollections.size(); + mJobs--; + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << QStringLiteral("Failed to retrieve mailboxes: ") + job->errorString(); + cancelTask(QStringLiteral("Collection retrieval failed")); + } else { + QSet mailboxes; + Q_FOREACH (const QString &mailbox, mMailCollections.keys()) { + if (!mailbox.isEmpty() && !isNamespaceFolder(mailbox, resourceState()->userNamespaces() + resourceState()->sharedNamespaces())) { + mailboxes << mailbox; + } + } + + //Only request metadata for subscribed Other Users Folders + const QStringList metadataMailboxes = mailboxes.unite(mSubscribedMailboxes.toList().toSet()).toList(); + + RetrieveMetadataJob *metadata = new RetrieveMetadataJob(mSession, metadataMailboxes, serverCapabilities(), mRequestedMetadata, separatorCharacter(), resourceState()->sharedNamespaces(), resourceState()->userNamespaces(), this); + connect(metadata, SIGNAL(result(KJob*)), this, SLOT(onMetadataRetrieved(KJob*))); + mJobs++; + metadata->start(); + } +} + +void KolabRetrieveCollectionsTask::applyRights(QHash rights) +{ + // qCDebug(KOLABRESOURCE_LOG) << rights; + Q_FOREACH (const QString &mailbox, rights.keys()) { + if (mMailCollections.contains(mailbox)) { + const KIMAP::Acl::Rights imapRights = rights.value(mailbox); + QStringList parts = mailbox.split(separatorCharacter()); + parts.removeLast(); + QString parentMailbox = parts.join(separatorCharacter()); + + KIMAP::Acl::Rights parentImapRights; + //If the parent folder is not existing we cant rename + if (!parentMailbox.isEmpty() && rights.contains(parentMailbox)) { + parentImapRights = rights.value(parentMailbox); + } + // qCDebug(KOLABRESOURCE_LOG) << mailbox << parentMailbox << imapRights << parentImapRights; + + Akonadi::Collection &collection = mMailCollections[mailbox]; + CollectionMetadataHelper::applyRights(collection, imapRights, parentImapRights); + + // Store the mailbox ACLs + Akonadi::ImapAclAttribute *aclAttribute = collection.attribute(Akonadi::Collection::AddIfMissing); + const KIMAP::Acl::Rights oldRights = aclAttribute->myRights(); + if (oldRights != imapRights) { + aclAttribute->setMyRights(imapRights); + } + } else { + qCWarning(KOLABRESOURCE_LOG) << "Can't find mailbox " << mailbox; + } + } +} + +void KolabRetrieveCollectionsTask::applyMetadata(QHash > metadataMap) +{ + // qCDebug(KOLABRESOURCE_LOG) << metadataMap; + Q_FOREACH (const QString &mailbox, metadataMap.keys()) { + const QMap metadata = metadataMap.value(mailbox); + if (mMailCollections.contains(mailbox)) { + Akonadi::Collection &collection = mMailCollections[mailbox]; + // qCDebug(KOLABRESOURCE_LOG) << "setting metadata: " << mailbox << metadata; + collection.attribute(Akonadi::Collection::AddIfMissing)->setAnnotations(metadata); + const QByteArray type = KolabHelpers::getFolderTypeAnnotation(metadata); + const Kolab::FolderType folderType = KolabHelpers::folderTypeFromString(type); + collection.setContentMimeTypes(KolabHelpers::getContentMimeTypes(folderType)); + QSet keepLocalChanges = collection.keepLocalChanges(); + keepLocalChanges.remove(cContentMimeTypes); + collection.setKeepLocalChanges(keepLocalChanges); + } + } +} + +void KolabRetrieveCollectionsTask::onMetadataRetrieved(KJob *job) { + Trace(); + qCDebug(KOLABRESOURCE_LOG) << mTime.elapsed(); mJobs--; if (job->error()) { - cancelTask(job->errorString()); + qCWarning(KOLABRESOURCE_LOG) << "Error while retrieving metadata, aborting collection retrieval: " << job->errorString(); + cancelTask(QStringLiteral("Collection retrieval failed")); } else { + RetrieveMetadataJob *metadata = static_cast(job); + applyRights(metadata->mRights); + applyMetadata(metadata->mMetadata); checkDone(); } } @@ -225,12 +505,14 @@ void KolabRetrieveCollectionsTask::checkDone() { if (!mJobs) { - collectionsRetrieved(mMailCollections.values()); + Trace() << "done " << mMailCollections.size(); + collectionsRetrieved(Akonadi::valuesToVector(mMailCollections)); + qCDebug(KOLABRESOURCE_LOG) << "done " << mTime.elapsed(); } } -void KolabRetrieveCollectionsTask::onFullMailBoxesReceived(const QList< KIMAP::MailBoxDescriptor >& descriptors, - const QList< QList< QByteArray > >& flags) +void KolabRetrieveCollectionsTask::onFullMailBoxesReceived(const QList< KIMAP::MailBoxDescriptor > &descriptors, + const QList< QList< QByteArray > > &flags) { Q_UNUSED(flags); foreach (const KIMAP::MailBoxDescriptor &descriptor, descriptors) { @@ -238,11 +520,14 @@ } } -void KolabRetrieveCollectionsTask::onFullMailBoxesReceiveDone(KJob* job) +void KolabRetrieveCollectionsTask::onFullMailBoxesReceiveDone(KJob *job) { + Trace(); + qCDebug(KOLABRESOURCE_LOG) << "received subscribed collections " << mTime.elapsed(); mJobs--; if (job->error()) { - cancelTask(job->errorString()); + qCWarning(KOLABRESOURCE_LOG) << QStringLiteral("Failed to retrieve subscribed collections: ") + job->errorString(); + cancelTask(QStringLiteral("Collection retrieval failed")); } else { checkDone(); } diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabretrievecollectionstask.h kdepim-runtime-15.08.0/resources/kolab/kolabretrievecollectionstask.h --- kdepim-runtime-4.14.6/resources/kolab/kolabretrievecollectionstask.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabretrievecollectionstask.h 2015-08-10 21:01:02.000000000 +0000 @@ -25,7 +25,7 @@ #include -#include +#include #include @@ -39,10 +39,11 @@ private slots: void onMailBoxesReceived(const QList &descriptors, - const QList< QList > &flags); + const QList< QList > &flags); void onMailBoxesReceiveDone(KJob *job); void onFullMailBoxesReceived(const QList &descriptors, const QList > &flags); void onFullMailBoxesReceiveDone(KJob *job); + void onMetadataRetrieved(KJob *job); protected: virtual void doStart(KIMAP::Session *session); @@ -50,11 +51,51 @@ private: void checkDone(); Akonadi::Collection getOrCreateParent(const QString &parentPath); - void createCollection(const QString &mailbox, const QList &flags); + void createCollection(const QString &mailbox, const QList &flags, bool isSubscribed); + void setAttributes(Akonadi::Collection &c, const QStringList &pathParts, const QString &path); + void applyRights(QHash rights); + void applyMetadata(QHash > metadata); int mJobs; QHash mMailCollections; QSet mSubscribedMailboxes; + QSet mRequestedMetadata; + KIMAP::Session *mSession; + QTime mTime; + //For implicit sharing + const QByteArray cContentMimeTypes; + const QByteArray cAccessRights; + const QByteArray cImapAcl; + const QByteArray cCollectionAnnotations; + const QSet cDefaultKeepLocalChanges; + const QStringList cDefaultMimeTypes; + const QStringList cCollectionOnlyContentMimeTypes; +}; + +class RetrieveMetadataJob : public KJob +{ + Q_OBJECT +public: + RetrieveMetadataJob(KIMAP::Session *session, const QStringList &mailboxes, const QStringList &serverCapabilities, const QSet &requestedMetadata, const QString &separator, const QList &sharedNamespace, const QList &userNamespace, QObject *parent = 0); + void start(); + + QHash > mMetadata; + QHash mRights; + +private: + void checkDone(); + int mJobs; + QSet mRequestedMetadata; + QStringList mServerCapabilities; + QStringList mMailboxes; + KIMAP::Session *mSession; + QString mSeparator; + QList mSharedNamespace; + QList mUserNamespace; + +private Q_SLOTS: + void onGetMetaDataDone(KJob *job); + void onRightsReceived(KJob *job); }; #endif diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabretrievetagstask.cpp kdepim-runtime-15.08.0/resources/kolab/kolabretrievetagstask.cpp --- kdepim-runtime-4.14.6/resources/kolab/kolabretrievetagstask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabretrievetagstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,227 @@ +/* + Copyright (c) 2014 Christian Mollekopf + + 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 "kolabretrievetagstask.h" +#include "kolabresource_debug.h" +#include "tagchangehelper.h" + +#include +#include +#include +#include +#include "tracer.h" + +KolabRetrieveTagTask::KolabRetrieveTagTask(ResourceStateInterface::Ptr resource, RetrieveType type, QObject *parent) + : KolabRelationResourceTask(resource, parent) + , mSession(0) + , mRetrieveType(type) +{ +} + +void KolabRetrieveTagTask::startRelationTask(KIMAP::Session *session) +{ + mSession = session; + const QString mailBox = mailBoxForCollection(relationCollection()); + + KIMAP::SelectJob *select = new KIMAP::SelectJob(session); + select->setMailBox(mailBox); + connect(select, SIGNAL(result(KJob*)), + this, SLOT(onFinalSelectDone(KJob*))); + select->start(); +} + +void KolabRetrieveTagTask::onFinalSelectDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << job->errorString(); + cancelTask(job->errorString()); + return; + } + + KIMAP::SelectJob *select = static_cast(job); + KIMAP::FetchJob *fetch = new KIMAP::FetchJob(select->session()); + + if (select->messageCount() == 0) { + taskComplete(); + return; + } + + KIMAP::ImapSet set; + set.add(KIMAP::ImapInterval(1, 0)); + fetch->setSequenceSet(set); + fetch->setUidBased(false); + + KIMAP::FetchJob::FetchScope scope; + scope.parts.clear(); + scope.mode = KIMAP::FetchJob::FetchScope::Full; + fetch->setScope(scope); + + connect(fetch, SIGNAL(headersReceived(QString, + QMap, + QMap, + QMap, + QMap, + QMap)), + this, SLOT(onHeadersReceived(QString, + QMap, + QMap, + QMap, + QMap, + QMap))); + connect(fetch, SIGNAL(result(KJob*)), + this, SLOT(onHeadersFetchDone(KJob*))); + fetch->start(); +} + +void KolabRetrieveTagTask::onHeadersReceived(const QString &mailBox, + const QMap &uids, + const QMap &sizes, + const QMap &attrs, + const QMap &flags, + const QMap &messages) +{ + KIMAP::FetchJob *fetch = static_cast(sender()); + Q_ASSERT(fetch); + + foreach (qint64 number, uids.keys()) { //krazy:exclude=foreach + if (flags[number].contains(ImapFlags::Deleted)) { + continue; + } + const KMime::Message::Ptr msg = messages[number]; + const Kolab::KolabObjectReader reader(msg); + switch (reader.getType()) { + case Kolab::RelationConfigurationObject: + if (mRetrieveType == RetrieveTags && reader.isTag()) { + extractTag(reader, uids[number]); + } else if (mRetrieveType == RetrieveRelations && reader.isRelation()) { + extractRelation(reader, uids[number]); + } + break; + + default: + break; + } + } +} + +Akonadi::Item KolabRetrieveTagTask::extractMember(const Kolab::RelationMember &member) +{ + //TODO should we create a dummy item if it isn't yet available? + Akonadi::Item i; + if (!member.gid.isEmpty()) { + //Reference by GID + i.setGid(member.gid); + } else { + //Reference by imap uid + if (member.uid < 0) { + return Akonadi::Item(); + } + i.setRemoteId(QString::number(member.uid)); + qCDebug(KOLABRESOURCE_LOG) << "got member: " << member.uid << member.mailbox; + Akonadi::Collection parent; + { + //The root collection is not part of the mailbox path + Akonadi::Collection col; + col.setRemoteId(rootRemoteId()); + col.setParentCollection(Akonadi::Collection::root()); + parent = col; + } + Q_FOREACH (const QByteArray part, member.mailbox) { + Akonadi::Collection col; + col.setRemoteId(separatorCharacter() + QString::fromLatin1(part)); + col.setParentCollection(parent); + parent = col; + } + i.setParentCollection(parent); + } + return i; +} + +void KolabRetrieveTagTask::extractTag(const Kolab::KolabObjectReader &reader, qint64 remoteUid) +{ + Akonadi::Tag tag = reader.getTag(); + tag.setRemoteId(QByteArray::number(remoteUid)); + mTags << tag; + + Trace() << "Extracted tag: " << tag.gid() << " remoteId: " << remoteUid << tag.remoteId(); + + Akonadi::Item::List members; + Q_FOREACH (const QString &memberUrl, reader.getTagMembers()) { + Kolab::RelationMember member = Kolab::parseMemberUrl(memberUrl); + const Akonadi::Item i = extractMember(member); + //TODO implement fallback to search if uid is not available + if (!i.remoteId().isEmpty() || !i.gid().isEmpty()) { + members << i; + } else { + qCWarning(KOLABRESOURCE_LOG) << "Failed to parse member: " << memberUrl; + } + } + mTagMembers.insert(QString::fromLatin1(tag.remoteId()), members); +} + +void KolabRetrieveTagTask::extractRelation(const Kolab::KolabObjectReader &reader, qint64 remoteUid) +{ + Akonadi::Item::List members; + Q_FOREACH (const QString &memberUrl, reader.getTagMembers()) { + Kolab::RelationMember member = Kolab::parseMemberUrl(memberUrl); + const Akonadi::Item i = extractMember(member); + //TODO implement fallback to search if uid is not available + if (!i.remoteId().isEmpty() || !i.gid().isEmpty()) { + members << i; + } else { + qCWarning(KOLABRESOURCE_LOG) << "Failed to parse member: " << memberUrl; + } + } + if (members.size() != 2) { + qCWarning(KOLABRESOURCE_LOG) << "Wrong numbers of members for a relation, expected 2: " << members.size(); + return; + } + + Akonadi::Relation relation = reader.getRelation(); + relation.setType(Akonadi::Relation::GENERIC); + relation.setRemoteId(QByteArray::number(remoteUid)); + relation.setLeft(members.at(0)); + relation.setRight(members.at(1)); + mRelations << relation; +} + +void KolabRetrieveTagTask::onHeadersFetchDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "Fetch job failed " << job->errorString(); + cancelTask(job->errorString()); + return; + } + + taskComplete(); +} + +void KolabRetrieveTagTask::taskComplete() +{ + if (mRetrieveType == RetrieveTags) { + qCDebug(KOLABRESOURCE_LOG) << "Fetched tags: " << mTags.size() << mTagMembers.size(); + resourceState()->tagsRetrieved(mTags, mTagMembers); + } else if (mRetrieveType == RetrieveRelations) { + qCDebug(KOLABRESOURCE_LOG) << "Fetched relations:" << mRelations.size(); + resourceState()->relationsRetrieved(mRelations); + } + + deleteLater(); +} + diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabretrievetagstask.h kdepim-runtime-15.08.0/resources/kolab/kolabretrievetagstask.h --- kdepim-runtime-4.14.6/resources/kolab/kolabretrievetagstask.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabretrievetagstask.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,70 @@ +/* + Copyright (c) 2014 Christian Mollekopf + + 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 KOLABRETRIEVETAGSTASK_H +#define KOLABRETRIEVETAGSTASK_H + +#include "kolabrelationresourcetask.h" +#include + +namespace Kolab +{ +class KolabObjectReader; +class RelationMember; +} // namespace Kolab + +class KolabRetrieveTagTask : public KolabRelationResourceTask +{ + Q_OBJECT +public: + enum RetrieveType { + RetrieveTags, + RetrieveRelations + }; + + explicit KolabRetrieveTagTask(ResourceStateInterface::Ptr resource, RetrieveType type, QObject *parent = 0); + +protected: + virtual void startRelationTask(KIMAP::Session *session); + +private: + KIMAP::Session *mSession; + Akonadi::Tag::List mTags; + QHash mTagMembers; + Akonadi::Relation::List mRelations; + RetrieveType mRetrieveType; + +private Q_SLOTS: + void onFinalSelectDone(KJob *job); + void onHeadersReceived(const QString &mailBox, + const QMap &uids, + const QMap &sizes, + const QMap &attrs, + const QMap &flags, + const QMap &messages); + void onHeadersFetchDone(KJob *job); + +private: + void extractTag(const Kolab::KolabObjectReader &reader, qint64 remoteUid); + void extractRelation(const Kolab::KolabObjectReader &reader, qint64 remoteUid); + Akonadi::Item extractMember(const Kolab::RelationMember &member); + void taskComplete(); +}; + +#endif // KOLABCHANGETAGTASK_H diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabsettings.cpp kdepim-runtime-15.08.0/resources/kolab/kolabsettings.cpp --- kdepim-runtime-4.14.6/resources/kolab/kolabsettings.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabsettings.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,53 @@ +/* + Copyright (c) 2014 Sandro Knauß + + 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 "kolabsettings.h" + +KolabSettings::KolabSettings(WId winId) : Settings(winId) +{ + changeDefaults(); + load(); +} + +void KolabSettings::changeDefaults() +{ + setCurrentGroup(QLatin1String("network")); + KConfigSkeleton::ItemInt *itemImapPort; + itemImapPort = (KConfigSkeleton::ItemInt *) findItem(QLatin1String("ImapPort")); + itemImapPort->setDefaultValue(143); + KConfigSkeleton::ItemString *itemSafety; + itemSafety = (KConfigSkeleton::ItemString *) findItem(QLatin1String("Safety")); + itemSafety->setDefaultValue(QLatin1String("STARTTLS")); + KConfigSkeleton::ItemBool *itemSubscriptionEnabled; + itemSubscriptionEnabled = (KConfigSkeleton::ItemBool *) findItem(QLatin1String("SubscriptionEnabled")); + itemSubscriptionEnabled->setDefaultValue(true); + + setCurrentGroup(QLatin1String("cache")); + KConfigSkeleton::ItemBool *itemDisconnectedModeEnabled; + itemDisconnectedModeEnabled = (KConfigSkeleton::ItemBool *) findItem(QLatin1String("DisconnectedModeEnabled")); + itemDisconnectedModeEnabled->setDefaultValue(true); + + setCurrentGroup(QLatin1String("siever")); + KConfigSkeleton::ItemBool *itemSieveSupport; + itemSieveSupport = (KConfigSkeleton::ItemBool *) findItem(QLatin1String("SieveSupport")); + itemSieveSupport->setDefaultValue(true); + KConfigSkeleton::ItemBool *itemSieveReuseConfig; + itemSieveReuseConfig = (KConfigSkeleton::ItemBool *) findItem(QLatin1String("SieveReuseConfig")); + itemSieveReuseConfig->setDefaultValue(true); +} diff -Nru kdepim-runtime-4.14.6/resources/kolab/kolabsettings.h kdepim-runtime-15.08.0/resources/kolab/kolabsettings.h --- kdepim-runtime-4.14.6/resources/kolab/kolabsettings.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/kolabsettings.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,35 @@ +/* + Copyright (c) 2014 Sandro Knauß + + 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 KOLABSETTINGS_H +#define KOLABSETTINGS_H + +#include "settings.h" + +class KolabSettings : public Settings +{ + Q_OBJECT +public: + explicit KolabSettings(WId = 0); + +protected: + virtual void changeDefaults(); +}; + +#endif diff -Nru kdepim-runtime-4.14.6/resources/kolab/tagchangehelper.cpp kdepim-runtime-15.08.0/resources/kolab/tagchangehelper.cpp --- kdepim-runtime-4.14.6/resources/kolab/tagchangehelper.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tagchangehelper.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,129 @@ +/* + Copyright (c) 2014 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Krammer + + 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 "tagchangehelper.h" +#include "kolabresource_debug.h" +#include "kolabrelationresourcetask.h" +#include "kolabhelpers.h" +#include "updatemessagejob.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +KMime::Message::Ptr TagConverter::createMessage(const Akonadi::Tag &tag, const Akonadi::Item::List &items, const QString &username) +{ + QStringList itemRemoteIds; + itemRemoteIds.reserve(items.count()); + Q_FOREACH (const Akonadi::Item &item, items) { + const QString memberUrl = KolabHelpers::createMemberUrl(item, username); + if (!memberUrl.isEmpty()) { + itemRemoteIds << memberUrl; + } + } + + // save message to the server. + const QLatin1String productId("Akonadi-Kolab-Resource"); + const KMime::Message::Ptr message = Kolab::KolabObjectWriter::writeTag(tag, itemRemoteIds, Kolab::KolabV3, productId); + return message; +} + +struct TagMerger : public Merger { + virtual ~TagMerger() {} + virtual KMime::Message::Ptr merge(KMime::Message::Ptr newMessage, QList conflictingMessages) const + { + qCDebug(KOLABRESOURCE_LOG) << "Got " << conflictingMessages.size() << " conflicting relation configuration objects. Overwriting with local version."; + return newMessage; + } +}; + +TagChangeHelper::TagChangeHelper(KolabRelationResourceTask *parent) + : QObject(parent) + , mTask(parent) +{ +} + +void TagChangeHelper::start(const Akonadi::Tag &tag, const KMime::Message::Ptr &message, KIMAP::Session *session) +{ + Q_ASSERT(tag.isValid()); + const QString mailBox = mTask->mailBoxForCollection(mTask->relationCollection()); + const qint64 oldUid = tag.remoteId().toLongLong(); + qCDebug(KOLABRESOURCE_LOG) << mailBox << oldUid; + + const qint64 uidNext = -1; + + UpdateMessageJob *append = new UpdateMessageJob(message, session, tag.gid(), QSharedPointer(new TagMerger), mailBox, uidNext, oldUid, this); + connect(append, SIGNAL(result(KJob*)), this, SLOT(onReplaceDone(KJob*))); + append->setProperty("tag", QVariant::fromValue(tag)); + append->start(); +} + +void TagChangeHelper::recordNewUid(qint64 newUid, Akonadi::Tag tag) +{ + Q_ASSERT(newUid > 0); + Q_ASSERT(tag.isValid()); + + const QByteArray remoteId = QByteArray::number(newUid); + qCDebug(KOLABRESOURCE_LOG) << "Setting remote ID to " << remoteId << " on tag with local id: " << tag.id(); + //Make sure we only update the id and send nothing else + Akonadi::Tag updateTag; + updateTag.setId(tag.id()); + updateTag.setRemoteId(remoteId); + Akonadi::TagModifyJob *modJob = new Akonadi::TagModifyJob(updateTag); + connect(modJob, SIGNAL(result(KJob*)), this, SLOT(onModifyDone(KJob*))); +} + +void TagChangeHelper::onReplaceDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "Replace failed: " << job->errorString(); + } + UpdateMessageJob *replaceJob = static_cast(job); + const qint64 newUid = replaceJob->newUid(); + const Akonadi::Tag tag = job->property("tag").value(); + if (newUid > 0) { + recordNewUid(newUid, tag); + } else { + emit cancelTask(job->errorString()); + } +} + +void TagChangeHelper::onModifyDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "Modify failed: " << job->errorString(); + emit cancelTask(job->errorString()); + return; + } + emit changeCommitted(); +} + diff -Nru kdepim-runtime-4.14.6/resources/kolab/tagchangehelper.h kdepim-runtime-15.08.0/resources/kolab/tagchangehelper.h --- kdepim-runtime-4.14.6/resources/kolab/tagchangehelper.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tagchangehelper.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,71 @@ +/* + Copyright (c) 2014 Klarälvdalens Datakonsult AB, + a KDAB Group company + Author: Kevin Krammer + + 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 TAGCHANGEHELPER_H +#define TAGCHANGEHELPER_H + +#include +#include +#include + +#include + +namespace KIMAP +{ +class Session; +} + +namespace Akonadi +{ +class Tag; +} + +class KolabRelationResourceTask; + +struct TagConverter { + KMime::Message::Ptr createMessage(const Akonadi::Tag &tag, const Akonadi::Item::List &items, const QString &username); +}; + +class TagChangeHelper : public QObject +{ + Q_OBJECT +public: + explicit TagChangeHelper(KolabRelationResourceTask *parent = 0); + + void start(const Akonadi::Tag &tag, const KMime::Message::Ptr &message, KIMAP::Session *session); + +Q_SIGNALS: + void applyCollectionChanges(const Akonadi::Collection &collection); + void cancelTask(const QString &errorText); + void changeCommitted(); + +private: + KolabRelationResourceTask *const mTask; + +private: + void recordNewUid(qint64 newUid, Akonadi::Tag tag); + +private Q_SLOTS: + void onReplaceDone(KJob *job); + void onModifyDone(KJob *job); +}; + +#endif // TAGCHANGEHELPER_H diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/CMakeLists.txt kdepim-runtime-15.08.0/resources/kolab/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/kolab/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,25 @@ +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) + +# if kdepimlibs was built without -DKDE4_BUILD_TESTS, kimaptest doesn't exist. +find_path(KIMAPTEST_INCLUDE_DIR NAMES kimaptest/fakeserver.h) +find_library(KIMAPTEST_LIBRARY NAMES kimaptest) + +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) +set(KDEPIMLIBS_RUN_ISOLATED_TESTS TRUE) +set(KDEPIMLIBS_RUN_SQLITE_ISOLATED_TESTS TRUE) + +if(KIMAPTEST_INCLUDE_DIR AND KIMAPTEST_LIBRARY) + MACRO(KOLAB_RESOURCE_ISOLATED_TESTS) + FOREACH(_testname ${ARGN}) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/.. ../../imap/autotests/) + add_akonadi_isolated_test_advanced(${_testname}.cpp "../../imap/autotests/dummypasswordrequester.cpp;../../imap/autotests/dummyresourcestate.cpp;../../imap/autotests/imaptestbase.cpp" "KF5::KDELibs4Support;KF5::IMAP;${KIMAPTEST_LIBRARY};Qt5::Test;imapresource;kolabresource;akonaditest;${Libkolab_LIBRARIES}") + kde_enable_exceptions() + ENDFOREACH(_testname) + ENDMACRO(KOLAB_RESOURCE_ISOLATED_TESTS) + + KOLAB_RESOURCE_ISOLATED_TESTS ( + testretrievetagstask + testchangeitemstagstask + ) +endif() + diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/imaptestbase.cpp kdepim-runtime-15.08.0/resources/kolab/tests/imaptestbase.cpp --- kdepim-runtime-4.14.6/resources/kolab/tests/imaptestbase.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/imaptestbase.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,136 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" + +ImapTestBase::ImapTestBase(QObject *parent) + : QObject(parent) +{ + +} + +QString ImapTestBase::defaultUserName() const +{ + return QLatin1String("test@kdab.com"); +} + +QString ImapTestBase::defaultPassword() const +{ + return QLatin1String("foobar"); +} + +ImapAccount *ImapTestBase::createDefaultAccount() const +{ + ImapAccount *account = new ImapAccount; + + account->setServer(QLatin1String("127.0.0.1")); + account->setPort(5989); + account->setUserName(defaultUserName()); + account->setSubscriptionEnabled(true); + account->setEncryptionMode(KIMAP::LoginJob::Unencrypted); + account->setAuthenticationMode(KIMAP::LoginJob::ClearText); + + return account; +} + +DummyPasswordRequester *ImapTestBase::createDefaultRequester() +{ + DummyPasswordRequester *requester = new DummyPasswordRequester(this); + requester->setPassword(defaultPassword()); + return requester; +} + +void ImapTestBase::setupTestCase() +{ + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); +} + +QList ImapTestBase::defaultAuthScenario() const +{ + QList scenario; + + scenario << FakeServer::greeting() + << "C: A000001 LOGIN \"test@kdab.com\" \"foobar\"" + << "S: A000001 OK User Logged in"; + + return scenario; +} + +QList ImapTestBase::defaultPoolConnectionScenario(const QList &customCapabilities) const +{ + QList scenario; + + QByteArray caps = "S: * CAPABILITY IMAP4 IMAP4rev1 UIDPLUS IDLE"; + Q_FOREACH (const QByteArray &cap, customCapabilities) { + caps += " " + cap; + } + + scenario << defaultAuthScenario() + << "C: A000002 CAPABILITY" + << caps + << "S: A000002 OK Completed"; + + return scenario; +} + +bool ImapTestBase::waitForSignal(QObject *obj, const char *member, int timeout) const +{ + QEventLoop loop; + QTimer timer; + + connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + + QSignalSpy spy(obj, member); + connect(obj, member, &loop, SLOT(quit())); + + timer.setSingleShot(true); + timer.start(timeout); + loop.exec(); + timer.stop(); + + return spy.count() == 1; +} + +Akonadi::Collection ImapTestBase::createCollectionChain(const QString &remoteId) const +{ + QChar separator = remoteId.length() > 0 ? remoteId.at(0) : QLatin1Char('/'); + + Akonadi::Collection parent(1); + parent.setRemoteId(QLatin1String("root-id")); + parent.setParentCollection(Akonadi::Collection::root()); + Akonadi::Entity::Id id = 2; + + Akonadi::Collection collection = parent; + + const QStringList collections = remoteId.split(separator, QString::SkipEmptyParts); + Q_FOREACH (const QString &colId, collections) { + collection = Akonadi::Collection(id); + collection.setRemoteId(separator + colId); + collection.setParentCollection(parent); + + parent = collection; + id++; + } + + return collection; +} + diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/imaptestbase.h kdepim-runtime-15.08.0/resources/kolab/tests/imaptestbase.h --- kdepim-runtime-4.14.6/resources/kolab/tests/imaptestbase.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/imaptestbase.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,62 @@ +/* + Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or ( at your option ) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef IMAPTESTBASE_H +#define IMAPTESTBASE_H + +#include + +#include + +#include "dummypasswordrequester.h" +#include "dummyresourcestate.h" +#include "imapaccount.h" +#include "resourcetask.h" +#include "sessionpool.h" + +Q_DECLARE_METATYPE(ImapAccount *) +Q_DECLARE_METATYPE(DummyPasswordRequester *) +Q_DECLARE_METATYPE(DummyResourceState::Ptr) +Q_DECLARE_METATYPE(KIMAP::Session *) +Q_DECLARE_METATYPE(QVariant) + +class ImapTestBase : public QObject +{ + Q_OBJECT + +public: + ImapTestBase(QObject *parent = 0); + +protected: + QString defaultUserName() const; + QString defaultPassword() const; + ImapAccount *createDefaultAccount() const; + DummyPasswordRequester *createDefaultRequester(); + QList defaultAuthScenario() const; + QList defaultPoolConnectionScenario(const QList &customCapabilities = QList()) const; + + bool waitForSignal(QObject *obj, const char *member, int timeout = 500) const; + + Akonadi::Collection createCollectionChain(const QString &remoteId) const; + +private slots: + void setupTestCase(); +}; + +#endif diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/testchangeitemstagstask.cpp kdepim-runtime-15.08.0/resources/kolab/tests/testchangeitemstagstask.cpp --- kdepim-runtime-4.14.6/resources/kolab/tests/testchangeitemstagstask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/testchangeitemstagstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,235 @@ +/* + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +namespace Akonadi +{ +class Tag; +}; + +unsigned int qHash(const Akonadi::Tag &tag); + +#include "imaptestbase.h" + +#include + +#include +#include +#include +#include +#include +//#include +#include +#include + +#include "kolabchangeitemstagstask.h" +#include "kolabhelpers.h" + +using namespace Akonadi; + +typedef QHash Members; + +Q_DECLARE_METATYPE(TagListAndMembers); +Q_DECLARE_METATYPE(Members); + +struct TestTagConverter : public TagConverter { + virtual KMime::Message::Ptr createMessage(const Akonadi::Tag &tag, const Akonadi::Item::List &items) + { + return KMime::Message::Ptr(new KMime::Message()); + } +}; + +class TestChangeItemsTagsTask : public ImapTestBase +{ + Q_OBJECT + +private slots: + + void initTestCase() + { + AkonadiTest::checkTestIsIsolated(); + } + + void testRetrieveTags_data() + { + Akonadi::VirtualResource *resource = new Akonadi::VirtualResource(QLatin1String("akonadi_knut_resource_0"), this); + + Akonadi::Collection root; + root.setName(QLatin1String("akonadi_knut_resource_0")); + root.setContentMimeTypes(QStringList() << Akonadi::Collection::mimeType()); + root.setParentCollection(Akonadi::Collection::root()); + root.setRemoteId("root-id"); + root = resource->createRootCollection(root); + + Akonadi::Collection col; + col.setName("Configuration"); + col.setContentMimeTypes(QStringList() << KolabHelpers::getMimeType(Kolab::ConfigurationType)); + col.setRemoteId("/configuration"); + col = resource->createCollection(col); + + Akonadi::Collection mailcol; + mailcol.setName("INBOX"); + mailcol.setContentMimeTypes(QStringList() << KMime::Message::mimeType()); + mailcol.setRemoteId("/INBOX"); + mailcol = resource->createCollection(mailcol); + + Akonadi::Tag tag("tagname"); + { + Akonadi::TagCreateJob *createJob = new Akonadi::TagCreateJob(tag); + AKVERIFYEXEC(createJob); + tag = createJob->tag(); + } + + Akonadi::Item item(KMime::Message::mimeType()); + item.setRemoteId("20"); + item.setTag(tag); + item = resource->createItem(item, mailcol); + + QTest::addColumn< QList >("scenario"); + QTest::addColumn("callNames"); + QTest::addColumn("expectedTags"); + QTest::addColumn("expectedMembers"); + QTest::addColumn("resourceState"); + + { + QList scenario; + scenario << defaultPoolConnectionScenario(); + + QStringList callNames; + callNames << "changeProcessed"; + + QHash expectedMembers; + + DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); + state->setServerCapabilities(QStringList() << "METADATA" << "ACL"); + state->setUserName("Hans"); + + QTest::newRow("nothing changed") << scenario << callNames << Akonadi::Tag::List() << expectedMembers << state; + } + { + KMime::Message::Ptr msg(new KMime::Message()); + + const QByteArray &content = msg->encodedContent(true); + QList scenario; + scenario << defaultPoolConnectionScenario() + << "C: A000003 APPEND \"configuration\" {" + QByteArray::number(content.size()) + "}" + << "S: A000003 OK append done [ APPENDUID 1239890035 65 ]"; + + QStringList callNames; + callNames << "changeProcessed"; + + Akonadi::Tag expectedTag = tag; + expectedTag.setRemoteId("7"); + + QHash expectedMembers; + Akonadi::Item member; + member.setRemoteId("20"); + member.setParentCollection(createCollectionChain("/INBOX")); + expectedMembers.insert(expectedTag.remoteId(), (Akonadi::Item::List() << member)); + + DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); + state->setServerCapabilities(QStringList() << "METADATA" << "ACL"); + state->setUserName("Hans"); + state->setAddedTags(QSet() << tag); + + QTest::newRow("list single tag") << scenario << callNames << (Akonadi::Tag::List() << expectedTag) << expectedMembers << state; + } + } + + void testRetrieveTags() + { + QFETCH(QList, scenario); + QFETCH(QStringList, callNames); + QFETCH(Akonadi::Tag::List, expectedTags); + QFETCH(Members, expectedMembers); + QFETCH(DummyResourceState::Ptr, resourceState); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(1); + + pool.setPasswordRequester(createDefaultRequester()); + QVERIFY(pool.connect(createDefaultAccount())); + QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int,QString)))); + + KolabChangeItemsTagsTask *task = new KolabChangeItemsTagsTask(resourceState, QSharedPointer(new TestTagConverter)); + + task->start(&pool); + + QTRY_COMPARE(resourceState->calls().count(), callNames.size()); + for (int i = 0; i < callNames.size(); i++) { + QString command = QString::fromUtf8(resourceState->calls().at(i).first); + QVariant parameter = resourceState->calls().at(i).second; + + if (command == "cancelTask" && callNames[i] != "cancelTask") { + qCDebug(KOLABRESOURCE_LOG) << "Got a cancel:" << parameter.toString(); + } + + QCOMPARE(command, callNames[i]); + + if (command == "tagsRetrieved") { + QPair > pair = parameter.value(); + Akonadi::Tag::List tags = pair.first; + QHash members = pair.second; + QCOMPARE(tags.size(), expectedTags.size()); + for (int i = 0 ; i < tags.size(); i++) { + QCOMPARE(tags[i].name(), expectedTags[i].name()); + QCOMPARE(tags[i].remoteId(), expectedTags[i].remoteId()); + const Akonadi::Item::List memberlist = members.value(tags[i].remoteId()); + const Akonadi::Item::List expectedMemberlist = expectedMembers.value(tags[i].remoteId()); + QCOMPARE(memberlist.size(), expectedMemberlist.size()); + for (int i = 0 ; i < expectedMemberlist.size(); i++) { + QCOMPARE(memberlist[i].remoteId(), expectedMemberlist[i].remoteId()); + Akonadi::Collection parent = memberlist[i].parentCollection(); + Akonadi::Collection expectedParent = expectedMemberlist[i].parentCollection(); + while (expectedParent.isValid()) { + QCOMPARE(parent.remoteId(), expectedParent.remoteId()); + expectedParent = expectedParent.parentCollection(); + parent = parent.parentCollection(); + } + } + } + } + } + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } + + void testTagConverter() + { + TagConverter converter; + Akonadi::Item item(KMime::Message::mimeType()); + KMime::Message::Ptr msg = KMime::Message::Ptr(new KMime::Message()); + msg->subject(true)->from7BitString("subject"); + + msg->messageID(true)->from7BitString(""); + msg->date(true)->setDateTime(KDateTime(QDate(2014, 12, 10), QTime(9, 8, 7))); + item.setPayload(msg); + item.setRemoteId(QLatin1String("20")); + item.setParentCollection(createCollectionChain("/INBOX")); + const QString member = KolabHelpers::createMemberUrl(item, QLatin1String("localuser@localhost")); + const QString expected = QLatin1String("imap:///user/localuser%40localhost/INBOX/20?message-id=%3Cmessageid%40example.com%3E&subject=subject&date=Wed%2C%2010%20Dec%202014%2009%3A08%3A07%20%2B0000"); + QCOMPARE(member, expected); + } +}; + +QTEST_AKONADIMAIN(TestChangeItemsTagsTask) + +#include "testchangeitemstagstask.moc" diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/testretrievetagstask.cpp kdepim-runtime-15.08.0/resources/kolab/tests/testretrievetagstask.cpp --- kdepim-runtime-4.14.6/resources/kolab/tests/testretrievetagstask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/testretrievetagstask.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,184 @@ +/* + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "imaptestbase.h" + +#include "kolabretrievetagstask.h" + +#include +#include +#include +#include +#include +#include +#include "kolabhelpers.h" +#include + +typedef QHash Members; + +Q_DECLARE_METATYPE(TagListAndMembers); +Q_DECLARE_METATYPE(Members); + +class TestRetrieveTagsTask : public ImapTestBase +{ + Q_OBJECT + +private slots: + + void initTestCase() + { + AkonadiTest::checkTestIsIsolated(); + } + + void testRetrieveTags_data() + { + Akonadi::VirtualResource *resource = new Akonadi::VirtualResource(QLatin1String("akonadi_knut_resource_0"), this); + + Akonadi::Collection root; + root.setName(QLatin1String("akonadi_knut_resource_0")); + root.setContentMimeTypes(QStringList() << Akonadi::Collection::mimeType()); + root.setParentCollection(Akonadi::Collection::root()); + root.setRemoteId("root-id"); + root = resource->createRootCollection(root); + + Akonadi::Collection col; + col.setName("Configuration"); + col.setContentMimeTypes(QStringList() << KolabHelpers::getMimeType(Kolab::ConfigurationType)); + col.setRemoteId("/configuration"); + col = resource->createCollection(col); + + Akonadi::Collection mailcol; + mailcol.setName("INBOX"); + mailcol.setContentMimeTypes(QStringList() << KMime::Message::mimeType()); + mailcol.setRemoteId("/INBOX"); + mailcol = resource->createCollection(mailcol); + + Akonadi::Item item(KMime::Message::mimeType()); + item.setRemoteId("20"); + item = resource->createItem(item, mailcol); + + QTest::addColumn< QList >("scenario"); + QTest::addColumn("callNames"); + QTest::addColumn("expectedTags"); + QTest::addColumn("expectedMembers"); + + QList scenario; + QStringList callNames; + + Akonadi::Tag tag; + tag.setName("tagname"); + Kolab::KolabObjectWriter writer; + QStringList members; + members << QLatin1String("imap:///user/john.doe%40example.org/INBOX/20?message-id=%3Cf06aa3345a25005380b47547ad161d36%40lhm.klab.cc%3E&date=Tue%2C+12+Aug+2014+20%3A42%3A59+%2B0200&subject=Re%3A+test"); + KMime::Message::Ptr msg = writer.writeTag(tag, members); + // qCDebug(KOLABRESOURCE_LOG) << msg->encodedContent(); + + const QByteArray &content = msg->encodedContent(true); + scenario.clear(); + scenario << defaultPoolConnectionScenario() + << "C: A000003 SELECT \"configuration\"" + << "S: A000003 OK select done" + << "C: A000004 FETCH 1:* (RFC822.SIZE INTERNALDATE BODY.PEEK[] FLAGS UID)" + << "S: * 1 FETCH ( FLAGS (\\Seen) UID 7 INTERNALDATE \"29-Jun-2010 15:26:42 +0200\" " + "RFC822.SIZE 75 BODY[] {" + QByteArray::number(content.size()) + "}\r\n" + + content + " )" + << "S: A000004 OK fetch done"; + + callNames.clear(); + callNames << "tagsRetrieved"; + + Akonadi::Tag expectedTag = tag; + expectedTag.setRemoteId("7"); + + QHash expectedMembers; + Akonadi::Item member; + member.setRemoteId("20"); + member.setParentCollection(createCollectionChain("/INBOX")); + expectedMembers.insert(expectedTag.remoteId(), (Akonadi::Item::List() << member)); + + QTest::newRow("list single tag") << scenario << callNames << (Akonadi::Tag::List() << expectedTag) << expectedMembers; + } + + void testRetrieveTags() + { + QFETCH(QList, scenario); + QFETCH(QStringList, callNames); + QFETCH(Akonadi::Tag::List, expectedTags); + QFETCH(Members, expectedMembers); + + FakeServer server; + server.setScenario(scenario); + server.startAndWait(); + + SessionPool pool(1); + + pool.setPasswordRequester(createDefaultRequester()); + QVERIFY(pool.connect(createDefaultAccount())); + QVERIFY(waitForSignal(&pool, SIGNAL(connectDone(int,QString)))); + + DummyResourceState::Ptr state = DummyResourceState::Ptr(new DummyResourceState); + state->setServerCapabilities(QStringList() << "METADATA" << "ACL"); + state->setUserName("Hans"); + KolabRetrieveTagTask *task = new KolabRetrieveTagTask(state, KolabRetrieveTagTask::RetrieveTags); + + task->start(&pool); + + QTRY_COMPARE(state->calls().count(), callNames.size()); + for (int i = 0; i < callNames.size(); i++) { + QString command = QString::fromUtf8(state->calls().at(i).first); + QVariant parameter = state->calls().at(i).second; + + if (command == "cancelTask" && callNames[i] != "cancelTask") { + qCDebug(KOLABRESOURCE_LOG) << "Got a cancel:" << parameter.toString(); + } + + QCOMPARE(command, callNames[i]); + + if (command == "tagsRetrieved") { + QPair > pair = parameter.value(); + Akonadi::Tag::List tags = pair.first; + QHash members = pair.second; + QCOMPARE(tags.size(), expectedTags.size()); + for (int i = 0 ; i < tags.size(); i++) { + QCOMPARE(tags[i].name(), expectedTags[i].name()); + QCOMPARE(tags[i].remoteId(), expectedTags[i].remoteId()); + const Akonadi::Item::List memberlist = members.value(tags[i].remoteId()); + const Akonadi::Item::List expectedMemberlist = expectedMembers.value(tags[i].remoteId()); + QCOMPARE(memberlist.size(), expectedMemberlist.size()); + for (int i = 0 ; i < expectedMemberlist.size(); i++) { + QCOMPARE(memberlist[i].remoteId(), expectedMemberlist[i].remoteId()); + Akonadi::Collection parent = memberlist[i].parentCollection(); + Akonadi::Collection expectedParent = expectedMemberlist[i].parentCollection(); + while (expectedParent.isValid()) { + QCOMPARE(parent.remoteId(), expectedParent.remoteId()); + expectedParent = expectedParent.parentCollection(); + parent = parent.parentCollection(); + } + } + } + } + } + + QVERIFY(server.isAllScenarioDone()); + + server.quit(); + } +}; + +QTEST_AKONADIMAIN(TestRetrieveTagsTask, NoGUI) + +#include "testretrievetagstask.moc" diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/config-mysql-db.xml kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/config-mysql-db.xml --- kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/config-mysql-db.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/config-mysql-db.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,8 @@ + + kdehome + xdgconfig-mysql.db + xdglocal + akonadi_knut_resource + true + mysql + diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/config-mysql-fs.xml kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/config-mysql-fs.xml --- kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/config-mysql-fs.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/config-mysql-fs.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,8 @@ + + kdehome + xdgconfig-mysql.fs + xdglocal + akonadi_knut_resource + true + mysql + diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/config-postgresql-db.xml kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/config-postgresql-db.xml --- kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/config-postgresql-db.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/config-postgresql-db.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,8 @@ + + kdehome + xdgconfig-postgresql.db + xdglocal + akonadi_knut_resource + true + postgresql + diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/config-postgresql-fs.xml kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/config-postgresql-fs.xml --- kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/config-postgresql-fs.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/config-postgresql-fs.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,8 @@ + + kdehome + xdgconfig-postgresql.fs + xdglocal + akonadi_knut_resource + true + postgresql + diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/config-sqlite-db.xml kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/config-sqlite-db.xml --- kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/config-sqlite-db.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/config-sqlite-db.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,8 @@ + + kdehome + xdgconfig-sqlite.db + xdglocal + akonadi_knut_resource + true + sqlite + diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc --- kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,4 @@ +[ProcessedDefaults] +defaultaddressbook=done +defaultcalendar=done +defaultnotebook=done diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc --- kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,4 @@ +[General] +DataFile[$e]=$KDEHOME/testdata-res1.xml +FileWatchingEnabled=false + diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/kdehome/share/config/kdebugrc kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/kdehome/share/config/kdebugrc --- kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/kdehome/share/config/kdebugrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/kdehome/share/config/kdebugrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,80 @@ +DisableAll=false + +[0] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[264] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[5250] +InfoOutput=2 + +[7009] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[7011] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[7012] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[7014] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[7021] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/kdehome/share/config/kdedrc kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/kdehome/share/config/kdedrc --- kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/kdehome/share/config/kdedrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/kdehome/share/config/kdedrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,3 @@ +[General] +CheckSycoca=false +CheckFileStamps=false diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/kdehome/testdata-res1.xml kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/kdehome/testdata-res1.xml --- kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/kdehome/testdata-res1.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/kdehome/testdata-res1.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,37 @@ + + + + + testmailbody + From: <test@user.tst> + \SEEN + \FLAGGED + \DRAFT + + + + /shared/vendor/kolab/folder-type event + + + /shared/vendor/kolab/folder-type contact + + + /shared/vendor/kolab/folder-type note + + + /shared/vendor/kolab/folder-type task + + + /shared/vendor/kolab/folder-type journal + + + /shared/vendor/kolab/folder-type configuration + + + /shared/vendor/kolab/folder-type freebusy + + + /shared/vendor/kolab/folder-type file + + + diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/xdgconfig-mysql.db/akonadi/akonadiserverrc kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/xdgconfig-mysql.db/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/xdgconfig-mysql.db/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/xdgconfig-mysql.db/akonadi/akonadiserverrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,5 @@ +[%General] +ExternalPayload=false + +[Search] +Manager=Dummy diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/xdgconfig-mysql.fs/akonadi/akonadiserverrc kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/xdgconfig-mysql.fs/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/xdgconfig-mysql.fs/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/xdgconfig-mysql.fs/akonadi/akonadiserverrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,6 @@ +[%General] +SizeThreshold=0 +ExternalPayload=true + +[Search] +Manager=Dummy diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/xdgconfig-postgresql.db/akonadi/akonadiserverrc kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/xdgconfig-postgresql.db/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/xdgconfig-postgresql.db/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/xdgconfig-postgresql.db/akonadi/akonadiserverrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,9 @@ +[%General] +Driver=QPSQL +ExternalPayload=false + +[Search] +Manager=Dummy + +[QPSQL] +StartServer=true diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/xdgconfig-postgresql.fs/akonadi/akonadiserverrc kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/xdgconfig-postgresql.fs/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/xdgconfig-postgresql.fs/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/xdgconfig-postgresql.fs/akonadi/akonadiserverrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,10 @@ +[%General] +Driver=QPSQL +SizeThreshold=0 +ExternalPayload=true + +[Search] +Manager=Dummy + +[QPSQL] +StartServer=true diff -Nru kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/xdgconfig-sqlite.db/akonadi/akonadiserverrc kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/xdgconfig-sqlite.db/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/resources/kolab/tests/unittestenv/xdgconfig-sqlite.db/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/tests/unittestenv/xdgconfig-sqlite.db/akonadi/akonadiserverrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,10 @@ +[%General] +# This is a slightly adjusted version of the QSQLITE driver from Qt +# It is provided by akonadi itself +Driver=QSQLITE3 + +[Debug] +Tracer=null + +[Search] +Manager=Dummy diff -Nru kdepim-runtime-4.14.6/resources/kolab/updatemessagejob.cpp kdepim-runtime-15.08.0/resources/kolab/updatemessagejob.cpp --- kdepim-runtime-4.14.6/resources/kolab/updatemessagejob.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/updatemessagejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,235 @@ +/* + Copyright (c) 2014 Christian Mollekopf + + 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 "updatemessagejob.h" + +#include +#include +#include +#include +#include +#include +#include "kolabresource_debug.h" +#include +#include + +#include "imapflags.h" + +//Check if the expected uid message is still there => no modification, replace message. +//otherwise search for uptodate message by subject containing UID, merge contents, and replace message + +UpdateMessageJob::UpdateMessageJob(const KMime::Message::Ptr &msg, KIMAP::Session *session, const QByteArray &kolabUid, QSharedPointer merger, const QString &mailbox, qint64 uidNext, qint64 oldUid, QObject *parent) + : KJob(parent), + mSession(session), + mMessage(msg), + mMailbox(mailbox), + mUidNext(uidNext), + mOldUid(oldUid), + mNewUid(-1), + mMessageId(msg->messageID()->asUnicodeString().toUtf8()), + mKolabUid(kolabUid), + mMerger(merger) +{ + mOldUids.add(oldUid); +} + +void UpdateMessageJob::start() +{ + KIMAP::FetchJob *fetchJob = new KIMAP::FetchJob(mSession); + + fetchJob->setSequenceSet(KIMAP::ImapSet(mOldUid)); + fetchJob->setUidBased(true); + + KIMAP::FetchJob::FetchScope scope; + scope.parts.clear(); + scope.mode = KIMAP::FetchJob::FetchScope::Headers; + fetchJob->setScope(scope); + + connect(fetchJob, SIGNAL(headersReceived(QString, + QMap, + QMap, + QMap, + QMap, + QMap)), + this, SLOT(onHeadersReceived(QString, + QMap, + QMap, + QMap, + QMap, + QMap))); + connect(fetchJob, SIGNAL(result(KJob*)), + this, SLOT(onHeadersFetchDone(KJob*))); + fetchJob->start(); + +} + +void UpdateMessageJob::onHeadersReceived(QString, + QMap uids, + QMap, + QMap, + QMap flags, + QMap) +{ + //Filter deleted messages + foreach (qint64 number, uids.keys()) { //krazy:exclude=foreach + // const KMime::Message::Ptr msg = messages[number]; + if (!flags[number].contains(ImapFlags::Deleted)) { + mFoundUids << uids[number]; + } + } +} + +void UpdateMessageJob::onHeadersFetchDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "Failed to fetch message: " << job->errorString(); + } + if (mFoundUids.size() >= 1) { + qCDebug(KOLABRESOURCE_LOG) << "Fast-forward update, replacing message."; + appendMessage(); + } else { + if (mSession->selectedMailBox() != mMailbox) { + KIMAP::SelectJob *select = new KIMAP::SelectJob(mSession); + select->setMailBox(mMailbox); + connect(select, SIGNAL(result(KJob*)), this, SLOT(onSelectDone(KJob*))); + select->start(); + } else { + searchForLatestVersion(); + } + } +} + +void UpdateMessageJob::onSelectDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << job->errorString(); + setError(KJob::UserDefinedError); + emitResult(); + } else { + searchForLatestVersion(); + } +} + +void UpdateMessageJob::searchForLatestVersion() +{ + KIMAP::SearchJob *search = new KIMAP::SearchJob(mSession); + search->setUidBased(true); + search->setSearchLogic(KIMAP::SearchJob::And); + search->addSearchCriteria(KIMAP::SearchJob::Header, "Subject " + mKolabUid); + connect(search, SIGNAL(result(KJob*)), + this, SLOT(onSearchDone(KJob*))); + search->start(); +} + +void UpdateMessageJob::onSearchDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << job->errorString(); + setError(KJob::UserDefinedError); + emitResult(); + return; + } + + KIMAP::SearchJob *search = static_cast(job); + + if (search->results().count() >= 1) { + mOldUids = KIMAP::ImapSet(); + foreach (qint64 id, search->results()) { + mOldUids.add(id); + } + + KIMAP::FetchJob *fetchJob = new KIMAP::FetchJob(mSession); + fetchJob->setSequenceSet(mOldUids); + fetchJob->setUidBased(true); + + KIMAP::FetchJob::FetchScope scope; + scope.parts.clear(); + scope.mode = KIMAP::FetchJob::FetchScope::Full; + fetchJob->setScope(scope); + + connect(fetchJob, SIGNAL(headersReceived(QString, + QMap, + QMap, + QMap, + QMap, + QMap)), + this, SLOT(onConflictingMessagesReceived(QString, + QMap, + QMap, + QMap, + QMap, + QMap))); + connect(fetchJob, SIGNAL(result(KJob*)), + this, SLOT(onConflictingMessageFetchDone(KJob*))); + fetchJob->start(); + } else { + qCWarning(KOLABRESOURCE_LOG) << "failed to find latest version of object"; + appendMessage(); + } +} + +void UpdateMessageJob::onConflictingMessagesReceived(QString, + QMap uids, + QMap, + QMap, + QMap flags, + QMap messages) +{ + foreach (qint64 number, uids.keys()) { //krazy:exclude=foreach + if (!flags[number].contains(ImapFlags::Deleted)) { + mMessagesToMerge << messages[number]; + } + } +} + +void UpdateMessageJob::onConflictingMessageFetchDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << "Failed to retrieve messages to merge: " << job->errorString(); + } + mMessage = mMerger->merge(mMessage, mMessagesToMerge); + appendMessage(); +} + +void UpdateMessageJob::appendMessage() +{ + const qint64 uidNext = -1; + ReplaceMessageJob *replace = new ReplaceMessageJob(mMessage, mSession, mMailbox, uidNext, mOldUids, this); + connect(replace, SIGNAL(result(KJob*)), this, SLOT(onReplaceDone(KJob*))); + replace->start(); +} + +void UpdateMessageJob::onReplaceDone(KJob *job) +{ + if (job->error()) { + qCWarning(KOLABRESOURCE_LOG) << job->errorString(); + setError(KJob::UserDefinedError); + emitResult(); + return; + } + ReplaceMessageJob *replaceJob = static_cast(job); + mNewUid = replaceJob->newUid(); + emitResult(); +} + +qint64 UpdateMessageJob::newUid() const +{ + return mNewUid; +} + diff -Nru kdepim-runtime-4.14.6/resources/kolab/updatemessagejob.h kdepim-runtime-15.08.0/resources/kolab/updatemessagejob.h --- kdepim-runtime-4.14.6/resources/kolab/updatemessagejob.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/updatemessagejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,85 @@ +/* + Copyright (c) 2014 Christian Mollekopf + + 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 UPDATEMESSAGEJOB_H +#define UPDATEMESSAGEJOB_H + +#include +#include +#include +#include + +struct Merger { + virtual ~Merger() {} + virtual KMime::Message::Ptr merge(KMime::Message::Ptr newMessage, QList conflictingMessages) const = 0; +}; + +/** + * This job appends a message, marks the old one as deleted, and returns the uid of the appended message. + */ +class UpdateMessageJob : public KJob +{ + Q_OBJECT +public: + UpdateMessageJob(const KMime::Message::Ptr &msg, KIMAP::Session *session, const QByteArray &kolabUid, QSharedPointer merger, const QString &mailbox, qint64 uidNext = -1, qint64 oldUid = -1, QObject *parent = 0); + + qint64 newUid() const; + + void start(); + +private: + void searchForLatestVersion(); + void appendMessage(); + +private Q_SLOTS: + void onHeadersReceived(QString, + QMap uids, + QMap, + QMap, + QMap, + QMap); + void onHeadersFetchDone(KJob *job); + void onSelectDone(KJob *job); + void onSearchDone(KJob *job); + void onConflictingMessagesReceived(QString, + QMap uids, + QMap, + QMap, + QMap, + QMap); + void onConflictingMessageFetchDone(KJob *job); + void onReplaceDone(KJob *job); + +private: + KIMAP::Session *mSession; + KMime::Message::Ptr mMessage; + const QString mMailbox; + qint64 mUidNext; + qint64 mOldUid; + KIMAP::ImapSet mOldUids; + qint64 mNewUid; + const QByteArray mMessageId; + const QByteArray mKolabUid; + QList mFoundUids; + QList mMessagesToMerge; + QSharedPointer mMerger; +}; + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/kolab/wizard/CMakeLists.txt kdepim-runtime-15.08.0/resources/kolab/wizard/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/kolab/wizard/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/wizard/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,5 @@ + +install( + FILES kolabwizard.desktop kolabwizard.es kolabwizard.ui kolabwizard2.ui + DESTINATION ${KDE_INSTALL_DATADIR}/akonadi/accountwizard/kolab +) diff -Nru kdepim-runtime-4.14.6/resources/kolab/wizard/kolabwizard2.ui kdepim-runtime-15.08.0/resources/kolab/wizard/kolabwizard2.ui --- kdepim-runtime-4.14.6/resources/kolab/wizard/kolabwizard2.ui 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/wizard/kolabwizard2.ui 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,180 @@ + + + kolabWizard_step2 + + + + 0 + 0 + 625 + 134 + + + + + + + + + + IMAP: + + + + + + + + + + 0 + 0 + + + + + + + + + + + IMAP Server Name: + + + + + + + + + + true + + + Manual Edit + + + false + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + true + + + Create + + + + + + + + + Freebusy: + + + + + + + SMTP: + + + + + + + + + + 0 + 0 + + + + + + + + + + + SMTP Server Name: + + + + + + + + + + true + + + Manual Edit + + + false + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + Create + + + + + + + + + LDAP: + + + + + + + + diff -Nru kdepim-runtime-4.14.6/resources/kolab/wizard/kolabwizard.desktop kdepim-runtime-15.08.0/resources/kolab/wizard/kolabwizard.desktop --- kdepim-runtime-4.14.6/resources/kolab/wizard/kolabwizard.desktop 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/wizard/kolabwizard.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,101 @@ +[Desktop Entry] +Name=Kolab Groupware Server +Name[bg]=Сървър Kolab Groupware +Name[bs]=Server kolaborativnog softvera +Name[ca]=Servidor de treball en grup Kolab +Name[ca@valencia]=Servidor de treball en grup Kolab +Name[cs]=Kolab Groupware server +Name[da]=Kolab groupware-server +Name[de]=Kolab Groupware-Server +Name[el]=Εξυπηρετητής Groupware Kolab +Name[en_GB]=Kolab Groupware Server +Name[es]=Servidor de colaboración Kolab +Name[et]=Kolabi grupitöö server +Name[fi]=Kolab-työryhmäpalvelin +Name[fr]=Serveur de logiciels de collaboration Kolab +Name[ga]=Freastalaí Groupware Kolab +Name[gl]=Servidor de Traballo en Grupo Kolab +Name[hu]=Kolab csoportmunka-kiszolgáló +Name[ia]=Servitor de Kolab Groupware +Name[it]=Server di groupware Kolab +Name[ja]=Kolab グループウェアサーバ +Name[kk]=Kolab топтық іс сервері +Name[km]=ម៉ាស៊ីន​បម្រើ Kolab Groupware +Name[ko]=Kolab 그룹웨어 서버 +Name[lt]=Kolab grupinio darbo serveris +Name[lv]=Kolab grupdarba serveris +Name[nb]=Kolab groupware-tjener +Name[nds]=Kolab-Arbeitkoppelserver +Name[nl]=Kolab groupwareserver +Name[nn]=Kolab Groupware-tenar +Name[pl]=Serwer Groupware Kolab +Name[pt]=Servidor de Groupware Kolab +Name[pt_BR]=Servidor groupware Kolab +Name[ro]=Server Kolab Groupware +Name[ru]=Сервер совместной работы Kolab +Name[sk]=Groupware Server Kolab +Name[sl]=Strežnik za skupinsko delo Kolab +Name[sr]=Колабов групверски сервер +Name[sr@ijekavian]=Колабов групверски сервер +Name[sr@ijekavianlatin]=Kolabov grupverski server +Name[sr@latin]=Kolabov grupverski server +Name[sv]=Kolab grupprogramserver +Name[tr]=Kolab Groupware Sunucusu +Name[uk]=Сервер групової роботи Kolab +Name[x-test]=xxKolab Groupware Serverxx +Name[zh_CN]=Kolab 群件服务器 +Name[zh_TW]=Kolab 群組伺服器 +Icon=kolab +Comment=Kolab Groupware Server +Comment[bg]=Сървър Kolab Groupware +Comment[bs]=Server kolaborativnog softvera +Comment[ca]=Servidor de treball en grup Kolab +Comment[ca@valencia]=Servidor de treball en grup Kolab +Comment[cs]=Kolab Groupware server +Comment[da]=Kolab groupware-server +Comment[de]=Kolab Groupware-Server +Comment[el]=Εξυπηρετητής Groupware Kolab +Comment[en_GB]=Kolab Groupware Server +Comment[es]=Servidor de colaboración Kolab +Comment[et]=Kolabi grupitöö server +Comment[fi]=Kolab-työryhmäpalvelin +Comment[fr]=Serveur de logiciels de collaboration Kolab +Comment[ga]=Freastalaí Groupware Kolab +Comment[gl]=Servidor de traballo en grupo Kolab +Comment[hu]=Kolab csoportmunka-kiszolgáló +Comment[ia]=Servitor de Kolab Groupware +Comment[it]=Server di groupware Kolab +Comment[ja]=Kolab グループウェアサーバ +Comment[kk]=Kolab топтық іс сервері +Comment[km]=ម៉ាស៊ីន​បម្រើ Kolab Groupware +Comment[ko]=Kolab 그룹웨어 서버 +Comment[lt]=Kolab grupinio darbo serveris +Comment[lv]=Kolab grupdarba serveris +Comment[nb]=Kolab groupware-tjener +Comment[nds]=Kolab-Arbeitkoppelserver +Comment[nl]=Kolab-groupware-server +Comment[nn]=Kolab Groupware-tenar +Comment[pl]=Serwer Kolab Groupware +Comment[pt]=Servidor de 'Groupware' Kolab +Comment[pt_BR]=Servidor groupware Kolab +Comment[ro]=Server Kolab Groupware +Comment[ru]=Сервер совместной работы Kolab +Comment[sk]=Groupware Server Kolab +Comment[sl]=Strežnik za skupinsko delo Kolab +Comment[sr]=Колабов групверски сервер +Comment[sr@ijekavian]=Колабов групверски сервер +Comment[sr@ijekavianlatin]=Kolabov grupverski server +Comment[sr@latin]=Kolabov grupverski server +Comment[sv]=Kolab grupprogramserver +Comment[tr]=Kolab Groupware Sunucusu +Comment[uk]=Сервер групової роботи Kolab +Comment[x-test]=xxKolab Groupware Serverxx +Comment[zh_CN]=Kolab 群件服务器 +Comment[zh_TW]=Kolab 群組伺服器 + +[Wizard] +Type=message/rfc822,text/directory,text/calendar,text/x-vnd.akonadi.note +Script=kolabwizard.es + +[Translate] +Filename=accountwizard_kolab diff -Nru kdepim-runtime-4.14.6/resources/kolab/wizard/kolabwizard.es kdepim-runtime-15.08.0/resources/kolab/wizard/kolabwizard.es --- kdepim-runtime-4.14.6/resources/kolab/wizard/kolabwizard.es 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/wizard/kolabwizard.es 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,322 @@ +/* + Copyright (c) 2014 Sandro Knauß + + 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. +*/ + +// add this function to trim user input of whitespace when needed +String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); }; + +var page = Dialog.addPage("kolabwizard.ui", qsTr("Personal Settings")); +var page2 = Dialog.addPage("kolabwizard2.ui", qsTr("Autoconfiguration")); +var userChangedServerAddress = false; + +page.widget().nameEdit.text = SetupManager.name() +page.widget().emailEdit.text = SetupManager.email() +page.widget().passwordEdit.text = SetupManager.password() + +function guessServerName() +{ + var email = page.widget().emailEdit.text; + var pos = email.indexOf("@"); + if (pos >= 0 && (pos + 1) < email.length) { + var server = email.slice(pos + 1, email.length); + return server; + } +} + +function validateInput() +{ + if (page.widget().emailEdit.text.trim() == "" || page.widget().passwordEdit.text.trim() == "") { + page.setValid(false); + } else { + page.setValid(true); + } +} + +//Server test +servertest_running = false; +//0 = not running, 1=submission, 2 = smtp, 3 = imap +servertest_mode = 0; + +function testResultFail() +{ + testOk( -1 ); +} + +var imapRes; +function testOk( arg ) +{ + print("testOk arg =", arg); + + if (servertest_mode < 3) { // submission & smtp + if (arg == "tls" ) { // tls is really STARTTLS + smtp.setEncryption("TLS"); + if (servertest_mode == 1) { //submission port 587 + smtp.setPort(587); + } else { + smtp.setPort(25); + } + } else if ( arg == "ssl" ) { //only possible as smtps + smtp.setPort(465); + smtp.setEncryption("SSL"); + } else if (servertest_mode == 2) { //test submission and smtp failed or only possible unencrypted -> set to standard value and open editor + smtp.setPort(587); + smtp.setEncryption("TLS"); + smtp.setEditMode(true); + } else if (servertest_mode == 1) { // submission test failed -> start smtp request + servertest_mode = 2; + ServerTest.test(page2.widget().lineEditSmtp.text, "smtp"); + return; + } + + // start imap test + servertest_mode = 3; + if (page2.widget().lineEditImap.text) { + SetupManager.setupInfo(qsTr("Probing IMAP server...")); + ServerTest.test(page2.widget().lineEditImap.text, "imap"); + } else { + SetupManager.execute(); + } + } else if (servertest_mode == 3) { //imap + if ( arg == "ssl" ) { + // The ENUM used for authentication (in the kolab resource only) + kolabRes.setOption( "Safety", "SSL" ); // SSL/TLS + kolabRes.setOption( "ImapPort", 993 ); + } else if ( arg == "tls" ) { // tls is really STARTTLS + kolabRes.setOption( "Safety", "STARTTLS" ); // STARTTLS + kolabRes.setOption( "ImapPort", 143 ); + } else { + // safe default fallback in case server test failed + kolabRes.setOption( "Safety", "STARTTLS" ); + kolabRes.setOption( "ImapPort", 143 ); + kolabRes.setEditMode(true); + } + SetupManager.execute(); + } else { + print ("Unknown servertest_mode = ", servertest_mode); + } +} + +var identity; // global so it can be accesed in setup and testOk + +var kolabRes; +var smtp; +var imapRes; + +var ac_mail; +var ac_freebusy; +var ac_ldap; + +var ac_mail_stat; +var ac_freebusy_stat; +var ac_ldap_stat; + +function checkAutoconfig() +{ + ac_mail_stat = false; + ac_freebusy_stat = false; + ac_ldap_stat = false; + + page2.widget().lineEditImap.text = guessServerName(); + page2.widget().lineEditSmtp.text = guessServerName(); + page2.widget().lineEditImap.visible = false; + page2.widget().lineEditSmtp.visible = false; + page2.widget().lineEditImapLabel.visible = false; + page2.widget().lineEditSmtpLabel.visible = false; + + page2.widget().checkBoxFreebusyEdit.text = qsTr("Create"); + page2.widget().checkBoxLdapEdit.text = qsTr("Create"); + + ac_mail = SetupManager.ispDB('autoconfigkolabmail'); + ac_mail.ispdbFinished.connect(mail_finished); + ac_mail.info.connect(mail_text); + ac_mail.setEmail(page.widget().emailEdit.text); + ac_mail.setPassword(page.widget().passwordEdit.text); + ac_mail.start(); + + ac_freebusy = SetupManager.ispDB('autoconfigkolabfreebusy'); + ac_freebusy.ispdbFinished.connect(freebusy_finished); + ac_freebusy.info.connect(freebusy_text); + ac_freebusy.setEmail(page.widget().emailEdit.text); + ac_freebusy.setPassword(page.widget().passwordEdit.text); + ac_freebusy.start(); + + ac_ldap = SetupManager.ispDB('autoconfigkolabldap'); + ac_ldap.ispdbFinished.connect(ldap_finished); + ac_ldap.info.connect(ldap_text); + ac_ldap.setEmail(page.widget().emailEdit.text); + ac_ldap.setPassword(page.widget().passwordEdit.text); + ac_ldap.start(); +} + +function mail_finished(stat) { + ac_mail_stat = stat; + if (stat) { + page2.widget().lineEditImap.visible = false; + page2.widget().lineEditSmtp.visible = false; + page2.widget().lineEditImapLabel.visible = false; + page2.widget().lineEditSmtpLabel.visible = false; + } else { + page2.widget().lineEditImap.visible = true; + page2.widget().lineEditSmtp.visible = true; + page2.widget().lineEditImapLabel.visible = true; + page2.widget().lineEditSmtpLabel.visible = true; + } +} + +function mail_text(text) { + page2.widget().labelImapSearch.text = text; + page2.widget().labelSmtpSearch.text = text; +} + +function freebusy_finished(stat) { + ac_freebusy_stat = stat; + if (stat) { + page2.widget().checkBoxFreebusyEdit.text = qsTr("Manual Edit"); + } +} + +function freebusy_text(text) { + page2.widget().labelFreebusySearch.text = text; +} + +function ldap_finished(stat) { + ac_ldap_stat = stat; + if (stat) { + page2.widget().checkBoxLdapEdit.text = qsTr("Manual Edit"); + } +} + +function ldap_text(text) { + page2.widget().labelLdapSearch.text = text; +} + +function setup() +{ + SetupManager.openWallet(); + smtp = SetupManager.createTransport("smtp"); + smtp.setEditMode(page2.widget().checkBoxSmtpEdit.checked); + smtp.setPassword(page.widget().passwordEdit.text); + + if (ac_mail_stat) { + ac_mail.fillSmtpServer(0, smtp); + } else if (page2.widget().lineEditSmtp.text) { + var serverAddress = page2.widget().lineEditSmtp.text; + servertest_running = true; + servertest_mode = 1; + smtp.setName(serverAddress); + smtp.setHost(serverAddress); + smtp.setUsername(page.widget().emailEdit.text); + smtp.setAuthenticationType("plain"); + + SetupManager.setupInfo(qsTr("Probing SMTP server...")); + ServerTest.test( serverAddress, "submission" ); //probe port and encryption + } + + for (i = 0; i < ac_mail.countIdentities(); i++) { + var j = SetupManager.createIdentity(); + j.setTransport(smtp); + //templates + //drafts + //fcc + ac_mail.fillIdentitiy(i,j); + if (i == ac_mail.defaultIdentity()) { + identity = j; + } + } + + if (ac_mail.countIdentities() == 0) { + identity = SetupManager.createIdentity(); + identity.setEmail(page.widget().emailEdit.text); + identity.setRealName(page.widget().nameEdit.text); + identity.setTransport(smtp); + } + + kolabRes = SetupManager.createResource("akonadi_kolab_resource"); + kolabRes.setEditMode(page2.widget().checkBoxImapEdit.checked); + kolabRes.setOption("Password", page.widget().passwordEdit.text); + kolabRes.setOption("UseDefaultIdentity", false); + kolabRes.setOption("AccountIdentity", identity.uoid()); + kolabRes.setOption("DisconnectedModeEnabled", true); + kolabRes.setOption("IntervalCheckTime", 60); + kolabRes.setOption("SubscriptionEnabled", true); + kolabRes.setOption("SieveSupport", true); + + if (ac_mail_stat) { + ac_mail.fillImapServer(0, kolabRes); + } else if (page2.widget().lineEditImap.text) { + var serverAddress = page2.widget().lineEditImap.text; + kolabRes.setOption("ImapServer", serverAddress); + kolabRes.setOption("UserName", page.widget().emailEdit.text.trim()); + + if (!servertest_running) { + servertest_mode = 2; + servertest_running = true; + SetupManager.setupInfo(qsTr("Probing IMAP server...")); + ServerTest.test(serverAddress, "imap"); + } kolabRes.setOption("Authentication", 7); + } + + if (ac_ldap_stat) { + for (i = 0; i < ac_ldap.countLdapServers(); i++) { + var ldap = SetupManager.createLdap(); + ldap.setEditMode(page2.widget().checkBoxLdapEdit.checked); + ac_ldap.fillLdapServer(i,ldap); + } + } else if (page2.widget().checkBoxLdapEdit.checked) { + var ldap = SetupManager.createLdap(); + ldap.setEditMode(page2.widget().checkBoxLdapEdit.checked); + ldap.setPassword(page.widget().passwordEdit.text); + ldap.setUser(page.widget().emailEdit.text); + ldap.setServer(guessServerName()); + } + + if (ac_freebusy_stat) { + var korganizer = SetupManager.createConfigFile("akonadi-calendarrc"); + korganizer.setEditMode(page2.widget().checkBoxFreebusyEdit.checked); + korganizer.setEditName("freebusy"); + korganizer.setName("korganizer"); + ac_freebusy.fillFreebusyServer(0,korganizer); + } else if (page2.widget().checkBoxFreebusyEdit.checked) { + var korganizer = SetupManager.createConfigFile("akonadi-calendarrc"); + korganizer.setEditMode(page2.widget().checkBoxFreebusyEdit.checked); + korganizer.setEditName("freebusy"); + korganizer.setName( "korganizer" ); + korganizer.setConfig( "FreeBusy Retrieve", "FreeBusyFullDomainRetrieval","true"); + korganizer.setConfig( "FreeBusy Retrieve", "FreeBusyRetrieveAuto", "true" ); + korganizer.setConfig( "FreeBusy Retrieve", "FreeBusyRetrieveUrl", "https://" + guessServerName() + "/freebusy/" ); + } + + if (!servertest_running) { + SetupManager.execute(); + } +} + +try { + ServerTest.testFail.connect(testResultFail); + ServerTest.testResult.connect(testOk); + + page.widget().emailEdit.textChanged.connect(validateInput); + page.widget().passwordEdit.textChanged.connect(validateInput); + + page.pageLeftNext.connect(checkAutoconfig); + page2.pageLeftNext.connect(setup); +} catch (e) { + print(e); +} + +validateInput(); diff -Nru kdepim-runtime-4.14.6/resources/kolab/wizard/kolabwizard.ui kdepim-runtime-15.08.0/resources/kolab/wizard/kolabwizard.ui --- kdepim-runtime-4.14.6/resources/kolab/wizard/kolabwizard.ui 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/wizard/kolabwizard.ui 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,98 @@ + + + kolabWizard_step1 + + + + 0 + 0 + 368 + 125 + + + + + QFormLayout::ExpandingFieldsGrow + + + + + &Name: + + + nameEdit + + + + + + + + + + &Email: + + + emailEdit + + + + + + + + + + &Password: + + + passwordEdit + + + + + + + QLineEdit::Password + + + + + + + Kolab Version: + + + versionComboBox + + + + + + + 1 + + + + v2 + + + + + v3 + + + + + + + + + KLineEdit + QLineEdit +
klineedit.h
+
+
+ + +
diff -Nru kdepim-runtime-4.14.6/resources/kolab/wizard/Messages.sh kdepim-runtime-15.08.0/resources/kolab/wizard/Messages.sh --- kdepim-runtime-4.14.6/resources/kolab/wizard/Messages.sh 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolab/wizard/Messages.sh 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +$EXTRACTRC *.ui >> rc.cpp +$XGETTEXT *.cpp -o $podir/accountwizard_kolab.pot +$XGETTEXT -kqsTr *.es -j -o $podir/accountwizard_kolab.pot diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/addressbookhandler.cpp kdepim-runtime-15.08.0/resources/kolabproxy/addressbookhandler.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/addressbookhandler.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/addressbookhandler.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,167 +0,0 @@ -/* - Copyright (c) 2009 Andras Mantia - Copyright (c) 2009 Kevin Krammer - Copyright (c) 2012 Christian Mollekopf - - 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 "addressbookhandler.h" -#include -#include - -AddressBookHandler::AddressBookHandler( const Akonadi::Collection &imapCollection ) - : KolabHandler( imapCollection ) -{ - m_mimeType = "application/x-vnd.kolab.contact"; -} - -AddressBookHandler::~AddressBookHandler() -{ -} - -Akonadi::Item::List AddressBookHandler::translateItems( const Akonadi::Item::List &items ) -{ - Akonadi::Item::List newItems; - Q_FOREACH ( const Akonadi::Item &item, items ) { - if ( !item.hasPayload() ) { - kWarning() << "Payload is not a MessagePtr!"; - continue; - } - const KMime::Message::Ptr payload = item.payload(); - Kolab::KolabObjectReader reader( payload ); - if ( reader.getType() == Kolab::ContactObject ) { - Akonadi::Item newItem( KABC::Addressee::mimeType() ); - newItem.setRemoteId( QString::number( item.id() ) ); - newItem.setPayload( reader.getContact() ); - newItems << newItem; - } else if ( reader.getType() == Kolab::DistlistObject ) { - KABC::ContactGroup contactGroup = reader.getDistlist(); - - QList toAdd; - for ( uint index = 0; index < contactGroup.contactReferenceCount(); ++index ) { - const KABC::ContactGroup::ContactReference& reference = contactGroup.contactReference( index ); - KABC::ContactGroup::ContactReference ref; - ref.setGid( reference.uid() ); //libkolab set a gid with setUid() - toAdd << ref; - } - contactGroup.removeAllContactReferences(); - foreach ( const KABC::ContactGroup::ContactReference &ref, toAdd ) { - contactGroup.append( ref ); - } - - Akonadi::Item newItem( KABC::ContactGroup::mimeType() ); - newItem.setRemoteId( QString::number( item.id() ) ); - newItem.setPayload( contactGroup ); - newItems << newItem; - } - if ( checkForErrors( item.id() ) && !newItems.isEmpty() ) { - newItems.removeLast(); //TODO: does this delete the item? - //rather set it to read-only (v2 never sets an error, - //so we should be safe for now). - } - } - - return newItems; -} - -bool AddressBookHandler::toKolabFormat( const Akonadi::Item &item, Akonadi::Item &imapItem ) -{ - if ( item.hasPayload() ) { - const KABC::Addressee &addressee = item.payload(); - - const KMime::Message::Ptr &message = - Kolab::KolabObjectWriter::writeContact( addressee, m_formatVersion, PRODUCT_ID ); - - if ( checkForErrors( item.id() ) ) { - return false; - } - imapItem.setMimeType( QLatin1String("message/rfc822") ); - imapItem.setPayload( message ); - } else if ( item.hasPayload() ) { - KABC::ContactGroup contactGroup = item.payload(); - - // Replace all references with real data-sets - // Hopefully all resources are available during saving, so we can look up - // in the addressbook to get name+email from the UID. - // TODO proxy should at least know the addressees it created - QList toAdd; - for ( uint index = 0; index < contactGroup.contactReferenceCount(); ++index ) { - const KABC::ContactGroup::ContactReference& reference = contactGroup.contactReference( index ); - - QString gid; - if (!reference.gid().isEmpty()) { - gid = reference.gid(); - } else { - const Akonadi::Item item( reference.uid().toLongLong() ); - Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( item ); - job->fetchScope().fetchFullPayload(); - if ( !job->exec() ) - continue; - - const Akonadi::Item::List items = job->items(); - if ( items.count() != 1 ) - continue; - - const KABC::Addressee addressee = job->items().first().payload(); - gid = addressee.uid(); - } - KABC::ContactGroup::ContactReference ref; - ref.setUid(gid); //libkolab expects a gid for uid() - toAdd << ref; - } - contactGroup.removeAllContactReferences(); - foreach ( const KABC::ContactGroup::ContactReference &ref, toAdd ) { - contactGroup.append( ref ); - } - - const KMime::Message::Ptr &message = - Kolab::KolabObjectWriter::writeDistlist( contactGroup, m_formatVersion, PRODUCT_ID ); - - if ( checkForErrors( item.id() ) ) { - return false; - } - imapItem.setMimeType( QLatin1String("message/rfc822") ); - imapItem.setPayload( message ); - } else { - kWarning() << "Payload is neither a KABC::Addressee nor KABC::ContactGroup!"; - return false; - } - return true; -} - -QStringList AddressBookHandler::contentMimeTypes() -{ - return QStringList() << KABC::Addressee::mimeType() - << KABC::ContactGroup::mimeType(); -} - -QString AddressBookHandler::iconName() const -{ - return QString::fromLatin1( "view-pim-contacts" ); -} - -QString AddressBookHandler::extractGid(const Akonadi::Item& kolabItem) -{ - if ( kolabItem.hasPayload() ) { - return kolabItem.payload().uid(); - } else if ( kolabItem.hasPayload() ) { - return kolabItem.payload().id(); - } - kWarning() << "invalid payload type!"; - return QString(); -} - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/addressbookhandler.h kdepim-runtime-15.08.0/resources/kolabproxy/addressbookhandler.h --- kdepim-runtime-4.14.6/resources/kolabproxy/addressbookhandler.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/addressbookhandler.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -/* - Copyright (c) 2009 Andras Mantia - Copyright (c) 2009 Kevin Krammer - Copyright (c) 2012 Christian Mollekopf - - 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 KOLABPROXY_ADDRESSBOOKHANDLER_H -#define KOLABPROXY_ADDRESSBOOKHANDLER_H - -#include "kolabhandler.h" - -/** - @author Andras Mantia -*/ -class AddressBookHandler : public KolabHandler -{ - public: - explicit AddressBookHandler( const Akonadi::Collection &imapCollection ); - - virtual ~AddressBookHandler(); - - virtual Akonadi::Item::List translateItems( const Akonadi::Item::List &addrs ); - virtual bool toKolabFormat( const Akonadi::Item &item, Akonadi::Item &imapItem ); - virtual QStringList contentMimeTypes(); - virtual QString iconName() const; - - virtual QString extractGid(const Akonadi::Item& kolabItem); -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/akonadi_kolabproxy_resource.notifyrc kdepim-runtime-15.08.0/resources/kolabproxy/akonadi_kolabproxy_resource.notifyrc --- kdepim-runtime-4.14.6/resources/kolabproxy/akonadi_kolabproxy_resource.notifyrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/akonadi_kolabproxy_resource.notifyrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -[Global] -IconName=kolab -Comment=Kolab Proxy Resource Notifications -Comment[bs]=Notifikacija Kolab Proxy resursa -Comment[ca]=Notificacions del recurs d'intermediari del Kolab -Comment[ca@valencia]=Notificacions del recurs d'intermediari del Kolab -Comment[da]=Bekendtgørelser fra Kolab-proxy-ressource -Comment[de]=Benachrichtigungen der Proxy-Ressource für Kolab -Comment[el]=Ειδοποιήσεις πόρου διαμεσολαβητή Kolab -Comment[en_GB]=Kolab Proxy Resource Notifications -Comment[es]=Notificaciones de recursos del proxy Kolab -Comment[et]=Kolabi puhverserveri ressursi märguanded -Comment[fi]=Kolab Proxy -resurssin ilmoitukset -Comment[fr]=Configuration des notifications Kolab -Comment[gl]=Notificacións do proxy de recurso de Kolab -Comment[hu]=Kolab proxy-erőforrás értesítések -Comment[ia]=Notificationes de ressource de proxy de Kolab -Comment[it]=Notifiche della risorsa proxy Kolab -Comment[ko]=Kolab 프록시 자원 알림 -Comment[lt]=Kolab įgaliotojo serverio resurso pranešimai -Comment[nb]=Kolab Proxy ressursvarslinger -Comment[nds]=Kolab-Proxy-Ressourcebescheden -Comment[nl]=Melding van Kolab-proxy-hulpbron -Comment[pl]=Powiadomienia zasobu pośrednika Kolab -Comment[pt]=Configuração dos Recursos de 'Proxy' do Kolab -Comment[pt_BR]=Notificação dos recursos de proxy do Kolab -Comment[ru]=Уведомления от источника данных Kolab -Comment[sk]=Upozornenia zdroja Kolab Proxy -Comment[sr]=Обавештења прокси ресурса Колаба -Comment[sr@ijekavian]=Обавештења прокси ресурса Колаба -Comment[sr@ijekavianlatin]=Obaveštenja proksi resursa Kolaba -Comment[sr@latin]=Obaveštenja proksi resursa Kolaba -Comment[sv]=Kolab-proxy resursunderrättelser -Comment[tr]=Kolab Vekil Sunucu Kaynak Bildirimleri -Comment[uk]=Сповіщення ресурсу проксі-сервера Kolab -Comment[x-test]=xxKolab Proxy Resource Notificationsxx -Comment[zh_TW]=Kolab Proxy 資源通知 -Name=Kolab Resource -Name[bs]=Kolab resurs -Name[ca]=Recurs de Kolab -Name[ca@valencia]=Recurs de Kolab -Name[cs]=Zdroj Kolab -Name[da]=Kolab-ressource -Name[de]=Kolab-Ressource -Name[el]=Πόρος Kolab -Name[en_GB]=Kolab Resource -Name[es]=Recurso de Kolab -Name[et]=Kolabi ressurss -Name[fi]=Kolab-resurssi -Name[fr]=Ressource Kolab -Name[gl]=Recurso do Kolab -Name[hu]=Kolab erőforrás -Name[ia]=Ressource de Kolab -Name[it]=Risorsa Kolab -Name[ko]=Kolab 자원 -Name[lt]=Kolab resursas -Name[nb]=Kolab-ressurs -Name[nds]=Kolab-Ressource -Name[nl]=Kolab-hulpbron -Name[pl]=Zasób Kolab -Name[pt]=Recurso do Kolab -Name[pt_BR]=Recurso do Kolab -Name[ru]=Источник данных Kolab -Name[sk]=Kolab zdroj -Name[sr]=Ресурс Колаба -Name[sr@ijekavian]=Ресурс Колаба -Name[sr@ijekavianlatin]=Resurs Kolaba -Name[sr@latin]=Resurs Kolaba -Name[sv]=Kolab-resurs -Name[tr]=Kolab Kaynağı -Name[uk]=Ресурс Kolab -Name[x-test]=xxKolab Resourcexx -Name[zh_TW]=Kolab 資源 - -[Event/Error] -Name=An error occurred -Name[bs]=Desila se greška -Name[ca]=S'ha produït un error -Name[ca@valencia]=S'ha produït un error -Name[cs]=Vyskytla se chyba -Name[da]=En fejl opstod -Name[de]=Es ist ein Fehler aufgetreten -Name[el]=Συνέβη ένα σφάλμα -Name[en_GB]=An error occurred -Name[es]=Ocurrió un error -Name[et]=Tekkis tõrge -Name[fi]=Tapahtui virhe -Name[fr]=Une erreur est survenue -Name[gl]=Produciuse un erro -Name[hu]=Hiba történt -Name[ia]=Un error occurreva -Name[it]=Si è verificato un errore -Name[ko]=오류가 발생함 -Name[lt]=Įvyko klaida -Name[nb]=Det oppsto en feil -Name[nds]=Dat geev en Fehler -Name[nl]=Er deed zich een fout voor -Name[pl]=Wystąpił błąd -Name[pt]=Ocorreu um erro -Name[pt_BR]=Ocorreu um erro -Name[ru]=Произошла ошибка -Name[sk]=Vyskytla sa chyba -Name[sr]=Дошло је до грешке -Name[sr@ijekavian]=Дошло је до грешке -Name[sr@ijekavianlatin]=Došlo je do greške -Name[sr@latin]=Došlo je do greške -Name[sv]=Ett fel uppstod -Name[tr]=Bir hata oluştu -Name[uk]=Сталася помилка -Name[x-test]=xxAn error occurredxx -Name[zh_TW]=發生錯誤 -Action=Popup diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/calendarhandler.cpp kdepim-runtime-15.08.0/resources/kolabproxy/calendarhandler.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/calendarhandler.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/calendarhandler.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -/* - Copyright (c) 2009 Andras Mantia - Copyright (c) 2012 Christian Mollekopf - - 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 "calendarhandler.h" - -CalendarHandler::CalendarHandler( const Akonadi::Collection &imapCollection ) - : IncidenceHandler( imapCollection ) -{ - m_mimeType = "application/x-vnd.kolab.event"; -} - -CalendarHandler::~CalendarHandler() -{ -} - -KMime::Message::Ptr CalendarHandler::incidenceToMime( const KCalCore::Incidence::Ptr &incidence ) -{ - return - Kolab::KolabObjectWriter::writeEvent( - incidence.dynamicCast(), - m_formatVersion, PRODUCT_ID, QLatin1String("UTC") ); -} - -QStringList CalendarHandler::contentMimeTypes() -{ - return QStringList() << KCalCore::Event::eventMimeType(); -} - -QString CalendarHandler::iconName() const -{ - return QString::fromLatin1( "view-calendar" ); -} diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/calendarhandler.h kdepim-runtime-15.08.0/resources/kolabproxy/calendarhandler.h --- kdepim-runtime-4.14.6/resources/kolabproxy/calendarhandler.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/calendarhandler.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -/* - Copyright (c) 2009 Andras Mantia - Copyright (c) 2012 Christian Mollekopf - - 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 KOLABPROXY_CALENDARHANDLER_H -#define KOLABPROXY_CALENDARHANDLER_H - -#include "incidencehandler.h" - -/** - @author Andras Mantia -*/ -class CalendarHandler : public IncidenceHandler -{ - Q_OBJECT - public: - explicit CalendarHandler( const Akonadi::Collection &imapCollection ); - virtual ~CalendarHandler(); - virtual QStringList contentMimeTypes(); - virtual QString iconName() const; - - private: - virtual KMime::Message::Ptr incidenceToMime( const KCalCore::Incidence::Ptr &incidence ); - -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/changeformat.ui kdepim-runtime-15.08.0/resources/kolabproxy/changeformat.ui --- kdepim-runtime-4.14.6/resources/kolabproxy/changeformat.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/changeformat.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,133 +0,0 @@ - - - ChangeFormatView - - - - 0 - 0 - 515 - 327 - - - - - QLayout::SetMinimumSize - - - QFormLayout::ExpandingFieldsGrow - - - - - Please select the format which should be used to write new Kolab objects according to your Kolab Groupware Server's version. You may close this window after selecting your version. - - - true - - - - - - - Kolab Format Version: - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 40 - - - - - - - - false - - - Change Format Version - - - false - - - - QFormLayout::ExpandingFieldsGrow - - - - - This allows you to upgrade your Kolab account to a different format version. This is normally not required and you should contact your administrator before doing so. - - - true - - - - - - - Status: - - - - - - - Not Started - - - - - - - 0 - - - - - - - Attention: Changing the format version will rewrite all Kolab objects. Make sure you have a backup of your data, and the account is fully synchronized and connected to the server. - - - true - - - - - - - Change Format Version - - - - - - - - - - - KComboBox - QComboBox -
kcombobox.h
-
-
- - -
diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/CMakeLists.txt kdepim-runtime-15.08.0/resources/kolabproxy/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/kolabproxy/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -project(kolabproxy) - -include_directories( - ${kdepim-runtime_SOURCE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} - ${Boost_INCLUDE_DIR} - ${Libkolab_INCLUDES} - ${Libkolabxml_INCLUDES} -) - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS} -fPIC") - -########### next target ############### - -set(kolabproxyresource_shared_SRCS - kolabhandler.cpp - addressbookhandler.cpp - incidencehandler.cpp - calendarhandler.cpp - freebusyupdatehandler.cpp - taskshandler.cpp - journalhandler.cpp - notehandler.cpp - setupdefaultfoldersjob.cpp - kolabdefs.cpp - upgradejob.cpp - imapitemaddedjob.cpp - imapitemremovedjob.cpp - itemaddedjob.cpp - itemchangedjob.cpp - handlermanager.cpp - revertitemchangesjob.cpp -) - -set(kolabproxyresource_SRCS - kolabproxyresource.cpp - collectiontreebuilder.cpp - setupkolab.cpp - ${kolabproxyresource_shared_SRCS} - ${AKONADI_COLLECTIONATTRIBUTES_SHARED_SOURCES} -) - -qt4_add_dbus_adaptor(kolabproxyresource_SRCS org.freedesktop.Akonadi.kolabproxy.xml kolabproxyresource.h KolabProxyResource) - -install(FILES kolabproxyresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents") - -kde4_add_kcfg_files(kolabproxyresource_SRCS settings.kcfgc) - -kde4_add_ui_files(kolabproxyresource_SRCS kolabsettings.ui changeformat.ui) - -kcfg_generate_dbus_interface( - ${CMAKE_CURRENT_SOURCE_DIR}/kolabproxyresource.kcfg - org.kde.Akonadi.kolabproxy.Settings -) - -qt4_add_dbus_adaptor(kolabproxyresource_SRCS - ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.kolabproxy.Settings.xml - settings.h Settings -) - -if(RUNTIME_PLUGINS_STATIC) - add_definitions(-DRUNTIME_PLUGINS_STATIC) -endif() - -kde4_add_executable(akonadi_kolabproxy_resource ${kolabproxyresource_SRCS}) -install(FILES akonadi_kolabproxy_resource.notifyrc DESTINATION "${DATA_INSTALL_DIR}/akonadi_kolabproxy_resource" ) - -if(Q_WS_MAC) - set_target_properties(akonadi_kolabproxy_resource PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template - ) - set_target_properties(akonadi_kolabproxy_resource PROPERTIES - MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.kolabproxy" - ) - set_target_properties(akonadi_kolabproxy_resource PROPERTIES - MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi Kolabproxy Resource" - ) -endif() - -target_link_libraries(akonadi_kolabproxy_resource - kdepim-copy - ${KDEPIMLIBS_AKONADI_KMIME_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KABC_LIBS} - ${KDEPIMLIBS_KCALCORE_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${KDE4_KIO_LIBS} - ${QT_QTDBUS_LIBRARY} - ${QT_QTXML_LIBRARY} - ${Libkolab_LIBRARIES} - ${Libkolabxml_LIBRARIES} -) - -if(RUNTIME_PLUGINS_STATIC) - target_link_libraries(akonadi_kolabproxy_resource - akonadi_serializer_addressee - akonadi_serializer_contactgroup - akonadi_serializer_kcalcore - akonadi_serializer_mail - ) -endif() - -install(TARGETS akonadi_kolabproxy_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) - -kde4_install_icons(${ICON_INSTALL_DIR}) - -add_subdirectory(tests) -add_subdirectory(wizard) diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/collectiontreebuilder.cpp kdepim-runtime-15.08.0/resources/kolabproxy/collectiontreebuilder.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/collectiontreebuilder.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/collectiontreebuilder.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "collectiontreebuilder.h" - -#include - -CollectionTreeBuilder::CollectionTreeBuilder( KolabProxyResource *parent ) - : Job( parent ), - m_resource( parent ) -{ -} - -void CollectionTreeBuilder::doStart() -{ - Akonadi::CollectionFetchJob *job = - new Akonadi::CollectionFetchJob( Akonadi::Collection::root(), - Akonadi::CollectionFetchJob::Recursive, this ); - - connect( job, SIGNAL(collectionsReceived(Akonadi::Collection::List)), - SLOT(collectionsReceived(Akonadi::Collection::List)) ); - - connect( job, SIGNAL(result(KJob*)), SLOT(collectionFetchResult(KJob*)) ); -} - -void CollectionTreeBuilder::collectionsReceived( const Akonadi::Collection::List &collections ) -{ - foreach ( const Akonadi::Collection &collection, collections ) { - if ( collection.resource() == resource()->identifier() || collection.resource().startsWith("akonadi_kolab_resource") ) { - continue; - } - resource()->updateHiddenAttribute( collection ); - if ( resource()->registerHandlerForCollection( collection ) ) { - m_kolabCollections.append( collection ); - } - m_allCollections.insert( collection.id(), collection ); - } -} - -Akonadi::Collection::List CollectionTreeBuilder::allCollections() const -{ - return m_resultCollections; -} - -Akonadi::Collection::List CollectionTreeBuilder::treeToList( - const QHash< Akonadi::Entity::Id, Akonadi::Collection::List > &tree, - const Akonadi::Collection ¤t ) -{ - Akonadi::Collection::List rv; - foreach ( const Akonadi::Collection &child, tree.value( current.id() ) ) { - rv += child; - rv += treeToList( tree, child ); - } - return rv; -} - -void CollectionTreeBuilder::collectionFetchResult( KJob *job ) -{ - Q_UNUSED( job ); - m_resultCollections.clear(); - - // step 1: build the minimal sub-tree that contains all Kolab collections - QHash remainingTree; - foreach ( const Akonadi::Collection &kolabCollection, m_kolabCollections ) { - Akonadi::Collection child = kolabCollection; - Akonadi::Collection::Id parentId = child.parentCollection().id(); - while ( child.isValid() && !remainingTree.value( parentId ).contains( child ) ) { - remainingTree[ parentId ].append( child ); - child = m_allCollections.value( parentId ); - parentId = child.parentCollection().id(); - } - } - - // step 2: path contraction - // TODO - - // step 3: flatten the tree and adjust root node - Akonadi::Collection::List collections = remainingTree.value( Akonadi::Collection::root().id() ); - foreach ( Akonadi::Collection topLevel, collections ) { //krazy:exclude=foreach - topLevel.setParentCollection( Akonadi::Collection::root() ); - m_resultCollections.append( topLevel ); - m_resultCollections += treeToList( remainingTree, topLevel ); - } - - emitResult(); // error handling already done by Akonadi::Job -} - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/collectiontreebuilder.h kdepim-runtime-15.08.0/resources/kolabproxy/collectiontreebuilder.h --- kdepim-runtime-4.14.6/resources/kolabproxy/collectiontreebuilder.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/collectiontreebuilder.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 KOLABPROXY_COLLECTIONTREEBUILDER_H -#define KOLABPROXY_COLLECTIONTREEBUILDER_H - -#include "kolabproxyresource.h" - -#include - -class CollectionTreeBuilder : public Akonadi::Job -{ - Q_OBJECT - public: - explicit CollectionTreeBuilder( KolabProxyResource *parent = 0 ); - - Akonadi::Collection::List allCollections() const; - - protected: - virtual void doStart(); - - private: - inline KolabProxyResource *resource() const - { - return m_resource; - } - - static Akonadi::Collection::List treeToList( const QHash &tree, - const Akonadi::Collection ¤t ); - - private slots: - void collectionsReceived( const Akonadi::Collection::List &collections ); - void collectionFetchResult( KJob *job ); - - private: - KolabProxyResource *m_resource; - Akonadi::Collection::List m_resultCollections; - Akonadi::Collection::List m_kolabCollections; - QHash m_allCollections; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/freebusyupdatehandler.cpp kdepim-runtime-15.08.0/resources/kolabproxy/freebusyupdatehandler.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/freebusyupdatehandler.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/freebusyupdatehandler.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -/* - Copyright (c) 2011 Tobias Koenig - - 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 "freebusyupdatehandler.h" - -#include -#include -#include -#include - -#include - -FreeBusyUpdateHandler::FreeBusyUpdateHandler( QObject *parent ) - : QObject( parent ), mTimer( new QTimer( this ) ) -{ - mTimer->setInterval( 2000 ); - connect( mTimer, SIGNAL(timeout()), SLOT(timeout()) ); -} - -FreeBusyUpdateHandler::~FreeBusyUpdateHandler() -{ - mTimer->stop(); -} - -void FreeBusyUpdateHandler::updateFolder( const QString &folderPath, const QString &userName, - const QString &password, const QString &host ) -{ - QString path( folderPath ); - - /* Steffen said: you must issue an authenticated HTTP GET request to - https://kolabserver/freebusy/trigger/user@domain/Folder/NestedFolder.pfb - (replace .pfb with .xpfb for extended fb lists). */ - - KUrl httpUrl; - httpUrl.setUser( userName ); - httpUrl.setPassword( password ); - httpUrl.setHost( host ); - httpUrl.setProtocol( QLatin1String( "https" ) ); - - // IMAP path is either /INBOX/ or /user/someone/ - //FIXME this assumption is no longer true. Kolabfolders can also be toplevel. - if ( !path.startsWith( QLatin1Char('/') ) ) { - //The path separator can i.e. also be '.' on a different imap server - kWarning() << "Unsupported path separator"; - return; - } - const int secondSlash = path.indexOf( QLatin1Char('/'), 1 ); - if ( secondSlash == -1 ) { - kWarning() << "path is too short: " << path; - return; - } - - if ( path.startsWith( QLatin1String( "/INBOX/" ), Qt::CaseInsensitive ) ) { - // If INBOX, replace it with the username (which is user@domain) - path = path.mid( secondSlash ); - path.prepend( userName ); - } else { - // If user, just remove it. So we keep the IMAP-returned username. - // This assumes it's a known user on the same domain. - path = path.mid( secondSlash ); - } - - if ( path.startsWith( QLatin1Char('/') ) ) { - httpUrl.setPath( QLatin1String("/freebusy/trigger") + path + QLatin1String(".pfb") ); - } else { - httpUrl.setPath( QLatin1String("/freebusy/trigger/") + path + QLatin1String(".pfb") ); - } - - mUrls.insert( httpUrl ); - mTimer->start(); -} - -void FreeBusyUpdateHandler::timeout() -{ - foreach ( const KUrl &url, mUrls ) { - kDebug() << "Triggering PFB update for " << url; - - KIO::Job *job = KIO::get( url, KIO::NoReload, KIO::HideProgressInfo ); - // we want an error in case of 404 - job->addMetaData( QLatin1String( "errorPage" ), QLatin1String( "false" ) ); - connect( job, SIGNAL(result(KJob*)), SLOT(slotFreeBusyTriggerResult(KJob*)) ); - } - - mUrls.clear(); -} - -void FreeBusyUpdateHandler::slotFreeBusyTriggerResult( KJob *job ) -{ - if ( job->error() ) { - KUrl url( job->errorText() ); - KPassivePopup::message( - i18n( "Could not trigger Free/Busy information update: %1.", url.prettyUrl() ), - (QWidget*)0 ); - } -} - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/freebusyupdatehandler.h kdepim-runtime-15.08.0/resources/kolabproxy/freebusyupdatehandler.h --- kdepim-runtime-4.14.6/resources/kolabproxy/freebusyupdatehandler.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/freebusyupdatehandler.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -/* - Copyright (c) 2011 Tobias Koenig - - 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 KOLABPROXY_FREEBUSYUPDATEHANDLER_H -#define KOLABPROXY_FREEBUSYUPDATEHANDLER_H - -#include -#include - -class KJob; -class KUrl; - -class QTimer; - -/** - * A class that triggers the update of freebusy lists on the Kolab server - * whenever a calendar IMAP folder has been changed. - */ -class FreeBusyUpdateHandler : public QObject -{ - Q_OBJECT - - public: - explicit FreeBusyUpdateHandler( QObject *parent = 0 ); - ~FreeBusyUpdateHandler(); - - void updateFolder( const QString &path, const QString &userName, - const QString &password, const QString &host ); - - private Q_SLOTS: - void timeout(); - void slotFreeBusyTriggerResult( KJob * ); - - private: - QSet mUrls; - QTimer *mTimer; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/handlermanager.cpp kdepim-runtime-15.08.0/resources/kolabproxy/handlermanager.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/handlermanager.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/handlermanager.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 "handlermanager.h" -#include - -Kolab::FolderType HandlerManager::getFolderType( const Akonadi::Collection& collection ) -{ - if (Akonadi::CollectionAnnotationsAttribute *attr = collection.attribute() ) { - return Kolab::folderTypeFromString( Kolab::getFolderTypeAnnotation(attr->annotations())); - } - return Kolab::MailType; -} - -bool HandlerManager::isKolabFolder(const Akonadi::Collection &collection) -{ - return (getFolderType(collection) != Kolab::MailType); -} - -bool HandlerManager::isHandledKolabFolder(const Akonadi::Collection& collection) -{ - return KolabHandler::hasHandler(getFolderType(collection)); -} - -KolabHandler::Ptr HandlerManager::getHandler(Akonadi::Entity::Id collectionId) -{ - return mMonitoredCollections.value(collectionId); -} - -QString HandlerManager::imapResourceForCollection( Akonadi::Collection::Id id ) -{ - return mResourceIdentifiers.value(id); -} - -bool HandlerManager::registerHandlerForCollection( const Akonadi::Collection &imapCollection, Kolab::Version version ) -{ - if (isHandledKolabFolder(imapCollection)) { - KolabHandler::Ptr handler = - KolabHandler::createHandler(getFolderType(imapCollection), imapCollection); - if (handler) { - handler->setKolabFormatVersion(version); - mMonitoredCollections.insert(imapCollection.id(), handler); - mResourceIdentifiers.insert(imapCollection.id(), imapCollection.resource()); - return true; - } - } - return false; -} - -void HandlerManager::removeFolder(Akonadi::Entity::Id imapCollection) -{ - mMonitoredCollections.remove(imapCollection); -} - -bool HandlerManager::isMonitored(Akonadi::Entity::Id imapCollection) const -{ - return mMonitoredCollections.contains(imapCollection); -} - -QList< Akonadi::Entity::Id > HandlerManager::monitoredCollections() const -{ - return mMonitoredCollections.keys(); -} - -void HandlerManager::clear() -{ - mMonitoredCollections.clear(); -} diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/handlermanager.h kdepim-runtime-15.08.0/resources/kolabproxy/handlermanager.h --- kdepim-runtime-4.14.6/resources/kolabproxy/handlermanager.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/handlermanager.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 HANDLERMANAGER_H -#define HANDLERMANAGER_H - -#include -#include -#include "kolabhandler.h" - -class HandlerManager -{ -public: - bool isMonitored(Akonadi::Collection::Id) const; - KolabHandler::Ptr getHandler(Akonadi::Collection::Id); - - /** - * Creates a new KolabHandler for @p imapCollection given it actually is - * a Kolab folder. - * - * @return @c true if @p imapCollection is a Kolab folder, @c false otherwise. - */ - bool registerHandlerForCollection(const Akonadi::Collection &imapCollection, Kolab::Version version); - - QString imapResourceForCollection(Akonadi::Collection::Id id); - - void removeFolder(Akonadi::Collection::Id imapCollection); - - QList monitoredCollections() const; - - void clear(); - - static bool isKolabFolder( const Akonadi::Collection &collection ); - static bool isHandledKolabFolder( const Akonadi::Collection &collection ); - static Kolab::FolderType getFolderType( const Akonadi::Collection &collection ); -private: - QMap mMonitoredCollections; - QMap mResourceIdentifiers; - -}; - -#endif \ No newline at end of file Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/kolabproxy/hi64-apps-kolab.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/kolabproxy/hi64-apps-kolab.png differ diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/imapitemaddedjob.cpp kdepim-runtime-15.08.0/resources/kolabproxy/imapitemaddedjob.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/imapitemaddedjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/imapitemaddedjob.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,130 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 "imapitemaddedjob.h" -#include -#include -#include -#include -#include - -ImapItemAddedJob::ImapItemAddedJob(const Akonadi::Item &imapItem, const Akonadi::Collection &imapCollection, KolabHandler &handler, QObject* parent) - :KJob(parent), - mHandler(handler), - mImapItem(imapItem), - mKolabCollection(imapToKolab(imapCollection)), - mImapCollection(imapCollection) -{ - -} - -void ImapItemAddedJob::start() -{ - //TODO: slow, would be nice if ItemCreateJob would work with a Collection - // having only the remoteId set - Akonadi::CollectionFetchJob *job = - new Akonadi::CollectionFetchJob(mKolabCollection, Akonadi::CollectionFetchJob::Base, this ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(onCollectionFetchDone(KJob*)) ); -} - -void ImapItemAddedJob::onCollectionFetchDone( KJob *job ) -{ - if ( job->error() ) { - kWarning( ) << "Error on collection fetch:" << job->errorText(); - return; - } - Akonadi::Collection::List collections = - qobject_cast(job)->collections(); - Q_ASSERT(collections.size() == 1); - mKolabCollection = collections.first(); - - const Akonadi::Item::List newItems = mHandler.translateItems(Akonadi::Item::List() << mImapItem); - if (newItems.isEmpty()) { - setError(KJob::UserDefinedError); - setErrorText("Failed to translate item"); - emitResult(); - return; - } - mTranslatedItem = newItems.first(); - - const QString &gid = mHandler.extractGid(mTranslatedItem); - if (!gid.isEmpty()) { - //We have a gid, let's see if this item already exists - Akonadi::Item item; - item.setGid(gid); - Akonadi::ItemFetchJob *itemFetchJob = new Akonadi::ItemFetchJob(item); - itemFetchJob->fetchScope().fetchFullPayload(false); - itemFetchJob->fetchScope().setFetchModificationTime(false); - itemFetchJob->fetchScope().setAncestorRetrieval(Akonadi::ItemFetchScope::Parent); - connect(itemFetchJob, SIGNAL(result(KJob*)), this, SLOT(onItemFetchJobDone(KJob*))); - } else { - kDebug() << "no gid, creating directly"; - Akonadi::ItemCreateJob *cjob = new Akonadi::ItemCreateJob(mTranslatedItem, mKolabCollection); - connect( cjob, SIGNAL(result(KJob*)), this, SLOT(itemCreatedDone(KJob*)) ); - } - } - - Akonadi::Item ImapItemAddedJob::getTranslatedItem() - { - return Akonadi::Item(); - } - - void ImapItemAddedJob::onItemFetchJobDone(KJob *job) - { - Akonadi::ItemFetchJob * const fetchJob = static_cast(job); - - Akonadi::Item::List conflictingItems; - foreach (const Akonadi::Item &item, fetchJob->items()) { - Q_ASSERT(item.parentCollection().isValid()); - //The same object may be in other collection, just not in this one. - if (item.parentCollection().id() != mKolabCollection.id()) { - continue; - } - conflictingItems << item; - } - if (conflictingItems.size() > 1) { - kWarning() << "Multiple conflicting items detected in col " << mKolabCollection.id() << ", this should never happen: "; - foreach (const Akonadi::Item &item, conflictingItems) { - kWarning() << "Conflicting kolab item: " << item.id(); - } - } - if (!conflictingItems.isEmpty()) { - //This is a conflict - const Akonadi::Item conflictingKolabItem = conflictingItems.first(); - mTranslatedItem.setId(conflictingKolabItem.id()); - imapToKolab(mImapItem, mTranslatedItem); - //TODO ensure the modifyjob doesn't collide with a removejob due to the original imap item vanishing. - kDebug() << "conflict, modifying existing item: " << conflictingKolabItem.id(); - Akonadi::ItemModifyJob *modJob = new Akonadi::ItemModifyJob(mTranslatedItem, this); - modJob->disableRevisionCheck(); - connect(modJob, SIGNAL(result(KJob*)), this, SLOT(itemCreatedDone(KJob*))); - } else { - kDebug() << "creating new item"; - Akonadi::ItemCreateJob *cjob = new Akonadi::ItemCreateJob(mTranslatedItem, mKolabCollection, this); - connect(cjob, SIGNAL(result(KJob*)), this, SLOT(itemCreatedDone(KJob*))); - } -} - -void ImapItemAddedJob::itemCreatedDone(KJob *job) -{ - if (job->error()) { - kWarning() << "Error on creating item:" << job->errorText(); - kWarning() << "imap item: " << mImapItem.id() << " in collection " << mImapCollection.id(); - } - emitResult(); -} diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/imapitemaddedjob.h kdepim-runtime-15.08.0/resources/kolabproxy/imapitemaddedjob.h --- kdepim-runtime-4.14.6/resources/kolabproxy/imapitemaddedjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/imapitemaddedjob.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 IMAPITEMADDEDJOB_H -#define IMAPITEMADDEDJOB_H -#include -#include "kolabhandler.h" - -class ImapItemAddedJob: public KJob -{ - Q_OBJECT -public: - ImapItemAddedJob(const Akonadi::Item &imapItem, const Akonadi::Collection &imapCollection, KolabHandler &handler, QObject* parent); - virtual void start(); -private slots: - void onItemFetchJobDone(KJob *job); - void onCollectionFetchDone(KJob *job); - void itemCreatedDone(KJob *job); -private: - Akonadi::Item getTranslatedItem(); - KolabHandler &mHandler; - Akonadi::Item mImapItem; - Akonadi::Item mTranslatedItem; - Akonadi::Collection mKolabCollection; - const Akonadi::Collection mImapCollection; - -}; - -#endif \ No newline at end of file diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/imapitemremovedjob.cpp kdepim-runtime-15.08.0/resources/kolabproxy/imapitemremovedjob.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/imapitemremovedjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/imapitemremovedjob.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 "imapitemremovedjob.h" -#include -#include -#include -#include -#include -#include - -ImapItemRemovedJob::ImapItemRemovedJob(const Akonadi::Item& imapItem, QObject* parent) - :KJob(parent), - mImapItem(imapItem), - mKolabItem(imapToKolab(imapItem)) -{ - -} - -void ImapItemRemovedJob::start() -{ - Akonadi::ItemFetchJob *fetchJob = new Akonadi::ItemFetchJob(mKolabItem, this); - fetchJob->fetchScope().setFetchRemoteIdentification(true); - fetchJob->fetchScope().setCacheOnly(true); //don't access the imap backend again - connect(fetchJob, SIGNAL(result(KJob*)), this, SLOT(onItemFetchJobDone(KJob*))); -} - -void ImapItemRemovedJob::onItemFetchJobDone(KJob* job) -{ - //This fetch job can fail if the kolab item has already been removed, so we ignore errors - Akonadi::ItemFetchJob *fetchJob = static_cast(job); - Q_ASSERT(fetchJob->items().size() <= 1); - if (fetchJob->items().isEmpty()) { - emitResult(); - return; - } - const Akonadi::Item kolabItem = fetchJob->items().first(); - //Check if the currently relevant imap item was removed or just an outdated copy - if (kolabItem.remoteId().toLongLong() == mImapItem.id()) { - Akonadi::ItemDeleteJob *deleteJob = new Akonadi::ItemDeleteJob(kolabItem, this ); - connect(deleteJob, SIGNAL(result(KJob*)), this, SLOT(onDeleteDone(KJob*))); - } else { - emitResult(); - } -} - -void ImapItemRemovedJob::onDeleteDone(KJob* job) -{ - if (job->error()) { - kWarning() << "Delete job failed" << job->errorString(); - } - emitResult(); -} - - - - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/imapitemremovedjob.h kdepim-runtime-15.08.0/resources/kolabproxy/imapitemremovedjob.h --- kdepim-runtime-4.14.6/resources/kolabproxy/imapitemremovedjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/imapitemremovedjob.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ - -/* - Copyright (c) 2013 Christian Mollekopf - - 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 IMAPITEMREMOVEDJOB_H -#define IMAPITEMREMOVEDJOB_H -#include -#include "kolabhandler.h" - -class ImapItemRemovedJob: public KJob -{ - Q_OBJECT -public: - ImapItemRemovedJob(const Akonadi::Item &imapItem, QObject* parent); - virtual void start(); -private slots: - void onItemFetchJobDone(KJob *job); - void onDeleteDone(KJob *job); -private: - const Akonadi::Item mImapItem; - const Akonadi::Item mKolabItem; -}; - -#endif \ No newline at end of file diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/incidencehandler.cpp kdepim-runtime-15.08.0/resources/kolabproxy/incidencehandler.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/incidencehandler.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/incidencehandler.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -/* - Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Copyright (c) 2009 Andras Mantia - Copyright (c) 2012 Christian Mollekopf - - 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 "incidencehandler.h" - -#include -#include - -#include - -#include - -IncidenceHandler::IncidenceHandler( const Akonadi::Collection &imapCollection ) - : KolabHandler( imapCollection ) -{ -} - -IncidenceHandler::~IncidenceHandler() -{ -} - -Akonadi::Item::List IncidenceHandler::translateItems( const Akonadi::Item::List &items ) -{ - Akonadi::Item::List newItems; - Q_FOREACH ( const Akonadi::Item &item, items ) { - if ( !item.hasPayload() ) { - kWarning() << "Payload is not a MessagePtr!"; - continue; - } - const KMime::Message::Ptr payload = item.payload(); - - KCalCore::Incidence::Ptr incidencePtr = Kolab::KolabObjectReader(payload).getIncidence(); - if ( checkForErrors( item.id() ) ) { - continue; - } - if ( !incidencePtr ) { - kWarning() << "Failed to read incidence."; - continue; - } - Akonadi::Item newItem( incidencePtr->mimeType() ); - newItem.setPayload( incidencePtr ); - newItem.setRemoteId( QString::number( item.id() ) ); - newItems << newItem; - } - - return newItems; -} - -bool IncidenceHandler::toKolabFormat( const Akonadi::Item &item, Akonadi::Item &imapItem ) -{ - if ( !item.hasPayload() ) { - kWarning() << "item is not an incidence"; - return false; - } - KCalCore::Incidence::Ptr incidencePtr = item.payload(); - if ( !incidencePtr ) { - kWarning() << "invalid incidence"; - return false; - } - - const KMime::Message::Ptr &message = incidenceToMime( incidencePtr ); - imapItem.setMimeType( QLatin1String("message/rfc822") ); - imapItem.setPayload( message ); - - if ( checkForErrors( item.id() ) ) { - return false; - } - return true; -} - -QString IncidenceHandler::extractGid(const Akonadi::Item& kolabItem) -{ - if ( !kolabItem.hasPayload() ) { - kWarning() << "Invalid payload!"; - return QString(); - } - return kolabItem.payload()->instanceIdentifier(); -} - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/incidencehandler.h kdepim-runtime-15.08.0/resources/kolabproxy/incidencehandler.h --- kdepim-runtime-4.14.6/resources/kolabproxy/incidencehandler.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/incidencehandler.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -/* - Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Copyright (c) 2009 Andras Mantia - Copyright (c) 2012 Christian Mollekopf - - 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 KOLABPROXY_INCIDENCEHANDLER_H -#define KOLABPROXY_INCIDENCEHANDLER_H - -#include "kolabhandler.h" - -#include - -/** - @author Andras Mantia -*/ -class IncidenceHandler : public KolabHandler -{ - Q_OBJECT - public: - explicit IncidenceHandler( const Akonadi::Collection &imapCollection ); - - virtual ~IncidenceHandler(); - - virtual Akonadi::Item::List translateItems( const Akonadi::Item::List &addrs ); - virtual bool toKolabFormat( const Akonadi::Item &item, Akonadi::Item &imapItem ); - - virtual QString extractGid(const Akonadi::Item& imapItem); - - protected: - virtual KMime::Message::Ptr incidenceToMime( const KCalCore::Incidence::Ptr &incidence ) = 0; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/itemaddedjob.cpp kdepim-runtime-15.08.0/resources/kolabproxy/itemaddedjob.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/itemaddedjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/itemaddedjob.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 "itemaddedjob.h" -#include -#include -#include - -ItemAddedJob::ItemAddedJob(const Akonadi::Item& kolabItem, const Akonadi::Collection& col, KolabHandler& handler, QObject* parent) - :KJob(parent), - mHandler(handler), - mKolabItem(kolabItem), - mParentCollection(col) -{ - -} - -void ItemAddedJob::start() -{ - QMetaObject::invokeMethod(this, "doStart", Qt::QueuedConnection); -} - -void ItemAddedJob::doStart() -{ - const Akonadi::Collection imapCollection = kolabToImap(mParentCollection); - kDebug() << imapCollection.id(); - Akonadi::Item imapItem( "message/rfc822" ); - if (!mHandler.toKolabFormat(mKolabItem, imapItem)) { - kWarning() << "Failed to convert item to kolab format: " << mKolabItem.id(); - setError(KJob::UserDefinedError); - setErrorText(i18n("Failed to convert item %1 to kolab format", mKolabItem.id())); - emitResult(); - return; - } - //FIXME remove - imapItem.setFlag(Akonadi::MessageFlags::Seen); - - Akonadi::ItemCreateJob *cjob = new Akonadi::ItemCreateJob(imapItem, imapCollection); - connect(cjob, SIGNAL(result(KJob*)), SLOT(onItemCreatedDone(KJob*))); -} - -void ItemAddedJob::onItemCreatedDone(KJob* job) -{ - if (job->error()) { - setError(KJob::UserDefinedError); - } else { - Akonadi::ItemCreateJob *cjob = static_cast(job); - mImapItem = cjob->item(); - } - emitResult(); -} - -Akonadi::Item ItemAddedJob::kolabItem() const -{ - return mKolabItem; -} - -Akonadi::Item ItemAddedJob::imapItem() const -{ - return mImapItem; -} diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/itemaddedjob.h kdepim-runtime-15.08.0/resources/kolabproxy/itemaddedjob.h --- kdepim-runtime-4.14.6/resources/kolabproxy/itemaddedjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/itemaddedjob.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 ITEMADDEDJOB_H -#define ITEMADDEDJOB_H -#include -#include "kolabhandler.h" - -class ItemAddedJob: public KJob -{ - Q_OBJECT -public: - ItemAddedJob(const Akonadi::Item &kolabItem, const Akonadi::Collection &col, KolabHandler &handler, QObject* parent); - virtual void start(); - Akonadi::Item kolabItem() const; - Akonadi::Item imapItem() const; -private slots: - void doStart(); - void onItemCreatedDone(KJob *job); -private: - KolabHandler &mHandler; - const Akonadi::Item mKolabItem; - Akonadi::Item mImapItem; - const Akonadi::Collection mParentCollection; -}; - -#endif \ No newline at end of file diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/itemchangedjob.cpp kdepim-runtime-15.08.0/resources/kolabproxy/itemchangedjob.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/itemchangedjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/itemchangedjob.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,136 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 "itemchangedjob.h" -#include "itemaddedjob.h" -#include -#include -#include -#include - -ItemChangedJob::ItemChangedJob(const Akonadi::Item& kolabItem, HandlerManager& handler, QObject* parent) -: KJob(parent), - mHandlerManager(handler), - mKolabItem(kolabItem) -{ - -} - -void ItemChangedJob::start() -{ - Akonadi::CollectionFetchJob *collectionFetchJob = new Akonadi::CollectionFetchJob(Akonadi::Collection(mKolabItem.storageCollectionId()), Akonadi::CollectionFetchJob::Base); - connect(collectionFetchJob, SIGNAL(result(KJob*)), this, SLOT(onKolabCollectionFetched(KJob*))); -} - -void ItemChangedJob::onKolabCollectionFetched(KJob* job) -{ - Akonadi::CollectionFetchJob *fetchjob = static_cast(job); - if (job->error() || fetchjob->collections().isEmpty()) { - kWarning() << "collection fetch job failed " << job->errorString() << fetchjob->collections().isEmpty(); - setError(KJob::UserDefinedError); - setErrorText(job->errorText()); - emitResult(); - return; - } - const Akonadi::Collection imapCollection = kolabToImap(fetchjob->collections().first()); - mHandler = mHandlerManager.getHandler(imapCollection.id()); - if (!mHandler) { - kWarning() << "Couldn't find a handler for the collection, but we should have one: " << imapCollection.id(); - setError(KJob::UserDefinedError); - setErrorText(job->errorText()); - emitResult(); - return; - } - - Akonadi::ItemFetchJob *itemFetchJob = new Akonadi::ItemFetchJob(kolabToImap(mKolabItem), this); - connect(itemFetchJob, SIGNAL(result(KJob*)), SLOT(onImapItemFetchDone(KJob*))); -} - -void ItemChangedJob::onImapItemFetchDone(KJob* job) -{ - if ( job->error() ) { - kWarning() << job->error() << job->errorString(); - setError(KJob::UserDefinedError); - setErrorText(job->errorText()); - emitResult(); - return; - } - - Akonadi::ItemFetchJob *fetchJob = qobject_cast(job); - if (fetchJob->items().isEmpty()) { //The corresponding imap item hasn't been created yet - kDebug() << "item is not yet created in imap resource"; - Akonadi::CollectionFetchJob *fetch = - new Akonadi::CollectionFetchJob( Akonadi::Collection( mKolabItem.storageCollectionId() ), - Akonadi::CollectionFetchJob::Base, this ); - connect( fetch, SIGNAL(result(KJob*)), SLOT(onCollectionFetchDone(KJob*)) ); - } else { - kDebug() << "item is in imap resource"; - Akonadi::Item imapItem = fetchJob->items().first(); - - if (!mHandler->toKolabFormat(mKolabItem, imapItem)) { - kWarning() << "Failed to convert item to kolab format: " << mKolabItem.id(); - setError(KJob::UserDefinedError); - setErrorText(i18n("Failed to convert item %1 to kolab format", mKolabItem.id())); - emitResult(); - return; - } - Akonadi::ItemModifyJob *mjob = new Akonadi::ItemModifyJob(imapItem); - connect(mjob, SIGNAL(result(KJob*)), SLOT(onItemModifyDone(KJob*))); - } -} - -void ItemChangedJob::onCollectionFetchDone(KJob *job) -{ - Akonadi::CollectionFetchJob *fetchJob = static_cast(job); - if ( job->error() || fetchJob->collections().isEmpty() ) { - kWarning() << "Collection fetch job failed" << fetchJob->errorString(); - setError(KJob::UserDefinedError); - setErrorText(job->errorText()); - emitResult(); - return; - } - - const Akonadi::Collection kolabCollection = fetchJob->collections().first(); - ItemAddedJob *itemAddedJob = new ItemAddedJob(mKolabItem, kolabCollection, *mHandler, this); - connect(itemAddedJob, SIGNAL(result(KJob*)), SLOT(onItemAddedDone(KJob*)) ); - itemAddedJob->start(); -} - -void ItemChangedJob::onItemAddedDone(KJob* job) -{ - if (job->error()) { - setError(KJob::UserDefinedError); - setErrorText(job->errorText()); - } - emitResult(); -} - -void ItemChangedJob::onItemModifyDone(KJob *job) -{ - if (job->error()) { - setError(KJob::UserDefinedError); - setErrorText(job->errorText()); - } - emitResult(); -} - -Akonadi::Item ItemChangedJob::item() const -{ - return mKolabItem; -} diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/itemchangedjob.h kdepim-runtime-15.08.0/resources/kolabproxy/itemchangedjob.h --- kdepim-runtime-4.14.6/resources/kolabproxy/itemchangedjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/itemchangedjob.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 ITEMCHANGEDJOB_H -#define ITEMCHANGEDJOB_H -#include -#include "kolabhandler.h" -#include "handlermanager.h" - -class ItemChangedJob: public KJob -{ - Q_OBJECT -public: - ItemChangedJob(const Akonadi::Item &kolabItem, HandlerManager &handler, QObject* parent); - virtual void start(); - Akonadi::Item item() const; -private slots: - void onKolabCollectionFetched(KJob* job); - void onImapItemFetchDone(KJob *job); - void onCollectionFetchDone(KJob *job); - void onItemAddedDone(KJob *job); - void onItemModifyDone(KJob *job); -private: - HandlerManager &mHandlerManager; - KolabHandler::Ptr mHandler; - const Akonadi::Item mKolabItem; -}; - -#endif \ No newline at end of file diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/journalhandler.cpp kdepim-runtime-15.08.0/resources/kolabproxy/journalhandler.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/journalhandler.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/journalhandler.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -/* - Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Copyright (c) 2009 Andras Mantia - Copyright (c) 2012 Christian Mollekopf - - 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 "journalhandler.h" - -JournalHandler::JournalHandler( const Akonadi::Collection &imapCollection ) - : IncidenceHandler( imapCollection ) -{ - m_mimeType = "application/x-vnd.kolab.journal"; -} - -JournalHandler::~JournalHandler() -{ -} - -KMime::Message::Ptr JournalHandler::incidenceToMime( const KCalCore::Incidence::Ptr &incidence ) -{ - return - Kolab::KolabObjectWriter::writeJournal( - incidence.dynamicCast(), - m_formatVersion, PRODUCT_ID, QLatin1String("UTC") ); -} - -QStringList JournalHandler::contentMimeTypes() -{ - return QStringList() << KCalCore::Journal::journalMimeType(); -} - -QString JournalHandler::iconName() const -{ - return QString::fromLatin1( "view-pim-journal" ); -} diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/journalhandler.h kdepim-runtime-15.08.0/resources/kolabproxy/journalhandler.h --- kdepim-runtime-4.14.6/resources/kolabproxy/journalhandler.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/journalhandler.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -/* - Copyright (C) 2009 Klar?lvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Copyright (c) 2009 Andras Mantia - Copyright (c) 2012 Christian Mollekopf - - 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 KOLABPROXY_JOURNALHANDLER_H -#define KOLABPROXY_JOURNALHANDLER_H - -#include "incidencehandler.h" - -/** - @author Andras Mantia -*/ -class JournalHandler : public IncidenceHandler -{ - public: - explicit JournalHandler( const Akonadi::Collection &imapCollection ); - virtual ~JournalHandler(); - - virtual QStringList contentMimeTypes(); - virtual QString iconName() const; - - private: - virtual KMime::Message::Ptr incidenceToMime( const KCalCore::Incidence::Ptr &incidence ); -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/kolabdefs.cpp kdepim-runtime-15.08.0/resources/kolabproxy/kolabdefs.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/kolabdefs.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/kolabdefs.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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 "kolabdefs.h" - -#include - -#include - -using namespace KolabV2; - -static const struct { - const char *name; - const char *label; -} folderTypeData[] = { - { KOLAB_FOLDER_TYPE_MAIL, "" }, - { KOLAB_FOLDER_TYPE_CONTACT, I18N_NOOP( "Contacts" ) }, - { KOLAB_FOLDER_TYPE_EVENT, I18N_NOOP( "Calendar" ) }, - { KOLAB_FOLDER_TYPE_TASK, I18N_NOOP( "Tasks" ) }, - { KOLAB_FOLDER_TYPE_JOURNAL, I18N_NOOP( "Journal" ) }, - { KOLAB_FOLDER_TYPE_NOTE, I18N_NOOP( "Notes" ) } -}; -static const int numFolderTypeData = sizeof folderTypeData / sizeof *folderTypeData; - -BOOST_STATIC_ASSERT( numFolderTypeData == KolabV2::FolderTypeSize ); - -FolderType KolabV2::folderTypeFromString( const QByteArray &folderTypeName ) -{ - if ( folderTypeName == KOLAB_FOLDER_TYPE_CONTACT || - folderTypeName == KOLAB_FOLDER_TYPE_CONTACT KOLAB_FOLDER_TYPE_DEFAULT_SUFFIX ) { - return KolabV2::Contact; - } - - if ( folderTypeName == KOLAB_FOLDER_TYPE_EVENT || - folderTypeName == KOLAB_FOLDER_TYPE_EVENT KOLAB_FOLDER_TYPE_DEFAULT_SUFFIX ) { - return KolabV2::Event; - } - - if ( folderTypeName == KOLAB_FOLDER_TYPE_TASK || - folderTypeName == KOLAB_FOLDER_TYPE_TASK KOLAB_FOLDER_TYPE_DEFAULT_SUFFIX ) { - return KolabV2::Task; - } - - if ( folderTypeName == KOLAB_FOLDER_TYPE_JOURNAL || - folderTypeName == KOLAB_FOLDER_TYPE_JOURNAL KOLAB_FOLDER_TYPE_DEFAULT_SUFFIX ) { - return KolabV2::Journal; - } - - if ( folderTypeName == KOLAB_FOLDER_TYPE_NOTE || - folderTypeName == KOLAB_FOLDER_TYPE_NOTE KOLAB_FOLDER_TYPE_DEFAULT_SUFFIX ) { - return KolabV2::Note; - } - - return KolabV2::Mail; -} - -QByteArray KolabV2::folderTypeToString( FolderType type, bool isDefault ) -{ - Q_ASSERT( type >= 0 && type < FolderTypeSize ); - QByteArray result = folderTypeData[ type ].name; - if ( isDefault ) { - result += KOLAB_FOLDER_TYPE_DEFAULT_SUFFIX; - } - return result; -} - -KolabV2::FolderType KolabV2::guessFolderTypeFromName( const QString &name ) -{ - for ( int i = 0; i < numFolderTypeData; ++i ) { - if ( name == i18n( folderTypeData[ i ].label ) || - name == QString::fromLatin1( folderTypeData[ i ].label ) ) { - return static_cast( i ); - } - } - return KolabV2::Mail; -} - -QString KolabV2::nameForFolderType( FolderType type ) -{ - Q_ASSERT( type >= 0 && type < FolderTypeSize ); - return i18n( folderTypeData[ type ].label ); -} - -Kolab::FolderType Kolab::folderTypeFromString(const QByteArray& folderTypeName) -{ - return Kolab::folderTypeFromString( std::string(folderTypeName.data(), folderTypeName.size()) ); -} - -QByteArray Kolab::getFolderTypeAnnotation(const QMap< QByteArray, QByteArray > &annotations) -{ - if ( annotations.contains( "/shared" KOLAB_FOLDER_TYPE_ANNOTATION ) ) { - return annotations.value( "/shared" KOLAB_FOLDER_TYPE_ANNOTATION ); - } - return annotations.value(KOLAB_FOLDER_TYPE_ANNOTATION); -} - -void Kolab::setFolderTypeAnnotation(QMap< QByteArray, QByteArray >& annotations, const QByteArray& value) -{ - annotations["/shared" KOLAB_FOLDER_TYPE_ANNOTATION] = value; -} - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/kolabdefs.h kdepim-runtime-15.08.0/resources/kolabproxy/kolabdefs.h --- kdepim-runtime-4.14.6/resources/kolabproxy/kolabdefs.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/kolabdefs.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - - 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 KOLABPROXY_KOLABDEFS_H -#define KOLABPROXY_KOLABDEFS_H - -#include -#include - -#include //libkolab -#include //libkolab - -namespace Kolab { - FolderType folderTypeFromString( const QByteArray &folderTypeName ); - QByteArray getFolderTypeAnnotation( const QMap &annotations); - void setFolderTypeAnnotation( QMap &annotations, const QByteArray &value); -} - -namespace KolabV2 { - -#define PRODUCT_ID QLatin1String("Akonadi-KolabResource") - - enum FolderType { - Mail = 0, - Contact, - Event, - Task, - Journal, - Note, - FolderTypeSize = Note + 1 - }; - - FolderType folderTypeFromString( const QByteArray &folderTypeName ); - QByteArray folderTypeToString( FolderType type, bool isDefault = false ); - FolderType guessFolderTypeFromName( const QString &name ); - QString nameForFolderType( FolderType type ); -} - -#endif diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/kolabhandler.cpp kdepim-runtime-15.08.0/resources/kolabproxy/kolabhandler.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/kolabhandler.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/kolabhandler.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,225 +0,0 @@ -/* - Copyright (c) 2009 Andras Mantia - Copyright (c) 2012 Christian Mollekopf - - 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 "kolabhandler.h" - -#include "addressbookhandler.h" -#include "calendarhandler.h" -#include "notehandler.h" -#include "taskshandler.h" -#include "imapitemaddedjob.h" -#include "imapitemremovedjob.h" - -#include //libkolab - -#include -#include - -KolabHandler::KolabHandler( const Akonadi::Collection &imapCollection ) - : m_imapCollection( imapCollection ), - m_formatVersion ( Kolab::KolabV3 ), - m_warningDisplayLevel( Kolab::ErrorHandler::Error ), - mItemAddJobInProgress( false ) -{ -} - -KolabHandler::Ptr KolabHandler::createHandler( Kolab::FolderType type, - const Akonadi::Collection &imapCollection ) -{ - switch (type) { - case Kolab::ContactType: - return Ptr( new AddressBookHandler( imapCollection ) ); - case Kolab::EventType: - return Ptr( new CalendarHandler( imapCollection ) ); - case Kolab::TaskType: - return Ptr( new TasksHandler( imapCollection ) ); - case Kolab::JournalType: - return Ptr( new JournalHandler( imapCollection ) ); - case Kolab::NoteType: - return Ptr( new NotesHandler( imapCollection ) ); - default: - qWarning() << "invalid type"; - } - return KolabHandler::Ptr(); -} - -bool KolabHandler::hasHandler( Kolab::FolderType type ) -{ - switch (type) { - case Kolab::ContactType: - case Kolab::EventType: - case Kolab::TaskType: - case Kolab::JournalType: - case Kolab::NoteType: - return true; - default: - return false; - } - return false; -} - -KolabHandler::Ptr KolabHandler::createHandler( const KolabV2::FolderType &type, - const Akonadi::Collection &imapCollection ) -{ - switch (type) { - case KolabV2::Contact: - return Ptr( new AddressBookHandler( imapCollection ) ); - case KolabV2::Event: - return Ptr( new CalendarHandler( imapCollection ) ); - case KolabV2::Task: - return Ptr( new TasksHandler( imapCollection ) ); - case KolabV2::Journal: - return Ptr( new JournalHandler( imapCollection ) ); - case KolabV2::Note: - return Ptr( new NotesHandler( imapCollection ) ); - default: - qWarning() << "invalid type"; - } - return KolabHandler::Ptr(); -} - -void KolabHandler::setKolabFormatVersion( Kolab::Version version ) -{ - m_formatVersion = version; -} - -QByteArray KolabHandler::kolabTypeForMimeType( const QStringList &contentMimeTypes ) -{ - if ( contentMimeTypes.contains( KABC::Addressee::mimeType() ) ) { - return "contact"; - } else if ( contentMimeTypes.contains( KCalCore::Event::eventMimeType() ) ) { - return "event"; - } else if ( contentMimeTypes.contains( KCalCore::Todo::todoMimeType() ) ) { - return "task"; - } else if ( contentMimeTypes.contains( KCalCore::Journal::journalMimeType() ) ) { - return "journal"; - } else if ( contentMimeTypes.contains( QLatin1String("application/x-vnd.akonadi.note") ) || - contentMimeTypes.contains( QLatin1String("text/x-vnd.akonadi.note") ) ) { - return "note"; - } - return QByteArray(); -} - -QStringList KolabHandler::allSupportedMimeTypes() -{ - return QStringList() - << KABC::Addressee::mimeType() - << KABC::ContactGroup::mimeType() - << KCalCore::Event::eventMimeType() - << KCalCore::Todo::todoMimeType() - << KCalCore::Journal::journalMimeType() - << QLatin1String( "application/x-vnd.akonadi.note" ) - << QLatin1String( "text/x-vnd.akonadi.note" ); -} - -KolabHandler::~KolabHandler() -{ -} - -QByteArray KolabHandler::mimeType() const -{ - return m_mimeType; -} - -bool KolabHandler::checkForErrors( Akonadi::Item::Id affectedItem ) -{ - if ( Kolab::ErrorHandler::instance().error() < m_warningDisplayLevel ) { - Kolab::ErrorHandler::instance().clear(); - return false; - } - - QString errorMsg; - foreach ( const Kolab::ErrorHandler::Err &error, Kolab::ErrorHandler::instance().getErrors() ) { - errorMsg.append( error.message ); - errorMsg.append( QLatin1String("\n") ); - } - - kWarning() << "Error on item " << affectedItem << ":\n" << errorMsg; - Kolab::ErrorHandler::instance().clear(); - return true; -} - -Akonadi::Item::List KolabHandler::resolveConflicts(const Akonadi::Item::List& kolabItems) -{ - //we should preserve the order here - Akonadi::Item::List finalItems; - QMap gidItemMap; - foreach (const Akonadi::Item &item, kolabItems) { - const QString gid = extractGid(item); - if (!gid.isEmpty()) { - gidItemMap[gid] << item; - } - } - foreach (const Akonadi::Item &item, kolabItems) { - const QString gid = extractGid(item); - if (gid.isEmpty()) { - finalItems << item; - } else if (gidItemMap.contains(gid)) { - //TODO assuming the items are in revers imap uid order (newest first) - finalItems << gidItemMap.value(gid).first(); - gidItemMap.remove(gid); - } - } - return finalItems; -} - -void KolabHandler::processItemAddedQueue() -{ - if (mItemAddedQueue.isEmpty() || mItemAddJobInProgress) { - return; - } - //TODO we would only have to serialize add jobs for items with the same GID - mItemAddJobInProgress = true; - const QPair pair = mItemAddedQueue.dequeue(); - ImapItemAddedJob *addedJob = new ImapItemAddedJob( pair.first, pair.second, *this, this ); - connect(addedJob, SIGNAL(result(KJob*)), this, SLOT(onItemAdded(KJob*))); - addedJob->start(); -} - -void KolabHandler::onItemAdded(KJob *job) -{ - mItemAddJobInProgress = false; - if (job->error()) { - kWarning() << job->errorString(); - } - processItemAddedQueue(); -} - -void KolabHandler::imapItemAdded(const Akonadi::Item& imapItem, const Akonadi::Collection& imapCollection) -{ - mItemAddedQueue.enqueue(qMakePair(imapItem, imapCollection)); - processItemAddedQueue(); -} - -void KolabHandler::imapItemRemoved(const Akonadi::Item& imapItem) -{ - //TODO delay this in case an imapItemAdded job is already running (it might reuse the item) - ImapItemRemovedJob *job = new ImapItemRemovedJob(imapItem, this); - connect(job, SIGNAL(result(KJob*)), this, SLOT(checkResult(KJob*))); - job->start(); -} - -void KolabHandler::checkResult(KJob* job) -{ - if ( job->error() ) { - kWarning() << "Error occurred: " << job->errorString(); - } -} - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/kolabhandler.h kdepim-runtime-15.08.0/resources/kolabproxy/kolabhandler.h --- kdepim-runtime-4.14.6/resources/kolabproxy/kolabhandler.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/kolabhandler.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,160 +0,0 @@ -/* - Copyright (c) 2009 Andras Mantia - Copyright (c) 2012 Christian Mollekopf - - 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 KOLABPROXY_KOLABHANDLER_H -#define KOLABPROXY_KOLABHANDLER_H - -#include "kolabdefs.h" - -#include -#include - -#include -#include - -#include //libkolab - -class KJob; -/** - @author Andras Mantia -*/ -class KolabHandler : public QObject -{ - Q_OBJECT - - public: - typedef QSharedPointer Ptr; - - static Ptr createHandler( Kolab::FolderType type, - const Akonadi::Collection &imapCollection ); - - static bool hasHandler( Kolab::FolderType type ); - - static Ptr createHandler( const KolabV2::FolderType &type, - const Akonadi::Collection &imapCollection ); - - /** - * Returns the Kolab folder type for the given collection. - */ - static QByteArray kolabTypeForMimeType( const QStringList &mimetypes ); - - /** - * Returns all mime types supported by Kolab. - */ - static QStringList allSupportedMimeTypes(); - - virtual ~KolabHandler(); - - /** - * Extracts the UID of a kolab object from an imap item. - * - * Used for conflict detection. - */ - virtual QString extractGid( const Akonadi::Item &kolabItem ) = 0; - - Akonadi::Item::List resolveConflicts( const Akonadi::Item::List &kolabItems ); - - /** - * Translates Kolab items into the items supported by the handler. - * @param addrs - * @return the translated items - */ - virtual Akonadi::Item::List translateItems( const Akonadi::Item::List &addrs ) = 0; - - /** - * Translates an item into Kolab format. - * @param item the item to be translated - * @param imapItem the item that will hold the Kolab format payload data. - * @return false if the conversion failed - */ - virtual bool toKolabFormat( const Akonadi::Item &item, Akonadi::Item &imapItem ) = 0; - - /** - * Return the mimetypes for the collections managed by the handler. - */ - virtual QStringList contentMimeTypes() = 0; - - /** - * Returns the default icon for this folder type. - */ - virtual QString iconName() const = 0; - - virtual QByteArray mimeType() const; - - void setKolabFormatVersion( Kolab::Version ); - - /** - * Returns true if the current operation should be aborted and false - * if everything is ok. - * - * Error handling strategy: - * If an error happened, either: - * - completely skip item => will be redownloaded - * (or will it be deleted from the server? (it shouldn't)) - * - mark item as corrup => readonly, will not be written back - * and will be redownloaded - * - * @param affectedItem The item which is currently being processed. - */ - bool checkForErrors( Akonadi::Item::Id affectedItem ); - - void imapItemAdded(const Akonadi::Item &imapItem, const Akonadi::Collection &imapCollection); - void imapItemRemoved(const Akonadi::Item &imapItem); - - protected: - explicit KolabHandler( const Akonadi::Collection &imapCollection ); - - QByteArray m_mimeType; - Akonadi::Collection m_imapCollection; - Kolab::Version m_formatVersion; - int m_warningDisplayLevel; - - private slots: - void onItemAdded(KJob*); - void checkResult(KJob*); - - private: - void processItemAddedQueue(); - QQueue > mItemAddedQueue; - bool mItemAddJobInProgress; -}; - -template -static inline T kolabToImap( const T &kolabObject ) -{ - return T( kolabObject.remoteId().toLongLong() ); -} - -template -static inline T imapToKolab( const T &imapObject, T &kolabObject) -{ - kolabObject.setRemoteId( QString::number( imapObject.id() ) ); - return kolabObject; -} - -template -static inline T imapToKolab( const T &imapObject ) -{ - T kolabObject; - imapToKolab( imapObject, kolabObject ); - return kolabObject; -} - - -#endif diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/kolabproxyresource.cpp kdepim-runtime-15.08.0/resources/kolabproxy/kolabproxyresource.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/kolabproxyresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/kolabproxyresource.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,832 +0,0 @@ -/* - Copyright (c) 2009 Andras Mantia - Copyright (c) 2012 Christian Mollekopf - - 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 "kolabproxyresource.h" - -#include "collectiontreebuilder.h" -#include "freebusyupdatehandler.h" -#include "settings.h" -#include "settingsadaptor.h" -#include "kolabproxyadaptor.h" -#include "setupkolab.h" -#include "imapitemaddedjob.h" -#include "imapitemremovedjob.h" -#include "itemaddedjob.h" -#include "itemchangedjob.h" -#include "revertitemchangesjob.h" -#include - -#include "collectionannotationsattribute.h" //from shared - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifdef RUNTIME_PLUGINS_STATIC -#include - -Q_IMPORT_PLUGIN(akonadi_serializer_mail) -Q_IMPORT_PLUGIN(akonadi_serializer_addressee) -Q_IMPORT_PLUGIN(akonadi_serializer_kcalcore) -Q_IMPORT_PLUGIN(akonadi_serializer_contactgroup) -#endif - -static const char KOLAB_COLLECTION[] = "KolabCollection"; - -static QString mailBoxForImapCollection( const Akonadi::Collection &imapCollection, - bool showWarnings ) -{ - if ( imapCollection.remoteId().isEmpty() ) { - if ( showWarnings ) { - kWarning() << "Got incomplete ancestor chain:" << imapCollection; - } - return QString(); - } - - if ( imapCollection.parentCollection() == Akonadi::Collection::root() ) { - return QLatin1String( "" ); - } - - const QString parentMailbox = - mailBoxForImapCollection( imapCollection.parentCollection(), showWarnings ); - - if ( parentMailbox.isNull() ) { - // invalid, != isEmpty() here! - return QString(); - } - - const QString mailbox = parentMailbox + imapCollection.remoteId(); - - return mailbox; -} - -KolabProxyResource::KolabProxyResource( const QString &id ) - : ResourceBase( id ), - mHandlerManager( new HandlerManager ) -{ - Akonadi::AttributeFactory::registerAttribute(); - new SettingsAdaptor( Settings::self() ); - QDBusConnection::sessionBus().registerObject( - QLatin1String( "/Settings" ), - Settings::self(), QDBusConnection::ExportAdaptors ); - - new KolabproxyAdaptor( this ); - Akonadi::DBusConnectionPool::threadConnection().registerObject( QLatin1String( "/KolabProxy" ), this, QDBusConnection::ExportAdaptors ); - Akonadi::DBusConnectionPool::threadConnection().registerService( QLatin1String( "Agent.akonadi_kolabproxy_resource" ) ); - - changeRecorder()->fetchCollection( true ); - changeRecorder()->itemFetchScope().fetchFullPayload(); - - m_monitor = new Akonadi::Monitor( this ); - m_monitor->itemFetchScope().fetchFullPayload(); - m_monitor->itemFetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::All ); - - m_collectionMonitor = new Akonadi::Monitor( this ); - m_collectionMonitor->fetchCollection( true ); - m_collectionMonitor->setCollectionMonitored( Akonadi::Collection::root() ); - m_collectionMonitor->ignoreSession( Akonadi::Session::defaultSession() ); - m_collectionMonitor->collectionFetchScope().setAncestorRetrieval( - Akonadi::CollectionFetchScope::All ); - - m_freeBusyUpdateHandler = new FreeBusyUpdateHandler( this ); - - connect( m_monitor, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)), - this, SLOT(imapItemAdded(Akonadi::Item,Akonadi::Collection)) ); - - connect( m_monitor, SIGNAL(itemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)), - this, SLOT(imapItemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)) ); - - connect( m_monitor, SIGNAL(itemRemoved(Akonadi::Item)), - this, SLOT(imapItemRemoved(Akonadi::Item)) ); - - //We don't connect to changed because an edit results in a new item (append/delete) on imap - - connect( m_collectionMonitor, SIGNAL(collectionAdded(Akonadi::Collection,Akonadi::Collection)), - this, SLOT(imapCollectionAdded(Akonadi::Collection,Akonadi::Collection)) ); - - connect( m_collectionMonitor, SIGNAL(collectionRemoved(Akonadi::Collection)), - this, SLOT(imapCollectionRemoved(Akonadi::Collection)) ); - - connect( m_collectionMonitor, SIGNAL(collectionChanged(Akonadi::Collection)), - this, SLOT(imapCollectionChanged(Akonadi::Collection)) ); - - connect( m_collectionMonitor, - SIGNAL(collectionMoved(Akonadi::Collection,Akonadi::Collection,Akonadi::Collection)), - this, - SLOT(imapCollectionMoved(Akonadi::Collection,Akonadi::Collection,Akonadi::Collection)) ); - - setName( i18n( "Kolab" ) ); - - // among other things, this ensures that m_root actually exists when a new imap folder is added - synchronizeCollectionTree(); -} - -KolabProxyResource::~KolabProxyResource() -{ -} - -void KolabProxyResource::showErrorMessage(const QString &msg) -{ - KNotification *notification = new KNotification(QLatin1String("Error"), KNotification::CloseOnTimeout, 0); - notification->setText(msg); - notification->setComponentData(KGlobal::mainComponent()); - notification->sendEvent(); -} - -bool KolabProxyResource::registerHandlerForCollection(const Akonadi::Collection& imapCollection) -{ - const Kolab::Version v = SetupKolab::readKolabVersion( imapCollection.resource() ); - if ( mHandlerManager->registerHandlerForCollection( imapCollection, v ) ) { - m_monitor->setCollectionMonitored( imapCollection ); - return true; - } - return false; -} - -QString KolabProxyResource::imapResourceForCollection( Akonadi::Entity::Id id) -{ - return mHandlerManager->imapResourceForCollection( id ); -} - -void KolabProxyResource::retrieveCollections() -{ - CollectionTreeBuilder *job = new CollectionTreeBuilder( this ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(retrieveCollectionsTreeDone(KJob*)) ); -} - -void KolabProxyResource::retrieveCollectionsTreeDone( KJob *job ) -{ - if ( job->error() ) { - kWarning( ) << "Error on collection fetch:" << job->errorText(); - cancelTask( job->errorText() ); - } else { - Akonadi::Collection::List imapCollections = - qobject_cast( job )->allCollections(); - - Akonadi::Collection::List kolabCollections; - Q_FOREACH ( const Akonadi::Collection &collection, imapCollections ) { - kolabCollections.append( createCollection( collection ) ); - } - collectionsRetrieved( kolabCollections ); - } -} - -void KolabProxyResource::retrieveItems( const Akonadi::Collection &collection ) -{ - const Akonadi::Collection imapCollection = kolabToImap( collection ); - if ( !mHandlerManager->isMonitored( imapCollection.id() ) ) { - //This should never happen - kWarning() << "received a retrieveItems request for a collection without imap counterpart" << collection.id(); - cancelTask(); - return; - } - - Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( imapCollection ); - job->fetchScope().fetchFullPayload(); - job->fetchScope().setIgnoreRetrievalErrors( true ); - - connect( job, SIGNAL(result(KJob*)), this, SLOT(retrieveItemsFetchDone(KJob*)) ); -} - -void KolabProxyResource::retrieveItemsFetchDone( KJob *job ) -{ - if ( job->error() ) { - kWarning( ) << "Error on item fetch:" << job->errorText(); - cancelTask(); - return; - } - - const Akonadi::Item::List items = qobject_cast(job)->items(); - if ( items.isEmpty() ) { - itemsRetrieved( Akonadi::Item::List() ); - return; - } - const KolabHandler::Ptr handler = mHandlerManager->getHandler( items[0].storageCollectionId() ); - if ( !handler ) { - cancelTask(); - return; - } - const Akonadi::Item::List newItems = handler->resolveConflicts( handler->translateItems( items ) ); - - itemsRetrieved( newItems ); -} - -bool KolabProxyResource::retrieveItem( const Akonadi::Item &item, const QSet &parts ) -{ - Q_UNUSED( parts ); - Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( kolabToImap( item ) ); - job->fetchScope().fetchFullPayload(); - job->setProperty( "itemId", item.id() ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(retrieveItemFetchDone(KJob*)) ); - return true; -} - -void KolabProxyResource::retrieveItemFetchDone( KJob *job ) -{ - if ( job->error() ) { - kWarning( ) << "Error on item fetch:" << job->errorText(); - cancelTask(); - return; - } - const Akonadi::Item::List items = qobject_cast(job)->items(); - if ( items.isEmpty() ) { - kWarning() << "Items is emtpy"; - cancelTask(); - return; - } - const KolabHandler::Ptr handler = mHandlerManager->getHandler( items[0].storageCollectionId() ); - if ( !handler ) { - cancelTask(); - return; - } - const Akonadi::Item::List newItems = handler->translateItems( items ); - if ( newItems.isEmpty() ) { - kWarning() << "Could not translate item"; - cancelTask(); - return; - } - Akonadi::Item item = newItems[0]; - item.setId(job->property("itemId").value()); - itemRetrieved( item ); -} - -void KolabProxyResource::aboutToQuit() -{ - mHandlerManager->clear(); -} - -void KolabProxyResource::configure( WId windowId ) -{ - // TODO: this method is usually called when a new resource is being - // added to the Akonadi setup. You can do any kind of user interaction here, - // e.g. showing dialogs. - // The given window ID is usually useful to get the correct - // "on top of parent" behavior if the running window manager applies any kind - // of focus stealing prevention technique - - QPointer kolabConfigDialog( new SetupKolab( this ) ); - if ( windowId ) - KWindowSystem::setMainWindow( kolabConfigDialog, windowId ); - - kolabConfigDialog->setWindowIcon( KIcon( QLatin1String("kolab") ) ); - kolabConfigDialog->exec(); - emit configurationDialogAccepted(); - - foreach ( Akonadi::Entity::Id id, mHandlerManager->monitoredCollections() ) { //krazy:exclude=foreach - KolabHandler::Ptr handler = mHandlerManager->getHandler( id ); - Kolab::Version v = SetupKolab::readKolabVersion( mHandlerManager->imapResourceForCollection( id ) ); - handler->setKolabFormatVersion( v ); - } - - delete kolabConfigDialog; -} - -void KolabProxyResource::itemAdded( const Akonadi::Item &kolabItem, - const Akonadi::Collection &collection ) -{ - const Akonadi::Collection imapCollection = kolabToImap( collection ); - const KolabHandler::Ptr handler = mHandlerManager->getHandler( imapCollection.id() ); - if ( !handler ) { - kWarning() << "Couldn't find a handler for the collection, but we should have one: " << imapCollection.id(); - showErrorMessage(i18n("An error occured while writing the item to the backend.")); - cancelTask(); - new Akonadi::ItemDeleteJob(kolabItem); - return; - } - ItemAddedJob *itemAddedJob = new ItemAddedJob(kolabItem, collection, *handler, this); - connect(itemAddedJob, SIGNAL(result(KJob*)), this, SLOT(onItemAddedDone(KJob*))); - itemAddedJob->start(); -} - -void KolabProxyResource::onItemAddedDone(KJob* job) -{ - ItemAddedJob *itemAddedJob = static_cast(job); - Akonadi::Item kolabItem = itemAddedJob->kolabItem(); - const Akonadi::Item imapItem = itemAddedJob->imapItem(); - if (job->error()) { - kWarning() << "Failed to create imap item: " << job->errorString(); - showErrorMessage(i18n("An error occured while writing the item to the backend.")); - cancelTask(); - new Akonadi::ItemDeleteJob(kolabItem); - return; - } - m_excludeAppend << imapItem.id(); - - kolabItem.setRemoteId( QString::number( imapItem.id() ) ); - changeCommitted( kolabItem ); -} - -void KolabProxyResource::itemChanged( const Akonadi::Item &kolabItem, - const QSet &parts ) -{ - Q_UNUSED( parts ); - ItemChangedJob *itemChangedJob = new ItemChangedJob(kolabItem, *mHandlerManager, this); - connect(itemChangedJob, SIGNAL(result(KJob*)), this, SLOT(onItemChangedDone(KJob*))); - itemChangedJob->start(); -} - -void KolabProxyResource::onItemChangedDone(KJob* job) -{ - ItemChangedJob *itemChangedJob = static_cast(job); - if ( job->error() ) { - showErrorMessage(i18n("An error occured while writing the item to the backend.")); - cancelTask( job->errorText() ); - kWarning() << "Failed to modify item, reverting to state of imap item: " << itemChangedJob->item().id(); - RevertItemChangesJob *revertJob = new RevertItemChangesJob(itemChangedJob->item(), *mHandlerManager, this); - connect(revertJob, SIGNAL(result(KJob*)), this, SLOT(checkResult(KJob*))); - revertJob->start(); - return; - } - changeCommitted( itemChangedJob->item() ); -} - -void KolabProxyResource::itemMoved( const Akonadi::Item &item, - const Akonadi::Collection &collectionSource, - const Akonadi::Collection &collectionDestination ) -{ - Q_UNUSED( collectionSource ); - KJob *job = new Akonadi::ItemMoveJob( kolabToImap( item ), kolabToImap( collectionDestination ), this ); - connect(job, SIGNAL(result(KJob*)), this, SLOT(checkResult(KJob*))); - changeCommitted( item ); -} - -void KolabProxyResource::itemRemoved( const Akonadi::Item &item ) -{ - const Akonadi::Item imapItem( item.remoteId().toUInt() ); - Akonadi::ItemDeleteJob *djob = new Akonadi::ItemDeleteJob( imapItem ); - changeCommitted( item ); - Q_UNUSED(djob); -} - -void KolabProxyResource::collectionAdded( const Akonadi::Collection &collection, - const Akonadi::Collection &parent ) -{ - if ( KolabHandler::kolabTypeForMimeType( collection.contentMimeTypes() ).isEmpty() ) { - kWarning() << "Collection " << collection.name() << collection.id() << collection.isValid() - << "doesn't have kolab type set. isValid = " - << "; parent is " << parent.name() << parent.id() << parent.isValid(); - cancelTask( QLatin1String( "Collection doesn't have kolab type." ) ); - return; - } - - Akonadi::Collection imapCollection( collection ); - imapCollection.setId( -1 ); - imapCollection.setRemoteId( QString() ); - imapCollection.setContentMimeTypes( QStringList() - << Akonadi::Collection::mimeType() - << QLatin1String( "message/rfc822" ) ); - const Akonadi::Collection imapParent = kolabToImap( parent ); - imapCollection.setParentCollection( imapParent ); - - Akonadi::CollectionAnnotationsAttribute *attr = - imapCollection.attribute( - Akonadi::Collection::AddIfMissing ); - - QMap annotations = attr->annotations(); - Kolab::setFolderTypeAnnotation( annotations, KolabHandler::kolabTypeForMimeType( collection.contentMimeTypes() ) ); - attr->setAnnotations( annotations ); - - Akonadi::CollectionCreateJob *job = new Akonadi::CollectionCreateJob( imapCollection, this ); - job->setProperty( KOLAB_COLLECTION, QVariant::fromValue( collection ) ); - connect( job, SIGNAL(result(KJob*)), SLOT(imapFolderCreateResult(KJob*)) ); -} - -void KolabProxyResource::imapFolderCreateResult( KJob *job ) -{ - if ( job->error() ) { - cancelTask( job->errorText() ); - } else { - const Akonadi::Collection imapCollection = - qobject_cast( job )->collection(); - - registerHandlerForCollection( imapCollection ); - Akonadi::Collection kolabCollection = - job->property( KOLAB_COLLECTION ).value(); - kolabCollection.setRemoteId( QString::number( imapCollection.id() ) ); - changeCommitted( kolabCollection ); - } -} - -void KolabProxyResource::applyAttributesToImap( Akonadi::Collection &imapCollection, - const Akonadi::Collection &kolabCollection ) -{ - static const Akonadi::EntityDisplayAttribute eda; - static const Akonadi::EntityHiddenAttribute hidden; - foreach ( const Akonadi::Attribute *attr, kolabCollection.attributes() ) { - if ( attr->type() == hidden.type() ) { - // Don't propagate HIDDEN because that would hide collections in korg, kab too. - continue; - } - - if ( attr->type() == eda.type() ) { - // Don't propagate DISPLAYATTRIBUTE because that would cause icons - // from the imap resource to use kolab icons. - Akonadi::EntityDisplayAttribute *imapEda = - imapCollection.attribute( Akonadi::Entity::AddIfMissing ); - - const QString dName = - static_cast( attr )->displayName(); - imapEda->setDisplayName( dName ); - continue; - } - - if ( attr->type() == "AccessRights" ) { - // Don't propagate access rights here, since it's already propagated using Collection::rights - continue; - } - - imapCollection.addAttribute( attr->clone() ); - } -} - -void KolabProxyResource::applyAttributesFromImap( Akonadi::Collection &kolabCollection, - const Akonadi::Collection &imapCollection ) -{ - static const Akonadi::EntityDisplayAttribute eda; - static const Akonadi::EntityHiddenAttribute hidden; - foreach ( const Akonadi::Attribute *attr, imapCollection.attributes() ) { - if ( attr->type() == hidden.type() ) { - continue; - } - - if ( attr->type() == eda.type() ) { - continue; - } - - if ( attr->type() == "AccessRights" ) { - continue; - } - - kolabCollection.addAttribute( attr->clone() ); - } -} - -void KolabProxyResource::updateFreeBusyInformation( const Akonadi::Collection &imapCollection ) -{ - if ( !HandlerManager::isHandledKolabFolder( imapCollection ) ) { - return; - } - - if ( HandlerManager::getFolderType( imapCollection ) != Kolab::EventType ) { - return; - } - - if ( !Settings::self()->updateFreeBusy() ) { - return; // disabled by user - } - - Kolab::Version v = SetupKolab::readKolabVersion( imapCollection.resource() ); - if (v != Kolab::KolabV2) { - return; - } - - const QString path = mailBoxForImapCollection( imapCollection, true ); - if ( path.isEmpty() ) { - return; - } - - const QString resourceId = imapCollection.resource(); - - QDBusInterface settingsInterface( - QString::fromLatin1( "org.freedesktop.Akonadi.Agent.%1" ).arg( resourceId ), - QLatin1String( "/Settings" ), QLatin1String( "org.kde.Akonadi.Imap.Settings" ) ); - - QDBusInterface walletInterface( - QString::fromLatin1( "org.freedesktop.Akonadi.Agent.%1" ).arg( resourceId ), - QLatin1String( "/Settings" ), QLatin1String( "org.kde.Akonadi.Imap.Wallet" ) ); - - if ( !settingsInterface.isValid() || !walletInterface.isValid() ) { - kWarning() << "unable to retrieve imap resource settings interface"; - return; - } - - const QDBusReply userNameReply = settingsInterface.call( QLatin1String( "userName" ) ); - if ( !userNameReply.isValid() ) { - kWarning() << "unable to retrieve user name from imap resource settings"; - return; - } - - const QDBusReply passwordReply = walletInterface.call( QLatin1String( "password" ) ); - if ( !passwordReply.isValid() ) { - kWarning() << "unable to retrieve password from imap resource settings"; - return; - } - - const QDBusReply hostReply = settingsInterface.call( QLatin1String( "imapServer" ) ); - if ( !hostReply.isValid() ) { - kWarning() << "unable to retrieve host from imap resource settings"; - return; - } - - m_freeBusyUpdateHandler->updateFolder( path, - userNameReply.value(), - passwordReply.value(), - hostReply.value() ); -} - -void KolabProxyResource::collectionChanged( const Akonadi::Collection &collection ) -{ - Akonadi::Collection imapCollection; - imapCollection.setId( collection.remoteId().toLongLong() ); - imapCollection.setName( collection.name() ); - imapCollection.setCachePolicy( collection.cachePolicy() ); - imapCollection.setRights( collection.rights() ); - - applyAttributesToImap( imapCollection, collection ); - - Akonadi::CollectionModifyJob *job = new Akonadi::CollectionModifyJob( imapCollection, this ); - Q_UNUSED( job ); - // TODO wait for the result - changeCommitted( collection ); -} - -void KolabProxyResource::collectionMoved( const Akonadi::Collection &collection, - const Akonadi::Collection &source, - const Akonadi::Collection &destination ) -{ - Q_UNUSED( source ); - KJob *job = new Akonadi::CollectionMoveJob( kolabToImap( collection ), kolabToImap( destination ), this ); - connect(job, SIGNAL(result(KJob*)), this, SLOT(checkResult(KJob*))); - changeCommitted( collection ); -} - -void KolabProxyResource::collectionRemoved( const Akonadi::Collection &collection ) -{ - Akonadi::Collection imapCollection = kolabToImap( collection ); - - Akonadi::CollectionDeleteJob *job = new Akonadi::CollectionDeleteJob( imapCollection, this ); - Q_UNUSED( job ); - // TODO wait for result - changeCommitted( collection ); -} - -void KolabProxyResource::imapItemAdded( const Akonadi::Item &item, - const Akonadi::Collection &collection ) -{ - //We only want updates about collections that are not from this resource - if ( collection.resource() == identifier() || collection.resource().startsWith("akonadi_kolab_resource") ) { - return; - } - if ( m_excludeAppend.contains( item.id() ) ) { - kDebug() << "item already present"; - m_excludeAppend.removeAll( item.id() ); - return; - } - if ( const KolabHandler::Ptr handler = mHandlerManager->getHandler( collection.id() ) ) { - handler->imapItemAdded(item, collection); - } -} - -void KolabProxyResource::imapItemRemoved( const Akonadi::Item &item ) -{ - //We only want updates about collections that are not from this resource - if ( item.parentCollection().resource() == identifier() || item.parentCollection().resource().startsWith("akonadi_kolab_resource") ) { - return; - } - if ( const KolabHandler::Ptr handler = mHandlerManager->getHandler( item.parentCollection().id() ) ) { - handler->imapItemRemoved(item); - } else { - //The handler is already gone, - kWarning() << "Couldn't find handler for collection " << item.storageCollectionId(); - ImapItemRemovedJob *job = new ImapItemRemovedJob(item, this); - connect(job, SIGNAL(result(KJob*)), this, SLOT(checkResult(KJob*))); - job->start(); - } -} - -void KolabProxyResource::imapItemMoved( const Akonadi::Item &item, - const Akonadi::Collection &collectionSource, - const Akonadi::Collection &collectionDestination ) -{ - //We only want updates about collections that are not from this resource - if ( collectionSource.resource() == identifier() || collectionDestination.resource() == identifier() || - collectionSource.resource().startsWith("akonadi_kolab_resource") || collectionDestination.resource().startsWith("akonadi_kolab_resource") ) { - return; - } - KJob *job = new Akonadi::ItemMoveJob( imapToKolab( item ), imapToKolab( collectionDestination ), this ); - connect(job, SIGNAL(result(KJob*)), this, SLOT(checkResult(KJob*))); -} - -void KolabProxyResource::imapCollectionAdded( const Akonadi::Collection &collection, - const Akonadi::Collection &parent ) -{ - Q_UNUSED( parent ); - //We only want updates about collections that are not from this resource - if ( collection.resource() == identifier() || collection.resource().startsWith("akonadi_kolab_resource") ) { - return; - } - if ( mHandlerManager->isMonitored( collection.id() ) ) { - // something is wrong, so better reload out collection tree - kWarning() << "IMAPCOLLECTIONADDED ABORT"; - synchronizeCollectionTree(); - return; - } - - updateHiddenAttribute( collection ); - - if ( registerHandlerForCollection( collection ) ) { - const Akonadi::Collection kolabCollection = createCollection( collection ); - Akonadi::CollectionCreateJob *job = new Akonadi::CollectionCreateJob( kolabCollection, this ); - connect( job, SIGNAL(result(KJob*)), SLOT(kolabFolderChangeResult(KJob*)) ); - } -} - -void KolabProxyResource::imapCollectionChanged( const Akonadi::Collection &collection ) -{ - //We only want updates about collections that are not from this resource - if ( collection.resource() == identifier() || collection.resource().startsWith("akonadi_kolab_resource") ) { - return; - } - - if ( !mHandlerManager->isMonitored( collection.id() ) ) { - if ( HandlerManager::isHandledKolabFolder( collection ) ) { - synchronizeCollectionTree(); - return; - } - - // not a Kolab folder, no need to resync the tree. - // just try to update a possible structural collection. - // if that fails it's not in our tree -> we don't care - Akonadi::Collection kolabCollection = createCollection( collection ); - Akonadi::CollectionModifyJob *job = new Akonadi::CollectionModifyJob( kolabCollection, this ); - Q_UNUSED( job ); - } else { - if ( !HandlerManager::isHandledKolabFolder( collection ) ) { - //This is no longer a kolab folder, remove - removeFolder( collection ); - return; - } - // Kolab folder we already have in our tree, if the update fails, reload our tree - Akonadi::Collection kolabCollection = createCollection( collection ); - Akonadi::CollectionModifyJob *job = new Akonadi::CollectionModifyJob( kolabCollection, this ); - connect( job, SIGNAL(result(KJob*)), SLOT(kolabFolderChangeResult(KJob*)) ); - } - - updateHiddenAttribute( collection ); - updateFreeBusyInformation( collection ); -} - -void KolabProxyResource::imapCollectionMoved( const Akonadi::Collection &collection, - const Akonadi::Collection &source, - const Akonadi::Collection &destination ) -{ - //We only want updates about collections that are not from this resource - if ( source.resource() == identifier() || destination.resource() == identifier() || - source.resource().startsWith("akonadi_kolab_resource") || destination.resource().startsWith("akonadi_kolab_resource") ) { - return; - } - if ( mHandlerManager->isMonitored( collection.id() ) ) { - KJob *job = new Akonadi::CollectionMoveJob( imapToKolab( collection ), imapToKolab( destination ), this ); - connect(job, SIGNAL(result(KJob*)), this, SLOT(checkResult(KJob*))); - } -} - -void KolabProxyResource::kolabFolderChangeResult( KJob *job ) -{ - if ( job->error() ) { - // something went wrong or the change was too complex to handle in the above slots, - // so re-sync the entire tree. - kWarning() << "Re-syncing collection tree as incremental changes did not succeed." - << job->errorText(); - synchronizeCollectionTree(); - } -} - -void KolabProxyResource::removeFolder( const Akonadi::Collection &imapCollection ) -{ - KJob *deleteJob = new Akonadi::CollectionDeleteJob( imapToKolab( imapCollection ) ); - connect(deleteJob, SIGNAL(result(KJob*)), this, SLOT(checkResult(KJob*))); - mHandlerManager->removeFolder( imapCollection.id() ); - updateFreeBusyInformation( imapCollection ); -} - -void KolabProxyResource::imapCollectionRemoved( const Akonadi::Collection &imapCollection ) -{ - //We only want updates about collections that are not from this resource - if ( imapCollection.resource() == identifier() || imapCollection.resource().startsWith("akonadi_kolab_resource") ) { - return; - } - if (mHandlerManager->isMonitored( imapCollection.id())) { - removeFolder(imapCollection); - } else if ( imapCollection.parentCollection() == Akonadi::Collection::root() ) { - //we are not explicitly monitoring the top-level collection, but it should be removed anyways when the rest is gone - removeFolder(imapCollection); - } -} - -Akonadi::Collection KolabProxyResource::createCollection( - const Akonadi::Collection &imapCollection ) -{ - Akonadi::Collection c; - QStringList contentTypes; - if ( imapCollection.parentCollection() == Akonadi::Collection::root() ) { - c.setParentCollection( Akonadi::Collection::root() ); - Akonadi::CachePolicy policy; - policy.setInheritFromParent( false ); - policy.setCacheTimeout( -1 ); - policy.setLocalParts( QStringList() << QLatin1String( "ALL" ) ); - c.setCachePolicy( policy ); - } else { - c.parentCollection().setRemoteId( QString::number( imapCollection.parentCollection().id() ) ); - } - c.setName( imapCollection.name() ); - c.setRights( imapCollection.rights() ); - - Akonadi::EntityDisplayAttribute *imapAttr = - imapCollection.attribute(); - Akonadi::EntityDisplayAttribute *kolabAttr = - c.attribute( Akonadi::Collection::AddIfMissing ); - - if ( imapAttr ) { - if ( imapAttr->iconName() == QLatin1String( "mail-folder-inbox" ) ) { - kolabAttr->setDisplayName( i18n( "My Data" ) ); - kolabAttr->setIconName( QLatin1String( "view-pim-summary" ) ); - //contentTypes << KolabHandler::allSupportedMimeTypes(); - c.setRights( Akonadi::Collection::ReadOnly | Akonadi::Collection::CanCreateCollection ); - } else if ( imapCollection.parentCollection() == Akonadi::Collection::root() ) { - c.setName( i18n( "Kolab (%1)", imapAttr->displayName() ) ); - kolabAttr->setIconName( QLatin1String( "kolab" ) ); - } else { - kolabAttr->setDisplayName( imapAttr->displayName() ); - kolabAttr->setIconName( imapAttr->iconName() ); - } - } else { - if ( imapCollection.parentCollection() == Akonadi::Collection::root() ) { - c.setName( i18n( "Kolab (%1)", imapCollection.name() ) ); - kolabAttr->setIconName( QLatin1String( "kolab" ) ); - } - } - applyAttributesFromImap( c, imapCollection ); - if ( HandlerManager::isKolabFolder( imapCollection ) ) { - KolabHandler::Ptr handler = mHandlerManager->getHandler( imapCollection.id() ); - if ( handler ) { - contentTypes.append( handler->contentMimeTypes() ); - kolabAttr->setIconName( handler->iconName() ); - } - } - contentTypes.append( Akonadi::Collection::mimeType() ); - c.setContentMimeTypes( contentTypes ); - c.setRemoteId( QString::number( imapCollection.id() ) ); - return c; -} - -void KolabProxyResource::updateHiddenAttribute( const Akonadi::Collection &imapCollection ) -{ - if ( HandlerManager::isKolabFolder( imapCollection ) && !imapCollection.hasAttribute()) { - Akonadi::Collection hiddenImapCol( imapCollection ); - hiddenImapCol.attribute( Akonadi::Collection::AddIfMissing ); - KJob *job = new Akonadi::CollectionModifyJob( hiddenImapCol, this ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(checkResult(KJob*)) ); - } - if ( !HandlerManager::isKolabFolder( imapCollection ) && imapCollection.hasAttribute()) { - Akonadi::Collection unhiddenImapCol( imapCollection ); - unhiddenImapCol.removeAttribute(); - KJob *job = new Akonadi::CollectionModifyJob( unhiddenImapCol, this ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(checkResult(KJob*)) ); - } -} - -void KolabProxyResource::checkResult(KJob* job) -{ - if ( job->error() ) { - kWarning() << "Error occurred: " << job->errorString(); - } -} - -AKONADI_RESOURCE_MAIN( KolabProxyResource ) diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/kolabproxyresource.desktop kdepim-runtime-15.08.0/resources/kolabproxy/kolabproxyresource.desktop --- kdepim-runtime-4.14.6/resources/kolabproxy/kolabproxyresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/kolabproxyresource.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -[Desktop Entry] -Name=Kolab Groupware Server (legacy) -Name[bs]=Kolab Groupware Server (stariji) -Name[ca]=Servidor de treball en grup Kolab (llegat) -Name[da]=Kolab groupware-server (forældet) -Name[de]=Kolab-Groupware-Server (veraltet) -Name[en_GB]=Kolab Groupware Server (legacy) -Name[es]=Servidor de trabajo en grupo Kolab (heredado) -Name[et]=Kolabi grupitöö server (pärand) -Name[fi]=Kolab-työryhmäpalvelin (vanha) -Name[fr]=Serveur de logiciels de collaboration Kolab (historique) -Name[hu]=Kolab csoportmunka-kiszolgáló (örökölt) -Name[it]=Server di groupware Kolab (legacy) -Name[ko]=Kolab 그룹웨어 서버(레거시) -Name[nb]=Kolab groupware-tjener (gammeldags) -Name[nds]=Kolab-Arbeitkoppel-Server (öller) -Name[nl]=Kolab groupwareserver (oude versie) -Name[pl]=Serwer Kolab Groupware (przestarzały) -Name[pt]=Servidor de Groupware Kolab (antigo) -Name[pt_BR]=Servidor Groupware Kolab (antigo) -Name[sk]=Groupware Server Kolab (starý) -Name[sr]=Колабов групверски сервер (застарело) -Name[sr@ijekavian]=Колабов групверски сервер (застарело) -Name[sr@ijekavianlatin]=Kolabov grupverski server (zastarelo) -Name[sr@latin]=Kolabov grupverski server (zastarelo) -Name[sv]=Kolab grupprogramserver (föråldrad) -Name[tr]=Kolab Groupware Sunucusu (miras) -Name[uk]=Сервер групової роботи Kolab (застаріле) -Name[x-test]=xxKolab Groupware Server (legacy)xx -Name[zh_TW]=Kolab 群組伺服器(傳統) -Comment=Provides access to Kolab groupware folders on an IMAP server (IMAP accounts need to be set up separately). This resource is obsolete, use the Kolab Groupware Server resource instead. -Comment[bs]=Omogućava pristup folderima kolaborativnog softvera na IMAP server (IMAP računi trebaju biti uspostavljeni odvojeno). Ovaj resutrs je zastario, koristite Kolab Groupware Server umjesto toga. -Comment[ca]=Proporciona accés a les carpetes de treball en grup Kolab en un servidor IMAP (els comptes IMAP s'han de configurar per separat). Aquest recurs és obsolet, en el seu lloc useu el recurs del servidor de treball en grup del Kolab. -Comment[da]=Giver adgang til Kolab groupware-mapper på en IMAP-server (IMAP-konti skal sættes op separat). Denne ressource er forældet, brug ressourcen til Kolab Groupware Server i stedet for. -Comment[de]=Ermöglicht den Zugriff auf Kolab-Groupware-Ordner auf einem Kolab-IMAP-Server. Diese Ressource ist veraltet, verwenden Sie statt dessen Ressource Kolab-Groupware-Server. -Comment[en_GB]=Provides access to Kolab groupware folders on an IMAP server (IMAP accounts need to be set up separately). This resource is obsolete, use the Kolab Groupware Server resource instead. -Comment[es]=Proporciona acceso a carpetas de trabajo en grupo de Kolab en un servidor IMAP (las cuentas IMAP necesitan ser configuradas por separado). Este recurso es obsoleto, usar el servidor de colaboración Kolab en su lugar. -Comment[et]=Ligipääsu tagamine Kolabi grupitöökaustadele IMAP serveris (IMAP kontod tuleb eraldi seadistada). See ressurss on iganenud, kasuta selle asemel Kolabi grupitöö serverit. -Comment[fi]=Tarjoaa pääsyn Kolab-työryhmäkansioihin IMAP-palvelimella (IMAP-tilit täytyy luoda erikseen). Tämä resurssi on vanha. Käytä tämän sijaan Kolab-työryhmäpalvelinta. -Comment[fr]=Fournit l'accès aux dossiers de logiciels de collaboration Kolab sur un serveur IMAP (il est nécessaire de configurer les comptes IMAP séparément). Cette ressource est obsolète. Utilisez la ressource Kolab. -Comment[hu]=Hozzáférést biztosít a Kolab csoportmunka-mappákhoz egy IMAP kiszolgálón (külön IMAP azonosítók beállítása szükséges). Ez az erőforrás elavult, használja helyette a Kolab csoportmunka-kiszolgálót. -Comment[it]=Fornisce l'accesso a cartelle di groupware Kolab su un server IMAP (gli account IMAP devono essere impostati separatamente). Questa risorsa è obsoleta, usa invece la risorsa «Server di groupware Kolab». -Comment[ko]=IMAP 서버에 있는 Kolab 그룹웨어 폴더에 접근합니다(IMAP 계정은 별도로 설정해야 함). 이 자원은 오래되었으므로 Kolab 그룹웨어 서버 자원을 사용하십시오. -Comment[nb]=Gir tilgang til Kolab gruppevaremapper på en IMAP-tjener (IMAP-kontoer må settes opp separat). Denne ressursen er utdatert, bruk i stedet ressursen Kolab groupware-tjener. -Comment[nds]=Stellt Togriep op Kolab-Arbeitkoppel-Ornern op en IMAP-Server praat (IMAP-Kontos mööt enkelt inricht warrn). Disse Ressource is överhaalt, bruuk ansteed bitte de Kolab-Arbeitkoppelserver-Ressource. -Comment[nl]=Levert toegang tot Kolab groupwaremappen op een IMAP-server (het is nodig om IMAP-accounts separaat in te stellen). Deze hulpbron is verouderd, gebruik in plaats daarvan de Kolab groupwareserver. -Comment[pl]=Zapewnia dostęp do katalogów do pracy grupowej Kolab na serwerze IMAP (konta IMAP muszą zostać ustawione osobno). Zasób ten jest przestarzały, zamiast niego użyj Serwera Kolab Groupware. -Comment[pt]=Oferece o acesso às pastas de 'groupware' do Kolab num servidor IMAP (as contas de IMAP têm de ser definidas em separado). Esta funcionalidade é obsoleta - use o recurso do Servidor de 'Groupware' Kolab em alternativa. -Comment[pt_BR]=Fornece acesso as pastas groupware Kolab em um servidor IMAP (as contas IMAP precisam ser definidas separadamente). Este recurso está obsoleto - use o recurso do Servidor Groupware Kolab como alternativa. -Comment[sk]=Poskytuje prístup k priečinkom Kolab groupware na IMAP serveri (IMAP účty musia byť nastavené oddelene). Tento zdroj je zastaralý, použite namiesto neho Server Kolab Groupware. -Comment[sr]=Омогућава приступ Колабовим групверским фасциклама на ИМАП серверу (ИМАП налози се морају одвојено поставити). Овај ресурс је застарео, користите уместо њега ресурс „Колабов групверски сервер“. -Comment[sr@ijekavian]=Омогућава приступ Колабовим групверским фасциклама на ИМАП серверу (ИМАП налози се морају одвојено поставити). Овај ресурс је застарео, користите уместо њега ресурс „Колабов групверски сервер“. -Comment[sr@ijekavianlatin]=Omogućava pristup Kolabovim grupverskim fasciklama na IMAP serveru (IMAP nalozi se moraju odvojeno postaviti). Ovaj resurs je zastareo, koristite umesto njega resurs „Kolabov grupverski server“. -Comment[sr@latin]=Omogućava pristup Kolabovim grupverskim fasciklama na IMAP serveru (IMAP nalozi se moraju odvojeno postaviti). Ovaj resurs je zastareo, koristite umesto njega resurs „Kolabov grupverski server“. -Comment[sv]=Ger tillgång till Kolab grupprogramkorgar på en IMAP-server (IMAP-konton måste ställas in separat). Resursen är föråldrad, använd istället Kolab grupprogramserver. -Comment[tr]=Bir IMAP sunucusu üzerindeki Kolab groupware klasörlerine erişim sağlar (IMAP hesabı ayrıca ayarlanmalıdır). Bu kaynak artık kullanılmadığından onun yerine Kolab Groupware Sunucu kaynağını kullanın. -Comment[uk]=Надає доступ до тек групової роботи Kolab на сервері IMAP (облікові записи IMAP слід налаштувати окремо). Цей ресурс вважається застарілим, замість нього слід використовувати ресурс сервера групової роботи Kolab. -Comment[x-test]=xxProvides access to Kolab groupware folders on an IMAP server (IMAP accounts need to be set up separately). This resource is obsolete, use the Kolab Groupware Server resource instead.xx -Comment[zh_TW]=提供存取某 IMAP 伺服器上的 Kolab 群組資料夾(IMAP 帳號要分別設定)。此資源已廢棄,請改用 Kolab 群組伺服器資源。 -Type=AkonadiResource -Exec=akonadi_kolabproxy_resource -Icon=kolab - -X-Akonadi-MimeTypes=text/directory,text/calendar,application/x-vnd.kde.contactgroup,application/x-vnd.akonadi.calendar.event,application/x-vnd.akonadi.calendar.todo,application/x-vnd.akonadi.calendar.journal,application/x-vnd.akonadi.calendar.freebusy,text/x-vnd.akonadi.note -X-Akonadi-Capabilities=Resource,Unique -X-Akonadi-Identifier=akonadi_kolabproxy_resource diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/kolabproxyresource.h kdepim-runtime-15.08.0/resources/kolabproxy/kolabproxyresource.h --- kdepim-runtime-4.14.6/resources/kolabproxy/kolabproxyresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/kolabproxyresource.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,144 +0,0 @@ -/* - Copyright (c) 2009 Andras Mantia - Copyright (c) 2012 Christian Mollekopf - - 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 KOLABPROXY_KOLABPROXYRESOURCE_H -#define KOLABPROXY_KOLABPROXYRESOURCE_H - -#include "kolabhandler.h" -#include "handlermanager.h" - -#include - -class FreeBusyUpdateHandler; - -namespace Akonadi { - class Monitor; -} - -class KolabProxyResource : public Akonadi::ResourceBase, - public Akonadi::AgentBase::ObserverV2 -{ - Q_OBJECT - - public: - explicit KolabProxyResource( const QString &id ); - ~KolabProxyResource(); - - /** - * Creates a new KolabHandler for @p imapCollection given it actually is - * a Kolab folder. - * - * @return @c true if @p imapCollection is a Kolab folder, @c false otherwise. - */ - bool registerHandlerForCollection( const Akonadi::Collection &imapCollection ); - - QString imapResourceForCollection( Akonadi::Collection::Id id ); - - void updateHiddenAttribute( const Akonadi::Collection &imapCollection ); - - public Q_SLOTS: - virtual void configure( WId windowId ); - - protected Q_SLOTS: - void retrieveCollections(); - - void retrieveItems( const Akonadi::Collection &col ); - - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - - void imapItemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - - void imapItemMoved( const Akonadi::Item &item, - const Akonadi::Collection &collectionSource, - const Akonadi::Collection &collectionDestination ); - - void imapItemRemoved( const Akonadi::Item &item ); - - void imapCollectionAdded( const Akonadi::Collection &collection, - const Akonadi::Collection &parent ); - - void imapCollectionRemoved( const Akonadi::Collection &collection ); - - void imapCollectionChanged( const Akonadi::Collection &collection ); - - void imapCollectionMoved( const Akonadi::Collection &collection, - const Akonadi::Collection &source, - const Akonadi::Collection &destination ); - - void retrieveItemFetchDone( KJob * ); - void retrieveItemsFetchDone( KJob * ); - void retrieveCollectionsTreeDone( KJob *job ); - - protected: - virtual void aboutToQuit(); - - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); - - virtual void itemMoved( const Akonadi::Item &item, - const Akonadi::Collection &collectionSource, - const Akonadi::Collection &collectionDestination ); - - virtual void itemRemoved( const Akonadi::Item &item ); - - virtual void collectionAdded( const Akonadi::Collection &collection, - const Akonadi::Collection &parent ); - - virtual void collectionChanged( const Akonadi::Collection &collection ); - - // do not hide the other variant, use implementation from base class - // which just forwards to the one above - using Akonadi::AgentBase::ObserverV2::collectionChanged; - virtual void collectionMoved( const Akonadi::Collection &collection, - const Akonadi::Collection &source, - const Akonadi::Collection &destination ); - - virtual void collectionRemoved( const Akonadi::Collection &collection ); - - private: - Akonadi::Collection createCollection( const Akonadi::Collection &imapCollection ); - void createItem( const Akonadi::Collection &imapCollection, const Akonadi::Item &kolabItem ); - - void applyAttributesToImap( Akonadi::Collection &imapCollection, - const Akonadi::Collection &kolabCollection ); - - void applyAttributesFromImap( Akonadi::Collection &kolabCollection, - const Akonadi::Collection &imapCollection ); - - void updateFreeBusyInformation( const Akonadi::Collection &imapCollection ); - - private slots: - void onItemAddedDone(KJob *job); - void onItemChangedDone(KJob *job); - void imapFolderCreateResult( KJob *job ); - void kolabFolderChangeResult( KJob *job ); - void checkResult( KJob *job ); - - private: - void showErrorMessage(const QString &); - void removeFolder( const Akonadi::Collection &imapCollection ); - Akonadi::Monitor *m_monitor; - Akonadi::Monitor *m_collectionMonitor; - QList m_excludeAppend; - FreeBusyUpdateHandler *m_freeBusyUpdateHandler; - QScopedPointer mHandlerManager; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/kolabproxyresource.kcfg kdepim-runtime-15.08.0/resources/kolabproxy/kolabproxyresource.kcfg --- kdepim-runtime-4.14.6/resources/kolabproxy/kolabproxyresource.kcfg 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/kolabproxyresource.kcfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ - - - - - - - false - - - - true - - - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/kolabsettings.ui kdepim-runtime-15.08.0/resources/kolabproxy/kolabsettings.ui --- kdepim-runtime-4.14.6/resources/kolabproxy/kolabsettings.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/kolabsettings.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,195 +0,0 @@ - - - SetupKolabView - - - - 0 - 0 - 667 - 491 - - - - - QLayout::SetMinimumSize - - - - - - 75 - true - - - - Account Type: Kolab Account - - - - - - - - - - 1 - - - - - - - The kolab resource needs an Imap resource. - - - - - - - Add Imap Resource - - - - - - - - - - - - - Select IMAP-Account: - - - true - - - - - - - IMAP-Account used for Kolab-Groupware. - - - - - - - - - - 0 - 0 - - - - Account Settings - - - - QLayout::SetMinimumSize - - - QFormLayout::ExpandingFieldsGrow - - - - - Create/Recover KolabFolders in IMAP-Account: - - - - - - - Ensure that Kolab-Groupware-Folders are existing in IMAP-Account. - - - Create Kolab Folders - - - - - - - Current Format Version: - - - - - - - Change the Kolab-Format Version: - - - - - - - Convert Account to different format version. - - - Change Format Version - - - - - - - TextLabel - - - - - - - - - - Note that the Kolab-Resource will use all available IMAP accounts that contain Kolab folders to provide Groupware-Data. The selection below applies to the settings only. - - - true - - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 40 - - - - - - - - - KSeparator - QFrame -
kseparator.h
- 1 -
- - KComboBox - QComboBox -
kcombobox.h
-
-
- - -
diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/Messages.sh kdepim-runtime-15.08.0/resources/kolabproxy/Messages.sh --- kdepim-runtime-4.14.6/resources/kolabproxy/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -#! /usr/bin/env bash -$EXTRACTRC *.ui *.kcfg >> rc.cpp -$XGETTEXT *.cpp -o $podir/akonadi_kolabproxy_resource.pot diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/notehandler.cpp kdepim-runtime-15.08.0/resources/kolabproxy/notehandler.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/notehandler.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/notehandler.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - Copyright (c) 2012 Christian Mollekopf - - 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 "notehandler.h" -#include - -NotesHandler::NotesHandler( const Akonadi::Collection &imapCollection ) - : JournalHandler( imapCollection ) -{ - m_mimeType = "application/x-vnd.kolab.note"; -} - -QStringList NotesHandler::contentMimeTypes() -{ - return QStringList() << QLatin1String( "text/x-vnd.akonadi.note" ); -} - -bool NotesHandler::toKolabFormat( const Akonadi::Item &item, Akonadi::Item &imapItem ) -{ - if ( item.hasPayload() ) { - KMime::Message::Ptr note = item.payload(); - KMime::Message::Ptr msg = Kolab::KolabObjectWriter::writeNote( note, m_formatVersion ); - if ( checkForErrors( item.id() ) ) { - return false; - } - imapItem.setMimeType( QLatin1String("message/rfc822") ); - imapItem.setPayload( msg ); - } else { - kWarning() << "Payload is not a note!"; - return false; - } - return true; -} - -Akonadi::Item::List NotesHandler::translateItems( const Akonadi::Item::List &kolabItems ) -{ - Akonadi::Item::List newItems; - foreach ( const Akonadi::Item &item, kolabItems ) { - if ( !item.hasPayload() ) { - kWarning() << "Payload is not a MessagePtr!"; - continue; - } - const KMime::Message::Ptr payload = item.payload(); - Akonadi::Item noteItem( QLatin1String("text/x-vnd.akonadi.note") ); - bool ret = noteFromKolab( payload, noteItem ); - if ( checkForErrors( item.id() ) ) { - continue; - } - if ( ret ) { - noteItem.setRemoteId( QString::number( item.id() ) ); - newItems.append( noteItem ); - } else { - kWarning() << "Failed to convert kolab item ( id:" << item.id() - << "rid:" << item.remoteId() << ") to Note message"; - continue; - } - } - - return newItems; -} - -QString NotesHandler::iconName() const -{ - return QString::fromLatin1( "view-pim-notes" ); -} - -bool NotesHandler::noteFromKolab( const KMime::Message::Ptr &kolabMsg, Akonadi::Item ¬eItem ) -{ - Kolab::KolabObjectReader reader( kolabMsg ); - if ( reader.getType() != Kolab::NoteObject ) { - return false; - } - noteItem.setPayload( reader.getNote() ); - return true; -} - -QString NotesHandler::extractGid(const Akonadi::Item& kolabItem) -{ - if ( !kolabItem.hasPayload() ) { - kWarning() << "Payload is not a MessagePtr!"; - return QString(); - } - const KMime::Message::Ptr payload = kolabItem.payload(); - const Akonadi::NoteUtils::NoteMessageWrapper note(payload); - return note.uid(); -} - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/notehandler.h kdepim-runtime-15.08.0/resources/kolabproxy/notehandler.h --- kdepim-runtime-4.14.6/resources/kolabproxy/notehandler.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/notehandler.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - Copyright (c) 2012 Christian Mollekopf - - 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 KOLABPROXY_NOTEHANDLER_H -#define KOLABPROXY_NOTEHANDLER_H - -#include "journalhandler.h" - -class NotesHandler : public JournalHandler -{ - public: - explicit NotesHandler( const Akonadi::Collection &imapCollection ); - - virtual Akonadi::Item::List translateItems( const Akonadi::Item::List &kolabItems ); - virtual bool toKolabFormat( const Akonadi::Item &item, Akonadi::Item &imapItem ); - virtual QStringList contentMimeTypes(); - virtual QString iconName() const; - - virtual QString extractGid(const Akonadi::Item& kolabItem); - - private: - bool noteFromKolab( const KMime::Message::Ptr &kolabMsg, Akonadi::Item ¬eItem ); - void noteToKolab( const KMime::Message::Ptr ¬e, Akonadi::Item &kolabItem ); - -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/org.freedesktop.Akonadi.kolabproxy.xml kdepim-runtime-15.08.0/resources/kolabproxy/org.freedesktop.Akonadi.kolabproxy.xml --- kdepim-runtime-4.14.6/resources/kolabproxy/org.freedesktop.Akonadi.kolabproxy.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/org.freedesktop.Akonadi.kolabproxy.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ - - - - - - - - - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/revertitemchangesjob.cpp kdepim-runtime-15.08.0/resources/kolabproxy/revertitemchangesjob.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/revertitemchangesjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/revertitemchangesjob.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 "revertitemchangesjob.h" -#include -#include -#include -#include - -RevertItemChangesJob::RevertItemChangesJob(const Akonadi::Item& kolabItem, HandlerManager &handlerManager, QObject* parent) - :KJob(parent), - mHandlerManager(handlerManager), - mKolabItem(kolabItem) -{ - -} - -void RevertItemChangesJob::start() -{ - Akonadi::ItemFetchJob *itemFetchJob = new Akonadi::ItemFetchJob(kolabToImap(mKolabItem), this); - itemFetchJob->fetchScope().fetchFullPayload(); - itemFetchJob->fetchScope().setAncestorRetrieval(Akonadi::ItemFetchScope::Parent); - connect(itemFetchJob, SIGNAL(result(KJob*)), SLOT(onImapItemFetchDone(KJob*))); -} - -void RevertItemChangesJob::onImapItemFetchDone(KJob* job) -{ - if ( job->error() ) { - setError(KJob::UserDefinedError); - setErrorText(job->errorText()); - emitResult(); - return; - } - - Akonadi::ItemFetchJob *fetchJob = qobject_cast(job); - if (fetchJob->items().isEmpty()) { //The corresponding imap item hasn't been created yet - kDebug() << "item is not yet created in imap resource, deleting the kolab item"; - Akonadi::ItemDeleteJob *deleteJob = new Akonadi::ItemDeleteJob(mKolabItem, this); - connect(deleteJob, SIGNAL(result(KJob*)), SLOT(onItemModifyDone(KJob*))); - } else { - kDebug() << "reverting to state of imap item"; - Akonadi::Item imapItem = fetchJob->items().first(); - const KolabHandler::Ptr handler = mHandlerManager.getHandler(imapItem.parentCollection().id()); - if (!handler) { - kWarning() << "No handler: " << imapItem.parentCollection().id(); - setError(KJob::UserDefinedError); - emitResult(); - return; - } - const Akonadi::Item::List translatedItems = handler->translateItems(fetchJob->items()); - - if (translatedItems.isEmpty()) { - kWarning() << "Failed to reload item: " << mKolabItem.id(); - setError(KJob::UserDefinedError); - emitResult(); - return; - } - Akonadi::Item kolabItem = translatedItems.first(); - kolabItem.setId(mKolabItem.id()); - Akonadi::ItemModifyJob *mjob = new Akonadi::ItemModifyJob(kolabItem); - connect(mjob, SIGNAL(result(KJob*)), SLOT(onItemModifyDone(KJob*))); - } -} - -void RevertItemChangesJob::onItemModifyDone(KJob *job) -{ - if (job->error()) { - setError(KJob::UserDefinedError); - setErrorText(job->errorText()); - } - emitResult(); -} diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/revertitemchangesjob.h kdepim-runtime-15.08.0/resources/kolabproxy/revertitemchangesjob.h --- kdepim-runtime-4.14.6/resources/kolabproxy/revertitemchangesjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/revertitemchangesjob.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 REVERTITEMCHANGESJOB -#define REVERTITEMCHANGESJOB - -#include -#include "handlermanager.h" - -/** - * Restore kolab item to the state of imapItem - */ -class RevertItemChangesJob: public KJob -{ - Q_OBJECT -public: - RevertItemChangesJob(const Akonadi::Item &kolabItem, HandlerManager &handlerManager, QObject* parent); - virtual void start(); - -private slots: - void onImapItemFetchDone(KJob* job); - void onItemModifyDone(KJob *job); - -private: - HandlerManager &mHandlerManager; - const Akonadi::Item mKolabItem; -}; - -#endif \ No newline at end of file diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/settings.kcfgc kdepim-runtime-15.08.0/resources/kolabproxy/settings.kcfgc --- kdepim-runtime-4.14.6/resources/kolabproxy/settings.kcfgc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/settings.kcfgc 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -File=kolabproxyresource.kcfg -ClassName=Settings -Mutators=true -ItemAccessors=true -SetUserTexts=true -Singleton=true -#IncludeFiles= -GlobalEnums=true diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/setupdefaultfoldersjob.cpp kdepim-runtime-15.08.0/resources/kolabproxy/setupdefaultfoldersjob.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/setupdefaultfoldersjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/setupdefaultfoldersjob.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,175 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - Copyright (c) 2012 Christian Mollekopf - - 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 "setupdefaultfoldersjob.h" - -#include "kolabdefs.h" - -#include "collectionannotationsattribute.h" //from shared - -#include -#include -#include -#include -#include - -#include - -SetupDefaultFoldersJob::SetupDefaultFoldersJob( const Akonadi::AgentInstance &instance, - QObject *parent ) - : Job( parent ), - m_agentInstance( instance ) -{ - Q_ASSERT( instance.isValid() ); -} - -void SetupDefaultFoldersJob::doStart() -{ - Akonadi::CollectionFetchJob *job = - new Akonadi::CollectionFetchJob( Akonadi::Collection::root(), - Akonadi::CollectionFetchJob::Recursive, this ); - job->fetchScope().setResource( m_agentInstance.identifier() ); - connect( job, SIGNAL(result(KJob*)), SLOT(collectionFetchResult(KJob*)) ); -} - -void SetupDefaultFoldersJob::collectionFetchResult( KJob *job ) -{ - if ( job->error() ) { - return; // Akonadi::Job propagates that automatically - } - - const Akonadi::Collection::List &collections = static_cast( job )->collections(); - - //FIXME: This should really look for the personal namespace, and use the folder there. - // As a workaround we try to use the inbox, and fallback to toplevel otherwise. - - // look for inbox - Akonadi::Collection defaultParent; - foreach ( const Akonadi::Collection &col, collections ) { - if ( !( col.rights() & Akonadi::Collection::CanCreateCollection ) ) { - continue; - } - Akonadi::EntityDisplayAttribute *attr = 0; - if ( ( attr = col.attribute() ) ) { - if ( attr->iconName() == QLatin1String( "mail-folder-inbox" ) ) { - defaultParent = col; - } - } - } - - if (!defaultParent.isValid()) { //get the toplevel collection as fallback - foreach ( const Akonadi::Collection &col, collections ) { - if ( col.parentCollection() == Akonadi::Collection::root() ) { - defaultParent = col; - } - } - } - - if (!defaultParent.isValid()) { - setError(KJob::UserDefinedError); - setErrorText(i18n("Could not find valid parent collection.")); - emitResult(); - } - kDebug() << "default parent " << defaultParent.id(); - - // look for existing folders - QVector existingDefaultFolders( KolabV2::FolderTypeSize ); - QVector recoveryCandidates( KolabV2::FolderTypeSize ); - foreach ( const Akonadi::Collection &col, collections ) { - if ( col.parentCollection() != defaultParent ) { - continue; - } - KolabV2::FolderType folderType = KolabV2::Mail; - Akonadi::CollectionAnnotationsAttribute *attr = 0; - if ( ( attr = col.attribute() ) ) { - folderType = - KolabV2::folderTypeFromString( Kolab::getFolderTypeAnnotation( attr->annotations() ) ); - } - KolabV2::FolderType guessedType = KolabV2::guessFolderTypeFromName( col.name() ); - - if ( folderType != KolabV2::Mail ) { - existingDefaultFolders[ folderType ] = col; - } else if ( guessedType != KolabV2::Mail ) { - recoveryCandidates[ guessedType ] = col; - } - } - - // create/fix folders - for ( int i = KolabV2::Contact; i < KolabV2::FolderTypeSize; ++i ) { - QString iconName; - if ( i == KolabV2::Mail ) { - //Nothing - } else if ( i == KolabV2::Contact ) { - iconName = QString::fromLatin1( "view-pim-contacts" ); - } else if ( i == KolabV2::Event ) { - iconName = QString::fromLatin1( "view-calendar" ); - } else if ( i == KolabV2::Task ) { - iconName = QString::fromLatin1( "view-calendar-tasks" ); - } else if ( i == KolabV2::Journal ) { - iconName = QString::fromLatin1( "view-pim-journal" ); - } else if ( i == KolabV2::Note ) { - iconName = QString::fromLatin1( "view-pim-notes" ); - } - - if ( existingDefaultFolders[ i ].isValid() ) { - kDebug() << "Existing collection ok: " << iconName; - continue; // all good - } else if ( recoveryCandidates[ i ].isValid() ) { - Akonadi::Collection col = recoveryCandidates[ i ]; - if ( !( col.rights() & Akonadi::Collection::CanChangeCollection ) ) { - kWarning() << "no change rights on collection"; - continue; - } - Akonadi::CollectionAnnotationsAttribute *attr = - col.attribute( Akonadi::Entity::AddIfMissing ); - - QMap annotations; - Kolab::setFolderTypeAnnotation( annotations, KolabV2::folderTypeToString( static_cast( i ), true ) ); - attr->setAnnotations( annotations ); - if ( !iconName.isEmpty() ) { - Akonadi::EntityDisplayAttribute *attribute = - col.attribute( Akonadi::Entity::AddIfMissing ); - attribute->setIconName( iconName ); - } - kDebug() << "Fixing collection: " << col.id() << iconName; - new Akonadi::CollectionModifyJob( col, 0 ); - } else { - Akonadi::Collection col; - col.setName( KolabV2::nameForFolderType( static_cast( i ) ) ); - col.setParentCollection( defaultParent ); - Akonadi::CollectionAnnotationsAttribute *attr = - col.attribute( Akonadi::Entity::AddIfMissing ); - - QMap annotations; - Kolab::setFolderTypeAnnotation( annotations, KolabV2::folderTypeToString( static_cast( i ), true ) ); - attr->setAnnotations( annotations ); - if ( !iconName.isEmpty() ) { - Akonadi::EntityDisplayAttribute *attribute = - col.attribute( Akonadi::Entity::AddIfMissing ); - attribute->setIconName( iconName ); - } - kDebug() << "Creating new collection: " << iconName; - new Akonadi::CollectionCreateJob( col, 0 ); - } - } - - emitResult(); -} - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/setupdefaultfoldersjob.h kdepim-runtime-15.08.0/resources/kolabproxy/setupdefaultfoldersjob.h --- kdepim-runtime-4.14.6/resources/kolabproxy/setupdefaultfoldersjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/setupdefaultfoldersjob.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -/* - Copyright (c) 2010 Volker Krause - Copyright (c) 2012 Christian Mollekopf - - 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 KOLABPROXY_SETUPDEFAULTFOLDERSJOB_H -#define KOLABPROXY_SETUPDEFAULTFOLDERSJOB_H - -#include -#include - -class SetupDefaultFoldersJob : public Akonadi::Job -{ - Q_OBJECT - public: - explicit SetupDefaultFoldersJob( const Akonadi::AgentInstance &instance, QObject *parent = 0 ); - - protected: - void doStart(); - - private slots: - void collectionFetchResult( KJob *job ); - - private: - Akonadi::AgentInstance m_agentInstance; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/setupkolab.cpp kdepim-runtime-15.08.0/resources/kolabproxy/setupkolab.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/setupkolab.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/setupkolab.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,228 +0,0 @@ -/* - Copyright (c) 2010-2015 Laurent Montel - Copyright (c) 2012 Christian Mollekopf - - 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 "setupkolab.h" - -#include "kolabproxyresource.h" -#include "setupdefaultfoldersjob.h" -#include "upgradejob.h" - -#include - -#include -#include - -#include - -#define IMAP_RESOURCE_IDENTIFIER QLatin1String("akonadi_imap_resource") - -SetupKolab::SetupKolab( KolabProxyResource *parentResource ) - : KDialog(), - m_ui( new Ui::SetupKolabView ), - m_versionUi( new Ui::ChangeFormatView ), - m_parentResource( parentResource ) -{ - m_ui->setupUi( mainWidget() ); - setButtons( Ok ); - initConnection(); - updateCombobox(); -} - -SetupKolab::~SetupKolab() -{ - delete m_ui; - delete m_versionUi; -} - -KConfigGroup SetupKolab::getConfigGroup() -{ - //This is a bit of a hack, but we have to reload the config file in case it was edited by the setupwizard (it's not reloaded automatically). - //Without this the config will not be able to load the correct values until restarted (e.g. akonadiconsole). - KSharedConfigPtr config = KGlobal::mainComponent().config(); - config->reparseConfiguration(); - return KConfigGroup( KGlobal::mainComponent().config(), "KolabProxyResourceSettings" ); -} - -Kolab::Version SetupKolab::readKolabVersion( const QString &resourceIdentifier ) -{ - KConfigGroup grp( getConfigGroup() ); - if ( resourceIdentifier.isEmpty() ) { - return Kolab::KolabV3; - } - const QString key (QLatin1String("KolabFormatVersion") + resourceIdentifier ); - Kolab::Version version = static_cast( - grp.readEntry( key, static_cast( Kolab::KolabV3 ) ) ); - return version; -} - -void SetupKolab::initConnection() -{ - connect( m_ui->launchWizard, SIGNAL(clicked()), this, SLOT(slotLaunchWizard()) ); - connect( m_ui->createKolabFolderButton, SIGNAL(clicked()), - this, SLOT(slotCreateDefaultKolabCollections()) ); - connect( m_ui->upgradeFormatButton, SIGNAL(clicked()), - this, SLOT(slotShowUpgradeDialog()) ); - connect( m_ui->imapAccountComboBox, SIGNAL(currentIndexChanged(QString)), - this, SLOT(slotSelectedAccountChanged()) ); - connect( Akonadi::AgentManager::self(), SIGNAL(instanceAdded(Akonadi::AgentInstance)), - this, SLOT(slotInstanceAddedRemoved()) ); - connect( Akonadi::AgentManager::self(), SIGNAL(instanceRemoved(Akonadi::AgentInstance)), - this, SLOT(slotInstanceAddedRemoved()) ); -} - -void SetupKolab::slotShowUpgradeDialog() -{ - const Akonadi::AgentInstance instanceSelected = - m_agentList[m_ui->imapAccountComboBox->currentText()]; - - KDialog *dialog = new KDialog( this ); - dialog->setButtons( Ok ); - m_versionUi->setupUi( dialog->mainWidget() ); - m_versionUi->progressBar->setDisabled( true ); - connect( m_versionUi->pushButton, SIGNAL(clicked()), this, SLOT(slotDoUpgrade()) ); - - Kolab::Version v = readKolabVersion( instanceSelected.identifier() ); - - m_versionUi->formatVersion->insertItem( 0, i18n("Kolab Format v2"), Kolab::KolabV2 ); - m_versionUi->formatVersion->insertItem( 1, i18n("Kolab Format v3"), Kolab::KolabV3 ); - if ( v == Kolab::KolabV2 ) { - m_versionUi->formatVersion->setCurrentIndex( 0 ); - } else { - m_versionUi->formatVersion->setCurrentIndex( 1 ); - } - KConfigGroup grp( getConfigGroup() ); - m_versionUi->upgradeGroupBox->setEnabled( grp.readEntry("UpgradeEnabled", false) ); - dialog->exec(); - grp.writeEntry( - QLatin1String("KolabFormatVersion") + instanceSelected.identifier(), - m_versionUi->formatVersion->itemData( m_versionUi->formatVersion->currentIndex() ) ); - grp.sync(); - slotSelectedAccountChanged(); - dialog->deleteLater(); -} - -void SetupKolab::slotDoUpgrade() -{ - const Akonadi::AgentInstance instanceSelected = - m_agentList[m_ui->imapAccountComboBox->currentText()]; - - m_versionUi->statusLabel->setText( i18n("Started") ); - m_versionUi->progressBar->setEnabled( true ); - - UpgradeJob *job = - new UpgradeJob( - static_cast( - m_versionUi->formatVersion->itemData( - m_versionUi->formatVersion->currentIndex() ).toInt() ), - instanceSelected, this ); - - connect( job, SIGNAL(percent(KJob*,ulong)), - this, SLOT(slotUpgradeProgress(KJob*,ulong)) ); - connect( job, SIGNAL(result(KJob*)), - this, SLOT(slotUpgradeDone(KJob*)) ); -} - -void SetupKolab::slotUpgradeProgress( KJob *job, ulong value ) -{ - Q_UNUSED( job ); - m_versionUi->progressBar->setValue( value ); -} - -void SetupKolab::slotUpgradeDone( KJob *job ) -{ - if ( job->error() ) { - kWarning() << job->errorString(); - m_versionUi->statusLabel->setText( i18n("Error") ); - KMessageBox::error( - this, - i18n( "Could not complete the upgrade process: " ) + job->errorString(), - i18n( "Error during Upgrade Process" ) ); - return; - } - m_versionUi->statusLabel->setText( i18n("Complete") ); - m_versionUi->progressBar->setValue( 100 ); -} - -void SetupKolab::slotSelectedAccountChanged() -{ - const Akonadi::AgentInstance instanceSelected = - m_agentList[m_ui->imapAccountComboBox->currentText()]; - - Kolab::Version v = readKolabVersion( instanceSelected.identifier() ); - - if ( v == Kolab::KolabV2 ) { - m_ui->formatVersion->setText( i18n("Kolab Format v2") ); - } else { - m_ui->formatVersion->setText( i18n("Kolab Format v3") ); - } -} - -void SetupKolab::updateCombobox() -{ - bool imapAccountFound = false; - m_ui->imapAccountComboBox->clear(); - m_agentList.clear(); - - foreach ( const Akonadi::AgentInstance &instance, Akonadi::AgentManager::self()->instances() ) { - if ( instance.identifier().contains( IMAP_RESOURCE_IDENTIFIER ) ) { - const QString instanceName = instance.name(); - m_agentList.insert( instanceName, instance ); - m_ui->imapAccountComboBox->addItem( instanceName ); - imapAccountFound = true; - } - } - if ( imapAccountFound ) { - m_ui->stackedWidget->setCurrentIndex( 1 ); - } else { - m_ui->stackedWidget->setCurrentIndex( 0 ); - } -} - -void SetupKolab::slotLaunchWizard() -{ - QStringList lst; - lst.append( QLatin1String("--assistant" )); - lst.append( QLatin1String("imap") ); - - const QString path = KStandardDirs::findExe( QLatin1String( "accountwizard" ) ); - if ( !QProcess::startDetached( path, lst ) ) { - KMessageBox::error( - this, - i18n( "Could not start the account wizard. " - "Please check your installation." ), - i18n( "Unable to start account wizard" ) ); - } -} - -void SetupKolab::slotInstanceAddedRemoved() -{ - updateCombobox(); -} - -void SetupKolab::slotCreateDefaultKolabCollections() -{ - const Akonadi::AgentInstance instanceSelected = - m_agentList[m_ui->imapAccountComboBox->currentText()]; - - if ( instanceSelected.isValid() ) { - new SetupDefaultFoldersJob( instanceSelected, this ); - } -} - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/setupkolab.h kdepim-runtime-15.08.0/resources/kolabproxy/setupkolab.h --- kdepim-runtime-4.14.6/resources/kolabproxy/setupkolab.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/setupkolab.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -/* - Copyright (c) 2010-2015 Laurent Montel - Copyright (c) 2012 Christian Mollekopf - - 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 KOLABPROXY_SETUPKOLAB_H -#define KOLABPROXY_SETUPKOLAB_H - -#include "ui_changeformat.h" -#include "ui_kolabsettings.h" - -#include - -#include -#include - -class KolabProxyResource; - -class KJob; - -class SetupKolab : public KDialog -{ - Q_OBJECT - - public: - explicit SetupKolab( KolabProxyResource *parentResource ); - ~SetupKolab(); - - static KConfigGroup getConfigGroup(); - static Kolab::Version readKolabVersion( const QString &resourceIdentifier ); - - protected: - void initConnection(); - void updateCombobox(); - - protected slots: - void slotLaunchWizard(); - void slotInstanceAddedRemoved(); - void slotCreateDefaultKolabCollections(); - void slotShowUpgradeDialog(); - void slotDoUpgrade(); - void slotSelectedAccountChanged(); - void slotUpgradeProgress( KJob *, ulong ); - void slotUpgradeDone( KJob * ); - - private: - QMap m_agentList; - Ui::SetupKolabView *m_ui; - Ui::ChangeFormatView *m_versionUi; - KolabProxyResource *m_parentResource; -}; - -#endif /* SETUPKOLAB_H */ - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/taskshandler.cpp kdepim-runtime-15.08.0/resources/kolabproxy/taskshandler.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/taskshandler.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/taskshandler.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -/* - Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Copyright (c) 2009 Andras Mantia - Copyright (c) 2012 Christian Mollekopf - - 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 "taskshandler.h" - -TasksHandler::TasksHandler( const Akonadi::Collection &imapCollection ) - : IncidenceHandler( imapCollection ) -{ - m_mimeType = "application/x-vnd.kolab.task"; -} - -TasksHandler::~TasksHandler() -{ -} - -KMime::Message::Ptr TasksHandler::incidenceToMime( const KCalCore::Incidence::Ptr &incidence ) -{ - return - Kolab::KolabObjectWriter::writeTodo( - incidence.dynamicCast(), - m_formatVersion, PRODUCT_ID, QLatin1String("UTC") ); -} - -QStringList TasksHandler::contentMimeTypes() -{ - return QStringList() << KCalCore::Todo::todoMimeType(); -} - -QString TasksHandler::iconName() const -{ - return QString::fromLatin1( "view-calendar-tasks" ); -} diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/taskshandler.h kdepim-runtime-15.08.0/resources/kolabproxy/taskshandler.h --- kdepim-runtime-4.14.6/resources/kolabproxy/taskshandler.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/taskshandler.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -/* - Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Copyright (c) 2009 Andras Mantia - Copyright (c) 2012 Christian Mollekopf - - 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 KOLABPROXY_TASKSHANDLER_H -#define KOLABPROXY_TASKSHANDLER_H - -#include "incidencehandler.h" - -/** - @author Andras Mantia -*/ -class TasksHandler : public IncidenceHandler -{ - public: - explicit TasksHandler( const Akonadi::Collection &imapCollection ); - virtual ~TasksHandler(); - virtual QStringList contentMimeTypes(); - virtual QString iconName() const; - - private: - virtual KMime::Message::Ptr incidenceToMime( const KCalCore::Incidence::Ptr &incidence ); - -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/clientsidetest.cpp kdepim-runtime-15.08.0/resources/kolabproxy/tests/clientsidetest.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/clientsidetest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/clientsidetest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,237 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include //libkolab -#include - -#include "../kolabdefs.h" -#include "testutils.h" - -Q_DECLARE_METATYPE(QSet) - -using namespace Akonadi; - -/* - * Tests clientside actions against the kolab proxy, such as creating an item. - */ -class ClientSideTest : public QObject -{ - Q_OBJECT - - AgentInstance mInstance; - Akonadi::Collection imapCollection; - Akonadi::Collection kolabCollection; - -public: - ClientSideTest(): - QObject() - { - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType >(); - } - - void cleanup() { - //cleanup - Akonadi::ItemDeleteJob *deleteJob = new Akonadi::ItemDeleteJob(imapCollection); - deleteJob->exec(); - Akonadi::ItemDeleteJob *deleteJob2 = new Akonadi::ItemDeleteJob(kolabCollection); - deleteJob2->exec(); - QTest::qWait(TIMEOUT); - } - -private slots: - void initTestCase() { - AkonadiTest::checkTestIsIsolated(); - AttributeFactory::registerAttribute(); - - const AgentType type = AgentManager::self()->type("akonadi_kolabproxy_resource"); - AgentInstanceCreateJob *agentCreateJob = new AgentInstanceCreateJob(type); - AKVERIFYEXEC(agentCreateJob); - mInstance = agentCreateJob->instance(); - - //Wait for kolabproxy to create all folders - QVERIFY(TestUtils::ensurePopulated(mInstance.identifier(), 6)); - - Akonadi::CollectionPathResolver *resolver = new CollectionPathResolver(QLatin1String("res1/Calendar"), this); - AKVERIFYEXEC(resolver); - imapCollection = Akonadi::Collection( resolver->collection() ); - QVERIFY(imapCollection.isValid()); - - kolabCollection = TestUtils::findCollection(mInstance.identifier(), "Calendar"); - QVERIFY(kolabCollection.isValid()); - } - - void testItemCreate() - { - KDateTime date(QDate(2013,10,10), KDateTime::ClockTime); - date.setDateOnly(true); - - KCalCore::Event::Ptr event(new KCalCore::Event()); - event->setDtStart(date); - Akonadi::Item createdItem; - { - Akonadi::Item item(event->mimeType()); - item.setPayload(event); - Akonadi::ItemCreateJob *createJob = new Akonadi::ItemCreateJob(item, kolabCollection); - QVERIFY(TestUtils::ensure(imapCollection, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)), createJob)); - createdItem = createJob->item(); - QVERIFY(createdItem.isValid()); - } - - { - Akonadi::ItemFetchJob *fetchJob = new Akonadi::ItemFetchJob(imapCollection); - AKVERIFYEXEC(fetchJob); - QCOMPARE(fetchJob->items().size(), 1); -// const Akonadi::Item item = fetchJob->items().first(); -// QCOMPARE(item.id(), createdItem.remoteId().toLongLong()); - } - cleanup(); - } - - void testItemCreateFailure() - { - KCalCore::Event::Ptr event(new KCalCore::Event()); - //an event requires an start date, so this will fail - { - Akonadi::Item item(event->mimeType()); - item.setPayload(event); - Akonadi::ItemCreateJob *createJob = new Akonadi::ItemCreateJob(item, kolabCollection); - //Check that the signal is NOT emitted within the timeout - QVERIFY(!TestUtils::ensure(imapCollection, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)), createJob)); - //TODO akonadi currently doesn't support failing itemcreatejobs if the resource fails to store the item. - // the item will simply remain dirty in the akonadi server -// QVERIFY(createJob->error()); - } - - //Ensure the item has been removed by the kolabproxy - { - Akonadi::ItemFetchJob *fetchJob = new Akonadi::ItemFetchJob(kolabCollection); - AKVERIFYEXEC(fetchJob); - QCOMPARE(fetchJob->items().size(), 0); - } - } - - void testItemModify() - { - KDateTime date1(QDate(2013,10,10), KDateTime::ClockTime); - date1.setDateOnly(true); - KDateTime date2(QDate(2014,10,10), KDateTime::ClockTime); - date2.setDateOnly(true); - - KCalCore::Event::Ptr event(new KCalCore::Event()); - event->setDtStart(date1); - Akonadi::Item createdItem; - { - Akonadi::Item item(event->mimeType()); - item.setPayload(event); - Akonadi::ItemCreateJob *createJob = new Akonadi::ItemCreateJob(item, kolabCollection); - QVERIFY(TestUtils::ensure(imapCollection, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)), createJob)); - createdItem = createJob->item(); - QVERIFY(createdItem.isValid()); - } - - { - event->setDtStart(date2); - createdItem.setPayload(event); - Akonadi::ItemModifyJob *modifyJob = new Akonadi::ItemModifyJob(createdItem); - QVERIFY(TestUtils::ensure(imapCollection, SIGNAL(itemChanged(Akonadi::Item,QSet)), modifyJob)); - Akonadi::Item modifiedItem = modifyJob->item(); - QVERIFY(modifiedItem.hasPayload()); - QCOMPARE(modifiedItem.payload()->dtStart().toString(), date2.toString()); - } - - { - Akonadi::ItemFetchJob *fetchJob = new Akonadi::ItemFetchJob(imapCollection); - fetchJob->fetchScope().fetchFullPayload(true); - AKVERIFYEXEC(fetchJob); - QCOMPARE(fetchJob->items().size(), 1); - const Akonadi::Item item = fetchJob->items().first(); - QVERIFY(item.hasPayload()); - Kolab::KolabObjectReader reader(item.payload()); - QCOMPARE(reader.getEvent()->dtStart().toString(), date2.toString()); - } - cleanup(); - } - - void testItemModifyFailure() - { - KDateTime date1(QDate(2013,10,10), KDateTime::ClockTime); - date1.setDateOnly(true); - - KCalCore::Event::Ptr event(new KCalCore::Event()); - event->setDtStart(date1); - Akonadi::Item createdItem; - { - Akonadi::Item item(event->mimeType()); - item.setPayload(event); - Akonadi::ItemCreateJob *createJob = new Akonadi::ItemCreateJob(item, kolabCollection); - QVERIFY(TestUtils::ensure(imapCollection, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)), createJob)); - createdItem = createJob->item(); - QVERIFY(createdItem.isValid()); - } - - { - event->setDtStart(KDateTime()); - createdItem.setPayload(event); - Akonadi::ItemModifyJob *modifyJob = new Akonadi::ItemModifyJob(createdItem); - AKVERIFYEXEC(modifyJob); - QTest::qWait(TIMEOUT); - //FIXME this fails, no idea why -// QVERIFY(!TestUtils::ensure(imapCollection, SIGNAL(itemChanged(Akonadi::Item,QSet)), modifyJob)); - } - - //Ensure the change has been reverted for the kolab item - { - Akonadi::ItemFetchJob *fetchJob = new Akonadi::ItemFetchJob(kolabCollection); - fetchJob->fetchScope().fetchFullPayload(); - AKVERIFYEXEC(fetchJob); - QCOMPARE(fetchJob->items().size(), 1); - const Akonadi::Item item = fetchJob->items().first(); - QVERIFY(item.hasPayload()); - QCOMPARE(item.payload()->dtStart().toString(), date1.toString()); - } - cleanup(); - } - -}; - -QTEST_AKONADIMAIN( ClientSideTest, NoGUI ) - -#include "clientsidetest.moc" diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/CMakeLists.txt kdepim-runtime-15.08.0/resources/kolabproxy/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ - -include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. ) -set( RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) - -foreach( _file ${kolabproxyresource_shared_SRCS} ) - list( APPEND kolabproxy_shared_relative_SRCS "../${_file}" ) -endforeach() - -kde4_add_library(kolabresourcetest STATIC - ${kolabproxy_shared_relative_SRCS} - ${AKONADI_COLLECTIONATTRIBUTES_SHARED_SOURCES} - testutils.cpp -) - -kde4_add_unit_test(kolabconvertertest kolabconvertertest.cpp) -target_link_libraries(kolabconvertertest - kolabresourcetest - ${Libkolab_LIBRARIES} - ${KDEPIMLIBS_AKONADI_LIBS} - ${QT_QTXML_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ${KDE4_KIO_LIBS} - ${KDEPIMLIBS_KABC_LIBS} - ${KDEPIMLIBS_AKONADI_KMIME_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${QT_QTTEST_LIBRARY} - kdepim-copy - ${KDEPIMLIBS_KCALCORE_LIBS} -) - -#akonadi_add_resourcetest( imap-kolab imaptest-kolab.es ) -#akonadi_add_resourcetest( imap-dovecot imaptest-dovecot.es ) -#akonadi_add_resourcetest( kolab kolabtest.es ) - -set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) -include(AkonadiMacros) -set(KDEPIMLIBS_RUN_ISOLATED_TESTS TRUE) -set(KDEPIMLIBS_RUN_SQLITE_ISOLATED_TESTS TRUE) - -add_akonadi_isolated_test_advanced(proxyintegrationtest.cpp "" "kolabresourcetest;${Libkolab_LIBRARIES}") -add_akonadi_isolated_test_advanced(imapsignaltest.cpp "" "kolabresourcetest;${Libkolab_LIBRARIES}") -add_akonadi_isolated_test_advanced(clientsidetest.cpp "" "kolabresourcetest;${Libkolab_LIBRARIES}") diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/couriervm.conf kdepim-runtime-15.08.0/resources/kolabproxy/tests/couriervm.conf --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/couriervm.conf 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/couriervm.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -[Emulator] -Arguments=-m 256M -Ports=22,25,80,143,389,443,465,993 -WaitForPorts=22,25,143 -MonitorPort=23 -SnapshotName=running-server - -[Image] -Source=https://files.kolab.org/local/imapd-testing/qemu-courier-0.53.3-20090923/qemu-courier-server-20090923.tar.bz2 -File=qemu-courier-server/running-server.qcow2 diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/create_ldap_users.py kdepim-runtime-15.08.0/resources/kolabproxy/tests/create_ldap_users.py --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/create_ldap_users.py 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/create_ldap_users.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,276 +0,0 @@ -#!/usr/bin/env python -"""Create some few kolab users in ldap. - -Usage: - -create_ldap_users.py [-h hostname] [-p port] [-u admin_dn] [-n num] [-o offset] [-t type] [--member dnmember] basedn cmd [passwd] - -cmd may be one of - - add add num (default 10) users named autoNUM - - delete delete all users named auto*. deletion is done by setting - kolabDeleteFlag so that the kolabd will later remove the users. - -Host and port default to localhost and the standard ldap port. - -The type can be "user" (default) or "group". - -The admin_dn should be the initial part of the dn of the admin account -to use, that ist admin + ',cn=internal,' + base_dn will be used as the -dn for the ldap bind. The default is 'cn=manager'. - -Offset will be the start number for additions and deletion (default = 0). -of users only. - -dn_member is the dn of the initial member for groups. - - -Security considerations: - The connection is not encrypted by default and thus the password - can be sniffed. -""" - -# requires the python-ldap module from -# http://python-ldap.sourceforge.net/ -# on debian woody it's packaged as python-ldap - -#import random -import re -import sys -import getopt -import ldap -import ldap.dn -import ldap.modlist -import getpass -import time -import sha -import base64 -import httplib - -def open_ldap(ldapuri, admin_dn_part, pwd = None): - conn = ldap.initialize(ldapuri) - if not pwd: - pwd = getpass.getpass("ldap bind password:") - conn.simple_bind_s(admin_dn_part + "," + "cn=internal" + "," + base_dn, - pwd) - return conn - -def fetch_kolab_info(conn): - try: - return conn.search_s("k=kolab," + base_dn, ldap.SCOPE_BASE, - filterstr='(objectClass=*)')[0][1] - except ldap.INVALID_DN_SYNTAX: - # should only happen if the server is no Kolab server, because - # k=... is only valid on Kolab servers. Since the script should - # also support non-kolab servers to an extent, we return None to - # indicate that the server is no Kolab server. - return None - -def set_delete_flag(conn, filterstr, offset): - hosts = fetch_kolab_info(conn)["kolabHost"] - result = conn.search_s(base_dn, ldap.SCOPE_ONELEVEL, filterstr=filterstr) - for dn, attrs in result: - n = re.match(r'cn=[^,0-9]+(\d+),',dn).group(1) - if int(n) >= offset: - conn.modify_s(dn, [(ldap.MOD_ADD, "kolabDeleteFlag", hosts)]) - print dn, hosts - -def random_salt(length): - """Returns a random salt for use with salted password hashes""" - random = open("/dev/urandom") - try: - return random.read(length) - finally: - random.close() - -SSHA_PREFIX = "{SSHA}" -def encode_ssha(password, salt): - """SSHA-Encodes the password with the given salt""" - digester = sha.new(password) - digester.update(salt) - return SSHA_PREFIX + base64.b64encode(digester.digest() + salt) - -def encode_clear(password, salt): - return password - - -def mail_domain_from_basedn(base_dn): - """Determine the mail-domain from the dn. - The function simple concatenates the values of the dc=... parts of - the dn separated by periods.""" - print "mail_domain_from_basedn", base_dn - return ".".join([item[0][1] - for item in ldap.dn.str2dn(base_dn) if item[0][0] == "dc"]) - - -def add_user(conn, num_users, offset, set_password=None, - http_hostname="localhost", http_port=80): - common_attrs = { - 'objectClass': ['top', 'inetOrgPerson'], - } - - kolab_info = fetch_kolab_info(conn) - - if kolab_info: - mail_domain = kolab_info["postfix-mydomain"][0] - # use the first of the kolab hosts as home server. - kolab_home_server = kolab_info["kolabHost"][0] - - common_attrs['objectClass'].append("kolabInetOrgPerson") - common_attrs['kolabHomeServer'] = [kolab_home_server] - common_attrs['kolabInvitationPolicy'] = ['ACT_MANUAL'] - - password_encoder = encode_ssha - else: - # The server is not a Kolab server, which currently means that - # it's the courier server in the qemu image. Here, the password - # is unencrypted and the domain can be inferred from the base - # dn. - mail_domain = mail_domain_from_basedn(base_dn) - password_encoder = encode_clear - - if set_password is not None: - common_attrs["userPassword"] = password_encoder(set_password, random_salt(8)) - - users = [("test%d" % n, "auto", "autotest%d" % n) - for n in range(offset, num_users + offset)] - for sn, givenName, mailuid in users: - #time.sleep(random.randrange(0,4)) - descr = common_attrs.copy() - cn = givenName + " " + sn - descr["cn"] = [cn] - descr["givenName"] = [givenName] - descr["sn"] = [sn] - descr["mail"] = descr["uid"] = [mailuid + "@" + mail_domain] - dn = "cn=" + cn + "," + base_dn - print dn, descr - print conn.add_s(dn, ldap.modlist.addModlist(descr)) - - if not kolab_info: - # The server is not a Kolab server, which currently means that - # it's the courier server in the qemu image which requires an - # extra step to finish the user creation process. - conn = httplib.HTTPConnection(http_hostname, http_port) - conn.request("GET", "/courier-maildir-trigger") - response = conn.getresponse() - if response.status != 200: - raise RuntimeError("User creation trigger failed: %d: %s" - % (response.status, response.reason)) - - -def delete_auto_users(conn, offset): - set_delete_flag(conn, "(&(objectClass=kolabInetOrgPerson)(cn=auto*))", - offset) - - -def add_groups(conn, num_entries, member, offset=0): - kolab_info = fetch_kolab_info(conn) - - mail_domain = kolab_info["postfix-mydomain"][0] - # use the first of the kolab hosts as home server. - kolab_home_server = kolab_info["kolabHost"][0] - - common_attrs = { - 'objectClass': ['top', 'groupOfNames', 'kolabGroupOfNames'], - } - - groups = ["testgrp%d@%s" % (n, mail_domain) - for n in range(offset, offset + num_entries)] - for mailuid in groups: - descr = common_attrs.copy() - descr["cn"] = descr["mail"] = [mailuid] - descr["member"] = [member] - dn = "cn=" + mailuid + "," + base_dn - print dn, descr - print conn.add_s(dn, ldap.modlist.addModlist(descr)) - - -def delete_auto_groups(conn, offset=0): - set_delete_flag(conn, "(&(objectClass=kolabGroupOfNames)(cn=testgrp*))", offset) - - -def main(): - global base_dn - - hostname = "localhost" - port = None - admin_dn_part = "cn=manager" - base_dn = None - num_entries = 10 - entry_type = "user" - group_member = None - offset = 0 - set_password = None - - opts, args = getopt.getopt(sys.argv[1:], 'h:p:u:n:o:t:', - ["host=", "port=", "user=", "num=", "offset=", - "set-password=", "type=", "member="]) - for optchar, value in opts: - if optchar in ("-h", "--host"): - hostname = value - elif optchar in ("-p", "--port"): - port = int(value) - elif optchar in ("-u", "--user"): - admin_dn_part = value - elif optchar in ("-o", "--offset"): - offset = int(value) - elif optchar == "--set-password": - set_password = value - elif optchar in ("-t", "--type"): - entry_type = value - elif optchar == "--member": - # dn of the initial member. groups may not be empty in Kolab - group_member = value - elif optchar in ("-n", "--num"): - num_entries = int(value) - else: - print >>sys.stderr, "Unknown option", optchar - sys.exit(1) - - if len(args) < 2: - print >>sys.stderr, "missing parameters" - sys.exit(1) - elif len(args) > 3: - print >>sys.stderr, "too many parameters" - sys.exit(1) - - base_dn, cmd, pwd = args - - if cmd not in ("add", "delete"): - print >>sys.stderr, "unknown command", repr(cmd) - sys.exit(1) - - - if port is not None: - ldap_uri ="ldap://%s:%d" % (hostname, port) - else: - ldap_uri ="ldap://%s" % (hostname,) - - - - # derive the http_port from the ldap port, assuming both are the - # standard ports for the respective protocol and are offset by the - # same value. - if port is not None: - http_port = port - 389 + 80 - else: - http_port = 80 - - conn = open_ldap(ldap_uri, admin_dn_part, pwd) - if entry_type == "user": - if cmd == "add": - add_user(conn, num_entries, offset, set_password=set_password, - http_hostname=hostname, http_port=http_port) - elif cmd == "delete": - delete_auto_users(conn, offset) - elif entry_type == "group": - if cmd == "add": - add_groups(conn, num_entries, group_member, offset) - elif cmd == "delete": - delete_auto_groups(conn, offset) - - - -if __name__ == "__main__": - main() diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/dovecotvm.conf kdepim-runtime-15.08.0/resources/kolabproxy/tests/dovecotvm.conf --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/dovecotvm.conf 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/dovecotvm.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -[Emulator] -Arguments=-m 256M -Ports=22,25,80,143,389,443,465,993 -WaitForPorts=22,25,143 -MonitorPort=23 -SnapshotName=running-server - -[Image] -Source=https://files.kolab.org/local/imapd-testing/qemu-dovecot-1.2-kolab-server-2.2.2-20090807/qemu-dovecot-server-20090807.tar.bz2 -File=qemu-dovecot-server/running-server.qcow2 diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/event.ical kdepim-runtime-15.08.0/resources/kolabproxy/tests/event.ical --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/event.ical 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/event.ical 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -BEGIN:VCALENDAR -PRODID:-//K Desktop Environment//NONSGML libkcal 3.5//EN -VERSION:2.0 -BEGIN:VEVENT -DTSTAMP:20070109T100625Z -ORGANIZER;CN=Volker Krause:MAILTO:vkrause@kde.org -CREATED:20070109T100553Z -UID:libkcal-1135684253.945 -SEQUENCE:1 -LAST-MODIFIED:20070109T100625Z -SUMMARY:Test event -LOCATION:here -CLASS:PUBLIC -PRIORITY:5 -CATEGORIES:KDE -DTSTART:20070109T183000Z -DTEND:20070109T225900Z -TRANSP:OPAQUE -BEGIN:VALARM -DESCRIPTION: -ACTION:DISPLAY -TRIGGER;VALUE=DURATION:-PT45M -END:VALARM -END:VEVENT -END:VCALENDAR - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/imap-quicktest.es kdepim-runtime-15.08.0/resources/kolabproxy/tests/imap-quicktest.es --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/imap-quicktest.es 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/imap-quicktest.es 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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. -*/ - - -var imapResource = Resource.newInstance( "akonadi_imap_resource" ); -imapResource.setOption( "ImapServer", "localhost:42143" ); -imapResource.setOption( "UserName", "autotest0@example.com" ); -imapResource.setOption( "Password", "nichtgeheim" ); -imapResource.create(); - -Test.alert( "resource created" ); - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/imapsignaltest.cpp kdepim-runtime-15.08.0/resources/kolabproxy/tests/imapsignaltest.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/imapsignaltest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/imapsignaltest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,339 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include //libkolab -#include - -#include "../kolabdefs.h" -#include "testutils.h" - -using namespace Akonadi; - -Q_DECLARE_METATYPE(QSet) - -class ImapSignalTest : public QObject -{ - Q_OBJECT - - AgentInstance mInstance; - Akonadi::Collection imapCollection; - Akonadi::Collection kolabCollection; - -public: - ImapSignalTest(): - QObject() - { - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType >(); - } - -private: - static Akonadi::Item createImapItem(const KCalCore::Event::Ptr &event) { - const KMime::Message::Ptr &message = Kolab::KolabObjectWriter::writeEvent(event, Kolab::KolabV3, "Proxytest", QLatin1String("UTC") ); - Q_ASSERT(message); - Akonadi::Item imapItem1; - imapItem1.setMimeType( QLatin1String("message/rfc822") ); - imapItem1.setPayload( message ); - return imapItem1; - } - - void cleanup() { - //cleanup -// Akonadi::ItemDeleteJob *deleteJob = new Akonadi::ItemDeleteJob(imapCollection); -// AKVERIFYEXEC(deleteJob); - Akonadi::ItemDeleteJob *deleteJob2 = new Akonadi::ItemDeleteJob(kolabCollection); - AKVERIFYEXEC(deleteJob2); - QTest::qWait(TIMEOUT); - } - -private slots: - void initTestCase() { - AkonadiTest::checkTestIsIsolated(); - AttributeFactory::registerAttribute(); - - const AgentType type = AgentManager::self()->type("akonadi_kolabproxy_resource"); - AgentInstanceCreateJob *agentCreateJob = new AgentInstanceCreateJob(type); - AKVERIFYEXEC(agentCreateJob); - mInstance = agentCreateJob->instance(); - - //Wait for kolabproxy to create all folders - QVERIFY(TestUtils::ensurePopulated(mInstance.identifier(), 5)); - - Akonadi::CollectionPathResolver *resolver = new CollectionPathResolver(QLatin1String("res1/Calendar"), this); - AKVERIFYEXEC(resolver); - imapCollection = Akonadi::Collection( resolver->collection() ); - QVERIFY(imapCollection.isValid()); - - kolabCollection = TestUtils::findCollection(mInstance.identifier(), "Calendar"); - QVERIFY(kolabCollection.isValid()); - } - - - void itemAddedSignal() { - KCalCore::Event::Ptr event(new KCalCore::Event); - event->setSummary("summary1"); - event->setDtStart(KDateTime(QDate(2013,02,01), QTime(1,1), KDateTime::ClockTime)); - - //Create item in imap resource - { - Akonadi::ItemCreateJob *createJob = new Akonadi::ItemCreateJob(createImapItem(event), imapCollection, this); - QVERIFY(TestUtils::ensure(kolabCollection, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)), createJob)); - } - - //TestUtils::ensure kolab equivalent gets created - { - Akonadi::Item expectedItem; - expectedItem.setGid(event->instanceIdentifier()); - Akonadi::ItemFetchJob *fetchJob = new Akonadi::ItemFetchJob(expectedItem); - AKVERIFYEXEC(fetchJob); - QCOMPARE(fetchJob->items().size(), 1); -// QCOMPARE(fetchJob->items().first().parentCollection().id() ); - } - - //create item again in imap resource (same gid), but with different content - Akonadi::Item recreatdImapItem; - { - event->setSummary("summary2"); - Akonadi::ItemCreateJob *createJob = new Akonadi::ItemCreateJob(createImapItem(event), imapCollection, this); - QVERIFY(TestUtils::ensure(kolabCollection, SIGNAL(itemChanged(Akonadi::Item,QSet)), createJob)); - recreatdImapItem = createJob->item(); - } - - //TestUtils::ensure only one item with gid exists, and it's content and rid has been updated as expected - { - Akonadi::Item expectedItem; - expectedItem.setGid(event->instanceIdentifier()); - Akonadi::ItemFetchJob *fetchJob = new Akonadi::ItemFetchJob(expectedItem); - fetchJob->fetchScope().setFetchRemoteIdentification(true); - fetchJob->fetchScope().fetchFullPayload(true); - AKVERIFYEXEC(fetchJob); - QCOMPARE(fetchJob->items().size(), 1); - const Akonadi::Item item = fetchJob->items().first(); - QCOMPARE(item.remoteId().toLongLong(), recreatdImapItem.id()); - QVERIFY(item.hasPayload()); - QCOMPARE(item.payload()->summary(), event->summary()); - } - - //test retrieve items with duplicates - { - - mInstance.synchronize(); //triggers retrieve items - //TODO listen for some signals instead of a timeout - QTest::qWait(TIMEOUT); - { - Akonadi::ItemFetchJob *fetchJob = new Akonadi::ItemFetchJob(kolabCollection); - fetchJob->fetchScope().setFetchRemoteIdentification(true); - fetchJob->fetchScope().fetchFullPayload(true); - AKVERIFYEXEC(fetchJob); - QCOMPARE(fetchJob->items().size(), 1); - const Akonadi::Item item = fetchJob->items().first(); - QCOMPARE(item.remoteId().toLongLong(), recreatdImapItem.id()); - QVERIFY(item.hasPayload()); - QCOMPARE(item.payload()->summary(), event->summary()); - } - } - - cleanup(); - } - - void twoItemAddedSignals() { - KCalCore::Event::Ptr event(new KCalCore::Event); - event->setSummary("summary1"); - event->setDtStart(KDateTime(QDate(2013,02,01), QTime(1,1), KDateTime::ClockTime)); - - //Create item in imap resource - { - Akonadi::ItemCreateJob *createJob = new Akonadi::ItemCreateJob(createImapItem(event), imapCollection, this); - AKVERIFYEXEC(createJob); - } - Akonadi::Item secondImapItem; - { - event->setSummary("summary2"); - Akonadi::ItemCreateJob *createJob = new Akonadi::ItemCreateJob(createImapItem(event), imapCollection, this); - QVERIFY(TestUtils::ensure(kolabCollection, SIGNAL(itemChanged(Akonadi::Item,QSet)), createJob)); - secondImapItem = createJob->item(); - } - - //Ensure the conflict resolution still works with two consequitive item creates - { - Akonadi::ItemFetchJob *fetchJob = new Akonadi::ItemFetchJob(kolabCollection); - fetchJob->fetchScope().setFetchRemoteIdentification(true); - AKVERIFYEXEC(fetchJob); - QCOMPARE(fetchJob->items().size(), 1); - const Akonadi::Item item = fetchJob->items().first(); - QCOMPARE(item.remoteId().toLongLong(), secondImapItem.id()); - } - - cleanup(); - - } - - void itemRemovedSignal() { - - KCalCore::Event::Ptr event(new KCalCore::Event); - event->setSummary("summary1"); - event->setDtStart(KDateTime(QDate(2013,02,01), QTime(1,1), KDateTime::ClockTime)); - - Akonadi::Item firstImapItem; - { - Akonadi::ItemCreateJob *createJob = new Akonadi::ItemCreateJob(createImapItem(event), imapCollection, this); - QVERIFY(TestUtils::ensure(kolabCollection, SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)), createJob)); - firstImapItem = createJob->item(); - } - - //create item again in imap resource (same gid), but with different content - Akonadi::Item secondImapItem; - { - event->setSummary("summary2"); - Akonadi::ItemCreateJob *createJob = new Akonadi::ItemCreateJob(createImapItem(event), imapCollection, this); -// AKVERIFYEXEC(createJob); - QVERIFY(TestUtils::ensure(kolabCollection, SIGNAL(itemChanged(Akonadi::Item,QSet)), createJob)); - secondImapItem = createJob->item(); - } - //we expect one kolab item that is linked to the second imap item - - //remove first imap item - { - Akonadi::ItemDeleteJob *deleteJob = new Akonadi::ItemDeleteJob(firstImapItem); - QVERIFY(!TestUtils::ensure(kolabCollection, SIGNAL(itemRemoved(Akonadi::Item)), deleteJob)); - } - - //TestUtils::ensure kolab item remains - { - Akonadi::ItemFetchJob *fetchJob = new Akonadi::ItemFetchJob(kolabCollection); - fetchJob->fetchScope().setFetchRemoteIdentification(true); - AKVERIFYEXEC(fetchJob); - QCOMPARE(fetchJob->items().size(), 1); - const Akonadi::Item item = fetchJob->items().first(); - QCOMPARE(item.remoteId().toLongLong(), secondImapItem.id()); - } - - //remove second imap item - { - Akonadi::ItemDeleteJob *deleteJob = new Akonadi::ItemDeleteJob(secondImapItem); - QVERIFY(TestUtils::ensure(kolabCollection, SIGNAL(itemRemoved(Akonadi::Item)), deleteJob)); - } - - //TestUtils::ensure kolab item is removed - { - Akonadi::ItemFetchJob *fetchJob = new Akonadi::ItemFetchJob(kolabCollection); - AKVERIFYEXEC(fetchJob); - QCOMPARE(fetchJob->items().size(), 0); - } - } - - void collectionAddedRemovedSignal() { - Akonadi::Collection createdCollection; - { - Akonadi::Collection col; - col.setParent(imapCollection); - col.setName("test"); - QMap annotations; - annotations.insert("/shared/vendor/kolab/folder-type", "event"); - col.addAttribute(new CollectionAnnotationsAttribute(annotations)); - Akonadi::CollectionCreateJob *createJob = new Akonadi::CollectionCreateJob(col, this); - QVERIFY(TestUtils::ensure(kolabCollection, SIGNAL(collectionAdded(Akonadi::Collection,Akonadi::Collection)), createJob)); - createdCollection = createJob->collection(); - } - { - Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(kolabCollection); - AKVERIFYEXEC(fetchJob); - QCOMPARE(fetchJob->collections().size(), 1); - } - //cleanup - { - Akonadi::CollectionDeleteJob *deleteJob = new Akonadi::CollectionDeleteJob(createdCollection); - QVERIFY(TestUtils::ensure(kolabCollection, SIGNAL(collectionRemoved(Akonadi::Collection)), deleteJob)); - } - { - Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(kolabCollection); - AKVERIFYEXEC(fetchJob); - QCOMPARE(fetchJob->collections().size(), 0); - } - } - - void collectionChangedSignal() { - Akonadi::Collection createdCollection; - { - Akonadi::Collection col; - col.setParent(imapCollection); - col.setName("test"); - QMap annotations; - annotations.insert("/shared/vendor/kolab/folder-type", "event"); - col.addAttribute(new CollectionAnnotationsAttribute(annotations)); - col.setRights(Akonadi::Collection::AllRights); - Akonadi::CollectionCreateJob *createJob = new Akonadi::CollectionCreateJob(col, this); - QVERIFY(TestUtils::ensure(kolabCollection, SIGNAL(collectionAdded(Akonadi::Collection,Akonadi::Collection)), createJob)); - createdCollection = createJob->collection(); - } - - { - Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(kolabCollection); - AKVERIFYEXEC(fetchJob); - QCOMPARE(fetchJob->collections().size(), 1); - QCOMPARE(fetchJob->collections().first().rights(), Akonadi::Collection::AllRights); - } - { - createdCollection.setRights(Akonadi::Collection::ReadOnly); - Akonadi::CollectionModifyJob *modJob = new Akonadi::CollectionModifyJob(createdCollection); - QVERIFY(TestUtils::ensure(kolabCollection, SIGNAL(collectionChanged(Akonadi::Collection)), modJob)); - } - { - Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(kolabCollection); - AKVERIFYEXEC(fetchJob); - QCOMPARE(fetchJob->collections().size(), 1); - QCOMPARE(fetchJob->collections().first().rights(), Akonadi::Collection::ReadOnly); - } - //cleanup - { - Akonadi::CollectionDeleteJob *deleteJob = new Akonadi::CollectionDeleteJob(createdCollection); - QVERIFY(TestUtils::ensure(kolabCollection, SIGNAL(collectionRemoved(Akonadi::Collection)), deleteJob)); - } - } - -}; - -QTEST_AKONADIMAIN( ImapSignalTest, NoGUI ) - -#include "imapsignaltest.moc" - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/imaptest-dovecot.es kdepim-runtime-15.08.0/resources/kolabproxy/tests/imaptest-dovecot.es --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/imaptest-dovecot.es 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/imaptest-dovecot.es 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -Script.include( "imaptest.es" ); -testImap( "dovecot" ); diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/imaptest-dovecot-step1.xml kdepim-runtime-15.08.0/resources/kolabproxy/tests/imaptest-dovecot-step1.xml --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/imaptest-dovecot-step1.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/imaptest-dovecot-step1.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ - - - - - - - 1 - - \ANSWERED \FLAGGED \DELETED \SEEN \DRAFT - 1249661411 - - 1 - - \ANSWERED \FLAGGED \DELETED \SEEN \DRAFT - 1249661412 - - - - 2 - - \ANSWERED \FLAGGED \DELETED \SEEN \DRAFT - 1249661409 - - From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h - - - - 1 - - \ANSWERED \FLAGGED \DELETED \SEEN \DRAFT - 1249661410 - - - ("Shared Folders" "x-mail-distribution-list" false) - - 1 - - - - 1 - \ANSWERED \FLAGGED \DELETED \SEEN \DRAFT - autotest0@example.com lrswipckxtdae - 1249661407 - - ("Inbox" "mail-folder-inbox" false) - 2 - \ANSWERED \FLAGGED \DELETED \SEEN \DRAFT - autotest0@example.com lrswipckxtdae - 1249661406 - - From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h - - - - - - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/imaptest-dovecot-step2.xml kdepim-runtime-15.08.0/resources/kolabproxy/tests/imaptest-dovecot-step2.xml --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/imaptest-dovecot-step2.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/imaptest-dovecot-step2.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ - - - - - - - 1 - - \ANSWERED \FLAGGED \DELETED \SEEN \DRAFT - 1249661417 - - 1 - - \ANSWERED \FLAGGED \DELETED \SEEN \DRAFT - 1249661418 - - - - 2 - - \ANSWERED \FLAGGED \DELETED \SEEN \DRAFT - 1249661415 - - From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h - - - - 1 - - \ANSWERED \FLAGGED \DELETED \SEEN \DRAFT - 1249661416 - - - ("Shared Folders" "x-mail-distribution-list" false) - - 1 - - - - 2 - \ANSWERED \FLAGGED \DELETED \SEEN \DRAFT - autotest0@example.com lrswipckxtdae - 1249661415 - - From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h - - - - - 1 - \ANSWERED \FLAGGED \DELETED \SEEN \DRAFT - autotest0@example.com lrswipckxtdae - 1249661414 - - ("Inbox" "mail-folder-inbox" false) - 2 - \ANSWERED \FLAGGED \DELETED \SEEN \DRAFT - autotest0@example.com lrswipckxtdae - 1249661413 - - From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h - - - - - - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/imaptest.es kdepim-runtime-15.08.0/resources/kolabproxy/tests/imaptest.es --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/imaptest.es 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/imaptest.es 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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. -*/ - -/** helper function to run IMAP commands for the initial VM setup */ -runImapCmd = function( user, cmd ) -{ - var args = ["--port", QEmu.portOffset() + 143, "--user", user + "@example.com", "--password", "nichtgeheim" ]; - args = args.concat( cmd ); - System.exec( "runimapcommand.py", args ); -} - -/** creates two user accounts with a standard set of Kolab folders shared between two users */ -setupServer = function() -{ - System.exec( "create_ldap_users.py", ["-h", "localhost", "-p", QEmu.portOffset() + 389, - "-n", "2", "--set-password", "nichtgeheim", "dc=example,dc=com", "add", "nichtgeheim" ] ); - - // Wait until the user accounts have been fully created - runImapCmd( "autotest0", [ "waitformailbox", "INBOX"] ); - runImapCmd( "autotest1", [ "waitformailbox", "INBOX"] ); - - // creates folders and messages for the primary test user - runImapCmd( "autotest0", [ "create", "INBOX/Calendar" ] ); - runImapCmd( "autotest0", [ "append", "INBOX", - Script.absoluteFileName( "testmail.mbox" ) ] ); - - // creates folders and messages for the secondary test user and share them with the first one - runImapCmd( "autotest1", [ "create", "INBOX/child1" ] ); - runImapCmd( "autotest1", [ "create", "INBOX/child2" ] ); - runImapCmd( "autotest1", [ "create", "INBOX/child1/grandchild1" ] ); - runImapCmd( "autotest1", [ "create", "INBOX/child2/grandchild1" ] ); - runImapCmd( "autotest1", [ "append", "INBOX/child1/grandchild1", - Script.absoluteFileName( "testmail.mbox" ) ] ); - runImapCmd( "autotest1", [ "setacl", "INBOX/child1", "autotest0@example.com", "lrs" ] ); - runImapCmd( "autotest1", [ "setacl", "INBOX/child2", "autotest0@example.com", "lrs" ] ); - runImapCmd( "autotest1", [ "setacl", "INBOX/child1/grandchild1", "autotest0@example.com", "lrs" ] ); - runImapCmd( "autotest1", [ "setacl", "INBOX/child2/grandchild1", "autotest0@example.com", "lrs" ] ); -} - -/** The actual tests for the IMAP resource, @p vm is the name of the VM - * to use. The names of the VM config file and the XML files with the - * expected contents of hte resources are derived from this. */ -testImap = function( vm ) -{ - QEmu.setVMConfig( vm + "vm.conf" ); - QEmu.start(); - - setupServer(); - - var imapResource = Resource.newInstance( "akonadi_imap_resource" ); - imapResource.setOption( "ImapServer", "localhost:42143" ); - imapResource.setOption( "UserName", "autotest0@example.com" ); - imapResource.setOption( "Password", "nichtgeheim" ); - imapResource.create(); - - // verify reading by checking if we can read the initial server state - XmlOperations.setXmlFile( "imaptest-" + vm + "-step1.xml" ); - XmlOperations.setRootCollections( imapResource.identifier() ); - // FIXME: one of the attributes contains a current date/time breaking the comparison - XmlOperations.ignoreCollectionField( "Attributes" ); - XmlOperations.assertEqual(); - - // folder creation - CollectionTest.setParent( "localhost:42143\\/autotest0@example.com/INBOX" ); - CollectionTest.addContentType( "message/rfc822" ); - CollectionTest.setName( "test folder" ); - CollectionTest.create(); - - // item creation - ItemTest.setParentCollection( "localhost:42143\\/autotest0@example.com/INBOX/test folder" ); - ItemTest.setMimeType( "message/rfc822" ); - ItemTest.setPayloadFromFile( "testmail.mbox" ); - ItemTest.create(); - - imapResource.recreate(); - XmlOperations.setXmlFile( "imaptest-" + vm + "-step2.xml" ); - XmlOperations.setRootCollections( imapResource.identifier() ); - // FIXME: one of the attributes contains a current date/time breaking the comparison - XmlOperations.ignoreCollectionField( "Attributes" ); - XmlOperations.assertEqual(); - - // TODO: test change, move, item delete - - // folder deletion - CollectionTest.setCollection( "localhost:42143\\/autotest0@example.com/INBOX/test folder" ); - CollectionTest.remove(); - - XmlOperations.setXmlFile( "imaptest-" + vm + "-step1.xml" ); - XmlOperations.setRootCollections( imapResource.identifier() ); - // FIXME: one of the attributes contains a current date/time breaking the comparison - XmlOperations.ignoreCollectionField( "Attributes" ); - XmlOperations.assertEqual(); - - imapResource.destroy(); - QEmu.stop(); -} diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/imaptest-kolab.es kdepim-runtime-15.08.0/resources/kolabproxy/tests/imaptest-kolab.es --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/imaptest-kolab.es 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/imaptest-kolab.es 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -Script.include( "imaptest.es" ); -testImap( "kolab" ); diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/imaptest-kolab-step1.xml kdepim-runtime-15.08.0/resources/kolabproxy/tests/imaptest-kolab-step1.xml --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/imaptest-kolab-step1.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/imaptest-kolab-step1.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ - - - - - - - 1 - - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - 1251189141 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 - - 1 - - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - 1251189141 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 - - - - 2 - - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - 1251189141 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 627 - - From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h - - - - 1 - - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - 1251189141 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 - - - 1 - - - 1 - - - - 1 - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - autotest0@example.com lrswipckxtdae - 1251189141 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 - - 2 - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - autotest0@example.com lrswipckxtdae - 1251189140 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 627 - - From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h - - - - - - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/imaptest-kolab-step2.xml kdepim-runtime-15.08.0/resources/kolabproxy/tests/imaptest-kolab-step2.xml --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/imaptest-kolab-step2.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/imaptest-kolab-step2.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,128 +0,0 @@ - - - - - - - 1 - - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - 1251191271 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 - - 1 - - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - 1251191271 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 - - - - 2 - - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - 1251191271 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 627 - - From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h - - - - 1 - - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - 1251191271 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 - - - 1 - - - 1 - - - - 2 - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - autotest0@example.com lrswipckxtdae - 1251191279 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 627 - - From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h - - - - - 1 - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - autotest0@example.com lrswipckxtdae - 1251191270 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 - - 2 - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - autotest0@example.com lrswipckxtdae - 1251191270 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 627 - - From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h - - - - - - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/kolabconvertertest.cpp kdepim-runtime-15.08.0/resources/kolabproxy/tests/kolabconvertertest.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/kolabconvertertest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/kolabconvertertest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 -#include -#include -#include -#include -#include -#include -#include - -using namespace Akonadi; -using namespace KMime; -Q_DECLARE_METATYPE(KCalCore::Incidence::Ptr) - -class KolabConverterTest : public QObject -{ - Q_OBJECT - private slots: - void testContacts_data() - { - QTest::addColumn( "addressee" ); - KABC::Addressee contact; - contact.setName(QLatin1String("John Doe")); - contact.setEmails(QStringList() << QLatin1String("doe@example.org")); - - QTest::newRow( "contact" ) << contact; - } - - void testContacts() - { - QFETCH( KABC::Addressee, addressee ); - - KolabHandler::Ptr handler = KolabHandler::createHandler( Kolab::ContactType, Collection() ); - QVERIFY( handler ); - - Item vcardItem( QLatin1String("text/directory") ); - vcardItem.setPayload( addressee ); - - //Convert to kolab item - Item kolabItem; - handler->toKolabFormat( vcardItem, kolabItem ); - QVERIFY( kolabItem.hasPayload() ); - - //and back - Item::List vcardItems = handler->translateItems( Akonadi::Item::List() << kolabItem ); - QCOMPARE( vcardItems.size(), 1 ); - QVERIFY( vcardItems.first().hasPayload() ); - } - - void testIncidences_data() - { - QTest::addColumn( "type" ); - QTest::addColumn( "incidence" ); - - KCalCore::Incidence::Ptr event(new KCalCore::Event); - event->setDtStart(KDateTime::currentUtcDateTime()); - QTest::newRow("event") << "event" << event; - - KCalCore::Incidence::Ptr todo(new KCalCore::Todo); - todo->setDtStart(KDateTime::currentUtcDateTime()); - QTest::newRow("todo") << "task" << todo; - - KCalCore::Incidence::Ptr journal(new KCalCore::Journal); - journal->setDtStart(KDateTime::currentUtcDateTime()); - QTest::newRow("journal") << "journal" << journal; - } - - void testIncidences() - { - QFETCH( QString, type ); - QFETCH( KCalCore::Incidence::Ptr, incidence ); - - KolabHandler::Ptr handler = KolabHandler::createHandler( Kolab::folderTypeFromString( type.toLatin1() ), Collection() ); - QVERIFY( handler ); - - Item icalItem; - switch ( incidence->type() ) { - case KCalCore::IncidenceBase::TypeEvent: icalItem.setMimeType( KCalCore::Event::eventMimeType() ); return; - case KCalCore::IncidenceBase::TypeTodo: icalItem.setMimeType( KCalCore::Todo::todoMimeType() ); return; - case KCalCore::IncidenceBase::TypeJournal: icalItem.setMimeType( KCalCore::Journal::journalMimeType() ); return; - default: QFAIL( "incidence type not supported" ); - } - icalItem.setPayload( incidence ); - - // Convert to kolab item - Item kolabItem; - handler->toKolabFormat( icalItem, kolabItem ); - QVERIFY( kolabItem.hasPayload() ); - - //and back - Item::List icalItems = handler->translateItems( Akonadi::Item::List() << kolabItem ); - QCOMPARE( icalItems.size(), 1 ); - QVERIFY( icalItems.first().hasPayload() ); - if ( type == QLatin1String("task") ) { - QVERIFY( icalItems.first().hasPayload() ); - } - } -}; - -QTEST_KDEMAIN( KolabConverterTest, NoGUI ) - -#include "kolabconvertertest.moc" diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/kolabevent.mbox kdepim-runtime-15.08.0/resources/kolabproxy/tests/kolabevent.mbox --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/kolabevent.mbox 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/kolabevent.mbox 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -From: Volker Krause -X-KMail-Fcc: sent-mail -Subject: libkcal-1109914.774 -Date: Sun, 12 Apr 2009 13:36:53 +0200 -User-Agent: KMail/1.9.9 -MIME-Version: 1.0 -X-Kolab-Type: application/x-vnd.kolab.event -Content-Type: Multipart/Mixed; - boundary="Boundary-00=_VJd4J1dXKX5M02c" -Status: RO -X-Status: OT -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: -X-UID: 150 -X-Length: 1728 - ---Boundary-00=_VJd4J1dXKX5M02c -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Content-Disposition: - -This is a Kolab Groupware object. -To view this object you will need an email client that can understand the Kolab Groupware format. -For a list of such email clients please visit -http://www.kolab.org/kolab2-clients.html ---Boundary-00=_VJd4J1dXKX5M02c -Content-Type: application/x-vnd.kolab.event; - name="kolab.xml" -Content-Transfer-Encoding: 7bit -Content-Disposition: attachment; - filename="kolab.xml" - - - - KOrganizer 3.5.9 (enterprise35 0.20080722.836276), Kolab resource - libkcal-1109914.774 - KDE - 2009-04-12T11:36:49Z - 2009-04-12T11:36:49Z - public - 0 - 2009-06-03 - Release KDE 4.2.4 - - Volker Krause - vkrause@kde.org - - 0 - free - 2009-06-03 - - ---Boundary-00=_VJd4J1dXKX5M02c-- - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/kolab-step1.xml kdepim-runtime-15.08.0/resources/kolabproxy/tests/kolab-step1.xml --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/kolab-step1.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/kolab-step1.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - ("Shared Folders" "x-mail-distribution-list") - - - - - a - - - a - - - a - - - a - - - a - - BEGIN:VCALENDAR -PRODID:-//K Desktop Environment//NONSGML libkcal 3.2//EN -VERSION:2.0 -BEGIN:VEVENT -DTSTAMP:20090730T201426Z -ORGANIZER;CN="Volker Krause":MAILTO:vkrause@kde.org -CREATED:20090412T113649Z -UID:libkcal-1109914.774 -LAST-MODIFIED:20090412T113649Z -SUMMARY:Release KDE 4.2.4 -CATEGORIES:KDE -DTSTART;VALUE=DATE:20090603 -DTEND;VALUE=DATE:20090604 -TRANSP:TRANSPARENT -END:VEVENT - -END:VCALENDAR - - - ("My Data" "view-pim-summary") - a - - - - ("Kolab" "kolab") - - - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/kolab-step2.xml kdepim-runtime-15.08.0/resources/kolabproxy/tests/kolab-step2.xml --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/kolab-step2.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/kolab-step2.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,270 +0,0 @@ - - - - - - 1 - - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - 1245682294 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/lastupdate 22-Jun-2009 16:51:37 +0200 % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 % /vendor/kolab/folder-type task.default - - - - 1 - - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - 1245682293 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/lastupdate 22-Jun-2009 16:51:37 +0200 % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 % /vendor/kolab/folder-type note.default - - - - 1 - - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - 1245682293 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/lastupdate 22-Jun-2009 16:51:37 +0200 % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 % /vendor/kolab/folder-type journal.default - - - - 1 - - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - 1245682293 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/lastupdate 22-Jun-2009 16:51:37 +0200 % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 % /vendor/kolab/folder-type contact.default - - - - 1 - - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - 1245682293 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/lastupdate 22-Jun-2009 16:51:36 +0200 % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 % /vendor/kolab/folder-type event.default - - - - 1 - - ("Shared Folders" "x-mail-distribution-list") - - 1 - - - - 2 - a - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - autotest0@example.com lrswipckxtdae - 1245682291 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/lastupdate 22-Jun-2009 16:51:31 +0200 % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 % /vendor/kolab/folder-type task.default - - - From: vkrause@kde.org, vkrause@kde.org -Subject: libkcal-1506191911.958 -User-Agent: Akonadi Kolab Proxy Resource -MIME-Version: 1.0 -Content-Type: multipart/mixed; boundary="nextPart1765520.vjZoYI2vSi" -Date: Mon Jun 22 16:53:27 2009 -X-Kolab-Type: application/x-vnd.kolab.task - - ---nextPart1765520.vjZoYI2vSi - - ---nextPart1765520.vjZoYI2vSi -Content-Type: text/plain; charset="us-ascii" -Content-Transfer-Encoding: 7bit - -This is a Kolab Groupware object. -To view this object you will need an email client that can understand the Kolab Groupware format. -For a list of such email clients please visit -http://www.kolab.org/kolab2-clients.html - ---nextPart1765520.vjZoYI2vSi -Content-Type: application/x-vnd.kolab.task; name="kolab.xml" -Content-Transfer-Encoding: quoted-printable -Content-Disposition: attachment; filename="kolab.xml" - -<?xml version=3D"1.0" encoding=3D"UTF-8"?> -<task version=3D"1.0" > - <product-id>KOrganizer 4.3.0 rc1, Kolab resource</product-id> - <uid>libkcal-1506191911.958</uid> - <creation-date>2004-05-05T09:41:43Z</creation-date> - <last-modification-date>2004-05-12T13:39:25+00:00</last-modification-date> - <sensitivity>public</sensitivity> - <summary>Add a demo task to this file</summary> - <organizer> - <smtp-address>vkrause@kde.org</smtp-address> - </organizer> - <revision>0</revision> - <priority>3</priority> - <completed>100</completed> - <status>not-started</status> - <due-date>2009-01-01T00:00:00Z</due-date> - <x-completed-date>2009-01-01T13:39:25Z</x-completed-date> -</task> - ---nextPart1765520.vjZoYI2vSi-- - - - - - 1 - a - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - autotest0@example.com lrswipckxtdae - 1245682290 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/lastupdate 22-Jun-2009 16:51:30 +0200 % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 % /vendor/kolab/folder-type note.default - - - - 1 - a - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - autotest0@example.com lrswipckxtdae - 1245682289 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/lastupdate 22-Jun-2009 16:51:29 +0200 % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 % /vendor/kolab/folder-type journal.default - - - - 1 - a - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - autotest0@example.com lrswipckxtdae - 1245682289 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/lastupdate 22-Jun-2009 16:51:29 +0200 % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 % /vendor/kolab/folder-type contact.default - - - - 3 - a - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - autotest0@example.com lrswipckxtdae - 1245682289 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/lastupdate 22-Jun-2009 16:51:32 +0200 % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 1750 % /vendor/kolab/folder-type event.default - - - From: Volker Krause <vkrause@kde.org> -Subject: libkcal-1109914.774 -Date: Sun, 12 Apr 2009 13:36:53 +0200 -User-Agent: KMail/1.9.9 -MIME-Version: 1.0 -Content-Type: multipart/mixed; boundary="Boundary-00=_VJd4J1dXKX5M02c" -X-KMail-Fcc: sent-mail -X-Kolab-Type: application/x-vnd.kolab.event -Status: RO -X-Status: OT -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: -X-UID: 150 -X-Length: 1728 - - ---Boundary-00=_VJd4J1dXKX5M02c -Content-Type: text/plain; charset="us-ascii" -Content-Transfer-Encoding: 7bit -Content-Disposition: - -This is a Kolab Groupware object. -To view this object you will need an email client that can understand the Kolab Groupware format. -For a list of such email clients please visit -http://www.kolab.org/kolab2-clients.html ---Boundary-00=_VJd4J1dXKX5M02c -Content-Type: application/x-vnd.kolab.event; name="kolab.xml" -Content-Transfer-Encoding: 7bit -Content-Disposition: attachment; filename="kolab.xml" - -<?xml version="1.0" encoding="UTF-8"?> -<event version="1.0" > - <product-id>KOrganizer 3.5.9 (enterprise35 0.20080722.836276), Kolab resource</product-id> - <uid>libkcal-1109914.774</uid> - <categories>KDE</categories> - <creation-date>2009-04-12T11:36:49Z</creation-date> - <last-modification-date>2009-04-12T11:36:49Z</last-modification-date> - <sensitivity>public</sensitivity> - <pilot-sync-status>0</pilot-sync-status> - <start-date>2009-06-03</start-date> - <summary>Release KDE 4.2.4</summary> - <organizer> - <display-name>Volker Krause</display-name> - <smtp-address>vkrause@kde.org</smtp-address> - </organizer> - <revision>0</revision> - <show-time-as>free</show-time-as> - <end-date>2009-06-03</end-date> -</event> - ---Boundary-00=_VJd4J1dXKX5M02c-- - - - - From: Volker Krause <vkrause@kde.org>, vkrause@kde.org -Subject: libkcal-1135684253.945 -User-Agent: Akonadi Kolab Proxy Resource -MIME-Version: 1.0 -Content-Type: multipart/mixed; boundary="nextPart4368523.kW76qGQa90" -Date: Mon Jun 22 16:53:26 2009 -X-Kolab-Type: application/x-vnd.kolab.event - - ---nextPart4368523.kW76qGQa90 - - ---nextPart4368523.kW76qGQa90 -Content-Type: text/plain; charset="us-ascii" -Content-Transfer-Encoding: 7bit - -This is a Kolab Groupware object. -To view this object you will need an email client that can understand the Kolab Groupware format. -For a list of such email clients please visit -http://www.kolab.org/kolab2-clients.html - ---nextPart4368523.kW76qGQa90 -Content-Type: application/x-vnd.kolab.event; name="kolab.xml" -Content-Transfer-Encoding: quoted-printable -Content-Disposition: attachment; filename="kolab.xml" - -<?xml version=3D"1.0" encoding=3D"UTF-8"?> -<event version=3D"1.0" > - <product-id>KOrganizer 4.3.0 rc1, Kolab resource</product-id> - <uid>libkcal-1135684253.945</uid> - <categories>KDE</categories> - <creation-date>2007-01-09T10:05:53Z</creation-date> - <last-modification-date>2007-01-09T10:06:25+00:00</last-modification-date> - <sensitivity>public</sensitivity> - <start-date>2007-01-09T18:30:00Z</start-date> - <summary>Test event</summary> - <location>here</location> - <organizer> - <display-name>Volker Krause</display-name> - <smtp-address>vkrause@kde.org</smtp-address> - </organizer> - <alarm>45</alarm> - <advanced-alarms> - <alarm type=3D"display" > - <enabled>1</enabled> - <start-offset>-45</start-offset> - </alarm> - </advanced-alarms> - <revision>0</revision> - <show-time-as>busy</show-time-as> - <end-date>2007-01-09T22:59:00Z</end-date> -</event> - ---nextPart4368523.kW76qGQa90-- - - - - ("Inbox" "mail-folder-inbox") - 1 - a - \ANSWERED \FLAGGED \DRAFT \DELETED \SEEN - autotest0@example.com lrswipckxtdae - 1245682273 - /vendor/cmu/cyrus-imapd/condstore false % /vendor/cmu/cyrus-imapd/duplicatedeliver false % /vendor/cmu/cyrus-imapd/lastpop % /vendor/cmu/cyrus-imapd/lastupdate 22-Jun-2009 16:53:28 +0200 % /vendor/cmu/cyrus-imapd/partition default % /vendor/cmu/cyrus-imapd/sharedseen false % /vendor/cmu/cyrus-imapd/size 0 - - - - - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/kolabtest.es kdepim-runtime-15.08.0/resources/kolabproxy/tests/kolabtest.es --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/kolabtest.es 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/kolabtest.es 1970-01-01 00:00:00.000000000 +0000 @@ -1,129 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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. -*/ - -/** helper function to run IMAP commands for the initial VM setup */ -function runImapCmd( user, cmd ) -{ - var args = ["--port", QEmu.portOffset() + 143, "--user", user + "@example.com", "--password", "nichtgeheim" ]; - args = args.concat( cmd ); - System.exec( "runimapcommand.py", args ); -} - -/** helper function to create a Kolab folder setup */ -function createKolabFolders( user ) -{ - runImapCmd( user, [ "create", "INBOX/Calendar" ] ); - runImapCmd( user, [ "create", "INBOX/Contacts" ] ); - runImapCmd( user, [ "create", "INBOX/Journal" ] ); - runImapCmd( user, [ "create", "INBOX/Notes" ] ); - runImapCmd( user, [ "create", "INBOX/Tasks" ] ); - - runImapCmd( user, [ "setannotation", "INBOX/Calendar", "/vendor/kolab/folder-type", "event.default" ] ); - runImapCmd( user, [ "setannotation", "INBOX/Contacts", "/vendor/kolab/folder-type", "contact.default" ] ); - runImapCmd( user, [ "setannotation", "INBOX/Journal", "/vendor/kolab/folder-type", "journal.default" ] ); - runImapCmd( user, [ "setannotation", "INBOX/Notes", "/vendor/kolab/folder-type", "note.default" ] ); - runImapCmd( user, [ "setannotation", "INBOX/Tasks", "/vendor/kolab/folder-type", "task.default" ] ); -} - -/** creates two user accounts with a standard set of Kolab folders shared between two users */ -function setupKolab() -{ - System.exec( "create_ldap_users.py", ["-h", "localhost", "-p", QEmu.portOffset() + 389, - "-n", "2", "--set-password", "nichtgeheim", "dc=example,dc=com", "add", "nichtgeheim" ] ); - - // Wait until the user accounts have been fully created - runImapCmd( "autotest0", [ "waitformailbox", "INBOX"] ); - runImapCmd( "autotest1", [ "waitformailbox", "INBOX"] ); - - // creates folders and messages for the primary test user - createKolabFolders( "autotest0" ); - runImapCmd( "autotest0", [ "append", "INBOX/Calendar", "kolabevent.mbox" ] ); - - // create folders and messages for the user sharing his folders with the test user - createKolabFolders( "autotest1" ); - runImapCmd( "autotest1", [ "setacl", "INBOX/Calendar", "autotest0@example.com", "lrs" ] ); - runImapCmd( "autotest1", [ "setacl", "INBOX/Contacts", "autotest0@example.com", "lrs" ] ); - runImapCmd( "autotest1", [ "setacl", "INBOX/Journal", "autotest0@example.com", "lrs" ] ); - runImapCmd( "autotest1", [ "setacl", "INBOX/Notes", "autotest0@example.com", "lrs" ] ); - runImapCmd( "autotest1", [ "setacl", "INBOX/Tasks", "autotest0@example.com", "lrs" ] ); -} - -/** The actual tests for the Kolab resource. */ -function testKolab( vm ) -{ - QEmu.setVMConfig( vm ); - QEmu.start(); - - setupKolab(); - - var imapResource = Resource.newInstance( "akonadi_imap_resource" ); - imapResource.setOption( "ImapServer", "localhost:42143" ); - imapResource.setOption( "UserName", "autotest0@example.com" ); - imapResource.setOption( "Password", "nichtgeheim" ); - imapResource.create(); - - Test.alert( "wait" ); // FIXME - - XmlOperations.setXmlFile( "kolab-step1.xml" ); - XmlOperations.setRootCollections( kolabResource.identifier() ); - XmlOperations.setCollectionKey( "Name" ); - XmlOperations.ignoreCollectionField( "RemoteId" ); - XmlOperations.setItemKey( "None" ); // FIXME this should not be necessary when using the testrunner? - XmlOperations.ignoreItemField( "RemoteId" ); - XmlOperations.assertEqual(); - - // TODO: adding/changing/removing collections, adding/changing/removing items, in both directions - - var eventItem = ItemTest.newInstance(); - eventItem.setMimeType( "application/x-vnd.akonadi.calendar.event" ); - eventItem.setParentCollection( "akonadi_kolabproxy_resource/localhost:42143\\/autotest0@example.com/INBOX/Calendar" ); - eventItem.setPayloadFromFile( "event.ical" ); - eventItem.create(); - - var taskItem = ItemTest.newInstance(); - taskItem.setMimeType( "application/x-vnd.akonadi.calendar.todo" ); - taskItem.setParentCollection( "akonadi_kolabproxy_resource/localhost:42143\\/autotest0@example.com/INBOX/Tasks" ); - taskItem.setPayloadFromFile( "task.ical" ); - taskItem.create(); - - Test.alert( "wait again" ); // FIXME - - // FIXME I need either two instances or a way to reset this thing... - XmlOperations.setXmlFile( "kolab-step2.xml" ); - XmlOperations.setRootCollections( imapResource.identifier() ); - XmlOperations.setCollectionKey( "RemoteId" ); - // FIXME: one of the attributes contains a current date/time breaking the comparison - XmlOperations.ignoreCollectionField( "Attributes" ); - XmlOperations.setItemKey( "RemoteId" ); - // FIXME: payload contains a current date/time... - XmlOperations.ignoreItemField( "Payload" ); - XmlOperations.assertEqual(); - - Test.alert( "done" ); - imapResource.destroy(); - QEmu.stop(); -} - -var kolabResource = Resource.newInstance( "akonadi_kolabproxy_resource" ); -kolabResource.create(); - -testKolab( "kolabvm.conf" ); -// testKolab( "dovecotvm.conf" ); - -kolabResource.destroy(); diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/kolabvm.conf kdepim-runtime-15.08.0/resources/kolabproxy/tests/kolabvm.conf --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/kolabvm.conf 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/kolabvm.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -[Emulator] -Arguments=-m 256M -Ports=22,25,80,143,389,443,465,993 -WaitForPorts=22,25,143 -MonitorPort=23 -SnapshotName=running-server - -[Image] -Source=http://files.kolab.org/server/development-2.2/testing/qemu-kolab-server-2.2.0-20090807/qemu-kolab-server-2.2.0-20090807.tar.bz2 -File=qemu-kolab-server/running-server.qcow2 - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/proxyintegrationtest.cpp kdepim-runtime-15.08.0/resources/kolabproxy/tests/proxyintegrationtest.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/proxyintegrationtest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/proxyintegrationtest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include //libkolab - -#include "testutils.h" - -#include "../kolabdefs.h" - -using namespace Akonadi; - -class ProxyIntegrationTest : public QObject -{ - Q_OBJECT - - static Collection createCollection(const QString &name, const QByteArray &annotation) - { - Collection col; - col.setName(name); - QMap annotations; - Kolab::setFolderTypeAnnotation( annotations, annotation ); - col.addAttribute(new CollectionAnnotationsAttribute(annotations)); - col.setRights(Collection::CanCreateItem | Collection::CanChangeItem | Collection::CanDeleteItem | Collection::CanCreateCollection | Collection::CanChangeCollection | Collection::CanDeleteCollection); - return col; - } - - AgentInstance mInstance; - -private slots: - void initTestCase() { - AkonadiTest::checkTestIsIsolated(); - AttributeFactory::registerAttribute(); - - const AgentType type = AgentManager::self()->type("akonadi_kolabproxy_resource"); - AgentInstanceCreateJob *agentCreateJob = new AgentInstanceCreateJob(type); - AKVERIFYEXEC(agentCreateJob); - mInstance = agentCreateJob->instance(); - - //Wait for kolabproxy to create all folders - QVERIFY(TestUtils::ensurePopulated(mInstance.identifier(), 6)); - } - - void setupKolabProxy() { - //Check that all collections in the kolab proxy have been created - CollectionFetchJob *fetchJob = new CollectionFetchJob(Collection::root(), CollectionFetchJob::Recursive); - fetchJob->fetchScope().setResource(mInstance.identifier()); - AKVERIFYEXEC(fetchJob); - - QList expectedCollections; - expectedCollections << createCollection("Calendar", "event"); - expectedCollections << createCollection("Tasks", "task"); - expectedCollections << createCollection("Journal", "journal"); - expectedCollections << createCollection("Notes", "note"); - expectedCollections << createCollection("Contact", "contact"); - - foreach (const Collection &col, fetchJob->collections()) { - if (!col.attribute()) { - continue; - } - for (int i = 0; i < expectedCollections.size(); i++) { - const Collection &expectedCol = expectedCollections.at(i); -// kDebug() << col.name() << expectedCol.name(); -// kDebug() << col.attribute()->annotations(); -// kDebug() << expectedCol.attribute()->annotations(); - if (col.name() == expectedCol.name()) { - kDebug() << " found " << col.name(); - QCOMPARE(col.attribute()->annotations(), expectedCol.attribute()->annotations()); - QCOMPARE(col.rights(), expectedCol.rights()); - expectedCollections.removeAt(i); - break; - } - } - } - QCOMPARE(expectedCollections.size(), 0); - } - - /** - * All kolab folders, if handled by kolab proxy or not, should receive an entity hidden attribute - */ - void ensureHiddenAttribute() { - CollectionFetchJob *fetchJob = new CollectionFetchJob(Collection::root(), CollectionFetchJob::Recursive); - fetchJob->fetchScope().setResource("akonadi_knut_resource_0"); - AKVERIFYEXEC(fetchJob); - - foreach (const Collection &col, fetchJob->collections()) { - if (!col.attribute()) { - continue; - } - if (Kolab::folderTypeFromString(Kolab::getFolderTypeAnnotation(col.attribute()->annotations())) != Kolab::MailType) { - //Kolab folder - QVERIFY(col.attribute()); - } - } - } - - void testRemoval() { - Akonadi::AgentInstance instance = AgentManager::self()->instance("akonadi_knut_resource_0"); - AgentManager::self()->removeInstance(instance); - - //Ensure all kolab collections are removed as well - QTest::qWait(10); - bool kolabCollectionsAreGone = false; - Akonadi::Collection::List rootCollections; - for (int i = 0; i < TIMEOUT/10; i++) { - Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(Akonadi::Collection::root()); - AKVERIFYEXEC(fetchJob); - rootCollections.clear(); - foreach (const Akonadi::Collection &col, fetchJob->collections()) { - if (col.resource().contains("kolabproxy")) { - rootCollections << col; - } - } - if (rootCollections.size() == 0) { - kolabCollectionsAreGone = true; - break; - } - QTest::qWait(10); - } - if (!kolabCollectionsAreGone) { - kDebug() << rootCollections; - } - QVERIFY(kolabCollectionsAreGone); - } - -}; - -QTEST_AKONADIMAIN( ProxyIntegrationTest, NoGUI ) - -#include "proxyintegrationtest.moc" diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/runimapcommand.py kdepim-runtime-15.08.0/resources/kolabproxy/tests/runimapcommand.py --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/runimapcommand.py 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/runimapcommand.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,284 +0,0 @@ -#! /usr/bin/env python - -import sys -import optparse -import inspect -import time -import imaplib -import re - - -class AnnotationsMixin: - - def __install_commands_in_imaplib(self): - imaplib.Commands['GETANNOTATION'] = ('AUTH', 'SELECTED') - imaplib.Commands['SETANNOTATION'] = ('AUTH', 'SELECTED') - - def __to_argument_string(self, arg): - if isinstance(arg, basestring): - return self._quote(arg) - elif arg is None: - return "NIL" - else: - return "(%s)" % (" ".join(self.__to_argument_string(item) - for item in arg),) - - def getannotation(self, *args): - # normally we would implement this command like the other - # commands in IMAP with an explicit list of parameters. For - # tests it's useful to be able to omit parameters or to send too - # many, so we allow an arbitrary number of parameters - self.__install_commands_in_imaplib() - args = tuple(self.__to_argument_string(item) for item in args) - typ, dat = self._simple_command('GETANNOTATION', *args) - return self._untagged_response(typ, dat, 'ANNOTATION') - - def setannotation(self, *args): - # normally we would implement this command like the other - # commands in IMAP with an explicit list of parameters. For - # tests it's useful to be able to omit parameters or to send too - # many, so we allow an arbitrary number of parameters - self.__install_commands_in_imaplib() - args = tuple(self.__to_argument_string(item) for item in args) - return self._simple_command('SETANNOTATION', *args) - - -class IMAP4_annotations(AnnotationsMixin, imaplib.IMAP4): - - pass - - -class IMAP4_SSL_annotations(AnnotationsMixin, imaplib.IMAP4_SSL): - - pass - - - -class ImapError(Exception): - - def __init__(self, host, port, imap_result): - Exception.__init__(self, "Unexpected response from imap server" - " (%r:%d):%r" % (host, port, imap_result)) - self.imap_result = imap_result - - -def extract_namespaces(raw_namespaces): - # Unfortunately, Python's imaplib doesn't contain a parser for IMAP - # data structures. This insufficient parser can at least extract - # most namespace definitions for common imap servers. - namespaces = [] - while raw_namespaces: - match = re.search(r'\("([^")]*)"[ \t]+"([^")]*)"\)', raw_namespaces) - if match: - namespaces.append((match.group(1), match.group(2))) - raw_namespaces = raw_namespaces[match.end(0):] - else: - break - return namespaces - - - -class ImapConnection(object): - - def __init__(self, host, port, login, password, use_ssl): - self.host = host - self.port = port - if use_ssl: - cls = IMAP4_SSL_annotations - else: - cls = IMAP4_annotations - self.error_class = cls.error - self.cached_namespaces = None - self.imap = cls(host, port) - self.auth_plain(login, password) - - def check_res(self, res, ok_responses=("OK",)): - assert len(res) == 2 - if res[0] not in ok_responses: - raise ImapError(self.host, self.port, res) - data = res[1] - # for some reason imaplib uses a one-element list containing - # None to indicate that no untagged responses came from the - # server. Translate this to an empty list. - if data == [None]: - data = [] - return data - - def lookup_namespace(self, mailbox): - if self.cached_namespaces is None: - self.cached_namespaces = extract_namespaces(self.namespace()[0]) - for prefix, separator in self.cached_namespaces: - if mailbox.startswith(prefix): - return (prefix, separator) - return (None, None) - - def convert_separator(self, mailbox): - split_mailbox = mailbox.split("/") - cache = dict() - - if self.cached_namespaces is None: - self.cached_namespaces = extract_namespaces(self.namespace()[0]) - - for prefix, separator in self.cached_namespaces: - if separator in cache: - converted_mailbox = cache[separator] - else: - converted_mailbox = separator.join(split_mailbox) - cache[separator] = converted_mailbox - if converted_mailbox.startswith(prefix): - return converted_mailbox - return mailbox - - def auth_plain(self, login, password): - self.check_res(self.imap.login(login, password)) - - def logout(self): - self.check_res(self.imap.logout(), ok_responses=("OK", "BYE")) - - @property - def capabilities(self): - return self.imap.capabilities - - def namespace(self): - return self.check_res(self.imap.namespace()) - - def create(self, mailbox): - self.check_res(self.imap.create(mailbox)) - - def delete(self, mailbox): - self.check_res(self.imap.delete(mailbox)) - - def rename(self, oldmailbox, newmailbox): - self.check_res(self.imap.rename(oldmailbox, newmailbox)) - - def getannotation(self, *args): - return self.check_res(self.imap.getannotation(*args)) - - def setannotation(self, *args): - return self.check_res(self.imap.setannotation(*args)) - - def setacl(self, *args): - return self.check_res(self.imap.setacl(*args)) - - def append(self, *args): - return self.check_res(self.imap.append(*args)) - - def list(self, *args): - return self.check_res(self.imap.list(*args)) - - -def command_create(connection, mailbox): - """Create a mailbox. Parameter: MAILBOX - Example: create INBOX/MyCalendar - """ - connection.create(connection.convert_separator(mailbox)) - -def command_setacl(connection, mailbox, user, rights): - """Set an ACL. Parameters: MAILBOX USERNAME RIGHTS - Example: setacl INBOX/MyCalendar someone@example.com lrs - """ - connection.setacl(connection.convert_separator(mailbox), user, rights) - -def command_setannotation(connection, mailbox, annotation, value): - """Set an annotation. Parameters: MAILBOX ANNOTATION VALUE - Example: setannotation INBOX/MyCalendar /vendor/kolab/folder-type event - """ - connection.setannotation(connection.convert_separator(mailbox), - annotation, ["value.shared", value]) - -def command_append(connection, mailbox, filename): - """Append a message to a mailbox. Parameters: MAILBOX FILENAME - Example: append INBOX/MyCalendar testdata/mytestmail - """ - connection.append(connection.convert_separator(mailbox), - None, None, open(filename).read()) - -def command_waitformailbox(connection, mailbox): - mailbox = connection.convert_separator(mailbox) - timeout = 20 - start = time.time() - while time.time() - start < timeout: - found = connection.list("", mailbox) - if found: - break - time.sleep(1) - else: - raise RuntimeError("waitformailbox timed out after %s seconds" % - (time.time() - start,)) - - -def find_commands(): - commands = [obj for obj in globals().values() - if inspect.isfunction(obj) - and obj.__name__.startswith("command_")] - commands.sort() - return commands - - -class OptionParserWithCommands(optparse.OptionParser): - - def format_help(self, formatter=None): - option_help = optparse.OptionParser.format_help(self, - formatter=formatter) - command_help = ["commands:"] - for command in find_commands(): - doc_lines = command.__doc__.splitlines() - command_help.append(" %-15s %s" - % (command.__name__[len("command_"):], - doc_lines[0])) - command_help.extend(doc_lines[1:]) - return option_help + "\n" + "\n".join(command_help) + "\n" - - -def main(): - parser = OptionParserWithCommands(usage=("%prog [options]" - " [command [arg1 ...]]")) - parser.set_defaults(host="localhost") - parser.add_option("--host", - help=("Hostname of the IMAP server" - " (default 'localhost').")) - parser.add_option("--port", type="int", - help=("Port number of the IMAP server (required).")) - parser.add_option("--ssl", action="store_true", - help=("Enable SSL.")) - parser.add_option("--user", - help=("Username for login (required).")) - parser.add_option("--password", - help=("Password for login (required).")) - - options, args = parser.parse_args() - - missing_required_option = False - for optname in "port user password".split(): - if getattr(options, optname) is None: - print >>sys.stderr, "Missing required option %r" % optname - missing_required_option = True - if missing_required_option: - sys.exit(1) - - if len(args) == 0: - print >>sys.stderr, "No command given" - sys.exit(1) - - command_name = args[0] - command_args = args[1:] - command = globals().get("command_" + command_name) - if command is None: - print >>sys.stderr, "Unknown command %r" % command_name - sys.exit(1) - - expected_num_args = len(inspect.getargspec(command)[0]) - 1 - if len(command_args) != expected_num_args: - print >>sys.stderr, "--%s requires %d arguments, got %d" % \ - (options.command, expected_num_args, len(command_args)) - sys.exit(1) - - connection = ImapConnection(options.host, options.port, - options.user, options.password, - options.ssl) - command(connection, *command_args) - connection.logout() - - -if __name__ == "__main__": - main() diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/task.ical kdepim-runtime-15.08.0/resources/kolabproxy/tests/task.ical --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/task.ical 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/task.ical 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -BEGIN:VCALENDAR -PRODID:-//K Desktop Environment//NONSGML libkcal 3.5//EN -VERSION:2.0 -BEGIN:VTODO -DTSTAMP:20090101T154017Z -ORGANIZER:MAILTO:vkrause@kde.org -CREATED:20040505T094143Z -UID:libkcal-1506191911.958 -LAST-MODIFIED:20040512T133925Z -SUMMARY:Add a demo task to this file -PRIORITY:3 -DUE;VALUE=DATE:20090101 -COMPLETED:20090101T133925Z -PERCENT-COMPLETE:100 -END:VTODO -END:VCALENDAR diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/testmail.mbox kdepim-runtime-15.08.0/resources/kolabproxy/tests/testmail.mbox --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/testmail.mbox 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/testmail.mbox 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -From: Volker Krause -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/testutils.cpp kdepim-runtime-15.08.0/resources/kolabproxy/tests/testutils.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/testutils.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/testutils.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - Copyright (c) 2013 Christian Mollekopf - - 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 "testutils.h" - -#include -#include -#include -#include -#include -#include -#include -#include //libkolab -#include - -#include "../kolabdefs.h" - -using namespace Akonadi; - -Akonadi::Item TestUtils::createImapItem(const KCalCore::Event::Ptr &event) { - const KMime::Message::Ptr &message = Kolab::KolabObjectWriter::writeEvent(event, Kolab::KolabV3, "Proxytest", QLatin1String("UTC") ); - Q_ASSERT(message); - Akonadi::Item imapItem1; - imapItem1.setMimeType( QLatin1String("message/rfc822") ); - imapItem1.setPayload( message ); - return imapItem1; -} - -TestUtils::MonitorPair TestUtils::monitor(Akonadi::Collection col, const char *signal) { - QSharedPointer monitor(new Akonadi::Monitor); - monitor->setCollectionMonitored(col); - QSharedPointer spy(new QSignalSpy(monitor.data(), signal)); - Q_ASSERT_X(spy->isValid(), "", signal); - return qMakePair, QSharedPointer >(spy, monitor); -} - -bool TestUtils::wait(const MonitorPair &pair) { - for (int i = 0; i < TIMEOUT/10 ; i++) { - if (pair.first->count() >= 1) { - kDebug() << pair.first->first(); - return true; - } - QTest::qWait(10); - } - return false; -} - -bool TestUtils::ensure(Akonadi::Collection col, const char *signal, Akonadi::Job *job) { - MonitorPair m = monitor(col, signal); - if (!job->exec()) { - return false; - } - return wait(m); -} - -bool TestUtils::ensurePopulated(QString agentinstance, int count) { - for (int i = 0; i < TIMEOUT/10 ; i++) { - Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(Collection::root(), CollectionFetchJob::Recursive); - fetchJob->fetchScope().setResource(agentinstance); - if (!fetchJob->exec()) { - return false; - } - if (fetchJob->collections().size() >= count) { - return true; - } - QTest::qWait(10); - } - return false; -} - -Akonadi::Collection TestUtils::findCollection(QString agentinstance, QString name) { - for (int i = 0; i < 500 ; i++) { - Akonadi::CollectionFetchJob *fetchJob = new Akonadi::CollectionFetchJob(Collection::root(), CollectionFetchJob::Recursive); - fetchJob->fetchScope().setResource(agentinstance); - if (!fetchJob->exec()) { - return Akonadi::Collection(); - } - foreach (const Collection &col, fetchJob->collections()) { - if (col.name().contains(name)) { - return col; - } - } - QTest::qWait(10); - } - return Akonadi::Collection(); -} diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/testutils.h kdepim-runtime-15.08.0/resources/kolabproxy/tests/testutils.h --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/testutils.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/testutils.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ - -/* - Copyright (c) 2013 Christian Mollekopf - - 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 -#include -#include -#include -#include - -using namespace Akonadi; -#define TIMEOUT 1000 -struct TestUtils -{ - static Akonadi::Item createImapItem(const KCalCore::Event::Ptr &event); - - typedef QPair, QSharedPointer > MonitorPair; - - static MonitorPair monitor(Akonadi::Collection col, const char *signal); - static bool wait(const MonitorPair &pair); - static bool ensure(Akonadi::Collection col, const char *signal, Akonadi::Job *job); - static bool ensurePopulated(QString agentinstance, int count); - static Akonadi::Collection findCollection(QString agentinstance, QString name); -}; diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/config-mysql-db.xml kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/config-mysql-db.xml --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/config-mysql-db.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/config-mysql-db.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ - - kdehome - xdgconfig-mysql.db - xdglocal - akonadi_knut_resource - true - mysql - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/config-mysql-fs.xml kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/config-mysql-fs.xml --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/config-mysql-fs.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/config-mysql-fs.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ - - kdehome - xdgconfig-mysql.fs - xdglocal - akonadi_knut_resource - true - mysql - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/config-postgresql-db.xml kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/config-postgresql-db.xml --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/config-postgresql-db.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/config-postgresql-db.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ - - kdehome - xdgconfig-postgresql.db - xdglocal - akonadi_knut_resource - true - postgresql - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/config-postgresql-fs.xml kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/config-postgresql-fs.xml --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/config-postgresql-fs.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/config-postgresql-fs.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ - - kdehome - xdgconfig-postgresql.fs - xdglocal - akonadi_knut_resource - true - postgresql - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/config-sqlite-db.xml kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/config-sqlite-db.xml --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/config-sqlite-db.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/config-sqlite-db.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ - - kdehome - xdgconfig-sqlite.db - xdglocal - akonadi_knut_resource - true - sqlite - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -[ProcessedDefaults] -defaultaddressbook=done -defaultcalendar=done -defaultnotebook=done diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/kdehome/share/config/akonadi_knut_resource_0rc 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -[General] -DataFile[$e]=$KDEHOME/testdata-res1.xml -FileWatchingEnabled=false - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/kdehome/share/config/kdebugrc kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/kdehome/share/config/kdebugrc --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/kdehome/share/config/kdebugrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/kdehome/share/config/kdebugrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -DisableAll=false - -[0] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[264] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[5250] -InfoOutput=2 - -[7009] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[7011] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[7012] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[7014] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=0 -FatalFilename[$e]=kdebug.dbg -FatalOutput=0 -InfoFilename[$e]=kdebug.dbg -InfoOutput=0 -WarnFilename[$e]=kdebug.dbg -WarnOutput=0 - -[7021] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/kdehome/share/config/kdedrc kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/kdehome/share/config/kdedrc --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/kdehome/share/config/kdedrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/kdehome/share/config/kdedrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[General] -CheckSycoca=false -CheckFileStamps=false diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/kdehome/testdata-res1.xml kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/kdehome/testdata-res1.xml --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/kdehome/testdata-res1.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/kdehome/testdata-res1.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ - - - - - testmailbody - From: <test@user.tst> - \SEEN - \FLAGGED - \DRAFT - - - - /shared/vendor/kolab/folder-type event - - - /shared/vendor/kolab/folder-type contact - - - /shared/vendor/kolab/folder-type note - - - /shared/vendor/kolab/folder-type task - - - /shared/vendor/kolab/folder-type journal - - - /shared/vendor/kolab/folder-type configuration - - - /shared/vendor/kolab/folder-type freebusy - - - /shared/vendor/kolab/folder-type file - - - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/xdgconfig-mysql.db/akonadi/akonadiserverrc kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/xdgconfig-mysql.db/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/xdgconfig-mysql.db/akonadi/akonadiserverrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/xdgconfig-mysql.db/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -[%General] -ExternalPayload=false - -[Search] -Manager=Dummy diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/xdgconfig-mysql.fs/akonadi/akonadiserverrc kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/xdgconfig-mysql.fs/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/xdgconfig-mysql.fs/akonadi/akonadiserverrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/xdgconfig-mysql.fs/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -[%General] -SizeThreshold=0 -ExternalPayload=true - -[Search] -Manager=Dummy diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/xdgconfig-postgresql.db/akonadi/akonadiserverrc kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/xdgconfig-postgresql.db/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/xdgconfig-postgresql.db/akonadi/akonadiserverrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/xdgconfig-postgresql.db/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -[%General] -Driver=QPSQL -ExternalPayload=false - -[Search] -Manager=Dummy - -[QPSQL] -StartServer=true diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/xdgconfig-postgresql.fs/akonadi/akonadiserverrc kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/xdgconfig-postgresql.fs/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/xdgconfig-postgresql.fs/akonadi/akonadiserverrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/xdgconfig-postgresql.fs/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -[%General] -Driver=QPSQL -SizeThreshold=0 -ExternalPayload=true - -[Search] -Manager=Dummy - -[QPSQL] -StartServer=true diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/xdgconfig-sqlite.db/akonadi/akonadiserverrc kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/xdgconfig-sqlite.db/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/resources/kolabproxy/tests/unittestenv/xdgconfig-sqlite.db/akonadi/akonadiserverrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/tests/unittestenv/xdgconfig-sqlite.db/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -[%General] -# This is a slightly adjusted version of the QSQLITE driver from Qt -# It is provided by akonadi itself -Driver=QSQLITE3 - -[Debug] -Tracer=null - -[Search] -Manager=Dummy diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/upgradejob.cpp kdepim-runtime-15.08.0/resources/kolabproxy/upgradejob.cpp --- kdepim-runtime-4.14.6/resources/kolabproxy/upgradejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/upgradejob.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2012 Christian Mollekopf - * - * 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 "upgradejob.h" - -#include "kolabdefs.h" -#include "kolabhandler.h" - -#include "collectionannotationsattribute.h" //from shared - -#include -#include -#include -#include -#include - -#define IMAP_COLLECTION "IMAP_COLLECTION" -#define FOLDER_TYPE "FOLDER_TYPE" - -UpgradeJob::UpgradeJob( Kolab::Version targetVersion, - const Akonadi::AgentInstance &instance, - QObject *parent ) - : Akonadi::Job( parent ), - m_agentInstance( instance ), - m_targetVersion( targetVersion ) -{ - kDebug() << targetVersion; -} - -void UpgradeJob::doStart() -{ - kDebug(); - //Get all subdirectories of kolab resource - Akonadi::CollectionFetchJob *job = - new Akonadi::CollectionFetchJob( Akonadi::Collection::root(), - Akonadi::CollectionFetchJob::Recursive, this ); - job->fetchScope().setResource( m_agentInstance.identifier() ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(collectionFetchResult(KJob*)) ); -} - -void UpgradeJob::collectionFetchResult( KJob *job ) -{ - kDebug(); - if ( job->error() ) { - kDebug() << job->errorString(); - emitResult(); - return; - } - int collCount = 0; - Akonadi::Collection::List collections = - static_cast( job )->collections(); - foreach ( const Akonadi::Collection &col, collections ) { - //FIXME: - // find a way to properly detect shared folders. - // Collection::CanCreateCollection never applies to shared folders, - // but that's just a workaround. - if ( !( col.rights() & Akonadi::Collection::CanCreateCollection ) || - !( col.rights() & Akonadi::Collection::CanChangeItem ) ) { - kDebug() << "skipping shared/non-editable folder"; - continue; - } - KolabV2::FolderType folderType = KolabV2::Mail; - Akonadi::CollectionAnnotationsAttribute *attr = 0; - if ( ( attr = col.attribute() ) ) { - folderType = - KolabV2::folderTypeFromString( Kolab::getFolderTypeAnnotation( attr->annotations() ) ); - } - if ( folderType == KolabV2::Mail ) { - //kWarning() << "Wrong folder annotation " - // << "(this should never happen, the annotation is probably not available)"; - continue; - } - - kDebug() << "upgrading " << col.id(); - collCount++; - Akonadi::ItemFetchJob *itemFetchJob = new Akonadi::ItemFetchJob( col, this ); - itemFetchJob->fetchScope().fetchFullPayload( true ); - itemFetchJob->fetchScope().setCacheOnly( false ); - itemFetchJob->setProperty( IMAP_COLLECTION, QVariant::fromValue( col ) ); - itemFetchJob->setProperty( FOLDER_TYPE, QVariant::fromValue( static_cast(folderType) ) ); - connect( itemFetchJob, SIGNAL(result(KJob*)), this, SLOT(itemFetchResult(KJob*)) ); - } - //Percent is only emitted when Bytes is the unit - setTotalAmount( Bytes, collCount ); - if ( !collCount ) { - emitResult(); - } -} - -void UpgradeJob::itemFetchResult( KJob *job ) -{ - if ( job->error() ) { - kDebug() << job->errorString(); - checkResult(); - return; // Akonadi::Job propagates that automatically - } - Akonadi::ItemFetchJob *j = static_cast( job ); - if ( j->items().isEmpty() ) { - qWarning() << "no items fetched "; - checkResult(); - return; - } - - const Akonadi::Collection imapCollection = - j->property( IMAP_COLLECTION ).value(); - if ( !imapCollection.isValid() ) { - qWarning() << "invalid imap collection"; - checkResult(); - return; - } - - KolabV2::FolderType folderType = - static_cast( j->property(FOLDER_TYPE).toInt() ); - - KolabHandler::Ptr handler = KolabHandler::createHandler( folderType, imapCollection ); - - if ( !handler ) { - qWarning() << "invalid handler"; - checkResult(); - return; - } - handler->setKolabFormatVersion( m_targetVersion ); - - foreach ( Akonadi::Item imapItem, j->items() ) { //krazy:exclude=foreach - if ( !imapItem.isValid() ) { - qWarning() << "invalid item"; - continue; - } - kDebug() << "updating item " << imapItem.id(); - const Akonadi::Item::List &translatedItems = - handler->translateItems( Akonadi::Item::List() << imapItem ); - - if ( translatedItems.size() != 1 ) { - qWarning() << "failed to translateItems" << translatedItems.size(); - continue; - } - handler->toKolabFormat( translatedItems.first(), imapItem ); - Akonadi::ItemModifyJob *modJob = new Akonadi::ItemModifyJob( imapItem, this ); - connect( modJob, SIGNAL(result(KJob*)), this, SLOT(itemModifyResult(KJob*)) ); - } - checkResult(); -} - -void UpgradeJob::checkResult() -{ - setProcessedAmount( Bytes, processedAmount( Bytes ) + 1 ); - if ( processedAmount( Bytes ) >= totalAmount( Bytes ) ) { - emitResult(); - } -} - -void UpgradeJob::itemModifyResult( KJob *job ) -{ - if ( job->error() ) { - kDebug() << job->errorString(); - return; // Akonadi::Job propagates that automatically - } - kDebug() << "modjob done"; -} - diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/upgradejob.h kdepim-runtime-15.08.0/resources/kolabproxy/upgradejob.h --- kdepim-runtime-4.14.6/resources/kolabproxy/upgradejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/upgradejob.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2012 Christian Mollekopf - * - * 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 KOLABPROXY_UPGRADEJOB_H -#define KOLABPROXY_UPGRADEJOB_H - -#include -#include - -#include //libkolab - -/** - * Fetch all items of an imap resource, read them, and write them out in the target version. - */ -class UpgradeJob : public Akonadi::Job -{ - Q_OBJECT - public: - explicit UpgradeJob( Kolab::Version targetVersion, - const Akonadi::AgentInstance &instance, - QObject *parent = 0 ); - - protected: - void doStart(); - - private slots: - void collectionFetchResult( KJob *job ); - void itemFetchResult( KJob *job ); - void itemModifyResult( KJob *job ); - - private: - void checkResult(); - Akonadi::AgentInstance m_agentInstance; - Kolab::Version m_targetVersion; -}; - -#endif // UPGRADEJOB_H diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/wizard/CMakeLists.txt kdepim-runtime-15.08.0/resources/kolabproxy/wizard/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/kolabproxy/wizard/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/wizard/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ - -install( - FILES kolabwizard.desktop kolabwizard.es kolabwizard.ui - DESTINATION ${DATA_INSTALL_DIR}/akonadi/accountwizard/kolab -) diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/wizard/kolabwizard.desktop kdepim-runtime-15.08.0/resources/kolabproxy/wizard/kolabwizard.desktop --- kdepim-runtime-4.14.6/resources/kolabproxy/wizard/kolabwizard.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/wizard/kolabwizard.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -[Desktop Entry] -Name=Kolab Groupware Server -Name[bg]=Сървър Kolab Groupware -Name[bs]=Server kolaborativnog softvera -Name[ca]=Servidor de treball en grup Kolab -Name[ca@valencia]=Servidor de treball en grup Kolab -Name[cs]=Kolab Groupware server -Name[da]=Kolab groupware-server -Name[de]=Kolab Groupware-Server -Name[el]=Εξυπηρετητής Groupware Kolab -Name[en_GB]=Kolab Groupware Server -Name[es]=Servidor de trabajo en grupo Kolab -Name[et]=Kolabi grupitöö server -Name[fi]=Kolab-työryhmäpalvelin -Name[fr]=Serveur de logiciels de collaboration Kolab -Name[ga]=Freastalaí Groupware Kolab -Name[gl]=Servidor de Traballo en Grupo Kolab -Name[hu]=Kolab csoportmunka-kiszolgáló -Name[ia]=Servitor de Kolab Groupware -Name[it]=Server di groupware Kolab -Name[ja]=Kolab グループウェアサーバ -Name[kk]=Kolab топтық іс сервері -Name[km]=ម៉ាស៊ីន​បម្រើ Kolab Groupware -Name[ko]=Kolab 그룹웨어 서버 -Name[lt]=Kolab grupinio darbo serveris -Name[lv]=Kolab grupdarba serveris -Name[nb]=Kolab groupware-tjener -Name[nds]=Kolab-Arbeitkoppelserver -Name[nl]=Kolab groupwareserver -Name[nn]=Kolab Groupware-tenar -Name[pl]=Serwer Groupware Kolab -Name[pt]=Servidor de Groupware Kolab -Name[pt_BR]=Servidor groupware Kolab -Name[ro]=Server Kolab Groupware -Name[ru]=Сервер совместной работы Kolab -Name[sk]=Groupware Server Kolab -Name[sl]=Strežnik za skupinsko delo Kolab -Name[sr]=Колабов групверски сервер -Name[sr@ijekavian]=Колабов групверски сервер -Name[sr@ijekavianlatin]=Kolabov grupverski server -Name[sr@latin]=Kolabov grupverski server -Name[sv]=Kolab grupprogramserver -Name[tr]=Kolab Groupware Sunucusu -Name[uk]=Сервер групової роботи Kolab -Name[x-test]=xxKolab Groupware Serverxx -Name[zh_CN]=Kolab 群件服务器 -Name[zh_TW]=Kolab 群組伺服器 -Icon=kolab -Comment=Kolab Groupware Server -Comment[bg]=Сървър Kolab Groupware -Comment[bs]=Server kolaborativnog softvera -Comment[ca]=Servidor de treball en grup Kolab -Comment[ca@valencia]=Servidor de treball en grup Kolab -Comment[cs]=Kolab Groupware server -Comment[da]=Kolab groupware-server -Comment[de]=Kolab Groupware-Server -Comment[el]=Εξυπηρετητής Groupware Kolab -Comment[en_GB]=Kolab Groupware Server -Comment[es]=Servidor de trabajo en grupo Kolab -Comment[et]=Kolabi grupitöö server -Comment[fi]=Kolab-työryhmäpalvelin -Comment[fr]=Serveur de logiciels de collaboration Kolab -Comment[ga]=Freastalaí Groupware Kolab -Comment[gl]=Servidor de traballo en grupo Kolab -Comment[hu]=Kolab csoportmunka-kiszolgáló -Comment[ia]=Servitor de Kolab Groupware -Comment[it]=Server di groupware Kolab -Comment[ja]=Kolab グループウェアサーバ -Comment[kk]=Kolab топтық іс сервері -Comment[km]=ម៉ាស៊ីន​បម្រើ Kolab Groupware -Comment[ko]=Kolab 그룹웨어 서버 -Comment[lt]=Kolab grupinio darbo serveris -Comment[lv]=Kolab grupdarba serveris -Comment[nb]=Kolab groupware-tjener -Comment[nds]=Kolab-Arbeitkoppelserver -Comment[nl]=Kolab-groupware-server -Comment[nn]=Kolab Groupware-tenar -Comment[pl]=Serwer Kolab Groupware -Comment[pt]=Servidor de 'Groupware' Kolab -Comment[pt_BR]=Servidor groupware Kolab -Comment[ro]=Server Kolab Groupware -Comment[ru]=Сервер совместной работы Kolab -Comment[sk]=Groupware Server Kolab -Comment[sl]=Strežnik za skupinsko delo Kolab -Comment[sr]=Колабов групверски сервер -Comment[sr@ijekavian]=Колабов групверски сервер -Comment[sr@ijekavianlatin]=Kolabov grupverski server -Comment[sr@latin]=Kolabov grupverski server -Comment[sv]=Kolab grupprogramserver -Comment[tr]=Kolab Groupware Sunucusu -Comment[uk]=Сервер групової роботи Kolab -Comment[x-test]=xxKolab Groupware Serverxx -Comment[zh_CN]=Kolab 群件服务器 -Comment[zh_TW]=Kolab 群組伺服器 - -[Wizard] -Type=message/rfc822,text/directory,text/calendar,text/x-vnd.akonadi.note -Script=kolabwizard.es - -[Translate] -Filename=accountwizard_kolab diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/wizard/kolabwizard.es kdepim-runtime-15.08.0/resources/kolabproxy/wizard/kolabwizard.es --- kdepim-runtime-4.14.6/resources/kolabproxy/wizard/kolabwizard.es 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/wizard/kolabwizard.es 1970-01-01 00:00:00.000000000 +0000 @@ -1,192 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - Copyright (c) 2010 Casey Link - - 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. -*/ - -// add this function to trim user input of whitespace when needed -String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); }; - -var page = Dialog.addPage( "kolabwizard.ui", qsTr("Personal Settings") ); -var userChangedServerAddress = false; - -page.widget().nameEdit.text = SetupManager.name() -page.widget().emailEdit.text = SetupManager.email() -page.widget().passwordEdit.text = SetupManager.password() -guessServerName(); - -if ( SetupManager.personalDataAvailable() ) { - page.widget().nameEdit.visible = false; - page.widget().nameLabel.visible = false; - page.widget().emailEdit.visible = false; - page.widget().emailLabel.visible = false; - page.widget().passwordEdit.visible = false; - page.widget().passwordLabel.visible = false; -} - - -function guessServerName() -{ - if ( userChangedServerAddress == true ) { - return; - } - - var email = page.widget().emailEdit.text; - var pos = email.indexOf( "@" ); - if ( pos >= 0 && (pos + 1) < email.length ) { - var server = email.slice( pos + 1, email.length ); - page.widget().serverAddress.text = server; - } - - userChangedServerAddress = false; -} - -function emailChanged( arg ) -{ - validateInput(); - guessServerName(); -} - -function serverChanged( arg ) -{ - validateInput(); - if ( arg == "" ) { - userChangedServerAddress = false; - } else { - userChangedServerAddress = true; - } -} - -function validateInput() -{ - if ( page.widget().serverAddress.text.trim() == "" || page.widget().emailEdit.text.trim() == "" ) { - page.setValid( false ); - } else { - page.setValid( true ); - } -} - -// stage 1, setup identity and run imap server test -// stage 2, smtp setup (no server test), ldap and korganizer -var stage = 1; -var identity; // global so it can be accesed in setup and testOk - -var kolabRes; -function setup() -{ - var serverAddress = page.widget().serverAddress.text.trim(); - if ( stage == 1 ) { - SetupManager.openWallet(); - kolabRes = SetupManager.createResource( "akonadi_kolabproxy_resource" ); - - identity = SetupManager.createIdentity(); - identity.setEmail( page.widget().emailEdit.text ); - identity.setRealName( page.widget().nameEdit.text ); - - ServerTest.test( serverAddress, "imap" ); - } else { // stage 2 - var smtp = SetupManager.createTransport( "smtp" ); - smtp.setName( serverAddress ); - smtp.setHost( serverAddress ); - smtp.setPort( 465 ); - smtp.setEncryption( "SSL" ); - smtp.setAuthenticationType( "plain" ); // using plain is ok, because we are using SSL. - smtp.setUsername( page.widget().emailEdit.text ); - smtp.setPassword( page.widget().passwordEdit.text ); - identity.setTransport( smtp ); - - var ldap = SetupManager.createLdap(); - ldap.setUser( page.widget().emailEdit.text ); - ldap.setServer( serverAddress ); - - var korganizer = SetupManager.createConfigFile( "korganizerrc" ); - korganizer.setName( "korganizer" ); - korganizer.setConfig( "FreeBusy Retrieve", "FreeBusyFullDomainRetrieval","true"); - korganizer.setConfig( "FreeBusy Retrieve", "FreeBusyRetrieveAuto", "true" ); - korganizer.setConfig( "FreeBusy Retrieve", "FreeBusyRetrieveUrl", "https://" + serverAddress + "/freebusy/" ); - SetupManager.execute(); - } -} - -function testResultFail() -{ - testOk( -1 ); -} - -var imapRes; -function testOk( arg ) -{ - print("testOk arg =", arg); - imapRes = SetupManager.createResource( "akonadi_imap_resource" ); - imapRes.setName( page.widget().serverAddress.text.trim() ); - imapRes.setOption( "ImapServer", page.widget().serverAddress.text.trim() ); - imapRes.setOption( "UserName", page.widget().emailEdit.text.trim() ); - imapRes.setOption( "Password", page.widget().passwordEdit.text.trim() ); - imapRes.setOption( "UseDefaultIdentity", false ); - imapRes.setOption( "AccountIdentity", identity.uoid() ); - imapRes.setOption( "DisconnectedModeEnabled", true ); - imapRes.setOption( "IntervalCheckTime", 60 ); - imapRes.setOption( "SubscriptionEnabled", true ); - imapRes.setOption( "SieveSupport", true ); - imapRes.setOption( "Authentication", 7 ); // ClearText - if ( arg == "ssl" ) { - // The ENUM used for authentication (in the imap resource only) - imapRes.setOption( "Safety", "SSL" ); // SSL/TLS - imapRes.setOption( "ImapPort", 993 ); - } else if ( arg == "tls" ) { // tls is really STARTTLS - imapRes.setOption( "Safety", "STARTTLS" ); // STARTTLS - imapRes.setOption( "ImapPort", 143 ); - } else if ( arg == "none" ) { - imapRes.setOption( "Safety", "NONE" ); // No encryption - imapRes.setOption( "ImapPort", 143 ); - } else { - // safe default fallback in case server test failed - imapRes.setOption( "Safety", "STARTTLS" ); - imapRes.setOption( "ImapPort", 143 ); - } - imapRes.finished.connect(configureKolabVersion); - stage = 2; - setup(); -} - -function configureKolabVersion( arg ) -{ - var kolabVersion = page.widget().versionComboBox.currentIndex; - var kolabproxyConfig = SetupManager.createConfigFile( "akonadi_kolabproxy_resourcerc" ); - kolabproxyConfig.setName("kolabproxy"); - if (kolabVersion == 0) { - kolabproxyConfig.setConfig( "KolabProxyResourceSettings", "KolabFormatVersion" + imapRes.identifier(), "0"); - } else { - kolabproxyConfig.setConfig( "KolabProxyResourceSettings", "KolabFormatVersion" + imapRes.identifier(), "1"); - } - //We have to write to the config file manually as the setup process has already finished - kolabproxyConfig.write(); - //And load the config - kolabRes.reconfigure(); -} - -try { - ServerTest.testFail.connect(testResultFail); - ServerTest.testResult.connect(testOk); - page.widget().emailEdit.textChanged.connect(emailChanged); - page.widget().serverAddress.textChanged.connect(serverChanged); - page.pageLeftNext.connect(setup); -} catch (e) { - print(e); -} - -validateInput(); diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/wizard/kolabwizard.ui kdepim-runtime-15.08.0/resources/kolabproxy/wizard/kolabwizard.ui --- kdepim-runtime-4.14.6/resources/kolabproxy/wizard/kolabwizard.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/wizard/kolabwizard.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ - - - kolabWizard - - - - 0 - 0 - 368 - 124 - - - - - QFormLayout::ExpandingFieldsGrow - - - - - &Name: - - - nameEdit - - - - - - - - - - &Email: - - - emailEdit - - - - - - - - - - &Password: - - - passwordEdit - - - - - - - QLineEdit::Password - - - - - - - &Server Address: - - - serverAddress - - - - - - - - - - Kolab Version: - - - - - - - 1 - - - - v2 - - - - - v3 - - - - - - - - - KLineEdit - QLineEdit -
klineedit.h
-
-
- - serverAddress - - - -
diff -Nru kdepim-runtime-4.14.6/resources/kolabproxy/wizard/Messages.sh kdepim-runtime-15.08.0/resources/kolabproxy/wizard/Messages.sh --- kdepim-runtime-4.14.6/resources/kolabproxy/wizard/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/kolabproxy/wizard/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -#! /usr/bin/env bash -$EXTRACTRC *.ui >> rc.cpp -$XGETTEXT *.cpp -o $podir/accountwizard_kolab.pot -$XGETTEXT -kqsTr *.es -j -o $podir/accountwizard_kolab.pot diff -Nru kdepim-runtime-4.14.6/resources/localbookmarks/CMakeLists.txt kdepim-runtime-15.08.0/resources/localbookmarks/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/localbookmarks/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/localbookmarks/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -include_directories( - ${kdepim-runtime_SOURCE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} - ${Boost_INCLUDE_DIR} -) - -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - - -########### next target ############### - -set( localbookmarksresource_SRCS - localbookmarksresource.cpp -) - -install( FILES localbookmarksresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) - - -kde4_add_kcfg_files(localbookmarksresource_SRCS settings.kcfgc) -kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/localbookmarksresource.kcfg org.kde.Akonadi.LocalBookmarks.Settings) -qt4_add_dbus_adaptor(localbookmarksresource_SRCS - ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.LocalBookmarks.Settings.xml settings.h Settings -) - -kde4_add_executable(akonadi_localbookmarks_resource ${localbookmarksresource_SRCS}) - -if (Q_WS_MAC) - set_target_properties(akonadi_localbookmarks_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) - set_target_properties(akonadi_localbookmarks_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.LocalBookmarks") - set_target_properties(akonadi_localbookmarks_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi LocalBookmarks Resource") -endif () - -target_link_libraries(akonadi_localbookmarks_resource ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTDBUS_LIBRARY} ${KDE4_KIO_LIBS}) - -install(TARGETS akonadi_localbookmarks_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) - diff -Nru kdepim-runtime-4.14.6/resources/localbookmarks/localbookmarksresource.cpp kdepim-runtime-15.08.0/resources/localbookmarks/localbookmarksresource.cpp --- kdepim-runtime-4.14.6/resources/localbookmarks/localbookmarksresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/localbookmarks/localbookmarksresource.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,221 +0,0 @@ -/* - Copyright (c) 2006 Till Adam - - 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 "localbookmarksresource.h" - -#include "settings.h" -#include "settingsadaptor.h" - -#include -#include -#include -#include - -using namespace Akonadi; - -LocalBookmarksResource::LocalBookmarksResource( const QString &id ) - : ResourceBase( id ), mBookmarkManager( 0 ) -{ - new SettingsAdaptor( Settings::self() ); - QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ), - Settings::self(), QDBusConnection::ExportAdaptors ); - - const QString fileName = Settings::self()->path(); - if (!fileName.isEmpty() ) { - mBookmarkManager = KBookmarkManager::managerForFile( fileName, name() ); - } -} - -LocalBookmarksResource::~LocalBookmarksResource() -{ -} - -bool LocalBookmarksResource::retrieveItem( const Akonadi::Item &item, const QSet& ) -{ - itemRetrieved( item ); - - return true; -} - -void LocalBookmarksResource::configure( WId windowId ) -{ - const QString oldFile = Settings::self()->path(); - - KUrl url; - if ( !oldFile.isEmpty() ) - url = KUrl::fromPath( oldFile ); - else - url = KUrl::fromPath( QDir::homePath() ); - - const QString newFile = KFileDialog::getOpenFileNameWId( url, QLatin1String("*.xml |") + i18nc( "Filedialog filter for *.xml", - "XML Bookmark file"), - windowId, i18n( "Select Bookmarks File" ) ); - - if ( newFile.isEmpty() ) { - emit configurationDialogRejected(); - return; - } - - if ( oldFile == newFile ) { - emit configurationDialogAccepted(); - return; - } - - Settings::self()->setPath( newFile ); - - mBookmarkManager = KBookmarkManager::managerForFile( newFile, name() ); - - Settings::self()->writeConfig(); - synchronize(); - - emit configurationDialogAccepted(); -} - -void LocalBookmarksResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ) -{ - if ( item.mimeType() != QLatin1String( "application/x-xbel" ) ) { - cancelTask( i18n( "Item is not a bookmark" ) ); - return; - } - - KBookmark bookmark = item.payload(); - KBookmark bookmarkGroup = mBookmarkManager->findByAddress( collection.remoteId() ); - if ( !bookmarkGroup.isGroup() ) { - cancelTask( i18n( "Bookmark group not found" ) ); - return; - } - - KBookmarkGroup group = bookmarkGroup.toGroup(); - group.addBookmark( bookmark ); - - // saves the file - mBookmarkManager->emitChanged( group ); - - changeCommitted( item ); -} - -void LocalBookmarksResource::itemChanged( const Akonadi::Item& item, const QSet& ) -{ - KBookmark bookmark = item.payload(); - - // saves the file - mBookmarkManager->emitChanged( bookmark.parentGroup() ); - - changeCommitted( item ); -} - -void LocalBookmarksResource::itemRemoved( const Akonadi::Item &item ) -{ - const KBookmark bookmark = mBookmarkManager->findByAddress( item.remoteId() ); - KBookmarkGroup bookmarkGroup = bookmark.parentGroup(); - - bookmarkGroup.deleteBookmark( bookmark ); - - // saves the file - mBookmarkManager->emitChanged( bookmarkGroup ); - - changeCommitted( item ); -} - -static Collection::List listRecursive( const KBookmarkGroup &parentGroup, const Collection &parentCollection ) -{ - const QStringList mimeTypes = QStringList() << QLatin1String("application/x-xbel") << Collection::mimeType(); - - Collection::List collections; - - for ( KBookmark it = parentGroup.first(); !it.isNull(); it = parentGroup.next( it ) ) { - - if ( !it.isGroup() ) - continue; - - KBookmarkGroup bookmarkGroup = it.toGroup(); - Collection collection; - collection.setName( bookmarkGroup.fullText() + QLatin1Char('(') + bookmarkGroup.address() + QLatin1Char(')') ); // has to be unique - collection.setRemoteId( bookmarkGroup.address() ); - collection.setParentCollection( parentCollection ); - collection.setContentMimeTypes( mimeTypes ); // ### - - collections << collection; - collections << listRecursive( bookmarkGroup, collection ); - } - - return collections; -} - -void LocalBookmarksResource::retrieveCollections() -{ - Collection root; - root.setParentCollection( Collection::root() ); - root.setRemoteId( Settings::self()->path() ); - root.setName( name() ); - QStringList mimeTypes; - mimeTypes << QLatin1String("application/x-xbel") << Collection::mimeType(); - root.setContentMimeTypes( mimeTypes ); - - - if (!mBookmarkManager) { - mBookmarkManager = KBookmarkManager::managerForFile( Settings::self()->path(), name() ); - } - - Collection::List list; - list << root; - list << listRecursive( mBookmarkManager->root(), root ); - - collectionsRetrieved( list ); -} - -void LocalBookmarksResource::retrieveItems( const Akonadi::Collection &collection ) -{ - if ( !collection.isValid() ) { - cancelTask( i18n( "Bookmark collection is invalid" ) ); - return; - } - - KBookmarkGroup bookmarkGroup; - if ( collection.remoteId() == Settings::self()->path() ) { - bookmarkGroup = mBookmarkManager->root(); - } else { - - const KBookmark bookmark = mBookmarkManager->findByAddress( collection.remoteId() ); - if ( bookmark.isNull() || !bookmark.isGroup() ) { - cancelTask( i18n( "Bookmark collection is invalid" ) ); - return; - } - - bookmarkGroup = bookmark.toGroup(); - } - - Item::List itemList; - for ( KBookmark it = bookmarkGroup.first(); !it.isNull(); it = bookmarkGroup.next( it ) ) { - - if ( it.isGroup() || it.isSeparator() || it.isNull() ) - continue; - - Item item; - item.setRemoteId( it.address() ); - item.setMimeType( QLatin1String("application/x-xbel") ); - item.setPayload( it ); - itemList.append( item ); - } - - itemsRetrieved( itemList ); -} - -AKONADI_RESOURCE_MAIN( LocalBookmarksResource ) - diff -Nru kdepim-runtime-4.14.6/resources/localbookmarks/localbookmarksresource.desktop kdepim-runtime-15.08.0/resources/localbookmarks/localbookmarksresource.desktop --- kdepim-runtime-4.14.6/resources/localbookmarks/localbookmarksresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/localbookmarks/localbookmarksresource.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,102 +0,0 @@ -[Desktop Entry] -Name=Local Bookmarks -Name[ar]=علامات محلية -Name[bs]=Lokale oznake -Name[ca]=Adreces d'interès locals -Name[ca@valencia]=Punts locals -Name[cs]=Místní záložky -Name[da]=Lokale bogmærker -Name[de]=Lokale Lesezeichen -Name[el]=Τοπικοί σελιδοδείκτες -Name[en_GB]=Local Bookmarks -Name[es]=Marcadores locales -Name[et]=Kohalikud järjehoidjad -Name[fi]=Paikalliset kirjanmerkit -Name[fr]=Signets locaux -Name[ga]=Leabharmharcanna Logánta -Name[gl]=Marcadores Locais -Name[hu]=Helyi könyvjelzők -Name[ia]=Favoritos local -Name[it]=Segnalibri locali -Name[ja]=ローカルブックマーク -Name[kk]=Жергілікті бетбелгілер -Name[km]=ចំណាំ​មូលដ្ឋាន -Name[ko]=로컬 책갈피 -Name[lt]=Vietinis adresynas -Name[lv]=Lokālās grāmatzīmes -Name[nb]=Lokale bokmerker -Name[nds]=Lokaal Leestekens -Name[nl]=Lokale bladwijzers -Name[nn]=Lokalbokmerke -Name[pa]=ਲੋਕਲ ਬੁੱਕਮਾਰਕ -Name[pl]=Zakładki lokalne -Name[pt]=Favoritos Locais -Name[pt_BR]=Favoritos locais -Name[ro]=Semne de carte locale -Name[ru]=Локальные закладки -Name[sk]=Miestne záložky -Name[sl]=Krajevni zaznamki -Name[sr]=Локални обележивачи -Name[sr@ijekavian]=Локални обиљеживачи -Name[sr@ijekavianlatin]=Lokalni obilježivači -Name[sr@latin]=Lokalni obeleživači -Name[sv]=Lokala bokmärken -Name[tr]=Yerel Yer İmleri -Name[uk]=Локальні закладки -Name[x-test]=xxLocal Bookmarksxx -Name[zh_CN]=本地书签 -Name[zh_TW]=本地書籤 -Comment=Loads data from a local bookmarks file -Comment[ar]=تحمل البيانات من ملف العلامات المحلية -Comment[bs]=Učitava podatke iz datoteke lokalnih oznaka -Comment[ca]=Carrega les dades des d'un fitxer d'adreces d'interès local -Comment[ca@valencia]=Carrega dades des d'un fitxer de punts local -Comment[cs]=Načítá data z místních záložek -Comment[da]=Indlæser data fra en lokal bogmærkefil -Comment[de]=Daten werden aus einer lokalen Lesezeichen-Datei geladen -Comment[el]=Φόρτωση δεδομένων από ένα τοπικό αρχείο σελιδοδεικτών -Comment[en_GB]=Loads data from a local bookmarks file -Comment[es]=Carga datos de un archivo de marcadores local -Comment[et]=Andmete laadimine kohalikust järjehoidjafailist -Comment[fi]=Lataa tietoja paikallisesta kirjanmerkkitiedostosta -Comment[fr]=Charge des données depuis un fichier local de signets -Comment[ga]=Breiseán a luchtaíonn sonraí ó chomhad logánta leabharmharcanna -Comment[gl]=Carga datos desde un ficheiro local de marcadores -Comment[hu]=Adatbetöltő helyi könyvjelzőfájlokhoz -Comment[ia]=Lege datos de un file con favoritos local -Comment[it]=Carica dati da un file locale di segnalibri -Comment[ja]=ローカルのブックマークファイルからデータを読み込みます -Comment[kk]=Жергілікті бетбелгілер файлынан деректі алып береді -Comment[km]=ផ្ទុក​ទិន្នន័យ​ពី​ឯកសារ​ចំណាំ​មូលដ្ឋាន -Comment[ko]=로컬 책갈피 파일에서 데이터를 불러옵니다 -Comment[lt]=Įkelia duomenis iš vietinio adresyno failo -Comment[lv]=Ielādē datus no lokālā grāmatzīmju faila -Comment[nb]=Laster data fra en lokal bokmerkefil -Comment[nds]=Laadt Daten ut en lokaal Leestekendatei -Comment[nl]=Laadt gegevens van een lokaal bladwijzerbestand -Comment[nn]=Lastar data frå ei lokal bokmerkefil -Comment[pa]=ਇੱਕ ਲੋਕਲ ਬੁੱਕਮਾਰਕ ਫਾਇਲ ਤੋਂ ਡਾਟਾ ਲੋਡ ਕਰੋ -Comment[pl]=Wczytuje dane z pliku lokalnych zakładek -Comment[pt]=Carrega os dados a partir de um ficheiro de favoritos local -Comment[pt_BR]=Carrega os dados de um arquivo de favoritos local -Comment[ro]=Încarcă date dintr-un fișier local de tip semn de carte -Comment[ru]=Загрузка данных из локального файла с закладками -Comment[sk]=Načíta dáta z miestneho súboru záložiek -Comment[sl]=Naloži podatke iz krajevne datoteke z zaznamki -Comment[sr]=Учитава податке из локалног фајла обележивача -Comment[sr@ijekavian]=Учитава податке из локалног фајла обиљеживача -Comment[sr@ijekavianlatin]=Učitava podatke iz lokalnog fajla obilježivača -Comment[sr@latin]=Učitava podatke iz lokalnog fajla obeleživača -Comment[sv]=Laddar data från en lokal bokmärkesfil -Comment[tr]=Yerel bir yer imleri dosyasından veri yükler -Comment[uk]=Завантажує дані з локального файла закладок -Comment[x-test]=xxLoads data from a local bookmarks filexx -Comment[zh_CN]=从本地书签文件载入数据 -Comment[zh_TW]=從本地書籤檔載入資料 -Type=AkonadiResource -Exec=akonadi_localbookmarks_resource -Icon=bookmarks - -X-Akonadi-MimeTypes=text/bookmark -X-Akonadi-Capabilities=Resource -X-Akonadi-Identifier=akonadi_localbookmarks_resource diff -Nru kdepim-runtime-4.14.6/resources/localbookmarks/localbookmarksresource.h kdepim-runtime-15.08.0/resources/localbookmarks/localbookmarksresource.h --- kdepim-runtime-4.14.6/resources/localbookmarks/localbookmarksresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/localbookmarks/localbookmarksresource.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -/* - Copyright (c) 2006 Till Adam - - 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 LOCALBOOKMARKS_H -#define LOCALBOOKMARKS_H - -#include -#include - -class KBookmarkManager; - -class LocalBookmarksResource : public Akonadi::ResourceBase, public Akonadi::AgentBase::Observer -{ - Q_OBJECT - - public: - explicit LocalBookmarksResource( const QString &id ); - ~LocalBookmarksResource(); - - public Q_SLOTS: - virtual void configure( WId windowId ); - - protected Q_SLOTS: - void retrieveCollections(); - void retrieveItems( const Akonadi::Collection &col ); - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - - protected: - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); - virtual void itemRemoved( const Akonadi::Item &item ); - - private: - KBookmarkManager *mBookmarkManager; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/localbookmarks/localbookmarksresource.kcfg kdepim-runtime-15.08.0/resources/localbookmarks/localbookmarksresource.kcfg --- kdepim-runtime-4.14.6/resources/localbookmarks/localbookmarksresource.kcfg 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/localbookmarks/localbookmarksresource.kcfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ - - - - - - - - - - - false - - - diff -Nru kdepim-runtime-4.14.6/resources/localbookmarks/Messages.sh kdepim-runtime-15.08.0/resources/localbookmarks/Messages.sh --- kdepim-runtime-4.14.6/resources/localbookmarks/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/localbookmarks/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -#! /usr/bin/env bash -$EXTRACTRC `find . -name \*.ui` `find . -name \*.kcfg` >> rc.cpp || exit 11 -$XGETTEXT *.cpp -o $podir/akonadi_localbookmarks_resource.pot -rm -f rc.cpp diff -Nru kdepim-runtime-4.14.6/resources/localbookmarks/settings.kcfgc kdepim-runtime-15.08.0/resources/localbookmarks/settings.kcfgc --- kdepim-runtime-4.14.6/resources/localbookmarks/settings.kcfgc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/localbookmarks/settings.kcfgc 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -File=localbookmarksresource.kcfg -ClassName=Settings -Mutators=true -ItemAccessors=true -SetUserTexts=true -Singleton=true -#IncludeFiles= -GlobalEnums=true diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/CMakeLists.txt kdepim-runtime-15.08.0/resources/maildir/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/maildir/autotests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,46 @@ +include(ECMMarkAsTest) + +find_package(Qt5Test CONFIG REQUIRED) + +set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) + +# Stolen from kdepimlibs/akonadi/tests +macro(add_akonadi_isolated_test _source) + get_filename_component(_targetName ${_source} NAME_WE) + set(_srcList ${_source} ) + + add_executable(${_targetName} ${_srcList}) + ecm_mark_as_test(${_targetName}) + target_link_libraries(${_targetName} + Qt5::Test + KF5::AkonadiCore + KF5::AkonadiMime + KF5::MailTransport + KF5::Mime + Qt5::DBus + Qt5::Widgets + ) + + # based on kde4_add_unit_test + if (WIN32) + get_target_property( _loc ${_targetName} LOCATION ) + set(_executable ${_loc}.bat) + else () + set(_executable ${EXECUTABLE_OUTPUT_PATH}/${_targetName}) + endif () + if (UNIX) + set(_executable ${_executable}.shell) + endif () + + find_program(_testrunner akonaditest) + + if (KDEPIM_RUN_ISOLATED_TESTS) + add_test( maildir-${_targetName} ${_testrunner} -c ${CMAKE_CURRENT_SOURCE_DIR}/unittestenv/config.xml ${_executable} ) + endif () +endmacro(add_akonadi_isolated_test) + + + +add_akonadi_isolated_test( synctest.cpp ) +akonadi_add_resourcetest( maildir maildir.js ) + diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/root/cur/1237726845.6570.BejQg!2,S kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/root/cur/1237726845.6570.BejQg!2,S --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/root/cur/1237726845.6570.BejQg!2,S 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/root/cur/1237726845.6570.BejQg!2,S 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,171 @@ +Return-Path: +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; + Sun, 22 Mar 2009 13:45:00 +0100 +X-Sieve: CMU Sieve 2.2 +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id 8C4FFE6C79B + for ; Sun, 22 Mar 2009 13:45:00 +0100 (CET) +Received: from smykowski.kdab.net ([127.0.0.1]) + by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id 09703-05 for ; + Sun, 22 Mar 2009 13:45:00 +0100 (CET) +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id 163D2E6C7AF + for ; Sun, 22 Mar 2009 13:45:00 +0100 (CET) +Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) + by smykowski.kdab.net (Postfix) with ESMTP id 31945E6C79E + for ; Sun, 22 Mar 2009 13:44:59 +0100 (CET) +Received: from ktown.kde.org ([131.246.120.250]) + by kdeget.osuosl.org with smtp (Exim 4.63) + (envelope-from ) + id 1LlN8R-0005Jr-VE + for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 13:50:40 +0100 +Received: (qmail 7667 invoked by uid 72); 22 Mar 2009 12:50:33 -0000 +Received: (qmail 7658 invoked from network); 22 Mar 2009 12:50:31 -0000 +Received: from unknown (HELO office.kde.org) (195.135.221.67) + by ktown.kde.org with SMTP; 22 Mar 2009 12:50:29 -0000 +Received: from svn.kde.org (localhost [127.0.0.1]) + by office.kde.org (Postfix) with SMTP id 93E9F18E + for ; Sun, 22 Mar 2009 13:50:30 +0100 (CET) +Received: (nullmailer pid 25707 invoked by uid 30); + Sun, 22 Mar 2009 12:50:30 -0000 +From: Volker Krause +To: kde-commits@kde.org +Subject: playground/pim/akonaditest/resourcetester +X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester +MIME-Version: 1.0 +Content-Type: text/plain; + charset=UTF-8 +Content-Transfer-Encoding: 8bit +Date: Sun, 22 Mar 2009 12:50:30 +0000 +Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> +X-BeenThere: kde-commits@kde.org +X-Mailman-Version: 2.1.9 +Precedence: list +Reply-To: kde-commits@kde.org +List-Id: Notification of KDE commits +List-Unsubscribe: , + +List-Post: +List-Help: +List-Subscribe: , + +X-Virus-Scanned: by amavisd-new at kdab.net +X-Kolab-Scheduling-Message: FALSE +X-UID: 26669 +X-Length: 5694 +Status: RO +X-Status: RC +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +SVN commit 942677 by vkrause: + +Add a safety timeout in case we do not receive the synchronized() signal +or the resource hangs during syncing. The first seems to happen randomly +if syncing is extremely fast. + + + M +40 -0 resourcesynchronizationjob.cpp + M +1 -1 resourcesynchronizationjob.h + + +--- trunk/playground/pim/akonaditest/resourcetester/resourcesynchronizationjob.cpp #942676:942677 +@@ -18,12 +18,14 @@ + #include "resourcesynchronizationjob.h" + + #include ++#include + + #include + #include + + #include + #include ++#include + + namespace Akonadi + { +@@ -31,15 +33,31 @@ + class ResourceSynchronizationJobPrivate + { + public: ++ ResourceSynchronizationJobPrivate() : ++ interface( 0 ), ++ safetyTimer( 0 ), ++ timeoutCount( 0 ) ++ {} ++ + AgentInstance instance; + QDBusInterface* interface; ++ QTimer* safetyTimer; ++ int timeoutCount; ++ static int timeoutCountLimit; + }; + ++int ResourceSynchronizationJobPrivate::timeoutCountLimit = 60; ++ + ResourceSynchronizationJob::ResourceSynchronizationJob(const AgentInstance& instance, QObject* parent) : + KJob( parent ), + d( new ResourceSynchronizationJobPrivate ) + { + d->instance = instance; ++ d->safetyTimer = new QTimer( this ); ++ connect( d->safetyTimer, SIGNAL(timeout()), SLOT(slotTimeout()) ); ++ d->safetyTimer->setInterval( 10 * 1000 ); ++ d->safetyTimer->setSingleShot( false ); ++ d->safetyTimer->start(); + } + + ResourceSynchronizationJob::~ResourceSynchronizationJob() +@@ -72,9 +90,31 @@ + + void ResourceSynchronizationJob::slotSynchronized() + { ++ disconnect( d->interface, SIGNAL(synchronized()), this, SLOT(slotSynchronized()) ); ++ d->safetyTimer->stop(); + emitResult(); + } + ++void ResourceSynchronizationJob::slotTimeout() ++{ ++ d->instance = AgentManager::self()->instance( d->instance.identifier() ); ++ d->timeoutCount++; ++ ++ if ( d->timeoutCount > d->timeoutCountLimit ) { ++ d->safetyTimer->stop(); ++ setError( UserDefinedError ); ++ setErrorText( i18n( "Resource synchronization timed out." ) ); ++ emitResult(); ++ return; ++ } ++ ++ if ( d->instance.status() == AgentInstance::Idle ) { ++ // try again, we might have lost the synchronized() signal ++ kDebug() << "trying again to sync resource" << d->instance.identifier(); ++ d->instance.synchronize(); ++ } + } + ++} ++ + #include "resourcesynchronizationjob.moc" +--- trunk/playground/pim/akonaditest/resourcetester/resourcesynchronizationjob.h #942676:942677 +@@ -27,7 +27,6 @@ + + /** + Synchronizes a given resource. +- @todo Add safety timeouts. + */ + class ResourceSynchronizationJob : public KJob + { +@@ -48,6 +47,7 @@ + + private slots: + void slotSynchronized(); ++ void slotTimeout(); + + private: + ResourceSynchronizationJobPrivate* const d; diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/root/new/.keep kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/root/new/.keep --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/root/new/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/root/new/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/root/tmp/.keep kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/root/tmp/.keep --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/root/tmp/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/root/tmp/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child1/cur/1237726858.6570.dtdn4!2,S kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child1/cur/1237726858.6570.dtdn4!2,S --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child1/cur/1237726858.6570.dtdn4!2,S 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child1/cur/1237726858.6570.dtdn4!2,S 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,107 @@ +Return-Path: +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; + Sun, 22 Mar 2009 12:55:23 +0100 +X-Sieve: CMU Sieve 2.2 +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id EF869E6C77A + for ; Sun, 22 Mar 2009 12:55:22 +0100 (CET) +Received: from smykowski.kdab.net ([127.0.0.1]) + by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id 06346-10 for ; + Sun, 22 Mar 2009 12:55:21 +0100 (CET) +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id 24127E6C79E + for ; Sun, 22 Mar 2009 12:55:21 +0100 (CET) +Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) + by smykowski.kdab.net (Postfix) with ESMTP id D175FE6C77A + for ; Sun, 22 Mar 2009 12:55:20 +0100 (CET) +Received: from ktown.kde.org ([131.246.120.250]) + by kdeget.osuosl.org with smtp (Exim 4.63) + (envelope-from ) + id 1LlMMP-0003EH-9D + for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 13:01:02 +0100 +Received: (qmail 14097 invoked by uid 72); 22 Mar 2009 12:00:55 -0000 +Received: (qmail 14075 invoked from network); 22 Mar 2009 12:00:53 -0000 +Received: from unknown (HELO office.kde.org) (195.135.221.67) + by ktown.kde.org with SMTP; 22 Mar 2009 12:00:51 -0000 +Received: from svn.kde.org (localhost [127.0.0.1]) + by office.kde.org (Postfix) with SMTP id 0F54D18E + for ; Sun, 22 Mar 2009 13:00:53 +0100 (CET) +Received: (nullmailer pid 17237 invoked by uid 30); + Sun, 22 Mar 2009 12:00:53 -0000 +From: Volker Krause +To: kde-commits@kde.org +Subject: playground/pim/akonaditest/resourcetester +X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester + trunk/playground/pim/akonaditest/resourcetester/tests +MIME-Version: 1.0 +Content-Type: text/plain; + charset=UTF-8 +Content-Transfer-Encoding: 8bit +Date: Sun, 22 Mar 2009 12:00:53 +0000 +Message-Id: <1237723253.005953.17235.nullmailer@svn.kde.org> +X-BeenThere: kde-commits@kde.org +X-Mailman-Version: 2.1.9 +Precedence: list +Reply-To: kde-commits@kde.org +List-Id: Notification of KDE commits +List-Unsubscribe: , + +List-Post: +List-Help: +List-Subscribe: , + +X-Virus-Scanned: by amavisd-new at kdab.net +X-Kolab-Scheduling-Message: FALSE +X-UID: 26667 +X-Length: 4226 +Status: RO +X-Status: ORC +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +SVN commit 942650 by vkrause: + +Add CMake macro to run resource tests. + + + M +20 -0 CMakeLists.txt + A tests/CMakeLists.txt + AM tests/vcardtest-readonly.js tests/vcardtest.js#942640 + AM tests/vcardtest-readonly.xml tests/vcardtest.xml#942640 + + +--- trunk/playground/pim/akonaditest/resourcetester/CMakeLists.txt #942649:942650 +@@ -17,6 +17,26 @@ + + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) + ++macro( akonadi_add_resourcetest _testname _script ) ++ if ( ${EXECUTABLE_OUTPUT_PATH} ) ++ set( _exepath ${EXECUTABLE_OUTPUT_PATH} ) ++ else ( ${EXECUTABLE_OUTPUT_PATH} ) ++ set( _exepath ${CMAKE_CURRENT_BINARY_DIR}/.. ) ++ endif ( ${EXECUTABLE_OUTPUT_PATH} ) ++ if (WIN32) ++ set(_resourcetester ${_exepath}/resourcetester.bat) ++ else (WIN32) ++ set(_resourcetester ${_exepath}/resourcetester) ++ endif (WIN32) ++ if (UNIX) ++ set(_resourcetester ${_resourcetester}.shell) ++ endif (UNIX) ++ ++ add_test( ${_testname} ${_resourcetester} -c ${CMAKE_CURRENT_SOURCE_DIR}/${_script} ) ++endmacro( akonadi_add_resourcetest ) ++ ++add_subdirectory( tests ) ++ + set( resourcetester_SRCS + global.cpp + main.cpp +** trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest-readonly.js #property svn:mergeinfo + + +** trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest-readonly.xml #property svn:mergeinfo + + diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child1/cur/1237726875.6570.R4KOW!2,S kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child1/cur/1237726875.6570.R4KOW!2,S --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child1/cur/1237726875.6570.R4KOW!2,S 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child1/cur/1237726875.6570.R4KOW!2,S 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,150 @@ +Return-Path: +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; + Sun, 22 Mar 2009 13:16:01 +0100 +X-Sieve: CMU Sieve 2.2 +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id CA2E8E6C783 + for ; Sun, 22 Mar 2009 13:16:00 +0100 (CET) +Received: from smykowski.kdab.net ([127.0.0.1]) + by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id 07855-05 for ; + Sun, 22 Mar 2009 13:15:58 +0100 (CET) +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id ABDFDE6C79B + for ; Sun, 22 Mar 2009 13:15:58 +0100 (CET) +Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) + by smykowski.kdab.net (Postfix) with ESMTP id 5CD44E6C783 + for ; Sun, 22 Mar 2009 13:15:58 +0100 (CET) +Received: from ktown.kde.org ([131.246.120.250]) + by kdeget.osuosl.org with smtp (Exim 4.63) + (envelope-from ) + id 1LlMgP-00046D-6T + for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 13:21:41 +0100 +Received: (qmail 27078 invoked by uid 72); 22 Mar 2009 12:21:36 -0000 +Received: (qmail 27060 invoked from network); 22 Mar 2009 12:21:34 -0000 +Received: from unknown (HELO office.kde.org) (195.135.221.67) + by ktown.kde.org with SMTP; 22 Mar 2009 12:21:32 -0000 +Received: from svn.kde.org (localhost [127.0.0.1]) + by office.kde.org (Postfix) with SMTP id 0A38E18E + for ; Sun, 22 Mar 2009 13:21:34 +0100 (CET) +Received: (nullmailer pid 20237 invoked by uid 30); + Sun, 22 Mar 2009 12:21:34 -0000 +From: Volker Krause +To: kde-commits@kde.org +Subject: playground/pim/akonaditest/resourcetester +X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester +MIME-Version: 1.0 +Content-Type: text/plain; + charset=UTF-8 +Content-Transfer-Encoding: 8bit +Date: Sun, 22 Mar 2009 12:21:34 +0000 +Message-Id: <1237724494.009832.20236.nullmailer@svn.kde.org> +X-BeenThere: kde-commits@kde.org +X-Mailman-Version: 2.1.9 +Precedence: list +Reply-To: kde-commits@kde.org +List-Id: Notification of KDE commits +List-Unsubscribe: , + +List-Post: +List-Help: +List-Subscribe: , + +X-Virus-Scanned: by amavisd-new at kdab.net +X-Kolab-Scheduling-Message: FALSE +X-UID: 26668 +X-Length: 4765 +Status: RO +X-Status: ORC +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +SVN commit 942656 by vkrause: + +- propagate script errors +- make sure the Akonadi server is operational + + + M +5 -0 main.cpp + M +13 -1 script.cpp + M +6 -3 script.h + + +--- trunk/playground/pim/akonaditest/resourcetester/main.cpp #942655:942656 +@@ -21,6 +21,8 @@ + #include "global.h" + #include "test.h" + ++#include ++ + #include + #include + #include +@@ -71,6 +73,9 @@ + signal( SIGQUIT, sigHandler ); + #endif + ++ if ( !Akonadi::Control::start() ) ++ qFatal( "Unable to start Akonadi!" ); ++ + Script *script = new Script(); + + script->configure(path); +--- trunk/playground/pim/akonaditest/resourcetester/script.cpp #942655:942656 +@@ -16,12 +16,13 @@ + */ + + #include "script.h" ++#include + #include + + Script::Script() + { + action = new Kross::Action(this, "ResourceTester"); +- connect( action, SIGNAL(finished(Kross::Action*)), QCoreApplication::instance(), SLOT(quit()) ); ++ connect( action, SIGNAL(finished(Kross::Action*)), SLOT(finished(Kross::Action*)) ); + } + + void Script::configure(const QString &path, QHash hash) +@@ -51,4 +52,15 @@ + action->trigger(); + } + ++void Script::finished(Kross::Action* action) ++{ ++ if ( action->hadError() ) { ++ kError() << action->errorMessage() << action->errorTrace(); ++ QCoreApplication::instance()->exit( 1 ); ++ } else { ++ QCoreApplication::instance()->quit(); ++ } ++} ++ ++ + #include "script.moc" +--- trunk/playground/pim/akonaditest/resourcetester/script.h #942655:942656 +@@ -24,9 +24,6 @@ + class Script : public QObject + { + Q_OBJECT +- private: +- Kross::Action *action; +- + public: + Script(); + void configure(const QString &path, QHash hash); +@@ -35,6 +32,12 @@ + + public slots: + void start(); ++ ++ private slots: ++ void finished( Kross::Action *action ); ++ ++ private: ++ Kross::Action *action; + }; + + #endif diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child1/new/.keep kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child1/new/.keep --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child1/new/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child1/new/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child1/tmp/.keep kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child1/tmp/.keep --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child1/tmp/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child1/tmp/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/.child1.directory/grandchild/cur/1237726881.6570.rfoxg!2,S kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/.child1.directory/grandchild/cur/1237726881.6570.rfoxg!2,S --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/.child1.directory/grandchild/cur/1237726881.6570.rfoxg!2,S 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/.child1.directory/grandchild/cur/1237726881.6570.rfoxg!2,S 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,282 @@ +Return-Path: +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; + Sun, 22 Mar 2009 12:10:48 +0100 +X-Sieve: CMU Sieve 2.2 +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id 4BDF8E6C790 + for ; Sun, 22 Mar 2009 12:10:48 +0100 (CET) +Received: from smykowski.kdab.net ([127.0.0.1]) + by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id 03694-02 for ; + Sun, 22 Mar 2009 12:10:45 +0100 (CET) +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id B289FE6C79B + for ; Sun, 22 Mar 2009 12:10:45 +0100 (CET) +Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) + by smykowski.kdab.net (Postfix) with ESMTP id 3B465E6C790 + for ; Sun, 22 Mar 2009 12:10:45 +0100 (CET) +Received: from ktown.kde.org ([131.246.120.250]) + by kdeget.osuosl.org with smtp (Exim 4.63) + (envelope-from ) + id 1LlLfE-0001OT-K7 + for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 12:16:25 +0100 +Received: (qmail 23006 invoked by uid 72); 22 Mar 2009 11:16:19 -0000 +Received: (qmail 22986 invoked from network); 22 Mar 2009 11:16:14 -0000 +Received: from unknown (HELO office.kde.org) (195.135.221.67) + by ktown.kde.org with SMTP; 22 Mar 2009 11:16:11 -0000 +Received: from svn.kde.org (localhost [127.0.0.1]) + by office.kde.org (Postfix) with SMTP id 85EE718E + for ; Sun, 22 Mar 2009 12:16:12 +0100 (CET) +Received: (nullmailer pid 13467 invoked by uid 30); + Sun, 22 Mar 2009 11:16:12 -0000 +From: Volker Krause +To: kde-commits@kde.org +Subject: playground/pim/akonaditest/resourcetester +X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester + trunk/playground/pim/akonaditest/resourcetester/tests +MIME-Version: 1.0 +Content-Type: text/plain; + charset=UTF-8 +Content-Transfer-Encoding: 8bit +Date: Sun, 22 Mar 2009 11:16:12 +0000 +Message-Id: <1237720572.493438.13466.nullmailer@svn.kde.org> +X-BeenThere: kde-commits@kde.org +X-Mailman-Version: 2.1.9 +Precedence: list +Reply-To: kde-commits@kde.org +List-Id: Notification of KDE commits +List-Unsubscribe: , + +List-Post: +List-Help: +List-Subscribe: , + +X-Virus-Scanned: by amavisd-new at kdab.net +X-Kolab-Scheduling-Message: FALSE +X-UID: 26666 +X-Length: 11240 +Status: RO +X-Status: ORC +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +SVN commit 942640 by vkrause: + +Allow to specifiy the collection property used to identify corresponding +collections. + + + M +2 -0 tests/vcardtest.js + M +1 -1 tests/vcardtest.xml + M +29 -14 xmloperations.cpp + M +46 -0 xmloperations.h + + +--- trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest.js #942639:942640 +@@ -4,6 +4,8 @@ + + XmlOperations.setXmlFile( "vcardtest.xml" ); + XmlOperations.setRootCollections( Resource.identifier() ); ++XmlOperations.setCollectionKey( "None" ); // we only expect one collection + XmlOperations.ignoreCollectionField( "Name" ); // name is the resource identifier and thus unpredictable ++XmlOperations.ignoreCollectionField( "RemoteId" ); // remote id is the absolute path + XmlOperations.assertEqual(); + +--- trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest.xml #942639:942640 +@@ -1,5 +1,5 @@ + +- ++ + wcdW + ("vcardtest.vcf" "office-address-book") + +--- trunk/playground/pim/akonaditest/resourcetester/xmloperations.cpp #942639:942640 +@@ -31,9 +31,6 @@ + #include + #include + +-#include +-#include +- + using namespace Akonadi; + + template QTextStream& operator<<( QTextStream &s, const QSet &set ) +@@ -53,7 +50,8 @@ + + XmlOperations::XmlOperations(QObject* parent) : + QObject( parent ), +- mCollectionFields( 0xFF ) ++ mCollectionFields( 0xFF ), ++ mCollectionKey( RemoteId ) + { + } + +@@ -99,6 +97,17 @@ + return mErrorMsg; + } + ++void XmlOperations::setCollectionKey(XmlOperations::CollectionField field) ++{ ++ mCollectionKey = field; ++} ++ ++void XmlOperations::setCollectionKey(const QString& fieldName) ++{ ++ const QMetaEnum me = metaObject()->enumerator( metaObject()->indexOfEnumerator( "CollectionField" ) ); ++ setCollectionKey( static_cast( me.keyToValue( fieldName.toLatin1() ) ) ); ++} ++ + void XmlOperations::ignoreCollectionField(XmlOperations::CollectionField field) + { + mCollectionFields = mCollectionFields & ~field; +@@ -137,8 +146,20 @@ + { + Collection::List cols( _cols ); + Collection::List refCols( _refCols ); +- std::sort( cols.begin(), cols.end(), boost::bind( &Collection::remoteId, _1 ) < boost::bind( &Collection::remoteId, _2 ) ); +- std::sort( refCols.begin(), refCols.end(), boost::bind( &Collection::remoteId, _1 ) < boost::bind( &Collection::remoteId, _2 ) ); ++ switch ( mCollectionKey ) { ++ case RemoteId: ++ sortCollectionList( cols, &Collection::remoteId ); ++ sortCollectionList( refCols, &Collection::remoteId ); ++ break; ++ case Name: ++ sortCollectionList( cols, &Collection::name ); ++ sortCollectionList( refCols, &Collection::name ); ++ break; ++ case None: ++ break; ++ default: ++ Q_ASSERT( false ); ++ } + + for ( int i = 0; i < cols.count(); ++i ) { + const Collection col = cols.at( i ); +@@ -148,11 +169,6 @@ + } + + const Collection refCol = refCols.at( i ); +- if ( col.remoteId() != refCol.remoteId() ) { +- mErrorMsg = QString::fromLatin1( "Collection with remote id '%1' is missing." ).arg( refCol.remoteId() ); +- return false; +- } +- + if ( !compareCollection( col, refCol ) ) + return false; + } +@@ -177,14 +193,13 @@ + + bool XmlOperations::compareCollection(const Collection& _col, const Collection& _refCol) + { +- Q_ASSERT( _col.remoteId() == _refCol.remoteId() ); +- + // normalize + Collection col( normalize( _col ) ); + Collection refCol( normalize( _refCol ) ); + + // compare the two collections +- if ( !compareValue( col, refCol, &Collection::contentMimeTypes, ContentMimeType ) || ++ if ( !compareValue( col, refCol, &Collection::remoteId, RemoteId ) || ++ !compareValue( col, refCol, &Collection::contentMimeTypes, ContentMimeType ) || + !compareValue( col, refCol, &Collection::name, Name ) ) + return false; + +--- trunk/playground/pim/akonaditest/resourcetester/xmloperations.h #942639:942640 +@@ -28,6 +28,10 @@ + #include + #include + ++#include ++#include ++ ++ + /** + Compares a Akonadi collection sub-tree with reference data supplied in an XML file. + */ +@@ -49,6 +53,7 @@ + + Q_DECLARE_FLAGS( CollectionFields, CollectionField ) + ++ void setCollectionKey( CollectionField field ); + void ignoreCollectionField( CollectionField field ); + + public slots: +@@ -59,6 +64,7 @@ + Akonadi::Item getItemByRemoteId(const QString& rid); + Akonadi::Collection getCollectionByRemoteId(const QString& rid); + ++ void setCollectionKey( const QString &fieldName ); + void ignoreCollectionField( const QString &fieldName ); + + bool compare(); +@@ -78,16 +84,25 @@ + template bool compareValue( const Akonadi::Collection &col, const Akonadi::Collection &refCol, + T (Akonadi::Collection::*property)() const, + CollectionField propertyType ); ++ template bool compareValue( const Akonadi::Collection &col, const Akonadi::Collection &refCol, ++ T (Akonadi::Entity::*property)() const, ++ CollectionField propertyType ); + template bool compareValue( const Akonadi::Item& item, const Akonadi::Item& refItem, + T (Akonadi::Item::*property)() const, + const char* propertyName ); + template bool compareValue( const T& value, const T& refValue ); + ++ template void sortCollectionList( Akonadi::Collection::List &list, ++ T ( Akonadi::Collection::*property)() const ) const; ++ template void sortCollectionList( Akonadi::Collection::List &list, ++ T ( Akonadi::Entity::*property)() const ) const; ++ + private: + Akonadi::Collection::List mRoots; + Akonadi::XmlDocument mDocument; + QString mErrorMsg; + CollectionFields mCollectionFields; ++ CollectionField mCollectionKey; + }; + + +@@ -109,6 +124,23 @@ + } + + template ++bool XmlOperations::compareValue( const Akonadi::Collection& col, const Akonadi::Collection& refCol, ++ T (Akonadi::Entity::*property)() const, ++ CollectionField propertyType ) ++{ ++ if ( mCollectionFields & propertyType ) { ++ const bool result = compareValue( ((col).*(property))(), ((refCol).*(property))() ); ++ if ( !result ) { ++ const QMetaEnum me = metaObject()->enumerator( metaObject()->indexOfEnumerator( "CollectionField" ) ); ++ mErrorMsg.prepend( QString::fromLatin1( "Collection with remote id '%1' differs in property '%2':\n" ) ++ .arg( col.remoteId() ).arg( me.valueToKey( propertyType ) ) ); ++ } ++ return result; ++ } ++ return true; ++} ++ ++template + bool XmlOperations::compareValue( const Akonadi::Item& item, const Akonadi::Item& refItem, + T (Akonadi::Item::*property)() const, + const char* propertyName ) +@@ -131,4 +163,18 @@ + return false; + } + ++template ++void XmlOperations::sortCollectionList( Akonadi::Collection::List &list, ++ T ( Akonadi::Collection::*property)() const ) const ++{ ++ std::sort( list.begin(), list.end(), boost::bind( property, _1 ) < boost::bind( property, _2 ) ); ++} ++ ++template ++void XmlOperations::sortCollectionList( Akonadi::Collection::List &list, ++ T ( Akonadi::Entity::*property)() const ) const ++{ ++ std::sort( list.begin(), list.end(), boost::bind( property, _1 ) < boost::bind( property, _2 ) ); ++} ++ + #endif diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/.child1.directory/grandchild/new/.keep kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/.child1.directory/grandchild/new/.keep --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/.child1.directory/grandchild/new/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/.child1.directory/grandchild/new/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/.child1.directory/grandchild/tmp/.keep kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/.child1.directory/grandchild/tmp/.keep --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/.child1.directory/grandchild/tmp/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/.child1.directory/grandchild/tmp/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child2/cur/.keep kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child2/cur/.keep --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child2/cur/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child2/cur/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child2/.keep kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child2/.keep --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child2/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child2/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child2/new/.keep kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child2/new/.keep --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child2/new/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child2/new/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child2/tmp/.keep kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child2/tmp/.keep --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir/.root.directory/child2/tmp/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir/.root.directory/child2/tmp/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir-empty.xml kdepim-runtime-15.08.0/resources/maildir/autotests/maildir-empty.xml --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir-empty.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir-empty.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,5 @@ + + + wcdC + + diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir.js kdepim-runtime-15.08.0/resources/maildir/autotests/maildir.js --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir.js 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir.js 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,63 @@ +Resource.setType( "akonadi_maildir_resource" ); + +// read test +Resource.setPathOption( "Path", "maildir/root" ); +Resource.create(); + +XmlOperations.setXmlFile( "maildir.xml" ); +XmlOperations.setRootCollections( Resource.identifier() ); +XmlOperations.setNormalizeRemoteIds( true ); +XmlOperations.ignoreCollectionField( "Name" ); +XmlOperations.assertEqual(); + +Resource.destroy(); + +// empty maildir +Resource.setPathOption( "Path", "newmaildir" ); +Resource.create(); + +XmlOperations.setXmlFile( "maildir-empty.xml" ); +XmlOperations.setRootCollections( Resource.identifier() ); +XmlOperations.assertEqual(); + +// folder creation +CollectionTest.setParent( Resource.identifier() ); +CollectionTest.addContentType( "message/rfc822" ); +CollectionTest.setName( "test folder" ); +CollectionTest.create(); + +// item creation +ItemTest.setParentCollection( Resource.identifier() + "/test folder" ); +ItemTest.setMimeType( "message/rfc822" ); +ItemTest.setPayloadFromFile( "testmail.mbox" ); +ItemTest.create(); + +Resource.recreate(); + +XmlOperations.setXmlFile( "maildir-step1.xml" ); +XmlOperations.setRootCollections( Resource.identifier() ); +XmlOperations.setItemKey( "None" ); +XmlOperations.ignoreItemField( "RemoteId" ); +XmlOperations.assertEqual(); + +// folder modification +CollectionTest.setCollection( Resource.identifier() + "/test folder" ); +CollectionTest.setName( "changed folder" ); +CollectionTest.update(); + +Resource.recreate(); + +XmlOperations.setXmlFile( "maildir-step2.xml" ); +XmlOperations.setRootCollections( Resource.identifier() ); +XmlOperations.assertEqual(); + +// folder deletion +CollectionTest.setCollection( Resource.identifier() + "/changed folder" ); +CollectionTest.remove(); + +Resource.recreate(); + +XmlOperations.setXmlFile( "maildir-empty.xml" ); +XmlOperations.setRootCollections( Resource.identifier() ); +XmlOperations.assertEqual(); + diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir-step1.xml kdepim-runtime-15.08.0/resources/maildir/autotests/maildir-step1.xml --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir-step1.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir-step1.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,29 @@ + + + wcdC + + + From: Volker Krause <vkrause@kde.org> +To: kde-commits@kde.org +Subject: playground/pim/akonaditest/resourcetester +MIME-Version: 1.0 +Content-Type: text/plain; + charset=UTF-8 +Content-Transfer-Encoding: 8bit +Date: Sun, 22 Mar 2009 12:50:30 +0000 +Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> + +SVN commit 942677 by vkrause: + +Add a safety timeout in case we do not receive the synchronized() signal +or the resource hangs during syncing. The first seems to happen randomly +if syncing is extremely fast. + + + M +40 -0 resourcesynchronizationjob.cpp + M +1 -1 resourcesynchronizationjob.h + + + + + diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir-step2.xml kdepim-runtime-15.08.0/resources/maildir/autotests/maildir-step2.xml --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir-step2.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir-step2.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,29 @@ + + + wcdC + + + From: Volker Krause <vkrause@kde.org> +To: kde-commits@kde.org +Subject: playground/pim/akonaditest/resourcetester +MIME-Version: 1.0 +Content-Type: text/plain; + charset=UTF-8 +Content-Transfer-Encoding: 8bit +Date: Sun, 22 Mar 2009 12:50:30 +0000 +Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> + +SVN commit 942677 by vkrause: + +Add a safety timeout in case we do not receive the synchronized() signal +or the resource hangs during syncing. The first seems to happen randomly +if syncing is extremely fast. + + + M +40 -0 resourcesynchronizationjob.cpp + M +1 -1 resourcesynchronizationjob.h + + + + + diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/maildir.xml kdepim-runtime-15.08.0/resources/maildir/autotests/maildir.xml --- kdepim-runtime-4.14.6/resources/maildir/autotests/maildir.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/maildir.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,732 @@ + + + wcdC + + + + + Return-Path: <commitfilter@new.kstuff.org> +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; + Sun, 22 Mar 2009 12:10:48 +0100 +X-Sieve: CMU Sieve 2.2 +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id 4BDF8E6C790 + for <asok@kdab.net>; Sun, 22 Mar 2009 12:10:48 +0100 (CET) +Received: from smykowski.kdab.net ([127.0.0.1]) + by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id 03694-02 for <asok@kdab.net>; + Sun, 22 Mar 2009 12:10:45 +0100 (CET) +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id B289FE6C79B + for <asok@kdab.net>; Sun, 22 Mar 2009 12:10:45 +0100 (CET) +Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) + by smykowski.kdab.net (Postfix) with ESMTP id 3B465E6C790 + for <asok@kdab.net>; Sun, 22 Mar 2009 12:10:45 +0100 (CET) +Received: from ktown.kde.org ([131.246.120.250]) + by kdeget.osuosl.org with smtp (Exim 4.63) + (envelope-from <kde-commits-bounces-+commitfilter=new.kstuff.org@kde.org>) + id 1LlLfE-0001OT-K7 + for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 12:16:25 +0100 +Received: (qmail 23006 invoked by uid 72); 22 Mar 2009 11:16:19 -0000 +Received: (qmail 22986 invoked from network); 22 Mar 2009 11:16:14 -0000 +Received: from unknown (HELO office.kde.org) (195.135.221.67) + by ktown.kde.org with SMTP; 22 Mar 2009 11:16:11 -0000 +Received: from svn.kde.org (localhost [127.0.0.1]) + by office.kde.org (Postfix) with SMTP id 85EE718E + for <kde-commits@kde.org>; Sun, 22 Mar 2009 12:16:12 +0100 (CET) +Received: (nullmailer pid 13467 invoked by uid 30); + Sun, 22 Mar 2009 11:16:12 -0000 +From: Volker Krause <vkrause@kde.org> +To: kde-commits@kde.org +Subject: playground/pim/akonaditest/resourcetester +X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester + trunk/playground/pim/akonaditest/resourcetester/tests +MIME-Version: 1.0 +Content-Type: text/plain; + charset=UTF-8 +Content-Transfer-Encoding: 8bit +Date: Sun, 22 Mar 2009 11:16:12 +0000 +Message-Id: <1237720572.493438.13466.nullmailer@svn.kde.org> +X-BeenThere: kde-commits@kde.org +X-Mailman-Version: 2.1.9 +Precedence: list +Reply-To: kde-commits@kde.org +List-Id: Notification of KDE commits <kde-commits.kde.org> +List-Unsubscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, + <mailto:kde-commits-request@kde.org?subject=unsubscribe> +List-Post: <mailto:kde-commits@kde.org> +List-Help: <mailto:kde-commits-request@kde.org?subject=help> +List-Subscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, + <mailto:kde-commits-request@kde.org?subject=subscribe> +X-Virus-Scanned: by amavisd-new at kdab.net +X-Kolab-Scheduling-Message: FALSE +X-UID: 26666 +X-Length: 11240 +Status: RO +X-Status: ORC +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +SVN commit 942640 by vkrause: + +Allow to specifiy the collection property used to identify corresponding +collections. + + + M +2 -0 tests/vcardtest.js + M +1 -1 tests/vcardtest.xml + M +29 -14 xmloperations.cpp + M +46 -0 xmloperations.h + + +--- trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest.js #942639:942640 +@@ -4,6 +4,8 @@ + + XmlOperations.setXmlFile( "vcardtest.xml" ); + XmlOperations.setRootCollections( Resource.identifier() ); ++XmlOperations.setCollectionKey( "None" ); // we only expect one collection + XmlOperations.ignoreCollectionField( "Name" ); // name is the resource identifier and thus unpredictable ++XmlOperations.ignoreCollectionField( "RemoteId" ); // remote id is the absolute path + XmlOperations.assertEqual(); + +--- trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest.xml #942639:942640 +@@ -1,5 +1,5 @@ + <knut> +- <collection rid="/k/kde4/src/playground/pim/akonaditest/resourcetester/tests/vcardtest.vcf" name="akonadi_vcard_resource_0" content="text/directory"> ++ <collection rid="vcardtest.vcf" name="akonadi_vcard_resource_0" content="text/directory"> + <attribute type="AccessRights" >wcdW</attribute> + <attribute type="ENTITYDISPLAY" >("vcardtest.vcf" "office-address-book")</attribute> + <item rid="bb2slGmqxb" mimetype="text/directory"> +--- trunk/playground/pim/akonaditest/resourcetester/xmloperations.cpp #942639:942640 +@@ -31,9 +31,6 @@ + #include <QFileInfo> + #include <QStringList> + +-#include <boost/bind.hpp> +-#include <algorithm> +- + using namespace Akonadi; + + template <typename T> QTextStream& operator<<( QTextStream &s, const QSet<T> &set ) +@@ -53,7 +50,8 @@ + + XmlOperations::XmlOperations(QObject* parent) : + QObject( parent ), +- mCollectionFields( 0xFF ) ++ mCollectionFields( 0xFF ), ++ mCollectionKey( RemoteId ) + { + } + +@@ -99,6 +97,17 @@ + return mErrorMsg; + } + ++void XmlOperations::setCollectionKey(XmlOperations::CollectionField field) ++{ ++ mCollectionKey = field; ++} ++ ++void XmlOperations::setCollectionKey(const QString& fieldName) ++{ ++ const QMetaEnum me = metaObject()->enumerator( metaObject()->indexOfEnumerator( "CollectionField" ) ); ++ setCollectionKey( static_cast<CollectionField>( me.keyToValue( fieldName.toLatin1() ) ) ); ++} ++ + void XmlOperations::ignoreCollectionField(XmlOperations::CollectionField field) + { + mCollectionFields = mCollectionFields & ~field; +@@ -137,8 +146,20 @@ + { + Collection::List cols( _cols ); + Collection::List refCols( _refCols ); +- std::sort( cols.begin(), cols.end(), boost::bind( &Collection::remoteId, _1 ) < boost::bind( &Collection::remoteId, _2 ) ); +- std::sort( refCols.begin(), refCols.end(), boost::bind( &Collection::remoteId, _1 ) < boost::bind( &Collection::remoteId, _2 ) ); ++ switch ( mCollectionKey ) { ++ case RemoteId: ++ sortCollectionList( cols, &Collection::remoteId ); ++ sortCollectionList( refCols, &Collection::remoteId ); ++ break; ++ case Name: ++ sortCollectionList( cols, &Collection::name ); ++ sortCollectionList( refCols, &Collection::name ); ++ break; ++ case None: ++ break; ++ default: ++ Q_ASSERT( false ); ++ } + + for ( int i = 0; i < cols.count(); ++i ) { + const Collection col = cols.at( i ); +@@ -148,11 +169,6 @@ + } + + const Collection refCol = refCols.at( i ); +- if ( col.remoteId() != refCol.remoteId() ) { +- mErrorMsg = QString::fromLatin1( "Collection with remote id '%1' is missing." ).arg( refCol.remoteId() ); +- return false; +- } +- + if ( !compareCollection( col, refCol ) ) + return false; + } +@@ -177,14 +193,13 @@ + + bool XmlOperations::compareCollection(const Collection& _col, const Collection& _refCol) + { +- Q_ASSERT( _col.remoteId() == _refCol.remoteId() ); +- + // normalize + Collection col( normalize( _col ) ); + Collection refCol( normalize( _refCol ) ); + + // compare the two collections +- if ( !compareValue( col, refCol, &Collection::contentMimeTypes, ContentMimeType ) || ++ if ( !compareValue( col, refCol, &Collection::remoteId, RemoteId ) || ++ !compareValue( col, refCol, &Collection::contentMimeTypes, ContentMimeType ) || + !compareValue( col, refCol, &Collection::name, Name ) ) + return false; + +--- trunk/playground/pim/akonaditest/resourcetester/xmloperations.h #942639:942640 +@@ -28,6 +28,10 @@ + #include <QtCore/QObject> + #include <QtCore/QTextStream> + ++#include <boost/bind.hpp> ++#include <algorithm> ++ ++ + /** + Compares a Akonadi collection sub-tree with reference data supplied in an XML file. + */ +@@ -49,6 +53,7 @@ + + Q_DECLARE_FLAGS( CollectionFields, CollectionField ) + ++ void setCollectionKey( CollectionField field ); + void ignoreCollectionField( CollectionField field ); + + public slots: +@@ -59,6 +64,7 @@ + Akonadi::Item getItemByRemoteId(const QString& rid); + Akonadi::Collection getCollectionByRemoteId(const QString& rid); + ++ void setCollectionKey( const QString &fieldName ); + void ignoreCollectionField( const QString &fieldName ); + + bool compare(); +@@ -78,16 +84,25 @@ + template <typename T> bool compareValue( const Akonadi::Collection &col, const Akonadi::Collection &refCol, + T (Akonadi::Collection::*property)() const, + CollectionField propertyType ); ++ template <typename T> bool compareValue( const Akonadi::Collection &col, const Akonadi::Collection &refCol, ++ T (Akonadi::Entity::*property)() const, ++ CollectionField propertyType ); + template <typename T> bool compareValue( const Akonadi::Item& item, const Akonadi::Item& refItem, + T (Akonadi::Item::*property)() const, + const char* propertyName ); + template <typename T> bool compareValue( const T& value, const T& refValue ); + ++ template <typename T> void sortCollectionList( Akonadi::Collection::List &list, ++ T ( Akonadi::Collection::*property)() const ) const; ++ template <typename T> void sortCollectionList( Akonadi::Collection::List &list, ++ T ( Akonadi::Entity::*property)() const ) const; ++ + private: + Akonadi::Collection::List mRoots; + Akonadi::XmlDocument mDocument; + QString mErrorMsg; + CollectionFields mCollectionFields; ++ CollectionField mCollectionKey; + }; + + +@@ -109,6 +124,23 @@ + } + + template <typename T> ++bool XmlOperations::compareValue( const Akonadi::Collection& col, const Akonadi::Collection& refCol, ++ T (Akonadi::Entity::*property)() const, ++ CollectionField propertyType ) ++{ ++ if ( mCollectionFields & propertyType ) { ++ const bool result = compareValue<T>( ((col).*(property))(), ((refCol).*(property))() ); ++ if ( !result ) { ++ const QMetaEnum me = metaObject()->enumerator( metaObject()->indexOfEnumerator( "CollectionField" ) ); ++ mErrorMsg.prepend( QString::fromLatin1( "Collection with remote id '%1' differs in property '%2':\n" ) ++ .arg( col.remoteId() ).arg( me.valueToKey( propertyType ) ) ); ++ } ++ return result; ++ } ++ return true; ++} ++ ++template <typename T> + bool XmlOperations::compareValue( const Akonadi::Item& item, const Akonadi::Item& refItem, + T (Akonadi::Item::*property)() const, + const char* propertyName ) +@@ -131,4 +163,18 @@ + return false; + } + ++template <typename T> ++void XmlOperations::sortCollectionList( Akonadi::Collection::List &list, ++ T ( Akonadi::Collection::*property)() const ) const ++{ ++ std::sort( list.begin(), list.end(), boost::bind( property, _1 ) < boost::bind( property, _2 ) ); ++} ++ ++template <typename T> ++void XmlOperations::sortCollectionList( Akonadi::Collection::List &list, ++ T ( Akonadi::Entity::*property)() const ) const ++{ ++ std::sort( list.begin(), list.end(), boost::bind( property, _1 ) < boost::bind( property, _2 ) ); ++} ++ + #endif + + + + + Return-Path: <commitfilter@new.kstuff.org> +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; + Sun, 22 Mar 2009 12:55:23 +0100 +X-Sieve: CMU Sieve 2.2 +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id EF869E6C77A + for <asok@kdab.net>; Sun, 22 Mar 2009 12:55:22 +0100 (CET) +Received: from smykowski.kdab.net ([127.0.0.1]) + by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id 06346-10 for <asok@kdab.net>; + Sun, 22 Mar 2009 12:55:21 +0100 (CET) +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id 24127E6C79E + for <asok@kdab.net>; Sun, 22 Mar 2009 12:55:21 +0100 (CET) +Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) + by smykowski.kdab.net (Postfix) with ESMTP id D175FE6C77A + for <asok@kdab.net>; Sun, 22 Mar 2009 12:55:20 +0100 (CET) +Received: from ktown.kde.org ([131.246.120.250]) + by kdeget.osuosl.org with smtp (Exim 4.63) + (envelope-from <kde-commits-bounces-+commitfilter=new.kstuff.org@kde.org>) + id 1LlMMP-0003EH-9D + for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 13:01:02 +0100 +Received: (qmail 14097 invoked by uid 72); 22 Mar 2009 12:00:55 -0000 +Received: (qmail 14075 invoked from network); 22 Mar 2009 12:00:53 -0000 +Received: from unknown (HELO office.kde.org) (195.135.221.67) + by ktown.kde.org with SMTP; 22 Mar 2009 12:00:51 -0000 +Received: from svn.kde.org (localhost [127.0.0.1]) + by office.kde.org (Postfix) with SMTP id 0F54D18E + for <kde-commits@kde.org>; Sun, 22 Mar 2009 13:00:53 +0100 (CET) +Received: (nullmailer pid 17237 invoked by uid 30); + Sun, 22 Mar 2009 12:00:53 -0000 +From: Volker Krause <vkrause@kde.org> +To: kde-commits@kde.org +Subject: playground/pim/akonaditest/resourcetester +X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester + trunk/playground/pim/akonaditest/resourcetester/tests +MIME-Version: 1.0 +Content-Type: text/plain; + charset=UTF-8 +Content-Transfer-Encoding: 8bit +Date: Sun, 22 Mar 2009 12:00:53 +0000 +Message-Id: <1237723253.005953.17235.nullmailer@svn.kde.org> +X-BeenThere: kde-commits@kde.org +X-Mailman-Version: 2.1.9 +Precedence: list +Reply-To: kde-commits@kde.org +List-Id: Notification of KDE commits <kde-commits.kde.org> +List-Unsubscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, + <mailto:kde-commits-request@kde.org?subject=unsubscribe> +List-Post: <mailto:kde-commits@kde.org> +List-Help: <mailto:kde-commits-request@kde.org?subject=help> +List-Subscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, + <mailto:kde-commits-request@kde.org?subject=subscribe> +X-Virus-Scanned: by amavisd-new at kdab.net +X-Kolab-Scheduling-Message: FALSE +X-UID: 26667 +X-Length: 4226 +Status: RO +X-Status: ORC +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +SVN commit 942650 by vkrause: + +Add CMake macro to run resource tests. + + + M +20 -0 CMakeLists.txt + A tests/CMakeLists.txt + AM tests/vcardtest-readonly.js tests/vcardtest.js#942640 + AM tests/vcardtest-readonly.xml tests/vcardtest.xml#942640 + + +--- trunk/playground/pim/akonaditest/resourcetester/CMakeLists.txt #942649:942650 +@@ -17,6 +17,26 @@ + + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) + ++macro( akonadi_add_resourcetest _testname _script ) ++ if ( ${EXECUTABLE_OUTPUT_PATH} ) ++ set( _exepath ${EXECUTABLE_OUTPUT_PATH} ) ++ else ( ${EXECUTABLE_OUTPUT_PATH} ) ++ set( _exepath ${CMAKE_CURRENT_BINARY_DIR}/.. ) ++ endif ( ${EXECUTABLE_OUTPUT_PATH} ) ++ if (WIN32) ++ set(_resourcetester ${_exepath}/resourcetester.bat) ++ else (WIN32) ++ set(_resourcetester ${_exepath}/resourcetester) ++ endif (WIN32) ++ if (UNIX) ++ set(_resourcetester ${_resourcetester}.shell) ++ endif (UNIX) ++ ++ add_test( ${_testname} ${_resourcetester} -c ${CMAKE_CURRENT_SOURCE_DIR}/${_script} ) ++endmacro( akonadi_add_resourcetest ) ++ ++add_subdirectory( tests ) ++ + set( resourcetester_SRCS + global.cpp + main.cpp +** trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest-readonly.js #property svn:mergeinfo + + +** trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest-readonly.xml #property svn:mergeinfo + + + + + + Return-Path: <commitfilter@new.kstuff.org> +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; + Sun, 22 Mar 2009 13:16:01 +0100 +X-Sieve: CMU Sieve 2.2 +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id CA2E8E6C783 + for <asok@kdab.net>; Sun, 22 Mar 2009 13:16:00 +0100 (CET) +Received: from smykowski.kdab.net ([127.0.0.1]) + by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id 07855-05 for <asok@kdab.net>; + Sun, 22 Mar 2009 13:15:58 +0100 (CET) +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id ABDFDE6C79B + for <asok@kdab.net>; Sun, 22 Mar 2009 13:15:58 +0100 (CET) +Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) + by smykowski.kdab.net (Postfix) with ESMTP id 5CD44E6C783 + for <asok@kdab.net>; Sun, 22 Mar 2009 13:15:58 +0100 (CET) +Received: from ktown.kde.org ([131.246.120.250]) + by kdeget.osuosl.org with smtp (Exim 4.63) + (envelope-from <kde-commits-bounces-+commitfilter=new.kstuff.org@kde.org>) + id 1LlMgP-00046D-6T + for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 13:21:41 +0100 +Received: (qmail 27078 invoked by uid 72); 22 Mar 2009 12:21:36 -0000 +Received: (qmail 27060 invoked from network); 22 Mar 2009 12:21:34 -0000 +Received: from unknown (HELO office.kde.org) (195.135.221.67) + by ktown.kde.org with SMTP; 22 Mar 2009 12:21:32 -0000 +Received: from svn.kde.org (localhost [127.0.0.1]) + by office.kde.org (Postfix) with SMTP id 0A38E18E + for <kde-commits@kde.org>; Sun, 22 Mar 2009 13:21:34 +0100 (CET) +Received: (nullmailer pid 20237 invoked by uid 30); + Sun, 22 Mar 2009 12:21:34 -0000 +From: Volker Krause <vkrause@kde.org> +To: kde-commits@kde.org +Subject: playground/pim/akonaditest/resourcetester +X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester +MIME-Version: 1.0 +Content-Type: text/plain; + charset=UTF-8 +Content-Transfer-Encoding: 8bit +Date: Sun, 22 Mar 2009 12:21:34 +0000 +Message-Id: <1237724494.009832.20236.nullmailer@svn.kde.org> +X-BeenThere: kde-commits@kde.org +X-Mailman-Version: 2.1.9 +Precedence: list +Reply-To: kde-commits@kde.org +List-Id: Notification of KDE commits <kde-commits.kde.org> +List-Unsubscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, + <mailto:kde-commits-request@kde.org?subject=unsubscribe> +List-Post: <mailto:kde-commits@kde.org> +List-Help: <mailto:kde-commits-request@kde.org?subject=help> +List-Subscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, + <mailto:kde-commits-request@kde.org?subject=subscribe> +X-Virus-Scanned: by amavisd-new at kdab.net +X-Kolab-Scheduling-Message: FALSE +X-UID: 26668 +X-Length: 4765 +Status: RO +X-Status: ORC +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +SVN commit 942656 by vkrause: + +- propagate script errors +- make sure the Akonadi server is operational + + + M +5 -0 main.cpp + M +13 -1 script.cpp + M +6 -3 script.h + + +--- trunk/playground/pim/akonaditest/resourcetester/main.cpp #942655:942656 +@@ -21,6 +21,8 @@ + #include "global.h" + #include "test.h" + ++#include <akonadi/control.h> ++ + #include <KApplication> + #include <KAboutData> + #include <KCmdLineArgs> +@@ -71,6 +73,9 @@ + signal( SIGQUIT, sigHandler ); + #endif + ++ if ( !Akonadi::Control::start() ) ++ qFatal( "Unable to start Akonadi!" ); ++ + Script *script = new Script(); + + script->configure(path); +--- trunk/playground/pim/akonaditest/resourcetester/script.cpp #942655:942656 +@@ -16,12 +16,13 @@ + */ + + #include "script.h" ++#include <KDebug> + #include <qcoreapplication.h> + + Script::Script() + { + action = new Kross::Action(this, "ResourceTester"); +- connect( action, SIGNAL(finished(Kross::Action*)), QCoreApplication::instance(), SLOT(quit()) ); ++ connect( action, SIGNAL(finished(Kross::Action*)), SLOT(finished(Kross::Action*)) ); + } + + void Script::configure(const QString &path, QHash<QString, QObject * > hash) +@@ -51,4 +52,15 @@ + action->trigger(); + } + ++void Script::finished(Kross::Action* action) ++{ ++ if ( action->hadError() ) { ++ kError() << action->errorMessage() << action->errorTrace(); ++ QCoreApplication::instance()->exit( 1 ); ++ } else { ++ QCoreApplication::instance()->quit(); ++ } ++} ++ ++ + #include "script.moc" +--- trunk/playground/pim/akonaditest/resourcetester/script.h #942655:942656 +@@ -24,9 +24,6 @@ + class Script : public QObject + { + Q_OBJECT +- private: +- Kross::Action *action; +- + public: + Script(); + void configure(const QString &path, QHash<QString, QObject *> hash); +@@ -35,6 +32,12 @@ + + public slots: + void start(); ++ ++ private slots: ++ void finished( Kross::Action *action ); ++ ++ private: ++ Kross::Action *action; + }; + + #endif + + + + + Return-Path: <commitfilter@new.kstuff.org> +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; + Sun, 22 Mar 2009 13:45:00 +0100 +X-Sieve: CMU Sieve 2.2 +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id 8C4FFE6C79B + for <asok@kdab.net>; Sun, 22 Mar 2009 13:45:00 +0100 (CET) +Received: from smykowski.kdab.net ([127.0.0.1]) + by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id 09703-05 for <asok@kdab.net>; + Sun, 22 Mar 2009 13:45:00 +0100 (CET) +Received: from localhost (localhost [127.0.0.1]) + by smykowski.kdab.net (Postfix) with ESMTP id 163D2E6C7AF + for <asok@kdab.net>; Sun, 22 Mar 2009 13:45:00 +0100 (CET) +Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) + by smykowski.kdab.net (Postfix) with ESMTP id 31945E6C79E + for <asok@kdab.net>; Sun, 22 Mar 2009 13:44:59 +0100 (CET) +Received: from ktown.kde.org ([131.246.120.250]) + by kdeget.osuosl.org with smtp (Exim 4.63) + (envelope-from <kde-commits-bounces-+commitfilter=new.kstuff.org@kde.org>) + id 1LlN8R-0005Jr-VE + for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 13:50:40 +0100 +Received: (qmail 7667 invoked by uid 72); 22 Mar 2009 12:50:33 -0000 +Received: (qmail 7658 invoked from network); 22 Mar 2009 12:50:31 -0000 +Received: from unknown (HELO office.kde.org) (195.135.221.67) + by ktown.kde.org with SMTP; 22 Mar 2009 12:50:29 -0000 +Received: from svn.kde.org (localhost [127.0.0.1]) + by office.kde.org (Postfix) with SMTP id 93E9F18E + for <kde-commits@kde.org>; Sun, 22 Mar 2009 13:50:30 +0100 (CET) +Received: (nullmailer pid 25707 invoked by uid 30); + Sun, 22 Mar 2009 12:50:30 -0000 +From: Volker Krause <vkrause@kde.org> +To: kde-commits@kde.org +Subject: playground/pim/akonaditest/resourcetester +X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester +MIME-Version: 1.0 +Content-Type: text/plain; + charset=UTF-8 +Content-Transfer-Encoding: 8bit +Date: Sun, 22 Mar 2009 12:50:30 +0000 +Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> +X-BeenThere: kde-commits@kde.org +X-Mailman-Version: 2.1.9 +Precedence: list +Reply-To: kde-commits@kde.org +List-Id: Notification of KDE commits <kde-commits.kde.org> +List-Unsubscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, + <mailto:kde-commits-request@kde.org?subject=unsubscribe> +List-Post: <mailto:kde-commits@kde.org> +List-Help: <mailto:kde-commits-request@kde.org?subject=help> +List-Subscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, + <mailto:kde-commits-request@kde.org?subject=subscribe> +X-Virus-Scanned: by amavisd-new at kdab.net +X-Kolab-Scheduling-Message: FALSE +X-UID: 26669 +X-Length: 5694 +Status: RO +X-Status: RC +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +SVN commit 942677 by vkrause: + +Add a safety timeout in case we do not receive the synchronized() signal +or the resource hangs during syncing. The first seems to happen randomly +if syncing is extremely fast. + + + M +40 -0 resourcesynchronizationjob.cpp + M +1 -1 resourcesynchronizationjob.h + + +--- trunk/playground/pim/akonaditest/resourcetester/resourcesynchronizationjob.cpp #942676:942677 +@@ -18,12 +18,14 @@ + #include "resourcesynchronizationjob.h" + + #include <akonadi/agentinstance.h> ++#include <akonadi/agentmanager.h> + + #include <KDebug> + #include <KLocale> + + #include <QDBusConnection> + #include <QDBusInterface> ++#include <QTimer> + + namespace Akonadi + { +@@ -31,15 +33,31 @@ + class ResourceSynchronizationJobPrivate + { + public: ++ ResourceSynchronizationJobPrivate() : ++ interface( 0 ), ++ safetyTimer( 0 ), ++ timeoutCount( 0 ) ++ {} ++ + AgentInstance instance; + QDBusInterface* interface; ++ QTimer* safetyTimer; ++ int timeoutCount; ++ static int timeoutCountLimit; + }; + ++int ResourceSynchronizationJobPrivate::timeoutCountLimit = 60; ++ + ResourceSynchronizationJob::ResourceSynchronizationJob(const AgentInstance& instance, QObject* parent) : + KJob( parent ), + d( new ResourceSynchronizationJobPrivate ) + { + d->instance = instance; ++ d->safetyTimer = new QTimer( this ); ++ connect( d->safetyTimer, SIGNAL(timeout()), SLOT(slotTimeout()) ); ++ d->safetyTimer->setInterval( 10 * 1000 ); ++ d->safetyTimer->setSingleShot( false ); ++ d->safetyTimer->start(); + } + + ResourceSynchronizationJob::~ResourceSynchronizationJob() +@@ -72,9 +90,31 @@ + + void ResourceSynchronizationJob::slotSynchronized() + { ++ disconnect( d->interface, SIGNAL(synchronized()), this, SLOT(slotSynchronized()) ); ++ d->safetyTimer->stop(); + emitResult(); + } + ++void ResourceSynchronizationJob::slotTimeout() ++{ ++ d->instance = AgentManager::self()->instance( d->instance.identifier() ); ++ d->timeoutCount++; ++ ++ if ( d->timeoutCount > d->timeoutCountLimit ) { ++ d->safetyTimer->stop(); ++ setError( UserDefinedError ); ++ setErrorText( i18n( "Resource synchronization timed out." ) ); ++ emitResult(); ++ return; ++ } ++ ++ if ( d->instance.status() == AgentInstance::Idle ) { ++ // try again, we might have lost the synchronized() signal ++ kDebug() << "trying again to sync resource" << d->instance.identifier(); ++ d->instance.synchronize(); ++ } + } + ++} ++ + #include "resourcesynchronizationjob.moc" +--- trunk/playground/pim/akonaditest/resourcetester/resourcesynchronizationjob.h #942676:942677 +@@ -27,7 +27,6 @@ + + /** + Synchronizes a given resource. +- @todo Add safety timeouts. + */ + class ResourceSynchronizationJob : public KJob + { +@@ -48,6 +47,7 @@ + + private slots: + void slotSynchronized(); ++ void slotTimeout(); + + private: + ResourceSynchronizationJobPrivate* const d; + + + + diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/synctest.cpp kdepim-runtime-15.08.0/resources/maildir/autotests/synctest.cpp --- kdepim-runtime-4.14.6/resources/maildir/autotests/synctest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/synctest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,64 @@ +/* + Copyright 2009 Constantin Berzan + + 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 "synctest.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#define TIMES 100 // How many times to sync. +#define TIMEOUT 10 // How many seconds to wait before declaring the resource dead. + +using namespace Akonadi; + +void SyncTest::initTestCase() +{ + QVERIFY(Control::start()); + QTest::qWait(1000); +} + +void SyncTest::testSync() +{ + AgentInstance instance = AgentManager::self()->instance("akonadi_maildir_resource_0"); + QVERIFY(instance.isValid()); + + for (int i = 0; i < 100; i++) { + QDBusInterface *interface = new QDBusInterface( + QString::fromLatin1("org.freedesktop.Akonadi.Resource.%1").arg(instance.identifier()), + "/", "org.freedesktop.Akonadi.Resource", QDBusConnection::sessionBus(), this); + QVERIFY(interface->isValid()); + QTime t; + t.start(); + instance.synchronize(); + QSignalSpy spy(interface, SIGNAL(synchronized())); + QVERIFY(spy.wait(TIMEOUT * 1000)); + qDebug() << "Sync attempt" << i << "in" << t.elapsed() << "ms."; + } +} + +QTEST_AKONADIMAIN(SyncTest) + diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/synctest.h kdepim-runtime-15.08.0/resources/maildir/autotests/synctest.h --- kdepim-runtime-4.14.6/resources/maildir/autotests/synctest.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/synctest.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,43 @@ +/* + Copyright 2009 Constantin Berzan + + 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 SYNCTEST_H +#define SYNCTEST_H + +#include + +#include + +/** + This syncs the resource again and again, watching out for "lost" + synchronized() signals. + */ +class SyncTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void initTestCase(); + void testSync(); + +private: + +}; + +#endif diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/testmail.mbox kdepim-runtime-15.08.0/resources/maildir/autotests/testmail.mbox --- kdepim-runtime-4.14.6/resources/maildir/autotests/testmail.mbox 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/testmail.mbox 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,19 @@ +From: Volker Krause +To: kde-commits@kde.org +Subject: playground/pim/akonaditest/resourcetester +MIME-Version: 1.0 +Content-Type: text/plain; + charset=UTF-8 +Content-Transfer-Encoding: 8bit +Date: Sun, 22 Mar 2009 12:50:30 +0000 +Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> + +SVN commit 942677 by vkrause: + +Add a safety timeout in case we do not receive the synchronized() signal +or the resource hangs during syncing. The first seems to happen randomly +if syncing is extremely fast. + + + M +40 -0 resourcesynchronizationjob.cpp + M +1 -1 resourcesynchronizationjob.h diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/config.xml kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/config.xml --- kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/config.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/config.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,6 @@ + + kdehome + xdgconfig + xdglocal + akonadi_maildir_resource + diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/kdehome/share/config/akonadi-firstrunrc kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/kdehome/share/config/akonadi-firstrunrc --- kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/kdehome/share/config/akonadi-firstrunrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/kdehome/share/config/akonadi-firstrunrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,3 @@ +[ProcessedDefaults] +defaultaddressbook=done +defaultcalendar=done diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/kdehome/share/config/akonadi_maildir_resource_0rc kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/kdehome/share/config/akonadi_maildir_resource_0rc --- kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/kdehome/share/config/akonadi_maildir_resource_0rc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/kdehome/share/config/akonadi_maildir_resource_0rc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,2 @@ +[General] +Path[$e]=$HOME/.local/share/mail diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/kdehome/share/config/kdebugrc kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/kdehome/share/config/kdebugrc --- kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/kdehome/share/config/kdebugrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/kdehome/share/config/kdebugrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,110 @@ +[0] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[5250] +InfoOutput=2 + +[5251] +InfoOutput=2 + +[5252] +InfoOutput=2 + +[5253] +InfoOutput=2 + +[5254] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[5255] +InfoOutput=2 + +[5256] +InfoOutput=2 + +[5257] +InfoOutput=2 + +[5258] +InfoOutput=2 + +[5259] +InfoOutput=2 + +[5260] +InfoOutput=2 + +[5261] +InfoOutput=2 + +[5262] +InfoOutput=2 + +[5263] +InfoOutput=2 + +[5264] +InfoOutput=2 + +[5265] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[5266] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[5295] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[5324] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[7129] +InfoOutput=2 diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/kdehome/share/config/kdedrc kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/kdehome/share/config/kdedrc --- kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/kdehome/share/config/kdedrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/kdehome/share/config/kdedrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,3 @@ +[General] +CheckSycoca=false +CheckFileStamps=false diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/kdehome/share/config/kwalletrc kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/kdehome/share/config/kwalletrc --- kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/kdehome/share/config/kwalletrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/kdehome/share/config/kwalletrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,2 @@ +[Wallet] +Enabled=false diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/kdehome/share/config/qttestrc kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/kdehome/share/config/qttestrc --- kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/kdehome/share/config/qttestrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/kdehome/share/config/qttestrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,2 @@ +[Notification Messages] +WalletMigrate=false diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/kdehome/testdata.xml kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/kdehome/testdata.xml --- kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/kdehome/testdata.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/kdehome/testdata.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,4 @@ + + + + diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/xdgconfig/akonadi/akonadiserverrc kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/xdgconfig/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/xdgconfig/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/xdgconfig/akonadi/akonadiserverrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,4 @@ +[%General] + +[Search] +Manager=Dummy diff -Nru kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/xdglocal/.keep kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/xdglocal/.keep --- kdepim-runtime-4.14.6/resources/maildir/autotests/unittestenv/xdglocal/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/autotests/unittestenv/xdglocal/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/CMakeLists.txt kdepim-runtime-15.08.0/resources/maildir/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/maildir/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,44 +1,47 @@ +project(maildir) include_directories( - ${kdepim-runtime_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libmaildir - ${QT_QTDBUS_INCLUDE_DIR} - ${Boost_INCLUDE_DIR} + ${kdepim-runtime_SOURCE_DIR} ) -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) -add_subdirectory( tests ) +if (BUILD_TESTING) + add_subdirectory( autotests ) +endif() add_subdirectory( wizard ) # maildir access library add_subdirectory(libmaildir) -########### next target ############### +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_maildir_resource\") +########### next target ############### set( maildirresource_SRCS + maildirresource_debug.cpp + main.cpp maildirresource.cpp configdialog.cpp - main.cpp retrieveitemsjob.cpp ) -install( FILES maildirresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) - -kde4_add_ui_files(maildirresource_SRCS settings.ui) +ki18n_wrap_ui(maildirresource_SRCS settings.ui) -kde4_add_kcfg_files(maildirresource_SRCS settings.kcfgc) +kconfig_add_kcfg_files(maildirresource_SRCS settings.kcfgc) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/maildirresource.kcfg org.kde.Akonadi.Maildir.Settings) -qt4_add_dbus_adaptor(maildirresource_SRCS +qt5_add_dbus_adaptor(maildirresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.Maildir.Settings.xml settings.h Akonadi_Maildir_Resource::MaildirSettings maildirsettingsadaptor MaildirSettingsAdaptor ) -kde4_add_plugin(akonadi_maildir_resource ${maildirresource_SRCS}) +add_executable(akonadi_maildir_resource ${maildirresource_SRCS}) -target_link_libraries(akonadi_maildir_resource ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_AKONADI_KMIME_LIBS} maildir ${QT_QTDBUS_LIBRARY} ${KDE4_KIO_LIBS} ${KDEPIMLIBS_KMIME_LIBS} folderarchivesettings ) +target_link_libraries(akonadi_maildir_resource KF5::AkonadiCore KF5::AkonadiMime maildir KF5::KIOCore KF5::Mime folderarchivesettings KF5::AkonadiAgentBase KF5::DBusAddons) -install(TARGETS akonadi_maildir_resource DESTINATION ${PLUGIN_INSTALL_DIR}) +install(TARGETS akonadi_maildir_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.Maildir.Settings.xml - DESTINATION ${DBUS_INTERFACES_INSTALL_DIR}) + DESTINATION ${KDE_INSTALL_DBUSINTERFACEDIR}) + +install( FILES maildirresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) + diff -Nru kdepim-runtime-4.14.6/resources/maildir/configdialog.cpp kdepim-runtime-15.08.0/resources/maildir/configdialog.cpp --- kdepim-runtime-4.14.6/resources/maildir/configdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/configdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,31 +26,45 @@ #include #include #include +#include +#include using KPIM::Maildir; using namespace Akonadi_Maildir_Resource; -ConfigDialog::ConfigDialog(MaildirSettings *settings, const QString &identifier, QWidget * parent) : - KDialog( parent ), - mSettings( settings ), - mToplevelIsContainer( false ) -{ - setCaption( i18n( "Select a MailDir folder" ) ); - ui.setupUi( mainWidget() ); - mFolderArchiveSettingPage = new FolderArchiveSettingPage(identifier); - mFolderArchiveSettingPage->loadSettings(); - ui.tabWidget->addTab(mFolderArchiveSettingPage, i18n("Folder Archive")); - - mManager = new KConfigDialogManager( this, mSettings ); - mManager->updateWidgets(); - ui.kcfg_Path->setMode( KFile::Directory | KFile::ExistingOnly ); - ui.kcfg_Path->setUrl( KUrl( mSettings->path() ) ); - - connect( this, SIGNAL(okClicked()), SLOT(save()) ); - connect( ui.kcfg_Path->lineEdit(), SIGNAL(textChanged(QString)), SLOT(checkPath()) ); - ui.kcfg_Path->lineEdit()->setFocus(); - checkPath(); - readConfig(); +ConfigDialog::ConfigDialog(MaildirSettings *settings, const QString &identifier, QWidget *parent) : + QDialog(parent), + mSettings(settings), + mToplevelIsContainer(false) +{ + setWindowTitle(i18n("Select a MailDir folder")); + QWidget *mainWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); + ui.setupUi(mainWidget); + mFolderArchiveSettingPage = new FolderArchiveSettingPage(identifier); + mFolderArchiveSettingPage->loadSettings(); + ui.tabWidget->addTab(mFolderArchiveSettingPage, i18n("Folder Archive")); + + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + mOkButton = buttonBox->button(QDialogButtonBox::Ok); + mOkButton->setDefault(true); + mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &ConfigDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &ConfigDialog::reject); + mainLayout->addWidget(buttonBox); + + mManager = new KConfigDialogManager(this, mSettings); + mManager->updateWidgets(); + ui.kcfg_Path->setMode(KFile::Directory | KFile::ExistingOnly); + ui.kcfg_Path->setUrl(QUrl::fromLocalFile(mSettings->path())); + + connect(mOkButton, &QPushButton::clicked, this, &ConfigDialog::save); + connect(ui.kcfg_Path->lineEdit(), SIGNAL(textChanged(QString)), SLOT(checkPath())); + ui.kcfg_Path->lineEdit()->setFocus(); + checkPath(); + readConfig(); } ConfigDialog::~ConfigDialog() @@ -60,73 +74,73 @@ void ConfigDialog::readConfig() { - KConfigGroup group( KGlobal::config(), "ConfigDialog" ); - const QSize size = group.readEntry( "Size", QSize(600, 400) ); - if ( size.isValid() ) { - resize( size ); + KConfigGroup group(KSharedConfig::openConfig(), "ConfigDialog"); + const QSize size = group.readEntry("Size", QSize(600, 400)); + if (size.isValid()) { + resize(size); } } void ConfigDialog::writeConfig() { - KConfigGroup group( KGlobal::config(), "ConfigDialog" ); - group.writeEntry( "Size", size() ); + KConfigGroup group(KSharedConfig::openConfig(), "ConfigDialog"); + group.writeEntry("Size", size()); group.sync(); } void ConfigDialog::checkPath() { - if ( ui.kcfg_Path->url().isEmpty() ) { - ui.statusLabel->setText( i18n( "The selected path is empty." ) ); - enableButton( Ok, false ); - return; - } - bool ok = false; - mToplevelIsContainer = false; - QDir d( ui.kcfg_Path->url().toLocalFile() ); - - if ( d.exists() ) { - Maildir md( d.path() ); - if ( !md.isValid( false ) ) { - Maildir md2( d.path(), true ); - if ( md2.isValid( false ) ) { - ui.statusLabel->setText( i18n( "The selected path contains valid Maildir folders." ) ); - mToplevelIsContainer = true; - ok = true; - } else { - ui.statusLabel->setText( md.lastError() ); - } - } else { - ui.statusLabel->setText( i18n( "The selected path is a valid Maildir." ) ); - ok = true; + if (ui.kcfg_Path->url().isEmpty()) { + ui.statusLabel->setText(i18n("The selected path is empty.")); + mOkButton->setEnabled(false); + return; } - } else { - d.cdUp(); - if ( d.exists() ) { - ui.statusLabel->setText( i18n( "The selected path does not exist yet, a new Maildir will be created." ) ); - mToplevelIsContainer = true; - ok = true; + bool ok = false; + mToplevelIsContainer = false; + QDir d(ui.kcfg_Path->url().toLocalFile()); + + if (d.exists()) { + Maildir md(d.path()); + if (!md.isValid(false)) { + Maildir md2(d.path(), true); + if (md2.isValid(false)) { + ui.statusLabel->setText(i18n("The selected path contains valid Maildir folders.")); + mToplevelIsContainer = true; + ok = true; + } else { + ui.statusLabel->setText(md.lastError()); + } + } else { + ui.statusLabel->setText(i18n("The selected path is a valid Maildir.")); + ok = true; + } } else { - ui.statusLabel->setText( i18n( "The selected path does not exist." ) ); + d.cdUp(); + if (d.exists()) { + ui.statusLabel->setText(i18n("The selected path does not exist yet, a new Maildir will be created.")); + mToplevelIsContainer = true; + ok = true; + } else { + ui.statusLabel->setText(i18n("The selected path does not exist.")); + } } - } - enableButton( Ok, ok ); + mOkButton->setEnabled(ok); } void ConfigDialog::save() { - mFolderArchiveSettingPage->writeSettings(); - mManager->updateSettings(); - QString path = ui.kcfg_Path->url().isLocalFile() ? ui.kcfg_Path->url().toLocalFile() : ui.kcfg_Path->url().path(); - mSettings->setPath( path ); - mSettings->setTopLevelIsContainer( mToplevelIsContainer ); - mSettings->writeConfig(); - - if ( ui.kcfg_Path->url().isLocalFile() ) { - QDir d( path ); - if ( !d.exists() ) { - d.mkpath( ui.kcfg_Path->url().toLocalFile() ); + mFolderArchiveSettingPage->writeSettings(); + mManager->updateSettings(); + QString path = ui.kcfg_Path->url().isLocalFile() ? ui.kcfg_Path->url().toLocalFile() : ui.kcfg_Path->url().path(); + mSettings->setPath(path); + mSettings->setTopLevelIsContainer(mToplevelIsContainer); + mSettings->save(); + + if (ui.kcfg_Path->url().isLocalFile()) { + QDir d(path); + if (!d.exists()) { + d.mkpath(ui.kcfg_Path->url().toLocalFile()); + } } - } } diff -Nru kdepim-runtime-4.14.6/resources/maildir/configdialog.h kdepim-runtime-15.08.0/resources/maildir/configdialog.h --- kdepim-runtime-4.14.6/resources/maildir/configdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/configdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,35 +20,36 @@ #ifndef CONFIGDIALOG_H #define CONFIGDIALOG_H -#include +#include #include "ui_settings.h" - +class QPushButton; class KConfigDialogManager; namespace Akonadi_Maildir_Resource { class MaildirSettings; } class FolderArchiveSettingPage; -class ConfigDialog : public KDialog +class ConfigDialog : public QDialog { - Q_OBJECT - public: - explicit ConfigDialog( Akonadi_Maildir_Resource::MaildirSettings *settings, const QString &identifier, QWidget *parent = 0 ); + Q_OBJECT +public: + explicit ConfigDialog(Akonadi_Maildir_Resource::MaildirSettings *settings, const QString &identifier, QWidget *parent = Q_NULLPTR); ~ConfigDialog(); - private slots: +private Q_SLOTS: void checkPath(); void save(); - private: +private: void readConfig(); void writeConfig(); Ui::ConfigDialog ui; - KConfigDialogManager* mManager; + KConfigDialogManager *mManager; FolderArchiveSettingPage *mFolderArchiveSettingPage; Akonadi_Maildir_Resource::MaildirSettings *mSettings; bool mToplevelIsContainer; + QPushButton *mOkButton; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/maildir/libmaildir/autotests/CMakeLists.txt kdepim-runtime-15.08.0/resources/maildir/libmaildir/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/maildir/libmaildir/autotests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/libmaildir/autotests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,19 @@ +include(ECMAddTests) + +find_package(Qt5Test CONFIG REQUIRED) + +set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) + +include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. ) + +########### next target ############### + +set(testmaildir_SRCS testmaildir.cpp ) + + +add_executable( testmaildir ${testmaildir_SRCS} ) +add_test( testmaildir testmaildir ) +ecm_mark_as_test(maildir-testmaildir) + +target_link_libraries(testmaildir Qt5::Test KF5::AkonadiMime maildir) + diff -Nru kdepim-runtime-4.14.6/resources/maildir/libmaildir/autotests/testmaildir.cpp kdepim-runtime-15.08.0/resources/maildir/libmaildir/autotests/testmaildir.cpp --- kdepim-runtime-4.14.6/resources/maildir/libmaildir/autotests/testmaildir.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/libmaildir/autotests/testmaildir.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,436 @@ +/* + This file is part of the kpimutils library. + + Copyright (C) 2007 Till Adam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 "testmaildir.h" + +#include + +#include +#include + +#include + +#include +#include + +QTEST_MAIN(MaildirTest) + +#include "../maildir.h" +using namespace KPIM; + +static const char *testDir = "libmaildir-unit-test"; +static const char *testString = "From: theDukeOfMonmouth@uk.gov\n \nTo: theDukeOfBuccleuch@uk.gov\n\ntest\n"; +static const char *testStringHeaders = "From: theDukeOfMonmouth@uk.gov\n \nTo: theDukeOfBuccleuch@uk.gov\n"; + +void MaildirTest::init() +{ + QString tmpPath(QDir::tempPath() + QLatin1Char('/') + QLatin1String(testDir)); + QDir().mkpath(tmpPath); + m_temp = new QTemporaryDir(tmpPath); + + QDir temp(m_temp->path()); + QVERIFY(temp.exists()); + + temp.mkdir(QLatin1String("new")); + QVERIFY(temp.exists(QLatin1String("new"))); + temp.mkdir(QLatin1String("cur")); + QVERIFY(temp.exists(QLatin1String("cur"))); + temp.mkdir(QLatin1String("tmp")); + QVERIFY(temp.exists(QLatin1String("tmp"))); +} + +void MaildirTest::cleanup() +{ + m_temp->remove(); + QDir d(m_temp->path()); + const QString subFolderPath(QString::fromLatin1(".%1.directory").arg(d.dirName())); + QDir((subFolderPath)).removeRecursively(); + + delete m_temp; + m_temp = 0; +} + +void MaildirTest::fillDirectory(const QString &name, int limit) +{ + QFile file; + QDir::setCurrent(m_temp->path() + QLatin1Char('/') + name); + for (int i = 0; i < limit ; i++) { + file.setFileName(QLatin1String("testmail-") + QString::number(i)); + file.open(QIODevice::WriteOnly); + file.write(testString); + file.flush(); + file.close(); + } +} + +void MaildirTest::createSubFolders() +{ + QDir d(m_temp->path()); + const QString subFolderPath(QString::fromLatin1(".%1.directory").arg(d.dirName())); + d.cdUp(); + d.mkdir(subFolderPath); + d.cd(subFolderPath); + d.mkdir(QStringLiteral("foo")); + d.mkdir(QStringLiteral("barbar")); + d.mkdir(QStringLiteral("bazbaz")); +} + +void MaildirTest::fillNewDirectory() +{ + fillDirectory(QLatin1String("new"), 140); +} + +void MaildirTest::fillCurrentDirectory() +{ + fillDirectory(QLatin1String("cur"), 20); +} + +void MaildirTest::testMaildirInstantiation() +{ + Maildir d(QLatin1String("/foo/bar/Mail")); + Maildir d2(d); + Maildir d3; + d3 = d; + QVERIFY(d == d2); + QVERIFY(d3 == d2); + QVERIFY(d == d3); + QCOMPARE(d.path(), QString(QLatin1String("/foo/bar/Mail"))); + QCOMPARE(d.name(), QString(QLatin1String("Mail"))); + + QVERIFY(!d.isValid()); + + Maildir good(m_temp->path()); + QVERIFY(good.isValid()); + + QDir temp(m_temp->path()); + temp.rmdir(QLatin1String("new")); + QVERIFY(!good.isValid(false)); + QVERIFY(!good.lastError().isEmpty()); + + Maildir root1(QLatin1String("/foo/bar/Mail"), true); + QVERIFY(root1.isRoot()); + + Maildir root1Copy = root1; + QCOMPARE(root1Copy.path(), root1.path()); + QCOMPARE(root1Copy.isRoot(), root1.isRoot()); + + // FIXME test insufficient permissions? +} + +void MaildirTest::testMaildirListing() +{ + fillNewDirectory(); + + Maildir d(m_temp->path()); + QStringList entries = d.entryList(); + + QCOMPARE(entries.count(), 140); + + fillCurrentDirectory(); + entries = d.entryList(); + QCOMPARE(entries.count(), 160); +} + +void MaildirTest::testMaildirAccess() +{ + fillCurrentDirectory(); + Maildir d(m_temp->path()); + QStringList entries = d.entryList(); + QCOMPARE(entries.count(), 20); + + QByteArray data = d.readEntry(entries[0]); + QVERIFY(!data.isEmpty()); + QCOMPARE(data, QByteArray(testString)); +} + +void MaildirTest::testMaildirReadHeaders() +{ + fillCurrentDirectory(); + Maildir d(m_temp->path()); + QStringList entries = d.entryList(); + QCOMPARE(entries.count(), 20); + + QByteArray data = d.readEntryHeaders(entries[0]); + QVERIFY(!data.isEmpty()); + QCOMPARE(data, QByteArray(testStringHeaders)); +} + +void MaildirTest::testMaildirWrite() +{ + fillCurrentDirectory(); + Maildir d(m_temp->path()); + QStringList entries = d.entryList(); + QCOMPARE(entries.count(), 20); + + QByteArray data = d.readEntry(entries[0]); + QByteArray data2 = "changed\n"; + QVERIFY(d.writeEntry(entries[0], data2)); + QCOMPARE(data2, d.readEntry(entries[0])); +} + +void MaildirTest::testMaildirAppend() +{ + Maildir d(m_temp->path()); + QByteArray data = "newentry\n"; + QString key = d.addEntry(data); + QVERIFY(!key.isEmpty()); + QCOMPARE(data, d.readEntry(key)); +} + +void MaildirTest::testMaildirCreation() +{ + QString p(QLatin1String("CREATETEST")); + QString tmpPath(QDir::tempPath() + QLatin1Char('/') + p); + QDir().mkpath(tmpPath); + std::auto_ptr temp(new QTemporaryDir(tmpPath)); + Maildir d(temp->path() + p); + QVERIFY(!d.isValid(false)); + d.create(); + QVERIFY(d.isValid()); +} + +void MaildirTest::testMaildirRemoveEntry() +{ + Maildir d(m_temp->path()); + QByteArray data = "newentry\n"; + QString key = d.addEntry(data); + QVERIFY(!key.isEmpty()); + QCOMPARE(data, d.readEntry(key)); + QVERIFY(d.removeEntry(key)); + QVERIFY(d.readEntry(key).isEmpty()); +} + +void MaildirTest::testMaildirListSubfolders() +{ + fillNewDirectory(); + + Maildir d(m_temp->path()); + QStringList entries = d.subFolderList(); + + QVERIFY(entries.isEmpty()); + + createSubFolders(); + + entries = d.subFolderList(); + QVERIFY(!entries.isEmpty()); + QCOMPARE(entries.count(), 3); +} + +void MaildirTest::testMaildirCreateSubfolder() +{ + Maildir d(m_temp->path()); + QStringList entries = d.subFolderList(); + QVERIFY(entries.isEmpty()); + + d.addSubFolder(QLatin1String("subFolderTest")); + entries = d.subFolderList(); + QVERIFY(!entries.isEmpty()); + QCOMPARE(entries.count(), 1); + Maildir child = d.subFolder(entries.first()); + QVERIFY(child.isValid()); +} + +void MaildirTest::testMaildirRemoveSubfolder() +{ + Maildir d(m_temp->path()); + QVERIFY(d.isValid()); + + QString folderPath = d.addSubFolder(QLatin1String("subFolderTest")); + QVERIFY(!folderPath.isEmpty()); + QVERIFY(folderPath.endsWith(QLatin1String(".directory/subFolderTest"))); + bool removingWorked = d.removeSubFolder(QLatin1String("subFolderTest")); + QVERIFY(removingWorked); +} + +void MaildirTest::testMaildirRename() +{ + Maildir d(m_temp->path()); + QVERIFY(d.isValid()); + + QString folderPath = d.addSubFolder(QLatin1String("rename me!")); + QVERIFY(!folderPath.isEmpty()); + + Maildir d2(folderPath); + QVERIFY(d2.isValid()); + QVERIFY(d2.rename(QLatin1String("renamed"))); + QCOMPARE(d2.name(), QString(QLatin1String("renamed"))); + + // same again, should not fail + QVERIFY(d2.rename(QLatin1String("renamed"))); + QCOMPARE(d2.name(), QString(QLatin1String("renamed"))); + + // already existing name + QVERIFY(!d.addSubFolder(QLatin1String("this name is already taken")).isEmpty()); + QVERIFY(!d2.rename(QLatin1String("this name is already taken"))); +} + +void MaildirTest::testMaildirMoveTo() +{ + Maildir d(m_temp->path()); + QVERIFY(d.isValid()); + + QString folderPath1 = d.addSubFolder(QLatin1String("child1")); + QVERIFY(!folderPath1.isEmpty()); + + Maildir d2(folderPath1); + QVERIFY(d2.isValid()); + + QDir d2Dir(d2.path()); + QVERIFY(d2Dir.exists()); + + QString folderPath11 = d2.addSubFolder(QLatin1String("grandchild1")); + + Maildir d21(folderPath11); + QVERIFY(d21.isValid()); + + QDir d2SubDir(Maildir::subDirPathForFolderPath(d2.path())); + QVERIFY(d2SubDir.exists()); + + QString folderPath2 = d.addSubFolder(QLatin1String("child2")); + QVERIFY(!folderPath2.isEmpty()); + + Maildir d3(folderPath2); + QVERIFY(d3.isValid()); + + // move child1 to child2 + QVERIFY(d2.moveTo(d3)); + + Maildir d31 = d3.subFolder(QLatin1String("child1")); + QVERIFY(d31.isValid()); + + QVERIFY(!d2Dir.exists()); + QVERIFY(!d2SubDir.exists()); + + QDir d31Dir(d31.path()); + QVERIFY(d31Dir.exists()); + + QDir d31SubDir(Maildir::subDirPathForFolderPath(d31.path())); + QVERIFY(d31SubDir.exists()); + + Maildir d311 = d31.subFolder(QLatin1String("grandchild1")); + QVERIFY(d311.isValid()); + + // try moving again + d2 = Maildir(folderPath1); + QVERIFY(!d2.isValid(false)); + QVERIFY(!d2.moveTo(d3)); +} + +void MaildirTest::testMaildirFlagsReading() +{ + QFile file; + const QStringList markers = QStringList() << "P" << "R" << "S" << "F" << "FPRS"; + QDir::setCurrent(m_temp->path() + QLatin1Char('/') + "cur"); + for (int i = 0; i < 6 ; i++) { + QString fileName = QLatin1String("testmail-") + QString::number(i); + if (i < 5) { + fileName += +#ifdef Q_OS_WIN + "!2," +#else + ":2," +#endif + + markers[i]; + } + file.setFileName(fileName); + file.open(QIODevice::WriteOnly); + file.write(testString); + file.flush(); + file.close(); + } + + Maildir d(m_temp->path()); + QStringList entries = d.entryList(); + // Maildir::entryList() doesn't sort for performance reasons, + // do it here to make test sequence reliable. + entries.sort(); + + QCOMPARE(entries.count(), 6); + + Akonadi::Item::Flags flags = d.readEntryFlags(entries[0]); + QCOMPARE(flags.count(), 1); + QVERIFY(flags.contains(Akonadi::MessageFlags::Forwarded)); + + flags = d.readEntryFlags(entries[1]); + QCOMPARE(flags.count(), 1); + QVERIFY(flags.contains(Akonadi::MessageFlags::Replied)); + + flags = d.readEntryFlags(entries[2]); + QCOMPARE(flags.count(), 1); + QVERIFY(flags.contains(Akonadi::MessageFlags::Seen)); + + flags = d.readEntryFlags(entries[3]); + QCOMPARE(flags.count(), 1); + QVERIFY(flags.contains(Akonadi::MessageFlags::Flagged)); + + flags = d.readEntryFlags(entries[4]); + QCOMPARE(flags.count(), 4); + QVERIFY(flags.contains(Akonadi::MessageFlags::Forwarded)); + QVERIFY(flags.contains(Akonadi::MessageFlags::Replied)); + QVERIFY(flags.contains(Akonadi::MessageFlags::Seen)); + QVERIFY(flags.contains(Akonadi::MessageFlags::Flagged)); + + flags = d.readEntryFlags(entries[5]); + QVERIFY(flags.isEmpty()); +} + +void MaildirTest::testMaildirFlagsWriting_data() +{ + QTest::addColumn("origDir"); + QTest::addColumn("origFileName"); + QTest::newRow("cur/") << "cur" << "testmail"; + QTest::newRow("cur/S") << "cur" << "testmail:2,S"; // wrongly marked as "seen" on disk (#289428) + QTest::newRow("new/") << "new" << "testmail"; + QTest::newRow("new/S") << "new" << "testmail:2,S"; +} + +void MaildirTest::testMaildirFlagsWriting() +{ + QFETCH(QString, origDir); + QFETCH(QString, origFileName); + + // create an initialy new mail + QFile file; + QDir::setCurrent(m_temp->path()); + file.setFileName(origDir + QLatin1Char('/') + origFileName); + file.open(QIODevice::WriteOnly); + file.write(testString); + file.flush(); + file.close(); + + // add a single flag + Maildir d(m_temp->path()); + const QStringList entries = d.entryList(); + QCOMPARE(entries.size(), 1); + QVERIFY(QFile::exists(origDir + QLatin1Char('/') + entries[0])); + const QString newKey = d.changeEntryFlags(entries[0], Akonadi::Item::Flags() << Akonadi::MessageFlags::Seen); + // make sure the new key exists + QCOMPARE(newKey, d.entryList()[0]); + QVERIFY(QFile::exists("cur/" + newKey)); + // and it's the right file + QCOMPARE(d.readEntry(newKey), QByteArray(testString)); + // now check the file name + QVERIFY(newKey.endsWith(QLatin1String("2,S"))); + // and more flags + const QString newKey2 = d.changeEntryFlags(newKey, Akonadi::Item::Flags() << Akonadi::MessageFlags::Seen << Akonadi::MessageFlags::Replied); + // check the file name, and the sorting of markers + QVERIFY(newKey2.endsWith(QLatin1String("2,RS"))); + QVERIFY(QFile::exists("cur/" + newKey2)); +} diff -Nru kdepim-runtime-4.14.6/resources/maildir/libmaildir/autotests/testmaildir.h kdepim-runtime-15.08.0/resources/maildir/libmaildir/autotests/testmaildir.h --- kdepim-runtime-4.14.6/resources/maildir/libmaildir/autotests/testmaildir.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/libmaildir/autotests/testmaildir.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,59 @@ +/* + This file is part of the kpimutils library. + + Copyright (c) 2007 Till Adam + + 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 MAILDIRTEST_H +#define MAILDIRTEST_H + +#include + +class QTemporaryDir; + +class MaildirTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void init(); + void testMaildirInstantiation(); + void testMaildirCreation(); + void testMaildirListing(); + void testMaildirAccess(); + void testMaildirReadHeaders(); + void testMaildirWrite(); + void testMaildirAppend(); + void testMaildirRemoveEntry(); + void testMaildirListSubfolders(); + void testMaildirCreateSubfolder(); + void testMaildirRemoveSubfolder(); + void testMaildirRename(); + void testMaildirMoveTo(); + void testMaildirFlagsReading(); + void testMaildirFlagsWriting_data(); + void testMaildirFlagsWriting(); + void cleanup(); +private: + void fillDirectory(const QString &name, int limit); + void fillNewDirectory(); + void fillCurrentDirectory(); + void createSubFolders(); + QTemporaryDir *m_temp; +}; + +#endif diff -Nru kdepim-runtime-4.14.6/resources/maildir/libmaildir/CMakeLists.txt kdepim-runtime-15.08.0/resources/maildir/libmaildir/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/maildir/libmaildir/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/libmaildir/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,12 +1,17 @@ -add_subdirectory( tests ) +if (BUILD_TESTING) + add_subdirectory( autotests ) +endif() -set(maildir_LIB_SRCS keycache.cpp maildir.cpp) +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_maildir_resource\") -kde4_add_library(maildir ${LIBRARY_TYPE} ${maildir_LIB_SRCS}) +set(maildir_LIB_SRCS keycache.cpp maildir.cpp libmaildir_debug.cpp) -target_link_libraries(maildir ${KDE4_KDECORE_LIBS} ${KDEPIMLIBS_KPIMUTILS_LIBS} ${KDEPIMLIBS_AKONADI_KMIME_LIBS} ${QT_QTNETWORK_LIBRARY}) +add_library(maildir ${maildir_LIB_SRCS}) +generate_export_header(maildir BASE_NAME maildir) -set_target_properties(maildir PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} ) +target_link_libraries(maildir PUBLIC KF5::AkonadiMime PRIVATE KF5::KDELibs4Support KF5::I18n Qt5::Network) -install(TARGETS maildir ${INSTALL_TARGETS_DEFAULT_ARGS}) +set_target_properties(maildir PROPERTIES VERSION ${KDEPIMRUNTIME_LIB_VERSION} SOVERSION ${KDEPIMRUNTIME_LIB_SOVERSION} ) + +install(TARGETS maildir ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/maildir/libmaildir/keycache.cpp kdepim-runtime-15.08.0/resources/maildir/libmaildir/keycache.cpp --- kdepim-runtime-4.14.6/resources/maildir/libmaildir/keycache.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/libmaildir/keycache.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -16,73 +16,72 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - #include "keycache.h" #include -KeyCache* KeyCache::mSelf = 0; +KeyCache *KeyCache::mSelf = Q_NULLPTR; -void KeyCache::addKeys( const QString& dir ) +void KeyCache::addKeys(const QString &dir) { - if ( !mNewKeys.contains( dir ) ) { - mNewKeys.insert( dir, listNew( dir ) ); - //kDebug() << "Added new keys for: " << dir; - } + if (!mNewKeys.contains(dir)) { + mNewKeys.insert(dir, listNew(dir)); + //qCDebug(LIBMAILDIR_LOG) << "Added new keys for: " << dir; + } - if ( !mCurKeys.contains( dir ) ) { - mCurKeys.insert( dir, listCurrent( dir ) ); - //kDebug() << "Added cur keys for: " << dir; - } + if (!mCurKeys.contains(dir)) { + mCurKeys.insert(dir, listCurrent(dir)); + //qCDebug(LIBMAILDIR_LOG) << "Added cur keys for: " << dir; + } } -void KeyCache::refreshKeys( const QString& dir ) +void KeyCache::refreshKeys(const QString &dir) { - mNewKeys.remove( dir ); - mCurKeys.remove( dir ); - addKeys( dir ); + mNewKeys.remove(dir); + mCurKeys.remove(dir); + addKeys(dir); } -void KeyCache::addNewKey( const QString& dir, const QString& key ) +void KeyCache::addNewKey(const QString &dir, const QString &key) { - mNewKeys[dir].insert( key ); - // kDebug() << "Added new key for : " << dir << " key: " << key; + mNewKeys[dir].insert(key); + // qCDebug(LIBMAILDIR_LOG) << "Added new key for : " << dir << " key: " << key; } -void KeyCache::addCurKey( const QString& dir, const QString& key ) +void KeyCache::addCurKey(const QString &dir, const QString &key) { - mCurKeys[dir].insert( key ); - // kDebug() << "Added cur key for : " << dir << " key:" << key; + mCurKeys[dir].insert(key); + // qCDebug(LIBMAILDIR_LOG) << "Added cur key for : " << dir << " key:" << key; } -void KeyCache::removeKey( const QString& dir, const QString& key ) +void KeyCache::removeKey(const QString &dir, const QString &key) { - //kDebug() << "Removed new and cur key for: " << dir << " key:" << key; - mNewKeys[dir].remove( key ); - mCurKeys[dir].remove( key ); + //qCDebug(LIBMAILDIR_LOG) << "Removed new and cur key for: " << dir << " key:" << key; + mNewKeys[dir].remove(key); + mCurKeys[dir].remove(key); } -bool KeyCache::isCurKey( const QString& dir, const QString& key ) const +bool KeyCache::isCurKey(const QString &dir, const QString &key) const { - return mCurKeys.value( dir ).contains( key ); + return mCurKeys.value(dir).contains(key); } -bool KeyCache::isNewKey( const QString& dir, const QString& key ) const +bool KeyCache::isNewKey(const QString &dir, const QString &key) const { - return mNewKeys.value( dir ).contains( key ); + return mNewKeys.value(dir).contains(key); } -QSet< QString > KeyCache::listNew( const QString& dir ) const +QSet< QString > KeyCache::listNew(const QString &dir) const { - QDir d( dir + QString::fromLatin1( "/new" ) ); + QDir d(dir + QString::fromLatin1("/new")); d.setSorting(QDir::NoSort); - return d.entryList( QDir::Files ).toSet(); + return d.entryList(QDir::Files).toSet(); } -QSet< QString > KeyCache::listCurrent( const QString& dir ) const +QSet< QString > KeyCache::listCurrent(const QString &dir) const { - QDir d( dir + QString::fromLatin1( "/cur" ) ); + QDir d(dir + QString::fromLatin1("/cur")); d.setSorting(QDir::NoSort); - return d.entryList( QDir::Files ).toSet(); + return d.entryList(QDir::Files).toSet(); } diff -Nru kdepim-runtime-4.14.6/resources/maildir/libmaildir/keycache.h kdepim-runtime-15.08.0/resources/maildir/libmaildir/keycache.h --- kdepim-runtime-4.14.6/resources/maildir/libmaildir/keycache.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/libmaildir/keycache.h 2015-08-10 21:01:02.000000000 +0000 @@ -16,7 +16,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - #ifndef KEYCACHE_H #define KEYCACHE_H @@ -27,51 +26,53 @@ #include #include -class KeyCache { +class KeyCache +{ public: - static KeyCache *self() - { - if ( !mSelf ) + static KeyCache *self() + { + if (!mSelf) { mSelf = new KeyCache(); - return mSelf; - } + } + return mSelf; + } - /** Find the new and cur keys on the disk for @param dir and add them to the cache */ - void addKeys( const QString& dir ); + /** Find the new and cur keys on the disk for @param dir and add them to the cache */ + void addKeys(const QString &dir); - /** Refresh the new and cur keys for @param dir */ - void refreshKeys( const QString& dir ); + /** Refresh the new and cur keys for @param dir */ + void refreshKeys(const QString &dir); - /** Add a "new" key for @param dir. */ - void addNewKey( const QString& dir, const QString& key ); + /** Add a "new" key for @param dir. */ + void addNewKey(const QString &dir, const QString &key); - /** Add a "cur" key for @param dir. */ - void addCurKey( const QString& dir, const QString& key ); + /** Add a "cur" key for @param dir. */ + void addCurKey(const QString &dir, const QString &key); - /** Remove all keys associated with @param dir. */ - void removeKey( const QString& dir, const QString& key ); + /** Remove all keys associated with @param dir. */ + void removeKey(const QString &dir, const QString &key); - /** Check if the @param key is a "cur" key in @param dir */ - bool isCurKey( const QString& dir, const QString& key ) const; + /** Check if the @param key is a "cur" key in @param dir */ + bool isCurKey(const QString &dir, const QString &key) const; - /** Check if the @param key is a "new" key in @param dir */ - bool isNewKey( const QString& dir, const QString& key ) const; + /** Check if the @param key is a "new" key in @param dir */ + bool isNewKey(const QString &dir, const QString &key) const; private: - KeyCache() { - } + KeyCache() + { + } - QSet listNew( const QString& dir ) const; + QSet listNew(const QString &dir) const; - QSet listCurrent( const QString& dir ) const; + QSet listCurrent(const QString &dir) const; - QHash< QString, QSet > mNewKeys; - QHash< QString, QSet > mCurKeys; + QHash< QString, QSet > mNewKeys; + QHash< QString, QSet > mCurKeys; - static KeyCache* mSelf; + static KeyCache *mSelf; }; - #endif // KEYCACHE_H diff -Nru kdepim-runtime-4.14.6/resources/maildir/libmaildir/libmaildir_debug.cpp kdepim-runtime-15.08.0/resources/maildir/libmaildir/libmaildir_debug.cpp --- kdepim-runtime-4.14.6/resources/maildir/libmaildir/libmaildir_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/libmaildir/libmaildir_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 "libmaildir_debug.h" +Q_LOGGING_CATEGORY(LIBMAILDIR_LOG, "log_libmaildir") + diff -Nru kdepim-runtime-4.14.6/resources/maildir/libmaildir/libmaildir_debug.h kdepim-runtime-15.08.0/resources/maildir/libmaildir/libmaildir_debug.h --- kdepim-runtime-4.14.6/resources/maildir/libmaildir/libmaildir_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/libmaildir/libmaildir_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 LIBMAILDIR_DEBUG_H +#define LIBMAILDIR_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(LIBMAILDIR_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/maildir/libmaildir/maildir.cpp kdepim-runtime-15.08.0/resources/maildir/libmaildir/maildir.cpp --- kdepim-runtime-4.14.6/resources/maildir/libmaildir/maildir.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/libmaildir/maildir.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,10 +26,9 @@ #include #include -#include -#include -#include -#include +#include "libmaildir_debug.h" +#include +#include #include #include @@ -38,156 +37,156 @@ //Define it to get more debug output to expense of operating speed // #define DEBUG_KEYCACHE_CONSITENCY - static void initRandomSeed() { - static bool init = false; - if ( !init ) { - unsigned int seed; - init = true; - int fd = KDE_open( "/dev/urandom", O_RDONLY ); - if ( fd < 0 || ::read( fd, &seed, sizeof( seed ) ) != sizeof( seed ) ) { - // No /dev/urandom... try something else. - srand( getpid() ); - seed = rand() + time( 0 ); - } + static bool init = false; + if (!init) { + unsigned int seed; + init = true; + int fd = KDE_open("/dev/urandom", O_RDONLY); + if (fd < 0 || ::read(fd, &seed, sizeof(seed)) != sizeof(seed)) { + // No /dev/urandom... try something else. + srand(getpid()); + seed = rand() + time(Q_NULLPTR); + } - if ( fd >= 0 ) - close( fd ); + if (fd >= 0) { + close(fd); + } - qsrand( seed ); - } + qsrand(seed); + } } using namespace KPIM; -Q_GLOBAL_STATIC_WITH_ARGS( QRegExp, statusSeparatorRx, (":|!") ) +Q_GLOBAL_STATIC_WITH_ARGS(QRegExp, statusSeparatorRx, (":|!")) class Maildir::Private { public: - Private( const QString& p, bool isRoot ) - :path(p), isRoot(isRoot) + Private(const QString &p, bool isRoot) + : path(p), isRoot(isRoot) { - hostName = QHostInfo::localHostName(); - // The default implementation of QUuid::createUuid() doesn't use - // a seed that is random enough. Therefor we use our own initialization - // until this issue will be fixed in Qt 4.7. - initRandomSeed(); - - //Cache object is created the first time this runs. - //It will live throughout the lifetime of the application - KeyCache::self()->addKeys( path ); + hostName = QHostInfo::localHostName(); + // The default implementation of QUuid::createUuid() doesn't use + // a seed that is random enough. Therefor we use our own initialization + // until this issue will be fixed in Qt 4.7. + initRandomSeed(); + + //Cache object is created the first time this runs. + //It will live throughout the lifetime of the application + KeyCache::self()->addKeys(path); } - Private( const Private& rhs ) + Private(const Private &rhs) { path = rhs.path; isRoot = rhs.isRoot; hostName = rhs.hostName; } - bool operator==( const Private& rhs ) const + bool operator==(const Private &rhs) const { return path == rhs.path; } - bool accessIsPossible( bool createMissingFolders = true ); - bool canAccess( const QString& path ) const; + bool accessIsPossible(bool createMissingFolders = true); + bool canAccess(const QString &path) const; QStringList subPaths() const { QStringList paths; - paths << path + QString::fromLatin1( "/cur" ); - paths << path + QString::fromLatin1( "/new" ); - paths << path + QString::fromLatin1( "/tmp" ); + paths << path + QString::fromLatin1("/cur"); + paths << path + QString::fromLatin1("/new"); + paths << path + QString::fromLatin1("/tmp"); return paths; } QStringList listNew() const { - QDir d( path + QString::fromLatin1( "/new" ) ); + QDir d(path + QString::fromLatin1("/new")); d.setSorting(QDir::NoSort); - return d.entryList( QDir::Files ); + return d.entryList(QDir::Files); } QStringList listCurrent() const { - QDir d( path + QString::fromLatin1( "/cur" ) ); + QDir d(path + QString::fromLatin1("/cur")); d.setSorting(QDir::NoSort); - return d.entryList( QDir::Files ); + return d.entryList(QDir::Files); } - QString findRealKey( const QString& key ) const + QString findRealKey(const QString &key) const { - KeyCache* keyCache = KeyCache::self(); - if ( keyCache->isNewKey( path, key ) ) { + KeyCache *keyCache = KeyCache::self(); + if (keyCache->isNewKey(path, key)) { #ifdef DEBUG_KEYCACHE_CONSITENCY - if ( !QFile::exists( path + QString::fromLatin1( "/new/" ) + key ) ) { - kDebug() << "WARNING: key is in cache, but the file is gone: " << path + QString::fromLatin1( "/new/" ) + key; - } + if (!QFile::exists(path + QString::fromLatin1("/new/") + key)) { + qCDebug(LIBMAILDIR_LOG) << "WARNING: key is in cache, but the file is gone: " << path + QString::fromLatin1("/new/") + key; + } #endif - return path + QString::fromLatin1( "/new/" ) + key; + return path + QString::fromLatin1("/new/") + key; } - if ( keyCache->isCurKey( path, key ) ) { + if (keyCache->isCurKey(path, key)) { #ifdef DEBUG_KEYCACHE_CONSITENCY - if ( !QFile::exists( path + QString::fromLatin1( "/cur/" ) + key ) ) { - kDebug() << "WARNING: key is in cache, but the file is gone: " << path + QString::fromLatin1( "/cur/" ) + key; - } + if (!QFile::exists(path + QString::fromLatin1("/cur/") + key)) { + qCDebug(LIBMAILDIR_LOG) << "WARNING: key is in cache, but the file is gone: " << path + QString::fromLatin1("/cur/") + key; + } #endif - return path + QString::fromLatin1( "/cur/" ) + key; + return path + QString::fromLatin1("/cur/") + key; } - QString realKey = path + QString::fromLatin1( "/new/" ) + key; + QString realKey = path + QString::fromLatin1("/new/") + key; - QFile f( realKey ); - if ( f.exists() ) { - keyCache->addNewKey( path, key ); + QFile f(realKey); + if (f.exists()) { + keyCache->addNewKey(path, key); } else { //not in "new", search in "cur" - realKey = path + QString::fromLatin1( "/cur/" ) + key; - QFile f2( realKey ); - if ( f2.exists() ) { - keyCache->addCurKey( path, key ); - } else { - realKey.clear(); //not in "cur" either - } + realKey = path + QString::fromLatin1("/cur/") + key; + QFile f2(realKey); + if (f2.exists()) { + keyCache->addCurKey(path, key); + } else { + realKey.clear(); //not in "cur" either + } } return realKey; } - static QString subDirNameForFolderName( const QString &folderName ) + static QString subDirNameForFolderName(const QString &folderName) { - return QString::fromLatin1( ".%1.directory" ).arg( folderName ); + return QString::fromLatin1(".%1.directory").arg(folderName); } QString subDirPath() const { - QDir dir( path ); - return subDirNameForFolderName( dir.dirName() ); + QDir dir(path); + return subDirNameForFolderName(dir.dirName()); } - bool moveAndRename( QDir &dest, const QString &newName ) + bool moveAndRename(QDir &dest, const QString &newName) { - if ( !dest.exists() ) { - kDebug() << "Destination does not exist"; - return false; - } - if ( dest.exists( newName ) || dest.exists( subDirNameForFolderName( newName ) ) ) { - kDebug() << "New name already in use"; - return false; - } + if (!dest.exists()) { + qCDebug(LIBMAILDIR_LOG) << "Destination does not exist"; + return false; + } + if (dest.exists(newName) || dest.exists(subDirNameForFolderName(newName))) { + qCDebug(LIBMAILDIR_LOG) << "New name already in use"; + return false; + } - if ( !dest.rename( path, newName ) ) { - kDebug() << "Failed to rename maildir"; - return false; - } - const QDir subDirs( Maildir::subDirPathForFolderPath( path ) ); - if ( subDirs.exists() && !dest.rename( subDirs.path(), subDirNameForFolderName( newName ) ) ) { - kDebug() << "Failed to rename subfolders"; - return false; - } + if (!dest.rename(path, newName)) { + qCDebug(LIBMAILDIR_LOG) << "Failed to rename maildir"; + return false; + } + const QDir subDirs(Maildir::subDirPathForFolderPath(path)); + if (subDirs.exists() && !dest.rename(subDirs.path(), subDirNameForFolderName(newName))) { + qCDebug(LIBMAILDIR_LOG) << "Failed to rename subfolders"; + return false; + } - path = dest.path() + QDir::separator() + newName; - return true; + path = dest.path() + QDir::separator() + newName; + return true; } QString path; @@ -196,116 +195,114 @@ QString lastError; }; -Maildir::Maildir( const QString& path, bool isRoot ) -:d( new Private(path, isRoot) ) +Maildir::Maildir(const QString &path, bool isRoot) + : d(new Private(path, isRoot)) { } -void Maildir::swap( const Maildir &rhs ) +void Maildir::swap(const Maildir &rhs) { Private *p = d; - d = new Private( *rhs.d ); + d = new Private(*rhs.d); delete p; } - -Maildir::Maildir(const Maildir & rhs) - :d( new Private( *rhs.d ) ) +Maildir::Maildir(const Maildir &rhs) + : d(new Private(*rhs.d)) { } -Maildir& Maildir::operator= (const Maildir & rhs) +Maildir &Maildir::operator= (const Maildir &rhs) { // copy and swap, exception safe, and handles assignment to self - Maildir temp( rhs ); - swap( temp ); + Maildir temp(rhs); + swap(temp); return *this; } - -bool Maildir::operator== (const Maildir & rhs) const +bool Maildir::operator== (const Maildir &rhs) const { return *d == *rhs.d; } - Maildir::~Maildir() { delete d; } -bool Maildir::Private::canAccess( const QString& path ) const +bool Maildir::Private::canAccess(const QString &path) const { //return access( QFile::encodeName( path ), R_OK | W_OK | X_OK ) != 0; // FIXME X_OK? - QFileInfo d( path ); + QFileInfo d(path); return d.isReadable() && d.isWritable(); } -bool Maildir::Private::accessIsPossible( bool createMissingFolders ) +bool Maildir::Private::accessIsPossible(bool createMissingFolders) { QStringList paths = subPaths(); - paths.prepend( path ); + paths.prepend(path); - Q_FOREACH ( const QString &p, paths ) { - if ( !QFile::exists( p ) ) { - if ( !createMissingFolders ) { - lastError = i18n( "Error opening %1; this folder is missing.", p ); - return false; + Q_FOREACH (const QString &p, paths) { + if (!QFile::exists(p)) { + if (!createMissingFolders) { + lastError = i18n("Error opening %1; this folder is missing.", p); + return false; } - QDir().mkpath( p ); - if ( !QFile::exists( p ) ) { - lastError = i18n( "Error opening %1; this folder is missing.", p ); - return false; + QDir().mkpath(p); + if (!QFile::exists(p)) { + lastError = i18n("Error opening %1; this folder is missing.", p); + return false; } } - if ( !canAccess( p ) ) { - lastError = i18n( "Error opening %1; either this is not a valid " - "maildir folder, or you do not have sufficient access permissions." ,p ); + if (!canAccess(p)) { + lastError = i18n("Error opening %1; either this is not a valid " + "maildir folder, or you do not have sufficient access permissions." , p); return false; } } return true; } -bool Maildir::isValid( bool createMissingFolders ) const +bool Maildir::isValid(bool createMissingFolders) const { - if ( path().isEmpty() ) { - return false; + if (path().isEmpty()) { + return false; } - if ( !d->isRoot ) { - if ( d->accessIsPossible( createMissingFolders ) ) { - return true; - } + if (!d->isRoot) { + if (d->accessIsPossible(createMissingFolders)) { + return true; + } } else { - Q_FOREACH ( const QString &sf, subFolderList() ) { - const Maildir subMd = Maildir( path() + QLatin1Char( '/' ) + sf ); - if ( !subMd.isValid() ) { - d->lastError = subMd.lastError(); - return false; + Q_FOREACH (const QString &sf, subFolderList()) { + const Maildir subMd = Maildir(path() + QLatin1Char('/') + sf); + if (!subMd.isValid()) { + d->lastError = subMd.lastError(); + return false; + } } - } - return true; + return true; } return false; } bool Maildir::isRoot() const { - return d->isRoot; + return d->isRoot; } bool Maildir::create() { // FIXME: in a failure case, this will leave partially created dirs around // we should clean them up, but only if they didn't previously existed... - Q_FOREACH ( const QString &p, d->subPaths() ) { - QDir dir( p ); - if ( !dir.exists( p ) ) { - if ( !dir.mkpath( p ) ) + Q_FOREACH (const QString &p, d->subPaths()) { + QDir dir(p); + if (!dir.exists(p)) { + if (!dir.mkpath(p)) { return false; + } } } return true; @@ -318,107 +315,118 @@ QString Maildir::name() const { - const QDir dir( d->path ); - return dir.dirName(); + const QDir dir(d->path); + return dir.dirName(); } -QString Maildir::addSubFolder( const QString& path ) +QString Maildir::addSubFolder(const QString &path) { - if ( !isValid() ) + if (!isValid()) { return QString(); + } // make the subdir dir - QDir dir( d->path ); - if ( !d->isRoot ) { + QDir dir(d->path); + if (!d->isRoot) { dir.cdUp(); - if ( !dir.exists( d->subDirPath() ) ) - dir.mkdir( d->subDirPath() ); - dir.cd( d->subDirPath() ); + if (!dir.exists(d->subDirPath())) { + dir.mkdir(d->subDirPath()); + } + dir.cd(d->subDirPath()); } - const QString fullPath = dir.path() + QLatin1Char( '/' ) + path; - Maildir subdir( fullPath ); - if ( subdir.create() ) + const QString fullPath = dir.path() + QLatin1Char('/') + path; + Maildir subdir(fullPath); + if (subdir.create()) { return fullPath; + } return QString(); } -bool Maildir::removeSubFolder( const QString& folderName ) +bool Maildir::removeSubFolder(const QString &folderName) { - if ( !isValid() ) return false; - QDir dir( d->path ); - if ( !d->isRoot ) { + if (!isValid()) { + return false; + } + QDir dir(d->path); + if (!d->isRoot) { dir.cdUp(); - if ( !dir.exists( d->subDirPath() ) ) return false; - dir.cd( d->subDirPath() ); + if (!dir.exists(d->subDirPath())) { + return false; + } + dir.cd(d->subDirPath()); + } + if (!dir.exists(folderName)) { + return false; } - if ( !dir.exists( folderName ) ) return false; // remove it recursively - bool result = KPIMUtils::removeDirAndContentsRecursively( dir.absolutePath() + QLatin1Char( '/' ) + folderName ); + bool result = QDir(dir.absolutePath() + QLatin1Char('/') + folderName).removeRecursively(); QString subfolderName = subDirNameForFolderName(folderName); - if ( dir.exists( subfolderName ) ) - result &= KPIMUtils::removeDirAndContentsRecursively( dir.absolutePath() + QLatin1Char( '/' ) + subfolderName ); + if (dir.exists(subfolderName)) { + result &= QDir(dir.absolutePath() + QLatin1Char('/') + subfolderName).removeRecursively(); + } return result; } -Maildir Maildir::subFolder( const QString& subFolder ) const +Maildir Maildir::subFolder(const QString &subFolder) const { // make the subdir dir - QDir dir( d->path ); - if ( !d->isRoot ) { + QDir dir(d->path); + if (!d->isRoot) { dir.cdUp(); - if ( dir.exists( d->subDirPath() ) ) { - dir.cd( d->subDirPath() ); + if (dir.exists(d->subDirPath())) { + dir.cd(d->subDirPath()); } } - return Maildir( dir.path() + QLatin1Char( '/' ) + subFolder ); + return Maildir(dir.path() + QLatin1Char('/') + subFolder); } Maildir Maildir::parent() const { - if ( !isValid() || d->isRoot ) - return Maildir(); - QDir dir( d->path ); - dir.cdUp(); - if ( !dir.dirName().startsWith( QLatin1Char('.') ) || !dir.dirName().endsWith( QLatin1String( ".directory" ) ) ) - return Maildir(); - const QString parentName = dir.dirName().mid( 1, dir.dirName().size() - 11 ); - dir.cdUp(); - dir.cd( parentName ); - return Maildir ( dir.path() ); + if (!isValid() || d->isRoot) { + return Maildir(); + } + QDir dir(d->path); + dir.cdUp(); + if (!dir.dirName().startsWith(QLatin1Char('.')) || !dir.dirName().endsWith(QLatin1String(".directory"))) { + return Maildir(); + } + const QString parentName = dir.dirName().mid(1, dir.dirName().size() - 11); + dir.cdUp(); + dir.cd(parentName); + return Maildir(dir.path()); } QStringList Maildir::entryList() const { QStringList result; - if ( isValid() ) { + if (isValid()) { result += d->listNew(); result += d->listCurrent(); } - // kDebug() <<"Maildir::entryList()" << result; + // qCDebug(LIBMAILDIR_LOG) <<"Maildir::entryList()" << result; return result; } QStringList Maildir::listCurrent() const { QStringList result; - if ( isValid() ) { + if (isValid()) { result += d->listCurrent(); } return result; } -QString Maildir::findRealKey(const QString& key) const +QString Maildir::findRealKey(const QString &key) const { - return d->findRealKey( key ); + return d->findRealKey(key); } - QStringList Maildir::listNew() const { QStringList result; - if ( isValid() ) { + if (isValid()) { result += d->listNew(); } return result; @@ -426,64 +434,63 @@ QString Maildir::pathToNew() const { - if ( isValid() ) { - return d->path + QString::fromLatin1( "/new" ); + if (isValid()) { + return d->path + QString::fromLatin1("/new"); } return QString(); } QString Maildir::pathToCurrent() const { - if ( isValid() ) { - return d->path + QString::fromLatin1( "/cur" ); + if (isValid()) { + return d->path + QString::fromLatin1("/cur"); } return QString(); } QString Maildir::subDirPath() const { - QDir dir( d->path ); - dir.cdUp(); - return dir.path() + QDir::separator() + d->subDirPath(); + QDir dir(d->path); + dir.cdUp(); + return dir.path() + QDir::separator() + d->subDirPath(); } - - QStringList Maildir::subFolderList() const { - QDir dir( d->path ); + QDir dir(d->path); // the root maildir has its subfolders directly beneath it - if ( !d->isRoot ) { + if (!d->isRoot) { dir.cdUp(); - if ( !dir.exists( d->subDirPath() ) ) + if (!dir.exists(d->subDirPath())) { return QStringList(); - dir.cd( d->subDirPath() ); + } + dir.cd(d->subDirPath()); } - dir.setFilter( QDir::Dirs | QDir::NoDotAndDotDot ); + dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); QStringList entries = dir.entryList(); - entries.removeAll( QLatin1String( "cur" ) ); - entries.removeAll( QLatin1String( "new" ) ); - entries.removeAll( QLatin1String( "tmp" ) ); + entries.removeAll(QLatin1String("cur")); + entries.removeAll(QLatin1String("new")); + entries.removeAll(QLatin1String("tmp")); return entries; } -QByteArray Maildir::readEntry( const QString& key ) const +QByteArray Maildir::readEntry(const QString &key) const { QByteArray result; - QString realKey( d->findRealKey( key ) ); - if ( realKey.isEmpty() ) { + QString realKey(d->findRealKey(key)); + if (realKey.isEmpty()) { // FIXME error handling? - qWarning() << "Maildir::readEntry unable to find: " << key; - d->lastError = i18n( "Cannot locate mail file %1." ,key ); + qCWarning(LIBMAILDIR_LOG) << "Maildir::readEntry unable to find: " << key; + d->lastError = i18n("Cannot locate mail file %1." , key); return result; } - QFile f( realKey ); - if ( !f.open( QIODevice::ReadOnly ) ) { - d->lastError = i18n( "Cannot open mail file %1.", realKey ); - return result; + QFile f(realKey); + if (!f.open(QIODevice::ReadOnly)) { + d->lastError = i18n("Cannot open mail file %1.", realKey); + return result; } // FIXME be safer than this @@ -491,107 +498,109 @@ return result; } -qint64 Maildir::size( const QString& key ) const +qint64 Maildir::size(const QString &key) const { - QString realKey( d->findRealKey( key ) ); - if ( realKey.isEmpty() ) { + QString realKey(d->findRealKey(key)); + if (realKey.isEmpty()) { // FIXME error handling? - qWarning() << "Maildir::size unable to find: " << key; - d->lastError = i18n( "Cannot locate mail file %1." , key ); + qCWarning(LIBMAILDIR_LOG) << "Maildir::size unable to find: " << key; + d->lastError = i18n("Cannot locate mail file %1." , key); return -1; } - QFileInfo info( realKey ); - if ( !info.exists() ) { - d->lastError = i18n( "Cannot open mail file %1." ,realKey ); + QFileInfo info(realKey); + if (!info.exists()) { + d->lastError = i18n("Cannot open mail file %1." , realKey); return -1; } return info.size(); } -QDateTime Maildir::lastModified(const QString& key) const +QDateTime Maildir::lastModified(const QString &key) const { - const QString realKey( d->findRealKey( key ) ); - if ( realKey.isEmpty() ) { - qWarning() << "Maildir::lastModified unable to find: " << key; - d->lastError = i18n( "Cannot locate mail file %1." , key ); + const QString realKey(d->findRealKey(key)); + if (realKey.isEmpty()) { + qCWarning(LIBMAILDIR_LOG) << "Maildir::lastModified unable to find: " << key; + d->lastError = i18n("Cannot locate mail file %1." , key); return QDateTime(); } - const QFileInfo info( realKey ); - if ( !info.exists() ) + const QFileInfo info(realKey); + if (!info.exists()) { return QDateTime(); + } return info.lastModified(); } -QByteArray Maildir::readEntryHeadersFromFile( const QString& file ) const +QByteArray Maildir::readEntryHeadersFromFile(const QString &file) const { QByteArray result; - QFile f( file ); - if ( !f.open( QIODevice::ReadOnly ) ) { + QFile f(file); + if (!f.open(QIODevice::ReadOnly)) { // FIXME error handling? - qWarning() << "Maildir::readEntryHeaders unable to find: " << file; - d->lastError = i18n( "Cannot locate mail file %1." , file ); + qCWarning(LIBMAILDIR_LOG) << "Maildir::readEntryHeaders unable to find: " << file; + d->lastError = i18n("Cannot locate mail file %1." , file); return result; } - f.map( 0, qMin( (qint64)8000, f.size() ) ); + f.map(0, qMin((qint64)8000, f.size())); forever { - QByteArray line = f.readLine(); - if ( line.isEmpty() || line.startsWith('\n') ) + QByteArray line = f.readLine(); + if (line.isEmpty() || line.startsWith('\n')) + { break; - result.append( line ); + } + result.append(line); } return result; } -QByteArray Maildir::readEntryHeaders( const QString& key ) const +QByteArray Maildir::readEntryHeaders(const QString &key) const { - const QString realKey( d->findRealKey( key ) ); - if ( realKey.isEmpty() ) { - qWarning() << "Maildir::readEntryHeaders unable to find: " << key; - d->lastError = i18n( "Cannot locate mail file %1." , key ); + const QString realKey(d->findRealKey(key)); + if (realKey.isEmpty()) { + qCWarning(LIBMAILDIR_LOG) << "Maildir::readEntryHeaders unable to find: " << key; + d->lastError = i18n("Cannot locate mail file %1." , key); return QByteArray(); } - return readEntryHeadersFromFile( realKey ); + return readEntryHeadersFromFile(realKey); } - static QString createUniqueFileName() { qint64 time = QDateTime::currentMSecsSinceEpoch() / 1000; int r = qrand() % 1000; - QString identifier = QLatin1String( "R" ) + QString::number( r ); + QString identifier = QLatin1String("R") + QString::number(r); - QString fileName = QString::number( time ) + QLatin1Char( '.' ) + identifier + QLatin1Char( '.' ); + QString fileName = QString::number(time) + QLatin1Char('.') + identifier + QLatin1Char('.'); return fileName; } -bool Maildir::writeEntry( const QString& key, const QByteArray& data ) +bool Maildir::writeEntry(const QString &key, const QByteArray &data) { - QString realKey( d->findRealKey( key ) ); - if ( realKey.isEmpty() ) { + QString realKey(d->findRealKey(key)); + if (realKey.isEmpty()) { // FIXME error handling? - qWarning() << "Maildir::writeEntry unable to find: " << key; - d->lastError = i18n( "Cannot locate mail file %1." ,key ); + qCWarning(LIBMAILDIR_LOG) << "Maildir::writeEntry unable to find: " << key; + d->lastError = i18n("Cannot locate mail file %1." , key); return false; } - QFile f( realKey ); - bool result = f.open( QIODevice::WriteOnly ); - result = result & ( f.write( data ) != -1 ); + QFile f(realKey); + bool result = f.open(QIODevice::WriteOnly); + result = result & (f.write(data) != -1); f.close(); - if ( !result) { - d->lastError = i18n( "Cannot write to mail file %1." ,realKey ); - return false; + if (!result) { + d->lastError = i18n("Cannot write to mail file %1." , realKey); + return false; } return true; } -QString Maildir::addEntry( const QByteArray& data ) +QString Maildir::addEntry(const QByteArray &data) { QString uniqueKey; QString key; @@ -601,19 +610,19 @@ // QUuid doesn't return globally unique identifiers, therefor we query until we // get one that doesn't exists yet do { - uniqueKey = createUniqueFileName() + d->hostName; - key = d->path + QLatin1String( "/tmp/" ) + uniqueKey; - finalKey = d->path + QLatin1String( "/new/" ) + uniqueKey; - curKey = d->path + QLatin1String( "/cur/" ) + uniqueKey; - } while ( QFile::exists( key ) || QFile::exists( finalKey ) || QFile::exists( curKey ) ); - - QFile f( key ); - bool result = f.open( QIODevice::WriteOnly ); - result = result & ( f.write( data ) != -1 ); + uniqueKey = createUniqueFileName() + d->hostName; + key = d->path + QLatin1String("/tmp/") + uniqueKey; + finalKey = d->path + QLatin1String("/new/") + uniqueKey; + curKey = d->path + QLatin1String("/cur/") + uniqueKey; + } while (QFile::exists(key) || QFile::exists(finalKey) || QFile::exists(curKey)); + + QFile f(key); + bool result = f.open(QIODevice::WriteOnly); + result = result & (f.write(data) != -1); f.close(); - if ( !result) { - d->lastError = i18n( "Cannot write to mail file %1." , key ); - return QString(); + if (!result) { + d->lastError = i18n("Cannot write to mail file %1." , key); + return QString(); } /* * FIXME: @@ -624,223 +633,233 @@ * * For reference: http://trolltech.com/developer/task-tracker/index_html?method=entry&id=211215 */ - if ( !f.rename( finalKey ) ) { - qWarning() << "Maildir: Failed to add entry: " << finalKey << "! Error: " << f.errorString(); - d->lastError = i18n( "Failed to create mail file %1. The error was: %2" , finalKey, f.errorString() ); + if (!f.rename(finalKey)) { + qCWarning(LIBMAILDIR_LOG) << "Maildir: Failed to add entry: " << finalKey << "! Error: " << f.errorString(); + d->lastError = i18n("Failed to create mail file %1. The error was: %2" , finalKey, f.errorString()); return QString(); } KeyCache *keyCache = KeyCache::self(); - keyCache->removeKey( d->path, key ); //remove all keys, be it "cur" or "new" first - keyCache->addNewKey( d->path, key ); //and add a key for "new", as the mail was moved there + keyCache->removeKey(d->path, key); //remove all keys, be it "cur" or "new" first + keyCache->addNewKey(d->path, key); //and add a key for "new", as the mail was moved there return uniqueKey; } -bool Maildir::removeEntry( const QString& key ) +bool Maildir::removeEntry(const QString &key) { - QString realKey( d->findRealKey( key ) ); - if ( realKey.isEmpty() ) { - qWarning() << "Maildir::removeEntry unable to find: " << key; + QString realKey(d->findRealKey(key)); + if (realKey.isEmpty()) { + qCWarning(LIBMAILDIR_LOG) << "Maildir::removeEntry unable to find: " << key; return false; } KeyCache *keyCache = KeyCache::self(); - keyCache->removeKey( d->path, key ); - return QFile::remove( realKey ); + keyCache->removeKey(d->path, key); + return QFile::remove(realKey); } -QString Maildir::changeEntryFlags(const QString& key, const Akonadi::Item::Flags& flags) +QString Maildir::changeEntryFlags(const QString &key, const Akonadi::Item::Flags &flags) { - QString realKey( d->findRealKey( key ) ); - if ( realKey.isEmpty() ) { - qWarning() << "Maildir::changeEntryFlags unable to find: " << key; - d->lastError = i18n( "Cannot locate mail file %1." , key ); + QString realKey(d->findRealKey(key)); + if (realKey.isEmpty()) { + qCWarning(LIBMAILDIR_LOG) << "Maildir::changeEntryFlags unable to find: " << key; + d->lastError = i18n("Cannot locate mail file %1." , key); return QString(); } - const QRegExp rx = *( statusSeparatorRx() ); - QString finalKey = key.left( key.indexOf( rx ) ); + const QRegExp rx = *(statusSeparatorRx()); + QString finalKey = key.left(key.indexOf(rx)); QStringList mailDirFlags; - Q_FOREACH ( const Akonadi::Item::Flag &flag, flags ) { - if ( flag == Akonadi::MessageFlags::Forwarded ) - mailDirFlags << QLatin1String( "P" ); - if ( flag == Akonadi::MessageFlags::Replied ) - mailDirFlags << QLatin1String( "R" ); - if ( flag == Akonadi::MessageFlags::Seen ) - mailDirFlags << QLatin1String( "S" ); - if ( flag == Akonadi::MessageFlags::Deleted ) - mailDirFlags << QLatin1String( "T" ); - if ( flag == Akonadi::MessageFlags::Flagged ) - mailDirFlags << QLatin1String( "F" ); + Q_FOREACH (const Akonadi::Item::Flag &flag, flags) { + if (flag == Akonadi::MessageFlags::Forwarded) { + mailDirFlags << QStringLiteral("P"); + } + if (flag == Akonadi::MessageFlags::Replied) { + mailDirFlags << QStringLiteral("R"); + } + if (flag == Akonadi::MessageFlags::Seen) { + mailDirFlags << QStringLiteral("S"); + } + if (flag == Akonadi::MessageFlags::Deleted) { + mailDirFlags << QStringLiteral("T"); + } + if (flag == Akonadi::MessageFlags::Flagged) { + mailDirFlags << QStringLiteral("F"); + } } mailDirFlags.sort(); - if ( !mailDirFlags.isEmpty() ) { + if (!mailDirFlags.isEmpty()) { #ifdef Q_OS_WIN - finalKey.append( QLatin1String( "!2," ) + mailDirFlags.join( QString() ) ); + finalKey.append(QLatin1String("!2,") + mailDirFlags.join(QString())); #else - finalKey.append( QLatin1String( ":2," ) + mailDirFlags.join( QString() ) ); + finalKey.append(QLatin1String(":2,") + mailDirFlags.join(QString())); #endif } QString newUniqueKey = finalKey; //key without path - finalKey.prepend( d->path + QString::fromLatin1( "/cur/" ) ); + finalKey.prepend(d->path + QString::fromLatin1("/cur/")); + + if (realKey == finalKey) { + // Somehow it already is named this way (e.g. migration bug -> wrong status in akonadi) + return newUniqueKey; + } + + QFile f(realKey); + if (QFile::exists(finalKey)) { + QFile destFile(finalKey); + QByteArray destContent; + if (destFile.open(QIODevice::ReadOnly)) { + destContent = destFile.readAll(); + destFile.close(); + } + QByteArray sourceContent; + if (f.open(QIODevice::ReadOnly)) { + sourceContent = f.readAll(); + f.close(); + } + + if (destContent != sourceContent) { + QString newFinalKey = QLatin1String("1-") + newUniqueKey; + int i = 1; + while (QFile::exists(d->path + QString::fromLatin1("/cur/") + newFinalKey)) { + i++; + newFinalKey = QString::number(i) + QLatin1Char('-') + newUniqueKey; + } + finalKey = d->path + QString::fromLatin1("/cur/") + newFinalKey; + } else { + QFile::remove(finalKey); //they are the same + } + } - if ( realKey == finalKey ) { - // Somehow it already is named this way (e.g. migration bug -> wrong status in akonadi) - return newUniqueKey; - } - - QFile f( realKey ); - if ( QFile::exists( finalKey ) ) { - QFile destFile( finalKey ); - QByteArray destContent; - if ( destFile.open( QIODevice::ReadOnly ) ) { - destContent = destFile.readAll(); - destFile.close(); - } - QByteArray sourceContent; - if ( f.open( QIODevice::ReadOnly ) ) { - sourceContent = f.readAll(); - f.close(); - } - - if ( destContent != sourceContent ) { - QString newFinalKey = QLatin1String("1-") + newUniqueKey; - int i = 1; - while ( QFile::exists( d->path + QString::fromLatin1( "/cur/" ) + newFinalKey ) ) { - i++; - newFinalKey = QString::number( i ) + QLatin1Char('-') + newUniqueKey; - } - finalKey = d->path + QString::fromLatin1( "/cur/" ) + newFinalKey; - } else { - QFile::remove( finalKey ); //they are the same - } - } - - if ( !f.rename( finalKey ) ) { - qWarning() << "Maildir: Failed to rename entry: " << f.fileName() << " to " << finalKey << "! Error: " << f.errorString(); - d->lastError = i18n( "Failed to update the file name %1 to %2 on the disk. The error was: %3." , f.fileName(), finalKey, f.errorString() ); + if (!f.rename(finalKey)) { + qCWarning(LIBMAILDIR_LOG) << "Maildir: Failed to rename entry: " << f.fileName() << " to " << finalKey << "! Error: " << f.errorString(); + d->lastError = i18n("Failed to update the file name %1 to %2 on the disk. The error was: %3." , f.fileName(), finalKey, f.errorString()); return QString(); - } + } KeyCache *keyCache = KeyCache::self(); - keyCache->removeKey( d->path, key ); - keyCache->addCurKey( d->path, newUniqueKey ); + keyCache->removeKey(d->path, key); + keyCache->addCurKey(d->path, newUniqueKey); return newUniqueKey; } -Akonadi::Item::Flags Maildir::readEntryFlags(const QString& key) const +Akonadi::Item::Flags Maildir::readEntryFlags(const QString &key) const { Akonadi::Item::Flags flags; - const QRegExp rx = *( statusSeparatorRx() ); - const int index = key.indexOf( rx ); - if ( index != -1 ) { - const QString mailDirFlags = key.mid( index + 3 ); // after "(:|!)2," + const QRegExp rx = *(statusSeparatorRx()); + const int index = key.indexOf(rx); + if (index != -1) { + const QString mailDirFlags = key.mid(index + 3); // after "(:|!)2," const int flagSize(mailDirFlags.size()); - for ( int i = 0; i < flagSize; ++i ) { - if ( mailDirFlags[i] == QLatin1Char( 'P' ) ) + for (int i = 0; i < flagSize; ++i) { + if (mailDirFlags[i] == QLatin1Char('P')) { flags << Akonadi::MessageFlags::Forwarded; - else if ( mailDirFlags[i] == QLatin1Char( 'R' ) ) + } else if (mailDirFlags[i] == QLatin1Char('R')) { flags << Akonadi::MessageFlags::Replied; - else if ( mailDirFlags[i] == QLatin1Char( 'S' ) ) + } else if (mailDirFlags[i] == QLatin1Char('S')) { flags << Akonadi::MessageFlags::Seen; - else if ( mailDirFlags[i] == QLatin1Char( 'F' ) ) + } else if (mailDirFlags[i] == QLatin1Char('F')) { flags << Akonadi::MessageFlags::Flagged; + } } } return flags; } - -bool Maildir::moveTo( const Maildir &newParent ) +bool Maildir::moveTo(const Maildir &newParent) { - if ( d->isRoot ) - return false; // not supported + if (d->isRoot) { + return false; // not supported + } - QDir newDir( newParent.path() ); - if ( !newParent.d->isRoot ) { - newDir.cdUp(); - if ( !newDir.exists( newParent.d->subDirPath() ) ) - newDir.mkdir( newParent.d->subDirPath() ); - newDir.cd( newParent.d->subDirPath() ); - } + QDir newDir(newParent.path()); + if (!newParent.d->isRoot) { + newDir.cdUp(); + if (!newDir.exists(newParent.d->subDirPath())) { + newDir.mkdir(newParent.d->subDirPath()); + } + newDir.cd(newParent.d->subDirPath()); + } - QDir currentDir( d->path ); - currentDir.cdUp(); + QDir currentDir(d->path); + currentDir.cdUp(); - if ( newDir == currentDir ) - return true; + if (newDir == currentDir) { + return true; + } - return d->moveAndRename( newDir, name() ); + return d->moveAndRename(newDir, name()); } -bool Maildir::rename( const QString &newName ) +bool Maildir::rename(const QString &newName) { - if ( name() == newName ) - return true; - if ( d->isRoot ) - return false; // not (yet) supported + if (name() == newName) { + return true; + } + if (d->isRoot) { + return false; // not (yet) supported + } - QDir dir( d->path ); - dir.cdUp(); + QDir dir(d->path); + dir.cdUp(); - return d->moveAndRename( dir, newName ); + return d->moveAndRename(dir, newName); } -QString Maildir::moveEntryTo( const QString &key, const Maildir &destination ) +QString Maildir::moveEntryTo(const QString &key, const Maildir &destination) { - const QString realKey( d->findRealKey( key ) ); - if ( realKey.isEmpty() ) { - kWarning() << "Unable to find: " << key; - d->lastError = i18n( "Cannot locate mail file %1." , key ); - return QString(); - } - QFile f( realKey ); - // ### is this safe regarding the maildir locking scheme? - const QString targetKey = destination.path() + QDir::separator() + QLatin1String( "new" ) + QDir::separator() + key; - if ( !f.rename( targetKey ) ) { - kDebug() << "Failed to rename" << realKey << "to" << targetKey << "! Error: " << f.errorString();; - d->lastError = f.errorString(); - return QString(); - } + const QString realKey(d->findRealKey(key)); + if (realKey.isEmpty()) { + qCWarning(LIBMAILDIR_LOG) << "Unable to find: " << key; + d->lastError = i18n("Cannot locate mail file %1." , key); + return QString(); + } + QFile f(realKey); + // ### is this safe regarding the maildir locking scheme? + const QString targetKey = destination.path() + QDir::separator() + QLatin1String("new") + QDir::separator() + key; + if (!f.rename(targetKey)) { + qCDebug(LIBMAILDIR_LOG) << "Failed to rename" << realKey << "to" << targetKey << "! Error: " << f.errorString();; + d->lastError = f.errorString(); + return QString(); + } - KeyCache* keyCache = KeyCache::self(); + KeyCache *keyCache = KeyCache::self(); - keyCache->addNewKey( destination.path(), key ); - keyCache->removeKey( d->path, key ); + keyCache->addNewKey(destination.path(), key); + keyCache->removeKey(d->path, key); - return key; + return key; } -QString Maildir::subDirPathForFolderPath( const QString &folderPath ) +QString Maildir::subDirPathForFolderPath(const QString &folderPath) { - QDir dir( folderPath ); - const QString dirName = dir.dirName(); - dir.cdUp(); - return QFileInfo( dir, Private::subDirNameForFolderName( dirName ) ).filePath(); + QDir dir(folderPath); + const QString dirName = dir.dirName(); + dir.cdUp(); + return QFileInfo(dir, Private::subDirNameForFolderName(dirName)).filePath(); } -QString Maildir::subDirNameForFolderName( const QString &folderName ) +QString Maildir::subDirNameForFolderName(const QString &folderName) { - return Private::subDirNameForFolderName( folderName ); + return Private::subDirNameForFolderName(folderName); } -void Maildir::removeCachedKeys(const QStringList & keys) +void Maildir::removeCachedKeys(const QStringList &keys) { - KeyCache *keyCache = KeyCache::self(); - Q_FOREACH ( const QString &key, keys ) { - keyCache->removeKey( d->path, key ); - } + KeyCache *keyCache = KeyCache::self(); + Q_FOREACH (const QString &key, keys) { + keyCache->removeKey(d->path, key); + } } void Maildir::refreshKeyCache() { - KeyCache::self()->refreshKeys( d->path ); + KeyCache::self()->refreshKeys(d->path); } QString Maildir::lastError() const { - return d->lastError; + return d->lastError; } diff -Nru kdepim-runtime-4.14.6/resources/maildir/libmaildir/maildir_export.h kdepim-runtime-15.08.0/resources/maildir/libmaildir/maildir_export.h --- kdepim-runtime-4.14.6/resources/maildir/libmaildir/maildir_export.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/libmaildir/maildir_export.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2007 David Faure - - 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 MAILDIR_EXPORT_H -#define MAILDIR_EXPORT_H - -/* needed for KDE_EXPORT and KDE_IMPORT macros */ -#include - -#ifndef MAILDIR_EXPORT -# if defined(KDEPIM_STATIC_LIBS) - /* No export/import for static libraries */ -# define MAILDIR_EXPORT -# elif defined(MAKE_MAILDIR_LIB) - /* We are building this library */ -# define MAILDIR_EXPORT KDE_EXPORT -# else - /* We are using this library */ -# define MAILDIR_EXPORT KDE_IMPORT -# endif -#endif - -# ifndef MAILDIR_EXPORT_DEPRECATED -# define MAILDIR_EXPORT_DEPRECATED KDE_DEPRECATED MAILDIR_EXPORT -# endif - -#endif diff -Nru kdepim-runtime-4.14.6/resources/maildir/libmaildir/maildir.h kdepim-runtime-15.08.0/resources/maildir/libmaildir/maildir.h --- kdepim-runtime-4.14.6/resources/maildir/libmaildir/maildir.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/libmaildir/maildir.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,16 +20,16 @@ #ifndef MAILDIR_H #define MAILDIR_H - #include "maildir_export.h" #include #include -#include +#include class QDateTime; -namespace KPIM { +namespace KPIM +{ class MAILDIR_EXPORT Maildir { @@ -42,13 +42,13 @@ @param isRoot Indicate whether this is a maildir containing mails and various sub-folders or a container only containing maildirs. */ - explicit Maildir( const QString& path = QString(), bool isRoot = false ); + explicit Maildir(const QString &path = QString(), bool isRoot = false); /* Copy constructor */ - Maildir(const Maildir & rhs); + Maildir(const Maildir &rhs); /* Copy operator */ - Maildir& operator=(const Maildir & rhs); + Maildir &operator=(const Maildir &rhs); /** Equality comparison */ - bool operator==(const Maildir & rhs) const; + bool operator==(const Maildir &rhs) const; /* Destructor */ ~Maildir(); @@ -56,7 +56,7 @@ * that they are readable, etc. * @param createMissingFolders if true (the default), the cur/new/tmp folders are created if they are missing */ - bool isValid( bool createMissingFolders = true ) const; + bool isValid(bool createMissingFolders = true) const; /** * Returns whether this is a normal maildir or a container containing maildirs. @@ -114,7 +114,7 @@ /** * Return the full path to the file identified by key (it can be either in the "new" or "cur" folder **/ - QString findRealKey( const QString& key ) const; + QString findRealKey(const QString &key) const; /** * Returns the list of subfolders, as names (relative paths). Use the @@ -127,19 +127,19 @@ * @return an empty string on failure or the full path of the new subfolder * on success */ - QString addSubFolder( const QString& folderName ); + QString addSubFolder(const QString &folderName); /** * Removes subfolder with the given @p folderName. Returns success or failure. */ - bool removeSubFolder( const QString& folderName ); + bool removeSubFolder(const QString &folderName); /** * Returns a Maildir object for the given @p folderName. If such a folder * exists, the Maildir object will be valid, otherwise you can call create() * on it, to make a subfolder with that name. */ - Maildir subFolder( const QString& folderName ) const; + Maildir subFolder(const QString &folderName) const; /** * Returns the parent Maildir object for this Maildir, if there is one (ie. this is not the root). @@ -150,72 +150,72 @@ * Returns the size of the file in the maildir with the given @p key or \c -1 if key is not valid. * @since 4.2 */ - qint64 size( const QString& key ) const; + qint64 size(const QString &key) const; /** * Returns the modification time of the file in the maildir with the given @p key. * @since 4.7 */ - QDateTime lastModified( const QString &key ) const; + QDateTime lastModified(const QString &key) const; /** * Return the contents of the file in the maildir with the given @p key. */ - QByteArray readEntry( const QString& key ) const; + QByteArray readEntry(const QString &key) const; /** * Return the flags encoded in the maildir file name for an entry **/ - Akonadi::Item::Flags readEntryFlags( const QString& key ) const; + Akonadi::Item::Flags readEntryFlags(const QString &key) const; /** * Return the contents of the headers section of the file the maildir with the given @p file, that * is a full path to the file. You can get it by using findRealKey(key) . */ - QByteArray readEntryHeadersFromFile( const QString& file ) const; + QByteArray readEntryHeadersFromFile(const QString &file) const; /** * Return the contents of the headers section of the file the maildir with the given @p key. */ - QByteArray readEntryHeaders( const QString& key ) const; + QByteArray readEntryHeaders(const QString &key) const; /** * Write the given @p data to a file in the maildir with the given @p key. * Returns true in case of success, false in case of any error. */ - bool writeEntry( const QString& key, const QByteArray& data ); + bool writeEntry(const QString &key, const QByteArray &data); /** * Adds the given @p data to the maildir. Returns the key of the entry. */ - QString addEntry( const QByteArray& data ); + QString addEntry(const QByteArray &data); /** * Removes the entry with the given @p key. Returns success or failure. */ - bool removeEntry( const QString& key ); + bool removeEntry(const QString &key); /** * Change the flags for an entry specified by @p key. Returns the new key of the entry (the key might change because * flags are stored in the unique filename). */ - QString changeEntryFlags( const QString& key, const Akonadi::Item::Flags& flags ); + QString changeEntryFlags(const QString &key, const Akonadi::Item::Flags &flags); /** * Moves this maildir into @p destination. */ - bool moveTo( const Maildir &destination ); + bool moveTo(const Maildir &destination); /** * Renames this maildir to @p newName. */ - bool rename( const QString &newName ); + bool rename(const QString &newName); /** * Moves the file with the given @p key into the Maildir @p destination. * @returns The new file name inside @p destination. */ - QString moveEntryTo( const QString& key, const KPIM::Maildir& destination ); + QString moveEntryTo(const QString &key, const KPIM::Maildir &destination); /** * Creates the maildir tree structure specific directory path that the @@ -225,7 +225,7 @@ * * @see subDirNameForFolderName() */ - static QString subDirPathForFolderPath( const QString &folderPath ); + static QString subDirPathForFolderPath(const QString &folderPath); /** * Creates the maildir tree structure specific directory name that the @@ -235,11 +235,10 @@ * * @see subDirPathForFolderPath() */ - static QString subDirNameForFolderName( const QString &folderName ); + static QString subDirNameForFolderName(const QString &folderName); /** Removes the listed keys from the key cache */ - void removeCachedKeys(const QStringList & keys); - + void removeCachedKeys(const QStringList &keys); /** Reloads the keys associated with the maildir in the key cache*/ void refreshKeyCache(); @@ -250,7 +249,7 @@ QString lastError() const; private: - void swap( const Maildir& ); + void swap(const Maildir &); class Private; Private *d; }; diff -Nru kdepim-runtime-4.14.6/resources/maildir/libmaildir/tests/CMakeLists.txt kdepim-runtime-15.08.0/resources/maildir/libmaildir/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/maildir/libmaildir/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/libmaildir/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) - -include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. ) - -########### next target ############### - -set(testmaildir_SRCS testmaildir.cpp ) - - -kde4_add_unit_test(testmaildir TESTNAME maildir-testmaildir ${testmaildir_SRCS}) - -target_link_libraries(testmaildir ${KDE4_KDECORE_LIBS} ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDEPIMLIBS_AKONADI_KMIME_LIBS} maildir) - diff -Nru kdepim-runtime-4.14.6/resources/maildir/libmaildir/tests/testmaildir.cpp kdepim-runtime-15.08.0/resources/maildir/libmaildir/tests/testmaildir.cpp --- kdepim-runtime-4.14.6/resources/maildir/libmaildir/tests/testmaildir.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/libmaildir/tests/testmaildir.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,435 +0,0 @@ -/* - This file is part of the kpimutils library. - - Copyright (C) 2007 Till Adam - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - 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 "testmaildir.h" - -#include - -#include -#include - -#include -#include -#include -#include - -QTEST_KDEMAIN( MaildirTest, NoGUI ) - -#include "../maildir.h" -using namespace KPIM; - -static const char * testDir = "libmaildir-unit-test"; -static const char * testString = "From: theDukeOfMonmouth@uk.gov\n \nTo: theDukeOfBuccleuch@uk.gov\n\ntest\n"; -static const char * testStringHeaders = "From: theDukeOfMonmouth@uk.gov\n \nTo: theDukeOfBuccleuch@uk.gov\n"; - -void MaildirTest::init() -{ - m_temp = new KTempDir( KStandardDirs::locateLocal( "tmp", QLatin1String( testDir ) ) ); - - QDir temp( m_temp->name() ); - QVERIFY( temp.exists() ); - - temp.mkdir( QLatin1String( "new" ) ); - QVERIFY( temp.exists( QLatin1String( "new" ) ) ); - temp.mkdir( QLatin1String( "cur" ) ); - QVERIFY( temp.exists( QLatin1String( "cur" ) ) ); - temp.mkdir( QLatin1String( "tmp" ) ); - QVERIFY( temp.exists( QLatin1String( "tmp" ) ) ); -} - -void MaildirTest::cleanup() -{ - m_temp->unlink(); - QDir d( m_temp->name() ); - const QString subFolderPath( QString::fromLatin1( ".%1.directory" ).arg( d.dirName() ) ); - KTempDir::removeDir(subFolderPath); - - delete m_temp; - m_temp = 0; -} - -void MaildirTest::fillDirectory(const QString& name, int limit ) -{ - QFile file; - QDir::setCurrent( m_temp->name() + QLatin1Char( '/' ) + name ); - for ( int i=0; iname() ); - const QString subFolderPath( QString::fromLatin1( ".%1.directory" ).arg( d.dirName() ) ); - d.cdUp(); - d.mkdir( subFolderPath ); - d.cd( subFolderPath ); - d.mkdir( QLatin1String( "foo" ) ); - d.mkdir( QLatin1String( "barbar" ) ); - d.mkdir( QLatin1String( "bazbaz" ) ); -} - -void MaildirTest::fillNewDirectory() -{ - fillDirectory( QLatin1String( "new" ), 140 ); -} - -void MaildirTest::fillCurrentDirectory() -{ - fillDirectory( QLatin1String( "cur" ), 20 ); -} - - -void MaildirTest::testMaildirInstantiation() -{ - Maildir d( QLatin1String( "/foo/bar/Mail" ) ); - Maildir d2( d ); - Maildir d3; - d3 = d; - QVERIFY( d == d2 ); - QVERIFY( d3 == d2 ); - QVERIFY( d == d3 ); - QCOMPARE( d.path(), QString( QLatin1String( "/foo/bar/Mail" ) ) ); - QCOMPARE( d.name(), QString( QLatin1String( "Mail" ) ) ); - - QVERIFY( !d.isValid() ); - - Maildir good( m_temp->name() ); - QVERIFY( good.isValid() ); - - QDir temp( m_temp->name() ); - temp.rmdir( QLatin1String( "new" ) ); - QVERIFY( !good.isValid( false ) ); - QVERIFY( !good.lastError().isEmpty() ); - - Maildir root1( QLatin1String( "/foo/bar/Mail" ), true ); - QVERIFY( root1.isRoot() ); - - Maildir root1Copy = root1; - QCOMPARE( root1Copy.path(), root1.path() ); - QCOMPARE( root1Copy.isRoot(), root1.isRoot() ); - - // FIXME test insufficient permissions? -} - -void MaildirTest::testMaildirListing() -{ - fillNewDirectory(); - - Maildir d( m_temp->name() ); - QStringList entries = d.entryList(); - - QCOMPARE( entries.count(), 140 ); - - fillCurrentDirectory(); - entries = d.entryList(); - QCOMPARE( entries.count(), 160 ); -} - -void MaildirTest::testMaildirAccess() -{ - fillCurrentDirectory(); - Maildir d( m_temp->name() ); - QStringList entries = d.entryList(); - QCOMPARE( entries.count(), 20 ); - - QByteArray data = d.readEntry( entries[0] ); - QVERIFY( !data.isEmpty() ); - QCOMPARE( data, QByteArray( testString ) ); -} - -void MaildirTest::testMaildirReadHeaders() -{ - fillCurrentDirectory(); - Maildir d( m_temp->name() ); - QStringList entries = d.entryList(); - QCOMPARE( entries.count(), 20 ); - - QByteArray data = d.readEntryHeaders( entries[0] ); - QVERIFY( !data.isEmpty() ); - QCOMPARE( data, QByteArray( testStringHeaders ) ); -} - -void MaildirTest::testMaildirWrite() -{ - fillCurrentDirectory(); - Maildir d( m_temp->name() ); - QStringList entries = d.entryList(); - QCOMPARE( entries.count(), 20 ); - - QByteArray data = d.readEntry( entries[0] ); - QByteArray data2 = "changed\n"; - QVERIFY( d.writeEntry( entries[0], data2 ) ); - QCOMPARE( data2, d.readEntry( entries[0] ) ); -} - -void MaildirTest::testMaildirAppend() -{ - Maildir d( m_temp->name() ); - QByteArray data = "newentry\n"; - QString key = d.addEntry( data ); - QVERIFY( !key.isEmpty() ); - QCOMPARE( data, d.readEntry( key ) ); -} - -void MaildirTest::testMaildirCreation() -{ - QString p( QLatin1String( "CREATETEST" ) ); - std::auto_ptr temp ( new KTempDir( KStandardDirs::locateLocal( "tmp", p ) ) ); - Maildir d( temp->name() + p ); - QVERIFY( !d.isValid( false ) ); - d.create(); - QVERIFY( d.isValid() ); -} - -void MaildirTest::testMaildirRemoveEntry() -{ - Maildir d( m_temp->name() ); - QByteArray data = "newentry\n"; - QString key = d.addEntry( data ); - QVERIFY( !key.isEmpty() ); - QCOMPARE( data, d.readEntry( key ) ); - QVERIFY( d.removeEntry( key ) ); - QVERIFY( d.readEntry( key ).isEmpty() ); -} - -void MaildirTest::testMaildirListSubfolders() -{ - fillNewDirectory(); - - Maildir d( m_temp->name() ); - QStringList entries = d.subFolderList(); - - QVERIFY( entries.isEmpty() ); - - createSubFolders(); - - entries = d.subFolderList(); - QVERIFY( !entries.isEmpty() ); - QCOMPARE( entries.count(), 3 ); -} - - -void MaildirTest::testMaildirCreateSubfolder() -{ - Maildir d( m_temp->name() ); - QStringList entries = d.subFolderList(); - QVERIFY( entries.isEmpty() ); - - d.addSubFolder( QLatin1String( "subFolderTest" ) ); - entries = d.subFolderList(); - QVERIFY( !entries.isEmpty() ); - QCOMPARE( entries.count(), 1 ); - Maildir child = d.subFolder( entries.first() ); - QVERIFY( child.isValid() ); -} - -void MaildirTest::testMaildirRemoveSubfolder() -{ - Maildir d( m_temp->name() ); - QVERIFY( d.isValid() ); - - QString folderPath = d.addSubFolder( QLatin1String( "subFolderTest" ) ); - QVERIFY( !folderPath.isEmpty() ); - QVERIFY( folderPath.endsWith( QLatin1String( ".directory/subFolderTest" ) ) ); - bool removingWorked = d.removeSubFolder( QLatin1String( "subFolderTest" ) ); - QVERIFY( removingWorked ); -} - -void MaildirTest::testMaildirRename() -{ - Maildir d( m_temp->name() ); - QVERIFY( d.isValid() ); - - QString folderPath = d.addSubFolder( QLatin1String( "rename me!" ) ); - QVERIFY( !folderPath.isEmpty() ); - - Maildir d2( folderPath ); - QVERIFY( d2.isValid() ); - QVERIFY( d2.rename( QLatin1String( "renamed" ) ) ); - QCOMPARE( d2.name(), QString( QLatin1String( "renamed" ) ) ); - - // same again, should not fail - QVERIFY( d2.rename( QLatin1String( "renamed" ) ) ); - QCOMPARE( d2.name(), QString( QLatin1String( "renamed" ) ) ); - - // already existing name - QVERIFY( !d.addSubFolder( QLatin1String( "this name is already taken" ) ).isEmpty() ); - QVERIFY( !d2.rename( QLatin1String( "this name is already taken" ) ) ); -} - -void MaildirTest::testMaildirMoveTo() -{ - Maildir d( m_temp->name() ); - QVERIFY( d.isValid() ); - - QString folderPath1 = d.addSubFolder( QLatin1String( "child1" ) ); - QVERIFY( !folderPath1.isEmpty() ); - - Maildir d2( folderPath1 ); - QVERIFY( d2.isValid() ); - - QDir d2Dir( d2.path() ); - QVERIFY( d2Dir.exists() ); - - QString folderPath11 = d2.addSubFolder( QLatin1String( "grandchild1" ) ); - - Maildir d21( folderPath11 ); - QVERIFY( d21.isValid() ); - - QDir d2SubDir( Maildir::subDirPathForFolderPath( d2.path() ) ); - QVERIFY( d2SubDir.exists() ); - - QString folderPath2 = d.addSubFolder( QLatin1String( "child2" ) ); - QVERIFY( !folderPath2.isEmpty() ); - - Maildir d3( folderPath2 ); - QVERIFY( d3.isValid() ); - - // move child1 to child2 - QVERIFY( d2.moveTo( d3 ) ); - - Maildir d31 = d3.subFolder( QLatin1String( "child1" ) ); - QVERIFY( d31.isValid() ); - - QVERIFY( !d2Dir.exists() ); - QVERIFY( !d2SubDir.exists() ); - - QDir d31Dir( d31.path() ); - QVERIFY( d31Dir.exists() ); - - QDir d31SubDir( Maildir::subDirPathForFolderPath( d31.path() ) ); - QVERIFY( d31SubDir.exists() ); - - Maildir d311 = d31.subFolder( QLatin1String( "grandchild1" ) ); - QVERIFY( d311.isValid() ); - - // try moving again - d2 = Maildir( folderPath1 ); - QVERIFY( !d2.isValid( false ) ); - QVERIFY( !d2.moveTo( d3 ) ); -} - -void MaildirTest::testMaildirFlagsReading() -{ - QFile file; - const QStringList markers = QStringList() << "P" << "R" << "S" << "F" << "FPRS"; - QDir::setCurrent( m_temp->name() + QLatin1Char( '/' ) + "cur" ); - for ( int i=0; i<6 ; i++) { - QString fileName = QLatin1String( "testmail-" ) + QString::number( i ); - if ( i < 5 ) { - fileName += - #ifdef Q_OS_WIN - "!2," - #else - ":2," - #endif - + markers[i]; - } - file.setFileName( fileName ); - file.open( QIODevice::WriteOnly ); - file.write( testString ); - file.flush(); - file.close(); - } - - Maildir d( m_temp->name() ); - QStringList entries = d.entryList(); - // Maildir::entryList() doesn't sort for performance reasons, - // do it here to make test sequence reliable. - entries.sort(); - - QCOMPARE( entries.count(), 6 ); - - Akonadi::Item::Flags flags = d.readEntryFlags( entries[0] ); - QCOMPARE( flags.count(), 1 ); - QVERIFY( flags.contains( Akonadi::MessageFlags::Forwarded ) ); - - flags = d.readEntryFlags( entries[1] ); - QCOMPARE( flags.count(), 1 ); - QVERIFY( flags.contains( Akonadi::MessageFlags::Replied ) ); - - flags = d.readEntryFlags( entries[2] ); - QCOMPARE( flags.count(), 1 ); - QVERIFY( flags.contains( Akonadi::MessageFlags::Seen ) ); - - flags = d.readEntryFlags( entries[3] ); - QCOMPARE( flags.count(), 1 ); - QVERIFY( flags.contains( Akonadi::MessageFlags::Flagged ) ); - - flags = d.readEntryFlags( entries[4] ); - QCOMPARE( flags.count(), 4 ); - QVERIFY( flags.contains( Akonadi::MessageFlags::Forwarded ) ); - QVERIFY( flags.contains( Akonadi::MessageFlags::Replied ) ); - QVERIFY( flags.contains( Akonadi::MessageFlags::Seen ) ); - QVERIFY( flags.contains( Akonadi::MessageFlags::Flagged ) ); - - flags = d.readEntryFlags( entries[5] ); - QVERIFY( flags.isEmpty() ); -} - -void MaildirTest::testMaildirFlagsWriting_data() -{ - QTest::addColumn( "origDir" ); - QTest::addColumn( "origFileName" ); - QTest::newRow( "cur/" ) << "cur" << "testmail"; - QTest::newRow( "cur/S" ) << "cur" << "testmail:2,S"; // wrongly marked as "seen" on disk (#289428) - QTest::newRow( "new/" ) << "new" << "testmail"; - QTest::newRow( "new/S" ) << "new" << "testmail:2,S"; -} - -void MaildirTest::testMaildirFlagsWriting() -{ - QFETCH( QString, origDir ); - QFETCH( QString, origFileName ); - - // create an initialy new mail - QFile file; - QDir::setCurrent( m_temp->name() ); - file.setFileName( origDir + '/' + origFileName ); - file.open( QIODevice::WriteOnly ); - file.write( testString ); - file.flush(); - file.close(); - - // add a single flag - Maildir d( m_temp->name() ); - const QStringList entries = d.entryList(); - QCOMPARE( entries.size(), 1 ); - QVERIFY( QFile::exists( origDir + '/' + entries[0] ) ); - const QString newKey = d.changeEntryFlags( entries[0], Akonadi::Item::Flags() << Akonadi::MessageFlags::Seen ); - // make sure the new key exists - QCOMPARE( newKey, d.entryList()[0] ); - QVERIFY( QFile::exists( "cur/" + newKey ) ); - // and it's the right file - QCOMPARE( d.readEntry( newKey ), QByteArray( testString ) ); - // now check the file name - QVERIFY( newKey.endsWith( QLatin1String( "2,S" ) ) ); - // and more flags - const QString newKey2 = d.changeEntryFlags( newKey, Akonadi::Item::Flags() << Akonadi::MessageFlags::Seen << Akonadi::MessageFlags::Replied ); - // check the file name, and the sorting of markers - QVERIFY( newKey2.endsWith( QLatin1String( "2,RS" ) ) ); - QVERIFY( QFile::exists( "cur/" + newKey2 ) ); -} diff -Nru kdepim-runtime-4.14.6/resources/maildir/libmaildir/tests/testmaildir.h kdepim-runtime-15.08.0/resources/maildir/libmaildir/tests/testmaildir.h --- kdepim-runtime-4.14.6/resources/maildir/libmaildir/tests/testmaildir.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/libmaildir/tests/testmaildir.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -/* - This file is part of the kpimutils library. - - Copyright (c) 2007 Till Adam - - 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 MAILDIRTEST_H -#define MAILDIRTEST_H - -#include - -class KTempDir; - -class MaildirTest : public QObject -{ - Q_OBJECT - private Q_SLOTS: - void init(); - void testMaildirInstantiation(); - void testMaildirCreation(); - void testMaildirListing(); - void testMaildirAccess(); - void testMaildirReadHeaders(); - void testMaildirWrite(); - void testMaildirAppend(); - void testMaildirRemoveEntry(); - void testMaildirListSubfolders(); - void testMaildirCreateSubfolder(); - void testMaildirRemoveSubfolder(); - void testMaildirRename(); - void testMaildirMoveTo(); - void testMaildirFlagsReading(); - void testMaildirFlagsWriting_data(); - void testMaildirFlagsWriting(); - void cleanup(); -private: - void fillDirectory(const QString &name, int limit ); - void fillNewDirectory(); - void fillCurrentDirectory(); - void createSubFolders(); - KTempDir *m_temp; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/maildir/maildirresource.cpp kdepim-runtime-15.08.0/resources/maildir/maildirresource.cpp --- kdepim-runtime-4.14.6/resources/maildir/maildirresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/maildirresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,28 +26,25 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include "maildirresource_debug.h" #include -#include -#include -#include +#include #include #include "libmaildir/maildir.h" -#include +#include using namespace Akonadi; using KPIM::Maildir; @@ -55,196 +52,198 @@ #define CLEANER_TIMEOUT 2*6000 -Maildir MaildirResource::maildirForCollection( const Collection& col ) +Maildir MaildirResource::maildirForCollection(const Collection &col) { - const QString path = maildirPathForCollection( col ); - if ( mMaildirsForCollection.contains( path ) ) { - return mMaildirsForCollection.value( path ); - } - - if ( col.remoteId().isEmpty() ) { - kWarning() << "Got incomplete ancestor chain:" << col; - return Maildir(); - } - - if ( col.parentCollection() == Collection::root() ) { - kWarning( col.remoteId() != mSettings->path() ) << "RID mismatch, is " << col.remoteId() << " expected " << mSettings->path(); - Maildir maildir( col.remoteId(), mSettings->topLevelIsContainer() ); - mMaildirsForCollection.insert( path, maildir ); + const QString path = maildirPathForCollection(col); + if (mMaildirsForCollection.contains(path)) { + return mMaildirsForCollection.value(path); + } + + if (col.remoteId().isEmpty()) { + qCWarning(MAILDIRRESOURCE_LOG) << "Got incomplete ancestor chain:" << col; + return Maildir(); + } + + if (col.parentCollection() == Collection::root()) { + if (col.remoteId() != mSettings->path()) { + qCWarning(MAILDIRRESOURCE_LOG) << "RID mismatch, is " << col.remoteId() << " expected " << mSettings->path(); + } + Maildir maildir(col.remoteId(), mSettings->topLevelIsContainer()); + mMaildirsForCollection.insert(path, maildir); + return maildir; + } + Maildir parentMd = maildirForCollection(col.parentCollection()); + Maildir maildir = parentMd.subFolder(col.remoteId()); + mMaildirsForCollection.insert(path, maildir); return maildir; - } - Maildir parentMd = maildirForCollection( col.parentCollection() ); - Maildir maildir = parentMd.subFolder( col.remoteId() ); - mMaildirsForCollection.insert( path, maildir ); - return maildir; -} - -Collection MaildirResource::collectionForMaildir(const Maildir& md) const -{ - if ( !md.isValid() ) - return Collection(); - - Collection col; - if ( md.path() == mSettings->path() ) { - col.setRemoteId( md.path() ); - col.setParentCollection( Collection::root() ); - } else { - const Collection parent = collectionForMaildir( md.parent() ); - col.setRemoteId( md.name() ); - col.setParentCollection( parent ); - } - - return col; -} - -MaildirResource::MaildirResource( const QString &id ) - :ResourceBase( id ), - mSettings( new MaildirSettings( componentData().config() ) ), - mFsWatcher( new KDirWatch( this ) ) -{ - // we cannot be sure that a config file is existing - // the MaildirResource will always be build - // look for a resource of this name - QString configFile = componentData().dirs()->findResource( "config", id + "rc" ); - // if not present, create it - if ( configFile.isEmpty() ) { - // check if the resource was used before - CollectionFetchJob *job = new CollectionFetchJob( Collection::root(), Akonadi::CollectionFetchJob::FirstLevel, this ); - job->fetchScope().setResource( id ); - connect( job, SIGNAL(result(KJob*)), SLOT(attemptConfigRestoring(KJob*)) ); - job->start(); - } - new MaildirSettingsAdaptor( mSettings ); - DBusConnectionPool::threadConnection().registerObject( QLatin1String( "/Settings" ), - mSettings, QDBusConnection::ExportAdaptors ); - connect( this, SIGNAL(reloadConfiguration()), SLOT(configurationChanged()) ); - - // We need to enable this here, otherwise we neither get the remote ID of the - // parent collection when a collection changes, nor the full item when an item - // is added. - changeRecorder()->fetchCollection( true ); - changeRecorder()->itemFetchScope().fetchFullPayload( true ); - changeRecorder()->itemFetchScope().setAncestorRetrieval( ItemFetchScope::All ); - changeRecorder()->itemFetchScope().setFetchModificationTime( false ); - changeRecorder()->collectionFetchScope().setAncestorRetrieval( CollectionFetchScope::All ); - changeRecorder()->fetchChangedOnly( true ); - - setHierarchicalRemoteIdentifiersEnabled( true ); - - ItemFetchScope scope( changeRecorder()->itemFetchScope() ); - scope.fetchFullPayload( false ); - scope.fetchPayloadPart( MessagePart::Header ); - scope.setAncestorRetrieval( ItemFetchScope::None ); - setItemSynchronizationFetchScope( scope ); - - connect( mFsWatcher, SIGNAL(dirty(QString)), SLOT(slotDirChanged(QString)) ); - if (!ensureSaneConfiguration()) { - emit error( i18n( "Unusable configuration." ) ); - } else { - synchronizeCollectionTree(); - } - - mChangedCleanerTimer = new QTimer( this ); - connect( mChangedCleanerTimer, SIGNAL(timeout()), this, SLOT(changedCleaner()) ); -} - -void MaildirResource::attemptConfigRestoring( KJob * job ) -{ - if ( job->error() ) { - kDebug() << job->errorString(); - return; - } - // we cannot be sure that a config file is existing - const QString id = identifier(); - const QString configFile = componentData().dirs()->findResource( "config", id + "rc" ); - // we test it again, to be sure - if ( configFile.isEmpty() ) { - // it is still empty, create it - kWarning() << "the resource is not properly configured:"; - kWarning() << "there is no config file for the resource."; - kWarning() << "we create a new one."; - const Collection::List cols = qobject_cast( job )->collections(); - QString path; - if ( !cols.isEmpty() ) { - kDebug() << "the collections list is not empty"; - Collection col = cols.first(); - // get the path of the collection - path = col.remoteId(); - } - // test the path - if ( path.isEmpty() ) { - kDebug() << "build a new path"; - const QString dataDir = componentData().dirs()->localxdgdatadir(); - // we use "id" to get an unique path - path = dataDir; - if (!defaultResourceType().isEmpty()) { - path += defaultResourceType() + QLatin1Char('/'); - } - path += id; - kDebug() << "set the path" << path; - mSettings->setPath( path ); - // set the resource into container mode for its top level - mSettings->setTopLevelIsContainer( true ); +} + +Collection MaildirResource::collectionForMaildir(const Maildir &md) const +{ + if (!md.isValid()) { + return Collection(); + } + + Collection col; + if (md.path() == mSettings->path()) { + col.setRemoteId(md.path()); + col.setParentCollection(Collection::root()); + } else { + const Collection parent = collectionForMaildir(md.parent()); + col.setRemoteId(md.name()); + col.setParentCollection(parent); + } + + return col; +} + +MaildirResource::MaildirResource(const QString &id) + : ResourceBase(id), + mSettings(new MaildirSettings(componentData().config())), + mFsWatcher(new KDirWatch(this)) +{ + // we cannot be sure that a config file is existing + // the MaildirResource will always be build + // look for a resource of this name + QString configFile = QStandardPaths::locate(QStandardPaths::ConfigLocation, id + "rc"); + // if not present, create it + if (configFile.isEmpty()) { + // check if the resource was used before + CollectionFetchJob *job = new CollectionFetchJob(Collection::root(), Akonadi::CollectionFetchJob::FirstLevel, this); + job->fetchScope().setResource(id); + connect(job, &CollectionFetchJob::result, this, &MaildirResource::attemptConfigRestoring); + job->start(); + } + new MaildirSettingsAdaptor(mSettings); + KDBusConnectionPool::threadConnection().registerObject(QStringLiteral("/Settings"), + mSettings, QDBusConnection::ExportAdaptors); + connect(this, &MaildirResource::reloadConfiguration, this, &MaildirResource::configurationChanged); + + // We need to enable this here, otherwise we neither get the remote ID of the + // parent collection when a collection changes, nor the full item when an item + // is added. + changeRecorder()->fetchCollection(true); + changeRecorder()->itemFetchScope().fetchFullPayload(true); + changeRecorder()->itemFetchScope().setAncestorRetrieval(ItemFetchScope::All); + changeRecorder()->itemFetchScope().setFetchModificationTime(false); + changeRecorder()->collectionFetchScope().setAncestorRetrieval(CollectionFetchScope::All); + changeRecorder()->fetchChangedOnly(true); + + setHierarchicalRemoteIdentifiersEnabled(true); + + ItemFetchScope scope(changeRecorder()->itemFetchScope()); + scope.fetchFullPayload(false); + scope.fetchPayloadPart(MessagePart::Header); + scope.setAncestorRetrieval(ItemFetchScope::None); + setItemSynchronizationFetchScope(scope); + + connect(mFsWatcher, &KDirWatch::dirty, this, &MaildirResource::slotDirChanged); + if (!ensureSaneConfiguration()) { + Q_EMIT error(i18n("Unusable configuration.")); } else { - // check how the directory looks like the actual check is missing. - Maildir root( mSettings->path(), true ); - mSettings->setTopLevelIsContainer( root.isValid() ); + synchronizeCollectionTree(); + } + + mChangedCleanerTimer = new QTimer(this); + connect(mChangedCleanerTimer, &QTimer::timeout, this, &MaildirResource::changedCleaner); +} + +void MaildirResource::attemptConfigRestoring(KJob *job) +{ + if (job->error()) { + qCDebug(MAILDIRRESOURCE_LOG) << job->errorString(); + return; + } + // we cannot be sure that a config file is existing + const QString id = identifier(); + const QString configFile = QStandardPaths::locate(QStandardPaths::ConfigLocation, id + "rc"); + // we test it again, to be sure + if (configFile.isEmpty()) { + // it is still empty, create it + qCWarning(MAILDIRRESOURCE_LOG) << "the resource is not properly configured:"; + qCWarning(MAILDIRRESOURCE_LOG) << "there is no config file for the resource."; + qCWarning(MAILDIRRESOURCE_LOG) << "we create a new one."; + const Collection::List cols = qobject_cast(job)->collections(); + QString path; + if (!cols.isEmpty()) { + qCDebug(MAILDIRRESOURCE_LOG) << "the collections list is not empty"; + Collection col = cols.first(); + // get the path of the collection + path = col.remoteId(); + } + // test the path + if (path.isEmpty()) { + qCDebug(MAILDIRRESOURCE_LOG) << "build a new path"; + const QString dataDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/'); + // we use "id" to get an unique path + path = dataDir; + if (!defaultResourceType().isEmpty()) { + path += defaultResourceType() + QLatin1Char('/'); + } + path += id; + qCDebug(MAILDIRRESOURCE_LOG) << "set the path" << path; + mSettings->setPath(path); + // set the resource into container mode for its top level + mSettings->setTopLevelIsContainer(true); + } else { + // check how the directory looks like the actual check is missing. + Maildir root(mSettings->path(), true); + mSettings->setTopLevelIsContainer(root.isValid()); + } + qCDebug(MAILDIRRESOURCE_LOG) << "synchronize"; + configurationChanged(); } - kDebug() << "synchronize"; - configurationChanged(); - } } MaildirResource::~ MaildirResource() { - delete mSettings; + delete mSettings; } -bool MaildirResource::retrieveItem( const Akonadi::Item &item, const QSet &parts ) +bool MaildirResource::retrieveItem(const Akonadi::Item &item, const QSet &parts) { - Q_UNUSED( parts ); + Q_UNUSED(parts); + + const Maildir md = maildirForCollection(item.parentCollection()); + if (!md.isValid()) { + cancelTask(i18n("Unable to fetch item: The maildir folder \"%1\" is not valid.", + md.path())); + return false; + } - const Maildir md = maildirForCollection( item.parentCollection() ); - if ( !md.isValid() ) { - cancelTask( i18n( "Unable to fetch item: The maildir folder \"%1\" is not valid.", - md.path() ) ); - return false; - } - - const QByteArray data = md.readEntry( item.remoteId() ); - KMime::Message *mail = new KMime::Message(); - mail->setContent( KMime::CRLFtoLF( data ) ); - mail->parse(); - - Item i( item ); - i.setPayload( KMime::Message::Ptr( mail ) ); - Akonadi::MessageFlags::copyMessageFlags(*mail, i); - itemRetrieved( i ); - return true; + const QByteArray data = md.readEntry(item.remoteId()); + KMime::Message *mail = new KMime::Message(); + mail->setContent(KMime::CRLFtoLF(data)); + mail->parse(); + + Item i(item); + i.setPayload(KMime::Message::Ptr(mail)); + Akonadi::MessageFlags::copyMessageFlags(*mail, i); + itemRetrieved(i); + return true; } QString MaildirResource::itemMimeType() const { - return KMime::Message::mimeType(); + return KMime::Message::mimeType(); } void MaildirResource::configurationChanged() { - mSettings->writeConfig(); - bool configValid = ensureSaneConfiguration(); - configValid &= ensureDirExists(); - if ( configValid ) { - emit status( Idle ); - setOnline( true ); - } + mSettings->save(); + bool configValid = ensureSaneConfiguration(); + configValid &= ensureDirExists(); + if (configValid) { + Q_EMIT status(Idle); + setOnline(true); + } } - void MaildirResource::aboutToQuit() { - // The settings may not have been saved if e.g. they have been modified via - // DBus instead of the config dialog. - mSettings->writeConfig(); + // The settings may not have been saved if e.g. they have been modified via + // DBus instead of the config dialog. + mSettings->save(); } QString MaildirResource::defaultResourceType() @@ -252,630 +251,638 @@ return QString(); } -void MaildirResource::configure( WId windowId ) +void MaildirResource::configure(WId windowId) { - ConfigDialog dlg( mSettings, identifier() ); - if ( windowId ) - KWindowSystem::setMainWindow( &dlg, windowId ); - dlg.setWindowIcon( KIcon( QLatin1String("message-rfc822") ) ); - if ( dlg.exec() ) { - // if we have no name, or the default one, - // better use the name of the top level collection - // that looks nicer - if ( name().isEmpty() || name() == identifier() ) { - Maildir md( mSettings->path() ); - setName( md.name() ); - } - emit configurationDialogAccepted(); - } else { - emit configurationDialogRejected(); - } - - configurationChanged(); - synchronizeCollectionTree(); -} - -void MaildirResource::itemAdded( const Akonadi::Item & item, const Akonadi::Collection& collection ) -{ - if ( !ensureSaneConfiguration() ) { - cancelTask( i18n( "Unusable configuration." ) ); - return; - } - Maildir dir = maildirForCollection( collection ); - if ( mSettings->readOnly() || !dir.isValid() ) { - cancelTask( dir.lastError() ); - return; + ConfigDialog dlg(mSettings, identifier()); + if (windowId) { + KWindowSystem::setMainWindow(&dlg, windowId); + } + dlg.setWindowIcon(QIcon::fromTheme(QStringLiteral("message-rfc822"))); + if (dlg.exec()) { + // if we have no name, or the default one, + // better use the name of the top level collection + // that looks nicer + if (name().isEmpty() || name() == identifier()) { + Maildir md(mSettings->path()); + setName(md.name()); + } + Q_EMIT configurationDialogAccepted(); + } else { + Q_EMIT configurationDialogRejected(); + } + + configurationChanged(); + synchronizeCollectionTree(); +} + +void MaildirResource::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) +{ + if (!ensureSaneConfiguration()) { + cancelTask(i18n("Unusable configuration.")); + return; + } + Maildir dir = maildirForCollection(collection); + if (mSettings->readOnly() || !dir.isValid()) { + cancelTask(dir.lastError()); + return; } // we can only deal with mail - if ( !item.hasPayload() ) { - cancelTask( i18n( "Error: Unsupported type." ) ); - return; + if (!item.hasPayload()) { + cancelTask(i18n("Error: Unsupported type.")); + return; } const KMime::Message::Ptr mail = item.payload(); - stopMaildirScan( dir ); - - const QString rid = dir.addEntry( mail->encodedContent() ); - mChangedFiles.insert( rid ); - mChangedCleanerTimer->start( CLEANER_TIMEOUT ); + stopMaildirScan(dir); - if ( rid.isEmpty() ) { - restartMaildirScan( dir ); - cancelTask( dir.lastError() ); - return; + const QString rid = dir.addEntry(mail->encodedContent()); + mChangedFiles.insert(rid); + mChangedCleanerTimer->start(CLEANER_TIMEOUT); + + if (rid.isEmpty()) { + restartMaildirScan(dir); + cancelTask(dir.lastError()); + return; } - restartMaildirScan( dir ); + restartMaildirScan(dir); - Item i( item ); - i.setRemoteId( rid ); - changeCommitted( i ); + Item i(item); + i.setRemoteId(rid); + changeCommitted(i); } -void MaildirResource::itemChanged( const Akonadi::Item& item, const QSet& parts ) +void MaildirResource::itemChanged(const Akonadi::Item &item, const QSet &parts) { - if ( !ensureSaneConfiguration() ) { - cancelTask( i18n( "Unusable configuration." ) ); - return; + if (!ensureSaneConfiguration()) { + cancelTask(i18n("Unusable configuration.")); + return; } - bool bodyChanged = false; bool flagsChanged = false; bool headChanged = false; - Q_FOREACH ( const QByteArray &part, parts ) { - if ( part.startsWith( "PLD:RFC822" ) ) { - bodyChanged = true; - } else if ( part.startsWith( "PLD:HEAD" ) ) { - headChanged = true; - } - if ( part.contains( "FLAGS" ) ) { - flagsChanged = true; - } - } - - if ( mSettings->readOnly() || ( !bodyChanged && !flagsChanged && !headChanged ) ) { - changeProcessed(); - return; - } - - Maildir dir = maildirForCollection( item.parentCollection() ); - if ( !dir.isValid() ) { - cancelTask( dir.lastError() ); + Q_FOREACH (const QByteArray &part, parts) { + if (part.startsWith("PLD:RFC822")) { + bodyChanged = true; + } else if (part.startsWith("PLD:HEAD")) { + headChanged = true; + } + if (part.contains("FLAGS")) { + flagsChanged = true; + } + } + + if (mSettings->readOnly() || (!bodyChanged && !flagsChanged && !headChanged)) { + changeProcessed(); + return; + } + + Maildir dir = maildirForCollection(item.parentCollection()); + if (!dir.isValid()) { + cancelTask(dir.lastError()); return; } - Item newItem( item ); - - if ( flagsChanged || bodyChanged || headChanged ) { //something has changed that we can deal with - stopMaildirScan( dir ); - - if ( flagsChanged ) { //flags changed, store in file name and get back the new filename (id) - const QString newKey = dir.changeEntryFlags( item.remoteId(), item.flags() ); - if ( newKey.isEmpty() ) { - restartMaildirScan( dir ); - cancelTask( i18n( "Failed to change the flags for the mail. %1" ).arg( dir.lastError() ) ); - return; - } - newItem.setRemoteId( newKey ); - } - - if ( bodyChanged || headChanged ) { //head or body changed - // we can only deal with mail - if ( item.hasPayload() ) { - const KMime::Message::Ptr mail = item.payload(); - QByteArray data = mail->encodedContent(); - if ( headChanged && !bodyChanged ) { - //only the head has changed, get the current version of the mail - //replace the head and store the new mail in the file - const QByteArray currentData = dir.readEntry( newItem.remoteId() ); - if ( currentData.isEmpty() && !dir.lastError().isEmpty() ) { - restartMaildirScan( dir ); - cancelTask( dir.lastError() ); - return; + Item newItem(item); + + if (flagsChanged || bodyChanged || headChanged) { //something has changed that we can deal with + stopMaildirScan(dir); + + if (flagsChanged) { //flags changed, store in file name and get back the new filename (id) + const QString newKey = dir.changeEntryFlags(item.remoteId(), item.flags()); + if (newKey.isEmpty()) { + restartMaildirScan(dir); + cancelTask(i18n("Failed to change the flags for the mail. %1").arg(dir.lastError())); + return; } - const QByteArray newHead = mail->head(); - mail->setContent( currentData ); - mail->setHead( newHead ); - mail->parse(); - data = mail->encodedContent(); - } - if ( !dir.writeEntry( newItem.remoteId(), data ) ) { - restartMaildirScan( dir ); - cancelTask( dir.lastError() ); - return; - } - mChangedFiles.insert( newItem.remoteId() ); - mChangedCleanerTimer->start( CLEANER_TIMEOUT ); - } else { - restartMaildirScan( dir ); - cancelTask( i18n( "Maildir resource got a non-mail content!" ) ); - return; + newItem.setRemoteId(newKey); } - } - restartMaildirScan( dir ); + if (bodyChanged || headChanged) { //head or body changed + // we can only deal with mail + if (item.hasPayload()) { + const KMime::Message::Ptr mail = item.payload(); + QByteArray data = mail->encodedContent(); + if (headChanged && !bodyChanged) { + //only the head has changed, get the current version of the mail + //replace the head and store the new mail in the file + const QByteArray currentData = dir.readEntry(newItem.remoteId()); + if (currentData.isEmpty() && !dir.lastError().isEmpty()) { + restartMaildirScan(dir); + cancelTask(dir.lastError()); + return; + } + const QByteArray newHead = mail->head(); + mail->setContent(currentData); + mail->setHead(newHead); + mail->parse(); + data = mail->encodedContent(); + } + if (!dir.writeEntry(newItem.remoteId(), data)) { + restartMaildirScan(dir); + cancelTask(dir.lastError()); + return; + } + mChangedFiles.insert(newItem.remoteId()); + mChangedCleanerTimer->start(CLEANER_TIMEOUT); + } else { + restartMaildirScan(dir); + cancelTask(i18n("Maildir resource got a non-mail content.")); + return; + } + } + + restartMaildirScan(dir); - changeCommitted( newItem ); + changeCommitted(newItem); } else { - emit changeProcessed(); + Q_EMIT changeProcessed(); } } -void MaildirResource::itemMoved( const Item &item, const Collection &source, const Collection &destination ) +void MaildirResource::itemMoved(const Item &item, const Collection &source, const Collection &destination) { - if ( source == destination ) { // should not happen but would confuse Maildir::moveEntryTo - changeProcessed(); - return; - } + if (source == destination) { // should not happen but would confuse Maildir::moveEntryTo + changeProcessed(); + return; + } - if ( !ensureSaneConfiguration() ) { - cancelTask( i18n( "Unusable configuration." ) ); - return; - } + if (!ensureSaneConfiguration()) { + cancelTask(i18n("Unusable configuration.")); + return; + } - Maildir sourceDir = maildirForCollection( source ); - if ( !sourceDir.isValid() ) { - cancelTask( i18n( "Source folder is invalid: '%1'.", sourceDir.lastError() ) ); - return; - } + Maildir sourceDir = maildirForCollection(source); + if (!sourceDir.isValid()) { + cancelTask(i18n("Source folder is invalid: '%1'.", sourceDir.lastError())); + return; + } - Maildir destDir = maildirForCollection( destination ); - if ( !destDir.isValid() ) { - cancelTask( i18n( "Destination folder is invalid: '%1'.", destDir.lastError() ) ); - return; - } + Maildir destDir = maildirForCollection(destination); + if (!destDir.isValid()) { + cancelTask(i18n("Destination folder is invalid: '%1'.", destDir.lastError())); + return; + } - stopMaildirScan( sourceDir ); - stopMaildirScan( destDir ); + stopMaildirScan(sourceDir); + stopMaildirScan(destDir); - const QString newRid = sourceDir.moveEntryTo( item.remoteId(), destDir ); + const QString newRid = sourceDir.moveEntryTo(item.remoteId(), destDir); - mChangedFiles.insert( newRid ); - mChangedCleanerTimer->start( CLEANER_TIMEOUT ); + mChangedFiles.insert(newRid); + mChangedCleanerTimer->start(CLEANER_TIMEOUT); - restartMaildirScan( sourceDir ); - restartMaildirScan( destDir ); + restartMaildirScan(sourceDir); + restartMaildirScan(destDir); - if ( newRid.isEmpty() ) { - cancelTask( i18n( "Could not move message '%1' from '%2' to '%3'. The error was %4.", item.remoteId(), sourceDir.path(), destDir.path(), sourceDir.lastError() ) ); - return; - } + if (newRid.isEmpty()) { + cancelTask(i18n("Could not move message '%1' from '%2' to '%3'. The error was %4.", item.remoteId(), sourceDir.path(), destDir.path(), sourceDir.lastError())); + return; + } - Item i( item ); - i.setRemoteId( newRid ); - changeCommitted( i ); + Item i(item); + i.setRemoteId(newRid); + changeCommitted(i); } -void MaildirResource::itemRemoved(const Akonadi::Item & item) +void MaildirResource::itemRemoved(const Akonadi::Item &item) { - if ( !ensureSaneConfiguration() ) { - cancelTask( i18n( "Unusable configuration." ) ); - return; - } + if (!ensureSaneConfiguration()) { + cancelTask(i18n("Unusable configuration.")); + return; + } - if ( !mSettings->readOnly() ) { - Maildir dir = maildirForCollection( item.parentCollection() ); - // !dir.isValid() means that our parent folder has been deleted already, - // so we don't care at all as that one will be recursive anyway - stopMaildirScan( dir ); - if ( dir.isValid() && !dir.removeEntry( item.remoteId() ) ) { - emit error( i18n( "Failed to delete message: %1", item.remoteId() ) ); - } - restartMaildirScan( dir ); - } - kDebug() << "Item removed" << item.id() << " in collection :" << item.parentCollection().id(); - changeProcessed(); -} - -Collection::List MaildirResource::listRecursive( const Collection &root, const Maildir &dir ) -{ - if ( mSettings->monitorFilesystem() ) { - mFsWatcher->addDir( dir.path() + QDir::separator() + QLatin1String( "new" ) ); - mFsWatcher->addDir( dir.path() + QDir::separator() + QLatin1String( "cur" ) ); - mFsWatcher->addDir( dir.subDirPath() ); - if ( dir.isRoot() ) { - mFsWatcher->addDir( dir.path() ); - } - } - - Collection::List list; - const QStringList mimeTypes = QStringList() << itemMimeType() << Collection::mimeType(); - foreach ( const QString &sub, dir.subFolderList() ) { - Collection c; - c.setName( sub ); - c.setRemoteId( sub ); - c.setParentCollection( root ); - c.setContentMimeTypes( mimeTypes ); - - const Maildir md = maildirForCollection( c ); - if ( !md.isValid() ) - continue; - - list << c; - list += listRecursive( c, md ); - } - return list; + if (!mSettings->readOnly()) { + Maildir dir = maildirForCollection(item.parentCollection()); + // !dir.isValid() means that our parent folder has been deleted already, + // so we don't care at all as that one will be recursive anyway + stopMaildirScan(dir); + if (dir.isValid() && !dir.removeEntry(item.remoteId())) { + Q_EMIT error(i18n("Failed to delete message: %1", item.remoteId())); + } + restartMaildirScan(dir); + } + qCDebug(MAILDIRRESOURCE_LOG) << "Item removed" << item.id() << " in collection :" << item.parentCollection().id(); + changeProcessed(); } -void MaildirResource::retrieveCollections() +Collection::List MaildirResource::listRecursive(const Collection &root, const Maildir &dir) { - Maildir dir( mSettings->path(), mSettings->topLevelIsContainer() ); - if ( !dir.isValid() ) { - emit error( dir.lastError() ); - collectionsRetrieved( Collection::List() ); - return; - } - - Collection root; - root.setParentCollection( Collection::root() ); - root.setRemoteId( mSettings->path() ); - root.setName( name() ); - if ( mSettings->readOnly() ) { - root.setRights( Collection::ReadOnly ); - } else { - if ( mSettings->topLevelIsContainer() ) { - root.setRights( Collection::ReadOnly | Collection::CanCreateCollection ); - } else { - root.setRights( Collection::CanChangeItem | Collection::CanCreateItem | Collection::CanDeleteItem - | Collection::CanCreateCollection ); + if (mSettings->monitorFilesystem()) { + mFsWatcher->addDir(dir.path() + QDir::separator() + QLatin1String("new")); + mFsWatcher->addDir(dir.path() + QDir::separator() + QLatin1String("cur")); + mFsWatcher->addDir(dir.subDirPath()); + if (dir.isRoot()) { + mFsWatcher->addDir(dir.path()); + } } - } - - CachePolicy policy; - policy.setInheritFromParent( false ); - policy.setSyncOnDemand( true ); - policy.setLocalParts( QStringList() << MessagePart::Envelope ); - policy.setCacheTimeout( 1 ); - policy.setIntervalCheckTime( -1 ); - root.setCachePolicy( policy ); - - QStringList mimeTypes; - mimeTypes << Collection::mimeType(); - mimeTypes << itemMimeType(); - root.setContentMimeTypes( mimeTypes ); + Collection::List list; + const QStringList mimeTypes = QStringList() << itemMimeType() << Collection::mimeType(); + foreach (const QString &sub, dir.subFolderList()) { + Collection c; + c.setName(sub); + c.setRemoteId(sub); + c.setParentCollection(root); + c.setContentMimeTypes(mimeTypes); + + const Maildir md = maildirForCollection(c); + if (!md.isValid()) { + continue; + } - Collection::List list; - list << root; - list += listRecursive( root, dir ); - collectionsRetrieved( list ); + list << c; + list += listRecursive(c, md); + } + return list; } -void MaildirResource::retrieveItems( const Akonadi::Collection & col ) +void MaildirResource::retrieveCollections() { - const Maildir md = maildirForCollection( col ); - if ( !md.isValid() ) { - cancelTask( i18n( "Maildir '%1' for collection '%2' is invalid.", md.path(), col.remoteId() ) ); - return; - } + Maildir dir(mSettings->path(), mSettings->topLevelIsContainer()); + if (!dir.isValid()) { + Q_EMIT error(dir.lastError()); + collectionsRetrieved(Collection::List()); + return; + } - RetrieveItemsJob *job = new RetrieveItemsJob( col, md, this ); - job->setMimeType( itemMimeType() ); - connect( job, SIGNAL(result(KJob*)), SLOT(slotItemsRetrievalResult(KJob*)) ); + Collection root; + root.setParentCollection(Collection::root()); + root.setRemoteId(mSettings->path()); + root.setName(name()); + if (mSettings->readOnly()) { + root.setRights(Collection::ReadOnly); + } else { + if (mSettings->topLevelIsContainer()) { + root.setRights(Collection::ReadOnly | Collection::CanCreateCollection); + } else { + root.setRights(Collection::CanChangeItem | Collection::CanCreateItem | Collection::CanDeleteItem + | Collection::CanCreateCollection); + } + } + + CachePolicy policy; + policy.setInheritFromParent(false); + policy.setSyncOnDemand(true); + policy.setLocalParts(QStringList() << MessagePart::Envelope); + policy.setCacheTimeout(1); + policy.setIntervalCheckTime(-1); + root.setCachePolicy(policy); + + QStringList mimeTypes; + mimeTypes << Collection::mimeType(); + mimeTypes << itemMimeType(); + root.setContentMimeTypes(mimeTypes); + + Collection::List list; + list << root; + list += listRecursive(root, dir); + collectionsRetrieved(list); +} + +void MaildirResource::retrieveItems(const Akonadi::Collection &col) +{ + const Maildir md = maildirForCollection(col); + if (!md.isValid()) { + cancelTask(i18n("Maildir '%1' for collection '%2' is invalid.", md.path(), col.remoteId())); + return; + } + + RetrieveItemsJob *job = new RetrieveItemsJob(col, md, this); + job->setMimeType(itemMimeType()); + connect(job, &RetrieveItemsJob::result, this, &MaildirResource::slotItemsRetrievalResult); } -void MaildirResource::slotItemsRetrievalResult ( KJob* job ) +void MaildirResource::slotItemsRetrievalResult(KJob *job) { - if ( job->error() ) - cancelTask( job->errorString() ); - else - itemsRetrievalDone(); + if (job->error()) { + cancelTask(job->errorString()); + } else { + itemsRetrievalDone(); + } } -void MaildirResource::collectionAdded(const Collection & collection, const Collection &parent) +void MaildirResource::collectionAdded(const Collection &collection, const Collection &parent) { - if ( !ensureSaneConfiguration() ) { - emit error( i18n( "Unusable configuration." ) ); - changeProcessed(); - return; - } - - Maildir md = maildirForCollection( parent ); - kDebug( 5254 ) << md.subFolderList() << md.entryList(); - if ( mSettings->readOnly() || !md.isValid() ) { - changeProcessed(); - return; - } else { - const QString collectionName( collection.name().replace( QDir::separator(), QString() ) ); - const QString newFolderPath = md.addSubFolder( collectionName ); - if ( newFolderPath.isEmpty() ) { - changeProcessed(); - return; + if (!ensureSaneConfiguration()) { + Q_EMIT error(i18n("Unusable configuration.")); + changeProcessed(); + return; } - kDebug( 5254 ) << md.subFolderList() << md.entryList(); + Maildir md = maildirForCollection(parent); + qCDebug(MAILDIRRESOURCE_LOG) << md.subFolderList() << md.entryList(); + if (mSettings->readOnly() || !md.isValid()) { + changeProcessed(); + return; + } else { + const QString collectionName(collection.name().replace(QDir::separator(), QString())); + const QString newFolderPath = md.addSubFolder(collectionName); + if (newFolderPath.isEmpty()) { + changeProcessed(); + return; + } - Collection col = collection; - col.setRemoteId( collectionName ); - col.setName( collectionName ); - changeCommitted( col ); - } + qCDebug(MAILDIRRESOURCE_LOG) << md.subFolderList() << md.entryList(); + + Collection col = collection; + col.setRemoteId(collectionName); + col.setName(collectionName); + changeCommitted(col); + } } -void MaildirResource::collectionChanged(const Collection & collection) +void MaildirResource::collectionChanged(const Collection &collection) { - if ( !ensureSaneConfiguration() ) { - emit error( i18n( "Unusable configuration." ) ); - changeProcessed(); - return; - } + if (!ensureSaneConfiguration()) { + Q_EMIT error(i18n("Unusable configuration.")); + changeProcessed(); + return; + } - if ( collection.parentCollection() == Collection::root() ) { - if ( collection.name() != name() ) - setName( collection.name() ); - changeProcessed(); - return; - } + if (collection.parentCollection() == Collection::root()) { + if (collection.name() != name()) { + setName(collection.name()); + } + changeProcessed(); + return; + } - if ( collection.remoteId() == collection.name() ) { - changeProcessed(); - return; - } + if (collection.remoteId() == collection.name()) { + changeProcessed(); + return; + } - Maildir md = maildirForCollection( collection ); - if ( !md.isValid() ) { - assert( !collection.remoteId().isEmpty() ); // caught in resourcebase - // we don't have a maildir for this collection yet, probably due to a race - // make one, otherwise the rename below will fail - md.create(); - } - - const QString collectionName( collection.name().replace( QDir::separator(), QString() ) ); - if ( !md.rename( collectionName ) ) { - emit error( i18n( "Unable to rename maildir folder '%1'.", collection.name() ) ); - changeProcessed(); - return; - } - Collection c( collection ); - c.setRemoteId( collectionName ); - c.setName( collectionName ); - changeCommitted( c ); + Maildir md = maildirForCollection(collection); + if (!md.isValid()) { + assert(!collection.remoteId().isEmpty()); // caught in resourcebase + // we don't have a maildir for this collection yet, probably due to a race + // make one, otherwise the rename below will fail + md.create(); + } + + const QString collectionName(collection.name().replace(QDir::separator(), QString())); + if (!md.rename(collectionName)) { + Q_EMIT error(i18n("Unable to rename maildir folder '%1'.", collection.name())); + changeProcessed(); + return; + } + Collection c(collection); + c.setRemoteId(collectionName); + c.setName(collectionName); + changeCommitted(c); } -void MaildirResource::collectionMoved( const Collection &collection, const Collection &source, const Collection &dest ) +void MaildirResource::collectionMoved(const Collection &collection, const Collection &source, const Collection &dest) { - kDebug() << collection << source << dest; + qCDebug(MAILDIRRESOURCE_LOG) << collection << source << dest; - if ( !ensureSaneConfiguration() ) { - emit error( i18n( "Unusable configuration." ) ); - changeProcessed(); - return; - } + if (!ensureSaneConfiguration()) { + Q_EMIT error(i18n("Unusable configuration.")); + changeProcessed(); + return; + } - if ( collection.parentCollection() == Collection::root() ) { - emit error( i18n( "Cannot move root maildir folder '%1'." ,collection.remoteId() ) ); - changeProcessed(); - return; - } + if (collection.parentCollection() == Collection::root()) { + Q_EMIT error(i18n("Cannot move root maildir folder '%1'." , collection.remoteId())); + changeProcessed(); + return; + } - if ( source == dest ) { // should not happen, but who knows... - changeProcessed(); - return; - } + if (source == dest) { // should not happen, but who knows... + changeProcessed(); + return; + } - Collection c( collection ); - c.setParentCollection( source ); - Maildir md = maildirForCollection( c ); - Maildir destMd = maildirForCollection( dest ); - if ( !md.moveTo( destMd ) ) { - emit error( i18n( "Unable to move maildir folder '%1' from '%2' to '%3'.", collection.remoteId(), source.remoteId(), dest.remoteId() ) ); - changeProcessed(); - } else { - const QString path = maildirPathForCollection( c ); - mMaildirsForCollection.remove( path ); - changeCommitted( collection ); - } + Collection c(collection); + c.setParentCollection(source); + Maildir md = maildirForCollection(c); + Maildir destMd = maildirForCollection(dest); + if (!md.moveTo(destMd)) { + Q_EMIT error(i18n("Unable to move maildir folder '%1' from '%2' to '%3'.", collection.remoteId(), source.remoteId(), dest.remoteId())); + changeProcessed(); + } else { + const QString path = maildirPathForCollection(c); + mMaildirsForCollection.remove(path); + changeCommitted(collection); + } } -void MaildirResource::collectionRemoved( const Akonadi::Collection &collection ) +void MaildirResource::collectionRemoved(const Akonadi::Collection &collection) { - if ( !ensureSaneConfiguration() ) { - emit error( i18n( "Unusable configuration." ) ); - changeProcessed(); - return; - } + if (!ensureSaneConfiguration()) { + Q_EMIT error(i18n("Unusable configuration.")); + changeProcessed(); + return; + } - if ( collection.parentCollection() == Collection::root() ) { - emit error( i18n( "Cannot delete top-level maildir folder '%1'.", mSettings->path() ) ); - changeProcessed(); - return; - } + if (collection.parentCollection() == Collection::root()) { + Q_EMIT error(i18n("Cannot delete top-level maildir folder '%1'.", mSettings->path())); + changeProcessed(); + return; + } - Maildir md = maildirForCollection( collection.parentCollection() ); - // !md.isValid() means that our parent folder has been deleted already, - // so we don't care at all as that one will be recursive anyway - if ( md.isValid() && !md.removeSubFolder( collection.remoteId() ) ) { - emit error( i18n( "Failed to delete sub-folder '%1'.", collection.remoteId() ) ); - } + Maildir md = maildirForCollection(collection.parentCollection()); + // !md.isValid() means that our parent folder has been deleted already, + // so we don't care at all as that one will be recursive anyway + if (md.isValid() && !md.removeSubFolder(collection.remoteId())) { + Q_EMIT error(i18n("Failed to delete sub-folder '%1'.", collection.remoteId())); + } - const QString path = maildirPathForCollection( collection ); - mMaildirsForCollection.remove( path ); + const QString path = maildirPathForCollection(collection); + mMaildirsForCollection.remove(path); - changeProcessed(); + changeProcessed(); } bool MaildirResource::ensureDirExists() { - Maildir root( mSettings->path() ); - if ( !root.isValid( false ) && !mSettings->topLevelIsContainer() ) { - if ( !root.create() ) - emit status( Broken, i18n( "Unable to create maildir '%1'.", mSettings->path() ) ); - return false; - } - return true; + Maildir root(mSettings->path()); + if (!root.isValid(false) && !mSettings->topLevelIsContainer()) { + if (!root.create()) { + Q_EMIT status(Broken, i18n("Unable to create maildir '%1'.", mSettings->path())); + } + return false; + } + return true; } bool MaildirResource::ensureSaneConfiguration() { - if ( mSettings->path().isEmpty() ) { - emit status( NotConfigured, i18n( "No usable storage location configured." ) ); - setOnline( false ); - return false; - } - return true; + if (mSettings->path().isEmpty()) { + Q_EMIT status(NotConfigured, i18n("No usable storage location configured.")); + setOnline(false); + return false; + } + return true; } - -void MaildirResource::slotDirChanged(const QString& dir) +void MaildirResource::slotDirChanged(const QString &dir) { - QFileInfo fileInfo( dir ); - if ( fileInfo.isFile() ) { - slotFileChanged( fileInfo ); - return; - } + QFileInfo fileInfo(dir); + if (fileInfo.isFile()) { + slotFileChanged(fileInfo); + return; + } - if ( dir == mSettings->path() ) { - synchronizeCollectionTree(); - synchronizeCollection( Collection::root().id() ); - return; - } + if (dir == mSettings->path()) { + synchronizeCollectionTree(); + synchronizeCollection(Collection::root().id()); + return; + } - if ( dir.endsWith( QLatin1String( ".directory" ) ) ) { - synchronizeCollectionTree(); //might be too much, but this is not a common case anyway - return; - } + if (dir.endsWith(QLatin1String(".directory"))) { + synchronizeCollectionTree(); //might be too much, but this is not a common case anyway + return; + } - QDir d( dir ); - if ( !d.cdUp() ) - return; + QDir d(dir); + if (!d.cdUp()) { + return; + } - Maildir md( d.path() ); - if ( !md.isValid() ) - return; + Maildir md(d.path()); + if (!md.isValid()) { + return; + } - md.refreshKeyCache(); + md.refreshKeyCache(); - const Collection col = collectionForMaildir( md ); - if ( col.remoteId().isEmpty() ) { - kDebug() << "unable to find collection for path" << dir; - return; - } + const Collection col = collectionForMaildir(md); + if (col.remoteId().isEmpty()) { + qCDebug(MAILDIRRESOURCE_LOG) << "unable to find collection for path" << dir; + return; + } - CollectionFetchJob *job = new CollectionFetchJob( col, Akonadi::CollectionFetchJob::Base, this ); - connect( job, SIGNAL(result(KJob*)), SLOT(fsWatchDirFetchResult(KJob*)) ); + CollectionFetchJob *job = new CollectionFetchJob(col, Akonadi::CollectionFetchJob::Base, this); + connect(job, &CollectionFetchJob::result, this, &MaildirResource::fsWatchDirFetchResult); } -void MaildirResource::fsWatchDirFetchResult(KJob* job) +void MaildirResource::fsWatchDirFetchResult(KJob *job) { - if ( job->error() ) { - kDebug() << job->errorString(); - return; - } - const Collection::List cols = qobject_cast( job )->collections(); - if ( cols.isEmpty() ) - return; + if (job->error()) { + qCDebug(MAILDIRRESOURCE_LOG) << job->errorString(); + return; + } + const Collection::List cols = qobject_cast(job)->collections(); + if (cols.isEmpty()) { + return; + } - synchronizeCollection( cols.first().id() ); + synchronizeCollection(cols.first().id()); } -void MaildirResource::slotFileChanged( const QFileInfo& fileInfo ) +void MaildirResource::slotFileChanged(const QFileInfo &fileInfo) { - const QString key = fileInfo.fileName(); - if ( mChangedFiles.contains( key ) ) { - mChangedFiles.remove( key ); - return; - } + const QString key = fileInfo.fileName(); + if (mChangedFiles.contains(key)) { + mChangedFiles.remove(key); + return; + } - QString path = fileInfo.path(); - if ( path.endsWith( QLatin1String( "/new" ) ) ) { - path.remove( path.length() - 4, 4 ); - } else if ( path.endsWith( QLatin1String( "/cur" ) ) ) { - path.remove( path.length() - 4, 4 ); - } + QString path = fileInfo.path(); + if (path.endsWith(QLatin1String("/new"))) { + path.remove(path.length() - 4, 4); + } else if (path.endsWith(QLatin1String("/cur"))) { + path.remove(path.length() - 4, 4); + } - const Maildir md( path ); - if ( !md.isValid() ) - return; + const Maildir md(path); + if (!md.isValid()) { + return; + } - const Collection col = collectionForMaildir( md ); - if ( col.remoteId().isEmpty() ) { - kDebug() << "unable to find collection for path" << fileInfo.path(); - return; - } + const Collection col = collectionForMaildir(md); + if (col.remoteId().isEmpty()) { + qCDebug(MAILDIRRESOURCE_LOG) << "unable to find collection for path" << fileInfo.path(); + return; + } - Item item; - item.setRemoteId( key ); - item.setParentCollection( col ); + Item item; + item.setRemoteId(key); + item.setParentCollection(col); - ItemFetchJob *job = new ItemFetchJob( item, this ); - job->setProperty( "entry", key ); - job->setProperty( "dir", path ); - connect( job, SIGNAL(result(KJob*)), SLOT(fsWatchFileFetchResult(KJob*)) ); + ItemFetchJob *job = new ItemFetchJob(item, this); + job->setProperty("entry", key); + job->setProperty("dir", path); + connect(job, &ItemFetchJob::result, this, &MaildirResource::fsWatchFileFetchResult); } -void MaildirResource::fsWatchFileFetchResult( KJob* job ) +void MaildirResource::fsWatchFileFetchResult(KJob *job) { - if ( job->error() ) { - kDebug() << job->errorString(); - return; - } - Item::List items = qobject_cast( job )->items(); - if ( items.isEmpty() ) - return; + if (job->error()) { + qCDebug(MAILDIRRESOURCE_LOG) << job->errorString(); + return; + } + Item::List items = qobject_cast(job)->items(); + if (items.isEmpty()) { + return; + } - const QString fileName = job->property( "entry" ).toString(); - const QString path = job->property( "dir" ).toString(); + const QString fileName = job->property("entry").toString(); + const QString path = job->property("dir").toString(); - const Maildir md( path ); + const Maildir md(path); - QString entry = fileName; - Item item( items.at( 0 ) ); - const qint64 entrySize = md.size( entry ); - if ( entrySize >= 0 ) - item.setSize( entrySize ); + QString entry = fileName; + Item item(items.at(0)); + const qint64 entrySize = md.size(entry); + if (entrySize >= 0) { + item.setSize(entrySize); + } - Item::Flags flags = md.readEntryFlags( entry ); - Q_FOREACH ( const Item::Flag &flag, flags ) { - item.setFlag( flag ); - } + Item::Flags flags = md.readEntryFlags(entry); + Q_FOREACH (const Item::Flag &flag, flags) { + item.setFlag(flag); + } - const QByteArray data = md.readEntry( entry ); - KMime::Message *mail = new KMime::Message(); - mail->setContent( KMime::CRLFtoLF( data ) ); - mail->parse(); + const QByteArray data = md.readEntry(entry); + KMime::Message *mail = new KMime::Message(); + mail->setContent(KMime::CRLFtoLF(data)); + mail->parse(); - item.setPayload( KMime::Message::Ptr( mail ) ); - Akonadi::MessageFlags::copyMessageFlags(*mail, item); + item.setPayload(KMime::Message::Ptr(mail)); + Akonadi::MessageFlags::copyMessageFlags(*mail, item); - ItemModifyJob *mjob = new ItemModifyJob( item ); - connect( mjob, SIGNAL(result(KJob*)), SLOT(fsWatchFileModifyResult(KJob*)) ); + ItemModifyJob *mjob = new ItemModifyJob(item); + connect(mjob, &ItemModifyJob::result, this, &MaildirResource::fsWatchFileModifyResult); } -void MaildirResource::fsWatchFileModifyResult(KJob* job) +void MaildirResource::fsWatchFileModifyResult(KJob *job) { - if ( job->error() ) { - kDebug() << job->errorString(); - return; - } + if (job->error()) { + qCDebug(MAILDIRRESOURCE_LOG) << job->errorString(); + return; + } } -QString MaildirResource::maildirPathForCollection(const Collection& collection) const +QString MaildirResource::maildirPathForCollection(const Collection &collection) const { - QString path = collection.remoteId(); - Akonadi::Collection parent = collection.parentCollection(); - while ( !parent.remoteId().isEmpty() ) { - path.prepend( parent.remoteId() + QLatin1Char('/') ); - parent = parent.parentCollection(); - } + QString path = collection.remoteId(); + Akonadi::Collection parent = collection.parentCollection(); + while (!parent.remoteId().isEmpty()) { + path.prepend(parent.remoteId() + QLatin1Char('/')); + parent = parent.parentCollection(); + } - return path; + return path; } void MaildirResource::stopMaildirScan(const Maildir &maildir) { const QString path = maildir.path(); - mFsWatcher->stopDirScan( path + QLatin1Literal( "/new" ) ); - mFsWatcher->stopDirScan( path + QLatin1Literal( "/cur" ) ); + mFsWatcher->stopDirScan(path + QLatin1Literal("/new")); + mFsWatcher->stopDirScan(path + QLatin1Literal("/cur")); } void MaildirResource::restartMaildirScan(const Maildir &maildir) { const QString path = maildir.path(); - mFsWatcher->restartDirScan( path + QLatin1Literal( "/new" ) ); - mFsWatcher->restartDirScan( path + QLatin1Literal( "/cur" ) ); + mFsWatcher->restartDirScan(path + QLatin1Literal("/new")); + mFsWatcher->restartDirScan(path + QLatin1Literal("/cur")); } void MaildirResource::changedCleaner() diff -Nru kdepim-runtime-4.14.6/resources/maildir/maildirresource_debug.cpp kdepim-runtime-15.08.0/resources/maildir/maildirresource_debug.cpp --- kdepim-runtime-4.14.6/resources/maildir/maildirresource_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/maildirresource_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2015 Laurent Montel + + 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 "maildirresource_debug.h" +Q_LOGGING_CATEGORY(MAILDIRRESOURCE_LOG, "log_maildirresource") + diff -Nru kdepim-runtime-4.14.6/resources/maildir/maildirresource_debug.h kdepim-runtime-15.08.0/resources/maildir/maildirresource_debug.h --- kdepim-runtime-4.14.6/resources/maildir/maildirresource_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/maildirresource_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2015 Laurent Montel + + 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 MAILDIRRESOURCE_DEBUG_H +#define MAILDIRRESOURCE_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(MAILDIRRESOURCE_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/maildir/maildirresource.desktop kdepim-runtime-15.08.0/resources/maildir/maildirresource.desktop --- kdepim-runtime-4.14.6/resources/maildir/maildirresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/maildirresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -104,5 +104,4 @@ X-Akonadi-MimeTypes=message/rfc822 X-Akonadi-Capabilities=Resource X-Akonadi-Identifier=akonadi_maildir_resource -X-Akonadi-LaunchMethod=AgentServer X-Akonadi-Custom-HasLocalStorage=true diff -Nru kdepim-runtime-4.14.6/resources/maildir/maildirresource.h kdepim-runtime-15.08.0/resources/maildir/maildirresource.h --- kdepim-runtime-4.14.6/resources/maildir/maildirresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/maildirresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,8 +20,8 @@ #ifndef MAILDIR_RESOURCE_H #define MAILDIR_RESOURCE_H -#include -#include +#include +#include class QTimer; class QFileInfo; @@ -37,61 +37,61 @@ class MaildirResource : public Akonadi::ResourceBase, public Akonadi::AgentBase::ObserverV2 { - Q_OBJECT + Q_OBJECT - public: - MaildirResource( const QString &id ); +public: + MaildirResource(const QString &id); ~MaildirResource(); virtual QString defaultResourceType(); public Q_SLOTS: - virtual void configure( WId windowId ); + void configure(WId windowId) Q_DECL_OVERRIDE; - protected Q_SLOTS: - void retrieveCollections(); - void retrieveItems( const Akonadi::Collection &col ); - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); +protected Q_SLOTS: + void retrieveCollections() Q_DECL_OVERRIDE; + void retrieveItems(const Akonadi::Collection &col) Q_DECL_OVERRIDE; + bool retrieveItem(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; - protected: +protected: virtual QString itemMimeType() const; - virtual void aboutToQuit(); + void aboutToQuit() Q_DECL_OVERRIDE; - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); - virtual void itemMoved( const Akonadi::Item &item, const Akonadi::Collection &source, const Akonadi::Collection &dest ); - virtual void itemRemoved( const Akonadi::Item &item ); + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + void itemMoved(const Akonadi::Item &item, const Akonadi::Collection &source, const Akonadi::Collection &dest) Q_DECL_OVERRIDE; + void itemRemoved(const Akonadi::Item &item) Q_DECL_OVERRIDE; - virtual void collectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection &parent ); - virtual void collectionChanged( const Akonadi::Collection &collection ); + void collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent) Q_DECL_OVERRIDE; + void collectionChanged(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; // do not hide the other variant, use implementation from base class // which just forwards to the one above using Akonadi::AgentBase::ObserverV2::collectionChanged; - virtual void collectionMoved( const Akonadi::Collection &collection, const Akonadi::Collection &source, const Akonadi::Collection &dest ); - virtual void collectionRemoved( const Akonadi::Collection &collection ); + void collectionMoved(const Akonadi::Collection &collection, const Akonadi::Collection &source, const Akonadi::Collection &dest) Q_DECL_OVERRIDE; + void collectionRemoved(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; - private slots: +private Q_SLOTS: void configurationChanged(); - void slotItemsRetrievalResult(KJob* job); - void slotDirChanged( const QString &dir ); - void slotFileChanged( const QFileInfo &fileInfo ); - void fsWatchDirFetchResult( KJob* job ); - void fsWatchFileFetchResult( KJob* job ); - void fsWatchFileModifyResult( KJob* job ); + void slotItemsRetrievalResult(KJob *job); + void slotDirChanged(const QString &dir); + void slotFileChanged(const QFileInfo &fileInfo); + void fsWatchDirFetchResult(KJob *job); + void fsWatchFileFetchResult(KJob *job); + void fsWatchFileModifyResult(KJob *job); // Try to restore some config values from Akonadi data - void attemptConfigRestoring( KJob* job ); + void attemptConfigRestoring(KJob *job); void changedCleaner(); - private: +private: bool ensureDirExists(); bool ensureSaneConfiguration(); - Akonadi::Collection::List listRecursive( const Akonadi::Collection &root, const KPIM::Maildir &dir ); + Akonadi::Collection::List listRecursive(const Akonadi::Collection &root, const KPIM::Maildir &dir); /** Creates a maildir object for the collection @p col, given it has the full ancestor chain set. */ - KPIM::Maildir maildirForCollection( const Akonadi::Collection &col ); + KPIM::Maildir maildirForCollection(const Akonadi::Collection &col); /** Creates a collection object for the given maildir @p md. */ - Akonadi::Collection collectionForMaildir( const KPIM::Maildir &md ) const; + Akonadi::Collection collectionForMaildir(const KPIM::Maildir &md) const; - QString maildirPathForCollection( const Akonadi::Collection &collection) const; + QString maildirPathForCollection(const Akonadi::Collection &collection) const; void stopMaildirScan(const KPIM::Maildir &maildir); void restartMaildirScan(const KPIM::Maildir &maildir); diff -Nru kdepim-runtime-4.14.6/resources/maildir/main.cpp kdepim-runtime-15.08.0/resources/maildir/main.cpp --- kdepim-runtime-4.14.6/resources/maildir/main.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/main.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,5 @@ /* - Copyright (c) 2007 Till Adam + Copyright (c) 2015 Daniel Vrátil 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 @@ -19,8 +19,4 @@ #include "maildirresource.h" -#include - -#include - -AKONADI_AGENT_FACTORY( MaildirResource, akonadi_maildir_resource ) +AKONADI_RESOURCE_MAIN(MaildirResource) diff -Nru kdepim-runtime-4.14.6/resources/maildir/retrieveitemsjob.cpp kdepim-runtime-15.08.0/resources/maildir/retrieveitemsjob.cpp --- kdepim-runtime-4.14.6/resources/maildir/retrieveitemsjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/retrieveitemsjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,170 +18,173 @@ */ #include "retrieveitemsjob.h" -#include -#include -#include -#include -#include -#include -#include - -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -RetrieveItemsJob::RetrieveItemsJob ( const Akonadi::Collection& collection, const KPIM::Maildir& md, QObject* parent ) : - Job ( parent ), - m_collection( collection ), - m_maildir( md ), - m_mimeType( KMime::Message::mimeType() ), - m_transaction( 0 ), - m_entryIterator(0), - m_previousMtime( 0 ), - m_highestMtime( 0 ) +RetrieveItemsJob::RetrieveItemsJob(const Akonadi::Collection &collection, const KPIM::Maildir &md, QObject *parent) : + Job(parent), + m_collection(collection), + m_maildir(md), + m_mimeType(KMime::Message::mimeType()), + m_transaction(Q_NULLPTR), + m_entryIterator(Q_NULLPTR), + m_previousMtime(0), + m_highestMtime(0) { - Q_ASSERT( m_collection.isValid() ); - Q_ASSERT( m_maildir.isValid() ); + Q_ASSERT(m_collection.isValid()); + Q_ASSERT(m_maildir.isValid()); } -void RetrieveItemsJob::setMimeType ( const QString& mimeType ) +void RetrieveItemsJob::setMimeType(const QString &mimeType) { - m_mimeType = mimeType; + m_mimeType = mimeType; } void RetrieveItemsJob::doStart() { - Q_ASSERT( !m_mimeType.isEmpty() ); - Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( m_collection, this ); - connect( job, SIGNAL(result(KJob*)), SLOT(localListDone(KJob*)) ); -} - -void RetrieveItemsJob::localListDone ( KJob* job ) -{ - if ( job->error() ) return; // handled by base class - - const Akonadi::Item::List items = qobject_cast( job )->items(); - m_localItems.reserve( items.size() ); - foreach ( const Akonadi::Item &item, items ) { - if ( !item.remoteId().isEmpty() ) - m_localItems.insert( item.remoteId(), item ); - } - - m_listingPath = m_maildir.path() + QLatin1String( "/new/" ); - delete m_entryIterator; - m_entryIterator = new QDirIterator( m_maildir.pathToNew(), QDir::Files ); - m_previousMtime = m_collection.remoteRevision().toLongLong(); - m_highestMtime = 0; - processEntry(); + Q_ASSERT(!m_mimeType.isEmpty()); + Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob(m_collection, this); + connect(job, &Akonadi::ItemFetchJob::result, this, &RetrieveItemsJob::localListDone); +} + +void RetrieveItemsJob::localListDone(KJob *job) +{ + if (job->error()) { + return; // handled by base class + } + + const Akonadi::Item::List items = qobject_cast(job)->items(); + m_localItems.reserve(items.size()); + foreach (const Akonadi::Item &item, items) { + if (!item.remoteId().isEmpty()) { + m_localItems.insert(item.remoteId(), item); + } + } + + m_listingPath = m_maildir.path() + QLatin1String("/new/"); + delete m_entryIterator; + m_entryIterator = new QDirIterator(m_maildir.pathToNew(), QDir::Files); + m_previousMtime = m_collection.remoteRevision().toLongLong(); + m_highestMtime = 0; + processEntry(); } void RetrieveItemsJob::processEntry() { - QFileInfo entryInfo; + QFileInfo entryInfo; - QString filePath = m_entryIterator->next(); + QString filePath = m_entryIterator->next(); - QString fileName = m_entryIterator->fileName(); + QString fileName = m_entryIterator->fileName(); - bool newItemFound = false; - while ( !newItemFound ) { - if ( filePath.isEmpty() ) { - if ( m_listingPath.endsWith( QLatin1String( "/new/" ) ) ) { - m_listingPath = m_maildir.path() + QLatin1String( "/cur/" ); - delete m_entryIterator; - m_entryIterator = new QDirIterator( m_maildir.pathToCurrent(), QDir::Files ); - processEntry(); - } else { - entriesProcessed(); - } - return; - } - - entryInfo = m_entryIterator->fileInfo(); - const qint64 currentMtime = entryInfo.lastModified().toMSecsSinceEpoch(); - m_highestMtime = qMax( m_highestMtime, currentMtime ); - if ( currentMtime <= m_previousMtime && m_localItems.contains( fileName ) ) { // old, we got this one already - m_localItems.remove( fileName ); - filePath = m_entryIterator->next(); - fileName = m_entryIterator->fileName(); - } else { - newItemFound = true; + bool newItemFound = false; + while (!newItemFound) { + if (filePath.isEmpty()) { + if (m_listingPath.endsWith(QLatin1String("/new/"))) { + m_listingPath = m_maildir.path() + QLatin1String("/cur/"); + delete m_entryIterator; + m_entryIterator = new QDirIterator(m_maildir.pathToCurrent(), QDir::Files); + processEntry(); + } else { + entriesProcessed(); + } + return; + } + + entryInfo = m_entryIterator->fileInfo(); + const qint64 currentMtime = entryInfo.lastModified().toMSecsSinceEpoch(); + m_highestMtime = qMax(m_highestMtime, currentMtime); + if (currentMtime <= m_previousMtime && m_localItems.contains(fileName)) { // old, we got this one already + m_localItems.remove(fileName); + filePath = m_entryIterator->next(); + fileName = m_entryIterator->fileName(); + } else { + newItemFound = true; + } + } + Akonadi::Item item; + item.setRemoteId(fileName); + item.setMimeType(m_mimeType); + const qint64 entrySize = entryInfo.size(); + if (entrySize >= 0) { + item.setSize(entrySize); + } + + KMime::Message *msg = new KMime::Message; + msg->setHead(KMime::CRLFtoLF(m_maildir.readEntryHeadersFromFile(m_listingPath + fileName))); + msg->parse(); + + Akonadi::Item::Flags flags = m_maildir.readEntryFlags(fileName); + Q_FOREACH (const Akonadi::Item::Flag &flag, flags) { + item.setFlag(flag); } - } - Akonadi::Item item; - item.setRemoteId( fileName ); - item.setMimeType( m_mimeType ); - const qint64 entrySize = entryInfo.size(); - if ( entrySize >= 0 ) - item.setSize( entrySize ); - - KMime::Message *msg = new KMime::Message; - msg->setHead( KMime::CRLFtoLF( m_maildir.readEntryHeadersFromFile( m_listingPath + fileName ) ) ); - msg->parse(); - - Akonadi::Item::Flags flags = m_maildir.readEntryFlags( fileName ); - Q_FOREACH ( const Akonadi::Item::Flag &flag, flags ) { - item.setFlag( flag ); - } - - item.setPayload( KMime::Message::Ptr( msg ) ); - Akonadi::MessageFlags::copyMessageFlags(*msg, item); - - KJob *job = 0; - if ( m_localItems.contains( fileName ) ) { // modification - item.setId( m_localItems.value( fileName ).id() ); - job = new Akonadi::ItemModifyJob( item, transaction() ); - m_localItems.remove( fileName ); - } else { // new item - job = new Akonadi::ItemCreateJob( item, m_collection, transaction() ); - } - connect(job, SIGNAL(result(KJob*)), SLOT(processEntryDone(KJob*)) ); + + item.setPayload(KMime::Message::Ptr(msg)); + Akonadi::MessageFlags::copyMessageFlags(*msg, item); + KJob *job = Q_NULLPTR; + if (m_localItems.contains(fileName)) { // modification + item.setId(m_localItems.value(fileName).id()); + job = new Akonadi::ItemModifyJob(item, transaction()); + m_localItems.remove(fileName); + } else { // new item + job = new Akonadi::ItemCreateJob(item, m_collection, transaction()); + } + connect(job, &Akonadi::ItemCreateJob::result, this, &RetrieveItemsJob::processEntryDone); } -void RetrieveItemsJob::processEntryDone( KJob* ) +void RetrieveItemsJob::processEntryDone(KJob *) { processEntry(); } void RetrieveItemsJob::entriesProcessed() { - delete m_entryIterator; - m_entryIterator = 0; - if ( !m_localItems.isEmpty() ) { - Akonadi::ItemDeleteJob *job = new Akonadi::ItemDeleteJob( m_localItems.values(), transaction() ); - m_maildir.removeCachedKeys( m_localItems.keys() ); - transaction()->setIgnoreJobFailure( job ); - } - - // update mtime - if ( m_highestMtime != m_previousMtime ) { - Akonadi::Collection newCol( m_collection ); - newCol.setRemoteRevision( QString::number( m_highestMtime ) ); - Akonadi::CollectionModifyJob *job = new Akonadi::CollectionModifyJob( newCol, transaction() ); - transaction()->setIgnoreJobFailure( job ); - } - - if ( !m_transaction ) // no jobs created here -> done - emitResult(); - else - m_transaction->commit(); -} + delete m_entryIterator; + m_entryIterator = Q_NULLPTR; + if (!m_localItems.isEmpty()) { + Akonadi::ItemDeleteJob *job = new Akonadi::ItemDeleteJob(Akonadi::valuesToVector(m_localItems), transaction()); + m_maildir.removeCachedKeys(m_localItems.keys()); + transaction()->setIgnoreJobFailure(job); + } + // update mtime + if (m_highestMtime != m_previousMtime) { + Akonadi::Collection newCol(m_collection); + newCol.setRemoteRevision(QString::number(m_highestMtime)); + Akonadi::CollectionModifyJob *job = new Akonadi::CollectionModifyJob(newCol, transaction()); + transaction()->setIgnoreJobFailure(job); + } + if (!m_transaction) { // no jobs created here -> done + emitResult(); + } else { + m_transaction->commit(); + } +} -Akonadi::TransactionSequence* RetrieveItemsJob::transaction() +Akonadi::TransactionSequence *RetrieveItemsJob::transaction() { - if ( !m_transaction ) { - m_transaction = new Akonadi::TransactionSequence( this ); - m_transaction->setAutomaticCommittingEnabled( false ); - connect( m_transaction, SIGNAL(result(KJob*)), SLOT(transactionDone(KJob*)) ); - } - return m_transaction; + if (!m_transaction) { + m_transaction = new Akonadi::TransactionSequence(this); + m_transaction->setAutomaticCommittingEnabled(false); + connect(m_transaction, &Akonadi::TransactionSequence::result, this, &RetrieveItemsJob::transactionDone); + } + return m_transaction; } -void RetrieveItemsJob::transactionDone ( KJob* job ) +void RetrieveItemsJob::transactionDone(KJob *job) { - if ( job->error() ) return; // handled by base class - emitResult(); + if (job->error()) { + return; // handled by base class + } + emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/maildir/retrieveitemsjob.h kdepim-runtime-15.08.0/resources/maildir/retrieveitemsjob.h --- kdepim-runtime-4.14.6/resources/maildir/retrieveitemsjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/retrieveitemsjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,9 +20,9 @@ #ifndef MAILDIR_RETRIEVEITEMSJOB_H #define MAILDIR_RETRIEVEITEMSJOB_H -#include -#include -#include +#include +#include +#include #include "maildir.h" @@ -38,25 +38,25 @@ */ class RetrieveItemsJob : public Akonadi::Job { - Q_OBJECT - public: - RetrieveItemsJob( const Akonadi::Collection &collection, const KPIM::Maildir &md, QObject* parent = 0 ); - void setMimeType( const QString &mimeType ); + Q_OBJECT +public: + RetrieveItemsJob(const Akonadi::Collection &collection, const KPIM::Maildir &md, QObject *parent = Q_NULLPTR); + void setMimeType(const QString &mimeType); - protected: - void doStart(); +protected: + void doStart() Q_DECL_OVERRIDE; - private: +private: void entriesProcessed(); - Akonadi::TransactionSequence* transaction(); + Akonadi::TransactionSequence *transaction(); - private slots: - void localListDone( KJob *job ); - void transactionDone( KJob *job ); +private Q_SLOTS: + void localListDone(KJob *job); + void transactionDone(KJob *job); void processEntry(); - void processEntryDone( KJob * ); + void processEntryDone(KJob *); - private: +private: Akonadi::Collection m_collection; KPIM::Maildir m_maildir; QHash m_localItems; diff -Nru kdepim-runtime-4.14.6/resources/maildir/settings.kcfgc kdepim-runtime-15.08.0/resources/maildir/settings.kcfgc --- kdepim-runtime-4.14.6/resources/maildir/settings.kcfgc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/settings.kcfgc 2015-08-10 21:01:02.000000000 +0000 @@ -6,4 +6,4 @@ Singleton=false #IncludeFiles= GlobalEnums=true -Namespace=Akonadi_Maildir_Resource +NameSpace=Akonadi_Maildir_Resource diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/CMakeLists.txt kdepim-runtime-15.08.0/resources/maildir/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/maildir/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) - -# Stolen from kdepimlibs/akonadi/tests -macro(add_akonadi_isolated_test _source) - get_filename_component(_targetName ${_source} NAME_WE) - set(_srcList ${_source} ) - - kde4_add_executable(${_targetName} TEST ${_srcList}) - target_link_libraries(${_targetName} - ${QT_QTTEST_LIBRARY} - ${QT_QTGUI_LIBRARY} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_AKONADI_KMIME_LIBS} - ${KDE4_KDECORE_LIBS} - ${KDEPIMLIBS_MAILTRANSPORT_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${QT_QTCORE_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ) - - # based on kde4_add_unit_test - if (WIN32) - get_target_property( _loc ${_targetName} LOCATION ) - set(_executable ${_loc}.bat) - else () - set(_executable ${EXECUTABLE_OUTPUT_PATH}/${_targetName}) - endif () - if (UNIX) - set(_executable ${_executable}.shell) - endif () - - find_program(_testrunner akonaditest) - - if (KDEPIM_RUN_ISOLATED_TESTS) - add_test( maildir-${_targetName} ${_testrunner} -c ${CMAKE_CURRENT_SOURCE_DIR}/unittestenv/config.xml ${_executable} ) - endif () -endmacro(add_akonadi_isolated_test) - - - -add_akonadi_isolated_test( synctest.cpp ) -akonadi_add_resourcetest( maildir maildir.js ) - diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir/root/cur/1237726845.6570.BejQg!2,S kdepim-runtime-15.08.0/resources/maildir/tests/maildir/root/cur/1237726845.6570.BejQg!2,S --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir/root/cur/1237726845.6570.BejQg!2,S 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir/root/cur/1237726845.6570.BejQg!2,S 1970-01-01 00:00:00.000000000 +0000 @@ -1,171 +0,0 @@ -Return-Path: -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; - Sun, 22 Mar 2009 13:45:00 +0100 -X-Sieve: CMU Sieve 2.2 -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id 8C4FFE6C79B - for ; Sun, 22 Mar 2009 13:45:00 +0100 (CET) -Received: from smykowski.kdab.net ([127.0.0.1]) - by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 09703-05 for ; - Sun, 22 Mar 2009 13:45:00 +0100 (CET) -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id 163D2E6C7AF - for ; Sun, 22 Mar 2009 13:45:00 +0100 (CET) -Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) - by smykowski.kdab.net (Postfix) with ESMTP id 31945E6C79E - for ; Sun, 22 Mar 2009 13:44:59 +0100 (CET) -Received: from ktown.kde.org ([131.246.120.250]) - by kdeget.osuosl.org with smtp (Exim 4.63) - (envelope-from ) - id 1LlN8R-0005Jr-VE - for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 13:50:40 +0100 -Received: (qmail 7667 invoked by uid 72); 22 Mar 2009 12:50:33 -0000 -Received: (qmail 7658 invoked from network); 22 Mar 2009 12:50:31 -0000 -Received: from unknown (HELO office.kde.org) (195.135.221.67) - by ktown.kde.org with SMTP; 22 Mar 2009 12:50:29 -0000 -Received: from svn.kde.org (localhost [127.0.0.1]) - by office.kde.org (Postfix) with SMTP id 93E9F18E - for ; Sun, 22 Mar 2009 13:50:30 +0100 (CET) -Received: (nullmailer pid 25707 invoked by uid 30); - Sun, 22 Mar 2009 12:50:30 -0000 -From: Volker Krause -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> -X-BeenThere: kde-commits@kde.org -X-Mailman-Version: 2.1.9 -Precedence: list -Reply-To: kde-commits@kde.org -List-Id: Notification of KDE commits -List-Unsubscribe: , - -List-Post: -List-Help: -List-Subscribe: , - -X-Virus-Scanned: by amavisd-new at kdab.net -X-Kolab-Scheduling-Message: FALSE -X-UID: 26669 -X-Length: 5694 -Status: RO -X-Status: RC -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h - - ---- trunk/playground/pim/akonaditest/resourcetester/resourcesynchronizationjob.cpp #942676:942677 -@@ -18,12 +18,14 @@ - #include "resourcesynchronizationjob.h" - - #include -+#include - - #include - #include - - #include - #include -+#include - - namespace Akonadi - { -@@ -31,15 +33,31 @@ - class ResourceSynchronizationJobPrivate - { - public: -+ ResourceSynchronizationJobPrivate() : -+ interface( 0 ), -+ safetyTimer( 0 ), -+ timeoutCount( 0 ) -+ {} -+ - AgentInstance instance; - QDBusInterface* interface; -+ QTimer* safetyTimer; -+ int timeoutCount; -+ static int timeoutCountLimit; - }; - -+int ResourceSynchronizationJobPrivate::timeoutCountLimit = 60; -+ - ResourceSynchronizationJob::ResourceSynchronizationJob(const AgentInstance& instance, QObject* parent) : - KJob( parent ), - d( new ResourceSynchronizationJobPrivate ) - { - d->instance = instance; -+ d->safetyTimer = new QTimer( this ); -+ connect( d->safetyTimer, SIGNAL(timeout()), SLOT(slotTimeout()) ); -+ d->safetyTimer->setInterval( 10 * 1000 ); -+ d->safetyTimer->setSingleShot( false ); -+ d->safetyTimer->start(); - } - - ResourceSynchronizationJob::~ResourceSynchronizationJob() -@@ -72,9 +90,31 @@ - - void ResourceSynchronizationJob::slotSynchronized() - { -+ disconnect( d->interface, SIGNAL(synchronized()), this, SLOT(slotSynchronized()) ); -+ d->safetyTimer->stop(); - emitResult(); - } - -+void ResourceSynchronizationJob::slotTimeout() -+{ -+ d->instance = AgentManager::self()->instance( d->instance.identifier() ); -+ d->timeoutCount++; -+ -+ if ( d->timeoutCount > d->timeoutCountLimit ) { -+ d->safetyTimer->stop(); -+ setError( UserDefinedError ); -+ setErrorText( i18n( "Resource synchronization timed out." ) ); -+ emitResult(); -+ return; -+ } -+ -+ if ( d->instance.status() == AgentInstance::Idle ) { -+ // try again, we might have lost the synchronized() signal -+ kDebug() << "trying again to sync resource" << d->instance.identifier(); -+ d->instance.synchronize(); -+ } - } - -+} -+ - #include "resourcesynchronizationjob.moc" ---- trunk/playground/pim/akonaditest/resourcetester/resourcesynchronizationjob.h #942676:942677 -@@ -27,7 +27,6 @@ - - /** - Synchronizes a given resource. -- @todo Add safety timeouts. - */ - class ResourceSynchronizationJob : public KJob - { -@@ -48,6 +47,7 @@ - - private slots: - void slotSynchronized(); -+ void slotTimeout(); - - private: - ResourceSynchronizationJobPrivate* const d; diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir/root/new/.keep kdepim-runtime-15.08.0/resources/maildir/tests/maildir/root/new/.keep --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir/root/new/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir/root/new/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir/root/tmp/.keep kdepim-runtime-15.08.0/resources/maildir/tests/maildir/root/tmp/.keep --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir/root/tmp/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir/root/tmp/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child1/cur/1237726858.6570.dtdn4!2,S kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child1/cur/1237726858.6570.dtdn4!2,S --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child1/cur/1237726858.6570.dtdn4!2,S 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child1/cur/1237726858.6570.dtdn4!2,S 1970-01-01 00:00:00.000000000 +0000 @@ -1,107 +0,0 @@ -Return-Path: -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; - Sun, 22 Mar 2009 12:55:23 +0100 -X-Sieve: CMU Sieve 2.2 -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id EF869E6C77A - for ; Sun, 22 Mar 2009 12:55:22 +0100 (CET) -Received: from smykowski.kdab.net ([127.0.0.1]) - by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 06346-10 for ; - Sun, 22 Mar 2009 12:55:21 +0100 (CET) -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id 24127E6C79E - for ; Sun, 22 Mar 2009 12:55:21 +0100 (CET) -Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) - by smykowski.kdab.net (Postfix) with ESMTP id D175FE6C77A - for ; Sun, 22 Mar 2009 12:55:20 +0100 (CET) -Received: from ktown.kde.org ([131.246.120.250]) - by kdeget.osuosl.org with smtp (Exim 4.63) - (envelope-from ) - id 1LlMMP-0003EH-9D - for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 13:01:02 +0100 -Received: (qmail 14097 invoked by uid 72); 22 Mar 2009 12:00:55 -0000 -Received: (qmail 14075 invoked from network); 22 Mar 2009 12:00:53 -0000 -Received: from unknown (HELO office.kde.org) (195.135.221.67) - by ktown.kde.org with SMTP; 22 Mar 2009 12:00:51 -0000 -Received: from svn.kde.org (localhost [127.0.0.1]) - by office.kde.org (Postfix) with SMTP id 0F54D18E - for ; Sun, 22 Mar 2009 13:00:53 +0100 (CET) -Received: (nullmailer pid 17237 invoked by uid 30); - Sun, 22 Mar 2009 12:00:53 -0000 -From: Volker Krause -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester - trunk/playground/pim/akonaditest/resourcetester/tests -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:00:53 +0000 -Message-Id: <1237723253.005953.17235.nullmailer@svn.kde.org> -X-BeenThere: kde-commits@kde.org -X-Mailman-Version: 2.1.9 -Precedence: list -Reply-To: kde-commits@kde.org -List-Id: Notification of KDE commits -List-Unsubscribe: , - -List-Post: -List-Help: -List-Subscribe: , - -X-Virus-Scanned: by amavisd-new at kdab.net -X-Kolab-Scheduling-Message: FALSE -X-UID: 26667 -X-Length: 4226 -Status: RO -X-Status: ORC -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -SVN commit 942650 by vkrause: - -Add CMake macro to run resource tests. - - - M +20 -0 CMakeLists.txt - A tests/CMakeLists.txt - AM tests/vcardtest-readonly.js tests/vcardtest.js#942640 - AM tests/vcardtest-readonly.xml tests/vcardtest.xml#942640 - - ---- trunk/playground/pim/akonaditest/resourcetester/CMakeLists.txt #942649:942650 -@@ -17,6 +17,26 @@ - - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - -+macro( akonadi_add_resourcetest _testname _script ) -+ if ( ${EXECUTABLE_OUTPUT_PATH} ) -+ set( _exepath ${EXECUTABLE_OUTPUT_PATH} ) -+ else ( ${EXECUTABLE_OUTPUT_PATH} ) -+ set( _exepath ${CMAKE_CURRENT_BINARY_DIR}/.. ) -+ endif ( ${EXECUTABLE_OUTPUT_PATH} ) -+ if (WIN32) -+ set(_resourcetester ${_exepath}/resourcetester.bat) -+ else (WIN32) -+ set(_resourcetester ${_exepath}/resourcetester) -+ endif (WIN32) -+ if (UNIX) -+ set(_resourcetester ${_resourcetester}.shell) -+ endif (UNIX) -+ -+ add_test( ${_testname} ${_resourcetester} -c ${CMAKE_CURRENT_SOURCE_DIR}/${_script} ) -+endmacro( akonadi_add_resourcetest ) -+ -+add_subdirectory( tests ) -+ - set( resourcetester_SRCS - global.cpp - main.cpp -** trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest-readonly.js #property svn:mergeinfo - + -** trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest-readonly.xml #property svn:mergeinfo - + diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child1/cur/1237726875.6570.R4KOW!2,S kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child1/cur/1237726875.6570.R4KOW!2,S --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child1/cur/1237726875.6570.R4KOW!2,S 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child1/cur/1237726875.6570.R4KOW!2,S 1970-01-01 00:00:00.000000000 +0000 @@ -1,150 +0,0 @@ -Return-Path: -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; - Sun, 22 Mar 2009 13:16:01 +0100 -X-Sieve: CMU Sieve 2.2 -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id CA2E8E6C783 - for ; Sun, 22 Mar 2009 13:16:00 +0100 (CET) -Received: from smykowski.kdab.net ([127.0.0.1]) - by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 07855-05 for ; - Sun, 22 Mar 2009 13:15:58 +0100 (CET) -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id ABDFDE6C79B - for ; Sun, 22 Mar 2009 13:15:58 +0100 (CET) -Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) - by smykowski.kdab.net (Postfix) with ESMTP id 5CD44E6C783 - for ; Sun, 22 Mar 2009 13:15:58 +0100 (CET) -Received: from ktown.kde.org ([131.246.120.250]) - by kdeget.osuosl.org with smtp (Exim 4.63) - (envelope-from ) - id 1LlMgP-00046D-6T - for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 13:21:41 +0100 -Received: (qmail 27078 invoked by uid 72); 22 Mar 2009 12:21:36 -0000 -Received: (qmail 27060 invoked from network); 22 Mar 2009 12:21:34 -0000 -Received: from unknown (HELO office.kde.org) (195.135.221.67) - by ktown.kde.org with SMTP; 22 Mar 2009 12:21:32 -0000 -Received: from svn.kde.org (localhost [127.0.0.1]) - by office.kde.org (Postfix) with SMTP id 0A38E18E - for ; Sun, 22 Mar 2009 13:21:34 +0100 (CET) -Received: (nullmailer pid 20237 invoked by uid 30); - Sun, 22 Mar 2009 12:21:34 -0000 -From: Volker Krause -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:21:34 +0000 -Message-Id: <1237724494.009832.20236.nullmailer@svn.kde.org> -X-BeenThere: kde-commits@kde.org -X-Mailman-Version: 2.1.9 -Precedence: list -Reply-To: kde-commits@kde.org -List-Id: Notification of KDE commits -List-Unsubscribe: , - -List-Post: -List-Help: -List-Subscribe: , - -X-Virus-Scanned: by amavisd-new at kdab.net -X-Kolab-Scheduling-Message: FALSE -X-UID: 26668 -X-Length: 4765 -Status: RO -X-Status: ORC -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -SVN commit 942656 by vkrause: - -- propagate script errors -- make sure the Akonadi server is operational - - - M +5 -0 main.cpp - M +13 -1 script.cpp - M +6 -3 script.h - - ---- trunk/playground/pim/akonaditest/resourcetester/main.cpp #942655:942656 -@@ -21,6 +21,8 @@ - #include "global.h" - #include "test.h" - -+#include -+ - #include - #include - #include -@@ -71,6 +73,9 @@ - signal( SIGQUIT, sigHandler ); - #endif - -+ if ( !Akonadi::Control::start() ) -+ qFatal( "Unable to start Akonadi!" ); -+ - Script *script = new Script(); - - script->configure(path); ---- trunk/playground/pim/akonaditest/resourcetester/script.cpp #942655:942656 -@@ -16,12 +16,13 @@ - */ - - #include "script.h" -+#include - #include - - Script::Script() - { - action = new Kross::Action(this, "ResourceTester"); -- connect( action, SIGNAL(finished(Kross::Action*)), QCoreApplication::instance(), SLOT(quit()) ); -+ connect( action, SIGNAL(finished(Kross::Action*)), SLOT(finished(Kross::Action*)) ); - } - - void Script::configure(const QString &path, QHash hash) -@@ -51,4 +52,15 @@ - action->trigger(); - } - -+void Script::finished(Kross::Action* action) -+{ -+ if ( action->hadError() ) { -+ kError() << action->errorMessage() << action->errorTrace(); -+ QCoreApplication::instance()->exit( 1 ); -+ } else { -+ QCoreApplication::instance()->quit(); -+ } -+} -+ -+ - #include "script.moc" ---- trunk/playground/pim/akonaditest/resourcetester/script.h #942655:942656 -@@ -24,9 +24,6 @@ - class Script : public QObject - { - Q_OBJECT -- private: -- Kross::Action *action; -- - public: - Script(); - void configure(const QString &path, QHash hash); -@@ -35,6 +32,12 @@ - - public slots: - void start(); -+ -+ private slots: -+ void finished( Kross::Action *action ); -+ -+ private: -+ Kross::Action *action; - }; - - #endif diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child1/new/.keep kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child1/new/.keep --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child1/new/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child1/new/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child1/tmp/.keep kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child1/tmp/.keep --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child1/tmp/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child1/tmp/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/.child1.directory/grandchild/cur/1237726881.6570.rfoxg!2,S kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/.child1.directory/grandchild/cur/1237726881.6570.rfoxg!2,S --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/.child1.directory/grandchild/cur/1237726881.6570.rfoxg!2,S 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/.child1.directory/grandchild/cur/1237726881.6570.rfoxg!2,S 1970-01-01 00:00:00.000000000 +0000 @@ -1,282 +0,0 @@ -Return-Path: -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; - Sun, 22 Mar 2009 12:10:48 +0100 -X-Sieve: CMU Sieve 2.2 -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id 4BDF8E6C790 - for ; Sun, 22 Mar 2009 12:10:48 +0100 (CET) -Received: from smykowski.kdab.net ([127.0.0.1]) - by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 03694-02 for ; - Sun, 22 Mar 2009 12:10:45 +0100 (CET) -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id B289FE6C79B - for ; Sun, 22 Mar 2009 12:10:45 +0100 (CET) -Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) - by smykowski.kdab.net (Postfix) with ESMTP id 3B465E6C790 - for ; Sun, 22 Mar 2009 12:10:45 +0100 (CET) -Received: from ktown.kde.org ([131.246.120.250]) - by kdeget.osuosl.org with smtp (Exim 4.63) - (envelope-from ) - id 1LlLfE-0001OT-K7 - for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 12:16:25 +0100 -Received: (qmail 23006 invoked by uid 72); 22 Mar 2009 11:16:19 -0000 -Received: (qmail 22986 invoked from network); 22 Mar 2009 11:16:14 -0000 -Received: from unknown (HELO office.kde.org) (195.135.221.67) - by ktown.kde.org with SMTP; 22 Mar 2009 11:16:11 -0000 -Received: from svn.kde.org (localhost [127.0.0.1]) - by office.kde.org (Postfix) with SMTP id 85EE718E - for ; Sun, 22 Mar 2009 12:16:12 +0100 (CET) -Received: (nullmailer pid 13467 invoked by uid 30); - Sun, 22 Mar 2009 11:16:12 -0000 -From: Volker Krause -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester - trunk/playground/pim/akonaditest/resourcetester/tests -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 11:16:12 +0000 -Message-Id: <1237720572.493438.13466.nullmailer@svn.kde.org> -X-BeenThere: kde-commits@kde.org -X-Mailman-Version: 2.1.9 -Precedence: list -Reply-To: kde-commits@kde.org -List-Id: Notification of KDE commits -List-Unsubscribe: , - -List-Post: -List-Help: -List-Subscribe: , - -X-Virus-Scanned: by amavisd-new at kdab.net -X-Kolab-Scheduling-Message: FALSE -X-UID: 26666 -X-Length: 11240 -Status: RO -X-Status: ORC -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -SVN commit 942640 by vkrause: - -Allow to specifiy the collection property used to identify corresponding -collections. - - - M +2 -0 tests/vcardtest.js - M +1 -1 tests/vcardtest.xml - M +29 -14 xmloperations.cpp - M +46 -0 xmloperations.h - - ---- trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest.js #942639:942640 -@@ -4,6 +4,8 @@ - - XmlOperations.setXmlFile( "vcardtest.xml" ); - XmlOperations.setRootCollections( Resource.identifier() ); -+XmlOperations.setCollectionKey( "None" ); // we only expect one collection - XmlOperations.ignoreCollectionField( "Name" ); // name is the resource identifier and thus unpredictable -+XmlOperations.ignoreCollectionField( "RemoteId" ); // remote id is the absolute path - XmlOperations.assertEqual(); - ---- trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest.xml #942639:942640 -@@ -1,5 +1,5 @@ - -- -+ - wcdW - ("vcardtest.vcf" "office-address-book") - ---- trunk/playground/pim/akonaditest/resourcetester/xmloperations.cpp #942639:942640 -@@ -31,9 +31,6 @@ - #include - #include - --#include --#include -- - using namespace Akonadi; - - template QTextStream& operator<<( QTextStream &s, const QSet &set ) -@@ -53,7 +50,8 @@ - - XmlOperations::XmlOperations(QObject* parent) : - QObject( parent ), -- mCollectionFields( 0xFF ) -+ mCollectionFields( 0xFF ), -+ mCollectionKey( RemoteId ) - { - } - -@@ -99,6 +97,17 @@ - return mErrorMsg; - } - -+void XmlOperations::setCollectionKey(XmlOperations::CollectionField field) -+{ -+ mCollectionKey = field; -+} -+ -+void XmlOperations::setCollectionKey(const QString& fieldName) -+{ -+ const QMetaEnum me = metaObject()->enumerator( metaObject()->indexOfEnumerator( "CollectionField" ) ); -+ setCollectionKey( static_cast( me.keyToValue( fieldName.toLatin1() ) ) ); -+} -+ - void XmlOperations::ignoreCollectionField(XmlOperations::CollectionField field) - { - mCollectionFields = mCollectionFields & ~field; -@@ -137,8 +146,20 @@ - { - Collection::List cols( _cols ); - Collection::List refCols( _refCols ); -- std::sort( cols.begin(), cols.end(), boost::bind( &Collection::remoteId, _1 ) < boost::bind( &Collection::remoteId, _2 ) ); -- std::sort( refCols.begin(), refCols.end(), boost::bind( &Collection::remoteId, _1 ) < boost::bind( &Collection::remoteId, _2 ) ); -+ switch ( mCollectionKey ) { -+ case RemoteId: -+ sortCollectionList( cols, &Collection::remoteId ); -+ sortCollectionList( refCols, &Collection::remoteId ); -+ break; -+ case Name: -+ sortCollectionList( cols, &Collection::name ); -+ sortCollectionList( refCols, &Collection::name ); -+ break; -+ case None: -+ break; -+ default: -+ Q_ASSERT( false ); -+ } - - for ( int i = 0; i < cols.count(); ++i ) { - const Collection col = cols.at( i ); -@@ -148,11 +169,6 @@ - } - - const Collection refCol = refCols.at( i ); -- if ( col.remoteId() != refCol.remoteId() ) { -- mErrorMsg = QString::fromLatin1( "Collection with remote id '%1' is missing." ).arg( refCol.remoteId() ); -- return false; -- } -- - if ( !compareCollection( col, refCol ) ) - return false; - } -@@ -177,14 +193,13 @@ - - bool XmlOperations::compareCollection(const Collection& _col, const Collection& _refCol) - { -- Q_ASSERT( _col.remoteId() == _refCol.remoteId() ); -- - // normalize - Collection col( normalize( _col ) ); - Collection refCol( normalize( _refCol ) ); - - // compare the two collections -- if ( !compareValue( col, refCol, &Collection::contentMimeTypes, ContentMimeType ) || -+ if ( !compareValue( col, refCol, &Collection::remoteId, RemoteId ) || -+ !compareValue( col, refCol, &Collection::contentMimeTypes, ContentMimeType ) || - !compareValue( col, refCol, &Collection::name, Name ) ) - return false; - ---- trunk/playground/pim/akonaditest/resourcetester/xmloperations.h #942639:942640 -@@ -28,6 +28,10 @@ - #include - #include - -+#include -+#include -+ -+ - /** - Compares a Akonadi collection sub-tree with reference data supplied in an XML file. - */ -@@ -49,6 +53,7 @@ - - Q_DECLARE_FLAGS( CollectionFields, CollectionField ) - -+ void setCollectionKey( CollectionField field ); - void ignoreCollectionField( CollectionField field ); - - public slots: -@@ -59,6 +64,7 @@ - Akonadi::Item getItemByRemoteId(const QString& rid); - Akonadi::Collection getCollectionByRemoteId(const QString& rid); - -+ void setCollectionKey( const QString &fieldName ); - void ignoreCollectionField( const QString &fieldName ); - - bool compare(); -@@ -78,16 +84,25 @@ - template bool compareValue( const Akonadi::Collection &col, const Akonadi::Collection &refCol, - T (Akonadi::Collection::*property)() const, - CollectionField propertyType ); -+ template bool compareValue( const Akonadi::Collection &col, const Akonadi::Collection &refCol, -+ T (Akonadi::Entity::*property)() const, -+ CollectionField propertyType ); - template bool compareValue( const Akonadi::Item& item, const Akonadi::Item& refItem, - T (Akonadi::Item::*property)() const, - const char* propertyName ); - template bool compareValue( const T& value, const T& refValue ); - -+ template void sortCollectionList( Akonadi::Collection::List &list, -+ T ( Akonadi::Collection::*property)() const ) const; -+ template void sortCollectionList( Akonadi::Collection::List &list, -+ T ( Akonadi::Entity::*property)() const ) const; -+ - private: - Akonadi::Collection::List mRoots; - Akonadi::XmlDocument mDocument; - QString mErrorMsg; - CollectionFields mCollectionFields; -+ CollectionField mCollectionKey; - }; - - -@@ -109,6 +124,23 @@ - } - - template -+bool XmlOperations::compareValue( const Akonadi::Collection& col, const Akonadi::Collection& refCol, -+ T (Akonadi::Entity::*property)() const, -+ CollectionField propertyType ) -+{ -+ if ( mCollectionFields & propertyType ) { -+ const bool result = compareValue( ((col).*(property))(), ((refCol).*(property))() ); -+ if ( !result ) { -+ const QMetaEnum me = metaObject()->enumerator( metaObject()->indexOfEnumerator( "CollectionField" ) ); -+ mErrorMsg.prepend( QString::fromLatin1( "Collection with remote id '%1' differs in property '%2':\n" ) -+ .arg( col.remoteId() ).arg( me.valueToKey( propertyType ) ) ); -+ } -+ return result; -+ } -+ return true; -+} -+ -+template - bool XmlOperations::compareValue( const Akonadi::Item& item, const Akonadi::Item& refItem, - T (Akonadi::Item::*property)() const, - const char* propertyName ) -@@ -131,4 +163,18 @@ - return false; - } - -+template -+void XmlOperations::sortCollectionList( Akonadi::Collection::List &list, -+ T ( Akonadi::Collection::*property)() const ) const -+{ -+ std::sort( list.begin(), list.end(), boost::bind( property, _1 ) < boost::bind( property, _2 ) ); -+} -+ -+template -+void XmlOperations::sortCollectionList( Akonadi::Collection::List &list, -+ T ( Akonadi::Entity::*property)() const ) const -+{ -+ std::sort( list.begin(), list.end(), boost::bind( property, _1 ) < boost::bind( property, _2 ) ); -+} -+ - #endif diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/.child1.directory/grandchild/new/.keep kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/.child1.directory/grandchild/new/.keep --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/.child1.directory/grandchild/new/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/.child1.directory/grandchild/new/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/.child1.directory/grandchild/tmp/.keep kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/.child1.directory/grandchild/tmp/.keep --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/.child1.directory/grandchild/tmp/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/.child1.directory/grandchild/tmp/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child2/cur/.keep kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child2/cur/.keep --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child2/cur/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child2/cur/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child2/.keep kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child2/.keep --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child2/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child2/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child2/new/.keep kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child2/new/.keep --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child2/new/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child2/new/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child2/tmp/.keep kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child2/tmp/.keep --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir/.root.directory/child2/tmp/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir/.root.directory/child2/tmp/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir-empty.xml kdepim-runtime-15.08.0/resources/maildir/tests/maildir-empty.xml --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir-empty.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir-empty.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ - - - wcdC - - diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir.js kdepim-runtime-15.08.0/resources/maildir/tests/maildir.js --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir.js 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -Resource.setType( "akonadi_maildir_resource" ); - -// read test -Resource.setPathOption( "Path", "maildir/root" ); -Resource.create(); - -XmlOperations.setXmlFile( "maildir.xml" ); -XmlOperations.setRootCollections( Resource.identifier() ); -XmlOperations.setNormalizeRemoteIds( true ); -XmlOperations.ignoreCollectionField( "Name" ); -XmlOperations.assertEqual(); - -Resource.destroy(); - -// empty maildir -Resource.setPathOption( "Path", "newmaildir" ); -Resource.create(); - -XmlOperations.setXmlFile( "maildir-empty.xml" ); -XmlOperations.setRootCollections( Resource.identifier() ); -XmlOperations.assertEqual(); - -// folder creation -CollectionTest.setParent( Resource.identifier() ); -CollectionTest.addContentType( "message/rfc822" ); -CollectionTest.setName( "test folder" ); -CollectionTest.create(); - -// item creation -ItemTest.setParentCollection( Resource.identifier() + "/test folder" ); -ItemTest.setMimeType( "message/rfc822" ); -ItemTest.setPayloadFromFile( "testmail.mbox" ); -ItemTest.create(); - -Resource.recreate(); - -XmlOperations.setXmlFile( "maildir-step1.xml" ); -XmlOperations.setRootCollections( Resource.identifier() ); -XmlOperations.setItemKey( "None" ); -XmlOperations.ignoreItemField( "RemoteId" ); -XmlOperations.assertEqual(); - -// folder modification -CollectionTest.setCollection( Resource.identifier() + "/test folder" ); -CollectionTest.setName( "changed folder" ); -CollectionTest.update(); - -Resource.recreate(); - -XmlOperations.setXmlFile( "maildir-step2.xml" ); -XmlOperations.setRootCollections( Resource.identifier() ); -XmlOperations.assertEqual(); - -// folder deletion -CollectionTest.setCollection( Resource.identifier() + "/changed folder" ); -CollectionTest.remove(); - -Resource.recreate(); - -XmlOperations.setXmlFile( "maildir-empty.xml" ); -XmlOperations.setRootCollections( Resource.identifier() ); -XmlOperations.assertEqual(); - diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir-step1.xml kdepim-runtime-15.08.0/resources/maildir/tests/maildir-step1.xml --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir-step1.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir-step1.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ - - - wcdC - - - From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h - - - - - diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir-step2.xml kdepim-runtime-15.08.0/resources/maildir/tests/maildir-step2.xml --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir-step2.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir-step2.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ - - - wcdC - - - From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h - - - - - diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/maildir.xml kdepim-runtime-15.08.0/resources/maildir/tests/maildir.xml --- kdepim-runtime-4.14.6/resources/maildir/tests/maildir.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/maildir.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,732 +0,0 @@ - - - wcdC - - - - - Return-Path: <commitfilter@new.kstuff.org> -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; - Sun, 22 Mar 2009 12:10:48 +0100 -X-Sieve: CMU Sieve 2.2 -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id 4BDF8E6C790 - for <asok@kdab.net>; Sun, 22 Mar 2009 12:10:48 +0100 (CET) -Received: from smykowski.kdab.net ([127.0.0.1]) - by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 03694-02 for <asok@kdab.net>; - Sun, 22 Mar 2009 12:10:45 +0100 (CET) -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id B289FE6C79B - for <asok@kdab.net>; Sun, 22 Mar 2009 12:10:45 +0100 (CET) -Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) - by smykowski.kdab.net (Postfix) with ESMTP id 3B465E6C790 - for <asok@kdab.net>; Sun, 22 Mar 2009 12:10:45 +0100 (CET) -Received: from ktown.kde.org ([131.246.120.250]) - by kdeget.osuosl.org with smtp (Exim 4.63) - (envelope-from <kde-commits-bounces-+commitfilter=new.kstuff.org@kde.org>) - id 1LlLfE-0001OT-K7 - for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 12:16:25 +0100 -Received: (qmail 23006 invoked by uid 72); 22 Mar 2009 11:16:19 -0000 -Received: (qmail 22986 invoked from network); 22 Mar 2009 11:16:14 -0000 -Received: from unknown (HELO office.kde.org) (195.135.221.67) - by ktown.kde.org with SMTP; 22 Mar 2009 11:16:11 -0000 -Received: from svn.kde.org (localhost [127.0.0.1]) - by office.kde.org (Postfix) with SMTP id 85EE718E - for <kde-commits@kde.org>; Sun, 22 Mar 2009 12:16:12 +0100 (CET) -Received: (nullmailer pid 13467 invoked by uid 30); - Sun, 22 Mar 2009 11:16:12 -0000 -From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester - trunk/playground/pim/akonaditest/resourcetester/tests -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 11:16:12 +0000 -Message-Id: <1237720572.493438.13466.nullmailer@svn.kde.org> -X-BeenThere: kde-commits@kde.org -X-Mailman-Version: 2.1.9 -Precedence: list -Reply-To: kde-commits@kde.org -List-Id: Notification of KDE commits <kde-commits.kde.org> -List-Unsubscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, - <mailto:kde-commits-request@kde.org?subject=unsubscribe> -List-Post: <mailto:kde-commits@kde.org> -List-Help: <mailto:kde-commits-request@kde.org?subject=help> -List-Subscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, - <mailto:kde-commits-request@kde.org?subject=subscribe> -X-Virus-Scanned: by amavisd-new at kdab.net -X-Kolab-Scheduling-Message: FALSE -X-UID: 26666 -X-Length: 11240 -Status: RO -X-Status: ORC -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -SVN commit 942640 by vkrause: - -Allow to specifiy the collection property used to identify corresponding -collections. - - - M +2 -0 tests/vcardtest.js - M +1 -1 tests/vcardtest.xml - M +29 -14 xmloperations.cpp - M +46 -0 xmloperations.h - - ---- trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest.js #942639:942640 -@@ -4,6 +4,8 @@ - - XmlOperations.setXmlFile( "vcardtest.xml" ); - XmlOperations.setRootCollections( Resource.identifier() ); -+XmlOperations.setCollectionKey( "None" ); // we only expect one collection - XmlOperations.ignoreCollectionField( "Name" ); // name is the resource identifier and thus unpredictable -+XmlOperations.ignoreCollectionField( "RemoteId" ); // remote id is the absolute path - XmlOperations.assertEqual(); - ---- trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest.xml #942639:942640 -@@ -1,5 +1,5 @@ - <knut> -- <collection rid="/k/kde4/src/playground/pim/akonaditest/resourcetester/tests/vcardtest.vcf" name="akonadi_vcard_resource_0" content="text/directory"> -+ <collection rid="vcardtest.vcf" name="akonadi_vcard_resource_0" content="text/directory"> - <attribute type="AccessRights" >wcdW</attribute> - <attribute type="ENTITYDISPLAY" >("vcardtest.vcf" "office-address-book")</attribute> - <item rid="bb2slGmqxb" mimetype="text/directory"> ---- trunk/playground/pim/akonaditest/resourcetester/xmloperations.cpp #942639:942640 -@@ -31,9 +31,6 @@ - #include <QFileInfo> - #include <QStringList> - --#include <boost/bind.hpp> --#include <algorithm> -- - using namespace Akonadi; - - template <typename T> QTextStream& operator<<( QTextStream &s, const QSet<T> &set ) -@@ -53,7 +50,8 @@ - - XmlOperations::XmlOperations(QObject* parent) : - QObject( parent ), -- mCollectionFields( 0xFF ) -+ mCollectionFields( 0xFF ), -+ mCollectionKey( RemoteId ) - { - } - -@@ -99,6 +97,17 @@ - return mErrorMsg; - } - -+void XmlOperations::setCollectionKey(XmlOperations::CollectionField field) -+{ -+ mCollectionKey = field; -+} -+ -+void XmlOperations::setCollectionKey(const QString& fieldName) -+{ -+ const QMetaEnum me = metaObject()->enumerator( metaObject()->indexOfEnumerator( "CollectionField" ) ); -+ setCollectionKey( static_cast<CollectionField>( me.keyToValue( fieldName.toLatin1() ) ) ); -+} -+ - void XmlOperations::ignoreCollectionField(XmlOperations::CollectionField field) - { - mCollectionFields = mCollectionFields & ~field; -@@ -137,8 +146,20 @@ - { - Collection::List cols( _cols ); - Collection::List refCols( _refCols ); -- std::sort( cols.begin(), cols.end(), boost::bind( &Collection::remoteId, _1 ) < boost::bind( &Collection::remoteId, _2 ) ); -- std::sort( refCols.begin(), refCols.end(), boost::bind( &Collection::remoteId, _1 ) < boost::bind( &Collection::remoteId, _2 ) ); -+ switch ( mCollectionKey ) { -+ case RemoteId: -+ sortCollectionList( cols, &Collection::remoteId ); -+ sortCollectionList( refCols, &Collection::remoteId ); -+ break; -+ case Name: -+ sortCollectionList( cols, &Collection::name ); -+ sortCollectionList( refCols, &Collection::name ); -+ break; -+ case None: -+ break; -+ default: -+ Q_ASSERT( false ); -+ } - - for ( int i = 0; i < cols.count(); ++i ) { - const Collection col = cols.at( i ); -@@ -148,11 +169,6 @@ - } - - const Collection refCol = refCols.at( i ); -- if ( col.remoteId() != refCol.remoteId() ) { -- mErrorMsg = QString::fromLatin1( "Collection with remote id '%1' is missing." ).arg( refCol.remoteId() ); -- return false; -- } -- - if ( !compareCollection( col, refCol ) ) - return false; - } -@@ -177,14 +193,13 @@ - - bool XmlOperations::compareCollection(const Collection& _col, const Collection& _refCol) - { -- Q_ASSERT( _col.remoteId() == _refCol.remoteId() ); -- - // normalize - Collection col( normalize( _col ) ); - Collection refCol( normalize( _refCol ) ); - - // compare the two collections -- if ( !compareValue( col, refCol, &Collection::contentMimeTypes, ContentMimeType ) || -+ if ( !compareValue( col, refCol, &Collection::remoteId, RemoteId ) || -+ !compareValue( col, refCol, &Collection::contentMimeTypes, ContentMimeType ) || - !compareValue( col, refCol, &Collection::name, Name ) ) - return false; - ---- trunk/playground/pim/akonaditest/resourcetester/xmloperations.h #942639:942640 -@@ -28,6 +28,10 @@ - #include <QtCore/QObject> - #include <QtCore/QTextStream> - -+#include <boost/bind.hpp> -+#include <algorithm> -+ -+ - /** - Compares a Akonadi collection sub-tree with reference data supplied in an XML file. - */ -@@ -49,6 +53,7 @@ - - Q_DECLARE_FLAGS( CollectionFields, CollectionField ) - -+ void setCollectionKey( CollectionField field ); - void ignoreCollectionField( CollectionField field ); - - public slots: -@@ -59,6 +64,7 @@ - Akonadi::Item getItemByRemoteId(const QString& rid); - Akonadi::Collection getCollectionByRemoteId(const QString& rid); - -+ void setCollectionKey( const QString &fieldName ); - void ignoreCollectionField( const QString &fieldName ); - - bool compare(); -@@ -78,16 +84,25 @@ - template <typename T> bool compareValue( const Akonadi::Collection &col, const Akonadi::Collection &refCol, - T (Akonadi::Collection::*property)() const, - CollectionField propertyType ); -+ template <typename T> bool compareValue( const Akonadi::Collection &col, const Akonadi::Collection &refCol, -+ T (Akonadi::Entity::*property)() const, -+ CollectionField propertyType ); - template <typename T> bool compareValue( const Akonadi::Item& item, const Akonadi::Item& refItem, - T (Akonadi::Item::*property)() const, - const char* propertyName ); - template <typename T> bool compareValue( const T& value, const T& refValue ); - -+ template <typename T> void sortCollectionList( Akonadi::Collection::List &list, -+ T ( Akonadi::Collection::*property)() const ) const; -+ template <typename T> void sortCollectionList( Akonadi::Collection::List &list, -+ T ( Akonadi::Entity::*property)() const ) const; -+ - private: - Akonadi::Collection::List mRoots; - Akonadi::XmlDocument mDocument; - QString mErrorMsg; - CollectionFields mCollectionFields; -+ CollectionField mCollectionKey; - }; - - -@@ -109,6 +124,23 @@ - } - - template <typename T> -+bool XmlOperations::compareValue( const Akonadi::Collection& col, const Akonadi::Collection& refCol, -+ T (Akonadi::Entity::*property)() const, -+ CollectionField propertyType ) -+{ -+ if ( mCollectionFields & propertyType ) { -+ const bool result = compareValue<T>( ((col).*(property))(), ((refCol).*(property))() ); -+ if ( !result ) { -+ const QMetaEnum me = metaObject()->enumerator( metaObject()->indexOfEnumerator( "CollectionField" ) ); -+ mErrorMsg.prepend( QString::fromLatin1( "Collection with remote id '%1' differs in property '%2':\n" ) -+ .arg( col.remoteId() ).arg( me.valueToKey( propertyType ) ) ); -+ } -+ return result; -+ } -+ return true; -+} -+ -+template <typename T> - bool XmlOperations::compareValue( const Akonadi::Item& item, const Akonadi::Item& refItem, - T (Akonadi::Item::*property)() const, - const char* propertyName ) -@@ -131,4 +163,18 @@ - return false; - } - -+template <typename T> -+void XmlOperations::sortCollectionList( Akonadi::Collection::List &list, -+ T ( Akonadi::Collection::*property)() const ) const -+{ -+ std::sort( list.begin(), list.end(), boost::bind( property, _1 ) < boost::bind( property, _2 ) ); -+} -+ -+template <typename T> -+void XmlOperations::sortCollectionList( Akonadi::Collection::List &list, -+ T ( Akonadi::Entity::*property)() const ) const -+{ -+ std::sort( list.begin(), list.end(), boost::bind( property, _1 ) < boost::bind( property, _2 ) ); -+} -+ - #endif - - - - - Return-Path: <commitfilter@new.kstuff.org> -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; - Sun, 22 Mar 2009 12:55:23 +0100 -X-Sieve: CMU Sieve 2.2 -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id EF869E6C77A - for <asok@kdab.net>; Sun, 22 Mar 2009 12:55:22 +0100 (CET) -Received: from smykowski.kdab.net ([127.0.0.1]) - by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 06346-10 for <asok@kdab.net>; - Sun, 22 Mar 2009 12:55:21 +0100 (CET) -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id 24127E6C79E - for <asok@kdab.net>; Sun, 22 Mar 2009 12:55:21 +0100 (CET) -Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) - by smykowski.kdab.net (Postfix) with ESMTP id D175FE6C77A - for <asok@kdab.net>; Sun, 22 Mar 2009 12:55:20 +0100 (CET) -Received: from ktown.kde.org ([131.246.120.250]) - by kdeget.osuosl.org with smtp (Exim 4.63) - (envelope-from <kde-commits-bounces-+commitfilter=new.kstuff.org@kde.org>) - id 1LlMMP-0003EH-9D - for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 13:01:02 +0100 -Received: (qmail 14097 invoked by uid 72); 22 Mar 2009 12:00:55 -0000 -Received: (qmail 14075 invoked from network); 22 Mar 2009 12:00:53 -0000 -Received: from unknown (HELO office.kde.org) (195.135.221.67) - by ktown.kde.org with SMTP; 22 Mar 2009 12:00:51 -0000 -Received: from svn.kde.org (localhost [127.0.0.1]) - by office.kde.org (Postfix) with SMTP id 0F54D18E - for <kde-commits@kde.org>; Sun, 22 Mar 2009 13:00:53 +0100 (CET) -Received: (nullmailer pid 17237 invoked by uid 30); - Sun, 22 Mar 2009 12:00:53 -0000 -From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester - trunk/playground/pim/akonaditest/resourcetester/tests -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:00:53 +0000 -Message-Id: <1237723253.005953.17235.nullmailer@svn.kde.org> -X-BeenThere: kde-commits@kde.org -X-Mailman-Version: 2.1.9 -Precedence: list -Reply-To: kde-commits@kde.org -List-Id: Notification of KDE commits <kde-commits.kde.org> -List-Unsubscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, - <mailto:kde-commits-request@kde.org?subject=unsubscribe> -List-Post: <mailto:kde-commits@kde.org> -List-Help: <mailto:kde-commits-request@kde.org?subject=help> -List-Subscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, - <mailto:kde-commits-request@kde.org?subject=subscribe> -X-Virus-Scanned: by amavisd-new at kdab.net -X-Kolab-Scheduling-Message: FALSE -X-UID: 26667 -X-Length: 4226 -Status: RO -X-Status: ORC -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -SVN commit 942650 by vkrause: - -Add CMake macro to run resource tests. - - - M +20 -0 CMakeLists.txt - A tests/CMakeLists.txt - AM tests/vcardtest-readonly.js tests/vcardtest.js#942640 - AM tests/vcardtest-readonly.xml tests/vcardtest.xml#942640 - - ---- trunk/playground/pim/akonaditest/resourcetester/CMakeLists.txt #942649:942650 -@@ -17,6 +17,26 @@ - - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - -+macro( akonadi_add_resourcetest _testname _script ) -+ if ( ${EXECUTABLE_OUTPUT_PATH} ) -+ set( _exepath ${EXECUTABLE_OUTPUT_PATH} ) -+ else ( ${EXECUTABLE_OUTPUT_PATH} ) -+ set( _exepath ${CMAKE_CURRENT_BINARY_DIR}/.. ) -+ endif ( ${EXECUTABLE_OUTPUT_PATH} ) -+ if (WIN32) -+ set(_resourcetester ${_exepath}/resourcetester.bat) -+ else (WIN32) -+ set(_resourcetester ${_exepath}/resourcetester) -+ endif (WIN32) -+ if (UNIX) -+ set(_resourcetester ${_resourcetester}.shell) -+ endif (UNIX) -+ -+ add_test( ${_testname} ${_resourcetester} -c ${CMAKE_CURRENT_SOURCE_DIR}/${_script} ) -+endmacro( akonadi_add_resourcetest ) -+ -+add_subdirectory( tests ) -+ - set( resourcetester_SRCS - global.cpp - main.cpp -** trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest-readonly.js #property svn:mergeinfo - + -** trunk/playground/pim/akonaditest/resourcetester/tests/vcardtest-readonly.xml #property svn:mergeinfo - + - - - - Return-Path: <commitfilter@new.kstuff.org> -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; - Sun, 22 Mar 2009 13:16:01 +0100 -X-Sieve: CMU Sieve 2.2 -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id CA2E8E6C783 - for <asok@kdab.net>; Sun, 22 Mar 2009 13:16:00 +0100 (CET) -Received: from smykowski.kdab.net ([127.0.0.1]) - by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 07855-05 for <asok@kdab.net>; - Sun, 22 Mar 2009 13:15:58 +0100 (CET) -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id ABDFDE6C79B - for <asok@kdab.net>; Sun, 22 Mar 2009 13:15:58 +0100 (CET) -Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) - by smykowski.kdab.net (Postfix) with ESMTP id 5CD44E6C783 - for <asok@kdab.net>; Sun, 22 Mar 2009 13:15:58 +0100 (CET) -Received: from ktown.kde.org ([131.246.120.250]) - by kdeget.osuosl.org with smtp (Exim 4.63) - (envelope-from <kde-commits-bounces-+commitfilter=new.kstuff.org@kde.org>) - id 1LlMgP-00046D-6T - for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 13:21:41 +0100 -Received: (qmail 27078 invoked by uid 72); 22 Mar 2009 12:21:36 -0000 -Received: (qmail 27060 invoked from network); 22 Mar 2009 12:21:34 -0000 -Received: from unknown (HELO office.kde.org) (195.135.221.67) - by ktown.kde.org with SMTP; 22 Mar 2009 12:21:32 -0000 -Received: from svn.kde.org (localhost [127.0.0.1]) - by office.kde.org (Postfix) with SMTP id 0A38E18E - for <kde-commits@kde.org>; Sun, 22 Mar 2009 13:21:34 +0100 (CET) -Received: (nullmailer pid 20237 invoked by uid 30); - Sun, 22 Mar 2009 12:21:34 -0000 -From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:21:34 +0000 -Message-Id: <1237724494.009832.20236.nullmailer@svn.kde.org> -X-BeenThere: kde-commits@kde.org -X-Mailman-Version: 2.1.9 -Precedence: list -Reply-To: kde-commits@kde.org -List-Id: Notification of KDE commits <kde-commits.kde.org> -List-Unsubscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, - <mailto:kde-commits-request@kde.org?subject=unsubscribe> -List-Post: <mailto:kde-commits@kde.org> -List-Help: <mailto:kde-commits-request@kde.org?subject=help> -List-Subscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, - <mailto:kde-commits-request@kde.org?subject=subscribe> -X-Virus-Scanned: by amavisd-new at kdab.net -X-Kolab-Scheduling-Message: FALSE -X-UID: 26668 -X-Length: 4765 -Status: RO -X-Status: ORC -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -SVN commit 942656 by vkrause: - -- propagate script errors -- make sure the Akonadi server is operational - - - M +5 -0 main.cpp - M +13 -1 script.cpp - M +6 -3 script.h - - ---- trunk/playground/pim/akonaditest/resourcetester/main.cpp #942655:942656 -@@ -21,6 +21,8 @@ - #include "global.h" - #include "test.h" - -+#include <akonadi/control.h> -+ - #include <KApplication> - #include <KAboutData> - #include <KCmdLineArgs> -@@ -71,6 +73,9 @@ - signal( SIGQUIT, sigHandler ); - #endif - -+ if ( !Akonadi::Control::start() ) -+ qFatal( "Unable to start Akonadi!" ); -+ - Script *script = new Script(); - - script->configure(path); ---- trunk/playground/pim/akonaditest/resourcetester/script.cpp #942655:942656 -@@ -16,12 +16,13 @@ - */ - - #include "script.h" -+#include <KDebug> - #include <qcoreapplication.h> - - Script::Script() - { - action = new Kross::Action(this, "ResourceTester"); -- connect( action, SIGNAL(finished(Kross::Action*)), QCoreApplication::instance(), SLOT(quit()) ); -+ connect( action, SIGNAL(finished(Kross::Action*)), SLOT(finished(Kross::Action*)) ); - } - - void Script::configure(const QString &path, QHash<QString, QObject * > hash) -@@ -51,4 +52,15 @@ - action->trigger(); - } - -+void Script::finished(Kross::Action* action) -+{ -+ if ( action->hadError() ) { -+ kError() << action->errorMessage() << action->errorTrace(); -+ QCoreApplication::instance()->exit( 1 ); -+ } else { -+ QCoreApplication::instance()->quit(); -+ } -+} -+ -+ - #include "script.moc" ---- trunk/playground/pim/akonaditest/resourcetester/script.h #942655:942656 -@@ -24,9 +24,6 @@ - class Script : public QObject - { - Q_OBJECT -- private: -- Kross::Action *action; -- - public: - Script(); - void configure(const QString &path, QHash<QString, QObject *> hash); -@@ -35,6 +32,12 @@ - - public slots: - void start(); -+ -+ private slots: -+ void finished( Kross::Action *action ); -+ -+ private: -+ Kross::Action *action; - }; - - #endif - - - - - Return-Path: <commitfilter@new.kstuff.org> -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Cyrus v2.2.12) with LMTPA; - Sun, 22 Mar 2009 13:45:00 +0100 -X-Sieve: CMU Sieve 2.2 -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id 8C4FFE6C79B - for <asok@kdab.net>; Sun, 22 Mar 2009 13:45:00 +0100 (CET) -Received: from smykowski.kdab.net ([127.0.0.1]) - by localhost (smykowski.kdab.net [127.0.0.1]) (amavisd-new, port 10024) - with ESMTP id 09703-05 for <asok@kdab.net>; - Sun, 22 Mar 2009 13:45:00 +0100 (CET) -Received: from localhost (localhost [127.0.0.1]) - by smykowski.kdab.net (Postfix) with ESMTP id 163D2E6C7AF - for <asok@kdab.net>; Sun, 22 Mar 2009 13:45:00 +0100 (CET) -Received: from kdeget.osuosl.org (kdeget.osuosl.org [140.211.166.77]) - by smykowski.kdab.net (Postfix) with ESMTP id 31945E6C79E - for <asok@kdab.net>; Sun, 22 Mar 2009 13:44:59 +0100 (CET) -Received: from ktown.kde.org ([131.246.120.250]) - by kdeget.osuosl.org with smtp (Exim 4.63) - (envelope-from <kde-commits-bounces-+commitfilter=new.kstuff.org@kde.org>) - id 1LlN8R-0005Jr-VE - for commitfilter@new.kstuff.org; Sun, 22 Mar 2009 13:50:40 +0100 -Received: (qmail 7667 invoked by uid 72); 22 Mar 2009 12:50:33 -0000 -Received: (qmail 7658 invoked from network); 22 Mar 2009 12:50:31 -0000 -Received: from unknown (HELO office.kde.org) (195.135.221.67) - by ktown.kde.org with SMTP; 22 Mar 2009 12:50:29 -0000 -Received: from svn.kde.org (localhost [127.0.0.1]) - by office.kde.org (Postfix) with SMTP id 93E9F18E - for <kde-commits@kde.org>; Sun, 22 Mar 2009 13:50:30 +0100 (CET) -Received: (nullmailer pid 25707 invoked by uid 30); - Sun, 22 Mar 2009 12:50:30 -0000 -From: Volker Krause <vkrause@kde.org> -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -X-Commit-Directories: (0) trunk/playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> -X-BeenThere: kde-commits@kde.org -X-Mailman-Version: 2.1.9 -Precedence: list -Reply-To: kde-commits@kde.org -List-Id: Notification of KDE commits <kde-commits.kde.org> -List-Unsubscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, - <mailto:kde-commits-request@kde.org?subject=unsubscribe> -List-Post: <mailto:kde-commits@kde.org> -List-Help: <mailto:kde-commits-request@kde.org?subject=help> -List-Subscribe: <https://mail.kde.org/mailman/listinfo/kde-commits>, - <mailto:kde-commits-request@kde.org?subject=subscribe> -X-Virus-Scanned: by amavisd-new at kdab.net -X-Kolab-Scheduling-Message: FALSE -X-UID: 26669 -X-Length: 5694 -Status: RO -X-Status: RC -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h - - ---- trunk/playground/pim/akonaditest/resourcetester/resourcesynchronizationjob.cpp #942676:942677 -@@ -18,12 +18,14 @@ - #include "resourcesynchronizationjob.h" - - #include <akonadi/agentinstance.h> -+#include <akonadi/agentmanager.h> - - #include <KDebug> - #include <KLocale> - - #include <QDBusConnection> - #include <QDBusInterface> -+#include <QTimer> - - namespace Akonadi - { -@@ -31,15 +33,31 @@ - class ResourceSynchronizationJobPrivate - { - public: -+ ResourceSynchronizationJobPrivate() : -+ interface( 0 ), -+ safetyTimer( 0 ), -+ timeoutCount( 0 ) -+ {} -+ - AgentInstance instance; - QDBusInterface* interface; -+ QTimer* safetyTimer; -+ int timeoutCount; -+ static int timeoutCountLimit; - }; - -+int ResourceSynchronizationJobPrivate::timeoutCountLimit = 60; -+ - ResourceSynchronizationJob::ResourceSynchronizationJob(const AgentInstance& instance, QObject* parent) : - KJob( parent ), - d( new ResourceSynchronizationJobPrivate ) - { - d->instance = instance; -+ d->safetyTimer = new QTimer( this ); -+ connect( d->safetyTimer, SIGNAL(timeout()), SLOT(slotTimeout()) ); -+ d->safetyTimer->setInterval( 10 * 1000 ); -+ d->safetyTimer->setSingleShot( false ); -+ d->safetyTimer->start(); - } - - ResourceSynchronizationJob::~ResourceSynchronizationJob() -@@ -72,9 +90,31 @@ - - void ResourceSynchronizationJob::slotSynchronized() - { -+ disconnect( d->interface, SIGNAL(synchronized()), this, SLOT(slotSynchronized()) ); -+ d->safetyTimer->stop(); - emitResult(); - } - -+void ResourceSynchronizationJob::slotTimeout() -+{ -+ d->instance = AgentManager::self()->instance( d->instance.identifier() ); -+ d->timeoutCount++; -+ -+ if ( d->timeoutCount > d->timeoutCountLimit ) { -+ d->safetyTimer->stop(); -+ setError( UserDefinedError ); -+ setErrorText( i18n( "Resource synchronization timed out." ) ); -+ emitResult(); -+ return; -+ } -+ -+ if ( d->instance.status() == AgentInstance::Idle ) { -+ // try again, we might have lost the synchronized() signal -+ kDebug() << "trying again to sync resource" << d->instance.identifier(); -+ d->instance.synchronize(); -+ } - } - -+} -+ - #include "resourcesynchronizationjob.moc" ---- trunk/playground/pim/akonaditest/resourcetester/resourcesynchronizationjob.h #942676:942677 -@@ -27,7 +27,6 @@ - - /** - Synchronizes a given resource. -- @todo Add safety timeouts. - */ - class ResourceSynchronizationJob : public KJob - { -@@ -48,6 +47,7 @@ - - private slots: - void slotSynchronized(); -+ void slotTimeout(); - - private: - ResourceSynchronizationJobPrivate* const d; - - - - diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/synctest.cpp kdepim-runtime-15.08.0/resources/maildir/tests/synctest.cpp --- kdepim-runtime-4.14.6/resources/maildir/tests/synctest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/synctest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -/* - Copyright 2009 Constantin Berzan - - 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 "synctest.h" - -#include -#include - -#include - -#include -#include -#include -#include - -#define TIMES 100 // How many times to sync. -#define TIMEOUT 10 // How many seconds to wait before declaring the resource dead. - -using namespace Akonadi; - -void SyncTest::initTestCase() -{ - QVERIFY( Control::start() ); - QTest::qWait( 1000 ); -} - -void SyncTest::testSync() -{ - AgentInstance instance = AgentManager::self()->instance( "akonadi_maildir_resource_0" ); - QVERIFY( instance.isValid() ); - - for ( int i = 0; i < 100; i++ ) { - QDBusInterface *interface = new QDBusInterface( - QString::fromLatin1( "org.freedesktop.Akonadi.Resource.%1" ).arg( instance.identifier() ), - "/", "org.freedesktop.Akonadi.Resource", QDBusConnection::sessionBus(), this ); - QVERIFY( interface->isValid() ); - QTime t; - t.start(); - instance.synchronize(); - QVERIFY( QTest::kWaitForSignal( interface, SIGNAL(synchronized()), TIMEOUT * 1000 ) ); - kDebug() << "Sync attempt" << i << "in" << t.elapsed() << "ms."; - } -} - -QTEST_AKONADIMAIN( SyncTest, NoGUI ) - diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/synctest.h kdepim-runtime-15.08.0/resources/maildir/tests/synctest.h --- kdepim-runtime-4.14.6/resources/maildir/tests/synctest.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/synctest.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/* - Copyright 2009 Constantin Berzan - - 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 SYNCTEST_H -#define SYNCTEST_H - -#include - -#include - -/** - This syncs the resource again and again, watching out for "lost" - synchronized() signals. - */ -class SyncTest : public QObject -{ - Q_OBJECT - - private Q_SLOTS: - void initTestCase(); - void testSync(); - - private: - -}; - - -#endif diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/testmail.mbox kdepim-runtime-15.08.0/resources/maildir/tests/testmail.mbox --- kdepim-runtime-4.14.6/resources/maildir/tests/testmail.mbox 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/testmail.mbox 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -From: Volker Krause -To: kde-commits@kde.org -Subject: playground/pim/akonaditest/resourcetester -MIME-Version: 1.0 -Content-Type: text/plain; - charset=UTF-8 -Content-Transfer-Encoding: 8bit -Date: Sun, 22 Mar 2009 12:50:30 +0000 -Message-Id: <1237726230.394911.25706.nullmailer@svn.kde.org> - -SVN commit 942677 by vkrause: - -Add a safety timeout in case we do not receive the synchronized() signal -or the resource hangs during syncing. The first seems to happen randomly -if syncing is extremely fast. - - - M +40 -0 resourcesynchronizationjob.cpp - M +1 -1 resourcesynchronizationjob.h diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/config.xml kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/config.xml --- kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/config.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/config.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ - - kdehome - xdgconfig - xdglocal - akonadi_maildir_resource - diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc --- kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[ProcessedDefaults] -defaultaddressbook=done -defaultcalendar=done diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/kdehome/share/config/akonadi_maildir_resource_0rc kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/kdehome/share/config/akonadi_maildir_resource_0rc --- kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/kdehome/share/config/akonadi_maildir_resource_0rc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/kdehome/share/config/akonadi_maildir_resource_0rc 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -[General] -Path[$e]=$HOME/.local/share/mail diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/kdehome/share/config/kdebugrc kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/kdehome/share/config/kdebugrc --- kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/kdehome/share/config/kdebugrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/kdehome/share/config/kdebugrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,110 +0,0 @@ -[0] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[5250] -InfoOutput=2 - -[5251] -InfoOutput=2 - -[5252] -InfoOutput=2 - -[5253] -InfoOutput=2 - -[5254] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[5255] -InfoOutput=2 - -[5256] -InfoOutput=2 - -[5257] -InfoOutput=2 - -[5258] -InfoOutput=2 - -[5259] -InfoOutput=2 - -[5260] -InfoOutput=2 - -[5261] -InfoOutput=2 - -[5262] -InfoOutput=2 - -[5263] -InfoOutput=2 - -[5264] -InfoOutput=2 - -[5265] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[5266] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[5295] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[5324] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[7129] -InfoOutput=2 diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/kdehome/share/config/kdedrc kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/kdehome/share/config/kdedrc --- kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/kdehome/share/config/kdedrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/kdehome/share/config/kdedrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[General] -CheckSycoca=false -CheckFileStamps=false diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/kdehome/share/config/kwalletrc kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/kdehome/share/config/kwalletrc --- kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/kdehome/share/config/kwalletrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/kdehome/share/config/kwalletrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -[Wallet] -Enabled=false diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/kdehome/share/config/qttestrc kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/kdehome/share/config/qttestrc --- kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/kdehome/share/config/qttestrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/kdehome/share/config/qttestrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -[Notification Messages] -WalletMigrate=false diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/kdehome/testdata.xml kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/kdehome/testdata.xml --- kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/kdehome/testdata.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/kdehome/testdata.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ - - - - diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -[%General] - -[Search] -Manager=Dummy diff -Nru kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/xdglocal/.keep kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/xdglocal/.keep --- kdepim-runtime-4.14.6/resources/maildir/tests/unittestenv/xdglocal/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/tests/unittestenv/xdglocal/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/maildir/wizard/CMakeLists.txt kdepim-runtime-15.08.0/resources/maildir/wizard/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/maildir/wizard/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/wizard/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,2 +1,2 @@ -install ( FILES maildirwizard.desktop maildirwizard.es maildirwizard.ui DESTINATION ${DATA_INSTALL_DIR}/akonadi/accountwizard/maildir ) +install ( FILES maildirwizard.desktop maildirwizard.es maildirwizard.ui DESTINATION ${KDE_INSTALL_DATADIR}/akonadi/accountwizard/maildir ) diff -Nru kdepim-runtime-4.14.6/resources/maildir/wizard/maildirwizard.desktop kdepim-runtime-15.08.0/resources/maildir/wizard/maildirwizard.desktop --- kdepim-runtime-4.14.6/resources/maildir/wizard/maildirwizard.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/maildir/wizard/maildirwizard.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -51,6 +51,7 @@ Name[zh_TW]=Maildir Icon=message-rfc822 Comment=Maildir account +Comment[bg]=Сметка Maildir Comment[bs]=Maildir nalog Comment[ca]=Compte Maildir Comment[ca@valencia]=Compte Maildir diff -Nru kdepim-runtime-4.14.6/resources/mailtransport_dummy/CMakeLists.txt kdepim-runtime-15.08.0/resources/mailtransport_dummy/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/mailtransport_dummy/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mailtransport_dummy/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -set( mtdummyresource_SRCS - configdialog.cpp - mtdummyresource.cpp -) - -# mailtransport debug area -add_definitions(-DKDE_DEFAULT_DEBUG_AREA=5324) - -install( FILES mtdummyresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) - -kde4_add_ui_files(mtdummyresource_SRCS settings.ui) -kde4_add_kcfg_files(mtdummyresource_SRCS settings.kcfgc) -kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/mtdummyresource.kcfg org.kde.Akonadi.MailTransportDummy.Settings) -qt4_add_dbus_adaptor(mtdummyresource_SRCS - ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.MailTransportDummy.Settings.xml settings.h Settings -) - -kde4_add_executable(akonadi_mailtransport_dummy_resource ${mtdummyresource_SRCS}) - -target_link_libraries(akonadi_mailtransport_dummy_resource ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTDBUS_LIBRARY} ${KDE4_KDECORE_LIBS} ${KDE4_KDEUI_LIBS}) - -install(TARGETS akonadi_mailtransport_dummy_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/mailtransport_dummy/configdialog.cpp kdepim-runtime-15.08.0/resources/mailtransport_dummy/configdialog.cpp --- kdepim-runtime-4.14.6/resources/mailtransport_dummy/configdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mailtransport_dummy/configdialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* - Copyright 2008 Ingo Klöcker - - 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 "configdialog.h" -#include "settings.h" - -#include -#include - -using namespace Akonadi; - -ConfigDialog::ConfigDialog(QWidget * parent) : - KDialog( parent ) -{ - ui.setupUi( mainWidget() ); - - ui.sink->setMimeTypeFilter( QStringList() << QLatin1String( "message/rfc822" ) ); - ui.sink->setAccessRightsFilter( Akonadi::Collection::CanCreateItem ); - // Don't bother fetching the collection. Will have an empty name :-/ - ui.sink->setCollection( Collection( Settings::self()->sink() ) ); - ui.sink->changeCollectionDialogOptions( Akonadi::CollectionDialog::AllowToCreateNewChildCollection ); - kDebug() << "Sink from settings" << Settings::self()->sink(); - - connect( this, SIGNAL(okClicked()), this, SLOT(save()) ); - connect( ui.sink, SIGNAL(collectionChanged(Akonadi::Collection)), this, SLOT(slotCollectionChanged(Akonadi::Collection)) ); - enableButtonOk(false); -} - -void ConfigDialog::slotCollectionChanged( const Akonadi::Collection& col ) -{ - enableButtonOk(col.isValid()); -} - -void ConfigDialog::save() -{ - kDebug() << "Sink changed to" << ui.sink->collection().id(); - Settings::self()->setSink( ui.sink->collection().id() ); - Settings::self()->writeConfig(); -} - diff -Nru kdepim-runtime-4.14.6/resources/mailtransport_dummy/configdialog.h kdepim-runtime-15.08.0/resources/mailtransport_dummy/configdialog.h --- kdepim-runtime-4.14.6/resources/mailtransport_dummy/configdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mailtransport_dummy/configdialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -/* - Copyright 2009 Constantin Berzan - - 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 CONFIGDIALOG_H -#define CONFIGDIALOG_H - -#include - -#include "ui_settings.h" - - - -class ConfigDialog : public KDialog -{ - Q_OBJECT - public: - ConfigDialog( QWidget *parent = 0 ); - - private slots: - void save(); - void slotCollectionChanged(const Akonadi::Collection& ); - private: - Ui::ConfigDialog ui; - -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/mailtransport_dummy/Messages.sh kdepim-runtime-15.08.0/resources/mailtransport_dummy/Messages.sh --- kdepim-runtime-4.14.6/resources/mailtransport_dummy/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mailtransport_dummy/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -#! /usr/bin/env bash -$EXTRACTRC *.ui *.kcfg >> rc.cpp -$XGETTEXT *.cpp -o $podir/akonadi_mailtransport_resource.pot diff -Nru kdepim-runtime-4.14.6/resources/mailtransport_dummy/mtdummyresource.cpp kdepim-runtime-15.08.0/resources/mailtransport_dummy/mtdummyresource.cpp --- kdepim-runtime-4.14.6/resources/mailtransport_dummy/mtdummyresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mailtransport_dummy/mtdummyresource.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ -/* - Copyright 2009 Constantin Berzan - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "mtdummyresource.h" - -#include "configdialog.h" -#include "settings.h" -#include "settingsadaptor.h" - -#include - -#include - -#include - -using namespace Akonadi; - -MTDummyResource::MTDummyResource( const QString &id ) - : ResourceBase( id ) -{ - KGlobal::locale()->insertCatalog( QLatin1String("akonadi_mailtransport_resource") ); - new SettingsAdaptor( Settings::self() ); - QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ), - Settings::self(), QDBusConnection::ExportAdaptors ); - currentlySending = -1; -} - -MTDummyResource::~MTDummyResource() -{ -} - -void MTDummyResource::retrieveCollections() -{ - // we have no collections of our own - collectionsRetrieved( Collection::List() ); -} - -void MTDummyResource::retrieveItems( const Akonadi::Collection &collection ) -{ - Q_UNUSED( collection ); - // we have no collections of our own - Q_ASSERT( false ); -} - -bool MTDummyResource::retrieveItem( const Akonadi::Item &item, const QSet &parts ) -{ - Q_UNUSED( item ); - Q_UNUSED( parts ); - // we have no collections of our own - Q_ASSERT( false ); - return false; -} - -void MTDummyResource::aboutToQuit() -{ -} - -void MTDummyResource::configure( WId windowId ) -{ - ConfigDialog dlg; - if ( windowId ) - KWindowSystem::setMainWindow( &dlg, windowId ); - - if ( dlg.exec() ) { - emit configurationDialogAccepted(); - } else { - emit configurationDialogRejected(); - } -} - -void MTDummyResource::sendItem( const Item &message ) -{ - kDebug() << "id" << message.id(); - Q_ASSERT( currentlySending == -1 ); - currentlySending = message.id(); - ItemCopyJob *job = new ItemCopyJob( message, Collection( Settings::self()->sink() ) ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(jobResult(KJob*)) ); -} - -void MTDummyResource::jobResult( KJob *job ) -{ - if( job->error() ) { - itemSent( Item( currentlySending ), TransportFailed, job->errorString() ); - } else { - itemSent( Item( currentlySending ), TransportSucceeded ); - } - currentlySending = -1; -} - -AKONADI_RESOURCE_MAIN( MTDummyResource ) - diff -Nru kdepim-runtime-4.14.6/resources/mailtransport_dummy/mtdummyresource.desktop kdepim-runtime-15.08.0/resources/mailtransport_dummy/mtdummyresource.desktop --- kdepim-runtime-4.14.6/resources/mailtransport_dummy/mtdummyresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mailtransport_dummy/mtdummyresource.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,90 +0,0 @@ -[Desktop Entry] -Name=Dummy MailTransport Resource -Name[bs]=Vještački resurs za transport maila -Name[ca]=Recurs de transport de correu simulat -Name[ca@valencia]=Recurs de transport de correu simulat -Name[da]=MailTransport-ressource (attrap) -Name[de]=Dummy MailTransport-Ressource -Name[el]=Εικονικός πόρος MailTransport -Name[en_GB]=Dummy MailTransport Resource -Name[es]=Recurso de transporte de correo vacío para pruebas -Name[et]=Kirjade edastamine libaressurss -Name[fi]=Tyhjä MailTransport-resurssi -Name[fr]=Ressource de test pour le transport de courriers électroniques -Name[gl]=Recurso de transporte de correo parvo -Name[hu]=Üres levéltovábbító erőforrás -Name[ia]=Ressource de Dummy MailTransport -Name[it]=Risorsa MailTransport fittizia -Name[kk]=Сынақ MailTransport ресурсы -Name[km]=ធនធាន MailTransport សម្រាប់​អ្នក​មិន​ចេះ -Name[ko]=더미 MailTransport 자원 -Name[lt]=Fiktyvus pašto transporto resursus -Name[lv]=MailTransport resursa imitācija -Name[nb]=Attrapp-ressurs for e-posttransport -Name[nds]=Platzholl-Nettpostöverdreegmetoden-Ressource -Name[nl]=Dummy e-mailtransporthulpmiddel -Name[nn]=Testressurs for e-posttransport -Name[pl]=Prosty zasób metody przekazywania poczty -Name[pt]=Recurso de Transporte de Correio para Testes -Name[pt_BR]=Recurso de transporte de e-mails para testes -Name[ru]=Фиктивный источник данных почтового транспорта -Name[sk]=Prázdny zdroj prenosu pošty -Name[sl]=Lažen vir MailTransport -Name[sr]=Лажни ресурс поштанског транспорта -Name[sr@ijekavian]=Лажни ресурс поштанског транспорта -Name[sr@ijekavianlatin]=Lažni resurs poštanskog transporta -Name[sr@latin]=Lažni resurs poštanskog transporta -Name[sv]=E-postsändningsresurs för test -Name[tr]=Boş MailTransport Kaynağı -Name[uk]=Тестовий ресурс MailTransport -Name[x-test]=xxDummy MailTransport Resourcexx -Name[zh_CN]=虚拟邮件传输资源 -Name[zh_TW]=空白郵件傳輸資源 -Comment=Dummy Resource implementing mail transport interface -Comment[bs]=Vještački resurs implementira sučelje mail transporta -Comment[ca]=Implementació de recurs simulat d'interfície de transport de correu -Comment[ca@valencia]=Implementació de recurs simulat d'interfície de transport de correu -Comment[da]=Attrap-ressource der implementerer mail-transport-grænseflade -Comment[de]=Dummy-Ressource, die die Mail-Transport-Schnittstelle implementiert -Comment[el]=Εικονικός πόρος που υλοποιεί την διεπαφή mail transport -Comment[en_GB]=Dummy Resource implementing mail transport interface -Comment[es]=Recurso vacío que implementa una interfaz de transporte de correo -Comment[et]=Kirjade edastamise liidese libaressurss -Comment[fi]=Tyhjä postinvälitysliitännän toteuttava resurssi -Comment[fr]=Ressource de test implémentant l'interface de transport de courriers électroniques -Comment[gl]=Recurso parvo que aporta a interface de transporte de correo -Comment[hu]=A levéltovábbító interfészt implementáló üres erőforrás -Comment[ia]=Inferfacie pro facer possibile transporto de posta como Dummy Resource -Comment[it]=Risorsa fittizia che implementa l'interfaccia di trasporto della posta -Comment[kk]=Пошта тасымалдау интерфейсінің сынақ MailTransport ресурсы -Comment[km]=ចំណុច​ប្រទាក់​បញ្ជូន​សំបុត្រ​ដោយ​អនុវត្ត​ធនធាន​ពី​ដំបូង -Comment[ko]=메일 전송 인터페이스를 구현하는 더미 자원 -Comment[lt]=Fiktyvus resursas, įgyvendinantis pašto transporto sąsają -Comment[lv]=Resursa imitācija, kas realizē pasta transporta saskarni -Comment[nb]=Attrappressurs som implementerer grensesnitt for e-posttransport -Comment[nds]=Platzhollressource mit inbuut Nettpostöverdreegmetood-Koppelsteed -Comment[nl]=Dummy hulpmiddel die een e-mailtransportinterface implementeert -Comment[nn]=Testressurs som tek i bruk eit grensesnitt for e-posttransport -Comment[pl]=Prosty zasób implementujący interfejs do przekazywania poczty -Comment[pt]=Uma interface de transporte de correio que implementa um recurso de testes -Comment[pt_BR]=Interface de transporte de e-mails que implementa um recurso de testes -Comment[ru]="Фиктивный источник данных, реализующий интерфейс почтового транспорта" -Comment[sk]=Prázdny zdroj implementujúci rozhranie prenosu pošty -Comment[sl]=Lažen vir z izvedbo vmesnika za prenos pošte -Comment[sr]=Лажни ресурс који изводи сучеље мрежног транспорта -Comment[sr@ijekavian]=Лажни ресурс који изводи сучеље мрежног транспорта -Comment[sr@ijekavianlatin]=Lažni resurs koji izvodi sučelje mrežnog transporta -Comment[sr@latin]=Lažni resurs koji izvodi sučelje mrežnog transporta -Comment[sv]=Testresurs som implementerar gränssnitt för e-postöverföring -Comment[tr]=Posta nakletme arayüzünü gerçekleyen boş kaynak -Comment[uk]="Тестовий ресурс, що реалізує інтерфейс пересилання пошти" -Comment[x-test]=xxDummy Resource implementing mail transport interfacexx -Comment[zh_CN]=实现了邮件传输接口的虚拟资源 -Comment[zh_TW]=空白資源,用於實作郵件傳輸介面 -Type=AkonadiResource -Exec=akonadi_mailtransport_dummy_resource -Icon=message-rfc822 - -X-Akonadi-MimeTypes=message/rfc822 -X-Akonadi-Capabilities=Resource,MailTransport -X-Akonadi-Identifier=akonadi_mailtransport_dummy_resource diff -Nru kdepim-runtime-4.14.6/resources/mailtransport_dummy/mtdummyresource.h kdepim-runtime-15.08.0/resources/mailtransport_dummy/mtdummyresource.h --- kdepim-runtime-4.14.6/resources/mailtransport_dummy/mtdummyresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mailtransport_dummy/mtdummyresource.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -/* - Copyright 2009 Constantin Berzan - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 MTDUMMYRESOURCE_H -#define MTDUMMYRESOURCE_H - -#include -#include -#include - -class MTDummyResource : public Akonadi::ResourceBase, public Akonadi::TransportResourceBase -{ - Q_OBJECT - - public: - explicit MTDummyResource( const QString &id ); - ~MTDummyResource(); - - public: - virtual void configure( WId windowId ); - - /* reimpl from ResourceBase::Transport */ - virtual void sendItem( const Akonadi::Item &message ); - - protected Q_SLOTS: - void retrieveCollections(); - void retrieveItems( const Akonadi::Collection &col ); - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - - protected: - virtual void aboutToQuit(); - - private Q_SLOTS: - void jobResult( KJob *job ); - - private: - Akonadi::Item::Id currentlySending; - -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/mailtransport_dummy/mtdummyresource.kcfg kdepim-runtime-15.08.0/resources/mailtransport_dummy/mtdummyresource.kcfg --- kdepim-runtime-4.14.6/resources/mailtransport_dummy/mtdummyresource.kcfg 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mailtransport_dummy/mtdummyresource.kcfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ - - - - - - - -1 - - - diff -Nru kdepim-runtime-4.14.6/resources/mailtransport_dummy/settings.kcfgc kdepim-runtime-15.08.0/resources/mailtransport_dummy/settings.kcfgc --- kdepim-runtime-4.14.6/resources/mailtransport_dummy/settings.kcfgc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mailtransport_dummy/settings.kcfgc 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -File=mtdummyresource.kcfg -ClassName=Settings -Mutators=true -ItemAccessors=true -SetUserTexts=true -Singleton=true -#IncludeFiles= -GlobalEnums=true diff -Nru kdepim-runtime-4.14.6/resources/mailtransport_dummy/settings.ui kdepim-runtime-15.08.0/resources/mailtransport_dummy/settings.ui --- kdepim-runtime-4.14.6/resources/mailtransport_dummy/settings.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mailtransport_dummy/settings.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ - - - Till Adam <adam@kde.org> - ConfigDialog - - - - 0 - 0 - 400 - 250 - - - - Mail Dispatcher Agent Settings - - - - - - Select the collection to dump sent messages to: - - - - - - - QFrame::NoFrame - - - QFrame::Plain - - - - - - - Qt::Vertical - - - - 20 - 13 - - - - - - - - - Akonadi::CollectionRequester - QFrame -
akonadi/collectionrequester.h
- 1 -
-
- - -
diff -Nru kdepim-runtime-4.14.6/resources/mbox/autotests/CMakeLists.txt kdepim-runtime-15.08.0/resources/mbox/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/mbox/autotests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/autotests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,7 @@ set( mbox_deleteitemsattributetest_source deleteitemsattributetest.cpp ../deleteditemsattribute.cpp) -kde4_add_unit_test( deleteitemsattributetest ${mbox_deleteitemsattributetest_source}) -target_link_libraries( deleteitemsattributetest ${QT_QTTEST_LIBRARY} ${KDE4_KDECORE_LIBS} ${QT_QTGUI_LIBRARY} ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_KMBOX_LIBS}) +add_executable( deleteitemsattributetest ${mbox_deleteitemsattributetest_source}) +add_test(deleteitemsattributetest deleteitemsattributetest) +ecm_mark_as_test(deleteitemsattributetest) +target_link_libraries( deleteitemsattributetest Qt5::Test Qt5::Gui KF5::AkonadiCore KF5::Mbox) diff -Nru kdepim-runtime-4.14.6/resources/mbox/autotests/deleteitemsattributetest.cpp kdepim-runtime-15.08.0/resources/mbox/autotests/deleteitemsattributetest.cpp --- kdepim-runtime-4.14.6/resources/mbox/autotests/deleteitemsattributetest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/autotests/deleteitemsattributetest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -17,8 +17,7 @@ #include "deleteitemsattributetest.h" #include "../deleteditemsattribute.h" -#include - +#include DeleteItemsAttributeTest::DeleteItemsAttributeTest(QObject *parent) : QObject(parent) @@ -81,4 +80,4 @@ QCOMPARE(attr.type(), QByteArray("DeletedMboxItems")); } -QTEST_KDEMAIN(DeleteItemsAttributeTest, NoGUI) +QTEST_MAIN(DeleteItemsAttributeTest) diff -Nru kdepim-runtime-4.14.6/resources/mbox/autotests/deleteitemsattributetest.h kdepim-runtime-15.08.0/resources/mbox/autotests/deleteitemsattributetest.h --- kdepim-runtime-4.14.6/resources/mbox/autotests/deleteitemsattributetest.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/autotests/deleteitemsattributetest.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,7 +24,7 @@ { Q_OBJECT public: - explicit DeleteItemsAttributeTest(QObject *parent = 0); + explicit DeleteItemsAttributeTest(QObject *parent = Q_NULLPTR); ~DeleteItemsAttributeTest(); private Q_SLOTS: diff -Nru kdepim-runtime-4.14.6/resources/mbox/CMakeLists.txt kdepim-runtime-15.08.0/resources/mbox/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/mbox/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,45 +1,40 @@ -include_directories( - ${kdepim-runtime_SOURCE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} - ${Boost_INCLUDE_DIR} -) - -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) add_subdirectory(wizard) ########### next target ############### +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_mbox_resource\") set( mboxresource_SRCS - ${AKONADI_SINGLEFILERESOURCE_SHARED_SOURCES} + mboxresource_debug.cpp compactpage.cpp lockmethodpage.cpp deleteditemsattribute.cpp mboxresource.cpp ) -install( FILES mboxresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) +install( FILES mboxresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) -kde4_add_ui_files(mboxresource_SRCS - ${AKONADI_SINGLEFILERESOURCE_SHARED_UI} +ki18n_wrap_ui(mboxresource_SRCS compactpage.ui lockfilepage.ui ) -kde4_add_kcfg_files(mboxresource_SRCS settings.kcfgc) +kconfig_add_kcfg_files(mboxresource_SRCS settings.kcfgc) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/mboxresource.kcfg org.kde.Akonadi.Mbox.Settings) -qt4_add_dbus_adaptor(mboxresource_SRCS +qt5_add_dbus_adaptor(mboxresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.Mbox.Settings.xml settings.h Settings ) -kde4_add_plugin(akonadi_mbox_resource ${mboxresource_SRCS}) +add_executable(akonadi_mbox_resource ${mboxresource_SRCS}) -if (Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_mbox_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) set_target_properties(akonadi_mbox_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.Mbox") set_target_properties(akonadi_mbox_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi Mbox Resource") endif () -target_link_libraries(akonadi_mbox_resource ${KDEPIMLIBS_KMBOX_LIBS} ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_AKONADI_KMIME_LIBS} ${QT_QTDBUS_LIBRARY} ${KDE4_KIO_LIBS} ${KDEPIMLIBS_KMIME_LIBS}) +target_link_libraries(akonadi_mbox_resource KF5::Mbox KF5::AkonadiCore KF5::AkonadiMime KF5::KIOCore KF5::Mime KF5::AkonadiAgentBase KF5::DBusAddons akonadi-singlefileresource) -install(TARGETS akonadi_mbox_resource DESTINATION ${PLUGIN_INSTALL_DIR}) -add_subdirectory(autotests) +install(TARGETS akonadi_mbox_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) +if (BUILD_TESTING) + add_subdirectory(autotests) +endif() diff -Nru kdepim-runtime-4.14.6/resources/mbox/compactpage.cpp kdepim-runtime-15.08.0/resources/mbox/compactpage.cpp --- kdepim-runtime-4.14.6/resources/mbox/compactpage.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/compactpage.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,9 +19,11 @@ #include "compactpage.h" -#include -#include +#include +#include #include +#include +#include #include "deleteditemsattribute.h" @@ -29,111 +31,110 @@ using namespace Akonadi; -CompactPage::CompactPage( const QString &collectionId, QWidget *parent ) - : QWidget( parent ) - , mCollectionId( collectionId ) +CompactPage::CompactPage(const QString &collectionId, QWidget *parent) + : QWidget(parent) + , mCollectionId(collectionId) { - ui.setupUi( this ); + ui.setupUi(this); - connect( ui.compactButton, SIGNAL(clicked()), this, SLOT(compact()) ); + connect(ui.compactButton, &QPushButton::clicked, this, &CompactPage::compact); - checkCollectionId(); + checkCollectionId(); } void CompactPage::checkCollectionId() { - if ( !mCollectionId.isEmpty() ) { - Collection collection; - collection.setRemoteId( mCollectionId ); - CollectionFetchJob *fetchJob = - new CollectionFetchJob( collection, CollectionFetchJob::Base ); + if (!mCollectionId.isEmpty()) { + Collection collection; + collection.setRemoteId(mCollectionId); + CollectionFetchJob *fetchJob = + new CollectionFetchJob(collection, CollectionFetchJob::Base); - connect( fetchJob, SIGNAL(result(KJob*)), - this, SLOT(onCollectionFetchCheck(KJob*)) ); - } + connect(fetchJob, &CollectionFetchJob::result, this, &CompactPage::onCollectionFetchCheck); + } } void CompactPage::compact() { - ui.compactButton->setEnabled( false ); + ui.compactButton->setEnabled(false); + + Collection collection; + collection.setRemoteId(mCollectionId); + CollectionFetchJob *fetchJob = + new CollectionFetchJob(collection, CollectionFetchJob::Base); + + connect(fetchJob, &CollectionFetchJob::result, this, &CompactPage::onCollectionFetchCompact); +} - Collection collection; - collection.setRemoteId( mCollectionId ); - CollectionFetchJob *fetchJob = - new CollectionFetchJob( collection, CollectionFetchJob::Base ); - - connect( fetchJob, SIGNAL(result(KJob*)), - this, SLOT(onCollectionFetchCompact(KJob*)) ); -} - -void CompactPage::onCollectionFetchCheck( KJob *job ) -{ - if ( job->error() ) { - // If we cannot fetch the collection, than also disable compacting. - ui.compactButton->setEnabled( false ); - return; - } - - CollectionFetchJob *fetchJob = dynamic_cast( job ); - Q_ASSERT( fetchJob ); - Q_ASSERT( fetchJob->collections().size() == 1 ); - - Collection mboxCollection = fetchJob->collections().first(); - DeletedItemsAttribute *attr - = mboxCollection.attribute( Akonadi::Entity::AddIfMissing ); - - if ( !attr->deletedItemOffsets().isEmpty() ) { - ui.compactButton->setEnabled( true ); - ui.messageLabel->setText( i18np( "(1 message marked for deletion)", - "(%1 messages marked for deletion)", attr->deletedItemOffsets().size() ) ); - } -} - -void CompactPage::onCollectionFetchCompact( KJob *job ) -{ - if ( job->error() ) { - ui.messageLabel->setText( i18n( "Failed to fetch the collection." ) ); - ui.compactButton->setEnabled( true ); - return; - } - - CollectionFetchJob *fetchJob = dynamic_cast( job ); - Q_ASSERT( fetchJob ); - Q_ASSERT( fetchJob->collections().size() == 1 ); - - Collection mboxCollection = fetchJob->collections().first(); - DeletedItemsAttribute *attr - = mboxCollection.attribute( Akonadi::Entity::AddIfMissing ); - - KMBox::MBox mbox; - // TODO: Set lock method. - const QString fileName = KUrl(mCollectionId).toLocalFile(); - if ( !mbox.load(fileName) ) { - ui.messageLabel->setText( i18n( "Failed to load the mbox file" ) ); - } else { - ui.messageLabel->setText( i18np( "(Deleting 1 message)", - "(Deleting %1 messages)", attr->offsetCount() ) ); - // TODO: implement and connect to messageProcessed signal. - if ( mbox.purge(attr->deletedItemEntries()) || - (QFileInfo(fileName).size() == 0) ) { - // even if purge() failed but the file is now empty. - // it was probably deleted/emptied by an external prog. For whatever reason - // doesn't matter here. We know the file is empty so we can get rid - // of our stored DeletedItemsAttribute - mboxCollection.removeAttribute(); - CollectionModifyJob *modifyJob = new CollectionModifyJob( mboxCollection ); - connect( modifyJob, SIGNAL(result(KJob*)), - this, SLOT(onCollectionModify(KJob*)) ); - } else - ui.messageLabel->setText( i18n( "Failed to compact the mbox file." ) ); - } -} - -void CompactPage::onCollectionModify( KJob *job ) -{ - if ( job->error() ) - ui.messageLabel->setText( i18n( "Failed to compact the mbox file." ) ); - else - ui.messageLabel->setText( i18n( "MBox file compacted." ) ); +void CompactPage::onCollectionFetchCheck(KJob *job) +{ + if (job->error()) { + // If we cannot fetch the collection, than also disable compacting. + ui.compactButton->setEnabled(false); + return; + } + + CollectionFetchJob *fetchJob = dynamic_cast(job); + Q_ASSERT(fetchJob); + Q_ASSERT(fetchJob->collections().size() == 1); + + Collection mboxCollection = fetchJob->collections().at(0); + DeletedItemsAttribute *attr + = mboxCollection.attribute(Akonadi::Entity::AddIfMissing); + + if (!attr->deletedItemOffsets().isEmpty()) { + ui.compactButton->setEnabled(true); + ui.messageLabel->setText(i18np("(1 message marked for deletion)", + "(%1 messages marked for deletion)", attr->deletedItemOffsets().size())); + } +} + +void CompactPage::onCollectionFetchCompact(KJob *job) +{ + if (job->error()) { + ui.messageLabel->setText(i18n("Failed to fetch the collection.")); + ui.compactButton->setEnabled(true); + return; + } + + CollectionFetchJob *fetchJob = dynamic_cast(job); + Q_ASSERT(fetchJob); + Q_ASSERT(fetchJob->collections().size() == 1); + + Collection mboxCollection = fetchJob->collections().at(0); + DeletedItemsAttribute *attr + = mboxCollection.attribute(Akonadi::Entity::AddIfMissing); + + KMBox::MBox mbox; + // TODO: Set lock method. + const QString fileName = QUrl::fromLocalFile(mCollectionId).toLocalFile(); + if (!mbox.load(fileName)) { + ui.messageLabel->setText(i18n("Failed to load the mbox file")); + } else { + ui.messageLabel->setText(i18np("(Deleting 1 message)", + "(Deleting %1 messages)", attr->offsetCount())); + // TODO: implement and connect to messageProcessed signal. + if (mbox.purge(attr->deletedItemEntries()) || + (QFileInfo(fileName).size() == 0)) { + // even if purge() failed but the file is now empty. + // it was probably deleted/emptied by an external prog. For whatever reason + // doesn't matter here. We know the file is empty so we can get rid + // of our stored DeletedItemsAttribute + mboxCollection.removeAttribute(); + CollectionModifyJob *modifyJob = new CollectionModifyJob(mboxCollection); + connect(modifyJob, &CollectionModifyJob::result, this, &CompactPage::onCollectionModify); + } else { + ui.messageLabel->setText(i18n("Failed to compact the mbox file.")); + } + } +} + +void CompactPage::onCollectionModify(KJob *job) +{ + if (job->error()) { + ui.messageLabel->setText(i18n("Failed to compact the mbox file.")); + } else { + ui.messageLabel->setText(i18n("MBox file compacted.")); + } } diff -Nru kdepim-runtime-4.14.6/resources/mbox/compactpage.h kdepim-runtime-15.08.0/resources/mbox/compactpage.h --- kdepim-runtime-4.14.6/resources/mbox/compactpage.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/compactpage.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,7 +20,7 @@ #ifndef COMPACTPAGE_H #define COMPACTPAGE_H -#include +#include #include "ui_compactpage.h" @@ -28,21 +28,21 @@ class CompactPage : public QWidget { - Q_OBJECT + Q_OBJECT - public: - explicit CompactPage( const QString &collectionId, QWidget *parent = 0 ); +public: + explicit CompactPage(const QString &collectionId, QWidget *parent = Q_NULLPTR); - private slots: +private Q_SLOTS: void compact(); - void onCollectionFetchCheck( KJob* ); - void onCollectionFetchCompact( KJob* ); - void onCollectionModify( KJob* ); + void onCollectionFetchCheck(KJob *); + void onCollectionFetchCompact(KJob *); + void onCollectionModify(KJob *); - private: // Methods +private: // Methods void checkCollectionId(); - private: // Members +private: // Members QString mCollectionId; Ui::CompactPage ui; }; diff -Nru kdepim-runtime-4.14.6/resources/mbox/compactpage.ui kdepim-runtime-15.08.0/resources/mbox/compactpage.ui --- kdepim-runtime-4.14.6/resources/mbox/compactpage.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/compactpage.ui 2015-08-10 21:01:02.000000000 +0000 @@ -91,10 +91,7 @@
- - - - + msg @@ -112,11 +109,6 @@
kbuttongroup.h
1 - - KIntNumInput - QWidget -
knuminput.h
-
diff -Nru kdepim-runtime-4.14.6/resources/mbox/deleteditemsattribute.cpp kdepim-runtime-15.08.0/resources/mbox/deleteditemsattribute.cpp --- kdepim-runtime-4.14.6/resources/mbox/deleteditemsattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/deleteditemsattribute.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,76 +23,78 @@ { } -DeletedItemsAttribute::DeletedItemsAttribute( const DeletedItemsAttribute &other ) - : Akonadi::Attribute() +DeletedItemsAttribute::DeletedItemsAttribute(const DeletedItemsAttribute &other) + : Akonadi::Attribute() { - if ( &other == this ) - return; + if (&other == this) { + return; + } - mDeletedItemOffsets = other.mDeletedItemOffsets; + mDeletedItemOffsets = other.mDeletedItemOffsets; } DeletedItemsAttribute::~DeletedItemsAttribute() { } -void DeletedItemsAttribute::addDeletedItemOffset( quint64 offset ) +void DeletedItemsAttribute::addDeletedItemOffset(quint64 offset) { - mDeletedItemOffsets.insert( offset ); + mDeletedItemOffsets.insert(offset); } DeletedItemsAttribute *DeletedItemsAttribute::clone() const { - return new DeletedItemsAttribute( *this ); + return new DeletedItemsAttribute(*this); } QSet DeletedItemsAttribute::deletedItemOffsets() const { - return mDeletedItemOffsets; + return mDeletedItemOffsets; } KMBox::MBoxEntry::List DeletedItemsAttribute::deletedItemEntries() const { - KMBox::MBoxEntry::List entries; + KMBox::MBoxEntry::List entries; + entries.reserve(mDeletedItemOffsets.count()); + foreach (quint64 offset, mDeletedItemOffsets) { + entries << KMBox::MBoxEntry(offset); + } - foreach ( quint64 offset, mDeletedItemOffsets ) - entries << KMBox::MBoxEntry( offset ); - - return entries; + return entries; } -void DeletedItemsAttribute::deserialize( const QByteArray &data ) +void DeletedItemsAttribute::deserialize(const QByteArray &data) { - QList offsets = data.split(','); - mDeletedItemOffsets.clear(); + QList offsets = data.split(','); + mDeletedItemOffsets.clear(); - foreach( const QByteArray& offset, offsets ) { - mDeletedItemOffsets.insert( offset.toULongLong() ); - } + foreach (const QByteArray &offset, offsets) { + mDeletedItemOffsets.insert(offset.toULongLong()); + } } QByteArray DeletedItemsAttribute::serialized() const { - QByteArray serialized; + QByteArray serialized; - foreach( quint64 offset, mDeletedItemOffsets ) { - serialized += QByteArray::number(offset); - serialized += ','; - } + foreach (quint64 offset, mDeletedItemOffsets) { + serialized += QByteArray::number(offset); + serialized += ','; + } - serialized.chop( 1 ); // Remove the last ',' + serialized.chop(1); // Remove the last ',' - return serialized; + return serialized; } int DeletedItemsAttribute::offsetCount() const { - return mDeletedItemOffsets.size(); + return mDeletedItemOffsets.size(); } QByteArray DeletedItemsAttribute::type() const { - static const QByteArray sType( "DeletedMboxItems" ); + static const QByteArray sType("DeletedMboxItems"); return sType; } diff -Nru kdepim-runtime-4.14.6/resources/mbox/deleteditemsattribute.h kdepim-runtime-15.08.0/resources/mbox/deleteditemsattribute.h --- kdepim-runtime-4.14.6/resources/mbox/deleteditemsattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/deleteditemsattribute.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,7 +20,7 @@ #ifndef DELETEDITEMSATTRIBUTE_H #define DELETEDITEMSATTRIBUTE_H -#include +#include #include #include @@ -31,30 +31,30 @@ */ class DeletedItemsAttribute : public Akonadi::Attribute { - public: +public: DeletedItemsAttribute(); - DeletedItemsAttribute( const DeletedItemsAttribute &other ); + DeletedItemsAttribute(const DeletedItemsAttribute &other); ~DeletedItemsAttribute(); - void addDeletedItemOffset( quint64 ); + void addDeletedItemOffset(quint64); - virtual DeletedItemsAttribute *clone() const; + DeletedItemsAttribute *clone() const Q_DECL_OVERRIDE; QSet deletedItemOffsets() const; KMBox::MBoxEntry::List deletedItemEntries() const; - virtual void deserialize( const QByteArray &data ); + void deserialize(const QByteArray &data) Q_DECL_OVERRIDE; /** * Returns the number of offsets stored in this attribute. */ int offsetCount() const; - virtual QByteArray serialized() const; + QByteArray serialized() const Q_DECL_OVERRIDE; - virtual QByteArray type() const; + QByteArray type() const Q_DECL_OVERRIDE; bool operator ==(const DeletedItemsAttribute &other) const; private: diff -Nru kdepim-runtime-4.14.6/resources/mbox/lockmethodpage.cpp kdepim-runtime-15.08.0/resources/mbox/lockmethodpage.cpp --- kdepim-runtime-4.14.6/resources/mbox/lockmethodpage.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/lockmethodpage.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,37 +21,39 @@ #include "settings.h" #include -#include + #include +#include -LockMethodPage::LockMethodPage( QWidget *parent ) : QWidget( parent ) +LockMethodPage::LockMethodPage(QWidget *parent) : QWidget(parent) { - ui.setupUi( this ); - checkAvailableLockMethods(); + ui.setupUi(this); + checkAvailableLockMethods(); } void LockMethodPage::checkAvailableLockMethods() { - // FIXME: I guess this whole checking makes only sense on linux machines. + // FIXME: I guess this whole checking makes only sense on linux machines. + + // Check for procmail lock method. + if (QStandardPaths::findExecutable(QStringLiteral("lockfile")).isEmpty()) { + ui.procmail->setEnabled(false); + if (ui.procmail->isChecked()) { // Select another lock method if necessary + ui.mutt_dotlock->setChecked(true); + } + } - // Check for procmail lock method. - if ( KStandardDirs::findExe( QLatin1String("lockfile") ).isEmpty() ) { - ui.procmail->setEnabled( false ); - if ( ui.procmail->isChecked() ) // Select another lock method if necessary - ui.mutt_dotlock->setChecked( true ); - } - - // Check for mutt lock method. - if ( KStandardDirs::findExe( QLatin1String("mutt_dotlock") ).isEmpty() ) { - ui.mutt_dotlock->setEnabled( false ); - ui.mutt_dotlock_privileged->setEnabled( false ); - if ( ui.mutt_dotlock->isChecked() || ui.mutt_dotlock_privileged->isChecked() ) - { - if ( ui.procmail->isEnabled() ) - ui.procmail->setChecked(true); - else - ui.none->setChecked(true); + // Check for mutt lock method. + if (QStandardPaths::findExecutable(QStringLiteral("mutt_dotlock")).isEmpty()) { + ui.mutt_dotlock->setEnabled(false); + ui.mutt_dotlock_privileged->setEnabled(false); + if (ui.mutt_dotlock->isChecked() || ui.mutt_dotlock_privileged->isChecked()) { + if (ui.procmail->isEnabled()) { + ui.procmail->setChecked(true); + } else { + ui.none->setChecked(true); + } + } } - } } diff -Nru kdepim-runtime-4.14.6/resources/mbox/lockmethodpage.h kdepim-runtime-15.08.0/resources/mbox/lockmethodpage.h --- kdepim-runtime-4.14.6/resources/mbox/lockmethodpage.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/lockmethodpage.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,20 +20,20 @@ #ifndef LOCKMETHODPAGE_H #define LOCKMETHODPAGE_H -#include +#include #include "ui_lockfilepage.h" class LockMethodPage : public QWidget { - Q_OBJECT - public: - explicit LockMethodPage( QWidget *parent = 0 ); + Q_OBJECT +public: + explicit LockMethodPage(QWidget *parent = Q_NULLPTR); - private: +private: void checkAvailableLockMethods(); - private: +private: Ui::LockFilePage ui; }; diff -Nru kdepim-runtime-4.14.6/resources/mbox/mboxresource.cpp kdepim-runtime-15.08.0/resources/mbox/mboxresource.cpp --- kdepim-runtime-4.14.6/resources/mbox/mboxresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/mboxresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -18,20 +18,22 @@ */ #include "mboxresource.h" +#include "mboxresource_debug.h" #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include #include "compactpage.h" #include "deleteditemsattribute.h" @@ -41,342 +43,337 @@ using namespace Akonadi; -static Entity::Id collectionId( const QString &remoteItemId ) +static Entity::Id collectionId(const QString &remoteItemId) { - // [CollectionId]::[RemoteCollectionId]::[Offset] - Q_ASSERT( remoteItemId.split( QLatin1String("::") ).size() == 3 ); - return remoteItemId.split( QLatin1String("::") ).first().toLongLong(); + // [CollectionId]::[RemoteCollectionId]::[Offset] + Q_ASSERT(remoteItemId.split(QLatin1String("::")).size() == 3); + return remoteItemId.split(QLatin1String("::")).first().toLongLong(); } static QString mboxFile(const QString &remoteItemId) { - // [CollectionId]::[RemoteCollectionId]::[Offset] - Q_ASSERT(remoteItemId.split( QLatin1String("::") ).size() == 3); - return remoteItemId.split( QLatin1String("::") ).at(1); + // [CollectionId]::[RemoteCollectionId]::[Offset] + Q_ASSERT(remoteItemId.split(QLatin1String("::")).size() == 3); + return remoteItemId.split(QLatin1String("::")).at(1); } -static quint64 itemOffset( const QString &remoteItemId ) +static quint64 itemOffset(const QString &remoteItemId) { - // [CollectionId]::[RemoteCollectionId]::[Offset] - Q_ASSERT( remoteItemId.split( QLatin1String("::") ).size() == 3 ); - return remoteItemId.split( QLatin1String("::") ).last().toULongLong(); + // [CollectionId]::[RemoteCollectionId]::[Offset] + Q_ASSERT(remoteItemId.split(QLatin1String("::")).size() == 3); + return remoteItemId.split(QLatin1String("::")).last().toULongLong(); } -MboxResource::MboxResource( const QString &id ) - : SingleFileResource( id ) - , mMBox( 0 ) +MboxResource::MboxResource(const QString &id) + : SingleFileResource(id) + , mMBox(Q_NULLPTR) { - new SettingsAdaptor( mSettings ); - DBusConnectionPool::threadConnection().registerObject( QLatin1String( "/Settings" ), - mSettings, QDBusConnection::ExportAdaptors ); + new SettingsAdaptor(mSettings); + KDBusConnectionPool::threadConnection().registerObject(QStringLiteral("/Settings"), + mSettings, QDBusConnection::ExportAdaptors); - QStringList mimeTypes; - mimeTypes << QLatin1String("message/rfc822"); - setSupportedMimetypes( mimeTypes, QLatin1String("message-rfc822") ); + QStringList mimeTypes; + mimeTypes << QStringLiteral("message/rfc822"); + setSupportedMimetypes(mimeTypes, QStringLiteral("message-rfc822")); - // Register the list of deleted items as an attribute of the collection. - AttributeFactory::registerAttribute(); + // Register the list of deleted items as an attribute of the collection. + AttributeFactory::registerAttribute(); } MboxResource::~MboxResource() { - delete mMBox; + delete mMBox; } -void MboxResource::customizeConfigDialog( SingleFileResourceConfigDialog* dlg ) +void MboxResource::customizeConfigDialog(SingleFileResourceConfigDialog *dlg) { - dlg->setWindowIcon( KIcon( QLatin1String("message-rfc822") ) ); - dlg->addPage( i18n( "Compact frequency" ), new CompactPage( mSettings->path() ) ); - dlg->addPage( i18n( "Lock method" ), new LockMethodPage() ); - dlg->setCaption( i18n( "Select MBox file" ) ); -} - -void MboxResource::retrieveItems( const Akonadi::Collection &col ) -{ - Q_UNUSED( col ); - if ( !mMBox ) { - cancelTask(); - return; - } - if (mMBox->fileName().isEmpty()) { - emit status(NotConfigured, i18nc( "@info:status", "MBox not configured." ) ); - return; - } - - reloadFile(); - - KMBox::MBoxEntry::List entryList; - if ( col.hasAttribute() ) { - DeletedItemsAttribute *attr = col.attribute(); - entryList = mMBox->entries( attr->deletedItemEntries() ); - } else { // No deleted items (yet) - entryList = mMBox->entries(); - } - - mMBox->lock(); // Lock the file so that it doesn't get locked for every - // readEntryHeaders() call. - - Item::List items; - QString colId = QString::number( col.id() ); - QString colRid = col.remoteId(); - double count = 1; - const int entryListSize( entryList.size() ); - foreach ( const KMBox::MBoxEntry &entry, entryList ) { - // TODO: Use cache policy to see what actually has to been set as payload. - // Currently most views need a minimal amount of information so the - // Items get Envelopes as payload. - KMime::Message *mail = new KMime::Message(); - mail->setHead( KMime::CRLFtoLF( mMBox->readMessageHeaders( entry ) ) ); - mail->parse(); - - Item item; - item.setRemoteId( colId + QLatin1String("::") + colRid + QLatin1String("::") + QString::number( entry.messageOffset() ) ); - item.setMimeType( QLatin1String("message/rfc822") ); - item.setSize( entry.messageSize() ); - item.setPayload( KMime::Message::Ptr( mail ) ); - - Akonadi::MessageFlags::copyMessageFlags(*mail, item); - - emit percent(count++ / entryListSize); - items << item; - } - - mMBox->unlock(); // Now we have the items, unlock - - itemsRetrieved( items ); -} - -bool MboxResource::retrieveItem( const Akonadi::Item &item, const QSet &parts ) -{ - Q_UNUSED(parts); - - if ( !mMBox ) { - emit error( i18n( "MBox not loaded." ) ); - return false; - } - if (mMBox->fileName().isEmpty()) { - emit status(NotConfigured, i18nc( "@info:status", "MBox not configured." ) ); - return false; - } - - const QString rid = item.remoteId(); - const quint64 offset = itemOffset( rid ); - KMime::Message *mail = mMBox->readMessage( KMBox::MBoxEntry( offset ) ); - if ( !mail ) { - emit error( i18n( "Failed to read message with uid '%1'.", rid ) ); - return false; - } + dlg->setWindowIcon(QIcon::fromTheme(QStringLiteral("message-rfc822"))); + dlg->addPage(i18n("Compact frequency"), new CompactPage(mSettings->path())); + dlg->addPage(i18n("Lock method"), new LockMethodPage()); + dlg->setWindowTitle(i18n("Select MBox file")); +} + +void MboxResource::retrieveItems(const Akonadi::Collection &col) +{ + Q_UNUSED(col); + if (!mMBox) { + cancelTask(); + return; + } + if (mMBox->fileName().isEmpty()) { + Q_EMIT status(NotConfigured, i18nc("@info:status", "MBox not configured.")); + return; + } + + reloadFile(); + + KMBox::MBoxEntry::List entryList; + if (col.hasAttribute()) { + DeletedItemsAttribute *attr = col.attribute(); + entryList = mMBox->entries(attr->deletedItemEntries()); + } else { // No deleted items (yet) + entryList = mMBox->entries(); + } + + mMBox->lock(); // Lock the file so that it doesn't get locked for every + // readEntryHeaders() call. + + Item::List items; + QString colId = QString::number(col.id()); + QString colRid = col.remoteId(); + double count = 1; + const int entryListSize(entryList.size()); + items.reserve(entryListSize); + foreach (const KMBox::MBoxEntry &entry, entryList) { + // TODO: Use cache policy to see what actually has to been set as payload. + // Currently most views need a minimal amount of information so the + // Items get Envelopes as payload. + KMime::Message *mail = new KMime::Message(); + mail->setHead(KMime::CRLFtoLF(mMBox->readMessageHeaders(entry))); + mail->parse(); + + Item item; + item.setRemoteId(colId + QLatin1String("::") + colRid + QLatin1String("::") + QString::number(entry.messageOffset())); + item.setMimeType(QLatin1String("message/rfc822")); + item.setSize(entry.messageSize()); + item.setPayload(KMime::Message::Ptr(mail)); + Akonadi::MessageFlags::copyMessageFlags(*mail, item); + Q_EMIT percent(count++ / entryListSize); + items << item; + } + + mMBox->unlock(); // Now we have the items, unlock + + itemsRetrieved(items); +} + +bool MboxResource::retrieveItem(const Akonadi::Item &item, const QSet &parts) +{ + Q_UNUSED(parts); + + if (!mMBox) { + Q_EMIT error(i18n("MBox not loaded.")); + return false; + } + if (mMBox->fileName().isEmpty()) { + Q_EMIT status(NotConfigured, i18nc("@info:status", "MBox not configured.")); + return false; + } + + const QString rid = item.remoteId(); + const quint64 offset = itemOffset(rid); + KMime::Message *mail = mMBox->readMessage(KMBox::MBoxEntry(offset)); + if (!mail) { + Q_EMIT error(i18n("Failed to read message with uid '%1'.", rid)); + return false; + } + + Item i(item); + i.setPayload(KMime::Message::Ptr(mail)); + Akonadi::MessageFlags::copyMessageFlags(*mail, i); + itemRetrieved(i); + return true; +} + +void MboxResource::aboutToQuit() +{ + if (!mSettings->readOnly()) { + writeFile(); + } + mSettings->save(); +} + +void MboxResource::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) +{ + if (!mMBox) { + cancelTask(i18n("MBox not loaded.")); + return; + } + if (mMBox->fileName().isEmpty()) { + Q_EMIT status(NotConfigured, i18nc("@info:status", "MBox not configured.")); + return; + } + + // we can only deal with mail + if (!item.hasPayload()) { + cancelTask(i18n("Only email messages can be added to the MBox resource.")); + return; + } + + const KMBox::MBoxEntry entry = mMBox->appendMessage(item.payload()); + if (!entry.isValid()) { + cancelTask(i18n("Mail message not added to the MBox.")); + return; + } - Item i( item ); - i.setPayload( KMime::Message::Ptr( mail ) ); + scheduleWrite(); + const QString rid = QString::number(collection.id()) + QLatin1String("::") + + collection.remoteId() + QLatin1String("::") + QString::number(entry.messageOffset()); - Akonadi::MessageFlags::copyMessageFlags(*mail, i); + Item i(item); + i.setRemoteId(rid); - itemRetrieved( i ); - return true; + changeCommitted(i); } -void MboxResource::aboutToQuit() +void MboxResource::itemChanged(const Akonadi::Item &item, const QSet &parts) { - if ( !mSettings->readOnly() ) - writeFile(); - mSettings->writeConfig(); -} - -void MboxResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ) -{ - if ( !mMBox ) { - cancelTask( i18n( "MBox not loaded." ) ); - return; - } - if (mMBox->fileName().isEmpty()) { - emit status(NotConfigured, i18nc( "@info:status", "MBox not configured." ) ); - return; - } - - // we can only deal with mail - if ( !item.hasPayload() ) { - cancelTask( i18n( "Only email messages can be added to the MBox resource." ) ); - return; - } - - const KMBox::MBoxEntry entry = mMBox->appendMessage( item.payload() ); - if ( !entry.isValid() ) { - cancelTask( i18n( "Mail message not added to the MBox." ) ); - return; - } - - scheduleWrite(); - const QString rid = QString::number( collection.id() ) + QLatin1String("::") - + collection.remoteId() + QLatin1String("::") + QString::number( entry.messageOffset() ); - - Item i( item ); - i.setRemoteId( rid ); - - changeCommitted( i ); -} - -void MboxResource::itemChanged( const Akonadi::Item &item, const QSet &parts ) -{ - if ( parts.contains( "PLD:RFC822" ) ) { - kDebug() << itemOffset( item.remoteId() ); - // Only complete messages can be stored in a MBox file. Because all messages - // are stored in one single file we do an ItemDelete and an ItemCreate to - // prevent that whole file must been rewritten. - CollectionFetchJob *fetchJob = - new CollectionFetchJob( Collection( collectionId( item.remoteId() ) ) - , CollectionFetchJob::Base ); + if (parts.contains("PLD:RFC822")) { + qCDebug(MBOXRESOURCE_LOG) << itemOffset(item.remoteId()); + // Only complete messages can be stored in a MBox file. Because all messages + // are stored in one single file we do an ItemDelete and an ItemCreate to + // prevent that whole file must been rewritten. + CollectionFetchJob *fetchJob = + new CollectionFetchJob(Collection(collectionId(item.remoteId())) + , CollectionFetchJob::Base); - connect( fetchJob, SIGNAL(result(KJob*)), - this, SLOT(onCollectionFetch(KJob*)) ); + connect(fetchJob, &CollectionFetchJob::result, this, &MboxResource::onCollectionFetch); - mCurrentItemDeletions.insert( fetchJob, item ); + mCurrentItemDeletions.insert(fetchJob, item); - fetchJob->start(); - return; - } + fetchJob->start(); + return; + } - changeProcessed(); + changeProcessed(); } -void MboxResource::itemRemoved( const Akonadi::Item &item ) +void MboxResource::itemRemoved(const Akonadi::Item &item) { - CollectionFetchJob *fetchJob = - new CollectionFetchJob( Collection( collectionId( item.remoteId() ) ) - , CollectionFetchJob::Base ); - - if ( !fetchJob->exec() ) { - cancelTask( i18n( "Could not fetch the collection: %1", fetchJob->errorString() ) ); - return; - } - - Q_ASSERT( fetchJob->collections().size() == 1 ); - Collection mboxCollection = fetchJob->collections().first(); - DeletedItemsAttribute *attr - = mboxCollection.attribute( Akonadi::Entity::AddIfMissing ); + CollectionFetchJob *fetchJob = + new CollectionFetchJob(Collection(collectionId(item.remoteId())) + , CollectionFetchJob::Base); - if ( mSettings->compactFrequency() == Settings::per_x_messages - && mSettings->messageCount() == static_cast( attr->offsetCount() + 1 ) ) { - kDebug() << "Compacting mbox file"; - mMBox->purge( attr->deletedItemEntries() << KMBox::MBoxEntry( itemOffset( item.remoteId() ) ) ); - scheduleWrite(); - mboxCollection.removeAttribute(); - } else { - attr->addDeletedItemOffset( itemOffset( item.remoteId() ) ); - } - - CollectionModifyJob *modifyJob = new CollectionModifyJob( mboxCollection ); - if ( !modifyJob->exec() ) { - cancelTask( modifyJob->errorString() ); - return; - } + if (!fetchJob->exec()) { + cancelTask(i18n("Could not fetch the collection: %1", fetchJob->errorString())); + return; + } + + Q_ASSERT(fetchJob->collections().size() == 1); + Collection mboxCollection = fetchJob->collections().at(0); + DeletedItemsAttribute *attr + = mboxCollection.attribute(Akonadi::Entity::AddIfMissing); + + if (mSettings->compactFrequency() == Settings::per_x_messages + && mSettings->messageCount() == static_cast(attr->offsetCount() + 1)) { + qCDebug(MBOXRESOURCE_LOG) << "Compacting mbox file"; + mMBox->purge(attr->deletedItemEntries() << KMBox::MBoxEntry(itemOffset(item.remoteId()))); + scheduleWrite(); + mboxCollection.removeAttribute(); + } else { + attr->addDeletedItemOffset(itemOffset(item.remoteId())); + } + + CollectionModifyJob *modifyJob = new CollectionModifyJob(mboxCollection); + if (!modifyJob->exec()) { + cancelTask(modifyJob->errorString()); + return; + } - changeProcessed(); + changeProcessed(); } void MboxResource::handleHashChange() { - emit warning( i18n( "The MBox file was changed by another program. " - "A copy of the new file was made and pending changes " - "are appended to that copy. To prevent this from happening " - "use locking and make sure that all programs accessing the mbox " - "use the same locking method." ) ); + Q_EMIT warning(i18n("The MBox file was changed by another program. " + "A copy of the new file was made and pending changes " + "are appended to that copy. To prevent this from happening " + "use locking and make sure that all programs accessing the mbox " + "use the same locking method.")); } -bool MboxResource::readFromFile( const QString &fileName ) +bool MboxResource::readFromFile(const QString &fileName) { - delete mMBox; - mMBox = new KMBox::MBox(); + delete mMBox; + mMBox = new KMBox::MBox(); - switch ( mSettings->lockfileMethod() ) { + switch (mSettings->lockfileMethod()) { case Settings::procmail: - mMBox->setLockType( KMBox::MBox::ProcmailLockfile ); - mMBox->setLockFile( mSettings->lockfile() ); - break; + mMBox->setLockType(KMBox::MBox::ProcmailLockfile); + mMBox->setLockFile(mSettings->lockfile()); + break; case Settings::mutt_dotlock: - mMBox->setLockType( KMBox::MBox::MuttDotlock ); - break; + mMBox->setLockType(KMBox::MBox::MuttDotlock); + break; case Settings::mutt_dotlock_privileged: - mMBox->setLockType( KMBox::MBox::MuttDotlockPrivileged ); - break; - } - - return mMBox->load( KUrl( fileName ).toLocalFile() ); -} - -bool MboxResource::writeToFile( const QString &fileName ) -{ - if ( !mMBox->save( fileName ) ) { - emit error( i18n( "Failed to save mbox file to %1", fileName ) ); - return false; - } - - // HACK: When writeToFile is called with another file than with which the mbox - // was loaded we assume that a backup is made as result of the fileChanged slot - // in SingleFileResourceBase. The problem is that SingleFileResource assumes that - // the implementing resources can save/retrieve the data from before the file - // change we have a problem at this point in the mbox resource. Therefore we - // copy the original file and append pending changes to it but also add an extra - // '\n' to make sure that the hashes differ and the user gets notified. Normally - // if this happens the user should make use of locking in all applications that - // use the mbox file. - if ( fileName != mMBox->fileName() ) { - QFile file( fileName ); - file.open( QIODevice::WriteOnly ); - file.seek( file.size() ); - file.write( "\n" ); - } + mMBox->setLockType(KMBox::MBox::MuttDotlockPrivileged); + break; + } + + return mMBox->load(QUrl::fromLocalFile(fileName).toLocalFile()); +} + +bool MboxResource::writeToFile(const QString &fileName) +{ + if (!mMBox->save(fileName)) { + Q_EMIT error(i18n("Failed to save mbox file to %1", fileName)); + return false; + } + + // HACK: When writeToFile is called with another file than with which the mbox + // was loaded we assume that a backup is made as result of the fileChanged slot + // in SingleFileResourceBase. The problem is that SingleFileResource assumes that + // the implementing resources can save/retrieve the data from before the file + // change we have a problem at this point in the mbox resource. Therefore we + // copy the original file and append pending changes to it but also add an extra + // '\n' to make sure that the hashes differ and the user gets notified. Normally + // if this happens the user should make use of locking in all applications that + // use the mbox file. + if (fileName != mMBox->fileName()) { + QFile file(fileName); + file.open(QIODevice::WriteOnly); + file.seek(file.size()); + file.write("\n"); + } - return true; + return true; } /// Private slots -void MboxResource::onCollectionFetch( KJob *job ) +void MboxResource::onCollectionFetch(KJob *job) { - Q_ASSERT( mCurrentItemDeletions.contains( job ) ); - const Item item = mCurrentItemDeletions.take( job ); + Q_ASSERT(mCurrentItemDeletions.contains(job)); + const Item item = mCurrentItemDeletions.take(job); - if ( job->error() ) { - cancelTask( job->errorString() ); - return; - } + if (job->error()) { + cancelTask(job->errorString()); + return; + } - CollectionFetchJob *fetchJob = dynamic_cast( job ); - Q_ASSERT( fetchJob ); - Q_ASSERT( fetchJob->collections().size() == 1 ); + CollectionFetchJob *fetchJob = dynamic_cast(job); + Q_ASSERT(fetchJob); + Q_ASSERT(fetchJob->collections().size() == 1); - Collection mboxCollection = fetchJob->collections().first(); - DeletedItemsAttribute *attr - = mboxCollection.attribute( Akonadi::Entity::AddIfMissing ); - attr->addDeletedItemOffset( itemOffset( item.remoteId() ) ); + Collection mboxCollection = fetchJob->collections().at(0); + DeletedItemsAttribute *attr + = mboxCollection.attribute(Akonadi::Entity::AddIfMissing); + attr->addDeletedItemOffset(itemOffset(item.remoteId())); - CollectionModifyJob *modifyJob = new CollectionModifyJob( mboxCollection ); - mCurrentItemDeletions.insert( modifyJob, item ); - connect( modifyJob, SIGNAL(result(KJob*)), - this, SLOT(onCollectionModify(KJob*)) ); - modifyJob->start(); + CollectionModifyJob *modifyJob = new CollectionModifyJob(mboxCollection); + mCurrentItemDeletions.insert(modifyJob, item); + connect(modifyJob, &CollectionModifyJob::result, this, &MboxResource::onCollectionModify); + modifyJob->start(); } -void MboxResource::onCollectionModify( KJob *job ) +void MboxResource::onCollectionModify(KJob *job) { - Q_ASSERT( mCurrentItemDeletions.contains( job ) ); - const Item item = mCurrentItemDeletions.take( job ); + Q_ASSERT(mCurrentItemDeletions.contains(job)); + const Item item = mCurrentItemDeletions.take(job); - if ( job->error() ) { - // Failed to store the offset of a deleted item in the DeletedItemsAttribute - // of the collection. In this case we shouldn't try to store the modified - // item. - cancelTask( i18n( "Failed to update the changed item because the old item " - "could not be deleted Reason: %1", job->errorString() ) ); - return; - } + if (job->error()) { + // Failed to store the offset of a deleted item in the DeletedItemsAttribute + // of the collection. In this case we shouldn't try to store the modified + // item. + cancelTask(i18n("Failed to update the changed item because the old item " + "could not be deleted Reason: %1", job->errorString())); + return; + } - Collection c( collectionId( item.remoteId() ) ); - c.setRemoteId( mboxFile( item.remoteId() ) ); + Collection c(collectionId(item.remoteId())); + c.setRemoteId(mboxFile(item.remoteId())); - itemAdded( item, c ); + itemAdded(item, c); } -AKONADI_AGENT_FACTORY( MboxResource, akonadi_mbox_resource ) - +AKONADI_RESOURCE_MAIN(MboxResource) diff -Nru kdepim-runtime-4.14.6/resources/mbox/mboxresource_debug.cpp kdepim-runtime-15.08.0/resources/mbox/mboxresource_debug.cpp --- kdepim-runtime-4.14.6/resources/mbox/mboxresource_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/mboxresource_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2015 Laurent Montel + + 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 "mboxresource_debug.h" +Q_LOGGING_CATEGORY(MBOXRESOURCE_LOG, "log_mboxresource") + diff -Nru kdepim-runtime-4.14.6/resources/mbox/mboxresource_debug.h kdepim-runtime-15.08.0/resources/mbox/mboxresource_debug.h --- kdepim-runtime-4.14.6/resources/mbox/mboxresource_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/mboxresource_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2015 Laurent Montel + + 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 MBOXRESOURCE_DEBUG_H +#define MBOXRESOURCE_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(MBOXRESOURCE_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/mbox/mboxresource.desktop kdepim-runtime-15.08.0/resources/mbox/mboxresource.desktop --- kdepim-runtime-4.14.6/resources/mbox/mboxresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/mboxresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -100,4 +100,3 @@ X-Akonadi-MimeTypes=message/rfc822 X-Akonadi-Capabilities=Resource X-Akonadi-Identifier=akonadi_mbox_resource -X-Akonadi-LaunchMethod=AgentServer diff -Nru kdepim-runtime-4.14.6/resources/mbox/mboxresource.h kdepim-runtime-15.08.0/resources/mbox/mboxresource.h --- kdepim-runtime-4.14.6/resources/mbox/mboxresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/mboxresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -23,45 +23,45 @@ #include "settings.h" #include "singlefileresource.h" -namespace KMBox { +namespace KMBox +{ class MBox; } class MboxResource : public Akonadi::SingleFileResource { - Q_OBJECT + Q_OBJECT - public: - explicit MboxResource( const QString &id ); +public: + explicit MboxResource(const QString &id); ~MboxResource(); - protected Q_SLOTS: - virtual bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - virtual void retrieveItems( const Akonadi::Collection &col ); - - protected: - virtual void aboutToQuit(); - - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); - virtual void itemRemoved( const Akonadi::Item &item ); +protected Q_SLOTS: + bool retrieveItem(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + void retrieveItems(const Akonadi::Collection &col) Q_DECL_OVERRIDE; + +protected: + void aboutToQuit() Q_DECL_OVERRIDE; + + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + void itemRemoved(const Akonadi::Item &item) Q_DECL_OVERRIDE; // From SingleFileResourceBase - virtual void handleHashChange(); - virtual bool readFromFile( const QString &fileName ); - virtual bool writeToFile( const QString &fileName ); + void handleHashChange() Q_DECL_OVERRIDE; + bool readFromFile(const QString &fileName) Q_DECL_OVERRIDE; + bool writeToFile(const QString &fileName) Q_DECL_OVERRIDE; /** * Customize the configuration dialog before it is displayed. */ - virtual void customizeConfigDialog( Akonadi::SingleFileResourceConfigDialog* dlg ); - + void customizeConfigDialog(Akonadi::SingleFileResourceConfigDialog *dlg) Q_DECL_OVERRIDE; - private Q_SLOTS: - void onCollectionFetch( KJob *job ); - void onCollectionModify( KJob *job ); +private Q_SLOTS: + void onCollectionFetch(KJob *job); + void onCollectionModify(KJob *job); - private: - QHash mCurrentItemDeletions; +private: + QHash mCurrentItemDeletions; KMBox::MBox *mMBox; }; diff -Nru kdepim-runtime-4.14.6/resources/mbox/wizard/CMakeLists.txt kdepim-runtime-15.08.0/resources/mbox/wizard/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/mbox/wizard/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/wizard/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,2 +1,2 @@ -install ( FILES mailboxwizard.desktop mailboxwizard.es mailboxwizard.ui DESTINATION ${DATA_INSTALL_DIR}/akonadi/accountwizard/mailbox ) +install ( FILES mailboxwizard.desktop mailboxwizard.es mailboxwizard.ui DESTINATION ${KDE_INSTALL_DATADIR}/akonadi/accountwizard/mailbox ) diff -Nru kdepim-runtime-4.14.6/resources/mbox/wizard/mailboxwizard.desktop kdepim-runtime-15.08.0/resources/mbox/wizard/mailboxwizard.desktop --- kdepim-runtime-4.14.6/resources/mbox/wizard/mailboxwizard.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mbox/wizard/mailboxwizard.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -49,6 +49,7 @@ Name[zh_TW]=信箱格式(Mailbox) Icon=message-rfc822 Comment=Mailbox account +Comment[bg]=Сметка mailbox Comment[bs]=Mailbox nalog Comment[ca]=Compte de bústia Comment[ca@valencia]=Compte de bústia diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/CMakeLists.txt kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,205 @@ +include(ECMAddTests) + +find_package(Qt5Test CONFIG REQUIRED) + +if(${EXECUTABLE_OUTPUT_PATH}) + set( PREVIOUS_EXEC_OUTPUT_PATH ${EXECUTABLE_OUTPUT_PATH} ) +else() + set( PREVIOUS_EXEC_OUTPUT_PATH . ) +endif() +set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) + +kde_enable_exceptions() + +include_directories( + ${Boost_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../ + ${CMAKE_CURRENT_BINARY_DIR}/../ + ${CMAKE_CURRENT_SOURCE_DIR} +) + +# test data +qt5_add_resources( testdata_generated_SRCS testdata.qrc ) + +set( testdata_SRCS + ${testdata_generated_SRCS} + testdatautil.cpp + ../mixedmaildir_debug.cpp +) + + +add_executable(testdatatest testdatatest.cpp ${testdata_SRCS}) +add_test(testdatatest testdatatest) +ecm_mark_as_test(mixedmaildir-testdatatest) + +target_link_libraries( + testdatatest + Qt5::Test +) + +# put the libraries all tests link against into a variable and use it +# in target_link_libraries instead +set( common_link_libraries + kmindexreader + maildir + akonadi-filestore + KF5::AkonadiMime + KF5::AkonadiCore + KF5::Mbox + KF5::Mime + Qt5::Test +) + +# test for overwritten methods +add_executable(templatemethodstest ../mixedmaildirstore.cpp templatemethodstest.cpp ../mixedmaildir_debug.cpp ../mixedmaildirresource_debug.cpp) +add_test(templatemethodstest templatemethodstest) +ecm_mark_as_test(mixedmaildir-templatemethodtest) + + +target_link_libraries( + templatemethodstest + ${common_link_libraries} +) + +# test for collection creation handling +add_executable(collectioncreatetest ../mixedmaildirstore.cpp collectioncreatetest.cpp ../mixedmaildir_debug.cpp ../mixedmaildirresource_debug.cpp) +add_test(collectioncreatetest collectioncreatetest) +ecm_mark_as_test(mixedmaildir-collectioncreatetest) + + +target_link_libraries( + collectioncreatetest + ${common_link_libraries} +) + +# test for collection deletion handling +add_executable(collectiondeletetest ../mixedmaildirstore.cpp collectiondeletetest.cpp ../mixedmaildir_debug.cpp ../mixedmaildirresource_debug.cpp) +add_test(collectiondeletetest collectiondeletetest) +ecm_mark_as_test(mixedmaildir-collectiondeletetest) + +target_link_libraries( + collectiondeletetest + ${common_link_libraries} +) + +# test for collection fetching handling +add_executable( collectionfetchtest ../mixedmaildirstore.cpp collectionfetchtest.cpp ../mixedmaildir_debug.cpp ../mixedmaildirresource_debug.cpp) +add_test(collectionfetchtest collectionfetchtest) +ecm_mark_as_test(mixedmaildir-collectionfetchtest) + + +target_link_libraries( + collectionfetchtest + ${common_link_libraries} +) + +# test for collection modification handling +add_executable( collectionmodifytest ../mixedmaildirstore.cpp + collectionmodifytest.cpp ../mixedmaildir_debug.cpp ../mixedmaildirresource_debug.cpp + ${testdata_SRCS} +) +add_test(collectionmodifytest collectionmodifytest) +ecm_mark_as_test(mixedmaildir-collectionmodifytest) + + +target_link_libraries( + collectionmodifytest + ${common_link_libraries} +) + +# test for collection move handling +add_executable( collectionmovetest ../mixedmaildirstore.cpp ../mixedmaildir_debug.cpp + collectionmovetest.cpp ../mixedmaildirresource_debug.cpp + ${testdata_SRCS} +) +add_test(collectionmovetest collectionmovetest) +ecm_mark_as_test(mixedmaildir-collectionmovetest) + +target_link_libraries( + collectionmovetest + ${common_link_libraries} +) + +# test for item creation handling +add_executable(itemcreatetest ../mixedmaildirstore.cpp ../mixedmaildir_debug.cpp ../mixedmaildirresource_debug.cpp + itemcreatetest.cpp + ${testdata_SRCS} +) +add_test(itemcreatetest itemcreatetest) +ecm_mark_as_test(mixedmaildir-itemcreatetest) + + +target_link_libraries( + itemcreatetest + ${common_link_libraries} +) + +# test for item creation handling +add_executable(itemdeletetest ../mixedmaildirstore.cpp + itemdeletetest.cpp ../mixedmaildirresource_debug.cpp + ${testdata_SRCS} +) +add_test(itemdeletetest itemdeletetest) +ecm_mark_as_test(mixedmaildir-itemdeletetest) + + +target_link_libraries( + itemdeletetest + ${common_link_libraries} +) +#REACTIVATE IT +if (0) +# test for item retrieval handling +add_executable(itemfetchtest ../mixedmaildirstore.cpp ../mixedmaildirresource_debug.cpp + itemfetchtest.cpp + ${testdata_SRCS} +) +add_test(itemfetchtest itemfetchtest) +ecm_mark_as_test(mixedmaildir-itemfetchtest) + +target_link_libraries( + itemfetchtest + ${common_link_libraries} +) +endif() + +# test for item modification handling +add_executable(itemmodifytest ../mixedmaildirstore.cpp ../mixedmaildirresource_debug.cpp + itemmodifytest.cpp + ${testdata_SRCS} +) +add_test(itemmodifytest itemmodifytest) +ecm_mark_as_test( mixedmaildir-itemmodifytest) + +target_link_libraries( + itemmodifytest + ${common_link_libraries} +) + +# test for item move handling +add_executable(itemmovetest ../mixedmaildirstore.cpp ../mixedmaildirresource_debug.cpp + itemmovetest.cpp + ${testdata_SRCS} +) +add_test(itemmovetest itemmovetest) +ecm_mark_as_test(mixedmaildir-itemmovetest) + + +target_link_libraries( + itemmovetest + ${common_link_libraries} +) + +# test for store compact handling +add_executable(storecompacttest ../mixedmaildirstore.cpp ../mixedmaildirresource_debug.cpp + storecompacttest.cpp + ${testdata_SRCS} +) +add_test(storecompacttest storecompacttest) +ecm_mark_as_test(mixedmaildir-storecompacttest) + + +target_link_libraries( + storecompacttest + ${common_link_libraries} +) diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/collectioncreatetest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/collectioncreatetest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/collectioncreatetest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/collectioncreatetest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,330 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" + +#include "filestore/collectioncreatejob.h" + +#include "libmaildir/maildir.h" + +#include + +#include + +#include +#include +#include + +using namespace Akonadi; + +class CollectionCreateTest : public QObject +{ + Q_OBJECT + +public: + CollectionCreateTest() : QObject(), mStore(0), mDir(0) {} + ~CollectionCreateTest() + { + delete mStore; + delete mDir; + } + +private: + MixedMaildirStore *mStore; + QTemporaryDir *mDir; + +private Q_SLOTS: + void init(); + void cleanup(); + void testCollectionProperties(); + void testEmptyDir(); + void testMaildirTree(); + void testMixedTree(); +}; + +void CollectionCreateTest::init() +{ + mStore = new MixedMaildirStore; + + mDir = new QTemporaryDir; + QVERIFY(mDir->isValid()); + QVERIFY(QDir(mDir->path()).exists()); + +} + +void CollectionCreateTest::cleanup() +{ + delete mStore; + mStore = 0; + delete mDir; + mDir = 0; +} + +void CollectionCreateTest::testCollectionProperties() +{ + mStore->setPath(mDir->path()); + + FileStore::CollectionCreateJob *job = 0; + + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + job = mStore->createCollection(collection1, mStore->topLevelCollection()); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection1 = job->collection(); + QCOMPARE(collection1.remoteId(), collection1.name()); + + QCOMPARE(collection1.contentMimeTypes(), QStringList() << Collection::mimeType() << KMime::Message::mimeType()); + + QCOMPARE(collection1.rights(), Collection::CanCreateItem | + Collection::CanChangeItem | + Collection::CanDeleteItem | + Collection::CanCreateCollection | + Collection::CanChangeCollection | + Collection::CanDeleteCollection); +} + +void CollectionCreateTest::testEmptyDir() +{ + mStore->setPath(mDir->path()); + + KPIM::Maildir topLevelMd(mStore->path(), true); + + FileStore::CollectionCreateJob *job = 0; + + // test creating first level collections + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + job = mStore->createCollection(collection1, mStore->topLevelCollection()); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection1 = job->collection(); + QVERIFY(!collection1.remoteId().isEmpty()); + QVERIFY(collection1.parentCollection() == mStore->topLevelCollection()); + + QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1")); + KPIM::Maildir md1 = topLevelMd.subFolder(collection1.remoteId()); + QVERIFY(md1.isValid()); + + Collection collection2; + collection2.setName(QStringLiteral("collection2")); + job = mStore->createCollection(collection2, mStore->topLevelCollection()); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection2 = job->collection(); + QVERIFY(!collection2.remoteId().isEmpty()); + QVERIFY(collection2.parentCollection() == mStore->topLevelCollection()); + + QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1") << QStringLiteral("collection2")); + KPIM::Maildir md2 = topLevelMd.subFolder(collection2.remoteId()); + QVERIFY(md2.isValid()); + + // test creating second level collections + Collection collection1_1; + collection1_1.setName(QStringLiteral("collection1_1")); + job = mStore->createCollection(collection1_1, collection1); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection1_1 = job->collection(); + QVERIFY(!collection1_1.remoteId().isEmpty()); + QVERIFY(collection1_1.parentCollection() == collection1); + + QCOMPARE(md1.subFolderList(), QStringList() << QStringLiteral("collection1_1")); + KPIM::Maildir md1_1 = md1.subFolder(collection1_1.remoteId()); + QVERIFY(md1_1.isValid()); + + Collection collection1_2; + collection1_2.setName(QStringLiteral("collection1_2")); + job = mStore->createCollection(collection1_2, collection1); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection1_2 = job->collection(); + QVERIFY(!collection1_2.remoteId().isEmpty()); + QVERIFY(collection1_2.parentCollection() == collection1); + + QCOMPARE(md1.subFolderList(), QStringList() << QStringLiteral("collection1_1") << QStringLiteral("collection1_2")); + KPIM::Maildir md1_2 = md1.subFolder(collection1_2.remoteId()); + QVERIFY(md1_2.isValid()); + + QCOMPARE(md2.subFolderList(), QStringList()); +} + +void CollectionCreateTest::testMaildirTree() +{ + KPIM::Maildir topLevelMd(mDir->path(), true); + QVERIFY(topLevelMd.isValid()); + + KPIM::Maildir md1(topLevelMd.addSubFolder("collection1"), false); + + KPIM::Maildir md1_2(md1.addSubFolder("collection1_2"), false); + + mStore->setPath(mDir->path()); + + FileStore::CollectionCreateJob *job = 0; + + // test creating first level collections + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + job = mStore->createCollection(collection1, mStore->topLevelCollection()); + QVERIFY(job != 0); + + QVERIFY(job->exec()); // works because it already exists + QCOMPARE(job->error(), 0); + + collection1 = job->collection(); + QVERIFY(!collection1.remoteId().isEmpty()); + QVERIFY(collection1.parentCollection() == mStore->topLevelCollection()); + + Collection collection2; + collection2.setName(QStringLiteral("collection2")); + job = mStore->createCollection(collection2, mStore->topLevelCollection()); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection2 = job->collection(); + QVERIFY(!collection2.remoteId().isEmpty()); + QVERIFY(collection2.parentCollection() == mStore->topLevelCollection()); + + QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1") << QStringLiteral("collection2")); + KPIM::Maildir md2 = topLevelMd.subFolder(collection2.remoteId()); + QVERIFY(md2.isValid()); + + // test creating second level collections + Collection collection1_1; + collection1_1.setName(QStringLiteral("collection1_1")); + job = mStore->createCollection(collection1_1, collection1); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection1_1 = job->collection(); + QVERIFY(!collection1_1.remoteId().isEmpty()); + QCOMPARE(collection1_1.parentCollection().remoteId(), QStringLiteral("collection1")); + + QCOMPARE(md1.subFolderList(), QStringList() << QStringLiteral("collection1_1") << QStringLiteral("collection1_2")); + KPIM::Maildir md1_1 = md1.subFolder(collection1_1.remoteId()); + QVERIFY(md1_1.isValid()); + + Collection collection1_2; + collection1_2.setName(QStringLiteral("collection1_2")); + job = mStore->createCollection(collection1_2, collection1); + QVERIFY(job != 0); + + QVERIFY(job->exec()); // works because it already exists + QCOMPARE(job->error(), 0); + + collection1_2 = job->collection(); + QVERIFY(!collection1_2.remoteId().isEmpty()); + QCOMPARE(collection1_2.parentCollection().remoteId(), QStringLiteral("collection1")); + + QCOMPARE(md2.subFolderList(), QStringList()); +} + +void CollectionCreateTest::testMixedTree() +{ + KPIM::Maildir topLevelMd(mDir->path(), true); + QVERIFY(topLevelMd.isValid()); + + // simulate a first level MBox + QFileInfo fileInfo1(mDir->path(), QStringLiteral("collection1")); + QFile file1(fileInfo1.absoluteFilePath()); + file1.open(QIODevice::WriteOnly); + file1.close(); + QVERIFY(fileInfo1.exists()); + + mStore->setPath(mDir->path()); + + FileStore::CollectionCreateJob *job = 0; + + // test creating first level collections + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + job = mStore->createCollection(collection1, mStore->topLevelCollection()); + QVERIFY(job != 0); + + QVERIFY(!job->exec()); // fails, there is an MBox with that name + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + collection1 = job->collection(); + QVERIFY(collection1.remoteId().isEmpty()); + + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + Collection collection2; + collection2.setName(QStringLiteral("collection2")); + job = mStore->createCollection(collection2, mStore->topLevelCollection()); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection2 = job->collection(); + QVERIFY(!collection2.remoteId().isEmpty()); + QVERIFY(collection2.parentCollection() == mStore->topLevelCollection()); + + // mbox does not show up as a maildir subfolder + QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection2")); + KPIM::Maildir md2 = topLevelMd.subFolder(collection2.remoteId()); + QVERIFY(md2.isValid()); + + // test creating second level collections inside mbox + Collection collection1_1; + collection1_1.setName(QStringLiteral("collection1_1")); + job = mStore->createCollection(collection1_1, collection1); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection1_1 = job->collection(); + QVERIFY(!collection1_1.remoteId().isEmpty()); + QCOMPARE(collection1_1.parentCollection().remoteId(), QStringLiteral("collection1")); + + // treat the MBox subdir path like a top level maildir + KPIM::Maildir md1(KPIM::Maildir::subDirPathForFolderPath(fileInfo1.absoluteFilePath()), true); + KPIM::Maildir md1_1 = md1.subFolder(collection1_1.remoteId()); + QVERIFY(md1_1.isValid()); + + QCOMPARE(md1.subFolderList(), QStringList() << QStringLiteral("collection1_1")); +} + +QTEST_MAIN(CollectionCreateTest) + +#include "collectioncreatetest.moc" + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/collectiondeletetest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/collectiondeletetest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/collectiondeletetest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/collectiondeletetest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,468 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" + +#include "filestore/collectiondeletejob.h" + +#include "libmaildir/maildir.h" + +#include + +#include +#include +#include + +using namespace Akonadi; + +class CollectionDeleteTest : public QObject +{ + Q_OBJECT + +public: + CollectionDeleteTest() : QObject(), mStore(0), mDir(0) {} + ~CollectionDeleteTest() + { + delete mStore; + delete mDir; + } + +private: + MixedMaildirStore *mStore; + QTemporaryDir *mDir; + +private Q_SLOTS: + void init(); + void cleanup(); + void testNonExisting(); + void testLeaves(); + void testSubTrees(); +}; + +void CollectionDeleteTest::init() +{ + mStore = new MixedMaildirStore; + + mDir = new QTemporaryDir; + QVERIFY(mDir->isValid()); + QVERIFY(QDir(mDir->path()).exists()); +} + +void CollectionDeleteTest::cleanup() +{ + delete mStore; + mStore = 0; + delete mDir; + mDir = 0; +} + +void CollectionDeleteTest::testNonExisting() +{ + KPIM::Maildir topLevelMd(mDir->path(), true); + QVERIFY(topLevelMd.isValid(false)); + + KPIM::Maildir md1(topLevelMd.addSubFolder("collection1"), false); + KPIM::Maildir md1_2(md1.addSubFolder("collection1_2"), false); + + KPIM::Maildir md2(topLevelMd.addSubFolder("collection2"), false); + + // simulate mbox + QFileInfo fileInfo1(mDir->path(), QStringLiteral("collection3")); + QFile file1(fileInfo1.absoluteFilePath()); + file1.open(QIODevice::WriteOnly); + file1.close(); + QVERIFY(fileInfo1.exists()); + + // simulate mbox with empty subtree + QFileInfo fileInfo2(mDir->path(), QStringLiteral("collection4")); + QFile file2(fileInfo2.absoluteFilePath()); + file2.open(QIODevice::WriteOnly); + file2.close(); + QVERIFY(fileInfo2.exists()); + + QFileInfo subDirInfo2(KPIM::Maildir::subDirPathForFolderPath(fileInfo2.absoluteFilePath())); + QDir topDir(mDir->path()); + QVERIFY(topDir.mkpath(subDirInfo2.absoluteFilePath())); + + mStore->setPath(mDir->path()); + + FileStore::CollectionDeleteJob *job = 0; + + // test fail of deleting first level collection + Collection collection5; + collection5.setName(QStringLiteral("collection5")); + collection5.setRemoteId(QStringLiteral("collection5")); + collection5.setParentCollection(mStore->topLevelCollection()); + job = mStore->deleteCollection(collection5); + QVERIFY(job != 0); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1") << QStringLiteral("collection2")); + QVERIFY(fileInfo1.exists()); + + // test fail of deleting second level collection in maildir leaf parent + Collection collection2; + collection2.setName(QStringLiteral("collection2")); + collection2.setRemoteId(QStringLiteral("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + Collection collection2_1; + collection2_1.setName(QStringLiteral("collection2_1")); + collection2_1.setRemoteId(QStringLiteral("collection2_1")); + collection2_1.setParentCollection(collection2); + job = mStore->deleteCollection(collection2_1); + QVERIFY(job != 0); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1") << QStringLiteral("collection2")); + + // test fail of deleting second level collection in maildir parent with subtree + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + Collection collection1_1; + collection1_1.setName(QStringLiteral("collection1_1")); + collection1_1.setRemoteId(QStringLiteral("collection1_1")); + collection1_1.setParentCollection(collection1); + job = mStore->deleteCollection(collection1_1); + QVERIFY(job != 0); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1") << QStringLiteral("collection2")); + QCOMPARE(md1.subFolderList(), QStringList() << QStringLiteral("collection1_2")); + + // test fail of deleting second level collection in mbox leaf parent + Collection collection3; + collection3.setName(QStringLiteral("collection3")); + collection3.setRemoteId(QStringLiteral("collection3")); + collection3.setParentCollection(mStore->topLevelCollection()); + + Collection collection3_1; + collection3_1.setName(QStringLiteral("collection3_1")); + collection3_1.setRemoteId(QStringLiteral("collection3_1")); + collection3_1.setParentCollection(collection3); + job = mStore->deleteCollection(collection3_1); + QVERIFY(job != 0); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + QVERIFY(fileInfo1.exists()); + + // test fail of deleting second level collection in mbox parent with subtree + Collection collection4; + collection4.setName(QStringLiteral("collection4")); + collection4.setRemoteId(QStringLiteral("collection4")); + collection4.setParentCollection(mStore->topLevelCollection()); + + Collection collection4_1; + collection4_1.setName(QStringLiteral("collection4_1")); + collection4_1.setRemoteId(QStringLiteral("collection4_1")); + collection4_1.setParentCollection(collection4); + job = mStore->deleteCollection(collection4_1); + QVERIFY(job != 0); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + QVERIFY(fileInfo2.exists()); + QVERIFY(subDirInfo2.exists()); + + // test fail of deleting second level collection with non existent parent + Collection collection5_1; + collection5_1.setName(QStringLiteral("collection5_1")); + collection5_1.setRemoteId(QStringLiteral("collection5_1")); + collection5_1.setParentCollection(collection5); + job = mStore->deleteCollection(collection5_1); + QVERIFY(job != 0); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1") << QStringLiteral("collection2")); + QVERIFY(fileInfo1.exists()); + QCOMPARE(md1.subFolderList(), QStringList() << QStringLiteral("collection1_2")); +} + +void CollectionDeleteTest::testLeaves() +{ + KPIM::Maildir topLevelMd(mDir->path(), true); + QVERIFY(topLevelMd.isValid(false)); + + QDir topDir(mDir->path()); + + KPIM::Maildir md1(topLevelMd.addSubFolder("collection1"), false); + KPIM::Maildir md1_2(md1.addSubFolder("collection1_2"), false); + + // simulate second level mbox in maildir parent + QFileInfo fileInfo1_1(KPIM::Maildir::subDirPathForFolderPath(md1.path()), + QStringLiteral("collection1_1")); + QFile file1_1(fileInfo1_1.absoluteFilePath()); + file1_1.open(QIODevice::WriteOnly); + file1_1.close(); + QVERIFY(fileInfo1_1.exists()); + + KPIM::Maildir md2(topLevelMd.addSubFolder("collection2"), false); + + // simulate first level mbox + QFileInfo fileInfo3(mDir->path(), QStringLiteral("collection3")); + QFile file3(fileInfo3.absoluteFilePath()); + file3.open(QIODevice::WriteOnly); + file3.close(); + QVERIFY(fileInfo3.exists()); + + // simulate first level mbox with subtree + QFileInfo fileInfo4(mDir->path(), QStringLiteral("collection4")); + QFile file4(fileInfo4.absoluteFilePath()); + file4.open(QIODevice::WriteOnly); + file4.close(); + QVERIFY(fileInfo4.exists()); + + QFileInfo subDirInfo4(KPIM::Maildir::subDirPathForFolderPath(fileInfo4.absoluteFilePath())); + QVERIFY(topDir.mkpath(subDirInfo4.absoluteFilePath())); + + KPIM::Maildir md4(subDirInfo4.absoluteFilePath(), true); + KPIM::Maildir md4_1(md4.addSubFolder("collection4_1"), false); + + // simulate second level mbox in mbox parent + QFileInfo fileInfo4_2(subDirInfo4.absoluteFilePath(), + QStringLiteral("collection4_2")); + QFile file4_2(fileInfo4_2.absoluteFilePath()); + file4_2.open(QIODevice::WriteOnly); + file4_2.close(); + QVERIFY(fileInfo4_2.exists()); + + mStore->setPath(mDir->path()); + + FileStore::CollectionDeleteJob *job = 0; + + // test second level leaves in maildir parent + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + Collection collection1_1; + collection1_1.setName(QStringLiteral("collection1_1")); + collection1_1.setRemoteId(QStringLiteral("collection1_1")); + collection1_1.setParentCollection(collection1); + job = mStore->deleteCollection(collection1_1); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + fileInfo1_1.refresh(); + QVERIFY(!fileInfo1_1.exists()); + + Collection collection1_2; + collection1_2.setName(QStringLiteral("collection1_2")); + collection1_2.setRemoteId(QStringLiteral("collection1_2")); + collection1_2.setParentCollection(collection1); + job = mStore->deleteCollection(collection1_2); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + QVERIFY(!md1_2.isValid(false)); + QCOMPARE(md1.subFolderList(), QStringList()); + + // test second level leaves in mbox parent + Collection collection4; + collection4.setName(QStringLiteral("collection4")); + collection4.setRemoteId(QStringLiteral("collection4")); + collection4.setParentCollection(mStore->topLevelCollection()); + + Collection collection4_1; + collection4_1.setName(QStringLiteral("collection4_1")); + collection4_1.setRemoteId(QStringLiteral("collection4_1")); + collection4_1.setParentCollection(collection4); + job = mStore->deleteCollection(collection4_1); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + QVERIFY(!md4_1.isValid(false)); + QCOMPARE(md4.subFolderList(), QStringList()); + + Collection collection4_2; + collection4_2.setName(QStringLiteral("collection4_2")); + collection4_2.setRemoteId(QStringLiteral("collection4_2")); + collection4_2.setParentCollection(collection4); + job = mStore->deleteCollection(collection4_2); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + fileInfo4_2.refresh(); + QVERIFY(!fileInfo4_2.exists()); + + // test deleting of first level leaves + Collection collection2; + collection2.setName(QStringLiteral("collection2")); + collection2.setRemoteId(QStringLiteral("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + job = mStore->deleteCollection(collection2); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + QVERIFY(!md2.isValid(false)); + QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1")); + + Collection collection3; + collection3.setName(QStringLiteral("collection3")); + collection3.setRemoteId(QStringLiteral("collection3")); + collection3.setParentCollection(mStore->topLevelCollection()); + + job = mStore->deleteCollection(collection3); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + fileInfo3.refresh(); + QVERIFY(!fileInfo3.exists()); + + // test deleting of first level leaves with empty subtrees + QFileInfo subDirInfo1(KPIM::Maildir::subDirPathForFolderPath(md1.path())); + QVERIFY(subDirInfo1.exists()); + + job = mStore->deleteCollection(collection1); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + QVERIFY(!md1.isValid(false)); + subDirInfo1.refresh(); + QVERIFY(!subDirInfo1.exists()); + QCOMPARE(topLevelMd.subFolderList(), QStringList()); + + job = mStore->deleteCollection(collection4); + QVERIFY(job != 0); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + fileInfo4.refresh(); + QVERIFY(!fileInfo4.exists()); + subDirInfo4.refresh(); + QVERIFY(!subDirInfo4.exists()); +} + +void CollectionDeleteTest::testSubTrees() +{ + KPIM::Maildir topLevelMd(mDir->path(), true); + QVERIFY(topLevelMd.isValid(false)); + + QDir topDir(mDir->path()); + + KPIM::Maildir md1(topLevelMd.addSubFolder("collection1"), false); + KPIM::Maildir md1_2(md1.addSubFolder("collection1_2"), false); + + // simulate second level mbox in maildir parent + QFileInfo fileInfo1_1(KPIM::Maildir::subDirPathForFolderPath(md1.path()), + QStringLiteral("collection1_1")); + QFile file1_1(fileInfo1_1.absoluteFilePath()); + file1_1.open(QIODevice::WriteOnly); + file1_1.close(); + QVERIFY(fileInfo1_1.exists()); + + // simulate first level mbox with subtree + QFileInfo fileInfo2(mDir->path(), QStringLiteral("collection2")); + QFile file2(fileInfo2.absoluteFilePath()); + file2.open(QIODevice::WriteOnly); + file2.close(); + QVERIFY(fileInfo2.exists()); + + QFileInfo subDirInfo2(KPIM::Maildir::subDirPathForFolderPath(fileInfo2.absoluteFilePath())); + QVERIFY(topDir.mkpath(subDirInfo2.absoluteFilePath())); + + KPIM::Maildir md2(subDirInfo2.absoluteFilePath(), true); + KPIM::Maildir md2_1(md2.addSubFolder("collection2_1"), false); + + // simulate second level mbox in mbox parent + QFileInfo fileInfo2_2(subDirInfo2.absoluteFilePath(), + QStringLiteral("collection2_2")); + QFile file2_2(fileInfo2_2.absoluteFilePath()); + file2_2.open(QIODevice::WriteOnly); + file2_2.close(); + QVERIFY(fileInfo2_2.exists()); + + mStore->setPath(mDir->path()); + + FileStore::CollectionDeleteJob *job = 0; + + // test deleting maildir subtree + QFileInfo subDirInfo1(KPIM::Maildir::subDirPathForFolderPath(md1.path())); + QVERIFY(subDirInfo1.exists()); + + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + job = mStore->deleteCollection(collection1); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + QVERIFY(!md1.isValid(false)); + QVERIFY(!md1_2.isValid(false)); + fileInfo1_1.refresh(); + QVERIFY(!fileInfo1_1.exists()); + + // test deleting mbox subtree + Collection collection2; + collection2.setName(QStringLiteral("collection2")); + collection2.setRemoteId(QStringLiteral("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + job = mStore->deleteCollection(collection2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + fileInfo2.refresh(); + QVERIFY(!fileInfo2.exists()); + QVERIFY(!md2_1.isValid(false)); + fileInfo2_2.refresh(); + QVERIFY(!fileInfo2_2.exists()); + QVERIFY(!subDirInfo2.exists()); +} + +QTEST_MAIN(CollectionDeleteTest) + +#include "collectiondeletetest.moc" + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/collectionfetchtest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/collectionfetchtest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/collectionfetchtest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/collectionfetchtest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,476 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" + +#include "filestore/collectionfetchjob.h" + +#include "libmaildir/maildir.h" + +#include + +#include + +#include + +#include +#include +#include + +using namespace Akonadi; + +static Collection::List collectionsFromSpy(QSignalSpy *spy) +{ + Collection::List collections; + + QListIterator > it(*spy); + while (it.hasNext()) { + const QList invocation = it.next(); + Q_ASSERT(invocation.count() == 1); + + collections << invocation.first().value(); + } + + return collections; +} + +class CollectionFetchTest : public QObject +{ + Q_OBJECT + +public: + CollectionFetchTest() : QObject(), mStore(0), mDir(0) + { + // for monitoring signals + qRegisterMetaType(); + } + + ~CollectionFetchTest() + { + delete mStore; + delete mDir; + } + +private: + MixedMaildirStore *mStore; + QTemporaryDir *mDir; + +private Q_SLOTS: + void init(); + void cleanup(); + void testEmptyDir(); + void testMixedTree(); +}; + +void CollectionFetchTest::init() +{ + mStore = new MixedMaildirStore; + + mDir = new QTemporaryDir; + QVERIFY(mDir->isValid()); + QVERIFY(QDir(mDir->path()).exists()); +} + +void CollectionFetchTest::cleanup() +{ + delete mStore; + mStore = 0; + delete mDir; + mDir = 0; +} + +void CollectionFetchTest::testEmptyDir() +{ + mStore->setPath(mDir->path()); + + FileStore::CollectionFetchJob *job = 0; + QSignalSpy *spy = 0; + Collection::List collections; + + // test base fetch of top level collection + job = mStore->fetchCollections(mStore->topLevelCollection(), FileStore::CollectionFetchJob::Base); + + spy = new QSignalSpy(job, SIGNAL(collectionsReceived(Akonadi::Collection::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + QCOMPARE(spy->count(), 1); + + collections = collectionsFromSpy(spy); + QCOMPARE(collections.count(), 1); + QCOMPARE(collections.first(), mStore->topLevelCollection()); + QCOMPARE(job->collections(), collections); + + // test first level fetch of top level collection + job = mStore->fetchCollections(mStore->topLevelCollection(), FileStore::CollectionFetchJob::FirstLevel); + + spy = new QSignalSpy(job, SIGNAL(collectionsReceived(Akonadi::Collection::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + QCOMPARE(spy->count(), 0); + + collections = collectionsFromSpy(spy); + QCOMPARE(collections.count(), 0); + QCOMPARE(job->collections(), collections); + + // test recursive fetch of top level collection + job = mStore->fetchCollections(mStore->topLevelCollection(), FileStore::CollectionFetchJob::Recursive); + + spy = new QSignalSpy(job, SIGNAL(collectionsReceived(Akonadi::Collection::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + QCOMPARE(spy->count(), 0); + + collections = collectionsFromSpy(spy); + QCOMPARE(collections.count(), 0); + QCOMPARE(job->collections(), collections); + + // test fail of base fetching non existent collection + Collection collection; + collection.setName(QStringLiteral("collection")); + collection.setRemoteId(QStringLiteral("collection")); + collection.setParentCollection(mStore->topLevelCollection()); + + job = mStore->fetchCollections(collection, FileStore::CollectionFetchJob::Base); + + spy = new QSignalSpy(job, SIGNAL(collectionsReceived(Akonadi::Collection::List))); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + QCOMPARE(spy->count(), 0); + + collections = collectionsFromSpy(spy); + QCOMPARE(collections.count(), 0); + QCOMPARE(job->collections(), collections); + + // test fail of first level fetching non existent collection + job = mStore->fetchCollections(collection, FileStore::CollectionFetchJob::FirstLevel); + + spy = new QSignalSpy(job, SIGNAL(collectionsReceived(Akonadi::Collection::List))); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + QCOMPARE(spy->count(), 0); + + collections = collectionsFromSpy(spy); + QCOMPARE(collections.count(), 0); + QCOMPARE(job->collections(), collections); + + // test fail of recursive fetching non existent collection + job = mStore->fetchCollections(collection, FileStore::CollectionFetchJob::FirstLevel); + + spy = new QSignalSpy(job, SIGNAL(collectionsReceived(Akonadi::Collection::List))); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + QCOMPARE(spy->count(), 0); + + collections = collectionsFromSpy(spy); + QCOMPARE(collections.count(), 0); + QCOMPARE(job->collections(), collections); +} + +void CollectionFetchTest::testMixedTree() +{ + QDir topDir(mDir->path()); + + KPIM::Maildir topLevelMd(mDir->path(), true); + QVERIFY(topLevelMd.isValid()); + + KPIM::Maildir md1(topLevelMd.addSubFolder("collection1"), false); + KPIM::Maildir md1_2(md1.addSubFolder("collection1_2"), false); + KPIM::Maildir md1_2_1(md1_2.addSubFolder("collection1_2_1"), false); + + // simulate second level mbox in maildir parent + QFileInfo fileInfo1_1(KPIM::Maildir::subDirPathForFolderPath(md1.path()), + QStringLiteral("collection1_1")); + QFile file1_1(fileInfo1_1.absoluteFilePath()); + file1_1.open(QIODevice::WriteOnly); + file1_1.close(); + QVERIFY(fileInfo1_1.exists()); + + QFileInfo subDirInfo1_1(KPIM::Maildir::subDirPathForFolderPath(fileInfo1_1.absoluteFilePath())); + QVERIFY(topDir.mkpath(subDirInfo1_1.absoluteFilePath())); + KPIM::Maildir md1_1(subDirInfo1_1.absoluteFilePath(), true); + KPIM::Maildir md1_1_1(md1_1.addSubFolder("collection1_1_1"), false); + + // simulate third level mbox in mbox parent + QFileInfo fileInfo1_1_2(md1_1.path(), QStringLiteral("collection1_1_2")); + QFile file1_1_2(fileInfo1_1_2.absoluteFilePath()); + file1_1_2.open(QIODevice::WriteOnly); + file1_1_2.close(); + QVERIFY(fileInfo1_1_2.exists()); + + KPIM::Maildir md2(topLevelMd.addSubFolder("collection2"), false); + + // simulate first level mbox + QFileInfo fileInfo3(mDir->path(), QStringLiteral("collection3")); + QFile file3(fileInfo3.absoluteFilePath()); + file3.open(QIODevice::WriteOnly); + file3.close(); + QVERIFY(fileInfo3.exists()); + + // simulate first level mbox with subtree + QFileInfo fileInfo4(mDir->path(), QStringLiteral("collection4")); + QFile file4(fileInfo4.absoluteFilePath()); + file4.open(QIODevice::WriteOnly); + file4.close(); + QVERIFY(fileInfo4.exists()); + + QFileInfo subDirInfo4(KPIM::Maildir::subDirPathForFolderPath(fileInfo4.absoluteFilePath())); + QVERIFY(topDir.mkpath(subDirInfo4.absoluteFilePath())); + + KPIM::Maildir md4(subDirInfo4.absoluteFilePath(), true); + KPIM::Maildir md4_1(md4.addSubFolder("collection4_1"), false); + + // simulate second level mbox in mbox parent + QFileInfo fileInfo4_2(subDirInfo4.absoluteFilePath(), + QStringLiteral("collection4_2")); + QFile file4_2(fileInfo4_2.absoluteFilePath()); + file4_2.open(QIODevice::WriteOnly); + file4_2.close(); + QVERIFY(fileInfo4_2.exists()); + + QSet firstLevelNames; + firstLevelNames << md1.name() << md2.name() << fileInfo3.fileName() << fileInfo4.fileName(); + + QSet secondLevelNames; + secondLevelNames << md1_2.name() << md4_1.name() + << fileInfo1_1.fileName() << fileInfo4_2.fileName(); + + QSet thirdLevelNames; + thirdLevelNames << md1_1_1.name() << fileInfo1_1_2.fileName() << md1_2_1.name(); + + mStore->setPath(mDir->path()); + //mDir = 0; + + FileStore::CollectionFetchJob *job = 0; + QSignalSpy *spy = 0; + Collection::List collections; + + // test base fetch of top level collection + job = mStore->fetchCollections(mStore->topLevelCollection(), FileStore::CollectionFetchJob::Base); + + spy = new QSignalSpy(job, SIGNAL(collectionsReceived(Akonadi::Collection::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + QCOMPARE(spy->count(), 1); + + collections = collectionsFromSpy(spy); + QCOMPARE(collections.count(), 1); + QCOMPARE(collections.first(), mStore->topLevelCollection()); + QCOMPARE(job->collections(), collections); + + // test first level fetch of top level collection + job = mStore->fetchCollections(mStore->topLevelCollection(), FileStore::CollectionFetchJob::FirstLevel); + + spy = new QSignalSpy(job, SIGNAL(collectionsReceived(Akonadi::Collection::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + QVERIFY(spy->count() > 0); + + collections = collectionsFromSpy(spy); + QCOMPARE(collections.count(), firstLevelNames.count()); + QCOMPARE(job->collections(), collections); + + Q_FOREACH (const Collection &collection, collections) { + QVERIFY(!collection.remoteId().isEmpty()); + QCOMPARE(collection.remoteId(), collection.name()); + QCOMPARE(collection.contentMimeTypes(), QStringList() << Collection::mimeType() << KMime::Message::mimeType()); + + QCOMPARE(collection.rights(), Collection::CanCreateItem | + Collection::CanChangeItem | + Collection::CanDeleteItem | + Collection::CanCreateCollection | + Collection::CanChangeCollection | + Collection::CanDeleteCollection); + + QCOMPARE(collection.parentCollection(), mStore->topLevelCollection()); + QVERIFY(firstLevelNames.contains(collection.name())); + } + + // test recursive fetch of top level collection + job = mStore->fetchCollections(mStore->topLevelCollection(), FileStore::CollectionFetchJob::Recursive); + + spy = new QSignalSpy(job, SIGNAL(collectionsReceived(Akonadi::Collection::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + QVERIFY(spy->count() > 0); + + collections = collectionsFromSpy(spy); + QCOMPARE(collections.count(), + firstLevelNames.count() + secondLevelNames.count() + thirdLevelNames.count()); + QCOMPARE(job->collections(), collections); + + Q_FOREACH (const Collection &collection, collections) { + QVERIFY(!collection.remoteId().isEmpty()); + QCOMPARE(collection.remoteId(), collection.name()); + QCOMPARE(collection.contentMimeTypes(), QStringList() << Collection::mimeType() << KMime::Message::mimeType()); + + QCOMPARE(collection.rights(), Collection::CanCreateItem | + Collection::CanChangeItem | + Collection::CanDeleteItem | + Collection::CanCreateCollection | + Collection::CanChangeCollection | + Collection::CanDeleteCollection); + + if (firstLevelNames.contains(collection.name())) { + QCOMPARE(collection.parentCollection(), mStore->topLevelCollection()); + } else if (secondLevelNames.contains(collection.name())) { + QVERIFY(firstLevelNames.contains(collection.parentCollection().name())); + QCOMPARE(collection.parentCollection().parentCollection(), mStore->topLevelCollection()); + } else if (thirdLevelNames.contains(collection.name())) { + QVERIFY(secondLevelNames.contains(collection.parentCollection().name())); + QCOMPARE(collection.parentCollection().parentCollection().parentCollection(), + mStore->topLevelCollection()); + } + } + + // test base fetching all collections + Q_FOREACH (const Collection &collection, collections) { + job = mStore->fetchCollections(collection, FileStore::CollectionFetchJob::Base); + + spy = new QSignalSpy(job, SIGNAL(collectionsReceived(Akonadi::Collection::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + QCOMPARE(spy->count(), 1); + + const Collection::List list = collectionsFromSpy(spy); + QCOMPARE(list.count(), 1); + QCOMPARE(list.first(), collection); + QCOMPARE(job->collections(), list); + + const Collection col = list.first(); + QVERIFY(!col.remoteId().isEmpty()); + QCOMPARE(col.remoteId(), col.name()); + QCOMPARE(col.contentMimeTypes(), QStringList() << Collection::mimeType() << KMime::Message::mimeType()); + + QCOMPARE(col.rights(), Collection::CanCreateItem | + Collection::CanChangeItem | + Collection::CanDeleteItem | + Collection::CanCreateCollection | + Collection::CanChangeCollection | + Collection::CanDeleteCollection); + } + + // test first level fetching all collections + Q_FOREACH (const Collection &collection, collections) { + job = mStore->fetchCollections(collection, FileStore::CollectionFetchJob::FirstLevel); + + spy = new QSignalSpy(job, SIGNAL(collectionsReceived(Akonadi::Collection::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + const Collection::List list = collectionsFromSpy(spy); + QCOMPARE(job->collections(), list); + + Q_FOREACH (const Collection &childCollection, list) { + QCOMPARE(childCollection.parentCollection(), collection); + + QVERIFY(!childCollection.remoteId().isEmpty()); + QCOMPARE(childCollection.remoteId(), childCollection.name()); + QCOMPARE(childCollection.contentMimeTypes(), QStringList() << Collection::mimeType() << KMime::Message::mimeType()); + + QCOMPARE(childCollection.rights(), Collection::CanCreateItem | + Collection::CanChangeItem | + Collection::CanDeleteItem | + Collection::CanCreateCollection | + Collection::CanChangeCollection | + Collection::CanDeleteCollection); + } + + if (firstLevelNames.contains(collection.name())) { + Q_FOREACH (const Collection &childCollection, list) { + QVERIFY(secondLevelNames.contains(childCollection.name())); + } + } else if (secondLevelNames.contains(collection.name())) { + Q_FOREACH (const Collection &childCollection, list) { + QVERIFY(thirdLevelNames.contains(childCollection.name())); + } + if (collection.name() == md1_2.name()) { + QCOMPARE(list.count(), 1); + QCOMPARE(list.first().name(), md1_2_1.name()); + } else if (collection.name() == fileInfo1_1.fileName()) { + QCOMPARE(list.count(), 2); + } + } else { + QCOMPARE(list.count(), 0); + } + } + + // test recursive fetching all collections + Q_FOREACH (const Collection &collection, collections) { + job = mStore->fetchCollections(collection, FileStore::CollectionFetchJob::Recursive); + + spy = new QSignalSpy(job, SIGNAL(collectionsReceived(Akonadi::Collection::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + const Collection::List list = collectionsFromSpy(spy); + QCOMPARE(job->collections(), list); + + Q_FOREACH (const Collection &childCollection, list) { + QVERIFY(childCollection.parentCollection() == collection || + childCollection.parentCollection().parentCollection() == collection); + QVERIFY(!childCollection.remoteId().isEmpty()); + QCOMPARE(childCollection.remoteId(), childCollection.name()); + QCOMPARE(childCollection.contentMimeTypes(), QStringList() << Collection::mimeType() << KMime::Message::mimeType()); + + QCOMPARE(childCollection.rights(), Collection::CanCreateItem | + Collection::CanChangeItem | + Collection::CanDeleteItem | + Collection::CanCreateCollection | + Collection::CanChangeCollection | + Collection::CanDeleteCollection); + } + + if (firstLevelNames.contains(collection.name())) { + Q_FOREACH (const Collection &childCollection, list) { + QVERIFY(secondLevelNames.contains(childCollection.name()) || + thirdLevelNames.contains(childCollection.name())); + } + } else if (secondLevelNames.contains(collection.name())) { + Q_FOREACH (const Collection &childCollection, list) { + QVERIFY(thirdLevelNames.contains(childCollection.name())); + } + if (collection.name() == md1_2.name()) { + QCOMPARE(list.count(), 1); + QCOMPARE(list.first().name(), md1_2_1.name()); + } else if (collection.name() == fileInfo1_1.fileName()) { + QCOMPARE(list.count(), 2); + } + } else { + QCOMPARE(list.count(), 0); + } + } +} + +QTEST_MAIN(CollectionFetchTest) + +#include "collectionfetchtest.moc" + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/collectionmodifytest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/collectionmodifytest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/collectionmodifytest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/collectionmodifytest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,631 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" + +#include "testdatautil.h" + +#include "filestore/collectionmodifyjob.h" +#include "filestore/itemfetchjob.h" + +#include "libmaildir/maildir.h" + +#include + +#include +#include +#include + +using namespace Akonadi; + +class CollectionModifyTest : public QObject +{ + Q_OBJECT + +public: + CollectionModifyTest() : QObject(), mStore(0), mDir(0) {} + + ~CollectionModifyTest() + { + delete mStore; + delete mDir; + } + +private: + MixedMaildirStore *mStore; + QTemporaryDir *mDir; + +private Q_SLOTS: + void init(); + void cleanup(); + void testRename(); + void testIndexPreservation(); + void testIndexCacheUpdate(); +}; + +void CollectionModifyTest::init() +{ + mStore = new MixedMaildirStore; + + mDir = new QTemporaryDir; + QVERIFY(mDir->isValid()); + QVERIFY(QDir(mDir->path()).exists()); +} + +void CollectionModifyTest::cleanup() +{ + delete mStore; + mStore = 0; + delete mDir; + mDir = 0; +} + +void CollectionModifyTest::testRename() +{ + QDir topDir(mDir->path()); + QVERIFY(topDir.mkdir(QStringLiteral("topLevel"))); + QVERIFY(topDir.cd(QStringLiteral("topLevel"))); + + KPIM::Maildir topLevelMd(topDir.path(), true); + QVERIFY(topLevelMd.isValid(false)); + + KPIM::Maildir md1(topLevelMd.addSubFolder("collection1"), false); + KPIM::Maildir md1_2(md1.addSubFolder("collection1_2"), false); + + // simulate second level mbox in maildir parent + QFileInfo fileInfo1_1(KPIM::Maildir::subDirPathForFolderPath(md1.path()), + QStringLiteral("collection1_1")); + QFile file1_1(fileInfo1_1.absoluteFilePath()); + file1_1.open(QIODevice::WriteOnly); + file1_1.close(); + QVERIFY(fileInfo1_1.exists()); + + KPIM::Maildir md2(topLevelMd.addSubFolder("collection2"), false); + + // simulate first level mbox + QFileInfo fileInfo3(topDir.path(), QStringLiteral("collection3")); + QFile file3(fileInfo3.absoluteFilePath()); + file3.open(QIODevice::WriteOnly); + file3.close(); + QVERIFY(fileInfo3.exists()); + + // simulate first level mbox with subtree + QFileInfo fileInfo4(topDir.path(), QStringLiteral("collection4")); + QFile file4(fileInfo4.absoluteFilePath()); + file4.open(QIODevice::WriteOnly); + file4.close(); + QVERIFY(fileInfo4.exists()); + + QFileInfo subDirInfo4(KPIM::Maildir::subDirPathForFolderPath(fileInfo4.absoluteFilePath())); + QVERIFY(topDir.mkpath(subDirInfo4.absoluteFilePath())); + + KPIM::Maildir md4(subDirInfo4.absoluteFilePath(), true); + KPIM::Maildir md4_1(md4.addSubFolder("collection4_1"), false); + + // simulate second level mbox in mbox parent + QFileInfo fileInfo4_2(subDirInfo4.absoluteFilePath(), + QStringLiteral("collection4_2")); + QFile file4_2(fileInfo4_2.absoluteFilePath()); + file4_2.open(QIODevice::WriteOnly); + file4_2.close(); + QVERIFY(fileInfo4_2.exists()); + + mStore->setPath(topDir.path()); + + FileStore::CollectionModifyJob *job = 0; + Collection collection; + + // test renaming top level collection + topDir.cdUp(); + QVERIFY(!topDir.exists(QStringLiteral("newTopLevel"))); + + Collection topLevelCollection = mStore->topLevelCollection(); + topLevelCollection.setName(QStringLiteral("newTopLevel")); + job = mStore->modifyCollection(topLevelCollection); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + QVERIFY(topDir.exists(QStringLiteral("newTopLevel"))); + QVERIFY(!topDir.exists(QStringLiteral("topLevel"))); + QVERIFY(topDir.cd(QStringLiteral("newTopLevel"))); + QCOMPARE(mStore->path(), topDir.path()); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), mStore->path()); + QCOMPARE(collection, mStore->topLevelCollection()); + + // test failure of renaming again + job = mStore->modifyCollection(topLevelCollection); + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int) FileStore::Job::InvalidJobContext); + QCOMPARE(collection.remoteId(), mStore->path()); + QCOMPARE(collection, mStore->topLevelCollection()); + + // adjust local handles + topLevelMd = KPIM::Maildir(topDir.path(), true); + QVERIFY(topLevelMd.isValid(false)); + + md1 = topLevelMd.subFolder("collection1"); + QVERIFY(md1.isValid(false)); + md1_2 = md1.subFolder("collection1_2"); + + fileInfo1_1 = QFileInfo(KPIM::Maildir::subDirPathForFolderPath(md1.path()), + QStringLiteral("collection1_1")); + QVERIFY(fileInfo1_1.exists()); + + md2 = topLevelMd.subFolder("collection2"); + + fileInfo3 = QFileInfo(topDir.path(), QStringLiteral("collection3")); + QVERIFY(fileInfo3.exists()); + + fileInfo4 = QFileInfo(topDir.path(), QStringLiteral("collection4")); + QVERIFY(fileInfo4.exists()); + + subDirInfo4 = QFileInfo(KPIM::Maildir::subDirPathForFolderPath(fileInfo4.absoluteFilePath())); + QVERIFY(subDirInfo4.exists()); + + md4 = KPIM::Maildir(subDirInfo4.absoluteFilePath(), true); + QVERIFY(md4.isValid(false)); + md4_1 = md4.subFolder("collection4_1"); + + fileInfo4_2 = QFileInfo(subDirInfo4.absoluteFilePath(), + QStringLiteral("collection4_2")); + QVERIFY(fileInfo4_2.exists()); + + QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1") << QStringLiteral("collection2")); + + // test rename first level maildir leaf + Collection collection2; + collection2.setRemoteId(QStringLiteral("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + collection2.setName(QStringLiteral("collection2_renamed")); + + job = mStore->modifyCollection(collection2); + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection.name()); + QCOMPARE(collection, collection2); + QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1") << QStringLiteral("collection2_renamed")); + QVERIFY(!md2.isValid(false)); + md2 = topLevelMd.subFolder(collection.remoteId()); + QVERIFY(md2.isValid(false)); + + // test failure of renaming again + job = mStore->modifyCollection(collection2); + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int) FileStore::Job::InvalidJobContext); + QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1") << QStringLiteral("collection2_renamed")); + QVERIFY(md2.isValid(false)); + + // test renaming of first level mbox leaf + Collection collection3; + collection3.setRemoteId(QStringLiteral("collection3")); + collection3.setParentCollection(mStore->topLevelCollection()); + collection3.setName(QStringLiteral("collection3_renamed")); + + job = mStore->modifyCollection(collection3); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection.name()); + QCOMPARE(collection, collection3); + fileInfo3.refresh(); + QVERIFY(!fileInfo3.exists()); + fileInfo3 = QFileInfo(topDir.path(), collection.remoteId()); + QVERIFY(fileInfo3.exists()); + + // test failure of renaming again + job = mStore->modifyCollection(collection3); + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int) FileStore::Job::InvalidJobContext); + fileInfo3.refresh(); + QVERIFY(fileInfo3.exists()); + + // test renaming second level maildir in mbox parent + Collection collection4; + collection4.setRemoteId(QStringLiteral("collection4")); + collection4.setParentCollection(mStore->topLevelCollection()); + collection4.setName(QStringLiteral("collection4")); + + Collection collection4_1; + collection4_1.setRemoteId(QStringLiteral("collection4_1")); + collection4_1.setParentCollection(collection4); + collection4_1.setName(QStringLiteral("collection4_1_renamed")); + + job = mStore->modifyCollection(collection4_1); + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection.name()); + QCOMPARE(collection, collection4_1); + QCOMPARE(md4.subFolderList(), QStringList() << QStringLiteral("collection4_1_renamed")); + QVERIFY(!md4_1.isValid(false)); + md4_1 = md4.subFolder(collection.remoteId()); + QVERIFY(md4_1.isValid(false)); + + // test failure of renaming again + job = mStore->modifyCollection(collection4_1); + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int) FileStore::Job::InvalidJobContext); + QCOMPARE(md4.subFolderList(), QStringList() << QStringLiteral("collection4_1_renamed")); + QVERIFY(md4_1.isValid(false)); + + // test renaming of second level mbox in mbox parent + Collection collection4_2; + collection4_2.setRemoteId(QStringLiteral("collection4_2")); + collection4_2.setParentCollection(collection4); + collection4_2.setName(QStringLiteral("collection4_2_renamed")); + + job = mStore->modifyCollection(collection4_2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection.name()); + QCOMPARE(collection, collection4_2); + fileInfo4_2.refresh(); + QVERIFY(!fileInfo4_2.exists()); + fileInfo4_2 = QFileInfo(md4.path(), collection.remoteId()); + QVERIFY(fileInfo4_2.exists()); + + // test failure of renaming again + job = mStore->modifyCollection(collection4_2); + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int) FileStore::Job::InvalidJobContext); + fileInfo4_2.refresh(); + QVERIFY(fileInfo4_2.exists()); + + // test renaming of maildir with subtree + Collection collection1; + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + collection1.setName(QStringLiteral("collection1_renamed")); + + job = mStore->modifyCollection(collection1); + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection.name()); + QCOMPARE(collection, collection1); + QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1_renamed") << QStringLiteral("collection2_renamed")); + QVERIFY(!md1.isValid(false)); + md1 = topLevelMd.subFolder(collection.remoteId()); + QVERIFY(md1.isValid(false)); + fileInfo1_1.refresh(); + QVERIFY(!fileInfo1_1.exists()); + QVERIFY(!md1_2.isValid(false)); + fileInfo1_1 = QFileInfo(KPIM::Maildir::subDirPathForFolderPath(md1.path()), + QStringLiteral("collection1_1")); + QVERIFY(fileInfo1_1.exists()); + md1_2 = md1.subFolder(QStringLiteral("collection1_2")); + QVERIFY(md1_2.isValid(false)); + + // test failure of renaming again + job = mStore->modifyCollection(collection1); + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int) FileStore::Job::InvalidJobContext); + QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1_renamed") << QStringLiteral("collection2_renamed")); + QVERIFY(md2.isValid(false)); + QVERIFY(fileInfo1_1.exists()); + QVERIFY(md1_2.isValid(false)); + + // test renaming of mbox with subtree + collection4.setName(QStringLiteral("collection4_renamed")); + job = mStore->modifyCollection(collection4); + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection.name()); + QCOMPARE(collection, collection4); + fileInfo4.refresh(); + QVERIFY(!fileInfo4.exists()); + fileInfo4 = QFileInfo(topDir.path(), collection.remoteId()); + QVERIFY(fileInfo4.exists()); + md4 = KPIM::Maildir(KPIM::Maildir::subDirPathForFolderPath(fileInfo4.absoluteFilePath()), true); + QVERIFY(md4.isValid(false)); + + QVERIFY(!md4_1.isValid(false)); + fileInfo4_2.refresh(); + QVERIFY(!fileInfo4_2.exists()); + md4_1 = md4.subFolder(QStringLiteral("collection4_1_renamed")); + QVERIFY(md4_1.isValid(false)); + fileInfo4_2 = QFileInfo(md4.path(), QStringLiteral("collection4_2_renamed")); + QVERIFY(fileInfo4_2.exists()); + + // test failure of renaming again + job = mStore->modifyCollection(collection4); + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int) FileStore::Job::InvalidJobContext); + fileInfo4.refresh(); + QVERIFY(fileInfo4.exists()); +} + +void CollectionModifyTest::testIndexPreservation() +{ + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), mDir->path(), QStringLiteral("collection1"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), mDir->path(), QStringLiteral("collection2"))); + + mStore->setPath(mDir->path()); + + const QVariant colListVar = QVariant::fromValue(Collection::List()); + FileStore::CollectionModifyJob *job = 0; + FileStore::ItemFetchJob *itemFetch = 0; + QVariant var; + Collection::List collections; + Item::List items; + + QMap flagCounts; + + // test renaming mbox + Collection collection1; + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + collection1.setName(QStringLiteral("collection1_renamed")); + + job = mStore->modifyCollection(collection1); + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection1); + + const QFileInfo indexFileInfo1(mDir->path(), QStringLiteral(".collection1_renamed.index")); + QVERIFY(!indexFileInfo1.exists()); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collections.first()); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + + // test renaming maildir + Collection collection2; + collection2.setRemoteId(QStringLiteral("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + collection2.setName(QStringLiteral("collection2_renamed")); + + job = mStore->modifyCollection(collection2); + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection2); + + const QFileInfo indexFileInfo2(mDir->path(), QStringLiteral(".collection2_renamed.index")); + QVERIFY(!indexFileInfo2.exists()); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collections.first()); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + + flagCounts.clear(); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); +} + +void CollectionModifyTest::testIndexCacheUpdate() +{ + KPIM::Maildir topLevelMd(mDir->path(), true); + QVERIFY(topLevelMd.isValid(false)); + + KPIM::Maildir md1(topLevelMd.addSubFolder("collection1"), false); + + // simulate first level mbox + QFileInfo fileInfo2(mDir->path(), QStringLiteral("collection2")); + QFile file2(fileInfo2.absoluteFilePath()); + file2.open(QIODevice::WriteOnly); + file2.close(); + QVERIFY(fileInfo2.exists()); + + const QString colSubDir1 = KPIM::Maildir::subDirPathForFolderPath(md1.path()); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), colSubDir1, QStringLiteral("collection1_1"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), colSubDir1, QStringLiteral("collection1_2"))); + + const QString colSubDir2 = KPIM::Maildir::subDirPathForFolderPath(fileInfo2.absoluteFilePath()); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), colSubDir2, QStringLiteral("collection2_1"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), colSubDir2, QStringLiteral("collection2_2"))); + + mStore->setPath(mDir->path()); + + FileStore::CollectionModifyJob *job = 0; + FileStore::ItemFetchJob *itemFetch = 0; + Collection collection; + Item::List items; + QMap flagCounts; + + // preparation: load all second level items to make sure respective index data is cached + Collection collection1; + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + collection1.setName(QStringLiteral("collection1")); + + Collection collection1_1; + collection1_1.setRemoteId(QStringLiteral("collection1_1")); + collection1_1.setParentCollection(collection1); + collection1_1.setName(QStringLiteral("collection1_1")); + + itemFetch = mStore->fetchItems(collection1_1); + QVERIFY(itemFetch->exec()); + + Collection collection1_2; + collection1_2.setRemoteId(QStringLiteral("collection1_2")); + collection1_2.setParentCollection(collection1); + collection1_2.setName(QStringLiteral("collection1_2")); + + itemFetch = mStore->fetchItems(collection1_2); + QVERIFY(itemFetch->exec()); + Collection collection2; + collection2.setRemoteId(QStringLiteral("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + collection2.setName(QStringLiteral("collection2")); + + Collection collection2_1; + collection2_1.setRemoteId(QStringLiteral("collection2_1")); + collection2_1.setParentCollection(collection2); + collection2_1.setName(QStringLiteral("collection2_1")); + + itemFetch = mStore->fetchItems(collection2_1); + QVERIFY(itemFetch->exec()); + Collection collection2_2; + collection2_2.setRemoteId(QStringLiteral("collection2_2")); + collection2_2.setParentCollection(collection2); + collection2_2.setName(QStringLiteral("collection2_2")); + + itemFetch = mStore->fetchItems(collection2_2); + QVERIFY(itemFetch->exec()); + + // test renaming the maildir parent + collection1.setName(QStringLiteral("collection1_renamed")); + + job = mStore->modifyCollection(collection1); + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + + // get the items of the children and check the flags (see data/README) + collection1_1.setParentCollection(collection); + itemFetch = mStore->fetchItems(collection1_1); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + collection1_2.setParentCollection(collection); + itemFetch = mStore->fetchItems(collection1_2); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // test renaming the mbox parent + collection2.setName(QStringLiteral("collection2_renamed")); + + job = mStore->modifyCollection(collection2); + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + + // get the items of the children and check the flags (see data/README) + collection2_1.setParentCollection(collection); + itemFetch = mStore->fetchItems(collection2_1); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + collection2_2.setParentCollection(collection); + itemFetch = mStore->fetchItems(collection2_2); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); +} + +QTEST_MAIN(CollectionModifyTest) + +#include "collectionmodifytest.moc" + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/collectionmovetest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/collectionmovetest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/collectionmovetest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/collectionmovetest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,2002 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" + +#include "testdatautil.h" + +#include "filestore/collectionmovejob.h" +#include "filestore/itemfetchjob.h" + +#include "libmaildir/maildir.h" + +#include + +#include +#include +#include + +using namespace Akonadi; + +class CollectionMoveTest : public QObject +{ + Q_OBJECT + +public: + CollectionMoveTest() : QObject(), mStore(0), mDir(0) {} + + ~CollectionMoveTest() + { + delete mStore; + delete mDir; + } + +private: + MixedMaildirStore *mStore; + QTemporaryDir *mDir; + +private Q_SLOTS: + void init(); + void cleanup(); + void testMoveToTopLevel(); + void testMoveToMaildir(); + void testMoveToMBox(); +}; + +void CollectionMoveTest::init() +{ + mStore = new MixedMaildirStore; + + mDir = new QTemporaryDir; + QVERIFY(mDir->isValid()); + QVERIFY(QDir(mDir->path()).exists()); +} + +void CollectionMoveTest::cleanup() +{ + delete mStore; + mStore = 0; + delete mDir; + mDir = 0; +} + +void CollectionMoveTest::testMoveToTopLevel() +{ + QDir topDir(mDir->path()); + + // top level dir + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection1"))); + QFileInfo fileInfo1(topDir, QStringLiteral("collection1")); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection2"))); + QFileInfo fileInfo2(topDir, QStringLiteral("collection2")); + + // first level maildir parent + QDir subDir1 = topDir; + QVERIFY(subDir1.mkdir(QStringLiteral(".collection1.directory"))); + QVERIFY(subDir1.cd(QStringLiteral(".collection1.directory"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), subDir1.path(), QStringLiteral("collection1_1"))); + QFileInfo fileInfo1_1(subDir1.path(), QStringLiteral("collection1_1")); + QVERIFY(fileInfo1_1.exists()); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), subDir1.path(), QStringLiteral("collection1_2"))); + QFileInfo fileInfo1_2(subDir1.path(), QStringLiteral("collection1_2")); + QVERIFY(fileInfo1_2.exists()); + + // first level mbox parent + QDir subDir2 = topDir; + QVERIFY(subDir2.mkdir(QStringLiteral(".collection2.directory"))); + QVERIFY(subDir2.cd(QStringLiteral(".collection2.directory"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), subDir2.path(), QStringLiteral("collection2_1"))); + QFileInfo fileInfo2_1(subDir2.path(), QStringLiteral("collection2_1")); + QVERIFY(fileInfo2_1.exists()); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), subDir2.path(), QStringLiteral("collection2_2"))); + QFileInfo fileInfo2_2(subDir2.path(), QStringLiteral("collection2_2")); + QVERIFY(fileInfo2_2.exists()); + + mStore->setPath(topDir.path()); + + // common variables + FileStore::CollectionMoveJob *job = 0; + FileStore::ItemFetchJob *itemFetch = 0; + Collection collection; + const QVariant colListVar = QVariant::fromValue(Collection::List()); + QVariant var; + Collection::List collections; + Item::List items; + QMap flagCounts; + + // test moving maildir from maildir parent + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + Collection collection1_1; + collection1_1.setName(QStringLiteral("collection1_1")); + collection1_1.setRemoteId(QStringLiteral("collection1_1")); + collection1_1.setParentCollection(collection1); + + job = mStore->moveCollection(collection1_1, mStore->topLevelCollection()); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_1.remoteId()); + QCOMPARE(collection.parentCollection(), mStore->topLevelCollection()); + + fileInfo1_1.refresh(); + QVERIFY(!fileInfo1_1.exists()); + fileInfo1_1 = QFileInfo(topDir.path(), collection.remoteId()); + QVERIFY(fileInfo1_1.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // test moving mbox from maildir parent + Collection collection1_2; + collection1_2.setName(QStringLiteral("collection1_2")); + collection1_2.setRemoteId(QStringLiteral("collection1_2")); + collection1_2.setParentCollection(collection1); + + job = mStore->moveCollection(collection1_2, mStore->topLevelCollection()); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_2.remoteId()); + QCOMPARE(collection.parentCollection(), mStore->topLevelCollection()); + + fileInfo1_2.refresh(); + QVERIFY(!fileInfo1_2.exists()); + fileInfo1_2 = QFileInfo(topDir.path(), collection.remoteId()); + QVERIFY(fileInfo1_2.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // test moving mbox from mbox parent + Collection collection2; + collection2.setName(QStringLiteral("collection2")); + collection2.setRemoteId(QStringLiteral("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + Collection collection2_1; + collection2_1.setName(QStringLiteral("collection2_1")); + collection2_1.setRemoteId(QStringLiteral("collection2_1")); + collection2_1.setParentCollection(collection2); + + job = mStore->moveCollection(collection2_1, mStore->topLevelCollection()); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection2_1.remoteId()); + QCOMPARE(collection.parentCollection(), mStore->topLevelCollection()); + + fileInfo2_1.refresh(); + QVERIFY(!fileInfo2_1.exists()); + fileInfo2_1 = QFileInfo(topDir.path(), collection.remoteId()); + QVERIFY(fileInfo2_1.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // test moving maildir from mbox parent + Collection collection2_2; + collection2_2.setName(QStringLiteral("collection2_2")); + collection2_2.setRemoteId(QStringLiteral("collection2_2")); + collection2_2.setParentCollection(collection2); + + job = mStore->moveCollection(collection2_2, mStore->topLevelCollection()); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection2_2.remoteId()); + QCOMPARE(collection.parentCollection(), mStore->topLevelCollection()); + + fileInfo2_2.refresh(); + QVERIFY(!fileInfo2_2.exists()); + fileInfo2_2 = QFileInfo(topDir.path(), collection.remoteId()); + QVERIFY(fileInfo2_2.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); +} + +void CollectionMoveTest::testMoveToMaildir() +{ + QDir topDir(mDir->path()); + + // top level dir + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection1"))); + QFileInfo fileInfo1(topDir, QStringLiteral("collection1")); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection2"))); + QFileInfo fileInfo2(topDir, QStringLiteral("collection2")); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection3"))); + QFileInfo fileInfo3(topDir, QStringLiteral("collection3")); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection4"))); + QFileInfo fileInfo4(topDir, QStringLiteral("collection4")); + + // first level maildir parent + QDir subDir1 = topDir; + QVERIFY(subDir1.mkdir(QStringLiteral(".collection1.directory"))); + QVERIFY(subDir1.cd(QStringLiteral(".collection1.directory"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), subDir1.path(), QStringLiteral("collection1_1"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), subDir1.path(), QStringLiteral("collection1_2"))); + + // first level mbox parent + QDir subDir4 = topDir; + QVERIFY(subDir4.mkdir(QStringLiteral(".collection4.directory"))); + QVERIFY(subDir4.cd(QStringLiteral(".collection4.directory"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), subDir4.path(), QStringLiteral("collection4_1"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), subDir4.path(), QStringLiteral("collection4_2"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), subDir4.path(), QStringLiteral("collection4_3"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), subDir4.path(), QStringLiteral("collection4_4"))); + + // target maildir + KPIM::Maildir topLevelMd(topDir.path(), true); + KPIM::Maildir targetMd(topLevelMd.addSubFolder(QStringLiteral("target")), false); + QVERIFY(targetMd.isValid()); + QDir subDirTarget; + + mStore->setPath(topDir.path()); + + // common variables + FileStore::CollectionMoveJob *job = 0; + FileStore::ItemFetchJob *itemFetch = 0; + Collection collection; + const QVariant colListVar = QVariant::fromValue(Collection::List()); + QVariant var; + Collection::List collections; + Item::List items; + QMap flagCounts; + + Collection target; + target.setName(QStringLiteral("target")); + target.setRemoteId(QStringLiteral("target")); + target.setParentCollection(mStore->topLevelCollection()); + + // test move leaf maildir into sibling + Collection collection2; + collection2.setName(QStringLiteral("collection2")); + collection2.setRemoteId(QStringLiteral("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + job = mStore->moveCollection(collection2, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + subDirTarget = topDir; + QVERIFY(subDirTarget.cd(QStringLiteral(".target.directory"))); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection2.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + fileInfo2.refresh(); + QVERIFY(!fileInfo2.exists()); + fileInfo2 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo2.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // test move leaf mbox into sibling + Collection collection3; + collection3.setName(QStringLiteral("collection3")); + collection3.setRemoteId(QStringLiteral("collection3")); + collection3.setParentCollection(mStore->topLevelCollection()); + + job = mStore->moveCollection(collection3, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection3.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + fileInfo3.refresh(); + QVERIFY(!fileInfo3.exists()); + fileInfo3 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo3.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // test move maildir with subtree into sibling + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + // load sub collection index data to check for correct cache updates + Collection collection1_1; + collection1_1.setName(QStringLiteral("collection1_1")); + collection1_1.setRemoteId(QStringLiteral("collection1_1")); + collection1_1.setParentCollection(collection1); + itemFetch = mStore->fetchItems(collection1_1); + QVERIFY(itemFetch->exec()); + + Collection collection1_2; + collection1_2.setName(QStringLiteral("collection1_2")); + collection1_2.setRemoteId(QStringLiteral("collection1_2")); + collection1_2.setParentCollection(collection1); + itemFetch = mStore->fetchItems(collection1_2); + QVERIFY(itemFetch->exec()); + + job = mStore->moveCollection(collection1, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + fileInfo1.refresh(); + QVERIFY(!fileInfo1.exists()); + fileInfo1 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo1.exists()); + QVERIFY(!subDir1.exists()); + subDir1 = subDirTarget; + QVERIFY(subDir1.cd(QStringLiteral(".collection1.directory"))); + QCOMPARE(subDir1.entryList(QStringList() << QStringLiteral("collection*")), + QStringList() << QStringLiteral("collection1_1") << QStringLiteral("collection1_2")); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // check for children cache path updates + collection1.setParentCollection(target); + collection1_1.setParentCollection(collection1); + collection1_2.setParentCollection(collection1); + + itemFetch = mStore->fetchItems(collection1_1); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + itemFetch = mStore->fetchItems(collection1_2); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // test move mbox with subtree into sibling + Collection collection4; + collection4.setName(QStringLiteral("collection4")); + collection4.setRemoteId(QStringLiteral("collection4")); + collection4.setParentCollection(mStore->topLevelCollection()); + + // load sub collection index data to check for correct cache updates + Collection collection4_1; + collection4_1.setName(QStringLiteral("collection4_1")); + collection4_1.setRemoteId(QStringLiteral("collection4_1")); + collection4_1.setParentCollection(collection4); + itemFetch = mStore->fetchItems(collection4_1); + QVERIFY(itemFetch->exec()); + + Collection collection4_2; + collection4_2.setName(QStringLiteral("collection4_2")); + collection4_2.setRemoteId(QStringLiteral("collection4_2")); + collection4_2.setParentCollection(collection4); + itemFetch = mStore->fetchItems(collection4_2); + QVERIFY(itemFetch->exec()); + + job = mStore->moveCollection(collection4, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection4.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + fileInfo4.refresh(); + QVERIFY(!fileInfo4.exists()); + fileInfo4 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo4.exists()); + QVERIFY(!subDir4.exists()); + subDir4 = subDirTarget; + QVERIFY(subDir4.cd(QStringLiteral(".collection4.directory"))); + QCOMPARE(subDir4.entryList(QStringList() << QStringLiteral("collection*")), + QStringList() << QStringLiteral("collection4_1") << QStringLiteral("collection4_2") + << QStringLiteral("collection4_3") << QStringLiteral("collection4_4") + ); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // check for children cache path updates + collection4.setParentCollection(target); + collection4_1.setParentCollection(collection4); + collection4_2.setParentCollection(collection4); + + itemFetch = mStore->fetchItems(collection4_1); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + itemFetch = mStore->fetchItems(collection4_2); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent maildir to parent's sibling + collection2.setParentCollection(target); + + job = mStore->moveCollection(collection1_1, collection2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + QDir subDir2 = subDirTarget; + QVERIFY(subDir2.cd(QStringLiteral(".collection2.directory"))); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_1.remoteId()); + QCOMPARE(collection.parentCollection(), collection2); + + QFileInfo fileInfo1_1(subDir1, collection.remoteId()); + QVERIFY(!fileInfo1_1.exists()); + fileInfo1_1 = QFileInfo(subDir2, collection.remoteId()); + QVERIFY(fileInfo1_1.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent maildir to parent's sibling + job = mStore->moveCollection(collection1_2, collection2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_2.remoteId()); + QCOMPARE(collection.parentCollection(), collection2); + + QFileInfo fileInfo1_2(subDir1, collection.remoteId()); + QVERIFY(!fileInfo1_2.exists()); + fileInfo1_2 = QFileInfo(subDir2, collection.remoteId()); + QVERIFY(fileInfo1_2.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent mbox to parent's sibling + job = mStore->moveCollection(collection4_1, collection2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection4_1.remoteId()); + QCOMPARE(collection.parentCollection(), collection2); + + QFileInfo fileInfo4_1(subDir4, collection.remoteId()); + QVERIFY(!fileInfo4_1.exists()); + fileInfo4_1 = QFileInfo(subDir2, collection.remoteId()); + QVERIFY(fileInfo4_1.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent mbox to parent's sibling + job = mStore->moveCollection(collection4_2, collection2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection4_2.remoteId()); + QCOMPARE(collection.parentCollection(), collection2); + + QFileInfo fileInfo4_2(subDir4, collection.remoteId()); + QVERIFY(!fileInfo4_2.exists()); + fileInfo4_2 = QFileInfo(subDir2, collection.remoteId()); + QVERIFY(fileInfo4_2.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent maildir to grandparent + collection1_1.setParentCollection(collection2); + + job = mStore->moveCollection(collection1_1, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_1.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + fileInfo1_1.refresh(); + QVERIFY(!fileInfo1_1.exists()); + fileInfo1_1 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo1_1.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent maildir to grandparent + collection1_2.setParentCollection(collection2); + job = mStore->moveCollection(collection1_2, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_2.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + fileInfo1_2.refresh(); + QVERIFY(!fileInfo1_2.exists()); + fileInfo1_2 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo1_2.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent mbox to grandparent + Collection collection4_3; + collection4_3.setName(QStringLiteral("collection4_3")); + collection4_3.setRemoteId(QStringLiteral("collection4_3")); + collection4_3.setParentCollection(collection4); + + job = mStore->moveCollection(collection4_3, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection4_3.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + QFileInfo fileInfo4_3(subDir4, collection.remoteId()); + QVERIFY(!fileInfo4_3.exists()); + fileInfo4_3 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo4_3.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent mbox to grandparent + Collection collection4_4; + collection4_4.setName(QStringLiteral("collection4_4")); + collection4_4.setRemoteId(QStringLiteral("collection4_4")); + collection4_4.setParentCollection(collection4); + + job = mStore->moveCollection(collection4_4, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection4_4.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + QFileInfo fileInfo4_4(subDir4, collection.remoteId()); + QVERIFY(!fileInfo4_4.exists()); + fileInfo4_4 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo4_4.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from maildir to grandchild + collection1_1.setParentCollection(target); + + job = mStore->moveCollection(collection1_1, collection2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_1.remoteId()); + QCOMPARE(collection.parentCollection(), collection2); + + fileInfo1_1.refresh(); + QVERIFY(!fileInfo1_1.exists()); + fileInfo1_1 = QFileInfo(subDir2, collection.remoteId()); + QVERIFY(fileInfo1_1.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from maildir to grandchild + collection1_2.setParentCollection(target); + + job = mStore->moveCollection(collection1_2, collection2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_2.remoteId()); + QCOMPARE(collection.parentCollection(), collection2); + + fileInfo1_2.refresh(); + QVERIFY(!fileInfo1_2.exists()); + fileInfo1_2 = QFileInfo(subDir2, collection.remoteId()); + QVERIFY(fileInfo1_2.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); +} + +void CollectionMoveTest::testMoveToMBox() +{ + QDir topDir(mDir->path()); + + // top level dir + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection1"))); + QFileInfo fileInfo1(topDir, QStringLiteral("collection1")); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection2"))); + QFileInfo fileInfo2(topDir, QStringLiteral("collection2")); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection3"))); + QFileInfo fileInfo3(topDir, QStringLiteral("collection3")); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection4"))); + QFileInfo fileInfo4(topDir, QStringLiteral("collection4")); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection5"))); + QFileInfo fileInfo5(topDir, QStringLiteral("collection5")); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection6"))); + QFileInfo fileInfo6(topDir, QStringLiteral("collection6")); + + // first level maildir parent + QDir subDir1 = topDir; + QVERIFY(subDir1.mkdir(QStringLiteral(".collection1.directory"))); + QVERIFY(subDir1.cd(QStringLiteral(".collection1.directory"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), subDir1.path(), QStringLiteral("collection1_1"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), subDir1.path(), QStringLiteral("collection1_2"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), subDir1.path(), QStringLiteral("collection1_3"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), subDir1.path(), QStringLiteral("collection1_4"))); + + // first level mbox parent + QDir subDir4 = topDir; + QVERIFY(subDir4.mkdir(QStringLiteral(".collection4.directory"))); + QVERIFY(subDir4.cd(QStringLiteral(".collection4.directory"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), subDir4.path(), QStringLiteral("collection4_1"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), subDir4.path(), QStringLiteral("collection4_2"))); + + // target mbox + QFileInfo fileInfoTarget(topDir.path(), QStringLiteral("target")); + QFile fileTarget(fileInfoTarget.absoluteFilePath()); + QVERIFY(fileTarget.open(QIODevice::WriteOnly)); + fileTarget.close(); + QVERIFY(fileInfoTarget.exists()); + + QDir subDirTarget; + + mStore->setPath(topDir.path()); + + // common variables + FileStore::CollectionMoveJob *job = 0; + FileStore::ItemFetchJob *itemFetch = 0; + Collection collection; + const QVariant colListVar = QVariant::fromValue(Collection::List()); + QVariant var; + Collection::List collections; + Item::List items; + QMap flagCounts; + + Collection target; + target.setName(QStringLiteral("target")); + target.setRemoteId(QStringLiteral("target")); + target.setParentCollection(mStore->topLevelCollection()); + + // test move leaf maildir into sibling + Collection collection2; + collection2.setName(QStringLiteral("collection2")); + collection2.setRemoteId(QStringLiteral("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + job = mStore->moveCollection(collection2, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + subDirTarget = topDir; + QVERIFY(subDirTarget.cd(QStringLiteral(".target.directory"))); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection2.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + fileInfo2.refresh(); + QVERIFY(!fileInfo2.exists()); + fileInfo2 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo2.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // test move leaf mbox into sibling + Collection collection3; + collection3.setName(QStringLiteral("collection3")); + collection3.setRemoteId(QStringLiteral("collection3")); + collection3.setParentCollection(mStore->topLevelCollection()); + + job = mStore->moveCollection(collection3, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection3.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + fileInfo3.refresh(); + QVERIFY(!fileInfo3.exists()); + fileInfo3 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo3.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // test move leaf mbox into sibling without subtree + Collection collection5; + collection5.setName(QStringLiteral("collection5")); + collection5.setRemoteId(QStringLiteral("collection5")); + collection5.setParentCollection(mStore->topLevelCollection()); + + Collection collection6; + collection6.setName(QStringLiteral("collection6")); + collection6.setRemoteId(QStringLiteral("collection6")); + collection6.setParentCollection(mStore->topLevelCollection()); + + job = mStore->moveCollection(collection5, collection6); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection5.remoteId()); + QCOMPARE(collection.parentCollection(), collection6); + + fileInfo5.refresh(); + QVERIFY(!fileInfo5.exists()); + QDir subDir6 = topDir; + QVERIFY(subDir6.cd(QStringLiteral(".collection6.directory"))); + fileInfo5 = QFileInfo(subDir6, collection.remoteId()); + QVERIFY(fileInfo5.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // test move maildir with subtree into sibling + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + // load sub collection index data to check for correct cache updates + Collection collection1_1; + collection1_1.setName(QStringLiteral("collection1_1")); + collection1_1.setRemoteId(QStringLiteral("collection1_1")); + collection1_1.setParentCollection(collection1); + itemFetch = mStore->fetchItems(collection1_1); + QVERIFY(itemFetch->exec()); + + Collection collection1_2; + collection1_2.setName(QStringLiteral("collection1_2")); + collection1_2.setRemoteId(QStringLiteral("collection1_2")); + collection1_2.setParentCollection(collection1); + itemFetch = mStore->fetchItems(collection1_2); + QVERIFY(itemFetch->exec()); + + job = mStore->moveCollection(collection1, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + fileInfo1.refresh(); + QVERIFY(!fileInfo1.exists()); + fileInfo1 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo1.exists()); + QVERIFY(!subDir1.exists()); + subDir1 = subDirTarget; + QVERIFY(subDir1.cd(QStringLiteral(".collection1.directory"))); + QCOMPARE(subDir1.entryList(QStringList() << QStringLiteral("collection*")), + QStringList() << QStringLiteral("collection1_1") << QStringLiteral("collection1_2") + << QStringLiteral("collection1_3") << QStringLiteral("collection1_4") + ); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // check for children cache path updates + collection1.setParentCollection(target); + collection1_1.setParentCollection(collection1); + collection1_2.setParentCollection(collection1); + + itemFetch = mStore->fetchItems(collection1_1); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + itemFetch = mStore->fetchItems(collection1_2); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // test move mbox with subtree into sibling + Collection collection4; + collection4.setName(QStringLiteral("collection4")); + collection4.setRemoteId(QStringLiteral("collection4")); + collection4.setParentCollection(mStore->topLevelCollection()); + + // load sub collection index data to check for correct cache updates + Collection collection4_1; + collection4_1.setName(QStringLiteral("collection4_1")); + collection4_1.setRemoteId(QStringLiteral("collection4_1")); + collection4_1.setParentCollection(collection4); + itemFetch = mStore->fetchItems(collection4_1); + QVERIFY(itemFetch->exec()); + + Collection collection4_2; + collection4_2.setName(QStringLiteral("collection4_2")); + collection4_2.setRemoteId(QStringLiteral("collection4_2")); + collection4_2.setParentCollection(collection4); + itemFetch = mStore->fetchItems(collection4_2); + QVERIFY(itemFetch->exec()); + + job = mStore->moveCollection(collection4, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection4.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + fileInfo4.refresh(); + QVERIFY(!fileInfo4.exists()); + fileInfo4 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo4.exists()); + QVERIFY(!subDir4.exists()); + subDir4 = subDirTarget; + QVERIFY(subDir4.cd(QStringLiteral(".collection4.directory"))); + QCOMPARE(subDir4.entryList(QStringList() << QStringLiteral("collection*")), + QStringList() << QStringLiteral("collection4_1") << QStringLiteral("collection4_2") + ); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // check for children cache path updates + collection4.setParentCollection(target); + collection4_1.setParentCollection(collection4); + collection4_2.setParentCollection(collection4); + + itemFetch = mStore->fetchItems(collection4_1); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + itemFetch = mStore->fetchItems(collection4_2); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent maildir to parent's sibling + collection3.setParentCollection(target); + + job = mStore->moveCollection(collection1_1, collection3); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + QDir subDir3 = subDirTarget; + QVERIFY(subDir3.cd(QStringLiteral(".collection3.directory"))); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_1.remoteId()); + QCOMPARE(collection.parentCollection(), collection3); + + QFileInfo fileInfo1_1(subDir1, collection.remoteId()); + QVERIFY(!fileInfo1_1.exists()); + fileInfo1_1 = QFileInfo(subDir3, collection.remoteId()); + QVERIFY(fileInfo1_1.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent maildir to parent's sibling + job = mStore->moveCollection(collection1_2, collection3); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_2.remoteId()); + QCOMPARE(collection.parentCollection(), collection3); + + QFileInfo fileInfo1_2(subDir1, collection.remoteId()); + QVERIFY(!fileInfo1_2.exists()); + fileInfo1_2 = QFileInfo(subDir3, collection.remoteId()); + QVERIFY(fileInfo1_2.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent mbox to parent's sibling + job = mStore->moveCollection(collection4_1, collection3); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection4_1.remoteId()); + QCOMPARE(collection.parentCollection(), collection3); + + QFileInfo fileInfo4_1(subDir4, collection.remoteId()); + QVERIFY(!fileInfo4_1.exists()); + fileInfo4_1 = QFileInfo(subDir3, collection.remoteId()); + QVERIFY(fileInfo4_1.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent mbox to parent's sibling + job = mStore->moveCollection(collection4_2, collection3); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection4_2.remoteId()); + QCOMPARE(collection.parentCollection(), collection3); + + QFileInfo fileInfo4_2(subDir4, collection.remoteId()); + QVERIFY(!fileInfo4_2.exists()); + fileInfo4_2 = QFileInfo(subDir3, collection.remoteId()); + QVERIFY(fileInfo4_2.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent mbox to grandparent + collection1_1.setParentCollection(collection3); + + job = mStore->moveCollection(collection1_1, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_1.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + fileInfo1_1.refresh(); + QVERIFY(!fileInfo1_1.exists()); + fileInfo1_1 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo1_1.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent mbox to grandparent + collection1_2.setParentCollection(collection3); + job = mStore->moveCollection(collection1_2, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_2.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + fileInfo1_2.refresh(); + QVERIFY(!fileInfo1_2.exists()); + fileInfo1_2 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo1_2.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent maildir to grandparent + Collection collection1_3; + collection1_3.setName(QStringLiteral("collection1_3")); + collection1_3.setRemoteId(QStringLiteral("collection1_3")); + collection1_3.setParentCollection(collection1); + + job = mStore->moveCollection(collection1_3, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_3.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + QFileInfo fileInfo1_3(subDir1, collection.remoteId()); + QVERIFY(!fileInfo1_3.exists()); + fileInfo1_3 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo1_3.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from parent maildir to grandparent + Collection collection1_4; + collection1_4.setName(QStringLiteral("collection1_4")); + collection1_4.setRemoteId(QStringLiteral("collection1_4")); + collection1_4.setParentCollection(collection1); + + job = mStore->moveCollection(collection1_4, target); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_4.remoteId()); + QCOMPARE(collection.parentCollection(), target); + + QFileInfo fileInfo1_4(subDir1, collection.remoteId()); + QVERIFY(!fileInfo1_4.exists()); + fileInfo1_4 = QFileInfo(subDirTarget, collection.remoteId()); + QVERIFY(fileInfo1_4.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from mbox to grandchild + collection1_1.setParentCollection(target); + + job = mStore->moveCollection(collection1_1, collection3); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_1.remoteId()); + QCOMPARE(collection.parentCollection(), collection3); + + fileInfo1_1.refresh(); + QVERIFY(!fileInfo1_1.exists()); + fileInfo1_1 = QFileInfo(subDir3, collection.remoteId()); + QVERIFY(fileInfo1_1.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + // move from maildir to grandchild + collection1_2.setParentCollection(target); + + job = mStore->moveCollection(collection1_2, collection3); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collection = job->collection(); + QCOMPARE(collection.remoteId(), collection1_2.remoteId()); + QCOMPARE(collection.parentCollection(), collection3); + + fileInfo1_2.refresh(); + QVERIFY(!fileInfo1_2.exists()); + fileInfo1_2 = QFileInfo(subDir3, collection.remoteId()); + QVERIFY(fileInfo1_2.exists()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 4); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); +} + +QTEST_MAIN(CollectionMoveTest) + +#include "collectionmovetest.moc" + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.g8PCJ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.g8PCJ --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.g8PCJ 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.g8PCJ 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,46 @@ +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx106) with SMTP; 24 Jul 2010 15:51:39 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id A6DEC95366A + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 6305495366F + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id 4D0C995366A + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 21F263103EEB + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 06BF13103EE6 + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 3 +Date: Sat, 24 Jul 2010 15:51:36 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241551.37547.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: R +X-Status: N +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: +X-UID: 12 + + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.LUBVK kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.LUBVK --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.LUBVK 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.LUBVK 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,46 @@ +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx102) with SMTP; 24 Jul 2010 15:51:39 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 5074095366D + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id DEC1195366F + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id C668A95366D + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 9EEB53103EE6 + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 8367A3103EEE + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 2 +Date: Sat, 24 Jul 2010 15:51:16 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241551.16855.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: RO +X-Status: U +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: +X-UID: 10 + +Body of Test 2 diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.qs6V9_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.qs6V9_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.qs6V9_2,S 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.qs6V9_2,S 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,48 @@ +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:41 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx033) with SMTP; 24 Jul 2010 15:51:41 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id BD28395366A + for ; Sat, 24 Jul 2010 15:51:40 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id CA62095366E + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id B5E0195366A + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 754B03103EEB + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 545963103EE6 + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 1 +Date: Sat, 24 Jul 2010 15:50:45 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241550.46907.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: RO +X-Status: RG +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: +X-UID: 13 + +Body +of +Test 1 diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.RTmAd_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.RTmAd_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.RTmAd_2,S 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/dimap/cur/1279980064.4595.RTmAd_2,S 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,45 @@ +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:52:14 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx036) with SMTP; 24 Jul 2010 15:52:14 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 3536595366D + for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 101AC95366A + for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id ED25794D9DA + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id C2DA93103EEB + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id AE2D13103EE6 + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Date: Sat, 24 Jul 2010 15:52:00 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241552.01232.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iM2SSXdnXxuLgAcAvPC3Xr5Z6OPcGoHnWX0YgscMEgMNa/UP6 + 0PsZjBktxR5hqB4N3jaDTD+60EUFg8bPz1GGvD1YActDYJympMTApbcs85zthOivOU3SH3UvpiHN + TRN8A==V1; +Status: RO +X-Status: RK +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: +X-UID: 11 + +Body of Test 4 diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/dimap/new/.keep kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/dimap/new/.keep --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/dimap/new/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/dimap/new/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/dimap/tmp/.keep kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/dimap/tmp/.keep --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/dimap/tmp/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/dimap/tmp/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/.dimap.index and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/.dimap.index differ diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir/cur/1279979617.4595.bwXSm kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir/cur/1279979617.4595.bwXSm --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir/cur/1279979617.4595.bwXSm 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir/cur/1279979617.4595.bwXSm 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,45 @@ +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx106) with SMTP; 24 Jul 2010 15:51:39 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id A6DEC95366A + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 6305495366F + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id 4D0C995366A + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 21F263103EEB + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 06BF13103EE6 + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 3 +Date: Sat, 24 Jul 2010 15:51:36 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241551.37547.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: R +X-Status: N +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir/cur/1279979618.4595.CStza_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir/cur/1279979618.4595.CStza_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir/cur/1279979618.4595.CStza_2,S 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir/cur/1279979618.4595.CStza_2,S 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,47 @@ +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:41 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx033) with SMTP; 24 Jul 2010 15:51:41 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id BD28395366A + for ; Sat, 24 Jul 2010 15:51:40 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id CA62095366E + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id B5E0195366A + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 754B03103EEB + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 545963103EE6 + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 1 +Date: Sat, 24 Jul 2010 15:50:45 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241550.46907.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: RO +X-Status: R +X-KMail-EncryptionState: N +X-KMail-SignatureState: N +X-KMail-MDN-Sent: + +Body +of +Test 1 diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir/cur/1279979618.4595.DUl0I_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir/cur/1279979618.4595.DUl0I_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir/cur/1279979618.4595.DUl0I_2,S 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir/cur/1279979618.4595.DUl0I_2,S 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,44 @@ +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:52:14 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx036) with SMTP; 24 Jul 2010 15:52:14 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 3536595366D + for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 101AC95366A + for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id ED25794D9DA + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id C2DA93103EEB + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id AE2D13103EE6 + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Date: Sat, 24 Jul 2010 15:52:00 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241552.01232.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iM2SSXdnXxuLgAcAvPC3Xr5Z6OPcGoHnWX0YgscMEgMNa/UP6 + 0PsZjBktxR5hqB4N3jaDTD+60EUFg8bPz1GGvD1YActDYJympMTApbcs85zthOivOU3SH3UvpiHN + TRN8A==V1; +Status: RO +X-Status: R +X-KMail-EncryptionState: N +X-KMail-SignatureState: N +X-KMail-MDN-Sent: + +Body of Test 4 diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir/cur/1279979618.4595.pY5ny kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir/cur/1279979618.4595.pY5ny --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir/cur/1279979618.4595.pY5ny 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir/cur/1279979618.4595.pY5ny 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,45 @@ +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx102) with SMTP; 24 Jul 2010 15:51:39 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 5074095366D + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id DEC1195366F + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id C668A95366D + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 9EEB53103EE6 + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 8367A3103EEE + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 2 +Date: Sat, 24 Jul 2010 15:51:16 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241551.16855.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: R +X-Status: N +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +Body of Test 2 diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir/new/.keep kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir/new/.keep --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir/new/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir/new/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir/tmp/.keep kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir/tmp/.keep --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir/tmp/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir/tmp/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/.maildir.index and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/.maildir.index differ diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.6qZsA_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.6qZsA_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.6qZsA_2,S 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.6qZsA_2,S 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,45 @@ +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:52:14 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx036) with SMTP; 24 Jul 2010 15:52:14 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 3536595366D + for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 101AC95366A + for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id ED25794D9DA + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id C2DA93103EEB + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id AE2D13103EE6 + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Date: Sat, 24 Jul 2010 15:52:00 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241552.01232.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iM2SSXdnXxuLgAcAvPC3Xr5Z6OPcGoHnWX0YgscMEgMNa/UP6 + 0PsZjBktxR5hqB4N3jaDTD+60EUFg8bPz1GGvD1YActDYJympMTApbcs85zthOivOU3SH3UvpiHN + TRN8A==V1; +Status: RO +X-Status: RK +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +Body of Test 4 + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.f0l49_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.f0l49_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.f0l49_2,S 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.f0l49_2,S 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,45 @@ +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx106) with SMTP; 24 Jul 2010 15:51:39 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id A6DEC95366A + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 6305495366F + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id 4D0C995366A + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 21F263103EEB + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 06BF13103EE6 + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 3 +Date: Sat, 24 Jul 2010 15:51:36 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241551.37547.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: R +X-Status: N +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.kwx1b_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.kwx1b_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.kwx1b_2,S 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.kwx1b_2,S 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,47 @@ +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:41 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx033) with SMTP; 24 Jul 2010 15:51:41 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id BD28395366A + for ; Sat, 24 Jul 2010 15:51:40 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id CA62095366E + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id B5E0195366A + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 754B03103EEB + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 545963103EE6 + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 1 +Date: Sat, 24 Jul 2010 15:50:45 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241550.46907.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: RO +X-Status: RG +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +Body +of +Test 1 diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.Xdz3R_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.Xdz3R_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.Xdz3R_2,S 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir-tagged/cur/1279982188.18722.Xdz3R_2,S 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,46 @@ +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx102) with SMTP; 24 Jul 2010 15:51:39 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 5074095366D + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id DEC1195366F + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id C668A95366D + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 9EEB53103EE6 + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 8367A3103EEE + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 2 +Date: Sat, 24 Jul 2010 15:51:16 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241551.16855.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: RO +X-Status: U +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +Body of Test 2 + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir-tagged/new/.keep kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir-tagged/new/.keep --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir-tagged/new/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir-tagged/new/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir-tagged/tmp/.keep kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir-tagged/tmp/.keep --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/maildir-tagged/tmp/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/maildir-tagged/tmp/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/.maildir-tagged.index and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/.maildir-tagged.index differ diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/mbox kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/mbox --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/mbox 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/mbox 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,187 @@ +From kevin.krammer@demo.kolab.org Sat Jul 24 15:51:16 2010 +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx102) with SMTP; 24 Jul 2010 15:51:39 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 5074095366D + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id DEC1195366F + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id C668A95366D + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 9EEB53103EE6 + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 8367A3103EEE + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 2 +Date: Sat, 24 Jul 2010 15:51:16 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241551.16855.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: RO +X-Status: U +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +Body of Test 2 + +From kevin.krammer@demo.kolab.org Sat Jul 24 15:52:00 2010 +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:52:14 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx036) with SMTP; 24 Jul 2010 15:52:14 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 3536595366D + for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 101AC95366A + for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id ED25794D9DA + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id C2DA93103EEB + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id AE2D13103EE6 + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Date: Sat, 24 Jul 2010 15:52:00 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241552.01232.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iM2SSXdnXxuLgAcAvPC3Xr5Z6OPcGoHnWX0YgscMEgMNa/UP6 + 0PsZjBktxR5hqB4N3jaDTD+60EUFg8bPz1GGvD1YActDYJympMTApbcs85zthOivOU3SH3UvpiHN + TRN8A==V1; +Status: RO +X-Status: RK +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +Body of Test 4 + +From kevin.krammer@demo.kolab.org Sat Jul 24 15:51:36 2010 +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx106) with SMTP; 24 Jul 2010 15:51:39 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id A6DEC95366A + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 6305495366F + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id 4D0C995366A + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 21F263103EEB + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 06BF13103EE6 + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 3 +Date: Sat, 24 Jul 2010 15:51:36 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241551.37547.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: R +X-Status: N +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + + +From kevin.krammer@demo.kolab.org Sat Jul 24 15:50:45 2010 +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:41 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx033) with SMTP; 24 Jul 2010 15:51:41 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id BD28395366A + for ; Sat, 24 Jul 2010 15:51:40 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id CA62095366E + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id B5E0195366A + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 754B03103EEB + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 545963103EE6 + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 1 +Date: Sat, 24 Jul 2010 15:50:45 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241550.46907.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: RO +X-Status: RG +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +Body +of +Test 1 Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/.mbox.index and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/.mbox.index differ diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/mbox-tagged kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/mbox-tagged --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/mbox-tagged 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/mbox-tagged 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,187 @@ +From kevin.krammer@demo.kolab.org Sat Jul 24 15:51:16 2010 +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx102) with SMTP; 24 Jul 2010 15:51:39 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 5074095366D + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id DEC1195366F + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id C668A95366D + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 9EEB53103EE6 + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 8367A3103EEE + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 2 +Date: Sat, 24 Jul 2010 15:51:16 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241551.16855.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: RO +X-Status: U +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +Body of Test 2 + +From kevin.krammer@demo.kolab.org Sat Jul 24 15:52:00 2010 +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:52:14 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx036) with SMTP; 24 Jul 2010 15:52:14 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 3536595366D + for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 101AC95366A + for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id ED25794D9DA + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id C2DA93103EEB + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id AE2D13103EE6 + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Date: Sat, 24 Jul 2010 15:52:00 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241552.01232.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iM2SSXdnXxuLgAcAvPC3Xr5Z6OPcGoHnWX0YgscMEgMNa/UP6 + 0PsZjBktxR5hqB4N3jaDTD+60EUFg8bPz1GGvD1YActDYJympMTApbcs85zthOivOU3SH3UvpiHN + TRN8A==V1; +Status: RO +X-Status: RK +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +Body of Test 4 + +From kevin.krammer@demo.kolab.org Sat Jul 24 15:51:36 2010 +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx106) with SMTP; 24 Jul 2010 15:51:39 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id A6DEC95366A + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 6305495366F + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id 4D0C995366A + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 21F263103EEB + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 06BF13103EE6 + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 3 +Date: Sat, 24 Jul 2010 15:51:36 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241551.37547.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: R +X-Status: N +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + + +From kevin.krammer@demo.kolab.org Sat Jul 24 15:50:45 2010 +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:41 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx033) with SMTP; 24 Jul 2010 15:51:41 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id BD28395366A + for ; Sat, 24 Jul 2010 15:51:40 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id CA62095366E + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id B5E0195366A + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 754B03103EEB + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 545963103EE6 + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 1 +Date: Sat, 24 Jul 2010 15:50:45 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241550.46907.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: RO +X-Status: RG +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +Body +of +Test 1 Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/.mbox-tagged.index and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/.mbox-tagged.index differ diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/mbox-unpurged kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/mbox-unpurged --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/mbox-unpurged 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/mbox-unpurged 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,187 @@ +From kevin.krammer@demo.kolab.org Sat Jul 24 15:51:16 2010 +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx102) with SMTP; 24 Jul 2010 15:51:39 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 5074095366D + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id DEC1195366F + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id C668A95366D + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 9EEB53103EE6 + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 8367A3103EEE + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 2 +Date: Sat, 24 Jul 2010 15:51:16 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241551.16855.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: RO +X-Status: U +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +Body of Test 2 + +From kevin.krammer@demo.kolab.org Sat Jul 24 15:52:00 2010 +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:52:14 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx036) with SMTP; 24 Jul 2010 15:52:14 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 3536595366D + for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 101AC95366A + for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id ED25794D9DA + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id C2DA93103EEB + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id AE2D13103EE6 + for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Date: Sat, 24 Jul 2010 15:52:00 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241552.01232.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iM2SSXdnXxuLgAcAvPC3Xr5Z6OPcGoHnWX0YgscMEgMNa/UP6 + 0PsZjBktxR5hqB4N3jaDTD+60EUFg8bPz1GGvD1YActDYJympMTApbcs85zthOivOU3SH3UvpiHN + TRN8A==V1; +Status: RO +X-Status: RK +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +Body of Test 4 + +From kevin.krammer@demo.kolab.org Sat Jul 24 15:51:36 2010 +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx106) with SMTP; 24 Jul 2010 15:51:39 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id A6DEC95366A + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id 6305495366F + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id 4D0C995366A + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 21F263103EEB + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 06BF13103EE6 + for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 3 +Date: Sat, 24 Jul 2010 15:51:36 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241551.37547.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: R +X-Status: N +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + + +From kevin.krammer@demo.kolab.org Sat Jul 24 15:50:45 2010 +Return-Path: +Delivered-To: GMX delivery to kevin.krammer@gmx.at +Received: (qmail invoked by alias); 24 Jul 2010 13:51:41 -0000 +Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] + by mx0.gmx.net (mx033) with SMTP; 24 Jul 2010 15:51:41 +0200 +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id BD28395366A + for ; Sat, 24 Jul 2010 15:51:40 +0200 (CEST) +X-Virus-Scanned: by amavisd-new at intevation.de +Received: from localhost (localhost.localdomain [127.0.0.1]) + by kolab.intevation.de (Postfix) with ESMTP id CA62095366E + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) + by kolab.intevation.de (Postfix) with ESMTP id B5E0195366A + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from localhost (localhost [127.0.0.1]) + by demo.kolab.org (Postfix) with ESMTP id 754B03103EEB + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) + (Authenticated sender: kevin.krammer@demo.kolab.org) + by demo.kolab.org (Postfix) with ESMTP id 545963103EE6 + for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) +From: Kevin Krammer +Organization: Kolab Demo +To: kevin.krammer@gmx.at +Subject: Test 1 +Date: Sat, 24 Jul 2010 15:50:45 +0200 +User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) +MIME-Version: 1.0 +Content-Type: Text/Plain; + charset="us-ascii" +Content-Transfer-Encoding: 7bit +Message-Id: <201007241550.46907.kevin.krammer@demo.kolab.org> +X-GMX-Antivirus: 0 (no virus found) +X-GMX-Antispam: 0 (Mail was not recognized as spam); + Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i + k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY + UsgKg==V1; +Status: RO +X-Status: RG +X-KMail-EncryptionState: +X-KMail-SignatureState: +X-KMail-MDN-Sent: + +Body +of +Test 1 Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/.mbox-unpurged.index and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/.mbox-unpurged.index differ diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/README kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/README --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/data/README 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/data/README 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,38 @@ +Description of contained Test data +================================== + +maildir/dimap message filenames that contained ':' had it replaced with '_' + +1) dimap: 4 messages + index + - message 1 flagged important + - message 2 flagged unread + - message 3 flagged new, empty body + - message 4 flagged task, empty subject + +2) maildir: 4 messages + index + - message 1 flagged important + - message 2 flagged unread + - message 3 flagged new, empty body + - message 4 flagged task, empty subject + +3) mbox: 4 messages + index + - message 1 flagged unread + - message 2 flagged task, empty subject + - message 3 flagged new, empty body + - message 4 flagged important + +4) maildir-tagged: 4 messages + index + - message 1 flagged important, tag1 + - message 2 flagged unread, tag2 + - message 3 flagged new, empty body, tag 3 + - message 4 flagged task, empty subject + +5) mbox-tagged: 4 messages + index + - message 1 flagged unread, tag2 + - message 2 flagged task, empty subject + - message 3 flagged new, empty body, tag 3 + - message 4 flagged important, tag1 + +6) mbox-unpurged: 4 messages + index with entries for the first two + - simulating an unpurged mbox: all messages in mbox, no index entries for + the two messages in the middle diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/itemcreatetest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/itemcreatetest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/itemcreatetest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/itemcreatetest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,538 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" + +#include "testdatautil.h" + +#include "filestore/itemcreatejob.h" +#include "filestore/itemfetchjob.h" + +#include "libmaildir/maildir.h" + +#include +#include + +#include +#include + +#include +#include +#include + +using namespace Akonadi; + +class ItemCreateTest : public QObject +{ + Q_OBJECT + +public: + ItemCreateTest() : QObject(), mStore(0), mDir(0) {} + + ~ItemCreateTest() + { + delete mStore; + delete mDir; + } + +private: + MixedMaildirStore *mStore; + QTemporaryDir *mDir; + +private Q_SLOTS: + void init(); + void cleanup(); + void testExpectedFail(); + void testMBox(); + void testMaildir(); +}; + +void ItemCreateTest::init() +{ + mStore = new MixedMaildirStore; + + mDir = new QTemporaryDir; + QVERIFY(mDir->isValid()); + QVERIFY(QDir(mDir->path()).exists()); +} + +void ItemCreateTest::cleanup() +{ + delete mStore; + mStore = 0; + delete mDir; + mDir = 0; +} + +void ItemCreateTest::testExpectedFail() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir"), topDir.path(), QStringLiteral("data"))); + QDir dataDir = topDir; + QVERIFY(dataDir.cd(QLatin1String("data"))); + KPIM::Maildir dataMd(dataDir.path(), false); + QVERIFY(dataMd.isValid()); + + const QStringList dataEntryList = dataMd.entryList(); + QCOMPARE(dataEntryList.count(), 4); + KMime::Message::Ptr msgPtr(new KMime::Message); + msgPtr->setContent(KMime::CRLFtoLF(dataMd.readEntry(dataEntryList.first()))); + + QVERIFY(topDir.mkdir(QLatin1String("store"))); + QVERIFY(topDir.cd(QLatin1String("store"))); + mStore->setPath(topDir.path()); + + FileStore::ItemCreateJob *job = 0; + + // test failure of adding item to top level collection + Item item; + item.setMimeType(KMime::Message::mimeType()); + item.setPayload(msgPtr); + + job = mStore->createItem(item, mStore->topLevelCollection()); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + // test failure of adding item to non existent collection + Collection collection; + collection.setName(QLatin1String("collection")); + collection.setRemoteId(QLatin1String("collection")); + collection.setParentCollection(mStore->topLevelCollection()); + + job = mStore->createItem(item, collection); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); +} + +void ItemCreateTest::testMBox() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir"), topDir.path(), QStringLiteral("data"))); + QDir dataDir = topDir; + QVERIFY(dataDir.cd(QLatin1String("data"))); + KPIM::Maildir dataMd(dataDir.path(), false); + QVERIFY(dataMd.isValid()); + + const QStringList dataEntryList = dataMd.entryList(); + QCOMPARE(dataEntryList.count(), 4); + KMime::Message::Ptr msgPtr1(new KMime::Message); + msgPtr1->setContent(KMime::CRLFtoLF(dataMd.readEntry(dataEntryList.first()))); + KMime::Message::Ptr msgPtr2(new KMime::Message); + msgPtr2->setContent(KMime::CRLFtoLF(dataMd.readEntry(dataEntryList.last()))); + + QVERIFY(topDir.mkdir(QLatin1String("store"))); + QVERIFY(topDir.cd(QLatin1String("store"))); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox"), topDir.path(), QStringLiteral("collection1"))); + + QFileInfo fileInfo1(topDir.path(), QStringLiteral("collection1")); + KMBox::MBox mbox1; + QVERIFY(mbox1.load(fileInfo1.absoluteFilePath())); + QCOMPARE((int)mbox1.entries().count(), 4); + const int size1 = fileInfo1.size(); + + // simulate empty mbox + QFileInfo fileInfo2(topDir.path(), QStringLiteral("collection2")); + QFile file2(fileInfo2.absoluteFilePath()); + QVERIFY(file2.open(QIODevice::WriteOnly)); + file2.close(); + QVERIFY(file2.exists()); + QCOMPARE((int)file2.size(), 0); + + mStore->setPath(topDir.path()); + + // common variables + const QVariant colListVar = QVariant::fromValue(Collection::List()); + QVariant var; + Collection::List collections; + Item::List items; + QMap flagCounts; + + FileStore::ItemCreateJob *job = 0; + FileStore::ItemFetchJob *itemFetch = 0; + + // test adding to empty mbox + Collection collection2; + collection2.setName(QLatin1String("collection2")); + collection2.setRemoteId(QLatin1String("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + Item item1; + item1.setId(KRandom::random()); + item1.setMimeType(KMime::Message::mimeType()); + item1.setPayload(msgPtr1); + + job = mStore->createItem(item1, collection2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + Item item = job->item(); + QCOMPARE(item.id(), item1.id()); + QVERIFY(!item.remoteId().isEmpty()); + QCOMPARE(item.remoteId(), QStringLiteral("0")); + QCOMPARE(item.parentCollection(), collection2); + + fileInfo2.refresh(); + QVERIFY(fileInfo2.size() > 0); + const int size2 = fileInfo2.size(); + + KMBox::MBox mbox2; + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + QCOMPARE((int)mbox2.entries().count(), 1); + + Item item2; + item2.setId(KRandom::random()); + item2.setMimeType(KMime::Message::mimeType()); + item2.setPayload(msgPtr2); + + job = mStore->createItem(item2, collection2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + item = job->item(); + QCOMPARE(item.id(), item2.id()); + QVERIFY(!item.remoteId().isEmpty()); + QCOMPARE(item.remoteId(), QString::number(size2 + 1)); + QCOMPARE(item.parentCollection(), collection2); + + fileInfo2.refresh(); + QVERIFY(fileInfo2.size() > 0); + + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + QCOMPARE((int)mbox2.entries().count(), 2); + + // test adding to non-empty mbox + Collection collection1; + collection1.setName(QLatin1String("collection1")); + collection1.setRemoteId(QLatin1String("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + job = mStore->createItem(item1, collection1); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + item = job->item(); + QCOMPARE(item.id(), item1.id()); + QVERIFY(!item.remoteId().isEmpty()); + QCOMPARE(item.remoteId(), QString::number(size1 + 1)); + QCOMPARE(item.parentCollection(), collection1); + + fileInfo1.refresh(); + QVERIFY(fileInfo1.size() > size1); + + QVERIFY(mbox1.load(fileInfo1.absoluteFilePath())); + QCOMPARE((int)mbox1.entries().count(), 5); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection1); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection1); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 5); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + job = mStore->createItem(item2, collection1); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + item = job->item(); + QCOMPARE(item.id(), item2.id()); + QVERIFY(!item.remoteId().isEmpty()); + QCOMPARE(item.remoteId(), QString::number(size1 + 1 + size2 + 1)); + QCOMPARE(item.parentCollection(), collection1); + + fileInfo1.refresh(); + QVERIFY(fileInfo1.size() > (size1 + size2)); + + QVERIFY(mbox1.load(fileInfo1.absoluteFilePath())); + QCOMPARE((int)mbox1.entries().count(), 6); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection1); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection1); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 6); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); +} + +void ItemCreateTest::testMaildir() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir"), topDir.path(), QStringLiteral("data"))); + QDir dataDir = topDir; + QVERIFY(dataDir.cd(QLatin1String("data"))); + KPIM::Maildir dataMd(dataDir.path(), false); + QVERIFY(dataMd.isValid()); + + const QStringList dataEntryList = dataMd.entryList(); + QCOMPARE(dataEntryList.count(), 4); + KMime::Message::Ptr msgPtr1(new KMime::Message); + msgPtr1->setContent(KMime::CRLFtoLF(dataMd.readEntry(dataEntryList.first()))); + KMime::Message::Ptr msgPtr2(new KMime::Message); + msgPtr2->setContent(KMime::CRLFtoLF(dataMd.readEntry(dataEntryList.last()))); + + QVERIFY(topDir.mkdir(QLatin1String("store"))); + QVERIFY(topDir.cd(QLatin1String("store"))); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir"), topDir.path(), QStringLiteral("collection1"))); + + KPIM::Maildir topLevelMd(topDir.path(), true); + KPIM::Maildir md1 = topLevelMd.subFolder(QLatin1String("collection1")); + QVERIFY(md1.isValid()); + + QSet entrySet1 = QSet::fromList(md1.entryList()); + QCOMPARE((int)entrySet1.count(), 4); + + // simulate empty maildir + KPIM::Maildir md2(topLevelMd.addSubFolder(QLatin1String("collection2")), false); + QVERIFY(md2.isValid()); + + QSet entrySet2 = QSet::fromList(md2.entryList()); + QCOMPARE((int)entrySet2.count(), 0); + + mStore->setPath(topDir.path()); + + // common variables + const QVariant colListVar = QVariant::fromValue(Collection::List()); + QVariant var; + Collection::List collections; + Item::List items; + QMap flagCounts; + + QSet entrySet; + QSet newIdSet; + QString newId; + + FileStore::ItemCreateJob *job = 0; + FileStore::ItemFetchJob *itemFetch = 0; + + // test adding to empty maildir + Collection collection2; + collection2.setName(QLatin1String("collection2")); + collection2.setRemoteId(QLatin1String("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + Item item1; + item1.setId(KRandom::random()); + item1.setMimeType(KMime::Message::mimeType()); + item1.setPayload(msgPtr1); + + job = mStore->createItem(item1, collection2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + Item item = job->item(); + QCOMPARE(item.id(), item1.id()); + QVERIFY(!item.remoteId().isEmpty()); + QCOMPARE(item.parentCollection(), collection2); + + entrySet = QSet::fromList(md2.entryList()); + QCOMPARE((int)entrySet.count(), 1); + + newIdSet = entrySet.subtract(entrySet2); + QCOMPARE((int)newIdSet.count(), 1); + + newId = *newIdSet.cbegin(); + QCOMPARE(item.remoteId(), newId); + entrySet2 << newId; + QCOMPARE((int)entrySet2.count(), 1); + + Item item2; + item2.setId(KRandom::random()); + item2.setMimeType(KMime::Message::mimeType()); + item2.setPayload(msgPtr2); + + job = mStore->createItem(item2, collection2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + item = job->item(); + QCOMPARE(item.id(), item2.id()); + QVERIFY(!item.remoteId().isEmpty()); + QCOMPARE(item.parentCollection(), collection2); + + entrySet = QSet::fromList(md2.entryList()); + QCOMPARE((int)entrySet.count(), 2); + + newIdSet = entrySet.subtract(entrySet2); + QCOMPARE((int)newIdSet.count(), 1); + + newId = *newIdSet.cbegin(); + QCOMPARE(item.remoteId(), newId); + entrySet2 << newId; + QCOMPARE((int)entrySet2.count(), 2); + + // test adding to non-empty maildir + Collection collection1; + collection1.setName(QLatin1String("collection1")); + collection1.setRemoteId(QLatin1String("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + job = mStore->createItem(item1, collection1); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + item = job->item(); + QCOMPARE(item.id(), item1.id()); + QVERIFY(!item.remoteId().isEmpty()); + QCOMPARE(item.parentCollection(), collection1); + + entrySet = QSet::fromList(md1.entryList()); + QCOMPARE((int)entrySet.count(), 5); + + newIdSet = entrySet.subtract(entrySet1); + QCOMPARE((int)newIdSet.count(), 1); + + newId = *newIdSet.cbegin(); + QCOMPARE(item.remoteId(), newId); + entrySet1 << newId; + QCOMPARE((int)entrySet1.count(), 5); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection1); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection1); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 5); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + job = mStore->createItem(item2, collection1); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + item = job->item(); + QCOMPARE(item.id(), item2.id()); + QVERIFY(!item.remoteId().isEmpty()); + QCOMPARE(item.parentCollection(), collection1); + + entrySet = QSet::fromList(md1.entryList()); + QCOMPARE((int)entrySet.count(), 6); + + newIdSet = entrySet.subtract(entrySet1); + QCOMPARE((int)newIdSet.count(), 1); + + newId = *newIdSet.cbegin(); + QCOMPARE(item.remoteId(), newId); + entrySet1 << newId; + QCOMPARE((int)entrySet1.count(), 6); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection1); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection1); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 6); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); +} + +QTEST_MAIN(ItemCreateTest) + +#include "itemcreatetest.moc" + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/itemdeletetest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/itemdeletetest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/itemdeletetest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/itemdeletetest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,609 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" + +#include "testdatautil.h" + +#include "filestore/entitycompactchangeattribute.h" +#include "filestore/itemdeletejob.h" +#include "filestore/itemfetchjob.h" +#include "filestore/storecompactjob.h" + +#include "libmaildir/maildir.h" + +#include +#include + +#include +#include + +#include + +#include +#include +#include + +using namespace Akonadi; + +static Collection::List collectionsFromSpy(QSignalSpy *spy) +{ + Collection::List collections; + + QListIterator > it(*spy); + while (it.hasNext()) { + const QList invocation = it.next(); + Q_ASSERT(invocation.count() == 1); + + collections << invocation.first().value(); + } + + return collections; +} + +static Item::List itemsFromSpy(QSignalSpy *spy) +{ + Item::List items; + + QListIterator > it(*spy); + while (it.hasNext()) { + const QList invocation = it.next(); + Q_ASSERT(invocation.count() == 1); + + items << invocation.first().value(); + } + + return items; +} + +static bool fullEntryCompare(const KMBox::MBoxEntry &a, const KMBox::MBoxEntry &b) +{ + return a.messageOffset() == b.messageOffset() && + a.separatorSize() == b.separatorSize() && + a.messageSize() == b.messageSize(); +} + +class ItemDeleteTest : public QObject +{ + Q_OBJECT + +public: + ItemDeleteTest() : QObject(), mStore(0), mDir(0) + { + // for monitoring signals + qRegisterMetaType(); + qRegisterMetaType(); + } + + ~ItemDeleteTest() + { + delete mStore; + delete mDir; + } + +private: + MixedMaildirStore *mStore; + QTemporaryDir *mDir; + +private Q_SLOTS: + void init(); + void cleanup(); + void testMaildir(); + void testMBox(); + void testCachePreservation(); + void testExpectedFailure(); +}; + +void ItemDeleteTest::init() +{ + mStore = new MixedMaildirStore; + + mDir = new QTemporaryDir; + QVERIFY(mDir->isValid()); + QVERIFY(QDir(mDir->path()).exists()); +} + +void ItemDeleteTest::cleanup() +{ + delete mStore; + mStore = 0; + delete mDir; + mDir = 0; +} + +void ItemDeleteTest::testMaildir() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection1"))); + + KPIM::Maildir topLevelMd(topDir.path(), true); + KPIM::Maildir md1 = topLevelMd.subFolder(QStringLiteral("collection1")); + QVERIFY(md1.isValid()); + + QSet entrySet1 = QSet::fromList(md1.entryList()); + QCOMPARE((int)entrySet1.count(), 4); + + mStore->setPath(topDir.path()); + + // common variables + FileStore::ItemDeleteJob *job = 0; + QSet entrySet; + QSet delIdSet; + QString delId; + + // test deleting one message + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + Item item1; + item1.setMimeType(KMime::Message::mimeType()); + item1.setId(KRandom::random()); + item1.setRemoteId(*entrySet1.cbegin()); + item1.setParentCollection(collection1); + + job = mStore->deleteItem(item1); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + Item item = job->item(); + QCOMPARE(item.id(), item1.id()); + + entrySet = QSet::fromList(md1.entryList()); + QCOMPARE((int)entrySet.count(), 3); + + delIdSet = entrySet1.subtract(entrySet); + QCOMPARE((int)delIdSet.count(), 1); + + delId = *delIdSet.cbegin(); + QCOMPARE(delId, *entrySet1.cbegin()); + QCOMPARE(delId, item.remoteId()); + + // test failure of deleting again + job = mStore->deleteItem(item1); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); +} + +void ItemDeleteTest::testMBox() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection1"))); + + QFileInfo fileInfo1(topDir.path(), QStringLiteral("collection1")); + KMBox::MBox mbox1; + QVERIFY(mbox1.load(fileInfo1.absoluteFilePath())); + KMBox::MBoxEntry::List entryList1 = mbox1.entries(); + QCOMPARE((int)entryList1.count(), 4); + int size1 = fileInfo1.size(); + + mStore->setPath(topDir.path()); + + // common variables + FileStore::ItemDeleteJob *job = 0; + FileStore::ItemFetchJob *itemFetch = 0; + FileStore::StoreCompactJob *storeCompact = 0; + + Item::List items; + Collection::List collections; + KMBox::MBoxEntry::List entryList; + + QSignalSpy *collectionsSpy = 0; + QSignalSpy *itemsSpy = 0; + + QVariant var; + + // test deleting last item in mbox + // file stays untouched, message still accessible through MBox, but item gone + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + Item item4; + item4.setMimeType(KMime::Message::mimeType()); + item4.setId(KRandom::random()); + item4.setRemoteId(QString::number(entryList1.value(3).messageOffset())); + item4.setParentCollection(collection1); + + job = mStore->deleteItem(item4); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + Item item = job->item(); + QCOMPARE(item.id(), item4.id()); + + fileInfo1.refresh(); + QCOMPARE((int) fileInfo1.size(), size1); + QVERIFY(mbox1.load(fileInfo1.absoluteFilePath())); + entryList = mbox1.entries(); + QCOMPARE(entryList.count(), entryList1.count()); + QCOMPARE(entryList.value(3).messageOffset(), entryList1.value(3).messageOffset()); + + var = job->property("compactStore"); + QVERIFY(var.isValid()); + QCOMPARE(var.type(), QVariant::Bool); + QCOMPARE(var.toBool(), true); + + itemFetch = mStore->fetchItems(collection1); + + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 3); + QCOMPARE(items.value(0).remoteId(), QString::number(entryList1.value(0).messageOffset())); + QCOMPARE(items.value(1).remoteId(), QString::number(entryList1.value(1).messageOffset())); + QCOMPARE(items.value(2).remoteId(), QString::number(entryList1.value(2).messageOffset())); + + // test that the item is purged from the file on store compaction + // last item purging does not change any others + storeCompact = mStore->compactStore(); + + collectionsSpy = new QSignalSpy(storeCompact, SIGNAL(collectionsChanged(Akonadi::Collection::List))); + itemsSpy = new QSignalSpy(storeCompact, SIGNAL(itemsChanged(Akonadi::Item::List))); + + QVERIFY(storeCompact->exec()); + QCOMPARE(storeCompact->error(), 0); + + collections = storeCompact->changedCollections(); + QCOMPARE(collections.count(), 0); + items = storeCompact->changedItems(); + QCOMPARE(items.count(), 0); + + QCOMPARE(collectionsFromSpy(collectionsSpy), collections); + QCOMPARE(itemsFromSpy(itemsSpy), items); + + fileInfo1.refresh(); + QVERIFY(fileInfo1.size() < size1); + size1 = fileInfo1.size(); + QVERIFY(mbox1.load(fileInfo1.absoluteFilePath())); + entryList = mbox1.entries(); + entryList1.pop_back(); + QVERIFY(std::equal(entryList1.begin(), entryList1.end(), entryList.begin(), fullEntryCompare)); + + // test deleting item somewhere between first and last + // again, file stays untouched, message still accessible through MBox, but item gone + Item item2; + item2.setMimeType(KMime::Message::mimeType()); + item2.setId(KRandom::random()); + item2.setRemoteId(QString::number(entryList1.value(1).messageOffset())); + item2.setParentCollection(collection1); + + job = mStore->deleteItem(item2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + item = job->item(); + QCOMPARE(item.id(), item2.id()); + + fileInfo1.refresh(); + QCOMPARE((int) fileInfo1.size(), size1); + QVERIFY(mbox1.load(fileInfo1.absoluteFilePath())); + entryList = mbox1.entries(); + QCOMPARE(entryList.count(), entryList1.count()); + QCOMPARE(entryList.value(1).messageOffset(), entryList1.value(1).messageOffset()); + + var = job->property("compactStore"); + QVERIFY(var.isValid()); + QCOMPARE(var.type(), QVariant::Bool); + QCOMPARE(var.toBool(), true); + + itemFetch = mStore->fetchItems(collection1); + + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 2); + QCOMPARE(items.value(0).remoteId(), QString::number(entryList1.value(0).messageOffset())); + QCOMPARE(items.value(1).remoteId(), QString::number(entryList1.value(2).messageOffset())); + + // test that the item is purged from the file on store compaction + // non-last item purging changes all items after it + storeCompact = mStore->compactStore(); + + collectionsSpy = new QSignalSpy(storeCompact, SIGNAL(collectionsChanged(Akonadi::Collection::List))); + itemsSpy = new QSignalSpy(storeCompact, SIGNAL(itemsChanged(Akonadi::Item::List))); + + QVERIFY(storeCompact->exec()); + QCOMPARE(storeCompact->error(), 0); + + collections = storeCompact->changedCollections(); + QCOMPARE(collections.count(), 1); + items = storeCompact->changedItems(); + QCOMPARE(items.count(), 1); + + QCOMPARE(collectionsFromSpy(collectionsSpy), collections); + QCOMPARE(itemsFromSpy(itemsSpy), items); + + Item item3; + item3.setRemoteId(QString::number(entryList1.value(2).messageOffset())); + + item = items.first(); + QCOMPARE(item3.remoteId(), item.remoteId()); + + QVERIFY(item.hasAttribute()); + FileStore::EntityCompactChangeAttribute *attribute = + item.attribute(); + + QString newRemoteId = attribute->remoteId(); + QVERIFY(!newRemoteId.isEmpty()); + + fileInfo1.refresh(); + QVERIFY(fileInfo1.size() < size1); + size1 = fileInfo1.size(); + QVERIFY(mbox1.load(fileInfo1.absoluteFilePath())); + entryList = mbox1.entries(); + QCOMPARE(QString::number(entryList.value(1).messageOffset()), newRemoteId); + + entryList1.removeAt(1); + QCOMPARE(entryList1.count(), entryList.count()); + QCOMPARE(QString::number(entryList1.value(1).messageOffset()), item3.remoteId()); +} + +void ItemDeleteTest::testCachePreservation() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection1"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection2"))); + + KPIM::Maildir topLevelMd(topDir.path(), true); + KPIM::Maildir md1 = topLevelMd.subFolder(QStringLiteral("collection1")); + QVERIFY(md1.isValid()); + + QSet entrySet1 = QSet::fromList(md1.entryList()); + QCOMPARE((int)entrySet1.count(), 4); + + QFileInfo fileInfo2(topDir.path(), QStringLiteral("collection2")); + KMBox::MBox mbox2; + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + KMBox::MBoxEntry::List entryList2 = mbox2.entries(); + QCOMPARE((int)entryList2.count(), 4); + + mStore->setPath(topDir.path()); + + // common variables + const QVariant colListVar = QVariant::fromValue(Collection::List()); + QVariant var; + Collection::List collections; + Item::List items; + QMap flagCounts; + + FileStore::ItemDeleteJob *job = 0; + FileStore::ItemFetchJob *itemFetch = 0; + + // test deleting from maildir + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + Item item1; + item1.setMimeType(KMime::Message::mimeType()); + item1.setId(KRandom::random()); + item1.setRemoteId(*entrySet1.cbegin()); + item1.setParentCollection(collection1); + + job = mStore->deleteItem(item1); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + Item item = job->item(); + QCOMPARE(item.id(), item1.id()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection1); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection1); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 3); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + // TODO since we don't know which message we've deleted, we can only check if some flags are present + int flagCountTotal = 0; + Q_FOREACH (int count, flagCounts) { + flagCountTotal += count; + } + QVERIFY(flagCountTotal > 0); + flagCounts.clear(); + + // test deleting from mbox + Collection collection2; + collection2.setName(QStringLiteral("collection2")); + collection2.setRemoteId(QStringLiteral("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + Item item2; + item2.setMimeType(KMime::Message::mimeType()); + item2.setId(KRandom::random()); + item2.setRemoteId(QString::number(entryList2.value(1).messageOffset())); + item2.setParentCollection(collection2); + + job = mStore->deleteItem(item2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + item = job->item(); + QCOMPARE(item.id(), item2.id()); + + // at this point no change has been written to disk yet, so index and mbox file are + // still in sync + var = job->property("onDiskIndexInvalidated"); + QVERIFY(!var.isValid()); + + FileStore::StoreCompactJob *storeCompact = mStore->compactStore(); + + QVERIFY(storeCompact->exec()); + QCOMPARE(storeCompact->error(), 0); + + // check for index preservation + var = storeCompact->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection2); + + // get the items and check the flags (see data/README) + itemFetch = mStore->fetchItems(collection2); + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + items = itemFetch->items(); + QCOMPARE((int)items.count(), 3); + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + // we've deleted message 2, it flagged TODO and seen + QCOMPARE(flagCounts[ "\\SEEN" ], 1); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + flagCounts.clear(); +} + +void ItemDeleteTest::testExpectedFailure() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection1"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection2"))); + + KPIM::Maildir topLevelMd(topDir.path(), true); + KPIM::Maildir md1 = topLevelMd.subFolder(QStringLiteral("collection1")); + QVERIFY(md1.isValid()); + + QSet entrySet1 = QSet::fromList(md1.entryList()); + QCOMPARE((int)entrySet1.count(), 4); + + QFileInfo fileInfo2(topDir.path(), QStringLiteral("collection2")); + KMBox::MBox mbox2; + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + KMBox::MBoxEntry::List entryList2 = mbox2.entries(); + QCOMPARE((int)entryList2.count(), 4); + + mStore->setPath(topDir.path()); + + // common variables + FileStore::ItemDeleteJob *job = 0; + FileStore::ItemFetchJob *itemFetch = 0; + FileStore::StoreCompactJob *storeCompact = 0; + + // test failure of fetching an item previously deleted from maildir + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + Item item1_1; + item1_1.setRemoteId(*entrySet1.cbegin()); + item1_1.setParentCollection(collection1); + + job = mStore->deleteItem(item1_1); + + QVERIFY(job->exec()); + + itemFetch = mStore->fetchItem(item1_1); + + QVERIFY(!itemFetch->exec()); + QCOMPARE(itemFetch->error(), (int)FileStore::Job::InvalidJobContext); + + // test failure of deleting an item from maildir again + job = mStore->deleteItem(item1_1); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + // test failure of fetching an item previously deleted from mbox + Collection collection2; + collection2.setName(QStringLiteral("collection2")); + collection2.setRemoteId(QStringLiteral("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + Item item2_1; + item2_1.setRemoteId(QString::number(entryList2.value(0).messageOffset())); + item2_1.setParentCollection(collection2); + + job = mStore->deleteItem(item2_1); + + QVERIFY(job->exec()); + + itemFetch = mStore->fetchItem(item2_1); + + QVERIFY(!itemFetch->exec()); + QCOMPARE(itemFetch->error(), (int)FileStore::Job::InvalidJobContext); + + // test failure of deleting an item from mbox again + job = mStore->deleteItem(item2_1); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + // compact store and check that offset 0 is a valid remoteId again, but + // offset of other items (e.f. item 4) are no longer valid (moved to the front of the file) + storeCompact = mStore->compactStore(); + + QVERIFY(storeCompact->exec()); + + itemFetch = mStore->fetchItem(item2_1); + + QVERIFY(itemFetch->exec()); + + Item item4_1; + item4_1.setRemoteId(QString::number(entryList2.value(3).messageOffset())); + item4_1.setParentCollection(collection2); + + itemFetch = mStore->fetchItem(item4_1); + + QVERIFY(!itemFetch->exec()); + QCOMPARE(itemFetch->error(), (int)FileStore::Job::InvalidJobContext); +} + +QTEST_MAIN(ItemDeleteTest) + +#include "itemdeletetest.moc" + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/itemfetchtest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/itemfetchtest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/itemfetchtest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/itemfetchtest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,1165 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" +#include "mixedmaildirresource_debug.h" +#include "testdatautil.h" + +#include "filestore/itemcreatejob.h" +#include "filestore/itemfetchjob.h" + +#include "libmaildir/maildir.h" + +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +using namespace Akonadi; +using namespace KMBox; + +static Item::List itemsFromSpy(QSignalSpy *spy) +{ + Item::List items; + + QListIterator > it(*spy); + while (it.hasNext()) { + const QList invocation = it.next(); + Q_ASSERT(invocation.count() == 1); + + items << invocation.first().value(); + } + + return items; +} + +// copied from mail serializer plugin, Copyright (c) 2007 Till Adam +static QSet messageParts(const KMime::Message::Ptr &msgPtr) +{ + QSet set; + // FIXME: we actually want "has any header" here, but the kmime api doesn't offer that yet + if (msgPtr->hasContent() || msgPtr->hasHeader("Message-ID")) { + set << MessagePart::Envelope << MessagePart::Header; + if (!msgPtr->body().isEmpty() || !msgPtr->contents().isEmpty()) { + set << MessagePart::Body; + } + } + return set; +} + +// needed to sort maildir directory entries by filename which is their +// remoteId. tagListHash.contains tests below need sorting of entries. +static bool itemLessThanByRemoteId(const Item &item1, const Item &item2) +{ + return item1.remoteId() < item2.remoteId(); +} + +class ItemFetchTest : public QObject +{ + Q_OBJECT + +public: + ItemFetchTest() + : QObject(), mStore(0), mDir(0), mIndexFilePattern(QLatin1String(".%1.index")) + { + // for monitoring signals + qRegisterMetaType(); + qRegisterMetaType(); + } + + ~ItemFetchTest() + { + delete mStore; + delete mDir; + } + + QString indexFile(const QString &folder) const + { + return mIndexFilePattern.arg(folder); + } + + QString indexFile(const QFileInfo &folderFileInfo) const + { + return QFileInfo(folderFileInfo.absolutePath(), + mIndexFilePattern.arg(folderFileInfo.fileName())).absoluteFilePath(); + } + +private: + MixedMaildirStore *mStore; + QTemporaryDir *mDir; + + const QString mIndexFilePattern; + +private Q_SLOTS: + void init(); + void cleanup(); + void testListingMaildir(); + void testListingMBox(); + void testSingleItemFetchMaildir(); + void testSingleItemFetchMBox(); +}; + +void ItemFetchTest::init() +{ + mStore = new MixedMaildirStore; + + mDir = new QTemporaryDir; + QVERIFY(mDir->isValid()); + QVERIFY(QDir(mDir->path()).exists()); +} + +void ItemFetchTest::cleanup() +{ + delete mStore; + mStore = 0; + delete mDir; + mDir = 0; +} + +void ItemFetchTest::testListingMaildir() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir"), topDir.path(), QLatin1String("collection1"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir"), topDir.path(), QLatin1String("collection2"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir-tagged"), topDir.path(), QLatin1String("collection3"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("dimap"), topDir.path(), QLatin1String("collection4"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir-tagged"), topDir.path(), QLatin1String("collection5"))); + + KPIM::Maildir topLevelMd(topDir.path(), true); + + KPIM::Maildir md1 = topLevelMd.subFolder(QLatin1String("collection1")); + QSet entrySet1 = QSet::fromList(md1.entryList()); + QCOMPARE((int)entrySet1.count(), 4); + + QFileInfo indexFileInfo1(indexFile(QFileInfo(md1.path()))); + QVERIFY(QFile::remove(indexFileInfo1.absoluteFilePath())); + + KPIM::Maildir md2 = topLevelMd.subFolder(QLatin1String("collection2")); + QSet entrySet2 = QSet::fromList(md2.entryList()); + QCOMPARE((int)entrySet2.count(), 4); + + KPIM::Maildir md3 = topLevelMd.subFolder(QLatin1String("collection3")); + QSet entrySet3 = QSet::fromList(md3.entryList()); + QCOMPARE((int)entrySet3.count(), 4); + + KPIM::Maildir md4 = topLevelMd.subFolder(QLatin1String("collection4")); + QSet entrySet4 = QSet::fromList(md4.entryList()); + QCOMPARE((int)entrySet4.count(), 4); + + KPIM::Maildir md5 = topLevelMd.subFolder(QLatin1String("collection5")); + QSet entrySet5 = QSet::fromList(md5.entryList()); + QCOMPARE((int)entrySet5.count(), 4); + + mStore->setPath(topDir.path()); + + // common variables + FileStore::ItemFetchJob *job = 0; + + QSignalSpy *spy = 0; + Item::List items; + + QHash uidHash; + const QVariant varUidHash = QVariant::fromValue< QHash >(uidHash); + QHash tagListHash; + const QVariant varTagListHash = QVariant::fromValue< QHash >(tagListHash); + QVariant var; + + QSet entrySet; + QMap flagCounts; + + // test listing maildir without index + Collection collection1; + collection1.setName(QLatin1String("collection1")); + collection1.setRemoteId(QLatin1String("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + job = mStore->fetchItems(collection1); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 4); + QCOMPARE(itemsFromSpy(spy), items); + + entrySet = entrySet1; + QVERIFY(entrySet.remove(items[ 0 ].remoteId())); + QVERIFY(entrySet.remove(items[ 1 ].remoteId())); + QVERIFY(entrySet.remove(items[ 2 ].remoteId())); + QVERIFY(entrySet.remove(items[ 3 ].remoteId())); + + QCOMPARE(items[ 0 ].parentCollection(), collection1); + QCOMPARE(items[ 1 ].parentCollection(), collection1); + QCOMPARE(items[ 2 ].parentCollection(), collection1); + QCOMPARE(items[ 3 ].parentCollection(), collection1); + + QVERIFY(!items[ 0 ].hasPayload()); + QVERIFY(!items[ 1 ].hasPayload()); + QVERIFY(!items[ 2 ].hasPayload()); + QVERIFY(!items[ 3 ].hasPayload()); + + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + // no flags from maildir file name, no advanced flags without index + QCOMPARE(flagCounts.count(), 0); + QCOMPARE(flagCounts[ "\\SEEN" ], 0); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 0); + QCOMPARE(flagCounts[ "$TODO" ], 0); + flagCounts.clear(); + + var = job->property("remoteIdToTagList"); + QVERIFY(!var.isValid()); + + // test listing empty mbox without index + Q_FOREACH (const QString &entry, entrySet1) { + QVERIFY(md1.removeEntry(entry)); + } + QCOMPARE(md1.entryList().count(), 0); + + job = mStore->fetchItems(collection1); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 0); + QCOMPARE(spy->count(), 0); + + var = job->property("remoteIdToTagList"); + QVERIFY(!var.isValid()); + + // test listing maildir with index + Collection collection2; + collection2.setName(QLatin1String("collection2")); + collection2.setRemoteId(QLatin1String("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + job = mStore->fetchItems(collection2); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 4); + QCOMPARE(itemsFromSpy(spy), items); + + entrySet = entrySet2; + QVERIFY(entrySet.remove(items[ 0 ].remoteId())); + QVERIFY(entrySet.remove(items[ 1 ].remoteId())); + QVERIFY(entrySet.remove(items[ 2 ].remoteId())); + QVERIFY(entrySet.remove(items[ 3 ].remoteId())); + + QCOMPARE(items[ 0 ].parentCollection(), collection2); + QCOMPARE(items[ 1 ].parentCollection(), collection2); + QCOMPARE(items[ 2 ].parentCollection(), collection2); + QCOMPARE(items[ 3 ].parentCollection(), collection2); + + QVERIFY(!items[ 0 ].hasPayload()); + QVERIFY(!items[ 1 ].hasPayload()); + QVERIFY(!items[ 2 ].hasPayload()); + QVERIFY(!items[ 3 ].hasPayload()); + + // see data/README + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + var = job->property("remoteIdToTagList"); + QVERIFY(!var.isValid()); + + // test listing empty maildir with index + Q_FOREACH (const QString &entry, entrySet2) { + QVERIFY(md2.removeEntry(entry)); + } + QCOMPARE(md2.entryList().count(), 0); + + job = mStore->fetchItems(collection2); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 0); + QCOMPARE(spy->count(), 0); + + var = job->property("remoteIdToTagList"); + QVERIFY(!var.isValid()); + + // test listing maildir with index which has tags + Collection collection3; + collection3.setName(QLatin1String("collection3")); + collection3.setRemoteId(QLatin1String("collection3")); + collection3.setParentCollection(mStore->topLevelCollection()); + + job = mStore->fetchItems(collection3); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 4); + QCOMPARE(itemsFromSpy(spy), items); + + entrySet = entrySet3; + QVERIFY(entrySet.remove(items[ 0 ].remoteId())); + QVERIFY(entrySet.remove(items[ 1 ].remoteId())); + QVERIFY(entrySet.remove(items[ 2 ].remoteId())); + QVERIFY(entrySet.remove(items[ 3 ].remoteId())); + + QCOMPARE(items[ 0 ].parentCollection(), collection3); + QCOMPARE(items[ 1 ].parentCollection(), collection3); + QCOMPARE(items[ 2 ].parentCollection(), collection3); + QCOMPARE(items[ 3 ].parentCollection(), collection3); + + QVERIFY(!items[ 0 ].hasPayload()); + QVERIFY(!items[ 1 ].hasPayload()); + QVERIFY(!items[ 2 ].hasPayload()); + QVERIFY(!items[ 3 ].hasPayload()); + + // see data/README + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + + // 2x \SEEN flags: 2x from index, none from file name + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + var = job->property("remoteIdToTagList"); + QVERIFY(var.isValid()); + + // tagListHash.contains tests below needs sorting of entries, + // but libmaildir does not sort for performance reasons. + // TODO: Check should not depend on any specific ordering. + qSort(items.begin(), items.end(), itemLessThanByRemoteId); + + tagListHash = var.value< QHash >(); + QCOMPARE((int)tagListHash.count(), 3); + QVERIFY(!tagListHash.contains(items[ 0 ].remoteId())); + QVERIFY(!tagListHash.value(items[ 1 ].remoteId()).toString().isEmpty()); + QVERIFY(!tagListHash.value(items[ 2 ].remoteId()).toString().isEmpty()); + QVERIFY(!tagListHash.value(items[ 3 ].remoteId()).toString().isEmpty()); + + // test listing maildir with index which contains IMAP UIDs (dimap cache directory) + Collection collection4; + collection4.setName(QLatin1String("collection4")); + collection4.setRemoteId(QLatin1String("collection4")); + collection4.setParentCollection(mStore->topLevelCollection()); + + job = mStore->fetchItems(collection4); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 4); + QCOMPARE(itemsFromSpy(spy), items); + + entrySet = entrySet4; + QVERIFY(entrySet.remove(items[ 0 ].remoteId())); + QVERIFY(entrySet.remove(items[ 1 ].remoteId())); + QVERIFY(entrySet.remove(items[ 2 ].remoteId())); + QVERIFY(entrySet.remove(items[ 3 ].remoteId())); + + QCOMPARE(items[ 0 ].parentCollection(), collection4); + QCOMPARE(items[ 1 ].parentCollection(), collection4); + QCOMPARE(items[ 2 ].parentCollection(), collection4); + QCOMPARE(items[ 3 ].parentCollection(), collection4); + + QVERIFY(!items[ 0 ].hasPayload()); + QVERIFY(!items[ 1 ].hasPayload()); + QVERIFY(!items[ 2 ].hasPayload()); + QVERIFY(!items[ 3 ].hasPayload()); + + // see data/README + Q_FOREACH (const Item &item, items) { + Q_FOREACH (const QByteArray &flag, item.flags()) { + ++flagCounts[ flag ]; + } + } + QCOMPARE(flagCounts[ "\\SEEN" ], 2); + QCOMPARE(flagCounts[ "\\FLAGGED" ], 1); + QCOMPARE(flagCounts[ "$TODO" ], 1); + flagCounts.clear(); + + var = job->property("remoteIdToTagList"); + QVERIFY(!var.isValid()); + + var = job->property("remoteIdToIndexUid"); + QVERIFY(var.isValid()); + + uidHash = var.value< QHash >(); + QCOMPARE((int)uidHash.count(), 4); + bool ok = false; + QVERIFY(!uidHash.value(items[ 0 ].remoteId()).toString().toInt(&ok) >= 0 && ok); + QVERIFY(!uidHash.value(items[ 1 ].remoteId()).toString().toInt(&ok) >= 0 && ok); + QVERIFY(!uidHash.value(items[ 2 ].remoteId()).toString().toInt(&ok) >= 0 && ok); + QVERIFY(!uidHash.value(items[ 3 ].remoteId()).toString().toInt(&ok) >= 0 && ok); + + // test listing maildir with index but newer modification date than index's one + const QByteArray data5 = md5.readEntry(*entrySet5.cbegin()); + QVERIFY(!data5.isEmpty()); + + QTest::qSleep(1000); + + QString newRemoteId = md5.addEntry(data5); + QVERIFY(!newRemoteId.isEmpty()); + + entrySet = QSet::fromList(md5.entryList()); + entrySet.remove(newRemoteId); + QCOMPARE(entrySet, entrySet5); + QFileInfo fileInfo5(md5.path(), QLatin1String("new")); + QFileInfo indexFileInfo5 = indexFile(QFileInfo(md5.path())); + QVERIFY(fileInfo5.lastModified() > indexFileInfo5.lastModified()); + + Collection collection5; + collection5.setName(QLatin1String("collection5")); + collection5.setRemoteId(QLatin1String("collection5")); + collection5.setParentCollection(mStore->topLevelCollection()); + + job = mStore->fetchItems(collection5); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 5); + QCOMPARE(itemsFromSpy(spy), items); + + entrySet = entrySet5; + entrySet << newRemoteId; + QVERIFY(entrySet.remove(items[ 0 ].remoteId())); + QVERIFY(entrySet.remove(items[ 1 ].remoteId())); + QVERIFY(entrySet.remove(items[ 2 ].remoteId())); + QVERIFY(entrySet.remove(items[ 3 ].remoteId())); + QVERIFY(entrySet.remove(items[ 4 ].remoteId())); + + QCOMPARE(items[ 0 ].parentCollection(), collection5); + QCOMPARE(items[ 1 ].parentCollection(), collection5); + QCOMPARE(items[ 2 ].parentCollection(), collection5); + QCOMPARE(items[ 3 ].parentCollection(), collection5); + QCOMPARE(items[ 4 ].parentCollection(), collection5); + + QVERIFY(!items[ 0 ].hasPayload()); + QVERIFY(!items[ 1 ].hasPayload()); + QVERIFY(!items[ 2 ].hasPayload()); + QVERIFY(!items[ 3 ].hasPayload()); + QVERIFY(!items[ 4 ].hasPayload()); + + // not flags from index, no flags from file names + QCOMPARE(items[ 0 ].flags(), QSet()); + QCOMPARE(items[ 1 ].flags(), QSet()); + QCOMPARE(items[ 2 ].flags(), QSet()); + QCOMPARE(items[ 3 ].flags(), QSet()); + QCOMPARE(items[ 4 ].flags(), QSet()); + + var = job->property("remoteIdToTagList"); + QVERIFY(!var.isValid()); +} + +void ItemFetchTest::testListingMBox() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox"), topDir.path(), QLatin1String("collection1"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox"), topDir.path(), QLatin1String("collection2"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox-tagged"), topDir.path(), QLatin1String("collection3"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox-unpurged"), topDir.path(), QLatin1String("collection4"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox-tagged"), topDir.path(), QLatin1String("collection5"))); + + QFileInfo fileInfo1(topDir.path(), QLatin1String("collection1")); + MBox mbox1; + QVERIFY(mbox1.load(fileInfo1.absoluteFilePath())); + MBoxEntry::List entryList1 = mbox1.entries(); + QCOMPARE((int)entryList1.count(), 4); + + QFileInfo indexFileInfo1 = indexFile(fileInfo1); + QVERIFY(QFile::remove(indexFileInfo1.absoluteFilePath())); + + QFileInfo fileInfo2(topDir.path(), QLatin1String("collection2")); + MBox mbox2; + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + MBoxEntry::List entryList2 = mbox2.entries(); + QCOMPARE((int)entryList2.count(), 4); + + QFileInfo fileInfo3(topDir.path(), QLatin1String("collection3")); + MBox mbox3; + QVERIFY(mbox3.load(fileInfo3.absoluteFilePath())); + MBoxEntry::List entryList3 = mbox3.entries(); + QCOMPARE((int)entryList3.count(), 4); + + QFileInfo fileInfo4(topDir.path(), QLatin1String("collection4")); + MBox mbox4; + QVERIFY(mbox4.load(fileInfo4.absoluteFilePath())); + MBoxEntry::List entryList4 = mbox4.entries(); + QCOMPARE((int)entryList4.count(), 4); + + QFileInfo fileInfo5(topDir.path(), QLatin1String("collection5")); + MBox mbox5; + QVERIFY(mbox5.load(fileInfo5.absoluteFilePath())); + MBoxEntry::List entryList5 = mbox5.entries(); + QCOMPARE((int)entryList5.count(), 4); + + mStore->setPath(topDir.path()); + + // common variables + FileStore::ItemFetchJob *job = 0; + + QSignalSpy *spy = 0; + Item::List items; + + QHash tagListHash; + const QVariant varTagListHash = QVariant::fromValue< QHash >(tagListHash); + QVariant var; + + // test listing mbox without index + Collection collection1; + collection1.setName(QLatin1String("collection1")); + collection1.setRemoteId(QLatin1String("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + job = mStore->fetchItems(collection1); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 4); + QCOMPARE(itemsFromSpy(spy), items); + + QCOMPARE(items[ 0 ].remoteId(), QString::number(entryList1[ 0 ].messageOffset())); + QCOMPARE(items[ 1 ].remoteId(), QString::number(entryList1[ 1 ].messageOffset())); + QCOMPARE(items[ 2 ].remoteId(), QString::number(entryList1[ 2 ].messageOffset())); + QCOMPARE(items[ 3 ].remoteId(), QString::number(entryList1[ 3 ].messageOffset())); + + QCOMPARE(items[ 0 ].parentCollection(), collection1); + QCOMPARE(items[ 1 ].parentCollection(), collection1); + QCOMPARE(items[ 2 ].parentCollection(), collection1); + QCOMPARE(items[ 3 ].parentCollection(), collection1); + + QVERIFY(!items[ 0 ].hasPayload()); + QVERIFY(!items[ 1 ].hasPayload()); + QVERIFY(!items[ 2 ].hasPayload()); + QVERIFY(!items[ 3 ].hasPayload()); + + QCOMPARE(items[ 0 ].flags(), QSet()); + QCOMPARE(items[ 1 ].flags(), QSet()); + QCOMPARE(items[ 2 ].flags(), QSet()); + QCOMPARE(items[ 3 ].flags(), QSet()); + + var = job->property("remoteIdToTagList"); + QVERIFY(!var.isValid()); + + // test listing empty mbox without index + QFile file1(fileInfo1.absoluteFilePath()); + QVERIFY(file1.open(QIODevice::WriteOnly | QIODevice::Truncate)); + file1.close(); + QCOMPARE((int)file1.size(), 0); + + job = mStore->fetchItems(collection1); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 0); + QCOMPARE(spy->count(), 0); + + var = job->property("remoteIdToTagList"); + QVERIFY(!var.isValid()); + + // test listing mbox with index + Collection collection2; + collection2.setName(QLatin1String("collection2")); + collection2.setRemoteId(QLatin1String("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + job = mStore->fetchItems(collection2); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 4); + QCOMPARE(itemsFromSpy(spy), items); + + QCOMPARE(items[ 0 ].remoteId(), QString::number(entryList2[ 0 ].messageOffset())); + QCOMPARE(items[ 1 ].remoteId(), QString::number(entryList2[ 1 ].messageOffset())); + QCOMPARE(items[ 2 ].remoteId(), QString::number(entryList2[ 2 ].messageOffset())); + QCOMPARE(items[ 3 ].remoteId(), QString::number(entryList2[ 3 ].messageOffset())); + + QCOMPARE(items[ 0 ].parentCollection(), collection2); + QCOMPARE(items[ 1 ].parentCollection(), collection2); + QCOMPARE(items[ 2 ].parentCollection(), collection2); + QCOMPARE(items[ 3 ].parentCollection(), collection2); + + QVERIFY(!items[ 0 ].hasPayload()); + QVERIFY(!items[ 1 ].hasPayload()); + QVERIFY(!items[ 2 ].hasPayload()); + QVERIFY(!items[ 3 ].hasPayload()); + + // see data/README + QCOMPARE(items[ 0 ].flags(), QSet()); + QCOMPARE(items[ 1 ].flags(), QSet() << "\\SEEN" << "$TODO"); + QCOMPARE(items[ 2 ].flags(), QSet()); + QCOMPARE(items[ 3 ].flags(), QSet() << "\\SEEN" << "\\FLAGGED"); + + var = job->property("remoteIdToTagList"); + QVERIFY(!var.isValid()); + + // test listing empty mbox with index + QFile file2(fileInfo2.absoluteFilePath()); + QVERIFY(file2.open(QIODevice::WriteOnly | QIODevice::Truncate)); + file2.close(); + QCOMPARE((int)file2.size(), 0); + + job = mStore->fetchItems(collection2); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 0); + QCOMPARE(spy->count(), 0); + + var = job->property("remoteIdToTagList"); + QVERIFY(!var.isValid()); + + // test listing mbox with index which has tags + Collection collection3; + collection3.setName(QLatin1String("collection3")); + collection3.setRemoteId(QLatin1String("collection3")); + collection3.setParentCollection(mStore->topLevelCollection()); + + job = mStore->fetchItems(collection3); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 4); + QCOMPARE(itemsFromSpy(spy), items); + + QCOMPARE(items[ 0 ].remoteId(), QString::number(entryList3[ 0 ].messageOffset())); + QCOMPARE(items[ 1 ].remoteId(), QString::number(entryList3[ 1 ].messageOffset())); + QCOMPARE(items[ 2 ].remoteId(), QString::number(entryList3[ 2 ].messageOffset())); + QCOMPARE(items[ 3 ].remoteId(), QString::number(entryList3[ 3 ].messageOffset())); + + QCOMPARE(items[ 0 ].parentCollection(), collection3); + QCOMPARE(items[ 1 ].parentCollection(), collection3); + QCOMPARE(items[ 2 ].parentCollection(), collection3); + QCOMPARE(items[ 3 ].parentCollection(), collection3); + + QVERIFY(!items[ 0 ].hasPayload()); + QVERIFY(!items[ 1 ].hasPayload()); + QVERIFY(!items[ 2 ].hasPayload()); + QVERIFY(!items[ 3 ].hasPayload()); + + // see data/README + QCOMPARE(items[ 0 ].flags(), QSet()); + QCOMPARE(items[ 1 ].flags(), QSet() << "\\SEEN" << "$TODO"); + QCOMPARE(items[ 2 ].flags(), QSet()); + QCOMPARE(items[ 3 ].flags(), QSet() << "\\SEEN" << "\\FLAGGED"); + + var = job->property("remoteIdToTagList"); + QVERIFY(var.isValid()); + + tagListHash = var.value< QHash >(); + QCOMPARE((int)tagListHash.count(), 3); + QVERIFY(!tagListHash.value(items[ 0 ].remoteId()).toString().isEmpty()); + QVERIFY(!tagListHash.contains(items[ 1 ].remoteId())); + QVERIFY(!tagListHash.value(items[ 2 ].remoteId()).toString().isEmpty()); + QVERIFY(!tagListHash.value(items[ 3 ].remoteId()).toString().isEmpty()); + + // test listing mbox with index and unpurged messages (in mbox but not in index) + Collection collection4; + collection4.setName(QLatin1String("collection4")); + collection4.setRemoteId(QLatin1String("collection4")); + collection4.setParentCollection(mStore->topLevelCollection()); + + job = mStore->fetchItems(collection4); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 4); + QCOMPARE(itemsFromSpy(spy), items); + + QCOMPARE(items[ 0 ].remoteId(), QString::number(entryList4[ 0 ].messageOffset())); + QCOMPARE(items[ 1 ].remoteId(), QString::number(entryList4[ 1 ].messageOffset())); + QCOMPARE(items[ 2 ].remoteId(), QString::number(entryList4[ 2 ].messageOffset())); + QCOMPARE(items[ 3 ].remoteId(), QString::number(entryList4[ 3 ].messageOffset())); + + QCOMPARE(items[ 0 ].parentCollection(), collection4); + QCOMPARE(items[ 1 ].parentCollection(), collection4); + QCOMPARE(items[ 2 ].parentCollection(), collection4); + QCOMPARE(items[ 3 ].parentCollection(), collection4); + + QVERIFY(!items[ 0 ].hasPayload()); + QVERIFY(!items[ 1 ].hasPayload()); + QVERIFY(!items[ 2 ].hasPayload()); + QVERIFY(!items[ 3 ].hasPayload()); + + // see data/README + QCOMPARE(items[ 0 ].flags(), QSet() << "\\SEEN"); + QCOMPARE(items[ 1 ].flags(), QSet() << "\\DELETED"); + QCOMPARE(items[ 2 ].flags(), QSet() << "\\DELETED"); + QCOMPARE(items[ 3 ].flags(), QSet() << "\\SEEN"); + + var = job->property("remoteIdToTagList"); + QVERIFY(!var.isValid()); + + // test listing mbox with index but newer modification date than index's one + QFile file5(fileInfo5.absoluteFilePath()); + QVERIFY(file5.open(QIODevice::ReadOnly)); + const QByteArray data5 = file5.readAll(); + file5.close(); + + QTest::qSleep(1000); + + QVERIFY(file5.open(QIODevice::WriteOnly)); + file5.write(data5); + file5.close(); + + QCOMPARE(file5.size(), fileInfo5.size()); + fileInfo5.refresh(); + QFileInfo indexFileInfo5 = indexFile(fileInfo5); + QVERIFY(fileInfo5.lastModified() > indexFileInfo5.lastModified()); + + Collection collection5; + collection5.setName(QLatin1String("collection5")); + collection5.setRemoteId(QLatin1String("collection5")); + collection5.setParentCollection(mStore->topLevelCollection()); + + job = mStore->fetchItems(collection5); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 4); + QCOMPARE(itemsFromSpy(spy), items); + + QCOMPARE(items[ 0 ].remoteId(), QString::number(entryList5[ 0 ].messageOffset())); + QCOMPARE(items[ 1 ].remoteId(), QString::number(entryList5[ 1 ].messageOffset())); + QCOMPARE(items[ 2 ].remoteId(), QString::number(entryList5[ 2 ].messageOffset())); + QCOMPARE(items[ 3 ].remoteId(), QString::number(entryList5[ 3 ].messageOffset())); + + QCOMPARE(items[ 0 ].parentCollection(), collection5); + QCOMPARE(items[ 1 ].parentCollection(), collection5); + QCOMPARE(items[ 2 ].parentCollection(), collection5); + QCOMPARE(items[ 3 ].parentCollection(), collection5); + + QVERIFY(!items[ 0 ].hasPayload()); + QVERIFY(!items[ 1 ].hasPayload()); + QVERIFY(!items[ 2 ].hasPayload()); + QVERIFY(!items[ 3 ].hasPayload()); + + QCOMPARE(items[ 0 ].flags(), QSet()); + QCOMPARE(items[ 1 ].flags(), QSet()); + QCOMPARE(items[ 2 ].flags(), QSet()); + QCOMPARE(items[ 3 ].flags(), QSet()); + + var = job->property("remoteIdToTagList"); + QVERIFY(!var.isValid()); + + // test that a new message in an mbox with index it not marked as deleted + KMime::Message::Ptr msgPtr(new KMime::Message); + msgPtr->subject()->from7BitString("Test 5"); + msgPtr->to()->from7BitString("kevin.krammer@gmx.at"); + msgPtr->assemble(); + + Item item3_5; + item3_5.setMimeType(KMime::Message::mimeType()); + item3_5.setPayload(msgPtr); + + FileStore::ItemCreateJob *itemCreate = mStore->createItem(item3_5, collection3); + QVERIFY(itemCreate->exec()); + + item3_5 = itemCreate->item(); + QVERIFY(!item3_5.remoteId().isEmpty()); + + job = mStore->fetchItems(collection3); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 5); + QCOMPARE(itemsFromSpy(spy), items); + + QCOMPARE(items[ 0 ].remoteId(), QString::number(entryList3[ 0 ].messageOffset())); + QCOMPARE(items[ 1 ].remoteId(), QString::number(entryList3[ 1 ].messageOffset())); + QCOMPARE(items[ 2 ].remoteId(), QString::number(entryList3[ 2 ].messageOffset())); + QCOMPARE(items[ 3 ].remoteId(), QString::number(entryList3[ 3 ].messageOffset())); + QCOMPARE(items[ 4 ].remoteId(), item3_5.remoteId()); + + QCOMPARE(items[ 0 ].parentCollection(), collection3); + QCOMPARE(items[ 1 ].parentCollection(), collection3); + QCOMPARE(items[ 2 ].parentCollection(), collection3); + QCOMPARE(items[ 3 ].parentCollection(), collection3); + QCOMPARE(items[ 4 ].parentCollection(), collection3); + + QVERIFY(!items[ 0 ].hasPayload()); + QVERIFY(!items[ 1 ].hasPayload()); + QVERIFY(!items[ 2 ].hasPayload()); + QVERIFY(!items[ 3 ].hasPayload()); + QVERIFY(!items[ 4 ].hasPayload()); + + // see data/README + QCOMPARE(items[ 0 ].flags(), QSet()); + QCOMPARE(items[ 1 ].flags(), QSet() << "\\SEEN" << "$TODO"); + QCOMPARE(items[ 2 ].flags(), QSet()); + QCOMPARE(items[ 3 ].flags(), QSet() << "\\SEEN" << "\\FLAGGED"); + QCOMPARE(items[ 4 ].flags(), QSet()); + + var = job->property("remoteIdToTagList"); + QVERIFY(var.isValid()); +} + +void ItemFetchTest::testSingleItemFetchMaildir() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir"), topDir.path(), QLatin1String("collection1"))); + + KPIM::Maildir topLevelMd(topDir.path(), true); + + KPIM::Maildir md1 = topLevelMd.subFolder(QLatin1String("collection1")); + QStringList entryList1 = md1.entryList(); + QCOMPARE((int)entryList1.count(), 4); + + KRandomSequence randomSequence; + QStringList randomList1 = entryList1; + randomSequence.randomize(randomList1); + + mStore->setPath(topDir.path()); + + // common variables + FileStore::ItemFetchJob *job = 0; + + QSignalSpy *spy = 0; + Item::List items; + + // test fetching from maildir, headers only + Collection collection1; + collection1.setName(QLatin1String("collection1")); + collection1.setRemoteId(QLatin1String("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + Q_FOREACH (const QString &entry, randomList1) { + Item item1; + item1.setId(KRandom::random()); + item1.setRemoteId(entry); + item1.setParentCollection(collection1); + + job = mStore->fetchItem(item1); + job->fetchScope().fetchPayloadPart(MessagePart::Header); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 1); + QCOMPARE(itemsFromSpy(spy), items); + + Item item = items.first(); + QCOMPARE(item, item1); + QVERIFY(item.hasPayload()); + + KMime::Message::Ptr msgPtr = item.payload(); + QVERIFY(msgPtr != 0); + + const QSet parts = messageParts(msgPtr); + QVERIFY(!parts.isEmpty()); + QVERIFY(parts.contains(MessagePart::Header)); + QVERIFY(!parts.contains(MessagePart::Body)); + } + + // test fetching from maildir, including body + randomSequence.randomize(randomList1); + Q_FOREACH (const QString &entry, randomList1) { + Item item1; + item1.setId(KRandom::random()); + item1.setRemoteId(entry); + item1.setParentCollection(collection1); + + job = mStore->fetchItem(item1); + job->fetchScope().fetchPayloadPart(MessagePart::Header); + job->fetchScope().fetchPayloadPart(MessagePart::Body); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 1); + QCOMPARE(itemsFromSpy(spy), items); + + Item item = items.first(); + QCOMPARE(item, item1); + QVERIFY(item.hasPayload()); + + KMime::Message::Ptr msgPtr = item.payload(); + QVERIFY(msgPtr != 0); + + const QSet parts = messageParts(msgPtr); + QVERIFY(!parts.isEmpty()); + QVERIFY(parts.contains(MessagePart::Header)); + QVERIFY(parts.contains(MessagePart::Body)); + } + + // test fetching from maildir, just specifying full payload + randomSequence.randomize(randomList1); + Q_FOREACH (const QString &entry, randomList1) { + Item item1; + item1.setId(KRandom::random()); + item1.setRemoteId(entry); + item1.setParentCollection(collection1); + + job = mStore->fetchItem(item1); + job->fetchScope().fetchFullPayload(true); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 1); + QCOMPARE(itemsFromSpy(spy), items); + + Item item = items.first(); + QCOMPARE(item, item1); + QVERIFY(item.hasPayload()); + + KMime::Message::Ptr msgPtr = item.payload(); + QVERIFY(msgPtr != 0); + + const QSet parts = messageParts(msgPtr); + QVERIFY(!parts.isEmpty()); + QVERIFY(parts.contains(MessagePart::Header)); + QVERIFY(parts.contains(MessagePart::Body)); + } +} + +void ItemFetchTest::testSingleItemFetchMBox() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox"), topDir.path(), QLatin1String("collection1"))); + // one message has no body + const QByteArray messageIdOfEmptyBodyMsg = "201007241551.37547.kevin.krammer@demo.kolab.org"; + + QFileInfo fileInfo1(topDir.path(), QLatin1String("collection1")); + MBox mbox1; + QVERIFY(mbox1.load(fileInfo1.absoluteFilePath())); + MBoxEntry::List entryList1 = mbox1.entries(); + QCOMPARE((int)entryList1.count(), 4); + + KRandomSequence randomSequence; + MBoxEntry::List randomList1 = entryList1; + randomSequence.randomize(randomList1); + + mStore->setPath(topDir.path()); + + // common variables + FileStore::ItemFetchJob *job = 0; + + QSignalSpy *spy = 0; + Item::List items; + + // test fetching from mbox, headers only + Collection collection1; + collection1.setName(QLatin1String("collection1")); + collection1.setRemoteId(QLatin1String("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + Q_FOREACH (const MBoxEntry &entry, randomList1) { + Item item1; + item1.setId(KRandom::random()); + item1.setRemoteId(QString::number(entry.messageOffset())); + item1.setParentCollection(collection1); + + job = mStore->fetchItem(item1); + job->fetchScope().fetchPayloadPart(MessagePart::Header); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 1); + QCOMPARE(itemsFromSpy(spy), items); + + Item item = items.first(); + QCOMPARE(item, item1); + QVERIFY(item.hasPayload()); + + KMime::Message::Ptr msgPtr = item.payload(); + QVERIFY(msgPtr != 0); + + const QSet parts = messageParts(msgPtr); + QVERIFY(!parts.isEmpty()); + QVERIFY(parts.contains(MessagePart::Header)); + QVERIFY(!parts.contains(MessagePart::Body)); + } + + // test fetching from mbox, including body + randomSequence.randomize(randomList1); + Q_FOREACH (const MBoxEntry &entry, randomList1) { + Item item1; + item1.setId(KRandom::random()); + item1.setRemoteId(QString::number(entry.messageOffset())); + item1.setParentCollection(collection1); + + job = mStore->fetchItem(item1); + job->fetchScope().fetchPayloadPart(MessagePart::Header); + job->fetchScope().fetchPayloadPart(MessagePart::Body); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 1); + QCOMPARE(itemsFromSpy(spy), items); + + Item item = items.first(); + QCOMPARE(item, item1); + QVERIFY(item.hasPayload()); + + KMime::Message::Ptr msgPtr = item.payload(); + QVERIFY(msgPtr != 0); + + const QSet parts = messageParts(msgPtr); + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << msgPtr->messageID()->identifier(); + QVERIFY(!parts.isEmpty()); + QVERIFY(parts.contains(MessagePart::Header)); + if (msgPtr->messageID()->identifier() == messageIdOfEmptyBodyMsg) { + QVERIFY(!parts.contains(MessagePart::Body)); + } else { + QVERIFY(parts.contains(MessagePart::Body)); + } + } + + // test fetching from mbox, just specifying full payload + randomSequence.randomize(randomList1); + Q_FOREACH (const MBoxEntry &entry, randomList1) { + Item item1; + item1.setId(KRandom::random()); + item1.setRemoteId(QString::number(entry.messageOffset())); + item1.setParentCollection(collection1); + + job = mStore->fetchItem(item1); + job->fetchScope().fetchFullPayload(true); + + spy = new QSignalSpy(job, SIGNAL(itemsReceived(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + items = job->items(); + QCOMPARE((int)items.count(), 1); + QCOMPARE(itemsFromSpy(spy), items); + + Item item = items.first(); + QCOMPARE(item, item1); + QVERIFY(item.hasPayload()); + + KMime::Message::Ptr msgPtr = item.payload(); + QVERIFY(msgPtr != 0); + + const QSet parts = messageParts(msgPtr); + QVERIFY(!parts.isEmpty()); + QVERIFY(parts.contains(MessagePart::Header)); + if (msgPtr->messageID()->identifier() == messageIdOfEmptyBodyMsg) { + QVERIFY(!parts.contains(MessagePart::Body)); + } else { + QVERIFY(parts.contains(MessagePart::Body)); + } + } +} + +QTEST_MAIN(ItemFetchTest) + +#include "itemfetchtest.moc" + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/itemmodifytest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/itemmodifytest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/itemmodifytest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/itemmodifytest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,671 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.com + Copyright (C) 2011 Kevin Krammer, kevin.krammer@gmx.at + + 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 "mixedmaildirstore.h" + +#include "testdatautil.h" + +#include "filestore/itemfetchjob.h" +#include "filestore/itemmodifyjob.h" +#include "filestore/storecompactjob.h" + +#include "libmaildir/maildir.h" + +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +using namespace Akonadi; +using namespace KMBox; + +static bool fullEntryCompare(const MBoxEntry &a, const MBoxEntry &b) +{ + return a.messageOffset() == b.messageOffset() && + a.separatorSize() == b.separatorSize() && + a.messageSize() == b.messageSize(); +} + +class ItemModifyTest : public QObject +{ + Q_OBJECT + +public: + ItemModifyTest() + : QObject(), mStore(0), mDir(0) {} + + ~ItemModifyTest() + { + delete mStore; + delete mDir; + } + +private: + MixedMaildirStore *mStore; + QTemporaryDir *mDir; + +private Q_SLOTS: + void init(); + void cleanup(); + void testExpectedFail(); + void testIgnorePayload(); + void testModifyPayload(); + void testModifyFlags(); + void testModifyFlagsAndPayload(); +}; + +void ItemModifyTest::init() +{ + mStore = new MixedMaildirStore; + + mDir = new QTemporaryDir; + QVERIFY(mDir->isValid()); + QVERIFY(QDir(mDir->path()).exists()); + +} + +void ItemModifyTest::cleanup() +{ + delete mStore; + mStore = 0; + delete mDir; + mDir = 0; +} + +void ItemModifyTest::testExpectedFail() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir"), topDir.path(), QStringLiteral("collection1"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox"), topDir.path(), QStringLiteral("collection2"))); + + KPIM::Maildir topLevelMd(topDir.path(), true); + + KPIM::Maildir md1 = topLevelMd.subFolder(QLatin1String("collection1")); + QSet entrySet1 = QSet::fromList(md1.entryList()); + QCOMPARE((int)entrySet1.count(), 4); + + QFileInfo fileInfo2(topDir.path(), QStringLiteral("collection2")); + MBox mbox2; + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + MBoxEntry::List entryList2 = mbox2.entries(); + QCOMPARE((int)entryList2.count(), 4); + + QSet entrySet2; + Q_FOREACH (const MBoxEntry &entry, entryList2) { + entrySet2 << entry.messageOffset(); + } + + mStore->setPath(topDir.path()); + + // common variables + FileStore::ItemModifyJob *job = 0; + + // test failure of modifying a non-existent maildir entry + Collection collection1; + collection1.setName(QLatin1String("collection1")); + collection1.setRemoteId(QLatin1String("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + QString remoteId1; + do { + remoteId1 = KRandom::randomString(20); + } while (entrySet1.contains(remoteId1)); + + KMime::Message::Ptr msgPtr(new KMime::Message); + + Item item1; + item1.setMimeType(KMime::Message::mimeType()); + item1.setRemoteId(remoteId1); + item1.setParentCollection(collection1); + item1.setPayload(msgPtr); + + job = mStore->modifyItem(item1); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + QSet entrySet = QSet::fromList(md1.entryList()); + QCOMPARE(entrySet, entrySet1); + + // test failure of modifying a non-existent mbox entry + Collection collection2; + collection2.setName(QLatin1String("collection2")); + collection2.setRemoteId(QLatin1String("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + qint64 remoteId2; + do { + remoteId2 = KRandom::random(); + } while (entrySet2.contains(remoteId2)); + + Item item2; + item2.setMimeType(KMime::Message::mimeType()); + item2.setRemoteId(QString::number(remoteId2)); + item2.setParentCollection(collection2); + item2.setPayload(msgPtr); + + job = mStore->modifyItem(item2); + + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + QVERIFY(mbox2.load(mbox2.fileName())); + MBoxEntry::List entryList = mbox2.entries(); + QVERIFY(std::equal(entryList.begin(), entryList.end(), entryList2.begin(), fullEntryCompare)); +} + +void ItemModifyTest::testIgnorePayload() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir"), topDir.path(), QStringLiteral("collection1"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox"), topDir.path(), QStringLiteral("collection2"))); + + KPIM::Maildir topLevelMd(topDir.path(), true); + + KPIM::Maildir md1 = topLevelMd.subFolder(QLatin1String("collection1")); + QStringList entryList1 = md1.entryList(); + QCOMPARE((int)entryList1.count(), 4); + + QFileInfo fileInfo2(topDir.path(), QStringLiteral("collection2")); + MBox mbox2; + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + MBoxEntry::List entryList2 = mbox2.entries(); + QCOMPARE((int)entryList2.count(), 4); + + mStore->setPath(topDir.path()); + + // common variables + FileStore::ItemModifyJob *job = 0; + + // test failure of modifying a non-existent maildir entry + Collection collection1; + collection1.setName(QLatin1String("collection1")); + collection1.setRemoteId(QLatin1String("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + const QByteArray data1 = md1.readEntry(entryList1.first()); + + KMime::Message::Ptr msgPtr(new KMime::Message); + msgPtr->subject()->from7BitString("Modify Test"); + msgPtr->assemble(); + + Item item1; + item1.setMimeType(KMime::Message::mimeType()); + item1.setRemoteId(entryList1.first()); + item1.setParentCollection(collection1); + item1.setPayload(msgPtr); + + job = mStore->modifyItem(item1); + job->setIgnorePayload(true); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + QCOMPARE(md1.entryList(), entryList1); + QCOMPARE(md1.readEntry(entryList1.first()), data1); + + // test failure of modifying a non-existent mbox entry + Collection collection2; + collection2.setName(QLatin1String("collection2")); + collection2.setRemoteId(QLatin1String("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + const QByteArray data2 = mbox2.readRawMessage(MBoxEntry(0)); + + Item item2; + item2.setMimeType(KMime::Message::mimeType()); + item2.setRemoteId(QLatin1String("0")); + item2.setParentCollection(collection2); + item2.setPayload(msgPtr); + + job = mStore->modifyItem(item2); + job->setIgnorePayload(true); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + QVERIFY(mbox2.load(mbox2.fileName())); + QCOMPARE(mbox2.entries(), entryList2); + QCOMPARE(mbox2.readRawMessage(MBoxEntry(0)), data2); +} + +void ItemModifyTest::testModifyPayload() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir"), topDir.path(), QStringLiteral("collection1"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox"), topDir.path(), QStringLiteral("collection2"))); + + KPIM::Maildir topLevelMd(topDir.path(), true); + + KPIM::Maildir md1 = topLevelMd.subFolder(QLatin1String("collection1")); + QStringList entryList1 = md1.entryList(); + QCOMPARE((int)entryList1.count(), 4); + + QFileInfo fileInfo2(topDir.path(), QStringLiteral("collection2")); + MBox mbox2; + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + MBoxEntry::List entryList2 = mbox2.entries(); + QCOMPARE((int)entryList2.count(), 4); + + mStore->setPath(topDir.path()); + + // common variables + FileStore::ItemModifyJob *job = 0; + + const QVariant colListVar = QVariant::fromValue(Collection::List()); + QVariant var; + Collection::List collections; + + // test modifying a maildir entry's header + Collection collection1; + collection1.setName(QLatin1String("collection1")); + collection1.setRemoteId(QLatin1String("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + const QByteArray data1 = md1.readEntry(entryList1.first()); + + KMime::Message::Ptr msgPtr(new KMime::Message); + msgPtr->setContent(KMime::CRLFtoLF(data1)); + msgPtr->subject()->from7BitString("Modify Test"); + msgPtr->assemble(); + + Item item1; + item1.setMimeType(KMime::Message::mimeType()); + item1.setRemoteId(entryList1.first()); + item1.setParentCollection(collection1); + item1.setPayload(msgPtr); + + job = mStore->modifyItem(item1); + // changing subject, so indicate a header change + job->setParts(QSet() << QByteArray("PLD:") + QByteArray(MessagePart::Header)); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + QCOMPARE(md1.entryList(), entryList1); + + QCOMPARE(md1.readEntry(entryList1.first()).size(), + msgPtr->encodedContent().size()); + QCOMPARE(md1.readEntry(entryList1.first()), msgPtr->encodedContent()); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection1); + + // test modifying an mbox entry's header + Collection collection2; + collection2.setName(QLatin1String("collection2")); + collection2.setRemoteId(QLatin1String("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + const QByteArray data2 = mbox2.readRawMessage(MBoxEntry(0)); + + msgPtr->setContent(KMime::CRLFtoLF(data2)); + msgPtr->subject()->from7BitString("Modify Test"); + msgPtr->assemble(); + + Item item2; + item2.setMimeType(KMime::Message::mimeType()); + item2.setRemoteId(QLatin1String("0")); + item2.setParentCollection(collection2); + item2.setPayload(msgPtr); + + job = mStore->modifyItem(item2); + // changing subject, so indicate a header change + job->setParts(QSet() << QByteArray("PLD:") + QByteArray(MessagePart::Header)); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + Item item = job->item(); + + QVERIFY(mbox2.load(mbox2.fileName())); + MBoxEntry::List entryList = mbox2.entries(); + QCOMPARE((int)entryList.count(), 5); // mbox file not purged yet + QCOMPARE(entryList.last().messageOffset(), item.remoteId().toULongLong()); + + var = job->property("compactStore"); + QVERIFY(var.isValid()); + QCOMPARE(var.type(), QVariant::Bool); + QCOMPARE(var.toBool(), true); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection2); + + FileStore::ItemFetchJob *itemFetch = mStore->fetchItem(item2); + QVERIFY(!itemFetch->exec()); // item at old offset gone + + FileStore::StoreCompactJob *storeCompact = mStore->compactStore(); + QVERIFY(storeCompact->exec()); + + QVERIFY(mbox2.load(mbox2.fileName())); + entryList = mbox2.entries(); + QCOMPARE((int)entryList.count(), 4); + + QCOMPARE(mbox2.readRawMessage(entryList.last()), msgPtr->encodedContent()); +} + +void ItemModifyTest::testModifyFlags() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir"), topDir.path(), QStringLiteral("collection1"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox"), topDir.path(), QStringLiteral("collection2"))); + + KPIM::Maildir topLevelMd(topDir.path(), true); + + KPIM::Maildir md1 = topLevelMd.subFolder(QLatin1String("collection1")); + QStringList entryList1 = md1.entryList(); + QCOMPARE((int)entryList1.count(), 4); + + QFileInfo fileInfo2(topDir.path(), QStringLiteral("collection2")); + MBox mbox2; + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + MBoxEntry::List entryList2 = mbox2.entries(); + QCOMPARE((int)entryList2.count(), 4); + + QCryptographicHash cryptoHash(QCryptographicHash::Sha1); + + QFile file2(fileInfo2.absoluteFilePath()); + QVERIFY(file2.open(QIODevice::ReadOnly)); + cryptoHash.addData(file2.readAll()); + const QByteArray mbox2Sha1 = cryptoHash.result(); + + file2.close(); + cryptoHash.reset(); + + mStore->setPath(topDir.path()); + + // common variables + FileStore::ItemModifyJob *job = 0; + + const QVariant colListVar = QVariant::fromValue(Collection::List()); + QVariant var; + Collection::List collections; + KMime::Message::Ptr msgPtr(new KMime::Message); + + // test modifying a flag of a maildir items changes the entry name but not the + // message contents + Collection collection1; + collection1.setName(QLatin1String("collection1")); + collection1.setRemoteId(QLatin1String("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + // check that the \SEEN flag is not set yet + QVERIFY(!md1.readEntryFlags(entryList1.first()).contains("\\SEEN")); + + const QByteArray data1 = md1.readEntry(entryList1.first()); + + msgPtr->setContent(KMime::CRLFtoLF(data1)); + msgPtr->subject()->from7BitString("Modify Test"); + msgPtr->assemble(); + + Item item1; + item1.setMimeType(KMime::Message::mimeType()); + item1.setRemoteId(entryList1.first()); + item1.setParentCollection(collection1); + item1.setPayload(msgPtr); + item1.setFlag("\\SEEN"); + + job = mStore->modifyItem(item1); + // setting \SEEN, so indicate a flags change + job->setParts(QSet() << "FLAGS"); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + Item item = job->item(); + + // returned item should contain the change + QVERIFY(item.flags().contains("\\SEEN")); + + // remote ID has changed + QVERIFY(item.remoteId() != entryList1.first()); + QVERIFY(!md1.entryList().contains(entryList1.first())); + + // no change in number of entries, one difference + QStringList entryList3 = md1.entryList(); + QCOMPARE(entryList3.count(), entryList1.count()); + Q_FOREACH (const QString &oldEntry, entryList1) { + entryList3.removeAll(oldEntry); + } + QCOMPARE(entryList3.count(), 1); + + // no change to data + QCOMPARE(md1.readEntry(entryList3.first()), data1); + + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection1); + + // fetch new item, check flag + item1 = Item(); + item1.setMimeType(KMime::Message::mimeType()); + item1.setRemoteId(entryList3.first()); + item1.setParentCollection(collection1); + + FileStore::ItemFetchJob *itemFetch = mStore->fetchItem(item1); + + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + QCOMPARE(itemFetch->items().count(), 1); + QEXPECT_FAIL("", "ItemFetch handling needs to be fixed to also fetch flags", Continue); + QVERIFY(itemFetch->items()[ 0 ].flags().contains("\\SEEN")); + + // test modifying flags of an mbox item "succeeds" (no error) but does not change + // anything in store or on disk + Collection collection2; + collection2.setName(QLatin1String("collection2")); + collection2.setRemoteId(QLatin1String("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + const QByteArray data2 = mbox2.readRawMessage(MBoxEntry(0)); + + msgPtr->setContent(KMime::CRLFtoLF(data2)); + msgPtr->subject()->from7BitString("Modify Test"); + msgPtr->assemble(); + + Item item2; + item2.setMimeType(KMime::Message::mimeType()); + item2.setRemoteId(QLatin1String("0")); + item2.setParentCollection(collection2); + item2.setPayload(msgPtr); + item2.setFlag("\\SEEN"); + + job = mStore->modifyItem(item2); + // setting \SEEN, so indicate a flags change + job->setParts(QSet() << "FLAGS"); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + item = job->item(); + + // returned item should contain the change + QVERIFY(item.flags().contains("\\SEEN")); + + // mbox not changed + QVERIFY(mbox2.load(mbox2.fileName())); + MBoxEntry::List entryList = mbox2.entries(); + QCOMPARE((int)entryList.count(), 4); + + var = job->property("compactStore"); + QVERIFY(!var.isValid()); + + // file not modified + QVERIFY(file2.open(QIODevice::ReadOnly)); + cryptoHash.addData(file2.readAll()); + QCOMPARE(cryptoHash.result(), mbox2Sha1); + + file2.close(); + cryptoHash.reset(); + + // check index preservation is not triggered + var = job->property("onDiskIndexInvalidated"); + QVERIFY(!var.isValid()); + +} + +void ItemModifyTest::testModifyFlagsAndPayload() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir"), topDir.path(), QStringLiteral("collection1"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox"), topDir.path(), QStringLiteral("collection2"))); + + KPIM::Maildir topLevelMd(topDir.path(), true); + + KPIM::Maildir md1 = topLevelMd.subFolder(QLatin1String("collection1")); + QStringList entryList1 = md1.entryList(); + QCOMPARE((int)entryList1.count(), 4); + + QFileInfo fileInfo2(topDir.path(), QStringLiteral("collection2")); + MBox mbox2; + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + MBoxEntry::List entryList2 = mbox2.entries(); + QCOMPARE((int)entryList2.count(), 4); + + mStore->setPath(topDir.path()); + + // common variables + FileStore::ItemModifyJob *job = 0; + + const QVariant colListVar = QVariant::fromValue(Collection::List()); + QVariant var; + Collection::List collections; + KMime::Message::Ptr msgPtr(new KMime::Message); + + // test modifying a flag of a maildir items changes the entry name but not the + // message contents + Collection collection1; + collection1.setName(QLatin1String("collection1")); + collection1.setRemoteId(QLatin1String("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + // check that the \SEEN flag is not set yet + QVERIFY(!md1.readEntryFlags(entryList1.first()).contains("\\SEEN")); + + const QByteArray data1 = md1.readEntry(entryList1.first()); + + msgPtr->setContent(KMime::CRLFtoLF(data1)); + msgPtr->subject()->from7BitString("Modify Test"); + msgPtr->assemble(); + + Item item1; + item1.setMimeType(KMime::Message::mimeType()); + item1.setRemoteId(entryList1.first()); + item1.setParentCollection(collection1); + item1.setPayload(msgPtr); + item1.setFlag("\\SEEN"); + + job = mStore->modifyItem(item1); + // setting \SEEN so indicate a flags change and + // setting new subject so indicate a payload change + job->setParts(QSet() << "FLAGS" + << QByteArray("PLD:") + QByteArray(MessagePart::Header)); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + Item item = job->item(); + + // returned item should contain the change + QVERIFY(item.flags().contains("\\SEEN")); + + // remote ID has changed + QVERIFY(item.remoteId() != entryList1.first()); + QVERIFY(!md1.entryList().contains(entryList1.first())); + + // no change in number of entries, one difference + QStringList entryList3 = md1.entryList(); + QCOMPARE(entryList3.count(), entryList1.count()); + Q_FOREACH (const QString &oldEntry, entryList1) { + entryList3.removeAll(oldEntry); + } + QCOMPARE(entryList3.count(), 1); + + // data changed + QCOMPARE(md1.readEntry(entryList3.first()), msgPtr->encodedContent()); + + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection1); + + // fetch new item, check flag + item1 = Item(); + item1.setMimeType(KMime::Message::mimeType()); + item1.setRemoteId(entryList3.first()); + item1.setParentCollection(collection1); + + FileStore::ItemFetchJob *itemFetch = mStore->fetchItem(item1); + itemFetch->fetchScope().fetchFullPayload(); + + QVERIFY(itemFetch->exec()); + QCOMPARE(itemFetch->error(), 0); + + QCOMPARE(itemFetch->items().count(), 1); + Item fetchedItem = itemFetch->items().first(); + QEXPECT_FAIL("", "ItemFetch handling needs to be fixed to also fetch flags", Continue); + QVERIFY(fetchedItem.flags().contains("\\SEEN")); + + QVERIFY(fetchedItem.hasPayload()); + KMime::Message::Ptr fetchedMsgPtr = fetchedItem.payload(); + QCOMPARE(msgPtr->encodedContent(), fetchedMsgPtr->encodedContent()); + + // TODO test for mbox. +} + +QTEST_MAIN(ItemModifyTest) + +#include "itemmodifytest.moc" + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/itemmovetest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/itemmovetest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/itemmovetest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/itemmovetest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,676 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" + +#include "testdatautil.h" + +#include "filestore/entitycompactchangeattribute.h" +#include "filestore/itemfetchjob.h" +#include "filestore/itemmovejob.h" +#include "filestore/storecompactjob.h" + +#include "libmaildir/maildir.h" + +#include +#include + +#include +#include + +#include + +#include +#include +#include +using namespace Akonadi; +using namespace KMBox; + +static bool fullEntryCompare(const MBoxEntry &a, const MBoxEntry &b) +{ + return a.messageOffset() == b.messageOffset() && + a.separatorSize() == b.separatorSize() && + a.messageSize() == b.messageSize(); +} + +static quint64 changedOffset(const Item &item) +{ + Q_ASSERT(item.hasAttribute()); + + const QString remoteId = item.attribute()->remoteId(); + Q_ASSERT(!remoteId.isEmpty()); + + bool ok = false; + const quint64 result = remoteId.toULongLong(&ok); + Q_ASSERT(ok); + + return result; +} + +class ItemMoveTest : public QObject +{ + Q_OBJECT + +public: + ItemMoveTest() + : QObject(), mStore(0), mDir(0) {} + + ~ItemMoveTest() + { + delete mStore; + delete mDir; + } + +private: + MixedMaildirStore *mStore; + QTemporaryDir *mDir; + +private Q_SLOTS: + void init(); + void cleanup(); + void testExpectedFail(); + void testMaildirItem(); + void testMBoxItem(); +}; + +void ItemMoveTest::init() +{ + mStore = new MixedMaildirStore; + + mDir = new QTemporaryDir; + QVERIFY(mDir->isValid()); + QVERIFY(QDir(mDir->path()).exists()); +} + +void ItemMoveTest::cleanup() +{ + delete mStore; + mStore = 0; + delete mDir; + mDir = 0; +} + +void ItemMoveTest::testExpectedFail() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection1"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection2"))); + + KPIM::Maildir topLevelMd(topDir.path(), true); + + KPIM::Maildir md1 = topLevelMd.subFolder(QStringLiteral("collection1")); + QSet entrySet1 = QSet::fromList(md1.entryList()); + QCOMPARE((int)entrySet1.count(), 4); + + QFileInfo fileInfo2(topDir.path(), QStringLiteral("collection2")); + MBox mbox2; + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + MBoxEntry::List entryList2 = mbox2.entries(); + QCOMPARE((int)entryList2.count(), 4); + + QSet entrySet2; + Q_FOREACH (const MBoxEntry &entry, entryList2) { + entrySet2 << entry.messageOffset(); + } + + mStore->setPath(topDir.path()); + + // common variables + FileStore::ItemMoveJob *job = 0; + + // test failure of moving from a non-existent collection + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + Collection collection3; + collection3.setName(QStringLiteral("collection3")); + collection3.setRemoteId(QStringLiteral("collection3")); + collection3.setParentCollection(mStore->topLevelCollection()); + + Item item3; + item3.setRemoteId(QStringLiteral("item3")); + item3.setParentCollection(collection3); + + job = mStore->moveItem(item3, collection1); + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + QCOMPARE(QSet::fromList(md1.entryList()), entrySet1); + + // test failure of moving from maildir to non-existent collection + Item item1; + item1.setId(KRandom::random()); + item1.setRemoteId(*entrySet1.cbegin()); + item1.setParentCollection(collection1); + + job = mStore->moveItem(item1, collection3); + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + QCOMPARE(QSet::fromList(md1.entryList()), entrySet1); + + // test failure of moving from mbox to non-existent collection + Collection collection2; + collection2.setName(QStringLiteral("collection2")); + collection2.setRemoteId(QStringLiteral("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + Item item2; + item2.setId(KRandom::random()); + item2.setRemoteId(QStringLiteral("0")); + item2.setParentCollection(collection2); + + job = mStore->moveItem(item1, collection3); + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + MBoxEntry::List tmpEntryList = mbox2.entries(); + QVERIFY(std::equal(tmpEntryList.begin(), tmpEntryList.end(), entryList2.begin(), fullEntryCompare)); + + // test failure of moving from maildir to top level collection + job = mStore->moveItem(item1, mStore->topLevelCollection()); + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + QCOMPARE(QSet::fromList(md1.entryList()), entrySet1); + + // test failure of moving from mbox to top level collection + job = mStore->moveItem(item1, mStore->topLevelCollection()); + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + tmpEntryList = mbox2.entries(); + QVERIFY(std::equal(tmpEntryList.begin(), tmpEntryList.end(), entryList2.begin(), fullEntryCompare)); + + // test failure of moving a non-existent maildir entry + QString remoteId1; + do { + remoteId1 = KRandom::randomString(20); + } while (entrySet1.contains(remoteId1)); + + item1.setRemoteId(remoteId1); + + job = mStore->moveItem(item1, collection2); + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + QCOMPARE(QSet::fromList(md1.entryList()), entrySet1); + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + tmpEntryList = mbox2.entries(); + QVERIFY(std::equal(tmpEntryList.begin(), tmpEntryList.end(), entryList2.begin(), fullEntryCompare)); + + // test failure of moving a non-existent mbox entry + quint64 remoteId2; + do { + remoteId2 = KRandom::random(); + } while (entrySet2.contains(remoteId2)); + + item2.setRemoteId(QString::number(remoteId2)); + + job = mStore->moveItem(item2, collection1); + QVERIFY(!job->exec()); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + + QCOMPARE(QSet::fromList(md1.entryList()), entrySet1); + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + tmpEntryList = mbox2.entries(); + QVERIFY(std::equal(tmpEntryList.begin(), tmpEntryList.end(), entryList2.begin(), fullEntryCompare)); +} + +void ItemMoveTest::testMaildirItem() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection1"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection2"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection5"))); + + KPIM::Maildir topLevelMd(topDir.path(), true); + + KPIM::Maildir md1 = topLevelMd.subFolder(QStringLiteral("collection1")); + QSet entrySet1 = QSet::fromList(md1.entryList()); + QCOMPARE((int)entrySet1.count(), 4); + + QFileInfo fileInfo2(topDir.path(), QStringLiteral("collection2")); + MBox mbox2; + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + MBoxEntry::List entryList2 = mbox2.entries(); + QCOMPARE((int)entryList2.count(), 4); + + KPIM::Maildir md3(topLevelMd.addSubFolder(QStringLiteral("collection3")), false); + QVERIFY(md3.isValid()); + QSet entrySet3 = QSet::fromList(md3.entryList()); + QCOMPARE((int)entrySet3.count(), 0); + + QFileInfo fileInfo4(topDir.path(), QStringLiteral("collection4")); + QFile file4(fileInfo4.absoluteFilePath()); + QVERIFY(file4.open(QIODevice::WriteOnly)); + file4.close(); + fileInfo4.refresh(); + QVERIFY(fileInfo4.exists()); + MBox mbox4; + QVERIFY(mbox4.load(fileInfo4.absoluteFilePath())); + MBoxEntry::List entryList4 = mbox4.entries(); + QCOMPARE((int)entryList4.count(), 0); + + KPIM::Maildir md5 = topLevelMd.subFolder(QStringLiteral("collection5")); + QSet entrySet5 = QSet::fromList(md5.entryList()); + QCOMPARE((int)entrySet5.count(), 4); + + mStore->setPath(topDir.path()); + + // common variables + FileStore::ItemMoveJob *job = 0; + + const QVariant colListVar = QVariant::fromValue(Collection::List()); + QVariant var; + Collection::List collections; + Item movedItem; + MBoxEntry::List entryList; + + // test moving to an empty maildir + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + Collection collection3; + collection3.setName(QStringLiteral("collection3")); + collection3.setRemoteId(QStringLiteral("collection3")); + collection3.setParentCollection(mStore->topLevelCollection()); + + Item item1; + item1.setId(KRandom::random()); + item1.setRemoteId(*entrySet1.cbegin()); + item1.setParentCollection(collection1); + + job = mStore->moveItem(item1, collection3); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + movedItem = job->item(); + QCOMPARE(movedItem.id(), item1.id()); + QCOMPARE(movedItem.parentCollection(), collection3); + + entrySet3 << movedItem.remoteId(); + QCOMPARE(QSet::fromList(md3.entryList()), entrySet3); + entrySet1.remove(item1.remoteId()); + QCOMPARE(QSet::fromList(md1.entryList()), entrySet1); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection1); + + // test moving to a non empty maildir + item1.setRemoteId(*entrySet1.cbegin()); + + Collection collection5; + collection5.setName(QStringLiteral("collection5")); + collection5.setRemoteId(QStringLiteral("collection5")); + collection5.setParentCollection(mStore->topLevelCollection()); + + job = mStore->moveItem(item1, collection5); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + movedItem = job->item(); + QCOMPARE(movedItem.id(), item1.id()); + QCOMPARE(movedItem.parentCollection(), collection5); + + entrySet5 << movedItem.remoteId(); + QCOMPARE(QSet::fromList(md5.entryList()), entrySet5); + entrySet1.remove(item1.remoteId()); + QCOMPARE(QSet::fromList(md1.entryList()), entrySet1); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 2); + QCOMPARE(collections, Collection::List() << collection1 << collection5); + + // test moving to an empty mbox + Collection collection4; + collection4.setName(QStringLiteral("collection4")); + collection4.setRemoteId(QStringLiteral("collection4")); + collection4.setParentCollection(mStore->topLevelCollection()); + + item1.setRemoteId(*entrySet1.cbegin()); + + job = mStore->moveItem(item1, collection4); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + movedItem = job->item(); + QCOMPARE(movedItem.id(), item1.id()); + QCOMPARE(movedItem.parentCollection(), collection4); + + QVERIFY(mbox4.load(mbox4.fileName())); + entryList = mbox4.entries(); + QCOMPARE((int)entryList.count(), 1); + + QCOMPARE(entryList.last().messageOffset(), movedItem.remoteId().toULongLong()); + entrySet1.remove(item1.remoteId()); + QCOMPARE(QSet::fromList(md1.entryList()), entrySet1); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection1); + + // test moving to a non empty mbox + item1.setRemoteId(*entrySet1.cbegin()); + + Collection collection2; + collection2.setName(QStringLiteral("collection2")); + collection2.setRemoteId(QStringLiteral("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + job = mStore->moveItem(item1, collection2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + movedItem = job->item(); + QCOMPARE(movedItem.id(), item1.id()); + QCOMPARE(movedItem.parentCollection(), collection2); + + QVERIFY(mbox2.load(mbox2.fileName())); + entryList = mbox2.entries(); + QCOMPARE((int)entryList.count(), 5); + + QCOMPARE(entryList.last().messageOffset(), movedItem.remoteId().toULongLong()); + entrySet1.remove(item1.remoteId()); + QCOMPARE(QSet::fromList(md1.entryList()), entrySet1); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 2); + QCOMPARE(collections, Collection::List() << collection1 << collection2); +} + +void ItemMoveTest::testMBoxItem() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection1"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection2"))); + QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection5"))); + + QFileInfo fileInfo1(topDir.path(), QStringLiteral("collection1")); + MBox mbox1; + QVERIFY(mbox1.load(fileInfo1.absoluteFilePath())); + MBoxEntry::List entryList1 = mbox1.entries(); + QCOMPARE((int)entryList1.count(), 4); + + KPIM::Maildir topLevelMd(topDir.path(), true); + + KPIM::Maildir md2 = topLevelMd.subFolder(QStringLiteral("collection2")); + QSet entrySet2 = QSet::fromList(md2.entryList()); + QCOMPARE((int)entrySet2.count(), 4); + + KPIM::Maildir md3(topLevelMd.addSubFolder(QStringLiteral("collection3")), false); + QVERIFY(md3.isValid()); + QSet entrySet3 = QSet::fromList(md3.entryList()); + QCOMPARE((int)entrySet3.count(), 0); + + QFileInfo fileInfo4(topDir.path(), QStringLiteral("collection4")); + QFile file4(fileInfo4.absoluteFilePath()); + QVERIFY(file4.open(QIODevice::WriteOnly)); + file4.close(); + fileInfo4.refresh(); + QVERIFY(fileInfo4.exists()); + MBox mbox4; + QVERIFY(mbox4.load(fileInfo4.absoluteFilePath())); + MBoxEntry::List entryList4 = mbox4.entries(); + QCOMPARE((int)entryList4.count(), 0); + + QFileInfo fileInfo5(topDir.path(), QStringLiteral("collection5")); + MBox mbox5; + QVERIFY(mbox5.load(fileInfo5.absoluteFilePath())); + MBoxEntry::List entryList5 = mbox5.entries(); + QCOMPARE((int)entryList5.count(), 4); + + mStore->setPath(topDir.path()); + + // common variables + FileStore::ItemMoveJob *job = 0; + FileStore::StoreCompactJob *compactStore = 0; + + const QVariant colListVar = QVariant::fromValue(Collection::List()); + QVariant var; + Collection::List collections; + Item movedItem; + MBoxEntry::List entryList; + Item::List items; + + // test moving to an empty maildir + Collection collection1; + collection1.setName(QStringLiteral("collection1")); + collection1.setRemoteId(QStringLiteral("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + Collection collection3; + collection3.setName(QStringLiteral("collection3")); + collection3.setRemoteId(QStringLiteral("collection3")); + collection3.setParentCollection(mStore->topLevelCollection()); + + Item item1; + item1.setId(KRandom::random()); + item1.setRemoteId(QString::number(entryList1.first().messageOffset())); + item1.setParentCollection(collection1); + + job = mStore->moveItem(item1, collection3); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + movedItem = job->item(); + QCOMPARE(movedItem.id(), item1.id()); + QCOMPARE(movedItem.parentCollection(), collection3); + + var = job->property("compactStore"); + QVERIFY(var.isValid()); + QCOMPARE(var.type(), QVariant::Bool); + QCOMPARE(var.toBool(), true); + + compactStore = mStore->compactStore(); + QVERIFY(compactStore->exec()); + + items = compactStore->changedItems(); + QCOMPARE((int)items.count(), 3); + + entrySet3 << movedItem.remoteId(); + QCOMPARE(QSet::fromList(md3.entryList()), entrySet3); + + entryList1.removeAt(0); + entryList1[ 0 ] = MBoxEntry(changedOffset(items[ 0 ])); + entryList1[ 1 ] = MBoxEntry(changedOffset(items[ 1 ])); + entryList1[ 2 ] = MBoxEntry(changedOffset(items[ 2 ])); + QVERIFY(mbox1.load(mbox1.fileName())); + QCOMPARE(mbox1.entries(), entryList1); + + // test moving to a non empty mbox + Collection collection5; + collection5.setName(QStringLiteral("collection5")); + collection5.setRemoteId(QStringLiteral("collection5")); + collection5.setParentCollection(mStore->topLevelCollection()); + + job = mStore->moveItem(item1, collection5); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + movedItem = job->item(); + QCOMPARE(movedItem.id(), item1.id()); + QCOMPARE(movedItem.parentCollection(), collection5); + + var = job->property("compactStore"); + QVERIFY(var.isValid()); + QCOMPARE(var.type(), QVariant::Bool); + QCOMPARE(var.toBool(), true); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 2); + QCOMPARE(collections, Collection::List() << collection1 << collection5); + + compactStore = mStore->compactStore(); + QVERIFY(compactStore->exec()); + + items = compactStore->changedItems(); + QCOMPARE((int)items.count(), 2); + + QVERIFY(mbox5.load(mbox5.fileName())); + QCOMPARE(mbox5.entries().count(), entryList5.count() + 1); + QCOMPARE(mbox5.entries().last().messageOffset(), movedItem.remoteId().toULongLong()); + + entryList1.removeAt(0); + entryList1[ 0 ] = MBoxEntry(changedOffset(items[ 0 ])); + entryList1[ 1 ] = MBoxEntry(changedOffset(items[ 1 ])); + QVERIFY(mbox1.load(mbox1.fileName())); + QCOMPARE(mbox1.entries(), entryList1); + + // test moving to an empty mbox + Collection collection4; + collection4.setName(QStringLiteral("collection4")); + collection4.setRemoteId(QStringLiteral("collection4")); + collection4.setParentCollection(mStore->topLevelCollection()); + + job = mStore->moveItem(item1, collection4); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + movedItem = job->item(); + QCOMPARE(movedItem.id(), item1.id()); + QCOMPARE(movedItem.parentCollection(), collection4); + + QVERIFY(mbox4.load(mbox4.fileName())); + entryList = mbox4.entries(); + QCOMPARE((int)entryList.count(), 1); + + QCOMPARE(entryList.last().messageOffset(), movedItem.remoteId().toULongLong()); + + var = job->property("compactStore"); + QVERIFY(var.isValid()); + QCOMPARE(var.type(), QVariant::Bool); + QCOMPARE(var.toBool(), true); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections.first(), collection1); + + compactStore = mStore->compactStore(); + QVERIFY(compactStore->exec()); + + items = compactStore->changedItems(); + QCOMPARE((int)items.count(), 1); + + QCOMPARE(mbox4.entries().count(), entryList4.count() + 1); + QCOMPARE(mbox4.entries().last().messageOffset(), movedItem.remoteId().toULongLong()); + + entryList1.removeAt(0); + entryList1[ 0 ] = MBoxEntry(changedOffset(items[ 0 ])); + QVERIFY(mbox1.load(mbox1.fileName())); + QCOMPARE(mbox1.entries(), entryList1); + + // test moving to a non empty maildir + Collection collection2; + collection2.setName(QStringLiteral("collection2")); + collection2.setRemoteId(QStringLiteral("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + job = mStore->moveItem(item1, collection2); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + movedItem = job->item(); + QCOMPARE(movedItem.id(), item1.id()); + QCOMPARE(movedItem.parentCollection(), collection2); + + QSet entrySet = QSet::fromList(md2.entryList()); + QCOMPARE((int)entrySet.count(), 5); + + QVERIFY(entrySet.contains(movedItem.remoteId())); + + var = job->property("compactStore"); + QVERIFY(var.isValid()); + QCOMPARE(var.type(), QVariant::Bool); + QCOMPARE(var.toBool(), true); + + // check for index preservation + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 2); + QCOMPARE(collections.first(), collection1); + + compactStore = mStore->compactStore(); + QVERIFY(compactStore->exec()); + + items = compactStore->changedItems(); + QCOMPARE((int)items.count(), 0); + + entryList1.removeAt(0); + QVERIFY(mbox1.load(mbox1.fileName())); + const MBoxEntry::List newEntryList = mbox1.entries(); + QVERIFY(std::equal(newEntryList.begin(), newEntryList.end(), entryList1.begin(), fullEntryCompare)); +} + +QTEST_MAIN(ItemMoveTest) + +#include "itemmovetest.moc" + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/storecompacttest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/storecompacttest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/storecompacttest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/storecompacttest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,401 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" + +#include "testdatautil.h" + +#include "filestore/entitycompactchangeattribute.h" +#include "filestore/itemdeletejob.h" +#include "filestore/storecompactjob.h" + +#include + +#include +#include + +#include + +#include +#include +#include +using namespace Akonadi; +using namespace KMBox; + +static Collection::List collectionsFromSpy(QSignalSpy *spy) +{ + Collection::List collections; + + QListIterator > it(*spy); + while (it.hasNext()) { + const QList invocation = it.next(); + Q_ASSERT(invocation.count() == 1); + + collections << invocation.first().value(); + } + + return collections; +} + +static Item::List itemsFromSpy(QSignalSpy *spy) +{ + Item::List items; + + QListIterator > it(*spy); + while (it.hasNext()) { + const QList invocation = it.next(); + Q_ASSERT(invocation.count() == 1); + + items << invocation.first().value(); + } + + return items; +} + +static bool fullEntryCompare(const MBoxEntry &a, const MBoxEntry &b) +{ + return a.messageOffset() == b.messageOffset() && + a.separatorSize() == b.separatorSize() && + a.messageSize() == b.messageSize(); +} + +static quint64 changedOffset(const Item &item) +{ + Q_ASSERT(item.hasAttribute()); + + const QString remoteId = item.attribute()->remoteId(); + Q_ASSERT(!remoteId.isEmpty()); + + bool ok = false; + const quint64 result = remoteId.toULongLong(&ok); + Q_ASSERT(ok); + + return result; +} + +class StoreCompactTest : public QObject +{ + Q_OBJECT + +public: + StoreCompactTest() : QObject(), mStore(0), mDir(0) + { + // for monitoring signals + qRegisterMetaType(); + qRegisterMetaType(); + } + + ~StoreCompactTest() + { + delete mStore; + delete mDir; + } + +private: + MixedMaildirStore *mStore; + QTemporaryDir *mDir; + +private Q_SLOTS: + void init(); + void cleanup(); + void testCompact(); +}; + +void StoreCompactTest::init() +{ + mStore = new MixedMaildirStore; + + mDir = new QTemporaryDir; + QVERIFY(mDir->isValid()); + QVERIFY(QDir(mDir->path()).exists()); +} + +void StoreCompactTest::cleanup() +{ + delete mStore; + mStore = 0; + delete mDir; + mDir = 0; +} + +void StoreCompactTest::testCompact() +{ + QDir topDir(mDir->path()); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox"), topDir.path(), QStringLiteral("collection1"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox"), topDir.path(), QStringLiteral("collection2"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox"), topDir.path(), QStringLiteral("collection3"))); + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox"), topDir.path(), QStringLiteral("collection4"))); + + QFileInfo fileInfo1(topDir.path(), QStringLiteral("collection1")); + MBox mbox1; + QVERIFY(mbox1.load(fileInfo1.absoluteFilePath())); + MBoxEntry::List entryList1 = mbox1.entries(); + QCOMPARE((int)entryList1.count(), 4); + + QFileInfo fileInfo2(topDir.path(), QStringLiteral("collection2")); + MBox mbox2; + QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); + MBoxEntry::List entryList2 = mbox2.entries(); + QCOMPARE((int)entryList2.count(), 4); + + QFileInfo fileInfo3(topDir.path(), QStringLiteral("collection3")); + MBox mbox3; + QVERIFY(mbox3.load(fileInfo3.absoluteFilePath())); + MBoxEntry::List entryList3 = mbox3.entries(); + QCOMPARE((int)entryList3.count(), 4); + + QFileInfo fileInfo4(topDir.path(), QStringLiteral("collection4")); + MBox mbox4; + QVERIFY(mbox4.load(fileInfo4.absoluteFilePath())); + MBoxEntry::List entryList4 = mbox4.entries(); + QCOMPARE((int)entryList4.count(), 4); + + mStore->setPath(topDir.path()); + + // common variables + FileStore::CollectionFetchJob *collectionFetch = 0; + FileStore::ItemDeleteJob *itemDelete = 0; + FileStore::StoreCompactJob *job = 0; + + Collection::List collections; + Item::List items; + + QSignalSpy *collectionSpy = 0; + QSignalSpy *itemSpy = 0; + + MBoxEntry::List entryList; + Collection collection; + FileStore::EntityCompactChangeAttribute *attribute = 0; + + const QVariant colListVar = QVariant::fromValue(Collection::List()); + QVariant var; + + // test compact after delete from the end of an mbox + Collection collection1; + collection1.setName(QLatin1String("collection1")); + collection1.setRemoteId(QLatin1String("collection1")); + collection1.setParentCollection(mStore->topLevelCollection()); + + Item item1; + item1.setRemoteId(QString::number(entryList1.last().messageOffset())); + item1.setParentCollection(collection1); + + itemDelete = mStore->deleteItem(item1); + + QVERIFY(itemDelete->exec()); + + job = mStore->compactStore(); + + collectionSpy = new QSignalSpy(job, SIGNAL(collectionsChanged(Akonadi::Collection::List))); + itemSpy = new QSignalSpy(job, SIGNAL(itemsChanged(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collections = job->changedCollections(); + items = job->changedItems(); + + QCOMPARE(collections.count(), 0); + QCOMPARE(items.count(), 0); + + QCOMPARE(collectionSpy->count(), 0); + QCOMPARE(itemSpy->count(), 0); + + QVERIFY(mbox1.load(mbox1.fileName())); + entryList = mbox1.entries(); + entryList1.pop_back(); + QVERIFY(std::equal(entryList.begin(), entryList.end(), entryList1.begin(), fullEntryCompare)); + + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections, Collection::List() << collection1); + + // test compact after delete from before the end of an mbox + Collection collection2; + collection2.setName(QLatin1String("collection2")); + collection2.setRemoteId(QLatin1String("collection2")); + collection2.setParentCollection(mStore->topLevelCollection()); + + Item item2; + item2.setRemoteId(QString::number(entryList2.first().messageOffset())); + item2.setParentCollection(collection2); + + itemDelete = mStore->deleteItem(item2); + + QVERIFY(itemDelete->exec()); + + job = mStore->compactStore(); + + collectionSpy = new QSignalSpy(job, SIGNAL(collectionsChanged(Akonadi::Collection::List))); + itemSpy = new QSignalSpy(job, SIGNAL(itemsChanged(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collections = job->changedCollections(); + items = job->changedItems(); + + QCOMPARE(collections.count(), 1); + QCOMPARE(items.count(), 3); + + QCOMPARE(collectionSpy->count(), 1); + QCOMPARE(itemSpy->count(), 1); + + QCOMPARE(collectionsFromSpy(collectionSpy), collections); + QCOMPARE(itemsFromSpy(itemSpy), items); + + collection = collections.first(); + QCOMPARE(collection, collection2); + QVERIFY(collection.hasAttribute()); + attribute = collection.attribute(); + QCOMPARE(attribute->remoteRevision().toInt(), collection2.remoteRevision().toInt() + 1); + + QVERIFY(mbox2.load(mbox2.fileName())); + entryList = mbox2.entries(); + + entryList2.pop_front(); + for (int i = 0; i < items.count(); ++i) { + entryList2[ i ] = MBoxEntry(changedOffset(items[ i ])); + } + QCOMPARE(entryList, entryList2); + + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 1); + QCOMPARE(collections, Collection::List() << collection2); + + collectionFetch = mStore->fetchCollections(collection2, FileStore::CollectionFetchJob::Base); + + QVERIFY(collectionFetch->exec()); + + collections = collectionFetch->collections(); + QCOMPARE((int)collections.count(), 1); + + collection = collections.first(); + QCOMPARE(collection, collection2); + QCOMPARE(collection.remoteRevision(), attribute->remoteRevision()); + + // test compact after delete from before the end of more than one mbox + Collection collection3; + collection3.setName(QLatin1String("collection3")); + collection3.setRemoteId(QLatin1String("collection3")); + collection3.setParentCollection(mStore->topLevelCollection()); + + Item item3; + item3.setRemoteId(QString::number(entryList3.first().messageOffset())); + item3.setParentCollection(collection3); + + itemDelete = mStore->deleteItem(item3); + + QVERIFY(itemDelete->exec()); + + Collection collection4; + collection4.setName(QLatin1String("collection4")); + collection4.setRemoteId(QLatin1String("collection4")); + collection4.setParentCollection(mStore->topLevelCollection()); + + Item item4; + item4.setRemoteId(QString::number(entryList3.value(1).messageOffset())); + item4.setParentCollection(collection4); + + itemDelete = mStore->deleteItem(item4); + + QVERIFY(itemDelete->exec()); + + job = mStore->compactStore(); + + collectionSpy = new QSignalSpy(job, SIGNAL(collectionsChanged(Akonadi::Collection::List))); + itemSpy = new QSignalSpy(job, SIGNAL(itemsChanged(Akonadi::Item::List))); + + QVERIFY(job->exec()); + QCOMPARE(job->error(), 0); + + collections = job->changedCollections(); + items = job->changedItems(); + + QCOMPARE(collections.count(), 2); + QCOMPARE(items.count(), 5); + + QCOMPARE(collectionSpy->count(), 2); + QCOMPARE(itemSpy->count(), 2); + + QCOMPARE(collectionsFromSpy(collectionSpy), collections); + QCOMPARE(itemsFromSpy(itemSpy), items); + + QHash compactedCollections; + Q_FOREACH (const Collection &col, collections) { + compactedCollections.insert(col.remoteId(), col); + } + QCOMPARE(compactedCollections.count(), 2); + + QVERIFY(compactedCollections.contains(collection3.remoteId())); + collection = compactedCollections[ collection3.remoteId() ]; + QCOMPARE(collection, collection3); + QVERIFY(collection.hasAttribute()); + attribute = collection.attribute(); + QCOMPARE(attribute->remoteRevision().toInt(), collection3.remoteRevision().toInt() + 1); + + QVERIFY(mbox3.load(mbox3.fileName())); + entryList = mbox3.entries(); + + entryList3.pop_front(); + for (int i = 0; i < entryList3.count(); ++i) { + entryList3[ i ] = MBoxEntry(changedOffset(items.first())); + items.pop_front(); + } + QCOMPARE(entryList, entryList3); + + QVERIFY(compactedCollections.contains(collection4.remoteId())); + collection = compactedCollections[ collection4.remoteId() ]; + QCOMPARE(collection, collection4); + QVERIFY(collection.hasAttribute()); + attribute = collection.attribute(); + QCOMPARE(attribute->remoteRevision().toInt(), collection4.remoteRevision().toInt() + 1); + + QVERIFY(mbox4.load(mbox4.fileName())); + entryList = mbox4.entries(); + + entryList4.removeAt(1); + for (int i = 0; i < items.count(); ++i) { + entryList4[ i + 1 ] = MBoxEntry(changedOffset(items[ i ])); + } + QCOMPARE(entryList, entryList4); + + var = job->property("onDiskIndexInvalidated"); + QVERIFY(var.isValid()); + QCOMPARE(var.userType(), colListVar.userType()); + + collections = var.value(); + QCOMPARE((int)collections.count(), 2); + QCOMPARE(collections, Collection::List() << collection3 << collection4); +} + +QTEST_MAIN(StoreCompactTest) + +#include "storecompacttest.moc" + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/templatemethodstest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/templatemethodstest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/templatemethodstest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/templatemethodstest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,235 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" + +#include "collectioncreatejob.h" +#include "collectiondeletejob.h" +#include "collectionfetchjob.h" +#include "collectionmodifyjob.h" +#include "collectionmovejob.h" +#include "itemcreatejob.h" +#include "itemdeletejob.h" +#include "itemfetchjob.h" +#include "itemmodifyjob.h" +#include "itemmovejob.h" +#include "sessionimpls_p.h" +#include "storecompactjob.h" + +#include +#include + +#include + +#include +#include + +#include + +using namespace Akonadi; + +class TestStore : public MixedMaildirStore +{ + Q_OBJECT + +public: + TestStore() : mLastCheckedJob(0), mErrorCode(0) {} + +public: + Collection mTopLevelCollection; + + mutable FileStore::Job *mLastCheckedJob; + mutable int mErrorCode; + mutable QString mErrorText; + +protected: + void setTopLevelCollection(const Collection &collection) + { + MixedMaildirStore::setTopLevelCollection(collection); + } + + void checkCollectionMove(FileStore::CollectionMoveJob *job, int &errorCode, QString &errorText) const + { + MixedMaildirStore::checkCollectionMove(job, errorCode, errorText); + + mLastCheckedJob = job; + mErrorCode = errorCode; + mErrorText = errorText; + } + + void checkItemCreate(FileStore::ItemCreateJob *job, int &errorCode, QString &errorText) const + { + MixedMaildirStore::checkItemCreate(job, errorCode, errorText); + + mLastCheckedJob = job; + mErrorCode = errorCode; + mErrorText = errorText; + } +}; + +class TemplateMethodsTest : public QObject +{ + Q_OBJECT + +public: + TemplateMethodsTest() : QObject(), mStore(0) {} + ~TemplateMethodsTest() + { + delete mStore; + } + +private: + QTemporaryDir mDir; + TestStore *mStore; + +private Q_SLOTS: + void init(); + void testSetTopLevelCollection(); + void testMoveCollection(); + void testCreateItem(); +}; + +void TemplateMethodsTest::init() +{ + delete mStore; + mStore = new TestStore; + QVERIFY(mDir.isValid()); + QVERIFY(QDir(mDir.path()).exists()); +} + +void TemplateMethodsTest::testSetTopLevelCollection() +{ + const QString file = KRandom::randomString(10); + const QString path = mDir.path() + file; + + mStore->setPath(path); + + // check the adjustments on the top level collection + const Collection collection = mStore->topLevelCollection(); + QCOMPARE(collection.contentMimeTypes(), QStringList() << Collection::mimeType()); + QCOMPARE(collection.rights(), Collection::CanCreateCollection | + Collection::CanChangeCollection | + Collection::CanDeleteCollection); + const CachePolicy cachePolicy = collection.cachePolicy(); + QVERIFY(!cachePolicy.inheritFromParent()); + QCOMPARE(cachePolicy.localParts(), QStringList() << MessagePart::Envelope); + QVERIFY(cachePolicy.syncOnDemand()); +} + +void TemplateMethodsTest::testMoveCollection() +{ + mStore->setPath(mDir.path()); + + FileStore::CollectionMoveJob *job = 0; + + // test moving into itself + Collection collection(KRandom::random()); + collection.setParentCollection(mStore->topLevelCollection()); + collection.setRemoteId("collection"); + job = mStore->moveCollection(collection, collection); + QVERIFY(job != 0); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(mStore->mErrorCode, job->error()); + QCOMPARE(mStore->mErrorText, job->errorText()); + + QVERIFY(!job->exec()); + + // test moving into child + Collection childCollection(collection.id() + 1); + childCollection.setParentCollection(collection); + childCollection.setRemoteId("child"); + job = mStore->moveCollection(collection, childCollection); + QVERIFY(job != 0); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(mStore->mErrorCode, job->error()); + QCOMPARE(mStore->mErrorText, job->errorText()); + + QVERIFY(!job->exec()); + + // test moving into grand child child + Collection grandChildCollection(collection.id() + 2); + grandChildCollection.setParentCollection(childCollection); + grandChildCollection.setRemoteId("grandchild"); + job = mStore->moveCollection(collection, grandChildCollection); + QVERIFY(job != 0); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(mStore->mErrorCode, job->error()); + QCOMPARE(mStore->mErrorText, job->errorText()); + + QVERIFY(!job->exec()); + + // test moving into unrelated collection + Collection otherCollection(collection.id() + KRandom::random()); + otherCollection.setParentCollection(mStore->topLevelCollection()); + otherCollection.setRemoteId("other"); + job = mStore->moveCollection(collection, otherCollection); + QVERIFY(job != 0); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + QCOMPARE(mStore->mLastCheckedJob, job); + + // collections don't exist in the store, so processing still fails + QVERIFY(!job->exec()); +} + +void TemplateMethodsTest::testCreateItem() +{ + mStore->setPath(mDir.path()); + + Collection collection(KRandom::random()); + collection.setParentCollection(mStore->topLevelCollection()); + collection.setRemoteId("collection"); + + FileStore::ItemCreateJob *job = 0; + + // test item without payload + Item item(KMime::Message::mimeType()); + job = mStore->createItem(item, collection); + QVERIFY(job != 0); + QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(mStore->mErrorCode, job->error()); + QCOMPARE(mStore->mErrorText, job->errorText()); + + QVERIFY(!job->exec()); + + // test item with payload + item.setPayloadFromData("Subject: dummy payload\n\nwith some content"); + job = mStore->createItem(item, collection); + QVERIFY(job != 0); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + QCOMPARE(mStore->mLastCheckedJob, job); + + // collections don't exist in the store, so processing still fails + QVERIFY(!job->exec()); +} + +QTEST_MAIN(TemplateMethodsTest) + +#include "templatemethodstest.moc" + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/testdata.qrc kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/testdata.qrc --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/testdata.qrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/testdata.qrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,31 @@ + + + + data/mbox + data/.mbox.index + + data/mbox-tagged + data/.mbox-tagged.index + + data/mbox-unpurged + data/.mbox-unpurged.index + + data/maildir/cur/1279979618.4595.CStza_2,S + data/maildir/cur/1279979618.4595.pY5ny + data/maildir/cur/1279979617.4595.bwXSm + data/maildir/cur/1279979618.4595.DUl0I_2,S + data/.maildir.index + + data/maildir-tagged/cur/1279982188.18722.6qZsA_2,S + data/maildir-tagged/cur/1279982188.18722.Xdz3R_2,S + data/maildir-tagged/cur/1279982188.18722.f0l49_2,S + data/maildir-tagged/cur/1279982188.18722.kwx1b_2,S + data/.maildir-tagged.index + + data/dimap/cur/1279980064.4595.qs6V9_2,S + data/dimap/cur/1279980064.4595.LUBVK + data/dimap/cur/1279980064.4595.g8PCJ + data/dimap/cur/1279980064.4595.RTmAd_2,S + data/.dimap.index + + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/testdatatest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/testdatatest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/testdatatest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/testdatatest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,106 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.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 "testdatautil.h" + +#include + +#include +#include + +class TestDataTest : public QObject +{ + Q_OBJECT +public: + TestDataTest() {} + +private Q_SLOTS: + void testResources(); + void testInstall(); +}; + +void TestDataTest::testResources() +{ + const QStringList testDataNames = TestDataUtil::testDataNames(); + QCOMPARE(testDataNames, QStringList() << QStringLiteral("dimap") + << QStringLiteral("maildir") + << QStringLiteral("maildir-tagged") + << QStringLiteral("mbox") + << QStringLiteral("mbox-tagged") + << QStringLiteral("mbox-unpurged")); + + Q_FOREACH (const QString testDataName, testDataNames) { + if (testDataName.startsWith(QLatin1String("mbox"))) { + QVERIFY(TestDataUtil::folderType(testDataName) == TestDataUtil::MBoxFolder); + } else { + QVERIFY(TestDataUtil::folderType(testDataName) == TestDataUtil::MaildirFolder); + } + } + + // TODO check contents? +} + +void TestDataTest::testInstall() +{ + QTemporaryDir dir; + QDir installDir(dir.path()); + QDir curDir; + + const QString indexFilePattern = QLatin1String(".%1.index"); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox"), dir.path(), QStringLiteral("mbox1"))); + QVERIFY(installDir.exists(QLatin1String("mbox1"))); + QVERIFY(installDir.exists(indexFilePattern.arg(QLatin1String("mbox1")))); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("mbox-tagged"), dir.path(), QStringLiteral("mbox2"))); + QVERIFY(installDir.exists(QLatin1String("mbox2"))); + QVERIFY(installDir.exists(indexFilePattern.arg(QLatin1String("mbox2")))); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir"), dir.path(), QStringLiteral("md1"))); + QVERIFY(installDir.exists(QLatin1String("md1"))); + QVERIFY(installDir.exists(QLatin1String("md1/new"))); + QVERIFY(installDir.exists(QLatin1String("md1/cur"))); + QVERIFY(installDir.exists(QLatin1String("md1/tmp"))); + QVERIFY(installDir.exists(indexFilePattern.arg(QLatin1String("md1")))); + + curDir = installDir; + curDir.cd(QLatin1String("md1")); + curDir.cd(QLatin1String("cur")); + curDir.setFilter(QDir::Files); + QCOMPARE((int)curDir.count(), 4); + + QVERIFY(TestDataUtil::installFolder(QLatin1String("maildir-tagged"), dir.path(), QStringLiteral("md2"))); + QVERIFY(installDir.exists(QLatin1String("md2"))); + QVERIFY(installDir.exists(QLatin1String("md2/new"))); + QVERIFY(installDir.exists(QLatin1String("md2/cur"))); + QVERIFY(installDir.exists(QLatin1String("md2/tmp"))); + QVERIFY(installDir.exists(indexFilePattern.arg(QLatin1String("md2")))); + + curDir = installDir; + curDir.cd(QLatin1String("md2")); + curDir.cd(QLatin1String("cur")); + curDir.setFilter(QDir::Files); + QCOMPARE((int)curDir.count(), 4); +} + +#include "testdatatest.moc" + +QTEST_MAIN(TestDataTest) + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/testdatautil.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/testdatautil.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/testdatautil.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/testdatautil.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,201 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.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 "testdatautil.h" + +#include "mixedmaildirresource_debug.h" + +#include +#include + +using namespace TestDataUtil; + +// use this instead of QFile::copy() because we want overwrite in case it exists +static bool copyFile(const QString &sourceFileName, const QString &targetFileName) +{ + QFile sourceFile(sourceFileName); + QFile targetFile(targetFileName); + + if (!sourceFile.open(QIODevice::ReadOnly)) { + qCritical() << "Cannot open source file" << sourceFileName; + return false; + } + + if (!targetFile.open(QIODevice::WriteOnly)) { + qCritical() << "Cannot open target file" << targetFileName; + return false; + } + + return targetFile.write(sourceFile.readAll()) != -1; +} + +static bool copyFiles(const QDir &sourceDir, const QDir &targetDir) +{ + const QStringList files = sourceDir.entryList(QStringList(), QDir::Files); + Q_FOREACH (const QString &file, files) { + const QFileInfo sourceFileInfo(sourceDir, file); + const QFileInfo targetFileInfo(targetDir, file); + if (!copyFile(sourceFileInfo.absoluteFilePath(), targetFileInfo.absoluteFilePath())) { + qCritical() << "Failed to copy" << sourceFileInfo.absoluteFilePath() + << "to" << targetFileInfo.absoluteFilePath(); + return false; + } + } + + return true; +} + +FolderType TestDataUtil::folderType(const QString &testDataName) +{ + const QDir dir(QLatin1String(":/data")); + const QString indexFilePattern = QLatin1String(".%1.index"); + + if (!dir.exists(testDataName) || !dir.exists(indexFilePattern.arg(testDataName))) { + return InvalidFolder; + } + + const QFileInfo fileInfo(dir, testDataName); + return (fileInfo.isDir() ? MaildirFolder : MBoxFolder); +} + +QStringList TestDataUtil::testDataNames() +{ + const QDir dir(QLatin1String(":/data")); + const QFileInfoList dirEntries = dir.entryInfoList(); + + const QString indexFilePattern = QLatin1String(".%1.index"); + + QStringList result; + Q_FOREACH (const QFileInfo &fileInfo, dirEntries) { + if (dir.exists(indexFilePattern.arg(fileInfo.fileName()))) { + result << fileInfo.fileName(); + } + } + + result.sort(); + return result; +} + +bool TestDataUtil::installFolder(const QString &testDataName, const QString &installPath, const QString &folderName) +{ + const FolderType type = TestDataUtil::folderType(testDataName); + if (type == InvalidFolder) { + qCritical() << "testDataName" << testDataName << "is not a valid mail folder type"; + return false; + } + + if (!QDir::current().mkpath(installPath)) { + qCritical() << "Couldn't create installPath" << installPath; + return false; + } + + const QDir installDir(installPath); + const QFileInfo installFileInfo(installDir, folderName); + if (installDir.exists(folderName)) { + switch (type) { + case MaildirFolder: + if (!installFileInfo.isDir()) { + qCritical() << "Target file name" << folderName << "already exists but is not a directory"; + return false; + } + break; + + case MBoxFolder: + if (!installFileInfo.isFile()) { + qCritical() << "Target file name" << folderName << "already exists but is not a directory"; + return false; + } + break; + + default: + // already handled at beginning + Q_ASSERT(false); + return false; + } + } + + const QDir testDataDir(QLatin1String(":/data")); + + switch (type) { + case MaildirFolder: { + const QString subPathPattern = QLatin1String("%1/%2"); + if (!installDir.mkpath(subPathPattern.arg(folderName, QStringLiteral("new"))) || + !installDir.mkpath(subPathPattern.arg(folderName, QStringLiteral("cur"))) || + !installDir.mkpath(subPathPattern.arg(folderName, QStringLiteral("tmp")))) { + qCritical() << "Couldn't create maildir directory structure"; + return false; + } + + QDir sourceDir = testDataDir; + QDir targetDir = installDir; + + sourceDir.cd(testDataName); + targetDir.cd(folderName); + + if (sourceDir.cd(QLatin1String("new"))) { + targetDir.cd(QLatin1String("new")); + if (!copyFiles(sourceDir, targetDir)) { + return false; + } + sourceDir.cdUp(); + targetDir.cdUp(); + } + + if (sourceDir.cd(QLatin1String("cur"))) { + targetDir.cd(QLatin1String("cur")); + if (!copyFiles(sourceDir, targetDir)) { + return false; + } + sourceDir.cdUp(); + targetDir.cdUp(); + } + + if (sourceDir.cd(QLatin1String("tmp"))) { + targetDir.cd(QLatin1String("tmp")); + if (!copyFiles(sourceDir, targetDir)) { + return false; + } + } + break; + } + + case MBoxFolder: { + const QFileInfo mboxFileInfo(testDataDir, testDataName); + if (!copyFile(mboxFileInfo.absoluteFilePath(), installFileInfo.absoluteFilePath())) { + qCritical() << "Failed to copy" << mboxFileInfo.absoluteFilePath() + << "to" << installFileInfo.absoluteFilePath(); + return false; + } + break; + } + + default: + // already handled at beginning + Q_ASSERT(false); + return false; + } + + const QString indexFilePattern = QLatin1String(".%1.index"); + const QFileInfo indexFileInfo(testDataDir, indexFilePattern.arg(testDataName)); + const QFileInfo indexInstallFileInfo(installDir, indexFilePattern.arg(folderName)); + + return copyFile(indexFileInfo.absoluteFilePath(), indexInstallFileInfo.absoluteFilePath()); +} + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/testdatautil.h kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/testdatautil.h --- kdepim-runtime-4.14.6/resources/mixedmaildir/autotests/testdatautil.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/autotests/testdatautil.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,43 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.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 TESTDATAUTIL_H +#define TESTDATAUTIL_H + +class QString; +class QStringList; + +namespace TestDataUtil +{ +enum FolderType { + InvalidFolder, + MaildirFolder, + MBoxFolder +}; + +FolderType folderType(const QString &testDataName); + +QStringList testDataNames(); + +bool installFolder(const QString &testDataName, const QString &installPath, const QString &folderName); +} + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/CMakeLists.txt kdepim-runtime-15.08.0/resources/mixedmaildir/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/mixedmaildir/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -7,41 +7,39 @@ ${kdepim-runtime_SOURCE_DIR}/resources/maildir ${kdepim-runtime_SOURCE_DIR}/resources/mbox ${CMAKE_CURRENT_SOURCE_DIR}/kmindexreader - ${QT_QTDBUS_INCLUDE_DIR} - ${Boost_INCLUDE_DIR} ) -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_mixedmaildir_resource\") add_subdirectory(kmindexreader) -add_definitions(-DKDE_DEFAULT_DEBUG_AREA=5254) # TODO get our own debug area ########### next target ############### set( mixedmaildirresource_SRCS + mixedmaildirresource_debug.cpp compactchangehelper.cpp configdialog.cpp mixedmaildirresource.cpp mixedmaildirstore.cpp retrieveitemsjob.cpp - ../shared/createandsettagsjob.cpp + mixedmaildir_debug.cpp ) -install( FILES mixedmaildirresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) +install( FILES mixedmaildirresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) -kde4_add_ui_files(mixedmaildirresource_SRCS settings.ui) +ki18n_wrap_ui(mixedmaildirresource_SRCS settings.ui) -kde4_add_kcfg_files(mixedmaildirresource_SRCS settings.kcfgc) +kconfig_add_kcfg_files(mixedmaildirresource_SRCS settings.kcfgc) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/mixedmaildirresource.kcfg org.kde.Akonadi.MixedMaildir.Settings) -qt4_add_dbus_adaptor(mixedmaildirresource_SRCS +qt5_add_dbus_adaptor(mixedmaildirresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.MixedMaildir.Settings.xml settings.h Settings ) -kde4_add_executable(akonadi_mixedmaildir_resource ${mixedmaildirresource_SRCS}) +add_executable(akonadi_mixedmaildir_resource ${mixedmaildirresource_SRCS}) -if (Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_mixedmaildir_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) set_target_properties(akonadi_mixedmaildir_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.MixedMaildir") set_target_properties(akonadi_mixedmaildir_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi MixedMaildir Resource") @@ -51,20 +49,21 @@ kmindexreader maildir akonadi-filestore - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_AKONADI_KMIME_LIBS} - ${QT_QTDBUS_LIBRARY} - ${KDE4_KIO_LIBS} - ${KDEPIMLIBS_KMBOX_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${KDEPIMLIBS_KPIMUTILS_LIBS} + KF5::AkonadiCore + KF5::AkonadiMime + KF5::KIOCore + KF5::Mbox + KF5::Mime + KF5::AkonadiAgentBase + KF5::KDELibs4Support + akonadi-singlefileresource ) -install(TARGETS akonadi_mixedmaildir_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(TARGETS akonadi_mixedmaildir_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.MixedMaildir.Settings.xml - DESTINATION ${DBUS_INTERFACES_INSTALL_DIR}) + DESTINATION ${KDE_INSTALL_DBUSINTERFACEDIR}) # unit tests -if (KDE4_BUILD_TESTS) - add_subdirectory( tests ) +if (BUILD_TESTING) + add_subdirectory( autotests ) endif () diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/compactchangehelper.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/compactchangehelper.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/compactchangehelper.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/compactchangehelper.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,15 +19,15 @@ */ #include "compactchangehelper.h" - +#include "mixedmaildirresource_debug.h" #include "filestore/entitycompactchangeattribute.h" -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include #include @@ -39,200 +39,198 @@ typedef QMap RevisionChangeMap; typedef QMap CollectionRevisionMap; -struct UpdateBatch -{ - QQueue items; - Collection collection; +struct UpdateBatch { + QQueue items; + Collection collection; }; class CompactChangeHelper::Private { - CompactChangeHelper *const q; + CompactChangeHelper *const q; - public: - explicit Private( CompactChangeHelper *parent ) : q( parent ), mSession( 0 ) +public: + explicit Private(CompactChangeHelper *parent) : q(parent), mSession(Q_NULLPTR) { } - public: +public: Session *mSession; CollectionRevisionMap mChangesByCollection; QQueue mPendingUpdates; UpdateBatch mCurrentUpdate; - public: // slots +public: // slots void processNextBatch(); void processNextItem(); - void itemFetchResult( KJob *job ); + void itemFetchResult(KJob *job); }; void CompactChangeHelper::Private::processNextBatch() { - //kDebug() << "pendingUpdates.count=" << mPendingUpdates.count(); - if ( mPendingUpdates.isEmpty() ) { - return; - } + //qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "pendingUpdates.count=" << mPendingUpdates.count(); + if (mPendingUpdates.isEmpty()) { + return; + } - mCurrentUpdate = mPendingUpdates.dequeue(); + mCurrentUpdate = mPendingUpdates.dequeue(); - processNextItem(); + processNextItem(); } void CompactChangeHelper::Private::processNextItem() { - //kDebug() << "mCurrentUpdate.items.count=" << mCurrentUpdate.items.count(); - if ( mCurrentUpdate.items.isEmpty() ) { - CollectionModifyJob *job = new CollectionModifyJob( mCurrentUpdate.collection, mSession ); - QObject::connect( job, SIGNAL(result(KJob*)), q, SLOT(processNextBatch()) ); - return; - } + //qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "mCurrentUpdate.items.count=" << mCurrentUpdate.items.count(); + if (mCurrentUpdate.items.isEmpty()) { + CollectionModifyJob *job = new CollectionModifyJob(mCurrentUpdate.collection, mSession); + QObject::connect(job, SIGNAL(result(KJob*)), q, SLOT(processNextBatch())); + return; + } - const Item nextItem = mCurrentUpdate.items.dequeue(); + const Item nextItem = mCurrentUpdate.items.dequeue(); - Item item; - item.setRemoteId( nextItem.remoteId() ); + Item item; + item.setRemoteId(nextItem.remoteId()); - ItemFetchJob *job = new ItemFetchJob( item ); - job->setProperty( "oldRemoteId", item.remoteId() ); - job->setProperty( "newRemoteId", nextItem.attribute()->remoteId() ); - QObject::connect( job, SIGNAL(result(KJob*)), q, SLOT(itemFetchResult(KJob*)) ); + ItemFetchJob *job = new ItemFetchJob(item); + job->setProperty("oldRemoteId", item.remoteId()); + job->setProperty("newRemoteId", nextItem.attribute()->remoteId()); + QObject::connect(job, SIGNAL(result(KJob*)), q, SLOT(itemFetchResult(KJob*))); } -void CompactChangeHelper::Private::itemFetchResult( KJob *job ) +void CompactChangeHelper::Private::itemFetchResult(KJob *job) { - ItemFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob != 0 ); + ItemFetchJob *fetchJob = qobject_cast(job); + Q_ASSERT(fetchJob != 0); - const QString oldRemoteId = fetchJob->property( "oldRemoteId" ).value(); - Q_ASSERT( !oldRemoteId.isEmpty() ); + const QString oldRemoteId = fetchJob->property("oldRemoteId").value(); + Q_ASSERT(!oldRemoteId.isEmpty()); - const QString newRemoteId = fetchJob->property( "newRemoteId" ).value(); - Q_ASSERT( !newRemoteId.isEmpty() ); + const QString newRemoteId = fetchJob->property("newRemoteId").value(); + Q_ASSERT(!newRemoteId.isEmpty()); - if ( fetchJob->error() != 0 ) { - kError() << "Item fetch for remoteId=" << oldRemoteId - << "new remoteId=" << newRemoteId << "failed:" << fetchJob->errorString(); - processNextItem(); - return; - } + if (fetchJob->error() != 0) { + //qCCritical(MIXEDMAILDIRRESOURCE_LOG) << "Item fetch for remoteId=" << oldRemoteId + // << "new remoteId=" << newRemoteId << "failed:" << fetchJob->errorString(); + processNextItem(); + return; + } - // since we only need the item to modify its remote ID, we don't care - // if it does not exist (anymore) - if ( fetchJob->items().isEmpty() ) { - processNextItem(); - return; - } + // since we only need the item to modify its remote ID, we don't care + // if it does not exist (anymore) + if (fetchJob->items().isEmpty()) { + processNextItem(); + return; + } - const Item item = fetchJob->items().first(); + const Item item = fetchJob->items().at(0); - Item updatedItem( item ); - updatedItem.setRemoteId( newRemoteId ); + Item updatedItem(item); + updatedItem.setRemoteId(newRemoteId); - ItemModifyJob *modifyJob = new ItemModifyJob( updatedItem ); - QObject::connect( modifyJob, SIGNAL(result(KJob*)), q, SLOT(processNextItem()) ); + ItemModifyJob *modifyJob = new ItemModifyJob(updatedItem); + QObject::connect(modifyJob, SIGNAL(result(KJob*)), q, SLOT(processNextItem())); } -CompactChangeHelper::CompactChangeHelper( const QByteArray &sessionId, QObject *parent ) - : QObject( parent ), d( new Private( this ) ) +CompactChangeHelper::CompactChangeHelper(const QByteArray &sessionId, QObject *parent) + : QObject(parent), d(new Private(this)) { - d->mSession = new Session( sessionId, this ); + d->mSession = new Session(sessionId, this); } CompactChangeHelper::~CompactChangeHelper() { - delete d; + delete d; } -void CompactChangeHelper::addChangedItems( const Item::List &items ) +void CompactChangeHelper::addChangedItems(const Item::List &items) { - if ( items.isEmpty() ) { - return; - } - - kDebug() << "items.count=" << items.count() - << "pendingUpdates.count=" << d->mPendingUpdates.count(); - UpdateBatch updateBatch; - - Q_FOREACH( const Item &item, items ) { - const Collection collection = item.parentCollection(); - const qint64 revision = collection.remoteRevision().toLongLong(); + if (items.isEmpty()) { + return; + } - RevisionChangeMap &changesByRevision = d->mChangesByCollection[ collection.id() ]; - OldIdItemMap &changes = changesByRevision[ revision ]; - changes.insert( item.remoteId(), item ); + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "items.count=" << items.count() + << "pendingUpdates.count=" << d->mPendingUpdates.count(); + UpdateBatch updateBatch; + + Q_FOREACH (const Item &item, items) { + const Collection collection = item.parentCollection(); + const qint64 revision = collection.remoteRevision().toLongLong(); + + RevisionChangeMap &changesByRevision = d->mChangesByCollection[ collection.id() ]; + OldIdItemMap &changes = changesByRevision[ revision ]; + changes.insert(item.remoteId(), item); + + if (!updateBatch.collection.isValid()) { + updateBatch.collection = collection; + } else if (updateBatch.collection != collection) { + d->mPendingUpdates << updateBatch; + updateBatch.items.clear(); + updateBatch.collection = collection; + } - if ( !updateBatch.collection.isValid() ) { - updateBatch.collection = collection; - } else if ( updateBatch.collection != collection ) { - d->mPendingUpdates << updateBatch; - updateBatch.items.clear(); - updateBatch.collection = collection; + updateBatch.items << item; } - updateBatch.items << item; - } - - if ( updateBatch.collection.isValid() ) { - d->mPendingUpdates << updateBatch; - } + if (updateBatch.collection.isValid()) { + d->mPendingUpdates << updateBatch; + } - QMetaObject::invokeMethod( this, "processNextBatch", Qt::QueuedConnection ); + QMetaObject::invokeMethod(this, "processNextBatch", Qt::QueuedConnection); } -QString CompactChangeHelper::currentRemoteId( const Item &item ) const +QString CompactChangeHelper::currentRemoteId(const Item &item) const { - const Collection collection = item.parentCollection(); - const qint64 revision = collection.remoteRevision().toLongLong(); + const Collection collection = item.parentCollection(); + const qint64 revision = collection.remoteRevision().toLongLong(); - QString remoteId = item.remoteId(); + QString remoteId = item.remoteId(); - const CollectionRevisionMap::const_iterator colIt = d->mChangesByCollection.constFind( collection.id() ); - if ( colIt != d->mChangesByCollection.constEnd() ) { - // find revision and iterate until the highest available one - RevisionChangeMap::const_iterator revIt = colIt->constFind( revision ); - for ( ; revIt != colIt->constEnd(); ++revIt ) { - const OldIdItemMap::const_iterator idIt = revIt->constFind( remoteId ); - if ( idIt != revIt->constEnd() ) { - remoteId = idIt.value().attribute()->remoteId(); - } else { - break; - } + const CollectionRevisionMap::const_iterator colIt = d->mChangesByCollection.constFind(collection.id()); + if (colIt != d->mChangesByCollection.constEnd()) { + // find revision and iterate until the highest available one + RevisionChangeMap::const_iterator revIt = colIt->constFind(revision); + for (; revIt != colIt->constEnd(); ++revIt) { + const OldIdItemMap::const_iterator idIt = revIt->constFind(remoteId); + if (idIt != revIt->constEnd()) { + remoteId = idIt.value().attribute()->remoteId(); + } else { + break; + } + } } - } - if ( item.remoteId() != remoteId ) { - kDebug() << "item (id=" << item.id() << "remoteId=" << item.remoteId() - << "), col(id=" << collection.id() << ", name=" << collection.name() - << ", revision=" << revision << ") in compact change set (revisions=" - << colIt->keys() << ": current remoteId=" << remoteId; - } + if (item.remoteId() != remoteId) { + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "item (id=" << item.id() << "remoteId=" << item.remoteId() + << "), col(id=" << collection.id() << ", name=" << collection.name() + << ", revision=" << revision << ") in compact change set (revisions=" + << colIt->keys() << ": current remoteId=" << remoteId; + } - return remoteId; + return remoteId; } -void CompactChangeHelper::checkCollectionChanged( const Collection &collection ) +void CompactChangeHelper::checkCollectionChanged(const Collection &collection) { - const qint64 revision = collection.remoteRevision().toLongLong(); - //kDebug() << "col.id=" << collection.id() << ", remoteId=" << collection.remoteId() - // << "revision=" << revision; - - const CollectionRevisionMap::iterator colIt = d->mChangesByCollection.find( collection.id() ); - if ( colIt != d->mChangesByCollection.end() ) { - kDebug() << "matching change map found with" << colIt->count() << "entries"; - // remove all revisions until the seen one appears - RevisionChangeMap::iterator revIt = colIt->begin(); - while ( revIt != colIt->end() && revIt.key() <= revision ) { - kDebug() << "removing entry for revision" << revIt.key(); - revIt = colIt->erase( revIt ); - } + const qint64 revision = collection.remoteRevision().toLongLong(); + //qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "col.id=" << collection.id() << ", remoteId=" << collection.remoteId() + // << "revision=" << revision; - if ( revIt == colIt->end() ) { - kDebug() << "all change maps gone"; - d->mChangesByCollection.erase( colIt ); + const CollectionRevisionMap::iterator colIt = d->mChangesByCollection.find(collection.id()); + if (colIt != d->mChangesByCollection.end()) { + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "matching change map found with" << colIt->count() << "entries"; + // remove all revisions until the seen one appears + RevisionChangeMap::iterator revIt = colIt->begin(); + while (revIt != colIt->end() && revIt.key() <= revision) { + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "removing entry for revision" << revIt.key(); + revIt = colIt->erase(revIt); + } + + if (revIt == colIt->end()) { + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "all change maps gone"; + d->mChangesByCollection.erase(colIt); + } } - } } #include "moc_compactchangehelper.cpp" -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/compactchangehelper.h kdepim-runtime-15.08.0/resources/mixedmaildir/compactchangehelper.h --- kdepim-runtime-4.14.6/resources/mixedmaildir/compactchangehelper.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/compactchangehelper.h 2015-08-10 21:01:02.000000000 +0000 @@ -25,37 +25,37 @@ template class QList; -namespace Akonadi { - class Collection; - class Item; +namespace Akonadi +{ +class Collection; +class Item; - typedef QList ItemList; +typedef QVector ItemList; } class CompactChangeHelper : public QObject { - Q_OBJECT + Q_OBJECT - public: - explicit CompactChangeHelper( const QByteArray &sessionId, QObject *parent = 0 ); +public: + explicit CompactChangeHelper(const QByteArray &sessionId, QObject *parent = Q_NULLPTR); ~CompactChangeHelper(); - void addChangedItems( const Akonadi::ItemList &items ); + void addChangedItems(const Akonadi::ItemList &items); - QString currentRemoteId( const Akonadi::Item &item ) const; + QString currentRemoteId(const Akonadi::Item &item) const; - void checkCollectionChanged( const Akonadi::Collection &collection ); + void checkCollectionChanged(const Akonadi::Collection &collection); - private: +private: class Private; Private *const d; - Q_PRIVATE_SLOT( d, void processNextBatch() ) - Q_PRIVATE_SLOT( d, void processNextItem() ) - Q_PRIVATE_SLOT( d, void itemFetchResult( KJob* ) ) + Q_PRIVATE_SLOT(d, void processNextBatch()) + Q_PRIVATE_SLOT(d, void processNextItem()) + Q_PRIVATE_SLOT(d, void itemFetchResult(KJob *)) }; #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/configdialog.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/configdialog.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/configdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/configdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -25,69 +25,82 @@ #include #include #include - +#include +#include using KPIM::Maildir; -ConfigDialog::ConfigDialog(QWidget * parent) : - KDialog( parent ), - mToplevelIsContainer( false ) +ConfigDialog::ConfigDialog(QWidget *parent) : + QDialog(parent), + mToplevelIsContainer(false) { - setCaption( i18n( "Select a KMail Mail folder" ) ); - ui.setupUi( mainWidget() ); - mManager = new KConfigDialogManager( this, Settings::self() ); - mManager->updateWidgets(); - ui.kcfg_Path->setMode( KFile::Directory | KFile::ExistingOnly ); - ui.kcfg_Path->setUrl( KUrl( Settings::self()->path() ) ); - - connect( this, SIGNAL(okClicked()), SLOT(save()) ); - connect( ui.kcfg_Path->lineEdit(), SIGNAL(textChanged(QString)), SLOT(checkPath()) ); - ui.kcfg_Path->lineEdit()->setFocus(); - checkPath(); + setWindowTitle(i18n("Select a KMail Mail folder")); + QWidget *mainWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); + ui.setupUi(mainWidget); + mManager = new KConfigDialogManager(this, Settings::self()); + mManager->updateWidgets(); + ui.kcfg_Path->setMode(KFile::Directory | KFile::ExistingOnly); + ui.kcfg_Path->setUrl(QUrl::fromLocalFile(Settings::self()->path())); + + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + mainLayout->addWidget(buttonBox); + mOkButton = buttonBox->button(QDialogButtonBox::Ok); + mOkButton->setDefault(true); + mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &ConfigDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &ConfigDialog::reject); + + connect(mOkButton, &QPushButton::clicked, this, &ConfigDialog::save); + connect(ui.kcfg_Path->lineEdit(), SIGNAL(textChanged(QString)), SLOT(checkPath())); + ui.kcfg_Path->lineEdit()->setFocus(); + checkPath(); } void ConfigDialog::checkPath() { - if ( ui.kcfg_Path->url().isEmpty() ) { - ui.statusLabel->setText( i18n( "The selected path is empty.") ); - enableButton( Ok, false); - return; - } - bool ok = false; - mToplevelIsContainer = false; - QDir d( ui.kcfg_Path->url().toLocalFile() ); - - if ( d.exists() ) { - Maildir md( d.path() ); - if ( !md.isValid() ) { - Maildir md2( d.path(), true ); - if ( md2.isValid() ) { - ui.statusLabel->setText( i18n( "The selected path contains valid Maildir folders." ) ); - mToplevelIsContainer = true; - ok = true; - } else { - ui.statusLabel->setText( md.lastError() ); - } - } else { - ui.statusLabel->setText( i18n( "The selected path is a valid Maildir." ) ); - ok = true; + if (ui.kcfg_Path->url().isEmpty()) { + ui.statusLabel->setText(i18n("The selected path is empty.")); + mOkButton->setEnabled(false); + return; } - } else { - d.cdUp(); - if ( d.exists() ) { - ui.statusLabel->setText( i18n( "The selected path does not exist yet, a new Maildir will be created." ) ); - ok = true; + bool ok = false; + mToplevelIsContainer = false; + QDir d(ui.kcfg_Path->url().toLocalFile()); + + if (d.exists()) { + Maildir md(d.path()); + if (!md.isValid()) { + Maildir md2(d.path(), true); + if (md2.isValid()) { + ui.statusLabel->setText(i18n("The selected path contains valid Maildir folders.")); + mToplevelIsContainer = true; + ok = true; + } else { + ui.statusLabel->setText(md.lastError()); + } + } else { + ui.statusLabel->setText(i18n("The selected path is a valid Maildir.")); + ok = true; + } } else { - ui.statusLabel->setText( i18n( "The selected path does not exist." ) ); + d.cdUp(); + if (d.exists()) { + ui.statusLabel->setText(i18n("The selected path does not exist yet, a new Maildir will be created.")); + ok = true; + } else { + ui.statusLabel->setText(i18n("The selected path does not exist.")); + } } - } - enableButton( Ok, ok ); + mOkButton->setEnabled(ok); } void ConfigDialog::save() { - mManager->updateSettings(); - Settings::self()->setPath( ui.kcfg_Path->url().isLocalFile() ? ui.kcfg_Path->url().toLocalFile() : ui.kcfg_Path->url().path() ); - Settings::self()->setTopLevelIsContainer( mToplevelIsContainer ); - Settings::self()->writeConfig(); + mManager->updateSettings(); + Settings::self()->setPath(ui.kcfg_Path->url().isLocalFile() ? ui.kcfg_Path->url().toLocalFile() : ui.kcfg_Path->url().path()); + Settings::self()->setTopLevelIsContainer(mToplevelIsContainer); + Settings::self()->save(); } diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/configdialog.h kdepim-runtime-15.08.0/resources/mixedmaildir/configdialog.h --- kdepim-runtime-4.14.6/resources/mixedmaildir/configdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/configdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,25 +20,27 @@ #ifndef CONFIGDIALOG_H #define CONFIGDIALOG_H -#include +#include #include "ui_settings.h" +class QPushButton; class KConfigDialogManager; -class ConfigDialog : public KDialog +class ConfigDialog : public QDialog { - Q_OBJECT - public: - explicit ConfigDialog( QWidget *parent = 0 ); + Q_OBJECT +public: + explicit ConfigDialog(QWidget *parent = Q_NULLPTR); - private slots: +private Q_SLOTS: void checkPath(); void save(); - private: +private: Ui::ConfigDialog ui; - KConfigDialogManager* mManager; + KConfigDialogManager *mManager; + QPushButton *mOkButton; bool mToplevelIsContainer; }; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/autotests/CMakeLists.txt kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/autotests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/autotests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,14 @@ +add_definitions(-DTEST_PATH=${CMAKE_CURRENT_SOURCE_DIR}) +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${mixedmaildirresource_SOURCE_DIR}/kmindexreader +) + +set( testidxreader_SRCS + testidxreader.cpp +) +add_executable( testidxreader ${testidxreader_SRCS} ) +add_test( testidxreader testidxreader ) +ecm_mark_as_test(testidxreader) + +target_link_libraries( testidxreader Qt5::Test kmindexreader KF5::AkonadiMime ) diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/autotests/data/.keep kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/autotests/data/.keep --- kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/autotests/data/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/autotests/data/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/autotests/testidxreader.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/autotests/testidxreader.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/autotests/testidxreader.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/autotests/testidxreader.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2010 Casey Link + * Copyright (c) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "testidxreader.h" + +#include "../kmindexreader.h" + +#include "TestIdxReader_data.h" + +#include +using Akonadi::MessageStatus; +#include + +#include +#include +#include + +#include + +QTEST_MAIN(TestIdxReader) + +TestIdxReader::TestIdxReader() +{ +} + +void TestIdxReader::testError() +{ + KMIndexReader reader("IDoNotExist"); + + QVERIFY(reader.error() == true); +} + +void TestIdxReader::testReadHeader() +{ + QTemporaryFile tmp; + if (!tmp.open()) { + qDebug() << "Could not open temp file."; + return; + } + tmp.write(QByteArray::fromBase64(mailDirOneEmail)); + tmp.close(); + KMIndexReader reader(tmp.fileName()); + + QVERIFY(reader.error() == false); + + int version = 0; + bool success = reader.readHeader(&version); + + QVERIFY(success == true); + QCOMPARE(version, 1506); + + QVERIFY(reader.error() == false); +} + +void TestIdxReader::testRead() +{ + QTemporaryFile tmp; + if (!tmp.open()) { + qDebug() << "Could not open temp file."; + return; + } + tmp.write(QByteArray::fromBase64(mailDirTwoEmailOneTagFlags)); + tmp.close(); + KMIndexReader reader(tmp.fileName()); + QVERIFY(reader.error() == false); + bool success = reader.readIndex(); + QVERIFY(success == true); + + QVERIFY(reader.messages().size() == 2); + + KMIndexDataPtr msg = reader.messages().front(); + + QString subject = msg->mCachedStringParts[KMIndexReader::MsgSubjectPart]; + MessageStatus status; + status.fromQInt32(msg->mCachedLongParts[KMIndexReader::MsgStatusPart]); + QCOMPARE(subject, QString("hello from kmail")); + QVERIFY(!status.isImportant()); + QVERIFY(!msg->status().isImportant()); + QVERIFY(msg->status().isRead()); + QVERIFY(msg->tagList().contains("N5tUHPOZFf")); + + msg = reader.messages().back(); + status.fromQInt32(msg->mCachedLongParts[KMIndexReader::MsgStatusPart]); + subject = msg->mCachedStringParts[KMIndexReader::MsgSubjectPart]; + QCOMPARE(subject, QString("foo bar")); + QVERIFY(status.isImportant()); + QVERIFY(msg->status().isImportant()); + QVERIFY(!msg->status().isRead()); + QVERIFY(msg->tagList().size() == 0); +} + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/autotests/TestIdxReader_data.h kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/autotests/TestIdxReader_data.h --- kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/autotests/TestIdxReader_data.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/autotests/TestIdxReader_data.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010 Casey Link + * Copyright (c) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TESTIDXREADER_DATA +#define TESTIDXREADER_DATA + +/* contains one maildir with one email inside*/ +static const char mailDirOneEmail[] = + "IyBLTWFpbC1JbmRleCBWMTUwNgoACAAAAHhWNBIIAAAAagEAAAUAAAAAAAgAAAAIAAAAAAAAAAAA" + "AQAAABQAAEMAYQBzAGUAeQAgAEwAaQBuAGsTAAAAAAACAAAAIAAAaABlAGwAbABvACAAZgByAG8A" + "bQAgAGsAbQBhAGkAbAMAAAAcAABLAEQAQQBCACAARQBtAHAAbABvAHkAZQBlAHMEAAAAAAAGAAAA" + "AAALAAAANAAAMQAyADcAMQA1ADEAMwA1ADMANwAuADEAOQA1ADcANgAuADEATABLADYAZQA6ADIA" + "LABTCQAAAAgAhAIAAAAAAAAHAAAACAAAAAAAAAAAAAoAAAAIAMHByUsAAAAADAAAAAgATgBOAAAA" + "AAANAAAACAAgAAAAAAAAAA4AAAAAAA8AAAAsAABxADEAUABJAFkAbgBhAGwAVwB3AFYAQgAzAHEA" + "aAB2AEYAUABUAHQAaQBBEAAAAAgABAAAAAAAAAARAAAACAAAAAAAAAAAABIAAAAIAAAAAAAAAAAA"; + +/* + Folder: "Test1" type:Maildir + Message1: "foo bar" Important, Unread + Message2: "hello from kmail" Read, tagged "N5tUHPOZFf" + */ +static const char mailDirTwoEmailOneTagFlags[] = + "IyBLTWFpbC1JbmRleCBWMTUwNgoACAAAAHhWNBIIAAAAlAEAAAUAAAAAAAgAAAAIAAAAAAAAAAAA" + "AQAAABQAAEMAYQBzAGUAeQAgAEwAaQBuAGsTAAAAKgAATgA1AHQAVQBIAFAATwBaAEYAZgAsAFUA" + "RgBNAEUAagBHAHMAUQA5AG8CAAAAIAAAaABlAGwAbABvACAAZgByAG8AbQAgAGsAbQBhAGkAbAMA" + "AAAcAABLAEQAQQBCACAARQBtAHAAbABvAHkAZQBlAHMEAAAAAAAGAAAAAAALAAAANAAAMQAyADcA" + "MQA1ADEAMwA1ADMANwAuADEAOQA1ADcANgAuADEATABLADYAZQA6ADIALABTCQAAAAgAhAIAAAAA" + "AAAHAAAACAAAAAAAAAAAAAoAAAAIAMHByUsAAAAADAAAAAgATgBOAAAAAAANAAAACAAgAAAAAAAA" + "AA4AAAAAAA8AAAAsAABxADEAUABJAFkAbgBhAGwAVwB3AFYAQgAzAHEAaAB2AEYAUABUAHQAaQBB" + "EAAAAAgABAAAAAAAAAARAAAACAAAAAAAAAAAABIAAAAIAAAAAAAAAAAASAEAAAUAAAAAAAgAAAAI" + "AAAAAAAAAAAAAQAAABQAAEMAYQBzAGUAeQAgAEwAaQBuAGsTAAAAAAACAAAADgAAZgBvAG8AIABi" + "AGEAcgMAAAAWAABvAG4AZQBAAG8AbgBlAC4AYwBvAG0EAAAAAAAGAAAAAAALAAAAKgAAMQAyADcA" + "MQA3ADcAMwAwADEAOQAuADUANwA1ADQALgBwAFcAcQBaAFMJAAAACABKAgAAAAAAAAcAAAAIAAAA" + "AAAAAAAACgAAAAgAW7fNSwAAAAAMAAAACABOAE4AAAAAAA0AAAAIACAAAAAAAAAADgAAAAAADwAA" + "ACwAAE0AbgB0AHYAQgAwAE4AWQBFAFMATwBiAHgASAA0AFYAUgBEAFUAeQBjAHcQAAAACAACAgAA" + "AAAAABEAAAAIAAAAAAAAAAAAEgAAAAgAAAAAAAAAAAA="; + +#endif diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/autotests/testidxreader.h kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/autotests/testidxreader.h --- kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/autotests/testidxreader.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/autotests/testidxreader.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2010 Casey Link + * Copyright (c) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TESTIDXREADER_H +#define TESTIDXREADER_H + +#include + +class TestIdxReader : public QObject +{ + Q_OBJECT +public: + TestIdxReader(); +private Q_SLOTS: + void testError(); + void testReadHeader(); + void testRead(); +private: + +}; + +#endif // TESTIDXREADER_H diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/CMakeLists.txt kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,23 +1,23 @@ -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${KDE4_INCLUDES} -) - -add_subdirectory(tests) +if (BUILD_TESTING) + add_subdirectory(autotests) +endif() ########### next target ############### set(kmindexreader_LIB_SRCS kmindexreader.cpp + ../mixedmaildir_debug.cpp + ../mixedmaildirresource_debug.cpp ) -kde4_add_library(kmindexreader ${LIBRARY_TYPE} ${kmindexreader_LIB_SRCS}) +add_library(kmindexreader ${kmindexreader_LIB_SRCS}) +generate_export_header(kmindexreader BASE_NAME kmindexreader) target_link_libraries(kmindexreader - ${KDE4_KDECORE_LIBS} - ${KDEPIMLIBS_AKONADI_KMIME_LIBS} + KF5::AkonadiMime + KF5::KDELibs4Support ) -set_target_properties(kmindexreader PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} ) +set_target_properties(kmindexreader PROPERTIES VERSION ${KDEPIMRUNTIME_LIB_VERSION} SOVERSION ${KDEPIMRUNTIME_LIB_SOVERSION} ) -install(TARGETS kmindexreader ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(TARGETS kmindexreader ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/kmindexreader.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/kmindexreader.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/kmindexreader.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/kmindexreader.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,7 +24,8 @@ #include "kmindexreader.h" -#include +#include "../mixedmaildirresource_debug.h" +#include "../mixedmaildir_debug.h" #include #include using Akonadi::MessageStatus; @@ -40,7 +41,7 @@ static const int INDEX_VERSION = 1506; const size_t readCount = 1; #ifndef MAX_LINE - static const int MAX_LINE = 4096; +static const int MAX_LINE = 4096; #endif // We define functions as kmail_swap_NN so that we don't get compile errors @@ -51,7 +52,7 @@ #define kmail_swap_16(x) bswap_16(x) #else #define kmail_swap_16(x) \ - ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)) + ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)) #endif /* Swap bytes in 32 bit value. */ @@ -59,8 +60,8 @@ #define kmail_swap_32(x) bswap_32(x) #else #define kmail_swap_32(x) \ - ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ - (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) #endif /* Swap bytes in 64 bit value. */ @@ -68,322 +69,337 @@ #define kmail_swap_64(x) bswap_64(x) #else #define kmail_swap_64(x) \ - ((((x) & 0xff00000000000000ull) >> 56) \ - | (((x) & 0x00ff000000000000ull) >> 40) \ - | (((x) & 0x0000ff0000000000ull) >> 24) \ - | (((x) & 0x000000ff00000000ull) >> 8) \ - | (((x) & 0x00000000ff000000ull) << 8) \ - | (((x) & 0x0000000000ff0000ull) << 24) \ - | (((x) & 0x000000000000ff00ull) << 40) \ - | (((x) & 0x00000000000000ffull) << 56)) + ((((x) & 0xff00000000000000ull) >> 56) \ + | (((x) & 0x00ff000000000000ull) >> 40) \ + | (((x) & 0x0000ff0000000000ull) >> 24) \ + | (((x) & 0x000000ff00000000ull) >> 8) \ + | (((x) & 0x00000000ff000000ull) << 8) \ + | (((x) & 0x0000000000ff0000ull) << 24) \ + | (((x) & 0x000000000000ff00ull) << 40) \ + | (((x) & 0x00000000000000ffull) << 56)) #endif /** The old status format, only one at a time possible. Needed for upgrade path purposes. */ -typedef enum -{ - KMLegacyMsgStatusUnknown=' ', - KMLegacyMsgStatusNew='N', - KMLegacyMsgStatusUnread='U', - KMLegacyMsgStatusRead='R', - KMLegacyMsgStatusOld='O', - KMLegacyMsgStatusDeleted='D', - KMLegacyMsgStatusReplied='A', - KMLegacyMsgStatusForwarded='F', - KMLegacyMsgStatusQueued='Q', - KMLegacyMsgStatusSent='S', - KMLegacyMsgStatusFlag='G' +typedef enum { + KMLegacyMsgStatusUnknown = ' ', + KMLegacyMsgStatusNew = 'N', + KMLegacyMsgStatusUnread = 'U', + KMLegacyMsgStatusRead = 'R', + KMLegacyMsgStatusOld = 'O', + KMLegacyMsgStatusDeleted = 'D', + KMLegacyMsgStatusReplied = 'A', + KMLegacyMsgStatusForwarded = 'F', + KMLegacyMsgStatusQueued = 'Q', + KMLegacyMsgStatusSent = 'S', + KMLegacyMsgStatusFlag = 'G' } KMLegacyMsgStatus; //END: Magic definitions from old kmail code //BEGIN: KMIndexMsg methods -KMIndexData::KMIndexData() : mPartsCacheBuilt( false ) +KMIndexData::KMIndexData() : mPartsCacheBuilt(false) { - const uint count = sizeof( mCachedLongParts ) / sizeof( unsigned long ); - for ( uint i = 0; i < count; ++i ) { - mCachedLongParts[ i ] = 0; - } -} - -MessageStatus& KMIndexData::status() -{ - if ( mStatus.isOfUnknownStatus() ) { - mStatus.fromQInt32( mCachedLongParts[KMIndexReader::MsgStatusPart] ); - if ( mStatus.isOfUnknownStatus() ) { - // We are opening an old index for the first time, get the legacy - // status and merge it in. - // This is kept to provide an upgrade path from the old single - // status to the new multiple status scheme. - KMLegacyMsgStatus legacyMsgStatus = (KMLegacyMsgStatus) mCachedLongParts[KMIndexReader::MsgLegacyStatusPart]; - mStatus.setRead(); - switch ( legacyMsgStatus ) { - case KMLegacyMsgStatusUnknown: - mStatus.clear(); - break; - case KMLegacyMsgStatusUnread: - mStatus.setRead( false ); - break; - case KMLegacyMsgStatusRead: - mStatus.setRead(); - break; - case KMLegacyMsgStatusDeleted: - mStatus.setDeleted(); - break; - case KMLegacyMsgStatusReplied: - mStatus.setReplied(); - break; - case KMLegacyMsgStatusForwarded: - mStatus.setForwarded(); - break; - case KMLegacyMsgStatusQueued: - mStatus.setQueued(); - break; - case KMLegacyMsgStatusSent: - mStatus.setSent(); - break; - case KMLegacyMsgStatusFlag: - mStatus.setImportant(); - break; - default: - break; - } - - } - } - return mStatus; + const uint count = sizeof(mCachedLongParts) / sizeof(unsigned long); + for (uint i = 0; i < count; ++i) { + mCachedLongParts[ i ] = 0; + } +} + +MessageStatus &KMIndexData::status() +{ + if (mStatus.isOfUnknownStatus()) { + mStatus.fromQInt32(mCachedLongParts[KMIndexReader::MsgStatusPart]); + if (mStatus.isOfUnknownStatus()) { + // We are opening an old index for the first time, get the legacy + // status and merge it in. + // This is kept to provide an upgrade path from the old single + // status to the new multiple status scheme. + KMLegacyMsgStatus legacyMsgStatus = (KMLegacyMsgStatus) mCachedLongParts[KMIndexReader::MsgLegacyStatusPart]; + mStatus.setRead(); + switch (legacyMsgStatus) { + case KMLegacyMsgStatusUnknown: + mStatus.clear(); + break; + case KMLegacyMsgStatusUnread: + mStatus.setRead(false); + break; + case KMLegacyMsgStatusRead: + mStatus.setRead(); + break; + case KMLegacyMsgStatusDeleted: + mStatus.setDeleted(); + break; + case KMLegacyMsgStatusReplied: + mStatus.setReplied(); + break; + case KMLegacyMsgStatusForwarded: + mStatus.setForwarded(); + break; + case KMLegacyMsgStatusQueued: + mStatus.setQueued(); + break; + case KMLegacyMsgStatusSent: + mStatus.setSent(); + break; + case KMLegacyMsgStatusFlag: + mStatus.setImportant(); + break; + default: + break; + } + + } + } + return mStatus; } QStringList KMIndexData::tagList() const { - return mCachedStringParts[KMIndexReader::MsgTagPart].split( ',', QString::SkipEmptyParts ); + return mCachedStringParts[KMIndexReader::MsgTagPart].split(',', QString::SkipEmptyParts); } quint64 KMIndexData::uid() const { - return mCachedLongParts[KMIndexReader::MsgUIDPart]; + return mCachedLongParts[KMIndexReader::MsgUIDPart]; } bool KMIndexData::isEmpty() const { - return !mPartsCacheBuilt; + return !mPartsCacheBuilt; } //END: KMIndexMsg methods -KMIndexReader::KMIndexReader(const QString& indexFile) -: mIndexFileName( indexFile ) -, mIndexFile( indexFile ) -, mConvertToUtf8 ( false ) -, mIndexSwapByteOrder( false ) -, mHeaderOffset( 0 ) -, mError( false ) -{ - if( !mIndexFile.exists() ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "file doesn't exist"; - mError = true; - } - - if( !mIndexFile.open( QIODevice::ReadOnly ) ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "file cant be open"; - mError = true; - } +KMIndexReader::KMIndexReader(const QString &indexFile) + : mIndexFileName(indexFile) + , mIndexFile(indexFile) + , mConvertToUtf8(false) + , mIndexSwapByteOrder(false) + , mHeaderOffset(0) + , mError(false) +{ + if (!mIndexFile.exists()) { + qCDebug(MIXEDMAILDIR_LOG) << "file doesn't exist"; + mError = true; + } - mFp = fdopen( mIndexFile.handle(), "r"); + if (!mIndexFile.open(QIODevice::ReadOnly)) { + qCDebug(MIXEDMAILDIR_LOG) << "file cant be open"; + mError = true; + } + + mFp = fdopen(mIndexFile.handle(), "r"); } KMIndexReader::~KMIndexReader() { - if (mFp) - fclose(mFp); + if (mFp) { + fclose(mFp); + } } bool KMIndexReader::error() const { - return mError; + return mError; } -KMIndexDataPtr KMIndexReader::dataByOffset( quint64 offset ) const +KMIndexDataPtr KMIndexReader::dataByOffset(quint64 offset) const { - QHash::const_iterator it = mMsgByOffset.constFind( offset ); - if ( it == mMsgByOffset.constEnd() ) { + QHash::const_iterator it = mMsgByOffset.constFind(offset); + if (it == mMsgByOffset.constEnd()) { return KMIndexDataPtr(); } return it.value(); } -KMIndexDataPtr KMIndexReader::dataByFileName( const QString &fileName ) const +KMIndexDataPtr KMIndexReader::dataByFileName(const QString &fileName) const { - QHash::const_iterator it = mMsgByFileName.constFind( fileName ); - if ( it == mMsgByFileName.constEnd() ) { + QHash::const_iterator it = mMsgByFileName.constFind(fileName); + if (it == mMsgByFileName.constEnd()) { return KMIndexDataPtr(); } return it.value(); } -bool KMIndexReader::readHeader( int *version ) +bool KMIndexReader::readHeader(int *version) { - int indexVersion; - Q_ASSERT( mFp != 0 ); - mIndexSwapByteOrder = false; - mIndexSizeOfLong = sizeof( long ); - - int ret = fscanf( mFp, "# KMail-Index V%d\n", &indexVersion ); - if ( ret == EOF || ret == 0 ) - return false; // index file has invalid header - if( version ) - *version = indexVersion; - if ( indexVersion < 1505 ) { - if( indexVersion == 1503 ) { - kWarning() << "Need to convert old index file" << mIndexFileName << "to utf-8"; - mConvertToUtf8 = true; - } - return true; - } else if ( indexVersion == 1505 ) { - } else if ( indexVersion < INDEX_VERSION ) { - kFatal() << "Index file" << mIndexFileName << "is out of date. What to do?"; + int indexVersion; + Q_ASSERT(mFp != 0); + mIndexSwapByteOrder = false; + mIndexSizeOfLong = sizeof(long); + + int ret = fscanf(mFp, "# KMail-Index V%d\n", &indexVersion); + if (ret == EOF || ret == 0) { + return false; // index file has invalid header + } + if (version) { + *version = indexVersion; + } + if (indexVersion < 1505) { + if (indexVersion == 1503) { + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "Need to convert old index file" << mIndexFileName << "to utf-8"; + mConvertToUtf8 = true; + } + return true; + } else if (indexVersion == 1505) { + } else if (indexVersion < INDEX_VERSION) { + qCCritical(MIXEDMAILDIR_LOG) << "Index file" << mIndexFileName << "is out of date. What to do?"; // createIndexFromContents(); - return false; - } else if( indexVersion > INDEX_VERSION ) { - kFatal() << "index file of newer version"; - return false; - } else { - // Header - quint32 byteOrder = 0; - quint32 sizeOfLong = sizeof( long ); // default - - quint32 header_length = 0; - KDE_fseek( mFp, sizeof( char ), SEEK_CUR ); - if ( fread( &header_length, sizeof( header_length ), readCount, mFp ) != readCount ) { - kWarning() << "Failed to read header_length"; - return false; - } - if ( header_length > 0xFFFF ) - header_length = kmail_swap_32( header_length ); - - off_t endOfHeader = KDE_ftell( mFp ) + header_length; - - bool needs_update = true; - // Process available header parts - if ( header_length >= sizeof( byteOrder ) ) { - if ( fread( &byteOrder, sizeof( byteOrder ), readCount, mFp ) != readCount ) { - kWarning() << "Failed to read byteOrder"; - return false; - } - mIndexSwapByteOrder = ( byteOrder == 0x78563412 ); - header_length -= sizeof( byteOrder ); - - if ( header_length >= sizeof( sizeOfLong ) ) { - if ( fread( &sizeOfLong, sizeof( sizeOfLong ), readCount, mFp ) != readCount ) { - kWarning() << "Failed to read sizeOfLong"; + return false; + } else if (indexVersion > INDEX_VERSION) { + qFatal("index file of newer version"); + return false; + } else { + // Header + quint32 byteOrder = 0; + quint32 sizeOfLong = sizeof(long); // default + + quint32 header_length = 0; + KDE_fseek(mFp, sizeof(char), SEEK_CUR); + if (fread(&header_length, sizeof(header_length), readCount, mFp) != readCount) { + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "Failed to read header_length"; + return false; + } + if (header_length > 0xFFFF) { + header_length = kmail_swap_32(header_length); + } + + off_t endOfHeader = KDE_ftell(mFp) + header_length; + + bool needs_update = true; + // Process available header parts + if (header_length >= sizeof(byteOrder)) { + if (fread(&byteOrder, sizeof(byteOrder), readCount, mFp) != readCount) { + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "Failed to read byteOrder"; return false; } - if ( mIndexSwapByteOrder ) - sizeOfLong = kmail_swap_32( sizeOfLong ); - mIndexSizeOfLong = sizeOfLong; - header_length -= sizeof( sizeOfLong ); - needs_update = false; - } - } - if ( needs_update || mIndexSwapByteOrder || ( mIndexSizeOfLong != sizeof( long ) ) ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "DIRTY!"; + mIndexSwapByteOrder = (byteOrder == 0x78563412); + header_length -= sizeof(byteOrder); + + if (header_length >= sizeof(sizeOfLong)) { + if (fread(&sizeOfLong, sizeof(sizeOfLong), readCount, mFp) != readCount) { + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "Failed to read sizeOfLong"; + return false; + } + if (mIndexSwapByteOrder) { + sizeOfLong = kmail_swap_32(sizeOfLong); + } + mIndexSizeOfLong = sizeOfLong; + header_length -= sizeof(sizeOfLong); + needs_update = false; + } + } + if (needs_update || mIndexSwapByteOrder || (mIndexSizeOfLong != sizeof(long))) { + qCDebug(MIXEDMAILDIR_LOG) << "DIRTY!"; // setDirty( true ); - } - // Seek to end of header - KDE_fseek( mFp, endOfHeader, SEEK_SET ); - - if ( mIndexSwapByteOrder ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Index File has byte order swapped!"; - } - if ( mIndexSizeOfLong != sizeof( long ) ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Index File sizeOfLong is" << mIndexSizeOfLong << "while sizeof(long) is" << sizeof(long) << "!"; - } + } + // Seek to end of header + KDE_fseek(mFp, endOfHeader, SEEK_SET); - } - return true; + if (mIndexSwapByteOrder) { + qCDebug(MIXEDMAILDIR_LOG) << "Index File has byte order swapped!"; + } + if (mIndexSizeOfLong != sizeof(long)) { + qCDebug(MIXEDMAILDIR_LOG) << "Index File sizeOfLong is" << mIndexSizeOfLong << "while sizeof(long) is" << sizeof(long) << "!"; + } + + } + return true; } bool KMIndexReader::readIndex() { - qint32 len; - KMIndexData* msg; + qint32 len; + KMIndexData *msg; - Q_ASSERT( mFp != 0 ); - rewind( mFp ); + Q_ASSERT(mFp != 0); + rewind(mFp); - mMsgList.clear(); - mMsgByFileName.clear(); - mMsgByOffset.clear(); - - int version; - - if ( !readHeader( &version ) ) return false; - - mHeaderOffset = KDE_ftell( mFp ); - - // loop through the entire index - while ( !feof( mFp ) ) { - //kDebug( KDE_DEFAULT_DEBUG_AREA ) << "NEW MSG!"; - msg = 0; - // check version (parsed by readHeader) - // because different versions must be - // parsed differently - //kDebug( KDE_DEFAULT_DEBUG_AREA ) << "parsing version" << version; - if( version >= 1505 ) { - // parse versions >= 1505 - if( !fread( &len, sizeof( len ), 1, mFp ) ) - break; - - // swap bytes if needed - if ( mIndexSwapByteOrder ) - len = kmail_swap_32( len ); - - off_t offs = KDE_ftell( mFp ); - if( KDE_fseek( mFp, len, SEEK_CUR ) ) - break; - msg = new KMIndexData(); - fillPartsCache( msg, offs, len ); - } else { - ////////////////////// - //BEGIN UNTESTED CODE - ////////////////////// - //parse verions < 1505 - QByteArray line( MAX_LINE, '\0' ); - if ( fgets( line.data(), MAX_LINE, mFp ) == NULL ) break; - if ( feof( mFp ) ) break; - if ( *line.data() == '\0' ) { - // really, i have no idea when or how this would occur - // but we probably want to know if it does - Casey - kWarning() << "Unknowable bad occurred"; - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "fclose(mFp = " << mFp << ")"; - fclose( mFp ); - mFp = 0; - mMsgList.clear(); - mMsgByFileName.clear(); - mMsgByOffset.clear(); + mMsgList.clear(); + mMsgByFileName.clear(); + mMsgByOffset.clear(); + + int version; + + if (!readHeader(&version)) { return false; - } - off_t offs = KDE_ftell( mFp ); - if ( KDE_fseek( mFp, len, SEEK_CUR ) ) - break; - msg = new KMIndexData; - fromOldIndexString( msg, line, mConvertToUtf8 ); - - fillPartsCache( msg, offs, len ); - ////////////////////// - //END UNTESTED CODE - ////////////////////// - } - if ( !msg ) - break; - - if ( msg->status().isDeleted() ) { - delete msg; // skip messages that are marked as deleted - continue; } + + mHeaderOffset = KDE_ftell(mFp); + + // loop through the entire index + while (!feof(mFp)) { + //qCDebug(MIXEDMAILDIR_LOG) << "NEW MSG!"; + msg = Q_NULLPTR; + // check version (parsed by readHeader) + // because different versions must be + // parsed differently + //qCDebug(MIXEDMAILDIR_LOG) << "parsing version" << version; + if (version >= 1505) { + // parse versions >= 1505 + if (!fread(&len, sizeof(len), 1, mFp)) { + break; + } + + // swap bytes if needed + if (mIndexSwapByteOrder) { + len = kmail_swap_32(len); + } + + off_t offs = KDE_ftell(mFp); + if (KDE_fseek(mFp, len, SEEK_CUR)) { + break; + } + msg = new KMIndexData(); + fillPartsCache(msg, offs, len); + } else { + ////////////////////// + //BEGIN UNTESTED CODE + ////////////////////// + //parse verions < 1505 + QByteArray line(MAX_LINE, '\0'); + if (fgets(line.data(), MAX_LINE, mFp) == Q_NULLPTR) { + break; + } + if (feof(mFp)) { + break; + } + if (*line.data() == '\0') { + // really, i have no idea when or how this would occur + // but we probably want to know if it does - Casey + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "Unknowable bad occurred"; + qCDebug(MIXEDMAILDIR_LOG) << "fclose(mFp = " << mFp << ")"; + fclose(mFp); + mFp = Q_NULLPTR; + mMsgList.clear(); + mMsgByFileName.clear(); + mMsgByOffset.clear(); + return false; + } + off_t offs = KDE_ftell(mFp); + if (KDE_fseek(mFp, len, SEEK_CUR)) { + break; + } + msg = new KMIndexData; + fromOldIndexString(msg, line, mConvertToUtf8); + + fillPartsCache(msg, offs, len); + ////////////////////// + //END UNTESTED CODE + ////////////////////// + } + if (!msg) { + break; + } + + if (msg->status().isDeleted()) { + delete msg; // skip messages that are marked as deleted + continue; + } #ifdef OBSOLETE // else if (mi->isNew()) // { @@ -391,26 +407,26 @@ // mi->setDirty(false); // } #endif - KMIndexDataPtr msgPtr( msg ); - mMsgList.append( msgPtr ); - const QString fileName = msg->mCachedStringParts[ MsgFilePart ]; - if ( !fileName.isEmpty() ) { - mMsgByFileName.insert( fileName, msgPtr ); - } + KMIndexDataPtr msgPtr(msg); + mMsgList.append(msgPtr); + const QString fileName = msg->mCachedStringParts[ MsgFilePart ]; + if (!fileName.isEmpty()) { + mMsgByFileName.insert(fileName, msgPtr); + } - const quint64 offset = msg->mCachedLongParts[ MsgOffsetPart ]; - if ( offset > 0 ) { - mMsgByOffset.insert( offset, msgPtr ); - } - } // end while + const quint64 offset = msg->mCachedLongParts[ MsgOffsetPart ]; + if (offset > 0) { + mMsgByOffset.insert(offset, msgPtr); + } + } // end while - return true; + return true; } //--- For compatibility with old index files -bool KMIndexReader::fromOldIndexString( KMIndexData* msg, const QByteArray& str, bool toUtf8) +bool KMIndexReader::fromOldIndexString(KMIndexData *msg, const QByteArray &str, bool toUtf8) { - Q_UNUSED( toUtf8 ) + Q_UNUSED(toUtf8) // const char *start, *offset; // msg->modifiers = KMMsgInfoPrivate::ALL_SET; // msg->xmark = str.mid(33, 3).trimmed(); @@ -438,153 +454,159 @@ // } // msg->replyToIdMD5 = str.mid(240, 22).trimmed(); // msg->msgIdMD5 = str.mid(263, 22).trimmed(); - msg->mStatus.setStatusFromStr( str ); - return true; + msg->mStatus.setStatusFromStr(str); + return true; } //----------------------------------------------------------------------------- -static void swapEndian( QString &str ) +static void swapEndian(QString &str) +{ + QChar *data = str.data(); + while (!data->isNull()) { + *data = kmail_swap_16(data->unicode()); + data++; + } +} + +static int g_chunk_length = 0, g_chunk_offset = 0; +static uchar *g_chunk = Q_NULLPTR; + +namespace +{ +template < typename T > void copy_from_stream(T &x) { - QChar *data = str.data(); - while ( !data->isNull() ) { - *data = kmail_swap_16( data->unicode() ); - data++; - } -} - -static int g_chunk_length = 0, g_chunk_offset=0; -static uchar *g_chunk = 0; - -namespace { - template < typename T > void copy_from_stream( T & x ) { - if( g_chunk_offset + int( sizeof( T ) ) > g_chunk_length ) { - g_chunk_offset = g_chunk_length; - kWarning() << "This should never happen.."; - x = 0; + if (g_chunk_offset + int(sizeof(T)) > g_chunk_length) { + g_chunk_offset = g_chunk_length; + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "This should never happen.."; + x = 0; } else { - // the memcpy is optimized out by the compiler for the values - // of sizeof(T) that is called with - memcpy( &x, g_chunk + g_chunk_offset, sizeof( T ) ); - g_chunk_offset += sizeof( T ); - } - } -} - -bool KMIndexReader::fillPartsCache( KMIndexData* msg, off_t indexOff, short int indexLen ) -{ - if( !msg ) - return false; - //kDebug( KDE_DEFAULT_DEBUG_AREA ); - if ( g_chunk_length < indexLen ) - g_chunk = (uchar *)realloc( g_chunk, g_chunk_length = indexLen ); - - off_t first_off = KDE_ftell( mFp ); - KDE_fseek( mFp, indexOff, SEEK_SET ); - if ( fread( g_chunk, indexLen, readCount, mFp ) != readCount ) { - kWarning() << "Failed to read index"; - return false; - } - KDE_fseek( mFp, first_off, SEEK_SET ); - - MsgPartType type; - quint16 len; - off_t ret = 0; - for ( g_chunk_offset = 0; g_chunk_offset < indexLen; g_chunk_offset += len ) { - quint32 tmp; - copy_from_stream( tmp ); - copy_from_stream( len ); - if ( mIndexSwapByteOrder ) { - tmp = kmail_swap_32( tmp ); - len = kmail_swap_16( len ); - } - type = (MsgPartType) tmp; - if ( g_chunk_offset + len > indexLen ) { - kWarning() << "g_chunk_offset + len > indexLen" << "This should never happen.."; - return false; + // the memcpy is optimized out by the compiler for the values + // of sizeof(T) that is called with + memcpy(&x, g_chunk + g_chunk_offset, sizeof(T)); + g_chunk_offset += sizeof(T); + } +} +} + +bool KMIndexReader::fillPartsCache(KMIndexData *msg, off_t indexOff, short int indexLen) +{ + if (!msg) { + return false; + } + //qCDebug(MIXEDMAILDIR_LOG); + if (g_chunk_length < indexLen) { + g_chunk = (uchar *)realloc(g_chunk, g_chunk_length = indexLen); } + + off_t first_off = KDE_ftell(mFp); + KDE_fseek(mFp, indexOff, SEEK_SET); + if (fread(g_chunk, indexLen, readCount, mFp) != readCount) { + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "Failed to read index"; + return false; + } + KDE_fseek(mFp, first_off, SEEK_SET); + + MsgPartType type; + quint16 len; + off_t ret = 0; + for (g_chunk_offset = 0; g_chunk_offset < indexLen; g_chunk_offset += len) { + quint32 tmp; + copy_from_stream(tmp); + copy_from_stream(len); + if (mIndexSwapByteOrder) { + tmp = kmail_swap_32(tmp); + len = kmail_swap_16(len); + } + type = (MsgPartType) tmp; + if (g_chunk_offset + len > indexLen) { + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "g_chunk_offset + len > indexLen" << "This should never happen.."; + return false; + } // Only try to create strings if the part is really a string part, see declaration of - // MsgPartType - if ( len && ( ( type >= 1 && type <= 6 ) || type == 11 || type == 14 || type == 15 || type == 19 ) ) { + // MsgPartType + if (len && ((type >= 1 && type <= 6) || type == 11 || type == 14 || type == 15 || type == 19)) { - // This works because the QString constructor does a memcpy. - // Otherwise we would need to be concerned about the alignment. - QString str( (QChar *)( g_chunk + g_chunk_offset ), len/2 ); - msg->mCachedStringParts[type] = str; - - // Normally we need to swap the byte order because the QStrings are written - // in the style of Qt2 (MSB -> network ordered). - // QStrings in Qt3 expect host ordering. - // On e.g. Intel host ordering is LSB, on e.g. Sparc it is MSB. + // This works because the QString constructor does a memcpy. + // Otherwise we would need to be concerned about the alignment. + QString str((QChar *)(g_chunk + g_chunk_offset), len / 2); + msg->mCachedStringParts[type] = str; + + // Normally we need to swap the byte order because the QStrings are written + // in the style of Qt2 (MSB -> network ordered). + // QStrings in Qt3 expect host ordering. + // On e.g. Intel host ordering is LSB, on e.g. Sparc it is MSB. # if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - // Byte order is little endian (swap is true) - swapEndian( msg->mCachedStringParts[type] ); + // Byte order is little endian (swap is true) + swapEndian(msg->mCachedStringParts[type]); # else - // Byte order is big endian (swap is false) + // Byte order is big endian (swap is false) # endif - } else if( ( type >= 7 && type <= 10 ) || type == 12 || type == 13 || ( type >= 16 && type <= 18 ) ) { - Q_ASSERT( mIndexSizeOfLong == len ); - if ( mIndexSizeOfLong == sizeof( ret ) ) { - //kDebug( KDE_DEFAULT_DEBUG_AREA ) << "mIndexSizeOfLong == sizeof(ret)"; - // this memcpy replaces the original call to copy_from_stream - // so that g_chunk_offset is not changed - memcpy( &ret, g_chunk + g_chunk_offset, sizeof( ret ) ); - if ( mIndexSwapByteOrder ) { - if ( sizeof(ret) == 4 ) - ret = kmail_swap_32( ret ); - else - ret = kmail_swap_64( ret ); - } - } - ////////////////////// - //BEGIN UNTESTED CODE - ////////////////////// - else if ( mIndexSizeOfLong == 4 ) { - // Long is stored as 4 bytes in index file, sizeof(long) = 8 - quint32 ret_32; - // this memcpy replaces the original call to copy_from_stream - // so that g_chunk_offset is not changed - memcpy( &ret_32, g_chunk + g_chunk_offset, sizeof( quint32 ) ); - if ( mIndexSwapByteOrder ) - ret_32 = kmail_swap_32( ret_32 ); - ret = ret_32; - } else if ( mIndexSizeOfLong == 8 ) { - // Long is stored as 8 bytes in index file, sizeof(long) = 4 - quint32 ret_1; - quint32 ret_2; - // these memcpys replace the original calls to copy_from_stream - // so that g_chunk_offset is not changed - memcpy( &ret_1, g_chunk + g_chunk_offset, sizeof( quint32 ) ); - memcpy( &ret_2, g_chunk + g_chunk_offset, sizeof( quint32 ) ); - if ( !mIndexSwapByteOrder ) { - // Index file order is the same as the order of this CPU. + } else if ((type >= 7 && type <= 10) || type == 12 || type == 13 || (type >= 16 && type <= 18)) { + Q_ASSERT(mIndexSizeOfLong == len); + if (mIndexSizeOfLong == sizeof(ret)) { + //qCDebug(MIXEDMAILDIR_LOG) << "mIndexSizeOfLong == sizeof(ret)"; + // this memcpy replaces the original call to copy_from_stream + // so that g_chunk_offset is not changed + memcpy(&ret, g_chunk + g_chunk_offset, sizeof(ret)); + if (mIndexSwapByteOrder) { + if (sizeof(ret) == 4) { + ret = kmail_swap_32(ret); + } else { + ret = kmail_swap_64(ret); + } + } + } + ////////////////////// + //BEGIN UNTESTED CODE + ////////////////////// + else if (mIndexSizeOfLong == 4) { + // Long is stored as 4 bytes in index file, sizeof(long) = 8 + quint32 ret_32; + // this memcpy replaces the original call to copy_from_stream + // so that g_chunk_offset is not changed + memcpy(&ret_32, g_chunk + g_chunk_offset, sizeof(quint32)); + if (mIndexSwapByteOrder) { + ret_32 = kmail_swap_32(ret_32); + } + ret = ret_32; + } else if (mIndexSizeOfLong == 8) { + // Long is stored as 8 bytes in index file, sizeof(long) = 4 + quint32 ret_1; + quint32 ret_2; + // these memcpys replace the original calls to copy_from_stream + // so that g_chunk_offset is not changed + memcpy(&ret_1, g_chunk + g_chunk_offset, sizeof(quint32)); + memcpy(&ret_2, g_chunk + g_chunk_offset, sizeof(quint32)); + if (!mIndexSwapByteOrder) { + // Index file order is the same as the order of this CPU. #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - // Index file order is little endian - ret = ret_1; // We drop the 4 most significant bytes + // Index file order is little endian + ret = ret_1; // We drop the 4 most significant bytes #else - // Index file order is big endian - ret = ret_2; // We drop the 4 most significant bytes + // Index file order is big endian + ret = ret_2; // We drop the 4 most significant bytes #endif - } else { - // Index file order is different from this CPU. + } else { + // Index file order is different from this CPU. #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - // Index file order is big endian - ret = ret_2; // We drop the 4 most significant bytes + // Index file order is big endian + ret = ret_2; // We drop the 4 most significant bytes #else - // Index file order is little endian - ret = ret_1; // We drop the 4 most significant bytes + // Index file order is little endian + ret = ret_1; // We drop the 4 most significant bytes #endif - // We swap the result to host order. - ret = kmail_swap_32( ret ); - } - } - ////////////////////// - //END UNTESTED CODE - ////////////////////// - msg->mCachedLongParts[type] = ret; - } - } // for loop + // We swap the result to host order. + ret = kmail_swap_32(ret); + } + } + ////////////////////// + //END UNTESTED CODE + ////////////////////// + msg->mCachedLongParts[type] = ret; + } + } // for loop msg->mPartsCacheBuilt = true; return true; } @@ -593,5 +615,5 @@ QList< KMIndexDataPtr > KMIndexReader::messages() { - return mMsgList; + return mMsgList; } diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/kmindexreader_export.h kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/kmindexreader_export.h --- kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/kmindexreader_export.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/kmindexreader_export.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company - Author: Kevin Krammer - - 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 KMINDEXREADER_EXPORT_H -#define KMINDEXREADER_EXPORT_H - -/* needed for KDE_EXPORT and KDE_IMPORT macros */ -#include - -#ifndef KMINDEXREADER_EXPORT -# if defined(KDEPIM_STATIC_LIBS) - /* No export/import for static libraries */ -# define KMINDEXREADER_EXPORT -# elif defined(MAKE_KMINDEXREADER_LIB) - /* We are building this library */ -# define KMINDEXREADER_EXPORT KDE_EXPORT -# else - /* We are using this library */ -# define KMINDEXREADER_EXPORT KDE_IMPORT -# endif -#endif - -# ifndef MBOX_EXPORT_DEPRECATED -# define MBOX_EXPORT_DEPRECATED KDE_DEPRECATED MBOX_EXPORT -# endif - -#endif diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/kmindexreader.h kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/kmindexreader.h --- kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/kmindexreader.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/kmindexreader.h 2015-08-10 21:01:02.000000000 +0000 @@ -23,7 +23,7 @@ #include "kmindexreader_export.h" -#include +#include using Akonadi::MessageStatus; #include @@ -37,15 +37,16 @@ namespace boost { - template class shared_ptr; +template class shared_ptr; } -class KMINDEXREADER_EXPORT KMIndexData { - Q_DISABLE_COPY( KMIndexData ) +class KMINDEXREADER_EXPORT KMIndexData +{ + Q_DISABLE_COPY(KMIndexData) public: KMIndexData(); /** Status object of the message. */ - MessageStatus& status(); + MessageStatus &status(); QStringList tagList() const ; quint64 uid() const; bool isEmpty() const; @@ -69,10 +70,11 @@ * It uses old kmfolderindex code, authors attributed as appropriate. * @author Casey Link */ -class KMINDEXREADER_EXPORT KMIndexReader { +class KMINDEXREADER_EXPORT KMIndexReader +{ public: - explicit KMIndexReader ( const QString &indexFile ); - ~KMIndexReader(); + explicit KMIndexReader(const QString &indexFile); + ~KMIndexReader(); bool error() const; @@ -111,30 +113,29 @@ MsgTagPart = 19 }; - KMIndexDataPtr dataByOffset( quint64 offset ) const; + KMIndexDataPtr dataByOffset(quint64 offset) const; - KMIndexDataPtr dataByFileName( const QString &fileName ) const; + KMIndexDataPtr dataByFileName(const QString &fileName) const; private: - /** * Reads the header of an index */ - bool readHeader ( int *version ); + bool readHeader(int *version); /** * creates a message object from an old index files */ - bool fromOldIndexString ( KMIndexData* msg, const QByteArray& str, bool toUtf8 ); + bool fromOldIndexString(KMIndexData *msg, const QByteArray &str, bool toUtf8); - bool fillPartsCache ( KMIndexData* msg, off_t off, short int len ); + bool fillPartsCache(KMIndexData *msg, off_t off, short int len); QList messages(); QString mIndexFileName; QFile mIndexFile; - FILE* mFp; + FILE *mFp; bool mConvertToUtf8; bool mIndexSwapByteOrder; // Index file was written with swapped byte order diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/tests/CMakeLists.txt kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -add_definitions(-DTEST_PATH=${CMAKE_CURRENT_SOURCE_DIR}) -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${mixedmaildirresource_SOURCE_DIR}/kmindexreader - ${KDE4_INCLUDES} -) - -set( testidxreader_SRCS - testidxreader.cpp -) - -kde4_add_unit_test( testidxreader ${testidxreader_SRCS} ) - -target_link_libraries( testidxreader ${KDE4_KDECORE_LIBS} ${QT_QTTEST_LIBRARY} kmindexreader ${KDEPIMLIBS_AKONADI_KMIME_LIBS} ) diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/tests/data/.keep kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/tests/data/.keep --- kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/tests/data/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/tests/data/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/tests/testidxreader.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/tests/testidxreader.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/tests/testidxreader.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/tests/testidxreader.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2010 Casey Link - * Copyright (c) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "testidxreader.h" - -#include "../kmindexreader.h" - -#include "TestIdxReader_data.h" - -#include -using Akonadi::MessageStatus; -#include - -#include -#include -#include - -#include - -QTEST_MAIN ( TestIdxReader ) - - -TestIdxReader::TestIdxReader() { -} - -void TestIdxReader::testError() { - KMIndexReader reader ( "IDoNotExist" ); - - QVERIFY ( reader.error() == true ); -} - -void TestIdxReader::testReadHeader() { - QTemporaryFile tmp; - if ( !tmp.open() ) { - qDebug() << "Could not open temp file."; - return; - } - tmp.write ( QByteArray::fromBase64 ( mailDirOneEmail ) ); - tmp.close(); - KMIndexReader reader ( tmp.fileName() ); - - QVERIFY ( reader.error() == false ); - - int version = 0; - bool success = reader.readHeader ( &version ); - - QVERIFY ( success == true ); - QCOMPARE ( version, 1506 ); - - QVERIFY ( reader.error() == false ); -} - -void TestIdxReader::testRead() { - QTemporaryFile tmp; - if ( !tmp.open() ) { - qDebug() << "Could not open temp file."; - return; - } - tmp.write ( QByteArray::fromBase64 ( mailDirTwoEmailOneTagFlags ) ); - tmp.close(); - KMIndexReader reader ( tmp.fileName() ); - QVERIFY ( reader.error() == false ); - bool success = reader.readIndex(); - QVERIFY ( success == true ); - - QVERIFY ( reader.messages().size() == 2 ); - - KMIndexDataPtr msg = reader.messages().front(); - - QString subject = msg->mCachedStringParts[KMIndexReader::MsgSubjectPart]; - MessageStatus status; - status.fromQInt32 ( msg->mCachedLongParts[KMIndexReader::MsgStatusPart] ); - QCOMPARE ( subject, QString ( "hello from kmail" ) ); - QVERIFY ( !status.isImportant() ); - QVERIFY ( !msg->status().isImportant() ); - QVERIFY ( msg->status().isRead() ); - QVERIFY ( msg->tagList().contains( "N5tUHPOZFf" ) ); - - msg = reader.messages().back(); - status.fromQInt32 ( msg->mCachedLongParts[KMIndexReader::MsgStatusPart] ); - subject = msg->mCachedStringParts[KMIndexReader::MsgSubjectPart]; - QCOMPARE ( subject, QString ( "foo bar" ) ); - QVERIFY ( status.isImportant() ); - QVERIFY ( msg->status().isImportant() ); - QVERIFY ( !msg->status().isRead() ); - QVERIFY ( msg->tagList().size() == 0 ); -} - diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/tests/TestIdxReader_data.h kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/tests/TestIdxReader_data.h --- kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/tests/TestIdxReader_data.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/tests/TestIdxReader_data.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2010 Casey Link - * Copyright (c) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef TESTIDXREADER_DATA -#define TESTIDXREADER_DATA - -/* contains one maildir with one email inside*/ -static const char mailDirOneEmail[] = - "IyBLTWFpbC1JbmRleCBWMTUwNgoACAAAAHhWNBIIAAAAagEAAAUAAAAAAAgAAAAIAAAAAAAAAAAA" - "AQAAABQAAEMAYQBzAGUAeQAgAEwAaQBuAGsTAAAAAAACAAAAIAAAaABlAGwAbABvACAAZgByAG8A" - "bQAgAGsAbQBhAGkAbAMAAAAcAABLAEQAQQBCACAARQBtAHAAbABvAHkAZQBlAHMEAAAAAAAGAAAA" - "AAALAAAANAAAMQAyADcAMQA1ADEAMwA1ADMANwAuADEAOQA1ADcANgAuADEATABLADYAZQA6ADIA" - "LABTCQAAAAgAhAIAAAAAAAAHAAAACAAAAAAAAAAAAAoAAAAIAMHByUsAAAAADAAAAAgATgBOAAAA" - "AAANAAAACAAgAAAAAAAAAA4AAAAAAA8AAAAsAABxADEAUABJAFkAbgBhAGwAVwB3AFYAQgAzAHEA" - "aAB2AEYAUABUAHQAaQBBEAAAAAgABAAAAAAAAAARAAAACAAAAAAAAAAAABIAAAAIAAAAAAAAAAAA"; - -/* - Folder: "Test1" type:Maildir - Message1: "foo bar" Important, Unread - Message2: "hello from kmail" Read, tagged "N5tUHPOZFf" - */ -static const char mailDirTwoEmailOneTagFlags[] = -"IyBLTWFpbC1JbmRleCBWMTUwNgoACAAAAHhWNBIIAAAAlAEAAAUAAAAAAAgAAAAIAAAAAAAAAAAA" -"AQAAABQAAEMAYQBzAGUAeQAgAEwAaQBuAGsTAAAAKgAATgA1AHQAVQBIAFAATwBaAEYAZgAsAFUA" -"RgBNAEUAagBHAHMAUQA5AG8CAAAAIAAAaABlAGwAbABvACAAZgByAG8AbQAgAGsAbQBhAGkAbAMA" -"AAAcAABLAEQAQQBCACAARQBtAHAAbABvAHkAZQBlAHMEAAAAAAAGAAAAAAALAAAANAAAMQAyADcA" -"MQA1ADEAMwA1ADMANwAuADEAOQA1ADcANgAuADEATABLADYAZQA6ADIALABTCQAAAAgAhAIAAAAA" -"AAAHAAAACAAAAAAAAAAAAAoAAAAIAMHByUsAAAAADAAAAAgATgBOAAAAAAANAAAACAAgAAAAAAAA" -"AA4AAAAAAA8AAAAsAABxADEAUABJAFkAbgBhAGwAVwB3AFYAQgAzAHEAaAB2AEYAUABUAHQAaQBB" -"EAAAAAgABAAAAAAAAAARAAAACAAAAAAAAAAAABIAAAAIAAAAAAAAAAAASAEAAAUAAAAAAAgAAAAI" -"AAAAAAAAAAAAAQAAABQAAEMAYQBzAGUAeQAgAEwAaQBuAGsTAAAAAAACAAAADgAAZgBvAG8AIABi" -"AGEAcgMAAAAWAABvAG4AZQBAAG8AbgBlAC4AYwBvAG0EAAAAAAAGAAAAAAALAAAAKgAAMQAyADcA" -"MQA3ADcAMwAwADEAOQAuADUANwA1ADQALgBwAFcAcQBaAFMJAAAACABKAgAAAAAAAAcAAAAIAAAA" -"AAAAAAAACgAAAAgAW7fNSwAAAAAMAAAACABOAE4AAAAAAA0AAAAIACAAAAAAAAAADgAAAAAADwAA" -"ACwAAE0AbgB0AHYAQgAwAE4AWQBFAFMATwBiAHgASAA0AFYAUgBEAFUAeQBjAHcQAAAACAACAgAA" -"AAAAABEAAAAIAAAAAAAAAAAAEgAAAAgAAAAAAAAAAAA="; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/tests/testidxreader.h kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/tests/testidxreader.h --- kdepim-runtime-4.14.6/resources/mixedmaildir/kmindexreader/tests/testidxreader.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/kmindexreader/tests/testidxreader.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2010 Casey Link - * Copyright (c) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef TESTIDXREADER_H -#define TESTIDXREADER_H - -#include - -class TestIdxReader : public QObject -{ -Q_OBJECT -public: - TestIdxReader(); -private slots: - void testError(); - void testReadHeader(); - void testRead(); -private: - -}; - -#endif // TESTIDXREADER_H diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildir_debug.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildir_debug.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildir_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildir_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 "mixedmaildir_debug.h" +Q_LOGGING_CATEGORY(MIXEDMAILDIR_LOG, "log_mixedmaildir") + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildir_debug.h kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildir_debug.h --- kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildir_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildir_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 MIXEDMAILDIR_DEBUG_H +#define MIXEDMAILDIR_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(MIXEDMAILDIR_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildirresource.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildirresource.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildirresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildirresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,6 +21,7 @@ */ #include "mixedmaildirresource.h" +#include "mixedmaildir_debug.h" #include "compactchangehelper.h" #include "configdialog.h" @@ -30,7 +31,6 @@ #include "retrieveitemsjob.h" #include "createandsettagsjob.h" - #include "filestore/collectioncreatejob.h" #include "filestore/collectiondeletejob.h" #include "filestore/collectionfetchjob.h" @@ -47,789 +47,785 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include -#include +#include "mixedmaildirresource_debug.h" #include #include #include #include -#include +#include using namespace Akonadi; - - -MixedMaildirResource::MixedMaildirResource( const QString &id ) - : ResourceBase( id ), mStore( new MixedMaildirStore() ), mCompactHelper( 0 ) +MixedMaildirResource::MixedMaildirResource(const QString &id) + : ResourceBase(id), mStore(new MixedMaildirStore()), mCompactHelper(Q_NULLPTR) { - new SettingsAdaptor( Settings::self() ); - QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ), - Settings::self(), QDBusConnection::ExportAdaptors ); - connect( this, SIGNAL(reloadConfiguration()), SLOT(reapplyConfiguration()) ); - - // We need to enable this here, otherwise we neither get the remote ID of the - // parent collection when a collection changes, nor the full item when an item - // is added. - changeRecorder()->fetchCollection( true ); - changeRecorder()->itemFetchScope().fetchFullPayload( true ); - changeRecorder()->itemFetchScope().setAncestorRetrieval( ItemFetchScope::All ); - changeRecorder()->collectionFetchScope().setAncestorRetrieval( CollectionFetchScope::All ); - - setHierarchicalRemoteIdentifiersEnabled( true ); - - if ( ensureSaneConfiguration() ) { - const bool changeName = name().isEmpty() || name() == identifier() || - name() == mStore->topLevelCollection().name(); - mStore->setPath( Settings::self()->path() ); - if ( changeName ) { - setName( mStore->topLevelCollection().name() ); + new SettingsAdaptor(Settings::self()); + QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"), + Settings::self(), QDBusConnection::ExportAdaptors); + connect(this, &MixedMaildirResource::reloadConfiguration, this, &MixedMaildirResource::reapplyConfiguration); + + // We need to enable this here, otherwise we neither get the remote ID of the + // parent collection when a collection changes, nor the full item when an item + // is added. + changeRecorder()->fetchCollection(true); + changeRecorder()->itemFetchScope().fetchFullPayload(true); + changeRecorder()->itemFetchScope().setAncestorRetrieval(ItemFetchScope::All); + changeRecorder()->collectionFetchScope().setAncestorRetrieval(CollectionFetchScope::All); + + setHierarchicalRemoteIdentifiersEnabled(true); + + if (ensureSaneConfiguration()) { + const bool changeName = name().isEmpty() || name() == identifier() || + name() == mStore->topLevelCollection().name(); + mStore->setPath(Settings::self()->path()); + if (changeName) { + setName(mStore->topLevelCollection().name()); + } } - } - const QByteArray compactHelperSessionId = id.toUtf8() + "-compacthelper"; - mCompactHelper = new CompactChangeHelper( compactHelperSessionId, this ); + const QByteArray compactHelperSessionId = id.toUtf8() + "-compacthelper"; + mCompactHelper = new CompactChangeHelper(compactHelperSessionId, this); } MixedMaildirResource::~MixedMaildirResource() { - delete mStore; + delete mStore; } void MixedMaildirResource::aboutToQuit() { - // The settings may not have been saved if e.g. they have been modified via - // DBus instead of the config dialog. - Settings::self()->writeConfig(); + // The settings may not have been saved if e.g. they have been modified via + // DBus instead of the config dialog. + Settings::self()->save(); } -void MixedMaildirResource::configure( WId windowId ) +void MixedMaildirResource::configure(WId windowId) { - ConfigDialog dlg; - if ( windowId ) { - KWindowSystem::setMainWindow( &dlg, windowId ); - } - dlg.setWindowIcon( KIcon( "message-rfc822" ) ); + ConfigDialog dlg; + if (windowId) { + KWindowSystem::setMainWindow(&dlg, windowId); + } + dlg.setWindowIcon(QIcon::fromTheme("message-rfc822")); - bool fullSync = false; + bool fullSync = false; - if ( dlg.exec() ) { - const bool changeName = name().isEmpty() || name() == identifier() || - name() == mStore->topLevelCollection().name(); + if (dlg.exec()) { + const bool changeName = name().isEmpty() || name() == identifier() || + name() == mStore->topLevelCollection().name(); - const QString oldPath = mStore->path(); - mStore->setPath( Settings::self()->path() ); + const QString oldPath = mStore->path(); + mStore->setPath(Settings::self()->path()); - fullSync = oldPath != mStore->path(); + fullSync = oldPath != mStore->path(); - if ( changeName ) { - setName( mStore->topLevelCollection().name() ); + if (changeName) { + setName(mStore->topLevelCollection().name()); + } + Q_EMIT configurationDialogAccepted(); + } else { + Q_EMIT configurationDialogRejected(); } - emit configurationDialogAccepted(); - } else { - emit configurationDialogRejected(); - } - if ( ensureDirExists() ) { - if ( fullSync ) { - mSynchronizedCollections.clear(); - mPendingSynchronizeCollections.clear(); + if (ensureDirExists()) { + if (fullSync) { + mSynchronizedCollections.clear(); + mPendingSynchronizeCollections.clear(); + } + synchronizeCollectionTree(); } - synchronizeCollectionTree(); - } } -void MixedMaildirResource::itemAdded( const Item &item, const Collection& collection ) +void MixedMaildirResource::itemAdded(const Item &item, const Collection &collection) { -/* kDebug() << "item.id=" << item.id() << "col=" << collection.remoteId();*/ - if ( !ensureSaneConfiguration() ) { - const QString message = i18nc( "@info:status", "Unusable configuration." ); - kError() << message; - cancelTask( message ); - return; - } + /* qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "item.id=" << item.id() << "col=" << collection.remoteId();*/ + if (!ensureSaneConfiguration()) { + const QString message = i18nc("@info:status", "Unusable configuration."); + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << message; + cancelTask(message); + return; + } - FileStore::ItemCreateJob *job = mStore->createItem( item, collection ); - connect( job, SIGNAL(result(KJob*)), SLOT(itemAddedResult(KJob*)) ); + FileStore::ItemCreateJob *job = mStore->createItem(item, collection); + connect(job, &FileStore::ItemCreateJob::result, this, &MixedMaildirResource::itemAddedResult); } -void MixedMaildirResource::itemChanged( const Item &item, const QSet& parts ) +void MixedMaildirResource::itemChanged(const Item &item, const QSet &parts) { -/* kDebug() << "item.id=" << item.id() << "col=" << item.parentCollection().remoteId() - << "parts=" << parts;*/ - if ( !ensureSaneConfiguration() ) { - const QString message = i18nc( "@info:status", "Unusable configuration." ); - kError() << message; - cancelTask( message ); - return; - } + /* qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "item.id=" << item.id() << "col=" << item.parentCollection().remoteId() + << "parts=" << parts;*/ + if (!ensureSaneConfiguration()) { + const QString message = i18nc("@info:status", "Unusable configuration."); + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << message; + cancelTask(message); + return; + } - if ( Settings::self()->readOnly() ) { - changeProcessed(); - return; - } + if (Settings::self()->readOnly()) { + changeProcessed(); + return; + } - Item storeItem( item ); - storeItem.setRemoteId( mCompactHelper->currentRemoteId( item ) ); + Item storeItem(item); + storeItem.setRemoteId(mCompactHelper->currentRemoteId(item)); - FileStore::ItemModifyJob *job = mStore->modifyItem( storeItem ); - job->setIgnorePayload( !item.hasPayload() ); - job->setParts( parts ); - job->setProperty( "originalRemoteId", storeItem.remoteId() ); - connect( job, SIGNAL(result(KJob*)), SLOT(itemChangedResult(KJob*)) ); + FileStore::ItemModifyJob *job = mStore->modifyItem(storeItem); + job->setIgnorePayload(!item.hasPayload()); + job->setParts(parts); + job->setProperty("originalRemoteId", storeItem.remoteId()); + connect(job, &FileStore::ItemModifyJob::result, this, &MixedMaildirResource::itemChangedResult); } -void MixedMaildirResource::itemMoved( const Item &item, const Collection &source, const Collection &destination ) +void MixedMaildirResource::itemMoved(const Item &item, const Collection &source, const Collection &destination) { -/* kDebug() << "item.id=" << item.id() << "remoteId=" << item.remoteId() - << "source=" << source.remoteId() << "dest=" << destination.remoteId();*/ - if ( source == destination ) { - changeProcessed(); - return; - } + /* qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "item.id=" << item.id() << "remoteId=" << item.remoteId() + << "source=" << source.remoteId() << "dest=" << destination.remoteId();*/ + if (source == destination) { + changeProcessed(); + return; + } - if ( !ensureSaneConfiguration() ) { - const QString message = i18nc( "@info:status", "Unusable configuration." ); - kError() << message; - cancelTask( message ); - return; - } + if (!ensureSaneConfiguration()) { + const QString message = i18nc("@info:status", "Unusable configuration."); + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << message; + cancelTask(message); + return; + } - Item moveItem = item; - moveItem.setRemoteId( mCompactHelper->currentRemoteId( item ) ); - moveItem.setParentCollection( source ); + Item moveItem = item; + moveItem.setRemoteId(mCompactHelper->currentRemoteId(item)); + moveItem.setParentCollection(source); - FileStore::ItemMoveJob *job = mStore->moveItem( moveItem, destination ); - job->setProperty( "originalRemoteId", moveItem.remoteId() ); - connect( job, SIGNAL(result(KJob*)), SLOT(itemMovedResult(KJob*)) ); + FileStore::ItemMoveJob *job = mStore->moveItem(moveItem, destination); + job->setProperty("originalRemoteId", moveItem.remoteId()); + connect(job, &FileStore::ItemMoveJob::result, this, &MixedMaildirResource::itemMovedResult); } void MixedMaildirResource::itemRemoved(const Item &item) { -/* kDebug() << "item.id=" << item.id() << "col=" << collection.remoteId() - << "collection.remoteRevision=" << item.parentCollection().remoteRevision();*/ - Q_ASSERT( !item.remoteId().isEmpty() ); - Q_ASSERT( item.parentCollection().isValid() ); - if ( item.parentCollection().remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Item %1 belongs to invalid collection %2. Maybe it was deleted meanwhile?", item.id(), item.parentCollection().id() ); - kError() << message; - cancelTask( message ); - return; - } - - if ( !ensureSaneConfiguration() ) { - const QString message = i18nc( "@info:status", "Unusable configuration." ); - kError() << message; - cancelTask( message ); - return; - } - - Item storeItem( item ); - storeItem.setRemoteId( mCompactHelper->currentRemoteId( item ) ); - FileStore::ItemDeleteJob *job = mStore->deleteItem( storeItem ); - connect( job, SIGNAL(result(KJob*)), SLOT(itemRemovedResult(KJob*)) ); + /* qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "item.id=" << item.id() << "col=" << collection.remoteId() + << "collection.remoteRevision=" << item.parentCollection().remoteRevision();*/ + Q_ASSERT(!item.remoteId().isEmpty()); + Q_ASSERT(item.parentCollection().isValid()); + if (item.parentCollection().remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Item %1 belongs to invalid collection %2. Maybe it was deleted meanwhile?", item.id(), item.parentCollection().id()); + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << message; + cancelTask(message); + return; + } + + if (!ensureSaneConfiguration()) { + const QString message = i18nc("@info:status", "Unusable configuration."); + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << message; + cancelTask(message); + return; + } + + Item storeItem(item); + storeItem.setRemoteId(mCompactHelper->currentRemoteId(item)); + FileStore::ItemDeleteJob *job = mStore->deleteItem(storeItem); + connect(job, &FileStore::ItemDeleteJob::result, this, &MixedMaildirResource::itemRemovedResult); } void MixedMaildirResource::retrieveCollections() { - if ( !ensureSaneConfiguration() ) { - const QString message = i18nc( "@info:status", "Unusable configuration." ); - kError() << message; - cancelTask( message ); - return; - } + if (!ensureSaneConfiguration()) { + const QString message = i18nc("@info:status", "Unusable configuration."); + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << message; + cancelTask(message); + return; + } - FileStore::CollectionFetchJob *job = mStore->fetchCollections( mStore->topLevelCollection(), FileStore::CollectionFetchJob::Recursive ); - connect( job, SIGNAL(result(KJob*)), SLOT(retrieveCollectionsResult(KJob*)) ); + FileStore::CollectionFetchJob *job = mStore->fetchCollections(mStore->topLevelCollection(), FileStore::CollectionFetchJob::Recursive); + connect(job, &FileStore::CollectionFetchJob::result, this, &MixedMaildirResource::retrieveCollectionsResult); - status( Running, i18nc( "@info:status", "Synchronizing email folders" ) ); + status(Running, i18nc("@info:status", "Synchronizing email folders")); } -void MixedMaildirResource::retrieveItems( const Collection & col ) +void MixedMaildirResource::retrieveItems(const Collection &col) { - if ( !ensureSaneConfiguration() ) { - const QString message = i18nc( "@info:status", "Unusable configuration." ); - kError() << message; - cancelTask( message ); - return; - } - - RetrieveItemsJob *job = new RetrieveItemsJob( col, mStore, this ); - connect( job, SIGNAL(result(KJob*)), SLOT(retrieveItemsResult(KJob*)) ); + if (!ensureSaneConfiguration()) { + const QString message = i18nc("@info:status", "Unusable configuration."); + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << message; + cancelTask(message); + return; + } + + RetrieveItemsJob *job = new RetrieveItemsJob(col, mStore, this); + connect(job, &RetrieveItemsJob::result, this, &MixedMaildirResource::retrieveItemsResult); - status( Running, i18nc( "@info:status", "Synchronizing email folder %1", col.name() ) ); + status(Running, i18nc("@info:status", "Synchronizing email folder %1", col.name())); } -bool MixedMaildirResource::retrieveItem( const Item &item, const QSet &parts ) +bool MixedMaildirResource::retrieveItem(const Item &item, const QSet &parts) { - Q_UNUSED( parts ); + Q_UNUSED(parts); - FileStore::ItemFetchJob *job = mStore->fetchItem( item ); - if ( parts.contains( Item::FullPayload ) ) { - job->fetchScope().fetchFullPayload( true ); - } else { - Q_FOREACH( const QByteArray &part, parts ) { - job->fetchScope().fetchPayloadPart( part, true ); + FileStore::ItemFetchJob *job = mStore->fetchItem(item); + if (parts.contains(Item::FullPayload)) { + job->fetchScope().fetchFullPayload(true); + } else { + Q_FOREACH (const QByteArray &part, parts) { + job->fetchScope().fetchPayloadPart(part, true); + } } - } - connect( job, SIGNAL(result(KJob*)), SLOT(retrieveItemResult(KJob*)) ); + connect(job, &RetrieveItemsJob::result, this, &MixedMaildirResource::retrieveItemResult); - return true; + return true; } void MixedMaildirResource::collectionAdded(const Collection &collection, const Collection &parent) { - if ( !ensureSaneConfiguration() ) { - const QString message = i18nc( "@info:status", "Unusable configuration." ); - kError() << message; - cancelTask( message ); - return; - } + if (!ensureSaneConfiguration()) { + const QString message = i18nc("@info:status", "Unusable configuration."); + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << message; + cancelTask(message); + return; + } - FileStore::CollectionCreateJob *job = mStore->createCollection( collection, parent ); - connect( job, SIGNAL(result(KJob*)), SLOT(collectionAddedResult(KJob*)) ); + FileStore::CollectionCreateJob *job = mStore->createCollection(collection, parent); + connect(job, &RetrieveItemsJob::result, this, &MixedMaildirResource::collectionAddedResult); } void MixedMaildirResource::collectionChanged(const Collection &collection) { - if ( !ensureSaneConfiguration() ) { - const QString message = i18nc( "@info:status", "Unusable configuration." ); - kError() << message; - cancelTask( message ); - return; - } - - // when the top level collection gets renamed, we do not rename the directory - // but rename the resource. - if ( collection.remoteId() == mStore->topLevelCollection().remoteId() ) { - if ( collection.name() != name() ) { - kDebug() << "TopLevel collection name differs from resource name: collection=" - << collection.name() << "resource=" << name() << ". Renaming resource"; - setName( collection.name() ); - } - changeCommitted( collection ); - return; - } - - mCompactHelper->checkCollectionChanged( collection ); - - FileStore::CollectionModifyJob *job = mStore->modifyCollection( collection ); - connect( job, SIGNAL(result(KJob*)), SLOT(collectionChangedResult(KJob*)) ); -} - -void MixedMaildirResource::collectionChanged(const Collection &collection, const QSet &changedAttributes ) -{ - if ( !ensureSaneConfiguration() ) { - const QString message = i18nc( "@info:status", "Unusable configuration." ); - kError() << message; - cancelTask( message ); - return; - } - - // when the top level collection gets renamed, we do not rename the directory - // but rename the resource. - if ( collection.remoteId() == mStore->topLevelCollection().remoteId() ) { - if ( collection.name() != name() ) { - kDebug() << "TopLevel collection name differs from resource name: collection=" - << collection.name() << "resource=" << name() << ". Renaming resource"; - setName( collection.name() ); - } - changeCommitted( collection ); - return; - } - - mCompactHelper->checkCollectionChanged( collection ); - - Q_UNUSED( changedAttributes ); - - FileStore::CollectionModifyJob *job = mStore->modifyCollection( collection ); - connect( job, SIGNAL(result(KJob*)), SLOT(collectionChangedResult(KJob*)) ); -} - -void MixedMaildirResource::collectionMoved( const Collection &collection, const Collection &source, const Collection &dest ) -{ - //kDebug( KDE_DEFAULT_DEBUG_AREA ) << collection << source << dest; - - if ( !ensureSaneConfiguration() ) { - const QString message = i18nc( "@info:status", "Unusable configuration." ); - kError() << message; - cancelTask( message ); - return; - } - - if ( collection.parentCollection() == Collection::root() ) { - const QString message = i18nc( "@info:status", "Cannot move root maildir folder '%1'." ,collection.remoteId() ); - kError() << message; - cancelTask( message ); - return; - } - - if ( source == dest ) { // should not happen, but who knows... - changeProcessed(); - return; - } - - Collection moveCollection = collection; - moveCollection.setParentCollection( source ); - - FileStore::CollectionMoveJob *job = mStore->moveCollection( moveCollection, dest ); - connect( job, SIGNAL(result(KJob*)), SLOT(collectionMovedResult(KJob*)) ); -} - -void MixedMaildirResource::collectionRemoved( const Collection &collection ) -{ - if ( !ensureSaneConfiguration() ) { - const QString message = i18nc( "@info:status", "Unusable configuration." ); - kError() << message; - cancelTask( message ); - return; - } - - if ( collection.parentCollection() == Collection::root() ) { - emit error( i18n( "Cannot delete top-level maildir folder '%1'.", Settings::self()->path() ) ); - changeProcessed(); - return; - } + if (!ensureSaneConfiguration()) { + const QString message = i18nc("@info:status", "Unusable configuration."); + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << message; + cancelTask(message); + return; + } + + // when the top level collection gets renamed, we do not rename the directory + // but rename the resource. + if (collection.remoteId() == mStore->topLevelCollection().remoteId()) { + if (collection.name() != name()) { + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "TopLevel collection name differs from resource name: collection=" + << collection.name() << "resource=" << name() << ". Renaming resource"; + setName(collection.name()); + } + changeCommitted(collection); + return; + } + + mCompactHelper->checkCollectionChanged(collection); + + FileStore::CollectionModifyJob *job = mStore->modifyCollection(collection); + connect(job, &RetrieveItemsJob::result, this, &MixedMaildirResource::collectionChangedResult); +} + +void MixedMaildirResource::collectionChanged(const Collection &collection, const QSet &changedAttributes) +{ + if (!ensureSaneConfiguration()) { + const QString message = i18nc("@info:status", "Unusable configuration."); + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << message; + cancelTask(message); + return; + } + + // when the top level collection gets renamed, we do not rename the directory + // but rename the resource. + if (collection.remoteId() == mStore->topLevelCollection().remoteId()) { + if (collection.name() != name()) { + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "TopLevel collection name differs from resource name: collection=" + << collection.name() << "resource=" << name() << ". Renaming resource"; + setName(collection.name()); + } + changeCommitted(collection); + return; + } + + mCompactHelper->checkCollectionChanged(collection); + + Q_UNUSED(changedAttributes); + + FileStore::CollectionModifyJob *job = mStore->modifyCollection(collection); + connect(job, &RetrieveItemsJob::result, this, &MixedMaildirResource::collectionChangedResult); +} + +void MixedMaildirResource::collectionMoved(const Collection &collection, const Collection &source, const Collection &dest) +{ + //qCDebug(MIXEDMAILDIR_LOG) << collection << source << dest; + + if (!ensureSaneConfiguration()) { + const QString message = i18nc("@info:status", "Unusable configuration."); + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << message; + cancelTask(message); + return; + } + + if (collection.parentCollection() == Collection::root()) { + const QString message = i18nc("@info:status", "Cannot move root maildir folder '%1'." , collection.remoteId()); + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << message; + cancelTask(message); + return; + } + + if (source == dest) { // should not happen, but who knows... + changeProcessed(); + return; + } + + Collection moveCollection = collection; + moveCollection.setParentCollection(source); + + FileStore::CollectionMoveJob *job = mStore->moveCollection(moveCollection, dest); + connect(job, &RetrieveItemsJob::result, this, &MixedMaildirResource::collectionMovedResult); +} + +void MixedMaildirResource::collectionRemoved(const Collection &collection) +{ + if (!ensureSaneConfiguration()) { + const QString message = i18nc("@info:status", "Unusable configuration."); + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << message; + cancelTask(message); + return; + } + + if (collection.parentCollection() == Collection::root()) { + Q_EMIT error(i18n("Cannot delete top-level maildir folder '%1'.", Settings::self()->path())); + changeProcessed(); + return; + } - FileStore::CollectionDeleteJob *job = mStore->deleteCollection( collection ); - connect( job, SIGNAL(result(KJob*)), SLOT(collectionRemovedResult(KJob*)) ); + FileStore::CollectionDeleteJob *job = mStore->deleteCollection(collection); + connect(job, &RetrieveItemsJob::result, this, &MixedMaildirResource::collectionRemovedResult); } bool MixedMaildirResource::ensureDirExists() { - QDir dir( Settings::self()->path() ); - if ( !dir.exists() ) { - if ( !dir.mkpath( Settings::self()->path() ) ) { - const QString message = i18nc( "@info:status", "Unable to create maildir '%1'.", Settings::self()->path() ); - kError() << message; - status( Broken, message ); - return false; + QDir dir(Settings::self()->path()); + if (!dir.exists()) { + if (!dir.mkpath(Settings::self()->path())) { + const QString message = i18nc("@info:status", "Unable to create maildir '%1'.", Settings::self()->path()); + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << message; + status(Broken, message); + return false; + } } - } - return true; + return true; } bool MixedMaildirResource::ensureSaneConfiguration() { - if ( Settings::self()->path().isEmpty() ) { - const QString message = i18nc( "@info:status", "No usable storage location configured." ); - kError() << message; - status( NotConfigured, message ); - return false; - } - return true; -} - -void MixedMaildirResource::checkForInvalidatedIndexCollections( KJob * job ) -{ - // when operations invalidate the on-disk index, we need to make sure all index - // data has been transferred into Akonadi by synchronizing the collections - const QVariant var = job->property( "onDiskIndexInvalidated" ); - if ( var.isValid() ) { - const Collection::List collections = var.value(); - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "On disk index of" << collections.count() - << "collections invalidated after" << job->metaObject()->className(); - - Q_FOREACH( const Collection &collection, collections ) { - const Collection::Id id = collection.id(); - if ( !mSynchronizedCollections.contains( id ) && !mPendingSynchronizeCollections.contains( id ) ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Requesting sync of collection" << collection.name() - << ", id=" << collection.id(); - mPendingSynchronizeCollections << id; - synchronizeCollection( id ); - } + if (Settings::self()->path().isEmpty()) { + const QString message = i18nc("@info:status", "No usable storage location configured."); + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << message; + status(NotConfigured, message); + return false; + } + return true; +} + +void MixedMaildirResource::checkForInvalidatedIndexCollections(KJob *job) +{ + // when operations invalidate the on-disk index, we need to make sure all index + // data has been transferred into Akonadi by synchronizing the collections + const QVariant var = job->property("onDiskIndexInvalidated"); + if (var.isValid()) { + const Collection::List collections = var.value(); + qCDebug(MIXEDMAILDIR_LOG) << "On disk index of" << collections.count() + << "collections invalidated after" << job->metaObject()->className(); + + Q_FOREACH (const Collection &collection, collections) { + const Collection::Id id = collection.id(); + if (!mSynchronizedCollections.contains(id) && !mPendingSynchronizeCollections.contains(id)) { + qCDebug(MIXEDMAILDIR_LOG) << "Requesting sync of collection" << collection.name() + << ", id=" << collection.id(); + mPendingSynchronizeCollections << id; + synchronizeCollection(id); + } + } } - } } void MixedMaildirResource::reapplyConfiguration() { - if ( ensureSaneConfiguration() && ensureDirExists() ) { - const QString oldPath = mStore->path(); - mStore->setPath( Settings::self()->path() ); - - if ( oldPath != mStore->path() ) { - mSynchronizedCollections.clear(); - mPendingSynchronizeCollections.clear(); + if (ensureSaneConfiguration() && ensureDirExists()) { + const QString oldPath = mStore->path(); + mStore->setPath(Settings::self()->path()); + + if (oldPath != mStore->path()) { + mSynchronizedCollections.clear(); + mPendingSynchronizeCollections.clear(); + } + synchronizeCollectionTree(); } - synchronizeCollectionTree(); - } } -void MixedMaildirResource::retrieveCollectionsResult( KJob *job ) +void MixedMaildirResource::retrieveCollectionsResult(KJob *job) { - if ( job->error() != 0 ) { - kError() << job->errorString(); - status( Broken, job->errorString() ); - cancelTask( job->errorString() ); - return; - } + if (job->error() != 0) { + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << job->errorString(); + status(Broken, job->errorString()); + cancelTask(job->errorString()); + return; + } - FileStore::CollectionFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob != 0 ); + FileStore::CollectionFetchJob *fetchJob = qobject_cast(job); + Q_ASSERT(fetchJob != 0); - Collection topLevelCollection = mStore->topLevelCollection(); - if ( !name().isEmpty() && name() != identifier() ) { - topLevelCollection.setName( name() ); - } + Collection topLevelCollection = mStore->topLevelCollection(); + if (!name().isEmpty() && name() != identifier()) { + topLevelCollection.setName(name()); + } - Collection::List collections; - collections << topLevelCollection; - collections << fetchJob->collections(); - collectionsRetrieved( collections ); + Collection::List collections; + collections << topLevelCollection; + collections << fetchJob->collections(); + collectionsRetrieved(collections); } -void MixedMaildirResource::retrieveItemsResult( KJob *job ) +void MixedMaildirResource::retrieveItemsResult(KJob *job) { - if ( job->error() != 0 ) { - kError() << job->errorString(); - status( Broken, job->errorString() ); - cancelTask( job->errorString() ); - return; - } + if (job->error() != 0) { + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << job->errorString(); + status(Broken, job->errorString()); + cancelTask(job->errorString()); + return; + } - RetrieveItemsJob *retrieveJob = qobject_cast( job ); - Q_ASSERT( retrieveJob != 0 ); + RetrieveItemsJob *retrieveJob = qobject_cast(job); + Q_ASSERT(retrieveJob != 0); - // messages marked as deleted have been deleted from mbox files but never got purged - // TODO FileStore could provide deleteItems() to deleted all filtered items in one go - KJob* deleteJob = 0; - kDebug( KDE_DEFAULT_DEBUG_AREA ) << retrieveJob->itemsMarkedAsDeleted().count() - << "items marked as Deleted"; - Q_FOREACH( const Item &item, retrieveJob->itemsMarkedAsDeleted() ) { - deleteJob = mStore->deleteItem( item ); - } + // messages marked as deleted have been deleted from mbox files but never got purged + // TODO FileStore could provide deleteItems() to deleted all filtered items in one go + KJob *deleteJob = Q_NULLPTR; + qCDebug(MIXEDMAILDIR_LOG) << retrieveJob->itemsMarkedAsDeleted().count() + << "items marked as Deleted"; + Q_FOREACH (const Item &item, retrieveJob->itemsMarkedAsDeleted()) { + deleteJob = mStore->deleteItem(item); + } - if ( deleteJob != 0 ) { - // last item delete triggers mbox purge, i.e. store compact - const bool connected = connect( deleteJob, SIGNAL(result(KJob*)), this, SLOT(itemsDeleted(KJob*)) ); - Q_ASSERT( connected ); - Q_UNUSED( connected ); - } + if (deleteJob != Q_NULLPTR) { + // last item delete triggers mbox purge, i.e. store compact + const bool connected = connect(deleteJob, SIGNAL(result(KJob*)), this, SLOT(itemsDeleted(KJob*))); + Q_ASSERT(connected); + Q_UNUSED(connected); + } - // if some items have tags, we need to complete the retrieval and schedule tagging - // to a later time so we can then fetch the items to get their Akonadi URLs - const Item::List items = retrieveJob->availableItems(); - const QVariant var = retrieveJob->property( "remoteIdToTagList" ); - if ( var.isValid() ) { - const QHash tagListHash = var.value< QHash >(); - if ( !tagListHash.isEmpty() ) { - kDebug() << tagListHash.count() << "of" << items.count() - << "items in collection" << retrieveJob->collection().remoteId() << "have tags"; + // if some items have tags, we need to complete the retrieval and schedule tagging + // to a later time so we can then fetch the items to get their Akonadi URLs + const Item::List items = retrieveJob->availableItems(); + const QVariant var = retrieveJob->property("remoteIdToTagList"); + if (var.isValid()) { + const QHash tagListHash = var.value< QHash >(); + if (!tagListHash.isEmpty()) { + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << tagListHash.count() << "of" << items.count() + << "items in collection" << retrieveJob->collection().remoteId() << "have tags"; - TagContextList taggedItems; - Q_FOREACH( const Item &item, items ) { - const QVariant tagListVar = tagListHash[ item.remoteId() ]; - if ( tagListVar.isValid() ) { - const QStringList tagList = tagListVar.value(); - if ( !tagListHash.isEmpty() ) { - TagContext tag; - tag.mItem = item; - tag.mTagList = tagList; + TagContextList taggedItems; + Q_FOREACH (const Item &item, items) { + const QVariant tagListVar = tagListHash[ item.remoteId() ]; + if (tagListVar.isValid()) { + const QStringList tagList = tagListVar.value(); + if (!tagListHash.isEmpty()) { + TagContext tag; + tag.mItem = item; + tag.mTagList = tagList; - taggedItems << tag; - } - } - } + taggedItems << tag; + } + } + } - if ( !taggedItems.isEmpty() ) { - mTagContextByColId.insert( retrieveJob->collection().id(), taggedItems ); + if (!taggedItems.isEmpty()) { + mTagContextByColId.insert(retrieveJob->collection().id(), taggedItems); - scheduleCustomTask( this, "restoreTags", QVariant::fromValue( retrieveJob->collection() ) ); - } + scheduleCustomTask(this, "restoreTags", QVariant::fromValue(retrieveJob->collection())); + } + } } - } - mSynchronizedCollections << retrieveJob->collection().id(); - mPendingSynchronizeCollections.remove( retrieveJob->collection().id() ); + mSynchronizedCollections << retrieveJob->collection().id(); + mPendingSynchronizeCollections.remove(retrieveJob->collection().id()); - itemsRetrievalDone(); + itemsRetrievalDone(); } -void MixedMaildirResource::retrieveItemResult( KJob *job ) +void MixedMaildirResource::retrieveItemResult(KJob *job) { - if ( job->error() != 0 ) { - kError() << job->errorString(); - status( Broken, job->errorString() ); - cancelTask( job->errorString() ); - return; - } + if (job->error() != 0) { + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << job->errorString(); + status(Broken, job->errorString()); + cancelTask(job->errorString()); + return; + } - FileStore::ItemFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob != 0 ); - Q_ASSERT( !fetchJob->items().isEmpty() ); + FileStore::ItemFetchJob *fetchJob = qobject_cast(job); + Q_ASSERT(fetchJob != 0); + Q_ASSERT(!fetchJob->items().isEmpty()); - itemRetrieved( fetchJob->items()[ 0 ] ); + itemRetrieved(fetchJob->items()[ 0 ]); } -void MixedMaildirResource::itemAddedResult( KJob *job ) +void MixedMaildirResource::itemAddedResult(KJob *job) { - if ( job->error() != 0 ) { - kError() << job->errorString(); - status( Broken, job->errorString() ); - cancelTask( job->errorString() ); - return; - } + if (job->error() != 0) { + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << job->errorString(); + status(Broken, job->errorString()); + cancelTask(job->errorString()); + return; + } - FileStore::ItemCreateJob *itemJob = qobject_cast( job ); - Q_ASSERT( itemJob != 0 ); + FileStore::ItemCreateJob *itemJob = qobject_cast(job); + Q_ASSERT(itemJob != 0); -/* kDebug() << "item.id=" << itemJob->item().id() << "remoteId=" << itemJob->item().remoteId();*/ - changeCommitted( itemJob->item() ); + /* qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "item.id=" << itemJob->item().id() << "remoteId=" << itemJob->item().remoteId();*/ + changeCommitted(itemJob->item()); - checkForInvalidatedIndexCollections( job ); + checkForInvalidatedIndexCollections(job); } -void MixedMaildirResource::itemChangedResult( KJob *job ) +void MixedMaildirResource::itemChangedResult(KJob *job) { - if ( job->error() != 0 ) { - kError() << job->errorString(); - status( Broken, job->errorString() ); - cancelTask( job->errorString() ); - return; - } + if (job->error() != 0) { + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << job->errorString(); + status(Broken, job->errorString()); + cancelTask(job->errorString()); + return; + } - FileStore::ItemModifyJob *itemJob = qobject_cast( job ); - Q_ASSERT( itemJob != 0 ); + FileStore::ItemModifyJob *itemJob = qobject_cast(job); + Q_ASSERT(itemJob != 0); - changeCommitted( itemJob->item() ); + changeCommitted(itemJob->item()); - const QString remoteId = itemJob->property( "originalRemoteId" ).value(); + const QString remoteId = itemJob->property("originalRemoteId").value(); - const QVariant compactStoreVar = itemJob->property( "compactStore" ); - if ( compactStoreVar.isValid() && compactStoreVar.toBool() ) { - scheduleCustomTask( this, "compactStore", QVariant() ); - } + const QVariant compactStoreVar = itemJob->property("compactStore"); + if (compactStoreVar.isValid() && compactStoreVar.toBool()) { + scheduleCustomTask(this, "compactStore", QVariant()); + } - checkForInvalidatedIndexCollections( job ); + checkForInvalidatedIndexCollections(job); } -void MixedMaildirResource::itemMovedResult( KJob *job ) +void MixedMaildirResource::itemMovedResult(KJob *job) { - if ( job->error() != 0 ) { - kError() << job->errorString(); - status( Broken, job->errorString() ); - cancelTask( job->errorString() ); - return; - } + if (job->error() != 0) { + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << job->errorString(); + status(Broken, job->errorString()); + cancelTask(job->errorString()); + return; + } - FileStore::ItemMoveJob *itemJob = qobject_cast( job ); - Q_ASSERT( itemJob != 0 ); + FileStore::ItemMoveJob *itemJob = qobject_cast(job); + Q_ASSERT(itemJob != 0); - changeCommitted( itemJob->item() ); + changeCommitted(itemJob->item()); - const QString remoteId = itemJob->property( "originalRemoteId" ).value(); -// kDebug() << "item.id=" << itemJob->item().id() << "remoteId=" << itemJob->item().remoteId() + const QString remoteId = itemJob->property("originalRemoteId").value(); +// qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "item.id=" << itemJob->item().id() << "remoteId=" << itemJob->item().remoteId() // << "old remoteId=" << remoteId; - const QVariant compactStoreVar = itemJob->property( "compactStore" ); - if ( compactStoreVar.isValid() && compactStoreVar.toBool() ) { - scheduleCustomTask( this, "compactStore", QVariant() ); - } + const QVariant compactStoreVar = itemJob->property("compactStore"); + if (compactStoreVar.isValid() && compactStoreVar.toBool()) { + scheduleCustomTask(this, "compactStore", QVariant()); + } - checkForInvalidatedIndexCollections( job ); + checkForInvalidatedIndexCollections(job); } -void MixedMaildirResource::itemRemovedResult( KJob *job ) +void MixedMaildirResource::itemRemovedResult(KJob *job) { - if ( job->error() != 0 ) { - kError() << job->errorString(); - status( Broken, job->errorString() ); - cancelTask( job->errorString() ); - return; - } + if (job->error() != 0) { + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << job->errorString(); + status(Broken, job->errorString()); + cancelTask(job->errorString()); + return; + } - FileStore::ItemDeleteJob *itemJob = qobject_cast( job ); - Q_ASSERT( itemJob != 0 ); + FileStore::ItemDeleteJob *itemJob = qobject_cast(job); + Q_ASSERT(itemJob != 0); - changeCommitted( itemJob->item() ); + changeCommitted(itemJob->item()); - const QString remoteId = itemJob->item().remoteId(); + const QString remoteId = itemJob->item().remoteId(); - const QVariant compactStoreVar = itemJob->property( "compactStore" ); - if ( compactStoreVar.isValid() && compactStoreVar.toBool() ) { - scheduleCustomTask( this, "compactStore", QVariant() ); - } + const QVariant compactStoreVar = itemJob->property("compactStore"); + if (compactStoreVar.isValid() && compactStoreVar.toBool()) { + scheduleCustomTask(this, "compactStore", QVariant()); + } - checkForInvalidatedIndexCollections( job ); + checkForInvalidatedIndexCollections(job); } -void MixedMaildirResource::itemsDeleted( KJob *job ) +void MixedMaildirResource::itemsDeleted(KJob *job) { - Q_UNUSED( job ); - scheduleCustomTask( this, "compactStore", QVariant() ); + Q_UNUSED(job); + scheduleCustomTask(this, "compactStore", QVariant()); } -void MixedMaildirResource::collectionAddedResult( KJob *job ) +void MixedMaildirResource::collectionAddedResult(KJob *job) { - if ( job->error() != 0 ) { - kError() << job->errorString(); - status( Broken, job->errorString() ); - cancelTask( job->errorString() ); - return; - } + if (job->error() != 0) { + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << job->errorString(); + status(Broken, job->errorString()); + cancelTask(job->errorString()); + return; + } - FileStore::CollectionCreateJob *colJob = qobject_cast( job ); - Q_ASSERT( colJob != 0 ); + FileStore::CollectionCreateJob *colJob = qobject_cast(job); + Q_ASSERT(colJob != 0); - changeCommitted( colJob->collection() ); + changeCommitted(colJob->collection()); } -void MixedMaildirResource::collectionChangedResult( KJob *job ) +void MixedMaildirResource::collectionChangedResult(KJob *job) { - if ( job->error() != 0 ) { - kError() << job->errorString(); - status( Broken, job->errorString() ); - cancelTask( job->errorString() ); - return; - } + if (job->error() != 0) { + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << job->errorString(); + status(Broken, job->errorString()); + cancelTask(job->errorString()); + return; + } - FileStore::CollectionModifyJob *colJob = qobject_cast( job ); - Q_ASSERT( colJob != 0 ); + FileStore::CollectionModifyJob *colJob = qobject_cast(job); + Q_ASSERT(colJob != 0); - changeCommitted( colJob->collection() ); + changeCommitted(colJob->collection()); - checkForInvalidatedIndexCollections( job ); + checkForInvalidatedIndexCollections(job); } -void MixedMaildirResource::collectionMovedResult( KJob *job ) +void MixedMaildirResource::collectionMovedResult(KJob *job) { - if ( job->error() != 0 ) { - kError() << job->errorString(); - status( Broken, job->errorString() ); - cancelTask( job->errorString() ); - return; - } + if (job->error() != 0) { + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << job->errorString(); + status(Broken, job->errorString()); + cancelTask(job->errorString()); + return; + } - FileStore::CollectionMoveJob *colJob = qobject_cast( job ); - Q_ASSERT( colJob != 0 ); + FileStore::CollectionMoveJob *colJob = qobject_cast(job); + Q_ASSERT(colJob != 0); - changeCommitted( colJob->collection() ); + changeCommitted(colJob->collection()); - checkForInvalidatedIndexCollections( job ); + checkForInvalidatedIndexCollections(job); } -void MixedMaildirResource::collectionRemovedResult( KJob *job ) +void MixedMaildirResource::collectionRemovedResult(KJob *job) { - if ( job->error() != 0 ) { - kError() << job->errorString(); - status( Broken, job->errorString() ); - cancelTask( job->errorString() ); - return; - } + if (job->error() != 0) { + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << job->errorString(); + status(Broken, job->errorString()); + cancelTask(job->errorString()); + return; + } - FileStore::CollectionDeleteJob *colJob = qobject_cast( job ); - Q_ASSERT( colJob != 0 ); + FileStore::CollectionDeleteJob *colJob = qobject_cast(job); + Q_ASSERT(colJob != 0); - changeCommitted( colJob->collection() ); + changeCommitted(colJob->collection()); } -void MixedMaildirResource::compactStore( const QVariant &arg ) +void MixedMaildirResource::compactStore(const QVariant &arg) { - Q_UNUSED( arg ); + Q_UNUSED(arg); - FileStore::StoreCompactJob *job = mStore->compactStore(); - connect( job, SIGNAL(result(KJob*)), SLOT(compactStoreResult(KJob*)) ); + FileStore::StoreCompactJob *job = mStore->compactStore(); + connect(job, &RetrieveItemsJob::result, this, &MixedMaildirResource::compactStoreResult); } -void MixedMaildirResource::compactStoreResult( KJob *job ) +void MixedMaildirResource::compactStoreResult(KJob *job) { - if ( job->error() != 0 ) { - kError() << job->errorString(); - status( Broken, job->errorString() ); - cancelTask( job->errorString() ); - return; - } + if (job->error() != 0) { + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << job->errorString(); + status(Broken, job->errorString()); + cancelTask(job->errorString()); + return; + } - FileStore::StoreCompactJob *compactJob = qobject_cast( job ); - Q_ASSERT( compactJob != 0 ); + FileStore::StoreCompactJob *compactJob = qobject_cast(job); + Q_ASSERT(compactJob != 0); - const Item::List items = compactJob->changedItems(); - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Compacting store resulted in" << items.count() << "changed items"; + const Item::List items = compactJob->changedItems(); + qCDebug(MIXEDMAILDIR_LOG) << "Compacting store resulted in" << items.count() << "changed items"; - mCompactHelper->addChangedItems( items ); + mCompactHelper->addChangedItems(items); - taskDone(); + taskDone(); - checkForInvalidatedIndexCollections( job ); + checkForInvalidatedIndexCollections(job); } -void MixedMaildirResource::restoreTags( const QVariant &arg ) +void MixedMaildirResource::restoreTags(const QVariant &arg) { - if ( !arg.isValid() ) { - kError() << "Given variant is not valid"; - cancelTask(); - return; - } + if (!arg.isValid()) { + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << "Given variant is not valid"; + cancelTask(); + return; + } - const Collection collection = arg.value(); - if ( !collection.isValid() ) { - kError() << "Given variant is not valid"; - cancelTask(); - return; - } + const Collection collection = arg.value(); + if (!collection.isValid()) { + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << "Given variant is not valid"; + cancelTask(); + return; + } - const TagContextList taggedItems = mTagContextByColId[ collection.id() ]; - mPendingTagContexts << taggedItems; + const TagContextList taggedItems = mTagContextByColId[ collection.id() ]; + mPendingTagContexts << taggedItems; - QMetaObject::invokeMethod( this, "processNextTagContext", Qt::QueuedConnection ); - taskDone(); + QMetaObject::invokeMethod(this, "processNextTagContext", Qt::QueuedConnection); + taskDone(); } void MixedMaildirResource::processNextTagContext() { - kDebug() << mPendingTagContexts.count() << "items to go"; - if ( mPendingTagContexts.isEmpty() ) { - return; - } + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << mPendingTagContexts.count() << "items to go"; + if (mPendingTagContexts.isEmpty()) { + return; + } - const TagContext tagContext = mPendingTagContexts.front(); - mPendingTagContexts.pop_front(); + const TagContext tagContext = mPendingTagContexts.front(); + mPendingTagContexts.pop_front(); - ItemFetchJob *fetchJob = new ItemFetchJob( tagContext.mItem ); - fetchJob->setProperty( "tagList", tagContext.mTagList ); - connect( fetchJob, SIGNAL(result(KJob*)), SLOT(tagFetchJobResult(KJob*)) ); + ItemFetchJob *fetchJob = new ItemFetchJob(tagContext.mItem); + fetchJob->setProperty("tagList", tagContext.mTagList); + connect(fetchJob, &ItemFetchJob::result, this, &MixedMaildirResource::tagFetchJobResult); } -void MixedMaildirResource::tagFetchJobResult( KJob *job ) +void MixedMaildirResource::tagFetchJobResult(KJob *job) { - if ( job->error() != 0 ) { - kError() << job->errorString(); - processNextTagContext(); - return; - } + if (job->error() != 0) { + qCCritical(MIXEDMAILDIRRESOURCE_LOG) << job->errorString(); + processNextTagContext(); + return; + } - ItemFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob != 0 ); + ItemFetchJob *fetchJob = qobject_cast(job); + Q_ASSERT(fetchJob != 0); - Q_ASSERT( !fetchJob->items().isEmpty() ); + Q_ASSERT(!fetchJob->items().isEmpty()); - const Item item = fetchJob->items()[ 0 ]; - const QStringList tagList = job->property( "tagList" ).value(); - kDebug() << "Tagging item" << item.url() << "with" << tagList; - - Akonadi::Tag::List tags; - Q_FOREACH( const QString &tag, tagList ) { - if ( tag.isEmpty() ) { - kWarning() << "TagList for item" << item.url() << "contains an empty tag"; - } else { - tags << Akonadi::Tag(tag); + const Item item = fetchJob->items()[ 0 ]; + const QStringList tagList = job->property("tagList").value(); + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "Tagging item" << item.url() << "with" << tagList; + + Akonadi::Tag::List tags; + Q_FOREACH (const QString &tag, tagList) { + if (tag.isEmpty()) { + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "TagList for item" << item.url() << "contains an empty tag"; + } else { + tags << Akonadi::Tag(tag); + } } - } - new CreateAndSetTagsJob(item, tags); + new CreateAndSetTagsJob(item, tags); - processNextTagContext(); + processNextTagContext(); } +AKONADI_RESOURCE_MAIN(MixedMaildirResource) -AKONADI_RESOURCE_MAIN( MixedMaildirResource ) - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildirresource_debug.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildirresource_debug.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildirresource_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildirresource_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 "mixedmaildirresource_debug.h" +Q_LOGGING_CATEGORY(MIXEDMAILDIRRESOURCE_LOG, "log_mixedmaildirresource") + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildirresource_debug.h kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildirresource_debug.h --- kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildirresource_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildirresource_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 MIXEDMAILDIRRESOURCE_DEBUG_H +#define MIXEDMAILDIRRESOURCE_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(MIXEDMAILDIRRESOURCE_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildirresource.desktop kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildirresource.desktop --- kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildirresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildirresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,6 @@ [Desktop Entry] Name=KMail Mail Folder +Name[bg]=Папка с поща на KMail Name[bs]=KMail fascikla pošte Name[ca]=Carpeta de correu del KMail Name[ca@valencia]=Carpeta de correu del KMail @@ -42,6 +43,7 @@ Name[zh_CN]=KMail 邮件文件夹 Name[zh_TW]=KMail 資料夾 Comment=Loads data from a local KMail mail folder +Comment[bg]=Зареждане на данни от локална папка с поща на KMail Comment[bs]=Učitava podatke iz lokalne fascikle KMail pošte Comment[ca]=Carrega les dades des d'una carpeta local de correu del KMail Comment[ca@valencia]=Carrega dades des d'una carpeta local de correu del KMail diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildirresource.h kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildirresource.h --- kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildirresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildirresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,7 +22,7 @@ #ifndef MIXEDMAILDIR_RESOURCE_H #define MIXEDMAILDIR_RESOURCE_H -#include +#include #include @@ -31,73 +31,72 @@ class MixedMaildirResource : public Akonadi::ResourceBase, public Akonadi::AgentBase::ObserverV2 { - Q_OBJECT + Q_OBJECT - public: - explicit MixedMaildirResource( const QString &id ); +public: + explicit MixedMaildirResource(const QString &id); ~MixedMaildirResource(); - public Q_SLOTS: - void configure( WId windowId ); +public Q_SLOTS: + void configure(WId windowId) Q_DECL_OVERRIDE; - protected Q_SLOTS: - void retrieveCollections(); - void retrieveItems( const Akonadi::Collection &col ); - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - - protected: - void aboutToQuit(); - - void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - void itemChanged( const Akonadi::Item &item, const QSet &parts ); - void itemMoved( const Akonadi::Item &item, const Akonadi::Collection &source, const Akonadi::Collection &dest ); - void itemRemoved( const Akonadi::Item &item ); - - void collectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection &parent ); - void collectionChanged( const Akonadi::Collection &collection ); - void collectionChanged( const Akonadi::Collection &collection, const QSet &changedAttributes ); - void collectionMoved( const Akonadi::Collection &collection, const Akonadi::Collection &source, const Akonadi::Collection &dest ); - void collectionRemoved( const Akonadi::Collection &collection ); +protected Q_SLOTS: + void retrieveCollections() Q_DECL_OVERRIDE; + void retrieveItems(const Akonadi::Collection &col) Q_DECL_OVERRIDE; + bool retrieveItem(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + +protected: + void aboutToQuit() Q_DECL_OVERRIDE; + + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + void itemMoved(const Akonadi::Item &item, const Akonadi::Collection &source, const Akonadi::Collection &dest) Q_DECL_OVERRIDE; + void itemRemoved(const Akonadi::Item &item) Q_DECL_OVERRIDE; + + void collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent) Q_DECL_OVERRIDE; + void collectionChanged(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void collectionChanged(const Akonadi::Collection &collection, const QSet &changedAttributes) Q_DECL_OVERRIDE; + void collectionMoved(const Akonadi::Collection &collection, const Akonadi::Collection &source, const Akonadi::Collection &dest) Q_DECL_OVERRIDE; + void collectionRemoved(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; - private: +private: bool ensureDirExists(); bool ensureSaneConfiguration(); - void checkForInvalidatedIndexCollections( KJob * job ); + void checkForInvalidatedIndexCollections(KJob *job); - private Q_SLOTS: +private Q_SLOTS: void reapplyConfiguration(); - void retrieveCollectionsResult( KJob *job ); - void retrieveItemsResult( KJob *job ); - void retrieveItemResult( KJob *job ); - - void itemAddedResult( KJob *job ); - void itemChangedResult( KJob *job ); - void itemMovedResult( KJob *job ); - void itemRemovedResult( KJob *job ); - - void itemsDeleted( KJob *job ); - - void collectionAddedResult( KJob *job ); - void collectionChangedResult( KJob *job ); - void collectionMovedResult( KJob *job ); - void collectionRemovedResult( KJob *job ); + void retrieveCollectionsResult(KJob *job); + void retrieveItemsResult(KJob *job); + void retrieveItemResult(KJob *job); + + void itemAddedResult(KJob *job); + void itemChangedResult(KJob *job); + void itemMovedResult(KJob *job); + void itemRemovedResult(KJob *job); + + void itemsDeleted(KJob *job); + + void collectionAddedResult(KJob *job); + void collectionChangedResult(KJob *job); + void collectionMovedResult(KJob *job); + void collectionRemovedResult(KJob *job); - void compactStore( const QVariant &arg ); - void compactStoreResult( KJob *job ); + void compactStore(const QVariant &arg); + void compactStoreResult(KJob *job); - void restoreTags( const QVariant &arg ); + void restoreTags(const QVariant &arg); void processNextTagContext(); - void tagFetchJobResult( KJob *job ); + void tagFetchJobResult(KJob *job); - private: +private: MixedMaildirStore *mStore; - struct TagContext - { - Akonadi::Item mItem; - QStringList mTagList; + struct TagContext { + Akonadi::Item mItem; + QStringList mTagList; }; typedef QList TagContextList; @@ -112,4 +111,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildirstore.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildirstore.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildirstore.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildirstore.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,6 +21,7 @@ #include "mixedmaildirstore.h" #include "kmindexreader/kmindexreader.h" +#include "mixedmaildir_debug.h" #include "filestore/collectioncreatejob.h" #include "filestore/collectiondeletejob.h" @@ -40,16 +41,15 @@ #include #include -#include -#include - -#include -#include - -#include +#include +#include +#include +#include #include +#include "mixedmaildirresource_debug.h" + #include #include #include @@ -58,200 +58,208 @@ using KPIM::Maildir; using namespace KMBox; -static bool fullEntryCompare( const KMBox::MBoxEntry &left, const KMBox::MBoxEntry &right ) +static bool fullEntryCompare(const KMBox::MBoxEntry &left, const KMBox::MBoxEntry &right) { - return ( left.messageOffset() == right.messageOffset() && - left.separatorSize() == right.separatorSize() && - left.messageSize() == right.messageSize() ); + return (left.messageOffset() == right.messageOffset() && + left.separatorSize() == right.separatorSize() && + left.messageSize() == right.messageSize()); } -static bool indexFileForFolder( const QFileInfo &folderDirInfo, QFileInfo &indexFileInfo ) +static bool indexFileForFolder(const QFileInfo &folderDirInfo, QFileInfo &indexFileInfo) { - indexFileInfo = QFileInfo( folderDirInfo.dir(), QString::fromUtf8( ".%1.index" ).arg( folderDirInfo.fileName() ) ); + indexFileInfo = QFileInfo(folderDirInfo.dir(), QString::fromUtf8(".%1.index").arg(folderDirInfo.fileName())); - if ( !indexFileInfo.exists() || !indexFileInfo.isReadable() ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "No index file" << indexFileInfo.absoluteFilePath() << "or not readable"; - return false; - } + if (!indexFileInfo.exists() || !indexFileInfo.isReadable()) { + qCDebug(MIXEDMAILDIR_LOG) << "No index file" << indexFileInfo.absoluteFilePath() << "or not readable"; + return false; + } - return true; + return true; } class MBoxContext { - public: - MBoxContext() : mRevision( 0 ), mIndexDataLoaded( false ), mHasIndexData( false ) {} +public: + MBoxContext() : mRevision(0), mIndexDataLoaded(false), mHasIndexData(false) {} QString fileName() const { - return mMBox.fileName(); + return mMBox.fileName(); } - bool load( const QString &fileName ) + bool load(const QString &fileName) { - mModificationTime = QFileInfo( fileName ).lastModified(); + mModificationTime = QFileInfo(fileName).lastModified(); - // in case of reload, check if anything changed, otherwise keep deleted entries - if ( !mDeletedOffsets.isEmpty() && fileName == mMBox.fileName() ) { - const KMBox::MBoxEntry::List currentEntryList = mMBox.entries(); - if ( mMBox.load( fileName ) ) { - const KMBox::MBoxEntry::List newEntryList = mMBox.entries(); - if ( !std::equal( currentEntryList.begin(), currentEntryList.end(), newEntryList.begin(), fullEntryCompare ) ) { - mDeletedOffsets.clear(); - } - return true; - } + // in case of reload, check if anything changed, otherwise keep deleted entries + if (!mDeletedOffsets.isEmpty() && fileName == mMBox.fileName()) { + const KMBox::MBoxEntry::List currentEntryList = mMBox.entries(); + if (mMBox.load(fileName)) { + const KMBox::MBoxEntry::List newEntryList = mMBox.entries(); + if (!std::equal(currentEntryList.begin(), currentEntryList.end(), newEntryList.begin(), fullEntryCompare)) { + mDeletedOffsets.clear(); + } + return true; + } - return false; - } + return false; + } - mDeletedOffsets.clear(); - return mMBox.load( fileName ); + mDeletedOffsets.clear(); + return mMBox.load(fileName); } - QDateTime modificationTime() const { return mModificationTime; } + QDateTime modificationTime() const + { + return mModificationTime; + } KMBox::MBoxEntry::List entryList() const { - KMBox::MBoxEntry::List result; - Q_FOREACH( const KMBox::MBoxEntry &entry, mMBox.entries() ) { - if ( !mDeletedOffsets.contains( entry.messageOffset() ) ) { - result << entry; + KMBox::MBoxEntry::List result; + Q_FOREACH (const KMBox::MBoxEntry &entry, mMBox.entries()) { + if (!mDeletedOffsets.contains(entry.messageOffset())) { + result << entry; + } } - } - return result; + return result; } - QByteArray readRawEntry( quint64 offset ) + QByteArray readRawEntry(quint64 offset) { - return mMBox.readRawMessage( KMBox::MBoxEntry( offset ) ); + return mMBox.readRawMessage(KMBox::MBoxEntry(offset)); } - QByteArray readEntryHeaders( quint64 offset ) + QByteArray readEntryHeaders(quint64 offset) { - return mMBox.readMessageHeaders( KMBox::MBoxEntry( offset ) ); + return mMBox.readMessageHeaders(KMBox::MBoxEntry(offset)); } - qint64 appendEntry( const KMime::Message::Ptr &entry ) + qint64 appendEntry(const KMime::Message::Ptr &entry) { - const KMBox::MBoxEntry result = mMBox.appendMessage( entry ); - if ( result.isValid() && mHasIndexData ) { - mIndexData.insert( result.messageOffset(), KMIndexDataPtr( new KMIndexData ) ); - Q_ASSERT( mIndexData.value( result.messageOffset() )->isEmpty() ); - } + const KMBox::MBoxEntry result = mMBox.appendMessage(entry); + if (result.isValid() && mHasIndexData) { + mIndexData.insert(result.messageOffset(), KMIndexDataPtr(new KMIndexData)); + Q_ASSERT(mIndexData.value(result.messageOffset())->isEmpty()); + } - return result.messageOffset(); + return result.messageOffset(); } - void deleteEntry( quint64 offset ) + void deleteEntry(quint64 offset) { - mDeletedOffsets << offset; + mDeletedOffsets << offset; } - bool isValidOffset( quint64 offset ) const + bool isValidOffset(quint64 offset) const { - if ( mDeletedOffsets.contains( offset ) ) { - return false; - } + if (mDeletedOffsets.contains(offset)) { + return false; + } - Q_FOREACH( const KMBox::MBoxEntry &entry, mMBox.entries() ) { - if ( entry.messageOffset() == offset ) { - return true; + Q_FOREACH (const KMBox::MBoxEntry &entry, mMBox.entries()) { + if (entry.messageOffset() == offset) { + return true; + } } - } - return false; + return false; } bool save() { - bool ret = mMBox.save(); - mModificationTime = QDateTime::currentDateTime(); - return ret; + bool ret = mMBox.save(); + mModificationTime = QDateTime::currentDateTime(); + return ret; } - int purge( QList &movedEntries ) + int purge(QList &movedEntries) { - const int deleteCount = mDeletedOffsets.count(); - - KMBox::MBoxEntry::List deletedEntries; - Q_FOREACH( quint64 offset, mDeletedOffsets ) - deletedEntries << KMBox::MBoxEntry( offset ); + const int deleteCount = mDeletedOffsets.count(); - const bool result = mMBox.purge( deletedEntries, &movedEntries ); - - if ( mHasIndexData ) { - // keep copy of original for lookup - const IndexDataHash indexData = mIndexData; - - // delete index data for removed entries - Q_FOREACH( quint64 offset, mDeletedOffsets ) { - mIndexData.remove( offset ); + KMBox::MBoxEntry::List deletedEntries; + deletedEntries.reserve(deleteCount); + Q_FOREACH (quint64 offset, mDeletedOffsets) { + deletedEntries << KMBox::MBoxEntry(offset); } - // delete index data for changed entries - // readded below in an extra loop to handled cases where a new index is equal to an - // old index of a different entry - Q_FOREACH( const KMBox::MBoxEntry::Pair &entry, movedEntries ) { - mIndexData.remove( entry.first.messageOffset() ); - } + const bool result = mMBox.purge(deletedEntries, &movedEntries); - // readd index data for changed entries at their new position - Q_FOREACH( const KMBox::MBoxEntry::Pair &entry, movedEntries ) { - const KMIndexDataPtr data = indexData.value( entry.first.messageOffset() ); - mIndexData.insert( entry.second.messageOffset(), data ); + if (mHasIndexData) { + // keep copy of original for lookup + const IndexDataHash indexData = mIndexData; + + // delete index data for removed entries + Q_FOREACH (quint64 offset, mDeletedOffsets) { + mIndexData.remove(offset); + } + + // delete index data for changed entries + // readded below in an extra loop to handled cases where a new index is equal to an + // old index of a different entry + Q_FOREACH (const KMBox::MBoxEntry::Pair &entry, movedEntries) { + mIndexData.remove(entry.first.messageOffset()); + } + + // readd index data for changed entries at their new position + Q_FOREACH (const KMBox::MBoxEntry::Pair &entry, movedEntries) { + const KMIndexDataPtr data = indexData.value(entry.first.messageOffset()); + mIndexData.insert(entry.second.messageOffset(), data); + } } - } - mDeletedOffsets.clear(); - mModificationTime = QDateTime::currentDateTime(); - return ( result ? deleteCount : -1 ); + mDeletedOffsets.clear(); + mModificationTime = QDateTime::currentDateTime(); + return (result ? deleteCount : -1); } MBox &mbox() { - return mMBox; + return mMBox; } const MBox &mbox() const { - return mMBox; + return mMBox; } bool hasDeletedOffsets() const { - return !mDeletedOffsets.isEmpty(); + return !mDeletedOffsets.isEmpty(); } void readIndexData(); - KMIndexDataPtr indexData( quint64 offset ) const { - if ( mHasIndexData ) { - if ( !mDeletedOffsets.contains( offset ) ) { - IndexDataHash::const_iterator it = mIndexData.constFind( offset ); - if ( it != mIndexData.constEnd() ) { - return it.value(); - } + KMIndexDataPtr indexData(quint64 offset) const + { + if (mHasIndexData) { + if (!mDeletedOffsets.contains(offset)) { + IndexDataHash::const_iterator it = mIndexData.constFind(offset); + if (it != mIndexData.constEnd()) { + return it.value(); + } + } } - } - return KMIndexDataPtr(); + return KMIndexDataPtr(); } - bool hasIndexData() const { - return mHasIndexData; + bool hasIndexData() const + { + return mHasIndexData; } - void updatePath( const QString &newPath ) { - // TODO FIXME there has to be a better of doing that - mMBox.load( newPath ); + void updatePath(const QString &newPath) + { + // TODO FIXME there has to be a better of doing that + mMBox.load(newPath); } - public: +public: Collection mCollection; qint64 mRevision; - private: +private: QSet mDeletedOffsets; MBox mMBox; QDateTime mModificationTime; @@ -266,157 +274,170 @@ void MBoxContext::readIndexData() { - if ( mIndexDataLoaded ) { - return; - } - - mIndexDataLoaded = true; - - const QFileInfo mboxFileInfo( mMBox.fileName() ); - QFileInfo indexFileInfo; - if ( !indexFileForFolder( mboxFileInfo, indexFileInfo ) ) { - return; - } - - if ( mboxFileInfo.lastModified() > indexFileInfo.lastModified() ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "MBox file " << mboxFileInfo.absoluteFilePath() - << "newer than the index: mbox modified at" - << mboxFileInfo.lastModified() << ", index modified at" - << indexFileInfo.lastModified(); - return; - } - - KMIndexReader indexReader( indexFileInfo.absoluteFilePath() ); - if ( indexReader.error() || !indexReader.readIndex() ) { - kError() << "Index file" << indexFileInfo.path() << "could not be read"; - return; - } - - mHasIndexData = true; - - const KMBox::MBoxEntry::List entries = mMBox.entries(); - Q_FOREACH( const KMBox::MBoxEntry &entry, entries ) { - const quint64 indexOffset = entry.messageOffset() + entry.separatorSize(); - const KMIndexDataPtr data = indexReader.dataByOffset( indexOffset ); - if ( data != 0 ) { - mIndexData.insert( entry.messageOffset(), data ); + if (mIndexDataLoaded) { + return; + } + + mIndexDataLoaded = true; + + const QFileInfo mboxFileInfo(mMBox.fileName()); + QFileInfo indexFileInfo; + if (!indexFileForFolder(mboxFileInfo, indexFileInfo)) { + return; } - } - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Read" << mIndexData.count() << "index entries from" - << indexFileInfo.absoluteFilePath(); + if (mboxFileInfo.lastModified() > indexFileInfo.lastModified()) { + qCDebug(MIXEDMAILDIR_LOG) << "MBox file " << mboxFileInfo.absoluteFilePath() + << "newer than the index: mbox modified at" + << mboxFileInfo.lastModified() << ", index modified at" + << indexFileInfo.lastModified(); + return; + } + + KMIndexReader indexReader(indexFileInfo.absoluteFilePath()); + if (indexReader.error() || !indexReader.readIndex()) { + qCritical() << "Index file" << indexFileInfo.path() << "could not be read"; + return; + } + + mHasIndexData = true; + + const KMBox::MBoxEntry::List entries = mMBox.entries(); + Q_FOREACH (const KMBox::MBoxEntry &entry, entries) { + const quint64 indexOffset = entry.messageOffset() + entry.separatorSize(); + const KMIndexDataPtr data = indexReader.dataByOffset(indexOffset); + if (data != Q_NULLPTR) { + mIndexData.insert(entry.messageOffset(), data); + } + } + + qCDebug(MIXEDMAILDIR_LOG) << "Read" << mIndexData.count() << "index entries from" + << indexFileInfo.absoluteFilePath(); } class MaildirContext { - public: - MaildirContext( const QString &path, bool isTopLevel ) - : mMaildir( path, isTopLevel ), mIndexDataLoaded( false ), mHasIndexData( false ) +public: + MaildirContext(const QString &path, bool isTopLevel) + : mMaildir(path, isTopLevel), mIndexDataLoaded(false), mHasIndexData(false) { } - MaildirContext( const Maildir &md ) - : mMaildir( md ), mIndexDataLoaded( false ), mHasIndexData( false ) + MaildirContext(const Maildir &md) + : mMaildir(md), mIndexDataLoaded(false), mHasIndexData(false) { } - QStringList entryList() const { - return mMaildir.entryList(); + QStringList entryList() const + { + return mMaildir.entryList(); } - QString addEntry( const QByteArray &data ) { - const QString result = mMaildir.addEntry( data ); - if ( !result.isEmpty() && mHasIndexData ) { - mIndexData.insert( result, KMIndexDataPtr( new KMIndexData ) ); - Q_ASSERT( mIndexData.value( result )->isEmpty() ); - } else { - //TODO: use the error string? - kWarning() << mMaildir.lastError(); - } + QString addEntry(const QByteArray &data) + { + const QString result = mMaildir.addEntry(data); + if (!result.isEmpty() && mHasIndexData) { + mIndexData.insert(result, KMIndexDataPtr(new KMIndexData)); + Q_ASSERT(mIndexData.value(result)->isEmpty()); + } else { + //TODO: use the error string? + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << mMaildir.lastError(); + } - return result; + return result; } - void writeEntry( const QString &key, const QByteArray &data ) { - mMaildir.writeEntry( key, data ); //TODO: error handling - if ( mHasIndexData ) { - mIndexData.insert( key, KMIndexDataPtr( new KMIndexData ) ); - } + void writeEntry(const QString &key, const QByteArray &data) + { + mMaildir.writeEntry(key, data); //TODO: error handling + if (mHasIndexData) { + mIndexData.insert(key, KMIndexDataPtr(new KMIndexData)); + } } - bool removeEntry( const QString &key ) { - const bool result = mMaildir.removeEntry( key ); - if ( result && mHasIndexData ) { - mIndexData.remove( key ); - } + bool removeEntry(const QString &key) + { + const bool result = mMaildir.removeEntry(key); + if (result && mHasIndexData) { + mIndexData.remove(key); + } - return result; + return result; } - QString moveEntryTo( const QString &key, MaildirContext &destination ) { - const QString result = mMaildir.moveEntryTo( key, destination.mMaildir ); - if ( !result.isEmpty() ) { - if ( mHasIndexData ) { - mIndexData.remove( key ); - } - - if ( destination.mHasIndexData ) { - destination.mIndexData.insert( result, KMIndexDataPtr( new KMIndexData ) ); + QString moveEntryTo(const QString &key, MaildirContext &destination) + { + const QString result = mMaildir.moveEntryTo(key, destination.mMaildir); + if (!result.isEmpty()) { + if (mHasIndexData) { + mIndexData.remove(key); + } + + if (destination.mHasIndexData) { + destination.mIndexData.insert(result, KMIndexDataPtr(new KMIndexData)); + } + } else { + //TODO error handling? + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << mMaildir.lastError(); } - } else { - //TODO error handling? - kWarning() << mMaildir.lastError(); - } - return result; + return result; } - QByteArray readEntryHeaders( const QString &key ) const { - return mMaildir.readEntryHeaders( key ); + QByteArray readEntryHeaders(const QString &key) const + { + return mMaildir.readEntryHeaders(key); } - QByteArray readEntry( const QString &key ) const { - return mMaildir.readEntry( key ); + QByteArray readEntry(const QString &key) const + { + return mMaildir.readEntry(key); } - bool isValid( QString &error ) const { - bool result = mMaildir.isValid(); - if ( !result ) { - error = mMaildir.lastError(); - } - return result; + bool isValid(QString &error) const + { + bool result = mMaildir.isValid(); + if (!result) { + error = mMaildir.lastError(); + } + return result; } - bool isValidEntry( const QString &entry ) const { - return !mMaildir.findRealKey( entry ).isEmpty(); + bool isValidEntry(const QString &entry) const + { + return !mMaildir.findRealKey(entry).isEmpty(); } void readIndexData(); - KMIndexDataPtr indexData( const QString &fileName ) const { - if ( mHasIndexData ) { - IndexDataHash::const_iterator it = mIndexData.constFind( fileName ); - if ( it != mIndexData.constEnd() ) { - return it.value(); + KMIndexDataPtr indexData(const QString &fileName) const + { + if (mHasIndexData) { + IndexDataHash::const_iterator it = mIndexData.constFind(fileName); + if (it != mIndexData.constEnd()) { + return it.value(); + } } - } - return KMIndexDataPtr(); + return KMIndexDataPtr(); } - bool hasIndexData() const { - return mHasIndexData; + bool hasIndexData() const + { + return mHasIndexData; } - void updatePath( const QString &newPath ) { - mMaildir = Maildir( newPath, mMaildir.isRoot() ); + void updatePath(const QString &newPath) + { + mMaildir = Maildir(newPath, mMaildir.isRoot()); } - const Maildir & maildir() const { + const Maildir &maildir() const + { return mMaildir; } - private: +private: Maildir mMaildir; typedef QHash IndexDataHash; @@ -427,104 +448,103 @@ void MaildirContext::readIndexData() { - if ( mIndexDataLoaded ) { - return; - } - - mIndexDataLoaded = true; - - const QFileInfo maildirFileInfo( mMaildir.path() ); - QFileInfo indexFileInfo; - if ( !indexFileForFolder( maildirFileInfo, indexFileInfo ) ) { - return; - } - - const QDir maildirBaseDir( maildirFileInfo.absoluteFilePath() ); - const QFileInfo curDirFileInfo( maildirBaseDir, QLatin1String( "cur" ) ); - const QFileInfo newDirFileInfo( maildirBaseDir, QLatin1String( "new" ) ); - - if ( curDirFileInfo.lastModified() > indexFileInfo.lastModified() ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Maildir " << maildirFileInfo.absoluteFilePath() - << "\"cur\" directory newer than the index: cur modified at" - << curDirFileInfo.lastModified() << ", index modified at" - << indexFileInfo.lastModified(); - return; - } - if ( newDirFileInfo.lastModified() > indexFileInfo.lastModified() ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Maildir \"new\" directory newer than the index: cur modified at" - << newDirFileInfo.lastModified() << ", index modified at" - << indexFileInfo.lastModified(); - return; - } - - KMIndexReader indexReader( indexFileInfo.absoluteFilePath() ); - if ( indexReader.error() || !indexReader.readIndex() ) { - kError() << "Index file" << indexFileInfo.path() << "could not be read"; - return; - } - - mHasIndexData = true; - - const QStringList entries = mMaildir.entryList(); - Q_FOREACH( const QString &entry, entries ) { - const KMIndexDataPtr data = indexReader.dataByFileName( entry ); - if ( data != 0 ) { - mIndexData.insert( entry, data ); + if (mIndexDataLoaded) { + return; + } + + mIndexDataLoaded = true; + + const QFileInfo maildirFileInfo(mMaildir.path()); + QFileInfo indexFileInfo; + if (!indexFileForFolder(maildirFileInfo, indexFileInfo)) { + return; + } + + const QDir maildirBaseDir(maildirFileInfo.absoluteFilePath()); + const QFileInfo curDirFileInfo(maildirBaseDir, QStringLiteral("cur")); + const QFileInfo newDirFileInfo(maildirBaseDir, QStringLiteral("new")); + + if (curDirFileInfo.lastModified() > indexFileInfo.lastModified()) { + qCDebug(MIXEDMAILDIR_LOG) << "Maildir " << maildirFileInfo.absoluteFilePath() + << "\"cur\" directory newer than the index: cur modified at" + << curDirFileInfo.lastModified() << ", index modified at" + << indexFileInfo.lastModified(); + return; + } + if (newDirFileInfo.lastModified() > indexFileInfo.lastModified()) { + qCDebug(MIXEDMAILDIR_LOG) << "Maildir \"new\" directory newer than the index: cur modified at" + << newDirFileInfo.lastModified() << ", index modified at" + << indexFileInfo.lastModified(); + return; + } + + KMIndexReader indexReader(indexFileInfo.absoluteFilePath()); + if (indexReader.error() || !indexReader.readIndex()) { + qCritical() << "Index file" << indexFileInfo.path() << "could not be read"; + return; + } + + mHasIndexData = true; + + const QStringList entries = mMaildir.entryList(); + Q_FOREACH (const QString &entry, entries) { + const KMIndexDataPtr data = indexReader.dataByFileName(entry); + if (data != Q_NULLPTR) { + mIndexData.insert(entry, data); + } } - } - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Read" << mIndexData.count() << "index entries from" - << indexFileInfo.absoluteFilePath(); + qCDebug(MIXEDMAILDIR_LOG) << "Read" << mIndexData.count() << "index entries from" + << indexFileInfo.absoluteFilePath(); } typedef boost::shared_ptr MaildirPtr; class MixedMaildirStore::Private : public FileStore::Job::Visitor { - MixedMaildirStore *const q; + MixedMaildirStore *const q; - public: - enum FolderType - { - InvalidFolder, - TopLevelFolder, - MaildirFolder, - MBoxFolder +public: + enum FolderType { + InvalidFolder, + TopLevelFolder, + MaildirFolder, + MBoxFolder }; - Private( MixedMaildirStore *parent ) : q( parent ) + Private(MixedMaildirStore *parent) : q(parent) { } - FolderType folderForCollection( const Collection &col, QString &path, QString &errorText ) const; + FolderType folderForCollection(const Collection &col, QString &path, QString &errorText) const; - MBoxPtr getOrCreateMBoxPtr( const QString &path ); - MaildirPtr getOrCreateMaildirPtr( const QString &path, bool isTopLevel ); + MBoxPtr getOrCreateMBoxPtr(const QString &path); + MaildirPtr getOrCreateMaildirPtr(const QString &path, bool isTopLevel); - void fillMBoxCollectionDetails( const MBoxPtr &mbox, Collection &collection ); - void fillMaildirCollectionDetails( const Maildir &md, Collection &collection ); - void fillMaildirTreeDetails( const Maildir &md, const Collection &collection, Collection::List &collections, bool recurse ); - void listCollection( FileStore::Job *job, MBoxPtr &mbox, const Collection &collection, Item::List &items ); - void listCollection( FileStore::Job *job, MaildirPtr &md, const Collection &collection, Item::List &items ); - bool fillItem( MBoxPtr &mbox, bool includeHeaders, bool includeBody, Item &item ) const; - bool fillItem( const MaildirPtr &md, bool includeHeaders, bool includeBody, Item &item ) const; - void updateContextHashes( const QString &oldPath, const QString &newPath ); - - public: // visitor interface implementation - bool visit( FileStore::Job *job ); - bool visit( FileStore::CollectionCreateJob *job ); - bool visit( FileStore::CollectionDeleteJob *job ); - bool visit( FileStore::CollectionFetchJob *job ); - bool visit( FileStore::CollectionModifyJob *job ); - bool visit( FileStore::CollectionMoveJob *job ); - bool visit( FileStore::ItemCreateJob *job ); - bool visit( FileStore::ItemDeleteJob *job ); - bool visit( FileStore::ItemFetchJob *job ); - bool visit( FileStore::ItemModifyJob *job ); - bool visit( FileStore::ItemMoveJob *job ); - bool visit( FileStore::StoreCompactJob *job ); + void fillMBoxCollectionDetails(const MBoxPtr &mbox, Collection &collection); + void fillMaildirCollectionDetails(const Maildir &md, Collection &collection); + void fillMaildirTreeDetails(const Maildir &md, const Collection &collection, Collection::List &collections, bool recurse); + void listCollection(FileStore::Job *job, MBoxPtr &mbox, const Collection &collection, Item::List &items); + void listCollection(FileStore::Job *job, MaildirPtr &md, const Collection &collection, Item::List &items); + bool fillItem(MBoxPtr &mbox, bool includeHeaders, bool includeBody, Item &item) const; + bool fillItem(const MaildirPtr &md, bool includeHeaders, bool includeBody, Item &item) const; + void updateContextHashes(const QString &oldPath, const QString &newPath); + +public: // visitor interface implementation + bool visit(FileStore::Job *job) Q_DECL_OVERRIDE; + bool visit(FileStore::CollectionCreateJob *job) Q_DECL_OVERRIDE; + bool visit(FileStore::CollectionDeleteJob *job) Q_DECL_OVERRIDE; + bool visit(FileStore::CollectionFetchJob *job) Q_DECL_OVERRIDE; + bool visit(FileStore::CollectionModifyJob *job) Q_DECL_OVERRIDE; + bool visit(FileStore::CollectionMoveJob *job) Q_DECL_OVERRIDE; + bool visit(FileStore::ItemCreateJob *job) Q_DECL_OVERRIDE; + bool visit(FileStore::ItemDeleteJob *job) Q_DECL_OVERRIDE; + bool visit(FileStore::ItemFetchJob *job) Q_DECL_OVERRIDE; + bool visit(FileStore::ItemModifyJob *job) Q_DECL_OVERRIDE; + bool visit(FileStore::ItemMoveJob *job) Q_DECL_OVERRIDE; + bool visit(FileStore::StoreCompactJob *job) Q_DECL_OVERRIDE; - public: +public: typedef QHash MBoxHash; MBoxHash mMBoxes; @@ -532,1838 +552,1839 @@ MaildirHash mMaildirs; }; -MixedMaildirStore::Private::FolderType MixedMaildirStore::Private::folderForCollection( const Collection &col, QString &path, QString &errorText ) const +MixedMaildirStore::Private::FolderType MixedMaildirStore::Private::folderForCollection(const Collection &col, QString &path, QString &errorText) const { - path.clear(); - errorText.clear(); - - if ( col.remoteId().isEmpty() ) { - errorText = i18nc( "@info:status", "Given folder name is empty" ); - kWarning() << "Incomplete ancestor chain for collection."; - Q_ASSERT( !col.remoteId().isEmpty() ); // abort! Look at backtrace to see where we came from. - return InvalidFolder; - } + path.clear(); + errorText.clear(); - if ( col.parentCollection() == Collection::root() ) { - path = q->path(); - if ( col.remoteId() != path ) - kWarning() << "RID mismatch, is" << col.remoteId() << "expected" << path; - return TopLevelFolder; - } + if (col.remoteId().isEmpty()) { + errorText = i18nc("@info:status", "Given folder name is empty"); + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "Incomplete ancestor chain for collection."; + Q_ASSERT(!col.remoteId().isEmpty()); // abort! Look at backtrace to see where we came from. + return InvalidFolder; + } + + if (col.parentCollection() == Collection::root()) { + path = q->path(); + if (col.remoteId() != path) { + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "RID mismatch, is" << col.remoteId() << "expected" << path; + } + return TopLevelFolder; + } - FolderType type = folderForCollection( col.parentCollection(), path, errorText ); - switch ( type ) { + FolderType type = folderForCollection(col.parentCollection(), path, errorText); + switch (type) { case InvalidFolder: return InvalidFolder; case TopLevelFolder: // fall through case MaildirFolder: { - const Maildir parentMd( path, type == TopLevelFolder ); - const Maildir subFolder = parentMd.subFolder( col.remoteId() ); - if ( subFolder.isValid( false ) ) { - path = subFolder.path(); - return MaildirFolder; - } - - const QString subDirPath = - (type == TopLevelFolder ? path : Maildir::subDirPathForFolderPath( path ) ); - QFileInfo fileInfo( QDir( subDirPath ), col.remoteId() ); - if ( fileInfo.isFile() ) { - path = fileInfo.absoluteFilePath(); - return MBoxFolder; - } + const Maildir parentMd(path, type == TopLevelFolder); + const Maildir subFolder = parentMd.subFolder(col.remoteId()); + if (subFolder.isValid(false)) { + path = subFolder.path(); + return MaildirFolder; + } - errorText = i18nc( "@info:status", "Folder %1 does not seem to be a valid email folder", fileInfo.absoluteFilePath() ); - return InvalidFolder; + const QString subDirPath = + (type == TopLevelFolder ? path : Maildir::subDirPathForFolderPath(path)); + QFileInfo fileInfo(QDir(subDirPath), col.remoteId()); + if (fileInfo.isFile()) { + path = fileInfo.absoluteFilePath(); + return MBoxFolder; + } + + errorText = i18nc("@info:status", "Folder %1 does not seem to be a valid email folder", fileInfo.absoluteFilePath()); + return InvalidFolder; } case MBoxFolder: { - const QString subDirPath = Maildir::subDirPathForFolderPath( path ); - QFileInfo fileInfo( QDir( subDirPath ), col.remoteId() ); + const QString subDirPath = Maildir::subDirPathForFolderPath(path); + QFileInfo fileInfo(QDir(subDirPath), col.remoteId()); - if ( fileInfo.isFile() ) { - path = fileInfo.absoluteFilePath(); - return MBoxFolder; - } + if (fileInfo.isFile()) { + path = fileInfo.absoluteFilePath(); + return MBoxFolder; + } - const Maildir subFolder( fileInfo.absoluteFilePath(), false ); - if ( subFolder.isValid( false ) ) { - path = subFolder.path(); - return MaildirFolder; - } + const Maildir subFolder(fileInfo.absoluteFilePath(), false); + if (subFolder.isValid(false)) { + path = subFolder.path(); + return MaildirFolder; + } - errorText = i18nc( "@info:status", "Folder %1 does not seem to be a valid email folder", fileInfo.absoluteFilePath() ); - return InvalidFolder; + errorText = i18nc("@info:status", "Folder %1 does not seem to be a valid email folder", fileInfo.absoluteFilePath()); + return InvalidFolder; + } } - } - return InvalidFolder; + return InvalidFolder; } -MBoxPtr MixedMaildirStore::Private::getOrCreateMBoxPtr( const QString &path ) +MBoxPtr MixedMaildirStore::Private::getOrCreateMBoxPtr(const QString &path) { - MBoxPtr mbox; - const MBoxHash::const_iterator it = mMBoxes.constFind( path ); - if ( it == mMBoxes.constEnd() ) { - mbox = MBoxPtr( new MBoxContext ); - mMBoxes.insert( path, mbox ); - } else { - mbox = it.value(); - } + MBoxPtr mbox; + const MBoxHash::const_iterator it = mMBoxes.constFind(path); + if (it == mMBoxes.constEnd()) { + mbox = MBoxPtr(new MBoxContext); + mMBoxes.insert(path, mbox); + } else { + mbox = it.value(); + } - return mbox; + return mbox; } -MaildirPtr MixedMaildirStore::Private::getOrCreateMaildirPtr( const QString &path, bool isTopLevel ) +MaildirPtr MixedMaildirStore::Private::getOrCreateMaildirPtr(const QString &path, bool isTopLevel) { - MaildirPtr md; - const MaildirHash::const_iterator it = mMaildirs.constFind( path ); - if ( it == mMaildirs.constEnd() ) { - md = MaildirPtr( new MaildirContext( path, isTopLevel ) ); - mMaildirs.insert( path, md ); - } else { - md = it.value(); - } + MaildirPtr md; + const MaildirHash::const_iterator it = mMaildirs.constFind(path); + if (it == mMaildirs.constEnd()) { + md = MaildirPtr(new MaildirContext(path, isTopLevel)); + mMaildirs.insert(path, md); + } else { + md = it.value(); + } - return md; + return md; } -void MixedMaildirStore::Private::fillMBoxCollectionDetails( const MBoxPtr &mbox, Collection &collection ) +void MixedMaildirStore::Private::fillMBoxCollectionDetails(const MBoxPtr &mbox, Collection &collection) { - collection.setContentMimeTypes( QStringList() << Collection::mimeType() - << KMime::Message::mimeType() ); + collection.setContentMimeTypes(QStringList() << Collection::mimeType() + << KMime::Message::mimeType()); - const QFileInfo fileInfo( mbox->fileName() ); - if ( fileInfo.isWritable() ) { - collection.setRights( Collection::CanCreateItem | - Collection::CanChangeItem | - Collection::CanDeleteItem | - Collection::CanCreateCollection | - Collection::CanChangeCollection | - Collection::CanDeleteCollection ); - } else { - collection.setRights( Collection::ReadOnly ); - } + const QFileInfo fileInfo(mbox->fileName()); + if (fileInfo.isWritable()) { + collection.setRights(Collection::CanCreateItem | + Collection::CanChangeItem | + Collection::CanDeleteItem | + Collection::CanCreateCollection | + Collection::CanChangeCollection | + Collection::CanDeleteCollection); + } else { + collection.setRights(Collection::ReadOnly); + } - if ( mbox->mRevision > 0 ) { - collection.setRemoteRevision( QString::number( mbox->mRevision ) ); - } + if (mbox->mRevision > 0) { + collection.setRemoteRevision(QString::number(mbox->mRevision)); + } } -void MixedMaildirStore::Private::fillMaildirCollectionDetails( const Maildir &md, Collection &collection ) +void MixedMaildirStore::Private::fillMaildirCollectionDetails(const Maildir &md, Collection &collection) { - collection.setContentMimeTypes( QStringList() << Collection::mimeType() - << KMime::Message::mimeType() ); + collection.setContentMimeTypes(QStringList() << Collection::mimeType() + << KMime::Message::mimeType()); - const QFileInfo fileInfo( md.path() ); - if ( fileInfo.isWritable() ) { - collection.setRights( Collection::CanCreateItem | - Collection::CanChangeItem | - Collection::CanDeleteItem | - Collection::CanCreateCollection | - Collection::CanChangeCollection | - Collection::CanDeleteCollection ); - } else { - collection.setRights( Collection::ReadOnly ); - } + const QFileInfo fileInfo(md.path()); + if (fileInfo.isWritable()) { + collection.setRights(Collection::CanCreateItem | + Collection::CanChangeItem | + Collection::CanDeleteItem | + Collection::CanCreateCollection | + Collection::CanChangeCollection | + Collection::CanDeleteCollection); + } else { + collection.setRights(Collection::ReadOnly); + } } -void MixedMaildirStore::Private::fillMaildirTreeDetails( const Maildir &md, const Collection &collection, Collection::List &collections, bool recurse ) +void MixedMaildirStore::Private::fillMaildirTreeDetails(const Maildir &md, const Collection &collection, Collection::List &collections, bool recurse) { - if ( md.path().isEmpty() ) { - return; - } - - const QStringList maildirSubFolders = md.subFolderList(); - Q_FOREACH( const QString &subFolder, maildirSubFolders ) { - const Maildir subMd = md.subFolder( subFolder ); - - if ( !mMaildirs.contains( subMd.path() ) ) { - const MaildirPtr mdPtr = MaildirPtr( new MaildirContext( subMd ) ); - mMaildirs.insert( subMd.path(), mdPtr ); + if (md.path().isEmpty()) { + return; } - Collection col; - col.setRemoteId( subFolder ); - col.setName( subFolder ); - col.setParentCollection( collection ); - fillMaildirCollectionDetails( subMd, col ); - collections << col; + const QStringList maildirSubFolders = md.subFolderList(); + Q_FOREACH (const QString &subFolder, maildirSubFolders) { + const Maildir subMd = md.subFolder(subFolder); - if ( recurse ) { - fillMaildirTreeDetails( subMd, col, collections, true ); - } - } + if (!mMaildirs.contains(subMd.path())) { + const MaildirPtr mdPtr = MaildirPtr(new MaildirContext(subMd)); + mMaildirs.insert(subMd.path(), mdPtr); + } - const QDir dir( md.isRoot() ? md.path() : Maildir::subDirPathForFolderPath( md.path() ) ); - const QFileInfoList fileInfos = dir.entryInfoList( QDir::Files ); - Q_FOREACH( const QFileInfo &fileInfo, fileInfos ) { - if ( fileInfo.isHidden() || !fileInfo.isReadable() ) { - continue; - } + Collection col; + col.setRemoteId(subFolder); + col.setName(subFolder); + col.setParentCollection(collection); + fillMaildirCollectionDetails(subMd, col); + collections << col; - const QString mboxPath = fileInfo.absoluteFilePath(); + if (recurse) { + fillMaildirTreeDetails(subMd, col, collections, true); + } + } - MBoxPtr mbox = getOrCreateMBoxPtr( mboxPath ); - if ( mbox->load( mboxPath ) ) { - const QString subFolder = fileInfo.fileName(); - Collection col; - col.setRemoteId( subFolder ); - col.setName( subFolder ); - col.setParentCollection( collection ); - mbox->mCollection = col; + const QDir dir(md.isRoot() ? md.path() : Maildir::subDirPathForFolderPath(md.path())); + const QFileInfoList fileInfos = dir.entryInfoList(QDir::Files); + Q_FOREACH (const QFileInfo &fileInfo, fileInfos) { + if (fileInfo.isHidden() || !fileInfo.isReadable()) { + continue; + } - fillMBoxCollectionDetails( mbox, col ); - collections << col; + const QString mboxPath = fileInfo.absoluteFilePath(); - if ( recurse ) { - const QString subDirPath = Maildir::subDirPathForFolderPath( fileInfo.absoluteFilePath() ); - const Maildir subMd( subDirPath, true ); - fillMaildirTreeDetails( subMd, col, collections, true ); - } - } else { - mMBoxes.remove( fileInfo.absoluteFilePath() ); + MBoxPtr mbox = getOrCreateMBoxPtr(mboxPath); + if (mbox->load(mboxPath)) { + const QString subFolder = fileInfo.fileName(); + Collection col; + col.setRemoteId(subFolder); + col.setName(subFolder); + col.setParentCollection(collection); + mbox->mCollection = col; + + fillMBoxCollectionDetails(mbox, col); + collections << col; + + if (recurse) { + const QString subDirPath = Maildir::subDirPathForFolderPath(fileInfo.absoluteFilePath()); + const Maildir subMd(subDirPath, true); + fillMaildirTreeDetails(subMd, col, collections, true); + } + } else { + mMBoxes.remove(fileInfo.absoluteFilePath()); + } } - } } -void MixedMaildirStore::Private::listCollection( FileStore::Job *job, MBoxPtr &mbox, const Collection &collection, Item::List &items ) +void MixedMaildirStore::Private::listCollection(FileStore::Job *job, MBoxPtr &mbox, const Collection &collection, Item::List &items) { - mbox->readIndexData(); + mbox->readIndexData(); - QHash uidHash; - QHash tagListHash; + QHash uidHash; + QHash tagListHash; - const KMBox::MBoxEntry::List entryList = mbox->entryList(); - Q_FOREACH( const KMBox::MBoxEntry &entry, entryList ) { - Item item; - item.setMimeType( KMime::Message::mimeType() ); - item.setRemoteId( QString::number( entry.messageOffset() ) ); - item.setParentCollection( collection ); + const KMBox::MBoxEntry::List entryList = mbox->entryList(); + Q_FOREACH (const KMBox::MBoxEntry &entry, entryList) { + Item item; + item.setMimeType(KMime::Message::mimeType()); + item.setRemoteId(QString::number(entry.messageOffset())); + item.setParentCollection(collection); + + if (mbox->hasIndexData()) { + const KMIndexDataPtr indexData = mbox->indexData(entry.messageOffset()); + if (indexData != Q_NULLPTR && !indexData->isEmpty()) { + item.setFlags(indexData->status().statusFlags()); + + quint64 uid = indexData->uid(); + if (uid != 0) { + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "item" << item.remoteId() << "has UID" << uid; + uidHash.insert(item.remoteId(), QString::number(uid)); + } + + const QStringList tagList = indexData->tagList(); + if (!tagList.isEmpty()) { + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "item" << item.remoteId() << "has" + << tagList.count() << "tags:" << tagList; + tagListHash.insert(item.remoteId(), tagList); + } + } else if (indexData == Q_NULLPTR) { + Akonadi::MessageStatus status; + status.setDeleted(true), + item.setFlags(status.statusFlags()); + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "no index for item" << item.remoteId() << "in MBox" << mbox->fileName() + << "so it has been deleted but not purged. Marking it as" + << item.flags(); + } + } - if ( mbox->hasIndexData() ) { - const KMIndexDataPtr indexData = mbox->indexData( entry.messageOffset() ); - if ( indexData != 0 && !indexData->isEmpty() ) { - item.setFlags( indexData->status().statusFlags() ); + items << item; + } - quint64 uid = indexData->uid(); - if ( uid != 0 ) { - kDebug() << "item" << item.remoteId() << "has UID" << uid; - uidHash.insert( item.remoteId(), QString::number( uid ) ); + if (mbox->hasIndexData()) { + QVariant var; + + if (!uidHash.isEmpty()) { + var = QVariant::fromValue< QHash >(uidHash); + job->setProperty("remoteIdToIndexUid", var); } - const QStringList tagList = indexData->tagList(); - if ( !tagList.isEmpty() ) { - kDebug() << "item" << item.remoteId() << "has" - << tagList.count() << "tags:" << tagList; - tagListHash.insert( item.remoteId(), tagList ); + if (!tagListHash.isEmpty()) { + var = QVariant::fromValue< QHash >(tagListHash); + job->setProperty("remoteIdToTagList", var); } - } else if ( indexData == 0 ) { - Akonadi::MessageStatus status; - status.setDeleted( true ), - item.setFlags( status.statusFlags() ); - kDebug() << "no index for item" << item.remoteId() << "in MBox" << mbox->fileName() - << "so it has been deleted but not purged. Marking it as" - << item.flags(); - } } +} - items << item; - } +void MixedMaildirStore::Private::listCollection(FileStore::Job *job, MaildirPtr &md, const Collection &collection, Item::List &items) +{ + md->readIndexData(); - if ( mbox->hasIndexData() ) { - QVariant var; + QHash uidHash; + QHash tagListHash; - if ( !uidHash.isEmpty() ) { - var = QVariant::fromValue< QHash >( uidHash ); - job->setProperty( "remoteIdToIndexUid", var ); + const QStringList entryList = md->entryList(); + Q_FOREACH (const QString &entry, entryList) { + Item item; + item.setMimeType(KMime::Message::mimeType()); + item.setRemoteId(entry); + item.setParentCollection(collection); + + if (md->hasIndexData()) { + const KMIndexDataPtr indexData = md->indexData(entry); + if (indexData != Q_NULLPTR && !indexData->isEmpty()) { + item.setFlags(indexData->status().statusFlags()); + + const quint64 uid = indexData->uid(); + if (uid != 0) { + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "item" << item.remoteId() << "has UID" << uid; + uidHash.insert(item.remoteId(), QString::number(uid)); + } + + const QStringList tagList = indexData->tagList(); + if (!tagList.isEmpty()) { + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "item" << item.remoteId() << "has" + << tagList.count() << "tags:" << tagList; + tagListHash.insert(item.remoteId(), tagList); + } + } + } + Akonadi::Item::Flags flags = md->maildir().readEntryFlags(entry); + Q_FOREACH (const Akonadi::Item::Flag &flag, flags) { + item.setFlag(flag); + } + + items << item; } - if ( !tagListHash.isEmpty() ) { - var = QVariant::fromValue< QHash >( tagListHash ); - job->setProperty( "remoteIdToTagList", var ); + if (md->hasIndexData()) { + QVariant var; + + if (!uidHash.isEmpty()) { + var = QVariant::fromValue< QHash >(uidHash); + job->setProperty("remoteIdToIndexUid", var); + } + + if (!tagListHash.isEmpty()) { + var = QVariant::fromValue< QHash >(tagListHash); + job->setProperty("remoteIdToTagList", var); + } } - } } -void MixedMaildirStore::Private::listCollection( FileStore::Job *job, MaildirPtr &md, const Collection &collection, Item::List &items ) +bool MixedMaildirStore::Private::fillItem(MBoxPtr &mbox, bool includeHeaders, bool includeBody, Item &item) const { - md->readIndexData(); - - QHash uidHash; - QHash tagListHash; +// qCDebug(MIXEDMAILDIR_LOG) << "Filling item" << item.remoteId() << "from MBox: includeBody=" << includeBody; + bool ok = false; + const quint64 offset = item.remoteId().toULongLong(&ok); + if (!ok || !mbox->isValidOffset(offset)) { + return false; + } - const QStringList entryList = md->entryList(); - Q_FOREACH( const QString &entry, entryList ) { - Item item; - item.setMimeType( KMime::Message::mimeType() ); - item.setRemoteId( entry ); - item.setParentCollection( collection ); + item.setModificationTime(mbox->modificationTime()); - if ( md->hasIndexData() ) { - const KMIndexDataPtr indexData = md->indexData( entry ); - if ( indexData != 0 && !indexData->isEmpty() ) { - item.setFlags( indexData->status().statusFlags() ); + // TODO: size? - const quint64 uid = indexData->uid(); - if ( uid != 0 ) { - kDebug() << "item" << item.remoteId() << "has UID" << uid; - uidHash.insert( item.remoteId(), QString::number( uid ) ); + if (includeHeaders || includeBody) { + KMime::Message::Ptr messagePtr(new KMime::Message()); + if (includeBody) { + const QByteArray data = mbox->readRawEntry(offset); + messagePtr->setContent(KMime::CRLFtoLF(data)); + } else { + const QByteArray data = mbox->readEntryHeaders(offset); + messagePtr->setHead(KMime::CRLFtoLF(data)); } + messagePtr->parse(); - const QStringList tagList = indexData->tagList(); - if ( !tagList.isEmpty() ) { - kDebug() << "item" << item.remoteId() << "has" - << tagList.count() << "tags:" << tagList; - tagListHash.insert( item.remoteId(), tagList ); - } - } + item.setPayload(messagePtr); + Akonadi::MessageFlags::copyMessageFlags(*messagePtr, item); } - Akonadi::Item::Flags flags = md->maildir().readEntryFlags( entry ); - Q_FOREACH( const Akonadi::Item::Flag& flag, flags ) { - item.setFlag(flag); + return true; +} + +bool MixedMaildirStore::Private::fillItem(const MaildirPtr &md, bool includeHeaders, bool includeBody, Item &item) const +{ + /* qCDebug(MIXEDMAILDIR_LOG) << "Filling item" << item.remoteId() << "from Maildir: includeBody=" << includeBody;*/ + + const qint64 entrySize = md->maildir().size(item.remoteId()); + if (entrySize < 0) { + return false; } - items << item; - } + item.setSize(entrySize); + item.setModificationTime(md->maildir().lastModified(item.remoteId())); - if ( md->hasIndexData() ) { - QVariant var; + if (includeHeaders || includeBody) { + KMime::Message::Ptr messagePtr(new KMime::Message()); + if (includeBody) { + const QByteArray data = md->readEntry(item.remoteId()); + if (data.isEmpty()) { + return false; + } + + messagePtr->setContent(KMime::CRLFtoLF(data)); + } else { + const QByteArray data = md->readEntryHeaders(item.remoteId()); + if (data.isEmpty()) { + return false; + } - if ( !uidHash.isEmpty() ) { - var = QVariant::fromValue< QHash >( uidHash ); - job->setProperty( "remoteIdToIndexUid", var ); - } + messagePtr->setHead(KMime::CRLFtoLF(data)); + } + messagePtr->parse(); - if ( !tagListHash.isEmpty() ) { - var = QVariant::fromValue< QHash >( tagListHash ); - job->setProperty( "remoteIdToTagList", var ); + item.setPayload(messagePtr); + Akonadi::MessageFlags::copyMessageFlags(*messagePtr, item); } - } + return true; } -bool MixedMaildirStore::Private::fillItem( MBoxPtr &mbox, bool includeHeaders, bool includeBody, Item &item ) const +void MixedMaildirStore::Private::updateContextHashes(const QString &oldPath, const QString &newPath) { -// kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Filling item" << item.remoteId() << "from MBox: includeBody=" << includeBody; - bool ok = false; - const quint64 offset = item.remoteId().toULongLong( &ok ); - if ( !ok || !mbox->isValidOffset( offset ) ) { - return false; - } + //qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "oldPath=" << oldPath << "newPath=" << newPath; + const QString oldSubDirPath = Maildir::subDirPathForFolderPath(oldPath); + const QString newSubDirPath = Maildir::subDirPathForFolderPath(newPath); + + MBoxHash mboxes; + MBoxHash::const_iterator mboxIt = mMBoxes.constBegin(); + MBoxHash::const_iterator mboxEndIt = mMBoxes.constEnd(); + for (; mboxIt != mboxEndIt; ++mboxIt) { + QString key = mboxIt.key(); + MBoxPtr mboxPtr = mboxIt.value(); + + if (key == oldPath) { + key = newPath; + } else if (key.startsWith(oldSubDirPath)) { + if (mboxPtr->hasIndexData() || mboxPtr->mRevision > 0) { + key.replace(oldSubDirPath, newSubDirPath); + } else { + // if there is no index data yet, just discard this context + key.clear(); + } + } - item.setModificationTime( mbox->modificationTime() ); - - // TODO: size? - - if ( includeHeaders || includeBody ) { - KMime::Message::Ptr messagePtr( new KMime::Message() ); - if ( includeBody ) { - const QByteArray data = mbox->readRawEntry( offset ); - messagePtr->setContent( KMime::CRLFtoLF( data ) ); - } else { - const QByteArray data = mbox->readEntryHeaders( offset ); - messagePtr->setHead( KMime::CRLFtoLF( data ) ); + if (!key.isEmpty()) { + mboxPtr->updatePath(key); + mboxes.insert(key, mboxPtr); + } } - messagePtr->parse(); + //qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "mbox: old keys=" << mMBoxes.keys() << "new keys" << mboxes.keys(); + mMBoxes = mboxes; - item.setPayload( messagePtr ); - Akonadi::MessageFlags::copyMessageFlags(*messagePtr, item); - } - return true; + MaildirHash maildirs; + MaildirHash::const_iterator mdIt = mMaildirs.constBegin(); + MaildirHash::const_iterator mdEndIt = mMaildirs.constEnd(); + for (; mdIt != mdEndIt; ++mdIt) { + QString key = mdIt.key(); + MaildirPtr mdPtr = mdIt.value(); + + if (key == oldPath) { + key = newPath; + } else if (key.startsWith(oldSubDirPath)) { + if (mdPtr->hasIndexData()) { + key.replace(oldSubDirPath, newSubDirPath); + } else { + // if there is no index data yet, just discard this context + key.clear(); + } + } + + if (!key.isEmpty()) { + mdPtr->updatePath(key); + maildirs.insert(key, mdPtr); + } + } + //qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "maildir: old keys=" << mMaildirs.keys() << "new keys" << maildirs.keys(); + mMaildirs = maildirs; } -bool MixedMaildirStore::Private::fillItem( const MaildirPtr &md, bool includeHeaders, bool includeBody, Item &item ) const +bool MixedMaildirStore::Private::visit(FileStore::Job *job) { -/* kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Filling item" << item.remoteId() << "from Maildir: includeBody=" << includeBody;*/ - - const qint64 entrySize = md->maildir().size( item.remoteId() ); - if ( entrySize < 0 ) + const QString message = i18nc("@info:status", "Unhandled operation %1", QLatin1String(job->metaObject()->className())); + qCritical() << message; + q->notifyError(FileStore::Job::InvalidJobContext, message); return false; +} - item.setSize( entrySize ); - item.setModificationTime( md->maildir().lastModified( item.remoteId() ) ); +bool MixedMaildirStore::Private::visit(FileStore::CollectionCreateJob *job) +{ + QString path; + QString errorText; - if ( includeHeaders || includeBody ) { - KMime::Message::Ptr messagePtr( new KMime::Message() ); - if ( includeBody ) { - const QByteArray data = md->readEntry( item.remoteId() ); - if ( data.isEmpty() ) { + const FolderType folderType = folderForCollection(job->targetParent(), path, errorText); + if (folderType == InvalidFolder) { + errorText = i18nc("@info:status", "Cannot create folder %1 inside folder %2", + job->collection().name(), job->targetParent().name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); return false; - } + } + + const QString collectionName = job->collection().name().replace(QDir::separator(), QString()); + Maildir md; + if (folderType == MBoxFolder) { + const QString subDirPath = Maildir::subDirPathForFolderPath(path); + const QDir dir(subDirPath); + const QFileInfo dirInfo(dir, collectionName); + if (dirInfo.exists() && !dirInfo.isDir()) { + errorText = i18nc("@info:status", "Cannot create folder %1 inside folder %2", + job->collection().name(), job->targetParent().name()); + qCritical() << errorText << "FolderType=" << folderType << ", dirInfo exists and it not a dir"; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + + if (!dir.mkpath(collectionName)) { + errorText = i18nc("@info:status", "Cannot create folder %1 inside folder %2", + job->collection().name(), job->targetParent().name()); + qCritical() << errorText << "FolderType=" << folderType << ", mkpath failed"; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - messagePtr->setContent( KMime::CRLFtoLF( data ) ); + md = Maildir(dirInfo.absoluteFilePath(), false); + if (!md.create()) { + errorText = i18nc("@info:status", "Cannot create folder %1 inside folder %2", + job->collection().name(), job->targetParent().name()); + qCritical() << errorText << "FolderType=" << folderType << ", maildir create failed"; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + + const MaildirPtr mdPtr(new MaildirContext(md)); + mMaildirs.insert(md.path(), mdPtr); } else { - const QByteArray data = md->readEntryHeaders( item.remoteId() ); - if ( data.isEmpty() ) { - return false; - } + Maildir parentMd(path, folderType == TopLevelFolder); + if (parentMd.addSubFolder(collectionName).isEmpty()) { + errorText = i18nc("@info:status", "Cannot create folder %1 inside folder %2", + job->collection().name(), job->targetParent().name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - messagePtr->setHead( KMime::CRLFtoLF( data ) ); + md = Maildir(parentMd.subFolder(collectionName)); + const MaildirPtr mdPtr(new MaildirContext(md)); + mMaildirs.insert(md.path(), mdPtr); } - messagePtr->parse(); - item.setPayload( messagePtr ); - Akonadi::MessageFlags::copyMessageFlags(*messagePtr, item); - } - return true; + Collection collection = job->collection(); + collection.setRemoteId(collectionName); + collection.setName(collectionName); + collection.setParentCollection(job->targetParent()); + fillMaildirCollectionDetails(md, collection); + + q->notifyCollectionsProcessed(Collection::List() << collection); + return true; } -void MixedMaildirStore::Private::updateContextHashes( const QString &oldPath, const QString &newPath ) +bool MixedMaildirStore::Private::visit(FileStore::CollectionDeleteJob *job) { - //kDebug() << "oldPath=" << oldPath << "newPath=" << newPath; - const QString oldSubDirPath = Maildir::subDirPathForFolderPath( oldPath ); - const QString newSubDirPath = Maildir::subDirPathForFolderPath( newPath ); + QString path; + QString errorText; - MBoxHash mboxes; - MBoxHash::const_iterator mboxIt = mMBoxes.constBegin(); - MBoxHash::const_iterator mboxEndIt = mMBoxes.constEnd(); - for ( ; mboxIt != mboxEndIt; ++mboxIt ) { - QString key = mboxIt.key(); - MBoxPtr mboxPtr = mboxIt.value(); - - if ( key == oldPath ) { - key = newPath; - } else if ( key.startsWith( oldSubDirPath ) ) { - if ( mboxPtr->hasIndexData() || mboxPtr->mRevision > 0 ) { - key.replace( oldSubDirPath, newSubDirPath ); - } else { - // if there is no index data yet, just discard this context - key.clear(); - } + const FolderType folderType = folderForCollection(job->collection(), path, errorText); + if (folderType == InvalidFolder) { + errorText = i18nc("@info:status", "Cannot remove folder %1 from folder %2", + job->collection().name(), job->collection().parentCollection().name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; } - if ( !key.isEmpty() ) { - mboxPtr->updatePath( key ); - mboxes.insert( key, mboxPtr ); + QString parentPath; + const FolderType parentFolderType = folderForCollection(job->collection().parentCollection(), parentPath, errorText); + if (parentFolderType == InvalidFolder) { + errorText = i18nc("@info:status", "Cannot remove folder %1 from folder %2", + job->collection().name(), job->collection().parentCollection().name()); + qCritical() << errorText << "Parent FolderType=" << parentFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; } - } - //kDebug() << "mbox: old keys=" << mMBoxes.keys() << "new keys" << mboxes.keys(); - mMBoxes = mboxes; - - MaildirHash maildirs; - MaildirHash::const_iterator mdIt = mMaildirs.constBegin(); - MaildirHash::const_iterator mdEndIt = mMaildirs.constEnd(); - for ( ; mdIt != mdEndIt; ++mdIt ) { - QString key = mdIt.key(); - MaildirPtr mdPtr = mdIt.value(); - if ( key == oldPath ) { - key = newPath; - } else if ( key.startsWith( oldSubDirPath ) ) { - if ( mdPtr->hasIndexData() ) { - key.replace( oldSubDirPath, newSubDirPath ); - } else { - // if there is no index data yet, just discard this context - key.clear(); - } + if (folderType == MBoxFolder) { + if (!QFile::remove(path)) { + errorText = i18nc("@info:status", "Cannot remove folder %1 from folder %2", + job->collection().name(), job->collection().parentCollection().name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + } else { + if (!QDir(path).removeRecursively()) { + errorText = i18nc("@info:status", "Cannot remove folder %1 from folder %2", + job->collection().name(), job->collection().parentCollection().name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } } - if ( !key.isEmpty() ) { - mdPtr->updatePath( key ); - maildirs.insert( key, mdPtr ); - } - } - //kDebug() << "maildir: old keys=" << mMaildirs.keys() << "new keys" << maildirs.keys(); - mMaildirs = maildirs; -} + const QString subDirPath = Maildir::subDirPathForFolderPath(path); + QDir(subDirPath).removeRecursively(); -bool MixedMaildirStore::Private::visit( FileStore::Job *job ) -{ - const QString message = i18nc( "@info:status", "Unhandled operation %1", QLatin1String(job->metaObject()->className()) ); - kError() << message; - q->notifyError( FileStore::Job::InvalidJobContext, message ); - return false; + q->notifyCollectionsProcessed(Collection::List() << job->collection()); + return true; } -bool MixedMaildirStore::Private::visit( FileStore::CollectionCreateJob *job ) +bool MixedMaildirStore::Private::visit(FileStore::CollectionFetchJob *job) { - QString path; - QString errorText; - - const FolderType folderType = folderForCollection( job->targetParent(), path, errorText ); - if ( folderType == InvalidFolder ) { - errorText = i18nc( "@info:status", "Cannot create folder %1 inside folder %2", - job->collection().name(), job->targetParent().name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - const QString collectionName = job->collection().name().replace( QDir::separator(), QString() ); - Maildir md; - if ( folderType == MBoxFolder ) { - const QString subDirPath = Maildir::subDirPathForFolderPath( path ); - const QDir dir( subDirPath ); - const QFileInfo dirInfo( dir, collectionName ); - if ( dirInfo.exists() && !dirInfo.isDir() ) { - errorText = i18nc( "@info:status", "Cannot create folder %1 inside folder %2", - job->collection().name(), job->targetParent().name() ); - kError() << errorText << "FolderType=" << folderType << ", dirInfo exists and it not a dir"; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - if ( !dir.mkpath( collectionName ) ) { - errorText = i18nc( "@info:status", "Cannot create folder %1 inside folder %2", - job->collection().name(), job->targetParent().name() ); - kError() << errorText << "FolderType=" << folderType << ", mkpath failed"; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - md = Maildir( dirInfo.absoluteFilePath(), false ); - if ( !md.create() ) { - errorText = i18nc( "@info:status", "Cannot create folder %1 inside folder %2", - job->collection().name(), job->targetParent().name() ); - kError() << errorText << "FolderType=" << folderType << ", maildir create failed"; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - const MaildirPtr mdPtr( new MaildirContext( md ) ); - mMaildirs.insert( md.path(), mdPtr ); - } else { - Maildir parentMd( path, folderType == TopLevelFolder ); - if ( parentMd.addSubFolder( collectionName ).isEmpty() ) { - errorText = i18nc( "@info:status", "Cannot create folder %1 inside folder %2", - job->collection().name(), job->targetParent().name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - md = Maildir( parentMd.subFolder( collectionName ) ); - const MaildirPtr mdPtr( new MaildirContext( md ) ); - mMaildirs.insert( md.path(), mdPtr ); - } - - Collection collection = job->collection(); - collection.setRemoteId( collectionName ); - collection.setName( collectionName ); - collection.setParentCollection( job->targetParent() ); - fillMaildirCollectionDetails( md, collection ); - - q->notifyCollectionsProcessed( Collection::List() << collection ); - return true; -} - -bool MixedMaildirStore::Private::visit( FileStore::CollectionDeleteJob *job ) -{ - QString path; - QString errorText; - - const FolderType folderType = folderForCollection( job->collection(), path, errorText ); - if ( folderType == InvalidFolder ) { - errorText = i18nc( "@info:status", "Cannot remove folder %1 from folder %2", - job->collection().name(), job->collection().parentCollection().name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - QString parentPath; - const FolderType parentFolderType = folderForCollection( job->collection().parentCollection(), parentPath, errorText ); - if ( parentFolderType == InvalidFolder ) { - errorText = i18nc( "@info:status", "Cannot remove folder %1 from folder %2", - job->collection().name(), job->collection().parentCollection().name() ); - kError() << errorText << "Parent FolderType=" << parentFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - if ( folderType == MBoxFolder ) { - if ( !QFile::remove( path ) ) { - errorText = i18nc( "@info:status", "Cannot remove folder %1 from folder %2", - job->collection().name(), job->collection().parentCollection().name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - } else { - if ( !KPIMUtils::removeDirAndContentsRecursively( path ) ) { - errorText = i18nc( "@info:status", "Cannot remove folder %1 from folder %2", - job->collection().name(), job->collection().parentCollection().name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - } - - const QString subDirPath = Maildir::subDirPathForFolderPath( path ); - KPIMUtils::removeDirAndContentsRecursively( subDirPath ); - - q->notifyCollectionsProcessed( Collection::List() << job->collection() ); - return true; -} - -bool MixedMaildirStore::Private::visit( FileStore::CollectionFetchJob *job ) -{ - QString path; - QString errorText; - const FolderType folderType = folderForCollection( job->collection(), path, errorText ); - - if ( folderType == InvalidFolder ) { - kError() << errorText << "collection:" << job->collection(); - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + QString path; + QString errorText; + const FolderType folderType = folderForCollection(job->collection(), path, errorText); + + if (folderType == InvalidFolder) { + qCritical() << errorText << "collection:" << job->collection(); + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - Collection::List collections; - Collection collection = job->collection(); - if ( job->type() == FileStore::CollectionFetchJob::Base ) { - collection.setName( collection.remoteId() ); - if ( folderType == MBoxFolder ) { - MBoxPtr mbox; - MBoxHash::const_iterator findIt = mMBoxes.constFind( path ); - if ( findIt == mMBoxes.constEnd() ) { - mbox = MBoxPtr( new MBoxContext ); - if ( !mbox->load( path ) ) { - errorText = i18nc( "@info:status", "Failed to load MBox folder %1", path ); - kError() << errorText << "collection=" << collection; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); // TODO should be a different error code - return false; + Collection::List collections; + Collection collection = job->collection(); + if (job->type() == FileStore::CollectionFetchJob::Base) { + collection.setName(collection.remoteId()); + if (folderType == MBoxFolder) { + MBoxPtr mbox; + MBoxHash::const_iterator findIt = mMBoxes.constFind(path); + if (findIt == mMBoxes.constEnd()) { + mbox = MBoxPtr(new MBoxContext); + if (!mbox->load(path)) { + errorText = i18nc("@info:status", "Failed to load MBox folder %1", path); + qCritical() << errorText << "collection=" << collection; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); // TODO should be a different error code + return false; + } + + mbox->mCollection = collection; + mMBoxes.insert(path, mbox); + } else { + mbox = findIt.value(); + } + + fillMBoxCollectionDetails(mbox, collection); + } else { + const Maildir md(path, folderType == TopLevelFolder); + fillMaildirCollectionDetails(md, collection); } - - mbox->mCollection = collection; - mMBoxes.insert( path, mbox ); - } else { - mbox = findIt.value(); - } - - fillMBoxCollectionDetails( mbox, collection ); + collections << collection; } else { - const Maildir md( path, folderType == TopLevelFolder ); - fillMaildirCollectionDetails( md, collection ); - } - collections << collection; - } else { - // if the base is an mbox, use its sub folder dir like a top level maildir - if ( folderType == MBoxFolder ) { - path = Maildir::subDirPathForFolderPath( path ); + // if the base is an mbox, use its sub folder dir like a top level maildir + if (folderType == MBoxFolder) { + path = Maildir::subDirPathForFolderPath(path); + } + const Maildir md(path, folderType != MaildirFolder); + fillMaildirTreeDetails(md, collection, collections, + job->type() == FileStore::CollectionFetchJob::Recursive); } - const Maildir md( path, folderType != MaildirFolder ); - fillMaildirTreeDetails( md, collection, collections, - job->type() == FileStore::CollectionFetchJob::Recursive ); - } - if ( !collections.isEmpty() ) { - q->notifyCollectionsProcessed( collections ); - } - return true; + if (!collections.isEmpty()) { + q->notifyCollectionsProcessed(collections); + } + return true; } -static Collection updateMBoxCollectionTree( const Collection &collection, const Collection &oldParent, const Collection &newParent ) +static Collection updateMBoxCollectionTree(const Collection &collection, const Collection &oldParent, const Collection &newParent) { - if ( collection == oldParent ) { - return newParent; - } + if (collection == oldParent) { + return newParent; + } - if ( collection == Collection::root() ) { - return collection; - } + if (collection == Collection::root()) { + return collection; + } - Collection updatedCollection = collection; - updatedCollection.setParentCollection( updateMBoxCollectionTree( collection.parentCollection(), oldParent, newParent ) ); + Collection updatedCollection = collection; + updatedCollection.setParentCollection(updateMBoxCollectionTree(collection.parentCollection(), oldParent, newParent)); - return updatedCollection; + return updatedCollection; } -bool MixedMaildirStore::Private::visit( FileStore::CollectionModifyJob *job ) +bool MixedMaildirStore::Private::visit(FileStore::CollectionModifyJob *job) { - const Collection collection = job->collection(); - const QString collectionName = collection.name().replace( QDir::separator(), QString() ); + const Collection collection = job->collection(); + const QString collectionName = collection.name().replace(QDir::separator(), QString()); - // we also only do renames - if ( collection.remoteId() == collection.name() ) { - kWarning() << "CollectionModifyJob with name still identical to remoteId. Ignoring"; - return true; - } + // we also only do renames + if (collection.remoteId() == collection.name()) { + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "CollectionModifyJob with name still identical to remoteId. Ignoring"; + return true; + } - QString path; - QString errorText; - const FolderType folderType = folderForCollection( collection, path, errorText ); - if ( folderType == InvalidFolder ) { - errorText = i18nc( "@info:status", "Cannot rename folder %1", - collection.name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + QString path; + QString errorText; + const FolderType folderType = folderForCollection(collection, path, errorText); + if (folderType == InvalidFolder) { + errorText = i18nc("@info:status", "Cannot rename folder %1", + collection.name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - const QFileInfo fileInfo( path ); - const QFileInfo subDirInfo = Maildir::subDirPathForFolderPath( path ); + const QFileInfo fileInfo(path); + const QFileInfo subDirInfo = Maildir::subDirPathForFolderPath(path); - QDir parentDir( path ); - parentDir.cdUp(); + QDir parentDir(path); + parentDir.cdUp(); - const QFileInfo targetFileInfo( parentDir, collectionName ); - const QFileInfo targetSubDirInfo = Maildir::subDirPathForFolderPath( targetFileInfo.absoluteFilePath() ); - - if ( targetFileInfo.exists() || ( subDirInfo.exists() && targetSubDirInfo.exists() ) ) { - errorText = i18nc( "@info:status", "Cannot rename folder %1", - collection.name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + const QFileInfo targetFileInfo(parentDir, collectionName); + const QFileInfo targetSubDirInfo = Maildir::subDirPathForFolderPath(targetFileInfo.absoluteFilePath()); - // if there is an index, make sure it is read before renaming - // do not rename index as it could already be out of date - bool indexInvalidated = false; - if ( folderType == MBoxFolder ) { - // TODO would be nice if getOrCreateMBoxPtr() could be used instead, like below for Maildir - MBoxPtr mbox; - MBoxHash::const_iterator findIt = mMBoxes.constFind( path ); - if ( findIt == mMBoxes.constEnd() ) { - mbox = MBoxPtr( new MBoxContext ); - if ( !mbox->load( path ) ) { - kWarning() << "Failed to load mbox" << path; - } + if (targetFileInfo.exists() || (subDirInfo.exists() && targetSubDirInfo.exists())) { + errorText = i18nc("@info:status", "Cannot rename folder %1", + collection.name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - mbox->mCollection = collection; - mMBoxes.insert( path, mbox ); - } else { - mbox = findIt.value(); + // if there is an index, make sure it is read before renaming + // do not rename index as it could already be out of date + bool indexInvalidated = false; + if (folderType == MBoxFolder) { + // TODO would be nice if getOrCreateMBoxPtr() could be used instead, like below for Maildir + MBoxPtr mbox; + MBoxHash::const_iterator findIt = mMBoxes.constFind(path); + if (findIt == mMBoxes.constEnd()) { + mbox = MBoxPtr(new MBoxContext); + if (!mbox->load(path)) { + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "Failed to load mbox" << path; + } + + mbox->mCollection = collection; + mMBoxes.insert(path, mbox); + } else { + mbox = findIt.value(); + } + + mbox->readIndexData(); + indexInvalidated = mbox->hasIndexData(); + } else if (folderType == MaildirFolder) { + MaildirPtr md = getOrCreateMaildirPtr(path, false); + + md->readIndexData(); + indexInvalidated = md->hasIndexData(); } - mbox->readIndexData(); - indexInvalidated = mbox->hasIndexData(); - } else if ( folderType == MaildirFolder ) { - MaildirPtr md = getOrCreateMaildirPtr( path, false ); + if (!parentDir.rename(fileInfo.absoluteFilePath(), targetFileInfo.fileName())) { + errorText = i18nc("@info:status", "Cannot rename folder %1", + collection.name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - md->readIndexData(); - indexInvalidated = md->hasIndexData(); - } + if (subDirInfo.exists()) { + if (!parentDir.rename(subDirInfo.absoluteFilePath(), targetSubDirInfo.fileName())) { + errorText = i18nc("@info:status", "Cannot rename folder %1", + collection.name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + + // try to recover the previous rename + parentDir.rename(targetFileInfo.absoluteFilePath(), fileInfo.fileName()); + return false; + } + } - if ( !parentDir.rename( fileInfo.absoluteFilePath(), targetFileInfo.fileName() ) ) { - errorText = i18nc( "@info:status", "Cannot rename folder %1", - collection.name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + // update context hashes + updateContextHashes(fileInfo.absoluteFilePath(), targetFileInfo.absoluteFilePath()); + + Collection renamedCollection = collection; - if ( subDirInfo.exists() ) { - if ( !parentDir.rename( subDirInfo.absoluteFilePath(), targetSubDirInfo.fileName() ) ) { - errorText = i18nc( "@info:status", "Cannot rename folder %1", - collection.name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); + // when renaming top level folder, change path of store + if (folderType == TopLevelFolder) { + // backup caches, setTopLevelCollection() clears them + const MBoxHash mboxes = mMBoxes; + const MaildirHash maildirs = mMaildirs; - // try to recover the previous rename - parentDir.rename( targetFileInfo.absoluteFilePath(), fileInfo.fileName() ); - return false; + q->setPath(targetFileInfo.absoluteFilePath()); + + // restore caches + mMBoxes = mboxes; + mMaildirs = maildirs; + + renamedCollection = q->topLevelCollection(); + } else { + renamedCollection.setRemoteId(collectionName); + renamedCollection.setName(collectionName); } - } - // update context hashes - updateContextHashes( fileInfo.absoluteFilePath(), targetFileInfo.absoluteFilePath() ); + // update collections in MBox contexts so they stay usable for purge + Q_FOREACH (const MBoxPtr &mbox, mMBoxes) { + if (mbox->mCollection.isValid()) { + MBoxPtr updatedMBox = mbox; + updatedMBox->mCollection = updateMBoxCollectionTree(mbox->mCollection, collection, renamedCollection); + } + } - Collection renamedCollection = collection; + if (indexInvalidated) { + const QVariant var = QVariant::fromValue(Collection::List() << renamedCollection); + job->setProperty("onDiskIndexInvalidated", var); + } - // when renaming top level folder, change path of store - if ( folderType == TopLevelFolder ) { - // backup caches, setTopLevelCollection() clears them - const MBoxHash mboxes = mMBoxes; - const MaildirHash maildirs = mMaildirs; + q->notifyCollectionsProcessed(Collection::List() << renamedCollection); + return true; +} - q->setPath( targetFileInfo.absoluteFilePath() ); +bool MixedMaildirStore::Private::visit(FileStore::CollectionMoveJob *job) +{ + QString errorText; - // restore caches - mMBoxes = mboxes; - mMaildirs = maildirs; + const Collection moveCollection = job->collection(); + const Collection targetCollection = job->targetParent(); - renamedCollection = q->topLevelCollection(); - } else { - renamedCollection.setRemoteId( collectionName ); - renamedCollection.setName( collectionName ); - } - - // update collections in MBox contexts so they stay usable for purge - Q_FOREACH( const MBoxPtr &mbox, mMBoxes ) { - if ( mbox->mCollection.isValid() ) { - MBoxPtr updatedMBox = mbox; - updatedMBox->mCollection = updateMBoxCollectionTree( mbox->mCollection, collection, renamedCollection ); - } - } - - if ( indexInvalidated ) { - const QVariant var = QVariant::fromValue( Collection::List() << renamedCollection ); - job->setProperty( "onDiskIndexInvalidated", var ); - } - - q->notifyCollectionsProcessed( Collection::List() << renamedCollection ); - return true; -} - -bool MixedMaildirStore::Private::visit( FileStore::CollectionMoveJob *job ) -{ - QString errorText; - - const Collection moveCollection = job->collection(); - const Collection targetCollection = job->targetParent(); - - QString movePath; - const FolderType moveFolderType = folderForCollection( moveCollection, movePath, errorText ); - if ( moveFolderType == InvalidFolder || moveFolderType == TopLevelFolder ) { - errorText = i18nc( "@info:status", "Cannot move folder %1 from folder %2 to folder %3", - moveCollection.name(), moveCollection.parentCollection().name(), targetCollection.name() ); - kError() << errorText << "FolderType=" << moveFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + QString movePath; + const FolderType moveFolderType = folderForCollection(moveCollection, movePath, errorText); + if (moveFolderType == InvalidFolder || moveFolderType == TopLevelFolder) { + errorText = i18nc("@info:status", "Cannot move folder %1 from folder %2 to folder %3", + moveCollection.name(), moveCollection.parentCollection().name(), targetCollection.name()); + qCritical() << errorText << "FolderType=" << moveFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } -// kDebug( KDE_DEFAULT_DEBUG_AREA ) << "moveCollection" << moveCollection.remoteId() +// qCDebug(MIXEDMAILDIR_LOG) << "moveCollection" << moveCollection.remoteId() // << "movePath=" << movePath // << "moveType=" << moveFolderType; - QString targetPath; - const FolderType targetFolderType = folderForCollection( targetCollection, targetPath, errorText ); - if ( targetFolderType == InvalidFolder ) { - errorText = i18nc( "@info:status", "Cannot move folder %1 from folder %2 to folder %3", - moveCollection.name(), moveCollection.parentCollection().name(), targetCollection.name() ); - kError() << errorText << "FolderType=" << targetFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + QString targetPath; + const FolderType targetFolderType = folderForCollection(targetCollection, targetPath, errorText); + if (targetFolderType == InvalidFolder) { + errorText = i18nc("@info:status", "Cannot move folder %1 from folder %2 to folder %3", + moveCollection.name(), moveCollection.parentCollection().name(), targetCollection.name()); + qCritical() << errorText << "FolderType=" << targetFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } -// kDebug( KDE_DEFAULT_DEBUG_AREA ) << "targetCollection" << targetCollection.remoteId() +// qCDebug(MIXEDMAILDIR_LOG) << "targetCollection" << targetCollection.remoteId() // << "targetPath=" << targetPath // << "targetType=" << targetFolderType; - const QFileInfo targetSubDirInfo( Maildir::subDirPathForFolderPath( targetPath ) ); + const QFileInfo targetSubDirInfo(Maildir::subDirPathForFolderPath(targetPath)); - // if target is not the top level folder, make sure the sub folder directory exists - if ( targetFolderType != TopLevelFolder ) { - if ( !targetSubDirInfo.exists() ) { - QDir topDir( q->path() ); - if ( !topDir.mkpath( targetSubDirInfo.absoluteFilePath() ) ) { - errorText = i18nc( "@info:status", "Cannot move folder %1 from folder %2 to folder %3", - moveCollection.name(), moveCollection.parentCollection().name(), targetCollection.name() ); - kError() << errorText << "MoveFolderType=" << moveFolderType - << "TargetFolderType=" << targetFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + // if target is not the top level folder, make sure the sub folder directory exists + if (targetFolderType != TopLevelFolder) { + if (!targetSubDirInfo.exists()) { + QDir topDir(q->path()); + if (!topDir.mkpath(targetSubDirInfo.absoluteFilePath())) { + errorText = i18nc("@info:status", "Cannot move folder %1 from folder %2 to folder %3", + moveCollection.name(), moveCollection.parentCollection().name(), targetCollection.name()); + qCritical() << errorText << "MoveFolderType=" << moveFolderType + << "TargetFolderType=" << targetFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + } } - } - bool indexInvalidated = false; - QString movedPath; + bool indexInvalidated = false; + QString movedPath; - if ( moveFolderType == MBoxFolder ) { - // TODO would be nice if getOrCreateMBoxPtr() could be used instead, like below for Maildir - MBoxPtr mbox; - MBoxHash::const_iterator findIt = mMBoxes.constFind( movePath ); - if ( findIt == mMBoxes.constEnd() ) { - mbox = MBoxPtr( new MBoxContext ); - if ( !mbox->load( movePath ) ) { - kWarning() << "Failed to load mbox" << movePath; - } + if (moveFolderType == MBoxFolder) { + // TODO would be nice if getOrCreateMBoxPtr() could be used instead, like below for Maildir + MBoxPtr mbox; + MBoxHash::const_iterator findIt = mMBoxes.constFind(movePath); + if (findIt == mMBoxes.constEnd()) { + mbox = MBoxPtr(new MBoxContext); + if (!mbox->load(movePath)) { + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "Failed to load mbox" << movePath; + } + + mbox->mCollection = moveCollection; + mMBoxes.insert(movePath, mbox); + } else { + mbox = findIt.value(); + } - mbox->mCollection = moveCollection; - mMBoxes.insert( movePath, mbox ); - } else { - mbox = findIt.value(); - } + mbox->readIndexData(); + indexInvalidated = mbox->hasIndexData(); - mbox->readIndexData(); - indexInvalidated = mbox->hasIndexData(); + const QFileInfo moveFileInfo(movePath); + const QFileInfo moveSubDirInfo(Maildir::subDirPathForFolderPath(movePath)); + const QFileInfo targetFileInfo(targetPath); + + QDir targetDir(targetFolderType == TopLevelFolder ? + targetPath : Maildir::subDirPathForFolderPath(targetPath)); + if (targetDir.exists(moveFileInfo.fileName()) || + !targetDir.rename(moveFileInfo.absoluteFilePath(), moveFileInfo.fileName())) { + errorText = i18nc("@info:status", "Cannot move folder %1 from folder %2 to folder %3", + moveCollection.name(), moveCollection.parentCollection().name(), targetCollection.name()); + qCritical() << errorText << "MoveFolderType=" << moveFolderType + << "TargetFolderType=" << targetFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - const QFileInfo moveFileInfo( movePath ); - const QFileInfo moveSubDirInfo( Maildir::subDirPathForFolderPath( movePath ) ); - const QFileInfo targetFileInfo( targetPath ); - - QDir targetDir( targetFolderType == TopLevelFolder ? - targetPath : Maildir::subDirPathForFolderPath( targetPath ) ); - if ( targetDir.exists( moveFileInfo.fileName() ) || - !targetDir.rename( moveFileInfo.absoluteFilePath(), moveFileInfo.fileName() ) ) { - errorText = i18nc( "@info:status", "Cannot move folder %1 from folder %2 to folder %3", - moveCollection.name(), moveCollection.parentCollection().name(), targetCollection.name() ); - kError() << errorText << "MoveFolderType=" << moveFolderType - << "TargetFolderType=" << targetFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - if ( moveSubDirInfo.exists() ) { - if ( targetDir.exists( moveSubDirInfo.fileName() ) || - !targetDir.rename( moveSubDirInfo.absoluteFilePath(), moveSubDirInfo.fileName() ) ) { - errorText = i18nc( "@info:status", "Cannot move folder %1 from folder %2 to folder %3", - moveCollection.name(), moveCollection.parentCollection().name(), targetCollection.name() ); - kError() << errorText << "MoveFolderType=" << moveFolderType - << "TargetFolderType=" << targetFolderType; - - // try to revert the other rename - QDir sourceDir( moveFileInfo.absolutePath() ); - sourceDir.cdUp(); - sourceDir.rename( targetFileInfo.absoluteFilePath(), moveFileInfo.fileName() ); - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - } + if (moveSubDirInfo.exists()) { + if (targetDir.exists(moveSubDirInfo.fileName()) || + !targetDir.rename(moveSubDirInfo.absoluteFilePath(), moveSubDirInfo.fileName())) { + errorText = i18nc("@info:status", "Cannot move folder %1 from folder %2 to folder %3", + moveCollection.name(), moveCollection.parentCollection().name(), targetCollection.name()); + qCritical() << errorText << "MoveFolderType=" << moveFolderType + << "TargetFolderType=" << targetFolderType; + + // try to revert the other rename + QDir sourceDir(moveFileInfo.absolutePath()); + sourceDir.cdUp(); + sourceDir.rename(targetFileInfo.absoluteFilePath(), moveFileInfo.fileName()); + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + } - movedPath = QFileInfo( targetDir, moveFileInfo.fileName() ).absoluteFilePath(); - } else { - MaildirPtr md = getOrCreateMaildirPtr( movePath, false ); + movedPath = QFileInfo(targetDir, moveFileInfo.fileName()).absoluteFilePath(); + } else { + MaildirPtr md = getOrCreateMaildirPtr(movePath, false); - md->readIndexData(); - indexInvalidated = md->hasIndexData(); + md->readIndexData(); + indexInvalidated = md->hasIndexData(); - Maildir moveMd( movePath, false ); + Maildir moveMd(movePath, false); - // for moving purpose we can treat the MBox target's subDirPath like a top level maildir - Maildir targetMd; - if ( targetFolderType == MBoxFolder ) { - targetMd = Maildir( targetSubDirInfo.absoluteFilePath(), true ); - } else { - targetMd = Maildir( targetPath, targetFolderType == TopLevelFolder ); - } + // for moving purpose we can treat the MBox target's subDirPath like a top level maildir + Maildir targetMd; + if (targetFolderType == MBoxFolder) { + targetMd = Maildir(targetSubDirInfo.absoluteFilePath(), true); + } else { + targetMd = Maildir(targetPath, targetFolderType == TopLevelFolder); + } - if ( !moveMd.moveTo( targetMd ) ) { - errorText = i18nc( "@info:status", "Cannot move folder %1 from folder %2 to folder %3", - moveCollection.name(), moveCollection.parentCollection().name(), targetCollection.name() ); - kError() << errorText << "MoveFolderType=" << moveFolderType - << "TargetFolderType=" << targetFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + if (!moveMd.moveTo(targetMd)) { + errorText = i18nc("@info:status", "Cannot move folder %1 from folder %2 to folder %3", + moveCollection.name(), moveCollection.parentCollection().name(), targetCollection.name()); + qCritical() << errorText << "MoveFolderType=" << moveFolderType + << "TargetFolderType=" << targetFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - movedPath = targetMd.subFolder( moveCollection.remoteId() ).path(); - } + movedPath = targetMd.subFolder(moveCollection.remoteId()).path(); + } - // update context hashes - updateContextHashes( movePath, movedPath ); + // update context hashes + updateContextHashes(movePath, movedPath); - Collection movedCollection = moveCollection; - movedCollection.setParentCollection( targetCollection ); + Collection movedCollection = moveCollection; + movedCollection.setParentCollection(targetCollection); - // update collections in MBox contexts so they stay usable for purge - Q_FOREACH( const MBoxPtr &mbox, mMBoxes ) { - if ( mbox->mCollection.isValid() ) { - MBoxPtr updatedMBox = mbox; - updatedMBox->mCollection = updateMBoxCollectionTree( mbox->mCollection, moveCollection, movedCollection ); + // update collections in MBox contexts so they stay usable for purge + Q_FOREACH (const MBoxPtr &mbox, mMBoxes) { + if (mbox->mCollection.isValid()) { + MBoxPtr updatedMBox = mbox; + updatedMBox->mCollection = updateMBoxCollectionTree(mbox->mCollection, moveCollection, movedCollection); + } } - } - if ( indexInvalidated ) { - const QVariant var = QVariant::fromValue( Collection::List() << movedCollection ); - job->setProperty( "onDiskIndexInvalidated", var ); - } + if (indexInvalidated) { + const QVariant var = QVariant::fromValue(Collection::List() << movedCollection); + job->setProperty("onDiskIndexInvalidated", var); + } - q->notifyCollectionsProcessed( Collection::List() << movedCollection ); - return true; + q->notifyCollectionsProcessed(Collection::List() << movedCollection); + return true; } -bool MixedMaildirStore::Private::visit( FileStore::ItemCreateJob *job ) +bool MixedMaildirStore::Private::visit(FileStore::ItemCreateJob *job) { - QString path; - QString errorText; + QString path; + QString errorText; - const FolderType folderType = folderForCollection( job->collection(), path, errorText ); - if ( folderType == InvalidFolder || folderType == TopLevelFolder ) { - errorText = i18nc( "@info:status", "Cannot add emails to folder %1", - job->collection().name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - Item item = job->item(); - - if ( folderType == MBoxFolder ) { - MBoxPtr mbox; - MBoxHash::const_iterator findIt = mMBoxes.constFind( path ); - if ( findIt == mMBoxes.constEnd() ) { - mbox = MBoxPtr( new MBoxContext ); - if ( !mbox->load( path ) ) { - errorText = i18nc( "@info:status", "Cannot add emails to folder %1", - job->collection().name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); + const FolderType folderType = folderForCollection(job->collection(), path, errorText); + if (folderType == InvalidFolder || folderType == TopLevelFolder) { + errorText = i18nc("@info:status", "Cannot add emails to folder %1", + job->collection().name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); return false; - } - - mbox->mCollection = job->collection(); - mMBoxes.insert( path, mbox ); - } else { - mbox = findIt.value(); } - // make sure to read the index (if available) before modifying the data, which would - // make the index invalid - mbox->readIndexData(); + Item item = job->item(); + + if (folderType == MBoxFolder) { + MBoxPtr mbox; + MBoxHash::const_iterator findIt = mMBoxes.constFind(path); + if (findIt == mMBoxes.constEnd()) { + mbox = MBoxPtr(new MBoxContext); + if (!mbox->load(path)) { + errorText = i18nc("@info:status", "Cannot add emails to folder %1", + job->collection().name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + + mbox->mCollection = job->collection(); + mMBoxes.insert(path, mbox); + } else { + mbox = findIt.value(); + } - // if there is index data now, we let the job creator know that the on-disk index - // became invalid - if ( mbox->hasIndexData() ) { - const QVariant var = QVariant::fromValue( Collection::List() << job->collection() ); - job->setProperty( "onDiskIndexInvalidated", var ); - } - - qint64 result = mbox->appendEntry( item.payload() ); - if ( result < 0 ) { - errorText = i18nc( "@info:status", "Cannot add emails to folder %1", - job->collection().name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - mbox->save(); - item.setRemoteId( QString::number( result ) ); - } else { - MaildirPtr mdPtr; - MaildirHash::const_iterator findIt = mMaildirs.constFind( path ); - if ( findIt == mMaildirs.constEnd() ) { - mdPtr = MaildirPtr( new MaildirContext( path, false ) ); - mMaildirs.insert( path, mdPtr ); + // make sure to read the index (if available) before modifying the data, which would + // make the index invalid + mbox->readIndexData(); + + // if there is index data now, we let the job creator know that the on-disk index + // became invalid + if (mbox->hasIndexData()) { + const QVariant var = QVariant::fromValue(Collection::List() << job->collection()); + job->setProperty("onDiskIndexInvalidated", var); + } + + qint64 result = mbox->appendEntry(item.payload()); + if (result < 0) { + errorText = i18nc("@info:status", "Cannot add emails to folder %1", + job->collection().name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + mbox->save(); + item.setRemoteId(QString::number(result)); } else { - mdPtr = findIt.value(); - } + MaildirPtr mdPtr; + MaildirHash::const_iterator findIt = mMaildirs.constFind(path); + if (findIt == mMaildirs.constEnd()) { + mdPtr = MaildirPtr(new MaildirContext(path, false)); + mMaildirs.insert(path, mdPtr); + } else { + mdPtr = findIt.value(); + } - // make sure to read the index (if available) before modifying the data, which would - // make the index invalid - mdPtr->readIndexData(); + // make sure to read the index (if available) before modifying the data, which would + // make the index invalid + mdPtr->readIndexData(); + + // if there is index data now, we let the job creator know that the on-disk index + // became invalid + if (mdPtr->hasIndexData()) { + const QVariant var = QVariant::fromValue(Collection::List() << job->collection()); + job->setProperty("onDiskIndexInvalidated", var); + } - // if there is index data now, we let the job creator know that the on-disk index - // became invalid - if ( mdPtr->hasIndexData() ) { - const QVariant var = QVariant::fromValue( Collection::List() << job->collection() ); - job->setProperty( "onDiskIndexInvalidated", var ); - } + const QString result = mdPtr->addEntry(item.payload()->encodedContent()); + if (result.isEmpty()) { + errorText = i18nc("@info:status", "Cannot add emails to folder %1", + job->collection().name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - const QString result = mdPtr->addEntry( item.payload()->encodedContent() ); - if ( result.isEmpty() ) { - errorText = i18nc( "@info:status", "Cannot add emails to folder %1", - job->collection().name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; + item.setRemoteId(result); } - item.setRemoteId( result ); - } - - item.setParentCollection( job->collection() ); - q->notifyItemsProcessed( Item::List() << item ); - return true; + item.setParentCollection(job->collection()); + q->notifyItemsProcessed(Item::List() << item); + return true; } -bool MixedMaildirStore::Private::visit( FileStore::ItemDeleteJob *job ) +bool MixedMaildirStore::Private::visit(FileStore::ItemDeleteJob *job) { - const Item item = job->item(); - const Collection collection = item.parentCollection(); - QString path; - QString errorText; - - const FolderType folderType = folderForCollection( collection, path, errorText ); - if ( folderType == InvalidFolder || folderType == TopLevelFolder ) { - errorText = i18nc( "@info:status", "Cannot remove emails from folder %1", - collection.name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - if ( folderType == MBoxFolder ) { - MBoxPtr mbox; - MBoxHash::const_iterator findIt = mMBoxes.constFind( path ); - if ( findIt == mMBoxes.constEnd() ) { - mbox = MBoxPtr( new MBoxContext ); - if ( !mbox->load( path ) ) { - errorText = i18nc( "@info:status", "Cannot remove emails from folder %1", - collection.name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); + const Item item = job->item(); + const Collection collection = item.parentCollection(); + QString path; + QString errorText; + + const FolderType folderType = folderForCollection(collection, path, errorText); + if (folderType == InvalidFolder || folderType == TopLevelFolder) { + errorText = i18nc("@info:status", "Cannot remove emails from folder %1", + collection.name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); return false; - } - - mMBoxes.insert( path, mbox ); - } else { - mbox = findIt.value(); } - bool ok = false; - qint64 offset = item.remoteId().toLongLong( &ok ); - if ( !ok || offset < 0 || !mbox->isValidOffset( offset ) ) { - errorText = i18nc( "@info:status", "Cannot remove emails from folder %1", - collection.name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - mbox->mCollection = collection; - mbox->deleteEntry( offset ); - job->setProperty( "compactStore", true ); - } else { - MaildirPtr mdPtr; - MaildirHash::const_iterator findIt = mMaildirs.constFind( path ); - if ( findIt == mMaildirs.constEnd() ) { - mdPtr = MaildirPtr( new MaildirContext( path, false ) ); + if (folderType == MBoxFolder) { + MBoxPtr mbox; + MBoxHash::const_iterator findIt = mMBoxes.constFind(path); + if (findIt == mMBoxes.constEnd()) { + mbox = MBoxPtr(new MBoxContext); + if (!mbox->load(path)) { + errorText = i18nc("@info:status", "Cannot remove emails from folder %1", + collection.name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + + mMBoxes.insert(path, mbox); + } else { + mbox = findIt.value(); + } - mMaildirs.insert( path, mdPtr ); - } else { - mdPtr = findIt.value(); - } + bool ok = false; + qint64 offset = item.remoteId().toLongLong(&ok); + if (!ok || offset < 0 || !mbox->isValidOffset(offset)) { + errorText = i18nc("@info:status", "Cannot remove emails from folder %1", + collection.name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - // make sure to read the index (if available) before modifying the data, which would - // make the index invalid - mdPtr->readIndexData(); + mbox->mCollection = collection; + mbox->deleteEntry(offset); + job->setProperty("compactStore", true); + } else { + MaildirPtr mdPtr; + MaildirHash::const_iterator findIt = mMaildirs.constFind(path); + if (findIt == mMaildirs.constEnd()) { + mdPtr = MaildirPtr(new MaildirContext(path, false)); + + mMaildirs.insert(path, mdPtr); + } else { + mdPtr = findIt.value(); + } - // if there is index data now, we let the job creator know that the on-disk index - // became invalid - if ( mdPtr->hasIndexData() ) { - const QVariant var = QVariant::fromValue( Collection::List() << collection ); - job->setProperty( "onDiskIndexInvalidated", var ); - } + // make sure to read the index (if available) before modifying the data, which would + // make the index invalid + mdPtr->readIndexData(); + + // if there is index data now, we let the job creator know that the on-disk index + // became invalid + if (mdPtr->hasIndexData()) { + const QVariant var = QVariant::fromValue(Collection::List() << collection); + job->setProperty("onDiskIndexInvalidated", var); + } - if ( !mdPtr->removeEntry( item.remoteId() ) ) { - errorText = i18nc( "@info:status", "Cannot remove emails from folder %1", - collection.name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; + if (!mdPtr->removeEntry(item.remoteId())) { + errorText = i18nc("@info:status", "Cannot remove emails from folder %1", + collection.name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } } - } - q->notifyItemsProcessed( Item::List() << item ); - return true; + q->notifyItemsProcessed(Item::List() << item); + return true; } -bool MixedMaildirStore::Private::visit( FileStore::ItemFetchJob *job ) +bool MixedMaildirStore::Private::visit(FileStore::ItemFetchJob *job) { - ItemFetchScope scope = job->fetchScope(); - const bool includeBody = scope.fullPayload() || - scope.payloadParts().contains( MessagePart::Body ); - const bool includeHeaders = scope.payloadParts().contains( MessagePart::Header ) || - scope.payloadParts().contains( MessagePart::Envelope ); + ItemFetchScope scope = job->fetchScope(); + const bool includeBody = scope.fullPayload() || + scope.payloadParts().contains(MessagePart::Body); + const bool includeHeaders = scope.payloadParts().contains(MessagePart::Header) || + scope.payloadParts().contains(MessagePart::Envelope); + + const bool fetchSingleItem = job->collection().remoteId().isEmpty(); + const Collection collection = fetchSingleItem ? job->item().parentCollection() : job->collection(); + + QString path; + QString errorText; + Q_ASSERT(!collection.remoteId().isEmpty()); + const FolderType folderType = folderForCollection(collection, path, errorText); + + if (folderType == InvalidFolder) { + qCritical() << errorText << "collection:" << job->collection(); + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - const bool fetchSingleItem = job->collection().remoteId().isEmpty(); - const Collection collection = fetchSingleItem ? job->item().parentCollection() : job->collection(); + if (folderType == MBoxFolder) { + MBoxHash::iterator findIt = mMBoxes.find(path); + if (findIt == mMBoxes.end() || !fetchSingleItem) { + MBoxPtr mbox = findIt != mMBoxes.end() ? findIt.value() : MBoxPtr(new MBoxContext); + if (!mbox->load(path)) { + errorText = i18nc("@info:status", "Failed to load MBox folder %1", path); + qCritical() << errorText << "collection=" << collection; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); // TODO should be a different error code + if (findIt != mMBoxes.end()) { + mMBoxes.erase(findIt); + } + return false; + } + + if (findIt == mMBoxes.end()) { + findIt = mMBoxes.insert(path, mbox); + } + } - QString path; - QString errorText; - Q_ASSERT( !collection.remoteId().isEmpty() ); - const FolderType folderType = folderForCollection( collection, path, errorText ); + Item::List items; + if (fetchSingleItem) { + items << job->item(); + } else { + listCollection(job, findIt.value(), collection, items); + } - if ( folderType == InvalidFolder ) { - kError() << errorText << "collection:" << job->collection(); - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + Item::List::iterator it = items.begin(); + Item::List::iterator endIt = items.end(); + for (; it != endIt; ++it) { + if (!fillItem(findIt.value(), includeHeaders, includeBody, *it)) { + const QString errorText = + i18nc("@info:status", "Error while reading mails from folder %1", collection.name()); + q->notifyError(FileStore::Job::InvalidJobContext, errorText); // TODO should be a different error code + qCritical() << "Failed to read item" << (*it).remoteId() << "in MBox file" << path; + return false; + } + } - if ( folderType == MBoxFolder ) { - MBoxHash::iterator findIt = mMBoxes.find( path ); - if ( findIt == mMBoxes.end() || !fetchSingleItem ) { - MBoxPtr mbox = findIt != mMBoxes.end() ? findIt.value() : MBoxPtr( new MBoxContext ); - if ( !mbox->load( path ) ) { - errorText = i18nc( "@info:status", "Failed to load MBox folder %1", path ); - kError() << errorText << "collection=" << collection; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); // TODO should be a different error code - if ( findIt != mMBoxes.end() ) { - mMBoxes.erase( findIt ); + if (!items.isEmpty()) { + q->notifyItemsProcessed(items); + } + } else { + MaildirPtr mdPtr; + MaildirHash::const_iterator mdIt = mMaildirs.constFind(path); + if (mdIt == mMaildirs.constEnd()) { + mdPtr = MaildirPtr(new MaildirContext(path, folderType == TopLevelFolder)); + mMaildirs.insert(path, mdPtr); + } else { + mdPtr = mdIt.value(); } - return false; - } - if ( findIt == mMBoxes.end() ) { - findIt = mMBoxes.insert( path, mbox ); - } - } + if (!mdPtr->isValid(errorText)) { + errorText = i18nc("@info:status", "Failed to load Maildirs folder %1", path); + qCritical() << errorText << "collection=" << collection; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); // TODO should be a different error code + return false; + } - Item::List items; - if ( fetchSingleItem ) { - items << job->item(); - } else { - listCollection( job, findIt.value(), collection, items ); - } + Item::List items; + if (fetchSingleItem) { + items << job->item(); + } else { + listCollection(job, mdPtr, collection, items); + } - Item::List::iterator it = items.begin(); - Item::List::iterator endIt = items.end(); - for ( ; it != endIt; ++it ) { - if ( !fillItem( findIt.value(), includeHeaders, includeBody, *it ) ) { - const QString errorText = - i18nc( "@info:status", "Error while reading mails from folder %1", collection.name() ); - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); // TODO should be a different error code - kError() << "Failed to read item" << (*it).remoteId() << "in MBox file" << path; - return false; - } - } + Item::List::iterator it = items.begin(); + Item::List::iterator endIt = items.end(); + for (; it != endIt; ++it) { + if (!fillItem(mdPtr, includeHeaders, includeBody, *it)) { + const QString errorText = + i18nc("@info:status", "Error while reading mails from folder %1", collection.name()); + q->notifyError(FileStore::Job::InvalidJobContext, errorText); // TODO should be a different error code + qCritical() << "Failed to read item" << (*it).remoteId() << "in Maildir" << path; + return false; + } + } - if ( !items.isEmpty() ) { - q->notifyItemsProcessed( items ); - } - } else { - MaildirPtr mdPtr; - MaildirHash::const_iterator mdIt = mMaildirs.constFind( path ); - if ( mdIt == mMaildirs.constEnd() ) { - mdPtr = MaildirPtr( new MaildirContext( path, folderType == TopLevelFolder ) ); - mMaildirs.insert( path, mdPtr ); - } else { - mdPtr = mdIt.value(); + if (!items.isEmpty()) { + q->notifyItemsProcessed(items); + } } - if ( !mdPtr->isValid( errorText ) ) { - errorText = i18nc( "@info:status", "Failed to load Maildirs folder %1", path ); - kError() << errorText << "collection=" << collection; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); // TODO should be a different error code - return false; - } + return true; +} - Item::List items; - if ( fetchSingleItem ) { - items << job->item(); - } else { - listCollection( job, mdPtr, collection, items ); +bool MixedMaildirStore::Private::visit(FileStore::ItemModifyJob *job) +{ + const QSet parts = job->parts(); + bool payloadChanged = false; + bool flagsChanged = false; + Q_FOREACH (const QByteArray &part, parts) { + if (part.startsWith("PLD:")) { + payloadChanged = true; + } + if (part.contains("FLAGS")) { + flagsChanged = true; + } } - Item::List::iterator it = items.begin(); - Item::List::iterator endIt = items.end(); - for ( ; it != endIt; ++it ) { - if ( !fillItem( mdPtr, includeHeaders, includeBody, *it ) ) { - const QString errorText = - i18nc( "@info:status", "Error while reading mails from folder %1", collection.name() ); - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); // TODO should be a different error code - kError() << "Failed to read item" << (*it).remoteId() << "in Maildir" << path; + const bool nothingChanged = (!payloadChanged && !flagsChanged); + const bool payloadChangedButIgnored = payloadChanged && job->ignorePayload(); + const bool ignoreModifyIfValid = nothingChanged || + (payloadChangedButIgnored && !flagsChanged); + + Item item = job->item(); + const Collection collection = item.parentCollection(); + QString path; + QString errorText; + + const FolderType folderType = folderForCollection(collection, path, errorText); + if (folderType == InvalidFolder || folderType == TopLevelFolder) { + errorText = i18nc("@info:status", "Cannot modify emails in folder %1", + collection.name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); return false; - } - } - - if ( !items.isEmpty() ) { - q->notifyItemsProcessed( items ); } - } - return true; -} + if (folderType == MBoxFolder) { + MBoxPtr mbox; + MBoxHash::const_iterator findIt = mMBoxes.constFind(path); + if (findIt == mMBoxes.constEnd()) { + mbox = MBoxPtr(new MBoxContext); + if (!mbox->load(path)) { + errorText = i18nc("@info:status", "Cannot modify emails in folder %1", + collection.name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + + mMBoxes.insert(path, mbox); + } else { + mbox = findIt.value(); + } -bool MixedMaildirStore::Private::visit( FileStore::ItemModifyJob *job ) -{ - const QSet parts = job->parts(); - bool payloadChanged = false; - bool flagsChanged = false; - Q_FOREACH( const QByteArray &part, parts ) { - if ( part.startsWith( "PLD:" ) ) { - payloadChanged = true; - } - if ( part.contains( "FLAGS" ) ) { - flagsChanged = true; - } - } + bool ok = false; + qint64 offset = item.remoteId().toLongLong(&ok); + if (!ok || offset < 0 || !mbox->isValidOffset(offset)) { + errorText = i18nc("@info:status", "Cannot modify emails in folder %1", + collection.name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - const bool nothingChanged = ( !payloadChanged && !flagsChanged ); - const bool payloadChangedButIgnored = payloadChanged && job->ignorePayload(); - const bool ignoreModifyIfValid = nothingChanged || - ( payloadChangedButIgnored && !flagsChanged ); + // if we can ignore payload, or we have nothing else to change, then we are finished + if (ignoreModifyIfValid) { + qCDebug(MIXEDMAILDIR_LOG) << "ItemModifyJob for item" << item.remoteId() + << "in collection" << collection.remoteId() + << "skipped: nothing of interest changed (" << nothingChanged + << ") or only payload changed but should be ignored (" + << (payloadChanged && !flagsChanged && job->ignorePayload()) + << "). Modified parts:" << parts; + q->notifyItemsProcessed(Item::List() << job->item()); + return true; + } - Item item = job->item(); - const Collection collection = item.parentCollection(); - QString path; - QString errorText; + // mbox can only change payload, ignore any other change + if (!payloadChanged) { + q->notifyItemsProcessed(Item::List() << item); + return true; + } - const FolderType folderType = folderForCollection( collection, path, errorText ); - if ( folderType == InvalidFolder || folderType == TopLevelFolder ) { - errorText = i18nc( "@info:status", "Cannot modify emails in folder %1", - collection.name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + // make sure to read the index (if available) before modifying the data, which would + // make the index invalid + mbox->readIndexData(); + + // if there is index data now, we let the job creator know that the on-disk index + // became invalid + if (mbox->hasIndexData()) { + const QVariant var = QVariant::fromValue(Collection::List() << collection); + job->setProperty("onDiskIndexInvalidated", var); + } - if ( folderType == MBoxFolder ) { - MBoxPtr mbox; - MBoxHash::const_iterator findIt = mMBoxes.constFind( path ); - if ( findIt == mMBoxes.constEnd() ) { - mbox = MBoxPtr( new MBoxContext ); - if ( !mbox->load( path ) ) { - errorText = i18nc( "@info:status", "Cannot modify emails in folder %1", - collection.name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + qint64 newOffset = mbox->appendEntry(item.payload()); + if (newOffset < 0) { + errorText = i18nc("@info:status", "Cannot modify emails in folder %1", + collection.name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - mMBoxes.insert( path, mbox ); + if (newOffset > 0) { + mbox->mCollection = collection; + mbox->deleteEntry(offset); + job->setProperty("compactStore", true); + } + mbox->save(); + item.setRemoteId(QString::number(newOffset)); } else { - mbox = findIt.value(); - } + MaildirPtr mdPtr; + MaildirHash::const_iterator findIt = mMaildirs.constFind(path); + if (findIt == mMaildirs.constEnd()) { + mdPtr = MaildirPtr(new MaildirContext(path, false)); + mMaildirs.insert(path, mdPtr); + } else { + mdPtr = findIt.value(); + } - bool ok = false; - qint64 offset = item.remoteId().toLongLong( &ok ); - if ( !ok || offset < 0 || !mbox->isValidOffset( offset ) ) { - errorText = i18nc( "@info:status", "Cannot modify emails in folder %1", - collection.name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - // if we can ignore payload, or we have nothing else to change, then we are finished - if ( ignoreModifyIfValid ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "ItemModifyJob for item" << item.remoteId() - << "in collection" << collection.remoteId() - << "skipped: nothing of interest changed (" << nothingChanged - << ") or only payload changed but should be ignored (" - << ( payloadChanged && !flagsChanged && job->ignorePayload() ) - << "). Modified parts:" << parts; - q->notifyItemsProcessed( Item::List() << job->item() ); - return true; - } - - // mbox can only change payload, ignore any other change - if ( !payloadChanged ) { - q->notifyItemsProcessed( Item::List() << item ); - return true; - } + if (!mdPtr->isValidEntry(item.remoteId())) { + errorText = i18nc("@info:status", "Cannot modify emails in folder %1", + collection.name()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - // make sure to read the index (if available) before modifying the data, which would - // make the index invalid - mbox->readIndexData(); + // if we can ignore payload, or we have nothing else to change, then we are finished + if (ignoreModifyIfValid) { + qCDebug(MIXEDMAILDIR_LOG) << "ItemModifyJob for item" << item.remoteId() + << "in collection" << collection.remoteId() + << "skipped: nothing of interest changed (" << nothingChanged + << ") or only payload changed but should be ignored (" + << (payloadChanged && !flagsChanged && job->ignorePayload()) + << "). Modified parts:" << parts; + q->notifyItemsProcessed(Item::List() << job->item()); + return true; + } - // if there is index data now, we let the job creator know that the on-disk index - // became invalid - if ( mbox->hasIndexData() ) { - const QVariant var = QVariant::fromValue( Collection::List() << collection ); - job->setProperty( "onDiskIndexInvalidated", var ); - } - - qint64 newOffset = mbox->appendEntry( item.payload() ); - if ( newOffset < 0 ) { - errorText = i18nc( "@info:status", "Cannot modify emails in folder %1", - collection.name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - if ( newOffset > 0 ) { - mbox->mCollection = collection; - mbox->deleteEntry( offset ); - job->setProperty( "compactStore", true ); - } - mbox->save(); - item.setRemoteId( QString::number( newOffset ) ); - } else { - MaildirPtr mdPtr; - MaildirHash::const_iterator findIt = mMaildirs.constFind( path ); - if ( findIt == mMaildirs.constEnd() ) { - mdPtr = MaildirPtr( new MaildirContext( path, false ) ); - mMaildirs.insert( path, mdPtr ); - } else { - mdPtr = findIt.value(); - } + // make sure to read the index (if available) before modifying the data, which would + // make the index invalid + mdPtr->readIndexData(); + + // if there is index data now, we let the job creator know that the on-disk index + // became invalid + if (mdPtr->hasIndexData()) { + const QVariant var = QVariant::fromValue(Collection::List() << collection); + job->setProperty("onDiskIndexInvalidated", var); + } - if ( !mdPtr->isValidEntry( item.remoteId() ) ) { - errorText = i18nc( "@info:status", "Cannot modify emails in folder %1", - collection.name() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - // if we can ignore payload, or we have nothing else to change, then we are finished - if ( ignoreModifyIfValid ) { - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "ItemModifyJob for item" << item.remoteId() - << "in collection" << collection.remoteId() - << "skipped: nothing of interest changed (" << nothingChanged - << ") or only payload changed but should be ignored (" - << ( payloadChanged && !flagsChanged && job->ignorePayload() ) - << "). Modified parts:" << parts; - q->notifyItemsProcessed( Item::List() << job->item() ); - return true; - } - - // make sure to read the index (if available) before modifying the data, which would - // make the index invalid - mdPtr->readIndexData(); - - // if there is index data now, we let the job creator know that the on-disk index - // became invalid - if ( mdPtr->hasIndexData() ) { - const QVariant var = QVariant::fromValue( Collection::List() << collection ); - job->setProperty( "onDiskIndexInvalidated", var ); - } - - QString newKey = item.remoteId(); - if ( flagsChanged ) { - Maildir md( mdPtr->maildir() ); - newKey = md.changeEntryFlags( item.remoteId(), item.flags() ); - if ( newKey.isEmpty() ) { - errorText = i18nc( "@info:status", "Cannot modify emails in folder %1. %2", - collection.name(), md.lastError() ); - kError() << errorText << "FolderType=" << folderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - item.setRemoteId( newKey ); - } + QString newKey = item.remoteId(); + if (flagsChanged) { + Maildir md(mdPtr->maildir()); + newKey = md.changeEntryFlags(item.remoteId(), item.flags()); + if (newKey.isEmpty()) { + errorText = i18nc("@info:status", "Cannot modify emails in folder %1. %2", + collection.name(), md.lastError()); + qCritical() << errorText << "FolderType=" << folderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + item.setRemoteId(newKey); + } - if ( payloadChanged ) { - mdPtr->writeEntry( newKey, item.payload()->encodedContent() ); + if (payloadChanged) { + mdPtr->writeEntry(newKey, item.payload()->encodedContent()); + } } - } - q->notifyItemsProcessed( Item::List() << item ); - return true; + q->notifyItemsProcessed(Item::List() << item); + return true; } -bool MixedMaildirStore::Private::visit( FileStore::ItemMoveJob *job ) +bool MixedMaildirStore::Private::visit(FileStore::ItemMoveJob *job) { - QString errorText; + QString errorText; - QString sourcePath; - const Collection sourceCollection = job->item().parentCollection(); - const FolderType sourceFolderType = folderForCollection( sourceCollection, sourcePath, errorText ); - if ( sourceFolderType == InvalidFolder || sourceFolderType == TopLevelFolder ) { - errorText = i18nc( "@info:status", "Cannot move emails from folder %1", - sourceCollection.name() ); - kError() << errorText << "FolderType=" << sourceFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + QString sourcePath; + const Collection sourceCollection = job->item().parentCollection(); + const FolderType sourceFolderType = folderForCollection(sourceCollection, sourcePath, errorText); + if (sourceFolderType == InvalidFolder || sourceFolderType == TopLevelFolder) { + errorText = i18nc("@info:status", "Cannot move emails from folder %1", + sourceCollection.name()); + qCritical() << errorText << "FolderType=" << sourceFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } -// kDebug( KDE_DEFAULT_DEBUG_AREA ) << "sourceCollection" << sourceCollection.remoteId() +// qCDebug(MIXEDMAILDIR_LOG) << "sourceCollection" << sourceCollection.remoteId() // << "sourcePath=" << sourcePath // << "sourceType=" << sourceFolderType; - QString targetPath; - const Collection targetCollection = job->targetParent(); - const FolderType targetFolderType = folderForCollection( targetCollection, targetPath, errorText ); - if ( targetFolderType == InvalidFolder || targetFolderType == TopLevelFolder ) { - errorText = i18nc( "@info:status", "Cannot move emails to folder %1", - targetCollection.name() ); - kError() << errorText << "FolderType=" << targetFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + QString targetPath; + const Collection targetCollection = job->targetParent(); + const FolderType targetFolderType = folderForCollection(targetCollection, targetPath, errorText); + if (targetFolderType == InvalidFolder || targetFolderType == TopLevelFolder) { + errorText = i18nc("@info:status", "Cannot move emails to folder %1", + targetCollection.name()); + qCritical() << errorText << "FolderType=" << targetFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } -// kDebug( KDE_DEFAULT_DEBUG_AREA ) << "targetCollection" << targetCollection.remoteId() +// qCDebug(MIXEDMAILDIR_LOG) << "targetCollection" << targetCollection.remoteId() // << "targetPath=" << targetPath // << "targetType=" << targetFolderType; - Item item = job->item(); + Item item = job->item(); - if ( sourceFolderType == MBoxFolder ) { -/* kDebug( KDE_DEFAULT_DEBUG_AREA ) << "source is MBox";*/ - bool ok= false; - quint64 offset = item.remoteId().toULongLong( &ok ); - if ( !ok ) { - errorText = i18nc( "@info:status", "Cannot move emails from folder %1", - sourceCollection.name() ); - kError() << errorText << "FolderType=" << sourceFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - MBoxPtr mbox; - MBoxHash::const_iterator findIt = mMBoxes.constFind( sourcePath ); - if ( findIt == mMBoxes.constEnd() ) { - mbox = MBoxPtr( new MBoxContext ); - if ( !mbox->load( sourcePath ) ) { - errorText = i18nc( "@info:status", "Cannot move emails to folder %1", - sourceCollection.name() ); - kError() << errorText << "FolderType=" << sourceFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - mbox->mCollection = sourceCollection; - mMBoxes.insert( sourcePath, mbox ); - } else { - mbox = findIt.value(); - } - - if ( !mbox->isValidOffset( offset ) ) { - errorText = i18nc( "@info:status", "Cannot move emails from folder %1", - sourceCollection.name() ); - kError() << errorText << "FolderType=" << sourceFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - if ( !item.hasPayload() || - !item.loadedPayloadParts().contains( MessagePart::Body ) ) { - if ( !fillItem( mbox, true, true, item ) ) { - errorText = i18nc( "@info:status", "Cannot move email from folder %1", - sourceCollection.name() ); - kError() << errorText << "FolderType=" << sourceFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - } - - Collection::List collections; + if (sourceFolderType == MBoxFolder) { + /* qCDebug(MIXEDMAILDIR_LOG) << "source is MBox";*/ + bool ok = false; + quint64 offset = item.remoteId().toULongLong(&ok); + if (!ok) { + errorText = i18nc("@info:status", "Cannot move emails from folder %1", + sourceCollection.name()); + qCritical() << errorText << "FolderType=" << sourceFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - // make sure to read the index (if available) before modifying the data, which would - // make the index invalid - mbox->readIndexData(); + MBoxPtr mbox; + MBoxHash::const_iterator findIt = mMBoxes.constFind(sourcePath); + if (findIt == mMBoxes.constEnd()) { + mbox = MBoxPtr(new MBoxContext); + if (!mbox->load(sourcePath)) { + errorText = i18nc("@info:status", "Cannot move emails to folder %1", + sourceCollection.name()); + qCritical() << errorText << "FolderType=" << sourceFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + + mbox->mCollection = sourceCollection; + mMBoxes.insert(sourcePath, mbox); + } else { + mbox = findIt.value(); + } - if ( mbox->hasIndexData() ) { - collections << sourceCollection; - } + if (!mbox->isValidOffset(offset)) { + errorText = i18nc("@info:status", "Cannot move emails from folder %1", + sourceCollection.name()); + qCritical() << errorText << "FolderType=" << sourceFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - if ( targetFolderType == MBoxFolder ) { -/* kDebug( KDE_DEFAULT_DEBUG_AREA ) << "target is MBox";*/ - MBoxPtr targetMBox; - MBoxHash::const_iterator findIt = mMBoxes.constFind( targetPath ); - if ( findIt == mMBoxes.constEnd() ) { - targetMBox = MBoxPtr( new MBoxContext ); - if ( !targetMBox->load( targetPath ) ) { - errorText = i18nc( "@info:status", "Cannot move emails to folder %1", - targetCollection.name() ); - kError() << errorText << "FolderType=" << targetFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - targetMBox->mCollection = targetCollection; - mMBoxes.insert( targetPath, targetMBox ); - } else { - targetMBox = findIt.value(); - } - - // make sure to read the index (if available) before modifying the data, which would - // make the index invalid - targetMBox->readIndexData(); - - // if there is index data now, we let the job creator know that the on-disk index - // became invalid - if ( targetMBox->hasIndexData() ) { - collections << targetCollection; - } - - qint64 remoteId = targetMBox->appendEntry( item.payload() ); - if ( remoteId < 0 ) { - errorText = i18nc( "@info:status", "Cannot move emails to folder %1", - targetCollection.name() ); - kError() << errorText << "FolderType=" << targetFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + if (!item.hasPayload() || + !item.loadedPayloadParts().contains(MessagePart::Body)) { + if (!fillItem(mbox, true, true, item)) { + errorText = i18nc("@info:status", "Cannot move email from folder %1", + sourceCollection.name()); + qCritical() << errorText << "FolderType=" << sourceFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + } - if ( !targetMBox->save() ) { - errorText = i18nc( "@info:status", "Cannot move emails to folder %1", - targetCollection.name() ); - kError() << errorText << "FolderType=" << targetFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + Collection::List collections; - item.setRemoteId( QString::number( remoteId ) ); - } else { -/* kDebug( KDE_DEFAULT_DEBUG_AREA ) << "target is Maildir";*/ - MaildirPtr targetMdPtr = getOrCreateMaildirPtr( targetPath, false ); + // make sure to read the index (if available) before modifying the data, which would + // make the index invalid + mbox->readIndexData(); - // make sure to read the index (if available) before modifying the data, which would - // make the index invalid - targetMdPtr->readIndexData(); - - // if there is index data now, we let the job creator know that the on-disk index - // became invalid - if ( targetMdPtr->hasIndexData() ) { - collections << targetCollection; - } - - const QString remoteId = targetMdPtr->addEntry( mbox->readRawEntry( offset ) ); - if ( remoteId.isEmpty() ) { - errorText = i18nc( "@info:status", "Cannot move email from folder %1 to folder %2", - sourceCollection.name(), targetCollection.name() ); - kError() << errorText << "SourceFolderType=" << sourceFolderType << "TargetFolderType=" << targetFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + if (mbox->hasIndexData()) { + collections << sourceCollection; + } - item.setRemoteId( remoteId ); - } + if (targetFolderType == MBoxFolder) { + /* qCDebug(MIXEDMAILDIR_LOG) << "target is MBox";*/ + MBoxPtr targetMBox; + MBoxHash::const_iterator findIt = mMBoxes.constFind(targetPath); + if (findIt == mMBoxes.constEnd()) { + targetMBox = MBoxPtr(new MBoxContext); + if (!targetMBox->load(targetPath)) { + errorText = i18nc("@info:status", "Cannot move emails to folder %1", + targetCollection.name()); + qCritical() << errorText << "FolderType=" << targetFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + + targetMBox->mCollection = targetCollection; + mMBoxes.insert(targetPath, targetMBox); + } else { + targetMBox = findIt.value(); + } + + // make sure to read the index (if available) before modifying the data, which would + // make the index invalid + targetMBox->readIndexData(); + + // if there is index data now, we let the job creator know that the on-disk index + // became invalid + if (targetMBox->hasIndexData()) { + collections << targetCollection; + } + + qint64 remoteId = targetMBox->appendEntry(item.payload()); + if (remoteId < 0) { + errorText = i18nc("@info:status", "Cannot move emails to folder %1", + targetCollection.name()); + qCritical() << errorText << "FolderType=" << targetFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + + if (!targetMBox->save()) { + errorText = i18nc("@info:status", "Cannot move emails to folder %1", + targetCollection.name()); + qCritical() << errorText << "FolderType=" << targetFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + + item.setRemoteId(QString::number(remoteId)); + } else { + /* qCDebug(MIXEDMAILDIR_LOG) << "target is Maildir";*/ + MaildirPtr targetMdPtr = getOrCreateMaildirPtr(targetPath, false); + + // make sure to read the index (if available) before modifying the data, which would + // make the index invalid + targetMdPtr->readIndexData(); + + // if there is index data now, we let the job creator know that the on-disk index + // became invalid + if (targetMdPtr->hasIndexData()) { + collections << targetCollection; + } + + const QString remoteId = targetMdPtr->addEntry(mbox->readRawEntry(offset)); + if (remoteId.isEmpty()) { + errorText = i18nc("@info:status", "Cannot move email from folder %1 to folder %2", + sourceCollection.name(), targetCollection.name()); + qCritical() << errorText << "SourceFolderType=" << sourceFolderType << "TargetFolderType=" << targetFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - if ( !collections.isEmpty() ) { - const QVariant var = QVariant::fromValue( collections ); - job->setProperty( "onDiskIndexInvalidated", var ); - } + item.setRemoteId(remoteId); + } - mbox->mCollection = sourceCollection; - mbox->deleteEntry( offset ); - job->setProperty( "compactStore", true ); - } else { -/* kDebug( KDE_DEFAULT_DEBUG_AREA ) << "source is Maildir";*/ - MaildirPtr sourceMdPtr = getOrCreateMaildirPtr( sourcePath, false ); + if (!collections.isEmpty()) { + const QVariant var = QVariant::fromValue(collections); + job->setProperty("onDiskIndexInvalidated", var); + } - if ( !sourceMdPtr->isValidEntry( item.remoteId() ) ) { - errorText = i18nc( "@info:status", "Cannot move email from folder %1", - sourceCollection.name() ); - kError() << errorText << "FolderType=" << sourceFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + mbox->mCollection = sourceCollection; + mbox->deleteEntry(offset); + job->setProperty("compactStore", true); + } else { + /* qCDebug(MIXEDMAILDIR_LOG) << "source is Maildir";*/ + MaildirPtr sourceMdPtr = getOrCreateMaildirPtr(sourcePath, false); - Collection::List collections; + if (!sourceMdPtr->isValidEntry(item.remoteId())) { + errorText = i18nc("@info:status", "Cannot move email from folder %1", + sourceCollection.name()); + qCritical() << errorText << "FolderType=" << sourceFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - // make sure to read the index (if available) before modifying the data, which would - // make the index invalid - sourceMdPtr->readIndexData(); - - // if there is index data now, we let the job creator know that the on-disk index - // became invalid - if ( sourceMdPtr->hasIndexData() ) { - collections << sourceCollection; - } - - if ( targetFolderType == MBoxFolder ) { -/* kDebug( KDE_DEFAULT_DEBUG_AREA ) << "target is MBox";*/ - if ( !item.hasPayload() || - !item.loadedPayloadParts().contains( MessagePart::Body ) ) { - if ( !fillItem( sourceMdPtr, true, true, item ) ) { - errorText = i18nc( "@info:status", "Cannot move email from folder %1", - sourceCollection.name() ); - kError() << errorText << "FolderType=" << sourceFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - } - - MBoxPtr mbox; - MBoxHash::const_iterator findIt = mMBoxes.constFind( targetPath ); - if ( findIt == mMBoxes.constEnd() ) { - mbox = MBoxPtr( new MBoxContext ); - if ( !mbox->load( targetPath ) ) { - errorText = i18nc( "@info:status", "Cannot move emails to folder %1", - targetCollection.name() ); - kError() << errorText << "FolderType=" << targetFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - - mbox->mCollection = targetCollection; - mMBoxes.insert( targetPath, mbox ); - } else { - mbox = findIt.value(); - } - - // make sure to read the index (if available) before modifying the data, which would - // make the index invalid - mbox->readIndexData(); - - // if there is index data now, we let the job creator know that the on-disk index - // became invalid - if ( mbox->hasIndexData() ) { - collections << targetCollection; - } - - const qint64 remoteId = mbox->appendEntry( item.payload() ); - if ( remoteId < 0 ) { - errorText = i18nc( "@info:status", "Cannot move emails to folder %1", - targetCollection.name() ); - kError() << errorText << "FolderType=" << targetFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } - sourceMdPtr->removeEntry( item.remoteId() ); + Collection::List collections; - mbox->save(); - item.setRemoteId( QString::number( remoteId ) ); - } else { -/* kDebug( KDE_DEFAULT_DEBUG_AREA ) << "target is Maildir";*/ - MaildirPtr targetMdPtr = getOrCreateMaildirPtr( targetPath, false ); + // make sure to read the index (if available) before modifying the data, which would + // make the index invalid + sourceMdPtr->readIndexData(); + + // if there is index data now, we let the job creator know that the on-disk index + // became invalid + if (sourceMdPtr->hasIndexData()) { + collections << sourceCollection; + } - // make sure to read the index (if available) before modifying the data, which would - // make the index invalid - targetMdPtr->readIndexData(); - - // if there is index data now, we let the job creator know that the on-disk index - // became invalid - if ( targetMdPtr->hasIndexData() ) { - collections << targetCollection; - } - - const QString remoteId = sourceMdPtr->moveEntryTo( item.remoteId(), *targetMdPtr ); - if ( remoteId.isEmpty() ) { - errorText = i18nc( "@info:status", "Cannot move email from folder %1 to folder %2", - sourceCollection.name(), targetCollection.name() ); - kError() << errorText << "SourceFolderType=" << sourceFolderType << "TargetFolderType=" << targetFolderType; - q->notifyError( FileStore::Job::InvalidJobContext, errorText ); - return false; - } + if (targetFolderType == MBoxFolder) { + /* qCDebug(MIXEDMAILDIR_LOG) << "target is MBox";*/ + if (!item.hasPayload() || + !item.loadedPayloadParts().contains(MessagePart::Body)) { + if (!fillItem(sourceMdPtr, true, true, item)) { + errorText = i18nc("@info:status", "Cannot move email from folder %1", + sourceCollection.name()); + qCritical() << errorText << "FolderType=" << sourceFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + } + + MBoxPtr mbox; + MBoxHash::const_iterator findIt = mMBoxes.constFind(targetPath); + if (findIt == mMBoxes.constEnd()) { + mbox = MBoxPtr(new MBoxContext); + if (!mbox->load(targetPath)) { + errorText = i18nc("@info:status", "Cannot move emails to folder %1", + targetCollection.name()); + qCritical() << errorText << "FolderType=" << targetFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + + mbox->mCollection = targetCollection; + mMBoxes.insert(targetPath, mbox); + } else { + mbox = findIt.value(); + } + + // make sure to read the index (if available) before modifying the data, which would + // make the index invalid + mbox->readIndexData(); + + // if there is index data now, we let the job creator know that the on-disk index + // became invalid + if (mbox->hasIndexData()) { + collections << targetCollection; + } + + const qint64 remoteId = mbox->appendEntry(item.payload()); + if (remoteId < 0) { + errorText = i18nc("@info:status", "Cannot move emails to folder %1", + targetCollection.name()); + qCritical() << errorText << "FolderType=" << targetFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } + sourceMdPtr->removeEntry(item.remoteId()); + + mbox->save(); + item.setRemoteId(QString::number(remoteId)); + } else { + /* qCDebug(MIXEDMAILDIR_LOG) << "target is Maildir";*/ + MaildirPtr targetMdPtr = getOrCreateMaildirPtr(targetPath, false); + + // make sure to read the index (if available) before modifying the data, which would + // make the index invalid + targetMdPtr->readIndexData(); + + // if there is index data now, we let the job creator know that the on-disk index + // became invalid + if (targetMdPtr->hasIndexData()) { + collections << targetCollection; + } + + const QString remoteId = sourceMdPtr->moveEntryTo(item.remoteId(), *targetMdPtr); + if (remoteId.isEmpty()) { + errorText = i18nc("@info:status", "Cannot move email from folder %1 to folder %2", + sourceCollection.name(), targetCollection.name()); + qCritical() << errorText << "SourceFolderType=" << sourceFolderType << "TargetFolderType=" << targetFolderType; + q->notifyError(FileStore::Job::InvalidJobContext, errorText); + return false; + } - item.setRemoteId( remoteId ); - } + item.setRemoteId(remoteId); + } - if ( !collections.isEmpty() ) { - const QVariant var = QVariant::fromValue( collections ); - job->setProperty( "onDiskIndexInvalidated", var ); + if (!collections.isEmpty()) { + const QVariant var = QVariant::fromValue(collections); + job->setProperty("onDiskIndexInvalidated", var); + } } - } - item.setParentCollection( targetCollection ); - q->notifyItemsProcessed( Item::List() << item ); - return true; + item.setParentCollection(targetCollection); + q->notifyItemsProcessed(Item::List() << item); + return true; } -bool MixedMaildirStore::Private::visit( FileStore::StoreCompactJob *job ) +bool MixedMaildirStore::Private::visit(FileStore::StoreCompactJob *job) { - Q_UNUSED( job ); + Q_UNUSED(job); - Collection::List collections; - - MBoxHash::const_iterator it = mMBoxes.constBegin(); - MBoxHash::const_iterator endIt = mMBoxes.constEnd(); - for ( ; it != endIt; ++it ) { - MBoxPtr mbox = it.value(); - - if ( !mbox->hasDeletedOffsets() ) { - continue; - } - - // make sure to read the index (if available) before modifying the data, which would - // make the index invalid - mbox->readIndexData(); - - QList movedEntries; - const int result = mbox->purge( movedEntries ); - if ( result > 0 ) { - if ( movedEntries.count() > 0 ) { - qint64 revision = mbox->mCollection.remoteRevision().toLongLong(); - kDebug() << "purge of" << mbox->mCollection.name() << "caused item move: oldRevision=" - << revision << "(stored)," << mbox->mRevision << "(local)"; - revision = qMax( revision, mbox->mRevision ) + 1; - - const QString remoteRevision = QString::number( revision ); - - Collection collection = mbox->mCollection; - collection.attribute( Entity::AddIfMissing )->setRemoteRevision( remoteRevision ); - - q->notifyCollectionsProcessed( Collection::List() << collection ); - - mbox->mCollection.setRemoteRevision( remoteRevision ); - mbox->mRevision = revision; - } - - Item::List items; - Q_FOREACH( const KMBox::MBoxEntry::Pair &offsetPair, movedEntries ) { - const QString oldRemoteId( QString::number( offsetPair.first.messageOffset() ) ); - const QString newRemoteId( QString::number( offsetPair.second.messageOffset() ) ); - - Item item; - item.setRemoteId( oldRemoteId ); - item.setParentCollection( mbox->mCollection ); - item.attribute( Entity::AddIfMissing )->setRemoteId( newRemoteId ); + Collection::List collections; - items << item; - } + MBoxHash::const_iterator it = mMBoxes.constBegin(); + MBoxHash::const_iterator endIt = mMBoxes.constEnd(); + for (; it != endIt; ++it) { + MBoxPtr mbox = it.value(); - // if there is index data, we let the job creator know that the on-disk index - // became invalid - if ( mbox->hasIndexData() ) { - collections << mbox->mCollection; - } + if (!mbox->hasDeletedOffsets()) { + continue; + } - if ( !items.isEmpty() ) { - q->notifyItemsProcessed( items ); - } + // make sure to read the index (if available) before modifying the data, which would + // make the index invalid + mbox->readIndexData(); + + QList movedEntries; + const int result = mbox->purge(movedEntries); + if (result > 0) { + if (movedEntries.count() > 0) { + qint64 revision = mbox->mCollection.remoteRevision().toLongLong(); + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "purge of" << mbox->mCollection.name() << "caused item move: oldRevision=" + << revision << "(stored)," << mbox->mRevision << "(local)"; + revision = qMax(revision, mbox->mRevision) + 1; + + const QString remoteRevision = QString::number(revision); + + Collection collection = mbox->mCollection; + collection.attribute(Entity::AddIfMissing)->setRemoteRevision(remoteRevision); + + q->notifyCollectionsProcessed(Collection::List() << collection); + + mbox->mCollection.setRemoteRevision(remoteRevision); + mbox->mRevision = revision; + } + + Item::List items; + items.reserve(movedEntries.count()); + Q_FOREACH (const KMBox::MBoxEntry::Pair &offsetPair, movedEntries) { + const QString oldRemoteId(QString::number(offsetPair.first.messageOffset())); + const QString newRemoteId(QString::number(offsetPair.second.messageOffset())); + + Item item; + item.setRemoteId(oldRemoteId); + item.setParentCollection(mbox->mCollection); + item.attribute(Entity::AddIfMissing)->setRemoteId(newRemoteId); + + items << item; + } + + // if there is index data, we let the job creator know that the on-disk index + // became invalid + if (mbox->hasIndexData()) { + collections << mbox->mCollection; + } + + if (!items.isEmpty()) { + q->notifyItemsProcessed(items); + } + } } - } - if ( !collections.isEmpty() ) { - const QVariant var = QVariant::fromValue( collections ); - job->setProperty( "onDiskIndexInvalidated", var ); - } + if (!collections.isEmpty()) { + const QVariant var = QVariant::fromValue(collections); + job->setProperty("onDiskIndexInvalidated", var); + } - return true; + return true; } -MixedMaildirStore::MixedMaildirStore() : FileStore::AbstractLocalStore(), d( new Private( this ) ) +MixedMaildirStore::MixedMaildirStore() : FileStore::AbstractLocalStore(), d(new Private(this)) { } MixedMaildirStore::~MixedMaildirStore() { - delete d; + delete d; } -void MixedMaildirStore::setTopLevelCollection( const Collection &collection ) +void MixedMaildirStore::setTopLevelCollection(const Collection &collection) { - QStringList contentMimeTypes; - contentMimeTypes << Collection::mimeType(); + QStringList contentMimeTypes; + contentMimeTypes << Collection::mimeType(); - Collection::Rights rights; - // TODO check if read-only? - rights = Collection::CanCreateCollection | Collection::CanChangeCollection | Collection::CanDeleteCollection; + Collection::Rights rights; + // TODO check if read-only? + rights = Collection::CanCreateCollection | Collection::CanChangeCollection | Collection::CanDeleteCollection; - CachePolicy cachePolicy; - cachePolicy.setInheritFromParent( false ); - cachePolicy.setLocalParts( QStringList() << QLatin1String(MessagePart::Envelope) ); - cachePolicy.setSyncOnDemand( true ); - cachePolicy.setCacheTimeout( 1 ); + CachePolicy cachePolicy; + cachePolicy.setInheritFromParent(false); + cachePolicy.setLocalParts(QStringList() << QLatin1String(MessagePart::Envelope)); + cachePolicy.setSyncOnDemand(true); + cachePolicy.setCacheTimeout(1); - Collection modifiedCollection = collection; - modifiedCollection.setContentMimeTypes( contentMimeTypes ); - modifiedCollection.setRights( rights ); - modifiedCollection.setParentCollection( Collection::root() ); - modifiedCollection.setCachePolicy( cachePolicy ); + Collection modifiedCollection = collection; + modifiedCollection.setContentMimeTypes(contentMimeTypes); + modifiedCollection.setRights(rights); + modifiedCollection.setParentCollection(Collection::root()); + modifiedCollection.setCachePolicy(cachePolicy); - // clear caches - d->mMBoxes.clear(); - d->mMaildirs.clear(); + // clear caches + d->mMBoxes.clear(); + d->mMaildirs.clear(); - FileStore::AbstractLocalStore::setTopLevelCollection( modifiedCollection ); + FileStore::AbstractLocalStore::setTopLevelCollection(modifiedCollection); } -void MixedMaildirStore::processJob( FileStore::Job *job ) +void MixedMaildirStore::processJob(FileStore::Job *job) { - if ( !job->accept( d ) ) { - // check that an error has been set - if ( job->error() == 0 || job->errorString().isEmpty() ) { - kError() << "visitor did not set either error code or error string when returning false"; - Q_ASSERT( job->error() == 0 || job->errorString().isEmpty() ); - } - } else { - // check that no error has been set - if ( job->error() != 0 || !job->errorString().isEmpty() ) { - kError() << "visitor did set either error code or error string when returning true"; - Q_ASSERT( job->error() != 0 || !job->errorString().isEmpty() ); + if (!job->accept(d)) { + // check that an error has been set + if (job->error() == 0 || job->errorString().isEmpty()) { + qCritical() << "visitor did not set either error code or error string when returning false"; + Q_ASSERT(job->error() == 0 || job->errorString().isEmpty()); + } + } else { + // check that no error has been set + if (job->error() != 0 || !job->errorString().isEmpty()) { + qCritical() << "visitor did set either error code or error string when returning true"; + Q_ASSERT(job->error() != 0 || !job->errorString().isEmpty()); + } } - } } -void MixedMaildirStore::checkCollectionMove( FileStore::CollectionMoveJob *job, int &errorCode, QString &errorText ) const +void MixedMaildirStore::checkCollectionMove(FileStore::CollectionMoveJob *job, int &errorCode, QString &errorText) const { - // check if the target is not the collection itself or one if its children - Collection targetCollection = job->targetParent(); - while ( targetCollection.isValid() ) { - if ( targetCollection == job->collection() ) { - errorCode = FileStore::Job::InvalidJobContext; - errorText = i18nc( "@info:status", "Cannot move folder %1 into one of its own subfolder tree", job->collection().name() ); - return; - } + // check if the target is not the collection itself or one if its children + Collection targetCollection = job->targetParent(); + while (targetCollection.isValid()) { + if (targetCollection == job->collection()) { + errorCode = FileStore::Job::InvalidJobContext; + errorText = i18nc("@info:status", "Cannot move folder %1 into one of its own subfolder tree", job->collection().name()); + return; + } - targetCollection = targetCollection.parentCollection(); - } + targetCollection = targetCollection.parentCollection(); + } } -void MixedMaildirStore::checkItemCreate( FileStore::ItemCreateJob *job, int &errorCode, QString &errorText ) const +void MixedMaildirStore::checkItemCreate(FileStore::ItemCreateJob *job, int &errorCode, QString &errorText) const { - if ( !job->item().hasPayload() ) { - errorCode = FileStore::Job::InvalidJobContext; - errorText = i18nc( "@info:status", "Cannot add email to folder %1 because there is no email content", job->collection().name() ); - } + if (!job->item().hasPayload()) { + errorCode = FileStore::Job::InvalidJobContext; + errorText = i18nc("@info:status", "Cannot add email to folder %1 because there is no email content", job->collection().name()); + } } -void MixedMaildirStore::checkItemModify( FileStore::ItemModifyJob *job, int &errorCode, QString &errorText ) const +void MixedMaildirStore::checkItemModify(FileStore::ItemModifyJob *job, int &errorCode, QString &errorText) const { - if ( !job->ignorePayload() && !job->item().hasPayload() ) { - errorCode = FileStore::Job::InvalidJobContext; - errorText = i18nc( "@info:status", "Cannot modify email in folder %1 because there is no email content", job->item().parentCollection().name() ); - } + if (!job->ignorePayload() && !job->item().hasPayload()) { + errorCode = FileStore::Job::InvalidJobContext; + errorText = i18nc("@info:status", "Cannot modify email in folder %1 because there is no email content", job->item().parentCollection().name()); + } } -void MixedMaildirStore::checkItemFetch( FileStore::ItemFetchJob *job, int &errorCode, QString &errorText ) const +void MixedMaildirStore::checkItemFetch(FileStore::ItemFetchJob *job, int &errorCode, QString &errorText) const { - Q_UNUSED( errorCode ); - Q_UNUSED( errorText ); - const bool fetchSingleItem = job->collection().remoteId().isEmpty(); - if ( fetchSingleItem ) { - Collection coll = job->item().parentCollection(); - Q_ASSERT( !coll.remoteId().isEmpty() ); - } + Q_UNUSED(errorCode); + Q_UNUSED(errorText); + const bool fetchSingleItem = job->collection().remoteId().isEmpty(); + if (fetchSingleItem) { + Collection coll = job->item().parentCollection(); + Q_ASSERT(!coll.remoteId().isEmpty()); + } } - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildirstore.h kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildirstore.h --- kdepim-runtime-4.14.6/resources/mixedmaildir/mixedmaildirstore.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/mixedmaildirstore.h 2015-08-10 21:01:02.000000000 +0000 @@ -25,30 +25,29 @@ class MixedMaildirStore : public Akonadi::FileStore::AbstractLocalStore { - Q_OBJECT + Q_OBJECT - public: +public: MixedMaildirStore(); ~MixedMaildirStore(); - protected: - void setTopLevelCollection( const Akonadi::Collection &collection ); - void processJob( Akonadi::FileStore::Job *job ); +protected: + void setTopLevelCollection(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void processJob(Akonadi::FileStore::Job *job) Q_DECL_OVERRIDE; - void checkCollectionMove( Akonadi::FileStore::CollectionMoveJob *job, int &errorCode, QString &errorText ) const; + void checkCollectionMove(Akonadi::FileStore::CollectionMoveJob *job, int &errorCode, QString &errorText) const Q_DECL_OVERRIDE; - void checkItemCreate( Akonadi::FileStore::ItemCreateJob *job, int &errorCode, QString &errorText ) const; + void checkItemCreate(Akonadi::FileStore::ItemCreateJob *job, int &errorCode, QString &errorText) const Q_DECL_OVERRIDE; - void checkItemModify( Akonadi::FileStore::ItemModifyJob *job, int &errorCode, QString &errorText ) const; + void checkItemModify(Akonadi::FileStore::ItemModifyJob *job, int &errorCode, QString &errorText) const Q_DECL_OVERRIDE; - void checkItemFetch( Akonadi::FileStore::ItemFetchJob *job, int &errorCode, QString &errorText ) const; + void checkItemFetch(Akonadi::FileStore::ItemFetchJob *job, int &errorCode, QString &errorText) const Q_DECL_OVERRIDE; - private: +private: class Private; Private *const d; }; #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/retrieveitemsjob.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/retrieveitemsjob.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/retrieveitemsjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/retrieveitemsjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,21 +20,25 @@ #include "retrieveitemsjob.h" #include "mixedmaildirstore.h" +#include "mixedmaildir_debug.h" #include "filestore/itemfetchjob.h" #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mixedmaildirresource_debug.h" #include #include @@ -43,33 +47,33 @@ using namespace Akonadi; enum { - MaxItemCreateJobs = 100, - MaxItemModifyJobs = 100 + MaxItemCreateJobs = 100, + MaxItemModifyJobs = 100 }; class RetrieveItemsJob::Private { - RetrieveItemsJob *const q; + RetrieveItemsJob *const q; - public: - Private( RetrieveItemsJob *parent, const Collection &collection, MixedMaildirStore *store ) - : q( parent ), mCollection( collection ), mStore( store ), - mTransaction( 0 ), mHighestModTime( -1 ), mNumItemCreateJobs( 0 ), mNumItemModifyJobs( 0 ) +public: + Private(RetrieveItemsJob *parent, const Collection &collection, MixedMaildirStore *store) + : q(parent), mCollection(collection), mStore(store), + mTransaction(Q_NULLPTR), mHighestModTime(-1), mNumItemCreateJobs(0), mNumItemModifyJobs(0) { } TransactionSequence *transaction() { - if ( !mTransaction ) { - mTransaction = new TransactionSequence( q ); - mTransaction->setAutomaticCommittingEnabled( false ); - connect( mTransaction, SIGNAL(result(KJob*)), - q, SLOT(transactionResult(KJob*)) ); - } - return mTransaction; + if (!mTransaction) { + mTransaction = new TransactionSequence(q); + mTransaction->setAutomaticCommittingEnabled(false); + connect(mTransaction, SIGNAL(result(KJob*)), + q, SLOT(transactionResult(KJob*))); + } + return mTransaction; } - public: +public: const Collection mCollection; MixedMaildirStore *const mStore; TransactionSequence *mTransaction; @@ -84,276 +88,279 @@ int mNumItemCreateJobs; int mNumItemModifyJobs; - public: // slots - void akonadiFetchResult( KJob *job ); - void transactionResult( KJob *job ); - void storeListResult( KJob* ); +public: // slots + void akonadiFetchResult(KJob *job); + void transactionResult(KJob *job); + void storeListResult(KJob *); void processNewItem(); - void fetchNewResult( KJob* ); + void fetchNewResult(KJob *); void processChangedItem(); - void fetchChangedResult( KJob* ); - void itemCreateJobResult( KJob* ); - void itemModifyJobResult( KJob* ); + void fetchChangedResult(KJob *); + void itemCreateJobResult(KJob *); + void itemModifyJobResult(KJob *); }; -void RetrieveItemsJob::Private::itemCreateJobResult( KJob *job ) +void RetrieveItemsJob::Private::itemCreateJobResult(KJob *job) { - if ( job->error() ) { - kError() << "Error running ItemCreateJob: " << job->errorText(); - } + if (job->error()) { + qCCritical(MIXEDMAILDIR_LOG) << "Error running ItemCreateJob: " << job->errorText(); + } - mNumItemCreateJobs--; - QMetaObject::invokeMethod( q, "processNewItem", Qt::QueuedConnection ); + mNumItemCreateJobs--; + QMetaObject::invokeMethod(q, "processNewItem", Qt::QueuedConnection); } -void RetrieveItemsJob::Private::itemModifyJobResult( KJob *job ) +void RetrieveItemsJob::Private::itemModifyJobResult(KJob *job) { - if ( job->error() ) { - kError() << "Error running ItemModifyJob: " << job->errorText(); - } + if (job->error()) { + qCCritical(MIXEDMAILDIR_LOG) << "Error running ItemModifyJob: " << job->errorText(); + } - mNumItemModifyJobs--; - QMetaObject::invokeMethod( q, "processChangedItem", Qt::QueuedConnection ); + mNumItemModifyJobs--; + QMetaObject::invokeMethod(q, "processChangedItem", Qt::QueuedConnection); } -void RetrieveItemsJob::Private::akonadiFetchResult( KJob *job ) +void RetrieveItemsJob::Private::akonadiFetchResult(KJob *job) { - if ( job->error() != 0 ) return; // handled by base class - - ItemFetchJob *itemFetch = qobject_cast( job ); - Q_ASSERT( itemFetch != 0 ); + if (job->error() != 0) { + return; // handled by base class + } - Item::List items = itemFetch->items(); - itemFetch->clearItems(); // save memory - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Akonadi fetch got" << items.count() << "items"; + ItemFetchJob *itemFetch = qobject_cast(job); + Q_ASSERT(itemFetch != 0); - mServerItemsByRemoteId.reserve( items.size() ); - for ( int i = 0 ; i < items.count() ; ++i ) { - Item &item = items[i]; - // items without remoteId have not been written to the resource yet - if ( !item.remoteId().isEmpty() ) { - // set the parent collection (with all ancestors) in every item - item.setParentCollection( mCollection ); - mServerItemsByRemoteId.insert( item.remoteId(), item ); + Item::List items = itemFetch->items(); + itemFetch->clearItems(); // save memory + qCDebug(MIXEDMAILDIR_LOG) << "Akonadi fetch got" << items.count() << "items"; + + mServerItemsByRemoteId.reserve(items.size()); + for (int i = 0 ; i < items.count() ; ++i) { + Item &item = items[i]; + // items without remoteId have not been written to the resource yet + if (!item.remoteId().isEmpty()) { + // set the parent collection (with all ancestors) in every item + item.setParentCollection(mCollection); + mServerItemsByRemoteId.insert(item.remoteId(), item); + } } - } - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "of which" << mServerItemsByRemoteId.count() << "have remoteId"; + qCDebug(MIXEDMAILDIR_LOG) << "of which" << mServerItemsByRemoteId.count() << "have remoteId"; - FileStore::ItemFetchJob *storeFetch = mStore->fetchItems( mCollection ); - // just basic items, no data + FileStore::ItemFetchJob *storeFetch = mStore->fetchItems(mCollection); + // just basic items, no data - connect( storeFetch, SIGNAL(result(KJob*)), q, SLOT(storeListResult(KJob*)) ); + connect(storeFetch, SIGNAL(result(KJob*)), q, SLOT(storeListResult(KJob*))); } -void RetrieveItemsJob::Private::storeListResult( KJob *job ) +void RetrieveItemsJob::Private::storeListResult(KJob *job) { - kDebug() << "storeList->error=" << job->error(); - FileStore::ItemFetchJob *storeList = qobject_cast( job ); - Q_ASSERT( storeList != 0 ); + qCDebug(MIXEDMAILDIRRESOURCE_LOG) << "storeList->error=" << job->error(); + FileStore::ItemFetchJob *storeList = qobject_cast(job); + Q_ASSERT(storeList != 0); - if ( storeList->error() != 0 ) { - q->setError( storeList->error() ); - q->setErrorText( storeList->errorText() ); - q->emitResult(); - return; - } + if (storeList->error() != 0) { + q->setError(storeList->error()); + q->setErrorText(storeList->errorText()); + q->emitResult(); + return; + } - // if some items have tags, we need to complete the retrieval and schedule tagging - // to a later time so we can then fetch the items to get their Akonadi URLs - // forward the property to this instance so the resource can take care of that - const QVariant var = storeList->property( "remoteIdToTagList" ); - if ( var.isValid() ) { - q->setProperty( "remoteIdToTagList", var ); - } - - const qint64 collectionTimestamp = mCollection.remoteRevision().toLongLong(); - - const Item::List storedItems = storeList->items(); - Q_FOREACH( const Item &item, storedItems ) { - // messages marked as deleted have been deleted from mbox files but never got purged - Akonadi::MessageStatus status; - status.setStatusFromFlags( item.flags() ); - if ( status.isDeleted() ) { - mItemsMarkedAsDeleted << item; - continue; - } - - mAvailableItems << item; - - const QHash::iterator it = mServerItemsByRemoteId.find( item.remoteId() ); - if ( it == mServerItemsByRemoteId.end() ) { - // item not in server items -> new - mNewItems << item; - } else { - // item both on server and in store, check modification time - const QDateTime modTime = item.modificationTime(); - if ( !modTime.isValid() || modTime.toMSecsSinceEpoch() > collectionTimestamp ) { - mChangedItems << it.value(); - } - - // remove from hash so only no longer existing items remain - mServerItemsByRemoteId.erase( it ); - } - } - - kDebug( KDE_DEFAULT_DEBUG_AREA ) << "Store fetch got" << storedItems.count() << "items" - << "of which" << mNewItems.count() << "are new and" << mChangedItems.count() - << "are changed and" << mServerItemsByRemoteId.count() - << "need to be removed"; - - // all items remaining in mServerItemsByRemoteId are no longer in the store - - if ( !mServerItemsByRemoteId.isEmpty() ) { - ItemDeleteJob *deleteJob = new ItemDeleteJob( mServerItemsByRemoteId.values(), transaction() ); - transaction()->setIgnoreJobFailure( deleteJob ); - } + // if some items have tags, we need to complete the retrieval and schedule tagging + // to a later time so we can then fetch the items to get their Akonadi URLs + // forward the property to this instance so the resource can take care of that + const QVariant var = storeList->property("remoteIdToTagList"); + if (var.isValid()) { + q->setProperty("remoteIdToTagList", var); + } - processNewItem(); + const qint64 collectionTimestamp = mCollection.remoteRevision().toLongLong(); + + const Item::List storedItems = storeList->items(); + Q_FOREACH (const Item &item, storedItems) { + // messages marked as deleted have been deleted from mbox files but never got purged + Akonadi::MessageStatus status; + status.setStatusFromFlags(item.flags()); + if (status.isDeleted()) { + mItemsMarkedAsDeleted << item; + continue; + } + + mAvailableItems << item; + + const QHash::iterator it = mServerItemsByRemoteId.find(item.remoteId()); + if (it == mServerItemsByRemoteId.end()) { + // item not in server items -> new + mNewItems << item; + } else { + // item both on server and in store, check modification time + const QDateTime modTime = item.modificationTime(); + if (!modTime.isValid() || modTime.toMSecsSinceEpoch() > collectionTimestamp) { + mChangedItems << it.value(); + } + + // remove from hash so only no longer existing items remain + mServerItemsByRemoteId.erase(it); + } + } + + qCDebug(MIXEDMAILDIR_LOG) << "Store fetch got" << storedItems.count() << "items" + << "of which" << mNewItems.count() << "are new and" << mChangedItems.count() + << "are changed and" << mServerItemsByRemoteId.count() + << "need to be removed"; + + // all items remaining in mServerItemsByRemoteId are no longer in the store + + if (!mServerItemsByRemoteId.isEmpty()) { + ItemDeleteJob *deleteJob = new ItemDeleteJob(Akonadi::valuesToVector(mServerItemsByRemoteId), transaction()); + transaction()->setIgnoreJobFailure(deleteJob); + } + + processNewItem(); } void RetrieveItemsJob::Private::processNewItem() { - if ( mNewItems.isEmpty() ) { - processChangedItem(); - return; - } - - const Item item = mNewItems.dequeue(); - FileStore::ItemFetchJob *storeFetch = mStore->fetchItem( item ); - storeFetch->fetchScope().fetchPayloadPart( MessagePart::Envelope ); - - connect( storeFetch, SIGNAL(result(KJob*)), q, SLOT(fetchNewResult(KJob*)) ); -} - -void RetrieveItemsJob::Private::fetchNewResult( KJob *job ) -{ - FileStore::ItemFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob != 0 ); - - if ( fetchJob->items().count() != 1 ) { - const Item item = fetchJob->item(); - kWarning() << "Store fetch for new item" << item.remoteId() - << "in collection" << item.parentCollection().id() - << "," << item.parentCollection().remoteId() - << "did not return the expected item. error=" - << fetchJob->error() << "," << fetchJob->errorText(); - processNewItem(); - return; - } + if (mNewItems.isEmpty()) { + processChangedItem(); + return; + } + + const Item item = mNewItems.dequeue(); + FileStore::ItemFetchJob *storeFetch = mStore->fetchItem(item); + storeFetch->fetchScope().fetchPayloadPart(MessagePart::Envelope); + + connect(storeFetch, SIGNAL(result(KJob*)), q, SLOT(fetchNewResult(KJob*))); +} + +void RetrieveItemsJob::Private::fetchNewResult(KJob *job) +{ + FileStore::ItemFetchJob *fetchJob = qobject_cast(job); + Q_ASSERT(fetchJob != 0); + + if (fetchJob->items().count() != 1) { + const Item item = fetchJob->item(); + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "Store fetch for new item" << item.remoteId() + << "in collection" << item.parentCollection().id() + << "," << item.parentCollection().remoteId() + << "did not return the expected item. error=" + << fetchJob->error() << "," << fetchJob->errorText(); + processNewItem(); + return; + } + + const Item item = fetchJob->items().at(0); + const QDateTime modTime = item.modificationTime(); + if (modTime.isValid()) { + mHighestModTime = qMax(modTime.toMSecsSinceEpoch(), mHighestModTime); + } + + ItemCreateJob *itemCreate = new ItemCreateJob(item, mCollection, transaction()); + mNumItemCreateJobs++; + connect(itemCreate, SIGNAL(result(KJob*)), q, SLOT(itemCreateJobResult(KJob*))); - const Item item = fetchJob->items().first(); - const QDateTime modTime = item.modificationTime(); - if ( modTime.isValid() ) { - mHighestModTime = qMax( modTime.toMSecsSinceEpoch(), mHighestModTime ); - } - - ItemCreateJob *itemCreate = new ItemCreateJob( item, mCollection, transaction() ); - mNumItemCreateJobs++; - connect( itemCreate, SIGNAL(result(KJob*)), q, SLOT(itemCreateJobResult(KJob*)) ); - - if (mNumItemCreateJobs < MaxItemCreateJobs ) { - QMetaObject::invokeMethod( q, "processNewItem", Qt::QueuedConnection ); - } + if (mNumItemCreateJobs < MaxItemCreateJobs) { + QMetaObject::invokeMethod(q, "processNewItem", Qt::QueuedConnection); + } } void RetrieveItemsJob::Private::processChangedItem() { - if ( mChangedItems.isEmpty() ) { - if ( !mTransaction ) { - // no jobs created here -> done - q->emitResult(); - return; - } - - if ( mHighestModTime > -1 ) { - Collection collection( mCollection ); - collection.setRemoteRevision( QString::number( mHighestModTime ) ); - CollectionModifyJob *job = new CollectionModifyJob( collection, transaction() ); - transaction()->setIgnoreJobFailure( job ); - } - transaction()->commit(); - return; - } - - const Item item = mChangedItems.dequeue(); - FileStore::ItemFetchJob *storeFetch = mStore->fetchItem( item ); - storeFetch->fetchScope().fetchPayloadPart( MessagePart::Envelope ); - - connect( storeFetch, SIGNAL(result(KJob*)), q, SLOT(fetchChangedResult(KJob*)) ); -} - -void RetrieveItemsJob::Private::fetchChangedResult( KJob *job ) -{ - FileStore::ItemFetchJob *fetchJob = qobject_cast( job ); - Q_ASSERT( fetchJob != 0 ); - - if ( fetchJob->items().count() != 1 ) { - const Item item = fetchJob->item(); - kWarning() << "Store fetch for changed item" << item.remoteId() - << "in collection" << item.parentCollection().id() - << "," << item.parentCollection().remoteId() - << "did not return the expected item. error=" - << fetchJob->error() << "," << fetchJob->errorText(); - processChangedItem(); - return; - } - - const Item item = fetchJob->items().first(); - const QDateTime modTime = item.modificationTime(); - if ( modTime.isValid() ) { - mHighestModTime = qMax( modTime.toMSecsSinceEpoch(), mHighestModTime ); - } - - ItemModifyJob *itemModify = new ItemModifyJob( item, transaction() ); - connect( itemModify, SIGNAL(result(KJob*)), q, SLOT(itemModifyJobResult(KJob*)) ); - mNumItemModifyJobs++; - if ( mNumItemModifyJobs < MaxItemModifyJobs ) { - QMetaObject::invokeMethod( q, "processChangedItem", Qt::QueuedConnection ); - } -} - -void RetrieveItemsJob::Private::transactionResult( KJob *job ) -{ - if ( job->error() != 0 ) return; // handled by base class - - q->emitResult(); -} - -RetrieveItemsJob::RetrieveItemsJob( const Akonadi::Collection &collection, MixedMaildirStore *store, QObject* parent ) - : Job( parent ), d( new Private( this, collection, store ) ) -{ - Q_ASSERT( d->mCollection.isValid() ); - Q_ASSERT( !d->mCollection.remoteId().isEmpty() ); - Q_ASSERT( d->mStore != 0 ); + if (mChangedItems.isEmpty()) { + if (!mTransaction) { + // no jobs created here -> done + q->emitResult(); + return; + } + + if (mHighestModTime > -1) { + Collection collection(mCollection); + collection.setRemoteRevision(QString::number(mHighestModTime)); + CollectionModifyJob *job = new CollectionModifyJob(collection, transaction()); + transaction()->setIgnoreJobFailure(job); + } + transaction()->commit(); + return; + } + + const Item item = mChangedItems.dequeue(); + FileStore::ItemFetchJob *storeFetch = mStore->fetchItem(item); + storeFetch->fetchScope().fetchPayloadPart(MessagePart::Envelope); + + connect(storeFetch, SIGNAL(result(KJob*)), q, SLOT(fetchChangedResult(KJob*))); +} + +void RetrieveItemsJob::Private::fetchChangedResult(KJob *job) +{ + FileStore::ItemFetchJob *fetchJob = qobject_cast(job); + Q_ASSERT(fetchJob != 0); + + if (fetchJob->items().count() != 1) { + const Item item = fetchJob->item(); + qCWarning(MIXEDMAILDIRRESOURCE_LOG) << "Store fetch for changed item" << item.remoteId() + << "in collection" << item.parentCollection().id() + << "," << item.parentCollection().remoteId() + << "did not return the expected item. error=" + << fetchJob->error() << "," << fetchJob->errorText(); + processChangedItem(); + return; + } + + const Item item = fetchJob->items().at(0); + const QDateTime modTime = item.modificationTime(); + if (modTime.isValid()) { + mHighestModTime = qMax(modTime.toMSecsSinceEpoch(), mHighestModTime); + } + + ItemModifyJob *itemModify = new ItemModifyJob(item, transaction()); + connect(itemModify, SIGNAL(result(KJob*)), q, SLOT(itemModifyJobResult(KJob*))); + mNumItemModifyJobs++; + if (mNumItemModifyJobs < MaxItemModifyJobs) { + QMetaObject::invokeMethod(q, "processChangedItem", Qt::QueuedConnection); + } +} + +void RetrieveItemsJob::Private::transactionResult(KJob *job) +{ + if (job->error() != 0) { + return; // handled by base class + } + + q->emitResult(); +} + +RetrieveItemsJob::RetrieveItemsJob(const Akonadi::Collection &collection, MixedMaildirStore *store, QObject *parent) + : Job(parent), d(new Private(this, collection, store)) +{ + Q_ASSERT(d->mCollection.isValid()); + Q_ASSERT(!d->mCollection.remoteId().isEmpty()); + Q_ASSERT(d->mStore != 0); } RetrieveItemsJob::~RetrieveItemsJob() { - delete d; + delete d; } Collection RetrieveItemsJob::collection() const { - return d->mCollection; + return d->mCollection; } Item::List RetrieveItemsJob::availableItems() const { - return d->mAvailableItems; + return d->mAvailableItems; } Item::List RetrieveItemsJob::itemsMarkedAsDeleted() const { - return d->mItemsMarkedAsDeleted; + return d->mItemsMarkedAsDeleted; } void RetrieveItemsJob::doStart() { - ItemFetchJob *job = new Akonadi::ItemFetchJob( d->mCollection, this ); - connect( job, SIGNAL(result(KJob*)), this, SLOT(akonadiFetchResult(KJob*)) ); + ItemFetchJob *job = new Akonadi::ItemFetchJob(d->mCollection, this); + connect(job, SIGNAL(result(KJob*)), this, SLOT(akonadiFetchResult(KJob*))); } #include "moc_retrieveitemsjob.cpp" -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/retrieveitemsjob.h kdepim-runtime-15.08.0/resources/mixedmaildir/retrieveitemsjob.h --- kdepim-runtime-4.14.6/resources/mixedmaildir/retrieveitemsjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/retrieveitemsjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,12 +20,12 @@ #ifndef MIXEDMAILDIR_RETRIEVEITEMSJOB_H #define MIXEDMAILDIR_RETRIEVEITEMSJOB_H -#include -#include +#include +#include namespace Akonadi { - class Collection; +class Collection; } class MixedMaildirStore; @@ -36,36 +36,35 @@ */ class RetrieveItemsJob : public Akonadi::Job { - Q_OBJECT - public: - RetrieveItemsJob( const Akonadi::Collection &collection, MixedMaildirStore *store, QObject* parent = 0 ); - + Q_OBJECT +public: + RetrieveItemsJob(const Akonadi::Collection &collection, MixedMaildirStore *store, QObject *parent = Q_NULLPTR); + ~RetrieveItemsJob(); Akonadi::Collection collection() const; Akonadi::Item::List availableItems() const; - + Akonadi::Item::List itemsMarkedAsDeleted() const; - - protected: + +protected: void doStart(); - private: +private: class Private; Private *const d; - Q_PRIVATE_SLOT( d, void itemModifyJobResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void itemCreateJobResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void akonadiFetchResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void transactionResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void storeListResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void processNewItem() ) - Q_PRIVATE_SLOT( d, void fetchNewResult( KJob* ) ) - Q_PRIVATE_SLOT( d, void processChangedItem() ) - Q_PRIVATE_SLOT( d, void fetchChangedResult( KJob* ) ) + Q_PRIVATE_SLOT(d, void itemModifyJobResult(KJob *)) + Q_PRIVATE_SLOT(d, void itemCreateJobResult(KJob *)) + Q_PRIVATE_SLOT(d, void akonadiFetchResult(KJob *)) + Q_PRIVATE_SLOT(d, void transactionResult(KJob *)) + Q_PRIVATE_SLOT(d, void storeListResult(KJob *)) + Q_PRIVATE_SLOT(d, void processNewItem()) + Q_PRIVATE_SLOT(d, void fetchNewResult(KJob *)) + Q_PRIVATE_SLOT(d, void processChangedItem()) + Q_PRIVATE_SLOT(d, void fetchChangedResult(KJob *)) }; #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/CMakeLists.txt kdepim-runtime-15.08.0/resources/mixedmaildir/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,206 +0,0 @@ -if(${EXECUTABLE_OUTPUT_PATH}) - set( PREVIOUS_EXEC_OUTPUT_PATH ${EXECUTABLE_OUTPUT_PATH} ) -else() - set( PREVIOUS_EXEC_OUTPUT_PATH . ) -endif() -set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) - -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - -include_directories( - ${AKONADI_INCLUDE_DIR} - ${KDE4_INCLUDES} - ${KDEPIMLIBS_INCLUDE_DIR} - ${QT_INCLUDES} - ${Boost_INCLUDE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../ - ${CMAKE_CURRENT_BINARY_DIR}/../ - ${CMAKE_CURRENT_SOURCE_DIR} -) - -# test data -qt4_add_resources( testdata_generated_SRCS testdata.qrc ) - -set( testdata_SRCS - ${testdata_generated_SRCS} - testdatautil.cpp -) - -kde4_add_unit_test( testdatatest - TESTNAME mixedmaildir-testdatatest - testdatatest.cpp - ${testdata_SRCS} -) - -target_link_libraries( - testdatatest - ${KDE4_KDECORE_LIBS} - ${QT_QTTEST_LIBRARY} - ${QT_QTGUI_LIBRARY} -) - -# put the libraries all tests link against into a variable and use it -# in target_link_libraries instead -set( common_link_libraries - kmindexreader - maildir - akonadi-filestore - ${KDEPIMLIBS_AKONADI_KMIME_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KMBOX_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${KDEPIMLIBS_KPIMUTILS_LIBS} - ${QT_QTTEST_LIBRARY} -) - -# test for overwritten methods -kde4_add_unit_test( templatemethodstest - TESTNAME mixedmaildir-templatemethodtest - ../mixedmaildirstore.cpp - templatemethodstest.cpp -) - -target_link_libraries( - templatemethodstest - ${common_link_libraries} -) - -# test for collection creation handling -kde4_add_unit_test( collectioncreatetest - TESTNAME mixedmaildir-collectioncreatetest - ../mixedmaildirstore.cpp - collectioncreatetest.cpp -) - -target_link_libraries( - collectioncreatetest - ${common_link_libraries} -) - -# test for collection deletion handling -kde4_add_unit_test( collectiondeletetest - TESTNAME mixedmaildir-collectiondeletetest - ../mixedmaildirstore.cpp - collectiondeletetest.cpp -) - -target_link_libraries( - collectiondeletetest - ${common_link_libraries} -) - -# test for collection fetching handling -kde4_add_unit_test( collectionfetchtest - TESTNAME mixedmaildir-collectionfetchtest - ../mixedmaildirstore.cpp - collectionfetchtest.cpp -) - -target_link_libraries( - collectionfetchtest - ${common_link_libraries} -) - -# test for collection modification handling -kde4_add_unit_test( collectionmodifytest - TESTNAME mixedmaildir-collectionmodifytest - ../mixedmaildirstore.cpp - collectionmodifytest.cpp - ${testdata_SRCS} -) - -target_link_libraries( - collectionmodifytest - ${common_link_libraries} -) - -# test for collection move handling -kde4_add_unit_test( collectionmovetest - TESTNAME mixedmaildir-collectionmovetest - ../mixedmaildirstore.cpp - collectionmovetest.cpp - ${testdata_SRCS} -) - -target_link_libraries( - collectionmovetest - ${common_link_libraries} -) - -# test for item creation handling -kde4_add_unit_test( itemcreatetest - TESTNAME mixedmaildir-itemcreatetest - ../mixedmaildirstore.cpp - itemcreatetest.cpp - ${testdata_SRCS} -) - -target_link_libraries( - itemcreatetest - ${common_link_libraries} -) - -# test for item creation handling -kde4_add_unit_test( itemdeletetest - TESTNAME mixedmaildir-itemdeletetest - ../mixedmaildirstore.cpp - itemdeletetest.cpp - ${testdata_SRCS} -) - -target_link_libraries( - itemdeletetest - ${common_link_libraries} -) - -# test for item retrieval handling -kde4_add_unit_test( itemfetchtest - TESTNAME mixedmaildir-itemfetchtest - ../mixedmaildirstore.cpp - itemfetchtest.cpp - ${testdata_SRCS} -) - -target_link_libraries( - itemfetchtest - ${common_link_libraries} -) - -# test for item modification handling -kde4_add_unit_test( itemmodifytest - TESTNAME mixedmaildir-itemmodifytest - ../mixedmaildirstore.cpp - itemmodifytest.cpp - ${testdata_SRCS} -) - -target_link_libraries( - itemmodifytest - ${common_link_libraries} -) - -# test for item move handling -kde4_add_unit_test( itemmovetest - TESTNAME mixedmaildir-itemmovetest - ../mixedmaildirstore.cpp - itemmovetest.cpp - ${testdata_SRCS} -) - -target_link_libraries( - itemmovetest - ${common_link_libraries} -) - -# test for store compact handling -kde4_add_unit_test( storecompacttest - TESTNAME mixedmaildir-storecompacttest - ../mixedmaildirstore.cpp - storecompacttest.cpp - ${testdata_SRCS} -) - -target_link_libraries( - storecompacttest - ${common_link_libraries} -) diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/collectioncreatetest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/tests/collectioncreatetest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/collectioncreatetest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/collectioncreatetest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,326 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" - -#include "filestore/collectioncreatejob.h" - -#include "libmaildir/maildir.h" - -#include - -#include - -#include - -using namespace Akonadi; - -class CollectionCreateTest : public QObject -{ - Q_OBJECT - - public: - CollectionCreateTest() : QObject(), mStore( 0 ), mDir( 0 ) {} - ~CollectionCreateTest() { - delete mStore; - delete mDir; - } - - private: - MixedMaildirStore *mStore; - KTempDir *mDir; - - private Q_SLOTS: - void init(); - void cleanup(); - void testCollectionProperties(); - void testEmptyDir(); - void testMaildirTree(); - void testMixedTree(); -}; - -void CollectionCreateTest::init() -{ - mStore = new MixedMaildirStore; - - mDir = new KTempDir; - QVERIFY( mDir->exists() ); -} - -void CollectionCreateTest::cleanup() -{ - delete mStore; - mStore = 0; - delete mDir; - mDir = 0; -} - -void CollectionCreateTest::testCollectionProperties() -{ - mStore->setPath( mDir->name() ); - - FileStore::CollectionCreateJob *job = 0; - - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - job = mStore->createCollection( collection1, mStore->topLevelCollection() ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection1 = job->collection(); - QCOMPARE( collection1.remoteId(), collection1.name() ); - - QCOMPARE( collection1.contentMimeTypes(), QStringList() << Collection::mimeType() << KMime::Message::mimeType() ); - - QCOMPARE( collection1.rights(), Collection::CanCreateItem | - Collection::CanChangeItem | - Collection::CanDeleteItem | - Collection::CanCreateCollection | - Collection::CanChangeCollection | - Collection::CanDeleteCollection ); -} - -void CollectionCreateTest::testEmptyDir() -{ - mStore->setPath( mDir->name() ); - - KPIM::Maildir topLevelMd( mStore->path(), true ); - - FileStore::CollectionCreateJob *job = 0; - - // test creating first level collections - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - job = mStore->createCollection( collection1, mStore->topLevelCollection() ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection1 = job->collection(); - QVERIFY( !collection1.remoteId().isEmpty() ); - QVERIFY( collection1.parentCollection() == mStore->topLevelCollection() ); - - QCOMPARE( topLevelMd.subFolderList(), QStringList() << QLatin1String( "collection1" ) ); - KPIM::Maildir md1 = topLevelMd.subFolder( collection1.remoteId() ); - QVERIFY( md1.isValid() ); - - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - job = mStore->createCollection( collection2, mStore->topLevelCollection() ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection2 = job->collection(); - QVERIFY( !collection2.remoteId().isEmpty() ); - QVERIFY( collection2.parentCollection() == mStore->topLevelCollection() ); - - QCOMPARE( topLevelMd.subFolderList(), QStringList() << QLatin1String( "collection1" ) << QLatin1String( "collection2" ) ); - KPIM::Maildir md2 = topLevelMd.subFolder( collection2.remoteId() ); - QVERIFY( md2.isValid() ); - - // test creating second level collections - Collection collection1_1; - collection1_1.setName( QLatin1String( "collection1_1" ) ); - job = mStore->createCollection( collection1_1, collection1 ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection1_1 = job->collection(); - QVERIFY( !collection1_1.remoteId().isEmpty() ); - QVERIFY( collection1_1.parentCollection() == collection1 ); - - QCOMPARE( md1.subFolderList(), QStringList() << QLatin1String( "collection1_1" ) ); - KPIM::Maildir md1_1 = md1.subFolder( collection1_1.remoteId() ); - QVERIFY( md1_1.isValid() ); - - Collection collection1_2; - collection1_2.setName( QLatin1String( "collection1_2" ) ); - job = mStore->createCollection( collection1_2, collection1 ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection1_2 = job->collection(); - QVERIFY( !collection1_2.remoteId().isEmpty() ); - QVERIFY( collection1_2.parentCollection() == collection1 ); - - QCOMPARE( md1.subFolderList(), QStringList() << QLatin1String( "collection1_1" ) << QLatin1String( "collection1_2" ) ); - KPIM::Maildir md1_2 = md1.subFolder( collection1_2.remoteId() ); - QVERIFY( md1_2.isValid() ); - - QCOMPARE( md2.subFolderList(), QStringList() ); -} - -void CollectionCreateTest::testMaildirTree() -{ - KPIM::Maildir topLevelMd( mDir->name(), true ); - QVERIFY( topLevelMd.isValid() ); - - KPIM::Maildir md1( topLevelMd.addSubFolder( "collection1" ), false ); - - KPIM::Maildir md1_2( md1.addSubFolder( "collection1_2" ), false ); - - mStore->setPath( mDir->name() ); - - FileStore::CollectionCreateJob *job = 0; - - // test creating first level collections - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - job = mStore->createCollection( collection1, mStore->topLevelCollection() ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); // works because it already exists - QCOMPARE( job->error(), 0 ); - - collection1 = job->collection(); - QVERIFY( !collection1.remoteId().isEmpty() ); - QVERIFY( collection1.parentCollection() == mStore->topLevelCollection() ); - - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - job = mStore->createCollection( collection2, mStore->topLevelCollection() ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection2 = job->collection(); - QVERIFY( !collection2.remoteId().isEmpty() ); - QVERIFY( collection2.parentCollection() == mStore->topLevelCollection() ); - - QCOMPARE( topLevelMd.subFolderList(), QStringList() << QLatin1String( "collection1" ) << QLatin1String( "collection2" ) ); - KPIM::Maildir md2 = topLevelMd.subFolder( collection2.remoteId() ); - QVERIFY( md2.isValid() ); - - // test creating second level collections - Collection collection1_1; - collection1_1.setName( QLatin1String( "collection1_1" ) ); - job = mStore->createCollection( collection1_1, collection1 ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection1_1 = job->collection(); - QVERIFY( !collection1_1.remoteId().isEmpty() ); - QCOMPARE( collection1_1.parentCollection().remoteId(), QLatin1String( "collection1" ) ); - - QCOMPARE( md1.subFolderList(), QStringList() << QLatin1String( "collection1_1" ) << QLatin1String( "collection1_2" ) ); - KPIM::Maildir md1_1 = md1.subFolder( collection1_1.remoteId() ); - QVERIFY( md1_1.isValid() ); - - Collection collection1_2; - collection1_2.setName( QLatin1String( "collection1_2" ) ); - job = mStore->createCollection( collection1_2, collection1 ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); // works because it already exists - QCOMPARE( job->error(), 0 ); - - collection1_2 = job->collection(); - QVERIFY( !collection1_2.remoteId().isEmpty() ); - QCOMPARE( collection1_2.parentCollection().remoteId(), QLatin1String( "collection1" ) ); - - QCOMPARE( md2.subFolderList(), QStringList() ); -} - -void CollectionCreateTest::testMixedTree() -{ - KPIM::Maildir topLevelMd( mDir->name(), true ); - QVERIFY( topLevelMd.isValid() ); - - // simulate a first level MBox - QFileInfo fileInfo1( mDir->name(), QLatin1String( "collection1" ) ); - QFile file1( fileInfo1.absoluteFilePath() ); - file1.open( QIODevice::WriteOnly ); - file1.close(); - QVERIFY( fileInfo1.exists() ); - - mStore->setPath( mDir->name() ); - - FileStore::CollectionCreateJob *job = 0; - - // test creating first level collections - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - job = mStore->createCollection( collection1, mStore->topLevelCollection() ); - QVERIFY( job != 0 ); - - QVERIFY( !job->exec() ); // fails, there is an MBox with that name - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - collection1 = job->collection(); - QVERIFY( collection1.remoteId().isEmpty() ); - - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - job = mStore->createCollection( collection2, mStore->topLevelCollection() ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection2 = job->collection(); - QVERIFY( !collection2.remoteId().isEmpty() ); - QVERIFY( collection2.parentCollection() == mStore->topLevelCollection() ); - - // mbox does not show up as a maildir subfolder - QCOMPARE( topLevelMd.subFolderList(), QStringList() << QLatin1String( "collection2" ) ); - KPIM::Maildir md2 = topLevelMd.subFolder( collection2.remoteId() ); - QVERIFY( md2.isValid() ); - - // test creating second level collections inside mbox - Collection collection1_1; - collection1_1.setName( QLatin1String( "collection1_1" ) ); - job = mStore->createCollection( collection1_1, collection1 ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection1_1 = job->collection(); - QVERIFY( !collection1_1.remoteId().isEmpty() ); - QCOMPARE( collection1_1.parentCollection().remoteId(), QLatin1String( "collection1" ) ); - - // treat the MBox subdir path like a top level maildir - KPIM::Maildir md1( KPIM::Maildir::subDirPathForFolderPath( fileInfo1.absoluteFilePath() ), true ); - KPIM::Maildir md1_1 = md1.subFolder( collection1_1.remoteId() ); - QVERIFY( md1_1.isValid() ); - - QCOMPARE( md1.subFolderList(), QStringList() << QLatin1String( "collection1_1" ) ); -} - -QTEST_KDEMAIN( CollectionCreateTest, NoGUI ) - -#include "collectioncreatetest.moc" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/collectiondeletetest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/tests/collectiondeletetest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/collectiondeletetest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/collectiondeletetest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,465 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" - -#include "filestore/collectiondeletejob.h" - -#include "libmaildir/maildir.h" - -#include - -#include - -using namespace Akonadi; - -class CollectionDeleteTest : public QObject -{ - Q_OBJECT - - public: - CollectionDeleteTest() : QObject(), mStore( 0 ), mDir( 0 ) {} - ~CollectionDeleteTest() { - delete mStore; - delete mDir; - } - - private: - MixedMaildirStore *mStore; - KTempDir *mDir; - - private Q_SLOTS: - void init(); - void cleanup(); - void testNonExisting(); - void testLeaves(); - void testSubTrees(); -}; - -void CollectionDeleteTest::init() -{ - mStore = new MixedMaildirStore; - - mDir = new KTempDir; - QVERIFY( mDir->exists() ); -} - -void CollectionDeleteTest::cleanup() -{ - delete mStore; - mStore = 0; - delete mDir; - mDir = 0; -} - -void CollectionDeleteTest::testNonExisting() -{ - KPIM::Maildir topLevelMd( mDir->name(), true ); - QVERIFY( topLevelMd.isValid( false ) ); - - KPIM::Maildir md1( topLevelMd.addSubFolder( "collection1" ), false ); - KPIM::Maildir md1_2( md1.addSubFolder( "collection1_2" ), false ); - - KPIM::Maildir md2( topLevelMd.addSubFolder( "collection2" ), false ); - - // simulate mbox - QFileInfo fileInfo1( mDir->name(), QLatin1String( "collection3" ) ); - QFile file1( fileInfo1.absoluteFilePath() ); - file1.open( QIODevice::WriteOnly ); - file1.close(); - QVERIFY( fileInfo1.exists() ); - - // simulate mbox with empty subtree - QFileInfo fileInfo2( mDir->name(), QLatin1String( "collection4" ) ); - QFile file2( fileInfo2.absoluteFilePath() ); - file2.open( QIODevice::WriteOnly ); - file2.close(); - QVERIFY( fileInfo2.exists() ); - - QFileInfo subDirInfo2( KPIM::Maildir::subDirPathForFolderPath( fileInfo2.absoluteFilePath() ) ); - QDir topDir( mDir->name() ); - QVERIFY( topDir.mkpath( subDirInfo2.absoluteFilePath() ) ); - - mStore->setPath( mDir->name() ); - - FileStore::CollectionDeleteJob *job = 0; - - // test fail of deleting first level collection - Collection collection5; - collection5.setName( QLatin1String( "collection5" ) ); - collection5.setRemoteId( QLatin1String( "collection5" ) ); - collection5.setParentCollection( mStore->topLevelCollection() ); - job = mStore->deleteCollection( collection5 ); - QVERIFY( job != 0 ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - QCOMPARE( topLevelMd.subFolderList(), QStringList() << QLatin1String( "collection1" ) << QLatin1String( "collection2" ) ); - QVERIFY( fileInfo1.exists() ); - - // test fail of deleting second level collection in maildir leaf parent - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - Collection collection2_1; - collection2_1.setName( QLatin1String( "collection2_1" ) ); - collection2_1.setRemoteId( QLatin1String( "collection2_1" ) ); - collection2_1.setParentCollection( collection2 ); - job = mStore->deleteCollection( collection2_1 ); - QVERIFY( job != 0 ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - QCOMPARE( topLevelMd.subFolderList(), QStringList() << QLatin1String( "collection1" ) << QLatin1String( "collection2" ) ); - - // test fail of deleting second level collection in maildir parent with subtree - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - Collection collection1_1; - collection1_1.setName( QLatin1String( "collection1_1" ) ); - collection1_1.setRemoteId( QLatin1String( "collection1_1" ) ); - collection1_1.setParentCollection( collection1 ); - job = mStore->deleteCollection( collection1_1 ); - QVERIFY( job != 0 ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - QCOMPARE( topLevelMd.subFolderList(), QStringList() << QLatin1String( "collection1" ) << QLatin1String( "collection2" ) ); - QCOMPARE( md1.subFolderList(), QStringList() << QLatin1String( "collection1_2" ) ); - - // test fail of deleting second level collection in mbox leaf parent - Collection collection3; - collection3.setName( QLatin1String( "collection3" ) ); - collection3.setRemoteId( QLatin1String( "collection3" ) ); - collection3.setParentCollection( mStore->topLevelCollection() ); - - Collection collection3_1; - collection3_1.setName( QLatin1String( "collection3_1" ) ); - collection3_1.setRemoteId( QLatin1String( "collection3_1" ) ); - collection3_1.setParentCollection( collection3 ); - job = mStore->deleteCollection( collection3_1 ); - QVERIFY( job != 0 ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - QVERIFY( fileInfo1.exists() ); - - // test fail of deleting second level collection in mbox parent with subtree - Collection collection4; - collection4.setName( QLatin1String( "collection4" ) ); - collection4.setRemoteId( QLatin1String( "collection4" ) ); - collection4.setParentCollection( mStore->topLevelCollection() ); - - Collection collection4_1; - collection4_1.setName( QLatin1String( "collection4_1" ) ); - collection4_1.setRemoteId( QLatin1String( "collection4_1" ) ); - collection4_1.setParentCollection( collection4 ); - job = mStore->deleteCollection( collection4_1 ); - QVERIFY( job != 0 ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - QVERIFY( fileInfo2.exists() ); - QVERIFY( subDirInfo2.exists() ); - - // test fail of deleting second level collection with non existant parent - Collection collection5_1; - collection5_1.setName( QLatin1String( "collection5_1" ) ); - collection5_1.setRemoteId( QLatin1String( "collection5_1" ) ); - collection5_1.setParentCollection( collection5 ); - job = mStore->deleteCollection( collection5_1 ); - QVERIFY( job != 0 ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - QCOMPARE( topLevelMd.subFolderList(), QStringList() << QLatin1String( "collection1" ) << QLatin1String( "collection2" ) ); - QVERIFY( fileInfo1.exists() ); - QCOMPARE( md1.subFolderList(), QStringList() << QLatin1String( "collection1_2" ) ); -} - -void CollectionDeleteTest::testLeaves() -{ - KPIM::Maildir topLevelMd( mDir->name(), true ); - QVERIFY( topLevelMd.isValid( false ) ); - - QDir topDir( mDir->name() ); - - KPIM::Maildir md1( topLevelMd.addSubFolder( "collection1" ), false ); - KPIM::Maildir md1_2( md1.addSubFolder( "collection1_2" ), false ); - - // simulate second level mbox in maildir parent - QFileInfo fileInfo1_1( KPIM::Maildir::subDirPathForFolderPath( md1.path() ), - QLatin1String( "collection1_1" ) ); - QFile file1_1( fileInfo1_1.absoluteFilePath() ); - file1_1.open( QIODevice::WriteOnly ); - file1_1.close(); - QVERIFY( fileInfo1_1.exists() ); - - KPIM::Maildir md2( topLevelMd.addSubFolder( "collection2" ), false ); - - // simulate first level mbox - QFileInfo fileInfo3( mDir->name(), QLatin1String( "collection3" ) ); - QFile file3( fileInfo3.absoluteFilePath() ); - file3.open( QIODevice::WriteOnly ); - file3.close(); - QVERIFY( fileInfo3.exists() ); - - // simulate first level mbox with subtree - QFileInfo fileInfo4( mDir->name(), QLatin1String( "collection4" ) ); - QFile file4( fileInfo4.absoluteFilePath() ); - file4.open( QIODevice::WriteOnly ); - file4.close(); - QVERIFY( fileInfo4.exists() ); - - QFileInfo subDirInfo4( KPIM::Maildir::subDirPathForFolderPath( fileInfo4.absoluteFilePath() ) ); - QVERIFY( topDir.mkpath( subDirInfo4.absoluteFilePath() ) ); - - KPIM::Maildir md4( subDirInfo4.absoluteFilePath(), true ); - KPIM::Maildir md4_1( md4.addSubFolder( "collection4_1" ), false ); - - // simulate second level mbox in mbox parent - QFileInfo fileInfo4_2( subDirInfo4.absoluteFilePath(), - QLatin1String( "collection4_2" ) ); - QFile file4_2( fileInfo4_2.absoluteFilePath() ); - file4_2.open( QIODevice::WriteOnly ); - file4_2.close(); - QVERIFY( fileInfo4_2.exists() ); - - mStore->setPath( mDir->name() ); - - FileStore::CollectionDeleteJob *job = 0; - - // test second level leaves in maildir parent - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - Collection collection1_1; - collection1_1.setName( QLatin1String( "collection1_1" ) ); - collection1_1.setRemoteId( QLatin1String( "collection1_1" ) ); - collection1_1.setParentCollection( collection1 ); - job = mStore->deleteCollection( collection1_1 ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - fileInfo1_1.refresh(); - QVERIFY( !fileInfo1_1.exists() ); - - Collection collection1_2; - collection1_2.setName( QLatin1String( "collection1_2" ) ); - collection1_2.setRemoteId( QLatin1String( "collection1_2" ) ); - collection1_2.setParentCollection( collection1 ); - job = mStore->deleteCollection( collection1_2 ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - QVERIFY( !md1_2.isValid( false ) ); - QCOMPARE( md1.subFolderList(), QStringList() ); - - // test second level leaves in mbox parent - Collection collection4; - collection4.setName( QLatin1String( "collection4" ) ); - collection4.setRemoteId( QLatin1String( "collection4" ) ); - collection4.setParentCollection( mStore->topLevelCollection() ); - - Collection collection4_1; - collection4_1.setName( QLatin1String( "collection4_1" ) ); - collection4_1.setRemoteId( QLatin1String( "collection4_1" ) ); - collection4_1.setParentCollection( collection4 ); - job = mStore->deleteCollection( collection4_1 ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - QVERIFY( !md4_1.isValid( false ) ); - QCOMPARE( md4.subFolderList(), QStringList() ); - - Collection collection4_2; - collection4_2.setName( QLatin1String( "collection4_2" ) ); - collection4_2.setRemoteId( QLatin1String( "collection4_2" ) ); - collection4_2.setParentCollection( collection4 ); - job = mStore->deleteCollection( collection4_2 ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - fileInfo4_2.refresh(); - QVERIFY( !fileInfo4_2.exists() ); - - // test deleting of first level leaves - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->deleteCollection( collection2 ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - QVERIFY( !md2.isValid( false ) ); - QCOMPARE( topLevelMd.subFolderList(), QStringList() << QLatin1String( "collection1" ) ); - - Collection collection3; - collection3.setName( QLatin1String( "collection3" ) ); - collection3.setRemoteId( QLatin1String( "collection3" ) ); - collection3.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->deleteCollection( collection3 ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - fileInfo3.refresh(); - QVERIFY( !fileInfo3.exists() ); - - // test deleting of first level leaves with empty subtrees - QFileInfo subDirInfo1( KPIM::Maildir::subDirPathForFolderPath( md1.path() ) ); - QVERIFY( subDirInfo1.exists() ); - - job = mStore->deleteCollection( collection1 ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - QVERIFY( !md1.isValid( false ) ); - subDirInfo1.refresh(); - QVERIFY( !subDirInfo1.exists() ); - QCOMPARE( topLevelMd.subFolderList(), QStringList() ); - - job = mStore->deleteCollection( collection4 ); - QVERIFY( job != 0 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - fileInfo4.refresh(); - QVERIFY( !fileInfo4.exists() ); - subDirInfo4.refresh(); - QVERIFY( !subDirInfo4.exists() ); -} - -void CollectionDeleteTest::testSubTrees() -{ - KPIM::Maildir topLevelMd( mDir->name(), true ); - QVERIFY( topLevelMd.isValid( false ) ); - - QDir topDir( mDir->name() ); - - KPIM::Maildir md1( topLevelMd.addSubFolder( "collection1" ), false ); - KPIM::Maildir md1_2( md1.addSubFolder( "collection1_2" ), false ); - - // simulate second level mbox in maildir parent - QFileInfo fileInfo1_1( KPIM::Maildir::subDirPathForFolderPath( md1.path() ), - QLatin1String( "collection1_1" ) ); - QFile file1_1( fileInfo1_1.absoluteFilePath() ); - file1_1.open( QIODevice::WriteOnly ); - file1_1.close(); - QVERIFY( fileInfo1_1.exists() ); - - // simulate first level mbox with subtree - QFileInfo fileInfo2( mDir->name(), QLatin1String( "collection2" ) ); - QFile file2( fileInfo2.absoluteFilePath() ); - file2.open( QIODevice::WriteOnly ); - file2.close(); - QVERIFY( fileInfo2.exists() ); - - QFileInfo subDirInfo2( KPIM::Maildir::subDirPathForFolderPath( fileInfo2.absoluteFilePath() ) ); - QVERIFY( topDir.mkpath( subDirInfo2.absoluteFilePath() ) ); - - KPIM::Maildir md2( subDirInfo2.absoluteFilePath(), true ); - KPIM::Maildir md2_1( md2.addSubFolder( "collection2_1" ), false ); - - // simulate second level mbox in mbox parent - QFileInfo fileInfo2_2( subDirInfo2.absoluteFilePath(), - QLatin1String( "collection2_2" ) ); - QFile file2_2( fileInfo2_2.absoluteFilePath() ); - file2_2.open( QIODevice::WriteOnly ); - file2_2.close(); - QVERIFY( fileInfo2_2.exists() ); - - mStore->setPath( mDir->name() ); - - FileStore::CollectionDeleteJob *job = 0; - - // test deleting maildir subtree - QFileInfo subDirInfo1( KPIM::Maildir::subDirPathForFolderPath( md1.path() ) ); - QVERIFY( subDirInfo1.exists() ); - - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->deleteCollection( collection1 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - QVERIFY( !md1.isValid( false ) ); - QVERIFY( !md1_2.isValid( false ) ); - fileInfo1_1.refresh(); - QVERIFY( !fileInfo1_1.exists() ); - - // test deleting mbox subtree - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->deleteCollection( collection2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - fileInfo2.refresh(); - QVERIFY( !fileInfo2.exists() ); - QVERIFY( !md2_1.isValid( false ) ); - fileInfo2_2.refresh(); - QVERIFY( !fileInfo2_2.exists() ); - QVERIFY( !subDirInfo2.exists() ); -} - -QTEST_KDEMAIN( CollectionDeleteTest, NoGUI ) - -#include "collectiondeletetest.moc" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/collectionfetchtest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/tests/collectionfetchtest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/collectionfetchtest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/collectionfetchtest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,471 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" - -#include "filestore/collectionfetchjob.h" - -#include "libmaildir/maildir.h" - -#include - -#include - -#include - -#include - -using namespace Akonadi; - -static Collection::List collectionsFromSpy( QSignalSpy *spy ) { - Collection::List collections; - - QListIterator > it( *spy ); - while( it.hasNext() ) { - const QList invocation = it.next(); - Q_ASSERT( invocation.count() == 1 ); - - collections << invocation.first().value(); - } - - return collections; -} - -class CollectionFetchTest : public QObject -{ - Q_OBJECT - - public: - CollectionFetchTest() : QObject(), mStore( 0 ), mDir( 0 ) { - // for monitoring signals - qRegisterMetaType(); - } - - ~CollectionFetchTest() { - delete mStore; - delete mDir; - } - - private: - MixedMaildirStore *mStore; - KTempDir *mDir; - - private Q_SLOTS: - void init(); - void cleanup(); - void testEmptyDir(); - void testMixedTree(); -}; - -void CollectionFetchTest::init() -{ - mStore = new MixedMaildirStore; - - mDir = new KTempDir; - QVERIFY( mDir->exists() ); -} - -void CollectionFetchTest::cleanup() -{ - delete mStore; - mStore = 0; - delete mDir; - mDir = 0; -} - -void CollectionFetchTest::testEmptyDir() -{ - mStore->setPath( mDir->name() ); - - FileStore::CollectionFetchJob *job = 0; - QSignalSpy *spy = 0; - Collection::List collections; - - // test base fetch of top level collection - job = mStore->fetchCollections( mStore->topLevelCollection(), FileStore::CollectionFetchJob::Base ); - - spy = new QSignalSpy( job, SIGNAL(collectionsReceived(Akonadi::Collection::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - QCOMPARE( spy->count(), 1 ); - - collections = collectionsFromSpy( spy ); - QCOMPARE( collections.count(), 1 ); - QCOMPARE( collections.first(), mStore->topLevelCollection() ); - QCOMPARE( job->collections(), collections ); - - // test first level fetch of top level collection - job = mStore->fetchCollections( mStore->topLevelCollection(), FileStore::CollectionFetchJob::FirstLevel ); - - spy = new QSignalSpy( job, SIGNAL(collectionsReceived(Akonadi::Collection::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - QCOMPARE( spy->count(), 0 ); - - collections = collectionsFromSpy( spy ); - QCOMPARE( collections.count(), 0 ); - QCOMPARE( job->collections(), collections ); - - // test recursive fetch of top level collection - job = mStore->fetchCollections( mStore->topLevelCollection(), FileStore::CollectionFetchJob::Recursive ); - - spy = new QSignalSpy( job, SIGNAL(collectionsReceived(Akonadi::Collection::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - QCOMPARE( spy->count(), 0 ); - - collections = collectionsFromSpy( spy ); - QCOMPARE( collections.count(), 0 ); - QCOMPARE( job->collections(), collections ); - - // test fail of base fetching non existant collection - Collection collection; - collection.setName( QLatin1String( "collection" ) ); - collection.setRemoteId( QLatin1String( "collection" ) ); - collection.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->fetchCollections( collection, FileStore::CollectionFetchJob::Base ); - - spy = new QSignalSpy( job, SIGNAL(collectionsReceived(Akonadi::Collection::List)) ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - QCOMPARE( spy->count(), 0 ); - - collections = collectionsFromSpy( spy ); - QCOMPARE( collections.count(), 0 ); - QCOMPARE( job->collections(), collections ); - - // test fail of first level fetching non existant collection - job = mStore->fetchCollections( collection, FileStore::CollectionFetchJob::FirstLevel ); - - spy = new QSignalSpy( job, SIGNAL(collectionsReceived(Akonadi::Collection::List)) ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - QCOMPARE( spy->count(), 0 ); - - collections = collectionsFromSpy( spy ); - QCOMPARE( collections.count(), 0 ); - QCOMPARE( job->collections(), collections ); - - // test fail of recursive fetching non existant collection - job = mStore->fetchCollections( collection, FileStore::CollectionFetchJob::FirstLevel ); - - spy = new QSignalSpy( job, SIGNAL(collectionsReceived(Akonadi::Collection::List)) ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - QCOMPARE( spy->count(), 0 ); - - collections = collectionsFromSpy( spy ); - QCOMPARE( collections.count(), 0 ); - QCOMPARE( job->collections(), collections ); -} - -void CollectionFetchTest::testMixedTree() -{ - QDir topDir( mDir->name() ); - - KPIM::Maildir topLevelMd( mDir->name(), true ); - QVERIFY( topLevelMd.isValid() ); - - KPIM::Maildir md1( topLevelMd.addSubFolder( "collection1" ), false ); - KPIM::Maildir md1_2( md1.addSubFolder( "collection1_2" ), false ); - KPIM::Maildir md1_2_1( md1_2.addSubFolder( "collection1_2_1" ), false ); - - // simulate second level mbox in maildir parent - QFileInfo fileInfo1_1( KPIM::Maildir::subDirPathForFolderPath( md1.path() ), - QLatin1String( "collection1_1" ) ); - QFile file1_1( fileInfo1_1.absoluteFilePath() ); - file1_1.open( QIODevice::WriteOnly ); - file1_1.close(); - QVERIFY( fileInfo1_1.exists() ); - - QFileInfo subDirInfo1_1( KPIM::Maildir::subDirPathForFolderPath( fileInfo1_1.absoluteFilePath() ) ); - QVERIFY( topDir.mkpath( subDirInfo1_1.absoluteFilePath() ) ); - KPIM::Maildir md1_1( subDirInfo1_1.absoluteFilePath(), true ); - KPIM::Maildir md1_1_1( md1_1.addSubFolder( "collection1_1_1" ), false ); - - // simulate third level mbox in mbox parent - QFileInfo fileInfo1_1_2( md1_1.path(), QLatin1String( "collection1_1_2" ) ); - QFile file1_1_2( fileInfo1_1_2.absoluteFilePath() ); - file1_1_2.open( QIODevice::WriteOnly ); - file1_1_2.close(); - QVERIFY( fileInfo1_1_2.exists() ); - - KPIM::Maildir md2( topLevelMd.addSubFolder( "collection2" ), false ); - - // simulate first level mbox - QFileInfo fileInfo3( mDir->name(), QLatin1String( "collection3" ) ); - QFile file3( fileInfo3.absoluteFilePath() ); - file3.open( QIODevice::WriteOnly ); - file3.close(); - QVERIFY( fileInfo3.exists() ); - - // simulate first level mbox with subtree - QFileInfo fileInfo4( mDir->name(), QLatin1String( "collection4" ) ); - QFile file4( fileInfo4.absoluteFilePath() ); - file4.open( QIODevice::WriteOnly ); - file4.close(); - QVERIFY( fileInfo4.exists() ); - - QFileInfo subDirInfo4( KPIM::Maildir::subDirPathForFolderPath( fileInfo4.absoluteFilePath() ) ); - QVERIFY( topDir.mkpath( subDirInfo4.absoluteFilePath() ) ); - - KPIM::Maildir md4( subDirInfo4.absoluteFilePath(), true ); - KPIM::Maildir md4_1( md4.addSubFolder( "collection4_1" ), false ); - - // simulate second level mbox in mbox parent - QFileInfo fileInfo4_2( subDirInfo4.absoluteFilePath(), - QLatin1String( "collection4_2" ) ); - QFile file4_2( fileInfo4_2.absoluteFilePath() ); - file4_2.open( QIODevice::WriteOnly ); - file4_2.close(); - QVERIFY( fileInfo4_2.exists() ); - - QSet firstLevelNames; - firstLevelNames << md1.name() << md2.name() << fileInfo3.fileName() << fileInfo4.fileName(); - - QSet secondLevelNames; - secondLevelNames << md1_2.name() << md4_1.name() - << fileInfo1_1.fileName() << fileInfo4_2.fileName(); - - QSet thirdLevelNames; - thirdLevelNames << md1_1_1.name() << fileInfo1_1_2.fileName() << md1_2_1.name(); - - mStore->setPath( mDir->name() ); - //mDir = 0; - - FileStore::CollectionFetchJob *job = 0; - QSignalSpy *spy = 0; - Collection::List collections; - - // test base fetch of top level collection - job = mStore->fetchCollections( mStore->topLevelCollection(), FileStore::CollectionFetchJob::Base ); - - spy = new QSignalSpy( job, SIGNAL(collectionsReceived(Akonadi::Collection::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - QCOMPARE( spy->count(), 1 ); - - collections = collectionsFromSpy( spy ); - QCOMPARE( collections.count(), 1 ); - QCOMPARE( collections.first(), mStore->topLevelCollection() ); - QCOMPARE( job->collections(), collections ); - - // test first level fetch of top level collection - job = mStore->fetchCollections( mStore->topLevelCollection(), FileStore::CollectionFetchJob::FirstLevel ); - - spy = new QSignalSpy( job, SIGNAL(collectionsReceived(Akonadi::Collection::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - QVERIFY( spy->count() > 0 ); - - collections = collectionsFromSpy( spy ); - QCOMPARE( collections.count(), firstLevelNames.count() ); - QCOMPARE( job->collections(), collections ); - - Q_FOREACH( const Collection &collection, collections ) { - QVERIFY( !collection.remoteId().isEmpty() ); - QCOMPARE( collection.remoteId(), collection.name() ); - QCOMPARE( collection.contentMimeTypes(), QStringList() << Collection::mimeType() << KMime::Message::mimeType() ); - - QCOMPARE( collection.rights(), Collection::CanCreateItem | - Collection::CanChangeItem | - Collection::CanDeleteItem | - Collection::CanCreateCollection | - Collection::CanChangeCollection | - Collection::CanDeleteCollection ); - - QCOMPARE( collection.parentCollection(), mStore->topLevelCollection() ); - QVERIFY( firstLevelNames.contains( collection.name() ) ); - } - - // test recursive fetch of top level collection - job = mStore->fetchCollections( mStore->topLevelCollection(), FileStore::CollectionFetchJob::Recursive ); - - spy = new QSignalSpy( job, SIGNAL(collectionsReceived(Akonadi::Collection::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - QVERIFY( spy->count() > 0 ); - - collections = collectionsFromSpy( spy ); - QCOMPARE( collections.count(), - firstLevelNames.count() + secondLevelNames.count() + thirdLevelNames.count() ); - QCOMPARE( job->collections(), collections ); - - Q_FOREACH( const Collection &collection, collections ) { - QVERIFY( !collection.remoteId().isEmpty() ); - QCOMPARE( collection.remoteId(), collection.name() ); - QCOMPARE( collection.contentMimeTypes(), QStringList() << Collection::mimeType() << KMime::Message::mimeType() ); - - QCOMPARE( collection.rights(), Collection::CanCreateItem | - Collection::CanChangeItem | - Collection::CanDeleteItem | - Collection::CanCreateCollection | - Collection::CanChangeCollection | - Collection::CanDeleteCollection ); - - if ( firstLevelNames.contains( collection.name() ) ) { - QCOMPARE( collection.parentCollection(), mStore->topLevelCollection() ); - } else if ( secondLevelNames.contains( collection.name() ) ) { - QVERIFY( firstLevelNames.contains( collection.parentCollection().name() ) ); - QCOMPARE( collection.parentCollection().parentCollection(), mStore->topLevelCollection() ); - } else if ( thirdLevelNames.contains( collection.name() ) ) { - QVERIFY( secondLevelNames.contains( collection.parentCollection().name() ) ); - QCOMPARE( collection.parentCollection().parentCollection().parentCollection(), - mStore->topLevelCollection() ); - } - } - - // test base fetching all collections - Q_FOREACH( const Collection &collection, collections ) { - job = mStore->fetchCollections( collection, FileStore::CollectionFetchJob::Base ); - - spy = new QSignalSpy( job, SIGNAL(collectionsReceived(Akonadi::Collection::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - QCOMPARE( spy->count(), 1 ); - - const Collection::List list = collectionsFromSpy( spy ); - QCOMPARE( list.count(), 1 ); - QCOMPARE( list.first(), collection ); - QCOMPARE( job->collections(), list ); - - const Collection col = list.first(); - QVERIFY( !col.remoteId().isEmpty() ); - QCOMPARE( col.remoteId(), col.name() ); - QCOMPARE( col.contentMimeTypes(), QStringList() << Collection::mimeType() << KMime::Message::mimeType() ); - - QCOMPARE( col.rights(), Collection::CanCreateItem | - Collection::CanChangeItem | - Collection::CanDeleteItem | - Collection::CanCreateCollection | - Collection::CanChangeCollection | - Collection::CanDeleteCollection ); - } - - // test first level fetching all collections - Q_FOREACH( const Collection &collection, collections ) { - job = mStore->fetchCollections( collection, FileStore::CollectionFetchJob::FirstLevel ); - - spy = new QSignalSpy( job, SIGNAL(collectionsReceived(Akonadi::Collection::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - const Collection::List list = collectionsFromSpy( spy ); - QCOMPARE( job->collections(), list ); - - Q_FOREACH( const Collection &childCollection, list ) { - QCOMPARE( childCollection.parentCollection(), collection ); - - QVERIFY( !childCollection.remoteId().isEmpty() ); - QCOMPARE( childCollection.remoteId(), childCollection.name() ); - QCOMPARE( childCollection.contentMimeTypes(), QStringList() << Collection::mimeType() << KMime::Message::mimeType() ); - - QCOMPARE( childCollection.rights(), Collection::CanCreateItem | - Collection::CanChangeItem | - Collection::CanDeleteItem | - Collection::CanCreateCollection | - Collection::CanChangeCollection | - Collection::CanDeleteCollection ); - } - - if ( firstLevelNames.contains( collection.name() ) ) { - Q_FOREACH( const Collection &childCollection, list ) { - QVERIFY( secondLevelNames.contains( childCollection.name() ) ); - } - } else if ( secondLevelNames.contains( collection.name() ) ) { - Q_FOREACH( const Collection &childCollection, list ) { - QVERIFY( thirdLevelNames.contains( childCollection.name() ) ); - } - if ( collection.name() == md1_2.name() ) { - QCOMPARE( list.count(), 1 ); - QCOMPARE( list.first().name(), md1_2_1.name() ); - } else if ( collection.name() == fileInfo1_1.fileName() ) { - QCOMPARE( list.count(), 2 ); - } - } else { - QCOMPARE( list.count(), 0 ); - } - } - - // test recursive fetching all collections - Q_FOREACH( const Collection &collection, collections ) { - job = mStore->fetchCollections( collection, FileStore::CollectionFetchJob::Recursive ); - - spy = new QSignalSpy( job, SIGNAL(collectionsReceived(Akonadi::Collection::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - const Collection::List list = collectionsFromSpy( spy ); - QCOMPARE( job->collections(), list ); - - Q_FOREACH( const Collection &childCollection, list ) { - QVERIFY( childCollection.parentCollection() == collection || - childCollection.parentCollection().parentCollection() == collection ); - QVERIFY( !childCollection.remoteId().isEmpty() ); - QCOMPARE( childCollection.remoteId(), childCollection.name() ); - QCOMPARE( childCollection.contentMimeTypes(), QStringList() << Collection::mimeType() << KMime::Message::mimeType() ); - - QCOMPARE( childCollection.rights(), Collection::CanCreateItem | - Collection::CanChangeItem | - Collection::CanDeleteItem | - Collection::CanCreateCollection | - Collection::CanChangeCollection | - Collection::CanDeleteCollection ); - } - - if ( firstLevelNames.contains( collection.name() ) ) { - Q_FOREACH( const Collection &childCollection, list ) { - QVERIFY( secondLevelNames.contains( childCollection.name() ) || - thirdLevelNames.contains( childCollection.name() ) ); - } - } else if ( secondLevelNames.contains( collection.name() ) ) { - Q_FOREACH( const Collection &childCollection, list ) { - QVERIFY( thirdLevelNames.contains( childCollection.name() ) ); - } - if ( collection.name() == md1_2.name() ) { - QCOMPARE( list.count(), 1 ); - QCOMPARE( list.first().name(), md1_2_1.name() ); - } else if ( collection.name() == fileInfo1_1.fileName() ) { - QCOMPARE( list.count(), 2 ); - } - } else { - QCOMPARE( list.count(), 0 ); - } - } -} - -QTEST_KDEMAIN( CollectionFetchTest, NoGUI ) - -#include "collectionfetchtest.moc" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/collectionmodifytest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/tests/collectionmodifytest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/collectionmodifytest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/collectionmodifytest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,628 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" - -#include "testdatautil.h" - -#include "filestore/collectionmodifyjob.h" -#include "filestore/itemfetchjob.h" - -#include "libmaildir/maildir.h" - -#include - -#include - -using namespace Akonadi; - -class CollectionModifyTest : public QObject -{ - Q_OBJECT - - public: - CollectionModifyTest() : QObject(), mStore( 0 ), mDir( 0 ) {} - - ~CollectionModifyTest() { - delete mStore; - delete mDir; - } - - private: - MixedMaildirStore *mStore; - KTempDir *mDir; - - private Q_SLOTS: - void init(); - void cleanup(); - void testRename(); - void testIndexPreservation(); - void testIndexCacheUpdate(); -}; - -void CollectionModifyTest::init() -{ - mStore = new MixedMaildirStore; - - mDir = new KTempDir; - QVERIFY( mDir->exists() ); -} - -void CollectionModifyTest::cleanup() -{ - delete mStore; - mStore = 0; - delete mDir; - mDir = 0; -} - -void CollectionModifyTest::testRename() -{ - QDir topDir( mDir->name() ); - QVERIFY( topDir.mkdir( QLatin1String( "topLevel" ) ) ); - QVERIFY( topDir.cd( QLatin1String( "topLevel" ) ) ); - - KPIM::Maildir topLevelMd( topDir.path(), true ); - QVERIFY( topLevelMd.isValid( false ) ); - - KPIM::Maildir md1( topLevelMd.addSubFolder( "collection1" ), false ); - KPIM::Maildir md1_2( md1.addSubFolder( "collection1_2" ), false ); - - // simulate second level mbox in maildir parent - QFileInfo fileInfo1_1( KPIM::Maildir::subDirPathForFolderPath( md1.path() ), - QLatin1String( "collection1_1" ) ); - QFile file1_1( fileInfo1_1.absoluteFilePath() ); - file1_1.open( QIODevice::WriteOnly ); - file1_1.close(); - QVERIFY( fileInfo1_1.exists() ); - - KPIM::Maildir md2( topLevelMd.addSubFolder( "collection2" ), false ); - - // simulate first level mbox - QFileInfo fileInfo3( topDir.path(), QLatin1String( "collection3" ) ); - QFile file3( fileInfo3.absoluteFilePath() ); - file3.open( QIODevice::WriteOnly ); - file3.close(); - QVERIFY( fileInfo3.exists() ); - - // simulate first level mbox with subtree - QFileInfo fileInfo4( topDir.path(), QLatin1String( "collection4" ) ); - QFile file4( fileInfo4.absoluteFilePath() ); - file4.open( QIODevice::WriteOnly ); - file4.close(); - QVERIFY( fileInfo4.exists() ); - - QFileInfo subDirInfo4( KPIM::Maildir::subDirPathForFolderPath( fileInfo4.absoluteFilePath() ) ); - QVERIFY( topDir.mkpath( subDirInfo4.absoluteFilePath() ) ); - - KPIM::Maildir md4( subDirInfo4.absoluteFilePath(), true ); - KPIM::Maildir md4_1( md4.addSubFolder( "collection4_1" ), false ); - - // simulate second level mbox in mbox parent - QFileInfo fileInfo4_2( subDirInfo4.absoluteFilePath(), - QLatin1String( "collection4_2" ) ); - QFile file4_2( fileInfo4_2.absoluteFilePath() ); - file4_2.open( QIODevice::WriteOnly ); - file4_2.close(); - QVERIFY( fileInfo4_2.exists() ); - - mStore->setPath( topDir.path() ); - - FileStore::CollectionModifyJob *job = 0; - Collection collection; - - // test renaming top level collection - topDir.cdUp(); - QVERIFY( !topDir.exists( QLatin1String( "newTopLevel" ) ) ); - - Collection topLevelCollection = mStore->topLevelCollection(); - topLevelCollection.setName( QLatin1String( "newTopLevel" ) ); - job = mStore->modifyCollection( topLevelCollection ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - QVERIFY( topDir.exists( QLatin1String( "newTopLevel" ) ) ); - QVERIFY( !topDir.exists( QLatin1String( "topLevel" ) ) ); - QVERIFY( topDir.cd( QLatin1String( "newTopLevel" ) ) ); - QCOMPARE( mStore->path(), topDir.path() ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), mStore->path() ); - QCOMPARE( collection, mStore->topLevelCollection() ); - - // test failure of renaming again - job = mStore->modifyCollection( topLevelCollection ); - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int) FileStore::Job::InvalidJobContext ); - QCOMPARE( collection.remoteId(), mStore->path() ); - QCOMPARE( collection, mStore->topLevelCollection() ); - - // adjust local handles - topLevelMd = KPIM::Maildir( topDir.path(), true ); - QVERIFY( topLevelMd.isValid( false ) ); - - md1 = topLevelMd.subFolder( "collection1" ); - QVERIFY( md1.isValid( false ) ); - md1_2 = md1.subFolder( "collection1_2" ); - - fileInfo1_1 = QFileInfo( KPIM::Maildir::subDirPathForFolderPath( md1.path() ), - QLatin1String( "collection1_1" ) ); - QVERIFY( fileInfo1_1.exists() ); - - md2 = topLevelMd.subFolder( "collection2" ); - - fileInfo3 = QFileInfo( topDir.path(), QLatin1String( "collection3" ) ); - QVERIFY( fileInfo3.exists() ); - - fileInfo4 = QFileInfo( topDir.path(), QLatin1String( "collection4" ) ); - QVERIFY( fileInfo4.exists() ); - - subDirInfo4 = QFileInfo( KPIM::Maildir::subDirPathForFolderPath( fileInfo4.absoluteFilePath() ) ); - QVERIFY( subDirInfo4.exists() ); - - md4 = KPIM::Maildir( subDirInfo4.absoluteFilePath(), true ); - QVERIFY( md4.isValid( false ) ); - md4_1 = md4.subFolder( "collection4_1" ); - - fileInfo4_2 = QFileInfo( subDirInfo4.absoluteFilePath(), - QLatin1String( "collection4_2" ) ); - QVERIFY( fileInfo4_2.exists() ); - - QCOMPARE( topLevelMd.subFolderList(), QStringList() << QLatin1String( "collection1" ) << QLatin1String( "collection2" ) ); - - // test rename first level maildir leaf - Collection collection2; - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - collection2.setName( QLatin1String( "collection2_renamed" ) ); - - job = mStore->modifyCollection( collection2 ); - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection.name() ); - QCOMPARE( collection, collection2 ); - QCOMPARE( topLevelMd.subFolderList(), QStringList() << QLatin1String( "collection1" ) << QLatin1String( "collection2_renamed" ) ); - QVERIFY( !md2.isValid( false ) ); - md2 = topLevelMd.subFolder( collection.remoteId() ); - QVERIFY( md2.isValid( false ) ); - - // test failure of renaming again - job = mStore->modifyCollection( collection2 ); - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int) FileStore::Job::InvalidJobContext ); - QCOMPARE( topLevelMd.subFolderList(), QStringList() << QLatin1String( "collection1" ) << QLatin1String( "collection2_renamed" ) ); - QVERIFY( md2.isValid( false ) ); - - // test renaming of first level mbox leaf - Collection collection3; - collection3.setRemoteId( QLatin1String( "collection3" ) ); - collection3.setParentCollection( mStore->topLevelCollection() ); - collection3.setName( QLatin1String( "collection3_renamed" ) ); - - job = mStore->modifyCollection( collection3 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection.name() ); - QCOMPARE( collection, collection3 ); - fileInfo3.refresh(); - QVERIFY( !fileInfo3.exists() ); - fileInfo3 = QFileInfo( topDir.path(), collection.remoteId() ); - QVERIFY( fileInfo3.exists() ); - - // test failure of renaming again - job = mStore->modifyCollection( collection3 ); - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int) FileStore::Job::InvalidJobContext ); - fileInfo3.refresh(); - QVERIFY( fileInfo3.exists() ); - - // test renaming second level maildir in mbox parent - Collection collection4; - collection4.setRemoteId( QLatin1String( "collection4" ) ); - collection4.setParentCollection( mStore->topLevelCollection() ); - collection4.setName( QLatin1String( "collection4" ) ); - - Collection collection4_1; - collection4_1.setRemoteId( QLatin1String( "collection4_1" ) ); - collection4_1.setParentCollection( collection4 ); - collection4_1.setName( QLatin1String( "collection4_1_renamed" ) ); - - job = mStore->modifyCollection( collection4_1 ); - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection.name() ); - QCOMPARE( collection, collection4_1 ); - QCOMPARE( md4.subFolderList(), QStringList() << QLatin1String( "collection4_1_renamed" ) ); - QVERIFY( !md4_1.isValid( false ) ); - md4_1 = md4.subFolder( collection.remoteId() ); - QVERIFY( md4_1.isValid( false ) ); - - // test failure of renaming again - job = mStore->modifyCollection( collection4_1 ); - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int) FileStore::Job::InvalidJobContext ); - QCOMPARE( md4.subFolderList(), QStringList() << QLatin1String( "collection4_1_renamed" ) ); - QVERIFY( md4_1.isValid( false ) ); - - // test renaming of second level mbox in mbox parent - Collection collection4_2; - collection4_2.setRemoteId( QLatin1String( "collection4_2" ) ); - collection4_2.setParentCollection( collection4 ); - collection4_2.setName( QLatin1String( "collection4_2_renamed" ) ); - - job = mStore->modifyCollection( collection4_2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection.name() ); - QCOMPARE( collection, collection4_2 ); - fileInfo4_2.refresh(); - QVERIFY( !fileInfo4_2.exists() ); - fileInfo4_2 = QFileInfo( md4.path(), collection.remoteId() ); - QVERIFY( fileInfo4_2.exists() ); - - // test failure of renaming again - job = mStore->modifyCollection( collection4_2 ); - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int) FileStore::Job::InvalidJobContext ); - fileInfo4_2.refresh(); - QVERIFY( fileInfo4_2.exists() ); - - // test renaming of maildir with subtree - Collection collection1; - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - collection1.setName( QLatin1String( "collection1_renamed" ) ); - - job = mStore->modifyCollection( collection1 ); - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection.name() ); - QCOMPARE( collection, collection1 ); - QCOMPARE( topLevelMd.subFolderList(), QStringList() << QLatin1String( "collection1_renamed" ) << QLatin1String( "collection2_renamed" ) ); - QVERIFY( !md1.isValid( false ) ); - md1 = topLevelMd.subFolder( collection.remoteId() ); - QVERIFY( md1.isValid( false ) ); - fileInfo1_1.refresh(); - QVERIFY( !fileInfo1_1.exists() ); - QVERIFY( !md1_2.isValid( false ) ); - fileInfo1_1 = QFileInfo( KPIM::Maildir::subDirPathForFolderPath( md1.path() ), - QLatin1String( "collection1_1" ) ); - QVERIFY( fileInfo1_1.exists() ); - md1_2 = md1.subFolder( QLatin1String( "collection1_2" ) ); - QVERIFY( md1_2.isValid( false ) ); - - // test failure of renaming again - job = mStore->modifyCollection( collection1 ); - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int) FileStore::Job::InvalidJobContext ); - QCOMPARE( topLevelMd.subFolderList(), QStringList() << QLatin1String( "collection1_renamed" ) << QLatin1String( "collection2_renamed" ) ); - QVERIFY( md2.isValid( false ) ); - QVERIFY( fileInfo1_1.exists() ); - QVERIFY( md1_2.isValid( false ) ); - - // test renaming of mbox with subtree - collection4.setName( QLatin1String( "collection4_renamed" ) ); - job = mStore->modifyCollection( collection4 ); - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection.name() ); - QCOMPARE( collection, collection4 ); - fileInfo4.refresh(); - QVERIFY( !fileInfo4.exists() ); - fileInfo4 = QFileInfo( topDir.path(), collection.remoteId() ); - QVERIFY( fileInfo4.exists() ); - md4 = KPIM::Maildir( KPIM::Maildir::subDirPathForFolderPath( fileInfo4.absoluteFilePath() ), true ); - QVERIFY( md4.isValid( false ) ); - - QVERIFY( !md4_1.isValid( false ) ); - fileInfo4_2.refresh(); - QVERIFY( !fileInfo4_2.exists() ); - md4_1 = md4.subFolder( QLatin1String( "collection4_1_renamed" ) ); - QVERIFY( md4_1.isValid( false ) ); - fileInfo4_2 = QFileInfo( md4.path(), QLatin1String( "collection4_2_renamed" ) ); - QVERIFY( fileInfo4_2.exists() ); - - // test failure of renaming again - job = mStore->modifyCollection( collection4 ); - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int) FileStore::Job::InvalidJobContext ); - fileInfo4.refresh(); - QVERIFY( fileInfo4.exists() ); -} - -void CollectionModifyTest::testIndexPreservation() -{ - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), mDir->name(), QLatin1String( "collection1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), mDir->name(), QLatin1String( "collection2" ) ) ); - - mStore->setPath( mDir->name() ); - - const QVariant colListVar = QVariant::fromValue( Collection::List() ); - FileStore::CollectionModifyJob *job = 0; - FileStore::ItemFetchJob *itemFetch = 0; - QVariant var; - Collection::List collections; - Item::List items; - - QMap flagCounts; - - // test renaming mbox - Collection collection1; - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - collection1.setName( QLatin1String( "collection1_renamed" ) ); - - job = mStore->modifyCollection( collection1 ); - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection1 ); - - const QFileInfo indexFileInfo1( mDir->name(), QLatin1String( ".collection1_renamed.index" ) ); - QVERIFY( !indexFileInfo1.exists() ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collections.first() ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - - // test renaming maildir - Collection collection2; - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - collection2.setName( QLatin1String( "collection2_renamed" ) ); - - job = mStore->modifyCollection( collection2 ); - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection2 ); - - const QFileInfo indexFileInfo2( mDir->name(), QLatin1String( ".collection2_renamed.index" ) ); - QVERIFY( !indexFileInfo2.exists() ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collections.first() ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - - flagCounts.clear(); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); -} - -void CollectionModifyTest::testIndexCacheUpdate() -{ - KPIM::Maildir topLevelMd( mDir->name(), true ); - QVERIFY( topLevelMd.isValid( false ) ); - - KPIM::Maildir md1( topLevelMd.addSubFolder( "collection1" ), false ); - - // simulate first level mbox - QFileInfo fileInfo2( mDir->name(), QLatin1String( "collection2" ) ); - QFile file2( fileInfo2.absoluteFilePath() ); - file2.open( QIODevice::WriteOnly ); - file2.close(); - QVERIFY( fileInfo2.exists() ); - - const QString colSubDir1 = KPIM::Maildir::subDirPathForFolderPath( md1.path() ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), colSubDir1, QLatin1String( "collection1_1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), colSubDir1, QLatin1String( "collection1_2" ) ) ); - - const QString colSubDir2 = KPIM::Maildir::subDirPathForFolderPath( fileInfo2.absoluteFilePath() ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), colSubDir2, QLatin1String( "collection2_1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), colSubDir2, QLatin1String( "collection2_2" ) ) ); - - mStore->setPath( mDir->name() ); - - FileStore::CollectionModifyJob *job = 0; - FileStore::ItemFetchJob *itemFetch = 0; - Collection collection; - Item::List items; - QMap flagCounts; - - // preparation: load all second level items to make sure respective index data is cached - Collection collection1; - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - collection1.setName( QLatin1String( "collection1" ) ); - - Collection collection1_1; - collection1_1.setRemoteId( QLatin1String( "collection1_1" ) ); - collection1_1.setParentCollection( collection1 ); - collection1_1.setName( QLatin1String( "collection1_1" ) ); - - itemFetch = mStore->fetchItems( collection1_1 ); - QVERIFY( itemFetch->exec() ); - - Collection collection1_2; - collection1_2.setRemoteId( QLatin1String( "collection1_2" ) ); - collection1_2.setParentCollection( collection1 ); - collection1_2.setName( QLatin1String( "collection1_2" ) ); - - itemFetch = mStore->fetchItems( collection1_2 ); - QVERIFY( itemFetch->exec() ); - Collection collection2; - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - collection2.setName( QLatin1String( "collection2" ) ); - - Collection collection2_1; - collection2_1.setRemoteId( QLatin1String( "collection2_1" ) ); - collection2_1.setParentCollection( collection2 ); - collection2_1.setName( QLatin1String( "collection2_1" ) ); - - itemFetch = mStore->fetchItems( collection2_1 ); - QVERIFY( itemFetch->exec() ); - Collection collection2_2; - collection2_2.setRemoteId( QLatin1String( "collection2_2" ) ); - collection2_2.setParentCollection( collection2 ); - collection2_2.setName( QLatin1String( "collection2_2" ) ); - - itemFetch = mStore->fetchItems( collection2_2 ); - QVERIFY( itemFetch->exec() ); - - // test renaming the maildir parent - collection1.setName( QLatin1String( "collection1_renamed" ) ); - - job = mStore->modifyCollection( collection1 ); - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - - // get the items of the children and check the flags (see data/README) - collection1_1.setParentCollection( collection ); - itemFetch = mStore->fetchItems( collection1_1 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - collection1_2.setParentCollection( collection ); - itemFetch = mStore->fetchItems( collection1_2 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // test renaming the mbox parent - collection2.setName( QLatin1String( "collection2_renamed" ) ); - - job = mStore->modifyCollection( collection2 ); - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - - // get the items of the children and check the flags (see data/README) - collection2_1.setParentCollection( collection ); - itemFetch = mStore->fetchItems( collection2_1 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - collection2_2.setParentCollection( collection ); - itemFetch = mStore->fetchItems( collection2_2 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); -} - -QTEST_KDEMAIN( CollectionModifyTest, NoGUI ) - -#include "collectionmodifytest.moc" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/collectionmovetest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/tests/collectionmovetest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/collectionmovetest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/collectionmovetest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1999 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" - -#include "testdatautil.h" - -#include "filestore/collectionmovejob.h" -#include "filestore/itemfetchjob.h" - -#include "libmaildir/maildir.h" - -#include - -#include - -using namespace Akonadi; - -class CollectionMoveTest : public QObject -{ - Q_OBJECT - - public: - CollectionMoveTest() : QObject(), mStore( 0 ), mDir( 0 ) {} - - ~CollectionMoveTest() { - delete mStore; - delete mDir; - } - - private: - MixedMaildirStore *mStore; - KTempDir *mDir; - - private Q_SLOTS: - void init(); - void cleanup(); - void testMoveToTopLevel(); - void testMoveToMaildir(); - void testMoveToMBox(); -}; - -void CollectionMoveTest::init() -{ - mStore = new MixedMaildirStore; - - mDir = new KTempDir; - QVERIFY( mDir->exists() ); -} - -void CollectionMoveTest::cleanup() -{ - delete mStore; - mStore = 0; - delete mDir; - mDir = 0; -} - -void CollectionMoveTest::testMoveToTopLevel() -{ - QDir topDir( mDir->name() ); - - // top level dir - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QFileInfo fileInfo1( topDir, QLatin1String( "collection1" ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection2" ) ) ); - QFileInfo fileInfo2( topDir, QLatin1String( "collection2" ) ); - - // first level maildir parent - QDir subDir1 = topDir; - QVERIFY( subDir1.mkdir( QLatin1String( ".collection1.directory" ) ) ); - QVERIFY( subDir1.cd( QLatin1String( ".collection1.directory" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), subDir1.path(), QLatin1String( "collection1_1" ) ) ); - QFileInfo fileInfo1_1( subDir1.path(), QLatin1String( "collection1_1" ) ); - QVERIFY( fileInfo1_1.exists() ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), subDir1.path(), QLatin1String( "collection1_2" ) ) ); - QFileInfo fileInfo1_2( subDir1.path(), QLatin1String( "collection1_2" ) ); - QVERIFY( fileInfo1_2.exists() ); - - // first level mbox parent - QDir subDir2 = topDir; - QVERIFY( subDir2.mkdir( QLatin1String( ".collection2.directory" ) ) ); - QVERIFY( subDir2.cd( QLatin1String( ".collection2.directory" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), subDir2.path(), QLatin1String( "collection2_1" ) ) ); - QFileInfo fileInfo2_1( subDir2.path(), QLatin1String( "collection2_1" ) ); - QVERIFY( fileInfo2_1.exists() ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), subDir2.path(), QLatin1String( "collection2_2" ) ) ); - QFileInfo fileInfo2_2( subDir2.path(), QLatin1String( "collection2_2" ) ); - QVERIFY( fileInfo2_2.exists() ); - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::CollectionMoveJob *job = 0; - FileStore::ItemFetchJob *itemFetch = 0; - Collection collection; - const QVariant colListVar = QVariant::fromValue( Collection::List() ); - QVariant var; - Collection::List collections; - Item::List items; - QMap flagCounts; - - // test moving maildir from maildir parent - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - Collection collection1_1; - collection1_1.setName( QLatin1String( "collection1_1" ) ); - collection1_1.setRemoteId( QLatin1String( "collection1_1" ) ); - collection1_1.setParentCollection( collection1 ); - - job = mStore->moveCollection( collection1_1, mStore->topLevelCollection() ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_1.remoteId() ); - QCOMPARE( collection.parentCollection(), mStore->topLevelCollection() ); - - fileInfo1_1.refresh(); - QVERIFY( !fileInfo1_1.exists() ); - fileInfo1_1 = QFileInfo( topDir.path(), collection.remoteId() ); - QVERIFY( fileInfo1_1.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // test moving mbox from maildir parent - Collection collection1_2; - collection1_2.setName( QLatin1String( "collection1_2" ) ); - collection1_2.setRemoteId( QLatin1String( "collection1_2" ) ); - collection1_2.setParentCollection( collection1 ); - - job = mStore->moveCollection( collection1_2, mStore->topLevelCollection() ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_2.remoteId() ); - QCOMPARE( collection.parentCollection(), mStore->topLevelCollection() ); - - fileInfo1_2.refresh(); - QVERIFY( !fileInfo1_2.exists() ); - fileInfo1_2 = QFileInfo( topDir.path(), collection.remoteId() ); - QVERIFY( fileInfo1_2.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // test moving mbox from mbox parent - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - Collection collection2_1; - collection2_1.setName( QLatin1String( "collection2_1" ) ); - collection2_1.setRemoteId( QLatin1String( "collection2_1" ) ); - collection2_1.setParentCollection( collection2 ); - - job = mStore->moveCollection( collection2_1, mStore->topLevelCollection() ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection2_1.remoteId() ); - QCOMPARE( collection.parentCollection(), mStore->topLevelCollection() ); - - fileInfo2_1.refresh(); - QVERIFY( !fileInfo2_1.exists() ); - fileInfo2_1 = QFileInfo( topDir.path(), collection.remoteId() ); - QVERIFY( fileInfo2_1.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // test moving maildir from mbox parent - Collection collection2_2; - collection2_2.setName( QLatin1String( "collection2_2" ) ); - collection2_2.setRemoteId( QLatin1String( "collection2_2" ) ); - collection2_2.setParentCollection( collection2 ); - - job = mStore->moveCollection( collection2_2, mStore->topLevelCollection() ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection2_2.remoteId() ); - QCOMPARE( collection.parentCollection(), mStore->topLevelCollection() ); - - fileInfo2_2.refresh(); - QVERIFY( !fileInfo2_2.exists() ); - fileInfo2_2 = QFileInfo( topDir.path(), collection.remoteId() ); - QVERIFY( fileInfo2_2.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); -} - -void CollectionMoveTest::testMoveToMaildir() -{ - QDir topDir( mDir->name() ); - - // top level dir - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QFileInfo fileInfo1( topDir, QLatin1String( "collection1" ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection2" ) ) ); - QFileInfo fileInfo2( topDir, QLatin1String( "collection2" ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection3" ) ) ); - QFileInfo fileInfo3( topDir, QLatin1String( "collection3" ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection4" ) ) ); - QFileInfo fileInfo4( topDir, QLatin1String( "collection4" ) ); - - // first level maildir parent - QDir subDir1 = topDir; - QVERIFY( subDir1.mkdir( QLatin1String( ".collection1.directory" ) ) ); - QVERIFY( subDir1.cd( QLatin1String( ".collection1.directory" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), subDir1.path(), QLatin1String( "collection1_1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), subDir1.path(), QLatin1String( "collection1_2" ) ) ); - - // first level mbox parent - QDir subDir4 = topDir; - QVERIFY( subDir4.mkdir( QLatin1String( ".collection4.directory" ) ) ); - QVERIFY( subDir4.cd( QLatin1String( ".collection4.directory" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), subDir4.path(), QLatin1String( "collection4_1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), subDir4.path(), QLatin1String( "collection4_2" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), subDir4.path(), QLatin1String( "collection4_3" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), subDir4.path(), QLatin1String( "collection4_4" ) ) ); - - // target maildir - KPIM::Maildir topLevelMd( topDir.path(), true ); - KPIM::Maildir targetMd( topLevelMd.addSubFolder( QLatin1String( "target" ) ), false ); - QVERIFY( targetMd.isValid() ); - QDir subDirTarget; - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::CollectionMoveJob *job = 0; - FileStore::ItemFetchJob *itemFetch = 0; - Collection collection; - const QVariant colListVar = QVariant::fromValue( Collection::List() ); - QVariant var; - Collection::List collections; - Item::List items; - QMap flagCounts; - - Collection target; - target.setName( QLatin1String( "target" ) ); - target.setRemoteId( QLatin1String( "target" ) ); - target.setParentCollection( mStore->topLevelCollection() ); - - // test move leaf maildir into sibling - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->moveCollection( collection2, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - subDirTarget = topDir; - QVERIFY( subDirTarget.cd( QLatin1String( ".target.directory" ) ) ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection2.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - fileInfo2.refresh(); - QVERIFY( !fileInfo2.exists() ); - fileInfo2 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo2.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // test move leaf mbox into sibling - Collection collection3; - collection3.setName( QLatin1String( "collection3" ) ); - collection3.setRemoteId( QLatin1String( "collection3" ) ); - collection3.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->moveCollection( collection3, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection3.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - fileInfo3.refresh(); - QVERIFY( !fileInfo3.exists() ); - fileInfo3 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo3.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // test move maildir with subtree into sibling - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - // load sub collection index data to check for correct cache updates - Collection collection1_1; - collection1_1.setName( QLatin1String( "collection1_1" ) ); - collection1_1.setRemoteId( QLatin1String( "collection1_1" ) ); - collection1_1.setParentCollection( collection1 ); - itemFetch = mStore->fetchItems( collection1_1 ); - QVERIFY( itemFetch->exec() ); - - Collection collection1_2; - collection1_2.setName( QLatin1String( "collection1_2" ) ); - collection1_2.setRemoteId( QLatin1String( "collection1_2" ) ); - collection1_2.setParentCollection( collection1 ); - itemFetch = mStore->fetchItems( collection1_2 ); - QVERIFY( itemFetch->exec() ); - - job = mStore->moveCollection( collection1, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - fileInfo1.refresh(); - QVERIFY( !fileInfo1.exists() ); - fileInfo1 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo1.exists() ); - QVERIFY( !subDir1.exists() ); - subDir1 = subDirTarget; - QVERIFY( subDir1.cd( QLatin1String( ".collection1.directory" ) ) ); - QCOMPARE( subDir1.entryList( QStringList() << QLatin1String( "collection*" ) ), - QStringList() << QLatin1String( "collection1_1" ) << QLatin1String( "collection1_2" ) ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // check for children cache path updates - collection1.setParentCollection( target ); - collection1_1.setParentCollection( collection1 ); - collection1_2.setParentCollection( collection1 ); - - itemFetch = mStore->fetchItems( collection1_1 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - itemFetch = mStore->fetchItems( collection1_2 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // test move mbox with subtree into sibling - Collection collection4; - collection4.setName( QLatin1String( "collection4" ) ); - collection4.setRemoteId( QLatin1String( "collection4" ) ); - collection4.setParentCollection( mStore->topLevelCollection() ); - - // load sub collection index data to check for correct cache updates - Collection collection4_1; - collection4_1.setName( QLatin1String( "collection4_1" ) ); - collection4_1.setRemoteId( QLatin1String( "collection4_1" ) ); - collection4_1.setParentCollection( collection4 ); - itemFetch = mStore->fetchItems( collection4_1 ); - QVERIFY( itemFetch->exec() ); - - Collection collection4_2; - collection4_2.setName( QLatin1String( "collection4_2" ) ); - collection4_2.setRemoteId( QLatin1String( "collection4_2" ) ); - collection4_2.setParentCollection( collection4 ); - itemFetch = mStore->fetchItems( collection4_2 ); - QVERIFY( itemFetch->exec() ); - - job = mStore->moveCollection( collection4, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection4.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - fileInfo4.refresh(); - QVERIFY( !fileInfo4.exists() ); - fileInfo4 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo4.exists() ); - QVERIFY( !subDir4.exists() ); - subDir4 = subDirTarget; - QVERIFY( subDir4.cd( QLatin1String( ".collection4.directory" ) ) ); - QCOMPARE( subDir4.entryList( QStringList() << QLatin1String( "collection*" ) ), - QStringList() << QLatin1String( "collection4_1" ) << QLatin1String( "collection4_2" ) - << QLatin1String( "collection4_3" ) << QLatin1String( "collection4_4" ) - ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // check for children cache path updates - collection4.setParentCollection( target ); - collection4_1.setParentCollection( collection4 ); - collection4_2.setParentCollection( collection4 ); - - itemFetch = mStore->fetchItems( collection4_1 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - itemFetch = mStore->fetchItems( collection4_2 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent maildir to parent's sibling - collection2.setParentCollection( target ); - - job = mStore->moveCollection( collection1_1, collection2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - QDir subDir2 = subDirTarget; - QVERIFY( subDir2.cd( QLatin1String( ".collection2.directory" ) ) ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_1.remoteId() ); - QCOMPARE( collection.parentCollection(), collection2 ); - - QFileInfo fileInfo1_1( subDir1, collection.remoteId() ); - QVERIFY( !fileInfo1_1.exists() ); - fileInfo1_1 = QFileInfo( subDir2, collection.remoteId() ); - QVERIFY( fileInfo1_1.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent maildir to parent's sibling - job = mStore->moveCollection( collection1_2, collection2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_2.remoteId() ); - QCOMPARE( collection.parentCollection(), collection2 ); - - QFileInfo fileInfo1_2( subDir1, collection.remoteId() ); - QVERIFY( !fileInfo1_2.exists() ); - fileInfo1_2 = QFileInfo( subDir2, collection.remoteId() ); - QVERIFY( fileInfo1_2.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent mbox to parent's sibling - job = mStore->moveCollection( collection4_1, collection2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection4_1.remoteId() ); - QCOMPARE( collection.parentCollection(), collection2 ); - - QFileInfo fileInfo4_1( subDir4, collection.remoteId() ); - QVERIFY( !fileInfo4_1.exists() ); - fileInfo4_1 = QFileInfo( subDir2, collection.remoteId() ); - QVERIFY( fileInfo4_1.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent mbox to parent's sibling - job = mStore->moveCollection( collection4_2, collection2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection4_2.remoteId() ); - QCOMPARE( collection.parentCollection(), collection2 ); - - QFileInfo fileInfo4_2( subDir4, collection.remoteId() ); - QVERIFY( !fileInfo4_2.exists() ); - fileInfo4_2 = QFileInfo( subDir2, collection.remoteId() ); - QVERIFY( fileInfo4_2.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent maildir to grandparent - collection1_1.setParentCollection( collection2 ); - - job = mStore->moveCollection( collection1_1, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_1.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - fileInfo1_1.refresh(); - QVERIFY( !fileInfo1_1.exists() ); - fileInfo1_1 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo1_1.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent maildir to grandparent - collection1_2.setParentCollection( collection2 ); - job = mStore->moveCollection( collection1_2, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_2.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - fileInfo1_2.refresh(); - QVERIFY( !fileInfo1_2.exists() ); - fileInfo1_2 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo1_2.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent mbox to grandparent - Collection collection4_3; - collection4_3.setName( QLatin1String( "collection4_3" ) ); - collection4_3.setRemoteId( QLatin1String( "collection4_3" ) ); - collection4_3.setParentCollection( collection4 ); - - job = mStore->moveCollection( collection4_3, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection4_3.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - QFileInfo fileInfo4_3( subDir4, collection.remoteId() ); - QVERIFY( !fileInfo4_3.exists() ); - fileInfo4_3 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo4_3.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent mbox to grandparent - Collection collection4_4; - collection4_4.setName( QLatin1String( "collection4_4" ) ); - collection4_4.setRemoteId( QLatin1String( "collection4_4" ) ); - collection4_4.setParentCollection( collection4 ); - - job = mStore->moveCollection( collection4_4, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection4_4.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - QFileInfo fileInfo4_4( subDir4, collection.remoteId() ); - QVERIFY( !fileInfo4_4.exists() ); - fileInfo4_4 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo4_4.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from maildir to grandchild - collection1_1.setParentCollection( target ); - - job = mStore->moveCollection( collection1_1, collection2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_1.remoteId() ); - QCOMPARE( collection.parentCollection(), collection2 ); - - fileInfo1_1.refresh(); - QVERIFY( !fileInfo1_1.exists() ); - fileInfo1_1 = QFileInfo( subDir2, collection.remoteId() ); - QVERIFY( fileInfo1_1.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from maildir to grandchild - collection1_2.setParentCollection( target ); - - job = mStore->moveCollection( collection1_2, collection2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_2.remoteId() ); - QCOMPARE( collection.parentCollection(), collection2 ); - - fileInfo1_2.refresh(); - QVERIFY( !fileInfo1_2.exists() ); - fileInfo1_2 = QFileInfo( subDir2, collection.remoteId() ); - QVERIFY( fileInfo1_2.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); -} - -void CollectionMoveTest::testMoveToMBox() -{ - QDir topDir( mDir->name() ); - - // top level dir - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QFileInfo fileInfo1( topDir, QLatin1String( "collection1" ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection2" ) ) ); - QFileInfo fileInfo2( topDir, QLatin1String( "collection2" ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection3" ) ) ); - QFileInfo fileInfo3( topDir, QLatin1String( "collection3" ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection4" ) ) ); - QFileInfo fileInfo4( topDir, QLatin1String( "collection4" ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection5" ) ) ); - QFileInfo fileInfo5( topDir, QLatin1String( "collection5" ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection6" ) ) ); - QFileInfo fileInfo6( topDir, QLatin1String( "collection6" ) ); - - // first level maildir parent - QDir subDir1 = topDir; - QVERIFY( subDir1.mkdir( QLatin1String( ".collection1.directory" ) ) ); - QVERIFY( subDir1.cd( QLatin1String( ".collection1.directory" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), subDir1.path(), QLatin1String( "collection1_1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), subDir1.path(), QLatin1String( "collection1_2" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), subDir1.path(), QLatin1String( "collection1_3" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), subDir1.path(), QLatin1String( "collection1_4" ) ) ); - - // first level mbox parent - QDir subDir4 = topDir; - QVERIFY( subDir4.mkdir( QLatin1String( ".collection4.directory" ) ) ); - QVERIFY( subDir4.cd( QLatin1String( ".collection4.directory" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), subDir4.path(), QLatin1String( "collection4_1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), subDir4.path(), QLatin1String( "collection4_2" ) ) ); - - // target mbox - QFileInfo fileInfoTarget( topDir.path(), QLatin1String( "target" ) ); - QFile fileTarget( fileInfoTarget.absoluteFilePath() ); - QVERIFY( fileTarget.open( QIODevice::WriteOnly ) ); - fileTarget.close(); - QVERIFY( fileInfoTarget.exists() ); - - QDir subDirTarget; - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::CollectionMoveJob *job = 0; - FileStore::ItemFetchJob *itemFetch = 0; - Collection collection; - const QVariant colListVar = QVariant::fromValue( Collection::List() ); - QVariant var; - Collection::List collections; - Item::List items; - QMap flagCounts; - - Collection target; - target.setName( QLatin1String( "target" ) ); - target.setRemoteId( QLatin1String( "target" ) ); - target.setParentCollection( mStore->topLevelCollection() ); - - // test move leaf maildir into sibling - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->moveCollection( collection2, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - subDirTarget = topDir; - QVERIFY( subDirTarget.cd( QLatin1String( ".target.directory" ) ) ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection2.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - fileInfo2.refresh(); - QVERIFY( !fileInfo2.exists() ); - fileInfo2 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo2.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // test move leaf mbox into sibling - Collection collection3; - collection3.setName( QLatin1String( "collection3" ) ); - collection3.setRemoteId( QLatin1String( "collection3" ) ); - collection3.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->moveCollection( collection3, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection3.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - fileInfo3.refresh(); - QVERIFY( !fileInfo3.exists() ); - fileInfo3 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo3.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // test move leaf mbox into sibling without subtree - Collection collection5; - collection5.setName( QLatin1String( "collection5" ) ); - collection5.setRemoteId( QLatin1String( "collection5" ) ); - collection5.setParentCollection( mStore->topLevelCollection() ); - - Collection collection6; - collection6.setName( QLatin1String( "collection6" ) ); - collection6.setRemoteId( QLatin1String( "collection6" ) ); - collection6.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->moveCollection( collection5, collection6 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection5.remoteId() ); - QCOMPARE( collection.parentCollection(), collection6 ); - - fileInfo5.refresh(); - QVERIFY( !fileInfo5.exists() ); - QDir subDir6 = topDir; - QVERIFY( subDir6.cd( QLatin1String( ".collection6.directory" ) ) ); - fileInfo5 = QFileInfo( subDir6, collection.remoteId() ); - QVERIFY( fileInfo5.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // test move maildir with subtree into sibling - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - // load sub collection index data to check for correct cache updates - Collection collection1_1; - collection1_1.setName( QLatin1String( "collection1_1" ) ); - collection1_1.setRemoteId( QLatin1String( "collection1_1" ) ); - collection1_1.setParentCollection( collection1 ); - itemFetch = mStore->fetchItems( collection1_1 ); - QVERIFY( itemFetch->exec() ); - - Collection collection1_2; - collection1_2.setName( QLatin1String( "collection1_2" ) ); - collection1_2.setRemoteId( QLatin1String( "collection1_2" ) ); - collection1_2.setParentCollection( collection1 ); - itemFetch = mStore->fetchItems( collection1_2 ); - QVERIFY( itemFetch->exec() ); - - job = mStore->moveCollection( collection1, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - fileInfo1.refresh(); - QVERIFY( !fileInfo1.exists() ); - fileInfo1 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo1.exists() ); - QVERIFY( !subDir1.exists() ); - subDir1 = subDirTarget; - QVERIFY( subDir1.cd( QLatin1String( ".collection1.directory" ) ) ); - QCOMPARE( subDir1.entryList( QStringList() << QLatin1String( "collection*" ) ), - QStringList() << QLatin1String( "collection1_1" ) << QLatin1String( "collection1_2" ) - << QLatin1String( "collection1_3" ) << QLatin1String( "collection1_4" ) - ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // check for children cache path updates - collection1.setParentCollection( target ); - collection1_1.setParentCollection( collection1 ); - collection1_2.setParentCollection( collection1 ); - - itemFetch = mStore->fetchItems( collection1_1 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - itemFetch = mStore->fetchItems( collection1_2 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // test move mbox with subtree into sibling - Collection collection4; - collection4.setName( QLatin1String( "collection4" ) ); - collection4.setRemoteId( QLatin1String( "collection4" ) ); - collection4.setParentCollection( mStore->topLevelCollection() ); - - // load sub collection index data to check for correct cache updates - Collection collection4_1; - collection4_1.setName( QLatin1String( "collection4_1" ) ); - collection4_1.setRemoteId( QLatin1String( "collection4_1" ) ); - collection4_1.setParentCollection( collection4 ); - itemFetch = mStore->fetchItems( collection4_1 ); - QVERIFY( itemFetch->exec() ); - - Collection collection4_2; - collection4_2.setName( QLatin1String( "collection4_2" ) ); - collection4_2.setRemoteId( QLatin1String( "collection4_2" ) ); - collection4_2.setParentCollection( collection4 ); - itemFetch = mStore->fetchItems( collection4_2 ); - QVERIFY( itemFetch->exec() ); - - job = mStore->moveCollection( collection4, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection4.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - fileInfo4.refresh(); - QVERIFY( !fileInfo4.exists() ); - fileInfo4 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo4.exists() ); - QVERIFY( !subDir4.exists() ); - subDir4 = subDirTarget; - QVERIFY( subDir4.cd( QLatin1String( ".collection4.directory" ) ) ); - QCOMPARE( subDir4.entryList( QStringList() << QLatin1String( "collection*" ) ), - QStringList() << QLatin1String( "collection4_1" ) << QLatin1String( "collection4_2" ) - ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // check for children cache path updates - collection4.setParentCollection( target ); - collection4_1.setParentCollection( collection4 ); - collection4_2.setParentCollection( collection4 ); - - itemFetch = mStore->fetchItems( collection4_1 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - itemFetch = mStore->fetchItems( collection4_2 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent maildir to parent's sibling - collection3.setParentCollection( target ); - - job = mStore->moveCollection( collection1_1, collection3 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - QDir subDir3 = subDirTarget; - QVERIFY( subDir3.cd( QLatin1String( ".collection3.directory" ) ) ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_1.remoteId() ); - QCOMPARE( collection.parentCollection(), collection3 ); - - QFileInfo fileInfo1_1( subDir1, collection.remoteId() ); - QVERIFY( !fileInfo1_1.exists() ); - fileInfo1_1 = QFileInfo( subDir3, collection.remoteId() ); - QVERIFY( fileInfo1_1.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent maildir to parent's sibling - job = mStore->moveCollection( collection1_2, collection3 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_2.remoteId() ); - QCOMPARE( collection.parentCollection(), collection3 ); - - QFileInfo fileInfo1_2( subDir1, collection.remoteId() ); - QVERIFY( !fileInfo1_2.exists() ); - fileInfo1_2 = QFileInfo( subDir3, collection.remoteId() ); - QVERIFY( fileInfo1_2.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent mbox to parent's sibling - job = mStore->moveCollection( collection4_1, collection3 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection4_1.remoteId() ); - QCOMPARE( collection.parentCollection(), collection3 ); - - QFileInfo fileInfo4_1( subDir4, collection.remoteId() ); - QVERIFY( !fileInfo4_1.exists() ); - fileInfo4_1 = QFileInfo( subDir3, collection.remoteId() ); - QVERIFY( fileInfo4_1.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent mbox to parent's sibling - job = mStore->moveCollection( collection4_2, collection3 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection4_2.remoteId() ); - QCOMPARE( collection.parentCollection(), collection3 ); - - QFileInfo fileInfo4_2( subDir4, collection.remoteId() ); - QVERIFY( !fileInfo4_2.exists() ); - fileInfo4_2 = QFileInfo( subDir3, collection.remoteId() ); - QVERIFY( fileInfo4_2.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent mbox to grandparent - collection1_1.setParentCollection( collection3 ); - - job = mStore->moveCollection( collection1_1, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_1.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - fileInfo1_1.refresh(); - QVERIFY( !fileInfo1_1.exists() ); - fileInfo1_1 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo1_1.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent mbox to grandparent - collection1_2.setParentCollection( collection3 ); - job = mStore->moveCollection( collection1_2, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_2.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - fileInfo1_2.refresh(); - QVERIFY( !fileInfo1_2.exists() ); - fileInfo1_2 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo1_2.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent maildir to grandparent - Collection collection1_3; - collection1_3.setName( QLatin1String( "collection1_3" ) ); - collection1_3.setRemoteId( QLatin1String( "collection1_3" ) ); - collection1_3.setParentCollection( collection1 ); - - job = mStore->moveCollection( collection1_3, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_3.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - QFileInfo fileInfo1_3( subDir1, collection.remoteId() ); - QVERIFY( !fileInfo1_3.exists() ); - fileInfo1_3 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo1_3.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from parent maildir to grandparent - Collection collection1_4; - collection1_4.setName( QLatin1String( "collection1_4" ) ); - collection1_4.setRemoteId( QLatin1String( "collection1_4" ) ); - collection1_4.setParentCollection( collection1 ); - - job = mStore->moveCollection( collection1_4, target ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_4.remoteId() ); - QCOMPARE( collection.parentCollection(), target ); - - QFileInfo fileInfo1_4( subDir1, collection.remoteId() ); - QVERIFY( !fileInfo1_4.exists() ); - fileInfo1_4 = QFileInfo( subDirTarget, collection.remoteId() ); - QVERIFY( fileInfo1_4.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from mbox to grandchild - collection1_1.setParentCollection( target ); - - job = mStore->moveCollection( collection1_1, collection3 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_1.remoteId() ); - QCOMPARE( collection.parentCollection(), collection3 ); - - fileInfo1_1.refresh(); - QVERIFY( !fileInfo1_1.exists() ); - fileInfo1_1 = QFileInfo( subDir3, collection.remoteId() ); - QVERIFY( fileInfo1_1.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - // move from maildir to grandchild - collection1_2.setParentCollection( target ); - - job = mStore->moveCollection( collection1_2, collection3 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collection = job->collection(); - QCOMPARE( collection.remoteId(), collection1_2.remoteId() ); - QCOMPARE( collection.parentCollection(), collection3 ); - - fileInfo1_2.refresh(); - QVERIFY( !fileInfo1_2.exists() ); - fileInfo1_2 = QFileInfo( subDir3, collection.remoteId() ); - QVERIFY( fileInfo1_2.exists() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 4 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); -} - -QTEST_KDEMAIN( CollectionMoveTest, NoGUI ) - -#include "collectionmovetest.moc" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.g8PCJ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.g8PCJ --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.g8PCJ 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.g8PCJ 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx106) with SMTP; 24 Jul 2010 15:51:39 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id A6DEC95366A - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 6305495366F - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id 4D0C995366A - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 21F263103EEB - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 06BF13103EE6 - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 3 -Date: Sat, 24 Jul 2010 15:51:36 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241551.37547.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: R -X-Status: N -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: -X-UID: 12 - - diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.LUBVK kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.LUBVK --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.LUBVK 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.LUBVK 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx102) with SMTP; 24 Jul 2010 15:51:39 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 5074095366D - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id DEC1195366F - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id C668A95366D - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 9EEB53103EE6 - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 8367A3103EEE - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 2 -Date: Sat, 24 Jul 2010 15:51:16 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241551.16855.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: RO -X-Status: U -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: -X-UID: 10 - -Body of Test 2 diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.qs6V9_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.qs6V9_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.qs6V9_2,S 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.qs6V9_2,S 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:41 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx033) with SMTP; 24 Jul 2010 15:51:41 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id BD28395366A - for ; Sat, 24 Jul 2010 15:51:40 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id CA62095366E - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id B5E0195366A - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 754B03103EEB - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 545963103EE6 - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 1 -Date: Sat, 24 Jul 2010 15:50:45 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241550.46907.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: RO -X-Status: RG -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: -X-UID: 13 - -Body -of -Test 1 diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.RTmAd_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.RTmAd_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.RTmAd_2,S 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/dimap/cur/1279980064.4595.RTmAd_2,S 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:52:14 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx036) with SMTP; 24 Jul 2010 15:52:14 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 3536595366D - for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 101AC95366A - for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id ED25794D9DA - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id C2DA93103EEB - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id AE2D13103EE6 - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Date: Sat, 24 Jul 2010 15:52:00 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241552.01232.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iM2SSXdnXxuLgAcAvPC3Xr5Z6OPcGoHnWX0YgscMEgMNa/UP6 - 0PsZjBktxR5hqB4N3jaDTD+60EUFg8bPz1GGvD1YActDYJympMTApbcs85zthOivOU3SH3UvpiHN - TRN8A==V1; -Status: RO -X-Status: RK -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: -X-UID: 11 - -Body of Test 4 diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/dimap/new/.keep kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/dimap/new/.keep --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/dimap/new/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/dimap/new/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/dimap/tmp/.keep kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/dimap/tmp/.keep --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/dimap/tmp/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/dimap/tmp/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/.dimap.index and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/.dimap.index differ diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir/cur/1279979617.4595.bwXSm kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir/cur/1279979617.4595.bwXSm --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir/cur/1279979617.4595.bwXSm 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir/cur/1279979617.4595.bwXSm 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx106) with SMTP; 24 Jul 2010 15:51:39 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id A6DEC95366A - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 6305495366F - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id 4D0C995366A - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 21F263103EEB - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 06BF13103EE6 - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 3 -Date: Sat, 24 Jul 2010 15:51:36 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241551.37547.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: R -X-Status: N -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - - diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir/cur/1279979618.4595.CStza_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir/cur/1279979618.4595.CStza_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir/cur/1279979618.4595.CStza_2,S 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir/cur/1279979618.4595.CStza_2,S 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:41 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx033) with SMTP; 24 Jul 2010 15:51:41 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id BD28395366A - for ; Sat, 24 Jul 2010 15:51:40 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id CA62095366E - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id B5E0195366A - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 754B03103EEB - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 545963103EE6 - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 1 -Date: Sat, 24 Jul 2010 15:50:45 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241550.46907.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: RO -X-Status: R -X-KMail-EncryptionState: N -X-KMail-SignatureState: N -X-KMail-MDN-Sent: - -Body -of -Test 1 diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir/cur/1279979618.4595.DUl0I_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir/cur/1279979618.4595.DUl0I_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir/cur/1279979618.4595.DUl0I_2,S 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir/cur/1279979618.4595.DUl0I_2,S 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:52:14 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx036) with SMTP; 24 Jul 2010 15:52:14 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 3536595366D - for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 101AC95366A - for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id ED25794D9DA - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id C2DA93103EEB - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id AE2D13103EE6 - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Date: Sat, 24 Jul 2010 15:52:00 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241552.01232.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iM2SSXdnXxuLgAcAvPC3Xr5Z6OPcGoHnWX0YgscMEgMNa/UP6 - 0PsZjBktxR5hqB4N3jaDTD+60EUFg8bPz1GGvD1YActDYJympMTApbcs85zthOivOU3SH3UvpiHN - TRN8A==V1; -Status: RO -X-Status: R -X-KMail-EncryptionState: N -X-KMail-SignatureState: N -X-KMail-MDN-Sent: - -Body of Test 4 diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir/cur/1279979618.4595.pY5ny kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir/cur/1279979618.4595.pY5ny --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir/cur/1279979618.4595.pY5ny 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir/cur/1279979618.4595.pY5ny 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx102) with SMTP; 24 Jul 2010 15:51:39 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 5074095366D - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id DEC1195366F - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id C668A95366D - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 9EEB53103EE6 - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 8367A3103EEE - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 2 -Date: Sat, 24 Jul 2010 15:51:16 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241551.16855.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: R -X-Status: N -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -Body of Test 2 diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir/new/.keep kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir/new/.keep --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir/new/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir/new/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir/tmp/.keep kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir/tmp/.keep --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir/tmp/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir/tmp/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/.maildir.index and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/.maildir.index differ diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.6qZsA_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.6qZsA_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.6qZsA_2,S 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.6qZsA_2,S 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:52:14 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx036) with SMTP; 24 Jul 2010 15:52:14 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 3536595366D - for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 101AC95366A - for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id ED25794D9DA - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id C2DA93103EEB - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id AE2D13103EE6 - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Date: Sat, 24 Jul 2010 15:52:00 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241552.01232.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iM2SSXdnXxuLgAcAvPC3Xr5Z6OPcGoHnWX0YgscMEgMNa/UP6 - 0PsZjBktxR5hqB4N3jaDTD+60EUFg8bPz1GGvD1YActDYJympMTApbcs85zthOivOU3SH3UvpiHN - TRN8A==V1; -Status: RO -X-Status: RK -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -Body of Test 4 - diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.f0l49_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.f0l49_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.f0l49_2,S 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.f0l49_2,S 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx106) with SMTP; 24 Jul 2010 15:51:39 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id A6DEC95366A - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 6305495366F - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id 4D0C995366A - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 21F263103EEB - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 06BF13103EE6 - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 3 -Date: Sat, 24 Jul 2010 15:51:36 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241551.37547.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: R -X-Status: N -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - - diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.kwx1b_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.kwx1b_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.kwx1b_2,S 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.kwx1b_2,S 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:41 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx033) with SMTP; 24 Jul 2010 15:51:41 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id BD28395366A - for ; Sat, 24 Jul 2010 15:51:40 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id CA62095366E - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id B5E0195366A - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 754B03103EEB - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 545963103EE6 - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 1 -Date: Sat, 24 Jul 2010 15:50:45 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241550.46907.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: RO -X-Status: RG -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -Body -of -Test 1 diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.Xdz3R_2,S kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.Xdz3R_2,S --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.Xdz3R_2,S 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir-tagged/cur/1279982188.18722.Xdz3R_2,S 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx102) with SMTP; 24 Jul 2010 15:51:39 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 5074095366D - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id DEC1195366F - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id C668A95366D - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 9EEB53103EE6 - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 8367A3103EEE - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 2 -Date: Sat, 24 Jul 2010 15:51:16 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241551.16855.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: RO -X-Status: U -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -Body of Test 2 - diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir-tagged/new/.keep kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir-tagged/new/.keep --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir-tagged/new/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir-tagged/new/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir-tagged/tmp/.keep kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir-tagged/tmp/.keep --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/maildir-tagged/tmp/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/maildir-tagged/tmp/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/.maildir-tagged.index and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/.maildir-tagged.index differ diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/mbox kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/mbox --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/mbox 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/mbox 1970-01-01 00:00:00.000000000 +0000 @@ -1,187 +0,0 @@ -From kevin.krammer@demo.kolab.org Sat Jul 24 15:51:16 2010 -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx102) with SMTP; 24 Jul 2010 15:51:39 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 5074095366D - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id DEC1195366F - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id C668A95366D - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 9EEB53103EE6 - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 8367A3103EEE - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 2 -Date: Sat, 24 Jul 2010 15:51:16 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241551.16855.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: RO -X-Status: U -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -Body of Test 2 - -From kevin.krammer@demo.kolab.org Sat Jul 24 15:52:00 2010 -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:52:14 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx036) with SMTP; 24 Jul 2010 15:52:14 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 3536595366D - for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 101AC95366A - for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id ED25794D9DA - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id C2DA93103EEB - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id AE2D13103EE6 - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Date: Sat, 24 Jul 2010 15:52:00 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241552.01232.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iM2SSXdnXxuLgAcAvPC3Xr5Z6OPcGoHnWX0YgscMEgMNa/UP6 - 0PsZjBktxR5hqB4N3jaDTD+60EUFg8bPz1GGvD1YActDYJympMTApbcs85zthOivOU3SH3UvpiHN - TRN8A==V1; -Status: RO -X-Status: RK -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -Body of Test 4 - -From kevin.krammer@demo.kolab.org Sat Jul 24 15:51:36 2010 -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx106) with SMTP; 24 Jul 2010 15:51:39 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id A6DEC95366A - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 6305495366F - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id 4D0C995366A - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 21F263103EEB - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 06BF13103EE6 - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 3 -Date: Sat, 24 Jul 2010 15:51:36 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241551.37547.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: R -X-Status: N -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - - -From kevin.krammer@demo.kolab.org Sat Jul 24 15:50:45 2010 -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:41 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx033) with SMTP; 24 Jul 2010 15:51:41 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id BD28395366A - for ; Sat, 24 Jul 2010 15:51:40 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id CA62095366E - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id B5E0195366A - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 754B03103EEB - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 545963103EE6 - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 1 -Date: Sat, 24 Jul 2010 15:50:45 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241550.46907.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: RO -X-Status: RG -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -Body -of -Test 1 Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/.mbox.index and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/.mbox.index differ diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/mbox-tagged kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/mbox-tagged --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/mbox-tagged 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/mbox-tagged 1970-01-01 00:00:00.000000000 +0000 @@ -1,187 +0,0 @@ -From kevin.krammer@demo.kolab.org Sat Jul 24 15:51:16 2010 -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx102) with SMTP; 24 Jul 2010 15:51:39 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 5074095366D - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id DEC1195366F - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id C668A95366D - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 9EEB53103EE6 - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 8367A3103EEE - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 2 -Date: Sat, 24 Jul 2010 15:51:16 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241551.16855.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: RO -X-Status: U -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -Body of Test 2 - -From kevin.krammer@demo.kolab.org Sat Jul 24 15:52:00 2010 -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:52:14 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx036) with SMTP; 24 Jul 2010 15:52:14 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 3536595366D - for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 101AC95366A - for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id ED25794D9DA - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id C2DA93103EEB - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id AE2D13103EE6 - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Date: Sat, 24 Jul 2010 15:52:00 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241552.01232.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iM2SSXdnXxuLgAcAvPC3Xr5Z6OPcGoHnWX0YgscMEgMNa/UP6 - 0PsZjBktxR5hqB4N3jaDTD+60EUFg8bPz1GGvD1YActDYJympMTApbcs85zthOivOU3SH3UvpiHN - TRN8A==V1; -Status: RO -X-Status: RK -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -Body of Test 4 - -From kevin.krammer@demo.kolab.org Sat Jul 24 15:51:36 2010 -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx106) with SMTP; 24 Jul 2010 15:51:39 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id A6DEC95366A - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 6305495366F - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id 4D0C995366A - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 21F263103EEB - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 06BF13103EE6 - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 3 -Date: Sat, 24 Jul 2010 15:51:36 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241551.37547.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: R -X-Status: N -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - - -From kevin.krammer@demo.kolab.org Sat Jul 24 15:50:45 2010 -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:41 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx033) with SMTP; 24 Jul 2010 15:51:41 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id BD28395366A - for ; Sat, 24 Jul 2010 15:51:40 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id CA62095366E - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id B5E0195366A - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 754B03103EEB - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 545963103EE6 - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 1 -Date: Sat, 24 Jul 2010 15:50:45 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241550.46907.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: RO -X-Status: RG -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -Body -of -Test 1 Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/.mbox-tagged.index and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/.mbox-tagged.index differ diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/mbox-unpurged kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/mbox-unpurged --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/mbox-unpurged 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/mbox-unpurged 1970-01-01 00:00:00.000000000 +0000 @@ -1,187 +0,0 @@ -From kevin.krammer@demo.kolab.org Sat Jul 24 15:51:16 2010 -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx102) with SMTP; 24 Jul 2010 15:51:39 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 5074095366D - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id DEC1195366F - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id C668A95366D - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 9EEB53103EE6 - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 8367A3103EEE - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 2 -Date: Sat, 24 Jul 2010 15:51:16 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241551.16855.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: RO -X-Status: U -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -Body of Test 2 - -From kevin.krammer@demo.kolab.org Sat Jul 24 15:52:00 2010 -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:52:14 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx036) with SMTP; 24 Jul 2010 15:52:14 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 3536595366D - for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 101AC95366A - for ; Sat, 24 Jul 2010 15:52:14 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id ED25794D9DA - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id C2DA93103EEB - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id AE2D13103EE6 - for ; Sat, 24 Jul 2010 15:52:13 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Date: Sat, 24 Jul 2010 15:52:00 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241552.01232.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iM2SSXdnXxuLgAcAvPC3Xr5Z6OPcGoHnWX0YgscMEgMNa/UP6 - 0PsZjBktxR5hqB4N3jaDTD+60EUFg8bPz1GGvD1YActDYJympMTApbcs85zthOivOU3SH3UvpiHN - TRN8A==V1; -Status: RO -X-Status: RK -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -Body of Test 4 - -From kevin.krammer@demo.kolab.org Sat Jul 24 15:51:36 2010 -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:39 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx106) with SMTP; 24 Jul 2010 15:51:39 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id A6DEC95366A - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id 6305495366F - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id 4D0C995366A - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 21F263103EEB - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 06BF13103EE6 - for ; Sat, 24 Jul 2010 15:51:39 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 3 -Date: Sat, 24 Jul 2010 15:51:36 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241551.37547.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: R -X-Status: N -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - - -From kevin.krammer@demo.kolab.org Sat Jul 24 15:50:45 2010 -Return-Path: -Delivered-To: GMX delivery to kevin.krammer@gmx.at -Received: (qmail invoked by alias); 24 Jul 2010 13:51:41 -0000 -Received: from aktaia.intevation.org (EHLO kolab.intevation.de) [212.95.126.10] - by mx0.gmx.net (mx033) with SMTP; 24 Jul 2010 15:51:41 +0200 -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id BD28395366A - for ; Sat, 24 Jul 2010 15:51:40 +0200 (CEST) -X-Virus-Scanned: by amavisd-new at intevation.de -Received: from localhost (localhost.localdomain [127.0.0.1]) - by kolab.intevation.de (Postfix) with ESMTP id CA62095366E - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from demo.kolab.org (demo.kolab.org [78.47.168.37]) - by kolab.intevation.de (Postfix) with ESMTP id B5E0195366A - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from localhost (localhost [127.0.0.1]) - by demo.kolab.org (Postfix) with ESMTP id 754B03103EEB - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -Received: from artemis.localnet (bergfex.jusinger.at [213.47.44.9]) - (Authenticated sender: kevin.krammer@demo.kolab.org) - by demo.kolab.org (Postfix) with ESMTP id 545963103EE6 - for ; Sat, 24 Jul 2010 15:51:38 +0200 (CEST) -From: Kevin Krammer -Organization: Kolab Demo -To: kevin.krammer@gmx.at -Subject: Test 1 -Date: Sat, 24 Jul 2010 15:50:45 +0200 -User-Agent: KMail/1.13.3 (Linux/2.6.33-grml; KDE/4.4.4; i686; ; ) -MIME-Version: 1.0 -Content-Type: Text/Plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -Message-Id: <201007241550.46907.kevin.krammer@demo.kolab.org> -X-GMX-Antivirus: 0 (no virus found) -X-GMX-Antispam: 0 (Mail was not recognized as spam); - Detail=5D7Q89H36p5mOUCHqrP9iL/6eeEA7/vGXc8Az2zQ5lkNsVrprUw5ljr293uKsrVdFBp1i - k5eF2TKdovp4qtfEvYkwJlTyCJPnhg0xAPWnM7rhY/+LZUrte1UAr5224vU33NgWA8bmceIWcEOY - UsgKg==V1; -Status: RO -X-Status: RG -X-KMail-EncryptionState: -X-KMail-SignatureState: -X-KMail-MDN-Sent: - -Body -of -Test 1 Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/.mbox-unpurged.index and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/.mbox-unpurged.index differ diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/README kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/README --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/data/README 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/data/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -Description of contained Test data -================================== - -maildir/dimap message filenames that contained ':' had it replaced with '_' - -1) dimap: 4 messages + index - - message 1 flagged important - - message 2 flagged unread - - message 3 flagged new, empty body - - message 4 flagged task, empty subject - -2) maildir: 4 messages + index - - message 1 flagged important - - message 2 flagged unread - - message 3 flagged new, empty body - - message 4 flagged task, empty subject - -3) mbox: 4 messages + index - - message 1 flagged unread - - message 2 flagged task, empty subject - - message 3 flagged new, empty body - - message 4 flagged important - -4) maildir-tagged: 4 messages + index - - message 1 flagged important, tag1 - - message 2 flagged unread, tag2 - - message 3 flagged new, empty body, tag 3 - - message 4 flagged task, empty subject - -5) mbox-tagged: 4 messages + index - - message 1 flagged unread, tag2 - - message 2 flagged task, empty subject - - message 3 flagged new, empty body, tag 3 - - message 4 flagged important, tag1 - -6) mbox-unpurged: 4 messages + index with entries for the first two - - simulating an unpurged mbox: all messages in mbox, no index entries for - the two messages in the middle diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/itemcreatetest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/tests/itemcreatetest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/itemcreatetest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/itemcreatetest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,535 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" - -#include "testdatautil.h" - -#include "filestore/itemcreatejob.h" -#include "filestore/itemfetchjob.h" - -#include "libmaildir/maildir.h" - -#include -#include - -#include -#include - -#include - -using namespace Akonadi; - -class ItemCreateTest : public QObject -{ - Q_OBJECT - - public: - ItemCreateTest() : QObject(), mStore( 0 ), mDir( 0 ) {} - - ~ItemCreateTest() { - delete mStore; - delete mDir; - } - - private: - MixedMaildirStore *mStore; - KTempDir *mDir; - - private Q_SLOTS: - void init(); - void cleanup(); - void testExpectedFail(); - void testMBox(); - void testMaildir(); -}; - -void ItemCreateTest::init() -{ - mStore = new MixedMaildirStore; - - mDir = new KTempDir; - QVERIFY( mDir->exists() ); -} - -void ItemCreateTest::cleanup() -{ - delete mStore; - mStore = 0; - delete mDir; - mDir = 0; -} - -void ItemCreateTest::testExpectedFail() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "data" ) ) ); - QDir dataDir = topDir; - QVERIFY( dataDir.cd( QLatin1String( "data" ) ) ); - KPIM::Maildir dataMd( dataDir.path(), false ); - QVERIFY( dataMd.isValid() ); - - const QStringList dataEntryList = dataMd.entryList(); - QCOMPARE( dataEntryList.count(), 4 ); - KMime::Message::Ptr msgPtr( new KMime::Message ); - msgPtr->setContent( KMime::CRLFtoLF( dataMd.readEntry( dataEntryList.first() ) ) ); - - QVERIFY( topDir.mkdir( QLatin1String( "store" ) ) ); - QVERIFY( topDir.cd( QLatin1String( "store" ) ) ); - mStore->setPath( topDir.path() ); - - FileStore::ItemCreateJob *job = 0; - - // test failure of adding item to top level collection - Item item; - item.setMimeType( KMime::Message::mimeType() ); - item.setPayload( msgPtr ); - - job = mStore->createItem( item, mStore->topLevelCollection() ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - // test failure of adding item to non existant collection - Collection collection; - collection.setName( QLatin1String( "collection" ) ); - collection.setRemoteId( QLatin1String( "collection" ) ); - collection.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->createItem( item, collection ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); -} - -void ItemCreateTest::testMBox() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "data" ) ) ); - QDir dataDir = topDir; - QVERIFY( dataDir.cd( QLatin1String( "data" ) ) ); - KPIM::Maildir dataMd( dataDir.path(), false ); - QVERIFY( dataMd.isValid() ); - - const QStringList dataEntryList = dataMd.entryList(); - QCOMPARE( dataEntryList.count(), 4 ); - KMime::Message::Ptr msgPtr1( new KMime::Message ); - msgPtr1->setContent( KMime::CRLFtoLF( dataMd.readEntry( dataEntryList.first() ) ) ); - KMime::Message::Ptr msgPtr2( new KMime::Message ); - msgPtr2->setContent( KMime::CRLFtoLF( dataMd.readEntry( dataEntryList.last() ) ) ); - - QVERIFY( topDir.mkdir( QLatin1String( "store" ) ) ); - QVERIFY( topDir.cd( QLatin1String( "store" ) ) ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection1" ) ) ); - - QFileInfo fileInfo1( topDir.path(), QLatin1String( "collection1" ) ); - KMBox::MBox mbox1; - QVERIFY( mbox1.load( fileInfo1.absoluteFilePath() ) ); - QCOMPARE( (int)mbox1.entries().count(), 4 ); - const int size1 = fileInfo1.size(); - - // simulate empty mbox - QFileInfo fileInfo2( topDir.path(), QLatin1String( "collection2" ) ); - QFile file2( fileInfo2.absoluteFilePath() ); - QVERIFY( file2.open( QIODevice::WriteOnly ) ); - file2.close(); - QVERIFY( file2.exists() ); - QCOMPARE( (int)file2.size(), 0 ); - - mStore->setPath( topDir.path() ); - - // common variables - const QVariant colListVar = QVariant::fromValue( Collection::List() ); - QVariant var; - Collection::List collections; - Item::List items; - QMap flagCounts; - - FileStore::ItemCreateJob *job = 0; - FileStore::ItemFetchJob *itemFetch = 0; - - // test adding to empty mbox - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - Item item1; - item1.setId( KRandom::random() ); - item1.setMimeType( KMime::Message::mimeType() ); - item1.setPayload( msgPtr1 ); - - job = mStore->createItem( item1, collection2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - Item item = job->item(); - QCOMPARE( item.id(), item1.id() ); - QVERIFY( !item.remoteId().isEmpty() ); - QCOMPARE( item.remoteId(), QLatin1String( "0" ) ); - QCOMPARE( item.parentCollection(), collection2 ); - - fileInfo2.refresh(); - QVERIFY( fileInfo2.size() > 0 ); - const int size2 = fileInfo2.size(); - - KMBox::MBox mbox2; - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - QCOMPARE( (int)mbox2.entries().count(), 1 ); - - Item item2; - item2.setId( KRandom::random() ); - item2.setMimeType( KMime::Message::mimeType() ); - item2.setPayload( msgPtr2 ); - - job = mStore->createItem( item2, collection2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - item = job->item(); - QCOMPARE( item.id(), item2.id() ); - QVERIFY( !item.remoteId().isEmpty() ); - QCOMPARE( item.remoteId(), QString::number( size2 + 1) ); - QCOMPARE( item.parentCollection(), collection2 ); - - fileInfo2.refresh(); - QVERIFY( fileInfo2.size() > 0 ); - - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - QCOMPARE( (int)mbox2.entries().count(), 2 ); - - // test adding to non-empty mbox - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->createItem( item1, collection1 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - item = job->item(); - QCOMPARE( item.id(), item1.id() ); - QVERIFY( !item.remoteId().isEmpty() ); - QCOMPARE( item.remoteId(), QString::number( size1 + 1 ) ); - QCOMPARE( item.parentCollection(), collection1 ); - - fileInfo1.refresh(); - QVERIFY( fileInfo1.size() > size1 ); - - QVERIFY( mbox1.load( fileInfo1.absoluteFilePath() ) ); - QCOMPARE( (int)mbox1.entries().count(), 5 ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection1 ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection1 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 5 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - job = mStore->createItem( item2, collection1 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - item = job->item(); - QCOMPARE( item.id(), item2.id() ); - QVERIFY( !item.remoteId().isEmpty() ); - QCOMPARE( item.remoteId(), QString::number( size1 + 1 + size2 + 1 ) ); - QCOMPARE( item.parentCollection(), collection1 ); - - fileInfo1.refresh(); - QVERIFY( fileInfo1.size() > (size1 + size2 ) ); - - QVERIFY( mbox1.load( fileInfo1.absoluteFilePath() ) ); - QCOMPARE( (int)mbox1.entries().count(), 6 ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection1 ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection1 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 6 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); -} - -void ItemCreateTest::testMaildir() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "data" ) ) ); - QDir dataDir = topDir; - QVERIFY( dataDir.cd( QLatin1String( "data" ) ) ); - KPIM::Maildir dataMd( dataDir.path(), false ); - QVERIFY( dataMd.isValid() ); - - const QStringList dataEntryList = dataMd.entryList(); - QCOMPARE( dataEntryList.count(), 4 ); - KMime::Message::Ptr msgPtr1( new KMime::Message ); - msgPtr1->setContent( KMime::CRLFtoLF( dataMd.readEntry( dataEntryList.first() ) ) ); - KMime::Message::Ptr msgPtr2( new KMime::Message ); - msgPtr2->setContent( KMime::CRLFtoLF( dataMd.readEntry( dataEntryList.last() ) ) ); - - QVERIFY( topDir.mkdir( QLatin1String( "store" ) ) ); - QVERIFY( topDir.cd( QLatin1String( "store" ) ) ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - - KPIM::Maildir topLevelMd( topDir.path(), true ); - KPIM::Maildir md1 = topLevelMd.subFolder( QLatin1String( "collection1" ) ); - QVERIFY( md1.isValid() ); - - QSet entrySet1 = QSet::fromList( md1.entryList() ); - QCOMPARE( (int)entrySet1.count(), 4 ); - - // simulate empty maildir - KPIM::Maildir md2( topLevelMd.addSubFolder( QLatin1String( "collection2" ) ), false ); - QVERIFY( md2.isValid() ); - - QSet entrySet2 = QSet::fromList( md2.entryList() ); - QCOMPARE( (int)entrySet2.count(), 0 ); - - mStore->setPath( topDir.path() ); - - // common variables - const QVariant colListVar = QVariant::fromValue( Collection::List() ); - QVariant var; - Collection::List collections; - Item::List items; - QMap flagCounts; - - QSet entrySet; - QSet newIdSet; - QString newId; - - FileStore::ItemCreateJob *job = 0; - FileStore::ItemFetchJob *itemFetch = 0; - - // test adding to empty maildir - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - Item item1; - item1.setId( KRandom::random() ); - item1.setMimeType( KMime::Message::mimeType() ); - item1.setPayload( msgPtr1 ); - - job = mStore->createItem( item1, collection2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - Item item = job->item(); - QCOMPARE( item.id(), item1.id() ); - QVERIFY( !item.remoteId().isEmpty() ); - QCOMPARE( item.parentCollection(), collection2 ); - - entrySet = QSet::fromList( md2.entryList() ); - QCOMPARE( (int)entrySet.count(), 1 ); - - newIdSet = entrySet.subtract( entrySet2 ); - QCOMPARE( (int)newIdSet.count(), 1 ); - - newId = newIdSet.values().first(); - QCOMPARE( item.remoteId(), newId ); - entrySet2 << newId; - QCOMPARE( (int)entrySet2.count(), 1 ); - - Item item2; - item2.setId( KRandom::random() ); - item2.setMimeType( KMime::Message::mimeType() ); - item2.setPayload( msgPtr2 ); - - job = mStore->createItem( item2, collection2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - item = job->item(); - QCOMPARE( item.id(), item2.id() ); - QVERIFY( !item.remoteId().isEmpty() ); - QCOMPARE( item.parentCollection(), collection2 ); - - entrySet = QSet::fromList( md2.entryList() ); - QCOMPARE( (int)entrySet.count(), 2 ); - - newIdSet = entrySet.subtract( entrySet2 ); - QCOMPARE( (int)newIdSet.count(), 1 ); - - newId = newIdSet.values().first(); - QCOMPARE( item.remoteId(), newId ); - entrySet2 << newId; - QCOMPARE( (int)entrySet2.count(), 2 ); - - // test adding to non-empty maildir - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->createItem( item1, collection1 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - item = job->item(); - QCOMPARE( item.id(), item1.id() ); - QVERIFY( !item.remoteId().isEmpty() ); - QCOMPARE( item.parentCollection(), collection1 ); - - entrySet = QSet::fromList( md1.entryList() ); - QCOMPARE( (int)entrySet.count(), 5 ); - - newIdSet = entrySet.subtract( entrySet1 ); - QCOMPARE( (int)newIdSet.count(), 1 ); - - newId = newIdSet.values().first(); - QCOMPARE( item.remoteId(), newId ); - entrySet1 << newId; - QCOMPARE( (int)entrySet1.count(), 5 ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection1 ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection1 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 5 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - job = mStore->createItem( item2, collection1 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - item = job->item(); - QCOMPARE( item.id(), item2.id() ); - QVERIFY( !item.remoteId().isEmpty() ); - QCOMPARE( item.parentCollection(), collection1 ); - - entrySet = QSet::fromList( md1.entryList() ); - QCOMPARE( (int)entrySet.count(), 6 ); - - newIdSet = entrySet.subtract( entrySet1 ); - QCOMPARE( (int)newIdSet.count(), 1 ); - - newId = newIdSet.values().first(); - QCOMPARE( item.remoteId(), newId ); - entrySet1 << newId; - QCOMPARE( (int)entrySet1.count(), 6 ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection1 ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection1 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 6 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); -} - -QTEST_KDEMAIN( ItemCreateTest, NoGUI ) - -#include "itemcreatetest.moc" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/itemdeletetest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/tests/itemdeletetest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/itemdeletetest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/itemdeletetest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,603 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" - -#include "testdatautil.h" - -#include "filestore/entitycompactchangeattribute.h" -#include "filestore/itemdeletejob.h" -#include "filestore/itemfetchjob.h" -#include "filestore/storecompactjob.h" - -#include "libmaildir/maildir.h" - -#include -#include - -#include -#include - -#include - -#include - -using namespace Akonadi; - -static Collection::List collectionsFromSpy( QSignalSpy *spy ) { - Collection::List collections; - - QListIterator > it( *spy ); - while( it.hasNext() ) { - const QList invocation = it.next(); - Q_ASSERT( invocation.count() == 1 ); - - collections << invocation.first().value(); - } - - return collections; -} - -static Item::List itemsFromSpy( QSignalSpy *spy ) { - Item::List items; - - QListIterator > it( *spy ); - while( it.hasNext() ) { - const QList invocation = it.next(); - Q_ASSERT( invocation.count() == 1 ); - - items << invocation.first().value(); - } - - return items; -} - -static bool fullEntryCompare( const KMBox::MBoxEntry &a, const KMBox::MBoxEntry &b ) -{ - return a.messageOffset() == b.messageOffset() && - a.separatorSize() == b.separatorSize() && - a.messageSize() == b.messageSize(); -} - -class ItemDeleteTest : public QObject -{ - Q_OBJECT - - public: - ItemDeleteTest() : QObject(), mStore( 0 ), mDir( 0 ) { - // for monitoring signals - qRegisterMetaType(); - qRegisterMetaType(); - } - - ~ItemDeleteTest() { - delete mStore; - delete mDir; - } - - private: - MixedMaildirStore *mStore; - KTempDir *mDir; - - private Q_SLOTS: - void init(); - void cleanup(); - void testMaildir(); - void testMBox(); - void testCachePreservation(); - void testExpectedFailure(); -}; - -void ItemDeleteTest::init() -{ - mStore = new MixedMaildirStore; - - mDir = new KTempDir; - QVERIFY( mDir->exists() ); -} - -void ItemDeleteTest::cleanup() -{ - delete mStore; - mStore = 0; - delete mDir; - mDir = 0; -} - -void ItemDeleteTest::testMaildir() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - - KPIM::Maildir topLevelMd( topDir.path(), true ); - KPIM::Maildir md1 = topLevelMd.subFolder( QLatin1String( "collection1" ) ); - QVERIFY( md1.isValid() ); - - QSet entrySet1 = QSet::fromList( md1.entryList() ); - QCOMPARE( (int)entrySet1.count(), 4 ); - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::ItemDeleteJob *job = 0; - QSet entrySet; - QSet delIdSet; - QString delId; - - // test deleting one message - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - Item item1; - item1.setMimeType( KMime::Message::mimeType() ); - item1.setId( KRandom::random() ); - item1.setRemoteId( entrySet1.values().first() ); - item1.setParentCollection( collection1 ); - - job = mStore->deleteItem( item1 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - Item item = job->item(); - QCOMPARE( item.id(), item1.id() ); - - entrySet = QSet::fromList( md1.entryList() ); - QCOMPARE( (int)entrySet.count(), 3 ); - - delIdSet = entrySet1.subtract( entrySet ); - QCOMPARE( (int)delIdSet.count(), 1 ); - - delId = delIdSet.values().first(); - QCOMPARE( delId, entrySet1.values().first() ); - QCOMPARE( delId, item.remoteId() ); - - // test failure of deleting again - job = mStore->deleteItem( item1 ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); -} - -void ItemDeleteTest::testMBox() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection1" ) ) ); - - QFileInfo fileInfo1( topDir.path(), QLatin1String( "collection1" ) ); - KMBox::MBox mbox1; - QVERIFY( mbox1.load( fileInfo1.absoluteFilePath() ) ); - KMBox::MBoxEntry::List entryList1 = mbox1.entries(); - QCOMPARE( (int)entryList1.count(), 4 ); - int size1 = fileInfo1.size(); - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::ItemDeleteJob *job = 0; - FileStore::ItemFetchJob *itemFetch = 0; - FileStore::StoreCompactJob *storeCompact = 0; - - Item::List items; - Collection::List collections; - KMBox::MBoxEntry::List entryList; - - QSignalSpy *collectionsSpy = 0; - QSignalSpy *itemsSpy = 0; - - QVariant var; - - // test deleting last item in mbox - // file stays untouched, message still accessible through MBox, but item gone - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - Item item4; - item4.setMimeType( KMime::Message::mimeType() ); - item4.setId( KRandom::random() ); - item4.setRemoteId( QString::number( entryList1.value( 3 ).messageOffset() ) ); - item4.setParentCollection( collection1 ); - - job = mStore->deleteItem( item4 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - Item item = job->item(); - QCOMPARE( item.id(), item4.id() ); - - fileInfo1.refresh(); - QCOMPARE( (int) fileInfo1.size(), size1 ); - QVERIFY( mbox1.load( fileInfo1.absoluteFilePath() ) ); - entryList = mbox1.entries(); - QCOMPARE( entryList.count(), entryList1.count() ); - QCOMPARE( entryList.value( 3 ).messageOffset(), entryList1.value( 3 ).messageOffset() ); - - var = job->property( "compactStore" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.type(), QVariant::Bool ); - QCOMPARE( var.toBool(), true ); - - itemFetch = mStore->fetchItems( collection1 ); - - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 3 ); - QCOMPARE( items.value( 0 ).remoteId(), QString::number( entryList1.value( 0 ).messageOffset() ) ); - QCOMPARE( items.value( 1 ).remoteId(), QString::number( entryList1.value( 1 ).messageOffset() ) ); - QCOMPARE( items.value( 2 ).remoteId(), QString::number( entryList1.value( 2 ).messageOffset() ) ); - - // test that the item is purged from the file on store compaction - // last item purging does not change any others - storeCompact = mStore->compactStore(); - - collectionsSpy = new QSignalSpy( storeCompact, SIGNAL(collectionsChanged(Akonadi::Collection::List)) ); - itemsSpy = new QSignalSpy( storeCompact, SIGNAL(itemsChanged(Akonadi::Item::List)) ); - - QVERIFY( storeCompact->exec() ); - QCOMPARE( storeCompact->error(), 0 ); - - collections = storeCompact->changedCollections(); - QCOMPARE( collections.count(), 0 ); - items = storeCompact->changedItems(); - QCOMPARE( items.count(), 0 ); - - QCOMPARE( collectionsFromSpy( collectionsSpy ), collections ); - QCOMPARE( itemsFromSpy( itemsSpy ), items ); - - fileInfo1.refresh(); - QVERIFY( fileInfo1.size() < size1 ); - size1 = fileInfo1.size(); - QVERIFY( mbox1.load( fileInfo1.absoluteFilePath() ) ); - entryList = mbox1.entries(); - entryList1.pop_back(); - QVERIFY( std::equal( entryList1.begin(), entryList1.end(), entryList.begin(), fullEntryCompare ) ); - - // test deleting item somewhere between first and last - // again, file stays untouched, message still accessible through MBox, but item gone - Item item2; - item2.setMimeType( KMime::Message::mimeType() ); - item2.setId( KRandom::random() ); - item2.setRemoteId( QString::number( entryList1.value( 1 ).messageOffset() ) ); - item2.setParentCollection( collection1 ); - - job = mStore->deleteItem( item2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - item = job->item(); - QCOMPARE( item.id(), item2.id() ); - - fileInfo1.refresh(); - QCOMPARE( (int) fileInfo1.size(), size1 ); - QVERIFY( mbox1.load( fileInfo1.absoluteFilePath() ) ); - entryList = mbox1.entries(); - QCOMPARE( entryList.count(), entryList1.count() ); - QCOMPARE( entryList.value( 1 ).messageOffset(), entryList1.value( 1 ).messageOffset() ); - - var = job->property( "compactStore" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.type(), QVariant::Bool ); - QCOMPARE( var.toBool(), true ); - - itemFetch = mStore->fetchItems( collection1 ); - - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 2 ); - QCOMPARE( items.value( 0 ).remoteId(), QString::number( entryList1.value( 0 ).messageOffset() ) ); - QCOMPARE( items.value( 1 ).remoteId(), QString::number( entryList1.value( 2 ).messageOffset() ) ); - - // test that the item is purged from the file on store compaction - // non-last item purging changes all items after it - storeCompact = mStore->compactStore(); - - collectionsSpy = new QSignalSpy( storeCompact, SIGNAL(collectionsChanged(Akonadi::Collection::List)) ); - itemsSpy = new QSignalSpy( storeCompact, SIGNAL(itemsChanged(Akonadi::Item::List)) ); - - QVERIFY( storeCompact->exec() ); - QCOMPARE( storeCompact->error(), 0 ); - - collections = storeCompact->changedCollections(); - QCOMPARE( collections.count(), 1 ); - items = storeCompact->changedItems(); - QCOMPARE( items.count(), 1 ); - - QCOMPARE( collectionsFromSpy( collectionsSpy ), collections ); - QCOMPARE( itemsFromSpy( itemsSpy ), items ); - - Item item3; - item3.setRemoteId( QString::number( entryList1.value( 2 ).messageOffset() ) ); - - item = items.first(); - QCOMPARE( item3.remoteId(), item.remoteId() ); - - QVERIFY( item.hasAttribute() ); - FileStore::EntityCompactChangeAttribute *attribute = - item.attribute(); - - QString newRemoteId = attribute->remoteId(); - QVERIFY( !newRemoteId.isEmpty() ); - - fileInfo1.refresh(); - QVERIFY( fileInfo1.size() < size1 ); - size1 = fileInfo1.size(); - QVERIFY( mbox1.load( fileInfo1.absoluteFilePath() ) ); - entryList = mbox1.entries(); - QCOMPARE( QString::number( entryList.value( 1 ).messageOffset() ), newRemoteId ); - - entryList1.removeAt( 1 ); - QCOMPARE( entryList1.count(), entryList.count() ); - QCOMPARE( QString::number( entryList1.value( 1 ).messageOffset() ), item3.remoteId() ); -} - -void ItemDeleteTest::testCachePreservation() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection2" ) ) ); - - KPIM::Maildir topLevelMd( topDir.path(), true ); - KPIM::Maildir md1 = topLevelMd.subFolder( QLatin1String( "collection1" ) ); - QVERIFY( md1.isValid() ); - - QSet entrySet1 = QSet::fromList( md1.entryList() ); - QCOMPARE( (int)entrySet1.count(), 4 ); - - QFileInfo fileInfo2( topDir.path(), QLatin1String( "collection2" ) ); - KMBox::MBox mbox2; - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - KMBox::MBoxEntry::List entryList2 = mbox2.entries(); - QCOMPARE( (int)entryList2.count(), 4 ); - - mStore->setPath( topDir.path() ); - - // common variables - const QVariant colListVar = QVariant::fromValue( Collection::List() ); - QVariant var; - Collection::List collections; - Item::List items; - QMap flagCounts; - - FileStore::ItemDeleteJob *job = 0; - FileStore::ItemFetchJob *itemFetch = 0; - - // test deleting from maildir - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - Item item1; - item1.setMimeType( KMime::Message::mimeType() ); - item1.setId( KRandom::random() ); - item1.setRemoteId( entrySet1.values().first() ); - item1.setParentCollection( collection1 ); - - job = mStore->deleteItem( item1 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - Item item = job->item(); - QCOMPARE( item.id(), item1.id() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection1 ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection1 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 3 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - // TODO since we don't know which message we've deleted, we can only check if some flags are present - int flagCountTotal = 0; - Q_FOREACH( int count, flagCounts ) { - flagCountTotal += count; - } - QVERIFY( flagCountTotal > 0 ); - flagCounts.clear(); - - // test deleting from mbox - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - Item item2; - item2.setMimeType( KMime::Message::mimeType() ); - item2.setId( KRandom::random() ); - item2.setRemoteId( QString::number( entryList2.value( 1 ).messageOffset() ) ); - item2.setParentCollection( collection2 ); - - job = mStore->deleteItem( item2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - item = job->item(); - QCOMPARE( item.id(), item2.id() ); - - // at this point no change has been written to disk yet, so index and mbox file are - // still in sync - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( !var.isValid() ); - - FileStore::StoreCompactJob *storeCompact = mStore->compactStore(); - - QVERIFY( storeCompact->exec() ); - QCOMPARE( storeCompact->error(), 0 ); - - // check for index preservation - var = storeCompact->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection2 ); - - // get the items and check the flags (see data/README) - itemFetch = mStore->fetchItems( collection2 ); - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - items = itemFetch->items(); - QCOMPARE( (int)items.count(), 3 ); - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - // we've deleted message 2, it flagged TODO and seen - QCOMPARE( flagCounts[ "\\SEEN" ], 1 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - flagCounts.clear(); -} - -void ItemDeleteTest::testExpectedFailure() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection2" ) ) ); - - KPIM::Maildir topLevelMd( topDir.path(), true ); - KPIM::Maildir md1 = topLevelMd.subFolder( QLatin1String( "collection1" ) ); - QVERIFY( md1.isValid() ); - - QSet entrySet1 = QSet::fromList( md1.entryList() ); - QCOMPARE( (int)entrySet1.count(), 4 ); - - QFileInfo fileInfo2( topDir.path(), QLatin1String( "collection2" ) ); - KMBox::MBox mbox2; - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - KMBox::MBoxEntry::List entryList2 = mbox2.entries(); - QCOMPARE( (int)entryList2.count(), 4 ); - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::ItemDeleteJob *job = 0; - FileStore::ItemFetchJob *itemFetch = 0; - FileStore::StoreCompactJob *storeCompact = 0; - - // test failure of fetching an item previously deleted from maildir - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - Item item1_1; - item1_1.setRemoteId( entrySet1.values().first() ); - item1_1.setParentCollection( collection1 ); - - job = mStore->deleteItem( item1_1 ); - - QVERIFY( job->exec() ); - - itemFetch = mStore->fetchItem( item1_1 ); - - QVERIFY( !itemFetch->exec() ); - QCOMPARE( itemFetch->error(), (int)FileStore::Job::InvalidJobContext ); - - // test failure of deleting an item from maildir again - job = mStore->deleteItem( item1_1 ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - // test failure of fetching an item previously deleted from mbox - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - Item item2_1; - item2_1.setRemoteId( QString::number( entryList2.value( 0 ).messageOffset() ) ); - item2_1.setParentCollection( collection2 ); - - job = mStore->deleteItem( item2_1 ); - - QVERIFY( job->exec() ); - - itemFetch = mStore->fetchItem( item2_1 ); - - QVERIFY( !itemFetch->exec() ); - QCOMPARE( itemFetch->error(), (int)FileStore::Job::InvalidJobContext ); - - // test failure of deleting an item from mbox again - job = mStore->deleteItem( item2_1 ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - // compact store and check that offset 0 is a valid remoteId again, but - // offset of other items (e.f. item 4) are no longer valid (moved to the front of the file) - storeCompact = mStore->compactStore(); - - QVERIFY( storeCompact->exec() ); - - itemFetch = mStore->fetchItem( item2_1 ); - - QVERIFY( itemFetch->exec() ); - - Item item4_1; - item4_1.setRemoteId( QString::number( entryList2.value( 3 ).messageOffset() ) ); - item4_1.setParentCollection( collection2 ); - - itemFetch = mStore->fetchItem( item4_1 ); - - QVERIFY( !itemFetch->exec() ); - QCOMPARE( itemFetch->error(), (int)FileStore::Job::InvalidJobContext ); -} - -QTEST_KDEMAIN( ItemDeleteTest, NoGUI ) - -#include "itemdeletetest.moc" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/itemfetchtest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/tests/itemfetchtest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/itemfetchtest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/itemfetchtest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1157 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" - -#include "testdatautil.h" - -#include "filestore/itemcreatejob.h" -#include "filestore/itemfetchjob.h" - -#include "libmaildir/maildir.h" - -#include -#include - -#include -#include - -#include -#include -#include - -#include - -#include - -using namespace Akonadi; -using namespace KMBox; - -static Item::List itemsFromSpy( QSignalSpy *spy ) { - Item::List items; - - QListIterator > it( *spy ); - while( it.hasNext() ) { - const QList invocation = it.next(); - Q_ASSERT( invocation.count() == 1 ); - - items << invocation.first().value(); - } - - return items; -} - -// copied from mail serializer plugin, Copyright (c) 2007 Till Adam -static QSet messageParts( const KMime::Message::Ptr &msgPtr ) -{ - QSet set; - // FIXME: we actually want "has any header" here, but the kmime api doesn't offer that yet - if ( msgPtr->hasContent() || msgPtr->hasHeader( "Message-ID" ) ) { - set << MessagePart::Envelope << MessagePart::Header; - if ( !msgPtr->body().isEmpty() || !msgPtr->contents().isEmpty() ) { - set << MessagePart::Body; - } - } - return set; -} - -// needed to sort maildir directory entries by filename which is their -// remoteId. tagListHash.contains tests below need sorting of entries. -static bool itemLessThanByRemoteId(const Item &item1, const Item &item2) -{ - return item1.remoteId() < item2.remoteId(); -} - -class ItemFetchTest : public QObject -{ - Q_OBJECT - - public: - ItemFetchTest() - : QObject(), mStore( 0 ), mDir( 0 ), mIndexFilePattern( QLatin1String( ".%1.index" ) ) { - // for monitoring signals - qRegisterMetaType(); - qRegisterMetaType(); - } - - ~ItemFetchTest() { - delete mStore; - delete mDir; - } - - QString indexFile( const QString &folder ) const { - return mIndexFilePattern.arg( folder ); - } - - QString indexFile( const QFileInfo &folderFileInfo ) const { - return QFileInfo( folderFileInfo.absolutePath(), - mIndexFilePattern.arg( folderFileInfo.fileName() ) ).absoluteFilePath(); - } - - private: - MixedMaildirStore *mStore; - KTempDir *mDir; - - const QString mIndexFilePattern; - - private Q_SLOTS: - void init(); - void cleanup(); - void testListingMaildir(); - void testListingMBox(); - void testSingleItemFetchMaildir(); - void testSingleItemFetchMBox(); -}; - -void ItemFetchTest::init() -{ - mStore = new MixedMaildirStore; - - mDir = new KTempDir; - QVERIFY( mDir->exists() ); -} - -void ItemFetchTest::cleanup() -{ - delete mStore; - mStore = 0; - delete mDir; - mDir = 0; -} - -void ItemFetchTest::testListingMaildir() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection2" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir-tagged" ), topDir.path(), QLatin1String( "collection3" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "dimap" ), topDir.path(), QLatin1String( "collection4" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir-tagged" ), topDir.path(), QLatin1String( "collection5" ) ) ); - - KPIM::Maildir topLevelMd( topDir.path(), true ); - - KPIM::Maildir md1 = topLevelMd.subFolder( QLatin1String( "collection1" ) ); - QSet entrySet1 = QSet::fromList( md1.entryList() ); - QCOMPARE( (int)entrySet1.count(), 4 ); - - QFileInfo indexFileInfo1( indexFile( QFileInfo( md1.path() ) ) ); - QVERIFY( QFile::remove( indexFileInfo1.absoluteFilePath() ) ); - - KPIM::Maildir md2 = topLevelMd.subFolder( QLatin1String( "collection2" ) ); - QSet entrySet2 = QSet::fromList( md2.entryList() ); - QCOMPARE( (int)entrySet2.count(), 4 ); - - KPIM::Maildir md3 = topLevelMd.subFolder( QLatin1String( "collection3" ) ); - QSet entrySet3 = QSet::fromList( md3.entryList() ); - QCOMPARE( (int)entrySet3.count(), 4 ); - - KPIM::Maildir md4 = topLevelMd.subFolder( QLatin1String( "collection4" ) ); - QSet entrySet4 = QSet::fromList( md4.entryList() ); - QCOMPARE( (int)entrySet4.count(), 4 ); - - KPIM::Maildir md5 = topLevelMd.subFolder( QLatin1String( "collection5" ) ); - QSet entrySet5 = QSet::fromList( md5.entryList() ); - QCOMPARE( (int)entrySet5.count(), 4 ); - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::ItemFetchJob *job = 0; - - QSignalSpy *spy = 0; - Item::List items; - - QHash uidHash; - const QVariant varUidHash = QVariant::fromValue< QHash >( uidHash ); - QHash tagListHash; - const QVariant varTagListHash = QVariant::fromValue< QHash >( tagListHash ); - QVariant var; - - QSet entrySet; - QMap flagCounts; - - // test listing maildir without index - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->fetchItems( collection1 ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 4 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - entrySet = entrySet1; - QVERIFY( entrySet.remove( items[ 0 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 1 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 2 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 3 ].remoteId() ) ); - - QCOMPARE( items[ 0 ].parentCollection(), collection1 ); - QCOMPARE( items[ 1 ].parentCollection(), collection1 ); - QCOMPARE( items[ 2 ].parentCollection(), collection1 ); - QCOMPARE( items[ 3 ].parentCollection(), collection1 ); - - QVERIFY( !items[ 0 ].hasPayload() ); - QVERIFY( !items[ 1 ].hasPayload() ); - QVERIFY( !items[ 2 ].hasPayload() ); - QVERIFY( !items[ 3 ].hasPayload() ); - - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - // no flags from maildir file name, no advanced flags without index - QCOMPARE( flagCounts.count(), 0 ); - QCOMPARE( flagCounts[ "\\SEEN" ], 0 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 0 ); - QCOMPARE( flagCounts[ "$TODO" ], 0 ); - flagCounts.clear(); - - var = job->property( "remoteIdToTagList" ); - QVERIFY( !var.isValid() ); - - // test listing empty mbox without index - Q_FOREACH( const QString &entry, entrySet1 ) { - QVERIFY( md1.removeEntry( entry ) ); - } - QCOMPARE( md1.entryList().count(), 0 ); - - job = mStore->fetchItems( collection1 ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 0 ); - QCOMPARE( spy->count(), 0 ); - - var = job->property( "remoteIdToTagList" ); - QVERIFY( !var.isValid() ); - - // test listing maildir with index - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->fetchItems( collection2 ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 4 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - entrySet = entrySet2; - QVERIFY( entrySet.remove( items[ 0 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 1 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 2 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 3 ].remoteId() ) ); - - QCOMPARE( items[ 0 ].parentCollection(), collection2 ); - QCOMPARE( items[ 1 ].parentCollection(), collection2 ); - QCOMPARE( items[ 2 ].parentCollection(), collection2 ); - QCOMPARE( items[ 3 ].parentCollection(), collection2 ); - - QVERIFY( !items[ 0 ].hasPayload() ); - QVERIFY( !items[ 1 ].hasPayload() ); - QVERIFY( !items[ 2 ].hasPayload() ); - QVERIFY( !items[ 3 ].hasPayload() ); - - // see data/README - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - var = job->property( "remoteIdToTagList" ); - QVERIFY( !var.isValid() ); - - // test listing empty maildir with index - Q_FOREACH( const QString &entry, entrySet2 ) { - QVERIFY( md2.removeEntry( entry ) ); - } - QCOMPARE( md2.entryList().count(), 0 ); - - job = mStore->fetchItems( collection2 ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 0 ); - QCOMPARE( spy->count(), 0 ); - - var = job->property( "remoteIdToTagList" ); - QVERIFY( !var.isValid() ); - - // test listing maildir with index which has tags - Collection collection3; - collection3.setName( QLatin1String( "collection3" ) ); - collection3.setRemoteId( QLatin1String( "collection3" ) ); - collection3.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->fetchItems( collection3 ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 4 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - entrySet = entrySet3; - QVERIFY( entrySet.remove( items[ 0 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 1 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 2 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 3 ].remoteId() ) ); - - QCOMPARE( items[ 0 ].parentCollection(), collection3 ); - QCOMPARE( items[ 1 ].parentCollection(), collection3 ); - QCOMPARE( items[ 2 ].parentCollection(), collection3 ); - QCOMPARE( items[ 3 ].parentCollection(), collection3 ); - - QVERIFY( !items[ 0 ].hasPayload() ); - QVERIFY( !items[ 1 ].hasPayload() ); - QVERIFY( !items[ 2 ].hasPayload() ); - QVERIFY( !items[ 3 ].hasPayload() ); - - // see data/README - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - - // 2x \SEEN flags: 2x from index, none from file name - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - var = job->property( "remoteIdToTagList" ); - QVERIFY( var.isValid() ); - - // tagListHash.contains tests below needs sorting of entries, - // but libmaildir does not sort for performance reasons. - // TODO: Check should not depend on any specific ordering. - qSort(items.begin(), items.end(), itemLessThanByRemoteId); - - tagListHash = var.value< QHash >(); - QCOMPARE( (int)tagListHash.count(), 3 ); - QVERIFY( !tagListHash.contains( items[ 0 ].remoteId() ) ); - QVERIFY( !tagListHash.value( items[ 1 ].remoteId() ).toString().isEmpty() ); - QVERIFY( !tagListHash.value( items[ 2 ].remoteId() ).toString().isEmpty() ); - QVERIFY( !tagListHash.value( items[ 3 ].remoteId() ).toString().isEmpty() ); - - // test listing maildir with index which contains IMAP UIDs (dimap cache directory) - Collection collection4; - collection4.setName( QLatin1String( "collection4" ) ); - collection4.setRemoteId( QLatin1String( "collection4" ) ); - collection4.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->fetchItems( collection4 ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 4 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - entrySet = entrySet4; - QVERIFY( entrySet.remove( items[ 0 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 1 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 2 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 3 ].remoteId() ) ); - - QCOMPARE( items[ 0 ].parentCollection(), collection4 ); - QCOMPARE( items[ 1 ].parentCollection(), collection4 ); - QCOMPARE( items[ 2 ].parentCollection(), collection4 ); - QCOMPARE( items[ 3 ].parentCollection(), collection4 ); - - QVERIFY( !items[ 0 ].hasPayload() ); - QVERIFY( !items[ 1 ].hasPayload() ); - QVERIFY( !items[ 2 ].hasPayload() ); - QVERIFY( !items[ 3 ].hasPayload() ); - - // see data/README - Q_FOREACH( const Item &item, items ) { - Q_FOREACH( const QByteArray &flag, item.flags() ) { - ++flagCounts[ flag ]; - } - } - QCOMPARE( flagCounts[ "\\SEEN" ], 2 ); - QCOMPARE( flagCounts[ "\\FLAGGED" ], 1 ); - QCOMPARE( flagCounts[ "$TODO" ], 1 ); - flagCounts.clear(); - - var = job->property( "remoteIdToTagList" ); - QVERIFY( !var.isValid() ); - - var = job->property( "remoteIdToIndexUid" ); - QVERIFY( var.isValid() ); - - uidHash = var.value< QHash >(); - QCOMPARE( (int)uidHash.count(), 4 ); - bool ok = false; - QVERIFY( !uidHash.value( items[ 0 ].remoteId() ).toString().toInt( &ok) >= 0 && ok ); - QVERIFY( !uidHash.value( items[ 1 ].remoteId() ).toString().toInt( &ok) >= 0 && ok ); - QVERIFY( !uidHash.value( items[ 2 ].remoteId() ).toString().toInt( &ok) >= 0 && ok ); - QVERIFY( !uidHash.value( items[ 3 ].remoteId() ).toString().toInt( &ok) >= 0 && ok ); - - // test listing maildir with index but newer modification date than index's one - const QByteArray data5 = md5.readEntry( entrySet5.values().first() ); - QVERIFY( !data5.isEmpty() ); - - QTest::qSleep( 1000 ); - - QString newRemoteId = md5.addEntry( data5 ); - QVERIFY( !newRemoteId.isEmpty() ); - - entrySet = QSet::fromList( md5.entryList() ); - entrySet.remove( newRemoteId ); - QCOMPARE( entrySet, entrySet5 ); - QFileInfo fileInfo5( md5.path(), QLatin1String( "new" ) ); - QFileInfo indexFileInfo5 = indexFile( QFileInfo( md5.path() ) ); - QVERIFY( fileInfo5.lastModified() > indexFileInfo5.lastModified() ); - - Collection collection5; - collection5.setName( QLatin1String( "collection5" ) ); - collection5.setRemoteId( QLatin1String( "collection5" ) ); - collection5.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->fetchItems( collection5 ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 5 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - entrySet = entrySet5; - entrySet << newRemoteId; - QVERIFY( entrySet.remove( items[ 0 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 1 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 2 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 3 ].remoteId() ) ); - QVERIFY( entrySet.remove( items[ 4 ].remoteId() ) ); - - QCOMPARE( items[ 0 ].parentCollection(), collection5 ); - QCOMPARE( items[ 1 ].parentCollection(), collection5 ); - QCOMPARE( items[ 2 ].parentCollection(), collection5 ); - QCOMPARE( items[ 3 ].parentCollection(), collection5 ); - QCOMPARE( items[ 4 ].parentCollection(), collection5 ); - - QVERIFY( !items[ 0 ].hasPayload() ); - QVERIFY( !items[ 1 ].hasPayload() ); - QVERIFY( !items[ 2 ].hasPayload() ); - QVERIFY( !items[ 3 ].hasPayload() ); - QVERIFY( !items[ 4 ].hasPayload() ); - - // not flags from index, no flags from file names - QCOMPARE( items[ 0 ].flags(), QSet() ); - QCOMPARE( items[ 1 ].flags(), QSet() ); - QCOMPARE( items[ 2 ].flags(), QSet() ); - QCOMPARE( items[ 3 ].flags(), QSet() ); - QCOMPARE( items[ 4 ].flags(), QSet() ); - - var = job->property( "remoteIdToTagList" ); - QVERIFY( !var.isValid() ); -} - -void ItemFetchTest::testListingMBox() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection2" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox-tagged" ), topDir.path(), QLatin1String( "collection3" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox-unpurged" ), topDir.path(), QLatin1String( "collection4" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox-tagged" ), topDir.path(), QLatin1String( "collection5" ) ) ); - - QFileInfo fileInfo1( topDir.path(), QLatin1String( "collection1" ) ); - MBox mbox1; - QVERIFY( mbox1.load( fileInfo1.absoluteFilePath() ) ); - MBoxEntry::List entryList1 = mbox1.entries(); - QCOMPARE( (int)entryList1.count(), 4 ); - - QFileInfo indexFileInfo1 = indexFile( fileInfo1 ); - QVERIFY( QFile::remove( indexFileInfo1.absoluteFilePath() ) ); - - QFileInfo fileInfo2( topDir.path(), QLatin1String( "collection2" ) ); - MBox mbox2; - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - MBoxEntry::List entryList2 = mbox2.entries(); - QCOMPARE( (int)entryList2.count(), 4 ); - - QFileInfo fileInfo3( topDir.path(), QLatin1String( "collection3" ) ); - MBox mbox3; - QVERIFY( mbox3.load( fileInfo3.absoluteFilePath() ) ); - MBoxEntry::List entryList3 = mbox3.entries(); - QCOMPARE( (int)entryList3.count(), 4 ); - - QFileInfo fileInfo4( topDir.path(), QLatin1String( "collection4" ) ); - MBox mbox4; - QVERIFY( mbox4.load( fileInfo4.absoluteFilePath() ) ); - MBoxEntry::List entryList4 = mbox4.entries(); - QCOMPARE( (int)entryList4.count(), 4 ); - - QFileInfo fileInfo5( topDir.path(), QLatin1String( "collection5" ) ); - MBox mbox5; - QVERIFY( mbox5.load( fileInfo5.absoluteFilePath() ) ); - MBoxEntry::List entryList5 = mbox5.entries(); - QCOMPARE( (int)entryList5.count(), 4 ); - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::ItemFetchJob *job = 0; - - QSignalSpy *spy = 0; - Item::List items; - - QHash tagListHash; - const QVariant varTagListHash = QVariant::fromValue< QHash >( tagListHash ); - QVariant var; - - // test listing mbox without index - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->fetchItems( collection1 ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 4 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - QCOMPARE( items[ 0 ].remoteId(), QString::number( entryList1[ 0 ].messageOffset() ) ); - QCOMPARE( items[ 1 ].remoteId(), QString::number( entryList1[ 1 ].messageOffset() ) ); - QCOMPARE( items[ 2 ].remoteId(), QString::number( entryList1[ 2 ].messageOffset() ) ); - QCOMPARE( items[ 3 ].remoteId(), QString::number( entryList1[ 3 ].messageOffset() ) ); - - QCOMPARE( items[ 0 ].parentCollection(), collection1 ); - QCOMPARE( items[ 1 ].parentCollection(), collection1 ); - QCOMPARE( items[ 2 ].parentCollection(), collection1 ); - QCOMPARE( items[ 3 ].parentCollection(), collection1 ); - - QVERIFY( !items[ 0 ].hasPayload() ); - QVERIFY( !items[ 1 ].hasPayload() ); - QVERIFY( !items[ 2 ].hasPayload() ); - QVERIFY( !items[ 3 ].hasPayload() ); - - QCOMPARE( items[ 0 ].flags(), QSet() ); - QCOMPARE( items[ 1 ].flags(), QSet() ); - QCOMPARE( items[ 2 ].flags(), QSet() ); - QCOMPARE( items[ 3 ].flags(), QSet() ); - - var = job->property( "remoteIdToTagList" ); - QVERIFY( !var.isValid() ); - - // test listing empty mbox without index - QFile file1( fileInfo1.absoluteFilePath() ); - QVERIFY( file1.open( QIODevice::WriteOnly | QIODevice::Truncate ) ); - file1.close(); - QCOMPARE( (int)file1.size(), 0 ); - - job = mStore->fetchItems( collection1 ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 0 ); - QCOMPARE( spy->count(), 0 ); - - var = job->property( "remoteIdToTagList" ); - QVERIFY( !var.isValid() ); - - // test listing mbox with index - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->fetchItems( collection2 ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 4 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - QCOMPARE( items[ 0 ].remoteId(), QString::number( entryList2[ 0 ].messageOffset() ) ); - QCOMPARE( items[ 1 ].remoteId(), QString::number( entryList2[ 1 ].messageOffset() ) ); - QCOMPARE( items[ 2 ].remoteId(), QString::number( entryList2[ 2 ].messageOffset() ) ); - QCOMPARE( items[ 3 ].remoteId(), QString::number( entryList2[ 3 ].messageOffset() ) ); - - QCOMPARE( items[ 0 ].parentCollection(), collection2 ); - QCOMPARE( items[ 1 ].parentCollection(), collection2 ); - QCOMPARE( items[ 2 ].parentCollection(), collection2 ); - QCOMPARE( items[ 3 ].parentCollection(), collection2 ); - - QVERIFY( !items[ 0 ].hasPayload() ); - QVERIFY( !items[ 1 ].hasPayload() ); - QVERIFY( !items[ 2 ].hasPayload() ); - QVERIFY( !items[ 3 ].hasPayload() ); - - // see data/README - QCOMPARE( items[ 0 ].flags(), QSet() ); - QCOMPARE( items[ 1 ].flags(), QSet() << "\\SEEN" << "$TODO" ); - QCOMPARE( items[ 2 ].flags(), QSet() ); - QCOMPARE( items[ 3 ].flags(), QSet() << "\\SEEN" << "\\FLAGGED" ); - - var = job->property( "remoteIdToTagList" ); - QVERIFY( !var.isValid() ); - - // test listing empty mbox with index - QFile file2( fileInfo2.absoluteFilePath() ); - QVERIFY( file2.open( QIODevice::WriteOnly | QIODevice::Truncate ) ); - file2.close(); - QCOMPARE( (int)file2.size(), 0 ); - - job = mStore->fetchItems( collection2 ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 0 ); - QCOMPARE( spy->count(), 0 ); - - var = job->property( "remoteIdToTagList" ); - QVERIFY( !var.isValid() ); - - // test listing mbox with index which has tags - Collection collection3; - collection3.setName( QLatin1String( "collection3" ) ); - collection3.setRemoteId( QLatin1String( "collection3" ) ); - collection3.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->fetchItems( collection3 ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 4 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - QCOMPARE( items[ 0 ].remoteId(), QString::number( entryList3[ 0 ].messageOffset() ) ); - QCOMPARE( items[ 1 ].remoteId(), QString::number( entryList3[ 1 ].messageOffset() ) ); - QCOMPARE( items[ 2 ].remoteId(), QString::number( entryList3[ 2 ].messageOffset() ) ); - QCOMPARE( items[ 3 ].remoteId(), QString::number( entryList3[ 3 ].messageOffset() ) ); - - QCOMPARE( items[ 0 ].parentCollection(), collection3 ); - QCOMPARE( items[ 1 ].parentCollection(), collection3 ); - QCOMPARE( items[ 2 ].parentCollection(), collection3 ); - QCOMPARE( items[ 3 ].parentCollection(), collection3 ); - - QVERIFY( !items[ 0 ].hasPayload() ); - QVERIFY( !items[ 1 ].hasPayload() ); - QVERIFY( !items[ 2 ].hasPayload() ); - QVERIFY( !items[ 3 ].hasPayload() ); - - // see data/README - QCOMPARE( items[ 0 ].flags(), QSet() ); - QCOMPARE( items[ 1 ].flags(), QSet() << "\\SEEN" << "$TODO" ); - QCOMPARE( items[ 2 ].flags(), QSet() ); - QCOMPARE( items[ 3 ].flags(), QSet() << "\\SEEN" << "\\FLAGGED" ); - - var = job->property( "remoteIdToTagList" ); - QVERIFY( var.isValid() ); - - tagListHash = var.value< QHash >(); - QCOMPARE( (int)tagListHash.count(), 3 ); - QVERIFY( !tagListHash.value( items[ 0 ].remoteId() ).toString().isEmpty() ); - QVERIFY( !tagListHash.contains( items[ 1 ].remoteId() ) ); - QVERIFY( !tagListHash.value( items[ 2 ].remoteId() ).toString().isEmpty() ); - QVERIFY( !tagListHash.value( items[ 3 ].remoteId() ).toString().isEmpty() ); - - // test listing mbox with index and unpurged messages (in mbox but not in index) - Collection collection4; - collection4.setName( QLatin1String( "collection4" ) ); - collection4.setRemoteId( QLatin1String( "collection4" ) ); - collection4.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->fetchItems( collection4 ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 4 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - QCOMPARE( items[ 0 ].remoteId(), QString::number( entryList4[ 0 ].messageOffset() ) ); - QCOMPARE( items[ 1 ].remoteId(), QString::number( entryList4[ 1 ].messageOffset() ) ); - QCOMPARE( items[ 2 ].remoteId(), QString::number( entryList4[ 2 ].messageOffset() ) ); - QCOMPARE( items[ 3 ].remoteId(), QString::number( entryList4[ 3 ].messageOffset() ) ); - - QCOMPARE( items[ 0 ].parentCollection(), collection4 ); - QCOMPARE( items[ 1 ].parentCollection(), collection4 ); - QCOMPARE( items[ 2 ].parentCollection(), collection4 ); - QCOMPARE( items[ 3 ].parentCollection(), collection4 ); - - QVERIFY( !items[ 0 ].hasPayload() ); - QVERIFY( !items[ 1 ].hasPayload() ); - QVERIFY( !items[ 2 ].hasPayload() ); - QVERIFY( !items[ 3 ].hasPayload() ); - - // see data/README - QCOMPARE( items[ 0 ].flags(), QSet() << "\\SEEN" ); - QCOMPARE( items[ 1 ].flags(), QSet() << "\\DELETED" ); - QCOMPARE( items[ 2 ].flags(), QSet() << "\\DELETED" ); - QCOMPARE( items[ 3 ].flags(), QSet() << "\\SEEN" ); - - var = job->property( "remoteIdToTagList" ); - QVERIFY( !var.isValid() ); - - // test listing mbox with index but newer modification date than index's one - QFile file5( fileInfo5.absoluteFilePath() ); - QVERIFY( file5.open( QIODevice::ReadOnly ) ); - const QByteArray data5 = file5.readAll(); - file5.close(); - - QTest::qSleep( 1000 ); - - QVERIFY( file5.open( QIODevice::WriteOnly ) ); - file5.write( data5 ); - file5.close(); - - QCOMPARE( file5.size(), fileInfo5.size() ); - fileInfo5.refresh(); - QFileInfo indexFileInfo5 = indexFile( fileInfo5 ); - QVERIFY( fileInfo5.lastModified() > indexFileInfo5.lastModified() ); - - Collection collection5; - collection5.setName( QLatin1String( "collection5" ) ); - collection5.setRemoteId( QLatin1String( "collection5" ) ); - collection5.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->fetchItems( collection5 ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 4 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - QCOMPARE( items[ 0 ].remoteId(), QString::number( entryList5[ 0 ].messageOffset() ) ); - QCOMPARE( items[ 1 ].remoteId(), QString::number( entryList5[ 1 ].messageOffset() ) ); - QCOMPARE( items[ 2 ].remoteId(), QString::number( entryList5[ 2 ].messageOffset() ) ); - QCOMPARE( items[ 3 ].remoteId(), QString::number( entryList5[ 3 ].messageOffset() ) ); - - QCOMPARE( items[ 0 ].parentCollection(), collection5 ); - QCOMPARE( items[ 1 ].parentCollection(), collection5 ); - QCOMPARE( items[ 2 ].parentCollection(), collection5 ); - QCOMPARE( items[ 3 ].parentCollection(), collection5 ); - - QVERIFY( !items[ 0 ].hasPayload() ); - QVERIFY( !items[ 1 ].hasPayload() ); - QVERIFY( !items[ 2 ].hasPayload() ); - QVERIFY( !items[ 3 ].hasPayload() ); - - QCOMPARE( items[ 0 ].flags(), QSet() ); - QCOMPARE( items[ 1 ].flags(), QSet() ); - QCOMPARE( items[ 2 ].flags(), QSet() ); - QCOMPARE( items[ 3 ].flags(), QSet() ); - - var = job->property( "remoteIdToTagList" ); - QVERIFY( !var.isValid() ); - - // test that a new message in an mbox with index it not marked as deleted - KMime::Message::Ptr msgPtr( new KMime::Message ); - msgPtr->subject()->from7BitString( "Test 5" ); - msgPtr->to()->from7BitString( "kevin.krammer@gmx.at" ); - msgPtr->assemble(); - - Item item3_5; - item3_5.setMimeType( KMime::Message::mimeType() ); - item3_5.setPayload( msgPtr ); - - FileStore::ItemCreateJob *itemCreate = mStore->createItem( item3_5, collection3 ); - QVERIFY( itemCreate->exec() ); - - item3_5 = itemCreate->item(); - QVERIFY( !item3_5.remoteId().isEmpty() ); - - job = mStore->fetchItems( collection3 ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 5 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - QCOMPARE( items[ 0 ].remoteId(), QString::number( entryList3[ 0 ].messageOffset() ) ); - QCOMPARE( items[ 1 ].remoteId(), QString::number( entryList3[ 1 ].messageOffset() ) ); - QCOMPARE( items[ 2 ].remoteId(), QString::number( entryList3[ 2 ].messageOffset() ) ); - QCOMPARE( items[ 3 ].remoteId(), QString::number( entryList3[ 3 ].messageOffset() ) ); - QCOMPARE( items[ 4 ].remoteId(), item3_5.remoteId() ); - - QCOMPARE( items[ 0 ].parentCollection(), collection3 ); - QCOMPARE( items[ 1 ].parentCollection(), collection3 ); - QCOMPARE( items[ 2 ].parentCollection(), collection3 ); - QCOMPARE( items[ 3 ].parentCollection(), collection3 ); - QCOMPARE( items[ 4 ].parentCollection(), collection3 ); - - QVERIFY( !items[ 0 ].hasPayload() ); - QVERIFY( !items[ 1 ].hasPayload() ); - QVERIFY( !items[ 2 ].hasPayload() ); - QVERIFY( !items[ 3 ].hasPayload() ); - QVERIFY( !items[ 4 ].hasPayload() ); - - // see data/README - QCOMPARE( items[ 0 ].flags(), QSet() ); - QCOMPARE( items[ 1 ].flags(), QSet() << "\\SEEN" << "$TODO" ); - QCOMPARE( items[ 2 ].flags(), QSet() ); - QCOMPARE( items[ 3 ].flags(), QSet() << "\\SEEN" << "\\FLAGGED" ); - QCOMPARE( items[ 4 ].flags(), QSet() ); - - var = job->property( "remoteIdToTagList" ); - QVERIFY( var.isValid() ); -} - -void ItemFetchTest::testSingleItemFetchMaildir() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - - KPIM::Maildir topLevelMd( topDir.path(), true ); - - KPIM::Maildir md1 = topLevelMd.subFolder( QLatin1String( "collection1" ) ); - QStringList entryList1 = md1.entryList(); - QCOMPARE( (int)entryList1.count(), 4 ); - - KRandomSequence randomSequence; - QStringList randomList1 = entryList1; - randomSequence.randomize( randomList1 ); - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::ItemFetchJob *job = 0; - - QSignalSpy *spy = 0; - Item::List items; - - // test fetching from maildir, headers only - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - Q_FOREACH( const QString &entry, randomList1 ) { - Item item1; - item1.setId( KRandom::random() ); - item1.setRemoteId( entry ); - item1.setParentCollection( collection1 ); - - job = mStore->fetchItem( item1 ); - job->fetchScope().fetchPayloadPart( MessagePart::Header ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 1 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - Item item = items.first(); - QCOMPARE( item, item1 ); - QVERIFY( item.hasPayload() ); - - KMime::Message::Ptr msgPtr = item.payload(); - QVERIFY( msgPtr != 0 ); - - const QSet parts = messageParts( msgPtr ); - QVERIFY( !parts.isEmpty() ); - QVERIFY( parts.contains( MessagePart::Header ) ); - QVERIFY( !parts.contains( MessagePart::Body ) ); - } - - // test fetching from maildir, including body - randomSequence.randomize( randomList1 ); - Q_FOREACH( const QString &entry, randomList1 ) { - Item item1; - item1.setId( KRandom::random() ); - item1.setRemoteId( entry ); - item1.setParentCollection( collection1 ); - - job = mStore->fetchItem( item1 ); - job->fetchScope().fetchPayloadPart( MessagePart::Header ); - job->fetchScope().fetchPayloadPart( MessagePart::Body ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 1 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - Item item = items.first(); - QCOMPARE( item, item1 ); - QVERIFY( item.hasPayload() ); - - KMime::Message::Ptr msgPtr = item.payload(); - QVERIFY( msgPtr != 0 ); - - const QSet parts = messageParts( msgPtr ); - QVERIFY( !parts.isEmpty() ); - QVERIFY( parts.contains( MessagePart::Header ) ); - QVERIFY( parts.contains( MessagePart::Body ) ); - } - - // test fetching from maildir, just specifying full payload - randomSequence.randomize( randomList1 ); - Q_FOREACH( const QString &entry, randomList1 ) { - Item item1; - item1.setId( KRandom::random() ); - item1.setRemoteId( entry ); - item1.setParentCollection( collection1 ); - - job = mStore->fetchItem( item1 ); - job->fetchScope().fetchFullPayload( true ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 1 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - Item item = items.first(); - QCOMPARE( item, item1 ); - QVERIFY( item.hasPayload() ); - - KMime::Message::Ptr msgPtr = item.payload(); - QVERIFY( msgPtr != 0 ); - - const QSet parts = messageParts( msgPtr ); - QVERIFY( !parts.isEmpty() ); - QVERIFY( parts.contains( MessagePart::Header ) ); - QVERIFY( parts.contains( MessagePart::Body ) ); - } -} - -void ItemFetchTest::testSingleItemFetchMBox() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection1" ) ) ); - // one message has no body - const QByteArray messageIdOfEmptyBodyMsg = "201007241551.37547.kevin.krammer@demo.kolab.org"; - - QFileInfo fileInfo1( topDir.path(), QLatin1String( "collection1" ) ); - MBox mbox1; - QVERIFY( mbox1.load( fileInfo1.absoluteFilePath() ) ); - MBoxEntry::List entryList1 = mbox1.entries(); - QCOMPARE( (int)entryList1.count(), 4 ); - - KRandomSequence randomSequence; - MBoxEntry::List randomList1 = entryList1; - randomSequence.randomize( randomList1 ); - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::ItemFetchJob *job = 0; - - QSignalSpy *spy = 0; - Item::List items; - - // test fetching from mbox, headers only - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - Q_FOREACH( const MBoxEntry &entry, randomList1 ) { - Item item1; - item1.setId( KRandom::random() ); - item1.setRemoteId( QString::number( entry.messageOffset() ) ); - item1.setParentCollection( collection1 ); - - job = mStore->fetchItem( item1 ); - job->fetchScope().fetchPayloadPart( MessagePart::Header ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 1 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - Item item = items.first(); - QCOMPARE( item, item1 ); - QVERIFY( item.hasPayload() ); - - KMime::Message::Ptr msgPtr = item.payload(); - QVERIFY( msgPtr != 0 ); - - const QSet parts = messageParts( msgPtr ); - QVERIFY( !parts.isEmpty() ); - QVERIFY( parts.contains( MessagePart::Header ) ); - QVERIFY( !parts.contains( MessagePart::Body ) ); - } - - // test fetching from mbox, including body - randomSequence.randomize( randomList1 ); - Q_FOREACH( const MBoxEntry &entry, randomList1 ) { - Item item1; - item1.setId( KRandom::random() ); - item1.setRemoteId( QString::number( entry.messageOffset() ) ); - item1.setParentCollection( collection1 ); - - job = mStore->fetchItem( item1 ); - job->fetchScope().fetchPayloadPart( MessagePart::Header ); - job->fetchScope().fetchPayloadPart( MessagePart::Body ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 1 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - Item item = items.first(); - QCOMPARE( item, item1 ); - QVERIFY( item.hasPayload() ); - - KMime::Message::Ptr msgPtr = item.payload(); - QVERIFY( msgPtr != 0 ); - - const QSet parts = messageParts( msgPtr ); - qDebug() << msgPtr->messageID()->identifier(); - QVERIFY( !parts.isEmpty() ); - QVERIFY( parts.contains( MessagePart::Header ) ); - if ( msgPtr->messageID()->identifier() == messageIdOfEmptyBodyMsg ) - QVERIFY( !parts.contains( MessagePart::Body ) ); - else - QVERIFY( parts.contains( MessagePart::Body ) ); - } - - // test fetching from mbox, just specifying full payload - randomSequence.randomize( randomList1 ); - Q_FOREACH( const MBoxEntry &entry, randomList1 ) { - Item item1; - item1.setId( KRandom::random() ); - item1.setRemoteId( QString::number( entry.messageOffset() ) ); - item1.setParentCollection( collection1 ); - - job = mStore->fetchItem( item1 ); - job->fetchScope().fetchFullPayload( true ); - - spy = new QSignalSpy( job, SIGNAL(itemsReceived(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - items = job->items(); - QCOMPARE( (int)items.count(), 1 ); - QCOMPARE( itemsFromSpy( spy ), items ); - - Item item = items.first(); - QCOMPARE( item, item1 ); - QVERIFY( item.hasPayload() ); - - KMime::Message::Ptr msgPtr = item.payload(); - QVERIFY( msgPtr != 0 ); - - const QSet parts = messageParts( msgPtr ); - QVERIFY( !parts.isEmpty() ); - QVERIFY( parts.contains( MessagePart::Header ) ); - if ( msgPtr->messageID()->identifier() == messageIdOfEmptyBodyMsg ) - QVERIFY( !parts.contains( MessagePart::Body ) ); - else - QVERIFY( parts.contains( MessagePart::Body ) ); - } -} - -QTEST_KDEMAIN( ItemFetchTest, NoGUI ) - -#include "itemfetchtest.moc" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/itemmodifytest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/tests/itemmodifytest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/itemmodifytest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/itemmodifytest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,670 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.com - Copyright (C) 2011 Kevin Krammer, kevin.krammer@gmx.at - - 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 "mixedmaildirstore.h" - -#include "testdatautil.h" - -#include "filestore/itemfetchjob.h" -#include "filestore/itemmodifyjob.h" -#include "filestore/storecompactjob.h" - -#include "libmaildir/maildir.h" - -#include -#include - -#include -#include - -#include -#include - -#include - -#include - -using namespace Akonadi; -using namespace KMBox; - -static bool fullEntryCompare( const MBoxEntry &a, const MBoxEntry &b ) -{ - return a.messageOffset() == b.messageOffset() && - a.separatorSize() == b.separatorSize() && - a.messageSize() == b.messageSize(); -} - -class ItemModifyTest : public QObject -{ - Q_OBJECT - - public: - ItemModifyTest() - : QObject(), mStore( 0 ), mDir( 0 ) {} - - ~ItemModifyTest() { - delete mStore; - delete mDir; - } - - private: - MixedMaildirStore *mStore; - KTempDir *mDir; - - private Q_SLOTS: - void init(); - void cleanup(); - void testExpectedFail(); - void testIgnorePayload(); - void testModifyPayload(); - void testModifyFlags(); - void testModifyFlagsAndPayload(); -}; - -void ItemModifyTest::init() -{ - mStore = new MixedMaildirStore; - - mDir = new KTempDir; - QVERIFY( mDir->exists() ); -} - -void ItemModifyTest::cleanup() -{ - delete mStore; - mStore = 0; - delete mDir; - mDir = 0; -} - -void ItemModifyTest::testExpectedFail() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection2" ) ) ); - - KPIM::Maildir topLevelMd( topDir.path(), true ); - - KPIM::Maildir md1 = topLevelMd.subFolder( QLatin1String( "collection1" ) ); - QSet entrySet1 = QSet::fromList( md1.entryList() ); - QCOMPARE( (int)entrySet1.count(), 4 ); - - QFileInfo fileInfo2( topDir.path(), QLatin1String( "collection2" ) ); - MBox mbox2; - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - MBoxEntry::List entryList2 = mbox2.entries(); - QCOMPARE( (int)entryList2.count(), 4 ); - - QSet entrySet2; - Q_FOREACH( const MBoxEntry &entry, entryList2 ) { - entrySet2 << entry.messageOffset(); - } - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::ItemModifyJob *job = 0; - - // test failure of modifying a non-existant maildir entry - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - QString remoteId1; - do { - remoteId1 = KRandom::randomString( 20 ); - } while ( entrySet1.contains( remoteId1 ) ); - - KMime::Message::Ptr msgPtr( new KMime::Message ); - - Item item1; - item1.setMimeType( KMime::Message::mimeType() ); - item1.setRemoteId( remoteId1 ); - item1.setParentCollection( collection1 ); - item1.setPayload( msgPtr ); - - job = mStore->modifyItem( item1 ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - QSet entrySet = QSet::fromList( md1.entryList() ); - QCOMPARE( entrySet, entrySet1 ); - - // test failure of modifying a non-existant mbox entry - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - qint64 remoteId2; - do { - remoteId2 = KRandom::random(); - } while ( entrySet2.contains( remoteId2 ) ); - - Item item2; - item2.setMimeType( KMime::Message::mimeType() ); - item2.setRemoteId( QString::number( remoteId2 ) ); - item2.setParentCollection( collection2 ); - item2.setPayload( msgPtr ); - - job = mStore->modifyItem( item2 ); - - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - QVERIFY( mbox2.load( mbox2.fileName() ) ); - MBoxEntry::List entryList = mbox2.entries(); - QVERIFY( std::equal( entryList.begin(), entryList.end(), entryList2.begin(), fullEntryCompare ) ); -} - -void ItemModifyTest::testIgnorePayload() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection2" ) ) ); - - KPIM::Maildir topLevelMd( topDir.path(), true ); - - KPIM::Maildir md1 = topLevelMd.subFolder( QLatin1String( "collection1" ) ); - QStringList entryList1 = md1.entryList(); - QCOMPARE( (int)entryList1.count(), 4 ); - - QFileInfo fileInfo2( topDir.path(), QLatin1String( "collection2" ) ); - MBox mbox2; - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - MBoxEntry::List entryList2 = mbox2.entries(); - QCOMPARE( (int)entryList2.count(), 4 ); - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::ItemModifyJob *job = 0; - - // test failure of modifying a non-existant maildir entry - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - const QByteArray data1 = md1.readEntry( entryList1.first() ); - - KMime::Message::Ptr msgPtr( new KMime::Message ); - msgPtr->subject()->from7BitString( "Modify Test" ); - msgPtr->assemble(); - - Item item1; - item1.setMimeType( KMime::Message::mimeType() ); - item1.setRemoteId( entryList1.first() ); - item1.setParentCollection( collection1 ); - item1.setPayload( msgPtr ); - - job = mStore->modifyItem( item1 ); - job->setIgnorePayload( true ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - QCOMPARE( md1.entryList(), entryList1 ); - QCOMPARE( md1.readEntry( entryList1.first() ), data1 ); - - // test failure of modifying a non-existant mbox entry - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - const QByteArray data2 = mbox2.readRawMessage( MBoxEntry( 0 ) ); - - Item item2; - item2.setMimeType( KMime::Message::mimeType() ); - item2.setRemoteId( QLatin1String( "0" ) ); - item2.setParentCollection( collection2 ); - item2.setPayload( msgPtr ); - - job = mStore->modifyItem( item2 ); - job->setIgnorePayload( true ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - QVERIFY( mbox2.load( mbox2.fileName() ) ); - QCOMPARE( mbox2.entries(), entryList2 ); - QCOMPARE( mbox2.readRawMessage( MBoxEntry( 0 ) ), data2 ); -} - -void ItemModifyTest::testModifyPayload() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection2" ) ) ); - - KPIM::Maildir topLevelMd( topDir.path(), true ); - - KPIM::Maildir md1 = topLevelMd.subFolder( QLatin1String( "collection1" ) ); - QStringList entryList1 = md1.entryList(); - QCOMPARE( (int)entryList1.count(), 4 ); - - QFileInfo fileInfo2( topDir.path(), QLatin1String( "collection2" ) ); - MBox mbox2; - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - MBoxEntry::List entryList2 = mbox2.entries(); - QCOMPARE( (int)entryList2.count(), 4 ); - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::ItemModifyJob *job = 0; - - const QVariant colListVar = QVariant::fromValue( Collection::List() ); - QVariant var; - Collection::List collections; - - // test modifying a maildir entry's header - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - const QByteArray data1 = md1.readEntry( entryList1.first() ); - - KMime::Message::Ptr msgPtr( new KMime::Message ); - msgPtr->setContent( KMime::CRLFtoLF( data1 ) ); - msgPtr->subject()->from7BitString( "Modify Test" ); - msgPtr->assemble(); - - Item item1; - item1.setMimeType( KMime::Message::mimeType() ); - item1.setRemoteId( entryList1.first() ); - item1.setParentCollection( collection1 ); - item1.setPayload( msgPtr ); - - job = mStore->modifyItem( item1 ); - // changing subject, so indicate a header change - job->setParts( QSet() << QByteArray( "PLD:" ) + MessagePart::Header ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - QCOMPARE( md1.entryList(), entryList1 ); - - QCOMPARE( md1.readEntry( entryList1.first() ).size(), - msgPtr->encodedContent().size() ); - QCOMPARE( md1.readEntry( entryList1.first() ), msgPtr->encodedContent() ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection1 ); - - // test modifying an mbox entry's header - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - const QByteArray data2 = mbox2.readRawMessage( MBoxEntry( 0 ) ); - - msgPtr->setContent( KMime::CRLFtoLF( data2 ) ); - msgPtr->subject()->from7BitString( "Modify Test" ); - msgPtr->assemble(); - - Item item2; - item2.setMimeType( KMime::Message::mimeType() ); - item2.setRemoteId( QLatin1String( "0" ) ); - item2.setParentCollection( collection2 ); - item2.setPayload( msgPtr ); - - job = mStore->modifyItem( item2 ); - // changing subject, so indicate a header change - job->setParts( QSet() << QByteArray( "PLD:" ) + MessagePart::Header ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - Item item = job->item(); - - QVERIFY( mbox2.load( mbox2.fileName() ) ); - MBoxEntry::List entryList = mbox2.entries(); - QCOMPARE( (int)entryList.count(), 5 ); // mbox file not purged yet - QCOMPARE( entryList.last().messageOffset(), item.remoteId().toULongLong() ); - - var = job->property( "compactStore" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.type(), QVariant::Bool ); - QCOMPARE( var.toBool(), true ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection2 ); - - FileStore::ItemFetchJob *itemFetch = mStore->fetchItem( item2 ); - QVERIFY( !itemFetch->exec() ); // item at old offset gone - - FileStore::StoreCompactJob *storeCompact = mStore->compactStore(); - QVERIFY( storeCompact->exec() ); - - QVERIFY( mbox2.load( mbox2.fileName() ) ); - entryList = mbox2.entries(); - QCOMPARE( (int)entryList.count(), 4 ); - - QCOMPARE( mbox2.readRawMessage( entryList.last() ), msgPtr->encodedContent() ); -} - -void ItemModifyTest::testModifyFlags() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection2" ) ) ); - - KPIM::Maildir topLevelMd( topDir.path(), true ); - - KPIM::Maildir md1 = topLevelMd.subFolder( QLatin1String( "collection1" ) ); - QStringList entryList1 = md1.entryList(); - QCOMPARE( (int)entryList1.count(), 4 ); - - QFileInfo fileInfo2( topDir.path(), QLatin1String( "collection2" ) ); - MBox mbox2; - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - MBoxEntry::List entryList2 = mbox2.entries(); - QCOMPARE( (int)entryList2.count(), 4 ); - - QCryptographicHash cryptoHash( QCryptographicHash::Sha1 ); - - QFile file2( fileInfo2.absoluteFilePath() ); - QVERIFY( file2.open( QIODevice::ReadOnly ) ); - cryptoHash.addData( file2.readAll() ); - const QByteArray mbox2Sha1 = cryptoHash.result(); - - file2.close(); - cryptoHash.reset(); - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::ItemModifyJob *job = 0; - - const QVariant colListVar = QVariant::fromValue( Collection::List() ); - QVariant var; - Collection::List collections; - KMime::Message::Ptr msgPtr( new KMime::Message ); - - // test modifying a flag of a maildir items changes the entry name but not the - // message contents - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - // check that the \SEEN flag is not set yet - QVERIFY( !md1.readEntryFlags( entryList1.first() ).contains( "\\SEEN" ) ); - - const QByteArray data1 = md1.readEntry( entryList1.first() ); - - msgPtr->setContent( KMime::CRLFtoLF( data1 ) ); - msgPtr->subject()->from7BitString( "Modify Test" ); - msgPtr->assemble(); - - Item item1; - item1.setMimeType( KMime::Message::mimeType() ); - item1.setRemoteId( entryList1.first() ); - item1.setParentCollection( collection1 ); - item1.setPayload( msgPtr ); - item1.setFlag( "\\SEEN" ); - - job = mStore->modifyItem( item1 ); - // setting \SEEN, so indicate a flags change - job->setParts( QSet() << "FLAGS" ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - Item item = job->item(); - - // returned item should contain the change - QVERIFY( item.flags().contains( "\\SEEN" ) ); - - // remote ID has changed - QVERIFY( item.remoteId() != entryList1.first() ); - QVERIFY( !md1.entryList().contains( entryList1.first() ) ); - - // no change in number of entries, one difference - QStringList entryList3 = md1.entryList(); - QCOMPARE( entryList3.count(), entryList1.count() ); - Q_FOREACH( const QString &oldEntry, entryList1 ) { - entryList3.removeAll( oldEntry ); - } - QCOMPARE( entryList3.count(), 1 ); - - // no change to data - QCOMPARE( md1.readEntry( entryList3.first() ), data1 ); - - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection1 ); - - // fetch new item, check flag - item1 = Item(); - item1.setMimeType( KMime::Message::mimeType() ); - item1.setRemoteId( entryList3.first() ); - item1.setParentCollection( collection1 ); - - FileStore::ItemFetchJob *itemFetch = mStore->fetchItem( item1 ); - - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - QCOMPARE( itemFetch->items().count(), 1 ); - QEXPECT_FAIL( "", "ItemFetch handling needs to be fixed to also fetch flags", Continue ); - QVERIFY( itemFetch->items()[ 0 ].flags().contains( "\\SEEN" ) ); - - // test modifying flags of an mbox item "succeeds" (no error) but does not change - // anything in store or on disk - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - const QByteArray data2 = mbox2.readRawMessage( MBoxEntry( 0 ) ); - - msgPtr->setContent( KMime::CRLFtoLF( data2 ) ); - msgPtr->subject()->from7BitString( "Modify Test" ); - msgPtr->assemble(); - - Item item2; - item2.setMimeType( KMime::Message::mimeType() ); - item2.setRemoteId( QLatin1String( "0" ) ); - item2.setParentCollection( collection2 ); - item2.setPayload( msgPtr ); - item2.setFlag( "\\SEEN" ); - - job = mStore->modifyItem( item2 ); - // setting \SEEN, so indicate a flags change - job->setParts( QSet() << "FLAGS" ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - item = job->item(); - - // returned item should contain the change - QVERIFY( item.flags().contains( "\\SEEN" ) ); - - // mbox not changed - QVERIFY( mbox2.load( mbox2.fileName() ) ); - MBoxEntry::List entryList = mbox2.entries(); - QCOMPARE( (int)entryList.count(), 4 ); - - var = job->property( "compactStore" ); - QVERIFY( !var.isValid() ); - - // file not modified - QVERIFY( file2.open( QIODevice::ReadOnly ) ); - cryptoHash.addData( file2.readAll() ); - QCOMPARE( cryptoHash.result(), mbox2Sha1 ); - - file2.close(); - cryptoHash.reset(); - - // check index preservation is not triggered - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( !var.isValid() ); - -} - - -void ItemModifyTest::testModifyFlagsAndPayload() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection2" ) ) ); - - KPIM::Maildir topLevelMd( topDir.path(), true ); - - KPIM::Maildir md1 = topLevelMd.subFolder( QLatin1String( "collection1" ) ); - QStringList entryList1 = md1.entryList(); - QCOMPARE( (int)entryList1.count(), 4 ); - - QFileInfo fileInfo2( topDir.path(), QLatin1String( "collection2" ) ); - MBox mbox2; - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - MBoxEntry::List entryList2 = mbox2.entries(); - QCOMPARE( (int)entryList2.count(), 4 ); - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::ItemModifyJob *job = 0; - - const QVariant colListVar = QVariant::fromValue( Collection::List() ); - QVariant var; - Collection::List collections; - KMime::Message::Ptr msgPtr( new KMime::Message ); - - // test modifying a flag of a maildir items changes the entry name but not the - // message contents - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - // check that the \SEEN flag is not set yet - QVERIFY( !md1.readEntryFlags( entryList1.first() ).contains( "\\SEEN" ) ); - - const QByteArray data1 = md1.readEntry( entryList1.first() ); - - msgPtr->setContent( KMime::CRLFtoLF( data1 ) ); - msgPtr->subject()->from7BitString( "Modify Test" ); - msgPtr->assemble(); - - Item item1; - item1.setMimeType( KMime::Message::mimeType() ); - item1.setRemoteId( entryList1.first() ); - item1.setParentCollection( collection1 ); - item1.setPayload( msgPtr ); - item1.setFlag( "\\SEEN" ); - - job = mStore->modifyItem( item1 ); - // setting \SEEN so indicate a flags change and - // setting new subject so indicate a payload change - job->setParts( QSet() << "FLAGS" - << QByteArray( "PLD:" ) + MessagePart::Header ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - Item item = job->item(); - - // returned item should contain the change - QVERIFY( item.flags().contains( "\\SEEN" ) ); - - // remote ID has changed - QVERIFY( item.remoteId() != entryList1.first() ); - QVERIFY( !md1.entryList().contains( entryList1.first() ) ); - - // no change in number of entries, one difference - QStringList entryList3 = md1.entryList(); - QCOMPARE( entryList3.count(), entryList1.count() ); - Q_FOREACH( const QString &oldEntry, entryList1 ) { - entryList3.removeAll( oldEntry ); - } - QCOMPARE( entryList3.count(), 1 ); - - // data changed - QCOMPARE( md1.readEntry( entryList3.first() ), msgPtr->encodedContent() ); - - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection1 ); - - // fetch new item, check flag - item1 = Item(); - item1.setMimeType( KMime::Message::mimeType() ); - item1.setRemoteId( entryList3.first() ); - item1.setParentCollection( collection1 ); - - FileStore::ItemFetchJob *itemFetch = mStore->fetchItem( item1 ); - itemFetch->fetchScope().fetchFullPayload(); - - QVERIFY( itemFetch->exec() ); - QCOMPARE( itemFetch->error(), 0 ); - - QCOMPARE( itemFetch->items().count(), 1 ); - Item fetchedItem = itemFetch->items().first(); - QEXPECT_FAIL( "", "ItemFetch handling needs to be fixed to also fetch flags", Continue ); - QVERIFY( fetchedItem.flags().contains( "\\SEEN" ) ); - - QVERIFY( fetchedItem.hasPayload() ); - KMime::Message::Ptr fetchedMsgPtr = fetchedItem.payload(); - QCOMPARE( msgPtr->encodedContent(), fetchedMsgPtr->encodedContent() ); - - - // TODO test for mbox. -} - -QTEST_KDEMAIN( ItemModifyTest, NoGUI ) - -#include "itemmodifytest.moc" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/itemmovetest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/tests/itemmovetest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/itemmovetest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/itemmovetest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,673 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" - -#include "testdatautil.h" - -#include "filestore/entitycompactchangeattribute.h" -#include "filestore/itemfetchjob.h" -#include "filestore/itemmovejob.h" -#include "filestore/storecompactjob.h" - -#include "libmaildir/maildir.h" - -#include -#include - -#include -#include - -#include - -#include - -using namespace Akonadi; -using namespace KMBox; - -static bool fullEntryCompare( const MBoxEntry &a, const MBoxEntry &b ) -{ - return a.messageOffset() == b.messageOffset() && - a.separatorSize() == b.separatorSize() && - a.messageSize() == b.messageSize(); -} - -static quint64 changedOffset( const Item &item ) { - Q_ASSERT( item.hasAttribute() ); - - const QString remoteId = item.attribute()->remoteId(); - Q_ASSERT( !remoteId.isEmpty() ); - - bool ok = false; - const quint64 result = remoteId.toULongLong( &ok ); - Q_ASSERT( ok ); - - return result; -} - -class ItemMoveTest : public QObject -{ - Q_OBJECT - - public: - ItemMoveTest() - : QObject(), mStore( 0 ), mDir( 0 ) {} - - ~ItemMoveTest() { - delete mStore; - delete mDir; - } - - private: - MixedMaildirStore *mStore; - KTempDir *mDir; - - private Q_SLOTS: - void init(); - void cleanup(); - void testExpectedFail(); - void testMaildirItem(); - void testMBoxItem(); -}; - -void ItemMoveTest::init() -{ - mStore = new MixedMaildirStore; - - mDir = new KTempDir; - QVERIFY( mDir->exists() ); -} - -void ItemMoveTest::cleanup() -{ - delete mStore; - mStore = 0; - delete mDir; - mDir = 0; -} - -void ItemMoveTest::testExpectedFail() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection2" ) ) ); - - KPIM::Maildir topLevelMd( topDir.path(), true ); - - KPIM::Maildir md1 = topLevelMd.subFolder( QLatin1String( "collection1" ) ); - QSet entrySet1 = QSet::fromList( md1.entryList() ); - QCOMPARE( (int)entrySet1.count(), 4 ); - - QFileInfo fileInfo2( topDir.path(), QLatin1String( "collection2" ) ); - MBox mbox2; - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - MBoxEntry::List entryList2 = mbox2.entries(); - QCOMPARE( (int)entryList2.count(), 4 ); - - QSet entrySet2; - Q_FOREACH( const MBoxEntry &entry, entryList2 ) { - entrySet2 << entry.messageOffset(); - } - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::ItemMoveJob *job = 0; - - // test failure of moving from a non-existant collection - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - Collection collection3; - collection3.setName( QLatin1String( "collection3" ) ); - collection3.setRemoteId( QLatin1String( "collection3" ) ); - collection3.setParentCollection( mStore->topLevelCollection() ); - - Item item3; - item3.setRemoteId( QLatin1String( "item3" ) ); - item3.setParentCollection( collection3 ); - - job = mStore->moveItem( item3, collection1 ); - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - QCOMPARE( QSet::fromList( md1.entryList() ), entrySet1 ); - - // test failure of moving from maildir to non-existant collection - Item item1; - item1.setId( KRandom::random() ); - item1.setRemoteId( entrySet1.values().first() ); - item1.setParentCollection( collection1 ); - - job = mStore->moveItem( item1, collection3 ); - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - QCOMPARE( QSet::fromList( md1.entryList() ), entrySet1 ); - - // test failure of moving from mbox to non-existant collection - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - Item item2; - item2.setId( KRandom::random() ); - item2.setRemoteId( QLatin1String( "0" ) ); - item2.setParentCollection( collection2 ); - - job = mStore->moveItem( item1, collection3 ); - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - MBoxEntry::List tmpEntryList = mbox2.entries(); - QVERIFY( std::equal( tmpEntryList.begin(), tmpEntryList.end(), entryList2.begin(), fullEntryCompare ) ); - - // test failure of moving from maildir to top level collection - job = mStore->moveItem( item1, mStore->topLevelCollection() ); - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - QCOMPARE( QSet::fromList( md1.entryList() ), entrySet1 ); - - // test failure of moving from mbox to top level collection - job = mStore->moveItem( item1, mStore->topLevelCollection() ); - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - tmpEntryList = mbox2.entries(); - QVERIFY( std::equal( tmpEntryList.begin(), tmpEntryList.end(), entryList2.begin(), fullEntryCompare ) ); - - // test failure of moving a non-existant maildir entry - QString remoteId1; - do { - remoteId1 = KRandom::randomString( 20 ); - } while ( entrySet1.contains( remoteId1 ) ); - - item1.setRemoteId( remoteId1 ); - - job = mStore->moveItem( item1, collection2 ); - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - QCOMPARE( QSet::fromList( md1.entryList() ), entrySet1 ); - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - tmpEntryList = mbox2.entries(); - QVERIFY( std::equal( tmpEntryList.begin(), tmpEntryList.end(), entryList2.begin(), fullEntryCompare ) ); - - // test failure of moving a non-existant mbox entry - quint64 remoteId2; - do { - remoteId2 = KRandom::random(); - } while ( entrySet2.contains( remoteId2 ) ); - - item2.setRemoteId( QString::number( remoteId2 ) ); - - job = mStore->moveItem( item2, collection1 ); - QVERIFY( !job->exec() ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - - QCOMPARE( QSet::fromList( md1.entryList() ), entrySet1 ); - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - tmpEntryList = mbox2.entries(); - QVERIFY( std::equal( tmpEntryList.begin(), tmpEntryList.end(), entryList2.begin(), fullEntryCompare ) ); -} - -void ItemMoveTest::testMaildirItem() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection2" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection5" ) ) ); - - KPIM::Maildir topLevelMd( topDir.path(), true ); - - KPIM::Maildir md1 = topLevelMd.subFolder( QLatin1String( "collection1" ) ); - QSet entrySet1 = QSet::fromList( md1.entryList() ); - QCOMPARE( (int)entrySet1.count(), 4 ); - - QFileInfo fileInfo2( topDir.path(), QLatin1String( "collection2" ) ); - MBox mbox2; - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - MBoxEntry::List entryList2 = mbox2.entries(); - QCOMPARE( (int)entryList2.count(), 4 ); - - KPIM::Maildir md3( topLevelMd.addSubFolder( QLatin1String( "collection3" ) ), false ); - QVERIFY( md3.isValid() ); - QSet entrySet3 = QSet::fromList( md3.entryList() ); - QCOMPARE( (int)entrySet3.count(), 0 ); - - QFileInfo fileInfo4( topDir.path(), QLatin1String( "collection4" ) ); - QFile file4( fileInfo4.absoluteFilePath() ); - QVERIFY( file4.open( QIODevice::WriteOnly ) ); - file4.close(); - fileInfo4.refresh(); - QVERIFY( fileInfo4.exists() ); - MBox mbox4; - QVERIFY( mbox4.load( fileInfo4.absoluteFilePath() ) ); - MBoxEntry::List entryList4 = mbox4.entries(); - QCOMPARE( (int)entryList4.count(), 0 ); - - KPIM::Maildir md5 = topLevelMd.subFolder( QLatin1String( "collection5" ) ); - QSet entrySet5 = QSet::fromList( md5.entryList() ); - QCOMPARE( (int)entrySet5.count(), 4 ); - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::ItemMoveJob *job = 0; - - const QVariant colListVar = QVariant::fromValue( Collection::List() ); - QVariant var; - Collection::List collections; - Item movedItem; - MBoxEntry::List entryList; - - // test moving to an empty maildir - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - Collection collection3; - collection3.setName( QLatin1String( "collection3" ) ); - collection3.setRemoteId( QLatin1String( "collection3" ) ); - collection3.setParentCollection( mStore->topLevelCollection() ); - - Item item1; - item1.setId( KRandom::random() ); - item1.setRemoteId( entrySet1.values().first() ); - item1.setParentCollection( collection1 ); - - job = mStore->moveItem( item1, collection3 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - movedItem = job->item(); - QCOMPARE( movedItem.id(), item1.id() ); - QCOMPARE( movedItem.parentCollection(), collection3 ); - - entrySet3 << movedItem.remoteId(); - QCOMPARE( QSet::fromList( md3.entryList() ), entrySet3 ); - entrySet1.remove( item1.remoteId() ); - QCOMPARE( QSet::fromList( md1.entryList() ), entrySet1 ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection1 ); - - // test moving to a non empty maildir - item1.setRemoteId( entrySet1.values().first() ); - - Collection collection5; - collection5.setName( QLatin1String( "collection5" ) ); - collection5.setRemoteId( QLatin1String( "collection5" ) ); - collection5.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->moveItem( item1, collection5 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - movedItem = job->item(); - QCOMPARE( movedItem.id(), item1.id() ); - QCOMPARE( movedItem.parentCollection(), collection5 ); - - entrySet5 << movedItem.remoteId(); - QCOMPARE( QSet::fromList( md5.entryList() ), entrySet5 ); - entrySet1.remove( item1.remoteId() ); - QCOMPARE( QSet::fromList( md1.entryList() ), entrySet1 ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 2 ); - QCOMPARE( collections, Collection::List() << collection1 << collection5 ); - - // test moving to an empty mbox - Collection collection4; - collection4.setName( QLatin1String( "collection4" ) ); - collection4.setRemoteId( QLatin1String( "collection4" ) ); - collection4.setParentCollection( mStore->topLevelCollection() ); - - item1.setRemoteId( entrySet1.values().first() ); - - job = mStore->moveItem( item1, collection4 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - movedItem = job->item(); - QCOMPARE( movedItem.id(), item1.id() ); - QCOMPARE( movedItem.parentCollection(), collection4 ); - - QVERIFY( mbox4.load( mbox4.fileName() ) ); - entryList = mbox4.entries(); - QCOMPARE( (int)entryList.count(), 1 ); - - QCOMPARE( entryList.last().messageOffset(), movedItem.remoteId().toULongLong() ); - entrySet1.remove( item1.remoteId() ); - QCOMPARE( QSet::fromList( md1.entryList() ), entrySet1 ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection1 ); - - // test moving to a non empty mbox - item1.setRemoteId( entrySet1.values().first() ); - - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->moveItem( item1, collection2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - movedItem = job->item(); - QCOMPARE( movedItem.id(), item1.id() ); - QCOMPARE( movedItem.parentCollection(), collection2 ); - - QVERIFY( mbox2.load( mbox2.fileName() ) ); - entryList = mbox2.entries(); - QCOMPARE( (int)entryList.count(), 5 ); - - QCOMPARE( entryList.last().messageOffset(), movedItem.remoteId().toULongLong() ); - entrySet1.remove( item1.remoteId() ); - QCOMPARE( QSet::fromList( md1.entryList() ), entrySet1 ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 2 ); - QCOMPARE( collections, Collection::List() << collection1 << collection2 ); -} - -void ItemMoveTest::testMBoxItem() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), topDir.path(), QLatin1String( "collection2" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection5" ) ) ); - - QFileInfo fileInfo1( topDir.path(), QLatin1String( "collection1" ) ); - MBox mbox1; - QVERIFY( mbox1.load( fileInfo1.absoluteFilePath() ) ); - MBoxEntry::List entryList1 = mbox1.entries(); - QCOMPARE( (int)entryList1.count(), 4 ); - - KPIM::Maildir topLevelMd( topDir.path(), true ); - - KPIM::Maildir md2 = topLevelMd.subFolder( QLatin1String( "collection2" ) ); - QSet entrySet2 = QSet::fromList( md2.entryList() ); - QCOMPARE( (int)entrySet2.count(), 4 ); - - KPIM::Maildir md3( topLevelMd.addSubFolder( QLatin1String( "collection3" ) ), false ); - QVERIFY( md3.isValid() ); - QSet entrySet3 = QSet::fromList( md3.entryList() ); - QCOMPARE( (int)entrySet3.count(), 0 ); - - QFileInfo fileInfo4( topDir.path(), QLatin1String( "collection4" ) ); - QFile file4( fileInfo4.absoluteFilePath() ); - QVERIFY( file4.open( QIODevice::WriteOnly ) ); - file4.close(); - fileInfo4.refresh(); - QVERIFY( fileInfo4.exists() ); - MBox mbox4; - QVERIFY( mbox4.load( fileInfo4.absoluteFilePath() ) ); - MBoxEntry::List entryList4 = mbox4.entries(); - QCOMPARE( (int)entryList4.count(), 0 ); - - QFileInfo fileInfo5( topDir.path(), QLatin1String( "collection5" ) ); - MBox mbox5; - QVERIFY( mbox5.load( fileInfo5.absoluteFilePath() ) ); - MBoxEntry::List entryList5 = mbox5.entries(); - QCOMPARE( (int)entryList5.count(), 4 ); - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::ItemMoveJob *job = 0; - FileStore::StoreCompactJob *compactStore = 0; - - const QVariant colListVar = QVariant::fromValue( Collection::List() ); - QVariant var; - Collection::List collections; - Item movedItem; - MBoxEntry::List entryList; - Item::List items; - - // test moving to an empty maildir - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - Collection collection3; - collection3.setName( QLatin1String( "collection3" ) ); - collection3.setRemoteId( QLatin1String( "collection3" ) ); - collection3.setParentCollection( mStore->topLevelCollection() ); - - Item item1; - item1.setId( KRandom::random() ); - item1.setRemoteId( QString::number( entryList1.first().messageOffset() ) ); - item1.setParentCollection( collection1 ); - - job = mStore->moveItem( item1, collection3 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - movedItem = job->item(); - QCOMPARE( movedItem.id(), item1.id() ); - QCOMPARE( movedItem.parentCollection(), collection3 ); - - var = job->property( "compactStore" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.type(), QVariant::Bool ); - QCOMPARE( var.toBool(), true ); - - compactStore = mStore->compactStore(); - QVERIFY( compactStore->exec() ); - - items = compactStore->changedItems(); - QCOMPARE( (int)items.count(), 3 ); - - entrySet3 << movedItem.remoteId(); - QCOMPARE( QSet::fromList( md3.entryList() ), entrySet3 ); - - entryList1.removeAt( 0 ); - entryList1[ 0 ] = MBoxEntry( changedOffset( items[ 0 ] ) ); - entryList1[ 1 ] = MBoxEntry( changedOffset( items[ 1 ] ) ); - entryList1[ 2 ] = MBoxEntry( changedOffset( items[ 2 ] ) ); - QVERIFY( mbox1.load( mbox1.fileName() ) ); - QCOMPARE( mbox1.entries(), entryList1 ); - - // test moving to a non empty mbox - Collection collection5; - collection5.setName( QLatin1String( "collection5" ) ); - collection5.setRemoteId( QLatin1String( "collection5" ) ); - collection5.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->moveItem( item1, collection5 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - movedItem = job->item(); - QCOMPARE( movedItem.id(), item1.id() ); - QCOMPARE( movedItem.parentCollection(), collection5 ); - - var = job->property( "compactStore" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.type(), QVariant::Bool ); - QCOMPARE( var.toBool(), true ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 2 ); - QCOMPARE( collections, Collection::List() << collection1 << collection5 ); - - compactStore = mStore->compactStore(); - QVERIFY( compactStore->exec() ); - - items = compactStore->changedItems(); - QCOMPARE( (int)items.count(), 2 ); - - QVERIFY( mbox5.load( mbox5.fileName() ) ); - QCOMPARE( mbox5.entries().count(), entryList5.count() + 1 ); - QCOMPARE( mbox5.entries().last().messageOffset(), movedItem.remoteId().toULongLong() ); - - entryList1.removeAt( 0 ); - entryList1[ 0 ] = MBoxEntry( changedOffset( items[ 0 ] ) ); - entryList1[ 1 ] = MBoxEntry( changedOffset( items[ 1 ] ) ); - QVERIFY( mbox1.load( mbox1.fileName() ) ); - QCOMPARE( mbox1.entries(), entryList1 ); - - // test moving to an empty mbox - Collection collection4; - collection4.setName( QLatin1String( "collection4" ) ); - collection4.setRemoteId( QLatin1String( "collection4" ) ); - collection4.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->moveItem( item1, collection4 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - movedItem = job->item(); - QCOMPARE( movedItem.id(), item1.id() ); - QCOMPARE( movedItem.parentCollection(), collection4 ); - - QVERIFY( mbox4.load( mbox4.fileName() ) ); - entryList = mbox4.entries(); - QCOMPARE( (int)entryList.count(), 1 ); - - QCOMPARE( entryList.last().messageOffset(), movedItem.remoteId().toULongLong() ); - - var = job->property( "compactStore" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.type(), QVariant::Bool ); - QCOMPARE( var.toBool(), true ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections.first(), collection1 ); - - compactStore = mStore->compactStore(); - QVERIFY( compactStore->exec() ); - - items = compactStore->changedItems(); - QCOMPARE( (int)items.count(), 1 ); - - QCOMPARE( mbox4.entries().count(), entryList4.count() + 1 ); - QCOMPARE( mbox4.entries().last().messageOffset(), movedItem.remoteId().toULongLong() ); - - entryList1.removeAt( 0 ); - entryList1[ 0 ] = MBoxEntry( changedOffset( items[ 0 ] ) ); - QVERIFY( mbox1.load( mbox1.fileName() ) ); - QCOMPARE( mbox1.entries(), entryList1 ); - - // test moving to a non empty maildir - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - job = mStore->moveItem( item1, collection2 ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - movedItem = job->item(); - QCOMPARE( movedItem.id(), item1.id() ); - QCOMPARE( movedItem.parentCollection(), collection2 ); - - QSet entrySet = QSet::fromList( md2.entryList() ); - QCOMPARE( (int)entrySet.count(), 5 ); - - QVERIFY( entrySet.contains( movedItem.remoteId() ) ); - - var = job->property( "compactStore" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.type(), QVariant::Bool ); - QCOMPARE( var.toBool(), true ); - - // check for index preservation - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 2 ); - QCOMPARE( collections.first(), collection1 ); - - compactStore = mStore->compactStore(); - QVERIFY( compactStore->exec() ); - - items = compactStore->changedItems(); - QCOMPARE( (int)items.count(), 0 ); - - entryList1.removeAt( 0 ); - QVERIFY( mbox1.load( mbox1.fileName() ) ); - const MBoxEntry::List newEntryList = mbox1.entries(); - QVERIFY( std::equal( newEntryList.begin(), newEntryList.end(), entryList1.begin(), fullEntryCompare ) ); -} - -QTEST_KDEMAIN( ItemMoveTest, NoGUI ) - -#include "itemmovetest.moc" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/storecompacttest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/tests/storecompacttest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/storecompacttest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/storecompacttest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,395 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" - -#include "testdatautil.h" - -#include "filestore/entitycompactchangeattribute.h" -#include "filestore/itemdeletejob.h" -#include "filestore/storecompactjob.h" - -#include - -#include -#include - -#include - -#include - -using namespace Akonadi; -using namespace KMBox; - -static Collection::List collectionsFromSpy( QSignalSpy *spy ) { - Collection::List collections; - - QListIterator > it( *spy ); - while( it.hasNext() ) { - const QList invocation = it.next(); - Q_ASSERT( invocation.count() == 1 ); - - collections << invocation.first().value(); - } - - return collections; -} - -static Item::List itemsFromSpy( QSignalSpy *spy ) { - Item::List items; - - QListIterator > it( *spy ); - while( it.hasNext() ) { - const QList invocation = it.next(); - Q_ASSERT( invocation.count() == 1 ); - - items << invocation.first().value(); - } - - return items; -} - -static bool fullEntryCompare( const MBoxEntry &a, const MBoxEntry &b ) -{ - return a.messageOffset() == b.messageOffset() && - a.separatorSize() == b.separatorSize() && - a.messageSize() == b.messageSize(); -} - -static quint64 changedOffset( const Item &item ) { - Q_ASSERT( item.hasAttribute() ); - - const QString remoteId = item.attribute()->remoteId(); - Q_ASSERT( !remoteId.isEmpty() ); - - bool ok = false; - const quint64 result = remoteId.toULongLong( &ok ); - Q_ASSERT( ok ); - - return result; -} - -class StoreCompactTest : public QObject -{ - Q_OBJECT - - public: - StoreCompactTest() : QObject(), mStore( 0 ), mDir( 0 ) { - // for monitoring signals - qRegisterMetaType(); - qRegisterMetaType(); - } - - ~StoreCompactTest() { - delete mStore; - delete mDir; - } - - private: - MixedMaildirStore *mStore; - KTempDir *mDir; - - private Q_SLOTS: - void init(); - void cleanup(); - void testCompact(); -}; - -void StoreCompactTest::init() -{ - mStore = new MixedMaildirStore; - - mDir = new KTempDir; - QVERIFY( mDir->exists() ); -} - -void StoreCompactTest::cleanup() -{ - delete mStore; - mStore = 0; - delete mDir; - mDir = 0; -} - -void StoreCompactTest::testCompact() -{ - QDir topDir( mDir->name() ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection1" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection2" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection3" ) ) ); - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), topDir.path(), QLatin1String( "collection4" ) ) ); - - QFileInfo fileInfo1( topDir.path(), QLatin1String( "collection1" ) ); - MBox mbox1; - QVERIFY( mbox1.load( fileInfo1.absoluteFilePath() ) ); - MBoxEntry::List entryList1 = mbox1.entries(); - QCOMPARE( (int)entryList1.count(), 4 ); - - QFileInfo fileInfo2( topDir.path(), QLatin1String( "collection2" ) ); - MBox mbox2; - QVERIFY( mbox2.load( fileInfo2.absoluteFilePath() ) ); - MBoxEntry::List entryList2 = mbox2.entries(); - QCOMPARE( (int)entryList2.count(), 4 ); - - QFileInfo fileInfo3( topDir.path(), QLatin1String( "collection3" ) ); - MBox mbox3; - QVERIFY( mbox3.load( fileInfo3.absoluteFilePath() ) ); - MBoxEntry::List entryList3 = mbox3.entries(); - QCOMPARE( (int)entryList3.count(), 4 ); - - QFileInfo fileInfo4( topDir.path(), QLatin1String( "collection4" ) ); - MBox mbox4; - QVERIFY( mbox4.load( fileInfo4.absoluteFilePath() ) ); - MBoxEntry::List entryList4 = mbox4.entries(); - QCOMPARE( (int)entryList4.count(), 4 ); - - mStore->setPath( topDir.path() ); - - // common variables - FileStore::CollectionFetchJob *collectionFetch = 0; - FileStore::ItemDeleteJob *itemDelete = 0; - FileStore::StoreCompactJob *job = 0; - - Collection::List collections; - Item::List items; - - QSignalSpy *collectionSpy = 0; - QSignalSpy *itemSpy = 0; - - MBoxEntry::List entryList; - Collection collection; - FileStore::EntityCompactChangeAttribute *attribute = 0; - - const QVariant colListVar = QVariant::fromValue( Collection::List() ); - QVariant var; - - // test compact after delete from the end of an mbox - Collection collection1; - collection1.setName( QLatin1String( "collection1" ) ); - collection1.setRemoteId( QLatin1String( "collection1" ) ); - collection1.setParentCollection( mStore->topLevelCollection() ); - - Item item1; - item1.setRemoteId( QString::number( entryList1.last().messageOffset() ) ); - item1.setParentCollection( collection1 ); - - itemDelete = mStore->deleteItem( item1 ); - - QVERIFY( itemDelete->exec() ); - - job = mStore->compactStore(); - - collectionSpy = new QSignalSpy( job, SIGNAL(collectionsChanged(Akonadi::Collection::List)) ); - itemSpy = new QSignalSpy( job, SIGNAL(itemsChanged(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collections = job->changedCollections(); - items = job->changedItems(); - - QCOMPARE( collections.count(), 0 ); - QCOMPARE( items.count(), 0 ); - - QCOMPARE( collectionSpy->count(), 0 ); - QCOMPARE( itemSpy->count(), 0 ); - - QVERIFY( mbox1.load( mbox1.fileName() ) ); - entryList = mbox1.entries(); - entryList1.pop_back(); - QVERIFY( std::equal( entryList.begin(), entryList.end(), entryList1.begin(), fullEntryCompare ) ); - - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections, Collection::List() << collection1 ); - - // test compact after delete from before the end of an mbox - Collection collection2; - collection2.setName( QLatin1String( "collection2" ) ); - collection2.setRemoteId( QLatin1String( "collection2" ) ); - collection2.setParentCollection( mStore->topLevelCollection() ); - - Item item2; - item2.setRemoteId( QString::number( entryList2.first().messageOffset() ) ); - item2.setParentCollection( collection2 ); - - itemDelete = mStore->deleteItem( item2 ); - - QVERIFY( itemDelete->exec() ); - - job = mStore->compactStore(); - - collectionSpy = new QSignalSpy( job, SIGNAL(collectionsChanged(Akonadi::Collection::List)) ); - itemSpy = new QSignalSpy( job, SIGNAL(itemsChanged(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collections = job->changedCollections(); - items = job->changedItems(); - - QCOMPARE( collections.count(), 1 ); - QCOMPARE( items.count(), 3 ); - - QCOMPARE( collectionSpy->count(), 1 ); - QCOMPARE( itemSpy->count(), 1 ); - - QCOMPARE( collectionsFromSpy( collectionSpy ), collections ); - QCOMPARE( itemsFromSpy( itemSpy ), items ); - - collection = collections.first(); - QCOMPARE( collection, collection2 ); - QVERIFY( collection.hasAttribute() ); - attribute = collection.attribute(); - QCOMPARE( attribute->remoteRevision().toInt(), collection2.remoteRevision().toInt() + 1 ); - - QVERIFY( mbox2.load( mbox2.fileName() ) ); - entryList = mbox2.entries(); - - entryList2.pop_front(); - for ( int i = 0; i < items.count(); ++i ) { - entryList2[ i ] = MBoxEntry( changedOffset( items[ i ] ) ); - } - QCOMPARE( entryList, entryList2 ); - - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 1 ); - QCOMPARE( collections, Collection::List() << collection2 ); - - collectionFetch = mStore->fetchCollections( collection2, FileStore::CollectionFetchJob::Base ); - - QVERIFY( collectionFetch->exec() ); - - collections = collectionFetch->collections(); - QCOMPARE( (int)collections.count(), 1 ); - - collection = collections.first(); - QCOMPARE( collection, collection2 ); - QCOMPARE( collection.remoteRevision(), attribute->remoteRevision() ); - - // test compact after delete from before the end of more than one mbox - Collection collection3; - collection3.setName( QLatin1String( "collection3" ) ); - collection3.setRemoteId( QLatin1String( "collection3" ) ); - collection3.setParentCollection( mStore->topLevelCollection() ); - - Item item3; - item3.setRemoteId( QString::number( entryList3.first().messageOffset() ) ); - item3.setParentCollection( collection3 ); - - itemDelete = mStore->deleteItem( item3 ); - - QVERIFY( itemDelete->exec() ); - - Collection collection4; - collection4.setName( QLatin1String( "collection4" ) ); - collection4.setRemoteId( QLatin1String( "collection4" ) ); - collection4.setParentCollection( mStore->topLevelCollection() ); - - Item item4; - item4.setRemoteId( QString::number( entryList3.value( 1 ).messageOffset() ) ); - item4.setParentCollection( collection4 ); - - itemDelete = mStore->deleteItem( item4 ); - - QVERIFY( itemDelete->exec() ); - - job = mStore->compactStore(); - - collectionSpy = new QSignalSpy( job, SIGNAL(collectionsChanged(Akonadi::Collection::List)) ); - itemSpy = new QSignalSpy( job, SIGNAL(itemsChanged(Akonadi::Item::List)) ); - - QVERIFY( job->exec() ); - QCOMPARE( job->error(), 0 ); - - collections = job->changedCollections(); - items = job->changedItems(); - - QCOMPARE( collections.count(), 2 ); - QCOMPARE( items.count(), 5 ); - - QCOMPARE( collectionSpy->count(), 2 ); - QCOMPARE( itemSpy->count(), 2 ); - - QCOMPARE( collectionsFromSpy( collectionSpy ), collections ); - QCOMPARE( itemsFromSpy( itemSpy ), items ); - - QHash compactedCollections; - Q_FOREACH ( const Collection &col, collections ) { - compactedCollections.insert( col.remoteId(), col ); - } - QCOMPARE( compactedCollections.count(), 2 ); - - QVERIFY( compactedCollections.contains( collection3.remoteId() ) ); - collection = compactedCollections[ collection3.remoteId() ]; - QCOMPARE( collection, collection3 ); - QVERIFY( collection.hasAttribute() ); - attribute = collection.attribute(); - QCOMPARE( attribute->remoteRevision().toInt(), collection3.remoteRevision().toInt() + 1 ); - - QVERIFY( mbox3.load( mbox3.fileName() ) ); - entryList = mbox3.entries(); - - entryList3.pop_front(); - for ( int i = 0; i < entryList3.count(); ++i ) { - entryList3[ i ] = MBoxEntry( changedOffset( items.first() ) ); - items.pop_front(); - } - QCOMPARE( entryList, entryList3 ); - - QVERIFY( compactedCollections.contains( collection4.remoteId() ) ); - collection = compactedCollections[ collection4.remoteId() ]; - QCOMPARE( collection, collection4 ); - QVERIFY( collection.hasAttribute() ); - attribute = collection.attribute(); - QCOMPARE( attribute->remoteRevision().toInt(), collection4.remoteRevision().toInt() + 1 ); - - QVERIFY( mbox4.load( mbox4.fileName() ) ); - entryList = mbox4.entries(); - - entryList4.removeAt( 1 ); - for ( int i = 0; i < items.count(); ++i ) { - entryList4[ i + 1 ] = MBoxEntry( changedOffset( items[ i ] ) ); - } - QCOMPARE( entryList, entryList4 ); - - var = job->property( "onDiskIndexInvalidated" ); - QVERIFY( var.isValid() ); - QCOMPARE( var.userType(), colListVar.userType() ); - - collections = var.value(); - QCOMPARE( (int)collections.count(), 2 ); - QCOMPARE( collections, Collection::List() << collection3 << collection4 ); -} - -QTEST_KDEMAIN( StoreCompactTest, NoGUI ) - -#include "storecompacttest.moc" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/templatemethodstest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/tests/templatemethodstest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/templatemethodstest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/templatemethodstest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "mixedmaildirstore.h" - -#include "collectioncreatejob.h" -#include "collectiondeletejob.h" -#include "collectionfetchjob.h" -#include "collectionmodifyjob.h" -#include "collectionmovejob.h" -#include "itemcreatejob.h" -#include "itemdeletejob.h" -#include "itemfetchjob.h" -#include "itemmodifyjob.h" -#include "itemmovejob.h" -#include "sessionimpls_p.h" -#include "storecompactjob.h" - -#include -#include - -#include - -#include -#include - -#include - -using namespace Akonadi; - -class TestStore : public MixedMaildirStore -{ - Q_OBJECT - - public: - TestStore() : mLastCheckedJob( 0 ), mErrorCode( 0 ) {} - - public: - Collection mTopLevelCollection; - - mutable FileStore::Job *mLastCheckedJob; - mutable int mErrorCode; - mutable QString mErrorText; - - protected: - void setTopLevelCollection( const Collection &collection ) - { - MixedMaildirStore::setTopLevelCollection( collection ); - } - - void checkCollectionMove( FileStore::CollectionMoveJob *job, int &errorCode, QString &errorText ) const - { - MixedMaildirStore::checkCollectionMove( job, errorCode, errorText ); - - mLastCheckedJob = job; - mErrorCode = errorCode; - mErrorText = errorText; - } - - void checkItemCreate( FileStore::ItemCreateJob *job, int &errorCode, QString &errorText ) const - { - MixedMaildirStore::checkItemCreate( job, errorCode, errorText ); - - mLastCheckedJob = job; - mErrorCode = errorCode; - mErrorText = errorText; - } -}; - -class TemplateMethodsTest : public QObject -{ - Q_OBJECT - - public: - TemplateMethodsTest() : QObject(), mStore( 0 ) {} - ~TemplateMethodsTest() { delete mStore; } - - private: - KTempDir mDir; - TestStore *mStore; - - private Q_SLOTS: - void init(); - void testSetTopLevelCollection(); - void testMoveCollection(); - void testCreateItem(); -}; - -void TemplateMethodsTest::init() -{ - delete mStore; - mStore = new TestStore; - QVERIFY( mDir.exists() ); -} - -void TemplateMethodsTest::testSetTopLevelCollection() -{ - const QString file = KRandom::randomString( 10 ); - const QString path = mDir.name() + file; - - mStore->setPath( path ); - - // check the adjustments on the top level collection - const Collection collection = mStore->topLevelCollection(); - QCOMPARE( collection.contentMimeTypes(), QStringList() << Collection::mimeType() ); - QCOMPARE( collection.rights(), Collection::CanCreateCollection | - Collection::CanChangeCollection | - Collection::CanDeleteCollection ); - const CachePolicy cachePolicy = collection.cachePolicy(); - QVERIFY( !cachePolicy.inheritFromParent() ); - QCOMPARE( cachePolicy.localParts(), QStringList() << MessagePart::Envelope ); - QVERIFY( cachePolicy.syncOnDemand() ); -} - -void TemplateMethodsTest::testMoveCollection() -{ - mStore->setPath( mDir.name() ); - - FileStore::CollectionMoveJob *job = 0; - - // test moving into itself - Collection collection( KRandom::random() ); - collection.setParentCollection( mStore->topLevelCollection() ); - collection.setRemoteId( "collection" ); - job = mStore->moveCollection( collection, collection ); - QVERIFY( job != 0 ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( mStore->mErrorCode, job->error() ); - QCOMPARE( mStore->mErrorText, job->errorText() ); - - QVERIFY( !job->exec() ); - - // test moving into child - Collection childCollection( collection.id() + 1 ); - childCollection.setParentCollection( collection ); - childCollection.setRemoteId( "child" ); - job = mStore->moveCollection( collection, childCollection ); - QVERIFY( job != 0 ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( mStore->mErrorCode, job->error() ); - QCOMPARE( mStore->mErrorText, job->errorText() ); - - QVERIFY( !job->exec() ); - - // test moving into grand child child - Collection grandChildCollection( collection.id() + 2 ); - grandChildCollection.setParentCollection( childCollection ); - grandChildCollection.setRemoteId( "grandchild" ); - job = mStore->moveCollection( collection, grandChildCollection ); - QVERIFY( job != 0 ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( mStore->mErrorCode, job->error() ); - QCOMPARE( mStore->mErrorText, job->errorText() ); - - QVERIFY( !job->exec() ); - - // test moving into unrelated collection - Collection otherCollection( collection.id() + KRandom::random() ); - otherCollection.setParentCollection( mStore->topLevelCollection() ); - otherCollection.setRemoteId( "other" ); - job = mStore->moveCollection( collection, otherCollection ); - QVERIFY( job != 0 ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - QCOMPARE( mStore->mLastCheckedJob, job ); - - // collections don't exist in the store, so processing still fails - QVERIFY( !job->exec() ); -} - -void TemplateMethodsTest::testCreateItem() -{ - mStore->setPath( mDir.name() ); - - Collection collection( KRandom::random() ); - collection.setParentCollection( mStore->topLevelCollection() ); - collection.setRemoteId( "collection" ); - - FileStore::ItemCreateJob *job = 0; - - // test item without payload - Item item( KMime::Message::mimeType() ); - job = mStore->createItem( item, collection ); - QVERIFY( job != 0 ); - QCOMPARE( job->error(), (int)FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( mStore->mErrorCode, job->error() ); - QCOMPARE( mStore->mErrorText, job->errorText() ); - - QVERIFY( !job->exec() ); - - // test item with payload - item.setPayloadFromData( "Subject: dummy payload\n\nwith some content" ); - job = mStore->createItem( item, collection ); - QVERIFY( job != 0 ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - QCOMPARE( mStore->mLastCheckedJob, job ); - - // collections don't exist in the store, so processing still fails - QVERIFY( !job->exec() ); -} - -QTEST_KDEMAIN( TemplateMethodsTest, NoGUI ) - -#include "templatemethodstest.moc" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/testdata.qrc kdepim-runtime-15.08.0/resources/mixedmaildir/tests/testdata.qrc --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/testdata.qrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/testdata.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ - - - - data/mbox - data/.mbox.index - - data/mbox-tagged - data/.mbox-tagged.index - - data/mbox-unpurged - data/.mbox-unpurged.index - - data/maildir/cur/1279979618.4595.CStza_2,S - data/maildir/cur/1279979618.4595.pY5ny - data/maildir/cur/1279979617.4595.bwXSm - data/maildir/cur/1279979618.4595.DUl0I_2,S - data/.maildir.index - - data/maildir-tagged/cur/1279982188.18722.6qZsA_2,S - data/maildir-tagged/cur/1279982188.18722.Xdz3R_2,S - data/maildir-tagged/cur/1279982188.18722.f0l49_2,S - data/maildir-tagged/cur/1279982188.18722.kwx1b_2,S - data/.maildir-tagged.index - - data/dimap/cur/1279980064.4595.qs6V9_2,S - data/dimap/cur/1279980064.4595.LUBVK - data/dimap/cur/1279980064.4595.g8PCJ - data/dimap/cur/1279980064.4595.RTmAd_2,S - data/.dimap.index - - diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/testdatatest.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/tests/testdatatest.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/testdatatest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/testdatatest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "testdatautil.h" - -#include - -#include - -class TestDataTest : public QObject -{ - Q_OBJECT - public: - TestDataTest() {} - - private Q_SLOTS: - void testResources(); - void testInstall(); -}; - -void TestDataTest::testResources() -{ - const QStringList testDataNames = TestDataUtil::testDataNames(); - QCOMPARE( testDataNames, QStringList() << QLatin1String( "dimap" ) - << QLatin1String( "maildir" ) - << QLatin1String( "maildir-tagged" ) - << QLatin1String( "mbox" ) - << QLatin1String( "mbox-tagged" ) - << QLatin1String( "mbox-unpurged" ) ); - - Q_FOREACH( const QString testDataName, testDataNames ) { - if ( testDataName.startsWith( QLatin1String( "mbox" ) ) ) { - QVERIFY( TestDataUtil::folderType( testDataName ) == TestDataUtil::MBoxFolder ); - } else { - QVERIFY( TestDataUtil::folderType( testDataName ) == TestDataUtil::MaildirFolder ); - } - } - - // TODO check contents? -} - -void TestDataTest::testInstall() -{ - KTempDir dir; - QDir installDir( dir.name() ); - QDir curDir; - - const QString indexFilePattern = QLatin1String( ".%1.index" ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox" ), dir.name(), QLatin1String( "mbox1" ) ) ); - QVERIFY( installDir.exists( QLatin1String( "mbox1" ) ) ); - QVERIFY( installDir.exists( indexFilePattern.arg( QLatin1String( "mbox1" ) ) ) ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "mbox-tagged" ), dir.name(), QLatin1String( "mbox2" ) ) ); - QVERIFY( installDir.exists( QLatin1String( "mbox2" ) ) ); - QVERIFY( installDir.exists( indexFilePattern.arg( QLatin1String( "mbox2" ) ) ) ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir" ), dir.name(), QLatin1String( "md1" ) ) ); - QVERIFY( installDir.exists( QLatin1String( "md1" ) ) ); - QVERIFY( installDir.exists( QLatin1String( "md1/new" ) ) ); - QVERIFY( installDir.exists( QLatin1String( "md1/cur" ) ) ); - QVERIFY( installDir.exists( QLatin1String( "md1/tmp" ) ) ); - QVERIFY( installDir.exists( indexFilePattern.arg( QLatin1String( "md1" ) ) ) ); - - curDir = installDir; - curDir.cd( QLatin1String( "md1" ) ); - curDir.cd( QLatin1String( "cur" ) ); - curDir.setFilter( QDir::Files ); - QCOMPARE( (int)curDir.count(), 4 ); - - QVERIFY( TestDataUtil::installFolder( QLatin1String( "maildir-tagged" ), dir.name(), QLatin1String( "md2" ) ) ); - QVERIFY( installDir.exists( QLatin1String( "md2" ) ) ); - QVERIFY( installDir.exists( QLatin1String( "md2/new" ) ) ); - QVERIFY( installDir.exists( QLatin1String( "md2/cur" ) ) ); - QVERIFY( installDir.exists( QLatin1String( "md2/tmp" ) ) ); - QVERIFY( installDir.exists( indexFilePattern.arg( QLatin1String( "md2" ) ) ) ); - - curDir = installDir; - curDir.cd( QLatin1String( "md2" ) ); - curDir.cd( QLatin1String( "cur" ) ); - curDir.setFilter( QDir::Files ); - QCOMPARE( (int)curDir.count(), 4 ); -} - -#include "testdatatest.moc" - -QTEST_KDEMAIN( TestDataTest, NoGUI ) - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/testdatautil.cpp kdepim-runtime-15.08.0/resources/mixedmaildir/tests/testdatautil.cpp --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/testdatautil.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/testdatautil.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,202 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "testdatautil.h" - -#include - -#include -#include - -using namespace TestDataUtil; - -// use this instead of QFile::copy() because we want overwrite in case it exists -static bool copyFile( const QString &sourceFileName, const QString &targetFileName ) -{ - QFile sourceFile( sourceFileName ); - QFile targetFile( targetFileName ); - - if ( !sourceFile.open( QIODevice::ReadOnly ) ) { - kError() << "Cannot open source file" << sourceFileName; - return false; - } - - if ( !targetFile.open( QIODevice::WriteOnly ) ) { - kError() << "Cannot open target file" << targetFileName; - return false; - } - - return targetFile.write( sourceFile.readAll() ) != -1; -} - -static bool copyFiles( const QDir &sourceDir, const QDir &targetDir ) -{ - const QStringList files = sourceDir.entryList( QStringList(), QDir::Files ); - Q_FOREACH( const QString &file, files ) { - const QFileInfo sourceFileInfo( sourceDir, file ); - const QFileInfo targetFileInfo( targetDir, file ); - if ( !copyFile( sourceFileInfo.absoluteFilePath(), targetFileInfo.absoluteFilePath() ) ) { - kError() << "Failed to copy" << sourceFileInfo.absoluteFilePath() - << "to" << targetFileInfo.absoluteFilePath(); - return false; - } - } - - return true; -} - -FolderType TestDataUtil::folderType( const QString &testDataName ) -{ - const QDir dir( QLatin1String( ":/data" ) ); - const QString indexFilePattern = QLatin1String( ".%1.index" ); - - if ( !dir.exists( testDataName ) || !dir.exists( indexFilePattern.arg( testDataName ) ) ) { - return InvalidFolder; - } - - const QFileInfo fileInfo( dir, testDataName ); - return ( fileInfo.isDir() ? MaildirFolder : MBoxFolder ); -} - -QStringList TestDataUtil::testDataNames() -{ - const QDir dir( QLatin1String( ":/data" ) ); - const QFileInfoList dirEntries = dir.entryInfoList(); - - const QString indexFilePattern = QLatin1String( ".%1.index" ); - - QStringList result; - Q_FOREACH( const QFileInfo& fileInfo, dirEntries ) { - if ( dir.exists( indexFilePattern.arg( fileInfo.fileName() ) ) ) { - result << fileInfo.fileName(); - } - } - - result.sort(); - return result; -} - -bool TestDataUtil::installFolder( const QString &testDataName, const QString &installPath, const QString &folderName ) -{ - const FolderType type = TestDataUtil::folderType( testDataName ); - if ( type == InvalidFolder ) { - kError() << "testDataName" << testDataName << "is not a valid mail folder type"; - return false; - } - - if ( !QDir::current().mkpath( installPath ) ) { - kError() << "Couldn't create installPath" << installPath; - return false; - } - - const QDir installDir( installPath ); - const QFileInfo installFileInfo( installDir, folderName ); - if ( installDir.exists( folderName ) ) { - switch ( type ) { - case MaildirFolder: - if ( !installFileInfo.isDir() ) { - kError() << "Target file name" << folderName << "already exists but is not a directory"; - return false; - } - break; - - case MBoxFolder: - if ( !installFileInfo.isFile() ) { - kError() << "Target file name" << folderName << "already exists but is not a directory"; - return false; - } - break; - - default: - // already handled at beginning - Q_ASSERT( false ); - return false; - } - } - - const QDir testDataDir( QLatin1String( ":/data" ) ); - - switch ( type ) { - case MaildirFolder: { - const QString subPathPattern = QLatin1String( "%1/%2" ); - if ( !installDir.mkpath( subPathPattern.arg( folderName, QLatin1String( "new" ) ) ) || - !installDir.mkpath( subPathPattern.arg( folderName, QLatin1String( "cur" ) ) ) || - !installDir.mkpath( subPathPattern.arg( folderName, QLatin1String( "tmp" ) ) ) ) { - kError() << "Couldn't create maildir directory structure"; - return false; - } - - QDir sourceDir = testDataDir; - QDir targetDir = installDir; - - sourceDir.cd( testDataName ); - targetDir.cd( folderName ); - - if ( sourceDir.cd( QLatin1String( "new" ) ) ) { - targetDir.cd( QLatin1String( "new" ) ); - if ( !copyFiles( sourceDir, targetDir ) ) { - return false; - } - sourceDir.cdUp(); - targetDir.cdUp(); - } - - if ( sourceDir.cd( QLatin1String( "cur" ) ) ) { - targetDir.cd( QLatin1String( "cur" ) ); - if ( !copyFiles( sourceDir, targetDir ) ) { - return false; - } - sourceDir.cdUp(); - targetDir.cdUp(); - } - - if ( sourceDir.cd( QLatin1String( "tmp" ) ) ) { - targetDir.cd( QLatin1String( "tmp" ) ); - if ( !copyFiles( sourceDir, targetDir ) ) { - return false; - } - } - break; - } - - case MBoxFolder: { - const QFileInfo mboxFileInfo( testDataDir, testDataName ); - if ( !copyFile( mboxFileInfo.absoluteFilePath(), installFileInfo.absoluteFilePath() ) ) { - kError() << "Failed to copy" << mboxFileInfo.absoluteFilePath() - << "to" << installFileInfo.absoluteFilePath(); - return false; - } - break; - } - - default: - // already handled at beginning - Q_ASSERT( false ); - return false; - } - - const QString indexFilePattern = QLatin1String( ".%1.index" ); - const QFileInfo indexFileInfo( testDataDir, indexFilePattern.arg( testDataName ) ); - const QFileInfo indexInstallFileInfo( installDir, indexFilePattern.arg( folderName ) ); - - return copyFile( indexFileInfo.absoluteFilePath(), indexInstallFileInfo.absoluteFilePath() ); -} - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/mixedmaildir/tests/testdatautil.h kdepim-runtime-15.08.0/resources/mixedmaildir/tests/testdatautil.h --- kdepim-runtime-4.14.6/resources/mixedmaildir/tests/testdatautil.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/mixedmaildir/tests/testdatautil.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 TESTDATAUTIL_H -#define TESTDATAUTIL_H - -class QString; -class QStringList; - -namespace TestDataUtil -{ - enum FolderType { - InvalidFolder, - MaildirFolder, - MBoxFolder - }; - - FolderType folderType( const QString &testDataName ); - - QStringList testDataNames(); - - bool installFolder( const QString &testDataName, const QString &installPath, const QString &folderName ); -} - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/nntp/CMakeLists.txt kdepim-runtime-15.08.0/resources/nntp/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/nntp/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/nntp/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -include_directories( - ${kdepim-runtime_SOURCE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} - ${Boost_INCLUDE_DIR} -) - -set( nntpresource_SRCS - nntpcollectionattribute.cpp - nntpresource.cpp - configdialog.cpp - settings.cpp -) - -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - -install( FILES nntpresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) - -kcfg_generate_dbus_interface( ${CMAKE_CURRENT_SOURCE_DIR}/nntpresource.kcfg org.kde.Akonadi.NNTP.Settings ) - -qt4_add_dbus_adaptor( nntpresource_SRCS - ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.NNTP.Settings.xml settings.h Settings -) -kde4_add_ui_files(nntpresource_SRCS configdialog.ui) -kde4_add_kcfg_files(nntpresource_SRCS settingsbase.kcfgc) -kde4_add_executable(akonadi_nntp_resource ${nntpresource_SRCS}) - - -if (Q_WS_MAC) - set_target_properties(akonadi_nntp_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) - set_target_properties(akonadi_nntp_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.NNTP") - set_target_properties(akonadi_nntp_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi NNTP Resource") -endif () - -target_link_libraries(akonadi_nntp_resource ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_AKONADI_KMIME_LIBS} ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} ${KDEPIMLIBS_KMIME_LIBS} ${QT_QTCORE_LIBRARY}) - -install(TARGETS akonadi_nntp_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/nntp/configdialog.cpp kdepim-runtime-15.08.0/resources/nntp/configdialog.cpp --- kdepim-runtime-4.14.6/resources/nntp/configdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/nntp/configdialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 "configdialog.h" -#include "settings.h" - -#include - -ConfigDialog::ConfigDialog(QWidget * parent) : - KDialog( parent ) -{ - ui.setupUi( mainWidget() ); - mManager = new KConfigDialogManager( this, Settings::self() ); - mManager->updateWidgets(); - ui.password->setText( Settings::self()->password() ); - ui.kcfg_MaxDownload->setSuffix( ki18np( " article", " articles" ) ); - - connect( this, SIGNAL(okClicked()), SLOT(save()) ); -} - -void ConfigDialog::save() -{ - if ( ui.kcfg_StorePassword->isChecked() ) - Settings::self()->setPassword( ui.password->text() ); - mManager->updateSettings(); -} - diff -Nru kdepim-runtime-4.14.6/resources/nntp/configdialog.h kdepim-runtime-15.08.0/resources/nntp/configdialog.h --- kdepim-runtime-4.14.6/resources/nntp/configdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/nntp/configdialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 CONFIGDIALOG_H -#define CONFIGDIALOG_H - -#include - -#include "ui_configdialog.h" - -class KConfigDialogManager; - -class ConfigDialog : public KDialog -{ - Q_OBJECT - public: - explicit ConfigDialog( QWidget *parent = 0 ); - - private slots: - void save(); - - private: - Ui::ConfigDialog ui; - KConfigDialogManager* mManager; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/nntp/configdialog.ui kdepim-runtime-15.08.0/resources/nntp/configdialog.ui --- kdepim-runtime-4.14.6/resources/nntp/configdialog.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/nntp/configdialog.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,399 +0,0 @@ - - Volker Krause <vkrause@kde.org> - ConfigDialog - - - - 0 - 0 - 400 - 513 - - - - - - - true - - - 0 - - - - General - - - - - - &Name: - - - kcfg_Name - - - - - - - - - - &Server: - - - kcfg_Server - - - - - - - - - - Port: - - - - - - - - - - Qt::Horizontal - - - - 181 - 20 - - - - - - - - Encryption - - - - - - - - &None - - - - - - - &SSL - - - - - - - &TLS - - - - - - - - - Qt::Horizontal - - - - 191 - 20 - - - - - - - - false - - - &Check Server - - - - - - - - - - Authentication - - - - - - Server requires authentication - - - - - - - false - - - &Username: - - - kcfg_UserName - - - - - - - false - - - - - - - false - - - &Password: - - - password - - - - - - - false - - - true - - - - - - - false - - - Store password in KWallet - - - - - - - - - - Qt::Vertical - - - - 317 - 41 - - - - - - - - - Advanced - - - - - - Articles - - - - - - Download at most: - - - - - - - 1 - - - - - - - Qt::Horizontal - - - - 16 - 20 - - - - - - - - - - - Newsgroups - - - - - - Create flat newsgroup hierarchy by default - - - - - - - - - - Qt::Vertical - - - - 20 - 241 - - - - - - - - - - - - - KButtonGroup - QGroupBox -
kbuttongroup.h
- 1 -
- - KIntNumInput - QWidget -
knuminput.h
-
- - KLineEdit - QLineEdit -
klineedit.h
-
- - KPushButton - QPushButton -
kpushbutton.h
-
-
- - - - kcfg_RequiresAuthentication - toggled(bool) - kcfg_UserName - setEnabled(bool) - - - 83 - 196 - - - 127 - 227 - - - - - kcfg_RequiresAuthentication - toggled(bool) - password - setEnabled(bool) - - - 59 - 206 - - - 105 - 269 - - - - - kcfg_RequiresAuthentication - toggled(bool) - label_5 - setEnabled(bool) - - - 48 - 213 - - - 46 - 232 - - - - - kcfg_RequiresAuthentication - toggled(bool) - label_4 - setEnabled(bool) - - - 140 - 201 - - - 83 - 265 - - - - - kcfg_RequiresAuthentication - toggled(bool) - kcfg_StorePassword - setEnabled(bool) - - - 232 - 209 - - - 242 - 305 - - - - -
diff -Nru kdepim-runtime-4.14.6/resources/nntp/Messages.sh kdepim-runtime-15.08.0/resources/nntp/Messages.sh --- kdepim-runtime-4.14.6/resources/nntp/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/nntp/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -#! /usr/bin/env bash -$EXTRACTRC `find . -name \*.ui` `find . -name \*.kcfg` >> rc.cpp || exit 11 -$XGETTEXT *.cpp -o $podir/akonadi_nntp_resource.pot diff -Nru kdepim-runtime-4.14.6/resources/nntp/nntpcollectionattribute.cpp kdepim-runtime-15.08.0/resources/nntp/nntpcollectionattribute.cpp --- kdepim-runtime-4.14.6/resources/nntp/nntpcollectionattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/nntp/nntpcollectionattribute.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -/* - Copyright (c) 2007 Volker Krause - - 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 "nntpcollectionattribute.h" - -#include - -NntpCollectionAttribute::NntpCollectionAttribute() - : Attribute(), - mLastArticleId( 0 ) -{ -} - -QByteArray NntpCollectionAttribute::type() const -{ - static const QByteArray sType( "NNTP" ); - return sType; -} - -NntpCollectionAttribute * NntpCollectionAttribute::clone() const -{ - NntpCollectionAttribute *attr = new NntpCollectionAttribute(); - attr->mLastArticleId = mLastArticleId; - return attr; -} - -QByteArray NntpCollectionAttribute::serialized() const -{ - QByteArray data = QByteArray::number( mLastArticleId ); - return data; -} - -void NntpCollectionAttribute::deserialize(const QByteArray & data) -{ - mLastArticleId = data.toInt(); -} - -int NntpCollectionAttribute::lastArticle() const -{ - return mLastArticleId; -} - -void NntpCollectionAttribute::setLastArticle(int last) -{ - mLastArticleId = last; -} diff -Nru kdepim-runtime-4.14.6/resources/nntp/nntpcollectionattribute.h kdepim-runtime-15.08.0/resources/nntp/nntpcollectionattribute.h --- kdepim-runtime-4.14.6/resources/nntp/nntpcollectionattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/nntp/nntpcollectionattribute.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -/* - Copyright (c) 2007 Volker Krause - - 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_NNTPCOLLECTIONATTRIBUTE_H -#define AKONADI_NNTPCOLLECTIONATTRIBUTE_H - -#include - -/** - Collection attribute to store information needed for incremental - collection updates. -*/ -class NntpCollectionAttribute : public Akonadi::Attribute -{ - public: - NntpCollectionAttribute(); - QByteArray type() const; - NntpCollectionAttribute* clone() const; - QByteArray serialized() const; - void deserialize( const QByteArray &data ); - - /** - Returns the serial number of the last fetched article. - */ - int lastArticle() const; - - /** - Sets the serial number of the last fetched serial number. - @param last Serial number of the last fetched article. - */ - void setLastArticle( int last ); - - private: - qint32 mLastArticleId; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/nntp/nntpresource.cpp kdepim-runtime-15.08.0/resources/nntp/nntpresource.cpp --- kdepim-runtime-4.14.6/resources/nntp/nntpresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/nntp/nntpresource.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,335 +0,0 @@ -/* - Copyright (c) 2007 Volker Krause - - 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 "nntpresource.h" -#include "nntpcollectionattribute.h" -#include "configdialog.h" -#include "settings.h" -#include "settingsadaptor.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include -typedef boost::shared_ptr MessagePtr; - -using namespace Akonadi; - -NntpResource::NntpResource(const QString & id) - : ResourceBase( id ) -{ - AttributeFactory::registerAttribute(); - changeRecorder()->fetchCollection( true ); - new SettingsAdaptor( Settings::self() ); - QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ), - Settings::self(), QDBusConnection::ExportAdaptors ); -} - -NntpResource::~ NntpResource() -{ -} - -bool NntpResource::retrieveItem(const Akonadi::Item& item, const QSet &parts) -{ - Q_UNUSED( parts ); - KIO::Job* job = KIO::storedGet( KUrl( item.remoteId() ), KIO::NoReload, KIO::HideProgressInfo ); - setupKioJob( job ); - connect( job, SIGNAL(result(KJob*)), SLOT(fetchArticleResult(KJob*)) ); - return true; -} - -void NntpResource::retrieveCollections() -{ - remoteCollections.clear(); - Collection rootCollection; - rootCollection.setParentCollection( Collection::root() ); - rootCollection.setRemoteId( baseUrl().url() ); - rootCollection.setName( Settings::self()->name() ); - CachePolicy policy; - policy.setInheritFromParent( false ); - policy.setSyncOnDemand( true ); - policy.setLocalParts( QStringList( MessagePart::Envelope ) ); - rootCollection.setCachePolicy( policy ); - QStringList contentTypes; - contentTypes << Collection::mimeType(); - rootCollection.setContentMimeTypes( contentTypes ); - remoteCollections << rootCollection; - - KUrl url = baseUrl(); - QDate lastList = Settings::self()->lastGroupList().date(); - if ( lastList.isValid() ) { - mIncremental = true; - url.addQueryItem( "since", QString( "%1%2%3 000000" ) - .arg( lastList.year() % 100, 2, 10, QChar( '0' ) ) - .arg( lastList.month(), 2, 10, QChar( '0' ) ) - .arg( lastList.day(), 2, 10, QChar( '0' ) ) ); - } else { - mIncremental = false; - } - - KIO::ListJob* job = KIO::listDir( url, KIO::HideProgressInfo, true ); - setupKioJob( job ); - connect( job, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)), - SLOT(listGroups(KIO::Job*,KIO::UDSEntryList)) ); - connect( job, SIGNAL(result(KJob*)), SLOT(listGroupsResult(KJob*)) ); -} - -void NntpResource::retrieveItems( const Akonadi::Collection & col ) -{ - if ( !(col.contentMimeTypes().count() == 1 && col.contentMimeTypes().first() == "message/news" ) ) { - // not a newsgroup, skip it - itemsRetrievalDone(); - return; - } - - KUrl url = baseUrl(); - url.setPath( col.remoteId() ); - - NntpCollectionAttribute *attr = col.attribute(); - if ( attr && attr->lastArticle() > 0 ) - url.addQueryItem( "first", QString::number( attr->lastArticle() + 1 ) ); - else - url.addQueryItem( "max", QString::number( Settings::self()->maxDownload() ) ); - - KIO::ListJob* job = KIO::listDir( url, KIO::HideProgressInfo, true ); - setupKioJob( job ); - connect( job, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)), - SLOT(listGroup(KIO::Job*,KIO::UDSEntryList)) ); - connect( job, SIGNAL(result(KJob*)), SLOT(listGroupResult(KJob*)) ); -} - -void NntpResource::listGroups(KIO::Job * job, const KIO::UDSEntryList & list) -{ - Q_UNUSED( job ); - QString name; - QStringList contentTypes; - contentTypes << "message/news"; - for( KIO::UDSEntryList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it ) { - name = (*it).stringValue( KIO::UDSEntry::UDS_NAME ); - if ( name.isEmpty() ) - continue; - - Collection c; - c.setRemoteId( name ); - c.setContentMimeTypes( contentTypes ); - - if ( Settings::self()->flatHierarchy() ) { - c.setName( name ); - c.parentCollection().setRemoteId( baseUrl().url() ); - } else { - const QStringList path = name.split( '.' ); - Q_ASSERT( !path.isEmpty() ); - c.setName( path.last() ); - c.parentCollection().setRemoteId( findParent( path ) ); - } - - remoteCollections << c; - } -} - -void NntpResource::listGroupsResult(KJob * job) -{ - if ( job->error() ) { - emit error( job->errorString() ); - return; - } else { - Settings::self()->setLastGroupList( QDateTime::currentDateTime() ); - } - if ( mIncremental ) - collectionsRetrievedIncremental( remoteCollections, Collection::List() ); - else - collectionsRetrieved( remoteCollections ); -} - -void NntpResource::listGroup(KIO::Job * job, const KIO::UDSEntryList & list) -{ - Q_UNUSED( job ); - foreach ( const KIO::UDSEntry &entry, list ) { - KUrl url = baseUrl(); - url.setPath( currentCollection().remoteId() + '/' + entry.stringValue( KIO::UDSEntry::UDS_NAME ) ); - Item item; - item.setRemoteId( url.url() ); - item.setMimeType( "message/news" ); - - KMime::NewsArticle *art = new KMime::NewsArticle(); - foreach ( uint field, entry.listFields() ) { - if ( field >= KIO::UDSEntry::UDS_EXTRA && field <= KIO::UDSEntry::UDS_EXTRA_END ) { - const QString value = entry.stringValue( field ); - int pos = value.indexOf( ':' ); - if ( pos >= value.length() - 1 ) - continue; // value is empty - const QString hdrName = value.left( pos ); - const QString hdrValue = value.right( value.length() - ( hdrName.length() + 2 ) ); - - if ( hdrName == "Subject" ) { - art->subject()->from7BitString( hdrValue.toLatin1() ); - if ( art->subject()->isEmpty() ) - art->subject()->fromUnicodeString( i18n( "no subject" ), art->defaultCharset() ); - } else if ( hdrName == "From" ) { - art->from()->from7BitString( hdrValue.toLatin1() ); - } else if ( hdrName == "Date" ) { - art->date()->from7BitString( hdrValue.toLatin1() ); - } else if ( hdrName == "Message-ID" ) { - art->messageID()->from7BitString( hdrValue.simplified().toLatin1() ); - } else if ( hdrName == "References" ) { - if ( !hdrValue.isEmpty() ) - art->references()->from7BitString( hdrValue.toLatin1() ); - } else if ( hdrName == "Lines" ) { - art->lines()->setNumberOfLines( hdrValue.toInt() ); - } else { - // optional extra headers - art->setHeader( new KMime::Headers::Generic( hdrName.toLatin1(), art, hdrValue.toLatin1() ) ); - } - } - } - - item.setPayload( MessagePtr( art ) ); - ItemCreateJob *append = new ItemCreateJob( item, currentCollection() ); - // TODO: check error - Q_UNUSED( append ) - } -} - -void NntpResource::listGroupResult(KJob * job) -{ - if ( job->error() ) { - emit error( job->errorString() ); - } else { - // store last serial number - Collection col = currentCollection(); - NntpCollectionAttribute *attr = col.attribute( Collection::AddIfMissing ); - KIO::Job *j = static_cast( job ); - if ( j->metaData().contains( "LastSerialNumber" ) ) - attr->setLastArticle( j->metaData().value( "LastSerialNumber" ).toInt() ); - CollectionModifyJob *modify = new CollectionModifyJob( col ); - // TODO: check result signal - Q_UNUSED( modify ) - } - - itemsRetrievalDone(); -} - -KUrl NntpResource::baseUrl() const -{ - KUrl url; - if ( Settings::self()->encryption() == Settings::SSL ) - url.setProtocol( "nntps" ); - else - url.setProtocol( "nntp" ); - url.setHost( Settings::self()->server() ); - url.setPort( Settings::self()->port() ); - if ( Settings::self()->requiresAuthentication() ) { - url.setUser( Settings::self()->userName() ); - url.setPass( Settings::self()->password() ); - } - return url; -} - -void NntpResource::fetchArticleResult(KJob * job) -{ - if ( job->error() ) { - emit error( job->errorString() ); - return; - } - KIO::StoredTransferJob *j = static_cast( job ); - KMime::Message *msg = new KMime::Message(); - msg->setContent( KMime::CRLFtoLF( j->data() ) ); - msg->parse(); - Item item = currentItem(); - item.setMimeType( "message/news" ); - item.setPayload( MessagePtr( msg ) ); - itemRetrieved( item ); -} - -void NntpResource::configure( WId windowId ) -{ - ConfigDialog dlg; - if ( windowId ) { - KWindowSystem::setMainWindow( &dlg, windowId ); - } - dlg.setWindowIcon( KIcon( "message-news" ) ); - if ( dlg.exec() ) { - emit configurationDialogAccepted(); - } else { - emit configurationDialogRejected(); - } - - if ( !Settings::self()->name().isEmpty() ) - setName( Settings::self()->name() ); -} - -void NntpResource::setupKioJob(KIO::Job * job) const -{ - Q_ASSERT( job ); - if ( Settings::self()->encryption() == Settings::TLS ) - job->addMetaData( "tls", "on" ); - else - job->addMetaData( "tls", "off" ); - // TODO connect percent and status message signals to something -} - -QString NntpResource::findParent(const QStringList & _path) -{ - QStringList path = _path; - path.removeLast(); - if ( path.isEmpty() ) - return baseUrl().url(); - QString rid = path.join( "." ); - foreach ( const Collection &col, remoteCollections ) - if ( col.remoteId() == rid ) - return col.remoteId(); - Collection parent; - parent.setRemoteId( rid ); - QStringList ct; - ct << Collection::mimeType(); - parent.setContentMimeTypes( ct ); - parent.parentCollection().setRemoteId( findParent( path ) ); - parent.setName( path.last() ); - remoteCollections << parent; - return parent.remoteId(); -} - -void NntpResource::collectionChanged(const Akonadi::Collection & collection) -{ - if ( collection.remoteId() == baseUrl().url() && !collection.name().isEmpty() ) { - Settings::self()->setName( collection.name() ); - setName( collection.name() ); - } - changeCommitted( collection ); -} - -AKONADI_RESOURCE_MAIN( NntpResource ) - diff -Nru kdepim-runtime-4.14.6/resources/nntp/nntpresource.desktop kdepim-runtime-15.08.0/resources/nntp/nntpresource.desktop --- kdepim-runtime-4.14.6/resources/nntp/nntpresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/nntp/nntpresource.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -[Desktop Entry] -Name=Usenet Newsgroups (NNTP) -Name[ar]=المجموعات الإخبارية يوزنت (NNTP) -Name[bs]=Usenet grupe za novosti (NNTP) -Name[ca]=Grups de notícies d'Usenet (NNTP) -Name[ca@valencia]=Grups de notícies d'Usenet (NNTP) -Name[cs]=Diskuzní skupiny (NNTP) -Name[da]=Usenet-nyhedsgrupper (NNTP) -Name[de]=Usenet Newsgruppen (NNTP) -Name[el]=Ομάδες συζήτησης Usenet (NNTP) -Name[en_GB]=Usenet Newsgroups (NNTP) -Name[es]=Grupos de noticias Usenet (NNTP) -Name[et]=Useneti uudistegrupid (NNTP) -Name[fi]=Usenet-keskusteluryhmät (NNTP) -Name[fr]=Forum de discussions « usenet » (NNTP) -Name[ga]=Grúpaí Nuachta Usenet (NNTP) -Name[gl]=Grupos de noticias de Usenet (NNTP) -Name[hu]=Usenet-hírcsoportok (NNTP) -Name[ia]=Gruppos de novas in Usenet (NNTP) -Name[it]=Gruppi di discussione Usenet (NNTP) -Name[ja]=Usenet ニュースグループ (NNTP) -Name[kk]=Usenet жаңалық топтары (NNTP) -Name[km]=Usenet Newsgroups (NNTP) -Name[ko]=유즈넷 뉴스그룹 (NNTP) -Name[lt]=Usenet naujienų grupės (NNTP) -Name[lv]=Usenet interešgrupas (NNTP) -Name[nb]=Njusgrupper (NNTP) -Name[nds]=Usenet-Narichtenkrinken (NNTP) -Name[nl]=Usenet-nieuwsgroepen (NNTP) -Name[nn]=Temagrupper (NNTP) -Name[pl]=Grupy Usenet (NNTP) -Name[pt]=Grupos de Notícias da Usenet (NNTP) -Name[pt_BR]=Grupos de notícias da Usenet (NNTP) -Name[ro]=Grupuri de știri Usenet (NNTP) -Name[ru]=Телеконференции Usenet (NNTP) -Name[sk]=Diskusné skupiny Usenet (NNTP) -Name[sl]=Novičarske skupine (NNTP) -Name[sr]=Јузнетове групе вести (ННТП) -Name[sr@ijekavian]=Јузнетове групе вијести (ННТП) -Name[sr@ijekavianlatin]=Usenetove grupe vijesti (NNTP) -Name[sr@latin]=Usenetove grupe vesti (NNTP) -Name[sv]=Usenet-nyhetsgrupper (NNTP) -Name[tr]=Usenet Haber Grubu (NNTP) -Name[uk]=Групи новин Usenet (NNTP) -Name[x-test]=xxUsenet Newsgroups (NNTP)xx -Name[zh_CN]=Usenet 新闻组(NNTP) -Name[zh_TW]=Usenet 新聞群組(NNTP) -Comment=Makes it possible to read articles from a news server -Comment[ar]=تمكِن قراءة المقالات من خادم الأخبار -Comment[bs]=Omogućava čitanje članaka sa servera novosti -Comment[ca]=Facilita la lectura d'articles des d'un servidor de notícies -Comment[ca@valencia]=Facilita la lectura d'articles des d'un servidor de notícies -Comment[cs]=Umožňuje číst příspěvky z diskuzního serveru -Comment[da]=Muliggør løsning af artikler fra en nyhedsserver -Comment[de]=Lesen von Artikeln von einem News-Server -Comment[el]=Καθιστά δυνατή την ανάγνωση άρθρων από έναν διακομιστή νέων -Comment[en_GB]=Makes it possible to read articles from a news server -Comment[es]=Hace posible leer artículos desde un servidor de noticias -Comment[et]=Võimaldab lugeda artikleid uudisteserverist -Comment[fi]=Mahdollistaa keskusteluryhmäpalvelimen artikkelin lukemisen -Comment[fr]=Permet de lire des articles à partir d'un serveur de nouvelles -Comment[gl]=Permite ler artigos desde un servidor de novas. -Comment[hu]=Híreket tud letölteni NNTP-hírkiszolgálókról -Comment[ia]=Face lo possibile leger articulos de un servitor de novas -Comment[it]=Permette la lettura di articoli da un server di gruppi di discussione -Comment[ja]=ニュースサーバから記事を読めるようにします -Comment[kk]=Жаңалық серверіндегі мақалаларды оқуға мүмкіндік береді -Comment[km]=ធ្វើ​ឲ្យ​អាច​អាន​ចំណងជើង​ពី​ម៉ាស៊ីន​បម្រើ​ព័ត៌មាន​បាន -Comment[ko]=뉴스 서버의 글을 가져옵니다 -Comment[lt]=Sudaro galimybes skaityti straipsnius iš naujienų serverio -Comment[lv]=Ļauj lasīt rakstus no news servera -Comment[nb]=Gjør det mulig å lese artikler fra en newstjener -Comment[nds]=MIt dit Moduul laat sik Artikels vun Narichtenservers lesen -Comment[nl]=Maakt het mogelijk om artikelen van een nieuwsserver te halen -Comment[nn]=Gjer det mogleg å lesa artiklar frå ein temagruppetenar -Comment[pl]=Umożliwia czytanie wiadomości z serwerów niusów -Comment[pt]=Possibilita a leitura de artigos de um servidor de notícias -Comment[pt_BR]=Possibilita a leitura de artigos de um servidor de notícias -Comment[ro]=Face posibilă citirea articolelor de pe un server de știri -Comment[ru]=Чтение статей с серверов телеконференций -Comment[sk]=Umožňuje čítanie článkov zo servera noviniek -Comment[sl]=Omogoča branje sestavkov na strežniku z novičarskimi skupinami -Comment[sr]=Омогућава читање чланака са сервера вести -Comment[sr@ijekavian]=Омогућава читање чланака са сервера вијести -Comment[sr@ijekavianlatin]=Omogućava čitanje članaka sa servera vijesti -Comment[sr@latin]=Omogućava čitanje članaka sa servera vesti -Comment[sv]=Gör det möjligt att läsa artiklar från en nyhetsserver -Comment[tr]=Bir haber sunucusundan haberleri okumak için bir araç -Comment[uk]=Робить можливим читання статей з сервера новин -Comment[x-test]=xxMakes it possible to read articles from a news serverxx -Comment[zh_CN]=可以从新闻组服务器上读取文章 -Comment[zh_TW]=從新聞伺服器讀取文章 -Type=AkonadiResource -Exec=akonadi_nntp_resource -Icon=message-news - -X-Akonadi-MimeTypes=message/news -X-Akonadi-Capabilities=Resource -X-Akonadi-Identifier=akonadi_nntp_resource diff -Nru kdepim-runtime-4.14.6/resources/nntp/nntpresource.h kdepim-runtime-15.08.0/resources/nntp/nntpresource.h --- kdepim-runtime-4.14.6/resources/nntp/nntpresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/nntp/nntpresource.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -/* - Copyright (c) 2007 Volker Krause - - 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_NNTPRESOURCE_H -#define AKONADI_NNTPRESOURCE_H - -#include - -#include -#include - -class NntpResource : public Akonadi::ResourceBase, public Akonadi::AgentBase::Observer -{ - Q_OBJECT - - public: - explicit NntpResource( const QString &id ); - ~NntpResource(); - - public Q_SLOTS: - virtual void configure( WId windowId ); - - protected Q_SLOTS: - void retrieveCollections(); - void retrieveItems( const Akonadi::Collection &col ); - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - - protected: - void collectionChanged( const Akonadi::Collection &collection ); - - private: - /** - Returns the base url used for all KIO operations, containing - protocol, hostname and port. - */ - KUrl baseUrl() const; - - void setupKioJob( KIO::Job *job ) const; - - QString findParent( const QStringList &_path ); - - private slots: - void listGroups( KIO::Job* job, const KIO::UDSEntryList &list ); - void listGroupsResult( KJob* job ); - - void listGroup( KIO::Job* job, const KIO::UDSEntryList &list ); - void listGroupResult( KJob* job ); - - void fetchArticleResult( KJob* job ); - - private: - Akonadi::Collection::List remoteCollections; - - bool mIncremental; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/nntp/nntpresource.kcfg kdepim-runtime-15.08.0/resources/nntp/nntpresource.kcfg --- kdepim-runtime-4.14.6/resources/nntp/nntpresource.kcfg 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/nntp/nntpresource.kcfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ - - - - - - - - - - - - 119 - - - - - None - - - - - - - - - - - - - - - - - - - false - - - - - - - - false - - - - - - - - - 5 - - - - - - - - true - - - - true - - - - true - - - - - - - - - - diff -Nru kdepim-runtime-4.14.6/resources/nntp/settingsbase.kcfgc kdepim-runtime-15.08.0/resources/nntp/settingsbase.kcfgc --- kdepim-runtime-4.14.6/resources/nntp/settingsbase.kcfgc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/nntp/settingsbase.kcfgc 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -File=nntpresource.kcfg -ClassName=SettingsBase -Mutators=true -ItemAccessors=true -SetUserTexts=true -Singleton=false -#IncludeFiles= -GlobalEnums=true diff -Nru kdepim-runtime-4.14.6/resources/nntp/settings.cpp kdepim-runtime-15.08.0/resources/nntp/settings.cpp --- kdepim-runtime-4.14.6/resources/nntp/settings.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/nntp/settings.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 "settings.h" - -#include - -class SettingsHelper -{ - public: - SettingsHelper() : q(0) {} - ~SettingsHelper() { delete q; } - Settings *q; -}; - -K_GLOBAL_STATIC(SettingsHelper, s_globalSettings) - -Settings *Settings::self() -{ - if ( !s_globalSettings->q ) { - new Settings; - s_globalSettings->q->readConfig(); - } - - return s_globalSettings->q; -} - -Settings::Settings() : SettingsBase() -{ - Q_ASSERT( !s_globalSettings->q ); - s_globalSettings->q = this; -} - -QString Settings::password() const -{ - return mPassword; -} - -void Settings::setPassword(const QString & password) -{ - mPassword = password; -} - diff -Nru kdepim-runtime-4.14.6/resources/nntp/settings.h kdepim-runtime-15.08.0/resources/nntp/settings.h --- kdepim-runtime-4.14.6/resources/nntp/settings.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/nntp/settings.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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 SETTINGS_H -#define SETTINGS_H - -#include "settingsbase.h" - -class Settings : public SettingsBase -{ - public: - Settings(); - static Settings *self(); - - // TODO: temporary, wallet support - QString password() const; - void setPassword( const QString &password ); - - private: - QString mPassword; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/openxchange/CMakeLists.txt kdepim-runtime-15.08.0/resources/openxchange/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/openxchange/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,3 +1,6 @@ + +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_openxchange_resource\") + set( openxchangeresource_SRCS oxa/connectiontestjob.cpp oxa/contactutils.cpp @@ -34,27 +37,27 @@ openxchangeresource.cpp ) -kde4_add_ui_files( openxchangeresource_SRCS configdialog.ui ) +ki18n_wrap_ui( openxchangeresource_SRCS configdialog.ui ) -install( FILES openxchangeresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) +install( FILES openxchangeresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) -kde4_add_kcfg_files(openxchangeresource_SRCS settings.kcfgc) +kconfig_add_kcfg_files(openxchangeresource_SRCS settings.kcfgc) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/openxchangeresource.kcfg org.kde.Akonadi.OpenXchange.Settings) -qt4_add_dbus_adaptor(openxchangeresource_SRCS +qt5_add_dbus_adaptor(openxchangeresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.OpenXchange.Settings.xml settings.h Settings ) -kde4_add_executable(akonadi_openxchange_resource RUN_UNINSTALLED ${openxchangeresource_SRCS}) +add_executable(akonadi_openxchange_resource ${openxchangeresource_SRCS}) -if (Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_openxchange_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) set_target_properties(akonadi_openxchange_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.OpenXchange") set_target_properties(akonadi_openxchange_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi OpenXchange Resource") endif () -target_link_libraries(akonadi_openxchange_resource ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_KABC_LIBS} ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} ${KDEPIMLIBS_KCALCORE_LIBS} ${KDEPIMLIBS_AKONADI_CONTACT_LIBS} ) +target_link_libraries(akonadi_openxchange_resource KF5::AkonadiAgentBase KF5::AkonadiCore KF5::Contacts KF5::KIOCore KF5::CalendarCore KF5::AkonadiContact ) -install(TARGETS akonadi_openxchange_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(TARGETS akonadi_openxchange_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) add_subdirectory(icons) diff -Nru kdepim-runtime-4.14.6/resources/openxchange/configdialog.cpp kdepim-runtime-15.08.0/resources/openxchange/configdialog.cpp --- kdepim-runtime-4.14.6/resources/openxchange/configdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/configdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -28,83 +28,101 @@ #include #include #include +#include +#include +#include +#include +#include + +ConfigDialog::ConfigDialog(WId windowId) + : QDialog() +{ + if (windowId) { + KWindowSystem::setMainWindow(this, windowId); + } + + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + QWidget *mainWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); + QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); + okButton->setDefault(true); + okButton->setShortcut(Qt::CTRL | Qt::Key_Return); + QPushButton *user1Button = new QPushButton; + buttonBox->addButton(user1Button, QDialogButtonBox::ActionRole); + connect(buttonBox, &QDialogButtonBox::accepted, this, &ConfigDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &ConfigDialog::reject); + mainLayout->addWidget(buttonBox); + user1Button->setText(i18n("About...")); + + setWindowTitle(i18n("Open-Xchange Configuration")); + + Ui::ConfigDialog ui; + ui.setupUi(mainWidget); + + ui.kcfg_BaseUrl->setWhatsThis(i18n("Enter the http or https URL to your Open-Xchange installation here.")); + ui.kcfg_Username->setWhatsThis(i18n("Enter the username of your Open-Xchange account here.")); + ui.kcfg_Password->setWhatsThis(i18n("Enter the password of your Open-Xchange account here.")); + + mServerEdit = ui.kcfg_BaseUrl; + mUserEdit = ui.kcfg_Username; + mPasswordEdit = ui.kcfg_Password; + mCheckConnectionButton = ui.checkConnectionButton; + + mManager = new KConfigDialogManager(this, Settings::self()); + mManager->updateWidgets(); + + connect(okButton, &QPushButton::clicked, this, &ConfigDialog::save); + connect(user1Button, &QPushButton::clicked, this, &ConfigDialog::showAboutDialog); + connect(mServerEdit, &KLineEdit::textChanged, this, &ConfigDialog::updateButtonState); + connect(mUserEdit, &KLineEdit::textChanged, this, &ConfigDialog::updateButtonState); + connect(mCheckConnectionButton, &QPushButton::clicked, this, &ConfigDialog::checkConnection); -ConfigDialog::ConfigDialog( WId windowId ) - : KDialog() -{ - if ( windowId ) - KWindowSystem::setMainWindow( this, windowId ); - - setButtons( Ok | Cancel | User1 ); - setButtonText( User1, i18n( "About..." ) ); - - setCaption( i18n( "Open-Xchange Configuration" ) ); - - Ui::ConfigDialog ui; - ui.setupUi( mainWidget() ); - - ui.kcfg_BaseUrl->setWhatsThis( i18n( "Enter the http or https URL to your Open-Xchange installation here." ) ); - ui.kcfg_Username->setWhatsThis( i18n( "Enter the username of your Open-Xchange account here." ) ); - ui.kcfg_Password->setWhatsThis( i18n( "Enter the password of your Open-Xchange account here." ) ); - - mServerEdit = ui.kcfg_BaseUrl; - mUserEdit = ui.kcfg_Username; - mPasswordEdit = ui.kcfg_Password; - mCheckConnectionButton = ui.checkConnectionButton; - - mManager = new KConfigDialogManager( this, Settings::self() ); - mManager->updateWidgets(); - - connect( this, SIGNAL(okClicked()), SLOT(save()) ); - connect( this, SIGNAL(user1Clicked()), this, SLOT(showAboutDialog()) ); - connect( mServerEdit, SIGNAL(textChanged(QString)), SLOT(updateButtonState()) ); - connect( mUserEdit, SIGNAL(textChanged(QString)), SLOT(updateButtonState()) ); - connect( mCheckConnectionButton, SIGNAL(clicked()), SLOT(checkConnection()) ); - - setInitialSize( QSize( 410, 200 ) ); + resize(QSize(410, 200)); } void ConfigDialog::save() { - mManager->updateSettings(); - Settings::self()->writeConfig(); + mManager->updateSettings(); + Settings::self()->save(); } void ConfigDialog::showAboutDialog() { - KAboutData aboutData( "ox", "", ki18n( "Open-Xchange" ), "0.1", - ki18n( "Akonadi Open-Xchange Resource" ), - KAboutData::License_LGPL, - ki18n( "(c) 2009 by Tobias Koenig (credativ GmbH)" ) ); - aboutData.addAuthor( ki18n( "Tobias Koenig" ), ki18n( "Current maintainer" ), "tokoe@kde.org" ); - aboutData.addCredit( ki18n( "credativ GmbH" ), ki18n( "Funded and supported" ), 0, "http://www.credativ.com" ); + KAboutData aboutData(QStringLiteral("ox"), i18n("Open-Xchange"), QStringLiteral("0.1"), + i18n("Akonadi Open-Xchange Resource"), + KAboutLicense::LGPL, + i18n("(c) 2009 by Tobias Koenig (credativ GmbH)")); + aboutData.addAuthor(i18n("Tobias Koenig"), i18n("Current maintainer"), QStringLiteral("tokoe@kde.org")); + aboutData.addCredit(i18n("credativ GmbH"), i18n("Funded and supported"), QStringLiteral("http://www.credativ.com")); - KAboutApplicationDialog dlg( &aboutData, this ); - dlg.exec(); + KAboutApplicationDialog dlg(aboutData, this); + dlg.exec(); } void ConfigDialog::updateButtonState() { - mCheckConnectionButton->setEnabled( !mServerEdit->text().isEmpty() && !mUserEdit->text().isEmpty() ); + mCheckConnectionButton->setEnabled(!mServerEdit->text().isEmpty() && !mUserEdit->text().isEmpty()); } void ConfigDialog::checkConnection() { - OXA::ConnectionTestJob *job = new OXA::ConnectionTestJob( mServerEdit->text(), mUserEdit->text(), - mPasswordEdit->text(), this ); - connect( job, SIGNAL(result(KJob*)), SLOT(checkConnectionJobFinished(KJob*)) ); - job->start(); + OXA::ConnectionTestJob *job = new OXA::ConnectionTestJob(mServerEdit->text(), mUserEdit->text(), + mPasswordEdit->text(), this); + connect(job, &OXA::ConnectionTestJob::result, this, &ConfigDialog::checkConnectionJobFinished); + job->start(); - QApplication::setOverrideCursor( Qt::WaitCursor ); + QApplication::setOverrideCursor(Qt::WaitCursor); } -void ConfigDialog::checkConnectionJobFinished( KJob *job ) +void ConfigDialog::checkConnectionJobFinished(KJob *job) { - QApplication::restoreOverrideCursor(); + QApplication::restoreOverrideCursor(); - if ( job->error() ) { - KMessageBox::error( this, i18n( "Unable to connect: %1", job->errorText() ), i18n( "Connection error" ) ); - } else { - KMessageBox::information( this, i18n( "Tested connection successfully." ), i18n( "Connection success" ) ); - } + if (job->error()) { + KMessageBox::error(this, i18n("Unable to connect: %1", job->errorText()), i18n("Connection error")); + } else { + KMessageBox::information(this, i18n("Tested connection successfully."), i18n("Connection success")); + } } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/configdialog.h kdepim-runtime-15.08.0/resources/openxchange/configdialog.h --- kdepim-runtime-4.14.6/resources/openxchange/configdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/configdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,27 +20,27 @@ #ifndef CONFIGDIALOG_H #define CONFIGDIALOG_H -#include +#include class KConfigDialogManager; class KJob; class KLineEdit; -class ConfigDialog : public KDialog +class ConfigDialog : public QDialog { - Q_OBJECT + Q_OBJECT - public: - explicit ConfigDialog( WId windowId ); +public: + explicit ConfigDialog(WId windowId); - private Q_SLOTS: +private Q_SLOTS: void save(); void showAboutDialog(); void updateButtonState(); void checkConnection(); - void checkConnectionJobFinished( KJob* ); + void checkConnectionJobFinished(KJob *); - private: +private: KConfigDialogManager *mManager; KLineEdit *mServerEdit; KLineEdit *mUserEdit; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/configdialog.ui kdepim-runtime-15.08.0/resources/openxchange/configdialog.ui --- kdepim-runtime-4.14.6/resources/openxchange/configdialog.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/configdialog.ui 2015-08-10 21:01:02.000000000 +0000 @@ -50,7 +50,7 @@ The URL of the Open-Xchange server, should be something like https://myserver.org/ - + https://myserver.org
Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/openxchange/icons/128-apps-ox.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/openxchange/icons/128-apps-ox.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/openxchange/icons/16-apps-ox.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/openxchange/icons/16-apps-ox.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/openxchange/icons/32-apps-ox.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/openxchange/icons/32-apps-ox.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/openxchange/icons/48-apps-ox.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/openxchange/icons/48-apps-ox.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/openxchange/icons/64-apps-ox.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/openxchange/icons/64-apps-ox.png differ diff -Nru kdepim-runtime-4.14.6/resources/openxchange/icons/CMakeLists.txt kdepim-runtime-15.08.0/resources/openxchange/icons/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/openxchange/icons/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/icons/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1 +1 @@ -kde4_install_icons(${ICON_INSTALL_DIR}) +ecm_install_icons(ICONS 128-apps-ox.png 16-apps-ox.png 32-apps-ox.png 48-apps-ox.png 64-apps-ox.png DESTINATION ${KDE_INSTALL_ICONDIR} THEME hicolor) Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/openxchange/icons/hi128-app-ox.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/openxchange/icons/hi128-app-ox.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/openxchange/icons/hi16-app-ox.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/openxchange/icons/hi16-app-ox.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/openxchange/icons/hi32-app-ox.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/openxchange/icons/hi32-app-ox.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/openxchange/icons/hi48-app-ox.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/openxchange/icons/hi48-app-ox.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resources/openxchange/icons/hi64-app-ox.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resources/openxchange/icons/hi64-app-ox.png differ diff -Nru kdepim-runtime-4.14.6/resources/openxchange/openxchangeresource.cpp kdepim-runtime-15.08.0/resources/openxchange/openxchangeresource.cpp --- kdepim-runtime-4.14.6/resources/openxchange/openxchangeresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/openxchangeresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,18 +22,18 @@ #include "configdialog.h" #include "settingsadaptor.h" -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include -#include +#include #include #include -#include -#include +#include #include #include @@ -52,82 +52,93 @@ #include #include #include +#include +#include using namespace Akonadi; class RemoteInformation { - public: - RemoteInformation( qlonglong objectId, OXA::Folder::Module module, const QString &lastModified ) - : mObjectId( objectId ), - mModule( module ), - mLastModified( lastModified ) +public: + RemoteInformation(qlonglong objectId, OXA::Folder::Module module, const QString &lastModified) + : mObjectId(objectId), + mModule(module), + mLastModified(lastModified) { } inline qlonglong objectId() const { - return mObjectId; + return mObjectId; } inline OXA::Folder::Module module() const { - return mModule; + return mModule; } inline QString lastModified() const { - return mLastModified; + return mLastModified; } - inline void setLastModified( const QString &lastModified ) + inline void setLastModified(const QString &lastModified) { - mLastModified = lastModified; + mLastModified = lastModified; } - static RemoteInformation load( const Entity &entity ) + static RemoteInformation load(const Entity &entity) { - const QStringList parts = entity.remoteRevision().split( QLatin1Char( ':' ), QString::KeepEmptyParts ); + const QStringList parts = entity.remoteRevision().split(QLatin1Char(':'), QString::KeepEmptyParts); - OXA::Folder::Module module = OXA::Folder::Unbound; + OXA::Folder::Module module = OXA::Folder::Unbound; - if ( parts.count() > 0 ) { - if ( parts.at( 0 ) == QLatin1String( "calendar" ) ) - module = OXA::Folder::Calendar; - else if ( parts.at( 0 ) == QLatin1String( "contacts" ) ) - module = OXA::Folder::Contacts; - else if ( parts.at( 0 ) == QLatin1String( "tasks" ) ) - module = OXA::Folder::Tasks; - else - module = OXA::Folder::Unbound; - } + if (parts.count() > 0) { + if (parts.at(0) == QLatin1String("calendar")) { + module = OXA::Folder::Calendar; + } else if (parts.at(0) == QLatin1String("contacts")) { + module = OXA::Folder::Contacts; + } else if (parts.at(0) == QLatin1String("tasks")) { + module = OXA::Folder::Tasks; + } else { + module = OXA::Folder::Unbound; + } + } - QString lastModified = QLatin1String( "0" ); - if ( parts.count() > 1 ) - lastModified = parts.at( 1 ); + QString lastModified = QLatin1String("0"); + if (parts.count() > 1) { + lastModified = parts.at(1); + } - return RemoteInformation( entity.remoteId().toLongLong(), module, lastModified ); + return RemoteInformation(entity.remoteId().toLongLong(), module, lastModified); } - void store( Entity &entity ) const + void store(Entity &entity) const { - QString module; - switch ( mModule ) { - case OXA::Folder::Calendar: module = QLatin1String( "calendar" ); break; - case OXA::Folder::Contacts: module = QLatin1String( "contacts" ); break; - case OXA::Folder::Tasks: module = QLatin1String( "tasks" ); break; - case OXA::Folder::Unbound: break; - } - - QStringList parts; - parts.append( module ); - parts.append( mLastModified ); + QString module; + switch (mModule) { + case OXA::Folder::Calendar: + module = QStringLiteral("calendar"); + break; + case OXA::Folder::Contacts: + module = QStringLiteral("contacts"); + break; + case OXA::Folder::Tasks: + module = QStringLiteral("tasks"); + break; + case OXA::Folder::Unbound: + break; + } - entity.setRemoteId( QString::number( mObjectId ) ); - entity.setRemoteRevision( parts.join( QLatin1String( ":" ) ) ); + QStringList parts; + parts.append(module); + parts.append(mLastModified); + + entity.setRemoteId(QString::number(mObjectId)); + entity.setRemoteRevision(parts.join(QLatin1String(":"))); } - private: +private: qlonglong mObjectId; OXA::Folder::Module mModule; QString mLastModified; @@ -135,168 +146,171 @@ class ObjectsLastSync { - public: +public: ObjectsLastSync() { - if ( !Settings::self()->objectsLastSync().isEmpty() ) { - const QStringList pairs = Settings::self()->objectsLastSync().split( QLatin1Char( ':' ), QString::KeepEmptyParts ); - foreach ( const QString &pair, pairs ) { - const QStringList entry = pair.split( QLatin1Char( '=' ), QString::KeepEmptyParts ); - mObjectsMap.insert( entry.at( 0 ).toLongLong(), entry.at( 1 ).toULongLong() ); + if (!Settings::self()->objectsLastSync().isEmpty()) { + const QStringList pairs = Settings::self()->objectsLastSync().split(QLatin1Char(':'), QString::KeepEmptyParts); + foreach (const QString &pair, pairs) { + const QStringList entry = pair.split(QLatin1Char('='), QString::KeepEmptyParts); + mObjectsMap.insert(entry.at(0).toLongLong(), entry.at(1).toULongLong()); + } } - } } void save() { - QStringList pairs; + QStringList pairs; + pairs.reserve(mObjectsMap.count()); - QMapIterator it( mObjectsMap ); - while ( it.hasNext() ) { - it.next(); - pairs.append( QString::number( it.key() ) + QLatin1Char( '=' ) + QString::number( it.value() ) ); - } + QMapIterator it(mObjectsMap); + while (it.hasNext()) { + it.next(); + pairs.append(QString::number(it.key()) + QLatin1Char('=') + QString::number(it.value())); + } - Settings::self()->setObjectsLastSync( pairs.join( QLatin1String( ":" ) ) ); - Settings::self()->writeConfig(); + Settings::self()->setObjectsLastSync(pairs.join(QLatin1String(":"))); + Settings::self()->save(); } - qulonglong lastSync( qlonglong collectionId ) const + qulonglong lastSync(qlonglong collectionId) const { - if ( !mObjectsMap.contains( collectionId ) ) - return 0; + if (!mObjectsMap.contains(collectionId)) { + return 0; + } - return mObjectsMap.value( collectionId ); + return mObjectsMap.value(collectionId); } - void setLastSync( qlonglong collectionId, qulonglong timeStamp ) + void setLastSync(qlonglong collectionId, qulonglong timeStamp) { - mObjectsMap.insert( collectionId, timeStamp ); + mObjectsMap.insert(collectionId, timeStamp); } - private: +private: QMap mObjectsMap; }; -static Collection::Rights folderPermissionsToCollectionRights( const OXA::Folder &folder ) +static Collection::Rights folderPermissionsToCollectionRights(const OXA::Folder &folder) { - const OXA::Folder::UserPermissions userPermissions = folder.userPermissions(); + const OXA::Folder::UserPermissions userPermissions = folder.userPermissions(); - if ( !userPermissions.contains( OXA::Users::self()->currentUserId() ) ) { - // There are no rights given for us explicitly, so it is read-only - return Collection::ReadOnly; - } else { - const OXA::Folder::Permissions permissions = userPermissions.value( OXA::Users::self()->currentUserId() ); - Collection::Rights rights = Collection::ReadOnly; - switch ( permissions.folderPermission() ) { - case OXA::Folder::Permissions::FolderIsVisible: rights |= Collection::ReadOnly; break; - case OXA::Folder::Permissions::CreateObjects: rights |= Collection::CanCreateItem; break; - case OXA::Folder::Permissions::CreateSubfolders: // fallthrough - case OXA::Folder::Permissions::AdminPermission: rights |= (Collection::CanCreateItem | Collection::CanCreateCollection); break; - default: break; - } - - if ( permissions.objectWritePermission() != OXA::Folder::Permissions::NoWritePermission ) { - rights |= Collection::CanChangeItem; - rights |= Collection::CanChangeCollection; - } - - if ( permissions.objectDeletePermission() != OXA::Folder::Permissions::NoDeletePermission ) { - rights |= Collection::CanDeleteItem; - rights |= Collection::CanDeleteCollection; - } - - return rights; - } -} - -OpenXchangeResource::OpenXchangeResource( const QString &id ) - : ResourceBase( id ) -{ - // setup the resource - new SettingsAdaptor( Settings::self() ); - QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ), - Settings::self(), QDBusConnection::ExportAdaptors ); - - changeRecorder()->fetchCollection( true ); - changeRecorder()->itemFetchScope().fetchFullPayload( true ); - changeRecorder()->itemFetchScope().setAncestorRetrieval( ItemFetchScope::Parent ); - changeRecorder()->collectionFetchScope().setAncestorRetrieval( CollectionFetchScope::Parent ); - - setName( i18n( "Open-Xchange" ) ); - - OXA::Users::self()->init( identifier() ); - - KUrl baseUrl = Settings::self()->baseUrl(); - baseUrl.setUserName( Settings::self()->username() ); - baseUrl.setPassword( Settings::self()->password() ); - OXA::DavManager::self()->setBaseUrl( baseUrl ); - - // Create the standard collections. - // - // There exists special OX folders (e.g. private, public, shared) that are not - // returned by a normal webdav listing, therefor we create them manually here. - // This is possible because the remote ids of these folders are fixed values from 1 - // till 4. - mResourceCollection.setParentCollection( Collection::root() ); - const RemoteInformation resourceInformation( 0, OXA::Folder::Unbound, QString() ); - resourceInformation.store( mResourceCollection ); - mResourceCollection.setName( name() ); - mResourceCollection.setContentMimeTypes( QStringList() << Collection::mimeType() ); - mResourceCollection.setRights( Collection::ReadOnly ); - EntityDisplayAttribute *attribute = mResourceCollection.attribute( Collection::AddIfMissing ); - attribute->setIconName( QLatin1String( "ox" ) ); - - Collection privateFolder; - privateFolder.setParentCollection( mResourceCollection ); - const RemoteInformation privateFolderInformation( 1, OXA::Folder::Unbound, QString() ); - privateFolderInformation.store( privateFolder ); - privateFolder.setName( i18n( "Private Folder" ) ); - privateFolder.setContentMimeTypes( QStringList() << Collection::mimeType() ); - privateFolder.setRights( Collection::ReadOnly ); - - Collection publicFolder; - publicFolder.setParentCollection( mResourceCollection ); - const RemoteInformation publicFolderInformation( 2, OXA::Folder::Unbound, QString() ); - publicFolderInformation.store( publicFolder ); - publicFolder.setName( i18n( "Public Folder" ) ); - publicFolder.setContentMimeTypes( QStringList() << Collection::mimeType() ); - publicFolder.setRights( Collection::ReadOnly ); - - Collection sharedFolder; - sharedFolder.setParentCollection( mResourceCollection ); - const RemoteInformation sharedFolderInformation( 3, OXA::Folder::Unbound, QString() ); - sharedFolderInformation.store( sharedFolder ); - sharedFolder.setName( i18n( "Shared Folder" ) ); - sharedFolder.setContentMimeTypes( QStringList() << Collection::mimeType() ); - sharedFolder.setRights( Collection::ReadOnly ); - - Collection systemFolder; - systemFolder.setParentCollection( mResourceCollection ); - const RemoteInformation systemFolderInformation( 4, OXA::Folder::Unbound, QString() ); - systemFolderInformation.store( systemFolder ); - systemFolder.setName( i18n( "System Folder" ) ); - systemFolder.setContentMimeTypes( QStringList() << Collection::mimeType() ); - systemFolder.setRights( Collection::ReadOnly ); - - // TODO: set cache policy depending on sync behaviour - Akonadi::CachePolicy cachePolicy; - cachePolicy.setInheritFromParent( false ); - cachePolicy.setSyncOnDemand( false ); - cachePolicy.setCacheTimeout( -1 ); - cachePolicy.setIntervalCheckTime( 5 ); - mResourceCollection.setCachePolicy( cachePolicy ); - - mStandardCollectionsMap.insert( 0, mResourceCollection ); - mStandardCollectionsMap.insert( 1, privateFolder ); - mStandardCollectionsMap.insert( 2, publicFolder ); - mStandardCollectionsMap.insert( 3, sharedFolder ); - mStandardCollectionsMap.insert( 4, systemFolder ); + if (!userPermissions.contains(OXA::Users::self()->currentUserId())) { + // There are no rights given for us explicitly, so it is read-only + return Collection::ReadOnly; + } else { + const OXA::Folder::Permissions permissions = userPermissions.value(OXA::Users::self()->currentUserId()); + Collection::Rights rights = Collection::ReadOnly; + switch (permissions.folderPermission()) { + case OXA::Folder::Permissions::FolderIsVisible: rights |= Collection::ReadOnly; break; + case OXA::Folder::Permissions::CreateObjects: rights |= Collection::CanCreateItem; break; + case OXA::Folder::Permissions::CreateSubfolders: // fallthrough + case OXA::Folder::Permissions::AdminPermission: rights |= (Collection::CanCreateItem | Collection::CanCreateCollection); break; + default: break; + } - mCollectionsMap = mStandardCollectionsMap; + if (permissions.objectWritePermission() != OXA::Folder::Permissions::NoWritePermission) { + rights |= Collection::CanChangeItem; + rights |= Collection::CanChangeCollection; + } - if ( Settings::self()->useIncrementalUpdates() ) - syncCollectionsRemoteIdCache(); + if (permissions.objectDeletePermission() != OXA::Folder::Permissions::NoDeletePermission) { + rights |= Collection::CanDeleteItem; + rights |= Collection::CanDeleteCollection; + } + + return rights; + } +} + +OpenXchangeResource::OpenXchangeResource(const QString &id) + : ResourceBase(id) +{ + // setup the resource + new SettingsAdaptor(Settings::self()); + QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"), + Settings::self(), QDBusConnection::ExportAdaptors); + + changeRecorder()->fetchCollection(true); + changeRecorder()->itemFetchScope().fetchFullPayload(true); + changeRecorder()->itemFetchScope().setAncestorRetrieval(ItemFetchScope::Parent); + changeRecorder()->collectionFetchScope().setAncestorRetrieval(CollectionFetchScope::Parent); + + setName(i18n("Open-Xchange")); + + OXA::Users::self()->init(identifier()); + + QUrl baseUrl = QUrl::fromLocalFile(Settings::self()->baseUrl()); + baseUrl.setUserName(Settings::self()->username()); + baseUrl.setPassword(Settings::self()->password()); + OXA::DavManager::self()->setBaseUrl(baseUrl); + + // Create the standard collections. + // + // There exists special OX folders (e.g. private, public, shared) that are not + // returned by a normal webdav listing, therefor we create them manually here. + // This is possible because the remote ids of these folders are fixed values from 1 + // till 4. + mResourceCollection.setParentCollection(Collection::root()); + const RemoteInformation resourceInformation(0, OXA::Folder::Unbound, QString()); + resourceInformation.store(mResourceCollection); + mResourceCollection.setName(name()); + mResourceCollection.setContentMimeTypes(QStringList() << Collection::mimeType()); + mResourceCollection.setRights(Collection::ReadOnly); + EntityDisplayAttribute *attribute = mResourceCollection.attribute(Collection::AddIfMissing); + attribute->setIconName(QLatin1String("ox")); + + Collection privateFolder; + privateFolder.setParentCollection(mResourceCollection); + const RemoteInformation privateFolderInformation(1, OXA::Folder::Unbound, QString()); + privateFolderInformation.store(privateFolder); + privateFolder.setName(i18n("Private Folder")); + privateFolder.setContentMimeTypes(QStringList() << Collection::mimeType()); + privateFolder.setRights(Collection::ReadOnly); + + Collection publicFolder; + publicFolder.setParentCollection(mResourceCollection); + const RemoteInformation publicFolderInformation(2, OXA::Folder::Unbound, QString()); + publicFolderInformation.store(publicFolder); + publicFolder.setName(i18n("Public Folder")); + publicFolder.setContentMimeTypes(QStringList() << Collection::mimeType()); + publicFolder.setRights(Collection::ReadOnly); + + Collection sharedFolder; + sharedFolder.setParentCollection(mResourceCollection); + const RemoteInformation sharedFolderInformation(3, OXA::Folder::Unbound, QString()); + sharedFolderInformation.store(sharedFolder); + sharedFolder.setName(i18n("Shared Folder")); + sharedFolder.setContentMimeTypes(QStringList() << Collection::mimeType()); + sharedFolder.setRights(Collection::ReadOnly); + + Collection systemFolder; + systemFolder.setParentCollection(mResourceCollection); + const RemoteInformation systemFolderInformation(4, OXA::Folder::Unbound, QString()); + systemFolderInformation.store(systemFolder); + systemFolder.setName(i18n("System Folder")); + systemFolder.setContentMimeTypes(QStringList() << Collection::mimeType()); + systemFolder.setRights(Collection::ReadOnly); + + // TODO: set cache policy depending on sync behaviour + Akonadi::CachePolicy cachePolicy; + cachePolicy.setInheritFromParent(false); + cachePolicy.setSyncOnDemand(false); + cachePolicy.setCacheTimeout(-1); + cachePolicy.setIntervalCheckTime(5); + mResourceCollection.setCachePolicy(cachePolicy); + + mStandardCollectionsMap.insert(0, mResourceCollection); + mStandardCollectionsMap.insert(1, privateFolder); + mStandardCollectionsMap.insert(2, publicFolder); + mStandardCollectionsMap.insert(3, sharedFolder); + mStandardCollectionsMap.insert(4, systemFolder); + + mCollectionsMap = mStandardCollectionsMap; + + if (Settings::self()->useIncrementalUpdates()) { + syncCollectionsRemoteIdCache(); + } } OpenXchangeResource::~OpenXchangeResource() @@ -305,798 +319,801 @@ void OpenXchangeResource::cleanup() { - // be nice and remove cache file when resource is removed - QFile::remove( OXA::Users::self()->cacheFilePath() ); + // be nice and remove cache file when resource is removed + QFile::remove(OXA::Users::self()->cacheFilePath()); - QFile::remove( KStandardDirs::locateLocal( "config", Settings::self()->config()->name() ) ); + QFile::remove(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + Settings::self()->config()->name()) ; - ResourceBase::cleanup(); + ResourceBase::cleanup(); } void OpenXchangeResource::aboutToQuit() { } -void OpenXchangeResource::configure( WId windowId ) +void OpenXchangeResource::configure(WId windowId) { - const bool useIncrementalUpdates = Settings::self()->useIncrementalUpdates(); - - ConfigDialog dlg( windowId ); - dlg.setWindowIcon( KIcon( "ox" ) ); - if ( dlg.exec() ) { //krazy:exclude=crashy - - // if the user has changed the incremental update settings we have to do - // some additional initialization work - if ( useIncrementalUpdates != Settings::self()->useIncrementalUpdates() ) { - Settings::self()->setFoldersLastSync( 0 ); - Settings::self()->setObjectsLastSync( QString() ); - } + const bool useIncrementalUpdates = Settings::self()->useIncrementalUpdates(); - Settings::self()->writeConfig(); + ConfigDialog dlg(windowId); + dlg.setWindowIcon(QIcon::fromTheme("ox")); + if (dlg.exec()) { //krazy:exclude=crashy + + // if the user has changed the incremental update settings we have to do + // some additional initialization work + if (useIncrementalUpdates != Settings::self()->useIncrementalUpdates()) { + Settings::self()->setFoldersLastSync(0); + Settings::self()->setObjectsLastSync(QString()); + } - clearCache(); + Settings::self()->save(); - KUrl baseUrl = Settings::self()->baseUrl(); - baseUrl.setUserName( Settings::self()->username() ); - baseUrl.setPassword( Settings::self()->password() ); - OXA::DavManager::self()->setBaseUrl( baseUrl ); + clearCache(); - // To find out the correct ACLs we need the uid of the user that - // logs in. For loading events and tasks we need a complete mapping of - // user id to name as well, so the mapping must be loaded as well. - // Both is done by UpdateUsersJob, so trigger it here before we continue - // with synchronization in onUpdateUsersJobFinished. - OXA::UpdateUsersJob *job = new OXA::UpdateUsersJob( this ); - connect( job, SIGNAL(result(KJob*)), SLOT(onUpdateUsersJobFinished(KJob*)) ); - job->start(); - } else { - emit configurationDialogRejected(); - } + QUrl baseUrl = QUrl::fromLocalFile(Settings::self()->baseUrl()); + baseUrl.setUserName(Settings::self()->username()); + baseUrl.setPassword(Settings::self()->password()); + OXA::DavManager::self()->setBaseUrl(baseUrl); + + // To find out the correct ACLs we need the uid of the user that + // logs in. For loading events and tasks we need a complete mapping of + // user id to name as well, so the mapping must be loaded as well. + // Both is done by UpdateUsersJob, so trigger it here before we continue + // with synchronization in onUpdateUsersJobFinished. + OXA::UpdateUsersJob *job = new OXA::UpdateUsersJob(this); + connect(job, &OXA::UpdateUsersJob::result, this, &OpenXchangeResource::onUpdateUsersJobFinished); + job->start(); + } else { + Q_EMIT configurationDialogRejected(); + } } void OpenXchangeResource::retrieveCollections() { - //qDebug("tokoe: retrieve collections called"); - if ( Settings::self()->useIncrementalUpdates() ) { - //qDebug( "lastSync=%llu", Settings::self()->foldersLastSync() ); - OXA::FoldersRequestDeltaJob *job = new OXA::FoldersRequestDeltaJob( Settings::self()->foldersLastSync(), this ); - connect( job, SIGNAL(result(KJob*)), SLOT(onFoldersRequestDeltaJobFinished(KJob*)) ); - job->start(); - } else { - OXA::FoldersRequestJob *job = new OXA::FoldersRequestJob( 0, OXA::FoldersRequestJob::Modified, this ); - connect( job, SIGNAL(result(KJob*)), SLOT(onFoldersRequestJobFinished(KJob*)) ); - job->start(); - } + //qDebug("tokoe: retrieve collections called"); + if (Settings::self()->useIncrementalUpdates()) { + //qDebug( "lastSync=%llu", Settings::self()->foldersLastSync() ); + OXA::FoldersRequestDeltaJob *job = new OXA::FoldersRequestDeltaJob(Settings::self()->foldersLastSync(), this); + connect(job, &OXA::UpdateUsersJob::result, this, &OpenXchangeResource::onFoldersRequestDeltaJobFinished); + job->start(); + } else { + OXA::FoldersRequestJob *job = new OXA::FoldersRequestJob(0, OXA::FoldersRequestJob::Modified, this); + connect(job, &OXA::UpdateUsersJob::result, this, &OpenXchangeResource::onFoldersRequestJobFinished); + job->start(); + } } -void OpenXchangeResource::retrieveItems( const Akonadi::Collection &collection ) +void OpenXchangeResource::retrieveItems(const Akonadi::Collection &collection) { - //qDebug( "tokoe: retrieveItems on %s called", qPrintable( collection.name() ) ); - const RemoteInformation remoteInformation = RemoteInformation::load( collection ); + //qDebug( "tokoe: retrieveItems on %s called", qPrintable( collection.name() ) ); + const RemoteInformation remoteInformation = RemoteInformation::load(collection); - OXA::Folder folder; - folder.setObjectId( remoteInformation.objectId() ); - folder.setModule( remoteInformation.module() ); - - if ( Settings::self()->useIncrementalUpdates() ) { - ObjectsLastSync lastSyncInfo; - //qDebug( "lastSync=%llu", lastSyncInfo.lastSync( collection.id() ) ); - OXA::ObjectsRequestDeltaJob *job = new OXA::ObjectsRequestDeltaJob( folder, lastSyncInfo.lastSync( collection.id() ), this ); - job->setProperty( "collection", QVariant::fromValue( collection ) ); - connect( job, SIGNAL(result(KJob*)), SLOT(onObjectsRequestDeltaJobFinished(KJob*)) ); - job->start(); - } else { - OXA::ObjectsRequestJob *job = new OXA::ObjectsRequestJob( folder, 0, OXA::ObjectsRequestJob::Modified, this ); - connect( job, SIGNAL(result(KJob*)), SLOT(onObjectsRequestJobFinished(KJob*)) ); - job->start(); - } + OXA::Folder folder; + folder.setObjectId(remoteInformation.objectId()); + folder.setModule(remoteInformation.module()); + + if (Settings::self()->useIncrementalUpdates()) { + ObjectsLastSync lastSyncInfo; + //qDebug( "lastSync=%llu", lastSyncInfo.lastSync( collection.id() ) ); + OXA::ObjectsRequestDeltaJob *job = new OXA::ObjectsRequestDeltaJob(folder, lastSyncInfo.lastSync(collection.id()), this); + job->setProperty("collection", QVariant::fromValue(collection)); + connect(job, &OXA::UpdateUsersJob::result, this, &OpenXchangeResource::onObjectsRequestDeltaJobFinished); + job->start(); + } else { + OXA::ObjectsRequestJob *job = new OXA::ObjectsRequestJob(folder, 0, OXA::ObjectsRequestJob::Modified, this); + connect(job, &OXA::UpdateUsersJob::result, this, &OpenXchangeResource::onObjectsRequestJobFinished); + job->start(); + } } -bool OpenXchangeResource::retrieveItem( const Akonadi::Item &item, const QSet& ) +bool OpenXchangeResource::retrieveItem(const Akonadi::Item &item, const QSet &) { - //qDebug( "tokoe: retrieveItem %lld called", item.id() ); - const RemoteInformation remoteInformation = RemoteInformation::load( item ); + //qDebug( "tokoe: retrieveItem %lld called", item.id() ); + const RemoteInformation remoteInformation = RemoteInformation::load(item); - OXA::Object object; - object.setObjectId( remoteInformation.objectId() ); - object.setModule( remoteInformation.module() ); - - OXA::ObjectRequestJob *job = new OXA::ObjectRequestJob( object, this ); - job->setProperty( "item", QVariant::fromValue( item ) ); - connect( job, SIGNAL(result(KJob*)), SLOT(onObjectRequestJobFinished(KJob*)) ); - job->start(); + OXA::Object object; + object.setObjectId(remoteInformation.objectId()); + object.setModule(remoteInformation.module()); + + OXA::ObjectRequestJob *job = new OXA::ObjectRequestJob(object, this); + job->setProperty("item", QVariant::fromValue(item)); + connect(job, &OXA::UpdateUsersJob::result, this, &OpenXchangeResource::onObjectRequestJobFinished); + job->start(); - return true; + return true; } -void OpenXchangeResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ) +void OpenXchangeResource::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) { - const RemoteInformation remoteInformation = RemoteInformation::load( collection ); + const RemoteInformation remoteInformation = RemoteInformation::load(collection); - OXA::Object object; - object.setFolderId( remoteInformation.objectId() ); - object.setModule( remoteInformation.module() ); + OXA::Object object; + object.setFolderId(remoteInformation.objectId()); + object.setModule(remoteInformation.module()); - if ( item.hasPayload() ) { - object.setContact( item.payload() ); - } else if ( item.hasPayload() ) { - object.setContactGroup( item.payload() ); - } else if ( item.hasPayload() ) { - object.setEvent( item.payload() ); - } else if ( item.hasPayload() ) { - object.setTask( item.payload() ); - } else { - Q_ASSERT( false ); - } + if (item.hasPayload()) { + object.setContact(item.payload()); + } else if (item.hasPayload()) { + object.setContactGroup(item.payload()); + } else if (item.hasPayload()) { + object.setEvent(item.payload()); + } else if (item.hasPayload()) { + object.setTask(item.payload()); + } else { + Q_ASSERT(false); + } - OXA::ObjectCreateJob *job = new OXA::ObjectCreateJob( object, this ); - job->setProperty( "item", QVariant::fromValue( item ) ); - connect( job, SIGNAL(result(KJob*)), SLOT(onObjectCreateJobFinished(KJob*)) ); - job->start(); + OXA::ObjectCreateJob *job = new OXA::ObjectCreateJob(object, this); + job->setProperty("item", QVariant::fromValue(item)); + connect(job, &OXA::UpdateUsersJob::result, this, &OpenXchangeResource::onObjectCreateJobFinished); + job->start(); } -void OpenXchangeResource::itemChanged( const Akonadi::Item &item, const QSet& ) +void OpenXchangeResource::itemChanged(const Akonadi::Item &item, const QSet &) { - const RemoteInformation remoteInformation = RemoteInformation::load( item ); - const RemoteInformation parentRemoteInformation = RemoteInformation::load( item.parentCollection() ); - - OXA::Object object; - object.setObjectId( remoteInformation.objectId() ); - object.setModule( remoteInformation.module() ); - object.setFolderId( parentRemoteInformation.objectId() ); - object.setLastModified( remoteInformation.lastModified() ); + const RemoteInformation remoteInformation = RemoteInformation::load(item); + const RemoteInformation parentRemoteInformation = RemoteInformation::load(item.parentCollection()); - if ( item.hasPayload() ) { - object.setContact( item.payload() ); - } else if ( item.hasPayload() ) { - object.setContactGroup( item.payload() ); - } else if ( item.hasPayload() ) { - object.setEvent( item.payload() ); - } else if ( item.hasPayload() ) { - object.setTask( item.payload() ); - } else { - Q_ASSERT( false ); - } + OXA::Object object; + object.setObjectId(remoteInformation.objectId()); + object.setModule(remoteInformation.module()); + object.setFolderId(parentRemoteInformation.objectId()); + object.setLastModified(remoteInformation.lastModified()); + + if (item.hasPayload()) { + object.setContact(item.payload()); + } else if (item.hasPayload()) { + object.setContactGroup(item.payload()); + } else if (item.hasPayload()) { + object.setEvent(item.payload()); + } else if (item.hasPayload()) { + object.setTask(item.payload()); + } else { + Q_ASSERT(false); + } - OXA::ObjectModifyJob *job = new OXA::ObjectModifyJob( object, this ); - job->setProperty( "item", QVariant::fromValue( item ) ); - connect( job, SIGNAL(result(KJob*)), SLOT(onObjectModifyJobFinished(KJob*)) ); - job->start(); + OXA::ObjectModifyJob *job = new OXA::ObjectModifyJob(object, this); + job->setProperty("item", QVariant::fromValue(item)); + connect(job, &OXA::UpdateUsersJob::result, this, &OpenXchangeResource::onObjectModifyJobFinished); + job->start(); } -void OpenXchangeResource::itemRemoved( const Akonadi::Item &item ) +void OpenXchangeResource::itemRemoved(const Akonadi::Item &item) { - const RemoteInformation remoteInformation = RemoteInformation::load( item ); - const RemoteInformation parentRemoteInformation = RemoteInformation::load( item.parentCollection() ); + const RemoteInformation remoteInformation = RemoteInformation::load(item); + const RemoteInformation parentRemoteInformation = RemoteInformation::load(item.parentCollection()); - OXA::Object object; - object.setObjectId( remoteInformation.objectId() ); - object.setFolderId( parentRemoteInformation.objectId() ); - object.setModule( remoteInformation.module() ); - object.setLastModified( remoteInformation.lastModified() ); + OXA::Object object; + object.setObjectId(remoteInformation.objectId()); + object.setFolderId(parentRemoteInformation.objectId()); + object.setModule(remoteInformation.module()); + object.setLastModified(remoteInformation.lastModified()); - OXA::ObjectDeleteJob *job = new OXA::ObjectDeleteJob( object, this ); - connect( job, SIGNAL(result(KJob*)), SLOT(onObjectDeleteJobFinished(KJob*)) ); + OXA::ObjectDeleteJob *job = new OXA::ObjectDeleteJob(object, this); + connect(job, &OXA::UpdateUsersJob::result, this, &OpenXchangeResource::onObjectDeleteJobFinished); - job->start(); + job->start(); } -void OpenXchangeResource::itemMoved( const Akonadi::Item &item, const Akonadi::Collection &collectionSource, - const Akonadi::Collection &collectionDestination ) +void OpenXchangeResource::itemMoved(const Akonadi::Item &item, const Akonadi::Collection &collectionSource, + const Akonadi::Collection &collectionDestination) { - const RemoteInformation remoteInformation = RemoteInformation::load( item ); - const RemoteInformation parentRemoteInformation = RemoteInformation::load( collectionSource ); - const RemoteInformation newParentRemoteInformation = RemoteInformation::load( collectionDestination ); + const RemoteInformation remoteInformation = RemoteInformation::load(item); + const RemoteInformation parentRemoteInformation = RemoteInformation::load(collectionSource); + const RemoteInformation newParentRemoteInformation = RemoteInformation::load(collectionDestination); + + OXA::Object object; + object.setObjectId(remoteInformation.objectId()); + object.setModule(remoteInformation.module()); + object.setFolderId(parentRemoteInformation.objectId()); + object.setLastModified(remoteInformation.lastModified()); + + OXA::Folder destinationFolder; + destinationFolder.setObjectId(newParentRemoteInformation.objectId()); + + OXA::ObjectMoveJob *job = new OXA::ObjectMoveJob(object, destinationFolder, this); + job->setProperty("item", QVariant::fromValue(item)); + connect(job, &OXA::UpdateUsersJob::result, this, &OpenXchangeResource::onObjectMoveJobFinished); - OXA::Object object; - object.setObjectId( remoteInformation.objectId() ); - object.setModule( remoteInformation.module() ); - object.setFolderId( parentRemoteInformation.objectId() ); - object.setLastModified( remoteInformation.lastModified() ); - - OXA::Folder destinationFolder; - destinationFolder.setObjectId( newParentRemoteInformation.objectId() ); - - OXA::ObjectMoveJob *job = new OXA::ObjectMoveJob( object, destinationFolder, this ); - job->setProperty( "item", QVariant::fromValue( item ) ); - connect( job, SIGNAL(result(KJob*)), SLOT(onObjectMoveJobFinished(KJob*)) ); - - job->start(); + job->start(); } -void OpenXchangeResource::collectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection &parent ) +void OpenXchangeResource::collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent) { - const RemoteInformation parentRemoteInformation = RemoteInformation::load( parent ); + const RemoteInformation parentRemoteInformation = RemoteInformation::load(parent); - OXA::Folder folder; - folder.setTitle( collection.name() ); - folder.setFolderId( parentRemoteInformation.objectId() ); - folder.setType( OXA::Folder::Private ); + OXA::Folder folder; + folder.setTitle(collection.name()); + folder.setFolderId(parentRemoteInformation.objectId()); + folder.setType(OXA::Folder::Private); + + // the folder 'inherits' the module type of its parent collection + folder.setModule(parentRemoteInformation.module()); + + // fill permissions + OXA::Folder::Permissions permissions; + permissions.setFolderPermission(OXA::Folder::Permissions::CreateSubfolders); + permissions.setObjectReadPermission(OXA::Folder::Permissions::ReadOwnObjects); + permissions.setObjectWritePermission(OXA::Folder::Permissions::WriteOwnObjects); + permissions.setObjectDeletePermission(OXA::Folder::Permissions::DeleteOwnObjects); + permissions.setAdminFlag(true); + + // assign permissions to user + OXA::Folder::UserPermissions userPermissions; + userPermissions.insert(OXA::Users::self()->currentUserId(), permissions); + + // set user permissions of folder + folder.setUserPermissions(userPermissions); + + OXA::FolderCreateJob *job = new OXA::FolderCreateJob(folder, this); + job->setProperty("collection", QVariant::fromValue(collection)); + connect(job, &OXA::UpdateUsersJob::result, this, &OpenXchangeResource::onFolderCreateJobFinished); + job->start(); +} - // the folder 'inherits' the module type of its parent collection - folder.setModule( parentRemoteInformation.module() ); +void OpenXchangeResource::collectionChanged(const Akonadi::Collection &collection) +{ + const RemoteInformation remoteInformation = RemoteInformation::load(collection); - // fill permissions - OXA::Folder::Permissions permissions; - permissions.setFolderPermission( OXA::Folder::Permissions::CreateSubfolders ); - permissions.setObjectReadPermission( OXA::Folder::Permissions::ReadOwnObjects ); - permissions.setObjectWritePermission( OXA::Folder::Permissions::WriteOwnObjects ); - permissions.setObjectDeletePermission( OXA::Folder::Permissions::DeleteOwnObjects ); - permissions.setAdminFlag( true ); + // do not try to change the standard collections + if (remoteInformation.objectId() >= 0 && remoteInformation.objectId() <= 4) { + changeCommitted(collection); + return; + } - // assign permissions to user - OXA::Folder::UserPermissions userPermissions; - userPermissions.insert( OXA::Users::self()->currentUserId(), permissions ); + const RemoteInformation parentRemoteInformation = RemoteInformation::load(collection.parentCollection()); - // set user permissions of folder - folder.setUserPermissions( userPermissions ); + OXA::Folder folder; + folder.setObjectId(remoteInformation.objectId()); + folder.setFolderId(parentRemoteInformation.objectId()); + folder.setTitle(collection.name()); + folder.setLastModified(remoteInformation.lastModified()); - OXA::FolderCreateJob *job = new OXA::FolderCreateJob( folder, this ); - job->setProperty( "collection", QVariant::fromValue( collection ) ); - connect( job, SIGNAL(result(KJob*)), SLOT(onFolderCreateJobFinished(KJob*)) ); - job->start(); + OXA::FolderModifyJob *job = new OXA::FolderModifyJob(folder, this); + job->setProperty("collection", QVariant::fromValue(collection)); + connect(job, &OXA::UpdateUsersJob::result, this, &OpenXchangeResource::onFolderModifyJobFinished); } -void OpenXchangeResource::collectionChanged( const Akonadi::Collection &collection ) +void OpenXchangeResource::collectionRemoved(const Akonadi::Collection &collection) { - const RemoteInformation remoteInformation = RemoteInformation::load( collection ); + const RemoteInformation remoteInformation = RemoteInformation::load(collection); - // do not try to change the standard collections - if ( remoteInformation.objectId() >= 0 && remoteInformation.objectId() <= 4 ) { - changeCommitted( collection ); - return; - } + OXA::Folder folder; + folder.setObjectId(remoteInformation.objectId()); + folder.setLastModified(remoteInformation.lastModified()); - const RemoteInformation parentRemoteInformation = RemoteInformation::load( collection.parentCollection() ); + OXA::FolderDeleteJob *job = new OXA::FolderDeleteJob(folder, this); + connect(job, &OXA::UpdateUsersJob::result, this, &OpenXchangeResource::onFolderDeleteJobFinished); - OXA::Folder folder; - folder.setObjectId( remoteInformation.objectId() ); - folder.setFolderId( parentRemoteInformation.objectId() ); - folder.setTitle( collection.name() ); - folder.setLastModified( remoteInformation.lastModified() ); - - OXA::FolderModifyJob *job = new OXA::FolderModifyJob( folder, this ); - job->setProperty( "collection", QVariant::fromValue( collection ) ); - connect( job, SIGNAL(result(KJob*)), SLOT(onFolderModifyJobFinished(KJob*)) ); + job->start(); } -void OpenXchangeResource::collectionRemoved( const Akonadi::Collection &collection ) +void OpenXchangeResource::collectionMoved(const Akonadi::Collection &collection, const Akonadi::Collection &collectionSource, + const Akonadi::Collection &collectionDestination) { - const RemoteInformation remoteInformation = RemoteInformation::load( collection ); - - OXA::Folder folder; - folder.setObjectId( remoteInformation.objectId() ); - folder.setLastModified( remoteInformation.lastModified() ); - - OXA::FolderDeleteJob *job = new OXA::FolderDeleteJob( folder, this ); - connect( job, SIGNAL(result(KJob*)), SLOT(onFolderDeleteJobFinished(KJob*)) ); + const RemoteInformation remoteInformation = RemoteInformation::load(collection); + const RemoteInformation parentRemoteInformation = RemoteInformation::load(collectionSource); + const RemoteInformation newParentRemoteInformation = RemoteInformation::load(collectionDestination); + + OXA::Folder folder; + folder.setObjectId(remoteInformation.objectId()); + folder.setFolderId(parentRemoteInformation.objectId()); + + OXA::Folder destinationFolder; + destinationFolder.setObjectId(newParentRemoteInformation.objectId()); + + OXA::FolderMoveJob *job = new OXA::FolderMoveJob(folder, destinationFolder, this); + job->setProperty("collection", QVariant::fromValue(collection)); + connect(job, &OXA::UpdateUsersJob::result, this, &OpenXchangeResource::onFolderMoveJobFinished); - job->start(); + job->start(); } -void OpenXchangeResource::collectionMoved( const Akonadi::Collection &collection, const Akonadi::Collection &collectionSource, - const Akonadi::Collection &collectionDestination ) +//// job result slots + +void OpenXchangeResource::onUpdateUsersJobFinished(KJob *job) { - const RemoteInformation remoteInformation = RemoteInformation::load( collection ); - const RemoteInformation parentRemoteInformation = RemoteInformation::load( collectionSource ); - const RemoteInformation newParentRemoteInformation = RemoteInformation::load( collectionDestination ); + if (job->error()) { + // This might be an indication that we can not connect to the server... + Q_EMIT status(Broken, i18n("Unable to connect to server")); + return; + } - OXA::Folder folder; - folder.setObjectId( remoteInformation.objectId() ); - folder.setFolderId( parentRemoteInformation.objectId() ); + if (Settings::self()->useIncrementalUpdates()) { + syncCollectionsRemoteIdCache(); + } - OXA::Folder destinationFolder; - destinationFolder.setObjectId( newParentRemoteInformation.objectId() ); + // now we have all user information, so continue synchronization + synchronize(); + Q_EMIT configurationDialogAccepted(); +} - OXA::FolderMoveJob *job = new OXA::FolderMoveJob( folder, destinationFolder, this ); - job->setProperty( "collection", QVariant::fromValue( collection ) ); - connect( job, SIGNAL(result(KJob*)), SLOT(onFolderMoveJobFinished(KJob*)) ); +void OpenXchangeResource::onObjectsRequestJobFinished(KJob *job) +{ + if (job->error()) { + cancelTask(job->errorText()); + return; + } - job->start(); -} + OXA::ObjectsRequestJob *requestJob = qobject_cast(job); + Q_ASSERT(requestJob); -//// job result slots + Item::List items; -void OpenXchangeResource::onUpdateUsersJobFinished( KJob *job ) -{ - if ( job->error() ) { - // This might be an indication that we can not connect to the server... - emit status( Broken, i18n( "Unable to connect to server" ) ); - return; - } - - if ( Settings::self()->useIncrementalUpdates() ) - syncCollectionsRemoteIdCache(); - - // now we have all user information, so continue synchronization - synchronize(); - emit configurationDialogAccepted(); -} - -void OpenXchangeResource::onObjectsRequestJobFinished( KJob *job ) -{ - if ( job->error() ) { - cancelTask( job->errorText() ); - return; - } - - OXA::ObjectsRequestJob *requestJob = qobject_cast( job ); - Q_ASSERT( requestJob ); - - Item::List items; - - const OXA::Object::List objects = requestJob->objects(); - foreach ( const OXA::Object &object, objects ) { - Item item; - switch ( object.module() ) { - case OXA::Folder::Contacts: - if ( !object.contact().isEmpty() ) { - item.setMimeType( KABC::Addressee::mimeType() ); - item.setPayload( object.contact() ); - } else { - item.setMimeType( KABC::ContactGroup::mimeType() ); - item.setPayload( object.contactGroup() ); + const OXA::Object::List objects = requestJob->objects(); + foreach (const OXA::Object &object, objects) { + Item item; + switch (object.module()) { + case OXA::Folder::Contacts: + if (!object.contact().isEmpty()) { + item.setMimeType(KContacts::Addressee::mimeType()); + item.setPayload(object.contact()); + } else { + item.setMimeType(KContacts::ContactGroup::mimeType()); + item.setPayload(object.contactGroup()); + } + break; + case OXA::Folder::Calendar: + item.setMimeType(KCalCore::Event::eventMimeType()); + item.setPayload(object.event()); + break; + case OXA::Folder::Tasks: + item.setMimeType(KCalCore::Todo::todoMimeType()); + item.setPayload(object.task()); + break; + case OXA::Folder::Unbound: + Q_ASSERT(false); + break; } - break; - case OXA::Folder::Calendar: - item.setMimeType( KCalCore::Event::eventMimeType() ); - item.setPayload( object.event() ); - break; - case OXA::Folder::Tasks: - item.setMimeType( KCalCore::Todo::todoMimeType() ); - item.setPayload( object.task() ); - break; - case OXA::Folder::Unbound: - Q_ASSERT( false ); - break; - } - const RemoteInformation remoteInformation( object.objectId(), object.module(), object.lastModified() ); - remoteInformation.store( item ); + const RemoteInformation remoteInformation(object.objectId(), object.module(), object.lastModified()); + remoteInformation.store(item); - items.append( item ); - } + items.append(item); + } - itemsRetrieved( items ); + itemsRetrieved(items); } -void OpenXchangeResource::onObjectsRequestDeltaJobFinished( KJob *job ) +void OpenXchangeResource::onObjectsRequestDeltaJobFinished(KJob *job) { - if ( job->error() ) { - cancelTask( job->errorText() ); - return; - } + if (job->error()) { + cancelTask(job->errorText()); + return; + } - OXA::ObjectsRequestDeltaJob *requestJob = qobject_cast( job ); - Q_ASSERT( requestJob ); + OXA::ObjectsRequestDeltaJob *requestJob = qobject_cast(job); + Q_ASSERT(requestJob); - const Akonadi::Collection collection = requestJob->property( "collection" ).value(); + const Akonadi::Collection collection = requestJob->property("collection").value(); - ObjectsLastSync lastSyncInfo; + ObjectsLastSync lastSyncInfo; - qulonglong objectsLastSync = lastSyncInfo.lastSync( collection.id() ); + qulonglong objectsLastSync = lastSyncInfo.lastSync(collection.id()); - Item::List changedItems; + Item::List changedItems; - const OXA::Object::List modifiedObjects = requestJob->modifiedObjects(); - foreach ( const OXA::Object &object, modifiedObjects ) { - Item item; - switch ( object.module() ) { - case OXA::Folder::Contacts: - if ( !object.contact().isEmpty() ) { - item.setMimeType( KABC::Addressee::mimeType() ); - item.setPayload( object.contact() ); - } else { - item.setMimeType( KABC::ContactGroup::mimeType() ); - item.setPayload( object.contactGroup() ); + const OXA::Object::List modifiedObjects = requestJob->modifiedObjects(); + foreach (const OXA::Object &object, modifiedObjects) { + Item item; + switch (object.module()) { + case OXA::Folder::Contacts: + if (!object.contact().isEmpty()) { + item.setMimeType(KContacts::Addressee::mimeType()); + item.setPayload(object.contact()); + } else { + item.setMimeType(KContacts::ContactGroup::mimeType()); + item.setPayload(object.contactGroup()); + } + break; + case OXA::Folder::Calendar: + item.setMimeType(KCalCore::Event::eventMimeType()); + item.setPayload(object.event()); + break; + case OXA::Folder::Tasks: + item.setMimeType(KCalCore::Todo::todoMimeType()); + item.setPayload(object.task()); + break; + case OXA::Folder::Unbound: + Q_ASSERT(false); + break; } - break; - case OXA::Folder::Calendar: - item.setMimeType( KCalCore::Event::eventMimeType() ); - item.setPayload( object.event() ); - break; - case OXA::Folder::Tasks: - item.setMimeType( KCalCore::Todo::todoMimeType() ); - item.setPayload( object.task() ); - break; - case OXA::Folder::Unbound: - Q_ASSERT( false ); - break; - } - const RemoteInformation remoteInformation( object.objectId(), object.module(), object.lastModified() ); - remoteInformation.store( item ); + const RemoteInformation remoteInformation(object.objectId(), object.module(), object.lastModified()); + remoteInformation.store(item); - // the value of objectsLastSync is determined by the maximum last modified value - // of the added or changed objects - objectsLastSync = qMax( objectsLastSync, object.lastModified().toULongLong() ); + // the value of objectsLastSync is determined by the maximum last modified value + // of the added or changed objects + objectsLastSync = qMax(objectsLastSync, object.lastModified().toULongLong()); - changedItems.append( item ); - } + changedItems.append(item); + } - Item::List removedItems; + Item::List removedItems; - const OXA::Object::List deletedObjects = requestJob->deletedObjects(); - foreach ( const OXA::Object &object, deletedObjects ) { - Item item; + const OXA::Object::List deletedObjects = requestJob->deletedObjects(); + removedItems.reserve(deletedObjects.count()); + foreach (const OXA::Object &object, deletedObjects) { + Item item; - const RemoteInformation remoteInformation( object.objectId(), object.module(), object.lastModified() ); - remoteInformation.store( item ); + const RemoteInformation remoteInformation(object.objectId(), object.module(), object.lastModified()); + remoteInformation.store(item); - removedItems.append( item ); - } + removedItems.append(item); + } - if ( objectsLastSync != lastSyncInfo.lastSync( collection.id() ) ) { - // according to the OX developers we should subtract one millisecond from the - // maximum last modified value to cover multiple changes that might have been - // done in the same millisecond to the data on the server - lastSyncInfo.setLastSync( collection.id(), objectsLastSync - 1 ); - lastSyncInfo.save(); - } + if (objectsLastSync != lastSyncInfo.lastSync(collection.id())) { + // according to the OX developers we should subtract one millisecond from the + // maximum last modified value to cover multiple changes that might have been + // done in the same millisecond to the data on the server + lastSyncInfo.setLastSync(collection.id(), objectsLastSync - 1); + lastSyncInfo.save(); + } - //qDebug( "changedObjects=%d removedObjects=%d", modifiedObjects.count(), deletedObjects.count() ); - //qDebug( "changedItems=%d removedItems=%d", changedItems.count(), removedItems.count() ); - itemsRetrievedIncremental( changedItems, removedItems ); + //qDebug( "changedObjects=%d removedObjects=%d", modifiedObjects.count(), deletedObjects.count() ); + //qDebug( "changedItems=%d removedItems=%d", changedItems.count(), removedItems.count() ); + itemsRetrievedIncremental(changedItems, removedItems); } -void OpenXchangeResource::onObjectRequestJobFinished( KJob *job ) +void OpenXchangeResource::onObjectRequestJobFinished(KJob *job) { - if ( job->error() ) { - cancelTask( job->errorText() ); - return; - } + if (job->error()) { + cancelTask(job->errorText()); + return; + } - OXA::ObjectRequestJob *requestJob = qobject_cast( job ); - Q_ASSERT( requestJob ); + OXA::ObjectRequestJob *requestJob = qobject_cast(job); + Q_ASSERT(requestJob); - const OXA::Object object = requestJob->object(); + const OXA::Object object = requestJob->object(); - Item item = job->property( "item" ).value(); + Item item = job->property("item").value(); - const RemoteInformation remoteInformation( object.objectId(), object.module(), object.lastModified() ); - remoteInformation.store( item ); + const RemoteInformation remoteInformation(object.objectId(), object.module(), object.lastModified()); + remoteInformation.store(item); - switch ( object.module() ) { + switch (object.module()) { case OXA::Folder::Contacts: - if ( !object.contact().isEmpty() ) { - item.setMimeType( KABC::Addressee::mimeType() ); - item.setPayload( object.contact() ); - } else { - item.setMimeType( KABC::ContactGroup::mimeType() ); - item.setPayload( object.contactGroup() ); - } - break; + if (!object.contact().isEmpty()) { + item.setMimeType(KContacts::Addressee::mimeType()); + item.setPayload(object.contact()); + } else { + item.setMimeType(KContacts::ContactGroup::mimeType()); + item.setPayload(object.contactGroup()); + } + break; case OXA::Folder::Calendar: - item.setMimeType( KCalCore::Event::eventMimeType() ); - item.setPayload( object.event() ); - break; + item.setMimeType(KCalCore::Event::eventMimeType()); + item.setPayload(object.event()); + break; case OXA::Folder::Tasks: - item.setMimeType( KCalCore::Todo::todoMimeType() ); - item.setPayload( object.task() ); - break; + item.setMimeType(KCalCore::Todo::todoMimeType()); + item.setPayload(object.task()); + break; case OXA::Folder::Unbound: - Q_ASSERT( false ); - break; - } + Q_ASSERT(false); + break; + } - itemRetrieved( item ); + itemRetrieved(item); } -void OpenXchangeResource::onObjectCreateJobFinished( KJob *job ) +void OpenXchangeResource::onObjectCreateJobFinished(KJob *job) { - if ( job->error() ) { - QString errorText = job->errorText(); - if ( job->error() == KJob::UserDefinedError ) { - switch ( OXA::OXErrors::getEditErrorID( job->errorText() ) ) { - case OXA::OXErrors::ConcurrentModification : errorText = i18n( "The object was edited by another participant in the meantime. Please check." ); break; - case OXA::OXErrors::ObjectNotFound : errorText = i18n( "Object not found. Maybe it was deleted by another participant in the meantime." ); break; - case OXA::OXErrors::NoPermissionForThisAction : errorText = i18n( "You don't have the permission to perform this action on this object." ); break; - case OXA::OXErrors::ConflictsDetected : errorText = i18n( "A conflict detected. Please check if there are other objects in conflict with this one." ); break; - case OXA::OXErrors::MissingMandatoryFields : errorText = i18n( "A mandatory data field is missing. Please check. Otherwise contact your administrator." ); break; - case OXA::OXErrors::AppointmentConflicts : errorText = i18n( "An appointment conflict detected.\nPlease check if there are other appointments in conflict with this one." ); break; - case OXA::OXErrors::InternalServerError : errorText = i18n( "Internal server error. Please contact your administrator." ); break; - case OXA::OXErrors::EditErrorUndefined : - default : ; - } + if (job->error()) { + QString errorText = job->errorText(); + if (job->error() == KJob::UserDefinedError) { + switch (OXA::OXErrors::getEditErrorID(job->errorText())) { + case OXA::OXErrors::ConcurrentModification : errorText = i18n("The object was edited by another participant in the meantime. Please check."); break; + case OXA::OXErrors::ObjectNotFound : errorText = i18n("Object not found. Maybe it was deleted by another participant in the meantime."); break; + case OXA::OXErrors::NoPermissionForThisAction : errorText = i18n("You don't have the permission to perform this action on this object."); break; + case OXA::OXErrors::ConflictsDetected : errorText = i18n("A conflict detected. Please check if there are other objects in conflict with this one."); break; + case OXA::OXErrors::MissingMandatoryFields : errorText = i18n("A mandatory data field is missing. Please check. Otherwise contact your administrator."); break; + case OXA::OXErrors::AppointmentConflicts : errorText = i18n("An appointment conflict detected.\nPlease check if there are other appointments in conflict with this one."); break; + case OXA::OXErrors::InternalServerError : errorText = i18n("Internal server error. Please contact your administrator."); break; + case OXA::OXErrors::EditErrorUndefined : + default : ; + } + } + cancelTask(errorText); + return; } - cancelTask( errorText ); - return; - } - OXA::ObjectCreateJob *createJob = qobject_cast( job ); - Q_ASSERT( createJob ); + OXA::ObjectCreateJob *createJob = qobject_cast(job); + Q_ASSERT(createJob); - const OXA::Object object = createJob->object(); + const OXA::Object object = createJob->object(); - Item item = job->property( "item" ).value(); + Item item = job->property("item").value(); - const RemoteInformation remoteInformation( object.objectId(), object.module(), object.lastModified() ); - remoteInformation.store( item ); + const RemoteInformation remoteInformation(object.objectId(), object.module(), object.lastModified()); + remoteInformation.store(item); - changeCommitted( item ); + changeCommitted(item); } -void OpenXchangeResource::onObjectModifyJobFinished( KJob *job ) +void OpenXchangeResource::onObjectModifyJobFinished(KJob *job) { - if ( job->error() ) { - cancelTask( job->errorText() ); - return; - } + if (job->error()) { + cancelTask(job->errorText()); + return; + } - OXA::ObjectModifyJob *modifyJob = qobject_cast( job ); - Q_ASSERT( modifyJob ); + OXA::ObjectModifyJob *modifyJob = qobject_cast(job); + Q_ASSERT(modifyJob); - const OXA::Object object = modifyJob->object(); + const OXA::Object object = modifyJob->object(); - Item item = job->property( "item" ).value(); + Item item = job->property("item").value(); - // update last_modified property - RemoteInformation remoteInformation = RemoteInformation::load( item ); - remoteInformation.setLastModified( object.lastModified() ); - remoteInformation.store( item ); + // update last_modified property + RemoteInformation remoteInformation = RemoteInformation::load(item); + remoteInformation.setLastModified(object.lastModified()); + remoteInformation.store(item); - changeCommitted( item ); + changeCommitted(item); } -void OpenXchangeResource::onObjectMoveJobFinished( KJob *job ) +void OpenXchangeResource::onObjectMoveJobFinished(KJob *job) { - if ( job->error() ) { - cancelTask( job->errorText() ); - return; - } + if (job->error()) { + cancelTask(job->errorText()); + return; + } - OXA::ObjectMoveJob *moveJob = qobject_cast( job ); - Q_ASSERT( moveJob ); + OXA::ObjectMoveJob *moveJob = qobject_cast(job); + Q_ASSERT(moveJob); - const OXA::Object object = moveJob->object(); + const OXA::Object object = moveJob->object(); - Item item = job->property( "item" ).value(); + Item item = job->property("item").value(); - // update last_modified property - RemoteInformation remoteInformation = RemoteInformation::load( item ); - remoteInformation.setLastModified( object.lastModified() ); - remoteInformation.store( item ); + // update last_modified property + RemoteInformation remoteInformation = RemoteInformation::load(item); + remoteInformation.setLastModified(object.lastModified()); + remoteInformation.store(item); - changeCommitted( item ); + changeCommitted(item); } -void OpenXchangeResource::onObjectDeleteJobFinished( KJob *job ) +void OpenXchangeResource::onObjectDeleteJobFinished(KJob *job) { - if ( job->error() ) { - cancelTask( job->errorText() ); - return; - } + if (job->error()) { + cancelTask(job->errorText()); + return; + } - changeProcessed(); + changeProcessed(); } -static Collection folderToCollection( const OXA::Folder &folder, const Collection &parentCollection ) +static Collection folderToCollection(const OXA::Folder &folder, const Collection &parentCollection) { - Collection collection; + Collection collection; - collection.setParentCollection( parentCollection ); + collection.setParentCollection(parentCollection); - const RemoteInformation remoteInformation( folder.objectId(), folder.module(), folder.lastModified() ); - remoteInformation.store( collection ); + const RemoteInformation remoteInformation(folder.objectId(), folder.module(), folder.lastModified()); + remoteInformation.store(collection); - // set a unique name to make Akonadi happy - collection.setName( folder.title() + '_' + QUuid::createUuid().toString() ); + // set a unique name to make Akonadi happy + collection.setName(folder.title() + '_' + QUuid::createUuid().toString()); - EntityDisplayAttribute *attribute = collection.attribute( Collection::AddIfMissing ); - attribute->setDisplayName( folder.title() ); + EntityDisplayAttribute *attribute = collection.attribute(Collection::AddIfMissing); + attribute->setDisplayName(folder.title()); - QStringList mimeTypes; - mimeTypes.append( Collection::mimeType() ); - switch ( folder.module() ) { + QStringList mimeTypes; + mimeTypes.append(Collection::mimeType()); + switch (folder.module()) { case OXA::Folder::Calendar: - mimeTypes.append( KCalCore::Event::eventMimeType() ); - attribute->setIconName( QString::fromLatin1( "view-calendar" ) ); - break; + mimeTypes.append(KCalCore::Event::eventMimeType()); + attribute->setIconName(QStringLiteral("view-calendar")); + break; case OXA::Folder::Contacts: - mimeTypes.append( KABC::Addressee::mimeType() ); - mimeTypes.append( KABC::ContactGroup::mimeType() ); - attribute->setIconName( QString::fromLatin1( "view-pim-contacts" ) ); - break; + mimeTypes.append(KContacts::Addressee::mimeType()); + mimeTypes.append(KContacts::ContactGroup::mimeType()); + attribute->setIconName(QStringLiteral("view-pim-contacts")); + break; case OXA::Folder::Tasks: - mimeTypes.append( KCalCore::Todo::todoMimeType() ); - attribute->setIconName( QString::fromLatin1( "view-pim-tasks" ) ); - break; + mimeTypes.append(KCalCore::Todo::todoMimeType()); + attribute->setIconName(QStringLiteral("view-pim-tasks")); + break; case OXA::Folder::Unbound: - break; - } + break; + } - collection.setContentMimeTypes( mimeTypes ); - collection.setRights( folderPermissionsToCollectionRights( folder ) ); + collection.setContentMimeTypes(mimeTypes); + collection.setRights(folderPermissionsToCollectionRights(folder)); - return collection; + return collection; } -void OpenXchangeResource::onFoldersRequestJobFinished( KJob *job ) +void OpenXchangeResource::onFoldersRequestJobFinished(KJob *job) { - if ( job->error() ) { - cancelTask( job->errorText() ); - return; - } - - OXA::FoldersRequestJob *requestJob = qobject_cast( job ); - Q_ASSERT( requestJob ); + if (job->error()) { + cancelTask(job->errorText()); + return; + } - Collection::List collections; + OXA::FoldersRequestJob *requestJob = qobject_cast(job); + Q_ASSERT(requestJob); - // add the standard collections - collections << mStandardCollectionsMap.values(); + Collection::List collections; - QMap remoteIdMap( mStandardCollectionsMap ); + // add the standard collections + collections << Akonadi::valuesToVector(mStandardCollectionsMap); - // add the folders from the server - OXA::Folder::List folders = requestJob->folders(); - while ( !folders.isEmpty() ) { - const OXA::Folder folder = folders.takeFirst(); - if ( remoteIdMap.contains( folder.folderId() ) ) { - // we have the parent collection created already - const Collection collection = folderToCollection( folder, remoteIdMap.value( folder.folderId() ) ); - remoteIdMap.insert( folder.objectId(), collection ); - collections.append( collection ); - } else { - // we have to wait until the parent folder has been created - folders.append( folder ); - qDebug() << "Error: parent folder id" << folder.folderId() << "of folder" << folder.title() << "is unknown"; + QMap remoteIdMap(mStandardCollectionsMap); + + // add the folders from the server + OXA::Folder::List folders = requestJob->folders(); + while (!folders.isEmpty()) { + const OXA::Folder folder = folders.takeFirst(); + if (remoteIdMap.contains(folder.folderId())) { + // we have the parent collection created already + const Collection collection = folderToCollection(folder, remoteIdMap.value(folder.folderId())); + remoteIdMap.insert(folder.objectId(), collection); + collections.append(collection); + } else { + // we have to wait until the parent folder has been created + folders.append(folder); + qDebug() << "Error: parent folder id" << folder.folderId() << "of folder" << folder.title() << "is unknown"; + } } - } - collectionsRetrieved( collections ); + collectionsRetrieved(collections); } -void OpenXchangeResource::onFoldersRequestDeltaJobFinished( KJob *job ) +void OpenXchangeResource::onFoldersRequestDeltaJobFinished(KJob *job) { - //qDebug( "onFoldersRequestDeltaJobFinished mCollectionsMap.count() = %d", mCollectionsMap.count() ); + //qDebug( "onFoldersRequestDeltaJobFinished mCollectionsMap.count() = %d", mCollectionsMap.count() ); - if ( job->error() ) { - cancelTask( job->errorText() ); - return; - } - - OXA::FoldersRequestDeltaJob *requestJob = qobject_cast( job ); - Q_ASSERT( requestJob ); - - Collection::List changedCollections; + if (job->error()) { + cancelTask(job->errorText()); + return; + } - // add the standard collections - changedCollections << mStandardCollectionsMap.values(); + OXA::FoldersRequestDeltaJob *requestJob = qobject_cast(job); + Q_ASSERT(requestJob); - qulonglong foldersLastSync = Settings::self()->foldersLastSync(); + Collection::List changedCollections; - // add the new or modified folders from the server - OXA::Folder::List modifiedFolders = requestJob->modifiedFolders(); - while ( !modifiedFolders.isEmpty() ) { - const OXA::Folder folder = modifiedFolders.takeFirst(); - if ( mCollectionsMap.contains( folder.folderId() ) ) { - // we have the parent collection created already - const Collection collection = folderToCollection( folder, mCollectionsMap.value( folder.folderId() ) ); - mCollectionsMap.insert( folder.objectId(), collection ); - changedCollections.append( collection ); + // add the standard collections + changedCollections << Akonadi::valuesToVector(mStandardCollectionsMap); - // the value of foldersLastSync is determined by the maximum last modified value - // of the added or changed folders - foldersLastSync = qMax( foldersLastSync, folder.lastModified().toULongLong() ); + qulonglong foldersLastSync = Settings::self()->foldersLastSync(); + + // add the new or modified folders from the server + OXA::Folder::List modifiedFolders = requestJob->modifiedFolders(); + while (!modifiedFolders.isEmpty()) { + const OXA::Folder folder = modifiedFolders.takeFirst(); + if (mCollectionsMap.contains(folder.folderId())) { + // we have the parent collection created already + const Collection collection = folderToCollection(folder, mCollectionsMap.value(folder.folderId())); + mCollectionsMap.insert(folder.objectId(), collection); + changedCollections.append(collection); + + // the value of foldersLastSync is determined by the maximum last modified value + // of the added or changed folders + foldersLastSync = qMax(foldersLastSync, folder.lastModified().toULongLong()); - } else { - // we have to wait until the parent folder has been created - modifiedFolders.append( folder ); - qDebug() << "Error: parent folder id" << folder.folderId() << "of folder" << folder.title() << "is unknown"; + } else { + // we have to wait until the parent folder has been created + modifiedFolders.append(folder); + qDebug() << "Error: parent folder id" << folder.folderId() << "of folder" << folder.title() << "is unknown"; + } } - } - Collection::List removedCollections; + Collection::List removedCollections; - // add the deleted folders from the server - OXA::Folder::List deletedFolders = requestJob->deletedFolders(); - foreach ( const OXA::Folder &folder, deletedFolders ) { - Collection collection; - collection.setRemoteId( QString::number( folder.objectId() ) ); + // add the deleted folders from the server + OXA::Folder::List deletedFolders = requestJob->deletedFolders(); + removedCollections.reserve(deletedFolders.count()); + foreach (const OXA::Folder &folder, deletedFolders) { + Collection collection; + collection.setRemoteId(QString::number(folder.objectId())); - removedCollections.append( collection ); - } + removedCollections.append(collection); + } - if ( foldersLastSync != Settings::self()->foldersLastSync() ) { - // according to the OX developers we should subtract one millisecond from the - // maximum last modified value to cover multiple changes that might have been - // done in the same millisecond to the data on the server - Settings::self()->setFoldersLastSync( foldersLastSync - 1 ); - Settings::self()->writeConfig(); - } + if (foldersLastSync != Settings::self()->foldersLastSync()) { + // according to the OX developers we should subtract one millisecond from the + // maximum last modified value to cover multiple changes that might have been + // done in the same millisecond to the data on the server + Settings::self()->setFoldersLastSync(foldersLastSync - 1); + Settings::self()->save(); + } - //qDebug( "changedFolders=%d removedFolders=%d", modifiedFolders.count(), deletedFolders.count() ); - //qDebug( "changedCollections=%d removedCollections=%d", changedCollections.count(), removedCollections.count() ); - collectionsRetrievedIncremental( changedCollections, removedCollections ); + //qDebug( "changedFolders=%d removedFolders=%d", modifiedFolders.count(), deletedFolders.count() ); + //qDebug( "changedCollections=%d removedCollections=%d", changedCollections.count(), removedCollections.count() ); + collectionsRetrievedIncremental(changedCollections, removedCollections); } -void OpenXchangeResource::onFolderCreateJobFinished( KJob *job ) +void OpenXchangeResource::onFolderCreateJobFinished(KJob *job) { - if ( job->error() ) { - cancelTask( job->errorText() ); - return; - } + if (job->error()) { + cancelTask(job->errorText()); + return; + } - OXA::FolderCreateJob *createJob = qobject_cast( job ); - Q_ASSERT( createJob ); + OXA::FolderCreateJob *createJob = qobject_cast(job); + Q_ASSERT(createJob); - const OXA::Folder folder = createJob->folder(); + const OXA::Folder folder = createJob->folder(); - Collection collection = job->property( "collection" ).value(); + Collection collection = job->property("collection").value(); - const RemoteInformation remoteInformation( folder.objectId(), folder.module(), folder.lastModified() ); - remoteInformation.store( collection ); + const RemoteInformation remoteInformation(folder.objectId(), folder.module(), folder.lastModified()); + remoteInformation.store(collection); - // set matching icon - EntityDisplayAttribute *attribute = collection.attribute( Collection::AddIfMissing ); - switch ( folder.module() ) { + // set matching icon + EntityDisplayAttribute *attribute = collection.attribute(Collection::AddIfMissing); + switch (folder.module()) { case OXA::Folder::Calendar: - attribute->setIconName( QString::fromLatin1( "view-calendar" ) ); - break; + attribute->setIconName(QStringLiteral("view-calendar")); + break; case OXA::Folder::Contacts: - attribute->setIconName( QString::fromLatin1( "view-pim-contacts" ) ); - break; + attribute->setIconName(QStringLiteral("view-pim-contacts")); + break; case OXA::Folder::Tasks: - attribute->setIconName( QString::fromLatin1( "view-pim-tasks" ) ); - break; + attribute->setIconName(QStringLiteral("view-pim-tasks")); + break; case OXA::Folder::Unbound: - break; - } + break; + } - changeCommitted( collection ); + changeCommitted(collection); } -void OpenXchangeResource::onFolderModifyJobFinished( KJob *job ) +void OpenXchangeResource::onFolderModifyJobFinished(KJob *job) { - if ( job->error() ) { - cancelTask( job->errorText() ); - return; - } + if (job->error()) { + cancelTask(job->errorText()); + return; + } - OXA::FolderModifyJob *modifyJob = qobject_cast( job ); - Q_ASSERT( modifyJob ); + OXA::FolderModifyJob *modifyJob = qobject_cast(job); + Q_ASSERT(modifyJob); - const OXA::Folder folder = modifyJob->folder(); + const OXA::Folder folder = modifyJob->folder(); - Collection collection = job->property( "collection" ).value(); + Collection collection = job->property("collection").value(); - // update last_modified property - RemoteInformation remoteInformation = RemoteInformation::load( collection ); - remoteInformation.setLastModified( folder.lastModified() ); - remoteInformation.store( collection ); + // update last_modified property + RemoteInformation remoteInformation = RemoteInformation::load(collection); + remoteInformation.setLastModified(folder.lastModified()); + remoteInformation.store(collection); - changeCommitted( collection ); + changeCommitted(collection); } -void OpenXchangeResource::onFolderMoveJobFinished( KJob *job ) +void OpenXchangeResource::onFolderMoveJobFinished(KJob *job) { - if ( job->error() ) { - cancelTask( job->errorText() ); - return; - } + if (job->error()) { + cancelTask(job->errorText()); + return; + } - OXA::FolderMoveJob *moveJob = qobject_cast( job ); - Q_ASSERT( moveJob ); + OXA::FolderMoveJob *moveJob = qobject_cast(job); + Q_ASSERT(moveJob); - const OXA::Folder folder = moveJob->folder(); + const OXA::Folder folder = moveJob->folder(); - Collection collection = job->property( "collection" ).value(); + Collection collection = job->property("collection").value(); - // update last_modified property - RemoteInformation remoteInformation = RemoteInformation::load( collection ); - remoteInformation.setLastModified( folder.lastModified() ); - remoteInformation.store( collection ); + // update last_modified property + RemoteInformation remoteInformation = RemoteInformation::load(collection); + remoteInformation.setLastModified(folder.lastModified()); + remoteInformation.store(collection); - changeCommitted( collection ); + changeCommitted(collection); } -void OpenXchangeResource::onFolderDeleteJobFinished( KJob *job ) +void OpenXchangeResource::onFolderDeleteJobFinished(KJob *job) { - if ( job->error() ) { - cancelTask( job->errorText() ); - return; - } + if (job->error()) { + cancelTask(job->errorText()); + return; + } - changeProcessed(); + changeProcessed(); } /** @@ -1110,29 +1127,30 @@ */ void OpenXchangeResource::syncCollectionsRemoteIdCache() { - mCollectionsMap.clear(); + mCollectionsMap.clear(); - // copy the standard collections - mCollectionsMap = mStandardCollectionsMap; + // copy the standard collections + mCollectionsMap = mStandardCollectionsMap; - CollectionFetchJob *job = new CollectionFetchJob( mResourceCollection, CollectionFetchJob::Recursive, this ); - connect( job, SIGNAL(result(KJob*)), SLOT(onFetchResourceCollectionsFinished(KJob*)) ); + CollectionFetchJob *job = new CollectionFetchJob(mResourceCollection, CollectionFetchJob::Recursive, this); + connect(job, &OXA::UpdateUsersJob::result, this, &OpenXchangeResource::onFetchResourceCollectionsFinished); } -void OpenXchangeResource::onFetchResourceCollectionsFinished( KJob *job ) +void OpenXchangeResource::onFetchResourceCollectionsFinished(KJob *job) { - if ( job->error() ) { - qDebug() << "Error: Unable to fetch resource collections:" << job->errorText(); - return; - } + if (job->error()) { + qDebug() << "Error: Unable to fetch resource collections:" << job->errorText(); + return; + } - const CollectionFetchJob *fetchJob = qobject_cast( job ); + const CollectionFetchJob *fetchJob = qobject_cast(job); - // copy the remaining collections of the resource - const Collection::List collections = fetchJob->collections(); - foreach ( const Collection &collection, collections ) - mCollectionsMap.insert( collection.remoteId().toULongLong(), collection ); + // copy the remaining collections of the resource + const Collection::List collections = fetchJob->collections(); + foreach (const Collection &collection, collections) { + mCollectionsMap.insert(collection.remoteId().toULongLong(), collection); + } } -AKONADI_RESOURCE_MAIN( OpenXchangeResource ) +AKONADI_RESOURCE_MAIN(OpenXchangeResource) diff -Nru kdepim-runtime-4.14.6/resources/openxchange/openxchangeresource.desktop kdepim-runtime-15.08.0/resources/openxchange/openxchangeresource.desktop --- kdepim-runtime-4.14.6/resources/openxchange/openxchangeresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/openxchangeresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -9,7 +9,7 @@ Name[de]=Open-Xchange-Groupware-Server Name[el]=Εξυπηρετητής Groupware OpenXchange Name[en_GB]=Open-Xchange Groupware Server -Name[es]=Servidor de trabajo en grupo Open-Xchange +Name[es]=Servidor de colaboración Open-Xchange Name[et]=Open-Xchange'i grupitöö server Name[fi]=Open-Xchange-työryhmäpalvelin Name[fr]=Serveur de logiciels de collaboration Open-Xchange @@ -70,6 +70,7 @@ Comment[pt_BR]="Fornece acesso aos compromissos, tarefas e contatos de um servidor groupware Open-Xchange." Comment[ru]="Доступ к встречам, задачам и контактам на сервере совместной работы Open-Xchange" Comment[sk]="Poskytuje prístup k schôdzkam, úlohám a kontaktom groupware servera Open-Xchange." +Comment[sl]=»Omogoča dostop do sestankov, opravil in stikov, shranjenih na strežniku za skupinsko delo Open-Xchange.« Comment[sr]="Омогућава приступ састанцима, пословима и контактима са Опен‑ексчејнџовог групверског сервера." Comment[sr@ijekavian]="Омогућава приступ састанцима, пословима и контактима са Опен‑ексчејнџовог групверског сервера." Comment[sr@ijekavianlatin]="Omogućava pristup sastancima, poslovima i kontaktima sa Open‑Xchangeovog grupverskog servera." @@ -78,6 +79,7 @@ Comment[tr]="Open-Xchange groupware sunucusundaki toplantı, yapılacak iş ve kişilere erişimi sağlar." Comment[uk]="Надає доступ до записів зустрічей, завдань і контактів, які зберігаються на сервері групової роботи Open-Xchange." Comment[x-test]=xx"Provides access to the appointments, tasks, and contacts of an Open-Xchange groupware server."xx +Comment[zh_CN]=“提供对存储在 Open-Xchange 服务器上的约会、任务和联系人的访问支持。” Comment[zh_TW]=「提供存取儲存在 Open-Xchange 群組伺服器上的約會、工作與聯絡人的功能。」 Type=AkonadiResource Exec=akonadi_openxchange_resource diff -Nru kdepim-runtime-4.14.6/resources/openxchange/openxchangeresource.h kdepim-runtime-15.08.0/resources/openxchange/openxchangeresource.h --- kdepim-runtime-4.14.6/resources/openxchange/openxchangeresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/openxchangeresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,64 +20,63 @@ #ifndef OPENXCHANGERESOURCE_H #define OPENXCHANGERESOURCE_H -#include +#include class OpenXchangeResource : public Akonadi::ResourceBase, public Akonadi::AgentBase::ObserverV2 { - Q_OBJECT + Q_OBJECT - public: - explicit OpenXchangeResource( const QString &id ); +public: + explicit OpenXchangeResource(const QString &id); ~OpenXchangeResource(); - virtual void cleanup(); + void cleanup() Q_DECL_OVERRIDE; - public Q_SLOTS: - virtual void configure( WId windowId ); - virtual void aboutToQuit(); - - protected Q_SLOTS: - void retrieveCollections(); - void retrieveItems( const Akonadi::Collection &collection ); - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - - protected: - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); - virtual void itemRemoved( const Akonadi::Item &item ); - virtual void itemMoved( const Akonadi::Item &item, const Akonadi::Collection &collectionSource, - const Akonadi::Collection &collectionDestination ); +public Q_SLOTS: + void configure(WId windowId) Q_DECL_OVERRIDE; + void aboutToQuit() Q_DECL_OVERRIDE; + +protected Q_SLOTS: + void retrieveCollections() Q_DECL_OVERRIDE; + void retrieveItems(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + bool retrieveItem(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + +protected: + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + void itemRemoved(const Akonadi::Item &item) Q_DECL_OVERRIDE; + virtual void itemMoved(const Akonadi::Item &item, const Akonadi::Collection &collectionSource, + const Akonadi::Collection &collectionDestination) Q_DECL_OVERRIDE; - - virtual void collectionAdded( const Akonadi::Collection &collection, const Akonadi::Collection &parent ); - virtual void collectionChanged( const Akonadi::Collection &collection ); + void collectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &parent) Q_DECL_OVERRIDE; + void collectionChanged(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; // do not hide the other variant, use implementation from base class // which just forwards to the one above using Akonadi::AgentBase::ObserverV2::collectionChanged; - virtual void collectionRemoved( const Akonadi::Collection &collection ); - virtual void collectionMoved( const Akonadi::Collection &collection, const Akonadi::Collection &collectionSource, - const Akonadi::Collection &collectionDestination ); - - private Q_SLOTS: - void onUpdateUsersJobFinished( KJob* ); - void onFoldersRequestJobFinished( KJob* ); - void onFoldersRequestDeltaJobFinished( KJob* ); - void onFolderCreateJobFinished( KJob* ); - void onFolderModifyJobFinished( KJob* ); - void onFolderMoveJobFinished( KJob* ); - void onFolderDeleteJobFinished( KJob* ); - - void onObjectsRequestJobFinished( KJob* ); - void onObjectsRequestDeltaJobFinished( KJob* ); - void onObjectRequestJobFinished( KJob* ); - void onObjectCreateJobFinished( KJob* ); - void onObjectModifyJobFinished( KJob* ); - void onObjectMoveJobFinished( KJob* ); - void onObjectDeleteJobFinished( KJob* ); + void collectionRemoved(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + virtual void collectionMoved(const Akonadi::Collection &collection, const Akonadi::Collection &collectionSource, + const Akonadi::Collection &collectionDestination) Q_DECL_OVERRIDE; + +private Q_SLOTS: + void onUpdateUsersJobFinished(KJob *); + void onFoldersRequestJobFinished(KJob *); + void onFoldersRequestDeltaJobFinished(KJob *); + void onFolderCreateJobFinished(KJob *); + void onFolderModifyJobFinished(KJob *); + void onFolderMoveJobFinished(KJob *); + void onFolderDeleteJobFinished(KJob *); + + void onObjectsRequestJobFinished(KJob *); + void onObjectsRequestDeltaJobFinished(KJob *); + void onObjectRequestJobFinished(KJob *); + void onObjectCreateJobFinished(KJob *); + void onObjectModifyJobFinished(KJob *); + void onObjectMoveJobFinished(KJob *); + void onObjectDeleteJobFinished(KJob *); - void onFetchResourceCollectionsFinished( KJob* ); + void onFetchResourceCollectionsFinished(KJob *); - private: +private: void syncCollectionsRemoteIdCache(); QMap mCollectionsMap; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/connectiontestjob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/connectiontestjob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/connectiontestjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/connectiontestjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,52 +26,52 @@ using namespace OXA; -ConnectionTestJob::ConnectionTestJob( const QString &url, const QString &user, const QString &password, QObject *parent ) - : KJob( parent ), mUrl( url ), mUser( user ), mPassword( password ) +ConnectionTestJob::ConnectionTestJob(const QString &url, const QString &user, const QString &password, QObject *parent) + : KJob(parent), mUrl(url), mUser(user), mPassword(password) { } void ConnectionTestJob::start() { - const KUrl url( mUrl + QString::fromLatin1( "/ajax/login?action=login&name=%1&password=%2" ).arg( mUser ).arg( mPassword ) ); + const QUrl url(mUrl + QString::fromLatin1("/ajax/login?action=login&name=%1&password=%2").arg(mUser).arg(mPassword)); - KJob *job = KIO::storedGet( url, KIO::Reload, KIO::HideProgressInfo ); - connect( job, SIGNAL(result(KJob*)), SLOT(httpJobFinished(KJob*)) ); + KJob *job = KIO::storedGet(url, KIO::Reload, KIO::HideProgressInfo); + connect(job, &KJob::result, this, &ConnectionTestJob::httpJobFinished); } -void ConnectionTestJob::httpJobFinished( KJob *job ) +void ConnectionTestJob::httpJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } - - KIO::StoredTransferJob *transferJob = qobject_cast( job ); - Q_ASSERT( transferJob ); - - const QString data = QString::fromUtf8( transferJob->data() ); + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } + + KIO::StoredTransferJob *transferJob = qobject_cast(job); + Q_ASSERT(transferJob); + + const QString data = QString::fromUtf8(transferJob->data()); + + // on success data contains something like: {"session":"e530578bca504aa89738fadde9e44b3d","random":"ac9090d2cc284fed926fa3c7e316c43b"} + // on failure data contains something like: {"category":1,"error_params":[],"error":"Invalid credentials.","error_id":"-1529642166-37","code":"LGI-0006"} + const int index = data.indexOf(QLatin1String("\"session\":\"")); + if (index == -1) { // error case + const int errorIndex = data.indexOf(QLatin1String("\"error\":\"")); + const QString errorText = data.mid(errorIndex + 9, data.indexOf(QLatin1Char('"'), errorIndex + 10) - errorIndex - 9); + + setError(UserDefinedError); + setErrorText(errorText); + emitResult(); + return; + } else { // success case + const QString sessionId = data.mid(index + 11, 33); // I assume here the session id is always 32 characters long :} + + // logout correctly... + const QUrl url(mUrl + QString::fromLatin1("/ajax/login?action=logout&session=%1").arg(sessionId)); + KIO::storedGet(url, KIO::Reload, KIO::HideProgressInfo); + } - // on success data contains something like: {"session":"e530578bca504aa89738fadde9e44b3d","random":"ac9090d2cc284fed926fa3c7e316c43b"} - // on failure data contains something like: {"category":1,"error_params":[],"error":"Invalid credentials.","error_id":"-1529642166-37","code":"LGI-0006"} - const int index = data.indexOf( QLatin1String( "\"session\":\"" ) ); - if ( index == -1 ) { // error case - const int errorIndex = data.indexOf( QLatin1String( "\"error\":\"" ) ); - const QString errorText = data.mid( errorIndex + 9, data.indexOf( QLatin1Char( '"' ), errorIndex + 10 ) - errorIndex - 9 ); - - setError( UserDefinedError ); - setErrorText( errorText ); emitResult(); - return; - } else { // success case - const QString sessionId = data.mid( index + 11, 33 ); // I assume here the session id is always 32 characters long :} - - // logout correctly... - const KUrl url( mUrl + QString::fromLatin1( "/ajax/login?action=logout&session=%1" ).arg( sessionId ) ); - KIO::storedGet( url, KIO::Reload, KIO::HideProgressInfo ); - } - - emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/connectiontestjob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/connectiontestjob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/connectiontestjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/connectiontestjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,21 +24,22 @@ #include -namespace OXA { +namespace OXA +{ class ConnectionTestJob : public KJob { - Q_OBJECT + Q_OBJECT - public: - ConnectionTestJob( const QString &url, const QString &user, const QString &password, QObject *parent = 0 ); +public: + ConnectionTestJob(const QString &url, const QString &user, const QString &password, QObject *parent = Q_NULLPTR); - virtual void start(); + void start() Q_DECL_OVERRIDE; - private Q_SLOTS: - void httpJobFinished( KJob* ); +private Q_SLOTS: + void httpJobFinished(KJob *); - private: +private: QString mUrl; QString mUser; QString mPassword; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/contactutils.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/contactutils.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/contactutils.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/contactutils.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -25,400 +25,411 @@ #include "oxutils.h" #include "users.h" -#include +#include #include #include using namespace OXA; -void OXA::ContactUtils::parseContact( const QDomElement &propElement, Object &object ) +void OXA::ContactUtils::parseContact(const QDomElement &propElement, Object &object) { - bool isDistributionList = false; - QDomElement distributionListElement = propElement.firstChildElement( QLatin1String("distributionlist_flag") ); - if ( !distributionListElement.isNull() ) { - if ( OXUtils::readBoolean( distributionListElement.text() ) == true ) - isDistributionList = true; - } - - if ( isDistributionList ) { - KABC::ContactGroup contactGroup; - - QDomElement element = propElement.firstChildElement(); - while ( !element.isNull() ) { - const QString tagName = element.tagName(); - const QString text = OXUtils::readString( element.text() ); - - if ( tagName == QLatin1String( "displayname" ) ) { - contactGroup.setName( text ); - } else if ( tagName == QLatin1String( "distributionlist" ) ) { - QDomElement emailElement = element.firstChildElement(); - while ( !emailElement.isNull() ) { - const QString tagName = emailElement.tagName(); - const QString text = OXUtils::readString( emailElement.text() ); - - if ( tagName == QLatin1String( "email" ) ) { - const int emailField = OXUtils::readNumber( emailElement.attribute( QLatin1String( "emailfield" ) ) ); - if ( emailField == 0 ) { // internal data - KABC::ContactGroup::Data data; - data.setName( OXUtils::readString( emailElement.attribute( QLatin1String( "displayname" ) ) ) ); - data.setEmail( text ); - - contactGroup.append( data ); - } else { // external reference - // we convert them to internal data, seems like a more stable approach - KABC::ContactGroup::Data data; - const qlonglong uid = OXUtils::readNumber( emailElement.attribute( QLatin1String( "id" ) ) ); - - const User user = Users::self()->lookupUid( uid ); - if ( user.isValid() ) { - data.setName( user.name() ); - data.setEmail( user.email() ); - } else { - // fallback: use the data from the element - data.setName( OXUtils::readString( emailElement.attribute( QLatin1String( "displayname" ) ) ) ); - data.setEmail( text ); - } + bool isDistributionList = false; + QDomElement distributionListElement = propElement.firstChildElement(QStringLiteral("distributionlist_flag")); + if (!distributionListElement.isNull()) { + if (OXUtils::readBoolean(distributionListElement.text()) == true) { + isDistributionList = true; + } + } - contactGroup.append( data ); - } - } + if (isDistributionList) { + KContacts::ContactGroup contactGroup; - emailElement = emailElement.nextSiblingElement(); + QDomElement element = propElement.firstChildElement(); + while (!element.isNull()) { + const QString tagName = element.tagName(); + const QString text = OXUtils::readString(element.text()); + + if (tagName == QLatin1String("displayname")) { + contactGroup.setName(text); + } else if (tagName == QLatin1String("distributionlist")) { + QDomElement emailElement = element.firstChildElement(); + while (!emailElement.isNull()) { + const QString tagName = emailElement.tagName(); + const QString text = OXUtils::readString(emailElement.text()); + + if (tagName == QLatin1String("email")) { + const int emailField = OXUtils::readNumber(emailElement.attribute(QLatin1String("emailfield"))); + if (emailField == 0) { // internal data + KContacts::ContactGroup::Data data; + data.setName(OXUtils::readString(emailElement.attribute(QLatin1String("displayname")))); + data.setEmail(text); + + contactGroup.append(data); + } else { // external reference + // we convert them to internal data, seems like a more stable approach + KContacts::ContactGroup::Data data; + const qlonglong uid = OXUtils::readNumber(emailElement.attribute(QLatin1String("id"))); + + const User user = Users::self()->lookupUid(uid); + if (user.isValid()) { + data.setName(user.name()); + data.setEmail(user.email()); + } else { + // fallback: use the data from the element + data.setName(OXUtils::readString(emailElement.attribute(QLatin1String("displayname")))); + data.setEmail(text); + } + + contactGroup.append(data); + } + } + + emailElement = emailElement.nextSiblingElement(); + } + } + element = element.nextSiblingElement(); } - } - element = element.nextSiblingElement(); - } - object.setContactGroup( contactGroup ); - } else { - KABC::Addressee contact; - KABC::Address homeAddress( KABC::Address::Home ); - KABC::Address workAddress( KABC::Address::Work ); - KABC::Address otherAddress( KABC::Address::Dom ); - - QDomElement element = propElement.firstChildElement(); - while ( !element.isNull() ) { - const QString tagName = element.tagName(); - const QString text = OXUtils::readString( element.text() ); - - // name - if ( tagName == QLatin1String( "title" ) ) { - contact.setTitle( text ); - } else if ( tagName == QLatin1String( "first_name" ) ) { - contact.setGivenName( text ); - } else if ( tagName == QLatin1String( "second_name" ) ) { - contact.setAdditionalName( text ); - } else if ( tagName == QLatin1String( "last_name" ) ) { - contact.setFamilyName( text ); - } else if ( tagName == QLatin1String( "suffix" ) ) { - contact.setSuffix( text ); - } else if ( tagName == QLatin1String( "displayname" ) ) { - contact.setFormattedName( text ); - } else if ( tagName == QLatin1String( "nickname" ) ) { - contact.setNickName( text ); - // dates - } else if ( tagName == QLatin1String( "birthday" ) ) { - contact.setBirthday( OXUtils::readDateTime( element.text() ) ); - } else if ( tagName == QLatin1String( "anniversary" ) ) { - contact.insertCustom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-Anniversary" ), OXUtils::readDateTime( element.text() ).toString( Qt::ISODate ) ); - } else if ( tagName == QLatin1String( "spouse_name" ) ) { - contact.insertCustom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-SpousesName" ), text ); - // addresses - } else if ( tagName == QLatin1String( "street" ) ) { - homeAddress.setStreet( text ); - } else if ( tagName == QLatin1String( "postal_code" ) ) { - homeAddress.setPostalCode( text ); - } else if ( tagName == QLatin1String( "city" ) ) { - homeAddress.setLocality( text ); - } else if ( tagName == QLatin1String( "country" ) ) { - homeAddress.setCountry( text ); - } else if ( tagName == QLatin1String( "state" ) ) { - homeAddress.setRegion( text ); - } else if ( tagName == QLatin1String( "business_street" ) ) { - workAddress.setStreet( text ); - } else if ( tagName == QLatin1String( "business_postal_code" ) ) { - workAddress.setPostalCode( text ); - } else if ( tagName == QLatin1String( "business_city" ) ) { - workAddress.setLocality( text ); - } else if ( tagName == QLatin1String( "business_country" ) ) { - workAddress.setCountry( text ); - } else if ( tagName == QLatin1String( "business_state" ) ) { - workAddress.setRegion( text ); - } else if ( tagName == QLatin1String( "second_street" ) ) { - otherAddress.setStreet( text ); - } else if ( tagName == QLatin1String( "second_postal_code" ) ) { - otherAddress.setPostalCode( text ); - } else if ( tagName == QLatin1String( "second_city" ) ) { - otherAddress.setLocality( text ); - } else if ( tagName == QLatin1String( "second_country" ) ) { - otherAddress.setCountry( text ); - } else if ( tagName == QLatin1String( "second_state" ) ) { - otherAddress.setRegion( text ); - } else if ( tagName == QLatin1String( "defaultaddress" ) ) { - const int number = text.toInt(); - if ( number == 1 ) - workAddress.setType( workAddress.type() | KABC::Address::Pref ); - else if ( number == 2 ) - homeAddress.setType( homeAddress.type() | KABC::Address::Pref ); - else if ( number == 3 ) - otherAddress.setType( otherAddress.type() | KABC::Address::Pref ); - // further information - } else if ( tagName == QLatin1String( "note" ) ) { - contact.setNote( text ); - } else if ( tagName == QLatin1String( "url" ) ) { - contact.setUrl( text ); - } else if ( tagName == QLatin1String( "image1" ) ) { - const QByteArray data = text.toUtf8(); - contact.setPhoto( KABC::Picture( QImage::fromData( QByteArray::fromBase64( data ) ) ) ); - // company information - } else if ( tagName == QLatin1String( "company" ) ) { - contact.setOrganization( text ); - } else if ( tagName == QLatin1String( "department" ) ) { - contact.setDepartment( text ); - } else if ( tagName == QLatin1String( "assistants_name" ) ) { - contact.insertCustom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-AssistantsName" ), text ); - } else if ( tagName == QLatin1String( "managers_name" ) ) { - contact.insertCustom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-ManagersName" ), text ); - } else if ( tagName == QLatin1String( "position" ) ) { - contact.setRole( text ); - } else if ( tagName == QLatin1String( "profession" ) ) { - contact.insertCustom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-Profession" ), text ); - } else if ( tagName == QLatin1String( "room_number" ) ) { - contact.insertCustom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-Office" ), text ); - // communication - } else if ( tagName == QLatin1String( "email1" ) ) { - contact.insertEmail( text, true ); - } else if ( tagName == QLatin1String( "email2" ) || - tagName == QLatin1String( "email3" ) ) { - contact.insertEmail( text ); - } else if ( tagName == QLatin1String( "mobile1" ) ) { - contact.insertPhoneNumber( KABC::PhoneNumber( text, KABC::PhoneNumber::Cell ) ); - } else if ( tagName == QLatin1String( "instant_messenger" ) ) { - contact.insertCustom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-IMAddress" ), text ); - } else if ( tagName.startsWith( QLatin1String( "phone_" ) ) ) { - KABC::PhoneNumber number; - number.setNumber( text ); - bool supportedType = false; - - if ( tagName.endsWith( QLatin1String( "_business" ) ) ) { - number.setType( KABC::PhoneNumber::Work ); - supportedType = true; - } else if ( tagName.endsWith( QLatin1String( "_home" ) ) ) { - number.setType( KABC::PhoneNumber::Home ); - supportedType = true; - } else if ( tagName.endsWith( QLatin1String( "_other" ) ) ) { - number.setType( KABC::PhoneNumber::Voice ); - supportedType = true; - } else if ( tagName.endsWith( QLatin1String( "_car" ) ) ) { - number.setType( KABC::PhoneNumber::Car ); - supportedType = true; - } - - if ( supportedType ) - contact.insertPhoneNumber( number ); - } else if ( tagName.startsWith( QLatin1String( "fax_" ) ) ) { - KABC::PhoneNumber number; - number.setNumber( text ); - bool supportedType = false; - - if ( tagName.endsWith( QLatin1String( "_business" ) ) ) { - number.setType( KABC::PhoneNumber::Fax | KABC::PhoneNumber::Work ); - supportedType = true; - } else if ( tagName.endsWith( QLatin1String( "_home" ) ) ) { - number.setType( KABC::PhoneNumber::Fax | KABC::PhoneNumber::Home ); - supportedType = true; - } else if ( tagName.endsWith( QLatin1String( "_other" ) ) ) { - number.setType( KABC::PhoneNumber::Fax | KABC::PhoneNumber::Voice ); - supportedType = true; - } - - if ( supportedType ) - contact.insertPhoneNumber( number ); - } else if ( tagName == QLatin1String( "pager" ) ) { - contact.insertPhoneNumber( KABC::PhoneNumber( text, KABC::PhoneNumber::Pager ) ); - } else if ( tagName == QLatin1String( "categories" ) ) { - contact.setCategories( text.split( QRegExp( QLatin1String( ",\\s*" ) ) ) ); - } + object.setContactGroup(contactGroup); + } else { + KContacts::Addressee contact; + KContacts::Address homeAddress(KContacts::Address::Home); + KContacts::Address workAddress(KContacts::Address::Work); + KContacts::Address otherAddress(KContacts::Address::Dom); + + QDomElement element = propElement.firstChildElement(); + while (!element.isNull()) { + const QString tagName = element.tagName(); + const QString text = OXUtils::readString(element.text()); + + // name + if (tagName == QLatin1String("title")) { + contact.setTitle(text); + } else if (tagName == QLatin1String("first_name")) { + contact.setGivenName(text); + } else if (tagName == QLatin1String("second_name")) { + contact.setAdditionalName(text); + } else if (tagName == QLatin1String("last_name")) { + contact.setFamilyName(text); + } else if (tagName == QLatin1String("suffix")) { + contact.setSuffix(text); + } else if (tagName == QLatin1String("displayname")) { + contact.setFormattedName(text); + } else if (tagName == QLatin1String("nickname")) { + contact.setNickName(text); + // dates + } else if (tagName == QLatin1String("birthday")) { + contact.setBirthday(OXUtils::readDateTime(element.text())); + } else if (tagName == QLatin1String("anniversary")) { + contact.insertCustom(QLatin1String("KADDRESSBOOK"), QStringLiteral("X-Anniversary"), OXUtils::readDateTime(element.text()).toString(Qt::ISODate)); + } else if (tagName == QLatin1String("spouse_name")) { + contact.insertCustom(QLatin1String("KADDRESSBOOK"), QStringLiteral("X-SpousesName"), text); + // addresses + } else if (tagName == QLatin1String("street")) { + homeAddress.setStreet(text); + } else if (tagName == QLatin1String("postal_code")) { + homeAddress.setPostalCode(text); + } else if (tagName == QLatin1String("city")) { + homeAddress.setLocality(text); + } else if (tagName == QLatin1String("country")) { + homeAddress.setCountry(text); + } else if (tagName == QLatin1String("state")) { + homeAddress.setRegion(text); + } else if (tagName == QLatin1String("business_street")) { + workAddress.setStreet(text); + } else if (tagName == QLatin1String("business_postal_code")) { + workAddress.setPostalCode(text); + } else if (tagName == QLatin1String("business_city")) { + workAddress.setLocality(text); + } else if (tagName == QLatin1String("business_country")) { + workAddress.setCountry(text); + } else if (tagName == QLatin1String("business_state")) { + workAddress.setRegion(text); + } else if (tagName == QLatin1String("second_street")) { + otherAddress.setStreet(text); + } else if (tagName == QLatin1String("second_postal_code")) { + otherAddress.setPostalCode(text); + } else if (tagName == QLatin1String("second_city")) { + otherAddress.setLocality(text); + } else if (tagName == QLatin1String("second_country")) { + otherAddress.setCountry(text); + } else if (tagName == QLatin1String("second_state")) { + otherAddress.setRegion(text); + } else if (tagName == QLatin1String("defaultaddress")) { + const int number = text.toInt(); + if (number == 1) { + workAddress.setType(workAddress.type() | KContacts::Address::Pref); + } else if (number == 2) { + homeAddress.setType(homeAddress.type() | KContacts::Address::Pref); + } else if (number == 3) { + otherAddress.setType(otherAddress.type() | KContacts::Address::Pref); + } + // further information + } else if (tagName == QLatin1String("note")) { + contact.setNote(text); + } else if (tagName == QLatin1String("url")) { + KContacts::ResourceLocatorUrl url; + url.setUrl(QUrl(text)); + contact.setUrl(url); + } else if (tagName == QLatin1String("image1")) { + const QByteArray data = text.toUtf8(); + contact.setPhoto(KContacts::Picture(QImage::fromData(QByteArray::fromBase64(data)))); + // company information + } else if (tagName == QLatin1String("company")) { + contact.setOrganization(text); + } else if (tagName == QLatin1String("department")) { + contact.setDepartment(text); + } else if (tagName == QLatin1String("assistants_name")) { + contact.insertCustom(QLatin1String("KADDRESSBOOK"), QStringLiteral("X-AssistantsName"), text); + } else if (tagName == QLatin1String("managers_name")) { + contact.insertCustom(QLatin1String("KADDRESSBOOK"), QStringLiteral("X-ManagersName"), text); + } else if (tagName == QLatin1String("position")) { + contact.setRole(text); + } else if (tagName == QLatin1String("profession")) { + contact.insertCustom(QLatin1String("KADDRESSBOOK"), QStringLiteral("X-Profession"), text); + } else if (tagName == QLatin1String("room_number")) { + contact.insertCustom(QLatin1String("KADDRESSBOOK"), QStringLiteral("X-Office"), text); + // communication + } else if (tagName == QLatin1String("email1")) { + contact.insertEmail(text, true); + } else if (tagName == QLatin1String("email2") || + tagName == QLatin1String("email3")) { + contact.insertEmail(text); + } else if (tagName == QLatin1String("mobile1")) { + contact.insertPhoneNumber(KContacts::PhoneNumber(text, KContacts::PhoneNumber::Cell)); + } else if (tagName == QLatin1String("instant_messenger")) { + contact.insertCustom(QLatin1String("KADDRESSBOOK"), QStringLiteral("X-IMAddress"), text); + } else if (tagName.startsWith(QLatin1String("phone_"))) { + KContacts::PhoneNumber number; + number.setNumber(text); + bool supportedType = false; + + if (tagName.endsWith(QLatin1String("_business"))) { + number.setType(KContacts::PhoneNumber::Work); + supportedType = true; + } else if (tagName.endsWith(QLatin1String("_home"))) { + number.setType(KContacts::PhoneNumber::Home); + supportedType = true; + } else if (tagName.endsWith(QLatin1String("_other"))) { + number.setType(KContacts::PhoneNumber::Voice); + supportedType = true; + } else if (tagName.endsWith(QLatin1String("_car"))) { + number.setType(KContacts::PhoneNumber::Car); + supportedType = true; + } + + if (supportedType) { + contact.insertPhoneNumber(number); + } + } else if (tagName.startsWith(QLatin1String("fax_"))) { + KContacts::PhoneNumber number; + number.setNumber(text); + bool supportedType = false; + + if (tagName.endsWith(QLatin1String("_business"))) { + number.setType(KContacts::PhoneNumber::Fax | KContacts::PhoneNumber::Work); + supportedType = true; + } else if (tagName.endsWith(QLatin1String("_home"))) { + number.setType(KContacts::PhoneNumber::Fax | KContacts::PhoneNumber::Home); + supportedType = true; + } else if (tagName.endsWith(QLatin1String("_other"))) { + number.setType(KContacts::PhoneNumber::Fax | KContacts::PhoneNumber::Voice); + supportedType = true; + } + + if (supportedType) { + contact.insertPhoneNumber(number); + } + } else if (tagName == QLatin1String("pager")) { + contact.insertPhoneNumber(KContacts::PhoneNumber(text, KContacts::PhoneNumber::Pager)); + } else if (tagName == QLatin1String("categories")) { + contact.setCategories(text.split(QRegExp(QStringLiteral(",\\s*")))); + } - element = element.nextSiblingElement(); - } + element = element.nextSiblingElement(); + } - if ( !homeAddress.isEmpty() ) - contact.insertAddress( homeAddress ); - if ( !workAddress.isEmpty() ) - contact.insertAddress( workAddress ); - if ( !otherAddress.isEmpty() ) - contact.insertAddress( otherAddress ); + if (!homeAddress.isEmpty()) { + contact.insertAddress(homeAddress); + } + if (!workAddress.isEmpty()) { + contact.insertAddress(workAddress); + } + if (!otherAddress.isEmpty()) { + contact.insertAddress(otherAddress); + } - object.setContact( contact ); - } + object.setContact(contact); + } } -void OXA::ContactUtils::addContactElements( QDomDocument &document, QDomElement &propElement, const Object &object, void *preloadedData ) +void OXA::ContactUtils::addContactElements(QDomDocument &document, QDomElement &propElement, const Object &object, void *preloadedData) { - if ( !object.contact().isEmpty() ) { - // it is a contact payload + if (!object.contact().isEmpty()) { + // it is a contact payload - const KABC::Addressee contact = object.contact(); + const KContacts::Addressee contact = object.contact(); - // name - DAVUtils::addOxElement( document, propElement, QLatin1String( "title" ), OXUtils::writeString( contact.title() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "first_name" ), OXUtils::writeString( contact.givenName() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "second_name" ), OXUtils::writeString( contact.additionalName() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "last_name" ), OXUtils::writeString( contact.familyName() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "suffix" ), OXUtils::writeString( contact.suffix() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "displayname" ), OXUtils::writeString( contact.formattedName() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "nickname" ), OXUtils::writeString( contact.nickName() ) ); - - // dates - if ( contact.birthday().date().isValid() ) - DAVUtils::addOxElement( document, propElement, QLatin1String( "birthday" ), OXUtils::writeDate( contact.birthday().date() ) ); - else - DAVUtils::addOxElement( document, propElement, QLatin1String( "birthday" ) ); - - // since QDateTime::to/fromString() doesn't carry timezone information, we have to fake it here - const QDate anniversary = QDate::fromString( contact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-Anniversary" ) ), Qt::ISODate ); - if ( anniversary.isValid() ) - DAVUtils::addOxElement( document, propElement, QLatin1String( "anniversary" ), OXUtils::writeDate( anniversary ) ); - else - DAVUtils::addOxElement( document, propElement, QLatin1String( "anniversary" ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "spouse_name" ), OXUtils::writeString( contact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-SpousesName" ) ) ) ); - - // addresses - const KABC::Address homeAddress = contact.address( KABC::Address::Home ); - if ( !homeAddress.isEmpty() ) { - DAVUtils::addOxElement( document, propElement, QLatin1String( "street" ), OXUtils::writeString( homeAddress.street() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "postal_code" ), OXUtils::writeString( homeAddress.postalCode() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "city" ), OXUtils::writeString( homeAddress.locality() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "state" ), OXUtils::writeString( homeAddress.region() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "country" ), OXUtils::writeString( homeAddress.country() ) ); - } - const KABC::Address workAddress = contact.address( KABC::Address::Work ); - if ( !workAddress.isEmpty() ) { - DAVUtils::addOxElement( document, propElement, QLatin1String( "business_street" ), OXUtils::writeString( workAddress.street() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "business_postal_code" ), OXUtils::writeString( workAddress.postalCode() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "business_city" ), OXUtils::writeString( workAddress.locality() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "business_state" ), OXUtils::writeString( workAddress.region() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "business_country" ), OXUtils::writeString( workAddress.country() ) ); - } - const KABC::Address otherAddress = contact.address( KABC::Address::Dom ); - if ( !otherAddress.isEmpty() ) { - DAVUtils::addOxElement( document, propElement, QLatin1String( "second_street" ), OXUtils::writeString( otherAddress.street() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "second_postal_code" ), OXUtils::writeString( otherAddress.postalCode() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "second_city" ), OXUtils::writeString( otherAddress.locality() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "second_state" ), OXUtils::writeString( otherAddress.region() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "second_country" ), OXUtils::writeString( otherAddress.country() ) ); - } + // name + DAVUtils::addOxElement(document, propElement, QStringLiteral("title"), OXUtils::writeString(contact.title())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("first_name"), OXUtils::writeString(contact.givenName())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("second_name"), OXUtils::writeString(contact.additionalName())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("last_name"), OXUtils::writeString(contact.familyName())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("suffix"), OXUtils::writeString(contact.suffix())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("displayname"), OXUtils::writeString(contact.formattedName())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("nickname"), OXUtils::writeString(contact.nickName())); + + // dates + if (contact.birthday().date().isValid()) { + DAVUtils::addOxElement(document, propElement, QStringLiteral("birthday"), OXUtils::writeDate(contact.birthday().date())); + } else { + DAVUtils::addOxElement(document, propElement, QStringLiteral("birthday")); + } - // further information - DAVUtils::addOxElement( document, propElement, QLatin1String( "note" ), OXUtils::writeString( contact.note() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "url" ), OXUtils::writeString( contact.url().url() ) ); - - // image - const KABC::Picture photo = contact.photo(); - if ( !photo.data().isNull() ) { - QByteArray imageData; - QBuffer buffer( &imageData ); - buffer.open( QIODevice::WriteOnly ); - - QString contentType; - if ( !photo.data().hasAlphaChannel() ) { - photo.data().save( &buffer, "JPEG" ); - contentType = QLatin1String( "image/jpg" ); - } else { - photo.data().save( &buffer, "PNG" ); - contentType = QLatin1String( "image/png" ); - } + // since QDateTime::to/fromString() doesn't carry timezone information, we have to fake it here + const QDate anniversary = QDate::fromString(contact.custom(QLatin1String("KADDRESSBOOK"), QStringLiteral("X-Anniversary")), Qt::ISODate); + if (anniversary.isValid()) { + DAVUtils::addOxElement(document, propElement, QStringLiteral("anniversary"), OXUtils::writeDate(anniversary)); + } else { + DAVUtils::addOxElement(document, propElement, QStringLiteral("anniversary")); + } + DAVUtils::addOxElement(document, propElement, QStringLiteral("spouse_name"), OXUtils::writeString(contact.custom(QLatin1String("KADDRESSBOOK"), QStringLiteral("X-SpousesName")))); - buffer.close(); + // addresses + const KContacts::Address homeAddress = contact.address(KContacts::Address::Home); + if (!homeAddress.isEmpty()) { + DAVUtils::addOxElement(document, propElement, QStringLiteral("street"), OXUtils::writeString(homeAddress.street())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("postal_code"), OXUtils::writeString(homeAddress.postalCode())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("city"), OXUtils::writeString(homeAddress.locality())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("state"), OXUtils::writeString(homeAddress.region())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("country"), OXUtils::writeString(homeAddress.country())); + } + const KContacts::Address workAddress = contact.address(KContacts::Address::Work); + if (!workAddress.isEmpty()) { + DAVUtils::addOxElement(document, propElement, QStringLiteral("business_street"), OXUtils::writeString(workAddress.street())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("business_postal_code"), OXUtils::writeString(workAddress.postalCode())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("business_city"), OXUtils::writeString(workAddress.locality())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("business_state"), OXUtils::writeString(workAddress.region())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("business_country"), OXUtils::writeString(workAddress.country())); + } + const KContacts::Address otherAddress = contact.address(KContacts::Address::Dom); + if (!otherAddress.isEmpty()) { + DAVUtils::addOxElement(document, propElement, QStringLiteral("second_street"), OXUtils::writeString(otherAddress.street())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("second_postal_code"), OXUtils::writeString(otherAddress.postalCode())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("second_city"), OXUtils::writeString(otherAddress.locality())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("second_state"), OXUtils::writeString(otherAddress.region())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("second_country"), OXUtils::writeString(otherAddress.country())); + } - DAVUtils::addOxElement( document, propElement, QLatin1String( "image1" ), QString::fromLatin1( imageData.toBase64() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "image_content_type" ), contentType ); - } else { - DAVUtils::addOxElement( document, propElement, QLatin1String( "image1" ) ); - } + // further information + DAVUtils::addOxElement(document, propElement, QStringLiteral("note"), OXUtils::writeString(contact.note())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("url"), OXUtils::writeString(contact.url().url().url())); + + // image + const KContacts::Picture photo = contact.photo(); + if (!photo.data().isNull()) { + QByteArray imageData; + QBuffer buffer(&imageData); + buffer.open(QIODevice::WriteOnly); + + QString contentType; + if (!photo.data().hasAlphaChannel()) { + photo.data().save(&buffer, "JPEG"); + contentType = QLatin1String("image/jpg"); + } else { + photo.data().save(&buffer, "PNG"); + contentType = QLatin1String("image/png"); + } - // company information - DAVUtils::addOxElement( document, propElement, QLatin1String( "company" ), OXUtils::writeString( contact.organization() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "department" ), OXUtils::writeString( contact.department() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "assistants_name" ), OXUtils::writeString( contact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-AssistantsName" ) ) ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "managers_name" ), OXUtils::writeString( contact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-ManagersName" ) ) ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "position" ), OXUtils::writeString( contact.role() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "profession" ), OXUtils::writeString( contact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-Profession" ) ) ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "room_number" ), OXUtils::writeString( contact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-Office" ) ) ) ); - - // communication - const QStringList emails = contact.emails(); - for ( int i = 0; i < 3 && i < emails.count(); ++i ) { - DAVUtils::addOxElement( document, propElement, QString::fromLatin1( "email%1" ).arg( i + 1 ), OXUtils::writeString( emails.at( i ) ) ); - } + buffer.close(); + + DAVUtils::addOxElement(document, propElement, QStringLiteral("image1"), QString::fromLatin1(imageData.toBase64())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("image_content_type"), contentType); + } else { + DAVUtils::addOxElement(document, propElement, QStringLiteral("image1")); + } - DAVUtils::addOxElement( document, propElement, QLatin1String( "mobile1" ), OXUtils::writeString( contact.phoneNumber( KABC::PhoneNumber::Cell ).number() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "instant_messenger" ), OXUtils::writeString( contact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-IMAddress" ) ) ) ); + // company information + DAVUtils::addOxElement(document, propElement, QStringLiteral("company"), OXUtils::writeString(contact.organization())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("department"), OXUtils::writeString(contact.department())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("assistants_name"), OXUtils::writeString(contact.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-AssistantsName")))); + DAVUtils::addOxElement(document, propElement, QStringLiteral("managers_name"), OXUtils::writeString(contact.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-ManagersName")))); + DAVUtils::addOxElement(document, propElement, QStringLiteral("position"), OXUtils::writeString(contact.role())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("profession"), OXUtils::writeString(contact.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-Profession")))); + DAVUtils::addOxElement(document, propElement, QStringLiteral("room_number"), OXUtils::writeString(contact.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-Office")))); + + // communication + const QStringList emails = contact.emails(); + for (int i = 0; i < 3 && i < emails.count(); ++i) { + DAVUtils::addOxElement(document, propElement, QString::fromLatin1("email%1").arg(i + 1), OXUtils::writeString(emails.at(i))); + } + + DAVUtils::addOxElement(document, propElement, QStringLiteral("mobile1"), OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Cell).number())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("instant_messenger"), OXUtils::writeString(contact.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-IMAddress")))); + + DAVUtils::addOxElement(document, propElement, QStringLiteral("phone_business"), OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Work).number())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("phone_home"), OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Home).number())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("phone_other"), OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Voice).number())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("phone_car"), OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Car).number())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("fax_business"), OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Fax | KContacts::PhoneNumber::Work).number())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("fax_home"), OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Fax | KContacts::PhoneNumber::Home).number())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("fax_other"), OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Fax | KContacts::PhoneNumber::Voice).number())); - DAVUtils::addOxElement( document, propElement, QLatin1String( "phone_business" ), OXUtils::writeString( contact.phoneNumber( KABC::PhoneNumber::Work ).number() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "phone_home" ), OXUtils::writeString( contact.phoneNumber( KABC::PhoneNumber::Home ).number() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "phone_other" ), OXUtils::writeString( contact.phoneNumber( KABC::PhoneNumber::Voice ).number() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "phone_car" ), OXUtils::writeString( contact.phoneNumber( KABC::PhoneNumber::Car ).number() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "fax_business" ), OXUtils::writeString( contact.phoneNumber( KABC::PhoneNumber::Fax | KABC::PhoneNumber::Work ).number() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "fax_home" ), OXUtils::writeString( contact.phoneNumber( KABC::PhoneNumber::Fax | KABC::PhoneNumber::Home ).number() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "fax_other" ), OXUtils::writeString( contact.phoneNumber( KABC::PhoneNumber::Fax | KABC::PhoneNumber::Voice ).number() ) ); - - DAVUtils::addOxElement( document, propElement, QLatin1String( "pager" ), OXUtils::writeString( contact.phoneNumber( KABC::PhoneNumber::Pager ).number() ) ); - - DAVUtils::addOxElement( document, propElement, QLatin1String( "categories" ), OXUtils::writeString( contact.categories().join( QLatin1String( "," ) ) ) ); - } else { - // it is a distribution list payload - - const KABC::ContactGroup contactGroup = object.contactGroup(); - - DAVUtils::addOxElement( document, propElement, QLatin1String( "displayname" ), OXUtils::writeString( contactGroup.name() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "last_name" ), OXUtils::writeString( contactGroup.name() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "distributionlist_flag" ), OXUtils::writeBoolean( true ) ); - - QDomElement distributionList = DAVUtils::addOxElement( document, propElement, QLatin1String( "distributionlist" ) ); - - if ( preloadedData ) { - // the contact group contains contact references that has been preloaded - KABC::Addressee::List *contacts = static_cast( preloadedData ); - foreach ( const KABC::Addressee &contact, *contacts ) { - QDomElement email = DAVUtils::addOxElement( document, distributionList, QLatin1String( "email" ), - OXUtils::writeString( contact.preferredEmail() ) ); - - DAVUtils::setOxAttribute( email, QLatin1String( "folder_id" ), OXUtils::writeNumber( 0 ) ); - DAVUtils::setOxAttribute( email, QLatin1String( "emailfield" ), OXUtils::writeNumber( 0 ) ); - DAVUtils::setOxAttribute( email, QLatin1String( "id" ), OXUtils::writeNumber( 0 ) ); - DAVUtils::setOxAttribute( email, QLatin1String( "displayname" ), OXUtils::writeString( contact.realName() ) ); - } + DAVUtils::addOxElement(document, propElement, QStringLiteral("pager"), OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Pager).number())); - delete contacts; + DAVUtils::addOxElement(document, propElement, QStringLiteral("categories"), OXUtils::writeString(contact.categories().join(QLatin1String(",")))); } else { - // the contact group contains only internal contact data - for ( uint i = 0; i < contactGroup.dataCount(); ++i ) { - const KABC::ContactGroup::Data &data = contactGroup.data( i ); - QDomElement email = DAVUtils::addOxElement( document, distributionList, QLatin1String( "email" ), - OXUtils::writeString( data.email() ) ); - - DAVUtils::setOxAttribute( email, QLatin1String( "folder_id" ), OXUtils::writeNumber( 0 ) ); - DAVUtils::setOxAttribute( email, QLatin1String( "emailfield" ), OXUtils::writeNumber( 0 ) ); - DAVUtils::setOxAttribute( email, QLatin1String( "id" ), OXUtils::writeNumber( 0 ) ); - DAVUtils::setOxAttribute( email, QLatin1String( "displayname" ), OXUtils::writeString( data.name() ) ); - } + // it is a distribution list payload + + const KContacts::ContactGroup contactGroup = object.contactGroup(); + + DAVUtils::addOxElement(document, propElement, QStringLiteral("displayname"), OXUtils::writeString(contactGroup.name())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("last_name"), OXUtils::writeString(contactGroup.name())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("distributionlist_flag"), OXUtils::writeBoolean(true)); + + QDomElement distributionList = DAVUtils::addOxElement(document, propElement, QStringLiteral("distributionlist")); + + if (preloadedData) { + // the contact group contains contact references that has been preloaded + KContacts::Addressee::List *contacts = static_cast(preloadedData); + foreach (const KContacts::Addressee &contact, *contacts) { + QDomElement email = DAVUtils::addOxElement(document, distributionList, QStringLiteral("email"), + OXUtils::writeString(contact.preferredEmail())); + + DAVUtils::setOxAttribute(email, QStringLiteral("folder_id"), OXUtils::writeNumber(0)); + DAVUtils::setOxAttribute(email, QStringLiteral("emailfield"), OXUtils::writeNumber(0)); + DAVUtils::setOxAttribute(email, QStringLiteral("id"), OXUtils::writeNumber(0)); + DAVUtils::setOxAttribute(email, QStringLiteral("displayname"), OXUtils::writeString(contact.realName())); + } + + delete contacts; + } else { + // the contact group contains only internal contact data + for (uint i = 0; i < contactGroup.dataCount(); ++i) { + const KContacts::ContactGroup::Data &data = contactGroup.data(i); + QDomElement email = DAVUtils::addOxElement(document, distributionList, QStringLiteral("email"), + OXUtils::writeString(data.email())); + + DAVUtils::setOxAttribute(email, QStringLiteral("folder_id"), OXUtils::writeNumber(0)); + DAVUtils::setOxAttribute(email, QStringLiteral("emailfield"), OXUtils::writeNumber(0)); + DAVUtils::setOxAttribute(email, QStringLiteral("id"), OXUtils::writeNumber(0)); + DAVUtils::setOxAttribute(email, QStringLiteral("displayname"), OXUtils::writeString(data.name())); + } + } } - } } -KJob* OXA::ContactUtils::preloadJob( const Object &object ) +KJob *OXA::ContactUtils::preloadJob(const Object &object) { - Akonadi::ContactGroupExpandJob *job = new Akonadi::ContactGroupExpandJob( object.contactGroup() ); - return job; + Akonadi::ContactGroupExpandJob *job = new Akonadi::ContactGroupExpandJob(object.contactGroup()); + return job; } -void* OXA::ContactUtils::preloadData( const Object&, KJob *job ) +void *OXA::ContactUtils::preloadData(const Object &, KJob *job) { - Akonadi::ContactGroupExpandJob *expandJob = qobject_cast( job ); - Q_ASSERT( expandJob ); + Akonadi::ContactGroupExpandJob *expandJob = qobject_cast(job); + Q_ASSERT(expandJob); - return new KABC::Addressee::List( expandJob->contacts() ); + return new KContacts::Addressee::List(expandJob->contacts()); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/contactutils.h kdepim-runtime-15.08.0/resources/openxchange/oxa/contactutils.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/contactutils.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/contactutils.h 2015-08-10 21:01:02.000000000 +0000 @@ -29,7 +29,8 @@ class QDomDocument; class QDomElement; -namespace OXA { +namespace OXA +{ /** * Namespace that contains helper methods for handling contacts. @@ -38,18 +39,18 @@ */ namespace ContactUtils { - /** - * Parses the XML tree under @p propElement and fills the contact data of @p object. - */ - void parseContact( const QDomElement &propElement, Object &object ); +/** + * Parses the XML tree under @p propElement and fills the contact data of @p object. + */ +void parseContact(const QDomElement &propElement, Object &object); - /** - * Adds the contact data of @p object to the @p document under the @p propElement. - */ - void addContactElements( QDomDocument &document, QDomElement &propElement, const Object &object, void *preloadedData ); +/** + * Adds the contact data of @p object to the @p document under the @p propElement. + */ +void addContactElements(QDomDocument &document, QDomElement &propElement, const Object &object, void *preloadedData); - KJob* preloadJob( const Object &object ); - void* preloadData( const Object &object, KJob *job ); +KJob *preloadJob(const Object &object); +void *preloadData(const Object &object, KJob *job); } } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/davmanager.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/davmanager.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/davmanager.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/davmanager.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -27,7 +27,7 @@ using namespace OXA; -DavManager* DavManager::mSelf = 0; +DavManager *DavManager::mSelf = Q_NULLPTR; DavManager::DavManager() { @@ -37,36 +37,37 @@ { } -DavManager* DavManager::self() +DavManager *DavManager::self() { - if ( !mSelf ) - mSelf = new DavManager(); + if (!mSelf) { + mSelf = new DavManager(); + } - return mSelf; + return mSelf; } -void DavManager::setBaseUrl( const KUrl &url ) +void DavManager::setBaseUrl(const QUrl &url) { - mBaseUrl = url; + mBaseUrl = url; } -KUrl DavManager::baseUrl() const +QUrl DavManager::baseUrl() const { - return mBaseUrl; + return mBaseUrl; } -KIO::DavJob* DavManager::createFindJob( const QString &path, const QDomDocument &document ) const +KIO::DavJob *DavManager::createFindJob(const QString &path, const QDomDocument &document) const { - KUrl url( mBaseUrl ); - url.setPath( path ); + QUrl url(mBaseUrl); + url.setPath(path); - return KIO::davPropFind( url, document, "0", KIO::HideProgressInfo ); + return KIO::davPropFind(url, document, "0", KIO::HideProgressInfo); } -KIO::DavJob* DavManager::createPatchJob( const QString &path, const QDomDocument &document ) const +KIO::DavJob *DavManager::createPatchJob(const QString &path, const QDomDocument &document) const { - KUrl url( mBaseUrl ); - url.setPath( path ); + QUrl url(mBaseUrl); + url.setPath(path); - return KIO::davPropPatch( url, document, KIO::HideProgressInfo ); + return KIO::davPropPatch(url, document, KIO::HideProgressInfo); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/davmanager.h kdepim-runtime-15.08.0/resources/openxchange/oxa/davmanager.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/davmanager.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/davmanager.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,15 +22,17 @@ #ifndef OXA_DAVMANAGER_H #define OXA_DAVMANAGER_H -#include +#include -namespace KIO { +namespace KIO +{ class DavJob; } class QDomDocument; -namespace OXA { +namespace OXA +{ /** * @short A class that manages DAV specific information. @@ -43,7 +45,7 @@ */ class DavManager { - public: +public: /** * Destroys the DAV manager. */ @@ -52,17 +54,17 @@ /** * Returns the global instance of the DAV manager. */ - static DavManager* self(); + static DavManager *self(); /** * Sets the base @p url the DAV manager should use. */ - void setBaseUrl( const KUrl &url ); + void setBaseUrl(const QUrl &url); /** * Returns the base url the DAV manager uses. */ - KUrl baseUrl() const; + QUrl baseUrl() const; /** * Returns a new DAV find job. @@ -70,7 +72,7 @@ * @param path The path that is appended to the base url. * @param document The request XML document. */ - KIO::DavJob* createFindJob( const QString &path, const QDomDocument &document ) const; + KIO::DavJob *createFindJob(const QString &path, const QDomDocument &document) const; /** * Returns a new DAV patch job. @@ -78,16 +80,16 @@ * @param path The path that is appended to the base url. * @param document The request XML document. */ - KIO::DavJob* createPatchJob( const QString &path, const QDomDocument &document ) const; + KIO::DavJob *createPatchJob(const QString &path, const QDomDocument &document) const; - private: +private: /** * Creates a new DAV manager. */ DavManager(); - KUrl mBaseUrl; - static DavManager* mSelf; + QUrl mBaseUrl; + static DavManager *mSelf; }; } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/davutils.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/davutils.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/davutils.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/davutils.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,50 +23,50 @@ using namespace OXA; -QDomElement DAVUtils::addDavElement( QDomDocument &document, QDomNode &parentNode, const QString &tag ) +QDomElement DAVUtils::addDavElement(QDomDocument &document, QDomNode &parentNode, const QString &tag) { - const QDomElement element = document.createElementNS( QLatin1String( "DAV:" ), QLatin1String( "D:" ) + tag ); - parentNode.appendChild( element ); + const QDomElement element = document.createElementNS(QStringLiteral("DAV:"), QStringLiteral("D:") + tag); + parentNode.appendChild(element); - return element; + return element; } -QDomElement DAVUtils::addOxElement( QDomDocument &document, QDomNode &parentNode, const QString &tag, const QString &text ) +QDomElement DAVUtils::addOxElement(QDomDocument &document, QDomNode &parentNode, const QString &tag, const QString &text) { - QDomElement element = document.createElementNS( QLatin1String( "http://www.open-xchange.org" ), QLatin1String( "ox:" ) + tag ); + QDomElement element = document.createElementNS(QStringLiteral("http://www.open-xchange.org"), QStringLiteral("ox:") + tag); - if ( !text.isEmpty() ) { - const QDomText textNode = document.createTextNode( text ); - element.appendChild( textNode ); - } + if (!text.isEmpty()) { + const QDomText textNode = document.createTextNode(text); + element.appendChild(textNode); + } - parentNode.appendChild( element ); + parentNode.appendChild(element); - return element; + return element; } -void DAVUtils::setOxAttribute( QDomElement &element, const QString &name, const QString &value ) +void DAVUtils::setOxAttribute(QDomElement &element, const QString &name, const QString &value) { - element.setAttributeNS( QLatin1String( "http://www.open-xchange.org" ), QLatin1String( "ox:" ) + name, value ); + element.setAttributeNS(QLatin1String("http://www.open-xchange.org"), QStringLiteral("ox:") + name, value); } -bool DAVUtils::davErrorOccurred( const QDomDocument &document, QString &errorText, QString &errorStatus ) +bool DAVUtils::davErrorOccurred(const QDomDocument &document, QString &errorText, QString &errorStatus) { - const QDomElement documentElement = document.documentElement(); - const QDomNodeList propStats = documentElement.elementsByTagNameNS( QLatin1String( "DAV:" ), - QLatin1String( "propstat" ) ); - - for ( int i = 0; i < propStats.count(); ++i ) { - const QDomElement propStat = propStats.at( i ).toElement(); - const QDomElement status = propStat.firstChildElement( QLatin1String( "status" ) ); - const QDomElement description = propStat.firstChildElement( QLatin1String( "responsedescription" ) ); - - if ( status.text() != QLatin1String( "200" ) ) { - errorText = description.text(); - errorStatus = status.text(); - return true; + const QDomElement documentElement = document.documentElement(); + const QDomNodeList propStats = documentElement.elementsByTagNameNS(QLatin1String("DAV:"), + QLatin1String("propstat")); + + for (int i = 0; i < propStats.count(); ++i) { + const QDomElement propStat = propStats.at(i).toElement(); + const QDomElement status = propStat.firstChildElement(QLatin1String("status")); + const QDomElement description = propStat.firstChildElement(QLatin1String("responsedescription")); + + if (status.text() != QLatin1String("200")) { + errorText = description.text(); + errorStatus = status.text(); + return true; + } } - } - return false; + return false; } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/davutils.h kdepim-runtime-15.08.0/resources/openxchange/oxa/davutils.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/davutils.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/davutils.h 2015-08-10 21:01:02.000000000 +0000 @@ -27,7 +27,8 @@ #include #include -namespace OXA { +namespace OXA +{ /** * Namespace that contains methods for creating or modifying DAV XML documents. @@ -36,32 +37,32 @@ */ namespace DAVUtils { - /** - * Adds a new element with the given @p tag inside the DAV namespace under @p parentNode - * to the @p document. - * - * @return The newly added element. - */ - QDomElement addDavElement( QDomDocument &document, QDomNode &parentNode, const QString &tag ); - - /** - * Adds a new element with the given @p tag and @p value inside the OX namespace under @p parentNode - * to the @p document. - * - * @return The newly added element. - */ - QDomElement addOxElement( QDomDocument &document, QDomNode &parentNode, const QString &tag, const QString &text = QString() ); - - /** - * Sets the attribute of @p element inside the OX namespace with the given @p name to @p value. - */ - void setOxAttribute( QDomElement &element, const QString &name, const QString &value ); - - /** - * Checks whether the response @p document contains an error message. - * If so, @c true is returned, @p errorText set to the error message and @p errorStatus set to error status. - */ - bool davErrorOccurred( const QDomDocument &document, QString &errorText, QString &errorStatus ); +/** + * Adds a new element with the given @p tag inside the DAV namespace under @p parentNode + * to the @p document. + * + * @return The newly added element. + */ +QDomElement addDavElement(QDomDocument &document, QDomNode &parentNode, const QString &tag); + +/** + * Adds a new element with the given @p tag and @p value inside the OX namespace under @p parentNode + * to the @p document. + * + * @return The newly added element. + */ +QDomElement addOxElement(QDomDocument &document, QDomNode &parentNode, const QString &tag, const QString &text = QString()); + +/** + * Sets the attribute of @p element inside the OX namespace with the given @p name to @p value. + */ +void setOxAttribute(QDomElement &element, const QString &name, const QString &value); + +/** + * Checks whether the response @p document contains an error message. + * If so, @c true is returned, @p errorText set to the error message and @p errorStatus set to error status. + */ +bool davErrorOccurred(const QDomDocument &document, QString &errorText, QString &errorStatus); } } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/folder.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/folder.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/folder.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/folder.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,176 +24,175 @@ using namespace OXA; Folder::Permissions::Permissions() - : mFolderPermission( NoPermission ), - mObjectReadPermission( NoReadPermission ), - mObjectWritePermission( NoWritePermission ), - mObjectDeletePermission( NoDeletePermission ), - mAdminFlag( false ) + : mFolderPermission(NoPermission), + mObjectReadPermission(NoReadPermission), + mObjectWritePermission(NoWritePermission), + mObjectDeletePermission(NoDeletePermission), + mAdminFlag(false) { } -void Folder::Permissions::setFolderPermission( FolderPermission permission ) +void Folder::Permissions::setFolderPermission(FolderPermission permission) { - mFolderPermission = permission; + mFolderPermission = permission; } Folder::Permissions::FolderPermission Folder::Permissions::folderPermission() const { - return mFolderPermission; + return mFolderPermission; } -void Folder::Permissions::setObjectReadPermission( ObjectReadPermission permission ) +void Folder::Permissions::setObjectReadPermission(ObjectReadPermission permission) { - mObjectReadPermission = permission; + mObjectReadPermission = permission; } Folder::Permissions::ObjectReadPermission Folder::Permissions::objectReadPermission() const { - return mObjectReadPermission; + return mObjectReadPermission; } -void Folder::Permissions::setObjectWritePermission( ObjectWritePermission permission ) +void Folder::Permissions::setObjectWritePermission(ObjectWritePermission permission) { - mObjectWritePermission = permission; + mObjectWritePermission = permission; } Folder::Permissions::ObjectWritePermission Folder::Permissions::objectWritePermission() const { - return mObjectWritePermission; + return mObjectWritePermission; } -void Folder::Permissions::setObjectDeletePermission( ObjectDeletePermission permission ) +void Folder::Permissions::setObjectDeletePermission(ObjectDeletePermission permission) { - mObjectDeletePermission = permission; + mObjectDeletePermission = permission; } Folder::Permissions::ObjectDeletePermission Folder::Permissions::objectDeletePermission() const { - return mObjectDeletePermission; + return mObjectDeletePermission; } -void Folder::Permissions::setAdminFlag( bool value ) +void Folder::Permissions::setAdminFlag(bool value) { - mAdminFlag = value; + mAdminFlag = value; } bool Folder::Permissions::adminFlag() const { - return mAdminFlag; + return mAdminFlag; } - Folder::Folder() - : mObjectId( -1 ), mFolderId( -1 ) + : mObjectId(-1), mFolderId(-1) { } -void Folder::setObjectStatus( ObjectStatus status ) +void Folder::setObjectStatus(ObjectStatus status) { - mObjectStatus = status; + mObjectStatus = status; } Folder::ObjectStatus Folder::objectStatus() const { - return mObjectStatus; + return mObjectStatus; } -void Folder::setTitle( const QString &title ) +void Folder::setTitle(const QString &title) { - mTitle = title; + mTitle = title; } QString Folder::title() const { - return mTitle; + return mTitle; } -void Folder::setType( Type type ) +void Folder::setType(Type type) { - mType = type; + mType = type; } Folder::Type Folder::type() const { - return mType; + return mType; } -void Folder::setModule( Module module ) +void Folder::setModule(Module module) { - mModule = module; + mModule = module; } Folder::Module Folder::module() const { - return mModule; + return mModule; } -void Folder::setObjectId( qlonglong id ) +void Folder::setObjectId(qlonglong id) { - mObjectId = id; + mObjectId = id; } qlonglong Folder::objectId() const { - return mObjectId; + return mObjectId; } -void Folder::setFolderId( qlonglong id ) +void Folder::setFolderId(qlonglong id) { - mFolderId = id; + mFolderId = id; } qlonglong Folder::folderId() const { - return mFolderId; + return mFolderId; } -void Folder::setIsDefaultFolder( bool value ) +void Folder::setIsDefaultFolder(bool value) { - mIsDefaultFolder = value; + mIsDefaultFolder = value; } bool Folder::isDefaultFolder() const { - return mIsDefaultFolder; + return mIsDefaultFolder; } -void Folder::setOwner( qlonglong id ) +void Folder::setOwner(qlonglong id) { - mOwner = id; + mOwner = id; } qlonglong Folder::owner() const { - return mOwner; + return mOwner; } -void Folder::setLastModified( const QString &timeStamp ) +void Folder::setLastModified(const QString &timeStamp) { - mLastModified = timeStamp; + mLastModified = timeStamp; } QString Folder::lastModified() const { - return mLastModified; + return mLastModified; } -void Folder::setUserPermissions( const UserPermissions &permissions ) +void Folder::setUserPermissions(const UserPermissions &permissions) { - mUserPermissions = permissions; + mUserPermissions = permissions; } Folder::UserPermissions Folder::userPermissions() const { - return mUserPermissions; + return mUserPermissions; } -void Folder::setGroupPermissions( const GroupPermissions &permissions ) +void Folder::setGroupPermissions(const GroupPermissions &permissions) { - mGroupPermissions = permissions; + mGroupPermissions = permissions; } Folder::GroupPermissions Folder::groupPermissions() const { - return mGroupPermissions; + return mGroupPermissions; } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/foldercreatejob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/foldercreatejob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/foldercreatejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/foldercreatejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -30,67 +30,68 @@ using namespace OXA; -FolderCreateJob::FolderCreateJob( const Folder &folder, QObject *parent ) - : KJob( parent ), mFolder( folder ) +FolderCreateJob::FolderCreateJob(const Folder &folder, QObject *parent) + : KJob(parent), mFolder(folder) { } void FolderCreateJob::start() { - QDomDocument document; - QDomElement propertyupdate = DAVUtils::addDavElement( document, document, QLatin1String( "propertyupdate" ) ); - QDomElement set = DAVUtils::addDavElement( document, propertyupdate, QLatin1String( "set" ) ); - QDomElement prop = DAVUtils::addDavElement( document, set, QLatin1String( "prop" ) ); + QDomDocument document; + QDomElement propertyupdate = DAVUtils::addDavElement(document, document, QStringLiteral("propertyupdate")); + QDomElement set = DAVUtils::addDavElement(document, propertyupdate, QStringLiteral("set")); + QDomElement prop = DAVUtils::addDavElement(document, set, QStringLiteral("prop")); - FolderUtils::addFolderElements( document, prop, mFolder ); + FolderUtils::addFolderElements(document, prop, mFolder); - const QString path = QLatin1String( "/servlet/webdav.folders" ); + const QString path = QLatin1String("/servlet/webdav.folders"); - KIO::DavJob *job = DavManager::self()->createPatchJob( path, document ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + KIO::DavJob *job = DavManager::self()->createPatchJob(path, document); + connect(job, &KIO::DavJob::result, this, &FolderCreateJob::davJobFinished); } Folder FolderCreateJob::folder() const { - return mFolder; + return mFolder; } -void FolderCreateJob::davJobFinished( KJob *job ) +void FolderCreateJob::davJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } - - KIO::DavJob *davJob = qobject_cast( job ); + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } + + KIO::DavJob *davJob = qobject_cast(job); + + const QDomDocument document = davJob->response(); + + QString errorText, errorStatus; + if (DAVUtils::davErrorOccurred(document, errorText, errorStatus)) { + setError(UserDefinedError); + setErrorText(errorText); + emitResult(); + return; + } + + QDomElement multistatus = document.documentElement(); + QDomElement response = multistatus.firstChildElement(QStringLiteral("response")); + const QDomNodeList props = response.elementsByTagName("prop"); + const QDomElement prop = props.at(0).toElement(); + + QDomElement element = prop.firstChildElement(); + while (!element.isNull()) { + if (element.tagName() == QLatin1String("object_id")) { + mFolder.setObjectId(OXUtils::readNumber(element.text())); + } else if (element.tagName() == QLatin1String("last_modified")) { + mFolder.setLastModified(OXUtils::readString(element.text())); + } - const QDomDocument document = davJob->response(); + element = element.nextSiblingElement(); + } - QString errorText, errorStatus; - if ( DAVUtils::davErrorOccurred( document, errorText, errorStatus ) ) { - setError( UserDefinedError ); - setErrorText( errorText ); emitResult(); - return; - } - - QDomElement multistatus = document.documentElement(); - QDomElement response = multistatus.firstChildElement( QLatin1String( "response" ) ); - const QDomNodeList props = response.elementsByTagName( "prop" ); - const QDomElement prop = props.at( 0 ).toElement(); - - QDomElement element = prop.firstChildElement(); - while ( !element.isNull() ) { - if ( element.tagName() == QLatin1String( "object_id" ) ) - mFolder.setObjectId( OXUtils::readNumber( element.text() ) ); - else if ( element.tagName() == QLatin1String( "last_modified" ) ) - mFolder.setLastModified( OXUtils::readString( element.text() ) ); - - element = element.nextSiblingElement(); - } - - emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/foldercreatejob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/foldercreatejob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/foldercreatejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/foldercreatejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,7 +26,8 @@ #include "folder.h" -namespace OXA { +namespace OXA +{ /** * @short A job that creates a new folder on the OX server. @@ -35,31 +36,31 @@ */ class FolderCreateJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new folder create job. * * @param folder The folder to create. * @param parent The parent object. */ - explicit FolderCreateJob( const Folder &folder, QObject *parent = 0 ); + explicit FolderCreateJob(const Folder &folder, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Returns the updated folder that has been created. */ Folder folder() const; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: Folder mFolder; }; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/folderdeletejob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/folderdeletejob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/folderdeletejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/folderdeletejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -31,48 +31,48 @@ using namespace OXA; -FolderDeleteJob::FolderDeleteJob( const Folder &folder, QObject *parent ) - : KJob( parent ), mFolder( folder ) +FolderDeleteJob::FolderDeleteJob(const Folder &folder, QObject *parent) + : KJob(parent), mFolder(folder) { } void FolderDeleteJob::start() { - QDomDocument document; - QDomElement propertyupdate = DAVUtils::addDavElement( document, document, QLatin1String( "propertyupdate" ) ); - QDomElement set = DAVUtils::addDavElement( document, propertyupdate, QLatin1String( "set" ) ); - QDomElement prop = DAVUtils::addDavElement( document, set, QLatin1String( "prop" ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "object_id" ), OXUtils::writeNumber( mFolder.objectId() ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "method" ), OXUtils::writeString( QLatin1String( "DELETE" ) ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "last_modified" ), OXUtils::writeString( mFolder.lastModified() ) ); + QDomDocument document; + QDomElement propertyupdate = DAVUtils::addDavElement(document, document, QStringLiteral("propertyupdate")); + QDomElement set = DAVUtils::addDavElement(document, propertyupdate, QStringLiteral("set")); + QDomElement prop = DAVUtils::addDavElement(document, set, QStringLiteral("prop")); + DAVUtils::addOxElement(document, prop, QStringLiteral("object_id"), OXUtils::writeNumber(mFolder.objectId())); + DAVUtils::addOxElement(document, prop, QStringLiteral("method"), OXUtils::writeString(QLatin1String("DELETE"))); + DAVUtils::addOxElement(document, prop, QStringLiteral("last_modified"), OXUtils::writeString(mFolder.lastModified())); - const QString path = QLatin1String( "/servlet/webdav.folders" ); + const QString path = QLatin1String("/servlet/webdav.folders"); - KIO::DavJob *job = DavManager::self()->createPatchJob( path, document ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + KIO::DavJob *job = DavManager::self()->createPatchJob(path, document); + connect(job, &KIO::DavJob::result, this, &FolderDeleteJob::davJobFinished); } -void FolderDeleteJob::davJobFinished( KJob *job ) +void FolderDeleteJob::davJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } - - KIO::DavJob *davJob = qobject_cast( job ); + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } + + KIO::DavJob *davJob = qobject_cast(job); + + const QDomDocument document = davJob->response(); + + QString errorText, errorStatus; + if (DAVUtils::davErrorOccurred(document, errorText, errorStatus)) { + setError(UserDefinedError); + setErrorText(errorText); + emitResult(); + return; + } - const QDomDocument document = davJob->response(); - - QString errorText, errorStatus; - if ( DAVUtils::davErrorOccurred( document, errorText, errorStatus ) ) { - setError( UserDefinedError ); - setErrorText( errorText ); emitResult(); - return; - } - - emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/folderdeletejob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/folderdeletejob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/folderdeletejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/folderdeletejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,7 +26,8 @@ #include -namespace OXA { +namespace OXA +{ /** * @short A job that deletes a folder on the OX server. @@ -35,9 +36,9 @@ */ class FolderDeleteJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new folder delete job. * @@ -46,17 +47,17 @@ * * @note The folder needs the objectId, folderId and lastModified property set. */ - explicit FolderDeleteJob( const Folder &folder, QObject *parent = 0 ); + explicit FolderDeleteJob(const Folder &folder, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: Folder mFolder; }; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/folder.h kdepim-runtime-15.08.0/resources/openxchange/oxa/folder.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/folder.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/folder.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,11 +22,12 @@ #ifndef OXA_FOLDER_H #define OXA_FOLDER_H -#include +#include #include #include -namespace OXA { +namespace OXA +{ /** * @short A class that contains information about folders on the OX server. @@ -35,39 +36,36 @@ */ class Folder { - public: +public: /** * Describes a list of folders. */ - typedef QList List; + typedef QVector List; /** * Describes the status of the folder. */ - enum ObjectStatus - { - Created, ///< The folder has been created or modified. - Deleted ///< The folder has been deleted. + enum ObjectStatus { + Created, ///< The folder has been created or modified. + Deleted ///< The folder has been deleted. }; /** * Describes the visibility type of the folder. */ - enum Type - { - Public, ///< The folder is visible for all users. - Private ///< The folder is only visible for the owner. + enum Type { + Public, ///< The folder is visible for all users. + Private ///< The folder is only visible for the owner. }; /** * Describes the module the folder belongs to. */ - enum Module - { - Unbound, ///< The folder is only a structural folder. - Calendar, ///< The folder contains events. - Contacts, ///< The folder contains contacts. - Tasks ///< The folder contains tasks. + enum Module { + Unbound, ///< The folder is only a structural folder. + Calendar, ///< The folder contains events. + Contacts, ///< The folder contains contacts. + Tasks ///< The folder contains tasks. }; /** @@ -76,70 +74,66 @@ */ class Permissions { - public: + public: /** * Describes the permissions on folder objects. */ - enum FolderPermission - { - NoPermission = 0, ///< No permissions. - FolderIsVisible = 2, ///< The folder can be read. - CreateObjects = 4, ///< Objects can be created in the folder. - CreateSubfolders = 8, ///< Subfolders can be created in the folder. - AdminPermission = 128 ///< Permissions can be changed. + enum FolderPermission { + NoPermission = 0, ///< No permissions. + FolderIsVisible = 2, ///< The folder can be read. + CreateObjects = 4, ///< Objects can be created in the folder. + CreateSubfolders = 8, ///< Subfolders can be created in the folder. + AdminPermission = 128 ///< Permissions can be changed. }; /** * Describes the read permissions on other objects. */ - enum ObjectReadPermission - { - NoReadPermission = 0, ///< The objects can not be read. - ReadOwnObjects = 2, ///< Only own objects can be read. - ReadAllObjects = 4, ///< All objects can be read. - AdminReadPermission = 128 + enum ObjectReadPermission { + NoReadPermission = 0, ///< The objects can not be read. + ReadOwnObjects = 2, ///< Only own objects can be read. + ReadAllObjects = 4, ///< All objects can be read. + AdminReadPermission = 128 }; /** * Describes the write permissions on other objects. */ - enum ObjectWritePermission - { - NoWritePermission = 0, ///< The objects can not be written. - WriteOwnObjects = 2, ///< Only own objects can be written. - WriteAllObjects = 4, ///< All objects can be written. - AdminWritePermission = 128 + enum ObjectWritePermission { + NoWritePermission = 0, ///< The objects can not be written. + WriteOwnObjects = 2, ///< Only own objects can be written. + WriteAllObjects = 4, ///< All objects can be written. + AdminWritePermission = 128 }; /** * Describes the delete permissions on other objects. */ - enum ObjectDeletePermission - { - NoDeletePermission = 0, ///< The objects can not be deleted. - DeleteOwnObjects = 2, ///< Only own objects can be deleted. - DeleteAllObjects = 4, ///< All objects can be deleted. - AdminDeletePermission = 128 + enum ObjectDeletePermission { + NoDeletePermission = 0, ///< The objects can not be deleted. + DeleteOwnObjects = 2, ///< Only own objects can be deleted. + DeleteAllObjects = 4, ///< All objects can be deleted. + AdminDeletePermission = 128 }; Permissions(); - void setFolderPermission( FolderPermission permission ); + void setFolderPermission(FolderPermission permission); FolderPermission folderPermission() const; - void setObjectReadPermission( ObjectReadPermission permission ); + void setObjectReadPermission(ObjectReadPermission permission); ObjectReadPermission objectReadPermission() const; - void setObjectWritePermission( ObjectWritePermission permission ); + void setObjectWritePermission(ObjectWritePermission permission); ObjectWritePermission objectWritePermission() const; - void setObjectDeletePermission( ObjectDeletePermission permission ); + void setObjectDeletePermission(ObjectDeletePermission permission); ObjectDeletePermission objectDeletePermission() const; - void setAdminFlag( bool value ); + void setAdminFlag(bool value); bool adminFlag() const; - private: + private: FolderPermission mFolderPermission; ObjectReadPermission mObjectReadPermission; ObjectWritePermission mObjectWritePermission; @@ -152,40 +146,40 @@ Folder(); - void setObjectStatus( ObjectStatus status ); + void setObjectStatus(ObjectStatus status); ObjectStatus objectStatus() const; - void setTitle( const QString &title ); + void setTitle(const QString &title); QString title() const; - void setType( Type type ); + void setType(Type type); Type type() const; - void setModule( Module module ); + void setModule(Module module); Module module() const; - void setObjectId( qlonglong id ); + void setObjectId(qlonglong id); qlonglong objectId() const; - void setFolderId( qlonglong id ); + void setFolderId(qlonglong id); qlonglong folderId() const; - void setIsDefaultFolder( bool value ); + void setIsDefaultFolder(bool value); bool isDefaultFolder() const; - void setOwner( qlonglong id ); + void setOwner(qlonglong id); qlonglong owner() const; - void setLastModified( const QString &timeStamp ); + void setLastModified(const QString &timeStamp); QString lastModified() const; - void setUserPermissions( const UserPermissions &permissions ); + void setUserPermissions(const UserPermissions &permissions); UserPermissions userPermissions() const; - void setGroupPermissions( const GroupPermissions &permissions ); + void setGroupPermissions(const GroupPermissions &permissions); GroupPermissions groupPermissions() const; - private: +private: ObjectStatus mObjectStatus; QString mTitle; Type mType; @@ -200,5 +194,6 @@ }; } +Q_DECLARE_TYPEINFO( OXA::Folder, Q_MOVABLE_TYPE ); #endif diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/foldermodifyjob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/foldermodifyjob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/foldermodifyjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/foldermodifyjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -29,67 +29,68 @@ using namespace OXA; -FolderModifyJob::FolderModifyJob( const Folder &folder, QObject *parent ) - : KJob( parent ), mFolder( folder ) +FolderModifyJob::FolderModifyJob(const Folder &folder, QObject *parent) + : KJob(parent), mFolder(folder) { } void FolderModifyJob::start() { - QDomDocument document; - QDomElement propertyupdate = DAVUtils::addDavElement( document, document, QLatin1String( "propertyupdate" ) ); - QDomElement set = DAVUtils::addDavElement( document, propertyupdate, QLatin1String( "set" ) ); - QDomElement prop = DAVUtils::addDavElement( document, set, QLatin1String( "prop" ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "title" ), OXUtils::writeString( mFolder.title() ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "object_id" ), OXUtils::writeNumber( mFolder.objectId() ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "folder_id" ), OXUtils::writeNumber( mFolder.folderId() ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "last_modified" ), OXUtils::writeString( mFolder.lastModified() ) ); + QDomDocument document; + QDomElement propertyupdate = DAVUtils::addDavElement(document, document, QStringLiteral("propertyupdate")); + QDomElement set = DAVUtils::addDavElement(document, propertyupdate, QStringLiteral("set")); + QDomElement prop = DAVUtils::addDavElement(document, set, QStringLiteral("prop")); + DAVUtils::addOxElement(document, prop, QStringLiteral("title"), OXUtils::writeString(mFolder.title())); + DAVUtils::addOxElement(document, prop, QStringLiteral("object_id"), OXUtils::writeNumber(mFolder.objectId())); + DAVUtils::addOxElement(document, prop, QStringLiteral("folder_id"), OXUtils::writeNumber(mFolder.folderId())); + DAVUtils::addOxElement(document, prop, QStringLiteral("last_modified"), OXUtils::writeString(mFolder.lastModified())); - const QString path = QLatin1String( "/servlet/webdav.folders" ); + const QString path = QLatin1String("/servlet/webdav.folders"); - KIO::DavJob *job = DavManager::self()->createPatchJob( path, document ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + KIO::DavJob *job = DavManager::self()->createPatchJob(path, document); + connect(job, &KIO::DavJob::result, this, &FolderModifyJob::davJobFinished); } Folder FolderModifyJob::folder() const { - return mFolder; + return mFolder; } -void FolderModifyJob::davJobFinished( KJob *job ) +void FolderModifyJob::davJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } - - KIO::DavJob *davJob = qobject_cast( job ); + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } + + KIO::DavJob *davJob = qobject_cast(job); + + const QDomDocument document = davJob->response(); + + QString errorText, errorStatus; + if (DAVUtils::davErrorOccurred(document, errorText, errorStatus)) { + setError(UserDefinedError); + setErrorText(errorText); + emitResult(); + return; + } + + QDomElement multistatus = document.documentElement(); + QDomElement response = multistatus.firstChildElement(QLatin1String("response")); + const QDomNodeList props = response.elementsByTagName("prop"); + const QDomElement prop = props.at(0).toElement(); + + QDomElement element = prop.firstChildElement(); + while (!element.isNull()) { + if (element.tagName() == QLatin1String("last_modified")) { + mFolder.setLastModified(OXUtils::readString(element.text())); + } - const QDomDocument document = davJob->response(); + element = element.nextSiblingElement(); + } - QString errorText, errorStatus; - if ( DAVUtils::davErrorOccurred( document, errorText, errorStatus ) ) { - setError( UserDefinedError ); - setErrorText( errorText ); emitResult(); - return; - } - - QDomElement multistatus = document.documentElement(); - QDomElement response = multistatus.firstChildElement( QLatin1String( "response" ) ); - const QDomNodeList props = response.elementsByTagName( "prop" ); - const QDomElement prop = props.at( 0 ).toElement(); - - QDomElement element = prop.firstChildElement(); - while ( !element.isNull() ) { - if ( element.tagName() == QLatin1String( "last_modified" ) ) - mFolder.setLastModified( OXUtils::readString( element.text() ) ); - - element = element.nextSiblingElement(); - } - - emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/foldermodifyjob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/foldermodifyjob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/foldermodifyjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/foldermodifyjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,7 +26,8 @@ #include "folder.h" -namespace OXA { +namespace OXA +{ /** * @short A job that modifies a folder on the OX server. @@ -35,9 +36,9 @@ */ class FolderModifyJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new folder modify job. * @@ -46,22 +47,22 @@ * * @note The folder needs at least the objectId and lastModified property set. */ - explicit FolderModifyJob( const Folder &folder, QObject *parent = 0 ); + explicit FolderModifyJob(const Folder &folder, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Returns the updated folder that has been modified. */ Folder folder() const; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: Folder mFolder; }; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/foldermovejob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/foldermovejob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/foldermovejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/foldermovejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -29,67 +29,68 @@ using namespace OXA; -FolderMoveJob::FolderMoveJob( const Folder &folder, const Folder &destinationFolder, QObject *parent ) - : KJob( parent ), mFolder( folder ), mDestinationFolder( destinationFolder ) +FolderMoveJob::FolderMoveJob(const Folder &folder, const Folder &destinationFolder, QObject *parent) + : KJob(parent), mFolder(folder), mDestinationFolder(destinationFolder) { } void FolderMoveJob::start() { - QDomDocument document; - QDomElement propertyupdate = DAVUtils::addDavElement( document, document, QLatin1String( "propertyupdate" ) ); - QDomElement set = DAVUtils::addDavElement( document, propertyupdate, QLatin1String( "set" ) ); - QDomElement prop = DAVUtils::addDavElement( document, set, QLatin1String( "prop" ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "object_id" ), OXUtils::writeNumber( mFolder.objectId() ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "folder_id" ), OXUtils::writeNumber( mFolder.folderId() ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "last_modified" ), OXUtils::writeString( mFolder.lastModified() ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "folder" ), OXUtils::writeNumber( mDestinationFolder.objectId() ) ); + QDomDocument document; + QDomElement propertyupdate = DAVUtils::addDavElement(document, document, QStringLiteral("propertyupdate")); + QDomElement set = DAVUtils::addDavElement(document, propertyupdate, QStringLiteral("set")); + QDomElement prop = DAVUtils::addDavElement(document, set, QStringLiteral("prop")); + DAVUtils::addOxElement(document, prop, QStringLiteral("object_id"), OXUtils::writeNumber(mFolder.objectId())); + DAVUtils::addOxElement(document, prop, QStringLiteral("folder_id"), OXUtils::writeNumber(mFolder.folderId())); + DAVUtils::addOxElement(document, prop, QStringLiteral("last_modified"), OXUtils::writeString(mFolder.lastModified())); + DAVUtils::addOxElement(document, prop, QStringLiteral("folder"), OXUtils::writeNumber(mDestinationFolder.objectId())); - const QString path = QLatin1String( "/servlet/webdav.folders" ); + const QString path = QLatin1String("/servlet/webdav.folders"); - KIO::DavJob *job = DavManager::self()->createPatchJob( path, document ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + KIO::DavJob *job = DavManager::self()->createPatchJob(path, document); + connect(job, &KIO::DavJob::result, this, &FolderMoveJob::davJobFinished); } Folder FolderMoveJob::folder() const { - return mFolder; + return mFolder; } -void FolderMoveJob::davJobFinished( KJob *job ) +void FolderMoveJob::davJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } - - KIO::DavJob *davJob = qobject_cast( job ); + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } + + KIO::DavJob *davJob = qobject_cast(job); + + const QDomDocument document = davJob->response(); + + QString errorText, errorStatus; + if (DAVUtils::davErrorOccurred(document, errorText, errorStatus)) { + setError(UserDefinedError); + setErrorText(errorText); + emitResult(); + return; + } + + QDomElement multistatus = document.documentElement(); + QDomElement response = multistatus.firstChildElement(QLatin1String("response")); + const QDomNodeList props = response.elementsByTagName("prop"); + const QDomElement prop = props.at(0).toElement(); + + QDomElement element = prop.firstChildElement(); + while (!element.isNull()) { + if (element.tagName() == QLatin1String("last_modified")) { + mFolder.setLastModified(OXUtils::readString(element.text())); + } - const QDomDocument document = davJob->response(); + element = element.nextSiblingElement(); + } - QString errorText, errorStatus; - if ( DAVUtils::davErrorOccurred( document, errorText, errorStatus ) ) { - setError( UserDefinedError ); - setErrorText( errorText ); emitResult(); - return; - } - - QDomElement multistatus = document.documentElement(); - QDomElement response = multistatus.firstChildElement( QLatin1String( "response" ) ); - const QDomNodeList props = response.elementsByTagName( "prop" ); - const QDomElement prop = props.at( 0 ).toElement(); - - QDomElement element = prop.firstChildElement(); - while ( !element.isNull() ) { - if ( element.tagName() == QLatin1String( "last_modified" ) ) - mFolder.setLastModified( OXUtils::readString( element.text() ) ); - - element = element.nextSiblingElement(); - } - - emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/foldermovejob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/foldermovejob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/foldermovejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/foldermovejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,7 +26,8 @@ #include "folder.h" -namespace OXA { +namespace OXA +{ /** * @short A job that moves a folder on the OX server. @@ -35,9 +36,9 @@ */ class FolderMoveJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new folder move job. * @@ -48,22 +49,22 @@ * @note The folder needs the objectId, folderId and lastModified property set, the * destinationFolder the objectId property. */ - FolderMoveJob( const Folder &folder, const Folder &destinationFolder, QObject *parent = 0 ); + FolderMoveJob(const Folder &folder, const Folder &destinationFolder, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Returns the updated folder that has been moved. */ Folder folder() const; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: Folder mFolder; Folder mDestinationFolder; }; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/folderrequestjob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/folderrequestjob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/folderrequestjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/folderrequestjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -30,56 +30,56 @@ using namespace OXA; -FolderRequestJob::FolderRequestJob( const Folder &folder, QObject *parent ) - : KJob( parent ), mFolder( folder ) +FolderRequestJob::FolderRequestJob(const Folder &folder, QObject *parent) + : KJob(parent), mFolder(folder) { } void FolderRequestJob::start() { - QDomDocument document; - QDomElement multistatus = DAVUtils::addDavElement( document, document, QLatin1String( "multistatus" ) ); - QDomElement prop = DAVUtils::addDavElement( document, multistatus, QLatin1String( "prop" ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "object_id" ), OXUtils::writeNumber( mFolder.objectId() ) ); + QDomDocument document; + QDomElement multistatus = DAVUtils::addDavElement(document, document, QStringLiteral("multistatus")); + QDomElement prop = DAVUtils::addDavElement(document, multistatus, QStringLiteral("prop")); + DAVUtils::addOxElement(document, prop, QStringLiteral("object_id"), OXUtils::writeNumber(mFolder.objectId())); - const QString path = QLatin1String( "/servlet/webdav.folders" ); + const QString path = QLatin1String("/servlet/webdav.folders"); - KIO::DavJob *job = DavManager::self()->createFindJob( path, document ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + KIO::DavJob *job = DavManager::self()->createFindJob(path, document); + connect(job, &KIO::DavJob::result, this, &FolderRequestJob::davJobFinished); } Folder FolderRequestJob::folder() const { - return mFolder; + return mFolder; } -void FolderRequestJob::davJobFinished( KJob *job ) +void FolderRequestJob::davJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } - - KIO::DavJob *davJob = qobject_cast( job ); - - const QDomDocument document = davJob->response(); + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } + + KIO::DavJob *davJob = qobject_cast(job); + + const QDomDocument document = davJob->response(); + + QString errorText, errorStatus; + if (DAVUtils::davErrorOccurred(document, errorText, errorStatus)) { + setError(UserDefinedError); + setErrorText(errorText); + emitResult(); + return; + } + + QDomElement multistatus = document.documentElement(); + QDomElement response = multistatus.firstChildElement(QLatin1String("response")); + const QDomNodeList props = response.elementsByTagName("prop"); + const QDomElement prop = props.at(0).toElement(); + mFolder = FolderUtils::parseFolder(prop); - QString errorText, errorStatus; - if ( DAVUtils::davErrorOccurred( document, errorText, errorStatus ) ) { - setError( UserDefinedError ); - setErrorText( errorText ); emitResult(); - return; - } - - QDomElement multistatus = document.documentElement(); - QDomElement response = multistatus.firstChildElement( QLatin1String( "response" ) ); - const QDomNodeList props = response.elementsByTagName( "prop" ); - const QDomElement prop = props.at( 0 ).toElement(); - mFolder = FolderUtils::parseFolder( prop ); - - emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/folderrequestjob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/folderrequestjob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/folderrequestjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/folderrequestjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,7 +26,8 @@ #include "folder.h" -namespace OXA { +namespace OXA +{ /** * @short A job that requests a folder from the OX server. @@ -35,9 +36,9 @@ */ class FolderRequestJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new folder request job. * @@ -46,22 +47,22 @@ * * @note The folder needs the objectId property set. */ - explicit FolderRequestJob( const Folder &folder, QObject *parent = 0 ); + explicit FolderRequestJob(const Folder &folder, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Returns the requested folder. */ Folder folder() const; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: Folder mFolder; }; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/foldersrequestdeltajob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/foldersrequestdeltajob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/foldersrequestdeltajob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/foldersrequestdeltajob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -27,67 +27,69 @@ using namespace OXA; -FoldersRequestDeltaJob::FoldersRequestDeltaJob( qulonglong lastSync, QObject *parent ) - : KJob( parent ), mLastSync( lastSync ), mJobFinishedCount( 0 ) +FoldersRequestDeltaJob::FoldersRequestDeltaJob(qulonglong lastSync, QObject *parent) + : KJob(parent), mLastSync(lastSync), mJobFinishedCount(0) { } void FoldersRequestDeltaJob::start() { - FoldersRequestJob *modifiedJob = new FoldersRequestJob( mLastSync, FoldersRequestJob::Modified, this ); - connect( modifiedJob, SIGNAL(result(KJob*)), SLOT(fetchModifiedJobFinished(KJob*)) ); - modifiedJob->start(); - - FoldersRequestJob *deletedJob = new FoldersRequestJob( mLastSync, FoldersRequestJob::Deleted, this ); - connect( deletedJob, SIGNAL(result(KJob*)), SLOT(fetchDeletedJobFinished(KJob*)) ); - deletedJob->start(); + FoldersRequestJob *modifiedJob = new FoldersRequestJob(mLastSync, FoldersRequestJob::Modified, this); + connect(modifiedJob, &FoldersRequestJob::result, this, &FoldersRequestDeltaJob::fetchModifiedJobFinished); + modifiedJob->start(); + + FoldersRequestJob *deletedJob = new FoldersRequestJob(mLastSync, FoldersRequestJob::Deleted, this); + connect(deletedJob, &FoldersRequestJob::result, this, &FoldersRequestDeltaJob::fetchDeletedJobFinished); + deletedJob->start(); } Folder::List FoldersRequestDeltaJob::modifiedFolders() const { - return mModifiedFolders; + return mModifiedFolders; } Folder::List FoldersRequestDeltaJob::deletedFolders() const { - return mDeletedFolders; + return mDeletedFolders; } -void FoldersRequestDeltaJob::fetchModifiedJobFinished( KJob *job ) +void FoldersRequestDeltaJob::fetchModifiedJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } - const FoldersRequestJob *requestJob = qobject_cast( job ); + const FoldersRequestJob *requestJob = qobject_cast(job); - mModifiedFolders << requestJob->folders(); + mModifiedFolders << requestJob->folders(); - mJobFinishedCount++; + mJobFinishedCount++; - if ( mJobFinishedCount == 2 ) - emitResult(); + if (mJobFinishedCount == 2) { + emitResult(); + } } -void FoldersRequestDeltaJob::fetchDeletedJobFinished( KJob *job ) +void FoldersRequestDeltaJob::fetchDeletedJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } - const FoldersRequestJob *requestJob = qobject_cast( job ); + const FoldersRequestJob *requestJob = qobject_cast(job); - mDeletedFolders << requestJob->folders(); + mDeletedFolders << requestJob->folders(); - mJobFinishedCount++; + mJobFinishedCount++; - if ( mJobFinishedCount == 2 ) - emitResult(); + if (mJobFinishedCount == 2) { + emitResult(); + } } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/foldersrequestdeltajob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/foldersrequestdeltajob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/foldersrequestdeltajob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/foldersrequestdeltajob.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,7 +26,8 @@ #include "folder.h" -namespace OXA { +namespace OXA +{ /** * @short A job that requests the delta for folders changes from the OX server. @@ -35,9 +36,9 @@ */ class FoldersRequestDeltaJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new folders request delta job. * @@ -45,12 +46,12 @@ * after this date will be requested. 0 will request all available folders. * @param parent The parent object. */ - explicit FoldersRequestDeltaJob( qulonglong lastSync, QObject *parent = 0 ); + explicit FoldersRequestDeltaJob(qulonglong lastSync, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Returns the list of all added and modified folders. @@ -62,11 +63,11 @@ */ Folder::List deletedFolders() const; - private Q_SLOTS: - void fetchModifiedJobFinished( KJob* ); - void fetchDeletedJobFinished( KJob* ); +private Q_SLOTS: + void fetchModifiedJobFinished(KJob *); + void fetchDeletedJobFinished(KJob *); - private: +private: qulonglong mLastSync; Folder::List mModifiedFolders; Folder::List mDeletedFolders; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/foldersrequestjob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/foldersrequestjob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/foldersrequestjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/foldersrequestjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -32,63 +32,64 @@ using namespace OXA; -FoldersRequestJob::FoldersRequestJob( qulonglong lastSync, Mode mode, QObject *parent ) - : KJob( parent ), mLastSync( lastSync ), mMode( mode ) +FoldersRequestJob::FoldersRequestJob(qulonglong lastSync, Mode mode, QObject *parent) + : KJob(parent), mLastSync(lastSync), mMode(mode) { } void FoldersRequestJob::start() { - QDomDocument document; - QDomElement multistatus = DAVUtils::addDavElement( document, document, QLatin1String( "multistatus" ) ); - QDomElement prop = DAVUtils::addDavElement( document, multistatus, QLatin1String( "prop" ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "lastsync" ), OXUtils::writeNumber( mLastSync ) ); - if ( mMode == Modified ) - DAVUtils::addOxElement( document, prop, QLatin1String( "objectmode" ), QLatin1String( "MODIFIED" ) ); - else - DAVUtils::addOxElement( document, prop, QLatin1String( "objectmode" ), QLatin1String( "DELETED" ) ); + QDomDocument document; + QDomElement multistatus = DAVUtils::addDavElement(document, document, QStringLiteral("multistatus")); + QDomElement prop = DAVUtils::addDavElement(document, multistatus, QStringLiteral("prop")); + DAVUtils::addOxElement(document, prop, QStringLiteral("lastsync"), OXUtils::writeNumber(mLastSync)); + if (mMode == Modified) { + DAVUtils::addOxElement(document, prop, QStringLiteral("objectmode"), QStringLiteral("MODIFIED")); + } else { + DAVUtils::addOxElement(document, prop, QStringLiteral("objectmode"), QStringLiteral("DELETED")); + } - const QString path = QLatin1String( "/servlet/webdav.folders" ); + const QString path = QLatin1String("/servlet/webdav.folders"); - KIO::DavJob *job = DavManager::self()->createFindJob( path, document ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + KIO::DavJob *job = DavManager::self()->createFindJob(path, document); + connect(job, &KIO::DavJob::result, this, &FoldersRequestJob::davJobFinished); } Folder::List FoldersRequestJob::folders() const { - return mFolders; + return mFolders; } -void FoldersRequestJob::davJobFinished( KJob *job ) +void FoldersRequestJob::davJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } - - KIO::DavJob *davJob = qobject_cast( job ); - - const QDomDocument document = davJob->response(); + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } + + KIO::DavJob *davJob = qobject_cast(job); + + const QDomDocument document = davJob->response(); + + QString errorText, errorStatus; + if (DAVUtils::davErrorOccurred(document, errorText, errorStatus)) { + setError(UserDefinedError); + setErrorText(errorText); + emitResult(); + return; + } + + QDomElement multistatus = document.documentElement(); + QDomElement response = multistatus.firstChildElement(QLatin1String("response")); + while (!response.isNull()) { + const QDomNodeList props = response.elementsByTagName("prop"); + const QDomElement prop = props.at(0).toElement(); + mFolders.append(FolderUtils::parseFolder(prop)); + response = response.nextSiblingElement(); + } - QString errorText, errorStatus; - if ( DAVUtils::davErrorOccurred( document, errorText, errorStatus ) ) { - setError( UserDefinedError ); - setErrorText( errorText ); emitResult(); - return; - } - - QDomElement multistatus = document.documentElement(); - QDomElement response = multistatus.firstChildElement( QLatin1String( "response" ) ); - while ( !response.isNull() ) { - const QDomNodeList props = response.elementsByTagName( "prop" ); - const QDomElement prop = props.at( 0 ).toElement(); - mFolders.append( FolderUtils::parseFolder( prop ) ); - response = response.nextSiblingElement(); - } - - emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/foldersrequestjob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/foldersrequestjob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/foldersrequestjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/foldersrequestjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,7 +26,8 @@ #include "folder.h" -namespace OXA { +namespace OXA +{ /** * @short A job that requests all folders from the OX server. @@ -35,16 +36,15 @@ */ class FoldersRequestJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Describes the mode of the request job. */ - enum Mode - { - Modified, ///< Fetches all new and modified folders - Deleted ///< Fetches all deleted folders + enum Mode { + Modified, ///< Fetches all new and modified folders + Deleted ///< Fetches all deleted folders }; /** @@ -55,22 +55,22 @@ * @param mode The mode of folders to request. * @param parent The parent object. */ - explicit FoldersRequestJob( qulonglong lastSync = 0, Mode mode = Modified, QObject *parent = 0 ); + explicit FoldersRequestJob(qulonglong lastSync = 0, Mode mode = Modified, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Returns the list of all requested folders. */ Folder::List folders() const; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: qulonglong mLastSync; Mode mMode; Folder::List mFolders; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/folderutils.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/folderutils.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/folderutils.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/folderutils.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -29,157 +29,160 @@ using namespace OXA; -static void createFolderPermissions( const Folder &folder, QDomDocument &document, QDomElement &permissions ) +static void createFolderPermissions(const Folder &folder, QDomDocument &document, QDomElement &permissions) { - { - const Folder::UserPermissions userPermissions = folder.userPermissions(); - Folder::UserPermissions::ConstIterator it = userPermissions.constBegin(); - while ( it != userPermissions.constEnd() ) { - QDomElement user = DAVUtils::addOxElement( document, permissions, QLatin1String( "user" ), - OXUtils::writeNumber( it.key() ) ); - DAVUtils::setOxAttribute( user, QLatin1String( "folderpermission" ), - OXUtils::writeNumber( it.value().folderPermission() ) ); - DAVUtils::setOxAttribute( user, QLatin1String( "objectreadpermission" ), - OXUtils::writeNumber( it.value().objectReadPermission() ) ); - DAVUtils::setOxAttribute( user, QLatin1String( "objectwritepermission" ), - OXUtils::writeNumber( it.value().objectWritePermission() ) ); - DAVUtils::setOxAttribute( user, QLatin1String( "objectdeletepermission" ), - OXUtils::writeNumber( it.value().objectDeletePermission() ) ); - DAVUtils::setOxAttribute( user, QLatin1String( "admin_flag" ), - OXUtils::writeBoolean( it.value().adminFlag() ) ); + { + const Folder::UserPermissions userPermissions = folder.userPermissions(); + Folder::UserPermissions::ConstIterator it = userPermissions.constBegin(); + while (it != userPermissions.constEnd()) { + QDomElement user = DAVUtils::addOxElement(document, permissions, QStringLiteral("user"), + OXUtils::writeNumber(it.key())); + DAVUtils::setOxAttribute(user, QStringLiteral("folderpermission"), + OXUtils::writeNumber(it.value().folderPermission())); + DAVUtils::setOxAttribute(user, QStringLiteral("objectreadpermission"), + OXUtils::writeNumber(it.value().objectReadPermission())); + DAVUtils::setOxAttribute(user, QStringLiteral("objectwritepermission"), + OXUtils::writeNumber(it.value().objectWritePermission())); + DAVUtils::setOxAttribute(user, QStringLiteral("objectdeletepermission"), + OXUtils::writeNumber(it.value().objectDeletePermission())); + DAVUtils::setOxAttribute(user, QStringLiteral("admin_flag"), + OXUtils::writeBoolean(it.value().adminFlag())); - ++it; + ++it; + } } - } - { - const Folder::GroupPermissions groupPermissions = folder.groupPermissions(); - Folder::GroupPermissions::ConstIterator it = groupPermissions.constBegin(); - while ( it != groupPermissions.constEnd() ) { - QDomElement group = DAVUtils::addOxElement( document, permissions, QLatin1String( "group" ), - OXUtils::writeNumber( it.key() ) ); - DAVUtils::setOxAttribute( group, QLatin1String( "folderpermission" ), - OXUtils::writeNumber( it.value().folderPermission() ) ); - DAVUtils::setOxAttribute( group, QLatin1String( "objectreadpermission" ), - OXUtils::writeNumber( it.value().objectReadPermission() ) ); - DAVUtils::setOxAttribute( group, QLatin1String( "objectwritepermission" ), - OXUtils::writeNumber( it.value().objectWritePermission() ) ); - DAVUtils::setOxAttribute( group, QLatin1String( "objectdeletepermission" ), - OXUtils::writeNumber( it.value().objectDeletePermission() ) ); - DAVUtils::setOxAttribute( group, QLatin1String( "admin_flag" ), - OXUtils::writeBoolean( it.value().adminFlag() ) ); + { + const Folder::GroupPermissions groupPermissions = folder.groupPermissions(); + Folder::GroupPermissions::ConstIterator it = groupPermissions.constBegin(); + while (it != groupPermissions.constEnd()) { + QDomElement group = DAVUtils::addOxElement(document, permissions, QStringLiteral("group"), + OXUtils::writeNumber(it.key())); + DAVUtils::setOxAttribute(group, QStringLiteral("folderpermission"), + OXUtils::writeNumber(it.value().folderPermission())); + DAVUtils::setOxAttribute(group, QStringLiteral("objectreadpermission"), + OXUtils::writeNumber(it.value().objectReadPermission())); + DAVUtils::setOxAttribute(group, QStringLiteral("objectwritepermission"), + OXUtils::writeNumber(it.value().objectWritePermission())); + DAVUtils::setOxAttribute(group, QStringLiteral("objectdeletepermission"), + OXUtils::writeNumber(it.value().objectDeletePermission())); + DAVUtils::setOxAttribute(group, QStringLiteral("admin_flag"), + OXUtils::writeBoolean(it.value().adminFlag())); - ++it; + ++it; + } } - } } -static void parseFolderPermissions( const QDomElement &permissions, Folder &folder ) +static void parseFolderPermissions(const QDomElement &permissions, Folder &folder) { - Folder::UserPermissions userPermissions; - Folder::GroupPermissions groupPermissions; + Folder::UserPermissions userPermissions; + Folder::GroupPermissions groupPermissions; - QDomElement element = permissions.firstChildElement(); - while ( !element.isNull() ) { - if ( element.tagName() == QLatin1String( "user" ) ) { - Folder::Permissions permissions; - permissions.setFolderPermission( (Folder::Permissions::FolderPermission)OXUtils::readNumber( element.attribute( QLatin1String( "folderpermission" ), QLatin1String( "0" ) ) ) ); - permissions.setObjectReadPermission( (Folder::Permissions::ObjectReadPermission)OXUtils::readNumber( element.attribute( QLatin1String( "objectreadpermission" ), QLatin1String( "0" ) ) ) ); - permissions.setObjectWritePermission( (Folder::Permissions::ObjectWritePermission)OXUtils::readNumber( element.attribute( QLatin1String( "objectwritepermission" ), QLatin1String( "0" ) ) ) ); - permissions.setObjectDeletePermission( (Folder::Permissions::ObjectDeletePermission)OXUtils::readNumber( element.attribute( QLatin1String( "objectdeletepermission" ), QLatin1String( "0" ) ) ) ); - permissions.setAdminFlag( OXUtils::readBoolean( element.attribute( QLatin1String( "admin_flag" ), QLatin1String( "false" ) ) ) ); - - userPermissions.insert( OXUtils::readNumber( element.text() ), permissions ); - } else if ( element.tagName() == QLatin1String( "group" ) ) { - Folder::Permissions permissions; - permissions.setFolderPermission( (Folder::Permissions::FolderPermission)OXUtils::readNumber( element.attribute( QLatin1String( "folderpermission" ), QLatin1String( "0" ) ) ) ); - permissions.setObjectReadPermission( (Folder::Permissions::ObjectReadPermission)OXUtils::readNumber( element.attribute( QLatin1String( "objectreadpermission" ), QLatin1String( "0" ) ) ) ); - permissions.setObjectWritePermission( (Folder::Permissions::ObjectWritePermission)OXUtils::readNumber( element.attribute( QLatin1String( "objectwritepermission" ), QLatin1String( "0" ) ) ) ); - permissions.setObjectDeletePermission( (Folder::Permissions::ObjectDeletePermission)OXUtils::readNumber( element.attribute( QLatin1String( "objectdeletepermission" ), QLatin1String( "0" ) ) ) ); - permissions.setAdminFlag( OXUtils::readBoolean( element.attribute( QLatin1String( "admin_flag" ), QLatin1String( "false" ) ) ) ); + QDomElement element = permissions.firstChildElement(); + while (!element.isNull()) { + if (element.tagName() == QLatin1String("user")) { + Folder::Permissions permissions; + permissions.setFolderPermission((Folder::Permissions::FolderPermission)OXUtils::readNumber(element.attribute(QStringLiteral("folderpermission"), QStringLiteral("0")))); + permissions.setObjectReadPermission((Folder::Permissions::ObjectReadPermission)OXUtils::readNumber(element.attribute(QStringLiteral("objectreadpermission"), QStringLiteral("0")))); + permissions.setObjectWritePermission((Folder::Permissions::ObjectWritePermission)OXUtils::readNumber(element.attribute(QStringLiteral("objectwritepermission"), QStringLiteral("0")))); + permissions.setObjectDeletePermission((Folder::Permissions::ObjectDeletePermission)OXUtils::readNumber(element.attribute(QStringLiteral("objectdeletepermission"), QStringLiteral("0")))); + permissions.setAdminFlag(OXUtils::readBoolean(element.attribute(QStringLiteral("admin_flag"), QStringLiteral("false")))); + + userPermissions.insert(OXUtils::readNumber(element.text()), permissions); + } else if (element.tagName() == QLatin1String("group")) { + Folder::Permissions permissions; + permissions.setFolderPermission((Folder::Permissions::FolderPermission)OXUtils::readNumber(element.attribute(QStringLiteral("folderpermission"), QStringLiteral("0")))); + permissions.setObjectReadPermission((Folder::Permissions::ObjectReadPermission)OXUtils::readNumber(element.attribute(QStringLiteral("objectreadpermission"), QStringLiteral("0")))); + permissions.setObjectWritePermission((Folder::Permissions::ObjectWritePermission)OXUtils::readNumber(element.attribute(QStringLiteral("objectwritepermission"), QStringLiteral("0")))); + permissions.setObjectDeletePermission((Folder::Permissions::ObjectDeletePermission)OXUtils::readNumber(element.attribute(QStringLiteral("objectdeletepermission"), QStringLiteral("0")))); + permissions.setAdminFlag(OXUtils::readBoolean(element.attribute(QStringLiteral("admin_flag"), QStringLiteral("false")))); - groupPermissions.insert( OXUtils::readNumber( element.text() ), permissions ); - } + groupPermissions.insert(OXUtils::readNumber(element.text()), permissions); + } - element = element.nextSiblingElement(); - } + element = element.nextSiblingElement(); + } - folder.setUserPermissions( userPermissions ); - folder.setGroupPermissions( groupPermissions ); + folder.setUserPermissions(userPermissions); + folder.setGroupPermissions(groupPermissions); } -Folder OXA::FolderUtils::parseFolder( const QDomElement &propElement ) +Folder OXA::FolderUtils::parseFolder(const QDomElement &propElement) { - Folder folder; + Folder folder; - QDomElement element = propElement.firstChildElement(); - while ( !element.isNull() ) { - if ( element.tagName() == QLatin1String( "object_status" ) ) { - const QString content = OXUtils::readString( element.text() ); - if ( content == QLatin1String( "CREATE" ) ) - folder.setObjectStatus( Folder::Created ); - else if ( content == QLatin1String( "DELETE" ) ) - folder.setObjectStatus( Folder::Deleted ); - else - Q_ASSERT( false ); - } else if ( element.tagName() == QLatin1String( "title" ) ) { - folder.setTitle( OXUtils::readString( element.text() ) ); - } else if ( element.tagName() == QLatin1String( "owner" ) ) { - folder.setOwner( OXUtils::readNumber( element.text() ) ); - } else if ( element.tagName() == QLatin1String( "module" ) ) { - const QString content = OXUtils::readString( element.text() ); - if ( content == QLatin1String( "calendar" ) ) - folder.setModule( Folder::Calendar ); - else if ( content == QLatin1String( "contact" ) ) - folder.setModule( Folder::Contacts ); - else if ( content == QLatin1String( "task" ) ) - folder.setModule( Folder::Tasks ); - else - folder.setModule( Folder::Unbound ); - } else if ( element.tagName() == QLatin1String( "type" ) ) { - const QString content = OXUtils::readString( element.text() ); - if ( content == QLatin1String( "public" ) ) - folder.setType( Folder::Public ); - else if ( content == QLatin1String( "private" ) ) - folder.setType( Folder::Private ); - else - Q_ASSERT( false ); - } else if ( element.tagName() == QLatin1String( "defaultfolder" ) ) { - folder.setIsDefaultFolder( OXUtils::readBoolean( element.text() ) ); - } else if ( element.tagName() == QLatin1String( "last_modified" ) ) { - folder.setLastModified( OXUtils::readString( element.text() ) ); - } else if ( element.tagName() == QLatin1String( "object_id" ) ) { - folder.setObjectId( OXUtils::readNumber( element.text() ) ); - } else if ( element.tagName() == QLatin1String( "folder_id" ) ) { - folder.setFolderId( OXUtils::readNumber( element.text() ) ); - } else if ( element.tagName() == QLatin1String( "permissions" ) ) { - parseFolderPermissions( element, folder ); - } + QDomElement element = propElement.firstChildElement(); + while (!element.isNull()) { + if (element.tagName() == QLatin1String("object_status")) { + const QString content = OXUtils::readString(element.text()); + if (content == QLatin1String("CREATE")) { + folder.setObjectStatus(Folder::Created); + } else if (content == QLatin1String("DELETE")) { + folder.setObjectStatus(Folder::Deleted); + } else { + Q_ASSERT(false); + } + } else if (element.tagName() == QLatin1String("title")) { + folder.setTitle(OXUtils::readString(element.text())); + } else if (element.tagName() == QLatin1String("owner")) { + folder.setOwner(OXUtils::readNumber(element.text())); + } else if (element.tagName() == QLatin1String("module")) { + const QString content = OXUtils::readString(element.text()); + if (content == QLatin1String("calendar")) { + folder.setModule(Folder::Calendar); + } else if (content == QLatin1String("contact")) { + folder.setModule(Folder::Contacts); + } else if (content == QLatin1String("task")) { + folder.setModule(Folder::Tasks); + } else { + folder.setModule(Folder::Unbound); + } + } else if (element.tagName() == QLatin1String("type")) { + const QString content = OXUtils::readString(element.text()); + if (content == QLatin1String("public")) { + folder.setType(Folder::Public); + } else if (content == QLatin1String("private")) { + folder.setType(Folder::Private); + } else { + Q_ASSERT(false); + } + } else if (element.tagName() == QLatin1String("defaultfolder")) { + folder.setIsDefaultFolder(OXUtils::readBoolean(element.text())); + } else if (element.tagName() == QLatin1String("last_modified")) { + folder.setLastModified(OXUtils::readString(element.text())); + } else if (element.tagName() == QLatin1String("object_id")) { + folder.setObjectId(OXUtils::readNumber(element.text())); + } else if (element.tagName() == QLatin1String("folder_id")) { + folder.setFolderId(OXUtils::readNumber(element.text())); + } else if (element.tagName() == QLatin1String("permissions")) { + parseFolderPermissions(element, folder); + } - element = element.nextSiblingElement(); - } + element = element.nextSiblingElement(); + } - return folder; + return folder; } -void OXA::FolderUtils::addFolderElements( QDomDocument &document, QDomElement &propElement, const Folder &folder ) +void OXA::FolderUtils::addFolderElements(QDomDocument &document, QDomElement &propElement, const Folder &folder) { - DAVUtils::addOxElement( document, propElement, QLatin1String( "title" ), OXUtils::writeString( folder.title() ) ); - DAVUtils::addOxElement( document, propElement, QLatin1String( "folder_id" ), OXUtils::writeNumber( folder.folderId() ) ); + DAVUtils::addOxElement(document, propElement, QStringLiteral("title"), OXUtils::writeString(folder.title())); + DAVUtils::addOxElement(document, propElement, QStringLiteral("folder_id"), OXUtils::writeNumber(folder.folderId())); - const QString type = (folder.type() == Folder::Public ? QLatin1String( "public" ) : QLatin1String( "private" )); - DAVUtils::addOxElement( document, propElement, QLatin1String( "type" ), OXUtils::writeString( type ) ); + const QString type = (folder.type() == Folder::Public ? QLatin1String("public") : QLatin1String("private")); + DAVUtils::addOxElement(document, propElement, QStringLiteral("type"), OXUtils::writeString(type)); - QString module; - switch ( folder.module() ) { - case Folder::Calendar: module = QLatin1String( "calendar" ); break; - case Folder::Contacts: module = QLatin1String( "contact" ); break; - case Folder::Tasks: module = QLatin1String( "task" ); break; + QString module; + switch (folder.module()) { + case Folder::Calendar: module = QLatin1String("calendar"); break; + case Folder::Contacts: module = QLatin1String("contact"); break; + case Folder::Tasks: module = QLatin1String("task"); break; default: break; - } - DAVUtils::addOxElement( document, propElement, QLatin1String( "module" ), OXUtils::writeString( module ) ); + } + DAVUtils::addOxElement(document, propElement, QStringLiteral("module"), OXUtils::writeString(module)); - QDomElement permissions = DAVUtils::addOxElement( document, propElement, QLatin1String( "permissions" ) ); - createFolderPermissions( folder, document, permissions ); + QDomElement permissions = DAVUtils::addOxElement(document, propElement, QStringLiteral("permissions")); + createFolderPermissions(folder, document, permissions); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/folderutils.h kdepim-runtime-15.08.0/resources/openxchange/oxa/folderutils.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/folderutils.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/folderutils.h 2015-08-10 21:01:02.000000000 +0000 @@ -25,7 +25,8 @@ class QDomDocument; class QDomElement; -namespace OXA { +namespace OXA +{ class Folder; @@ -36,15 +37,15 @@ */ namespace FolderUtils { - /** - * Parses the XML tree under @p propElement and return the folder. - */ - Folder parseFolder( const QDomElement &propElement ); +/** + * Parses the XML tree under @p propElement and return the folder. + */ +Folder parseFolder(const QDomElement &propElement); - /** - * Adds the @p folder data to the @p document under the @p propElement. - */ - void addFolderElements( QDomDocument &document, QDomElement &propElement, const Folder &folder ); +/** + * Adds the @p folder data to the @p document under the @p propElement. + */ +void addFolderElements(QDomDocument &document, QDomElement &propElement, const Folder &folder); } } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/incidenceutils.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/incidenceutils.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/incidenceutils.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/incidenceutils.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,8 +26,8 @@ #include "oxutils.h" #include "users.h" -#include -#include +#include +#include #include @@ -36,531 +36,560 @@ using namespace OXA; -static void parseMembersAttribute( const QDomElement &element, - const KCalCore::Incidence::Ptr &incidence ) +static void parseMembersAttribute(const QDomElement &element, + const KCalCore::Incidence::Ptr &incidence) { - incidence->clearAttendees(); + incidence->clearAttendees(); - for ( QDomElement child = element.firstChildElement(); !child.isNull(); child = child.nextSiblingElement() ) { - if ( child.tagName() == QLatin1String( "user" ) ) { - const QString uid = child.text(); - - const User user = Users::self()->lookupUid( uid.toLongLong() ); - - QString name; - QString email; - KCalCore::Attendee::Ptr attendee = incidence->attendeeByUid( uid ); - if ( !user.isValid() ) { - if ( attendee ) - continue; - - name = uid; - email = uid + '@' + KUrl( DavManager::self()->baseUrl() ).host(); - } else { - name = user.name(); - email = user.email(); - } - - if ( attendee ) { - attendee->setName( name ); - attendee->setEmail( email ); - } else { - attendee = KCalCore::Attendee::Ptr( new KCalCore::Attendee( name, email ) ); - attendee->setUid( uid ); - incidence->addAttendee( attendee ); - } - - const QString status = child.attribute( "confirm" ); - if ( !status.isEmpty() ) { - if ( status == QLatin1String( "accept" ) ) { - attendee->setStatus( KCalCore::Attendee::Accepted ); - } else if ( status == QLatin1String( "decline" ) ) { - attendee->setStatus( KCalCore::Attendee::Declined ); + for (QDomElement child = element.firstChildElement(); !child.isNull(); child = child.nextSiblingElement()) { + if (child.tagName() == QLatin1String("user")) { + const QString uid = child.text(); + + const User user = Users::self()->lookupUid(uid.toLongLong()); + + QString name; + QString email; + KCalCore::Attendee::Ptr attendee = incidence->attendeeByUid(uid); + if (!user.isValid()) { + if (attendee) { + continue; + } + + name = uid; + email = uid + '@' + DavManager::self()->baseUrl().host(); + } else { + name = user.name(); + email = user.email(); + } + + if (attendee) { + attendee->setName(name); + attendee->setEmail(email); + } else { + attendee = KCalCore::Attendee::Ptr(new KCalCore::Attendee(name, email)); + attendee->setUid(uid); + incidence->addAttendee(attendee); + } + + const QString status = child.attribute("confirm"); + if (!status.isEmpty()) { + if (status == QLatin1String("accept")) { + attendee->setStatus(KCalCore::Attendee::Accepted); + } else if (status == QLatin1String("decline")) { + attendee->setStatus(KCalCore::Attendee::Declined); + } else { + attendee->setStatus(KCalCore::Attendee::NeedsAction); + } + } + } + } +} + +static void parseIncidenceAttribute(const QDomElement &element, + const KCalCore::Incidence::Ptr &incidence) +{ + const QString tagName = element.tagName(); + const QString text = OXUtils::readString(element.text()); + + if (tagName == QLatin1String("title")) { + incidence->setSummary(text); + } else if (tagName == QLatin1String("note")) { + incidence->setDescription(text); + } else if (tagName == QLatin1String("alarm")) { + const int minutes = OXUtils::readNumber(element.text()); + if (minutes != 0) { + KCalCore::Alarm::List alarms = incidence->alarms(); + KCalCore::Alarm::Ptr alarm; + if (alarms.isEmpty()) { + alarm = incidence->newAlarm(); + } else { + alarm = alarms.first(); + } + + if (alarm->type() == KCalCore::Alarm::Invalid) { + alarm->setType(KCalCore::Alarm::Display); + } + + KCalCore::Duration duration(minutes * -60); + alarm->setStartOffset(duration); + alarm->setEnabled(true); } else { - attendee->setStatus( KCalCore::Attendee::NeedsAction ); + // 0 reminder -> disable alarm + incidence->clearAlarms(); } - } + } else if (tagName == QLatin1String("created_by")) { + const User user = Users::self()->lookupUid(OXUtils::readNumber(element.text())); + incidence->setOrganizer(KCalCore::Person::Ptr(new KCalCore::Person(user.name(), user.email()))); + } else if (tagName == QLatin1String("participants")) { + parseMembersAttribute(element, incidence); + } else if (tagName == QLatin1String("private_flag")) { + if (OXUtils::readBoolean(element.text()) == true) { + incidence->setSecrecy(KCalCore::Incidence::SecrecyPrivate); + } else { + incidence->setSecrecy(KCalCore::Incidence::SecrecyPublic); + } + } else if (tagName == QLatin1String("categories")) { + incidence->setCategories(text.split(QRegExp(QLatin1String(",\\s*")))); } - } } -static void parseIncidenceAttribute( const QDomElement &element, - const KCalCore::Incidence::Ptr &incidence ) -{ - const QString tagName = element.tagName(); - const QString text = OXUtils::readString( element.text() ); - - if ( tagName == QLatin1String( "title" ) ) { - incidence->setSummary( text ); - } else if ( tagName == QLatin1String( "note" ) ) { - incidence->setDescription( text ); - } else if ( tagName == QLatin1String( "alarm" ) ) { - const int minutes = OXUtils::readNumber( element.text() ); - if ( minutes != 0 ) { - KCalCore::Alarm::List alarms = incidence->alarms(); - KCalCore::Alarm::Ptr alarm; - if ( alarms.isEmpty() ) - alarm = incidence->newAlarm(); - else - alarm = alarms.first(); - - if ( alarm->type() == KCalCore::Alarm::Invalid ) - alarm->setType( KCalCore::Alarm::Display ); - - KCalCore::Duration duration( minutes * -60 ); - alarm->setStartOffset( duration ); - alarm->setEnabled( true ); +static void parseEventAttribute(const QDomElement &element, + const KCalCore::Event::Ptr &event) +{ + const QString tagName = element.tagName(); + const QString text = OXUtils::readString(element.text()); + + if (tagName == QLatin1String("start_date")) { + KDateTime dateTime = KDateTime(OXUtils::readDateTime(element.text()), KDateTime::UTC); + if (event->allDay()) { + dateTime.setDateOnly(true); + } + + event->setDtStart(dateTime); + + } else if (tagName == QLatin1String("end_date")) { + KDateTime dateTime = KDateTime(OXUtils::readDateTime(element.text()), KDateTime::UTC); + if (event->allDay()) { + dateTime = dateTime.addSecs(-1); + } + + event->setDtEnd(dateTime); + + } else if (tagName == QLatin1String("location")) { + event->setLocation(text); + } +} + +static void parseTodoAttribute(const QDomElement &element, + const KCalCore::Todo::Ptr &todo) +{ + const QString tagName = element.tagName(); + const QString text = OXUtils::readString(element.text()); + + if (tagName == QLatin1String("start_date")) { + const KDateTime dateTime = KDateTime(OXUtils::readDateTime(element.text()), KDateTime::UTC); + if (dateTime.isValid()) { + todo->setDtStart(dateTime); + } + } else if (tagName == QLatin1String("end_date")) { + const KDateTime dateTime = KDateTime(OXUtils::readDateTime(element.text()), KDateTime::UTC); + if (dateTime.isValid()) { + todo->setDtDue(dateTime); + } + } else if (tagName == QLatin1String("priority")) { + const int priorityNumber = OXUtils::readNumber(element.text()); + if (priorityNumber < 1 || priorityNumber > 3) { + qDebug() << "Unknown priority:" << text; + } else { + int priority = 0; + switch (priorityNumber) { + case 1: + priority = 9; + break; + case 2: + priority = 5; + break; + case 3: + priority = 1; + break; + } + todo->setPriority(priority); + } + } else if (tagName == QLatin1String("percent_completed")) { + todo->setPercentComplete(OXUtils::readNumber(element.text())); + } +} + +static void parseRecurrence(const QDomElement &element, + const KCalCore::Incidence::Ptr &incidence) +{ + QString type; + + int dailyValue = -1; + QDateTime endDate; + + int weeklyValue = -1; + QBitArray days(7); // days, starting with monday + bool daysSet = false; + + int monthlyValueDay = -1; + int monthlyValueMonth = -1; + + int yearlyValueDay = -1; + int yearlyMonth = -1; + + int monthly2Recurrency = 0; + int monthly2ValueMonth = -1; + + int yearly2Recurrency = 0; + int yearly2Day = 0; + int yearly2Month = -1; + + KCalCore::DateList deleteExceptions; + + for (QDomElement child = element.firstChildElement(); !child.isNull(); child = child.nextSiblingElement()) { + const QString tagName = child.tagName(); + const QString text = OXUtils::readString(child.text()); + + if (tagName == QLatin1String("recurrence_type")) { + type = text; + } else if (tagName == QLatin1String("interval")) { + dailyValue = text.toInt(); + weeklyValue = text.toInt(); + monthlyValueMonth = text.toInt(); + monthly2ValueMonth = text.toInt(); + } else if (tagName == QLatin1String("days")) { + int tmp = text.toInt(); // OX encodes days binary: 1=Su, 2=Mo, 4=Tu, ... + for (int i = 0; i < 7; ++i) { + if (tmp & (1 << i)) { + days.setBit((i + 6) % 7); + } + } + daysSet = true; + } else if (tagName == QLatin1String("day_in_month")) { + monthlyValueDay = text.toInt(); + monthly2Recurrency = text.toInt(); + yearlyValueDay = text.toInt(); + yearly2Recurrency = text.toInt(); + } else if (tagName == QLatin1String("month")) { + yearlyMonth = text.toInt() + 1; // starts at 0 + yearly2Month = text.toInt() + 1; + } else if ((tagName == QLatin1String("deleteexceptions")) || (tagName == QLatin1String("changeexceptions"))) { + const QStringList exceptionDates = text.split(QLatin1String(",")); + deleteExceptions.reserve(exceptionDates.count()); + foreach (const QString &date, exceptionDates) { + deleteExceptions.append(OXUtils::readDate(date)); + } + } else if (tagName == QLatin1String("until")) { + endDate = OXUtils::readDateTime(child.text()); + } + //TODO: notification + } + + if (daysSet && type == QLatin1String("monthly")) { + type = QLatin1String("monthly2"); // HACK: OX doesn't cleanly distinguish between monthly and monthly2 + } + if (daysSet && type == QLatin1String("yearly")) { + type = QLatin1String("yearly2"); + } + + KCalCore::Recurrence *recurrence = incidence->recurrence(); + + if (type == QLatin1String("daily")) { + recurrence->setDaily(dailyValue); + } else if (type == QLatin1String("weekly")) { + recurrence->setWeekly(weeklyValue, days); + } else if (type == QLatin1String("monthly")) { + recurrence->setMonthly(monthlyValueMonth); + recurrence->addMonthlyDate(monthlyValueDay); + } else if (type == QLatin1String("yearly")) { + recurrence->setYearly(1); + recurrence->addYearlyDate(yearlyValueDay); + recurrence->addYearlyMonth(yearlyMonth); + } else if (type == QLatin1String("monthly2")) { + recurrence->setMonthly(monthly2ValueMonth); + QBitArray _days(7); + if (daysSet) { + _days = days; + } else { + _days.setBit(incidence->dtStart().date().dayOfWeek()); + } + recurrence->addMonthlyPos(monthly2Recurrency, _days); + } else if (type == QLatin1String("yearly2")) { + recurrence->setYearly(1); + recurrence->addYearlyMonth(yearly2Month); + QBitArray _days(7); + if (daysSet) { + _days = days; + } else { + _days.setBit((yearly2Day + 5) % 7); + } + recurrence->addYearlyPos(yearly2Recurrency, _days); + } + + if (endDate.isValid()) { + recurrence->setEndDate(endDate.date()); + } + + recurrence->setExDates(deleteExceptions); +} + +static void createIncidenceAttributes(QDomDocument &document, QDomElement &parent, + const KCalCore::Incidence::Ptr &incidence) +{ + DAVUtils::addOxElement(document, parent, QStringLiteral("title"), OXUtils::writeString(incidence->summary())); + DAVUtils::addOxElement(document, parent, QStringLiteral("note"), OXUtils::writeString(incidence->description())); + + if (incidence->attendeeCount() > 0) { + QDomElement members = DAVUtils::addOxElement(document, parent, QStringLiteral("participants")); + const KCalCore::Attendee::List attendees = incidence->attendees(); + foreach (const KCalCore::Attendee::Ptr &attendee, attendees) { + const User user = Users::self()->lookupEmail(attendee->email()); + + if (!user.isValid()) { + continue; + } + + QString status; + switch (attendee->status()) { + case KCalCore::Attendee::Accepted: status = QLatin1String("accept"); break; + case KCalCore::Attendee::Declined: status = QLatin1String("decline"); break; + default: status = QLatin1String("none"); break; + } + + QDomElement element = DAVUtils::addOxElement(document, members, QStringLiteral("user"), OXUtils::writeNumber(user.uid())); + DAVUtils::setOxAttribute(element, "confirm", status); + } + } + + if (incidence->secrecy() == KCalCore::Incidence::SecrecyPublic) { + DAVUtils::addOxElement(document, parent, QStringLiteral("private_flag"), OXUtils::writeBoolean(false)); + } else { + DAVUtils::addOxElement(document, parent, QStringLiteral("private_flag"), OXUtils::writeBoolean(true)); + } + + // set reminder as the number of minutes to the start of the event + const KCalCore::Alarm::List alarms = incidence->alarms(); + if (!alarms.isEmpty() && alarms.first()->hasStartOffset() && alarms.first()->enabled()) { + DAVUtils::addOxElement(document, parent, QStringLiteral("alarm_flag"), OXUtils::writeBoolean(true)); + DAVUtils::addOxElement(document, parent, QStringLiteral("alarm"), OXUtils::writeNumber((-1) * alarms.first()->startOffset().asSeconds() / 60)); + } else { + DAVUtils::addOxElement(document, parent, QStringLiteral("alarm_flag"), OXUtils::writeBoolean(false)); + DAVUtils::addOxElement(document, parent, QStringLiteral("alarm"), QStringLiteral("0")); + } + + // categories + DAVUtils::addOxElement(document, parent, QStringLiteral("categories"), OXUtils::writeString(incidence->categories().join(QLatin1String(", ")))); +} + +static void createEventAttributes(QDomDocument &document, QDomElement &parent, + const KCalCore::Event::Ptr &event) +{ + if (event->allDay()) { + DAVUtils::addOxElement(document, parent, QStringLiteral("start_date"), OXUtils::writeDate(event->dtStart().date())); + if (event->hasEndDate()) { + DAVUtils::addOxElement(document, parent, QStringLiteral("end_date"), OXUtils::writeDate(event->dtEnd().date())); + } + } else { + DAVUtils::addOxElement(document, parent, QStringLiteral("start_date"), OXUtils::writeDateTime(event->dtStart().dateTime())); + if (event->hasEndDate()) { + DAVUtils::addOxElement(document, parent, QStringLiteral("end_date"), OXUtils::writeDateTime(event->dtEnd().dateTime())); + } + } + + if (!event->hasEndDate()) { + DAVUtils::addOxElement(document, parent, QStringLiteral("end_date")); + } + + DAVUtils::addOxElement(document, parent, QStringLiteral("location"), OXUtils::writeString(event->location())); + DAVUtils::addOxElement(document, parent, QStringLiteral("full_time"), OXUtils::writeBoolean(event->allDay())); + + if (event->transparency() == KCalCore::Event::Transparent) { + DAVUtils::addOxElement(document, parent, QStringLiteral("shown_as"), OXUtils::writeNumber(4)); + } else if (event->transparency() == KCalCore::Event::Opaque) { + DAVUtils::addOxElement(document, parent, QStringLiteral("shown_as"), OXUtils::writeNumber(1)); + } + +} + +static void createTaskAttributes(QDomDocument &document, QDomElement &parent, + const KCalCore::Todo::Ptr &todo) +{ + if (todo->hasStartDate()) { + DAVUtils::addOxElement(document, parent, QStringLiteral("start_date"), OXUtils::writeDateTime(todo->dtStart().dateTime())); } else { - // 0 reminder -> disable alarm - incidence->clearAlarms(); + DAVUtils::addOxElement(document, parent, QStringLiteral("start_date")); } - } else if ( tagName == QLatin1String( "created_by" ) ) { - const User user = Users::self()->lookupUid( OXUtils::readNumber( element.text() ) ); - incidence->setOrganizer( KCalCore::Person::Ptr( new KCalCore::Person( user.name(), user.email() ) ) ); - } else if ( tagName == QLatin1String( "participants" ) ) { - parseMembersAttribute( element, incidence ); - } else if ( tagName == QLatin1String( "private_flag" ) ) { - if ( OXUtils::readBoolean( element.text() ) == true ) - incidence->setSecrecy( KCalCore::Incidence::SecrecyPrivate ); - else - incidence->setSecrecy( KCalCore::Incidence::SecrecyPublic ); - } else if ( tagName == QLatin1String( "categories" ) ) { - incidence->setCategories( text.split( QRegExp( QLatin1String( ",\\s*" ) ) ) ); - } -} - -static void parseEventAttribute( const QDomElement &element, - const KCalCore::Event::Ptr &event ) -{ - const QString tagName = element.tagName(); - const QString text = OXUtils::readString( element.text() ); - - if ( tagName == QLatin1String( "start_date" ) ) { - KDateTime dateTime = KDateTime( OXUtils::readDateTime( element.text() ), KDateTime::UTC ); - if ( event->allDay() ) - dateTime.setDateOnly( true ); - - event->setDtStart( dateTime ); - - } else if ( tagName == QLatin1String( "end_date" ) ) { - KDateTime dateTime = KDateTime( OXUtils::readDateTime( element.text() ), KDateTime::UTC ); - if ( event->allDay() ) - dateTime = dateTime.addSecs( -1 ); - - event->setDtEnd( dateTime ); - - } else if ( tagName == QLatin1String( "location" ) ) { - event->setLocation( text ); - } -} - -static void parseTodoAttribute( const QDomElement &element, - const KCalCore::Todo::Ptr &todo ) -{ - const QString tagName = element.tagName(); - const QString text = OXUtils::readString( element.text() ); - - if ( tagName == QLatin1String( "start_date" ) ) { - const KDateTime dateTime = KDateTime( OXUtils::readDateTime( element.text() ), KDateTime::UTC ); - if ( dateTime.isValid() ) { - todo->setDtStart( dateTime ); - } - } else if ( tagName == QLatin1String( "end_date" ) ) { - const KDateTime dateTime = KDateTime( OXUtils::readDateTime( element.text() ), KDateTime::UTC ); - if ( dateTime.isValid() ) { - todo->setDtDue( dateTime ); - } - } else if ( tagName == QLatin1String( "priority" ) ) { - const int priorityNumber = OXUtils::readNumber( element.text() ); - if ( priorityNumber < 1 || priorityNumber > 3 ) { - qDebug() << "Unknown priority:" << text; + + if (todo->hasDueDate()) { + DAVUtils::addOxElement(document, parent, QStringLiteral("end_date"), OXUtils::writeDateTime(todo->dtDue().dateTime())); } else { - int priority; - switch ( priorityNumber ) { - case 1: - priority = 9; - break; - case 2: - priority = 5; - break; - case 3: - priority = 1; - break; - } - todo->setPriority( priority ); - } - } else if ( tagName == QLatin1String( "percent_completed" ) ) { - todo->setPercentComplete( OXUtils::readNumber( element.text() ) ); - } -} - -static void parseRecurrence( const QDomElement &element, - const KCalCore::Incidence::Ptr &incidence ) -{ - QString type; - - int dailyValue = -1; - QDateTime endDate; - - int weeklyValue = -1; - QBitArray days( 7 ); // days, starting with monday - bool daysSet = false; - - int monthlyValueDay = -1; - int monthlyValueMonth = -1; - - int yearlyValueDay = -1; - int yearlyMonth = -1; - - int monthly2Recurrency = 0; - int monthly2ValueMonth = -1; - - int yearly2Recurrency = 0; - int yearly2Day = 0; - int yearly2Month = -1; - - KCalCore::DateList deleteExceptions; - - for ( QDomElement child = element.firstChildElement(); !child.isNull(); child = child.nextSiblingElement() ) { - const QString tagName = child.tagName(); - const QString text = OXUtils::readString( child.text() ); - - if ( tagName == QLatin1String( "recurrence_type" ) ) { - type = text; - } else if ( tagName == QLatin1String( "interval" ) ) { - dailyValue = text.toInt(); - weeklyValue = text.toInt(); - monthlyValueMonth = text.toInt(); - monthly2ValueMonth = text.toInt(); - } else if ( tagName == QLatin1String( "days" ) ) { - int tmp = text.toInt(); // OX encodes days binary: 1=Su, 2=Mo, 4=Tu, ... - for ( int i = 0; i < 7; ++i ) { - if ( tmp & (1 << i) ) - days.setBit( (i + 6) % 7 ); - } - daysSet = true; - } else if ( tagName == QLatin1String( "day_in_month" ) ) { - monthlyValueDay = text.toInt(); - monthly2Recurrency = text.toInt(); - yearlyValueDay = text.toInt(); - yearly2Recurrency = text.toInt(); - } else if ( tagName == QLatin1String( "month" ) ) { - yearlyMonth = text.toInt() + 1; // starts at 0 - yearly2Month = text.toInt() + 1; - } else if ( ( tagName == QLatin1String( "deleteexceptions" ) ) || ( tagName == QLatin1String( "changeexceptions" ) ) ) { - const QStringList exceptionDates = text.split( QLatin1String( "," ) ); - foreach ( const QString &date, exceptionDates ) - deleteExceptions.append( OXUtils::readDate( date ) ); - } else if ( tagName == QLatin1String( "until" ) ) { - endDate = OXUtils::readDateTime( child.text() ); - } - //TODO: notification - } - - if ( daysSet && type == QLatin1String( "monthly" ) ) - type = QLatin1String( "monthly2" ); // HACK: OX doesn't cleanly distinguish between monthly and monthly2 - if ( daysSet && type == QLatin1String( "yearly" ) ) - type = QLatin1String( "yearly2" ); - - KCalCore::Recurrence *recurrence = incidence->recurrence(); - - if ( type == QLatin1String( "daily" ) ) { - recurrence->setDaily( dailyValue ); - } else if ( type == QLatin1String( "weekly" ) ) { - recurrence->setWeekly( weeklyValue, days ); - } else if ( type == QLatin1String( "monthly" ) ) { - recurrence->setMonthly( monthlyValueMonth ); - recurrence->addMonthlyDate( monthlyValueDay ); - } else if ( type == QLatin1String( "yearly" ) ) { - recurrence->setYearly( 1 ); - recurrence->addYearlyDate( yearlyValueDay ); - recurrence->addYearlyMonth( yearlyMonth ); - } else if ( type == QLatin1String( "monthly2" ) ) { - recurrence->setMonthly( monthly2ValueMonth ); - QBitArray _days( 7 ); - if ( daysSet ) - _days = days; - else - _days.setBit( incidence->dtStart().date().dayOfWeek() ); - recurrence->addMonthlyPos( monthly2Recurrency, _days ); - } else if ( type == QLatin1String( "yearly2" ) ) { - recurrence->setYearly( 1 ); - recurrence->addYearlyMonth( yearly2Month ); - QBitArray _days( 7 ); - if ( daysSet ) - _days = days; - else - _days.setBit( ( yearly2Day + 5 ) % 7 ); - recurrence->addYearlyPos( yearly2Recurrency, _days ); - } - - if ( endDate.isValid() ) - recurrence->setEndDate( endDate.date() ); - - recurrence->setExDates( deleteExceptions ); -} - - -static void createIncidenceAttributes( QDomDocument &document, QDomElement &parent, - const KCalCore::Incidence::Ptr &incidence ) -{ - DAVUtils::addOxElement( document, parent, QLatin1String( "title" ), OXUtils::writeString( incidence->summary() ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "note" ), OXUtils::writeString( incidence->description() ) ); - - if ( incidence->attendeeCount() > 0 ) { - QDomElement members = DAVUtils::addOxElement( document, parent, QLatin1String( "participants" ) ); - const KCalCore::Attendee::List attendees = incidence->attendees(); - foreach ( const KCalCore::Attendee::Ptr attendee, attendees ) { - const User user = Users::self()->lookupEmail( attendee->email() ); - - if ( !user.isValid() ) - continue; - - QString status; - switch ( attendee->status() ) { - case KCalCore::Attendee::Accepted: status = QLatin1String( "accept" ); break; - case KCalCore::Attendee::Declined: status = QLatin1String( "decline" ); break; - default: status = QLatin1String( "none" ); break; - } - - QDomElement element = DAVUtils::addOxElement( document, members, QLatin1String( "user" ), OXUtils::writeNumber( user.uid() ) ); - DAVUtils::setOxAttribute( element, "confirm", status ); - } - } - - if ( incidence->secrecy() == KCalCore::Incidence::SecrecyPublic ) - DAVUtils::addOxElement( document, parent, QLatin1String( "private_flag" ), OXUtils::writeBoolean( false ) ); - else - DAVUtils::addOxElement( document, parent, QLatin1String( "private_flag" ), OXUtils::writeBoolean( true ) ); - - // set reminder as the number of minutes to the start of the event - const KCalCore::Alarm::List alarms = incidence->alarms(); - if ( !alarms.isEmpty() && alarms.first()->hasStartOffset() && alarms.first()->enabled() ) { - DAVUtils::addOxElement( document, parent, QLatin1String( "alarm_flag" ), OXUtils::writeBoolean( true ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "alarm" ), OXUtils::writeNumber( (-1) * alarms.first()->startOffset().asSeconds() / 60 ) ); - } else { - DAVUtils::addOxElement( document, parent, QLatin1String( "alarm_flag" ), OXUtils::writeBoolean( false ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "alarm" ), QLatin1String( "0" ) ); - } - - // categories - DAVUtils::addOxElement( document, parent, QLatin1String( "categories" ), OXUtils::writeString( incidence->categories().join( QLatin1String( ", " ) ) ) ); -} - -static void createEventAttributes( QDomDocument &document, QDomElement &parent, - const KCalCore::Event::Ptr &event ) -{ - if ( event->allDay() ) { - DAVUtils::addOxElement( document, parent, QLatin1String( "start_date" ), OXUtils::writeDate( event->dtStart().date() ) ); - if ( event->hasEndDate() ) DAVUtils::addOxElement( document, parent, QLatin1String( "end_date" ), OXUtils::writeDate( event->dtEnd().date() ) ); - } else { - DAVUtils::addOxElement( document, parent, QLatin1String( "start_date" ), OXUtils::writeDateTime( event->dtStart().dateTime() ) ); - if ( event->hasEndDate() ) DAVUtils::addOxElement( document, parent, QLatin1String( "end_date" ), OXUtils::writeDateTime( event->dtEnd().dateTime() ) ); - } - - if ( !event->hasEndDate() ) DAVUtils::addOxElement( document, parent, QLatin1String( "end_date" ) ); - - DAVUtils::addOxElement( document, parent, QLatin1String( "location" ), OXUtils::writeString( event->location() ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "full_time" ), OXUtils::writeBoolean( event->allDay() ) ); - - if ( event->transparency() == KCalCore::Event::Transparent ) { - DAVUtils::addOxElement( document, parent, QLatin1String( "shown_as" ), OXUtils::writeNumber( 4 ) ); - } else if ( event->transparency() == KCalCore::Event::Opaque ) { - DAVUtils::addOxElement( document, parent, QLatin1String( "shown_as" ), OXUtils::writeNumber( 1 ) ); - } - -} - -static void createTaskAttributes( QDomDocument &document, QDomElement &parent, - const KCalCore::Todo::Ptr &todo ) -{ - if ( todo->hasStartDate() ) - DAVUtils::addOxElement( document, parent, QLatin1String( "start_date" ), OXUtils::writeDateTime( todo->dtStart().dateTime() ) ); - else - DAVUtils::addOxElement( document, parent, QLatin1String( "start_date" ) ); - - if ( todo->hasDueDate() ) - DAVUtils::addOxElement( document, parent, QLatin1String( "end_date" ), OXUtils::writeDateTime( todo->dtDue().dateTime() ) ); - else - DAVUtils::addOxElement( document, parent, QLatin1String( "end_date" ) ); + DAVUtils::addOxElement(document, parent, QStringLiteral("end_date")); + } - QString priority; - switch ( todo->priority() ) { + QString priority; + switch (todo->priority()) { case 9: case 8: - priority = QLatin1String( "1" ); - break; + priority = QLatin1String("1"); + break; case 2: case 1: - priority = QLatin1String( "3" ); - break; + priority = QLatin1String("3"); + break; default: - priority = QLatin1String( "2" ); - break; - } - DAVUtils::addOxElement( document, parent, QLatin1String( "priority" ), priority ); + priority = QLatin1String("2"); + break; + } + DAVUtils::addOxElement(document, parent, QStringLiteral("priority"), priority); - DAVUtils::addOxElement( document, parent, QLatin1String( "percent_completed" ), OXUtils::writeNumber( todo->percentComplete() ) ); + DAVUtils::addOxElement(document, parent, QStringLiteral("percent_completed"), OXUtils::writeNumber(todo->percentComplete())); } -static void createRecurrenceAttributes( QDomDocument &document, QDomElement &parent, - const KCalCore::Incidence::Ptr &incidence ) +static void createRecurrenceAttributes(QDomDocument &document, QDomElement &parent, + const KCalCore::Incidence::Ptr &incidence) { - if ( !incidence->recurs() ) { - DAVUtils::addOxElement( document, parent, QLatin1String( "recurrence_type" ), QLatin1String( "none" ) ); - return; - } + if (!incidence->recurs()) { + DAVUtils::addOxElement(document, parent, QStringLiteral("recurrence_type"), QStringLiteral("none")); + return; + } - const KCalCore::Recurrence *recurrence = incidence->recurrence(); - int monthOffset = -1; - switch ( recurrence->recurrenceType() ) { + const KCalCore::Recurrence *recurrence = incidence->recurrence(); + int monthOffset = -1; + switch (recurrence->recurrenceType()) { case KCalCore::Recurrence::rDaily: - DAVUtils::addOxElement( document, parent, QLatin1String( "recurrence_type" ), QLatin1String( "daily" ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "interval" ), OXUtils::writeNumber( recurrence->frequency() ) ); - break; - case KCalCore::Recurrence::rWeekly: - { - DAVUtils::addOxElement( document, parent, QLatin1String( "recurrence_type" ), QLatin1String( "weekly" ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "interval" ), OXUtils::writeNumber( recurrence->frequency() ) ); + DAVUtils::addOxElement(document, parent, QStringLiteral("recurrence_type"), QStringLiteral("daily")); + DAVUtils::addOxElement(document, parent, QStringLiteral("interval"), OXUtils::writeNumber(recurrence->frequency())); + break; + case KCalCore::Recurrence::rWeekly: { + DAVUtils::addOxElement(document, parent, QStringLiteral("recurrence_type"), QStringLiteral("weekly")); + DAVUtils::addOxElement(document, parent, QStringLiteral("interval"), OXUtils::writeNumber(recurrence->frequency())); int days = 0; - for ( int i = 0; i < 7; ++i ) { - if ( recurrence->days()[i] ) - days += 1 << ( ( i + 1 ) % 7 ); + for (int i = 0; i < 7; ++i) { + if (recurrence->days()[i]) { + days += 1 << ((i + 1) % 7); + } } - DAVUtils::addOxElement( document, parent, QLatin1String( "days" ), OXUtils::writeNumber( days ) ); - } - break; + DAVUtils::addOxElement(document, parent, QStringLiteral("days"), OXUtils::writeNumber(days)); + } + break; case KCalCore::Recurrence::rMonthlyDay: - DAVUtils::addOxElement( document, parent, QLatin1String( "recurrence_type" ), QLatin1String( "monthly" ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "interval" ), OXUtils::writeNumber( recurrence->frequency() ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "day_in_month" ), OXUtils::writeNumber( recurrence->monthDays().first() ) ); - break; - case KCalCore::Recurrence::rMonthlyPos: - { + DAVUtils::addOxElement(document, parent, QStringLiteral("recurrence_type"), QStringLiteral("monthly")); + DAVUtils::addOxElement(document, parent, QStringLiteral("interval"), OXUtils::writeNumber(recurrence->frequency())); + DAVUtils::addOxElement(document, parent, QStringLiteral("day_in_month"), OXUtils::writeNumber(recurrence->monthDays().first())); + break; + case KCalCore::Recurrence::rMonthlyPos: { const KCalCore::RecurrenceRule::WDayPos wdp = recurrence->monthPositions().first(); - DAVUtils::addOxElement( document, parent, QLatin1String( "recurrence_type" ), QLatin1String( "monthly" ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "interval" ), OXUtils::writeNumber( recurrence->frequency() ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "days" ), OXUtils::writeNumber( 1 << wdp.day() ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "day_in_month" ), OXUtils::writeNumber( wdp.pos() ) ); - } - break; + DAVUtils::addOxElement(document, parent, QStringLiteral("recurrence_type"), QStringLiteral("monthly")); + DAVUtils::addOxElement(document, parent, QStringLiteral("interval"), OXUtils::writeNumber(recurrence->frequency())); + DAVUtils::addOxElement(document, parent, QStringLiteral("days"), OXUtils::writeNumber(1 << wdp.day())); + DAVUtils::addOxElement(document, parent, QStringLiteral("day_in_month"), OXUtils::writeNumber(wdp.pos())); + } + break; case KCalCore::Recurrence::rYearlyMonth: - DAVUtils::addOxElement( document, parent, QLatin1String( "recurrence_type" ), QLatin1String( "yearly" ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "interval" ), QLatin1String( "1" ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "day_in_month" ), OXUtils::writeNumber( recurrence->yearDates().first() ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "month" ), OXUtils::writeNumber( recurrence->yearMonths().first() + monthOffset ) ); - break; - case KCalCore::Recurrence::rYearlyPos: - { + DAVUtils::addOxElement(document, parent, QStringLiteral("recurrence_type"), QStringLiteral("yearly")); + DAVUtils::addOxElement(document, parent, QStringLiteral("interval"), QStringLiteral("1")); + DAVUtils::addOxElement(document, parent, QStringLiteral("day_in_month"), OXUtils::writeNumber(recurrence->yearDates().first())); + DAVUtils::addOxElement(document, parent, QStringLiteral("month"), OXUtils::writeNumber(recurrence->yearMonths().first() + monthOffset)); + break; + case KCalCore::Recurrence::rYearlyPos: { const KCalCore::RecurrenceRule::WDayPos wdp = recurrence->monthPositions().first(); - DAVUtils::addOxElement( document, parent, QLatin1String( "recurrence_type" ), QLatin1String( "yearly" ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "interval" ), QLatin1String( "1" ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "days" ), OXUtils::writeNumber( 1 << wdp.day() ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "day_in_month" ), OXUtils::writeNumber( wdp.pos() ) ); - DAVUtils::addOxElement( document, parent, QLatin1String( "month" ), OXUtils::writeNumber( recurrence->yearMonths().first() + monthOffset ) ); - } - break; + DAVUtils::addOxElement(document, parent, QStringLiteral("recurrence_type"), QStringLiteral("yearly")); + DAVUtils::addOxElement(document, parent, QStringLiteral("interval"), QStringLiteral("1")); + DAVUtils::addOxElement(document, parent, QStringLiteral("days"), OXUtils::writeNumber(1 << wdp.day())); + DAVUtils::addOxElement(document, parent, QStringLiteral("day_in_month"), OXUtils::writeNumber(wdp.pos())); + DAVUtils::addOxElement(document, parent, QStringLiteral("month"), OXUtils::writeNumber(recurrence->yearMonths().first() + monthOffset)); + } + break; default: - qDebug() << "unsupported recurrence type:" << recurrence->recurrenceType(); - } + qDebug() << "unsupported recurrence type:" << recurrence->recurrenceType(); + } - if ( recurrence->endDateTime().isValid() ) - DAVUtils::addOxElement( document, parent, QLatin1String( "until" ), OXUtils::writeDateTime( recurrence->endDateTime().dateTime() ) ); - else - DAVUtils::addOxElement( document, parent, QLatin1String( "until" ) ); + if (recurrence->endDateTime().isValid()) { + DAVUtils::addOxElement(document, parent, QStringLiteral("until"), OXUtils::writeDateTime(recurrence->endDateTime().dateTime())); + } else { + DAVUtils::addOxElement(document, parent, QStringLiteral("until")); + } - // delete exceptions - const KCalCore::DateList exceptionList = recurrence->exDates(); + // delete exceptions + const KCalCore::DateList exceptionList = recurrence->exDates(); - QStringList dates; - foreach ( const QDate &date, exceptionList ) - dates.append( OXUtils::writeDate( date ) ); + QStringList dates; + dates.reserve(exceptionList.count()); + foreach (const QDate &date, exceptionList) { + dates.append(OXUtils::writeDate(date)); + } - DAVUtils::addOxElement( document, parent, QLatin1String( "deleteexceptions" ), dates.join( QLatin1String( "," ) ) ); + DAVUtils::addOxElement(document, parent, QStringLiteral("deleteexceptions"), dates.join(QLatin1String(","))); - //TODO: changeexceptions + //TODO: changeexceptions } -void OXA::IncidenceUtils::parseEvent( const QDomElement &propElement, Object &object ) +void OXA::IncidenceUtils::parseEvent(const QDomElement &propElement, Object &object) { - KCalCore::Event::Ptr event( new KCalCore::Event ); + KCalCore::Event::Ptr event(new KCalCore::Event); - const QDomElement fullTimeElement = propElement.firstChildElement( "full_time" ); - if ( !fullTimeElement.isNull() ) - event->setAllDay( OXUtils::readBoolean( fullTimeElement.text() ) ); + const QDomElement fullTimeElement = propElement.firstChildElement("full_time"); + if (!fullTimeElement.isNull()) { + event->setAllDay(OXUtils::readBoolean(fullTimeElement.text())); + } - const QDomElement ShowAsElement = propElement.firstChildElement( "shown_as" ); - if ( !ShowAsElement.isNull() ) { - int showAs = OXUtils::readNumber( ShowAsElement.text() ); - switch (showAs) { - case 1 : event->setTransparency(KCalCore::Event::Transparent); break; - case 4 : event->setTransparency(KCalCore::Event::Opaque); break; - default : event->setTransparency(KCalCore::Event::Opaque); + const QDomElement ShowAsElement = propElement.firstChildElement("shown_as"); + if (!ShowAsElement.isNull()) { + int showAs = OXUtils::readNumber(ShowAsElement.text()); + switch (showAs) { + case 1 : event->setTransparency(KCalCore::Event::Transparent); break; + case 4 : event->setTransparency(KCalCore::Event::Opaque); break; + default : event->setTransparency(KCalCore::Event::Opaque); + } } - } - bool doesRecur = false; - const QDomElement recurrenceTypeElement = propElement.firstChildElement( "recurrence_type" ); - if ( !recurrenceTypeElement.isNull() && recurrenceTypeElement.text() != QLatin1String( "none" ) ) - doesRecur = true; + bool doesRecur = false; + const QDomElement recurrenceTypeElement = propElement.firstChildElement("recurrence_type"); + if (!recurrenceTypeElement.isNull() && recurrenceTypeElement.text() != QLatin1String("none")) { + doesRecur = true; + } - QDomElement element = propElement.firstChildElement(); - while ( !element.isNull() ) { - parseIncidenceAttribute( element, event ); - parseEventAttribute( element, event ); + QDomElement element = propElement.firstChildElement(); + while (!element.isNull()) { + parseIncidenceAttribute(element, event); + parseEventAttribute(element, event); - element = element.nextSiblingElement(); - } + element = element.nextSiblingElement(); + } - if ( doesRecur ) - parseRecurrence( propElement, event ); - else - event->recurrence()->unsetRecurs(); + if (doesRecur) { + parseRecurrence(propElement, event); + } else { + event->recurrence()->unsetRecurs(); + } - object.setEvent( KCalCore::Incidence::Ptr( event ) ); + object.setEvent(KCalCore::Incidence::Ptr(event)); } -void OXA::IncidenceUtils::parseTask( const QDomElement &propElement, Object &object ) +void OXA::IncidenceUtils::parseTask(const QDomElement &propElement, Object &object) { - KCalCore::Todo::Ptr todo( new KCalCore::Todo ); - todo->setSecrecy( KCalCore::Incidence::SecrecyPrivate ); + KCalCore::Todo::Ptr todo(new KCalCore::Todo); + todo->setSecrecy(KCalCore::Incidence::SecrecyPrivate); - bool doesRecur = false; - const QDomElement recurrenceTypeElement = propElement.firstChildElement( "recurrence_type" ); - if ( !recurrenceTypeElement.isNull() && recurrenceTypeElement.text() != QLatin1String( "none" ) ) - doesRecur = true; + bool doesRecur = false; + const QDomElement recurrenceTypeElement = propElement.firstChildElement("recurrence_type"); + if (!recurrenceTypeElement.isNull() && recurrenceTypeElement.text() != QLatin1String("none")) { + doesRecur = true; + } - QDomElement element = propElement.firstChildElement(); - while ( !element.isNull() ) { - parseIncidenceAttribute( element, todo ); - parseTodoAttribute( element, todo ); + QDomElement element = propElement.firstChildElement(); + while (!element.isNull()) { + parseIncidenceAttribute(element, todo); + parseTodoAttribute(element, todo); - element = element.nextSiblingElement(); - } + element = element.nextSiblingElement(); + } - if ( doesRecur ) - parseRecurrence( propElement, todo ); - else - todo->recurrence()->unsetRecurs(); + if (doesRecur) { + parseRecurrence(propElement, todo); + } else { + todo->recurrence()->unsetRecurs(); + } - object.setTask( KCalCore::Incidence::Ptr( todo ) ); + object.setTask(KCalCore::Incidence::Ptr(todo)); } -void OXA::IncidenceUtils::addEventElements( QDomDocument &document, QDomElement &propElement, const Object &object ) +void OXA::IncidenceUtils::addEventElements(QDomDocument &document, QDomElement &propElement, const Object &object) { - createIncidenceAttributes( document, propElement, object.event() ); - createEventAttributes( document, propElement, object.event().staticCast() ); - createRecurrenceAttributes( document, propElement, object.event() ); + createIncidenceAttributes(document, propElement, object.event()); + createEventAttributes(document, propElement, object.event().staticCast()); + createRecurrenceAttributes(document, propElement, object.event()); } -void OXA::IncidenceUtils::addTaskElements( QDomDocument &document, QDomElement &propElement, const Object &object ) +void OXA::IncidenceUtils::addTaskElements(QDomDocument &document, QDomElement &propElement, const Object &object) { - createIncidenceAttributes( document, propElement, object.task() ); - createTaskAttributes( document, propElement, object.task().staticCast() ); - createRecurrenceAttributes( document, propElement, object.task() ); + createIncidenceAttributes(document, propElement, object.task()); + createTaskAttributes(document, propElement, object.task().staticCast()); + createRecurrenceAttributes(document, propElement, object.task()); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/incidenceutils.h kdepim-runtime-15.08.0/resources/openxchange/oxa/incidenceutils.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/incidenceutils.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/incidenceutils.h 2015-08-10 21:01:02.000000000 +0000 @@ -27,32 +27,33 @@ class QDomDocument; class QDomElement; -namespace OXA { +namespace OXA +{ /** * Namespace that contains helper methods for handling events and tasks. */ namespace IncidenceUtils { - /** - * Parses the XML tree under @p propElement and fills the event data of @p object. - */ - void parseEvent( const QDomElement &propElement, Object &object ); - - /** - * Parses the XML tree under @p propElement and fills the task data of @p object. - */ - void parseTask( const QDomElement &propElement, Object &object ); - - /** - * Adds the event data of @p object to the @p document under the @p propElement. - */ - void addEventElements( QDomDocument &document, QDomElement &propElement, const Object &object ); - - /** - * Adds the task data of @p object to the @p document under the @p propElement. - */ - void addTaskElements( QDomDocument &document, QDomElement &propElement, const Object &object ); +/** + * Parses the XML tree under @p propElement and fills the event data of @p object. + */ +void parseEvent(const QDomElement &propElement, Object &object); + +/** + * Parses the XML tree under @p propElement and fills the task data of @p object. + */ +void parseTask(const QDomElement &propElement, Object &object); + +/** + * Adds the event data of @p object to the @p document under the @p propElement. + */ +void addEventElements(QDomDocument &document, QDomElement &propElement, const Object &object); + +/** + * Adds the task data of @p object to the @p document under the @p propElement. + */ +void addTaskElements(QDomDocument &document, QDomElement &propElement, const Object &object); } } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/object.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/object.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/object.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/object.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,100 +24,100 @@ using namespace OXA; Object::Object() - : mObjectStatus( Created ), mObjectId( -1 ), mFolderId( -1 ) + : mObjectStatus(Created), mObjectId(-1), mFolderId(-1) { } -void Object::setObjectStatus( ObjectStatus status ) +void Object::setObjectStatus(ObjectStatus status) { - mObjectStatus = status; + mObjectStatus = status; } Object::ObjectStatus Object::objectStatus() const { - return mObjectStatus; + return mObjectStatus; } -void Object::setObjectId( qlonglong id ) +void Object::setObjectId(qlonglong id) { - mObjectId = id; + mObjectId = id; } qlonglong Object::objectId() const { - return mObjectId; + return mObjectId; } -void Object::setFolderId( qlonglong id ) +void Object::setFolderId(qlonglong id) { - mFolderId = id; + mFolderId = id; } qlonglong Object::folderId() const { - return mFolderId; + return mFolderId; } -void Object::setLastModified( const QString &timeStamp ) +void Object::setLastModified(const QString &timeStamp) { - mLastModified = timeStamp; + mLastModified = timeStamp; } QString Object::lastModified() const { - return mLastModified; + return mLastModified; } -void Object::setModule( Folder::Module module ) +void Object::setModule(Folder::Module module) { - mModule = module; + mModule = module; } Folder::Module Object::module() const { - return mModule; + return mModule; } -void Object::setContact( const KABC::Addressee &contact ) +void Object::setContact(const KContacts::Addressee &contact) { - mModule = Folder::Contacts; - mContact = contact; + mModule = Folder::Contacts; + mContact = contact; } -KABC::Addressee Object::contact() const +KContacts::Addressee Object::contact() const { - return mContact; + return mContact; } -void Object::setContactGroup( const KABC::ContactGroup &group ) +void Object::setContactGroup(const KContacts::ContactGroup &group) { - mModule = Folder::Contacts; - mContactGroup = group; + mModule = Folder::Contacts; + mContactGroup = group; } -KABC::ContactGroup Object::contactGroup() const +KContacts::ContactGroup Object::contactGroup() const { - return mContactGroup; + return mContactGroup; } -void Object::setEvent( const KCalCore::Incidence::Ptr &event ) +void Object::setEvent(const KCalCore::Incidence::Ptr &event) { - mModule = Folder::Calendar; - mEvent = event; + mModule = Folder::Calendar; + mEvent = event; } KCalCore::Incidence::Ptr Object::event() const { - return mEvent; + return mEvent; } -void Object::setTask( const KCalCore::Incidence::Ptr &task ) +void Object::setTask(const KCalCore::Incidence::Ptr &task) { - mModule = Folder::Tasks; - mTask = task; + mModule = Folder::Tasks; + mTask = task; } KCalCore::Incidence::Ptr Object::task() const { - return mTask; + return mTask; } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectcreatejob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/objectcreatejob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectcreatejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectcreatejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -30,90 +30,91 @@ using namespace OXA; -ObjectCreateJob::ObjectCreateJob( const Object &object, QObject *parent ) - : KJob( parent ), mObject( object ) +ObjectCreateJob::ObjectCreateJob(const Object &object, QObject *parent) + : KJob(parent), mObject(object) { } void ObjectCreateJob::start() { - if ( ObjectUtils::needsPreloading( mObject ) ) { - KJob *job = ObjectUtils::preloadJob( mObject ); - connect( job, SIGNAL(result(KJob*)), SLOT(preloadingJobFinished(KJob*)) ); - job->start(); - } else { - QDomDocument document; - QDomElement propertyupdate = DAVUtils::addDavElement( document, document, QLatin1String( "propertyupdate" ) ); - QDomElement set = DAVUtils::addDavElement( document, propertyupdate, QLatin1String( "set" ) ); - QDomElement prop = DAVUtils::addDavElement( document, set, QLatin1String( "prop" ) ); - - ObjectUtils::addObjectElements( document, prop, mObject ); - - const QString path = ObjectUtils::davPath( mObject.module() ); - - KIO::DavJob *job = DavManager::self()->createPatchJob( path, document ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); - } + if (ObjectUtils::needsPreloading(mObject)) { + KJob *job = ObjectUtils::preloadJob(mObject); + connect(job, &KJob::result, this, &ObjectCreateJob::preloadingJobFinished); + job->start(); + } else { + QDomDocument document; + QDomElement propertyupdate = DAVUtils::addDavElement(document, document, QStringLiteral("propertyupdate")); + QDomElement set = DAVUtils::addDavElement(document, propertyupdate, QStringLiteral("set")); + QDomElement prop = DAVUtils::addDavElement(document, set, QStringLiteral("prop")); + + ObjectUtils::addObjectElements(document, prop, mObject); + + const QString path = ObjectUtils::davPath(mObject.module()); + + KIO::DavJob *job = DavManager::self()->createPatchJob(path, document); + connect(job, &KJob::result, this, &ObjectCreateJob::davJobFinished); + } } Object ObjectCreateJob::object() const { - return mObject; + return mObject; } -void ObjectCreateJob::preloadingJobFinished( KJob *job ) +void ObjectCreateJob::preloadingJobFinished(KJob *job) { - void *preloadedData = ObjectUtils::preloadData( mObject, job ); + void *preloadedData = ObjectUtils::preloadData(mObject, job); - QDomDocument document; - QDomElement propertyupdate = DAVUtils::addDavElement( document, document, QLatin1String( "propertyupdate" ) ); - QDomElement set = DAVUtils::addDavElement( document, propertyupdate, QLatin1String( "set" ) ); - QDomElement prop = DAVUtils::addDavElement( document, set, QLatin1String( "prop" ) ); + QDomDocument document; + QDomElement propertyupdate = DAVUtils::addDavElement(document, document, QStringLiteral("propertyupdate")); + QDomElement set = DAVUtils::addDavElement(document, propertyupdate, QStringLiteral("set")); + QDomElement prop = DAVUtils::addDavElement(document, set, QStringLiteral("prop")); - ObjectUtils::addObjectElements( document, prop, mObject, preloadedData ); + ObjectUtils::addObjectElements(document, prop, mObject, preloadedData); - const QString path = ObjectUtils::davPath( mObject.module() ); + const QString path = ObjectUtils::davPath(mObject.module()); - KIO::DavJob *davJob = DavManager::self()->createPatchJob( path, document ); - connect( davJob, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + KIO::DavJob *davJob = DavManager::self()->createPatchJob(path, document); + connect(davJob, &KIO::DavJob::result, this, &ObjectCreateJob::davJobFinished); } -void ObjectCreateJob::davJobFinished( KJob *job ) +void ObjectCreateJob::davJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } - - KIO::DavJob *davJob = qobject_cast( job ); + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } + + KIO::DavJob *davJob = qobject_cast(job); + + const QDomDocument document = davJob->response(); + + QString errorText, errorStatus; + if (DAVUtils::davErrorOccurred(document, errorText, errorStatus)) { + setError(UserDefinedError); + setErrorText(errorText); + emitResult(); + return; + } + + QDomElement multistatus = document.documentElement(); + QDomElement response = multistatus.firstChildElement(QStringLiteral("response")); + const QDomNodeList props = response.elementsByTagName("prop"); + const QDomElement prop = props.at(0).toElement(); + + QDomElement element = prop.firstChildElement(); + while (!element.isNull()) { + if (element.tagName() == QLatin1String("object_id")) { + mObject.setObjectId(OXUtils::readNumber(element.text())); + } else if (element.tagName() == QLatin1String("last_modified")) { + mObject.setLastModified(OXUtils::readString(element.text())); + } - const QDomDocument document = davJob->response(); + element = element.nextSiblingElement(); + } - QString errorText, errorStatus; - if ( DAVUtils::davErrorOccurred( document, errorText, errorStatus ) ) { - setError( UserDefinedError ); - setErrorText( errorText ); emitResult(); - return; - } - - QDomElement multistatus = document.documentElement(); - QDomElement response = multistatus.firstChildElement( QLatin1String( "response" ) ); - const QDomNodeList props = response.elementsByTagName( "prop" ); - const QDomElement prop = props.at( 0 ).toElement(); - - QDomElement element = prop.firstChildElement(); - while ( !element.isNull() ) { - if ( element.tagName() == QLatin1String( "object_id" ) ) - mObject.setObjectId( OXUtils::readNumber( element.text() ) ); - else if ( element.tagName() == QLatin1String( "last_modified" ) ) - mObject.setLastModified( OXUtils::readString( element.text() ) ); - - element = element.nextSiblingElement(); - } - - emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectcreatejob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/objectcreatejob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectcreatejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectcreatejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,24 +26,25 @@ #include "object.h" -namespace OXA { +namespace OXA +{ class ObjectCreateJob : public KJob { - Q_OBJECT + Q_OBJECT - public: - explicit ObjectCreateJob( const Object &object, QObject *parent = 0 ); +public: + explicit ObjectCreateJob(const Object &object, QObject *parent = Q_NULLPTR); - virtual void start(); + void start() Q_DECL_OVERRIDE; Object object() const; - private Q_SLOTS: - void preloadingJobFinished( KJob* ); - void davJobFinished( KJob* ); +private Q_SLOTS: + void preloadingJobFinished(KJob *); + void davJobFinished(KJob *); - private: +private: Object mObject; }; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectdeletejob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/objectdeletejob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectdeletejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectdeletejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -30,49 +30,49 @@ using namespace OXA; -ObjectDeleteJob::ObjectDeleteJob( const Object &object, QObject *parent ) - : KJob( parent ), mObject( object ) +ObjectDeleteJob::ObjectDeleteJob(const Object &object, QObject *parent) + : KJob(parent), mObject(object) { } void ObjectDeleteJob::start() { - QDomDocument document; - QDomElement propertyupdate = DAVUtils::addDavElement( document, document, QLatin1String( "propertyupdate" ) ); - QDomElement set = DAVUtils::addDavElement( document, propertyupdate, QLatin1String( "set" ) ); - QDomElement prop = DAVUtils::addDavElement( document, set, QLatin1String( "prop" ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "object_id" ), OXUtils::writeNumber( mObject.objectId() ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "folder_id" ), OXUtils::writeNumber( mObject.folderId() ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "method" ), OXUtils::writeString( QLatin1String( "DELETE" ) ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "last_modified" ), OXUtils::writeString( mObject.lastModified() ) ); + QDomDocument document; + QDomElement propertyupdate = DAVUtils::addDavElement(document, document, QStringLiteral("propertyupdate")); + QDomElement set = DAVUtils::addDavElement(document, propertyupdate, QStringLiteral("set")); + QDomElement prop = DAVUtils::addDavElement(document, set, QStringLiteral("prop")); + DAVUtils::addOxElement(document, prop, QStringLiteral("object_id"), OXUtils::writeNumber(mObject.objectId())); + DAVUtils::addOxElement(document, prop, QStringLiteral("folder_id"), OXUtils::writeNumber(mObject.folderId())); + DAVUtils::addOxElement(document, prop, QStringLiteral("method"), OXUtils::writeString(QStringLiteral("DELETE"))); + DAVUtils::addOxElement(document, prop, QStringLiteral("last_modified"), OXUtils::writeString(mObject.lastModified())); - const QString path = ObjectUtils::davPath( mObject.module() ); + const QString path = ObjectUtils::davPath(mObject.module()); - KIO::DavJob *job = DavManager::self()->createPatchJob( path, document ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + KIO::DavJob *job = DavManager::self()->createPatchJob(path, document); + connect(job, &KIO::DavJob::result, this, &ObjectDeleteJob::davJobFinished); } -void ObjectDeleteJob::davJobFinished( KJob *job ) +void ObjectDeleteJob::davJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } - - KIO::DavJob *davJob = qobject_cast( job ); + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } + + KIO::DavJob *davJob = qobject_cast(job); + + const QDomDocument document = davJob->response(); + + QString errorText, errorStatus; + if (DAVUtils::davErrorOccurred(document, errorText, errorStatus)) { + setError(UserDefinedError); + setErrorText(errorText); + emitResult(); + return; + } - const QDomDocument document = davJob->response(); - - QString errorText, errorStatus; - if ( DAVUtils::davErrorOccurred( document, errorText, errorStatus ) ) { - setError( UserDefinedError ); - setErrorText( errorText ); emitResult(); - return; - } - - emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectdeletejob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/objectdeletejob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectdeletejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectdeletejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,21 +26,22 @@ #include -namespace OXA { +namespace OXA +{ class ObjectDeleteJob : public KJob { - Q_OBJECT + Q_OBJECT - public: - explicit ObjectDeleteJob( const Object &object, QObject *parent = 0 ); +public: + explicit ObjectDeleteJob(const Object &object, QObject *parent = Q_NULLPTR); - virtual void start(); + void start() Q_DECL_OVERRIDE; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: Object mObject; }; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/object.h kdepim-runtime-15.08.0/resources/openxchange/oxa/object.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/object.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/object.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,73 +24,74 @@ #include "folder.h" -#include -#include -#include +#include +#include +#include -#include +#include #include -namespace OXA { +namespace OXA +{ class Object { - public: +public: /** * Describes a list of objects. */ - typedef QList List; + typedef QVector List; /** * Describes the status of the object. */ - enum ObjectStatus - { - Created, ///< The object has been created or modified. - Deleted ///< The object has been deleted. + enum ObjectStatus { + Created, ///< The object has been created or modified. + Deleted ///< The object has been deleted. }; Object(); - void setObjectStatus( ObjectStatus status ); + void setObjectStatus(ObjectStatus status); ObjectStatus objectStatus() const; - void setObjectId( qlonglong id ); + void setObjectId(qlonglong id); qlonglong objectId() const; - void setFolderId( qlonglong id ); + void setFolderId(qlonglong id); qlonglong folderId() const; - void setLastModified( const QString &timeStamp ); + void setLastModified(const QString &timeStamp); QString lastModified() const; - void setModule( Folder::Module module ); + void setModule(Folder::Module module); Folder::Module module() const; - void setContact( const KABC::Addressee &contact ); - KABC::Addressee contact() const; + void setContact(const KContacts::Addressee &contact); + KContacts::Addressee contact() const; - void setContactGroup( const KABC::ContactGroup &group ); - KABC::ContactGroup contactGroup() const; + void setContactGroup(const KContacts::ContactGroup &group); + KContacts::ContactGroup contactGroup() const; - void setEvent( const KCalCore::Incidence::Ptr &event ); + void setEvent(const KCalCore::Incidence::Ptr &event); KCalCore::Incidence::Ptr event() const; - void setTask( const KCalCore::Incidence::Ptr &task ); + void setTask(const KCalCore::Incidence::Ptr &task); KCalCore::Incidence::Ptr task() const; - private: +private: ObjectStatus mObjectStatus; qlonglong mObjectId; qlonglong mFolderId; QString mLastModified; Folder::Module mModule; - KABC::Addressee mContact; - KABC::ContactGroup mContactGroup; + KContacts::Addressee mContact; + KContacts::ContactGroup mContactGroup; KCalCore::Incidence::Ptr mEvent; KCalCore::Incidence::Ptr mTask; }; - } +Q_DECLARE_TYPEINFO( OXA::Object, Q_MOVABLE_TYPE ); + #endif diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectmodifyjob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/objectmodifyjob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectmodifyjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectmodifyjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -30,88 +30,89 @@ using namespace OXA; -ObjectModifyJob::ObjectModifyJob( const Object &object, QObject *parent ) - : KJob( parent ), mObject( object ) +ObjectModifyJob::ObjectModifyJob(const Object &object, QObject *parent) + : KJob(parent), mObject(object) { } void ObjectModifyJob::start() { - if ( ObjectUtils::needsPreloading( mObject ) ) { - KJob *job = ObjectUtils::preloadJob( mObject ); - connect( job, SIGNAL(result(KJob*)), SLOT(preloadingJobFinished(KJob*)) ); - job->start(); - } else { - QDomDocument document; - QDomElement propertyupdate = DAVUtils::addDavElement( document, document, QLatin1String( "propertyupdate" ) ); - QDomElement set = DAVUtils::addDavElement( document, propertyupdate, QLatin1String( "set" ) ); - QDomElement prop = DAVUtils::addDavElement( document, set, QLatin1String( "prop" ) ); - - ObjectUtils::addObjectElements( document, prop, mObject ); - - const QString path = ObjectUtils::davPath( mObject.module() ); - - KIO::DavJob *job = DavManager::self()->createPatchJob( path, document ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); - } + if (ObjectUtils::needsPreloading(mObject)) { + KJob *job = ObjectUtils::preloadJob(mObject); + connect(job, &KJob::result, this, &ObjectModifyJob::preloadingJobFinished); + job->start(); + } else { + QDomDocument document; + QDomElement propertyupdate = DAVUtils::addDavElement(document, document, QStringLiteral("propertyupdate")); + QDomElement set = DAVUtils::addDavElement(document, propertyupdate, QStringLiteral("set")); + QDomElement prop = DAVUtils::addDavElement(document, set, QStringLiteral("prop")); + + ObjectUtils::addObjectElements(document, prop, mObject); + + const QString path = ObjectUtils::davPath(mObject.module()); + + KIO::DavJob *job = DavManager::self()->createPatchJob(path, document); + connect(job, &KJob::result, this, &ObjectModifyJob::davJobFinished); + } } Object ObjectModifyJob::object() const { - return mObject; + return mObject; } -void ObjectModifyJob::preloadingJobFinished( KJob *job ) +void ObjectModifyJob::preloadingJobFinished(KJob *job) { - void *preloadedData = ObjectUtils::preloadData( mObject, job ); + void *preloadedData = ObjectUtils::preloadData(mObject, job); - QDomDocument document; - QDomElement propertyupdate = DAVUtils::addDavElement( document, document, QLatin1String( "propertyupdate" ) ); - QDomElement set = DAVUtils::addDavElement( document, propertyupdate, QLatin1String( "set" ) ); - QDomElement prop = DAVUtils::addDavElement( document, set, QLatin1String( "prop" ) ); + QDomDocument document; + QDomElement propertyupdate = DAVUtils::addDavElement(document, document, QStringLiteral("propertyupdate")); + QDomElement set = DAVUtils::addDavElement(document, propertyupdate, QStringLiteral("set")); + QDomElement prop = DAVUtils::addDavElement(document, set, QStringLiteral("prop")); - ObjectUtils::addObjectElements( document, prop, mObject, preloadedData ); + ObjectUtils::addObjectElements(document, prop, mObject, preloadedData); - const QString path = ObjectUtils::davPath( mObject.module() ); + const QString path = ObjectUtils::davPath(mObject.module()); - KIO::DavJob *davJob = DavManager::self()->createPatchJob( path, document ); - connect( davJob, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + KIO::DavJob *davJob = DavManager::self()->createPatchJob(path, document); + connect(davJob, &KIO::DavJob::result, this, &ObjectModifyJob::davJobFinished); } -void ObjectModifyJob::davJobFinished( KJob *job ) +void ObjectModifyJob::davJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } - - KIO::DavJob *davJob = qobject_cast( job ); + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } + + KIO::DavJob *davJob = qobject_cast(job); + + const QDomDocument document = davJob->response(); + + QString errorText, errorStatus; + if (DAVUtils::davErrorOccurred(document, errorText, errorStatus)) { + setError(UserDefinedError); + setErrorText(errorText); + emitResult(); + return; + } + + QDomElement multistatus = document.documentElement(); + QDomElement response = multistatus.firstChildElement(QStringLiteral("response")); + const QDomNodeList props = response.elementsByTagName("prop"); + const QDomElement prop = props.at(0).toElement(); + + QDomElement element = prop.firstChildElement(); + while (!element.isNull()) { + if (element.tagName() == QLatin1String("last_modified")) { + mObject.setLastModified(OXUtils::readString(element.text())); + } - const QDomDocument document = davJob->response(); + element = element.nextSiblingElement(); + } - QString errorText, errorStatus; - if ( DAVUtils::davErrorOccurred( document, errorText, errorStatus ) ) { - setError( UserDefinedError ); - setErrorText( errorText ); emitResult(); - return; - } - - QDomElement multistatus = document.documentElement(); - QDomElement response = multistatus.firstChildElement( QLatin1String( "response" ) ); - const QDomNodeList props = response.elementsByTagName( "prop" ); - const QDomElement prop = props.at( 0 ).toElement(); - - QDomElement element = prop.firstChildElement(); - while ( !element.isNull() ) { - if ( element.tagName() == QLatin1String( "last_modified" ) ) - mObject.setLastModified( OXUtils::readString( element.text() ) ); - - element = element.nextSiblingElement(); - } - - emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectmodifyjob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/objectmodifyjob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectmodifyjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectmodifyjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,24 +26,25 @@ #include "object.h" -namespace OXA { +namespace OXA +{ class ObjectModifyJob : public KJob { - Q_OBJECT + Q_OBJECT - public: - explicit ObjectModifyJob( const Object &object, QObject *parent = 0 ); +public: + explicit ObjectModifyJob(const Object &object, QObject *parent = Q_NULLPTR); - virtual void start(); + void start() Q_DECL_OVERRIDE; Object object() const; - private Q_SLOTS: - void preloadingJobFinished( KJob* ); - void davJobFinished( KJob* ); +private Q_SLOTS: + void preloadingJobFinished(KJob *); + void davJobFinished(KJob *); - private: +private: Object mObject; }; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectmovejob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/objectmovejob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectmovejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectmovejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -30,67 +30,68 @@ using namespace OXA; -ObjectMoveJob::ObjectMoveJob( const Object &object, const Folder &destinationFolder, QObject *parent ) - : KJob( parent ), mObject( object ), mDestinationFolder( destinationFolder ) +ObjectMoveJob::ObjectMoveJob(const Object &object, const Folder &destinationFolder, QObject *parent) + : KJob(parent), mObject(object), mDestinationFolder(destinationFolder) { } void ObjectMoveJob::start() { - QDomDocument document; - QDomElement propertyupdate = DAVUtils::addDavElement( document, document, QLatin1String( "propertyupdate" ) ); - QDomElement set = DAVUtils::addDavElement( document, propertyupdate, QLatin1String( "set" ) ); - QDomElement prop = DAVUtils::addDavElement( document, set, QLatin1String( "prop" ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "object_id" ), OXUtils::writeNumber( mObject.objectId() ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "folder_id" ), OXUtils::writeNumber( mObject.folderId() ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "last_modified" ), OXUtils::writeString( mObject.lastModified() ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "folder" ), OXUtils::writeNumber( mDestinationFolder.objectId() ) ); + QDomDocument document; + QDomElement propertyupdate = DAVUtils::addDavElement(document, document, QStringLiteral("propertyupdate")); + QDomElement set = DAVUtils::addDavElement(document, propertyupdate, QStringLiteral("set")); + QDomElement prop = DAVUtils::addDavElement(document, set, QStringLiteral("prop")); + DAVUtils::addOxElement(document, prop, QStringLiteral("object_id"), OXUtils::writeNumber(mObject.objectId())); + DAVUtils::addOxElement(document, prop, QStringLiteral("folder_id"), OXUtils::writeNumber(mObject.folderId())); + DAVUtils::addOxElement(document, prop, QStringLiteral("last_modified"), OXUtils::writeString(mObject.lastModified())); + DAVUtils::addOxElement(document, prop, QStringLiteral("folder"), OXUtils::writeNumber(mDestinationFolder.objectId())); - const QString path = ObjectUtils::davPath( mObject.module() ); + const QString path = ObjectUtils::davPath(mObject.module()); - KIO::DavJob *job = DavManager::self()->createPatchJob( path, document ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + KIO::DavJob *job = DavManager::self()->createPatchJob(path, document); + connect(job, &KIO::DavJob::result, this, &ObjectMoveJob::davJobFinished); } Object ObjectMoveJob::object() const { - return mObject; + return mObject; } -void ObjectMoveJob::davJobFinished( KJob *job ) +void ObjectMoveJob::davJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } - - KIO::DavJob *davJob = qobject_cast( job ); + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } + + KIO::DavJob *davJob = qobject_cast(job); + + const QDomDocument document = davJob->response(); + + QString errorText, errorStatus; + if (DAVUtils::davErrorOccurred(document, errorText, errorStatus)) { + setError(UserDefinedError); + setErrorText(errorText); + emitResult(); + return; + } + + QDomElement multistatus = document.documentElement(); + QDomElement response = multistatus.firstChildElement(QStringLiteral("response")); + const QDomNodeList props = response.elementsByTagName("prop"); + const QDomElement prop = props.at(0).toElement(); + + QDomElement element = prop.firstChildElement(); + while (!element.isNull()) { + if (element.tagName() == QLatin1String("last_modified")) { + mObject.setLastModified(OXUtils::readString(element.text())); + } - const QDomDocument document = davJob->response(); + element = element.nextSiblingElement(); + } - QString errorText, errorStatus; - if ( DAVUtils::davErrorOccurred( document, errorText, errorStatus ) ) { - setError( UserDefinedError ); - setErrorText( errorText ); emitResult(); - return; - } - - QDomElement multistatus = document.documentElement(); - QDomElement response = multistatus.firstChildElement( QLatin1String( "response" ) ); - const QDomNodeList props = response.elementsByTagName( "prop" ); - const QDomElement prop = props.at( 0 ).toElement(); - - QDomElement element = prop.firstChildElement(); - while ( !element.isNull() ) { - if ( element.tagName() == QLatin1String( "last_modified" ) ) - mObject.setLastModified( OXUtils::readString( element.text() ) ); - - element = element.nextSiblingElement(); - } - - emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectmovejob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/objectmovejob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectmovejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectmovejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -27,23 +27,24 @@ #include "folder.h" #include "object.h" -namespace OXA { +namespace OXA +{ class ObjectMoveJob : public KJob { - Q_OBJECT + Q_OBJECT - public: - ObjectMoveJob( const Object &object, const Folder &destinationFolder, QObject *parent = 0 ); +public: + ObjectMoveJob(const Object &object, const Folder &destinationFolder, QObject *parent = Q_NULLPTR); - virtual void start(); + void start() Q_DECL_OVERRIDE; Object object() const; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: Object mObject; Folder mDestinationFolder; }; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectrequestjob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/objectrequestjob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectrequestjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectrequestjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -30,56 +30,56 @@ using namespace OXA; -ObjectRequestJob::ObjectRequestJob( const Object &object, QObject *parent ) - : KJob( parent ), mObject( object ) +ObjectRequestJob::ObjectRequestJob(const Object &object, QObject *parent) + : KJob(parent), mObject(object) { } void ObjectRequestJob::start() { - QDomDocument document; - QDomElement multistatus = DAVUtils::addDavElement( document, document, QLatin1String( "multistatus" ) ); - QDomElement prop = DAVUtils::addDavElement( document, multistatus, QLatin1String( "prop" ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "object_id" ), OXUtils::writeNumber( mObject.objectId() ) ); + QDomDocument document; + QDomElement multistatus = DAVUtils::addDavElement(document, document, QStringLiteral("multistatus")); + QDomElement prop = DAVUtils::addDavElement(document, multistatus, QStringLiteral("prop")); + DAVUtils::addOxElement(document, prop, QStringLiteral("object_id"), OXUtils::writeNumber(mObject.objectId())); - const QString path = ObjectUtils::davPath( mObject.module() ); + const QString path = ObjectUtils::davPath(mObject.module()); - KIO::DavJob *job = DavManager::self()->createFindJob( path, document ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + KIO::DavJob *job = DavManager::self()->createFindJob(path, document); + connect(job, &KIO::DavJob::result, this, &ObjectRequestJob::davJobFinished); } Object ObjectRequestJob::object() const { - return mObject; + return mObject; } -void ObjectRequestJob::davJobFinished( KJob *job ) +void ObjectRequestJob::davJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } - - KIO::DavJob *davJob = qobject_cast( job ); - - const QDomDocument document = davJob->response(); + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } + + KIO::DavJob *davJob = qobject_cast(job); + + const QDomDocument document = davJob->response(); + + QString errorText, errorStatus; + if (DAVUtils::davErrorOccurred(document, errorText, errorStatus)) { + setError(UserDefinedError); + setErrorText(errorText); + emitResult(); + return; + } + + QDomElement multistatus = document.documentElement(); + QDomElement response = multistatus.firstChildElement(QStringLiteral("response")); + const QDomNodeList props = response.elementsByTagName("prop"); + const QDomElement prop = props.at(0).toElement(); + mObject = ObjectUtils::parseObject(prop, mObject.module()); - QString errorText, errorStatus; - if ( DAVUtils::davErrorOccurred( document, errorText, errorStatus ) ) { - setError( UserDefinedError ); - setErrorText( errorText ); emitResult(); - return; - } - - QDomElement multistatus = document.documentElement(); - QDomElement response = multistatus.firstChildElement( QLatin1String( "response" ) ); - const QDomNodeList props = response.elementsByTagName( "prop" ); - const QDomElement prop = props.at( 0 ).toElement(); - mObject = ObjectUtils::parseObject( prop, mObject.module() ); - - emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectrequestjob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/objectrequestjob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectrequestjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectrequestjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,23 +26,24 @@ #include "object.h" -namespace OXA { +namespace OXA +{ class ObjectRequestJob : public KJob { - Q_OBJECT + Q_OBJECT - public: - explicit ObjectRequestJob( const Object &object, QObject *parent = 0 ); +public: + explicit ObjectRequestJob(const Object &object, QObject *parent = Q_NULLPTR); - virtual void start(); + void start() Q_DECL_OVERRIDE; Object object() const; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: Object mObject; }; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectsrequestdeltajob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/objectsrequestdeltajob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectsrequestdeltajob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectsrequestdeltajob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -27,67 +27,69 @@ using namespace OXA; -ObjectsRequestDeltaJob::ObjectsRequestDeltaJob( const Folder &folder, qulonglong lastSync, QObject *parent ) - : KJob( parent ), mFolder( folder ), mLastSync( lastSync ), mJobFinishedCount( 0 ) +ObjectsRequestDeltaJob::ObjectsRequestDeltaJob(const Folder &folder, qulonglong lastSync, QObject *parent) + : KJob(parent), mFolder(folder), mLastSync(lastSync), mJobFinishedCount(0) { } void ObjectsRequestDeltaJob::start() { - ObjectsRequestJob *modifiedJob = new ObjectsRequestJob( mFolder, mLastSync, ObjectsRequestJob::Modified, this ); - connect( modifiedJob, SIGNAL(result(KJob*)), SLOT(fetchModifiedJobFinished(KJob*)) ); - modifiedJob->start(); - - ObjectsRequestJob *deletedJob = new ObjectsRequestJob( mFolder, mLastSync, ObjectsRequestJob::Deleted, this ); - connect( deletedJob, SIGNAL(result(KJob*)), SLOT(fetchDeletedJobFinished(KJob*)) ); - deletedJob->start(); + ObjectsRequestJob *modifiedJob = new ObjectsRequestJob(mFolder, mLastSync, ObjectsRequestJob::Modified, this); + connect(modifiedJob, &ObjectsRequestJob::result, this, &ObjectsRequestDeltaJob::fetchModifiedJobFinished); + modifiedJob->start(); + + ObjectsRequestJob *deletedJob = new ObjectsRequestJob(mFolder, mLastSync, ObjectsRequestJob::Deleted, this); + connect(deletedJob, &ObjectsRequestJob::result, this, &ObjectsRequestDeltaJob::fetchDeletedJobFinished); + deletedJob->start(); } Object::List ObjectsRequestDeltaJob::modifiedObjects() const { - return mModifiedObjects; + return mModifiedObjects; } Object::List ObjectsRequestDeltaJob::deletedObjects() const { - return mDeletedObjects; + return mDeletedObjects; } -void ObjectsRequestDeltaJob::fetchModifiedJobFinished( KJob *job ) +void ObjectsRequestDeltaJob::fetchModifiedJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } - const ObjectsRequestJob *requestJob = qobject_cast( job ); + const ObjectsRequestJob *requestJob = qobject_cast(job); - mModifiedObjects << requestJob->objects(); + mModifiedObjects << requestJob->objects(); - mJobFinishedCount++; + mJobFinishedCount++; - if ( mJobFinishedCount == 2 ) - emitResult(); + if (mJobFinishedCount == 2) { + emitResult(); + } } -void ObjectsRequestDeltaJob::fetchDeletedJobFinished( KJob *job ) +void ObjectsRequestDeltaJob::fetchDeletedJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } - const ObjectsRequestJob *requestJob = qobject_cast( job ); + const ObjectsRequestJob *requestJob = qobject_cast(job); - mDeletedObjects << requestJob->objects(); + mDeletedObjects << requestJob->objects(); - mJobFinishedCount++; + mJobFinishedCount++; - if ( mJobFinishedCount == 2 ) - emitResult(); + if (mJobFinishedCount == 2) { + emitResult(); + } } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectsrequestdeltajob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/objectsrequestdeltajob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectsrequestdeltajob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectsrequestdeltajob.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,7 +26,8 @@ #include "object.h" -namespace OXA { +namespace OXA +{ /** * @short A job that requests the delta for objects changes from the OX server. @@ -35,9 +36,9 @@ */ class ObjectsRequestDeltaJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Creates a new objects request delta job. * @@ -46,12 +47,12 @@ * after this date will be requested. 0 will request all available objects. * @param parent The parent object. */ - ObjectsRequestDeltaJob( const Folder &folder, qulonglong lastSync, QObject *parent = 0 ); + ObjectsRequestDeltaJob(const Folder &folder, qulonglong lastSync, QObject *parent = Q_NULLPTR); /** * Starts the job. */ - virtual void start(); + void start() Q_DECL_OVERRIDE; /** * Returns the list of all added and modified objects. @@ -63,11 +64,11 @@ */ Object::List deletedObjects() const; - private Q_SLOTS: - void fetchModifiedJobFinished( KJob* ); - void fetchDeletedJobFinished( KJob* ); +private Q_SLOTS: + void fetchModifiedJobFinished(KJob *); + void fetchDeletedJobFinished(KJob *); - private: +private: Folder mFolder; qulonglong mLastSync; Object::List mModifiedObjects; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectsrequestjob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/objectsrequestjob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectsrequestjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectsrequestjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -32,64 +32,65 @@ using namespace OXA; -ObjectsRequestJob::ObjectsRequestJob( const Folder &folder, qulonglong lastSync, Mode mode, QObject *parent ) - : KJob( parent ), mFolder( folder ), mLastSync( lastSync ), mMode( mode ) +ObjectsRequestJob::ObjectsRequestJob(const Folder &folder, qulonglong lastSync, Mode mode, QObject *parent) + : KJob(parent), mFolder(folder), mLastSync(lastSync), mMode(mode) { } void ObjectsRequestJob::start() { - QDomDocument document; - QDomElement multistatus = DAVUtils::addDavElement( document, document, QLatin1String( "multistatus" ) ); - QDomElement prop = DAVUtils::addDavElement( document, multistatus, QLatin1String( "prop" ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "folder_id" ), OXUtils::writeNumber( mFolder.objectId() ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "lastsync" ), OXUtils::writeNumber( mLastSync ) ); - if ( mMode == Modified ) - DAVUtils::addOxElement( document, prop, QLatin1String( "objectmode" ), QLatin1String( "MODIFIED" ) ); - else - DAVUtils::addOxElement( document, prop, QLatin1String( "objectmode" ), QLatin1String( "DELETED" ) ); + QDomDocument document; + QDomElement multistatus = DAVUtils::addDavElement(document, document, QStringLiteral("multistatus")); + QDomElement prop = DAVUtils::addDavElement(document, multistatus, QStringLiteral("prop")); + DAVUtils::addOxElement(document, prop, QStringLiteral("folder_id"), OXUtils::writeNumber(mFolder.objectId())); + DAVUtils::addOxElement(document, prop, QStringLiteral("lastsync"), OXUtils::writeNumber(mLastSync)); + if (mMode == Modified) { + DAVUtils::addOxElement(document, prop, QStringLiteral("objectmode"), QStringLiteral("MODIFIED")); + } else { + DAVUtils::addOxElement(document, prop, QStringLiteral("objectmode"), QStringLiteral("DELETED")); + } - const QString path = ObjectUtils::davPath( mFolder.module() ); + const QString path = ObjectUtils::davPath(mFolder.module()); - KIO::DavJob *job = DavManager::self()->createFindJob( path, document ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + KIO::DavJob *job = DavManager::self()->createFindJob(path, document); + connect(job, &KIO::DavJob::result, this, &ObjectsRequestJob::davJobFinished); } Object::List ObjectsRequestJob::objects() const { - return mObjects; + return mObjects; } -void ObjectsRequestJob::davJobFinished( KJob *job ) +void ObjectsRequestJob::davJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } - - KIO::DavJob *davJob = qobject_cast( job ); - - const QDomDocument document = davJob->response(); + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } + + KIO::DavJob *davJob = qobject_cast(job); + + const QDomDocument document = davJob->response(); + + QString errorText, errorStatus; + if (DAVUtils::davErrorOccurred(document, errorText, errorStatus)) { + setError(UserDefinedError); + setErrorText(errorText); + emitResult(); + return; + } + + QDomElement multistatus = document.documentElement(); + QDomElement response = multistatus.firstChildElement(QStringLiteral("response")); + while (!response.isNull()) { + const QDomNodeList props = response.elementsByTagName("prop"); + const QDomElement prop = props.at(0).toElement(); + mObjects.append(ObjectUtils::parseObject(prop, mFolder.module())); + response = response.nextSiblingElement(); + } - QString errorText, errorStatus; - if ( DAVUtils::davErrorOccurred( document, errorText, errorStatus ) ) { - setError( UserDefinedError ); - setErrorText( errorText ); emitResult(); - return; - } - - QDomElement multistatus = document.documentElement(); - QDomElement response = multistatus.firstChildElement( QLatin1String( "response" ) ); - while ( !response.isNull() ) { - const QDomNodeList props = response.elementsByTagName( "prop" ); - const QDomElement prop = props.at( 0 ).toElement(); - mObjects.append( ObjectUtils::parseObject( prop, mFolder.module() ) ); - response = response.nextSiblingElement(); - } - - emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectsrequestjob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/objectsrequestjob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectsrequestjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectsrequestjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -27,20 +27,20 @@ #include "folder.h" #include "object.h" -namespace OXA { +namespace OXA +{ class ObjectsRequestJob : public KJob { - Q_OBJECT + Q_OBJECT - public: +public: /** * Describes the mode of the request job. */ - enum Mode - { - Modified, ///< Fetches all new and modified objects - Deleted ///< Fetches all deleted objects + enum Mode { + Modified, ///< Fetches all new and modified objects + Deleted ///< Fetches all deleted objects }; /** @@ -52,16 +52,16 @@ * @param mode The mode of objects to request. * @param parent The parent object. */ - explicit ObjectsRequestJob( const Folder &folder, qulonglong lastSync = 0, Mode mode = Modified, QObject *parent = 0 ); + explicit ObjectsRequestJob(const Folder &folder, qulonglong lastSync = 0, Mode mode = Modified, QObject *parent = Q_NULLPTR); - virtual void start(); + void start() Q_DECL_OVERRIDE; Object::List objects() const; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: Folder mFolder; qulonglong mLastSync; Mode mMode; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectutils.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/objectutils.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectutils.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectutils.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -31,98 +31,103 @@ using namespace OXA; -Object OXA::ObjectUtils::parseObject( const QDomElement &propElement, Folder::Module module ) +Object OXA::ObjectUtils::parseObject(const QDomElement &propElement, Folder::Module module) { - Object object; + Object object; - QDomElement element = propElement.firstChildElement(); - while ( !element.isNull() ) { - if ( element.tagName() == QLatin1String( "last_modified" ) ) { - object.setLastModified( OXUtils::readString( element.text() ) ); - } else if ( element.tagName() == QLatin1String( "object_id" ) ) { - object.setObjectId( OXUtils::readNumber( element.text() ) ); - } else if ( element.tagName() == QLatin1String( "folder_id" ) ) { - object.setFolderId( OXUtils::readNumber( element.text() ) ); - } else if ( element.tagName() == QLatin1String( "object_status" ) ) { - const QString content = OXUtils::readString( element.text() ); - if ( content == QLatin1String( "CREATE" ) ) - object.setObjectStatus( Object::Created ); - else if ( content == QLatin1String( "DELETE" ) ) - object.setObjectStatus( Object::Deleted ); - else - Q_ASSERT( false ); - } + QDomElement element = propElement.firstChildElement(); + while (!element.isNull()) { + if (element.tagName() == QLatin1String("last_modified")) { + object.setLastModified(OXUtils::readString(element.text())); + } else if (element.tagName() == QLatin1String("object_id")) { + object.setObjectId(OXUtils::readNumber(element.text())); + } else if (element.tagName() == QLatin1String("folder_id")) { + object.setFolderId(OXUtils::readNumber(element.text())); + } else if (element.tagName() == QLatin1String("object_status")) { + const QString content = OXUtils::readString(element.text()); + if (content == QLatin1String("CREATE")) { + object.setObjectStatus(Object::Created); + } else if (content == QLatin1String("DELETE")) { + object.setObjectStatus(Object::Deleted); + } else { + Q_ASSERT(false); + } + } - element = element.nextSiblingElement(); - } + element = element.nextSiblingElement(); + } - switch ( module ) { - case Folder::Contacts: ContactUtils::parseContact( propElement, object ); break; - case Folder::Calendar: IncidenceUtils::parseEvent( propElement, object ); break; - case Folder::Tasks: IncidenceUtils::parseTask( propElement, object ); break; - case Folder::Unbound: Q_ASSERT( false ); break; - } + switch (module) { + case Folder::Contacts: ContactUtils::parseContact(propElement, object); break; + case Folder::Calendar: IncidenceUtils::parseEvent(propElement, object); break; + case Folder::Tasks: IncidenceUtils::parseTask(propElement, object); break; + case Folder::Unbound: Q_ASSERT(false); break; + } - return object; + return object; } -void OXA::ObjectUtils::addObjectElements( QDomDocument &document, QDomElement &propElement, const Object &object, void *preloadedData ) +void OXA::ObjectUtils::addObjectElements(QDomDocument &document, QDomElement &propElement, const Object &object, void *preloadedData) { - if ( object.objectId() != -1 ) - DAVUtils::addOxElement( document, propElement, QLatin1String( "object_id" ), OXUtils::writeNumber( object.objectId() ) ); - if ( object.folderId() != -1 ) - DAVUtils::addOxElement( document, propElement, QLatin1String( "folder_id" ), OXUtils::writeNumber( object.folderId() ) ); - if ( !object.lastModified().isEmpty() ) - DAVUtils::addOxElement( document, propElement, QLatin1String( "last_modified" ), OXUtils::writeString( object.lastModified() ) ); + if (object.objectId() != -1) { + DAVUtils::addOxElement(document, propElement, QStringLiteral("object_id"), OXUtils::writeNumber(object.objectId())); + } + if (object.folderId() != -1) { + DAVUtils::addOxElement(document, propElement, QStringLiteral("folder_id"), OXUtils::writeNumber(object.folderId())); + } + if (!object.lastModified().isEmpty()) { + DAVUtils::addOxElement(document, propElement, QStringLiteral("last_modified"), OXUtils::writeString(object.lastModified())); + } - switch ( object.module() ) { - case Folder::Contacts: ContactUtils::addContactElements( document, propElement, object, preloadedData ); break; - case Folder::Calendar: IncidenceUtils::addEventElements( document, propElement, object ); break; - case Folder::Tasks: IncidenceUtils::addTaskElements( document, propElement, object ); break; - case Folder::Unbound: Q_ASSERT( false ); break; - } + switch (object.module()) { + case Folder::Contacts: ContactUtils::addContactElements(document, propElement, object, preloadedData); break; + case Folder::Calendar: IncidenceUtils::addEventElements(document, propElement, object); break; + case Folder::Tasks: IncidenceUtils::addTaskElements(document, propElement, object); break; + case Folder::Unbound: Q_ASSERT(false); break; + } } -bool OXA::ObjectUtils::needsPreloading( const Object &object ) +bool OXA::ObjectUtils::needsPreloading(const Object &object) { - if ( object.module() == Folder::Contacts ) { - if ( object.contactGroup().contactReferenceCount() != 0 ) // we have to resolve these entries first - return true; - } + if (object.module() == Folder::Contacts) { + if (object.contactGroup().contactReferenceCount() != 0) { // we have to resolve these entries first + return true; + } + } - return false; + return false; } -KJob* OXA::ObjectUtils::preloadJob( const Object &object ) +KJob *OXA::ObjectUtils::preloadJob(const Object &object) { - if ( object.module() == Folder::Contacts ) { - if ( object.contactGroup().contactReferenceCount() != 0 ) { - return ContactUtils::preloadJob( object ); + if (object.module() == Folder::Contacts) { + if (object.contactGroup().contactReferenceCount() != 0) { + return ContactUtils::preloadJob(object); + } } - } - return 0; + return Q_NULLPTR; } -void* OXA::ObjectUtils::preloadData( const Object &object, KJob *job ) +void *OXA::ObjectUtils::preloadData(const Object &object, KJob *job) { - if ( object.module() == Folder::Contacts ) { - if ( object.contactGroup().contactReferenceCount() != 0 ) { - return ContactUtils::preloadData( object, job ); + if (object.module() == Folder::Contacts) { + if (object.contactGroup().contactReferenceCount() != 0) { + return ContactUtils::preloadData(object, job); + } } - } - return 0; + return Q_NULLPTR; } -QString OXA::ObjectUtils::davPath( Folder::Module module ) +QString OXA::ObjectUtils::davPath(Folder::Module module) { - switch ( module ) { - case Folder::Contacts: return QLatin1String( "/servlet/webdav.contacts" ); break; - case Folder::Calendar: return QLatin1String( "/servlet/webdav.calendar" ); break; - case Folder::Tasks: return QLatin1String( "/servlet/webdav.tasks" ); break; - case Folder::Unbound: Q_ASSERT( false ); return QString(); break; - } + switch (module) { + case Folder::Contacts: return QStringLiteral("/servlet/webdav.contacts"); break; + case Folder::Calendar: return QStringLiteral("/servlet/webdav.calendar"); break; + case Folder::Tasks: return QStringLiteral("/servlet/webdav.tasks"); break; + case Folder::Unbound: Q_ASSERT(false); return QString(); break; + } - return QString(); + return QString(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/objectutils.h kdepim-runtime-15.08.0/resources/openxchange/oxa/objectutils.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/objectutils.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/objectutils.h 2015-08-10 21:01:02.000000000 +0000 @@ -30,38 +30,39 @@ class QDomDocument; class QDomElement; -namespace OXA { +namespace OXA +{ namespace ObjectUtils { - Object parseObject( const QDomElement &propElement, Folder::Module module ); - void addObjectElements( QDomDocument &document, QDomElement &propElement, const Object &object, void *preloadedData = 0 ); +Object parseObject(const QDomElement &propElement, Folder::Module module); +void addObjectElements(QDomDocument &document, QDomElement &propElement, const Object &object, void *preloadedData = Q_NULLPTR); - /** - * Returns the dav path that is used for the given @p module. - */ - QString davPath( Folder::Module module ); - - /** - * On some actions (e.g. creating or modifiying items) we have to preload - * data asynchronously. The following methods allow to do that in a generic way. - */ - - /** - * Checks whether the @p object needs preloading of data. - */ - bool needsPreloading( const Object &object ); - - /** - * Creates a preloading job for the @p object. - */ - KJob* preloadJob( const Object &object ); - - /** - * Converts the data loaded by the preloading @p job into pointer - * that will be passed to addObjectElements later on. - */ - void* preloadData( const Object &object, KJob *job ); +/** + * Returns the dav path that is used for the given @p module. + */ +QString davPath(Folder::Module module); + +/** + * On some actions (e.g. creating or modifiying items) we have to preload + * data asynchronously. The following methods allow to do that in a generic way. + */ + +/** + * Checks whether the @p object needs preloading of data. + */ +bool needsPreloading(const Object &object); + +/** + * Creates a preloading job for the @p object. + */ +KJob *preloadJob(const Object &object); + +/** + * Converts the data loaded by the preloading @p job into pointer + * that will be passed to addObjectElements later on. + */ +void *preloadData(const Object &object, KJob *job); } } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/oxerrors.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/oxerrors.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/oxerrors.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/oxerrors.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -23,17 +23,19 @@ using namespace OXA; -OXErrors::EditErrorID OXErrors::getEditErrorID( const QString& errorText ) +OXErrors::EditErrorID OXErrors::getEditErrorID(const QString &errorText) { - int b1Pos = errorText.indexOf( '[' ); - int b2Pos = errorText.indexOf( ']' ); - QString errorID = errorText.mid( b1Pos+1, b2Pos-b1Pos-1 ); + int b1Pos = errorText.indexOf('['); + int b2Pos = errorText.indexOf(']'); + QString errorID = errorText.mid(b1Pos + 1, b2Pos - b1Pos - 1); - bool ok; - int eid = errorID.toInt( &ok ); - if ( !ok ) return OXErrors::EditErrorUndefined; + bool ok; + int eid = errorID.toInt(&ok); + if (!ok) { + return OXErrors::EditErrorUndefined; + } - switch ( eid ) { + switch (eid) { case 1000 : return OXErrors::ConcurrentModification; case 1001 : return OXErrors::ObjectNotFound; case 1002 : return OXErrors::NoPermissionForThisAction; @@ -42,7 +44,7 @@ case 1006 : return OXErrors::AppointmentConflicts; case 1500 : return OXErrors::InternalServerError; default : ; - } + } - return OXErrors::EditErrorUndefined; + return OXErrors::EditErrorUndefined; } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/oxerrors.h kdepim-runtime-15.08.0/resources/openxchange/oxa/oxerrors.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/oxerrors.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/oxerrors.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,7 +24,8 @@ #include -namespace OXA { +namespace OXA +{ /** * Namespace that contains methods for handling OX errors. @@ -34,7 +35,7 @@ namespace OXErrors { - enum EditErrorID { +enum EditErrorID { EditErrorUndefined = 0, ConcurrentModification, ObjectNotFound, @@ -43,12 +44,12 @@ MissingMandatoryFields, AppointmentConflicts, InternalServerError - }; +}; - /** - * Parse error id from edit error text string @p errorText - */ - EditErrorID getEditErrorID( const QString& errorText ); +/** + * Parse error id from edit error text string @p errorText + */ +EditErrorID getEditErrorID(const QString &errorText); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/oxutils.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/oxutils.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/oxutils.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/oxutils.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,118 +21,117 @@ #include "oxutils.h" -#include +#include using namespace OXA; -QString OXUtils::writeBoolean( bool value ) +QString OXUtils::writeBoolean(bool value) { - return (value ? QLatin1String( "true" ) : QLatin1String( "false" )); + return (value ? QLatin1String("true") : QLatin1String("false")); } -QString OXUtils::writeNumber( qlonglong value ) +QString OXUtils::writeNumber(qlonglong value) { - return QString::number( value ); + return QString::number(value); } -QString OXUtils::writeString( const QString &value ) +QString OXUtils::writeString(const QString &value) { - QStringList lines = value.split( '\n' ); + QStringList lines = value.split('\n'); - for ( int i = 0; i < lines.count(); ++i ) - { - lines[i].replace( '\\', "\\\\" ); - lines[i].replace( '"', "\\\"" ); - } + for (int i = 0; i < lines.count(); ++i) { + lines[i].replace('\\', "\\\\"); + lines[i].replace('"', "\\\""); + } - return lines.join( "\n" ); + return lines.join("\n"); } -QString OXUtils::writeName( const QString &value ) +QString OXUtils::writeName(const QString &value) { - //TODO: assert on invalid names - return value; + //TODO: assert on invalid names + return value; } -QString OXUtils::writeDateTime( const QDateTime &value ) +QString OXUtils::writeDateTime(const QDateTime &value) { - QString result; + QString result; - //workaround, as QDateTime does not support negative time_t values - QDateTime Time_t_S( QDate( 1970, 1, 1 ), QTime( 0, 0, 0 ), Qt::UTC); + //workaround, as QDateTime does not support negative time_t values + QDateTime Time_t_S(QDate(1970, 1, 1), QTime(0, 0, 0), Qt::UTC); - if ( value < Time_t_S ) { + if (value < Time_t_S) { - result = QString::number( Time_t_S.secsTo( value ) ); + result = QString::number(Time_t_S.secsTo(value)); - } else { + } else { - result = QString::number( value.toUTC().toTime_t() ); + result = QString::number(value.toUTC().toTime_t()); - } + } - return QString( result + QLatin1String( "000" ) ); + return QString(result + QLatin1String("000")); } -QString OXUtils::writeDate( const QDate &value ) +QString OXUtils::writeDate(const QDate &value) { - return writeDateTime( QDateTime( value, QTime( 0, 0, 0 ), Qt::UTC ) ); + return writeDateTime(QDateTime(value, QTime(0, 0, 0), Qt::UTC)); } -bool OXUtils::readBoolean( const QString &text ) +bool OXUtils::readBoolean(const QString &text) { - if ( text == QLatin1String( "true" ) ) - return true; - else if ( text == QLatin1String( "false" ) ) - return false; - else { - Q_ASSERT( false ); - return false; - } + if (text == QLatin1String("true")) { + return true; + } else if (text == QLatin1String("false")) { + return false; + } else { + Q_ASSERT(false); + return false; + } } -qlonglong OXUtils::readNumber( const QString &text ) +qlonglong OXUtils::readNumber(const QString &text) { - return text.toLongLong(); + return text.toLongLong(); } -QString OXUtils::readString( const QString &text ) +QString OXUtils::readString(const QString &text) { - QString value( text ); - value.replace( "\\\"", "\"" ); - value.replace( "\\\\", "\\" ); + QString value(text); + value.replace("\\\"", "\""); + value.replace("\\\\", "\\"); - return value; + return value; } -QString OXUtils::readName( const QString &text ) +QString OXUtils::readName(const QString &text) { - return text; + return text; } -QDateTime OXUtils::readDateTime( const QString &text ) +QDateTime OXUtils::readDateTime(const QString &text) { - // remove the trailing '000', they exceed the integer dimension - const int ticks = text.mid( 0, text.length() - 3 ).toLongLong(); + // remove the trailing '000', they exceed the integer dimension + const int ticks = text.mid(0, text.length() - 3).toLongLong(); - //workaround, as QDateTime does not support negative time_t values - QDateTime value; - if ( ticks < 0 ) { + //workaround, as QDateTime does not support negative time_t values + QDateTime value; + if (ticks < 0) { - value.setTime_t( 0 ); - value = value.addSecs( ticks ); + value.setTime_t(0); + value = value.addSecs(ticks); - } else { + } else { - value.setTime_t( ticks ); + value.setTime_t(ticks); - } + } - return value; + return value; } -QDate OXUtils::readDate( const QString &text ) +QDate OXUtils::readDate(const QString &text) { - return readDateTime( text ).date(); + return readDateTime(text).date(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/oxutils.h kdepim-runtime-15.08.0/resources/openxchange/oxa/oxutils.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/oxutils.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/oxutils.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,24 +26,24 @@ #include #include - -namespace OXA { +namespace OXA +{ namespace OXUtils { - QString writeBoolean( bool value ); - QString writeNumber( qlonglong value ); - QString writeString( const QString &value ); - QString writeName( const QString &value ); - QString writeDateTime( const QDateTime &value ); - QString writeDate( const QDate &value ); +QString writeBoolean(bool value); +QString writeNumber(qlonglong value); +QString writeString(const QString &value); +QString writeName(const QString &value); +QString writeDateTime(const QDateTime &value); +QString writeDate(const QDate &value); - bool readBoolean( const QString &text ); - qlonglong readNumber( const QString &text ); - QString readString( const QString &text ); - QString readName( const QString &text ); - QDateTime readDateTime( const QString &text ); - QDate readDate( const QString &text ); +bool readBoolean(const QString &text); +qlonglong readNumber(const QString &text); +QString readString(const QString &text); +QString readName(const QString &text); +QDateTime readDateTime(const QString &text); +QDate readDate(const QString &text); } } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/updateusersjob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/updateusersjob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/updateusersjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/updateusersjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -27,67 +27,68 @@ using namespace OXA; -UpdateUsersJob::UpdateUsersJob( QObject *parent ) - : KJob( parent ), mUserIdRequestFinished( false ), mUsersRequestFinished( false ), mUserId( -1 ) +UpdateUsersJob::UpdateUsersJob(QObject *parent) + : KJob(parent), mUserIdRequestFinished(false), mUsersRequestFinished(false), mUserId(-1) { } void UpdateUsersJob::start() { - UserIdRequestJob *userIdJob = new UserIdRequestJob( this ); - connect( userIdJob, SIGNAL(result(KJob*)), SLOT(userIdRequestJobFinished(KJob*)) ); + UserIdRequestJob *userIdJob = new UserIdRequestJob(this); + connect(userIdJob, &UserIdRequestJob::result, this, &UpdateUsersJob::userIdRequestJobFinished); - UsersRequestJob *usersJob = new UsersRequestJob( this ); - connect( usersJob, SIGNAL(result(KJob*)), SLOT(usersRequestJobFinished(KJob*)) ); + UsersRequestJob *usersJob = new UsersRequestJob(this); + connect(usersJob, &UsersRequestJob::result, this, &UpdateUsersJob::usersRequestJobFinished); - userIdJob->start(); - usersJob->start(); + userIdJob->start(); + usersJob->start(); } -void UpdateUsersJob::userIdRequestJobFinished( KJob *job ) +void UpdateUsersJob::userIdRequestJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - } else { - mUserIdRequestFinished = true; + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + } else { + mUserIdRequestFinished = true; - UserIdRequestJob *requestJob = qobject_cast( job ); - mUserId = requestJob->userId(); + UserIdRequestJob *requestJob = qobject_cast(job); + mUserId = requestJob->userId(); - finish(); - } + finish(); + } } -void UpdateUsersJob::usersRequestJobFinished( KJob *job ) +void UpdateUsersJob::usersRequestJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - } else { - mUsersRequestFinished = true; + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + } else { + mUsersRequestFinished = true; - UsersRequestJob *requestJob = qobject_cast( job ); - mUsers = requestJob->users(); + UsersRequestJob *requestJob = qobject_cast(job); + mUsers = requestJob->users(); - finish(); - } + finish(); + } } void UpdateUsersJob::finish() { - // check if both sub-jobs have finished - if ( !(mUserIdRequestFinished && mUsersRequestFinished) ) - return; + // check if both sub-jobs have finished + if (!(mUserIdRequestFinished && mUsersRequestFinished)) { + return; + } + + if (error()) { + emitResult(); + return; + } - if ( error() ) { - emitResult(); - return; - } - - Users::self()->setCurrentUserId( mUserId ); - Users::self()->setUsers( mUsers ); + Users::self()->setCurrentUserId(mUserId); + Users::self()->setUsers(mUsers); - emitResult(); + emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/updateusersjob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/updateusersjob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/updateusersjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/updateusersjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,22 +26,23 @@ #include "user.h" -namespace OXA { +namespace OXA +{ class UpdateUsersJob : public KJob { - Q_OBJECT + Q_OBJECT - public: - explicit UpdateUsersJob( QObject *parent = 0 ); +public: + explicit UpdateUsersJob(QObject *parent = Q_NULLPTR); - virtual void start(); + void start() Q_DECL_OVERRIDE; - private Q_SLOTS: - void userIdRequestJobFinished( KJob* ); - void usersRequestJobFinished( KJob* ); +private Q_SLOTS: + void userIdRequestJobFinished(KJob *); + void usersRequestJobFinished(KJob *); - private: +private: void finish(); bool mUserIdRequestFinished; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/user.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/user.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/user.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/user.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -24,41 +24,41 @@ using namespace OXA; User::User() - : mUid( -1 ) + : mUid(-1) { } bool User::isValid() const { - return (mUid != -1); + return (mUid != -1); } -void User::setUid( qlonglong uid ) +void User::setUid(qlonglong uid) { - mUid = uid; + mUid = uid; } qlonglong User::uid() const { - return mUid; + return mUid; } -void User::setEmail( const QString &email ) +void User::setEmail(const QString &email) { - mEmail = email; + mEmail = email; } QString User::email() const { - return mEmail; + return mEmail; } -void User::setName( const QString &name ) +void User::setName(const QString &name) { - mName = name; + mName = name; } QString User::name() const { - return mName; + return mName; } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/user.h kdepim-runtime-15.08.0/resources/openxchange/oxa/user.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/user.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/user.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,30 +22,31 @@ #ifndef OXA_USER_H #define OXA_USER_H -#include +#include #include -namespace OXA { +namespace OXA +{ class User { - public: - typedef QList List; +public: + typedef QVector List; User(); bool isValid() const; - void setUid( qlonglong uid ); + void setUid(qlonglong uid); qlonglong uid() const; - void setEmail( const QString &email ); + void setEmail(const QString &email); QString email() const; - void setName( const QString &name ); + void setName(const QString &name); QString name() const; - private: +private: qlonglong mUid; QString mEmail; QString mName; @@ -53,4 +54,5 @@ } +Q_DECLARE_TYPEINFO( OXA::User, Q_MOVABLE_TYPE ); #endif diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/useridrequestjob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/useridrequestjob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/useridrequestjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/useridrequestjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -28,51 +28,51 @@ using namespace OXA; -UserIdRequestJob::UserIdRequestJob( QObject *parent ) - : KJob( parent ), mUserId( -1 ) +UserIdRequestJob::UserIdRequestJob(QObject *parent) + : KJob(parent), mUserId(-1) { } void UserIdRequestJob::start() { - FoldersRequestJob *job = new FoldersRequestJob( 0, FoldersRequestJob::Modified, this ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + FoldersRequestJob *job = new FoldersRequestJob(0, FoldersRequestJob::Modified, this); + connect(job, &FoldersRequestJob::result, this, &UserIdRequestJob::davJobFinished); - job->start(); + job->start(); } qlonglong UserIdRequestJob::userId() const { - return mUserId; + return mUserId; } -void UserIdRequestJob::davJobFinished( KJob *job ) +void UserIdRequestJob::davJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } - FoldersRequestJob *requestJob = qobject_cast( job ); - Q_ASSERT( requestJob ); + FoldersRequestJob *requestJob = qobject_cast(job); + Q_ASSERT(requestJob); - const Folder::List folders = requestJob->folders(); - foreach ( const Folder &folder, folders ) { - if ( folder.folderId() == 1 ) { - // Found folder with 'Private Folders' as parent, so the owner must - // be the user that is currently logged in. - mUserId = folder.owner(); - break; + const Folder::List folders = requestJob->folders(); + foreach (const Folder &folder, folders) { + if (folder.folderId() == 1) { + // Found folder with 'Private Folders' as parent, so the owner must + // be the user that is currently logged in. + mUserId = folder.owner(); + break; + } } - } - if ( mUserId == -1 ) { - setError( UserDefinedError ); - setErrorText( "No private folder found" ); - } + if (mUserId == -1) { + setError(UserDefinedError); + setErrorText("No private folder found"); + } - emitResult(); + emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/useridrequestjob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/useridrequestjob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/useridrequestjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/useridrequestjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,23 +24,24 @@ #include -namespace OXA { +namespace OXA +{ class UserIdRequestJob : public KJob { - Q_OBJECT + Q_OBJECT - public: - explicit UserIdRequestJob( QObject *parent = 0 ); +public: + explicit UserIdRequestJob(QObject *parent = Q_NULLPTR); - virtual void start(); + void start() Q_DECL_OVERRIDE; qlonglong userId() const; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: qlonglong mUserId; }; diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/users.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/users.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/users.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/users.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,15 +22,15 @@ #include "users.h" #include - -#include +#include +#include using namespace OXA; -Users* Users::mSelf = 0; +Users *Users::mSelf = Q_NULLPTR; Users::Users() - : mCurrentUserId( -1 ) + : mCurrentUserId(-1) { } @@ -38,117 +38,122 @@ { } -Users* Users::self() +Users *Users::self() { - if ( !mSelf ) - mSelf = new Users(); + if (!mSelf) { + mSelf = new Users(); + } - return mSelf; + return mSelf; } -void Users::init( const QString &identifier ) +void Users::init(const QString &identifier) { - mIdentifier = identifier; + mIdentifier = identifier; - loadFromCache(); + loadFromCache(); } qlonglong Users::currentUserId() const { - return mCurrentUserId; + return mCurrentUserId; } -User Users::lookupUid( qlonglong uid ) const +User Users::lookupUid(qlonglong uid) const { - return mUsers.value( uid ); + return mUsers.value(uid); } -User Users::lookupEmail( const QString &email ) const +User Users::lookupEmail(const QString &email) const { - QMapIterator it( mUsers ); - while ( it.hasNext() ) { - it.next(); + QMapIterator it(mUsers); + while (it.hasNext()) { + it.next(); - if ( it.value().email() == email ) - return it.value(); - } + if (it.value().email() == email) { + return it.value(); + } + } - return User(); + return User(); } QString Users::cacheFilePath() const { - return KStandardDirs::locateLocal( "data", "akonadi/openxchangeresource_" + mIdentifier ); + return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + "openxchangeresource_" + mIdentifier ; } -void Users::setCurrentUserId( qlonglong id ) +void Users::setCurrentUserId(qlonglong id) { - mCurrentUserId = id; + mCurrentUserId = id; - saveToCache(); + saveToCache(); } -void Users::setUsers( const User::List &users ) +void Users::setUsers(const User::List &users) { - mUsers.clear(); + mUsers.clear(); - foreach ( const User &user, users ) - mUsers.insert( user.uid(), user ); + foreach (const User &user, users) { + mUsers.insert(user.uid(), user); + } - saveToCache(); + saveToCache(); } void Users::loadFromCache() { - QFile cacheFile( cacheFilePath() ); - if ( !cacheFile.open( QIODevice::ReadOnly ) ) - return; - - QDataStream stream( &cacheFile ); - stream.setVersion( QDataStream::Qt_4_6 ); - - mUsers.clear(); - - stream >> mCurrentUserId; - - qulonglong count; - stream >> count; - - qlonglong uid; - QString name; - QString email; - for ( qulonglong i = 0; i < count; ++i ) { - stream >> uid >> name >> email; - - User user; - user.setUid( uid ); - user.setName( name ); - user.setEmail( email ); - mUsers.insert( user.uid(), user ); - } + QFile cacheFile(cacheFilePath()); + if (!cacheFile.open(QIODevice::ReadOnly)) { + return; + } + + QDataStream stream(&cacheFile); + stream.setVersion(QDataStream::Qt_4_6); + + mUsers.clear(); + + stream >> mCurrentUserId; + + qulonglong count; + stream >> count; + + qlonglong uid; + QString name; + QString email; + for (qulonglong i = 0; i < count; ++i) { + stream >> uid >> name >> email; + + User user; + user.setUid(uid); + user.setName(name); + user.setEmail(email); + mUsers.insert(user.uid(), user); + } } void Users::saveToCache() { - QFile cacheFile( cacheFilePath() ); - if ( !cacheFile.open( QIODevice::WriteOnly ) ) - return; - - QDataStream stream( &cacheFile ); - stream.setVersion( QDataStream::Qt_4_6 ); - - // write current user id - stream << mCurrentUserId; - - // write number of users - stream << (qulonglong)mUsers.count(); - - // write uid, name and email address for each user - QMapIterator it( mUsers ); - while ( it.hasNext() ) { - it.next(); + QFile cacheFile(cacheFilePath()); + if (!cacheFile.open(QIODevice::WriteOnly)) { + return; + } + + QDataStream stream(&cacheFile); + stream.setVersion(QDataStream::Qt_4_6); + + // write current user id + stream << mCurrentUserId; + + // write number of users + stream << (qulonglong)mUsers.count(); + + // write uid, name and email address for each user + QMapIterator it(mUsers); + while (it.hasNext()) { + it.next(); - stream << it.value().uid() << it.value().name() << it.value().email(); - } + stream << it.value().uid() << it.value().name() << it.value().email(); + } } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/users.h kdepim-runtime-15.08.0/resources/openxchange/oxa/users.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/users.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/users.h 2015-08-10 21:01:02.000000000 +0000 @@ -27,33 +27,33 @@ #include #include - -namespace OXA { +namespace OXA +{ class Users : public QObject { - Q_OBJECT + Q_OBJECT - public: +public: ~Users(); - static Users* self(); + static Users *self(); - void init( const QString &identifier ); + void init(const QString &identifier); qlonglong currentUserId() const; - User lookupUid( qlonglong uid ) const; - User lookupEmail( const QString &email ) const; + User lookupUid(qlonglong uid) const; + User lookupEmail(const QString &email) const; QString cacheFilePath() const; - private: +private: friend class UpdateUsersJob; Users(); - void setCurrentUserId( qlonglong ); - void setUsers( const User::List& ); + void setCurrentUserId(qlonglong); + void setUsers(const User::List &); void loadFromCache(); void saveToCache(); @@ -62,7 +62,7 @@ QMap mUsers; QString mIdentifier; - static Users* mSelf; + static Users *mSelf; }; } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/usersrequestjob.cpp kdepim-runtime-15.08.0/resources/openxchange/oxa/usersrequestjob.cpp --- kdepim-runtime-4.14.6/resources/openxchange/oxa/usersrequestjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/usersrequestjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -29,72 +29,72 @@ using namespace OXA; -UsersRequestJob::UsersRequestJob( QObject *parent ) - : KJob( parent ) +UsersRequestJob::UsersRequestJob(QObject *parent) + : KJob(parent) { } void UsersRequestJob::start() { - QDomDocument document; - QDomElement multistatus = DAVUtils::addDavElement( document, document, QLatin1String( "multistatus" ) ); - QDomElement prop = DAVUtils::addDavElement( document, multistatus, QLatin1String( "prop" ) ); - DAVUtils::addOxElement( document, prop, QLatin1String( "user" ), QLatin1String( "*" ) ); + QDomDocument document; + QDomElement multistatus = DAVUtils::addDavElement(document, document, QStringLiteral("multistatus")); + QDomElement prop = DAVUtils::addDavElement(document, multistatus, QStringLiteral("prop")); + DAVUtils::addOxElement(document, prop, QStringLiteral("user"), QStringLiteral("*")); - const QString path = QLatin1String( "/servlet/webdav.groupuser" ); + const QString path = QLatin1String("/servlet/webdav.groupuser"); - KIO::DavJob *job = DavManager::self()->createFindJob( path, document ); - connect( job, SIGNAL(result(KJob*)), SLOT(davJobFinished(KJob*)) ); + KIO::DavJob *job = DavManager::self()->createFindJob(path, document); + connect(job, &KIO::DavJob::result, this, &UsersRequestJob::davJobFinished); - job->start(); + job->start(); } User::List UsersRequestJob::users() const { - return mUsers; + return mUsers; } -void UsersRequestJob::davJobFinished( KJob *job ) +void UsersRequestJob::davJobFinished(KJob *job) { - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - emitResult(); - return; - } + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + return; + } - KIO::DavJob *davJob = qobject_cast( job ); + KIO::DavJob *davJob = qobject_cast(job); - const QDomDocument document = davJob->response(); + const QDomDocument document = davJob->response(); - QDomElement multistatus = document.documentElement(); - QDomElement response = multistatus.firstChildElement( QLatin1String( "response" ) ); - QDomElement propstat = response.firstChildElement( QLatin1String( "propstat" ) ); - QDomElement prop = propstat.firstChildElement( QLatin1String( "prop" ) ); - QDomElement users = prop.firstChildElement( QLatin1String( "users" ) ); - - QDomElement userElement = users.firstChildElement( QLatin1String( "user" ) ); - while ( !userElement.isNull() ) { - User user; - - QDomElement element = userElement.firstChildElement(); - while ( !element.isNull() ) { - if ( element.tagName() == QLatin1String( "uid" ) ) { - user.setUid( OXUtils::readNumber( element.text() ) ); - } else if ( element.tagName() == QLatin1String( "email1" ) ) { - user.setEmail( OXUtils::readString( element.text() ) ); - } else if ( element.tagName() == QLatin1String( "displayname" ) ) { - user.setName( OXUtils::readString( element.text() ) ); - } + QDomElement multistatus = document.documentElement(); + QDomElement response = multistatus.firstChildElement(QStringLiteral("response")); + QDomElement propstat = response.firstChildElement(QStringLiteral("propstat")); + QDomElement prop = propstat.firstChildElement(QStringLiteral("prop")); + QDomElement users = prop.firstChildElement(QStringLiteral("users")); + + QDomElement userElement = users.firstChildElement(QStringLiteral("user")); + while (!userElement.isNull()) { + User user; + + QDomElement element = userElement.firstChildElement(); + while (!element.isNull()) { + if (element.tagName() == QLatin1String("uid")) { + user.setUid(OXUtils::readNumber(element.text())); + } else if (element.tagName() == QLatin1String("email1")) { + user.setEmail(OXUtils::readString(element.text())); + } else if (element.tagName() == QLatin1String("displayname")) { + user.setName(OXUtils::readString(element.text())); + } - element = element.nextSiblingElement(); - } + element = element.nextSiblingElement(); + } - mUsers.append( user ); + mUsers.append(user); - userElement = userElement.nextSiblingElement( QLatin1String( "user" ) ); - } + userElement = userElement.nextSiblingElement(QStringLiteral("user")); + } - emitResult(); + emitResult(); } diff -Nru kdepim-runtime-4.14.6/resources/openxchange/oxa/usersrequestjob.h kdepim-runtime-15.08.0/resources/openxchange/oxa/usersrequestjob.h --- kdepim-runtime-4.14.6/resources/openxchange/oxa/usersrequestjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/openxchange/oxa/usersrequestjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -26,23 +26,24 @@ #include "user.h" -namespace OXA { +namespace OXA +{ class UsersRequestJob : public KJob { - Q_OBJECT + Q_OBJECT - public: - explicit UsersRequestJob( QObject *parent = 0 ); +public: + explicit UsersRequestJob(QObject *parent = Q_NULLPTR); - virtual void start(); + void start() Q_DECL_OVERRIDE; User::List users() const; - private Q_SLOTS: - void davJobFinished( KJob* ); +private Q_SLOTS: + void davJobFinished(KJob *); - private: +private: User::List mUsers; }; diff -Nru kdepim-runtime-4.14.6/resources/pop3/accountdialog.cpp kdepim-runtime-15.08.0/resources/pop3/accountdialog.cpp --- kdepim-runtime-4.14.6/resources/pop3/accountdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/accountdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -27,664 +27,639 @@ #include "settingsadaptor.h" // KDEPIMLIBS includes -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include // KDELIBS includes #include #include -#include #include #include #include +#include "pop3resource_debug.h" +#include +#include +#include +#include using namespace MailTransport; using namespace Akonadi; using namespace KWallet; -namespace { +namespace +{ class BusyCursorHelper : public QObject { public: - inline BusyCursorHelper( QObject *parent ) - : QObject( parent ) - { + inline BusyCursorHelper(QObject *parent) + : QObject(parent) + { #ifndef QT_NO_CURSOR - qApp->setOverrideCursor( Qt::BusyCursor ); + qApp->setOverrideCursor(Qt::BusyCursor); #endif - } + } - inline ~BusyCursorHelper() - { + inline ~BusyCursorHelper() + { #ifndef QT_NO_CURSOR - qApp->restoreOverrideCursor(); + qApp->restoreOverrideCursor(); #endif - } + } }; } +AccountDialog::AccountDialog(POP3Resource *parentResource, WId parentWindow) + : QDialog(), + mParentResource(parentResource), + mServerTest(Q_NULLPTR), + mValidator(this), + mWallet(Q_NULLPTR) +{ + KWindowSystem::setMainWindow(this, parentWindow); + setWindowIcon(QIcon::fromTheme(QStringLiteral("network-server"))); + setWindowTitle(i18n("POP3 Account Settings")); + mValidator.setRegExp(QRegExp(QStringLiteral("[A-Za-z0-9-_:.]*"))); -AccountDialog::AccountDialog( POP3Resource *parentResource, WId parentWindow ) - : KDialog(), - mParentResource( parentResource ), - mServerTest( 0 ), - mValidator( this ), - mWallet( 0 ) -{ - KWindowSystem::setMainWindow( this, parentWindow ); - setWindowIcon( KIcon( QLatin1String("network-server") ) ); - setWindowTitle( i18n( "POP3 Account Settings" ) ); - setButtons( Ok|Cancel ); - mValidator.setRegExp( QRegExp( QLatin1String("[A-Za-z0-9-_:.]*") ) ); - - setupWidgets(); - loadSettings(); + setupWidgets(); + loadSettings(); } AccountDialog::~AccountDialog() { - delete mWallet; - mWallet = 0; - delete mServerTest; - mServerTest = 0; + delete mWallet; + mWallet = Q_NULLPTR; + delete mServerTest; + mServerTest = Q_NULLPTR; } void AccountDialog::setupWidgets() { - QWidget *page = new QWidget( this ); - setupUi( page ); - setMainWidget( page ); - - // only letters, digits, '-', '.', ':' (IPv6) and '_' (for Windows - // compatibility) are allowed - hostEdit->setValidator( &mValidator ); - intervalSpin->setSuffix( ki18np( " minute", " minutes" ) ); - - intervalSpin->setRange( ResourceSettings::self()->minimumCheckInterval(), 10000, 1 ); - - connect( leaveOnServerCheck, SIGNAL(clicked()), - this, SLOT(slotLeaveOnServerClicked()) ); - connect( leaveOnServerDaysCheck, SIGNAL(toggled(bool)), - this, SLOT(slotEnableLeaveOnServerDays(bool)) ); - connect( leaveOnServerDaysSpin, SIGNAL(valueChanged(int)), - SLOT(slotLeaveOnServerDaysChanged(int))); - connect( leaveOnServerCountCheck, SIGNAL(toggled(bool)), - this, SLOT(slotEnableLeaveOnServerCount(bool)) ); - connect( leaveOnServerCountSpin, SIGNAL(valueChanged(int)), - SLOT(slotLeaveOnServerCountChanged(int))); - connect( leaveOnServerSizeCheck, SIGNAL(toggled(bool)), - this, SLOT(slotEnableLeaveOnServerSize(bool)) ); - - connect(filterOnServerSizeSpin, SIGNAL(valueChanged(int)), - SLOT(slotFilterOnServerSizeChanged(int))); - connect( filterOnServerCheck, SIGNAL(toggled(bool)), - filterOnServerSizeSpin, SLOT(setEnabled(bool)) ); - connect( filterOnServerCheck, SIGNAL(clicked()), - this, SLOT(slotFilterOnServerClicked()) ); - - connect( checkCapabilities, SIGNAL(clicked()), - SLOT(slotCheckPopCapabilities()) ); - encryptionButtonGroup = new QButtonGroup(); - encryptionButtonGroup->addButton( encryptionNone, - Transport::EnumEncryption::None ); - encryptionButtonGroup->addButton( encryptionSSL, - Transport::EnumEncryption::SSL ); - encryptionButtonGroup->addButton( encryptionTLS, - Transport::EnumEncryption::TLS ); - - connect( encryptionButtonGroup, SIGNAL(buttonClicked(int)), - SLOT(slotPopEncryptionChanged(int)) ); - connect( intervalCheck, SIGNAL(toggled(bool)), - this, SLOT(slotEnablePopInterval(bool)) ); - - populateDefaultAuthenticationOptions(); - - folderRequester->setMimeTypeFilter( - QStringList() << QLatin1String( "message/rfc822" ) ); - folderRequester->setFrameStyle( QFrame::NoFrame ); - folderRequester->setAccessRightsFilter( Akonadi::Collection::CanCreateItem ); - folderRequester->changeCollectionDialogOptions( Akonadi::CollectionDialog::AllowToCreateNewChildCollection ); - - connect( usePipeliningCheck, SIGNAL(clicked()), - SLOT(slotPipeliningClicked()) ); - - connect(KGlobalSettings::self(),SIGNAL(kdisplayFontChanged()), - SLOT(slotFontChanged())); - - // FIXME: Hide widgets which are not supported yet - filterOnServerCheck->hide(); - filterOnServerSizeSpin->hide(); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mOkButton = buttonBox->button(QDialogButtonBox::Ok); + mOkButton->setDefault(true); + mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &AccountDialog::slotAccepted); + connect(buttonBox, &QDialogButtonBox::rejected, this, &AccountDialog::reject); + + QWidget *page = new QWidget(this); + mainLayout->addWidget(page); + mainLayout->addWidget(buttonBox); + + setupUi(page); + + // only letters, digits, '-', '.', ':' (IPv6) and '_' (for Windows + // compatibility) are allowed + hostEdit->setValidator(&mValidator); + intervalSpin->setSuffix(ki18np(" minute", " minutes")); + + intervalSpin->setRange(ResourceSettings::self()->minimumCheckInterval(), 10000); + intervalSpin->setSingleStep(1); + + connect(leaveOnServerCheck, &QCheckBox::clicked, this, &AccountDialog::slotLeaveOnServerClicked); + connect(leaveOnServerDaysCheck, &QCheckBox::toggled, this, &AccountDialog::slotEnableLeaveOnServerDays); + connect(leaveOnServerDaysSpin, static_cast(&QSpinBox::valueChanged), this, &AccountDialog::slotLeaveOnServerDaysChanged); + connect(leaveOnServerCountCheck, &QCheckBox::toggled, this, &AccountDialog::slotEnableLeaveOnServerCount); + connect(leaveOnServerCountSpin, static_cast(&QSpinBox::valueChanged), this, &AccountDialog::slotLeaveOnServerCountChanged); + connect(leaveOnServerSizeCheck, &QCheckBox::toggled, this, &AccountDialog::slotEnableLeaveOnServerSize); + + connect(filterOnServerSizeSpin, static_cast(&QSpinBox::valueChanged), this, &AccountDialog::slotFilterOnServerSizeChanged); + connect(filterOnServerCheck, &QCheckBox::toggled, filterOnServerSizeSpin, &QSpinBox::setEnabled); + connect(filterOnServerCheck, &QCheckBox::clicked, this, &AccountDialog::slotFilterOnServerClicked); + + connect(checkCapabilities, &QPushButton::clicked, this, &AccountDialog::slotCheckPopCapabilities); + encryptionButtonGroup = new QButtonGroup(); + encryptionButtonGroup->addButton(encryptionNone, + Transport::EnumEncryption::None); + encryptionButtonGroup->addButton(encryptionSSL, + Transport::EnumEncryption::SSL); + encryptionButtonGroup->addButton(encryptionTLS, + Transport::EnumEncryption::TLS); + + connect(encryptionButtonGroup, static_cast(&QButtonGroup::buttonClicked), this, &AccountDialog::slotPopEncryptionChanged); + connect(intervalCheck, &QCheckBox::toggled, this, &AccountDialog::slotEnablePopInterval); + + populateDefaultAuthenticationOptions(); + + folderRequester->setMimeTypeFilter( + QStringList() << QStringLiteral("message/rfc822")); + folderRequester->setAccessRightsFilter(Akonadi::Collection::CanCreateItem); + folderRequester->changeCollectionDialogOptions(Akonadi::CollectionDialog::AllowToCreateNewChildCollection); + + connect(usePipeliningCheck, &QCheckBox::clicked, this, &AccountDialog::slotPipeliningClicked); + + // FIXME: Hide widgets which are not supported yet + filterOnServerCheck->hide(); + filterOnServerSizeSpin->hide(); } void AccountDialog::loadSettings() { - if ( mParentResource->name() == mParentResource->identifier() ) - mParentResource->setName( i18n( "POP3 Account") ); + if (mParentResource->name() == mParentResource->identifier()) { + mParentResource->setName(i18n("POP3 Account")); + } - nameEdit->setText( mParentResource->name() ); - nameEdit->setFocus(); - loginEdit->setText( !Settings::self()->login().isEmpty() ? Settings::self()->login() : - KUser().loginName() ); - - hostEdit->setText( - !Settings::self()->host().isEmpty() ? Settings::self()->host() : - KEMailSettings().getSetting( KEMailSettings::InServer ) ); - hostEdit->setText( Settings::self()->host() ); - portEdit->setValue( Settings::self()->port() ); - precommand->setText( Settings::self()->precommand() ); - usePipeliningCheck->setChecked( Settings::self()->pipelining() ); - leaveOnServerCheck->setChecked( Settings::self()->leaveOnServer() ); - leaveOnServerDaysCheck->setEnabled( Settings::self()->leaveOnServer() ); - leaveOnServerDaysCheck->setChecked( Settings::self()->leaveOnServerDays() >= 1 ); - leaveOnServerDaysSpin->setValue( Settings::self()->leaveOnServerDays() >= 1 ? - Settings::self()->leaveOnServerDays() : 7 ); - leaveOnServerCountCheck->setEnabled( Settings::self()->leaveOnServer() ); - leaveOnServerCountCheck->setChecked( Settings::self()->leaveOnServerCount() >= 1 ); - leaveOnServerCountSpin->setValue( Settings::self()->leaveOnServerCount() >= 1 ? - Settings::self()->leaveOnServerCount() : 100 ); - leaveOnServerSizeCheck->setEnabled( Settings::self()->leaveOnServer() ); - leaveOnServerSizeCheck->setChecked( Settings::self()->leaveOnServerSize() >= 1 ); - leaveOnServerSizeSpin->setValue( Settings::self()->leaveOnServerSize() >= 1 ? - Settings::self()->leaveOnServerSize() : 10 ); - filterOnServerCheck->setChecked( Settings::self()->filterOnServer() ); - filterOnServerSizeSpin->setValue( Settings::self()->filterCheckSize() ); - intervalCheck->setChecked( Settings::self()->intervalCheckEnabled() ); - intervalSpin->setValue( Settings::self()->intervalCheckInterval() ); - intervalSpin->setEnabled( Settings::self()->intervalCheckEnabled() ); - - const int authenticationMethod = Settings::self()->authenticationMethod(); - authCombo->setCurrentIndex( authCombo->findData( authenticationMethod ) ); - encryptionNone->setChecked( !Settings::self()->useSSL() && !Settings::self()->useTLS() ); - encryptionSSL->setChecked( Settings::self()->useSSL() ); - encryptionTLS->setChecked( Settings::self()->useTLS() ); - - slotEnableLeaveOnServerDays( leaveOnServerDaysCheck->isEnabled() ? - Settings::self()->leaveOnServerDays() >= 1 : 0); - slotEnableLeaveOnServerCount( leaveOnServerCountCheck->isEnabled() ? - Settings::self()->leaveOnServerCount() >= 1 : 0); - slotEnableLeaveOnServerSize( leaveOnServerSizeCheck->isEnabled() ? - Settings::self()->leaveOnServerSize() >= 1 : 0); - - // We need to fetch the collection, as the CollectionRequester needs the name - // of it to work correctly - Collection targetCollection( Settings::self()->targetCollection() ); - if ( targetCollection.isValid() ) { - CollectionFetchJob *fetchJob = new CollectionFetchJob( targetCollection, - CollectionFetchJob::Base, - this ); - connect( fetchJob, SIGNAL(collectionsReceived(Akonadi::Collection::List)), - this, SLOT(targetCollectionReceived(Akonadi::Collection::List)) ); - } - else { - // FIXME: This is a bit duplicated from POP3Resource... - - // No target collection set in the config? Try requesting a default inbox - SpecialMailCollectionsRequestJob *requestJob = new SpecialMailCollectionsRequestJob( this ); - requestJob->requestDefaultCollection( SpecialMailCollections::Inbox ); - requestJob->start(); - connect ( requestJob, SIGNAL(result(KJob*)), - this, SLOT(localFolderRequestJobFinished(KJob*)) ); - } - - mWallet = Wallet::openWallet( Wallet::NetworkWallet(), winId(), - Wallet::Asynchronous ); - if ( mWallet ) { - connect( mWallet, SIGNAL(walletOpened(bool)), - this, SLOT(walletOpenedForLoading(bool)) ); - } else { - passwordEdit->setClickMessage( i18n( "Wallet disabled in system settings" ) ); - } - passwordEdit->setEnabled( false ); - passwordLabel->setEnabled( false ); -} - -void AccountDialog::walletOpenedForLoading( bool success ) -{ - if ( success ) { - if ( mWallet->isOpen() ) { - passwordEdit->setEnabled( true ); - passwordLabel->setEnabled( true ); - } - if ( mWallet->isOpen() && mWallet->hasFolder( QLatin1String("pop3") ) ) { - QString password; - mWallet->setFolder( QLatin1String("pop3") ); - mWallet->readPassword( mParentResource->identifier(), password ); - passwordEdit->setText( password ); - mInitalPassword = password; + nameEdit->setText(mParentResource->name()); + nameEdit->setFocus(); + loginEdit->setText(!Settings::self()->login().isEmpty() ? Settings::self()->login() : + KUser().loginName()); + + hostEdit->setText( + !Settings::self()->host().isEmpty() ? Settings::self()->host() : + KEMailSettings().getSetting(KEMailSettings::InServer)); + hostEdit->setText(Settings::self()->host()); + portEdit->setValue(Settings::self()->port()); + precommand->setText(Settings::self()->precommand()); + usePipeliningCheck->setChecked(Settings::self()->pipelining()); + leaveOnServerCheck->setChecked(Settings::self()->leaveOnServer()); + leaveOnServerDaysCheck->setEnabled(Settings::self()->leaveOnServer()); + leaveOnServerDaysCheck->setChecked(Settings::self()->leaveOnServerDays() >= 1); + leaveOnServerDaysSpin->setValue(Settings::self()->leaveOnServerDays() >= 1 ? + Settings::self()->leaveOnServerDays() : 7); + leaveOnServerCountCheck->setEnabled(Settings::self()->leaveOnServer()); + leaveOnServerCountCheck->setChecked(Settings::self()->leaveOnServerCount() >= 1); + leaveOnServerCountSpin->setValue(Settings::self()->leaveOnServerCount() >= 1 ? + Settings::self()->leaveOnServerCount() : 100); + leaveOnServerSizeCheck->setEnabled(Settings::self()->leaveOnServer()); + leaveOnServerSizeCheck->setChecked(Settings::self()->leaveOnServerSize() >= 1); + leaveOnServerSizeSpin->setValue(Settings::self()->leaveOnServerSize() >= 1 ? + Settings::self()->leaveOnServerSize() : 10); + filterOnServerCheck->setChecked(Settings::self()->filterOnServer()); + filterOnServerSizeSpin->setValue(Settings::self()->filterCheckSize()); + intervalCheck->setChecked(Settings::self()->intervalCheckEnabled()); + intervalSpin->setValue(Settings::self()->intervalCheckInterval()); + intervalSpin->setEnabled(Settings::self()->intervalCheckEnabled()); + + const int authenticationMethod = Settings::self()->authenticationMethod(); + authCombo->setCurrentIndex(authCombo->findData(authenticationMethod)); + encryptionNone->setChecked(!Settings::self()->useSSL() && !Settings::self()->useTLS()); + encryptionSSL->setChecked(Settings::self()->useSSL()); + encryptionTLS->setChecked(Settings::self()->useTLS()); + + slotEnableLeaveOnServerDays(leaveOnServerDaysCheck->isEnabled() ? + Settings::self()->leaveOnServerDays() >= 1 : 0); + slotEnableLeaveOnServerCount(leaveOnServerCountCheck->isEnabled() ? + Settings::self()->leaveOnServerCount() >= 1 : 0); + slotEnableLeaveOnServerSize(leaveOnServerSizeCheck->isEnabled() ? + Settings::self()->leaveOnServerSize() >= 1 : 0); + + // We need to fetch the collection, as the CollectionRequester needs the name + // of it to work correctly + Collection targetCollection(Settings::self()->targetCollection()); + if (targetCollection.isValid()) { + CollectionFetchJob *fetchJob = new CollectionFetchJob(targetCollection, + CollectionFetchJob::Base, + this); + connect(fetchJob, &CollectionFetchJob::collectionsReceived, this, &AccountDialog::targetCollectionReceived); } else { - kWarning() << "Wallet not open or doesn't have pop3 folder."; + // FIXME: This is a bit duplicated from POP3Resource... + + // No target collection set in the config? Try requesting a default inbox + SpecialMailCollectionsRequestJob *requestJob = new SpecialMailCollectionsRequestJob(this); + requestJob->requestDefaultCollection(SpecialMailCollections::Inbox); + requestJob->start(); + connect(requestJob, &SpecialMailCollectionsRequestJob::result, this, &AccountDialog::localFolderRequestJobFinished); } - } - else { - kWarning() << "Failed to open wallet for loading the password."; - } - - const bool walletError = !success || !mWallet->isOpen(); - if ( walletError ) { - passwordEdit->setClickMessage( i18n( "Unable to open wallet" ) ); - } -} - -void AccountDialog::walletOpenedForSaving( bool success ) -{ - if ( success ) { - if ( mWallet && mWallet->isOpen() ) { - - // Remove the password from the wallet if the user doesn't want to store it - if ( passwordEdit->text().isEmpty() && mWallet->hasFolder( QLatin1String("pop3") ) ) { - mWallet->setFolder( QLatin1String("pop3") ); - mWallet->removeEntry( mParentResource->identifier() ); - } - - // Store the password in the wallet if the user wants that - else if ( !passwordEdit->text().isEmpty() ) { - if ( !mWallet->hasFolder( QLatin1String("pop3") ) ) { - mWallet->createFolder( QLatin1String("pop3") ); + + mWallet = Wallet::openWallet(Wallet::NetworkWallet(), winId(), + Wallet::Asynchronous); + if (mWallet) { + connect(mWallet, &KWallet::Wallet::walletOpened, this, &AccountDialog::walletOpenedForLoading); + } else { + passwordEdit->setPlaceholderText(i18n("Wallet disabled in system settings")); + } + passwordEdit->setEnabled(false); + passwordLabel->setEnabled(false); +} + +void AccountDialog::walletOpenedForLoading(bool success) +{ + if (success) { + if (mWallet->isOpen()) { + passwordEdit->setEnabled(true); + passwordLabel->setEnabled(true); + } + if (mWallet->isOpen() && mWallet->hasFolder(QStringLiteral("pop3"))) { + QString password; + mWallet->setFolder(QStringLiteral("pop3")); + mWallet->readPassword(mParentResource->identifier(), password); + passwordEdit->setText(password); + mInitalPassword = password; + } else { + qCWarning(POP3RESOURCE_LOG) << "Wallet not open or doesn't have pop3 folder."; } - mWallet->setFolder( QLatin1String("pop3") ); - mWallet->writePassword( mParentResource->identifier(), passwordEdit->text() ); - } - - mParentResource->clearCachedPassword(); - } - else { - kWarning() << "Wallet not open."; - } - } - else { - // Should we alert the user here? - kWarning() << "Failed to open wallet for saving the password."; - } - - delete mWallet; - mWallet = 0; - accept(); + } else { + qCWarning(POP3RESOURCE_LOG) << "Failed to open wallet for loading the password."; + } + + const bool walletError = !success || !mWallet->isOpen(); + if (walletError) { + passwordEdit->setPlaceholderText(i18n("Unable to open wallet")); + } +} + +void AccountDialog::walletOpenedForSaving(bool success) +{ + if (success) { + if (mWallet && mWallet->isOpen()) { + + // Remove the password from the wallet if the user doesn't want to store it + if (passwordEdit->text().isEmpty() && mWallet->hasFolder(QStringLiteral("pop3"))) { + mWallet->setFolder(QStringLiteral("pop3")); + mWallet->removeEntry(mParentResource->identifier()); + } + + // Store the password in the wallet if the user wants that + else if (!passwordEdit->text().isEmpty()) { + if (!mWallet->hasFolder(QStringLiteral("pop3"))) { + mWallet->createFolder(QStringLiteral("pop3")); + } + mWallet->setFolder(QStringLiteral("pop3")); + mWallet->writePassword(mParentResource->identifier(), passwordEdit->text()); + } + + mParentResource->clearCachedPassword(); + } else { + qCWarning(POP3RESOURCE_LOG) << "Wallet not open."; + } + } else { + // Should we alert the user here? + qCWarning(POP3RESOURCE_LOG) << "Failed to open wallet for saving the password."; + } + + delete mWallet; + mWallet = Q_NULLPTR; + accept(); } void AccountDialog::slotLeaveOnServerClicked() { - const bool state = leaveOnServerCheck->isChecked(); - leaveOnServerDaysCheck->setEnabled( state ); - leaveOnServerCountCheck->setEnabled( state ); - leaveOnServerSizeCheck->setEnabled( state ); - if ( state ) { - if ( leaveOnServerDaysCheck->isChecked() ) { - slotEnableLeaveOnServerDays( state ); - } - if ( leaveOnServerCountCheck->isChecked() ) { - slotEnableLeaveOnServerCount( state ); - } - if ( leaveOnServerSizeCheck->isChecked() ) { - slotEnableLeaveOnServerSize( state ); - } - } else { - slotEnableLeaveOnServerDays( state ); - slotEnableLeaveOnServerCount( state ); - slotEnableLeaveOnServerSize( state ); - } - if ( mServerTest && !mServerTest->capabilities().contains( ServerTest::UIDL ) && - leaveOnServerCheck->isChecked() ) { - KMessageBox::information( topLevelWidget(), - i18n("The server does not seem to support unique " - "message numbers, but this is a " - "requirement for leaving messages on the " - "server.\n" - "Since some servers do not correctly " - "announce their capabilities you still " - "have the possibility to turn leaving " - "fetched messages on the server on.") ); - } + const bool state = leaveOnServerCheck->isChecked(); + leaveOnServerDaysCheck->setEnabled(state); + leaveOnServerCountCheck->setEnabled(state); + leaveOnServerSizeCheck->setEnabled(state); + if (state) { + if (leaveOnServerDaysCheck->isChecked()) { + slotEnableLeaveOnServerDays(state); + } + if (leaveOnServerCountCheck->isChecked()) { + slotEnableLeaveOnServerCount(state); + } + if (leaveOnServerSizeCheck->isChecked()) { + slotEnableLeaveOnServerSize(state); + } + } else { + slotEnableLeaveOnServerDays(state); + slotEnableLeaveOnServerCount(state); + slotEnableLeaveOnServerSize(state); + } + if (mServerTest && !mServerTest->capabilities().contains(ServerTest::UIDL) && + leaveOnServerCheck->isChecked()) { + KMessageBox::information(topLevelWidget(), + i18n("The server does not seem to support unique " + "message numbers, but this is a " + "requirement for leaving messages on the " + "server.\n" + "Since some servers do not correctly " + "announce their capabilities you still " + "have the possibility to turn leaving " + "fetched messages on the server on.")); + } } void AccountDialog::slotFilterOnServerClicked() { - if ( mServerTest && !mServerTest->capabilities().contains( ServerTest::Top ) && - filterOnServerCheck->isChecked() ) { - KMessageBox::information( topLevelWidget(), - i18n("The server does not seem to support " - "fetching message headers, but this is a " - "requirement for filtering messages on the " - "server.\n" - "Since some servers do not correctly " - "announce their capabilities you still " - "have the possibility to turn filtering " - "messages on the server on.") ); - } + if (mServerTest && !mServerTest->capabilities().contains(ServerTest::Top) && + filterOnServerCheck->isChecked()) { + KMessageBox::information(topLevelWidget(), + i18n("The server does not seem to support " + "fetching message headers, but this is a " + "requirement for filtering messages on the " + "server.\n" + "Since some servers do not correctly " + "announce their capabilities you still " + "have the possibility to turn filtering " + "messages on the server on.")); + } } void AccountDialog::slotPipeliningClicked() { - if (usePipeliningCheck->isChecked()) - KMessageBox::information( topLevelWidget(), - i18n("Please note that this feature can cause some POP3 servers " - "that do not support pipelining to send corrupted mail;\n" - "this is configurable, though, because some servers support pipelining " - "but do not announce their capabilities. To check whether your POP3 server " - "announces pipelining support use the \"Check What the Server " - "Supports\" button at the bottom of the dialog;\n" - "if your server does not announce it, but you want more speed, then " - "you should do some testing first by sending yourself a batch " - "of mail and downloading it."), QString(), - QLatin1String("pipelining")); -} + if (usePipeliningCheck->isChecked()) + KMessageBox::information(topLevelWidget(), + i18n("Please note that this feature can cause some POP3 servers " + "that do not support pipelining to send corrupted mail;\n" + "this is configurable, though, because some servers support pipelining " + "but do not announce their capabilities. To check whether your POP3 server " + "announces pipelining support use the \"Check What the Server " + "Supports\" button at the bottom of the dialog;\n" + "if your server does not announce it, but you want more speed, then " + "you should do some testing first by sending yourself a batch " + "of mail and downloading it."), QString(), + QStringLiteral("pipelining")); +} + +void AccountDialog::slotPopEncryptionChanged(int id) +{ + qCDebug(POP3RESOURCE_LOG) << "setting port"; + // adjust port + if (id == Transport::EnumEncryption::SSL || portEdit->value() == 995) { + portEdit->setValue((id == Transport::EnumEncryption::SSL) ? 995 : 110); + } + qCDebug(POP3RESOURCE_LOG) << "port set "; + enablePopFeatures(); // removes invalid auth options from the combobox +} -void AccountDialog::slotPopEncryptionChanged( int id ) -{ - kDebug() << "setting port"; - // adjust port - if ( id == Transport::EnumEncryption::SSL || portEdit->value() == 995 ) - portEdit->setValue( ( id == Transport::EnumEncryption::SSL ) ? 995 : 110 ); +void AccountDialog::slotCheckPopCapabilities() +{ + if (hostEdit->text().isEmpty()) { + KMessageBox::sorry(this, i18n("Please specify a server and port on " + "the General tab first.")); + return; + } + delete mServerTest; + mServerTest = new ServerTest(this); + BusyCursorHelper *busyCursorHelper = new BusyCursorHelper(mServerTest); + mServerTest->setProgressBar(checkCapabilitiesProgress); + mOkButton->setEnabled(false); + checkCapabilitiesStack->setCurrentIndex(1); + Transport::EnumEncryption::type encryptionType; + if (encryptionSSL->isChecked()) { + encryptionType = Transport::EnumEncryption::SSL; + } else { + encryptionType = Transport::EnumEncryption::None; + } + mServerTest->setPort(encryptionType, portEdit->value()); + mServerTest->setServer(hostEdit->text()); + mServerTest->setProtocol(QStringLiteral("pop")); + connect(mServerTest, &MailTransport::ServerTest::finished, this, &AccountDialog::slotPopCapabilities); + connect(mServerTest, &MailTransport::ServerTest::finished, busyCursorHelper, &BusyCursorHelper::deleteLater); - kDebug() << "port set "; - enablePopFeatures(); // removes invalid auth options from the combobox + mServerTest->start(); + mServerTestFailed = false; } -void AccountDialog::slotCheckPopCapabilities() +void AccountDialog::slotPopCapabilities(const QList &encryptionTypes) { - if ( hostEdit->text().isEmpty() ) - { - KMessageBox::sorry( this, i18n( "Please specify a server and port on " - "the General tab first." ) ); - return; - } - delete mServerTest; - mServerTest = new ServerTest( this ); - BusyCursorHelper *busyCursorHelper = new BusyCursorHelper( mServerTest ); - mServerTest->setProgressBar( checkCapabilitiesProgress ); - enableButtonOk( false ); - checkCapabilitiesStack->setCurrentIndex( 1 ); - Transport::EnumEncryption::type encryptionType; - if ( encryptionSSL->isChecked() ) - encryptionType = Transport::EnumEncryption::SSL; - else - encryptionType = Transport::EnumEncryption::None; - mServerTest->setPort( encryptionType, portEdit->value() ); - mServerTest->setServer( hostEdit->text() ); - mServerTest->setProtocol( QLatin1String("pop") ); - connect( mServerTest, SIGNAL(finished(QList)), - this, SLOT(slotPopCapabilities(QList)) ); - connect( mServerTest, SIGNAL(finished(QList)), - busyCursorHelper, SLOT(deleteLater()) ); - - mServerTest->start(); - mServerTestFailed = false; -} - -void AccountDialog::slotPopCapabilities( const QList &encryptionTypes ) -{ - checkCapabilitiesStack->setCurrentIndex( 0 ); - enableButtonOk( true ); - - // if both fail, popup a dialog - if ( !mServerTest->isNormalPossible() && !mServerTest->isSecurePossible() ) - KMessageBox::sorry( this, i18n( "Unable to connect to the server, please verify the server address." ) ); - - // If the servertest did not find any useable authentication modes, assume the - // connection failed and don't disable any of the radioboxes. - if ( encryptionTypes.isEmpty() ) { - mServerTestFailed = true; - return; - } - - encryptionNone->setEnabled( encryptionTypes.contains( Transport::EnumEncryption::None ) ); - encryptionSSL->setEnabled( encryptionTypes.contains( Transport::EnumEncryption::SSL ) ); - encryptionTLS->setEnabled( encryptionTypes.contains( Transport::EnumEncryption::TLS ) ); + checkCapabilitiesStack->setCurrentIndex(0); + mOkButton->setEnabled(true); - usePipeliningCheck->setChecked( mServerTest->capabilities().contains( ServerTest::Pipelining ) ); + // if both fail, popup a dialog + if (!mServerTest->isNormalPossible() && !mServerTest->isSecurePossible()) { + KMessageBox::sorry(this, i18n("Unable to connect to the server, please verify the server address.")); + } - checkHighest( encryptionButtonGroup ); -} + // If the servertest did not find any useable authentication modes, assume the + // connection failed and don't disable any of the radioboxes. + if (encryptionTypes.isEmpty()) { + mServerTestFailed = true; + return; + } + encryptionNone->setEnabled(encryptionTypes.contains(Transport::EnumEncryption::None)); + encryptionSSL->setEnabled(encryptionTypes.contains(Transport::EnumEncryption::SSL)); + encryptionTLS->setEnabled(encryptionTypes.contains(Transport::EnumEncryption::TLS)); + + usePipeliningCheck->setChecked(mServerTest->capabilities().contains(ServerTest::Pipelining)); + + checkHighest(encryptionButtonGroup); +} void AccountDialog::enablePopFeatures() { - if ( !mServerTest || mServerTestFailed ) - return; + if (!mServerTest || mServerTestFailed) { + return; + } - QList supportedAuths; - if ( encryptionButtonGroup->checkedId() == Transport::EnumEncryption::None ) - supportedAuths = mServerTest->normalProtocols(); - if ( encryptionButtonGroup->checkedId() == Transport::EnumEncryption::SSL ) - supportedAuths = mServerTest->secureProtocols(); - if ( encryptionButtonGroup->checkedId() == Transport::EnumEncryption::TLS ) - supportedAuths = mServerTest->tlsProtocols(); - - authCombo->clear(); - foreach( int prot, supportedAuths ) { - authCombo->addItem( Transport::authenticationTypeString( prot ) , prot ); - } - - if ( mServerTest && !mServerTest->capabilities().contains( ServerTest::Pipelining ) && - usePipeliningCheck->isChecked() ) { - usePipeliningCheck->setChecked( false ); - KMessageBox::information( topLevelWidget(), - i18n("The server does not seem to support " - "pipelining; therefore, this option has " - "been disabled.\n" - "Since some servers do not correctly " - "announce their capabilities you still " - "have the possibility to turn pipelining " - "on. But please note that this feature can " - "cause some POP servers that do not " - "support pipelining to send corrupt " - "messages. So before using this feature " - "with important mail you should first " - "test it by sending yourself a larger " - "number of test messages which you all " - "download in one go from the POP " - "server.") ); - } - - if ( mServerTest && !mServerTest->capabilities().contains( ServerTest::UIDL ) && - leaveOnServerCheck->isChecked() ) { - leaveOnServerCheck->setChecked( false ); - KMessageBox::information( topLevelWidget(), - i18n("The server does not seem to support unique " - "message numbers, but this is a " - "requirement for leaving messages on the " - "server; therefore, this option has been " - "disabled.\n" - "Since some servers do not correctly " - "announce their capabilities you still " - "have the possibility to turn leaving " - "fetched messages on the server on.") ); - } - - if ( mServerTest && !mServerTest->capabilities().contains( ServerTest::Top ) && - filterOnServerCheck->isChecked() ) { - filterOnServerCheck->setChecked( false ); - KMessageBox::information( topLevelWidget(), - i18n("The server does not seem to support " - "fetching message headers, but this is a " - "requirement for filtering messages on the " - "server; therefore, this option has been " - "disabled.\n" - "Since some servers do not correctly " - "announce their capabilities you still " - "have the possibility to turn filtering " - "messages on the server on.") ); - } + QList supportedAuths; + if (encryptionButtonGroup->checkedId() == Transport::EnumEncryption::None) { + supportedAuths = mServerTest->normalProtocols(); + } + if (encryptionButtonGroup->checkedId() == Transport::EnumEncryption::SSL) { + supportedAuths = mServerTest->secureProtocols(); + } + if (encryptionButtonGroup->checkedId() == Transport::EnumEncryption::TLS) { + supportedAuths = mServerTest->tlsProtocols(); + } + + authCombo->clear(); + foreach (int prot, supportedAuths) { + authCombo->addItem(Transport::authenticationTypeString(prot) , prot); + } + + if (mServerTest && !mServerTest->capabilities().contains(ServerTest::Pipelining) && + usePipeliningCheck->isChecked()) { + usePipeliningCheck->setChecked(false); + KMessageBox::information(topLevelWidget(), + i18n("The server does not seem to support " + "pipelining; therefore, this option has " + "been disabled.\n" + "Since some servers do not correctly " + "announce their capabilities you still " + "have the possibility to turn pipelining " + "on. But please note that this feature can " + "cause some POP servers that do not " + "support pipelining to send corrupt " + "messages. So before using this feature " + "with important mail you should first " + "test it by sending yourself a larger " + "number of test messages which you all " + "download in one go from the POP " + "server.")); + } + + if (mServerTest && !mServerTest->capabilities().contains(ServerTest::UIDL) && + leaveOnServerCheck->isChecked()) { + leaveOnServerCheck->setChecked(false); + KMessageBox::information(topLevelWidget(), + i18n("The server does not seem to support unique " + "message numbers, but this is a " + "requirement for leaving messages on the " + "server; therefore, this option has been " + "disabled.\n" + "Since some servers do not correctly " + "announce their capabilities you still " + "have the possibility to turn leaving " + "fetched messages on the server on.")); + } + + if (mServerTest && !mServerTest->capabilities().contains(ServerTest::Top) && + filterOnServerCheck->isChecked()) { + filterOnServerCheck->setChecked(false); + KMessageBox::information(topLevelWidget(), + i18n("The server does not seem to support " + "fetching message headers, but this is a " + "requirement for filtering messages on the " + "server; therefore, this option has been " + "disabled.\n" + "Since some servers do not correctly " + "announce their capabilities you still " + "have the possibility to turn filtering " + "messages on the server on.")); + } } -static void addAuthenticationItem( QComboBox *combo, - int authenticationType ) +static void addAuthenticationItem(QComboBox *combo, + int authenticationType) { - combo->addItem( Transport::authenticationTypeString( authenticationType ), - QVariant( authenticationType ) ); + combo->addItem(Transport::authenticationTypeString(authenticationType), + QVariant(authenticationType)); } void AccountDialog::populateDefaultAuthenticationOptions() { - authCombo->clear(); - addAuthenticationItem( authCombo, Transport::EnumAuthenticationType::CLEAR ); - addAuthenticationItem( authCombo, Transport::EnumAuthenticationType::LOGIN ); - addAuthenticationItem( authCombo, Transport::EnumAuthenticationType::PLAIN ); - addAuthenticationItem( authCombo, Transport::EnumAuthenticationType::CRAM_MD5 ); - addAuthenticationItem( authCombo, Transport::EnumAuthenticationType::DIGEST_MD5 ); - addAuthenticationItem( authCombo, Transport::EnumAuthenticationType::NTLM ); - addAuthenticationItem( authCombo, Transport::EnumAuthenticationType::GSSAPI ); - addAuthenticationItem( authCombo, Transport::EnumAuthenticationType::APOP ); + authCombo->clear(); + addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::CLEAR); + addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::LOGIN); + addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::PLAIN); + addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::CRAM_MD5); + addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::DIGEST_MD5); + addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::NTLM); + addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::GSSAPI); + addAuthenticationItem(authCombo, Transport::EnumAuthenticationType::APOP); } - -void AccountDialog::slotLeaveOnServerDaysChanged ( int value ) +void AccountDialog::slotLeaveOnServerDaysChanged(int value) { - leaveOnServerDaysSpin->setSuffix( i18np(" day", " days", value) ); + leaveOnServerDaysSpin->setSuffix(i18np(" day", " days", value)); } - -void AccountDialog::slotLeaveOnServerCountChanged ( int value ) +void AccountDialog::slotLeaveOnServerCountChanged(int value) { - leaveOnServerCountSpin->setSuffix( i18np(" message", " messages", value) ); + leaveOnServerCountSpin->setSuffix(i18np(" message", " messages", value)); } - -void AccountDialog::slotFilterOnServerSizeChanged ( int value ) +void AccountDialog::slotFilterOnServerSizeChanged(int value) { - filterOnServerSizeSpin->setSuffix( i18np(" byte", " bytes", value) ); + filterOnServerSizeSpin->setSuffix(i18np(" byte", " bytes", value)); } -void AccountDialog::checkHighest( QButtonGroup *btnGroup ) +void AccountDialog::checkHighest(QButtonGroup *btnGroup) { - QListIterator it( btnGroup->buttons() ); - it.toBack(); - while ( it.hasPrevious() ) { - QAbstractButton *btn = it.previous(); - if ( btn && btn->isEnabled() ) { - btn->animateClick(); - return; + QListIterator it(btnGroup->buttons()); + it.toBack(); + while (it.hasPrevious()) { + QAbstractButton *btn = it.previous(); + if (btn && btn->isEnabled()) { + btn->animateClick(); + return; + } } - } } -void AccountDialog::slotButtonClicked( int button ) +void AccountDialog::slotAccepted() { - switch( button ) { - case Ok: saveSettings(); - // Don't call accept() yet, saveSettings() triggers an asnychronous wallet operation, // which will call accept() when it is finished - break; - case Cancel: - reject(); - return; - } } void AccountDialog::saveSettings() { - mParentResource->setName( nameEdit->text() ); + mParentResource->setName(nameEdit->text()); - Settings::self()->setIntervalCheckEnabled( intervalCheck->checkState() == Qt::Checked ); - Settings::self()->setIntervalCheckInterval( intervalSpin->value() ); - Settings::self()->setHost( hostEdit->text().trimmed() ); - Settings::self()->setPort( portEdit->value() ); - Settings::self()->setLogin( loginEdit->text().trimmed() ); - Settings::self()->setPrecommand( precommand->text() ); - Settings::self()->setUseSSL( encryptionSSL->isChecked() ); - Settings::self()->setUseTLS( encryptionTLS->isChecked() ); - Settings::self()->setAuthenticationMethod( authCombo->itemData( authCombo->currentIndex() ).toInt() ); - Settings::self()->setPipelining( usePipeliningCheck->isChecked() ); - Settings::self()->setLeaveOnServer( leaveOnServerCheck->isChecked() ); - Settings::self()->setLeaveOnServerDays( leaveOnServerCheck->isChecked() ? - ( leaveOnServerDaysCheck->isChecked() ? - leaveOnServerDaysSpin->value() : -1 ) : 0); - Settings::self()->setLeaveOnServerCount( leaveOnServerCheck->isChecked() ? - ( leaveOnServerCountCheck->isChecked() ? - leaveOnServerCountSpin->value() : -1 ) : 0 ); - Settings::self()->setLeaveOnServerSize( leaveOnServerCheck->isChecked() ? - ( leaveOnServerSizeCheck->isChecked() ? - leaveOnServerSizeSpin->value() : -1 ) : 0 ); - Settings::self()->setFilterOnServer( filterOnServerCheck->isChecked() ); - Settings::self()->setFilterCheckSize (filterOnServerSizeSpin->value() ); - Settings::self()->setTargetCollection( folderRequester->collection().id() ); - Settings::self()->writeConfig(); - - // Now, either save the password or delete it from the wallet. For both, we need - // to open it. - const bool userChangedPassword = mInitalPassword != passwordEdit->text(); - const bool userWantsToDeletePassword = - passwordEdit->text().isEmpty() && userChangedPassword; - - if ( ( !passwordEdit->text().isEmpty() && userChangedPassword ) || - userWantsToDeletePassword ) { - kDebug() << mWallet << mWallet->isOpen(); - if ( mWallet && mWallet->isOpen() ) { - // wallet is already open - walletOpenedForSaving( true ); + Settings::self()->setIntervalCheckEnabled(intervalCheck->checkState() == Qt::Checked); + Settings::self()->setIntervalCheckInterval(intervalSpin->value()); + Settings::self()->setHost(hostEdit->text().trimmed()); + Settings::self()->setPort(portEdit->value()); + Settings::self()->setLogin(loginEdit->text().trimmed()); + Settings::self()->setPrecommand(precommand->text()); + Settings::self()->setUseSSL(encryptionSSL->isChecked()); + Settings::self()->setUseTLS(encryptionTLS->isChecked()); + Settings::self()->setAuthenticationMethod(authCombo->itemData(authCombo->currentIndex()).toInt()); + Settings::self()->setPipelining(usePipeliningCheck->isChecked()); + Settings::self()->setLeaveOnServer(leaveOnServerCheck->isChecked()); + Settings::self()->setLeaveOnServerDays(leaveOnServerCheck->isChecked() ? + (leaveOnServerDaysCheck->isChecked() ? + leaveOnServerDaysSpin->value() : -1) : 0); + Settings::self()->setLeaveOnServerCount(leaveOnServerCheck->isChecked() ? + (leaveOnServerCountCheck->isChecked() ? + leaveOnServerCountSpin->value() : -1) : 0); + Settings::self()->setLeaveOnServerSize(leaveOnServerCheck->isChecked() ? + (leaveOnServerSizeCheck->isChecked() ? + leaveOnServerSizeSpin->value() : -1) : 0); + Settings::self()->setFilterOnServer(filterOnServerCheck->isChecked()); + Settings::self()->setFilterCheckSize(filterOnServerSizeSpin->value()); + Settings::self()->setTargetCollection(folderRequester->collection().id()); + Settings::self()->save(); + + // Now, either save the password or delete it from the wallet. For both, we need + // to open it. + const bool userChangedPassword = mInitalPassword != passwordEdit->text(); + const bool userWantsToDeletePassword = + passwordEdit->text().isEmpty() && userChangedPassword; + + if ((!passwordEdit->text().isEmpty() && userChangedPassword) || + userWantsToDeletePassword) { + qCDebug(POP3RESOURCE_LOG) << mWallet << mWallet->isOpen(); + if (mWallet && mWallet->isOpen()) { + // wallet is already open + walletOpenedForSaving(true); + } else { + // we need to open the wallet + qCDebug(POP3RESOURCE_LOG) << "we need to open the wallet"; + mWallet = Wallet::openWallet(Wallet::NetworkWallet(), winId(), + Wallet::Asynchronous); + if (mWallet) { + connect(mWallet, &KWallet::Wallet::walletOpened, this, &AccountDialog::walletOpenedForSaving); + } else { + accept(); + } + } } else { - // we need to open the wallet - kDebug() << "we need to open the wallet"; - mWallet = Wallet::openWallet( Wallet::NetworkWallet(), winId(), - Wallet::Asynchronous ); - if ( mWallet ) { - connect( mWallet, SIGNAL(walletOpened(bool)), - this, SLOT(walletOpenedForSaving(bool)) ); - } else { accept(); - } } - } - else { - accept(); - } -} - -void AccountDialog::slotEnableLeaveOnServerDays( bool state ) -{ - if ( state && !leaveOnServerDaysCheck->isEnabled() ) - return; - leaveOnServerDaysSpin->setEnabled( state ); } -void AccountDialog::slotEnableLeaveOnServerCount( bool state ) +void AccountDialog::slotEnableLeaveOnServerDays(bool state) { - if ( state && !leaveOnServerCountCheck->isEnabled() ) - return; - leaveOnServerCountSpin->setEnabled( state ); - return; + if (state && !leaveOnServerDaysCheck->isEnabled()) { + return; + } + leaveOnServerDaysSpin->setEnabled(state); } -void AccountDialog::slotEnableLeaveOnServerSize( bool state ) +void AccountDialog::slotEnableLeaveOnServerCount(bool state) { - if ( state && !leaveOnServerSizeCheck->isEnabled() ) - return; - leaveOnServerSizeSpin->setEnabled( state ); - return; + if (state && !leaveOnServerCountCheck->isEnabled()) { + return; + } + leaveOnServerCountSpin->setEnabled(state); } -void AccountDialog::slotEnablePopInterval( bool state ) +void AccountDialog::slotEnableLeaveOnServerSize(bool state) { - intervalSpin->setEnabled( state ); - intervalLabel->setEnabled( state ); + if (state && !leaveOnServerSizeCheck->isEnabled()) { + return; + } + leaveOnServerSizeSpin->setEnabled(state); } -void AccountDialog::slotFontChanged( void ) +void AccountDialog::slotEnablePopInterval(bool state) { - QFont titleFont( titleLabel->font() ); - titleFont.setBold( true ); - titleLabel->setFont(titleFont); + intervalSpin->setEnabled(state); + intervalLabel->setEnabled(state); } -void AccountDialog::targetCollectionReceived( Akonadi::Collection::List collections ) +void AccountDialog::targetCollectionReceived(Akonadi::Collection::List collections) { - folderRequester->setCollection( collections.first() ); + folderRequester->setCollection(collections.first()); } -void AccountDialog::localFolderRequestJobFinished( KJob *job ) +void AccountDialog::localFolderRequestJobFinished(KJob *job) { - if ( !job->error() ) { - Collection targetCollection = SpecialMailCollections::self()->defaultCollection( SpecialMailCollections::Inbox ); - Q_ASSERT( targetCollection.isValid() ); - folderRequester->setCollection( targetCollection ); - } + if (!job->error()) { + Collection targetCollection = SpecialMailCollections::self()->defaultCollection(SpecialMailCollections::Inbox); + Q_ASSERT(targetCollection.isValid()); + folderRequester->setCollection(targetCollection); + } } diff -Nru kdepim-runtime-4.14.6/resources/pop3/accountdialog.h kdepim-runtime-15.08.0/resources/pop3/accountdialog.h --- kdepim-runtime-4.14.6/resources/pop3/accountdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/accountdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -25,54 +25,55 @@ #include "ui_popsettings.h" -namespace MailTransport { +namespace MailTransport +{ class ServerTest; } -namespace KWallet { - class Wallet; +namespace KWallet +{ +class Wallet; } class POP3Resource; class KJob; -class AccountDialog : public KDialog, private Ui::PopPage +class AccountDialog : public QDialog, private Ui::PopPage { - Q_OBJECT + Q_OBJECT - public: - AccountDialog( POP3Resource *parentResource, WId parentWindow ); +public: + AccountDialog(POP3Resource *parentResource, WId parentWindow); virtual ~AccountDialog(); - private slots: - virtual void slotButtonClicked( int button ); - void slotEnablePopInterval( bool state ); - void slotFontChanged(); +private Q_SLOTS: + void slotEnablePopInterval(bool state); void slotLeaveOnServerClicked(); - void slotEnableLeaveOnServerDays( bool state ); - void slotEnableLeaveOnServerCount( bool state ); - void slotEnableLeaveOnServerSize( bool state ); + void slotEnableLeaveOnServerDays(bool state); + void slotEnableLeaveOnServerCount(bool state); + void slotEnableLeaveOnServerSize(bool state); void slotFilterOnServerClicked(); void slotPipeliningClicked(); void slotPopEncryptionChanged(int); void slotCheckPopCapabilities(); - void slotPopCapabilities(const QList & ); - void slotLeaveOnServerDaysChanged( int value ); - void slotLeaveOnServerCountChanged( int value ); - void slotFilterOnServerSizeChanged( int value ); - - void targetCollectionReceived( Akonadi::Collection::List collections ); - void localFolderRequestJobFinished( KJob *job ); - void walletOpenedForLoading( bool success ); - void walletOpenedForSaving( bool success ); - private: + void slotPopCapabilities(const QList &); + void slotLeaveOnServerDaysChanged(int value); + void slotLeaveOnServerCountChanged(int value); + void slotFilterOnServerSizeChanged(int value); + + void targetCollectionReceived(Akonadi::Collection::List collections); + void localFolderRequestJobFinished(KJob *job); + void walletOpenedForLoading(bool success); + void walletOpenedForSaving(bool success); + void slotAccepted(); +private: void setupWidgets(); void loadSettings(); void saveSettings(); - void checkHighest( QButtonGroup * ); + void checkHighest(QButtonGroup *); void enablePopFeatures(); void populateDefaultAuthenticationOptions(); - private: +private: POP3Resource *mParentResource; QButtonGroup *encryptionButtonGroup; MailTransport::ServerTest *mServerTest; @@ -80,6 +81,7 @@ bool mServerTestFailed; KWallet::Wallet *mWallet; QString mInitalPassword; + QPushButton *mOkButton; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/pop3/autotests/CMakeLists.txt kdepim-runtime-15.08.0/resources/pop3/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/pop3/autotests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/autotests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,55 @@ +set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${Boost_INCLUDE_DIR} + ${AKONADI_INCLUDE_DIR} +) + +# Stolen from kdepimlibs/akonadi/tests +kde_enable_exceptions() + +macro(add_akonadi_isolated_test _source) + get_filename_component(_targetName ${_source} NAME_WE) + set(_srcList ${_source} fakeserver/fakeserver.cpp) + + kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/../settings.kcfg org.kde.Akonadi.POP3.Settings) + set(pop3settingsinterface_xml ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.POP3.Settings.xml) + kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/../../maildir/maildirresource.kcfg org.kde.Akonadi.Maildir.Settings) + set(maildirsettingsinterface_xml ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.Maildir.Settings.xml) + set_source_files_properties(${pop3settingsinterface_xml} PROPERTIES INCLUDE "../metatype.h") + qt5_add_dbus_interface(_srcList ${pop3settingsinterface_xml} pop3settings) + qt5_add_dbus_interface(_srcList ${maildirsettingsinterface_xml} maildirsettings) + # add the dbus interace to every test (easier than adding to particular tests only) + #qt5_add_dbus_interface(_srcList ../org.kde.krss.xml krssinterface) + + add_executable(${_targetName} ${_srcList}) + target_link_libraries(${_targetName} + Qt5::Test + KF5::AkonadiCore + KF5::Mime + Qt5::Network + Qt5::Widgets + Qt5::DBus + ) + + # based on kde4_add_unit_test + if (WIN32) + get_target_property( _loc ${_targetName} LOCATION ) + set(_executable ${_loc}.bat) + else () + set(_executable ${EXECUTABLE_OUTPUT_PATH}/${_targetName}) + endif () + if (UNIX) + set(_executable ${_executable}.shell) + endif () + + find_program(_testrunner akonaditest) + + if (KDEPIM_RUN_ISOLATED_TESTS) + add_test( ${_targetName} ${_testrunner} -c ${CMAKE_CURRENT_SOURCE_DIR}/unittestenv/config.xml ${_executable} ) + endif () +endmacro(add_akonadi_isolated_test) + +add_akonadi_isolated_test(pop3test.cpp) diff -Nru kdepim-runtime-4.14.6/resources/pop3/autotests/fakeserver/fakeserver.cpp kdepim-runtime-15.08.0/resources/pop3/autotests/fakeserver/fakeserver.cpp --- kdepim-runtime-4.14.6/resources/pop3/autotests/fakeserver/fakeserver.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/autotests/fakeserver/fakeserver.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,293 @@ +/* + Copyright (C) 2008 Omat Holding B.V. + Copyright (C) 2009 Thomas McGuire + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +// Own +#include "fakeserver.h" + +// Qt +#include +#include + +FakeServerThread::FakeServerThread(QObject *parent) + : QThread(parent), + mServer(Q_NULLPTR) +{ +} + +void FakeServerThread::run() +{ + mServer = new FakeServer(); + + // Run forever, until someone from the outside calls quit() on us and quits the + // event loop + exec(); + + delete mServer; + mServer = Q_NULLPTR; +} + +FakeServer *FakeServerThread::server() const +{ + Q_ASSERT(mServer != 0); + return mServer; +} + +FakeServer::FakeServer(QObject *parent) + : QObject(parent), + mConnections(0), + mProgress(0), + mGotDisconnected(false) +{ + mTcpServer = new QTcpServer(); + if (!mTcpServer->listen(QHostAddress(QHostAddress::LocalHost), 5989)) { + qCritical() << "Unable to start the server"; + } + + connect(mTcpServer, &QTcpServer::newConnection, this, &FakeServer::newConnection); +} + +FakeServer::~FakeServer() +{ + if (mConnections > 0) { + disconnect(mTcpServerConnection, &QTcpSocket::readyRead, this, &FakeServer::dataAvailable); + } + + delete mTcpServer; + mTcpServer = Q_NULLPTR; +} + +QByteArray FakeServer::parseDeleteMark(const QByteArray &expectedData, + const QByteArray &dataReceived) +{ + // Only called from parseResponse(), which is already thread-safe + + const QByteArray deleteMark = QString::fromLatin1("%DELE%").toUtf8(); + if (expectedData.contains(deleteMark)) { + Q_ASSERT(!mAllowedDeletions.isEmpty()); + for (int i = 0; i < mAllowedDeletions.size(); i++) { + QByteArray substituted = expectedData; + substituted = substituted.replace(deleteMark, mAllowedDeletions[i]); + if (substituted == dataReceived) { + mAllowedDeletions.removeAt(i); + return substituted; + } + } + qWarning() << "Received:" << dataReceived.data() + << "\nExpected:" << expectedData.data(); + Q_ASSERT_X(false, "FakeServer::parseDeleteMark", "Unable to substitute data!"); + return QByteArray(); + } else { + return expectedData; + } +} + +QByteArray FakeServer::parseRetrMark(const QByteArray &expectedData, + const QByteArray &dataReceived) +{ + // Only called from parseResponse(), which is already thread-safe + + const QByteArray retrMark = QString::fromLatin1("%RETR%").toUtf8(); + if (expectedData.contains(retrMark)) { + Q_ASSERT(!mAllowedRetrieves.isEmpty()); + for (int i = 0; i < mAllowedRetrieves.size(); i++) { + QByteArray substituted = expectedData; + substituted = substituted.replace(retrMark, mAllowedRetrieves[i]); + if (substituted == dataReceived) { + mAllowedRetrieves.removeAt(i); + return substituted; + } + } + qWarning() << "Received:" << dataReceived.data() + << "\nExpected:" << expectedData.data(); + Q_ASSERT_X(false, "FakeServer::parseRetrMark", "Unable to substitute data!"); + return QByteArray(); + } else { + return expectedData; + } +} + +QByteArray FakeServer::parseResponse(const QByteArray &expectedData, + const QByteArray &dataReceived) +{ + // Only called from dataAvailable, which is already thread-safe + + QByteArray result; + result = parseDeleteMark(expectedData, dataReceived); + if (result != expectedData) { + return result; + } else { + return parseRetrMark(expectedData, dataReceived); + } +} + +/* +// Used only for the debug output in dataAvailable() +static QByteArray removeCRLF( const QByteArray &ba ) +{ + QByteArray returnArray = ba; + returnArray.replace( "\r\n", QByteArray() ); + return returnArray; +} +*/ + +void FakeServer::dataAvailable() +{ + QMutexLocker locker(&mMutex); + mProgress++; + + // We got data, so we better expect it and have an answer! + Q_ASSERT(!mReadData.isEmpty()); + Q_ASSERT(!mWriteData.isEmpty()); + + const QByteArray data = mTcpServerConnection->readAll(); + //qDebug() << "Got data:" << removeCRLF( data ); + const QByteArray expected(mReadData.takeFirst()); + //qDebug() << "Expected data:" << removeCRLF( expected ); + const QByteArray reallyExpected = parseResponse(expected, data); + //qDebug() << "Really expected:" << removeCRLF( reallyExpected ); + + Q_ASSERT(data == reallyExpected); + + QByteArray toWrite = mWriteData.takeFirst(); + //qDebug() << "Going to write data:" << removeCRLF( toWrite ); + const bool allWritten = mTcpServerConnection->write(toWrite) == toWrite.size(); + Q_ASSERT(allWritten); + Q_UNUSED(allWritten); + const bool flushed = mTcpServerConnection->flush(); + Q_ASSERT(flushed); + Q_UNUSED(flushed); +} + +void FakeServer::newConnection() +{ + QMutexLocker locker(&mMutex); + Q_ASSERT(mConnections == 0); + mConnections++; + mGotDisconnected = false; + + mTcpServerConnection = mTcpServer->nextPendingConnection(); + mTcpServerConnection->write(QByteArray("+OK Initech POP3 server ready.\r\n")); + connect(mTcpServerConnection, &QTcpSocket::readyRead, this, &FakeServer::dataAvailable); + connect(mTcpServerConnection, &QTcpSocket::disconnected, this, &FakeServer::slotDisconnected); +} + +void FakeServer::slotDisconnected() +{ + QMutexLocker locker(&mMutex); + mConnections--; + mGotDisconnected = true; + Q_ASSERT(mConnections == 0); + Q_ASSERT(mAllowedDeletions.isEmpty()); + Q_ASSERT(mAllowedRetrieves.isEmpty()); + Q_ASSERT(mReadData.isEmpty()); + Q_ASSERT(mWriteData.isEmpty()); + Q_EMIT disconnected(); +} + +void FakeServer::setAllowedDeletions(const QString &deleteIds) +{ + QMutexLocker locker(&mMutex); + mAllowedDeletions.clear(); + QStringList ids = deleteIds.split(QLatin1Char(','), QString::SkipEmptyParts); + foreach (const QString &id, ids) { + mAllowedDeletions.append(id.toUtf8()); + } +} + +void FakeServer::setAllowedRetrieves(const QString &retrieveIds) +{ + QMutexLocker locker(&mMutex); + mAllowedRetrieves.clear(); + QStringList ids = retrieveIds.split(QLatin1Char(','), QString::SkipEmptyParts); + foreach (const QString &id, ids) { + mAllowedRetrieves.append(id.toUtf8()); + } +} + +void FakeServer::setMails(const QList &mails) +{ + QMutexLocker locker(&mMutex); + mMails = mails; +} + +void FakeServer::setNextConversation(const QString &conversation, + const QList &exceptions) +{ + QMutexLocker locker(&mMutex); + + Q_ASSERT(mReadData.isEmpty()); + Q_ASSERT(mWriteData.isEmpty()); + Q_ASSERT(!conversation.isEmpty()); + + mGotDisconnected = false; + QStringList lines = conversation.split(QLatin1String("\r\n"), QString::SkipEmptyParts); + Q_ASSERT(lines.first().startsWith(QLatin1String("C:"))); + + enum Mode { Client, Server }; + Mode mode = Client; + + const QByteArray mailSizeMarker = QString::fromLatin1("%MAILSIZE%").toLatin1(); + const QByteArray mailMarker = QString::fromLatin1("%MAIL%").toLatin1(); + int sizeIndex = 0; + int mailIndex = 0; + + foreach (const QString &line, lines) { + + QByteArray lineData(line.toUtf8()); + + if (lineData.contains(mailSizeMarker)) { + Q_ASSERT(mMails.size() > sizeIndex); + lineData.replace(mailSizeMarker, + QString::number(mMails[sizeIndex++].size()).toLatin1()); + } + if (lineData.contains(mailMarker)) { + while (exceptions.contains(mailIndex + 1)) { + mailIndex++; + } + Q_ASSERT(mMails.size() > mailIndex); + lineData.replace(mailMarker, mMails[mailIndex++]); + } + + if (lineData.startsWith("S: ")) { + mWriteData.append(lineData.mid(3) + "\r\n"); + mode = Server; + } else if (line.startsWith(QLatin1String("C: "))) { + mReadData.append(lineData.mid(3) + "\r\n"); + mode = Client; + } else { + switch (mode) { + case Server: mWriteData.last() += (lineData + "\r\n"); break; + case Client: mReadData.last() += (lineData + "\r\n"); break; + } + } + } +} + +int FakeServer::progress() const +{ + QMutexLocker locker(&mMutex); + return mProgress; +} + +bool FakeServer::gotDisconnected() const +{ + QMutexLocker locker(&mMutex); + return mGotDisconnected; +} + diff -Nru kdepim-runtime-4.14.6/resources/pop3/autotests/fakeserver/fakeserver.h kdepim-runtime-15.08.0/resources/pop3/autotests/fakeserver/fakeserver.h --- kdepim-runtime-4.14.6/resources/pop3/autotests/fakeserver/fakeserver.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/autotests/fakeserver/fakeserver.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,105 @@ +/* + Copyright (C) 2008 Omat Holding B.V. + Copyright (C) 2009 Thomas McGuire + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +#ifndef FAKESERVER_H +#define FAKESERVER_H + +#include +#include +#include +#include + +class FakeServer : public QObject +{ + Q_OBJECT + +public: + FakeServer(QObject *parent = Q_NULLPTR); + ~FakeServer(); + + void setNextConversation(const QString &conversation, + const QList &exceptions = QList()); + void setAllowedDeletions(const QString &deleteIds); + void setAllowedRetrieves(const QString &retrieveIds); + void setMails(const QList &mails); + + // This is kind of a hack: The POP3 test needs to know when the POP3 client + // disconnects from the server. Normally, we could just use a QSignalSpy on the + // disconnected() signal, but that is not thread-safe. Therefore this hack with the + // state variable mGotDisconnected + bool gotDisconnected() const; + + // Returns an integer that is incremented each time the POP3 server receives some + // data + int progress() const; + +Q_SIGNALS: + void disconnected(); + +private Q_SLOTS: + + void newConnection(); + void dataAvailable(); + void slotDisconnected(); + +private: + + QByteArray parseDeleteMark(const QByteArray &expectedData, const QByteArray &dataReceived); + QByteArray parseRetrMark(const QByteArray &expectedData, const QByteArray &dataReceived); + QByteArray parseResponse(const QByteArray &expectedData, const QByteArray &dataReceived); + + QList mReadData; + QList mWriteData; + QList mAllowedDeletions; + QList mAllowedRetrieves; + QList mMails; + QTcpServer *mTcpServer; + QTcpSocket *mTcpServerConnection; + int mConnections; + int mProgress; + bool mGotDisconnected; + + // We use one big mutex to protect everything + // There shouldn't be deadlocks, as there are only 2 places where the functions + // are called: From the KTcpSocket signals, which are triggered by the POP3 ioslave, + // and from the actual test. + mutable QMutex mMutex; +}; + +class FakeServerThread : public QThread +{ + Q_OBJECT + +public: + + explicit FakeServerThread(QObject *parent); + void run() Q_DECL_OVERRIDE; + + // Returns the FakeServer use. Be careful when using this and make sure + // the methods you use are actually thread-safe!! + // This should however be the case because the FakeServer uses one big mutex + // to protect everything. + FakeServer *server() const; + +private: + + FakeServer *mServer; +}; + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/pop3/autotests/pop3test.cpp kdepim-runtime-15.08.0/resources/pop3/autotests/pop3test.cpp --- kdepim-runtime-4.14.6/resources/pop3/autotests/pop3test.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/autotests/pop3test.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,924 @@ +/* Copyright 2009 Thomas McGuire + + 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 ) version 3 or, at the discretion of KDE e.V. + ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "pop3test.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +QTEST_AKONADIMAIN(Pop3Test) + +using namespace Akonadi; + +void Pop3Test::initTestCase() +{ + QVERIFY(Akonadi::Control::start()); + + // switch all resources offline to reduce interference from them + foreach (Akonadi::AgentInstance agent, Akonadi::AgentManager::self()->instances()) { + agent.setIsOnline(false); + } + + /* + qDebug() << "==========================================================="; + qDebug() << "============ Stopping for debugging ======================="; + qDebug() << "==========================================================="; + kill( qApp->applicationPid(), SIGSTOP ); + */ + + // + // Create the maildir and pop3 resources + // + AgentType maildirType = AgentManager::self()->type(QLatin1String("akonadi_maildir_resource")); + AgentInstanceCreateJob *agentCreateJob = new AgentInstanceCreateJob(maildirType); + QVERIFY(agentCreateJob->exec()); + mMaildirIdentifier = agentCreateJob->instance().identifier(); + + AgentType popType = AgentManager::self()->type(QLatin1String("akonadi_pop3_resource")); + agentCreateJob = new AgentInstanceCreateJob(popType); + QVERIFY(agentCreateJob->exec()); + mPop3Identifier = agentCreateJob->instance().identifier(); + + // + // Configure the maildir resource + // + QString maildirRootPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QLatin1String("tester"); + mMaildirPath = maildirRootPath + QLatin1String("/new"); + mMaildirSettingsInterface = new OrgKdeAkonadiMaildirSettingsInterface( + QLatin1String("org.freedesktop.Akonadi.Resource.") + mMaildirIdentifier, + QLatin1String("/Settings"), QDBusConnection::sessionBus(), this); + QDBusReply setPathReply = mMaildirSettingsInterface->setPath(maildirRootPath); + QVERIFY(setPathReply.isValid()); + AgentManager::self()->instance(mMaildirIdentifier).reconfigure(); + QDBusReply getPathReply = mMaildirSettingsInterface->path(); + QCOMPARE(getPathReply.value(), maildirRootPath); + AgentManager::self()->instance(mMaildirIdentifier).synchronize(); + + // + // Find the root maildir collection + // + bool found = false; + QTime time; + time.start(); + while (!found) { + CollectionFetchJob *job = new CollectionFetchJob(Collection::root(), CollectionFetchJob::Recursive); + QVERIFY(job->exec()); + Collection::List collections = job->collections(); + foreach (const Collection &col, collections) { + if (col.resource() == AgentManager::self()->instance(mMaildirIdentifier).identifier()) { + mMaildirCollection = col; + found = true; + break; + } + } + + QVERIFY(time.elapsed() < 10 * 1000); // maildir should not need more than 10 secs to sync + } + + // + // Start the fake POP3 server + // + mFakeServerThread = new FakeServerThread(this); + mFakeServerThread->start(); + QTest::qWait(100); + QVERIFY(mFakeServerThread->server() != Q_NULLPTR); + + // + // Configure the pop3 resource + // + mPOP3SettingsInterface = new OrgKdeAkonadiPOP3SettingsInterface( + QLatin1String("org.freedesktop.Akonadi.Resource.") + mPop3Identifier, + QLatin1String("/Settings"), QDBusConnection::sessionBus(), this); + + QDBusReply reply0 = mPOP3SettingsInterface->port(); + QVERIFY(reply0.isValid()); + QVERIFY(reply0.value() == 110); + + mPOP3SettingsInterface->setPort(5989); + AgentManager::self()->instance(mPop3Identifier).reconfigure(); + QDBusReply reply = mPOP3SettingsInterface->port(); + QVERIFY(reply.isValid()); + QVERIFY(reply.value() == 5989); + + mPOP3SettingsInterface->setHost(QLatin1String("localhost")); + AgentManager::self()->instance(mPop3Identifier).reconfigure(); + QDBusReply reply2 = mPOP3SettingsInterface->host(); + QVERIFY(reply2.isValid()); + QVERIFY(reply2.value() == QLatin1String("localhost")); + mPOP3SettingsInterface->setLogin(QLatin1String("HansWurst")); + AgentManager::self()->instance(mPop3Identifier).reconfigure(); + QDBusReply reply3 = mPOP3SettingsInterface->login(); + QVERIFY(reply3.isValid()); + QVERIFY(reply3.value() == QLatin1String("HansWurst")); + + mPOP3SettingsInterface->setUnitTestPassword(QLatin1String("Geheim")); + AgentManager::self()->instance(mPop3Identifier).reconfigure(); + QDBusReply reply4 = mPOP3SettingsInterface->unitTestPassword(); + QVERIFY(reply4.isValid()); + QVERIFY(reply4.value() == QLatin1String("Geheim")); + + mPOP3SettingsInterface->setTargetCollection(mMaildirCollection.id()); + AgentManager::self()->instance(mPop3Identifier).reconfigure(); + QDBusReply reply5 = mPOP3SettingsInterface->targetCollection(); + QVERIFY(reply5.isValid()); + QVERIFY(reply5.value() == mMaildirCollection.id()); +} + +void Pop3Test::cleanupTestCase() +{ + // Post the "quit" event to the thread's event loop, then wait until the thread + // is finished (it finishes when the event loop finishes) + QMetaObject::invokeMethod(mFakeServerThread, "quit", Qt::QueuedConnection); + if (!mFakeServerThread->wait(10000)) { + qWarning() << "The fake server thread has not yet finished, what is wrong!?"; + } +} + +static const QByteArray simpleMail1 = + "From: \"Bill Lumbergh\" \r\n" + "To: \"Peter Gibbons\" \r\n" + "Subject: TPS Reports - New Cover Sheets\r\n" + "MIME-Version: 1.0\r\n" + "Content-Type: text/plain\r\n" + "Date: Mon, 23 Mar 2009 18:04:05 +0300\r\n" + "\r\n" + "Hi, Peter. What's happening? We need to talk about your TPS reports.\r\n"; + +static const QByteArray simpleMail2 = + "From: \"Amy McCorkell\" \r\n" + "To: gov.palin@yaho.com\r\n" + "Subject: HI SARAH\r\n" + "MIME-Version: 1.0\r\n" + "Content-Type: text/plain\r\n" + "Date: Mon, 23 Mar 2009 18:04:05 +0300\r\n" + "\r\n" + "Hey Sarah,\r\n" + "bla bla bla bla bla\r\n"; + +static const QByteArray simpleMail3 = + "From: chunkylover53@aol.com\r\n" + "To: tylerdurden@paperstreetsoapcompany.com\r\n" + "Subject: ILOVEYOU\r\n" + "MIME-Version: 1.0\r\n" + "Content-Type: text/plain\r\n" + "Date: Mon, 23 Mar 2009 18:04:05 +0300\r\n" + "\r\n" + "kindly check the attached LOVELETTER coming from me.\r\n"; + +static const QByteArray simpleMail4 = + "From: karl@aol.com\r\n" + "To: lenny@aol.com\r\n" + "Subject: Who took the donuts?\r\n" + "\r\n" + "Hi Lenny, do you know who took all the donuts?\r\n"; + +static const QByteArray simpleMail5 = + "From: foo@bar.com\r\n" + "To: bar@foo.com\r\n" + "Subject: Hello\r\n" + "\r\n" + "Hello World!!\r\n"; + +void Pop3Test::cleanupMaildir(Akonadi::Item::List items) +{ + // Delete all mails so the maildir is clean for the next test + if (!items.isEmpty()) { + ItemDeleteJob *job = new ItemDeleteJob(items); + QVERIFY(job->exec()); + } + + QTime time; + time.start(); + int lastCount = -1; + forever { + qApp->processEvents(); + QTest::qWait(500); + QDir maildir(mMaildirPath); + maildir.refresh(); + int curCount = maildir.entryList(QDir::Files | QDir::NoDotAndDotDot).count(); + + // Restart the timer when a mail arrives, as it shows that the maildir resource is + // still alive and kicking. + if (curCount != lastCount) + { + time.restart(); + lastCount = curCount; + } + + if (curCount == 0) + { + break; + } + + QVERIFY(time.elapsed() < 60000 || time.elapsed() > 80000000); + } +} + +void Pop3Test::checkMailsInMaildir(const QList &mails) +{ + // Now, test that all mails actually ended up in the maildir. Since the maildir resource + // might be slower, give it a timeout so it can write the files to disk + QTime time; + time.start(); + int lastCount = -1; + forever { + qApp->processEvents(); + QTest::qWait(500); + QDir maildir(mMaildirPath); + maildir.refresh(); + int curCount = static_cast(maildir.entryList(QDir::Files | QDir::NoDotAndDotDot).count()); + + // Restart the timer when a mail arrives, as it shows that the maildir resource is + // still alive and kicking. + if (curCount != lastCount) + { + time.start(); + lastCount = curCount; + } + + if (curCount == mails.count()) + { + break; + } + QVERIFY(static_cast(maildir.entryList(QDir::NoDotAndDotDot).count()) <= mails.count()); + QVERIFY(time.elapsed() < 60000 || time.elapsed() > 80000000); + } + + // TODO: check file contents as well or is this overkill? +} + +Akonadi::Item::List Pop3Test::checkMailsOnAkonadiServer(const QList &mails) +{ + // The fake server got disconnected, which means the pop3 resource has entered the QUIT + // stage. That means all messages should be on the server now, so test that. + ItemFetchJob *job = new ItemFetchJob(mMaildirCollection); + job->fetchScope().fetchFullPayload(); + Q_ASSERT(job->exec()); + Item::List items = job->items(); + Q_ASSERT(mails.size() == items.size()); + + QSet ourMailBodies; + QSet itemMailBodies; + + foreach (const Item &item, items) { + KMime::Message::Ptr itemMail = item.payload(); + QByteArray itemMailBody = itemMail->body(); + + // For some reason, the body in the maildir has one additional newline. + // Get rid of this so we can compare them. + // FIXME: is this a bug? Find out where the newline comes from! + itemMailBody.chop(1); + itemMailBodies.insert(itemMailBody); + } + + foreach (const QByteArray &mail, mails) { + KMime::Message::Ptr ourMail(new KMime::Message()); + ourMail->setContent(KMime::CRLFtoLF(mail)); + ourMail->parse(); + QByteArray ourMailBody = ourMail->body(); + ourMailBodies.insert(ourMailBody); + } + + Q_ASSERT(ourMailBodies == itemMailBodies); + return items; +} + +void Pop3Test::syncAndWaitForFinish() +{ + AgentManager::self()->instance(mPop3Identifier).synchronize(); + + // The pop3 resource, ioslave and the fakeserver are all in different processes or threads. + // We simply wait until the FakeServer got disconnected or until a timeout. + // Since POP3 fetching can take longer, we reset the timeout timer when the FakeServer + // does some processing. + QTime time; + time.start(); + int lastProgress = -1; + forever { + qApp->processEvents(); + + // Finish correctly when the connection got closed + if (mFakeServerThread->server()->gotDisconnected()) + { + break; + } + + // Reset the timeout when the server is working + const int newProgress = mFakeServerThread->server()->progress(); + if (newProgress != lastProgress) + { + time.restart(); + lastProgress = newProgress; + } + + // Assert when nothing happens for a certain timeout, that indicates something went + // wrong and is stuck somewhere + if (time.elapsed() >= 60000) + { + Q_ASSERT_X(false, "poptest", "FakeServer timed out."); + break; + } + } +} + +QString Pop3Test::loginSequence() const +{ + return + QLatin1String("C: USER HansWurst\r\n" + "S: +OK May I have your password, please?\r\n" + "C: PASS Geheim\r\n" + "S: +OK Mailbox locked and ready\r\n"); +} + +QString Pop3Test::retrieveSequence(const QList &mails, + const QList &exceptions) const +{ + QString result; + for (int i = 1; i <= mails.size(); i++) { + if (!exceptions.contains(i)) { + result += QLatin1String( + "C: RETR %RETR%\r\n" + "S: +OK Here is your spam\r\n" + "%MAIL%\r\n" + ".\r\n"); + } + } + return result; +} + +QString Pop3Test::deleteSequence(int numToDelete) const +{ + QString result; + for (int i = 0; i < numToDelete; i++) { + result += + QLatin1String("C: DELE %DELE%\r\n" + "S: +OK message sent to /dev/null\r\n"); + } + return result; +} + +QString Pop3Test::quitSequence() const +{ + return + QLatin1String("C: QUIT\r\n" + "S: +OK Have a nice day.\r\n"); +} + +QString Pop3Test::listSequence(const QList &mails) const +{ + QString result = QLatin1String("C: LIST\r\n" + "S: +OK You got new spam\r\n"); + for (int i = 1; i <= mails.size(); i++) { + result += QString::fromLatin1("%1 %MAILSIZE%\r\n").arg(i); + } + result += QLatin1String(".\r\n"); + return result; +} + +QString Pop3Test::uidSequence(const QStringList &uids) const +{ + QString result = QLatin1String("C: UIDL\r\n" + "S: +OK\r\n"); + for (int i = 1; i <= uids.size(); i++) { + result += QString::fromLatin1("%1 %2\r\n").arg(i).arg(uids[i - 1]); + } + result += QLatin1String(".\r\n"); + return result; +} + +static bool sortedEqual(const QStringList &list1, const QStringList &list2) +{ + QStringList sorted1 = list1; + sorted1.sort(); + QStringList sorted2 = list2; + sorted2.sort(); + + return qEqual(sorted1.begin(), sorted1.end(), sorted2.begin()); +} + +void Pop3Test::lowerTimeOfSeenMail(const QString &uidOfMail, int secondsToLower) +{ + const int index = mPOP3SettingsInterface->seenUidList().value().indexOf(uidOfMail); + QList seenTimeList = mPOP3SettingsInterface->seenUidTimeList().value(); + int msgTime = seenTimeList.at(index); + msgTime -= secondsToLower; + seenTimeList.replace(index, msgTime); + mPOP3SettingsInterface->setSeenUidTimeList(seenTimeList); +} + +void Pop3Test::testSimpleDownload() +{ + QList mails; + mails << simpleMail1 << simpleMail2 << simpleMail3; + QStringList uids; + uids << QStringLiteral("UID1") << QStringLiteral("UID2") << QStringLiteral("UID3"); + mFakeServerThread->server()->setAllowedDeletions(QLatin1String("1,2,3")); + mFakeServerThread->server()->setAllowedRetrieves(QLatin1String("1,2,3")); + mFakeServerThread->server()->setMails(mails); + mFakeServerThread->server()->setNextConversation( + loginSequence() + + listSequence(mails) + + uidSequence(uids) + + retrieveSequence(mails) + + deleteSequence(mails.size()) + + quitSequence() + ); + + syncAndWaitForFinish(); + Akonadi::Item::List items = checkMailsOnAkonadiServer(mails); + checkMailsInMaildir(mails); + cleanupMaildir(items); +} + +void Pop3Test::testBigFetch() +{ + QList mails; + QStringList uids; + QString allowedRetrs; + for (int i = 0; i < 1000; i++) { + QByteArray newMail = simpleMail1; + newMail.append(QString::number(i + 1).toLatin1()); + mails << newMail; + uids << QString::fromLatin1("UID%1").arg(i + 1); + allowedRetrs += QString::number(i + 1) + QLatin1Char(','); + } + allowedRetrs.chop(1); + + mFakeServerThread->server()->setMails(mails); + mFakeServerThread->server()->setAllowedRetrieves(allowedRetrs); + mFakeServerThread->server()->setAllowedDeletions(allowedRetrs); + mFakeServerThread->server()->setNextConversation( + loginSequence() + + listSequence(mails) + + uidSequence(uids) + + retrieveSequence(mails) + + deleteSequence(mails.size()) + + quitSequence() + ); + + syncAndWaitForFinish(); + Akonadi::Item::List items = checkMailsOnAkonadiServer(mails); + checkMailsInMaildir(mails); + cleanupMaildir(items); +} + +void Pop3Test::testSeenUIDCleanup() +{ + // + // First, fetch 3 normal mails, but leave them on the server. + // + mPOP3SettingsInterface->setLeaveOnServer(true); + QList mails; + mails << simpleMail1 << simpleMail2 << simpleMail3; + QStringList uids; + uids << QStringLiteral("UID1") << QStringLiteral("UID2") << QStringLiteral("UID3"); + mFakeServerThread->server()->setAllowedDeletions(QString()); + mFakeServerThread->server()->setAllowedRetrieves(QLatin1String("1,2,3")); + mFakeServerThread->server()->setMails(mails); + mFakeServerThread->server()->setNextConversation( + loginSequence() + + listSequence(mails) + + uidSequence(uids) + + retrieveSequence(mails) + + quitSequence() + ); + + syncAndWaitForFinish(); + Akonadi::Item::List items = checkMailsOnAkonadiServer(mails); + checkMailsInMaildir(mails); + cleanupMaildir(items); + + QVERIFY(sortedEqual(uids, mPOP3SettingsInterface->seenUidList().value())); + QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == + mPOP3SettingsInterface->seenUidList().value().size()); + + // + // Now, pretend that the messages were removed from the server in the meantime + // by having no mails on the fake server. + // + mFakeServerThread->server()->setMails(QList()); + mFakeServerThread->server()->setAllowedRetrieves(QString()); + mFakeServerThread->server()->setAllowedDeletions(QString()); + mFakeServerThread->server()->setNextConversation( + loginSequence() + + listSequence(QList()) + + uidSequence(QStringList()) + + quitSequence() + ); + syncAndWaitForFinish(); + items = checkMailsOnAkonadiServer(QList()); + checkMailsInMaildir(QList()); + cleanupMaildir(items); + + QVERIFY(mPOP3SettingsInterface->seenUidList().value().isEmpty()); + QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == + mPOP3SettingsInterface->seenUidList().value().size()); + + mPOP3SettingsInterface->setLeaveOnServer(false); +} + +void Pop3Test::testSimpleLeaveOnServer() +{ + mPOP3SettingsInterface->setLeaveOnServer(true); + + QList mails; + mails << simpleMail1 << simpleMail2 << simpleMail3; + QStringList uids; + uids << QStringLiteral("UID1") << QStringLiteral("UID2") << QStringLiteral("UID3"); + mFakeServerThread->server()->setMails(mails); + mFakeServerThread->server()->setAllowedRetrieves(QLatin1String("1,2,3")); + mFakeServerThread->server()->setNextConversation( + loginSequence() + + listSequence(mails) + + uidSequence(uids) + + retrieveSequence(mails) + + quitSequence() + ); + + syncAndWaitForFinish(); + Akonadi::Item::List items = checkMailsOnAkonadiServer(mails); + checkMailsInMaildir(mails); + + // The resource should have saved the UIDs of the seen messages + QVERIFY(sortedEqual(uids, mPOP3SettingsInterface->seenUidList().value())); + QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == + mPOP3SettingsInterface->seenUidList().value().size()); + foreach (int seenTime, mPOP3SettingsInterface->seenUidTimeList().value()) { + // Those message were just downloaded from the fake server, so they are at maximum + // 10 minutes old (for slooooow running tests) + QVERIFY(seenTime >= time(Q_NULLPTR) - 10 * 60); + } + + // + // OK, next mail check: We have to check that the old seen messages are not downloaded again, + // only new mails. + // + QList newMails(mails); + newMails << simpleMail4; + QStringList newUids(uids); + newUids << QStringLiteral("newUID"); + QList idsToNotDownload; + idsToNotDownload << 1 << 2 << 3; + mFakeServerThread->server()->setMails(newMails); + mFakeServerThread->server()->setAllowedRetrieves(QLatin1String("4")); + mFakeServerThread->server()->setNextConversation( + loginSequence() + + listSequence(newMails) + + uidSequence(newUids) + + retrieveSequence(newMails, idsToNotDownload) + + quitSequence(), + idsToNotDownload + ); + + syncAndWaitForFinish(); + items = checkMailsOnAkonadiServer(newMails); + checkMailsInMaildir(newMails); + QVERIFY(sortedEqual(newUids, mPOP3SettingsInterface->seenUidList().value())); + QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == + mPOP3SettingsInterface->seenUidList().value().size()); + + // + // Ok, next test: When turning off leaving on the server, all mails should be deleted, but + // none downloaded. + // + mPOP3SettingsInterface->setLeaveOnServer(false); + + mFakeServerThread->server()->setAllowedDeletions(QLatin1String("1,2,3,4")); + mFakeServerThread->server()->setAllowedRetrieves(QString()); + mFakeServerThread->server()->setNextConversation( + loginSequence() + + listSequence(newMails) + + uidSequence(newUids) + + deleteSequence(newMails.size()) + + quitSequence() + ); + + syncAndWaitForFinish(); + items = checkMailsOnAkonadiServer(newMails); + checkMailsInMaildir(newMails); + cleanupMaildir(items); + QVERIFY(mPOP3SettingsInterface->seenUidList().value().isEmpty()); + QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == + mPOP3SettingsInterface->seenUidList().value().size()); +} + +void Pop3Test::testTimeBasedLeaveRule() +{ + mPOP3SettingsInterface->setLeaveOnServer(true); + mPOP3SettingsInterface->setLeaveOnServerDays(2); + + // + // First download 3 mails and leave them on the server + // + QList mails; + mails << simpleMail1 << simpleMail2 << simpleMail3; + QStringList uids; + uids << QStringLiteral("UID1") << QStringLiteral("UID2") << QStringLiteral("UID3"); + mFakeServerThread->server()->setMails(mails); + mFakeServerThread->server()->setAllowedRetrieves(QLatin1String("1,2,3")); + mFakeServerThread->server()->setNextConversation( + loginSequence() + + listSequence(mails) + + uidSequence(uids) + + retrieveSequence(mails) + + quitSequence() + ); + + syncAndWaitForFinish(); + Akonadi::Item::List items = checkMailsOnAkonadiServer(mails); + checkMailsInMaildir(mails); + + QVERIFY(sortedEqual(uids, mPOP3SettingsInterface->seenUidList().value())); + QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == + mPOP3SettingsInterface->seenUidList().value().size()); + + // + // Now, modify the seenUidTimeList on the server for UID2 to pretend it + // was downloaded 3 days ago, which means it should be deleted. + // + lowerTimeOfSeenMail(QLatin1String("UID2"), 60 * 60 * 24 * 3); + + QList idsToNotDownload; + idsToNotDownload << 1 << 3; + mFakeServerThread->server()->setAllowedDeletions(QLatin1String("2")); + mFakeServerThread->server()->setAllowedRetrieves(QString()); + mFakeServerThread->server()->setNextConversation( + loginSequence() + + listSequence(mails) + + uidSequence(uids) + + deleteSequence(1) + + quitSequence(), + idsToNotDownload + ); + syncAndWaitForFinish(); + items = checkMailsOnAkonadiServer(mails); + checkMailsInMaildir(mails); + cleanupMaildir(items); + + uids.removeAll(QLatin1String("UID2")); + QVERIFY(sortedEqual(uids, mPOP3SettingsInterface->seenUidList().value())); + QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == + mPOP3SettingsInterface->seenUidList().value().size()); + foreach (int seenTime, mPOP3SettingsInterface->seenUidTimeList().value()) { + QVERIFY(seenTime >= time(Q_NULLPTR) - 10 * 60); + } + + mPOP3SettingsInterface->setLeaveOnServer(false); + mPOP3SettingsInterface->setLeaveOnServerDays(0); + mPOP3SettingsInterface->setSeenUidTimeList(QList()); + mPOP3SettingsInterface->setSeenUidList(QStringList()); +} + +void Pop3Test::testCountBasedLeaveRule() +{ + mPOP3SettingsInterface->setLeaveOnServer(true); + mPOP3SettingsInterface->setLeaveOnServerCount(3); + + // + // First download 3 mails and leave them on the server + // + QList mails; + mails << simpleMail1 << simpleMail2 << simpleMail3; + QStringList uids; + uids << QStringLiteral("UID1") << QStringLiteral("UID2") << QStringLiteral("UID3"); + mFakeServerThread->server()->setMails(mails); + mFakeServerThread->server()->setAllowedRetrieves(QLatin1String("1,2,3")); + mFakeServerThread->server()->setNextConversation( + loginSequence() + + listSequence(mails) + + uidSequence(uids) + + retrieveSequence(mails) + + quitSequence() + ); + + syncAndWaitForFinish(); + checkMailsOnAkonadiServer(mails); + checkMailsInMaildir(mails); + + // Make the 3 just downloaded mails appear older than they are + lowerTimeOfSeenMail(QLatin1String("UID1"), 60 * 60 * 24 * 2); + lowerTimeOfSeenMail(QLatin1String("UID2"), 60 * 60 * 24 * 1); + lowerTimeOfSeenMail(QLatin1String("UID3"), 60 * 60 * 24 * 3); + + // + // Now, download 2 more mails. Since only 3 mails are allowed to be left + // on the server, the oldest ones, UID1 and UID3, should be deleted + // + QList moreMails; + moreMails << simpleMail4 << simpleMail5; + QStringList moreUids; + moreUids << QStringLiteral("UID4") << QStringLiteral("UID5"); + mFakeServerThread->server()->setMails(mails + moreMails); + mFakeServerThread->server()->setAllowedRetrieves(QLatin1String("4,5")); + mFakeServerThread->server()->setAllowedDeletions(QLatin1String("1,3")); + mFakeServerThread->server()->setNextConversation( + loginSequence() + + listSequence(mails + moreMails) + + uidSequence(uids + moreUids) + + retrieveSequence(moreMails) + + deleteSequence(2) + + quitSequence(), QList() << 1 << 2 << 3 + ); + + syncAndWaitForFinish(); + Akonadi::Item::List items = checkMailsOnAkonadiServer(mails + moreMails); + checkMailsInMaildir(mails + moreMails); + cleanupMaildir(items); + + QStringList uidsLeft; + uidsLeft << QStringLiteral("UID2") << QStringLiteral("UID4") << QStringLiteral("UID5"); + + QVERIFY(sortedEqual(uidsLeft, mPOP3SettingsInterface->seenUidList().value())); + QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == + mPOP3SettingsInterface->seenUidList().value().size()); + + mPOP3SettingsInterface->setLeaveOnServer(false); + mPOP3SettingsInterface->setLeaveOnServerCount(0); + mPOP3SettingsInterface->setSeenUidTimeList(QList()); + mPOP3SettingsInterface->setSeenUidList(QStringList()); +} + +void Pop3Test::testSizeBasedLeaveRule() +{ + mPOP3SettingsInterface->setLeaveOnServer(true); + mPOP3SettingsInterface->setLeaveOnServerSize(10); // 10 MB + + // + // First download 3 mails and leave them on the server. + // + QList mails; + mails << simpleMail1 << simpleMail2 << simpleMail3; + QStringList uids; + uids << QStringLiteral("UID1") << QStringLiteral("UID2") << QStringLiteral("UID3"); + mFakeServerThread->server()->setMails(mails); + mFakeServerThread->server()->setAllowedRetrieves(QLatin1String("1,2,3")); + mFakeServerThread->server()->setNextConversation( + loginSequence() + + listSequence(mails) + + uidSequence(uids) + + retrieveSequence(mails) + + quitSequence() + ); + + syncAndWaitForFinish(); + checkMailsOnAkonadiServer(mails); + checkMailsInMaildir(mails); + + // Make the 3 just downloaded mails appear older than they are + lowerTimeOfSeenMail(QLatin1String("UID1"), 60 * 60 * 24 * 2); + lowerTimeOfSeenMail(QLatin1String("UID2"), 60 * 60 * 24 * 1); + lowerTimeOfSeenMail(QLatin1String("UID3"), 60 * 60 * 24 * 3); + + // Now, do another mail check, but with no new mails on the server. + // Instead we let the server pretend that the mails have a fake size, + // each 7 MB. That means the two oldest get deleted, because the total + // mail size is over 10 MB with them. + mFakeServerThread->server()->setMails(mails); + mFakeServerThread->server()->setAllowedRetrieves(QString()); + mFakeServerThread->server()->setAllowedDeletions(QLatin1String("1,3")); + mFakeServerThread->server()->setNextConversation( + loginSequence() + + QLatin1String("C: LIST\r\n" + "S: +OK You got new spam\r\n" + "1 7340032\r\n" + "2 7340032\r\n" + "3 7340032\r\n" + ".\r\n") + + uidSequence(uids) + + deleteSequence(2) + + quitSequence() + ); + + syncAndWaitForFinish(); + Akonadi::Item::List items = checkMailsOnAkonadiServer(mails); + checkMailsInMaildir(mails); + cleanupMaildir(items); + + QStringList uidsLeft; + uidsLeft << QStringLiteral("UID2"); + + QVERIFY(sortedEqual(uidsLeft, mPOP3SettingsInterface->seenUidList().value())); + QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == + mPOP3SettingsInterface->seenUidList().value().size()); + + mPOP3SettingsInterface->setLeaveOnServer(false); + mPOP3SettingsInterface->setLeaveOnServerCount(0); + mPOP3SettingsInterface->setLeaveOnServerSize(0); + mPOP3SettingsInterface->setSeenUidTimeList(QList()); + mPOP3SettingsInterface->setSeenUidList(QStringList()); +} + +void Pop3Test::testMixedLeaveRules() +{ + mPOP3SettingsInterface->setLeaveOnServer(true); + // + // Generate 10 mails + // + QList mails; + QStringList uids; + QString allowedRetrs; + for (int i = 0; i < 10; i++) { + QByteArray newMail = simpleMail1; + newMail.append(QString::number(i + 1).toLatin1()); + mails << newMail; + uids << QString::fromLatin1("UID%1").arg(i + 1); + allowedRetrs += QString::number(i + 1) + QLatin1Char(','); + } + allowedRetrs.chop(1); + + // + // Now, download these 10 mails + // + mFakeServerThread->server()->setMails(mails); + mFakeServerThread->server()->setAllowedRetrieves(allowedRetrs); + mFakeServerThread->server()->setNextConversation( + loginSequence() + + listSequence(mails) + + uidSequence(uids) + + retrieveSequence(mails) + + quitSequence() + ); + + syncAndWaitForFinish(); + checkMailsOnAkonadiServer(mails); + checkMailsInMaildir(mails); + + // Fake the time of the messages, UID1 is one day old, UID2 is two days old, etc + for (int i = 1; i <= 10; i++) { + lowerTimeOfSeenMail(QString::fromLatin1("UID%1").arg(i), 60 * 60 * 24 * i); + } + + mPOP3SettingsInterface->setLeaveOnServer(true); + mPOP3SettingsInterface->setLeaveOnServerSize(25); // UID 4, 5 oldest here + mPOP3SettingsInterface->setLeaveOnServerCount(5); // UID 6, 7 oldest here + mPOP3SettingsInterface->setLeaveOnServerDays(7); // UID 8, 9 and 10 too old + + // Ok, now we do another mail check that only deletes stuff from the server. + // Above are the UIDs that should be deleted. + mFakeServerThread->server()->setMails(mails); + mFakeServerThread->server()->setAllowedRetrieves(QString()); + mFakeServerThread->server()->setAllowedDeletions(QLatin1String("4,5,6,7,8,9,10")); + mFakeServerThread->server()->setNextConversation( + loginSequence() + + QLatin1String("C: LIST\r\n" + "S: +OK You got new spam\r\n" + "1 7340032\r\n" + "2 7340032\r\n" + "3 7340032\r\n" + "4 7340032\r\n" + "5 7340032\r\n" + "6 7340032\r\n" + "7 7340032\r\n" + "8 7340032\r\n" + "9 7340032\r\n" + "10 7340032\r\n" + ".\r\n") + + uidSequence(uids) + + deleteSequence(7) + + quitSequence() + ); + + syncAndWaitForFinish(); + Akonadi::Item::List items = checkMailsOnAkonadiServer(mails); + checkMailsInMaildir(mails); + cleanupMaildir(items); + + QStringList uidsLeft; + uidsLeft << QStringLiteral("UID1") << QStringLiteral("UID2") << QStringLiteral("UID3"); + + QVERIFY(sortedEqual(uidsLeft, mPOP3SettingsInterface->seenUidList().value())); + QVERIFY(mPOP3SettingsInterface->seenUidTimeList().value().size() == + mPOP3SettingsInterface->seenUidList().value().size()); + + mPOP3SettingsInterface->setLeaveOnServer(false); + mPOP3SettingsInterface->setLeaveOnServerCount(0); + mPOP3SettingsInterface->setLeaveOnServerSize(0); + mPOP3SettingsInterface->setSeenUidTimeList(QList()); + mPOP3SettingsInterface->setSeenUidList(QStringList()); +} diff -Nru kdepim-runtime-4.14.6/resources/pop3/autotests/pop3test.h kdepim-runtime-15.08.0/resources/pop3/autotests/pop3test.h --- kdepim-runtime-4.14.6/resources/pop3/autotests/pop3test.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/autotests/pop3test.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,73 @@ +/* Copyright 2009 Thomas McGuire + + 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 ) version 3 or, at the discretion of KDE e.V. + ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 POP3TEST_H +#define POP3TEST_H + +#include "fakeserver/fakeserver.h" +#include "pop3settings.h" +#include "maildirsettings.h" + +#include +#include + +#include +#include + +class Pop3Test : public QObject +{ + Q_OBJECT + + void replymMaildirSettingsInterface(QString arg1); +private Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); + void testSimpleDownload(); + void testSimpleLeaveOnServer(); + void testBigFetch(); + void testSeenUIDCleanup(); + void testTimeBasedLeaveRule(); + void testCountBasedLeaveRule(); + void testSizeBasedLeaveRule(); + void testMixedLeaveRules(); + +private: + void lowerTimeOfSeenMail(const QString &uidOfMail, int secondsToLower); + void cleanupMaildir(Akonadi::Item::List items); + void checkMailsInMaildir(const QList< QByteArray > &mails); + Akonadi::Item::List checkMailsOnAkonadiServer(const QList &mails); + void syncAndWaitForFinish(); + QString loginSequence() const; + QString retrieveSequence(const QList< QByteArray > &mails, + const QList &exceptions = QList()) const; + QString deleteSequence(int numToDelete) const; + QString quitSequence() const; + QString listSequence(const QList &mails) const; + QString uidSequence(const QStringList &uids) const; + + FakeServerThread *mFakeServerThread; + + OrgKdeAkonadiPOP3SettingsInterface *mPOP3SettingsInterface; + OrgKdeAkonadiMaildirSettingsInterface *mMaildirSettingsInterface; + Akonadi::Collection mMaildirCollection; + QString mPop3Identifier; + QString mMaildirIdentifier; + QString mMaildirPath; +}; + +#endif diff -Nru kdepim-runtime-4.14.6/resources/pop3/autotests/unittestenv/config.xml kdepim-runtime-15.08.0/resources/pop3/autotests/unittestenv/config.xml --- kdepim-runtime-4.14.6/resources/pop3/autotests/unittestenv/config.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/autotests/unittestenv/config.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,6 @@ + + kdehome + xdgconfig + xdglocal + true + diff -Nru kdepim-runtime-4.14.6/resources/pop3/autotests/unittestenv/kdehome/share/apps/.keep kdepim-runtime-15.08.0/resources/pop3/autotests/unittestenv/kdehome/share/apps/.keep --- kdepim-runtime-4.14.6/resources/pop3/autotests/unittestenv/kdehome/share/apps/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/autotests/unittestenv/kdehome/share/apps/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/pop3/autotests/unittestenv/kdehome/share/config/akonadi-firstrunrc kdepim-runtime-15.08.0/resources/pop3/autotests/unittestenv/kdehome/share/config/akonadi-firstrunrc --- kdepim-runtime-4.14.6/resources/pop3/autotests/unittestenv/kdehome/share/config/akonadi-firstrunrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/autotests/unittestenv/kdehome/share/config/akonadi-firstrunrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,3 @@ +[ProcessedDefaults] +defaultaddressbook=done +defaultcalendar=done diff -Nru kdepim-runtime-4.14.6/resources/pop3/autotests/unittestenv/kdehome/share/config/kdebugrc kdepim-runtime-15.08.0/resources/pop3/autotests/unittestenv/kdehome/share/config/kdebugrc --- kdepim-runtime-4.14.6/resources/pop3/autotests/unittestenv/kdehome/share/config/kdebugrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/autotests/unittestenv/kdehome/share/config/kdebugrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,103 @@ +[0] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 + +[kbuildsycoca4] +AbortFatal=true +ErrorOutput=0 +FatalOutput=0 +InfoOutput=0 +WarnOutput=0 + +[kdecore (services)] +AbortFatal=true +ErrorOutput=0 +FatalOutput=0 +InfoOutput=0 +WarnOutput=0 + +[264] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=4 +FatalFilename[$e]=kdebug.dbg +FatalOutput=4 +InfoFilename[$e]=kdebug.dbg +WarnFilename[$e]=kdebug.dbg +WarnOutput=4 + +[5250] +InfoOutput=2 + +[7009] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=4 +FatalFilename[$e]=kdebug.dbg +FatalOutput=4 +InfoFilename[$e]=kdebug.dbg +InfoOutput=4 +WarnFilename[$e]=kdebug.dbg +WarnOutput=4 + +[7011] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=4 +FatalFilename[$e]=kdebug.dbg +FatalOutput=4 +InfoFilename[$e]=kdebug.dbg +InfoOutput=4 +WarnFilename[$e]=kdebug.dbg +WarnOutput=4 + +[7012] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=4 +FatalFilename[$e]=kdebug.dbg +FatalOutput=4 +InfoFilename[$e]=kdebug.dbg +InfoOutput=4 +WarnFilename[$e]=kdebug.dbg +WarnOutput=4 + +[7014] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=0 +FatalFilename[$e]=kdebug.dbg +FatalOutput=0 +InfoFilename[$e]=kdebug.dbg +InfoOutput=0 +WarnFilename[$e]=kdebug.dbg +WarnOutput=0 + +[7021] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=4 +FatalFilename[$e]=kdebug.dbg +FatalOutput=4 +InfoFilename[$e]=kdebug.dbg +InfoOutput=4 +WarnFilename[$e]=kdebug.dbg +WarnOutput=4 + +[7105] +AbortFatal=true +ErrorFilename[$e]=kdebug.dbg +ErrorOutput=2 +FatalFilename[$e]=kdebug.dbg +FatalOutput=2 +InfoFilename[$e]=kdebug.dbg +InfoOutput=2 +WarnFilename[$e]=kdebug.dbg +WarnOutput=2 diff -Nru kdepim-runtime-4.14.6/resources/pop3/autotests/unittestenv/xdgconfig/akonadi/akonadiserverrc kdepim-runtime-15.08.0/resources/pop3/autotests/unittestenv/xdgconfig/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/resources/pop3/autotests/unittestenv/xdgconfig/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/autotests/unittestenv/xdgconfig/akonadi/akonadiserverrc 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,4 @@ +[%General] + +[Search] +Manager=Dummy diff -Nru kdepim-runtime-4.14.6/resources/pop3/autotests/unittestenv/xdglocal/.keep kdepim-runtime-15.08.0/resources/pop3/autotests/unittestenv/xdglocal/.keep --- kdepim-runtime-4.14.6/resources/pop3/autotests/unittestenv/xdglocal/.keep 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/autotests/unittestenv/xdglocal/.keep 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1 @@ +force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/pop3/CMakeLists.txt kdepim-runtime-15.08.0/resources/pop3/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/pop3/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,26 +1,7 @@ project(pop3) -if (XSLTPROC_EXECUTABLE) - # generates a D-Bus interface description from a KConfigXT file - macro( kcfg_generate_dbus_interface _kcfg _name ) - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml - COMMAND ${XSLTPROC_EXECUTABLE} --stringparam interfaceName ${_name} - ${KDEPIMLIBS_DATA_DIR}/akonadi-kde/kcfg2dbus.xsl - ${_kcfg} - > ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml - DEPENDS ${KDEPIMLIBS_DATA_DIR}/akonadi-kde/kcfg2dbus.xsl - ${_kcfg} - ) - endmacro() -endif () - -include_directories( - ${KDE4_INCLUDES} - ${KDEPIMLIBS_INCLUDE_DIRS} -) +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_pop3_resource\") -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) ########### next target ############### @@ -30,23 +11,24 @@ accountdialog.cpp jobs.cpp settings.cpp - pop3resourceattribute.cpp + pop3resource_debug.cpp ) -add_definitions(-DKDE_DEFAULT_DEBUG_AREA=5266) -install( FILES pop3resource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) -kde4_add_ui_files( pop3resource_SRCS popsettings.ui) -kde4_add_kcfg_files(pop3resource_SRCS settingsbase.kcfgc) +install( FILES pop3resource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) + +ki18n_wrap_ui( pop3resource_SRCS popsettings.ui) +kconfig_add_kcfg_files(pop3resource_SRCS settingsbase.kcfgc) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/settings.kcfg org.kde.Akonadi.POP3.Settings) -qt4_add_dbus_adaptor(pop3resource_SRCS +qt5_add_dbus_adaptor(pop3resource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.POP3.Settings.xml settings.h Settings ) -kde4_add_executable(akonadi_pop3_resource RUN_UNINSTALLED ${pop3resource_SRCS}) +#add_executable(akonadi_pop3_resource RUN_UNINSTALLED ${pop3resource_SRCS}) +add_executable(akonadi_pop3_resource ${pop3resource_SRCS}) -if (Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_pop3_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) set_target_properties(akonadi_pop3_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.POP3") set_target_properties(akonadi_pop3_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi POP3 Resource") @@ -54,19 +36,19 @@ target_link_libraries( akonadi_pop3_resource - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_AKONADI_KMIME_LIBS} - ${QT_QTCORE_LIBRARY} - ${QT_QTGUI_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ${KDE4_KDECORE_LIBS} - ${KDE4_KIO_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${KDEPIMLIBS_MAILTRANSPORT_LIBS} - ${KDEPIMLIBS_KPIMUTILS_LIBS} + KF5::AkonadiCore + KF5::AkonadiMime + KF5::KIOCore + KF5::Mime + KF5::MailTransport + KF5::AkonadiAgentBase + KF5::AkonadiWidgets ) -add_subdirectory( tests ) +if(BUILD_TESTING) + add_subdirectory( autotests ) +endif() + add_subdirectory( wizard ) -install(TARGETS akonadi_pop3_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(TARGETS akonadi_pop3_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/pop3/jobs.cpp kdepim-runtime-15.08.0/resources/pop3/jobs.cpp --- kdepim-runtime-4.14.6/resources/pop3/jobs.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/jobs.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,488 +20,481 @@ #include "jobs.h" #include "settings.h" -#include +#include #include #include -#include +#include +#include +#include "pop3resource_debug.h" #include -POPSession::POPSession( const QString &password ) - : mCurrentJob(0), mPassword( password ) +POPSession::POPSession(const QString &password) + : mCurrentJob(Q_NULLPTR), mPassword(password) { - KIO::Scheduler::connect( - SIGNAL(slaveError(KIO::Slave*,int,QString)), this, - SLOT(slotSlaveError(KIO::Slave*,int,QString)) ); + KIO::Scheduler::connect(SIGNAL(slaveError(KIO::Slave*,int,QString)), this, SLOT(slotSlaveError(KIO::Slave*,int,QString))); } POPSession::~POPSession() { - closeSession(); + closeSession(); } -void POPSession::slotSlaveError( KIO::Slave *slave , int errorCode, - const QString &errorMessage ) +void POPSession::slotSlaveError(KIO::Slave *slave , int errorCode, + const QString &errorMessage) { - Q_UNUSED( slave ); - kWarning() << "Got a slave error:" << errorMessage; + Q_UNUSED(slave); + qCWarning(POP3RESOURCE_LOG) << "Got a slave error:" << errorMessage; - if ( slave != mSlave ) - return; + if (slave != mSlave) { + return; + } - if ( errorCode == KIO::ERR_SLAVE_DIED ) - mSlave = 0; + if (errorCode == KIO::ERR_SLAVE_DIED) { + mSlave = Q_NULLPTR; + } - // Explicitly disconnect the slave if the connection went down - if ( errorCode == KIO::ERR_CONNECTION_BROKEN && mSlave ) { - KIO::Scheduler::disconnectSlave( mSlave ); - mSlave = 0; - } + // Explicitly disconnect the slave if the connection went down + if (errorCode == KIO::ERR_CONNECTION_BROKEN && mSlave) { + KIO::Scheduler::disconnectSlave(mSlave); + mSlave = Q_NULLPTR; + } - if ( !mCurrentJob ) { - emit slaveError( errorCode, errorMessage ); - } - else { - // Let the job deal with the problem - mCurrentJob->slaveError( errorCode, errorMessage ); - } + if (!mCurrentJob) { + Q_EMIT slaveError(errorCode, errorMessage); + } else { + // Let the job deal with the problem + mCurrentJob->slaveError(errorCode, errorMessage); + } } -void POPSession::setCurrentJob( SlaveBaseJob *job ) +void POPSession::setCurrentJob(SlaveBaseJob *job) { - mCurrentJob = job; + mCurrentJob = job; } KIO::MetaData POPSession::slaveConfig() const { - KIO::MetaData m; + KIO::MetaData m; - m.insert( QLatin1String("progress"), QLatin1String("off") ); - m.insert( QLatin1String("tls"), Settings::self()->useTLS() ? QLatin1String("on") : QLatin1String("off") ); - m.insert( QLatin1String("pipelining"), ( Settings::self()->pipelining() ) ? QLatin1String("on") : QLatin1String("off") ); - int type = Settings::self()->authenticationMethod(); - switch( type ) { + m.insert(QLatin1String("progress"), QStringLiteral("off")); + m.insert(QLatin1String("tls"), Settings::self()->useTLS() ? QLatin1String("on") : QLatin1String("off")); + m.insert(QLatin1String("pipelining"), (Settings::self()->pipelining()) ? QLatin1String("on") : QLatin1String("off")); + int type = Settings::self()->authenticationMethod(); + switch (type) { case MailTransport::Transport::EnumAuthenticationType::PLAIN: case MailTransport::Transport::EnumAuthenticationType::LOGIN: case MailTransport::Transport::EnumAuthenticationType::CRAM_MD5: case MailTransport::Transport::EnumAuthenticationType::DIGEST_MD5: case MailTransport::Transport::EnumAuthenticationType::NTLM: case MailTransport::Transport::EnumAuthenticationType::GSSAPI: - m.insert( QLatin1String("auth"), QLatin1String("SASL") ); - m.insert( QLatin1String("sasl"), authenticationToString( type ) ); - break; + m.insert(QLatin1String("auth"), QStringLiteral("SASL")); + m.insert(QLatin1String("sasl"), authenticationToString(type)); + break; case MailTransport::Transport::EnumAuthenticationType::CLEAR: - m.insert( QLatin1String("auth"), QLatin1String("USER") ); - break; + m.insert(QLatin1String("auth"), QStringLiteral("USER")); + break; default: - m.insert( QLatin1String("auth"), authenticationToString( type ) ); - break; - } - return m; + m.insert(QLatin1String("auth"), authenticationToString(type)); + break; + } + return m; } -QString POPSession::authenticationToString( int type ) const +QString POPSession::authenticationToString(int type) const { - switch ( type ) { + switch (type) { case MailTransport::Transport::EnumAuthenticationType::LOGIN: - return QLatin1String("LOGIN"); + return QStringLiteral("LOGIN"); case MailTransport::Transport::EnumAuthenticationType::PLAIN: - return QLatin1String("PLAIN"); + return QStringLiteral("PLAIN"); case MailTransport::Transport::EnumAuthenticationType::CRAM_MD5: - return QLatin1String("CRAM-MD5"); + return QStringLiteral("CRAM-MD5"); case MailTransport::Transport::EnumAuthenticationType::DIGEST_MD5: - return QLatin1String("DIGEST-MD5"); + return QStringLiteral("DIGEST-MD5"); case MailTransport::Transport::EnumAuthenticationType::GSSAPI: - return QLatin1String("GSSAPI"); + return QStringLiteral("GSSAPI"); case MailTransport::Transport::EnumAuthenticationType::NTLM: - return QLatin1String("NTLM"); + return QStringLiteral("NTLM"); case MailTransport::Transport::EnumAuthenticationType::CLEAR: - return QLatin1String("USER"); + return QStringLiteral("USER"); case MailTransport::Transport::EnumAuthenticationType::APOP: - return QLatin1String("APOP"); + return QStringLiteral("APOP"); default: - break; - } - return QString(); + break; + } + return QString(); } -KUrl POPSession::getUrl() const +QUrl POPSession::getUrl() const { - KUrl url; + QUrl url; - if ( Settings::self()->useSSL() ) - url.setProtocol( QLatin1String("pop3s") ); - else - url.setProtocol( QLatin1String("pop3") ); + if (Settings::self()->useSSL()) { + url.setScheme(QLatin1String("pop3s")); + } else { + url.setScheme(QLatin1String("pop3")); + } - url.setUser( Settings::self()->login() ); - url.setPass( mPassword ); - url.setHost( Settings::self()->host() ); - url.setPort( Settings::self()->port() ); - return url; + url.setUserName(Settings::self()->login()); + url.setPassword(mPassword); + url.setHost(Settings::self()->host()); + url.setPort(Settings::self()->port()); + return url; } bool POPSession::connectSlave() { - mSlave = KIO::Scheduler::getConnectedSlave( getUrl(), slaveConfig() ); - return mSlave != 0; + mSlave = KIO::Scheduler::getConnectedSlave(getUrl(), slaveConfig()); + return mSlave != Q_NULLPTR; } void POPSession::abortCurrentJob() { - if ( mCurrentJob ) { - mCurrentJob->kill( KJob::Quietly ); - mCurrentJob = 0; - } + if (mCurrentJob) { + mCurrentJob->kill(KJob::Quietly); + mCurrentJob = Q_NULLPTR; + } } void POPSession::closeSession() { - if ( mSlave ) { - KIO::Scheduler::disconnectSlave( mSlave ); - } + if (mSlave) { + KIO::Scheduler::disconnectSlave(mSlave); + } } -KIO::Slave* POPSession::getSlave() const +KIO::Slave *POPSession::getSlave() const { - return mSlave; + return mSlave; } - - - - -static QByteArray cleanupListRespone( const QByteArray &response ) +static QByteArray cleanupListRespone(const QByteArray &response) { - QByteArray ret = response.simplified(); // Workaround for Maillennium POP3/UNIBOX + QByteArray ret = response.simplified(); // Workaround for Maillennium POP3/UNIBOX - // Get rid of the null terminating character, if it exists - if ( ret.size() > 0 && ret.at( ret.size() - 1 ) == 0 ) - ret.chop( 1 ); - return ret; + // Get rid of the null terminating character, if it exists + if (ret.size() > 0 && ret.at(ret.size() - 1) == 0) { + ret.chop(1); + } + return ret; } -static QString intListToString( const QList &intList ) +static QString intListToString(const QList &intList) { - QString idList; - foreach( int id, intList ) - idList += QString::number( id ) + QLatin1Char(','); - idList.chop( 1 ); - return idList; + QString idList; + foreach (int id, intList) { + idList += QString::number(id) + QLatin1Char(','); + } + idList.chop(1); + return idList; } - - - -SlaveBaseJob::SlaveBaseJob( POPSession *POPSession ) - : mJob( 0 ), - mPOPSession( POPSession ) +SlaveBaseJob::SlaveBaseJob(POPSession *POPSession) + : mJob(Q_NULLPTR), + mPOPSession(POPSession) { - mPOPSession->setCurrentJob( this ); + mPOPSession->setCurrentJob(this); } SlaveBaseJob::~SlaveBaseJob() { - // Don't do that here, the job might be destroyed after another one was started - // and therefore overwrite the current job - //mPOPSession->setCurrentJob( 0 ); + // Don't do that here, the job might be destroyed after another one was started + // and therefore overwrite the current job + //mPOPSession->setCurrentJob( 0 ); } bool SlaveBaseJob::doKill() { - if ( mJob ) - return mJob->kill(); - else - return KJob::doKill(); + if (mJob) { + return mJob->kill(); + } else { + return KJob::doKill(); + } } -void SlaveBaseJob::slotSlaveResult( KJob *job ) +void SlaveBaseJob::slotSlaveResult(KJob *job) { - mPOPSession->setCurrentJob( 0 ); - if ( job->error() ) { - setError( job->error() ); - setErrorText( job->errorText() ); - } - emitResult(); - mJob = 0; + mPOPSession->setCurrentJob(Q_NULLPTR); + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + } + emitResult(); + mJob = Q_NULLPTR; } -void SlaveBaseJob::slotSlaveData( KIO::Job *job, const QByteArray &data ) +void SlaveBaseJob::slotSlaveData(KIO::Job *job, const QByteArray &data) { - Q_UNUSED( job ); - kWarning() << "Got unexpected slave data:" << data.data(); + Q_UNUSED(job); + qCWarning(POP3RESOURCE_LOG) << "Got unexpected slave data:" << data.data(); } -void SlaveBaseJob::slaveError( int errorCode, const QString &errorMessage ) +void SlaveBaseJob::slaveError(int errorCode, const QString &errorMessage) { - // The slave experienced some problem while running our job. - // Just treat this as an error. - // Derived jobs can do something more sophisticated here - setError( errorCode ); - setErrorText( errorMessage); - emitResult(); - mJob = 0; + // The slave experienced some problem while running our job. + // Just treat this as an error. + // Derived jobs can do something more sophisticated here + setError(errorCode); + setErrorText(errorMessage); + emitResult(); + mJob = Q_NULLPTR; } void SlaveBaseJob::connectJob() { - connect( mJob, SIGNAL(data(KIO::Job*,QByteArray)), - SLOT(slotSlaveData(KIO::Job*,QByteArray)) ); - connect( mJob, SIGNAL(result(KJob*)), - SLOT(slotSlaveResult(KJob*)) ); + connect(mJob, &KIO::TransferJob::data, this, &SlaveBaseJob::slotSlaveData); + connect(mJob, &KIO::TransferJob::result, this, &SlaveBaseJob::slotSlaveResult); } -void SlaveBaseJob::startJob( const QString &path) -{ - KUrl url = mPOPSession->getUrl(); - url.setPath( path ); - mJob = KIO::get( url, KIO::NoReload, KIO::HideProgressInfo ); - KIO::Scheduler::assignJobToSlave( mPOPSession->getSlave(), mJob ); - connectJob(); +void SlaveBaseJob::startJob(const QString &path) +{ + QUrl url = mPOPSession->getUrl(); + url.setPath(path); + mJob = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo); + KIO::Scheduler::assignJobToSlave(mPOPSession->getSlave(), mJob); + connectJob(); } QString SlaveBaseJob::errorString() const { - if ( mJob ) { - return mJob->errorString(); - } else { - return KJob::errorString(); - } + if (mJob) { + return mJob->errorString(); + } else { + return KJob::errorString(); + } } - -LoginJob::LoginJob( POPSession *popSession ) - : SlaveBaseJob( popSession ) +LoginJob::LoginJob(POPSession *popSession) + : SlaveBaseJob(popSession) { } void LoginJob::start() { - // This will create a connected slave, which means it will also try to login. - KIO::Scheduler::connect( SIGNAL(slaveConnected(KIO::Slave*)), - this, SLOT(slaveConnected(KIO::Slave*))); - if ( !mPOPSession->connectSlave() ) { - setError ( KJob::UserDefinedError ); - setErrorText( i18n( "Unable to create POP3 slave, aborting mail check." ) ); - emitResult(); - } + // This will create a connected slave, which means it will also try to login. + KIO::Scheduler::connect(SIGNAL(slaveConnected(KIO::Slave*)), this, SLOT(slaveConnected(KIO::Slave*))); + if (!mPOPSession->connectSlave()) { + setError(KJob::UserDefinedError); + setErrorText(i18n("Unable to create POP3 slave, aborting mail check.")); + emitResult(); + } } -void LoginJob::slaveConnected( KIO::Slave *slave ) +void LoginJob::slaveConnected(KIO::Slave *slave) { - if ( slave != mPOPSession->getSlave() ) { - // Odd, not our slave... - return; - } + if (slave != mPOPSession->getSlave()) { + // Odd, not our slave... + return; + } - // Yeah it connected, so login was sucessful! - emitResult(); + // Yeah it connected, so login was sucessful! + emitResult(); } -void LoginJob::slaveError( int errorCode, const QString &errorMessage ) +void LoginJob::slaveError(int errorCode, const QString &errorMessage) { - setError( errorCode ); - setErrorText( errorMessage ); - mErrorString = KIO::buildErrorString( errorCode, errorMessage ); - emitResult(); + setError(errorCode); + setErrorText(errorMessage); + mErrorString = KIO::buildErrorString(errorCode, errorMessage); + emitResult(); } QString LoginJob::errorString() const { - return mErrorString; + return mErrorString; } -ListJob::ListJob( POPSession *popSession ) - : SlaveBaseJob( popSession ) +ListJob::ListJob(POPSession *popSession) + : SlaveBaseJob(popSession) { } void ListJob::start() { - startJob( QLatin1String("/index") ); + startJob(QLatin1String("/index")); } -void ListJob::slotSlaveData( KIO::Job *job, const QByteArray &data ) +void ListJob::slotSlaveData(KIO::Job *job, const QByteArray &data) { - Q_UNUSED( job ); - - // Silly slave, why are you sending us empty data? - if ( data.isEmpty() ) - return; + Q_UNUSED(job); - QByteArray cleanData = cleanupListRespone( data ); - const int space = cleanData.indexOf( ' ' ); - - if ( space > 0 ) { - QByteArray lengthString = cleanData.mid( space + 1 ); - const int spaceInLengthPos = lengthString.indexOf( ' ' ); - if ( spaceInLengthPos != -1 ) - lengthString.truncate( spaceInLengthPos ); - const int length = lengthString.toInt(); + // Silly slave, why are you sending us empty data? + if (data.isEmpty()) { + return; + } - QByteArray idString = cleanData.left( space ); + QByteArray cleanData = cleanupListRespone(data); + const int space = cleanData.indexOf(' '); - bool idIsNumber; - int id = QString::fromLatin1( idString ).toInt( &idIsNumber ); - if ( idIsNumber ) - mIdList.insert( id, length ); - else - kWarning() << "Got non-integer ID as part of the LIST response, ignoring" - << idString.data(); - } - else { - kWarning() << "Got invalid LIST response:" << data.data(); - } + if (space > 0) { + QByteArray lengthString = cleanData.mid(space + 1); + const int spaceInLengthPos = lengthString.indexOf(' '); + if (spaceInLengthPos != -1) { + lengthString.truncate(spaceInLengthPos); + } + const int length = lengthString.toInt(); + + QByteArray idString = cleanData.left(space); + + bool idIsNumber; + int id = QString::fromLatin1(idString).toInt(&idIsNumber); + if (idIsNumber) { + mIdList.insert(id, length); + } else + qCWarning(POP3RESOURCE_LOG) << "Got non-integer ID as part of the LIST response, ignoring" + << idString.data(); + } else { + qCWarning(POP3RESOURCE_LOG) << "Got invalid LIST response:" << data.data(); + } } -QMap ListJob::idList() const +QMap ListJob::idList() const { - return mIdList; + return mIdList; } -UIDListJob::UIDListJob( POPSession *popSession ) - : SlaveBaseJob( popSession ) +UIDListJob::UIDListJob(POPSession *popSession) + : SlaveBaseJob(popSession) { } void UIDListJob::start() { - startJob( QLatin1String("/uidl") ); + startJob(QLatin1String("/uidl")); } -void UIDListJob::slotSlaveData( KIO::Job *job, const QByteArray &data ) +void UIDListJob::slotSlaveData(KIO::Job *job, const QByteArray &data) { - Q_UNUSED( job ); + Q_UNUSED(job); - // Silly slave, why are you sending us empty data? - if ( data.isEmpty() ) - return; + // Silly slave, why are you sending us empty data? + if (data.isEmpty()) { + return; + } - QByteArray cleanData = cleanupListRespone( data ); - const int space = cleanData.indexOf( ' ' ); + QByteArray cleanData = cleanupListRespone(data); + const int space = cleanData.indexOf(' '); - if ( space <= 0 ) { - kWarning() << "Invalid response to the UIDL command:" << data.data(); - kWarning() << "Ignoring this entry."; - } - else { - QByteArray idString = cleanData.left( space ); - QByteArray uidString = cleanData.mid( space + 1 ); - bool idIsNumber; - int id = QString::fromLatin1( idString ).toInt( &idIsNumber ); - if ( idIsNumber ) { - const QString uidQString = QString::fromLatin1( uidString ); - if ( !uidQString.isEmpty() ) { - mUidList.insert( id, uidQString ); - mIdList.insert( uidQString, id ); - } - else { - kWarning() << "Got invalid/empty UID from the UIDL command:" - << uidString.data(); - kWarning() << "The whole response was:" << data.data(); - } - } - else { - kWarning() << "Got invalid ID from the UIDL command:" << idString.data(); - kWarning() << "The whole response was:" << data.data(); + if (space <= 0) { + qCWarning(POP3RESOURCE_LOG) << "Invalid response to the UIDL command:" << data.data(); + qCWarning(POP3RESOURCE_LOG) << "Ignoring this entry."; + } else { + QByteArray idString = cleanData.left(space); + QByteArray uidString = cleanData.mid(space + 1); + bool idIsNumber; + int id = QString::fromLatin1(idString).toInt(&idIsNumber); + if (idIsNumber) { + const QString uidQString = QString::fromLatin1(uidString); + if (!uidQString.isEmpty()) { + mUidList.insert(id, uidQString); + mIdList.insert(uidQString, id); + } else { + qCWarning(POP3RESOURCE_LOG) << "Got invalid/empty UID from the UIDL command:" + << uidString.data(); + qCWarning(POP3RESOURCE_LOG) << "The whole response was:" << data.data(); + } + } else { + qCWarning(POP3RESOURCE_LOG) << "Got invalid ID from the UIDL command:" << idString.data(); + qCWarning(POP3RESOURCE_LOG) << "The whole response was:" << data.data(); + } } - } } -QMap UIDListJob::uidList() const +QMap UIDListJob::uidList() const { - return mUidList; + return mUidList; } -QMap UIDListJob::idList() const +QMap UIDListJob::idList() const { - return mIdList; + return mIdList; } -DeleteJob::DeleteJob( POPSession *popSession ) - : SlaveBaseJob( popSession ) +DeleteJob::DeleteJob(POPSession *popSession) + : SlaveBaseJob(popSession) { } -void DeleteJob::setDeleteIds(const QList &ids ) +void DeleteJob::setDeleteIds(const QList &ids) { - mIdsToDelete = ids; + mIdsToDelete = ids; } void DeleteJob::start() { - startJob( QLatin1String("/remove/") + intListToString( mIdsToDelete ) ); + startJob(QLatin1String("/remove/") + intListToString(mIdsToDelete)); } QList DeleteJob::deletedIDs() const { - // FIXME : The slave doesn't tell us which of the IDs were actually deleted, we - // just assume all of them here - return mIdsToDelete; + // FIXME : The slave doesn't tell us which of the IDs were actually deleted, we + // just assume all of them here + return mIdsToDelete; } -QuitJob::QuitJob( POPSession *popSession ) - : SlaveBaseJob( popSession ) +QuitJob::QuitJob(POPSession *popSession) + : SlaveBaseJob(popSession) { } void QuitJob::start() { - startJob( QLatin1String("/commit") ); + startJob(QLatin1String("/commit")); } -FetchJob::FetchJob ( POPSession *session ) - : SlaveBaseJob( session ), - mBytesDownloaded( 0 ), - mTotalBytesToDownload( 0 ), - mDataCounter( 0 ) +FetchJob::FetchJob(POPSession *session) + : SlaveBaseJob(session), + mBytesDownloaded(0), + mTotalBytesToDownload(0), + mDataCounter(0) { } -void FetchJob::setFetchIds( const QList &ids, const QList &sizes ) +void FetchJob::setFetchIds(const QList &ids, const QList &sizes) { - mIdsPendingDownload = ids; - foreach( int size, sizes ) - mTotalBytesToDownload += size; + mIdsPendingDownload = ids; + foreach (int size, sizes) { + mTotalBytesToDownload += size; + } } void FetchJob::start() { - startJob( QLatin1String("/download/") + intListToString( mIdsPendingDownload ) ); - setTotalAmount( KJob::Bytes, mTotalBytesToDownload ); + startJob(QLatin1String("/download/") + intListToString(mIdsPendingDownload)); + setTotalAmount(KJob::Bytes, mTotalBytesToDownload); } void FetchJob::connectJob() { - SlaveBaseJob::connectJob(); - connect( mJob, SIGNAL(infoMessage(KJob*,QString,QString)), - SLOT(slotInfoMessage(KJob*,QString,QString)) ); + SlaveBaseJob::connectJob(); + connect(mJob, &KIO::TransferJob::infoMessage, this, &FetchJob::slotInfoMessage); } -void FetchJob::slotSlaveData( KIO::Job *job, const QByteArray &data ) +void FetchJob::slotSlaveData(KIO::Job *job, const QByteArray &data) { - Q_UNUSED( job ); - mCurrentMessage += data; - mBytesDownloaded += data.size(); - mDataCounter++; - if ( mDataCounter % 5 == 0 ) { - setProcessedAmount( KJob::Bytes, mBytesDownloaded ); - } + Q_UNUSED(job); + mCurrentMessage += data; + mBytesDownloaded += data.size(); + mDataCounter++; + if (mDataCounter % 5 == 0) { + setProcessedAmount(KJob::Bytes, mBytesDownloaded); + } } -void FetchJob::slotInfoMessage( KJob *job, const QString &infoMessage, const QString & ) +void FetchJob::slotInfoMessage(KJob *job, const QString &infoMessage, const QString &) { - Q_UNUSED( job ); - if ( infoMessage != QLatin1String("message complete") ) - return; - - KMime::Message::Ptr msg( new KMime::Message ); - msg->setContent( KMime::CRLFtoLF( mCurrentMessage ) ); - msg->parse(); + Q_UNUSED(job); + if (infoMessage != QLatin1String("message complete")) { + return; + } - mCurrentMessage.clear(); - const int idOfCurrentMessage = mIdsPendingDownload.takeFirst(); - emit messageFinished( idOfCurrentMessage, msg ); + KMime::Message::Ptr msg(new KMime::Message); + msg->setContent(KMime::CRLFtoLF(mCurrentMessage)); + msg->parse(); + + mCurrentMessage.clear(); + const int idOfCurrentMessage = mIdsPendingDownload.takeFirst(); + Q_EMIT messageFinished(idOfCurrentMessage, msg); } - diff -Nru kdepim-runtime-4.14.6/resources/pop3/jobs.h kdepim-runtime-15.08.0/resources/pop3/jobs.h --- kdepim-runtime-4.14.6/resources/pop3/jobs.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/jobs.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,7 +20,7 @@ #define JOBS_H #include -#include +#include #include #include @@ -32,176 +32,171 @@ namespace KIO { - class Slave; - class Job; - class TransferJob; +class Slave; +class Job; +class TransferJob; } class SlaveBaseJob; class POPSession : public QObject { - Q_OBJECT + Q_OBJECT public: - explicit POPSession( const QString &password ); - ~POPSession(); - bool connectSlave(); + explicit POPSession(const QString &password); + ~POPSession(); + bool connectSlave(); - void abortCurrentJob(); - void closeSession(); + void abortCurrentJob(); + void closeSession(); - KIO::Slave* getSlave() const; - KUrl getUrl() const; + KIO::Slave *getSlave() const; + QUrl getUrl() const; - // Sets the current SlaveBaseJob that is using the POPSession. - // If there is a job, all slave errors will be forwared to that job - void setCurrentJob( SlaveBaseJob *job ); + // Sets the current SlaveBaseJob that is using the POPSession. + // If there is a job, all slave errors will be forwared to that job + void setCurrentJob(SlaveBaseJob *job); -private slots: - void slotSlaveError( KIO::Slave *slave , int, const QString & ); +private Q_SLOTS: + void slotSlaveError(KIO::Slave *slave , int, const QString &); -signals: +Q_SIGNALS: - // An error occurred within the slave. If there is a current job, this - // signal is not emitted, as the job deals with it. - void slaveError( int errorCode, const QString &errorMessage ); + // An error occurred within the slave. If there is a current job, this + // signal is not emitted, as the job deals with it. + void slaveError(int errorCode, const QString &errorMessage); private: - KIO::MetaData slaveConfig() const; - QString authenticationToString( int type ) const; + KIO::MetaData slaveConfig() const; + QString authenticationToString(int type) const; - QPointer mSlave; - SlaveBaseJob *mCurrentJob; - QString mPassword; + QPointer mSlave; + SlaveBaseJob *mCurrentJob; + QString mPassword; }; - class SlaveBaseJob : public KJob { - Q_OBJECT + Q_OBJECT public: - explicit SlaveBaseJob( POPSession *POPSession ); - ~SlaveBaseJob(); + explicit SlaveBaseJob(POPSession *POPSession); + ~SlaveBaseJob(); - virtual void slaveError( int errorCode, const QString &errorMessage ); + virtual void slaveError(int errorCode, const QString &errorMessage); -protected slots: - virtual void slotSlaveData( KIO::Job *job, const QByteArray &data ); - virtual void slotSlaveResult( KJob *job ); +protected Q_SLOTS: + virtual void slotSlaveData(KIO::Job *job, const QByteArray &data); + virtual void slotSlaveResult(KJob *job); protected: - virtual QString errorString() const; - virtual bool doKill(); - void startJob( const QString &path ); - virtual void connectJob(); + QString errorString() const Q_DECL_OVERRIDE; + bool doKill() Q_DECL_OVERRIDE; + void startJob(const QString &path); + virtual void connectJob(); - KIO::TransferJob *mJob; - POPSession *mPOPSession; + KIO::TransferJob *mJob; + POPSession *mPOPSession; }; class LoginJob : public SlaveBaseJob { - Q_OBJECT + Q_OBJECT public: - LoginJob( POPSession *popSession ); - virtual void start(); + LoginJob(POPSession *popSession); + void start() Q_DECL_OVERRIDE; protected: - virtual QString errorString() const; + QString errorString() const Q_DECL_OVERRIDE; -private slots: - void slaveConnected( KIO::Slave *slave ); +private Q_SLOTS: + void slaveConnected(KIO::Slave *slave); private: - virtual void slaveError( int errorCode, const QString &errorMessage ); + void slaveError(int errorCode, const QString &errorMessage) Q_DECL_OVERRIDE; - QString mErrorString; + QString mErrorString; }; - class ListJob : public SlaveBaseJob { - Q_OBJECT + Q_OBJECT public: - ListJob( POPSession *popSession ); - QMap idList() const; - virtual void start(); + ListJob(POPSession *popSession); + QMap idList() const; + void start() Q_DECL_OVERRIDE; private: - virtual void slotSlaveData( KIO::Job *job, const QByteArray &data ); + void slotSlaveData(KIO::Job *job, const QByteArray &data) Q_DECL_OVERRIDE; private: - QMap mIdList; + QMap mIdList; }; - class UIDListJob : public SlaveBaseJob { - Q_OBJECT + Q_OBJECT public: - UIDListJob( POPSession *popSession ); - QMap uidList() const; - QMap idList() const; - virtual void start(); + UIDListJob(POPSession *popSession); + QMap uidList() const; + QMap idList() const; + void start() Q_DECL_OVERRIDE; private: - virtual void slotSlaveData( KIO::Job *job, const QByteArray &data ); + void slotSlaveData(KIO::Job *job, const QByteArray &data) Q_DECL_OVERRIDE; - QMap mUidList; - QMap mIdList; + QMap mUidList; + QMap mIdList; }; class DeleteJob : public SlaveBaseJob { - Q_OBJECT + Q_OBJECT public: - DeleteJob( POPSession *popSession ); - void setDeleteIds( const QList &ids ); - virtual void start(); - QList deletedIDs() const; + DeleteJob(POPSession *popSession); + void setDeleteIds(const QList &ids); + void start() Q_DECL_OVERRIDE; + QList deletedIDs() const; private: - QList mIdsToDelete; + QList mIdsToDelete; }; class QuitJob : public SlaveBaseJob { - Q_OBJECT + Q_OBJECT public: - QuitJob( POPSession *popSession ); - virtual void start(); + QuitJob(POPSession *popSession); + void start() Q_DECL_OVERRIDE; }; - class FetchJob : public SlaveBaseJob { - Q_OBJECT + Q_OBJECT public: - FetchJob( POPSession *session ); - void setFetchIds( const QList &ids, const QList &sizes ); - virtual void start(); + FetchJob(POPSession *session); + void setFetchIds(const QList &ids, const QList &sizes); + void start() Q_DECL_OVERRIDE; -private slots: - void slotInfoMessage( KJob *job, const QString &infoMessage, const QString & ); +private Q_SLOTS: + void slotInfoMessage(KJob *job, const QString &infoMessage, const QString &); -signals: - void messageFinished( int id, KMime::Message::Ptr message ); +Q_SIGNALS: + void messageFinished(int id, KMime::Message::Ptr message); private: - virtual void connectJob(); - virtual void slotSlaveData( KIO::Job *job, const QByteArray &data ); + void connectJob() Q_DECL_OVERRIDE; + void slotSlaveData(KIO::Job *job, const QByteArray &data) Q_DECL_OVERRIDE; - QList mIdsPendingDownload; - QByteArray mCurrentMessage; - int mBytesDownloaded; - int mTotalBytesToDownload; - uint mDataCounter; + QList mIdsPendingDownload; + QByteArray mCurrentMessage; + int mBytesDownloaded; + int mTotalBytesToDownload; + uint mDataCounter; }; - #endif // JOBS_H diff -Nru kdepim-runtime-4.14.6/resources/pop3/metatype.h kdepim-runtime-15.08.0/resources/pop3/metatype.h --- kdepim-runtime-4.14.6/resources/pop3/metatype.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/metatype.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,6 +24,6 @@ #include -Q_DECLARE_METATYPE(QList) +//Q_DECLARE_METATYPE(QList) #endif diff -Nru kdepim-runtime-4.14.6/resources/pop3/pop3resourceattribute.cpp kdepim-runtime-15.08.0/resources/pop3/pop3resourceattribute.cpp --- kdepim-runtime-4.14.6/resources/pop3/pop3resourceattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/pop3resourceattribute.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/* - Copyright (c) 2013-2015 Montel Laurent - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#include "pop3resourceattribute.h" - -#include -#include -#include - -class Pop3ResourceAttributePrivate -{ -public: - Pop3ResourceAttributePrivate() - { - } - QString accountName; -}; - -Pop3ResourceAttribute::Pop3ResourceAttribute() - : d(new Pop3ResourceAttributePrivate) -{ -} - -Pop3ResourceAttribute::~Pop3ResourceAttribute() -{ - delete d; -} - -Pop3ResourceAttribute *Pop3ResourceAttribute::clone() const -{ - Pop3ResourceAttribute *attr = new Pop3ResourceAttribute(); - attr->setPop3AccountName(pop3AccountName()); - return attr; -} - -QByteArray Pop3ResourceAttribute::type() const -{ - static const QByteArray sType( "pop3resourceattribute" ); - return sType; -} - -QByteArray Pop3ResourceAttribute::serialized() const -{ - QByteArray result; - QDataStream s( &result, QIODevice::WriteOnly ); - s << pop3AccountName(); - return result; -} - -void Pop3ResourceAttribute::deserialize( const QByteArray &data ) -{ - QDataStream s( data ); - QString value; - s >> value; - d->accountName = value; -} - -QString Pop3ResourceAttribute::pop3AccountName() const -{ - return d->accountName; -} - -void Pop3ResourceAttribute::setPop3AccountName(const QString &accountName) -{ - d->accountName = accountName; -} - diff -Nru kdepim-runtime-4.14.6/resources/pop3/pop3resourceattribute.h kdepim-runtime-15.08.0/resources/pop3/pop3resourceattribute.h --- kdepim-runtime-4.14.6/resources/pop3/pop3resourceattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/pop3resourceattribute.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -/* - Copyright (c) 2013-2015 Montel Laurent - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef POP3RESOURCEATTRIBUTE_H -#define POP3RESOURCEATTRIBUTE_H - -#include - -class Pop3ResourceAttributePrivate; -class Pop3ResourceAttribute : public Akonadi::Attribute -{ -public: - Pop3ResourceAttribute(); - ~Pop3ResourceAttribute(); - - /* reimpl */ - Pop3ResourceAttribute *clone() const; - QByteArray type() const; - QByteArray serialized() const; - void deserialize( const QByteArray &data ); - - QString pop3AccountName() const; - void setPop3AccountName(const QString &accountName); - -private: - friend class Pop3ResourceAttributePrivate; - Pop3ResourceAttributePrivate * const d; -}; - - -#endif // POP3RESOURCEATTRIBUTE_H diff -Nru kdepim-runtime-4.14.6/resources/pop3/pop3resource.cpp kdepim-runtime-15.08.0/resources/pop3/pop3resource.cpp --- kdepim-runtime-4.14.6/resources/pop3/pop3resource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/pop3resource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -20,21 +20,24 @@ #include "accountdialog.h" #include "settings.h" #include "jobs.h" -#include "pop3resourceattribute.h" +#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include -#include -#include +#include +#include +#include +#include #include #include #include +#include "pop3resource_debug.h" #include @@ -42,961 +45,921 @@ using namespace MailTransport; using namespace KWallet; -POP3Resource::POP3Resource( const QString &id ) - : ResourceBase( id ), - mState( Idle ), - mPopSession( 0 ), - mAskAgain( false ), - mIntervalTimer( new QTimer( this ) ), - mTestLocalInbox( false ), - mWallet( 0 ) -{ - Akonadi::AttributeFactory::registerAttribute(); - setNeedsNetwork( true ); - Settings::self()->setResourceId( identifier() ); - resetState(); - - connect( this, SIGNAL(abortRequested()), - this, SLOT(slotAbortRequested()) ); - connect( mIntervalTimer, SIGNAL(timeout()), - this, SLOT(intervalCheckTriggered()) ); - connect( this, SIGNAL(reloadConfiguration()), SLOT(configurationChanged()) ); +POP3Resource::POP3Resource(const QString &id) + : ResourceBase(id), + mState(Idle), + mPopSession(Q_NULLPTR), + mAskAgain(false), + mIntervalTimer(new QTimer(this)), + mTestLocalInbox(false), + mWallet(Q_NULLPTR) +{ + Akonadi::AttributeFactory::registerAttribute(); + setNeedsNetwork(true); + Settings::self()->setResourceId(identifier()); + resetState(); + + connect(this, &POP3Resource::abortRequested, this, &POP3Resource::slotAbortRequested); + connect(mIntervalTimer, SIGNAL(timeout()), + this, SLOT(intervalCheckTriggered())); + connect(this, &POP3Resource::reloadConfiguration, this, &POP3Resource::configurationChanged); } POP3Resource::~POP3Resource() { - Settings::self()->writeConfig(); - delete mWallet; - mWallet = 0; + Settings::self()->save(); + delete mWallet; + mWallet = Q_NULLPTR; } void POP3Resource::configurationChanged() { - Settings::self()->writeConfig(); - updateIntervalTimer(); + Settings::self()->save(); + updateIntervalTimer(); } void POP3Resource::updateIntervalTimer() { - if ( Settings::self()->intervalCheckEnabled() && mState == Idle ) { - mIntervalTimer->start( Settings::self()->intervalCheckInterval() * 1000 * 60 ); - } - else { - mIntervalTimer->stop(); - } + if (Settings::self()->intervalCheckEnabled() && mState == Idle) { + mIntervalTimer->start(Settings::self()->intervalCheckInterval() * 1000 * 60); + } else { + mIntervalTimer->stop(); + } } void POP3Resource::intervalCheckTriggered() { - Q_ASSERT( mState == Idle ); - if ( isOnline() ) { - kDebug() << "Starting interval mail check."; - startMailCheck(); - mIntervalCheckInProgress = true; - } else { - mIntervalTimer->start(); - } + Q_ASSERT(mState == Idle); + if (isOnline()) { + qCDebug(POP3RESOURCE_LOG) << "Starting interval mail check."; + startMailCheck(); + mIntervalCheckInProgress = true; + } else { + mIntervalTimer->start(); + } } void POP3Resource::aboutToQuit() { - if ( mState != Idle ) - cancelSync( i18n( "Mail check aborted." ) ); + if (mState != Idle) { + cancelSync(i18n("Mail check aborted.")); + } } void POP3Resource::slotAbortRequested() { - if ( mState != Idle ) - cancelSync( i18n( "Mail check was canceled manually." ), false /* no error */ ); + if (mState != Idle) { + cancelSync(i18n("Mail check was canceled manually."), false /* no error */); + } } -void POP3Resource::configure( WId windowId ) +void POP3Resource::configure(WId windowId) { - QPointer accountDialog( new AccountDialog( this, windowId ) ); - if ( accountDialog->exec() == QDialog::Accepted ) { - updateIntervalTimer(); - emit configurationDialogAccepted(); - } - else { - emit configurationDialogRejected(); - } + QPointer accountDialog(new AccountDialog(this, windowId)); + if (accountDialog->exec() == QDialog::Accepted) { + updateIntervalTimer(); + Q_EMIT configurationDialogAccepted(); + } else { + Q_EMIT configurationDialogRejected(); + } - delete accountDialog; + delete accountDialog; } -void POP3Resource::retrieveItems( const Akonadi::Collection &collection ) +void POP3Resource::retrieveItems(const Akonadi::Collection &collection) { - Q_UNUSED( collection ); - kWarning() << "This should never be called, we don't have a collection!"; + Q_UNUSED(collection); + qCWarning(POP3RESOURCE_LOG) << "This should never be called, we don't have a collection!"; } -bool POP3Resource::retrieveItem( const Akonadi::Item &item, const QSet &parts ) +bool POP3Resource::retrieveItem(const Akonadi::Item &item, const QSet &parts) { - Q_UNUSED( item ); - Q_UNUSED( parts ); - kWarning() << "This should never be called, we don't have any item!"; - return false; + Q_UNUSED(item); + Q_UNUSED(parts); + qCWarning(POP3RESOURCE_LOG) << "This should never be called, we don't have any item!"; + return false; } -QString POP3Resource::buildLabelForPasswordDialog( const QString &detailedError ) const +QString POP3Resource::buildLabelForPasswordDialog(const QString &detailedError) const { - QString queryText = i18n( "Please enter the username and password for account '%1'.", - agentName() ); - queryText += QLatin1String("
") + detailedError; - return queryText; + QString queryText = i18n("Please enter the username and password for account '%1'.", + agentName()); + queryText += QLatin1String("
") + detailedError; + return queryText; } -void POP3Resource::walletOpenedForLoading( bool success ) +void POP3Resource::walletOpenedForLoading(bool success) { - bool passwordLoaded = success; - if ( success ) { - if ( mWallet && mWallet->isOpen() && mWallet->hasFolder( QLatin1String("pop3") ) ) { - mWallet->setFolder( QLatin1String("pop3") ); - if ( mWallet->hasEntry( identifier() ) ) - mWallet->readPassword( identifier(), mPassword ); - else - passwordLoaded = false; - } - else { - passwordLoaded = false; + bool passwordLoaded = success; + if (success) { + if (mWallet && mWallet->isOpen() && mWallet->hasFolder(QStringLiteral("pop3"))) { + mWallet->setFolder(QStringLiteral("pop3")); + if (mWallet->hasEntry(identifier())) { + mWallet->readPassword(identifier(), mPassword); + } else { + passwordLoaded = false; + } + } else { + passwordLoaded = false; + } } - } - delete mWallet; - mWallet = 0; + delete mWallet; + mWallet = Q_NULLPTR; - if ( !passwordLoaded ) { - QString queryText = buildLabelForPasswordDialog( - i18n( "You are asked here because the password could not be loaded from the wallet." ) ); - showPasswordDialog( queryText ); - } - else { - advanceState( Connect ); - } + if (!passwordLoaded) { + QString queryText = buildLabelForPasswordDialog( + i18n("You are asked here because the password could not be loaded from the wallet.")); + showPasswordDialog(queryText); + } else { + advanceState(Connect); + } } -void POP3Resource::walletOpenedForSaving( bool success ) +void POP3Resource::walletOpenedForSaving(bool success) { - if ( success ) { - if ( mWallet && mWallet->isOpen() ) { - if ( !mWallet->hasFolder( QLatin1String("pop3") ) ) { - mWallet->createFolder( QLatin1String("pop3") ); - } - mWallet->setFolder( QLatin1String("pop3") ); - mWallet->writePassword( identifier(), mPassword ); + if (success) { + if (mWallet && mWallet->isOpen()) { + if (!mWallet->hasFolder(QStringLiteral("pop3"))) { + mWallet->createFolder(QStringLiteral("pop3")); + } + mWallet->setFolder(QStringLiteral("pop3")); + mWallet->writePassword(identifier(), mPassword); + } + } else { + qCWarning(POP3RESOURCE_LOG) << "Unable to write the password to the wallet."; } - } - else - kWarning() << "Unable to write the password to the wallet."; - delete mWallet; - mWallet = 0; - finish(); + delete mWallet; + mWallet = Q_NULLPTR; + finish(); } - -void POP3Resource::showPasswordDialog( const QString &queryText ) +void POP3Resource::showPasswordDialog(const QString &queryText) { - QPointer dlg = - new KPasswordDialog( - 0, - KPasswordDialog::ShowUsernameLine ); - dlg->setModal( true ); - dlg->setUsername( Settings::self()->login() ); - dlg->setPassword( mPassword ); - dlg->setPrompt( queryText ); - dlg->setCaption( name() ); - dlg->addCommentLine( i18n( "Account:" ), name() ); + QPointer dlg = + new KPasswordDialog( + Q_NULLPTR, + KPasswordDialog::ShowUsernameLine); + dlg->setModal(true); + dlg->setUsername(Settings::self()->login()); + dlg->setPassword(mPassword); + dlg->setPrompt(queryText); + dlg->setWindowTitle(name()); + dlg->addCommentLine(i18n("Account:"), name()); + + bool gotIt = false; + if (dlg->exec()) { + mPassword = dlg->password(); + Settings::self()->setLogin(dlg->username()); + Settings::self()->save(); + if (!dlg->password().isEmpty()) { + mSavePassword = true; + } - bool gotIt = false; - if ( dlg->exec() ) { - mPassword = dlg->password(); - Settings::self()->setLogin( dlg->username() ); - Settings::self()->writeConfig(); - if ( !dlg->password().isEmpty() ) { - mSavePassword = true; + mAskAgain = false; + advanceState(Connect); + gotIt = true; + } + delete dlg; + if (!gotIt) { + cancelSync(i18n("No username and password supplied.")); } - - mAskAgain = false; - advanceState( Connect ); - gotIt = true; - } - delete dlg; - if ( !gotIt ) { - cancelSync( i18n( "No username and password supplied." ) ); - } } -void POP3Resource::advanceState( State nextState ) +void POP3Resource::advanceState(State nextState) { - mState = nextState; - doStateStep(); + mState = nextState; + doStateStep(); } void POP3Resource::doStateStep() { - switch ( mState ) - { - case Idle: - { - Q_ASSERT( false ); - kWarning() << "State machine should not be called in idle state!"; - break; - } - case FetchTargetCollection: - { - kDebug() << "================ Starting state FetchTargetCollection =========="; - emit status( Running, i18n( "Preparing transmission from \"%1\".", name() ) ); - Collection targetCollection( Settings::self()->targetCollection() ); - if ( !targetCollection.isValid() ) { - // No target collection set in the config? Try requesting a default inbox - SpecialMailCollectionsRequestJob *requestJob = new SpecialMailCollectionsRequestJob( this ); - requestJob->requestDefaultCollection( SpecialMailCollections::Inbox ); - requestJob->start(); - connect ( requestJob, SIGNAL(result(KJob*)), - this, SLOT(localFolderRequestJobFinished(KJob*)) ); - } - else { - CollectionFetchJob *fetchJob = new CollectionFetchJob( targetCollection, - CollectionFetchJob::Base ); - fetchJob->start(); - connect( fetchJob, SIGNAL(result(KJob*)), - this, SLOT(targetCollectionFetchJobFinished(KJob*)) ); - } - break; - } - case Precommand: - { - kDebug() << "================ Starting state Precommand ====================="; - if ( !Settings::self()->precommand().isEmpty() ) { - PrecommandJob *precommandJob = new PrecommandJob( Settings::self()->precommand(), this ); - connect( precommandJob, SIGNAL(result(KJob*)), - this, SLOT(precommandResult(KJob*)) ); - precommandJob->start(); - emit status( Running, i18n( "Executing precommand." ) ); - } - else { - advanceState( RequestPassword ); - } - break; - } - case RequestPassword: - { - kDebug() << "================ Starting state RequestPassword ================"; - - // Don't show any wallet or password prompts when we are unit-testing - if ( !Settings::self()->unitTestPassword().isEmpty() ) { - mPassword = Settings::self()->unitTestPassword(); - advanceState( Connect ); + switch (mState) { + case Idle: { + Q_ASSERT(false); + qCWarning(POP3RESOURCE_LOG) << "State machine should not be called in idle state!"; + break; + } + case FetchTargetCollection: { + qCDebug(POP3RESOURCE_LOG) << "================ Starting state FetchTargetCollection =========="; + Q_EMIT status(Running, i18n("Preparing transmission from \"%1\".", name())); + Collection targetCollection(Settings::self()->targetCollection()); + if (!targetCollection.isValid()) { + // No target collection set in the config? Try requesting a default inbox + SpecialMailCollectionsRequestJob *requestJob = new SpecialMailCollectionsRequestJob(this); + requestJob->requestDefaultCollection(SpecialMailCollections::Inbox); + requestJob->start(); + connect(requestJob, &SpecialMailCollectionsRequestJob::result, this, &POP3Resource::localFolderRequestJobFinished); + } else { + CollectionFetchJob *fetchJob = new CollectionFetchJob(targetCollection, + CollectionFetchJob::Base); + fetchJob->start(); + connect(fetchJob, &CollectionFetchJob::result, this, &POP3Resource::targetCollectionFetchJobFinished); + } + break; + } + case Precommand: { + qCDebug(POP3RESOURCE_LOG) << "================ Starting state Precommand ====================="; + if (!Settings::self()->precommand().isEmpty()) { + PrecommandJob *precommandJob = new PrecommandJob(Settings::self()->precommand(), this); + connect(precommandJob, &PrecommandJob::result, this, &POP3Resource::precommandResult); + precommandJob->start(); + Q_EMIT status(Running, i18n("Executing precommand.")); + } else { + advanceState(RequestPassword); + } break; - } + } + case RequestPassword: { + qCDebug(POP3RESOURCE_LOG) << "================ Starting state RequestPassword ================"; - const bool passwordNeeded = Settings::self()->authenticationMethod() != MailTransport::Transport::EnumAuthenticationType::GSSAPI; - const bool loadPasswordFromWallet = !mAskAgain && passwordNeeded && !Settings::self()->login().isEmpty() && - mPassword.isEmpty(); - if ( loadPasswordFromWallet ) { - mWallet = Wallet::openWallet( Wallet::NetworkWallet(), winIdForDialogs(), - Wallet::Asynchronous ); - } - if ( loadPasswordFromWallet && mWallet ) { - connect( mWallet, SIGNAL(walletOpened(bool)), - this, SLOT(walletOpenedForLoading(bool)) ); - } - else if ( passwordNeeded && ( mPassword.isEmpty() || mAskAgain ) ) { - QString detail; - if ( mAskAgain ) - detail = i18n( "You are asked here because the previous login was not successful." ); - else if ( Settings::self()->login().isEmpty() ) - detail = i18n( "You are asked here because the username you supplied is empty." ); - else if ( !mWallet ) - detail = i18n( "You are asked here because the wallet password storage is disabled." ); - - showPasswordDialog( buildLabelForPasswordDialog( detail ) ); - } - else { - // No password needed or using previous password, go on with Connect - advanceState( Connect ); - } - - break; - } - case Connect: - { - kDebug() << "================ Starting state Connect ========================"; - Q_ASSERT( !mPopSession ); - mPopSession = new POPSession( mPassword ); - connect( mPopSession, SIGNAL(slaveError(int,QString)), - this, SLOT(slotSessionError(int,QString)) ); - advanceState( Login ); - break; - } - case Login: - { - kDebug() << "================ Starting state Login =========================="; - - LoginJob *loginJob = new LoginJob( mPopSession ); - connect( loginJob, SIGNAL(result(KJob*)), - this, SLOT(loginJobResult(KJob*)) ); - loginJob->start(); - break; - } - case List: - { - kDebug() << "================ Starting state List ==========================="; - emit status( Running, i18n( "Fetching mail listing." ) ); - ListJob *listJob = new ListJob( mPopSession ); - connect( listJob, SIGNAL(result(KJob*)), - this, SLOT(listJobResult(KJob*)) ); - listJob->start(); + // Don't show any wallet or password prompts when we are unit-testing + if (!Settings::self()->unitTestPassword().isEmpty()) { + mPassword = Settings::self()->unitTestPassword(); + advanceState(Connect); + break; + } + + const bool passwordNeeded = Settings::self()->authenticationMethod() != MailTransport::Transport::EnumAuthenticationType::GSSAPI; + const bool loadPasswordFromWallet = !mAskAgain && passwordNeeded && !Settings::self()->login().isEmpty() && + mPassword.isEmpty(); + if (loadPasswordFromWallet) { + mWallet = Wallet::openWallet(Wallet::NetworkWallet(), winIdForDialogs(), + Wallet::Asynchronous); + } + if (loadPasswordFromWallet && mWallet) { + connect(mWallet, &KWallet::Wallet::walletOpened, this, &POP3Resource::walletOpenedForLoading); + } else if (passwordNeeded && (mPassword.isEmpty() || mAskAgain)) { + QString detail; + if (mAskAgain) { + detail = i18n("You are asked here because the previous login was not successful."); + } else if (Settings::self()->login().isEmpty()) { + detail = i18n("You are asked here because the username you supplied is empty."); + } else if (!mWallet) { + detail = i18n("You are asked here because the wallet password storage is disabled."); + } + + showPasswordDialog(buildLabelForPasswordDialog(detail)); + } else { + // No password needed or using previous password, go on with Connect + advanceState(Connect); + } + + break; + } + case Connect: { + qCDebug(POP3RESOURCE_LOG) << "================ Starting state Connect ========================"; + Q_ASSERT(!mPopSession); + mPopSession = new POPSession(mPassword); + connect(mPopSession, &POPSession::slaveError, this, &POP3Resource::slotSessionError); + advanceState(Login); + break; + } + case Login: { + qCDebug(POP3RESOURCE_LOG) << "================ Starting state Login =========================="; + + LoginJob *loginJob = new LoginJob(mPopSession); + connect(loginJob, &LoginJob::result, this, &POP3Resource::loginJobResult); + loginJob->start(); + break; + } + case List: { + qCDebug(POP3RESOURCE_LOG) << "================ Starting state List ==========================="; + Q_EMIT status(Running, i18n("Fetching mail listing.")); + ListJob *listJob = new ListJob(mPopSession); + connect(listJob, &ListJob::result, this, &POP3Resource::listJobResult); + listJob->start(); } break; - case UIDList: - { - kDebug() << "================ Starting state UIDList ========================"; - UIDListJob *uidListJob = new UIDListJob( mPopSession ); - connect( uidListJob, SIGNAL(result(KJob*)), - this, SLOT(uidListJobResult(KJob*)) ); - uidListJob->start(); + case UIDList: { + qCDebug(POP3RESOURCE_LOG) << "================ Starting state UIDList ========================"; + UIDListJob *uidListJob = new UIDListJob(mPopSession); + connect(uidListJob, &UIDListJob::result, this, &POP3Resource::uidListJobResult); + uidListJob->start(); } break; - case Download: - { - kDebug() << "================ Starting state Download ======================="; - FetchJob *fetchJob = new FetchJob( mPopSession ); - - // Determine which mails we want to download. Those are all mails which are - // currently on ther server, minus the ones we have already downloaded (we - // remember which UIDs we have downloaded in the settings) - QList idsToDownload = mIdsToSizeMap.keys(); - const QList UIDsOnServer = mIdsToUidsMap.values(); - const QList alreadyDownloadedUIDs = Settings::self()->seenUidList(); - foreach( const QString &uidOnServer, UIDsOnServer ) { - if ( alreadyDownloadedUIDs.contains( uidOnServer ) ) { - const int idOfUIDOnServer = mUidsToIdsMap.value( uidOnServer, -1 ); - Q_ASSERT( idOfUIDOnServer != -1 ); - idsToDownload.removeAll( idOfUIDOnServer ); - } - } - mIdsToDownload = idsToDownload; - kDebug() << "We are going to download" << mIdsToDownload.size() << "messages"; - - // For proper progress, the job needs to know the sizes of the messages, so - // put them into a list here - QList sizesOfMessagesToDownload; - foreach( int id, idsToDownload ) { - sizesOfMessagesToDownload.append( mIdsToSizeMap.value( id ) ); - } - - fetchJob->setFetchIds( idsToDownload, sizesOfMessagesToDownload ); - connect( fetchJob, SIGNAL(result(KJob*)), - this, SLOT(fetchJobResult(KJob*)) ); - connect( fetchJob, SIGNAL(messageFinished(int,KMime::Message::Ptr)), - this, SLOT(messageFinished(int,KMime::Message::Ptr)) ); - connect( fetchJob, SIGNAL(processedAmount(KJob*,KJob::Unit,qulonglong)), - this, SLOT(messageDownloadProgress(KJob*,KJob::Unit,qulonglong)) ); - fetchJob->start(); + case Download: { + qCDebug(POP3RESOURCE_LOG) << "================ Starting state Download ======================="; + FetchJob *fetchJob = new FetchJob(mPopSession); + + // Determine which mails we want to download. Those are all mails which are + // currently on ther server, minus the ones we have already downloaded (we + // remember which UIDs we have downloaded in the settings) + QList idsToDownload = mIdsToSizeMap.keys(); + const QList alreadyDownloadedUIDs = Settings::self()->seenUidList(); + foreach (const QString &uidOnServer, mIdsToUidsMap) { + if (alreadyDownloadedUIDs.contains(uidOnServer)) { + const int idOfUIDOnServer = mUidsToIdsMap.value(uidOnServer, -1); + Q_ASSERT(idOfUIDOnServer != -1); + idsToDownload.removeAll(idOfUIDOnServer); + } + } + mIdsToDownload = idsToDownload; + qCDebug(POP3RESOURCE_LOG) << "We are going to download" << mIdsToDownload.size() << "messages"; + + // For proper progress, the job needs to know the sizes of the messages, so + // put them into a list here + QList sizesOfMessagesToDownload; + sizesOfMessagesToDownload.reserve(idsToDownload.count()); + foreach (int id, idsToDownload) { + sizesOfMessagesToDownload.append(mIdsToSizeMap.value(id)); + } + + fetchJob->setFetchIds(idsToDownload, sizesOfMessagesToDownload); + connect(fetchJob, &FetchJob::result, this, &POP3Resource::fetchJobResult); + connect(fetchJob, &FetchJob::messageFinished, this, &POP3Resource::messageFinished); + connect(fetchJob, SIGNAL(processedAmount(KJob*,KJob::Unit,qulonglong)), + this, SLOT(messageDownloadProgress(KJob*,KJob::Unit,qulonglong))); + + fetchJob->start(); } break; - case Save: - { - kDebug() << "================ Starting state Save ==========================="; - kDebug() << mPendingCreateJobs.size() << "item create jobs are pending"; - if ( mPendingCreateJobs.size() > 0 ) - emit status( Running, i18n( "Saving downloaded messages." ) ); - - // It can happen that the create job map is empty, for example if there was no - // mail to download or if all ItemCreateJob's finished before reaching this - // stage - if ( mPendingCreateJobs.isEmpty() ) { - advanceState( Delete ); - } + case Save: { + qCDebug(POP3RESOURCE_LOG) << "================ Starting state Save ==========================="; + qCDebug(POP3RESOURCE_LOG) << mPendingCreateJobs.size() << "item create jobs are pending"; + if (mPendingCreateJobs.size() > 0) { + Q_EMIT status(Running, i18n("Saving downloaded messages.")); + } + + // It can happen that the create job map is empty, for example if there was no + // mail to download or if all ItemCreateJob's finished before reaching this + // stage + if (mPendingCreateJobs.isEmpty()) { + advanceState(Delete); + } } break; - case Delete: - { - kDebug() << "================ Starting state Delete ========================="; - QList idsToKill = idsToDelete(); - if ( !idsToKill.isEmpty() ) { - emit status( Running, i18n( "Deleting messages from the server.") ); - DeleteJob *deleteJob = new DeleteJob( mPopSession ); - deleteJob->setDeleteIds( idsToKill ); - connect( deleteJob, SIGNAL(result(KJob*)), - this, SLOT(deleteJobResult(KJob*)) ); - deleteJob->start(); - } - else { - advanceState( Quit ); - } + case Delete: { + qCDebug(POP3RESOURCE_LOG) << "================ Starting state Delete ========================="; + QList idsToKill = idsToDelete(); + if (!idsToKill.isEmpty()) { + Q_EMIT status(Running, i18n("Deleting messages from the server.")); + DeleteJob *deleteJob = new DeleteJob(mPopSession); + deleteJob->setDeleteIds(idsToKill); + connect(deleteJob, &DeleteJob::result, this, &POP3Resource::deleteJobResult); + deleteJob->start(); + } else { + advanceState(Quit); + } } break; - case Quit: - { - kDebug() << "================ Starting state Quit ==========================="; - QuitJob *quitJob = new QuitJob( mPopSession ); - connect( quitJob, SIGNAL(result(KJob*)), - this, SLOT(quitJobResult(KJob*)) ); - quitJob->start(); + case Quit: { + qCDebug(POP3RESOURCE_LOG) << "================ Starting state Quit ==========================="; + QuitJob *quitJob = new QuitJob(mPopSession); + connect(quitJob, &QuitJob::result, this, &POP3Resource::quitJobResult); + quitJob->start(); } break; - case SavePassword: - { - kDebug() << "================ Starting state SavePassword ==================="; - if ( !mSavePassword ) - finish(); - else { - kDebug() << "Writing password back to the wallet."; - emit status( Running, i18n( "Saving password to the wallet." ) ); - mWallet = Wallet::openWallet( Wallet::NetworkWallet(), winIdForDialogs(), - Wallet::Asynchronous ); - if ( mWallet ) { - connect( mWallet, SIGNAL(walletOpened(bool)), - this, SLOT(walletOpenedForSaving(bool)) ); + case SavePassword: { + qCDebug(POP3RESOURCE_LOG) << "================ Starting state SavePassword ==================="; + if (!mSavePassword) { + finish(); } else { - finish(); + qCDebug(POP3RESOURCE_LOG) << "Writing password back to the wallet."; + Q_EMIT status(Running, i18n("Saving password to the wallet.")); + mWallet = Wallet::openWallet(Wallet::NetworkWallet(), winIdForDialogs(), + Wallet::Asynchronous); + if (mWallet) { + connect(mWallet, &KWallet::Wallet::walletOpened, this, &POP3Resource::walletOpenedForSaving); + } else { + finish(); + } } - } - break; + break; + } } - } } -void POP3Resource::localFolderRequestJobFinished( KJob *job ) -{ - if ( job->error() ) { - cancelSync( i18n( "Error while trying to get the local inbox folder, " - "aborting mail check." ) + QLatin1Char('\n') + job->errorString() ); - return; - } - if ( mTestLocalInbox ) { - KMessageBox::information(0, - i18n("The folder you deleted was associated with the account " - "%1 which delivered mail into it. The folder the account " - "delivers new mail into was reset to the main Inbox folder.", name())); - } - mTestLocalInbox = false; - - mTargetCollection = SpecialMailCollections::self()->defaultCollection( SpecialMailCollections::Inbox ); - Q_ASSERT( mTargetCollection.isValid() ); - advanceState( Precommand ); -} - -void POP3Resource::targetCollectionFetchJobFinished( KJob *job ) -{ - if ( job->error() ) { - if ( !mTestLocalInbox ) { - mTestLocalInbox = true; - Settings::self()->setTargetCollection( -1 ); - advanceState( FetchTargetCollection ); - return; - } else { - cancelSync( i18n( "Error while trying to get the folder for incoming mail, " - "aborting mail check." ) + QLatin1Char('\n') + job->errorString() ); - mTestLocalInbox = false; - return; - } - } - mTestLocalInbox = false; - Akonadi::CollectionFetchJob *fetchJob = - dynamic_cast( job ); - Q_ASSERT( fetchJob ); - Q_ASSERT( fetchJob->collections().size() <= 1 ); - - if ( fetchJob->collections().isEmpty() ) { - cancelSync( i18n( "Could not find folder for incoming mail, aborting mail check.") ); - return; - } - else { - mTargetCollection = fetchJob->collections().first(); - advanceState( Precommand ); - } -} - -void POP3Resource::precommandResult( KJob *job ) -{ - if ( job->error() ) { - cancelSync( i18n( "Error while executing precommand." ) + - QLatin1Char('\n') + job->errorString() ); - return; - } - else { - advanceState( RequestPassword ); - } -} - -void POP3Resource::loginJobResult( KJob *job ) -{ - if ( job->error() ) { - kDebug() << job->error() << job->errorText(); - if ( job->error() == KIO::ERR_COULD_NOT_LOGIN ) - mAskAgain = true; - cancelSync( i18n( "Unable to login to the server %1.", Settings::self()->host() ) + - QLatin1Char('\n') + job->errorString() ); - } - else { - advanceState( List ); - } -} - -void POP3Resource::listJobResult( KJob *job ) -{ - if ( job->error() ) { - cancelSync( i18n( "Error while getting the list of messages on the server." ) + - QLatin1Char('\n') + job->errorString() ); - } - else { - ListJob *listJob = dynamic_cast( job ); - Q_ASSERT( listJob ); - mIdsToSizeMap = listJob->idList(); - kDebug() << "IdsToSizeMap:" << mIdsToSizeMap; - advanceState( UIDList ); - } -} - -void POP3Resource::uidListJobResult( KJob *job ) -{ - if ( job->error() ) { - cancelSync( i18n( "Error while getting list of unique mail identifiers from the server." ) + - QLatin1Char('\n') + job->errorString() ); - } - else { - UIDListJob *listJob = dynamic_cast( job ); - Q_ASSERT( listJob ); - mIdsToUidsMap = listJob->uidList(); - mUidsToIdsMap = listJob->idList(); - kDebug() << "IdToUidMap:" << mIdsToUidsMap; - kDebug() << "UidToIdMap:" << mUidsToIdsMap; - - mUidListValid = !mIdsToUidsMap.isEmpty() || mIdsToSizeMap.isEmpty(); - if ( Settings::self()->leaveOnServer() && !mUidListValid ) { - // FIXME: this needs a proper parent window - KMessageBox::sorry( 0, - i18n( "Your POP3 server (Account: %1) does not support " - "the UIDL command: this command is required to determine, in a reliable way, " - "which of the mails on the server KMail has already seen before;\n" - "the feature to leave the mails on the server will therefore not " - "work properly.", name() ) ); - } - - advanceState( Download ); - } -} - -void POP3Resource::fetchJobResult( KJob *job ) -{ - if ( job->error() ) { - cancelSync( i18n( "Error while fetching mails from the server." ) + - QLatin1Char('\n') + job->errorString() ); - return; - } - else { - kDebug() << "Downloaded" << mDownloadedIDs.size() << "mails"; - - if ( !mIdsToDownload.isEmpty() ) { - kWarning() << "We did not download all messages, there are still some remaining " - "IDs, even though we requested their download:" << mIdsToDownload; - } - - advanceState( Save ); - } -} - -void POP3Resource::messageFinished( int messageId, KMime::Message::Ptr message ) -{ - if ( mState != Download ) { - // This can happen if the slave does not get notified in time about the fact - // that the job was killed - return; - } - - //kDebug() << "Got message" << messageId - // << "with subject" << message->subject()->asUnicodeString(); - - Akonadi::Item item; - item.setMimeType( QLatin1String("message/rfc822") ); - item.setPayload( message ); - - Pop3ResourceAttribute *attr = item.attribute( Akonadi::Entity::AddIfMissing ); - attr->setPop3AccountName( identifier() ); - - Akonadi::MessageFlags::copyMessageFlags(*message, item); - - ItemCreateJob *itemCreateJob = new ItemCreateJob( item, mTargetCollection ); - - mPendingCreateJobs.insert( itemCreateJob, messageId ); - connect( itemCreateJob, SIGNAL(result(KJob*)), - this, SLOT(itemCreateJobResult(KJob*)) ); - - mDownloadedIDs.append( messageId ); - mIdsToDownload.removeAll( messageId ); -} - -void POP3Resource::messageDownloadProgress( KJob *job, KJob::Unit unit, qulonglong totalBytes ) -{ - Q_UNUSED( totalBytes ); - Q_UNUSED( unit ); - Q_ASSERT( unit == KJob::Bytes ); - QString statusMessage; - const int totalMessages = mIdsToDownload.size() + mDownloadedIDs.size(); - int bytesRemainingOnServer = 0; - foreach( const QString &alreadyDownloadedUID, Settings::self()->seenUidList() ) { - const int alreadyDownloadedID = mUidsToIdsMap.value( alreadyDownloadedUID, -1 ); - if ( alreadyDownloadedID != -1 ) - bytesRemainingOnServer += mIdsToSizeMap.value( alreadyDownloadedID ); - } - - if ( Settings::self()->leaveOnServer() && bytesRemainingOnServer > 0 ) { - - statusMessage = i18n( "Fetching message %1 of %2 (%3 of %4 KB) for %5 " - "(%6 KB remain on the server).", - mDownloadedIDs.size() + 1, totalMessages, - job->processedAmount( KJob::Bytes ) / 1024, - job->totalAmount( KJob::Bytes ) / 1024, name(), - bytesRemainingOnServer / 1024 ); - } - else { - statusMessage = i18n( "Fetching message %1 of %2 (%3 of %4 KB) for %5", - mDownloadedIDs.size() +1, totalMessages, - job->processedAmount( KJob::Bytes ) / 1024, - job->totalAmount( KJob::Bytes ) / 1024, name() ); - } - emit status( Running, statusMessage ); - emit percent( job->percent() ); -} - -void POP3Resource::itemCreateJobResult( KJob *job ) -{ - if ( mState != Download && mState != Save ) { - // This can happen if the slave does not get notified in time about the fact - // that the job was killed - return; - } - - ItemCreateJob *createJob = dynamic_cast( job ); - Q_ASSERT( createJob ); - - if ( job->error() ) { - cancelSync( i18n( "Unable to store downloaded mails." ) + - QLatin1Char('\n') + job->errorString() ); - return; - } - - const int idOfMessageJustCreated = mPendingCreateJobs.value( createJob, -1 ); - Q_ASSERT( idOfMessageJustCreated != -1 ); - mPendingCreateJobs.remove( createJob ); - mIDsStored.append( idOfMessageJustCreated ); - //kDebug() << "Just stored message with ID" << idOfMessageJustCreated - // << "on the Akonadi server"; - - // Have all create jobs finished? Go to the next state, then - if ( mState == Save && mPendingCreateJobs.isEmpty() ) { - advanceState( Delete ); - } -} - -int POP3Resource::idToTime( int id ) const -{ - const QString uid = mIdsToUidsMap.value( id ); - if ( !uid.isEmpty() ) { - const int index = Settings::self()->seenUidList().indexOf( uid ); - if ( index != -1 ) - return Settings::self()->seenUidTimeList().at( index ); - } - - // If we don't find any mail, either we have no UID, or it is not in the seen UID - // list. In that case, we assume that the mail is new, i.e. from now - return time( 0 ); -} - -int POP3Resource::idOfOldestMessage( QList &idList ) const -{ - int timeOfOldestMessage = time( 0 ) + 999; - int idOfOldestMessage = -1; - foreach( int id, idList ) { - const int idTime = idToTime( id ); - if ( idTime < timeOfOldestMessage ) { - timeOfOldestMessage = idTime; - idOfOldestMessage = id; - } - } - Q_ASSERT( idList.isEmpty() || idOfOldestMessage != -1 ); - return idOfOldestMessage; +void POP3Resource::localFolderRequestJobFinished(KJob *job) +{ + if (job->error()) { + cancelSync(i18n("Error while trying to get the local inbox folder, " + "aborting mail check.") + QLatin1Char('\n') + job->errorString()); + return; + } + if (mTestLocalInbox) { + KMessageBox::information(Q_NULLPTR, + i18n("The folder you deleted was associated with the account " + "%1 which delivered mail into it. The folder the account " + "delivers new mail into was reset to the main Inbox folder.", name())); + } + mTestLocalInbox = false; + + mTargetCollection = SpecialMailCollections::self()->defaultCollection(SpecialMailCollections::Inbox); + Q_ASSERT(mTargetCollection.isValid()); + advanceState(Precommand); +} + +void POP3Resource::targetCollectionFetchJobFinished(KJob *job) +{ + if (job->error()) { + if (!mTestLocalInbox) { + mTestLocalInbox = true; + Settings::self()->setTargetCollection(-1); + advanceState(FetchTargetCollection); + return; + } else { + cancelSync(i18n("Error while trying to get the folder for incoming mail, " + "aborting mail check.") + QLatin1Char('\n') + job->errorString()); + mTestLocalInbox = false; + return; + } + } + mTestLocalInbox = false; + Akonadi::CollectionFetchJob *fetchJob = + dynamic_cast(job); + Q_ASSERT(fetchJob); + Q_ASSERT(fetchJob->collections().size() <= 1); + + if (fetchJob->collections().isEmpty()) { + cancelSync(i18n("Could not find folder for incoming mail, aborting mail check.")); + return; + } else { + mTargetCollection = fetchJob->collections().at(0); + advanceState(Precommand); + } } -QList POP3Resource::idsToDelete() const +void POP3Resource::precommandResult(KJob *job) { - QList idsToDeleteFromServer = mIdsToSizeMap.keys(); - QList idsToSave; + if (job->error()) { + cancelSync(i18n("Error while executing precommand.") + + QLatin1Char('\n') + job->errorString()); + return; + } else { + advanceState(RequestPassword); + } +} - // Don't attempt to delete messages that weren't downloaded correctly - foreach( int idNotDownloaded, mIdsToDownload ) - idsToDeleteFromServer.removeAll( idNotDownloaded ); - - // By default, we delete all messages. But if we have "leave on server" - // rules, we can save some messages. - if ( Settings::self()->leaveOnServer() && !idsToDeleteFromServer.isEmpty() ) { - - // If the time-limited leave rule is checked, add the newer messages to - // the list of messages to keep - if ( Settings::self()->leaveOnServerDays() > 0 ) { - const int secondsPerDay = 86400; - time_t timeLimit = time( 0 ) - ( secondsPerDay * Settings::self()->leaveOnServerDays() ); - foreach( int idToDelete, idsToDeleteFromServer ) { - const int msgTime = idToTime( idToDelete ); - if ( msgTime >= timeLimit ) { - idsToSave.append( idToDelete ); +void POP3Resource::loginJobResult(KJob *job) +{ + if (job->error()) { + qCDebug(POP3RESOURCE_LOG) << job->error() << job->errorText(); + if (job->error() == KIO::ERR_COULD_NOT_LOGIN) { + mAskAgain = true; } - else { - kDebug() << "Message" << idToDelete << "is too old and will be deleted."; + cancelSync(i18n("Unable to login to the server %1.", Settings::self()->host()) + + QLatin1Char('\n') + job->errorString()); + } else { + advanceState(List); + } +} + +void POP3Resource::listJobResult(KJob *job) +{ + if (job->error()) { + cancelSync(i18n("Error while getting the list of messages on the server.") + + QLatin1Char('\n') + job->errorString()); + } else { + ListJob *listJob = dynamic_cast(job); + Q_ASSERT(listJob); + mIdsToSizeMap = listJob->idList(); + qCDebug(POP3RESOURCE_LOG) << "IdsToSizeMap:" << mIdsToSizeMap; + advanceState(UIDList); + } +} + +void POP3Resource::uidListJobResult(KJob *job) +{ + if (job->error()) { + cancelSync(i18n("Error while getting list of unique mail identifiers from the server.") + + QLatin1Char('\n') + job->errorString()); + } else { + UIDListJob *listJob = dynamic_cast(job); + Q_ASSERT(listJob); + mIdsToUidsMap = listJob->uidList(); + mUidsToIdsMap = listJob->idList(); + qCDebug(POP3RESOURCE_LOG) << "IdToUidMap:" << mIdsToUidsMap; + qCDebug(POP3RESOURCE_LOG) << "UidToIdMap:" << mUidsToIdsMap; + + mUidListValid = !mIdsToUidsMap.isEmpty() || mIdsToSizeMap.isEmpty(); + if (Settings::self()->leaveOnServer() && !mUidListValid) { + // FIXME: this needs a proper parent window + KMessageBox::sorry(Q_NULLPTR, + i18n("Your POP3 server (Account: %1) does not support " + "the UIDL command: this command is required to determine, in a reliable way, " + "which of the mails on the server KMail has already seen before;\n" + "the feature to leave the mails on the server will therefore not " + "work properly.", name())); } - } + + advanceState(Download); } +} - // Otherwise, add all messages to the list of messages to keep - this may - // be reduced in the following number-limited leave rule and size-limited - // leave rule checks - else { - foreach ( int idToDelete, idsToDeleteFromServer ) { - idsToSave.append( idToDelete ); - } +void POP3Resource::fetchJobResult(KJob *job) +{ + if (job->error()) { + cancelSync(i18n("Error while fetching mails from the server.") + + QLatin1Char('\n') + job->errorString()); + return; + } else { + qCDebug(POP3RESOURCE_LOG) << "Downloaded" << mDownloadedIDs.size() << "mails"; + + if (!mIdsToDownload.isEmpty()) { + qCWarning(POP3RESOURCE_LOG) << "We did not download all messages, there are still some remaining " + "IDs, even though we requested their download:" << mIdsToDownload; + } + + advanceState(Save); } +} - // - // Delete more old messages if there are more than mLeaveOnServerCount - // - if ( Settings::self()->leaveOnServerCount() > 0 ) { - const int numToDelete = idsToSave.count() - Settings::self()->leaveOnServerCount(); - if ( numToDelete > 0 && numToDelete < idsToSave.count() ) { - // Get rid of the first numToDelete messages - for ( int i = 0; i < numToDelete; i++ ) { - idsToSave.removeAll( idOfOldestMessage( idsToSave ) ); - } - } - else if ( numToDelete >= idsToSave.count() ) - idsToSave.clear(); +void POP3Resource::messageFinished(int messageId, KMime::Message::Ptr message) +{ + if (mState != Download) { + // This can happen if the slave does not get notified in time about the fact + // that the job was killed + return; } - // - // Delete more old messages until we're under mLeaveOnServerSize MBs - // - if ( Settings::self()->leaveOnServerSize() > 0 ) { - const qint64 limitInBytes = Settings::self()->leaveOnServerSize() * ( 1024 * 1024 ); - qint64 sizeOnServerAfterDeletion = 0; - foreach( int id, idsToSave ) { - sizeOnServerAfterDeletion += mIdsToSizeMap.value( id ); - } - while ( sizeOnServerAfterDeletion > limitInBytes ) { - int oldestId = idOfOldestMessage( idsToSave ); - idsToSave.removeAll( oldestId ); - sizeOnServerAfterDeletion -= mIdsToSizeMap.value( oldestId ); - } + //qCDebug(POP3RESOURCE_LOG) << "Got message" << messageId + // << "with subject" << message->subject()->asUnicodeString(); + + Akonadi::Item item; + item.setMimeType(QLatin1String("message/rfc822")); + item.setPayload(message); + + Akonadi::Pop3ResourceAttribute *attr = item.attribute(Akonadi::Entity::AddIfMissing); + attr->setPop3AccountName(identifier()); + Akonadi::MessageFlags::copyMessageFlags(*message, item); + ItemCreateJob *itemCreateJob = new ItemCreateJob(item, mTargetCollection); + + mPendingCreateJobs.insert(itemCreateJob, messageId); + connect(itemCreateJob, &ItemCreateJob::result, this, &POP3Resource::itemCreateJobResult); + + mDownloadedIDs.append(messageId); + mIdsToDownload.removeAll(messageId); +} + +void POP3Resource::messageDownloadProgress(KJob *job, KJob::Unit unit, qulonglong totalBytes) +{ + Q_UNUSED(totalBytes); + Q_UNUSED(unit); + Q_ASSERT(unit == KJob::Bytes); + QString statusMessage; + const int totalMessages = mIdsToDownload.size() + mDownloadedIDs.size(); + int bytesRemainingOnServer = 0; + foreach (const QString &alreadyDownloadedUID, Settings::self()->seenUidList()) { + const int alreadyDownloadedID = mUidsToIdsMap.value(alreadyDownloadedUID, -1); + if (alreadyDownloadedID != -1) { + bytesRemainingOnServer += mIdsToSizeMap.value(alreadyDownloadedID); + } } - // - // Now save the messages from deletion - // - foreach( int idToSave, idsToSave ) { - idsToDeleteFromServer.removeAll( idToSave ); + if (Settings::self()->leaveOnServer() && bytesRemainingOnServer > 0) { + + statusMessage = i18n("Fetching message %1 of %2 (%3 of %4 KB) for %5 " + "(%6 KB remain on the server).", + mDownloadedIDs.size() + 1, totalMessages, + job->processedAmount(KJob::Bytes) / 1024, + job->totalAmount(KJob::Bytes) / 1024, name(), + bytesRemainingOnServer / 1024); + } else { + statusMessage = i18n("Fetching message %1 of %2 (%3 of %4 KB) for %5", + mDownloadedIDs.size() + 1, totalMessages, + job->processedAmount(KJob::Bytes) / 1024, + job->totalAmount(KJob::Bytes) / 1024, name()); + } + Q_EMIT status(Running, statusMessage); + Q_EMIT percent(job->percent()); +} + +void POP3Resource::itemCreateJobResult(KJob *job) +{ + if (mState != Download && mState != Save) { + // This can happen if the slave does not get notified in time about the fact + // that the job was killed + return; + } + + ItemCreateJob *createJob = dynamic_cast(job); + Q_ASSERT(createJob); + + if (job->error()) { + cancelSync(i18n("Unable to store downloaded mails.") + + QLatin1Char('\n') + job->errorString()); + return; + } + + const int idOfMessageJustCreated = mPendingCreateJobs.value(createJob, -1); + Q_ASSERT(idOfMessageJustCreated != -1); + mPendingCreateJobs.remove(createJob); + mIDsStored.append(idOfMessageJustCreated); + //qCDebug(POP3RESOURCE_LOG) << "Just stored message with ID" << idOfMessageJustCreated + // << "on the Akonadi server"; + + // Have all create jobs finished? Go to the next state, then + if (mState == Save && mPendingCreateJobs.isEmpty()) { + advanceState(Delete); + } +} + +int POP3Resource::idToTime(int id) const +{ + const QString uid = mIdsToUidsMap.value(id); + if (!uid.isEmpty()) { + const int index = Settings::self()->seenUidList().indexOf(uid); + if (index != -1) { + return Settings::self()->seenUidTimeList().at(index); + } + } + + // If we don't find any mail, either we have no UID, or it is not in the seen UID + // list. In that case, we assume that the mail is new, i.e. from now + return time(Q_NULLPTR); +} + +int POP3Resource::idOfOldestMessage(QList &idList) const +{ + int timeOfOldestMessage = time(Q_NULLPTR) + 999; + int idOfOldestMessage = -1; + foreach (int id, idList) { + const int idTime = idToTime(id); + if (idTime < timeOfOldestMessage) { + timeOfOldestMessage = idTime; + idOfOldestMessage = id; + } + } + Q_ASSERT(idList.isEmpty() || idOfOldestMessage != -1); + return idOfOldestMessage; +} + +QList POP3Resource::idsToDelete() const +{ + QList idsToDeleteFromServer = mIdsToSizeMap.keys(); + QList idsToSave; + + // Don't attempt to delete messages that weren't downloaded correctly + foreach (int idNotDownloaded, mIdsToDownload) { + idsToDeleteFromServer.removeAll(idNotDownloaded); + } + + // By default, we delete all messages. But if we have "leave on server" + // rules, we can save some messages. + if (Settings::self()->leaveOnServer() && !idsToDeleteFromServer.isEmpty()) { + + // If the time-limited leave rule is checked, add the newer messages to + // the list of messages to keep + if (Settings::self()->leaveOnServerDays() > 0) { + const int secondsPerDay = 86400; + time_t timeLimit = time(Q_NULLPTR) - (secondsPerDay * Settings::self()->leaveOnServerDays()); + foreach (int idToDelete, idsToDeleteFromServer) { + const int msgTime = idToTime(idToDelete); + if (msgTime >= timeLimit) { + idsToSave.append(idToDelete); + } else { + qCDebug(POP3RESOURCE_LOG) << "Message" << idToDelete << "is too old and will be deleted."; + } + } + } + + // Otherwise, add all messages to the list of messages to keep - this may + // be reduced in the following number-limited leave rule and size-limited + // leave rule checks + else { + idsToSave.reserve(idsToDeleteFromServer.count()); + foreach (int idToDelete, idsToDeleteFromServer) { + idsToSave.append(idToDelete); + } + } + + // + // Delete more old messages if there are more than mLeaveOnServerCount + // + if (Settings::self()->leaveOnServerCount() > 0) { + const int numToDelete = idsToSave.count() - Settings::self()->leaveOnServerCount(); + if (numToDelete > 0 && numToDelete < idsToSave.count()) { + // Get rid of the first numToDelete messages + for (int i = 0; i < numToDelete; i++) { + idsToSave.removeAll(idOfOldestMessage(idsToSave)); + } + } else if (numToDelete >= idsToSave.count()) { + idsToSave.clear(); + } + } + + // + // Delete more old messages until we're under mLeaveOnServerSize MBs + // + if (Settings::self()->leaveOnServerSize() > 0) { + const qint64 limitInBytes = Settings::self()->leaveOnServerSize() * (1024 * 1024); + qint64 sizeOnServerAfterDeletion = 0; + foreach (int id, idsToSave) { + sizeOnServerAfterDeletion += mIdsToSizeMap.value(id); + } + while (sizeOnServerAfterDeletion > limitInBytes) { + int oldestId = idOfOldestMessage(idsToSave); + idsToSave.removeAll(oldestId); + sizeOnServerAfterDeletion -= mIdsToSizeMap.value(oldestId); + } + } + + // + // Now save the messages from deletion + // + foreach (int idToSave, idsToSave) { + idsToDeleteFromServer.removeAll(idToSave); + } } - } - kDebug() << "Going to delete" << idsToDeleteFromServer.size() << idsToDeleteFromServer; - return idsToDeleteFromServer; + qCDebug(POP3RESOURCE_LOG) << "Going to delete" << idsToDeleteFromServer.size() << idsToDeleteFromServer; + return idsToDeleteFromServer; } -void POP3Resource::deleteJobResult( KJob *job ) -{ - if ( job->error() ) { - cancelSync( i18n( "Failed to delete the messages from the server.") + - QLatin1Char('\n') + job->errorString() ); - return; - } - - DeleteJob *deleteJob = dynamic_cast( job ); - Q_ASSERT( deleteJob ); - mDeletedIDs = deleteJob->deletedIDs(); - - // Remove all deleted messages from the list of already downloaded messages, - // as it is no longer necessary to store them (they just waste space) - QList seenUIDs = Settings::self()->seenUidList(); - QList timeOfSeenUids = Settings::self()->seenUidTimeList(); - Q_ASSERT( seenUIDs.size() == timeOfSeenUids.size() ); - foreach( int deletedId, mDeletedIDs ) { - QString deletedUID = mIdsToUidsMap.value( deletedId ); - if ( !deletedUID.isEmpty() ) { - int index = seenUIDs.indexOf( deletedUID ); - if ( index != -1 ) { - // TEST - kDebug() << "Removing UID" << deletedUID << "from the seen UID list, as it was deleted."; - seenUIDs.removeAt( index ); - timeOfSeenUids.removeAt( index ); - } - } - } - Settings::self()->setSeenUidList( seenUIDs ); - Settings::self()->setSeenUidTimeList( timeOfSeenUids ); - Settings::self()->writeConfig(), +void POP3Resource::deleteJobResult(KJob *job) +{ + if (job->error()) { + cancelSync(i18n("Failed to delete the messages from the server.") + + QLatin1Char('\n') + job->errorString()); + return; + } + + DeleteJob *deleteJob = dynamic_cast(job); + Q_ASSERT(deleteJob); + mDeletedIDs = deleteJob->deletedIDs(); + + // Remove all deleted messages from the list of already downloaded messages, + // as it is no longer necessary to store them (they just waste space) + QList seenUIDs = Settings::self()->seenUidList(); + QList timeOfSeenUids = Settings::self()->seenUidTimeList(); + Q_ASSERT(seenUIDs.size() == timeOfSeenUids.size()); + foreach (int deletedId, mDeletedIDs) { + QString deletedUID = mIdsToUidsMap.value(deletedId); + if (!deletedUID.isEmpty()) { + int index = seenUIDs.indexOf(deletedUID); + if (index != -1) { + // TEST + qCDebug(POP3RESOURCE_LOG) << "Removing UID" << deletedUID << "from the seen UID list, as it was deleted."; + seenUIDs.removeAt(index); + timeOfSeenUids.removeAt(index); + } + } + } + Settings::self()->setSeenUidList(seenUIDs); + Settings::self()->setSeenUidTimeList(timeOfSeenUids); + Settings::self()->save(), - advanceState( Quit ); + advanceState(Quit); } void POP3Resource::finish() { - kDebug() << "================= Mail check finished. ============================="; - saveSeenUIDList(); - if ( !mIntervalCheckInProgress ) - collectionsRetrieved( Akonadi::Collection::List() ); - if ( mDownloadedIDs.isEmpty() ) - emit status( Idle, i18n( "Finished mail check, no message downloaded." ) ); - else - emit status( Idle, i18np( "Finished mail check, 1 message downloaded.", - "Finished mail check, %1 messages downloaded.", - mDownloadedIDs.size() ) ); + qCDebug(POP3RESOURCE_LOG) << "================= Mail check finished. ============================="; + saveSeenUIDList(); + if (!mIntervalCheckInProgress) { + collectionsRetrieved(Akonadi::Collection::List()); + } + if (mDownloadedIDs.isEmpty()) { + Q_EMIT status(Idle, i18n("Finished mail check, no message downloaded.")); + } else + Q_EMIT status(Idle, i18np("Finished mail check, 1 message downloaded.", + "Finished mail check, %1 messages downloaded.", + mDownloadedIDs.size())); - resetState(); + resetState(); } -void POP3Resource::quitJobResult( KJob *job ) +void POP3Resource::quitJobResult(KJob *job) { - if ( job->error() ) { - cancelSync( i18n( "Unable to complete the mail fetch." ) + - QLatin1Char('\n') + job->errorString() ); - return; - } + if (job->error()) { + cancelSync(i18n("Unable to complete the mail fetch.") + + QLatin1Char('\n') + job->errorString()); + return; + } - advanceState( SavePassword ); + advanceState(SavePassword); } -void POP3Resource::slotSessionError( int errorCode, const QString &errorMessage ) +void POP3Resource::slotSessionError(int errorCode, const QString &errorMessage) { - kWarning() << "Error in our session, unrelated to a currently running job!"; - cancelSync( KIO::buildErrorString( errorCode, errorMessage ) ); + qCWarning(POP3RESOURCE_LOG) << "Error in our session, unrelated to a currently running job!"; + cancelSync(KIO::buildErrorString(errorCode, errorMessage)); } void POP3Resource::saveSeenUIDList() { - QList seenUIDs = Settings::self()->seenUidList(); - QList timeOfSeenUIDs = Settings::self()->seenUidTimeList(); + QList seenUIDs = Settings::self()->seenUidList(); + QList timeOfSeenUIDs = Settings::self()->seenUidTimeList(); - // - // Find the messages that we have successfully stored, but did not actually get - // deleted. - // Those messages, we have to remember, so we don't download them again. - // - QList idsOfMessagesDownloadedButNotDeleted = mIDsStored; - foreach( int deletedId, mDeletedIDs ) - idsOfMessagesDownloadedButNotDeleted.removeAll( deletedId ); - QList uidsOfMessagesDownloadedButNotDeleted; - foreach( int id, idsOfMessagesDownloadedButNotDeleted ) { - QString uid = mIdsToUidsMap.value( id ); - if ( !uid.isEmpty() ) { - uidsOfMessagesDownloadedButNotDeleted.append( uid ); - } - } - Q_ASSERT( seenUIDs.size() == timeOfSeenUIDs.size() ); - foreach( const QString &uid, uidsOfMessagesDownloadedButNotDeleted ) { - if ( !seenUIDs.contains( uid ) ) { - seenUIDs.append( uid ); - timeOfSeenUIDs.append( time( 0 ) ); - } - } - - // - // If we have a valid UID list from the server, delete those UIDs that are in - // the seenUidList but are not on the server. - // This can happen if someone else than this resource deleted the mails from the - // server which we kept here. - // - if ( mUidListValid ) { - QList::iterator uidIt = seenUIDs.begin(); - QList::iterator timeIt = timeOfSeenUIDs.begin(); - while ( uidIt != seenUIDs.end() ) { - const QString curSeenUID = *uidIt; - if ( !mUidsToIdsMap.contains( curSeenUID ) ) { - // Ok, we have a UID in the seen UID list that is not anymore on the server. - // Therefore remove it from the seen UID list, it is not needed there anymore, - // it just wastes space. - uidIt = seenUIDs.erase( uidIt ); - timeIt = timeOfSeenUIDs.erase( timeIt ); - } - else { - ++uidIt; - ++timeIt; - } - } - } - else - kWarning() << "UID list from server is not valid."; - - - // - // Now save it in the settings - // - kDebug() << "The seen UID list has" << seenUIDs.size() << "entries"; - Settings::self()->setSeenUidList( seenUIDs ); - Settings::self()->setSeenUidTimeList( timeOfSeenUIDs ); - Settings::self()->writeConfig(); -} - -void POP3Resource::cancelSync( const QString &errorMessage, bool error ) -{ - if ( error ) { - cancelTask( errorMessage ); - kWarning() << "============== ERROR DURING POP3 SYNC =========================="; - kWarning() << errorMessage; - } - else { - kDebug() << "Canceled the sync, but no error."; - cancelTask(); - } - saveSeenUIDList(); - resetState(); + // + // Find the messages that we have successfully stored, but did not actually get + // deleted. + // Those messages, we have to remember, so we don't download them again. + // + QList idsOfMessagesDownloadedButNotDeleted = mIDsStored; + foreach (int deletedId, mDeletedIDs) { + idsOfMessagesDownloadedButNotDeleted.removeAll(deletedId); + } + QList uidsOfMessagesDownloadedButNotDeleted; + foreach (int id, idsOfMessagesDownloadedButNotDeleted) { + QString uid = mIdsToUidsMap.value(id); + if (!uid.isEmpty()) { + uidsOfMessagesDownloadedButNotDeleted.append(uid); + } + } + Q_ASSERT(seenUIDs.size() == timeOfSeenUIDs.size()); + foreach (const QString &uid, uidsOfMessagesDownloadedButNotDeleted) { + if (!seenUIDs.contains(uid)) { + seenUIDs.append(uid); + timeOfSeenUIDs.append(time(Q_NULLPTR)); + } + } + + // + // If we have a valid UID list from the server, delete those UIDs that are in + // the seenUidList but are not on the server. + // This can happen if someone else than this resource deleted the mails from the + // server which we kept here. + // + if (mUidListValid) { + QList::iterator uidIt = seenUIDs.begin(); + QList::iterator timeIt = timeOfSeenUIDs.begin(); + while (uidIt != seenUIDs.end()) { + const QString curSeenUID = *uidIt; + if (!mUidsToIdsMap.contains(curSeenUID)) { + // Ok, we have a UID in the seen UID list that is not anymore on the server. + // Therefore remove it from the seen UID list, it is not needed there anymore, + // it just wastes space. + uidIt = seenUIDs.erase(uidIt); + timeIt = timeOfSeenUIDs.erase(timeIt); + } else { + ++uidIt; + ++timeIt; + } + } + } else { + qCWarning(POP3RESOURCE_LOG) << "UID list from server is not valid."; + } + + // + // Now save it in the settings + // + qCDebug(POP3RESOURCE_LOG) << "The seen UID list has" << seenUIDs.size() << "entries"; + Settings::self()->setSeenUidList(seenUIDs); + Settings::self()->setSeenUidTimeList(timeOfSeenUIDs); + Settings::self()->save(); +} + +void POP3Resource::cancelSync(const QString &errorMessage, bool error) +{ + if (error) { + cancelTask(errorMessage); + qCWarning(POP3RESOURCE_LOG) << "============== ERROR DURING POP3 SYNC =========================="; + qCWarning(POP3RESOURCE_LOG) << errorMessage; + } else { + qCDebug(POP3RESOURCE_LOG) << "Canceled the sync, but no error."; + cancelTask(); + } + saveSeenUIDList(); + resetState(); } void POP3Resource::resetState() { - mState = Idle; - mTargetCollection = Collection( -1 ); - mIdsToSizeMap.clear(); - mIdsToUidsMap.clear(); - mUidsToIdsMap.clear(); - mDownloadedIDs.clear(); - mIdsToDownload.clear(); - mPendingCreateJobs.clear(); - mIDsStored.clear(); - mDeletedIDs.clear(); - mUidListValid = false; - mIntervalCheckInProgress = false; - mSavePassword = false; - updateIntervalTimer(); - delete mWallet; - mWallet = 0; - - if ( mPopSession ) { - // Closing the POP session means the KIO slave will get disconnected, which - // automatically issues the QUIT command. - // Delete the POP session later, otherwise the scheduler makes us crash - mPopSession->abortCurrentJob(); - mPopSession->deleteLater(); - mPopSession = 0; - } + mState = Idle; + mTargetCollection = Collection(-1); + mIdsToSizeMap.clear(); + mIdsToUidsMap.clear(); + mUidsToIdsMap.clear(); + mDownloadedIDs.clear(); + mIdsToDownload.clear(); + mPendingCreateJobs.clear(); + mIDsStored.clear(); + mDeletedIDs.clear(); + mUidListValid = false; + mIntervalCheckInProgress = false; + mSavePassword = false; + updateIntervalTimer(); + delete mWallet; + mWallet = Q_NULLPTR; + + if (mPopSession) { + // Closing the POP session means the KIO slave will get disconnected, which + // automatically issues the QUIT command. + // Delete the POP session later, otherwise the scheduler makes us crash + mPopSession->abortCurrentJob(); + mPopSession->deleteLater(); + mPopSession = Q_NULLPTR; + } } void POP3Resource::startMailCheck() { - resetState(); - mIntervalTimer->stop(); - emit percent( 0 ); // Otherwise the value from the last sync is taken - advanceState( FetchTargetCollection ); + resetState(); + mIntervalTimer->stop(); + Q_EMIT percent(0); // Otherwise the value from the last sync is taken + advanceState(FetchTargetCollection); } void POP3Resource::retrieveCollections() { - if ( mState == Idle ) { - startMailCheck(); - } - else { - cancelSync( - i18n( "Mail check already in progress, unable to start a second check." ) ); - } + if (mState == Idle) { + startMailCheck(); + } else { + cancelSync( + i18n("Mail check already in progress, unable to start a second check.")); + } } void POP3Resource::clearCachedPassword() @@ -1006,27 +969,29 @@ void POP3Resource::cleanup() { - if (mWallet && mWallet->isOpen() && mWallet->hasFolder( QLatin1String("pop3") ) ) { - mWallet->setFolder( QLatin1String("pop3") ); - if ( mWallet->hasEntry( identifier() ) ) - mWallet->removeEntry(identifier()); + if (mWallet && mWallet->isOpen() && mWallet->hasFolder(QStringLiteral("pop3"))) { + mWallet->setFolder(QStringLiteral("pop3")); + if (mWallet->hasEntry(identifier())) { + mWallet->removeEntry(identifier()); + } } + Akonadi::AgentBase::cleanup(); } -void POP3Resource::doSetOnline( bool online ) +void POP3Resource::doSetOnline(bool online) { - ResourceBase::doSetOnline( online ); - if ( online ) { - emit status( Idle, i18n("Ready") ); - } else { - if ( mState != Idle ) { - cancelSync( i18n( "Mail check aborted after going offline." ), false /* no error */ ); + ResourceBase::doSetOnline(online); + if (online) { + Q_EMIT status(Idle, i18n("Ready")); + } else { + if (mState != Idle) { + cancelSync(i18n("Mail check aborted after going offline."), false /* no error */); + } + Q_EMIT status(Idle, i18n("Offline")); + delete mWallet; + mWallet = Q_NULLPTR; + clearCachedPassword(); } - emit status( Idle, i18n("Offline") ); - delete mWallet; - mWallet = 0; - clearCachedPassword(); - } } -AKONADI_RESOURCE_MAIN( POP3Resource ) +AKONADI_RESOURCE_MAIN(POP3Resource) diff -Nru kdepim-runtime-4.14.6/resources/pop3/pop3resource_debug.cpp kdepim-runtime-15.08.0/resources/pop3/pop3resource_debug.cpp --- kdepim-runtime-4.14.6/resources/pop3/pop3resource_debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/pop3resource_debug.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,22 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 "pop3resource_debug.h" +Q_LOGGING_CATEGORY(POP3RESOURCE_LOG, "log_pop3resource") + diff -Nru kdepim-runtime-4.14.6/resources/pop3/pop3resource_debug.h kdepim-runtime-15.08.0/resources/pop3/pop3resource_debug.h --- kdepim-runtime-4.14.6/resources/pop3/pop3resource_debug.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/pop3resource_debug.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,27 @@ +/* This file is part of the KDE project + Copyright (C) 2014 Laurent Montel + + 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 POP3RESOURCE_DEBUG_H +#define POP3RESOURCE_DEBUG_H + +#include +Q_DECLARE_LOGGING_CATEGORY(POP3RESOURCE_LOG) + +#endif + diff -Nru kdepim-runtime-4.14.6/resources/pop3/pop3resource.desktop kdepim-runtime-15.08.0/resources/pop3/pop3resource.desktop --- kdepim-runtime-4.14.6/resources/pop3/pop3resource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/pop3resource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -82,7 +82,7 @@ Comment[ro]=Se conectează la un server de poștă POP3 Comment[ru]=Подключение к почтовому серверу POP3 Comment[sk]=Pripojí sa na POP3 poštový server -Comment[sl]=Povezava z e-poštnim strežnikom POP3 +Comment[sl]=Poveže se z e-poštnim strežnikom POP3 Comment[sr]=Повезује се на ПОП3 сервер е‑поште Comment[sr@ijekavian]=Повезује се на ПОП3 сервер е‑поште Comment[sr@ijekavianlatin]=Povezuje se na POP3 server e‑pošte diff -Nru kdepim-runtime-4.14.6/resources/pop3/pop3resource.h kdepim-runtime-15.08.0/resources/pop3/pop3resource.h --- kdepim-runtime-4.14.6/resources/pop3/pop3resource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/pop3resource.h 2015-08-10 21:01:02.000000000 +0000 @@ -19,14 +19,16 @@ #ifndef POP3RESOURCE_H #define POP3RESOURCE_H -#include +#include #include #include -namespace Akonadi { +namespace Akonadi +{ class ItemCreateJob; } -namespace KWallet { +namespace KWallet +{ class Wallet; } @@ -34,106 +36,106 @@ class QTimer; class POP3Resource : public Akonadi::ResourceBase, - public Akonadi::AgentBase::Observer + public Akonadi::AgentBase::Observer { - Q_OBJECT + Q_OBJECT - public: - POP3Resource( const QString &id ); +public: + POP3Resource(const QString &id); ~POP3Resource(); void clearCachedPassword(); - void cleanup(); + void cleanup() Q_DECL_OVERRIDE; - public Q_SLOTS: - virtual void configure( WId windowId ); +public Q_SLOTS: + void configure(WId windowId) Q_DECL_OVERRIDE; - protected Q_SLOTS: - void retrieveCollections(); - void retrieveItems( const Akonadi::Collection &col ); - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); +protected Q_SLOTS: + void retrieveCollections() Q_DECL_OVERRIDE; + void retrieveItems(const Akonadi::Collection &col) Q_DECL_OVERRIDE; + bool retrieveItem(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; - protected: +protected: - virtual void aboutToQuit(); - virtual void doSetOnline( bool online ); + void aboutToQuit() Q_DECL_OVERRIDE; + void doSetOnline(bool online) Q_DECL_OVERRIDE; - private Q_SLOTS: +private Q_SLOTS: void slotAbortRequested(); void intervalCheckTriggered(); void configurationChanged(); // Error unrelated to a state - void slotSessionError( int errorCode, const QString &errorMessage ); + void slotSessionError(int errorCode, const QString &errorMessage); // For state FetchTargetCollection - void targetCollectionFetchJobFinished( KJob *job ); - void localFolderRequestJobFinished( KJob *job ); + void targetCollectionFetchJobFinished(KJob *job); + void localFolderRequestJobFinished(KJob *job); // For state Precommand - void precommandResult( KJob *job ); + void precommandResult(KJob *job); // For state RequestPassword - void walletOpenedForLoading( bool success ); + void walletOpenedForLoading(bool success); // For state Login - void loginJobResult( KJob *job ); + void loginJobResult(KJob *job); // For state List - void listJobResult( KJob *job ); + void listJobResult(KJob *job); // For state UIDList - void uidListJobResult( KJob *job ); + void uidListJobResult(KJob *job); // For state Download - void messageFinished( int messageId, KMime::Message::Ptr message ); - void fetchJobResult( KJob *job ); - void messageDownloadProgress( KJob *job, KJob::Unit unit, qulonglong totalBytes ); + void messageFinished(int messageId, KMime::Message::Ptr message); + void fetchJobResult(KJob *job); + void messageDownloadProgress(KJob *job, KJob::Unit unit, qulonglong totalBytes); // For state Save - void itemCreateJobResult( KJob *job ); + void itemCreateJobResult(KJob *job); // For state Delete - void deleteJobResult( KJob *job ); + void deleteJobResult(KJob *job); // For state Quit - void quitJobResult( KJob *job ); + void quitJobResult(KJob *job); // For state SavePassword - void walletOpenedForSaving( bool success ); + void walletOpenedForSaving(bool success); - private: +private: enum State { - Idle, - FetchTargetCollection, - Precommand, - RequestPassword, - Connect, - Login, - List, - UIDList, - Download, - Save, - Delete, - Quit, - SavePassword + Idle, + FetchTargetCollection, + Precommand, + RequestPassword, + Connect, + Login, + List, + UIDList, + Download, + Save, + Delete, + Quit, + SavePassword }; void resetState(); void doStateStep(); - void advanceState( State nextState ); - void cancelSync( const QString &errorMessage, bool error = true ); + void advanceState(State nextState); + void cancelSync(const QString &errorMessage, bool error = true); void saveSeenUIDList(); QList idsToDelete() const; - int idToTime( int id ) const; - int idOfOldestMessage( QList &idList ) const; + int idToTime(int id) const; + int idOfOldestMessage(QList &idList) const; void startMailCheck(); void updateIntervalTimer(); - void showPasswordDialog( const QString &queryText ); - QString buildLabelForPasswordDialog( const QString &detailedError ) const; + void showPasswordDialog(const QString &queryText); + QString buildLabelForPasswordDialog(const QString &detailedError) const; void finish(); State mState; @@ -148,15 +150,15 @@ KWallet::Wallet *mWallet; // Maps IDs on the server to message sizes on the server - QMap mIdsToSizeMap; + QMap mIdsToSizeMap; // Maps IDs on the server to UIDs on the server. // This can be empty, if the server doesn't support UIDL - QMap mIdsToUidsMap; + QMap mIdsToUidsMap; // Maps UIDs on the server to IDs on the server. // This can be empty, if the server doesn't support UIDL - QMap mUidsToIdsMap; + QMap mUidsToIdsMap; // Whether we actually received a valid UID list from the server bool mUidListValid; @@ -175,7 +177,7 @@ // POP3 IDs. // When an ItemCreateJob finished, it is removed from this map. // The Save state waits until this map becomes empty. - QMap mPendingCreateJobs; + QMap mPendingCreateJobs; // List of message IDs that were successfully stored in Akonadi QList mIDsStored; diff -Nru kdepim-runtime-4.14.6/resources/pop3/popsettings.ui kdepim-runtime-15.08.0/resources/pop3/popsettings.ui --- kdepim-runtime-4.14.6/resources/pop3/popsettings.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/popsettings.ui 2015-08-10 21:01:02.000000000 +0000 @@ -28,7 +28,7 @@ - + 0 @@ -85,7 +85,7 @@ - + 5 @@ -95,9 +95,6 @@ 10000000 - - - @@ -258,7 +255,7 @@ - + false @@ -271,9 +268,6 @@ 365 - - days - @@ -290,7 +284,7 @@ - + false @@ -303,9 +297,6 @@ 999999 - - messages - @@ -322,7 +313,7 @@ - + false @@ -351,7 +342,7 @@ - + false @@ -367,12 +358,6 @@ 10000000 - - 100 - - - bytes - @@ -428,12 +413,6 @@ - - QFrame::StyledPanel - - - QFrame::Raised - @@ -464,7 +443,7 @@ - + Auto Detect @@ -593,25 +572,14 @@ 1 - KPushButton - QPushButton -
kpushbutton.h
-
- - KIntNumInput - QWidget -
knuminput.h
-
- - KTabWidget - QTabWidget -
ktabwidget.h
- 1 + KPluralHandlingSpinBox + QSpinBox +
KPluralHandlingSpinBox
Akonadi::CollectionRequester QFrame -
Akonadi/CollectionRequester
+
CollectionRequester
1
diff -Nru kdepim-runtime-4.14.6/resources/pop3/settings.cpp kdepim-runtime-15.08.0/resources/pop3/settings.cpp --- kdepim-runtime-4.14.6/resources/pop3/settings.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/settings.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -19,64 +19,66 @@ #include "settings.h" #include "settingsadaptor.h" -#include #include +#include "pop3resource_debug.h" class SettingsHelper { - public: - SettingsHelper() : q( 0 ) {} - ~SettingsHelper() { - kWarning() << q; - delete q; - q = 0; +public: + SettingsHelper() : q(Q_NULLPTR) {} + ~SettingsHelper() + { + qCWarning(POP3RESOURCE_LOG) << q; + delete q; + q = Q_NULLPTR; } Settings *q; }; -K_GLOBAL_STATIC( SettingsHelper, s_globalSettings ) +Q_GLOBAL_STATIC(SettingsHelper, s_globalSettings) Settings *Settings::self() { - if ( !s_globalSettings->q ) { - new Settings; - s_globalSettings->q->readConfig(); - } - return s_globalSettings->q; + if (!s_globalSettings->q) { + new Settings; + s_globalSettings->q->load(); + } + return s_globalSettings->q; } Settings::Settings() { - Q_ASSERT( !s_globalSettings->q ); - s_globalSettings->q = this; + Q_ASSERT(!s_globalSettings->q); + s_globalSettings->q = this; - new SettingsAdaptor( this ); - QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ), this, - QDBusConnection::ExportAdaptors | QDBusConnection::ExportScriptableContents ); + new SettingsAdaptor(this); + QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"), this, + QDBusConnection::ExportAdaptors | QDBusConnection::ExportScriptableContents); } -void Settings::setWindowId( WId id ) +void Settings::setWindowId(WId id) { - mWinId = id; + mWinId = id; } -void Settings::setResourceId( const QString &resourceIdentifier ) +void Settings::setResourceId(const QString &resourceIdentifier) { - mResourceId = resourceIdentifier; + mResourceId = resourceIdentifier; } -void Settings::setPassword( const QString& password ) +void Settings::setPassword(const QString &password) { - using namespace KWallet; - Wallet *wallet = Wallet::openWallet( Wallet::NetworkWallet(), mWinId, - Wallet::Synchronous ); - if ( wallet && wallet->isOpen() ) { - if ( !wallet->hasFolder( QLatin1String("pop3") ) ) - wallet->createFolder( QLatin1String("pop3") ); - wallet->setFolder( QLatin1String("pop3") ); - wallet->writePassword( mResourceId, password ); - } else { - kWarning() << "Unable to open wallet!"; - } - delete wallet; + using namespace KWallet; + Wallet *wallet = Wallet::openWallet(Wallet::NetworkWallet(), mWinId, + Wallet::Synchronous); + if (wallet && wallet->isOpen()) { + if (!wallet->hasFolder(QStringLiteral("pop3"))) { + wallet->createFolder(QStringLiteral("pop3")); + } + wallet->setFolder(QStringLiteral("pop3")); + wallet->writePassword(mResourceId, password); + } else { + qCWarning(POP3RESOURCE_LOG) << "Unable to open wallet!"; + } + delete wallet; } diff -Nru kdepim-runtime-4.14.6/resources/pop3/settings.h kdepim-runtime-15.08.0/resources/pop3/settings.h --- kdepim-runtime-4.14.6/resources/pop3/settings.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/settings.h 2015-08-10 21:01:02.000000000 +0000 @@ -29,17 +29,17 @@ */ class Settings : public SettingsBase { - Q_OBJECT - Q_CLASSINFO( "D-Bus Interface", "org.kde.Akonadi.POP3.Wallet" ) - public: + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.Akonadi.POP3.Wallet") +public: Settings(); - void setWindowId( WId id ); - void setResourceId( const QString &resourceIdentifier ); + void setWindowId(WId id); + void setResourceId(const QString &resourceIdentifier); static Settings *self(); - public slots: - Q_SCRIPTABLE void setPassword( const QString &password ); - private: +public Q_SLOTS: + Q_SCRIPTABLE void setPassword(const QString &password); +private: WId mWinId; QString mResourceId; }; diff -Nru kdepim-runtime-4.14.6/resources/pop3/tests/CMakeLists.txt kdepim-runtime-15.08.0/resources/pop3/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/pop3/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ${Boost_INCLUDE_DIR} - ${AKONADI_INCLUDE_DIR} - ${KDEPIMLIBS_INCLUDE_DIRS} -) - -# Stolen from kdepimlibs/akonadi/tests -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - -macro(add_akonadi_isolated_test _source) - get_filename_component(_targetName ${_source} NAME_WE) - set(_srcList ${_source} fakeserver/fakeserver.cpp) - - kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/../settings.kcfg org.kde.Akonadi.POP3.Settings) - set(pop3settingsinterface_xml ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.POP3.Settings.xml) - kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/../../maildir/maildirresource.kcfg org.kde.Akonadi.Maildir.Settings) - set(maildirsettingsinterface_xml ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.Maildir.Settings.xml) - set_source_files_properties(${pop3settingsinterface_xml} PROPERTIES INCLUDE "../metatype.h") - qt4_add_dbus_interface(_srcList ${pop3settingsinterface_xml} pop3settings) - qt4_add_dbus_interface(_srcList ${maildirsettingsinterface_xml} maildirsettings) - # add the dbus interace to every test (easier than adding to particular tests only) - #qt4_add_dbus_interface(_srcList ../org.kde.krss.xml krssinterface) - - kde4_add_executable(${_targetName} TEST ${_srcList}) - target_link_libraries(${_targetName} - ${QT_QTTEST_LIBRARY} - ${QT_QTGUI_LIBRARY} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDE4_KDECORE_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${QT_QTCORE_LIBRARY} - ${QT_QTNETWORK_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ) - - # based on kde4_add_unit_test - if (WIN32) - get_target_property( _loc ${_targetName} LOCATION ) - set(_executable ${_loc}.bat) - else () - set(_executable ${EXECUTABLE_OUTPUT_PATH}/${_targetName}) - endif () - if (UNIX) - set(_executable ${_executable}.shell) - endif () - - find_program(_testrunner akonaditest) - - if (KDEPIM_RUN_ISOLATED_TESTS) - add_test( ${_targetName} ${_testrunner} -c ${CMAKE_CURRENT_SOURCE_DIR}/unittestenv/config.xml ${_executable} ) - endif () -endmacro(add_akonadi_isolated_test) - -add_akonadi_isolated_test(pop3test.cpp) diff -Nru kdepim-runtime-4.14.6/resources/pop3/tests/fakeserver/fakeserver.cpp kdepim-runtime-15.08.0/resources/pop3/tests/fakeserver/fakeserver.cpp --- kdepim-runtime-4.14.6/resources/pop3/tests/fakeserver/fakeserver.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/tests/fakeserver/fakeserver.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,295 +0,0 @@ -/* - Copyright (C) 2008 Omat Holding B.V. - Copyright (C) 2009 Thomas McGuire - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -// Own -#include "fakeserver.h" - -// Qt -#include -#include -#include - -// KDE -#include - -FakeServerThread::FakeServerThread( QObject *parent ) - : QThread( parent ), - mServer( 0 ) -{ -} - -void FakeServerThread::run() -{ - mServer = new FakeServer(); - - // Run forever, until someone from the outside calls quit() on us and quits the - // event loop - exec(); - - delete mServer; - mServer = 0; -} - -FakeServer *FakeServerThread::server() const -{ - Q_ASSERT( mServer != 0 ); - return mServer; -} - -FakeServer::FakeServer( QObject* parent ) - : QObject( parent ), - mConnections( 0 ), - mProgress( 0 ), - mGotDisconnected( false ) -{ - mTcpServer = new QTcpServer(); - if ( !mTcpServer->listen( QHostAddress( QHostAddress::LocalHost ), 5989 ) ) { - kFatal() << "Unable to start the server"; - } - - connect( mTcpServer, SIGNAL(newConnection()), - this, SLOT(newConnection()) ); -} - -FakeServer::~FakeServer() -{ - if ( mConnections > 0 ) - disconnect( mTcpServerConnection, SIGNAL(readyRead()), - this, SLOT(dataAvailable()) ); - - delete mTcpServer; - mTcpServer = 0; -} - -QByteArray FakeServer::parseDeleteMark( const QByteArray &expectedData, - const QByteArray &dataReceived ) -{ - // Only called from parseResponse(), which is already thread-safe - - const QByteArray deleteMark = QString::fromLatin1( "%DELE%" ).toUtf8(); - if ( expectedData.contains( deleteMark ) ) { - Q_ASSERT( !mAllowedDeletions.isEmpty() ); - for ( int i = 0; i < mAllowedDeletions.size(); i++ ) { - QByteArray substituted = expectedData; - substituted = substituted.replace( deleteMark, mAllowedDeletions[i] ); - if ( substituted == dataReceived ) { - mAllowedDeletions.removeAt( i ); - return substituted; - } - } - qWarning() << "Received:" << dataReceived.data() - << "\nExpected:" << expectedData.data(); - Q_ASSERT_X( false, "FakeServer::parseDeleteMark", "Unable to substitute data!" ); - return QByteArray(); - } - else return expectedData; -} - -QByteArray FakeServer::parseRetrMark( const QByteArray &expectedData, - const QByteArray &dataReceived ) -{ - // Only called from parseResponse(), which is already thread-safe - - const QByteArray retrMark = QString::fromLatin1( "%RETR%" ).toUtf8(); - if ( expectedData.contains( retrMark ) ) { - Q_ASSERT( !mAllowedRetrieves.isEmpty() ); - for ( int i = 0; i < mAllowedRetrieves.size(); i++ ) { - QByteArray substituted = expectedData; - substituted = substituted.replace( retrMark, mAllowedRetrieves[i] ); - if ( substituted == dataReceived ) { - mAllowedRetrieves.removeAt( i ); - return substituted; - } - } - qWarning() << "Received:" << dataReceived.data() - << "\nExpected:" << expectedData.data(); - Q_ASSERT_X( false, "FakeServer::parseRetrMark", "Unable to substitute data!" ); - return QByteArray(); - } - else return expectedData; -} - -QByteArray FakeServer::parseResponse( const QByteArray& expectedData, - const QByteArray& dataReceived ) -{ - // Only called from dataAvailable, which is already thread-safe - - QByteArray result; - result = parseDeleteMark( expectedData, dataReceived ); - if ( result != expectedData ) - return result; - else return parseRetrMark( expectedData,dataReceived ); -} - -/* -// Used only for the debug output in dataAvailable() -static QByteArray removeCRLF( const QByteArray &ba ) -{ - QByteArray returnArray = ba; - returnArray.replace( "\r\n", QByteArray() ); - return returnArray; -} -*/ - -void FakeServer::dataAvailable() -{ - QMutexLocker locker( &mMutex ); - mProgress++; - - // We got data, so we better expect it and have an answer! - Q_ASSERT( !mReadData.isEmpty() ); - Q_ASSERT( !mWriteData.isEmpty() ); - - const QByteArray data = mTcpServerConnection->readAll(); - //qDebug() << "Got data:" << removeCRLF( data ); - const QByteArray expected( mReadData.takeFirst() ); - //qDebug() << "Expected data:" << removeCRLF( expected ); - const QByteArray reallyExpected = parseResponse( expected, data ); - //qDebug() << "Really expected:" << removeCRLF( reallyExpected ); - - Q_ASSERT( data == reallyExpected ); - - QByteArray toWrite = mWriteData.takeFirst(); - //qDebug() << "Going to write data:" << removeCRLF( toWrite ); - const bool allWritten = mTcpServerConnection->write( toWrite ) == toWrite.size(); - Q_ASSERT( allWritten ); - Q_UNUSED( allWritten ); - const bool flushed = mTcpServerConnection->flush(); - Q_ASSERT( flushed ); - Q_UNUSED( flushed ); -} - -void FakeServer::newConnection() -{ - QMutexLocker locker( &mMutex ); - Q_ASSERT( mConnections == 0 ); - mConnections++; - mGotDisconnected = false; - - mTcpServerConnection = mTcpServer->nextPendingConnection(); - mTcpServerConnection->write( QByteArray( "+OK Initech POP3 server ready.\r\n" ) ); - connect( mTcpServerConnection, SIGNAL(readyRead()), this, SLOT(dataAvailable()) ); - connect( mTcpServerConnection, SIGNAL(disconnected()), this, SLOT(slotDisconnected()) ); -} - -void FakeServer::slotDisconnected() -{ - QMutexLocker locker( &mMutex ); - mConnections--; - mGotDisconnected = true; - Q_ASSERT( mConnections == 0 ); - Q_ASSERT( mAllowedDeletions.isEmpty() ); - Q_ASSERT( mAllowedRetrieves.isEmpty() ); - Q_ASSERT( mReadData.isEmpty() ); - Q_ASSERT( mWriteData.isEmpty() ); - emit disconnected(); -} - -void FakeServer::setAllowedDeletions( const QString &deleteIds ) -{ - QMutexLocker locker( &mMutex ); - mAllowedDeletions.clear(); - QStringList ids = deleteIds.split( QLatin1Char(','), QString::SkipEmptyParts ); - foreach( const QString &id, ids ) { - mAllowedDeletions.append( id.toUtf8() ); - } -} - -void FakeServer::setAllowedRetrieves( const QString &retrieveIds ) -{ - QMutexLocker locker( &mMutex ); - mAllowedRetrieves.clear(); - QStringList ids = retrieveIds.split( QLatin1Char(','), QString::SkipEmptyParts ); - foreach( const QString &id, ids ) { - mAllowedRetrieves.append( id.toUtf8() ); - } -} - -void FakeServer::setMails( const QList &mails) -{ - QMutexLocker locker( &mMutex ); - mMails = mails; -} - -void FakeServer::setNextConversation( const QString& conversation, - const QList &exceptions ) -{ - QMutexLocker locker( &mMutex ); - - Q_ASSERT( mReadData.isEmpty() ); - Q_ASSERT( mWriteData.isEmpty() ); - Q_ASSERT( !conversation.isEmpty() ); - - mGotDisconnected = false; - QStringList lines = conversation.split( QLatin1String("\r\n"), QString::SkipEmptyParts ); - Q_ASSERT( lines.first().startsWith( QLatin1String("C:") ) ); - - enum Mode { Client, Server }; - Mode mode = Client; - - const QByteArray mailSizeMarker = QString::fromLatin1( "%MAILSIZE%" ).toLatin1(); - const QByteArray mailMarker = QString::fromLatin1( "%MAIL%" ).toLatin1(); - int sizeIndex = 0; - int mailIndex = 0; - - foreach( const QString &line, lines ) { - - QByteArray lineData( line.toUtf8() ); - - if ( lineData.contains( mailSizeMarker ) ) { - Q_ASSERT( mMails.size() > sizeIndex ); - lineData.replace( mailSizeMarker, - QString::number( mMails[sizeIndex++].size() ).toLatin1() ); - } - if ( lineData.contains( mailMarker ) ) { - while( exceptions.contains( mailIndex + 1 ) ) - mailIndex++; - Q_ASSERT( mMails.size() > mailIndex ); - lineData.replace( mailMarker, mMails[mailIndex++] ); - } - - if ( lineData.startsWith( "S: " ) ) { - mWriteData.append( lineData.mid( 3 ) + "\r\n" ); - mode = Server; - } - else if ( line.startsWith( QLatin1String("C: ") ) ) { - mReadData.append( lineData.mid( 3 ) + "\r\n" ); - mode = Client; - } - else { - switch ( mode ) { - case Server: mWriteData.last() += ( lineData + "\r\n" ); break; - case Client: mReadData.last() += ( lineData + "\r\n" ); break; - } - } - } -} - -int FakeServer::progress() const -{ - QMutexLocker locker( &mMutex ); - return mProgress; -} - -bool FakeServer::gotDisconnected() const -{ - QMutexLocker locker( &mMutex ); - return mGotDisconnected; -} - diff -Nru kdepim-runtime-4.14.6/resources/pop3/tests/fakeserver/fakeserver.h kdepim-runtime-15.08.0/resources/pop3/tests/fakeserver/fakeserver.h --- kdepim-runtime-4.14.6/resources/pop3/tests/fakeserver/fakeserver.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/tests/fakeserver/fakeserver.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -/* - Copyright (C) 2008 Omat Holding B.V. - Copyright (C) 2009 Thomas McGuire - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -#ifndef FAKESERVER_H -#define FAKESERVER_H - -#include -#include -#include -#include -#include - -class FakeServer : public QObject -{ - Q_OBJECT - -public: - FakeServer( QObject* parent = 0 ); - ~FakeServer(); - - void setNextConversation( const QString &conversation, - const QList &exceptions = QList() ); - void setAllowedDeletions( const QString &deleteIds ); - void setAllowedRetrieves( const QString &retrieveIds ); - void setMails( const QList &mails ); - - // This is kind of a hack: The POP3 test needs to know when the POP3 client - // disconnects from the server. Normally, we could just use a QSignalSpy on the - // disconnected() signal, but that is not thread-safe. Therefore this hack with the - // state variable mGotDisconnected - bool gotDisconnected() const; - - // Returns an integer that is incremented each time the POP3 server receives some - // data - int progress() const; - -Q_SIGNALS: - void disconnected(); - -private Q_SLOTS: - - void newConnection(); - void dataAvailable(); - void slotDisconnected(); - -private: - - QByteArray parseDeleteMark( const QByteArray& expectedData, const QByteArray& dataReceived ); - QByteArray parseRetrMark( const QByteArray& expectedData, const QByteArray& dataReceived ); - QByteArray parseResponse( const QByteArray& expectedData, const QByteArray& dataReceived ); - - QList mReadData; - QList mWriteData; - QList mAllowedDeletions; - QList mAllowedRetrieves; - QList mMails; - QTcpServer *mTcpServer; - QTcpSocket* mTcpServerConnection; - int mConnections; - int mProgress; - bool mGotDisconnected; - - // We use one big mutex to protect everything - // There shouldn't be deadlocks, as there are only 2 places where the functions - // are called: From the KTcpSocket signals, which are triggered by the POP3 ioslave, - // and from the actual test. - mutable QMutex mMutex; -}; - -class FakeServerThread : public QThread -{ - Q_OBJECT - -public: - - explicit FakeServerThread( QObject *parent ); - virtual void run(); - - // Returns the FakeServer use. Be careful when using this and make sure - // the methods you use are actually thread-safe!! - // This should however be the case because the FakeServer uses one big mutex - // to protect everything. - FakeServer *server() const; - -private: - - FakeServer *mServer; -}; - -#endif - diff -Nru kdepim-runtime-4.14.6/resources/pop3/tests/pop3test.cpp kdepim-runtime-15.08.0/resources/pop3/tests/pop3test.cpp --- kdepim-runtime-4.14.6/resources/pop3/tests/pop3test.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/tests/pop3test.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,914 +0,0 @@ -/* Copyright 2009 Thomas McGuire - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "pop3test.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -QTEST_AKONADIMAIN( Pop3Test, NoGUI ) - -using namespace Akonadi; - -void Pop3Test::initTestCase() -{ - QVERIFY( Akonadi::Control::start() ); - - // switch all resources offline to reduce interference from them - foreach ( Akonadi::AgentInstance agent, Akonadi::AgentManager::self()->instances() ) - agent.setIsOnline( false ); - - /* - qDebug() << "==========================================================="; - qDebug() << "============ Stopping for debugging ======================="; - qDebug() << "==========================================================="; - kill( qApp->applicationPid(), SIGSTOP ); - */ - - // - // Create the maildir and pop3 resources - // - AgentType maildirType = AgentManager::self()->type( QLatin1String("akonadi_maildir_resource") ); - AgentInstanceCreateJob *agentCreateJob = new AgentInstanceCreateJob( maildirType ); - QVERIFY( agentCreateJob->exec() ); - mMaildirIdentifier = agentCreateJob->instance().identifier(); - - AgentType popType = AgentManager::self()->type( QLatin1String("akonadi_pop3_resource") ); - agentCreateJob = new AgentInstanceCreateJob( popType ); - QVERIFY( agentCreateJob->exec() ); - mPop3Identifier = agentCreateJob->instance().identifier(); - - // - // Configure the maildir resource - // - QString maildirRootPath = KGlobal::dirs()->saveLocation( "data", QLatin1String("tester"), false ) + QLatin1String("maildirtest"); - mMaildirPath = maildirRootPath + QLatin1String("/new"); - mMaildirSettingsInterface = new OrgKdeAkonadiMaildirSettingsInterface( - QLatin1String("org.freedesktop.Akonadi.Resource." )+ mMaildirIdentifier, - QLatin1String("/Settings"), QDBusConnection::sessionBus(), this ); - QDBusReply setPathReply = mMaildirSettingsInterface->setPath( maildirRootPath ); - QVERIFY( setPathReply.isValid() ); - AgentManager::self()->instance( mMaildirIdentifier ).reconfigure(); - QDBusReply getPathReply = mMaildirSettingsInterface->path(); - QCOMPARE( getPathReply.value(), maildirRootPath ); - AgentManager::self()->instance( mMaildirIdentifier ).synchronize(); - - // - // Find the root maildir collection - // - bool found = false; - QTime time; - time.start(); - while ( !found ) { - CollectionFetchJob *job = new CollectionFetchJob( Collection::root(), CollectionFetchJob::Recursive ); - QVERIFY( job->exec() ); - Collection::List collections = job->collections(); - foreach( const Collection &col, collections ) { - if ( col.resource() == AgentManager::self()->instance( mMaildirIdentifier ).identifier() ) { - mMaildirCollection = col; - found = true; - break; - } - } - - QVERIFY( time.elapsed() < 10 * 1000 ); // maildir should not need more than 10 secs to sync - } - - // - // Start the fake POP3 server - // - mFakeServerThread = new FakeServerThread( this ); - mFakeServerThread->start(); - QTest::qWait( 100 ); - QVERIFY( mFakeServerThread->server() != 0 ); - - // - // Configure the pop3 resource - // - mPOP3SettingsInterface = new OrgKdeAkonadiPOP3SettingsInterface( - QLatin1String("org.freedesktop.Akonadi.Resource.") + mPop3Identifier, - QLatin1String("/Settings"), QDBusConnection::sessionBus(), this ); - - QDBusReply reply0 = mPOP3SettingsInterface->port(); - QVERIFY( reply0.isValid() ); - QVERIFY( reply0.value() == 110 ); - - mPOP3SettingsInterface->setPort( 5989 ); - AgentManager::self()->instance( mPop3Identifier ).reconfigure(); - QDBusReply reply = mPOP3SettingsInterface->port(); - QVERIFY( reply.isValid() ); - QVERIFY( reply.value() == 5989 ); - - mPOP3SettingsInterface->setHost( QLatin1String("localhost") ); - AgentManager::self()->instance( mPop3Identifier ).reconfigure(); - QDBusReply reply2 = mPOP3SettingsInterface->host(); - QVERIFY( reply2.isValid() ); - QVERIFY( reply2.value() == QLatin1String("localhost") ); - mPOP3SettingsInterface->setLogin( QLatin1String("HansWurst") ); - AgentManager::self()->instance( mPop3Identifier ).reconfigure(); - QDBusReply reply3 = mPOP3SettingsInterface->login(); - QVERIFY( reply3.isValid() ); - QVERIFY( reply3.value() == QLatin1String("HansWurst") ); - - mPOP3SettingsInterface->setUnitTestPassword( QLatin1String("Geheim") ); - AgentManager::self()->instance( mPop3Identifier ).reconfigure(); - QDBusReply reply4 = mPOP3SettingsInterface->unitTestPassword(); - QVERIFY( reply4.isValid() ); - QVERIFY( reply4.value() == QLatin1String("Geheim") ); - - mPOP3SettingsInterface->setTargetCollection( mMaildirCollection.id() ); - AgentManager::self()->instance( mPop3Identifier ).reconfigure(); - QDBusReply reply5 = mPOP3SettingsInterface->targetCollection(); - QVERIFY( reply5.isValid() ); - QVERIFY( reply5.value() == mMaildirCollection.id() ); -} - -void Pop3Test::cleanupTestCase() -{ - // Post the "quit" event to the thread's event loop, then wait until the thread - // is finished (it finishes when the event loop finishes) - QMetaObject::invokeMethod( mFakeServerThread, "quit", Qt::QueuedConnection ); - if ( !mFakeServerThread->wait( 10000 ) ) - qWarning() << "The fake server thread has not yet finished, what is wrong!?"; -} - -static const QByteArray simpleMail1 = - "From: \"Bill Lumbergh\" \r\n" - "To: \"Peter Gibbons\" \r\n" - "Subject: TPS Reports - New Cover Sheets\r\n" - "MIME-Version: 1.0\r\n" - "Content-Type: text/plain\r\n" - "Date: Mon, 23 Mar 2009 18:04:05 +0300\r\n" - "\r\n" - "Hi, Peter. What's happening? We need to talk about your TPS reports.\r\n"; - -static const QByteArray simpleMail2 = - "From: \"Amy McCorkell\" \r\n" - "To: gov.palin@yaho.com\r\n" - "Subject: HI SARAH\r\n" - "MIME-Version: 1.0\r\n" - "Content-Type: text/plain\r\n" - "Date: Mon, 23 Mar 2009 18:04:05 +0300\r\n" - "\r\n" - "Hey Sarah,\r\n" - "bla bla bla bla bla\r\n"; - -static const QByteArray simpleMail3 = - "From: chunkylover53@aol.com\r\n" - "To: tylerdurden@paperstreetsoapcompany.com\r\n" - "Subject: ILOVEYOU\r\n" - "MIME-Version: 1.0\r\n" - "Content-Type: text/plain\r\n" - "Date: Mon, 23 Mar 2009 18:04:05 +0300\r\n" - "\r\n" - "kindly check the attached LOVELETTER coming from me.\r\n"; - -static const QByteArray simpleMail4 = - "From: karl@aol.com\r\n" - "To: lenny@aol.com\r\n" - "Subject: Who took the donuts?\r\n" - "\r\n" - "Hi Lenny, do you know who took all the donuts?\r\n"; - -static const QByteArray simpleMail5 = - "From: foo@bar.com\r\n" - "To: bar@foo.com\r\n" - "Subject: Hello\r\n" - "\r\n" - "Hello World!!\r\n"; - -void Pop3Test::cleanupMaildir( Akonadi::Item::List items ) -{ - // Delete all mails so the maildir is clean for the next test - if ( !items.isEmpty() ) { - ItemDeleteJob *job = new ItemDeleteJob( items ); - QVERIFY( job->exec() ); - } - - QTime time; - time.start(); - int lastCount = -1; - forever { - qApp->processEvents(); - QTest::qWait( 500 ); - QDir maildir( mMaildirPath ); - maildir.refresh(); - int curCount = maildir.entryList( QDir::Files | QDir::NoDotAndDotDot ).count(); - - // Restart the timer when a mail arrives, as it shows that the maildir resource is - // still alive and kicking. - if ( curCount != lastCount ) { - time.restart(); - lastCount = curCount; - } - - if ( curCount == 0 ) - break; - - QVERIFY( time.elapsed() < 60000 || time.elapsed() > 80000000 ); - } -} - -void Pop3Test::checkMailsInMaildir( const QList &mails ) -{ - // Now, test that all mails actually ended up in the maildir. Since the maildir resource - // might be slower, give it a timeout so it can write the files to disk - QTime time; - time.start(); - int lastCount = -1; - forever { - qApp->processEvents(); - QTest::qWait( 500 ); - QDir maildir( mMaildirPath ); - maildir.refresh(); - int curCount = static_cast( maildir.entryList( QDir::Files | QDir::NoDotAndDotDot ).count() ); - - // Restart the timer when a mail arrives, as it shows that the maildir resource is - // still alive and kicking. - if ( curCount != lastCount ) { - time.start(); - lastCount = curCount; - } - - if ( curCount == mails.count() ) { - break; - } - QVERIFY( static_cast( maildir.entryList( QDir::NoDotAndDotDot ).count() ) <= mails.count() ); - QVERIFY( time.elapsed() < 60000 || time.elapsed() > 80000000 ); - } - - // TODO: check file contents as well or is this overkill? -} - -Akonadi::Item::List Pop3Test::checkMailsOnAkonadiServer( const QList &mails ) -{ - // The fake server got disconnected, which means the pop3 resource has entered the QUIT - // stage. That means all messages should be on the server now, so test that. - ItemFetchJob *job = new ItemFetchJob( mMaildirCollection ); - job->fetchScope().fetchFullPayload(); - Q_ASSERT( job->exec() ); - Item::List items = job->items(); - Q_ASSERT( mails.size() == items.size() ); - - QSet ourMailBodies; - QSet itemMailBodies; - - foreach( const Item &item, items ) { - KMime::Message::Ptr itemMail = item.payload(); - QByteArray itemMailBody = itemMail->body(); - - // For some reason, the body in the maildir has one additional newline. - // Get rid of this so we can compare them. - // FIXME: is this a bug? Find out where the newline comes from! - itemMailBody.chop( 1 ); - itemMailBodies.insert( itemMailBody ); - } - - foreach( const QByteArray &mail, mails ) { - KMime::Message::Ptr ourMail( new KMime::Message() ); - ourMail->setContent( KMime::CRLFtoLF( mail ) ); - ourMail->parse(); - QByteArray ourMailBody = ourMail->body(); - ourMailBodies.insert( ourMailBody ); - } - - Q_ASSERT( ourMailBodies == itemMailBodies ); - return items; -} - -void Pop3Test::syncAndWaitForFinish() -{ - AgentManager::self()->instance( mPop3Identifier ).synchronize(); - - // The pop3 resource, ioslave and the fakeserver are all in different processes or threads. - // We simply wait until the FakeServer got disconnected or until a timeout. - // Since POP3 fetching can take longer, we reset the timeout timer when the FakeServer - // does some processing. - QTime time; - time.start(); - int lastProgress = -1; - forever { - qApp->processEvents(); - - // Finish correctly when the connection got closed - if ( mFakeServerThread->server()->gotDisconnected() ) { - break; - } - - // Reset the timeout when the server is working - const int newProgress = mFakeServerThread->server()->progress(); - if ( newProgress != lastProgress ) { - time.restart(); - lastProgress = newProgress; - } - - // Assert when nothing happens for a certain timeout, that indicates something went - // wrong and is stucked somewhere - if ( time.elapsed() >= 60000 ) { - Q_ASSERT_X( false, "poptest", "FakeServer timed out." ); - break; - } - } -} - -QString Pop3Test::loginSequence() const -{ - return - QLatin1String("C: USER HansWurst\r\n" - "S: +OK May I have your password, please?\r\n" - "C: PASS Geheim\r\n" - "S: +OK Mailbox locked and ready\r\n"); -} - -QString Pop3Test::retrieveSequence( const QList &mails, - const QList &exceptions ) const -{ - QString result; - for( int i = 1; i <= mails.size(); i++ ) { - if ( !exceptions.contains( i ) ) { - result += QLatin1String( - "C: RETR %RETR%\r\n" - "S: +OK Here is your spam\r\n" - "%MAIL%\r\n" - ".\r\n" ); - } - } - return result; -} - -QString Pop3Test::deleteSequence( int numToDelete ) const -{ - QString result; - for ( int i = 0; i < numToDelete; i++ ) { - result += - QLatin1String("C: DELE %DELE%\r\n" - "S: +OK message sent to /dev/null\r\n"); - } - return result; -} - -QString Pop3Test::quitSequence() const -{ - return - QLatin1String("C: QUIT\r\n" - "S: +OK Have a nice day.\r\n"); -} - -QString Pop3Test::listSequence( const QList &mails ) const -{ - QString result = QLatin1String("C: LIST\r\n" - "S: +OK You got new spam\r\n"); - for ( int i = 1; i <= mails.size(); i++ ) { - result += QString::fromLatin1( "%1 %MAILSIZE%\r\n" ).arg( i ); - } - result += QLatin1String(".\r\n"); - return result; -} - -QString Pop3Test::uidSequence( const QStringList& uids ) const -{ - QString result = QLatin1String("C: UIDL\r\n" - "S: +OK\r\n"); - for ( int i = 1; i <= uids.size(); i++ ) { - result += QString::fromLatin1( "%1 %2\r\n" ).arg( i ).arg( uids[i - 1] ); - } - result += QLatin1String(".\r\n"); - return result; -} - -static bool sortedEqual( const QStringList &list1, const QStringList &list2 ) -{ - QStringList sorted1 = list1; - sorted1.sort(); - QStringList sorted2 = list2; - sorted2.sort(); - - return qEqual( sorted1.begin(), sorted1.end(), sorted2.begin() ); -} - -void Pop3Test::lowerTimeOfSeenMail( const QString &uidOfMail, int secondsToLower ) -{ - const int index = mPOP3SettingsInterface->seenUidList().value().indexOf( uidOfMail ); - QList seenTimeList = mPOP3SettingsInterface->seenUidTimeList().value(); - int msgTime = seenTimeList.at( index ); - msgTime -= secondsToLower; - seenTimeList.replace( index, msgTime ); - mPOP3SettingsInterface->setSeenUidTimeList( seenTimeList ); -} - -void Pop3Test::testSimpleDownload() -{ - QList mails; - mails << simpleMail1 << simpleMail2 << simpleMail3; - QStringList uids; - uids << QLatin1String("UID1") << QLatin1String("UID2") << QLatin1String("UID3"); - mFakeServerThread->server()->setAllowedDeletions(QLatin1String("1,2,3")); - mFakeServerThread->server()->setAllowedRetrieves(QLatin1String("1,2,3")); - mFakeServerThread->server()->setMails( mails ); - mFakeServerThread->server()->setNextConversation( - loginSequence() + - listSequence( mails ) + - uidSequence( uids ) + - retrieveSequence( mails ) + - deleteSequence( mails.size() ) + - quitSequence() - ); - - syncAndWaitForFinish(); - Akonadi::Item::List items = checkMailsOnAkonadiServer( mails ); - checkMailsInMaildir( mails ); - cleanupMaildir( items ); -} - -void Pop3Test::testBigFetch() -{ - QList mails; - QStringList uids; - QString allowedRetrs; - for( int i = 0; i < 1000; i++ ) { - QByteArray newMail = simpleMail1; - newMail.append( QString::number( i + 1 ).toLatin1() ); - mails << newMail; - uids << QString::fromLatin1( "UID%1" ).arg( i + 1 ); - allowedRetrs += QString::number( i + 1 ) + QLatin1Char(','); - } - allowedRetrs.chop( 1 ); - - mFakeServerThread->server()->setMails( mails ); - mFakeServerThread->server()->setAllowedRetrieves( allowedRetrs ); - mFakeServerThread->server()->setAllowedDeletions( allowedRetrs ); - mFakeServerThread->server()->setNextConversation( - loginSequence() + - listSequence( mails ) + - uidSequence( uids ) + - retrieveSequence( mails ) + - deleteSequence( mails.size() ) + - quitSequence() - ); - - syncAndWaitForFinish(); - Akonadi::Item::List items = checkMailsOnAkonadiServer( mails ); - checkMailsInMaildir( mails ); - cleanupMaildir( items ); -} - -void Pop3Test::testSeenUIDCleanup() -{ - // - // First, fetch 3 normal mails, but leave them on the server. - // - mPOP3SettingsInterface->setLeaveOnServer( true ); - QList mails; - mails << simpleMail1 << simpleMail2 << simpleMail3; - QStringList uids; - uids << QLatin1String("UID1") << QLatin1String("UID2") << QLatin1String("UID3"); - mFakeServerThread->server()->setAllowedDeletions( QString() ); - mFakeServerThread->server()->setAllowedRetrieves( QLatin1String("1,2,3") ); - mFakeServerThread->server()->setMails( mails ); - mFakeServerThread->server()->setNextConversation( - loginSequence() + - listSequence( mails ) + - uidSequence( uids ) + - retrieveSequence( mails ) + - quitSequence() - ); - - syncAndWaitForFinish(); - Akonadi::Item::List items = checkMailsOnAkonadiServer( mails ); - checkMailsInMaildir( mails ); - cleanupMaildir( items ); - - QVERIFY( sortedEqual( uids, mPOP3SettingsInterface->seenUidList().value() ) ); - QVERIFY( mPOP3SettingsInterface->seenUidTimeList().value().size() == - mPOP3SettingsInterface->seenUidList().value().size() ); - - // - // Now, pretend that the messages were removed from the server in the meantime - // by having no mails on the fake server. - // - mFakeServerThread->server()->setMails( QList() ); - mFakeServerThread->server()->setAllowedRetrieves( QString() ); - mFakeServerThread->server()->setAllowedDeletions( QString() ); - mFakeServerThread->server()->setNextConversation( - loginSequence() + - listSequence( QList() ) + - uidSequence( QStringList() ) + - quitSequence() - ); - syncAndWaitForFinish(); - items = checkMailsOnAkonadiServer( QList() ); - checkMailsInMaildir( QList() ); - cleanupMaildir( items ); - - QVERIFY( mPOP3SettingsInterface->seenUidList().value().isEmpty() ); - QVERIFY( mPOP3SettingsInterface->seenUidTimeList().value().size() == - mPOP3SettingsInterface->seenUidList().value().size() ); - - mPOP3SettingsInterface->setLeaveOnServer(false ); -} - -void Pop3Test::testSimpleLeaveOnServer() -{ - mPOP3SettingsInterface->setLeaveOnServer( true ); - - QList mails; - mails << simpleMail1 << simpleMail2 << simpleMail3; - QStringList uids; - uids << QLatin1String("UID1") << QLatin1String("UID2") << QLatin1String("UID3"); - mFakeServerThread->server()->setMails( mails ); - mFakeServerThread->server()->setAllowedRetrieves(QLatin1String("1,2,3")); - mFakeServerThread->server()->setNextConversation( - loginSequence() + - listSequence( mails ) + - uidSequence( uids ) + - retrieveSequence( mails ) + - quitSequence() - ); - - syncAndWaitForFinish(); - Akonadi::Item::List items = checkMailsOnAkonadiServer( mails ); - checkMailsInMaildir( mails ); - - // The resource should have saved the UIDs of the seen messages - QVERIFY( sortedEqual( uids, mPOP3SettingsInterface->seenUidList().value() ) ); - QVERIFY( mPOP3SettingsInterface->seenUidTimeList().value().size() == - mPOP3SettingsInterface->seenUidList().value().size() ); - foreach( int seenTime, mPOP3SettingsInterface->seenUidTimeList().value() ) { - // Those message were just downloaded from the fake server, so they are at maximum - // 10 minutes old (for slooooow running tests) - QVERIFY( seenTime >= time( 0 ) - 10 * 60 ); - } - - // - // OK, next mail check: We have to check that the old seen messages are not downloaded again, - // only new mails. - // - QList newMails( mails ); - newMails << simpleMail4; - QStringList newUids( uids ); - newUids << QLatin1String("newUID"); - QList idsToNotDownload; - idsToNotDownload << 1 << 2 << 3; - mFakeServerThread->server()->setMails( newMails ); - mFakeServerThread->server()->setAllowedRetrieves(QLatin1String("4")); - mFakeServerThread->server()->setNextConversation( - loginSequence() + - listSequence( newMails ) + - uidSequence( newUids ) + - retrieveSequence( newMails, idsToNotDownload ) + - quitSequence(), - idsToNotDownload - ); - - syncAndWaitForFinish(); - items = checkMailsOnAkonadiServer( newMails ); - checkMailsInMaildir( newMails ); - QVERIFY( sortedEqual( newUids, mPOP3SettingsInterface->seenUidList().value() ) ); - QVERIFY( mPOP3SettingsInterface->seenUidTimeList().value().size() == - mPOP3SettingsInterface->seenUidList().value().size() ); - - // - // Ok, next test: When turning off leaving on the server, all mails should be deleted, but - // none downloaded. - // - mPOP3SettingsInterface->setLeaveOnServer( false ); - - mFakeServerThread->server()->setAllowedDeletions(QLatin1String( "1,2,3,4") ); - mFakeServerThread->server()->setAllowedRetrieves( QString() ); - mFakeServerThread->server()->setNextConversation( - loginSequence() + - listSequence( newMails ) + - uidSequence( newUids ) + - deleteSequence( newMails.size() ) + - quitSequence() - ); - - syncAndWaitForFinish(); - items = checkMailsOnAkonadiServer( newMails ); - checkMailsInMaildir( newMails ); - cleanupMaildir( items ); - QVERIFY( mPOP3SettingsInterface->seenUidList().value().isEmpty() ); - QVERIFY( mPOP3SettingsInterface->seenUidTimeList().value().size() == - mPOP3SettingsInterface->seenUidList().value().size() ); -} - -void Pop3Test::testTimeBasedLeaveRule() -{ - mPOP3SettingsInterface->setLeaveOnServer( true ); - mPOP3SettingsInterface->setLeaveOnServerDays( 2 ); - - // - // First download 3 mails and leave them on the server - // - QList mails; - mails << simpleMail1 << simpleMail2 << simpleMail3; - QStringList uids; - uids << QLatin1String("UID1") << QLatin1String("UID2") << QLatin1String("UID3"); - mFakeServerThread->server()->setMails( mails ); - mFakeServerThread->server()->setAllowedRetrieves(QLatin1String("1,2,3")); - mFakeServerThread->server()->setNextConversation( - loginSequence() + - listSequence( mails ) + - uidSequence( uids ) + - retrieveSequence( mails ) + - quitSequence() - ); - - syncAndWaitForFinish(); - Akonadi::Item::List items = checkMailsOnAkonadiServer( mails ); - checkMailsInMaildir( mails ); - - QVERIFY( sortedEqual( uids, mPOP3SettingsInterface->seenUidList().value() ) ); - QVERIFY( mPOP3SettingsInterface->seenUidTimeList().value().size() == - mPOP3SettingsInterface->seenUidList().value().size() ); - - // - // Now, modify the seenUidTimeList on the server for UID2 to pretend it - // was downloaded 3 days ago, which means it should be deleted. - // - lowerTimeOfSeenMail( QLatin1String("UID2"), 60 * 60 * 24 * 3 ); - - QList idsToNotDownload; - idsToNotDownload << 1 << 3; - mFakeServerThread->server()->setAllowedDeletions( QLatin1String("2") ); - mFakeServerThread->server()->setAllowedRetrieves( QString() ); - mFakeServerThread->server()->setNextConversation( - loginSequence() + - listSequence( mails ) + - uidSequence( uids ) + - deleteSequence( 1 ) + - quitSequence(), - idsToNotDownload - ); - syncAndWaitForFinish(); - items = checkMailsOnAkonadiServer( mails ); - checkMailsInMaildir( mails ); - cleanupMaildir( items ); - - uids.removeAll( QLatin1String("UID2") ); - QVERIFY( sortedEqual( uids, mPOP3SettingsInterface->seenUidList().value() ) ); - QVERIFY( mPOP3SettingsInterface->seenUidTimeList().value().size() == - mPOP3SettingsInterface->seenUidList().value().size() ); - foreach( int seenTime, mPOP3SettingsInterface->seenUidTimeList().value() ) { - QVERIFY( seenTime >= time( 0 ) - 10 * 60 ); - } - - mPOP3SettingsInterface->setLeaveOnServer( false ); - mPOP3SettingsInterface->setLeaveOnServerDays( 0 ); - mPOP3SettingsInterface->setSeenUidTimeList( QList() ); - mPOP3SettingsInterface->setSeenUidList( QStringList() ); -} - -void Pop3Test::testCountBasedLeaveRule() -{ - mPOP3SettingsInterface->setLeaveOnServer( true ); - mPOP3SettingsInterface->setLeaveOnServerCount( 3 ); - - // - // First download 3 mails and leave them on the server - // - QList mails; - mails << simpleMail1 << simpleMail2 << simpleMail3; - QStringList uids; - uids << QLatin1String("UID1") << QLatin1String("UID2") << QLatin1String("UID3"); - mFakeServerThread->server()->setMails( mails ); - mFakeServerThread->server()->setAllowedRetrieves(QLatin1String("1,2,3")); - mFakeServerThread->server()->setNextConversation( - loginSequence() + - listSequence( mails ) + - uidSequence( uids ) + - retrieveSequence( mails ) + - quitSequence() - ); - - syncAndWaitForFinish(); - checkMailsOnAkonadiServer( mails ); - checkMailsInMaildir( mails ); - - // Make the 3 just downloaded mails appear older than they are - lowerTimeOfSeenMail( QLatin1String("UID1"), 60 * 60 * 24 * 2 ); - lowerTimeOfSeenMail( QLatin1String("UID2"), 60 * 60 * 24 * 1 ); - lowerTimeOfSeenMail( QLatin1String("UID3"), 60 * 60 * 24 * 3 ); - - // - // Now, download 2 more mails. Since only 3 mails are allowed to be left - // on the server, the oldest ones, UID1 and UID3, should be deleted - // - QList moreMails; - moreMails << simpleMail4 << simpleMail5; - QStringList moreUids; - moreUids << QLatin1String("UID4") << QLatin1String("UID5"); - mFakeServerThread->server()->setMails( mails + moreMails ); - mFakeServerThread->server()->setAllowedRetrieves( QLatin1String("4,5") ); - mFakeServerThread->server()->setAllowedDeletions( QLatin1String("1,3") ); - mFakeServerThread->server()->setNextConversation( - loginSequence() + - listSequence( mails + moreMails ) + - uidSequence( uids + moreUids ) + - retrieveSequence( moreMails ) + - deleteSequence( 2 ) + - quitSequence(), QList() << 1 << 2 << 3 - ); - - syncAndWaitForFinish(); - Akonadi::Item::List items = checkMailsOnAkonadiServer( mails + moreMails ); - checkMailsInMaildir( mails + moreMails ); - cleanupMaildir( items ); - - QStringList uidsLeft; - uidsLeft << QLatin1String("UID2") << QLatin1String("UID4") << QLatin1String("UID5"); - - QVERIFY( sortedEqual( uidsLeft, mPOP3SettingsInterface->seenUidList().value() ) ); - QVERIFY( mPOP3SettingsInterface->seenUidTimeList().value().size() == - mPOP3SettingsInterface->seenUidList().value().size() ); - - mPOP3SettingsInterface->setLeaveOnServer( false ); - mPOP3SettingsInterface->setLeaveOnServerCount( 0 ); - mPOP3SettingsInterface->setSeenUidTimeList( QList() ); - mPOP3SettingsInterface->setSeenUidList( QStringList() ); -} - -void Pop3Test::testSizeBasedLeaveRule() -{ - mPOP3SettingsInterface->setLeaveOnServer( true ); - mPOP3SettingsInterface->setLeaveOnServerSize( 10 ); // 10 MB - - // - // First download 3 mails and leave them on the server. - // - QList mails; - mails << simpleMail1 << simpleMail2 << simpleMail3; - QStringList uids; - uids << QLatin1String("UID1") << QLatin1String("UID2") << QLatin1String("UID3"); - mFakeServerThread->server()->setMails( mails ); - mFakeServerThread->server()->setAllowedRetrieves(QLatin1String("1,2,3")); - mFakeServerThread->server()->setNextConversation( - loginSequence() + - listSequence( mails ) + - uidSequence( uids ) + - retrieveSequence( mails ) + - quitSequence() - ); - - syncAndWaitForFinish(); - checkMailsOnAkonadiServer( mails ); - checkMailsInMaildir( mails ); - - // Make the 3 just downloaded mails appear older than they are - lowerTimeOfSeenMail( QLatin1String("UID1"), 60 * 60 * 24 * 2 ); - lowerTimeOfSeenMail( QLatin1String("UID2"), 60 * 60 * 24 * 1 ); - lowerTimeOfSeenMail( QLatin1String("UID3"), 60 * 60 * 24 * 3 ); - - // Now, do another mail check, but with no new mails on the server. - // Instead we let the server pretend that the mails have a fake size, - // each 7 MB. That means the two oldest get deleted, because the total - // mail size is over 10 MB with them. - mFakeServerThread->server()->setMails( mails ); - mFakeServerThread->server()->setAllowedRetrieves( QString() ); - mFakeServerThread->server()->setAllowedDeletions( QLatin1String("1,3") ); - mFakeServerThread->server()->setNextConversation( - loginSequence() + - QLatin1String("C: LIST\r\n" - "S: +OK You got new spam\r\n" - "1 7340032\r\n" - "2 7340032\r\n" - "3 7340032\r\n" - ".\r\n") + - uidSequence( uids ) + - deleteSequence( 2 ) + - quitSequence() - ); - - syncAndWaitForFinish(); - Akonadi::Item::List items = checkMailsOnAkonadiServer( mails ); - checkMailsInMaildir( mails ); - cleanupMaildir( items ); - - QStringList uidsLeft; - uidsLeft << QLatin1String("UID2"); - - QVERIFY( sortedEqual( uidsLeft, mPOP3SettingsInterface->seenUidList().value() ) ); - QVERIFY( mPOP3SettingsInterface->seenUidTimeList().value().size() == - mPOP3SettingsInterface->seenUidList().value().size() ); - - mPOP3SettingsInterface->setLeaveOnServer( false ); - mPOP3SettingsInterface->setLeaveOnServerCount( 0 ); - mPOP3SettingsInterface->setLeaveOnServerSize( 0 ); - mPOP3SettingsInterface->setSeenUidTimeList( QList() ); - mPOP3SettingsInterface->setSeenUidList( QStringList() ); -} - -void Pop3Test::testMixedLeaveRules() -{ - mPOP3SettingsInterface->setLeaveOnServer( true ); - // - // Generate 10 mails - // - QList mails; - QStringList uids; - QString allowedRetrs; - for( int i = 0; i < 10; i++ ) { - QByteArray newMail = simpleMail1; - newMail.append( QString::number( i + 1 ).toLatin1() ); - mails << newMail; - uids << QString::fromLatin1( "UID%1" ).arg( i + 1 ); - allowedRetrs += QString::number( i + 1 ) + QLatin1Char(','); - } - allowedRetrs.chop( 1 ); - - // - // Now, download these 10 mails - // - mFakeServerThread->server()->setMails( mails ); - mFakeServerThread->server()->setAllowedRetrieves( allowedRetrs ); - mFakeServerThread->server()->setNextConversation( - loginSequence() + - listSequence( mails ) + - uidSequence( uids ) + - retrieveSequence( mails ) + - quitSequence() - ); - - syncAndWaitForFinish(); - checkMailsOnAkonadiServer( mails ); - checkMailsInMaildir( mails ); - - // Fake the time of the messages, UID1 is one day old, UID2 is two days old, etc - for ( int i = 1; i <= 10; i++ ) - lowerTimeOfSeenMail( QString::fromLatin1( "UID%1" ).arg( i ), 60 * 60 * 24 * i ); - - mPOP3SettingsInterface->setLeaveOnServer( true ); - mPOP3SettingsInterface->setLeaveOnServerSize( 25 ); // UID 4, 5 oldest here - mPOP3SettingsInterface->setLeaveOnServerCount( 5 ); // UID 6, 7 oldest here - mPOP3SettingsInterface->setLeaveOnServerDays( 7 ); // UID 8, 9 and 10 too old - - // Ok, now we do another mail check that only deletes stuff from the server. - // Above are the UIDs that should be deleted. - mFakeServerThread->server()->setMails( mails ); - mFakeServerThread->server()->setAllowedRetrieves( QString() ); - mFakeServerThread->server()->setAllowedDeletions( QLatin1String("4,5,6,7,8,9,10") ); - mFakeServerThread->server()->setNextConversation( - loginSequence() + - QLatin1String("C: LIST\r\n" - "S: +OK You got new spam\r\n" - "1 7340032\r\n" - "2 7340032\r\n" - "3 7340032\r\n" - "4 7340032\r\n" - "5 7340032\r\n" - "6 7340032\r\n" - "7 7340032\r\n" - "8 7340032\r\n" - "9 7340032\r\n" - "10 7340032\r\n" - ".\r\n") + - uidSequence( uids ) + - deleteSequence( 7 ) + - quitSequence() - ); - - syncAndWaitForFinish(); - Akonadi::Item::List items = checkMailsOnAkonadiServer( mails ); - checkMailsInMaildir( mails ); - cleanupMaildir( items ); - - QStringList uidsLeft; - uidsLeft << QLatin1String("UID1") << QLatin1String("UID2")<seenUidList().value() ) ); - QVERIFY( mPOP3SettingsInterface->seenUidTimeList().value().size() == - mPOP3SettingsInterface->seenUidList().value().size() ); - - mPOP3SettingsInterface->setLeaveOnServer( false ); - mPOP3SettingsInterface->setLeaveOnServerCount( 0 ); - mPOP3SettingsInterface->setLeaveOnServerSize( 0 ); - mPOP3SettingsInterface->setSeenUidTimeList( QList() ); - mPOP3SettingsInterface->setSeenUidList( QStringList() ); -} diff -Nru kdepim-runtime-4.14.6/resources/pop3/tests/pop3test.h kdepim-runtime-15.08.0/resources/pop3/tests/pop3test.h --- kdepim-runtime-4.14.6/resources/pop3/tests/pop3test.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/tests/pop3test.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -/* Copyright 2009 Thomas McGuire - - 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 ) version 3 or, at the discretion of KDE e.V. - ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 POP3TEST_H -#define POP3TEST_H - -#include "fakeserver/fakeserver.h" -#include "pop3settings.h" -#include "maildirsettings.h" - -#include -#include - -#include -#include - -class Pop3Test : public QObject -{ - Q_OBJECT - - void replymMaildirSettingsInterface ( QString arg1 ); - private slots: - void initTestCase(); - void cleanupTestCase(); - void testSimpleDownload(); - void testSimpleLeaveOnServer(); - void testBigFetch(); - void testSeenUIDCleanup(); - void testTimeBasedLeaveRule(); - void testCountBasedLeaveRule(); - void testSizeBasedLeaveRule(); - void testMixedLeaveRules(); - - private: - void lowerTimeOfSeenMail( const QString &uidOfMail, int secondsToLower ); - void cleanupMaildir( Akonadi::Item::List items ); - void checkMailsInMaildir( const QList< QByteArray >& mails ); - Akonadi::Item::List checkMailsOnAkonadiServer( const QList &mails ); - void syncAndWaitForFinish(); - QString loginSequence() const; - QString retrieveSequence( const QList< QByteArray >& mails, - const QList &exceptions = QList() ) const; - QString deleteSequence( int numToDelete ) const; - QString quitSequence() const; - QString listSequence( const QList &mails ) const; - QString uidSequence( const QStringList &uids ) const; - - FakeServerThread *mFakeServerThread; - - OrgKdeAkonadiPOP3SettingsInterface *mPOP3SettingsInterface; - OrgKdeAkonadiMaildirSettingsInterface *mMaildirSettingsInterface; - Akonadi::Collection mMaildirCollection; - QString mPop3Identifier; - QString mMaildirIdentifier; - QString mMaildirPath; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/pop3/tests/unittestenv/config.xml kdepim-runtime-15.08.0/resources/pop3/tests/unittestenv/config.xml --- kdepim-runtime-4.14.6/resources/pop3/tests/unittestenv/config.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/tests/unittestenv/config.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ - - kdehome - xdgconfig - xdglocal - true - diff -Nru kdepim-runtime-4.14.6/resources/pop3/tests/unittestenv/kdehome/share/apps/.keep kdepim-runtime-15.08.0/resources/pop3/tests/unittestenv/kdehome/share/apps/.keep --- kdepim-runtime-4.14.6/resources/pop3/tests/unittestenv/kdehome/share/apps/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/tests/unittestenv/kdehome/share/apps/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/pop3/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc kdepim-runtime-15.08.0/resources/pop3/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc --- kdepim-runtime-4.14.6/resources/pop3/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[ProcessedDefaults] -defaultaddressbook=done -defaultcalendar=done diff -Nru kdepim-runtime-4.14.6/resources/pop3/tests/unittestenv/kdehome/share/config/kdebugrc kdepim-runtime-15.08.0/resources/pop3/tests/unittestenv/kdehome/share/config/kdebugrc --- kdepim-runtime-4.14.6/resources/pop3/tests/unittestenv/kdehome/share/config/kdebugrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/tests/unittestenv/kdehome/share/config/kdebugrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ -[0] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[kbuildsycoca4] -AbortFatal=true -ErrorOutput=0 -FatalOutput=0 -InfoOutput=0 -WarnOutput=0 - -[kdecore (services)] -AbortFatal=true -ErrorOutput=0 -FatalOutput=0 -InfoOutput=0 -WarnOutput=0 - -[264] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[5250] -InfoOutput=2 - -[7009] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[7011] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[7012] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[7014] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=0 -FatalFilename[$e]=kdebug.dbg -FatalOutput=0 -InfoFilename[$e]=kdebug.dbg -InfoOutput=0 -WarnFilename[$e]=kdebug.dbg -WarnOutput=0 - -[7021] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[7105] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 diff -Nru kdepim-runtime-4.14.6/resources/pop3/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc kdepim-runtime-15.08.0/resources/pop3/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/resources/pop3/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/tests/unittestenv/xdgconfig/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -[%General] - -[Search] -Manager=Dummy diff -Nru kdepim-runtime-4.14.6/resources/pop3/tests/unittestenv/xdglocal/.keep kdepim-runtime-15.08.0/resources/pop3/tests/unittestenv/xdglocal/.keep --- kdepim-runtime-4.14.6/resources/pop3/tests/unittestenv/xdglocal/.keep 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/tests/unittestenv/xdglocal/.keep 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -force git to include this file diff -Nru kdepim-runtime-4.14.6/resources/pop3/wizard/CMakeLists.txt kdepim-runtime-15.08.0/resources/pop3/wizard/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/pop3/wizard/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/wizard/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,2 +1,2 @@ -install ( FILES pop3wizard.desktop pop3wizard.es pop3wizard.ui DESTINATION ${DATA_INSTALL_DIR}/akonadi/accountwizard/pop3 ) +install ( FILES pop3wizard.desktop pop3wizard.es pop3wizard.ui DESTINATION ${KDE_INSTALL_DATADIR}/akonadi/accountwizard/pop3 ) diff -Nru kdepim-runtime-4.14.6/resources/pop3/wizard/pop3wizard.desktop kdepim-runtime-15.08.0/resources/pop3/wizard/pop3wizard.desktop --- kdepim-runtime-4.14.6/resources/pop3/wizard/pop3wizard.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/pop3/wizard/pop3wizard.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,52 +1,41 @@ [Desktop Entry] -Name=Pop3 -Name[bg]=Pop3 -Name[bs]=Pop3 -Name[ca]=Pop3 -Name[ca@valencia]=Pop3 -Name[cs]=Pop3 +Name=POP3 +Name[bg]=POP3 +Name[ca]=POP3 +Name[cs]=POP3 Name[da]=POP3 Name[de]=POP3 -Name[el]=Pop3 -Name[en_GB]=Pop3 -Name[es]=Pop3 +Name[el]=POP3 +Name[en_GB]=POP3 +Name[es]=POP3 Name[et]=POP3 Name[fi]=POP3 -Name[fr]=Pop3 -Name[ga]=POP3 -Name[gl]=Pop3 -Name[hr]=Pop3 +Name[fr]=POP3 +Name[gl]=POP3 Name[hu]=POP3 -Name[ia]=POP3 Name[it]=POP3 -Name[ja]=Pop3 -Name[kk]=Pop3 -Name[km]=Pop3 -Name[ko]=Pop3 -Name[lt]=Pop3 -Name[lv]=Pop3 -Name[nb]=Pop3 +Name[ko]=POP3 +Name[lv]=POP3 +Name[nb]=POP3 Name[nds]=POP3 Name[nl]=POP3 Name[nn]=POP3 -Name[pa]=Pop3 -Name[pl]=Pop3 +Name[pa]=POP3 +Name[pl]=POP3 Name[pt]=POP3 Name[pt_BR]=POP3 -Name[ro]=Pop3 -Name[ru]=POP3 -Name[sk]=Pop3 +Name[sk]=POP3 Name[sl]=POP3 Name[sr]=ПОП3 Name[sr@ijekavian]=ПОП3 Name[sr@ijekavianlatin]=POP3 Name[sr@latin]=POP3 Name[sv]=Pop3 -Name[tr]=Pop3 +Name[tr]=POP3 Name[uk]=POP3 -Name[x-test]=xxPop3xx -Name[zh_CN]=Pop3 -Name[zh_TW]=Pop3 +Name[x-test]=xxPOP3xx +Name[zh_CN]=POP3 +Name[zh_TW]=POP3 Icon=message-rfc822 Comment=Pop3 account Comment[bg]=Сметка POP3 diff -Nru kdepim-runtime-4.14.6/resources/shared/CMakeLists.txt kdepim-runtime-15.08.0/resources/shared/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/shared/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,2 +1,3 @@ add_subdirectory(filestore) -add_subdirectory(tests) \ No newline at end of file +add_subdirectory(singlefileresource) + diff -Nru kdepim-runtime-4.14.6/resources/shared/collectionannotationsattribute.cpp kdepim-runtime-15.08.0/resources/shared/collectionannotationsattribute.cpp --- kdepim-runtime-4.14.6/resources/shared/collectionannotationsattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/collectionannotationsattribute.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -/* - Copyright (C) 2008 Omat Holding B.V. - - 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 "collectionannotationsattribute.h" - -#include -#include -#include - -using namespace Akonadi; - -CollectionAnnotationsAttribute::CollectionAnnotationsAttribute() -{ -} - -CollectionAnnotationsAttribute::CollectionAnnotationsAttribute( const QMap &annotations ) - : mAnnotations( annotations ) -{ -} - -void CollectionAnnotationsAttribute::setAnnotations( const QMap &annotations ) -{ - mAnnotations = annotations; -} - -QMap CollectionAnnotationsAttribute::annotations() const -{ - return mAnnotations; -} - -QByteArray CollectionAnnotationsAttribute::type() const -{ - static const QByteArray sType( "collectionannotations" ); - return sType; -} - -Akonadi::Attribute* CollectionAnnotationsAttribute::clone() const -{ - return new CollectionAnnotationsAttribute( mAnnotations ); -} - -QByteArray CollectionAnnotationsAttribute::serialized() const -{ - QByteArray result = ""; - - foreach ( const QByteArray &key, mAnnotations.keys() ) { - result+= key; - result+= ' '; - result+= mAnnotations[key]; - result+= " % "; // We use this separator as '%' is not allowed in keys or values - } - result.chop( 3 ); - - return result; -} - -void CollectionAnnotationsAttribute::deserialize( const QByteArray &data ) -{ - mAnnotations.clear(); - const QList lines = data.split( '%' ); - - for ( int i = 0; i < lines.size(); ++i ) { - QByteArray line = lines[i]; - if ( i != 0 && line.startsWith( ' ' ) ) - line = line.mid( 1 ); - if ( i != lines.size() - 1 && line.endsWith( ' ' ) ) - line.chop( 1 ); - if ( line.trimmed().isEmpty() ) - continue; - int wsIndex = line.indexOf( ' ' ); - if ( wsIndex > 0 ) { - const QByteArray key = line.mid( 0, wsIndex ); - const QByteArray value = line.mid( wsIndex+1 ); - mAnnotations[key] = value; - } else { - mAnnotations.insert( line, QByteArray() ); - } - } -} diff -Nru kdepim-runtime-4.14.6/resources/shared/collectionannotationsattribute.h kdepim-runtime-15.08.0/resources/shared/collectionannotationsattribute.h --- kdepim-runtime-4.14.6/resources/shared/collectionannotationsattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/collectionannotationsattribute.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -/* - Copyright (C) 2008 Omat Holding B.V. - - 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_COLLECTIONANNOTATIONSATTRIBUTE_H -#define AKONADI_COLLECTIONANNOTATIONSATTRIBUTE_H - -#include - -#include - -namespace Akonadi { - -class CollectionAnnotationsAttribute : public Akonadi::Attribute -{ - public: - CollectionAnnotationsAttribute(); - CollectionAnnotationsAttribute( const QMap &annotations ); - void setAnnotations( const QMap &annotations ); - QMap annotations() const; - virtual QByteArray type() const; - virtual Attribute *clone() const; - virtual QByteArray serialized() const; - virtual void deserialize( const QByteArray &data ); - - private: - QMap mAnnotations; -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/collectionflagsattribute.cpp kdepim-runtime-15.08.0/resources/shared/collectionflagsattribute.cpp --- kdepim-runtime-4.14.6/resources/shared/collectionflagsattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/collectionflagsattribute.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -/* - Copyright (C) 2008 Omat Holding B.V. - - 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 "collectionflagsattribute.h" - -#include -#include - -using namespace Akonadi; - -CollectionFlagsAttribute::CollectionFlagsAttribute( const QList &flags ) - : mFlags( flags ) -{ -} - -void CollectionFlagsAttribute::setFlags( const QList &flags ) -{ - mFlags = flags; -} - -QList CollectionFlagsAttribute::flags() const -{ - return mFlags; -} - -QByteArray CollectionFlagsAttribute::type() const -{ - static const QByteArray sType( "collectionflags" ); - return sType; -} - -Akonadi::Attribute* CollectionFlagsAttribute::clone() const -{ - return new CollectionFlagsAttribute( mFlags ); -} - -QByteArray CollectionFlagsAttribute::serialized() const -{ - QByteArray result; - - foreach ( const QByteArray &flag, mFlags ) { - result+= flag+' '; - } - result.chop( 1 ); - - return result; -} - -void CollectionFlagsAttribute::deserialize( const QByteArray &data ) -{ - mFlags = data.split( ' ' ); -} diff -Nru kdepim-runtime-4.14.6/resources/shared/collectionflagsattribute.h kdepim-runtime-15.08.0/resources/shared/collectionflagsattribute.h --- kdepim-runtime-4.14.6/resources/shared/collectionflagsattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/collectionflagsattribute.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/* - Copyright (C) 2008 Omat Holding B.V. - - 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_COLLECTIONFLAGSATTRIBUTE_H -#define AKONADI_COLLECTIONFLAGSATTRIBUTE_H - -#include - -namespace Akonadi { - -class CollectionFlagsAttribute : public Akonadi::Attribute -{ - public: - explicit CollectionFlagsAttribute( const QList &flags = QList() ); - void setFlags( const QList &flags ); - QList flags() const; - virtual QByteArray type() const; - virtual Attribute *clone() const; - virtual QByteArray serialized() const; - virtual void deserialize( const QByteArray &data ); - - private: - QList mFlags; -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/createandsettagsjob.cpp kdepim-runtime-15.08.0/resources/shared/createandsettagsjob.cpp --- kdepim-runtime-4.14.6/resources/shared/createandsettagsjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/createandsettagsjob.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2014 Christian Mollekopf - * - * 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 "createandsettagsjob.h" -#include -#include - -using namespace Akonadi; - -CreateAndSetTagsJob::CreateAndSetTagsJob(const Item& item, const Akonadi::Tag::List& tags, QObject* parent) -: KJob(parent), - mItem(item), - mTags(tags), - mCount(0) -{ - -} - -void CreateAndSetTagsJob::start() -{ - if (mTags.isEmpty()) { - emitResult(); - } - Q_FOREACH (const Akonadi::Tag &tag, mTags) { - Akonadi::TagCreateJob *createJob = new Akonadi::TagCreateJob(tag, this); - createJob->setMergeIfExisting(true); - connect(createJob, SIGNAL(result(KJob*)), this, SLOT(onCreateDone(KJob*))); - } -} - -void CreateAndSetTagsJob::onCreateDone(KJob *job) -{ - mCount++; - if (job->error()) { - kWarning() << "Failed to create tag " << job->errorString(); - } else { - Akonadi::TagCreateJob *createJob = static_cast(job); - mCreatedTags << createJob->tag(); - } - if (mCount == mTags.size()) { - Q_FOREACH (const Akonadi::Tag &tag, mCreatedTags) { - mItem.setTag(tag); - } - Akonadi::ItemModifyJob *modJob = new Akonadi::ItemModifyJob(mItem, this); - connect(modJob, SIGNAL(result(KJob*)), this, SLOT(onModifyDone(KJob*))); - } -} - -void CreateAndSetTagsJob::onModifyDone(KJob *job) -{ - if (job->error()) { - kWarning() << "Failed to modify item " << job->errorString(); - setError(KJob::UserDefinedError); - } - emitResult(); -} diff -Nru kdepim-runtime-4.14.6/resources/shared/createandsettagsjob.h kdepim-runtime-15.08.0/resources/shared/createandsettagsjob.h --- kdepim-runtime-4.14.6/resources/shared/createandsettagsjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/createandsettagsjob.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2014 Christian Mollekopf - * - * 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 CREATEANDSETTAGSJOB_H -#define CREATEANDSETTAGSJOB_H - -#include -#include -#include - -class CreateAndSetTagsJob : public KJob -{ - Q_OBJECT -public: - explicit CreateAndSetTagsJob(const Akonadi::Item &item, const Akonadi::Tag::List &tags, QObject* parent = 0); - - virtual void start(); - -private Q_SLOTS: - void onCreateDone(KJob*); - void onModifyDone(KJob*); - -private: - Akonadi::Item mItem; - Akonadi::Tag::List mTags; - Akonadi::Tag::List mCreatedTags; - int mCount; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/dirsettingsdialog.cpp kdepim-runtime-15.08.0/resources/shared/dirsettingsdialog.cpp --- kdepim-runtime-4.14.6/resources/shared/dirsettingsdialog.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/dirsettingsdialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -/* - Copyright (c) 2009 Tobias Koenig - - 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 "dirsettingsdialog.h" - -#include "settings.h" - -#include -#include - -#include - -using namespace Akonadi; - -SettingsDialog::SettingsDialog( WId windowId ) - : KDialog() -{ - ui.setupUi( mainWidget() ); - ui.kcfg_Path->setMode( KFile::LocalOnly | KFile::Directory ); - setButtons( Ok | Cancel ); - - if ( windowId ) - KWindowSystem::setMainWindow( this, windowId ); - - connect( this, SIGNAL(okClicked()), SLOT(save()) ); - - connect( ui.kcfg_Path, SIGNAL(textChanged(QString)), SLOT(validate()) ); - connect( ui.kcfg_ReadOnly, SIGNAL(toggled(bool)), SLOT(validate()) ); - - QTimer::singleShot( 0, this, SLOT(validate()) ); - - ui.kcfg_Path->setUrl( KUrl( Settings::self()->path() ) ); - ui.kcfg_AutosaveInterval->setSuffix(ki18np(" minute", " minutes")); - mManager = new KConfigDialogManager( this, Settings::self() ); - mManager->updateWidgets(); -} - -void SettingsDialog::save() -{ - mManager->updateSettings(); - Settings::self()->setPath( ui.kcfg_Path->url().toLocalFile() ); - Settings::self()->writeConfig(); -} - -void SettingsDialog::validate() -{ - const KUrl currentUrl = ui.kcfg_Path->url(); - if ( currentUrl.isEmpty() ) { - enableButton( Ok, false ); - return; - } - - const QFileInfo file( currentUrl.toLocalFile() ); - if ( file.exists() && !file.isWritable() ) { - ui.kcfg_ReadOnly->setEnabled( false ); - ui.kcfg_ReadOnly->setChecked( true ); - } else { - ui.kcfg_ReadOnly->setEnabled( true ); - } - enableButton( Ok, true ); -} diff -Nru kdepim-runtime-4.14.6/resources/shared/dirsettingsdialog.h kdepim-runtime-15.08.0/resources/shared/dirsettingsdialog.h --- kdepim-runtime-4.14.6/resources/shared/dirsettingsdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/dirsettingsdialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -/* - Copyright (c) 2009 Tobias Koenig - - 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 DIRSETTINGSDIALOG_H -#define DIRSETTINGSDIALOG_H - -#include "ui_settingsdialog.h" - -#include - -class KConfigDialogManager; - -namespace Akonadi { - -class SettingsDialog : public KDialog -{ - Q_OBJECT - public: - explicit SettingsDialog( WId windowId ); - - private Q_SLOTS: - void save(); - void validate(); - - private: - Ui::SettingsDialog ui; - KConfigDialogManager* mManager; -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/abstractlocalstore.cpp kdepim-runtime-15.08.0/resources/shared/filestore/abstractlocalstore.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/abstractlocalstore.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/abstractlocalstore.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -33,249 +33,281 @@ #include "sessionimpls_p.h" #include "storecompactjob.h" -#include -#include +#include +#include #include - +#include #include using namespace Akonadi; class JobProcessingAdaptor : public FileStore::Job::Visitor { - public: - explicit JobProcessingAdaptor( FileStore::AbstractJobSession *session ) - : mSession( session ) +public: + explicit JobProcessingAdaptor(FileStore::AbstractJobSession *session) + : mSession(session) { } - public: // Job::Visitor interface implementation - bool visit( FileStore::Job *job ) { Q_UNUSED( job ); return false ; } +public: // Job::Visitor interface implementation + bool visit(FileStore::Job *job) Q_DECL_OVERRIDE { + Q_UNUSED(job); + return false ; + } - bool visit( FileStore::CollectionCreateJob *job ) { Q_UNUSED( job ); return false ; } + bool visit(FileStore::CollectionCreateJob *job) Q_DECL_OVERRIDE { + Q_UNUSED(job); + return false ; + } - bool visit( FileStore::CollectionDeleteJob *job ) { Q_UNUSED( job ); return false ; } + bool visit(FileStore::CollectionDeleteJob *job) Q_DECL_OVERRIDE { + Q_UNUSED(job); + return false ; + } - bool visit( FileStore::CollectionFetchJob *job ) { Q_UNUSED( job ); return false ; } + bool visit(FileStore::CollectionFetchJob *job) Q_DECL_OVERRIDE { + Q_UNUSED(job); + return false ; + } - bool visit( FileStore::CollectionModifyJob *job ) { Q_UNUSED( job ); return false ; } + bool visit(FileStore::CollectionModifyJob *job) Q_DECL_OVERRIDE { + Q_UNUSED(job); + return false ; + } - bool visit( FileStore::CollectionMoveJob *job ) { Q_UNUSED( job ); return false ; } + bool visit(FileStore::CollectionMoveJob *job) Q_DECL_OVERRIDE { + Q_UNUSED(job); + return false ; + } - bool visit( FileStore::ItemCreateJob *job ) { Q_UNUSED( job ); return false ; } + bool visit(FileStore::ItemCreateJob *job) Q_DECL_OVERRIDE { + Q_UNUSED(job); + return false ; + } - bool visit( FileStore::ItemDeleteJob *job ) { Q_UNUSED( job ); return false ; } + bool visit(FileStore::ItemDeleteJob *job) Q_DECL_OVERRIDE { + Q_UNUSED(job); + return false ; + } - bool visit( FileStore::ItemFetchJob *job ) { Q_UNUSED( job ); return false ; } + bool visit(FileStore::ItemFetchJob *job) Q_DECL_OVERRIDE { + Q_UNUSED(job); + return false ; + } - bool visit( FileStore::ItemModifyJob *job ) { Q_UNUSED( job ); return false ; } + bool visit(FileStore::ItemModifyJob *job) Q_DECL_OVERRIDE { + Q_UNUSED(job); + return false ; + } - bool visit( FileStore::ItemMoveJob *job ) { Q_UNUSED( job ); return false ; } + bool visit(FileStore::ItemMoveJob *job) Q_DECL_OVERRIDE { + Q_UNUSED(job); + return false ; + } - bool visit( FileStore::StoreCompactJob *job ) { Q_UNUSED( job ); return false ; } + bool visit(FileStore::StoreCompactJob *job) Q_DECL_OVERRIDE { + Q_UNUSED(job); + return false ; + } - protected: +protected: FileStore::AbstractJobSession *mSession; }; class TopLevelCollectionFetcher : public JobProcessingAdaptor { - public: - explicit TopLevelCollectionFetcher( FileStore::AbstractJobSession *session ) - : JobProcessingAdaptor( session ) +public: + explicit TopLevelCollectionFetcher(FileStore::AbstractJobSession *session) + : JobProcessingAdaptor(session) { } - void setTopLevelCollection( const Collection &collection ) + void setTopLevelCollection(const Collection &collection) { - mTopLevelCollection = collection; + mTopLevelCollection = collection; } - public: +public: using JobProcessingAdaptor::visit; - bool visit( FileStore::CollectionFetchJob *job ) - { - if ( job->type() == FileStore::CollectionFetchJob::Base && - job->collection().remoteId() == mTopLevelCollection.remoteId() ) { - mSession->notifyCollectionsReceived( job, Collection::List() << mTopLevelCollection ); - return true; - } + bool visit(FileStore::CollectionFetchJob *job) Q_DECL_OVERRIDE { + if (job->type() == FileStore::CollectionFetchJob::Base && + job->collection().remoteId() == mTopLevelCollection.remoteId()) + { + mSession->notifyCollectionsReceived(job, Collection::List() << mTopLevelCollection); + return true; + } - return false; + return false; } - private: +private: Collection mTopLevelCollection; }; class CollectionsProcessedNotifier : public JobProcessingAdaptor { - public: - explicit CollectionsProcessedNotifier( FileStore::AbstractJobSession *session ) - : JobProcessingAdaptor( session ) +public: + explicit CollectionsProcessedNotifier(FileStore::AbstractJobSession *session) + : JobProcessingAdaptor(session) { } - void setCollections( const Collection::List &collections ) + void setCollections(const Collection::List &collections) { - mCollections = collections; + mCollections = collections; } - public: +public: using JobProcessingAdaptor::visit; - bool visit( FileStore::CollectionCreateJob* job ) - { - Q_ASSERT( !mCollections.isEmpty() ); - if ( mCollections.count() > 1 ) { - kError() << "Processing collections for CollectionCreateJob " - "encountered more than one collection. Just processing the first one."; - } + bool visit(FileStore::CollectionCreateJob *job) Q_DECL_OVERRIDE { + Q_ASSERT(!mCollections.isEmpty()); + if (mCollections.count() > 1) + { + qCritical() << "Processing collections for CollectionCreateJob " + "encountered more than one collection. Just processing the first one."; + } - mSession->notifyCollectionCreated( job, mCollections[ 0 ] ); - return true; + mSession->notifyCollectionCreated(job, mCollections[ 0 ]); + return true; } - bool visit( FileStore::CollectionDeleteJob* job ) - { - Q_ASSERT( !mCollections.isEmpty() ); - if ( mCollections.count() > 1 ) { - kError() << "Processing collections for CollectionDeleteJob " - "encountered more than one collection. Just processing the first one."; - } + bool visit(FileStore::CollectionDeleteJob *job) Q_DECL_OVERRIDE { + Q_ASSERT(!mCollections.isEmpty()); + if (mCollections.count() > 1) + { + qCritical() << "Processing collections for CollectionDeleteJob " + "encountered more than one collection. Just processing the first one."; + } - mSession->notifyCollectionDeleted( job, mCollections[ 0 ] ); - return true; + mSession->notifyCollectionDeleted(job, mCollections[ 0 ]); + return true; } - bool visit( FileStore::CollectionFetchJob* job ) - { - mSession->notifyCollectionsReceived( job, mCollections ); - return true; + bool visit(FileStore::CollectionFetchJob *job) Q_DECL_OVERRIDE { + mSession->notifyCollectionsReceived(job, mCollections); + return true; } - bool visit( FileStore::CollectionModifyJob* job ) - { - Q_ASSERT( !mCollections.isEmpty() ); - if ( mCollections.count() > 1 ) { - kError() << "Processing collections for CollectionModifyJob " - "encountered more than one collection. Just processing the first one."; - } + bool visit(FileStore::CollectionModifyJob *job) Q_DECL_OVERRIDE { + Q_ASSERT(!mCollections.isEmpty()); + if (mCollections.count() > 1) + { + qCritical() << "Processing collections for CollectionModifyJob " + "encountered more than one collection. Just processing the first one."; + } - mSession->notifyCollectionModified( job, mCollections[ 0 ] ); - return true; + mSession->notifyCollectionModified(job, mCollections[ 0 ]); + return true; } - bool visit( FileStore::CollectionMoveJob* job ) - { - Q_ASSERT( !mCollections.isEmpty() ); - if ( mCollections.count() > 1 ) { - kError() << "Processing collections for CollectionMoveJob " - "encountered more than one collection. Just processing the first one."; - } + bool visit(FileStore::CollectionMoveJob *job) Q_DECL_OVERRIDE { + Q_ASSERT(!mCollections.isEmpty()); + if (mCollections.count() > 1) + { + qCritical() << "Processing collections for CollectionMoveJob " + "encountered more than one collection. Just processing the first one."; + } - mSession->notifyCollectionMoved( job, mCollections[ 0 ] ); - return true; + mSession->notifyCollectionMoved(job, mCollections[ 0 ]); + return true; } - bool visit( FileStore::StoreCompactJob* job ) - { - mSession->notifyCollectionsChanged( job, mCollections ); - return true; + bool visit(FileStore::StoreCompactJob *job) Q_DECL_OVERRIDE { + mSession->notifyCollectionsChanged(job, mCollections); + return true; } - private: +private: Collection::List mCollections; }; class ItemsProcessedNotifier : public JobProcessingAdaptor { - public: - explicit ItemsProcessedNotifier( FileStore::AbstractJobSession *session ) - : JobProcessingAdaptor( session ) +public: + explicit ItemsProcessedNotifier(FileStore::AbstractJobSession *session) + : JobProcessingAdaptor(session) { } - void setItems( const Item::List &items ) + void setItems(const Item::List &items) { - mItems = items; + mItems = items; } void clearItems() { - mItems.clear(); + mItems.clear(); } - public: +public: using JobProcessingAdaptor::visit; - bool visit( FileStore::ItemCreateJob* job ) - { - Q_ASSERT( !mItems.isEmpty() ); - if ( mItems.count() > 1 ) { - kError() << "Processing items for ItemCreateJob encountered more than one item. " - "Just processing the first one."; - } + bool visit(FileStore::ItemCreateJob *job) Q_DECL_OVERRIDE { + Q_ASSERT(!mItems.isEmpty()); + if (mItems.count() > 1) + { + qCritical() << "Processing items for ItemCreateJob encountered more than one item. " + "Just processing the first one."; + } - mSession->notifyItemCreated( job, mItems[ 0 ] ); - return true; + mSession->notifyItemCreated(job, mItems[ 0 ]); + return true; } - bool visit( FileStore::ItemFetchJob* job ) - { - mSession->notifyItemsReceived( job, mItems ); - return true; + bool visit(FileStore::ItemFetchJob *job) Q_DECL_OVERRIDE { + mSession->notifyItemsReceived(job, mItems); + return true; } - bool visit( FileStore::ItemModifyJob* job ) - { - Q_ASSERT( !mItems.isEmpty() ); - if ( mItems.count() > 1 ) { - kError() << "Processing items for ItemModifyJob encountered more than one item. " - "Just processing the first one."; - } + bool visit(FileStore::ItemModifyJob *job) Q_DECL_OVERRIDE { + Q_ASSERT(!mItems.isEmpty()); + if (mItems.count() > 1) + { + qCritical() << "Processing items for ItemModifyJob encountered more than one item. " + "Just processing the first one."; + } - mSession->notifyItemModified( job, mItems[ 0 ] ); - return true; + mSession->notifyItemModified(job, mItems[ 0 ]); + return true; } - bool visit( FileStore::ItemMoveJob* job ) - { - Q_ASSERT( !mItems.isEmpty() ); - if ( mItems.count() > 1 ) { - kError() << "Processing items for ItemMoveJob encountered more than one item. " - "Just processing the first one."; - } + bool visit(FileStore::ItemMoveJob *job) Q_DECL_OVERRIDE { + Q_ASSERT(!mItems.isEmpty()); + if (mItems.count() > 1) + { + qCritical() << "Processing items for ItemMoveJob encountered more than one item. " + "Just processing the first one."; + } - mSession->notifyItemMoved( job, mItems[ 0 ] ); - return true; + mSession->notifyItemMoved(job, mItems[ 0 ]); + return true; } - bool visit( FileStore::StoreCompactJob* job ) - { - mSession->notifyItemsChanged( job, mItems ); - return true; + bool visit(FileStore::StoreCompactJob *job) Q_DECL_OVERRIDE { + mSession->notifyItemsChanged(job, mItems); + return true; } - private: +private: Item::List mItems; }; class FileStore::AbstractLocalStore::Private { - AbstractLocalStore *const q; + AbstractLocalStore *const q; - public: - explicit Private( FileStore::AbstractLocalStore *parent ) - : q( parent ), mSession( new FileStore::FiFoQueueJobSession( q ) ), mCurrentJob( 0 ), - mTopLevelCollectionFetcher( mSession ), mCollectionsProcessedNotifier( mSession ), - mItemsProcessedNotifier( mSession ) +public: + explicit Private(FileStore::AbstractLocalStore *parent) + : q(parent), mSession(new FileStore::FiFoQueueJobSession(q)), mCurrentJob(Q_NULLPTR), + mTopLevelCollectionFetcher(mSession), mCollectionsProcessedNotifier(mSession), + mItemsProcessedNotifier(mSession) { } - public: +public: QFileInfo mPathFileInfo; Collection mTopLevelCollection; @@ -286,568 +318,567 @@ CollectionsProcessedNotifier mCollectionsProcessedNotifier; ItemsProcessedNotifier mItemsProcessedNotifier; - public: - void processJobs( const QList &jobs ); +public: + void processJobs(const QList &jobs); }; -void FileStore::AbstractLocalStore::Private::processJobs( const QList &jobs ) +void FileStore::AbstractLocalStore::Private::processJobs(const QList &jobs) { - Q_FOREACH( FileStore::Job *job, jobs ) { - mCurrentJob = job; + Q_FOREACH (FileStore::Job *job, jobs) { + mCurrentJob = job; - if ( job->error() == 0 ) { - if ( !job->accept( &mTopLevelCollectionFetcher ) ) { - q->processJob( job ); - } - } - mSession->emitResult( job ); - mCurrentJob = 0; - } + if (job->error() == 0) { + if (!job->accept(&mTopLevelCollectionFetcher)) { + q->processJob(job); + } + } + mSession->emitResult(job); + mCurrentJob = Q_NULLPTR; + } } FileStore::AbstractLocalStore::AbstractLocalStore() - : QObject(), d( new Private( this ) ) + : QObject(), d(new Private(this)) { - connect( d->mSession, SIGNAL(jobsReady(QList)), this, SLOT(processJobs(QList)) ); + connect(d->mSession, SIGNAL(jobsReady(QList)), this, SLOT(processJobs(QList))); } FileStore::AbstractLocalStore::~AbstractLocalStore() { - delete d; + delete d; } -void FileStore::AbstractLocalStore::setPath( const QString &path ) +void FileStore::AbstractLocalStore::setPath(const QString &path) { - QFileInfo pathFileInfo( path ); - if ( pathFileInfo.fileName().isEmpty() ) { - pathFileInfo = QFileInfo( pathFileInfo.path() ); - } - pathFileInfo.makeAbsolute(); + QFileInfo pathFileInfo(path); + if (pathFileInfo.fileName().isEmpty()) { + pathFileInfo = QFileInfo(pathFileInfo.path()); + } + pathFileInfo.makeAbsolute(); - if ( pathFileInfo.absoluteFilePath() == d->mPathFileInfo.absoluteFilePath() ) { - return; - } + if (pathFileInfo.absoluteFilePath() == d->mPathFileInfo.absoluteFilePath()) { + return; + } - d->mPathFileInfo = pathFileInfo; + d->mPathFileInfo = pathFileInfo; - Collection collection; - collection.setRemoteId( d->mPathFileInfo.absoluteFilePath() ); - collection.setName( d->mPathFileInfo.fileName() ); + Collection collection; + collection.setRemoteId(d->mPathFileInfo.absoluteFilePath()); + collection.setName(d->mPathFileInfo.fileName()); - EntityDisplayAttribute *attribute = collection.attribute(); - if ( attribute != 0 ) { - attribute->setDisplayName( d->mPathFileInfo.fileName() ); - } + EntityDisplayAttribute *attribute = collection.attribute(); + if (attribute != Q_NULLPTR) { + attribute->setDisplayName(d->mPathFileInfo.fileName()); + } - setTopLevelCollection( collection ); + setTopLevelCollection(collection); } QString FileStore::AbstractLocalStore::path() const { - return d->mPathFileInfo.absoluteFilePath(); + return d->mPathFileInfo.absoluteFilePath(); } Collection FileStore::AbstractLocalStore::topLevelCollection() const { - return d->mTopLevelCollection; + return d->mTopLevelCollection; } -FileStore::CollectionCreateJob *FileStore::AbstractLocalStore::createCollection( const Collection &collection, const Collection &targetParent ) +FileStore::CollectionCreateJob *FileStore::AbstractLocalStore::createCollection(const Collection &collection, const Collection &targetParent) { - FileStore::CollectionCreateJob *job = new FileStore::CollectionCreateJob( collection, targetParent, d->mSession ); + FileStore::CollectionCreateJob *job = new FileStore::CollectionCreateJob(collection, targetParent, d->mSession); - if ( d->mTopLevelCollection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Configured storage location is empty" ); - kError() << message; - kError() << collection << targetParent; - d->mSession->setError( job, FileStore::Job::InvalidStoreState, message ); - } else if ( targetParent.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Given folder name is empty" ); - kError() << message; - kError() << collection << targetParent; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } else if ( ( targetParent.rights() & Collection::CanCreateCollection ) == 0 ) { - const QString message = i18nc( "@info:status", "Access control prohibits folder creation in folder %1", targetParent.name() ); - kError() << message; - kError() << collection << targetParent; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } - - int errorCode = 0; - QString errorText; - checkCollectionCreate( job, errorCode, errorText ); - if ( errorCode != 0 ) { - d->mSession->setError( job, errorCode, errorText ); - } - - return job; -} - -FileStore::CollectionDeleteJob *FileStore::AbstractLocalStore::deleteCollection( const Collection &collection ) -{ - FileStore::CollectionDeleteJob *job = new FileStore::CollectionDeleteJob( collection, d->mSession ); - - if ( d->mTopLevelCollection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Configured storage location is empty" ); - kError() << message; - kError() << collection; - d->mSession->setError( job, FileStore::Job::InvalidStoreState, message ); - } else if ( collection.remoteId().isEmpty() || - collection.parentCollection().remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Given folder name is empty" ); - kError() << message; - kError() << collection; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } else if ( ( collection.rights() & Collection::CanDeleteCollection ) == 0 ) { - const QString message = i18nc( "@info:status", "Access control prohibits folder deletion in folder %1", collection.name() ); - kError() << message; - kError() << collection; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } - - int errorCode = 0; - QString errorText; - checkCollectionDelete( job, errorCode, errorText ); - if ( errorCode != 0 ) { - d->mSession->setError( job, errorCode, errorText ); - } - - return job; -} - -FileStore::CollectionFetchJob *FileStore::AbstractLocalStore::fetchCollections( const Collection &collection, FileStore::CollectionFetchJob::Type type ) const -{ - FileStore::CollectionFetchJob *job = new FileStore::CollectionFetchJob( collection, type, d->mSession ); - - if ( d->mTopLevelCollection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Configured storage location is empty" ); - kError() << message; - kError() << collection << "FetchType=" << type; - d->mSession->setError( job, FileStore::Job::InvalidStoreState, message ); - } else if ( collection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Given folder name is empty" ); - kError() << message; - kError() << collection << "FetchType=" << type; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } - - int errorCode = 0; - QString errorText; - checkCollectionFetch( job, errorCode, errorText ); - if ( errorCode != 0 ) { - d->mSession->setError( job, errorCode, errorText ); - } - - return job; -} - -FileStore::CollectionModifyJob *FileStore::AbstractLocalStore::modifyCollection( const Collection &collection ) -{ - FileStore::CollectionModifyJob *job = new FileStore::CollectionModifyJob( collection, d->mSession ); - - if ( d->mTopLevelCollection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Configured storage location is empty" ); - kError() << message; - kError() << collection; - d->mSession->setError( job, FileStore::Job::InvalidStoreState, message ); - } else if ( collection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Given folder name is empty" ); - kError() << message; - kError() << collection; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } else if ( ( collection.rights() & Collection::CanChangeCollection ) == 0 ) { - const QString message = i18nc( "@info:status", "Access control prohibits folder modification in folder %1", collection.name() ); - kError() << message; - kError() << collection; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } - - int errorCode = 0; - QString errorText; - checkCollectionModify( job, errorCode, errorText ); - if ( errorCode != 0 ) { - d->mSession->setError( job, errorCode, errorText ); - } - - return job; -} - -FileStore::CollectionMoveJob *FileStore::AbstractLocalStore::moveCollection( const Collection &collection, const Collection &targetParent ) -{ - FileStore::CollectionMoveJob *job = new FileStore::CollectionMoveJob( collection, targetParent, d->mSession ); - - if ( d->mTopLevelCollection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Configured storage location is empty" ); - kError() << message; - kError() << collection << targetParent; - d->mSession->setError( job, FileStore::Job::InvalidStoreState, message ); - } else if ( collection.remoteId().isEmpty() || - collection.parentCollection().remoteId().isEmpty() || - targetParent.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Given folder name is empty" ); - kError() << message; - kError() << collection << targetParent; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } else if ( ( targetParent.rights() & Collection::CanCreateCollection ) == 0 ) { - const QString message = i18nc( "@info:status", "Access control prohibits folder creation in folder %1", targetParent.name() ); - kError() << message; - kError() << collection << targetParent; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } - - int errorCode = 0; - QString errorText; - checkCollectionMove( job, errorCode, errorText ); - if ( errorCode != 0 ) { - d->mSession->setError( job, errorCode, errorText ); - } - - return job; -} - -FileStore::ItemFetchJob *FileStore::AbstractLocalStore::fetchItems( const Collection &collection ) const -{ - FileStore::ItemFetchJob *job = new FileStore::ItemFetchJob( collection, d->mSession ); - - if ( d->mTopLevelCollection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Configured storage location is empty" ); - kError() << message; - kError() << collection; - d->mSession->setError( job, FileStore::Job::InvalidStoreState, message ); - } else if ( collection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Given folder name is empty" ); - kError() << message; - kError() << collection; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } - - int errorCode = 0; - QString errorText; - checkItemFetch( job, errorCode, errorText ); - if ( errorCode != 0 ) { - d->mSession->setError( job, errorCode, errorText ); - } - - return job; -} - -FileStore::ItemFetchJob *FileStore::AbstractLocalStore::fetchItem( const Item &item ) const -{ - FileStore::ItemFetchJob *job = new FileStore::ItemFetchJob( item, d->mSession ); - - if ( d->mTopLevelCollection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Configured storage location is empty" ); - kError() << message; - kError() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ", parentCollection=" << item.parentCollection().remoteId() << ")"; - d->mSession->setError( job, FileStore::Job::InvalidStoreState, message ); - } else if ( item.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Given item identifier is empty" ); - kError() << message; - kError() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ", parentCollection=" << item.parentCollection().remoteId() << ")"; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } - - int errorCode = 0; - QString errorText; - checkItemFetch( job, errorCode, errorText ); - if ( errorCode != 0 ) { - d->mSession->setError( job, errorCode, errorText ); - } - - return job; -} - -FileStore::ItemCreateJob *FileStore::AbstractLocalStore::createItem( const Item &item, const Collection &collection ) -{ - FileStore::ItemCreateJob *job = new FileStore::ItemCreateJob( item, collection, d->mSession ); - - if ( d->mTopLevelCollection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Configured storage location is empty" ); - kError() << message; - kError() << collection - << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ")"; - d->mSession->setError( job, FileStore::Job::InvalidStoreState, message ); - } else if ( collection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Given folder name is empty" ); - kError() << message; - kError() << collection - << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ")"; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } else if ( ( collection.rights() & Collection::CanCreateItem ) == 0 ) { - const QString message = i18nc( "@info:status", "Access control prohibits item creation in folder %1", collection.name() ); - kError() << message; - kError() << collection - << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ")"; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } - - int errorCode = 0; - QString errorText; - checkItemCreate( job, errorCode, errorText ); - if ( errorCode != 0 ) { - d->mSession->setError( job, errorCode, errorText ); - } - - return job; -} - -FileStore::ItemModifyJob *FileStore::AbstractLocalStore::modifyItem( const Item &item ) -{ - FileStore::ItemModifyJob *job = new FileStore::ItemModifyJob( item, d->mSession ); - - if ( d->mTopLevelCollection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Configured storage location is empty" ); - kError() << message; - kError() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ", parentCollection=" << item.parentCollection().remoteId() << ")"; - d->mSession->setError( job, FileStore::Job::InvalidStoreState, message ); - } else if ( item.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Given item identifier is empty" ); - kError() << message; - kError() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ", parentCollection=" << item.parentCollection().remoteId() << ")"; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } else if ( ( item.parentCollection().rights() & Collection::CanChangeItem ) == 0 ) { - const QString message = i18nc( "@info:status", "Access control prohibits item modification in folder %1", item.parentCollection().name() ); - kError() << message; - kError() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ", parentCollection=" << item.parentCollection().remoteId() << ")"; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } - - int errorCode = 0; - QString errorText; - checkItemModify( job, errorCode, errorText ); - if ( errorCode != 0 ) { - d->mSession->setError( job, errorCode, errorText ); - } - - return job; -} - -FileStore::ItemDeleteJob *FileStore::AbstractLocalStore::deleteItem( const Item &item ) -{ - FileStore::ItemDeleteJob *job = new FileStore::ItemDeleteJob( item, d->mSession ); - - if ( d->mTopLevelCollection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Configured storage location is empty" ); - kError() << message; - kError() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ", parentCollection=" << item.parentCollection().remoteId() << ")"; - d->mSession->setError( job, FileStore::Job::InvalidStoreState, message ); - } else if ( item.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Given item identifier is empty" ); - kError() << message; - kError() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ", parentCollection=" << item.parentCollection().remoteId() << ")"; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } else if ( ( item.parentCollection().rights() & Collection::CanDeleteItem ) == 0 ) { - const QString message = i18nc( "@info:status", "Access control prohibits item deletion in folder %1", item.parentCollection().name() ); - kError() << message; - kError() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ", parentCollection=" << item.parentCollection().remoteId() << ")"; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } - - int errorCode = 0; - QString errorText; - checkItemDelete( job, errorCode, errorText ); - if ( errorCode != 0 ) { - d->mSession->setError( job, errorCode, errorText ); - } - - return job; -} - -FileStore::ItemMoveJob *FileStore::AbstractLocalStore::moveItem( const Item &item, const Collection &targetParent ) -{ - FileStore::ItemMoveJob *job = new FileStore::ItemMoveJob( item, targetParent, d->mSession ); - - if ( d->mTopLevelCollection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Configured storage location is empty" ); - kError() << message; - kError() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ", parentCollection=" << item.parentCollection().remoteId() << ")" - << targetParent; - d->mSession->setError( job, FileStore::Job::InvalidStoreState, message ); - } else if ( item.parentCollection().remoteId().isEmpty() || - targetParent.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Given folder name is empty" ); - kError() << message; - kError() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ", parentCollection=" << item.parentCollection().remoteId() << ")" - << targetParent; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } else if ( ( targetParent.rights() & Collection::CanCreateItem ) == 0 ) { - const QString message = i18nc( "@info:status", "Access control prohibits item creation in folder %1", targetParent.name() ); - kError() << message; - kError() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ", parentCollection=" << item.parentCollection().remoteId() << ")" - << targetParent; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } else if ( ( item.parentCollection().rights() & Collection::CanDeleteItem ) == 0 ) { - const QString message = i18nc( "@info:status", "Access control prohibits item deletion in folder %1", item.parentCollection().name() ); - kError() << message; - kError() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ", parentCollection=" << item.parentCollection().remoteId() << ")" - << targetParent; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } else if ( item.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Given item identifier is empty" ); - kError() << message; - kError() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() - << ", parentCollection=" << item.parentCollection().remoteId() << ")" - << targetParent; - d->mSession->setError( job, FileStore::Job::InvalidJobContext, message ); - } - - int errorCode = 0; - QString errorText; - checkItemMove( job, errorCode, errorText ); - if ( errorCode != 0 ) { - d->mSession->setError( job, errorCode, errorText ); - } + if (d->mTopLevelCollection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Configured storage location is empty"); + qCritical() << message; + qCritical() << collection << targetParent; + d->mSession->setError(job, FileStore::Job::InvalidStoreState, message); + } else if (targetParent.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Given folder name is empty"); + qCritical() << message; + qCritical() << collection << targetParent; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } else if ((targetParent.rights() & Collection::CanCreateCollection) == 0) { + const QString message = i18nc("@info:status", "Access control prohibits folder creation in folder %1", targetParent.name()); + qCritical() << message; + qCritical() << collection << targetParent; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } + + int errorCode = 0; + QString errorText; + checkCollectionCreate(job, errorCode, errorText); + if (errorCode != 0) { + d->mSession->setError(job, errorCode, errorText); + } + + return job; +} + +FileStore::CollectionDeleteJob *FileStore::AbstractLocalStore::deleteCollection(const Collection &collection) +{ + FileStore::CollectionDeleteJob *job = new FileStore::CollectionDeleteJob(collection, d->mSession); + + if (d->mTopLevelCollection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Configured storage location is empty"); + qCritical() << message; + qCritical() << collection; + d->mSession->setError(job, FileStore::Job::InvalidStoreState, message); + } else if (collection.remoteId().isEmpty() || + collection.parentCollection().remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Given folder name is empty"); + qCritical() << message; + qCritical() << collection; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } else if ((collection.rights() & Collection::CanDeleteCollection) == 0) { + const QString message = i18nc("@info:status", "Access control prohibits folder deletion in folder %1", collection.name()); + qCritical() << message; + qCritical() << collection; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } + + int errorCode = 0; + QString errorText; + checkCollectionDelete(job, errorCode, errorText); + if (errorCode != 0) { + d->mSession->setError(job, errorCode, errorText); + } + + return job; +} + +FileStore::CollectionFetchJob *FileStore::AbstractLocalStore::fetchCollections(const Collection &collection, FileStore::CollectionFetchJob::Type type) const +{ + FileStore::CollectionFetchJob *job = new FileStore::CollectionFetchJob(collection, type, d->mSession); + + if (d->mTopLevelCollection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Configured storage location is empty"); + qCritical() << message; + qCritical() << collection << "FetchType=" << type; + d->mSession->setError(job, FileStore::Job::InvalidStoreState, message); + } else if (collection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Given folder name is empty"); + qCritical() << message; + qCritical() << collection << "FetchType=" << type; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } + + int errorCode = 0; + QString errorText; + checkCollectionFetch(job, errorCode, errorText); + if (errorCode != 0) { + d->mSession->setError(job, errorCode, errorText); + } + + return job; +} + +FileStore::CollectionModifyJob *FileStore::AbstractLocalStore::modifyCollection(const Collection &collection) +{ + FileStore::CollectionModifyJob *job = new FileStore::CollectionModifyJob(collection, d->mSession); + + if (d->mTopLevelCollection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Configured storage location is empty"); + qCritical() << message; + qCritical() << collection; + d->mSession->setError(job, FileStore::Job::InvalidStoreState, message); + } else if (collection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Given folder name is empty"); + qCritical() << message; + qCritical() << collection; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } else if ((collection.rights() & Collection::CanChangeCollection) == 0) { + const QString message = i18nc("@info:status", "Access control prohibits folder modification in folder %1", collection.name()); + qCritical() << message; + qCritical() << collection; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } + + int errorCode = 0; + QString errorText; + checkCollectionModify(job, errorCode, errorText); + if (errorCode != 0) { + d->mSession->setError(job, errorCode, errorText); + } + + return job; +} + +FileStore::CollectionMoveJob *FileStore::AbstractLocalStore::moveCollection(const Collection &collection, const Collection &targetParent) +{ + FileStore::CollectionMoveJob *job = new FileStore::CollectionMoveJob(collection, targetParent, d->mSession); + + if (d->mTopLevelCollection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Configured storage location is empty"); + qCritical() << message; + qCritical() << collection << targetParent; + d->mSession->setError(job, FileStore::Job::InvalidStoreState, message); + } else if (collection.remoteId().isEmpty() || + collection.parentCollection().remoteId().isEmpty() || + targetParent.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Given folder name is empty"); + qCritical() << message; + qCritical() << collection << targetParent; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } else if ((targetParent.rights() & Collection::CanCreateCollection) == 0) { + const QString message = i18nc("@info:status", "Access control prohibits folder creation in folder %1", targetParent.name()); + qCritical() << message; + qCritical() << collection << targetParent; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } + + int errorCode = 0; + QString errorText; + checkCollectionMove(job, errorCode, errorText); + if (errorCode != 0) { + d->mSession->setError(job, errorCode, errorText); + } + + return job; +} + +FileStore::ItemFetchJob *FileStore::AbstractLocalStore::fetchItems(const Collection &collection) const +{ + FileStore::ItemFetchJob *job = new FileStore::ItemFetchJob(collection, d->mSession); + + if (d->mTopLevelCollection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Configured storage location is empty"); + qCritical() << message; + qCritical() << collection; + d->mSession->setError(job, FileStore::Job::InvalidStoreState, message); + } else if (collection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Given folder name is empty"); + qCritical() << message; + qCritical() << collection; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } + + int errorCode = 0; + QString errorText; + checkItemFetch(job, errorCode, errorText); + if (errorCode != 0) { + d->mSession->setError(job, errorCode, errorText); + } + + return job; +} + +FileStore::ItemFetchJob *FileStore::AbstractLocalStore::fetchItem(const Item &item) const +{ + FileStore::ItemFetchJob *job = new FileStore::ItemFetchJob(item, d->mSession); + + if (d->mTopLevelCollection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Configured storage location is empty"); + qCritical() << message; + qCritical() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ", parentCollection=" << item.parentCollection().remoteId() << ")"; + d->mSession->setError(job, FileStore::Job::InvalidStoreState, message); + } else if (item.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Given item identifier is empty"); + qCritical() << message; + qCritical() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ", parentCollection=" << item.parentCollection().remoteId() << ")"; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } + + int errorCode = 0; + QString errorText; + checkItemFetch(job, errorCode, errorText); + if (errorCode != 0) { + d->mSession->setError(job, errorCode, errorText); + } + + return job; +} + +FileStore::ItemCreateJob *FileStore::AbstractLocalStore::createItem(const Item &item, const Collection &collection) +{ + FileStore::ItemCreateJob *job = new FileStore::ItemCreateJob(item, collection, d->mSession); + + if (d->mTopLevelCollection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Configured storage location is empty"); + qCritical() << message; + qCritical() << collection + << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ")"; + d->mSession->setError(job, FileStore::Job::InvalidStoreState, message); + } else if (collection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Given folder name is empty"); + qCritical() << message; + qCritical() << collection + << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ")"; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } else if ((collection.rights() & Collection::CanCreateItem) == 0) { + const QString message = i18nc("@info:status", "Access control prohibits item creation in folder %1", collection.name()); + qCritical() << message; + qCritical() << collection + << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ")"; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } + + int errorCode = 0; + QString errorText; + checkItemCreate(job, errorCode, errorText); + if (errorCode != 0) { + d->mSession->setError(job, errorCode, errorText); + } + + return job; +} + +FileStore::ItemModifyJob *FileStore::AbstractLocalStore::modifyItem(const Item &item) +{ + FileStore::ItemModifyJob *job = new FileStore::ItemModifyJob(item, d->mSession); + + if (d->mTopLevelCollection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Configured storage location is empty"); + qCritical() << message; + qCritical() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ", parentCollection=" << item.parentCollection().remoteId() << ")"; + d->mSession->setError(job, FileStore::Job::InvalidStoreState, message); + } else if (item.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Given item identifier is empty"); + qCritical() << message; + qCritical() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ", parentCollection=" << item.parentCollection().remoteId() << ")"; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } else if ((item.parentCollection().rights() & Collection::CanChangeItem) == 0) { + const QString message = i18nc("@info:status", "Access control prohibits item modification in folder %1", item.parentCollection().name()); + qCritical() << message; + qCritical() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ", parentCollection=" << item.parentCollection().remoteId() << ")"; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } + + int errorCode = 0; + QString errorText; + checkItemModify(job, errorCode, errorText); + if (errorCode != 0) { + d->mSession->setError(job, errorCode, errorText); + } + + return job; +} + +FileStore::ItemDeleteJob *FileStore::AbstractLocalStore::deleteItem(const Item &item) +{ + FileStore::ItemDeleteJob *job = new FileStore::ItemDeleteJob(item, d->mSession); + + if (d->mTopLevelCollection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Configured storage location is empty"); + qCritical() << message; + qCritical() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ", parentCollection=" << item.parentCollection().remoteId() << ")"; + d->mSession->setError(job, FileStore::Job::InvalidStoreState, message); + } else if (item.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Given item identifier is empty"); + qCritical() << message; + qCritical() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ", parentCollection=" << item.parentCollection().remoteId() << ")"; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } else if ((item.parentCollection().rights() & Collection::CanDeleteItem) == 0) { + const QString message = i18nc("@info:status", "Access control prohibits item deletion in folder %1", item.parentCollection().name()); + qCritical() << message; + qCritical() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ", parentCollection=" << item.parentCollection().remoteId() << ")"; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } + + int errorCode = 0; + QString errorText; + checkItemDelete(job, errorCode, errorText); + if (errorCode != 0) { + d->mSession->setError(job, errorCode, errorText); + } + + return job; +} + +FileStore::ItemMoveJob *FileStore::AbstractLocalStore::moveItem(const Item &item, const Collection &targetParent) +{ + FileStore::ItemMoveJob *job = new FileStore::ItemMoveJob(item, targetParent, d->mSession); + + if (d->mTopLevelCollection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Configured storage location is empty"); + qCritical() << message; + qCritical() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ", parentCollection=" << item.parentCollection().remoteId() << ")" + << targetParent; + d->mSession->setError(job, FileStore::Job::InvalidStoreState, message); + } else if (item.parentCollection().remoteId().isEmpty() || + targetParent.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Given folder name is empty"); + qCritical() << message; + qCritical() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ", parentCollection=" << item.parentCollection().remoteId() << ")" + << targetParent; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } else if ((targetParent.rights() & Collection::CanCreateItem) == 0) { + const QString message = i18nc("@info:status", "Access control prohibits item creation in folder %1", targetParent.name()); + qCritical() << message; + qCritical() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ", parentCollection=" << item.parentCollection().remoteId() << ")" + << targetParent; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } else if ((item.parentCollection().rights() & Collection::CanDeleteItem) == 0) { + const QString message = i18nc("@info:status", "Access control prohibits item deletion in folder %1", item.parentCollection().name()); + qCritical() << message; + qCritical() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ", parentCollection=" << item.parentCollection().remoteId() << ")" + << targetParent; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } else if (item.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Given item identifier is empty"); + qCritical() << message; + qCritical() << "Item(remoteId=" << item.remoteId() << ", mimeType=" << item.mimeType() + << ", parentCollection=" << item.parentCollection().remoteId() << ")" + << targetParent; + d->mSession->setError(job, FileStore::Job::InvalidJobContext, message); + } + + int errorCode = 0; + QString errorText; + checkItemMove(job, errorCode, errorText); + if (errorCode != 0) { + d->mSession->setError(job, errorCode, errorText); + } - return job; + return job; } FileStore::StoreCompactJob *FileStore::AbstractLocalStore::compactStore() { - FileStore::StoreCompactJob *job = new FileStore::StoreCompactJob( d->mSession ); + FileStore::StoreCompactJob *job = new FileStore::StoreCompactJob(d->mSession); - if ( d->mTopLevelCollection.remoteId().isEmpty() ) { - const QString message = i18nc( "@info:status", "Configured storage location is empty" ); - kError() << message; - d->mSession->setError( job, FileStore::Job::InvalidStoreState, message ); - } - - int errorCode = 0; - QString errorText; - checkStoreCompact( job, errorCode, errorText ); - if ( errorCode != 0 ) { - d->mSession->setError( job, errorCode, errorText ); - } + if (d->mTopLevelCollection.remoteId().isEmpty()) { + const QString message = i18nc("@info:status", "Configured storage location is empty"); + qCritical() << message; + d->mSession->setError(job, FileStore::Job::InvalidStoreState, message); + } + + int errorCode = 0; + QString errorText; + checkStoreCompact(job, errorCode, errorText); + if (errorCode != 0) { + d->mSession->setError(job, errorCode, errorText); + } - return job; + return job; } FileStore::Job *FileStore::AbstractLocalStore::currentJob() const { - return d->mCurrentJob; + return d->mCurrentJob; } -void FileStore::AbstractLocalStore::notifyError( int errorCode, const QString &errorText ) const +void FileStore::AbstractLocalStore::notifyError(int errorCode, const QString &errorText) const { - Q_ASSERT( d->mCurrentJob != 0); + Q_ASSERT(d->mCurrentJob != 0); - d->mSession->setError( d->mCurrentJob, errorCode, errorText ); + d->mSession->setError(d->mCurrentJob, errorCode, errorText); } -void FileStore::AbstractLocalStore::notifyCollectionsProcessed( const Collection::List &collections ) const +void FileStore::AbstractLocalStore::notifyCollectionsProcessed(const Collection::List &collections) const { - Q_ASSERT( d->mCurrentJob != 0); + Q_ASSERT(d->mCurrentJob != 0); - d->mCollectionsProcessedNotifier.setCollections( collections ); - d->mCurrentJob->accept( &( d->mCollectionsProcessedNotifier ) ); + d->mCollectionsProcessedNotifier.setCollections(collections); + d->mCurrentJob->accept(&(d->mCollectionsProcessedNotifier)); } -void FileStore::AbstractLocalStore::notifyItemsProcessed( const Item::List &items ) const +void FileStore::AbstractLocalStore::notifyItemsProcessed(const Item::List &items) const { - Q_ASSERT( d->mCurrentJob != 0); + Q_ASSERT(d->mCurrentJob != 0); - d->mItemsProcessedNotifier.setItems( items ); - d->mCurrentJob->accept( &( d->mItemsProcessedNotifier ) ); - d->mItemsProcessedNotifier.clearItems(); // save memory + d->mItemsProcessedNotifier.setItems(items); + d->mCurrentJob->accept(&(d->mItemsProcessedNotifier)); + d->mItemsProcessedNotifier.clearItems(); // save memory } -void FileStore::AbstractLocalStore::setTopLevelCollection( const Collection &collection ) +void FileStore::AbstractLocalStore::setTopLevelCollection(const Collection &collection) { - d->mTopLevelCollection = collection; - d->mTopLevelCollectionFetcher.setTopLevelCollection( collection ); + d->mTopLevelCollection = collection; + d->mTopLevelCollectionFetcher.setTopLevelCollection(collection); } -void FileStore::AbstractLocalStore::checkCollectionCreate( FileStore::CollectionCreateJob *job, int &errorCode, QString &errorText ) const +void FileStore::AbstractLocalStore::checkCollectionCreate(FileStore::CollectionCreateJob *job, int &errorCode, QString &errorText) const { - Q_UNUSED( job ); - Q_UNUSED( errorCode ); - Q_UNUSED( errorText ); + Q_UNUSED(job); + Q_UNUSED(errorCode); + Q_UNUSED(errorText); } -void FileStore::AbstractLocalStore::checkCollectionDelete( FileStore::CollectionDeleteJob *job, int &errorCode, QString &errorText ) const +void FileStore::AbstractLocalStore::checkCollectionDelete(FileStore::CollectionDeleteJob *job, int &errorCode, QString &errorText) const { - Q_UNUSED( job ); - Q_UNUSED( errorCode ); - Q_UNUSED( errorText ); + Q_UNUSED(job); + Q_UNUSED(errorCode); + Q_UNUSED(errorText); } -void FileStore::AbstractLocalStore::checkCollectionFetch( FileStore::CollectionFetchJob *job, int &errorCode, QString &errorText ) const +void FileStore::AbstractLocalStore::checkCollectionFetch(FileStore::CollectionFetchJob *job, int &errorCode, QString &errorText) const { - Q_UNUSED( job ); - Q_UNUSED( errorCode ); - Q_UNUSED( errorText ); + Q_UNUSED(job); + Q_UNUSED(errorCode); + Q_UNUSED(errorText); } -void FileStore::AbstractLocalStore::checkCollectionModify( FileStore::CollectionModifyJob *job, int &errorCode, QString &errorText ) const +void FileStore::AbstractLocalStore::checkCollectionModify(FileStore::CollectionModifyJob *job, int &errorCode, QString &errorText) const { - Q_UNUSED( job ); - Q_UNUSED( errorCode ); - Q_UNUSED( errorText ); + Q_UNUSED(job); + Q_UNUSED(errorCode); + Q_UNUSED(errorText); } -void FileStore::AbstractLocalStore::checkCollectionMove( FileStore::CollectionMoveJob *job, int &errorCode, QString &errorText ) const +void FileStore::AbstractLocalStore::checkCollectionMove(FileStore::CollectionMoveJob *job, int &errorCode, QString &errorText) const { - Q_UNUSED( job ); - Q_UNUSED( errorCode ); - Q_UNUSED( errorText ); + Q_UNUSED(job); + Q_UNUSED(errorCode); + Q_UNUSED(errorText); } -void FileStore::AbstractLocalStore::checkItemCreate( FileStore::ItemCreateJob *job, int &errorCode, QString &errorText ) const +void FileStore::AbstractLocalStore::checkItemCreate(FileStore::ItemCreateJob *job, int &errorCode, QString &errorText) const { - Q_UNUSED( job ); - Q_UNUSED( errorCode ); - Q_UNUSED( errorText ); + Q_UNUSED(job); + Q_UNUSED(errorCode); + Q_UNUSED(errorText); } -void FileStore::AbstractLocalStore::checkItemDelete( FileStore::ItemDeleteJob *job, int &errorCode, QString &errorText ) const +void FileStore::AbstractLocalStore::checkItemDelete(FileStore::ItemDeleteJob *job, int &errorCode, QString &errorText) const { - Q_UNUSED( job ); - Q_UNUSED( errorCode ); - Q_UNUSED( errorText ); + Q_UNUSED(job); + Q_UNUSED(errorCode); + Q_UNUSED(errorText); } -void FileStore::AbstractLocalStore::checkItemFetch( FileStore::ItemFetchJob *job, int &errorCode, QString &errorText ) const +void FileStore::AbstractLocalStore::checkItemFetch(FileStore::ItemFetchJob *job, int &errorCode, QString &errorText) const { - Q_UNUSED( job ); - Q_UNUSED( errorCode ); - Q_UNUSED( errorText ); + Q_UNUSED(job); + Q_UNUSED(errorCode); + Q_UNUSED(errorText); } -void FileStore::AbstractLocalStore::checkItemModify( FileStore::ItemModifyJob *job, int &errorCode, QString &errorText ) const +void FileStore::AbstractLocalStore::checkItemModify(FileStore::ItemModifyJob *job, int &errorCode, QString &errorText) const { - Q_UNUSED( job ); - Q_UNUSED( errorCode ); - Q_UNUSED( errorText ); + Q_UNUSED(job); + Q_UNUSED(errorCode); + Q_UNUSED(errorText); } -void FileStore::AbstractLocalStore::checkItemMove( FileStore::ItemMoveJob *job, int &errorCode, QString &errorText ) const +void FileStore::AbstractLocalStore::checkItemMove(FileStore::ItemMoveJob *job, int &errorCode, QString &errorText) const { - Q_UNUSED( job ); - Q_UNUSED( errorCode ); - Q_UNUSED( errorText ); + Q_UNUSED(job); + Q_UNUSED(errorCode); + Q_UNUSED(errorText); } -void FileStore::AbstractLocalStore::checkStoreCompact( FileStore::StoreCompactJob *job, int &errorCode, QString &errorText ) const +void FileStore::AbstractLocalStore::checkStoreCompact(FileStore::StoreCompactJob *job, int &errorCode, QString &errorText) const { - Q_UNUSED( job ); - Q_UNUSED( errorCode ); - Q_UNUSED( errorText ); + Q_UNUSED(job); + Q_UNUSED(errorCode); + Q_UNUSED(errorText); } #include "moc_abstractlocalstore.cpp" -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/abstractlocalstore.h kdepim-runtime-15.08.0/resources/shared/filestore/abstractlocalstore.h --- kdepim-runtime-4.14.6/resources/shared/filestore/abstractlocalstore.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/abstractlocalstore.h 2015-08-10 21:01:02.000000000 +0000 @@ -23,8 +23,8 @@ #include "storeinterface.h" -#include -#include +#include +#include #include @@ -40,82 +40,82 @@ */ class AKONADI_FILESTORE_EXPORT AbstractLocalStore : public QObject, public StoreInterface { - Q_OBJECT + Q_OBJECT - public: +public: AbstractLocalStore(); ~AbstractLocalStore(); - virtual void setPath( const QString &path ); + virtual void setPath(const QString &path); QString path() const; Collection topLevelCollection() const; - CollectionCreateJob *createCollection( const Collection &collection, const Collection &targetParent ); + CollectionCreateJob *createCollection(const Collection &collection, const Collection &targetParent); - CollectionFetchJob *fetchCollections( const Collection &collection, CollectionFetchJob::Type type = CollectionFetchJob::FirstLevel ) const; + CollectionFetchJob *fetchCollections(const Collection &collection, CollectionFetchJob::Type type = CollectionFetchJob::FirstLevel) const; - CollectionDeleteJob *deleteCollection( const Collection &collection ); + CollectionDeleteJob *deleteCollection(const Collection &collection); - CollectionModifyJob *modifyCollection( const Collection &collection ); + CollectionModifyJob *modifyCollection(const Collection &collection); - CollectionMoveJob *moveCollection( const Collection &collection, const Collection &targetParent ); + CollectionMoveJob *moveCollection(const Collection &collection, const Collection &targetParent); - ItemFetchJob *fetchItems( const Collection &collection ) const; + ItemFetchJob *fetchItems(const Collection &collection) const; - ItemFetchJob *fetchItem( const Item &item ) const; + ItemFetchJob *fetchItem(const Item &item) const; - ItemCreateJob *createItem( const Item &item, const Collection &collection ); + ItemCreateJob *createItem(const Item &item, const Collection &collection); - ItemModifyJob *modifyItem( const Item &item ); + ItemModifyJob *modifyItem(const Item &item); - ItemDeleteJob *deleteItem( const Item &item ); + ItemDeleteJob *deleteItem(const Item &item); - ItemMoveJob *moveItem( const Item &item, const Collection &targetParent ); + ItemMoveJob *moveItem(const Item &item, const Collection &targetParent); StoreCompactJob *compactStore(); - protected: // job processing - virtual void processJob( Job *job ) = 0; +protected: // job processing + virtual void processJob(Job *job) = 0; Job *currentJob() const; - void notifyError( int errorCode, const QString &errorText ) const; + void notifyError(int errorCode, const QString &errorText) const; - void notifyCollectionsProcessed( const Collection::List &collections ) const; + void notifyCollectionsProcessed(const Collection::List &collections) const; - void notifyItemsProcessed( const Item::List &items ) const; + void notifyItemsProcessed(const Item::List &items) const; - protected: // template methods - void setTopLevelCollection( const Collection &collection ); +protected: // template methods + void setTopLevelCollection(const Collection &collection); - virtual void checkCollectionCreate( CollectionCreateJob *job, int &errorCode, QString &errorText ) const; + virtual void checkCollectionCreate(CollectionCreateJob *job, int &errorCode, QString &errorText) const; - virtual void checkCollectionDelete( CollectionDeleteJob *job, int &errorCode, QString &errorText ) const; + virtual void checkCollectionDelete(CollectionDeleteJob *job, int &errorCode, QString &errorText) const; - virtual void checkCollectionFetch( CollectionFetchJob *job, int &errorCode, QString &errorText ) const; + virtual void checkCollectionFetch(CollectionFetchJob *job, int &errorCode, QString &errorText) const; - virtual void checkCollectionModify( CollectionModifyJob *job, int &errorCode, QString &errorText ) const; + virtual void checkCollectionModify(CollectionModifyJob *job, int &errorCode, QString &errorText) const; - virtual void checkCollectionMove( CollectionMoveJob *job, int &errorCode, QString &errorText ) const; + virtual void checkCollectionMove(CollectionMoveJob *job, int &errorCode, QString &errorText) const; - virtual void checkItemCreate( ItemCreateJob *job, int &errorCode, QString &errorText ) const; + virtual void checkItemCreate(ItemCreateJob *job, int &errorCode, QString &errorText) const; - virtual void checkItemDelete( ItemDeleteJob *job, int &errorCode, QString &errorText ) const; + virtual void checkItemDelete(ItemDeleteJob *job, int &errorCode, QString &errorText) const; - virtual void checkItemFetch( ItemFetchJob *job, int &errorCode, QString &errorText ) const; + virtual void checkItemFetch(ItemFetchJob *job, int &errorCode, QString &errorText) const; - virtual void checkItemModify( ItemModifyJob *job, int &errorCode, QString &errorText ) const; + virtual void checkItemModify(ItemModifyJob *job, int &errorCode, QString &errorText) const; - virtual void checkItemMove( ItemMoveJob *job, int &errorCode, QString &errorText ) const; + virtual void checkItemMove(ItemMoveJob *job, int &errorCode, QString &errorText) const; - virtual void checkStoreCompact( StoreCompactJob *job, int &errorCode, QString &errorText ) const; + virtual void checkStoreCompact(StoreCompactJob *job, int &errorCode, QString &errorText) const; - private: +private: class Private; Private *const d; - Q_PRIVATE_SLOT( d, void processJobs( const QList &jobs ) ) + Q_PRIVATE_SLOT(d, void processJobs(const QList &jobs)) }; } @@ -123,4 +123,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/akonadi-filestore_export.h kdepim-runtime-15.08.0/resources/shared/filestore/akonadi-filestore_export.h --- kdepim-runtime-4.14.6/resources/shared/filestore/akonadi-filestore_export.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/akonadi-filestore_export.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2009 Kevin Krammer - - 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_FILESTORE_EXPORT_H -#define AKONADI_FILESTORE_EXPORT_H - -/* needed for KDE_EXPORT and KDE_IMPORT macros */ -#include - -#ifndef AKONADI_FILESTORE_EXPORT -# if defined(KDEPIM_STATIC_LIBS) - /* No export/import for static libraries */ -# define AKONADI_FILESTORE_EXPORT -# elif defined(MAKE_AKONADI_FILESTORE_LIB) - /* We are building this library */ -# define AKONADI_FILESTORE_EXPORT KDE_EXPORT -# else - /* We are using this library */ -# define AKONADI_FILESTORE_EXPORT KDE_IMPORT -# endif -#endif - -#endif - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/autotests/abstractlocalstoretest.cpp kdepim-runtime-15.08.0/resources/shared/filestore/autotests/abstractlocalstoretest.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/autotests/abstractlocalstoretest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/autotests/abstractlocalstoretest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,971 @@ +/* This file is part of the KDE project + Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net + Author: Kevin Krammer, krake@kdab.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 "abstractlocalstore.h" + +#include "collectioncreatejob.h" +#include "collectiondeletejob.h" +#include "collectionfetchjob.h" +#include "collectionmodifyjob.h" +#include "collectionmovejob.h" +#include "itemcreatejob.h" +#include "itemdeletejob.h" +#include "itemfetchjob.h" +#include "itemmodifyjob.h" +#include "itemmovejob.h" +#include "sessionimpls_p.h" +#include "storecompactjob.h" + +#include + +#include + +using namespace Akonadi; +using namespace Akonadi::FileStore; + +class TestStore : public AbstractLocalStore +{ + Q_OBJECT + +public: + TestStore() : mLastCheckedJob(0), mLastProcessedJob(0), mErrorCode(0) {} + +public: + mutable Akonadi::FileStore::Job *mLastCheckedJob; + Akonadi::FileStore::Job *mLastProcessedJob; + + Collection mTopLevelCollection; + + int mErrorCode; + QString mErrorText; + +protected: + void processJob(Akonadi::FileStore::Job *job); + +protected: + void setTopLevelCollection(const Collection &collection) + { + mTopLevelCollection = collection; + + Collection modifiedCollection = collection; + modifiedCollection.setContentMimeTypes(QStringList() << Collection::mimeType()); + + AbstractLocalStore::setTopLevelCollection(modifiedCollection); + } + + void checkCollectionCreate(Akonadi::FileStore::CollectionCreateJob *job, int &errorCode, QString &errorText) const + { + mLastCheckedJob = job; + errorCode = mErrorCode; + errorText = mErrorText; + } + + void checkCollectionDelete(Akonadi::FileStore::CollectionDeleteJob *job, int &errorCode, QString &errorText) const + { + mLastCheckedJob = job; + errorCode = mErrorCode; + errorText = mErrorText; + } + + void checkCollectionFetch(Akonadi::FileStore::CollectionFetchJob *job, int &errorCode, QString &errorText) const + { + mLastCheckedJob = job; + errorCode = mErrorCode; + errorText = mErrorText; + } + + void checkCollectionModify(Akonadi::FileStore::CollectionModifyJob *job, int &errorCode, QString &errorText) const + { + mLastCheckedJob = job; + errorCode = mErrorCode; + errorText = mErrorText; + } + + void checkCollectionMove(Akonadi::FileStore::CollectionMoveJob *job, int &errorCode, QString &errorText) const + { + mLastCheckedJob = job; + errorCode = mErrorCode; + errorText = mErrorText; + } + + void checkItemCreate(Akonadi::FileStore::ItemCreateJob *job, int &errorCode, QString &errorText) const + { + mLastCheckedJob = job; + errorCode = mErrorCode; + errorText = mErrorText; + } + + void checkItemDelete(Akonadi::FileStore::ItemDeleteJob *job, int &errorCode, QString &errorText) const + { + mLastCheckedJob = job; + errorCode = mErrorCode; + errorText = mErrorText; + } + + void checkItemFetch(Akonadi::FileStore::ItemFetchJob *job, int &errorCode, QString &errorText) const + { + mLastCheckedJob = job; + errorCode = mErrorCode; + errorText = mErrorText; + } + + void checkItemModify(Akonadi::FileStore::ItemModifyJob *job, int &errorCode, QString &errorText) const + { + mLastCheckedJob = job; + errorCode = mErrorCode; + errorText = mErrorText; + } + + void checkItemMove(Akonadi::FileStore::ItemMoveJob *job, int &errorCode, QString &errorText) const + { + mLastCheckedJob = job; + errorCode = mErrorCode; + errorText = mErrorText; + } + + void checkStoreCompact(Akonadi::FileStore::StoreCompactJob *job, int &errorCode, QString &errorText) const + { + mLastCheckedJob = job; + errorCode = mErrorCode; + errorText = mErrorText; + } +}; + +void TestStore::processJob(Akonadi::FileStore::Job *job) +{ + mLastProcessedJob = job; + + QCOMPARE(currentJob(), job); + QVERIFY(job->error() == 0); + + if (mErrorCode != 0) { + notifyError(mErrorCode, mErrorText); + } +} + +class AbstractLocalStoreTest : public QObject +{ + Q_OBJECT + +public: + AbstractLocalStoreTest() : QObject(), mStore(0) {} + ~AbstractLocalStoreTest() + { + delete mStore; + } + +private: + TestStore *mStore; + +private Q_SLOTS: + void init(); + void testSetPath(); + void testCreateCollection(); + void testDeleteCollection(); + void testFetchCollection(); + void testModifyCollection(); + void testMoveCollection(); + void testFetchItems(); + void testFetchItem(); + void testCreateItem(); + void testDeleteItem(); + void testModifyItem(); + void testMoveItem(); + void testCompactStore(); +}; + +void AbstractLocalStoreTest::init() +{ + delete mStore; + mStore = new TestStore; +} + +void AbstractLocalStoreTest::testSetPath() +{ + const QString file = KRandom::randomString(10); + const QString path = QLatin1String("/tmp/test/") + file; + + // check that setTopLevelCollection() has been called + mStore->setPath(path); + QCOMPARE(mStore->mTopLevelCollection.remoteId(), path); + + // check that the modified collection is the one returned by topLevelCollection() + QVERIFY(mStore->mTopLevelCollection.contentMimeTypes().isEmpty()); + QCOMPARE(mStore->topLevelCollection().remoteId(), path); + QCOMPARE(mStore->topLevelCollection().contentMimeTypes(), QStringList() << Collection::mimeType()); + QCOMPARE(mStore->topLevelCollection().name(), file); + + // check that calling with the same path again, does not call the template method + mStore->mTopLevelCollection = Collection(); + mStore->setPath(path); + QVERIFY(mStore->mTopLevelCollection.remoteId().isEmpty()); + QCOMPARE(mStore->topLevelCollection().remoteId(), path); + QCOMPARE(mStore->topLevelCollection().contentMimeTypes(), QStringList() << Collection::mimeType()); + QCOMPARE(mStore->topLevelCollection().name(), file); + + // check that calling with a different path works like the first call + const QString file2 = KRandom::randomString(10); + const QString path2 = QLatin1String("/tmp/test2/") + file2; + + mStore->setPath(path2); + QCOMPARE(mStore->mTopLevelCollection.remoteId(), path2); + QCOMPARE(mStore->topLevelCollection().remoteId(), path2); + QCOMPARE(mStore->topLevelCollection().contentMimeTypes(), QStringList() << Collection::mimeType()); + QCOMPARE(mStore->topLevelCollection().name(), file2); +} + +void AbstractLocalStoreTest::testCreateCollection() +{ + CollectionCreateJob *job = 0; + + // test without setPath() + job = mStore->createCollection(Collection(), Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with path but with invalid collections + mStore->setPath(QLatin1String("/tmp/test")); + job = mStore->createCollection(Collection(), Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with potentially valid collection (has remoteId), but invalid target parent + Collection collection; + collection.setRemoteId(QLatin1String("/tmp/test/foo")); + job = mStore->createCollection(collection, Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with potentially valid collections + Collection targetParent; + targetParent.setRemoteId(QLatin1String("/tmp/test2")); + job = mStore->createCollection(collection, targetParent); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + + QVERIFY(job->exec()); + QCOMPARE(mStore->mLastProcessedJob, job); + mStore->mLastProcessedJob = 0; + + // test template check method + mStore->mErrorCode = KRandom::random() + 1; + mStore->mErrorText = KRandom::randomString(10); + + job = mStore->createCollection(collection, targetParent); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), mStore->mErrorCode); + QCOMPARE(job->errorText(), mStore->mErrorText); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + mStore->mErrorCode = 0; + mStore->mErrorText = QString(); +} + +void AbstractLocalStoreTest::testDeleteCollection() +{ + CollectionDeleteJob *job = 0; + + // test without setPath() + job = mStore->deleteCollection(Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with path but with invalid collection + mStore->setPath(QLatin1String("/tmp/test")); + job = mStore->deleteCollection(Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with ivalid collection (has remoteId, but no parent collection remoteId) + Collection collection; + collection.setRemoteId(QLatin1String("/tmp/test/foo")); + job = mStore->deleteCollection(collection); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with potentially valid collection (has remoteId and parent collection remoteId) + Collection parentCollection; + parentCollection.setRemoteId(QLatin1String("/tmp/test")); + collection.setParentCollection(parentCollection); + job = mStore->deleteCollection(collection); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + + QVERIFY(job->exec()); + QCOMPARE(mStore->mLastProcessedJob, job); + mStore->mLastProcessedJob = 0; + + // test template check method + mStore->mErrorCode = KRandom::random() + 1; + mStore->mErrorText = KRandom::randomString(10); + + job = mStore->deleteCollection(collection); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), mStore->mErrorCode); + QCOMPARE(job->errorText(), mStore->mErrorText); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + mStore->mErrorCode = 0; + mStore->mErrorText = QString(); +} + +void AbstractLocalStoreTest::testFetchCollection() +{ + Akonadi::FileStore::CollectionFetchJob *job = 0; + + // test without setPath() + job = mStore->fetchCollections(Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with path but with invalid collection + mStore->setPath(QLatin1String("/tmp/test")); + job = mStore->fetchCollections(Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with potentially valid collection (has remoteId) + Collection collection; + collection.setRemoteId(QLatin1String("/tmp/test/foo")); + job = mStore->fetchCollections(collection); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + + QVERIFY(job->exec()); + QCOMPARE(mStore->mLastProcessedJob, job); + mStore->mLastProcessedJob = 0; + + // test template check method + mStore->mErrorCode = KRandom::random() + 1; + mStore->mErrorText = KRandom::randomString(10); + + job = mStore->fetchCollections(collection); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), mStore->mErrorCode); + QCOMPARE(job->errorText(), mStore->mErrorText); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + mStore->mErrorCode = 0; + mStore->mErrorText = QString(); + + // test fetch of top level collection only + collection.setRemoteId(mStore->topLevelCollection().remoteId()); + job = mStore->fetchCollections(collection, Akonadi::FileStore::CollectionFetchJob::Base); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + + QVERIFY(job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); // job not handed to subclass because it is full processed in base class + QCOMPARE(job->collections().count(), 1); + QCOMPARE(job->collections()[ 0 ], mStore->topLevelCollection()); +} + +void AbstractLocalStoreTest::testModifyCollection() +{ + Akonadi::FileStore::CollectionModifyJob *job = 0; + + // test without setPath() + job = mStore->modifyCollection(Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with path but with invalid item + mStore->setPath(QLatin1String("/tmp/test")); + job = mStore->modifyCollection(Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with potentially valid collection (has remoteId, but no parent remoteId) + Collection collection; + collection.setRemoteId(QLatin1String("/tmp/test/foo")); + job = mStore->modifyCollection(collection); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + + QVERIFY(job->exec()); + QCOMPARE(mStore->mLastProcessedJob, job); + mStore->mLastProcessedJob = 0; + + // test with potentially valid collection (has remoteId and parent remoteId) + Collection parentCollection; + parentCollection.setRemoteId(QLatin1String("/tmp/test")); + collection.setParentCollection(parentCollection); + job = mStore->modifyCollection(collection); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + + QVERIFY(job->exec()); + QCOMPARE(mStore->mLastProcessedJob, job); + mStore->mLastProcessedJob = 0; + + // test template check method + mStore->mErrorCode = KRandom::random() + 1; + mStore->mErrorText = KRandom::randomString(10); + + job = mStore->modifyCollection(collection); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), mStore->mErrorCode); + QCOMPARE(job->errorText(), mStore->mErrorText); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); +} + +void AbstractLocalStoreTest::testMoveCollection() +{ + CollectionMoveJob *job = 0; + + // test without setPath() + job = mStore->moveCollection(Collection(), Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with path but with invalid collections + mStore->setPath(QLatin1String("/tmp/test")); + job = mStore->moveCollection(Collection(), Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with potentially valid collection (has remoteId and parent remoteId), but invalid target parent + Collection collection; + collection.setRemoteId(QLatin1String("/tmp/test/foo")); + Collection parentCollection; + parentCollection.setRemoteId(QLatin1String("/tmp/test")); + collection.setParentCollection(parentCollection); + job = mStore->moveCollection(collection, Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with invalid parent collection, but with potentially valid collection and target parent + collection.setParentCollection(Collection()); + job = mStore->moveCollection(collection, parentCollection); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with potentially valid collections + Collection targetParent; + targetParent.setRemoteId(QLatin1String("/tmp/test2")); + collection.setParentCollection(parentCollection); + job = mStore->moveCollection(collection, targetParent); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + + QVERIFY(job->exec()); + QCOMPARE(mStore->mLastProcessedJob, job); + mStore->mLastProcessedJob = 0; + + // test template check method + mStore->mErrorCode = KRandom::random() + 1; + mStore->mErrorText = KRandom::randomString(10); + + job = mStore->moveCollection(collection, targetParent); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), mStore->mErrorCode); + QCOMPARE(job->errorText(), mStore->mErrorText); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); +} + +void AbstractLocalStoreTest::testFetchItems() +{ + ItemFetchJob *job = 0; + + // test without setPath() + job = mStore->fetchItems(Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with path but with invalid collection + mStore->setPath(QLatin1String("/tmp/test")); + job = mStore->fetchItems(Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with potentially valid collection (has remoteId) + Collection collection; + collection.setRemoteId(QLatin1String("/tmp/test/foo")); + job = mStore->fetchItems(collection); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + + QVERIFY(job->exec()); + QCOMPARE(mStore->mLastProcessedJob, job); + mStore->mLastProcessedJob = 0; + + // test template check method + mStore->mErrorCode = KRandom::random() + 1; + mStore->mErrorText = KRandom::randomString(10); + + job = mStore->fetchItems(collection); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), mStore->mErrorCode); + QCOMPARE(job->errorText(), mStore->mErrorText); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + mStore->mErrorCode = 0; + mStore->mErrorText = QString(); +} + +void AbstractLocalStoreTest::testFetchItem() +{ + ItemFetchJob *job = 0; + + // test without setPath() + job = mStore->fetchItem(Item()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with path but with invalid item + mStore->setPath(QLatin1String("/tmp/test")); + job = mStore->fetchItem(Item()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with potentially valid item (has remoteId) + Item item; + item.setRemoteId(QLatin1String("/tmp/test/foo")); + job = mStore->fetchItem(item); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + + QVERIFY(job->exec()); + QCOMPARE(mStore->mLastProcessedJob, job); + mStore->mLastProcessedJob = 0; + + // test template check method + mStore->mErrorCode = KRandom::random() + 1; + mStore->mErrorText = KRandom::randomString(10); + + job = mStore->fetchItem(item); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), mStore->mErrorCode); + QCOMPARE(job->errorText(), mStore->mErrorText); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + mStore->mErrorCode = 0; + mStore->mErrorText = QString(); +} + +void AbstractLocalStoreTest::testCreateItem() +{ + Akonadi::FileStore::ItemCreateJob *job = 0; + + // test without setPath() + job = mStore->createItem(Item(), Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with path but with invalid collection + mStore->setPath(QLatin1String("/tmp/test")); + job = mStore->createItem(Item(), Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with potentially valid collection (has remoteId) + Collection collection; + collection.setRemoteId(QLatin1String("/tmp/test/foo")); + job = mStore->createItem(Item(), collection); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + + QVERIFY(job->exec()); + QCOMPARE(mStore->mLastProcessedJob, job); + mStore->mLastProcessedJob = 0; + + // test template check method + mStore->mErrorCode = KRandom::random() + 1; + mStore->mErrorText = KRandom::randomString(10); + + job = mStore->createItem(Item(), collection); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), mStore->mErrorCode); + QCOMPARE(job->errorText(), mStore->mErrorText); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + mStore->mErrorCode = 0; + mStore->mErrorText = QString(); +} + +void AbstractLocalStoreTest::testDeleteItem() +{ + ItemDeleteJob *job = 0; + + // test without setPath() + job = mStore->deleteItem(Item()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with path but with invalid item + mStore->setPath(QLatin1String("/tmp/test")); + job = mStore->deleteItem(Item()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with potentially valid item (has remoteId) + Item item; + item.setRemoteId(QLatin1String("/tmp/test/foo")); + job = mStore->deleteItem(item); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + + QVERIFY(job->exec()); + QCOMPARE(mStore->mLastProcessedJob, job); + mStore->mLastProcessedJob = 0; + + // test template check method + mStore->mErrorCode = KRandom::random() + 1; + mStore->mErrorText = KRandom::randomString(10); + + job = mStore->deleteItem(item); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), mStore->mErrorCode); + QCOMPARE(job->errorText(), mStore->mErrorText); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + mStore->mErrorCode = 0; + mStore->mErrorText = QString(); +} + +void AbstractLocalStoreTest::testModifyItem() +{ + Akonadi::FileStore::ItemModifyJob *job = 0; + + // test without setPath() + job = mStore->modifyItem(Item()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with path but with invalid item + mStore->setPath(QLatin1String("/tmp/test")); + job = mStore->modifyItem(Item()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with potentially valid item (has remoteId) + Item item; + item.setRemoteId(QLatin1String("/tmp/test/foo")); + job = mStore->modifyItem(item); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + + QVERIFY(job->exec()); + QCOMPARE(mStore->mLastProcessedJob, job); + mStore->mLastProcessedJob = 0; + + // test template check method + mStore->mErrorCode = KRandom::random() + 1; + mStore->mErrorText = KRandom::randomString(10); + + job = mStore->modifyItem(item); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), mStore->mErrorCode); + QCOMPARE(job->errorText(), mStore->mErrorText); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); +} + +void AbstractLocalStoreTest::testMoveItem() +{ + ItemMoveJob *job = 0; + + // test without setPath() + job = mStore->moveItem(Item(), Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with path but with invalid item and collection + mStore->setPath(QLatin1String("/tmp/test")); + job = mStore->moveItem(Item(), Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with potentially valid item (has remoteId and parent remoteId), but invalid target parent + Item item; + item.setRemoteId(QLatin1String("/tmp/test/foo")); + Collection parentCollection; + parentCollection.setRemoteId(QLatin1String("/tmp/test")); + item.setParentCollection(parentCollection); + job = mStore->moveItem(item, Collection()); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with invalid parent collection, but with potentially valid item and target parent + item.setParentCollection(Collection()); + job = mStore->moveItem(item, parentCollection); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with potentially valid item and collections + Collection targetParent; + targetParent.setRemoteId(QLatin1String("/tmp/test2")); + item.setParentCollection(parentCollection); + job = mStore->moveItem(item, targetParent); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + + QVERIFY(job->exec()); + QCOMPARE(mStore->mLastProcessedJob, job); + mStore->mLastProcessedJob = 0; + + // test template check method + mStore->mErrorCode = KRandom::random() + 1; + mStore->mErrorText = KRandom::randomString(10); + + job = mStore->moveItem(item, targetParent); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), mStore->mErrorCode); + QCOMPARE(job->errorText(), mStore->mErrorText); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); +} + +void AbstractLocalStoreTest::testCompactStore() +{ + StoreCompactJob *job = 0; + + // test without setPath() + job = mStore->compactStore(); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState); + QVERIFY(!job->errorText().isEmpty()); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + + // test with path + mStore->setPath(QLatin1String("/tmp/test")); + job = mStore->compactStore(); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), 0); + QVERIFY(job->errorText().isEmpty()); + + QVERIFY(job->exec()); + QCOMPARE(mStore->mLastProcessedJob, job); + mStore->mLastProcessedJob = 0; + + // test template check method + mStore->mErrorCode = KRandom::random() + 1; + mStore->mErrorText = KRandom::randomString(10); + + job = mStore->compactStore(); + QVERIFY(job != 0); + QCOMPARE(mStore->mLastCheckedJob, job); + QCOMPARE(job->error(), mStore->mErrorCode); + QCOMPARE(job->errorText(), mStore->mErrorText); + + QVERIFY(!job->exec()); + QVERIFY(mStore->mLastProcessedJob == 0); + mStore->mErrorCode = 0; + mStore->mErrorText = QString(); +} + +QTEST_MAIN(AbstractLocalStoreTest) + +#include "abstractlocalstoretest.moc" + diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/autotests/CMakeLists.txt kdepim-runtime-15.08.0/resources/shared/filestore/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/shared/filestore/autotests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/autotests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,31 @@ +include(ECMAddTests) + +find_package(Qt5Test CONFIG REQUIRED) + +if(${EXECUTABLE_OUTPUT_PATH}) + set( PREVIOUS_EXEC_OUTPUT_PATH ${EXECUTABLE_OUTPUT_PATH} ) +else() + set( PREVIOUS_EXEC_OUTPUT_PATH . ) +endif() +set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) + + + +include_directories( + ${AKONADI_INCLUDE_DIR} + ${Boost_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../ + ${CMAKE_CURRENT_BINARY_DIR}/../ + ${CMAKE_CURRENT_SOURCE_DIR} +) + +add_executable(abstractlocalstoretest abstractlocalstoretest.cpp) +add_test(abstractlocalstoretest abstractlocalstoretest) +ecm_mark_as_test(abstractlocalstoretest) + +target_link_libraries( + abstractlocalstoretest + akonadi-filestore + KF5::AkonadiCore + Qt5::Test +) diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/CMakeLists.txt kdepim-runtime-15.08.0/resources/shared/filestore/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/shared/filestore/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,17 +1,7 @@ project(akonadi-filestore) -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${AKONADI_INCLUDE_DIR} - ${KDE4_INCLUDES} - ${KDEPIMLIBS_INCLUDE_DIR} - ${QT_INCLUDES} - ${Boost_INCLUDE_DIR} -) - -include(KDE4Defaults) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}") +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi-filestore\") set(akonadi-filestore_SRCS abstractlocalstore.cpp @@ -32,21 +22,21 @@ storecompactjob.cpp ) -kde4_add_library(akonadi-filestore ${LIBRARY_TYPE} ${akonadi-filestore_SRCS} ) +add_library(akonadi-filestore ${akonadi-filestore_SRCS} ) +generate_export_header(akonadi-filestore BASE_NAME akonadi-filestore) target_link_libraries(akonadi-filestore - ${AKONADI_COMMON_LIBRARIES} - ${QT_QTCORE_LIBRARY} - ${QT_QTGUI_LIBRARY} - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDE4_KIO_LIBS} + PUBLIC + KF5::AkonadiCore + PRIVATE + KF5::I18n ) -set_target_properties(akonadi-filestore PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} ) +set_target_properties(akonadi-filestore PROPERTIES VERSION ${KDEPIMRUNTIME_LIB_VERSION} SOVERSION ${KDEPIMRUNTIME_LIB_SOVERSION} ) -install(TARGETS akonadi-filestore ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(TARGETS akonadi-filestore ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) -if (KDE4_BUILD_TESTS) - add_subdirectory( tests ) +if (BUILD_TESTING) + add_subdirectory( autotests ) endif () diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/collectioncreatejob.cpp kdepim-runtime-15.08.0/resources/shared/filestore/collectioncreatejob.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/collectioncreatejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/collectioncreatejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,55 +26,53 @@ class FileStore::CollectionCreateJob::Private { - public: - explicit Private( FileStore::CollectionCreateJob *parent ) - : mParent( parent ) +public: + explicit Private(FileStore::CollectionCreateJob *parent) + : mParent(parent) { } - public: +public: Collection mCollection; Collection mTargetParent; - private: +private: FileStore::CollectionCreateJob *mParent; }; -FileStore::CollectionCreateJob::CollectionCreateJob( const Collection &collection, const Collection &targetParent, FileStore::AbstractJobSession *session ) - : FileStore::Job( session ), d( new Private( this ) ) +FileStore::CollectionCreateJob::CollectionCreateJob(const Collection &collection, const Collection &targetParent, FileStore::AbstractJobSession *session) + : FileStore::Job(session), d(new Private(this)) { - Q_ASSERT( session != 0 ); + Q_ASSERT(session != 0); - d->mCollection = collection; - d->mTargetParent = targetParent; + d->mCollection = collection; + d->mTargetParent = targetParent; - session->addJob( this ); + session->addJob(this); } FileStore::CollectionCreateJob::~CollectionCreateJob() { - delete d; + delete d; } Collection FileStore::CollectionCreateJob::collection() const { - return d->mCollection; + return d->mCollection; } Collection FileStore::CollectionCreateJob::targetParent() const { - return d->mTargetParent; + return d->mTargetParent; } -bool FileStore::CollectionCreateJob::accept( FileStore::Job::Visitor *visitor ) +bool FileStore::CollectionCreateJob::accept(FileStore::Job::Visitor *visitor) { - return visitor->visit( this ); + return visitor->visit(this); } -void FileStore::CollectionCreateJob::handleCollectionCreated( const Collection &collection ) +void FileStore::CollectionCreateJob::handleCollectionCreated(const Collection &collection) { - d->mCollection = collection; + d->mCollection = collection; } - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/collectioncreatejob.h kdepim-runtime-15.08.0/resources/shared/filestore/collectioncreatejob.h --- kdepim-runtime-4.14.6/resources/shared/filestore/collectioncreatejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/collectioncreatejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -25,22 +25,22 @@ namespace Akonadi { - class Collection; +class Collection; namespace FileStore { - class AbstractJobSession; +class AbstractJobSession; /** */ class AKONADI_FILESTORE_EXPORT CollectionCreateJob : public Job { - friend class AbstractJobSession; + friend class AbstractJobSession; - Q_OBJECT + Q_OBJECT - public: - explicit CollectionCreateJob( const Collection &collection, const Collection &targetParent, AbstractJobSession *session = 0 ); +public: + explicit CollectionCreateJob(const Collection &collection, const Collection &targetParent, AbstractJobSession *session = Q_NULLPTR); virtual ~CollectionCreateJob(); @@ -48,12 +48,12 @@ Collection targetParent() const; - virtual bool accept( Visitor *visitor ); + bool accept(Visitor *visitor) Q_DECL_OVERRIDE; - private: - void handleCollectionCreated( const Collection &collection ); +private: + void handleCollectionCreated(const Collection &collection); - private: +private: class Private; Private *const d; }; @@ -63,4 +63,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/collectiondeletejob.cpp kdepim-runtime-15.08.0/resources/shared/filestore/collectiondeletejob.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/collectiondeletejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/collectiondeletejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,48 +26,46 @@ class FileStore::CollectionDeleteJob::Private { - public: - explicit Private( FileStore::CollectionDeleteJob *parent ) - : mParent( parent ) +public: + explicit Private(FileStore::CollectionDeleteJob *parent) + : mParent(parent) { } - public: +public: Collection mCollection; - private: +private: FileStore::CollectionDeleteJob *mParent; }; -FileStore::CollectionDeleteJob::CollectionDeleteJob( const Collection &collection, FileStore::AbstractJobSession *session ) - : FileStore::Job( session ), d( new Private( this ) ) +FileStore::CollectionDeleteJob::CollectionDeleteJob(const Collection &collection, FileStore::AbstractJobSession *session) + : FileStore::Job(session), d(new Private(this)) { - Q_ASSERT( session != 0 ); + Q_ASSERT(session != 0); - d->mCollection = collection; + d->mCollection = collection; - session->addJob( this ); + session->addJob(this); } FileStore::CollectionDeleteJob::~CollectionDeleteJob() { - delete d; + delete d; } Collection FileStore::CollectionDeleteJob::collection() const { - return d->mCollection; + return d->mCollection; } -bool FileStore::CollectionDeleteJob::accept( FileStore::Job::Visitor *visitor ) +bool FileStore::CollectionDeleteJob::accept(FileStore::Job::Visitor *visitor) { - return visitor->visit( this ); + return visitor->visit(this); } -void FileStore::CollectionDeleteJob::handleCollectionDeleted( const Collection &collection ) +void FileStore::CollectionDeleteJob::handleCollectionDeleted(const Collection &collection) { - d->mCollection = collection; + d->mCollection = collection; } - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/collectiondeletejob.h kdepim-runtime-15.08.0/resources/shared/filestore/collectiondeletejob.h --- kdepim-runtime-4.14.6/resources/shared/filestore/collectiondeletejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/collectiondeletejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -25,33 +25,33 @@ namespace Akonadi { - class Collection; +class Collection; namespace FileStore { - class AbstractJobSession; +class AbstractJobSession; /** */ class AKONADI_FILESTORE_EXPORT CollectionDeleteJob : public Job { - friend class AbstractJobSession; + friend class AbstractJobSession; - Q_OBJECT + Q_OBJECT - public: - explicit CollectionDeleteJob( const Collection &collection, AbstractJobSession *session = 0 ); +public: + explicit CollectionDeleteJob(const Collection &collection, AbstractJobSession *session = Q_NULLPTR); virtual ~CollectionDeleteJob(); Collection collection() const; - virtual bool accept( Visitor *visitor ); + bool accept(Visitor *visitor) Q_DECL_OVERRIDE; - private: - void handleCollectionDeleted( const Collection &collection ); +private: + void handleCollectionDeleted(const Collection &collection); - private: +private: class Private; Private *const d; }; @@ -61,4 +61,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/collectionfetchjob.cpp kdepim-runtime-15.08.0/resources/shared/filestore/collectionfetchjob.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/collectionfetchjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/collectionfetchjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,20 +21,20 @@ #include "session_p.h" -#include +#include using namespace Akonadi; class FileStore::CollectionFetchJob::Private { - public: - explicit Private( FileStore::CollectionFetchJob *parent ) - : mType( FileStore::CollectionFetchJob::Base ), - mParent( parent ) +public: + explicit Private(FileStore::CollectionFetchJob *parent) + : mType(FileStore::CollectionFetchJob::Base), + mParent(parent) { } - public: +public: FileStore::CollectionFetchJob::Type mType; Collection mCollection; @@ -42,62 +42,60 @@ Collection::List mCollections; - private: +private: FileStore::CollectionFetchJob *mParent; }; -FileStore::CollectionFetchJob::CollectionFetchJob( const Collection &collection, Type type, FileStore::AbstractJobSession *session ) - : FileStore::Job( session ), d( new Private( this ) ) +FileStore::CollectionFetchJob::CollectionFetchJob(const Collection &collection, Type type, FileStore::AbstractJobSession *session) + : FileStore::Job(session), d(new Private(this)) { - Q_ASSERT( session != 0 ); + Q_ASSERT(session != 0); - d->mType = type; - d->mCollection = collection; + d->mType = type; + d->mCollection = collection; - session->addJob( this ); + session->addJob(this); } FileStore::CollectionFetchJob::~CollectionFetchJob() { - delete d; + delete d; } FileStore::CollectionFetchJob::Type FileStore::CollectionFetchJob::type() const { - return d->mType; + return d->mType; } Collection FileStore::CollectionFetchJob::collection() const { - return d->mCollection; + return d->mCollection; } -void FileStore::CollectionFetchJob::setFetchScope( const CollectionFetchScope &fetchScope ) +void FileStore::CollectionFetchJob::setFetchScope(const CollectionFetchScope &fetchScope) { - d->mFetchScope = fetchScope; + d->mFetchScope = fetchScope; } CollectionFetchScope &FileStore::CollectionFetchJob::fetchScope() { - return d->mFetchScope; + return d->mFetchScope; } Collection::List FileStore::CollectionFetchJob::collections() const { - return d->mCollections; + return d->mCollections; } -bool FileStore::CollectionFetchJob::accept( FileStore::Job::Visitor *visitor ) +bool FileStore::CollectionFetchJob::accept(FileStore::Job::Visitor *visitor) { - return visitor->visit( this ); + return visitor->visit(this); } -void FileStore::CollectionFetchJob::handleCollectionsReceived( const Collection::List &collections ) +void FileStore::CollectionFetchJob::handleCollectionsReceived(const Collection::List &collections) { - d->mCollections << collections; + d->mCollections << collections; - emit collectionsReceived( collections ); + Q_EMIT collectionsReceived(collections); } - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/collectionfetchjob.h kdepim-runtime-15.08.0/resources/shared/filestore/collectionfetchjob.h --- kdepim-runtime-4.14.6/resources/shared/filestore/collectionfetchjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/collectionfetchjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,33 +22,32 @@ #include "job.h" -#include +#include namespace Akonadi { - class CollectionFetchScope; +class CollectionFetchScope; namespace FileStore { - class AbstractJobSession; +class AbstractJobSession; /** */ class AKONADI_FILESTORE_EXPORT CollectionFetchJob : public Job { - friend class AbstractJobSession; + friend class AbstractJobSession; - Q_OBJECT + Q_OBJECT - public: - enum Type - { - Base, - FirstLevel, - Recursive +public: + enum Type { + Base, + FirstLevel, + Recursive }; - explicit CollectionFetchJob( const Collection &collection, Type type = FirstLevel, AbstractJobSession *session = 0 ); + explicit CollectionFetchJob(const Collection &collection, Type type = FirstLevel, AbstractJobSession *session = Q_NULLPTR); virtual ~CollectionFetchJob(); @@ -56,21 +55,21 @@ Collection collection() const; - void setFetchScope( const CollectionFetchScope &fetchScope ); + void setFetchScope(const CollectionFetchScope &fetchScope); CollectionFetchScope &fetchScope(); Collection::List collections() const; - virtual bool accept( Visitor *visitor ); + bool accept(Visitor *visitor) Q_DECL_OVERRIDE; - Q_SIGNALS: - void collectionsReceived( const Akonadi::Collection::List &items ); +Q_SIGNALS: + void collectionsReceived(const Akonadi::Collection::List &items); - private: - void handleCollectionsReceived( const Akonadi::Collection::List &collections ); +private: + void handleCollectionsReceived(const Akonadi::Collection::List &collections); - private: +private: class Private; Private *const d; }; @@ -80,4 +79,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/collectionmodifyjob.cpp kdepim-runtime-15.08.0/resources/shared/filestore/collectionmodifyjob.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/collectionmodifyjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/collectionmodifyjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,48 +26,46 @@ class FileStore::CollectionModifyJob::Private { - public: - explicit Private( FileStore::CollectionModifyJob *parent ) - : mParent( parent ) +public: + explicit Private(FileStore::CollectionModifyJob *parent) + : mParent(parent) { } - public: +public: Collection mCollection; - private: +private: FileStore::CollectionModifyJob *mParent; }; -FileStore::CollectionModifyJob::CollectionModifyJob( const Collection &collection, FileStore::AbstractJobSession *session ) - : FileStore::Job( session ), d( new Private( this ) ) +FileStore::CollectionModifyJob::CollectionModifyJob(const Collection &collection, FileStore::AbstractJobSession *session) + : FileStore::Job(session), d(new Private(this)) { - Q_ASSERT( session != 0 ); + Q_ASSERT(session != 0); - d->mCollection = collection; + d->mCollection = collection; - session->addJob( this ); + session->addJob(this); } FileStore::CollectionModifyJob::~CollectionModifyJob() { - delete d; + delete d; } Collection FileStore::CollectionModifyJob::collection() const { - return d->mCollection; + return d->mCollection; } -bool FileStore::CollectionModifyJob::accept( FileStore::Job::Visitor *visitor ) +bool FileStore::CollectionModifyJob::accept(FileStore::Job::Visitor *visitor) { - return visitor->visit( this ); + return visitor->visit(this); } -void FileStore::CollectionModifyJob::handleCollectionModified( const Collection &collection ) +void FileStore::CollectionModifyJob::handleCollectionModified(const Collection &collection) { - d->mCollection = collection; + d->mCollection = collection; } - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/collectionmodifyjob.h kdepim-runtime-15.08.0/resources/shared/filestore/collectionmodifyjob.h --- kdepim-runtime-4.14.6/resources/shared/filestore/collectionmodifyjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/collectionmodifyjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -25,33 +25,33 @@ namespace Akonadi { - class Collection; +class Collection; namespace FileStore { - class AbstractJobSession; +class AbstractJobSession; /** */ class AKONADI_FILESTORE_EXPORT CollectionModifyJob : public Job { - friend class AbstractJobSession; + friend class AbstractJobSession; - Q_OBJECT + Q_OBJECT - public: - explicit CollectionModifyJob( const Collection &collection, AbstractJobSession *session = 0 ); +public: + explicit CollectionModifyJob(const Collection &collection, AbstractJobSession *session = Q_NULLPTR); virtual ~CollectionModifyJob(); Collection collection() const; - virtual bool accept( Visitor *visitor ); + bool accept(Visitor *visitor) Q_DECL_OVERRIDE; - private: - void handleCollectionModified( const Collection &collection ); +private: + void handleCollectionModified(const Collection &collection); - private: +private: class Private; Private *const d; }; @@ -61,4 +61,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/collectionmovejob.cpp kdepim-runtime-15.08.0/resources/shared/filestore/collectionmovejob.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/collectionmovejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/collectionmovejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,55 +26,53 @@ class FileStore::CollectionMoveJob::Private { - public: - explicit Private( FileStore::CollectionMoveJob *parent ) - : mParent( parent ) +public: + explicit Private(FileStore::CollectionMoveJob *parent) + : mParent(parent) { } - public: +public: Collection mCollection; Collection mTargetParent; - private: +private: FileStore::CollectionMoveJob *mParent; }; -FileStore::CollectionMoveJob::CollectionMoveJob( const Collection &collection, const Collection &targetParent, FileStore::AbstractJobSession *session ) - : FileStore::Job( session ), d( new Private( this ) ) +FileStore::CollectionMoveJob::CollectionMoveJob(const Collection &collection, const Collection &targetParent, FileStore::AbstractJobSession *session) + : FileStore::Job(session), d(new Private(this)) { - Q_ASSERT( session != 0 ); + Q_ASSERT(session != 0); - d->mCollection = collection; - d->mTargetParent = targetParent; + d->mCollection = collection; + d->mTargetParent = targetParent; - session->addJob( this ); + session->addJob(this); } FileStore::CollectionMoveJob::~CollectionMoveJob() { - delete d; + delete d; } Collection FileStore::CollectionMoveJob::collection() const { - return d->mCollection; + return d->mCollection; } Collection FileStore::CollectionMoveJob::targetParent() const { - return d->mTargetParent; + return d->mTargetParent; } -bool FileStore::CollectionMoveJob::accept( FileStore::Job::Visitor *visitor ) +bool FileStore::CollectionMoveJob::accept(FileStore::Job::Visitor *visitor) { - return visitor->visit( this ); + return visitor->visit(this); } -void FileStore::CollectionMoveJob::handleCollectionMoved( const Collection &collection ) +void FileStore::CollectionMoveJob::handleCollectionMoved(const Collection &collection) { - d->mCollection = collection; + d->mCollection = collection; } - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/collectionmovejob.h kdepim-runtime-15.08.0/resources/shared/filestore/collectionmovejob.h --- kdepim-runtime-4.14.6/resources/shared/filestore/collectionmovejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/collectionmovejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -25,22 +25,22 @@ namespace Akonadi { - class Collection; +class Collection; namespace FileStore { - class AbstractJobSession; +class AbstractJobSession; /** */ class AKONADI_FILESTORE_EXPORT CollectionMoveJob : public Job { - friend class AbstractJobSession; + friend class AbstractJobSession; - Q_OBJECT + Q_OBJECT - public: - explicit CollectionMoveJob( const Collection &collection, const Collection &targetParent, AbstractJobSession *session = 0 ); +public: + explicit CollectionMoveJob(const Collection &collection, const Collection &targetParent, AbstractJobSession *session = Q_NULLPTR); virtual ~CollectionMoveJob(); @@ -48,12 +48,12 @@ Collection targetParent() const; - virtual bool accept( Visitor *visitor ); + bool accept(Visitor *visitor) Q_DECL_OVERRIDE; - private: - void handleCollectionMoved( const Collection &collection ); +private: + void handleCollectionMoved(const Collection &collection); - private: +private: class Private; Private *const d; }; @@ -63,4 +63,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/entitycompactchangeattribute.cpp kdepim-runtime-15.08.0/resources/shared/filestore/entitycompactchangeattribute.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/entitycompactchangeattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/entitycompactchangeattribute.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,88 +26,87 @@ class FileStore::EntityCompactChangeAttribute::Private { - FileStore::EntityCompactChangeAttribute *const q; + FileStore::EntityCompactChangeAttribute *const q; - public: - explicit Private( FileStore::EntityCompactChangeAttribute *parent ) : q( parent ) +public: + explicit Private(FileStore::EntityCompactChangeAttribute *parent) : q(parent) { } - Private& operator=( const Private &other ) + Private &operator=(const Private &other) { - if ( &other == this ) { - return *this; - } + if (&other == this) { + return *this; + } - mRemoteId = other.mRemoteId; - mRemoteRev = other.mRemoteRev; - return *this; + mRemoteId = other.mRemoteId; + mRemoteRev = other.mRemoteRev; + return *this; } - public: +public: QString mRemoteId; QString mRemoteRev; }; FileStore::EntityCompactChangeAttribute::EntityCompactChangeAttribute() - : Attribute(), d( new Private( this ) ) + : Attribute(), d(new Private(this)) { } FileStore::EntityCompactChangeAttribute::~EntityCompactChangeAttribute() { - delete d; + delete d; } -void FileStore::EntityCompactChangeAttribute::setRemoteId( const QString &remoteId ) +void FileStore::EntityCompactChangeAttribute::setRemoteId(const QString &remoteId) { - d->mRemoteId = remoteId; + d->mRemoteId = remoteId; } QString FileStore::EntityCompactChangeAttribute::remoteId() const { - return d->mRemoteId; + return d->mRemoteId; } -void FileStore::EntityCompactChangeAttribute::setRemoteRevision( const QString &remoteRev ) +void FileStore::EntityCompactChangeAttribute::setRemoteRevision(const QString &remoteRev) { - d->mRemoteRev = remoteRev; + d->mRemoteRev = remoteRev; } QString FileStore::EntityCompactChangeAttribute::remoteRevision() const { - return d->mRemoteRev; + return d->mRemoteRev; } QByteArray FileStore::EntityCompactChangeAttribute::type() const { - static const QByteArray sType( "ENTITYCOMPACTCHANGE" ); + static const QByteArray sType("ENTITYCOMPACTCHANGE"); return sType; } -FileStore::EntityCompactChangeAttribute* FileStore::EntityCompactChangeAttribute::clone() const +FileStore::EntityCompactChangeAttribute *FileStore::EntityCompactChangeAttribute::clone() const { - FileStore::EntityCompactChangeAttribute *copy = new FileStore::EntityCompactChangeAttribute(); - *(copy->d) = *d; - return copy; + FileStore::EntityCompactChangeAttribute *copy = new FileStore::EntityCompactChangeAttribute(); + *(copy->d) = *d; + return copy; } QByteArray FileStore::EntityCompactChangeAttribute::serialized() const { - QByteArray data; - QDataStream stream( &data, QIODevice::WriteOnly ); + QByteArray data; + QDataStream stream(&data, QIODevice::WriteOnly); - stream << d->mRemoteId; - stream << d->mRemoteRev; + stream << d->mRemoteId; + stream << d->mRemoteRev; - return data; + return data; } -void FileStore::EntityCompactChangeAttribute::deserialize( const QByteArray &data ) +void FileStore::EntityCompactChangeAttribute::deserialize(const QByteArray &data) { - QDataStream stream( data ); - stream >> d->mRemoteId; - stream >> d->mRemoteRev; + QDataStream stream(data); + stream >> d->mRemoteId; + stream >> d->mRemoteRev; } -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/entitycompactchangeattribute.h kdepim-runtime-15.08.0/resources/shared/filestore/entitycompactchangeattribute.h --- kdepim-runtime-4.14.6/resources/shared/filestore/entitycompactchangeattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/entitycompactchangeattribute.h 2015-08-10 21:01:02.000000000 +0000 @@ -23,7 +23,7 @@ #include "akonadi-filestore_export.h" -#include +#include namespace Akonadi { @@ -33,29 +33,29 @@ class AKONADI_FILESTORE_EXPORT EntityCompactChangeAttribute : public Attribute { - public: +public: EntityCompactChangeAttribute(); ~EntityCompactChangeAttribute(); - void setRemoteId( const QString &remoteId ); + void setRemoteId(const QString &remoteId); QString remoteId() const; - void setRemoteRevision( const QString &remoteRev ); + void setRemoteRevision(const QString &remoteRev); QString remoteRevision() const; - public: /* reimpl */ - QByteArray type() const; +public: /* reimpl */ + QByteArray type() const Q_DECL_OVERRIDE; - EntityCompactChangeAttribute* clone() const; + EntityCompactChangeAttribute *clone() const Q_DECL_OVERRIDE; - QByteArray serialized() const; + QByteArray serialized() const Q_DECL_OVERRIDE; - void deserialize( const QByteArray &data ); + void deserialize(const QByteArray &data) Q_DECL_OVERRIDE; - private: +private: //@cond PRIVATE class Private; Private *const d; @@ -68,4 +68,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/itemcreatejob.cpp kdepim-runtime-15.08.0/resources/shared/filestore/itemcreatejob.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/itemcreatejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/itemcreatejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -25,53 +25,51 @@ class FileStore::ItemCreateJob::Private { - public: - explicit Private( FileStore::ItemCreateJob *parent ) - : mParent( parent ) +public: + explicit Private(FileStore::ItemCreateJob *parent) + : mParent(parent) { } - public: +public: Item mItem; Collection mCollection; - private: +private: FileStore::ItemCreateJob *mParent; }; -FileStore::ItemCreateJob::ItemCreateJob( const Item &item, const Collection &collection, FileStore::AbstractJobSession *session ) - : FileStore::Job( session ), d( new Private( this ) ) +FileStore::ItemCreateJob::ItemCreateJob(const Item &item, const Collection &collection, FileStore::AbstractJobSession *session) + : FileStore::Job(session), d(new Private(this)) { - d->mItem = item; - d->mCollection = collection; + d->mItem = item; + d->mCollection = collection; - session->addJob( this ); + session->addJob(this); } FileStore::ItemCreateJob::~ItemCreateJob() { - delete d; + delete d; } Collection FileStore::ItemCreateJob::collection() const { - return d->mCollection; + return d->mCollection; } Item FileStore::ItemCreateJob::item() const { - return d->mItem; + return d->mItem; } -bool FileStore::ItemCreateJob::accept( FileStore::Job::Visitor *visitor ) +bool FileStore::ItemCreateJob::accept(FileStore::Job::Visitor *visitor) { - return visitor->visit( this ); + return visitor->visit(this); } -void FileStore::ItemCreateJob::handleItemCreated( const Item &item ) +void FileStore::ItemCreateJob::handleItemCreated(const Item &item) { - d->mItem = item; + d->mItem = item; } - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/itemcreatejob.h kdepim-runtime-15.08.0/resources/shared/filestore/itemcreatejob.h --- kdepim-runtime-4.14.6/resources/shared/filestore/itemcreatejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/itemcreatejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,23 +24,23 @@ namespace Akonadi { - class Collection; - class Item; +class Collection; +class Item; namespace FileStore { - class AbstractJobSession; +class AbstractJobSession; /** */ class AKONADI_FILESTORE_EXPORT ItemCreateJob : public Job { - friend class AbstractJobSession; + friend class AbstractJobSession; - Q_OBJECT + Q_OBJECT - public: - explicit ItemCreateJob( const Item &item, const Collection &collection, AbstractJobSession *session = 0 ); +public: + explicit ItemCreateJob(const Item &item, const Collection &collection, AbstractJobSession *session = Q_NULLPTR); virtual ~ItemCreateJob(); @@ -48,12 +48,12 @@ Item item() const; - virtual bool accept( Visitor *visitor ); + bool accept(Visitor *visitor) Q_DECL_OVERRIDE; - private: - void handleItemCreated( const Akonadi::Item &item ); +private: + void handleItemCreated(const Akonadi::Item &item); - private: +private: class Private; Private *const d; }; @@ -63,4 +63,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/itemdeletejob.cpp kdepim-runtime-15.08.0/resources/shared/filestore/itemdeletejob.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/itemdeletejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/itemdeletejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -25,46 +25,44 @@ class FileStore::ItemDeleteJob::Private { - public: - explicit Private( FileStore::ItemDeleteJob *parent ) - : mParent( parent ) +public: + explicit Private(FileStore::ItemDeleteJob *parent) + : mParent(parent) { } - public: +public: Item mItem; - private: +private: FileStore::ItemDeleteJob *mParent; }; -FileStore::ItemDeleteJob::ItemDeleteJob( const Item &item, FileStore::AbstractJobSession *session ) - : FileStore::Job( session ), d( new Private( this ) ) +FileStore::ItemDeleteJob::ItemDeleteJob(const Item &item, FileStore::AbstractJobSession *session) + : FileStore::Job(session), d(new Private(this)) { - d->mItem = item; + d->mItem = item; - session->addJob( this ); + session->addJob(this); } FileStore::ItemDeleteJob::~ItemDeleteJob() { - delete d; + delete d; } Item FileStore::ItemDeleteJob::item() const { - return d->mItem; + return d->mItem; } -bool FileStore::ItemDeleteJob::accept( FileStore::Job::Visitor *visitor ) +bool FileStore::ItemDeleteJob::accept(FileStore::Job::Visitor *visitor) { - return visitor->visit( this ); + return visitor->visit(this); } -void FileStore::ItemDeleteJob::handleItemDeleted( const Item &item ) +void FileStore::ItemDeleteJob::handleItemDeleted(const Item &item) { - d->mItem = item; + d->mItem = item; } - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/itemdeletejob.h kdepim-runtime-15.08.0/resources/shared/filestore/itemdeletejob.h --- kdepim-runtime-4.14.6/resources/shared/filestore/itemdeletejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/itemdeletejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -24,33 +24,33 @@ namespace Akonadi { - class Item; +class Item; namespace FileStore { - class AbstractJobSession; +class AbstractJobSession; /** */ class AKONADI_FILESTORE_EXPORT ItemDeleteJob : public Job { - friend class AbstractJobSession; + friend class AbstractJobSession; - Q_OBJECT + Q_OBJECT - public: - explicit ItemDeleteJob( const Item &item, AbstractJobSession *session = 0 ); +public: + explicit ItemDeleteJob(const Item &item, AbstractJobSession *session = Q_NULLPTR); virtual ~ItemDeleteJob(); Item item() const; - virtual bool accept( Visitor *visitor ); + bool accept(Visitor *visitor) Q_DECL_OVERRIDE; - private: - void handleItemDeleted( const Akonadi::Item &item ); +private: + void handleItemDeleted(const Akonadi::Item &item); - private: +private: class Private; Private *const d; }; @@ -60,4 +60,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/itemfetchjob.cpp kdepim-runtime-15.08.0/resources/shared/filestore/itemfetchjob.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/itemfetchjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/itemfetchjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,19 +21,19 @@ #include "session_p.h" -#include +#include using namespace Akonadi; class FileStore::ItemFetchJob::Private { - public: - explicit Private( FileStore::ItemFetchJob *parent ) - : mParent( parent ) +public: + explicit Private(FileStore::ItemFetchJob *parent) + : mParent(parent) { } - public: +public: ItemFetchScope mFetchScope; Item::List mItems; @@ -41,67 +41,65 @@ Collection mCollection; Item mItem; - private: +private: FileStore::ItemFetchJob *mParent; }; -FileStore::ItemFetchJob::ItemFetchJob( const Collection &collection, FileStore::AbstractJobSession *session ) - : FileStore::Job( session ), d( new Private( this ) ) +FileStore::ItemFetchJob::ItemFetchJob(const Collection &collection, FileStore::AbstractJobSession *session) + : FileStore::Job(session), d(new Private(this)) { - d->mCollection = collection; + d->mCollection = collection; - session->addJob( this ); + session->addJob(this); } -FileStore::ItemFetchJob::ItemFetchJob( const Item &item, FileStore::AbstractJobSession *session ) - : FileStore::Job( session ), d( new Private( this ) ) +FileStore::ItemFetchJob::ItemFetchJob(const Item &item, FileStore::AbstractJobSession *session) + : FileStore::Job(session), d(new Private(this)) { - d->mItem = item; + d->mItem = item; - session->addJob( this ); + session->addJob(this); } FileStore::ItemFetchJob::~ItemFetchJob() { - delete d; + delete d; } Collection FileStore::ItemFetchJob::collection() const { - return d->mCollection; + return d->mCollection; } Item FileStore::ItemFetchJob::item() const { - return d->mItem; + return d->mItem; } -void FileStore::ItemFetchJob::setFetchScope( const ItemFetchScope &fetchScope ) +void FileStore::ItemFetchJob::setFetchScope(const ItemFetchScope &fetchScope) { - d->mFetchScope = fetchScope; + d->mFetchScope = fetchScope; } ItemFetchScope &FileStore::ItemFetchJob::fetchScope() { - return d->mFetchScope; + return d->mFetchScope; } Item::List FileStore::ItemFetchJob::items() const { - return d->mItems; + return d->mItems; } -bool FileStore::ItemFetchJob::accept( FileStore::Job::Visitor *visitor ) +bool FileStore::ItemFetchJob::accept(FileStore::Job::Visitor *visitor) { - return visitor->visit( this ); + return visitor->visit(this); } -void FileStore::ItemFetchJob::handleItemsReceived( const Item::List &items ) +void FileStore::ItemFetchJob::handleItemsReceived(const Item::List &items) { - d->mItems << items; + d->mItems << items; - emit itemsReceived( items ); + Q_EMIT itemsReceived(items); } - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/itemfetchjob.h kdepim-runtime-15.08.0/resources/shared/filestore/itemfetchjob.h --- kdepim-runtime-4.14.6/resources/shared/filestore/itemfetchjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/itemfetchjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,29 +22,29 @@ #include "job.h" -#include +#include namespace Akonadi { - class Collection; - class ItemFetchScope; +class Collection; +class ItemFetchScope; namespace FileStore { - class AbstractJobSession; +class AbstractJobSession; /** */ class AKONADI_FILESTORE_EXPORT ItemFetchJob : public Job { - friend class AbstractJobSession; + friend class AbstractJobSession; - Q_OBJECT + Q_OBJECT - public: - explicit ItemFetchJob( const Collection &collection, AbstractJobSession *session = 0 ); +public: + explicit ItemFetchJob(const Collection &collection, AbstractJobSession *session = Q_NULLPTR); - explicit ItemFetchJob( const Item &item, AbstractJobSession *session = 0 ); + explicit ItemFetchJob(const Item &item, AbstractJobSession *session = Q_NULLPTR); virtual ~ItemFetchJob(); @@ -52,21 +52,21 @@ Item item() const; - void setFetchScope( const ItemFetchScope &fetchScope ); + void setFetchScope(const ItemFetchScope &fetchScope); ItemFetchScope &fetchScope(); Item::List items() const; - virtual bool accept( Visitor *visitor ); + bool accept(Visitor *visitor) Q_DECL_OVERRIDE; - Q_SIGNALS: - void itemsReceived( const Akonadi::Item::List &items ); +Q_SIGNALS: + void itemsReceived(const Akonadi::Item::List &items); - private: - void handleItemsReceived( const Akonadi::Item::List &items ); +private: + void handleItemsReceived(const Akonadi::Item::List &items); - private: +private: class Private; Private *const d; }; @@ -76,4 +76,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/itemmodifyjob.cpp kdepim-runtime-15.08.0/resources/shared/filestore/itemmodifyjob.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/itemmodifyjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/itemmodifyjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -25,68 +25,66 @@ class FileStore::ItemModifyJob::Private { - public: - explicit Private( FileStore::ItemModifyJob *parent ) - : mIgnorePayload( false ), mParent( parent ) +public: + explicit Private(FileStore::ItemModifyJob *parent) + : mIgnorePayload(false), mParent(parent) { } - public: +public: bool mIgnorePayload; Item mItem; QSet mParts; - private: +private: FileStore::ItemModifyJob *mParent; }; -FileStore::ItemModifyJob::ItemModifyJob( const Item &item, FileStore::AbstractJobSession *session ) - : FileStore::Job( session ), d( new Private( this ) ) +FileStore::ItemModifyJob::ItemModifyJob(const Item &item, FileStore::AbstractJobSession *session) + : FileStore::Job(session), d(new Private(this)) { - d->mItem = item; + d->mItem = item; - session->addJob( this ); + session->addJob(this); } FileStore::ItemModifyJob::~ItemModifyJob() { - delete d; + delete d; } -void FileStore::ItemModifyJob::setIgnorePayload( bool ignorePayload ) +void FileStore::ItemModifyJob::setIgnorePayload(bool ignorePayload) { - d->mIgnorePayload = ignorePayload; + d->mIgnorePayload = ignorePayload; } bool FileStore::ItemModifyJob::ignorePayload() const { - return d->mIgnorePayload; + return d->mIgnorePayload; } Item FileStore::ItemModifyJob::item() const { - return d->mItem; + return d->mItem; } -void FileStore::ItemModifyJob::setParts( const QSet& parts ) +void FileStore::ItemModifyJob::setParts(const QSet &parts) { d->mParts = parts; } -const QSet& FileStore::ItemModifyJob::parts() const +const QSet &FileStore::ItemModifyJob::parts() const { - return d->mParts; + return d->mParts; } -bool FileStore::ItemModifyJob::accept( FileStore::Job::Visitor *visitor ) +bool FileStore::ItemModifyJob::accept(FileStore::Job::Visitor *visitor) { - return visitor->visit( this ); + return visitor->visit(this); } -void FileStore::ItemModifyJob::handleItemModified( const Item &item ) +void FileStore::ItemModifyJob::handleItemModified(const Item &item) { - d->mItem = item; + d->mItem = item; } - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/itemmodifyjob.h kdepim-runtime-15.08.0/resources/shared/filestore/itemmodifyjob.h --- kdepim-runtime-4.14.6/resources/shared/filestore/itemmodifyjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/itemmodifyjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,43 +22,43 @@ #include "job.h" -#include +#include namespace Akonadi { namespace FileStore { - class AbstractJobSession; +class AbstractJobSession; /** */ class AKONADI_FILESTORE_EXPORT ItemModifyJob : public Job { - friend class AbstractJobSession; + friend class AbstractJobSession; - Q_OBJECT + Q_OBJECT - public: - explicit ItemModifyJob( const Item &item, AbstractJobSession *session = 0 ); +public: + explicit ItemModifyJob(const Item &item, AbstractJobSession *session = Q_NULLPTR); virtual ~ItemModifyJob(); - void setIgnorePayload( bool ignorePayload ); + void setIgnorePayload(bool ignorePayload); bool ignorePayload() const; Item item() const; - const QSet& parts() const; - void setParts( const QSet& parts ); + const QSet &parts() const; + void setParts(const QSet &parts); - virtual bool accept( Visitor *visitor ); + bool accept(Visitor *visitor) Q_DECL_OVERRIDE; - private: - void handleItemModified( const Akonadi::Item &item ); +private: + void handleItemModified(const Akonadi::Item &item); - private: +private: class Private; Private *const d; }; @@ -68,4 +68,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/itemmovejob.cpp kdepim-runtime-15.08.0/resources/shared/filestore/itemmovejob.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/itemmovejob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/itemmovejob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -26,53 +26,51 @@ class FileStore::ItemMoveJob::Private { - public: - explicit Private( FileStore::ItemMoveJob *parent ) - : mParent( parent ) +public: + explicit Private(FileStore::ItemMoveJob *parent) + : mParent(parent) { } - public: +public: Item mItem; Collection mTargetParent; - private: +private: FileStore::ItemMoveJob *mParent; }; -FileStore::ItemMoveJob::ItemMoveJob( const Item &item, const Collection &targetParent, FileStore::AbstractJobSession *session ) - : FileStore::Job( session ), d( new Private( this ) ) +FileStore::ItemMoveJob::ItemMoveJob(const Item &item, const Collection &targetParent, FileStore::AbstractJobSession *session) + : FileStore::Job(session), d(new Private(this)) { - d->mItem = item; - d->mTargetParent = targetParent; + d->mItem = item; + d->mTargetParent = targetParent; - session->addJob( this ); + session->addJob(this); } FileStore::ItemMoveJob::~ItemMoveJob() { - delete d; + delete d; } Collection FileStore::ItemMoveJob::targetParent() const { - return d->mTargetParent; + return d->mTargetParent; } Item FileStore::ItemMoveJob::item() const { - return d->mItem; + return d->mItem; } -bool FileStore::ItemMoveJob::accept( FileStore::Job::Visitor *visitor ) +bool FileStore::ItemMoveJob::accept(FileStore::Job::Visitor *visitor) { - return visitor->visit( this ); + return visitor->visit(this); } -void FileStore::ItemMoveJob::handleItemMoved( const Item &item ) +void FileStore::ItemMoveJob::handleItemMoved(const Item &item) { - d->mItem = item; + d->mItem = item; } - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/itemmovejob.h kdepim-runtime-15.08.0/resources/shared/filestore/itemmovejob.h --- kdepim-runtime-4.14.6/resources/shared/filestore/itemmovejob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/itemmovejob.h 2015-08-10 21:01:02.000000000 +0000 @@ -25,23 +25,23 @@ namespace Akonadi { - class Collection; - class Item; +class Collection; +class Item; namespace FileStore { - class AbstractJobSession; +class AbstractJobSession; /** */ class AKONADI_FILESTORE_EXPORT ItemMoveJob : public Job { - friend class AbstractJobSession; + friend class AbstractJobSession; - Q_OBJECT + Q_OBJECT - public: - ItemMoveJob( const Item &item, const Collection &targetParent, AbstractJobSession *session = 0 ); +public: + ItemMoveJob(const Item &item, const Collection &targetParent, AbstractJobSession *session = Q_NULLPTR); virtual ~ItemMoveJob(); @@ -49,12 +49,12 @@ Item item() const; - virtual bool accept( Visitor *visitor ); + bool accept(Visitor *visitor) Q_DECL_OVERRIDE; - private: - void handleItemMoved( const Item &item ); +private: + void handleItemMoved(const Item &item); - private: +private: class Private; Private *const d; }; @@ -64,4 +64,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/job.cpp kdepim-runtime-15.08.0/resources/shared/filestore/job.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/job.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/job.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -25,35 +25,33 @@ class FileStore::Job::Private { - public: - explicit Private( FileStore::Job *parent ) - : mParent( parent ) +public: + explicit Private(FileStore::Job *parent) + : mParent(parent) { } - private: +private: FileStore::Job *mParent; }; -FileStore::Job::Job( FileStore::AbstractJobSession *session ) - : KJob( session ), d( new Private( this ) ) +FileStore::Job::Job(FileStore::AbstractJobSession *session) + : KJob(session), d(new Private(this)) { - setAutoDelete( true ); + setAutoDelete(true); } FileStore::Job::~Job() { - delete d; + delete d; } void FileStore::Job::start() { } -bool FileStore::Job::accept( FileStore::Job::Visitor *visitor ) +bool FileStore::Job::accept(FileStore::Job::Visitor *visitor) { - return visitor->visit( this ); + return visitor->visit(this); } - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/job.h kdepim-runtime-15.08.0/resources/shared/filestore/job.h --- kdepim-runtime-4.14.6/resources/shared/filestore/job.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/job.h 2015-08-10 21:01:02.000000000 +0000 @@ -31,73 +31,72 @@ namespace FileStore { - class AbstractJobSession; - class CollectionCreateJob; - class CollectionDeleteJob; - class CollectionFetchJob; - class CollectionModifyJob; - class CollectionMoveJob; - class ItemCreateJob; - class ItemDeleteJob; - class ItemFetchJob; - class ItemModifyJob; - class ItemMoveJob; - class StoreCompactJob; +class AbstractJobSession; +class CollectionCreateJob; +class CollectionDeleteJob; +class CollectionFetchJob; +class CollectionModifyJob; +class CollectionMoveJob; +class ItemCreateJob; +class ItemDeleteJob; +class ItemFetchJob; +class ItemModifyJob; +class ItemMoveJob; +class StoreCompactJob; /** */ class AKONADI_FILESTORE_EXPORT Job : public KJob { - friend class AbstractJobSession; + friend class AbstractJobSession; - Q_OBJECT + Q_OBJECT - public: +public: class Visitor { - public: + public: virtual ~Visitor() {} - virtual bool visit( Job *job ) = 0; + virtual bool visit(Job *job) = 0; - virtual bool visit( CollectionCreateJob *job ) = 0; + virtual bool visit(CollectionCreateJob *job) = 0; - virtual bool visit( CollectionDeleteJob *job ) = 0; + virtual bool visit(CollectionDeleteJob *job) = 0; - virtual bool visit( CollectionFetchJob *job ) = 0; + virtual bool visit(CollectionFetchJob *job) = 0; - virtual bool visit( CollectionModifyJob *job ) = 0; + virtual bool visit(CollectionModifyJob *job) = 0; - virtual bool visit( CollectionMoveJob *job ) = 0; + virtual bool visit(CollectionMoveJob *job) = 0; - virtual bool visit( ItemCreateJob *job ) = 0; + virtual bool visit(ItemCreateJob *job) = 0; - virtual bool visit( ItemDeleteJob *job ) = 0; + virtual bool visit(ItemDeleteJob *job) = 0; - virtual bool visit( ItemFetchJob *job ) = 0; + virtual bool visit(ItemFetchJob *job) = 0; - virtual bool visit( ItemModifyJob *job ) = 0; + virtual bool visit(ItemModifyJob *job) = 0; - virtual bool visit( ItemMoveJob *job ) = 0; + virtual bool visit(ItemMoveJob *job) = 0; - virtual bool visit( StoreCompactJob *job ) = 0; + virtual bool visit(StoreCompactJob *job) = 0; }; - enum ErrorCodes - { - InvalidStoreState = KJob::UserDefinedError + 1, - InvalidJobContext + enum ErrorCodes { + InvalidStoreState = KJob::UserDefinedError + 1, + InvalidJobContext }; - explicit Job( AbstractJobSession *session = 0 ); + explicit Job(AbstractJobSession *session = Q_NULLPTR); virtual ~Job(); - virtual void start(); + void start() Q_DECL_OVERRIDE; - virtual bool accept( Visitor *visitor ); + virtual bool accept(Visitor *visitor); - private: +private: class Private; Private *d; }; @@ -107,4 +106,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/session.cpp kdepim-runtime-15.08.0/resources/shared/filestore/session.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/session.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/session.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -32,8 +32,8 @@ using namespace Akonadi; -FileStore::AbstractJobSession::AbstractJobSession( QObject *parent ) - : QObject( parent ) +FileStore::AbstractJobSession::AbstractJobSession(QObject *parent) + : QObject(parent) { } @@ -41,105 +41,104 @@ { } -void FileStore::AbstractJobSession::notifyCollectionsReceived( FileStore::Job* job, const Collection::List &collections ) +void FileStore::AbstractJobSession::notifyCollectionsReceived(FileStore::Job *job, const Collection::List &collections) { - FileStore::CollectionFetchJob *fetchJob = dynamic_cast( job ); - if ( fetchJob != 0 ) { - fetchJob->handleCollectionsReceived( collections ); - } + FileStore::CollectionFetchJob *fetchJob = dynamic_cast(job); + if (fetchJob != Q_NULLPTR) { + fetchJob->handleCollectionsReceived(collections); + } } -void FileStore::AbstractJobSession::notifyCollectionCreated( FileStore::Job *job, const Collection &collection ) +void FileStore::AbstractJobSession::notifyCollectionCreated(FileStore::Job *job, const Collection &collection) { - FileStore::CollectionCreateJob *createJob = dynamic_cast( job ); - if ( createJob != 0 ) { - createJob->handleCollectionCreated( collection ); - } + FileStore::CollectionCreateJob *createJob = dynamic_cast(job); + if (createJob != Q_NULLPTR) { + createJob->handleCollectionCreated(collection); + } } -void FileStore::AbstractJobSession::notifyCollectionDeleted( FileStore::Job *job, const Collection &collection ) +void FileStore::AbstractJobSession::notifyCollectionDeleted(FileStore::Job *job, const Collection &collection) { - FileStore::CollectionDeleteJob *deleteJob = dynamic_cast( job ); - if ( deleteJob != 0 ) { - deleteJob->handleCollectionDeleted( collection ); - } + FileStore::CollectionDeleteJob *deleteJob = dynamic_cast(job); + if (deleteJob != Q_NULLPTR) { + deleteJob->handleCollectionDeleted(collection); + } } -void FileStore::AbstractJobSession::notifyCollectionModified( FileStore::Job *job, const Collection &collection ) +void FileStore::AbstractJobSession::notifyCollectionModified(FileStore::Job *job, const Collection &collection) { - FileStore::CollectionModifyJob *modifyJob = dynamic_cast( job ); - if ( modifyJob != 0 ) { - modifyJob->handleCollectionModified( collection ); - } + FileStore::CollectionModifyJob *modifyJob = dynamic_cast(job); + if (modifyJob != Q_NULLPTR) { + modifyJob->handleCollectionModified(collection); + } } -void FileStore::AbstractJobSession::notifyCollectionMoved( FileStore::Job *job, const Collection &collection ) +void FileStore::AbstractJobSession::notifyCollectionMoved(FileStore::Job *job, const Collection &collection) { - FileStore::CollectionMoveJob *moveJob = dynamic_cast( job ); - if ( moveJob != 0 ) { - moveJob->handleCollectionMoved( collection ); - } + FileStore::CollectionMoveJob *moveJob = dynamic_cast(job); + if (moveJob != Q_NULLPTR) { + moveJob->handleCollectionMoved(collection); + } } -void FileStore::AbstractJobSession::notifyItemsReceived( FileStore::Job* job, const Item::List &items ) +void FileStore::AbstractJobSession::notifyItemsReceived(FileStore::Job *job, const Item::List &items) { - FileStore::ItemFetchJob *fetchJob = dynamic_cast( job ); - if ( fetchJob != 0 ) { - fetchJob->handleItemsReceived( items ); - } + FileStore::ItemFetchJob *fetchJob = dynamic_cast(job); + if (fetchJob != Q_NULLPTR) { + fetchJob->handleItemsReceived(items); + } } -void FileStore::AbstractJobSession::notifyItemCreated( FileStore::Job *job, const Item &item ) +void FileStore::AbstractJobSession::notifyItemCreated(FileStore::Job *job, const Item &item) { - FileStore::ItemCreateJob *createJob = dynamic_cast( job ); - if ( createJob != 0 ) { - createJob->handleItemCreated( item ); - } + FileStore::ItemCreateJob *createJob = dynamic_cast(job); + if (createJob != Q_NULLPTR) { + createJob->handleItemCreated(item); + } } -void FileStore::AbstractJobSession::notifyItemModified( FileStore::Job *job, const Item &item ) +void FileStore::AbstractJobSession::notifyItemModified(FileStore::Job *job, const Item &item) { - FileStore::ItemModifyJob *modifyJob = dynamic_cast( job ); - if ( modifyJob != 0 ) { - modifyJob->handleItemModified( item ); - } + FileStore::ItemModifyJob *modifyJob = dynamic_cast(job); + if (modifyJob != Q_NULLPTR) { + modifyJob->handleItemModified(item); + } } -void FileStore::AbstractJobSession::notifyItemMoved( FileStore::Job *job, const Item &item ) +void FileStore::AbstractJobSession::notifyItemMoved(FileStore::Job *job, const Item &item) { - FileStore::ItemMoveJob *moveJob = dynamic_cast( job ); - if ( moveJob != 0 ) { - moveJob->handleItemMoved( item ); - } + FileStore::ItemMoveJob *moveJob = dynamic_cast(job); + if (moveJob != Q_NULLPTR) { + moveJob->handleItemMoved(item); + } } -void FileStore::AbstractJobSession::notifyCollectionsChanged( FileStore::Job *job, const Collection::List &collections ) +void FileStore::AbstractJobSession::notifyCollectionsChanged(FileStore::Job *job, const Collection::List &collections) { - FileStore::StoreCompactJob *compactJob = dynamic_cast( job ); - if ( compactJob != 0 ) { - compactJob->handleCollectionsChanged( collections ); - } + FileStore::StoreCompactJob *compactJob = dynamic_cast(job); + if (compactJob != Q_NULLPTR) { + compactJob->handleCollectionsChanged(collections); + } } -void FileStore::AbstractJobSession::notifyItemsChanged( FileStore::Job *job, const Item::List &items ) +void FileStore::AbstractJobSession::notifyItemsChanged(FileStore::Job *job, const Item::List &items) { - FileStore::StoreCompactJob *compactJob = dynamic_cast( job ); - if ( compactJob != 0 ) { - compactJob->handleItemsChanged( items ); - } + FileStore::StoreCompactJob *compactJob = dynamic_cast(job); + if (compactJob != Q_NULLPTR) { + compactJob->handleItemsChanged(items); + } } -void FileStore::AbstractJobSession::setError( FileStore::Job *job, int errorCode, const QString& errorText ) +void FileStore::AbstractJobSession::setError(FileStore::Job *job, int errorCode, const QString &errorText) { - job->setError( errorCode ); - job->setErrorText( errorText ); + job->setError(errorCode); + job->setErrorText(errorText); } -void FileStore::AbstractJobSession::emitResult( FileStore::Job *job ) +void FileStore::AbstractJobSession::emitResult(FileStore::Job *job) { - removeJob( job ); + removeJob(job); - job->emitResult(); + job->emitResult(); } -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/sessionimpls.cpp kdepim-runtime-15.08.0/resources/shared/filestore/sessionimpls.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/sessionimpls.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/sessionimpls.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -31,7 +31,7 @@ #include "itemmovejob.h" #include "storecompactjob.h" -#include +#include #include #include @@ -40,164 +40,162 @@ class AbstractEnqueueVisitor : public FileStore::Job::Visitor { - public: - bool visit( FileStore::Job *job ) { - enqueue( job, "Job" ); - return true; +public: + bool visit(FileStore::Job *job) Q_DECL_OVERRIDE { + enqueue(job, "Job"); + return true; } - bool visit( FileStore::CollectionCreateJob *job ) { - enqueue( job, "CollectionCreateJob" ); - return true; + bool visit(FileStore::CollectionCreateJob *job) Q_DECL_OVERRIDE { + enqueue(job, "CollectionCreateJob"); + return true; } - bool visit( FileStore::CollectionDeleteJob *job ) { - enqueue( job, "CollectionDeleteJob" ); - return true; + bool visit(FileStore::CollectionDeleteJob *job) Q_DECL_OVERRIDE { + enqueue(job, "CollectionDeleteJob"); + return true; } - bool visit( FileStore::CollectionFetchJob *job ) { - enqueue( job, "CollectionFetchJob" ); - return true; + bool visit(FileStore::CollectionFetchJob *job) Q_DECL_OVERRIDE { + enqueue(job, "CollectionFetchJob"); + return true; } - bool visit( FileStore::CollectionModifyJob *job ) { - enqueue( job, "CollectionModifyJob" ); - return true; + bool visit(FileStore::CollectionModifyJob *job) Q_DECL_OVERRIDE { + enqueue(job, "CollectionModifyJob"); + return true; } - bool visit( FileStore::CollectionMoveJob *job ) { - enqueue( job, "CollectionMoveJob" ); - return true; + bool visit(FileStore::CollectionMoveJob *job) Q_DECL_OVERRIDE { + enqueue(job, "CollectionMoveJob"); + return true; } - bool visit( FileStore::ItemCreateJob *job ) { - enqueue( job, "ItemCreateJob" ); - return true; + bool visit(FileStore::ItemCreateJob *job) Q_DECL_OVERRIDE { + enqueue(job, "ItemCreateJob"); + return true; } - bool visit( FileStore::ItemDeleteJob *job ) { - enqueue( job, "ItemDeleteJob" ); - return true; + bool visit(FileStore::ItemDeleteJob *job) Q_DECL_OVERRIDE { + enqueue(job, "ItemDeleteJob"); + return true; } - bool visit( FileStore::ItemFetchJob *job ) { - enqueue( job, "ItemFetchJob" ); - return true; + bool visit(FileStore::ItemFetchJob *job) Q_DECL_OVERRIDE { + enqueue(job, "ItemFetchJob"); + return true; } - bool visit( FileStore::ItemModifyJob *job ) { - enqueue( job, "ItemModifyJob" ); - return true; + bool visit(FileStore::ItemModifyJob *job) Q_DECL_OVERRIDE { + enqueue(job, "ItemModifyJob"); + return true; } - bool visit( FileStore::ItemMoveJob *job ) { - enqueue( job, "ItemMoveJob" ); - return true; + bool visit(FileStore::ItemMoveJob *job) Q_DECL_OVERRIDE { + enqueue(job, "ItemMoveJob"); + return true; } - bool visit( FileStore::StoreCompactJob *job ) { - enqueue( job, "StoreCompactJob" ); - return true; + bool visit(FileStore::StoreCompactJob *job) Q_DECL_OVERRIDE { + enqueue(job, "StoreCompactJob"); + return true; } - protected: - virtual void enqueue( FileStore::Job *job, const char* className ) = 0; +protected: + virtual void enqueue(FileStore::Job *job, const char *className) = 0; }; class FileStore::FiFoQueueJobSession::Private : public AbstractEnqueueVisitor { - public: - explicit Private( FileStore::FiFoQueueJobSession *parent ) - : mParent( parent ) +public: + explicit Private(FileStore::FiFoQueueJobSession *parent) + : mParent(parent) { - QObject::connect( &mJobRunTimer, SIGNAL(timeout()), mParent, SLOT(runNextJob()) ); + QObject::connect(&mJobRunTimer, SIGNAL(timeout()), mParent, SLOT(runNextJob())); } void runNextJob() { -/* kDebug() << "Queue with" << mJobQueue.count() << "entries";*/ - if ( mJobQueue.isEmpty() ) { - mJobRunTimer.stop(); - return; - } - - FileStore::Job *job = mJobQueue.dequeue(); - while ( job != 0 && job->error() != 0 ) { -/* kDebug() << "Dequeued job" << job << "has error (" - << job->error() << "," << job->errorText() << ")";*/ - mParent->emitResult( job ); - if ( !mJobQueue.isEmpty() ) { - job = mJobQueue.dequeue(); - } else { - job = 0; + /* qDebug() << "Queue with" << mJobQueue.count() << "entries";*/ + if (mJobQueue.isEmpty()) { + mJobRunTimer.stop(); + return; + } + + FileStore::Job *job = mJobQueue.dequeue(); + while (job != Q_NULLPTR && job->error() != 0) { + /* qDebug() << "Dequeued job" << job << "has error (" + << job->error() << "," << job->errorText() << ")";*/ + mParent->emitResult(job); + if (!mJobQueue.isEmpty()) { + job = mJobQueue.dequeue(); + } else { + job = Q_NULLPTR; + } } - } - if ( job != 0 ) { -/* kDebug() << "Dequeued job" << job << "is ready";*/ - QList jobs; - jobs << job; - - emit mParent->jobsReady( jobs ); - } else { -/* kDebug() << "Queue now empty";*/ - mJobRunTimer.stop(); - } + if (job != Q_NULLPTR) { + /* qDebug() << "Dequeued job" << job << "is ready";*/ + QList jobs; + jobs << job; + + Q_EMIT mParent->jobsReady(jobs); + } else { + /* qDebug() << "Queue now empty";*/ + mJobRunTimer.stop(); + } } - public: - QQueue mJobQueue; +public: + QQueue mJobQueue; QTimer mJobRunTimer; - protected: - virtual void enqueue( FileStore::Job *job, const char* className ) - { - Q_UNUSED( className ); - mJobQueue.enqueue( job ); +protected: + virtual void enqueue(FileStore::Job *job, const char *className) Q_DECL_OVERRIDE { + Q_UNUSED(className); + mJobQueue.enqueue(job); -// kDebug() << "adding" << className << ". Queue now with" +// qDebug() << "adding" << className << ". Queue now with" // << mJobQueue.count() << "entries"; - mJobRunTimer.start( 0 ); + mJobRunTimer.start(0); } - private: +private: FileStore::FiFoQueueJobSession *mParent; }; -FileStore::FiFoQueueJobSession::FiFoQueueJobSession( QObject *parent ) - : FileStore::AbstractJobSession( parent ), d( new Private( this ) ) +FileStore::FiFoQueueJobSession::FiFoQueueJobSession(QObject *parent) + : FileStore::AbstractJobSession(parent), d(new Private(this)) { } FileStore::FiFoQueueJobSession::~FiFoQueueJobSession() { - cancelAllJobs(); - delete d; + cancelAllJobs(); + delete d; } -void FileStore::FiFoQueueJobSession::addJob( FileStore::Job *job ) +void FileStore::FiFoQueueJobSession::addJob(FileStore::Job *job) { - job->accept( d ); + job->accept(d); } void FileStore::FiFoQueueJobSession::cancelAllJobs() { - // KJob::kill() also deletes the job - foreach( FileStore::Job *job, d->mJobQueue ) { - job->kill( KJob::EmitResult ); - } + // KJob::kill() also deletes the job + foreach (FileStore::Job *job, d->mJobQueue) { + job->kill(KJob::EmitResult); + } - d->mJobQueue.clear(); + d->mJobQueue.clear(); } -void FileStore::FiFoQueueJobSession::removeJob( FileStore::Job *job ) +void FileStore::FiFoQueueJobSession::removeJob(FileStore::Job *job) { - d->mJobQueue.removeAll( job ); + d->mJobQueue.removeAll(job); } #include "moc_sessionimpls_p.cpp" -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/sessionimpls_p.h kdepim-runtime-15.08.0/resources/shared/filestore/sessionimpls_p.h --- kdepim-runtime-4.14.6/resources/shared/filestore/sessionimpls_p.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/sessionimpls_p.h 2015-08-10 21:01:02.000000000 +0000 @@ -32,25 +32,25 @@ */ class FiFoQueueJobSession : public AbstractJobSession { - Q_OBJECT + Q_OBJECT - public: - explicit FiFoQueueJobSession( QObject *parent = 0 ); +public: + explicit FiFoQueueJobSession(QObject *parent = Q_NULLPTR); virtual ~FiFoQueueJobSession(); - virtual void addJob( Job *job ); + void addJob(Job *job) Q_DECL_OVERRIDE; - virtual void cancelAllJobs(); + void cancelAllJobs() Q_DECL_OVERRIDE; - protected: - virtual void removeJob( Job *job ); +protected: + void removeJob(Job *job) Q_DECL_OVERRIDE; - private: +private: class Private; Private *const d; - Q_PRIVATE_SLOT( d, void runNextJob() ) + Q_PRIVATE_SLOT(d, void runNextJob()) }; } @@ -58,4 +58,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/session_p.h kdepim-runtime-15.08.0/resources/shared/filestore/session_p.h --- kdepim-runtime-4.14.6/resources/shared/filestore/session_p.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/session_p.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,8 +20,8 @@ #ifndef AKONADI_FILESTORE_SESSION_P_H #define AKONADI_FILESTORE_SESSION_P_H -#include -#include +#include +#include #include @@ -37,48 +37,48 @@ */ class AbstractJobSession : public QObject { - Q_OBJECT + Q_OBJECT - public: - explicit AbstractJobSession( QObject *parent = 0 ); +public: + explicit AbstractJobSession(QObject *parent = Q_NULLPTR); virtual ~AbstractJobSession(); - virtual void addJob( Job *job ) = 0; + virtual void addJob(Job *job) = 0; virtual void cancelAllJobs() = 0; - void notifyCollectionsReceived( Job *job, const Collection::List &collections ); + void notifyCollectionsReceived(Job *job, const Collection::List &collections); - void notifyCollectionCreated( Job *job, const Collection &collection ); + void notifyCollectionCreated(Job *job, const Collection &collection); - void notifyCollectionDeleted( Job *job, const Collection &collection ); + void notifyCollectionDeleted(Job *job, const Collection &collection); - void notifyCollectionModified( Job *job, const Collection &collection ); + void notifyCollectionModified(Job *job, const Collection &collection); - void notifyCollectionMoved( Job *job, const Collection &collection ); + void notifyCollectionMoved(Job *job, const Collection &collection); - void notifyItemsReceived( Job *job, const Item::List &items ); + void notifyItemsReceived(Job *job, const Item::List &items); - void notifyItemCreated( Job *job, const Item &item ); + void notifyItemCreated(Job *job, const Item &item); - void notifyItemModified( Job *job, const Item &item ); + void notifyItemModified(Job *job, const Item &item); - void notifyItemMoved( Job *job, const Item &item ); + void notifyItemMoved(Job *job, const Item &item); - void notifyCollectionsChanged( Job *job, const Collection::List &collections ); + void notifyCollectionsChanged(Job *job, const Collection::List &collections); - void notifyItemsChanged( Job *job, const Item::List &items ); + void notifyItemsChanged(Job *job, const Item::List &items); - void setError( Job *job, int errorCode, const QString& errorText ); + void setError(Job *job, int errorCode, const QString &errorText); - void emitResult( Job *job ); + void emitResult(Job *job); - Q_SIGNALS: - void jobsReady( const QList &jobs ); +Q_SIGNALS: + void jobsReady(const QList &jobs); - protected: - virtual void removeJob( Job *job ) = 0; +protected: + virtual void removeJob(Job *job) = 0; }; } @@ -86,4 +86,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/storecompactjob.cpp kdepim-runtime-15.08.0/resources/shared/filestore/storecompactjob.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/storecompactjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/storecompactjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -25,56 +25,54 @@ class FileStore::StoreCompactJob::Private { - public: - explicit Private( FileStore::StoreCompactJob *parent ) - : mParent( parent ) +public: + explicit Private(FileStore::StoreCompactJob *parent) + : mParent(parent) { } - public: +public: FileStore::StoreCompactJob *mParent; Collection::List mCollections; Item::List mItems; }; -FileStore::StoreCompactJob::StoreCompactJob( FileStore::AbstractJobSession *session ) - : FileStore::Job( session ), d( new Private( this ) ) +FileStore::StoreCompactJob::StoreCompactJob(FileStore::AbstractJobSession *session) + : FileStore::Job(session), d(new Private(this)) { - session->addJob( this ); + session->addJob(this); } FileStore::StoreCompactJob::~StoreCompactJob() { - delete d; + delete d; } -bool FileStore::StoreCompactJob::accept( FileStore::Job::Visitor *visitor ) +bool FileStore::StoreCompactJob::accept(FileStore::Job::Visitor *visitor) { - return visitor->visit( this ); + return visitor->visit(this); } Item::List FileStore::StoreCompactJob::changedItems() const { - return d->mItems; + return d->mItems; } Collection::List FileStore::StoreCompactJob::changedCollections() const { - return d->mCollections; + return d->mCollections; } -void FileStore::StoreCompactJob::handleCollectionsChanged( const Collection::List &collections ) +void FileStore::StoreCompactJob::handleCollectionsChanged(const Collection::List &collections) { - d->mCollections << collections; - emit collectionsChanged( collections ); + d->mCollections << collections; + Q_EMIT collectionsChanged(collections); } -void FileStore::StoreCompactJob::handleItemsChanged( const Item::List &items ) +void FileStore::StoreCompactJob::handleItemsChanged(const Item::List &items) { - d->mItems << items; - emit itemsChanged( items ); + d->mItems << items; + Q_EMIT itemsChanged(items); } - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/storecompactjob.h kdepim-runtime-15.08.0/resources/shared/filestore/storecompactjob.h --- kdepim-runtime-4.14.6/resources/shared/filestore/storecompactjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/storecompactjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -22,8 +22,8 @@ #include "job.h" -#include -#include +#include +#include namespace Akonadi { @@ -35,30 +35,30 @@ */ class AKONADI_FILESTORE_EXPORT StoreCompactJob : public Job { - friend class AbstractJobSession; + friend class AbstractJobSession; - Q_OBJECT + Q_OBJECT - public: - explicit StoreCompactJob( AbstractJobSession *session = 0 ); +public: + explicit StoreCompactJob(AbstractJobSession *session = Q_NULLPTR); virtual ~StoreCompactJob(); - virtual bool accept( Visitor *visitor ); + bool accept(Visitor *visitor) Q_DECL_OVERRIDE; Item::List changedItems() const; Collection::List changedCollections() const; - Q_SIGNALS: - void collectionsChanged( const Akonadi::Collection::List &collections ); - void itemsChanged( const Akonadi::Item::List &items ); - - private: - void handleCollectionsChanged( const Collection::List &collections ); - void handleItemsChanged( const Item::List &items ); +Q_SIGNALS: + void collectionsChanged(const Akonadi::Collection::List &collections); + void itemsChanged(const Akonadi::Item::List &items); + +private: + void handleCollectionsChanged(const Collection::List &collections); + void handleItemsChanged(const Item::List &items); - private: +private: class Private; Private *d; }; @@ -68,4 +68,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/storeinterface.h kdepim-runtime-15.08.0/resources/shared/filestore/storeinterface.h --- kdepim-runtime-4.14.6/resources/shared/filestore/storeinterface.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/storeinterface.h 2015-08-10 21:01:02.000000000 +0000 @@ -27,58 +27,58 @@ namespace Akonadi { - class Collection; - class Item; +class Collection; +class Item; namespace FileStore { - class CollectionCreateJob; - class CollectionDeleteJob; - class CollectionFetchJob; - class CollectionModifyJob; - class CollectionMoveJob; - class ItemCreateJob; - class ItemDeleteJob; - class ItemFetchJob; - class ItemModifyJob; - class ItemMoveJob; - class StoreCompactJob; +class CollectionCreateJob; +class CollectionDeleteJob; +class CollectionFetchJob; +class CollectionModifyJob; +class CollectionMoveJob; +class ItemCreateJob; +class ItemDeleteJob; +class ItemFetchJob; +class ItemModifyJob; +class ItemMoveJob; +class StoreCompactJob; /** */ class AKONADI_FILESTORE_EXPORT StoreInterface { - public: +public: virtual ~StoreInterface() {} virtual Collection topLevelCollection() const = 0; - virtual CollectionCreateJob *createCollection( const Collection &collection, const Collection &targetParent ) = 0; + virtual CollectionCreateJob *createCollection(const Collection &collection, const Collection &targetParent) = 0; - virtual CollectionFetchJob *fetchCollections( const Collection &collection, CollectionFetchJob::Type type = CollectionFetchJob::FirstLevel ) const = 0; + virtual CollectionFetchJob *fetchCollections(const Collection &collection, CollectionFetchJob::Type type = CollectionFetchJob::FirstLevel) const = 0; - virtual CollectionDeleteJob *deleteCollection( const Collection &collection ) = 0; + virtual CollectionDeleteJob *deleteCollection(const Collection &collection) = 0; - virtual CollectionModifyJob *modifyCollection( const Collection &collection ) = 0; + virtual CollectionModifyJob *modifyCollection(const Collection &collection) = 0; - virtual CollectionMoveJob *moveCollection( const Collection &collection, const Collection &targetParent ) = 0; + virtual CollectionMoveJob *moveCollection(const Collection &collection, const Collection &targetParent) = 0; - virtual ItemFetchJob *fetchItems( const Collection &collection ) const = 0; + virtual ItemFetchJob *fetchItems(const Collection &collection) const = 0; - virtual ItemFetchJob *fetchItem( const Item &item ) const = 0; + virtual ItemFetchJob *fetchItem(const Item &item) const = 0; - virtual ItemCreateJob *createItem( const Item &item, const Collection &collection ) = 0; + virtual ItemCreateJob *createItem(const Item &item, const Collection &collection) = 0; - virtual ItemModifyJob *modifyItem( const Item &item ) = 0; + virtual ItemModifyJob *modifyItem(const Item &item) = 0; - virtual ItemDeleteJob *deleteItem( const Item &item ) = 0; + virtual ItemDeleteJob *deleteItem(const Item &item) = 0; - virtual ItemMoveJob *moveItem( const Item &item, const Collection &targetParent ) = 0; + virtual ItemMoveJob *moveItem(const Item &item, const Collection &targetParent) = 0; virtual StoreCompactJob *compactStore() = 0; - protected: - virtual void setTopLevelCollection( const Collection &collection ) = 0; +protected: + virtual void setTopLevelCollection(const Collection &collection) = 0; }; } @@ -86,4 +86,3 @@ #endif -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/tests/abstractlocalstoretest.cpp kdepim-runtime-15.08.0/resources/shared/filestore/tests/abstractlocalstoretest.cpp --- kdepim-runtime-4.14.6/resources/shared/filestore/tests/abstractlocalstoretest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/tests/abstractlocalstoretest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,969 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net - Author: Kevin Krammer, krake@kdab.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 "abstractlocalstore.h" - -#include "collectioncreatejob.h" -#include "collectiondeletejob.h" -#include "collectionfetchjob.h" -#include "collectionmodifyjob.h" -#include "collectionmovejob.h" -#include "itemcreatejob.h" -#include "itemdeletejob.h" -#include "itemfetchjob.h" -#include "itemmodifyjob.h" -#include "itemmovejob.h" -#include "sessionimpls_p.h" -#include "storecompactjob.h" - -#include - -#include - -using namespace Akonadi; -using namespace Akonadi::FileStore; - -class TestStore : public AbstractLocalStore -{ - Q_OBJECT - - public: - TestStore() : mLastCheckedJob( 0 ), mLastProcessedJob( 0 ), mErrorCode( 0 ) {} - - public: - mutable Akonadi::FileStore::Job *mLastCheckedJob; - Akonadi::FileStore::Job *mLastProcessedJob; - - Collection mTopLevelCollection; - - int mErrorCode; - QString mErrorText; - - protected: - void processJob( Akonadi::FileStore::Job *job ); - - protected: - void setTopLevelCollection( const Collection &collection ) - { - mTopLevelCollection = collection; - - Collection modifiedCollection = collection; - modifiedCollection.setContentMimeTypes( QStringList() << Collection::mimeType() ); - - AbstractLocalStore::setTopLevelCollection( modifiedCollection ); - } - - void checkCollectionCreate( Akonadi::FileStore::CollectionCreateJob *job, int &errorCode, QString &errorText ) const - { - mLastCheckedJob = job; - errorCode = mErrorCode; - errorText = mErrorText; - } - - void checkCollectionDelete( Akonadi::FileStore::CollectionDeleteJob *job, int &errorCode, QString &errorText ) const - { - mLastCheckedJob = job; - errorCode = mErrorCode; - errorText = mErrorText; - } - - void checkCollectionFetch( Akonadi::FileStore::CollectionFetchJob *job, int &errorCode, QString &errorText ) const - { - mLastCheckedJob = job; - errorCode = mErrorCode; - errorText = mErrorText; - } - - void checkCollectionModify( Akonadi::FileStore::CollectionModifyJob *job, int &errorCode, QString &errorText ) const - { - mLastCheckedJob = job; - errorCode = mErrorCode; - errorText = mErrorText; - } - - void checkCollectionMove( Akonadi::FileStore::CollectionMoveJob *job, int &errorCode, QString &errorText ) const - { - mLastCheckedJob = job; - errorCode = mErrorCode; - errorText = mErrorText; - } - - void checkItemCreate( Akonadi::FileStore::ItemCreateJob *job, int &errorCode, QString &errorText ) const - { - mLastCheckedJob = job; - errorCode = mErrorCode; - errorText = mErrorText; - } - - void checkItemDelete( Akonadi::FileStore::ItemDeleteJob *job, int &errorCode, QString &errorText ) const - { - mLastCheckedJob = job; - errorCode = mErrorCode; - errorText = mErrorText; - } - - void checkItemFetch( Akonadi::FileStore::ItemFetchJob *job, int &errorCode, QString &errorText ) const - { - mLastCheckedJob = job; - errorCode = mErrorCode; - errorText = mErrorText; - } - - void checkItemModify( Akonadi::FileStore::ItemModifyJob *job, int &errorCode, QString &errorText ) const - { - mLastCheckedJob = job; - errorCode = mErrorCode; - errorText = mErrorText; - } - - void checkItemMove( Akonadi::FileStore::ItemMoveJob *job, int &errorCode, QString &errorText ) const - { - mLastCheckedJob = job; - errorCode = mErrorCode; - errorText = mErrorText; - } - - void checkStoreCompact( Akonadi::FileStore::StoreCompactJob *job, int &errorCode, QString &errorText ) const - { - mLastCheckedJob = job; - errorCode = mErrorCode; - errorText = mErrorText; - } -}; - -void TestStore::processJob( Akonadi::FileStore::Job *job ) -{ - mLastProcessedJob = job; - - QCOMPARE( currentJob(), job ); - QVERIFY( job->error() == 0 ); - - if ( mErrorCode != 0 ) { - notifyError( mErrorCode, mErrorText ); - } -} - -class AbstractLocalStoreTest : public QObject -{ - Q_OBJECT - - public: - AbstractLocalStoreTest() : QObject(), mStore( 0 ) {} - ~AbstractLocalStoreTest() { delete mStore; } - - private: - TestStore *mStore; - - private Q_SLOTS: - void init(); - void testSetPath(); - void testCreateCollection(); - void testDeleteCollection(); - void testFetchCollection(); - void testModifyCollection(); - void testMoveCollection(); - void testFetchItems(); - void testFetchItem(); - void testCreateItem(); - void testDeleteItem(); - void testModifyItem(); - void testMoveItem(); - void testCompactStore(); -}; - -void AbstractLocalStoreTest::init() -{ - delete mStore; - mStore = new TestStore; -} - -void AbstractLocalStoreTest::testSetPath() -{ - const QString file = KRandom::randomString( 10 ); - const QString path = QLatin1String( "/tmp/test/" ) + file; - - // check that setTopLevelCollection() has been called - mStore->setPath( path ); - QCOMPARE( mStore->mTopLevelCollection.remoteId(), path ); - - // check that the modified collection is the one returned by topLevelCollection() - QVERIFY( mStore->mTopLevelCollection.contentMimeTypes().isEmpty() ); - QCOMPARE( mStore->topLevelCollection().remoteId(), path ); - QCOMPARE( mStore->topLevelCollection().contentMimeTypes(), QStringList() << Collection::mimeType() ); - QCOMPARE( mStore->topLevelCollection().name(), file ); - - // check that calling with the same path again, does not call the template method - mStore->mTopLevelCollection = Collection(); - mStore->setPath( path ); - QVERIFY( mStore->mTopLevelCollection.remoteId().isEmpty() ); - QCOMPARE( mStore->topLevelCollection().remoteId(), path ); - QCOMPARE( mStore->topLevelCollection().contentMimeTypes(), QStringList() << Collection::mimeType() ); - QCOMPARE( mStore->topLevelCollection().name(), file ); - - // check that calling with a different path works like the first call - const QString file2 = KRandom::randomString( 10 ); - const QString path2 = QLatin1String( "/tmp/test2/" ) + file2; - - mStore->setPath( path2 ); - QCOMPARE( mStore->mTopLevelCollection.remoteId(), path2 ); - QCOMPARE( mStore->topLevelCollection().remoteId(), path2 ); - QCOMPARE( mStore->topLevelCollection().contentMimeTypes(), QStringList() << Collection::mimeType() ); - QCOMPARE( mStore->topLevelCollection().name(), file2 ); -} - -void AbstractLocalStoreTest::testCreateCollection() -{ - CollectionCreateJob *job = 0; - - // test without setPath() - job = mStore->createCollection( Collection(), Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with path but with invalid collections - mStore->setPath( QLatin1String( "/tmp/test" ) ); - job = mStore->createCollection( Collection(), Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with potentially valid collection (has remoteId), but invalid target parent - Collection collection; - collection.setRemoteId( QLatin1String( "/tmp/test/foo" ) ); - job = mStore->createCollection( collection, Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with potentially valid collections - Collection targetParent; - targetParent.setRemoteId( QLatin1String( "/tmp/test2" ) ); - job = mStore->createCollection( collection, targetParent ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - - QVERIFY( job->exec() ); - QCOMPARE( mStore->mLastProcessedJob, job ); - mStore->mLastProcessedJob = 0; - - // test template check method - mStore->mErrorCode = KRandom::random() + 1; - mStore->mErrorText = KRandom::randomString( 10 ); - - job = mStore->createCollection( collection, targetParent ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), mStore->mErrorCode ); - QCOMPARE( job->errorText(), mStore->mErrorText ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - mStore->mErrorCode = 0; - mStore->mErrorText = QString(); -} - -void AbstractLocalStoreTest::testDeleteCollection() -{ - CollectionDeleteJob *job = 0; - - // test without setPath() - job = mStore->deleteCollection( Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with path but with invalid collection - mStore->setPath( QLatin1String( "/tmp/test" ) ); - job = mStore->deleteCollection( Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with ivalid collection (has remoteId, but no parent collection remoteId) - Collection collection; - collection.setRemoteId( QLatin1String( "/tmp/test/foo" ) ); - job = mStore->deleteCollection( collection ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with potentially valid collection (has remoteId and parent collection remoteId) - Collection parentCollection; - parentCollection.setRemoteId( QLatin1String( "/tmp/test" ) ); - collection.setParentCollection( parentCollection ); - job = mStore->deleteCollection( collection ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - - QVERIFY( job->exec() ); - QCOMPARE( mStore->mLastProcessedJob, job ); - mStore->mLastProcessedJob = 0; - - // test template check method - mStore->mErrorCode = KRandom::random() + 1; - mStore->mErrorText = KRandom::randomString( 10 ); - - job = mStore->deleteCollection( collection ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), mStore->mErrorCode ); - QCOMPARE( job->errorText(), mStore->mErrorText ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - mStore->mErrorCode = 0; - mStore->mErrorText = QString(); -} - -void AbstractLocalStoreTest::testFetchCollection() -{ - Akonadi::FileStore::CollectionFetchJob *job = 0; - - // test without setPath() - job = mStore->fetchCollections( Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with path but with invalid collection - mStore->setPath( QLatin1String( "/tmp/test" ) ); - job = mStore->fetchCollections( Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with potentially valid collection (has remoteId) - Collection collection; - collection.setRemoteId( QLatin1String( "/tmp/test/foo" ) ); - job = mStore->fetchCollections( collection ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - - QVERIFY( job->exec() ); - QCOMPARE( mStore->mLastProcessedJob, job ); - mStore->mLastProcessedJob = 0; - - // test template check method - mStore->mErrorCode = KRandom::random() + 1; - mStore->mErrorText = KRandom::randomString( 10 ); - - job = mStore->fetchCollections( collection ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), mStore->mErrorCode ); - QCOMPARE( job->errorText(), mStore->mErrorText ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - mStore->mErrorCode = 0; - mStore->mErrorText = QString(); - - // test fetch of top level collection only - collection.setRemoteId( mStore->topLevelCollection().remoteId() ); - job = mStore->fetchCollections( collection, Akonadi::FileStore::CollectionFetchJob::Base ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - - QVERIFY( job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); // job not handed to subclass because it is full processed in base class - QCOMPARE( job->collections().count(), 1 ); - QCOMPARE( job->collections()[ 0 ], mStore->topLevelCollection() ); -} - -void AbstractLocalStoreTest::testModifyCollection() -{ - Akonadi::FileStore::CollectionModifyJob *job = 0; - - // test without setPath() - job = mStore->modifyCollection( Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with path but with invalid item - mStore->setPath( QLatin1String( "/tmp/test" ) ); - job = mStore->modifyCollection( Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with potentially valid collection (has remoteId, but no parent remoteId) - Collection collection; - collection.setRemoteId( QLatin1String( "/tmp/test/foo" ) ); - job = mStore->modifyCollection( collection ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - - QVERIFY( job->exec() ); - QCOMPARE( mStore->mLastProcessedJob, job ); - mStore->mLastProcessedJob = 0; - - // test with potentially valid collection (has remoteId and parent remoteId) - Collection parentCollection; - parentCollection.setRemoteId( QLatin1String( "/tmp/test" ) ); - collection.setParentCollection( parentCollection ); - job = mStore->modifyCollection( collection ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - - QVERIFY( job->exec() ); - QCOMPARE( mStore->mLastProcessedJob, job ); - mStore->mLastProcessedJob = 0; - - // test template check method - mStore->mErrorCode = KRandom::random() + 1; - mStore->mErrorText = KRandom::randomString( 10 ); - - job = mStore->modifyCollection( collection ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), mStore->mErrorCode ); - QCOMPARE( job->errorText(), mStore->mErrorText ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); -} - -void AbstractLocalStoreTest::testMoveCollection() -{ - CollectionMoveJob *job = 0; - - // test without setPath() - job = mStore->moveCollection( Collection(), Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with path but with invalid collections - mStore->setPath( QLatin1String( "/tmp/test" ) ); - job = mStore->moveCollection( Collection(), Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with potentially valid collection (has remoteId and parent remoteId), but invalid target parent - Collection collection; - collection.setRemoteId( QLatin1String( "/tmp/test/foo" ) ); - Collection parentCollection; - parentCollection.setRemoteId( QLatin1String( "/tmp/test" ) ); - collection.setParentCollection( parentCollection ); - job = mStore->moveCollection( collection, Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with invalid parent collection, but with potentially valid collection and target parent - collection.setParentCollection( Collection() ); - job = mStore->moveCollection( collection, parentCollection ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with potentially valid collections - Collection targetParent; - targetParent.setRemoteId( QLatin1String( "/tmp/test2" ) ); - collection.setParentCollection( parentCollection ); - job = mStore->moveCollection( collection, targetParent ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - - QVERIFY( job->exec() ); - QCOMPARE( mStore->mLastProcessedJob, job ); - mStore->mLastProcessedJob = 0; - - // test template check method - mStore->mErrorCode = KRandom::random() + 1; - mStore->mErrorText = KRandom::randomString( 10 ); - - job = mStore->moveCollection( collection, targetParent ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), mStore->mErrorCode ); - QCOMPARE( job->errorText(), mStore->mErrorText ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); -} - -void AbstractLocalStoreTest::testFetchItems() -{ - ItemFetchJob *job = 0; - - // test without setPath() - job = mStore->fetchItems( Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with path but with invalid collection - mStore->setPath( QLatin1String( "/tmp/test" ) ); - job = mStore->fetchItems( Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with potentially valid collection (has remoteId) - Collection collection; - collection.setRemoteId( QLatin1String( "/tmp/test/foo" ) ); - job = mStore->fetchItems( collection ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - - QVERIFY( job->exec() ); - QCOMPARE( mStore->mLastProcessedJob, job ); - mStore->mLastProcessedJob = 0; - - // test template check method - mStore->mErrorCode = KRandom::random() + 1; - mStore->mErrorText = KRandom::randomString( 10 ); - - job = mStore->fetchItems( collection ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), mStore->mErrorCode ); - QCOMPARE( job->errorText(), mStore->mErrorText ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - mStore->mErrorCode = 0; - mStore->mErrorText = QString(); -} - -void AbstractLocalStoreTest::testFetchItem() -{ - ItemFetchJob *job = 0; - - // test without setPath() - job = mStore->fetchItem( Item() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with path but with invalid item - mStore->setPath( QLatin1String( "/tmp/test" ) ); - job = mStore->fetchItem( Item() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with potentially valid item (has remoteId) - Item item; - item.setRemoteId( QLatin1String( "/tmp/test/foo" ) ); - job = mStore->fetchItem( item ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - - QVERIFY( job->exec() ); - QCOMPARE( mStore->mLastProcessedJob, job ); - mStore->mLastProcessedJob = 0; - - // test template check method - mStore->mErrorCode = KRandom::random() + 1; - mStore->mErrorText = KRandom::randomString( 10 ); - - job = mStore->fetchItem( item ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), mStore->mErrorCode ); - QCOMPARE( job->errorText(), mStore->mErrorText ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - mStore->mErrorCode = 0; - mStore->mErrorText = QString(); -} - -void AbstractLocalStoreTest::testCreateItem() -{ - Akonadi::FileStore::ItemCreateJob *job = 0; - - // test without setPath() - job = mStore->createItem( Item(), Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with path but with invalid collection - mStore->setPath( QLatin1String( "/tmp/test" ) ); - job = mStore->createItem( Item(), Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with potentially valid collection (has remoteId) - Collection collection; - collection.setRemoteId( QLatin1String( "/tmp/test/foo" ) ); - job = mStore->createItem( Item(), collection ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - - QVERIFY( job->exec() ); - QCOMPARE( mStore->mLastProcessedJob, job ); - mStore->mLastProcessedJob = 0; - - // test template check method - mStore->mErrorCode = KRandom::random() + 1; - mStore->mErrorText = KRandom::randomString( 10 ); - - job = mStore->createItem( Item(), collection ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), mStore->mErrorCode ); - QCOMPARE( job->errorText(), mStore->mErrorText ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - mStore->mErrorCode = 0; - mStore->mErrorText = QString(); -} - -void AbstractLocalStoreTest::testDeleteItem() -{ - ItemDeleteJob *job = 0; - - // test without setPath() - job = mStore->deleteItem( Item() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with path but with invalid item - mStore->setPath( QLatin1String( "/tmp/test" ) ); - job = mStore->deleteItem( Item() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with potentially valid item (has remoteId) - Item item; - item.setRemoteId( QLatin1String( "/tmp/test/foo" ) ); - job = mStore->deleteItem( item ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - - QVERIFY( job->exec() ); - QCOMPARE( mStore->mLastProcessedJob, job ); - mStore->mLastProcessedJob = 0; - - // test template check method - mStore->mErrorCode = KRandom::random() + 1; - mStore->mErrorText = KRandom::randomString( 10 ); - - job = mStore->deleteItem( item ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), mStore->mErrorCode ); - QCOMPARE( job->errorText(), mStore->mErrorText ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - mStore->mErrorCode = 0; - mStore->mErrorText = QString(); -} - -void AbstractLocalStoreTest::testModifyItem() -{ - Akonadi::FileStore::ItemModifyJob *job = 0; - - // test without setPath() - job = mStore->modifyItem( Item() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with path but with invalid item - mStore->setPath( QLatin1String( "/tmp/test" ) ); - job = mStore->modifyItem( Item() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with potentially valid item (has remoteId) - Item item; - item.setRemoteId( QLatin1String( "/tmp/test/foo" ) ); - job = mStore->modifyItem( item ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - - QVERIFY( job->exec() ); - QCOMPARE( mStore->mLastProcessedJob, job ); - mStore->mLastProcessedJob = 0; - - // test template check method - mStore->mErrorCode = KRandom::random() + 1; - mStore->mErrorText = KRandom::randomString( 10 ); - - job = mStore->modifyItem( item ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), mStore->mErrorCode ); - QCOMPARE( job->errorText(), mStore->mErrorText ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); -} - -void AbstractLocalStoreTest::testMoveItem() -{ - ItemMoveJob *job = 0; - - // test without setPath() - job = mStore->moveItem( Item(), Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with path but with invalid item and collection - mStore->setPath( QLatin1String( "/tmp/test" ) ); - job = mStore->moveItem( Item(), Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with potentially valid item (has remoteId and parent remoteId), but invalid target parent - Item item; - item.setRemoteId( QLatin1String( "/tmp/test/foo" ) ); - Collection parentCollection; - parentCollection.setRemoteId( QLatin1String( "/tmp/test" ) ); - item.setParentCollection( parentCollection ); - job = mStore->moveItem( item, Collection() ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with invalid parent collection, but with potentially valid item and target parent - item.setParentCollection( Collection() ); - job = mStore->moveItem( item, parentCollection ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidJobContext ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with potentially valid item and collections - Collection targetParent; - targetParent.setRemoteId( QLatin1String( "/tmp/test2" ) ); - item.setParentCollection( parentCollection ); - job = mStore->moveItem( item, targetParent ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - - QVERIFY( job->exec() ); - QCOMPARE( mStore->mLastProcessedJob, job ); - mStore->mLastProcessedJob = 0; - - // test template check method - mStore->mErrorCode = KRandom::random() + 1; - mStore->mErrorText = KRandom::randomString( 10 ); - - job = mStore->moveItem( item, targetParent ); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), mStore->mErrorCode ); - QCOMPARE( job->errorText(), mStore->mErrorText ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); -} - -void AbstractLocalStoreTest::testCompactStore() -{ - StoreCompactJob *job = 0; - - // test without setPath() - job = mStore->compactStore(); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), (int)Akonadi::FileStore::Job::InvalidStoreState ); - QVERIFY( !job->errorText().isEmpty() ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - - // test with path - mStore->setPath( QLatin1String( "/tmp/test" ) ); - job = mStore->compactStore(); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), 0 ); - QVERIFY( job->errorText().isEmpty() ); - - QVERIFY( job->exec() ); - QCOMPARE( mStore->mLastProcessedJob, job ); - mStore->mLastProcessedJob = 0; - - // test template check method - mStore->mErrorCode = KRandom::random() + 1; - mStore->mErrorText = KRandom::randomString( 10 ); - - job = mStore->compactStore(); - QVERIFY( job != 0 ); - QCOMPARE( mStore->mLastCheckedJob, job ); - QCOMPARE( job->error(), mStore->mErrorCode ); - QCOMPARE( job->errorText(), mStore->mErrorText ); - - QVERIFY( !job->exec() ); - QVERIFY( mStore->mLastProcessedJob == 0 ); - mStore->mErrorCode = 0; - mStore->mErrorText = QString(); -} - -QTEST_KDEMAIN( AbstractLocalStoreTest, NoGUI ) - -#include "abstractlocalstoretest.moc" - -// kate: space-indent on; indent-width 2; replace-tabs on; diff -Nru kdepim-runtime-4.14.6/resources/shared/filestore/tests/CMakeLists.txt kdepim-runtime-15.08.0/resources/shared/filestore/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/shared/filestore/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/filestore/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -if(${EXECUTABLE_OUTPUT_PATH}) - set( PREVIOUS_EXEC_OUTPUT_PATH ${EXECUTABLE_OUTPUT_PATH} ) -else() - set( PREVIOUS_EXEC_OUTPUT_PATH . ) -endif() -set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) - -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - -include_directories( - ${AKONADI_INCLUDE_DIR} - ${KDE4_INCLUDES} - ${KDEPIMLIBS_INCLUDE_DIR} - ${QT_INCLUDES} - ${Boost_INCLUDE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../ - ${CMAKE_CURRENT_BINARY_DIR}/../ - ${CMAKE_CURRENT_SOURCE_DIR} -) - -kde4_add_unit_test( abstractlocalstoretest abstractlocalstoretest.cpp ) -target_link_libraries( - abstractlocalstoretest - akonadi-filestore - ${KDEPIMLIBS_AKONADI_LIBS} - ${QT_QTTEST_LIBRARY} -) diff -Nru kdepim-runtime-4.14.6/resources/shared/getcredentialsjob.cpp kdepim-runtime-15.08.0/resources/shared/getcredentialsjob.cpp --- kdepim-runtime-4.14.6/resources/shared/getcredentialsjob.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/getcredentialsjob.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ -/************************************************************************************* - * Copyright (C) 2013 by Alejandro Fiestas Olivares * - * * - * 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 KDE e.V's discretion) 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 "getcredentialsjob.h" - -#include -#include -#include - -#include - -#include -#include - -GetCredentialsJob::GetCredentialsJob(const Accounts::AccountId &id, QObject *parent) -: KJob(parent) -, m_id(id) -, m_manager(new Accounts::Manager(this)) -{ - -} - -void GetCredentialsJob::start() -{ - QMetaObject::invokeMethod(this, "getCredentials", Qt::QueuedConnection); -} - -void GetCredentialsJob::setServiceType(const QString &serviceType) -{ - m_serviceType = serviceType; -} - -void GetCredentialsJob::getCredentials() -{ - Accounts::Account *acc = m_manager->account(m_id); - if (!acc) { - setError(-1); - setErrorText(i18n("Could not find account")); - emitResult(); - return; - } - Accounts::AccountService *service = new Accounts::AccountService(acc, m_manager->service(m_serviceType), this); - - Accounts::AuthData authData = service->authData(); - m_authData = authData.parameters(); - SignOn::Identity *identity = SignOn::Identity::existingIdentity(authData.credentialsId(), this); - - if (!identity) { - setError(-1); - setErrorText(i18n("Could not find credentials")); - emitResult(); - return; - } - - m_authData[QLatin1String("AccountUsername")] = acc->value(QLatin1String("username")).toString(); - QPointer authSession = identity->createSession(authData.method()); - - connect(authSession, SIGNAL(response(SignOn::SessionData)), - SLOT(sessionResponse(SignOn::SessionData))); - connect(authSession, SIGNAL(error(SignOn::Error)), - SLOT(sessionError(SignOn::Error))); - - authSession->process(authData.parameters(), authData.mechanism()); -} - -void GetCredentialsJob::sessionResponse(const SignOn::SessionData &data) -{ - m_sessionData = data; - emitResult(); -} - -void GetCredentialsJob::sessionError(const SignOn::Error &error) -{ - kDebug() << error.message(); - setError(-1); - setErrorText(error.message()); - emitResult(); -} - -Accounts::AccountId GetCredentialsJob::accountId() const -{ - return m_id; -} - -QVariantMap GetCredentialsJob::credentialsData() const -{ - return m_sessionData.toMap().unite(m_authData); -} diff -Nru kdepim-runtime-4.14.6/resources/shared/getcredentialsjob.h kdepim-runtime-15.08.0/resources/shared/getcredentialsjob.h --- kdepim-runtime-4.14.6/resources/shared/getcredentialsjob.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/getcredentialsjob.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -/************************************************************************************* - * Copyright (C) 2013 by Alejandro Fiestas Olivares * - * * - * 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 KDE e.V's discretion) 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 GET_CREDENTIALS_JOB_H -#define GET_CREDENTIALS_JOB_H - -#include - -#include -#include -#include - -namespace Accounts { - class Manager; -}; -namespace SignOn { - class Error; -}; - -class GetCredentialsJob : public KJob -{ - Q_OBJECT -public: - explicit GetCredentialsJob(const Accounts::AccountId &id, QObject *parent = 0); - virtual void start(); - - void setServiceType(const QString &serviceType); - - QVariantMap credentialsData() const; - Accounts::AccountId accountId() const; - -private Q_SLOTS: - void getCredentials(); - void sessionResponse(const SignOn::SessionData &data); - void sessionError(const SignOn::Error &error); - -private: - QString m_serviceType; - Accounts::AccountId m_id; - QVariantMap m_authData; - Accounts::Manager *m_manager; - SignOn::SessionData m_sessionData; -}; - -#endif //GET_CREDENTIALS_JOB_H diff -Nru kdepim-runtime-4.14.6/resources/shared/imapaclattribute.cpp kdepim-runtime-15.08.0/resources/shared/imapaclattribute.cpp --- kdepim-runtime-4.14.6/resources/shared/imapaclattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/imapaclattribute.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -/* - Copyright (C) 2009 Kevin Ottens - - 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 "imapaclattribute.h" - -#include - -using namespace Akonadi; - -ImapAclAttribute::ImapAclAttribute() -{ -} - -ImapAclAttribute::ImapAclAttribute( const QMap &rights, - const QMap &oldRights ) - : mRights( rights ), mOldRights( oldRights ) -{ -} - -void ImapAclAttribute::setRights( const QMap &rights ) -{ - mOldRights = mRights; - mRights = rights; -} - -QMap ImapAclAttribute::rights() const -{ - return mRights; -} - -QMap ImapAclAttribute::oldRights() const -{ - return mOldRights; -} - -QByteArray ImapAclAttribute::type() const -{ - static const QByteArray sType( "imapacl" ); - return sType; -} - -Akonadi::Attribute* ImapAclAttribute::clone() const -{ - return new ImapAclAttribute( mRights, mOldRights ); -} - -QByteArray ImapAclAttribute::serialized() const -{ - QByteArray result = ""; - - bool added = false; - foreach ( const QByteArray &id, mRights.keys() ) { - result+= id; - result+= ' '; - result+= KIMAP::Acl::rightsToString( mRights[id] ); - result+= " % "; // We use this separator as '%' is not allowed in keys or values - added = true; - } - - if ( added ) - result.chop( 3 ); - - result+= " %% "; - - added = false; - foreach ( const QByteArray &id, mOldRights.keys() ) { - result+= id; - result+= ' '; - result+= KIMAP::Acl::rightsToString( mOldRights[id] ); - result+= " % "; // We use this separator as '%' is not allowed in keys or values - added = true; - } - - if ( added ) - result.chop( 3 ); - - return result; -} - -static void fillRightsMap( const QList &rights, QMap &map ) -{ - foreach ( const QByteArray &right, rights ) { - const QByteArray trimmed = right.trimmed(); - const int wsIndex = trimmed.indexOf( ' ' ); - const QByteArray id = trimmed.mid( 0, wsIndex ).trimmed(); - if ( !id.isEmpty() ) { - const bool noValue = ( wsIndex == -1 ); - if ( noValue ) { - map[id] = KIMAP::Acl::None; - } else { - const QByteArray value = trimmed.mid( wsIndex + 1, right.length() - wsIndex ).trimmed(); - map[id] = KIMAP::Acl::rightsFromString( value ); - } - } - } -} - -void ImapAclAttribute::deserialize( const QByteArray &data ) -{ - mRights.clear(); - mOldRights.clear(); - const int pos = data.indexOf( " %% " ); - if ( pos == -1 ) - return; - - const QByteArray leftPart = data.left( pos ); - const QByteArray rightPart = data.mid( pos + 4 ); - fillRightsMap( leftPart.split( '%' ), mRights ); - fillRightsMap( rightPart.split( '%' ), mOldRights ); -} diff -Nru kdepim-runtime-4.14.6/resources/shared/imapaclattribute.h kdepim-runtime-15.08.0/resources/shared/imapaclattribute.h --- kdepim-runtime-4.14.6/resources/shared/imapaclattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/imapaclattribute.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -/* - Copyright (C) 2009 Kevin Ottens - - 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_IMAPACLATTRIBUTE_H -#define AKONADI_IMAPACLATTRIBUTE_H - -#include - -#include - -#include - -namespace Akonadi { - -class ImapAclAttribute : public Akonadi::Attribute -{ - public: - ImapAclAttribute(); - ImapAclAttribute( const QMap &rights, - const QMap &oldRights ); - void setRights( const QMap &rights ); - QMap rights() const; - QMap oldRights() const; - virtual QByteArray type() const; - virtual Attribute *clone() const; - virtual QByteArray serialized() const; - virtual void deserialize( const QByteArray &data ); - - private: - QMap mRights; - QMap mOldRights; -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/imapquotaattribute.cpp kdepim-runtime-15.08.0/resources/shared/imapquotaattribute.cpp --- kdepim-runtime-4.14.6/resources/shared/imapquotaattribute.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/imapquotaattribute.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,194 +0,0 @@ -/* - Copyright (C) 2009 Kevin Ottens - - 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 "imapquotaattribute.h" - -#include -#include -#include - -#include - -using namespace Akonadi; - -ImapQuotaAttribute::ImapQuotaAttribute() -{ -} - -Akonadi::ImapQuotaAttribute::ImapQuotaAttribute( const QList &roots, - const QList< QMap > &limits, - const QList< QMap > &usages ) - : mRoots( roots ), mLimits( limits ), mUsages( usages ) -{ - Q_ASSERT( roots.size()==limits.size() ); - Q_ASSERT( roots.size()==usages.size() ); -} - -void Akonadi::ImapQuotaAttribute::setQuotas( const QList &roots, - const QList< QMap > &limits, - const QList< QMap > &usages ) -{ - Q_ASSERT( roots.size()==limits.size() ); - Q_ASSERT( roots.size()==usages.size() ); - - mRoots = roots; - mLimits = limits; - mUsages = usages; -} - -QList Akonadi::ImapQuotaAttribute::roots() const -{ - return mRoots; -} - -QList< QMap > Akonadi::ImapQuotaAttribute::limits() const -{ - return mLimits; -} - -QList< QMap > Akonadi::ImapQuotaAttribute::usages() const -{ - return mUsages; -} - -QByteArray ImapQuotaAttribute::type() const -{ - static const QByteArray sType( "imapquota" ); - return sType; -} - -Akonadi::Attribute* ImapQuotaAttribute::clone() const -{ - return new ImapQuotaAttribute( mRoots, mLimits, mUsages ); -} - -QByteArray ImapQuotaAttribute::serialized() const -{ - typedef QMap QuotaMap; - QByteArray result = ""; - - // First the roots list - foreach ( const QByteArray &root, mRoots ) { - result+=root+" % "; - } - result.chop( 3 ); - - result+= " %%%% "; // Members separator - - // Then the limit maps list - for ( int i=0; i limits = mLimits[i]; - foreach ( const QByteArray &key, limits.keys() ) { - result+= key; - result+= " % "; // We use this separator as '%' is not allowed in keys or values - result+= QByteArray::number( limits[key] ); - result+= " %% "; // Pairs separator - } - result.chop( 4 ); - result+= " %%% "; // Maps separator - } - result.chop( 5 ); - - result+= " %%%% "; // Members separator - - // Then the usage maps list - for ( int i=0; i usages = mUsages[i]; - foreach ( const QByteArray &key, usages.keys() ) { - result+= key; - result+= " % "; // We use this separator as '%' is not allowed in keys or values - result+= QByteArray::number( usages[key] ); - result+= " %% "; // Pairs separator - } - result.chop( 4 ); - result+= " %%% "; // Maps separator - } - result.chop( 5 ); - - return result; -} - -void ImapQuotaAttribute::deserialize( const QByteArray &data ) -{ - mRoots.clear(); - mLimits.clear(); - mUsages.clear(); - - // Nothing was saved. - if ( data.trimmed().isEmpty() ) { - return; - } - - QString string = QString::fromUtf8(data); // QByteArray has no proper split, so we're forced to convert to QString... - - QStringList members = string.split( QLatin1String("%%%%") ); - - // We expect exactly three members (roots, limits and usages), otherwise something is funky - if ( members.size() != 3 ) { - kWarning() << "We didn't find exactly three members in this quota serialization"; - return; - } - - QStringList roots = members[0].trimmed().split( QLatin1String(" % ") ); - foreach ( const QString &root, roots ) { - mRoots << root.trimmed().toUtf8(); - } - - QStringList allLimits = members[1].trimmed().split( QLatin1String("%%%") ); - - foreach ( const QString &limits, allLimits ) { - QMap limitsMap; - QStringList strLines = limits.split( QLatin1String("%%") ); - QList lines; - foreach ( const QString &strLine, strLines ) { - lines << strLine.trimmed().toUtf8(); - } - - foreach ( const QByteArray &line, lines ) { - QByteArray trimmed = line.trimmed(); - int wsIndex = trimmed.indexOf( '%' ); - const QByteArray key = trimmed.mid( 0, wsIndex ).trimmed(); - const QByteArray value = trimmed.mid( wsIndex+1, line.length()-wsIndex ).trimmed(); - limitsMap[key] = value.toLongLong(); - } - - mLimits << limitsMap; - } - - QStringList allUsages = members[2].trimmed().split( QLatin1String("%%%") ); - - foreach ( const QString &usages, allUsages ) { - QMap usagesMap; - QStringList strLines = usages.split( QLatin1String("%%") ); - QList lines; - foreach ( const QString &strLine, strLines ) { - lines << strLine.trimmed().toUtf8(); - } - - foreach ( const QByteArray &line, lines ) { - QByteArray trimmed = line.trimmed(); - int wsIndex = trimmed.indexOf( '%' ); - const QByteArray key = trimmed.mid( 0, wsIndex ).trimmed(); - const QByteArray value = trimmed.mid( wsIndex+1, line.length()-wsIndex ).trimmed(); - usagesMap[key] = value.toLongLong(); - } - - mUsages << usagesMap; - } -} diff -Nru kdepim-runtime-4.14.6/resources/shared/imapquotaattribute.h kdepim-runtime-15.08.0/resources/shared/imapquotaattribute.h --- kdepim-runtime-4.14.6/resources/shared/imapquotaattribute.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/imapquotaattribute.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -/* - Copyright (C) 2009 Kevin Ottens - - 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_IMAPQUOTAATTRIBUTE_H -#define AKONADI_IMAPQUOTAATTRIBUTE_H - -#include - -#include - -namespace Akonadi { - -class ImapQuotaAttribute : public Akonadi::Attribute -{ - public: - ImapQuotaAttribute(); - ImapQuotaAttribute( const QList &roots, - const QList< QMap > &limits, - const QList< QMap > &usages ); - - void setQuotas( const QList &roots, - const QList< QMap > &limits, - const QList< QMap > &usages ); - - QList roots() const; - QList< QMap > limits() const; - QList< QMap > usages() const; - - virtual QByteArray type() const; - virtual Attribute *clone() const; - virtual QByteArray serialized() const; - virtual void deserialize( const QByteArray &data ); - - private: - QList mRoots; - QList< QMap > mLimits; - QList< QMap > mUsages; -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/Messages.sh kdepim-runtime-15.08.0/resources/shared/Messages.sh --- kdepim-runtime-4.14.6/resources/shared/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -#! /usr/bin/env bash -$EXTRACTRC `find . -name \*.ui` >> rc.cpp || exit 11 -$XGETTEXT *.cpp *.h -o $podir/akonadi_singlefile_resource.pot -rm -f rc.cpp diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/autotests/CMakeLists.txt kdepim-runtime-15.08.0/resources/shared/singlefileresource/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/autotests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/autotests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,16 @@ +include(ECMAddTests) + +find_package(Qt5Test CONFIG REQUIRED) + +macro(_add_test _source) + set(_test ${_source}) + get_filename_component(_name ${_source} NAME_WE) + add_executable( ${_name} ${_test} ) + add_test( ${_name} ${_name} ) + ecm_mark_as_test(knotes-${_name}) + target_link_libraries(${_name} Qt5::Test + KF5::AkonadiCore KF5::IMAP) +endmacro() + +_add_test( collectionannotationattributetest.cpp ) +_add_test( imapaclattributetest.cpp ) diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/autotests/collectionannotationattributetest.cpp kdepim-runtime-15.08.0/resources/shared/singlefileresource/autotests/collectionannotationattributetest.cpp --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/autotests/collectionannotationattributetest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/autotests/collectionannotationattributetest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,85 @@ +/* + Copyright (C) 2009 Volker Krause + + 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 +#include +#include "../collectionannotationsattribute.cpp" + +typedef QMap Annotation; +Q_DECLARE_METATYPE(Annotation) + +using namespace Akonadi; + +class CollectionAnnotationAttributeTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void testSerializeDeserialize_data() + { + QTest::addColumn("annotation"); + + Annotation a; + QTest::newRow("empty") << a; + + a.insert("/vendor/cmu/cyrus-imapd/lastpop", ""); + QTest::newRow("empty value, single key") << a; + + a.insert("/vendor/cmu/cyrus-imapd/condstore", "false"); + QTest::newRow("empty value, two keys") << a; + + a.insert("/vendor/cmu/cyrus-imapd/sharedseen", "false"); + QTest::newRow("empty value, three keys") << a; + + a.clear(); + a.insert("vendor/cmu/cyrus-imapd/lastpop", " "); + QTest::newRow("space value, single key") << a; + + a.insert("/vendor/cmu/cyrus-imapd/condstore", "false"); + QTest::newRow("space value, two keys") << a; + + a.insert("/vendor/cmu/cyrus-imapd/sharedseen", "false"); + QTest::newRow("space value, three keys") << a; + } + + void testSerializeDeserialize() + { + QFETCH(Annotation, annotation); + CollectionAnnotationsAttribute *attr1 = new CollectionAnnotationsAttribute(); + attr1->setAnnotations(annotation); + QCOMPARE(attr1->annotations(), annotation); + + CollectionAnnotationsAttribute *attr2 = new CollectionAnnotationsAttribute(); + attr2->deserialize(attr1->serialized()); + QCOMPARE(attr2->annotations(), annotation); + + CollectionAnnotationsAttribute *attr3 = new CollectionAnnotationsAttribute(); + attr3->setAnnotations(attr2->annotations()); + QCOMPARE(attr3->serialized(), attr1->serialized()); + + delete attr1; + delete attr2; + delete attr3; + } + +}; + +QTEST_MAIN(CollectionAnnotationAttributeTest) + +#include "collectionannotationattributetest.moc" + diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/autotests/imapaclattributetest.cpp kdepim-runtime-15.08.0/resources/shared/singlefileresource/autotests/imapaclattributetest.cpp --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/autotests/imapaclattributetest.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/autotests/imapaclattributetest.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,256 @@ +/* + Copyright (C) 2010 Tobias Koenig + + 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 +#include +#include "../imapaclattribute.cpp" + +using namespace Akonadi; + +typedef QMap ImapAcl; + +Q_DECLARE_METATYPE(ImapAcl) +Q_DECLARE_METATYPE(KIMAP::Acl::Rights) + +class ImapAclAttributeTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void shouldHaveDefaultValue() + { + ImapAclAttribute attr; + QVERIFY(attr.oldRights().isEmpty()); + QVERIFY(attr.rights().isEmpty()); + QVERIFY(!attr.myRights()); + } + + void shouldBuildAttribute() + { + QMap right; + right.insert("test", KIMAP::Acl::Admin); + right.insert("foo", KIMAP::Acl::Admin); + + QMap oldright; + right.insert("test", KIMAP::Acl::Delete); + right.insert("foo", KIMAP::Acl::Delete); + ImapAclAttribute attr(right, oldright); + QCOMPARE(attr.oldRights(), oldright); + QCOMPARE(attr.rights(), right); + } + + void shouldAssignValue() + { + ImapAclAttribute attr; + QMap right; + right.insert("test", KIMAP::Acl::Admin); + right.insert("foo", KIMAP::Acl::Admin); + attr.setRights(right); + QCOMPARE(attr.rights(), right); + } + + void shouldCloneAttr() + { + ImapAclAttribute attr; + QMap right; + right.insert("test", KIMAP::Acl::Admin); + right.insert("foo", KIMAP::Acl::Admin); + attr.setRights(right); + ImapAclAttribute *clone = attr.clone(); + QVERIFY(attr == *clone); + delete clone; + } + + void shouldSerializedAttribute() + { + QMap right; + right.insert("test", KIMAP::Acl::Admin); + right.insert("foo", KIMAP::Acl::Admin); + + QMap oldright; + right.insert("test", KIMAP::Acl::Delete); + right.insert("foo", KIMAP::Acl::Delete); + ImapAclAttribute attr(right, oldright); + const QByteArray ba = attr.serialized(); + ImapAclAttribute result; + result.deserialize(ba); + QVERIFY(attr == result); + } + + void shouldHaveType() + { + ImapAclAttribute attr; + QCOMPARE(attr.type(), QByteArray("imapacl")); + } + + void testMyRights() + { + ImapAclAttribute attr; + KIMAP::Acl::Rights myRight = KIMAP::Acl::Admin; + + attr.setMyRights(myRight); + QCOMPARE(attr.myRights(), myRight); + + ImapAclAttribute *clone = attr.clone(); + QCOMPARE(clone->myRights(), myRight); + + QVERIFY(*clone == attr); + + clone->setMyRights(KIMAP::Acl::Custom0); + QVERIFY(!(*clone == attr)); + delete clone; + } + + void testDeserialize_data() + { + QTest::addColumn("rights"); + QTest::addColumn("myRights"); + QTest::addColumn("serialized"); + + KIMAP::Acl::Rights rights = KIMAP::Acl::None; + + { + ImapAcl acl; + QTest::newRow("empty") << acl << KIMAP::Acl::Rights(KIMAP::Acl::None) << QByteArray(" %% "); + } + + { + ImapAcl acl; + acl.insert("user@host", rights); + QTest::newRow("none") << acl << KIMAP::Acl::Rights(KIMAP::Acl::None) << QByteArray("user@host %% "); + } + + { + ImapAcl acl; + acl.insert("user@host", KIMAP::Acl::Lookup); + QTest::newRow("lookup") << acl << KIMAP::Acl::Rights(KIMAP::Acl::None) << QByteArray("user@host l %% "); + } + + { + ImapAcl acl; + acl.insert("user@host", KIMAP::Acl::Lookup | KIMAP::Acl::Read); + QTest::newRow("lookup/read") << acl << KIMAP::Acl::Rights(KIMAP::Acl::None) << QByteArray("user@host lr %% "); + } + + { + ImapAcl acl; + acl.insert("user@host", KIMAP::Acl::Lookup | KIMAP::Acl::Read); + acl.insert("otheruser@host", KIMAP::Acl::Lookup | KIMAP::Acl::Read); + QTest::newRow("lookup/read") << acl << KIMAP::Acl::Rights(KIMAP::Acl::None) << QByteArray("otheruser@host lr % user@host lr %% "); + } + + { + QTest::newRow("myrights") << ImapAcl() << KIMAP::Acl::rightsFromString("lrswipckxtdaen") << QByteArray(" %% %% lrswipckxtdaen"); + } + } + + void testDeserialize() + { + QFETCH(ImapAcl, rights); + QFETCH(KIMAP::Acl::Rights, myRights); + QFETCH(QByteArray, serialized); + + ImapAclAttribute deserializeAttr; + deserializeAttr.deserialize(serialized); + QCOMPARE(deserializeAttr.rights(), rights); + QCOMPARE(deserializeAttr.myRights(), myRights); + } + + void testSerializeDeserialize_data() + { + QTest::addColumn("rights"); + QTest::addColumn("myRights"); + QTest::addColumn("serialized"); + QTest::addColumn("oldSerialized"); + + ImapAcl acl; + QTest::newRow("empty") << acl << KIMAP::Acl::Rights(KIMAP::Acl::None) << QByteArray(" %% ") << QByteArray("testme@host l %% "); + + acl.insert("user@host", KIMAP::Acl::None); + QTest::newRow("none") << acl << KIMAP::Acl::Rights(KIMAP::Acl::None) << QByteArray("user@host %% ") << QByteArray("testme@host l %% user@host "); + + acl.insert("user@host", KIMAP::Acl::Lookup); + QTest::newRow("lookup") << acl << KIMAP::Acl::Rights(KIMAP::Acl::None) << QByteArray("user@host l %% ") << QByteArray("testme@host l %% user@host l"); + + acl.insert("user@host", KIMAP::Acl::Lookup | KIMAP::Acl::Read); + QTest::newRow("lookup/read") << acl << KIMAP::Acl::Rights(KIMAP::Acl::None) << QByteArray("user@host lr %% ") << QByteArray("testme@host l %% user@host lr"); + + acl.insert("otheruser@host", KIMAP::Acl::Lookup | KIMAP::Acl::Read); + QTest::newRow("lookup/read") << acl << KIMAP::Acl::Rights(KIMAP::Acl::None) << QByteArray("otheruser@host lr % user@host lr %% ") + << QByteArray("testme@host l %% otheruser@host lr % user@host lr"); + + QTest::newRow("myrights") << acl << KIMAP::Acl::rightsFromString("lrswipckxtdaen") << QByteArray("otheruser@host lr % user@host lr %% %% lrswipckxtdaen") + << QByteArray("testme@host l %% otheruser@host lr % user@host lr %% lrswipckxtdaen"); + } + + void testSerializeDeserialize() + { + QFETCH(ImapAcl, rights); + QFETCH(KIMAP::Acl::Rights, myRights); + QFETCH(QByteArray, serialized); + QFETCH(QByteArray, oldSerialized); + + ImapAclAttribute *attr = new ImapAclAttribute(); + attr->setRights(rights); + attr->setMyRights(myRights); + QCOMPARE(attr->serialized(), serialized); + + ImapAcl acl; + acl.insert("testme@host", KIMAP::Acl::Lookup); + attr->setRights(acl); + + QCOMPARE(attr->serialized(), oldSerialized); + + delete attr; + + ImapAclAttribute deserializeAttr; + deserializeAttr.deserialize(serialized); + QCOMPARE(deserializeAttr.rights(), rights); + QCOMPARE(deserializeAttr.myRights(), myRights); + } + + void testOldRights() + { + ImapAcl acls; + acls.insert("first_user@host", KIMAP::Acl::Lookup | KIMAP::Acl::Read); + acls.insert("second_user@host", KIMAP::Acl::Lookup | KIMAP::Acl::Read); + acls.insert("third_user@host", KIMAP::Acl::Lookup | KIMAP::Acl::Read); + + ImapAclAttribute *attr = new ImapAclAttribute(); + attr->setRights(acls); + + ImapAcl oldAcls = acls; + + acls.remove("first_user@host"); + acls.remove("third_user@host"); + + attr->setRights(acls); + + QCOMPARE(attr->oldRights(), oldAcls); + + attr->setRights(acls); + + QCOMPARE(attr->oldRights(), acls); + delete attr; + } +}; + +QTEST_MAIN(ImapAclAttributeTest) + +#include "imapaclattributetest.moc" diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/CMakeLists.txt kdepim-runtime-15.08.0/resources/shared/singlefileresource/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,59 @@ + +project(akonadi-singlefileresource) + + +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_singlefile_resource\") + +set( AKONADI_SINGLEFILERESOURCE_SHARED_SOURCES + singlefileresourcebase.cpp + singlefileresourceconfigdialogbase.cpp +) + +if (KDEPIM_MOBILE_UI) +set( AKONADI_SINGLEFILERESOURCE_SHARED_UI + singlefileresourceconfigdialog_mobile.ui + singlefileresourceconfigdialog.ui +) +else () +set( AKONADI_SINGLEFILERESOURCE_SHARED_UI + singlefileresourceconfigdialog_desktop.ui + singlefileresourceconfigdialog.ui +) +endif () + +set( AKONADI_COLLECTIONATTRIBUTES_SHARED_SOURCES + collectionannotationsattribute.cpp + collectionflagsattribute.cpp +) + +set( AKONADI_IMAPATTRIBUTES_SHARED_SOURCES + imapaclattribute.cpp + imapquotaattribute.cpp +) + + +set(akonadi-singlefileresource_SRCS + ${AKONADI_SINGLEFILERESOURCE_SHARED_SOURCES} + ${AKONADI_COLLECTIONATTRIBUTES_SHARED_SOURCES} + ${AKONADI_IMAPATTRIBUTES_SHARED_SOURCES} + createandsettagsjob.cpp +) + +ki18n_wrap_ui(akonadi-singlefileresource_SRCS ${AKONADI_SINGLEFILERESOURCE_SHARED_UI} settingsdialog.ui) + +add_library(akonadi-singlefileresource ${akonadi-singlefileresource_SRCS} ) +generate_export_header(akonadi-singlefileresource BASE_NAME akonadi-singlefileresource) + +target_link_libraries(akonadi-singlefileresource + KF5::AkonadiCore + KF5::AkonadiAgentBase + KF5::KIOCore + KF5::IMAP +) + +set_target_properties(akonadi-singlefileresource PROPERTIES VERSION ${KDEPIMRUNTIME_LIB_VERSION} SOVERSION ${KDEPIMRUNTIME_LIB_SOVERSION} ) +install(TARGETS akonadi-singlefileresource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) + +if (BUILD_TESTING) + add_subdirectory(autotests) +endif() diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/collectionannotationsattribute.cpp kdepim-runtime-15.08.0/resources/shared/singlefileresource/collectionannotationsattribute.cpp --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/collectionannotationsattribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/collectionannotationsattribute.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,98 @@ +/* + Copyright (C) 2008 Omat Holding B.V. + + 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 "collectionannotationsattribute.h" + +#include +#include +#include + +using namespace Akonadi; + +CollectionAnnotationsAttribute::CollectionAnnotationsAttribute() +{ +} + +CollectionAnnotationsAttribute::CollectionAnnotationsAttribute(const QMap &annotations) + : mAnnotations(annotations) +{ +} + +void CollectionAnnotationsAttribute::setAnnotations(const QMap &annotations) +{ + mAnnotations = annotations; +} + +QMap CollectionAnnotationsAttribute::annotations() const +{ + return mAnnotations; +} + +QByteArray CollectionAnnotationsAttribute::type() const +{ + static const QByteArray sType("collectionannotations"); + return sType; +} + +Akonadi::Attribute *CollectionAnnotationsAttribute::clone() const +{ + return new CollectionAnnotationsAttribute(mAnnotations); +} + +QByteArray CollectionAnnotationsAttribute::serialized() const +{ + QByteArray result = ""; + + foreach (const QByteArray &key, mAnnotations.keys()) { + result += key; + result += ' '; + result += mAnnotations[key]; + result += " % "; // We use this separator as '%' is not allowed in keys or values + } + result.chop(3); + + return result; +} + +void CollectionAnnotationsAttribute::deserialize(const QByteArray &data) +{ + mAnnotations.clear(); + const QList lines = data.split('%'); + + for (int i = 0; i < lines.size(); ++i) { + QByteArray line = lines[i]; + if (i != 0 && line.startsWith(' ')) { + line = line.mid(1); + } + if (i != lines.size() - 1 && line.endsWith(' ')) { + line.chop(1); + } + if (line.trimmed().isEmpty()) { + continue; + } + int wsIndex = line.indexOf(' '); + if (wsIndex > 0) { + const QByteArray key = line.mid(0, wsIndex); + const QByteArray value = line.mid(wsIndex + 1); + mAnnotations[key] = value; + } else { + mAnnotations.insert(line, QByteArray()); + } + } +} diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/collectionannotationsattribute.h kdepim-runtime-15.08.0/resources/shared/singlefileresource/collectionannotationsattribute.h --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/collectionannotationsattribute.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/collectionannotationsattribute.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,48 @@ +/* + Copyright (C) 2008 Omat Holding B.V. + + 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_COLLECTIONANNOTATIONSATTRIBUTE_H +#define AKONADI_COLLECTIONANNOTATIONSATTRIBUTE_H + +#include +#include "akonadi-singlefileresource_export.h" +#include + +namespace Akonadi +{ + +class AKONADI_SINGLEFILERESOURCE_EXPORT CollectionAnnotationsAttribute : public Akonadi::Attribute +{ +public: + CollectionAnnotationsAttribute(); + CollectionAnnotationsAttribute(const QMap &annotations); + void setAnnotations(const QMap &annotations); + QMap annotations() const; + QByteArray type() const Q_DECL_OVERRIDE; + Attribute *clone() const Q_DECL_OVERRIDE; + QByteArray serialized() const Q_DECL_OVERRIDE; + void deserialize(const QByteArray &data) Q_DECL_OVERRIDE; + +private: + QMap mAnnotations; +}; + +} + +#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/collectionflagsattribute.cpp kdepim-runtime-15.08.0/resources/shared/singlefileresource/collectionflagsattribute.cpp --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/collectionflagsattribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/collectionflagsattribute.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,68 @@ +/* + Copyright (C) 2008 Omat Holding B.V. + + 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 "collectionflagsattribute.h" + +#include +#include + +using namespace Akonadi; + +CollectionFlagsAttribute::CollectionFlagsAttribute(const QList &flags) + : mFlags(flags) +{ +} + +void CollectionFlagsAttribute::setFlags(const QList &flags) +{ + mFlags = flags; +} + +QList CollectionFlagsAttribute::flags() const +{ + return mFlags; +} + +QByteArray CollectionFlagsAttribute::type() const +{ + static const QByteArray sType("collectionflags"); + return sType; +} + +Akonadi::Attribute *CollectionFlagsAttribute::clone() const +{ + return new CollectionFlagsAttribute(mFlags); +} + +QByteArray CollectionFlagsAttribute::serialized() const +{ + QByteArray result; + + foreach (const QByteArray &flag, mFlags) { + result += flag + ' '; + } + result.chop(1); + + return result; +} + +void CollectionFlagsAttribute::deserialize(const QByteArray &data) +{ + mFlags = data.split(' '); +} diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/collectionflagsattribute.h kdepim-runtime-15.08.0/resources/shared/singlefileresource/collectionflagsattribute.h --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/collectionflagsattribute.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/collectionflagsattribute.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,46 @@ +/* + Copyright (C) 2008 Omat Holding B.V. + + 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_COLLECTIONFLAGSATTRIBUTE_H +#define AKONADI_COLLECTIONFLAGSATTRIBUTE_H + +#include +#include "akonadi-singlefileresource_export.h" + +namespace Akonadi +{ + +class AKONADI_SINGLEFILERESOURCE_EXPORT CollectionFlagsAttribute : public Akonadi::Attribute +{ +public: + explicit CollectionFlagsAttribute(const QList &flags = QList()); + void setFlags(const QList &flags); + QList flags() const; + QByteArray type() const Q_DECL_OVERRIDE; + Attribute *clone() const Q_DECL_OVERRIDE; + QByteArray serialized() const Q_DECL_OVERRIDE; + void deserialize(const QByteArray &data) Q_DECL_OVERRIDE; + +private: + QList mFlags; +}; + +} + +#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/createandsettagsjob.cpp kdepim-runtime-15.08.0/resources/shared/singlefileresource/createandsettagsjob.cpp --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/createandsettagsjob.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/createandsettagsjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014 Christian Mollekopf + * + * 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 "createandsettagsjob.h" +#include +#include + +#include + +using namespace Akonadi; + +CreateAndSetTagsJob::CreateAndSetTagsJob(const Item &item, const Akonadi::Tag::List &tags, QObject *parent) + : KJob(parent), + mItem(item), + mTags(tags), + mCount(0) +{ + +} + +void CreateAndSetTagsJob::start() +{ + if (mTags.isEmpty()) { + emitResult(); + } + Q_FOREACH (const Akonadi::Tag &tag, mTags) { + Akonadi::TagCreateJob *createJob = new Akonadi::TagCreateJob(tag, this); + createJob->setMergeIfExisting(true); + connect(createJob, &Akonadi::TagCreateJob::result, this, &CreateAndSetTagsJob::onCreateDone); + } +} + +void CreateAndSetTagsJob::onCreateDone(KJob *job) +{ + mCount++; + if (job->error()) { + qWarning() << "Failed to create tag " << job->errorString(); + } else { + Akonadi::TagCreateJob *createJob = static_cast(job); + mCreatedTags << createJob->tag(); + } + if (mCount == mTags.size()) { + Q_FOREACH (const Akonadi::Tag &tag, mCreatedTags) { + mItem.setTag(tag); + } + Akonadi::ItemModifyJob *modJob = new Akonadi::ItemModifyJob(mItem, this); + connect(modJob, &Akonadi::ItemModifyJob::result, this, &CreateAndSetTagsJob::onModifyDone); + } +} + +void CreateAndSetTagsJob::onModifyDone(KJob *job) +{ + if (job->error()) { + qWarning() << "Failed to modify item " << job->errorString(); + setError(KJob::UserDefinedError); + } + emitResult(); +} diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/createandsettagsjob.h kdepim-runtime-15.08.0/resources/shared/singlefileresource/createandsettagsjob.h --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/createandsettagsjob.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/createandsettagsjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014 Christian Mollekopf + * + * 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 CREATEANDSETTAGSJOB_H +#define CREATEANDSETTAGSJOB_H + +#include +#include +#include +#include "akonadi-singlefileresource_export.h" + +class AKONADI_SINGLEFILERESOURCE_EXPORT CreateAndSetTagsJob : public KJob +{ + Q_OBJECT +public: + explicit CreateAndSetTagsJob(const Akonadi::Item &item, const Akonadi::Tag::List &tags, QObject *parent = Q_NULLPTR); + + void start() Q_DECL_OVERRIDE; + +private Q_SLOTS: + void onCreateDone(KJob *); + void onModifyDone(KJob *); + +private: + Akonadi::Item mItem; + Akonadi::Tag::List mTags; + Akonadi::Tag::List mCreatedTags; + int mCount; +}; + +#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/getcredentialsjob.cpp kdepim-runtime-15.08.0/resources/shared/singlefileresource/getcredentialsjob.cpp --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/getcredentialsjob.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/getcredentialsjob.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,102 @@ +/************************************************************************************* + * Copyright (C) 2013 by Alejandro Fiestas Olivares * + * * + * 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 KDE e.V's discretion) 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 "getcredentialsjob.h" + +#include +#include +#include + +#include + +#include +#include + +GetCredentialsJob::GetCredentialsJob(const Accounts::AccountId &id, QObject *parent) + : KJob(parent) + , m_id(id) + , m_manager(new Accounts::Manager(this)) +{ + +} + +void GetCredentialsJob::start() +{ + QMetaObject::invokeMethod(this, "getCredentials", Qt::QueuedConnection); +} + +void GetCredentialsJob::setServiceType(const QString &serviceType) +{ + m_serviceType = serviceType; +} + +void GetCredentialsJob::getCredentials() +{ + Accounts::Account *acc = m_manager->account(m_id); + if (!acc) { + setError(-1); + setErrorText(i18n("Could not find account")); + emitResult(); + return; + } + Accounts::AccountService *service = new Accounts::AccountService(acc, m_manager->service(m_serviceType), this); + + Accounts::AuthData authData = service->authData(); + m_authData = authData.parameters(); + SignOn::Identity *identity = SignOn::Identity::existingIdentity(authData.credentialsId(), this); + + if (!identity) { + setError(-1); + setErrorText(i18n("Could not find credentials")); + emitResult(); + return; + } + + m_authData[QLatin1String("AccountUsername")] = acc->value(QLatin1String("username")).toString(); + QPointer authSession = identity->createSession(authData.method()); + + connect(authSession, SIGNAL(response(SignOn::SessionData)), SLOT(sessionResponse(SignOn::SessionData))); + connect(authSession, SIGNAL(error(SignOn::Error)), SLOT(sessionError(SignOn::Error))); + + authSession->process(authData.parameters(), authData.mechanism()); +} + +void GetCredentialsJob::sessionResponse(const SignOn::SessionData &data) +{ + m_sessionData = data; + emitResult(); +} + +void GetCredentialsJob::sessionError(const SignOn::Error &error) +{ + qDebug() << error.message(); + setError(-1); + setErrorText(error.message()); + emitResult(); +} + +Accounts::AccountId GetCredentialsJob::accountId() const +{ + return m_id; +} + +QVariantMap GetCredentialsJob::credentialsData() const +{ + return m_sessionData.toMap().unite(m_authData); +} diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/getcredentialsjob.h kdepim-runtime-15.08.0/resources/shared/singlefileresource/getcredentialsjob.h --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/getcredentialsjob.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/getcredentialsjob.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,64 @@ +/************************************************************************************* + * Copyright (C) 2013 by Alejandro Fiestas Olivares * + * * + * 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 KDE e.V's discretion) 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 GET_CREDENTIALS_JOB_H +#define GET_CREDENTIALS_JOB_H + +#include "akonadi-singlefileresource_export.h" +#include + +#include +#include +#include + +namespace Accounts +{ +class Manager; +}; +namespace SignOn +{ +class Error; +}; + +class AKONADI_SINGLEFILERESOURCE_EXPORT GetCredentialsJob : public KJob +{ + Q_OBJECT +public: + explicit GetCredentialsJob(const Accounts::AccountId &id, QObject *parent = 0); + virtual void start(); + + void setServiceType(const QString &serviceType); + + QVariantMap credentialsData() const; + Accounts::AccountId accountId() const; + +private Q_SLOTS: + void getCredentials(); + void sessionResponse(const SignOn::SessionData &data); + void sessionError(const SignOn::Error &error); + +private: + QString m_serviceType; + Accounts::AccountId m_id; + QVariantMap m_authData; + Accounts::Manager *m_manager; + SignOn::SessionData m_sessionData; +}; + +#endif //GET_CREDENTIALS_JOB_H diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/imapaclattribute.cpp kdepim-runtime-15.08.0/resources/shared/singlefileresource/imapaclattribute.cpp --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/imapaclattribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/imapaclattribute.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,163 @@ +/* + Copyright (C) 2009 Kevin Ottens + + 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 "imapaclattribute.h" + +#include + +using namespace Akonadi; + +ImapAclAttribute::ImapAclAttribute() +{ +} + +ImapAclAttribute::ImapAclAttribute(const QMap &rights, + const QMap &oldRights) + : mRights(rights), mOldRights(oldRights) +{ +} + +void ImapAclAttribute::setRights(const QMap &rights) +{ + mOldRights = mRights; + mRights = rights; +} + +QMap ImapAclAttribute::rights() const +{ + return mRights; +} + +QMap ImapAclAttribute::oldRights() const +{ + return mOldRights; +} + +void ImapAclAttribute::setMyRights(KIMAP::Acl::Rights rights) +{ + mMyRights = rights; +} + +KIMAP::Acl::Rights ImapAclAttribute::myRights() const +{ + return mMyRights; +} + +QByteArray ImapAclAttribute::type() const +{ + static const QByteArray sType("imapacl"); + return sType; +} + +ImapAclAttribute *ImapAclAttribute::clone() const +{ + ImapAclAttribute *attr = new ImapAclAttribute(mRights, mOldRights); + attr->setMyRights(mMyRights); + return attr; +} + +QByteArray ImapAclAttribute::serialized() const +{ + QByteArray result = ""; + + bool added = false; + foreach (const QByteArray &id, mRights.keys()) { + result += id; + result += ' '; + result += KIMAP::Acl::rightsToString(mRights[id]); + result += " % "; // We use this separator as '%' is not allowed in keys or values + added = true; + } + + if (added) { + result.chop(3); + } + + result += " %% "; + + added = false; + foreach (const QByteArray &id, mOldRights.keys()) { + result += id; + result += ' '; + result += KIMAP::Acl::rightsToString(mOldRights[id]); + result += " % "; // We use this separator as '%' is not allowed in keys or values + added = true; + } + + if (added) { + result.chop(3); + } + + if (mMyRights) { + result += " %% "; + result += KIMAP::Acl::rightsToString(mMyRights); + } + + return result; +} + +static void fillRightsMap(const QList &rights, QMap &map) +{ + foreach (const QByteArray &right, rights) { + const QByteArray trimmed = right.trimmed(); + const int wsIndex = trimmed.indexOf(' '); + const QByteArray id = trimmed.mid(0, wsIndex).trimmed(); + if (!id.isEmpty()) { + const bool noValue = (wsIndex == -1); + if (noValue) { + map[id] = KIMAP::Acl::None; + } else { + const QByteArray value = trimmed.mid(wsIndex + 1, right.length() - wsIndex).trimmed(); + map[id] = KIMAP::Acl::rightsFromString(value); + } + } + } +} + +void ImapAclAttribute::deserialize(const QByteArray &data) +{ + mRights.clear(); + mOldRights.clear(); + mMyRights = KIMAP::Acl::None; + + QList parts; + int lastPos = 0; + int pos; + while ((pos = data.indexOf(" %% ", lastPos)) != -1) { + parts << data.mid(lastPos, pos - lastPos); + lastPos = pos + 4; + } + parts << data.mid(lastPos); + + if (parts.size() < 2) { + return; + } + fillRightsMap(parts.at(0).split('%'), mRights); + fillRightsMap(parts.at(1).split('%'), mOldRights); + if (parts.size() >= 3) { + mMyRights = KIMAP::Acl::rightsFromString(parts.at(2)); + } +} + +bool ImapAclAttribute::operator==(const ImapAclAttribute &other) const +{ + return (oldRights() == other.oldRights()) + && (rights() == other.rights()) + && (myRights() == other.myRights()); +} diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/imapaclattribute.h kdepim-runtime-15.08.0/resources/shared/singlefileresource/imapaclattribute.h --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/imapaclattribute.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/imapaclattribute.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,58 @@ +/* + Copyright (C) 2009 Kevin Ottens + + 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_IMAPACLATTRIBUTE_H +#define AKONADI_IMAPACLATTRIBUTE_H + +#include "akonadi-singlefileresource_export.h" +#include + +#include + +#include + +namespace Akonadi +{ + +class AKONADI_SINGLEFILERESOURCE_EXPORT ImapAclAttribute : public Akonadi::Attribute +{ +public: + ImapAclAttribute(); + ImapAclAttribute(const QMap &rights, + const QMap &oldRights); + void setRights(const QMap &rights); + QMap rights() const; + QMap oldRights() const; + void setMyRights(KIMAP::Acl::Rights rights); + KIMAP::Acl::Rights myRights() const; + QByteArray type() const Q_DECL_OVERRIDE; + ImapAclAttribute *clone() const Q_DECL_OVERRIDE; + QByteArray serialized() const Q_DECL_OVERRIDE; + void deserialize(const QByteArray &data) Q_DECL_OVERRIDE; + + bool operator==(const ImapAclAttribute &other) const; +private: + QMap mRights; + QMap mOldRights; + KIMAP::Acl::Rights mMyRights; +}; + +} + +#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/imapquotaattribute.cpp kdepim-runtime-15.08.0/resources/shared/singlefileresource/imapquotaattribute.cpp --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/imapquotaattribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/imapquotaattribute.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,196 @@ +/* + Copyright (C) 2009 Kevin Ottens + + 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 "imapquotaattribute.h" + +#include +#include +#include + +#include + +using namespace Akonadi; + +ImapQuotaAttribute::ImapQuotaAttribute() +{ +} + +Akonadi::ImapQuotaAttribute::ImapQuotaAttribute(const QList &roots, + const QList< QMap > &limits, + const QList< QMap > &usages) + : mRoots(roots), mLimits(limits), mUsages(usages) +{ + Q_ASSERT(roots.size() == limits.size()); + Q_ASSERT(roots.size() == usages.size()); +} + +void Akonadi::ImapQuotaAttribute::setQuotas(const QList &roots, + const QList< QMap > &limits, + const QList< QMap > &usages) +{ + Q_ASSERT(roots.size() == limits.size()); + Q_ASSERT(roots.size() == usages.size()); + + mRoots = roots; + mLimits = limits; + mUsages = usages; +} + +QList Akonadi::ImapQuotaAttribute::roots() const +{ + return mRoots; +} + +QList< QMap > Akonadi::ImapQuotaAttribute::limits() const +{ + return mLimits; +} + +QList< QMap > Akonadi::ImapQuotaAttribute::usages() const +{ + return mUsages; +} + +QByteArray ImapQuotaAttribute::type() const +{ + static const QByteArray sType("imapquota"); + return sType; +} + +Akonadi::Attribute *ImapQuotaAttribute::clone() const +{ + return new ImapQuotaAttribute(mRoots, mLimits, mUsages); +} + +QByteArray ImapQuotaAttribute::serialized() const +{ + QByteArray result = ""; + + // First the roots list + foreach (const QByteArray &root, mRoots) { + result += root + " % "; + } + result.chop(3); + + result += " %%%% "; // Members separator + + // Then the limit maps list + for (int i = 0; i < mRoots.size(); ++i) { + const QMap limits = mLimits[i]; + for (auto it = limits.cbegin(), end = limits.cend(); it != end; ++it) { + result += it.key(); + result += " % "; // We use this separator as '%' is not allowed in keys or values + result += QByteArray::number(it.value()); + result += " %% "; // Pairs separator + } + result.chop(4); + result += " %%% "; // Maps separator + } + result.chop(5); + + result += " %%%% "; // Members separator + + // Then the usage maps list + for (int i = 0; i < mRoots.size(); ++i) { + const QMap usages = mUsages[i]; + for (auto it = usages.cbegin(), end = usages.cend(); it != end; ++it) { + result += it.key(); + result += " % "; // We use this separator as '%' is not allowed in keys or values + result += QByteArray::number(it.value()); + result += " %% "; // Pairs separator + } + result.chop(4); + result += " %%% "; // Maps separator + } + result.chop(5); + + return result; +} + +void ImapQuotaAttribute::deserialize(const QByteArray &data) +{ + mRoots.clear(); + mLimits.clear(); + mUsages.clear(); + + // Nothing was saved. + if (data.trimmed().isEmpty()) { + return; + } + + QString string = QString::fromUtf8(data); // QByteArray has no proper split, so we're forced to convert to QString... + + QStringList members = string.split(QLatin1String("%%%%")); + + // We expect exactly three members (roots, limits and usages), otherwise something is funky + if (members.size() != 3) { + qWarning() << "We didn't find exactly three members in this quota serialization"; + return; + } + + QStringList roots = members[0].trimmed().split(QLatin1String(" % ")); + foreach (const QString &root, roots) { + mRoots << root.trimmed().toUtf8(); + } + + QStringList allLimits = members[1].trimmed().split(QLatin1String("%%%")); + + foreach (const QString &limits, allLimits) { + QMap limitsMap; + QStringList strLines = limits.split(QLatin1String("%%")); + QList lines; + lines.reserve(strLines.count()); + foreach (const QString &strLine, strLines) { + lines << strLine.trimmed().toUtf8(); + } + + foreach (const QByteArray &line, lines) { + QByteArray trimmed = line.trimmed(); + int wsIndex = trimmed.indexOf('%'); + const QByteArray key = trimmed.mid(0, wsIndex).trimmed(); + const QByteArray value = trimmed.mid(wsIndex + 1, line.length() - wsIndex).trimmed(); + limitsMap[key] = value.toLongLong(); + } + + mLimits << limitsMap; + } + + QStringList allUsages = members[2].trimmed().split(QLatin1String("%%%")); + mUsages.reserve(allUsages.count()); + + foreach (const QString &usages, allUsages) { + QMap usagesMap; + QStringList strLines = usages.split(QLatin1String("%%")); + QList lines; + lines.reserve(strLines.count()); + foreach (const QString &strLine, strLines) { + lines << strLine.trimmed().toUtf8(); + } + + foreach (const QByteArray &line, lines) { + QByteArray trimmed = line.trimmed(); + int wsIndex = trimmed.indexOf('%'); + const QByteArray key = trimmed.mid(0, wsIndex).trimmed(); + const QByteArray value = trimmed.mid(wsIndex + 1, line.length() - wsIndex).trimmed(); + usagesMap[key] = value.toLongLong(); + } + + mUsages << usagesMap; + } +} diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/imapquotaattribute.h kdepim-runtime-15.08.0/resources/shared/singlefileresource/imapquotaattribute.h --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/imapquotaattribute.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/imapquotaattribute.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,60 @@ +/* + Copyright (C) 2009 Kevin Ottens + + 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_IMAPQUOTAATTRIBUTE_H +#define AKONADI_IMAPQUOTAATTRIBUTE_H + +#include "akonadi-singlefileresource_export.h" +#include + +#include + +namespace Akonadi +{ + +class AKONADI_SINGLEFILERESOURCE_EXPORT ImapQuotaAttribute : public Akonadi::Attribute +{ +public: + ImapQuotaAttribute(); + ImapQuotaAttribute(const QList &roots, + const QList< QMap > &limits, + const QList< QMap > &usages); + + void setQuotas(const QList &roots, + const QList< QMap > &limits, + const QList< QMap > &usages); + + QList roots() const; + QList< QMap > limits() const; + QList< QMap > usages() const; + + QByteArray type() const Q_DECL_OVERRIDE; + Attribute *clone() const Q_DECL_OVERRIDE; + QByteArray serialized() const Q_DECL_OVERRIDE; + void deserialize(const QByteArray &data) Q_DECL_OVERRIDE; + +private: + QList mRoots; + QList< QMap > mLimits; + QList< QMap > mUsages; +}; + +} + +#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/Messages.sh kdepim-runtime-15.08.0/resources/shared/singlefileresource/Messages.sh --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/Messages.sh 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/Messages.sh 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +$EXTRACTRC `find . -name \*.ui` >> rc.cpp || exit 11 +$XGETTEXT *.cpp *.h -o $podir/akonadi_singlefile_resource.pot +rm -f rc.cpp diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/settingsdialog.ui kdepim-runtime-15.08.0/resources/shared/singlefileresource/settingsdialog.ui --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/settingsdialog.ui 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/settingsdialog.ui 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,215 @@ + + SettingsDialog + + + + 0 + 0 + 547 + 386 + + + + + + + 0 + + + + Directory + + + + + + Directory Name + + + + + + + + &Directory: + + + kcfg_Path + + + + + + + + + + + + Select the directory whose contents should be represented by this resource. If the directory does not exist, it will be created. + + + true + + + + + + + + + + Access Rights + + + + + + Read only + + + + + + + If read-only mode is enabled, no changes will be written to the directory selected above. Read-only mode will be automatically enabled if you do not have write access to the directory. + + + true + + + + + + + + + + Qt::Vertical + + + + 20 + 4 + + + + + + + + + Tuning + + + + + + The options on this page allow you to change parameters that balance data safety and consistency against performance. In general you should be careful with changing anything here, the defaults are good enough in most cases. + + + true + + + + + + + + + Autosave delay: + + + + + + + 1 + + + 0 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 138 + + + + + + + + + + + + + KPluralHandlingSpinBox + QSpinBox +
KPluralHandlingSpinBox
+
+ + KUrlRequester + QFrame +
kurlrequester.h
+
+
+ + + + kcfg_ReadOnly + toggled(bool) + kcfg_AutosaveInterval + setDisabled(bool) + + + 273 + 205 + + + 157 + 101 + + + + + kcfg_ReadOnly + toggled(bool) + autosaveLabel + setDisabled(bool) + + + 273 + 205 + + + 56 + 101 + + + + +
diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourcebase.cpp kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourcebase.cpp --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourcebase.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourcebase.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,289 @@ +/* + Copyright (c) 2008 Bertjan Broeksema + Copyright (c) 2008 Volker Krause + + 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 "singlefileresourcebase.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +using namespace Akonadi; + +SingleFileResourceBase::SingleFileResourceBase(const QString &id) + : ResourceBase(id), mDownloadJob(Q_NULLPTR), mUploadJob(Q_NULLPTR) +{ + connect(this, &SingleFileResourceBase::reloadConfiguration, this, &SingleFileResourceBase::reloadFile); + QTimer::singleShot(0, this, SLOT(readFile())); + + changeRecorder()->itemFetchScope().fetchFullPayload(); + changeRecorder()->fetchCollection(true); + + connect(changeRecorder(), SIGNAL(changesAdded()), SLOT(scheduleWrite())); + + connect(KDirWatch::self(), &KDirWatch::dirty, this, &SingleFileResourceBase::fileChanged); + connect(KDirWatch::self(), &KDirWatch::created, this, &SingleFileResourceBase::fileChanged); + + //QT5 KLocalizedString::global()->insertCatalog( QLatin1String("akonadi_singlefile_resource") ); +} + +KSharedConfig::Ptr SingleFileResourceBase::runtimeConfig() const +{ + return KSharedConfig::openConfig(name() + QLatin1String("rc"), KConfig::SimpleConfig, QStandardPaths::CacheLocation); +} + +bool SingleFileResourceBase::readLocalFile(const QString &fileName) +{ + const QByteArray newHash = calculateHash(fileName); + if (mCurrentHash != newHash) { + if (!mCurrentHash.isEmpty()) { + // There was a hash stored in the config file or a chached one from + // a previous read and it is different from the hash we just read. + handleHashChange(); + } + + if (!readFromFile(fileName)) { + mCurrentHash.clear(); + mCurrentUrl = QUrl(); // reset so we don't accidentally overwrite the file + return false; + } + + if (mCurrentHash.isEmpty()) { + // This is the very first time we read the file so make sure to store + // the hash as writeFile() might not be called at all (e.g in case of + // read only resources). + saveHash(newHash); + } + + // Only synchronize when the contents of the file have changed wrt to + // the last time this file was read. Before we synchronize first + // clearCache is called to make sure that the cached items get the + // actual values as present in the file. + invalidateCache(rootCollection()); + synchronize(); + } else { + // The hash didn't change, notify implementing resources about the + // actual file name that should be used when reading the file is + // necessary. + setLocalFileName(fileName); + } + + mCurrentHash = newHash; + return true; +} + +void SingleFileResourceBase::setLocalFileName(const QString &fileName) +{ + // Default implementation. + if (!readFromFile(fileName)) { + mCurrentHash.clear(); + mCurrentUrl = QUrl(); // reset so we don't accidentally overwrite the file + return; + } +} + +QString SingleFileResourceBase::cacheFile() const +{ + return QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1String("/") + identifier() ; +} + +QByteArray SingleFileResourceBase::calculateHash(const QString &fileName) const +{ + QFile file(fileName); + if (!file.exists()) { + return QByteArray(); + } + + if (!file.open(QIODevice::ReadOnly)) { + return QByteArray(); + } + + QCryptographicHash hash(QCryptographicHash::Md5); + qint64 blockSize = 512 * 1024; // Read blocks of 512K + + while (!file.atEnd()) { + hash.addData(file.read(blockSize)); + } + + file.close(); + + return hash.result(); +} + +void SingleFileResourceBase::handleHashChange() +{ + // Default implementation does nothing. + qDebug() << "The hash has changed."; +} + +QByteArray SingleFileResourceBase::loadHash() const +{ + KConfigGroup generalGroup(runtimeConfig(), "General"); + return QByteArray::fromHex(generalGroup.readEntry("hash", QByteArray())); +} + +void SingleFileResourceBase::saveHash(const QByteArray &hash) const +{ + KSharedConfig::Ptr config = runtimeConfig(); + KConfigGroup generalGroup(config, "General"); + generalGroup.writeEntry("hash", hash.toHex()); + config->sync(); +} + +void SingleFileResourceBase::setSupportedMimetypes(const QStringList &mimeTypes, const QString &icon) +{ + mSupportedMimetypes = mimeTypes; + mCollectionIcon = icon; +} + +void SingleFileResourceBase::collectionChanged(const Akonadi::Collection &collection) +{ + const QString newName = collection.displayName(); + if (collection.hasAttribute()) { + EntityDisplayAttribute *attr = collection.attribute(); + if (!attr->iconName().isEmpty()) { + mCollectionIcon = attr->iconName(); + } + } + + if (newName != name()) { + setName(newName); + } + + changeCommitted(collection); +} + +void SingleFileResourceBase::reloadFile() +{ + // Update the network setting. + setNeedsNetwork(!mCurrentUrl.isEmpty() && !mCurrentUrl.isLocalFile()); + + // if we have something loaded already, make sure we write that back in case + // the settings changed + if (!mCurrentUrl.isEmpty() && !readOnly()) { + writeFile(); + } + + readFile(); + + // name or rights could have changed + synchronizeCollectionTree(); +} + +void SingleFileResourceBase::handleProgress(KJob *, unsigned long pct) +{ + Q_EMIT percent(pct); +} + +void SingleFileResourceBase::fileChanged(const QString &fileName) +{ + if (fileName != mCurrentUrl.toLocalFile()) { + return; + } + + const QByteArray newHash = calculateHash(fileName); + + // There is only a need to synchronize when the file was changed by another + // process. At this point we're sure that it is the file that the resource + // was configured for because of the check at the beginning of this function. + if (newHash == mCurrentHash) { + return; + } + + if (!mCurrentUrl.isEmpty()) { + QString lostFoundFileName; + const QUrl prevUrl = mCurrentUrl; + int i = 0; + do { + lostFoundFileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + identifier() + QDir::separator() + prevUrl.fileName() + QLatin1Char('-') + QString::number(++i) ; + } while (QFile(lostFoundFileName).exists()); + + // create the directory if it doesn't exist yet + QDir dir = QFileInfo(lostFoundFileName).dir(); + if (!dir.exists()) { + dir.mkpath(dir.path()); + } + + mCurrentUrl = QUrl::fromLocalFile(lostFoundFileName); + writeFile(); + mCurrentUrl = prevUrl; + + const QString message = i18n("The file '%1' was changed on disk. " + "As a precaution, a backup of its previous contents has been created at '%2'.", + prevUrl.toDisplayString(), QUrl::fromLocalFile(lostFoundFileName).toDisplayString()); + Q_EMIT warning(message); + } + + readFile(); + + // Notify resources, so that information bound to the file like indexes etc. + // can be updated. + handleHashChange(); + invalidateCache(rootCollection()); + synchronize(); +} + +void SingleFileResourceBase::scheduleWrite() +{ + scheduleCustomTask(this, "writeFile", QVariant(true), ResourceBase::AfterChangeReplay); +} + +void SingleFileResourceBase::slotDownloadJobResult(KJob *job) +{ + if (job->error() && job->error() != KIO::ERR_DOES_NOT_EXIST) { + const QString message = i18n("Could not load file '%1'.", mCurrentUrl.toDisplayString()); + qWarning() << message; + Q_EMIT status(Broken, message); + } else { + readLocalFile(QUrl::fromLocalFile(cacheFile()).toLocalFile()); + } + + mDownloadJob = Q_NULLPTR; + KGlobal::deref(); + + Q_EMIT status(Idle, i18nc("@info:status", "Ready")); +} + +void SingleFileResourceBase::slotUploadJobResult(KJob *job) +{ + if (job->error()) { + const QString message = i18n("Could not save file '%1'.", mCurrentUrl.toDisplayString()); + qWarning() << message; + Q_EMIT status(Broken, message); + } + + mUploadJob = Q_NULLPTR; + KGlobal::deref(); + + Q_EMIT status(Idle, i18nc("@info:status", "Ready")); +} + diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourcebase.h kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourcebase.h --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourcebase.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourcebase.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,189 @@ +/* + Copyright (c) 2008 Volker Krause + + 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_SINGLEFILERESOURCEBASE_H +#define AKONADI_SINGLEFILERESOURCEBASE_H + +#include "akonadi-singlefileresource_export.h" +#include + +#include +#include +#include + +namespace KIO +{ +class FileCopyJob; +class Job; +} + +namespace Akonadi +{ + +/** + * Base class for single file based resources. + * @see SingleFileResource + */ +class AKONADI_SINGLEFILERESOURCE_EXPORT SingleFileResourceBase : public ResourceBase, public AgentBase::Observer +{ + Q_OBJECT +public: + explicit SingleFileResourceBase(const QString &id); + + /** + * Set the mimetypes supported by this resource and an optional icon for the collection. + */ + void setSupportedMimetypes(const QStringList &mimeTypes, const QString &icon = QString()); + + void collectionChanged(const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + +public Q_SLOTS: + void reloadFile(); + + /* + * Read the current state from a file. This can happen + * from direct callers, or as part of a scheduled task. + * @p taskContext specifies whether the method is being + * called from within a task or not. + */ + virtual void readFile(bool taskContext = false) = 0; + /* + * Writes the current state out to a file. This can happen + * from direct callers, or as part of a scheduled task. + * @p taskContext specifies whether the method is being + * called from within a task or not. + */ + virtual void writeFile(bool taskContext = false) = 0; + + /* + * Same method as above, but uses a QVariant so it can + * be called from Akonadi::ResourceScheduler. + */ + virtual void writeFile(const QVariant &taskContext) = 0; + +protected: + /** + * Returns a pointer to the KConfig object which is used to store runtime + * information of the resource. + */ + KSharedConfig::Ptr runtimeConfig() const; + + /** + * Handles everything needed when the hash of a file has changed between the + * last write and the first read. This stores the new hash in a config file + * and notifies implementing resources to handle a hash change if the + * previous known hash was not empty. Finally this method clears the cache + * and calls synchronize. + * Returns true on succes, false otherwise. + */ + bool readLocalFile(const QString &fileName); + + /** + * Reimplement to read your data from the given file. + * The file is always local, loading from the network is done + * automatically if needed. + */ + virtual bool readFromFile(const QString &fileName) = 0; + + /** + * Reimplement to write your data to the given file. + * The file is always local, storing back to the network url is done + * automatically when needed. + */ + virtual bool writeToFile(const QString &fileName) = 0; + + /** + * It is not always needed to parse the file when a resources is started. + * (e.g. When the hash of the file is the same as the last time the resource + * has written changes to the file). In this case setActualFileName is + * called so that the implementing resource does know which file to read + * when it actually needs to read the file. + * + * The default implementation will just call readFromFile( fileName ), so + * implementing resources will have to explictly reimplement this method to + * actually get any profit of this. + * + * @p fileName This will always be a path to a local file. + */ + virtual void setLocalFileName(const QString &fileName); + + /** + * Generates the full path for the cache file in the case that a remote file + * is used. + */ + QString cacheFile() const; + + /** + * Calculates an MD5 hash for given file. If the file does not exists + * or the path is empty, this will return an empty QByteArray. + */ + QByteArray calculateHash(const QString &fileName) const; + + /** + * This method is called when the hash of the file has changed between the + * last writeFile() and a readFile() call. This means that the file was + * changed by another program. + * + * Note: This method is not called when the last known hash is + * empty. In that case it is assumed that the file is loaded for the + * first time. + */ + virtual void handleHashChange(); + + /** + * Returns the hash that was stored to a cache file. + */ + QByteArray loadHash() const; + + /** + * Stores the given hash into a cache file. + */ + void saveHash(const QByteArray &hash) const; + + /** + * Returns whether the resource can be written to. + */ + virtual bool readOnly() const = 0; + + /** + * Returns the collection of this resource. + */ + virtual Collection rootCollection() const = 0; + +protected: + QUrl mCurrentUrl; + QStringList mSupportedMimetypes; + QString mCollectionIcon; + KIO::FileCopyJob *mDownloadJob; + KIO::FileCopyJob *mUploadJob; + QByteArray mCurrentHash; + +protected Q_SLOTS: + void scheduleWrite(); /// Called when changes are added to the ChangeRecorder. + +private Q_SLOTS: + void handleProgress(KJob *, unsigned long); + void fileChanged(const QString &fileName); + void slotDownloadJobResult(KJob *); + void slotUploadJobResult(KJob *); +}; + +} + +#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourceconfigdialogbase.cpp kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourceconfigdialogbase.cpp --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourceconfigdialogbase.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourceconfigdialogbase.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,247 @@ +/* + Copyright (c) 2008 Bertjan Broeksema + Copyright (c) 2008 Volker Krause + Copyright (c) 2010,2011 David Jarvie + + 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 "singlefileresourceconfigdialogbase.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace Akonadi; + +SingleFileResourceConfigDialogBase::SingleFileResourceConfigDialogBase(WId windowId) : + QDialog(), + mManager(Q_NULLPTR), + mStatJob(Q_NULLPTR), + mAppendedWidget(Q_NULLPTR), + mDirUrlChecked(false), + mMonitorEnabled(true), + mLocalFileOnly(false) +{ + QWidget *mainWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); + ui.setupUi(mainWidget); + ui.kcfg_Path->setMode(KFile::File); +#ifndef KDEPIM_MOBILE_UI + ui.statusLabel->setText(QString()); +#endif + + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + mOkButton = buttonBox->button(QDialogButtonBox::Ok); + mOkButton->setDefault(true); + mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &SingleFileResourceConfigDialogBase::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &SingleFileResourceConfigDialogBase::reject); + mainLayout->addWidget(buttonBox); + + if (windowId) { + KWindowSystem::setMainWindow(this, windowId); + } + + ui.ktabwidget->tabBar()->hide(); + + connect(mOkButton, &QPushButton::clicked, this, &SingleFileResourceConfigDialogBase::save); + + connect(ui.kcfg_Path, &KUrlRequester::textChanged, this, &SingleFileResourceConfigDialogBase::validate); + connect(ui.kcfg_MonitorFile, &QCheckBox::toggled, this, &SingleFileResourceConfigDialogBase::validate); + ui.kcfg_Path->setFocus(); + QTimer::singleShot(0, this, SLOT(validate())); + setMinimumSize(600, 540); + readConfig(); +} + +SingleFileResourceConfigDialogBase::~SingleFileResourceConfigDialogBase() +{ + writeConfig(); +} + +void SingleFileResourceConfigDialogBase::writeConfig() +{ + KConfigGroup group(KSharedConfig::openConfig(), "SingleFileResourceConfigDialogBase"); + group.writeEntry("Size", size()); +} + +void SingleFileResourceConfigDialogBase::readConfig() +{ + KConfigGroup group(KSharedConfig::openConfig(), "SingleFileResourceConfigDialogBase"); + const QSize sizeDialog = group.readEntry("Size", QSize(600, 540)); + if (sizeDialog.isValid()) { + resize(sizeDialog); + } +} + +void SingleFileResourceConfigDialogBase::addPage(const QString &title, QWidget *page) +{ + ui.ktabwidget->tabBar()->show(); + ui.ktabwidget->addTab(page, title); + mManager->addWidget(page); + mManager->updateWidgets(); +} + +void SingleFileResourceConfigDialogBase::setFilter(const QString &filter) +{ + ui.kcfg_Path->setFilter(filter); +} + +void SingleFileResourceConfigDialogBase::setMonitorEnabled(bool enable) +{ + mMonitorEnabled = enable; +#ifdef KDEPIM_MOBILE_UI + ui.kcfg_MonitorFile->setVisible(mMonitorEnabled); +#else + ui.groupBox_MonitorFile->setVisible(mMonitorEnabled); +#endif +} + +void SingleFileResourceConfigDialogBase::setUrl(const QUrl &url) +{ + ui.kcfg_Path->setUrl(url); +} + +QUrl SingleFileResourceConfigDialogBase::url() const +{ + return ui.kcfg_Path->url(); +} + +void SingleFileResourceConfigDialogBase::setLocalFileOnly(bool local) +{ + mLocalFileOnly = local; + ui.kcfg_Path->setMode(mLocalFileOnly ? KFile::File | KFile::LocalOnly : KFile::File); +} + +void SingleFileResourceConfigDialogBase::appendWidget(SingleFileValidatingWidget *widget) +{ + widget->setParent(static_cast(ui.tab)); + ui.tabLayout->addWidget(widget); + connect(widget, &SingleFileValidatingWidget::changed, this, &SingleFileResourceConfigDialogBase::validate); + mAppendedWidget = widget; +} + +void SingleFileResourceConfigDialogBase::validate() +{ + if (mAppendedWidget && !mAppendedWidget->validate()) { + mOkButton->setEnabled(false); + return; + } + + const QUrl currentUrl = ui.kcfg_Path->url(); + if (ui.kcfg_Path->text().trimmed().isEmpty() || currentUrl.isEmpty()) { + mOkButton->setEnabled(false); + return; + } + + if (currentUrl.isLocalFile()) { + if (mMonitorEnabled) { + ui.kcfg_MonitorFile->setEnabled(true); + } +#ifndef KDEPIM_MOBILE_UI + ui.statusLabel->setText(QString()); +#endif + + // The read-only checkbox used to be disabled if the file is read-only, + // but it is then impossible to know at a later date if the file + // permissions change, whether the user actually wanted the resource to be + // read-only or not. So just leave the read-only checkbox untouched. + mOkButton->setEnabled(true); + } else { + // Not a local file. + if (mLocalFileOnly) { + mOkButton->setEnabled(false); + return; + } + if (mMonitorEnabled) { + ui.kcfg_MonitorFile->setEnabled(false); + } +#ifndef KDEPIM_MOBILE_UI + ui.statusLabel->setText(i18nc("@info:status", "Checking file information...")); +#endif + + if (mStatJob) { + mStatJob->kill(); + } + + mStatJob = KIO::stat(currentUrl, KIO::DefaultFlags | KIO::HideProgressInfo); + mStatJob->setDetails(2); // All details. + mStatJob->setSide(KIO::StatJob::SourceSide); + + connect(mStatJob, &KIO::StatJob::result, this, &SingleFileResourceConfigDialogBase::slotStatJobResult); + + // Allow the OK button to be disabled until the MetaJob is finished. + mOkButton->setEnabled(false); + } +} + +void SingleFileResourceConfigDialogBase::slotStatJobResult(KJob *job) +{ + if (job->error() == KIO::ERR_DOES_NOT_EXIST && !mDirUrlChecked) { + // The file did not exist, so let's see if the directory the file should + // reside in supports writing. + + QUrl dirUrl(ui.kcfg_Path->url()); + dirUrl = KIO::upUrl(dirUrl); + + mStatJob = KIO::stat(dirUrl, KIO::DefaultFlags | KIO::HideProgressInfo); + mStatJob->setDetails(2); // All details. + mStatJob->setSide(KIO::StatJob::SourceSide); + + connect(mStatJob, &KIO::StatJob::result, this, &SingleFileResourceConfigDialogBase::slotStatJobResult); + + // Make sure we don't check the whole path upwards. + mDirUrlChecked = true; + return; + } else if (job->error()) { + // It doesn't seem possible to read nor write from the location so leave the + // ok button disabled +#ifndef KDEPIM_MOBILE_UI + ui.statusLabel->setText(QString()); +#endif + mOkButton->setEnabled(false); + mDirUrlChecked = false; + mStatJob = Q_NULLPTR; + return; + } + +#ifndef KDEPIM_MOBILE_UI + ui.statusLabel->setText(QString()); +#endif + mOkButton->setEnabled(true); + + mDirUrlChecked = false; + mStatJob = Q_NULLPTR; +} + +SingleFileValidatingWidget::SingleFileValidatingWidget(QWidget *parent) + : QWidget(parent) +{ +} diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourceconfigdialogbase.h kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourceconfigdialogbase.h --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourceconfigdialogbase.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourceconfigdialogbase.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,150 @@ +/* + Copyright (c) 2008 Bertjan Broeksema + Copyright (c) 2008 Volker Krause + Copyright (c) 2010,2011 David Jarvie + + 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_SINGLEFILERESOURCECONFIGDIALOGBASE_H +#define AKONADI_SINGLEFILERESOURCECONFIGDIALOGBASE_H + +#include "akonadi-singlefileresource_export.h" + +#ifdef KDEPIM_MOBILE_UI +#include "ui_singlefileresourceconfigdialog_mobile.h" +#else +#include "ui_singlefileresourceconfigdialog_desktop.h" +#endif + +#include +#include +class KConfigDialogManager; +class KJob; +class QPushButton; + +namespace KIO +{ +class StatJob; +} + +namespace Akonadi +{ + +class SingleFileValidatingWidget; + +/** + * Base class for the configuration dialog for single file based resources. + * @see SingleFileResourceConfigDialog + */ +class AKONADI_SINGLEFILERESOURCE_EXPORT SingleFileResourceConfigDialogBase : public QDialog +{ + Q_OBJECT +public: + explicit SingleFileResourceConfigDialogBase(WId windowId); + ~SingleFileResourceConfigDialogBase(); + + /** + * Adds @param page to the tabwidget. This can be used to add custom + * settings for a specific single file resource. + */ + void addPage(const QString &title, QWidget *page); + + /** + * Set file extension filter. + */ + void setFilter(const QString &filter); + + /** + * Enable and show, or disable and hide, the monitor option. + * If the option is disabled, its value will not be saved. + * By default, the monitor option is enabled. + */ + void setMonitorEnabled(bool enable); + + /** + * Return the file URL. + */ + QUrl url() const; + + /** + * Set the file URL. + */ + void setUrl(const QUrl &url); + + /** + * Specify whether the file must be local. + * The default is to allow both local and remote files. + */ + void setLocalFileOnly(bool local); + + /** + * Add a widget to the dialog. + */ + void appendWidget(SingleFileValidatingWidget *widget); + +protected Q_SLOTS: + virtual void save() = 0; + +protected: + Ui::SingleFileResourceConfigDialog ui; + KConfigDialogManager *mManager; + +private Q_SLOTS: + void validate(); + void slotStatJobResult(KJob *); + +private: + void writeConfig(); + void readConfig(); + KIO::StatJob *mStatJob; + SingleFileValidatingWidget *mAppendedWidget; + bool mDirUrlChecked; + bool mMonitorEnabled; + bool mLocalFileOnly; + QPushButton *mOkButton; +}; + +/** + * Base class for widgets added to SingleFileResourceConfigDialogBase + * using its appendWidget() method. + * + * Derived classes must implement validate() andQ_EMIT changed() when + * appropriate. + */ +class AKONADI_SINGLEFILERESOURCE_EXPORT SingleFileValidatingWidget : public QWidget +{ + Q_OBJECT +public: + explicit SingleFileValidatingWidget(QWidget *parent = Q_NULLPTR); + + /** + * Return whether the widget's value is valid when the dialog is + * accepted. + */ + virtual bool validate() const = 0; + +Q_SIGNALS: + /** + * Signal emitted when the widget's value changes in a way which + * might affect the result of validate(). + */ + void changed(); +}; + +} + +#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourceconfigdialog_desktop.ui kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourceconfigdialog_desktop.ui --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourceconfigdialog_desktop.ui 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourceconfigdialog_desktop.ui 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,175 @@ + + + SingleFileResourceConfigDialog + + + + 0 + 0 + 487 + 497 + + + + + + + 0 + + + + File + + + + + + Filename + + + + + + + + &Filename: + + + kcfg_Path + + + + + + + + + + + + Status: + + + + + + + Select the file whose contents should be represented by this resource. If the file does not exist, it will be created. A URL of a remote file can also be specified, but note that monitoring for file changes will not work in this case. + + + true + + + + + + + + + + Display Name + + + + + + + + &Name: + + + kcfg_DisplayName + + + + + + + + + + + + Enter the name used to identify this resource in displays. If not specified, the filename will be used. + + + true + + + + + + + + + + Access Rights + + + + + + Read only + + + + + + + If read-only mode is enabled, no changes will be written to the file selected above. Read-only mode will be automatically enabled if you do not have write access to the file or the file is on a remote server that does not support write access. + + + true + + + + + + + + + + Monitoring + + + + + + If file monitoring is enabled the resource will reload the file when changes are made by other programs. It also tries to create a backup in case of conflicts whenever possible. + + + true + + + + + + + Enable file &monitoring + + + + + + + + + + + + + + + KLineEdit + QLineEdit +
klineedit.h
+
+ + KUrlRequester + QFrame +
kurlrequester.h
+
+
+ + +
diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourceconfigdialog.h kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourceconfigdialog.h --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourceconfigdialog.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourceconfigdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,60 @@ +/* + Copyright (c) 2008 Bertjan Broeksema + Copyright (c) 2008 Volker Krause + + 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_SINGLEFILERESOURCECONFIGDIALOG_H +#define AKONADI_SINGLEFILERESOURCECONFIGDIALOG_H + +#include "akonadi-singlefileresource_export.h" +#include "singlefileresourceconfigdialogbase.h" + +#include + +namespace Akonadi +{ + +/** + * Configuration dialog for single file resources. + */ +template +class AKONADI_SINGLEFILERESOURCE_EXPORT SingleFileResourceConfigDialog : public SingleFileResourceConfigDialogBase +{ + Settings *mSettings; + +public: + explicit SingleFileResourceConfigDialog(WId windowId, Settings *settings) + : SingleFileResourceConfigDialogBase(windowId) + , mSettings(settings) + { + ui.kcfg_Path->setUrl(QUrl::fromLocalFile(mSettings->path())); + mManager = new KConfigDialogManager(this, mSettings); + mManager->updateWidgets(); + } + +protected: + void save() Q_DECL_OVERRIDE { + mManager->updateSettings(); + mSettings->setPath(ui.kcfg_Path->url().toLocalFile()); + mSettings->save(); + } +}; + +} + +#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourceconfigdialog_mobile.ui kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourceconfigdialog_mobile.ui --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourceconfigdialog_mobile.ui 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourceconfigdialog_mobile.ui 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,102 @@ + + + SingleFileResourceConfigDialog + + + + 0 + 0 + 487 + 183 + + + + + + + + File + + + + + + + + &Filename: + + + kcfg_Path + + + + + + + + + + + + + + &Display name: + + + kcfg_DisplayName + + + + + + + + + + + + Read only + + + + + + + Enable file &monitoring + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + KLineEdit + QLineEdit +
klineedit.h
+
+ + KUrlRequester + QFrame +
kurlrequester.h
+
+
+ + +
diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourceconfigdialog.ui kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourceconfigdialog.ui --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresourceconfigdialog.ui 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresourceconfigdialog.ui 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,12 @@ + + + SingleFileResourceConfigDialog + + + + + + + + + diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresource.h kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresource.h --- kdepim-runtime-4.14.6/resources/shared/singlefileresource/singlefileresource.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource/singlefileresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,386 @@ +/* + Copyright (c) 2008 Bertjan Broeksema + Copyright (c) 2008 Volker Krause + Copyright (c) 2010 David Jarvie + + 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_SINGLEFILERESOURCE_H +#define AKONADI_SINGLEFILERESOURCE_H + +#include "akonadi-singlefileresource_export.h" +#include "singlefileresourcebase.h" +#include "singlefileresourceconfigdialog.h" + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace Akonadi +{ + +/** + * Base class for single file based resources. + */ +template +class AKONADI_SINGLEFILERESOURCE_EXPORT SingleFileResource : public SingleFileResourceBase +{ +public: + SingleFileResource(const QString &id) + : SingleFileResourceBase(id) + , mSettings(new Settings(componentData().config())) + { + // The resource needs network when the path refers to a non local file. + setNeedsNetwork(!QUrl::fromLocalFile(mSettings->path()).isLocalFile()); + } + ~SingleFileResource() + { + delete mSettings; + } + + /** + * Read changes from the backend file. + */ + void readFile(bool taskContext = false) Q_DECL_OVERRIDE { + if (KDirWatch::self()->contains(mCurrentUrl.toLocalFile())) + { + KDirWatch::self()->removeFile(mCurrentUrl.toLocalFile()); + } + + if (mSettings->path().isEmpty()) + { + const QString message = i18n("No file selected."); + qWarning() << message; + emit status(NotConfigured, i18n("The resource not configured yet")); + if (taskContext) { + cancelTask(); + } + return; + } + + mCurrentUrl = QUrl::fromLocalFile(mSettings->path()); + if (mCurrentHash.isEmpty()) + { + // First call to readFile() lets see if there is a hash stored in a + // cache file. If both are the same than there is no need to load the + // file and synchronize the resource. + mCurrentHash = loadHash(); + } + + if (mCurrentUrl.isLocalFile()) + { + if (mSettings->displayName().isEmpty() + && (name().isEmpty() || name() == identifier()) && !mCurrentUrl.isEmpty()) { + setName(mCurrentUrl.fileName()); + } + + // check if the file does not exist yet, if so, create it + if (!QFile::exists(mCurrentUrl.toLocalFile())) { + QFile f(mCurrentUrl.toLocalFile()); + + // first create try to create the directory the file should be located in + QDir dir = QFileInfo(f).dir(); + if (! dir.exists()) { + dir.mkpath(dir.path()); + } + + if (f.open(QIODevice::WriteOnly) && f.resize(0)) { + emit status(Idle, i18nc("@info:status", "Ready")); + } else { + const QString message = i18n("Could not create file '%1'.", mCurrentUrl.toDisplayString()); + qWarning() << message; + emit status(Broken, message); + mCurrentUrl.clear(); + if (taskContext) { + cancelTask(); + } + return; + } + } + + // Cache, because readLocalFile will clear mCurrentUrl on failure. + const QString localFileName = mCurrentUrl.toLocalFile(); + if (!readLocalFile(mCurrentUrl.toLocalFile())) { + const QString message = i18n("Could not read file '%1'", localFileName); + qWarning() << message; + emit status(Broken, message); + if (taskContext) { + cancelTask(); + } + return; + } + + if (mSettings->monitorFile()) { + KDirWatch::self()->addFile(mCurrentUrl.toLocalFile()); + } + + emit status(Idle, i18nc("@info:status", "Ready")); + } else { // !mCurrentUrl.isLocalFile() + if (mDownloadJob) + { + const QString message = i18n("Another download is still in progress."); + qWarning() << message; + emit error(message); + if (taskContext) { + cancelTask(); + } + return; + } + + if (mUploadJob) + { + const QString message = i18n("Another file upload is still in progress."); + qWarning() << message; + emit error(message); + if (taskContext) { + cancelTask(); + } + return; + } + + KGlobal::ref(); + + // NOTE: Test what happens with remotefile -> save, close before save is finished. + mDownloadJob = KIO::file_copy(mCurrentUrl, QUrl::fromLocalFile(cacheFile()), -1, KIO::Overwrite | KIO::DefaultFlags | KIO::HideProgressInfo); + connect(mDownloadJob, SIGNAL(result(KJob *)), + SLOT(slotDownloadJobResult(KJob *))); + connect(mDownloadJob, SIGNAL(percent(KJob *, ulong)), + SLOT(handleProgress(KJob *, ulong))); + + emit status(Running, i18n("Downloading remote file.")); + } + + const QString display = mSettings->displayName(); + if (!display.isEmpty()) + { + setName(display); + } + } + + void writeFile(const QVariant &task_context) Q_DECL_OVERRIDE { + writeFile(task_context.canConvert() &&task_context.toBool()); + } + + /** + * Write changes to the backend file. + */ + void writeFile(bool taskContext = false) Q_DECL_OVERRIDE { + if (mSettings->readOnly()) + { + const QString message = i18n("Trying to write to a read-only file: '%1'.", mSettings->path()); + qWarning() << message; + emit error(message); + if (taskContext) { + cancelTask(); + } + return; + } + + // We don't use the Settings::self()->path() here as that might have changed + // and in that case it would probably cause data lose. + if (mCurrentUrl.isEmpty()) + { + const QString message = i18n("No file specified."); + qWarning() << message; + emit status(Broken, message); + if (taskContext) { + cancelTask(); + } + return; + } + + if (mCurrentUrl.isLocalFile()) + { + KDirWatch::self()->stopScan(); + const bool writeResult = writeToFile(mCurrentUrl.toLocalFile()); + // Update the hash so we can detect at fileChanged() if the file actually + // did change. + mCurrentHash = calculateHash(mCurrentUrl.toLocalFile()); + saveHash(mCurrentHash); + KDirWatch::self()->startScan(); + if (!writeResult) { + qWarning() << "Error writing to file..."; + if (taskContext) { + cancelTask(); + } + return; + } + emit status(Idle, i18nc("@info:status", "Ready")); + + } else { + // Check if there is a download or an upload in progress. + if (mDownloadJob) + { + const QString message = i18n("A download is still in progress."); + qWarning() << message; + emit error(message); + if (taskContext) { + cancelTask(); + } + return; + } + + if (mUploadJob) + { + const QString message = i18n("Another file upload is still in progress."); + qWarning() << message; + emit error(message); + if (taskContext) { + cancelTask(); + } + return; + } + + // Write te items to the locally cached file. + if (!writeToFile(cacheFile())) + { + qWarning() << "Error writing to file"; + if (taskContext) { + cancelTask(); + } + return; + } + + // Update the hash so we can detect at fileChanged() if the file actually + // did change. + mCurrentHash = calculateHash(cacheFile()); + saveHash(mCurrentHash); + + KGlobal::ref(); + // Start a job to upload the locally cached file to the remote location. + mUploadJob = KIO::file_copy(QUrl::fromLocalFile(cacheFile()), mCurrentUrl, -1, KIO::Overwrite | KIO::DefaultFlags | KIO::HideProgressInfo); + connect(mUploadJob, SIGNAL(result(KJob *)), + SLOT(slotUploadJobResult(KJob *))); + connect(mUploadJob, SIGNAL(percent(KJob *, ulong)), + SLOT(handleProgress(KJob *, ulong))); + + emit status(Running, i18n("Uploading cached file to remote location.")); + } + if (taskContext) + { + taskDone(); + } + } + + virtual void collectionChanged(const Collection &collection) Q_DECL_OVERRIDE { + QString newName; + if (collection.hasAttribute()) + { + EntityDisplayAttribute *attr = collection.attribute(); + newName = attr->displayName(); + } + const QString oldName = mSettings->displayName(); + if (newName != oldName) + { + mSettings->setDisplayName(newName); + mSettings->save(); + } + SingleFileResourceBase::collectionChanged(collection); + } + + virtual Collection rootCollection() const Q_DECL_OVERRIDE + { + Collection c; + c.setParentCollection(Collection::root()); + c.setRemoteId(mSettings->path()); + const QString display = mSettings->displayName(); + c.setName(display.isEmpty() ? identifier() : display); + QStringList mimeTypes; + c.setContentMimeTypes(mSupportedMimetypes); + if (readOnly()) { + c.setRights(Collection::CanChangeCollection); + } else { + Collection::Rights rights; + rights |= Collection::CanChangeItem; + rights |= Collection::CanCreateItem; + rights |= Collection::CanDeleteItem; + rights |= Collection::CanChangeCollection; + c.setRights(rights); + } + EntityDisplayAttribute *attr = c.attribute(Collection::AddIfMissing); + attr->setDisplayName(name()); + attr->setIconName(mCollectionIcon); + return c; + } + +public Q_SLOTS: + /** + * Display the configuration dialog for the resource. + */ + void configure(WId windowId) Q_DECL_OVERRIDE { + QPointer > dlg + = new SingleFileResourceConfigDialog(windowId, mSettings); + customizeConfigDialog(dlg); + if (dlg->exec() == QDialog::Accepted) + { + if (dlg) { // in case is got destroyed + configDialogAcceptedActions(dlg); + } + reloadFile(); + synchronizeCollectionTree(); + emit configurationDialogAccepted(); + } else { + emit configurationDialogRejected(); + } + delete dlg; + } + +protected: + /** + * Implement in derived classes to customize the configuration dialog + * before it is displayed. + */ + virtual void customizeConfigDialog(SingleFileResourceConfigDialog *dlg) + { + Q_UNUSED(dlg); + } + + /** + * Implement in derived classes to do things when the configuration dialog + * has been accepted, before reloadFile() is called. + */ + virtual void configDialogAcceptedActions(SingleFileResourceConfigDialog *dlg) + { + Q_UNUSED(dlg); + } + + void retrieveCollections() Q_DECL_OVERRIDE { + Collection::List list; + list << rootCollection(); + collectionsRetrieved(list); + } + + bool readOnly() const Q_DECL_OVERRIDE + { + return mSettings->readOnly(); + } + +protected: + Settings *mSettings; +}; + +} + +#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresourcebase.cpp kdepim-runtime-15.08.0/resources/shared/singlefileresourcebase.cpp --- kdepim-runtime-4.14.6/resources/shared/singlefileresourcebase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresourcebase.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,280 +0,0 @@ -/* - Copyright (c) 2008 Bertjan Broeksema - Copyright (c) 2008 Volker Krause - - 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 "singlefileresourcebase.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -using namespace Akonadi; - -SingleFileResourceBase::SingleFileResourceBase( const QString & id ) - : ResourceBase( id ), mDownloadJob( 0 ), mUploadJob( 0 ) -{ - connect( this, SIGNAL(reloadConfiguration()), SLOT(reloadFile()) ); - QTimer::singleShot( 0, this, SLOT(readFile()) ); - - changeRecorder()->itemFetchScope().fetchFullPayload(); - changeRecorder()->fetchCollection( true ); - - connect( changeRecorder(), SIGNAL(changesAdded()), SLOT(scheduleWrite()) ); - - connect( KDirWatch::self(), SIGNAL(dirty(QString)), SLOT(fileChanged(QString)) ); - connect( KDirWatch::self(), SIGNAL(created(QString)), SLOT(fileChanged(QString)) ); - - KGlobal::locale()->insertCatalog( QLatin1String("akonadi_singlefile_resource") ); -} - -KSharedConfig::Ptr SingleFileResourceBase::runtimeConfig() const -{ - return KSharedConfig::openConfig( name() + QLatin1String("rc"), KConfig::SimpleConfig, "cache" ); -} - -bool SingleFileResourceBase::readLocalFile( const QString &fileName ) -{ - const QByteArray newHash = calculateHash( fileName ); - if ( mCurrentHash != newHash ) { - if ( !mCurrentHash.isEmpty() ) { - // There was a hash stored in the config file or a chached one from - // a previous read and it is different from the hash we just read. - handleHashChange(); - } - - if ( !readFromFile( fileName ) ) { - mCurrentHash.clear(); - mCurrentUrl = KUrl(); // reset so we don't accidentally overwrite the file - return false; - } - - if ( mCurrentHash.isEmpty() ) { - // This is the very first time we read the file so make sure to store - // the hash as writeFile() might not be called at all (e.g in case of - // read only resources). - saveHash( newHash ); - } - - // Only synchronize when the contents of the file have changed wrt to - // the last time this file was read. Before we synchronize first - // clearCache is called to make sure that the cached items get the - // actual values as present in the file. - invalidateCache( rootCollection() ); - synchronize(); - } else { - // The hash didn't change, notify implementing resources about the - // actual file name that should be used when reading the file is - // necessary. - setLocalFileName( fileName ); - } - - mCurrentHash = newHash; - return true; -} - -void SingleFileResourceBase::setLocalFileName( const QString &fileName ) -{ - // Default implementation. - if ( !readFromFile( fileName ) ) { - mCurrentHash.clear(); - mCurrentUrl = KUrl(); // reset so we don't accidentally overwrite the file - return; - } -} - -QString SingleFileResourceBase::cacheFile() const -{ - return KStandardDirs::locateLocal( "cache", QLatin1String("akonadi/") + identifier() ); -} - -QByteArray SingleFileResourceBase::calculateHash( const QString &fileName ) const -{ - QFile file( fileName ); - if ( !file.exists() ) - return QByteArray(); - - if ( !file.open( QIODevice::ReadOnly ) ) - return QByteArray(); - - QCryptographicHash hash( QCryptographicHash::Md5 ); - qint64 blockSize = 512 * 1024; // Read blocks of 512K - - while ( !file.atEnd() ) { - hash.addData( file.read( blockSize ) ); - } - - file.close(); - - return hash.result(); -} - -void SingleFileResourceBase::handleHashChange() -{ - // Default implementation does nothing. - kDebug() << "The hash has changed."; -} - -QByteArray SingleFileResourceBase::loadHash() const -{ - KConfigGroup generalGroup( runtimeConfig(), "General" ); - return QByteArray::fromHex( generalGroup.readEntry( "hash", QByteArray() ) ); -} - -void SingleFileResourceBase::saveHash( const QByteArray &hash ) const -{ - KSharedConfig::Ptr config = runtimeConfig(); - KConfigGroup generalGroup( config, "General" ); - generalGroup.writeEntry( "hash", hash.toHex() ); - config->sync(); -} - -void SingleFileResourceBase::setSupportedMimetypes( const QStringList & mimeTypes, const QString &icon ) -{ - mSupportedMimetypes = mimeTypes; - mCollectionIcon = icon; -} - -void SingleFileResourceBase::collectionChanged( const Akonadi::Collection & collection ) -{ - const QString newName = collection.displayName(); - if ( collection.hasAttribute() ) { - EntityDisplayAttribute *attr = collection.attribute(); - if ( !attr->iconName().isEmpty() ) - mCollectionIcon = attr->iconName(); - } - - if ( newName != name() ) - setName( newName ); - - changeCommitted( collection ); -} - -void SingleFileResourceBase::reloadFile() -{ - // Update the network setting. - setNeedsNetwork( !mCurrentUrl.isEmpty() && !mCurrentUrl.isLocalFile() ); - - // if we have something loaded already, make sure we write that back in case - // the settings changed - if ( !mCurrentUrl.isEmpty() && !readOnly() ) - writeFile(); - - readFile(); - - // name or rights could have changed - synchronizeCollectionTree(); -} - -void SingleFileResourceBase::handleProgress( KJob *, unsigned long pct ) -{ - emit percent( pct ); -} - -void SingleFileResourceBase::fileChanged( const QString & fileName ) -{ - if ( fileName != mCurrentUrl.toLocalFile() ) - return; - - const QByteArray newHash = calculateHash( fileName ); - - // There is only a need to synchronize when the file was changed by another - // process. At this point we're sure that it is the file that the resource - // was configured for because of the check at the beginning of this function. - if ( newHash == mCurrentHash ) - return; - - if ( !mCurrentUrl.isEmpty() ) { - QString lostFoundFileName; - const KUrl prevUrl = mCurrentUrl; - int i = 0; - do { - lostFoundFileName = KStandardDirs::locateLocal( "data", identifier() + QDir::separator() - + prevUrl.fileName() + QLatin1Char('-') + QString::number( ++i ) ); - } while ( KStandardDirs::exists( lostFoundFileName ) ); - - // create the directory if it doesn't exist yet - QDir dir = QFileInfo(lostFoundFileName).dir(); - if ( !dir.exists() ) - dir.mkpath( dir.path() ); - - mCurrentUrl = KUrl( lostFoundFileName ); - writeFile(); - mCurrentUrl = prevUrl; - - const QString message = i18n( "The file '%1' was changed on disk. " - "As a precaution, a backup of its previous contents has been created at '%2'.", - prevUrl.prettyUrl(), KUrl( lostFoundFileName ).prettyUrl() ); - emit warning( message ); - } - - readFile(); - - // Notify resources, so that information bound to the file like indexes etc. - // can be updated. - handleHashChange(); - invalidateCache( rootCollection() ); - synchronize(); -} - -void SingleFileResourceBase::scheduleWrite() -{ - scheduleCustomTask(this, "writeFile", QVariant(true), ResourceBase::AfterChangeReplay); -} - -void SingleFileResourceBase::slotDownloadJobResult( KJob *job ) -{ - if ( job->error() && job->error() != KIO::ERR_DOES_NOT_EXIST ) { - const QString message = i18n( "Could not load file '%1'.", mCurrentUrl.prettyUrl() ); - kWarning() << message; - emit status( Broken, message ); - } else { - readLocalFile( KUrl( cacheFile() ).toLocalFile() ); - } - - mDownloadJob = 0; - KGlobal::deref(); - - emit status( Idle, i18nc( "@info:status", "Ready" ) ); -} - -void SingleFileResourceBase::slotUploadJobResult( KJob *job ) -{ - if ( job->error() ) { - const QString message = i18n( "Could not save file '%1'.", mCurrentUrl.prettyUrl() ); - kWarning() << message; - emit status( Broken, message ); - } - - mUploadJob = 0; - KGlobal::deref(); - - emit status( Idle, i18nc( "@info:status", "Ready" ) ); -} - diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresourcebase.h kdepim-runtime-15.08.0/resources/shared/singlefileresourcebase.h --- kdepim-runtime-4.14.6/resources/shared/singlefileresourcebase.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresourcebase.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,188 +0,0 @@ -/* - Copyright (c) 2008 Volker Krause - - 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_SINGLEFILERESOURCEBASE_H -#define AKONADI_SINGLEFILERESOURCEBASE_H - -#include - -#include -#include -#include - -namespace KIO { -class FileCopyJob; -class Job; -} - -namespace Akonadi -{ - -/** - * Base class for single file based resources. - * @see SingleFileResource - */ -class SingleFileResourceBase : public ResourceBase, public AgentBase::Observer -{ - Q_OBJECT - public: - explicit SingleFileResourceBase( const QString &id ); - - /** - * Set the mimetypes supported by this resource and an optional icon for the collection. - */ - void setSupportedMimetypes( const QStringList &mimeTypes, const QString &icon = QString() ); - - void collectionChanged( const Akonadi::Collection &collection ); - - public Q_SLOTS: - void reloadFile(); - - /* - * Read the current state from a file. This can happen - * from direct callers, or as part of a scheduled task. - * @p taskContext specifies whether the method is being - * called from within a task or not. - */ - virtual void readFile( bool taskContext = false ) = 0; - /* - * Writes the current state out to a file. This can happen - * from direct callers, or as part of a scheduled task. - * @p taskContext specifies whether the method is being - * called from within a task or not. - */ - virtual void writeFile( bool taskContext = false ) = 0; - - /* - * Same method as above, but uses a QVariant so it can - * be called from Akonadi::ResourceScheduler. - */ - virtual void writeFile( const QVariant &taskContext ) = 0; - - protected: - /** - * Returns a pointer to the KConfig object which is used to store runtime - * information of the resource. - */ - KSharedConfig::Ptr runtimeConfig() const; - - - /** - * Handles everything needed when the hash of a file has changed between the - * last write and the first read. This stores the new hash in a config file - * and notifies implementing resources to handle a hash change if the - * previous known hash was not empty. Finally this method clears the cache - * and calls synchronize. - * Returns true on succes, false otherwise. - */ - bool readLocalFile( const QString &fileName ); - - /** - * Reimplement to read your data from the given file. - * The file is always local, loading from the network is done - * automatically if needed. - */ - virtual bool readFromFile( const QString &fileName ) = 0; - - /** - * Reimplement to write your data to the given file. - * The file is always local, storing back to the network url is done - * automatically when needed. - */ - virtual bool writeToFile( const QString &fileName ) = 0; - - /** - * It is not always needed to parse the file when a resources is started. - * (e.g. When the hash of the file is the same as the last time the resource - * has written changes to the file). In this case setActualFileName is - * called so that the implementing resource does know which file to read - * when it actually needs to read the file. - * - * The default implementation will just call readFromFile( fileName ), so - * implementing resources will have to explictly reimplement this method to - * actually get any profit of this. - * - * @p fileName This will always be a path to a local file. - */ - virtual void setLocalFileName( const QString &fileName ); - - /** - * Generates the full path for the cache file in the case that a remote file - * is used. - */ - QString cacheFile() const; - - /** - * Calculates an MD5 hash for given file. If the file does not exists - * or the path is empty, this will return an empty QByteArray. - */ - QByteArray calculateHash( const QString &fileName ) const; - - /** - * This method is called when the hash of the file has changed between the - * last writeFile() and a readFile() call. This means that the file was - * changed by another program. - * - * Note: This method is not called when the last known hash is - * empty. In that case it is assumed that the file is loaded for the - * first time. - */ - virtual void handleHashChange(); - - /** - * Returns the hash that was stored to a cache file. - */ - QByteArray loadHash() const; - - /** - * Stores the given hash into a cache file. - */ - void saveHash( const QByteArray &hash ) const; - - /** - * Returns whether the resource can be written to. - */ - virtual bool readOnly() const = 0; - - /** - * Returns the collection of this resource. - */ - virtual Collection rootCollection() const = 0; - - protected: - KUrl mCurrentUrl; - QStringList mSupportedMimetypes; - QString mCollectionIcon; - KIO::FileCopyJob *mDownloadJob; - KIO::FileCopyJob *mUploadJob; - QByteArray mCurrentHash; - - protected Q_SLOTS: - void scheduleWrite(); /// Called when changes are added to the ChangeRecorder. - - private Q_SLOTS: - void handleProgress( KJob *, unsigned long ); - void fileChanged( const QString &fileName ); - void slotDownloadJobResult( KJob * ); - void slotUploadJobResult( KJob * ); -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresourceconfigdialogbase.cpp kdepim-runtime-15.08.0/resources/shared/singlefileresourceconfigdialogbase.cpp --- kdepim-runtime-4.14.6/resources/shared/singlefileresourceconfigdialogbase.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresourceconfigdialogbase.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,229 +0,0 @@ -/* - Copyright (c) 2008 Bertjan Broeksema - Copyright (c) 2008 Volker Krause - Copyright (c) 2010,2011 David Jarvie - - 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 "singlefileresourceconfigdialogbase.h" - -#include -#include -#include -#include -#include - -#include - -using namespace Akonadi; - -SingleFileResourceConfigDialogBase::SingleFileResourceConfigDialogBase( WId windowId ) : - KDialog(), - mManager( 0 ), - mStatJob( 0 ), - mAppendedWidget( 0 ), - mDirUrlChecked( false ), - mMonitorEnabled( true ), - mLocalFileOnly( false ) -{ - ui.setupUi( mainWidget() ); - ui.kcfg_Path->setMode( KFile::File ); -#ifndef KDEPIM_MOBILE_UI - ui.statusLabel->setText( QString() ); -#endif - - setButtons( Ok | Cancel ); - - if ( windowId ) - KWindowSystem::setMainWindow( this, windowId ); - - ui.ktabwidget->setTabBarHidden( true ); - - connect( this, SIGNAL(okClicked()), SLOT(save()) ); - - connect( ui.kcfg_Path, SIGNAL(textChanged(QString)), SLOT(validate()) ); - connect( ui.kcfg_MonitorFile, SIGNAL(toggled(bool)), SLOT(validate()) ); - ui.kcfg_Path->setFocus(); - QTimer::singleShot( 0, this, SLOT(validate()) ); - setMinimumSize(600, 540); - readConfig(); -} - -SingleFileResourceConfigDialogBase::~SingleFileResourceConfigDialogBase() -{ - writeConfig(); -} - -void SingleFileResourceConfigDialogBase::writeConfig() -{ - KConfigGroup group( KGlobal::config(), "SingleFileResourceConfigDialogBase" ); - group.writeEntry( "Size", size() ); -} - -void SingleFileResourceConfigDialogBase::readConfig() -{ - KConfigGroup group( KGlobal::config(), "SingleFileResourceConfigDialogBase" ); - const QSize sizeDialog = group.readEntry( "Size", QSize(600,540) ); - if ( sizeDialog.isValid() ) { - resize( sizeDialog ); - } -} - - -void SingleFileResourceConfigDialogBase::addPage( const QString &title, QWidget *page ) -{ - ui.ktabwidget->setTabBarHidden( false ); - ui.ktabwidget->addTab( page, title ); - mManager->addWidget( page ); - mManager->updateWidgets(); -} - -void SingleFileResourceConfigDialogBase::setFilter(const QString & filter) -{ - ui.kcfg_Path->setFilter( filter ); -} - -void SingleFileResourceConfigDialogBase::setMonitorEnabled(bool enable) -{ - mMonitorEnabled = enable; -#ifdef KDEPIM_MOBILE_UI - ui.kcfg_MonitorFile->setVisible( mMonitorEnabled ); -#else - ui.groupBox_MonitorFile->setVisible( mMonitorEnabled ); -#endif -} - -void SingleFileResourceConfigDialogBase::setUrl(const KUrl &url ) -{ - ui.kcfg_Path->setUrl( url ); -} - -KUrl SingleFileResourceConfigDialogBase::url() const -{ - return ui.kcfg_Path->url(); -} - -void SingleFileResourceConfigDialogBase::setLocalFileOnly( bool local ) -{ - mLocalFileOnly = local; - ui.kcfg_Path->setMode( mLocalFileOnly ? KFile::File | KFile::LocalOnly : KFile::File ); -} - -void SingleFileResourceConfigDialogBase::appendWidget( SingleFileValidatingWidget* widget ) -{ - widget->setParent( static_cast( ui.tab ) ); - ui.tabLayout->addWidget( widget ); - connect( widget, SIGNAL(changed()), SLOT(validate()) ); - mAppendedWidget = widget; -} - -void SingleFileResourceConfigDialogBase::validate() -{ - if ( mAppendedWidget && !mAppendedWidget->validate() ) { - enableButton( Ok, false ); - return; - } - - const KUrl currentUrl = ui.kcfg_Path->url(); - if ( currentUrl.isEmpty() ) { - enableButton( Ok, false ); - return; - } - - if ( currentUrl.isLocalFile() ) { - if ( mMonitorEnabled ) { - ui.kcfg_MonitorFile->setEnabled( true ); - } -#ifndef KDEPIM_MOBILE_UI - ui.statusLabel->setText( QString() ); -#endif - - // The read-only checkbox used to be disabled if the file is read-only, - // but it is then impossible to know at a later date if the file - // permissions change, whether the user actually wanted the resource to be - // read-only or not. So just leave the read-only checkbox untouched. - enableButton( Ok, true ); - } else { - // Not a local file. - if ( mLocalFileOnly ) { - enableButton( Ok, false ); - return; - } - if ( mMonitorEnabled ) { - ui.kcfg_MonitorFile->setEnabled( false ); - } -#ifndef KDEPIM_MOBILE_UI - ui.statusLabel->setText( i18nc( "@info:status", "Checking file information..." ) ); -#endif - - if ( mStatJob ) - mStatJob->kill(); - - mStatJob = KIO::stat( currentUrl, KIO::DefaultFlags | KIO::HideProgressInfo ); - mStatJob->setDetails( 2 ); // All details. - mStatJob->setSide( KIO::StatJob::SourceSide ); - - connect( mStatJob, SIGNAL(result(KJob*)), - SLOT(slotStatJobResult(KJob*)) ); - - // Allow the OK button to be disabled until the MetaJob is finished. - enableButton( Ok, false ); - } -} - -void SingleFileResourceConfigDialogBase::slotStatJobResult( KJob* job ) -{ - if ( job->error() == KIO::ERR_DOES_NOT_EXIST && !mDirUrlChecked ) { - // The file did not exist, so let's see if the directory the file should - // reside in supports writing. - const KUrl dirUrl = ui.kcfg_Path->url().upUrl(); - - mStatJob = KIO::stat( dirUrl, KIO::DefaultFlags | KIO::HideProgressInfo ); - mStatJob->setDetails( 2 ); // All details. - mStatJob->setSide( KIO::StatJob::SourceSide ); - - connect( mStatJob, SIGNAL(result(KJob*)), - SLOT(slotStatJobResult(KJob*)) ); - - // Make sure we don't check the whole path upwards. - mDirUrlChecked = true; - return; - } else if ( job->error() ) { - // It doesn't seem possible to read nor write from the location so leave the - // ok button disabled -#ifndef KDEPIM_MOBILE_UI - ui.statusLabel->setText( QString() ); -#endif - enableButton( Ok, false ); - mDirUrlChecked = false; - mStatJob = 0; - return; - } - -#ifndef KDEPIM_MOBILE_UI - ui.statusLabel->setText( QString() ); -#endif - enableButton( Ok, true ); - - mDirUrlChecked = false; - mStatJob = 0; -} - -SingleFileValidatingWidget::SingleFileValidatingWidget( QWidget* parent ) - : QWidget( parent ) -{ -} diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresourceconfigdialogbase.h kdepim-runtime-15.08.0/resources/shared/singlefileresourceconfigdialogbase.h --- kdepim-runtime-4.14.6/resources/shared/singlefileresourceconfigdialogbase.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresourceconfigdialogbase.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,144 +0,0 @@ -/* - Copyright (c) 2008 Bertjan Broeksema - Copyright (c) 2008 Volker Krause - Copyright (c) 2010,2011 David Jarvie - - 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_SINGLEFILERESOURCECONFIGDIALOGBASE_H -#define AKONADI_SINGLEFILERESOURCECONFIGDIALOGBASE_H - -#ifdef KDEPIM_MOBILE_UI -#include "ui_singlefileresourceconfigdialog_mobile.h" -#else -#include "ui_singlefileresourceconfigdialog_desktop.h" -#endif - -#include - -class KConfigDialogManager; -class KJob; - -namespace KIO { - class StatJob; -} - -namespace Akonadi { - -class SingleFileValidatingWidget; - -/** - * Base class for the configuration dialog for single file based resources. - * @see SingleFileResourceConfigDialog - */ -class SingleFileResourceConfigDialogBase : public KDialog -{ - Q_OBJECT - public: - explicit SingleFileResourceConfigDialogBase( WId windowId ); - ~SingleFileResourceConfigDialogBase(); - - /** - * Adds @param page to the tabwidget. This can be used to add custom - * settings for a specific single file resource. - */ - void addPage( const QString &title, QWidget *page ); - - /** - * Set file extension filter. - */ - void setFilter( const QString &filter ); - - /** - * Enable and show, or disable and hide, the monitor option. - * If the option is disabled, its value will not be saved. - * By default, the monitor option is enabled. - */ - void setMonitorEnabled( bool enable ); - - /** - * Return the file URL. - */ - KUrl url() const; - - /** - * Set the file URL. - */ - void setUrl( const KUrl& url ); - - /** - * Specify whether the file must be local. - * The default is to allow both local and remote files. - */ - void setLocalFileOnly( bool local ); - - /** - * Add a widget to the dialog. - */ - void appendWidget(SingleFileValidatingWidget* widget); - - protected Q_SLOTS: - virtual void save() = 0; - - protected: - Ui::SingleFileResourceConfigDialog ui; - KConfigDialogManager* mManager; - - private Q_SLOTS: - void validate(); - void slotStatJobResult( KJob * ); - - private: - void writeConfig(); - void readConfig(); - KIO::StatJob* mStatJob; - SingleFileValidatingWidget* mAppendedWidget; - bool mDirUrlChecked; - bool mMonitorEnabled; - bool mLocalFileOnly; -}; - -/** - * Base class for widgets added to SingleFileResourceConfigDialogBase - * using its appendWidget() method. - * - * Derived classes must implement validate() and emit changed() when - * appropriate. - */ -class SingleFileValidatingWidget : public QWidget -{ - Q_OBJECT - public: - explicit SingleFileValidatingWidget( QWidget* parent = 0 ); - - /** - * Return whether the widget's value is valid when the dialog is - * accepted. - */ - virtual bool validate() const = 0; - - signals: - /** - * Signal emitted when the widget's value changes in a way which - * might affect the result of validate(). - */ - void changed(); -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresourceconfigdialog_desktop.ui kdepim-runtime-15.08.0/resources/shared/singlefileresourceconfigdialog_desktop.ui --- kdepim-runtime-4.14.6/resources/shared/singlefileresourceconfigdialog_desktop.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresourceconfigdialog_desktop.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,181 +0,0 @@ - - - SingleFileResourceConfigDialog - - - - 0 - 0 - 487 - 479 - - - - - - - 0 - - - - File - - - - - - Filename - - - - - - - - &Filename: - - - kcfg_Path - - - - - - - - - - - - Status: - - - - - - - Select the file whose contents should be represented by this resource. If the file does not exist, it will be created. A URL of a remote file can also be specified, but note that monitoring for file changes will not work in this case. - - - true - - - - - - - - - - Display Name - - - - - - - - &Name: - - - kcfg_DisplayName - - - - - - - - - - - - Enter the name used to identify this resource in displays. If not specified, the filename will be used. - - - true - - - - - - - - - - Access Rights - - - - - - Read only - - - - - - - If read-only mode is enabled, no changes will be written to the file selected above. Read-only mode will be automatically enabled if you do not have write access to the file or the file is on a remote server that does not support write access. - - - true - - - - - - - - - - Monitoring - - - - - - If file monitoring is enabled the resource will reload the file when changes are made by other programs. It also tries to create a backup in case of conflicts whenever possible. - - - true - - - - - - - Enable file &monitoring - - - - - - - - - - - - - - - KLineEdit - QLineEdit -
klineedit.h
-
- - KUrlRequester - QFrame -
kurlrequester.h
-
- - KTabWidget - QTabWidget -
ktabwidget.h
- 1 -
-
- - -
diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresourceconfigdialog.h kdepim-runtime-15.08.0/resources/shared/singlefileresourceconfigdialog.h --- kdepim-runtime-4.14.6/resources/shared/singlefileresourceconfigdialog.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresourceconfigdialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -/* - Copyright (c) 2008 Bertjan Broeksema - Copyright (c) 2008 Volker Krause - - 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_SINGLEFILERESOURCECONFIGDIALOG_H -#define AKONADI_SINGLEFILERESOURCECONFIGDIALOG_H - -#include "singlefileresourceconfigdialogbase.h" - -#include - -namespace Akonadi { - -/** - * Configuration dialog for single file resources. - */ -template -class SingleFileResourceConfigDialog : public SingleFileResourceConfigDialogBase -{ - Settings *mSettings; - - public: - explicit SingleFileResourceConfigDialog( WId windowId, Settings *settings ) - : SingleFileResourceConfigDialogBase( windowId ) - , mSettings( settings ) - { - ui.kcfg_Path->setUrl( KUrl( mSettings->path() ) ); - mManager = new KConfigDialogManager( this, mSettings ); - mManager->updateWidgets(); - } - - protected: - void save() - { - mManager->updateSettings(); - mSettings->setPath( ui.kcfg_Path->url().url() ); - mSettings->writeConfig(); - } -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresourceconfigdialog_mobile.ui kdepim-runtime-15.08.0/resources/shared/singlefileresourceconfigdialog_mobile.ui --- kdepim-runtime-4.14.6/resources/shared/singlefileresourceconfigdialog_mobile.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresourceconfigdialog_mobile.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,108 +0,0 @@ - - - SingleFileResourceConfigDialog - - - - 0 - 0 - 487 - 183 - - - - - - - - File - - - - - - - - &Filename: - - - kcfg_Path - - - - - - - - - - - - - - &Display name: - - - kcfg_DisplayName - - - - - - - - - - - - Read only - - - - - - - Enable file &monitoring - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - KLineEdit - QLineEdit -
klineedit.h
-
- - KUrlRequester - QFrame -
kurlrequester.h
-
- - KTabWidget - QTabWidget -
ktabwidget.h
- 1 -
-
- - -
diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresourceconfigdialog.ui kdepim-runtime-15.08.0/resources/shared/singlefileresourceconfigdialog.ui --- kdepim-runtime-4.14.6/resources/shared/singlefileresourceconfigdialog.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresourceconfigdialog.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ - - - SingleFileResourceConfigDialog - - - - - - - - - - - KTabWidget - QTabWidget -
ktabwidget.h
- 1 -
-
- - -
diff -Nru kdepim-runtime-4.14.6/resources/shared/singlefileresource.h kdepim-runtime-15.08.0/resources/shared/singlefileresource.h --- kdepim-runtime-4.14.6/resources/shared/singlefileresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/singlefileresource.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,365 +0,0 @@ -/* - Copyright (c) 2008 Bertjan Broeksema - Copyright (c) 2008 Volker Krause - Copyright (c) 2010 David Jarvie - - 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_SINGLEFILERESOURCE_H -#define AKONADI_SINGLEFILERESOURCE_H - -#include "singlefileresourcebase.h" -#include "singlefileresourceconfigdialog.h" - -#include - -#include -#include -#include -#include - -#include -#include -#include - -namespace Akonadi -{ - -/** - * Base class for single file based resources. - */ -template -class SingleFileResource : public SingleFileResourceBase -{ - public: - SingleFileResource( const QString &id ) - : SingleFileResourceBase( id ) - , mSettings( new Settings( componentData().config() ) ) - { - // The resource needs network when the path refers to a non local file. - setNeedsNetwork( !KUrl( mSettings->path() ).isLocalFile() ); - } - ~SingleFileResource() - { - delete mSettings; - } - - /** - * Read changes from the backend file. - */ - void readFile( bool taskContext = false ) - { - if ( KDirWatch::self()->contains( mCurrentUrl.toLocalFile() ) ) - KDirWatch::self()->removeFile( mCurrentUrl.toLocalFile() ); - - if ( mSettings->path().isEmpty() ) { - const QString message = i18n( "No file selected." ); - kWarning() << message; - emit status( NotConfigured, i18n("The resource not configured yet") ); - if ( taskContext ) - cancelTask(); - return; - } - - mCurrentUrl = KUrl( mSettings->path() ); - if ( mCurrentHash.isEmpty() ) { - // First call to readFile() lets see if there is a hash stored in a - // cache file. If both are the same than there is no need to load the - // file and synchronize the resource. - mCurrentHash = loadHash(); - } - - if ( mCurrentUrl.isLocalFile() ) - { - if ( mSettings->displayName().isEmpty() - && ( name().isEmpty() || name() == identifier() ) && !mCurrentUrl.isEmpty() ) - setName( mCurrentUrl.fileName() ); - - // check if the file does not exist yet, if so, create it - if ( !QFile::exists( mCurrentUrl.toLocalFile() ) ) { - QFile f( mCurrentUrl.toLocalFile() ); - - // first create try to create the directory the file should be located in - QDir dir = QFileInfo(f).dir(); - if ( ! dir.exists() ) { - dir.mkpath( dir.path() ); - } - - if ( f.open( QIODevice::WriteOnly ) && f.resize( 0 ) ) { - emit status( Idle, i18nc( "@info:status", "Ready" ) ); - } else { - const QString message = i18n( "Could not create file '%1'.", mCurrentUrl.prettyUrl() ); - kWarning() << message; - emit status( Broken, message ); - mCurrentUrl.clear(); - if ( taskContext ) - cancelTask(); - return; - } - } - - // Cache, because readLocalFile will clear mCurrentUrl on failure. - const QString localFileName = mCurrentUrl.toLocalFile(); - if ( !readLocalFile( mCurrentUrl.toLocalFile() ) ) { - const QString message = i18n( "Could not read file '%1'", localFileName ); - kWarning() << message; - emit status( Broken, message ); - if ( taskContext ) - cancelTask(); - return; - } - - if ( mSettings->monitorFile() ) - KDirWatch::self()->addFile( mCurrentUrl.toLocalFile() ); - - emit status( Idle, i18nc( "@info:status", "Ready" ) ); - } - else // !mCurrentUrl.isLocalFile() - { - if ( mDownloadJob ) - { - const QString message = i18n( "Another download is still in progress." ); - kWarning() << message; - emit error( message ); - if ( taskContext ) - cancelTask(); - return; - } - - if ( mUploadJob ) - { - const QString message = i18n( "Another file upload is still in progress." ); - kWarning() << message; - emit error( message ); - if ( taskContext ) - cancelTask(); - return; - } - - KGlobal::ref(); - - // NOTE: Test what happens with remotefile -> save, close before save is finished. - mDownloadJob = KIO::file_copy( mCurrentUrl, KUrl( cacheFile() ), -1, KIO::Overwrite | KIO::DefaultFlags | KIO::HideProgressInfo ); - connect( mDownloadJob, SIGNAL(result(KJob*)), - SLOT(slotDownloadJobResult(KJob*)) ); - connect( mDownloadJob, SIGNAL(percent(KJob*,ulong)), - SLOT(handleProgress(KJob*,ulong)) ); - - emit status( Running, i18n( "Downloading remote file." ) ); - } - - const QString display = mSettings->displayName(); - if ( !display.isEmpty() ) { - setName( display ); - } - } - - void writeFile( const QVariant &task_context ) - { - writeFile( task_context.canConvert() && task_context.toBool() ); - } - - /** - * Write changes to the backend file. - */ - void writeFile( bool taskContext = false ) - { - if ( mSettings->readOnly() ) { - const QString message = i18n( "Trying to write to a read-only file: '%1'.", mSettings->path() ); - kWarning() << message; - emit error( message ); - if ( taskContext ) - cancelTask(); - return; - } - - // We don't use the Settings::self()->path() here as that might have changed - // and in that case it would probably cause data lose. - if ( mCurrentUrl.isEmpty() ) { - const QString message = i18n( "No file specified." ); - kWarning() << message; - emit status( Broken, message ); - if ( taskContext ) - cancelTask(); - return; - } - - if ( mCurrentUrl.isLocalFile() ) { - KDirWatch::self()->stopScan(); - const bool writeResult = writeToFile( mCurrentUrl.toLocalFile() ); - // Update the hash so we can detect at fileChanged() if the file actually - // did change. - mCurrentHash = calculateHash( mCurrentUrl.toLocalFile() ); - saveHash( mCurrentHash ); - KDirWatch::self()->startScan(); - if ( !writeResult ) - { - kWarning() << "Error writing to file..."; - if ( taskContext ) - cancelTask(); - return; - } - emit status( Idle, i18nc( "@info:status", "Ready" ) ); - - } else { - // Check if there is a download or an upload in progress. - if ( mDownloadJob ) { - const QString message = i18n( "A download is still in progress." ); - kWarning() << message; - emit error( message ); - if ( taskContext ) - cancelTask(); - return; - } - - if ( mUploadJob ) { - const QString message = i18n( "Another file upload is still in progress." ); - kWarning() << message; - emit error( message ); - if ( taskContext ) - cancelTask(); - return; - } - - // Write te items to the locally cached file. - if ( !writeToFile( cacheFile() ) ) - { - kWarning() << "Error writing to file"; - if ( taskContext ) - cancelTask(); - return; - } - - // Update the hash so we can detect at fileChanged() if the file actually - // did change. - mCurrentHash = calculateHash( cacheFile() ); - saveHash( mCurrentHash ); - - KGlobal::ref(); - // Start a job to upload the locally cached file to the remote location. - mUploadJob = KIO::file_copy( KUrl( cacheFile() ), mCurrentUrl, -1, KIO::Overwrite | KIO::DefaultFlags | KIO::HideProgressInfo ); - connect( mUploadJob, SIGNAL(result(KJob*)), - SLOT(slotUploadJobResult(KJob*)) ); - connect( mUploadJob, SIGNAL(percent(KJob*,ulong)), - SLOT(handleProgress(KJob*,ulong)) ); - - emit status( Running, i18n( "Uploading cached file to remote location." ) ); - } - if ( taskContext ) - taskDone(); - } - - virtual void collectionChanged( const Collection &collection ) - { - QString newName; - if ( collection.hasAttribute() ) { - EntityDisplayAttribute *attr = collection.attribute(); - newName = attr->displayName(); - } - const QString oldName = mSettings->displayName(); - if ( newName != oldName ) { - mSettings->setDisplayName( newName ); - mSettings->writeConfig(); - } - SingleFileResourceBase::collectionChanged( collection ); - } - - virtual Collection rootCollection() const - { - Collection c; - c.setParentCollection( Collection::root() ); - c.setRemoteId( mSettings->path() ); - const QString display = mSettings->displayName(); - c.setName( display.isEmpty() ? identifier() : display ); - QStringList mimeTypes; - c.setContentMimeTypes( mSupportedMimetypes ); - if ( readOnly() ) { - c.setRights( Collection::CanChangeCollection ); - } else { - Collection::Rights rights; - rights |= Collection::CanChangeItem; - rights |= Collection::CanCreateItem; - rights |= Collection::CanDeleteItem; - rights |= Collection::CanChangeCollection; - c.setRights( rights ); - } - EntityDisplayAttribute* attr = c.attribute( Collection::AddIfMissing ); - attr->setDisplayName( name() ); - attr->setIconName( mCollectionIcon ); - return c; - } - - public Q_SLOTS: - /** - * Display the configuration dialog for the resource. - */ - void configure( WId windowId ) - { - QPointer > dlg - = new SingleFileResourceConfigDialog( windowId, mSettings ); - customizeConfigDialog( dlg ); - if ( dlg->exec() == QDialog::Accepted ) { - if ( dlg ) { // in case is got destroyed - configDialogAcceptedActions( dlg ); - } - reloadFile(); - synchronizeCollectionTree(); - emit configurationDialogAccepted(); - } else { - emit configurationDialogRejected(); - } - delete dlg; - } - - protected: - /** - * Implement in derived classes to customize the configuration dialog - * before it is displayed. - */ - virtual void customizeConfigDialog( SingleFileResourceConfigDialog* dlg ) - { - Q_UNUSED(dlg); - } - - /** - * Implement in derived classes to do things when the configuration dialog - * has been accepted, before reloadFile() is called. - */ - virtual void configDialogAcceptedActions( SingleFileResourceConfigDialog* dlg ) - { - Q_UNUSED(dlg); - } - - void retrieveCollections() - { - Collection::List list; - list << rootCollection(); - collectionsRetrieved( list ); - } - - bool readOnly() const - { - return mSettings->readOnly(); - } - - protected: - Settings *mSettings; -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/resources/shared/tests/CMakeLists.txt kdepim-runtime-15.08.0/resources/shared/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/shared/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -macro(_add_test _source) - set(_test ${_source}) - get_filename_component(_name ${_source} NAME_WE) - kde4_add_unit_test(${_name} TESTNAME akonadi-${_name} ${_test}) - target_link_libraries(${_name} ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDE4_KDECORE_LIBS} - ${AKONADI_COMMON_LIBRARIES} ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_KIMAP_LIBS}) -endmacro() - -_add_test( collectionannotationattributetest.cpp ) -_add_test( imapaclattributetest.cpp ) diff -Nru kdepim-runtime-4.14.6/resources/shared/tests/collectionannotationattributetest.cpp kdepim-runtime-15.08.0/resources/shared/tests/collectionannotationattributetest.cpp --- kdepim-runtime-4.14.6/resources/shared/tests/collectionannotationattributetest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/tests/collectionannotationattributetest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -/* - Copyright (C) 2009 Volker Krause - - 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 -#include -#include "../collectionannotationsattribute.cpp" - -typedef QMap Annotation; -Q_DECLARE_METATYPE( Annotation ) - -using namespace Akonadi; - -class CollectionAnnotationAttributeTest : public QObject -{ - Q_OBJECT - private slots: - void testSerializeDeserialize_data() - { - QTest::addColumn( "annotation" ); - - Annotation a; - QTest::newRow( "empty" ) << a; - - a.insert( "/vendor/cmu/cyrus-imapd/lastpop", "" ); - QTest::newRow( "empty value, single key" ) << a; - - a.insert( "/vendor/cmu/cyrus-imapd/condstore", "false" ); - QTest::newRow( "empty value, two keys" ) << a; - - a.insert( "/vendor/cmu/cyrus-imapd/sharedseen", "false" ); - QTest::newRow( "empty value, three keys" ) << a; - - a.clear(); - a.insert( "vendor/cmu/cyrus-imapd/lastpop", " " ); - QTest::newRow( "space value, single key" ) << a; - - a.insert( "/vendor/cmu/cyrus-imapd/condstore", "false" ); - QTest::newRow( "space value, two keys" ) << a; - - a.insert( "/vendor/cmu/cyrus-imapd/sharedseen", "false" ); - QTest::newRow( "space value, three keys" ) << a; - } - - void testSerializeDeserialize() - { - QFETCH( Annotation, annotation ); - CollectionAnnotationsAttribute *attr1 = new CollectionAnnotationsAttribute(); - attr1->setAnnotations( annotation ); - QCOMPARE( attr1->annotations(), annotation ); - - CollectionAnnotationsAttribute *attr2 = new CollectionAnnotationsAttribute(); - attr2->deserialize( attr1->serialized() ); - QCOMPARE( attr2->annotations(), annotation ); - - CollectionAnnotationsAttribute *attr3 = new CollectionAnnotationsAttribute(); - attr3->setAnnotations( attr2->annotations() ); - QCOMPARE( attr3->serialized(), attr1->serialized() ); - - delete attr1; - delete attr2; - delete attr3; - } - -}; - -QTEST_KDEMAIN( CollectionAnnotationAttributeTest, NoGUI ) - -#include "collectionannotationattributetest.moc" - diff -Nru kdepim-runtime-4.14.6/resources/shared/tests/imapaclattributetest.cpp kdepim-runtime-15.08.0/resources/shared/tests/imapaclattributetest.cpp --- kdepim-runtime-4.14.6/resources/shared/tests/imapaclattributetest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/shared/tests/imapaclattributetest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,110 +0,0 @@ -/* - Copyright (C) 2010 Tobias Koenig - - 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 -#include -#include "../imapaclattribute.cpp" - -using namespace Akonadi; - -typedef QMap ImapAcl; - -Q_DECLARE_METATYPE( ImapAcl ) - -class ImapAclAttributeTest : public QObject -{ - Q_OBJECT - - private Q_SLOTS: - - void testSerializeDeserialize_data() - { - QTest::addColumn( "rights" ); - QTest::addColumn( "serialized" ); - QTest::addColumn( "oldSerialized" ); - - ImapAcl acl; - QTest::newRow( "empty" ) << acl << QByteArray( " %% " ) << QByteArray( "testme@host l %% " ); - - acl.insert( "user@host", KIMAP::Acl::None ); - QTest::newRow( "none" ) << acl << QByteArray( "user@host %% " ) << QByteArray( "testme@host l %% user@host " ); - - acl.insert( "user@host", KIMAP::Acl::Lookup ); - QTest::newRow( "lookup" ) << acl << QByteArray( "user@host l %% " ) << QByteArray( "testme@host l %% user@host l" ); - - acl.insert( "user@host", KIMAP::Acl::Lookup | KIMAP::Acl::Read ); - QTest::newRow( "lookup/read" ) << acl << QByteArray( "user@host lr %% " ) << QByteArray( "testme@host l %% user@host lr" ); - - acl.insert( "otheruser@host", KIMAP::Acl::Lookup | KIMAP::Acl::Read ); - QTest::newRow( "lookup/read" ) << acl << QByteArray( "otheruser@host lr % user@host lr %% " ) - << QByteArray( "testme@host l %% otheruser@host lr % user@host lr" ); - } - - void testSerializeDeserialize() - { - QFETCH( ImapAcl, rights ); - QFETCH( QByteArray, serialized ); - QFETCH( QByteArray, oldSerialized ); - - ImapAclAttribute *attr = new ImapAclAttribute(); - attr->setRights( rights ); - QCOMPARE( attr->serialized(), serialized ); - - ImapAcl acl; - acl.insert( "testme@host", KIMAP::Acl::Lookup ); - attr->setRights( acl ); - - QCOMPARE( attr->serialized(), oldSerialized ); - - delete attr; - - ImapAclAttribute deserializeAttr; - deserializeAttr.deserialize( serialized ); - QCOMPARE( deserializeAttr.rights(), rights ); - } - - void testOldRights() - { - ImapAcl acls; - acls.insert( "first_user@host", KIMAP::Acl::Lookup | KIMAP::Acl::Read ); - acls.insert( "second_user@host", KIMAP::Acl::Lookup | KIMAP::Acl::Read ); - acls.insert( "third_user@host", KIMAP::Acl::Lookup | KIMAP::Acl::Read ); - - ImapAclAttribute *attr = new ImapAclAttribute(); - attr->setRights( acls ); - - ImapAcl oldAcls = acls; - - acls.remove( "first_user@host" ); - acls.remove( "third_user@host" ); - - attr->setRights( acls ); - - QCOMPARE( attr->oldRights(), oldAcls ); - - attr->setRights( acls ); - - QCOMPARE( attr->oldRights(), acls ); - delete attr; - } -}; - -QTEST_KDEMAIN( ImapAclAttributeTest, NoGUI ) - -#include "imapaclattributetest.moc" diff -Nru kdepim-runtime-4.14.6/resources/vcard/autotests/CMakeLists.txt kdepim-runtime-15.08.0/resources/vcard/autotests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/vcard/autotests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/autotests/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,6 @@ +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/vcardtest.xml ${CMAKE_CURRENT_BINARY_DIR}/vcardtest.xml COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/vcardtest-readonly.xml ${CMAKE_CURRENT_BINARY_DIR}/vcardtest-readonly.xml COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/vcardtest.vcf ${CMAKE_CURRENT_BINARY_DIR}/vcardtest.vcf COPYONLY) + +akonadi_add_resourcetest( vcard-read vcardtest.js ) +akonadi_add_resourcetest( vcard-read-readonly vcardtest-readonly.js ) diff -Nru kdepim-runtime-4.14.6/resources/vcard/autotests/vcardtest.js kdepim-runtime-15.08.0/resources/vcard/autotests/vcardtest.js --- kdepim-runtime-4.14.6/resources/vcard/autotests/vcardtest.js 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/autotests/vcardtest.js 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,11 @@ +Resource.setType( "akonadi_vcard_resource" ); +Resource.setPathOption( "Path", "vcardtest.vcf" ); +Resource.create(); + +XmlOperations.setXmlFile( "vcardtest.xml" ); +XmlOperations.setRootCollections( Resource.identifier() ); +XmlOperations.setCollectionKey( "None" ); // we only expect one collection +XmlOperations.ignoreCollectionField( "Name" ); // name is the resource identifier and thus unpredictable +XmlOperations.ignoreCollectionField( "RemoteId" ); // remote id is the absolute path +XmlOperations.assertEqual(); + diff -Nru kdepim-runtime-4.14.6/resources/vcard/autotests/vcardtest-readonly.js kdepim-runtime-15.08.0/resources/vcard/autotests/vcardtest-readonly.js --- kdepim-runtime-4.14.6/resources/vcard/autotests/vcardtest-readonly.js 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/autotests/vcardtest-readonly.js 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,12 @@ +Resource.setType( "akonadi_vcard_resource" ); +Resource.setPathOption( "Path", "vcardtest.vcf" ); +Resource.setOption( "ReadOnly", true ); +Resource.create(); + +XmlOperations.setXmlFile( "vcardtest-readonly.xml" ); +XmlOperations.setRootCollections( Resource.identifier() ); +XmlOperations.setCollectionKey( "None" ); // we only expect one collection +XmlOperations.ignoreCollectionField( "Name" ); // name is the resource identifier and thus unpredictable +XmlOperations.ignoreCollectionField( "RemoteId" ); // remote id is the absolute path +XmlOperations.assertEqual(); + diff -Nru kdepim-runtime-4.14.6/resources/vcard/autotests/vcardtest-readonly.xml kdepim-runtime-15.08.0/resources/vcard/autotests/vcardtest-readonly.xml --- kdepim-runtime-4.14.6/resources/vcard/autotests/vcardtest-readonly.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/autotests/vcardtest-readonly.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,24 @@ + + + W + ("vcardtest.vcf" "office-address-book") + + +BEGIN:VCARD +EMAIL:vkrause@kde.org +FN:Volker Krause +GEO:52.500000;13.366667 +N:Krause;Volker;;; +NAME:Volker Krause +ORG:KDE +REV:2003-02-27T20:08:42Z +ROLE:Author of this file +TZ:+02:00 +UID:bb2slGmqxb +URL:http://www.akonadi-project.org +VERSION:3.0 +END:VCARD + + + + diff -Nru kdepim-runtime-4.14.6/resources/vcard/autotests/vcardtest.vcf kdepim-runtime-15.08.0/resources/vcard/autotests/vcardtest.vcf --- kdepim-runtime-4.14.6/resources/vcard/autotests/vcardtest.vcf 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/autotests/vcardtest.vcf 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,15 @@ +BEGIN:VCARD +EMAIL:vkrause@kde.org +FN:Volker Krause +GEO:52.500000;13.366667 +N:Krause;Volker;;; +NAME:Volker Krause +ORG:KDE +REV:2003-02-27T20:08:42Z +ROLE:Author of this file +TZ:+02:00 +UID:bb2slGmqxb +URL:http://www.akonadi-project.org +VERSION:3.0 +END:VCARD + diff -Nru kdepim-runtime-4.14.6/resources/vcard/autotests/vcardtest.xml kdepim-runtime-15.08.0/resources/vcard/autotests/vcardtest.xml --- kdepim-runtime-4.14.6/resources/vcard/autotests/vcardtest.xml 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/autotests/vcardtest.xml 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,24 @@ + + + wcdW + ("vcardtest.vcf" "office-address-book") + + +BEGIN:VCARD +EMAIL:vkrause@kde.org +FN:Volker Krause +GEO:52.500000;13.366667 +N:Krause;Volker;;; +NAME:Volker Krause +ORG:KDE +REV:2003-02-27T20:08:42Z +ROLE:Author of this file +TZ:+02:00 +UID:bb2slGmqxb +URL:http://www.akonadi-project.org +VERSION:3.0 +END:VCARD + + + + diff -Nru kdepim-runtime-4.14.6/resources/vcard/CMakeLists.txt kdepim-runtime-15.08.0/resources/vcard/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/vcard/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,38 +1,36 @@ -include_directories( - ${kdepim-runtime_SOURCE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} -) -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) -add_subdirectory( tests ) + +if(BUILD_TESTING) + add_subdirectory( autotests ) +endif() + +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_vcard_resource\") ########### next target ############### set( vcardresource_SRCS - ${AKONADI_SINGLEFILERESOURCE_SHARED_SOURCES} vcardresource.cpp ) -install( FILES vcardresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) +install( FILES vcardresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) -kde4_add_ui_files(vcardresource_SRCS ${AKONADI_SINGLEFILERESOURCE_SHARED_UI}) -kde4_add_kcfg_files(vcardresource_SRCS settings.kcfgc) +kconfig_add_kcfg_files(vcardresource_SRCS settings.kcfgc) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/vcardresource.kcfg org.kde.Akonadi.VCard.Settings) -qt4_add_dbus_adaptor(vcardresource_SRCS +qt5_add_dbus_adaptor(vcardresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.VCard.Settings.xml settings.h Akonadi_VCard_Resource::Settings vcardsettingsadaptor VCardSettingsAdaptor ) -kde4_add_plugin(akonadi_vcard_resource ${vcardresource_SRCS}) +add_executable(akonadi_vcard_resource ${vcardresource_SRCS}) add_subdirectory( wizard ) -if (Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_vcard_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) set_target_properties(akonadi_vcard_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.VCard") set_target_properties(akonadi_vcard_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi VCard Resource") endif () -target_link_libraries(akonadi_vcard_resource ${KDEPIMLIBS_AKONADI_LIBS} ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${KDE4_KDECORE_LIBS} ${KDEPIMLIBS_KABC_LIBS} ${KDE4_KIO_LIBS}) +target_link_libraries(akonadi_vcard_resource KF5::AkonadiCore KF5::KIOCore KF5::AkonadiAgentBase KF5::Contacts KF5::DBusAddons akonadi-singlefileresource) -install(TARGETS akonadi_vcard_resource DESTINATION ${PLUGIN_INSTALL_DIR}) +install(TARGETS akonadi_vcard_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/vcard/settings.kcfgc kdepim-runtime-15.08.0/resources/vcard/settings.kcfgc --- kdepim-runtime-4.14.6/resources/vcard/settings.kcfgc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/settings.kcfgc 2015-08-10 21:01:02.000000000 +0000 @@ -6,4 +6,4 @@ Singleton=false #IncludeFiles= GlobalEnums=true -Namespace=Akonadi_VCard_Resource +NameSpace=Akonadi_VCard_Resource diff -Nru kdepim-runtime-4.14.6/resources/vcard/tests/CMakeLists.txt kdepim-runtime-15.08.0/resources/vcard/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/vcard/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/vcardtest.xml ${CMAKE_CURRENT_BINARY_DIR}/vcardtest.xml COPYONLY) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/vcardtest-readonly.xml ${CMAKE_CURRENT_BINARY_DIR}/vcardtest-readonly.xml COPYONLY) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/vcardtest.vcf ${CMAKE_CURRENT_BINARY_DIR}/vcardtest.vcf COPYONLY) - -akonadi_add_resourcetest( vcard-read vcardtest.js ) -akonadi_add_resourcetest( vcard-read-readonly vcardtest-readonly.js ) diff -Nru kdepim-runtime-4.14.6/resources/vcard/tests/vcardtest.js kdepim-runtime-15.08.0/resources/vcard/tests/vcardtest.js --- kdepim-runtime-4.14.6/resources/vcard/tests/vcardtest.js 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/tests/vcardtest.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -Resource.setType( "akonadi_vcard_resource" ); -Resource.setPathOption( "Path", "vcardtest.vcf" ); -Resource.create(); - -XmlOperations.setXmlFile( "vcardtest.xml" ); -XmlOperations.setRootCollections( Resource.identifier() ); -XmlOperations.setCollectionKey( "None" ); // we only expect one collection -XmlOperations.ignoreCollectionField( "Name" ); // name is the resource identifier and thus unpredictable -XmlOperations.ignoreCollectionField( "RemoteId" ); // remote id is the absolute path -XmlOperations.assertEqual(); - diff -Nru kdepim-runtime-4.14.6/resources/vcard/tests/vcardtest-readonly.js kdepim-runtime-15.08.0/resources/vcard/tests/vcardtest-readonly.js --- kdepim-runtime-4.14.6/resources/vcard/tests/vcardtest-readonly.js 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/tests/vcardtest-readonly.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -Resource.setType( "akonadi_vcard_resource" ); -Resource.setPathOption( "Path", "vcardtest.vcf" ); -Resource.setOption( "ReadOnly", true ); -Resource.create(); - -XmlOperations.setXmlFile( "vcardtest-readonly.xml" ); -XmlOperations.setRootCollections( Resource.identifier() ); -XmlOperations.setCollectionKey( "None" ); // we only expect one collection -XmlOperations.ignoreCollectionField( "Name" ); // name is the resource identifier and thus unpredictable -XmlOperations.ignoreCollectionField( "RemoteId" ); // remote id is the absolute path -XmlOperations.assertEqual(); - diff -Nru kdepim-runtime-4.14.6/resources/vcard/tests/vcardtest-readonly.xml kdepim-runtime-15.08.0/resources/vcard/tests/vcardtest-readonly.xml --- kdepim-runtime-4.14.6/resources/vcard/tests/vcardtest-readonly.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/tests/vcardtest-readonly.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ - - - W - ("vcardtest.vcf" "office-address-book") - - -BEGIN:VCARD -EMAIL:vkrause@kde.org -FN:Volker Krause -GEO:52.500000;13.366667 -N:Krause;Volker;;; -NAME:Volker Krause -ORG:KDE -REV:2003-02-27T20:08:42Z -ROLE:Author of this file -TZ:+02:00 -UID:bb2slGmqxb -URL:http://www.akonadi-project.org -VERSION:3.0 -END:VCARD - - - - diff -Nru kdepim-runtime-4.14.6/resources/vcard/tests/vcardtest.vcf kdepim-runtime-15.08.0/resources/vcard/tests/vcardtest.vcf --- kdepim-runtime-4.14.6/resources/vcard/tests/vcardtest.vcf 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/tests/vcardtest.vcf 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -BEGIN:VCARD -EMAIL:vkrause@kde.org -FN:Volker Krause -GEO:52.500000;13.366667 -N:Krause;Volker;;; -NAME:Volker Krause -ORG:KDE -REV:2003-02-27T20:08:42Z -ROLE:Author of this file -TZ:+02:00 -UID:bb2slGmqxb -URL:http://www.akonadi-project.org -VERSION:3.0 -END:VCARD - diff -Nru kdepim-runtime-4.14.6/resources/vcard/tests/vcardtest.xml kdepim-runtime-15.08.0/resources/vcard/tests/vcardtest.xml --- kdepim-runtime-4.14.6/resources/vcard/tests/vcardtest.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/tests/vcardtest.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ - - - wcdW - ("vcardtest.vcf" "office-address-book") - - -BEGIN:VCARD -EMAIL:vkrause@kde.org -FN:Volker Krause -GEO:52.500000;13.366667 -N:Krause;Volker;;; -NAME:Volker Krause -ORG:KDE -REV:2003-02-27T20:08:42Z -ROLE:Author of this file -TZ:+02:00 -UID:bb2slGmqxb -URL:http://www.akonadi-project.org -VERSION:3.0 -END:VCARD - - - - diff -Nru kdepim-runtime-4.14.6/resources/vcard/vcardresource.cpp kdepim-runtime-15.08.0/resources/vcard/vcardresource.cpp --- kdepim-runtime-4.14.6/resources/vcard/vcardresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/vcardresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -22,168 +22,176 @@ #include "vcardsettingsadaptor.h" #include "singlefileresourceconfigdialog.h" -#include -#include +#include +#include -#include -#include -#include +#include #include using namespace Akonadi; using namespace Akonadi_VCard_Resource; -VCardResource::VCardResource( const QString &id ) - : SingleFileResource( id ) +VCardResource::VCardResource(const QString &id) + : SingleFileResource(id) { - setSupportedMimetypes( QStringList() << KABC::Addressee::mimeType(), QLatin1String("office-address-book") ); + setSupportedMimetypes(QStringList() << KContacts::Addressee::mimeType(), QStringLiteral("office-address-book")); - new VCardSettingsAdaptor( mSettings ); - DBusConnectionPool::threadConnection().registerObject( QLatin1String( "/Settings" ), - mSettings, QDBusConnection::ExportAdaptors ); + new VCardSettingsAdaptor(mSettings); + KDBusConnectionPool::threadConnection().registerObject(QStringLiteral("/Settings"), + mSettings, QDBusConnection::ExportAdaptors); } VCardResource::~VCardResource() { - mAddressees.clear(); + mAddressees.clear(); } -bool VCardResource::retrieveItem( const Akonadi::Item &item, const QSet &parts ) +bool VCardResource::retrieveItem(const Akonadi::Item &item, const QSet &parts) { - Q_UNUSED( parts ); - const QString rid = item.remoteId(); - if ( !mAddressees.contains( rid ) ) { - emit error( i18n( "Contact with uid '%1' not found." ,rid ) ); - return false; - } - Item i( item ); - i.setPayload( mAddressees.value( rid ) ); - itemRetrieved( i ); - return true; + Q_UNUSED(parts); + const QString rid = item.remoteId(); + if (!mAddressees.contains(rid)) { + Q_EMIT error(i18n("Contact with uid '%1' not found." , rid)); + return false; + } + Item i(item); + i.setPayload(mAddressees.value(rid)); + itemRetrieved(i); + return true; } void VCardResource::aboutToQuit() { - if ( !mSettings->readOnly() ) - writeFile(); - mSettings->writeConfig(); + if (!mSettings->readOnly()) { + writeFile(); + } + mSettings->save(); } -void VCardResource::customizeConfigDialog( SingleFileResourceConfigDialog* dlg ) +void VCardResource::customizeConfigDialog(SingleFileResourceConfigDialog *dlg) { - dlg->setWindowIcon( KIcon( QLatin1String("text-directory") ) ); - dlg->setFilter( QLatin1String("*.vcf|") + i18nc("Filedialog filter for *.vcf", "vCard Address Book File" ) ); - dlg->setCaption( i18n("Select Address Book") ); + dlg->setWindowIcon(QIcon::fromTheme(QStringLiteral("text-directory"))); + dlg->setFilter(QStringLiteral("*.vcf|") + i18nc("Filedialog filter for *.vcf", "vCard Address Book File")); + dlg->setWindowTitle(i18n("Select Address Book")); } -void VCardResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection& ) +void VCardResource::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &) { - KABC::Addressee addressee; - if ( item.hasPayload() ) - addressee = item.payload(); + KContacts::Addressee addressee; + if (item.hasPayload()) { + addressee = item.payload(); + } - if ( !addressee.isEmpty() ) { - mAddressees.insert( addressee.uid(), addressee ); + if (!addressee.isEmpty()) { + mAddressees.insert(addressee.uid(), addressee); - Item i( item ); - i.setRemoteId( addressee.uid() ); - changeCommitted( i ); + Item i(item); + i.setRemoteId(addressee.uid()); + changeCommitted(i); - scheduleWrite(); - } else { - changeProcessed(); - } + scheduleWrite(); + } else { + changeProcessed(); + } } -void VCardResource::itemChanged( const Akonadi::Item &item, const QSet& ) +void VCardResource::itemChanged(const Akonadi::Item &item, const QSet &) { - KABC::Addressee addressee; - if ( item.hasPayload() ) - addressee = item.payload(); + KContacts::Addressee addressee; + if (item.hasPayload()) { + addressee = item.payload(); + } - if ( !addressee.isEmpty() ) { - mAddressees.insert( addressee.uid(), addressee ); + if (!addressee.isEmpty()) { + mAddressees.insert(addressee.uid(), addressee); - Item i( item ); - i.setRemoteId( addressee.uid() ); - changeCommitted( i ); + Item i(item); + i.setRemoteId(addressee.uid()); + changeCommitted(i); - scheduleWrite(); - } else { - changeProcessed(); - } + scheduleWrite(); + } else { + changeProcessed(); + } } -void VCardResource::itemRemoved(const Akonadi::Item & item) +void VCardResource::itemRemoved(const Akonadi::Item &item) { - if ( mAddressees.contains( item.remoteId() ) ) - mAddressees.remove( item.remoteId() ); + if (mAddressees.contains(item.remoteId())) { + mAddressees.remove(item.remoteId()); + } - scheduleWrite(); + scheduleWrite(); - changeProcessed(); + changeProcessed(); } -void VCardResource::retrieveItems( const Akonadi::Collection & col ) +void VCardResource::retrieveItems(const Akonadi::Collection &col) { - // VCard does not support folders so we can safely ignore the collection - Q_UNUSED( col ); + // VCard does not support folders so we can safely ignore the collection + Q_UNUSED(col); - Item::List items; + Item::List items; + items.reserve(mAddressees.count()); - // FIXME: Check if the KIO::Job is done and was successful, if so send the - // items, otherwise set a bool and in the result slot of the job send the - // items if the bool is set. + // FIXME: Check if the KIO::Job is done and was successful, if so send the + // items, otherwise set a bool and in the result slot of the job send the + // items if the bool is set. - foreach ( const KABC::Addressee &addressee, mAddressees ) { - Item item; - item.setRemoteId( addressee.uid() ); - item.setMimeType( KABC::Addressee::mimeType() ); - item.setPayload( addressee ); - items.append( item ); - } + foreach (const KContacts::Addressee &addressee, mAddressees) { + Item item; + item.setRemoteId(addressee.uid()); + item.setMimeType(KContacts::Addressee::mimeType()); + item.setPayload(addressee); + items.append(item); + } - itemsRetrieved( items ); + itemsRetrieved(items); } -bool VCardResource::readFromFile( const QString &fileName ) +bool VCardResource::readFromFile(const QString &fileName) { - mAddressees.clear(); + mAddressees.clear(); - QFile file( KUrl( fileName ).toLocalFile() ); - if ( !file.open( QIODevice::ReadOnly ) ) { - emit status( Broken, i18n( "Unable to open vCard file '%1'.", fileName ) ); - return false; - } + QFile file(QUrl::fromLocalFile(fileName).toLocalFile()); + if (!file.open(QIODevice::ReadOnly)) { + Q_EMIT status(Broken, i18n("Unable to open vCard file '%1'.", fileName)); + return false; + } - const QByteArray data = file.readAll(); - file.close(); + const QByteArray data = file.readAll(); + file.close(); - const KABC::Addressee::List list = mConverter.parseVCards( data ); - const int numberOfElementInList = list.count(); - for ( int i = 0; i < numberOfElementInList; ++i ) { - mAddressees.insert( list[ i ].uid(), list[ i ] ); - } + const KContacts::Addressee::List list = mConverter.parseVCards(data); + const int numberOfElementInList = list.count(); + for (int i = 0; i < numberOfElementInList; ++i) { + mAddressees.insert(list[ i ].uid(), list[ i ]); + } - return true; + return true; } -bool VCardResource::writeToFile( const QString &fileName ) +bool VCardResource::writeToFile(const QString &fileName) { - QFile file( fileName ); - if ( !file.open( QIODevice::WriteOnly ) ) { - emit status( Broken, i18n( "Unable to open vCard file '%1'.", fileName ) ); - return false; - } + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) { + Q_EMIT status(Broken, i18n("Unable to open vCard file '%1'.", fileName)); + return false; + } - const QByteArray data = mConverter.createVCards( mAddressees.values() ); + QVector v; + v.reserve(mAddressees.size()); + foreach (const KContacts::Addressee &addressee, mAddressees) { + v.push_back(addressee); + } - file.write( data ); - file.close(); + const QByteArray data = mConverter.createVCards(v); - return true; -} + file.write(data); + file.close(); -AKONADI_AGENT_FACTORY( VCardResource, akonadi_vcard_resource ) + return true; +} +AKONADI_RESOURCE_MAIN(VCardResource) diff -Nru kdepim-runtime-4.14.6/resources/vcard/vcardresource.desktop kdepim-runtime-15.08.0/resources/vcard/vcardresource.desktop --- kdepim-runtime-4.14.6/resources/vcard/vcardresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/vcardresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,6 @@ [Desktop Entry] Name=vCard File +Name[bg]=Файл vCard Name[bs]=VCard datoteka Name[ca]=Fitxer vCard Name[ca@valencia]=Fitxer vCard @@ -28,6 +29,7 @@ Name[pt_BR]=Arquivo vCard Name[ru]=Файл vCard Name[sk]=Súbor VCard +Name[sl]=Datoteka vCard Name[sr]=В‑кард фајл Name[sr@ijekavian]=В‑кард фајл Name[sr@ijekavianlatin]=VCard fajl @@ -40,6 +42,7 @@ Name[zh_CN]=vCard 文件 Name[zh_TW]=vCard 檔案 Comment=Loads data from a vCard file +Comment[bg]=Зареждане на данни от файл vCard Comment[bs]=Učitava podatke iz VCard datoteke Comment[ca]=Carrega les dades des d'un fitxer vCard Comment[ca@valencia]=Carrega dades des d'un fitxer vCard @@ -53,7 +56,7 @@ Comment[fi]=Lataa tietoa vCard-tiedostosta Comment[fr]=Charge des données depuis un fichier au format « vCard » Comment[ga]=Breiseán a luchtaíonn sonraí ó chomhad v-Chárta -Comment[gl]=Carga datos desde un ficheiro vCard +Comment[gl]=Carga datos desde un ficheiro VCard Comment[hu]=Adatokat tölt be egy vCard fájlból Comment[ia]=Carga datos ex un file vCard Comment[it]=Carica dati da un file vCard @@ -68,6 +71,7 @@ Comment[pt_BR]=Carrega os dados de um arquivo vCard Comment[ru]=Загрузка данных из файла vCard Comment[sk]=Načíta dáta zo súboru vCard +Comment[sl]=Naloži podatke iz datoteke vCard Comment[sr]=Учитава податке из в‑кард фајла Comment[sr@ijekavian]=Учитава податке из в‑кард фајла Comment[sr@ijekavianlatin]=Učitava podatke iz vCard fajla @@ -85,4 +89,3 @@ X-Akonadi-MimeTypes=text/directory X-Akonadi-Capabilities=Resource X-Akonadi-Identifier=akonadi_vcard_resource -X-Akonadi-LaunchMethod=AgentServer diff -Nru kdepim-runtime-4.14.6/resources/vcard/vcardresource.h kdepim-runtime-15.08.0/resources/vcard/vcardresource.h --- kdepim-runtime-4.14.6/resources/vcard/vcardresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/vcardresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -23,38 +23,38 @@ #include "singlefileresource.h" #include "settings.h" -#include -#include +#include +#include class VCardResource : public Akonadi::SingleFileResource { - Q_OBJECT + Q_OBJECT - public: - explicit VCardResource( const QString &id ); +public: + explicit VCardResource(const QString &id); ~VCardResource(); - protected Q_SLOTS: - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - void retrieveItems( const Akonadi::Collection &col ); +protected Q_SLOTS: + bool retrieveItem(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + void retrieveItems(const Akonadi::Collection &col) Q_DECL_OVERRIDE; - protected: +protected: /** * Customize the configuration dialog before it is displayed. */ - virtual void customizeConfigDialog( Akonadi::SingleFileResourceConfigDialog* dlg ); + void customizeConfigDialog(Akonadi::SingleFileResourceConfigDialog *dlg) Q_DECL_OVERRIDE; - bool readFromFile( const QString &fileName ); - bool writeToFile( const QString &fileName ); - virtual void aboutToQuit(); - - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); - virtual void itemRemoved( const Akonadi::Item &item ); - - private: - QMap mAddressees; - KABC::VCardConverter mConverter; + bool readFromFile(const QString &fileName) Q_DECL_OVERRIDE; + bool writeToFile(const QString &fileName) Q_DECL_OVERRIDE; + void aboutToQuit() Q_DECL_OVERRIDE; + + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + void itemRemoved(const Akonadi::Item &item) Q_DECL_OVERRIDE; + +private: + QMap mAddressees; + KContacts::VCardConverter mConverter; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/vcard/wizard/CMakeLists.txt kdepim-runtime-15.08.0/resources/vcard/wizard/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/vcard/wizard/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/wizard/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,4 +1,4 @@ -set(VCARD_FILE_DEFAULT_PATH "$HOME/.kde/share/apps/kaddressbook/contact.vcf") +set(VCARD_FILE_DEFAULT_PATH "$HOME/.local/share/kaddressbook/contact.vcf") configure_file(vcardwizard.es.cmake ${CMAKE_CURRENT_BINARY_DIR}/vcardwizard.es) -install ( FILES vcardwizard.desktop ${CMAKE_CURRENT_BINARY_DIR}/vcardwizard.es vcardwizard.ui DESTINATION ${DATA_INSTALL_DIR}/akonadi/accountwizard/vcard ) +install ( FILES vcardwizard.desktop ${CMAKE_CURRENT_BINARY_DIR}/vcardwizard.es vcardwizard.ui DESTINATION ${KDE_INSTALL_DATADIR}/akonadi/accountwizard/vcard ) diff -Nru kdepim-runtime-4.14.6/resources/vcard/wizard/vcardwizard.desktop kdepim-runtime-15.08.0/resources/vcard/wizard/vcardwizard.desktop --- kdepim-runtime-4.14.6/resources/vcard/wizard/vcardwizard.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcard/wizard/vcardwizard.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,16 +1,18 @@ [Desktop Entry] Name=VCard File -Name[bs]=VCard datoteka +Name[bg]=Файл vCard Name[ca]=Fitxer vCard Name[ca@valencia]=Fitxer vCard Name[cs]=Soubor s vizitkou Name[da]=VCard-fil Name[de]=vCard-Datei +Name[el]=VCard αρχείο Name[en_GB]=VCard File Name[es]=Archivo VCard Name[et]=vCard-fail Name[fi]=VCard-tiedosto Name[fr]=Fichier « vCard » +Name[gl]=Ficheiro VCard Name[hu]=VCard fájl Name[it]=File vCard Name[ja]=VCard ファイル @@ -21,9 +23,10 @@ Name[nn]=vCard-fil Name[pl]=Plik VCard Name[pt]=Ficheiro vCard -Name[pt_BR]=Arquivo VCard +Name[pt_BR]=Arquivo vCard Name[ru]=Файл vCard Name[sk]=Súbor VCard +Name[sl]=Datoteka vCard Name[sr]=В‑кард фајл Name[sr@ijekavian]=В‑кард фајл Name[sr@ijekavianlatin]=VCard fajl @@ -32,39 +35,40 @@ Name[tr]=VCard Dosyası Name[uk]=Файл vCard Name[x-test]=xxVCard Filexx +Name[zh_CN]=VCard 文件 Name[zh_TW]=vCard 檔案 Icon=text-directory -Comment=Loads contact from VCard File -Comment[bs]=Učitava kontakte iz VCard datoteke -Comment[ca]=Carrega contactes des d'un fitxer vCard -Comment[ca@valencia]=Carrega contactes des d'un fitxer vCard +Comment=Loads contact from vCard File +Comment[bg]=Зареждане на контакти от файл vCard +Comment[ca]=Carrega els contactes des d'un fitxer vCard Comment[cs]=Načítá data ze souboru vizitek -Comment[da]=Indlæs kontakt fra VCard-fil Comment[de]=Lädt Kontakte aus einer vCard-Datei -Comment[en_GB]=Loads contact from VCard File -Comment[es]=Cargar contactos desde un archivo VCard -Comment[et]=Kontakti laadimine vCard-failist -Comment[fi]=Lataa yhteystiedon VuCard-tiedostosta +Comment[el]=Φορτώνει επαφή από αρχείο VCard +Comment[en_GB]=Loads contact from vCard File +Comment[es]=Carga contactos desde un archivo vCard +Comment[fi]=Lataa yhteystiedon vCard-tiedostosta Comment[fr]=Charge un contact depuis un fichier au format « vCard » -Comment[hu]=Partnert tölt be egy VCard fájlból +Comment[gl]=Cargar os contactos dun ficheiro vCard +Comment[hu]=Névjegy betöltése vCard fájlból Comment[it]=Carica contatti da un file vCard Comment[ko]=vCard 파일에서 연락처를 가져옵니다 Comment[nb]=Laster kontakt fra vCard-fila -Comment[nds]=Laadt Daten ut en vCard-Datei -Comment[nl]=Laadt contactpersoon uit een VCard-bestand -Comment[pl]=Wczytuje kontakty z pliku VCard +Comment[nds]=Laadt Kontakten ut en vCard-Datei +Comment[nl]=Laadt contactpersoon uit een vCard-bestand +Comment[pl]=Wczytuje kontakty z pliku vCard Comment[pt]=Carrega um contacto de um ficheiro vCard -Comment[pt_BR]=Carrega os contatos de um arquivo VCard -Comment[ru]=Загрузка контакта из файла vCard +Comment[pt_BR]=Carrega os contatos de um arquivo vCard Comment[sk]=Načíta kontakt zo súboru vCard +Comment[sl]=Naloži stik iz datoteke vCard Comment[sr]=Учитава контакт из в‑кард фајла Comment[sr@ijekavian]=Учитава контакт из в‑кард фајла Comment[sr@ijekavianlatin]=Učitava kontakt iz vCard fajla Comment[sr@latin]=Učitava kontakt iz vCard fajla -Comment[sv]=Laddar data från en VCard-fil -Comment[tr]=Bir VCard dosyasından veri yükler +Comment[sv]=Laddar kontakt från en vCard-fil +Comment[tr]=VCard dosyasından bağlantı yükler Comment[uk]=Завантажує дані запису контакту із файла vCard -Comment[x-test]=xxLoads contact from VCard Filexx +Comment[x-test]=xxLoads contact from vCard Filexx +Comment[zh_CN]=从 vCard 文件载入联系人 Comment[zh_TW]=從 vCard 檔載入聯絡人 [Wizard] diff -Nru kdepim-runtime-4.14.6/resources/vcarddir/CMakeLists.txt kdepim-runtime-15.08.0/resources/vcarddir/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/vcarddir/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcarddir/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,30 +1,23 @@ -include_directories( - ${kdepim-runtime_SOURCE_DIR} - ${QT_QTDBUS_INCLUDE_DIR} -) - -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - +add_definitions(-DTRANSLATION_DOMAIN=\"akonadi_vcarddir_resource\") ########### next target ############### set( vcarddirresource_SRCS vcarddirresource.cpp - ../shared/dirsettingsdialog.cpp + dirsettingsdialog.cpp ) -kde4_add_ui_files(vcarddirresource_SRCS settingsdialog.ui) -kde4_add_kcfg_files(vcarddirresource_SRCS settings.kcfgc) +kconfig_add_kcfg_files(vcarddirresource_SRCS settings.kcfgc) kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/vcarddirresource.kcfg org.kde.Akonadi.VCardDirectory.Settings) -qt4_add_dbus_adaptor(vcarddirresource_SRCS +qt5_add_dbus_adaptor(vcarddirresource_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.VCardDirectory.Settings.xml settings.h Settings ) -install( FILES vcarddirresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) +install( FILES vcarddirresource.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" ) -kde4_add_executable(akonadi_vcarddir_resource ${vcarddirresource_SRCS}) +add_executable(akonadi_vcarddir_resource ${vcarddirresource_SRCS}) -if (Q_WS_MAC) +if( APPLE ) set_target_properties(akonadi_vcarddir_resource PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/../Info.plist.template) set_target_properties(akonadi_vcarddir_resource PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Akonadi.VCardDirectory") set_target_properties(akonadi_vcarddir_resource PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "KDE Akonadi VCardDirectory Resource") @@ -32,13 +25,11 @@ target_link_libraries(akonadi_vcarddir_resource - ${KDEPIMLIBS_AKONADI_LIBS} - ${QT_QTCORE_LIBRARY} - ${KDE4_KDECORE_LIBS} - ${KDEPIMLIBS_KABC_LIBS} - ${KDE4_KIO_LIBS} + KF5::AkonadiCore + KF5::AkonadiAgentBase + KF5::Contacts ) add_subdirectory(wizard) -install(TARGETS akonadi_vcarddir_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(TARGETS akonadi_vcarddir_resource ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff -Nru kdepim-runtime-4.14.6/resources/vcarddir/dirsettingsdialog.cpp kdepim-runtime-15.08.0/resources/vcarddir/dirsettingsdialog.cpp --- kdepim-runtime-4.14.6/resources/vcarddir/dirsettingsdialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcarddir/dirsettingsdialog.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,93 @@ +/* + Copyright (c) 2009 Tobias Koenig + + 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 "dirsettingsdialog.h" + +#include "settings.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +using namespace Akonadi; + +SettingsDialog::SettingsDialog(WId windowId) + : QDialog() +{ + QWidget *mainWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); + ui.setupUi(mainWidget); + ui.kcfg_Path->setMode(KFile::LocalOnly | KFile::Directory); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + mOkButton = buttonBox->button(QDialogButtonBox::Ok); + mOkButton->setDefault(true); + mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &SettingsDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &SettingsDialog::reject); + mainLayout->addWidget(buttonBox); + + if (windowId) { + KWindowSystem::setMainWindow(this, windowId); + } + + connect(mOkButton, &QPushButton::clicked, this, &SettingsDialog::save); + + connect(ui.kcfg_Path, &KUrlRequester::textChanged, this, &SettingsDialog::validate); + connect(ui.kcfg_ReadOnly, &QCheckBox::toggled, this, &SettingsDialog::validate); + + QTimer::singleShot(0, this, SLOT(validate())); + + ui.kcfg_Path->setUrl(QUrl::fromLocalFile(Settings::self()->path())); + ui.kcfg_AutosaveInterval->setSuffix(ki18np(" minute", " minutes")); + mManager = new KConfigDialogManager(this, Settings::self()); + mManager->updateWidgets(); +} + +void SettingsDialog::save() +{ + mManager->updateSettings(); + Settings::self()->setPath(ui.kcfg_Path->url().toLocalFile()); + Settings::self()->save(); +} + +void SettingsDialog::validate() +{ + const QUrl currentUrl = ui.kcfg_Path->url(); + if (currentUrl.isEmpty()) { + mOkButton->setEnabled(false); + return; + } + + const QFileInfo file(currentUrl.toLocalFile()); + if (file.exists() && !file.isWritable()) { + ui.kcfg_ReadOnly->setEnabled(false); + ui.kcfg_ReadOnly->setChecked(true); + } else { + ui.kcfg_ReadOnly->setEnabled(true); + } + mOkButton->setEnabled(true); +} diff -Nru kdepim-runtime-4.14.6/resources/vcarddir/dirsettingsdialog.h kdepim-runtime-15.08.0/resources/vcarddir/dirsettingsdialog.h --- kdepim-runtime-4.14.6/resources/vcarddir/dirsettingsdialog.h 1970-01-01 00:00:00.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcarddir/dirsettingsdialog.h 2015-08-10 21:01:02.000000000 +0000 @@ -0,0 +1,51 @@ +/* + Copyright (c) 2009 Tobias Koenig + + 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 DIRSETTINGSDIALOG_H +#define DIRSETTINGSDIALOG_H + +#include "ui_settingsdialog.h" + +#include +#include + +class KConfigDialogManager; + +namespace Akonadi +{ + +class SettingsDialog : public QDialog +{ + Q_OBJECT +public: + explicit SettingsDialog(WId windowId); + +private Q_SLOTS: + void save(); + void validate(); + +private: + Ui::SettingsDialog ui; + KConfigDialogManager *mManager; + QPushButton *mOkButton; +}; + +} + +#endif diff -Nru kdepim-runtime-4.14.6/resources/vcarddir/settingsdialog.ui kdepim-runtime-15.08.0/resources/vcarddir/settingsdialog.ui --- kdepim-runtime-4.14.6/resources/vcarddir/settingsdialog.ui 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcarddir/settingsdialog.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,221 +0,0 @@ - - SettingsDialog - - - - 0 - 0 - 547 - 386 - - - - - - - 0 - - - - Directory - - - - - - Directory Name - - - - - - - - &Directory: - - - kcfg_Path - - - - - - - - - - - - Select the directory whose contents should be represented by this resource. If the directory does not exist, it will be created. - - - true - - - - - - - - - - Access Rights - - - - - - Read only - - - - - - - If read-only mode is enabled, no changes will be written to the directory selected above. Read-only mode will be automatically enabled if you do not have write access to the directory. - - - true - - - - - - - - - - Qt::Vertical - - - - 20 - 4 - - - - - - - - - Tuning - - - - - - The options on this page allow you to change parameters that balance data safety and consistency against performance. In general you should be careful with changing anything here, the defaults are good enough in most cases. - - - true - - - - - - - - - Autosave delay: - - - - - - - 1 - - - 0 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Vertical - - - - 20 - 138 - - - - - - - - - - - - - KIntSpinBox - QSpinBox -
knuminput.h
-
- - KTabWidget - QTabWidget -
ktabwidget.h
- 1 -
- - KUrlRequester - QFrame -
kurlrequester.h
-
-
- - - - kcfg_ReadOnly - toggled(bool) - kcfg_AutosaveInterval - setDisabled(bool) - - - 273 - 205 - - - 157 - 101 - - - - - kcfg_ReadOnly - toggled(bool) - autosaveLabel - setDisabled(bool) - - - 273 - 205 - - - 56 - 101 - - - - -
diff -Nru kdepim-runtime-4.14.6/resources/vcarddir/vcarddirresource.cpp kdepim-runtime-15.08.0/resources/vcarddir/vcarddirresource.cpp --- kdepim-runtime-4.14.6/resources/vcarddir/vcarddirresource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcarddir/vcarddirresource.cpp 2015-08-10 21:01:02.000000000 +0000 @@ -21,258 +21,267 @@ #include "vcarddirresource.h" #include "settingsadaptor.h" -#include "../shared/dirsettingsdialog.h" +#include "dirsettingsdialog.h" #include #include #include -#include -#include -#include +#include +#include +#include + +#include +#include +#include using namespace Akonadi; -VCardDirResource::VCardDirResource( const QString &id ) - : ResourceBase( id ) +VCardDirResource::VCardDirResource(const QString &id) + : ResourceBase(id) { - // setup the resource - new SettingsAdaptor( Settings::self() ); - QDBusConnection::sessionBus().registerObject( QLatin1String( "/Settings" ), - Settings::self(), QDBusConnection::ExportAdaptors ); + // setup the resource + new SettingsAdaptor(Settings::self()); + QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"), + Settings::self(), QDBusConnection::ExportAdaptors); - changeRecorder()->itemFetchScope().fetchFullPayload(); + changeRecorder()->itemFetchScope().fetchFullPayload(); } VCardDirResource::~VCardDirResource() { - // clear cache - mAddressees.clear(); + // clear cache + mAddressees.clear(); } void VCardDirResource::aboutToQuit() { - Settings::self()->writeConfig(); + Settings::self()->save(); } -void VCardDirResource::configure( WId windowId ) +void VCardDirResource::configure(WId windowId) { - SettingsDialog dlg( windowId ); - dlg.setWindowIcon( KIcon( QLatin1String("text-directory") ) ); - if ( dlg.exec() ) { - initializeVCardDirectory(); - loadAddressees(); + SettingsDialog dlg(windowId); + dlg.setWindowIcon(QIcon::fromTheme(QStringLiteral("text-directory"))); + if (dlg.exec()) { + initializeVCardDirectory(); + loadAddressees(); - synchronize(); + synchronize(); - emit configurationDialogAccepted(); - } else { - emit configurationDialogRejected(); - } + Q_EMIT configurationDialogAccepted(); + } else { + Q_EMIT configurationDialogRejected(); + } } bool VCardDirResource::loadAddressees() { - mAddressees.clear(); + mAddressees.clear(); - QDirIterator it( vCardDirectoryName() ); - while ( it.hasNext() ) { - it.next(); - if ( it.fileName() != QLatin1String(".") && it.fileName() != QLatin1String("..") && it.fileName() != QLatin1String("WARNING_README.txt") ) { - QFile file( it.filePath() ); - if (file.open( QIODevice::ReadOnly )) { - const QByteArray data = file.readAll(); - file.close(); - - const KABC::Addressee addr = mConverter.parseVCard( data ); - if ( !addr.isEmpty() ) { - mAddressees.insert( addr.uid(), addr ); + QDirIterator it(vCardDirectoryName()); + while (it.hasNext()) { + it.next(); + if (it.fileName() != QLatin1String(".") && it.fileName() != QLatin1String("..") && it.fileName() != QLatin1String("WARNING_README.txt")) { + QFile file(it.filePath()); + if (file.open(QIODevice::ReadOnly)) { + const QByteArray data = file.readAll(); + file.close(); + + const KContacts::Addressee addr = mConverter.parseVCard(data); + if (!addr.isEmpty()) { + mAddressees.insert(addr.uid(), addr); + } + } else { + qDebug() << " file can't be load " << it.filePath(); + } } - } else { - kDebug()<<" file can't be load "<& ) +bool VCardDirResource::retrieveItem(const Akonadi::Item &item, const QSet &) { - const QString remoteId = item.remoteId(); - if ( !mAddressees.contains( remoteId ) ) { - emit error( i18n( "Contact with uid '%1' not found.", remoteId ) ); - return false; - } + const QString remoteId = item.remoteId(); + if (!mAddressees.contains(remoteId)) { + Q_EMIT error(i18n("Contact with uid '%1' not found.", remoteId)); + return false; + } - Item newItem( item ); - newItem.setPayload( mAddressees.value( remoteId ) ); - itemRetrieved( newItem ); + Item newItem(item); + newItem.setPayload(mAddressees.value(remoteId)); + itemRetrieved(newItem); - return true; + return true; } -void VCardDirResource::itemAdded( const Akonadi::Item &item, const Akonadi::Collection& ) +void VCardDirResource::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &) { - if ( Settings::self()->readOnly() ) { - emit error( i18n( "Trying to write to a read-only directory: '%1'", vCardDirectoryName() ) ); - cancelTask(); - return; - } - - KABC::Addressee addressee; - if ( item.hasPayload() ) - addressee = item.payload(); - - if ( !addressee.isEmpty() ) { - // add it to the cache... - mAddressees.insert( addressee.uid(), addressee ); + if (Settings::self()->readOnly()) { + Q_EMIT error(i18n("Trying to write to a read-only directory: '%1'", vCardDirectoryName())); + cancelTask(); + return; + } - // ... and write it through to the file system - const QByteArray data = mConverter.createVCard( addressee ); + KContacts::Addressee addressee; + if (item.hasPayload()) { + addressee = item.payload(); + } - QFile file( vCardDirectoryFileName( addressee.uid() ) ); - file.open( QIODevice::WriteOnly ); - file.write( data ); - file.close(); + if (!addressee.isEmpty()) { + // add it to the cache... + mAddressees.insert(addressee.uid(), addressee); + + // ... and write it through to the file system + const QByteArray data = mConverter.createVCard(addressee); + + QFile file(vCardDirectoryFileName(addressee.uid())); + file.open(QIODevice::WriteOnly); + file.write(data); + file.close(); - // report everything ok - Item newItem( item ); - newItem.setRemoteId( addressee.uid() ); - changeCommitted( newItem ); + // report everything ok + Item newItem(item); + newItem.setRemoteId(addressee.uid()); + changeCommitted(newItem); - } else { - changeProcessed(); - } + } else { + changeProcessed(); + } } -void VCardDirResource::itemChanged( const Akonadi::Item &item, const QSet& ) +void VCardDirResource::itemChanged(const Akonadi::Item &item, const QSet &) { - if ( Settings::self()->readOnly() ) { - emit error( i18n( "Trying to write to a read-only directory: '%1'", vCardDirectoryName() ) ); - cancelTask(); - return; - } + if (Settings::self()->readOnly()) { + Q_EMIT error(i18n("Trying to write to a read-only directory: '%1'", vCardDirectoryName())); + cancelTask(); + return; + } - KABC::Addressee addressee; - if ( item.hasPayload() ) - addressee = item.payload(); + KContacts::Addressee addressee; + if (item.hasPayload()) { + addressee = item.payload(); + } - if ( !addressee.isEmpty() ) { - // change it in the cache... - mAddressees.insert( addressee.uid(), addressee ); + if (!addressee.isEmpty()) { + // change it in the cache... + mAddressees.insert(addressee.uid(), addressee); + + // ... and write it through to the file system + const QByteArray data = mConverter.createVCard(addressee); + + QFile file(vCardDirectoryFileName(addressee.uid())); + if (file.open(QIODevice::WriteOnly)) { + file.write(data); + file.close(); + + Item newItem(item); + newItem.setRemoteId(addressee.uid()); + changeCommitted(newItem); + } else { + qDebug() << " We can't write in file " << file.fileName(); + } - // ... and write it through to the file system - const QByteArray data = mConverter.createVCard( addressee ); + } else { + changeProcessed(); + } +} - QFile file( vCardDirectoryFileName( addressee.uid() ) ); - if (file.open( QIODevice::WriteOnly )) { - file.write( data ); - file.close(); +void VCardDirResource::itemRemoved(const Akonadi::Item &item) +{ + if (Settings::self()->readOnly()) { + Q_EMIT error(i18n("Trying to write to a read-only directory: '%1'", vCardDirectoryName())); + cancelTask(); + return; + } - Item newItem( item ); - newItem.setRemoteId( addressee.uid() ); - changeCommitted( newItem ); - } else { - kDebug()<<" We can't write in file "<readOnly() ) { - emit error( i18n( "Trying to write to a read-only directory: '%1'", vCardDirectoryName() ) ); - cancelTask(); - return; - } - - // remove it from the cache... - if ( mAddressees.contains( item.remoteId() ) ) - mAddressees.remove( item.remoteId() ); + Collection c; + c.setParentCollection(Collection::root()); + c.setRemoteId(vCardDirectoryName()); + c.setName(name()); + QStringList mimeTypes; + mimeTypes << KContacts::Addressee::mimeType(); + c.setContentMimeTypes(mimeTypes); + if (Settings::self()->readOnly()) { + c.setRights(Collection::ReadOnly); + } else { + Collection::Rights rights; + rights |= Collection::CanChangeItem; + rights |= Collection::CanCreateItem; + rights |= Collection::CanDeleteItem; + rights |= Collection::CanChangeCollection; + c.setRights(rights); + } - // ... and remove it from the file system - QFile::remove( vCardDirectoryFileName( item.remoteId() ) ); + EntityDisplayAttribute *attr = c.attribute(Collection::AddIfMissing); + attr->setDisplayName(i18n("Contacts Folder")); + attr->setIconName(QLatin1String("x-office-address-book")); - changeProcessed(); + Collection::List list; + list << c; + collectionsRetrieved(list); } -void VCardDirResource::retrieveCollections() +void VCardDirResource::retrieveItems(const Akonadi::Collection &) { - Collection c; - c.setParentCollection( Collection::root() ); - c.setRemoteId( vCardDirectoryName() ); - c.setName( name() ); - QStringList mimeTypes; - mimeTypes << KABC::Addressee::mimeType(); - c.setContentMimeTypes( mimeTypes ); - if ( Settings::self()->readOnly() ) { - c.setRights( Collection::CanChangeCollection ); - } else { - Collection::Rights rights = Collection::ReadOnly; - rights |= Collection::CanChangeItem; - rights |= Collection::CanCreateItem; - rights |= Collection::CanDeleteItem; - rights |= Collection::CanChangeCollection; - c.setRights( rights ); - } - - EntityDisplayAttribute* attr = c.attribute( Collection::AddIfMissing ); - attr->setDisplayName( i18n( "Contacts Folder" ) ); - attr->setIconName( QLatin1String("x-office-address-book") ); - - Collection::List list; - list << c; - collectionsRetrieved( list ); -} - -void VCardDirResource::retrieveItems( const Akonadi::Collection& ) -{ - Item::List items; - - foreach ( const KABC::Addressee &addressee, mAddressees ) { - Item item; - item.setRemoteId( addressee.uid() ); - item.setMimeType( KABC::Addressee::mimeType() ); - items.append( item ); - } + Item::List items; + items.reserve(mAddressees.count()); + + foreach (const KContacts::Addressee &addressee, mAddressees) { + Item item; + item.setRemoteId(addressee.uid()); + item.setMimeType(KContacts::Addressee::mimeType()); + items.append(item); + } - itemsRetrieved( items ); + itemsRetrieved(items); } QString VCardDirResource::vCardDirectoryName() const { - return Settings::self()->path(); + return Settings::self()->path(); } -QString VCardDirResource::vCardDirectoryFileName( const QString &file ) const +QString VCardDirResource::vCardDirectoryFileName(const QString &file) const { - return Settings::self()->path() + QDir::separator() + file; + return Settings::self()->path() + QDir::separator() + file; } void VCardDirResource::initializeVCardDirectory() const { - QDir dir( vCardDirectoryName() ); + QDir dir(vCardDirectoryName()); - // if folder does not exists, create it - if ( !dir.exists() ) - QDir::root().mkpath( dir.absolutePath() ); - - // check whether warning file is in place... - QFile file( dir.absolutePath() + QDir::separator() + QLatin1String("WARNING_README.txt") ); - if ( !file.exists() ) { - // ... if not, create it - file.open( QIODevice::WriteOnly ); - file.write( "Important Warning!!!\n\n" - "Don't create or copy vCards inside this folder manually, they are managed by the Akonadi framework!\n" ); - file.close(); - } + // if folder does not exists, create it + if (!dir.exists()) { + QDir::root().mkpath(dir.absolutePath()); + } + + // check whether warning file is in place... + QFile file(dir.absolutePath() + QDir::separator() + QLatin1String("WARNING_README.txt")); + if (!file.exists()) { + // ... if not, create it + file.open(QIODevice::WriteOnly); + file.write("Important Warning!!!\n\n" + "Don't create or copy vCards inside this folder manually, they are managed by the Akonadi framework!\n"); + file.close(); + } } -AKONADI_RESOURCE_MAIN( VCardDirResource ) +AKONADI_RESOURCE_MAIN(VCardDirResource) diff -Nru kdepim-runtime-4.14.6/resources/vcarddir/vcarddirresource.desktop kdepim-runtime-15.08.0/resources/vcarddir/vcarddirresource.desktop --- kdepim-runtime-4.14.6/resources/vcarddir/vcarddirresource.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcarddir/vcarddirresource.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,5 +1,6 @@ [Desktop Entry] Name=vCard Directory +Name[bg]=Папка с vCard Name[bs]=VCard direktorij Name[ca]=Directori vCard Name[ca@valencia]=Directori vCard @@ -25,9 +26,10 @@ Name[nl]=vCard-map Name[pl]=Katalog vCard Name[pt]=Pasta de vCard's -Name[pt_BR]=Pasta de vCards +Name[pt_BR]=Pasta de VCards Name[ru]=Каталог с файлами vCard Name[sk]=Adresár VCard +Name[sl]=Mapa vCard Name[sr]=В‑кард фасцикла Name[sr@ijekavian]=В‑кард фасцикла Name[sr@ijekavianlatin]=VCard fascikla @@ -39,6 +41,7 @@ Name[zh_CN]=vCard 目录 Name[zh_TW]=vCard 目錄 Comment=Loads data from a directory with vCards +Comment[bg]=Зареждане на данни от папка с vCard Comment[bs]=Učitava podakte iz direktorija sa VCards Comment[ca]=Carrega les dades des d'un directori amb vCard Comment[ca@valencia]=Carrega dades des d'un directori amb vCard @@ -67,11 +70,12 @@ Comment[pt_BR]=Carrega os dados de uma pasta com vCards Comment[ru]=Загрузка данных из папки с файлами vCard Comment[sk]=Načíta dáta z adresára s vCards +Comment[sl]=Naloži podatke iz mape z datotekami vCard Comment[sr]=Учитава податке из фасцикле са в‑кардовима Comment[sr@ijekavian]=Учитава податке из фасцикле са в‑кардовима Comment[sr@ijekavianlatin]=Učitava podatke iz fascikle sa vCardovima Comment[sr@latin]=Učitava podatke iz fascikle sa vCardovima -Comment[sv]=Laddar data från en katalog med vCard-filer +Comment[sv]=Läser in data från en katalog med vCard-filer Comment[tr]=VCard dosyaları bulunan bir dizinden verileri yükler Comment[uk]=Завантажує дані з каталогу з vCard Comment[x-test]=xxLoads data from a directory with vCardsxx diff -Nru kdepim-runtime-4.14.6/resources/vcarddir/vcarddirresource.h kdepim-runtime-15.08.0/resources/vcarddir/vcarddirresource.h --- kdepim-runtime-4.14.6/resources/vcarddir/vcarddirresource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcarddir/vcarddirresource.h 2015-08-10 21:01:02.000000000 +0000 @@ -20,42 +20,42 @@ #ifndef VCARDDIRRESOURCE_H #define VCARDDIRRESOURCE_H -#include +#include -#include -#include +#include +#include class VCardDirResource : public Akonadi::ResourceBase, public Akonadi::AgentBase::Observer { - Q_OBJECT + Q_OBJECT - public: - VCardDirResource( const QString &id ); +public: + VCardDirResource(const QString &id); ~VCardDirResource(); - public Q_SLOTS: - virtual void configure( WId windowId ); - virtual void aboutToQuit(); - - protected Q_SLOTS: - void retrieveCollections(); - void retrieveItems( const Akonadi::Collection &col ); - bool retrieveItem( const Akonadi::Item &item, const QSet &parts ); - - protected: - virtual void itemAdded( const Akonadi::Item &item, const Akonadi::Collection &collection ); - virtual void itemChanged( const Akonadi::Item &item, const QSet &parts ); - virtual void itemRemoved( const Akonadi::Item &item ); +public Q_SLOTS: + void configure(WId windowId) Q_DECL_OVERRIDE; + void aboutToQuit() Q_DECL_OVERRIDE; + +protected Q_SLOTS: + void retrieveCollections() Q_DECL_OVERRIDE; + void retrieveItems(const Akonadi::Collection &col) Q_DECL_OVERRIDE; + bool retrieveItem(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + +protected: + void itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection) Q_DECL_OVERRIDE; + void itemChanged(const Akonadi::Item &item, const QSet &parts) Q_DECL_OVERRIDE; + void itemRemoved(const Akonadi::Item &item) Q_DECL_OVERRIDE; - private: +private: bool loadAddressees(); QString vCardDirectoryName() const; - QString vCardDirectoryFileName( const QString &file ) const; + QString vCardDirectoryFileName(const QString &file) const; void initializeVCardDirectory() const; - private: - QMap mAddressees; - KABC::VCardConverter mConverter; +private: + QMap mAddressees; + KContacts::VCardConverter mConverter; }; #endif diff -Nru kdepim-runtime-4.14.6/resources/vcarddir/wizard/CMakeLists.txt kdepim-runtime-15.08.0/resources/vcarddir/wizard/CMakeLists.txt --- kdepim-runtime-4.14.6/resources/vcarddir/wizard/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcarddir/wizard/CMakeLists.txt 2015-08-10 21:01:02.000000000 +0000 @@ -1,4 +1,4 @@ set(VCARDDIR_FILE_DEFAULT_PATH "$HOME/") configure_file(vcarddirwizard.es.cmake ${CMAKE_CURRENT_BINARY_DIR}/vcarddirwizard.es) -install ( FILES vcarddirwizard.desktop ${CMAKE_CURRENT_BINARY_DIR}/vcarddirwizard.es vcarddirwizard.ui DESTINATION ${DATA_INSTALL_DIR}/akonadi/accountwizard/vcarddir ) +install ( FILES vcarddirwizard.desktop ${CMAKE_CURRENT_BINARY_DIR}/vcarddirwizard.es vcarddirwizard.ui DESTINATION ${KDE_INSTALL_DATADIR}/akonadi/accountwizard/vcarddir ) diff -Nru kdepim-runtime-4.14.6/resources/vcarddir/wizard/vcarddirwizard.desktop kdepim-runtime-15.08.0/resources/vcarddir/wizard/vcarddirwizard.desktop --- kdepim-runtime-4.14.6/resources/vcarddir/wizard/vcarddirwizard.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resources/vcarddir/wizard/vcarddirwizard.desktop 2015-08-10 21:01:02.000000000 +0000 @@ -1,70 +1,76 @@ [Desktop Entry] -Name=VCard Directory -Name[bs]=VCard Directory +Name=vCard Directory +Name[bg]=Папка с vCard +Name[bs]=VCard direktorij Name[ca]=Directori vCard Name[ca@valencia]=Directori vCard Name[cs]=Adresář vizitek -Name[da]=VCard-mappe +Name[da]=vCard-mappe Name[de]=vCard-Ordner -Name[en_GB]=VCard Directory -Name[es]=Directorio VCard +Name[el]=VCard Κατάλογος +Name[en_GB]=vCard Directory +Name[es]=Directorio vCard Name[et]=vCardide kataloog -Name[fi]=VCard-kansio +Name[fi]=vCard-kansio Name[fr]=Dossier « vCard » -Name[hu]=VCard mappa -Name[it]=Cartella vCard -Name[ja]=VCard ディレクトリ +Name[ga]=Comhadlann v-Chártaí +Name[gl]=Directorio de vCard +Name[hu]=vCard mappa +Name[ia]=Directorio de VCard +Name[it]=Directory vCard +Name[kk]=VCard қапшығы Name[ko]=vCard 디렉터리 +Name[lt]=vCard katalogas Name[nb]=vCard-mappe -Name[nds]=vCard-Orner -Name[nl]=VCard-map -Name[nn]=vCard-katalog -Name[pl]=Katalog VCard +Name[nds]=VCard-Orner +Name[nl]=vCard-map +Name[pl]=Katalog vCard Name[pt]=Pasta de vCard's -Name[pt_BR]=Diretório vCard +Name[pt_BR]=Pasta de VCards Name[ru]=Каталог с файлами vCard Name[sk]=Adresár VCard +Name[sl]=Mapa vCard Name[sr]=В‑кард фасцикла Name[sr@ijekavian]=В‑кард фасцикла Name[sr@ijekavianlatin]=VCard fascikla Name[sr@latin]=VCard fascikla -Name[sv]=VCard-katalog +Name[sv]=vCard-katalog Name[tr]=VCard Dizini Name[uk]=Каталог vCard -Name[x-test]=xxVCard Directoryxx +Name[x-test]=xxvCard Directoryxx +Name[zh_CN]=vCard 目录 Name[zh_TW]=vCard 目錄 Icon=text-directory Comment=Loads contact from VCard Directory -Comment[bs]=Učitava kontakte iz VCard direktorija -Comment[ca]=Carrega contactes des d'un directori amb vCard -Comment[ca@valencia]=Carrega contactes des d'un directori amb vCard +Comment[bg]=Зареждане на контакти от папка с vCard +Comment[ca]=Carrega els contactes des d'un directori VCard Comment[cs]=Načítá data z adresáře vizitek -Comment[da]=Indlæser kontakt fra VCard-mappe Comment[de]=Lädt Kontakte aus einem vCard-Ordner +Comment[el]=Φορτώνει επαφή από κατάλογο VCard Comment[en_GB]=Loads contact from VCard Directory -Comment[es]=Cargar contactos desde un directorio VCard -Comment[et]=Kontakti laadimine vCardide kataloogist +Comment[es]=Carga contactos desde un directorio VCard Comment[fi]=Lataa yhteystiedon VCard-kansiosta Comment[fr]=Charge des données depuis un dossier « vCard » -Comment[hu]=Partnert tölt be egy VCard mappából +Comment[gl]=Carga contactos dun cartafol vCard Comment[it]=Carica contatti da una cartella vCard Comment[ko]=vCard 디렉터리에서 연락처를 가져옵니다 Comment[nb]=Laster kontakt fra vCard-mappa -Comment[nds]=Laadt Kontakten ut en vCard-Orner -Comment[nl]=Laadt contactpersoon uit een VCard-map -Comment[pl]=Wczytuje kontakty z katalogu vCard +Comment[nl]=Laadt contactpersoon uit een vCard-map +Comment[pl]=Wczytuje kontakty z katalogu wizytówek vCard Comment[pt]=Carrega um contacto de uma pasta de ficheiros vCard Comment[pt_BR]=Carrega os contatos de um diretório vCard Comment[ru]=Загрузка контактов из каталога с файлами vCard Comment[sk]=Načíta kontakt z adresára vCard +Comment[sl]=Naloži stik iz mape z datotekami vCard Comment[sr]=Учитава контакт из в‑кард фасцикле Comment[sr@ijekavian]=Учитава контакт из в‑кард фасцикле Comment[sr@ijekavianlatin]=Učitava kontakt iz vCard fascikle Comment[sr@latin]=Učitava kontakt iz vCard fascikle -Comment[sv]=Laddar data från en VCard-katalog -Comment[tr]=Bir VCard dosyasından veri yükler +Comment[sv]=Läser in kontakter från en vCard-katalog +Comment[tr]=vCard Dizininden bağlantıyı yükler Comment[uk]=Завантажує дані запису контакту із каталогу vCard Comment[x-test]=xxLoads contact from VCard Directoryxx +Comment[zh_CN]=从 VCard 目录载入联系人 Comment[zh_TW]=從 vCard 目錄載入聯絡人 [Wizard] diff -Nru kdepim-runtime-4.14.6/resourcetester/CMakeLists.txt kdepim-runtime-15.08.0/resourcetester/CMakeLists.txt --- kdepim-runtime-4.14.6/resourcetester/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ - -set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - -add_subdirectory( tests ) - -set( resourcetester_SRCS - global.cpp - main.cpp - resource.cpp - script.cpp - test.cpp - xmloperations.cpp - collectiontest.cpp - itemtest.cpp - qemu.cpp - system.cpp - wrappedobject.cpp -) - -kde4_add_executable(resourcetester ${resourcetester_SRCS}) - -target_link_libraries( resourcetester - ${KDEPIMLIBS_AKONADI_XML_LIBS} - ${KDEPIMLIBS_AKONADI_LIBS} - ${QT_QTCORE_LIBRARY} - ${QT_QTGUI_LIBRARY} - ${QT_QTXML_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ${QT_QTNETWORK_LIBRARY} - ${QT_QTTEST_LIBRARY} - ${KDE4_KROSSCORE_LIBS} - ${KDE4_KROSSUI_LIBS} - ${KDE4_KDECORE_LIBS} - ${KDE4_KDEUI_LIBS} - ${KDE4_KIO_LIBS} -) - diff -Nru kdepim-runtime-4.14.6/resourcetester/collectiontest.cpp kdepim-runtime-15.08.0/resourcetester/collectiontest.cpp --- kdepim-runtime-4.14.6/resourcetester/collectiontest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/collectiontest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "collectiontest.h" -#include "test.h" - -#include -#include -#include -#include - -#include - -using namespace Akonadi; - -CollectionTest::CollectionTest(QObject* parent) : - QObject( parent ) -{ -} - -void CollectionTest::setParent(const Akonadi::Collection& parent) -{ - mParent = parent; -} - -void CollectionTest::setCollection(const Akonadi::Collection& collection) -{ - mCollection = collection; -} - -void CollectionTest::setParent(const QString& parentPath) -{ - CollectionPathResolver* resolver = new CollectionPathResolver( parentPath, this ); - if ( !resolver->exec() ) - Test::instance()->fail( resolver->errorString() ); - setParent( Collection( resolver->collection() ) ); -} - -void CollectionTest::setCollection(const QString& path) -{ - CollectionPathResolver* resolver = new CollectionPathResolver( path, this ); - if ( !resolver->exec() ) - Test::instance()->fail( resolver->errorString() ); - setCollection( Collection( resolver->collection() ) ); -} - -void CollectionTest::setName(const QString& name) -{ - mCollection.setName( name ); -} - -void CollectionTest::addContentType(const QString& type) -{ - mCollection.setContentMimeTypes( mCollection.contentMimeTypes() << type ); -} - -void CollectionTest::create() -{ - mCollection.setParentCollection( mParent ); - CollectionCreateJob* job = new CollectionCreateJob( mCollection, this ); - if ( !job->exec() ) - Test::instance()->fail( job->errorString() ); -} - -void CollectionTest::update() -{ - CollectionModifyJob* job = new CollectionModifyJob( mCollection, this ); - if ( !job->exec() ) - Test::instance()->fail( job->errorString() ); -} - -void CollectionTest::remove() -{ - CollectionDeleteJob* job = new CollectionDeleteJob( mCollection, this ); - if ( !job->exec() ) - Test::instance()->fail( job->errorString() ); -} - -QObject* CollectionTest::newInstance() -{ - return createNewInstance( this ); -} - diff -Nru kdepim-runtime-4.14.6/resourcetester/collectiontest.h kdepim-runtime-15.08.0/resourcetester/collectiontest.h --- kdepim-runtime-4.14.6/resourcetester/collectiontest.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/collectiontest.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 COLLECTIONTEST_H -#define COLLECTIONTEST_H - -#include "wrappedobject.h" - -#include - -class CollectionTest : public QObject, protected WrappedObject -{ - Q_OBJECT - public: - explicit CollectionTest( QObject *parent = 0 ); - - void setParent( const Akonadi::Collection &parent ); - void setCollection( const Akonadi::Collection &collection ); - - public slots: - QObject* newInstance(); - - void setParent( const QString &parentPath ); - void setCollection( const QString &path ); - void setName( const QString &name ); - void addContentType( const QString &type ); - - void create(); - void update(); - void remove(); - - private: - Akonadi::Collection mParent; - Akonadi::Collection mCollection; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resourcetester/global.cpp kdepim-runtime-15.08.0/resourcetester/global.cpp --- kdepim-runtime-4.14.6/resourcetester/global.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/global.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2009 Volker Krause - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include "global.h" - -#include -#include -#include -#include - -class GlobalPrivate -{ - public: - GlobalPrivate() : parent( new QObject() ) {} - QString basePath; - QString vmPath; - QObject *parent; -}; - -K_GLOBAL_STATIC( GlobalPrivate, sInstance ) - -QString Global::basePath() -{ - return sInstance->basePath; -} - -void Global::setBasePath(const QString& path) -{ - sInstance->basePath = path; - if ( !path.endsWith( QDir::separator() ) ) - sInstance->basePath += QDir::separator(); -} - -QString Global::vmPath() -{ - if ( sInstance->vmPath.isEmpty() ) - setVMPath( KStandardDirs::locateLocal( "cache", "akonadi-resourcetester/", true ) ); - return sInstance->vmPath; -} - -void Global::setVMPath(const QString& path) -{ - kDebug() << path; - sInstance->vmPath = path; - if ( !path.endsWith( QDir::separator() ) ) - sInstance->vmPath += QDir::separator(); - const QDir dir( path ); - if ( !dir.exists() ) - QDir::root().mkpath( path ); -} - -QObject* Global::parent() -{ - Q_ASSERT( sInstance->parent ); - return sInstance->parent; -} - -void Global::cleanup() -{ - delete sInstance->parent; - sInstance->parent = 0; -} diff -Nru kdepim-runtime-4.14.6/resourcetester/global.h kdepim-runtime-15.08.0/resourcetester/global.h --- kdepim-runtime-4.14.6/resourcetester/global.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/global.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2009 Volker Krause - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef GLOBAL_H -#define GLOBAL_H - -#include - -class QObject; - -namespace Global -{ - QString basePath(); - void setBasePath( const QString &path ); - - QString vmPath(); - void setVMPath( const QString &path ); - - QObject *parent(); - void cleanup(); -} - -#endif diff -Nru kdepim-runtime-4.14.6/resourcetester/itemtest.cpp kdepim-runtime-15.08.0/resourcetester/itemtest.cpp --- kdepim-runtime-4.14.6/resourcetester/itemtest.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/itemtest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "itemtest.h" - -#include "global.h" -#include "test.h" - -#include -#include - -#include -#include - -using namespace Akonadi; - -ItemTest::ItemTest( QObject *parent ) : - QObject( parent ) -{ - setObjectName( "global" ); -} - -void ItemTest::setParentCollection(const Akonadi::Collection& parent) -{ - mParent = parent; -} - -void ItemTest::setParentCollection(const QString& path) -{ - CollectionPathResolver* resolver = new CollectionPathResolver( path, this ); - if ( !resolver->exec() ) - Test::instance()->fail( resolver->errorString() ); - setParentCollection( Collection( resolver->collection() ) ); -} - -QString ItemTest::mimeType() const -{ - return mItem.mimeType(); -} - -void ItemTest::setMimeType(const QString& mimeType) -{ - mItem.setMimeType( mimeType ); -} - -void ItemTest::setPayloadFromFile(const QString& fileName) -{ - QFile file( Global::basePath() + fileName ); - if ( !file.open( QFile::ReadOnly ) ) - Test::instance()->fail( file.errorString() ); - mItem.setPayloadFromData( file.readAll() ); -} - -void ItemTest::create() -{ - ItemCreateJob* job = new ItemCreateJob( mItem, mParent, this ); - if ( !job->exec() ) - Test::instance()->fail( job->errorString() ); - mItem = job->item(); -} - -QObject* ItemTest::newInstance() -{ - return createNewInstance( this ); -} - diff -Nru kdepim-runtime-4.14.6/resourcetester/itemtest.h kdepim-runtime-15.08.0/resourcetester/itemtest.h --- kdepim-runtime-4.14.6/resourcetester/itemtest.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/itemtest.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 ITEMTEST_H -#define ITEMTEST_H - -#include "wrappedobject.h" - -#include -#include - -class ItemTest : public QObject, protected WrappedObject -{ - Q_OBJECT - public: - explicit ItemTest( QObject *parent = 0 ); - - void setParentCollection( const Akonadi::Collection &parent ); - - public slots: - QObject* newInstance(); - - void setParentCollection( const QString &path ); - QString mimeType() const; - void setMimeType( const QString &mimeType ); - void setPayloadFromFile( const QString &fileName ); - - void create(); - - private: - Akonadi::Collection mParent; - Akonadi::Item mItem; -}; - -Q_DECLARE_METATYPE( ItemTest* ) - -#endif diff -Nru kdepim-runtime-4.14.6/resourcetester/main.cpp kdepim-runtime-15.08.0/resourcetester/main.cpp --- kdepim-runtime-4.14.6/resourcetester/main.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2009 Igor Trindade Oliveira - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include "resource.h" -#include "script.h" -#include "xmloperations.h" -#include "global.h" -#include "test.h" -#include "collectiontest.h" -#include "itemtest.h" -#include "system.h" -#include "qemu.h" - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include - -void sigHandler( int signal) -{ - Q_UNUSED( signal ); - QCoreApplication::quit(); -} - -int main(int argc, char *argv[]) -{ - QString path; - - KAboutData aboutdata( "akonadi-RT", 0, - ki18n( "Akonadi Resource Tester" ), - "1.0", - ki18n( "Resource Tester" ), - KAboutData::License_GPL, - ki18n( "(c) 2009 Igor Trindade Oliveira" ) ); - - KCmdLineArgs::init( argc, argv, &aboutdata ); - - - KCmdLineOptions options; - options.add( "c" ).add( "config ", ki18n( "Configuration file to open" ), "script.js/py/rb" ); - KCmdLineArgs::addCmdLineOptions( options ); - - KApplication app; - - const KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - - if ( args->isSet( "config" ) ) - path.append(args->getOption( "config" )) ; - else - return -1; - Global::setBasePath( QFileInfo( path ).absolutePath() ); - -#ifdef Q_OS_UNIX - signal( SIGINT, sigHandler ); - signal( SIGQUIT, sigHandler ); -#endif - - if ( !Akonadi::Control::start() ) - qFatal( "Unable to start Akonadi!" ); - - Script *script = new Script(); - - script->configure(path); - script->insertObject( new XmlOperations( Global::parent() ), "XmlOperations" ); - script->insertObject( new Resource( Global::parent() ), "Resource" ); - script->insertObject( Test::instance(), "Test" ); - script->insertObject( new CollectionTest( Global::parent() ), "CollectionTest" ); - script->insertObject( new ItemTest( Global::parent() ), "ItemTest" ); - script->insertObject( new System( Global::parent() ), "System" ); - script->insertObject( new QEmu( Global::parent() ), "QEmu" ); - QTimer::singleShot( 0, script, SLOT(start()) ); - - const int result = app.exec(); - Global::cleanup(); - return result; -} diff -Nru kdepim-runtime-4.14.6/resourcetester/qemu.cpp kdepim-runtime-15.08.0/resourcetester/qemu.cpp --- kdepim-runtime-4.14.6/resourcetester/qemu.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/qemu.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,204 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "qemu.h" - -#include "global.h" -#include "test.h" - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -QEmu::QEmu(QObject* parent) : - QObject( parent ), - mVMConfig( 0 ), - mVMProcess( 0 ), - mPortOffset( 42000 ), // TODO should be somewhat dynamic to allo running multiple instances in parallel - mMonitorPort( -1 ), - mStarted( false ) -{ - Q_ASSERT( parent ); -} - -QEmu::~QEmu() -{ - if ( mVMProcess && mVMProcess->state() == QProcess::Running ) - stop(); - delete mVMConfig; -} - -void QEmu::setVMConfig(const QString& configFileName) -{ - delete mVMConfig; - mVMConfig = new KConfig( Global::basePath() + '/' + configFileName ); -} - -void QEmu::start() -{ - Q_ASSERT( mVMConfig ); - if ( mVMProcess ) { - kWarning() << "VM already running."; - return; - } - - KConfigGroup emuConf( mVMConfig, "Emulator" ); - QStringList args = KShell::splitArgs( emuConf.readEntry( "Arguments", QString() ) ); - const QList ports = emuConf.readEntry( "Ports", QList() ); - foreach ( int port, ports ) { - args << "-redir" << QString::fromLatin1( "tcp:%1::%2" ).arg( port + mPortOffset ).arg( port ); - } - mMonitorPort = emuConf.readEntry( "MonitorPort", 23 ) + mPortOffset; - args << "-monitor" << QString::fromLatin1( "tcp:127.0.0.1:%1,server,nowait" ).arg( mMonitorPort ); - args << "-hda" << vmImage(); - - // If a SnapshotName is given in the configuration, load that snapshot - // with -loadvm and assume that it's OK to write to he image file. - // Othewise, use the -snapshot option to avoid changing the image - // file. - QString snapshotName = emuConf.readEntry( "SnapshotName", "" ); - if ( snapshotName.isEmpty() ) { - args << "-snapshot"; - } else { - args << "-loadvm" << snapshotName; - } - - kDebug() << "Starting QEMU with arguments" << args << "..."; - - mVMProcess = new KProcess( this ); - connect( mVMProcess, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(vmFinished(int,QProcess::ExitStatus)) ); - mVMProcess->setProgram( "qemu", args ); - mVMProcess->start(); - mVMProcess->waitForStarted(); - mStarted = true; - kDebug() << "QEMU started."; - - if ( emuConf.readEntry( "WaitForPorts", true ) ) { - const QList waitPorts = emuConf.readEntry( "WaitForPorts", QList() ); - foreach ( int port, waitPorts ) - waitForPort( port ); - } -} - -void QEmu::stop() -{ - mStarted = false; - if ( !mVMProcess ) - return; - kDebug() << "Stopping QEMU..."; - - // send stop command via QEMU monitor - QTcpSocket socket; - socket.connectToHost( "localhost", mMonitorPort ); - if ( socket.waitForConnected() ) { - socket.write( "quit\n"); - socket.flush(); - socket.waitForBytesWritten(); - mVMProcess->waitForFinished(10000); - } else { - kDebug() << "Unable to connect to QEMU monitor:" << socket.errorString(); - } - - if ( mVMProcess->state() == QProcess::Running ) { - kDebug() << "qemu is still running. terminating"; - mVMProcess->terminate(); - } - - delete mVMProcess; - mVMProcess = 0; - kDebug() << "QEMU stopped."; -} - -QString QEmu::vmImage() const -{ - KConfigGroup conf( mVMConfig, "Image" ); - - const KUrl imageUrl = conf.readEntry( "Source", QString() ); - Q_ASSERT( !imageUrl.isEmpty() ); - - const QString imageArchiveFileName = imageUrl.fileName(); - Q_ASSERT( !imageArchiveFileName.isEmpty() ); - - // check if the image has been downloaded already - const QString localArchiveFileName = Global::vmPath() + imageArchiveFileName; - if ( !QFile::exists( localArchiveFileName ) ) { - kDebug() << "Downloading VM image from" << imageUrl << "to" << localArchiveFileName << "..."; - const bool result = KIO::NetAccess::file_copy( imageUrl, localArchiveFileName, 0 ); - if ( !result ) - kFatal() << "Downloading" << imageUrl << "failed!"; - kDebug() << "Downloading VM image complete."; - } - - // check if the image archive has been extracted yet - const QString extractedDirName = Global::vmPath() + imageArchiveFileName + ".directory"; - if ( !QDir::root().exists( extractedDirName ) ) { - kDebug() << "Extracting VM image..."; - QDir::root().mkpath( extractedDirName ); - KProcess proc; - proc.setWorkingDirectory( extractedDirName ); - proc.setProgram( "tar", QStringList() << "xvf" << localArchiveFileName ); - proc.execute(); - kDebug() << "Extracting VM image complete."; - } - - // check if the actual image file is there and return it - const QString imageFile = extractedDirName + QDir::separator() + conf.readEntry( "File", QString() ); - if ( !QFile::exists( imageFile ) ) - kFatal() << "Image file" << imageFile << "does not exist."; - - return imageFile; -} - -void QEmu::waitForPort(int port) -{ - kDebug() << "Waiting for port" << (port + mPortOffset) << "..."; - forever { - QTcpSocket socket; - socket.connectToHost( "localhost", port + mPortOffset ); - if ( !socket.waitForConnected( 5000 ) ) { - QTest::qWait( 5000 ); - continue; - } - if ( socket.waitForReadyRead( 5000 ) ) - break; - } -} - -int QEmu::portOffset() const -{ - return mPortOffset; -} - -void QEmu::vmFinished(int exitCode, QProcess::ExitStatus exitStatus) -{ - Q_UNUSED( exitCode ); - Q_UNUSED( exitStatus ); - if ( mStarted ) - Test::instance()->fail( "QEMU termineated!" ); -} - - diff -Nru kdepim-runtime-4.14.6/resourcetester/qemu.h kdepim-runtime-15.08.0/resourcetester/qemu.h --- kdepim-runtime-4.14.6/resourcetester/qemu.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/qemu.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 QEMU_H -#define QEMU_H - -#include - -class KConfig; - -class QEmu : public QObject -{ - Q_OBJECT - public: - explicit QEmu( QObject *parent ); - ~QEmu(); - - public slots: - void setVMConfig( const QString &configFileName ); - void start(); - void stop(); - int portOffset() const; - - private: - QString vmImage() const; - void waitForPort( int port ); - - private slots: - void vmFinished( int exitCode, QProcess::ExitStatus exitStatus ); - - private: - KConfig* mVMConfig; - KProcess* mVMProcess; - int mPortOffset; - int mMonitorPort; - bool mStarted; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resourcetester/resource.cpp kdepim-runtime-15.08.0/resourcetester/resource.cpp --- kdepim-runtime-4.14.6/resourcetester/resource.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/resource.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2009 Igor Trindade Oliveira - * Copyright (c) 2009 Volker Krause - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include "resource.h" - -#include "global.h" -#include -#include "test.h" - -#include -#include - -#include -#include - -#include -#include -#include - -using namespace Akonadi; - -Resource::Resource(QObject* parent) : - QObject( parent ) -{ - Q_ASSERT( parent ); -} - -Resource::~Resource() -{ - destroy(); -} - -void Resource::setType(const QString& type) -{ - mTypeIdentifier = type; -} - -QString Resource::identifier() const -{ - return mInstance.identifier(); -} - -void Resource::setOption(const QString& key, const QVariant& value) -{ - mSettings.insert( key, value ); -} - -void Resource::setPathOption(const QString& key, const QString& path) -{ - if ( QFileInfo( path ).isAbsolute() ) - setOption( key, path ); - else - setOption( key, QString(Global::basePath() + QDir::separator() + path) ); -} - - -bool Resource::createResource() -{ - if ( mInstance.isValid() ) - return false; - - const AgentType type = AgentManager::self()->type( mTypeIdentifier ); - if ( !type.isValid() ) - return false; - - AgentInstanceCreateJob *job = new AgentInstanceCreateJob( type, this ); - if ( !job->exec() ) { - kWarning() << job->errorText(); - return false; - } - mInstance = job->instance(); - - QDBusInterface iface( "org.freedesktop.Akonadi.Resource." + identifier(), "/Settings" ); - if ( !iface.isValid() ) - return false; - - // configure resource - for ( QHash::const_iterator it = mSettings.constBegin(); it != mSettings.constEnd(); ++it ) { - kDebug() << "Setting up " << it.key() << " for agent " << identifier(); - const QString methodName = QString::fromLatin1("set%1").arg( it.key() ); - const QVariant arg = it.value(); - QDBusReply reply = iface.call( methodName, arg ); - if ( !reply.isValid() ) - kError() << "Setting " << it.key() << " failed for agent " << identifier() << ":" << reply.error().message(); - } - mInstance.reconfigure(); - - ResourceSynchronizationJob *syncJob = new ResourceSynchronizationJob( mInstance, this ); - if ( !syncJob->exec() ) - kError() << "Synching resource failed: " << syncJob->errorString(); - - return true; -} - -void Resource::create() -{ - if ( !createResource() ) - Test::instance()->fail( "Creating resource failed." ); -} - - -void Resource::destroy() -{ - if ( !mInstance.isValid() ) - return; - AgentManager::self()->removeInstance( mInstance ); - mInstance = AgentInstance(); -} - -void Resource::write() -{ - QDBusInterface iface( "org.freedesktop.Akonadi", "/notifications/debug", "org.freedesktop.Akonadi.NotificationManager" ); - Q_ASSERT( iface.isValid() ); - QDBusReply result = iface.call( "emitPendingNotifications" ); - if ( !result.isValid() ) - Test::instance()->fail( result.error().message() ); - ResourceSynchronizationJob *syncJob = new ResourceSynchronizationJob( mInstance, this ); - if ( !syncJob->exec() ) - kError() << "Synching resource failed: " << syncJob->errorString(); -} - -void Resource::recreate() -{ - write(); - destroy(); - create(); -} - -QObject* Resource::newInstance() -{ - return createNewInstance( this ); -} - -QObject* Resource::newInstance(const QString& type) -{ - Resource* r = qobject_cast( createNewInstance( this ) ); - Q_ASSERT( r ); - r->setType( type ); - return r; -} - diff -Nru kdepim-runtime-4.14.6/resourcetester/resource.h kdepim-runtime-15.08.0/resourcetester/resource.h --- kdepim-runtime-4.14.6/resourcetester/resource.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/resource.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - Copyright (c) 2009 Igor Trindade Oliveira - - 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 RESOURCE_H -#define RESOURCE_H - -#include "wrappedobject.h" -#include - -#include -#include -#include - -class Resource: public QObject, protected WrappedObject -{ - Q_OBJECT - public: - explicit Resource( QObject *parent ); - ~Resource(); - - public slots: - QObject* newInstance(); - QObject* newInstance( const QString &type ); - - void setType( const QString &type ); - QString identifier() const; - - void setOption( const QString &key, const QVariant &value ); - void setPathOption( const QString &key, const QString &path ); - - bool createResource(); - void create(); - void destroy(); - void write(); - void recreate(); - - private: - QString mTypeIdentifier; - Akonadi::AgentInstance mInstance; - QHash mSettings; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resourcetester/script.cpp kdepim-runtime-15.08.0/resourcetester/script.cpp --- kdepim-runtime-4.14.6/resourcetester/script.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/script.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2009 Igor Trindade Oliveira - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include "script.h" -#include "global.h" -#include -#include - -Script::Script() -{ - action = new Kross::Action(this, "ResourceTester"); - connect( action, SIGNAL(finished(Kross::Action*)), SLOT(finished(Kross::Action*)) ); - action->addObject( this, QLatin1String( "Script" ) ); -} - -void Script::configure(const QString &path) -{ - action->setFile(path); -} - -void Script::insertObject(QObject *object, const QString &objectName) -{ - action->addObject(object, objectName); -} - -void Script::include(const QString& path) -{ - QFile f( Global::basePath() + path ); - if ( !f.open( QFile::ReadOnly ) ) - kError() << "Unable to open file" << Global::basePath() + path; - else - action->evaluate( f.readAll() ); -} - -QString Script::absoluteFileName(const QString& path) -{ - return Global::basePath() + path; -} - -void Script::start() -{ - action->trigger(); -} - -void Script::finished(Kross::Action* action) -{ - if ( action->hadError() ) { - kError() << action->errorMessage() << action->errorTrace(); - QCoreApplication::instance()->exit( 1 ); - } else { - QCoreApplication::instance()->quit(); - } -} - - diff -Nru kdepim-runtime-4.14.6/resourcetester/script.h kdepim-runtime-15.08.0/resourcetester/script.h --- kdepim-runtime-4.14.6/resourcetester/script.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/script.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2009 Igor Trindade Oliveira - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef SCRIPT_H -#define SCRIPT_H - -#include -#include - -class Script : public QObject -{ - Q_OBJECT - public: - Script(); - void configure(const QString &path); - void insertObject(QObject *object, const QString &objectName); - - public slots: - Q_SCRIPTABLE void include( const QString &path ); - Q_SCRIPTABLE QString absoluteFileName( const QString &path ); - - private slots: - void start(); - void finished( Kross::Action *action ); - - private: - Kross::Action *action; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resourcetester/system.cpp kdepim-runtime-15.08.0/resourcetester/system.cpp --- kdepim-runtime-4.14.6/resourcetester/system.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/system.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "system.h" -#include "test.h" -#include "global.h" - -#include -#include -#include - -System::System(QObject* parent) : - QObject( parent ) -{ -} - -void System::exec(const QString &_program, const QStringList& args) -{ - QString program = _program; - if ( QFile::exists( Global::basePath() + _program ) ) - program = Global::basePath() + _program; - Test::instance()->verify( KProcess::execute( program, args ) == 0 ); -} - -void System::sleep(int secs) -{ - QTest::qWait( secs * 1000 ); -} - diff -Nru kdepim-runtime-4.14.6/resourcetester/system.h kdepim-runtime-15.08.0/resourcetester/system.h --- kdepim-runtime-4.14.6/resourcetester/system.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/system.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 SYSTEM_H -#define SYSTEM_H - -#include - -class System : public QObject -{ - Q_OBJECT - public: - explicit System( QObject *parent = 0 ); - - public slots: - void exec( const QString& program, const QStringList& args ); - void sleep( int secs ); -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resourcetester/test.cpp kdepim-runtime-15.08.0/resourcetester/test.cpp --- kdepim-runtime-4.14.6/resourcetester/test.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/test.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "test.h" -#include "resource.h" -#include "global.h" - -#include -#include -#include - -Test* Test::mSelf = 0; - -Test::Test(QObject* parent) : - QObject( parent ) -{ -} - -void Test::verify(bool value) -{ - if ( !value ) - fail( "Assertion failed." ); -} - -void Test::verify( QObject* object, const QString &slot ) -{ - kDebug() << object << slot; - bool result = false; - if ( !QMetaObject::invokeMethod( object, slot.toLatin1(), Q_RETURN_ARG( bool, result ) ) ) - fail( "Unable to call method " + slot ); - - if ( result ) - return; - - QString lastError = QString( "Call to method " + slot + " returned false." ); - QMetaObject::invokeMethod( object, "lastError", Q_RETURN_ARG( QString, lastError ) ); - fail( lastError ); -} - -void Test::fail(const QString& error) -{ - kError() << error; - abort(); -} - -void Test::abort() -{ - Global::cleanup(); - exit( -1 ); -} - -void Test::alert(const QString& msg) -{ - KMessageBox::information( 0, msg ); -} - -Test* Test::instance() -{ - if ( !mSelf ) - mSelf = new Test( Global::parent() ); - return mSelf; -} - - diff -Nru kdepim-runtime-4.14.6/resourcetester/test.h kdepim-runtime-15.08.0/resourcetester/test.h --- kdepim-runtime-4.14.6/resourcetester/test.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/test.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 TEST_H -#define TEST_H - -#include - -class Test : public QObject -{ - Q_OBJECT - public: - static Test* instance(); - - public slots: - void verify( bool value ); - void verify( QObject *object, const QString &slot ); - void fail( const QString &error ); - void abort(); - void alert( const QString &msg ); - - private: - Test( QObject *parent = 0 ); - - static Test* mSelf; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resourcetester/tests/CMakeLists.txt kdepim-runtime-15.08.0/resourcetester/tests/CMakeLists.txt --- kdepim-runtime-4.14.6/resourcetester/tests/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -akonadi_add_resourcetest( ctor-test construct.es ) diff -Nru kdepim-runtime-4.14.6/resourcetester/tests/construct.es kdepim-runtime-15.08.0/resourcetester/tests/construct.es --- kdepim-runtime-4.14.6/resourcetester/tests/construct.es 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/tests/construct.es 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -var i1 = ItemTest.newInstance(); -var i2 = ItemTest.newInstance(); - -print( i1 ); -print( i2 ); - -i1.setMimeType( "application/foo" ); -i2.setMimeType( "application/bar" ); - -print( i1.mimeType() + " != " + i2.mimeType() ); -Test.verify( i1.mimeType() != i2.mimeType() ); - diff -Nru kdepim-runtime-4.14.6/resourcetester/tests/unittestenv/config-mysql-db.xml kdepim-runtime-15.08.0/resourcetester/tests/unittestenv/config-mysql-db.xml --- kdepim-runtime-4.14.6/resourcetester/tests/unittestenv/config-mysql-db.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/tests/unittestenv/config-mysql-db.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ - - kdehome - xdgconfig-mysql.db - xdglocal - true - diff -Nru kdepim-runtime-4.14.6/resourcetester/tests/unittestenv/config.xml kdepim-runtime-15.08.0/resourcetester/tests/unittestenv/config.xml --- kdepim-runtime-4.14.6/resourcetester/tests/unittestenv/config.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/tests/unittestenv/config.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ - - kdehome - xdgconfig - xdglocal - akonadi_knut_resource - akonadi_knut_resource - akonadi_knut_resource - Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/resourcetester/tests/unittestenv/kdehome/share/apps/kwallet/kdewallet.kwl and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/resourcetester/tests/unittestenv/kdehome/share/apps/kwallet/kdewallet.kwl differ diff -Nru kdepim-runtime-4.14.6/resourcetester/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc kdepim-runtime-15.08.0/resourcetester/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc --- kdepim-runtime-4.14.6/resourcetester/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/tests/unittestenv/kdehome/share/config/akonadi-firstrunrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[ProcessedDefaults] -defaultaddressbook=done -defaultcalendar=done diff -Nru kdepim-runtime-4.14.6/resourcetester/tests/unittestenv/kdehome/share/config/kdebugrc kdepim-runtime-15.08.0/resourcetester/tests/unittestenv/kdehome/share/config/kdebugrc --- kdepim-runtime-4.14.6/resourcetester/tests/unittestenv/kdehome/share/config/kdebugrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/tests/unittestenv/kdehome/share/config/kdebugrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -[0] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=2 -FatalFilename[$e]=kdebug.dbg -FatalOutput=2 -InfoFilename[$e]=kdebug.dbg -InfoOutput=2 -WarnFilename[$e]=kdebug.dbg -WarnOutput=2 - -[264] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[5250] -InfoOutput=2 - -[7009] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[7011] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[7012] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 - -[7014] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=0 -FatalFilename[$e]=kdebug.dbg -FatalOutput=0 -InfoFilename[$e]=kdebug.dbg -InfoOutput=0 -WarnFilename[$e]=kdebug.dbg -WarnOutput=0 - -[7021] -AbortFatal=true -ErrorFilename[$e]=kdebug.dbg -ErrorOutput=4 -FatalFilename[$e]=kdebug.dbg -FatalOutput=4 -InfoFilename[$e]=kdebug.dbg -InfoOutput=4 -WarnFilename[$e]=kdebug.dbg -WarnOutput=4 diff -Nru kdepim-runtime-4.14.6/resourcetester/tests/unittestenv/kdehome/share/config/kdedrc kdepim-runtime-15.08.0/resourcetester/tests/unittestenv/kdehome/share/config/kdedrc --- kdepim-runtime-4.14.6/resourcetester/tests/unittestenv/kdehome/share/config/kdedrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/tests/unittestenv/kdehome/share/config/kdedrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[General] -CheckSycoca=false -CheckFileStamps=false diff -Nru kdepim-runtime-4.14.6/resourcetester/tests/unittestenv/kdehome/share/config/kwalletrc kdepim-runtime-15.08.0/resourcetester/tests/unittestenv/kdehome/share/config/kwalletrc --- kdepim-runtime-4.14.6/resourcetester/tests/unittestenv/kdehome/share/config/kwalletrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/tests/unittestenv/kdehome/share/config/kwalletrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -[Auto Allow] -kdewallet=Akonadi Resource - -[Wallet] -Close When Idle=false -Enabled=true -First Use=false -Use One Wallet=true diff -Nru kdepim-runtime-4.14.6/resourcetester/tests/unittestenv/xdgconfig-mysql.db/akonadi/akonadiserverrc kdepim-runtime-15.08.0/resourcetester/tests/unittestenv/xdgconfig-mysql.db/akonadi/akonadiserverrc --- kdepim-runtime-4.14.6/resourcetester/tests/unittestenv/xdgconfig-mysql.db/akonadi/akonadiserverrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/tests/unittestenv/xdgconfig-mysql.db/akonadi/akonadiserverrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -[%General] -ExternalPayload=false - -[Search] -Manager=Dummy diff -Nru kdepim-runtime-4.14.6/resourcetester/wrappedobject.cpp kdepim-runtime-15.08.0/resourcetester/wrappedobject.cpp --- kdepim-runtime-4.14.6/resourcetester/wrappedobject.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/wrappedobject.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "wrappedobject.h" - -int WrappedObject::mInstanceCounter = 0; diff -Nru kdepim-runtime-4.14.6/resourcetester/wrappedobject.h kdepim-runtime-15.08.0/resourcetester/wrappedobject.h --- kdepim-runtime-4.14.6/resourcetester/wrappedobject.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/wrappedobject.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 WRAPPEDOBJECT_H -#define WRAPPEDOBJECT_H - -#include - -class WrappedObject -{ - protected: - template - QObject* createNewInstance( QObject *parent ) - { - T* instance = new T( parent ); - instance->setObjectName( instance->metaObject()->className() + QString::number( ++mInstanceCounter ) ); - return instance; - } - - private: - static int mInstanceCounter; -}; - -#endif diff -Nru kdepim-runtime-4.14.6/resourcetester/xmloperations.cpp kdepim-runtime-15.08.0/resourcetester/xmloperations.cpp --- kdepim-runtime-4.14.6/resourcetester/xmloperations.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/xmloperations.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,428 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 "xmloperations.h" -#include "global.h" -#include "test.h" - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -using namespace Akonadi; - -template QTextStream& operator<<( QTextStream &s, const QSet &set ) -{ - s << '{'; - foreach ( const T &element, set ) - s << element << ", "; - s << '}'; - return s; -} - -QTextStream& operator<<( QTextStream &s, const QStringList &list ) -{ - s << '(' << list.join( ", " ) << ')'; - return s; -} - -XmlOperations::XmlOperations(QObject* parent) : - QObject( parent ), - mCollectionFields( 0xFF ), - mCollectionKey( RemoteId ), - mItemFields( 0xFF ), - mItemKey( ItemRemoteId ), - mNormalizeRemoteIds( false ) -{ -} - -XmlOperations::~XmlOperations() -{ -} - -Item XmlOperations::getItemByRemoteId(const QString& rid) -{ - return mDocument.itemByRemoteId( rid, true); -} - -Collection XmlOperations::getCollectionByRemoteId(const QString& rid) -{ - return mDocument.collectionByRemoteId(rid); -} - -void XmlOperations::setRootCollections(const QString& resourceId) -{ - CollectionFetchJob *job = new CollectionFetchJob( Collection::root(), CollectionFetchJob::FirstLevel, this ); - job->fetchScope().setAncestorRetrieval( CollectionFetchScope::All ); - job->fetchScope().setResource( resourceId ); - if ( job->exec() ) - setRootCollections( job->collections() ); - else - mErrorMsg = job->errorText(); -} - -void XmlOperations::setRootCollections(const Collection::List& roots) -{ - mRoots = roots; -} - -void XmlOperations::setXmlFile(const QString& fileName) -{ - mFileName = fileName; - if ( QFileInfo( fileName ).isAbsolute() ) - mDocument.loadFile( fileName ); - else - mDocument.loadFile( Global::basePath() + QDir::separator() + fileName ); -} - -QString XmlOperations::lastError() const -{ - return mErrorMsg; -} - -void XmlOperations::setCollectionKey(XmlOperations::CollectionField field) -{ - mCollectionKey = field; -} - -void XmlOperations::setCollectionKey(const QString& fieldName) -{ - const QMetaEnum me = metaObject()->enumerator( metaObject()->indexOfEnumerator( "CollectionField" ) ); - setCollectionKey( static_cast( me.keyToValue( fieldName.toLatin1() ) ) ); -} - -void XmlOperations::ignoreCollectionField(XmlOperations::CollectionField field) -{ - mCollectionFields = mCollectionFields & ~field; -} - -void XmlOperations::ignoreCollectionField(const QString& fieldName) -{ - const QMetaEnum me = metaObject()->enumerator( metaObject()->indexOfEnumerator( "CollectionField" ) ); - ignoreCollectionField( static_cast( me.keyToValue( fieldName.toLatin1() ) ) ); -} - -void XmlOperations::setItemKey(XmlOperations::ItemField field) -{ - mItemKey = field; -} - -void XmlOperations::setItemKey(const QString& _fieldName) -{ - QString fieldName = _fieldName; - if ( !fieldName.startsWith( QLatin1String ( "Item" ) ) ) - fieldName.prepend( "Item" ); - const QMetaEnum me = metaObject()->enumerator( metaObject()->indexOfEnumerator( "ItemField" ) ); - setItemKey( static_cast( me.keyToValue( fieldName.toLatin1() ) ) ); -} - -void XmlOperations::ignoreItemField(XmlOperations::ItemField field) -{ - mItemFields = mItemFields & ~field; -} - -void XmlOperations::ignoreItemField(const QString& _fieldName) -{ - QString fieldName = _fieldName; - if ( !fieldName.startsWith( "Item" ) ) - fieldName.prepend( "Item" ); - const QMetaEnum me = metaObject()->enumerator( metaObject()->indexOfEnumerator( "ItemField" ) ); - ignoreItemField( static_cast( me.keyToValue( fieldName.toLatin1() ) ) ); -} - -void XmlOperations::setNormalizeRemoteIds(bool enable) -{ - mNormalizeRemoteIds = enable; -} - -bool XmlOperations::compare() -{ - if ( !mDocument.isValid() ) { - mErrorMsg = mDocument.lastError(); - return false; - } - - if ( mRoots.isEmpty() ) { - if ( !mErrorMsg.isEmpty() ) - mErrorMsg = QLatin1String( "No root collections specified." ); - return false; - } - - const Collection::List docRoots = mDocument.childCollections( Collection::root() ); - if ( compareCollections( mRoots, docRoots ) ) - return true; - - XmlWriteJob *xmlJob = new XmlWriteJob( mRoots, mFileName + ".actual", this ); - if ( !xmlJob->exec() ) - kError() << xmlJob->errorText(); - return false; -} - -void XmlOperations::assertEqual() -{ - if ( !compare() ) - Test::instance()->fail( lastError() ); -} - -static QString normalizeRemoteId( const QString &in ) -{ - QString out( in ); - if ( in.startsWith( Global:: basePath() ) ) { - out = in.mid( Global::basePath().length() ); - if ( out.startsWith( QDir::separator() ) ) - out = out.mid( 1 ); - } - return out; -} - -Collection XmlOperations::normalizeCollection( const Collection &in ) const -{ - Collection out( in ); - if ( mNormalizeRemoteIds ) - out.setRemoteId( normalizeRemoteId( in.remoteId() ) ); - QStringList l = in.contentMimeTypes(); - std::sort( l.begin(), l.end() ); - out.setContentMimeTypes( l ); - return out; -} - -Item XmlOperations::normalizeItem( const Item& in ) const -{ - Item out( in ); - if ( mNormalizeRemoteIds ) - out.setRemoteId( normalizeRemoteId( in.remoteId() ) ); - return out; -} - -bool XmlOperations::compareCollections(const Collection::List& _cols, const Collection::List& _refCols) -{ - Collection::List cols; - foreach ( const Collection &c, _cols ) - cols.append( normalizeCollection( c ) ); - Collection::List refCols; - foreach ( const Collection &c, _refCols ) - refCols.append( normalizeCollection( c ) ); - - switch ( mCollectionKey ) { - case RemoteId: - sortEntityList( cols, &Collection::remoteId ); - sortEntityList( refCols, &Collection::remoteId ); - break; - case Name: - sortEntityList( cols, &Collection::name ); - sortEntityList( refCols, &Collection::name ); - break; - case None: - break; - default: - Q_ASSERT( false ); - } - - for ( int i = 0; i < cols.count(); ++i ) { - const Collection col = cols.at( i ); - if ( refCols.count() <= i ) { - mErrorMsg = QString::fromLatin1( "Additional collection with remote id '%1' was found." ).arg( col.remoteId() ); - return false; - } - - const Collection refCol = refCols.at( i ); - if ( !compareCollection( col, refCol ) ) - return false; - } - - if ( refCols.count() != cols.count() ) { - const Collection refCol = refCols.at( cols.count() ); - mErrorMsg = QString::fromLatin1( "Collection with remote id '%1' is missing." ).arg( refCol.remoteId() ); - return false; - } - - return true; -} - -bool XmlOperations::compareCollection(const Collection& col, const Collection& refCol) -{ - // compare the two collections - if ( !compareValue( col, refCol, &Collection::remoteId, RemoteId ) || - !compareValue( col, refCol, &Collection::contentMimeTypes, ContentMimeType ) || - !compareValue( col, refCol, &Collection::name, Name ) ) - return false; - - if ( (mCollectionFields & Attributes) && !compareAttributes( col, refCol ) ) - return false; - - // compare child items - ItemFetchJob *ijob = new ItemFetchJob( col, this ); - ijob->fetchScope().fetchAllAttributes( true ); - ijob->fetchScope().fetchFullPayload( true ); - if ( !ijob->exec() ) { - mErrorMsg = ijob->errorText(); - return false; - } - const Item::List items = ijob->items(); - const Item::List refItems = mDocument.items( refCol, true ); - if ( !compareItems( items, refItems ) ) - return false; - - // compare child collections - CollectionFetchJob *cjob = new CollectionFetchJob( col, CollectionFetchJob::FirstLevel, this ); - cjob->fetchScope().setAncestorRetrieval( CollectionFetchScope::All ); - if ( !cjob->exec() ) { - mErrorMsg = cjob->errorText(); - return false; - } - const Collection::List cols = cjob->collections(); - const Collection::List refCols = mDocument.childCollections( refCol ); - return compareCollections( cols, refCols ); -} - -bool XmlOperations::hasItem(const Item& _item, const Collection& _col) -{ - ItemFetchJob *ijob = new ItemFetchJob( _col, this ); - ijob->fetchScope().fetchAllAttributes( true ); - ijob->fetchScope().fetchFullPayload( true ); - if ( !ijob->exec() ) { - mErrorMsg = ijob->errorText(); - return false; - } - const Item::List items = ijob->items(); - - for( int i = 0; i < items.count(); ++i) { - if( _item == items.at(i) ) { - return true; - } - } - return false; -} - -bool XmlOperations::hasItem(const Item& _item, const QString& rid) -{ - CollectionFetchJob *job = new CollectionFetchJob( Collection::root(), CollectionFetchJob::FirstLevel, this ); - Collection::List colist; - - if ( job->exec() ) - colist = job->collections() ; - foreach( const Collection &collection, colist ) { - if(rid == collection.remoteId()) { - return hasItem(_item, collection); - } - } - return false; -} - - -bool XmlOperations::compareItems(const Item::List& _items, const Item::List& _refItems) -{ - Item::List items; - foreach ( const Item &i, _items ) - items.append( normalizeItem( i ) ); - Item::List refItems; - foreach ( const Item &i, _refItems ) - refItems.append( normalizeItem( i ) ); - - switch ( mItemKey ) { - case ItemRemoteId: - sortEntityList( items, &Item::remoteId ); - sortEntityList( refItems, &Item::remoteId ); - break; - case ItemNone: - break; - default: - Q_ASSERT( false ); - } - - for ( int i = 0; i < items.count(); ++i ) { - const Item item = items.at( i ); - if ( refItems.count() <= i ) { - mErrorMsg = QString::fromLatin1( "Additional item with remote id '%1' was found." ).arg( item.remoteId() ); - return false; - } - - const Item refItem = refItems.at( i ); - if ( !compareItem( item, refItem ) ) - return false; - } - - if ( refItems.count() != items.count() ) { - const Item refItem = refItems.at( items.count() ); - mErrorMsg = QString::fromLatin1( "Item with remote id '%1' is missing." ).arg( refItem.remoteId() ); - return false; - } - - return true; -} - -bool XmlOperations::compareItem(const Item& item, const Item& refItem) -{ - if ( !compareValue( item, refItem, &Item::remoteId, ItemRemoteId ) || - !compareValue( item, refItem, &Item::mimeType, ItemMimeType ) || - !compareValue( item, refItem, &Item::flags, ItemFlags ) || - !compareValue( item, refItem, &Item::payloadData, ItemPayload ) ) - return false; - - return compareAttributes( item, refItem ); -} - -bool XmlOperations::compareAttributes(const Entity& entity, const Entity& refEntity) -{ - Attribute::List attrs = entity.attributes(); - Attribute::List refAttrs = refEntity.attributes(); - std::sort( attrs.begin(), attrs.end(), boost::bind( &Attribute::type, _1 ) < boost::bind( &Attribute::type, _2 ) ); - std::sort( refAttrs.begin(), refAttrs.end(), boost::bind( &Attribute::type, _1 ) < boost::bind( &Attribute::type, _2 ) ); - - for ( int i = 0; i < attrs.count(); ++i ) { - Attribute* attr = attrs.at( i ); - if ( refAttrs.count() <= i ) { - mErrorMsg = QString::fromLatin1( "Additional attribute of type '%1' for object with remote id '%2' was found." ) - .arg( QString::fromLatin1( attr->type() ) ).arg( entity.remoteId() ); - return false; - } - - Attribute* refAttr = refAttrs.at( i ); - if ( attr->type() != refAttr->type() ) { - mErrorMsg = QString::fromLatin1( "Object with remote id '%1' misses attribute of type '%2'." ) - .arg( entity.remoteId() ).arg( QString::fromLatin1( refAttr->type() ) ); - return false; - } - - bool result = compareValue( attr->serialized(), refAttr->serialized() ); - if ( !result ) { - mErrorMsg.prepend( QString::fromLatin1( "Object with remote id '%1' differs in attribute '%2':\n" ) - .arg( entity.remoteId() ).arg( QString::fromLatin1( attr->type() ) ) ); - return false; - } - } - - if ( refAttrs.count() != attrs.count() ) { - Attribute* refAttr = refAttrs.at( attrs.count() ); - mErrorMsg = QString::fromLatin1( "Object with remote id '%1' misses attribute of type '%2'." ) - .arg( entity.remoteId() ).arg( QString::fromLatin1( refAttr->type() ) );; - return false; - } - - return true; -} - diff -Nru kdepim-runtime-4.14.6/resourcetester/xmloperations.h kdepim-runtime-15.08.0/resourcetester/xmloperations.h --- kdepim-runtime-4.14.6/resourcetester/xmloperations.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/resourcetester/xmloperations.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,179 +0,0 @@ -/* - Copyright (c) 2009 Volker Krause - - 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 XMLOPERATIONS_H -#define XMLOPERATIONS_H - -#include -#include -#include - -#include -#include -#include - -#include -#include - - -/** - Compares a Akonadi collection sub-tree with reference data supplied in an XML file. -*/ -class XmlOperations : public QObject -{ - Q_OBJECT - Q_ENUMS( CollectionField ItemField ) - - public: - explicit XmlOperations( QObject *parent = 0 ); - ~XmlOperations(); - - enum CollectionField { - None = 0, - RemoteId = 1, - Name = 2, - ContentMimeType = 4, - Attributes = 8 - }; - - enum ItemField { - ItemNone = 0, - ItemRemoteId = 1, - ItemMimeType = 2, - ItemFlags = 4, - ItemPayload = 8 - }; - - Q_DECLARE_FLAGS( CollectionFields, CollectionField ) - Q_DECLARE_FLAGS( ItemFields, ItemField ) - - void setCollectionKey( CollectionField field ); - void ignoreCollectionField( CollectionField field ); - void setItemKey( ItemField field ); - void ignoreItemField( ItemField field ); - - public slots: - void setRootCollections( const QString &resourceId ); - void setRootCollections( const Akonadi::Collection::List &roots ); - void setXmlFile( const QString &fileName ); - - Akonadi::Item getItemByRemoteId(const QString& rid); - Akonadi::Collection getCollectionByRemoteId(const QString& rid); - - void setCollectionKey( const QString &fieldName ); - void ignoreCollectionField( const QString &fieldName ); - void setItemKey( const QString &fieldName ); - void ignoreItemField( const QString &fieldName ); - - void setNormalizeRemoteIds( bool enable ); - - bool compare(); - void assertEqual(); - - QString lastError() const; - - bool compareCollections( const Akonadi::Collection::List &cols, const Akonadi::Collection::List &refCols ); - bool compareCollection( const Akonadi::Collection &col, const Akonadi::Collection &refCol ); - bool compareItems( const Akonadi::Item::List &items, const Akonadi::Item::List &refItems ); - bool compareItem( const Akonadi::Item &item, const Akonadi::Item &refItem ); - bool compareAttributes( const Akonadi::Entity &entity, const Akonadi::Entity &refEntity ); - bool hasItem(const Akonadi::Item& _item, const Akonadi::Collection& _col); - bool hasItem(const Akonadi::Item& _item, const QString& rid); - - private: - template - bool compareValue( const Akonadi::Collection &col, const Akonadi::Collection &refCol, - T (P::*property)() const, CollectionField propertyType ); - template - bool compareValue( const Akonadi::Item& item, const Akonadi::Item& refItem, - T (P::*property)() const, ItemField propertyType ); - template bool compareValue( const T& value, const T& refValue ); - - template - void sortEntityList( QList &list, T ( P::*property)() const ) const; - - - Akonadi::Collection normalizeCollection( const Akonadi::Collection &in ) const; - Akonadi::Item normalizeItem( const Akonadi::Item &in ) const; - - private: - Akonadi::Collection::List mRoots; - Akonadi::XmlDocument mDocument; - QString mFileName; - QString mErrorMsg; - CollectionFields mCollectionFields; - CollectionField mCollectionKey; - ItemFields mItemFields; - ItemField mItemKey; - bool mNormalizeRemoteIds; -}; - - -template -bool XmlOperations::compareValue( const Akonadi::Collection& col, const Akonadi::Collection& refCol, - T (P::*property)() const, - CollectionField propertyType ) -{ - if ( mCollectionFields & propertyType ) { - const bool result = compareValue( ((col).*(property))(), ((refCol).*(property))() ); - if ( !result ) { - const QMetaEnum me = metaObject()->enumerator( metaObject()->indexOfEnumerator( "CollectionField" ) ); - mErrorMsg.prepend( QString::fromLatin1( "Collection with remote id '%1' differs in property '%2':\n" ) - .arg( col.remoteId() ).arg( me.valueToKey( propertyType ) ) ); - } - return result; - } - return true; -} - -template -bool XmlOperations::compareValue( const Akonadi::Item& item, const Akonadi::Item& refItem, - T (P::*property)() const, - ItemField propertyType ) -{ - if ( mItemFields & propertyType ) { - const bool result = compareValue( ((item).*(property))(), ((refItem).*(property))() ); - if ( !result ) { - const QMetaEnum me = metaObject()->enumerator( metaObject()->indexOfEnumerator( "ItemField" ) ); - mErrorMsg.prepend( QString::fromLatin1( "Item with remote id '%1' differs in property '%2':\n" ) - .arg( item.remoteId() ).arg( me.valueToKey( propertyType ) ) ); - } - return result; - } - return true; -} - -template -bool XmlOperations::compareValue(const T& value, const T& refValue ) -{ - if ( value == refValue ) - return true; - QTextStream ts( &mErrorMsg ); - ts << " Actual: " << value << endl << " Expected: " << refValue; - return false; -} - -template -void XmlOperations::sortEntityList( QList &list, T ( P::*property)() const ) const -{ - std::sort( list.begin(), list.end(), boost::bind( property, _1 ) < boost::bind( property, _2 ) ); -} - - -#endif diff -Nru kdepim-runtime-4.14.6/.reviewboardrc kdepim-runtime-15.08.0/.reviewboardrc --- kdepim-runtime-4.14.6/.reviewboardrc 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/.reviewboardrc 2015-08-10 21:01:02.000000000 +0000 @@ -1,3 +1,5 @@ REVIEWBOARD_URL = "https://git.reviewboard.kde.org" TARGET_GROUPS = "kdepim" REPOSITORY = "kdepim-runtime" +TARGET_PEOPLE = "mlaurent" +BRANCH = "master" diff -Nru kdepim-runtime-4.14.6/tray/akonaditray.desktop kdepim-runtime-15.08.0/tray/akonaditray.desktop --- kdepim-runtime-4.14.6/tray/akonaditray.desktop 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/akonaditray.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -[Desktop Entry] -Type=Application -Categories=Qt;KDE;Utility; -Exec=akonaditray -Icon=akonaditray -Name=Akonaditray -Name[ar]=Akonaditray -Name[bs]=Akonaditray -Name[ca]=Akonaditray -Name[ca@valencia]=Akonaditray -Name[cs]=Akonaditray -Name[da]=Akonaditray -Name[de]=Akonadi-Miniprogramm -Name[el]=Akonaditray -Name[en_GB]=Akonaditray -Name[es]=Akonaditray -Name[et]=Akonaditray -Name[fi]=Akonaditray -Name[fr]=Miniature Akonadi -Name[ga]=Akonaditray -Name[gl]=Akonaditray -Name[hu]=Akonaditray -Name[ia]=Akonaditray -Name[it]=Akonaditray -Name[ja]=Akonaditray -Name[kk]=Akonaditray -Name[km]=Akonaditray -Name[ko]=Akonaditray -Name[lt]=Akondi dėklas -Name[lv]=Akonaditray -Name[nb]=Akonaditray -Name[nds]=Akonaditray -Name[nl]=Akonadi-vak -Name[nn]=Akonaditray -Name[pa]=ਅਕੌਂਡੀ-ਟਰੇ -Name[pl]=Tacka Akonadi -Name[pt]=Akonaditray -Name[pt_BR]=Akonaditray -Name[ro]=Akonaditray -Name[ru]=Akonaditray -Name[sk]=Akonaditray -Name[sl]=Akonadi v sistemski vrstici -Name[sq]=Akonaditray -Name[sr]=Аконадијева касета -Name[sr@ijekavian]=Аконадијева касета -Name[sr@ijekavianlatin]=Akonadijeva kaseta -Name[sr@latin]=Akonadijeva kaseta -Name[sv]=Akonadi-bricka -Name[tr]=Akonaditray -Name[ug]=Akonaditray -Name[uk]=Akonaditray -Name[x-test]=xxAkonaditrayxx -Name[zh_CN]=Akonadi 托盘 -Name[zh_TW]=Akonaditray -GenericName=Akonadi Tray Utility -GenericName[ar]=أداة اكوندا لصينية النظام -GenericName[bs]=Alat sistemskog tray-a Akonadi -GenericName[ca]=Utilitat de la safata per a l'Akonadi -GenericName[ca@valencia]=Utilitat de la safata per a l'Akonadi -GenericName[da]=Akonadi-værktøj til statusområdet -GenericName[de]=Akonadi für die Kontrollleiste -GenericName[el]=Εργαλείο πλαισίου συστήματος του Akonadi -GenericName[en_GB]=Akonadi Tray Utility -GenericName[es]=Utilidad de bandeja de Akonadi -GenericName[et]=Akonadi süsteemse salve tööriist -GenericName[fi]=Akonadin ilmoitusaluetyökalu -GenericName[fr]=Utilitaire miniature Akonadi -GenericName[ga]=Uirlis Tráidire Akonadi -GenericName[gl]=Utilidade da bandexa do Akonadi -GenericName[hu]=Akonadi-tálca -GenericName[ia]=Utensile de Akondaitray -GenericName[it]=Utilità del vassoio di sistema di Akonadi -GenericName[ja]=Akonadi システムトレイユーティリティ -GenericName[kk]=Akonadi сөресі -GenericName[km]=ឧបករណ៍​ប្រើប្រាស់​ថាស​ប្រព័ន្ធ​របស់ Akonadi -GenericName[ko]=Akonadi 트레이 유틸리티 -GenericName[lt]=Akonadi dėklo priemonė -GenericName[lv]=Anokadi sistēmas ikonas utilīta -GenericName[nb]=Akonadi kurvverktøy -GenericName[nds]=Akonadi-Systeemafsnittprogramm -GenericName[nl]=Akonadi-vak hulpmiddel -GenericName[nn]=Akonadi trauverktøy -GenericName[pa]=ਅਕੌਂਡੀ ਟਰੇ ਸਹੂਲਤ -GenericName[pl]=Narzędzie Akonadi na tacce systemowej -GenericName[pt]=Utilitário da Bandeja do Akonadi -GenericName[pt_BR]=Utilitário de notificação do Akonadi -GenericName[ro]=Utilitar Akonadi pentru tavă -GenericName[ru]=Поддержка системного лотка для Akonadi -GenericName[sk]=Tray utilita Akonadi -GenericName[sl]=Akonadijevo orodje v sistemski vrstici -GenericName[sr]=Аконадијева касетна алатка -GenericName[sr@ijekavian]=Аконадијева касетна алатка -GenericName[sr@ijekavianlatin]=Akonadijeva kasetna alatka -GenericName[sr@latin]=Akonadijeva kasetna alatka -GenericName[sv]=Akonadi-brickverktyg -GenericName[tr]=Akonadi Sistem Çekmecesi Aracı -GenericName[ug]=Akonadi قونداق قورالي -GenericName[uk]=Утиліта лотка Akonadi -GenericName[x-test]=xxAkonadi Tray Utilityxx -GenericName[zh_CN]=Akonadi 托盘工具 -GenericName[zh_TW]=Akonadi 系統匣工具 diff -Nru kdepim-runtime-4.14.6/tray/backupassistant.cpp kdepim-runtime-15.08.0/tray/backupassistant.cpp --- kdepim-runtime-4.14.6/tray/backupassistant.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/backupassistant.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2008 Omat Holding B.V. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "backupassistant.h" -#include "backup.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - -BackupAssistant::BackupAssistant( QWidget *parent ) : KAssistantDialog( parent ), m_selectFileButton( 0 ) -{ - m_backup = new Backup( this ); - connect( m_backup, SIGNAL(completed(bool)), SLOT(slotBackupComplete(bool)) ); - bool possible = m_backup->possible(); - - KVBox *box1 = new KVBox( this ); - QLabel *label1 = new QLabel( box1 ); - label1->setWordWrap( true ); - if ( !possible ) { - label1->setText( QLatin1Char('\n') + i18n( "The backup cannot be made. Either the mysqldump application " - "is not installed, or the bzip2 application is not found. " - "Please install those and make sure they can be found in " - "the current path. Restart this Assistant when this is fixed." ) ); - } else { - label1->setText( QLatin1Char('\n') + i18n( "Please select the file where to store " - "the backup, give it the extension .tar.bz2" ) + QLatin1String("\n\n") ); - - m_selectFileButton = new QPushButton( i18n( "&Click Here to Select the Backup Location..." ), box1 ); - connect( m_selectFileButton, SIGNAL(clicked(bool)), SLOT(slotSelectFile()) ); - - QLabel *label2 = new QLabel( QLatin1String("\n\n") + i18n( "Press 'Next' to start the Backup" ), box1 ); - label2->setWordWrap( true ); - label2->setAlignment( Qt::AlignRight ); - } - m_page1 = new KPageWidgetItem( box1, i18n( "Welcome to the Backup Assistant" ) ); - setValid( m_page1, false ); - - m_backupProgressLabel = new QLabel( this ); - m_backupProgressLabel->setWordWrap( true ); - m_page2 = new KPageWidgetItem( m_backupProgressLabel, i18n( "Making the backup" ) ); - setValid( m_page2, false ); - - addPage( m_page1 ); - addPage( m_page2 ); - showButton( KDialog::Help, false ); - - connect( this, SIGNAL(currentPageChanged(KPageWidgetItem*,KPageWidgetItem*)), - SLOT(slotPageChanged(KPageWidgetItem*,KPageWidgetItem*)) ); -} - -void BackupAssistant::slotSelectFile() -{ - QString file = QLatin1String( "akonadibackup-") + - QDateTime::currentDateTime().toString( QLatin1String("yyyyMMdd") ) + QLatin1String(".tar.bz2" ); - - // Build one special, as we want the keyword /and/ a proposed filename - KFileDialog dlg( KUrl( QLatin1String("kfiledialog://BackupDir") ), QString(), this ); - dlg.setSelection( file ); - dlg.setOperationMode( KFileDialog::Saving ); - dlg.setMode( KFile::File ); - dlg.setWindowTitle( i18n( "Save As" ) ); - dlg.exec(); - - m_filename = dlg.selectedFile(); - if ( !m_filename.isEmpty() ) { - m_selectFileButton->setText( m_filename ); - setValid( m_page1, true ); - } -} - -void BackupAssistant::slotPageChanged( KPageWidgetItem *current, KPageWidgetItem* ) -{ - if ( current != m_page2 ) - return; - - setValid( m_page2, false ); - m_backupProgressLabel->setText( i18n( "Please be patient, the backup is being created..." ) ); - m_backup->create( m_filename ); -} - -void BackupAssistant::slotBackupComplete( bool ok ) -{ - if ( ok ) { - m_backupProgressLabel->setText( i18n( "The backup has been made. Please verify manually " - "if the backup is complete. Also note that KWallet " - "stored passwords are not in the backup, you might " - "want to verify you have a backup of those elsewhere." ) ); - setValid( m_page2, true ); - } else - m_backupProgressLabel->setText( i18n( "The backup process ended unexpectedly. Please " - "report a bug, so we can find out what the cause is." ) ); -} - diff -Nru kdepim-runtime-4.14.6/tray/backupassistant.h kdepim-runtime-15.08.0/tray/backupassistant.h --- kdepim-runtime-4.14.6/tray/backupassistant.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/backupassistant.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -/* This file is part of the KDE project - - Copyright (C) 2008 Omat Holding B.V. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef BACKUPASSISTANT_H -#define BACKUPASSISTANT_H - -#include -class Backup; -class QLabel; -class QPushButton; - -/** - * Use this class to create a backup assistant. - */ -class BackupAssistant : public KAssistantDialog -{ - Q_OBJECT -public: - /** - * Constructor - */ - BackupAssistant( QWidget* ); - -private Q_SLOTS: - void slotSelectFile( ); - void slotPageChanged( KPageWidgetItem*, KPageWidgetItem* ); - void slotBackupComplete( bool ok ); - -private: - Backup *m_backup; - KPageWidgetItem *m_page1; - KPageWidgetItem *m_page2; - QLabel *m_backupProgressLabel; - QPushButton *m_selectFileButton; - QString m_filename; -}; - -#endif - diff -Nru kdepim-runtime-4.14.6/tray/backup.cpp kdepim-runtime-15.08.0/tray/backup.cpp --- kdepim-runtime-4.14.6/tray/backup.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/backup.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,163 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2008 Omat Holding B.V. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "backup.h" -#include "global.h" - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - - -using namespace Akonadi; - -/** - * Use this class to create a backup. possible() will tell you if all - * apps needed for the backup are available. Don't proceed without them. - * After that call create() to get it running. Please make sure the parameter - * has the tar.bz2 extension. - */ -Backup::Backup( QWidget *parent ) : QWidget( parent ) -{ -} - -bool Backup::possible() -{ - Tray::Global global; - QString dbDumpAppName; - if( global.dbdriver() == QLatin1String("QPSQL") ) - dbDumpAppName = QLatin1String("pg_dump"); - else if( global.dbdriver() == QLatin1String("QMYSQL") ) - dbDumpAppName = QLatin1String("mysqldump"); - else { - kError() << "Could not find an application to dump the database."; - } - - m_dbDumpApp = KStandardDirs::findExe( dbDumpAppName ); - const QString bzip2 = KStandardDirs::findExe( QLatin1String("bzip2") ); - const QString tar = KStandardDirs::findExe( QLatin1String("tar") ); - kDebug() << "m_dbDumpApp:" << m_dbDumpApp << "bzip2:" << bzip2 << "tar:" << tar; - return !m_dbDumpApp.isEmpty() && !bzip2.isEmpty() && !tar.isEmpty(); -} - -void Backup::create( const KUrl& filename ) -{ - if ( filename.isEmpty() ) { - emit completed( false ); - return; - } - - const QString sep( QDir::separator() ); - /* first create the temp folder. */ - KTempDir *tempDir = new KTempDir( KStandardDirs::locateLocal( "tmp", QLatin1String("akonadi") ) ); - tempDir->setAutoRemove( false ); - KIO::NetAccess::mkdir( QString(tempDir->name() + QLatin1String("kdeconfig")), this ); - KIO::NetAccess::mkdir( QString(tempDir->name() + QLatin1String("akonadiconfig")), this ); - KIO::NetAccess::mkdir( QString(tempDir->name() + QLatin1String("db")), this ); - - QStringList filesToBackup; - - /* Copy over the KDE config files. */ - AgentManager *manager = AgentManager::self(); - const AgentInstance::List list = manager->instances(); - foreach( const AgentInstance &agent, list ) { - const QString agentFileName = agent.identifier() + QLatin1String("rc"); - const QString configFileName = KStandardDirs::locateLocal( "config", agentFileName ); - bool exists = KIO::NetAccess::exists( configFileName, KIO::NetAccess::DestinationSide, this ); - if ( exists ) { - KIO::NetAccess::file_copy( configFileName, - QString(tempDir->name() + QLatin1String("kdeconfig") + sep + agentFileName), this ); - filesToBackup << QLatin1String("kdeconfig") + sep + agentFileName; - } - } - - /* Copy over the Akonadi config files */ - const QString config = XdgBaseDirs::findResourceDir( "config", QLatin1String("akonadi") ); - QDir dir( config ); - const QStringList configlist = dir.entryList( QDir::Files ); - foreach( const QString& item, configlist ) { - KIO::NetAccess::file_copy( QString(config + sep + item), - QString(tempDir->name() + QLatin1String("akonadiconfig") + sep + item), this ); - filesToBackup << QLatin1String("akonadiconfig/") + item; - } - - /* Dump the database */ - Tray::Global global; - KProcess *proc = new KProcess( this ); - QStringList params; - - if( global.dbdriver() == QLatin1String("QMYSQL") ) { - params << QLatin1String("--single-transaction") - << QLatin1String("--flush-logs") - << QLatin1String("--triggers") - << QLatin1String("--result-file=") + tempDir->name() + QLatin1String("db") + sep + QLatin1String("database.sql") - << global.dboptions() - << global.dbname(); - } - else if ( global.dbdriver() == QLatin1String("QPSQL") ) { - params << QLatin1String("--format=custom") - << QLatin1String("--blobs") - << QLatin1String("--file=") + tempDir->name() + QLatin1String("db") + sep + QLatin1String("database.sql") - << global.dboptions() - << global.dbname(); - } - - kDebug() << "Executing: " << m_dbDumpApp << params; - proc->setProgram( m_dbDumpApp, params ); - int result = proc->execute(); - delete proc; - if ( result != 0 ) { - kWarning() << "Executed: " << m_dbDumpApp << params << "Result: " << result; - tempDir->unlink(); - delete tempDir; - emit completed( false ); - return; - } - filesToBackup << QLatin1String("db") + sep + QLatin1String("database.sql"); - - /* Make a nice tar file. */ - proc = new KProcess( this ); - params.clear(); - params << QLatin1String("-C") << tempDir->name(); - params << QLatin1String("-cjf"); - params << filename.toLocalFile() << filesToBackup; - proc->setWorkingDirectory( tempDir->name() ); - proc->setProgram( KStandardDirs::findExe( QLatin1String("tar") ), params ); - result = proc->execute(); - delete proc; - if ( result != 0 ) { - kWarning() << "Executed: " << KStandardDirs::findExe( QLatin1String("tar") ) << params << QLatin1String("Result: ") << result; - tempDir->unlink(); - delete tempDir; - emit completed( false ); - return; - } - - tempDir->unlink(); - delete tempDir; - emit completed( true ); -} - diff -Nru kdepim-runtime-4.14.6/tray/backup.h kdepim-runtime-15.08.0/tray/backup.h --- kdepim-runtime-4.14.6/tray/backup.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/backup.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* This file is part of the KDE project - - Copyright (C) 2008 Omat Holding B.V. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef BACKUP_H -#define BACKUP_H - -#include - -class KUrl; - -class Backup : public QWidget -{ - Q_OBJECT -public: - /** - * Constructor - */ - Backup( QWidget* ); - - /** - * Checks if all the needed applications are available. - */ - bool possible(); - - /** - * Creates a backup and emits completed() when done. - * The filename should be the filename, with tar.bz2 extension. - */ - void create( const KUrl &filename ); - -private: - QString m_dbDumpApp; - -Q_SIGNALS: - void completed( bool ); -}; - -#endif // DOCK_H - diff -Nru kdepim-runtime-4.14.6/tray/CMakeLists.txt kdepim-runtime-15.08.0/tray/CMakeLists.txt --- kdepim-runtime-4.14.6/tray/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -add_definitions( -DQT_NO_CAST_FROM_ASCII ) -add_definitions( -DQT_NO_CAST_TO_ASCII ) - -include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} - ${QT_INCLUDE_DIR} ${QT_QTDBUS_INCLUDE_DIR} ) - -add_subdirectory(icons) - -set(tray_sources main.cpp dock.cpp backup.cpp backupassistant.cpp restore.cpp restoreassistant.cpp global.cpp) - -qt4_generate_dbus_interface( ${CMAKE_CURRENT_SOURCE_DIR}/dock.h - org.freedesktop.akonaditray.xml ) -qt4_add_dbus_adaptor( tray_sources org.freedesktop.akonaditray.xml dock.h Dock ) - -kde4_add_app_icon(tray_sources "${CMAKE_CURRENT_SOURCE_DIR}/icons/hi*-app-akonaditray.png") - -kde4_add_executable(akonaditray ${tray_sources}) - -target_link_libraries(akonaditray ${KDE4_KIO_LIBS} ${KDE4_KDEUI_LIBS} ${AKONADI_COMMON_LIBRARIES} ${KDEPIMLIBS_AKONADI_LIBS}) - -install(TARGETS akonaditray ${INSTALL_TARGETS_DEFAULT_ARGS}) -install(PROGRAMS akonaditray.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) diff -Nru kdepim-runtime-4.14.6/tray/dock.cpp kdepim-runtime-15.08.0/tray/dock.cpp --- kdepim-runtime-4.14.6/tray/dock.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/dock.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,211 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2008-2009 Omat Holding B.V. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "dock.h" -#include "backupassistant.h" -#include "restoreassistant.h" -#include "akonaditrayadaptor.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -using namespace Akonadi; - -Tray::Tray() : QWidget() -{ - hide(); - new Dock( this ); -} - -void Tray::setVisible( bool ) -{ - // We don't want this Widget to get visible because of a click on the tray icon. - QWidget::setVisible( false ); -} - -Dock::Dock( QWidget *parent ) - : KStatusNotifierItem( 0 ), m_explicitStart( false ) -{ - m_parentWidget = parent; - - setIconByName(QLatin1String("akonaditray")); - setCategory(SystemServices); - setStatus(Passive); - KMenu *menu = new KMenu(); - m_title = menu->addTitle( i18n( "Akonadi" ) ); - - new AkonaditrayAdaptor( this ); - QDBusConnection dbus = QDBusConnection::sessionBus(); - dbus.registerObject( QLatin1String("/Actions"), this ); - - m_stopAction = menu->addAction( i18n( "&Stop Akonadi" ), this, SLOT(slotStopAkonadi()) ); - m_startAction = menu->addAction( i18n( "S&tart Akonadi" ), this, SLOT(slotStartAkonadi()) ); - m_backupAction = menu->addAction( i18n( "Make &Backup..." ), this, SLOT(slotStartBackup()) ); - m_restoreAction = menu->addAction( i18n( "&Restore Backup..." ), this, SLOT(slotStartRestore()) ); - menu->addAction( KIcon( QLatin1String("configure") ), i18n( "&Configure..." ), this, SLOT(slotConfigure()) ); - - setContextMenu( menu ); - connect( menu, SIGNAL(aboutToShow()), SLOT(slotActivated()) ); - - connect( ServerManager::self(), SIGNAL(started()), SLOT(slotServerStarted()) ); - connect( ServerManager::self(), SIGNAL(stopped()), SLOT(slotServerStopped()) ); - - AgentManager *manager = AgentManager::self(); - connect( manager, - SIGNAL(instanceWarning(Akonadi::AgentInstance,QString)), - SLOT(slotInstanceWarning(Akonadi::AgentInstance,QString)) ); - connect( manager, - SIGNAL(instanceError(Akonadi::AgentInstance,QString)), - SLOT(slotInstanceError(Akonadi::AgentInstance,QString)) ); - - updateMenu( ServerManager::isRunning() ); -} - -Dock::~Dock() -{ -} - -void Dock::slotServerStarted() -{ - updateMenu( true ); - if ( m_explicitStart ) { - showMessage( i18n( "Akonadi available" ), - i18n( "The Akonadi server has been started and can be used now." ), QLatin1String("akonadi") ); - m_explicitStart = false; - } -} - -void Dock::slotServerStopped() -{ - updateMenu( false ); - showMessage( i18n( "Akonadi not available" ), - i18n( "The Akonadi server has been stopped, Akonadi related applications can no longer be used." ), QLatin1String("akonadi") ); -} - -void Dock::slotStopAkonadi() -{ - Akonadi::Control::stop( m_parentWidget ); -} - -void Dock::slotStartAkonadi() -{ - m_explicitStart = true; - Akonadi::Control::start( m_parentWidget ); -} - -void Dock::slotActivated() -{ - updateMenu( ServerManager::isRunning() ); -} - -void Dock::slotStartBackup() -{ - bool registered = ServerManager::isRunning(); - Q_ASSERT( registered ); - Q_UNUSED( registered ); - - QPointer backup = new BackupAssistant( m_parentWidget ); - backup->exec(); - delete backup; -} - -void Dock::slotStartRestore() -{ - bool registered = ServerManager::isRunning(); - Q_ASSERT( registered ); - Q_UNUSED( registered ); - - QPointer restore = new RestoreAssistant( m_parentWidget ); - restore->exec(); - delete restore; -} - -void Dock::updateMenu( bool registered ) -{ - if ( registered ) { - setToolTip( QLatin1String("akonadi"), i18n( "Akonadi available" ), - i18n( "The Akonadi server has been started and can be used now." ) ); - } else { - setToolTip( QLatin1String("akonadi"), i18n( "Akonadi not available" ), - i18n( "The Akonadi server has been stopped, Akonadi related applications can no longer be used." ) ); - } - - /* kdelibs... */ - QToolButton *button = static_cast(( static_cast( m_title ) )->defaultWidget() ); - QAction* action = button->defaultAction(); - action->setText( registered ? i18n( "Akonadi is running" ) : i18n( "Akonadi is not running" ) ); - button->setDefaultAction( action ); - - m_stopAction->setVisible( registered ); - m_backupAction->setEnabled( registered ); - m_restoreAction->setEnabled( registered ); - m_startAction->setVisible( !registered ); -} - -void Dock::slotInstanceWarning( const Akonadi::AgentInstance& agent, const QString& message ) -{ - QString msg = message; - if ( !agent.name().isEmpty() ) - msg = i18nc( ": ", "%1: %2", agent.name(), msg ); - infoMessage( msg, agent.name() ); -} - -void Dock::infoMessage( const QString &message, const QString &title ) -{ - KNotification::event( KNotification::Notification, title.isEmpty() ? i18n( "Akonadi message" ) : title, - message, QPixmap(), m_parentWidget ); -} - -void Dock::slotInstanceError( const Akonadi::AgentInstance& agent, const QString& message ) -{ - QString msg = message; - if ( !agent.name().isEmpty() ) - msg = i18nc( ": ", "%1: %2", agent.name(), msg ); - errorMessage( msg, agent.name() ); -} - -void Dock::errorMessage( const QString &message, const QString &title ) -{ - KNotification::event( KNotification::Error, title.isEmpty() ? i18n( "Akonadi error" ) : title, - message, DesktopIcon( QLatin1String("dialog-warning") ), m_parentWidget ); -} - -qlonglong Dock::getWinId() -{ - return ( qlonglong )m_parentWidget ->winId(); -} - -void Dock::slotConfigure() -{ - QProcess::startDetached( KStandardDirs::findExe( QLatin1String( "kcmshell4" ) ), QStringList() << QLatin1String("kcm_akonadi") ); -} - diff -Nru kdepim-runtime-4.14.6/tray/dock.h kdepim-runtime-15.08.0/tray/dock.h --- kdepim-runtime-4.14.6/tray/dock.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/dock.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -/* This file is part of the KDE project - - Copyright (C) 2008 Omat Holding B.V. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef DOCK_H -#define DOCK_H - -#include - -#include - -#include - -class QLabel; -class QAction; - -class Tray : public QWidget -{ -public: - Tray(); - -protected: - void setVisible( bool ); -}; - -class Dock : public KStatusNotifierItem -{ - Q_OBJECT - Q_CLASSINFO( "D-Bus Interface", "org.kde.akonaditray" ) - -public: - /** - * Contructor - * @param parent Parent Widget - */ - Dock( QWidget *parent ); - - /** - * Destructor - */ - ~Dock(); - -public Q_SLOTS: - void infoMessage( const QString&, const QString& = QString() ); - void errorMessage( const QString&, const QString& = QString() ); - qlonglong getWinId(); - -private Q_SLOTS: - void slotInstanceWarning( const Akonadi::AgentInstance&, const QString& ); - void slotInstanceError( const Akonadi::AgentInstance&, const QString& ); - void slotServerStarted(); - void slotServerStopped(); - void slotActivated(); - void slotStopAkonadi(); - void slotStartAkonadi(); - void slotStartBackup(); - void slotStartRestore(); - void slotConfigure(); - -private: - void updateMenu( bool ); - QWidget *m_parentWidget; - QAction *m_title; - QAction *m_stopAction; - QAction *m_startAction; - QAction *m_backupAction; - QAction *m_restoreAction; - bool m_explicitStart; -}; - -#endif // DOCK_H - diff -Nru kdepim-runtime-4.14.6/tray/global.cpp kdepim-runtime-15.08.0/tray/global.cpp --- kdepim-runtime-4.14.6/tray/global.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/global.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2008 Omat Holding B.V. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "global.h" - -#include -#include - -#include - -using namespace Akonadi; - -namespace Tray -{ - -void Global::init() -{ - const QString serverConfigFile = XdgBaseDirs::akonadiServerConfigFile( XdgBaseDirs::ReadWrite ); - QSettings settings( serverConfigFile, QSettings::IniFormat ); - - m_dbdriver = settings.value( QLatin1String("General/Driver"), QLatin1String("QMYSQL") ).toString(); - settings.beginGroup( m_dbdriver ); - - if( m_dbdriver == QLatin1String("QPSQL") ) { - m_dbname = settings.value( QLatin1String("Name"), QLatin1String("akonadi") ).toString(); - m_dboptions.append( QLatin1String("--host=") + settings.value( QLatin1String("Host"), QString() ).toString() ); - // If the server is started by the user, we don't need to know the username/password. - bool startServer = settings.value( QLatin1String("StartServer"), QLatin1String("true") ).toBool(); - if( !startServer ) { - // TODO: postgres will always ask for the user password ! implement .pgpass - m_dboptions.append( QLatin1String("--username=") + settings.value( QLatin1String("User"), QString() ).toString() ); - } - settings.endGroup(); - m_parsed = true; - } - - else if( m_dbdriver == QLatin1String("QMYSQL") ) { - m_dbname = settings.value( QLatin1String("Name"), QLatin1String("akonadi") ).toString(); - // If the server is started by the user, we don't need to know the username/password. - bool startServer = settings.value( QLatin1String("StartServer"), QString() ).toBool(); - if( !startServer ) { - m_dboptions.append( QLatin1String("--host=") + settings.value( QLatin1String("Host"), QString() ).toString() ); - m_dboptions.append( QLatin1String("--user=") + settings.value( QLatin1String("User"), QString() ).toString() ); - m_dboptions.append( QLatin1String("--password=") + settings.value( QLatin1String("Password"), QString() ).toString() ); - } - else { - const QString options = settings.value( QLatin1String("Options"), QString() ).toString(); - const QStringList list = options.split( QLatin1Char('=') ); - if( list.count() == 2 ) - m_dboptions.append( QLatin1String("--socket=") + list.at( 1 ) ); - else { - m_parsed = false; - return; - } - } - - settings.endGroup(); - m_parsed = true; - } - - else { - m_parsed = false; - } -} - -const QString Global::dbdriver() -{ - if ( !m_parsed ) - init(); - - return m_dbdriver; - -} - -const QStringList Global::dboptions() -{ - if ( !m_parsed ) - init(); - - return m_dboptions; -} - -const QString Global::dbname() -{ - if ( !m_parsed ) - init(); - - return m_dbname; -} - -} diff -Nru kdepim-runtime-4.14.6/tray/global.h kdepim-runtime-15.08.0/tray/global.h --- kdepim-runtime-4.14.6/tray/global.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/global.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -/* This file is part of the KDE project - - Copyright (C) 2006-2007 Omat Holding B.V. - Copyright (C) 2007 Frode M. Døving - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef GLOBAL_H -#define GLOBAL_H - -#include - -namespace Tray -{ - -class Global -{ -public: - Global() : m_parsed( false ) {}; - - /** - * Returns a string usable to connect to the akonadiserver. - */ - const QStringList dboptions(); - - /** - * Returns the database to connect to. - */ - const QString dbname(); - - /** - * Returns the database driver to use. - */ - const QString dbdriver(); - -private: - void init(); - - bool m_parsed; - QString m_dbdriver; - QStringList m_dboptions; - QString m_dbname; -}; - -} - -#endif diff -Nru kdepim-runtime-4.14.6/tray/icons/CMakeLists.txt kdepim-runtime-15.08.0/tray/icons/CMakeLists.txt --- kdepim-runtime-4.14.6/tray/icons/CMakeLists.txt 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/icons/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -kde4_install_icons(${ICON_INSTALL_DIR}) Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/tray/icons/hi128-app-akonaditray.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/tray/icons/hi128-app-akonaditray.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/tray/icons/hi22-app-akonaditray.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/tray/icons/hi22-app-akonaditray.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/tray/icons/hi32-app-akonaditray.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/tray/icons/hi32-app-akonaditray.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/tray/icons/hi64-app-akonaditray.png and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/tray/icons/hi64-app-akonaditray.png differ Binary files /tmp/7IyJeTLK7m/kdepim-runtime-4.14.6/tray/icons/hisc-app-akonaditray.svgz and /tmp/QoYTNVlFxo/kdepim-runtime-15.08.0/tray/icons/hisc-app-akonaditray.svgz differ diff -Nru kdepim-runtime-4.14.6/tray/main.cpp kdepim-runtime-15.08.0/tray/main.cpp --- kdepim-runtime-4.14.6/tray/main.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2008 Omat Holding B.V. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include - -#include "dock.h" - -/** - * @class AkonadiTrayApplication - * @author Tom Albers - * This class is a simple inheritance from KUniqueApplication - * the reason that it is reimplemented is that when AkonadiTray - * is launched a second time it would in the orinal implementation - * make the show(). which we do not want. This - * class misses that call. - */ -class AkonadiTrayApplication : public KUniqueApplication -{ -public: - /** - * Similar to KUniqueApplication::newInstance, only without - * the call to raise the widget when a second instance is started. - */ - int newInstance() { - return 0; - } -}; - -int main( int argc, char *argv[] ) -{ - KAboutData aboutData( "akonaditray", 0, - ki18n( "AkonadiTray" ), - "0.1", - ki18n( "System tray application to control basic Akonadi functions" ), - KAboutData::License_GPL, - ki18n( "(c) 2008 Omat Holding B.V." ), - KLocalizedString() ); - aboutData.addAuthor( ki18n( "Tom Albers" ), ki18n( "Maintainer and Author" ), - "tomalbers@kde.nl", "http://www.omat.nl" ); - aboutData.setProgramIconName( QLatin1String("akonaditray") ); - - KCmdLineArgs::init( argc, argv, &aboutData ); - - if ( !KUniqueApplication::start() ) { - fprintf( stderr, "akonaditray is already running!\n" ); - exit( 0 ); - } - - AkonadiTrayApplication a; - a.setQuitOnLastWindowClosed( false ); - - Tray tray; - - return a.exec(); -} diff -Nru kdepim-runtime-4.14.6/tray/Messages.sh kdepim-runtime-15.08.0/tray/Messages.sh --- kdepim-runtime-4.14.6/tray/Messages.sh 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/Messages.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -#!/bin/sh -$XGETTEXT *.cpp -o $podir/akonaditray.pot diff -Nru kdepim-runtime-4.14.6/tray/org.freedesktop.akonaditray.xml kdepim-runtime-15.08.0/tray/org.freedesktop.akonaditray.xml --- kdepim-runtime-4.14.6/tray/org.freedesktop.akonaditray.xml 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/org.freedesktop.akonaditray.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff -Nru kdepim-runtime-4.14.6/tray/restoreassistant.cpp kdepim-runtime-15.08.0/tray/restoreassistant.cpp --- kdepim-runtime-4.14.6/tray/restoreassistant.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/restoreassistant.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2008 Omat Holding B.V. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "restoreassistant.h" -#include "restore.h" - -#include -#include - -#include -#include -#include -#include -#include - -RestoreAssistant::RestoreAssistant( QWidget *parent ) : KAssistantDialog( parent ), m_selectFileButton(0) -{ - m_restore = new Restore( this ); - connect( m_restore, SIGNAL(completed(bool)), SLOT(slotRestoreComplete(bool)) ); - bool possible = m_restore->possible(); - - KVBox *box1 = new KVBox( this ); - QLabel *label1 = new QLabel( box1 ); - label1->setWordWrap( true ); - if ( !possible ) { - label1->setText( QLatin1Char('\n') + i18n( "The backup cannot be restored. Either the mysql application " - "is not installed, or the bzip2 application is not found. " - "Please install those and make sure they can be found in " - "the current path. Restart this Assistant when this is fixed." ) ); - } else { - label1->setText( QLatin1Char('\n') + i18n( "Please select the file to restore. Note that restoring a " - "backup will overwrite all existing data. You might want to " - "make a backup first and please consider closing all Akonadi " - "applications (but do not stop the akonadi server)." ) + QLatin1String("\n\n") ); - - m_selectFileButton = new QPushButton( i18n( "&Click Here to Select the File to Restore..." ), box1 ); - connect( m_selectFileButton, SIGNAL(clicked(bool)), SLOT(slotSelectFile()) ); - - QLabel *label2 = new QLabel( QLatin1String("\n\n") + i18n( "Press 'Next' to start the Restore" ), box1 ); - label2->setWordWrap( true ); - label2->setAlignment( Qt::AlignRight ); - } - m_page1 = new KPageWidgetItem( box1, i18n( "Welcome to the Restore Assistant" ) ); - setValid( m_page1, false ); - - m_restoreProgressLabel = new QLabel( this ); - m_restoreProgressLabel->setWordWrap( true ); - m_page2 = new KPageWidgetItem( m_restoreProgressLabel, i18n( "Restoring" ) ); - setValid( m_page2, false ); - - addPage( m_page1 ); - addPage( m_page2 ); - showButton( KDialog::Help, false ); - - connect( this, SIGNAL(currentPageChanged(KPageWidgetItem*,KPageWidgetItem*)), - SLOT(slotPageChanged(KPageWidgetItem*,KPageWidgetItem*)) ); -} - -void RestoreAssistant::slotSelectFile() -{ - m_filename = KFileDialog::getOpenFileName( KUrl( QLatin1String("kfiledialog://BackupDir") ) ); - if ( !m_filename.isEmpty() ) { - m_selectFileButton->setText( m_filename ); - setValid( m_page1, true ); - } -} - -void RestoreAssistant::slotPageChanged( KPageWidgetItem *current, KPageWidgetItem* ) -{ - if ( current != m_page2 ) - return; - - setValid( m_page2, false ); - m_restoreProgressLabel->setText( i18n( "Please be patient, the backup is being restored..." ) ); - m_restore->restore( m_filename ); -} - -void RestoreAssistant::slotRestoreComplete( bool ok ) -{ - if ( ok ) { - m_restoreProgressLabel->setText( i18n( "The backup has been restored. Note that KWallet " - "stored passwords are not restored, so applications might " - "ask for those." ) ); - setValid( m_page2, true ); - } else - m_restoreProgressLabel->setText( i18n( "The restore process ended unexpectedly. Please " - "report a bug, so we can find out what the cause is." ) ); -} - diff -Nru kdepim-runtime-4.14.6/tray/restoreassistant.h kdepim-runtime-15.08.0/tray/restoreassistant.h --- kdepim-runtime-4.14.6/tray/restoreassistant.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/restoreassistant.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -/* This file is part of the KDE project - - Copyright (C) 2008 Omat Holding B.V. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef RESTOREASSISTANT_H -#define RESTOREASSISTANT_H - -#include -class Restore; -class QLabel; -class QPushButton; - -/** - * Use this class to create a backup assistant. - */ -class RestoreAssistant : public KAssistantDialog -{ - Q_OBJECT -public: - /** - * Constructor - */ - RestoreAssistant( QWidget* ); - -private Q_SLOTS: - void slotSelectFile( ); - void slotPageChanged( KPageWidgetItem*, KPageWidgetItem* ); - void slotRestoreComplete( bool ok ); - -private: - Restore *m_restore; - KPageWidgetItem *m_page1; - KPageWidgetItem *m_page2; - QLabel *m_restoreProgressLabel; - QPushButton *m_selectFileButton; - QString m_filename; -}; - -#endif - diff -Nru kdepim-runtime-4.14.6/tray/restore.cpp kdepim-runtime-15.08.0/tray/restore.cpp --- kdepim-runtime-4.14.6/tray/restore.cpp 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/restore.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,164 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2008 Omat Holding B.V. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "restore.h" -#include "global.h" - -#include -#include -#include -#include -#include - -#include - -#include - -#include - - -using namespace Akonadi; - -/** - * Use this class to restore a backup. possible() will tell you if all - * apps needed for the restore are available. Don't proceed without them. - * After that call restore() to get it running. Please make sure the parameter - * has the tar.bz2 extension. - */ -Restore::Restore( QWidget *parent ) : QWidget( parent ) -{ -} - -bool Restore::possible() -{ - Tray::Global global; - QString dbRestoreAppName; - if( global.dbdriver() == QLatin1String("QPSQL") ) - dbRestoreAppName = QLatin1String("pg_restore"); - else if( global.dbdriver() == QLatin1String("QMYSQL") ) - dbRestoreAppName = QLatin1String("mysql"); - else { - kError() << "Could not find an application to restore the database."; - } - - m_dbRestoreApp = KStandardDirs::findExe( dbRestoreAppName ); - const QString bzip2 = KStandardDirs::findExe( QLatin1String("bzip2") ); - const QString tar = KStandardDirs::findExe( QLatin1String("tar") ); - kDebug() << "m_dbRestoreApp:" << m_dbRestoreApp << "bzip2:" << bzip2 << "tar:" << tar; - return !m_dbRestoreApp.isEmpty() && !bzip2.isEmpty() && !tar.isEmpty(); -} - -void Restore::restore( const KUrl& filename ) -{ - if ( filename.isEmpty() ) { - emit completed( false ); - return; - } - - const QString sep = QDir::separator(); - - /* first create the temp folder. */ - KTempDir *tempDir = new KTempDir( KStandardDirs::locateLocal( "tmp", QLatin1String("akonadi") ) ); - tempDir->setAutoRemove( false ); - kDebug() << "Temp dir: "<< tempDir->name(); - - /* Extract the nice tar file. */ - KProcess *proc = new KProcess( this ); - QStringList params; - params << QLatin1String("-C") << tempDir->name(); - params << QLatin1String("-xjf"); - params << filename.toLocalFile(); - proc->setWorkingDirectory( tempDir->name() ); - proc->setProgram( KStandardDirs::findExe( QLatin1String("tar") ), params ); - int result = proc->execute(); - delete proc; - if ( result != 0 ) { - kWarning() << "Executed:" << KStandardDirs::findExe( QLatin1String("tar") ) << params << " Result: " << result; - tempDir->unlink(); - delete tempDir; - emit completed( false ); - return; - } - - /* Copy over the KDE configuration files. */ - QDir dir( tempDir->name() + QLatin1String("kdeconfig") + sep ); - dir.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks ); - QFileInfoList list = dir.entryInfoList(); - const int numberOfElement = list.size(); - for ( int i = 0; i < numberOfElement; ++i ) { - QFileInfo fileInfo = list.at( i ); - const QString source = fileInfo.absoluteFilePath(); - const QString dest = KStandardDirs::locateLocal( "config", fileInfo.fileName() ); - - kDebug() << "Restoring: " << source << "to:" << dest; - KIO::NetAccess::file_copy( source, dest, this ); - } - - /* Copy over the Akonadi configuration files. */ - const QString akonadiconfigfolder = XdgBaseDirs::findResourceDir( "config", QLatin1String("akonadi") ); - dir.setPath( tempDir->name() + QLatin1String("akonadiconfig") + sep ); - dir.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks ); - list = dir.entryInfoList(); - const int sizeOfList = list.size(); - for ( int i = 0; i < sizeOfList; ++i ) { - QFileInfo fileInfo = list.at( i ); - const QString source = fileInfo.absoluteFilePath(); - const QString dest = akonadiconfigfolder + sep + fileInfo.fileName(); - - kDebug() << "Restoring: " << source << "to:" << dest; - KIO::NetAccess::file_copy( source, dest, this ); - } - - /* Restore the database */ - Tray::Global global; - proc = new KProcess( this ); - params.clear(); - - if( global.dbdriver() == QLatin1String("QPSQL") ) { - params << global.dboptions() - << QLatin1String("--dbname=") + global.dbname() - << QLatin1String("--format=custom") - << QLatin1String("--clean") - << QLatin1String("--no-owner") - << QLatin1String("--no-privileges") - << tempDir->name() + QLatin1String("db") + sep + QLatin1String("database.sql"); - } - else if (global.dbdriver() == QLatin1String("QMYSQL") ) { - params << global.dboptions() - << QLatin1String("--database=") + global.dbname(); - } - - kDebug() << "Executing:" << m_dbRestoreApp << params; - ; - proc->setProgram( KStandardDirs::findExe( m_dbRestoreApp ), params ); - proc->setStandardInputFile(tempDir->name() + QLatin1String("db") + sep + QLatin1String("database.sql")); - result = proc->execute(); - delete proc; - if ( result != 0 ) { - kWarning() << "Executed:" << m_dbRestoreApp << params << " Result: " << result; - tempDir->unlink(); - delete tempDir; - emit completed( false ); - return; - } - - tempDir->unlink(); - delete tempDir; - emit completed( true ); -} - diff -Nru kdepim-runtime-4.14.6/tray/restore.h kdepim-runtime-15.08.0/tray/restore.h --- kdepim-runtime-4.14.6/tray/restore.h 2015-02-27 00:16:51.000000000 +0000 +++ kdepim-runtime-15.08.0/tray/restore.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* This file is part of the KDE project - - Copyright (C) 2008 Omat Holding B.V. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - - -#ifndef RESTORE_H -#define RESTORE_H - -#include - -class KUrl; - -class Restore : public QWidget -{ - Q_OBJECT -public: - /** - * Constructor - */ - Restore( QWidget* ); - - /** - * Checks if all the needed applications are available. - */ - bool possible(); - - /** - * Restores a backup and emits completed() when done. - * The filename should be the filename, with tar.bz2 extension. - */ - void restore( const KUrl &filename ); - -private: - QString m_dbRestoreApp; - -Q_SIGNALS: - void completed( bool ); -}; - -#endif // DOCK_H -