From ed774d4f0f5d367402ad59dddff09b0a1abab564 Mon Sep 17 00:00:00 2001 From: lordmulder Date: Fri, 10 Feb 2012 18:42:16 +0100 Subject: [PATCH] Implemented asynchronous handling of dropped files, so the source application gets unblocked ASAP. Also added Drag&Drop support to the "Add Job" dialog. --- src/version.h | 2 +- src/win_addJob.cpp | 50 +++++++++++++++++++-- src/win_addJob.h | 2 + src/win_main.cpp | 129 +++++++++++++++++++++++++++++++++++++++++++++++------ src/win_main.h | 2 + 5 files changed, 168 insertions(+), 17 deletions(-) diff --git a/src/version.h b/src/version.h index 3ae7a83..945c1ba 100644 --- a/src/version.h +++ b/src/version.h @@ -21,7 +21,7 @@ #define VER_X264_MAJOR 2 #define VER_X264_MINOR 0 -#define VER_X264_PATCH 81 +#define VER_X264_PATCH 101 #define VER_X264_MINIMUM_REV 2146 #define VER_X264_CURRENT_API 120 diff --git a/src/win_addJob.cpp b/src/win_addJob.cpp index 14c6c53..0acf0d8 100644 --- a/src/win_addJob.cpp +++ b/src/win_addJob.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #define VALID_DIR(PATH) ((!(PATH).isEmpty()) && QFileInfo(PATH).exists() && QFileInfo(PATH).isDir()) @@ -189,7 +190,7 @@ AddJobDialog::AddJobDialog(QWidget *parent, OptionsModel *options, bool x64suppo connect(cbxTemplate, SIGNAL(currentIndexChanged(int)), this, SLOT(templateSelected())); //Load directories - const QString appDir = x264_portable() ? QApplication::applicationDirPath() : QDesktopServices::storageLocation(QDesktopServices::DataLocation); + const QString appDir = x264_data_path(); QSettings settings(QString("%1/last.ini").arg(appDir), QSettings::IniFormat); initialDir_src = settings.value("path/directory_openFrom", initialDir_src).toString(); initialDir_out = settings.value("path/directory_saveTo", initialDir_out).toString(); @@ -249,6 +250,49 @@ bool AddJobDialog::eventFilter(QObject *o, QEvent *e) return false; } +void AddJobDialog::dragEnterEvent(QDragEnterEvent *event) +{ + QStringList formats = event->mimeData()->formats(); + + if(formats.contains("application/x-qt-windows-mime;value=\"FileNameW\"", Qt::CaseInsensitive) && formats.contains("text/uri-list", Qt::CaseInsensitive)) + { + event->acceptProposedAction(); + } +} + +void AddJobDialog::dropEvent(QDropEvent *event) +{ + QString droppedFile; + QList urls = event->mimeData()->urls(); + + if(urls.count() > 1) + { + QDragEnterEvent dragEvent(event->pos(), event->proposedAction(), event->mimeData(), Qt::NoButton, Qt::NoModifier); + if(qApp->notify(parent(), &dragEvent)) + { + qApp->notify(parent(), event); + reject(); return; + } + } + + while((!urls.isEmpty()) && droppedFile.isEmpty()) + { + QUrl currentUrl = urls.takeFirst(); + QFileInfo file(currentUrl.toLocalFile()); + if(file.exists() && file.isFile()) + { + qDebug("AddJobDialog::dropEvent: %s", file.canonicalFilePath().toUtf8().constData()); + droppedFile = file.canonicalFilePath(); + } + } + + if(!droppedFile.isEmpty()) + { + editSource->setText(QDir::toNativeSeparators(droppedFile)); + generateOutputFileName(droppedFile); + } +} + /////////////////////////////////////////////////////////////////////////////// // Slots /////////////////////////////////////////////////////////////////////////////// @@ -295,7 +339,7 @@ void AddJobDialog::accept(void) } if(outputFile.exists() && (!outputFile.isFile())) { - QMessageBox::warning(this, tr("Not a File!"), tr("Selected output files does not appear to be a file!")); + QMessageBox::warning(this, tr("Not a File!"), tr("Selected output file does not appear to be a valid file!")); return; } if(!editCustomParams->hasAcceptableInput()) @@ -305,7 +349,7 @@ void AddJobDialog::accept(void) } //Save directories - const QString appDir = x264_portable() ? QApplication::applicationDirPath() : QDesktopServices::storageLocation(QDesktopServices::DataLocation); + const QString appDir = x264_data_path(); QSettings settings(QString("%1/last.ini").arg(appDir), QSettings::IniFormat); if(settings.isWritable()) { diff --git a/src/win_addJob.h b/src/win_addJob.h index a07510c..eea023a 100644 --- a/src/win_addJob.h +++ b/src/win_addJob.h @@ -56,6 +56,8 @@ protected: virtual void showEvent(QShowEvent *event); virtual bool eventFilter(QObject *o, QEvent *e); + virtual void dragEnterEvent(QDragEnterEvent *event); + virtual void dropEvent(QDropEvent *event); private slots: void modeIndexChanged(int index); diff --git a/src/win_main.cpp b/src/win_main.cpp index c3e6a8e..4e281b3 100644 --- a/src/win_main.cpp +++ b/src/win_main.cpp @@ -52,10 +52,16 @@ const char *tpl_last = ""; // Constructor & Destructor /////////////////////////////////////////////////////////////////////////////// +/* + * Constructor + */ MainWindow::MainWindow(const x264_cpu_t *const cpuFeatures) : m_cpuFeatures(cpuFeatures), m_appDir(QApplication::applicationDirPath()), + m_options(NULL), + m_jobList(NULL), + m_droppedFiles(NULL), m_firstShow(true) { //Init the dialog, from the .ui file @@ -149,12 +155,16 @@ MainWindow::MainWindow(const x264_cpu_t *const cpuFeatures) updateLabelPos(); } +/* + * Destructor + */ MainWindow::~MainWindow(void) { OptionsModel::saveTemplate(m_options, QString::fromLatin1(tpl_last)); X264_DELETE(m_jobList); X264_DELETE(m_options); + X264_DELETE(m_droppedFiles); X264_DELETE(m_label); while(!m_toolsList.isEmpty()) @@ -168,8 +178,13 @@ MainWindow::~MainWindow(void) // Slots /////////////////////////////////////////////////////////////////////////////// +/* + * The "add" button was clicked + */ void MainWindow::addButtonPressed(const QString &filePath, int fileNo, int fileTotal, bool *ok) { + qDebug("MainWindow::addButtonPressed"); + if(ok) *ok = false; AddJobDialog *addDialog = new AddJobDialog(this, m_options, m_cpuFeatures->x64); @@ -209,22 +224,34 @@ void MainWindow::addButtonPressed(const QString &filePath, int fileNo, int fileT X264_DELETE(addDialog); } +/* + * The "start" button was clicked + */ void MainWindow::startButtonPressed(void) { m_jobList->startJob(jobsView->currentIndex()); } +/* + * The "abort" button was clicked + */ void MainWindow::abortButtonPressed(void) { m_jobList->abortJob(jobsView->currentIndex()); } +/* + * The "delete" button was clicked + */ void MainWindow::deleteButtonPressed(void) { m_jobList->deleteJob(jobsView->currentIndex()); m_label->setVisible(m_jobList->rowCount(QModelIndex()) == 0); } +/* + * The "browse" button was clicked + */ void MainWindow::browseButtonPressed(void) { QString outputFile = m_jobList->getJobOutputFile(jobsView->currentIndex()); @@ -238,6 +265,9 @@ void MainWindow::browseButtonPressed(void) } } +/* + * The "pause" button was clicked + */ void MainWindow::pauseButtonPressed(bool checked) { if(checked) @@ -250,6 +280,9 @@ void MainWindow::pauseButtonPressed(bool checked) } } +/* + * Job item selected by user + */ void MainWindow::jobSelected(const QModelIndex & current, const QModelIndex & previous) { qDebug("Job selected: %d", current.row()); @@ -284,6 +317,9 @@ void MainWindow::jobSelected(const QModelIndex & current, const QModelIndex & pr progressBar->repaint(); } +/* + * Handle update of job info (status, progress, details, etc) + */ void MainWindow::jobChangedData(const QModelIndex &topLeft, const QModelIndex &bottomRight) { int selected = jobsView->currentIndex().row(); @@ -331,11 +367,17 @@ void MainWindow::jobChangedData(const QModelIndex &topLeft, const QModelIndex & } } +/* + * Handle new log file content + */ void MainWindow::jobLogExtended(const QModelIndex & parent, int start, int end) { QTimer::singleShot(0, logView, SLOT(scrollToBottom())); } +/* + * About screen + */ void MainWindow::showAbout(void) { QString text; @@ -387,6 +429,9 @@ void MainWindow::showAbout(void) } } +/* + * Open web-link + */ void MainWindow::showWebLink(void) { if(QObject::sender() == actionWebMulder) QDesktopServices::openUrl(QUrl(home_url)); @@ -401,6 +446,9 @@ void MainWindow::showWebLink(void) if(QObject::sender() == actionWebSecret) QDesktopServices::openUrl(QUrl("http://www.youtube.com/watch_popup?v=AXIeHY-OYNI")); } +/* + * Pereferences dialog + */ void MainWindow::showPreferences(void) { PreferencesDialog *preferences = new PreferencesDialog(this, &m_preferences, m_cpuFeatures->x64); @@ -408,6 +456,9 @@ void MainWindow::showPreferences(void) X264_DELETE(preferences); } +/* + * Launch next job, after running job has finished + */ void MainWindow::launchNextJob(void) { qDebug("launchNextJob(void)"); @@ -440,6 +491,9 @@ void MainWindow::launchNextJob(void) qWarning("No enqueued jobs left!"); } +/* + * Shut down the computer (with countdown) + */ void MainWindow::shutdownComputer(void) { qDebug("shutdownComputer(void)"); @@ -503,6 +557,9 @@ void MainWindow::shutdownComputer(void) } } +/* + * Main initialization function (called only once!) + */ void MainWindow::init(void) { static const char *binFiles = "x264.exe:x264_x64.exe:avs2yuv.exe:avs2yuv_x64.exe"; @@ -546,7 +603,7 @@ void MainWindow::init(void) { bool ok = false; static const char *data = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; - QFile writeTest(QString("%1/%2").arg(QApplication::applicationDirPath(), QUuid::createUuid().toString())); + QFile writeTest(QString("%1/%2").arg(x264_data_path(), QUuid::createUuid().toString())); if(writeTest.open(QIODevice::WriteOnly)) { ok = (writeTest.write(data) == strlen(data)); @@ -640,12 +697,18 @@ void MainWindow::init(void) } } +/* + * Update the label position + */ void MainWindow::updateLabelPos(void) { const QWidget *const viewPort = jobsView->viewport(); m_label->setGeometry(0, 0, viewPort->width(), viewPort->height()); } +/* + * Copy the complete log to the clipboard + */ void MainWindow::copyLogToClipboard(bool checked) { qDebug("copyLogToClipboard"); @@ -657,10 +720,35 @@ void MainWindow::copyLogToClipboard(bool checked) } } +/* + * Process the dropped files + */ +void MainWindow::handleDroppedFiles(void) +{ + qDebug("MainWindow::handleDroppedFiles"); + if(m_droppedFiles) + { + QStringList droppedFiles(*m_droppedFiles); + m_droppedFiles->clear(); + int totalFiles = droppedFiles.count(); + bool ok = true; int n = 0; + while((!droppedFiles.isEmpty()) && ok) + { + QString currentFile = droppedFiles.takeFirst(); + qDebug("Adding file: %s", currentFile.toUtf8().constData()); + addButtonPressed(currentFile, n++, totalFiles, &ok); + } + } + qDebug("Leave from MainWindow::handleDroppedFiles!"); +} + /////////////////////////////////////////////////////////////////////////////// // Event functions /////////////////////////////////////////////////////////////////////////////// +/* + * Window shown event + */ void MainWindow::showEvent(QShowEvent *e) { QMainWindow::showEvent(e); @@ -672,6 +760,9 @@ void MainWindow::showEvent(QShowEvent *e) } } +/* + * Window close event + */ void MainWindow::closeEvent(QCloseEvent *e) { if(countRunningJobs() > 0) @@ -706,6 +797,9 @@ void MainWindow::closeEvent(QCloseEvent *e) QMainWindow::closeEvent(e); } +/* + * Window resize event + */ void MainWindow::resizeEvent(QResizeEvent *e) { QMainWindow::resizeEvent(e); @@ -760,20 +854,20 @@ void MainWindow::dropEvent(QDropEvent *event) QFileInfo file(currentUrl.toLocalFile()); if(file.exists() && file.isFile()) { - qDebug("Dropped File: %s", file.canonicalFilePath().toUtf8().constData()); + qDebug("MainWindow::dropEvent: %s", file.canonicalFilePath().toUtf8().constData()); droppedFiles << file.canonicalFilePath(); } } - droppedFiles.sort(); - int totalFiles = droppedFiles.count(); - - bool ok = true; int n = 0; - while((!droppedFiles.isEmpty()) && ok) + if(droppedFiles.count() > 0) { - QString currentFile = droppedFiles.takeFirst(); - qDebug("Adding file: %s", currentFile.toUtf8().constData()); - addButtonPressed(currentFile, n++, totalFiles, &ok); + if(!m_droppedFiles) + { + m_droppedFiles = new QStringList(); + } + m_droppedFiles->append(droppedFiles); + m_droppedFiles->sort(); + QTimer::singleShot(0, this, SLOT(handleDroppedFiles())); } } @@ -781,7 +875,9 @@ void MainWindow::dropEvent(QDropEvent *event) // Private functions /////////////////////////////////////////////////////////////////////////////// -/*Jobs that are not completed (or failed, or aborted) yet*/ +/* + * Jobs that are not completed (or failed, or aborted) yet + */ unsigned int MainWindow::countPendingJobs(void) { unsigned int count = 0; @@ -799,7 +895,9 @@ unsigned int MainWindow::countPendingJobs(void) return count; } -/*Jobs that are still active, i.e. not terminated or enqueued*/ +/* + * Jobs that are still active, i.e. not terminated or enqueued + */ unsigned int MainWindow::countRunningJobs(void) { unsigned int count = 0; @@ -817,6 +915,9 @@ unsigned int MainWindow::countRunningJobs(void) return count; } +/* + * Update all buttons with respect to current job status + */ void MainWindow::updateButtons(EncodeThread::JobStatus status) { qDebug("MainWindow::updateButtons(void)"); @@ -837,7 +938,9 @@ void MainWindow::updateButtons(EncodeThread::JobStatus status) editDetails->setEnabled(status != EncodeThread::JobStatus_Paused); } - +/* + * Update the taskbar with current job status + */ void MainWindow::updateTaskbar(EncodeThread::JobStatus status, const QIcon &icon) { qDebug("MainWindow::updateTaskbar(void)"); diff --git a/src/win_main.h b/src/win_main.h index 8c33488..9ae0ad0 100644 --- a/src/win_main.h +++ b/src/win_main.h @@ -53,6 +53,7 @@ private: JobListModel *m_jobList; OptionsModel *m_options; + QStringList *m_droppedFiles; QList m_toolsList; PreferencesDialog::Preferences m_preferences; @@ -71,6 +72,7 @@ private slots: void browseButtonPressed(void); void deleteButtonPressed(void); void copyLogToClipboard(bool checked); + void handleDroppedFiles(void); void init(void); void jobSelected(const QModelIndex & current, const QModelIndex & previous); void jobChangedData(const QModelIndex &top, const QModelIndex &bottom); -- 2.11.0