~renatofilho/buteo-syncfw/more-verbose

« back to all changes in this revision

Viewing changes to libsyncprofile/SyncSchedule.cpp

  • Committer: Sergey Gerasimenko
  • Date: 2010-06-29 12:51:21 UTC
  • Revision ID: git-v1:cd8dab07b102ac96752ece4f3cde5fc62697d717
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of buteo-syncfw package
 
3
 *
 
4
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 
5
 *
 
6
 * Contact: Sateesh Kavuri <sateesh.kavuri@nokia.com>
 
7
 *
 
8
 * This library is free software; you can redistribute it and/or
 
9
 * modify it under the terms of the GNU Lesser General Public License
 
10
 * version 2.1 as published by the Free Software Foundation.
 
11
 *
 
12
 * This library is distributed in the hope that it will be useful, but
 
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
15
 * Lesser General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Lesser General Public
 
18
 * License along with this library; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 
20
 * 02110-1301 USA
 
21
 *
 
22
 */
 
23
 
 
24
 
 
25
#include "SyncSchedule.h"
 
26
#include "SyncSchedule_p.h"
 
27
#include "ProfileEngineDefs.h"
 
28
#include <QDomDocument>
 
29
#include <QStringList>
 
30
 
 
31
using namespace Buteo;
 
32
 
 
33
static const QString DAY_SEPARATOR = ",";
 
34
 
 
35
SyncSchedulePrivate::SyncSchedulePrivate()
 
36
:   iInterval(0), iRushInterval(0), iRushEnabled(false)
 
37
{
 
38
}
 
39
 
 
40
SyncSchedulePrivate::SyncSchedulePrivate(const SyncSchedulePrivate &aSource)
 
41
:   iDays(aSource.iDays),
 
42
    iTime(aSource.iTime),
 
43
    iInterval(aSource.iInterval),
 
44
    iRushDays(aSource.iRushDays),
 
45
    iRushBegin(aSource.iRushBegin),
 
46
    iRushEnd(aSource.iRushEnd),
 
47
    iRushInterval(aSource.iRushInterval),
 
48
    iRushEnabled(aSource.iRushEnabled)
 
49
{
 
50
}
 
51
 
 
52
SyncSchedule::SyncSchedule()
 
53
:   d_ptr(new SyncSchedulePrivate())
 
54
{
 
55
}
 
56
 
 
57
SyncSchedule::SyncSchedule(const SyncSchedule &aSource)
 
58
:   d_ptr(new SyncSchedulePrivate(*aSource.d_ptr))
 
59
{
 
60
}
 
61
 
 
62
SyncSchedule::SyncSchedule(const QDomElement &aRoot)
 
63
:   d_ptr(new SyncSchedulePrivate())
 
64
{
 
65
    d_ptr->iTime = QTime::fromString(aRoot.attribute(ATTR_TIME), Qt::ISODate);
 
66
    d_ptr->iInterval = aRoot.attribute(ATTR_INTERVAL).toUInt();
 
67
    d_ptr->iDays = d_ptr->parseDays(aRoot.attribute(ATTR_DAYS));
 
68
 
 
69
    QDomElement rush = aRoot.firstChildElement(TAG_RUSH);
 
70
    if (!rush.isNull())
 
71
    {
 
72
        d_ptr->iRushEnabled = (rush.attribute(ATTR_ENABLED) == BOOLEAN_TRUE);
 
73
        d_ptr->iRushInterval = rush.attribute(ATTR_INTERVAL).toUInt();
 
74
        d_ptr->iRushBegin = QTime::fromString(rush.attribute(ATTR_BEGIN), Qt::ISODate);
 
75
        d_ptr->iRushEnd = QTime::fromString(rush.attribute(ATTR_END), Qt::ISODate);
 
76
        d_ptr->iRushDays = d_ptr->parseDays(rush.attribute(ATTR_DAYS));
 
77
    }
 
78
    else
 
79
    {
 
80
        d_ptr->iRushEnabled = false;
 
81
        d_ptr->iRushInterval = 0;
 
82
    }
 
83
}
 
84
 
 
85
SyncSchedule::~SyncSchedule()
 
86
{
 
87
    delete d_ptr;
 
88
    d_ptr = 0;
 
89
}
 
90
 
 
91
SyncSchedule& SyncSchedule::operator=(const SyncSchedule &aRhs)
 
92
{
 
93
    if (&aRhs != this)
 
94
    {
 
95
        delete d_ptr;
 
96
        d_ptr = new SyncSchedulePrivate(*aRhs.d_ptr);
 
97
    }
 
98
 
 
99
    return *this;
 
100
}
 
101
 
 
102
QDomElement SyncSchedule::toXml(QDomDocument &aDoc) const
 
