X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2FDialog_MainWindow.cpp;h=27469bedf67ddd476c48d4ab19f40bfb62042953;hb=3073ceb312f3cc290655d20c2c82791592205985;hp=02bd5931d6e8145d600a0a57e94b719e45bd3e4a;hpb=4d898010c0622161ab1bd435f19cf68e5c653253;p=lamexp%2FLameXP.git diff --git a/src/Dialog_MainWindow.cpp b/src/Dialog_MainWindow.cpp index 02bd5931..27469bed 100644 --- a/src/Dialog_MainWindow.cpp +++ b/src/Dialog_MainWindow.cpp @@ -1,12 +1,12 @@ /////////////////////////////////////////////////////////////////////////////// // LameXP - Audio Encoder Front-End -// Copyright (C) 2004-2015 LoRd_MuldeR +// Copyright (C) 2004-2020 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 +// 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, but always including the *additional* -// restrictions defined in the "License.txt" file. +// (at your option) any later version; always including the non-optional +// LAMEXP GNU GENERAL PUBLIC LICENSE ADDENDUM. See "License.txt" file! // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -40,6 +40,7 @@ #include "Model_Settings.h" #include "Model_FileList.h" #include "Model_FileSystem.h" +#include "Model_FileExts.h" #include "Registry_Encoder.h" #include "Registry_Decoder.h" #include "Encoder_Abstract.h" @@ -81,42 +82,24 @@ #include //////////////////////////////////////////////////////////// -// Helper macros +// Constants //////////////////////////////////////////////////////////// -#define BANNER_VISIBLE ((m_banner != NULL) && m_banner->isVisible()) - -#define INIT_BANNER() do \ -{ \ - if(m_banner == NULL) \ - { \ - m_banner = new WorkingBanner(this); \ - } \ -} \ -while(0) - -#define SHOW_BANNER(TXT) do \ -{ \ - INIT_BANNER(); \ - m_banner->show((TXT)); \ -} \ -while(0) +static const unsigned int IDM_ABOUTBOX = 0xEFF0; +static const char *g_hydrogen_audio_url = "http://wiki.hydrogenaud.io/index.php?title=Main_Page"; +static const char *g_documents_base_url = "http://lamexp.sourceforge.net/doc"; -#define SHOW_BANNER_ARG(TXT, ARG) do \ -{ \ - INIT_BANNER(); \ - m_banner->show((TXT), (ARG)); \ -} \ -while(0) +//////////////////////////////////////////////////////////// +// Helper Macros +//////////////////////////////////////////////////////////// +#define BANNER_VISIBLE ((!m_banner.isNull()) && m_banner->isVisible()) -#define SHOW_BANNER_CONDITIONALLY(FLAG, TEST, TXT) do \ +#define INIT_BANNER() do \ { \ - if((!(FLAG)) && ((TEST))) \ + if(m_banner.isNull()) \ { \ - INIT_BANNER(); \ - m_banner->show((TXT)); \ - FLAG = true; \ + m_banner.reset(new WorkingBanner(this)); \ } \ } \ while(0) @@ -131,97 +114,171 @@ while(0) } \ while(0) -#define SET_TEXT_COLOR(WIDGET, COLOR) do \ +#define PLAY_SOUND_OPTIONAL(NAME, ASYNC) do \ { \ - QPalette _palette = WIDGET->palette(); \ - _palette.setColor(QPalette::WindowText, (COLOR)); \ - _palette.setColor(QPalette::Text, (COLOR)); \ - WIDGET->setPalette(_palette); \ + if(m_settings->soundsEnabled()) MUtils::Sound::play_sound((NAME), (ASYNC)); \ } \ while(0) -#define SET_FONT_BOLD(WIDGET,BOLD) do \ +#define SHOW_CORNER_WIDGET(FLAG) do \ { \ - QFont _font = WIDGET->font(); \ - _font.setBold(BOLD); \ - WIDGET->setFont(_font); \ + if(QWidget *cornerWidget = ui->menubar->cornerWidget()) \ + { \ + cornerWidget->setVisible((FLAG)); \ + } \ } \ while(0) -#define TEMP_HIDE_DROPBOX(CMD) do \ -{ \ - bool _dropBoxVisible = m_dropBox->isVisible(); \ - if(_dropBoxVisible) m_dropBox->hide(); \ - do { CMD } while(0); \ - if(_dropBoxVisible) m_dropBox->show(); \ -} \ -while(0) +#define LINK(URL) \ + (QString("%2").arg(URL).arg(QString(URL).replace("-", "−"))) -#define SET_MODEL(VIEW, MODEL) do \ -{ \ - QItemSelectionModel *_tmp = (VIEW)->selectionModel(); \ - (VIEW)->setModel(MODEL); \ - MUTILS_DELETE(_tmp); \ -} \ -while(0) +#define LINK_EX(URL, NAME) \ + (QString("%2").arg(URL).arg(QString(NAME).replace("-", "−"))) -#define SET_CHECKBOX_STATE(CHCKBX, STATE) do \ -{ \ - if((CHCKBX)->isChecked() != (STATE)) \ - { \ - (CHCKBX)->click(); \ - } \ - if((CHCKBX)->isChecked() != (STATE)) \ - { \ - qWarning("Warning: Failed to set checkbox " #CHCKBX " state!"); \ - } \ -} \ -while(0) +#define FSLINK(PATH) \ + (QString("%2").arg(PATH).arg(QString(PATH).replace("-", "−"))) -#define TRIM_STRING_RIGHT(STR) do \ -{ \ - while((STR.length() > 0) && STR[STR.length()-1].isSpace()) STR.chop(1); \ -} \ -while(0) +#define CENTER_CURRENT_OUTPUT_FOLDER_DELAYED() \ + QTimer::singleShot(125, this, SLOT(centerOutputFolderModel())) -#define MAKE_TRANSPARENT(WIDGET, FLAG) do \ -{ \ - QPalette _p = (WIDGET)->palette(); \ - _p.setColor(QPalette::Background, Qt::transparent); \ - (WIDGET)->setPalette(FLAG ? _p : QPalette()); \ -} \ -while(0) +//////////////////////////////////////////////////////////// +// Static Functions +//////////////////////////////////////////////////////////// -#define WITH_BLOCKED_SIGNALS(WIDGET, CMD, ...) do \ -{ \ - const bool _flag = (WIDGET)->blockSignals(true); \ - (WIDGET)->CMD(__VA_ARGS__); \ - if(!(_flag)) { (WIDGET)->blockSignals(false); } \ -} \ -while(0) +static inline void SET_TEXT_COLOR(QWidget *const widget, const QColor &color) +{ + QPalette _palette = widget->palette(); + _palette.setColor(QPalette::WindowText, (color)); + _palette.setColor(QPalette::Text, (color)); + widget->setPalette(_palette); +} -#define PLAY_SOUND_OPTIONAL(NAME, ASYNC) do \ -{ \ - if(m_settings->soundsEnabled()) MUtils::Sound::play_sound((NAME), (ASYNC)); \ -} \ -while(0) +static inline void SET_FONT_BOLD(QWidget *const widget, const bool &bold) +{ + QFont _font = widget->font(); + _font.setBold(bold); + widget->setFont(_font); +} -#define SHOW_CORNER_WIDGET(FLAG) do \ -{ \ - if(QWidget *cornerWidget = ui->menubar->cornerWidget()) \ - { \ - cornerWidget->setVisible((FLAG)); \ - } \ -} \ -while(0) +static inline void SET_FONT_BOLD(QAction *const widget, const bool &bold) +{ + QFont _font = widget->font(); + _font.setBold(bold); + widget->setFont(_font); +} -#define LINK(URL) QString("%2").arg(URL).arg(QString(URL).replace("-", "−")) -#define FSLINK(PATH) QString("%2").arg(PATH).arg(QString(PATH).replace("-", "−")) -#define CENTER_CURRENT_OUTPUT_FOLDER_DELAYED QTimer::singleShot(125, this, SLOT(centerOutputFolderModel())) +static inline void SET_MODEL(QAbstractItemView *const view, QAbstractItemModel *const model) +{ + QItemSelectionModel *_tmp = view->selectionModel(); + view->setModel(model); + MUTILS_DELETE(_tmp); +} -static const unsigned int IDM_ABOUTBOX = 0xEFF0; -static const char *g_hydrogen_audio_url = "http://wiki.hydrogenaud.io/index.php?title=Main_Page"; -static const char *g_documents_base_url = "http://lamexp.sourceforge.net/doc"; +static inline void SET_CHECKBOX_STATE(QCheckBox *const chckbx, const bool &state) +{ + const bool isDisabled = (!chckbx->isEnabled()); + if(isDisabled) + { + chckbx->setEnabled(true); + } + if(chckbx->isChecked() != state) + { + chckbx->click(); + } + if(chckbx->isChecked() != state) + { + qWarning("Warning: Failed to set checkbox %p state!", chckbx); + } + if(isDisabled) + { + chckbx->setEnabled(false); + } +} + +static inline void TRIM_STRING_RIGHT(QString &str) +{ + while((str.length() > 0) && str[str.length()-1].isSpace()) + { + str.chop(1); + } +} + +static inline void MAKE_TRANSPARENT(QWidget *const widget, const bool &flag) +{ + QPalette _p = widget->palette(); \ + _p.setColor(QPalette::Background, Qt::transparent); + widget->setPalette(flag ? _p : QPalette()); +} + +template +static QList& INVERT_LIST(QList &list) +{ + if(!list.isEmpty()) + { + const int limit = list.size() / 2, maxIdx = list.size() - 1; + for(int k = 0; k < limit; k++) list.swap(k, maxIdx - k); + } + return list; +} + +static quint32 encodeInstances(quint32 instances) +{ + if (instances > 16U) + { + instances -= (instances - 16U) / 2U; + if (instances > 24U) + { + instances -= (instances - 24U) / 2U; + } + } + return instances; +} + +static quint32 decodeInstances(quint32 instances) +{ + if (instances > 16U) + { + instances += instances - 16U; + if (instances > 32U) + { + instances += instances - 32U; + } + } + return instances; +} + +//////////////////////////////////////////////////////////// +// Helper Classes +//////////////////////////////////////////////////////////// + +class WidgetHideHelper +{ +public: + WidgetHideHelper(QWidget *const widget) : m_widget(widget), m_visible(widget && widget->isVisible()) { if(m_widget && m_visible) m_widget->hide(); } + ~WidgetHideHelper(void) { if(m_widget && m_visible) m_widget->show(); } +private: + QWidget *const m_widget; + const bool m_visible; +}; + +class SignalBlockHelper +{ +public: + SignalBlockHelper(QObject *const object) : m_object(object), m_flag(object && object->blockSignals(true)) {} + ~SignalBlockHelper(void) { if(m_object && (!m_flag)) m_object->blockSignals(false); } +private: + QObject *const m_object; + const bool m_flag; +}; + +class FileListBlockHelper +{ +public: + FileListBlockHelper(FileListModel *const fileList) : m_fileList(fileList) { if(m_fileList) m_fileList->setBlockUpdates(true); } + ~FileListBlockHelper(void) { if(m_fileList) m_fileList->setBlockUpdates(false); } +private: + FileListModel *const m_fileList; +}; //////////////////////////////////////////////////////////// // Constructor @@ -234,8 +291,6 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons m_fileListModel(fileListModel), m_metaData(metaInfo), m_settings(settingsModel), - m_fileSystemModel(NULL), - m_banner(NULL), m_accepted(false), m_firstTimeShown(true), m_outputFolderViewCentering(false), @@ -244,6 +299,7 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons //Init the dialog, from the .ui file ui->setupUi(this); setWindowFlags(windowFlags() ^ Qt::WindowMaximizeButtonHint); + setMinimumSize(this->size()); //Create window icon MUtils::GUI::set_window_icon(this, lamexp_app_icon(), true); @@ -265,13 +321,13 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons //Setup corner widget QLabel *cornerWidget = new QLabel(ui->menubar); - m_evenFilterCornerWidget = new CustomEventFilter; + m_evenFilterCornerWidget.reset(new CustomEventFilter); cornerWidget->setText("N/A"); cornerWidget->setFixedHeight(ui->menubar->height()); cornerWidget->setCursor(QCursor(Qt::PointingHandCursor)); cornerWidget->hide(); - cornerWidget->installEventFilter(m_evenFilterCornerWidget); - connect(m_evenFilterCornerWidget, SIGNAL(eventOccurred(QWidget*, QEvent*)), this, SLOT(cornerWidgetEventOccurred(QWidget*, QEvent*))); + cornerWidget->installEventFilter(m_evenFilterCornerWidget.data()); + connect(m_evenFilterCornerWidget.data(), SIGNAL(eventOccurred(QWidget*, QEvent*)), this, SLOT(cornerWidgetEventOccurred(QWidget*, QEvent*))); ui->menubar->setCornerWidget(cornerWidget); //-------------------------------- @@ -279,21 +335,21 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons //-------------------------------- ui->sourceFileView->setModel(m_fileListModel); - ui->sourceFileView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents); + ui->sourceFileView->verticalHeader() ->setResizeMode(QHeaderView::ResizeToContents); ui->sourceFileView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents); ui->sourceFileView->setContextMenuPolicy(Qt::CustomContextMenu); ui->sourceFileView->viewport()->installEventFilter(this); - m_dropNoteLabel = new QLabel(ui->sourceFileView); + m_dropNoteLabel.reset(new QLabel(ui->sourceFileView)); m_dropNoteLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - SET_FONT_BOLD(m_dropNoteLabel, true); - SET_TEXT_COLOR(m_dropNoteLabel, Qt::darkGray); - m_sourceFilesContextMenu = new QMenu(); - m_showDetailsContextAction = m_sourceFilesContextMenu->addAction(QIcon(":/icons/zoom.png"), "N/A"); - m_previewContextAction = m_sourceFilesContextMenu->addAction(QIcon(":/icons/sound.png"), "N/A"); - m_findFileContextAction = m_sourceFilesContextMenu->addAction(QIcon(":/icons/folder_go.png"), "N/A"); + SET_FONT_BOLD(m_dropNoteLabel.data(), true); + SET_TEXT_COLOR(m_dropNoteLabel.data(), Qt::darkGray); + m_sourceFilesContextMenu.reset(new QMenu()); + m_showDetailsContextAction = m_sourceFilesContextMenu->addAction(QIcon(":/icons/zoom.png"), "N/A"); + m_previewContextAction = m_sourceFilesContextMenu->addAction(QIcon(":/icons/sound.png"), "N/A"); + m_findFileContextAction = m_sourceFilesContextMenu->addAction(QIcon(":/icons/folder_go.png"), "N/A"); m_sourceFilesContextMenu->addSeparator(); - m_exportCsvContextAction = m_sourceFilesContextMenu->addAction(QIcon(":/icons/table_save.png"), "N/A"); - m_importCsvContextAction = m_sourceFilesContextMenu->addAction(QIcon(":/icons/folder_table.png"), "N/A"); + m_exportCsvContextAction = m_sourceFilesContextMenu->addAction(QIcon(":/icons/table_save.png"), "N/A"); + m_importCsvContextAction = m_sourceFilesContextMenu->addAction(QIcon(":/icons/folder_table.png"), "N/A"); SET_FONT_BOLD(m_showDetailsContextAction, true); connect(ui->buttonAddFiles, SIGNAL(clicked()), this, SLOT(addFilesButtonClicked())); @@ -324,63 +380,56 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons ui->outputFolderView->setContextMenuPolicy(Qt::CustomContextMenu); ui->outputFolderView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - m_evenFilterOutputFolderMouse = new CustomEventFilter; - ui->outputFoldersGoUpLabel->installEventFilter(m_evenFilterOutputFolderMouse); - ui->outputFoldersEditorLabel->installEventFilter(m_evenFilterOutputFolderMouse); - ui->outputFoldersFovoritesLabel->installEventFilter(m_evenFilterOutputFolderMouse); - ui->outputFolderLabel->installEventFilter(m_evenFilterOutputFolderMouse); + m_evenFilterOutputFolderMouse.reset(new CustomEventFilter); + ui->outputFoldersGoUpLabel ->installEventFilter(m_evenFilterOutputFolderMouse.data()); + ui->outputFoldersEditorLabel ->installEventFilter(m_evenFilterOutputFolderMouse.data()); + ui->outputFoldersFovoritesLabel->installEventFilter(m_evenFilterOutputFolderMouse.data()); + ui->outputFolderLabel ->installEventFilter(m_evenFilterOutputFolderMouse.data()); - m_evenFilterOutputFolderView = new CustomEventFilter; - ui->outputFolderView->installEventFilter(m_evenFilterOutputFolderView); + m_evenFilterOutputFolderView.reset(new CustomEventFilter); + ui->outputFolderView->installEventFilter(m_evenFilterOutputFolderView.data()); SET_CHECKBOX_STATE(ui->saveToSourceFolderCheckBox, m_settings->outputToSourceDir()); ui->prependRelativePathCheckBox->setChecked(m_settings->prependRelativeSourcePath()); - connect(ui->outputFolderView, SIGNAL(clicked(QModelIndex)), this, SLOT(outputFolderViewClicked(QModelIndex))); - connect(ui->outputFolderView, SIGNAL(activated(QModelIndex)), this, SLOT(outputFolderViewClicked(QModelIndex))); - connect(ui->outputFolderView, SIGNAL(pressed(QModelIndex)), this, SLOT(outputFolderViewClicked(QModelIndex))); - connect(ui->outputFolderView, SIGNAL(entered(QModelIndex)), this, SLOT(outputFolderViewMoved(QModelIndex))); - connect(ui->outputFolderView, SIGNAL(expanded(QModelIndex)), this, SLOT(outputFolderItemExpanded(QModelIndex))); - connect(ui->buttonMakeFolder, SIGNAL(clicked()), this, SLOT(makeFolderButtonClicked())); - connect(ui->buttonGotoHome, SIGNAL(clicked()), SLOT(gotoHomeFolderButtonClicked())); - connect(ui->buttonGotoDesktop, SIGNAL(clicked()), this, SLOT(gotoDesktopButtonClicked())); - connect(ui->buttonGotoMusic, SIGNAL(clicked()), this, SLOT(gotoMusicFolderButtonClicked())); - connect(ui->saveToSourceFolderCheckBox, SIGNAL(clicked()), this, SLOT(saveToSourceFolderChanged())); - connect(ui->prependRelativePathCheckBox, SIGNAL(clicked()), this, SLOT(prependRelativePathChanged())); - connect(ui->outputFolderEdit, SIGNAL(editingFinished()), this, SLOT(outputFolderEditFinished())); - connect(m_evenFilterOutputFolderMouse, SIGNAL(eventOccurred(QWidget*, QEvent*)), this, SLOT(outputFolderMouseEventOccurred(QWidget*, QEvent*))); - connect(m_evenFilterOutputFolderView, SIGNAL(eventOccurred(QWidget*, QEvent*)), this, SLOT(outputFolderViewEventOccurred(QWidget*, QEvent*))); - - if(m_outputFolderContextMenu = new QMenu()) - { - m_showFolderContextAction = m_outputFolderContextMenu->addAction(QIcon(":/icons/zoom.png"), "N/A"); - m_goUpFolderContextAction = m_outputFolderContextMenu->addAction(QIcon(":/icons/folder_up.png"), "N/A"); - m_outputFolderContextMenu->addSeparator(); - m_refreshFolderContextAction = m_outputFolderContextMenu->addAction(QIcon(":/icons/arrow_refresh.png"), "N/A"); - m_outputFolderContextMenu->setDefaultAction(m_showFolderContextAction); - connect(ui->outputFolderView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(outputFolderContextMenu(QPoint))); - connect(m_showFolderContextAction, SIGNAL(triggered(bool)), this, SLOT(showFolderContextActionTriggered())); - connect(m_refreshFolderContextAction, SIGNAL(triggered(bool)), this, SLOT(refreshFolderContextActionTriggered())); - connect(m_goUpFolderContextAction, SIGNAL(triggered(bool)), this, SLOT(goUpFolderContextActionTriggered())); - } - - if(m_outputFolderFavoritesMenu = new QMenu()) - { - m_addFavoriteFolderAction = m_outputFolderFavoritesMenu->addAction(QIcon(":/icons/add.png"), "N/A"); - m_outputFolderFavoritesMenu->insertSeparator(m_addFavoriteFolderAction); - connect(m_addFavoriteFolderAction, SIGNAL(triggered(bool)), this, SLOT(addFavoriteFolderActionTriggered())); - } + connect(ui->outputFolderView, SIGNAL(clicked(QModelIndex)), this, SLOT(outputFolderViewClicked(QModelIndex))); + connect(ui->outputFolderView, SIGNAL(activated(QModelIndex)), this, SLOT(outputFolderViewClicked(QModelIndex))); + connect(ui->outputFolderView, SIGNAL(pressed(QModelIndex)), this, SLOT(outputFolderViewClicked(QModelIndex))); + connect(ui->outputFolderView, SIGNAL(entered(QModelIndex)), this, SLOT(outputFolderViewMoved(QModelIndex))); + connect(ui->outputFolderView, SIGNAL(expanded(QModelIndex)), this, SLOT(outputFolderItemExpanded(QModelIndex))); + connect(ui->buttonMakeFolder, SIGNAL(clicked()), this, SLOT(makeFolderButtonClicked())); + connect(ui->buttonGotoHome, SIGNAL(clicked()), this, SLOT(gotoHomeFolderButtonClicked())); + connect(ui->buttonGotoDesktop, SIGNAL(clicked()), this, SLOT(gotoDesktopButtonClicked())); + connect(ui->buttonGotoMusic, SIGNAL(clicked()), this, SLOT(gotoMusicFolderButtonClicked())); + connect(ui->saveToSourceFolderCheckBox, SIGNAL(clicked()), this, SLOT(saveToSourceFolderChanged())); + connect(ui->prependRelativePathCheckBox, SIGNAL(clicked()), this, SLOT(prependRelativePathChanged())); + connect(ui->outputFolderEdit, SIGNAL(editingFinished()), this, SLOT(outputFolderEditFinished())); + connect(m_evenFilterOutputFolderMouse.data(), SIGNAL(eventOccurred(QWidget*, QEvent*)), this, SLOT(outputFolderMouseEventOccurred(QWidget*, QEvent*))); + connect(m_evenFilterOutputFolderView.data(), SIGNAL(eventOccurred(QWidget*, QEvent*)), this, SLOT(outputFolderViewEventOccurred(QWidget*, QEvent*))); + + m_outputFolderContextMenu.reset(new QMenu()); + m_showFolderContextAction = m_outputFolderContextMenu->addAction(QIcon(":/icons/zoom.png"), "N/A"); + m_goUpFolderContextAction = m_outputFolderContextMenu->addAction(QIcon(":/icons/folder_up.png"), "N/A"); + m_outputFolderContextMenu->addSeparator(); + m_refreshFolderContextAction = m_outputFolderContextMenu->addAction(QIcon(":/icons/arrow_refresh.png"), "N/A"); + m_outputFolderContextMenu->setDefaultAction(m_showFolderContextAction); + connect(ui->outputFolderView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(outputFolderContextMenu(QPoint))); + connect(m_showFolderContextAction, SIGNAL(triggered(bool)), this, SLOT(showFolderContextActionTriggered())); + connect(m_refreshFolderContextAction, SIGNAL(triggered(bool)), this, SLOT(refreshFolderContextActionTriggered())); + connect(m_goUpFolderContextAction, SIGNAL(triggered(bool)), this, SLOT(goUpFolderContextActionTriggered())); + + m_outputFolderFavoritesMenu.reset(new QMenu()); + m_addFavoriteFolderAction = m_outputFolderFavoritesMenu->addAction(QIcon(":/icons/add.png"), "N/A"); + m_outputFolderFavoritesMenu->insertSeparator(m_addFavoriteFolderAction); + connect(m_addFavoriteFolderAction, SIGNAL(triggered(bool)), this, SLOT(addFavoriteFolderActionTriggered())); ui->outputFolderEdit->setVisible(false); - if(m_outputFolderNoteBox = new QLabel(ui->outputFolderView)) - { - m_outputFolderNoteBox->setAutoFillBackground(true); - m_outputFolderNoteBox->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - m_outputFolderNoteBox->setFrameShape(QFrame::StyledPanel); - SET_FONT_BOLD(m_outputFolderNoteBox, true); - m_outputFolderNoteBox->hide(); - - } + m_outputFolderNoteBox.reset(new QLabel(ui->outputFolderView)); + m_outputFolderNoteBox->setAutoFillBackground(true); + m_outputFolderNoteBox->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + m_outputFolderNoteBox->setFrameShape(QFrame::StyledPanel); + SET_FONT_BOLD(m_outputFolderNoteBox.data(), true); + m_outputFolderNoteBox->hide(); outputFolderViewClicked(QModelIndex()); refreshFavorites(); @@ -389,42 +438,42 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons // Setup "Meta Data" tab //-------------------------------- - m_metaInfoModel = new MetaInfoModel(m_metaData); + m_metaInfoModel.reset(new MetaInfoModel(m_metaData)); m_metaInfoModel->clearData(); m_metaInfoModel->setData(m_metaInfoModel->index(4, 1), m_settings->metaInfoPosition()); - ui->metaDataView->setModel(m_metaInfoModel); + ui->metaDataView->setModel(m_metaInfoModel.data()); ui->metaDataView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents); ui->metaDataView->verticalHeader()->hide(); ui->metaDataView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents); SET_CHECKBOX_STATE(ui->writeMetaDataCheckBox, m_settings->writeMetaTags()); ui->generatePlaylistCheckBox->setChecked(m_settings->createPlaylist()); - connect(ui->buttonEditMeta, SIGNAL(clicked()), this, SLOT(editMetaButtonClicked())); - connect(ui->buttonClearMeta, SIGNAL(clicked()), this, SLOT(clearMetaButtonClicked())); - connect(ui->writeMetaDataCheckBox, SIGNAL(clicked()), this, SLOT(metaTagsEnabledChanged())); + connect(ui->buttonEditMeta, SIGNAL(clicked()), this, SLOT(editMetaButtonClicked())); + connect(ui->buttonClearMeta, SIGNAL(clicked()), this, SLOT(clearMetaButtonClicked())); + connect(ui->writeMetaDataCheckBox, SIGNAL(clicked()), this, SLOT(metaTagsEnabledChanged())); connect(ui->generatePlaylistCheckBox, SIGNAL(clicked()), this, SLOT(playlistEnabledChanged())); //-------------------------------- //Setup "Compression" tab //-------------------------------- - m_encoderButtonGroup = new QButtonGroup(this); - m_encoderButtonGroup->addButton(ui->radioButtonEncoderMP3, SettingsModel::MP3Encoder); + m_encoderButtonGroup.reset(new QButtonGroup(this)); + m_encoderButtonGroup->addButton(ui->radioButtonEncoderMP3, SettingsModel::MP3Encoder); m_encoderButtonGroup->addButton(ui->radioButtonEncoderVorbis, SettingsModel::VorbisEncoder); - m_encoderButtonGroup->addButton(ui->radioButtonEncoderAAC, SettingsModel::AACEncoder); - m_encoderButtonGroup->addButton(ui->radioButtonEncoderAC3, SettingsModel::AC3Encoder); - m_encoderButtonGroup->addButton(ui->radioButtonEncoderFLAC, SettingsModel::FLACEncoder); - m_encoderButtonGroup->addButton(ui->radioButtonEncoderAPE, SettingsModel::MACEncoder); - m_encoderButtonGroup->addButton(ui->radioButtonEncoderOpus, SettingsModel::OpusEncoder); - m_encoderButtonGroup->addButton(ui->radioButtonEncoderDCA, SettingsModel::DCAEncoder); - m_encoderButtonGroup->addButton(ui->radioButtonEncoderPCM, SettingsModel::PCMEncoder); + m_encoderButtonGroup->addButton(ui->radioButtonEncoderAAC, SettingsModel::AACEncoder); + m_encoderButtonGroup->addButton(ui->radioButtonEncoderAC3, SettingsModel::AC3Encoder); + m_encoderButtonGroup->addButton(ui->radioButtonEncoderFLAC, SettingsModel::FLACEncoder); + m_encoderButtonGroup->addButton(ui->radioButtonEncoderAPE, SettingsModel::MACEncoder); + m_encoderButtonGroup->addButton(ui->radioButtonEncoderOpus, SettingsModel::OpusEncoder); + m_encoderButtonGroup->addButton(ui->radioButtonEncoderDCA, SettingsModel::DCAEncoder); + m_encoderButtonGroup->addButton(ui->radioButtonEncoderPCM, SettingsModel::PCMEncoder); const int aacEncoder = EncoderRegistry::getAacEncoder(); ui->radioButtonEncoderAAC->setEnabled(aacEncoder > SettingsModel::AAC_ENCODER_NONE); - m_modeButtonGroup = new QButtonGroup(this); - m_modeButtonGroup->addButton(ui->radioButtonModeQuality, SettingsModel::VBRMode); + m_modeButtonGroup.reset(new QButtonGroup(this)); + m_modeButtonGroup->addButton(ui->radioButtonModeQuality, SettingsModel::VBRMode); m_modeButtonGroup->addButton(ui->radioButtonModeAverageBitrate, SettingsModel::ABRMode); - m_modeButtonGroup->addButton(ui->radioButtonConstBitrate, SettingsModel::CBRMode); + m_modeButtonGroup->addButton(ui->radioButtonConstBitrate, SettingsModel::CBRMode); ui->radioButtonEncoderMP3->setChecked(true); foreach(QAbstractButton *currentButton, m_encoderButtonGroup->buttons()) @@ -436,14 +485,14 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons } } - m_evenFilterCompressionTab = new CustomEventFilter(); - ui->labelCompressionHelp->installEventFilter(m_evenFilterCompressionTab); - ui->labelResetEncoders ->installEventFilter(m_evenFilterCompressionTab); + m_evenFilterCompressionTab.reset(new CustomEventFilter()); + ui->labelCompressionHelp->installEventFilter(m_evenFilterCompressionTab.data()); + ui->labelResetEncoders ->installEventFilter(m_evenFilterCompressionTab.data()); - connect(m_encoderButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(updateEncoder(int))); - connect(m_modeButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(updateRCMode(int))); - connect(m_evenFilterCompressionTab, SIGNAL(eventOccurred(QWidget*, QEvent*)), this, SLOT(compressionTabEventOccurred(QWidget*, QEvent*))); - connect(ui->sliderBitrate, SIGNAL(valueChanged(int)), this, SLOT(updateBitrate(int))); + connect(m_encoderButtonGroup.data(), SIGNAL(buttonClicked(int)), this, SLOT(updateEncoder(int))); + connect(m_modeButtonGroup.data(), SIGNAL(buttonClicked(int)), this, SLOT(updateRCMode(int))); + connect(m_evenFilterCompressionTab.data(), SIGNAL(eventOccurred(QWidget*, QEvent*)), this, SLOT(compressionTabEventOccurred(QWidget*, QEvent*))); + connect(ui->sliderBitrate, SIGNAL(valueChanged(int)), this, SLOT(updateBitrate(int))); updateEncoder(m_encoderButtonGroup->checkedId()); @@ -452,53 +501,63 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons //-------------------------------- ui->sliderLameAlgoQuality->setValue(m_settings->lameAlgoQuality()); - if(m_settings->maximumInstances() > 0) ui->sliderMaxInstances->setValue(m_settings->maximumInstances()); - - ui->spinBoxBitrateManagementMin->setValue(m_settings->bitrateManagementMinRate()); - ui->spinBoxBitrateManagementMax->setValue(m_settings->bitrateManagementMaxRate()); - ui->spinBoxNormalizationFilter->setValue(static_cast(m_settings->normalizationFilterMaxVolume()) / 100.0); - ui->spinBoxToneAdjustBass->setValue(static_cast(m_settings->toneAdjustBass()) / 100.0); - ui->spinBoxToneAdjustTreble->setValue(static_cast(m_settings->toneAdjustTreble()) / 100.0); - ui->spinBoxAftenSearchSize->setValue(m_settings->aftenExponentSearchSize()); - ui->spinBoxOpusComplexity->setValue(m_settings->opusComplexity()); + if (m_settings->maximumInstances() > 0U) + { + ui->sliderMaxInstances->setValue(static_cast(encodeInstances(m_settings->maximumInstances()))); + } + + ui->spinBoxBitrateManagementMin ->setValue(m_settings->bitrateManagementMinRate()); + ui->spinBoxBitrateManagementMax ->setValue(m_settings->bitrateManagementMaxRate()); + ui->spinBoxNormalizationFilterPeak->setValue(static_cast(m_settings->normalizationFilterMaxVolume()) / 100.0); + ui->spinBoxNormalizationFilterSize->setValue(m_settings->normalizationFilterSize()); + ui->spinBoxToneAdjustBass ->setValue(static_cast(m_settings->toneAdjustBass()) / 100.0); + ui->spinBoxToneAdjustTreble ->setValue(static_cast(m_settings->toneAdjustTreble()) / 100.0); + ui->spinBoxAftenSearchSize ->setValue(m_settings->aftenExponentSearchSize()); + ui->spinBoxOpusComplexity ->setValue(m_settings->opusComplexity()); - ui->comboBoxMP3ChannelMode->setCurrentIndex(m_settings->lameChannelMode()); - ui->comboBoxSamplingRate->setCurrentIndex(m_settings->samplingRate()); - ui->comboBoxAACProfile->setCurrentIndex(m_settings->aacEncProfile()); - ui->comboBoxAftenCodingMode->setCurrentIndex(m_settings->aftenAudioCodingMode()); - ui->comboBoxAftenDRCMode->setCurrentIndex(m_settings->aftenDynamicRangeCompression()); - ui->comboBoxNormalizationMode->setCurrentIndex(m_settings->normalizationFilterEQMode()); - ui->comboBoxOpusFramesize->setCurrentIndex(m_settings->opusFramesize()); + ui->comboBoxMP3ChannelMode ->setCurrentIndex(m_settings->lameChannelMode()); + ui->comboBoxSamplingRate ->setCurrentIndex(m_settings->samplingRate()); + ui->comboBoxAACProfile ->setCurrentIndex(m_settings->aacEncProfile()); + ui->comboBoxAftenCodingMode ->setCurrentIndex(m_settings->aftenAudioCodingMode()); + ui->comboBoxAftenDRCMode ->setCurrentIndex(m_settings->aftenDynamicRangeCompression()); + ui->comboBoxOpusFramesize ->setCurrentIndex(m_settings->opusFramesize()); - SET_CHECKBOX_STATE(ui->checkBoxBitrateManagement, m_settings->bitrateManagementEnabled()); - SET_CHECKBOX_STATE(ui->checkBoxNeroAAC2PassMode, m_settings->neroAACEnable2Pass()); - SET_CHECKBOX_STATE(ui->checkBoxAftenFastAllocation, m_settings->aftenFastBitAllocation()); - SET_CHECKBOX_STATE(ui->checkBoxNormalizationFilter, m_settings->normalizationFilterEnabled()); - SET_CHECKBOX_STATE(ui->checkBoxAutoDetectInstances, (m_settings->maximumInstances() < 1)); - SET_CHECKBOX_STATE(ui->checkBoxUseSystemTempFolder, !m_settings->customTempPathEnabled()); - SET_CHECKBOX_STATE(ui->checkBoxRenameOutput, m_settings->renameOutputFilesEnabled()); - SET_CHECKBOX_STATE(ui->checkBoxForceStereoDownmix, m_settings->forceStereoDownmix()); - SET_CHECKBOX_STATE(ui->checkBoxOpusDisableResample, m_settings->opusDisableResample()); + SET_CHECKBOX_STATE(ui->checkBoxBitrateManagement, m_settings->bitrateManagementEnabled()); + SET_CHECKBOX_STATE(ui->checkBoxNeroAAC2PassMode, m_settings->neroAACEnable2Pass()); + SET_CHECKBOX_STATE(ui->checkBoxAftenFastAllocation, m_settings->aftenFastBitAllocation()); + SET_CHECKBOX_STATE(ui->checkBoxNormalizationFilterEnabled, m_settings->normalizationFilterEnabled()); + SET_CHECKBOX_STATE(ui->checkBoxNormalizationFilterDynamic, m_settings->normalizationFilterDynamic()); + SET_CHECKBOX_STATE(ui->checkBoxNormalizationFilterCoupled, m_settings->normalizationFilterCoupled()); + SET_CHECKBOX_STATE(ui->checkBoxAutoDetectInstances, (m_settings->maximumInstances() < 1)); + SET_CHECKBOX_STATE(ui->checkBoxUseSystemTempFolder, (!m_settings->customTempPathEnabled())); + SET_CHECKBOX_STATE(ui->checkBoxRename_Rename, m_settings->renameFiles_renameEnabled()); + SET_CHECKBOX_STATE(ui->checkBoxRename_RegExp, m_settings->renameFiles_regExpEnabled()); + SET_CHECKBOX_STATE(ui->checkBoxForceStereoDownmix, m_settings->forceStereoDownmix()); + SET_CHECKBOX_STATE(ui->checkBoxOpusDisableResample, m_settings->opusDisableResample()); + SET_CHECKBOX_STATE(ui->checkBoxKeepOriginalDateTime, m_settings->keepOriginalDataTime()); + ui->checkBoxNeroAAC2PassMode->setEnabled(aacEncoder == SettingsModel::AAC_ENCODER_NERO); - ui->lineEditCustomParamLAME ->setText(EncoderRegistry::loadEncoderCustomParams(m_settings, SettingsModel::MP3Encoder)); - ui->lineEditCustomParamOggEnc ->setText(EncoderRegistry::loadEncoderCustomParams(m_settings, SettingsModel::VorbisEncoder)); - ui->lineEditCustomParamNeroAAC->setText(EncoderRegistry::loadEncoderCustomParams(m_settings, SettingsModel::AACEncoder)); - ui->lineEditCustomParamFLAC ->setText(EncoderRegistry::loadEncoderCustomParams(m_settings, SettingsModel::FLACEncoder)); - ui->lineEditCustomParamAften ->setText(EncoderRegistry::loadEncoderCustomParams(m_settings, SettingsModel::AC3Encoder)); - ui->lineEditCustomParamOpus ->setText(EncoderRegistry::loadEncoderCustomParams(m_settings, SettingsModel::OpusEncoder)); - ui->lineEditCustomTempFolder ->setText(QDir::toNativeSeparators(m_settings->customTempPath())); - ui->lineEditRenamePattern ->setText(m_settings->renameOutputFilesPattern()); + ui->lineEditCustomParamLAME ->setText(EncoderRegistry::loadEncoderCustomParams(m_settings, SettingsModel::MP3Encoder)); + ui->lineEditCustomParamOggEnc ->setText(EncoderRegistry::loadEncoderCustomParams(m_settings, SettingsModel::VorbisEncoder)); + ui->lineEditCustomParamNeroAAC ->setText(EncoderRegistry::loadEncoderCustomParams(m_settings, SettingsModel::AACEncoder)); + ui->lineEditCustomParamFLAC ->setText(EncoderRegistry::loadEncoderCustomParams(m_settings, SettingsModel::FLACEncoder)); + ui->lineEditCustomParamAften ->setText(EncoderRegistry::loadEncoderCustomParams(m_settings, SettingsModel::AC3Encoder)); + ui->lineEditCustomParamOpus ->setText(EncoderRegistry::loadEncoderCustomParams(m_settings, SettingsModel::OpusEncoder)); + ui->lineEditCustomTempFolder ->setText(QDir::toNativeSeparators(m_settings->customTempPath())); + ui->lineEditRenamePattern ->setText(m_settings->renameFiles_renamePattern()); + ui->lineEditRenameRegExp_Search ->setText(m_settings->renameFiles_regExpSearch ()); + ui->lineEditRenameRegExp_Replace->setText(m_settings->renameFiles_regExpReplace()); - m_evenFilterCustumParamsHelp = new CustomEventFilter(); - ui->helpCustomParamLAME->installEventFilter(m_evenFilterCustumParamsHelp); - ui->helpCustomParamOggEnc->installEventFilter(m_evenFilterCustumParamsHelp); - ui->helpCustomParamNeroAAC->installEventFilter(m_evenFilterCustumParamsHelp); - ui->helpCustomParamFLAC->installEventFilter(m_evenFilterCustumParamsHelp); - ui->helpCustomParamAften->installEventFilter(m_evenFilterCustumParamsHelp); - ui->helpCustomParamOpus->installEventFilter(m_evenFilterCustumParamsHelp); + m_evenFilterCustumParamsHelp.reset(new CustomEventFilter()); + ui->helpCustomParamLAME ->installEventFilter(m_evenFilterCustumParamsHelp.data()); + ui->helpCustomParamOggEnc ->installEventFilter(m_evenFilterCustumParamsHelp.data()); + ui->helpCustomParamNeroAAC->installEventFilter(m_evenFilterCustumParamsHelp.data()); + ui->helpCustomParamFLAC ->installEventFilter(m_evenFilterCustumParamsHelp.data()); + ui->helpCustomParamAften ->installEventFilter(m_evenFilterCustumParamsHelp.data()); + ui->helpCustomParamOpus ->installEventFilter(m_evenFilterCustumParamsHelp.data()); - m_overwriteButtonGroup = new QButtonGroup(this); + m_overwriteButtonGroup.reset(new QButtonGroup(this)); m_overwriteButtonGroup->addButton(ui->radioButtonOverwriteModeKeepBoth, SettingsModel::Overwrite_KeepBoth); m_overwriteButtonGroup->addButton(ui->radioButtonOverwriteModeSkipFile, SettingsModel::Overwrite_SkipFile); m_overwriteButtonGroup->addButton(ui->radioButtonOverwriteModeReplaces, SettingsModel::Overwrite_Replaces); @@ -507,46 +566,68 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons ui->radioButtonOverwriteModeSkipFile->setChecked(m_settings->overwriteMode() == SettingsModel::Overwrite_SkipFile); ui->radioButtonOverwriteModeReplaces->setChecked(m_settings->overwriteMode() == SettingsModel::Overwrite_Replaces); - connect(ui->sliderLameAlgoQuality, SIGNAL(valueChanged(int)), this, SLOT(updateLameAlgoQuality(int))); - connect(ui->checkBoxBitrateManagement, SIGNAL(clicked(bool)), this, SLOT(bitrateManagementEnabledChanged(bool))); - connect(ui->spinBoxBitrateManagementMin, SIGNAL(valueChanged(int)), this, SLOT(bitrateManagementMinChanged(int))); - connect(ui->spinBoxBitrateManagementMax, SIGNAL(valueChanged(int)), this, SLOT(bitrateManagementMaxChanged(int))); - connect(ui->comboBoxMP3ChannelMode, SIGNAL(currentIndexChanged(int)), this, SLOT(channelModeChanged(int))); - connect(ui->comboBoxSamplingRate, SIGNAL(currentIndexChanged(int)), this, SLOT(samplingRateChanged(int))); - connect(ui->checkBoxNeroAAC2PassMode, SIGNAL(clicked(bool)), this, SLOT(neroAAC2PassChanged(bool))); - connect(ui->comboBoxAACProfile, SIGNAL(currentIndexChanged(int)), this, SLOT(neroAACProfileChanged(int))); - connect(ui->checkBoxNormalizationFilter, SIGNAL(clicked(bool)), this, SLOT(normalizationEnabledChanged(bool))); - connect(ui->comboBoxAftenCodingMode, SIGNAL(currentIndexChanged(int)), this, SLOT(aftenCodingModeChanged(int))); - connect(ui->comboBoxAftenDRCMode, SIGNAL(currentIndexChanged(int)), this, SLOT(aftenDRCModeChanged(int))); - connect(ui->spinBoxAftenSearchSize, SIGNAL(valueChanged(int)), this, SLOT(aftenSearchSizeChanged(int))); - connect(ui->checkBoxAftenFastAllocation, SIGNAL(clicked(bool)), this, SLOT(aftenFastAllocationChanged(bool))); - connect(ui->spinBoxNormalizationFilter, SIGNAL(valueChanged(double)), this, SLOT(normalizationMaxVolumeChanged(double))); - connect(ui->comboBoxNormalizationMode, SIGNAL(currentIndexChanged(int)), this, SLOT(normalizationModeChanged(int))); - connect(ui->spinBoxToneAdjustBass, SIGNAL(valueChanged(double)), this, SLOT(toneAdjustBassChanged(double))); - connect(ui->spinBoxToneAdjustTreble, SIGNAL(valueChanged(double)), this, SLOT(toneAdjustTrebleChanged(double))); - connect(ui->buttonToneAdjustReset, SIGNAL(clicked()), this, SLOT(toneAdjustTrebleReset())); - connect(ui->lineEditCustomParamLAME, SIGNAL(editingFinished()), this, SLOT(customParamsChanged())); - connect(ui->lineEditCustomParamOggEnc, SIGNAL(editingFinished()), this, SLOT(customParamsChanged())); - connect(ui->lineEditCustomParamNeroAAC, SIGNAL(editingFinished()), this, SLOT(customParamsChanged())); - connect(ui->lineEditCustomParamFLAC, SIGNAL(editingFinished()), this, SLOT(customParamsChanged())); - connect(ui->lineEditCustomParamAften, SIGNAL(editingFinished()), this, SLOT(customParamsChanged())); - connect(ui->lineEditCustomParamOpus, SIGNAL(editingFinished()), this, SLOT(customParamsChanged())); - connect(ui->sliderMaxInstances, SIGNAL(valueChanged(int)), this, SLOT(updateMaximumInstances(int))); - connect(ui->checkBoxAutoDetectInstances, SIGNAL(clicked(bool)), this, SLOT(autoDetectInstancesChanged(bool))); - connect(ui->buttonBrowseCustomTempFolder, SIGNAL(clicked()), this, SLOT(browseCustomTempFolderButtonClicked())); - connect(ui->lineEditCustomTempFolder, SIGNAL(textChanged(QString)), this, SLOT(customTempFolderChanged(QString))); - connect(ui->checkBoxUseSystemTempFolder, SIGNAL(clicked(bool)), this, SLOT(useCustomTempFolderChanged(bool))); - connect(ui->buttonResetAdvancedOptions, SIGNAL(clicked()), this, SLOT(resetAdvancedOptionsButtonClicked())); - connect(ui->checkBoxRenameOutput, SIGNAL(clicked(bool)), this, SLOT(renameOutputEnabledChanged(bool))); - connect(ui->lineEditRenamePattern, SIGNAL(editingFinished()), this, SLOT(renameOutputPatternChanged())); - connect(ui->lineEditRenamePattern, SIGNAL(textChanged(QString)), this, SLOT(renameOutputPatternChanged(QString))); - connect(ui->labelShowRenameMacros, SIGNAL(linkActivated(QString)), this, SLOT(showRenameMacros(QString))); - connect(ui->checkBoxForceStereoDownmix, SIGNAL(clicked(bool)), this, SLOT(forceStereoDownmixEnabledChanged(bool))); - connect(ui->comboBoxOpusFramesize, SIGNAL(currentIndexChanged(int)), this, SLOT(opusSettingsChanged())); - connect(ui->spinBoxOpusComplexity, SIGNAL(valueChanged(int)), this, SLOT(opusSettingsChanged())); - connect(ui->checkBoxOpusDisableResample, SIGNAL(clicked(bool)), SLOT(opusSettingsChanged())); - connect(m_overwriteButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(overwriteModeChanged(int))); - connect(m_evenFilterCustumParamsHelp, SIGNAL(eventOccurred(QWidget*, QEvent*)), this, SLOT(customParamsHelpRequested(QWidget*, QEvent*))); + FileExtsModel *fileExtModel = new FileExtsModel(this); + fileExtModel->importItems(m_settings->renameFiles_fileExtension()); + ui->tableViewFileExts->setModel(fileExtModel); + ui->tableViewFileExts->verticalHeader() ->setResizeMode(QHeaderView::ResizeToContents); + ui->tableViewFileExts->horizontalHeader()->setResizeMode(QHeaderView::Stretch); + + connect(ui->sliderLameAlgoQuality, SIGNAL(valueChanged(int)), this, SLOT(updateLameAlgoQuality(int))); + connect(ui->checkBoxBitrateManagement, SIGNAL(clicked(bool)), this, SLOT(bitrateManagementEnabledChanged(bool))); + connect(ui->spinBoxBitrateManagementMin, SIGNAL(valueChanged(int)), this, SLOT(bitrateManagementMinChanged(int))); + connect(ui->spinBoxBitrateManagementMax, SIGNAL(valueChanged(int)), this, SLOT(bitrateManagementMaxChanged(int))); + connect(ui->comboBoxMP3ChannelMode, SIGNAL(currentIndexChanged(int)), this, SLOT(channelModeChanged(int))); + connect(ui->comboBoxSamplingRate, SIGNAL(currentIndexChanged(int)), this, SLOT(samplingRateChanged(int))); + connect(ui->checkBoxNeroAAC2PassMode, SIGNAL(clicked(bool)), this, SLOT(neroAAC2PassChanged(bool))); + connect(ui->comboBoxAACProfile, SIGNAL(currentIndexChanged(int)), this, SLOT(neroAACProfileChanged(int))); + connect(ui->checkBoxNormalizationFilterEnabled, SIGNAL(clicked(bool)), this, SLOT(normalizationEnabledChanged(bool))); + connect(ui->checkBoxNormalizationFilterDynamic, SIGNAL(clicked(bool)), this, SLOT(normalizationDynamicChanged(bool))); + connect(ui->checkBoxNormalizationFilterCoupled, SIGNAL(clicked(bool)), this, SLOT(normalizationCoupledChanged(bool))); + connect(ui->comboBoxAftenCodingMode, SIGNAL(currentIndexChanged(int)), this, SLOT(aftenCodingModeChanged(int))); + connect(ui->comboBoxAftenDRCMode, SIGNAL(currentIndexChanged(int)), this, SLOT(aftenDRCModeChanged(int))); + connect(ui->spinBoxAftenSearchSize, SIGNAL(valueChanged(int)), this, SLOT(aftenSearchSizeChanged(int))); + connect(ui->checkBoxAftenFastAllocation, SIGNAL(clicked(bool)), this, SLOT(aftenFastAllocationChanged(bool))); + connect(ui->spinBoxNormalizationFilterPeak, SIGNAL(valueChanged(double)), this, SLOT(normalizationMaxVolumeChanged(double))); + connect(ui->spinBoxNormalizationFilterSize, SIGNAL(valueChanged(int)), this, SLOT(normalizationFilterSizeChanged(int))); + connect(ui->spinBoxNormalizationFilterSize, SIGNAL(editingFinished()), this, SLOT(normalizationFilterSizeFinished())); + connect(ui->spinBoxToneAdjustBass, SIGNAL(valueChanged(double)), this, SLOT(toneAdjustBassChanged(double))); + connect(ui->spinBoxToneAdjustTreble, SIGNAL(valueChanged(double)), this, SLOT(toneAdjustTrebleChanged(double))); + connect(ui->buttonToneAdjustReset, SIGNAL(clicked()), this, SLOT(toneAdjustTrebleReset())); + connect(ui->lineEditCustomParamLAME, SIGNAL(editingFinished()), this, SLOT(customParamsChanged())); + connect(ui->lineEditCustomParamOggEnc, SIGNAL(editingFinished()), this, SLOT(customParamsChanged())); + connect(ui->lineEditCustomParamNeroAAC, SIGNAL(editingFinished()), this, SLOT(customParamsChanged())); + connect(ui->lineEditCustomParamFLAC, SIGNAL(editingFinished()), this, SLOT(customParamsChanged())); + connect(ui->lineEditCustomParamAften, SIGNAL(editingFinished()), this, SLOT(customParamsChanged())); + connect(ui->lineEditCustomParamOpus, SIGNAL(editingFinished()), this, SLOT(customParamsChanged())); + connect(ui->sliderMaxInstances, SIGNAL(valueChanged(int)), this, SLOT(updateMaximumInstances(int))); + connect(ui->checkBoxAutoDetectInstances, SIGNAL(clicked(bool)), this, SLOT(autoDetectInstancesChanged(bool))); + connect(ui->buttonBrowseCustomTempFolder, SIGNAL(clicked()), this, SLOT(browseCustomTempFolderButtonClicked())); + connect(ui->lineEditCustomTempFolder, SIGNAL(textChanged(QString)), this, SLOT(customTempFolderChanged(QString))); + connect(ui->checkBoxUseSystemTempFolder, SIGNAL(clicked(bool)), this, SLOT(useCustomTempFolderChanged(bool))); + connect(ui->buttonResetAdvancedOptions, SIGNAL(clicked()), this, SLOT(resetAdvancedOptionsButtonClicked())); + connect(ui->checkBoxRename_Rename, SIGNAL(clicked(bool)), this, SLOT(renameOutputEnabledChanged(bool))); + connect(ui->checkBoxRename_RegExp, SIGNAL(clicked(bool)), this, SLOT(renameRegExpEnabledChanged(bool))); + connect(ui->lineEditRenamePattern, SIGNAL(editingFinished()), this, SLOT(renameOutputPatternChanged())); + connect(ui->lineEditRenamePattern, SIGNAL(textChanged(QString)), this, SLOT(renameOutputPatternChanged(QString))); + connect(ui->lineEditRenameRegExp_Search, SIGNAL(editingFinished()), this, SLOT(renameRegExpValueChanged())); + connect(ui->lineEditRenameRegExp_Search, SIGNAL(textChanged(QString)), this, SLOT(renameRegExpSearchChanged(QString))); + connect(ui->lineEditRenameRegExp_Replace, SIGNAL(editingFinished()), this, SLOT(renameRegExpValueChanged())); + connect(ui->lineEditRenameRegExp_Replace, SIGNAL(textChanged(QString)), this, SLOT(renameRegExpReplaceChanged(QString))); + connect(ui->labelShowRenameMacros, SIGNAL(linkActivated(QString)), this, SLOT(showRenameMacros(QString))); + connect(ui->labelShowRegExpHelp, SIGNAL(linkActivated(QString)), this, SLOT(showRenameMacros(QString))); + connect(ui->checkBoxForceStereoDownmix, SIGNAL(clicked(bool)), this, SLOT(forceStereoDownmixEnabledChanged(bool))); + connect(ui->comboBoxOpusFramesize, SIGNAL(currentIndexChanged(int)), this, SLOT(opusSettingsChanged())); + connect(ui->spinBoxOpusComplexity, SIGNAL(valueChanged(int)), this, SLOT(opusSettingsChanged())); + connect(ui->checkBoxOpusDisableResample, SIGNAL(clicked(bool)), this, SLOT(opusSettingsChanged())); + connect(ui->buttonRename_Rename, SIGNAL(clicked(bool)), this, SLOT(renameButtonClicked(bool))); + connect(ui->buttonRename_RegExp, SIGNAL(clicked(bool)), this, SLOT(renameButtonClicked(bool))); + connect(ui->buttonRename_FileEx, SIGNAL(clicked(bool)), this, SLOT(renameButtonClicked(bool))); + connect(ui->buttonFileExts_Add, SIGNAL(clicked()), this, SLOT(fileExtAddButtonClicked())); + connect(ui->buttonFileExts_Remove, SIGNAL(clicked()), this, SLOT(fileExtRemoveButtonClicked())); + connect(ui->checkBoxKeepOriginalDateTime, SIGNAL(clicked(bool)), this, SLOT(keepOriginalDateTimeChanged(bool))); + connect(m_overwriteButtonGroup.data(), SIGNAL(buttonClicked(int)), this, SLOT(overwriteModeChanged(int))); + connect(m_evenFilterCustumParamsHelp.data(), SIGNAL(eventOccurred(QWidget*, QEvent*)), this, SLOT(customParamsHelpRequested(QWidget*, QEvent*))); + connect(fileExtModel, SIGNAL(modelReset()), this, SLOT(fileExtModelChanged())); //-------------------------------- // Force initial GUI update @@ -556,6 +637,7 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons updateMaximumInstances(ui->sliderMaxInstances->value()); toneAdjustTrebleChanged(ui->spinBoxToneAdjustTreble->value()); toneAdjustBassChanged(ui->spinBoxToneAdjustBass->value()); + normalizationEnabledChanged(ui->checkBoxNormalizationFilterEnabled->isChecked()); customParamsChanged(); //-------------------------------- @@ -563,13 +645,13 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons //-------------------------------- //Activate file menu actions - ui->actionOpenFolder->setData(QVariant::fromValue(false)); + ui->actionOpenFolder ->setData(QVariant::fromValue(false)); ui->actionOpenFolderRecursively->setData(QVariant::fromValue(true)); - connect(ui->actionOpenFolder, SIGNAL(triggered()), this, SLOT(openFolderActionActivated())); + connect(ui->actionOpenFolder, SIGNAL(triggered()), this, SLOT(openFolderActionActivated())); connect(ui->actionOpenFolderRecursively, SIGNAL(triggered()), this, SLOT(openFolderActionActivated())); //Activate view menu actions - m_tabActionGroup = new QActionGroup(this); + m_tabActionGroup.reset(new QActionGroup(this)); m_tabActionGroup->addAction(ui->actionSourceFiles); m_tabActionGroup->addAction(ui->actionOutputDirectory); m_tabActionGroup->addAction(ui->actionCompression); @@ -581,10 +663,10 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons ui->actionCompression->setData(3); ui->actionAdvancedOptions->setData(4); ui->actionSourceFiles->setChecked(true); - connect(m_tabActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(tabActionActivated(QAction*))); + connect(m_tabActionGroup.data(), SIGNAL(triggered(QAction*)), this, SLOT(tabActionActivated(QAction*))); //Activate style menu actions - m_styleActionGroup = new QActionGroup(this); + m_styleActionGroup .reset(new QActionGroup(this)); m_styleActionGroup->addAction(ui->actionStylePlastique); m_styleActionGroup->addAction(ui->actionStyleCleanlooks); m_styleActionGroup->addAction(ui->actionStyleWindowsVista); @@ -598,11 +680,11 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons ui->actionStylePlastique->setChecked(true); ui->actionStyleWindowsXP->setEnabled((QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) >= QSysInfo::WV_XP && MUtils::GUI::themes_enabled()); ui->actionStyleWindowsVista->setEnabled((QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) >= QSysInfo::WV_VISTA && MUtils::GUI::themes_enabled()); - connect(m_styleActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(styleActionActivated(QAction*))); + connect(m_styleActionGroup.data(), SIGNAL(triggered(QAction*)), this, SLOT(styleActionActivated(QAction*))); styleActionActivated(NULL); //Populate the language menu - m_languageActionGroup = new QActionGroup(this); + m_languageActionGroup.reset(new QActionGroup(this)); QStringList translations; if(MUtils::Translation::enumerate(translations) > 0) { @@ -619,8 +701,8 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons } } ui->menuLanguage->insertSeparator(ui->actionLoadTranslationFromFile); - connect(ui->actionLoadTranslationFromFile, SIGNAL(triggered(bool)), this, SLOT(languageFromFileActionActivated(bool))); - connect(m_languageActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(languageActionActivated(QAction*))); + connect(ui->actionLoadTranslationFromFile, SIGNAL(triggered(bool)), this, SLOT(languageFromFileActionActivated(bool))); + connect(m_languageActionGroup.data(), SIGNAL(triggered(QAction*)), this, SLOT(languageActionActivated(QAction*))); ui->actionLoadTranslationFromFile->setChecked(false); //Activate tools menu actions @@ -667,33 +749,30 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons // Prepare to show window //-------------------------------- - //Center window in screen - QRect desktopRect = QApplication::desktop()->screenGeometry(); - QRect thisRect = this->geometry(); - move((desktopRect.width() - thisRect.width()) / 2, (desktopRect.height() - thisRect.height()) / 2); - setMinimumSize(thisRect.width(), thisRect.height()); - + //Adjust size to DPI settings and re-center + MUtils::GUI::scale_widget(this); + //Create DropBox widget - m_dropBox = new DropBox(this, m_fileListModel, m_settings); - connect(m_fileListModel, SIGNAL(modelReset()), m_dropBox, SLOT(modelChanged())); - connect(m_fileListModel, SIGNAL(rowsInserted(QModelIndex,int,int)), m_dropBox, SLOT(modelChanged())); - connect(m_fileListModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), m_dropBox, SLOT(modelChanged())); - connect(m_fileListModel, SIGNAL(rowAppended()), m_dropBox, SLOT(modelChanged())); + m_dropBox.reset(new DropBox(this, m_fileListModel, m_settings)); + connect(m_fileListModel, SIGNAL(modelReset()), m_dropBox.data(), SLOT(modelChanged())); + connect(m_fileListModel, SIGNAL(rowsInserted(QModelIndex,int,int)), m_dropBox.data(), SLOT(modelChanged())); + connect(m_fileListModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), m_dropBox.data(), SLOT(modelChanged())); + connect(m_fileListModel, SIGNAL(rowAppended()), m_dropBox.data(), SLOT(modelChanged())); //Create message handler thread - m_messageHandler = new MessageHandlerThread(ipcChannel); - connect(m_messageHandler, SIGNAL(otherInstanceDetected()), this, SLOT(notifyOtherInstance()), Qt::QueuedConnection); - connect(m_messageHandler, SIGNAL(fileReceived(QString)), this, SLOT(addFileDelayed(QString)), Qt::QueuedConnection); - connect(m_messageHandler, SIGNAL(folderReceived(QString, bool)), this, SLOT(addFolderDelayed(QString, bool)), Qt::QueuedConnection); - connect(m_messageHandler, SIGNAL(killSignalReceived()), this, SLOT(close()), Qt::QueuedConnection); + m_messageHandler.reset(new MessageHandlerThread(ipcChannel)); + connect(m_messageHandler.data(), SIGNAL(otherInstanceDetected()), this, SLOT(notifyOtherInstance()), Qt::QueuedConnection); + connect(m_messageHandler.data(), SIGNAL(fileReceived(QString)), this, SLOT(addFileDelayed(QString)), Qt::QueuedConnection); + connect(m_messageHandler.data(), SIGNAL(folderReceived(QString, bool)), this, SLOT(addFolderDelayed(QString, bool)), Qt::QueuedConnection); + connect(m_messageHandler.data(), SIGNAL(killSignalReceived()), this, SLOT(close()), Qt::QueuedConnection); m_messageHandler->start(); //Init delayed file handling - m_delayedFileList = new QStringList(); - m_delayedFileTimer = new QTimer(); + m_delayedFileList .reset(new QStringList()); + m_delayedFileTimer.reset(new QTimer()); m_delayedFileTimer->setSingleShot(true); m_delayedFileTimer->setInterval(5000); - connect(m_delayedFileTimer, SIGNAL(timeout()), this, SLOT(handleDelayedFiles())); + connect(m_delayedFileTimer.data(), SIGNAL(timeout()), this, SLOT(handleDelayedFiles())); //Load translation initializeTranslation(); @@ -703,7 +782,7 @@ MainWindow::MainWindow(MUtils::IPCChannel *const ipcChannel, FileListModel *cons changeEvent(&languageChangeEvent); //Enable Drag & Drop - m_droppedFileList = new QList(); + m_droppedFileList.reset(new QList()); this->setAcceptDrops(true); } @@ -725,33 +804,9 @@ MainWindow::~MainWindow(void) } //Unset models - SET_MODEL(ui->sourceFileView, NULL); + SET_MODEL(ui->sourceFileView, NULL); SET_MODEL(ui->outputFolderView, NULL); - SET_MODEL(ui->metaDataView, NULL); - - //Free memory - MUTILS_DELETE(m_tabActionGroup); - MUTILS_DELETE(m_styleActionGroup); - MUTILS_DELETE(m_languageActionGroup); - MUTILS_DELETE(m_banner); - MUTILS_DELETE(m_fileSystemModel); - MUTILS_DELETE(m_messageHandler); - MUTILS_DELETE(m_droppedFileList); - MUTILS_DELETE(m_delayedFileList); - MUTILS_DELETE(m_delayedFileTimer); - MUTILS_DELETE(m_metaInfoModel); - MUTILS_DELETE(m_encoderButtonGroup); - MUTILS_DELETE(m_modeButtonGroup); - MUTILS_DELETE(m_overwriteButtonGroup); - MUTILS_DELETE(m_sourceFilesContextMenu); - MUTILS_DELETE(m_outputFolderFavoritesMenu); - MUTILS_DELETE(m_outputFolderContextMenu); - MUTILS_DELETE(m_dropBox); - MUTILS_DELETE(m_evenFilterCornerWidget); - MUTILS_DELETE(m_evenFilterCustumParamsHelp); - MUTILS_DELETE(m_evenFilterOutputFolderMouse); - MUTILS_DELETE(m_evenFilterOutputFolderView); - MUTILS_DELETE(m_evenFilterCompressionTab); + SET_MODEL(ui->metaDataView, NULL); //Un-initialize the dialog MUTILS_DELETE(ui); @@ -771,30 +826,28 @@ void MainWindow::addFiles(const QStringList &files) return; } - WITH_BLOCKED_SIGNALS(ui->tabWidget, setCurrentIndex, 0); - tabPageChanged(ui->tabWidget->currentIndex(), true); + if(ui->tabWidget->currentIndex() != 0) + { + SignalBlockHelper signalBlockHelper(ui->tabWidget); + ui->tabWidget->setCurrentIndex(0); + tabPageChanged(ui->tabWidget->currentIndex(), true); + } INIT_BANNER(); - FileAnalyzer *analyzer = new FileAnalyzer(files); + QScopedPointer analyzer(new FileAnalyzer(files)); - connect(analyzer, SIGNAL(fileSelected(QString)), m_banner, SLOT(setText(QString)), Qt::QueuedConnection); - connect(analyzer, SIGNAL(progressValChanged(unsigned int)), m_banner, SLOT(setProgressVal(unsigned int)), Qt::QueuedConnection); - connect(analyzer, SIGNAL(progressMaxChanged(unsigned int)), m_banner, SLOT(setProgressMax(unsigned int)), Qt::QueuedConnection); - connect(analyzer, SIGNAL(fileAnalyzed(AudioFileModel)), m_fileListModel, SLOT(addFile(AudioFileModel)), Qt::QueuedConnection); - connect(m_banner, SIGNAL(userAbort()), analyzer, SLOT(abortProcess()), Qt::DirectConnection); + connect(analyzer.data(), SIGNAL(fileSelected(QString)), m_banner.data(), SLOT(setText(QString)), Qt::QueuedConnection); + connect(analyzer.data(), SIGNAL(progressValChanged(unsigned int)), m_banner.data(), SLOT(setProgressVal(unsigned int)), Qt::QueuedConnection); + connect(analyzer.data(), SIGNAL(progressMaxChanged(unsigned int)), m_banner.data(), SLOT(setProgressMax(unsigned int)), Qt::QueuedConnection); + connect(analyzer.data(), SIGNAL(fileAnalyzed(AudioFileModel)), m_fileListModel, SLOT(addFile(AudioFileModel)), Qt::QueuedConnection); + connect(m_banner.data(), SIGNAL(userAbort()), analyzer.data(), SLOT(abortProcess()), Qt::DirectConnection); - try - { - m_fileListModel->setBlockUpdates(true); - QTime startTime = QTime::currentTime(); - m_banner->show(tr("Adding file(s), please wait..."), analyzer); - } - catch(...) + if(!analyzer.isNull()) { - /* ignore any exceptions that may occur */ + FileListBlockHelper fileListBlocker(m_fileListModel); + m_banner->show(tr("Adding file(s), please wait..."), analyzer.data()); } - m_fileListModel->setBlockUpdates(false); qApp->processEvents(QEventLoop::ExcludeUserInputEvents); ui->sourceFileView->update(); qApp->processEvents(QEventLoop::ExcludeUserInputEvents); @@ -803,35 +856,34 @@ void MainWindow::addFiles(const QStringList &files) if(analyzer->filesDenied()) { - QMessageBox::warning(this, tr("Access Denied"), QString("%1
%2").arg(NOBR(tr("%n file(s) have been rejected, because read access was not granted!", "", analyzer->filesDenied())), NOBR(tr("This usually means the file is locked by another process.")))); + QMessageBox::warning(this, tr("Access Denied"), NOBREAK(QString("%1
%2").arg(tr("%n file(s) have been rejected, because read access was not granted!", "", analyzer->filesDenied()), tr("This usually means the file is locked by another process.")))); } if(analyzer->filesDummyCDDA()) { - QMessageBox::warning(this, tr("CDDA Files"), QString("%1

