swift
overlaymessagesframe.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2015 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #ifndef SWIFT_GUI_OVERLAYMESSAGES_FRAME_H
7 #define SWIFT_GUI_OVERLAYMESSAGES_FRAME_H
8 
9 #include <functional>
10 
11 #include <QDockWidget>
12 #include <QFrame>
13 #include <QKeyEvent>
14 #include <QMessageBox>
15 #include <QObject>
16 #include <QSize>
17 #include <QString>
18 #include <QTabWidget>
19 #include <QTableView>
20 #include <QTreeView>
21 #include <QUrl>
22 #include <QWizardPage>
23 
26 #include "gui/guiutility.h"
27 #include "gui/overlaymessages.h"
28 #include "gui/swiftguiexport.h"
29 #include "misc/logmessage.h"
31 #include "misc/pixmap.h"
32 #include "misc/statusmessagelist.h"
33 #include "misc/variant.h"
34 
35 class QKeyEvent;
36 class QPaintEvent;
37 
38 namespace swift::gui
39 {
46  template <class WIDGET>
47  class COverlayMessagesBase : public WIDGET
48  {
49  public:
51  virtual ~COverlayMessagesBase() override {}
52 
55  void initOverlayMessages(QSize inner = {})
56  {
57  if (m_overlayMessages) { return; }
58  if (inner.isNull()) { inner = this->innerFrameSize(); }
59 
60  m_overlayMessages = new COverlayMessages(inner.width(), inner.height(), this);
62  m_overlayMessages->setForceSmall(m_forceSmallMsgs);
63  m_overlayMessages->setReducedInfo(m_reducedInfo);
64  }
65 
67  void activateTextMessages(bool activate)
68  {
69  this->initOverlayMessages();
71  }
72 
75 
77  void setOverlaySizeFactors(double widthFactor, double heightFactor, double middleFactor = 2)
78  {
79  m_widthFactor = widthFactor;
80  m_heightFactor = heightFactor;
81  if (middleFactor >= 0) { m_middleFactor = middleFactor; }
82  }
83 
85  void setForceSmall(bool force)
86  {
87  m_forceSmallMsgs = force;
89  }
90 
92  void setReducedInfo(bool reduced)
93  {
94  m_reducedInfo = reduced;
96  }
97 
100  bool appendOldMessages, const QString &confirmationMessage,
101  std::function<void()> okLambda,
103  std::chrono::milliseconds timeout = std::chrono::milliseconds(0))
104  {
105  if (messages.isEmpty()) { return; }
106  this->initInnerFrame();
107  if (!this->hasMinimumSize(150, 150)) { return; }
108  m_overlayMessages->showOverlayMessagesWithConfirmation(messages, appendOldMessages, confirmationMessage,
109  okLambda, defaultButton, timeout);
110  WIDGET::repaint();
111  }
112 
115  {
116  if (!m_overlayMessages) { return; }
118  }
119 
122  {
123  if (!m_overlayMessages) { return; }
125  }
126 
128  void showOverlayMessages(const swift::misc::CStatusMessageList &messages, bool appendOldMessages = false,
129  std::chrono::milliseconds timeout = std::chrono::milliseconds(0))
130  {
131  if (messages.isEmpty()) { return; }
132  this->initInnerFrame();
133  m_overlayMessages->showOverlayMessages(messages, appendOldMessages, timeout);
134  WIDGET::repaint();
135  }
136 
139  bool appendOldMessages = false,
140  std::chrono::milliseconds timeout = std::chrono::milliseconds(0))
141  {
142  if (messages.isEmpty()) { return; }
143  this->initInnerFrame();
144  m_overlayMessages->showOverlayMessagesOrSingleMessage(messages, appendOldMessages, timeout);
145  WIDGET::repaint();
146  }
147 
150  bool appendOldMessages = false,
151  std::chrono::milliseconds timeout = std::chrono::milliseconds(0))
152  {
153  if (messages.isEmpty()) { return; }
154  this->initInnerFrame();
155  m_overlayMessages->showOverlayMessagesOrHTMLMessage(messages, appendOldMessages, timeout);
156  WIDGET::repaint();
157  }
158 
161  {
162  m_overlayMessages->sortOverlayMessages(property, order);
163  }
164 
167  {
169  }
170 
173  std::chrono::milliseconds timeout = std::chrono::milliseconds(0))
174  {
175  if (message.isEmpty()) { return false; }
176  this->initInnerFrame();
177  m_overlayMessages->showOverlayMessage(message, timeout);
178  WIDGET::repaint();
179  return true;
180  }
181 
184  std::chrono::milliseconds timeout = std::chrono::milliseconds(0))
185  {
186  if (textMessage.isEmpty()) { return false; }
187  this->initInnerFrame();
188  m_overlayMessages->showOverlayTextMessage(textMessage, timeout);
189  WIDGET::repaint();
190  return true;
191  }
192 
195  std::chrono::milliseconds timeout = std::chrono::milliseconds(0))
196  {
199  {
200  this->initInnerFrame(0.75, 0.75);
201  if (!this->hasMinimumSize(150, 150)) { return; }
202  }
203  else { this->initInnerFrame(); }
204 
205  m_overlayMessages->showOverlayVariant(variant, timeout);
206  WIDGET::repaint();
207  }
208 
211  std::chrono::milliseconds timeout = std::chrono::milliseconds(0))
212  {
213  this->initInnerFrame();
214  m_overlayMessages->showOverlayImage(pixmap, timeout);
215  WIDGET::repaint();
216  }
217 
219  bool showOverlayHTMLMessage(const QString &htmlMessage,
220  std::chrono::milliseconds timeout = std::chrono::milliseconds(0))
221  {
222  this->initMinimalFrame();
223  m_overlayMessages->showHTMLMessage(htmlMessage, timeout);
224  WIDGET::repaint();
225  return true;
226  }
227 
230  std::chrono::milliseconds timeout = std::chrono::milliseconds(0))
231  {
232  this->initMinimalFrame();
233  m_overlayMessages->showHTMLMessage(message, timeout);
234  WIDGET::repaint();
235  return true;
236  }
237 
239  void showDownloadProgress(int progress, qint64 current, qint64 max, const QUrl &url,
240  std::chrono::milliseconds timeout = std::chrono::milliseconds(0))
241  {
242  this->initMinimalFrame();
243  m_overlayMessages->showDownloadProgress(progress, current, max, url, timeout);
244  WIDGET::repaint();
245  }
246 
249  {
250  this->initInnerFrame(0.75, 0.75);
251  if (!this->hasMinimumSize(150, 150)) { return; }
253  WIDGET::repaint();
254  }
255 
258  {
259  this->initInnerFrame(0.75, 0.75);
260  if (!this->hasMinimumSize(150, 150)) { return; }
262  WIDGET::repaint();
263  }
264 
265  protected:
267 
270  {
271  this->setWindowFlags(f);
272  const bool isFrameless = CGuiUtility::isMainWindowFrameless();
273  m_middleFactor = isFrameless ? 1.25 : 1.5; // 2 is middle in normal window
274  }
275 
277  void initInnerFrame(double widthFactor = -1, double heightFactor = -1)
278  {
279  const QSize inner(innerFrameSize(widthFactor, heightFactor));
280  if (!m_overlayMessages)
281  {
282  // lazy init
283  this->initOverlayMessages(inner);
284  }
285 
286  Q_ASSERT(m_overlayMessages);
287 
288  const QPoint middle = WIDGET::geometry().center();
289  const int w = inner.width();
290  const int h = inner.height();
291  const int x = middle.x() - w / 2;
292  const int y = qRound(middle.y() - h / m_middleFactor);
293 
294  m_overlayMessages->setGeometry(x, y, w, h);
296  }
297 
299  void initMinimalFrame(int lines = 4)
300  {
301  this->initInnerFrame();
302 
303  // get logical resolution
304  constexpr int MinHeight = 100;
305  QSizeF s = CGuiUtility::fontMetricsEstimateSize(100, lines, true); // 2 lines for header
306  if (s.height() < MinHeight) { s.setHeight(MinHeight); }
307 
308  const QSize inner(innerFrameSize());
309  const QPoint middle = WIDGET::geometry().center();
310  const int w = qMin(inner.width(), qRound(s.width()));
311  const int h = qMin(inner.height(), qRound(s.height()));
312  const int x = middle.x() - w / 2;
313  const int y = qRound(middle.y() - h / m_middleFactor);
314  m_overlayMessages->setGeometry(x, y, w, h);
315  }
316 
318  bool hasMinimumSize(int w, int h) const
319  {
320  if (w > 0 && m_overlayMessages->width() < w)
321  {
322  swift::misc::CLogMessage(this).info(u"Overlay widget too small (w)");
323  return false;
324  }
325 
326  if (h > 0 && m_overlayMessages->height() < h)
327  {
328  swift::misc::CLogMessage(this).info(u"Overlay widget too small (h)");
329  return false;
330  }
331  return true;
332  }
333 
335  virtual void keyPressEvent(QKeyEvent *event) override
336  {
337  if (m_overlayMessages && event->key() == Qt::Key_Escape)
338  {
340  event->accept();
341  }
342  else { WIDGET::keyPressEvent(event); }
343  }
344 
346  virtual void resizeEvent(QResizeEvent *event) override
347  {
348  WIDGET::resizeEvent(event);
350  }
351 
352  private:
354  QSize innerFrameSize(double widthFactor = -1, double heightFactor = -1) const
355  {
356  // check against minimum if widget is initialized, but not yet resized
357  const int w = std::max(WIDGET::width(), WIDGET::minimumWidth());
358  const int h = std::max(WIDGET::height(), WIDGET::minimumHeight());
359 
360  widthFactor = qMin(widthFactor < 0 ? m_widthFactor : widthFactor, 0.95);
361  heightFactor = qMin(heightFactor < 0 ? m_heightFactor : heightFactor, 0.95);
362 
363  int wInner = qRound(widthFactor * w);
364  int hInner = qRound(heightFactor * h);
365  if (wInner > WIDGET::maximumWidth()) { wInner = WIDGET::maximumWidth(); }
366  if (hInner > WIDGET::maximumHeight()) { hInner = WIDGET::maximumHeight(); }
367  return QSize(wInner, hInner);
368  }
369 
370  bool m_forceSmallMsgs = false;
371  bool m_reducedInfo = false;
372  double m_widthFactor = 0.7;
373  double m_heightFactor = 0.6;
374  double m_middleFactor = 2;
375  };
376 
381  {
382  Q_OBJECT
383 
384  public:
386  explicit COverlayMessagesFrame(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
387 
388  signals:
391 
394 
397  };
398 
403  public COverlayMessagesFrame,
405  {
406  Q_OBJECT
407 
408  public:
412 
413  private:
415  bool isForwardingOverlayMessages() const;
416  };
417 
422  {
423  Q_OBJECT
424 
425  public:
427  explicit COverlayMessagesTabWidget(QWidget *parent = nullptr);
428  };
429 
434  {
435  Q_OBJECT
436 
437  public:
439  explicit COverlayMessagesWizardPage(QWidget *parent = nullptr);
440  };
441 
446  {
447  Q_OBJECT
448 
449  public:
451  explicit COverlayMessagesDockWidget(QWidget *parent = nullptr);
452  };
453 
458  {
459  Q_OBJECT
460 
461  public:
463  explicit COverlayMessagesTableView(QWidget *parent = nullptr);
464  };
465 
470  {
471  Q_OBJECT
472 
473  public:
475  explicit COverlayMessagesTreeView(QWidget *parent = nullptr);
476  };
477 
478 } // namespace swift::gui
479 
480 #endif // SWIFT_GUI_OVERLAYMESSAGES_FRAME_H
Helper class: If a component is residing in an dockable widget. This class provides access to its inf...
static QSizeF fontMetricsEstimateSize(int xCharacters, int yCharacters, bool withRatio=false)
Estimate size based on current font.
Definition: guiutility.cpp:756
static bool isMainWindowFrameless()
Is main window frameless?
Definition: guiutility.cpp:178
Base class to display overlay messages in different widgets (nested in this widget).
COverlayMessages * m_overlayMessages
embedded QFrame with status messages
void showOverlayImage(const swift::misc::CPixmap &pixmap, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Image.
void closeOverlay()
Close button clicked.
bool showOverlayHTMLMessage(const QString &htmlMessage, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
HTML message.
void clearOverlayMessages()
Clear the overlay messages.
virtual ~COverlayMessagesBase()
Destructor.
bool showOverlayMessage(const swift::misc::CStatusMessage &message, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show single message.
void showOverlayMessages(const swift::misc::CStatusMessageList &messages, bool appendOldMessages=false, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show multiple messages.
void showOverlayMessagesWithConfirmation(const swift::misc::CStatusMessageList &messages, bool appendOldMessages, const QString &confirmationMessage, std::function< void()> okLambda, QMessageBox::StandardButton defaultButton=QMessageBox::Cancel, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show multiple messages with confirmation bar.
void showOverlayVariant(const swift::misc::CVariant &variant, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Display one of the supported types.
void initOverlayMessages(QSize inner={})
Init, normally we use lazy init, but by calling init explicitly we can force initalization.
void showStatusMessagesFrame()
Show the inner frame.
void sortOverlayMessages(const swift::misc::CPropertyIndex &property, Qt::SortOrder order)
Sort of overlay messages.
void setForceSmall(bool force)
Force small (smaller layout)
bool showOverlayHTMLMessage(const swift::misc::CStatusMessage &message, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
HTML message.
COverlayMessagesBase(QWidget *parent, Qt::WindowFlags f=Qt::WindowFlags())
Constructor.
void initInnerFrame(double widthFactor=-1, double heightFactor=-1)
Init the inner frame (if not yet initialized)
virtual void keyPressEvent(QKeyEvent *event)
void showOverlayMessagesOrSingleMessage(const swift::misc::CStatusMessageList &messages, bool appendOldMessages=false, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show multiple messages or a single message.
void initMinimalFrame(int lines=4)
Init a minimal frame (smaller as the normal one)
bool hasMinimumSize(int w, int h) const
Check minimum height/width.
void activateTextMessages(bool activate)
Active send/receive of text messages.
bool showOverlayTextMessage(const swift::misc::network::CTextMessage &textMessage, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Info message, based on text message.
void showOverlayInlineTextMessage(components::TextMessageTab tab)
Image.
void showDownloadProgress(int progress, qint64 current, qint64 max, const QUrl &url, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Download progress.
void setOverlayMessagesSorting(const swift::misc::CPropertyIndex &property, Qt::SortOrder order)
Set sorting of overlay messages.
void setOverlaySizeFactors(double widthFactor, double heightFactor, double middleFactor=2)
Set the size factors.
void showOverlayMessagesOrHTMLMessage(const swift::misc::CStatusMessageList &messages, bool appendOldMessages=false, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show multiple messages or a single message (HTML)
void setReducedInfo(bool reduced)
Display reduced information.
void showOverlayInlineTextMessage(const swift::misc::aviation::CCallsign &callsign)
Image.
virtual void resizeEvent(QResizeEvent *event)
Using this class provides a QDockWidget with the overlay functionality already integrated.
Using this class provides a QFrame with the overlay and dock widget functionality already integrated.
Using this class provides a QFrame with the overlay functionality already integrated.
void requestTextMessageEntryCallsign(const swift::misc::aviation::CCallsign &callsign)
Request an text message entry.
void requestTextMessageWidget(const swift::misc::aviation::CCallsign &callsign)
Request a text message widget.
void requestTextMessageEntryTab(components::TextMessageTab tab)
Request an text message entry.
Display status messages (nested in the parent widget)
void sortOverlayMessages(const swift::misc::CPropertyIndex &propertyIndex, Qt::SortOrder order=Qt::AscendingOrder)
Sort of overlay messages.
void showOverlayMessagesOrSingleMessage(const swift::misc::CStatusMessageList &messages, bool appendOldMessages=false, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show multiple messages or a single message.
void activateTextMessages(bool activate)
Active send/receive of text messages.
bool isTextMessagesActivated() const
Are text messages.
void showOverlayVariant(const swift::misc::CVariant &variant, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Display one of the supported types.
void showDownloadProgress(int progress, qint64 current, qint64 max, const QUrl &url, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Download progress.
void setOverlayMessagesSorting(const swift::misc::CPropertyIndex &propertyIndex, Qt::SortOrder order=Qt::AscendingOrder)
Set sorting of overlay messages.
void clearOverlayMessages()
Clear the overlay messages.
void close()
Close button clicked.
void showOverlayTextMessage(const swift::misc::network::CTextMessage &textMessage, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Info message, based on text message.
void showOverlayMessages(const swift::misc::CStatusMessageList &messages, bool appendOldMessages=false, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show multiple messages.
void showOverlayMessage(const swift::misc::CStatusMessage &message, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show single message.
void setForceSmall(bool force)
Force small (smaller layout)
void showOverlayMessagesOrHTMLMessage(const swift::misc::CStatusMessageList &messages, bool appendOldMessages=false, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show multiple messages or a single message (HTML)
void showOverlayInlineTextMessage(components::TextMessageTab tab)
Inline text message.
void setReducedInfo(bool reduced)
Display reduced information.
void showOverlayMessagesWithConfirmation(const swift::misc::CStatusMessageList &messages, bool appendOldMessages, const QString &confirmationMessage, std::function< void()> okLambda, QMessageBox::StandardButton defaultButton=QMessageBox::Cancel, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Show multiple messages with confirmation bar.
void showHTMLMessage(const swift::misc::CStatusMessage &message, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
HTML message.
void showOverlayImage(const swift::misc::CPixmap &image, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Image.
Using this class provides a QTabWidget with the overlay functionality already integrated.
Using this class provides a QTableView with the overlay functionality already integrated.
Using this class provides a QTableView with the overlay functionality already integrated.
Using this class provides a QWizardPage with the overlay functionality already integrated.
Class for emitting a log message.
Definition: logmessage.h:27
bool isEmpty() const
Message empty.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
Pixmap which can be transferred via DBus.
Definition: pixmap.h:28
bool isEmpty() const
Synonym for empty.
Definition: sequence.h:285
Streamable status message, e.g.
Status messages, e.g. from Core -> GUI.
Wrapper around QVariant which provides transparent access to CValueObject methods of the contained ob...
Definition: variant.h:66
bool canConvert(int typeId) const
True if this variant can be converted to the type with the given metatype ID.
Value object encapsulating information of a callsign.
Definition: callsign.h:30
Value object encapsulating information of a text message.
Definition: textmessage.h:31
bool isEmpty() const
Empty message.
Definition: textmessage.h:90
GUI related classes.
int key() const const
int x() const const
int y() const const
int height() const const
int width() const const
qreal height() const const
void setHeight(qreal height)
qreal width() const const
Key_Escape
SortOrder
typedef WindowFlags
void setGeometry(const QRect &)
void hide()
virtual void setVisible(bool visible)
#define SWIFT_GUI_EXPORT
Export a class or function from the library.