HTML overlay status message, smaller form of overlay message

* improved toHTML (with icon)
* overlay message
This commit is contained in:
Klaus Basan
2018-11-16 00:52:23 +01:00
parent d9788115c7
commit 753511cafb
9 changed files with 137 additions and 28 deletions

View File

@@ -117,7 +117,7 @@ namespace BlackGui
void CLogComponent::appendStatusMessageToConsole(const CStatusMessage &statusMessage)
{
if (statusMessage.isEmpty()) return;
ui->tep_StatusPageConsole->appendHtml(statusMessage.toHtml());
ui->tep_StatusPageConsole->appendHtml(statusMessage.toHtml(false));
}
void CLogComponent::appendPlainTextToConsole(const QString &text)

View File

@@ -499,6 +499,7 @@ namespace BlackGui
QSizeF CGuiUtility::fontMetrics80Chars(bool withRatio)
{
// scale is 3.0 on my hires display
static const QString s("01234567890123456789012345678901234567890123456789012345678901234567890123456789");
const QFontMetricsF fm = CGuiUtility::currentFontMetricsF();
const qreal scale = withRatio ? CGuiUtility::mainApplicationWidgetPixelRatio() : 1.0;
@@ -522,11 +523,12 @@ namespace BlackGui
{
// 1920/1080: 560/16 256/16 => 530/960
// 3840/2160: 400/10 178/10 => 375/600
// with ratio we get the physical solution, otherwise logical solution
const QSizeF s1 = CGuiUtility::fontMetrics80Chars(withRatio);
const QSizeF s2 = CGuiUtility::fontMetricsLazyDog43Chars(withRatio);
const QSizeF s = s1 + s2;
const qreal w = s.width() * xCharacters / 123;
const qreal h = s.height() * yCharacters / 2;
const qreal w = s.width() * xCharacters / 123; // 123 chars
const qreal h = s.height() * yCharacters / 2; // 2 lines
return QSizeF(w, h);
}

View File

@@ -74,7 +74,7 @@ namespace BlackGui
{
// the underlying model object as summary
const CStatusMessage msg(this->at(index));
return msg.toHtml();
return msg.toHtml(false);
}
return CListModelTimestampObjects::data(index, role);
}

View File