%2
%3").arg(NOBR(tr("%n file(s) have been rejected, because they are dummy CDDA files!", "", analyzer->filesDummyCDDA())), NOBR(tr("Sorry, LameXP cannot extract audio tracks from an Audio-CD at present.")), NOBR(tr("We recommend using %1 for that purpose.").arg("Exact Audio Copy")))); + QMessageBox::warning(this, tr("CDDA Files"), NOBREAK(QString("%1

%2
%3").arg(tr("%n file(s) have been rejected, because they are dummy CDDA files!", "", analyzer->filesDummyCDDA()), tr("Sorry, LameXP cannot extract audio tracks from an Audio-CD at present."), tr("We recommend using %1 for that purpose.").arg("Exact Audio Copy")))); } if(analyzer->filesCueSheet()) { - QMessageBox::warning(this, tr("Cue Sheet"), QString("%1
%2").arg(NOBR(tr("%n file(s) have been rejected, because they appear to be Cue Sheet images!", "",analyzer->filesCueSheet())), NOBR(tr("Please use LameXP's Cue Sheet wizard for importing Cue Sheet files.")))); + QMessageBox::warning(this, tr("Cue Sheet"), NOBREAK(QString("%1
%2").arg(tr("%n file(s) have been rejected, because they appear to be Cue Sheet images!", "",analyzer->filesCueSheet()), tr("Please use LameXP's Cue Sheet wizard for importing Cue Sheet files.")))); } if(analyzer->filesRejected()) { - QMessageBox::warning(this, tr("Files Rejected"), QString("%1
%2").arg(NOBR(tr("%n file(s) have been rejected, because the file format could not be recognized!", "", analyzer->filesRejected())), NOBR(tr("This usually means the file is damaged or the file format is not supported.")))); + QMessageBox::warning(this, tr("Files Rejected"), NOBREAK(QString("%1
%2").arg(tr("%n file(s) have been rejected, because the file format could not be recognized!", "", analyzer->filesRejected()), tr("This usually means the file is damaged or the file format is not supported.")))); } - MUTILS_DELETE(analyzer); m_banner->close(); } /* * Add folder to source list */ -void MainWindow::addFolder(const QString &path, bool recursive, bool delayed) +void MainWindow::addFolder(const QString &path, bool recursive, bool delayed, QString filter) { QFileInfoList folderInfoList; folderInfoList << QFileInfo(path); QStringList fileList; - SHOW_BANNER(tr("Scanning folder(s) for files, please wait...")); + showBanner(tr("Scanning folder(s) for files, please wait...")); QApplication::processEvents(); MUtils::OS::check_key_state_esc(); @@ -849,9 +901,12 @@ void MainWindow::addFolder(const QString &path, bool recursive, bool delayed) QDir currentDir(folderInfoList.takeFirst().canonicalFilePath()); QFileInfoList fileInfoList = currentDir.entryInfoList(QDir::Files | QDir::NoSymLinks); - while(!fileInfoList.isEmpty()) + for(QFileInfoList::ConstIterator iter = fileInfoList.constBegin(); iter != fileInfoList.constEnd(); iter++) { - fileList << fileInfoList.takeFirst().canonicalFilePath(); + if(filter.isEmpty() || (iter->suffix().compare(filter, Qt::CaseInsensitive) == 0)) + { + fileList << iter->canonicalFilePath(); + } } QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); @@ -882,8 +937,9 @@ void MainWindow::addFolder(const QString &path, bool recursive, bool delayed) /* * Check for updates */ -bool MainWindow::checkForUpdates(void) +bool MainWindow::checkForUpdates(bool &haveNewVersion) { + haveNewVersion = false; bool bReadyToInstall = false; UpdateDialog *updateDialog = new UpdateDialog(m_settings, this); @@ -893,6 +949,7 @@ bool MainWindow::checkForUpdates(void) { SHOW_CORNER_WIDGET(false); m_settings->autoUpdateLastCheck(QDate::currentDate().toString(Qt::ISODate)); + haveNewVersion = updateDialog->haveNewVersion(); bReadyToInstall = updateDialog->updateReadyToInstall(); } @@ -1020,6 +1077,84 @@ void MainWindow::openDocumentLink(QAction *const action) QDesktopServices::openUrl(url); } +/* + * Move selected files up/down + */ +void MainWindow::moveSelectedFiles(const bool &up) +{ + QItemSelectionModel *const selection = ui->sourceFileView->selectionModel(); + if(selection && selection->hasSelection()) + { + const QModelIndexList selectedRows = up ? selection->selectedRows() : INVERT_LIST(selection->selectedRows()); + if((up && (selectedRows.first().row() > 0)) || ((!up) && (selectedRows.first().row() < m_fileListModel->rowCount() - 1))) + { + const int delta = up ? (-1) : 1; + const int firstIndex = (up ? selectedRows.first() : selectedRows.last()).row() + delta; + const int selectionCount = selectedRows.count(); + if(abs(delta) > 0) + { + FileListBlockHelper fileListBlocker(m_fileListModel); + for(QModelIndexList::ConstIterator iter = selectedRows.constBegin(); iter != selectedRows.constEnd(); iter++) + { + if(!m_fileListModel->moveFile((*iter), delta)) + { + break; + } + } + } + selection->clearSelection(); + for(int i = 0; i < selectionCount; i++) + { + const QModelIndex item = m_fileListModel->index(firstIndex + i, 0); + selection->select(QItemSelection(item, item), QItemSelectionModel::Select | QItemSelectionModel::Rows); + } + ui->sourceFileView->scrollTo(m_fileListModel->index((up ? firstIndex : firstIndex + selectionCount - 1), 0), QAbstractItemView::PositionAtCenter); + return; + } + } + MUtils::Sound::beep(MUtils::Sound::BEEP_WRN); +} + +/* + * Show banner popup dialog + */ +void MainWindow::showBanner(const QString &text) +{ + INIT_BANNER(); + m_banner->show(text); +} + +/* + * Show banner popup dialog + */ +void MainWindow::showBanner(const QString &text, QThread *const thread) +{ + INIT_BANNER(); + m_banner->show(text, thread); +} + +/* + * Show banner popup dialog + */ +void MainWindow::showBanner(const QString &text, QEventLoop *const eventLoop) +{ + INIT_BANNER(); + m_banner->show(text, eventLoop); +} + +/* + * Show banner popup dialog + */ +void MainWindow::showBanner(const QString &text, bool &flag, const bool &test) +{ + if((!flag) && (test)) + { + INIT_BANNER(); + m_banner->show(text); + flag = true; + } +} + //////////////////////////////////////////////////////////// // EVENTS //////////////////////////////////////////////////////////// @@ -1035,7 +1170,8 @@ void MainWindow::showEvent(QShowEvent *event) if(!event->spontaneous()) { - WITH_BLOCKED_SIGNALS(ui->tabWidget, setCurrentIndex, 0); + SignalBlockHelper signalBlockHelper(ui->tabWidget); + ui->tabWidget->setCurrentIndex(0); tabPageChanged(ui->tabWidget->currentIndex(), true); } @@ -1064,7 +1200,7 @@ void MainWindow::changeEvent(QEvent *e) return; } - int comboBoxIndex[8]; + int comboBoxIndex[6]; //Backup combobox indices, as retranslateUi() resets comboBoxIndex[0] = ui->comboBoxMP3ChannelMode->currentIndex(); @@ -1072,9 +1208,7 @@ void MainWindow::changeEvent(QEvent *e) comboBoxIndex[2] = ui->comboBoxAACProfile->currentIndex(); comboBoxIndex[3] = ui->comboBoxAftenCodingMode->currentIndex(); comboBoxIndex[4] = ui->comboBoxAftenDRCMode->currentIndex(); - comboBoxIndex[5] = ui->comboBoxNormalizationMode->currentIndex(); - comboBoxIndex[6] = 0; //comboBoxOpusOptimize->currentIndex(); - comboBoxIndex[7] = ui->comboBoxOpusFramesize->currentIndex(); + comboBoxIndex[5] = ui->comboBoxOpusFramesize->currentIndex(); //Re-translate from UIC ui->retranslateUi(this); @@ -1085,9 +1219,7 @@ void MainWindow::changeEvent(QEvent *e) ui->comboBoxAACProfile->setCurrentIndex(comboBoxIndex[2]); ui->comboBoxAftenCodingMode->setCurrentIndex(comboBoxIndex[3]); ui->comboBoxAftenDRCMode->setCurrentIndex(comboBoxIndex[4]); - ui->comboBoxNormalizationMode->setCurrentIndex(comboBoxIndex[5]); - //comboBoxOpusOptimize->setCurrentIndex(comboBoxIndex[6]); - ui->comboBoxOpusFramesize->setCurrentIndex(comboBoxIndex[7]); + ui->comboBoxOpusFramesize->setCurrentIndex(comboBoxIndex[5]); //Update the window title if(MUTILS_DEBUG) @@ -1123,6 +1255,8 @@ void MainWindow::changeEvent(QEvent *e) updateLameAlgoQuality(ui->sliderLameAlgoQuality->value()); updateMaximumInstances(ui->sliderMaxInstances->value()); renameOutputPatternChanged(ui->lineEditRenamePattern->text(), true); + renameRegExpSearchChanged (ui->lineEditRenameRegExp_Search ->text(), true); + renameRegExpReplaceChanged(ui->lineEditRenameRegExp_Replace->text(), true); //Re-install shell integration if(m_settings->shellIntegrationEnabled()) @@ -1247,7 +1381,7 @@ void MainWindow::keyPressEvent(QKeyEvent *e) */ bool MainWindow::eventFilter(QObject *obj, QEvent *event) { - if(obj == m_fileSystemModel) + if(obj == m_fileSystemModel.data()) { if(QApplication::overrideCursor() == NULL) { @@ -1320,45 +1454,60 @@ void MainWindow::windowShown(void) //First run? const bool firstRun = arguments.contains("first-run"); + if (firstRun) + { + m_settings->licenseAccepted(0); + m_settings->autoUpdateCheckBeta(false); + m_settings->syncNow(); + } //Check license - if((m_settings->licenseAccepted() <= 0) || firstRun) + if (m_settings->licenseAccepted() <= 0) { - int iAccepted = m_settings->licenseAccepted(); - - if((iAccepted == 0) || firstRun) + if (m_settings->licenseAccepted() == 0) { - AboutDialog *about = new AboutDialog(m_settings, this, true); - iAccepted = about->exec(); - if(iAccepted <= 0) iAccepted = -2; - MUTILS_DELETE(about); + QScopedPointer about(new AboutDialog(m_settings, this, true)); + if (about->exec() > 0) + { + m_settings->licenseAccepted(1); + m_settings->syncNow(); + PLAY_SOUND_OPTIONAL("woohoo", false); + if (lamexp_version_demo()) + { + showAnnounceBox(); + } + } + else + { + m_settings->licenseAccepted(-1); + m_settings->syncNow(); + } } - - if(iAccepted <= 0) + else { - m_settings->licenseAccepted(++iAccepted); + m_settings->licenseAccepted(0); m_settings->syncNow(); - QApplication::processEvents(); - MUtils::Sound::play_sound("whammy", false); - QMessageBox::critical(this, tr("License Declined"), tr("You have declined the license. Consequently the application will exit now!"), tr("Goodbye!")); - QFileInfo uninstallerInfo = QFileInfo(QString("%1/Uninstall.exe").arg(QApplication::applicationDirPath())); - if(uninstallerInfo.exists()) + } + } + + //License declined? + if(m_settings->licenseAccepted() <= 0) + { + QApplication::processEvents(); + PLAY_SOUND_OPTIONAL("whammy", false); + QMessageBox::critical(this, tr("License Declined"), tr("You have declined the license. Consequently the application will exit now!"), tr("Goodbye!")); + QFileInfo uninstallerInfo = QFileInfo(QString("%1/Uninstall.exe").arg(QApplication::applicationDirPath())); + if(uninstallerInfo.exists()) + { + QString uninstallerDir = uninstallerInfo.canonicalPath(); + QString uninstallerPath = uninstallerInfo.canonicalFilePath(); + for(int i = 0; i < 3; i++) { - QString uninstallerDir = uninstallerInfo.canonicalPath(); - QString uninstallerPath = uninstallerInfo.canonicalFilePath(); - for(int i = 0; i < 3; i++) - { - if(MUtils::OS::shell_open(this, QDir::toNativeSeparators(uninstallerPath), "/Force", QDir::toNativeSeparators(uninstallerDir))) break; - } + if(MUtils::OS::shell_open(this, QDir::toNativeSeparators(uninstallerPath), "/Force", QDir::toNativeSeparators(uninstallerDir))) break; } - QApplication::quit(); - return; } - - MUtils::Sound::play_sound("woohoo", false); - m_settings->licenseAccepted(1); - m_settings->syncNow(); - if(lamexp_version_demo()) showAnnounceBox(); + QApplication::quit(); + return; } //Check for expiration @@ -1366,14 +1515,22 @@ void MainWindow::windowShown(void) { if(MUtils::OS::current_date() >= lamexp_version_expires()) { - qWarning("Binary has expired !!!"); - MUtils::Sound::play_sound("whammy", false); - if(QMessageBox::warning(this, tr("LameXP - Expired"), QString("%1
%2").arg(NOBR(tr("This demo (pre-release) version of LameXP has expired at %1.").arg(lamexp_version_expires().toString(Qt::ISODate))), NOBR(tr("LameXP is free software and release versions won't expire."))), tr("Check for Updates"), tr("Exit Program")) == 0) + qWarning("Binary expired !!!"); + PLAY_SOUND_OPTIONAL("whammy", false); + bool haveNewVersion = true; + if(QMessageBox::warning(this, tr("LameXP - Expired"), NOBREAK(QString("%1
%2").arg(tr("This demo (pre-release) version of LameXP has expired at %1.").arg(lamexp_version_expires().toString(Qt::ISODate)), tr("LameXP is free software and release versions won't expire."))), tr("Check for Updates"), tr("Exit Program")) == 0) { - checkForUpdates(); + if (checkForUpdates(haveNewVersion)) + { + QApplication::quit(); + return; + } + } + if(haveNewVersion) + { + QApplication::quit(); + return; } - QApplication::quit(); - return; } } @@ -1381,9 +1538,9 @@ void MainWindow::windowShown(void) if(m_settings->slowStartup() && m_settings->antivirNotificationsEnabled()) { QString message; - message += NOBR(tr("It seems that a bogus anti-virus software is slowing down the startup of LameXP.")).append("
"); - message += NOBR(tr("Please refer to the %1 document for details and solutions!")).arg("F.A.Q.").append("
"); - if(QMessageBox::warning(this, tr("Slow Startup"), message, tr("Discard"), tr("Don't Show Again")) == 1) + message += tr("It seems that a bogus anti-virus software is slowing down the startup of LameXP.").append("
"); + message += tr("Please refer to the %1 document for details and solutions!").arg(LINK_EX(QString("%1/Manual.html#performance-issues").arg(g_documents_base_url), tr("Manual"))).append("
"); + if(QMessageBox::warning(this, tr("Slow Startup"), NOBREAK(message), tr("Discard"), tr("Don't Show Again")) == 1) { m_settings->antivirNotificationsEnabled(false); ui->actionDisableSlowStartupNotifications->setChecked(!m_settings->antivirNotificationsEnabled()); @@ -1395,11 +1552,12 @@ void MainWindow::windowShown(void) { qWarning("Binary is more than a year old, time to update!"); SHOW_CORNER_WIDGET(true); - int ret = QMessageBox::warning(this, tr("Urgent Update"), NOBR(tr("Your version of LameXP is more than a year old. Time for an update!")), tr("Check for Updates"), tr("Exit Program"), tr("Ignore")); + int ret = QMessageBox::warning(this, tr("Urgent Update"), NOBREAK(tr("Your version of LameXP is more than a year old. Time for an update!")), tr("Check for Updates"), tr("Exit Program"), tr("Ignore")); switch(ret) { case 0: - if(checkForUpdates()) + bool haveNewVersion; + if(checkForUpdates(haveNewVersion)) { QApplication::quit(); return; @@ -1410,8 +1568,8 @@ void MainWindow::windowShown(void) return; default: QEventLoop loop; QTimer::singleShot(7000, &loop, SLOT(quit())); - MUtils::Sound::play_sound("waiting", true); - SHOW_BANNER_ARG(tr("Skipping update check this time, please be patient..."), &loop); + PLAY_SOUND_OPTIONAL("waiting", true); + showBanner(tr("Skipping update check this time, please be patient..."), &loop); break; } } @@ -1423,9 +1581,10 @@ void MainWindow::windowShown(void) SHOW_CORNER_WIDGET(true); if(m_settings->autoUpdateEnabled()) { - if(QMessageBox::information(this, tr("Update Reminder"), NOBR(lastUpdateCheck.isValid() ? tr("Your last update check was more than 14 days ago. Check for updates now?") : tr("Your did not check for LameXP updates yet. Check for updates now?")), tr("Check for Updates"), tr("Postpone")) == 0) + if(QMessageBox::information(this, tr("Update Reminder"), NOBREAK(lastUpdateCheck.isValid() ? tr("Your last update check was more than 14 days ago. Check for updates now?") : tr("Your did not check for LameXP updates yet. Check for updates now?")), tr("Check for Updates"), tr("Postpone")) == 0) { - if(checkForUpdates()) + bool haveNewVersion; + if(checkForUpdates(haveNewVersion)) { QApplication::quit(); return; @@ -1436,41 +1595,22 @@ void MainWindow::windowShown(void) } //Check for AAC support - const int aacEncoder = EncoderRegistry::getAacEncoder(); - if(aacEncoder == SettingsModel::AAC_ENCODER_NERO) - { - if(m_settings->neroAacNotificationsEnabled()) - { - if(lamexp_tools_version("neroAacEnc.exe") < lamexp_toolver_neroaac()) - { - QString messageText; - messageText += NOBR(tr("LameXP detected that your version of the Nero AAC encoder is outdated!")).append("
"); - messageText += NOBR(tr("The current version available is %1 (or later), but you still have version %2 installed.").arg(lamexp_version2string("?.?.?.?", lamexp_toolver_neroaac(), tr("n/a")), lamexp_version2string("?.?.?.?", lamexp_tools_version("neroAacEnc.exe"), tr("n/a")))).append("

