~ubuntu-branches/ubuntu/precise/gwenview/precise-proposed

« back to all changes in this revision

Viewing changes to lib/slideshow.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2011-12-15 14:17:54 UTC
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: package-import@ubuntu.com-20111215141754-z043hyx69dulbggf
Tags: upstream-4.7.90
ImportĀ upstreamĀ versionĀ 4.7.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
// Local
39
39
#include <gwenviewconfig.h>
40
40
 
41
 
namespace Gwenview {
 
41
namespace Gwenview
 
42
{
42
43
 
43
44
#undef ENABLE_LOG
44
45
#undef LOG
50
51
#endif
51
52
 
52
53
enum State {
53
 
        Stopped,
54
 
        Started,
55
 
        WaitForEndOfUrl
 
54
    Stopped,
 
55
    Started,
 
56
    WaitForEndOfUrl
56
57
};
57
58
 
58
59
/**
59
60
 * This class generate random numbers which are not the same between two runs
60
61
 * of Gwenview. See bug #132334
61
62
 */
62
 
class RandomNumberGenerator {
 
63
class RandomNumberGenerator
 
64
{
63
65
public:
64
 
        RandomNumberGenerator()
65
 
        : mSeed(time(0)) {
66
 
        }
 
66
    RandomNumberGenerator()
 
67
    : mSeed(time(0))
 
68
    {
 
69
    }
67
70
 
68
 
        int operator()(int n) {
69
 
                return rand_r(&mSeed) % n;
70
 
        }
 
71
    int operator()(int n)
 
72
    {
 
73
        return rand_r(&mSeed) % n;
 
74
    }
71
75
 
72
76
private:
73
 
        unsigned int mSeed;
 
77
    unsigned int mSeed;
74
78
};
75
79
 
76
80
struct SlideShowPrivate {
77
 
        QTimer* mTimer;
78
 
        State mState;
79
 
        QVector<KUrl> mUrls;
80
 
        QVector<KUrl> mShuffledUrls;
81
 
        QVector<KUrl>::ConstIterator mStartIt;
82
 
        KUrl mCurrentUrl;
83
 
        KUrl mLastShuffledUrl;
84
 
 
85
 
        QAction* mLoopAction;
86
 
        QAction* mRandomAction;
87
 
 
88
 
        KUrl findNextUrl() {
89
 
                if (GwenviewConfig::random()) {
90
 
                        return findNextRandomUrl();
91
 
                } else {
92
 
                        return findNextOrderedUrl();
93
 
                }
94
 
        }
95
 
 
96
 
 
97
 
        KUrl findNextOrderedUrl() {
98
 
                QVector<KUrl>::ConstIterator it = qFind(mUrls.constBegin(), mUrls.constEnd(), mCurrentUrl);
99
 
                if (it == mUrls.constEnd()) {
100
 
                        kWarning() << "Current url not found in list. This should not happen.\n";
101
 
                        return KUrl();
102
 
                }
103
 
 
104
 
                ++it;
105
 
                if (GwenviewConfig::loop()) {
106
 
                        // Looping, if we reach the end, start again
107
 
                        if (it == mUrls.constEnd()) {
108
 
                                it = mUrls.constBegin();
109
 
                        }
110
 
                } else {
111
 
                        // Not looping, have we reached the end?
112
 
                        // FIXME: stopAtEnd
113
 
                        if (/*(it==mUrls.end() && GwenviewConfig::stopAtEnd()) ||*/ it == mStartIt) {
114
 
                                it = mUrls.constEnd();
115
 
                        }
116
 
                }
117
 
 
118
 
                if (it != mUrls.constEnd()) {
119
 
                        return *it;
120
 
                } else {
121
 
                        return KUrl();
122
 
                }
123
 
        }
124
 
 
125
 
 
126
 
        void initShuffledUrls() {
127
 
                mShuffledUrls = mUrls;
128
 
                RandomNumberGenerator generator;
129
 
                std::random_shuffle(mShuffledUrls.begin(), mShuffledUrls.end(), generator);
130
 
                // Ensure the first url is different from the previous last one, so that
131
 
                // last url does not stay visible twice longer than usual
132
 
                if (mLastShuffledUrl == mShuffledUrls.first() && mShuffledUrls.count() > 1) {
133
 
                        qSwap(mShuffledUrls[0], mShuffledUrls[1]);
134
 
                }
135
 
                mLastShuffledUrl = mShuffledUrls.last();
136
 
        }
137
 
 
138
 
 
139
 
        KUrl findNextRandomUrl() {
140
 
                if (mShuffledUrls.empty()) {
141
 
                        if (GwenviewConfig::loop()) {
142
 
                                initShuffledUrls();
143
 
                        } else {
144
 
                                return KUrl();
145
 
                        }
146
 
                }
147
 
 
148
 
                KUrl url = mShuffledUrls.last();
149
 
                mShuffledUrls.pop_back();
150
 
 
151
 
                return url;
152
 
        }
153
 
 
154
 
 
155
 
        void updateTimerInterval() {
156
 
                mTimer->setInterval(int(GwenviewConfig::interval() * 1000));
157
 
        }
158
 
 
159
 
 
160
 
        void doStart() {
161
 
                if (MimeTypeUtils::urlKind(mCurrentUrl) == MimeTypeUtils::KIND_VIDEO) {
162
 
                        LOG("mState = WaitForEndOfUrl");
163
 
                        // Just in case
164
 
                        mTimer->stop();
165
 
                        mState = WaitForEndOfUrl;
166
 
                } else {
167
 
                        LOG("mState = Started");
168
 
                        mTimer->start();
169
 
                        mState = Started;
170
 
                }
171
 
        }
 
81
    QTimer* mTimer;
 
82
    State mState;
 
83
    QVector<KUrl> mUrls;
 
84
    QVector<KUrl> mShuffledUrls;
 
85
    QVector<KUrl>::ConstIterator mStartIt;
 
86
    KUrl mCurrentUrl;
 
87
    KUrl mLastShuffledUrl;
 
88
 
 
89
    QAction* mLoopAction;
 
90
    QAction* mRandomAction;
 
91
 
 
92
    KUrl findNextUrl()
 
93
    {
 
94
        if (GwenviewConfig::random()) {
 
95
            return findNextRandomUrl();
 
96
        } else {
 
97
            return findNextOrderedUrl();
 
98
        }
 
99
    }
 
100
 
 
101
    KUrl findNextOrderedUrl()
 
102
    {
 
103
        QVector<KUrl>::ConstIterator it = qFind(mUrls.constBegin(), mUrls.constEnd(), mCurrentUrl);
 
104
        if (it == mUrls.constEnd()) {
 
105
            kWarning() << "Current url not found in list. This should not happen.\n";
 
106
            return KUrl();
 
107
        }
 
108
 
 
109
        ++it;
 
110
        if (GwenviewConfig::loop()) {
 
111
            // Looping, if we reach the end, start again
 
112
            if (it == mUrls.constEnd()) {
 
113
                it = mUrls.constBegin();
 
114
            }
 
115
        } else {
 
116
            // Not looping, have we reached the end?
 
117
            // FIXME: stopAtEnd
 
118
            if (/*(it==mUrls.end() && GwenviewConfig::stopAtEnd()) ||*/ it == mStartIt) {
 
119
                it = mUrls.constEnd();
 
120
            }
 
121
        }
 
122
 
 
123
        if (it != mUrls.constEnd()) {
 
124
            return *it;
 
125
        } else {
 
126
            return KUrl();
 
127
        }
 
128
    }
 
129
 
 
130
    void initShuffledUrls()
 
131
    {
 
132
        mShuffledUrls = mUrls;
 
133
        RandomNumberGenerator generator;
 
134
        std::random_shuffle(mShuffledUrls.begin(), mShuffledUrls.end(), generator);
 
135
        // Ensure the first url is different from the previous last one, so that
 
136
        // last url does not stay visible twice longer than usual
 
137
        if (mLastShuffledUrl == mShuffledUrls.first() && mShuffledUrls.count() > 1) {
 
138
            qSwap(mShuffledUrls[0], mShuffledUrls[1]);
 
139
        }
 
140
        mLastShuffledUrl = mShuffledUrls.last();
 
141
    }
 
142
 
 
143
    KUrl findNextRandomUrl()
 
144
    {
 
145
        if (mShuffledUrls.empty()) {
 
146
            if (GwenviewConfig::loop()) {
 
147
                initShuffledUrls();
 
148
            } else {
 
149
                return KUrl();
 
150
            }
 
151
        }
 
152
 
 
153
        KUrl url = mShuffledUrls.last();
 
154
        mShuffledUrls.pop_back();
 
155
 
 
156
        return url;
 
157
    }
 
158
 
 
159
    void updateTimerInterval()
 
160
    {
 
161
        mTimer->setInterval(int(GwenviewConfig::interval() * 1000));
 
162
    }
 
163
 
 
164
    void doStart()
 
165
    {
 
166
        if (MimeTypeUtils::urlKind(mCurrentUrl) == MimeTypeUtils::KIND_VIDEO) {
 
167
            LOG("mState = WaitForEndOfUrl");
 
168
            // Just in case
 
169
            mTimer->stop();
 
170
            mState = WaitForEndOfUrl;
 
171
        } else {
 
172
            LOG("mState = Started");
 
173
            mTimer->start();
 
174
            mState = Started;
 
175
        }
 
176
    }
172
177
};
173
178
 
174
 
 
175
 
 
176
 
 
177
179
SlideShow::SlideShow(QObject* parent)
178
180
: QObject(parent)
179
 
, d(new SlideShowPrivate) {
180
 
        d->mState = Stopped;
181
 
 
182
 
        d->mTimer = new QTimer(this);
183
 
        connect(d->mTimer, SIGNAL(timeout()),
184
 
                        this, SLOT(goToNextUrl()) );
185
 
 
186
 
        d->mLoopAction = new QAction(this);
187
 
        d->mLoopAction->setText(i18nc("@item:inmenu toggle loop in slideshow", "Loop"));
188
 
        d->mLoopAction->setCheckable(true);
189
 
        connect(d->mLoopAction, SIGNAL(triggered()), SLOT(updateConfig()) );
190
 
 
191
 
        d->mRandomAction = new QAction(this);
192
 
        d->mRandomAction->setText(i18nc("@item:inmenu toggle random order in slideshow", "Random"));
193
 
        d->mRandomAction->setCheckable(true);
194
 
        connect(d->mRandomAction, SIGNAL(toggled(bool)), SLOT(slotRandomActionToggled(bool)) );
195
 
        connect(d->mRandomAction, SIGNAL(triggered()), SLOT(updateConfig()) );
196
 
 
197
 
        d->mLoopAction->setChecked(GwenviewConfig::loop());
198
 
        d->mRandomAction->setChecked(GwenviewConfig::random());
199
 
}
200
 
 
201
 
 
202
 
SlideShow::~SlideShow() {
203
 
        GwenviewConfig::self()->writeConfig();
204
 
        delete d;
205
 
}
206
 
 
207
 
 
208
 
QAction* SlideShow::loopAction() const {
209
 
        return d->mLoopAction;
210
 
}
211
 
 
212
 
 
213
 
QAction* SlideShow::randomAction() const {
214
 
        return d->mRandomAction;
215
 
}
216
 
 
217
 
 
218
 
void SlideShow::start(const QList<KUrl>& urls) {
219
 
        d->mUrls.resize(urls.size());
220
 
        qCopy(urls.begin(), urls.end(), d->mUrls.begin());
221
 
 
222
 
        d->mStartIt=qFind(d->mUrls.constBegin(), d->mUrls.constEnd(), d->mCurrentUrl);
223
 
        if (d->mStartIt==d->mUrls.constEnd()) {
224
 
                kWarning() << "Current url not found in list, aborting.\n";
225
 
                return;
226
 
        }
227
 
 
228
 
        if (GwenviewConfig::random()) {
229
 
                d->initShuffledUrls();
230
 
        }
231
 
        
232
 
        d->updateTimerInterval();
233
 
        d->mTimer->setSingleShot(false);
234
 
        d->doStart();
235
 
        stateChanged(true);
236
 
}
237
 
 
238
 
 
239
 
void SlideShow::setInterval(int intervalInSeconds) {
240
 
        GwenviewConfig::setInterval(double(intervalInSeconds));
241
 
        d->updateTimerInterval();
242
 
}
243
 
 
244
 
 
245
 
void SlideShow::stop() {
246
 
        LOG("Stopping timer");
247
 
        d->mTimer->stop();
248
 
        d->mState = Stopped;
249
 
        stateChanged(false);
250
 
}
251
 
 
252
 
 
253
 
void SlideShow::resumeAndGoToNextUrl() {
254
 
        LOG("");
255
 
        if (d->mState == WaitForEndOfUrl) {
256
 
                goToNextUrl();
257
 
        }
258
 
}
259
 
 
260
 
 
261
 
void SlideShow::goToNextUrl() {
262
 
        LOG("");
263
 
        KUrl url = d->findNextUrl();
264
 
        LOG("url:" << url);
265
 
        if (!url.isValid()) {
266
 
                stop();
267
 
                return;
268
 
        }
269
 
        goToUrl(url);
270
 
}
271
 
 
272
 
 
273
 
void SlideShow::setCurrentUrl(const KUrl& url) {
274
 
        LOG(url);
275
 
        if (d->mCurrentUrl == url) {
276
 
                return;
277
 
        }
278
 
        d->mCurrentUrl = url;
279
 
        // Restart timer to avoid showing new url for the remaining time of the old
280
 
        // url
281
 
        if (d->mState != Stopped) {
282
 
                d->doStart();
283
 
        }
284
 
}
285
 
 
286
 
 
287
 
bool SlideShow::isRunning() const {
288
 
        return d->mState != Stopped;
289
 
}
290
 
 
291
 
 
292
 
void SlideShow::updateConfig() {
293
 
        GwenviewConfig::setLoop(d->mLoopAction->isChecked());
294
 
        GwenviewConfig::setRandom(d->mRandomAction->isChecked());
295
 
}
296
 
 
297
 
 
298
 
void SlideShow::slotRandomActionToggled(bool on) {
299
 
        if (on && d->mState != Stopped) {
300
 
                d->initShuffledUrls();
301
 
        }
302
 
}
303
 
 
 
181
, d(new SlideShowPrivate)
 
182
{
 
183
    d->mState = Stopped;
 
184
 
 
185
    d->mTimer = new QTimer(this);
 
186
    connect(d->mTimer, SIGNAL(timeout()),
 
187
            this, SLOT(goToNextUrl()));
 
188
 
 
189
    d->mLoopAction = new QAction(this);
 
190
    d->mLoopAction->setText(i18nc("@item:inmenu toggle loop in slideshow", "Loop"));
 
191
    d->mLoopAction->setCheckable(true);
 
192
    connect(d->mLoopAction, SIGNAL(triggered()), SLOT(updateConfig()));
 
193
 
 
194
    d->mRandomAction = new QAction(this);
 
195
    d->mRandomAction->setText(i18nc("@item:inmenu toggle random order in slideshow", "Random"));
 
196
    d->mRandomAction->setCheckable(true);
 
197
    connect(d->mRandomAction, SIGNAL(toggled(bool)), SLOT(slotRandomActionToggled(bool)));
 
198
    connect(d->mRandomAction, SIGNAL(triggered()), SLOT(updateConfig()));
 
199
 
 
200
    d->mLoopAction->setChecked(GwenviewConfig::loop());
 
201
    d->mRandomAction->setChecked(GwenviewConfig::random());
 
202
}
 
203
 
 
204
SlideShow::~SlideShow()
 
205
{
 
206
    GwenviewConfig::self()->writeConfig();
 
207
    delete d;
 
208
}
 
209
 
 
210
QAction* SlideShow::loopAction() const
 
211
{
 
212
    return d->mLoopAction;
 
213
}
 
214
 
 
215
QAction* SlideShow::randomAction() const
 
216
{
 
217
    return d->mRandomAction;
 
218
}
 
219
 
 
220
void SlideShow::start(const QList<KUrl>& urls)
 
221
{
 
222
    d->mUrls.resize(urls.size());
 
223
    qCopy(urls.begin(), urls.end(), d->mUrls.begin());
 
224
 
 
225
    d->mStartIt = qFind(d->mUrls.constBegin(), d->mUrls.constEnd(), d->mCurrentUrl);
 
226
    if (d->mStartIt == d->mUrls.constEnd()) {
 
227
        kWarning() << "Current url not found in list, aborting.\n";
 
228
        return;
 
229
    }
 
230
 
 
231
    if (GwenviewConfig::random()) {
 
232
        d->initShuffledUrls();
 
233
    }
 
234
 
 
235
    d->updateTimerInterval();
 
236
    d->mTimer->setSingleShot(false);
 
237
    d->doStart();
 
238
    stateChanged(true);
 
239
}
 
240
 
 
241
void SlideShow::setInterval(int intervalInSeconds)
 
242
{
 
243
    GwenviewConfig::setInterval(double(intervalInSeconds));
 
244
    d->updateTimerInterval();
 
245
}
 
246
 
 
247
void SlideShow::stop()
 
248
{
 
249
    LOG("Stopping timer");
 
250
    d->mTimer->stop();
 
251
    d->mState = Stopped;
 
252
    stateChanged(false);
 
253
}
 
254
 
 
255
void SlideShow::resumeAndGoToNextUrl()
 
256
{
 
257
    LOG("");
 
258
    if (d->mState == WaitForEndOfUrl) {
 
259
        goToNextUrl();
 
260
    }
 
261
}
 
262
 
 
263
void SlideShow::goToNextUrl()
 
264
{
 
265
    LOG("");
 
266
    KUrl url = d->findNextUrl();
 
267
    LOG("url:" << url);
 
268
    if (!url.isValid()) {
 
269
        stop();
 
270
        return;
 
271
    }
 
272
    goToUrl(url);
 
273
}
 
274
 
 
275
void SlideShow::setCurrentUrl(const KUrl& url)
 
276
{
 
277
    LOG(url);
 
278
    if (d->mCurrentUrl == url) {
 
279
        return;
 
280
    }
 
281
    d->mCurrentUrl = url;
 
282
    // Restart timer to avoid showing new url for the remaining time of the old
 
283
    // url
 
284
    if (d->mState != Stopped) {
 
285
        d->doStart();
 
286
    }
 
287
}
 
288
 
 
289
bool SlideShow::isRunning() const
 
290
{
 
291
    return d->mState != Stopped;
 
292
}
 
293
 
 
294
void SlideShow::updateConfig()
 
295
{
 
296
    GwenviewConfig::setLoop(d->mLoopAction->isChecked());
 
297
    GwenviewConfig::setRandom(d->mRandomAction->isChecked());
 
298
}
 
299
 
 
300
void SlideShow::slotRandomActionToggled(bool on)
 
301
{
 
302
    if (on && d->mState != Stopped) {
 
303
        d->initShuffledUrls();
 
304
    }
 
305
}
304
306
 
305
307
} // namespace