Updated changelog.
[LameXP.git] / src / Dialog_WorkingBanner.cpp
blob85e32a805e4b355bd2209315451ba098dfaa0ed0
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2023 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; always including the non-optional
9 // LAMEXP GNU GENERAL PUBLIC LICENSE ADDENDUM. See "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 "UIC_WorkingBanner.h"
26 //Internal
27 #include "Global.h"
29 //MUtils
30 #include <MUtils/Global.h>
31 #include <MUtils/GUI.h>
32 #include <MUtils/Taskbar7.h>
34 //Qt
35 #include <QThread>
36 #include <QMovie>
37 #include <QKeyEvent>
38 #include <QFontMetrics>
39 #include <QPainter>
40 #include <QWindowsVistaStyle>
41 #include <QTimer>
43 #define EPS (1.0E-5)
45 /* 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. */
46 /* 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. */
47 /* 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. */
48 #define THREAD_RUNNING(THRD) (((THRD)->isRunning()) ? (!((THRD)->wait(1))) : false)
50 /*Update text color*/
51 static inline void SET_TEXT_COLOR(QWidget *control, const QColor &color)
53 QPalette pal = control->palette();
54 pal.setColor(QPalette::WindowText, color);
55 pal.setColor(QPalette::Text, color);
56 control->setPalette(pal);
59 /*Make widget translucent*/
60 static inline void MAKE_TRANSLUCENT(QWidget *control)
62 control->setAttribute(Qt::WA_TranslucentBackground);
63 control->setAttribute(Qt::WA_NoSystemBackground);
66 /*Update widget margins*/
67 static inline void UPDATE_MARGINS(QWidget *control, int l = 0, int r = 0, int t = 0, int b = 0)
69 if(QLayout *layout = control->layout())
71 QMargins margins = layout->contentsMargins();
72 margins.setLeft(margins.left() + l);
73 margins.setRight(margins.right() + r);
74 margins.setTop(margins.top() + t);
75 margins.setBottom(margins.bottom() + b);
76 layout->setContentsMargins(margins);
80 ////////////////////////////////////////////////////////////
81 // Constructor
82 ////////////////////////////////////////////////////////////
84 WorkingBanner::WorkingBanner(QWidget *parent)
86 QDialog(parent, Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint),
87 ui(new Ui::WorkingBanner()),
88 m_iconHourglass(new QIcon(":/icons/hourglass.png")),
89 m_taskbar(new MUtils::Taskbar7(parent)),
90 m_metrics(NULL), m_working(NULL), m_style(NULL)
92 //Init the dialog, from the .ui file
93 ui->setupUi(this);
94 setModal(true);
96 //Enable the "sheet of glass" effect
97 if(MUtils::GUI::sheet_of_glass(this))
99 m_style.reset(new QWindowsVistaStyle());
100 this->setStyle(m_style.data());
101 ui->progressBar->setStyle(m_style.data());
102 ui->labelStatus->setStyle(m_style.data());
103 ui->labelStatus->setStyleSheet("background-color: #FFFFFF;");
105 else
107 UPDATE_MARGINS(this, 5);
108 m_working.reset(new QMovie(":/images/Busy.gif"));
109 m_working->setCacheMode(QMovie::CacheAll);
110 ui->labelWorking->setMovie(m_working.data());
113 //Set Opacity
114 this->setWindowOpacity(0.9);
116 //Set wait cursor
117 setCursor(Qt::WaitCursor);
119 //Clear label
120 ui->labelStatus->clear();
123 ////////////////////////////////////////////////////////////
124 // Destructor
125 ////////////////////////////////////////////////////////////
127 WorkingBanner::~WorkingBanner(void)
129 if(!m_working.isNull())
131 m_working->stop();
134 delete ui;
137 ////////////////////////////////////////////////////////////
138 // PUBLIC FUNCTIONS
139 ////////////////////////////////////////////////////////////
141 void WorkingBanner::show(const QString &text)
143 m_canClose = false;
145 QDialog::show();
146 setFixedSize(size());
147 setText(text);
149 //Reset progress
150 ui->progressBar->setMinimum(0);
151 ui->progressBar->setMaximum(0);
152 ui->progressBar->setValue(-1);
155 void WorkingBanner::show(const QString &text, QThread *thread)
157 //Show splash
158 this->show(text);
160 //Create event loop
161 QEventLoop *loop = new QEventLoop(this);
162 connect(thread, SIGNAL(finished()), loop, SLOT(quit()));
163 connect(thread, SIGNAL(terminated()), loop, SLOT(quit()));
165 //Set taskbar state
166 m_taskbar->setOverlayIcon(m_iconHourglass.data());
167 m_taskbar->setTaskbarState(MUtils::Taskbar7::TASKBAR_STATE_INTERMEDIATE);
169 //Start the thread
170 thread->start();
172 //Update cursor
173 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
175 //Loop while thread is still running
176 while(THREAD_RUNNING(thread))
178 loop->exec();
181 //Restore cursor
182 QApplication::restoreOverrideCursor();
184 //Set taskbar state
185 m_taskbar->setTaskbarState(MUtils::Taskbar7::TASKBAR_STATE_NONE);
186 m_taskbar->setOverlayIcon(NULL);
188 //Free memory
189 MUTILS_DELETE(loop);
191 //Hide splash
192 this->close();
195 void WorkingBanner::show(const QString &text, QEventLoop *loop)
197 //Show splash
198 this->show(text);
200 //Set taskbar state
201 m_taskbar->setOverlayIcon(m_iconHourglass.data());
202 m_taskbar->setTaskbarState(MUtils::Taskbar7::TASKBAR_STATE_INTERMEDIATE);
204 //Update cursor
205 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
207 //Loop while thread is running
208 loop->exec(QEventLoop::ExcludeUserInputEvents);
210 //Restore cursor
211 QApplication::restoreOverrideCursor();
213 //Set taskbar state
214 m_taskbar->setTaskbarState(MUtils::Taskbar7::TASKBAR_STATE_NONE);
215 m_taskbar->setOverlayIcon(NULL);
217 //Hide splash
218 this->close();
221 bool WorkingBanner::close(void)
223 m_canClose = true;
224 emit userAbort();
225 return QDialog::close();
228 ////////////////////////////////////////////////////////////
229 // EVENTS
230 ////////////////////////////////////////////////////////////
232 void WorkingBanner::keyPressEvent(QKeyEvent *event)
234 if(event->key() == Qt::Key_Escape)
236 qDebug("QT::KEY_ESCAPE pressed!");
237 emit userAbort();
239 else if(event->key() == Qt::Key_M)
241 QTimer::singleShot(0, parent(), SLOT(showMinimized()));
244 QDialog::keyPressEvent(event);
247 void WorkingBanner::keyReleaseEvent(QKeyEvent *event)
249 QDialog::keyReleaseEvent(event);
252 void WorkingBanner::closeEvent(QCloseEvent *event)
254 if(!m_canClose) event->ignore();
257 void WorkingBanner::showEvent(QShowEvent *event)
259 QDialog::showEvent(event);
260 if(!event->spontaneous())
262 if(m_working)
264 m_working->start();
267 QTimer::singleShot(25, this, SLOT(windowShown()));
270 void WorkingBanner::hideEvent(QHideEvent *event)
272 QDialog::hideEvent(event);
273 if(!event->spontaneous())
275 if(m_working)
277 m_working->stop();
282 ////////////////////////////////////////////////////////////
283 // SLOTS
284 ////////////////////////////////////////////////////////////
286 void WorkingBanner::windowShown(void)
288 MUtils::GUI::bring_to_front(this);
291 void WorkingBanner::setText(const QString &text)
293 if(m_metrics.isNull())
295 m_metrics.reset(new QFontMetrics(ui->labelStatus->font()));
298 if(m_metrics->width(text) <= ui->labelStatus->width() - 16)
300 ui->labelStatus->setText(text);
302 else
304 QString choppedText = text.simplified().append("...");
305 while((m_metrics->width(choppedText) > ui->labelStatus->width() - 16) && (choppedText.length() > 8))
307 choppedText.chop(4);
308 choppedText = choppedText.trimmed();
309 choppedText.append("...");
311 ui->labelStatus->setText(choppedText);
315 void WorkingBanner::setProgressMax(unsigned int max)
317 ui->progressBar->setMaximum(max);
318 if(ui->progressBar->maximum() > ui->progressBar->minimum())
320 m_taskbar->setTaskbarState(MUtils::Taskbar7::TASKBAR_STATE_NONE);
321 m_taskbar->setTaskbarProgress(ui->progressBar->value(), ui->progressBar->maximum());
323 else
325 m_taskbar->setTaskbarState(MUtils::Taskbar7::TASKBAR_STATE_INTERMEDIATE);
329 void WorkingBanner::setProgressVal(unsigned int val)
331 ui->progressBar->setValue(val);
332 if(ui->progressBar->maximum() > ui->progressBar->minimum())
334 m_taskbar->setTaskbarProgress(ui->progressBar->value(), ui->progressBar->maximum());
338 ////////////////////////////////////////////////////////////
339 // Private
340 ////////////////////////////////////////////////////////////
343 void WorkingBanner::updateProgress(void)
345 if(m_progressMax > 0)
347 int newProgress = qRound(qBound(0.0, static_cast<double>(m_progressVal) / static_cast<double>(m_progressMax), 1.0) * 100.0);
348 if(m_progressInt != newProgress)
350 m_progressInt = newProgress;
351 m_progress->setText(QString::number(m_progressInt));
352 if(this->isVisible())
354 labelStatus->repaint();