OSDN Git Service

Better workaround for the previous commit.
[lamexp/LameXP.git] / src / Dialog_SplashScreen.cpp
index 1c8455d..3166244 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
 #include <QThread>
 #include <QMovie>
 #include <QKeyEvent>
-#include <Windows.h>
+#include <QTimer>
+
+#include "WinSevenTaskbar.h"
 
 #define EPS (1.0E-5)
+#define FADE_DELAY 4
 
 ////////////////////////////////////////////////////////////
 // Constructor
 ////////////////////////////////////////////////////////////
 
 SplashScreen::SplashScreen(QWidget *parent)
-       : QFrame(parent, Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint)
+:
+       QFrame(parent, Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint)
 {
        //Init the dialog, from the .ui file
        setupUi(this);
@@ -72,43 +76,81 @@ SplashScreen::~SplashScreen(void)
 
 void SplashScreen::showSplash(QThread *thread)
 {
+       double opacity = 0.0;
        SplashScreen *splashScreen = new SplashScreen();
        
        //Show splash
        splashScreen->m_canClose = false;
-       splashScreen->setWindowOpacity(0.0);
+       splashScreen->setWindowOpacity(opacity);
        splashScreen->show();
+
+       //Wait for window to show
        QApplication::processEvents();
+       Sleep(100);
+       QApplication::processEvents();
+
+       //Setup the event loop
+       QEventLoop *loop = new QEventLoop(splashScreen);
+       connect(thread, SIGNAL(terminated()), loop, SLOT(quit()), Qt::QueuedConnection);
+       connect(thread, SIGNAL(finished()), loop, SLOT(quit()), Qt::QueuedConnection);
 
-       //Start the thread
+       //Create timer
+       QTimer *timer = new QTimer();
+       connect(timer, SIGNAL(timeout()), loop, SLOT(quit()));
+
+       //Start thread
+       QApplication::processEvents();
        thread->start();
-       
+       QApplication::processEvents();
+
+       //Init taskbar
+       WinSevenTaskbar::setTaskbarState(splashScreen, WinSevenTaskbar::WinSevenTaskbarIndeterminateState);
+
        //Fade in
-       for(double d = 0.0; d <= 1.0 + EPS; d = d + 0.01)
+       for(int i = 0; i <= 100; i++)
        {
-               splashScreen->setWindowOpacity(d);
-               QApplication::processEvents();
-               Sleep(6);
+               opacity = 0.01 * static_cast<double>(i);
+               splashScreen->setWindowOpacity(opacity);
+               QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, FADE_DELAY);
+               Sleep(FADE_DELAY);
        }
 
-       //Loop while thread is running
-       while(thread->isRunning())
+       //Start the timer
+       timer->start(30720);
+
+       //Loop while thread is still running
+       bool bStillRunning = threadStillRunning(thread);
+       while(bStillRunning)
        {
-               QApplication::processEvents(QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents);
+               loop->exec();
+               if(bStillRunning = threadStillRunning(thread))
+               {
+                       qWarning("Potential deadlock in initialization thread!");
+               }
        }
-       
+
+       //Stop the timer
+       timer->stop();
+
        //Fade out
-       for(double d = 1.0; d >= 0.0; d = d - 0.01)
+       for(int i = 100; i >= 0; i--)
        {
-               splashScreen->setWindowOpacity(d);
-               QApplication::processEvents();
-               Sleep(6);
+               opacity = 0.01 * static_cast<double>(i);
+               splashScreen->setWindowOpacity(opacity);
+               QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, FADE_DELAY);
+               Sleep(FADE_DELAY);
        }
 
+       //Restore taskbar
+       WinSevenTaskbar::setTaskbarState(splashScreen, WinSevenTaskbar::WinSevenTaskbarNoState);
+
        //Hide splash
        splashScreen->m_canClose = true;
        splashScreen->close();
 
+       //Free
+       LAMEXP_DELETE(loop);
+       LAMEXP_DELETE(timer);
        LAMEXP_DELETE(splashScreen);
 }
 
@@ -130,3 +172,26 @@ void SplashScreen::closeEvent(QCloseEvent *event)
 {
        if(!m_canClose) event->ignore();
 }
+
+bool SplashScreen::winEvent(MSG *message, long *result)
+{
+       return WinSevenTaskbar::handleWinEvent(message, result);
+}
+
+////////////////////////////////////////////////////////////
+// HELPER FUNCTIONS
+////////////////////////////////////////////////////////////
+
+bool SplashScreen::threadStillRunning(const QThread *thread)
+{
+       for(int i = 0; i < 128; i++)
+       {
+               if(!(thread->isRunning()))
+               {
+                       return false;
+               }
+               QThread::yieldCurrentThread();
+       }
+
+       return thread->isRunning();
+}