"); - messageText += NOBR(tr("You can download the latest version of the Nero AAC encoder from the Nero website at:")).append("
"); - messageText += "" + LINK(AboutDialog::neroAacUrl) + "

"; - messageText += NOBR(tr("(Hint: Please ignore the name of the downloaded ZIP file and check the included 'changelog.txt' instead!)")).append("
"); - QMessageBox::information(this, tr("AAC Encoder Outdated"), messageText); - } - } - } - else - { - if(m_settings->neroAacNotificationsEnabled() && (aacEncoder <= SettingsModel::AAC_ENCODER_NONE)) + if(m_settings->neroAacNotificationsEnabled() && (EncoderRegistry::getAacEncoder() <= SettingsModel::AAC_ENCODER_NONE)) + { + QString appPath = QDir(QCoreApplication::applicationDirPath()).canonicalPath(); + if(appPath.isEmpty()) appPath = QCoreApplication::applicationDirPath(); + QString messageText; + messageText += tr("The Nero AAC encoder could not be found. AAC encoding support will be disabled.").append("
"); + messageText += tr("Please put 'neroAacEnc.exe', 'neroAacDec.exe' and 'neroAacTag.exe' into the LameXP directory!").append("

"); + messageText += QString("").append(tr("Your LameXP install directory is located here:")).append("
"); + messageText += QString("%1

