X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/9a5f54d83ddc84aa68348058acfcb385ef621577..b1c9b5126d:/src/statusbarmessagelabel.cpp diff --git a/src/statusbarmessagelabel.cpp b/src/statusbarmessagelabel.cpp index 0604b2633..bb7c59d6a 100644 --- a/src/statusbarmessagelabel.cpp +++ b/src/statusbarmessagelabel.cpp @@ -15,19 +15,22 @@ * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ #include "statusbarmessagelabel.h" -#include -#include -#include -//Added by qt3to4: -#include -#include -#include + +#include #include -#include +#include +#include + +#include +#include +#include +#include +#include +#include StatusBarMessageLabel::StatusBarMessageLabel(QWidget* parent) : QWidget(parent), @@ -35,67 +38,80 @@ StatusBarMessageLabel::StatusBarMessageLabel(QWidget* parent) : m_state(Default), m_illumination(0), m_minTextHeight(-1), - m_timer(0) + m_timer(0), + m_closeButton(0) { - setMinimumHeight(K3Icon::SizeSmall); + setMinimumHeight(KIconLoader::SizeSmall); m_timer = new QTimer(this); connect(m_timer, SIGNAL(timeout()), this, SLOT(timerDone())); + + m_closeButton = new QPushButton(i18nc("@action:button", "Close"), this); + m_closeButton->hide(); + connect(m_closeButton, SIGNAL(clicked()), + this, SLOT(closeErrorMessage())); } StatusBarMessageLabel::~StatusBarMessageLabel() { } -void StatusBarMessageLabel::setType(DolphinStatusBar::Type type) +void StatusBarMessageLabel::setMessage(const QString& text, + DolphinStatusBar::Type type) { - if (type != m_type) { - m_type = type; - - m_timer->stop(); - m_illumination = 0; - m_state = Default; - - const char* iconName = 0; - QPixmap pixmap; - switch (type) { - case DolphinStatusBar::OperationCompleted: - iconName = "ok"; - break; - - case DolphinStatusBar::Information: - iconName = "info"; - break; - - case DolphinStatusBar::Error: - iconName = "error"; - m_timer->start(100); - m_state = Illuminate; - break; - - case DolphinStatusBar::Default: - default: break; - } - - m_pixmap = (iconName == 0) ? QPixmap() : SmallIcon(iconName); - assureVisibleText(); - update(); + if ((text == m_text) && (type == m_type)) { + return; } -} -void StatusBarMessageLabel::setText(const QString& text) -{ - if (text != m_text) { - if (m_type == DolphinStatusBar::Error) { - m_timer->start(100); - m_illumination = 0; - m_state = Illuminate; + if (m_type == DolphinStatusBar::Error) { + if (type == DolphinStatusBar::Error) { + m_pendingMessages.insert(0, m_text); + } else if ((m_state != Default) || !m_pendingMessages.isEmpty()) { + // a non-error message should not be shown, as there + // are other pending error messages in the queue + return; } - m_text = text; - assureVisibleText(); - update(); } + + m_text = text; + m_type = type; + + m_timer->stop(); + m_illumination = 0; + m_state = Default; + + const char* iconName = 0; + QPixmap pixmap; + switch (type) { + case DolphinStatusBar::OperationCompleted: + iconName = "dialog-ok"; + // "ok" icon should probably be "dialog-success", but we don't have that icon in KDE 4.0 + m_closeButton->hide(); + break; + + case DolphinStatusBar::Information: + iconName = "dialog-information"; + m_closeButton->hide(); + break; + + case DolphinStatusBar::Error: + m_timer->start(100); + m_state = Illuminate; + + updateCloseButtonPosition(); + m_closeButton->show(); + break; + + case DolphinStatusBar::Default: + default: + m_closeButton->hide(); + break; + } + + m_pixmap = (iconName == 0) ? QPixmap() : SmallIcon(iconName); + QTimer::singleShot(GeometryTimeout, this, SLOT(assureVisibleText())); + update(); } void StatusBarMessageLabel::setMinimumTextHeight(int min) @@ -103,86 +119,101 @@ void StatusBarMessageLabel::setMinimumTextHeight(int min) if (min != m_minTextHeight) { m_minTextHeight = min; setMinimumHeight(min); + if (m_closeButton->height() > min) { + m_closeButton->setFixedHeight(min); + } } } +int StatusBarMessageLabel::widthGap() const +{ + QFontMetrics fontMetrics(font()); + const int defaultGap = 10; + return fontMetrics.width(m_text) - availableTextWidth() + defaultGap; +} + void StatusBarMessageLabel::paintEvent(QPaintEvent* /* event */) { - QPixmap buffer(size()); - QPainter painter(&buffer); + QPainter painter(this); - // draw background - QColor backgroundColor(colorGroup().background()); - QColor foregroundColor(KGlobalSettings::textColor()); if (m_illumination > 0) { - backgroundColor = mixColors(backgroundColor, QColor(255, 255, 64), m_illumination); - foregroundColor = mixColors(foregroundColor, QColor(0, 0, 0), m_illumination); + // at this point, a: we are a second label being drawn over the already + // painted status area, so we can be translucent, and b: our palette's + // window color (bg only) seems to be wrong (always black) + KColorScheme scheme(palette().currentColorGroup(), KColorScheme::Window); + QColor backgroundColor = scheme.background(KColorScheme::NegativeBackground).color(); + backgroundColor.setAlpha(qMin(255, m_illumination * 2)); + painter.setBrush(backgroundColor); + painter.setPen(Qt::NoPen); + painter.drawRect(QRect(0, 0, width(), height())); } - painter.setBrush(backgroundColor); - painter.setPen(backgroundColor); - painter.drawRect(QRect(0, 0, width(), height())); // draw pixmap - int x = pixmapGap(); - int y = (height() - m_pixmap.height()) / 2; + int x = BorderGap; + const int y = (m_minTextHeight - m_pixmap.height()) / 2; if (!m_pixmap.isNull()) { painter.drawPixmap(x, y, m_pixmap); - x += m_pixmap.width() + pixmapGap(); + x += m_pixmap.width() + BorderGap; } // draw text - painter.setPen(foregroundColor); - painter.drawText(QRect(x, 0, width() - x, height()), Qt::AlignVCenter | Qt::TextWordWrap, m_text); + painter.setPen(palette().windowText().color()); + int flags = Qt::AlignVCenter; + if (height() > m_minTextHeight) { + flags = flags | Qt::TextWordWrap; + } + painter.drawText(QRect(x, 0, availableTextWidth(), height()), flags, m_text); painter.end(); - - bitBlt(this, 0, 0, &buffer); } void StatusBarMessageLabel::resizeEvent(QResizeEvent* event) { QWidget::resizeEvent(event); - QTimer::singleShot(0, this, SLOT(assureVisibleText())); + updateCloseButtonPosition(); + QTimer::singleShot(GeometryTimeout, this, SLOT(assureVisibleText())); } void StatusBarMessageLabel::timerDone() { switch (m_state) { - case Illuminate: { - // increase the illumination - if (m_illumination < 100) { - m_illumination += 20; - update(); - } - else { - m_state = Illuminated; - m_timer->start(1000); + case Illuminate: { + // increase the illumination + const int illumination_max = 128; + if (m_illumination < illumination_max) { + m_illumination += 32; + if (m_illumination > illumination_max) { + m_illumination = illumination_max; } - break; + update(); + } else { + m_state = Illuminated; + m_timer->start(5000); } + break; + } - case Illuminated: { - // start desaturation - m_state = Desaturate; - m_timer->start(100); - break; - } + case Illuminated: { + // start desaturation + m_state = Desaturate; + m_timer->start(100); + break; + } - case Desaturate: { - // desaturate - if (m_illumination > 0) { - m_illumination -= 5; - update(); - } - else { - m_state = Default; - m_timer->stop(); - } - break; + case Desaturate: { + // desaturate + if (m_illumination > 0) { + m_illumination -= 5; + update(); + } else { + m_state = Default; + m_timer->stop(); } + break; + } - default: - break; + default: + break; } } @@ -192,30 +223,83 @@ void StatusBarMessageLabel::assureVisibleText() return; } + int requiredHeight = m_minTextHeight; + if (m_type != DolphinStatusBar::Default) { + // Calculate the required height of the widget thats + // needed for having a fully visible text. Note that for the default + // statusbar type (e. g. hover information) increasing the text height + // is not wanted, as this might rearrange the layout of items. + + QFontMetrics fontMetrics(font()); + const QRect bounds(fontMetrics.boundingRect(0, 0, availableTextWidth(), height(), + Qt::AlignVCenter | Qt::TextWordWrap, m_text)); + requiredHeight = bounds.height(); + if (requiredHeight < m_minTextHeight) { + requiredHeight = m_minTextHeight; + } + } - int availableWidth = width() - m_pixmap.width() - pixmapGap() * 2; + // Increase/decrease the current height of the widget to the + // required height. The increasing/decreasing is done in several + // steps to have an animation if the height is modified + // (see StatusBarMessageLabel::resizeEvent()) + const int gap = m_minTextHeight / 2; + int minHeight = minimumHeight(); + if (minHeight < requiredHeight) { + minHeight += gap; + if (minHeight > requiredHeight) { + minHeight = requiredHeight; + } + setMinimumHeight(minHeight); + updateGeometry(); + } else if (minHeight > requiredHeight) { + minHeight -= gap; + if (minHeight < requiredHeight) { + minHeight = requiredHeight; + } + setMinimumHeight(minHeight); + updateGeometry(); + } - QFontMetrics fontMetrics(font()); - QRect bounds(fontMetrics.boundingRect(0, 0, availableWidth, height(), - Qt::AlignVCenter | Qt::TextWordWrap, - m_text)); - int requiredHeight = bounds.height(); - if (requiredHeight < m_minTextHeight) { - requiredHeight = m_minTextHeight; - } - setMinimumHeight(requiredHeight); - updateGeometry(); + updateCloseButtonPosition(); +} + +int StatusBarMessageLabel::availableTextWidth() const +{ + const int buttonWidth = (m_type == DolphinStatusBar::Error) ? + m_closeButton->width() + BorderGap : 0; + return width() - m_pixmap.width() - (BorderGap * 4) - buttonWidth; +} + +void StatusBarMessageLabel::updateCloseButtonPosition() +{ + const int x = width() - m_closeButton->width() - BorderGap; + const int y = (height() - m_closeButton->height()) / 2; + m_closeButton->move(x, y); +} + +void StatusBarMessageLabel::closeErrorMessage() +{ + if (!showPendingMessage()) { + reset(); + setMessage(m_defaultText, DolphinStatusBar::Default); + } +} + +bool StatusBarMessageLabel::showPendingMessage() +{ + if (!m_pendingMessages.isEmpty()) { + reset(); + setMessage(m_pendingMessages.takeFirst(), DolphinStatusBar::Error); + return true; + } + return false; } -QColor StatusBarMessageLabel::mixColors(const QColor& c1, - const QColor& c2, - int percent) const +void StatusBarMessageLabel::reset() { - const int recip = 100 - percent; - const int red = (c1.red() * recip + c2.red() * percent) / 100; - const int green = (c1.green() * recip + c2.green() * percent) / 100; - const int blue = (c1.blue() * recip + c2.blue() * percent) / 100; - return QColor(red, green, blue); + m_text.clear(); + m_type = DolphinStatusBar::Default; } #include "statusbarmessagelabel.moc"