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);
61  m_overlayMessages->hide();
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,
102  QMessageBox::StandardButton defaultButton = QMessageBox::Cancel,
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 
160  void sortOverlayMessages(const swift::misc::CPropertyIndex &property, Qt::SortOrder order)
161  {
162  m_overlayMessages->sortOverlayMessages(property, order);
163  }
164 
166  void setOverlayMessagesSorting(const swift::misc::CPropertyIndex &property, Qt::SortOrder order)
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 
269  COverlayMessagesBase(QWidget *parent, Qt::WindowFlags f = Qt::WindowFlags()) : WIDGET(parent)
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);
295  m_overlayMessages->setVisible(true);
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);
349  if (m_overlayMessages && m_overlayMessages->isVisible()) { this->initInnerFrame(); }
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:
410  explicit COverlayMessagesFrameEnableForDockWidgetInfoArea(QWidget *parent = nullptr,
411  Qt::WindowFlags f = Qt::WindowFlags());
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:765
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.
#define SWIFT_GUI_EXPORT
Export a class or function from the library.