").arg(FSLINK(QDir::toNativeSeparators(appPath))); + messageText += QString("").append(tr("You can download the Nero AAC encoder for free from this website:")).append("
"); + messageText += QString("").append(LINK(AboutDialog::neroAacUrl)).append("

"); + messageText += QString("").append(tr("Note: Nero AAC encoder version %1 or newer is required to enable AAC encoding support!").arg(lamexp_version2string("v?.?.?.?", lamexp_toolver_neroaac(), "n/a"))).append("
"); + if(QMessageBox::information(this, tr("AAC Support Disabled"), NOBREAK(messageText), tr("Discard"), tr("Don't Show Again")) == 1) { - QString appPath = QDir(QCoreApplication::applicationDirPath()).canonicalPath(); - if(appPath.isEmpty()) appPath = QCoreApplication::applicationDirPath(); - QString messageText; - messageText += NOBR(tr("The Nero AAC encoder could not be found. AAC encoding support will be disabled.")).append("
"); - messageText += NOBR(tr("Please put 'neroAacEnc.exe', 'neroAacDec.exe' and 'neroAacTag.exe' into the LameXP directory!")).append("

"); - messageText += NOBR(tr("Your LameXP directory is located here:")).append("
"); - messageText += QString("%1

").arg(FSLINK(QDir::toNativeSeparators(appPath))); - messageText += NOBR(tr("You can download the Nero AAC encoder for free from the official Nero website at:")).append("
"); - messageText += "" + LINK(AboutDialog::neroAacUrl) + "
"; - if(QMessageBox::information(this, tr("AAC Support Disabled"), messageText, tr("Discard"), tr("Don't Show Again")) == 1) - { - m_settings->neroAacNotificationsEnabled(false); - ui->actionDisableNeroAacNotifications->setChecked(!m_settings->neroAacNotificationsEnabled()); - } + m_settings->neroAacNotificationsEnabled(false); + ui->actionDisableNeroAacNotifications->setChecked(!m_settings->neroAacNotificationsEnabled()); } } @@ -1530,14 +1670,14 @@ void MainWindow::showAnnounceBox(void) { const unsigned int timeout = 8U; - const QString announceText = QString("%1