103
{
 
104
    QDomElement root = aDoc.createElement(TAG_SCHEDULE);
 
105
    root.setAttribute(ATTR_TIME, d_ptr->iTime.toString(Qt::ISODate));
 
106
    root.setAttribute(ATTR_INTERVAL, QString::number(d_ptr->iInterval));
 
107
    root.setAttribute(ATTR_DAYS, d_ptr->createDays(d_ptr->iDays));
 
108
 
 
109
    QDomElement rush = aDoc.createElement(TAG_RUSH);
 
110
    rush.setAttribute(ATTR_ENABLED, d_ptr->iRushEnabled ? BOOLEAN_TRUE :
 
111
        BOOLEAN_FALSE);
 
112
    rush.setAttribute(ATTR_INTERVAL, QString::number(d_ptr->iRushInterval));
 
113
    rush.setAttribute(ATTR_BEGIN, d_ptr->iRushBegin.toString(Qt::ISODate));
 
114
    rush.setAttribute(ATTR_END, d_ptr->iRushEnd.toString(Qt::ISODate));
 
115
    rush.setAttribute(ATTR_DAYS, d_ptr->createDays(d_ptr->iRushDays));
 
116
    root.appendChild(rush);
 
117
 
 
118
    return root;
 
119
}
 
120
 
 
121
DaySet SyncSchedule::days() const
 
122
{
 
123
    return d_ptr->iDays;
 
124
}
 
125
 
 
126
void SyncSchedule::setDays(const DaySet &aDays)
 
127
{
 
128
    d_ptr->iDays = aDays;
 
129
}
 
130
 
 
131
QTime SyncSchedule::time() const
 
132
{
 
133
    return d_ptr->iTime;
 
134
}
 
135
 
 
136
void SyncSchedule::setTime(const QTime &aTime)
 
137
{
 
138
    d_ptr->iTime = aTime;
 
139
}
 
140
 
 
141
unsigned SyncSchedule::interval() const
 
142
{
 
143
    return d_ptr->iInterval;
 
144
}
 
145
 
 
146
void SyncSchedule::setInterval(unsigned aInterval)
 
147
{
 
148
    d_ptr->iInterval = aInterval;
 
149
}
 
150
 
 
151
bool SyncSchedule::rushEnabled() const
 
152
{
 
153
    return d_ptr->iRushEnabled;
 
154
}
 
155
 
 
156
void SyncSchedule::setRushEnabled(bool aEnabled)
 
157
{
 
158
    d_ptr->iRushEnabled = aEnabled;
 
159
}
 
160
 
 
161
DaySet SyncSchedule::rushDays() const
 
162
{
 
163
    return d_ptr->iRushDays;
 
164
}
 
165
 
 
166
void SyncSchedule::setRushDays(const DaySet &aDays)
 
167
{
 
168
    d_ptr->iRushDays = aDays;
 
169
}
 
170
 
 
171
QTime SyncSchedule::rushBegin() const
 
172
{
 
173
    return d_ptr->iRushBegin;
 
174
}
 
175
 
 
176
QTime SyncSchedule::rushEnd() const
 
177
{
 
178
    return d_ptr->iRushEnd;
 
179
}
 
180
 
 
181
void SyncSchedule::setRushTime(const QTime &aBegin, const QTime &aEnd)
 
182
{
 
183
    d_ptr->iRushBegin = aBegin;
 
184
    d_ptr->iRushEnd = aEnd;
 
185
}
 
186
 
 
187
unsigned SyncSchedule::rushInterval() const
 
188
{
 
189
    return d_ptr->iRushInterval;
 
190
}
 
191
 
 
192
void SyncSchedule::setRushInterval(unsigned aInterval)
 
193
{
 
194
    d_ptr->iRushInterval = aInterval;
 
195
}
 
196
 
 
197
QDateTime SyncSchedule::nextSyncTime(const QDateTime &aPrevSync,
 
198
                                     const QDateTime &aCurrentTime) const
 
