diff --git a/LameXP.vcproj b/LameXP.vcproj index e6d17ad5..d3a2b443 100644 --- a/LameXP.vcproj +++ b/LameXP.vcproj @@ -130,7 +130,7 @@ EnableIntrinsicFunctions="true" FavorSizeOrSpeed="1" OmitFramePointers="true" - AdditionalIncludeDirectories=""$(QTDIR)\include";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui"" + AdditionalIncludeDirectories=""$(QTDIR)\include";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui";"C:\Program Files\Microsoft SDKs\Windows\v7.1"" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;QT_LARGEFILE_SUPPORT;QT_GUI_LIB;QT_CORE_LIB;QT_THREAD_SUPPORT;QT_DLL;QT_NO_DEBUG" MinimalRebuild="false" BasicRuntimeChecks="0" @@ -422,6 +422,10 @@ RelativePath=".\src\Tool_Abstract.cpp" > + + @@ -769,7 +773,7 @@ @@ -779,7 +783,7 @@ @@ -1228,6 +1232,10 @@ /> + + @@ -1361,7 +1369,7 @@ @@ -1371,7 +1379,7 @@ diff --git a/gui/MainWindow.ui b/gui/MainWindow.ui index c213a5e2..e5c773f6 100644 --- a/gui/MainWindow.ui +++ b/gui/MainWindow.ui @@ -901,7 +901,7 @@ - + ForbiddenCursor @@ -923,7 +923,7 @@ - + Qt::Vertical @@ -949,7 +949,7 @@ - + Qt::Horizontal @@ -962,7 +962,7 @@ - + Qt::Horizontal @@ -975,6 +975,25 @@ + + + + false + + + + 50 + false + + + + More options will be added in a later version, stay tuned! + + + Qt::AlignCenter + + + @@ -1396,6 +1415,12 @@ + + + + + + diff --git a/gui/SplashScreen.ui b/gui/SplashScreen.ui index 6def4263..8348b3d0 100644 --- a/gui/SplashScreen.ui +++ b/gui/SplashScreen.ui @@ -114,7 +114,7 @@ - Frame + LameXP is launching... true @@ -261,6 +261,7 @@ + diff --git a/res/Icons.qrc b/res/Icons.qrc index 5d66644a..19243bb4 100644 --- a/res/Icons.qrc +++ b/res/Icons.qrc @@ -25,6 +25,7 @@ icons/computer.png icons/controller.png icons/control_pause_blue.png + icons/control_play_blue.png icons/cross.png icons/date.png icons/delete.png @@ -32,12 +33,14 @@ icons/door_out.png icons/drive_cd.png icons/exclamation.png + icons/error.png icons/feed.png icons/folder_add.png icons/folder_go.png icons/folder_image.png icons/folder_page.png icons/house.png + icons/hourglass.png icons/information.png icons/media_play.png icons/monitor.png diff --git a/res/Images.qrc b/res/Images.qrc index 47d7d308..5bc1ac2e 100644 --- a/res/Images.qrc +++ b/res/Images.qrc @@ -7,6 +7,8 @@ images/Label.png images/Loading.gif images/Logo.png + images/Logo_Contributors.png + images/Logo_Software.png images/Splash.png images/Thumb.png images/Construction.gif diff --git a/res/images/Logo_Contributors.png b/res/images/Logo_Contributors.png new file mode 100644 index 00000000..293927b4 Binary files /dev/null and b/res/images/Logo_Contributors.png differ diff --git a/res/images/Logo_Software.png b/res/images/Logo_Software.png new file mode 100644 index 00000000..bca3e198 Binary files /dev/null and b/res/images/Logo_Software.png differ diff --git a/src/Config.h b/src/Config.h index 404289b1..457dcb0d 100644 --- a/src/Config.h +++ b/src/Config.h @@ -25,7 +25,7 @@ #define VER_LAMEXP_MAJOR 4 #define VER_LAMEXP_MINOR_HI 0 #define VER_LAMEXP_MINOR_LO 0 -#define VER_LAMEXP_BUILD 120 +#define VER_LAMEXP_BUILD 124 #define VER_LAMEXP_SUFFIX TechPreview /* diff --git a/src/Dialog_About.cpp b/src/Dialog_About.cpp index 98c54254..d338ab46 100644 --- a/src/Dialog_About.cpp +++ b/src/Dialog_About.cpp @@ -190,7 +190,9 @@ void AboutDialog::showAboutContributors(void) contributorsAboutText += ""; contributorsAboutText += CONTRIBUTOR("Englisch", "LoRd_MuldeR <MuldeR2@GMX.de>", ":/flags/gb.png"); contributorsAboutText += CONTRIBUTOR("Deutsch", "LoRd_MuldeR <MuldeR2@GMX.de>", ":/flags/de.png"); - contributorsAboutText += "

