Make it possible to move jobs up/down the in the queue. Hold CTRL while pressing up/down cursor keys as a shortcut.
This commit is contained in:
parent
cc3d25dfce
commit
f80533f99a
@ -403,6 +403,9 @@
|
|||||||
<addaction name="actionJob_Browse"/>
|
<addaction name="actionJob_Browse"/>
|
||||||
<addaction name="actionJob_Delete"/>
|
<addaction name="actionJob_Delete"/>
|
||||||
<addaction name="actionJob_Restart"/>
|
<addaction name="actionJob_Restart"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionJob_MoveUp"/>
|
||||||
|
<addaction name="actionJob_MoveDown"/>
|
||||||
</widget>
|
</widget>
|
||||||
<addaction name="menuFile"/>
|
<addaction name="menuFile"/>
|
||||||
<addaction name="menuJob"/>
|
<addaction name="menuJob"/>
|
||||||
@ -741,6 +744,30 @@
|
|||||||
<string>Codecs.com Mirror</string>
|
<string>Codecs.com Mirror</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionJob_MoveUp">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../res/resources.qrc">
|
||||||
|
<normaloff>:/buttons/arrow_up.png</normaloff>:/buttons/arrow_up.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Move Up</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionJob_MoveDown">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../res/resources.qrc">
|
||||||
|
<normaloff>:/buttons/arrow_down.png</normaloff>:/buttons/arrow_down.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Move Down</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>buttonAddJob</tabstop>
|
<tabstop>buttonAddJob</tabstop>
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
<file>icons/movie.ico</file>
|
<file>icons/movie.ico</file>
|
||||||
<file>buttons/accept.png</file>
|
<file>buttons/accept.png</file>
|
||||||
<file>buttons/add.png</file>
|
<file>buttons/add.png</file>
|
||||||
|
<file>buttons/arrow_down.png</file>
|
||||||
|
<file>buttons/arrow_up.png</file>
|
||||||
<file>buttons/bomb.png</file>
|
<file>buttons/bomb.png</file>
|
||||||
<file>buttons/book_open.png</file>
|
<file>buttons/book_open.png</file>
|
||||||
<file>buttons/cancel.png</file>
|
<file>buttons/cancel.png</file>
|
||||||
|
@ -184,7 +184,7 @@ bool AbstractEncoder::runEncodingPass(AbstractSource* pipedSource, const QString
|
|||||||
processEncode.waitForFinished(5000);
|
processEncode.waitForFinished(5000);
|
||||||
if(processEncode.state() != QProcess::NotRunning)
|
if(processEncode.state() != QProcess::NotRunning)
|
||||||
{
|
{
|
||||||
qWarning("x264 process still running, going to kill it!");
|
qWarning("Encoder process still running, going to kill it!");
|
||||||
processEncode.kill();
|
processEncode.kill();
|
||||||
processEncode.waitForFinished(-1);
|
processEncode.waitForFinished(-1);
|
||||||
}
|
}
|
||||||
@ -217,7 +217,8 @@ bool AbstractEncoder::runEncodingPass(AbstractSource* pipedSource, const QString
|
|||||||
const int exitCode = processEncode.exitCode();
|
const int exitCode = processEncode.exitCode();
|
||||||
if((exitCode < 0) || (exitCode >= 32))
|
if((exitCode < 0) || (exitCode >= 32))
|
||||||
{
|
{
|
||||||
log(tr("\nFATAL ERROR: The encoder process has crashed, your encode probably is *incomplete* !!!"));
|
log(tr("\nFATAL ERROR: The encoder process has *crashed* -> your encode probably is *incomplete* !!!"));
|
||||||
|
log(tr("Note that this indicates a bug in the current encoder, *not* in Simple x264/x265 Launcher."));
|
||||||
}
|
}
|
||||||
log(tr("\nPROCESS EXITED WITH ERROR CODE: %1").arg(QString::number(exitCode)));
|
log(tr("\nPROCESS EXITED WITH ERROR CODE: %1").arg(QString::number(exitCode)));
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
//x265 version info
|
//x265 version info
|
||||||
static const unsigned int VERSION_X265_MINIMUM_VER = 9;
|
static const unsigned int VERSION_X265_MINIMUM_VER = 9;
|
||||||
static const unsigned int VERSION_X265_MINIMUM_REV = 53;
|
static const unsigned int VERSION_X265_MINIMUM_REV = 68;
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
// Helper Macros
|
// Helper Macros
|
||||||
|
100
src/input_filter.cpp
Normal file
100
src/input_filter.cpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Simple x264 Launcher
|
||||||
|
// Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
//
|
||||||
|
// http://www.gnu.org/licenses/gpl-2.0.txt
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "input_filter.h"
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QHash>
|
||||||
|
|
||||||
|
InputEventFilter::InputEventFilter(QWidget *target)
|
||||||
|
:
|
||||||
|
m_target(target),
|
||||||
|
m_keyMapping(new QHash<int, int>()),
|
||||||
|
m_mouseMapping(new QHash<int, int>())
|
||||||
|
{
|
||||||
|
m_target->installEventFilter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
InputEventFilter::~InputEventFilter(void)
|
||||||
|
{
|
||||||
|
m_target->removeEventFilter(this);
|
||||||
|
X264_DELETE(m_keyMapping);
|
||||||
|
X264_DELETE(m_mouseMapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputEventFilter::addKeyFilter(const int &keyCode, const int &tag)
|
||||||
|
{
|
||||||
|
m_keyMapping->insert(keyCode, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputEventFilter::addMouseFilter(const int &mouseCode, const int &tag)
|
||||||
|
{
|
||||||
|
m_mouseMapping->insert(mouseCode, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputEventFilter::eventFilter(QObject *obj, QEvent *event)
|
||||||
|
{
|
||||||
|
if(obj == m_target)
|
||||||
|
{
|
||||||
|
if(event->type() == QEvent::KeyPress)
|
||||||
|
{
|
||||||
|
QKeyEvent *keyEvent = dynamic_cast<QKeyEvent*>(event);
|
||||||
|
if(keyEvent)
|
||||||
|
{
|
||||||
|
return eventFilter(keyEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(event->type() == QEvent::MouseButtonPress)
|
||||||
|
{
|
||||||
|
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(event);
|
||||||
|
if(mouseEvent)
|
||||||
|
{
|
||||||
|
return eventFilter(mouseEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputEventFilter::eventFilter(QKeyEvent *keyEvent)
|
||||||
|
{
|
||||||
|
const int keyCode = keyEvent->key() | keyEvent->modifiers();
|
||||||
|
if(m_keyMapping->contains(keyCode))
|
||||||
|
{
|
||||||
|
emit keyPressed(m_keyMapping->value(keyCode));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputEventFilter::eventFilter(QMouseEvent *mouseEvent)
|
||||||
|
{
|
||||||
|
if(m_mouseMapping->contains(mouseEvent->button()))
|
||||||
|
{
|
||||||
|
emit mouseClicked(m_mouseMapping->value(mouseEvent->button()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
53
src/input_filter.h
Normal file
53
src/input_filter.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Simple x264 Launcher
|
||||||
|
// Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
//
|
||||||
|
// http://www.gnu.org/licenses/gpl-2.0.txt
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
template<class K, class T> class QHash;
|
||||||
|
class QKeyEvent;
|
||||||
|
class QMouseEvent;
|
||||||
|
|
||||||
|
class InputEventFilter : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
InputEventFilter(QWidget *target);
|
||||||
|
~InputEventFilter(void);
|
||||||
|
|
||||||
|
void addKeyFilter(const int &keyCode, const int &tag);
|
||||||
|
void addMouseFilter(const int &keyCode, const int &tag);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void keyPressed(const int &tag);
|
||||||
|
void mouseClicked(const int &tag);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event);
|
||||||
|
bool eventFilter(QKeyEvent *keyEvent);
|
||||||
|
bool eventFilter(QMouseEvent *mouseEvent);
|
||||||
|
|
||||||
|
QWidget *const m_target;
|
||||||
|
QHash<int, int> *m_keyMapping;
|
||||||
|
QHash<int, int> *m_mouseMapping;
|
||||||
|
};
|
@ -37,6 +37,8 @@ static const char *KEY_ENC_OPTIONS = "enc_options";
|
|||||||
|
|
||||||
static const char *JOB_TEMPLATE = "job_%08x";
|
static const char *JOB_TEMPLATE = "job_%08x";
|
||||||
|
|
||||||
|
#define VALID_INDEX(INDEX) ((INDEX).isValid() && ((INDEX).row() >= 0) && ((INDEX).row() < m_jobs.count()))
|
||||||
|
|
||||||
JobListModel::JobListModel(PreferencesModel *preferences)
|
JobListModel::JobListModel(PreferencesModel *preferences)
|
||||||
{
|
{
|
||||||
m_preferences = preferences;
|
m_preferences = preferences;
|
||||||
@ -311,7 +313,7 @@ QModelIndex JobListModel::insertJob(EncodeThread *thread)
|
|||||||
|
|
||||||
bool JobListModel::startJob(const QModelIndex &index)
|
bool JobListModel::startJob(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
if(index.isValid() && index.row() >= 0 && index.row() < m_jobs.count())
|
if(VALID_INDEX(index))
|
||||||
{
|
{
|
||||||
QUuid id = m_jobs.at(index.row());
|
QUuid id = m_jobs.at(index.row());
|
||||||
if(m_status.value(id) == JobStatus_Enqueued)
|
if(m_status.value(id) == JobStatus_Enqueued)
|
||||||
@ -328,7 +330,7 @@ bool JobListModel::startJob(const QModelIndex &index)
|
|||||||
|
|
||||||
bool JobListModel::pauseJob(const QModelIndex &index)
|
bool JobListModel::pauseJob(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
if(index.isValid() && index.row() >= 0 && index.row() < m_jobs.count())
|
if(VALID_INDEX(index))
|
||||||
{
|
{
|
||||||
QUuid id = m_jobs.at(index.row());
|
QUuid id = m_jobs.at(index.row());
|
||||||
JobStatus status = m_status.value(id);
|
JobStatus status = m_status.value(id);
|
||||||
@ -346,7 +348,7 @@ bool JobListModel::pauseJob(const QModelIndex &index)
|
|||||||
|
|
||||||
bool JobListModel::resumeJob(const QModelIndex &index)
|
bool JobListModel::resumeJob(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
if(index.isValid() && index.row() >= 0 && index.row() < m_jobs.count())
|
if(VALID_INDEX(index))
|
||||||
{
|
{
|
||||||
QUuid id = m_jobs.at(index.row());
|
QUuid id = m_jobs.at(index.row());
|
||||||
JobStatus status = m_status.value(id);
|
JobStatus status = m_status.value(id);
|
||||||
@ -363,7 +365,7 @@ bool JobListModel::resumeJob(const QModelIndex &index)
|
|||||||
|
|
||||||
bool JobListModel::abortJob(const QModelIndex &index)
|
bool JobListModel::abortJob(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
if(index.isValid() && index.row() >= 0 && index.row() < m_jobs.count())
|
if(VALID_INDEX(index))
|
||||||
{
|
{
|
||||||
QUuid id = m_jobs.at(index.row());
|
QUuid id = m_jobs.at(index.row());
|
||||||
if(m_status.value(id) == JobStatus_Indexing || m_status.value(id) == JobStatus_Running ||
|
if(m_status.value(id) == JobStatus_Indexing || m_status.value(id) == JobStatus_Running ||
|
||||||
@ -380,7 +382,7 @@ bool JobListModel::abortJob(const QModelIndex &index)
|
|||||||
|
|
||||||
bool JobListModel::deleteJob(const QModelIndex &index)
|
bool JobListModel::deleteJob(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
if(index.isValid() && index.row() >= 0 && index.row() < m_jobs.count())
|
if(VALID_INDEX(index))
|
||||||
{
|
{
|
||||||
QUuid id = m_jobs.at(index.row());
|
QUuid id = m_jobs.at(index.row());
|
||||||
if(m_status.value(id) == JobStatus_Completed || m_status.value(id) == JobStatus_Failed ||
|
if(m_status.value(id) == JobStatus_Completed || m_status.value(id) == JobStatus_Failed ||
|
||||||
@ -412,6 +414,29 @@ bool JobListModel::deleteJob(const QModelIndex &index)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool JobListModel::moveJob(const QModelIndex &index, const int &direction)
|
||||||
|
{
|
||||||
|
if(VALID_INDEX(index))
|
||||||
|
{
|
||||||
|
if((direction == MOVE_UP) && (index.row() > 0))
|
||||||
|
{
|
||||||
|
beginMoveRows(QModelIndex(), index.row(), index.row(), QModelIndex(), index.row() - 1);
|
||||||
|
m_jobs.swap(index.row(), index.row() - 1);
|
||||||
|
endMoveRows();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if((direction == MOVE_DOWN) && (index.row() < m_jobs.size() - 1))
|
||||||
|
{
|
||||||
|
beginMoveRows(QModelIndex(), index.row(), index.row(), QModelIndex(), index.row() + 2);
|
||||||
|
m_jobs.swap(index.row(), index.row() + 1);
|
||||||
|
endMoveRows();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
LogFileModel *JobListModel::getLogFile(const QModelIndex &index)
|
LogFileModel *JobListModel::getLogFile(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
if(index.isValid() && index.row() >= 0 && index.row() < m_jobs.count())
|
if(index.isValid() && index.row() >= 0 && index.row() < m_jobs.count())
|
||||||
@ -591,8 +616,16 @@ size_t JobListModel::loadQueuedJobs(const SysinfoModel *sysinfo)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t jobsCreated = 0;
|
const QStringList groups = settings.childGroups();
|
||||||
|
for(size_t i = 0; i < jobCounter; i++)
|
||||||
|
{
|
||||||
|
if(!groups.contains(QString().sprintf(JOB_TEMPLATE, i)))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t jobsCreated = 0;
|
||||||
for(size_t i = 0; i < jobCounter; i++)
|
for(size_t i = 0; i < jobCounter; i++)
|
||||||
{
|
{
|
||||||
settings.beginGroup(QString().sprintf(JOB_TEMPLATE, i));
|
settings.beginGroup(QString().sprintf(JOB_TEMPLATE, i));
|
||||||
@ -628,4 +661,6 @@ void JobListModel::clearQueuedJobs(void)
|
|||||||
const QString appDir = x264_data_path();
|
const QString appDir = x264_data_path();
|
||||||
QSettings settings(QString("%1/queue.ini").arg(appDir), QSettings::IniFormat);
|
QSettings settings(QString("%1/queue.ini").arg(appDir), QSettings::IniFormat);
|
||||||
settings.clear();
|
settings.clear();
|
||||||
|
settings.setValue(KEY_ENTRY_COUNT, 0);
|
||||||
|
settings.sync();
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,7 @@ public:
|
|||||||
bool resumeJob(const QModelIndex &index);
|
bool resumeJob(const QModelIndex &index);
|
||||||
bool abortJob(const QModelIndex &index);
|
bool abortJob(const QModelIndex &index);
|
||||||
bool deleteJob(const QModelIndex &index);
|
bool deleteJob(const QModelIndex &index);
|
||||||
|
bool moveJob(const QModelIndex &index, const int &direction);
|
||||||
LogFileModel *getLogFile(const QModelIndex &index);
|
LogFileModel *getLogFile(const QModelIndex &index);
|
||||||
const QString &getJobSourceFile(const QModelIndex &index);
|
const QString &getJobSourceFile(const QModelIndex &index);
|
||||||
const QString &getJobOutputFile(const QModelIndex &index);
|
const QString &getJobOutputFile(const QModelIndex &index);
|
||||||
@ -64,6 +65,13 @@ public:
|
|||||||
size_t loadQueuedJobs(const SysinfoModel *sysinfo);
|
size_t loadQueuedJobs(const SysinfoModel *sysinfo);
|
||||||
void clearQueuedJobs(void);
|
void clearQueuedJobs(void);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
MOVE_UP = +1,
|
||||||
|
MOVE_DOWN = -1
|
||||||
|
}
|
||||||
|
move_t;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QList<QUuid> m_jobs;
|
QList<QUuid> m_jobs;
|
||||||
QMap<QUuid, QString> m_name;
|
QMap<QUuid, QString> m_name;
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#define VER_X264_MAJOR 2
|
#define VER_X264_MAJOR 2
|
||||||
#define VER_X264_MINOR 3
|
#define VER_X264_MINOR 3
|
||||||
#define VER_X264_PATCH 7
|
#define VER_X264_PATCH 7
|
||||||
#define VER_X264_BUILD 838
|
#define VER_X264_BUILD 843
|
||||||
|
|
||||||
#define VER_X264_PORTABLE_EDITION (0)
|
#define VER_X264_PORTABLE_EDITION (0)
|
||||||
|
|
||||||
|
112
src/win_main.cpp
112
src/win_main.cpp
@ -35,6 +35,7 @@
|
|||||||
#include "thread_vapoursynth.h"
|
#include "thread_vapoursynth.h"
|
||||||
#include "thread_encode.h"
|
#include "thread_encode.h"
|
||||||
#include "taskbar7.h"
|
#include "taskbar7.h"
|
||||||
|
#include "input_filter.h"
|
||||||
#include "win_addJob.h"
|
#include "win_addJob.h"
|
||||||
#include "win_about.h"
|
#include "win_about.h"
|
||||||
#include "win_preferences.h"
|
#include "win_preferences.h"
|
||||||
@ -71,7 +72,6 @@ const char *tpl_last = "<LAST_USED>";
|
|||||||
#define NEXT(X) ((*reinterpret_cast<int*>(&(X)))++)
|
#define NEXT(X) ((*reinterpret_cast<int*>(&(X)))++)
|
||||||
#define SETUP_WEBLINK(OBJ, URL) do { (OBJ)->setData(QVariant(QUrl(URL))); connect((OBJ), SIGNAL(triggered()), this, SLOT(showWebLink())); } while(0)
|
#define SETUP_WEBLINK(OBJ, URL) do { (OBJ)->setData(QVariant(QUrl(URL))); connect((OBJ), SIGNAL(triggered()), this, SLOT(showWebLink())); } while(0)
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor & Destructor
|
// Constructor & Destructor
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -125,7 +125,6 @@ MainWindow::MainWindow(const x264_cpu_t *const cpuFeatures, IPC *ipc)
|
|||||||
|
|
||||||
//Update title
|
//Update title
|
||||||
ui->labelBuildDate->setText(tr("Built on %1 at %2").arg(x264_version_date().toString(Qt::ISODate), QString::fromLatin1(x264_version_time())));
|
ui->labelBuildDate->setText(tr("Built on %1 at %2").arg(x264_version_date().toString(Qt::ISODate), QString::fromLatin1(x264_version_time())));
|
||||||
ui->labelBuildDate->installEventFilter(this);
|
|
||||||
|
|
||||||
if(X264_DEBUG)
|
if(X264_DEBUG)
|
||||||
{
|
{
|
||||||
@ -152,6 +151,18 @@ MainWindow::MainWindow(const x264_cpu_t *const cpuFeatures, IPC *ipc)
|
|||||||
ui->jobsView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
|
ui->jobsView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
|
||||||
connect(ui->jobsView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(jobSelected(QModelIndex, QModelIndex)));
|
connect(ui->jobsView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(jobSelected(QModelIndex, QModelIndex)));
|
||||||
|
|
||||||
|
//Setup key listener
|
||||||
|
m_inputFilter_jobList = new InputEventFilter(ui->jobsView);
|
||||||
|
m_inputFilter_jobList->addKeyFilter(Qt::ControlModifier | Qt::Key_Up, 1);
|
||||||
|
m_inputFilter_jobList->addKeyFilter(Qt::ControlModifier | Qt::Key_Down, 2);
|
||||||
|
connect(m_inputFilter_jobList, SIGNAL(keyPressed(int)), this, SLOT(jobListKeyPressed(int)));
|
||||||
|
|
||||||
|
//Setup mouse listener
|
||||||
|
m_inputFilter_version = new InputEventFilter(ui->labelBuildDate);
|
||||||
|
m_inputFilter_version->addMouseFilter(Qt::LeftButton, 0);
|
||||||
|
m_inputFilter_version->addMouseFilter(Qt::RightButton, 0);
|
||||||
|
connect(m_inputFilter_version, SIGNAL(mouseClicked(int)), this, SLOT(versionLabelMouseClicked(int)));
|
||||||
|
|
||||||
//Create context menu
|
//Create context menu
|
||||||
QAction *actionClipboard = new QAction(QIcon(":/buttons/page_paste.png"), tr("Copy to Clipboard"), ui->logView);
|
QAction *actionClipboard = new QAction(QIcon(":/buttons/page_paste.png"), tr("Copy to Clipboard"), ui->logView);
|
||||||
actionClipboard->setEnabled(false);
|
actionClipboard->setEnabled(false);
|
||||||
@ -160,13 +171,15 @@ MainWindow::MainWindow(const x264_cpu_t *const cpuFeatures, IPC *ipc)
|
|||||||
ui->jobsView->addActions(ui->menuJob->actions());
|
ui->jobsView->addActions(ui->menuJob->actions());
|
||||||
|
|
||||||
//Enable buttons
|
//Enable buttons
|
||||||
connect(ui->buttonAddJob, SIGNAL(clicked()), this, SLOT(addButtonPressed()));
|
connect(ui->buttonAddJob, SIGNAL(clicked()), this, SLOT(addButtonPressed() ));
|
||||||
connect(ui->buttonStartJob, SIGNAL(clicked()), this, SLOT(startButtonPressed()));
|
connect(ui->buttonStartJob, SIGNAL(clicked()), this, SLOT(startButtonPressed() ));
|
||||||
connect(ui->buttonAbortJob, SIGNAL(clicked()), this, SLOT(abortButtonPressed()));
|
connect(ui->buttonAbortJob, SIGNAL(clicked()), this, SLOT(abortButtonPressed() ));
|
||||||
connect(ui->buttonPauseJob, SIGNAL(toggled(bool)), this, SLOT(pauseButtonPressed(bool)));
|
connect(ui->buttonPauseJob, SIGNAL(toggled(bool)), this, SLOT(pauseButtonPressed(bool)));
|
||||||
connect(ui->actionJob_Delete, SIGNAL(triggered()), this, SLOT(deleteButtonPressed()));
|
connect(ui->actionJob_Delete, SIGNAL(triggered()), this, SLOT(deleteButtonPressed() ));
|
||||||
connect(ui->actionJob_Restart, SIGNAL(triggered()), this, SLOT(restartButtonPressed()));
|
connect(ui->actionJob_Restart, SIGNAL(triggered()), this, SLOT(restartButtonPressed() ));
|
||||||
connect(ui->actionJob_Browse, SIGNAL(triggered()), this, SLOT(browseButtonPressed()));
|
connect(ui->actionJob_Browse, SIGNAL(triggered()), this, SLOT(browseButtonPressed() ));
|
||||||
|
connect(ui->actionJob_MoveUp, SIGNAL(triggered()), this, SLOT(moveButtonPressed() ));
|
||||||
|
connect(ui->actionJob_MoveDown, SIGNAL(triggered()), this, SLOT(moveButtonPressed() ));
|
||||||
|
|
||||||
//Enable menu
|
//Enable menu
|
||||||
connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(openActionTriggered()));
|
connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(openActionTriggered()));
|
||||||
@ -222,6 +235,8 @@ MainWindow::~MainWindow(void)
|
|||||||
X264_DELETE(m_options);
|
X264_DELETE(m_options);
|
||||||
X264_DELETE(m_pendingFiles);
|
X264_DELETE(m_pendingFiles);
|
||||||
X264_DELETE(m_label);
|
X264_DELETE(m_label);
|
||||||
|
X264_DELETE(m_inputFilter_jobList);
|
||||||
|
X264_DELETE(m_inputFilter_version);
|
||||||
|
|
||||||
while(!m_toolsList.isEmpty())
|
while(!m_toolsList.isEmpty())
|
||||||
{
|
{
|
||||||
@ -354,6 +369,37 @@ void MainWindow::browseButtonPressed(void)
|
|||||||
m_status = STATUS_IDLE;
|
m_status = STATUS_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The "browse" button was clicked
|
||||||
|
*/
|
||||||
|
void MainWindow::moveButtonPressed(void)
|
||||||
|
{
|
||||||
|
ENSURE_APP_IS_IDLE();
|
||||||
|
|
||||||
|
if(sender() == ui->actionJob_MoveUp)
|
||||||
|
{
|
||||||
|
qDebug("Move job %d (direction: UP)", ui->jobsView->currentIndex().row());
|
||||||
|
if(!m_jobList->moveJob(ui->jobsView->currentIndex(), JobListModel::MOVE_UP))
|
||||||
|
{
|
||||||
|
x264_beep(x264_beep_error);
|
||||||
|
}
|
||||||
|
ui->jobsView->scrollTo(ui->jobsView->currentIndex(), QAbstractItemView::PositionAtCenter);
|
||||||
|
}
|
||||||
|
else if(sender() == ui->actionJob_MoveDown)
|
||||||
|
{
|
||||||
|
qDebug("Move job %d (direction: DOWN)", ui->jobsView->currentIndex().row());
|
||||||
|
if(!m_jobList->moveJob(ui->jobsView->currentIndex(), JobListModel::MOVE_DOWN))
|
||||||
|
{
|
||||||
|
x264_beep(x264_beep_error);
|
||||||
|
}
|
||||||
|
ui->jobsView->scrollTo(ui->jobsView->currentIndex(), QAbstractItemView::PositionAtCenter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qWarning("[moveButtonPressed] Error: Unknown sender!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The "pause" button was clicked
|
* The "pause" button was clicked
|
||||||
*/
|
*/
|
||||||
@ -996,6 +1042,7 @@ void MainWindow::init(void)
|
|||||||
if(m_jobList->loadQueuedJobs(m_sysinfo) > 0)
|
if(m_jobList->loadQueuedJobs(m_sysinfo) > 0)
|
||||||
{
|
{
|
||||||
m_label->setVisible(m_jobList->rowCount(QModelIndex()) == 0);
|
m_label->setVisible(m_jobList->rowCount(QModelIndex()) == 0);
|
||||||
|
m_jobList->clearQueuedJobs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1152,6 +1199,27 @@ void MainWindow::checkUpdates(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::versionLabelMouseClicked(const int &tag)
|
||||||
|
{
|
||||||
|
if(tag == 0)
|
||||||
|
{
|
||||||
|
QTimer::singleShot(0, this, SLOT(showAbout()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::jobListKeyPressed(const int &tag)
|
||||||
|
{
|
||||||
|
switch(tag)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
ui->actionJob_MoveUp->trigger();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ui->actionJob_MoveDown->trigger();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Event functions
|
// Event functions
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1174,8 +1242,6 @@ void MainWindow::showEvent(QShowEvent *e)
|
|||||||
*/
|
*/
|
||||||
void MainWindow::closeEvent(QCloseEvent *e)
|
void MainWindow::closeEvent(QCloseEvent *e)
|
||||||
{
|
{
|
||||||
bool bJobsHaveBeenSaved = false;
|
|
||||||
|
|
||||||
if((m_status != STATUS_IDLE) && (m_status != STATUS_EXITTING))
|
if((m_status != STATUS_IDLE) && (m_status != STATUS_EXITTING))
|
||||||
{
|
{
|
||||||
e->ignore();
|
e->ignore();
|
||||||
@ -1202,10 +1268,7 @@ void MainWindow::closeEvent(QCloseEvent *e)
|
|||||||
int ret = QMessageBox::question(this, tr("Jobs Are Pending"), tr("You still have pending jobs. How do you want to proceed?"), tr("Save Pending Jobs"), tr("Discard"));
|
int ret = QMessageBox::question(this, tr("Jobs Are Pending"), tr("You still have pending jobs. How do you want to proceed?"), tr("Save Pending Jobs"), tr("Discard"));
|
||||||
if(ret == 0)
|
if(ret == 0)
|
||||||
{
|
{
|
||||||
if(m_jobList->saveQueuedJobs() > 0)
|
m_jobList->saveQueuedJobs();
|
||||||
{
|
|
||||||
bJobsHaveBeenSaved = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1219,12 +1282,6 @@ void MainWindow::closeEvent(QCloseEvent *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Clear "old" pending jobs for next startup (only if we have not saved "new" jobs already!)
|
|
||||||
if(!bJobsHaveBeenSaved)
|
|
||||||
{
|
|
||||||
m_jobList->clearQueuedJobs();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Delete remaining jobs
|
//Delete remaining jobs
|
||||||
while(m_jobList->rowCount(QModelIndex()) > 0)
|
while(m_jobList->rowCount(QModelIndex()) > 0)
|
||||||
{
|
{
|
||||||
@ -1255,19 +1312,6 @@ void MainWindow::resizeEvent(QResizeEvent *e)
|
|||||||
updateLabelPos();
|
updateLabelPos();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Event filter
|
|
||||||
*/
|
|
||||||
bool MainWindow::eventFilter(QObject *o, QEvent *e)
|
|
||||||
{
|
|
||||||
if((o == ui->labelBuildDate) && (e->type() == QEvent::MouseButtonPress))
|
|
||||||
{
|
|
||||||
QTimer::singleShot(0, this, SLOT(showAbout()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Win32 message filter
|
* Win32 message filter
|
||||||
*/
|
*/
|
||||||
@ -1493,6 +1537,8 @@ void MainWindow::updateButtons(JobStatus status)
|
|||||||
ui->actionJob_Delete->setEnabled(status == JobStatus_Completed || status == JobStatus_Aborted || status == JobStatus_Failed || status == JobStatus_Enqueued);
|
ui->actionJob_Delete->setEnabled(status == JobStatus_Completed || status == JobStatus_Aborted || status == JobStatus_Failed || status == JobStatus_Enqueued);
|
||||||
ui->actionJob_Restart->setEnabled(status == JobStatus_Completed || status == JobStatus_Aborted || status == JobStatus_Failed || status == JobStatus_Enqueued);
|
ui->actionJob_Restart->setEnabled(status == JobStatus_Completed || status == JobStatus_Aborted || status == JobStatus_Failed || status == JobStatus_Enqueued);
|
||||||
ui->actionJob_Browse->setEnabled(status == JobStatus_Completed);
|
ui->actionJob_Browse->setEnabled(status == JobStatus_Completed);
|
||||||
|
ui->actionJob_MoveUp->setEnabled(status != JobStatus_Undefined);
|
||||||
|
ui->actionJob_MoveDown->setEnabled(status != JobStatus_Undefined);
|
||||||
|
|
||||||
ui->actionJob_Start->setEnabled(ui->buttonStartJob->isEnabled());
|
ui->actionJob_Start->setEnabled(ui->buttonStartJob->isEnabled());
|
||||||
ui->actionJob_Abort->setEnabled(ui->buttonAbortJob->isEnabled());
|
ui->actionJob_Abort->setEnabled(ui->buttonAbortJob->isEnabled());
|
||||||
|
@ -32,6 +32,7 @@ class QFile;
|
|||||||
class QLibrary;
|
class QLibrary;
|
||||||
class PreferencesModel;
|
class PreferencesModel;
|
||||||
class RecentlyUsed;
|
class RecentlyUsed;
|
||||||
|
class InputEventFilter;
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
enum JobStatus;
|
enum JobStatus;
|
||||||
@ -53,7 +54,6 @@ protected:
|
|||||||
virtual void closeEvent(QCloseEvent *e);
|
virtual void closeEvent(QCloseEvent *e);
|
||||||
virtual void showEvent(QShowEvent *e);
|
virtual void showEvent(QShowEvent *e);
|
||||||
virtual void resizeEvent(QResizeEvent *e);
|
virtual void resizeEvent(QResizeEvent *e);
|
||||||
virtual bool eventFilter(QObject *o, QEvent *e);
|
|
||||||
virtual void dragEnterEvent(QDragEnterEvent *event);
|
virtual void dragEnterEvent(QDragEnterEvent *event);
|
||||||
virtual void dropEvent(QDropEvent *event);
|
virtual void dropEvent(QDropEvent *event);
|
||||||
virtual bool winEvent(MSG *message, long *result);
|
virtual bool winEvent(MSG *message, long *result);
|
||||||
@ -76,6 +76,9 @@ private:
|
|||||||
QLabel *m_label;
|
QLabel *m_label;
|
||||||
IPC *const m_ipc;
|
IPC *const m_ipc;
|
||||||
|
|
||||||
|
InputEventFilter *m_inputFilter_jobList;
|
||||||
|
InputEventFilter *m_inputFilter_version;
|
||||||
|
|
||||||
JobListModel *m_jobList;
|
JobListModel *m_jobList;
|
||||||
OptionsModel *m_options;
|
OptionsModel *m_options;
|
||||||
QStringList *m_pendingFiles;
|
QStringList *m_pendingFiles;
|
||||||
@ -110,7 +113,9 @@ private slots:
|
|||||||
void jobSelected(const QModelIndex ¤t, const QModelIndex &previous);
|
void jobSelected(const QModelIndex ¤t, const QModelIndex &previous);
|
||||||
void jobChangedData(const QModelIndex &top, const QModelIndex &bottom);
|
void jobChangedData(const QModelIndex &top, const QModelIndex &bottom);
|
||||||
void jobLogExtended(const QModelIndex & parent, int start, int end);
|
void jobLogExtended(const QModelIndex & parent, int start, int end);
|
||||||
|
void jobListKeyPressed(const int &tag);
|
||||||
void launchNextJob();
|
void launchNextJob();
|
||||||
|
void moveButtonPressed(void);
|
||||||
void pauseButtonPressed(bool checked);
|
void pauseButtonPressed(bool checked);
|
||||||
void restartButtonPressed(void);
|
void restartButtonPressed(void);
|
||||||
void saveLogFile(const QModelIndex &index);
|
void saveLogFile(const QModelIndex &index);
|
||||||
@ -120,4 +125,5 @@ private slots:
|
|||||||
void shutdownComputer(void);
|
void shutdownComputer(void);
|
||||||
void startButtonPressed(void);
|
void startButtonPressed(void);
|
||||||
void updateLabelPos(void);
|
void updateLabelPos(void);
|
||||||
|
void versionLabelMouseClicked(const int &tag);
|
||||||
};
|
};
|
||||||
|
@ -343,6 +343,14 @@ copy /Y "$(QTDIR)\plugins\imageformats\qgif4.dll" "$(TargetDir)\imageformats"
|
|||||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)tmp\moc\moc_%(Filename).cpp;%(Outputs)</Outputs>
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)tmp\moc\moc_%(Filename).cpp;%(Outputs)</Outputs>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
<ClInclude Include="src\job_object.h" />
|
<ClInclude Include="src\job_object.h" />
|
||||||
|
<CustomBuild Include="src\input_filter.h">
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)tmp\moc\moc_%(Filename).cpp" "%(FullPath)"</Command>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)tmp\moc\moc_%(Filename).cpp" "%(FullPath)"</Command>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MOC "$(SolutionDir)tmp\moc\moc_%(Filename).cpp"</Message>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MOC "$(SolutionDir)tmp\moc\moc_%(Filename).cpp"</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)tmp\moc\moc_%(Filename).cpp;%(Outputs)</Outputs>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)tmp\moc\moc_%(Filename).cpp;%(Outputs)</Outputs>
|
||||||
|
</CustomBuild>
|
||||||
<ClInclude Include="src\mediainfo.h" />
|
<ClInclude Include="src\mediainfo.h" />
|
||||||
<ClInclude Include="src\model_options.h" />
|
<ClInclude Include="src\model_options.h" />
|
||||||
<ClInclude Include="src\model_preferences.h" />
|
<ClInclude Include="src\model_preferences.h" />
|
||||||
@ -408,6 +416,7 @@ copy /Y "$(QTDIR)\plugins\imageformats\qgif4.dll" "$(TargetDir)\imageformats"
|
|||||||
<ClCompile Include="src\encoder_x265.cpp" />
|
<ClCompile Include="src\encoder_x265.cpp" />
|
||||||
<ClCompile Include="src\ipc.cpp" />
|
<ClCompile Include="src\ipc.cpp" />
|
||||||
<ClCompile Include="src\job_object.cpp" />
|
<ClCompile Include="src\job_object.cpp" />
|
||||||
|
<ClCompile Include="src\input_filter.cpp" />
|
||||||
<ClCompile Include="src\mediainfo.cpp" />
|
<ClCompile Include="src\mediainfo.cpp" />
|
||||||
<ClCompile Include="src\model_jobList.cpp" />
|
<ClCompile Include="src\model_jobList.cpp" />
|
||||||
<ClCompile Include="src\model_logFile.cpp" />
|
<ClCompile Include="src\model_logFile.cpp" />
|
||||||
@ -432,6 +441,7 @@ copy /Y "$(QTDIR)\plugins\imageformats\qgif4.dll" "$(TargetDir)\imageformats"
|
|||||||
<ClCompile Include="src\win_main.cpp" />
|
<ClCompile Include="src\win_main.cpp" />
|
||||||
<ClCompile Include="src\win_preferences.cpp" />
|
<ClCompile Include="src\win_preferences.cpp" />
|
||||||
<ClCompile Include="src\win_updater.cpp" />
|
<ClCompile Include="src\win_updater.cpp" />
|
||||||
|
<ClCompile Include="tmp\moc\moc_input_filter.cpp" />
|
||||||
<ClCompile Include="tmp\moc\moc_ipc.cpp" />
|
<ClCompile Include="tmp\moc\moc_ipc.cpp" />
|
||||||
<ClCompile Include="tmp\moc\moc_model_jobList.cpp" />
|
<ClCompile Include="tmp\moc\moc_model_jobList.cpp" />
|
||||||
<ClCompile Include="tmp\moc\moc_model_logFile.cpp" />
|
<ClCompile Include="tmp\moc\moc_model_logFile.cpp" />
|
||||||
|
@ -108,6 +108,9 @@
|
|||||||
<ClInclude Include="src\mediainfo.h">
|
<ClInclude Include="src\mediainfo.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\key_filter.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\main.cpp">
|
<ClCompile Include="src\main.cpp">
|
||||||
@ -263,6 +266,12 @@
|
|||||||
<ClCompile Include="src\mediainfo.cpp">
|
<ClCompile Include="src\mediainfo.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\input_filter.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="tmp\moc\moc_input_filter.cpp">
|
||||||
|
<Filter>Generated Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CustomBuild Include="src\win_main.h">
|
<CustomBuild Include="src\win_main.h">
|
||||||
|
Loading…
Reference in New Issue
Block a user