1 /***************************************************************************
2 * Copyright (C) 2006 by Peter Penz *
3 * 2012 Simon A. Eugster <simon.eu@gmail.com> *
5 * Code borrowed from Dolphin, adapted (2008) to Kdenlive by *
6 * Jean-Baptiste Mardelle, jb@kdenlive.org *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
22 ***************************************************************************/
24 #include "statusbarmessagelabel.h"
25 #include "kdenlivesettings.h"
27 #include <kcolorscheme.h>
28 #include <kiconloader.h>
31 #include <KNotification>
33 #include <QFontMetrics>
36 #include <QPushButton>
40 StatusBarMessageLabel::StatusBarMessageLabel(QWidget* parent) :
48 setMinimumHeight(KIconLoader::SizeSmall);
50 palette.setColor(QPalette::Background, Qt::transparent);
53 m_closeButton = new QPushButton(i18nc("@action:button", "Confirm"), this);
54 m_closeButton->hide();
56 m_queueTimer.setSingleShot(true);
59 b &= connect(&m_queueTimer, SIGNAL(timeout()), this, SLOT(slotMessageTimeout()));
61 b &= connect(m_closeButton, SIGNAL(clicked()), this, SLOT(confirmErrorMessage()));
62 b &= connect(&m_timer, SIGNAL(timeout()), this, SLOT(timerDone()));
66 StatusBarMessageLabel::~StatusBarMessageLabel()
70 void StatusBarMessageLabel::setMessage(const QString& text,
71 MessageType type, int timeoutMS)
73 StatusBarMessageItem item(text, type, timeoutMS);
75 if (item.type == ErrorMessage || item.type == MltError) {
76 KNotification::event("ErrorMessage", item.text);
79 m_queueSemaphore.acquire();
80 if (!m_messageQueue.contains(item)) {
81 if (item.type == ErrorMessage || item.type == MltError) {
82 qDebug() << item.text;
84 // Put the new errror message at first place and immediately show it
85 if (item.timeoutMillis < 2000) {
86 item.timeoutMillis = 2000;
88 m_messageQueue.push_front(item);
90 // In case we are already displaying an error message, add a little delay
91 int delay = 800 * (m_currentMessage.type == ErrorMessage || m_currentMessage.type == MltError);
92 m_queueTimer.start(delay);
96 // Message with normal priority
97 m_messageQueue.push_back(item);
98 if (!m_queueTimer.elapsed() >= m_currentMessage.timeoutMillis) {
99 m_queueTimer.start(0);
105 m_queueSemaphore.release();
108 bool StatusBarMessageLabel::slotMessageTimeout()
110 m_queueSemaphore.acquire();
112 bool newMessage = false;
114 // Get the next message from the queue, unless the current one needs to be confirmed
115 if (m_messageQueue.size() > 0) {
117 if (!m_currentMessage.needsConfirmation()) {
119 m_currentMessage = m_messageQueue.at(0);
120 m_messageQueue.removeFirst();
126 // If the queue is empty, add a default (empty) message
127 if (m_messageQueue.size() == 0 && m_currentMessage.type != DefaultMessage) {
128 m_messageQueue.push_back(StatusBarMessageItem());
131 // Start a new timer, unless the current message still needs to be confirmed
132 if (m_messageQueue.size() > 0) {
134 if (!m_currentMessage.needsConfirmation()) {
136 // If we only have the default message left to show in the queue,
137 // keep the current one for a little longer.
138 m_queueTimer.start(m_currentMessage.timeoutMillis + 2000*(m_messageQueue.at(0).type == DefaultMessage));
144 m_illumination = -64;
148 const char* iconName = 0;
149 switch (m_currentMessage.type) {
150 case OperationCompletedMessage:
151 iconName = "dialog-ok";
152 m_closeButton->hide();
155 case InformationMessage:
156 iconName = "dialog-information";
157 m_closeButton->hide();
161 iconName = "dialog-warning";
163 m_state = Illuminate;
164 m_closeButton->hide();
168 iconName = "dialog-close";
170 m_state = Illuminate;
171 updateCloseButtonPosition();
172 m_closeButton->show();
177 m_closeButton->hide();
181 m_pixmap = (iconName == 0) ? QPixmap() : SmallIcon(iconName);
183 m_queueSemaphore.release();
189 void StatusBarMessageLabel::confirmErrorMessage()
191 m_currentMessage.confirmed = true;
192 m_queueTimer.start(0);
195 void StatusBarMessageLabel::setMinimumTextHeight(int min)
197 if (min != m_minTextHeight) {
198 m_minTextHeight = min;
199 setMinimumHeight(min);
200 if (m_closeButton->height() > min) {
201 m_closeButton->setFixedHeight(min);
206 void StatusBarMessageLabel::paintEvent(QPaintEvent*)
208 QPainter painter(this);
211 QColor backgroundColor;
212 if (m_state == Default || m_illumination < 0) backgroundColor = palette().window().color();
214 backgroundColor = KStatefulBrush(KColorScheme::Window, KColorScheme::NegativeBackground, KSharedConfig::openConfig(KdenliveSettings::colortheme())).brush(this).color();
216 if (m_state == Desaturate && m_illumination > 0) {
217 backgroundColor.setAlpha(m_illumination * 2);
219 painter.fillRect(0, 0, width(), height(), backgroundColor);
223 int y = (height() - m_pixmap.height()) / 2;
225 if (!m_pixmap.isNull()) {
226 painter.drawPixmap(x, y, m_pixmap);
227 x += m_pixmap.width() + BorderGap * 2;
231 painter.setPen(palette().windowText().color());
232 int flags = Qt::AlignVCenter;
233 if (height() > m_minTextHeight) {
234 flags = flags | Qt::TextWordWrap;
236 painter.drawText(QRect(x, 0, availableTextWidth(), height()), flags, m_currentMessage.text);
240 void StatusBarMessageLabel::resizeEvent(QResizeEvent* event)
242 QWidget::resizeEvent(event);
243 updateCloseButtonPosition();
246 void StatusBarMessageLabel::timerDone()
250 // increase the illumination
251 const int illumination_max = 128;
252 if (m_illumination < illumination_max) {
253 m_illumination += 32;
254 if (m_illumination > illumination_max) {
255 m_illumination = illumination_max;
259 m_state = Illuminated;
266 // start desaturation
267 if (m_currentMessage.type != MltError) {
268 m_state = Desaturate;
276 if (m_illumination < -128) {
280 setMessage(QString(), DefaultMessage);
293 int StatusBarMessageLabel::availableTextWidth() const
295 const int buttonWidth = 0; /*(m_type == ErrorMessage) ?
296 m_closeButton->width() + BorderGap : 0;*/
297 return width() - m_pixmap.width() - (BorderGap * 4) - buttonWidth;
300 void StatusBarMessageLabel::updateCloseButtonPosition()
302 const int x = width() - m_closeButton->width() - BorderGap;
303 const int y = (height() - m_closeButton->height()) / 2;
304 m_closeButton->move(x, y);
308 #include "statusbarmessagelabel.moc"