Index: libksieve/autotests/parsertest.cpp
===================================================================
--- libksieve/autotests/parsertest.cpp
+++ libksieve/autotests/parsertest.cpp
@@ -462,12 +462,12 @@
const QString txt = "number" + (quantifier ? QString(" quantifier=\"%1\"").arg(quantifier) : QString()) ;
write(txt.toLatin1(), QString::number(number));
}
- void commandStart(const QString &identifier) Q_DECL_OVERRIDE {
+ void commandStart(const QString &identifier, int lineNumber) Q_DECL_OVERRIDE {
write("");
++indent;
write("identifier", identifier);
}
- void commandEnd() Q_DECL_OVERRIDE {
+ void commandEnd(int lineNumber) Q_DECL_OVERRIDE {
--indent;
write("");
}
@@ -488,11 +488,11 @@
--indent;
write("");
}
- void blockStart() Q_DECL_OVERRIDE {
+ void blockStart(int lineNumber) Q_DECL_OVERRIDE {
write("");
++indent;
}
- void blockEnd() Q_DECL_OVERRIDE {
+ void blockEnd(int lineNumber) Q_DECL_OVERRIDE {
--indent;
write("");
}
@@ -583,12 +583,12 @@
checkEquals(QString::number(number) + (quantifier ? quantifier : ' '));
++mNextResponse;
}
- void commandStart(const QString &identifier) Q_DECL_OVERRIDE {
+ void commandStart(const QString &identifier, int lineNumber) Q_DECL_OVERRIDE {
checkIs(CommandStart);
checkEquals(identifier);
++mNextResponse;
}
- void commandEnd() Q_DECL_OVERRIDE {
+ void commandEnd(int lineNumber) Q_DECL_OVERRIDE {
checkIs(CommandEnd);
++mNextResponse;
}
@@ -609,11 +609,11 @@
checkIs(TestListEnd);
++mNextResponse;
}
- void blockStart() Q_DECL_OVERRIDE {
+ void blockStart(int lineNumber) Q_DECL_OVERRIDE {
checkIs(BlockStart);
++mNextResponse;
}
- void blockEnd() Q_DECL_OVERRIDE {
+ void blockEnd(int lineNumber) Q_DECL_OVERRIDE {
checkIs(BlockEnd);
++mNextResponse;
}
Index: libksieve/src/ksieve/scriptbuilder.h
===================================================================
--- libksieve/src/ksieve/scriptbuilder.h
+++ libksieve/src/ksieve/scriptbuilder.h
@@ -53,17 +53,17 @@
virtual void stringListEntry(const QString &string, bool multiLine, const QString &embeddedHashComment) = 0;
virtual void stringListArgumentEnd() = 0;
- virtual void commandStart(const QString &identifier) = 0;
- virtual void commandEnd() = 0;
+ virtual void commandStart( const QString & identifier, int lineNumber ) = 0;
+ virtual void commandEnd(int lineNumber) = 0;
virtual void testStart(const QString &identifier) = 0;
virtual void testEnd() = 0;
virtual void testListStart() = 0;
virtual void testListEnd() = 0;
- virtual void blockStart() = 0;
- virtual void blockEnd() = 0;
+ virtual void blockStart(int lineNumber) = 0;
+ virtual void blockEnd(int lineNumber) = 0;
/** A hash comment always includes an implicit lineFeed() at it's end. */
virtual void hashComment(const QString &comment) = 0;
Index: libksieve/src/ksieveui/CMakeLists.txt
===================================================================
--- libksieve/src/ksieveui/CMakeLists.txt
+++ libksieve/src/ksieveui/CMakeLists.txt
@@ -16,6 +16,7 @@
add_subdirectory(editor/autotests)
add_subdirectory(autocreatescripts/tests)
add_subdirectory(scriptsparsing/tests)
+ add_subdirectory(vacation/autotests)
add_subdirectory(vacation/tests)
add_subdirectory(sievescriptdebugger/autotests)
add_subdirectory(sievescriptdebugger/tests)
@@ -169,6 +170,7 @@
widgets/managesievewidget.cpp
debug/sievedebugdialog.cpp
util/util.cpp
+ managescriptsjob/checkkep14supportjob.cpp
managescriptsjob/generateglobalscriptjob.cpp
managescriptsjob/parseuserscriptjob.cpp
templates/sievetemplatewidget.cpp
@@ -313,7 +315,5 @@
endif()
-
-
install(FILES data/ksieve_script.knsrc DESTINATION ${KDE_INSTALL_CONFDIR} )
install(DIRECTORY data/scripts/ DESTINATION ${KDE_INSTALL_DATADIR}/sieve/scripts/ )
Index: libksieve/src/ksieveui/managescriptsjob/autotests/parseuserjobtest.h
===================================================================
--- libksieve/src/ksieveui/managescriptsjob/autotests/parseuserjobtest.h
+++ libksieve/src/ksieveui/managescriptsjob/autotests/parseuserjobtest.h
@@ -19,7 +19,9 @@
#define PARSEUSERJOBTEST_H
#include
-class ParseUserTest : public QObject
+
+namespace KSieveUi {
+class ParseUserJobTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
@@ -29,5 +31,5 @@
void testParseUserDuplicateActiveScriptJob();
void testParseUserErrorScriptJob();
};
-
+}
#endif // PARSEUSERJOBTEST_H
Index: libksieve/src/ksieveui/managescriptsjob/autotests/parseuserjobtest.cpp
===================================================================
--- libksieve/src/ksieveui/managescriptsjob/autotests/parseuserjobtest.cpp
+++ libksieve/src/ksieveui/managescriptsjob/autotests/parseuserjobtest.cpp
@@ -18,18 +18,20 @@
#include "ksieveui/managescriptsjob/parseuserscriptjob.h"
#include
-QTEST_MAIN(ParseUserTest)
+using namespace KSieveUi;
-void ParseUserTest::testParseEmptyUserJob()
+QTEST_MAIN(ParseUserJobTest)
+
+void ParseUserJobTest::testParseEmptyUserJob()
{
const QString script;
bool result;
- const QStringList lst = KSieveUi::ParseUserScriptJob::parsescript(script, result);
+ const QStringList lst = ParseUserScriptJob::parsescript(script, result);
QCOMPARE(lst.count(), 0);
QCOMPARE(result, true);
}
-void ParseUserTest::testParseUserTwoActiveScriptJob()
+void ParseUserJobTest::testParseUserTwoActiveScriptJob()
{
const QString script = QStringLiteral("# USER Management Script\n"
"#\n"
@@ -43,12 +45,12 @@
"include :personal \"file1\";\n"
"include :personal \"file2\";\n");
bool result;
- const QStringList lst = KSieveUi::ParseUserScriptJob::parsescript(script, result);
+ const QStringList lst = ParseUserScriptJob::parsescript(script, result);
QCOMPARE(lst.count(), 2);
QCOMPARE(result, true);
}
-void ParseUserTest::testParseUserNoActiveScriptJob()
+void ParseUserJobTest::testParseUserNoActiveScriptJob()
{
const QString script = QStringLiteral("# USER Management Script\n"
"#\n"
@@ -60,12 +62,12 @@
"\n"
"require [\"include\"];\n");
bool result;
- const QStringList lst = KSieveUi::ParseUserScriptJob::parsescript(script, result);
+ const QStringList lst = ParseUserScriptJob::parsescript(script, result);
QCOMPARE(lst.count(), 0);
QCOMPARE(result, true);
}
-void ParseUserTest::testParseUserDuplicateActiveScriptJob()
+void ParseUserJobTest::testParseUserDuplicateActiveScriptJob()
{
const QString script = QStringLiteral("# USER Management Script\n"
"#\n"
@@ -79,12 +81,12 @@
"include :personal \"file1\";\n"
"include :personal \"file1\";\n");
bool result;
- const QStringList lst = KSieveUi::ParseUserScriptJob::parsescript(script, result);
+ const QStringList lst = ParseUserScriptJob::parsescript(script, result);
QCOMPARE(lst.count(), 1);
QCOMPARE(result, true);
}
-void ParseUserTest::testParseUserErrorScriptJob()
+void ParseUserJobTest::testParseUserErrorScriptJob()
{
const QString script = QStringLiteral("# USER Management Script\n"
"#\n"
@@ -96,7 +98,7 @@
"\n"
"errorscript\n");
bool result;
- const QStringList lst = KSieveUi::ParseUserScriptJob::parsescript(script, result);
+ const QStringList lst = ParseUserScriptJob::parsescript(script, result);
QCOMPARE(lst.count(), 0);
QCOMPARE(result, false);
}
Index: libksieve/src/ksieveui/managescriptsjob/checkkep14supportjob.h
===================================================================
--- libksieve/src/ksieveui/managescriptsjob/checkkep14supportjob.h
+++ libksieve/src/ksieveui/managescriptsjob/checkkep14supportjob.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013-2015 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,51 +15,51 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef VACATIONCREATESCRIPTJOB_H
-#define VACATIONCREATESCRIPTJOB_H
+#ifndef CHECKKEP14SUPPORTJOB_H
+#define CHECKKEP14SUPPORTJOB_H
#include
+#include
+
+#include "ksieveui_export.h"
#include
-namespace KManageSieve
-{
+namespace KManageSieve {
class SieveJob;
}
-namespace KSieveUi
-{
-class VacationCreateScriptJob : public QObject
+namespace KSieveUi {
+class KSIEVEUI_EXPORT CheckKep14SupportJob : public QObject
{
Q_OBJECT
public:
- explicit VacationCreateScriptJob(QObject *parent = Q_NULLPTR);
- ~VacationCreateScriptJob();
+ explicit CheckKep14SupportJob(QObject *parent=0);
+ ~CheckKep14SupportJob();
void start();
void setServerUrl(const QUrl &url);
- void setScript(const QString &script);
- void setServerName(const QString &servername);
- void setStatus(bool activate, bool wasActive);
+ void setServerName(const QString &name);
+ QString serverName();
-Q_SIGNALS:
- void result(bool);
- void scriptActive(bool activated, const QString &serverName);
+ QStringList availableScripts();
+ bool hasKep14Support();
+ QUrl serverUrl();
-private Q_SLOTS:
- void slotPutActiveResult(KManageSieve::SieveJob *job, bool success);
- void slotPutInactiveResult(KManageSieve::SieveJob *job, bool success);
+Q_SIGNALS:
+ void result(CheckKep14SupportJob*, bool);
private:
- void handlePutResult(KManageSieve::SieveJob *, bool success, bool activated);
QUrl mUrl;
- QString mScript;
- QString mServerName;
- bool mActivate;
- bool mWasActive;
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 // VACATIONCREATESCRIPTJOB_H
+#endif // CHECKKEP14SUPPORTJOB_H
Index: libksieve/src/ksieveui/managescriptsjob/checkkep14supportjob.cpp
===================================================================
--- /dev/null
+++ libksieve/src/ksieveui/managescriptsjob/checkkep14supportjob.cpp
@@ -0,0 +1,94 @@
+/*
+ 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 "libksieve_debug.h"
+
+using namespace KSieveUi;
+
+CheckKep14SupportJob::CheckKep14SupportJob(QObject *parent)
+ : QObject(parent),
+ mSieveJob(0)
+{
+
+}
+
+CheckKep14SupportJob::~CheckKep14SupportJob()
+{
+
+}
+
+void CheckKep14SupportJob::start()
+{
+ if (mUrl.isEmpty()) {
+ qCWarning(LIBKSIEVE_LOG) << " 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 QUrl &url)
+{
+ mUrl = url;
+}
+
+QUrl 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);
+}
Index: libksieve/src/ksieveui/managescriptsjob/generateglobalscriptjob.h
===================================================================
--- libksieve/src/ksieveui/managescriptsjob/generateglobalscriptjob.h
+++ libksieve/src/ksieveui/managescriptsjob/generateglobalscriptjob.h
@@ -35,6 +35,7 @@
~GenerateGlobalScriptJob();
void start();
+ void kill();
void addUserActiveScripts(const QStringList &lstScript);
@@ -52,7 +53,7 @@
void writeUserScript();
QStringList mListUserActiveScripts;
QUrl mCurrentUrl;
- KManageSieve::SieveJob *mMasterjob;
+ KManageSieve::SieveJob *mMasterJob;
KManageSieve::SieveJob *mUserJob;
};
}
Index: libksieve/src/ksieveui/managescriptsjob/generateglobalscriptjob.cpp
===================================================================
--- libksieve/src/ksieveui/managescriptsjob/generateglobalscriptjob.cpp
+++ libksieve/src/ksieveui/managescriptsjob/generateglobalscriptjob.cpp
@@ -25,19 +25,27 @@
GenerateGlobalScriptJob::GenerateGlobalScriptJob(const QUrl &url, QObject *parent)
: QObject(parent),
mCurrentUrl(url),
- mMasterjob(Q_NULLPTR),
+ mMasterJob(Q_NULLPTR),
mUserJob(Q_NULLPTR)
{
}
GenerateGlobalScriptJob::~GenerateGlobalScriptJob()
{
- if (mMasterjob) {
- mMasterjob->kill();
+ kill();
+}
+
+void GenerateGlobalScriptJob::kill()
+{
+ if (mMasterJob) {
+ mMasterJob->kill();
}
+ mMasterJob = Q_NULLPTR;
+
if (mUserJob) {
mUserJob->kill();
}
+ mUserJob = Q_NULLPTR;
}
void GenerateGlobalScriptJob::addUserActiveScripts(const QStringList &lstScript)
@@ -51,7 +59,7 @@
Q_EMIT error(i18n("Path is not specified."));
return;
}
- writeMasterScript();
+ writeUserScript();
}
void GenerateGlobalScriptJob::writeMasterScript()
@@ -82,17 +90,17 @@
QUrl url(mCurrentUrl);
url = url.adjusted(QUrl::RemoveFilename);
url.setPath(url.path() + QLatin1String("MASTER"));
- mMasterjob = KManageSieve::SieveJob::put(url, masterScript, true, true);
- connect(mMasterjob, &KManageSieve::SieveJob::result, this, &GenerateGlobalScriptJob::slotPutMasterResult);
+ mMasterJob = KManageSieve::SieveJob::put(url, masterScript, true, true);
+ connect(mMasterJob, &KManageSieve::SieveJob::result, this, &GenerateGlobalScriptJob::slotPutMasterResult);
}
void GenerateGlobalScriptJob::slotPutMasterResult(KManageSieve::SieveJob *, bool success)
{
if (!success) {
Q_EMIT error(i18n("Error when we wrote \"MASTER\" script on server."));
return;
}
- mMasterjob = Q_NULLPTR;
+ mMasterJob = Q_NULLPTR;
writeUserScript();
}
Index: libksieve/src/ksieveui/managescriptsjob/parseuserscriptjob.h
===================================================================
--- libksieve/src/ksieveui/managescriptsjob/parseuserscriptjob.h
+++ libksieve/src/ksieveui/managescriptsjob/parseuserscriptjob.h
@@ -20,6 +20,7 @@
#include
#include
+#include
#include "ksieveui_export.h"
class QDomDocument;
class QDomElement;
@@ -33,27 +34,36 @@
class KSIEVEUI_EXPORT ParseUserScriptJob : public QObject
{
Q_OBJECT
+
+ friend class ParseUserJobTest;
public:
- explicit ParseUserScriptJob(QObject *parent = Q_NULLPTR);
+ explicit ParseUserScriptJob(const QUrl &url, QObject *parent = Q_NULLPTR);
~ParseUserScriptJob();
void start();
- void scriptUrl(const QUrl &url);
- static QStringList parsescript(const QString &script, bool &result);
+ QUrl scriptUrl() const;
+
+ QStringList activeScriptList() const;
+ QString error() const;
+ void kill();
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);
QUrl mCurrentUrl;
KManageSieve::SieveJob *mSieveJob;
+ QStringList mActiveScripts;
+ QString mError;
};
}
Index: libksieve/src/ksieveui/managescriptsjob/parseuserscriptjob.cpp
===================================================================
--- libksieve/src/ksieveui/managescriptsjob/parseuserscriptjob.cpp
+++ libksieve/src/ksieveui/managescriptsjob/parseuserscriptjob.cpp
@@ -22,54 +22,74 @@
#include
using namespace KSieveUi;
-ParseUserScriptJob::ParseUserScriptJob(QObject *parent)
+ParseUserScriptJob::ParseUserScriptJob(const QUrl &url, QObject *parent)
: QObject(parent),
mSieveJob(Q_NULLPTR)
+ , mCurrentUrl(url)
{
}
ParseUserScriptJob::~ParseUserScriptJob()
{
+ kill();
+}
+
+void ParseUserScriptJob::kill()
+{
if (mSieveJob) {
mSieveJob->kill();
}
mSieveJob = Q_NULLPTR;
}
-void ParseUserScriptJob::scriptUrl(const QUrl &url)
+QUrl 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, &KManageSieve::SieveJob::result, this, &ParseUserScriptJob::slotGetResult);
}
void ParseUserScriptJob::slotGetResult(KManageSieve::SieveJob *, bool, const QString &script, bool)
{
mSieveJob = Q_NULLPTR;
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 +100,16 @@
return lst;
}
+QStringList ParseUserScriptJob::activeScriptList() const
+{
+ return mActiveScripts;
+}
+
+QString ParseUserScriptJob::error() const
+{
+ return mError;
+}
+
QStringList ParseUserScriptJob::extractActiveScript(const QDomDocument &doc)
{
QStringList lstScript;
Index: libksieve/src/ksieveui/scriptsparsing/xmlprintingscriptbuilder.h
===================================================================
--- libksieve/src/ksieveui/scriptsparsing/xmlprintingscriptbuilder.h
+++ libksieve/src/ksieveui/scriptsparsing/xmlprintingscriptbuilder.h
@@ -34,14 +34,14 @@
void taggedArgument(const QString &tag) Q_DECL_OVERRIDE;
void stringArgument(const QString &string, bool multiLine, const QString & /*fixme*/) Q_DECL_OVERRIDE;
void numberArgument(unsigned long number, char quantifier) Q_DECL_OVERRIDE;
- void commandStart(const QString &identifier) Q_DECL_OVERRIDE;
- void commandEnd() Q_DECL_OVERRIDE;
+ void commandStart(const QString &identifier, int lineNumber) Q_DECL_OVERRIDE;
+ void commandEnd(int lineNumber) Q_DECL_OVERRIDE;
void testStart(const QString &identifier) Q_DECL_OVERRIDE;
void testEnd() Q_DECL_OVERRIDE;
void testListStart() Q_DECL_OVERRIDE;
void testListEnd() Q_DECL_OVERRIDE;
- void blockStart() Q_DECL_OVERRIDE;
- void blockEnd() Q_DECL_OVERRIDE;
+ void blockStart(int lineNumber) Q_DECL_OVERRIDE;
+ void blockEnd(int lineNumber) Q_DECL_OVERRIDE;
void stringListArgumentStart() Q_DECL_OVERRIDE;
void stringListArgumentEnd() Q_DECL_OVERRIDE;
void stringListEntry(const QString &string, bool multiline, const QString &hashComment) Q_DECL_OVERRIDE;
Index: libksieve/src/ksieveui/scriptsparsing/xmlprintingscriptbuilder.cpp
===================================================================
--- libksieve/src/ksieveui/scriptsparsing/xmlprintingscriptbuilder.cpp
+++ libksieve/src/ksieveui/scriptsparsing/xmlprintingscriptbuilder.cpp
@@ -50,7 +50,7 @@
write(QStringLiteral("num"), (quantifier ? QStringLiteral("quantifier=\"%1\"").arg(quantifier) : QString()) , QString::number(number));
}
-void XMLPrintingScriptBuilder::commandStart(const QString &identifier)
+void XMLPrintingScriptBuilder::commandStart( const QString &identifier, int lineNumber )
{
if (identifier == QLatin1String("else") ||
identifier == QLatin1String("break") ||
@@ -66,7 +66,7 @@
}
}
-void XMLPrintingScriptBuilder::commandEnd()
+void XMLPrintingScriptBuilder::commandEnd(int lineNumber)
{
if (mIsAction) {
write(QStringLiteral(""));
@@ -96,12 +96,12 @@
write(QStringLiteral(""));
}
-void XMLPrintingScriptBuilder::blockStart()
+void XMLPrintingScriptBuilder::blockStart(int lineNumber)
{
write(QStringLiteral(""));
}
-void XMLPrintingScriptBuilder::blockEnd()
+void XMLPrintingScriptBuilder::blockEnd(int lineNumber)
{
write(QStringLiteral(""));
}
Index: libksieve/src/ksieveui/util/util.h
===================================================================
--- libksieve/src/ksieveui/util/util.h
+++ libksieve/src/ksieveui/util/util.h
@@ -45,6 +45,7 @@
class QUrl;
class QString;
+class QStringList;
namespace KSieveUi
{
@@ -76,6 +77,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);
}
}
Index: libksieve/src/ksieveui/util/util.cpp
===================================================================
--- libksieve/src/ksieveui/util/util.cpp
+++ libksieve/src/ksieveui/util/util.cpp
@@ -204,3 +204,45 @@
{
return VacationSettings::self()->allowOutOfOfficeSettings();
}
+
+bool Util::hasKep14Support(const QStringList &sieveCapabilities, const QStringList &availableScripts, const QString &activeScript)
+{
+ const bool hasIncludeCapability = sieveCapabilities.contains(QStringLiteral("include"));
+ if (!hasIncludeCapability) {
+ return false;
+ }
+
+ bool masterIsActive = !activeScript.isEmpty();
+ if (masterIsActive) {
+ const QString scriptName = activeScript.split(QLatin1Char('.')).first().toLower();
+ masterIsActive = (scriptName == QStringLiteral("master") || scriptName == QStringLiteral("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 == QStringLiteral("user")) {
+ hasUserScript = true;
+ break;
+ }
+ }
+
+ return hasIncludeCapability && masterIsActive && hasUserScript;
+}
+
+bool Util::isKep14ProtectedName(const QString &name)
+{
+ const QString n = name.split(QLatin1Char('.')).first().toLower();
+ if (n == QStringLiteral("master") ||
+ n == QStringLiteral("user") ||
+ n == QStringLiteral("management")) {
+ return true;
+ }
+ return false;
+}
\ No newline at end of file
Index: libksieve/src/ksieveui/vacation/autotests/CMakeLists.txt
===================================================================
--- /dev/null
+++ libksieve/src/ksieveui/vacation/autotests/CMakeLists.txt
@@ -0,0 +1,26 @@
+include_directories(${CMAKE_SOURCE_DIR}/libksieve/src
+ )
+
+set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} )
+
+macro( add_vacation_test _source )
+ set( _test ${_source}test.cpp
+ ../${_source}.cpp
+ ../vacationscriptextractor.cpp
+ ${CMAKE_BINARY_DIR}/libksieve/src/ksieveui/sieve-vacation.cpp
+ )
+ get_filename_component(_name ${_source} NAME_WE)
+ ecm_qt_declare_logging_category(_test HEADER libksieve_debug.h IDENTIFIER LIBKSIEVE_LOG CATEGORY_NAME log_libksieve)
+ add_executable(${_name} ${_test})
+ add_test(vacation-${_name} ${_name})
+ ecm_mark_as_test(vacation-${_name})
+ set_target_properties(${_name} PROPERTIES COMPILE_FLAGS -DVACATIONTESTDATADIR="\\"${CMAKE_CURRENT_SOURCE_DIR}/data/\\"")
+ target_link_libraries(${_name}
+ KF5::KSieveUi
+ Qt5::Test
+ KF5::IdentityManagement
+ KF5::Mime
+ )
+endmacro()
+
+add_vacation_test(vacationutils)
Index: libksieve/src/ksieveui/vacation/autotests/data/vacation-active-discard.siv
===================================================================
--- /dev/null
+++ libksieve/src/ksieveui/vacation/autotests/data/vacation-active-discard.siv
@@ -0,0 +1,9 @@
+require ["date","relational","vacation"];
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+if allof (not header :contains "X-Spam-Flag" "YES")
+{
+ vacation :days 7 :addresses "test@test.de" :subject "XXX" "dsfgsdfgsdfg";
+ discard;
+}
\ No newline at end of file
Index: libksieve/src/ksieveui/vacation/autotests/data/vacation-complex-time.siv
===================================================================
--- /dev/null
+++ libksieve/src/ksieveui/vacation/autotests/data/vacation-complex-time.siv
@@ -0,0 +1,8 @@
+require ["date","relational","vacation"];
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+if allof (currentdate :value "ge" "iso8601" "2015-01-02T02:00:00+00:00", currentdate :value "le" "date" "2015-03-04", not header :contains "X-Spam-Flag" "YES")
+{
+ vacation :days 7 :addresses "test@test.de" :subject "XXX" "dsfgsdfgsdfg";
+}
\ No newline at end of file
Index: libksieve/src/ksieveui/vacation/autotests/data/vacation-complex.siv
===================================================================
--- /dev/null
+++ libksieve/src/ksieveui/vacation/autotests/data/vacation-complex.siv
@@ -0,0 +1,8 @@
+require ["date","relational","vacation"];
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+if allof (currentdate :zone "+0100" :value "ge" "date" "2015-01-02", currentdate :zone "+0100" :value "le" "date" "2015-03-04", not header :contains "X-Spam-Flag" "YES")
+{
+ vacation :days 7 :addresses "test@test.de" :subject "XXX" "dsfgsdfgsdfg";
+}
\ No newline at end of file
Index: libksieve/src/ksieveui/vacation/autotests/data/vacation-deactivate-complex.siv
===================================================================
--- /dev/null
+++ libksieve/src/ksieveui/vacation/autotests/data/vacation-deactivate-complex.siv
@@ -0,0 +1,8 @@
+require ["date","relational","vacation"];
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+if false # allof (currentdate :zone "+0100" :value "ge" "date" "2015-01-02", currentdate :zone "+0100" :value "le" "date" "2015-03-04", not header :contains "X-Spam-Flag" "YES")
+{
+ vacation :days 7 :addresses "test@test.de" :subject "XXX" "dsfgsdfgsdfg";
+}
\ No newline at end of file
Index: libksieve/src/ksieveui/vacation/autotests/data/vacation-deactivate-multiple.siv
===================================================================
--- /dev/null
+++ libksieve/src/ksieveui/vacation/autotests/data/vacation-deactivate-multiple.siv
@@ -0,0 +1,19 @@
+require ["vacation"];
+
+if true
+{
+ testcommand;
+}
+
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+if false # true
+{
+ vacation :subject "XXX" "dsfgsdfgsdfg";
+}
+
+if true
+{
+ testcommand;
+}
\ No newline at end of file
Index: libksieve/src/ksieveui/vacation/autotests/data/vacation-deactivate.siv
===================================================================
--- /dev/null
+++ libksieve/src/ksieveui/vacation/autotests/data/vacation-deactivate.siv
@@ -0,0 +1,9 @@
+require ["vacation"];
+
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+if false # true
+{
+ vacation :subject "XXX" "dsfgsdfgsdfg";
+}
\ No newline at end of file
Index: libksieve/src/ksieveui/vacation/autotests/data/vacation-deactive-copy.siv
===================================================================
--- /dev/null
+++ libksieve/src/ksieveui/vacation/autotests/data/vacation-deactive-copy.siv
@@ -0,0 +1,10 @@
+require ["vacation", "copy"];
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+if false
+{
+ vacation :days 7 :addresses "test@test.de" :subject "XXX" "dsfgsdfgsdfg";
+ redirect :copy "copy@example.org";
+}
+discard;
\ No newline at end of file
Index: libksieve/src/ksieveui/vacation/autotests/data/vacation-deactive-send.siv
===================================================================
--- /dev/null
+++ libksieve/src/ksieveui/vacation/autotests/data/vacation-deactive-send.siv
@@ -0,0 +1,11 @@
+require ["vacation", "copy"];
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+if false
+{
+ vacation :days 7 :addresses "test@test.de" :subject "XXX" "dsfgsdfgsdfg";
+ redirect "redirect@example.org";
+}
+
+redirect :copy "argh@example.org";
\ No newline at end of file
Index: libksieve/src/ksieveui/vacation/autotests/data/vacation-multiple.siv
===================================================================
--- /dev/null
+++ libksieve/src/ksieveui/vacation/autotests/data/vacation-multiple.siv
@@ -0,0 +1,16 @@
+require ["vacation"];
+
+if false
+{
+ testcommand;
+}
+
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+vacation :subject "XXX" "dsfgsdfgsdfg";
+
+if false
+{
+ testcommand;
+}
Index: libksieve/src/ksieveui/vacation/autotests/data/vacation-notfound.siv
===================================================================
--- /dev/null
+++ libksieve/src/ksieveui/vacation/autotests/data/vacation-notfound.siv
@@ -0,0 +1,15 @@
+#blabla
+
+testcommand;
+
+if true {
+ testcmd2;
+}
+
+if false {
+ testcmd3;
+}
+
+if true {
+ testcmd4;
+}
\ No newline at end of file
Index: libksieve/src/ksieveui/vacation/autotests/data/vacation-simple.siv
===================================================================
--- /dev/null
+++ libksieve/src/ksieveui/vacation/autotests/data/vacation-simple.siv
@@ -0,0 +1,6 @@
+require ["vacation"];
+
+# EDITOR Roundcube (Managesieve)
+# EDITOR_VERSION 8.2
+# rule:[Urlaub]
+vacation :subject "XXX" "dsfgsdfgsdfg";
\ No newline at end of file
Index: libksieve/src/ksieveui/vacation/autotests/vacationutilstest.h
===================================================================
--- libksieve/src/ksieveui/vacation/autotests/vacationutilstest.h
+++ libksieve/src/ksieveui/vacation/autotests/vacationutilstest.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013-2015 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,33 +15,30 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef MULTIIMAPVACATIONMANAGER_H
-#define MULTIIMAPVACATIONMANAGER_H
+#ifndef VACATIONUTILSTEST_H
+#define VACATIONUTILSTEST_H
#include
-namespace KSieveUi
-{
-class MultiImapVacationManager : public QObject
+namespace KSieveUi {
+class VacationUtilsTest : public QObject
{
Q_OBJECT
-public:
- explicit MultiImapVacationManager(QObject *parent = Q_NULLPTR);
- ~MultiImapVacationManager();
-
- void checkVacation();
-
-Q_SIGNALS:
- void scriptActive(bool active, const QString &serverName);
- void requestEditVacation();
-
private Q_SLOTS:
- void slotScriptActive(bool active, const QString &serverName);
-
-private:
- int mNumberOfJobs;
- bool mQuestionAsked;
- bool mCheckInProgress;
+ void testParseEmptyScript();
+ void testParseOnlyComment();
+ void testParseActivate_data();
+ void testParseActivate();
+ void testParseScript_data();
+ void testParseScript();
+ void testParseScriptComplex();
+ void testParseScriptComplexTime();
+ void testMailAction_data();
+ void testMailAction();
+ void testWriteScript();
+ void testWriteSimpleScript();
+ void testUpdateVacationBlock();
+ void testMergeRequireLine();
};
}
-#endif // MULTIIMAPVACATIONMANAGER_H
+#endif // VACATIONUTILSTEST_H
Index: libksieve/src/ksieveui/vacation/autotests/vacationutilstest.cpp
===================================================================
--- /dev/null
+++ libksieve/src/ksieveui/vacation/autotests/vacationutilstest.cpp
@@ -0,0 +1,341 @@
+/*
+ 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 "vacationutilstest.h"
+#include "ksieveui/vacation/vacationutils.h"
+
+#include
+
+#include
+#include
+
+using namespace KSieveUi;
+
+QTEST_MAIN( VacationUtilsTest)
+
+void testAliases(KMime::Types::AddrSpecList l1, KMime::Types::AddrSpecList l2)
+{
+ QCOMPARE(l1.count(),l2.count());
+ for (int i=0; i < l1.count(); i++) {
+ QCOMPARE(l1.at(i).asString(),l2.at(i).asString());
+ }
+}
+
+void testAliases(KMime::Types::AddrSpecList l1, QStringList l2)
+{
+ QCOMPARE(l1.count(),l2.count());
+ for (int i=0;i < l1.count(); i++) {
+ QCOMPARE(l1.at(i).asString(),l2.at(i));
+ }
+}
+
+
+void VacationUtilsTest::testParseEmptyScript()
+{
+ const QString script;
+ QCOMPARE(VacationUtils::parseScript(script).isValid(), false);
+}
+
+void VacationUtilsTest::testParseOnlyComment()
+{
+ QString script(QLatin1String("#comment"));
+ QCOMPARE(VacationUtils::parseScript(script).isValid(), false);
+ script = QLatin1String("#comment\n\n#comment\n");
+ QCOMPARE(VacationUtils::parseScript(script).isValid(), false);
+}
+
+void VacationUtilsTest::testParseActivate_data()
+{
+ QTest::addColumn("filename");
+ QTest::addColumn("found");
+ QTest::addColumn("active");
+
+ QTest::newRow("notfound") << QStringLiteral("vacation-notfound.siv") << false << false;
+ QTest::newRow("simple") << QStringLiteral("vacation-simple.siv") << true << true;
+ QTest::newRow("multile if") << QStringLiteral("vacation-multiple.siv") << true << true;
+ QTest::newRow("deactivate") << QStringLiteral("vacation-deactivate.siv") << true << false;
+ QTest::newRow("deactivate-multiple if") << QStringLiteral("vacation-deactivate-multiple.siv") << true << false;
+ QTest::newRow("deactivate-complex") << QStringLiteral("vacation-deactivate-complex.siv") << true << false;
+}
+
+
+void VacationUtilsTest::testParseActivate()
+{
+ QFETCH(QString, filename);
+ QFETCH(bool, found);
+ QFETCH(bool, active);
+
+ QFile file(QLatin1String(VACATIONTESTDATADIR)+filename);
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QString script = QString::fromUtf8(file.readAll());
+
+ VacationUtils::Vacation vacation = VacationUtils::parseScript(script);
+ QCOMPARE(vacation.isValid(), found);
+ QCOMPARE(vacation.active, active);
+}
+
+void VacationUtilsTest::testParseScript_data()
+{
+ QTest::addColumn("activate");
+ QTest::addColumn("deactivate");
+
+ QTest::newRow("simple") << QStringLiteral("vacation-simple.siv") << QStringLiteral("vacation-deactivate.siv");
+ QTest::newRow("complex") << QStringLiteral("vacation-complex.siv") << QStringLiteral("vacation-deactivate-complex.siv");
+}
+
+
+void VacationUtilsTest::testParseScript()
+{
+ QFETCH(QString, activate);
+ QFETCH(QString, deactivate);
+ QFile fileA(QLatin1String(VACATIONTESTDATADIR) + activate);
+ QVERIFY(fileA.open(QIODevice::ReadOnly));
+ QString scriptA = QString::fromUtf8(fileA.readAll());
+ QFile fileD(QLatin1String(VACATIONTESTDATADIR) + deactivate);
+ QVERIFY(fileD.open(QIODevice::ReadOnly));
+ QString scriptD = QString::fromUtf8(fileD.readAll());
+
+ VacationUtils::Vacation vacationA = VacationUtils::parseScript(scriptA);
+ VacationUtils::Vacation vacationD = VacationUtils::parseScript(scriptD);
+ QCOMPARE(vacationA.active, true);
+ QCOMPARE(vacationD.active, false);
+ QCOMPARE(vacationD.messageText, vacationA.messageText);
+ QCOMPARE(vacationD.subject, vacationA.subject);
+ QCOMPARE(vacationD.notificationInterval, vacationA.notificationInterval);
+ testAliases(vacationD.aliases, vacationA.aliases);
+ QCOMPARE(vacationD.sendForSpam, vacationA.sendForSpam);
+ QCOMPARE(vacationD.excludeDomain, vacationA.excludeDomain);
+ QCOMPARE(vacationD.startDate, vacationA.startDate);
+ QCOMPARE(vacationD.endDate, vacationA.endDate);
+ QCOMPARE(vacationD.startTime, QTime());
+ QCOMPARE(vacationD.endTime, QTime());
+}
+
+void VacationUtilsTest::testMailAction_data()
+{
+ QTest::addColumn("filename");
+ QTest::addColumn("action");
+ QTest::addColumn("recipient");
+
+ QTest::newRow("keep") << QStringLiteral("vacation-complex.siv") << (int)VacationUtils::Keep << QString();
+ QTest::newRow("discard") << QStringLiteral("vacation-active-discard.siv") << (int)VacationUtils::Discard << QString();
+ QTest::newRow("send") << QStringLiteral("vacation-deactive-send.siv") << (int)VacationUtils::Sendto << QStringLiteral("redirect@example.org");
+ QTest::newRow("copy") << QStringLiteral("vacation-deactive-copy.siv") << (int)VacationUtils::CopyTo << QStringLiteral("copy@example.org");
+}
+
+void VacationUtilsTest::testMailAction()
+{
+ QFETCH(QString, filename);
+ QFETCH(int, action);
+ QFETCH(QString, recipient);
+
+ QFile file(QLatin1String(VACATIONTESTDATADIR) + filename);
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QString script = QString::fromUtf8(file.readAll());
+
+ VacationUtils::Vacation vacation = VacationUtils::parseScript(script);
+ QCOMPARE((int)vacation.mailAction, action);
+ QCOMPARE(vacation.mailActionRecipient, recipient);
+
+ const QString composedScript = VacationUtils::composeScript(vacation);
+ vacation = VacationUtils::parseScript(composedScript);
+ QCOMPARE((int)vacation.mailAction, action);
+ QCOMPARE(vacation.mailActionRecipient, recipient);
+}
+
+void VacationUtilsTest::testParseScriptComplex()
+{
+ QFile file(QLatin1String(VACATIONTESTDATADIR "vacation-complex.siv"));
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QString script = QString::fromUtf8(file.readAll());
+
+ VacationUtils::Vacation vacation = VacationUtils::parseScript(script);
+ QCOMPARE(vacation.active, true);
+ QCOMPARE(vacation.messageText, QLatin1String("dsfgsdfgsdfg"));
+ QCOMPARE(vacation.subject, QLatin1String("XXX"));
+ QCOMPARE(vacation.notificationInterval, 7);
+ testAliases(vacation.aliases, QStringList() << QLatin1String("test@test.de"));
+ QCOMPARE(vacation.sendForSpam, false);
+ QCOMPARE(vacation.excludeDomain, QString());
+ QCOMPARE(vacation.startDate, QDate(2015, 01, 02));
+ QCOMPARE(vacation.endDate, QDate(2015, 03, 04));
+ QCOMPARE(vacation.startTime, QTime());
+ QCOMPARE(vacation.endTime, QTime());
+}
+
+void VacationUtilsTest::testParseScriptComplexTime()
+{
+ QFile file(QLatin1String(VACATIONTESTDATADIR "vacation-complex-time.siv"));
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QString script = QString::fromUtf8(file.readAll());
+
+ VacationUtils::Vacation vacation = VacationUtils::parseScript(script);
+ QCOMPARE(vacation.active, true);
+ QCOMPARE(vacation.messageText, QLatin1String("dsfgsdfgsdfg"));
+ QCOMPARE(vacation.subject, QLatin1String("XXX"));
+ QCOMPARE(vacation.notificationInterval, 7);
+ testAliases(vacation.aliases, QStringList() << QLatin1String("test@test.de"));
+ QCOMPARE(vacation.sendForSpam, false);
+ QCOMPARE(vacation.excludeDomain, QString());
+ QCOMPARE(vacation.startDate, QDate(2015, 01, 02));
+ QCOMPARE(vacation.endDate, QDate(2015, 03, 04));
+ QCOMPARE(vacation.startTime, QTime(2,0));
+ QCOMPARE(vacation.endTime, QTime());
+
+ QString composedScript = VacationUtils::composeScript(vacation);
+ vacation = VacationUtils::parseScript(composedScript);
+ QCOMPARE(vacation.startTime, QTime(2,0));
+ QCOMPARE(vacation.endTime, QTime());
+}
+
+void VacationUtilsTest::testWriteScript()
+{
+ VacationUtils::Vacation vacation, vacationA;
+ QStringList aliases = QStringList() << QLatin1String("test@test.de");
+ vacation.valid = true;
+
+ vacation.messageText = QLatin1String("dsfgsdfgsdfg");
+ vacation.subject = QLatin1String("XXX");
+ vacation.notificationInterval = 7;
+ vacation.sendForSpam = false;
+ vacation.excludeDomain = QLatin1String("example.org");
+ vacation.startDate = QDate(2015, 01, 02);
+ vacation.endDate = QDate(2015, 03, 04);
+ vacation.active = true;
+
+ foreach(const QString &alias, aliases) {
+ KMime::Types::Mailbox a;
+ a.fromUnicodeString(alias);
+ vacation.aliases.append(a.addrSpec());
+ }
+
+ QString script = VacationUtils::composeScript(vacation);
+ vacationA = VacationUtils::parseScript(script);
+ QCOMPARE(vacationA.isValid(), true);
+ QCOMPARE(vacationA.active, vacation.active);
+ QCOMPARE(vacationA.messageText, vacation.messageText);
+ QCOMPARE(vacationA.subject, vacation.subject);
+ QCOMPARE(vacationA.notificationInterval, vacation.notificationInterval);
+ testAliases(vacationA.aliases, vacation.aliases);
+ QCOMPARE(vacationA.sendForSpam, vacation.sendForSpam);
+ QCOMPARE(vacationA.excludeDomain, vacation.excludeDomain);
+ QCOMPARE(vacationA.startDate, vacation.startDate);
+ QCOMPARE(vacationA.endDate, vacation.endDate);
+ QCOMPARE(vacationA.startTime, QTime());
+ QCOMPARE(vacationA.endTime, QTime());
+
+ vacation.active = false;
+ script = VacationUtils::composeScript(vacation);
+ vacationA = VacationUtils::parseScript(script);
+ QCOMPARE(vacationA.isValid(), true);
+ QCOMPARE(vacationA.active, vacation.active);
+ QCOMPARE(vacationA.messageText, vacation.messageText);
+ QCOMPARE(vacationA.subject, vacation.subject);
+ QCOMPARE(vacationA.notificationInterval, vacation.notificationInterval);
+ testAliases(vacationA.aliases, vacation.aliases);
+ QCOMPARE(vacationA.sendForSpam, vacation.sendForSpam);
+ QCOMPARE(vacationA.excludeDomain, vacation.excludeDomain);
+ QCOMPARE(vacationA.startDate, vacation.startDate);
+ QCOMPARE(vacationA.endDate, vacation.endDate);
+ QCOMPARE(vacationA.startTime, QTime());
+ QCOMPARE(vacationA.endTime, QTime());
+}
+
+
+void VacationUtilsTest::testWriteSimpleScript()
+{
+ VacationUtils::Vacation vacation;
+ vacation.valid = true;
+ vacation.messageText = QLatin1String("dsfgsdfgsdfg");
+ vacation.subject = QLatin1String("XXX");
+ vacation.notificationInterval = 7;
+ vacation.active = true;
+ vacation.sendForSpam = true;
+
+ QString script = VacationUtils::composeScript(vacation);
+ VacationUtils::Vacation vacationA = VacationUtils::parseScript(script);
+ QCOMPARE(vacation.isValid(), true);
+ QCOMPARE(vacationA.active, vacation.active);
+ QCOMPARE(vacationA.messageText, vacation.messageText);
+ QCOMPARE(vacationA.subject, vacation.subject);
+ QCOMPARE(vacationA.notificationInterval, vacation.notificationInterval);
+
+ vacation.active = false;
+ script = VacationUtils::composeScript(vacation);
+ vacationA = VacationUtils::parseScript(script);
+ QCOMPARE(vacation.isValid(), true);
+ QCOMPARE(vacationA.active, vacation.active);
+ QCOMPARE(vacationA.messageText, vacation.messageText);
+ QCOMPARE(vacationA.subject, vacation.subject);
+ QCOMPARE(vacationA.notificationInterval, vacation.notificationInterval);
+
+}
+
+void VacationUtilsTest::testUpdateVacationBlock()
+{
+ QFile fileA(QLatin1String(VACATIONTESTDATADIR "vacation-simple.siv"));
+ QVERIFY(fileA.open(QIODevice::ReadOnly));
+ QString scriptA = QString::fromUtf8(fileA.readAll());
+
+ QFile fileB(QLatin1String(VACATIONTESTDATADIR "vacation-deactivate.siv"));
+ QVERIFY(fileB.open(QIODevice::ReadOnly));
+ QString scriptB = QString::fromUtf8(fileB.readAll());
+
+ const QString attend = QLatin1String("if true\n{\ntestcmd;\n}\n");
+ const QString require = QLatin1String("require [\"date\", \"test\"];");
+ const QString scriptAattend = scriptA + QLatin1String("\n") + attend;
+ const QString scriptBattend = scriptB + QLatin1String("\n") + attend;
+
+ QStringList linesA = scriptA.split(QLatin1Char('\n'));
+ QStringList header;
+ for(int i=0; i<5;i++ ){
+ header.append(linesA.at(i));
+ }
+
+ QStringList vacation;
+ for(int i=5; i listCreateJob() const;
Index: libksieve/src/ksieveui/vacation/multiimapvacationdialog.cpp
===================================================================
--- libksieve/src/ksieveui/vacation/multiimapvacationdialog.cpp
+++ libksieve/src/ksieveui/vacation/multiimapvacationdialog.cpp
@@ -17,6 +17,7 @@
#include "multiimapvacationdialog.h"
#include "vacationpagewidget.h"
+#include "multiimapvacationmanager.h"
#include "ksieveui/util.h"
#include
@@ -45,19 +46,23 @@
MultiImapVacationDialogPrivate()
: mTabWidget(Q_NULLPTR),
mStackedWidget(Q_NULLPTR)
+ , mVacationManager(Q_NULLPTR)
{
}
QList mListCreateJob;
QTabWidget *mTabWidget;
QStackedWidget *mStackedWidget;
+ MultiImapVacationManager *mVacationManager;
};
-MultiImapVacationDialog::MultiImapVacationDialog(QWidget *parent)
+MultiImapVacationDialog::MultiImapVacationDialog(MultiImapVacationManager *manager, QWidget *parent)
: QDialog(parent),
d(new KSieveUi::MultiImapVacationDialogPrivate)
{
+ d->mVacationManager = manager;
+
setWindowTitle(i18n("Configure \"Out of Office\" Replies"));
KWindowSystem::setIcons(winId(), qApp->windowIcon().pixmap(IconSize(KIconLoader::Desktop), IconSize(KIconLoader::Desktop)), qApp->windowIcon().pixmap(IconSize(KIconLoader::Small), IconSize(KIconLoader::Small)));
@@ -104,26 +109,21 @@
"IMAP server for this. "
"You can do this on the \"Filtering\" tab of the IMAP "
"account configuration."));
+ lab->setWordWrap(true);
vbox->addWidget(lab);
vbox->addStretch();
lab->setWordWrap(true);
d->mStackedWidget->addWidget(w);
d->mStackedWidget->setCurrentIndex(0);
bool foundOneImap = false;
- const Akonadi::AgentInstance::List instances = KSieveUi::Util::imapAgentInstances();
- foreach (const Akonadi::AgentInstance &instance, instances) {
- if (instance.status() == Akonadi::AgentInstance::Broken) {
- continue;
- }
+ QDialogButtonBox *buttonBox = Q_NULLPTR;
- const QUrl url = KSieveUi::Util::findSieveUrlForAccount(instance.identifier());
- if (!url.isEmpty()) {
- const QString serverName = instance.name();
- createPage(serverName, url);
- foundOneImap = true;
- }
+ QMap list = d->mVacationManager->serverList();
+ foreach (const QString &serverName, list.keys()) {
+ const QUrl url = list.value(serverName);
+ createPage(serverName, url);
+ foundOneImap = true;
}
- QDialogButtonBox *buttonBox = Q_NULLPTR;
if (foundOneImap) {
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults);
QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
@@ -155,6 +155,7 @@
VacationPageWidget *page = new VacationPageWidget;
page->setServerUrl(url);
page->setServerName(serverName);
+ page->setVacationManager(d->mVacationManager);
d->mTabWidget->addTab(page, serverName + QStringLiteral(" (%1)").arg(url.userName()));
}
Index: libksieve/src/ksieveui/vacation/multiimapvacationmanager.h
===================================================================
--- libksieve/src/ksieveui/vacation/multiimapvacationmanager.h
+++ libksieve/src/ksieveui/vacation/multiimapvacationmanager.h
@@ -19,29 +19,42 @@
#define MULTIIMAPVACATIONMANAGER_H
#include
+#include
+
+#include "ksieveui_export.h"
+
+class QUrl;
namespace KSieveUi
{
-class MultiImapVacationManager : public QObject
+class CheckKep14SupportJob;
+class VacationCheckJob;
+class KSIEVEUI_EXPORT MultiImapVacationManager : public QObject
{
Q_OBJECT
public:
explicit MultiImapVacationManager(QObject *parent = Q_NULLPTR);
~MultiImapVacationManager();
void checkVacation();
+ QMap serverList();
+ void checkVacation(const QString &serverName, const QUrl &url);
+
+ bool kep14Support(QString serverName);
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 Q_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
Index: libksieve/src/ksieveui/vacation/multiimapvacationmanager.cpp
===================================================================
--- libksieve/src/ksieveui/vacation/multiimapvacationmanager.cpp
+++ libksieve/src/ksieveui/vacation/multiimapvacationmanager.cpp
@@ -18,17 +18,19 @@
#include "multiimapvacationmanager.h"
#include "vacationcheckjob.h"
#include "util/util.h"
+#include
+#include
+#include
#include
-#include
-#include
+
+#include "libksieve_debug.h"
using namespace KSieveUi;
MultiImapVacationManager::MultiImapVacationManager(QObject *parent)
: QObject(parent),
mNumberOfJobs(0),
- mQuestionAsked(false),
mCheckInProgress(false)
{
}
@@ -38,50 +40,95 @@
}
-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) {
continue;
}
const QUrl url = KSieveUi::Util::findSieveUrlForAccount(instance.identifier());
if (!url.isEmpty()) {
- const QString serverName = instance.name();
- ++mNumberOfJobs;
- VacationCheckJob *job = new VacationCheckJob(url, serverName, this);
- connect(job, &VacationCheckJob::scriptActive, this, &MultiImapVacationManager::slotScriptActive);
+ list.insert(instance.name(), url);
}
}
+ return list;
}
-void MultiImapVacationManager::slotScriptActive(bool active, const QString &serverName)
+void MultiImapVacationManager::checkVacation(const QString &serverName, const QUrl &url)
{
- --mNumberOfJobs;
- Q_EMIT scriptActive(active, serverName);
-
- if (active) {
- if (!mQuestionAsked) {
- mQuestionAsked = true;
- if (KMessageBox::questionYesNo(Q_NULLPTR, 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"), QStringLiteral("document-properties")),
- KGuiItem(i18n("Ignore"), QStringLiteral("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, &CheckKep14SupportJob::result, this, &MultiImapVacationManager::slotCheckKep14Ended);
+ checkKep14Job->start();
}
+ VacationCheckJob *job = new VacationCheckJob(url, serverName, this);
+ job->setKep14Support(mKep14Support[serverName]);
+ connect(job, &VacationCheckJob::scriptActive, this, &MultiImapVacationManager::slotScriptActive);
+ job->start();
+}
+
+void MultiImapVacationManager::checkVacation()
+{
+ if (mCheckInProgress) {
+ return;
+ }
+ mNumberOfJobs = 0;
+ mCheckInProgress = true;
+
+ QMap list = serverList();
+ foreach ( const QString &serverName, list.keys() ) {
+ const QUrl url = list.value(serverName);
+ checkVacation(serverName, url);
+ }
+}
+
+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, &VacationCheckJob::scriptActive, this, &MultiImapVacationManager::slotScriptActive);
+ checkJob->start();
+}
+
+bool MultiImapVacationManager::kep14Support(QString serverName)
+{
+ if (mKep14Support.contains(serverName)) {
+ return mKep14Support[serverName];
+ } else {
+ qCWarning(LIBKSIEVE_LOG) << "We don't know the KEP:14 support for this server." << serverName;
+ }
+ return false;
}
Index: libksieve/src/ksieveui/vacation/tests/main.cpp
===================================================================
--- libksieve/src/ksieveui/vacation/tests/main.cpp
+++ libksieve/src/ksieveui/vacation/tests/main.cpp
@@ -22,6 +22,7 @@
#include
#include "vacation/multiimapvacationdialog.h"
+#include "vacation/multiimapvacationmanager.h"
int main(int argc, char **argv)
{
@@ -41,9 +42,10 @@
parser.process(app);
aboutData.processCommandLine(&parser);
- app.setQuitOnLastWindowClosed(false);
+ app.setQuitOnLastWindowClosed(true);
- KSieveUi::MultiImapVacationDialog dlg;
+ KSieveUi::MultiImapVacationManager manager;
+ KSieveUi::MultiImapVacationDialog dlg(&manager);
dlg.show();
app.exec();
Index: libksieve/src/ksieveui/vacation/vacation.cpp
===================================================================
--- libksieve/src/ksieveui/vacation/vacation.cpp
+++ libksieve/src/ksieveui/vacation/vacation.cpp
@@ -113,42 +113,44 @@
return;
}
+ const bool supportsDate = job->sieveCapabilities().contains(QLatin1String("date"));
+
if (!mDialog && !mCheckOnly) {
mDialog = new VacationDialog(i18n("Configure \"Out of Office\" Replies"), Q_NULLPTR, false);
}
- QString messageText = VacationUtils::defaultMessageText();
- QString subject = VacationUtils::defaultSubject();
- int notificationInterval = VacationUtils::defaultNotificationInterval();
- QStringList aliases = VacationUtils::defaultMailAliases();
- bool sendForSpam = VacationUtils::defaultSendForSpam();
- QString domainName = VacationUtils::defaultDomainName();
- QDate startDate = VacationUtils::defaultStartDate();
- QDate endDate = VacationUtils::defaultEndDate();
if (!success) {
active = false; // default to inactive
}
- if (!mCheckOnly && (!success || !KSieveUi::VacationUtils::parseScript(script, messageText, subject, notificationInterval, aliases, sendForSpam, domainName, startDate, endDate)))
+ KSieveUi::VacationUtils::Vacation vacation = KSieveUi::VacationUtils::parseScript(script);
+
+ if (!mCheckOnly && (!success || (!vacation.isValid() && !script.trimmed().isEmpty())) ) {
KMessageBox::information(Q_NULLPTR, i18n("Someone (probably you) changed the "
"vacation script on the server.\n"
"KMail is no longer able to determine "
"the parameters for the autoreplies.\n"
"Default values will be used."));
-
+ }
mWasActive = active;
if (mDialog) {
- mDialog->setActivateVacation(active);
- mDialog->setSubject(subject);
- mDialog->setMessageText(messageText);
- mDialog->setNotificationInterval(notificationInterval);
- mDialog->setMailAliases(aliases.join(QStringLiteral(", ")));
- mDialog->setSendForSpam(sendForSpam);
- mDialog->setDomainName(domainName);
+ mDialog->setActivateVacation(active && vacation.active);
+ mDialog->setMailAction(vacation.mailAction, vacation.mailActionRecipient);
+ mDialog->setSubject(vacation.subject);
+ mDialog->setMessageText(vacation.messageText);
+ mDialog->setNotificationInterval(vacation.notificationInterval);
+ mDialog->setMailAliases(vacation.aliases);
+ mDialog->setSendForSpam(vacation.sendForSpam);
+ mDialog->setDomainName(vacation.excludeDomain);
mDialog->enableDomainAndSendForSpam(!VacationSettings::allowOutOfOfficeUploadButNoSettings());
- mDialog->enableDates(job->sieveCapabilities().contains(QStringLiteral("date")));
- mDialog->setStartDate(startDate);
- mDialog->setEndDate(endDate);
+ mDialog->enableDates(supportsDate);
+
+ if (supportsDate) {
+ mDialog->setStartDate(vacation.startDate);
+ mDialog->setEndTime(vacation.endTime);
+ mDialog->setEndDate(vacation.endDate);
+ mDialog->setEndTime(vacation.endTime);
+ }
connect(mDialog, &VacationDialog::okClicked, this, &Vacation::slotDialogOk);
connect(mDialog, &VacationDialog::cancelClicked, this, &Vacation::slotDialogCancel);
@@ -171,16 +173,24 @@
{
qCDebug(LIBKSIEVE_LOG);
// compose a new script:
- const QString script = VacationUtils::composeScript(mDialog->messageText(),
- mDialog->subject(),
- mDialog->notificationInterval(),
- mDialog->mailAliases(),
- mDialog->sendForSpam(),
- mDialog->domainName(),
- mDialog->startDate(),
- mDialog->endDate());
const bool active = mDialog->activateVacation();
- Q_EMIT scriptActive(active, mServerName);
+ VacationUtils::Vacation vacation;
+ vacation.valid = true;
+ vacation.active = active;
+ vacation.messageText = mDialog->messageText();
+ vacation.subject = mDialog->subject();
+ vacation.mailAction = mDialog->mailAction();
+ vacation.mailActionRecipient = mDialog->mailActionRecipient();
+ vacation.notificationInterval = mDialog->notificationInterval();
+ vacation.aliases = mDialog->mailAliases();
+ vacation.sendForSpam = mDialog->sendForSpam();
+ vacation.excludeDomain = mDialog->domainName();
+ vacation.startDate = mDialog->startDate();
+ vacation.startTime = mDialog->startTime();
+ vacation.endDate = mDialog->endDate();
+ vacation.endTime = mDialog->endTime();
+ const QString script = VacationUtils::composeScript(vacation);
+ emit scriptActive(active, mServerName);
qCDebug(LIBKSIEVE_LOG) << "script:" << endl << script;
Index: libksieve/src/ksieveui/vacation/vacationcheckjob.h
===================================================================
--- libksieve/src/ksieveui/vacation/vacationcheckjob.h
+++ libksieve/src/ksieveui/vacation/vacationcheckjob.h
@@ -19,6 +19,7 @@
#define VACATIONCHECKJOB_H
#include
+#include
#include
namespace KManageSieve
@@ -28,23 +29,45 @@
namespace KSieveUi
{
+class ParseUserScriptJob;
class VacationCheckJob : public QObject
{
Q_OBJECT
public:
explicit VacationCheckJob(const QUrl &url, const QString &serverName, QObject *parent = Q_NULLPTR);
~VacationCheckJob();
+ void setKep14Support(bool kep14Support);
+ void start();
+ void kill();
+ 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 Q_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 isLastScript() const;
private:
+ QStringList mAvailableScripts;
+ QStringList mActiveScripts;
+ QStringList mSieveCapabilities;
+ QString mScript;
QString mServerName;
QUrl mUrl;
KManageSieve::SieveJob *mSieveJob;
+ ParseUserScriptJob *mParseJob;
+ int mScriptPos;
+ bool mKep14Support;
+ bool mNoScriptFound;
};
}
Index: libksieve/src/ksieveui/vacation/vacationcheckjob.cpp
===================================================================
--- libksieve/src/ksieveui/vacation/vacationcheckjob.cpp
+++ libksieve/src/ksieveui/vacation/vacationcheckjob.cpp
@@ -17,53 +17,201 @@
#include "vacationcheckjob.h"
#include "vacationutils.h"
+#include "managescriptsjob/parseuserscriptjob.h"
+#include "util/util.h"
#include
#include
+#include "libksieve_debug.h"
+
using namespace KSieveUi;
VacationCheckJob::VacationCheckJob(const QUrl &url, const QString &serverName, QObject *parent)
: QObject(parent),
mServerName(serverName),
mUrl(url)
+ , mSieveJob(Q_NULLPTR)
+ , mParseJob(Q_NULLPTR)
+ , mScriptPos(-1)
+ , mKep14Support(false)
+ , mNoScriptFound(false)
{
- mSieveJob = KManageSieve::SieveJob::get(mUrl);
- mSieveJob->setInteractive(false);
- connect(mSieveJob, &KManageSieve::SieveJob::gotScript, this, &VacationCheckJob::slotGetResult);
}
VacationCheckJob::~VacationCheckJob()
{
- if (mSieveJob) {
+ kill();
+}
+
+void VacationCheckJob::kill()
+{
+ if ( mSieveJob )
mSieveJob->kill();
+ mSieveJob = Q_NULLPTR;
+
+ if (mParseJob) {
+ mParseJob->kill();
+ }
+ mParseJob = Q_NULLPTR;
+}
+
+
+void VacationCheckJob::setKep14Support(bool kep14Support)
+{
+ mKep14Support = kep14Support;
+}
+
+void VacationCheckJob::start()
+{
+ if (mKep14Support) {
+ QUrl url = mUrl;
+ url = url.adjusted(QUrl::RemoveFilename);
+ url.setPath(url.path() + QLatin1String("USER"));
+ mParseJob = new ParseUserScriptJob(url);
+ connect(mParseJob, &ParseUserScriptJob::finished, this, &VacationCheckJob::slotGotActiveScripts);
+ mParseJob->start();
+ mSieveJob = KManageSieve::SieveJob::list(url);
+ connect(mSieveJob, &KManageSieve::SieveJob::gotList, this, &VacationCheckJob::slotGotList);
+ } else {
+ mSieveJob = KManageSieve::SieveJob::get(mUrl);
+ mSieveJob->setInteractive(false);
+ connect(mSieveJob, &KManageSieve::SieveJob::gotScript, this, &VacationCheckJob::slotGetResult);
}
+}
+
+void VacationCheckJob::slotGetResult(KManageSieve::SieveJob *job, bool success, const QString &script, bool active)
+{
+ Q_ASSERT(job == mSieveJob);
+ mScript = script;
+ mSieveCapabilities = mSieveJob->sieveCapabilities();
mSieveJob = Q_NULLPTR;
+
+ if (mKep14Support) {
+ VacationUtils::Vacation vacation = VacationUtils::parseScript(script);
+ if (vacation.isValid()) {
+ const QString &scriptName = mAvailableScripts[mScriptPos-1];
+ bool active = mActiveScripts.contains(scriptName) && vacation.active;
+ if (active && vacation.startDate.isValid() && vacation.endDate.isValid()) {
+ active = (vacation.startDate <= QDate::currentDate() && vacation.endDate >= QDate::currentDate());
+ }
+ emit scriptActive(this, scriptName, active);
+ qDebug(LIBKSIEVE_LOG) << "vacation script found :)";
+ } else if (isLastScript()) {
+ mNoScriptFound = true;
+ emit scriptActive(this, QString(), false);
+ qDebug(LIBKSIEVE_LOG) << "no vacation script found :(";
+ } else {
+ getNextScript();
+ }
+ } else {
+ if ( !success ) {
+ active = false; // default to inactive
+ mNoScriptFound = true;
+}
+ if (active) {
+ mActiveScripts << mUrl.fileName();
+ }
+ emit scriptActive(this, mUrl.fileName(), active);
+ }
+}
+
+void VacationCheckJob::slotGotActiveScripts(ParseUserScriptJob *job)
+{
+ Q_ASSERT(job == mParseJob);
+ mParseJob = Q_NULLPTR;
+ if (!job->error().isEmpty()) {
+ emitError(QLatin1String("ParseUserScriptJob failed:")+job->error());
+ return;
+ }
+ mActiveScripts = job->activeScriptList();
+
+ if (!mSieveJob) {
+ searchVacationScript();
+ }
}
-void VacationCheckJob::slotGetResult(KManageSieve::SieveJob */*job*/, bool success, const QString &script, bool active)
+void VacationCheckJob::slotGotList(KManageSieve::SieveJob *job, bool success, const QStringList &availableScripts, const QString &activeScript)
{
+ Q_UNUSED(activeScript)
+ Q_ASSERT(job == mSieveJob);
mSieveJob = Q_NULLPTR;
if (!success) {
- active = false; // default to inactive
+ emitError(QLatin1String("SieveJob list failed."));
+ return;
}
- QDate startDate, endDate;
+ mAvailableScripts = availableScripts;
- QString dummyStr;
- QStringList dummyStrList;
- int dummyInt;
- bool dummyBool;
+ if (!mParseJob) {
+ searchVacationScript();
+ }
+}
+
+void VacationCheckJob::emitError(const QString &errorMessage)
+{
+ qWarning() << errorMessage;
+ //TODO: emit error
+}
+
+void VacationCheckJob::searchVacationScript()
+{
+ QStringList scriptList = mActiveScripts;
- // If the script is active then parse it, and verify whether it has date range set
- if (active) {
- bool valid = VacationUtils::parseScript(script, dummyStr, dummyStr, dummyInt, dummyStrList, dummyBool, dummyStr, startDate, endDate);
- // If the date range is set, mark the script as active only if the date range
- // includes now/today
- if (valid && startDate.isValid() && endDate.isValid()) {
- active = (startDate <= QDate::currentDate() && endDate >= QDate::currentDate());
+ // Reorder script list
+ foreach(const QString &script, mAvailableScripts) {
+ if (!scriptList.contains(script)) {
+ scriptList.append(script);
}
}
- Q_EMIT scriptActive(active, mServerName);
+ mAvailableScripts = scriptList;
+ mScriptPos = 0;
+ getNextScript();
+}
+
+void VacationCheckJob::getNextScript()
+{
+ if (isLastScript()) {
+ //TODO: no script found
+ mNoScriptFound = true;
+ emit scriptActive(this, QString(), false);
+ qDebug(LIBKSIEVE_LOG) << "no vacation script found :(";
+ }
+ QUrl url = mUrl;
+ url = url.adjusted(QUrl::RemoveFilename);
+ url.setPath(url.path() + mAvailableScripts[mScriptPos]);
+ mScriptPos += 1;
+ if (Util::isKep14ProtectedName(url.fileName())) {
+ getNextScript();
+ }
+ mSieveJob = KManageSieve::SieveJob::get(url);
+ mSieveJob->setInteractive(false);
+ connect(mSieveJob, &KManageSieve::SieveJob::gotScript, this, &VacationCheckJob::slotGetResult);
+}
+
+bool VacationCheckJob::isLastScript() const
+{
+ return mScriptPos >= mAvailableScripts.count();
+}
+
+bool VacationCheckJob::noScriptFound()
+{
+ return mNoScriptFound;
+}
+
+QString VacationCheckJob::serverName()
+{
+ return mServerName;
}
+
+QString VacationCheckJob::script()
+{
+ return mScript;
+}
+
+QStringList VacationCheckJob::sieveCapabilities()
+{
+ return mSieveCapabilities;
+}
+
Index: libksieve/src/ksieveui/vacation/vacationcreatescriptjob.h
===================================================================
--- libksieve/src/ksieveui/vacation/vacationcreatescriptjob.h
+++ libksieve/src/ksieveui/vacation/vacationcreatescriptjob.h
@@ -29,36 +29,49 @@
namespace KSieveUi
{
+class ParseUserScriptJob;
+class GenerateGlobalScriptJob;
class VacationCreateScriptJob : public QObject
{
Q_OBJECT
public:
explicit VacationCreateScriptJob(QObject *parent = Q_NULLPTR);
~VacationCreateScriptJob();
void start();
+ void kill();
void setServerUrl(const QUrl &url);
void setScript(const QString &script);
void setServerName(const QString &servername);
+ const QString &serverName() const;
void setStatus(bool activate, bool wasActive);
+ void setKep14Support(bool kep14Support);
Q_SIGNALS:
void result(bool);
void scriptActive(bool activated, const QString &serverName);
private Q_SLOTS:
- void slotPutActiveResult(KManageSieve::SieveJob *job, bool success);
- void slotPutInactiveResult(KManageSieve::SieveJob *job, bool success);
+ void slotPutResult(KManageSieve::SieveJob *job, bool success);
+ void slotGetScript(KManageSieve::SieveJob *job, bool success, const QString &oldScript, bool active);
+ void slotGotActiveScripts(ParseUserScriptJob *job);
+ void slotGenerateDone(const QString &error=QString());
private:
- void handlePutResult(KManageSieve::SieveJob *, bool success, bool activated);
+ void handleResult();
QUrl mUrl;
QString mScript;
QString mServerName;
bool mActivate;
- bool mWasActive;
+ bool mScriptActive;
+ bool mKep14Support;
+ bool mUserJobRunning;
+ bool mScriptJobRunning;
+ bool mSuccess;
KManageSieve::SieveJob *mSieveJob;
+ ParseUserScriptJob *mParseUserJob;
+ GenerateGlobalScriptJob *mCreateJob;
};
}
Index: libksieve/src/ksieveui/vacation/vacationcreatescriptjob.cpp
===================================================================
--- libksieve/src/ksieveui/vacation/vacationcreatescriptjob.cpp
+++ libksieve/src/ksieveui/vacation/vacationcreatescriptjob.cpp
@@ -16,6 +16,9 @@
*/
#include "vacationcreatescriptjob.h"
+#include "vacationutils.h"
+#include
+#include
#include
#include
@@ -25,43 +28,63 @@
using namespace KSieveUi;
VacationCreateScriptJob::VacationCreateScriptJob(QObject *parent)
- : QObject(parent),
- mActivate(false),
- mWasActive(false),
- mSieveJob(Q_NULLPTR)
+ : QObject(parent)
+ , mActivate(false)
+ , mScriptActive(false)
+ , mKep14Support(false)
+ , mUserJobRunning(false)
+ , mScriptJobRunning(false)
+ , mSuccess(true)
+ , mSieveJob(Q_NULLPTR)
+ , mParseUserJob(Q_NULLPTR)
+ , mCreateJob(Q_NULLPTR)
{
}
VacationCreateScriptJob::~VacationCreateScriptJob()
{
+ kill();
+}
+
+void VacationCreateScriptJob::kill()
+{
+ if (mSieveJob) {
+ mSieveJob->kill();
+ }
+ mSieveJob = Q_NULLPTR;
+
+ if (mParseUserJob) {
+ mParseUserJob->kill();
+ }
+ mParseUserJob = Q_NULLPTR;
+ if (mCreateJob) {
+ mCreateJob->kill();
}
+ mParseUserJob = Q_NULLPTR;
+}
+
void VacationCreateScriptJob::setStatus(bool activate, bool wasActive)
{
mActivate = activate;
- mWasActive = wasActive;
+ mScriptActive = wasActive;
}
void VacationCreateScriptJob::setServerName(const QString &servername)
{
mServerName = servername;
}
-void VacationCreateScriptJob::start()
+const QString &VacationCreateScriptJob::serverName() const
{
- if (mUrl.isEmpty()) {
- qCDebug(LIBKSIEVE_LOG) << " server url is empty";
- deleteLater();
- return;
- }
- mSieveJob = KManageSieve::SieveJob::put(mUrl, mScript, mActivate, mWasActive);
- if (mActivate) {
- connect(mSieveJob, &KManageSieve::SieveJob::gotScript, this, &VacationCreateScriptJob::slotPutActiveResult);
- } else {
- connect(mSieveJob, &KManageSieve::SieveJob::gotScript, this, &VacationCreateScriptJob::slotPutInactiveResult);
- }
+ return mServerName;
+}
+
+void VacationCreateScriptJob::setKep14Support(bool kep14Support)
+{
+ mKep14Support = kep14Support;
}
void VacationCreateScriptJob::setServerUrl(const QUrl &url)
@@ -74,28 +97,108 @@
mScript = script;
}
-void VacationCreateScriptJob::slotPutActiveResult(KManageSieve::SieveJob *job, bool success)
+void VacationCreateScriptJob::start()
{
- handlePutResult(job, success, true);
+ if (mUrl.isEmpty()) {
+ qDebug()<<" server url is empty";
+ deleteLater();
+ return;
+ }
+
+ mUserJobRunning = false;
+ mScriptJobRunning = true;
+ mSieveJob = KManageSieve::SieveJob::get(mUrl);
+ mSieveJob->setInteractive(false);
+ connect(mSieveJob, &KManageSieve::SieveJob::gotScript, this, &VacationCreateScriptJob::slotGetScript);
+
+ if (mKep14Support && mActivate && !mScriptActive) {
+ mUserJobRunning = true;
+ QUrl url = mUrl;
+ url = url.adjusted(QUrl::RemoveFilename);
+ url.setPath(url.path() + QLatin1String("USER"));
+ mParseUserJob = new ParseUserScriptJob(url, this);
+ connect(mParseUserJob, &ParseUserScriptJob::finished, this, &VacationCreateScriptJob::slotGotActiveScripts);
+ mParseUserJob->start();
+ }
+}
+
+void VacationCreateScriptJob::slotGetScript(KManageSieve::SieveJob *job, bool success, const QString &oldScript, bool active)
+{
+ Q_UNUSED(active)
+ Q_ASSERT(job == mSieveJob);
+ mSieveJob = Q_NULLPTR;
+ QString script = mScript;
+ if (success || !oldScript.trimmed().isEmpty()) {
+ script = VacationUtils::mergeRequireLine(oldScript, mScript);
+ script = VacationUtils::updateVacationBlock(oldScript,mScript);
+ }
+ if (mKep14Support) {
+ mSieveJob = KManageSieve::SieveJob::put( mUrl, mScript, false, false );
+ } else {
+ mSieveJob = KManageSieve::SieveJob::put( mUrl, mScript, mActivate, false ); //Never deactivate
+ }
+ connect(mSieveJob, &KManageSieve::SieveJob::gotScript, this, &VacationCreateScriptJob::slotPutResult);
}
-void VacationCreateScriptJob::slotPutInactiveResult(KManageSieve::SieveJob *job, bool success)
+void VacationCreateScriptJob::slotPutResult( KManageSieve::SieveJob * job, bool success )
{
- handlePutResult(job, success, false);
+ Q_ASSERT(job == mSieveJob);
+ mSieveJob = Q_NULLPTR;
+ mScriptJobRunning = false;
+ if (!success) {
+ mSuccess = false;
+ }
+ handleResult();
}
-void VacationCreateScriptJob::handlePutResult(KManageSieve::SieveJob *, bool success, bool activated)
+void VacationCreateScriptJob::handleResult()
{
- if (success)
- KMessageBox::information(Q_NULLPTR, activated
+ if (mUserJobRunning || mScriptJobRunning) { // Not both jobs are done
+ return;
+ }
+
+ if (mSuccess)
+ KMessageBox::information(Q_NULLPTR, mActivate
? i18n("Sieve script installed successfully on the server \'%1\'.\n"
"Out of Office reply is now active.", mServerName)
: i18n("Sieve script installed successfully on the server \'%1\'.\n"
"Out of Office reply has been deactivated.", mServerName));
- qCDebug(LIBKSIEVE_LOG) << "( ???," << success << ", ? )";
+ qCDebug(LIBKSIEVE_LOG) << "( ???," << mSuccess << ", ? )";
mSieveJob = Q_NULLPTR; // job deletes itself after returning from this slot!
- Q_EMIT result(success);
- Q_EMIT scriptActive(activated, mServerName);
+ Q_EMIT result(mSuccess);
+ Q_EMIT scriptActive(mActivate, mServerName);
deleteLater();
}
+
+void VacationCreateScriptJob::slotGotActiveScripts(ParseUserScriptJob *job)
+{
+ Q_ASSERT(job == mParseUserJob);
+ mParseUserJob = Q_NULLPTR;
+ if (!job->error().isEmpty()) {
+ slotGenerateDone(job->error());
+ return;
+ }
+
+ QStringList list = job->activeScriptList();
+
+ if (!list.contains(mUrl.fileName())) {
+ list.prepend(mUrl.fileName());
+ mCreateJob = new GenerateGlobalScriptJob(mUrl, this);
+ mCreateJob->addUserActiveScripts(list);
+ connect( mCreateJob, SIGNAL(success()), SLOT(slotGenerateDone()));
+ connect( mCreateJob, SIGNAL(error(QString)), SLOT(slotGenerateDone(QString)));
+ mCreateJob->start();
+ }
+}
+
+void VacationCreateScriptJob::slotGenerateDone(const QString &error)
+{
+ mCreateJob = Q_NULLPTR;
+ mUserJobRunning = false;
+ if (!error.isEmpty()) {
+ qWarning() << error;
+ mSuccess = false;
+ }
+ handleResult();
+}
Index: libksieve/src/ksieveui/vacation/vacationdialog.h
===================================================================
--- libksieve/src/ksieveui/vacation/vacationdialog.h
+++ libksieve/src/ksieveui/vacation/vacationdialog.h
@@ -14,10 +14,13 @@
#ifndef KSIEVE_KSIEVEUI_VACATIONDIALOG_H
#define KSIEVE_KSIEVEUI_VACATIONDIALOG_H
+#include "vacationutils.h"
+
#include
template class QList;
class QDate;
+class QTime;
namespace KMime
{
@@ -55,6 +58,10 @@
QString subject() const;
void setSubject(const QString &subject);
+ VacationUtils::MailAction mailAction() const;
+ QString mailActionRecipient() const;
+ void setMailAction (KSieveUi::VacationUtils::MailAction action, const QString &recipient);
+
int notificationInterval() const;
void setNotificationInterval(int days);
@@ -71,9 +78,15 @@
QDate startDate() const;
void setStartDate(const QDate &startDate);
+ QTime startTime() const;
+ void setStartTime(const QTime &startTime);
+
QDate endDate() const;
void setEndDate(const QDate &endDate);
+ QTime endTime() const;
+ void setEndTime(const QTime &endTime);
+
Q_SIGNALS:
void okClicked();
void cancelClicked();
Index: libksieve/src/ksieveui/vacation/vacationdialog.cpp
===================================================================
--- libksieve/src/ksieveui/vacation/vacationdialog.cpp
+++ libksieve/src/ksieveui/vacation/vacationdialog.cpp
@@ -128,6 +128,21 @@
return mVacationEditWidget->setSubject(subject);
}
+VacationUtils::MailAction VacationDialog::mailAction() const
+{
+ return mVacationEditWidget->mailAction();
+}
+
+QString VacationDialog::mailActionRecipient() const
+{
+ return mVacationEditWidget->mailActionRecipient();
+}
+
+void VacationDialog::setMailAction(VacationUtils::MailAction action, const QString& recipient)
+{
+ mVacationEditWidget->setMailAction(action, recipient);
+}
+
int VacationDialog::notificationInterval() const
{
return mVacationEditWidget->notificationInterval();
@@ -208,6 +223,16 @@
mVacationEditWidget->setEndDate(endDate);
}
+QTime VacationDialog::endTime() const
+{
+ return mVacationEditWidget->endTime();
+}
+
+void VacationDialog::setEndTime(const QTime &endTime)
+{
+ mVacationEditWidget->setEndTime(endTime);
+}
+
QDate VacationDialog::startDate() const
{
return mVacationEditWidget->startDate();
@@ -217,3 +242,13 @@
{
mVacationEditWidget->setStartDate(startDate);
}
+
+QTime VacationDialog::startTime() const
+{
+ return mVacationEditWidget->startTime();
+}
+
+void VacationDialog::setStartTime(const QTime &startTime)
+{
+ mVacationEditWidget->setStartTime(startTime);
+}
Index: libksieve/src/ksieveui/vacation/vacationeditwidget.h
===================================================================
--- libksieve/src/ksieveui/vacation/vacationeditwidget.h
+++ libksieve/src/ksieveui/vacation/vacationeditwidget.h
@@ -19,6 +19,13 @@
#define VACATIONEDITWIDGET_H
#include
+#include "vacationutils.h"
+class KDateComboBox;
+class KTimeComboBox;
+
+class QComboBox;
+class QDate;
+class QTime;
class QLabel;
class QSpinBox;
@@ -83,13 +90,24 @@
QDate startDate() const;
void setStartDate(const QDate &startDate);
+ QTime startTime() const;
+ void setStartTime(const QTime &startTime);
+
QDate endDate() const;
void setEndDate(const QDate &endDate);
+ QTime endTime() const;
+ void setEndTime(const QTime &endTime);
+
+ VacationUtils::MailAction mailAction() const;
+ QString mailActionRecipient() const;
+ void setMailAction(VacationUtils::MailAction action, const QString &recipient);
+
void setDefault();
private Q_SLOTS:
void slotIntervalSpinChanged(int value);
+ void mailActionChanged(int index);
protected:
QCheckBox *mActiveCheck;
@@ -100,9 +118,15 @@
QCheckBox *mDomainCheck;
QLineEdit *mDomainEdit;
QLineEdit *mSubject;
+ QComboBox *mMailAction;
+ QLineEdit *mMailActionRecipient;
KDateComboBox *mStartDate;
+ KTimeComboBox *mStartTime;
+ QCheckBox *mStartTimeActive;
QLabel *mStartDateLabel;
KDateComboBox *mEndDate;
+ KTimeComboBox *mEndTime;
+ QCheckBox *mEndTimeActive;
QLabel *mEndDateLabel;
};
}
Index: libksieve/src/ksieveui/vacation/vacationeditwidget.cpp
===================================================================
--- libksieve/src/ksieveui/vacation/vacationeditwidget.cpp
+++ libksieve/src/ksieveui/vacation/vacationeditwidget.cpp
@@ -20,17 +20,21 @@
#include
#include
+#include
#include
#include
+#include "libksieve_debug.h"
+
#include
#include
#include
#include
#include
#include
+#include
using KMime::Types::AddrSpecList;
using KMime::Types::AddressList;
@@ -75,22 +79,51 @@
glay->addWidget(tmpLabel, row, 0);
glay->addWidget(mSubject, row, 1);
+ QHBoxLayout *timeLayout = new QHBoxLayout(this);
// Start date
- ++row;
mStartDate = new KDateComboBox(this);
mStartDate->setObjectName(QStringLiteral("mStartDate"));
mStartDate->setOptions(KDateComboBox::EditDate | KDateComboBox::SelectDate | KDateComboBox::DatePicker | KDateComboBox::DateKeywords);
+
+ mStartTime = new KTimeComboBox(this);
+ mStartTime->setObjectName(QStringLiteral("mStartTime"));
+ mStartTime->setOptions(KTimeComboBox::EditTime | KTimeComboBox::SelectTime | KTimeComboBox::EditTime | KTimeComboBox::WarnOnInvalid);
+ mStartTime->setEnabled(false); // Disable by default - we need an extension to support this
+
+ mStartTimeActive = new QCheckBox(this);
+ connect(mStartTimeActive, &QCheckBox::toggled, mStartTime, &KTimeComboBox::setEnabled);
+
+ timeLayout->addWidget(mStartDate);
+ timeLayout->addWidget(mStartTimeActive);
+ timeLayout->addWidget(mStartTime);
+
+ ++row;
mStartDateLabel = new QLabel(i18n("&Start date:"), this);
mStartDateLabel->setObjectName(QStringLiteral("mStartDateLabel"));
mStartDateLabel->setBuddy(mStartDate);
glay->addWidget(mStartDateLabel, row, 0);
- glay->addWidget(mStartDate, row, 1);
+ glay->addLayout(timeLayout, row, 1);
// End date
- ++row;
+ timeLayout = new QHBoxLayout(this);
+
mEndDate = new KDateComboBox(this);
mEndDate->setObjectName(QStringLiteral("mEndDate"));
mEndDate->setOptions(KDateComboBox::EditDate | KDateComboBox::SelectDate | KDateComboBox::DatePicker | KDateComboBox::DateKeywords);
+
+ mEndTime = new KTimeComboBox(this);
+ mEndTime->setObjectName(QStringLiteral("mEndTime"));
+ mEndTime->setOptions(KTimeComboBox::EditTime | KTimeComboBox::SelectTime | KTimeComboBox::EditTime | KTimeComboBox::WarnOnInvalid);
+ mEndTime->setEnabled(false); // Disable by default - we need an extension to support this
+
+ mEndTimeActive = new QCheckBox(this);
+ connect(mEndTimeActive, &QCheckBox::toggled, mEndTime, &KTimeComboBox::setEnabled);
+
+ timeLayout->addWidget(mEndDate);
+ timeLayout->addWidget(mEndTimeActive);
+ timeLayout->addWidget(mEndTime);
+
+ ++row;
mEndDateLabel = new QLabel(i18n("&End date:"), this);
mEndDateLabel->setObjectName(QStringLiteral("mStartDateLabel"));
mEndDateLabel->setBuddy(mEndDate);
@@ -127,6 +160,30 @@
glay->addWidget(tmpLabel, row, 0);
glay->addWidget(mMailAliasesEdit, row, 1);
+ // Action for incomming mails
+ mMailAction = new QComboBox(this);
+ for (int i=0; i<4; i++) {
+ mMailAction->addItem(VacationUtils::mailAction((VacationUtils::MailAction) i));
+ }
+ mMailAction->setObjectName(QStringLiteral("mMailAction"));
+ connect(mMailAction, static_cast(&QComboBox::currentIndexChanged), this, &VacationEditWidget::mailActionChanged);
+
+ mMailActionRecipient = new QLineEdit(this);
+ mMailActionRecipient->setObjectName(QStringLiteral("mMailActionRecipient"));
+ mMailActionRecipient->setClearButtonEnabled(true);
+ mMailActionRecipient->setEnabled(false);
+
+ QHBoxLayout *hLayout = new QHBoxLayout(this);
+
+ hLayout->addWidget(mMailAction);
+ hLayout->addWidget(mMailActionRecipient);
+
+ ++row;
+ tmpLabel = new QLabel(i18n("&Action for incomming mails:"), this);
+ tmpLabel->setBuddy(mMailAction);
+ glay->addWidget(tmpLabel, row, 0);
+ glay->addLayout(hLayout, row, 1);
+
// "Send responses also to SPAM mail" checkbox:
++row;
mSpamCheck = new QCheckBox(i18n("Do not send vacation replies to spam messages"), this);
@@ -271,6 +328,22 @@
mEndDate->setDate(endDate);
}
+QTime VacationEditWidget::endTime() const
+{
+ if (mEndTime->isEnabled()) {
+ return mEndTime->time();
+ } else {
+ return QTime();
+ }
+}
+
+void VacationEditWidget::setEndTime(const QTime &endTime)
+{
+ mEndTimeActive->setChecked(endTime.isValid());
+ mEndTime->setEnabled(endTime.isValid());
+ mEndTime->setTime(endTime);
+}
+
QDate VacationEditWidget::startDate() const
{
if (mStartDate->isEnabled()) {
@@ -285,6 +358,22 @@
mStartDate->setDate(startDate);
}
+QTime VacationEditWidget::startTime() const
+{
+ if (mStartTime->isEnabled()) {
+ return mStartTime->time();
+ } else {
+ return QTime();
+ }
+}
+
+void VacationEditWidget::setStartTime(const QTime &startTime)
+{
+ mStartTimeActive->setChecked(startTime.isValid());
+ mStartTime->setEnabled(startTime.isValid());
+ mStartTime->setTime(startTime);
+}
+
void VacationEditWidget::setSubject(const QString &subject)
{
mSubject->setText(subject);
@@ -307,6 +396,29 @@
mEndDateLabel->setVisible(enable);
}
+void VacationEditWidget::mailActionChanged(int action)
+{
+ bool enable = (action == VacationUtils::CopyTo || action == VacationUtils::Sendto);
+ mMailActionRecipient->setEnabled(enable);
+}
+
+
+void VacationEditWidget::setMailAction(VacationUtils::MailAction action, const QString &recipient)
+{
+ mMailAction->setCurrentIndex(action);
+ mMailActionRecipient->setText(recipient);
+}
+
+VacationUtils::MailAction VacationEditWidget::mailAction() const
+{
+ return (VacationUtils::MailAction) mMailAction->currentIndex();
+}
+
+QString VacationEditWidget::mailActionRecipient() const
+{
+ return mMailActionRecipient->text();
+}
+
void VacationEditWidget::enableDomainAndSendForSpam(bool enable)
{
mDomainCheck->setEnabled(enable);
@@ -320,8 +432,9 @@
setMessageText(VacationUtils::defaultMessageText());
setSubject(VacationUtils::defaultSubject());
setNotificationInterval(VacationUtils::defaultNotificationInterval());
- setMailAliases(VacationUtils::defaultMailAliases().join(QStringLiteral(", ")));
+ setMailAliases(VacationUtils::defaultMailAliases());
setSendForSpam(VacationUtils::defaultSendForSpam());
setDomainName(VacationUtils::defaultDomainName());
+ setMailAction(VacationUtils::defaultMailAction(), QString());
setDomainCheck(false);
}
Index: libksieve/src/ksieveui/vacation/vacationmanager.h
===================================================================
--- libksieve/src/ksieveui/vacation/vacationmanager.h
+++ libksieve/src/ksieveui/vacation/vacationmanager.h
@@ -40,12 +40,13 @@
void slotEditVacation(const QString &serverName);
Q_SIGNALS:
- void updateVacationScriptStatus(bool, const QString &);
+ void updateVacationScriptStatus(bool active, const QString &serverName);
void editVacation();
private Q_SLOTS:
void slotDialogCanceled();
void slotDialogOk();
+ void slotUpdateVacationScriptStatus(bool active, const QString &serverName);
private:
VacationManagerPrivate *const d;
Index: libksieve/src/ksieveui/vacation/vacationmanager.cpp
===================================================================
--- libksieve/src/ksieveui/vacation/vacationmanager.cpp
+++ libksieve/src/ksieveui/vacation/vacationmanager.cpp
@@ -22,26 +22,36 @@
#include
+#include
+#include
+
using namespace KSieveUi;
class KSieveUi::VacationManagerPrivate
{
public:
VacationManagerPrivate(QWidget *parent)
: mWidget(parent)
+ , mMultiImapVacationDialog(Q_NULLPTR)
+ , mCheckVacation(Q_NULLPTR)
+ , mQuestionAsked(false)
{
}
+ QWidget *mWidget;
QPointer mMultiImapVacationDialog;
QPointer mCheckVacation;
- QWidget *mWidget;
+ bool mQuestionAsked;
};
VacationManager::VacationManager(QWidget *parent)
: QObject(parent),
d(new KSieveUi::VacationManagerPrivate(parent))
{
+ d->mCheckVacation = new KSieveUi::MultiImapVacationManager(this);
+ connect(d->mCheckVacation.data(), &KSieveUi::MultiImapVacationManager::scriptActive, this, &VacationManager::updateVacationScriptStatus);
+ connect(d->mCheckVacation.data(), &KSieveUi::MultiImapVacationManager::scriptActive, this, &VacationManager::slotUpdateVacationScriptStatus);
}
VacationManager::~VacationManager()
@@ -51,30 +61,38 @@
void VacationManager::checkVacation()
{
- delete d->mCheckVacation;
-
- d->mCheckVacation = new KSieveUi::MultiImapVacationManager(this);
- connect(d->mCheckVacation.data(), &MultiImapVacationManager::scriptActive, this, &VacationManager::updateVacationScriptStatus);
- connect(d->mCheckVacation.data(), &MultiImapVacationManager::requestEditVacation, this, &VacationManager::editVacation);
d->mCheckVacation->checkVacation();
}
+void VacationManager::slotUpdateVacationScriptStatus(bool active, const QString &serverName)
+{
+ if (active) {
+ if (!d->mQuestionAsked) {
+ d->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 (d->mMultiImapVacationDialog) {
- d->mMultiImapVacationDialog->show();
d->mMultiImapVacationDialog->raise();
d->mMultiImapVacationDialog->activateWindow();
- if (!serverName.isEmpty()) {
- d->mMultiImapVacationDialog->switchToServerNamePage(serverName);
- }
- return;
+ } else {
+ d->mMultiImapVacationDialog = new KSieveUi::MultiImapVacationDialog(d->mCheckVacation, d->mWidget);
+ connect(d->mMultiImapVacationDialog.data(), &KSieveUi::MultiImapVacationDialog::okClicked, this, &VacationManager::slotDialogOk);
+ connect(d->mMultiImapVacationDialog.data(), &KSieveUi::MultiImapVacationDialog::cancelClicked, this, &VacationManager::slotDialogCanceled);
}
-
- d->mMultiImapVacationDialog = new KSieveUi::MultiImapVacationDialog(d->mWidget);
- connect(d->mMultiImapVacationDialog.data(), &KSieveUi::MultiImapVacationDialog::okClicked, this, &VacationManager::slotDialogOk);
- connect(d->mMultiImapVacationDialog.data(), &KSieveUi::MultiImapVacationDialog::cancelClicked, this, &VacationManager::slotDialogCanceled);
d->mMultiImapVacationDialog->show();
+
if (!serverName.isEmpty()) {
d->mMultiImapVacationDialog->switchToServerNamePage(serverName);
}
@@ -96,6 +114,7 @@
QList listJob = d->mMultiImapVacationDialog->listCreateJob();
Q_FOREACH (KSieveUi::VacationCreateScriptJob *job, listJob) {
connect(job, &VacationCreateScriptJob::scriptActive, this, &VacationManager::updateVacationScriptStatus);
+ job->setKep14Support(d->mCheckVacation->kep14Support(job->serverName()));
job->start();
}
if (d->mMultiImapVacationDialog->isVisible()) {
Index: libksieve/src/ksieveui/vacation/vacationpagewidget.h
===================================================================
--- libksieve/src/ksieveui/vacation/vacationpagewidget.h
+++ libksieve/src/ksieveui/vacation/vacationpagewidget.h
@@ -31,6 +31,8 @@
class VacationEditWidget;
class VacationWarningWidget;
class VacationCreateScriptJob;
+class MultiImapVacationManager;
+class ParseUserScriptJob;
class VacationPageWidget : public QWidget
{
Q_OBJECT
@@ -42,11 +44,15 @@
void setServerName(const QString &serverName);
KSieveUi::VacationCreateScriptJob *writeScript();
void setDefault();
+ void setVacationManager(MultiImapVacationManager *vacationManager);
private Q_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
@@ -57,7 +63,7 @@
QStackedWidget *mStackWidget;
VacationEditWidget *mVacationEditWidget;
VacationWarningWidget *mVacationWarningWidget;
- KManageSieve::SieveJob *mSieveJob;
+ MultiImapVacationManager *mVacationManager;
PageType mPageScript;
bool mWasActive;
bool mHasDateSupport;
Index: libksieve/src/ksieveui/vacation/vacationpagewidget.cpp
===================================================================
--- libksieve/src/ksieveui/vacation/vacationpagewidget.cpp
+++ libksieve/src/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
@@ -33,10 +35,11 @@
#include
#include
+#include "libksieve_debug.h"
+
using namespace KSieveUi;
VacationPageWidget::VacationPageWidget(QWidget *parent)
: QWidget(parent),
- mSieveJob(Q_NULLPTR),
mPageScript(Script),
mWasActive(false),
mHasDateSupport(false)
@@ -80,90 +83,97 @@
VacationPageWidget::~VacationPageWidget()
{
- if (mSieveJob) {
- mSieveJob->kill();
- }
- mSieveJob = Q_NULLPTR;
}
void VacationPageWidget::setServerUrl(const QUrl &url)
{
mUrl = url;
mVacationEditWidget->setEnabled(false);
- mSieveJob = KManageSieve::SieveJob::get(url);
- connect(mSieveJob, &KManageSieve::SieveJob::gotScript, this, &VacationPageWidget::slotGetResult);
+}
+
+void VacationPageWidget::setVacationManager(MultiImapVacationManager *vacationManager)
+{
+ mVacationManager = vacationManager;
+ connect(mVacationManager, &MultiImapVacationManager::scriptAvailable, this, &VacationPageWidget::slotGetResult);
+ mVacationManager->checkVacation(mServerName, mUrl);
}
void VacationPageWidget::setServerName(const QString &serverName)
{
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)
{
- qCDebug(LIBKSIEVE_LOG) << success
- << ", ?," << active << ")" << endl
- << "script:" << endl
- << script;
- mSieveJob = Q_NULLPTR; // job deletes itself after returning from this slot!
-
- if (mUrl.scheme() == QLatin1String("sieve") &&
- !job->sieveCapabilities().contains(QStringLiteral("vacation"))) {
+ Q_ASSERT(mServerName == serverName);
+ qCDebug(LIBKSIEVE_LOG) << serverName << sieveCapabilities << endl
+ << scriptName << "(" << active << ")" << endl;
+
+
+ if (mUrl.scheme() == QStringLiteral("sieve") &&
+ !sieveCapabilities.contains(QStringLiteral("vacation"))) {
mStackWidget->setCurrentIndex(ScriptNotSupported);
return;
}
- mVacationEditWidget->setEnabled(true);
- QString messageText = VacationUtils::defaultMessageText();
- QString subject = VacationUtils::defaultSubject();
- int notificationInterval = VacationUtils::defaultNotificationInterval();
- QStringList aliases = VacationUtils::defaultMailAliases();
- bool sendForSpam = VacationUtils::defaultSendForSpam();
- QString domainName = VacationUtils::defaultDomainName();
- QDate startDate = VacationUtils::defaultStartDate();
- QDate endDate = VacationUtils::defaultEndDate();
- if (!success) {
- active = false; // default to inactive
- }
+ mUrl = mUrl.adjusted(QUrl::RemoveFilename);
+ mUrl.setPath(mUrl.path() + scriptName);
+
+ // Whether the server supports the "date" extension
+ const bool supportsSieveDate = mUrl.scheme() == QStringLiteral("sieve") && sieveCapabilities.contains(QStringLiteral("date"));
- if ((!success || !KSieveUi::VacationUtils::parseScript(script, messageText, subject, notificationInterval, aliases, sendForSpam, domainName, startDate, endDate))) {
+ KSieveUi::VacationUtils::Vacation vacation = KSieveUi::VacationUtils::parseScript(script);
+
+ if (!vacation.isValid() && !script.trimmed().isEmpty()) {
mVacationWarningWidget->setVisible(true);
}
mWasActive = active;
- mVacationEditWidget->setActivateVacation(active);
- mVacationEditWidget->setMessageText(messageText);
- mVacationEditWidget->setSubject(subject);
- mVacationEditWidget->setNotificationInterval(notificationInterval);
- mVacationEditWidget->setMailAliases(aliases.join(QStringLiteral(", ")));
- mVacationEditWidget->setSendForSpam(sendForSpam);
- mVacationEditWidget->setDomainName(domainName);
+ mVacationEditWidget->setEnabled(true);
+ mVacationEditWidget->setActivateVacation(active && vacation.active);
+ mVacationEditWidget->setMessageText(vacation.messageText);
+ mVacationEditWidget->setSubject(vacation.subject);
+ mVacationEditWidget->setMailAction(vacation.mailAction, vacation.mailActionRecipient);
+ mVacationEditWidget->setNotificationInterval(vacation.notificationInterval);
+ mVacationEditWidget->setMailAliases(vacation.aliases);
+ mVacationEditWidget->setSendForSpam(vacation.sendForSpam);
+ mVacationEditWidget->setDomainName(vacation.excludeDomain);
mVacationEditWidget->enableDomainAndSendForSpam(!VacationSettings::allowOutOfOfficeUploadButNoSettings());
- mHasDateSupport = job->sieveCapabilities().contains(QStringLiteral("date"));
- mVacationEditWidget->enableDates(mHasDateSupport);
- mVacationEditWidget->setStartDate(mHasDateSupport ? startDate : QDate());
- mVacationEditWidget->setEndDate(mHasDateSupport ? endDate : QDate());
- //Q_EMIT scriptActive( mWasActive, mServerName );
+ mVacationEditWidget->enableDates(supportsSieveDate);
+ if (supportsSieveDate) {
+ mVacationEditWidget->setStartDate(vacation.startDate);
+ mVacationEditWidget->setStartTime(vacation.startTime);
+ mVacationEditWidget->setEndDate(vacation.endDate);
+ mVacationEditWidget->setEndTime(vacation.endTime);
+ }
}
KSieveUi::VacationCreateScriptJob *VacationPageWidget::writeScript()
{
if (mPageScript == Script) {
KSieveUi::VacationCreateScriptJob *createJob = new KSieveUi::VacationCreateScriptJob;
createJob->setServerUrl(mUrl);
createJob->setServerName(mServerName);
- const QString script = VacationUtils::composeScript(mVacationEditWidget->messageText(),
- mVacationEditWidget->subject(),
- mVacationEditWidget->notificationInterval(),
- mVacationEditWidget->mailAliases(),
- mVacationEditWidget->sendForSpam(),
- mVacationEditWidget->domainName(),
- mHasDateSupport ? mVacationEditWidget->startDate() : QDate(),
- mHasDateSupport ? mVacationEditWidget->endDate() : QDate());
const bool active = mVacationEditWidget->activateVacation();
+ VacationUtils::Vacation vacation;
+ vacation.valid = true;
+ vacation.active = active;
+ vacation.messageText = mVacationEditWidget->messageText();
+ vacation.subject = mVacationEditWidget->subject();
+ vacation.mailAction = mVacationEditWidget->mailAction();
+ vacation.mailActionRecipient = mVacationEditWidget->mailActionRecipient();
+ vacation.notificationInterval = mVacationEditWidget->notificationInterval();
+ vacation.aliases = mVacationEditWidget->mailAliases();
+ vacation.sendForSpam = mVacationEditWidget->sendForSpam();
+ vacation.excludeDomain = mVacationEditWidget->domainName();
+ vacation.startDate = mVacationEditWidget->startDate();
+ vacation.startTime = mVacationEditWidget->startTime();
+ vacation.endDate = mVacationEditWidget->endDate();
+ vacation.endTime = mVacationEditWidget->endTime();
+ const QString script = VacationUtils::composeScript(vacation);
createJob->setStatus(active, mWasActive);
- //Q_EMIT scriptActive( active, mServerName);
+ //Q_EMIT scriptActive(active, mServerName);
createJob->setScript(script);
return createJob;
}
Index: libksieve/src/ksieveui/vacation/vacationscriptextractor.h
===================================================================
--- libksieve/src/ksieveui/vacation/vacationscriptextractor.h
+++ libksieve/src/ksieveui/vacation/vacationscriptextractor.h
@@ -20,6 +20,7 @@
#include "sieve-vacation.h"
#include "util/util.h"
+#include "vacationutils.h"
#include
#include
@@ -82,12 +83,12 @@
#ifdef FOREACH
#undef FOREACH
#endif
-#define FOREACH for ( std::vector::const_iterator it = mBuilders.begin(), end = mBuilders.end() ; it != end ; ++it ) (*it)->
- void commandStart(const QString &identifier) Q_DECL_OVERRIDE {
- FOREACH commandStart(identifier);
+#define FOREACH for (std::vector::const_iterator it = mBuilders.begin(), end = mBuilders.end() ; it != end ; ++it) (*it)->
+ void commandStart(const QString &identifier, int lineNumber) Q_DECL_OVERRIDE {
+ FOREACH commandStart(identifier, lineNumber);
}
- void commandEnd() Q_DECL_OVERRIDE {
- FOREACH commandEnd();
+ void commandEnd(int lineNumber) Q_DECL_OVERRIDE {
+ FOREACH commandEnd(lineNumber);
}
void testStart(const QString &identifier) Q_DECL_OVERRIDE {
FOREACH testStart(identifier);
@@ -101,11 +102,11 @@
void testListEnd() Q_DECL_OVERRIDE {
FOREACH testListEnd();
}
- void blockStart() Q_DECL_OVERRIDE {
- FOREACH blockStart();
+ void blockStart(int lineNumber) Q_DECL_OVERRIDE {
+ FOREACH blockStart(lineNumber);
}
- void blockEnd() Q_DECL_OVERRIDE {
- FOREACH blockEnd();
+ void blockEnd(int lineNumber) Q_DECL_OVERRIDE {
+ FOREACH blockEnd(lineNumber);
}
void hashComment(const QString &comment) Q_DECL_OVERRIDE {
FOREACH hashComment(comment);
@@ -186,21 +187,24 @@
unsigned int mState;
int mNestingDepth;
+ int mLineNumber;
+
public:
GenericInformationExtractor(const std::vector &nodes)
- : KSieve::ScriptBuilder(), mNodes(nodes), mState(0), mNestingDepth(0) {}
+ : KSieve::ScriptBuilder(), mNodes(nodes), mState(0), mNestingDepth(0), mLineNumber(0) {}
const std::map &results() const
{
return mResults;
}
private:
- void process(BuilderMethod method, const QString &string = QString())
+ virtual void process(BuilderMethod method, const QString &string = QString())
{
doProcess(method, string);
mRecursionGuard.clear();
}
+
void doProcess(BuilderMethod method, const QString &string)
{
mRecursionGuard.insert(mState);
@@ -218,7 +222,7 @@
}
qCDebug(LIBKSIEVE_LOG) << (found ? "found:" : "not found:")
<< mState << "->"
- << (found ? expected.if_found : expected.if_not_found);
+ << (found ? expected.if_found : expected.if_not_found);
mState = found ? expected.if_found : expected.if_not_found ;
assert(mState < mNodes.size());
if (found)
@@ -229,11 +233,13 @@
doProcess(method, string);
}
}
- void commandStart(const QString &identifier) Q_DECL_OVERRIDE {
+ void commandStart(const QString &identifier, int lineNumber) Q_DECL_OVERRIDE {
+ Q_UNUSED(lineNumber)
qCDebug(LIBKSIEVE_LOG) ;
process(CommandStart, identifier);
}
- void commandEnd() Q_DECL_OVERRIDE {
+ void commandEnd(int lineNumber) Q_DECL_OVERRIDE {
+ Q_UNUSED(lineNumber)
qCDebug(LIBKSIEVE_LOG) ;
process(CommandEnd);
}
@@ -253,12 +259,14 @@
qCDebug(LIBKSIEVE_LOG) ;
process(TestListEnd);
}
- void blockStart() Q_DECL_OVERRIDE {
+ void blockStart(int lineNumber) Q_DECL_OVERRIDE {
+ Q_UNUSED(lineNumber)
qCDebug(LIBKSIEVE_LOG) ;
process(BlockStart);
++mNestingDepth;
}
- void blockEnd() Q_DECL_OVERRIDE {
+ void blockEnd(int lineNumber) Q_DECL_OVERRIDE {
+ Q_UNUSED(lineNumber)
qCDebug(LIBKSIEVE_LOG) ;
--mNestingDepth;
process(BlockEnd);
@@ -308,35 +316,40 @@
typedef GenericInformationExtractor GIE;
static const GenericInformationExtractor::StateNode spamNodes[] = {
- { 0, GIE::CommandStart, "if", 1, 0, Q_NULLPTR }, // 0
- { 0, GIE::TestStart, "header", 2, 0, Q_NULLPTR }, // 1
- { 0, GIE::TaggedArgument, "contains", 3, 0, Q_NULLPTR }, // 2
+ { 0, GIE::CommandStart, "if", 1, 0, 0 }, // 0
+ { 0, GIE::TestStart, "allof", 2, 3, 0 }, // 1
+ { 0, GIE::TestListStart, 0, 3, 0, 0 }, // 2
+ { 0, GIE::TestStart, "not", 4, 3, 0 }, // 3
+ { 0, GIE::TestStart, "header", 5, 3, 0 }, // 4
+ { 0, GIE::TaggedArgument, "contains", 6, 0, 0 }, // 5
// accept both string and string-list:
- { 0, GIE::StringArgument, "x-spam-flag", 9, 4, "x-spam-flag" }, // 3
- { 0, GIE::StringListArgumentStart, Q_NULLPTR, 5, 0, Q_NULLPTR }, // 4
- { 0, GIE::StringListEntry, "x-spam-flag", 6, 7, "x-spam-flag" }, // 5
- { 0, GIE::StringListEntry, Q_NULLPTR, 6, 8, Q_NULLPTR }, // 6
- { 0, GIE::StringListArgumentEnd, Q_NULLPTR, 0, 5, Q_NULLPTR }, // 7
- { 0, GIE::StringListArgumentEnd, Q_NULLPTR, 9, 0, Q_NULLPTR }, // 8
+ { 0, GIE::StringArgument, "x-spam-flag", 12, 7, "x-spam-flag" }, // 6
+ { 0, GIE::StringListArgumentStart, 0, 8, 0, 0 }, // 7
+ { 0, GIE::StringListEntry, "x-spam-flag", 9, 10, "x-spam-flag" }, // 8
+ { 0, GIE::StringListEntry, 0, 9, 11, 0 }, // 9
+ { 0, GIE::StringListArgumentEnd, 0, 0, 8, 0 }, // 10
+ { 0, GIE::StringListArgumentEnd, 0, 12, 0, 0 }, // 11
// accept both string and string-list:
- { 0, GIE::StringArgument, "yes", 15, 10, "spam-flag-yes" }, // 9
- { 0, GIE::StringListArgumentStart, Q_NULLPTR, 11, 0, Q_NULLPTR }, // 10
- { 0, GIE::StringListEntry, "yes", 12, 13, "spam-flag-yes" }, // 11
- { 0, GIE::StringListEntry, Q_NULLPTR, 12, 14, Q_NULLPTR }, // 12
- { 0, GIE::StringListArgumentEnd, Q_NULLPTR, 0, 11, Q_NULLPTR }, // 13
- { 0, GIE::StringListArgumentEnd, Q_NULLPTR, 15, 0, Q_NULLPTR }, // 14
+ { 0, GIE::StringArgument, "yes", 18, 13, "spam-flag-yes" }, // 12
+ { 0, GIE::StringListArgumentStart, 0, 14, 0, 0 }, // 13
+ { 0, GIE::StringListEntry, "yes", 15, 16, "spam-flag-yes" }, // 14
+ { 0, GIE::StringListEntry, 0, 15, 17, 0 }, // 15
+ { 0, GIE::StringListArgumentEnd, 0, 0, 14, 0 }, // 16
+ { 0, GIE::StringListArgumentEnd, 0, 18, 0, 0 }, // 17
- { 0, GIE::TestEnd, Q_NULLPTR, 16, 0, Q_NULLPTR }, // 15
+ { 0, GIE::TestEnd, 0, 21, 20, 0 }, // 18
+ { 0, GIE::Any, 0, 21, 0, 0 }, // 19
+ { 0, GIE::TestListEnd, 0, 21, 19, 0 }, // 20
// block of command, find "stop", take nested if's into account:
- { 0, GIE::BlockStart, Q_NULLPTR, 17, 0, Q_NULLPTR }, // 16
- { 1, GIE::CommandStart, "stop", 20, 19, "stop" }, // 17
- { -1, GIE::Any, Q_NULLPTR, 17, 0, Q_NULLPTR }, // 18
- { 0, GIE::BlockEnd, Q_NULLPTR, 0, 18, Q_NULLPTR }, // 19
+ { 0, GIE::BlockStart, 0, 22, 18, 0 }, // 21
+ { 1, GIE::CommandStart, "vacation", 24, 22, "vacation" }, // 22
+ { 1, GIE::Any, 0, 24, 0, 0 }, // 23
+ { 0, GIE::BlockEnd, 0, 25, 23, 0 }, // 24
- { -1, GIE::Any, Q_NULLPTR, 20, 20, Q_NULLPTR }, // 20 end state
+ { -1, GIE::Any, 0, 25, 25, 0 }, // 25 end state
};
static const unsigned int numSpamNodes = sizeof spamNodes / sizeof *spamNodes ;
@@ -353,48 +366,49 @@
{
return mResults.count(QStringLiteral("x-spam-flag")) &&
mResults.count(QStringLiteral("spam-flag-yes")) &&
- mResults.count(QStringLiteral("stop")) ;
+ mResults.count(QStringLiteral("vacation")) ;
}
};
// to understand this table, study the output of
// libksieve/tests/parsertest
// 'if not address :domain :contains ["from"] ["mydomain.org"] { keep; stop; }'
static const GenericInformationExtractor::StateNode domainNodes[] = {
- { 0, GIE::CommandStart, "if", 1, 0, Q_NULLPTR }, // 0
- { 0, GIE::TestStart, "not", 2, 0, Q_NULLPTR, }, // 1
- { 0, GIE::TestStart, "address", 3, 0, Q_NULLPTR }, // 2
+ { 0, GIE::CommandStart, "if", 1, 0, 0 }, // 0
+ { 0, GIE::TestStart, "allof", 2, 3, 0 }, // 1
+ { 0, GIE::TestListStart, 0, 3, 0, 0 }, // 2
+ { 0, GIE::TestStart, "address", 4, 3, 0 }, // 3
// :domain and :contains in arbitrary order:
- { 0, GIE::TaggedArgument, "domain", 4, 5, Q_NULLPTR }, // 3
- { 0, GIE::TaggedArgument, "contains", 7, 0, Q_NULLPTR }, // 4
- { 0, GIE::TaggedArgument, "contains", 6, 0, Q_NULLPTR }, // 5
- { 0, GIE::TaggedArgument, "domain", 7, 0, Q_NULLPTR }, // 6
+ { 0, GIE::TaggedArgument, "domain", 5, 6, 0 }, // 4
+ { 0, GIE::TaggedArgument, "contains", 8, 0, 0 }, // 5
+ { 0, GIE::TaggedArgument, "contains", 7, 0, 0 }, // 6
+ { 0, GIE::TaggedArgument, "domain", 8, 0, 0 }, // 7
// accept both string and string-list:
- { 0, GIE::StringArgument, "from", 13, 8, "from" }, // 7
- { 0, GIE::StringListArgumentStart, Q_NULLPTR, 9, 0, Q_NULLPTR }, // 8
- { 0, GIE::StringListEntry, "from", 10, 11, "from" }, // 9
- { 0, GIE::StringListEntry, Q_NULLPTR, 10, 12, Q_NULLPTR }, // 10
- { 0, GIE::StringListArgumentEnd, Q_NULLPTR, 0, 9, Q_NULLPTR }, // 11
- { 0, GIE::StringListArgumentEnd, Q_NULLPTR, 13, 0, Q_NULLPTR }, // 12
+ { 0, GIE::StringArgument, "from", 14, 9, "from" }, // 8
+ { 0, GIE::StringListArgumentStart, 0, 10, 0, 0 }, // 9
+ { 0, GIE::StringListEntry, "from", 11, 12, "from" }, // 10
+ { 0, GIE::StringListEntry, 0, 11, 13, 0 }, // 11
+ { 0, GIE::StringListArgumentEnd, 0, 0, 10, 0 }, // 12
+ { 0, GIE::StringListArgumentEnd, 0, 14, 0, 0 }, // 13
// string: save, string-list: save last
- { 0, GIE::StringArgument, Q_NULLPTR, 17, 14, "domainName" }, // 13
- { 0, GIE::StringListArgumentStart, Q_NULLPTR, 15, 0, Q_NULLPTR }, // 14
- { 0, GIE::StringListEntry, Q_NULLPTR, 15, 16, "domainName" }, // 15
- { 0, GIE::StringListArgumentEnd, Q_NULLPTR, 17, 0, Q_NULLPTR }, // 16
+ { 0, GIE::StringArgument, 0, 18, 15, "domainName" }, // 14
+ { 0, GIE::StringListArgumentStart, 0, 16, 0, 0 }, // 15
+ { 0, GIE::StringListEntry, 0, 16, 17, "domainName" }, // 16
+ { 0, GIE::StringListArgumentEnd, 0, 18, 0, 0 }, // 17
- { 0, GIE::TestEnd, Q_NULLPTR, 18, 0, Q_NULLPTR }, // 17
- { 0, GIE::TestEnd, Q_NULLPTR, 19, 0, Q_NULLPTR }, // 18
+ { 0, GIE::TestEnd, 0, 18, 20, 0 }, // 18
+ { 0, GIE::Any, 0, 18, 0, 0 }, // 19
// block of commands, find "stop", take nested if's into account:
- { 0, GIE::BlockStart, Q_NULLPTR, 20, 0, Q_NULLPTR }, // 19
- { 1, GIE::CommandStart, "stop", 23, 22, "stop" }, // 20
- { -1, GIE::Any, Q_NULLPTR, 20, 0, Q_NULLPTR }, // 21
- { 0, GIE::BlockEnd, Q_NULLPTR, 0, 21, Q_NULLPTR }, // 22
+ { 0, GIE::BlockStart, 0, 21, 19, 0 }, // 20
+ { 1, GIE::CommandStart, "vacation", 23, 21, "vacation" }, // 21
+ { 1, GIE::Any, 0, 23, 0, 0 }, // 22
+ { 0, GIE::BlockEnd, 0, 24, 22, 0 }, // 23
- { -1, GIE::Any, Q_NULLPTR, 23, 23, Q_NULLPTR } // 23 end state
+ { -1, GIE::Any, 0, 24, 24, 0 } // 24 end state
};
static const unsigned int numDomainNodes = sizeof domainNodes / sizeof *domainNodes ;
@@ -409,51 +423,61 @@
QString domainName() /*not const, since map::op[] isn't const*/
{
- return mResults.count(QStringLiteral("stop")) && mResults.count(QStringLiteral("from"))
+ return mResults.count(QStringLiteral("vacation")) && mResults.count(QStringLiteral("from"))
? mResults[QStringLiteral("domainName")] : QString();
}
};
-// if not allof (currentDate :value "ge" date "YYYY-MM-DD",
-// currentDate :value "le" date "YYYY-MM-DD") { keep; stop; }
+// if not allof (currentdate :value "ge" date "YYYY-MM-DD",
+// currentfate :value "le" date "YYYY-MM-DD) { keep; stop; }
static const GenericInformationExtractor::StateNode datesNodes[] = {
- { 0, GIE::CommandStart, "if", 1, 0, Q_NULLPTR }, // 0
- { 0, GIE::TestStart, "not", 2, 0, Q_NULLPTR }, // 1
- { 0, GIE::TestStart, "allof", 3, 0, Q_NULLPTR }, // 2
+ { 0, GIE::CommandStart, "if", 1, 0, 0 }, // 0
+ { 0, GIE::TestStart, "allof", 2, 0, 0 }, // 1
// handle startDate and endDate in arbitrary order
- { 0, GIE::TestListStart, Q_NULLPTR, 4, 0, Q_NULLPTR }, // 3
- { 0, GIE::TestStart, "currentdate", 5, 0, Q_NULLPTR }, // 4
- { 0, GIE::TaggedArgument, "value", 6, 0, Q_NULLPTR }, // 5
- { 0, GIE::StringArgument, "ge", 7, 9, Q_NULLPTR }, // 6
- { 0, GIE::StringArgument, "date", 8, 0, Q_NULLPTR }, // 7
- { 0, GIE::StringArgument, Q_NULLPTR, 12, 0, "startDate" }, // 8
- { 0, GIE::StringArgument, "le", 10, 0, Q_NULLPTR }, // 9
- { 0, GIE::StringArgument, "date", 11, 0, Q_NULLPTR }, // 10
- { 0, GIE::StringArgument, Q_NULLPTR, 12, 0, "endDate" }, // 11
- { 0, GIE::TestEnd, Q_NULLPTR, 13, 0, Q_NULLPTR }, // 12
-
- { 0, GIE::TestStart, "currentdate", 14, 0, Q_NULLPTR }, // 13
- { 0, GIE::TaggedArgument, "value", 15, 0, Q_NULLPTR }, // 14
- { 0, GIE::StringArgument, "le", 16, 18, Q_NULLPTR }, // 15
- { 0, GIE::StringArgument, "date", 17, 0, Q_NULLPTR }, // 16
- { 0, GIE::StringArgument, Q_NULLPTR, 21, 0, "endDate" }, // 17
- { 0, GIE::StringArgument, "ge", 19, 0, Q_NULLPTR }, // 18
- { 0, GIE::StringArgument, "date", 20, 0, Q_NULLPTR }, // 19
- { 0, GIE::StringArgument, Q_NULLPTR, 21, 0, "startDate" }, // 20
- { 0, GIE::TestEnd, Q_NULLPTR, 22, 0, Q_NULLPTR }, // 21
- { 0, GIE::TestListEnd, Q_NULLPTR, 23, 0, Q_NULLPTR }, // 22
-
- { 0, GIE::TestEnd, Q_NULLPTR, 24, 0, Q_NULLPTR }, // 23
- { 0, GIE::TestEnd, Q_NULLPTR, 25, 0, Q_NULLPTR }, // 24
+ { 0, GIE::TestListStart, 0, 3, 0, 0 }, // 2
+ { 0, GIE::TestStart, "currentdate", 4, 3, 0 }, // 3
+ { 0, GIE::TaggedArgument, "value", 5, 4, 0 }, // 4
+ { 0, GIE::StringArgument, "ge", 6, 10, 0 }, // 5
+ { 0, GIE::StringArgument, "date", 7, 8, 0 }, // 6
+ { 0, GIE::StringArgument, 0, 15, 0, "startDate" }, // 7
+ { 0, GIE::StringArgument, "iso8601", 9, 0, 0 }, // 8
+ { 0, GIE::StringArgument, 0, 15, 0, "startDateTime" },// 9
+ { 0, GIE::StringArgument, "le", 11, 0, 0 }, // 10
+ { 0, GIE::StringArgument, "date", 12, 13, 0 }, // 11
+ { 0, GIE::StringArgument, 0, 15, 0, "endDate" }, // 12
+ { 0, GIE::StringArgument, "iso8601", 14, 0, 0 }, // 13
+ { 0, GIE::StringArgument, 0, 15, 0, "endDateTime" }, // 14
+ { 0, GIE::TestEnd, 0, 16, 0, 0 }, // 15
+
+ { 0, GIE::TestStart, "currentdate", 17, 16, 0 }, // 16
+ { 0, GIE::TaggedArgument, "value", 18, 17, 0 }, // 17
+ { 0, GIE::StringArgument, "le", 19, 23, 0 }, // 18
+ { 0, GIE::StringArgument, "date", 20, 21, 0 }, // 19
+ { 0, GIE::StringArgument, 0, 28, 0, "endDate" }, // 20
+ { 0, GIE::StringArgument, "iso8601", 22, 0, 0 }, // 21
+ { 0, GIE::StringArgument, 0, 28, 0, "endDateTime" }, // 22
+ { 0, GIE::StringArgument, "ge", 24, 0, 0 }, // 23
+ { 0, GIE::StringArgument, "date", 25, 26, 0 }, // 24
+ { 0, GIE::StringArgument, 0, 28, 0, "startDate" }, // 25
+ { 0, GIE::StringArgument, "iso8601", 27, 0, 0 }, // 26
+ { 0, GIE::StringArgument, 0, 28, 0, "startDateTime" }, // 27
+ { 0, GIE::TestEnd, 0, 32, 0, 0 }, // 28
+ { 0, GIE::TestStart, 0, 31, 30, 0 }, // 29
+ { -1, GIE::Any, 0, 32, 0, 0 }, // 30
+ { 0, GIE::TestEnd, 0, 32, 30, 0 }, // 31
+ { 0, GIE::TestListEnd, 0, 33, 29, 0 }, // 32
+
+ { 0, GIE::TestEnd, 0, 34, 0, 0 }, // 33
// block of commands, find "stop", take nested if's into account:
- { 0, GIE::BlockStart, Q_NULLPTR, 26, 0, Q_NULLPTR }, // 25
- { 1, GIE::CommandStart, "stop", 29, 28, "stop" }, // 26
- { -1, GIE::Any, Q_NULLPTR, 26, 0, Q_NULLPTR }, // 27
- { 0, GIE::BlockEnd, Q_NULLPTR, 0, 27, Q_NULLPTR }, // 28
+ { 0, GIE::BlockStart, 0, 36, 33, 0 }, // 34
+ { -1, GIE::Any, 0, 36, 0, 0 }, // 35
+ { 1, GIE::CommandStart, "vacation", 38, 35, "vacation" }, // 36
+ { -1, GIE::Any, 0, 38, 0, 0 }, // 37
+ { 0, GIE::BlockEnd, 0, 39, 37, 0 }, // 38
- { -1, GIE::Any, Q_NULLPTR, 27, 27, Q_NULLPTR } // 29 end state
+ { -1, GIE::Any, 0, 39, 39, 0 } // 39 end state
};
static const unsigned int numDatesNodes = sizeof datesNodes / sizeof *datesNodes;
@@ -466,25 +490,52 @@
{
}
- QDate endDate() const
- {
- return date(QStringLiteral("endDate"));
- }
-
- QDate startDate() const
- {
- return date(QStringLiteral("startDate"));
- }
+ QDate endDate() const
+ {
+ if (results().count(QLatin1String("endDateTime")) == 1) {
+ return datetime(QLatin1String("endDateTime")).date();
+ } else {
+ return date(QLatin1String("endDate"));
+ }
+ }
+
+ QDate startDate() const
+ {
+ if (results().count(QLatin1String("startDateTime")) == 1) {
+ return datetime(QLatin1String("startDateTime")).date();
+ } else {
+ return date(QLatin1String("startDate"));
+ }
+ }
+
+ QTime endTime() const
+ {
+ return datetime(QLatin1String("endDateTime")).time();
+ }
+
+ QTime startTime() const
+ {
+ return datetime(QLatin1String("startDateTime")).time();
+ }
private:
- QDate date(const QString &name) const
- {
- if (mResults.count(name) == 0) {
- return QDate();
- } else {
- return QDate::fromString(mResults.at(name), Qt::ISODate);
- }
- }
+ QDate date(const QString &name) const
+ {
+ if (results().count(name) == 0) {
+ return QDate();
+ } else {
+ return QDate::fromString(results().at(name), Qt::ISODate);
+ }
+ }
+
+ QDateTime datetime(const QString &name) const
+ {
+ if (results().count(name) == 0) {
+ return QDateTime();
+ } else {
+ return QDateTime::fromString(results().at(name), Qt::ISODate);
+ }
+ }
};
class VacationDataExtractor : public KSieve::ScriptBuilder
@@ -494,12 +545,23 @@
// command itself:
VacationCommand,
// tagged args:
- Days, Addresses, Subject
+ Days, Addresses, Subject,
+ VacationEnd,
+ IfBlock,
+ RedirectCommand
};
public:
VacationDataExtractor();
virtual ~VacationDataExtractor();
+ bool commandFound() const
+ {
+ return mContext == VacationEnd;
+ }
+ bool active() const
+ {
+ return mActive;
+ }
int notificationInterval() const
{
return mNotificationInterval;
@@ -512,24 +574,46 @@
{
return mAliases;
}
+ const QString &ifComment() const
+ {
+ return mIfComment;
+ }
+ VacationUtils::MailAction mailAction() const
+ {
+ return mMailAction;
+ }
+ const QString &mailActionRecipient() const
+ {
+ return mMailActionRecipient;
+ }
const QString &subject() const
{
return mSubject;
}
+ int lineStart() const
+ {
+ return mLineStart;
+ }
+
+ int lineEnd() const
+ {
+ return mLineEnd;
+ }
+
private:
- void commandStart(const QString &identifier) Q_DECL_OVERRIDE;
+ void commandStart(const QString &identifier, int lineNumber) Q_DECL_OVERRIDE;
- void commandEnd() Q_DECL_OVERRIDE;
+ void commandEnd(int lineNumber) Q_DECL_OVERRIDE;
- void testStart(const QString &) Q_DECL_OVERRIDE {}
+ void testStart(const QString &) Q_DECL_OVERRIDE;
void testEnd() Q_DECL_OVERRIDE {}
void testListStart() Q_DECL_OVERRIDE {}
void testListEnd() Q_DECL_OVERRIDE {}
- void blockStart() Q_DECL_OVERRIDE {}
- void blockEnd() Q_DECL_OVERRIDE {}
- void hashComment(const QString &) Q_DECL_OVERRIDE {}
+ void blockStart(int lineNumber) Q_DECL_OVERRIDE;
+ void blockEnd(int lineNumber) Q_DECL_OVERRIDE;
+ void hashComment(const QString &) Q_DECL_OVERRIDE;
void bracketComment(const QString &) Q_DECL_OVERRIDE {}
void lineFeed() Q_DECL_OVERRIDE {}
void error(const KSieve::Error &e) Q_DECL_OVERRIDE;
@@ -551,10 +635,70 @@
QString mMessageText;
QString mSubject;
QStringList mAliases;
+ bool mActive;
+ bool mInIfBlock;
+ bool mFoundInBlock;
+ int mBlockLevel;
+ QString mIfComment;
+ int mLineStart;
+ int mLineEnd;
+
+ VacationUtils::MailAction mMailAction;
+ Context mMailActionContext;
+ QString mMailActionRecipient;
void reset();
};
+class RequireExtractor : public KSieve::ScriptBuilder {
+ enum Context {
+ None = 0,
+ // command itself:
+ RequireCommand,
+ EndState
+ };
+public:
+ RequireExtractor();
+ virtual ~RequireExtractor();
+
+ bool commandFound() const { return mContext == EndState; }
+ const QStringList &requirements() const { return mRequirements; }
+
+ int lineStart() const {return mLineStart;}
+ int lineEnd() const {return mLineEnd;}
+
+private:
+ void commandStart(const QString & identifier, int lineNumber);
+
+ void commandEnd(int lineNumber);
+
+ void testStart(const QString &) {}
+ void testEnd() {}
+ void testListStart() {}
+ void testListEnd() {}
+ void blockStart(int lineNumber) { Q_UNUSED(lineNumber) }
+ void blockEnd(int lineNumber) { Q_UNUSED(lineNumber) }
+ void hashComment(const QString &) {}
+ void bracketComment(const QString &) {}
+ void lineFeed() {}
+ void error(const KSieve::Error & e);
+ void finished();
+
+ void taggedArgument(const QString & tag) { Q_UNUSED(tag) }
+ void numberArgument(unsigned long number, char) { Q_UNUSED(number) }
+
+ void stringArgument(const QString & string, bool, const QString &);
+
+ void stringListArgumentStart(){}
+ void stringListEntry(const QString & string, bool, const QString &);
+ void stringListArgumentEnd(){}
+
+private:
+ Context mContext;
+ QStringList mRequirements;
+ int mLineStart;
+ int mLineEnd;
+};
}
#endif // VACATIONSCRIPTEXTRACTOR_H
Index: libksieve/src/ksieveui/vacation/vacationscriptextractor.cpp
===================================================================
--- libksieve/src/ksieveui/vacation/vacationscriptextractor.cpp
+++ libksieve/src/ksieveui/vacation/vacationscriptextractor.cpp
@@ -24,6 +24,14 @@
: KSieve::ScriptBuilder(),
mContext(None),
mNotificationInterval(0)
+ , mActive(true)
+ , mInIfBlock(false)
+ , mFoundInBlock(false)
+ , mBlockLevel(0)
+ , mLineStart(0)
+ , mLineEnd(0)
+ , mMailAction(VacationUtils::Keep)
+ , mMailActionContext(None)
{
qCDebug(LIBKSIEVE_LOG);
}
@@ -33,20 +41,45 @@
}
-void VacationDataExtractor::commandStart(const QString &identifier)
+void VacationDataExtractor::commandStart(const QString &identifier, int lineNumber)
{
- qCDebug(LIBKSIEVE_LOG) << "( \"" << identifier << "\" )";
- if (identifier != QLatin1String("vacation")) {
+ qCDebug(LIBKSIEVE_LOG) << "(\"" << identifier << "\")";
+ if (identifier == QStringLiteral("if") && mContext == None) {
+ mContext = IfBlock;
+ mLineStart = lineNumber;
+ mInIfBlock = true;
+ }
+
+ if (commandFound() && (!mFoundInBlock || mBlockLevel > 0)) {
+ if (identifier == QStringLiteral("discard")) {
+ mMailAction = VacationUtils::Discard;
+ } else if (identifier == QStringLiteral("redirect")) {
+ mMailAction = VacationUtils::Sendto;
+ mMailActionContext = RedirectCommand;
+ }
+ }
+
+ if (identifier != QStringLiteral("vacation")) {
return;
}
+
+ if (mContext != IfBlock) {
+ mLineStart = lineNumber;
+ }
+
reset();
mContext = VacationCommand;
+ mFoundInBlock = (mBlockLevel > 0);
}
-void VacationDataExtractor::commandEnd()
+void VacationDataExtractor::commandEnd(int lineNumber)
{
qCDebug(LIBKSIEVE_LOG);
- mContext = None;
+ if (mContext != None && mContext != IfBlock && mContext != VacationEnd) {
+ mContext = VacationEnd;
+ mLineEnd = lineNumber;
+ }
+ mMailActionContext = None;
}
void VacationDataExtractor::error(const KSieve::Error &e)
@@ -59,24 +92,65 @@
}
+void VacationDataExtractor::testStart(const QString &test)
+{
+ if (mContext == IfBlock) {
+ if (test == QStringLiteral("true") || test == QStringLiteral("false")) {
+ mActive = (test == QStringLiteral("true"));
+ mIfComment = QString();
+ }
+ }
+}
+
+void VacationDataExtractor::hashComment(const QString &comment)
+{
+ if (mContext == IfBlock) {
+ mIfComment += comment;
+ }
+}
+
+
+void VacationDataExtractor::blockStart(int lineNumber)
+{
+ Q_UNUSED(lineNumber)
+ mBlockLevel++;
+}
+
+void VacationDataExtractor::blockEnd(int lineNumber)
+{
+ mBlockLevel--;
+ if(mBlockLevel == 0 && !commandFound()) { //We are in main level again, and didn't found vacation in block
+ mActive = true;
+ mIfComment = QString();
+ } else if (mInIfBlock && mBlockLevel == 0 && commandFound()) {
+ mLineEnd = lineNumber;
+ mInIfBlock = false;
+ }
+}
+
void VacationDataExtractor::taggedArgument(const QString &tag)
{
- qCDebug(LIBKSIEVE_LOG) << "( \"" << tag << "\" )";
+ qCDebug(LIBKSIEVE_LOG) << "(\"" << tag << "\")";
+ if (mMailActionContext == RedirectCommand) {
+ if (tag == QStringLiteral("copy")) {
+ mMailAction = VacationUtils::CopyTo;
+ }
+ }
if (mContext != VacationCommand) {
return;
}
- if (tag == QLatin1String("days")) {
+ if (tag == QStringLiteral("days")) {
mContext = Days;
- } else if (tag == QLatin1String("addresses")) {
+ } else if (tag == QStringLiteral("addresses")) {
mContext = Addresses;
- } else if (tag == QLatin1String("subject")) {
+ } else if (tag == QStringLiteral("subject")) {
mContext = Subject;
}
}
void VacationDataExtractor::stringArgument(const QString &string, bool, const QString &)
{
- qCDebug(LIBKSIEVE_LOG) << "( \"" << string << "\" )";
+ qCDebug(LIBKSIEVE_LOG) << "(\"" << string << "\")";
if (mContext == Addresses) {
mAliases.push_back(string);
mContext = VacationCommand;
@@ -87,11 +161,14 @@
mMessageText = string;
mContext = VacationCommand;
}
+ if (mMailActionContext == RedirectCommand) {
+ mMailActionRecipient = string;
+ }
}
void VacationDataExtractor::numberArgument(unsigned long number, char)
{
- qCDebug(LIBKSIEVE_LOG) << "( \"" << number << "\" )";
+ qCDebug(LIBKSIEVE_LOG) << "(\"" << number << "\")";
if (mContext != Days) {
return;
}
@@ -109,7 +186,7 @@
}
void VacationDataExtractor::stringListEntry(const QString &string, bool, const QString &)
{
- qCDebug(LIBKSIEVE_LOG) << "( \"" << string << "\" )";
+ qCDebug(LIBKSIEVE_LOG) << "(\"" << string << "\")";
if (mContext != Addresses) {
return;
}
@@ -129,7 +206,59 @@
{
qCDebug(LIBKSIEVE_LOG);
mContext = None;
+ mMailAction = VacationUtils::Keep;
+ mMailActionRecipient = QString();
mNotificationInterval = 0;
mAliases.clear();
mMessageText.clear();
}
+
+RequireExtractor::RequireExtractor()
+ : KSieve::ScriptBuilder()
+ , mContext(None)
+ , mLineStart(0)
+ , mLineEnd(0)
+{
+
+}
+
+RequireExtractor::~RequireExtractor()
+{
+
+}
+
+void RequireExtractor::commandStart(const QString &identifier, int lineNumber)
+{
+ if (identifier == QStringLiteral("require") && mContext == None) {
+ mContext = RequireCommand;
+ mLineStart = lineNumber;
+ }
+}
+
+void RequireExtractor::commandEnd(int lineNumber)
+{
+ if (mContext == RequireCommand) {
+ mContext = EndState;
+ mLineEnd = lineNumber;
+ }
+}
+
+void RequireExtractor::error(const KSieve::Error &e)
+{
+ qCDebug(LIBKSIEVE_LOG) << e.asString() << "@" << e.line() << "," << e.column();
+}
+
+void RequireExtractor::finished()
+{
+
+}
+
+void RequireExtractor::stringArgument(const QString &string, bool, const QString &)
+{
+ mRequirements << string;
+}
+
+void RequireExtractor::stringListEntry(const QString &string, bool, const QString &)
+{
+ mRequirements << string;
+}
Index: libksieve/src/ksieveui/vacation/vacationutils.h
===================================================================
--- libksieve/src/ksieveui/vacation/vacationutils.h
+++ libksieve/src/ksieveui/vacation/vacationutils.h
@@ -19,42 +19,72 @@
#define VACATIONUTILS_H
#include
#include
+#include
class QDate;
-namespace KMime
-{
-namespace Types
-{
-struct AddrSpec;
-typedef QVector AddrSpecList;
-}
-}
-
namespace KSieveUi
{
namespace VacationUtils
{
+
+enum MailAction {
+ Keep,
+ Discard,
+ Sendto,
+ CopyTo,
+};
+
QString defaultMessageText();
QString defaultSubject();
+MailAction defaultMailAction();
int defaultNotificationInterval();
-QStringList defaultMailAliases();
+KMime::Types::AddrSpecList defaultMailAliases();
bool defaultSendForSpam();
QString defaultDomainName();
QDate defaultStartDate();
QDate defaultEndDate();
-QString composeScript(const QString &messageText,
- const QString &subject,
- int notificationInterval,
- const KMime::Types::AddrSpecList &aliases,
- bool sendForSpam, const QString &excludeDomain,
- const QDate &startDate, const QDate &endDate);
-bool parseScript(const QString &script, QString &messageText,
- QString &subject,
- int ¬ificationInterval, QStringList &aliases,
- bool &sendForSpam, QString &domainName,
- QDate &startDate, QDate &endDate);
+struct Vacation {
+ Vacation()
+ : notificationInterval(1)
+ , mailAction(Keep)
+ , valid(false)
+ , active(false)
+ , sendForSpam(true)
+ {
+ }
+
+ bool isValid() const
+ {
+ return valid;
+ }
+
+ QString mailActionRecipient;
+ QString messageText;
+ QString subject;
+ KMime::Types::AddrSpecList aliases;
+ QString excludeDomain;
+ QDate startDate;
+ QTime startTime;
+ QDate endDate;
+ QTime endTime;
+ int notificationInterval;
+ MailAction mailAction;
+ bool valid;
+ bool active;
+ bool sendForSpam;
+};
+
+QString composeScript(const Vacation &vacation);
+
+KSieveUi::VacationUtils::Vacation parseScript(const QString &script);
+
+QString mergeRequireLine(const QString &script1, const QString script2);
+
+QString updateVacationBlock(const QString &oldScript, const QString &newScript);
+
+QString mailAction(MailAction action);
}
}
Index: libksieve/src/ksieveui/vacation/vacationutils.cpp
===================================================================
--- libksieve/src/ksieveui/vacation/vacationutils.cpp
+++ libksieve/src/ksieveui/vacation/vacationutils.cpp
@@ -31,9 +31,9 @@
static inline QString dotstuff(QString s) // krazy:exclude=passbyvalue
{
if (s.startsWith(QLatin1Char('.'))) {
- return QLatin1Char('.') + s.replace(QLatin1String("\n."), QStringLiteral("\n.."));
+ return QLatin1Char('.') + s.replace(QStringLiteral("\n."), QStringLiteral("\n.."));
} else {
- return s.replace(QLatin1String("\n."), QStringLiteral("\n.."));
+ return s.replace(QStringLiteral("\n."), QStringLiteral("\n.."));
}
}
@@ -48,7 +48,29 @@
return i18n("Out of office till %1", QLocale().toString(QDate::currentDate().addDays(1)));
}
-QString VacationUtils::defaultMessageText()
+QString KSieveUi::VacationUtils::mailAction(KSieveUi::VacationUtils::MailAction action)
+{
+ switch (action) {
+ case Keep:
+ return i18n("Keep");
+ case Discard:
+ return i18n("Discard");
+ case Sendto:
+ return i18n("Redirect to");
+ case CopyTo:
+ return i18n("Copy to");
+ default:
+ qCWarning(LIBKSIEVE_LOG) << "Unknown mail action" << action;
+ return i18n("Unkown action");
+ }
+}
+
+KSieveUi::VacationUtils::MailAction KSieveUi::VacationUtils::defaultMailAction()
+{
+ return KSieveUi::VacationUtils::Keep;
+}
+
+QString KSieveUi::VacationUtils::defaultMessageText()
{
return i18n("I am out of office till %1.\n"
"\n"
@@ -68,17 +90,24 @@
return 7; // days
}
-QStringList VacationUtils::defaultMailAliases()
+KMime::Types::AddrSpecList VacationUtils::defaultMailAliases()
{
- QStringList sl;
+ KMime::Types::AddrSpecList sl;
KIdentityManagement::IdentityManager manager(true);
KIdentityManagement::IdentityManager::ConstIterator end(manager.end());
for (KIdentityManagement::IdentityManager::ConstIterator it = manager.begin(); it != end ; ++it) {
if (!(*it).primaryEmailAddress().isEmpty()) {
- sl.push_back((*it).primaryEmailAddress());
+ KMime::Types::Mailbox a;
+ a.fromUnicodeString((*it).primaryEmailAddress());
+ sl.push_back(a.addrSpec());
+ }
+ foreach(const QString &email, (*it).emailAliases()) {
+ KMime::Types::Mailbox a;
+ a.fromUnicodeString(email);
+ sl.push_back(a.addrSpec());
}
- sl += (*it).emailAliases();
}
+
return sl;
}
@@ -102,20 +131,20 @@
return defaultStartDate().addDays(7);
}
-bool VacationUtils::parseScript(const QString &script, QString &messageText,
- QString &subject,
- int ¬ificationInterval, QStringList &aliases,
- bool &sendForSpam, QString &domainName,
- QDate &startDate, QDate &endDate)
+VacationUtils::Vacation VacationUtils::parseScript(const QString &script)
{
+ KSieveUi::VacationUtils::Vacation vacation;
if (script.trimmed().isEmpty()) {
- messageText = VacationUtils::defaultMessageText();
- subject = VacationUtils::defaultSubject();
- notificationInterval = VacationUtils::defaultNotificationInterval();
- aliases = VacationUtils::defaultMailAliases();
- sendForSpam = VacationUtils::defaultSendForSpam();
- domainName = VacationUtils::defaultDomainName();
- return true;
+ vacation.valid = false;
+ vacation.active = false;
+ vacation.mailAction = VacationUtils::defaultMailAction();
+ vacation.messageText = VacationUtils::defaultMessageText();
+ vacation.subject = VacationUtils::defaultSubject();
+ vacation.notificationInterval = VacationUtils::defaultNotificationInterval();
+ vacation.aliases = VacationUtils::defaultMailAliases();
+ vacation.sendForSpam = VacationUtils::defaultSendForSpam();
+ vacation.excludeDomain = VacationUtils::defaultDomainName();
+ return vacation;
}
// The trimmed() call below prevents parsing errors. The
@@ -128,28 +157,53 @@
VacationDataExtractor vdx;
SpamDataExtractor sdx;
DomainRestrictionDataExtractor drdx;
- DateExtractor dtx;
- KSieveExt::MultiScriptBuilder tsb(&vdx, &sdx, &drdx, &dtx);
+ DateExtractor dx;
+ KSieveExt::MultiScriptBuilder tsb(&vdx , &sdx, &drdx, &dx);
parser.setScriptBuilder(&tsb);
- if (!parser.parse()) {
- return false;
+ parser.parse();
+ if (!parser.parse() || !vdx.commandFound()) {
+ vacation.active = false;
+ vacation.valid = false;
+ return vacation;
}
- messageText = vdx.messageText().trimmed();
+ vacation.valid = true;
+ vacation.active = vdx.active();
+ vacation.mailAction = vdx.mailAction();
+ vacation.mailActionRecipient = vdx.mailActionRecipient();
+ vacation.messageText = vdx.messageText().trimmed();
if (!vdx.subject().isEmpty()) {
- subject = vdx.subject().trimmed();
+ vacation.subject = vdx.subject().trimmed();
+ }
+ vacation.notificationInterval = vdx.notificationInterval();
+ vacation.aliases = KMime::Types::AddrSpecList();
+ foreach(const QString &alias, vdx.aliases()) {
+ KMime::Types::Mailbox a;
+ a.fromUnicodeString(alias);
+ vacation.aliases.append(a.addrSpec());
}
- notificationInterval = vdx.notificationInterval();
- aliases = vdx.aliases();
- if (!VacationSettings::allowOutOfOfficeUploadButNoSettings()) {
- sendForSpam = !sdx.found();
- domainName = drdx.domainName();
+
+ if (!vacation.active && !vdx.ifComment().isEmpty()) {
+ const QByteArray newScript = QString::fromAscii("if ").toUtf8() + vdx.ifComment().toUtf8() + QStringLiteral("{vacation;}").toUtf8();
+ tsb = KSieveExt::MultiScriptBuilder(&sdx, &drdx, &dx);
+ KSieve::Parser parser(newScript.begin(),
+ newScript.begin() + newScript.length());
+ parser.setScriptBuilder(&tsb);
+ if (!parser.parse()) {
+ vacation.valid = false;
+ return vacation;
+ }
}
- startDate = dtx.startDate();
- endDate = dtx.endDate();
- return true;
+
+ vacation.sendForSpam = !sdx.found();
+ vacation.excludeDomain = drdx.domainName();
+ vacation.startDate = dx.startDate();
+ vacation.startTime = dx.startTime();
+ vacation.endDate = dx.endDate();
+ vacation.endTime = dx.endTime();
+ return vacation;
}
-QString VacationUtils::composeScript(const QString &messageText,
+QString composeOldScript(const QString & messageText,
const QString &subject,
int notificationInterval,
const AddrSpecList &addrSpecs,
@@ -159,24 +213,23 @@
QString addressesArgument;
QStringList aliases;
if (!addrSpecs.empty()) {
- addressesArgument += QLatin1String(":addresses [ ");
+ addressesArgument += QStringLiteral(":addresses [ ");
QStringList sl;
AddrSpecList::const_iterator end = addrSpecs.constEnd();
for (AddrSpecList::const_iterator it = addrSpecs.begin() ; it != end; ++it) {
sl.push_back(QLatin1Char('"') + (*it).asString().replace(QLatin1Char('\\'), QStringLiteral("\\\\")).replace(QLatin1Char('"'), QStringLiteral("\\\"")) + QLatin1Char('"'));
aliases.push_back((*it).asString());
}
- addressesArgument += sl.join(QStringLiteral(", ")) + QLatin1String(" ] ");
+ addressesArgument += sl.join(QStringLiteral(", ")) + QStringLiteral(" ] ");
}
- QString script = QStringLiteral("require \"vacation\";\n");
+ QString script;
+
if (startDate.isValid() && endDate.isValid()) {
- script += QStringLiteral("require \"relational\";\n"
- "require \"date\";\n\n");
+ script = QStringLiteral("require [\"vacation\", \"relational\", \"date\"];\n\n");
} else {
- script += QStringLiteral("\n");
+ script = QStringLiteral("require \"vacation\";\n\n");
}
-
if (!sendForSpam)
script += QStringLiteral("if header :contains \"X-Spam-Flag\" \"YES\""
" { keep; stop; }\n"); // FIXME?
@@ -192,7 +245,14 @@
endDate.toString(Qt::ISODate));
}
- script += QLatin1String("vacation ");
+ if (startDate.isValid() && endDate.isValid()) {
+ script += QStringLiteral("if not allof(currentdate :value \"ge\" \"date\" \"%1\","
+ " currentdate :value \"le\" \"date\" \"%2\")"
+ " { keep; stop; }\n").arg(startDate.toString(Qt::ISODate),
+ endDate.toString(Qt::ISODate));
+ }
+
+ script += QStringLiteral("vacation ");
script += addressesArgument;
if (notificationInterval > 0) {
script += QStringLiteral(":days %1 ").arg(notificationInterval);
@@ -208,3 +268,217 @@
return script;
}
+QString KSieveUi::VacationUtils::composeScript(const Vacation &vacation)
+{
+ QStringList condition;
+ QStringList require;
+
+ require << QStringLiteral("vacation");
+
+ if (vacation.startDate.isValid() || vacation.endDate.isValid()) {
+ require << QStringLiteral("date");
+ require << QStringLiteral("relational");
+ }
+
+ if (vacation.startDate.isValid()) {
+ if (vacation.startTime.isValid()) {
+ QDateTime start(vacation.startDate, vacation.startTime);
+ condition.append(QStringLiteral("currentdate :value \"ge\" \"iso8601\" \"%1\"")
+ .arg(start.toString(Qt::ISODate)));
+ } else {
+ condition.append(QStringLiteral("currentdate :value \"ge\" \"date\" \"%1\"")
+ .arg(vacation.startDate.toString(Qt::ISODate)));
+ }
+ }
+
+ if (vacation.endDate.isValid()) {
+ if (vacation.endTime.isValid()) {
+ QDateTime end(vacation.endDate, vacation.endTime);
+ condition.append(QStringLiteral("currentdate :value \"le\" \"iso8601\" \"%1\"")
+ .arg(end.toString(Qt::ISODate)));
+ } else {
+ condition.append(QStringLiteral("currentdate :value \"le\" \"date\" \"%1\"")
+ .arg(vacation.endDate.toString(Qt::ISODate)));
+ }
+ }
+
+ if (!vacation.sendForSpam) {
+ condition.append(QStringLiteral("not header :contains \"X-Spam-Flag\" \"YES\""));
+ }
+
+ if (!vacation.excludeDomain.isEmpty()) {
+ condition.append(QStringLiteral("address :domain :contains \"from\" \"%1\"").arg(vacation.excludeDomain));
+ }
+
+ QString addressesArgument;
+ QStringList aliases;
+ if (!vacation.aliases.empty()) {
+ addressesArgument += QStringLiteral(":addresses [ ");
+ QStringList sl;
+ AddrSpecList::const_iterator end = vacation.aliases.constEnd();
+ for (AddrSpecList::const_iterator it = vacation.aliases.begin() ; it != end; ++it) {
+ sl.push_back(QLatin1Char('"') + (*it).asString().replace(QLatin1Char('\\'), QStringLiteral("\\\\")).replace(QLatin1Char('"'), QStringLiteral("\\\"")) + QLatin1Char('"'));
+ aliases.push_back((*it).asString());
+ }
+ addressesArgument += sl.join(QStringLiteral(", ")) + QStringLiteral(" ] ");
+ }
+
+ QString sVacation(QStringLiteral("vacation "));
+ sVacation += addressesArgument;
+ if (vacation.notificationInterval > 0)
+ sVacation += QStringLiteral(":days %1 ").arg(vacation.notificationInterval);
+
+ if (!vacation.subject.trimmed().isEmpty()) {
+ sVacation += QStringLiteral(":subject \"%1\" ").arg(stringReplace(vacation.subject).trimmed());
+ }
+
+ sVacation += QStringLiteral("text:\n");
+ sVacation += dotstuff(vacation.messageText.isEmpty() ? VacationUtils::defaultMessageText() : vacation.messageText);
+ sVacation += QStringLiteral("\n.\n;");
+
+ switch (vacation.mailAction) {
+ case VacationUtils::Keep:
+ break;
+ case VacationUtils::Discard:
+ sVacation += QStringLiteral("\ndiscard;");
+ break;
+ case VacationUtils::Sendto:
+ sVacation += QStringLiteral("\nredirect \"") + vacation.mailActionRecipient + QStringLiteral("\";");
+ break;
+ case VacationUtils::CopyTo:
+ require << QStringLiteral("copy");
+ sVacation += QStringLiteral("\nredirect :copy \"") + vacation.mailActionRecipient + QStringLiteral("\";");
+ break;
+ }
+
+ QString script;
+
+ script = QStringLiteral("require [\"%1\"];\n\n");
+ script = script.arg(require.join(QStringLiteral("\", \"")));
+
+ if (condition.count() == 0) {
+ if (vacation.active) {
+ script += sVacation;
+ } else {
+ script += QStringLiteral("if false\n{\n\t");
+ script += sVacation;
+ script += QStringLiteral("\n}");
+ }
+ } else {
+ if (vacation.active) {
+ script += QStringLiteral("if allof(%1)\n{\n\t").arg(condition.join(QStringLiteral(", ")));
+ } else {
+ script += QStringLiteral("if false # allof(%1)\n{\n\t").arg(condition.join(QStringLiteral(", ")));
+ }
+ script += sVacation;
+ script += QStringLiteral("\n}");
+ }
+
+ script += QStringLiteral("\n");
+
+ return script;
+}
+
+
+QString KSieveUi::VacationUtils::mergeRequireLine(const QString &script, const QString scriptUpdate)
+{
+ const QByteArray scriptUTF8 = script.trimmed().toUtf8();
+ const QByteArray scriptUpdateUTF8 = scriptUpdate.trimmed().toUtf8();
+
+ if (scriptUTF8.isEmpty()) {
+ return scriptUpdate;
+ }
+
+ if (scriptUpdateUTF8.isEmpty()) {
+ return script;
+ }
+
+ KSieve::Parser parser(scriptUTF8.begin(),
+ scriptUTF8.begin() + scriptUTF8.length());
+ KSieve::Parser parserUpdate(scriptUpdateUTF8.begin(),
+ scriptUpdateUTF8.begin() + scriptUpdateUTF8.length());
+ RequireExtractor rx, rxUpdate;
+ parser.setScriptBuilder(&rx);
+ parserUpdate.setScriptBuilder(&rxUpdate);
+
+ int insert(0);
+ QStringList lines = script.split(QLatin1Char('\n'));
+ QSet requirements;
+
+ if (parser.parse() && rx.commandFound()) {
+ insert = rx.lineStart();
+ const int endOld(rx.lineEnd());
+ for (int i=insert; i<=endOld; i++) {
+ lines.removeAt(insert);
+ }
+ requirements = rx.requirements().toSet();
+ }
+
+ if (parserUpdate.parse() && rxUpdate.commandFound()) {
+ requirements += rxUpdate.requirements().toSet();
+ }
+
+ if (requirements.count() > 1) {
+ QStringList req = requirements.toList();
+ req.sort();
+ lines.insert(insert, QStringLiteral("require [\"%1\"];").arg(req.join(QStringLiteral("\", \""))));
+ } else if (requirements.count() == 1) {
+ lines.insert(insert, QStringLiteral("require \"%1\";").arg(requirements.toList().first()));
+ }
+
+ return lines.join(QStringLiteral("\n"));
+}
+
+QString KSieveUi::VacationUtils::updateVacationBlock(const QString &oldScript, const QString &newScript)
+{
+ const QByteArray oldScriptUTF8 = oldScript.trimmed().toUtf8();
+ const QByteArray newScriptUTF8 = newScript.trimmed().toUtf8();
+
+ if (oldScriptUTF8.isEmpty()) {
+ return newScript;
+ }
+
+ if (newScriptUTF8.isEmpty()) {
+ return oldScript;
+ }
+
+ KSieve::Parser parserOld(oldScriptUTF8.begin(),
+ oldScriptUTF8.begin() + oldScriptUTF8.length());
+ KSieve::Parser parserNew(newScriptUTF8.begin(),
+ newScriptUTF8.begin() + newScriptUTF8.length());
+ VacationDataExtractor vdxOld, vdxNew;
+ RequireExtractor rx;
+ KSieveExt::MultiScriptBuilder tsb(&vdxOld , &rx);
+ parserOld.setScriptBuilder(&tsb);
+ parserNew.setScriptBuilder(&vdxNew);
+
+ int startOld(0);
+
+ QStringList lines = oldScript.split(QLatin1Char('\n'));
+
+ QString script;
+ if (parserOld.parse() && vdxOld.commandFound()) {
+ startOld = vdxOld.lineStart();
+ const int endOld(vdxOld.lineEnd());
+ for (int i=startOld; i<=endOld; i++) {
+ lines.removeAt(startOld);
+ }
+ } else {
+ if (rx.commandFound()) { // after require
+ startOld = rx.lineEnd() + 1;
+ } else {
+ startOld = 0;
+ }
+ }
+
+ if (parserNew.parse() && vdxNew.commandFound()) {
+ const int startNew(vdxNew.lineStart());
+ const int endNew(vdxNew.lineEnd());
+ QStringList linesNew = newScript.split(QLatin1Char('\n'));
+ for(int i=endNew;i>=startNew;i--) {
+ lines.insert(startOld, linesNew.at(i));
+ }
+ }
+
+ return lines.join(QStringLiteral("\n"));
+}
Index: libksieve/src/ksieveui/widgets/managesievewidget.h
===================================================================
--- libksieve/src/ksieveui/widgets/managesievewidget.h
+++ libksieve/src/ksieveui/widgets/managesievewidget.h
@@ -35,6 +35,8 @@
{
class ManageSieveTreeView;
class ManageSieveWidgetPrivate;
+class ParseUserScriptJob;
+
class KSIEVEUI_EXPORT ManageSieveWidget : public QWidget
{
Q_OBJECT
@@ -66,6 +68,7 @@
void slotDoubleClicked(QTreeWidgetItem *item);
void slotSystemNetworkOnlineStateChanged(bool state);
void slotCheckNetworkStatus();
+ void setActiveScripts(ParseUserScriptJob *job);
void slotCancelFetch();
public Q_SLOTS:
@@ -92,7 +95,6 @@
bool isFileNameItem(QTreeWidgetItem *item) const;
bool itemIsActived(QTreeWidgetItem *item) const;
void changeActiveScript(QTreeWidgetItem *item, bool activate);
- bool isProtectedName(const QString &name);
ManageSieveWidgetPrivate *const d;
};
Index: libksieve/src/ksieveui/widgets/managesievewidget.cpp
===================================================================
--- libksieve/src/ksieveui/widgets/managesievewidget.cpp
+++ libksieve/src/ksieveui/widgets/managesievewidget.cpp
@@ -20,6 +20,9 @@
#include "widgets/sievetreewidgetitem.h"
#include
+#include
+#include
+#include
#include
#include
@@ -31,8 +34,11 @@
#include
#include "libksieve_debug.h"
#include
+#include
using namespace KSieveUi;
+Q_DECLARE_METATYPE(QTreeWidgetItem*)
+
class KSieveUi::ManageSieveWidgetPrivate
{
public:
@@ -216,7 +222,7 @@
return;
}
- if (isProtectedName(name.toLower())) {
+ if (Util::isKep14ProtectedName(name)) {
KMessageBox::error(this, i18n("You cannot use protected name."), i18n("New Script"));
return;
}
@@ -297,6 +303,23 @@
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 = d->mSelectedItems[item];
if (!selected) {
return;
@@ -371,16 +394,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()
{
d->mBlockSignal = true;
@@ -427,8 +440,7 @@
d->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);
@@ -444,19 +456,61 @@
d->mBlockSignal = false;
qCDebug(LIBKSIEVE_LOG) << " LOAD";
- const bool hasIncludeCapability = job->sieveCapabilities().contains(QStringLiteral("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) {
+ QUrl u = mUrls[parent];
+ u = u.adjusted(QUrl::RemoveFilename);
+ u.setPath(u.path() + QStringLiteral("USER"));
+ ParseUserScriptJob *parseJob = new ParseUserScriptJob(u);
+ parseJob->setProperty("parentItem", 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);
d->mTreeView->expandItem(parent);
}
+void ManageSieveWidget::setActiveScripts(ParseUserScriptJob *job)
+{
+ QTreeWidgetItem * parent = job->property("parentItem").value();
+ if ( !parent ) {
+ return;
+ }
+ (static_cast(parent))->stopAnimation();
+
+ if (!job->error().isEmpty()) {
+ qWarning() << job->error();
+ return;
+ }
+
+ d->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]);
+ }
+
+ d->mBlockSignal = false;
+}
+
+
void ManageSieveWidget::slotDoubleClicked(QTreeWidgetItem *item)
{
if (!isFileNameItem(item)) {
Index: libksieve/src/parser/lexer.cpp
===================================================================
--- libksieve/src/parser/lexer.cpp
+++ libksieve/src/parser/lexer.cpp
@@ -170,10 +170,11 @@
{
return ch < 0;
}
+
static QString removeCRLF(const QString &s)
{
const bool CRLF = s.endsWith(QStringLiteral("\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
@@ -274,7 +275,7 @@
case ')':
case ';':
case ',': // Special
- result = *mState.cursor++;
+ result = QLatin1Char(*mState.cursor++);
return Special;
case '0':
case '1':
@@ -430,7 +431,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
}
}
@@ -541,7 +542,7 @@
assert(isdigit(*mState.cursor));
while (!atEnd() && isdigit(*mState.cursor)) {
- result += *mState.cursor++;
+ result += QLatin1Char(*mState.cursor++);
}
if (atEnd() || isDelim(*mState.cursor)) {
@@ -555,7 +556,7 @@
case 'm':
case 'K':
case 'k':
- result += *mState.cursor++;
+ result += QLatin1Char(*mState.cursor++);
break;
default:
makeIllegalCharError();
@@ -632,22 +633,22 @@
}
const QString line = removeCRLF(QString::fromUtf8(oldBeginOfLine, lineLength));
lines.push_back(removeDotStuff(line));
- if (line == ".") {
+ if ( line == QStringLiteral(".") ) {
break;
}
} else {
lines.push_back(QString());
}
}
- if (lines.back() != ".") {
+ if ( lines.back() != QStringLiteral(".") ) {
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(QStringLiteral("\n"));
return true;
}
@@ -676,7 +677,7 @@
if (!eatCRLF()) {
return false;
}
- result += '\n';
+ result += QLatin1Char('\n');
break;
case '\\':
++mState.cursor;
@@ -686,7 +687,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();
Index: libksieve/src/parser/parser.cpp
===================================================================
--- libksieve/src/parser/parser.cpp
+++ libksieve/src/parser/parser.cpp
@@ -140,7 +140,7 @@
return isStringToken() ||
token() == Lexer::Number ||
token() == Lexer::Tag ||
- (token() == Lexer::Special && mTokenValue == "[");
+ (token() == Lexer::Special && mTokenValue == QStringLiteral("[")) ;
}
bool Parser::Impl::obtainToken()
@@ -244,7 +244,7 @@
}
if (scriptBuilder()) {
- scriptBuilder()->commandStart(tokenValue());
+ scriptBuilder()->commandStart(tokenValue(), lexer.line());
}
consumeToken();
@@ -279,7 +279,7 @@
return false;
}
- if (token() == Lexer::Special && tokenValue() == "(") { // test-list
+ if (token() == Lexer::Special && tokenValue() == QStringLiteral ("(")) { // test-list
if (!parseTestList()) {
assert(error());
return false;
@@ -309,9 +309,9 @@
return false;
}
- if (tokenValue() == ";") {
+ if (tokenValue() == QStringLiteral(";")) {
consumeToken();
- } else if (tokenValue() == "{") { // block
+ } else if (tokenValue() == QStringLiteral("{")) { // block
if (!parseBlock()) {
return false; // it's an error since we saw '{'
}
@@ -321,7 +321,7 @@
}
if (scriptBuilder()) {
- scriptBuilder()->commandEnd();
+ scriptBuilder()->commandEnd(lexer.line());
}
return true;
}
@@ -371,7 +371,7 @@
}
consumeToken();
return true;
- } else if (token() == Lexer::Special && tokenValue() == "[") {
+ } else if (token() == Lexer::Special && tokenValue() == QStringLiteral("[")) {
if (!parseStringList()) {
assert(error());
return false;
@@ -390,7 +390,7 @@
return false;
}
- if (token() != Lexer::Special || tokenValue() != "(") {
+ if (token() != Lexer::Special || tokenValue() != QStringLiteral("(")) {
return false;
}
if (scriptBuilder()) {
@@ -511,7 +511,7 @@
goto TestEnd;
}
- if (token() == Lexer::Special && tokenValue() == "(") { // test-list
+ if (token() == Lexer::Special && tokenValue() == QStringLiteral("(")) { // test-list
if (!parseTestList()) {
assert(error());
return false;
@@ -539,11 +539,11 @@
return false;
}
- if (token() != Lexer::Special || tokenValue() != "{") {
+ if (token() != Lexer::Special || tokenValue() != QStringLiteral("{")) {
return false;
}
if (scriptBuilder()) {
- scriptBuilder()->blockStart();
+ scriptBuilder()->blockStart(lexer.line());
}
consumeToken();
@@ -572,12 +572,12 @@
return false;
}
- if (token() != Lexer::Special || tokenValue() != "}") {
+ if (token() != Lexer::Special || tokenValue() != QStringLiteral("}")) {
makeError(Error::NonCommandInCommandList);
return false;
}
if (scriptBuilder()) {
- scriptBuilder()->blockEnd();
+ scriptBuilder()->blockEnd(lexer.line());
}
consumeToken();
return true;
@@ -596,7 +596,7 @@
return false;
}
- if (token() != Lexer::Special || tokenValue() != "[") {
+ if (token() != Lexer::Special || tokenValue() != QStringLiteral("[")) {
return false;
}
@@ -685,7 +685,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;