+ if(!m_dropBox->isVisible())
+ {
+ m_dropBox->show();
+ }
+
+ lamexp_blink_window(m_dropBox);
+}
+
+/*
+ * Check for beta (pre-release) updates
+ */
+void MainWindow::checkForBetaUpdatesActionTriggered(bool checked)
+{
+ bool checkUpdatesNow = false;
+
+ 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::information(this, tr("Beta Updates"), NOBR(tr("LameXP will check for Beta (pre-release) updates from now on.")), tr("Check Now"), tr("Discard")))
+ {
+ checkUpdatesNow = true;
+ }
+ m_settings->autoUpdateCheckBeta(true);
+ }
+ else
+ {
+ m_settings->autoUpdateCheckBeta(false);
+ }
+ }
+ else
+ {
+ QMessageBox::information(this, tr("Beta Updates"), NOBR(tr("LameXP will <i>not</i> check for Beta (pre-release) updates from now on.")));
+ m_settings->autoUpdateCheckBeta(false);
+ }
+
+ actionCheckForBetaUpdates->setChecked(m_settings->autoUpdateCheckBeta());
+
+ if(checkUpdatesNow)
+ {
+ if(checkForUpdates())
+ {
+ QApplication::quit();
+ }
+ }
+}
+
+/*
+ * Hibernate computer action
+ */
+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))
+ {
+ QMessageBox::information(this, tr("Hibernate Computer"), NOBR(tr("LameXP will hibernate the computer on shutdown from now on.")));
+ m_settings->hibernateComputer(true);
+ }
+ else
+ {
+ m_settings->hibernateComputer(false);
+ }
+ }
+ else
+ {
+ QMessageBox::information(this, tr("Hibernate Computer"), NOBR(tr("LameXP will <i>not</i> hibernate the computer on shutdown from now on.")));
+ m_settings->hibernateComputer(false);
+ }
+
+ actionHibernateComputer->setChecked(m_settings->hibernateComputer());
+}
+
+/*
+ * Disable shell integration action
+ */
+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))
+ {
+ ShellIntegration::remove();
+ QMessageBox::information(this, tr("Shell Integration"), NOBR(tr("The LameXP shell integration has been disabled.")));
+ m_settings->shellIntegrationEnabled(false);
+ }
+ else
+ {
+ m_settings->shellIntegrationEnabled(true);
+ }
+ }
+ else
+ {
+ ShellIntegration::install();
+ QMessageBox::information(this, tr("Shell Integration"), NOBR(tr("The LameXP shell integration has been re-enabled.")));
+ m_settings->shellIntegrationEnabled(true);
+ }
+
+ actionDisableShellIntegration->setChecked(!m_settings->shellIntegrationEnabled());
+
+ if(lamexp_portable_mode() && actionDisableShellIntegration->isChecked())
+ {
+ actionDisableShellIntegration->setEnabled(false);
+ }
+}
+
+// =========================================================
+// Help menu slots
+// =========================================================
+
+/*
+ * Visit homepage action
+ */
+void MainWindow::visitHomepageActionActivated(void)
+{
+ if(QAction *action = dynamic_cast<QAction*>(QObject::sender()))
+ {
+ if(action->data().isValid() && (action->data().type() == QVariant::String))
+ {
+ QDesktopServices::openUrl(QUrl(action->data().toString()));
+ }
+ }
+}
+
+/*
+ * Show document
+ */
+void MainWindow::documentActionActivated(void)
+{
+ if(QAction *action = dynamic_cast<QAction*>(QObject::sender()))
+ {
+ if(action->data().isValid() && (action->data().type() == QVariant::String))
+ {
+ QFileInfo document(action->data().toString());
+ QFileInfo resource(QString(":/doc/%1.html").arg(document.baseName()));
+ if(document.exists() && document.isFile() && (document.size() == resource.size()))
+ {
+ QDesktopServices::openUrl(QUrl::fromLocalFile(document.canonicalFilePath()));
+ }
+ else
+ {
+ QFile source(resource.filePath());
+ QFile output(QString("%1/%2.%3.html").arg(lamexp_temp_folder2(), document.baseName(), lamexp_rand_str().left(8)));
+ if(source.open(QIODevice::ReadOnly) && output.open(QIODevice::ReadWrite))
+ {
+ output.write(source.readAll());
+ action->setData(output.fileName());
+ source.close();
+ output.close();
+ QDesktopServices::openUrl(QUrl::fromLocalFile(output.fileName()));
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Check for updates action
+ */
+void MainWindow::checkUpdatesActionActivated(void)
+{
+ ABORT_IF_BUSY;
+ bool bFlag = false;
+
+ TEMP_HIDE_DROPBOX
+ (
+ bFlag = checkForUpdates();
+ )
+
+ if(bFlag)
+ {
+ QApplication::quit();
+ }
+}
+
+// =========================================================
+// Source file slots
+// =========================================================
+
+/*
+ * Add file(s) button
+ */
+void MainWindow::addFilesButtonClicked(void)
+{
+ ABORT_IF_BUSY;
+
+ TEMP_HIDE_DROPBOX
+ (
+ if(USE_NATIVE_FILE_DIALOG)
+ {
+ 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 selectedFiles = dialog.selectedFiles();
+ if(!selectedFiles.isEmpty())
+ {
+ m_settings->mostRecentInputPath(QFileInfo(selectedFiles.first()).canonicalPath());
+ addFiles(selectedFiles);
+ }
+ }
+ }
+ )
+}
+
+/*
+ * Open folder action
+ */
+void MainWindow::openFolderActionActivated(void)
+{
+ ABORT_IF_BUSY;
+ QString selectedFolder;
+
+ if(QAction *action = dynamic_cast<QAction*>(QObject::sender()))
+ {
+ TEMP_HIDE_DROPBOX
+ (
+ if(USE_NATIVE_FILE_DIALOG)
+ {
+ 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())
+ {
+ m_settings->mostRecentInputPath(QDir(selectedFolder).canonicalPath());
+ addFolder(selectedFolder, action->data().toBool());
+ }
+ )
+ }
+}
+
+/*
+ * Remove file button
+ */
+void MainWindow::removeFileButtonClicked(void)
+{
+ if(sourceFileView->currentIndex().isValid())
+ {
+ int iRow = sourceFileView->currentIndex().row();
+ m_fileListModel->removeFile(sourceFileView->currentIndex());
+ sourceFileView->selectRow(iRow < m_fileListModel->rowCount() ? iRow : m_fileListModel->rowCount()-1);
+ }
+}
+
+/*
+ * Clear files button
+ */
+void MainWindow::clearFilesButtonClicked(void)
+{
+ m_fileListModel->clearFiles();
+}
+
+/*
+ * Move file up button
+ */
+void MainWindow::fileUpButtonClicked(void)
+{
+ if(sourceFileView->currentIndex().isValid())
+ {
+ int iRow = sourceFileView->currentIndex().row() - 1;
+ m_fileListModel->moveFile(sourceFileView->currentIndex(), -1);
+ sourceFileView->selectRow(iRow >= 0 ? iRow : 0);
+ }
+}
+
+/*
+ * Move file down button
+ */
+void MainWindow::fileDownButtonClicked(void)
+{
+ if(sourceFileView->currentIndex().isValid())
+ {
+ int iRow = sourceFileView->currentIndex().row() + 1;
+ m_fileListModel->moveFile(sourceFileView->currentIndex(), 1);
+ sourceFileView->selectRow(iRow < m_fileListModel->rowCount() ? iRow : m_fileListModel->rowCount()-1);
+ }
+}
+
+/*
+ * Show details button
+ */
+void MainWindow::showDetailsButtonClicked(void)
+{
+ ABORT_IF_BUSY;
+
+ int iResult = 0;
+ MetaInfoDialog *metaInfoDialog = new MetaInfoDialog(this);
+ QModelIndex index = sourceFileView->currentIndex();
+
+ while(index.isValid())
+ {
+ if(iResult > 0)
+ {
+ index = m_fileListModel->index(index.row() + 1, index.column());
+ sourceFileView->selectRow(index.row());
+ }
+ if(iResult < 0)
+ {
+ index = m_fileListModel->index(index.row() - 1, index.column());
+ sourceFileView->selectRow(index.row());
+ }
+
+ AudioFileModel &file = (*m_fileListModel)[index];
+ TEMP_HIDE_DROPBOX
+ (
+ iResult = metaInfoDialog->exec(file, index.row() > 0, index.row() < m_fileListModel->rowCount() - 1);
+ )
+
+ if(iResult == INT_MAX)
+ {
+ m_metaInfoModel->assignInfoFrom(file);
+ tabWidget->setCurrentIndex(tabWidget->indexOf(tabMetaData));
+ break;
+ }
+
+ if(!iResult) break;
+ }
+
+ LAMEXP_DELETE(metaInfoDialog);
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+ sourceFilesScrollbarMoved(0);
+}
+
+/*
+ * Show context menu for source files
+ */
+void MainWindow::sourceFilesContextMenu(const QPoint &pos)
+{
+ QAbstractScrollArea *scrollArea = dynamic_cast<QAbstractScrollArea*>(QObject::sender());
+ QWidget *sender = scrollArea ? scrollArea->viewport() : dynamic_cast<QWidget*>(QObject::sender());
+
+ if(sender)
+ {
+ if(pos.x() <= sender->width() && pos.y() <= sender->height() && pos.x() >= 0 && pos.y() >= 0)
+ {
+ m_sourceFilesContextMenu->popup(sender->mapToGlobal(pos));
+ }
+ }
+}
+
+/*
+ * Scrollbar of source files moved
+ */
+void MainWindow::sourceFilesScrollbarMoved(int)
+{
+ sourceFileView->resizeColumnToContents(0);
+}
+
+/*
+ * Open selected file in external player
+ */
+void MainWindow::previewContextActionTriggered(void)
+{
+ const static char *appNames[3] = {"smplayer_portable.exe", "smplayer.exe", "mplayer.exe"};
+ const static wchar_t *registryKey = L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{DB9E4EAB-2717-499F-8D56-4CC8A644AB60}";
+
+ QModelIndex index = sourceFileView->currentIndex();
+ if(!index.isValid())
+ {
+ return;
+ }
+
+ QString mplayerPath;
+ HKEY registryKeyHandle;
+
+ if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, registryKey, 0, KEY_READ, ®istryKeyHandle) == ERROR_SUCCESS)
+ {
+ wchar_t Buffer[4096];
+ DWORD BuffSize = sizeof(wchar_t*) * 4096;
+ if(RegQueryValueExW(registryKeyHandle, L"InstallLocation", 0, 0, reinterpret_cast<BYTE*>(Buffer), &BuffSize) == ERROR_SUCCESS)
+ {
+ mplayerPath = QString::fromUtf16(reinterpret_cast<const unsigned short*>(Buffer));
+ }
+ }
+
+ if(!mplayerPath.isEmpty())
+ {
+ QDir mplayerDir(mplayerPath);
+ if(mplayerDir.exists())
+ {
+ for(int i = 0; i < 3; i++)
+ {
+ if(mplayerDir.exists(appNames[i]))
+ {
+ QProcess::startDetached(mplayerDir.absoluteFilePath(appNames[i]), QStringList() << QDir::toNativeSeparators(m_fileListModel->getFile(index).filePath()));
+ return;
+ }
+ }
+ }
+ }
+
+ QDesktopServices::openUrl(QString("file:///").append(m_fileListModel->getFile(index).filePath()));
+}
+
+/*
+ * Find selected file in explorer
+ */
+void MainWindow::findFileContextActionTriggered(void)
+{
+ QModelIndex index = sourceFileView->currentIndex();
+ if(index.isValid())
+ {
+ QString systemRootPath;
+
+ QDir systemRoot(lamexp_known_folder(lamexp_folder_systemfolder));
+ if(systemRoot.exists() && systemRoot.cdUp())
+ {
+ systemRootPath = systemRoot.canonicalPath();
+ }
+
+ if(!systemRootPath.isEmpty())
+ {
+ QFileInfo explorer(QString("%1/explorer.exe").arg(systemRootPath));
+ if(explorer.exists() && explorer.isFile())
+ {
+ QProcess::execute(explorer.canonicalFilePath(), QStringList() << "/select," << QDir::toNativeSeparators(m_fileListModel->getFile(index).filePath()));
+ return;
+ }
+ }
+ else
+ {
+ qWarning("SystemRoot directory could not be detected!");
+ }
+ }
+}
+
+/*
+ * Add all pending files
+ */
+void MainWindow::handleDelayedFiles(void)
+{
+ m_delayedFileTimer->stop();
+
+ if(m_delayedFileList->isEmpty())
+ {
+ return;
+ }
+
+ if(m_banner->isVisible())
+ {
+ m_delayedFileTimer->start(5000);
+ return;
+ }
+
+ QStringList selectedFiles;
+ tabWidget->setCurrentIndex(0);
+
+ while(!m_delayedFileList->isEmpty())
+ {
+ QFileInfo currentFile = QFileInfo(m_delayedFileList->takeFirst());
+ if(!currentFile.exists() || !currentFile.isFile())
+ {
+ continue;
+ }
+ selectedFiles << currentFile.canonicalFilePath();
+ }
+
+ addFiles(selectedFiles);
+}
+
+/*
+ * Show or hide Drag'n'Drop notice after model reset
+ */
+void MainWindow::sourceModelChanged(void)
+{
+ m_dropNoteLabel->setVisible(m_fileListModel->rowCount() <= 0);
+}
+
+// =========================================================
+// Output folder slots
+// =========================================================
+
+/*
+ * Output folder changed (mouse clicked)
+ */
+void MainWindow::outputFolderViewClicked(const QModelIndex &index)
+{
+ if(outputFolderView->currentIndex() != index)
+ {
+ outputFolderView->setCurrentIndex(index);
+ }
+ QString selectedDir = m_fileSystemModel->filePath(index);
+ if(selectedDir.length() < 3) selectedDir.append(QDir::separator());
+ outputFolderLabel->setText(QDir::toNativeSeparators(selectedDir));
+ m_settings->outputDir(selectedDir);
+}
+
+/*
+ * Output folder changed (mouse moved)
+ */
+void MainWindow::outputFolderViewMoved(const QModelIndex &index)
+{
+ if(QApplication::mouseButtons() & Qt::LeftButton)
+ {
+ outputFolderViewClicked(index);
+ }
+}
+
+/*
+ * Goto desktop button
+ */
+void MainWindow::gotoDesktopButtonClicked(void)
+{
+ QString desktopPath = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation);
+
+ if(!desktopPath.isEmpty() && QDir(desktopPath).exists())
+ {
+ outputFolderView->setCurrentIndex(m_fileSystemModel->index(desktopPath));
+ outputFolderViewClicked(outputFolderView->currentIndex());
+ outputFolderView->setFocus();
+ }
+ else
+ {
+ buttonGotoDesktop->setEnabled(false);
+ }
+}
+
+/*
+ * Goto home folder button
+ */
+void MainWindow::gotoHomeFolderButtonClicked(void)
+{
+ QString homePath = QDesktopServices::storageLocation(QDesktopServices::HomeLocation);
+
+ if(!homePath.isEmpty() && QDir(homePath).exists())
+ {
+ outputFolderView->setCurrentIndex(m_fileSystemModel->index(homePath));
+ outputFolderViewClicked(outputFolderView->currentIndex());
+ outputFolderView->setFocus();
+ }
+ else
+ {
+ buttonGotoHome->setEnabled(false);
+ }
+}
+
+/*
+ * Goto music folder button
+ */
+void MainWindow::gotoMusicFolderButtonClicked(void)
+{
+ QString musicPath = QDesktopServices::storageLocation(QDesktopServices::MusicLocation);
+
+ if(!musicPath.isEmpty() && QDir(musicPath).exists())
+ {
+ outputFolderView->setCurrentIndex(m_fileSystemModel->index(musicPath));
+ outputFolderViewClicked(outputFolderView->currentIndex());
+ outputFolderView->setFocus();
+ }
+ else
+ {
+ buttonGotoMusic->setEnabled(false);
+ }
+}
+
+/*
+ * Goto music favorite output folder
+ */
+void MainWindow::gotoFavoriteFolder(void)
+{
+ QAction *item = dynamic_cast<QAction*>(QObject::sender());
+
+ if(item)
+ {
+ QDir path(item->data().toString());
+ if(path.exists())
+ {
+ outputFolderView->setCurrentIndex(m_fileSystemModel->index(path.canonicalPath()));
+ outputFolderViewClicked(outputFolderView->currentIndex());
+ outputFolderView->setFocus();
+ }
+ else
+ {
+ MessageBeep(MB_ICONERROR);
+ m_outputFolderFavoritesMenu->removeAction(item);
+ item->deleteLater();
+ }
+ }
+}
+
+/*
+ * Make folder button
+ */
+void MainWindow::makeFolderButtonClicked(void)
+{
+ ABORT_IF_BUSY;
+
+ QDir basePath(m_fileSystemModel->fileInfo(outputFolderView->currentIndex()).absoluteFilePath());
+ QString suggestedName = tr("New Folder");
+
+ if(!m_metaData->fileArtist().isEmpty() && !m_metaData->fileAlbum().isEmpty())
+ {
+ suggestedName = QString("%1 - %2").arg(m_metaData->fileArtist(), m_metaData->fileAlbum());
+ }
+ else if(!m_metaData->fileArtist().isEmpty())
+ {
+ suggestedName = m_metaData->fileArtist();
+ }
+ else if(!m_metaData->fileAlbum().isEmpty())
+ {
+ suggestedName = m_metaData->fileAlbum();
+ }
+ else
+ {
+ for(int i = 0; i < m_fileListModel->rowCount(); i++)
+ {
+ AudioFileModel audioFile = m_fileListModel->getFile(m_fileListModel->index(i, 0));
+ if(!audioFile.fileAlbum().isEmpty() || !audioFile.fileArtist().isEmpty())
+ {
+ if(!audioFile.fileArtist().isEmpty() && !audioFile.fileAlbum().isEmpty())
+ {
+ suggestedName = QString("%1 - %2").arg(audioFile.fileArtist(), audioFile.fileAlbum());
+ }
+ else if(!audioFile.fileArtist().isEmpty())
+ {
+ suggestedName = audioFile.fileArtist();
+ }
+ else if(!audioFile.fileAlbum().isEmpty())
+ {
+ suggestedName = audioFile.fileAlbum();
+ }
+ break;
+ }
+ }
+ }