%2
%3
").arg + const QString announceText = QString("%1

%2
%3
").arg ( - NOBR("We are still looking for LameXP translators!"), - NOBR("If you are willing to translate LameXP to your language or to complete an existing translation, please refer to:"), + "We are still looking for LameXP translators!", + "If you are willing to translate LameXP to your language or to complete an existing translation, please refer to:", LINK("http://lamexp.sourceforge.net/doc/Translate.html") ); - QMessageBox *announceBox = new QMessageBox(QMessageBox::Warning, "We want you!", announceText, QMessageBox::NoButton, this); + QMessageBox *announceBox = new QMessageBox(QMessageBox::Warning, "We want you!", NOBREAK(announceText), QMessageBox::NoButton, this); announceBox->setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint); announceBox->setIconPixmap(QIcon(":/images/Announcement.png").pixmap(64,79)); @@ -1598,7 +1738,7 @@ void MainWindow::encodeButtonClicked(void) if(m_fileListModel->rowCount() < 1) { - QMessageBox::warning(this, tr("LameXP"), NOBR(tr("You must add at least one file to the list before proceeding!"))); + QMessageBox::warning(this, tr("LameXP"), NOBREAK(tr("You must add at least one file to the list before proceeding!"))); ui->tabWidget->setCurrentIndex(0); return; } @@ -1606,9 +1746,9 @@ void MainWindow::encodeButtonClicked(void) QString tempFolder = m_settings->customTempPathEnabled() ? m_settings->customTempPath() : MUtils::temp_folder(); if(!QFileInfo(tempFolder).exists() || !QFileInfo(tempFolder).isDir()) { - if(QMessageBox::warning(this, tr("Not Found"), QString("%1
%2").arg(NOBR(tr("Your currently selected TEMP folder does not exist anymore:")), NOBR(QDir::toNativeSeparators(tempFolder))), tr("Restore Default"), tr("Cancel")) == 0) + if(QMessageBox::warning(this, tr("Not Found"), NOBREAK(QString("%1
%2").arg(tr("Your currently selected TEMP folder does not exist anymore:"), QDir::toNativeSeparators(tempFolder))), tr("Restore Default"), tr("Cancel")) == 0) { - SET_CHECKBOX_STATE(ui->checkBoxUseSystemTempFolder, m_settings->customTempPathEnabledDefault()); + SET_CHECKBOX_STATE(ui->checkBoxUseSystemTempFolder, (!m_settings->customTempPathEnabledDefault())); } return; } @@ -1623,20 +1763,20 @@ void MainWindow::encodeButtonClicked(void) PLAY_SOUND_OPTIONAL("whammy", false); QString lowDiskspaceMsg = QString("%1
%2

%3
%4
").arg ( - NOBR(tr("There are less than %1 GB of free diskspace available on your system's TEMP folder.").arg(QString::number(minimumFreeDiskspaceMultiplier))), - NOBR(tr("It is highly recommend to free up more diskspace before proceeding with the encode!")), - NOBR(tr("Your TEMP folder is located at:")), - QString("%1").arg(FSLINK(tempFolderParts.join("\\"))) + tr("There are less than %1 GB of free diskspace available on your system's TEMP folder.").arg(QString::number(minimumFreeDiskspaceMultiplier)), + tr("It is highly recommend to free up more diskspace before proceeding with the encode!"), + tr("Your TEMP folder is located at:"), + QString("%1").arg(FSLINK(tempFolderParts.join("\\"))) ); - switch(QMessageBox::warning(this, tr("Low Diskspace Warning"), lowDiskspaceMsg, tr("Abort Encoding Process"), tr("Clean Disk Now"), tr("Ignore"))) + switch(QMessageBox::warning(this, tr("Low Diskspace Warning"), NOBREAK(lowDiskspaceMsg), tr("Abort Encoding Process"), tr("Clean Disk Now"), tr("Ignore"))) { case 1: - QProcess::startDetached(QString("%1/cleanmgr.exe").arg(MUtils::OS::known_folder(MUtils::OS::FOLDER_SYSTEMFOLDER)), QStringList() << "/D" << tempFolderParts.first()); + QProcess::startDetached(QString("%1/cleanmgr.exe").arg(MUtils::OS::known_folder(MUtils::OS::FOLDER_SYSTEM_DEF)), QStringList() << "/D" << tempFolderParts.first()); case 0: return; break; default: - QMessageBox::warning(this, tr("Low Diskspace"), NOBR(tr("You are proceeding with low diskspace. Problems might occur!"))); + QMessageBox::warning(this, tr("Low Diskspace"), NOBREAK(tr("You are proceeding with low diskspace. Problems might occur!"))); break; } } @@ -1662,10 +1802,10 @@ void MainWindow::encodeButtonClicked(void) if(!m_settings->outputToSourceDir()) { - QFile writeTest(QString("%1/~%2.txt").arg(m_settings->outputDir(), MUtils::rand_str())); + QFile writeTest(QString("%1/~%2.txt").arg(m_settings->outputDir(), MUtils::next_rand_str())); if(!(writeTest.open(QIODevice::ReadWrite) && (writeTest.write(writeTestBuffer) == strlen(writeTestBuffer)))) { - QMessageBox::warning(this, tr("LameXP"), QString("%1
%2

%3").arg(tr("Cannot write to the selected output directory."), m_settings->outputDir(), tr("Please choose a different directory!"))); + QMessageBox::warning(this, tr("LameXP"), NOBREAK(QString("%1
%2

