1 /*
2  * issuescounter.cpp
3  * Copyright 2019, Thorbjørn Lindeijer <bjorn@lindeijer.nl>
4  *
5  * This file is part of Tiled.
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "issuescounter.h"
22 
23 #include "issuesmodel.h"
24 #include "utils.h"
25 
26 #include <QApplication>
27 #include <QHBoxLayout>
28 #include <QLabel>
29 #include <QPaintEvent>
30 #include <QStyleOption>
31 #include <QStylePainter>
32 
33 namespace Tiled {
34 
IssuesCounter(QWidget * parent)35 IssuesCounter::IssuesCounter(QWidget *parent)
36     : QToolButton(parent)
37     , mErrorIcon(new QLabel)
38     , mErrorCount(new QLabel)
39     , mWarningIcon(new QLabel)
40     , mWarningCount(new QLabel)
41 {
42     auto layout = new QHBoxLayout;
43     const int margin = Utils::dpiScaled(2);
44     layout->setContentsMargins(margin, margin, margin, margin);
45 
46     int spacing = Utils::dpiScaled(5);
47     layout->addSpacing(spacing);
48     layout->addWidget(mErrorIcon);
49     layout->addWidget(mErrorCount);
50     layout->addWidget(mWarningIcon);
51     layout->addWidget(mWarningCount);
52     layout->addSpacing(spacing);
53 
54     setLayout(layout);
55     setAutoRaise(true);
56 
57     updateLabels();
58 
59     const auto &issuesModel = IssuesModel::instance();
60     connect(&issuesModel, &IssuesModel::rowsInserted, this, &IssuesCounter::updateLabels);
61     connect(&issuesModel, &IssuesModel::rowsRemoved, this, &IssuesCounter::updateLabels);
62     connect(&issuesModel, &IssuesModel::modelReset, this, &IssuesCounter::updateLabels);
63 }
64 
65 // Override paintEvent because we don't want to draw the button's text
paintEvent(QPaintEvent * event)66 void IssuesCounter::paintEvent(QPaintEvent *event)
67 {
68     QStylePainter p(this);
69 
70     QStyleOptionButton option;
71     option.initFrom(this);
72     option.features = underMouse() ? QStyleOptionButton::None : QStyleOptionButton::Flat;
73     if (isDown())
74         option.state |= QStyle::State_Sunken;
75     if (isChecked())
76         option.state |= QStyle::State_On;
77 
78     p.drawPrimitive(QStyle::PE_PanelButtonCommand, option);
79 
80     QWidget::paintEvent(event);
81 }
82 
updateLabels()83 void IssuesCounter::updateLabels()
84 {
85     const auto &issuesModel = IssuesModel::instance();
86     const int iconSize = Utils::dpiScaled(16);
87     const int errorCount = issuesModel.errorCount();
88     const int warningCount = issuesModel.warningCount();
89     const bool hasErrors = errorCount > 0;
90     const bool hasWarnings = warningCount > 0;
91 
92     const QFont font = QApplication::font();
93     QFont boldFont = font;
94     boldFont.setBold(true);
95 
96     mErrorCount->setText(QString::number(errorCount));
97     mErrorCount->setEnabled(hasErrors);
98     mErrorCount->setFont(hasErrors ? boldFont : font);
99 
100     mWarningCount->setText(QString::number(warningCount));
101     mWarningCount->setEnabled(hasWarnings);
102     mWarningCount->setFont(hasWarnings ? boldFont : font);
103 
104     const QIcon::Mode errorIconMode = hasErrors ? QIcon::Normal : QIcon::Disabled;
105     const QIcon::Mode warningIconMode = hasWarnings ? QIcon::Normal : QIcon::Disabled;
106 
107     mErrorIcon->setPixmap(issuesModel.errorIcon().pixmap(iconSize, errorIconMode));
108     mWarningIcon->setPixmap(issuesModel.warningIcon().pixmap(iconSize, warningIconMode));
109 
110     const QString errorText = tr("%n error(s)", "", errorCount);
111     const QString warningText = tr("%n warning(s)", "", warningCount);
112 
113     setToolTip(QStringLiteral("%1, %2").arg(errorText, warningText));
114 }
115 
116 } // namespace Tiled
117 
118 #include "moc_issuescounter.cpp"
119