diff --git a/libksieve/ksieveui/CMakeLists.txt b/libksieve/ksieveui/CMakeLists.txt --- a/libksieve/ksieveui/CMakeLists.txt +++ b/libksieve/ksieveui/CMakeLists.txt @@ -153,6 +153,7 @@ widgets/managesievewidget.cpp debug/sievedebugdialog.cpp util/util.cpp + managescriptsjob/checkkep14supportjob.cpp managescriptsjob/generateglobalscriptjob.cpp managescriptsjob/parseuserscriptjob.cpp templates/sievetemplatewidget.cpp diff --git a/libksieve/ksieveui/managescriptsjob/parseuserscriptjob.h b/libksieve/ksieveui/managescriptsjob/checkkep14supportjob.h copy from libksieve/ksieveui/managescriptsjob/parseuserscriptjob.h copy to libksieve/ksieveui/managescriptsjob/checkkep14supportjob.h --- a/libksieve/ksieveui/managescriptsjob/parseuserscriptjob.h +++ b/libksieve/ksieveui/managescriptsjob/checkkep14supportjob.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2013, 2014 Montel Laurent + Copyright (c) 2015 Sandro Knauß 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 @@ -15,45 +15,51 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef PARSEUSERSCRIPTJOB_H -#define PARSEUSERSCRIPTJOB_H +#ifndef CHECKKEP14SUPPORTJOB_H +#define CHECKKEP14SUPPORTJOB_H #include -#include +#include + #include "ksieveui_export.h" -class QDomDocument; -class QDomElement; + +#include + namespace KManageSieve { class SieveJob; } namespace KSieveUi { -class KSIEVEUI_EXPORT ParseUserScriptJob : public QObject +class KSIEVEUI_EXPORT CheckKep14SupportJob : public QObject { Q_OBJECT public: - explicit ParseUserScriptJob(QObject *parent=0); - ~ParseUserScriptJob(); + explicit CheckKep14SupportJob(QObject *parent=0); + ~CheckKep14SupportJob(); void start(); - void scriptUrl(const KUrl &url); - static QStringList parsescript(const QString &script, bool &result); - + void setServerUrl(const KUrl &url); + void setServerName(const QString &name); + QString serverName(); -private Q_SLOTS: - void slotGetResult( KManageSieve::SieveJob *, bool, const QString &, bool ); + QStringList availableScripts(); + bool hasKep14Support(); + KUrl serverUrl(); Q_SIGNALS: - void success(const QStringList &activeScriptList); - void error(const QString &msgError); + void result(CheckKep14SupportJob*, bool); private: - static QString loadInclude(const QDomElement &element); - static QStringList extractActiveScript(const QDomDocument &doc); - KUrl mCurrentUrl; + KUrl mUrl; KManageSieve::SieveJob *mSieveJob; + QStringList mAvailableScripts; + bool mKep14Support; + QString mServerName; + +private slots: + void slotCheckKep14Support(KManageSieve::SieveJob *job, bool success, const QStringList &availableScripts, const QString &activeScript); }; } -#endif // PARSEUSERSCRIPTJOB_H +#endif // CHECKKEP14SUPPORTJOB_H diff --git a/libksieve/ksieveui/managescriptsjob/checkkep14supportjob.cpp b/libksieve/ksieveui/managescriptsjob/checkkep14supportjob.cpp new file mode 100644 --- /dev/null +++ b/libksieve/ksieveui/managescriptsjob/checkkep14supportjob.cpp @@ -0,0 +1,93 @@ +/* + Copyright (c) 2015 Sandro Knauß + + 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 "checkkep14supportjob.h" +#include +#include + +#include +#include +#include + +using namespace KSieveUi; + +CheckKep14SupportJob::CheckKep14SupportJob(QObject *parent) + : QObject(parent), + mSieveJob(0) +{ + +} + +CheckKep14SupportJob::~CheckKep14SupportJob() +{ + +} + +void CheckKep14SupportJob::start() +{ + if (mUrl.isEmpty()) { + qDebug() << " server url is empty"; + deleteLater(); + return; + } + mSieveJob = KManageSieve::SieveJob::list(mUrl); + connect(mSieveJob, SIGNAL(gotList(KManageSieve::SieveJob*,bool,QStringList,QString)), + this, SLOT(slotCheckKep14Support(KManageSieve::SieveJob*,bool,QStringList,QString))); +} + +void CheckKep14SupportJob::setServerUrl(const KUrl &url) +{ + mUrl = url; +} + +KUrl CheckKep14SupportJob::serverUrl() +{ + return mUrl; +} + +void CheckKep14SupportJob::setServerName(const QString &name) +{ + mServerName = name; +} + +QString CheckKep14SupportJob::serverName() +{ + return mServerName; +} + + +QStringList CheckKep14SupportJob::availableScripts() +{ + return mAvailableScripts; +} + +bool CheckKep14SupportJob::hasKep14Support() +{ + return mKep14Support; +} + +void CheckKep14SupportJob::slotCheckKep14Support(KManageSieve::SieveJob *job, bool success, const QStringList &availableScripts, const QString &activeScript) +{ + if (!success) { + emit result(this, false); + return; + } + + mKep14Support = Util::hasKep14Support(job->sieveCapabilities(), availableScripts, activeScript); + mAvailableScripts = availableScripts; + emit result(this, true); +} diff --git a/libksieve/ksieveui/managescriptsjob/generateglobalscriptjob.cpp b/libksieve/ksieveui/managescriptsjob/generateglobalscriptjob.cpp --- a/libksieve/ksieveui/managescriptsjob/generateglobalscriptjob.cpp +++ b/libksieve/ksieveui/managescriptsjob/generateglobalscriptjob.cpp @@ -49,7 +49,7 @@ Q_EMIT error(i18n("Path is not specified.")); return; } - writeMasterScript(); + writeUserScript(); } void GenerateGlobalScriptJob::writeMasterScript() @@ -107,7 +107,7 @@ "require [\"include\"];\n"); Q_FOREACH (const QString &activeScript, mListUserActiveScripts) { - userScript += QString::fromLatin1("\ninclude :personal \"%1\"").arg(activeScript); + userScript += QString::fromLatin1("\ninclude :personal \"%1\";").arg(activeScript); } KUrl url(mCurrentUrl); diff --git a/libksieve/ksieveui/managescriptsjob/parseuserscriptjob.h b/libksieve/ksieveui/managescriptsjob/parseuserscriptjob.h --- a/libksieve/ksieveui/managescriptsjob/parseuserscriptjob.h +++ b/libksieve/ksieveui/managescriptsjob/parseuserscriptjob.h @@ -19,6 +19,7 @@ #define PARSEUSERSCRIPTJOB_H #include +#include #include #include "ksieveui_export.h" class QDomDocument; @@ -32,27 +33,32 @@ { Q_OBJECT public: - explicit ParseUserScriptJob(QObject *parent=0); + explicit ParseUserScriptJob(const KUrl &url,QObject *parent=0); ~ParseUserScriptJob(); void start(); - void scriptUrl(const KUrl &url); - static QStringList parsescript(const QString &script, bool &result); + KUrl scriptUrl() const; + QStringList activeScriptList() const; + QString error() const; private Q_SLOTS: void slotGetResult( KManageSieve::SieveJob *, bool, const QString &, bool ); Q_SIGNALS: - void success(const QStringList &activeScriptList); - void error(const QString &msgError); + void finished(ParseUserScriptJob* job); private: + void emitSuccess(const QStringList &activeScriptList); + void emitError(const QString &msgError); static QString loadInclude(const QDomElement &element); static QStringList extractActiveScript(const QDomDocument &doc); + static QStringList parsescript(const QString &script, bool &result); KUrl mCurrentUrl; KManageSieve::SieveJob *mSieveJob; + QStringList mActiveScripts; + QString mError; }; } diff --git a/libksieve/ksieveui/managescriptsjob/parseuserscriptjob.cpp b/libksieve/ksieveui/managescriptsjob/parseuserscriptjob.cpp --- a/libksieve/ksieveui/managescriptsjob/parseuserscriptjob.cpp +++ b/libksieve/ksieveui/managescriptsjob/parseuserscriptjob.cpp @@ -24,9 +24,10 @@ using namespace KSieveUi; -ParseUserScriptJob::ParseUserScriptJob(QObject *parent) +ParseUserScriptJob::ParseUserScriptJob(const KUrl &url, QObject *parent) : QObject(parent), mSieveJob(0) + , mCurrentUrl(url) { } @@ -37,19 +38,21 @@ mSieveJob = 0; } -void ParseUserScriptJob::scriptUrl(const KUrl &url) +KUrl ParseUserScriptJob::scriptUrl() const { - mCurrentUrl = url; + return mCurrentUrl; } void ParseUserScriptJob::start() { if (mCurrentUrl.isEmpty()) { - Q_EMIT error(i18n("Path is not specified.")); + emitError(i18n("Path is not specified.")); return; } if ( mSieveJob ) mSieveJob->kill(); + mActiveScripts = QStringList(); + mError = QString(); mSieveJob = KManageSieve::SieveJob::get( mCurrentUrl ); connect( mSieveJob, SIGNAL(result(KManageSieve::SieveJob*,bool,QString,bool)), this, SLOT(slotGetResult(KManageSieve::SieveJob*,bool,QString,bool)) ); @@ -59,17 +62,30 @@ { mSieveJob = 0; if (script.isEmpty()) { - Q_EMIT error(i18n("Script is empty.")); + emitError(i18n("Script is empty.")); return; } bool result; const QStringList lst = parsescript(script, result); if (result) - Q_EMIT success(lst); + emitSuccess(lst); else - Q_EMIT error(i18n("Script parsing error")); + emitError(i18n("Script parsing error")); } +void ParseUserScriptJob::emitError(const QString &msgError) +{ + mError = msgError; + emit finished(this); +} + +void ParseUserScriptJob::emitSuccess(const QStringList &activeScriptList) +{ + mActiveScripts = activeScriptList; + emit finished(this); +} + + QStringList ParseUserScriptJob::parsescript(const QString &script, bool &result) { QStringList lst; @@ -80,6 +96,16 @@ return lst; } +QStringList ParseUserScriptJob::activeScriptList() const +{ + return mActiveScripts; +} + +QString ParseUserScriptJob::error() const +{ + return mError; +} + QStringList ParseUserScriptJob::extractActiveScript(const QDomDocument &doc) { QStringList lstScript; diff --git a/libksieve/ksieveui/util/util.h b/libksieve/ksieveui/util/util.h --- a/libksieve/ksieveui/util/util.h +++ b/libksieve/ksieveui/util/util.h @@ -45,6 +45,7 @@ class KUrl; class QString; +class QStringList; namespace KSieveUi { @@ -75,6 +76,17 @@ * be available at all. */ KSIEVEUI_EXPORT bool allowOutOfOfficeSettings(); + + /** + * Checks if a server has KEP:14 support + */ + bool hasKep14Support(const QStringList &sieveCapabilities, const QStringList &availableScripts, const QString &activeScript); + + /** + * Is the given scriptName a protected KEP:14 name, that a normal user should not touch directly. + * it tests against MASTER, USER and MANAGEMENT script + */ + bool isKep14ProtectedName(const QString &scriptName); } } diff --git a/libksieve/ksieveui/util/util.cpp b/libksieve/ksieveui/util/util.cpp --- a/libksieve/ksieveui/util/util.cpp +++ b/libksieve/ksieveui/util/util.cpp @@ -166,3 +166,45 @@ { return VacationSettings::self()->allowOutOfOfficeSettings(); } + +bool Util::hasKep14Support(const QStringList &sieveCapabilities, const QStringList &availableScripts, const QString &activeScript) +{ + const bool hasIncludeCapability = sieveCapabilities.contains(QLatin1String("include")); + if (!hasIncludeCapability) { + return false; + } + + bool masterIsActive = !activeScript.isEmpty(); + if (masterIsActive) { + const QString scriptName = activeScript.split(QLatin1Char('.')).first().toLower(); + masterIsActive = (scriptName == QLatin1String("master") || scriptName == QLatin1String("user")); + } + if (!masterIsActive) { + return false; + } + + bool hasUserScript = false; + foreach(const QString &script, availableScripts) { + if (script.isEmpty()) { + continue; + } + const QString name = script.split(QLatin1Char('.')).first().toLower(); + if (name == QLatin1String("user")) { + hasUserScript = true; + break; + } + } + + return hasIncludeCapability && masterIsActive && hasUserScript; +} + +bool Util::isKep14ProtectedName(const QString &name) +{ + QString n = name.split(QLatin1Char('.')).first().toLower(); + if (n == QLatin1String("master") || + n == QLatin1String("user") || + n == QLatin1String("management")) { + return true; + } + return false; +} \ No newline at end of file diff --git a/libksieve/ksieveui/vacation/multiimapvacationdialog.h b/libksieve/ksieveui/vacation/multiimapvacationdialog.h --- a/libksieve/ksieveui/vacation/multiimapvacationdialog.h +++ b/libksieve/ksieveui/vacation/multiimapvacationdialog.h @@ -26,11 +26,12 @@ class QStackedWidget; namespace KSieveUi { class VacationCreateScriptJob; +class MultiImapVacationManager; class KSIEVEUI_EXPORT MultiImapVacationDialog : public KDialog { Q_OBJECT public: - explicit MultiImapVacationDialog(QWidget *parent=0); + explicit MultiImapVacationDialog(MultiImapVacationManager *manager, QWidget *parent=0); ~MultiImapVacationDialog(); QList listCreateJob() const; @@ -49,6 +50,7 @@ QList mListCreateJob; KTabWidget *mTabWidget; QStackedWidget *mStackedWidget; + MultiImapVacationManager* mVacationManager; }; } diff --git a/libksieve/ksieveui/vacation/multiimapvacationdialog.cpp b/libksieve/ksieveui/vacation/multiimapvacationdialog.cpp --- a/libksieve/ksieveui/vacation/multiimapvacationdialog.cpp +++ b/libksieve/ksieveui/vacation/multiimapvacationdialog.cpp @@ -18,6 +18,7 @@ #include "multiimapvacationdialog.h" #include "vacationpagewidget.h" +#include "multiimapvacationmanager.h" #include "ksieveui/util/util.h" #include @@ -34,8 +35,9 @@ using namespace KSieveUi; -MultiImapVacationDialog::MultiImapVacationDialog(QWidget *parent) +MultiImapVacationDialog::MultiImapVacationDialog(MultiImapVacationManager *manager, QWidget *parent) : KDialog(parent) + , mVacationManager(manager) { setCaption( i18n("Configure \"Out of Office\" Replies") ); @@ -87,17 +89,12 @@ void MultiImapVacationDialog::init() { bool foundOneImap = false; - const Akonadi::AgentInstance::List instances = KSieveUi::Util::imapAgentInstances(); - foreach ( const Akonadi::AgentInstance &instance, instances ) { - if ( instance.status() == Akonadi::AgentInstance::Broken ) - continue; - - const KUrl url = KSieveUi::Util::findSieveUrlForAccount( instance.identifier() ); - if ( !url.isEmpty() ) { - const QString serverName = instance.name(); - createPage(serverName, url); - foundOneImap = true; - } + + QMap list = mVacationManager->serverList(); + foreach (const QString &serverName, list.keys()) { + const KUrl url = list.value(serverName); + createPage(serverName, url); + foundOneImap = true; } if (foundOneImap) { setButtons( Ok | Cancel | Default ); @@ -115,6 +112,7 @@ VacationPageWidget *page = new VacationPageWidget; page->setServerUrl(url); page->setServerName(serverName); + page->setVacationManager(mVacationManager); mTabWidget->addTab(page,serverName); } diff --git a/libksieve/ksieveui/vacation/multiimapvacationmanager.h b/libksieve/ksieveui/vacation/multiimapvacationmanager.h --- a/libksieve/ksieveui/vacation/multiimapvacationmanager.h +++ b/libksieve/ksieveui/vacation/multiimapvacationmanager.h @@ -19,10 +19,15 @@ #define MULTIIMAPVACATIONMANAGER_H #include +#include #include "ksieveui_export.h" +class KUrl; + namespace KSieveUi { +class CheckKep14SupportJob; +class VacationCheckJob; class KSIEVEUI_EXPORT MultiImapVacationManager : public QObject { Q_OBJECT @@ -31,18 +36,22 @@ ~MultiImapVacationManager(); void checkVacation(); + QMap serverList(); + void checkVacation(const QString &serverName, const KUrl &url); Q_SIGNALS: void scriptActive(bool active, const QString &serverName); - void requestEditVacation(); + void scriptAvailable(const QString &serverName, const QStringList &sieveCapabilities, const QString &scriptName, const QString &script, bool active); private slots: - void slotScriptActive(bool active, const QString &serverName); + void slotScriptActive(VacationCheckJob* job, QString scriptName, bool active); + void slotCheckKep14Ended(CheckKep14SupportJob *job, bool success); private: int mNumberOfJobs; - bool mQuestionAsked; bool mCheckInProgress; + + QMap mKep14Support; //if the server has KEP:14 support }; } #endif // MULTIIMAPVACATIONMANAGER_H diff --git a/libksieve/ksieveui/vacation/multiimapvacationmanager.cpp b/libksieve/ksieveui/vacation/multiimapvacationmanager.cpp --- a/libksieve/ksieveui/vacation/multiimapvacationmanager.cpp +++ b/libksieve/ksieveui/vacation/multiimapvacationmanager.cpp @@ -18,6 +18,9 @@ #include "multiimapvacationmanager.h" #include "vacationcheckjob.h" #include "util/util.h" +#include +#include +#include #include @@ -28,7 +31,6 @@ MultiImapVacationManager::MultiImapVacationManager(QObject *parent) : QObject(parent), mNumberOfJobs(0), - mQuestionAsked(false), mCheckInProgress(false) { } @@ -38,14 +40,9 @@ } -void MultiImapVacationManager::checkVacation() +QMap MultiImapVacationManager::serverList() { - if (mCheckInProgress) - return; - mNumberOfJobs = 0; - mCheckInProgress = true; - mQuestionAsked = false; - + QMap list; const Akonadi::AgentInstance::List instances = KSieveUi::Util::imapAgentInstances(); foreach ( const Akonadi::AgentInstance &instance, instances ) { if ( instance.status() == Akonadi::AgentInstance::Broken ) @@ -53,32 +50,74 @@ const KUrl url = KSieveUi::Util::findSieveUrlForAccount( instance.identifier() ); if ( !url.isEmpty() ) { - const QString serverName = instance.name(); - ++mNumberOfJobs; - VacationCheckJob *job = new VacationCheckJob(url, serverName, this); - connect(job, SIGNAL(scriptActive(bool,QString)), this, SLOT(slotScriptActive(bool,QString))); + list.insert(instance.name(), url); } } + return list; } -void MultiImapVacationManager::slotScriptActive(bool active, const QString &serverName) +void MultiImapVacationManager::checkVacation(const QString &serverName, const KUrl &url) { - --mNumberOfJobs; - Q_EMIT scriptActive(active, serverName); - - if (active) { - if (!mQuestionAsked) { - mQuestionAsked = true; - if ( KMessageBox::questionYesNo( 0, i18n( "There is still an active out-of-office reply configured.\n" - "Do you want to edit it?"), i18n("Out-of-office reply still active"), - KGuiItem( i18n( "Edit"), QLatin1String("document-properties") ), - KGuiItem( i18n("Ignore"), QLatin1String("dialog-cancel") ) ) - == KMessageBox::Yes ) { - Q_EMIT requestEditVacation(); - } - } + ++mNumberOfJobs; + if (!mKep14Support.contains(serverName)) { + CheckKep14SupportJob *checkKep14Job = new CheckKep14SupportJob(this); + checkKep14Job->setProperty(QLatin1String("triggerScript").latin1(), true); + checkKep14Job->setServerName(serverName); + checkKep14Job->setServerUrl(url); + connect(checkKep14Job, SIGNAL(result(CheckKep14SupportJob*,bool)), SLOT(slotCheckKep14Ended(CheckKep14SupportJob*,bool))); + checkKep14Job->start(); + } + + VacationCheckJob *job = new VacationCheckJob(url, serverName, this); + job->setKep14Support(mKep14Support[serverName]); + connect(job, SIGNAL(scriptActive(VacationCheckJob*,QString,bool)), this, SLOT(slotScriptActive(VacationCheckJob*,QString,bool))); + job->start(); +} + +void MultiImapVacationManager::checkVacation() +{ + if (mCheckInProgress) + return; + mNumberOfJobs = 0; + mCheckInProgress = true; + + QMap list = serverList(); + foreach ( const QString &serverName, list.keys() ) { + const KUrl url = list.value(serverName); + checkVacation(serverName, url); } +} - if (mNumberOfJobs == 0) +void MultiImapVacationManager::slotScriptActive(VacationCheckJob* job, QString scriptName, bool active) +{ + --mNumberOfJobs; + if (mNumberOfJobs == 0) { mCheckInProgress = false; + } + + job->deleteLater(); + + if (job->noScriptFound()) { + emit scriptActive(false, job->serverName()); + return; + } + emit scriptActive(active, job->serverName()); + emit scriptAvailable(job->serverName(), job->sieveCapabilities(), scriptName, job->script(), active); +} + +void MultiImapVacationManager::slotCheckKep14Ended(CheckKep14SupportJob *job, bool success) +{ + job->deleteLater(); + if (!success) { + --mNumberOfJobs; + return; + } + + mKep14Support.insert(job->serverName(), job->hasKep14Support()); + + VacationCheckJob *checkJob = new VacationCheckJob(job->serverUrl(), job->serverName(), this); + checkJob->setKep14Support(job->hasKep14Support()); + connect(checkJob, SIGNAL(scriptActive(VacationCheckJob*,QString,bool)), + SLOT(slotScriptActive(VacationCheckJob*,QString,bool))); + checkJob->start(); } diff --git a/libksieve/ksieveui/vacation/tests/main.cpp b/libksieve/ksieveui/vacation/tests/main.cpp --- a/libksieve/ksieveui/vacation/tests/main.cpp +++ b/libksieve/ksieveui/vacation/tests/main.cpp @@ -20,6 +20,7 @@ #include #include "vacation/multiimapvacationdialog.h" +#include #include @@ -30,7 +31,8 @@ KApplication app; app.setQuitOnLastWindowClosed( false ); - KSieveUi::MultiImapVacationDialog dlg; + KSieveUi::MultiImapVacationManager manager; + KSieveUi::MultiImapVacationDialog dlg(&manager); dlg.show(); app.exec(); diff --git a/libksieve/ksieveui/vacation/vacationcheckjob.h b/libksieve/ksieveui/vacation/vacationcheckjob.h --- a/libksieve/ksieveui/vacation/vacationcheckjob.h +++ b/libksieve/ksieveui/vacation/vacationcheckjob.h @@ -19,6 +19,7 @@ #define VACATIONCHECKJOB_H #include +#include #include namespace KManageSieve { @@ -26,23 +27,45 @@ } namespace KSieveUi { +class ParseUserScriptJob; class VacationCheckJob : public QObject { Q_OBJECT public: explicit VacationCheckJob(const KUrl &url, const QString &serverName, QObject *parent=0); ~VacationCheckJob(); + void setKep14Support(bool kep14Support); + void start(); + bool noScriptFound(); + QString script(); + QStringList sieveCapabilities(); + QString serverName(); Q_SIGNALS: - void scriptActive(bool active, const QString &serverName); + void scriptActive(VacationCheckJob* job, const QString &sscriptName, bool active); private slots: void slotGetResult(KManageSieve::SieveJob *job, bool success, const QString &script, bool active); + void slotGotActiveScripts(ParseUserScriptJob *job); + void slotGotList(KManageSieve::SieveJob *job, bool success, const QStringList &availableScripts, const QString &activeScript); + void emitError(const QString &errorMessage); + void searchVacationScript(); + void getNextScript(); + bool isVacationScipt(const QString &script) const; + bool isLastScript() const; private: QString mServerName; KUrl mUrl; KManageSieve::SieveJob * mSieveJob; + ParseUserScriptJob *mParseJob; + bool mKep14Support; + QStringList mAvailableScripts; + QStringList mActiveScripts; + int mScriptPos; + bool mNoScriptFound; + QString mScript; + QStringList mSieveCapabilities; }; } diff --git a/libksieve/ksieveui/vacation/vacationcheckjob.cpp b/libksieve/ksieveui/vacation/vacationcheckjob.cpp --- a/libksieve/ksieveui/vacation/vacationcheckjob.cpp +++ b/libksieve/ksieveui/vacation/vacationcheckjob.cpp @@ -16,19 +16,24 @@ */ #include "vacationcheckjob.h" +#include "vacationutils.h" +#include +#include #include +#include + using namespace KSieveUi; VacationCheckJob::VacationCheckJob(const KUrl &url, const QString &serverName, QObject *parent) : QObject(parent), mServerName(serverName), mUrl(url) + , mKep14Support(false) + , mSieveJob(0) + , mParseJob(0) + , mNoScriptFound(0) { - mSieveJob = KManageSieve::SieveJob::get( mUrl ); - mSieveJob->setInteractive( false ); - connect( mSieveJob, SIGNAL(gotScript(KManageSieve::SieveJob*,bool,QString,bool)), - SLOT(slotGetResult(KManageSieve::SieveJob*,bool,QString,bool)) ); } VacationCheckJob::~VacationCheckJob() @@ -38,10 +43,154 @@ mSieveJob = 0; } -void VacationCheckJob::slotGetResult(KManageSieve::SieveJob */*job*/, bool success, const QString &/*script*/, bool active) +void VacationCheckJob::setKep14Support(bool kep14Support) +{ + mKep14Support = kep14Support; +} + +void VacationCheckJob::start() +{ + if (mKep14Support) { + KUrl url = mUrl; + url.setFileName(QLatin1String("USER")); + mParseJob = new ParseUserScriptJob(url); + connect(mParseJob, SIGNAL(finished(ParseUserScriptJob*)), SLOT(slotGotActiveScripts(ParseUserScriptJob*))); + mParseJob->start(); + mSieveJob = KManageSieve::SieveJob::list(url); + connect(mSieveJob, SIGNAL(gotList(KManageSieve::SieveJob*,bool,QStringList,QString)), + this, SLOT(slotGotList(KManageSieve::SieveJob*,bool,QStringList,QString))); + } else { + mSieveJob = KManageSieve::SieveJob::get(mUrl); + mSieveJob->setInteractive(false); + connect(mSieveJob, SIGNAL(gotScript(KManageSieve::SieveJob*,bool,QString,bool)), + SLOT(slotGetResult(KManageSieve::SieveJob*,bool,QString,bool))); + } +} + +void VacationCheckJob::slotGetResult(KManageSieve::SieveJob */*job*/, bool success, const QString &script, bool active) +{ + mScript = script; + mSieveCapabilities = mSieveJob->sieveCapabilities(); + mSieveJob = 0; + + if (mKep14Support) { + if (isVacationScipt(script)) { + const QString &scriptName = mAvailableScripts[mScriptPos-1]; + emit scriptActive(this, scriptName, mActiveScripts.contains(scriptName)); + kDebug() << "vacation script found :)"; + } else if (isLastScript()) { + mNoScriptFound = true; + emit scriptActive(this, QString(), false); + kDebug() << "no vacation script found :("; + } else { + getNextScript(); + } + } else { + if ( !success ) + active = false; // default to inactive + mNoScriptFound = true; + emit scriptActive(this, mUrl.fileName(), active); + } +} + +void VacationCheckJob::slotGotActiveScripts(ParseUserScriptJob *job) +{ + mParseJob = 0; + if (!job->error().isEmpty()) { + emitError(QLatin1String("ParseUserScriptJob failed:")+job->error()); + return; + } + mActiveScripts = job->activeScriptList(); + + if (!mSieveJob) { + searchVacationScript(); + } +} + +void VacationCheckJob::slotGotList(KManageSieve::SieveJob *job, bool success, const QStringList &availableScripts, const QString &activeScript) { mSieveJob = 0; - if ( !success ) - active = false; // default to inactive - emit scriptActive( active, mServerName ); + if (!success) { + emitError(QLatin1String("SieveJob list failed.")); + return; + } + + mAvailableScripts = availableScripts; + + if (!mParseJob) { + searchVacationScript(); + } +} + +void VacationCheckJob::emitError(const QString &errorMessage) +{ + qWarning() << errorMessage; + //TODO: emit error +} + +void VacationCheckJob::searchVacationScript() +{ + QStringList scriptList = mActiveScripts; + + // Reorder script list + foreach(const QString &script, mAvailableScripts) { + if (!scriptList.contains(script)) { + scriptList.append(script); + } + } + + mAvailableScripts = scriptList; + mScriptPos = 0; + getNextScript(); +} + +void VacationCheckJob::getNextScript() +{ + if (isLastScript()) { + //TODO: no script found + mNoScriptFound = true; + emit scriptActive(this, QString(), false); + kDebug() << "no vacation script found :("; + } + KUrl url = mUrl; + url.setFileName(mAvailableScripts[mScriptPos]); + mScriptPos += 1; + if (Util::isKep14ProtectedName(url.fileName())) { + getNextScript(); + } + mSieveJob = KManageSieve::SieveJob::get(url); + mSieveJob->setInteractive(false); + connect(mSieveJob, SIGNAL(gotScript(KManageSieve::SieveJob*,bool,QString,bool)), + SLOT(slotGetResult(KManageSieve::SieveJob*,bool,QString,bool))); +} + +bool VacationCheckJob::isLastScript() const +{ + return mScriptPos >= mAvailableScripts.count(); +} + +bool VacationCheckJob::isVacationScipt(const QString &script) const +{ + return KSieveUi::VacationUtils::foundVacationScript(script); +} + +bool VacationCheckJob::noScriptFound() +{ + return mNoScriptFound; +} + +QString VacationCheckJob::serverName() +{ + return mServerName; +} + +QString VacationCheckJob::script() +{ + return mScript; +} + +QStringList VacationCheckJob::sieveCapabilities() +{ + return mSieveCapabilities; } + diff --git a/libksieve/ksieveui/vacation/vacationmanager.h b/libksieve/ksieveui/vacation/vacationmanager.h --- a/libksieve/ksieveui/vacation/vacationmanager.h +++ b/libksieve/ksieveui/vacation/vacationmanager.h @@ -41,17 +41,19 @@ void slotEditVacation(const QString &serverName); Q_SIGNALS: - void updateVacationScriptStatus(bool, const QString&); + void updateVacationScriptStatus(bool active, const QString &serverName); void editVacation(); private slots: void slotDialogCanceled(); void slotDialogOk(); + void slotUpdateVacationScriptStatus(bool active, const QString &serverName); private: QPointer mMultiImapVacationDialog; QPointer mCheckVacation; QWidget *mWidget; + bool mQuestionAsked; }; } diff --git a/libksieve/ksieveui/vacation/vacationmanager.cpp b/libksieve/ksieveui/vacation/vacationmanager.cpp --- a/libksieve/ksieveui/vacation/vacationmanager.cpp +++ b/libksieve/ksieveui/vacation/vacationmanager.cpp @@ -30,38 +30,52 @@ VacationManager::VacationManager(QWidget *parent) : QObject(parent), mWidget(parent) + , mMultiImapVacationDialog(0) + , mQuestionAsked(false) { + mCheckVacation = new KSieveUi::MultiImapVacationManager( this ); + connect( mCheckVacation, SIGNAL(scriptActive(bool,QString)), SIGNAL(updateVacationScriptStatus(bool,QString)) ); + connect( mCheckVacation, SIGNAL(scriptActive(bool,QString)), SLOT(slotUpdateVacationScriptStatus(bool,QString)) ); } VacationManager::~VacationManager() { + delete mCheckVacation; } void VacationManager::checkVacation() { - delete mCheckVacation; - - mCheckVacation = new KSieveUi::MultiImapVacationManager( this ); - connect( mCheckVacation, SIGNAL(scriptActive(bool,QString)), SIGNAL(updateVacationScriptStatus(bool,QString)) ); - connect( mCheckVacation, SIGNAL(requestEditVacation()), SIGNAL(editVacation()) ); mCheckVacation->checkVacation(); } +void VacationManager::slotUpdateVacationScriptStatus(bool active, const QString &serverName) +{ + if (active) { + if (!mQuestionAsked) { + mQuestionAsked = true; + if ( KMessageBox::questionYesNo( 0, i18n( "There is still an active out-of-office reply configured.\n" + "Do you want to edit it?"), i18n("Out-of-office reply still active"), + KGuiItem( i18n( "Edit"), QLatin1String("document-properties") ), + KGuiItem( i18n("Ignore"), QLatin1String("dialog-cancel") ) ) + == KMessageBox::Yes ) { + slotEditVacation(serverName); + } + } + } +} + + void VacationManager::slotEditVacation(const QString &serverName) { if ( mMultiImapVacationDialog ) { - mMultiImapVacationDialog->show(); mMultiImapVacationDialog->raise(); mMultiImapVacationDialog->activateWindow(); - if (!serverName.isEmpty()) { - mMultiImapVacationDialog->switchToServerNamePage(serverName); - } - return; + } else { + mMultiImapVacationDialog = new KSieveUi::MultiImapVacationDialog(mCheckVacation, mWidget); + connect( mMultiImapVacationDialog, SIGNAL(okClicked()), SLOT(slotDialogOk()) ); + connect( mMultiImapVacationDialog, SIGNAL(cancelClicked()), SLOT(slotDialogCanceled()) ); } - mMultiImapVacationDialog = new KSieveUi::MultiImapVacationDialog(mWidget); - connect( mMultiImapVacationDialog, SIGNAL(okClicked()), SLOT(slotDialogOk()) ); - connect( mMultiImapVacationDialog, SIGNAL(cancelClicked()), SLOT(slotDialogCanceled()) ); mMultiImapVacationDialog->show(); if (!serverName.isEmpty()) { mMultiImapVacationDialog->switchToServerNamePage(serverName); diff --git a/libksieve/ksieveui/vacation/vacationpagewidget.h b/libksieve/ksieveui/vacation/vacationpagewidget.h --- a/libksieve/ksieveui/vacation/vacationpagewidget.h +++ b/libksieve/ksieveui/vacation/vacationpagewidget.h @@ -29,6 +29,8 @@ class VacationEditWidget; class VacationWarningWidget; class VacationCreateScriptJob; +class MultiImapVacationManager; +class ParseUserScriptJob; class VacationPageWidget : public QWidget { Q_OBJECT @@ -40,11 +42,15 @@ void setServerName(const QString &serverName); KSieveUi::VacationCreateScriptJob *writeScript(); void setDefault(); + void setVacationManager(MultiImapVacationManager *vacationManager); private slots: - void slotGetResult(KManageSieve::SieveJob *job, bool success, const QString &script, bool active); + void slotGetResult(const QString &serverName, const QStringList &sieveCapabilities, const QString &scriptName, const QString &script, bool active); private: + + void fillWithDefaults(); + enum PageType { Script = 0, ScriptNotSupported = 1 @@ -56,7 +62,7 @@ QStackedWidget *mStackWidget; VacationEditWidget *mVacationEditWidget; VacationWarningWidget *mVacationWarningWidget; - KManageSieve::SieveJob *mSieveJob; + MultiImapVacationManager *mVacationManager; bool mWasActive; }; } diff --git a/libksieve/ksieveui/vacation/vacationpagewidget.cpp b/libksieve/ksieveui/vacation/vacationpagewidget.cpp --- a/libksieve/ksieveui/vacation/vacationpagewidget.cpp +++ b/libksieve/ksieveui/vacation/vacationpagewidget.cpp @@ -20,6 +20,8 @@ #include "vacationwarningwidget.h" #include "vacationcreatescriptjob.h" #include "vacationutils.h" +#include "multiimapvacationmanager.h" +#include #include "sieve-vacation.h" #include @@ -37,7 +39,6 @@ VacationPageWidget::VacationPageWidget(QWidget *parent) : QWidget(parent), mPageScript(Script), - mSieveJob(0), mWasActive(false) { QVBoxLayout *lay = new QVBoxLayout; @@ -79,18 +80,20 @@ VacationPageWidget::~VacationPageWidget() { - if ( mSieveJob ) - mSieveJob->kill(); - mSieveJob = 0; } void VacationPageWidget::setServerUrl(const KUrl &url) { mUrl = url; mVacationEditWidget->setEnabled(false); - mSieveJob = KManageSieve::SieveJob::get( url ); - connect( mSieveJob, SIGNAL(gotScript(KManageSieve::SieveJob*,bool,QString,bool)), - SLOT(slotGetResult(KManageSieve::SieveJob*,bool,QString,bool)) ); +} + +void VacationPageWidget::setVacationManager(MultiImapVacationManager *vacationManager) +{ + mVacationManager = vacationManager; + connect(mVacationManager, SIGNAL(scriptAvailable(QString,QStringList,QString,QString,bool)), + SLOT(slotGetResult(QString,QStringList,QString,QString,bool))); + mVacationManager->checkVacation(mServerName, mUrl); } void VacationPageWidget::setServerName(const QString &serverName) @@ -98,24 +101,26 @@ mServerName = serverName; } -void VacationPageWidget::slotGetResult( KManageSieve::SieveJob * job, bool success, const QString & script, bool active ) +void VacationPageWidget::slotGetResult(const QString &serverName, const QStringList &sieveCapabilities, const QString &scriptName, const QString &script, bool active) { - kDebug() << success - << ", ?," << active << ")" << endl + if (serverName != mServerName) { + return; + } + + kDebug() << serverName << sieveCapabilities << endl + << scriptName << "(" << active << ")" << endl << "script:" << endl << script; - mSieveJob = 0; // job deletes itself after returning from this slot! if ( mUrl.protocol() == QLatin1String("sieve") && - !job->sieveCapabilities().contains(QLatin1String("vacation")) ) { + !sieveCapabilities.contains(QLatin1String("vacation")) ) { mStackWidget->setCurrentIndex(ScriptNotSupported); return; } // Whether the server supports the "date" extension - const bool supportsSieveDate = mUrl.protocol() == QLatin1String("sieve") && job->sieveCapabilities().contains(QLatin1String("date")); + const bool supportsSieveDate = mUrl.protocol() == QLatin1String("sieve") && sieveCapabilities.contains(QLatin1String("date")); - mVacationEditWidget->setEnabled(true); QString messageText = VacationUtils::defaultMessageText(); QString subject = VacationUtils::defaultSubject(); int notificationInterval = VacationUtils::defaultNotificationInterval(); @@ -124,13 +129,15 @@ QString domainName = VacationUtils::defaultDomainName(); QDate startDate = VacationUtils::defaultStartDate(); QDate endDate = VacationUtils::defaultEndDate(); - if ( !success ) - active = false; // default to inactive - if ( ( !success || !KSieveUi::VacationUtils::parseScript( script, messageText, subject, notificationInterval, aliases, sendForSpam, domainName, startDate, endDate ) ) ) + const bool bParse = KSieveUi::VacationUtils::parseScript(script, messageText, subject, notificationInterval, aliases, sendForSpam, domainName, startDate, endDate); + + if (!bParse) { mVacationWarningWidget->setVisible(true); + } mWasActive = active; + mVacationEditWidget->setEnabled(true); mVacationEditWidget->setActivateVacation( active ); mVacationEditWidget->setMessageText( messageText ); mVacationEditWidget->setSubject( subject ); @@ -149,6 +156,8 @@ //emit scriptActive( mWasActive, mServerName ); } + + KSieveUi::VacationCreateScriptJob *VacationPageWidget::writeScript() { if (mPageScript == Script) { diff --git a/libksieve/ksieveui/vacation/vacationutils.h b/libksieve/ksieveui/vacation/vacationutils.h --- a/libksieve/ksieveui/vacation/vacationutils.h +++ b/libksieve/ksieveui/vacation/vacationutils.h @@ -51,6 +51,8 @@ bool & sendForSpam, QString & domainName, QDate & startDate, QDate & endDate ); +bool foundVacationScript(const QString & script); + } } diff --git a/libksieve/ksieveui/vacation/vacationutils.cpp b/libksieve/ksieveui/vacation/vacationutils.cpp --- a/libksieve/ksieveui/vacation/vacationutils.cpp +++ b/libksieve/ksieveui/vacation/vacationutils.cpp @@ -144,6 +144,26 @@ return true; } +bool KSieveUi::VacationUtils::foundVacationScript(const QString &script) +{ + const QByteArray scriptUTF8 = script.trimmed().toUtf8(); + kDebug() << "scriptUtf8 = \"" + scriptUTF8 +"\""; + + if (scriptUTF8.isEmpty()) { + return false; + } + + KSieve::Parser parser( scriptUTF8.begin(), + scriptUTF8.begin() + scriptUTF8.length() ); + VacationDataExtractor vdx; + SpamDataExtractor sdx; + DomainRestrictionDataExtractor drdx; + DateExtractor dx; + KSieveExt::MultiScriptBuilder tsb( &vdx, &sdx, &drdx, &dx ); + parser.setScriptBuilder( &tsb ); + return parser.parse(); +} + QString KSieveUi::VacationUtils::composeScript( const QString & messageText, const QString &subject, int notificationInterval, diff --git a/libksieve/ksieveui/widgets/managesievewidget.h b/libksieve/ksieveui/widgets/managesievewidget.h --- a/libksieve/ksieveui/widgets/managesievewidget.h +++ b/libksieve/ksieveui/widgets/managesievewidget.h @@ -35,6 +35,7 @@ namespace KSieveUi { class ManageSieveTreeView; +class ParseUserScriptJob; class KSIEVEUI_EXPORT ManageSieveWidget : public QWidget { Q_OBJECT @@ -65,6 +66,7 @@ void slotDoubleClicked(QTreeWidgetItem *item); void slotSystemNetworkStatusChanged(Solid::Networking::Status status); void slotCheckNetworkStatus(); + void setActiveScripts(ParseUserScriptJob *job); public Q_SLOTS: void slotGotList(KManageSieve::SieveJob *job, bool success, const QStringList &listScript, const QString &activeScript); @@ -91,8 +93,6 @@ bool isFileNameItem(QTreeWidgetItem *item) const; bool itemIsActived(QTreeWidgetItem *item) const; void changeActiveScript(QTreeWidgetItem *item, bool activate); - bool isProtectedName(const QString &name); - // Maps top-level items to their child which has the radio button selection QMap mSelectedItems; diff --git a/libksieve/ksieveui/widgets/managesievewidget.cpp b/libksieve/ksieveui/widgets/managesievewidget.cpp --- a/libksieve/ksieveui/widgets/managesievewidget.cpp +++ b/libksieve/ksieveui/widgets/managesievewidget.cpp @@ -21,6 +21,9 @@ #include +#include +#include +#include #include #include @@ -31,8 +34,11 @@ #include #include #include +#include using namespace KSieveUi; +Q_DECLARE_METATYPE(QTreeWidgetItem*) + ManageSieveWidget::ManageSieveWidget(QWidget *parent) : QWidget(parent), mClearAll( false ), @@ -174,7 +180,7 @@ if ( !ok || name.isEmpty() ) return; - if (isProtectedName(name.toLower())) { + if (Util::isKep14ProtectedName(name)) { KMessageBox::error(this, i18n("You cannot use protected name."), i18n("New Script")); return; } @@ -245,11 +251,27 @@ KUrl u = mUrls[item]; if ( u.isEmpty() ) return; + + if (item->data(0, SIEVE_SERVER_MODE).toInt() == Kep14EditorMode) { + QStringList activeScripts; + for(int i=0; i < item->childCount(); i++) { + QTreeWidgetItem *j = item->child(i); + if (itemIsActived(j)) { + activeScripts << j->text(0); + } + } + GenerateGlobalScriptJob *job = new GenerateGlobalScriptJob(u); + job->addUserActiveScripts(activeScripts); + connect( job, SIGNAL(success()), SLOT(slotRefresh())); + connect( job, SIGNAL(error(QString)), SLOT(slotRefresh())); + job->start(); + return; + } + QTreeWidgetItem* selected = mSelectedItems[item]; if ( !selected ) return; u.setFileName( selected->text(0) ); - KManageSieve::SieveJob * job; if ( activate ) job = KManageSieve::SieveJob::activate( u ); @@ -311,16 +333,6 @@ Q_EMIT scriptDeleted(u); } -bool ManageSieveWidget::isProtectedName(const QString &name) -{ - if (name == QLatin1String("master") || - name == QLatin1String("user") || - name == QLatin1String("management")) { - return true; - } - return false; -} - void ManageSieveWidget::slotRefresh() { mBlockSignal = true; @@ -342,9 +354,7 @@ qDebug()<<"void ManageSieveWidget::slotGotList(KManageSieve::SieveJob *job, bool success, const QStringList &listScript, const QString &activeScript) success: "<(parent))->stopAnimation(); @@ -364,8 +374,7 @@ mBlockSignal = true; // don't trigger slotItemChanged Q_FOREACH (const QString &script, listScript) { //Hide protected name. - const QString lowerScript(script.toLower()); - if (isProtectedName(lowerScript)) + if (Util::isKep14ProtectedName(script)) continue; QTreeWidgetItem* item = new QTreeWidgetItem( parent ); item->setFlags(item->flags() & (Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable)); @@ -379,20 +388,60 @@ } mBlockSignal = false; - qDebug()<<" LOAD"; - const bool hasIncludeCapability = job->sieveCapabilities().contains(QLatin1String("include")); - const bool hasUserActiveScript = (activeScript.toLower() == QLatin1String("USER")); - QStringList mUserActiveScriptList; - if (hasUserActiveScript && hasIncludeCapability) { - //TODO parse file. + const bool hasKep14EditorMode = Util::hasKep14Support(job->sieveCapabilities(), listScript, activeScript); + if (hasKep14EditorMode) { + KUrl u = mUrls[parent]; + u.setFileName(QLatin1String("USER")); + ParseUserScriptJob *parseJob = new ParseUserScriptJob(u); + parseJob->setProperty(QLatin1String("parentItem").latin1(), QVariant::fromValue(parent)); + connect(parseJob, SIGNAL(finished(ParseUserScriptJob*)), SLOT(setActiveScripts(ParseUserScriptJob*))); + parseJob->start(); + (static_cast(parent))->startAnimation(); } parent->setData( 0, SIEVE_SERVER_CAPABILITIES, job->sieveCapabilities() ); parent->setData( 0, SIEVE_SERVER_ERROR, false ); - parent->setData( 0, SIEVE_SERVER_MODE, hasIncludeCapability ? Kep14EditorMode : NormalEditorMode); + parent->setData( 0, SIEVE_SERVER_MODE, hasKep14EditorMode ? Kep14EditorMode : NormalEditorMode); mTreeView->expandItem( parent ); } +void ManageSieveWidget::setActiveScripts(ParseUserScriptJob *job) +{ + QTreeWidgetItem * parent = job->property(QLatin1String("parentItem").latin1()).value(); + if ( !parent ) { + return; + } + (static_cast(parent))->stopAnimation(); + + if (!job->error().isEmpty()) { + qWarning() << job->error(); + return; + } + + mBlockSignal = true; // don't trigger slotItemChanged + const QStringList activeScriptList = job->activeScriptList(); + QStringList scriptOrder = activeScriptList; + QMap scriptMap; + + const int children = parent->childCount(); + for(int i=0; i < children; i++) { + QTreeWidgetItem *item = parent->takeChild(0); + scriptMap.insert(item->text(0), item); + const bool isActive = activeScriptList.contains(item->text(0)); + item->setCheckState(0, isActive ? Qt::Checked : Qt::Unchecked); + if (!isActive) { + scriptOrder << item->text(0); + } + } + + foreach(const QString &scriptName, scriptOrder) { + parent->addChild(scriptMap[scriptName]); + } + + mBlockSignal = false; +} + + void ManageSieveWidget::slotDoubleClicked( QTreeWidgetItem * item ) { if ( !isFileNameItem( item ) ) diff --git a/libksieve/parser/lexer.cpp b/libksieve/parser/lexer.cpp --- a/libksieve/parser/lexer.cpp +++ b/libksieve/parser/lexer.cpp @@ -161,7 +161,7 @@ #endif static QString removeCRLF( const QString & s ) { const bool CRLF = s.endsWith( QLatin1String("\r\n") ); - const bool LF = !CRLF && s.endsWith( '\n' ); + const bool LF = !CRLF && s.endsWith( QLatin1Char('\n') ); const int e = CRLF ? 2 : LF ? 1 : 0 ; // what to chop off at the end @@ -255,7 +255,7 @@ case ')': case ';': case ',': // Special - result = *mState.cursor++; + result = QLatin1Char(*mState.cursor++); return Special; case '0': case '1': @@ -401,7 +401,7 @@ } if ( reallySave ) { QString tmp = QString::fromUtf8( commentStart, commentLength ); - result += tmp.remove( '\r' ); // get rid of CR in CRLF pairs + result += tmp.remove( QLatin1Char('\r') ); // get rid of CR in CRLF pairs } } @@ -505,7 +505,7 @@ assert( isdigit( *mState.cursor ) ); while ( !atEnd() && isdigit( *mState.cursor ) ) - result += *mState.cursor++; + result += QLatin1Char(*mState.cursor++); if ( atEnd() || isDelim( *mState.cursor ) ) return true; @@ -517,7 +517,7 @@ case 'm': case 'K': case 'k': - result += *mState.cursor++; + result += QLatin1Char(*mState.cursor++); break; default: makeIllegalCharError(); @@ -589,21 +589,21 @@ } const QString line = removeCRLF( QString::fromUtf8( oldBeginOfLine, lineLength ) ); lines.push_back( removeDotStuff( line ) ); - if ( line == "." ) + if ( line == QLatin1String(".") ) break; } else { lines.push_back( QString() ); } } - if ( lines.back() != "." ) { + if ( lines.back() != QLatin1String(".") ) { makeError( Error::PrematureEndOfMultiLine, mlBeginLine, mlBeginCol ); return false; } assert( !lines.empty() ); lines.erase( --lines.end() ); // don't include the lone dot. - result = lines.join("\n"); + result = lines.join(QLatin1String("\n")); return true; } @@ -630,7 +630,7 @@ case '\n': if ( !eatCRLF() ) return false; - result += '\n'; + result += QLatin1Char('\n'); break; case '\\': ++mState.cursor; @@ -639,7 +639,7 @@ // else fall through: default: if ( !is8Bit( *mState.cursor ) ) - result += *mState.cursor++; + result += QLatin1Char(*mState.cursor++); else { // probably UTF-8 const char * const eightBitBegin = mState.cursor; skipTo8BitEnd(); diff --git a/libksieve/parser/parser.cpp b/libksieve/parser/parser.cpp --- a/libksieve/parser/parser.cpp +++ b/libksieve/parser/parser.cpp @@ -130,7 +130,7 @@ return isStringToken() || token() == Lexer::Number || token() == Lexer::Tag || - ( token() == Lexer::Special && mTokenValue == "[" ); + ( token() == Lexer::Special && mTokenValue == QLatin1String("[")) ; } bool Parser::Impl::obtainToken() { @@ -251,7 +251,7 @@ return false; } - if ( token() == Lexer::Special && tokenValue() == "(" ) { // test-list + if ( token() == Lexer::Special && tokenValue() == QLatin1String ("(")) { // test-list if ( !parseTestList() ) { assert( error() ); return false; @@ -280,9 +280,9 @@ return false; } - if ( tokenValue() == ";" ) + if ( tokenValue() == QLatin1String (";")) consumeToken(); - else if ( tokenValue() == "{" ) { // block + else if ( tokenValue() == QLatin1String ("{")) { // block if ( !parseBlock() ) return false; // it's an error since we saw '{' } else { @@ -334,7 +334,7 @@ scriptBuilder()->stringArgument( tokenValue(), token() == Lexer::MultiLineString, QString() ); consumeToken(); return true; - } else if ( token() == Lexer::Special && tokenValue() == "[" ) { + } else if ( token() == Lexer::Special && tokenValue() == QLatin1String("[")) { if ( !parseStringList() ) { assert( error() ); return false; @@ -352,7 +352,7 @@ if ( !obtainToken() || atEnd() ) return false; - if ( token() != Lexer::Special || tokenValue() != "(" ) + if ( token() != Lexer::Special || tokenValue() != QLatin1String("(")) return false; if ( scriptBuilder() ) scriptBuilder()->testListStart(); @@ -462,7 +462,7 @@ if ( atEnd() ) // a test w/o nested tests goto TestEnd; - if ( token() == Lexer::Special && tokenValue() == "(" ) { // test-list + if ( token() == Lexer::Special && tokenValue() == QLatin1String("(")) { // test-list if ( !parseTestList() ) { assert( error() ); return false; @@ -488,7 +488,7 @@ if ( !obtainToken() || atEnd() ) return false; - if ( token() != Lexer::Special || tokenValue() != "{" ) + if ( token() != Lexer::Special || tokenValue() != QLatin1String("{")) return false; if ( scriptBuilder() ) scriptBuilder()->blockStart(); @@ -517,7 +517,7 @@ return false; } - if ( token() != Lexer::Special || tokenValue() != "}" ) { + if ( token() != Lexer::Special || tokenValue() != QLatin1String("}")) { makeError( Error::NonCommandInCommandList ); return false; } @@ -538,7 +538,7 @@ if ( !obtainToken() || atEnd() ) return false; - if ( token() != Lexer::Special || tokenValue() != "[" ) + if ( token() != Lexer::Special || tokenValue() != QLatin1String("[") ) return false; if ( scriptBuilder() ) @@ -619,7 +619,7 @@ int i = 0; const QByteArray s = tokenValue().toLatin1(); for ( const int len = s.length() ; i < len && isdigit( s[i] ) ; ++i ) { - const unsigned long digitValue = s[i] - '0' ; + const unsigned long digitValue = s[i] - QLatin1Char('0').toLatin1() ; if ( willOverflowULong( result, digitValue ) ) { makeError( Error::NumberOutOfRange ); return false;