1 /*
2 * newsbutton.cpp
3 * Copyright 2018, 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 "newsbutton.h"
22
23 #include "newsfeed.h"
24 #include "preferences.h"
25 #include "utils.h"
26
27 #include <QDesktopServices>
28 #include <QEvent>
29 #include <QMenu>
30 #include <QPainter>
31
32 #ifdef TILED_SNAPSHOT
33 static const char newsArchiveUrl[] = "https://thorbjorn.itch.io/tiled/devlog";
34 #else
35 static const char newsArchiveUrl[] = "https://www.mapeditor.org/news";
36 #endif
37
38 namespace Tiled {
39
NewsButton(QWidget * parent)40 NewsButton::NewsButton(QWidget *parent)
41 : QToolButton(parent)
42 , mReadIcon(QLatin1String("://images/16/mail-read-symbolic.png"))
43 , mUnreadIcon(QLatin1String("://images/16/mail-unread-symbolic.png"))
44 {
45 const auto preferences = Preferences::instance();
46 setVisible(preferences->displayNews());
47 connect(preferences, &Preferences::displayNewsChanged, this, &NewsButton::setVisible);
48
49 auto &feed = NewsFeed::instance();
50
51 setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
52 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
53 setAutoRaise(true);
54 setToolTip(feed.errorString());
55
56 connect(&feed, &NewsFeed::refreshed,
57 this, &NewsButton::refreshButton);
58 connect(&feed, &NewsFeed::errorStringChanged,
59 this, &NewsButton::setToolTip);
60
61 connect(this, &QToolButton::pressed,
62 this, &NewsButton::showNewsMenu);
63
64 refreshButton();
65 retranslateUi();
66 }
67
changeEvent(QEvent * event)68 void NewsButton::changeEvent(QEvent *event)
69 {
70 QToolButton::changeEvent(event);
71 switch (event->type()) {
72 case QEvent::LanguageChange:
73 retranslateUi();
74 break;
75 default:
76 break;
77 }
78 }
79
refreshButton()80 void NewsButton::refreshButton()
81 {
82 auto &feed = NewsFeed::instance();
83 auto unreadCount = feed.unreadCount();
84
85 if (unreadCount > 0) {
86 QPixmap numberPixmap(Utils::smallIconSize());
87 numberPixmap.fill(Qt::transparent);
88
89 QPainter painter(&numberPixmap);
90 painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
91
92 painter.setBrush(QColor(250, 92, 92));
93 painter.setPen(Qt::NoPen);
94 painter.drawEllipse(numberPixmap.rect().adjusted(1, 1, -1, -1));
95
96 auto font = painter.font();
97 font.setBold(true);
98 painter.setFont(font);
99 painter.setBrush(Qt::white);
100 painter.setPen(Qt::white);
101 painter.drawText(numberPixmap.rect(), Qt::AlignCenter, unreadCount < 5 ? QString::number(unreadCount) :
102 QStringLiteral("!"));
103
104 setIcon(QIcon(numberPixmap));
105 } else {
106 setIcon(QIcon());
107 }
108
109 setEnabled(!feed.isEmpty());
110 }
111
showNewsMenu()112 void NewsButton::showNewsMenu()
113 {
114 auto newsFeedMenu = new QMenu;
115 auto &feed = NewsFeed::instance();
116
117 for (const NewsItem &newsItem : feed.newsItems()) {
118 QAction *action = newsFeedMenu->addAction(newsItem.title, [=] {
119 QDesktopServices::openUrl(newsItem.link);
120 NewsFeed::instance().markRead(newsItem);
121 });
122
123 if (feed.isUnread(newsItem)) {
124 QFont f = action->font();
125 f.setBold(true);
126 action->setFont(f);
127 action->setIcon(mUnreadIcon);
128 } else {
129 action->setIcon(mReadIcon);
130 }
131 }
132
133 newsFeedMenu->addSeparator();
134 #ifdef TILED_SNAPSHOT
135 QAction *action = newsFeedMenu->addAction(tr("View All Posts"));
136 #else
137 QAction *action = newsFeedMenu->addAction(tr("News Archive"));
138 #endif
139 connect(action, &QAction::triggered, [] {
140 QDesktopServices::openUrl(QUrl(QLatin1String(newsArchiveUrl)));
141 NewsFeed::instance().markAllRead();
142 });
143
144 auto size = newsFeedMenu->sizeHint();
145 auto rect = QRect(mapToGlobal(QPoint(width() - size.width(), -size.height())), size);
146 newsFeedMenu->setGeometry(rect);
147 newsFeedMenu->exec();
148
149 setDown(false);
150 }
151
retranslateUi()152 void NewsButton::retranslateUi()
153 {
154 #ifdef TILED_SNAPSHOT
155 setText(tr("Devlog"));
156 #else
157 setText(tr("News"));
158 #endif
159 }
160
161 } // namespace Tiled
162
163 #include "moc_newsbutton.cpp"
164