OSDN Git Service

Updated VS2008 projects/solution files.
[lamexp/LameXP.git] / src / Dialog_WorkingBanner.cpp
index 417e664..c60ede8 100644 (file)
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 // LameXP - Audio Encoder Front-End
-// Copyright (C) 2004-2011 LoRd_MuldeR <MuldeR2@GMX.de>
+// Copyright (C) 2004-2012 LoRd_MuldeR <MuldeR2@GMX.de>
 //
 // 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
 
 #define EPS (1.0E-5)
 
+/* 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. */
+/* 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. */
+/* 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. */
+#define THREAD_RUNNING(THRD) (((THRD)->isRunning()) ? (!((THRD)->wait(50))) : false)
+
 ////////////////////////////////////////////////////////////
 // Constructor
 ////////////////////////////////////////////////////////////
 
 WorkingBanner::WorkingBanner(QWidget *parent)
 :
-       QDialog(parent, Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint)
+       QDialog(parent, Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint),
+       m_progressMax(0), m_progressVal(0), m_progressInt(0), m_metrics(NULL)
 {
        //Init the dialog, from the .ui file
        setupUi(this);
@@ -45,9 +51,27 @@ WorkingBanner::WorkingBanner(QWidget *parent)
 
        //Start animation
        m_working = new QMovie(":/images/Busy.gif");
+       m_working->setSpeed(50);
        labelWorking->setMovie(m_working);
        m_working->start();
 
+       //Create progress indicator
+       m_progress = new QLabel(labelWorking);
+       m_progress->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
+       m_progress->move(0, 0);
+       m_progress->resize(labelWorking->size());
+
+       //Set font size
+       QFont font = m_progress->font();
+       font.setPointSize(6);
+       m_progress->setFont(font);
+
+       //Set font color
+       QPalette color = m_progress->palette();
+       color.setColor(QPalette::Text, QColor::fromRgb(0x33, 0x33, 0x33));
+       color.setColor(QPalette::WindowText, QColor::fromRgb(0x33, 0x33, 0x33));
+       m_progress->setPalette(color);
+
        //Set wait cursor
        setCursor(Qt::WaitCursor);
 }
@@ -64,6 +88,9 @@ WorkingBanner::~WorkingBanner(void)
                delete m_working;
                m_working = NULL;
        }
+
+       LAMEXP_DELETE(m_progress);
+       LAMEXP_DELETE(m_metrics);
 }
 
 ////////////////////////////////////////////////////////////
@@ -73,15 +100,22 @@ WorkingBanner::~WorkingBanner(void)
 void WorkingBanner::show(const QString &text)
 {
        m_canClose = false;
+       m_progressInt = -1;
+
        QDialog::show();
+       setFixedSize(size());
        setText(text);
+
+       m_progress->setText(QString());
+
        QApplication::processEvents();
 }
 
-void WorkingBanner::close(void)
+bool WorkingBanner::close(void)
 {
        m_canClose = true;
-       QDialog::close();
+       emit userAbort();
+       return QDialog::close();
 }
 
 void WorkingBanner::show(const QString &text, QThread *thread)
@@ -89,23 +123,31 @@ void WorkingBanner::show(const QString &text, QThread *thread)
        //Show splash
        this->show(text);
 
-       //Start the thread
-       thread->start();
+       //Create event loop
+       QEventLoop *loop = new QEventLoop(this);
+       connect(thread, SIGNAL(finished()), loop, SLOT(quit()));
+       connect(thread, SIGNAL(terminated()), loop, SLOT(quit()));
 
        //Set taskbar state
        WinSevenTaskbar::setOverlayIcon(dynamic_cast<QWidget*>(this->parent()), &QIcon(":/icons/hourglass.png"));
        WinSevenTaskbar::setTaskbarState(dynamic_cast<QWidget*>(this->parent()), WinSevenTaskbar::WinSevenTaskbarIndeterminateState);
 
-       //Loop while thread is running
-       while(thread->isRunning())
+       //Start the thread
+       thread->start();
+
+       //Loop while thread is still running
+       while(THREAD_RUNNING(thread))
        {
-               QApplication::processEvents(QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents);
+               loop->exec();
        }
 
        //Set taskbar state
        WinSevenTaskbar::setTaskbarState(dynamic_cast<QWidget*>(this->parent()), WinSevenTaskbar::WinSevenTaskbarNoState);
        WinSevenTaskbar::setOverlayIcon(dynamic_cast<QWidget*>(this->parent()), NULL);
 
+       //Free memory
+       LAMEXP_DELETE(loop);
+
        //Hide splash
        this->close();
 }
@@ -166,15 +208,19 @@ bool WorkingBanner::winEvent(MSG *message, long *result)
 
 void WorkingBanner::setText(const QString &text)
 {
-       QFontMetrics metrics(labelStatus->font());
-       if(metrics.width(text) <= labelStatus->width())
+       if(!m_metrics)
+       {
+                m_metrics = new QFontMetrics(labelStatus->font());
+       }
+
+       if(m_metrics->width(text) <= labelStatus->width())
        {
                labelStatus->setText(text);
        }
        else
        {
                QString choppedText = text.simplified().append("...");
-               while(metrics.width(choppedText) > labelStatus->width() && choppedText.length() > 8)
+               while((m_metrics->width(choppedText) > labelStatus->width()) && (choppedText.length() > 8))
                {
                        choppedText.chop(4);
                        choppedText = choppedText.trimmed();
@@ -184,6 +230,39 @@ void WorkingBanner::setText(const QString &text)
        }
        if(this->isVisible())
        {
-               QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+               labelStatus->repaint();
+       }
+}
+
+void WorkingBanner::setProgressMax(unsigned int max)
+{
+       m_progressMax = max;
+       updateProgress();
+}
+
+void WorkingBanner::setProgressVal(unsigned int val)
+{
+       m_progressVal = val;
+       updateProgress();
+}
+
+////////////////////////////////////////////////////////////
+// Private
+////////////////////////////////////////////////////////////
+
+void WorkingBanner::updateProgress(void)
+{
+       if(m_progressMax > 0)
+       {
+               int newProgress = qRound(qBound(0.0, static_cast<double>(m_progressVal) / static_cast<double>(m_progressMax), 1.0) * 100.0);
+               if(m_progressInt != newProgress)
+               {
+                       m_progressInt = newProgress;
+                       m_progress->setText(QString::number(m_progressInt));
+                       if(this->isVisible())
+                       {
+                               labelStatus->repaint();
+                       }
+               }
        }
 }