~ubuntu-branches/ubuntu/saucy/digikam/saucy

« back to all changes in this revision

Viewing changes to core/libs/widgets/common/ratingwidget.cpp

  • Committer: Package Import Robot
  • Author(s): Felix Geyer, Rohan Garg, Philip Muškovac, Felix Geyer
  • Date: 2011-09-23 18:18:55 UTC
  • mfrom: (1.2.36 upstream)
  • Revision ID: package-import@ubuntu.com-20110923181855-ifs67wxkugshev9k
Tags: 2:2.1.1-0ubuntu1
[ Rohan Garg ]
* New upstream release (LP: #834190)
  - debian/control
    + Build with libqtwebkit-dev
 - debian/kipi-plugins-common
    + Install libkvkontakte required by kipi-plugins
 - debian/digikam
    + Install panoramagui

[ Philip Muškovac ]
* New upstream release
  - debian/control:
    + Add libcv-dev, libcvaux-dev, libhighgui-dev, libboost-graph1.46-dev,
      libksane-dev, libxml2-dev, libxslt-dev, libqt4-opengl-dev, libqjson-dev,
      libgpod-dev and libqca2-dev to build-deps
    + Add packages for kipi-plugins, libmediawiki, libkface, libkgeomap and
      libkvkontakte
  - debian/rules:
    + Don't build with gphoto2 since it doesn't build with it.
  - Add kubuntu_fix_test_linking.diff to fix linking of the dngconverter test
  - update install files
  - update kubuntu_01_mysqld_executable_name.diff for new cmake layout
    and rename to kubuntu_mysqld_executable_name.diff
* Fix typo in digikam-data description (LP: #804894)
* Fix Vcs links

[ Felix Geyer ]
* Move library data files to the new packages libkface-data, libkgeomap-data
  and libkvkontakte-data.
* Override version of the embedded library packages to 1.0~digikam<version>.
* Exclude the library packages from digikam-dbg to prevent file conflicts in
  the future.
* Call dh_install with --list-missing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ============================================================
 
2
 *
 
3
 * This file is a part of digiKam project
 
4
 * http://www.digikam.org
 
5
 *
 
6
 * Date        : 2005-08-15
 
7
 * Description : a widget to draw stars rating
 
8
 *
 
9
 * Copyright (C) 2005 by Owen Hirst <n8rider@sbcglobal.net>
 
10
 * Copyright (C) 2006-2011 by Gilles Caulier <caulier dot gilles at gmail dot com>
 
11
 *
 
12
 * This program is free software; you can redistribute it
 
13
 * and/or modify it under the terms of the GNU General
 
14
 * Public License as published by the Free Software Foundation;
 
15
 * either version 2, or (at your option)
 
16
 * any later version.
 
17
 *
 
18
 * This program is distributed in the hope that it will be useful,
 
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
21
 * GNU General Public License for more details.
 
22
 *
 
23
 * ============================================================ */
 
24
 
 
25
#include "ratingwidget.moc"
 
26
 
 
27
// C++ includes
 
28
 
 
29
#include <cmath>
 
30
 
 
31
// Qt includes
 
32
 
 
33
#include <QPainter>
 
34
#include <QPalette>
 
35
#include <QPixmap>
 
36
#include <QTimeLine>
 
37
#include <QPolygon>
 
38
#include <QFont>
 
39
#include <QAction>
 
40
 
 
41
// KDE includes
 
42
 
 
43
#include <kglobalsettings.h>
 
44
#include <ksqueezedtextlabel.h>
 
45
#include <klocale.h>
 
46
#include <kdebug.h>
 
47
#include <kmenu.h>
 
48
#include <khbox.h>
 
49
#include <kapplication.h>
 
50
#include <kxmlguiwindow.h>
 
51
#include <kactioncollection.h>
 
52
 
 
53
// Local includes
 
54
 
 
55
#include "globals.h"
 
56
#include "thememanager.h"
 
57
 
 
58
namespace Digikam
 
59
{
 
60
 
 
61
class RatingWidget::RatingWidgetPriv
 
62
{
 
63
public:
 
64
 
 
65
    RatingWidgetPriv()
 
66
    {
 
67
        tracking       = true;
 
68
        isHovered      = false;
 
69
        fading         = false;
 
70
        rating         = 0;
 
71
        fadingTimeLine = 0;
 
72
        fadingValue    = 0;
 
73
        offset         = 0;
 
74
        duration       = 600;   // ms
 
75
 
 
76
        // Pre-computed star polygon for a 15x15 pixmap.
 
77
        starPolygon << QPoint(0,  6);
 
78
        starPolygon << QPoint(5,  5);
 
79
        starPolygon << QPoint(7,  0);
 
80
        starPolygon << QPoint(9,  5);
 
81
        starPolygon << QPoint(14, 6);
 
82
        starPolygon << QPoint(10, 9);
 
83
        starPolygon << QPoint(11, 14);
 
84
        starPolygon << QPoint(7,  11);
 
85
        starPolygon << QPoint(3,  14);
 
86
        starPolygon << QPoint(4,  9);
 
87
    }
 
88
 
 
89
    bool       tracking;
 
90
    bool       isHovered;
 
91
    bool       fading;
 
92
 
 
93
    int        rating;
 
94
    int        fadingValue;
 
95
    int        duration;
 
96
    int        offset;
 
97
 
 
98
    QTimeLine* fadingTimeLine;
 
99
 
 
100
    QPolygon   starPolygon;
 
101
 
 
102
    QPixmap    selPixmap;      // Selected star.
 
103
    QPixmap    regPixmap;      // Regular star.
 
104
    QPixmap    disPixmap;      // Disable star.
 
105
};
 
106
 
 
107
RatingWidget::RatingWidget(QWidget* parent)
 
108
    : QWidget(parent), d(new RatingWidgetPriv)
 
109
{
 
110
    slotThemeChanged();
 
111
 
 
112
    connect(ThemeManager::instance(), SIGNAL(signalThemeChanged()),
 
113
            this, SLOT(slotThemeChanged()));
 
114
}
 
115
 
 
116
RatingWidget::~RatingWidget()
 
117
{
 
118
    delete d;
 
119
}
 
120
 
 
121
void RatingWidget::setupTimeLine()
 
122
{
 
123
    delete d->fadingTimeLine;
 
124
    d->fadingTimeLine = new QTimeLine(d->duration, this);
 
125
    d->fadingTimeLine->setFrameRange(0, 255);
 
126
 
 
127
    connect(d->fadingTimeLine, SIGNAL(frameChanged(int)),
 
128
            this, SLOT(setFadingValue(int)));
 
129
 
 
130
    d->fadingTimeLine->start();
 
131
}
 
132
 
 
133
int RatingWidget::regPixmapWidth() const
 
134
{
 
135
    return d->regPixmap.width();
 
136
}
 
137
 
 
138
void RatingWidget::setRating(int val)
 
139
{
 
140
    if ((val < RatingMin || val > RatingMax) && val != NoRating)
 
141
    {
 
142
        return;
 
143
    }
 
144
 
 
145
    d->rating = val;
 
146
 
 
147
    if (d->tracking)
 
148
    {
 
149
        emit signalRatingChanged(d->rating);
 
150
    }
 
151
 
 
152
    emit signalRatingModified(d->rating);
 
153
    update();
 
154
}
 
155
 
 
156
int RatingWidget::rating() const
 
157
{
 
158
    return d->rating;
 
159
}
 
160
 
 
161
void RatingWidget::setTracking(bool tracking)
 
162
{
 
163
    d->tracking = tracking;
 
164
}
 
165
 
 
166
bool RatingWidget::hasTracking() const
 
167
{
 
168
    return d->tracking;
 
169
}
 
170
 
 
171
void RatingWidget::setFading(bool fading)
 
172
{
 
173
    d->fading = fading;
 
174
}
 
175
 
 
176
bool RatingWidget::hasFading() const
 
177
{
 
178
    return d->fading;
 
179
}
 
180
 
 
181
void RatingWidget::setFadingValue(int value)
 
182
{
 
183
    d->fadingValue = value;
 
184
 
 
185
    if (d->fadingValue >= 255 && d->fadingTimeLine)
 
186
    {
 
187
        d->fadingTimeLine->stop();
 
188
    }
 
189
 
 
190
    update();
 
191
}
 
192
 
 
193
void RatingWidget::setVisible(bool visible)
 
194
{
 
195
    QWidget::setVisible(visible);
 
196
 
 
197
    if (visible)
 
198
    {
 
199
        startFading();
 
200
    }
 
201
    else
 
202
    {
 
203
        stopFading();
 
204
    }
 
205
}
 
206
 
 
207
int RatingWidget::maximumVisibleWidth() const
 
208
{
 
209
    return RatingMax * (d->disPixmap.width()+1);
 
210
}
 
211
 
 
212
void RatingWidget::startFading()
 
213
{
 
214
    if (!hasFading())
 
215
    {
 
216
        return;
 
217
    }
 
218
 
 
219
    if (!d->isHovered)
 
220
    {
 
221
        d->isHovered   = true;
 
222
        d->fadingValue = 0;
 
223
        setupTimeLine();
 
224
    }
 
225
}
 
226
 
 
227
void RatingWidget::stopFading()
 
228
{
 
229
    if (!hasFading())
 
230
    {
 
231
        return;
 
232
    }
 
233
 
 
234
    if (d->fadingTimeLine)
 
235
    {
 
236
        d->fadingTimeLine->stop();
 
237
    }
 
238
 
 
239
    d->isHovered   = false;
 
240
    d->fadingValue = 0;
 
241
    update();
 
242
}
 
243
 
 
244
void RatingWidget::setVisibleImmediately()
 
245
{
 
246
    setFadingValue(255);
 
247
}
 
248
 
 
249
QPixmap RatingWidget::starPixmapDisabled() const
 
250
{
 
251
    return d->disPixmap;
 
252
}
 
253
 
 
254
QPixmap RatingWidget::starPixmapFilled() const
 
255
{
 
256
    return d->selPixmap;
 
257
}
 
258
 
 
259
QPixmap RatingWidget::starPixmap() const
 
260
{
 
261
    return d->regPixmap;
 
262
}
 
263
 
 
264
void RatingWidget::regeneratePixmaps()
 
265
{
 
266
    slotThemeChanged();
 
267
}
 
268
 
 
269
void RatingWidget::mousePressEvent(QMouseEvent* e)
 
270
{
 
271
    if (e->button() != Qt::LeftButton)
 
272
    {
 
273
        return;
 
274
    }
 
275
 
 
276
    if (hasFading() && d->fadingValue < 255)
 
277
    {
 
278
        return;
 
279
    }
 
280
 
 
281
    int pos = (e->x() - d->offset) / d->regPixmap.width() +1;
 
282
 
 
283
    if (d->rating == pos)
 
284
    {
 
285
        d->rating--;
 
286
    }
 
287
    else
 
288
    {
 
289
        d->rating = pos;
 
290
    }
 
291
 
 
292
    if (d->rating > RatingMax)
 
293
    {
 
294
        d->rating = RatingMax;
 
295
    }
 
296
 
 
297
    if (d->rating < RatingMin)
 
298
    {
 
299
        d->rating = RatingMin;
 
300
    }
 
301
 
 
302
    if (d->tracking)
 
303
    {
 
304
        emit signalRatingChanged(d->rating);
 
305
    }
 
306
 
 
307
    emit signalRatingModified(d->rating);
 
308
    update();
 
309
}
 
310
 
 
311
void RatingWidget::mouseMoveEvent(QMouseEvent* e)
 
312
{
 
313
    if (!(e->buttons() & Qt::LeftButton))
 
314
    {
 
315
        return;
 
316
    }
 
317
 
 
318
    if (hasFading() && d->fadingValue < 255)
 
319
    {
 
320
        return;
 
321
    }
 
322
 
 
323
    int pos = (e->x() - d->offset) / d->regPixmap.width() +1;
 
324
 
 
325
    if (d->rating != pos)
 
326
    {
 
327
        if (pos > RatingMax)       // NOTE: B.K.O. # 151357
 
328
        {
 
329
            pos = RatingMax;
 
330
        }
 
331
 
 
332
        if (pos < RatingMin)
 
333
        {
 
334
            pos = RatingMin;
 
335
        }
 
336
 
 
337
        d->rating = pos;
 
338
 
 
339
        if (d->tracking)
 
340
        {
 
341
            emit signalRatingChanged(d->rating);
 
342
        }
 
343
 
 
344
        emit signalRatingModified(d->rating);
 
345
        update();
 
346
    }
 
347
}
 
348
 
 
349
void RatingWidget::mouseReleaseEvent(QMouseEvent* e)
 
350
{
 
351
    if (e->button() != Qt::LeftButton)
 
352
    {
 
353
        return;
 
354
    }
 
355
 
 
356
    if (hasFading() && d->fadingValue < 255)
 
357
    {
 
358
        return;
 
359
    }
 
360
 
 
361
    emit signalRatingChanged(d->rating);
 
362
}
 
363
 
 
364
void RatingWidget::slotThemeChanged()
 
365
{
 
366
    d->regPixmap = QPixmap(15, 15);
 
367
    d->regPixmap.fill(Qt::transparent);
 
368
    d->selPixmap = QPixmap(15, 15);
 
369
    d->selPixmap.fill(Qt::transparent);
 
370
    d->disPixmap = QPixmap(15, 15);
 
371
    d->disPixmap.fill(Qt::transparent);
 
372
 
 
373
    QPainter p1(&d->regPixmap);
 
374
    p1.setRenderHint(QPainter::Antialiasing, true);
 
375
    p1.setBrush(palette().color(QPalette::Active, backgroundRole()));
 
376
    p1.setPen(palette().color(QPalette::Active, foregroundRole()));
 
377
    p1.drawPolygon(d->starPolygon, Qt::WindingFill);
 
378
    p1.end();
 
379
 
 
380
    QPainter p2(&d->selPixmap);
 
381
    p2.setRenderHint(QPainter::Antialiasing, true);
 
382
    p2.setBrush(kapp->palette().color(QPalette::Link));
 
383
    p2.setPen(palette().color(QPalette::Active, foregroundRole()));
 
384
    p2.drawPolygon(d->starPolygon, Qt::WindingFill);
 
385
    p2.end();
 
386
 
 
387
    QPainter p3(&d->disPixmap);
 
388
    p3.setRenderHint(QPainter::Antialiasing, true);
 
389
    p3.setBrush(palette().color(QPalette::Disabled, backgroundRole()));
 
390
    p3.setPen(palette().color(QPalette::Disabled, foregroundRole()));
 
391
    p3.drawPolygon(d->starPolygon, Qt::WindingFill);
 
392
    p3.end();
 
393
 
 
394
    setMinimumSize(QSize((d->regPixmap.width()+1)*RatingMax, d->regPixmap.height()));
 
395
    update();
 
396
}
 
397
 
 
398
void RatingWidget::paintEvent(QPaintEvent*)
 
399
{
 
400
    QPainter p(this);
 
401
 
 
402
    d->offset = (width() - RatingMax * (d->disPixmap.width()+1)) / 2;
 
403
 
 
404
    // Widget is disable : drawing grayed frame.
 
405
    if (!isEnabled())
 
406
    {
 
407
        int x = d->offset;
 
408
 
 
409
        for (int i = 0; i < RatingMax; ++i)
 
410
        {
 
411
            p.drawPixmap(x, 0, d->disPixmap);
 
412
            x += d->disPixmap.width()+1;
 
413
        }
 
414
    }
 
415
    else
 
416
    {
 
417
        int x       = d->offset;
 
418
        int rate    = d->rating != NoRating ? d->rating : 0;
 
419
        QPixmap sel = d->selPixmap;
 
420
        applyFading(sel);
 
421
 
 
422
        for (int i = 0; i < rate; ++i)
 
423
        {
 
424
            p.drawPixmap(x, 0, sel);
 
425
            x += sel.width()+1;
 
426
        }
 
427
 
 
428
        QPixmap reg = d->regPixmap;
 
429
        applyFading(reg);
 
430
 
 
431
        for (int i = rate; i < RatingMax; ++i)
 
432
        {
 
433
            p.drawPixmap(x, 0, reg);
 
434
            x += reg.width()+1;
 
435
        }
 
436
    }
 
437
 
 
438
    p.end();
 
439
}
 
440
 
 
441
void RatingWidget::applyFading(QPixmap& pix)
 
442
{
 
443
    if (hasFading() && d->fadingValue < 255)
 
444
    {
 
445
        QPixmap alphaMask(pix.width(), pix.height());
 
446
        const QColor color(d->fadingValue, d->fadingValue, d->fadingValue);
 
447
        alphaMask.fill(color);
 
448
        pix.setAlphaChannel(alphaMask);
 
449
    }
 
450
}
 
451
 
 
452
// -------------------------------------------------------------------------------
 
453
 
 
454
class RatingBox::RatingBoxPriv
 
455
{
 
456
 
 
457
public:
 
458
 
 
459
    RatingBoxPriv()
 
460
    {
 
461
        shortcut     = 0;
 
462
        ratingWidget = 0;
 
463
    }
 
464
 
 
465
    KSqueezedTextLabel* shortcut;
 
466
 
 
467
    RatingWidget*       ratingWidget;
 
468
};
 
469
 
 
470
RatingBox::RatingBox(QWidget* parent)
 
471
    : KVBox(parent), d(new RatingBoxPriv)
 
472
{
 
473
    setAttribute(Qt::WA_DeleteOnClose);
 
474
    setFocusPolicy(Qt::NoFocus);
 
475
 
 
476
    d->ratingWidget = new RatingWidget(this);
 
477
    d->ratingWidget->setTracking(false);
 
478
 
 
479
    d->shortcut = new KSqueezedTextLabel(this);
 
480
    QFont fnt   = d->shortcut->font();
 
481
    fnt.setItalic(true);
 
482
    d->shortcut->setFont(fnt);
 
483
    d->shortcut->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
 
484
    d->shortcut->setWordWrap(false);
 
485
 
 
486
    setMargin(0);
 
487
    setSpacing(0);
 
488
 
 
489
    // -------------------------------------------------------------
 
490
 
 
491
    connect(d->ratingWidget, SIGNAL(signalRatingModified(int)),
 
492
            this, SLOT(slotUpdateDescription(int)));
 
493
 
 
494
    connect(d->ratingWidget, SIGNAL(signalRatingChanged(int)),
 
495
            this, SIGNAL(signalRatingChanged(int)));
 
496
}
 
497
 
 
498
RatingBox::~RatingBox()
 
499
{
 
500
    delete d;
 
501
}
 
502
 
 
503
void RatingBox::slotUpdateDescription(int rating)
 
504
{
 
505
    KXmlGuiWindow* app = dynamic_cast<KXmlGuiWindow*>(kapp->activeWindow());
 
506
    if (app)
 
507
    {
 
508
        QAction* ac = app->actionCollection()->action(QString("rateshortcut-%1").arg(rating));
 
509
        if (ac)
 
510
            d->shortcut->setText(ac->shortcut().toString());
 
511
    }
 
512
}
 
513
 
 
514
// -------------------------------------------------------------------------------
 
515
 
 
516
RatingMenuAction::RatingMenuAction(QMenu* parent)
 
517
    : KActionMenu(parent)
 
518
{
 
519
    setText(i18n("Rating"));
 
520
    QWidgetAction* wa = new QWidgetAction(this);
 
521
    RatingBox* rb     = new RatingBox(parent);
 
522
    wa->setDefaultWidget(rb);
 
523
    addAction(wa);
 
524
 
 
525
    connect(rb, SIGNAL(signalRatingChanged(int)),
 
526
            this, SIGNAL(signalRatingChanged(int)));
 
527
 
 
528
    connect(rb, SIGNAL(signalRatingChanged(int)),
 
529
            parent, SLOT(close()));
 
530
}
 
531
 
 
532
RatingMenuAction::~RatingMenuAction()
 
533
{
 
534
}
 
535
 
 
536
}  // namespace Digikam