swift
managedstatusbar.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2014 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
4 #include "gui/managedstatusbar.h"
5 
6 #include <QFontMetrics>
7 #include <QLabel>
8 #include <QSize>
9 #include <QSizePolicy>
10 #include <QStatusBar>
11 #include <QString>
12 #include <QTimer>
13 #include <QWidget>
14 #include <QtGlobal>
15 
16 #include "misc/iterator.h"
17 #include "misc/sequence.h"
18 
19 using namespace swift::misc;
20 
21 namespace swift::gui
22 {
23  CManagedStatusBar::CManagedStatusBar(QObject *parent) : QObject(parent)
24  {
25  this->setObjectName("qo_ManagedStatusBar");
26  }
27 
29  {
30  // we are not necessarily the owner of the status bar
31  m_statusBar->removeWidget(m_statusBarLabel);
32  m_statusBar->removeWidget(m_statusBarIcon);
33  m_statusBar->removeWidget(m_errorButton);
34  m_statusBar->removeWidget(m_warningButton);
35 
36  // labels will be deleted with status bar
37  if (m_ownedStatusBar) { delete m_statusBar; }
38  }
39 
40  void CManagedStatusBar::initStatusBar(QStatusBar *statusBar)
41  {
42  if (m_statusBar) { return; }
43  m_ownedStatusBar = statusBar ? false : true;
44  m_statusBar = statusBar ? statusBar : new QStatusBar();
45  if (m_statusBar->objectName().isEmpty()) { m_statusBar->setObjectName("sb_ManagedStatusBar"); }
46 
47  m_statusBarIcon = new QLabel(m_statusBar);
48  m_statusBarIcon->setObjectName(QString("lbl_StatusBarIcon").append(m_statusBar->objectName()));
49  m_statusBarLabel = new QLabel(m_statusBar);
50  m_statusBarLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
51  m_statusBarLabel->setObjectName(QString("lbl_StatusBarLabel").append(m_statusBar->objectName()));
52  m_warningButton = new QPushButton("WARN", m_statusBar);
53  m_warningButton->setObjectName(QString("btn_StatusBarWarn").append(m_statusBar->objectName()));
54  m_warningButton->setHidden(!m_showWarnButtonInitially);
55  m_warningButton->setToolTip("ACK and show logs");
56  connect(m_warningButton, &QPushButton::pressed, this, &CManagedStatusBar::pressedWarnButton);
57  m_errorButton = new QPushButton("ERROR", m_statusBar);
58  m_errorButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
59  m_errorButton->setObjectName(QString("btn_StatusBarError").append(m_statusBar->objectName()));
60  m_errorButton->setHidden(!m_showErrorButtonInitially);
61  m_errorButton->setToolTip("ACK and show logs");
62  connect(m_errorButton, &QPushButton::pressed, this, &CManagedStatusBar::pressedErrorButton);
63 
64  // use insert to insert from left to right
65  // this keeps any grip on the right size
66  m_statusBar->insertPermanentWidget(0, m_statusBarIcon, 0); // status icon
67  m_statusBar->insertPermanentWidget(1, m_statusBarLabel, 1); // status text
68  m_statusBar->insertPermanentWidget(2, m_warningButton, 0);
69  m_statusBar->insertPermanentWidget(3, m_errorButton, 0);
70 
71  // timer
72  m_timerStatusBar.setObjectName(this->objectName().append(":m_timerStatusBar"));
73  m_timerStatusBar.setSingleShot(true);
74  connect(&m_timerStatusBar, &QTimer::timeout, this, &CManagedStatusBar::clearStatusBar);
75 
76  // done when injected status bar
77  if (m_ownedStatusBar)
78  {
79  // self created status bar
80  QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
81  sizePolicy.setHorizontalStretch(0);
82  sizePolicy.setVerticalStretch(0);
83  sizePolicy.setHeightForWidth(m_statusBar->sizePolicy().hasHeightForWidth());
84 
85  m_statusBar->setMinimumHeight(
86  24); // with no minimum height the layout always adjustes when displaying a status message
87  m_statusBar->setSizePolicy(sizePolicy);
88  m_statusBar->setSizeGripEnabled(false);
89  }
90  }
91 
93  {
94  if (!m_warningButton) { m_showWarnButtonInitially = true; }
95  else { m_warningButton->setHidden(false); }
96  }
97 
99  {
100  if (!m_errorButton) { m_showErrorButtonInitially = true; }
101  else { m_errorButton->setHidden(false); }
102  }
103 
105  {
106  if (!m_statusBar) { return; }
107  m_statusBar->show();
108  }
109 
111  {
112  if (!m_statusBar) { return; }
113  m_statusBar->hide();
114 
115  // reset minimum width
116  if (m_ownedStatusBar) { m_statusBar->setMinimumWidth(50); }
117  }
118 
120  {
121  Q_ASSERT_X(m_statusBarIcon, Q_FUNC_INFO, "Missing status bar icon");
122  Q_ASSERT_X(m_statusBar, Q_FUNC_INFO, "Missing status bar");
123  Q_ASSERT_X(m_statusBarLabel, Q_FUNC_INFO, "Missing label");
124 
125  // already displaying a message with severity higher than this one?
126  if (statusMessage.isEmpty()) { return; }
127  if (!statusMessage.isSeverityHigherOrEqual(m_currentSeverity)) { return; }
128 
129  // used with log subscriber, make sure it is not displayed twice
130  if (statusMessage.wasHandledBy(this)) { return; }
131  statusMessage.markAsHandledBy(this);
132 
133  this->show();
134  m_timerStatusBar.start(3000); // start / restart
135  m_statusBarIcon->setPixmap(CIcon(statusMessage.toIcon()));
136 
137  // restrict size for own status bars
138  const QSize size = m_statusBar->window()->size();
139  const int w = qRound(0.95 * size.width());
140  if (m_ownedStatusBar) { m_statusBar->setMaximumWidth(w); }
141 
142  if (m_elideMode != Qt::ElideNone)
143  {
144  const QFontMetrics metrics(m_statusBarLabel->font());
145  const QString elidedText = metrics.elidedText(statusMessage.getMessage(), m_elideMode, qRound(0.90 * w));
146  m_statusBarLabel->setText(elidedText);
147  }
148  else { m_statusBarLabel->setText(statusMessage.getMessage()); }
149  m_currentSeverity = statusMessage.getSeverity();
150  }
151 
153  {
154  for (const CStatusMessage &m : statusMessages) { this->displayStatusMessage(m); }
155  }
156 
158  {
159  if (m_statusBar) { m_statusBar->setSizeGripEnabled(enabled); }
160  }
161 
162  void CManagedStatusBar::clearStatusBar()
163  {
164  m_currentSeverity = StatusSeverity::SeverityDebug;
165  if (!m_statusBar) { return; }
166  m_statusBarIcon->clear();
167  m_statusBarLabel->clear();
168  }
169 
170  void CManagedStatusBar::pressedWarnButton()
171  {
172  Q_ASSERT_X(m_warningButton, Q_FUNC_INFO, "Missing warning button");
173  m_warningButton->setHidden(true);
174  emit requestLogPage();
175  }
176 
177  void CManagedStatusBar::pressedErrorButton()
178  {
179  Q_ASSERT_X(m_errorButton, Q_FUNC_INFO, "Missing error button");
180  m_errorButton->setHidden(true);
181  emit requestLogPage();
182  }
183 
184 } // namespace swift::gui
void showWarningButton()
Show warning log button.
void showErrorButton()
Show warning error button.
void setSizeGripEnabled(bool enabled)
Enabled size grip.
void displayStatusMessages(const swift::misc::CStatusMessageList &statusMessages)
Display status messages.
void displayStatusMessage(const swift::misc::CStatusMessage &statusMessage)
Display status message.
void initStatusBar(QStatusBar *statusBar=nullptr)
Init.
virtual ~CManagedStatusBar()
Destructor.
void requestLogPage()
Request to show the log page.
Value object for icons. An icon is stored in the global icon repository and identified by its index....
Definition: icon.h:39
bool isEmpty() const
Message empty.
Streamable status message, e.g.
void markAsHandledBy(const QObject *object) const
Mark the message as having been handled by the given object.
bool isSeverityHigherOrEqual(CStatusMessage::StatusSeverity severity) const
Is this message's severity higher or equal.
StatusSeverity getSeverity() const
Message severity.
QString getMessage() const
Message.
CIcons::IconIndex toIcon() const
Representing icon.
bool wasHandledBy(const QObject *object) const
Returns true if the message was marked as having been handled by the given object.
Status messages, e.g. from Core -> GUI.
GUI related classes.
Free functions in swift::misc.