summaryrefslogtreecommitdiffstats
path: root/qt-ui
diff options
context:
space:
mode:
authorGravatar Tomaz Canabrava <tomaz.canabrava@gmail.com>2015-06-03 22:08:57 -0300
committerGravatar Dirk Hohndel <dirk@hohndel.org>2015-06-03 21:26:31 -0700
commitef10490e037c435cac8b1089cb9130d260351ad2 (patch)
tree49602dc027bb4912b8eb73f53a6b8f5c7fed025f /qt-ui
parentbe0a708db0b05f2b8a42f81d49020ca2e656b714 (diff)
downloadsubsurface-ef10490e037c435cac8b1089cb9130d260351ad2.tar.gz
Update KMessageWidget to KF5
The KMessageWidget that we used was from an ancient version of KDE4, KF5 is out for quite a while, so it's good that we also update our software that uses parts of KDE. Signed-off-by: Tomaz Canabrava <tomaz.canabrava@gmail.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'qt-ui')
-rw-r--r--qt-ui/kmessagewidget.cpp569
-rw-r--r--qt-ui/kmessagewidget.h381
-rw-r--r--qt-ui/maintab.cpp14
3 files changed, 564 insertions, 400 deletions
diff --git a/qt-ui/kmessagewidget.cpp b/qt-ui/kmessagewidget.cpp
index bfa8c2745..04fb6c2b0 100644
--- a/qt-ui/kmessagewidget.cpp
+++ b/qt-ui/kmessagewidget.cpp
@@ -1,6 +1,7 @@
/* This file is part of the KDE libraries
*
* Copyright (c) 2011 Aurélien Gâteau <agateau@kde.org>
+ * Copyright (c) 2014 Dominik Haumann <dhaumann@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,406 +20,460 @@
*/
#include "kmessagewidget.h"
+#include <QAction>
+#include <QEvent>
#include <QGridLayout>
-#include <QDialogButtonBox>
+#include <QHBoxLayout>
#include <QLabel>
#include <QPainter>
#include <QShowEvent>
#include <QTimeLine>
#include <QToolButton>
#include <QStyle>
-#include <QAction>
+
+//---------------------------------------------------------------------
+// KMessageWidgetPrivate
+//---------------------------------------------------------------------
+class KMessageWidgetPrivate
+{
+public:
+ void init(KMessageWidget *);
+
+ KMessageWidget *q;
+ QFrame *content;
+ QLabel *iconLabel;
+ QLabel *textLabel;
+ QToolButton *closeButton;
+ QTimeLine *timeLine;
+ QIcon icon;
+
+ KMessageWidget::MessageType messageType;
+ bool wordWrap;
+ QList<QToolButton *> buttons;
+ QPixmap contentSnapShot;
+
+ void createLayout();
+ void updateSnapShot();
+ void updateLayout();
+ void slotTimeLineChanged(qreal);
+ void slotTimeLineFinished();
+
+ int bestContentHeight() const;
+};
void KMessageWidgetPrivate::init(KMessageWidget *q_ptr)
{
- q = q_ptr;
+ q = q_ptr;
+
+ q->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+
+ timeLine = new QTimeLine(500, q);
+ QObject::connect(timeLine, SIGNAL(valueChanged(qreal)), q, SLOT(slotTimeLineChanged(qreal)));
+ QObject::connect(timeLine, SIGNAL(finished()), q, SLOT(slotTimeLineFinished()));
- q->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ content = new QFrame(q);
+ content->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- timeLine = new QTimeLine(500, q);
- QObject::connect(timeLine, SIGNAL(valueChanged(qreal)), q, SLOT(slotTimeLineChanged(qreal)));
- QObject::connect(timeLine, SIGNAL(finished()), q, SLOT(slotTimeLineFinished()));
+ wordWrap = false;
- content = new QFrame(q);
- content->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ iconLabel = new QLabel(content);
+ iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ iconLabel->hide();
- wordWrap = false;
+ textLabel = new QLabel(content);
+ textLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ textLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ QObject::connect(textLabel, SIGNAL(linkActivated(QString)), q, SIGNAL(linkActivated(QString)));
+ QObject::connect(textLabel, SIGNAL(linkHovered(QString)), q, SIGNAL(linkHovered(QString)));
- iconLabel = new QLabel(content);
- iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
- iconLabel->hide();
+ QAction *closeAction = new QAction(q);
+ closeAction->setText(KMessageWidget::tr("&Close"));
+ closeAction->setToolTip(KMessageWidget::tr("Close message"));
+ closeAction->setIcon(q->style()->standardIcon(QStyle::SP_DialogCloseButton));
- textLabel = new QLabel(content);
- textLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- textLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
- QObject::connect(textLabel, SIGNAL(linkActivated(const QString &)), q, SIGNAL(linkActivated(const QString &)));
- QObject::connect(textLabel, SIGNAL(linkHovered(const QString &)), q, SIGNAL(linkHovered(const QString &)));
+ QObject::connect(closeAction, SIGNAL(triggered(bool)), q, SLOT(animatedHide()));
- QAction *closeAction = new QAction(QObject::tr("Close"), q);
- q->connect(closeAction, SIGNAL(triggered(bool)), q, SLOT(animatedHide()));
+ closeButton = new QToolButton(content);
+ closeButton->setAutoRaise(true);
+ closeButton->setDefaultAction(closeAction);
- closeButton = new QToolButton(content);
- closeButton->setAutoRaise(true);
- closeButton->setDefaultAction(closeAction);
- closeButton->setVisible(false);
- q->setMessageType(KMessageWidget::Information);
+ q->setMessageType(KMessageWidget::Information);
}
void KMessageWidgetPrivate::createLayout()
{
- delete content->layout();
-
- content->resize(q->size());
-
- qDeleteAll(buttons);
- buttons.clear();
-
- Q_FOREACH (QAction *action, q->actions()) {
- QToolButton *button = new QToolButton(content);
- button->setDefaultAction(action);
- button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
- buttons.append(button);
- }
-
- // AutoRaise reduces visual clutter, but we don't want to turn it on if
- // there are other buttons, otherwise the close button will look different
- // from the others.
- closeButton->setAutoRaise(buttons.isEmpty());
-
- if (wordWrap) {
- QGridLayout *layout = new QGridLayout(content);
- // Set alignment to make sure icon does not move down if text wraps
- layout->addWidget(iconLabel, 0, 0, 1, 1, Qt::AlignHCenter | Qt::AlignTop);
- layout->addWidget(textLabel, 0, 1);
-
- QDialogButtonBox *buttonLayout = new QDialogButtonBox();
- //buttonLayout->addStretch();
- Q_FOREACH (QToolButton *button, buttons) {
- // For some reason, calling show() is necessary if wordwrap is true,
- // otherwise the buttons do not show up. It is not needed if
- // wordwrap is false.
- button->show();
- buttonLayout->addButton(button, QDialogButtonBox::QDialogButtonBox::AcceptRole);
- }
- buttonLayout->addButton(closeButton, QDialogButtonBox::RejectRole);
- layout->addWidget(buttonLayout, 1, 0, 1, 2, Qt::AlignHCenter | Qt::AlignTop);
- } else {
- bool closeButtonVisible = closeButton->isVisible();
- QHBoxLayout *layout = new QHBoxLayout(content);
- layout->addWidget(iconLabel);
- layout->addWidget(textLabel);
-
- QDialogButtonBox *buttonLayout = new QDialogButtonBox();
- Q_FOREACH (QToolButton *button, buttons) {
- buttonLayout->addButton(button, QDialogButtonBox::QDialogButtonBox::AcceptRole);
- }
-
- buttonLayout->addButton(closeButton, QDialogButtonBox::RejectRole);
- // Something gets changed when added to the buttonLayout
- closeButton->setVisible(closeButtonVisible);
- layout->addWidget(buttonLayout);
- };
-
- if (q->isVisible()) {
- q->setFixedHeight(content->sizeHint().height());
- }
-
- q->updateGeometry();
+ delete content->layout();
+
+ content->resize(q->size());
+
+ qDeleteAll(buttons);
+ buttons.clear();
+
+ Q_FOREACH (QAction *action, q->actions()) {
+ QToolButton *button = new QToolButton(content);
+ button->setDefaultAction(action);
+ button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ buttons.append(button);
+ }
+
+ // AutoRaise reduces visual clutter, but we don't want to turn it on if
+ // there are other buttons, otherwise the close button will look different
+ // from the others.
+ closeButton->setAutoRaise(buttons.isEmpty());
+
+ if (wordWrap) {
+ QGridLayout *layout = new QGridLayout(content);
+ // Set alignment to make sure icon does not move down if text wraps
+ layout->addWidget(iconLabel, 0, 0, 1, 1, Qt::AlignHCenter | Qt::AlignTop);
+ layout->addWidget(textLabel, 0, 1);
+
+ QHBoxLayout *buttonLayout = new QHBoxLayout;
+ buttonLayout->addStretch();
+ Q_FOREACH (QToolButton *button, buttons) {
+ // For some reason, calling show() is necessary if wordwrap is true,
+ // otherwise the buttons do not show up. It is not needed if
+ // wordwrap is false.
+ button->show();
+ buttonLayout->addWidget(button);
+ }
+ buttonLayout->addWidget(closeButton);
+ layout->addItem(buttonLayout, 1, 0, 1, 2);
+ } else {
+ QHBoxLayout *layout = new QHBoxLayout(content);
+ layout->addWidget(iconLabel);
+ layout->addWidget(textLabel);
+
+ Q_FOREACH (QToolButton *button, buttons) {
+ layout->addWidget(button);
+ }
+
+ layout->addWidget(closeButton);
+ };
+
+ if (q->isVisible()) {
+ q->setFixedHeight(content->sizeHint().height());
+ }
+ q->updateGeometry();
}
void KMessageWidgetPrivate::updateLayout()
{
- if (content->layout()) {
- createLayout();
- }
+ if (content->layout()) {
+ createLayout();
+ }
}
void KMessageWidgetPrivate::updateSnapShot()
{
- // Attention: updateSnapShot calls QWidget::render(), which causes the whole
- // window layouts to be activated. Calling this method from resizeEvent()
- // can lead to infinite recursion, see:
- // https://bugs.kde.org/show_bug.cgi?id=311336
- contentSnapShot = QPixmap(content->size());
- contentSnapShot.fill(Qt::transparent);
- content->render(&contentSnapShot, QPoint(), QRegion(), QWidget::DrawChildren);
+ // Attention: updateSnapShot calls QWidget::render(), which causes the whole
+ // window layouts to be activated. Calling this method from resizeEvent()
+ // can lead to infinite recursion, see:
+ // https://bugs.kde.org/show_bug.cgi?id=311336
+ contentSnapShot = QPixmap(content->size() * q->devicePixelRatio());
+ contentSnapShot.setDevicePixelRatio(q->devicePixelRatio());
+ contentSnapShot.fill(Qt::transparent);
+ content->render(&contentSnapShot, QPoint(), QRegion(), QWidget::DrawChildren);
}
void KMessageWidgetPrivate::slotTimeLineChanged(qreal value)
{
- q->setFixedHeight(qMin(value * 2, qreal(1.0)) * content->height());
- q->update();
+ q->setFixedHeight(qMin(value * 2, qreal(1.0)) * content->height());
+ q->update();
}
void KMessageWidgetPrivate::slotTimeLineFinished()
{
- if (timeLine->direction() == QTimeLine::Forward) {
- // Show
- // We set the whole geometry here, because it may be wrong if a
- // KMessageWidget is shown right when the toplevel window is created.
- content->setGeometry(0, 0, q->width(), bestContentHeight());
- } else {
- // Hide
- q->hide();
- }
+ if (timeLine->direction() == QTimeLine::Forward) {
+ // Show
+ // We set the whole geometry here, because it may be wrong if a
+ // KMessageWidget is shown right when the toplevel window is created.
+ content->setGeometry(0, 0, q->width(), bestContentHeight());
+
+ // notify about finished animation
+ emit q->showAnimationFinished();
+ } else {
+ // hide and notify about finished animation
+ q->hide();
+ emit q->hideAnimationFinished();
+ }
}
int KMessageWidgetPrivate::bestContentHeight() const
{
- int height = content->heightForWidth(q->width());
-
- if (height == -1) {
- height = content->sizeHint().height();
- }
-
- return height;
+ int height = content->heightForWidth(q->width());
+ if (height == -1) {
+ height = content->sizeHint().height();
+ }
+ return height;
}
-
//---------------------------------------------------------------------
// KMessageWidget
//---------------------------------------------------------------------
-KMessageWidget::KMessageWidget(QWidget *parent) : QFrame(parent), d(new KMessageWidgetPrivate)
+KMessageWidget::KMessageWidget(QWidget *parent)
+ : QFrame(parent)
+ , d(new KMessageWidgetPrivate)
{
- d->init(this);
+ d->init(this);
}
-KMessageWidget::KMessageWidget(const QString &text, QWidget *parent) : QFrame(parent), d(new KMessageWidgetPrivate)
+KMessageWidget::KMessageWidget(const QString &text, QWidget *parent)
+ : QFrame(parent)
+ , d(new KMessageWidgetPrivate)
{
- d->init(this);
- setText(text);
+ d->init(this);
+ setText(text);
}
KMessageWidget::~KMessageWidget()
{
- delete d;
+ delete d;
}
QString KMessageWidget::text() const
{
- return d->textLabel->text();
+ return d->textLabel->text();
}
void KMessageWidget::setText(const QString &text)
{
- d->textLabel->setText(text);
- updateGeometry();
+ d->textLabel->setText(text);
+ updateGeometry();
}
-int KMessageWidget::bestContentHeight() const
+KMessageWidget::MessageType KMessageWidget::messageType() const
{
- return d->bestContentHeight();
+ return d->messageType;
}
-
-KMessageWidget::MessageType KMessageWidget::messageType() const
+static QColor darkShade(QColor c)
{
- return d->messageType;
+ qreal contrast = 0.7; // taken from kcolorscheme for the dark shade
+
+ qreal darkAmount;
+ if (c.lightnessF() < 0.006) { /* too dark */
+ darkAmount = 0.02 + 0.40 * contrast;
+ } else if (c.lightnessF() > 0.93) { /* too bright */
+ darkAmount = -0.06 - 0.60 * contrast;
+ } else {
+ darkAmount = (-c.lightnessF()) * (0.55 + contrast * 0.35);
+ }
+
+ qreal v = c.lightnessF() + darkAmount;
+ v = v > 0.0 ? (v < 1.0 ? v : 1.0) : 0.0;
+ c.setHsvF(c.hslHueF(), c.hslSaturationF(), v);
+ return c;
}
void KMessageWidget::setMessageType(KMessageWidget::MessageType type)
{
- d->messageType = type;
- QColor bg0, bg1, bg2, border, fg;
-
- switch (type) {
- case Positive:
- bg1 = QColor("#72D594"); // nice green
- fg = QColor(Qt::white);
- break;
-
- case Information:
- bg1 = QColor("#41A8E3"); // nice blue
- fg = QColor(Qt::black);
- break;
-
- case Warning:
- bg1 = QColor("#72D594"); // nice yellow
- fg = QColor(Qt::black);
- break;
-
- case Error:
- bg1 = QColor("#E4B7B7"); // nice red.
- fg = QColor(Qt::black);
- break;
- }
-
- // Colors
- bg0 = bg1.lighter(110);
- bg2 = bg1.darker(110);
- border = bg2.darker(110);
- d->content->setStyleSheet(
- QString(".QFrame {"
- "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
- " stop: 0 %1,"
- " stop: 0.1 %2,"
- " stop: 1.0 %3);"
- "border-radius: 5px;"
- "border: 1px solid %4;"
- "margin: %5px;"
- "}"
- ".QLabel { color: %6; }").arg(bg0.name())
- .arg(bg1.name())
- .arg(bg2.name())
- .arg(border.name())
- /*
- DefaultFrameWidth returns the size of the external margin + border width.
- We know our border is 1px, so we subtract this from the frame
- normal QStyle FrameWidth to get our margin
- */
- .arg(style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this) - 1)
- .arg(fg.name()));
+ d->messageType = type;
+ QColor bg0, bg1, bg2, border, fg;
+ switch (type) {
+ case Positive:
+ bg1.setRgb(0, 110, 40); // values taken from kcolorscheme.cpp (Positive)
+ break;
+ case Information:
+ bg1 = palette().highlight().color();
+ break;
+ case Warning:
+ bg1.setRgb(176, 128, 0); // values taken from kcolorscheme.cpp (Neutral)
+ break;
+ case Error:
+ bg1.setRgb(191, 3, 3); // values taken from kcolorscheme.cpp (Negative)
+ break;
+ }
+
+ // Colors
+ fg = palette().highlightedText().color();
+ bg0 = bg1.lighter(110);
+ bg2 = bg1.darker(110);
+ border = darkShade(bg1);
+
+ d->content->setStyleSheet(
+ QString(QLatin1String(".QFrame {"
+ "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
+ " stop: 0 %1,"
+ " stop: 0.1 %2,"
+ " stop: 1.0 %3);"
+ "border-radius: 5px;"
+ "border: 1px solid %4;"
+ "margin: %5px;"
+ "}"
+ ".QLabel { color: %6; }"
+ ))
+ .arg(bg0.name())
+ .arg(bg1.name())
+ .arg(bg2.name())
+ .arg(border.name())
+ // DefaultFrameWidth returns the size of the external margin + border width. We know our border is 1px, so we subtract this from the frame normal QStyle FrameWidth to get our margin
+ .arg(style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this) - 1)
+ .arg(fg.name())
+ );
}
QSize KMessageWidget::sizeHint() const
{
- ensurePolished();
- return d->content->sizeHint();
+ ensurePolished();
+ return d->content->sizeHint();
}
QSize KMessageWidget::minimumSizeHint() const
{
- ensurePolished();
- return d->content->minimumSizeHint();
+ ensurePolished();
+ return d->content->minimumSizeHint();
}
bool KMessageWidget::event(QEvent *event)
{
- if (event->type() == QEvent::Polish && !d->content->layout()) {
- d->createLayout();
- }
-
- return QFrame::event(event);
+ if (event->type() == QEvent::Polish && !d->content->layout()) {
+ d->createLayout();
+ }
+ return QFrame::event(event);
}
void KMessageWidget::resizeEvent(QResizeEvent *event)
{
- QFrame::resizeEvent(event);
+ QFrame::resizeEvent(event);
- if (d->timeLine->state() == QTimeLine::NotRunning) {
- d->content->resize(width(), d->bestContentHeight());
- }
+ if (d->timeLine->state() == QTimeLine::NotRunning) {
+ d->content->resize(width(), d->bestContentHeight());
+ }
}
int KMessageWidget::heightForWidth(int width) const
{
- ensurePolished();
- return d->content->heightForWidth(width);
+ ensurePolished();
+ return d->content->heightForWidth(width);
}
void KMessageWidget::paintEvent(QPaintEvent *event)
{
- QFrame::paintEvent(event);
-
- if (d->timeLine->state() == QTimeLine::Running) {
- QPainter painter(this);
- painter.setOpacity(d->timeLine->currentValue() * d->timeLine->currentValue());
- painter.drawPixmap(0, 0, d->contentSnapShot);
- }
-}
-
-void KMessageWidget::showEvent(QShowEvent *event)
-{
- // Keep this method here to avoid breaking binary compatibility:
- // QFrame::showEvent() used to be reimplemented.
- QFrame::showEvent(event);
+ QFrame::paintEvent(event);
+ if (d->timeLine->state() == QTimeLine::Running) {
+ QPainter painter(this);
+ painter.setOpacity(d->timeLine->currentValue() * d->timeLine->currentValue());
+ painter.drawPixmap(0, 0, d->contentSnapShot);
+ }
}
bool KMessageWidget::wordWrap() const
{
- return d->wordWrap;
+ return d->wordWrap;
}
void KMessageWidget::setWordWrap(bool wordWrap)
{
- d->wordWrap = wordWrap;
- d->textLabel->setWordWrap(wordWrap);
- QSizePolicy policy = sizePolicy();
- policy.setHeightForWidth(wordWrap);
- setSizePolicy(policy);
- d->updateLayout();
-
- // Without this, when user does wordWrap -> !wordWrap -> wordWrap, a minimum
- // height is set, causing the widget to be too high.
- // Mostly visible in test programs.
- if (wordWrap) {
- setMinimumHeight(0);
- }
+ d->wordWrap = wordWrap;
+ d->textLabel->setWordWrap(wordWrap);
+ QSizePolicy policy = sizePolicy();
+ policy.setHeightForWidth(wordWrap);
+ setSizePolicy(policy);
+ d->updateLayout();
+ // Without this, when user does wordWrap -> !wordWrap -> wordWrap, a minimum
+ // height is set, causing the widget to be too high.
+ // Mostly visible in test programs.
+ if (wordWrap) {
+ setMinimumHeight(0);
+ }
}
bool KMessageWidget::isCloseButtonVisible() const
{
- return d->closeButton->isVisible();
+ return d->closeButton->isVisible();
}
void KMessageWidget::setCloseButtonVisible(bool show)
{
- d->closeButton->setVisible(show);
- updateGeometry();
+ d->closeButton->setVisible(show);
+ updateGeometry();
}
void KMessageWidget::addAction(QAction *action)
{
- QFrame::addAction(action);
- d->updateLayout();
+ QFrame::addAction(action);
+ d->updateLayout();
}
void KMessageWidget::removeAction(QAction *action)
{
- QFrame::removeAction(action);
- d->updateLayout();
+ QFrame::removeAction(action);
+ d->updateLayout();
}
void KMessageWidget::animatedShow()
{
- if (isVisible()) {
- return;
- }
+ if (!style()->styleHint(QStyle::SH_Widget_Animate, 0, this)) {
+ show();
+ emit showAnimationFinished();
+ return;
+ }
- QFrame::show();
- setFixedHeight(0);
- int wantedHeight = d->bestContentHeight();
- d->content->setGeometry(0, -wantedHeight, width(), wantedHeight);
+ if (isVisible()) {
+ return;
+ }
- d->updateSnapShot();
+ QFrame::show();
+ setFixedHeight(0);
+ int wantedHeight = d->bestContentHeight();
+ d->content->setGeometry(0, -wantedHeight, width(), wantedHeight);
- d->timeLine->setDirection(QTimeLine::Forward);
+ d->updateSnapShot();
- if (d->timeLine->state() == QTimeLine::NotRunning) {
- d->timeLine->start();
- }
+ d->timeLine->setDirection(QTimeLine::Forward);
+ if (d->timeLine->state() == QTimeLine::NotRunning) {
+ d->timeLine->start();
+ }
}
void KMessageWidget::animatedHide()
{
- if (!isVisible()) {
- hide();
- return;
- }
+ if (!style()->styleHint(QStyle::SH_Widget_Animate, 0, this)) {
+ hide();
+ emit hideAnimationFinished();
+ return;
+ }
- d->content->move(0, -d->content->height());
- d->updateSnapShot();
+ if (!isVisible()) {
+ return;
+ }
- d->timeLine->setDirection(QTimeLine::Backward);
+ d->content->move(0, -d->content->height());
+ d->updateSnapShot();
- if (d->timeLine->state() == QTimeLine::NotRunning) {
- d->timeLine->start();
- }
+ d->timeLine->setDirection(QTimeLine::Backward);
+ if (d->timeLine->state() == QTimeLine::NotRunning) {
+ d->timeLine->start();
+ }
+}
+
+bool KMessageWidget::isHideAnimationRunning() const
+{
+ return (d->timeLine->direction() == QTimeLine::Backward)
+ && (d->timeLine->state() == QTimeLine::Running);
+}
+
+bool KMessageWidget::isShowAnimationRunning() const
+{
+ return (d->timeLine->direction() == QTimeLine::Forward)
+ && (d->timeLine->state() == QTimeLine::Running);
}
QIcon KMessageWidget::icon() const
{
- return d->icon;
+ return d->icon;
}
void KMessageWidget::setIcon(const QIcon &icon)
{
- d->icon = icon;
-
- if (d->icon.isNull()) {
- d->iconLabel->hide();
- } else {
- d->iconLabel->setPixmap(d->icon.pixmap(QSize(16, 16)));
- d->iconLabel->show();
- }
+ d->icon = icon;
+ if (d->icon.isNull()) {
+ d->iconLabel->hide();
+ } else {
+ const int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize);
+ d->iconLabel->setPixmap(d->icon.pixmap(size));
+ d->iconLabel->show();
+ }
}
+
+#include "moc_kmessagewidget.cpp"
diff --git a/qt-ui/kmessagewidget.h b/qt-ui/kmessagewidget.h
index dbc694afa..885d2a78f 100644
--- a/qt-ui/kmessagewidget.h
+++ b/qt-ui/kmessagewidget.h
@@ -1,6 +1,7 @@
/* This file is part of the KDE libraries
*
* Copyright (c) 2011 Aurélien Gâteau <agateau@kde.org>
+ * Copyright (c) 2014 Dominik Haumann <dhaumann@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -31,9 +32,14 @@ class KMessageWidgetPrivate;
* feedback, or to implement opportunistic interactions.
*
* As a feedback widget, KMessageWidget provides a less intrusive alternative
- * to "OK Only" message boxes. If you do not need the modalness of KMessageBox,
+ * to "OK Only" message boxes. If you want to avoid a modal KMessageBox,
* consider using KMessageWidget instead.
*
+ * Examples of KMessageWidget look as follows, all of them having an icon set
+ * with setIcon(), and the first three show a close button:
+ *
+ * \image html kmessagewidget.png "KMessageWidget with different message types"
+ *
* <b>Negative feedback</b>
*
* The KMessageWidget can be used as a secondary indicator of failure: the
@@ -67,7 +73,7 @@ class KMessageWidgetPrivate;
* @li Confirm success of "critical" transactions
* @li Indicate completion of background tasks
*
- * Example of inadapted uses:
+ * Example of unadapted uses:
*
* @li Indicate successful saving of a file
* @li Indicate a file has been successfully removed
@@ -87,153 +93,250 @@ class KMessageWidgetPrivate;
* @author Aurélien Gâteau <agateau@kde.org>
* @since 4.7
*/
-class KMessageWidget : public QFrame {
- Q_OBJECT
- Q_ENUMS(MessageType)
-
- Q_PROPERTY(QString text READ text WRITE setText)
- Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
- Q_PROPERTY(bool closeButtonVisible READ isCloseButtonVisible WRITE setCloseButtonVisible)
- Q_PROPERTY(MessageType messageType READ messageType WRITE setMessageType)
- Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
+class KMessageWidget : public QFrame
+{
+ Q_OBJECT
+ Q_ENUMS(MessageType)
+
+ Q_PROPERTY(QString text READ text WRITE setText)
+ Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
+ Q_PROPERTY(bool closeButtonVisible READ isCloseButtonVisible WRITE setCloseButtonVisible)
+ Q_PROPERTY(MessageType messageType READ messageType WRITE setMessageType)
+ Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
public:
- enum MessageType {
- Positive,
- Information,
- Warning,
- Error
- };
-
- /**
- * Constructs a KMessageWidget with the specified parent.
- */
- explicit KMessageWidget(QWidget *parent = 0);
-
- explicit KMessageWidget(const QString &text, QWidget *parent = 0);
-
- ~KMessageWidget();
-
- QString text() const;
-
- bool wordWrap() const;
-
- bool isCloseButtonVisible() const;
-
- MessageType messageType() const;
-
- void addAction(QAction *action);
-
- void removeAction(QAction *action);
-
- QSize sizeHint() const;
-
- QSize minimumSizeHint() const;
- int heightForWidth(int width) const;
+ /**
+ * Available message types.
+ * The background colors are chosen depending on the message type.
+ */
+ enum MessageType {
+ Positive,
+ Information,
+ Warning,
+ Error
+ };
+
+ /**
+ * Constructs a KMessageWidget with the specified @p parent.
+ */
+ explicit KMessageWidget(QWidget *parent = 0);
+
+ /**
+ * Constructs a KMessageWidget with the specified @p parent and
+ * contents @p text.
+ */
+ explicit KMessageWidget(const QString &text, QWidget *parent = 0);
+
+ /**
+ * Destructor.
+ */
+ ~KMessageWidget();
+
+ /**
+ * Get the text of this message widget.
+ * @see setText()
+ */
+ QString text() const;
+
+ /**
+ * Check whether word wrap is enabled.
+ *
+ * If word wrap is enabled, the message widget wraps the displayed text
+ * as required to the available width of the widget. This is useful to
+ * avoid breaking widget layouts.
+ *
+ * @see setWordWrap()
+ */
+ bool wordWrap() const;
+
+ /**
+ * Check whether the close button is visible.
+ *
+ * @see setCloseButtonVisible()
+ */
+ bool isCloseButtonVisible() const;
+
+ /**
+ * Get the type of this message.
+ * By default, the type is set to KMessageWidget::Information.
+ *
+ * @see KMessageWidget::MessageType, setMessageType()
+ */
+ MessageType messageType() const;
+
+ /**
+ * Add @p action to the message widget.
+ * For each action a button is added to the message widget in the
+ * order the actions were added.
+ *
+ * @param action the action to add
+ * @see removeAction(), QWidget::actions()
+ */
+ void addAction(QAction *action);
+
+ /**
+ * Remove @p action from the message widget.
+ *
+ * @param action the action to remove
+ * @see KMessageWidget::MessageType, addAction(), setMessageType()
+ */
+ void removeAction(QAction *action);
+
+ /**
+ * Returns the preferred size of the message widget.
+ */
+ QSize sizeHint() const Q_DECL_OVERRIDE;
+
+ /**
+ * Returns the minimum size of the message widget.
+ */
+ QSize minimumSizeHint() const Q_DECL_OVERRIDE;
+
+ /**
+ * Returns the required height for @p width.
+ * @param width the width in pixels
+ */
+ int heightForWidth(int width) const Q_DECL_OVERRIDE;
+
+ /**
+ * The icon shown on the left of the text. By default, no icon is shown.
+ * @since 4.11
+ */
+ QIcon icon() const;
+
+ /**
+ * Check whether the hide animation started by calling animatedHide()
+ * is still running. If animations are disabled, this function always
+ * returns @e false.
+ *
+ * @see animatedHide(), hideAnimationFinished()
+ * @since 5.0
+ */
+ bool isHideAnimationRunning() const;
+
+ /**
+ * Check whether the show animation started by calling animatedShow()
+ * is still running. If animations are disabled, this function always
+ * returns @e false.
+ *
+ * @see animatedShow(), showAnimationFinished()
+ * @since 5.0
+ */
+ bool isShowAnimationRunning() const;
+
+public Q_SLOTS:
+ /**
+ * Set the text of the message widget to @p text.
+ * If the message widget is already visible, the text changes on the fly.
+ *
+ * @param text the text to display, rich text is allowed
+ * @see text()
+ */
+ void setText(const QString &text);
+
+ /**
+ * Set word wrap to @p wordWrap. If word wrap is enabled, the text()
+ * of the message widget is wrapped to fit the available width.
+ * If word wrap is disabled, the message widget's minimum size is
+ * such that the entire text fits.
+ *
+ * @param wordWrap disable/enable word wrap
+ * @see wordWrap()
+ */
+ void setWordWrap(bool wordWrap);
+
+ /**
+ * Set the visibility of the close button. If @p visible is @e true,
+ * a close button is shown that calls animatedHide() if clicked.
+ *
+ * @see closeButtonVisible(), animatedHide()
+ */
+ void setCloseButtonVisible(bool visible);
+
+ /**
+ * Set the message type to @p type.
+ * By default, the message type is set to KMessageWidget::Information.
+ *
+ * @see messageType(), KMessageWidget::MessageType
+ */
+ void setMessageType(KMessageWidget::MessageType type);
+
+ /**
+ * Show the widget using an animation.
+ */
+ void animatedShow();
+
+ /**
+ * Hide the widget using an animation.
+ */
+ void animatedHide();
+
+ /**
+ * Define an icon to be shown on the left of the text
+ * @since 4.11
+ */
+ void setIcon(const QIcon &icon);
- /**
- * The icon shown on the left of the text. By default, no icon is shown.
- * @since 4.11
- */
- QIcon icon() const;
-
-public
-Q_SLOTS:
- void setText(const QString &text);
-
- void setWordWrap(bool wordWrap);
-
- void setCloseButtonVisible(bool visible);
-
- void setMessageType(KMessageWidget::MessageType type);
-
- /**
- * Show the widget using an animation, unless
- * KGlobalSettings::graphicsEffectLevel() does not allow simple effects.
- */
- void animatedShow();
-
- /**
- * Hide the widget using an animation, unless
- * KGlobalSettings::graphicsEffectLevel() does not allow simple effects.
- */
- void animatedHide();
-
- /**
- * Define an icon to be shown on the left of the text
- * @since 4.11
- */
- void setIcon(const QIcon &icon);
-
- int bestContentHeight() const;
Q_SIGNALS:
- /**
- * This signal is emitted when the user clicks a link in the text label.
- * The URL referred to by the href anchor is passed in contents.
- * @param contents text of the href anchor
- * @see QLabel::linkActivated()
- * @since 4.10
- */
- void linkActivated(const QString &contents);
-
- /**
- * This signal is emitted when the user hovers over a link in the text label.
- * The URL referred to by the href anchor is passed in contents.
- * @param contents text of the href anchor
- * @see QLabel::linkHovered()
- * @since 4.11
- */
- void linkHovered(const QString &contents);
+ /**
+ * This signal is emitted when the user clicks a link in the text label.
+ * The URL referred to by the href anchor is passed in contents.
+ * @param contents text of the href anchor
+ * @see QLabel::linkActivated()
+ * @since 4.10
+ */
+ void linkActivated(const QString &contents);
+
+ /**
+ * This signal is emitted when the user hovers over a link in the text label.
+ * The URL referred to by the href anchor is passed in contents.
+ * @param contents text of the href anchor
+ * @see QLabel::linkHovered()
+ * @since 4.11
+ */
+ void linkHovered(const QString &contents);
+
+ /**
+ * This signal is emitted when the hide animation is finished, started by
+ * calling animatedHide(). If animations are disabled, this signal is
+ * emitted immediately after the message widget got hidden.
+ *
+ * @note This signal is @e not emitted if the widget was hidden by
+ * calling hide(), so this signal is only useful in conjunction
+ * with animatedHide().
+ *
+ * @see animatedHide()
+ * @since 5.0
+ */
+ void hideAnimationFinished();
+
+ /**
+ * This signal is emitted when the show animation is finished, started by
+ * calling animatedShow(). If animations are disabled, this signal is
+ * emitted immediately after the message widget got shown.
+ *
+ * @note This signal is @e not emitted if the widget was shown by
+ * calling show(), so this signal is only useful in conjunction
+ * with animatedShow().
+ *
+ * @see animatedShow()
+ * @since 5.0
+ */
+ void showAnimationFinished();
protected:
- void paintEvent(QPaintEvent *event);
-
- bool event(QEvent *event);
+ void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
- void resizeEvent(QResizeEvent *event);
+ bool event(QEvent *event) Q_DECL_OVERRIDE;
- void showEvent(QShowEvent *event);
+ void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
private:
- KMessageWidgetPrivate *const d;
- friend class KMessageWidgetPrivate;
-
- Q_PRIVATE_SLOT(d, void slotTimeLineChanged(qreal))
- Q_PRIVATE_SLOT(d, void slotTimeLineFinished())
-};
-
-//---------------------------------------------------------------------
-// KMessageWidgetPrivate
-//---------------------------------------------------------------------
-class QLabel;
-class QToolButton;
-class QTimeLine;
-#include <QIcon>
+ KMessageWidgetPrivate *const d;
+ friend class KMessageWidgetPrivate;
-class KMessageWidgetPrivate {
-public:
- void init(KMessageWidget *);
-
- KMessageWidget *q;
- QFrame *content;
- QLabel *iconLabel;
- QLabel *textLabel;
- QToolButton *closeButton;
- QTimeLine *timeLine;
- QIcon icon;
-
- KMessageWidget::MessageType messageType;
- bool wordWrap;
- QList<QToolButton *> buttons;
- QPixmap contentSnapShot;
-
- void createLayout();
- void updateSnapShot();
- void updateLayout();
- void slotTimeLineChanged(qreal);
- void slotTimeLineFinished();
-
- int bestContentHeight() const;
+ Q_PRIVATE_SLOT(d, void slotTimeLineChanged(qreal))
+ Q_PRIVATE_SLOT(d, void slotTimeLineFinished())
};
-#endif // KMESSAGEWIDGET_H
+#endif /* KMESSAGEWIDGET_H */
diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp
index 85d45b357..f4c0d3af3 100644
--- a/qt-ui/maintab.cpp
+++ b/qt-ui/maintab.cpp
@@ -116,7 +116,10 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent),
ui.divemaster->setCompleter(completers.divemaster);
ui.suit->setCompleter(completers.suit);
ui.tagWidget->setCompleter(completers.tags);
-
+ ui.diveNotesMessage->hide();
+ ui.diveEquipmentMessage->hide();
+ ui.diveInfoMessage->hide();
+ ui.diveStatisticsMessage->hide();
setMinimumHeight(0);
setMinimumWidth(0);
@@ -312,9 +315,12 @@ void MainTab::displayMessage(QString str)
ui.diveStatisticsMessage->setText(str);
ui.diveStatisticsMessage->animatedShow();
updateTextLabels();
- ui.tagWidget->fixPopupPosition(ui.diveNotesMessage->bestContentHeight());
- ui.buddy->fixPopupPosition(ui.diveNotesMessage->bestContentHeight());
- ui.divemaster->fixPopupPosition(ui.diveNotesMessage->bestContentHeight());
+
+// TODO: this doesn't exists anymore. Find out why it was removed from
+// the KMessageWidget and try to see if this is still needed.
+// ui.tagWidget->fixPopupPosition(ui.diveNotesMessage->bestContentHeight());
+// ui.buddy->fixPopupPosition(ui.diveNotesMessage->bestContentHeight());
+// ui.divemaster->fixPopupPosition(ui.diveNotesMessage->bestContentHeight());
}
void MainTab::updateTextLabels(bool showUnits)