1/*
2 Copyright (c) 2009 Kevin Ottens <ervin@kde.org>
3
4 This library is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This library is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18*/
19
20#include "idlejob.h"
21
22#include <QtCore/QTimer>
23#include <KDE/KLocalizedString>
24
25#include "job_p.h"
26#include "message_p.h"
27#include "session_p.h"
28
29namespace KIMAP
30{
31 class IdleJobPrivate : public JobPrivate
32 {
33 public:
34 IdleJobPrivate( IdleJob *job, Session *session, const QString& name )
35 : JobPrivate( session, name ), q( job ),
36 messageCount( -1 ), recentCount( -1 ),
37 lastMessageCount( -1 ), lastRecentCount( -1 ),
38 originalSocketTimeout( -1 ) { }
39 ~IdleJobPrivate() { }
40
41 void emitStats()
42 {
43 emitStatsTimer.stop();
44
45 emit q->mailBoxStats( q, m_session->selectedMailBox(),
46 messageCount, recentCount );
47
48 lastMessageCount = messageCount;
49 lastRecentCount = recentCount;
50
51 messageCount = -1;
52 recentCount = -1;
53 }
54
55 void resetTimeout()
56 {
57 sessionInternal()->setSocketTimeout( originalSocketTimeout );
58 }
59
60 IdleJob * const q;
61
62 QTimer emitStatsTimer;
63
64 int messageCount;
65 int recentCount;
66
67 int lastMessageCount;
68 int lastRecentCount;
69
70 int originalSocketTimeout;
71 };
72}
73
74using namespace KIMAP;
75
76IdleJob::IdleJob( Session *session )
77 : Job( *new IdleJobPrivate( this, session, i18nc( "name of the idle job", "Idle" ) ) )
78{
79 Q_D( IdleJob );
80 connect( &d->emitStatsTimer, SIGNAL(timeout()),
81 this, SLOT(emitStats()) );
82
83 connect( this, SIGNAL(result(KJob*)),
84 this, SLOT(resetTimeout()) );
85}
86
87IdleJob::~IdleJob()
88{
89}
90
91void KIMAP::IdleJob::stop()
92{
93 Q_D( IdleJob );
94 d->sessionInternal()->setSocketTimeout( d->originalSocketTimeout );
95 d->sessionInternal()->sendData( "DONE" );
96}
97
98void IdleJob::doStart()
99{
100 Q_D( IdleJob );
101 d->originalSocketTimeout = d->sessionInternal()->socketTimeout();
102 d->sessionInternal()->setSocketTimeout( -1 );
103 d->tags << d->sessionInternal()->sendCommand( "IDLE" );
104}
105
106void IdleJob::handleResponse( const Message &response )
107{
108 Q_D( IdleJob );
109
110 // We can predict it'll be handled by handleErrorReplies() so emit
111 // pending signals now (if needed) so that result() will really be
112 // the last emitted signal.
113 if ( !response.content.isEmpty() &&
114 d->tags.size() == 1 &&
115 d->tags.contains( response.content.first().toString() ) &&
116 ( d->messageCount >= 0 || d->recentCount >= 0 ) ) {
117 d->emitStats();
118 }
119
120 if ( handleErrorReplies( response ) == NotHandled ) {
121 if ( response.content.size() > 0 && response.content[0].toString() == "+" ) {
122 // Got the continuation all is fine
123 return;
124
125 } else if ( response.content.size() > 2 ) {
126 if ( response.content[2].toString() == "EXISTS" ) {
127 if ( d->messageCount >= 0 ) {
128 d->emitStats();
129 }
130
131 d->messageCount = response.content[1].toString().toInt();
132 } else if ( response.content[2].toString() == "RECENT" ) {
133 if ( d->recentCount >= 0 ) {
134 d->emitStats();
135 }
136
137 d->recentCount = response.content[1].toString().toInt();
138 } else if ( response.content[2].toString() == "FETCH" ) {
139 const qint64 uid = response.content[1].toString().toLongLong();
140 Q_EMIT mailBoxMessageFlagsChanged( this, uid );
141 }
142 }
143
144 if ( d->messageCount>=0 && d->recentCount>=0 ) {
145 d->emitStats();
146 } else if ( d->messageCount>=0 || d->recentCount>=0 ) {
147 d->emitStatsTimer.start( 200 );
148 }
149 }
150}
151
152QString KIMAP::IdleJob::lastMailBox() const
153{
154 Q_D( const IdleJob );
155 return d->m_session->selectedMailBox();
156}
157
158int KIMAP::IdleJob::lastMessageCount() const
159{
160 Q_D( const IdleJob );
161 return d->lastMessageCount;
162}
163
164int KIMAP::IdleJob::lastRecentCount() const
165{
166 Q_D( const IdleJob );
167 return d->lastRecentCount;
168}
169
170#include "moc_idlejob.cpp"
171