delay a few things on startup, such as setting the visibility mode, which ensures...
[personal-kdebase.git] / apps / dolphin / src / statusbarmessagelabel.cpp
blobbb7c59d6a8cadc91855655c0a2d62794ce891261
1 /***************************************************************************
2 * Copyright (C) 2006 by Peter Penz *
3 * peter.penz@gmx.at *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
19 ***************************************************************************/
21 #include "statusbarmessagelabel.h"
23 #include <kcolorscheme.h>
24 #include <kiconloader.h>
25 #include <kicon.h>
26 #include <klocale.h>
28 #include <QFontMetrics>
29 #include <QPainter>
30 #include <QKeyEvent>
31 #include <QPushButton>
32 #include <QPixmap>
33 #include <QTimer>
35 StatusBarMessageLabel::StatusBarMessageLabel(QWidget* parent) :
36 QWidget(parent),
37 m_type(DolphinStatusBar::Default),
38 m_state(Default),
39 m_illumination(0),
40 m_minTextHeight(-1),
41 m_timer(0),
42 m_closeButton(0)
44 setMinimumHeight(KIconLoader::SizeSmall);
46 m_timer = new QTimer(this);
47 connect(m_timer, SIGNAL(timeout()),
48 this, SLOT(timerDone()));
50 m_closeButton = new QPushButton(i18nc("@action:button", "Close"), this);
51 m_closeButton->hide();
52 connect(m_closeButton, SIGNAL(clicked()),
53 this, SLOT(closeErrorMessage()));
56 StatusBarMessageLabel::~StatusBarMessageLabel()
60 void StatusBarMessageLabel::setMessage(const QString& text,
61 DolphinStatusBar::Type type)
63 if ((text == m_text) && (type == m_type)) {
64 return;
67 if (m_type == DolphinStatusBar::Error) {
68 if (type == DolphinStatusBar::Error) {
69 m_pendingMessages.insert(0, m_text);
70 } else if ((m_state != Default) || !m_pendingMessages.isEmpty()) {
71 // a non-error message should not be shown, as there
72 // are other pending error messages in the queue
73 return;
77 m_text = text;
78 m_type = type;
80 m_timer->stop();
81 m_illumination = 0;
82 m_state = Default;
84 const char* iconName = 0;
85 QPixmap pixmap;
86 switch (type) {
87 case DolphinStatusBar::OperationCompleted:
88 iconName = "dialog-ok";
89 // "ok" icon should probably be "dialog-success", but we don't have that icon in KDE 4.0
90 m_closeButton->hide();
91 break;
93 case DolphinStatusBar::Information:
94 iconName = "dialog-information";
95 m_closeButton->hide();
96 break;
98 case DolphinStatusBar::Error:
99 m_timer->start(100);
100 m_state = Illuminate;
102 updateCloseButtonPosition();
103 m_closeButton->show();
104 break;
106 case DolphinStatusBar::Default:
107 default:
108 m_closeButton->hide();
109 break;
112 m_pixmap = (iconName == 0) ? QPixmap() : SmallIcon(iconName);
113 QTimer::singleShot(GeometryTimeout, this, SLOT(assureVisibleText()));
114 update();
117 void StatusBarMessageLabel::setMinimumTextHeight(int min)
119 if (min != m_minTextHeight) {
120 m_minTextHeight = min;
121 setMinimumHeight(min);
122 if (m_closeButton->height() > min) {
123 m_closeButton->setFixedHeight(min);
128 int StatusBarMessageLabel::widthGap() const
130 QFontMetrics fontMetrics(font());
131 const int defaultGap = 10;
132 return fontMetrics.width(m_text) - availableTextWidth() + defaultGap;
135 void StatusBarMessageLabel::paintEvent(QPaintEvent* /* event */)
137 QPainter painter(this);
139 if (m_illumination > 0) {
140 // at this point, a: we are a second label being drawn over the already
141 // painted status area, so we can be translucent, and b: our palette's
142 // window color (bg only) seems to be wrong (always black)
143 KColorScheme scheme(palette().currentColorGroup(), KColorScheme::Window);
144 QColor backgroundColor = scheme.background(KColorScheme::NegativeBackground).color();
145 backgroundColor.setAlpha(qMin(255, m_illumination * 2));
146 painter.setBrush(backgroundColor);
147 painter.setPen(Qt::NoPen);
148 painter.drawRect(QRect(0, 0, width(), height()));
151 // draw pixmap
152 int x = BorderGap;
153 const int y = (m_minTextHeight - m_pixmap.height()) / 2;
155 if (!m_pixmap.isNull()) {
156 painter.drawPixmap(x, y, m_pixmap);
157 x += m_pixmap.width() + BorderGap;
160 // draw text
161 painter.setPen(palette().windowText().color());
162 int flags = Qt::AlignVCenter;
163 if (height() > m_minTextHeight) {
164 flags = flags | Qt::TextWordWrap;
166 painter.drawText(QRect(x, 0, availableTextWidth(), height()), flags, m_text);
167 painter.end();
170 void StatusBarMessageLabel::resizeEvent(QResizeEvent* event)
172 QWidget::resizeEvent(event);
173 updateCloseButtonPosition();
174 QTimer::singleShot(GeometryTimeout, this, SLOT(assureVisibleText()));
177 void StatusBarMessageLabel::timerDone()
179 switch (m_state) {
180 case Illuminate: {
181 // increase the illumination
182 const int illumination_max = 128;
183 if (m_illumination < illumination_max) {
184 m_illumination += 32;
185 if (m_illumination > illumination_max) {
186 m_illumination = illumination_max;
188 update();
189 } else {
190 m_state = Illuminated;
191 m_timer->start(5000);
193 break;
196 case Illuminated: {
197 // start desaturation
198 m_state = Desaturate;
199 m_timer->start(100);
200 break;
203 case Desaturate: {
204 // desaturate
205 if (m_illumination > 0) {
206 m_illumination -= 5;
207 update();
208 } else {
209 m_state = Default;
210 m_timer->stop();
212 break;
215 default:
216 break;
220 void StatusBarMessageLabel::assureVisibleText()
222 if (m_text.isEmpty()) {
223 return;
226 int requiredHeight = m_minTextHeight;
227 if (m_type != DolphinStatusBar::Default) {
228 // Calculate the required height of the widget thats
229 // needed for having a fully visible text. Note that for the default
230 // statusbar type (e. g. hover information) increasing the text height
231 // is not wanted, as this might rearrange the layout of items.
233 QFontMetrics fontMetrics(font());
234 const QRect bounds(fontMetrics.boundingRect(0, 0, availableTextWidth(), height(),
235 Qt::AlignVCenter | Qt::TextWordWrap, m_text));
236 requiredHeight = bounds.height();
237 if (requiredHeight < m_minTextHeight) {
238 requiredHeight = m_minTextHeight;
242 // Increase/decrease the current height of the widget to the
243 // required height. The increasing/decreasing is done in several
244 // steps to have an animation if the height is modified
245 // (see StatusBarMessageLabel::resizeEvent())
246 const int gap = m_minTextHeight / 2;
247 int minHeight = minimumHeight();
248 if (minHeight < requiredHeight) {
249 minHeight += gap;
250 if (minHeight > requiredHeight) {
251 minHeight = requiredHeight;
253 setMinimumHeight(minHeight);
254 updateGeometry();
255 } else if (minHeight > requiredHeight) {
256 minHeight -= gap;
257 if (minHeight < requiredHeight) {
258 minHeight = requiredHeight;
260 setMinimumHeight(minHeight);
261 updateGeometry();
264 updateCloseButtonPosition();
267 int StatusBarMessageLabel::availableTextWidth() const
269 const int buttonWidth = (m_type == DolphinStatusBar::Error) ?
270 m_closeButton->width() + BorderGap : 0;
271 return width() - m_pixmap.width() - (BorderGap * 4) - buttonWidth;
274 void StatusBarMessageLabel::updateCloseButtonPosition()
276 const int x = width() - m_closeButton->width() - BorderGap;
277 const int y = (height() - m_closeButton->height()) / 2;
278 m_closeButton->move(x, y);
281 void StatusBarMessageLabel::closeErrorMessage()
283 if (!showPendingMessage()) {
284 reset();
285 setMessage(m_defaultText, DolphinStatusBar::Default);
289 bool StatusBarMessageLabel::showPendingMessage()
291 if (!m_pendingMessages.isEmpty()) {
292 reset();
293 setMessage(m_pendingMessages.takeFirst(), DolphinStatusBar::Error);
294 return true;
296 return false;
299 void StatusBarMessageLabel::reset()
301 m_text.clear();
302 m_type = DolphinStatusBar::Default;
305 #include "statusbarmessagelabel.moc"