From b285281929c5220c76250d48cb0570dd03d2bc4d Mon Sep 17 00:00:00 2001
From: Tomaz Canabrava <tomaz.canabrava@gmail.com>
Date: Wed, 3 Jun 2015 22:08:57 -0300
Subject: [PATCH 01/25] 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>
---
 qt-ui/kmessagewidget.cpp | 570 ++++++++++++++++++++++++++---------------------
 qt-ui/kmessagewidget.h   | 381 +++++++++++++++++++------------
 qt-ui/maintab.cpp        |  14 +-
 3 files changed, 565 insertions(+), 400 deletions(-)

diff --git a/qt-ui/kmessagewidget.cpp b/qt-ui/kmessagewidget.cpp
index bfa8c27..f00bd56 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,461 @@
  */
 #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 dbc694a..885d2a7 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 85d45b3..f4c0d3a 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)
-- 
2.3.2 (Apple Git-55)

