1 // For license of this file, see <project-root-folder>/LICENSE.md.
2
3 #include "gui/toolbars/statusbar.h"
4
5 #include "gui/dialogs/formmain.h"
6 #include "gui/reusable/plaintoolbutton.h"
7 #include "gui/reusable/progressbarwithtext.h"
8 #include "gui/tabwidget.h"
9 #include "miscellaneous/iconfactory.h"
10 #include "miscellaneous/mutex.h"
11
12 #include <QLabel>
13 #include <QToolButton>
14
StatusBar(QWidget * parent)15 StatusBar::StatusBar(QWidget* parent) : QStatusBar(parent) {
16 setSizeGripEnabled(false);
17 setContentsMargins(2, 0, 2, 2);
18
19 m_barProgressFeeds = new ProgressBarWithText(this);
20 m_barProgressFeeds->setTextVisible(true);
21 m_barProgressFeeds->setFixedWidth(230);
22 m_barProgressFeeds->setVisible(false);
23 m_barProgressFeeds->setObjectName(QSL("m_barProgressFeeds"));
24
25 m_barProgressFeedsAction = new QAction(qApp->icons()->fromTheme(QSL("application-rss+xml")), tr("Feed update progress bar"), this);
26 m_barProgressFeedsAction->setObjectName(QSL("m_barProgressFeedsAction"));
27
28 m_barProgressDownload = new ProgressBarWithText(this);
29 m_barProgressDownload->setTextVisible(true);
30 m_barProgressDownload->setFixedWidth(230);
31 m_barProgressDownload->setVisible(false);
32 m_barProgressDownload->setObjectName(QSL("m_barProgressDownload"));
33
34 m_barProgressDownloadAction = new QAction(qApp->icons()->fromTheme(QSL("emblem-downloads")), tr("File download progress bar"), this);
35 m_barProgressDownloadAction->setObjectName(QSL("m_barProgressDownloadAction"));
36
37 m_barProgressDownload->installEventFilter(this);
38 }
39
~StatusBar()40 StatusBar::~StatusBar() {
41 clear();
42 qDebugNN << LOGSEC_GUI "Destroying StatusBar instance.";
43 }
44
availableActions() const45 QList<QAction*> StatusBar::availableActions() const {
46 QList<QAction*> actions = qApp->userActions();
47
48 // Now, add placeholder actions for custom stuff.
49 actions << m_barProgressDownloadAction
50 << m_barProgressFeedsAction;
51
52 return actions;
53 }
54
activatedActions() const55 QList<QAction*> StatusBar::activatedActions() const {
56 return actions();
57 }
58
saveAndSetActions(const QStringList & actions)59 void StatusBar::saveAndSetActions(const QStringList& actions) {
60 qApp->settings()->setValue(GROUP(GUI), GUI::StatusbarActions, actions.join(QSL(",")));
61 loadSpecificActions(convertActions(actions));
62 }
63
defaultActions() const64 QStringList StatusBar::defaultActions() const {
65 return QString(GUI::StatusbarActionsDef).split(',',
66 #if QT_VERSION >= 0x050F00 // Qt >= 5.15.0
67 Qt::SplitBehaviorFlags::SkipEmptyParts);
68 #else
69 QString::SplitBehavior::SkipEmptyParts);
70 #endif
71 }
72
savedActions() const73 QStringList StatusBar::savedActions() const {
74 return qApp->settings()->value(GROUP(GUI),
75 SETTING(GUI::StatusbarActions)).toString().split(',',
76 #if QT_VERSION >= 0x050F00 // Qt >= 5.15.0
77 Qt::SplitBehaviorFlags::SkipEmptyParts);
78 #else
79 QString::SplitBehavior::SkipEmptyParts);
80 #endif
81 }
82
convertActions(const QStringList & actions)83 QList<QAction*> StatusBar::convertActions(const QStringList& actions) {
84 bool progress_visible = this->actions().contains(m_barProgressFeedsAction) && m_barProgressFeeds->isVisible();
85 QList<QAction*> available_actions = availableActions();
86 QList<QAction*> spec_actions;
87
88 // Iterate action names and add respectable
89 // actions into the toolbar.
90 for (const QString& action_name : actions) {
91 QAction* matching_action = findMatchingAction(action_name, available_actions);
92 QAction* action_to_add;
93 QWidget* widget_to_add;
94
95 if (matching_action == m_barProgressDownloadAction) {
96 widget_to_add = m_barProgressDownload;
97 action_to_add = m_barProgressDownloadAction;
98 widget_to_add->setVisible(false);
99 }
100 else if (matching_action == m_barProgressFeedsAction) {
101 widget_to_add = m_barProgressFeeds;
102 action_to_add = m_barProgressFeedsAction;
103 widget_to_add->setVisible(progress_visible);
104 }
105 else {
106 if (action_name == QSL(SEPARATOR_ACTION_NAME)) {
107 QLabel* lbl = new QLabel(QSL("•"), this);
108
109 widget_to_add = lbl;
110 action_to_add = new QAction(this);
111 action_to_add->setSeparator(true);
112 }
113 else if (action_name == QSL(SPACER_ACTION_NAME)) {
114 QLabel* lbl = new QLabel(QSL("\t\t"), this);
115
116 widget_to_add = lbl;
117 action_to_add = new QAction(this);
118 action_to_add->setIcon(qApp->icons()->fromTheme(QSL("system-search")));
119 action_to_add->setProperty("type", SPACER_ACTION_NAME);
120 action_to_add->setProperty("name", tr("Toolbar spacer"));
121 }
122 else if (matching_action != nullptr) {
123 // Add originally toolbar action.
124 auto* tool_button = new PlainToolButton(this);
125
126 tool_button->reactOnActionChange(matching_action);
127 widget_to_add = tool_button;
128 action_to_add = matching_action;
129 connect(tool_button, &PlainToolButton::clicked, matching_action, &QAction::trigger);
130 connect(matching_action, &QAction::changed, tool_button, &PlainToolButton::reactOnSenderActionChange);
131 }
132 else {
133 action_to_add = nullptr;
134 widget_to_add = nullptr;
135 }
136 }
137
138 if (action_to_add != nullptr && widget_to_add != nullptr) {
139 action_to_add->setProperty("widget", QVariant::fromValue(widget_to_add));
140 spec_actions.append(action_to_add);
141 }
142 }
143
144 return spec_actions;
145 }
146
loadSpecificActions(const QList<QAction * > & actions,bool initial_load)147 void StatusBar::loadSpecificActions(const QList<QAction*>& actions, bool initial_load) {
148 if (initial_load) {
149 clear();
150
151 for (QAction* act : actions) {
152 QWidget* widget = act->property("widget").isValid() ? qvariant_cast<QWidget*>(act->property("widget")) : nullptr;
153
154 addAction(act);
155
156 // And also add widget.
157 if (widget != nullptr) {
158 addPermanentWidget(widget);
159 }
160 }
161 }
162 }
163
eventFilter(QObject * watched,QEvent * event)164 bool StatusBar::eventFilter(QObject* watched, QEvent* event) {
165 if (watched == m_barProgressDownload) {
166 if (event->type() == QEvent::Type::MouseButtonPress) {
167 qApp->mainForm()->tabWidget()->showDownloadManager();
168 }
169 }
170
171 return false;
172 }
173
clear()174 void StatusBar::clear() {
175 while (!actions().isEmpty()) {
176 QAction* act = actions().at(0);
177 QWidget* widget = act->property("widget").isValid() ? static_cast<QWidget*>(act->property("widget").value<void*>()) : nullptr;
178
179 if (widget != nullptr) {
180 removeWidget(widget);
181
182 widget->setParent(qApp->mainFormWidget());
183 widget->setVisible(false);
184 }
185
186 removeAction(act);
187 }
188 }
189
showProgressFeeds(int progress,const QString & label)190 void StatusBar::showProgressFeeds(int progress, const QString& label) {
191 if (actions().contains(m_barProgressFeedsAction)) {
192 m_barProgressFeeds->setVisible(true);
193 m_barProgressFeeds->setFormat(label);
194
195 if (progress < 0) {
196 m_barProgressFeeds->setRange(0, 0);
197 }
198 else {
199 m_barProgressFeeds->setRange(0, 100);
200 m_barProgressFeeds->setValue(progress);
201 }
202 }
203 }
204
clearProgressFeeds()205 void StatusBar::clearProgressFeeds() {
206 m_barProgressFeeds->setVisible(false);
207 }
208
showProgressDownload(int progress,const QString & tooltip)209 void StatusBar::showProgressDownload(int progress, const QString& tooltip) {
210 if (actions().contains(m_barProgressDownloadAction)) {
211 m_barProgressDownload->setVisible(true);
212 m_barProgressDownload->setFormat(tooltip);
213 m_barProgressDownload->setToolTip(tooltip);
214
215 if (progress < 0) {
216 m_barProgressDownload->setRange(0, 0);
217 }
218 else {
219 m_barProgressDownload->setRange(0, 100);
220 m_barProgressDownload->setValue(progress);
221 }
222 }
223 }
224
clearProgressDownload()225 void StatusBar::clearProgressDownload() {
226 m_barProgressDownload->setVisible(false);
227 m_barProgressDownload->setValue(0);
228 }
229