Commit d00c44f4 authored by David Faure's avatar David Faure

Move dolphin's statusbar message-label (the one with support for errors and a...

Move dolphin's statusbar message-label (the one with support for errors and a close button) to libkonq
so that it can be used in konqueror as well. Fix its sizeHint. Reviewed by Peter Penz.

svn path=/trunk/KDE/kdebase/apps/; revision=1169901
parent f590a297
......@@ -88,15 +88,17 @@ KonqFrameStatusBar::KonqFrameStatusBar( KonqFrame *_parent )
{
setSizeGripEnabled( false );
// TODO remove active view indicator and use a different bg color like dolphin does?
// Works nicely for file management, but not so much with other parts...
m_led = new QLabel( this );
m_led->setAlignment( Qt::AlignCenter );
m_led->setSizePolicy(QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ));
addWidget( m_led, 0 ); // led (active view indicator)
m_led->hide();
m_pStatusLabel = new KSqueezedTextLabel( this );
m_pStatusLabel->setMinimumSize( 0, 0 );
m_pStatusLabel->setSizePolicy(QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Fixed ));
// TODO re-enable squeezing
//m_pStatusLabel = new KSqueezedTextLabel( this );
m_pStatusLabel = new KonqStatusBarMessageLabel( this );
m_pStatusLabel->installEventFilter(this);
addWidget( m_pStatusLabel, 1 /*stretch*/ ); // status label
......@@ -122,7 +124,6 @@ KonqFrameStatusBar::KonqFrameStatusBar( KonqFrame *_parent )
m_progressBar->hide();
addPermanentWidget( m_progressBar, 0 );
fontChange(QFont());
installEventFilter( this );
}
......@@ -130,17 +131,6 @@ KonqFrameStatusBar::~KonqFrameStatusBar()
{
}
void KonqFrameStatusBar::fontChange(const QFont & /* oldFont */)
{
int h = fontMetrics().height();
if ( h < DEFAULT_HEADER_HEIGHT ) h = DEFAULT_HEADER_HEIGHT;
m_led->setFixedHeight( h + 2 );
m_progressBar->setFixedHeight( h + 2 );
// This one is important. Otherwise richtext messages make it grow in height.
m_pStatusLabel->setFixedHeight( h + 2 );
}
// I don't think this code _ever_ gets called!
// I don't want to remove it, though. :-)
void KonqFrameStatusBar::mousePressEvent( QMouseEvent* event )
......@@ -217,7 +207,7 @@ void KonqFrameStatusBar::message( const QString &msg )
void KonqFrameStatusBar::slotDisplayStatusText(const QString& text)
{
//kDebug() << text;
m_pStatusLabel->setText(text);
m_pStatusLabel->setMessage(text, KonqStatusBarMessageLabel::Default);
m_savedMessage = text;
}
......@@ -297,4 +287,9 @@ void KonqFrameStatusBar::updateActiveStatus()
m_led->setPixmap( hasFocus ? indicator_viewactive : indicator_empty );
}
void KonqFrameStatusBar::setMessage(const QString& msg, KonqStatusBarMessageLabel::Type type)
{
m_pStatusLabel->setMessage(msg, type);
}
#include "konqframestatusbar.moc"
/* This file is part of the KDE project
Copyright (C) 1998, 1999 Michael Reiher <michael.reiher@gmx.de>
Copyright 2007 David Faure <faure@kde.org>
Copyright 2007, 2010 David Faure <faure@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -21,11 +21,11 @@
#define KONQ_FRAMESTATUSBAR_H
#include <KStatusBar>
#include "konq_statusbarmessagelabel.h"
class QLabel;
class QProgressBar;
class QCheckBox;
class KonqView;
class KSqueezedTextLabel;
class KonqFrame;
namespace KParts { class ReadOnlyPart; }
......@@ -42,6 +42,8 @@ public:
explicit KonqFrameStatusBar( KonqFrame *_parent = 0 );
virtual ~KonqFrameStatusBar();
void setMessage(const QString& msg, KonqStatusBarMessageLabel::Type type);
/**
* Checks/unchecks the linked-view checkbox
*/
......@@ -87,16 +89,11 @@ protected:
*/
virtual void splitFrameMenu();
/**
* Takes care of the statusbars size
**/
virtual void fontChange(const QFont &oldFont);
private:
KonqFrame* m_pParentKonqFrame;
QCheckBox *m_pLinkedViewCheckBox;
QProgressBar *m_progressBar;
KSqueezedTextLabel *m_pStatusLabel;
KonqStatusBarMessageLabel *m_pStatusLabel;
QLabel* m_led;
QString m_savedMessage;
};
......
......@@ -12,16 +12,17 @@ set(konq_LIB_SRCS
konq_popupmenu.cpp # used by konqueror, kfind, folderview, kickoff
konq_popupmenuplugin.cpp # for KonqPopupMenu and its plugins
konq_dndpopupmenuplugin.cpp # for KonqDndPopupMenu and its plugins
konq_copytomenu.cpp # used by dolphin, KonqPopupMenu
konq_operations.cpp # used by dolphin and konqueror
konq_copytomenu.cpp # used by dolphin, KonqPopupMenu
konq_operations.cpp # used by dolphin and konqueror
konq_statusbarmessagelabel.cpp # used by dolphin and konqueror
konq_events.cpp
konqmimedata.cpp # used by dolphin, KonqOperations, some filemanagement konqueror modules.
konq_historyentry.cpp
konq_historyloader.cpp
konq_historyprovider.cpp
kversioncontrolplugin.cpp # used by dolphin and its version control plugins
konq_nameandurlinputdialog.cpp # used by KNewMenu internally, and by the sidebar externally
konq_nameandurlinputdialog.cpp # deprecated (functionality has moved to kdelibs)
knewmenu.cpp # deprecated (functionality has moved to kdelibs)
konq_popupmenuinformation.cpp # deprecated (functionality has moved to kdelibs)
konq_menuactions.cpp # deprecated (functionality has moved to kdelibs)
......@@ -30,7 +31,7 @@ set(konq_LIB_SRCS
kde4_add_library(konq SHARED ${konq_LIB_SRCS})
target_link_libraries(konq ${KDE4_KPARTS_LIBS} ${KDE4_KFILE_LIBS} ${ZLIB_LIBRARY})
target_link_libraries(konq ${KDE4_KPARTS_LIBS} ${KDE4_KFILE_LIBS} ${ZLIB_LIBRARY} ${X11_X11_LIB})
target_link_libraries(konq LINK_INTERFACE_LIBRARIES ${KDE4_KPARTS_LIBS})
set_target_properties(konq PROPERTIES
......
/***************************************************************************
* Copyright (C) 2006 by Peter Penz *
* peter.penz@gmx.at *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* 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., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "konq_statusbarmessagelabel.h"
#include <kcolorscheme.h>
#include <kiconloader.h>
#include <kicon.h>
#include <klocale.h>
#include <QFontMetrics>
#include <QPainter>
#include <QKeyEvent>
#include <QPixmap>
#include <QToolButton>
#include <QTimer>
enum { GeometryTimeout = 100 };
enum { BorderGap = 2 };
class KonqStatusBarMessageLabel::Private
{
public:
Private() :
m_type(Default),
m_state(DefaultState),
m_illumination(0),
m_minTextHeight(-1),
m_timer(0),
m_closeButton(0)
{}
KonqStatusBarMessageLabel::Type m_type;
KonqStatusBarMessageLabel::State m_state;
int m_illumination;
int m_minTextHeight;
QTimer* m_timer;
QString m_text;
QString m_defaultText;
QList<QString> m_pendingMessages;
QPixmap m_pixmap;
QToolButton* m_closeButton;
};
KonqStatusBarMessageLabel::KonqStatusBarMessageLabel(QWidget* parent) :
QWidget(parent), d(new Private)
{
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum /*the sizeHint is the max*/);
d->m_timer = new QTimer(this);
connect(d->m_timer, SIGNAL(timeout()),
this, SLOT(timerDone()));
d->m_closeButton = new QToolButton(this);
d->m_closeButton->setAutoRaise(true);
d->m_closeButton->setIcon(KIcon("dialog-close"));
d->m_closeButton->setToolTip(i18nc("@info", "Close"));
d->m_closeButton->hide();
connect(d->m_closeButton, SIGNAL(clicked()),
this, SLOT(closeErrorMessage()));
}
KonqStatusBarMessageLabel::~KonqStatusBarMessageLabel()
{
delete d;
}
void KonqStatusBarMessageLabel::setMessage(const QString& text,
Type type)
{
if ((text == d->m_text) && (type == d->m_type)) {
return;
}
if (d->m_type == Error) {
if (type == Error) {
d->m_pendingMessages.insert(0, d->m_text);
} else if ((d->m_state != DefaultState) || !d->m_pendingMessages.isEmpty()) {
// a non-error message should not be shown, as there
// are other pending error messages in the queue
return;
}
}
d->m_text = text;
d->m_type = type;
d->m_timer->stop();
d->m_illumination = 0;
d->m_state = DefaultState;
const char* iconName = 0;
QPixmap pixmap;
switch (type) {
case OperationCompleted:
iconName = "dialog-ok";
// "ok" icon should probably be "dialog-success", but we don't have that icon in KDE 4.0
d->m_closeButton->hide();
break;
case Information:
iconName = "dialog-information";
d->m_closeButton->hide();
break;
case Error:
d->m_timer->start(100);
d->m_state = Illuminate;
updateCloseButtonPosition();
d->m_closeButton->show();
break;
case Default:
default:
d->m_closeButton->hide();
break;
}
d->m_pixmap = (iconName == 0) ? QPixmap() : SmallIcon(iconName);
QTimer::singleShot(GeometryTimeout, this, SLOT(assureVisibleText()));
update();
}
KonqStatusBarMessageLabel::Type KonqStatusBarMessageLabel::type() const
{
return d->m_type;
}
QString KonqStatusBarMessageLabel::text() const
{
return d->m_text;
}
void KonqStatusBarMessageLabel::setDefaultText(const QString& text)
{
d->m_defaultText = text;
}
QString KonqStatusBarMessageLabel::defaultText() const
{
return d->m_defaultText;
}
void KonqStatusBarMessageLabel::setMinimumTextHeight(int min)
{
if (min != d->m_minTextHeight) {
d->m_minTextHeight = min;
setMinimumHeight(min);
if (d->m_closeButton->height() > min) {
d->m_closeButton->setFixedHeight(min);
}
}
}
int KonqStatusBarMessageLabel::minimumTextHeight() const
{
return d->m_minTextHeight;
}
void KonqStatusBarMessageLabel::paintEvent(QPaintEvent* /* event */)
{
QPainter painter(this);
if (d->m_illumination > 0) {
// 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, d->m_illumination * 2));
painter.setBrush(backgroundColor);
painter.setPen(Qt::NoPen);
painter.drawRect(QRect(0, 0, width(), height()));
}
// draw pixmap
int x = BorderGap;
const int y = (d->m_minTextHeight - d->m_pixmap.height()) / 2;
if (!d->m_pixmap.isNull()) {
painter.drawPixmap(x, y, d->m_pixmap);
x += d->m_pixmap.width() + BorderGap;
}
// draw text
painter.setPen(palette().windowText().color());
int flags = Qt::AlignVCenter;
if (height() > d->m_minTextHeight) {
flags = flags | Qt::TextWordWrap;
}
painter.drawText(QRect(x, 0, availableTextWidth(), height()), flags, d->m_text);
painter.end();
}
void KonqStatusBarMessageLabel::resizeEvent(QResizeEvent* event)
{
QWidget::resizeEvent(event);
updateCloseButtonPosition();
QTimer::singleShot(GeometryTimeout, this, SLOT(assureVisibleText()));
}
void KonqStatusBarMessageLabel::timerDone()
{
switch (d->m_state) {
case Illuminate: {
// increase the illumination
const int illumination_max = 128;
if (d->m_illumination < illumination_max) {
d->m_illumination += 32;
if (d->m_illumination > illumination_max) {
d->m_illumination = illumination_max;
}
update();
} else {
d->m_state = Illuminated;
d->m_timer->start(5000);
}
break;
}
case Illuminated: {
// start desaturation
d->m_state = Desaturate;
d->m_timer->start(100);
break;
}
case Desaturate: {
// desaturate
if (d->m_illumination > 0) {
d->m_illumination -= 5;
update();
} else {
d->m_state = DefaultState;
d->m_timer->stop();
}
break;
}
default:
break;
}
}
void KonqStatusBarMessageLabel::assureVisibleText()
{
if (d->m_text.isEmpty()) {
return;
}
int requiredHeight = d->m_minTextHeight;
if (d->m_type != 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, d->m_text));
requiredHeight = bounds.height();
if (requiredHeight < d->m_minTextHeight) {
requiredHeight = d->m_minTextHeight;
}
}
// 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 KonqStatusBarMessageLabel::resizeEvent())
const int gap = d->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();
}
updateCloseButtonPosition();
}
int KonqStatusBarMessageLabel::availableTextWidth() const
{
const int buttonWidth = (d->m_type == Error) ?
d->m_closeButton->width() + BorderGap : 0;
return width() - d->m_pixmap.width() - (BorderGap * 4) - buttonWidth;
}
void KonqStatusBarMessageLabel::updateCloseButtonPosition()
{
const int x = width() - d->m_closeButton->width() - BorderGap;
d->m_closeButton->move(x, 0);
}
void KonqStatusBarMessageLabel::closeErrorMessage()
{
if (!showPendingMessage()) {
reset();
setMessage(d->m_defaultText, Default);
}
}
bool KonqStatusBarMessageLabel::showPendingMessage()
{
if (!d->m_pendingMessages.isEmpty()) {
reset();
setMessage(d->m_pendingMessages.takeFirst(), Error);
return true;
}
return false;
}
void KonqStatusBarMessageLabel::reset()
{
d->m_text.clear();
d->m_type = Default;
}
QSize KonqStatusBarMessageLabel::sizeHint() const
{
return minimumSizeHint();
}
QSize KonqStatusBarMessageLabel::minimumSizeHint() const
{
const int fontHeight = fontMetrics().height();
const QSize toolButtonSize = d->m_closeButton->sizeHint();
return toolButtonSize.expandedTo(QSize(100, fontHeight));
}
#include "konq_statusbarmessagelabel.moc"
/***************************************************************************
* Copyright (C) 2006 by Peter Penz *
* peter.penz@gmx.at *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* 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., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef KONQ_STATUSBARMESSAGELABEL_H
#define KONQ_STATUSBARMESSAGELABEL_H
#include "libkonq_export.h"
#include <QtGui/QWidget>
class QPaintEvent;
class QResizeEvent;
/**
* @brief Represents a message text label as part of the status bar.
*
* Dependent from the given type automatically a corresponding icon
* is shown in front of the text. For message texts having the type
* KonqStatusBarMessageLabel::Error a dynamic color blending is done to get the
* attention from the user.
*/
class LIBKONQ_EXPORT KonqStatusBarMessageLabel : public QWidget
{
Q_OBJECT
public:
explicit KonqStatusBarMessageLabel(QWidget* parent);
virtual ~KonqStatusBarMessageLabel();
/**
* Describes the type of the message text. Dependent
* from the type a corresponding icon and color is
* used for the message text.
*/
enum Type {
Default,
OperationCompleted,
Information,
Error
};
void setMessage(const QString& text, Type type);
Type type() const;
QString text() const;
void setDefaultText(const QString& text);
QString defaultText() const;
// TODO: maybe a better approach is possible with the size hint
void setMinimumTextHeight(int min);
int minimumTextHeight() const;
/** @see QWidget::sizeHint */
virtual QSize sizeHint() const;
/** @see QWidget::minimumSizeHint */
virtual QSize minimumSizeHint() const;
protected:
/** @see QWidget::paintEvent() */
virtual void paintEvent(QPaintEvent* event);
/** @see QWidget::resizeEvent() */
virtual void resizeEvent(QResizeEvent* event);
private slots:
void timerDone();
/**
* Increases the height of the message label so that
* the given text fits into given area.
*/
void assureVisibleText();
/**
* Returns the available width in pixels for the text.
*/
int availableTextWidth() const;
/**
* Moves the close button to the upper right corner
* of the message label.
*/
void updateCloseButtonPosition();
/**
* Closes the currently shown error message and replaces it
* by the next pending message.
*/
void closeErrorMessage();
private:
/**
* Shows the next pending error message. If no pending message
* was in the queue, false is returned.
*/
bool showPendingMessage();
/**