Improved initialization of the working banner. Also banner can now be minimized using...
[LameXP.git] / src / Dialog_WorkingBanner.cpp
blob98484035627111fbdff73adbbcb1e1bb29c58830
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2013 LoRd_MuldeR <MuldeR2@GMX.de>
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, but always including the *additional*
9 // restrictions defined in the "License.txt" file.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 // http://www.gnu.org/licenses/gpl-2.0.txt
21 ///////////////////////////////////////////////////////////////////////////////
23 #include "Dialog_WorkingBanner.h"
24 #include "../tmp/UIC_WorkingBanner.h"
26 #include "Global.h"
27 #include "WinSevenTaskbar.h"
29 #include <QThread>
30 #include <QMovie>
31 #include <QKeyEvent>
32 #include <QFontMetrics>
33 #include <QPainter>
34 #include <QWindowsVistaStyle>
35 #include <QTimer>
37 #define EPS (1.0E-5)
39 /* It can happen that the QThread has just terminated and already emitted the 'terminated' signal, but did NOT change the 'isRunning' flag to FALSE yet. */
40 /* For this reason the macro will first check the 'isRunning' flag. If (and only if) the flag still returns TRUE, then we will wait() for at most 50 ms. */
41 /* If, after 50 ms, the wait() function returns with FALSE, then the thread probably is still running and we return TRUE. Otherwise we can return FALSE. */
42 #define THREAD_RUNNING(THRD) (((THRD)->isRunning()) ? (!((THRD)->wait(1))) : false)
44 /*Update text color*/
45 static inline void SET_TEXT_COLOR(QWidget *control, const QColor &color)
47 QPalette pal = control->palette();
48 pal.setColor(QPalette::WindowText, color);
49 pal.setColor(QPalette::Text, color);
50 control->setPalette(pal);
53 /*Make widget translucent*/
54 static inline void MAKE_TRANSLUCENT(QWidget *control)
56 control->setAttribute(Qt::WA_TranslucentBackground);
57 control->setAttribute(Qt::WA_NoSystemBackground);
60 /*Update widget margins*/
61 static inline void UPDATE_MARGINS(QWidget *control, int l = 0, int r = 0, int t = 0, int b = 0)
63 if(QLayout *layout = control->layout())
65 QMargins margins = layout->contentsMargins();
66 margins.setLeft(margins.left() + l);
67 margins.setRight(margins.right() + r);
68 margins.setTop(margins.top() + t);
69 margins.setBottom(margins.bottom() + b);
70 layout->setContentsMargins(margins);
74 ////////////////////////////////////////////////////////////
75 // Constructor
76 ////////////////////////////////////////////////////////////
78 WorkingBanner::WorkingBanner(QWidget *parent)
80 QDialog(parent, Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint),
81 ui(new Ui::WorkingBanner()), m_metrics(NULL), m_working(NULL), m_style(NULL)
83 //Init the dialog, from the .ui file
84 ui->setupUi(this);
85 setModal(true);
87 //Enable the "sheet of glass" effect
88 if(lamexp_sheet_of_glass(this))
90 m_style = new QWindowsVistaStyle();
91 this->setStyle(m_style);
92 ui->labelStatus->setStyle(m_style);
93 ui->progressBar->setStyle(m_style);
94 ui->labelStatus->setStyleSheet("background-color: rgb(255, 255, 255);");
96 else
98 UPDATE_MARGINS(this, 5);
99 m_working = new QMovie(":/images/Busy.gif");
100 m_working->setCacheMode(QMovie::CacheAll);
101 ui->labelWorking->setMovie(m_working);
102 m_working->start();
105 //Set Opacity
106 this->setWindowOpacity(0.9);
108 //Set wait cursor
109 setCursor(Qt::WaitCursor);
111 //Clear label
112 ui->labelStatus->clear();
115 ////////////////////////////////////////////////////////////
116 // Destructor
117 ////////////////////////////////////////////////////////////
119 WorkingBanner::~WorkingBanner(void)
121 if(m_working)
123 m_working->stop();
124 LAMEXP_DELETE(m_working);
127 LAMEXP_DELETE(m_style);
128 LAMEXP_DELETE(m_metrics);
129 delete ui;
132 ////////////////////////////////////////////////////////////
133 // PUBLIC FUNCTIONS
134 ////////////////////////////////////////////////////////////
136 void WorkingBanner::show(const QString &text)
138 m_canClose = false;
140 QDialog::show();
141 setFixedSize(size());
142 setText(text);
144 //Reset progress
145 ui->progressBar->setMinimum(0);
146 ui->progressBar->setMaximum(0);
147 ui->progressBar->setValue(-1);
150 void WorkingBanner::show(const QString &text, QThread *thread)
152 //Show splash
153 this->show(text);
155 //Create event loop
156 QEventLoop *loop = new QEventLoop(this);
157 connect(thread, SIGNAL(finished()), loop, SLOT(quit()));
158 connect(thread, SIGNAL(terminated()), loop, SLOT(quit()));
160 //Set taskbar state
161 WinSevenTaskbar::setOverlayIcon(dynamic_cast<QWidget*>(this->parent()), &QIcon(":/icons/hourglass.png"));
162 WinSevenTaskbar::setTaskbarState(dynamic_cast<QWidget*>(this->parent()), WinSevenTaskbar::WinSevenTaskbarIndeterminateState);
164 //Start the thread
165 thread->start();
167 //Update cursor
168 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
170 //Loop while thread is still running
171 while(THREAD_RUNNING(thread))
173 loop->exec();
176 //Restore cursor
177 QApplication::restoreOverrideCursor();
179 //Set taskbar state
180 WinSevenTaskbar::setTaskbarState(dynamic_cast<QWidget*>(this->parent()), WinSevenTaskbar::WinSevenTaskbarNoState);
181 WinSevenTaskbar::setOverlayIcon(dynamic_cast<QWidget*>(this->parent()), NULL);
183 //Free memory
184 LAMEXP_DELETE(loop);
186 //Hide splash
187 this->close();
190 void WorkingBanner::show(const QString &text, QEventLoop *loop)
192 //Show splash
193 this->show(text);
195 //Set taskbar state
196 WinSevenTaskbar::setOverlayIcon(dynamic_cast<QWidget*>(this->parent()), &QIcon(":/icons/hourglass.png"));
197 WinSevenTaskbar::setTaskbarState(dynamic_cast<QWidget*>(this->parent()), WinSevenTaskbar::WinSevenTaskbarIndeterminateState);
199 //Update cursor
200 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
202 //Loop while thread is running
203 loop->exec(QEventLoop::ExcludeUserInputEvents);
205 //Restore cursor
206 QApplication::restoreOverrideCursor();
208 //Set taskbar state
209 WinSevenTaskbar::setTaskbarState(dynamic_cast<QWidget*>(this->parent()), WinSevenTaskbar::WinSevenTaskbarNoState);
210 WinSevenTaskbar::setOverlayIcon(dynamic_cast<QWidget*>(this->parent()), NULL);
212 //Hide splash
213 this->close();
216 bool WorkingBanner::close(void)
218 m_canClose = true;
219 emit userAbort();
220 return QDialog::close();
223 ////////////////////////////////////////////////////////////
224 // EVENTS
225 ////////////////////////////////////////////////////////////
227 void WorkingBanner::keyPressEvent(QKeyEvent *event)
229 if(event->key() == Qt::Key_Escape)
231 qDebug("QT::KEY_ESCAPE pressed!");
232 emit userAbort();
234 else if(event->key() == Qt::Key_M)
236 QTimer::singleShot(0, parent(), SLOT(showMinimized()));
239 event->ignore();
242 void WorkingBanner::keyReleaseEvent(QKeyEvent *event)
244 event->ignore();
247 void WorkingBanner::closeEvent(QCloseEvent *event)
249 if(!m_canClose) event->ignore();
252 bool WorkingBanner::winEvent(MSG *message, long *result)
254 return WinSevenTaskbar::handleWinEvent(message, result);
257 void WorkingBanner::showEvent(QShowEvent *event)
259 QTimer::singleShot(25, this, SLOT(windowShown()));
262 ////////////////////////////////////////////////////////////
263 // SLOTS
264 ////////////////////////////////////////////////////////////
266 void WorkingBanner::windowShown(void)
268 lamexp_bring_to_front(this);
271 void WorkingBanner::setText(const QString &text)
273 if(!m_metrics)
275 m_metrics = new QFontMetrics(ui->labelStatus->font());
278 if(m_metrics->width(text) <= ui->labelStatus->width() - 16)
280 ui->labelStatus->setText(text);
282 else
284 QString choppedText = text.simplified().append("...");
285 while((m_metrics->width(choppedText) > ui->labelStatus->width() - 16) && (choppedText.length() > 8))
287 choppedText.chop(4);
288 choppedText = choppedText.trimmed();
289 choppedText.append("...");
291 ui->labelStatus->setText(choppedText);
295 void WorkingBanner::setProgressMax(unsigned int max)
297 ui->progressBar->setMaximum(max);
298 if(ui->progressBar->maximum() > ui->progressBar->minimum())
300 WinSevenTaskbar::setTaskbarState(dynamic_cast<QWidget*>(this->parent()), WinSevenTaskbar::WinSevenTaskbarNoState);
301 WinSevenTaskbar::setTaskbarProgress(dynamic_cast<QWidget*>(this->parent()), ui->progressBar->value(), ui->progressBar->maximum());
303 else
305 WinSevenTaskbar::setTaskbarState(dynamic_cast<QWidget*>(this->parent()), WinSevenTaskbar::WinSevenTaskbarIndeterminateState);
309 void WorkingBanner::setProgressVal(unsigned int val)
311 ui->progressBar->setValue(val);
312 if(ui->progressBar->maximum() > ui->progressBar->minimum())
314 WinSevenTaskbar::setTaskbarProgress(dynamic_cast<QWidget*>(this->parent()), ui->progressBar->value(), ui->progressBar->maximum());
318 ////////////////////////////////////////////////////////////
319 // Private
320 ////////////////////////////////////////////////////////////
323 void WorkingBanner::updateProgress(void)
325 if(m_progressMax > 0)
327 int newProgress = qRound(qBound(0.0, static_cast<double>(m_progressVal) / static_cast<double>(m_progressMax), 1.0) * 100.0);
328 if(m_progressInt != newProgress)
330 m_progressInt = newProgress;
331 m_progress->setText(QString::number(m_progressInt));
332 if(this->isVisible())
334 labelStatus->repaint();