199
{
 
200
    QDateTime nextSync;
 
201
 
 
202
    if (d_ptr->iTime.isValid() && !d_ptr->iDays.isEmpty())
 
203
    {
 
204
        // Explicit sync time defined.
 
205
        nextSync.setTime(d_ptr->iTime);
 
206
        nextSync.setDate(aCurrentTime.date());
 
207
        if (aCurrentTime.time() > d_ptr->iTime)
 
208
        {
 
209
            nextSync = nextSync.addDays(1);
 
210
        } // no else
 
211
        d_ptr->adjustDate(nextSync, d_ptr->iDays);
 
212
    }
 
213
    else if (d_ptr->iInterval > 0)
 
214
    {
 
215
        // Sync interval defined.
 
216
        if (!aPrevSync.isValid())
 
217
        {
 
218
            nextSync = aCurrentTime;
 
219
        }
 
220
        else
 
221
        {
 
222
            nextSync = aPrevSync.addSecs(d_ptr->iInterval * 60);
 
223
            if (d_ptr->adjustDate(nextSync, d_ptr->iDays))
 
224
            {
 
225
                nextSync.setTime(QTime(0, 0, 0, 0));
 
226
            } // no else
 
227
            if (nextSync.isValid() && nextSync < aCurrentTime)
 
228
            {
 
229
                nextSync = aCurrentTime;
 
230
            } // no else
 
231
        }
 
232
    }
 
233
 
 
234
    if (d_ptr->iRushEnabled && d_ptr->iRushInterval > 0)
 
235
    {
 
236
        // Calculate next sync time with rush settings.
 
237
        QDateTime nextSyncRush;
 
238
        if (!aPrevSync.isValid())
 
239
        {
 
240
            nextSyncRush = aCurrentTime;
 
241
        }
 
242
        else if (d_ptr->isRush(aCurrentTime))
 
243
        {
 
244
            nextSyncRush = aPrevSync.addSecs(d_ptr->iRushInterval * 60);
 
245
            if (nextSyncRush < aCurrentTime)
 
246
            {
 
247
                nextSyncRush = aCurrentTime;
 
248
            }
 
249
            else if (!d_ptr->isRush(nextSyncRush))
 
250
            {
 
251
                nextSyncRush.setTime(d_ptr->iRushBegin);
 
252
                if (nextSyncRush < aPrevSync)
 
253
                {
 
254
                    nextSyncRush = nextSyncRush.addDays(1);
 
255
                } // no else
 
256
                d_ptr->adjustDate(nextSyncRush, d_ptr->iRushDays);
 
257
            } // no else
 
258
        }
 
259
        else
 
260
        {
 
261
            nextSyncRush.setTime(d_ptr->iRushBegin);
 
262
            nextSyncRush.setDate(aCurrentTime.date());
 
263
            if (aCurrentTime.time() > d_ptr->iRushBegin)
 
264
            {
 
265
                nextSyncRush = nextSyncRush.addDays(1);
 
266
            } // no else
 
267
            d_ptr->adjustDate(nextSyncRush, d_ptr->iRushDays);
 
268
        }
 
269
 
 
270
        // Use next sync time calculated with rush settings is sooner than
 
271
        // with normal settings, use the rush sync time.
 
272
        if (nextSyncRush.isValid() &&
 
273
            (!nextSync.isValid() || nextSyncRush < nextSync))
 
274
        {
 
275
            nextSync = nextSyncRush;
 
276
        } // no else
 
277
    } // no else
 
278
 
 
279
    return nextSync;
 
280
}
 
281
 
 
282
DaySet SyncSchedulePrivate::parseDays(const QString &aDays) const
 
283
{
 
284
    DaySet daySet;
 
285
    if (!aDays.isNull())
 
286
    {
 
287
        QStringList dayList = aDays.split(DAY_SEPARATOR,
 
288
            QString::SkipEmptyParts);
 
289
        foreach (QString dayStr, dayList)
 
290
        {
 
291
            bool ok;
 
292
            int dayNum = dayStr.toInt(&ok);
 
293
            if (ok)
 
294
            {
 
295
                daySet.insert(dayNum);
 
296
            } // no else
 
297
        }
 
298
    } // no else
 
299
 
 
300
    return daySet;
 
301
}
 
302
 
 
303
QString SyncSchedulePrivate::createDays(const DaySet &aDays) const
 
304
{
 
305
    QStringList dayList;
 
306
 
 
307
    foreach (int dayNum, aDays)
 
308
    {
 
309
        dayList.append(QString::number(dayNum));
 
310
    }
 
311
 
 
312
    return dayList.join(DAY_SEPARATOR);
 
313
}
 
314
 
 
315
bool SyncSchedulePrivate::adjustDate(QDateTime &aTime, const DaySet &aDays) const
 
316
{
 
317
    if (aDays.isEmpty())
 
318
    {
 
319
        aTime = QDateTime();
 
320
        return false;
 
321
    } // no else
 
322
 
 
323
    bool newValidDay = false;
 
324
    int startDay = aTime.date().dayOfWeek();
 
325
    while (!aDays.contains(aTime.date().dayOfWeek()))
 
326
    {
 
327
        newValidDay = true;
 
328
        aTime = aTime.addDays(1);
 
329
        // Safety check, avoid infinite loop if date set contains
 
330
        // only invalid values.
 
331
        if (aTime.date().dayOfWeek() == startDay)
 
332
        {
 
333
            // Clear next sync time.
 
334
            newValidDay = false;
 
335
            aTime = QDateTime();
 
336
            break;
 
337
        } // no else
 
338
    }
 
339
 
 
340
    return newValidDay;
 
341
}
 
342
 
 
343
bool SyncSchedulePrivate::isRush(const QDateTime &aTime) const
 
344
{
 
345
    return (iRushDays.contains(aTime.date().dayOfWeek()) &&
 
346
            aTime.time() >= iRushBegin && aTime.time() < iRushEnd);
 
347
}
 
348
 
 
349