4 KMail, the KDE mail client.
5 Copyright (c) 2002 Marc Mutz <mutz@kde.org>
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License,
9 version 2.0, as published by the Free Software Foundation.
10 You should have received a copy of the GNU General Public License
11 along with this program; if not, write to the Free Software Foundation,
12 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
18 #include "vacationdialog.h"
22 using KMail::SieveJob
;
24 #include "accountmanager.h"
25 using KMail::AccountManager
;
26 #include "kmacctimap.h"
27 #include <kpimidentities/identitymanager.h>
28 #include <kpimidentities/identity.h>
29 #include "kmmessage.h"
30 #include "globalsettings.h"
32 #include <kmime/kmime_header_parsing.h>
33 using KMime::Types::AddrSpecList
;
35 #include <ksieve/parser.h>
36 #include <ksieve/scriptbuilder.h>
37 #include <ksieve/error.h>
41 #include <kmessagebox.h>
53 class MultiScriptBuilder
: public KSieve::ScriptBuilder
{
54 std::vector
<KSieve::ScriptBuilder
*> mBuilders
;
56 MultiScriptBuilder() : KSieve::ScriptBuilder() {}
57 MultiScriptBuilder( KSieve::ScriptBuilder
* sb1
)
58 : KSieve::ScriptBuilder(), mBuilders( 1 )
63 MultiScriptBuilder( KSieve::ScriptBuilder
* sb1
,
64 KSieve::ScriptBuilder
* sb2
)
65 : KSieve::ScriptBuilder(), mBuilders( 2 )
69 assert( sb1
); assert( sb2
);
71 MultiScriptBuilder( KSieve::ScriptBuilder
* sb1
,
72 KSieve::ScriptBuilder
* sb2
,
73 KSieve::ScriptBuilder
* sb3
)
74 : KSieve::ScriptBuilder(), mBuilders( 3 )
79 assert( sb1
); assert( sb2
); assert( sb3
);
81 ~MultiScriptBuilder() {}
86 #define FOREACH for ( std::vector<KSieve::ScriptBuilder*>::const_iterator it = mBuilders.begin(), end = mBuilders.end() ; it != end ; ++it ) (*it)->
87 void commandStart( const QString
& identifier
) { FOREACH
commandStart( identifier
); }
88 void commandEnd() { FOREACH
commandEnd(); }
89 void testStart( const QString
& identifier
) { FOREACH
testStart( identifier
); }
90 void testEnd() { FOREACH
testEnd(); }
91 void testListStart() { FOREACH
testListStart(); }
92 void testListEnd() { FOREACH
testListEnd(); }
93 void blockStart() { FOREACH
blockStart(); }
94 void blockEnd() { FOREACH
blockEnd(); }
95 void hashComment( const QString
& comment
) { FOREACH
hashComment( comment
); }
96 void bracketComment( const QString
& comment
) { FOREACH
bracketComment( comment
); }
97 void lineFeed() { FOREACH
lineFeed(); }
98 void error( const KSieve::Error
& e
) { FOREACH
error( e
); }
99 void finished() { FOREACH
finished(); }
100 void taggedArgument( const QString
& tag
) { FOREACH
taggedArgument( tag
); }
101 void stringArgument( const QString
& string
, bool multiline
, const QString
& fixme
) { FOREACH
stringArgument( string
, multiline
, fixme
); }
102 void numberArgument( unsigned long number
, char quantifier
) { FOREACH
numberArgument( number
, quantifier
); }
103 void stringListArgumentStart() { FOREACH
stringListArgumentStart(); }
104 void stringListEntry( const QString
& string
, bool multiline
, const QString
& fixme
) { FOREACH
stringListEntry( string
, multiline
, fixme
); }
105 void stringListArgumentEnd() { FOREACH
stringListArgumentEnd(); }
113 class GenericInformationExtractor
: public KSieve::ScriptBuilder
{
128 StringListArgumentStart
,
130 StringListArgumentEnd
136 BuilderMethod method
;
141 const char * save_tag
;
144 const std::vector
<StateNode
> mNodes
;
145 std::map
<QString
,QString
> mResults
;
146 std::set
<unsigned int> mRecursionGuard
;
151 GenericInformationExtractor( const std::vector
<StateNode
> & nodes
)
152 : KSieve::ScriptBuilder(), mNodes( nodes
), mState( 0 ), mNestingDepth( 0 ) {}
154 const std::map
<QString
,QString
> & results() const { return mResults
; }
157 void process( BuilderMethod method
, const QString
& string
=QString() ) {
158 doProcess( method
, string
);
159 mRecursionGuard
.clear();
161 void doProcess( BuilderMethod method
, const QString
& string
) {
162 mRecursionGuard
.insert( mState
);
164 const StateNode
& expected
= mNodes
[mState
];
165 if ( expected
.depth
!= -1 && mNestingDepth
!= expected
.depth
)
167 if ( expected
.method
!= Any
&& method
!= expected
.method
)
169 if ( const char * str
= expected
.string
)
170 if ( string
.toLower() != QString::fromUtf8( str
).toLower() )
172 kDebug(5006) << ( found
?"found:" :"not found:" )
174 << ( found
? expected
.if_found
: expected
.if_not_found
);
175 mState
= found
? expected
.if_found
: expected
.if_not_found
;
176 assert( mState
< mNodes
.size() );
178 if ( const char * save_tag
= expected
.save_tag
)
179 mResults
[save_tag
] = string
;
180 if ( !found
&& !mRecursionGuard
.count( mState
) ) {
181 doProcess( method
, string
);
184 void commandStart( const QString
& identifier
) { kDebug(5006) ; process( CommandStart
, identifier
); }
185 void commandEnd() { kDebug(5006) ; process( CommandEnd
); }
186 void testStart( const QString
& identifier
) { kDebug(5006) ; process( TestStart
, identifier
); }
187 void testEnd() { kDebug(5006) ; process( TestEnd
); }
188 void testListStart() { kDebug(5006) ; process( TestListStart
); }
189 void testListEnd() { kDebug(5006) ; process( TestListEnd
); }
190 void blockStart() { kDebug(5006) ; process( BlockStart
); ++mNestingDepth
; }
191 void blockEnd() { kDebug(5006) ; --mNestingDepth
; process( BlockEnd
); }
192 void hashComment( const QString
& ) { kDebug(5006) ; }
193 void bracketComment( const QString
& ) { kDebug(5006) ; }
194 void lineFeed() { kDebug(5006) ; }
195 void error( const KSieve::Error
& ) {
199 void finished() { kDebug(5006) ; }
201 void taggedArgument( const QString
& tag
) { kDebug(5006) ; process( TaggedArgument
, tag
); }
202 void stringArgument( const QString
& string
, bool, const QString
& ) { kDebug(5006) ; process( StringArgument
, string
); }
203 void numberArgument( unsigned long number
, char ) { kDebug(5006) ; process( NumberArgument
, QString::number( number
) ); }
204 void stringListArgumentStart() { kDebug(5006) ; process( StringListArgumentStart
); }
205 void stringListEntry( const QString
& string
, bool, const QString
& ) { kDebug(5006) ; process( StringListEntry
, string
); }
206 void stringListArgumentEnd() { kDebug(5006) ; process( StringListArgumentEnd
); }
209 typedef GenericInformationExtractor GIE
;
210 static const GenericInformationExtractor::StateNode spamNodes
[] = {
211 { 0, GIE::CommandStart
, "if", 1, 0, 0 }, // 0
212 { 0, GIE::TestStart
, "header", 2, 0, 0 }, // 1
213 { 0, GIE::TaggedArgument
, "contains", 3, 0, 0 }, // 2
215 // accept both string and string-list:
216 { 0, GIE::StringArgument
, "x-spam-flag", 9, 4, "x-spam-flag" }, // 3
217 { 0, GIE::StringListArgumentStart
, 0, 5, 0, 0 }, // 4
218 { 0, GIE::StringListEntry
, "x-spam-flag", 6, 7, "x-spam-flag" }, // 5
219 { 0, GIE::StringListEntry
, 0, 6, 8, 0 }, // 6
220 { 0, GIE::StringListArgumentEnd
, 0, 0, 5, 0 }, // 7
221 { 0, GIE::StringListArgumentEnd
, 0, 9, 0, 0 }, // 8
223 // accept both string and string-list:
224 { 0, GIE::StringArgument
, "yes", 15, 10, "spam-flag-yes" }, // 9
225 { 0, GIE::StringListArgumentStart
, 0, 11, 0, 0 }, // 10
226 { 0, GIE::StringListEntry
, "yes", 12, 13, "spam-flag-yes" }, // 11
227 { 0, GIE::StringListEntry
, 0, 12, 14, 0 }, // 12
228 { 0, GIE::StringListArgumentEnd
, 0, 0, 11, 0 }, // 13
229 { 0, GIE::StringListArgumentEnd
, 0, 15, 0, 0 }, // 14
231 { 0, GIE::TestEnd
, 0, 16, 0, 0 }, // 15
233 // block of command, find "stop", take nested if's into account:
234 { 0, GIE::BlockStart
, 0, 17, 0, 0 }, // 16
235 { 1, GIE::CommandStart
, "stop", 20, 19, "stop" }, // 17
236 { -1, GIE::Any
, 0, 17, 0, 0 }, // 18
237 { 0, GIE::BlockEnd
, 0, 0, 18, 0 }, // 19
239 { -1, GIE::Any
, 0, 20, 20, 0 }, // 20 end state
241 static const unsigned int numSpamNodes
= sizeof spamNodes
/ sizeof *spamNodes
;
243 class SpamDataExtractor
: public GenericInformationExtractor
{
246 : GenericInformationExtractor( std::vector
<StateNode
>( spamNodes
, spamNodes
+ numSpamNodes
) )
252 return mResults
.count( "x-spam-flag" ) &&
253 mResults
.count( "spam-flag-yes" ) &&
254 mResults
.count( "stop" ) ;
258 // to understand this table, study the output of
259 // libksieve/tests/parsertest
260 // 'if not address :domain :contains ["from"] ["mydomain.org"] { keep; stop; }'
261 static const GenericInformationExtractor::StateNode domainNodes
[] = {
262 { 0, GIE::CommandStart
, "if", 1, 0, 0 }, // 0
263 { 0, GIE::TestStart
, "not", 2, 0, 0, }, // 1
264 { 0, GIE::TestStart
, "address", 3, 0, 0 }, // 2
266 // :domain and :contains in arbitrary order:
267 { 0, GIE::TaggedArgument
, "domain", 4, 5, 0 }, // 3
268 { 0, GIE::TaggedArgument
, "contains", 7, 0, 0 }, // 4
269 { 0, GIE::TaggedArgument
, "contains", 6, 0, 0 }, // 5
270 { 0, GIE::TaggedArgument
, "domain", 7, 0, 0 }, // 6
272 // accept both string and string-list:
273 { 0, GIE::StringArgument
, "from", 13, 8, "from" }, // 7
274 { 0, GIE::StringListArgumentStart
, 0, 9, 0, 0 }, // 8
275 { 0, GIE::StringListEntry
, "from", 10, 11, "from" }, // 9
276 { 0, GIE::StringListEntry
, 0, 10, 12, 0 }, // 10
277 { 0, GIE::StringListArgumentEnd
, 0, 0, 9, 0 }, // 11
278 { 0, GIE::StringListArgumentEnd
, 0, 13, 0, 0 }, // 12
280 // string: save, string-list: save last
281 { 0, GIE::StringArgument
, 0, 17, 14, "domainName" }, // 13
282 { 0, GIE::StringListArgumentStart
, 0, 15, 0, 0 }, // 14
283 { 0, GIE::StringListEntry
, 0, 15, 16, "domainName" }, // 15
284 { 0, GIE::StringListArgumentEnd
, 0, 17, 0, 0 }, // 16
286 { 0, GIE::TestEnd
, 0, 18, 0, 0 }, // 17
287 { 0, GIE::TestEnd
, 0, 19, 0, 0 }, // 18
289 // block of commands, find "stop", take nested if's into account:
290 { 0, GIE::BlockStart
, 0, 20, 0, 0 }, // 19
291 { 1, GIE::CommandStart
, "stop", 23, 22, "stop" }, // 20
292 { -1, GIE::Any
, 0, 20, 0, 0 }, // 21
293 { 0, GIE::BlockEnd
, 0, 0, 21, 0 }, // 22
295 { -1, GIE::Any
, 0, 23, 23, 0 } // 23 end state
297 static const unsigned int numDomainNodes
= sizeof domainNodes
/ sizeof *domainNodes
;
299 class DomainRestrictionDataExtractor
: public GenericInformationExtractor
{
301 DomainRestrictionDataExtractor()
302 : GenericInformationExtractor( std::vector
<StateNode
>( domainNodes
, domainNodes
+numDomainNodes
) )
307 QString
domainName() /*not const, since map::op[] isn't const*/ {
308 return mResults
.count( "stop" ) && mResults
.count( "from" )
309 ? mResults
["domainName"] : QString();
313 class VacationDataExtractor
: public KSieve::ScriptBuilder
{
322 VacationDataExtractor()
323 : KSieve::ScriptBuilder(),
324 mContext( None
), mNotificationInterval( 0 )
326 kDebug(5006) <<"VacationDataExtractor instantiated";
328 virtual ~VacationDataExtractor() {}
330 int notificationInterval() const { return mNotificationInterval
; }
331 const QString
& messageText() const { return mMessageText
; }
332 const QStringList
& aliases() const { return mAliases
; }
335 void commandStart( const QString
& identifier
) {
336 kDebug( 5006 ) <<"VacationDataExtractor::commandStart( \"" << identifier
<<"\" )";
337 if ( identifier
!= "vacation" )
340 mContext
= VacationCommand
;
344 kDebug( 5006 ) <<"VacationDataExtractor::commandEnd()";
348 void testStart( const QString
& ) {}
350 void testListStart() {}
351 void testListEnd() {}
354 void hashComment( const QString
& ) {}
355 void bracketComment( const QString
& ) {}
357 void error( const KSieve::Error
& e
) {
358 kDebug( 5006 ) <<"VacationDataExtractor::error() ###"
359 << e
.asString() << "@" << e
.line() << "," << e
.column();
363 void taggedArgument( const QString
& tag
) {
364 kDebug( 5006 ) <<"VacationDataExtractor::taggedArgument( \"" << tag
<<"\" )";
365 if ( mContext
!= VacationCommand
)
369 else if ( tag
== "addresses" )
370 mContext
= Addresses
;
373 void stringArgument( const QString
& string
, bool, const QString
& ) {
374 kDebug( 5006 ) <<"VacationDataExtractor::stringArgument( \"" << string
<<"\" )";
375 if ( mContext
== Addresses
) {
376 mAliases
.push_back( string
);
377 mContext
= VacationCommand
;
378 } else if ( mContext
== VacationCommand
) {
379 mMessageText
= string
;
380 mContext
= VacationCommand
;
384 void numberArgument( unsigned long number
, char ) {
385 kDebug( 5006 ) <<"VacationDataExtractor::numberArgument( \"" << number
<<"\" )";
386 if ( mContext
!= Days
)
388 if ( number
> INT_MAX
)
389 mNotificationInterval
= INT_MAX
;
391 mNotificationInterval
= number
;
392 mContext
= VacationCommand
;
395 void stringListArgumentStart() {}
396 void stringListEntry( const QString
& string
, bool, const QString
& ) {
397 kDebug( 5006 ) <<"VacationDataExtractor::stringListEntry( \"" << string
<<"\" )";
398 if ( mContext
!= Addresses
)
400 mAliases
.push_back( string
);
402 void stringListArgumentEnd() {
403 kDebug( 5006 ) <<"VacationDataExtractor::stringListArgumentEnd()";
404 if ( mContext
!= Addresses
)
406 mContext
= VacationCommand
;
411 int mNotificationInterval
;
412 QString mMessageText
;
413 QStringList mAliases
;
416 kDebug(5006) <<"VacationDataExtractor::reset()";
418 mNotificationInterval
= 0;
420 mMessageText
.clear();
428 Vacation::Vacation( QObject
* parent
, const char * name
)
429 : QObject( parent
), mSieveJob( 0 ), mDialog( 0 ), mWasActive( false )
431 setObjectName( name
);
433 kDebug(5006) <<"Vacation: found url \"" << mUrl
.prettyUrl() <<"\"";
434 if ( mUrl
.isEmpty() ) // nothing to do...
436 mSieveJob
= SieveJob::get( mUrl
);
437 connect( mSieveJob
, SIGNAL(gotScript(KMail::SieveJob
*,bool,const QString
&,bool)),
438 SLOT(slotGetResult(KMail::SieveJob
*,bool,const QString
&,bool)) );
441 Vacation::~Vacation() {
442 if ( mSieveJob
) mSieveJob
->kill(); mSieveJob
= 0;
443 delete mDialog
; mDialog
= 0;
444 kDebug(5006) <<"~Vacation()";
447 static inline QString
dotstuff( QString s
) { // krazy:exclude=passbyvalue
448 if ( s
.startsWith( '.' ) )
449 return '.' + s
.replace( "\n.", "\n.." );
451 return s
.replace( "\n.", "\n.." );
454 QString
Vacation::composeScript( const QString
& messageText
,
455 int notificationInterval
,
456 const AddrSpecList
& addrSpecs
,
457 bool sendForSpam
, const QString
& domain
)
459 QString addressesArgument
;
461 if ( !addrSpecs
.empty() ) {
462 addressesArgument
+= ":addresses [ ";
464 for ( AddrSpecList::const_iterator it
= addrSpecs
.begin() ; it
!= addrSpecs
.end() ; ++it
) {
465 sl
.push_back( '"' + (*it
).asString().replace( '\\', "\\\\" ).replace( '"', "\\\"" ) + '"' );
466 aliases
.push_back( (*it
).asString() );
468 addressesArgument
+= sl
.join( ", " ) + " ] ";
470 QString script
= QString::fromLatin1("require \"vacation\";\n"
474 script
+= QString::fromLatin1( "if header :contains \"X-Spam-Flag\" \"YES\""
475 " { keep; stop; }\n" ); // FIXME?
477 if ( !domain
.isEmpty() ) // FIXME
478 script
+= QString::fromLatin1( "if not address :domain :contains \"from\" \"%1\" { keep; stop; }\n" ).arg( domain
);
480 script
+= "vacation ";
482 script
+= addressesArgument
;
483 if ( notificationInterval
> 0 )
484 script
+= QString::fromLatin1(":days %1 ").arg( notificationInterval
);
485 script
+= QString::fromLatin1("text:\n");
486 script
+= dotstuff( messageText
.isEmpty() ? defaultMessageText() : messageText
);
487 script
+= QString::fromLatin1( "\n.\n;\n" );
491 static KUrl
findUrlForAccount( const KMail::ImapAccountBase
* a
) {
493 const SieveConfig sieve
= a
->sieveConfig();
494 if ( !sieve
.managesieveSupported() )
496 if ( sieve
.reuseConfig() ) {
497 // assemble Sieve url from the settings of the account:
499 u
.setProtocol( "sieve" );
500 u
.setHost( a
->host() );
501 u
.setUser( a
->login() );
502 u
.setPass( a
->passwd() );
503 u
.setPort( sieve
.port() );
504 u
.setQuery( "x-mech=" + (a
->auth() == "*" ? "PLAIN" : a
->auth()) ); //translate IMAP LOGIN to PLAIN
505 u
.setFileName( sieve
.vacationFileName() );
508 KUrl u
= sieve
.alternateURL();
509 u
.setFileName( sieve
.vacationFileName() );
514 KUrl
Vacation::findURL() const {
515 AccountManager
* am
= kmkernel
->acctMgr();
517 for ( KMAccount
* a
= am
->first() ; a
; a
= am
->next() )
518 if ( KMail::ImapAccountBase
* iab
= dynamic_cast<KMail::ImapAccountBase
*>( a
) ) {
519 KUrl u
= findUrlForAccount( iab
);
526 bool Vacation::parseScript( const QString
& script
, QString
& messageText
,
527 int & notificationInterval
, QStringList
& aliases
,
528 bool & sendForSpam
, QString
& domainName
) {
529 if ( script
.trimmed().isEmpty() ) {
530 messageText
= defaultMessageText();
531 notificationInterval
= defaultNotificationInterval();
532 aliases
= defaultMailAliases();
533 sendForSpam
= defaultSendForSpam();
534 domainName
= defaultDomainName();
538 // The trimmed() call below prevents parsing errors. The
539 // slave somehow omits the last \n, which results in a lone \r at
540 // the end, leading to a parse error.
541 const QByteArray scriptUTF8
= script
.trimmed().toUtf8();
542 kDebug(5006) <<"scriptUtf8 = \"" + scriptUTF8
+"\"";
543 KSieve::Parser
parser( scriptUTF8
.begin(),
544 scriptUTF8
.begin() + scriptUTF8
.length() );
545 VacationDataExtractor vdx
;
546 SpamDataExtractor sdx
;
547 DomainRestrictionDataExtractor drdx
;
548 KSieveExt::MultiScriptBuilder
tsb( &vdx
, &sdx
, &drdx
);
549 parser
.setScriptBuilder( &tsb
);
550 if ( !parser
.parse() )
552 messageText
= vdx
.messageText().trimmed();
553 notificationInterval
= vdx
.notificationInterval();
554 aliases
= vdx
.aliases();
555 if ( !GlobalSettings::allowOutOfOfficeUploadButNoSettings() ) {
556 sendForSpam
= !sdx
.found();
557 domainName
= drdx
.domainName();
562 QString
Vacation::defaultMessageText() {
563 return i18n("I am out of office till %1.\n"
565 "In urgent cases, please contact Mrs. <vacation replacement>\n"
567 "email: <email address of vacation replacement>\n"
568 "phone: +49 711 1111 11\n"
569 "fax.: +49 711 1111 12\n"
572 "-- <enter your name and email address here>\n",
573 KGlobal::locale()->formatDate( QDate::currentDate().addDays( 1 ) ) );
576 int Vacation::defaultNotificationInterval() {
580 QStringList
Vacation::defaultMailAliases() {
582 for ( KPIMIdentities::IdentityManager::ConstIterator it
= kmkernel
->identityManager()->begin() ;
583 it
!= kmkernel
->identityManager()->end() ; ++it
)
584 if ( !(*it
).emailAddr().isEmpty() )
585 sl
.push_back( (*it
).emailAddr() );
589 bool Vacation::defaultSendForSpam() {
590 return GlobalSettings::outOfOfficeReactToSpam();
593 QString
Vacation::defaultDomainName() {
594 return GlobalSettings::outOfOfficeDomain();
597 void Vacation::slotGetResult( SieveJob
* job
, bool success
,
598 const QString
& script
, bool active
) {
599 kDebug(5006) <<"Vacation::slotGetResult( ??," << success
600 << ", ?," << active
<< ")" << endl
603 mSieveJob
= 0; // job deletes itself after returning from this slot!
605 if ( mUrl
.protocol() == "sieve" && !job
->sieveCapabilities().isEmpty() &&
606 !job
->sieveCapabilities().contains("vacation") ) {
607 KMessageBox::sorry( 0, i18n("Your server did not list \"vacation\" in "
608 "its list of supported Sieve extensions;\n"
609 "without it, KMail cannot install out-of-"
610 "office replies for you.\n"
611 "Please contact you system administrator.") );
612 emit
result( false );
617 mDialog
= new VacationDialog( i18n("Configure \"Out of Office\" Replies"), 0, 0, false );
619 QString messageText
= defaultMessageText();
620 int notificationInterval
= defaultNotificationInterval();
621 QStringList aliases
= defaultMailAliases();
622 bool sendForSpam
= defaultSendForSpam();
623 QString domainName
= defaultDomainName();
624 if ( !success
) active
= false; // default to inactive
626 if ( !success
|| !parseScript( script
, messageText
, notificationInterval
, aliases
, sendForSpam
, domainName
) )
627 KMessageBox::information( 0, i18n("Someone (probably you) changed the "
628 "vacation script on the server.\n"
629 "KMail is no longer able to determine "
630 "the parameters for the autoreplies.\n"
631 "Default values will be used." ) );
634 mDialog
->setActivateVacation( active
);
635 mDialog
->setMessageText( messageText
);
636 mDialog
->setNotificationInterval( notificationInterval
);
637 mDialog
->setMailAliases( aliases
.join(", ") );
638 mDialog
->setSendForSpam( sendForSpam
);
639 mDialog
->setDomainName( domainName
);
640 mDialog
->enableDomainAndSendForSpam( !GlobalSettings::allowOutOfOfficeUploadButNoSettings() );
642 connect( mDialog
, SIGNAL(okClicked()), SLOT(slotDialogOk()) );
643 connect( mDialog
, SIGNAL(cancelClicked()), SLOT(slotDialogCancel()) );
644 connect( mDialog
, SIGNAL(defaultClicked()), SLOT(slotDialogDefaults()) );
649 void Vacation::slotDialogDefaults() {
652 mDialog
->setActivateVacation( true );
653 mDialog
->setMessageText( defaultMessageText() );
654 mDialog
->setNotificationInterval( defaultNotificationInterval() );
655 mDialog
->setMailAliases( defaultMailAliases().join(", ") );
656 mDialog
->setSendForSpam( defaultSendForSpam() );
657 mDialog
->setDomainName( defaultDomainName() );
660 void Vacation::slotDialogOk() {
661 kDebug(5006) <<"Vacation::slotDialogOk()";
662 // compose a new script:
663 const QString script
= composeScript( mDialog
->messageText(),
664 mDialog
->notificationInterval(),
665 mDialog
->mailAliases(),
666 mDialog
->sendForSpam(),
667 mDialog
->domainName() );
668 const bool active
= mDialog
->activateVacation();
670 kDebug(5006) <<"script:" << endl
<< script
;
672 // and commit the dialog's settings to the server:
673 mSieveJob
= SieveJob::put( mUrl
, script
, active
, mWasActive
);
674 connect( mSieveJob
, SIGNAL(gotScript(KMail::SieveJob
*,bool,const QString
&,bool)),
676 ? SLOT(slotPutActiveResult(KMail::SieveJob
*,bool))
677 : SLOT(slotPutInactiveResult(KMail::SieveJob
*,bool)) );
679 // destroy the dialog:
680 mDialog
->delayedDestruct();
684 void Vacation::slotDialogCancel() {
685 kDebug(5006) <<"Vacation::slotDialogCancel()";
686 mDialog
->delayedDestruct();
688 emit
result( false );
691 void Vacation::slotPutActiveResult( SieveJob
* job
, bool success
) {
692 handlePutResult( job
, success
, true );
695 void Vacation::slotPutInactiveResult( SieveJob
* job
, bool success
) {
696 handlePutResult( job
, success
, false );
699 void Vacation::handlePutResult( SieveJob
*, bool success
, bool activated
) {
701 KMessageBox::information( 0, activated
702 ? i18n("Sieve script installed successfully on the server.\n"
703 "Out of Office reply is now active.")
704 : i18n("Sieve script installed successfully on the server.\n"
705 "Out of Office reply has been deactivated.") );
707 kDebug(5006) <<"Vacation::handlePutResult( ???," << success
<<", ? )";
708 mSieveJob
= 0; // job deletes itself after returning from this slot!
709 emit
result( success
);
715 #include "vacation.moc"