%3").arg(tr("Cannot write to the selected output directory."), m_settings->outputDir(), tr("Please choose a different directory!")))); ui->tabWidget->setCurrentIndex(1); return; } @@ -1686,13 +1826,9 @@ void MainWindow::encodeButtonClicked(void) void MainWindow::aboutButtonClicked(void) { ABORT_IF_BUSY; - - TEMP_HIDE_DROPBOX - ( - AboutDialog *aboutBox = new AboutDialog(m_settings, this); - aboutBox->exec(); - MUTILS_DELETE(aboutBox); - ); + WidgetHideHelper hiderHelper(m_dropBox.data()); + QScopedPointer aboutBox(new AboutDialog(m_settings, this)); + aboutBox->exec(); } /* @@ -1770,7 +1906,7 @@ void MainWindow::tabPageChanged(int idx, const bool silent) } else { - CENTER_CURRENT_OUTPUT_FOLDER_DELAYED; + CENTER_CURRENT_OUTPUT_FOLDER_DELAYED(); } } @@ -1948,9 +2084,9 @@ void MainWindow::disableUpdateReminderActionTriggered(bool checked) { if(checked) { - if(0 == QMessageBox::question(this, tr("Disable Update Reminder"), NOBR(tr("Do you really want to disable the update reminder?")), tr("Yes"), tr("No"), QString(), 1)) + if(0 == QMessageBox::question(this, tr("Disable Update Reminder"), NOBREAK(tr("Do you really want to disable the update reminder?")), tr("Yes"), tr("No"), QString(), 1)) { - QMessageBox::information(this, tr("Update Reminder"), QString("%1
%2").arg(NOBR(tr("The update reminder has been disabled.")), NOBR(tr("Please remember to check for updates at regular intervals!")))); + QMessageBox::information(this, tr("Update Reminder"), NOBREAK(QString("%1
%2").arg(tr("The update reminder has been disabled."), tr("Please remember to check for updates at regular intervals!")))); m_settings->autoUpdateEnabled(false); } else @@ -1960,7 +2096,7 @@ void MainWindow::disableUpdateReminderActionTriggered(bool checked) } else { - QMessageBox::information(this, tr("Update Reminder"), NOBR(tr("The update reminder has been re-enabled."))); + QMessageBox::information(this, tr("Update Reminder"), NOBREAK(tr("The update reminder has been re-enabled."))); m_settings->autoUpdateEnabled(true); } @@ -1974,9 +2110,9 @@ void MainWindow::disableSoundsActionTriggered(bool checked) { if(checked) { - if(0 == QMessageBox::question(this, tr("Disable Sound Effects"), NOBR(tr("Do you really want to disable all sound effects?")), tr("Yes"), tr("No"), QString(), 1)) + if(0 == QMessageBox::question(this, tr("Disable Sound Effects"), NOBREAK(tr("Do you really want to disable all sound effects?")), tr("Yes"), tr("No"), QString(), 1)) { - QMessageBox::information(this, tr("Sound Effects"), NOBR(tr("All sound effects have been disabled."))); + QMessageBox::information(this, tr("Sound Effects"), NOBREAK(tr("All sound effects have been disabled."))); m_settings->soundsEnabled(false); } else @@ -1986,7 +2122,7 @@ void MainWindow::disableSoundsActionTriggered(bool checked) } else { - QMessageBox::information(this, tr("Sound Effects"), NOBR(tr("The sound effects have been re-enabled."))); + QMessageBox::information(this, tr("Sound Effects"), NOBREAK(tr("The sound effects have been re-enabled."))); m_settings->soundsEnabled(true); } @@ -2000,9 +2136,9 @@ void MainWindow::disableNeroAacNotificationsActionTriggered(bool checked) { if(checked) { - if(0 == QMessageBox::question(this, tr("Nero AAC Notifications"), NOBR(tr("Do you really want to disable all Nero AAC Encoder notifications?")), tr("Yes"), tr("No"), QString(), 1)) + if(0 == QMessageBox::question(this, tr("Nero AAC Notifications"), NOBREAK(tr("Do you really want to disable all Nero AAC Encoder notifications?")), tr("Yes"), tr("No"), QString(), 1)) { - QMessageBox::information(this, tr("Nero AAC Notifications"), NOBR(tr("All Nero AAC Encoder notifications have been disabled."))); + QMessageBox::information(this, tr("Nero AAC Notifications"), NOBREAK(tr("All Nero AAC Encoder notifications have been disabled."))); m_settings->neroAacNotificationsEnabled(false); } else @@ -2012,8 +2148,8 @@ void MainWindow::disableNeroAacNotificationsActionTriggered(bool checked) } else { - QMessageBox::information(this, tr("Nero AAC Notifications"), NOBR(tr("The Nero AAC Encoder notifications have been re-enabled."))); - m_settings->neroAacNotificationsEnabled(true); + QMessageBox::information(this, tr("Nero AAC Notifications"), NOBREAK(tr("The Nero AAC Encoder notifications have been re-enabled."))); + m_settings->neroAacNotificationsEnabled(true); } ui->actionDisableNeroAacNotifications->setChecked(!m_settings->neroAacNotificationsEnabled()); @@ -2026,9 +2162,9 @@ void MainWindow::disableSlowStartupNotificationsActionTriggered(bool checked) { if(checked) { - if(0 == QMessageBox::question(this, tr("Slow Startup Notifications"), NOBR(tr("Do you really want to disable the slow startup notifications?")), tr("Yes"), tr("No"), QString(), 1)) + if(0 == QMessageBox::question(this, tr("Slow Startup Notifications"), NOBREAK(tr("Do you really want to disable the slow startup notifications?")), tr("Yes"), tr("No"), QString(), 1)) { - QMessageBox::information(this, tr("Slow Startup Notifications"), NOBR(tr("The slow startup notifications have been disabled."))); + QMessageBox::information(this, tr("Slow Startup Notifications"), NOBREAK(tr("The slow startup notifications have been disabled."))); m_settings->antivirNotificationsEnabled(false); } else @@ -2038,7 +2174,7 @@ void MainWindow::disableSlowStartupNotificationsActionTriggered(bool checked) } else { - QMessageBox::information(this, tr("Slow Startup Notifications"), NOBR(tr("The slow startup notifications have been re-enabled."))); + QMessageBox::information(this, tr("Slow Startup Notifications"), NOBREAK(tr("The slow startup notifications have been re-enabled."))); m_settings->antivirNotificationsEnabled(true); } @@ -2051,50 +2187,47 @@ void MainWindow::disableSlowStartupNotificationsActionTriggered(bool checked) void MainWindow::importCueSheetActionTriggered(bool checked) { ABORT_IF_BUSY; - - TEMP_HIDE_DROPBOX - ( - while(true) - { - int result = 0; - QString selectedCueFile; + WidgetHideHelper hiderHelper(m_dropBox.data()); - if(MUtils::GUI::themes_enabled()) - { - selectedCueFile = QFileDialog::getOpenFileName(this, tr("Open Cue Sheet"), m_settings->mostRecentInputPath(), QString("%1 (*.cue)").arg(tr("Cue Sheet File"))); - } - else - { - QFileDialog dialog(this, tr("Open Cue Sheet")); - dialog.setFileMode(QFileDialog::ExistingFile); - dialog.setNameFilter(QString("%1 (*.cue)").arg(tr("Cue Sheet File"))); - dialog.setDirectory(m_settings->mostRecentInputPath()); - if(dialog.exec()) - { - selectedCueFile = dialog.selectedFiles().first(); - } - } + while(true) + { + int result = 0; + QString selectedCueFile; - if(!selectedCueFile.isEmpty()) + if(MUtils::GUI::themes_enabled()) + { + selectedCueFile = QFileDialog::getOpenFileName(this, tr("Open Cue Sheet"), m_settings->mostRecentInputPath(), QString("%1 (*.cue)").arg(tr("Cue Sheet File"))); + } + else + { + QFileDialog dialog(this, tr("Open Cue Sheet")); + dialog.setFileMode(QFileDialog::ExistingFile); + dialog.setNameFilter(QString("%1 (*.cue)").arg(tr("Cue Sheet File"))); + dialog.setDirectory(m_settings->mostRecentInputPath()); + if(dialog.exec()) { - m_settings->mostRecentInputPath(QFileInfo(selectedCueFile).canonicalPath()); - CueImportDialog *cueImporter = new CueImportDialog(this, m_fileListModel, selectedCueFile, m_settings); - result = cueImporter->exec(); - MUTILS_DELETE(cueImporter); + selectedCueFile = dialog.selectedFiles().first(); } + } - if(result == QDialog::Accepted) - { - qApp->processEvents(QEventLoop::ExcludeUserInputEvents); - ui->sourceFileView->update(); - qApp->processEvents(QEventLoop::ExcludeUserInputEvents); - ui->sourceFileView->scrollToBottom(); - qApp->processEvents(QEventLoop::ExcludeUserInputEvents); - } + if(!selectedCueFile.isEmpty()) + { + m_settings->mostRecentInputPath(QFileInfo(selectedCueFile).canonicalPath()); + FileListBlockHelper fileListBlocker(m_fileListModel); + QScopedPointer cueImporter(new CueImportDialog(this, m_fileListModel, selectedCueFile, m_settings)); + result = cueImporter->exec(); + } - if(result != (-1)) break; + if(result != (-1)) + { + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); + ui->sourceFileView->update(); + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); + ui->sourceFileView->scrollToBottom(); + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); + break; } - ); + } } /* @@ -2107,10 +2240,10 @@ void MainWindow::showDropBoxWidgetActionTriggered(bool checked) if(!m_dropBox->isVisible()) { m_dropBox->show(); - QTimer::singleShot(2500, m_dropBox, SLOT(showToolTip())); + QTimer::singleShot(2500, m_dropBox.data(), SLOT(showToolTip())); } - MUtils::GUI::blink_window(m_dropBox); + MUtils::GUI::blink_window(m_dropBox.data()); } /* @@ -2122,9 +2255,9 @@ void MainWindow::checkForBetaUpdatesActionTriggered(bool checked) if(checked) { - if(0 == QMessageBox::question(this, tr("Beta Updates"), NOBR(tr("Do you really want LameXP to check for Beta (pre-release) updates?")), tr("Yes"), tr("No"), QString(), 1)) + if(0 == QMessageBox::question(this, tr("Beta Updates"), NOBREAK(tr("Do you really want LameXP to check for Beta (pre-release) updates?")), tr("Yes"), tr("No"), QString(), 1)) { - if(0 == QMessageBox::information(this, tr("Beta Updates"), NOBR(tr("LameXP will check for Beta (pre-release) updates from now on.")), tr("Check Now"), tr("Discard"))) + if(0 == QMessageBox::information(this, tr("Beta Updates"), NOBREAK(tr("LameXP will check for Beta (pre-release) updates from now on.")), tr("Check Now"), tr("Discard"))) { checkUpdatesNow = true; } @@ -2137,15 +2270,16 @@ void MainWindow::checkForBetaUpdatesActionTriggered(bool checked) } else { - QMessageBox::information(this, tr("Beta Updates"), NOBR(tr("LameXP will not check for Beta (pre-release) updates from now on."))); - m_settings->autoUpdateCheckBeta(false); + QMessageBox::information(this, tr("Beta Updates"), NOBREAK(tr("LameXP will not check for Beta (pre-release) updates from now on."))); + m_settings->autoUpdateCheckBeta(false); } ui->actionCheckForBetaUpdates->setChecked(m_settings->autoUpdateCheckBeta()); if(checkUpdatesNow) { - if(checkForUpdates()) + bool haveNewVersion; + if(checkForUpdates(haveNewVersion)) { QApplication::quit(); } @@ -2159,9 +2293,9 @@ void MainWindow::hibernateComputerActionTriggered(bool checked) { if(checked) { - if(0 == QMessageBox::question(this, tr("Hibernate Computer"), NOBR(tr("Do you really want the computer to be hibernated on shutdown?")), tr("Yes"), tr("No"), QString(), 1)) + if(0 == QMessageBox::question(this, tr("Hibernate Computer"), NOBREAK(tr("Do you really want the computer to be hibernated on shutdown?")), tr("Yes"), tr("No"), QString(), 1)) { - QMessageBox::information(this, tr("Hibernate Computer"), NOBR(tr("LameXP will hibernate the computer on shutdown from now on."))); + QMessageBox::information(this, tr("Hibernate Computer"), NOBREAK(tr("LameXP will hibernate the computer on shutdown from now on."))); m_settings->hibernateComputer(true); } else @@ -2171,7 +2305,7 @@ void MainWindow::hibernateComputerActionTriggered(bool checked) } else { - QMessageBox::information(this, tr("Hibernate Computer"), NOBR(tr("LameXP will not hibernate the computer on shutdown from now on."))); + QMessageBox::information(this, tr("Hibernate Computer"), NOBREAK(tr("LameXP will not hibernate the computer on shutdown from now on."))); m_settings->hibernateComputer(false); } @@ -2185,10 +2319,10 @@ void MainWindow::disableShellIntegrationActionTriggered(bool checked) { if(checked) { - if(0 == QMessageBox::question(this, tr("Shell Integration"), NOBR(tr("Do you really want to disable the LameXP shell integration?")), tr("Yes"), tr("No"), QString(), 1)) + if(0 == QMessageBox::question(this, tr("Shell Integration"), NOBREAK(tr("Do you really want to disable the LameXP shell integration?")), tr("Yes"), tr("No"), QString(), 1)) { ShellIntegration::remove(); - QMessageBox::information(this, tr("Shell Integration"), NOBR(tr("The LameXP shell integration has been disabled."))); + QMessageBox::information(this, tr("Shell Integration"), NOBREAK(tr("The LameXP shell integration has been disabled."))); m_settings->shellIntegrationEnabled(false); } else @@ -2199,7 +2333,7 @@ void MainWindow::disableShellIntegrationActionTriggered(bool checked) else { ShellIntegration::install(); - QMessageBox::information(this, tr("Shell Integration"), NOBR(tr("The LameXP shell integration has been re-enabled."))); + QMessageBox::information(this, tr("Shell Integration"), NOBREAK(tr("The LameXP shell integration has been re-enabled."))); m_settings->shellIntegrationEnabled(true); } @@ -2246,14 +2380,10 @@ void MainWindow::documentActionActivated(void) void MainWindow::checkUpdatesActionActivated(void) { ABORT_IF_BUSY; - bool bFlag = false; - - TEMP_HIDE_DROPBOX - ( - bFlag = checkForUpdates(); - ); + WidgetHideHelper hiderHelper(m_dropBox.data()); - if(bFlag) + bool haveNewVersion; + if(checkForUpdates(haveNewVersion)) { QApplication::quit(); } @@ -2269,37 +2399,35 @@ void MainWindow::checkUpdatesActionActivated(void) void MainWindow::addFilesButtonClicked(void) { ABORT_IF_BUSY; + WidgetHideHelper hiderHelper(m_dropBox.data()); - TEMP_HIDE_DROPBOX - ( - if(MUtils::GUI::themes_enabled()) + if(MUtils::GUI::themes_enabled() && (!MUTILS_DEBUG)) + { + QStringList fileTypeFilters = DecoderRegistry::getSupportedTypes(); + QStringList selectedFiles = QFileDialog::getOpenFileNames(this, tr("Add file(s)"), m_settings->mostRecentInputPath(), fileTypeFilters.join(";;")); + if(!selectedFiles.isEmpty()) + { + m_settings->mostRecentInputPath(QFileInfo(selectedFiles.first()).canonicalPath()); + addFiles(selectedFiles); + } + } + else + { + QFileDialog dialog(this, tr("Add file(s)")); + QStringList fileTypeFilters = DecoderRegistry::getSupportedTypes(); + dialog.setFileMode(QFileDialog::ExistingFiles); + dialog.setNameFilter(fileTypeFilters.join(";;")); + dialog.setDirectory(m_settings->mostRecentInputPath()); + if(dialog.exec()) { - QStringList fileTypeFilters = DecoderRegistry::getSupportedTypes(); - QStringList selectedFiles = QFileDialog::getOpenFileNames(this, tr("Add file(s)"), m_settings->mostRecentInputPath(), fileTypeFilters.join(";;")); + QStringList selectedFiles = dialog.selectedFiles(); if(!selectedFiles.isEmpty()) { m_settings->mostRecentInputPath(QFileInfo(selectedFiles.first()).canonicalPath()); addFiles(selectedFiles); } } - else - { - QFileDialog dialog(this, tr("Add file(s)")); - QStringList fileTypeFilters = DecoderRegistry::getSupportedTypes(); - dialog.setFileMode(QFileDialog::ExistingFiles); - dialog.setNameFilter(fileTypeFilters.join(";;")); - dialog.setDirectory(m_settings->mostRecentInputPath()); - if(dialog.exec()) - { - QStringList selectedFiles = dialog.selectedFiles(); - if(!selectedFiles.isEmpty()) - { - m_settings->mostRecentInputPath(QFileInfo(selectedFiles.first()).canonicalPath()); - addFiles(selectedFiles); - } - } - } - ); + } } /* @@ -2312,29 +2440,49 @@ void MainWindow::openFolderActionActivated(void) if(QAction *action = dynamic_cast(QObject::sender())) { - TEMP_HIDE_DROPBOX - ( - if(MUtils::GUI::themes_enabled()) - { - selectedFolder = QFileDialog::getExistingDirectory(this, tr("Add Folder"), m_settings->mostRecentInputPath()); - } - else - { - QFileDialog dialog(this, tr("Add Folder")); - dialog.setFileMode(QFileDialog::DirectoryOnly); - dialog.setDirectory(m_settings->mostRecentInputPath()); - if(dialog.exec()) - { - selectedFolder = dialog.selectedFiles().first(); - } - } - - if(!selectedFolder.isEmpty()) + WidgetHideHelper hiderHelper(m_dropBox.data()); + if(MUtils::GUI::themes_enabled()) + { + selectedFolder = QFileDialog::getExistingDirectory(this, tr("Add Folder"), m_settings->mostRecentInputPath()); + } + else + { + QFileDialog dialog(this, tr("Add Folder")); + dialog.setFileMode(QFileDialog::DirectoryOnly); + dialog.setDirectory(m_settings->mostRecentInputPath()); + if(dialog.exec()) { - m_settings->mostRecentInputPath(QDir(selectedFolder).canonicalPath()); - addFolder(selectedFolder, action->data().toBool()); + selectedFolder = dialog.selectedFiles().first(); } - ); + } + + if(selectedFolder.isEmpty()) + { + return; + } + + QStringList filterItems = DecoderRegistry::getSupportedExts(); + filterItems.prepend("*.*"); + + bool okay; + QString filterStr = QInputDialog::getItem(this, tr("Filter Files"), tr("Select filename filter:"), filterItems, 0, false, &okay).trimmed(); + if(!okay) + { + return; + } + + QRegExp regExp("\\*\\.([A-Za-z0-9]+)", Qt::CaseInsensitive); + if(regExp.lastIndexIn(filterStr) >= 0) + { + filterStr = regExp.cap(1).trimmed(); + } + else + { + filterStr.clear(); + } + + m_settings->mostRecentInputPath(QDir(selectedFolder).canonicalPath()); + addFolder(selectedFolder, action->data().toBool(), false, filterStr); } } @@ -2343,11 +2491,33 @@ void MainWindow::openFolderActionActivated(void) */ void MainWindow::removeFileButtonClicked(void) { - if(ui->sourceFileView->currentIndex().isValid()) + const QItemSelectionModel *const selection = ui->sourceFileView->selectionModel(); + if(selection && selection->hasSelection()) + { + int firstRow = -1; + const QModelIndexList selectedRows = INVERT_LIST(selection->selectedRows()); + if(!selectedRows.isEmpty()) + { + FileListBlockHelper fileListBlocker(m_fileListModel); + firstRow = selectedRows.last().row(); + for(QModelIndexList::ConstIterator iter = selectedRows.constBegin(); iter != selectedRows.constEnd(); iter++) + { + if(!m_fileListModel->removeFile(*iter)) + { + break; + } + } + } + if(m_fileListModel->rowCount() > 0) + { + const QModelIndex position = m_fileListModel->index(((firstRow >= 0) && (firstRow < m_fileListModel->rowCount())) ? firstRow : (m_fileListModel->rowCount() - 1), 0); + ui->sourceFileView->selectRow(position.row()); + ui->sourceFileView->scrollTo(position, QAbstractItemView::PositionAtCenter); + } + } + else { - int iRow = ui->sourceFileView->currentIndex().row(); - m_fileListModel->removeFile(ui->sourceFileView->currentIndex()); - ui->sourceFileView->selectRow(iRow < m_fileListModel->rowCount() ? iRow : m_fileListModel->rowCount()-1); + MUtils::Sound::beep(MUtils::Sound::BEEP_WRN); } } @@ -2356,7 +2526,14 @@ void MainWindow::removeFileButtonClicked(void) */ void MainWindow::clearFilesButtonClicked(void) { - m_fileListModel->clearFiles(); + if(m_fileListModel->rowCount() > 0) + { + m_fileListModel->clearFiles(); + } + else + { + MUtils::Sound::beep(MUtils::Sound::BEEP_WRN); + } } /* @@ -2364,12 +2541,7 @@ void MainWindow::clearFilesButtonClicked(void) */ void MainWindow::fileUpButtonClicked(void) { - if(ui->sourceFileView->currentIndex().isValid()) - { - int iRow = ui->sourceFileView->currentIndex().row() - 1; - m_fileListModel->moveFile(ui->sourceFileView->currentIndex(), -1); - ui->sourceFileView->selectRow(iRow >= 0 ? iRow : 0); - } + moveSelectedFiles(true); } /* @@ -2377,12 +2549,7 @@ void MainWindow::fileUpButtonClicked(void) */ void MainWindow::fileDownButtonClicked(void) { - if(ui->sourceFileView->currentIndex().isValid()) - { - int iRow = ui->sourceFileView->currentIndex().row() + 1; - m_fileListModel->moveFile(ui->sourceFileView->currentIndex(), 1); - ui->sourceFileView->selectRow(iRow < m_fileListModel->rowCount() ? iRow : m_fileListModel->rowCount()-1); - } + moveSelectedFiles(false); } /* @@ -2393,40 +2560,47 @@ void MainWindow::showDetailsButtonClicked(void) ABORT_IF_BUSY; int iResult = 0; - MetaInfoDialog *metaInfoDialog = new MetaInfoDialog(this); QModelIndex index = ui->sourceFileView->currentIndex(); - - while(index.isValid()) + + if(index.isValid()) { - if(iResult > 0) - { - index = m_fileListModel->index(index.row() + 1, index.column()); - ui->sourceFileView->selectRow(index.row()); - } - if(iResult < 0) + ui->sourceFileView->selectRow(index.row()); + QScopedPointer metaInfoDialog(new MetaInfoDialog(this)); + forever { - index = m_fileListModel->index(index.row() - 1, index.column()); - ui->sourceFileView->selectRow(index.row()); - } - - AudioFileModel &file = (*m_fileListModel)[index]; - TEMP_HIDE_DROPBOX - ( + AudioFileModel &file = (*m_fileListModel)[index]; + WidgetHideHelper hiderHelper(m_dropBox.data()); iResult = metaInfoDialog->exec(file, index.row() > 0, index.row() < m_fileListModel->rowCount() - 1); - ); - //Copy all info to Meta Info tab - if(iResult == INT_MAX) - { - m_metaInfoModel->assignInfoFrom(file); - ui->tabWidget->setCurrentIndex(ui->tabWidget->indexOf(ui->tabMetaData)); - break; - } + //Copy all info to Meta Info tab + if(iResult == INT_MAX) + { + m_metaInfoModel->assignInfoFrom(file); + ui->tabWidget->setCurrentIndex(ui->tabWidget->indexOf(ui->tabMetaData)); + break; + } + + if(iResult > 0) + { + index = m_fileListModel->index(index.row() + 1, index.column()); + ui->sourceFileView->selectRow(index.row()); + continue; + } + else if(iResult < 0) + { + index = m_fileListModel->index(index.row() - 1, index.column()); + ui->sourceFileView->selectRow(index.row()); + continue; + } - if(!iResult) break; + break; /*close dilalog now*/ + } + } + else + { + MUtils::Sound::beep(MUtils::Sound::BEEP_WRN); } - MUTILS_DELETE(metaInfoDialog); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); sourceFilesScrollbarMoved(0); } @@ -2482,17 +2656,10 @@ void MainWindow::findFileContextActionTriggered(void) QModelIndex index = ui->sourceFileView->currentIndex(); if(index.isValid()) { - QString systemRootPath; - - QDir systemRoot(MUtils::OS::known_folder(MUtils::OS::FOLDER_SYSTEMFOLDER)); - if(systemRoot.exists() && systemRoot.cdUp()) - { - systemRootPath = systemRoot.canonicalPath(); - } - - if(!systemRootPath.isEmpty()) + const QString systemToolsPath = MUtils::OS::known_folder(MUtils::OS::FOLDER_SYSROOT); + if(!systemToolsPath.isEmpty()) { - QFileInfo explorer(QString("%1/explorer.exe").arg(systemRootPath)); + QFileInfo explorer(QString("%1/explorer.exe").arg(systemToolsPath)); if(explorer.exists() && explorer.isFile()) { QProcess::execute(explorer.canonicalFilePath(), QStringList() << "/select," << QDir::toNativeSeparators(m_fileListModel->getFile(index).filePath())); @@ -2501,7 +2668,7 @@ void MainWindow::findFileContextActionTriggered(void) } else { - qWarning("SystemRoot directory could not be detected!"); + qWarning("System tools directory could not be detected!"); } } } @@ -2517,7 +2684,7 @@ void MainWindow::handleDroppedFiles(void) const QString bannerText = tr("Loading dropped files or folders, please wait..."); bool bUseBanner = false; - SHOW_BANNER_CONDITIONALLY(bUseBanner, (m_droppedFileList->count() >= MIN_COUNT), bannerText); + showBanner(bannerText, bUseBanner, (m_droppedFileList->count() >= MIN_COUNT)); QStringList droppedFiles; while(!m_droppedFileList->isEmpty()) @@ -2525,38 +2692,25 @@ void MainWindow::handleDroppedFiles(void) QFileInfo file(m_droppedFileList->takeFirst().toLocalFile()); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); - if(!file.exists()) - { - continue; - } - - if(file.isFile()) - { - qDebug("Dropped File: %s", MUTILS_UTF8(file.canonicalFilePath())); - droppedFiles << file.canonicalFilePath(); - continue; - } - - if(file.isDir()) + if(file.exists()) { - qDebug("Dropped Folder: %s", MUTILS_UTF8(file.canonicalFilePath())); - QFileInfoList list = QDir(file.canonicalFilePath()).entryInfoList(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks); - if(list.count() > 0) + if(file.isFile()) { - SHOW_BANNER_CONDITIONALLY(bUseBanner, (list.count() >= MIN_COUNT), bannerText); - for(QFileInfoList::ConstIterator iter = list.constBegin(); iter != list.constEnd(); iter++) - { - droppedFiles << (*iter).canonicalFilePath(); - } + qDebug("Dropped File: %s", MUTILS_UTF8(file.canonicalFilePath())); + droppedFiles << file.canonicalFilePath(); + continue; } - else + else if(file.isDir()) { - list = QDir(file.canonicalFilePath()).entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); - SHOW_BANNER_CONDITIONALLY(bUseBanner, (list.count() >= MIN_COUNT), bannerText); - for(QFileInfoList::ConstIterator iter = list.constBegin(); iter != list.constEnd(); iter++) + qDebug("Dropped Folder: %s", MUTILS_UTF8(file.canonicalFilePath())); + QFileInfoList list = QDir(file.canonicalFilePath()).entryInfoList(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks); + if(list.count() > 0) { - qDebug("Descending to Folder: %s", MUTILS_UTF8((*iter).canonicalFilePath())); - m_droppedFileList->prepend(QUrl::fromLocalFile((*iter).canonicalFilePath())); + showBanner(bannerText, bUseBanner, (list.count() >= MIN_COUNT)); + for(QFileInfoList::ConstIterator iter = list.constBegin(); iter != list.constEnd(); iter++) + { + droppedFiles << (*iter).canonicalFilePath(); + } } } } @@ -2591,8 +2745,12 @@ void MainWindow::handleDelayedFiles(void) return; } - WITH_BLOCKED_SIGNALS(ui->tabWidget, setCurrentIndex, 0); - tabPageChanged(ui->tabWidget->currentIndex(), true); + if(ui->tabWidget->currentIndex() != 0) + { + SignalBlockHelper signalBlockHelper(ui->tabWidget); + ui->tabWidget->setCurrentIndex(0); + tabPageChanged(ui->tabWidget->currentIndex(), true); + } QStringList selectedFiles; while(!m_delayedFileList->isEmpty()) @@ -2613,49 +2771,48 @@ void MainWindow::handleDelayedFiles(void) */ void MainWindow::exportCsvContextActionTriggered(void) { - TEMP_HIDE_DROPBOX - ( - QString selectedCsvFile; - - if(MUtils::GUI::themes_enabled()) - { - selectedCsvFile = QFileDialog::getSaveFileName(this, tr("Save CSV file"), m_settings->mostRecentInputPath(), QString("%1 (*.csv)").arg(tr("CSV File"))); - } - else + ABORT_IF_BUSY; + WidgetHideHelper hiderHelper(m_dropBox.data()); + + QString selectedCsvFile; + if(MUtils::GUI::themes_enabled()) + { + selectedCsvFile = QFileDialog::getSaveFileName(this, tr("Save CSV file"), m_settings->mostRecentInputPath(), QString("%1 (*.csv)").arg(tr("CSV File"))); + } + else + { + QFileDialog dialog(this, tr("Save CSV file")); + dialog.setFileMode(QFileDialog::AnyFile); + dialog.setAcceptMode(QFileDialog::AcceptSave); + dialog.setNameFilter(QString("%1 (*.csv)").arg(tr("CSV File"))); + dialog.setDirectory(m_settings->mostRecentInputPath()); + if(dialog.exec()) { - QFileDialog dialog(this, tr("Save CSV file")); - dialog.setFileMode(QFileDialog::AnyFile); - dialog.setAcceptMode(QFileDialog::AcceptSave); - dialog.setNameFilter(QString("%1 (*.csv)").arg(tr("CSV File"))); - dialog.setDirectory(m_settings->mostRecentInputPath()); - if(dialog.exec()) - { - selectedCsvFile = dialog.selectedFiles().first(); - } + selectedCsvFile = dialog.selectedFiles().first(); } + } - if(!selectedCsvFile.isEmpty()) + if(!selectedCsvFile.isEmpty()) + { + m_settings->mostRecentInputPath(QFileInfo(selectedCsvFile).canonicalPath()); + switch(m_fileListModel->exportToCsv(selectedCsvFile)) { - m_settings->mostRecentInputPath(QFileInfo(selectedCsvFile).canonicalPath()); - switch(m_fileListModel->exportToCsv(selectedCsvFile)) - { - case FileListModel::CsvError_NoTags: - QMessageBox::critical(this, tr("CSV Export"), NOBR(tr("Sorry, there are no meta tags that can be exported!"))); - break; - case FileListModel::CsvError_FileOpen: - QMessageBox::critical(this, tr("CSV Export"), NOBR(tr("Sorry, failed to open CSV file for writing!"))); - break; - case FileListModel::CsvError_FileWrite: - QMessageBox::critical(this, tr("CSV Export"), NOBR(tr("Sorry, failed to write to the CSV file!"))); - break; - case FileListModel::CsvError_OK: - QMessageBox::information(this, tr("CSV Export"), NOBR(tr("The CSV files was created successfully!"))); - break; - default: - qWarning("exportToCsv: Unknown return code!"); - } + case FileListModel::CsvError_NoTags: + QMessageBox::critical(this, tr("CSV Export"), NOBREAK(tr("Sorry, there are no meta tags that can be exported!"))); + break; + case FileListModel::CsvError_FileOpen: + QMessageBox::critical(this, tr("CSV Export"), NOBREAK(tr("Sorry, failed to open CSV file for writing!"))); + break; + case FileListModel::CsvError_FileWrite: + QMessageBox::critical(this, tr("CSV Export"), NOBREAK(tr("Sorry, failed to write to the CSV file!"))); + break; + case FileListModel::CsvError_OK: + QMessageBox::information(this, tr("CSV Export"), NOBREAK(tr("The CSV files was created successfully!"))); + break; + default: + qWarning("exportToCsv: Unknown return code!"); } - ); + } } @@ -2664,54 +2821,53 @@ void MainWindow::exportCsvContextActionTriggered(void) */ void MainWindow::importCsvContextActionTriggered(void) { - TEMP_HIDE_DROPBOX - ( - QString selectedCsvFile; - - if(MUtils::GUI::themes_enabled()) - { - selectedCsvFile = QFileDialog::getOpenFileName(this, tr("Open CSV file"), m_settings->mostRecentInputPath(), QString("%1 (*.csv)").arg(tr("CSV File"))); - } - else + ABORT_IF_BUSY; + WidgetHideHelper hiderHelper(m_dropBox.data()); + + QString selectedCsvFile; + if(MUtils::GUI::themes_enabled()) + { + selectedCsvFile = QFileDialog::getOpenFileName(this, tr("Open CSV file"), m_settings->mostRecentInputPath(), QString("%1 (*.csv)").arg(tr("CSV File"))); + } + else + { + QFileDialog dialog(this, tr("Open CSV file")); + dialog.setFileMode(QFileDialog::ExistingFile); + dialog.setNameFilter(QString("%1 (*.csv)").arg(tr("CSV File"))); + dialog.setDirectory(m_settings->mostRecentInputPath()); + if(dialog.exec()) { - QFileDialog dialog(this, tr("Open CSV file")); - dialog.setFileMode(QFileDialog::ExistingFile); - dialog.setNameFilter(QString("%1 (*.csv)").arg(tr("CSV File"))); - dialog.setDirectory(m_settings->mostRecentInputPath()); - if(dialog.exec()) - { - selectedCsvFile = dialog.selectedFiles().first(); - } + selectedCsvFile = dialog.selectedFiles().first(); } + } - if(!selectedCsvFile.isEmpty()) + if(!selectedCsvFile.isEmpty()) + { + m_settings->mostRecentInputPath(QFileInfo(selectedCsvFile).canonicalPath()); + switch(m_fileListModel->importFromCsv(this, selectedCsvFile)) { - m_settings->mostRecentInputPath(QFileInfo(selectedCsvFile).canonicalPath()); - switch(m_fileListModel->importFromCsv(this, selectedCsvFile)) - { - case FileListModel::CsvError_FileOpen: - QMessageBox::critical(this, tr("CSV Import"), NOBR(tr("Sorry, failed to open CSV file for reading!"))); - break; - case FileListModel::CsvError_FileRead: - QMessageBox::critical(this, tr("CSV Import"), NOBR(tr("Sorry, failed to read from the CSV file!"))); - break; - case FileListModel::CsvError_NoTags: - QMessageBox::critical(this, tr("CSV Import"), NOBR(tr("Sorry, the CSV file does not contain any known fields!"))); - break; - case FileListModel::CsvError_Incomplete: - QMessageBox::warning(this, tr("CSV Import"), NOBR(tr("CSV file is incomplete. Not all files were updated!"))); - break; - case FileListModel::CsvError_OK: - QMessageBox::information(this, tr("CSV Import"), NOBR(tr("The CSV files was imported successfully!"))); - break; - case FileListModel::CsvError_Aborted: - /* User aborted, ignore! */ - break; - default: - qWarning("exportToCsv: Unknown return code!"); - } + case FileListModel::CsvError_FileOpen: + QMessageBox::critical(this, tr("CSV Import"), NOBREAK(tr("Sorry, failed to open CSV file for reading!"))); + break; + case FileListModel::CsvError_FileRead: + QMessageBox::critical(this, tr("CSV Import"), NOBREAK(tr("Sorry, failed to read from the CSV file!"))); + break; + case FileListModel::CsvError_NoTags: + QMessageBox::critical(this, tr("CSV Import"), NOBREAK(tr("Sorry, the CSV file does not contain any known fields!"))); + break; + case FileListModel::CsvError_Incomplete: + QMessageBox::warning(this, tr("CSV Import"), NOBREAK(tr("CSV file is incomplete. Not all files were updated!"))); + break; + case FileListModel::CsvError_OK: + QMessageBox::information(this, tr("CSV Import"), NOBREAK(tr("The CSV files was imported successfully!"))); + break; + case FileListModel::CsvError_Aborted: + /* User aborted, ignore! */ + break; + default: + qWarning("exportToCsv: Unknown return code!"); } - ); + } } /* @@ -2773,13 +2929,13 @@ void MainWindow::gotoDesktopButtonClicked(void) return; } - QString desktopPath = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation); + const QString desktopPath = MUtils::OS::known_folder(MUtils::OS::FOLDER_DESKTOP_USER); if(!desktopPath.isEmpty() && QDir(desktopPath).exists()) { ui->outputFolderView->setCurrentIndex(m_fileSystemModel->index(desktopPath)); outputFolderViewClicked(ui->outputFolderView->currentIndex()); - CENTER_CURRENT_OUTPUT_FOLDER_DELAYED; + CENTER_CURRENT_OUTPUT_FOLDER_DELAYED(); } else { @@ -2798,13 +2954,13 @@ void MainWindow::gotoHomeFolderButtonClicked(void) return; } - QString homePath = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); - + const QString homePath = MUtils::OS::known_folder(MUtils::OS::FOLDER_PROFILE_USER); + if(!homePath.isEmpty() && QDir(homePath).exists()) { ui->outputFolderView->setCurrentIndex(m_fileSystemModel->index(homePath)); outputFolderViewClicked(ui->outputFolderView->currentIndex()); - CENTER_CURRENT_OUTPUT_FOLDER_DELAYED; + CENTER_CURRENT_OUTPUT_FOLDER_DELAYED(); } else { @@ -2823,13 +2979,13 @@ void MainWindow::gotoMusicFolderButtonClicked(void) return; } - QString musicPath = QDesktopServices::storageLocation(QDesktopServices::MusicLocation); + const QString musicPath = MUtils::OS::known_folder(MUtils::OS::FOLDER_MUSIC_USER); if(!musicPath.isEmpty() && QDir(musicPath).exists()) { ui->outputFolderView->setCurrentIndex(m_fileSystemModel->index(musicPath)); outputFolderViewClicked(ui->outputFolderView->currentIndex()); - CENTER_CURRENT_OUTPUT_FOLDER_DELAYED; + CENTER_CURRENT_OUTPUT_FOLDER_DELAYED(); } else { @@ -2857,7 +3013,7 @@ void MainWindow::gotoFavoriteFolder(void) { ui->outputFolderView->setCurrentIndex(m_fileSystemModel->index(path.canonicalPath())); outputFolderViewClicked(ui->outputFolderView->currentIndex()); - CENTER_CURRENT_OUTPUT_FOLDER_DELAYED; + CENTER_CURRENT_OUTPUT_FOLDER_DELAYED(); } else { @@ -2875,7 +3031,7 @@ void MainWindow::makeFolderButtonClicked(void) { ABORT_IF_BUSY; - if(!m_fileSystemModel) + if(m_fileSystemModel.isNull()) { qWarning("File system model not initialized yet!"); return; @@ -2894,7 +3050,7 @@ void MainWindow::makeFolderButtonClicked(void) } else if(!m_metaData->album().isEmpty()) { - suggestedName =m_metaData->album(); + suggestedName = m_metaData->album(); } else { @@ -2922,7 +3078,7 @@ void MainWindow::makeFolderButtonClicked(void) } } - suggestedName = MUtils::clean_file_name(suggestedName); + suggestedName = MUtils::clean_file_name(suggestedName, true); while(true) { @@ -2931,7 +3087,7 @@ void MainWindow::makeFolderButtonClicked(void) if(bApplied) { - folderName = MUtils::clean_file_path(folderName.simplified()); + folderName = MUtils::clean_file_path(folderName.simplified(), true); if(folderName.isEmpty()) { @@ -2955,12 +3111,12 @@ void MainWindow::makeFolderButtonClicked(void) QModelIndex newIndex = m_fileSystemModel->index(createdDir.canonicalPath()); ui->outputFolderView->setCurrentIndex(newIndex); outputFolderViewClicked(newIndex); - CENTER_CURRENT_OUTPUT_FOLDER_DELAYED; + CENTER_CURRENT_OUTPUT_FOLDER_DELAYED(); } } else { - QMessageBox::warning(this, tr("Failed to create folder"), QString("%1
%2