"; + contributorsAboutText += ""; + contributorsAboutText += "

"; + contributorsAboutText += "If you are willing to contribute a LameXP translation, feel free to contact us!
"; QMessageBox *contributorsAboutBox = new QMessageBox(this); contributorsAboutBox->setText(contributorsAboutText); @@ -201,6 +203,7 @@ void AboutDialog::showAboutContributors(void) closeButton->setMinimumWidth(90); contributorsAboutBox->setWindowTitle("About Contributors"); + contributorsAboutBox->setIconPixmap(QIcon(":/images/Logo_Contributors.png").pixmap(QSize(64,74))); contributorsAboutBox->setWindowIcon(QIcon(":/icons/user_suit.png")); contributorsAboutBox->exec(); @@ -239,6 +242,7 @@ void AboutDialog::showMoreAbout(void) closeButton->setMinimumWidth(90); moreAboutBox->setWindowTitle("About Third-party Software"); + moreAboutBox->setIconPixmap(QIcon(":/images/Logo_Software.png").pixmap(QSize(64,71))); moreAboutBox->setWindowIcon(QIcon(":/icons/page_white_cplusplus.png")); moreAboutBox->exec(); diff --git a/src/Dialog_MainWindow.cpp b/src/Dialog_MainWindow.cpp index be23342d..9cecca05 100644 --- a/src/Dialog_MainWindow.cpp +++ b/src/Dialog_MainWindow.cpp @@ -34,6 +34,7 @@ #include "Model_Settings.h" #include "Model_FileList.h" #include "Model_FileSystem.h" +#include "WinSevenTaskbar.h" //Qt includes #include @@ -152,6 +153,7 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S outputFolderView->setAnimated(true); outputFolderView->installEventFilter(this); outputFolderView->setMouseTracking(false); + outputFolderView->setContextMenuPolicy(Qt::CustomContextMenu); while(saveToSourceFolderCheckBox->isChecked() != m_settings->outputToSourceDir()) saveToSourceFolderCheckBox->click(); connect(outputFolderView, SIGNAL(clicked(QModelIndex)), this, SLOT(outputFolderViewClicked(QModelIndex))); connect(outputFolderView, SIGNAL(activated(QModelIndex)), this, SLOT(outputFolderViewClicked(QModelIndex))); @@ -163,6 +165,10 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S connect(buttonGotoDesktop, SIGNAL(clicked()), this, SLOT(gotoDesktopButtonClicked())); connect(buttonGotoMusic, SIGNAL(clicked()), this, SLOT(gotoMusicFolderButtonClicked())); connect(saveToSourceFolderCheckBox, SIGNAL(clicked()), this, SLOT(saveToSourceFolderChanged())); + m_outputFolderContextMenu = new QMenu(); + QAction *showFolderContextAction = m_outputFolderContextMenu->addAction(QIcon(":/icons/zoom.png"), "Browse Selected Folder"); + connect(outputFolderView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(outputFolderContextMenu(QPoint))); + connect(showFolderContextAction, SIGNAL(triggered(bool)), this, SLOT(showFolderContextActionTriggered())); //Setup "Meta Data" tab m_metaInfoModel = new MetaInfoModel(m_metaData, 6); @@ -1275,6 +1281,22 @@ void MainWindow::findFileContextActionTriggered(void) } } +/* + * Show context menu for output folder + */ +void MainWindow::outputFolderContextMenu(const QPoint &pos) +{ + m_outputFolderContextMenu->popup(outputFolderView->mapToGlobal(pos)); +} + +/* + * Show selected folder in explorer + */ +void MainWindow::showFolderContextActionTriggered(void) +{ + QDesktopServices::openUrl(QUrl::fromLocalFile(m_fileSystemModel->filePath(outputFolderView->currentIndex()))); +} + /* * Disable update reminder action */ diff --git a/src/Dialog_MainWindow.h b/src/Dialog_MainWindow.h index 8f5f2067..ed0679d5 100644 --- a/src/Dialog_MainWindow.h +++ b/src/Dialog_MainWindow.h @@ -85,6 +85,8 @@ private slots: void findFileContextActionTriggered(void); void disableUpdateReminderActionTriggered(bool checked); void disableSoundsActionTriggered(bool checked); + void outputFolderContextMenu(const QPoint &pos); + void showFolderContextActionTriggered(void); protected: void showEvent(QShowEvent *event); @@ -114,4 +116,5 @@ private: SettingsModel *m_settings; QLabel *m_dropNoteLabel; QMenu *m_sourceFilesContextMenu; + QMenu *m_outputFolderContextMenu; }; diff --git a/src/Dialog_Processing.cpp b/src/Dialog_Processing.cpp index 352c73a1..a8dca62d 100644 --- a/src/Dialog_Processing.cpp +++ b/src/Dialog_Processing.cpp @@ -31,6 +31,7 @@ #include "Encoder_MP3.h" #include "Encoder_Vorbis.h" #include "Encoder_AAC.h" +#include "WinSevenTaskbar.h" #include #include @@ -137,6 +138,9 @@ ProcessingDialog::~ProcessingDialog(void) LAMEXP_DELETE(m_progressModel); LAMEXP_DELETE(m_contextMenu); + WinSevenTaskbar::setOverlayIcon(this, NULL); + WinSevenTaskbar::setTaskbarState(this, WinSevenTaskbar::WinSevenTaskbarNoState); + while(!m_threadList.isEmpty()) { ProcessThread *thread = m_threadList.takeFirst(); @@ -219,6 +223,11 @@ void ProcessingDialog::initEncoding(void) button_AbortProcess->setEnabled(true); progressBar->setRange(0, m_pendingJobs.count()); + WinSevenTaskbar::initTaskbar(); + WinSevenTaskbar::setTaskbarState(this, WinSevenTaskbar::WinSevenTaskbarNormalState); + WinSevenTaskbar::setTaskbarProgress(this, 0, m_pendingJobs.count()); + WinSevenTaskbar::setOverlayIcon(this, &QIcon(":/icons/control_play_blue.png")); + lamexp_cpu_t cpuFeatures = lamexp_detect_cpu_features(); for(int i = 0; i < min(max(cpuFeatures.count, 1), 4); i++) @@ -248,6 +257,7 @@ void ProcessingDialog::doneEncoding(void) if(!m_userAborted) { label_progress->setText(QString("Encoding: %1 files of %2 completed so far, please wait...").arg(QString::number(progressBar->value()), QString::number(progressBar->maximum()))); + WinSevenTaskbar::setTaskbarProgress(this, progressBar->value(), progressBar->maximum()); } int index = m_threadList.indexOf(dynamic_cast(QWidget::sender())); @@ -282,6 +292,8 @@ void ProcessingDialog::doneEncoding(void) if(m_userAborted) { CHANGE_BACKGROUND_COLOR(frame_header, QColor("#FFF3BA")); + WinSevenTaskbar::setTaskbarState(this, WinSevenTaskbar::WinSevenTaskbarErrorState); + WinSevenTaskbar::setOverlayIcon(this, &QIcon(":/icons/error.png")); label_progress->setText((m_succeededFiles > 0) ? QString("Process was aborted by the user after %1 file(s)!").arg(QString::number(m_succeededFiles)) : "Process was aborted prematurely by the user!"); QApplication::processEvents(); if(m_settings->soundsEnabled()) PlaySound(MAKEINTRESOURCE(IDR_WAVE_ABORTED), GetModuleHandle(NULL), SND_RESOURCE | SND_SYNC); @@ -291,6 +303,8 @@ void ProcessingDialog::doneEncoding(void) if(m_failedFiles) { CHANGE_BACKGROUND_COLOR(frame_header, QColor("#FFBABA")); + WinSevenTaskbar::setTaskbarState(this, WinSevenTaskbar::WinSevenTaskbarErrorState); + WinSevenTaskbar::setOverlayIcon(this, &QIcon(":/icons/exclamation.png")); label_progress->setText(QString("Error: %1 of %2 files failed. Double-click failed items for detailed information!").arg(QString::number(m_failedFiles), QString::number(m_failedFiles + m_succeededFiles))); QApplication::processEvents(); if(m_settings->soundsEnabled()) PlaySound(MAKEINTRESOURCE(IDR_WAVE_ERROR), GetModuleHandle(NULL), SND_RESOURCE | SND_SYNC); @@ -298,6 +312,8 @@ void ProcessingDialog::doneEncoding(void) else { CHANGE_BACKGROUND_COLOR(frame_header, QColor("#D1FFD5")); + WinSevenTaskbar::setTaskbarState(this, WinSevenTaskbar::WinSevenTaskbarNormalState); + WinSevenTaskbar::setOverlayIcon(this, &QIcon(":/icons/accept.png")); label_progress->setText("Alle files completed successfully."); QApplication::processEvents(); if(m_settings->soundsEnabled()) PlaySound(MAKEINTRESOURCE(IDR_WAVE_SUCCESS), GetModuleHandle(NULL), SND_RESOURCE | SND_SYNC); @@ -310,7 +326,8 @@ void ProcessingDialog::doneEncoding(void) view_log->scrollToBottom(); m_progressIndicator->stop(); - progressBar->setValue(100); + progressBar->setValue(progressBar->maximum()); + WinSevenTaskbar::setTaskbarProgress(this, progressBar->value(), progressBar->maximum()); QApplication::restoreOverrideCursor(); } diff --git a/src/Dialog_WorkingBanner.cpp b/src/Dialog_WorkingBanner.cpp index 618992d9..af92bbc5 100644 --- a/src/Dialog_WorkingBanner.cpp +++ b/src/Dialog_WorkingBanner.cpp @@ -22,6 +22,7 @@ #include "Dialog_WorkingBanner.h" #include "Global.h" +#include "WinSevenTaskbar.h" #include #include @@ -36,7 +37,8 @@ //////////////////////////////////////////////////////////// WorkingBanner::WorkingBanner(QWidget *parent) -: QDialog(parent, Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint) +: + QDialog(parent, Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint) { //Init the dialog, from the .ui file setupUi(this); @@ -49,6 +51,9 @@ WorkingBanner::WorkingBanner(QWidget *parent) //Set wait cursor setCursor(Qt::WaitCursor); + + //Init taskbar + WinSevenTaskbar::initTaskbar(); } //////////////////////////////////////////////////////////// @@ -91,12 +96,20 @@ void WorkingBanner::show(const QString &text, QThread *thread) //Start the thread thread->start(); + //Set taskbar state + WinSevenTaskbar::setOverlayIcon(dynamic_cast(this->parent()), &QIcon(":/icons/hourglass.png")); + WinSevenTaskbar::setTaskbarState(dynamic_cast(this->parent()), WinSevenTaskbar::WinSevenTaskbarIndeterminateState); + //Loop while thread is running while(thread->isRunning()) { QApplication::processEvents(QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents); } + //Set taskbar state + WinSevenTaskbar::setTaskbarState(dynamic_cast(this->parent()), WinSevenTaskbar::WinSevenTaskbarNoState); + WinSevenTaskbar::setOverlayIcon(dynamic_cast(this->parent()), NULL); + //Hide splash this->close(); } diff --git a/src/Tool_Abstract.cpp b/src/Tool_Abstract.cpp index 2b599c31..6c523509 100644 --- a/src/Tool_Abstract.cpp +++ b/src/Tool_Abstract.cpp @@ -77,6 +77,8 @@ AbstractTool::AbstractTool(void) } } } + + m_firstLaunch = true; } /* @@ -118,8 +120,15 @@ bool AbstractTool::startProcess(QProcess &process, const QString &program, const { SetPriorityClass(process.pid()->hProcess, IDLE_PRIORITY_CLASS); } + lock.unlock(); - emit statusUpdated(0); + + if(m_firstLaunch) + { + emit statusUpdated(0); + m_firstLaunch = false; + } + return true; } diff --git a/src/Tool_Abstract.h b/src/Tool_Abstract.h index 902d592f..36772527 100644 --- a/src/Tool_Abstract.h +++ b/src/Tool_Abstract.h @@ -45,4 +45,5 @@ signals: private: static QMutex *m_mutex_startProcess; static void *m_handle_jobObject; + bool m_firstLaunch; }; diff --git a/src/WinSevenTaskbar.cpp b/src/WinSevenTaskbar.cpp new file mode 100644 index 00000000..7fca79ee --- /dev/null +++ b/src/WinSevenTaskbar.cpp @@ -0,0 +1,119 @@ +/////////////////////////////////////////////////////////////////////////////// +// LameXP - Audio Encoder Front-End +// Copyright (C) 2004-2010 LoRd_MuldeR +// +// 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 +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// http://www.gnu.org/licenses/gpl-2.0.txt +/////////////////////////////////////////////////////////////////////////////// + +#include "WinSevenTaskbar.h" + +#include +#include + +#ifdef __ITaskbarList3_INTERFACE_DEFINED__ + +ITaskbarList3 *WinSevenTaskbar::m_ptbl = NULL; + +WinSevenTaskbar::WinSevenTaskbar(void) +{ +} + +WinSevenTaskbar::~WinSevenTaskbar(void) +{ +} + +void WinSevenTaskbar::initTaskbar(void) +{ + OSVERSIONINFOW version; + memset(&version, 0, sizeof(OSVERSIONINFOW)); + version.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); + GetVersionEx(&version); + + if(version.dwMajorVersion >= 6 && version.dwMinorVersion >= 1) + { + if(!m_ptbl) + { + ITaskbarList3 *ptbl; + HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ptbl)); + + if (SUCCEEDED(hr)) + { + HRESULT hr2 = ptbl->HrInit(); + if(SUCCEEDED(hr2)) + { + m_ptbl = ptbl; + } + else + { + ptbl->Release(); + qWarning("ITaskbarList3::HrInit() has failed."); + } + } + else + { + qWarning("ITaskbarList3 could not be created."); + } + } + } + else + { + qWarning("This OS doesn't support the ITaskbarList3 interface (needs NT 6.1 or later)"); + } +} + +void WinSevenTaskbar::setTaskbarState(QWidget *window, WinSevenTaskbarState state) +{ + if(m_ptbl && window) + { + switch(state) + { + case WinSevenTaskbarNoState: + m_ptbl->SetProgressState(window->winId(), TBPF_NOPROGRESS); + break; + case WinSevenTaskbarNormalState: + m_ptbl->SetProgressState(window->winId(), TBPF_NORMAL); + break; + case WinSevenTaskbarIndeterminateState: + m_ptbl->SetProgressState(window->winId(), TBPF_INDETERMINATE); + break; + case WinSevenTaskbarErrorState: + m_ptbl->SetProgressState(window->winId(), TBPF_ERROR); + break; + case WinSevenTaskbarPausedState: + m_ptbl->SetProgressState(window->winId(), TBPF_PAUSED); + break; + } + } +} + +void WinSevenTaskbar::setTaskbarProgress(QWidget *window, unsigned __int64 currentValue, unsigned __int64 maximumValue) +{ + if(m_ptbl && window) + { + m_ptbl->SetProgressValue(window->winId(), currentValue, maximumValue); + } +} + +void WinSevenTaskbar::setOverlayIcon(QWidget *window, QIcon *icon) +{ + if(m_ptbl && window) + { + m_ptbl->SetOverlayIcon(window->winId(), (icon ? icon->pixmap(16,16).toWinHICON() : NULL), L"LameXP"); + } +} + +#endif //__ITaskbarList3_INTERFACE_DEFINED__ diff --git a/src/WinSevenTaskbar.h b/src/WinSevenTaskbar.h new file mode 100644 index 00000000..17415415 --- /dev/null +++ b/src/WinSevenTaskbar.h @@ -0,0 +1,84 @@ +/////////////////////////////////////////////////////////////////////////////// +// LameXP - Audio Encoder Front-End +// Copyright (C) 2004-2010 LoRd_MuldeR +// +// 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 +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// http://www.gnu.org/licenses/gpl-2.0.txt +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +class QWidget; +class QIcon; + +#ifdef __ITaskbarList3_INTERFACE_DEFINED__ + +class WinSevenTaskbar +{ +public: + WinSevenTaskbar(void); + ~WinSevenTaskbar(void); + + //Taskbar states + enum WinSevenTaskbarState + { + WinSevenTaskbarNoState = 0, + WinSevenTaskbarNormalState = 1, + WinSevenTaskbarIndeterminateState = 2, + WinSevenTaskbarPausedState = 3, + WinSevenTaskbarErrorState = 4 + }; + + //Public interface + static void initTaskbar(void); + static void setTaskbarState(QWidget *window, WinSevenTaskbarState state); + static void setTaskbarProgress(QWidget *window, unsigned __int64 currentValue, unsigned __int64 maximumValue); + static void setOverlayIcon(QWidget *window, QIcon *icon); + +private: + static ITaskbarList3 *m_ptbl; +}; + +#else //__ITaskbarList3_INTERFACE_DEFINED__ + +#pragma message("WARNING: ITaskbarList3 not defined. Compiling *without* support for Win7 taskbar!") + +class WinSevenTaskbar +{ +public: + WinSevenTaskbar(void); + ~WinSevenTaskbar(void); + + //Taskbar states + enum WinSevenTaskbarState + { + WinSevenTaskbarNoState = 0, + WinSevenTaskbarNormalState = 1, + WinSevenTaskbarIndeterminateState = 2, + WinSevenTaskbarPausedState = 3, + WinSevenTaskbarErrorState = 4 + }; + + //Public interface + static void initTaskbar(void) {} + static void setTaskbarState(QWidget *window, WinSevenTaskbarState state) {} + static void setTaskbarProgress(QWidget *window, unsigned __int64 currentValue, unsigned __int64 maximumValue) {} + static void setOverlayIcon(QWidget *window, QIcon *icon) {} +}; + +#endif //__ITaskbarList3_INTERFACE_DEFINED__