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 
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);
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);
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
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.
QString elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags) const const
void clear()
void setPixmap(const QPixmap &)
void setText(const QString &)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void setObjectName(QAnyStringView name)
int width() const const
void setHeightForWidth(bool dependent)
void setHorizontalStretch(int stretchFactor)
void setVerticalStretch(int stretchFactor)
int insertPermanentWidget(int index, QWidget *widget, int stretch)
void removeWidget(QWidget *widget)
void setSizeGripEnabled(bool)
ElideNone
void setSingleShot(bool singleShot)
void start()
void timeout()
void hide()
void setMaximumWidth(int maxw)
void setMinimumHeight(int minh)
void setMinimumWidth(int minw)
void setHidden(bool hidden)
void show()
void setSizePolicy(QSizePolicy)
void setToolTip(const QString &)
QWidget * window() const const