1 #include "library/stareditor.h"
2
3 #include <QStylePainter>
4
5 #include "library/starrating.h"
6 #include "moc_stareditor.cpp"
7 #include "util/painterscope.h"
8
9 // We enable mouse tracking on the widget so we can follow the cursor even
10 // when the user doesn't hold down any mouse button. We also turn on
11 // QWidget's auto-fill background feature to obtain an opaque background.
12 // (Without the call, the view's background would shine through the editor.)
13
14 /// StarEditor inherits QWidget and is used by StarDelegate to let the user
15 /// edit a star rating in the library using the mouse.
16 ///
17 /// The class has been adapted from the official "Star Delegate Example",
18 /// see http://doc.trolltech.com/4.5/itemviews-stardelegate.html
StarEditor(QWidget * parent,QTableView * pTableView,const QModelIndex & index,const QStyleOptionViewItem & option)19 StarEditor::StarEditor(QWidget *parent, QTableView* pTableView,
20 const QModelIndex& index,
21 const QStyleOptionViewItem& option)
22 : QWidget(parent),
23 m_pTableView(pTableView),
24 m_index(index),
25 m_styleOption(option) {
26 setMouseTracking(true);
27 }
28
sizeHint() const29 QSize StarEditor::sizeHint() const {
30 return m_starRating.sizeHint();
31 }
32
33 // static
renderHelper(QPainter * painter,QTableView * pTableView,const QStyleOptionViewItem & option,StarRating * pStarRating)34 void StarEditor::renderHelper(QPainter* painter,
35 QTableView* pTableView,
36 const QStyleOptionViewItem& option,
37 StarRating* pStarRating) {
38 PainterScope painterScope(painter);
39
40 painter->setClipRect(option.rect);
41
42 if (pTableView != nullptr) {
43 QStyle* style = pTableView->style();
44 if (style != nullptr) {
45 style->drawControl(QStyle::CE_ItemViewItem, &option, painter,
46 pTableView);
47 }
48 }
49
50 // Set the palette appropriately based on whether the row is selected or
51 // not. We also have to check if it is inactive or not and use the
52 // appropriate ColorGroup.
53 QPalette::ColorGroup cg = option.state & QStyle::State_Enabled
54 ? QPalette::Normal : QPalette::Disabled;
55 if (cg == QPalette::Normal && !(option.state & QStyle::State_Active)) {
56 cg = QPalette::Inactive;
57 }
58
59 if (option.state & QStyle::State_Selected) {
60 painter->setBrush(option.palette.color(cg, QPalette::HighlightedText));
61 } else {
62 painter->setBrush(option.palette.color(cg, QPalette::Text));
63 }
64
65 pStarRating->paint(painter, option.rect);
66 }
67
paintEvent(QPaintEvent *)68 void StarEditor::paintEvent(QPaintEvent*) {
69 // If a StarEditor is open, by definition the mouse is hovering over us.
70 m_styleOption.state |= QStyle::State_MouseOver;
71 m_styleOption.rect = rect();
72
73 if (m_pTableView) {
74 QItemSelectionModel* selectionModel = m_pTableView->selectionModel();
75 if (selectionModel && selectionModel->isSelected(m_index)) {
76 m_styleOption.state |= QStyle::State_Selected;
77 }
78 }
79
80 QPainter painter(this);
81 renderHelper(&painter, m_pTableView, m_styleOption, &m_starRating);
82 }
83
mouseMoveEvent(QMouseEvent * event)84 void StarEditor::mouseMoveEvent(QMouseEvent *event) {
85 int star = starAtPosition(event->x());
86
87 if (star != m_starRating.starCount() && star != -1) {
88 m_starRating.setStarCount(star);
89 update();
90 }
91 }
92
leaveEvent(QEvent *)93 void StarEditor::leaveEvent(QEvent*) {
94 m_starRating.setStarCount(0);
95 update();
96 }
97
mouseReleaseEvent(QMouseEvent *)98 void StarEditor::mouseReleaseEvent(QMouseEvent* /* event */) {
99 emit editingFinished();
100 }
101
starAtPosition(int x)102 int StarEditor::starAtPosition(int x) {
103 // If the mouse is very close to the left edge, set 0 stars.
104 if (x < m_starRating.sizeHint().width() * 0.05) {
105 return 0;
106 }
107 int star = (x / (m_starRating.sizeHint().width() / m_starRating.maxStarCount())) + 1;
108
109 if (star <= 0 || star > m_starRating.maxStarCount()) {
110 return 0;
111 }
112 return star;
113 }
114