@@ -54,7 +54,7 @@ namespace BlackGui
{
this->init(w, h);
this->showKillButton(false);
connect(sGui, &CGuiApplication::styleSheetsChanged, this, &COverlayMessages::onStyleSheetsChanged, Qt::QueuedConnection);
if (sGui) { connect(sGui, &CGuiApplication::styleSheetsChanged, this, &COverlayMessages::onStyleSheetsChanged, Qt::QueuedConnection); }
connect(ui->pb_Ok, &QPushButton::clicked, this, &COverlayMessages::onOkClicked);
connect(ui->pb_Cancel, &QPushButton::clicked, this, &COverlayMessages::onCancelClicked);
connect(ui->tb_Kill, &QPushButton::clicked, this, &COverlayMessages::onKillClicked);
@@ -126,7 +126,7 @@ namespace BlackGui
msgBox.setInformativeText("Do you want to terminate " + sGui->getApplicationNameAndVersion() + "?");
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Save);
if (QMessageBox::Ok == msgBox.exec())
if (QMessageBox::Ok == msgBox.exec() && sGui)
{
sGui->gracefulShutdown();
sGui->exit();
@@ -328,6 +328,28 @@ namespace BlackGui
}
}
void COverlayMessages::showHTMLMessage(const CStatusMessage &message, int timeOutMs)
{
if (message.isEmpty()) { return; }
if (!sGui || sGui->isShuttingDown()) { return; }
if (this->hasPendingConfirmation())
{
// defer message
QPointer<COverlayMessages> myself(this);
m_pendingMessageCalls.push_back([ = ]()
{
if (!myself) { return; }
myself->showHTMLMessage(message, timeOutMs);
});
return;
}
this->setModeToHTMLMessage();
ui->te_HTMLMessage->setText(message.toHtml(true));
this->display(timeOutMs);
}
void COverlayMessages::showKillButton(bool killButton)
{
m_hasKillButton = killButton;
@@ -355,6 +377,13 @@ namespace BlackGui
this->setHeader("Message");
}
void COverlayMessages::setModeToHTMLMessage(bool withKillButton)
{
ui->sw_StatusMessagesComponent->setCurrentWidget(ui->pg_HTMLMessage);
this->showKill(withKillButton);
this->setHeader("Message");
}
void COverlayMessages::setModeToTextMessage()
{
ui->sw_StatusMessagesComponent->setCurrentWidget(ui->pg_TextMessage);

View File

@@ -62,6 +62,9 @@ namespace BlackGui
//! Single Message mode
void setModeToMessageSmall(bool withKillButton = false);
//! HTML message mode
void setModeToHTMLMessage(bool withKillButton = false);
//! Single Text message mode
void setModeToTextMessage();
@@ -110,6 +113,9 @@ namespace BlackGui
//! Display one of the supported types
void showOverlayVariant(const BlackMisc::CVariant &variant, int timeOutMs = -1);
//! HTML message
void showHTMLMessage(const BlackMisc::CStatusMessage &message, int timeOutMs = -1);
//! Allows to globally enable/disable kill button
void showKillButton(bool killButton);

View File

@@ -113,7 +113,7 @@
<item>
<widget class="QStackedWidget" name="sw_StatusMessagesComponent">
<property name="currentIndex">
<number>5</number>
<number>6</number>
</property>
<widget class="QWidget" name="pg_StatusMessages">
<layout class="QVBoxLayout" name="vl_PgStatusMessages">
@@ -321,6 +321,25 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="pg_HTMLMessage">
<layout class="QVBoxLayout" name="vl_HTMLMessage">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTextEdit" name="te_HTMLMessage"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View File

@@ -163,6 +163,14 @@ namespace BlackGui
WIDGET::repaint();
}
//! \copydoc BlackGui::COverlayMessages::showHTMLMessage
void showOverlayHTMLMessage(const BlackMisc::CStatusMessage &message, int timeOutMs = -1)
{
this->initMinimalFrame();
m_overlayMessages->showHTMLMessage(message, timeOutMs);
WIDGET::repaint();
}
//! \copydoc BlackGui::COverlayMessages::showOverlayImage
void showOverlayInlineTextMessage(Components::TextMessageTab tab)
{
@@ -206,6 +214,25 @@ namespace BlackGui
m_overlayMessages->setGeometry(x, y, w, h);
}
//! Init a minimal frame (smaller as the normal one)
void initMinimalFrame()
{
this->initInnerFrame();
// get logical resolution
constexpr int MinHeight = 100;
QSizeF s = CGuiUtility::fontMetricsEstimateSize(100, 5); // 2 lines for header
if (s.height() < MinHeight) { s.setHeight(MinHeight); }
const QSize inner(innerFrameSize());
const QPoint middle = WIDGET::geometry().center();
const int w = qMin(inner.width(), qRound(s.width()));
const int h = qMin(inner.height(), qRound(s.height()));
const int x = middle.x() - w / 2;
const int y = qRound(middle.y() - h / m_middleFactor);
m_overlayMessages->setGeometry(x, y, w, h);
}
//! \copydoc QFrame::keyPressEvent
virtual void keyPressEvent(QKeyEvent *event) override
{

View File

@@ -137,8 +137,8 @@ namespace BlackMisc
switch (type)
{
default:
case QtDebugMsg: m_severity = SeverityDebug; break;
case QtInfoMsg: m_severity = SeverityInfo; break;
case QtDebugMsg: m_severity = SeverityDebug; break;
case QtInfoMsg: m_severity = SeverityInfo; break;
case QtWarningMsg: m_severity = SeverityWarning; break;
case QtCriticalMsg:
case QtFatalMsg:
@@ -155,10 +155,10 @@ namespace BlackMisc
switch (m_severity)
{
default:
case SeverityDebug: *o_type = QtDebugMsg; break;
case SeverityInfo: *o_type = QtInfoMsg; break;
case SeverityDebug: *o_type = QtDebugMsg; break;
case SeverityInfo: *o_type = QtInfoMsg; break;
case SeverityWarning: *o_type = QtWarningMsg; break;
case SeverityError: *o_type = QtCriticalMsg; break;
case SeverityError: *o_type = QtCriticalMsg; break;
}
}
@@ -182,8 +182,8 @@ namespace BlackMisc
QString CStatusMessage::getHumanReadablePattern() const
{
QStringList patternNames(getHumanReadablePatterns());
return patternNames.isEmpty() ? "" : patternNames.join(", ");
const QStringList patternNames(getHumanReadablePatterns());
return patternNames.isEmpty() ? QStringLiteral("") : patternNames.join(", ");
}
QStringList CStatusMessage::getHumanReadablePatterns() const
@@ -199,7 +199,7 @@ namespace BlackMisc
QString CStatusMessage::getHumanOrTechnicalCategoriesAsString() const
{
if (m_categories.isEmpty()) { return ""; }
QString c(getHumanReadablePattern());
const QString c(getHumanReadablePattern());
return c.isEmpty() ? this->getCategoriesAsString() : c;
}
@@ -280,14 +280,31 @@ namespace BlackMisc
{
switch (severity)
{
case SeverityDebug: return CIcon::iconByIndex(CIcons::StandardIconUnknown16); // TODO
case SeverityInfo: return CIcon::iconByIndex(CIcons::StandardIconInfo16);
case SeverityDebug: return CIcon::iconByIndex(CIcons::StandardIconUnknown16); // TODO
case SeverityInfo: return CIcon::iconByIndex(CIcons::StandardIconInfo16);
case SeverityWarning: return CIcon::iconByIndex(CIcons::StandardIconWarning16);
case SeverityError: return CIcon::iconByIndex(CIcons::StandardIconError16);
case SeverityError: return CIcon::iconByIndex(CIcons::StandardIconError16);
default: return CIcon::iconByIndex(CIcons::StandardIconInfo16);
}
}
const QString &CStatusMessage::convertToIconResource(CStatusMessage::StatusSeverity severity)
{
static const QString d;
static const QString i(":/pastel/icons/pastel/16/infomation.png");
static const QString w(":/pastel/icons/pastel/16/bullet-error.png");
static const QString e(":/pastel/icons/pastel/16/close-red.png");
switch (severity)
{
case SeverityDebug: return d;
case SeverityInfo: return i;
case SeverityWarning: return w;
case SeverityError: return e;
default: return d;
}
}
CStatusMessage CStatusMessage::fromDatabaseJson(const QJsonObject &json)
{
QString msgText(json.value("text").toString());
@@ -333,10 +350,10 @@ namespace BlackMisc
{
switch (severity)
{
case SeverityDebug: { static const QString d("debug"); return d; }
case SeverityInfo: { static const QString i("info"); return i; }
case SeverityDebug: { static const QString d("debug"); return d; }
case SeverityInfo: { static const QString i("info"); return i; }
case SeverityWarning: { static const QString w("warning"); return w; }
case SeverityError: { static const QString e("error"); return e; }
case SeverityError: { static const QString e("error"); return e; }
default:
{
static const QString x("unknown severity");
@@ -385,7 +402,7 @@ namespace BlackMisc
case IndexCategoriesAsString: return CVariant::from(m_categories.toQString());
case IndexCategoriesHumanReadableAsString: return CVariant::from(this->getHumanReadablePattern());
case IndexCategoryHumanReadableOrTechnicalAsString: return CVariant::from(this->getHumanOrTechnicalCategoriesAsString());
case IndexMessageAsHtml: return CVariant::from(this->toHtml());
case IndexMessageAsHtml: return CVariant::from(this->toHtml(false));
default: return CValueObject::propertyByIndex(index);
}
}
@@ -428,16 +445,22 @@ namespace BlackMisc
return 0;
}
QString CStatusMessage::toHtml() const
QString CStatusMessage::toHtml(bool withIcon) const
{
static const QString ef("</font>");
QString img;
if (withIcon)
{
const QString r = convertToIconResource(this->getSeverity());
if (!r.isEmpty()) { img = QStringLiteral("<img src=\"%1\"> ").arg(r); }
}
switch (this->getSeverity())
{
case SeverityWarning: return QStringLiteral("<font color=\"yellow\">") % this->getMessage() % ef;
case SeverityError: return QStringLiteral("<font color=\"red\">") % this->getMessage() % ef;
case SeverityWarning: return img % QStringLiteral("<font color=\"yellow\">") % this->getMessage() % QStringLiteral("</font>");
case SeverityError: return img % QStringLiteral("<font color=\"red\">") % this->getMessage() % QStringLiteral("</font>");
case SeverityDebug: break;
default: break;
}
return this->getMessage();
return img % this->getMessage();
}
} // ns

View File

@@ -347,7 +347,7 @@ namespace BlackMisc
QString convertToQString(bool i18n = false) const;
//! To HTML
QString toHtml() const;
QString toHtml(bool withIcon) const;
//! Representing icon
static const CIcon &convertToIcon(const CStatusMessage &statusMessage);
@@ -355,6 +355,9 @@ namespace BlackMisc
//! Representing icon
static const CIcon &convertToIcon(CStatusMessage::StatusSeverity severity);
//! Representing icon
static const QString &convertToIconResource(CStatusMessage::StatusSeverity severity);
//! Object from JSON
static CStatusMessage fromDatabaseJson(const QJsonObject &json);