diff --git a/doc/Changelog.html b/doc/Changelog.html index eaca4159..c89f1aea 100644 --- a/doc/Changelog.html +++ b/doc/Changelog.html @@ -23,6 +23,7 @@ a:visited { color: #0000EE; }
  • Reworked the application initialization code, resulting in notably faster startup speed
  • Improved file analyzer to retain the original ordering of files imported from a playlist
  • Improved internal encoder API, so each encoder can define its own configuration options +
  • Improved splash screen and working banner, using "sheet of glass" effect on supported OS
  • Improved dropbox widget, including proper multi-monitor support
  • Updated mpg123 decoder to v1.16.0 (2013-10-06), compiled with GCC 4.8.1
  • Updated GNU Wget binary to v1.14.0 (2012-08-05), compiled with GCC 4.8.1 diff --git a/etc/Translation/Blank.ts b/etc/Translation/Blank.ts index ad9d629d..5cb139c4 100644 --- a/etc/Translation/Blank.ts +++ b/etc/Translation/Blank.ts @@ -3300,22 +3300,22 @@ QApplication - + Executable '%1' doesn't support Windows compatibility mode. - + Executable '%1' requires Qt v%2, but found Qt v%3. - + Executable '%1' was built for Qt '%2', but found Qt '%3'. - + Executable '%1' requires Windows XP or later. @@ -3336,7 +3336,7 @@ SplashScreen - + LameXP is launching... diff --git a/etc/Translation/LameXP_PL.ts b/etc/Translation/LameXP_PL.ts index 05891979..91e0da15 100644 --- a/etc/Translation/LameXP_PL.ts +++ b/etc/Translation/LameXP_PL.ts @@ -3337,22 +3337,22 @@ QApplication - + Executable '%1' doesn't support Windows compatibility mode. Plik wykonywalny '%1' nie działa w trybie kompatybilności z Windows. - + Executable '%1' requires Qt v%2, but found Qt v%3. Plik wykonywalny '%1' wymaga Qt v%2, znaleziono jednak Qt v%3. - + Executable '%1' was built for Qt '%2', but found Qt '%3'. Plik wykonywalny "%1" został skompilowany dla Qt "%2", znaleziono "%3". - + Executable '%1' requires Windows XP or later. @@ -3373,7 +3373,7 @@ SplashScreen - + LameXP is launching... LameXP właśnie odpala... diff --git a/etc/Translation/LameXP_SV.ts b/etc/Translation/LameXP_SV.ts index 998c72d6..bf3ff7db 100644 --- a/etc/Translation/LameXP_SV.ts +++ b/etc/Translation/LameXP_SV.ts @@ -3320,22 +3320,22 @@ QApplication - + Executable '%1' doesn't support Windows compatibility mode. EXE-filen '%1' stöder inte Windows kompatibilitetsläge. - + Executable '%1' requires Qt v%2, but found Qt v%3. EXE-filen '%1' kräver Qt v%2, du har Qt v%3. - + Executable '%1' was built for Qt '%2', but found Qt '%3'. EXE-filen '%1' är byggd för Qt '%2', du har Qt '%3'. - + Executable '%1' requires Windows XP or later. @@ -3356,7 +3356,7 @@ SplashScreen - + LameXP is launching... LameXP startar... diff --git a/gui/WorkingBanner.ui b/gui/WorkingBanner.ui index 52ad7d76..997d930a 100644 --- a/gui/WorkingBanner.ui +++ b/gui/WorkingBanner.ui @@ -2,24 +2,27 @@ WorkingBanner + + Qt::ApplicationModal + 0 0 - 480 - 51 + 512 + 78 - 480 + 512 0 - 480 - 53 + 512 + 16777215 @@ -89,31 +92,40 @@ Working - + + true + + + + 20 + + + 10 + + + 15 + + + 15 + + + 15 + - - - - - - 31 - 31 - - - - - 31 - 31 - - - - - - - :/images/Busy.gif - - - + + + + + + :/images/Clock.png + + + + + + + 4 + @@ -122,6 +134,15 @@ true + + QFrame::StyledPanel + + + QFrame::Plain + + + 0 + $(Status) @@ -130,6 +151,19 @@ + + + + 0 + + + -1 + + + Qt::AlignCenter + + + diff --git a/res/Images.qrc b/res/Images.qrc index fe9e9739..b6eb2678 100644 --- a/res/Images.qrc +++ b/res/Images.qrc @@ -6,6 +6,7 @@ images/Busy.gif images/Cartoon.png images/CD.png + images/Clock.png images/Disque.png images/DropBox.png images/DropZone.png diff --git a/res/images/Busy.gif b/res/images/Busy.gif index c69e9372..6df09734 100644 Binary files a/res/images/Busy.gif and b/res/images/Busy.gif differ diff --git a/res/images/Clock.png b/res/images/Clock.png new file mode 100644 index 00000000..bfc7c855 Binary files /dev/null and b/res/images/Clock.png differ diff --git a/res/images/Splash.png b/res/images/Splash.png deleted file mode 100644 index 8182ce69..00000000 Binary files a/res/images/Splash.png and /dev/null differ diff --git a/res/images/Splash2.png b/res/images/Splash2.png deleted file mode 100644 index a91c139e..00000000 Binary files a/res/images/Splash2.png and /dev/null differ diff --git a/res/images/Starting.png b/res/images/Starting.png new file mode 100644 index 00000000..ef73d5d4 Binary files /dev/null and b/res/images/Starting.png differ diff --git a/src/Config.h b/src/Config.h index 2b4edc06..0aec7e90 100644 --- a/src/Config.h +++ b/src/Config.h @@ -35,7 +35,7 @@ #define VER_LAMEXP_MINOR_LO 9 #define VER_LAMEXP_TYPE Alpha #define VER_LAMEXP_PATCH 8 -#define VER_LAMEXP_BUILD 1464 +#define VER_LAMEXP_BUILD 1470 #define VER_LAMEXP_CONFG 1348 /////////////////////////////////////////////////////////////////////////////// diff --git a/src/Dialog_WorkingBanner.cpp b/src/Dialog_WorkingBanner.cpp index 25caea1f..480c3a9e 100644 --- a/src/Dialog_WorkingBanner.cpp +++ b/src/Dialog_WorkingBanner.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #define EPS (1.0E-5) @@ -37,6 +38,36 @@ /* 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(1))) : false) +/*Update text color*/ +static inline void SET_TEXT_COLOR(QWidget *control, const QColor &color) +{ + QPalette pal = control->palette(); + pal.setColor(QPalette::WindowText, color); + pal.setColor(QPalette::Text, color); + control->setPalette(pal); +} + +/*Make widget translucent*/ +static inline void MAKE_TRANSLUCENT(QWidget *control) +{ + control->setAttribute(Qt::WA_TranslucentBackground); + control->setAttribute(Qt::WA_NoSystemBackground); +} + +/*Update widget margins*/ +static inline void UPDATE_MARGINS(QWidget *control, int l = 0, int r = 0, int t = 0, int b = 0) +{ + if(QLayout *layout = control->layout()) + { + QMargins margins = layout->contentsMargins(); + margins.setLeft(margins.left() + l); + margins.setRight(margins.right() + r); + margins.setTop(margins.top() + t); + margins.setBottom(margins.bottom() + b); + layout->setContentsMargins(margins); + } +} + //////////////////////////////////////////////////////////// // Constructor //////////////////////////////////////////////////////////// @@ -44,40 +75,35 @@ WorkingBanner::WorkingBanner(QWidget *parent) : QDialog(parent, Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint), - m_progressMax(0), m_progressVal(0), m_progressInt(0), m_metrics(NULL) + m_metrics(NULL), m_working(NULL) { //Init the dialog, from the .ui file setupUi(this); setModal(true); - //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); + //Enable the "sheet of glass" effect + if(lamexp_sheet_of_glass(this)) + { + SET_TEXT_COLOR(labelStatus, lamexp_system_color(lamexp_syscolor_caption)); + } + else + { + UPDATE_MARGINS(this, 5); + m_working = new QMovie(":/images/Busy.gif"); + m_working->setSpeed(75); + m_working->setCacheMode(QMovie::CacheAll); + labelWorking->setMovie(m_working); + m_working->start(); + } //Set Opacity this->setWindowOpacity(0.9); //Set wait cursor setCursor(Qt::WaitCursor); + + //Clear label + labelStatus->clear(); } //////////////////////////////////////////////////////////// @@ -89,11 +115,9 @@ WorkingBanner::~WorkingBanner(void) if(m_working) { m_working->stop(); - delete m_working; - m_working = NULL; + LAMEXP_DELETE(m_working); } - LAMEXP_DELETE(m_progress); LAMEXP_DELETE(m_metrics); } @@ -104,22 +128,14 @@ 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(); -} - -bool WorkingBanner::close(void) -{ - m_canClose = true; - emit userAbort(); - return QDialog::close(); + //Reset progress + progressBar->setMaximum(0); + progressBar->setValue(-1); } void WorkingBanner::show(const QString &text, QThread *thread) @@ -139,12 +155,18 @@ void WorkingBanner::show(const QString &text, QThread *thread) //Start the thread thread->start(); + //Update cursor + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + //Loop while thread is still running while(THREAD_RUNNING(thread)) { loop->exec(); } + //Restore cursor + QApplication::restoreOverrideCursor(); + //Set taskbar state WinSevenTaskbar::setTaskbarState(dynamic_cast(this->parent()), WinSevenTaskbar::WinSevenTaskbarNoState); WinSevenTaskbar::setOverlayIcon(dynamic_cast(this->parent()), NULL); @@ -165,9 +187,15 @@ void WorkingBanner::show(const QString &text, QEventLoop *loop) WinSevenTaskbar::setOverlayIcon(dynamic_cast(this->parent()), &QIcon(":/icons/hourglass.png")); WinSevenTaskbar::setTaskbarState(dynamic_cast(this->parent()), WinSevenTaskbar::WinSevenTaskbarIndeterminateState); + //Update cursor + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + //Loop while thread is running loop->exec(QEventLoop::ExcludeUserInputEvents); + //Restore cursor + QApplication::restoreOverrideCursor(); + //Set taskbar state WinSevenTaskbar::setTaskbarState(dynamic_cast(this->parent()), WinSevenTaskbar::WinSevenTaskbarNoState); WinSevenTaskbar::setOverlayIcon(dynamic_cast(this->parent()), NULL); @@ -176,6 +204,13 @@ void WorkingBanner::show(const QString &text, QEventLoop *loop) this->close(); } +bool WorkingBanner::close(void) +{ + m_canClose = true; + emit userAbort(); + return QDialog::close(); +} + //////////////////////////////////////////////////////////// // EVENTS //////////////////////////////////////////////////////////// @@ -217,14 +252,14 @@ void WorkingBanner::setText(const QString &text) m_metrics = new QFontMetrics(labelStatus->font()); } - if(m_metrics->width(text) <= labelStatus->width()) + if(m_metrics->width(text) <= labelStatus->width() - 8) { labelStatus->setText(text); } else { QString choppedText = text.simplified().append("..."); - while((m_metrics->width(choppedText) > labelStatus->width()) && (choppedText.length() > 8)) + while((m_metrics->width(choppedText) > labelStatus->width() - 8) && (choppedText.length() > 8)) { choppedText.chop(4); choppedText = choppedText.trimmed(); @@ -232,28 +267,23 @@ void WorkingBanner::setText(const QString &text) } labelStatus->setText(choppedText); } - if(this->isVisible()) - { - labelStatus->repaint(); - } } void WorkingBanner::setProgressMax(unsigned int max) { - m_progressMax = max; - updateProgress(); + progressBar->setMaximum(max); } void WorkingBanner::setProgressVal(unsigned int val) { - m_progressVal = val; - updateProgress(); + progressBar->setValue(val); } //////////////////////////////////////////////////////////// // Private //////////////////////////////////////////////////////////// +/* void WorkingBanner::updateProgress(void) { if(m_progressMax > 0) @@ -270,3 +300,4 @@ void WorkingBanner::updateProgress(void) } } } +*/ diff --git a/src/Dialog_WorkingBanner.h b/src/Dialog_WorkingBanner.h index 4328aeb4..f030a56c 100644 --- a/src/Dialog_WorkingBanner.h +++ b/src/Dialog_WorkingBanner.h @@ -43,7 +43,6 @@ public: private: QMovie *m_working; bool m_canClose; - void updateProgress(void); public slots: void setText(const QString &text); @@ -60,9 +59,5 @@ protected: void closeEvent(QCloseEvent *event); bool winEvent(MSG *message, long *result); - QLabel *m_progress; QFontMetrics *m_metrics; - unsigned int m_progressMax; - unsigned int m_progressVal; - unsigned int m_progressInt; }; diff --git a/src/Global.h b/src/Global.h index 3be801c5..b271e8bb 100644 --- a/src/Global.h +++ b/src/Global.h @@ -33,6 +33,7 @@ class QTime; class QIcon; class QWidget; class QProcess; +class QColor; class LockedFile; enum QtMsgType; @@ -125,6 +126,15 @@ typedef enum } lamexp_network_t; +//System color types +typedef enum +{ + lamexp_syscolor_text = 0, + lamexp_syscolor_background = 1, + lamexp_syscolor_caption = 2 +} +lamexp_syscolor_t; + /////////////////////////////////////////////////////////////////////////////// // GLOBAL FUNCTIONS /////////////////////////////////////////////////////////////////////////////// @@ -195,8 +205,10 @@ void lamexp_register_tool(const QString &toolName, LockedFile *file, unsigned in bool lamexp_remove_file(const QString &filename); void lamexp_seed_rand(void); bool lamexp_sheet_of_glass(QWidget *window); +bool lamexp_sheet_of_glass_update(QWidget *window); bool lamexp_shutdown_computer(const QString &message, const unsigned long timeout = 30, const bool forceShutdown = true, const bool hibernate = false); void lamexp_sleep(const unsigned int delay); +QColor lamexp_system_color(const int color_id); const char *lamexp_support_url(void); const QString &lamexp_temp_folder2(void); void lamexp_temp_folder_clear(void); diff --git a/src/Global_Win32.cpp b/src/Global_Win32.cpp index 8bbb91cc..4dd487af 100644 --- a/src/Global_Win32.cpp +++ b/src/Global_Win32.cpp @@ -174,6 +174,7 @@ static struct { bool bInitialized; QLibrary *dwmapi_dll; + HRESULT (__stdcall *dwmIsCompositionEnabled)(BOOL *bEnabled); HRESULT (__stdcall *dwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS* pMarInset); HRESULT (__stdcall *dwmEnableBlurBehindWindow)(HWND hWnd, const DWM_BLURBEHIND* pBlurBehind); QReadWriteLock lock; @@ -1857,16 +1858,21 @@ bool lamexp_open_media_file(const QString &mediaFilePath) return false; } -static void lamexp_init_dwmapi(void) +static bool lamexp_init_dwmapi(void) { QReadLocker writeLock(&g_lamexp_dwmapi.lock); //Not initialized yet? if(g_lamexp_dwmapi.bInitialized) { - return; + return (g_lamexp_dwmapi.dwmIsCompositionEnabled != NULL); } + //Reset function pointers + g_lamexp_dwmapi.dwmIsCompositionEnabled = NULL; + g_lamexp_dwmapi.dwmExtendFrameIntoClientArea = NULL; + g_lamexp_dwmapi.dwmEnableBlurBehindWindow = NULL; + //Does OS support DWM? if(lamexp_get_os_version() >= lamexp_winver_vista) { @@ -1874,7 +1880,8 @@ static void lamexp_init_dwmapi(void) g_lamexp_dwmapi.dwmapi_dll = new QLibrary("dwmapi.dll"); if(g_lamexp_dwmapi.dwmapi_dll->load()) { - //Lookup required functions + //Initialize function pointers + g_lamexp_dwmapi.dwmIsCompositionEnabled = (HRESULT (__stdcall*)(BOOL*)) g_lamexp_dwmapi.dwmapi_dll->resolve("DwmIsCompositionEnabled"); g_lamexp_dwmapi.dwmExtendFrameIntoClientArea = (HRESULT (__stdcall*)(HWND, const MARGINS*)) g_lamexp_dwmapi.dwmapi_dll->resolve("DwmExtendFrameIntoClientArea"); g_lamexp_dwmapi.dwmEnableBlurBehindWindow = (HRESULT (__stdcall*)(HWND, const DWM_BLURBEHIND*)) g_lamexp_dwmapi.dwmapi_dll->resolve("DwmEnableBlurBehindWindow"); } @@ -1886,6 +1893,7 @@ static void lamexp_init_dwmapi(void) } g_lamexp_dwmapi.bInitialized = true; + return (g_lamexp_dwmapi.dwmIsCompositionEnabled != NULL); } /* @@ -1899,12 +1907,20 @@ bool lamexp_sheet_of_glass(QWidget *window) while(!g_lamexp_dwmapi.bInitialized) { readLock.unlock(); - lamexp_init_dwmapi(); + if(!lamexp_init_dwmapi()) return false; readLock.relock(); } - //Required functions available? - if((g_lamexp_dwmapi.dwmExtendFrameIntoClientArea == NULL) || (g_lamexp_dwmapi.dwmEnableBlurBehindWindow == NULL)) + //Check if composition is enabled + BOOL bEnabled = FALSE; + if(HRESULT hr = g_lamexp_dwmapi.dwmIsCompositionEnabled(&bEnabled)) + { + qWarning("DwmIsCompositionEnabled function has failed! (error %d)", hr); + return false; + } + + //Composition enabled and required functions available? + if((!bEnabled) || (g_lamexp_dwmapi.dwmExtendFrameIntoClientArea == NULL) || (g_lamexp_dwmapi.dwmEnableBlurBehindWindow == NULL)) { return false; } @@ -1929,12 +1945,84 @@ bool lamexp_sheet_of_glass(QWidget *window) } //Required for Qt + window->setAutoFillBackground(false); window->setAttribute(Qt::WA_TranslucentBackground); window->setAttribute(Qt::WA_NoSystemBackground); return true; } +/* + * Update "sheet of glass" effect on the given Window + */ +bool lamexp_sheet_of_glass_update(QWidget *window) +{ + QReadLocker readLock(&g_lamexp_dwmapi.lock); + + //Initialize the DWM API + while(!g_lamexp_dwmapi.bInitialized) + { + readLock.unlock(); + if(!lamexp_init_dwmapi()) return false; + readLock.relock(); + } + + //Check if composition is enabled + BOOL bEnabled = FALSE; + if(HRESULT hr = g_lamexp_dwmapi.dwmIsCompositionEnabled(&bEnabled)) + { + qWarning("DwmIsCompositionEnabled function has failed! (error %d)", hr); + return false; + } + + //Composition enabled and required functions available? + if((!bEnabled) || (g_lamexp_dwmapi.dwmEnableBlurBehindWindow == NULL)) + { + return false; + } + + //Create and populate the Blur Behind structure + DWM_BLURBEHIND bb; + memset(&bb, 0, sizeof(DWM_BLURBEHIND)); + bb.fEnable = TRUE; + bb.dwFlags = DWM_BB_ENABLE; + if(HRESULT hr = g_lamexp_dwmapi.dwmEnableBlurBehindWindow(window->winId(), &bb)) + { + qWarning("DwmEnableBlurBehindWindow function has failed! (error %d)", hr); + return false; + } + + return true; +} + +/* + * Get system color info + */ +QColor lamexp_system_color(const int color_id) +{ + int nIndex = -1; + + switch(color_id) + { + case lamexp_syscolor_text: + nIndex = COLOR_WINDOWTEXT; /*Text in windows*/ + break; + case lamexp_syscolor_background: + nIndex = COLOR_WINDOW; /*Window background*/ + break; + case lamexp_syscolor_caption: + nIndex = COLOR_CAPTIONTEXT; /*Text in caption, size box, and scroll bar arrow box*/ + break; + default: + qWarning("Unknown system color id (%d) specified!", color_id); + nIndex = COLOR_WINDOWTEXT; + } + + const DWORD rgb = GetSysColor(nIndex); + QColor color(GetRValue(rgb), GetGValue(rgb), GetBValue(rgb)); + return color; +} + /* * Fatal application exit */ @@ -2009,8 +2097,9 @@ void lamexp_finalization(void) LAMEXP_DELETE(application); //Release DWM API - g_lamexp_dwmapi.dwmEnableBlurBehindWindow = NULL; + g_lamexp_dwmapi.dwmIsCompositionEnabled = NULL; g_lamexp_dwmapi.dwmExtendFrameIntoClientArea = NULL; + g_lamexp_dwmapi.dwmEnableBlurBehindWindow = NULL; LAMEXP_DELETE(g_lamexp_dwmapi.dwmapi_dll); //Detach from shared memory diff --git a/src/Thread_FileAnalyzer.cpp b/src/Thread_FileAnalyzer.cpp index 55e627b5..d847fa23 100644 --- a/src/Thread_FileAnalyzer.cpp +++ b/src/Thread_FileAnalyzer.cpp @@ -152,8 +152,8 @@ void FileAnalyzer::run() m_timer->invalidate(); //Update progress - emit progressMaxChanged(m_inputFiles.count()); - emit progressValChanged(0); + //emit progressMaxChanged(m_inputFiles.count()); + //emit progressValChanged(0); //Create MediaInfo template file if(!m_templateFile) @@ -180,6 +180,7 @@ void FileAnalyzer::run() //Update progress emit progressMaxChanged(nFiles); + emit progressValChanged(0); //Create thread pool if(!m_pool) m_pool = new QThreadPool();