%3").arg(tr("The new folder could not be created:"), basePath.absoluteFilePath(newFolder), tr("Drive is read-only or insufficient access rights!"))); + QMessageBox::warning(this, tr("Failed to create folder"), NOBREAK(QString("%1
%2

%3").arg(tr("The new folder could not be created:"), basePath.absoluteFilePath(newFolder), tr("Drive is read-only or insufficient access rights!")))); } } break; @@ -3041,7 +3197,7 @@ void MainWindow::goUpFolderContextActionTriggered(void) { MUtils::Sound::beep(MUtils::Sound::BEEP_WRN); } - CENTER_CURRENT_OUTPUT_FOLDER_DELAYED; + CENTER_CURRENT_OUTPUT_FOLDER_DELAYED(); } } @@ -3127,7 +3283,7 @@ void MainWindow::outputFolderEditFinished(void) ui->outputFolderView->setEnabled(true); if(!ok) MUtils::Sound::beep(MUtils::Sound::BEEP_ERR); - CENTER_CURRENT_OUTPUT_FOLDER_DELAYED; + CENTER_CURRENT_OUTPUT_FOLDER_DELAYED(); } /* @@ -3144,17 +3300,17 @@ void MainWindow::initOutputFolderModel(void) if(m_fileSystemModel) { SET_MODEL(ui->outputFolderView, NULL); - MUTILS_DELETE(m_fileSystemModel); ui->outputFolderView->repaint(); } - if(m_fileSystemModel = new QFileSystemModelEx()) + m_fileSystemModel.reset(new QFileSystemModelEx()); + if(!m_fileSystemModel.isNull()) { m_fileSystemModel->installEventFilter(this); - connect(m_fileSystemModel, SIGNAL(directoryLoaded(QString)), this, SLOT(outputFolderDirectoryLoaded(QString))); - connect(m_fileSystemModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(outputFolderRowsInserted(QModelIndex,int,int))); + connect(m_fileSystemModel.data(), SIGNAL(directoryLoaded(QString)), this, SLOT(outputFolderDirectoryLoaded(QString))); + connect(m_fileSystemModel.data(), SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(outputFolderRowsInserted(QModelIndex,int,int))); - SET_MODEL(ui->outputFolderView, m_fileSystemModel); + SET_MODEL(ui->outputFolderView, m_fileSystemModel.data()); ui->outputFolderView->header()->setStretchLastSection(true); ui->outputFolderView->header()->hideSection(1); ui->outputFolderView->header()->hideSection(2); @@ -3166,7 +3322,7 @@ void MainWindow::initOutputFolderModel(void) outputFolderViewClicked(ui->outputFolderView->currentIndex()); } - CENTER_CURRENT_OUTPUT_FOLDER_DELAYED; + CENTER_CURRENT_OUTPUT_FOLDER_DELAYED(); QTimer::singleShot(125, this, SLOT(initOutputFolderModel_doAsync())); } } @@ -3183,7 +3339,7 @@ void MainWindow::initOutputFolderModel_doAsync(void) } else { - QTimer::singleShot(125, m_outputFolderNoteBox, SLOT(hide())); + QTimer::singleShot(125, m_outputFolderNoteBox.data(), SLOT(hide())); ui->outputFolderView->setFocus(); } } @@ -3221,7 +3377,7 @@ void MainWindow::outputFolderDirectoryLoaded(const QString &path) { if(m_outputFolderViewCentering) { - CENTER_CURRENT_OUTPUT_FOLDER_DELAYED; + CENTER_CURRENT_OUTPUT_FOLDER_DELAYED(); } } @@ -3232,7 +3388,7 @@ void MainWindow::outputFolderRowsInserted(const QModelIndex &parent, int start, { if(m_outputFolderViewCentering) { - CENTER_CURRENT_OUTPUT_FOLDER_DELAYED; + CENTER_CURRENT_OUTPUT_FOLDER_DELAYED(); } } @@ -3474,15 +3630,17 @@ void MainWindow::updateRCMode(int id) //Update slider min/max values if(valueCount > 0) { - WITH_BLOCKED_SIGNALS(ui->sliderBitrate, setEnabled, true); - WITH_BLOCKED_SIGNALS(ui->sliderBitrate, setMinimum, 0); - WITH_BLOCKED_SIGNALS(ui->sliderBitrate, setMaximum, valueCount-1); + SignalBlockHelper signalBlockHelper(ui->sliderBitrate); + ui->sliderBitrate->setEnabled(true); + ui->sliderBitrate->setMinimum(0); + ui->sliderBitrate->setMaximum(valueCount-1); } else { - WITH_BLOCKED_SIGNALS(ui->sliderBitrate, setEnabled, false); - WITH_BLOCKED_SIGNALS(ui->sliderBitrate, setMinimum, 0); - WITH_BLOCKED_SIGNALS(ui->sliderBitrate, setMaximum, 2); + SignalBlockHelper signalBlockHelper(ui->sliderBitrate); + ui->sliderBitrate->setEnabled(false); + ui->sliderBitrate->setMinimum(0); + ui->sliderBitrate->setMaximum(2); } //Now update bitrate/quality value! @@ -3739,6 +3897,16 @@ void MainWindow::opusSettingsChanged(void) void MainWindow::normalizationEnabledChanged(bool checked) { m_settings->normalizationFilterEnabled(checked); + normalizationDynamicChanged(ui->checkBoxNormalizationFilterDynamic->isChecked()); +} + +/* + * Dynamic normalization enabled changed + */ +void MainWindow::normalizationDynamicChanged(bool checked) +{ + ui->spinBoxNormalizationFilterSize->setEnabled(ui->checkBoxNormalizationFilterEnabled->isChecked() && checked); + m_settings->normalizationFilterDynamic(checked); } /* @@ -3752,9 +3920,30 @@ void MainWindow::normalizationMaxVolumeChanged(double value) /* * Normalization equalization mode changed */ -void MainWindow::normalizationModeChanged(int mode) +void MainWindow::normalizationCoupledChanged(bool checked) +{ + m_settings->normalizationFilterCoupled(checked); +} + +/* + * Normalization filter size changed + */ +void MainWindow::normalizationFilterSizeChanged(int value) +{ + m_settings->normalizationFilterSize(value); +} + +/* + * Normalization filter size editing finished + */ +void MainWindow::normalizationFilterSizeFinished(void) { - m_settings->normalizationFilterEQMode(mode); + const int value = ui->spinBoxNormalizationFilterSize->value(); + if((value % 2) != 1) + { + bool rnd = MUtils::parity(MUtils::next_rand_u32()); + ui->spinBoxNormalizationFilterSize->setValue(rnd ? value+1 : value-1); + } } /* @@ -3819,11 +4008,29 @@ void MainWindow::customParamsChanged(void) } /* + * One of the rename buttons has been clicked + */ +void MainWindow::renameButtonClicked(bool checked) +{ + if(QPushButton *const button = dynamic_cast(QObject::sender())) + { + QWidget *pages[] = { ui->pageRename_Rename, ui->pageRename_RegExp, ui->pageRename_FileEx }; + QPushButton *buttons[] = { ui->buttonRename_Rename, ui->buttonRename_RegExp, ui->buttonRename_FileEx }; + for(int i = 0; i < 3; i++) + { + const bool match = (button == buttons[i]); + buttons[i]->setChecked(match); + if(match && checked) ui->stackedWidget->setCurrentWidget(pages[i]); + } + } +} + +/* * Rename output files enabled changed */ -void MainWindow::renameOutputEnabledChanged(bool checked) +void MainWindow::renameOutputEnabledChanged(const bool &checked) { - m_settings->renameOutputFilesEnabled(checked); + m_settings->renameFiles_renameEnabled(checked); } /* @@ -3832,14 +4039,14 @@ void MainWindow::renameOutputEnabledChanged(bool checked) void MainWindow::renameOutputPatternChanged(void) { QString temp = ui->lineEditRenamePattern->text().simplified(); - ui->lineEditRenamePattern->setText(temp.isEmpty() ? m_settings->renameOutputFilesPatternDefault() : temp); - m_settings->renameOutputFilesPattern(ui->lineEditRenamePattern->text()); + ui->lineEditRenamePattern->setText(temp.isEmpty() ? m_settings->renameFiles_renamePatternDefault() : temp); + m_settings->renameFiles_renamePattern(ui->lineEditRenamePattern->text()); } /* * Rename output files patterm changed */ -void MainWindow::renameOutputPatternChanged(const QString &text, bool silent) +void MainWindow::renameOutputPatternChanged(const QString &text, const bool &silent) { QString pattern(text.simplified()); @@ -3851,7 +4058,7 @@ void MainWindow::renameOutputPatternChanged(const QString &text, bool silent) pattern.replace("", "2001", Qt::CaseInsensitive); pattern.replace("", "Encoded by LameXP", Qt::CaseInsensitive); - const QString patternClean = MUtils::clean_file_name(pattern); + const QString patternClean = MUtils::clean_file_name(pattern, false); if(pattern.compare(patternClean)) { @@ -3874,13 +4081,107 @@ void MainWindow::renameOutputPatternChanged(const QString &text, bool silent) } /* + * Regular expression enabled changed + */ +void MainWindow::renameRegExpEnabledChanged(const bool &checked) +{ + m_settings->renameFiles_regExpEnabled(checked); +} + +/* + * Regular expression value has changed + */ +void MainWindow::renameRegExpValueChanged(void) +{ + const QString search = ui->lineEditRenameRegExp_Search->text() .trimmed(); + const QString replace = ui->lineEditRenameRegExp_Replace->text().simplified(); + ui->lineEditRenameRegExp_Search ->setText(search.isEmpty() ? m_settings->renameFiles_regExpSearchDefault() : search); + ui->lineEditRenameRegExp_Replace->setText(replace.isEmpty() ? m_settings->renameFiles_regExpReplaceDefault() : replace); + m_settings->renameFiles_regExpSearch (ui->lineEditRenameRegExp_Search ->text()); + m_settings->renameFiles_regExpReplace(ui->lineEditRenameRegExp_Replace->text()); +} + +/* + * Regular expression search pattern has changed + */ +void MainWindow::renameRegExpSearchChanged(const QString &text, const bool &silent) +{ + const QString pattern(text.trimmed()); + + if((!pattern.isEmpty()) && (!QRegExp(pattern.trimmed()).isValid())) + { + if(ui->lineEditRenameRegExp_Search->palette().color(QPalette::Text) != Qt::red) + { + if(!silent) MUtils::Sound::beep(MUtils::Sound::BEEP_ERR); + SET_TEXT_COLOR(ui->lineEditRenameRegExp_Search, Qt::red); + } + } + else + { + if(ui->lineEditRenameRegExp_Search->palette() != QPalette()) + { + if(!silent) MUtils::Sound::beep(MUtils::Sound::BEEP_NFO); + ui->lineEditRenameRegExp_Search->setPalette(QPalette()); + } + } + + renameRegExpReplaceChanged(ui->lineEditRenameRegExp_Replace->text(), silent); +} + +/* + * Regular expression replacement string changed + */ +void MainWindow::renameRegExpReplaceChanged(const QString &text, const bool &silent) +{ + QString replacement(text.simplified()); + const QString search(ui->lineEditRenameRegExp_Search->text().trimmed()); + + if(!search.isEmpty()) + { + const QRegExp regexp(search); + if(regexp.isValid()) + { + const int count = regexp.captureCount(); + const QString blank; + for(int i = 0; i < count; i++) + { + replacement.replace(QString("\\%0").arg(QString::number(i+1)), blank); + } + } + } + + if(replacement.compare(MUtils::clean_file_name(replacement, false))) + { + if(ui->lineEditRenameRegExp_Replace->palette().color(QPalette::Text) != Qt::red) + { + if(!silent) MUtils::Sound::beep(MUtils::Sound::BEEP_ERR); + SET_TEXT_COLOR(ui->lineEditRenameRegExp_Replace, Qt::red); + } + } + else + { + if(ui->lineEditRenameRegExp_Replace->palette() != QPalette()) + { + if(!silent) MUtils::Sound::beep(MUtils::Sound::BEEP_NFO); + ui->lineEditRenameRegExp_Replace->setPalette(QPalette()); + } + } +} + +/* * Show list of rename macros */ void MainWindow::showRenameMacros(const QString &text) { if(text.compare("reset", Qt::CaseInsensitive) == 0) { - ui->lineEditRenamePattern->setText(m_settings->renameOutputFilesPatternDefault()); + ui->lineEditRenamePattern->setText(m_settings->renameFiles_renamePatternDefault()); + return; + } + + if(text.compare("regexp", Qt::CaseInsensitive) == 0) + { + MUtils::OS::shell_open(this, "http://www.regular-expressions.info/quickstart.html"); return; } @@ -3901,6 +4202,38 @@ void MainWindow::showRenameMacros(const QString &text) QMessageBox::information(this, tr("Rename Macros"), message, tr("Discard")); } +void MainWindow::fileExtAddButtonClicked(void) +{ + if(FileExtsModel *const model = dynamic_cast(ui->tableViewFileExts->model())) + { + model->addOverwrite(this); + } +} + +void MainWindow::fileExtRemoveButtonClicked(void) +{ + if(FileExtsModel *const model = dynamic_cast(ui->tableViewFileExts->model())) + { + const QModelIndex selected = ui->tableViewFileExts->currentIndex(); + if(selected.isValid()) + { + model->removeOverwrite(selected); + } + else + { + MUtils::Sound::beep(MUtils::Sound::BEEP_ERR); + } + } +} + +void MainWindow::fileExtModelChanged(void) +{ + if(FileExtsModel *const model = dynamic_cast(ui->tableViewFileExts->model())) + { + m_settings->renameFiles_fileExtension(model->exportItems()); + } +} + void MainWindow::forceStereoDownmixEnabledChanged(bool checked) { m_settings->forceStereoDownmix(checked); @@ -3909,18 +4242,19 @@ void MainWindow::forceStereoDownmixEnabledChanged(bool checked) /* * Maximum number of instances changed */ -void MainWindow::updateMaximumInstances(int value) +void MainWindow::updateMaximumInstances(const int value) { - ui->labelMaxInstances->setText(tr("%n Instance(s)", "", value)); - m_settings->maximumInstances(ui->checkBoxAutoDetectInstances->isChecked() ? NULL : value); + const quint32 instances = decodeInstances(qBound(1U, static_cast(value), 32U)); + m_settings->maximumInstances(ui->checkBoxAutoDetectInstances->isChecked() ? 0U : instances); + ui->labelMaxInstances->setText(tr("%n Instance(s)", "", static_cast(instances))); } /* * Auto-detect number of instances */ -void MainWindow::autoDetectInstancesChanged(bool checked) +void MainWindow::autoDetectInstancesChanged(const bool checked) { - m_settings->maximumInstances(checked ? NULL : ui->sliderMaxInstances->value()); + m_settings->maximumInstances(checked ? 0U : decodeInstances(qBound(1U, static_cast(ui->sliderMaxInstances->value()), 32U))); } /* @@ -3947,7 +4281,7 @@ void MainWindow::browseCustomTempFolderButtonClicked(void) if(!newTempFolder.isEmpty()) { - QFile writeTest(QString("%1/~%2.tmp").arg(newTempFolder, MUtils::rand_str())); + QFile writeTest(QString("%1/~%2.tmp").arg(newTempFolder, MUtils::next_rand_str())); if(writeTest.open(QIODevice::ReadWrite)) { writeTest.remove(); @@ -3995,20 +4329,21 @@ void MainWindow::customParamsHelpRequested(QWidget *obj, QEvent *event) } } - if(obj == ui->helpCustomParamLAME) showCustomParamsHelpScreen("lame.exe", "--longhelp"); + if(obj == ui->helpCustomParamLAME) showCustomParamsHelpScreen("lame.exe", "--longhelp"); else if(obj == ui->helpCustomParamOggEnc) showCustomParamsHelpScreen("oggenc2.exe", "--help"); else if(obj == ui->helpCustomParamNeroAAC) { switch(EncoderRegistry::getAacEncoder()) { - case SettingsModel::AAC_ENCODER_QAAC: showCustomParamsHelpScreen("qaac.exe", "--help"); break; - case SettingsModel::AAC_ENCODER_FHG : showCustomParamsHelpScreen("fhgaacenc.exe", ""); break; - case SettingsModel::AAC_ENCODER_NERO: showCustomParamsHelpScreen("neroAacEnc.exe", "-help"); break; + case SettingsModel::AAC_ENCODER_QAAC: showCustomParamsHelpScreen("qaac64.exe|qaac.exe", "--help"); break; + case SettingsModel::AAC_ENCODER_FHG : showCustomParamsHelpScreen("fhgaacenc.exe", "" ); break; + case SettingsModel::AAC_ENCODER_FDK : showCustomParamsHelpScreen("fdkaac.exe", "--help"); break; + case SettingsModel::AAC_ENCODER_NERO: showCustomParamsHelpScreen("neroAacEnc.exe", "-help" ); break; default: MUtils::Sound::beep(MUtils::Sound::BEEP_ERR); break; } } - else if(obj == ui->helpCustomParamFLAC) showCustomParamsHelpScreen("flac.exe", "--help"); - else if(obj == ui->helpCustomParamAften) showCustomParamsHelpScreen("aften.exe", "-h"); + else if(obj == ui->helpCustomParamFLAC) showCustomParamsHelpScreen("flac.exe", "--help"); + else if(obj == ui->helpCustomParamAften) showCustomParamsHelpScreen("aften.exe", "-h" ); else if(obj == ui->helpCustomParamOpus) showCustomParamsHelpScreen("opusenc.exe", "--help"); else MUtils::Sound::beep(MUtils::Sound::BEEP_ERR); } @@ -4018,7 +4353,17 @@ void MainWindow::customParamsHelpRequested(QWidget *obj, QEvent *event) */ void MainWindow::showCustomParamsHelpScreen(const QString &toolName, const QString &command) { - const QString binary = lamexp_tools_lookup(toolName); + const QStringList toolNames = toolName.split('|', QString::SkipEmptyParts); + QString binary; + for(QStringList::ConstIterator iter = toolNames.constBegin(); iter != toolNames.constEnd(); iter++) + { + if(lamexp_tools_check(*iter)) + { + binary = lamexp_tools_lookup(*iter); + break; + } + } + if(binary.isEmpty()) { MUtils::Sound::beep(MUtils::Sound::BEEP_ERR); @@ -4068,11 +4413,15 @@ void MainWindow::showCustomParamsHelpScreen(const QString &toolName, const QStri MUtils::Sound::beep(MUtils::Sound::BEEP_ERR); } - LogViewDialog *dialog = new LogViewDialog(this); - TEMP_HIDE_DROPBOX( dialog->exec(output); ); - MUTILS_DELETE(dialog); + WidgetHideHelper hiderHelper(m_dropBox.data()); + QScopedPointer dialog(new LogViewDialog(this)); + dialog->exec(output); } +/* +* File overwrite mode has changed +*/ + void MainWindow::overwriteModeChanged(int id) { if((id == SettingsModel::Overwrite_Replaces) && (m_settings->overwriteMode() != SettingsModel::Overwrite_Replaces)) @@ -4089,52 +4438,74 @@ void MainWindow::overwriteModeChanged(int id) } /* +* Keep original date/time opertion changed +*/ +void MainWindow::keepOriginalDateTimeChanged(bool checked) +{ + m_settings->keepOriginalDataTime(checked); +} + +/* * Reset all advanced options to their defaults */ void MainWindow::resetAdvancedOptionsButtonClicked(void) { PLAY_SOUND_OPTIONAL("blast", true); - ui->sliderLameAlgoQuality->setValue(m_settings->lameAlgoQualityDefault()); - ui->spinBoxBitrateManagementMin->setValue(m_settings->bitrateManagementMinRateDefault()); - ui->spinBoxBitrateManagementMax->setValue(m_settings->bitrateManagementMaxRateDefault()); - ui->spinBoxNormalizationFilter->setValue(static_cast(m_settings->normalizationFilterMaxVolumeDefault()) / 100.0); - ui->spinBoxToneAdjustBass->setValue(static_cast(m_settings->toneAdjustBassDefault()) / 100.0); - ui->spinBoxToneAdjustTreble->setValue(static_cast(m_settings->toneAdjustTrebleDefault()) / 100.0); - ui->spinBoxAftenSearchSize->setValue(m_settings->aftenExponentSearchSizeDefault()); - ui->spinBoxOpusComplexity->setValue(m_settings->opusComplexityDefault()); - ui->comboBoxMP3ChannelMode->setCurrentIndex(m_settings->lameChannelModeDefault()); - ui->comboBoxSamplingRate->setCurrentIndex(m_settings->samplingRateDefault()); - ui->comboBoxAACProfile->setCurrentIndex(m_settings->aacEncProfileDefault()); - ui->comboBoxAftenCodingMode->setCurrentIndex(m_settings->aftenAudioCodingModeDefault()); - ui->comboBoxAftenDRCMode->setCurrentIndex(m_settings->aftenDynamicRangeCompressionDefault()); - ui->comboBoxNormalizationMode->setCurrentIndex(m_settings->normalizationFilterEQModeDefault()); - ui->comboBoxOpusFramesize->setCurrentIndex(m_settings->opusFramesizeDefault()); - - SET_CHECKBOX_STATE(ui->checkBoxBitrateManagement, m_settings->bitrateManagementEnabledDefault()); - SET_CHECKBOX_STATE(ui->checkBoxNeroAAC2PassMode, m_settings->neroAACEnable2PassDefault()); - SET_CHECKBOX_STATE(ui->checkBoxNormalizationFilter, m_settings->normalizationFilterEnabledDefault()); - SET_CHECKBOX_STATE(ui->checkBoxAutoDetectInstances, (m_settings->maximumInstancesDefault() < 1)); - SET_CHECKBOX_STATE(ui->checkBoxUseSystemTempFolder, !m_settings->customTempPathEnabledDefault()); - SET_CHECKBOX_STATE(ui->checkBoxAftenFastAllocation, m_settings->aftenFastBitAllocationDefault()); - SET_CHECKBOX_STATE(ui->checkBoxRenameOutput, m_settings->renameOutputFilesEnabledDefault()); - SET_CHECKBOX_STATE(ui->checkBoxForceStereoDownmix, m_settings->forceStereoDownmixDefault()); - SET_CHECKBOX_STATE(ui->checkBoxOpusDisableResample, m_settings->opusDisableResampleDefault()); - - ui->lineEditCustomParamLAME ->setText(m_settings->customParametersLAMEDefault()); - ui->lineEditCustomParamOggEnc ->setText(m_settings->customParametersOggEncDefault()); - ui->lineEditCustomParamNeroAAC->setText(m_settings->customParametersAacEncDefault()); - ui->lineEditCustomParamFLAC ->setText(m_settings->customParametersFLACDefault()); - ui->lineEditCustomParamOpus ->setText(m_settings->customParametersOpusEncDefault()); - ui->lineEditCustomTempFolder ->setText(QDir::toNativeSeparators(m_settings->customTempPathDefault())); - ui->lineEditRenamePattern ->setText(m_settings->renameOutputFilesPatternDefault()); + ui->sliderLameAlgoQuality ->setValue(m_settings->lameAlgoQualityDefault()); + ui->spinBoxBitrateManagementMin ->setValue(m_settings->bitrateManagementMinRateDefault()); + ui->spinBoxBitrateManagementMax ->setValue(m_settings->bitrateManagementMaxRateDefault()); + ui->spinBoxNormalizationFilterPeak->setValue(static_cast(m_settings->normalizationFilterMaxVolumeDefault()) / 100.0); + ui->spinBoxNormalizationFilterSize->setValue(m_settings->normalizationFilterSizeDefault()); + ui->spinBoxToneAdjustBass ->setValue(static_cast(m_settings->toneAdjustBassDefault()) / 100.0); + ui->spinBoxToneAdjustTreble ->setValue(static_cast(m_settings->toneAdjustTrebleDefault()) / 100.0); + ui->spinBoxAftenSearchSize ->setValue(m_settings->aftenExponentSearchSizeDefault()); + ui->spinBoxOpusComplexity ->setValue(m_settings->opusComplexityDefault()); + ui->comboBoxMP3ChannelMode ->setCurrentIndex(m_settings->lameChannelModeDefault()); + ui->comboBoxSamplingRate ->setCurrentIndex(m_settings->samplingRateDefault()); + ui->comboBoxAACProfile ->setCurrentIndex(m_settings->aacEncProfileDefault()); + ui->comboBoxAftenCodingMode ->setCurrentIndex(m_settings->aftenAudioCodingModeDefault()); + ui->comboBoxAftenDRCMode ->setCurrentIndex(m_settings->aftenDynamicRangeCompressionDefault()); + ui->comboBoxOpusFramesize ->setCurrentIndex(m_settings->opusFramesizeDefault()); + + SET_CHECKBOX_STATE(ui->checkBoxBitrateManagement, m_settings->bitrateManagementEnabledDefault()); + SET_CHECKBOX_STATE(ui->checkBoxNeroAAC2PassMode, m_settings->neroAACEnable2PassDefault()); + SET_CHECKBOX_STATE(ui->checkBoxNormalizationFilterEnabled, m_settings->normalizationFilterEnabledDefault()); + SET_CHECKBOX_STATE(ui->checkBoxNormalizationFilterDynamic, m_settings->normalizationFilterDynamicDefault()); + SET_CHECKBOX_STATE(ui->checkBoxNormalizationFilterCoupled, m_settings->normalizationFilterCoupledDefault()); + SET_CHECKBOX_STATE(ui->checkBoxAutoDetectInstances, (m_settings->maximumInstancesDefault() < 1)); + SET_CHECKBOX_STATE(ui->checkBoxUseSystemTempFolder, (!m_settings->customTempPathEnabledDefault())); + SET_CHECKBOX_STATE(ui->checkBoxAftenFastAllocation, m_settings->aftenFastBitAllocationDefault()); + SET_CHECKBOX_STATE(ui->checkBoxRename_Rename, m_settings->renameFiles_renameEnabledDefault()); + SET_CHECKBOX_STATE(ui->checkBoxRename_RegExp, m_settings->renameFiles_regExpEnabledDefault()); + SET_CHECKBOX_STATE(ui->checkBoxForceStereoDownmix, m_settings->forceStereoDownmixDefault()); + SET_CHECKBOX_STATE(ui->checkBoxOpusDisableResample, m_settings->opusDisableResampleDefault()); + SET_CHECKBOX_STATE(ui->checkBoxKeepOriginalDateTime, m_settings->keepOriginalDataTimeDefault()); + + ui->lineEditCustomParamLAME ->setText(m_settings->customParametersLAMEDefault()); + ui->lineEditCustomParamOggEnc ->setText(m_settings->customParametersOggEncDefault()); + ui->lineEditCustomParamNeroAAC ->setText(m_settings->customParametersAacEncDefault()); + ui->lineEditCustomParamFLAC ->setText(m_settings->customParametersFLACDefault()); + ui->lineEditCustomParamOpus ->setText(m_settings->customParametersOpusEncDefault()); + ui->lineEditCustomTempFolder ->setText(QDir::toNativeSeparators(m_settings->customTempPathDefault())); + ui->lineEditRenamePattern ->setText(m_settings->renameFiles_renamePatternDefault()); + ui->lineEditRenameRegExp_Search ->setText(m_settings->renameFiles_regExpSearchDefault()); + ui->lineEditRenameRegExp_Replace->setText(m_settings->renameFiles_regExpReplaceDefault()); if(m_settings->overwriteModeDefault() == SettingsModel::Overwrite_KeepBoth) ui->radioButtonOverwriteModeKeepBoth->click(); if(m_settings->overwriteModeDefault() == SettingsModel::Overwrite_SkipFile) ui->radioButtonOverwriteModeSkipFile->click(); if(m_settings->overwriteModeDefault() == SettingsModel::Overwrite_Replaces) ui->radioButtonOverwriteModeReplaces->click(); - customParamsChanged(); + if(FileExtsModel *const model = dynamic_cast(ui->tableViewFileExts->model())) + { + model->importItems(m_settings->renameFiles_fileExtensionDefault()); + } + ui->scrollArea->verticalScrollBar()->setValue(0); + ui->buttonRename_Rename->click(); + customParamsChanged(); + renameOutputPatternChanged(); + renameRegExpValueChanged(); } // =========================================================