first commit
This commit is contained in:
1559
project/fm_viewer/tester/StackWalker.cpp
Normal file
1559
project/fm_viewer/tester/StackWalker.cpp
Normal file
File diff suppressed because it is too large
Load Diff
274
project/fm_viewer/tester/StackWalker.h
Normal file
274
project/fm_viewer/tester/StackWalker.h
Normal file
@@ -0,0 +1,274 @@
|
||||
#ifndef __STACKWALKER_H__
|
||||
#define __STACKWALKER_H__
|
||||
#if (REPORT_CRASH_LOG)
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* StackWalker.h
|
||||
*
|
||||
*
|
||||
*
|
||||
* LICENSE (http://www.opensource.org/licenses/bsd-license.php)
|
||||
*
|
||||
* Copyright (c) 2005-2009, Jochen Kalmbach
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* Neither the name of Jochen Kalmbach nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* **********************************************************************/
|
||||
// #pragma once is supported starting with _MSC_VER 1000,
|
||||
// so we need not to check the version (because we only support _MSC_VER >= 1100)!
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// special defines for VC5/6 (if no actual PSDK is installed):
|
||||
#if _MSC_VER < 1300
|
||||
typedef unsigned __int64 DWORD64, *PDWORD64;
|
||||
#if defined(_WIN64)
|
||||
typedef unsigned __int64 SIZE_T, *PSIZE_T;
|
||||
#else
|
||||
typedef unsigned long SIZE_T, *PSIZE_T;
|
||||
#endif
|
||||
#endif // _MSC_VER < 1300
|
||||
|
||||
class StackWalkerInternal; // forward
|
||||
class StackWalker
|
||||
{
|
||||
public:
|
||||
typedef enum ExceptType
|
||||
{
|
||||
NonExcept = 0, // RtlCaptureContext
|
||||
AfterExcept = 1,
|
||||
AfterCatch = 2, // get_current_exception_context
|
||||
} ExceptType;
|
||||
|
||||
typedef enum StackWalkOptions
|
||||
{
|
||||
// No addition info will be retrieved
|
||||
// (only the address is available)
|
||||
RetrieveNone = 0,
|
||||
|
||||
// Try to get the symbol-name
|
||||
RetrieveSymbol = 1,
|
||||
|
||||
// Try to get the line for this symbol
|
||||
RetrieveLine = 2,
|
||||
|
||||
// Try to retrieve the module-infos
|
||||
RetrieveModuleInfo = 4,
|
||||
|
||||
// Also retrieve the version for the DLL/EXE
|
||||
RetrieveFileVersion = 8,
|
||||
|
||||
// Contains all the above
|
||||
RetrieveVerbose = 0xF,
|
||||
|
||||
// Generate a "good" symbol-search-path
|
||||
SymBuildPath = 0x10,
|
||||
|
||||
// Also use the public Microsoft-Symbol-Server
|
||||
SymUseSymSrv = 0x20,
|
||||
|
||||
// Contains all the above "Sym"-options
|
||||
SymAll = 0x30,
|
||||
|
||||
// Contains all options (default)
|
||||
OptionsAll = 0x3F
|
||||
} StackWalkOptions;
|
||||
|
||||
StackWalker(ExceptType extype, int options = OptionsAll, PEXCEPTION_POINTERS exp = NULL);
|
||||
|
||||
StackWalker(int options = OptionsAll, // 'int' is by design, to combine the enum-flags
|
||||
LPCSTR szSymPath = NULL,
|
||||
DWORD dwProcessId = GetCurrentProcessId(),
|
||||
HANDLE hProcess = GetCurrentProcess());
|
||||
|
||||
StackWalker(DWORD dwProcessId, HANDLE hProcess);
|
||||
|
||||
virtual ~StackWalker();
|
||||
|
||||
bool SetSymPath(LPCSTR szSymPath);
|
||||
|
||||
bool SetTargetProcess(DWORD dwProcessId, HANDLE hProcess);
|
||||
|
||||
PCONTEXT GetCurrentExceptionContext();
|
||||
|
||||
private:
|
||||
bool Init(ExceptType extype, int options, LPCSTR szSymPath, DWORD dwProcessId,
|
||||
HANDLE hProcess, PEXCEPTION_POINTERS exp = NULL);
|
||||
|
||||
public:
|
||||
typedef BOOL(__stdcall* PReadProcessMemoryRoutine)(
|
||||
HANDLE hProcess,
|
||||
DWORD64 qwBaseAddress,
|
||||
PVOID lpBuffer,
|
||||
DWORD nSize,
|
||||
LPDWORD lpNumberOfBytesRead,
|
||||
LPVOID pUserData // optional data, which was passed in "ShowCallstack"
|
||||
);
|
||||
|
||||
BOOL LoadModules();
|
||||
|
||||
BOOL ShowCallstack(
|
||||
HANDLE hThread = GetCurrentThread(),
|
||||
const CONTEXT* context = NULL,
|
||||
PReadProcessMemoryRoutine readMemoryFunction = NULL,
|
||||
LPVOID pUserData = NULL // optional to identify some data in the 'readMemoryFunction'-callback
|
||||
);
|
||||
|
||||
BOOL ShowObject(LPVOID pObject);
|
||||
|
||||
#if _MSC_VER >= 1300
|
||||
// due to some reasons, the "STACKWALK_MAX_NAMELEN" must be declared as "public"
|
||||
// in older compilers in order to use it... starting with VC7 we can declare it as "protected"
|
||||
protected:
|
||||
#endif
|
||||
enum
|
||||
{
|
||||
STACKWALK_MAX_NAMELEN = 1024
|
||||
}; // max name length for found symbols
|
||||
|
||||
protected:
|
||||
// Entry for each Callstack-Entry
|
||||
typedef struct CallstackEntry
|
||||
{
|
||||
DWORD64 offset; // if 0, we have no valid entry
|
||||
CHAR name[STACKWALK_MAX_NAMELEN];
|
||||
CHAR undName[STACKWALK_MAX_NAMELEN];
|
||||
CHAR undFullName[STACKWALK_MAX_NAMELEN];
|
||||
DWORD64 offsetFromSmybol;
|
||||
DWORD offsetFromLine;
|
||||
DWORD lineNumber;
|
||||
CHAR lineFileName[STACKWALK_MAX_NAMELEN];
|
||||
DWORD symType;
|
||||
LPCSTR symTypeString;
|
||||
CHAR moduleName[STACKWALK_MAX_NAMELEN];
|
||||
DWORD64 baseOfImage;
|
||||
CHAR loadedImageName[STACKWALK_MAX_NAMELEN];
|
||||
} CallstackEntry;
|
||||
|
||||
typedef enum CallstackEntryType
|
||||
{
|
||||
firstEntry,
|
||||
nextEntry,
|
||||
lastEntry
|
||||
} CallstackEntryType;
|
||||
|
||||
virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName);
|
||||
virtual void OnLoadModule(LPCSTR img,
|
||||
LPCSTR mod,
|
||||
DWORD64 baseAddr,
|
||||
DWORD size,
|
||||
DWORD result,
|
||||
LPCSTR symType,
|
||||
LPCSTR pdbName,
|
||||
ULONGLONG fileVersion);
|
||||
virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry& entry);
|
||||
virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr);
|
||||
virtual void OnOutput(LPCSTR szText);
|
||||
|
||||
StackWalkerInternal* m_sw;
|
||||
HANDLE m_hProcess;
|
||||
DWORD m_dwProcessId;
|
||||
BOOL m_modulesLoaded;
|
||||
LPSTR m_szSymPath;
|
||||
|
||||
int m_options;
|
||||
int m_MaxRecursionCount;
|
||||
|
||||
static BOOL __stdcall myReadProcMem(HANDLE hProcess,
|
||||
DWORD64 qwBaseAddress,
|
||||
PVOID lpBuffer,
|
||||
DWORD nSize,
|
||||
LPDWORD lpNumberOfBytesRead);
|
||||
|
||||
friend StackWalkerInternal;
|
||||
}; // class StackWalker
|
||||
|
||||
// The "ugly" assembler-implementation is needed for systems before XP
|
||||
// If you have a new PSDK and you only compile for XP and later, then you can use
|
||||
// the "RtlCaptureContext"
|
||||
// Currently there is no define which determines the PSDK-Version...
|
||||
// So we just use the compiler-version (and assumes that the PSDK is
|
||||
// the one which was installed by the VS-IDE)
|
||||
|
||||
// INFO: If you want, you can use the RtlCaptureContext if you only target XP and later...
|
||||
// But I currently use it in x64/IA64 environments...
|
||||
//#if defined(_M_IX86) && (_WIN32_WINNT <= 0x0500) && (_MSC_VER < 1400)
|
||||
|
||||
#if defined(_M_IX86)
|
||||
#ifdef CURRENT_THREAD_VIA_EXCEPTION
|
||||
// TODO: The following is not a "good" implementation,
|
||||
// because the callstack is only valid in the "__except" block...
|
||||
#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \
|
||||
do \
|
||||
{ \
|
||||
memset(&c, 0, sizeof(CONTEXT)); \
|
||||
EXCEPTION_POINTERS* pExp = NULL; \
|
||||
__try \
|
||||
{ \
|
||||
throw 0; \
|
||||
} \
|
||||
__except (((pExp = GetExceptionInformation()) ? EXCEPTION_EXECUTE_HANDLER \
|
||||
: EXCEPTION_EXECUTE_HANDLER)) \
|
||||
{ \
|
||||
} \
|
||||
if (pExp != NULL) \
|
||||
memcpy(&c, pExp->ContextRecord, sizeof(CONTEXT)); \
|
||||
c.ContextFlags = contextFlags; \
|
||||
} while (0);
|
||||
#else
|
||||
// clang-format off
|
||||
// The following should be enough for walking the callstack...
|
||||
#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \
|
||||
do \
|
||||
{ \
|
||||
memset(&c, 0, sizeof(CONTEXT)); \
|
||||
c.ContextFlags = contextFlags; \
|
||||
__asm call x \
|
||||
__asm x: pop eax \
|
||||
__asm mov c.Eip, eax \
|
||||
__asm mov c.Ebp, ebp \
|
||||
__asm mov c.Esp, esp \
|
||||
} while (0)
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// The following is defined for x86 (XP and higher), x64 and IA64:
|
||||
#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \
|
||||
do \
|
||||
{ \
|
||||
memset(&c, 0, sizeof(CONTEXT)); \
|
||||
c.ContextFlags = contextFlags; \
|
||||
RtlCaptureContext(&c); \
|
||||
} while (0);
|
||||
#endif
|
||||
|
||||
#endif //defined(_MSC_VER)
|
||||
|
||||
#endif // #if (REPORT_CRASH_LOG)
|
||||
#endif // __STACKWALKER_H__
|
||||
236
project/fm_viewer/tester/fe_log.cpp
Normal file
236
project/fm_viewer/tester/fe_log.cpp
Normal file
@@ -0,0 +1,236 @@
|
||||
#include "fe_log.h"
|
||||
#if (FE_LOG_VERSION)
|
||||
#include <Windows.h>
|
||||
#include <QVBoxLayout>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QDateTime>
|
||||
#include <QSysInfo>
|
||||
#include <QStorageInfo>
|
||||
#include <QSettings>
|
||||
#include <QDebug>
|
||||
#include <QProcess>
|
||||
#include <QDateTime>
|
||||
#include <QCryptographicHash>
|
||||
#include <QScrollBar>
|
||||
#include <QFileDialog>
|
||||
|
||||
QVector<QString> FELogHandler::buffer = QVector<QString>();
|
||||
|
||||
void FELogHandler::messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||
{
|
||||
QString ds = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz ");
|
||||
buffer.append(ds + msg);
|
||||
emit FELogHandler::instance()->appended(msg);
|
||||
|
||||
//printDebug(__FUNCTION__ + msg);
|
||||
//OutputDebugString(reinterpret_cast<const wchar_t *>(msg.utf16()));
|
||||
|
||||
// QByteArray localMsg = msg.toLocal8Bit();
|
||||
// switch (type) {
|
||||
// case QtDebugMsg:
|
||||
// fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
|
||||
// break;
|
||||
// case QtInfoMsg:
|
||||
// fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
|
||||
// break;
|
||||
// case QtWarningMsg:
|
||||
// fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
|
||||
// break;
|
||||
// case QtCriticalMsg:
|
||||
// fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
|
||||
// break;
|
||||
// case QtFatalMsg:
|
||||
// fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
|
||||
// abort();
|
||||
// }
|
||||
// fflush(stderr);
|
||||
}
|
||||
void FELogHandler::printDebug(QString msg)
|
||||
{
|
||||
OutputDebugString(reinterpret_cast<const wchar_t *>(msg.utf16()));
|
||||
}
|
||||
void FELogDialog::onButton()
|
||||
{
|
||||
QPushButton* btn = qobject_cast<QPushButton*>(sender());
|
||||
QString cmd = btn->text().toUpper();
|
||||
|
||||
if(cmd == "SAVE")
|
||||
{
|
||||
QString savePath = QFileDialog::getSaveFileName(0,
|
||||
"LOG SAVE FILE",
|
||||
NULL,
|
||||
"Log files (*.log)",0,QFileDialog::DontConfirmOverwrite);
|
||||
|
||||
if(!savePath.isEmpty())
|
||||
{
|
||||
QFile file(savePath);
|
||||
if (file.open(QIODevice::WriteOnly)) {
|
||||
QTextStream stream(&file);
|
||||
stream << _text->toPlainText() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
QPushButton* FELogDialog::button(QWidget* parent,QLayout* layout,QString title)
|
||||
{
|
||||
QPushButton* btn = new QPushButton(parent);
|
||||
btn->setText(title);
|
||||
//btn->setStyleSheet("font-family: Arial;font-size: 9px;");
|
||||
btn->setStyleSheet("QPushButton{font-family: Fixedsys;color : white;}"
|
||||
"QPushButton[enabled=\"false\"]{color : #AAAAAA;}");
|
||||
btn->setFixedWidth(title.length() * 10);
|
||||
layout->addWidget(btn);
|
||||
connect(btn,SIGNAL(clicked()),SLOT(onButton()));
|
||||
return btn;
|
||||
}
|
||||
FELogDialog::FELogDialog(QWidget *parent,Qt::WindowFlags f) : QDialog(parent,f)
|
||||
{
|
||||
setWindowTitle("LOG.");
|
||||
|
||||
//setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint);
|
||||
setWindowModality(Qt::NonModal);
|
||||
|
||||
// 시작시 표시 및 처리되지 않도록 시작
|
||||
#if !(TOGGLE_PLAYER)
|
||||
setAttribute(Qt::WA_DontShowOnScreen,true);
|
||||
setAttribute(Qt::WA_ShowWithoutActivating,true);
|
||||
#endif
|
||||
resize(640,480);
|
||||
|
||||
|
||||
_layout = new QVBoxLayout(this);
|
||||
_layout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
_layout->setMargin(0);
|
||||
_layout->setSpacing(0);
|
||||
|
||||
|
||||
|
||||
_toolbar = new QWidget(this);
|
||||
_toolbar->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
|
||||
_toolbar->setFixedHeight(36);
|
||||
_layout->addWidget(_toolbar);
|
||||
|
||||
_toolbar->setStyleSheet("background-color: #818181;");
|
||||
//_toolbar->setObjectName("test_widget");
|
||||
|
||||
QHBoxLayout* toolLayout = new QHBoxLayout(_toolbar);
|
||||
toolLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
toolLayout->setSpacing(6);
|
||||
toolLayout->setMargin(2);
|
||||
|
||||
QPushButton* btn;
|
||||
btn = button(_toolbar,toolLayout,"SAVE");
|
||||
|
||||
// _openButton = button(_toolbar,toolLayout,"OPEN");
|
||||
// _reloadButton = button(_toolbar,toolLayout,"RELOAD");
|
||||
// _stopButton = button(_toolbar,toolLayout,"STOP");
|
||||
// _stopButton->setEnabled(false);
|
||||
|
||||
// btn = button(_toolbar,toolLayout,"CLEAR");
|
||||
// btn = button(_toolbar,toolLayout,"DIR");
|
||||
|
||||
|
||||
_text = new QPlainTextEdit(this);
|
||||
_text->setReadOnly(true);
|
||||
_text->setStyleSheet("font-family: Fixedsys;color : #00FF00;background-color: #111111;border:1px;border-style:solid;border-color:#313131;");
|
||||
_text->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
|
||||
|
||||
|
||||
_layout->addWidget(_text);
|
||||
|
||||
_addSystemInfo();
|
||||
|
||||
}
|
||||
FELogDialog* FELogDialog::instance(QWidget* parent)
|
||||
{
|
||||
static FELogDialog * _instance = NULL;
|
||||
if ( _instance == NULL )
|
||||
{
|
||||
_instance = new FELogDialog(parent);
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
void FELogDialog::showEvent( QShowEvent* event )
|
||||
{
|
||||
QDialog::showEvent(event);
|
||||
//qInfo() << __FUNCTION__;
|
||||
|
||||
setUpdatesEnabled(false);
|
||||
|
||||
_text->clear();
|
||||
QVectorIterator<QString> iter(FELogHandler::buffer);
|
||||
while (iter.hasNext()) {
|
||||
_text->insertPlainText(iter.next() + "\n");
|
||||
}
|
||||
connect(FELogHandler::instance(),SIGNAL(appended(QString)),SLOT(onAppended(QString)),Qt::UniqueConnection);
|
||||
//QMetaObject::invokeMethod(this, "afterWindowShown", Qt::ConnectionType::QueuedConnection);
|
||||
|
||||
setUpdatesEnabled(true);
|
||||
}
|
||||
void FELogDialog::onAppended(QString msg)
|
||||
{
|
||||
QString ds = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz ");
|
||||
|
||||
//FELogHandler::printDebug(__FUNCTION__ + msg);
|
||||
_text->insertPlainText(ds + msg + "\n");
|
||||
|
||||
_text->verticalScrollBar()->setValue(_text->verticalScrollBar()->maximum());
|
||||
|
||||
}
|
||||
|
||||
void FELogDialog::onClose()
|
||||
{
|
||||
disconnect(FELogHandler::instance(),SIGNAL(appended(QString)),this,SLOT(onAppended(QString)));
|
||||
//qInfo() << __FUNCTION__;
|
||||
//_hideOnFullScreen = false;
|
||||
setHidden(true);
|
||||
close();
|
||||
//RMApp::instance()->pMainWindow->setFocus();
|
||||
}
|
||||
bool FELogDialog::isHiddenReal()
|
||||
{
|
||||
if(testAttribute(Qt::WA_DontShowOnScreen))
|
||||
{
|
||||
setAttribute(Qt::WA_DontShowOnScreen,false);
|
||||
setAttribute(Qt::WA_ShowWithoutActivating,false);
|
||||
setHidden(true);
|
||||
return true;
|
||||
}
|
||||
return isHidden();
|
||||
}
|
||||
void FELogDialog::_addSystemInfo()
|
||||
{
|
||||
FELogHandler::buffer.append("---------------------------------------------");
|
||||
FELogHandler::buffer.append("SYSTEM INFO.");
|
||||
FELogHandler::buffer.append("OS:" + QSysInfo::prettyProductName() + " (" + QSysInfo::currentCpuArchitecture() + ")");
|
||||
FELogHandler::buffer.append("KERNEL:" + QSysInfo::kernelType() + " VER " + QSysInfo::kernelVersion());
|
||||
QSettings settings("HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\BIOS", QSettings::NativeFormat);
|
||||
FELogHandler::buffer.append("Manufacturer:" + settings.value("SystemManufacturer", "0").toString());
|
||||
FELogHandler::buffer.append("Product:" + settings.value("SystemProductName", "0").toString());
|
||||
|
||||
QProcess process_system;
|
||||
QString system_output;
|
||||
QString cpuname = "wmic cpu get name";
|
||||
process_system.start(cpuname);
|
||||
process_system.waitForFinished();
|
||||
system_output = process_system.readAllStandardOutput().toUpper();
|
||||
|
||||
while(system_output.contains(" ")) {
|
||||
system_output = system_output.replace(" "," ");
|
||||
}
|
||||
FELogHandler::buffer.append("CPU:" + system_output.replace("\n","").replace("\r",""));
|
||||
|
||||
QString gpuname = "wmic PATH Win32_videocontroller get VideoProcessor ";
|
||||
process_system.start(gpuname);
|
||||
process_system.waitForFinished();
|
||||
system_output = process_system.readAllStandardOutput();
|
||||
while(system_output.contains(" ")) {
|
||||
system_output = system_output.replace(" "," ");
|
||||
}
|
||||
FELogHandler::buffer.append("GPU:" + system_output.replace("\n","").replace("\r",""));
|
||||
FELogHandler::buffer.append("---------------------------------------------");
|
||||
|
||||
}
|
||||
|
||||
#endif // #if (FE_LOG_VERSION)
|
||||
64
project/fm_viewer/tester/fe_log.h
Normal file
64
project/fm_viewer/tester/fe_log.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef FELOG_H
|
||||
#define FELOG_H
|
||||
|
||||
#if (FE_LOG_VERSION)
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QPushButton>
|
||||
//#include <QDebug>
|
||||
|
||||
#define FE_LOG_FL qInfo()//"[" << __FUNCTION__ << __LINE__ << "]"
|
||||
|
||||
class FELogHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
FELogHandler(QObject* parent = nullptr) : QObject(parent){}
|
||||
|
||||
public:
|
||||
static void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);
|
||||
static QVector<QString> buffer;
|
||||
static void printDebug(QString msg);
|
||||
|
||||
static FELogHandler* instance()
|
||||
{
|
||||
static FELogHandler _instance;
|
||||
return &_instance;
|
||||
}
|
||||
//static void myMessageHandler(QtMsgType, const QMessageLogContext &, const QString &);
|
||||
signals:
|
||||
void appended(QString msg);
|
||||
};
|
||||
|
||||
|
||||
class QPlainTextEdit;
|
||||
class QVBoxLayout;
|
||||
|
||||
class FELogDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
explicit FELogDialog(QWidget *parent = nullptr,Qt::WindowFlags f= Qt::WindowTitleHint | Qt::Dialog | Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint);
|
||||
QWidget* _toolbar;
|
||||
QPlainTextEdit* _text;
|
||||
QVBoxLayout* _layout;
|
||||
void _addSystemInfo();
|
||||
QPushButton* button(QWidget* parent,QLayout* layout,QString title);
|
||||
|
||||
protected:
|
||||
void showEvent( QShowEvent* event );
|
||||
public:
|
||||
static FELogDialog* instance(QWidget* parent = nullptr);
|
||||
bool isHiddenReal();
|
||||
void onClose();
|
||||
signals:
|
||||
public slots:
|
||||
void onAppended(QString msg);
|
||||
void onButton();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // FE_LOG_VERSION
|
||||
#endif // FELOG_H
|
||||
249
project/fm_viewer/tester/rm_design_dialog.cpp
Normal file
249
project/fm_viewer/tester/rm_design_dialog.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
#include "rm_design_dialog.h"
|
||||
#if (DESIGN_LAYOUT_MODE)
|
||||
#include "../rm_include.h"
|
||||
#include "../ui/window_main.h"
|
||||
#include <windows.h>
|
||||
#include <QDebug>
|
||||
#include <QMainWindow>
|
||||
#include <QDesktopServices>
|
||||
#include <QUrl>
|
||||
#include <QFileDialog>
|
||||
#include <QStyle>
|
||||
#include <QMessageBox>
|
||||
#include <QScrollBar>
|
||||
#include <QGraphicsOpacityEffect>
|
||||
#include <QMouseEvent>
|
||||
|
||||
FMDesignDialog* FMDesignDialog::instance(QWidget* parent)
|
||||
{
|
||||
static FMDesignDialog * _instance = NULL;
|
||||
if ( _instance == NULL )
|
||||
{
|
||||
_instance = new FMDesignDialog(parent);
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
FMDesignDialog::FMDesignDialog(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
QString version;
|
||||
version.sprintf("model:%s %d.%d.%d.%d",WINDOW_TITLE,RM_MODEL_VERSION_0,RM_MODEL_VERSION_1,RM_MODEL_VERSION_1,RM_MODEL_SVN_VERSION);
|
||||
this->setWindowModality(Qt::NonModal);
|
||||
this->setWindowTitle("DESIGN (" + version + ")");
|
||||
this->setWindowFlags(Qt::Window | Qt::Tool | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
|
||||
this->setWindowModality(Qt::NonModal);
|
||||
setMinimumSize(300,500);
|
||||
|
||||
_layout = new QVBoxLayout(this);
|
||||
_layout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
_layout->setMargin(0);
|
||||
_layout->setSpacing(0);
|
||||
|
||||
//_swap = false;
|
||||
|
||||
createToolbar();
|
||||
createSliderPanel();
|
||||
createParamConsole();
|
||||
}
|
||||
|
||||
void FMDesignDialog::showEvent(QShowEvent * event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
QRect r = RMApp::instance()->pMainWindow->geometry();
|
||||
r.moveLeft(1480);
|
||||
r.moveTop(190);
|
||||
setGeometry(r.right(),r.top(),300,500);
|
||||
|
||||
//loadPreset();
|
||||
}
|
||||
|
||||
void FMDesignDialog::createToolbar()
|
||||
{
|
||||
_toolbar = new QWidget(this);
|
||||
_toolbar->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
|
||||
_toolbar->setFixedHeight(36);
|
||||
_layout->addWidget(_toolbar);
|
||||
|
||||
_toolbar->setStyleSheet("background-color: #818181;");
|
||||
//_toolbar->setObjectName("test_widget");
|
||||
|
||||
QHBoxLayout* toolLayout = new QHBoxLayout(_toolbar);
|
||||
toolLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
toolLayout->setSpacing(6);
|
||||
toolLayout->setMargin(2);
|
||||
|
||||
_resetButton = _button(_toolbar,toolLayout,"RESET");
|
||||
|
||||
_button(_toolbar,toolLayout,"VR");
|
||||
_button(_toolbar,toolLayout,"WIDE");
|
||||
|
||||
_button(_toolbar,toolLayout,"GET");
|
||||
|
||||
_button(_toolbar,toolLayout,"SET");
|
||||
|
||||
_button(_toolbar,toolLayout,"SWAP");
|
||||
}
|
||||
void FMDesignDialog::createSliderPanel()
|
||||
{
|
||||
|
||||
QWidget* info = new QWidget(this);
|
||||
info->setStyleSheet("background-color: #616161;");
|
||||
//info->setObjectName("test_widget");
|
||||
info->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);
|
||||
//info->setFixedHeight(48);
|
||||
_layout->addWidget(info);
|
||||
|
||||
//info->setStyleSheet("background-color: #000000;");
|
||||
|
||||
|
||||
QVBoxLayout* infoLayout = new QVBoxLayout(info);
|
||||
infoLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||
infoLayout->setSpacing(2);
|
||||
infoLayout->setMargin(2);
|
||||
|
||||
_labels = new QList<QLabel*>();
|
||||
_sliders = new QList<QSlider*>();
|
||||
_resetButtons = new QList<QPushButton*>();
|
||||
|
||||
_slider(info,infoLayout,"ALPHA");
|
||||
}
|
||||
void FMDesignDialog::createParamConsole()
|
||||
{
|
||||
_paramTextEdit = new QPlainTextEdit(this);
|
||||
//_paramTextEdit->setReadOnly(true);
|
||||
_paramTextEdit->setStyleSheet("font-family: Fixedsys;color : #00FF00;background-color: #111111;border:1px;border-style:solid;border-color:#313131;");
|
||||
_paramTextEdit->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
|
||||
_layout->addWidget(_paramTextEdit);
|
||||
QString scrollStyle = "QScrollBar:vertical\
|
||||
{\
|
||||
border-width: 0px;\
|
||||
border-style: solid;\
|
||||
background: #3B3B3B;\
|
||||
width: 10px;\
|
||||
margin: 21px 0 21px 0;\
|
||||
}\
|
||||
QScrollBar::handle:vertical:disabled{background: #3B3B3B;}\
|
||||
QScrollBar::handle:vertical\
|
||||
{\
|
||||
border-width: 0px;\
|
||||
background: #6A74FF;\
|
||||
min-height: 25px;\
|
||||
}\
|
||||
QScrollBar::add-line:vertical\
|
||||
{\
|
||||
border: none;\
|
||||
background: none;\
|
||||
height: 20px;\
|
||||
width: 15px;\
|
||||
subcontrol-position: bottom;\
|
||||
subcontrol-origin: margin;\
|
||||
}\
|
||||
QScrollBar::sub-line:vertical\
|
||||
{\
|
||||
border: none;\
|
||||
background: none;\
|
||||
height: 20px;\
|
||||
width: 15px;\
|
||||
subcontrol-position: top;\
|
||||
subcontrol-origin: margin;\
|
||||
}\
|
||||
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical\
|
||||
{\
|
||||
background: none;\
|
||||
}\
|
||||
QScrollBar::up-arrow:vertical\
|
||||
{\
|
||||
border: none;\
|
||||
background: #5A5A5A;\
|
||||
}\
|
||||
QScrollBar::down-arrow:vertical\
|
||||
{\
|
||||
border: none;\
|
||||
background: #5A5A5A;\
|
||||
}";
|
||||
_paramTextEdit->verticalScrollBar()->setStyleSheet(scrollStyle);
|
||||
}
|
||||
QSlider* FMDesignDialog::_slider(QWidget* parent,QLayout* layout, QString title)
|
||||
{
|
||||
QWidget* view = new QWidget(parent);
|
||||
QHBoxLayout* viewLayout = new QHBoxLayout(view);
|
||||
viewLayout->setAlignment(Qt::AlignCenter);
|
||||
|
||||
layout->addWidget(view);
|
||||
|
||||
QLabel* tl = new QLabel(view);
|
||||
tl->setText(title);
|
||||
tl->setStyleSheet("font-family: Fixedsys;color : #F0F0F0;");
|
||||
viewLayout->addWidget(tl);
|
||||
|
||||
QSlider* slider = new QSlider(view);
|
||||
slider->setOrientation(Qt::Horizontal);
|
||||
slider->setMinimum(0);
|
||||
slider->setMaximum(100);
|
||||
slider->setValue(100);
|
||||
slider->setWindowTitle(title);
|
||||
|
||||
connect(slider,SIGNAL(valueChanged(int)),SLOT(onSliderChange(int)));
|
||||
|
||||
_sliders->append(slider);
|
||||
|
||||
viewLayout->addWidget(slider);
|
||||
QLabel* label = new QLabel(view);
|
||||
label->setText("0.500");
|
||||
label->setStyleSheet("font-family: Fixedsys;color : #F0F0F0;");
|
||||
_labels->append(label);
|
||||
|
||||
viewLayout->addWidget(label);
|
||||
|
||||
QPushButton* reset = _button(view,viewLayout,"RS");
|
||||
_resetButtons->append(reset);
|
||||
|
||||
return slider;
|
||||
}
|
||||
QPushButton* FMDesignDialog::_button(QWidget* parent,QLayout* layout,QString title)
|
||||
{
|
||||
QPushButton* btn = new QPushButton(parent);
|
||||
btn->setText(title);
|
||||
btn->setStyleSheet("QPushButton{font-family: Fixedsys;color : white;}"
|
||||
"QPushButton[enabled=\"false\"]{color : #AAAAAA;}");
|
||||
btn->setFixedWidth(title.length() * 10);
|
||||
layout->addWidget(btn);
|
||||
connect(btn,SIGNAL(clicked()),SLOT(onButton()));
|
||||
return btn;
|
||||
}
|
||||
|
||||
void FMDesignDialog::onSliderChange(int value)
|
||||
{
|
||||
QSlider* slider = qobject_cast<QSlider*>(sender());
|
||||
int index = _sliders->indexOf(slider);
|
||||
QLabel* label = _labels->at(index);
|
||||
QString str;
|
||||
double v = ((double)value)/((double)100.0);
|
||||
label->setText(str.sprintf("%.3f",v));
|
||||
|
||||
QString key = slider->windowTitle();
|
||||
if(key == "ALPHA")
|
||||
{
|
||||
WindowMain::instance()->alpha->setOpacity(v);
|
||||
}
|
||||
}
|
||||
void FMDesignDialog::onButton()
|
||||
{
|
||||
QPushButton* btn = qobject_cast<QPushButton*>(sender());
|
||||
QString cmd = btn->text().toUpper();
|
||||
//FAV::OpenGLVideo* opengl = (FAV::OpenGLVideo*)gl();
|
||||
if(cmd == "RESET")
|
||||
{
|
||||
for(int i=0;i<_sliders->count();i++)
|
||||
{
|
||||
_sliders->at(i)->setValue(0);
|
||||
}
|
||||
}
|
||||
else if (cmd == "RS")
|
||||
{
|
||||
int index = _resetButtons->indexOf(btn);
|
||||
_sliders->at(index)->setValue(0);
|
||||
}
|
||||
|
||||
}
|
||||
#endif // DESIGN_LAYOUT_MODE
|
||||
46
project/fm_viewer/tester/rm_design_dialog.h
Normal file
46
project/fm_viewer/tester/rm_design_dialog.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef RM_DESIGN_DIALOG_H
|
||||
#define RM_DESIGN_DIALOG_H
|
||||
#if (DESIGN_LAYOUT_MODE)
|
||||
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QLineEdit>
|
||||
#include <QSlider>
|
||||
|
||||
class FMDesignDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static FMDesignDialog* instance(QWidget* parent = nullptr);
|
||||
private:
|
||||
QVBoxLayout* _layout;
|
||||
|
||||
QWidget* _toolbar;
|
||||
QPushButton* _resetButton;
|
||||
|
||||
QList<QLabel*>* _labels;
|
||||
QList<QSlider*>* _sliders;
|
||||
QList<QPushButton*>* _resetButtons;
|
||||
QPlainTextEdit* _paramTextEdit;
|
||||
//bool _swap;
|
||||
|
||||
explicit FMDesignDialog(QWidget *parent = nullptr);
|
||||
void showEvent(QShowEvent * event);
|
||||
|
||||
void createToolbar();
|
||||
void createSliderPanel();
|
||||
void createParamConsole();
|
||||
|
||||
QPushButton* _button(QWidget* parent,QLayout* layout,QString title);
|
||||
QSlider* _slider(QWidget* parent,QLayout* layout, QString title);
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void onSliderChange(int value);
|
||||
void onButton();
|
||||
};
|
||||
#endif // DESIGN_LAYOUT_MODE
|
||||
#endif // RM_DESIGN_DIALOG_H
|
||||
8
project/fm_viewer/tester/rm_test_controls.cpp
Normal file
8
project/fm_viewer/tester/rm_test_controls.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "rm_test_controls.h"
|
||||
#if (RM_TESTING)
|
||||
RMTestControls::RMTestControls(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
25
project/fm_viewer/tester/rm_test_controls.h
Normal file
25
project/fm_viewer/tester/rm_test_controls.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef RM_TEST_CONTROLS_H
|
||||
#define RM_TEST_CONTROLS_H
|
||||
#if (RM_TESTING)
|
||||
#include <QObject>
|
||||
|
||||
class RMTestControls : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RMTestControls(QObject *parent = nullptr);
|
||||
static RMTestControls* instance()
|
||||
{
|
||||
static RMTestControls * _instance = 0;
|
||||
if ( _instance == 0 ) {
|
||||
_instance = new RMTestControls();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // RM_TEST_CONTROLS_H
|
||||
385
project/fm_viewer/tester/rm_test_dialog.cpp
Normal file
385
project/fm_viewer/tester/rm_test_dialog.cpp
Normal file
@@ -0,0 +1,385 @@
|
||||
#include "rm_test_dialog.h"
|
||||
#if (RM_TESTING)
|
||||
#include <windows.h>
|
||||
#include <QDebug>
|
||||
#include <QMainWindow>
|
||||
#include <QDesktopServices>
|
||||
#include <QUrl>
|
||||
#include <QFileDialog>
|
||||
#include <QStyle>
|
||||
#include <QMessageBox>
|
||||
#include <QScrollBar>
|
||||
#include "../rm_app.h"
|
||||
#include "../rm_settings.h"
|
||||
|
||||
RMDialogTest::RMDialogTest(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
QString version;
|
||||
version.sprintf("model:%s %d.%d.%d.%d",WINDOW_TITLE,RM_MODEL_VERSION_0,RM_MODEL_VERSION_1,RM_MODEL_VERSION_1,RM_MODEL_SVN_VERSION);
|
||||
this->setWindowModality(Qt::NonModal);
|
||||
this->setWindowTitle("DVR TESTER (" + version + ")");
|
||||
this->setWindowFlags(Qt::Window | Qt::Tool | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
|
||||
this->setWindowModality(Qt::NonModal);
|
||||
setMinimumSize(300,500);
|
||||
|
||||
_layout = new QVBoxLayout(this);
|
||||
_layout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
_layout->setMargin(0);
|
||||
_layout->setSpacing(0);
|
||||
|
||||
createToolbar();
|
||||
createInfoPanel();
|
||||
createLogConsole();
|
||||
createFilterEditor();
|
||||
|
||||
_process = NULL;
|
||||
}
|
||||
void RMDialogTest::createToolbar()
|
||||
{
|
||||
_toolbar = new QWidget(this);
|
||||
_toolbar->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
|
||||
_toolbar->setFixedHeight(36);
|
||||
_layout->addWidget(_toolbar);
|
||||
|
||||
_toolbar->setStyleSheet("background-color: #818181;");
|
||||
//_toolbar->setObjectName("test_widget");
|
||||
|
||||
QHBoxLayout* toolLayout = new QHBoxLayout(_toolbar);
|
||||
toolLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
toolLayout->setSpacing(6);
|
||||
toolLayout->setMargin(2);
|
||||
|
||||
QPushButton* btn;
|
||||
_runButton = button(_toolbar,toolLayout,"RUN");
|
||||
_runButton->setEnabled(false);
|
||||
|
||||
_openButton = button(_toolbar,toolLayout,"OPEN");
|
||||
_reloadButton = button(_toolbar,toolLayout,"RELOAD");
|
||||
_stopButton = button(_toolbar,toolLayout,"STOP");
|
||||
_stopButton->setEnabled(false);
|
||||
|
||||
btn = button(_toolbar,toolLayout,"CLEAR");
|
||||
btn = button(_toolbar,toolLayout,"DIR");
|
||||
}
|
||||
void RMDialogTest::createInfoPanel()
|
||||
{
|
||||
QWidget* info = new QWidget(this);
|
||||
info->setStyleSheet("background-color: #616161;");
|
||||
//info->setObjectName("test_widget");
|
||||
info->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);
|
||||
//info->setFixedHeight(48);
|
||||
_layout->addWidget(info);
|
||||
|
||||
QVBoxLayout* infoLayout = new QVBoxLayout(info);
|
||||
infoLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||
infoLayout->setSpacing(2);
|
||||
infoLayout->setMargin(2);
|
||||
|
||||
_scriptLabel = label(info,infoLayout,"Script:","NONE");
|
||||
_statusLabel = label(info,infoLayout,"Status:","----");
|
||||
_timerLabel = label(info,infoLayout,"Timer:","00:00:00");
|
||||
_loopLabel = label(info,infoLayout,"Loop:","000");
|
||||
}
|
||||
void RMDialogTest::createFilterEditor()
|
||||
{
|
||||
QWidget* filter = new QWidget(this);
|
||||
filter->setStyleSheet("background-color: #818181;");
|
||||
_layout->addWidget(filter);
|
||||
|
||||
QHBoxLayout* filterLayout = new QHBoxLayout(filter);
|
||||
filterLayout->setMargin(0);
|
||||
filterLayout->setSpacing(0);
|
||||
|
||||
|
||||
_filterEdit = new QLineEdit(filter);
|
||||
_filterEdit->setStyleSheet("font-family: Fixedsys;color : #6666FF;background-color: #111111;border:1px;border-style:solid;border-color:#313131;");
|
||||
_filterEdit->setText("format=pix_fmts=rgb24,lenscorrection=cx=0.5:cy=0.5:k1=-.8:k2=-.0");
|
||||
filterLayout->addWidget(_filterEdit);
|
||||
|
||||
button(filter,filterLayout,"FA");
|
||||
button(filter,filterLayout,"FC");
|
||||
}
|
||||
|
||||
void RMDialogTest::createLogConsole()
|
||||
{
|
||||
_logTextEdit = new QPlainTextEdit(this);
|
||||
_logTextEdit->setReadOnly(true);
|
||||
_logTextEdit->setStyleSheet("font-family: Fixedsys;color : #00FF00;background-color: #111111;border:1px;border-style:solid;border-color:#313131;");
|
||||
_logTextEdit->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
|
||||
_layout->addWidget(_logTextEdit);
|
||||
QString scrollStyle = "QScrollBar:vertical\
|
||||
{\
|
||||
border-width: 0px;\
|
||||
border-style: solid;\
|
||||
background: #3B3B3B;\
|
||||
width: 10px;\
|
||||
margin: 21px 0 21px 0;\
|
||||
}\
|
||||
QScrollBar::handle:vertical:disabled{background: #3B3B3B;}\
|
||||
QScrollBar::handle:vertical\
|
||||
{\
|
||||
border-width: 0px;\
|
||||
background: #6A74FF;\
|
||||
min-height: 25px;\
|
||||
}\
|
||||
QScrollBar::add-line:vertical\
|
||||
{\
|
||||
border: none;\
|
||||
background: none;\
|
||||
height: 20px;\
|
||||
width: 15px;\
|
||||
subcontrol-position: bottom;\
|
||||
subcontrol-origin: margin;\
|
||||
}\
|
||||
QScrollBar::sub-line:vertical\
|
||||
{\
|
||||
border: none;\
|
||||
background: none;\
|
||||
height: 20px;\
|
||||
width: 15px;\
|
||||
subcontrol-position: top;\
|
||||
subcontrol-origin: margin;\
|
||||
}\
|
||||
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical\
|
||||
{\
|
||||
background: none;\
|
||||
}\
|
||||
QScrollBar::up-arrow:vertical\
|
||||
{\
|
||||
border: none;\
|
||||
background: #5A5A5A;\
|
||||
}\
|
||||
QScrollBar::down-arrow:vertical\
|
||||
{\
|
||||
border: none;\
|
||||
background: #5A5A5A;\
|
||||
}";
|
||||
_logTextEdit->verticalScrollBar()->setStyleSheet(scrollStyle);
|
||||
}
|
||||
|
||||
QLabel* RMDialogTest::label(QWidget* parent,QLayout* layout,QString title,QString text)
|
||||
{
|
||||
QWidget* row = new QWidget(parent);
|
||||
layout->addWidget(row);
|
||||
|
||||
QHBoxLayout* hLayout = new QHBoxLayout(row);
|
||||
hLayout->setMargin(0);
|
||||
hLayout->setSpacing(0);
|
||||
hLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
|
||||
QLabel* label = new QLabel(row);
|
||||
label->setText(title);
|
||||
label->setStyleSheet("font-family: Fixedsys;color : #F0F0F0;");
|
||||
hLayout->addWidget(label);
|
||||
label->setFixedWidth(72);
|
||||
|
||||
QLabel* textLabel = new QLabel(row);
|
||||
textLabel->setText(text);
|
||||
textLabel->setStyleSheet("font-family: Fixedsys;color : white;");
|
||||
hLayout->addWidget(textLabel);
|
||||
return textLabel;
|
||||
}
|
||||
|
||||
QPushButton* RMDialogTest::button(QWidget* parent,QLayout* layout,QString title)
|
||||
{
|
||||
QPushButton* btn = new QPushButton(parent);
|
||||
btn->setText(title);
|
||||
//btn->setStyleSheet("font-family: Arial;font-size: 9px;");
|
||||
btn->setStyleSheet("QPushButton{font-family: Fixedsys;color : white;}"
|
||||
"QPushButton[enabled=\"false\"]{color : #AAAAAA;}");
|
||||
btn->setFixedWidth(title.length() * 10);
|
||||
layout->addWidget(btn);
|
||||
connect(btn,SIGNAL(clicked()),SLOT(onButton()));
|
||||
return btn;
|
||||
}
|
||||
void RMDialogTest::onButton()
|
||||
{
|
||||
|
||||
QPushButton* btn = qobject_cast<QPushButton*>(sender());
|
||||
QString cmd = btn->text().toUpper();
|
||||
|
||||
if(cmd == "DIR")
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(RMApp::instance()->appPath(RMApp::SCRIPT)));
|
||||
}
|
||||
else if(cmd == "OPEN")
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(
|
||||
this,
|
||||
"OPEN",
|
||||
RMApp::instance()->appPath(RMApp::SCRIPT),
|
||||
"SCRIPT (*.txt)");
|
||||
|
||||
if(fileName.length() > 0)
|
||||
{
|
||||
openScript(fileName);
|
||||
}
|
||||
}
|
||||
else if(cmd == "RELOAD" && _process != NULL)
|
||||
{
|
||||
openScript(_process->filePath);
|
||||
}
|
||||
else if(cmd == "CLEAR")
|
||||
{
|
||||
_logTextEdit->clear();
|
||||
}
|
||||
else if (cmd == "FA")
|
||||
{
|
||||
RMPlayer::instance()->applyTestFilter(_filterEdit->text());
|
||||
}
|
||||
else if (cmd == "FC")
|
||||
{
|
||||
RMPlayer::instance()->applyTestFilter("");
|
||||
}
|
||||
}
|
||||
void RMDialogTest::onStatusMessage(QString message)
|
||||
{
|
||||
_statusLabel->setText(message);
|
||||
}
|
||||
void RMDialogTest::clearProcess()
|
||||
{
|
||||
if (_process != NULL)
|
||||
{
|
||||
disconnect(_runButton,SIGNAL(clicked()),this,SLOT(onRunProcess()));
|
||||
disconnect(_stopButton,SIGNAL(clicked()),this,SLOT(onStopProcess()));
|
||||
disconnect(_process,SIGNAL(statusChange(QString)),this,SLOT(onStatusMessage(QString)));
|
||||
disconnect(_process,SIGNAL(log(QString)),this,SLOT(onLog(QString)));
|
||||
disconnect(_process,SIGNAL(error(QString)),this,SLOT(onError(QString)));
|
||||
delete _process;
|
||||
_process = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void RMDialogTest::openScript(QString path)
|
||||
{
|
||||
clearProcess();
|
||||
_process = new RMTestProcess(this,path);
|
||||
connect(_runButton,SIGNAL(clicked()),SLOT(onRunProcess()));
|
||||
connect(_stopButton,SIGNAL(clicked()),SLOT(onStopProcess()));
|
||||
connect(_process,SIGNAL(statusChange(QString)),this,SLOT(onStatusMessage(QString)));
|
||||
connect(_process,SIGNAL(log(QString)),this,SLOT(onLog(QString)));
|
||||
connect(_process,SIGNAL(error(QString)),this,SLOT(onError(QString)));
|
||||
refreshRunStopButton();
|
||||
|
||||
QFileInfo fi(path);
|
||||
_scriptLabel->setText(fi.baseName() + "(" + QString::number(_process->count()) + ")");
|
||||
|
||||
RMSettings::instance()->setLastScript(path);
|
||||
}
|
||||
void RMDialogTest::refreshRunStopButton()
|
||||
{
|
||||
_runButton->setEnabled((_process != NULL && _process->isRunning() == false));
|
||||
_runButton->style()->unpolish(_runButton);
|
||||
_runButton->style()->polish(_runButton);
|
||||
|
||||
_openButton->setEnabled((_process == NULL || _process->isRunning() == false));
|
||||
_openButton->style()->unpolish(_openButton);
|
||||
_openButton->style()->polish(_openButton);
|
||||
|
||||
_reloadButton->setEnabled((_process != NULL && _process->isRunning() == false));
|
||||
_reloadButton->style()->unpolish(_reloadButton);
|
||||
_reloadButton->style()->polish(_reloadButton);
|
||||
|
||||
_stopButton->setEnabled((_process != NULL && _process->isRunning() == true));
|
||||
_stopButton->style()->unpolish(_stopButton);
|
||||
_stopButton->style()->polish(_stopButton);
|
||||
|
||||
_statusLabel->setText((_process != NULL && _process->isRunning()) ? "running" : "stopped");
|
||||
}
|
||||
|
||||
void RMDialogTest::onRunProcess()
|
||||
{
|
||||
if(_process == NULL || _process->isRunning())
|
||||
{
|
||||
return;
|
||||
}
|
||||
connect(_process,SIGNAL(timer(qint64)),SLOT(onTimer(qint64)));
|
||||
connect(_process,SIGNAL(loopChange(int)),SLOT(onLoopChange(int)));
|
||||
|
||||
_process->onRun();
|
||||
refreshRunStopButton();
|
||||
}
|
||||
void RMDialogTest::onStopProcess()
|
||||
{
|
||||
if(_process == NULL || _process->isRunning() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
disconnect(_process,SIGNAL(timer(qint64)),this,SLOT(onTimer(qint64)));
|
||||
disconnect(_process,SIGNAL(loopChange(int)),this,SLOT(onLoopChange(int)));
|
||||
_process->onStop();
|
||||
refreshRunStopButton();
|
||||
}
|
||||
void RMDialogTest::onTimer(qint64 msec)
|
||||
{
|
||||
int sec = msec;
|
||||
int h = 0;
|
||||
int m = 0;
|
||||
int s = 0;
|
||||
if(sec > 3600000)
|
||||
{
|
||||
h = sec / 3600000;
|
||||
sec = sec - (h * 3600000);
|
||||
}
|
||||
if(sec > 60)
|
||||
{
|
||||
m = sec / 60000;
|
||||
sec = sec - (m * 60000);
|
||||
}
|
||||
s = sec;
|
||||
|
||||
QString timeString;
|
||||
timeString.sprintf("%02d:%02d:%04.1f",h,m,(double)s/1000.0);
|
||||
_timerLabel->setText(timeString);
|
||||
}
|
||||
void RMDialogTest::onLoopChange(int loop)
|
||||
{
|
||||
QString str;
|
||||
str.sprintf("%03d",loop);
|
||||
_loopLabel->setText(str);
|
||||
}
|
||||
void RMDialogTest::onLog(QString log)
|
||||
{
|
||||
_logTextEdit->appendPlainText(log);
|
||||
}
|
||||
void RMDialogTest::onError(QString message)
|
||||
{
|
||||
// 일단 정지
|
||||
// if(RMPlayer::instance()->playerF()->isPaused() == false)
|
||||
// {
|
||||
// RMPlayer::instance()->onPlayOrPause();
|
||||
// }
|
||||
|
||||
::Beep(500,1000);
|
||||
onStopProcess();
|
||||
clearProcess();
|
||||
refreshRunStopButton();
|
||||
QMessageBox::warning(this,"ERROR",message,QMessageBox::Ok,QMessageBox::NoButton);
|
||||
|
||||
}
|
||||
|
||||
RMDialogTest* RMDialogTest::instance(QWidget* parent)
|
||||
{
|
||||
static RMDialogTest * _instance = NULL;
|
||||
if ( _instance == NULL )
|
||||
{
|
||||
_instance = new RMDialogTest(parent);
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
void RMDialogTest::showEvent(QShowEvent * event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
QRect r = RMApp::instance()->pMainWindow->geometry();
|
||||
r.moveLeft(460);
|
||||
r.moveTop(190);
|
||||
setGeometry(r.right(),r.top(),300,500);
|
||||
|
||||
QString script = RMSettings::instance()->lastScript();
|
||||
if(script.length() > 0 && QFile::exists(script))
|
||||
{
|
||||
openScript(script);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #if (RM_TESTING)
|
||||
67
project/fm_viewer/tester/rm_test_dialog.h
Normal file
67
project/fm_viewer/tester/rm_test_dialog.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#ifndef RM_TEST_DIALOG_H
|
||||
#define RM_TEST_DIALOG_H
|
||||
#if (RM_TESTING)
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QLineEdit>
|
||||
|
||||
#include "rm_test_process.h"
|
||||
|
||||
class RMDialogTest : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static RMDialogTest* instance(QWidget* parent = nullptr);
|
||||
private:
|
||||
QVBoxLayout* _layout;
|
||||
|
||||
RMTestProcess* _process;
|
||||
|
||||
QWidget* _toolbar;
|
||||
QPushButton* _openButton;
|
||||
QPushButton* _runButton;
|
||||
QPushButton* _stopButton;
|
||||
QPushButton* _reloadButton;
|
||||
|
||||
QLabel* _scriptLabel;
|
||||
QLabel* _statusLabel;
|
||||
QLabel* _timerLabel;
|
||||
QLabel* _loopLabel;
|
||||
QPlainTextEdit* _logTextEdit;
|
||||
|
||||
QLineEdit* _filterEdit;
|
||||
|
||||
explicit RMDialogTest(QWidget *parent = nullptr);
|
||||
void showEvent(QShowEvent * event);
|
||||
|
||||
void createToolbar();
|
||||
QPushButton* button(QWidget* parent,QLayout* layout,QString title);
|
||||
void createInfoPanel();
|
||||
QLabel* label(QWidget* parent,QLayout* layout,QString title,QString text);
|
||||
void createLogConsole();
|
||||
void createFilterEditor();
|
||||
|
||||
void refreshRunStopButton();
|
||||
|
||||
void clearProcess();
|
||||
void openScript(QString path);
|
||||
|
||||
void beep();
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void onButton();
|
||||
void onRunProcess();
|
||||
void onStopProcess();
|
||||
void onTimer(qint64 msec);
|
||||
void onLoopChange(int loop);
|
||||
void onStatusMessage(QString message);
|
||||
void onLog(QString log);
|
||||
void onError(QString message);
|
||||
};
|
||||
|
||||
#endif // #if (RM_TESTING)
|
||||
#endif // RM_TEST_DIALOG_H
|
||||
461
project/fm_viewer/tester/rm_test_process.cpp
Normal file
461
project/fm_viewer/tester/rm_test_process.cpp
Normal file
@@ -0,0 +1,461 @@
|
||||
#include "rm_test_process.h"
|
||||
#if (RM_TESTING)
|
||||
//#include <windows.h>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QMouseEvent>
|
||||
#include <QFileInfo>
|
||||
#include "../data/rm_video_list.h"
|
||||
#include "../ui/window_main.h"
|
||||
#include "../ui/rm_frame_right.h"
|
||||
#include "../ui/rm_frame_left.h"
|
||||
#include "../ui/rm_frame_list.h"
|
||||
#include "../ui/rm_frame_play.h"
|
||||
#include "../ui/rm_frame_slider.h"
|
||||
#include "../ui/rm_button.h"
|
||||
#include "../ui/rm_play_slider.h"
|
||||
#include "../ui/rm_slider.h"
|
||||
#include "../ui/rm_frame_video_sub.h"
|
||||
#include "../ui/rm_frame_video_main.h"
|
||||
|
||||
|
||||
RMTestProcess::RMTestProcess(QObject *parent,QString path) : QObject(parent)
|
||||
{
|
||||
_optionLogDrawFrame = false;
|
||||
_optionLogFileName = false;
|
||||
|
||||
_timer = NULL;
|
||||
_running = false;
|
||||
_processDelay = 1000; // 기본값 1초?
|
||||
_loop = 0;
|
||||
_nextFileTimeout = -1;
|
||||
_nextFileWatchTimer = NULL;
|
||||
|
||||
|
||||
load(path);
|
||||
|
||||
// PLAY_EVENT
|
||||
connect(RMPlayer::instance(),SIGNAL(playEvent(PLAY_EVENT,RMVideoItem*)),SLOT(onPlayEvent(PLAY_EVENT,RMVideoItem*)));
|
||||
}
|
||||
void RMTestProcess::onPlayEvent(PLAY_EVENT event,RMVideoItem* item)
|
||||
{
|
||||
if(_running == false) {
|
||||
return;
|
||||
}
|
||||
// LOG 처리
|
||||
|
||||
if (event == PLAY_DID_LOADED)
|
||||
{
|
||||
QFileInfo f1(item->filePath);
|
||||
QString name = f1.baseName();
|
||||
#if !(DUAL_CH_FILE)
|
||||
if(name.endsWith("_1") || name.endsWith("_2"))
|
||||
{
|
||||
name = name.remove(name.length()-3,2);
|
||||
}
|
||||
#endif
|
||||
lastFileName = name;
|
||||
|
||||
// 파일명 표시 로그
|
||||
if(_optionLogFileName)
|
||||
{
|
||||
//QApplication::beep();
|
||||
emit log("->" + name);
|
||||
}
|
||||
|
||||
if(_nextFileTimeout > 0)
|
||||
{
|
||||
if(_nextFileWatchTimer != NULL)
|
||||
{
|
||||
_nextFileWatchTimer->stop();
|
||||
delete _nextFileWatchTimer;
|
||||
_nextFileWatchTimer = NULL;
|
||||
}
|
||||
_nextFileWatchTimer = new QTimer(this);
|
||||
_nextFileWatchTimer->setSingleShot(true);
|
||||
_nextFileWatchTimer->setInterval(_nextFileTimeout);
|
||||
connect(_nextFileWatchTimer,SIGNAL(timeout()),SLOT(onFileTimeout()));
|
||||
_nextFileWatchTimer->start();
|
||||
|
||||
}
|
||||
}
|
||||
else if(event == PLAY_DID_CLEARED)
|
||||
{
|
||||
// DRAW FRAME COUNT 표시
|
||||
if(_optionLogDrawFrame)
|
||||
{
|
||||
int f = RMPlayer::instance()->playerF()->displyedFrameCount();
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
int r = RMPlayer::instance()->playerR()->displyedFrameCount();
|
||||
if(f > 0 || r > 0)
|
||||
#else
|
||||
if(f > 0)
|
||||
#endif
|
||||
{
|
||||
QString str;
|
||||
#if (SINGLE_CH_VIEWER)
|
||||
str.sprintf("DRAW FRAME:F:%d",RMPlayer::instance()->playerF()->displyedFrameCount());
|
||||
#else
|
||||
str.sprintf("DRAW FRAME:F:%d,R:%d",RMPlayer::instance()->playerF()->displyedFrameCount(),RMPlayer::instance()->playerR()->displyedFrameCount());
|
||||
#endif
|
||||
emit log(str);
|
||||
|
||||
#if (SINGLE_CH_VIEWER)
|
||||
if(f <= 0)
|
||||
#else
|
||||
if(f <= 0 || r <= 0)
|
||||
#endif
|
||||
{
|
||||
_running = false;
|
||||
emit error(str);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(_waitPlayEvent == event)
|
||||
{
|
||||
// 다음 프로세스로 이동
|
||||
QTimer::singleShot(_processDelay,Qt::PreciseTimer,this,SLOT(onProcessNext()));
|
||||
_waitPlayEvent = PLAY_UNDEFINED;
|
||||
}
|
||||
|
||||
}
|
||||
void RMTestProcess::onFileTimeout()
|
||||
{
|
||||
if(_nextFileWatchTimer != NULL)
|
||||
{
|
||||
_nextFileWatchTimer->stop();
|
||||
delete _nextFileWatchTimer;
|
||||
_nextFileWatchTimer = NULL;
|
||||
}
|
||||
_running = false;
|
||||
emit error("FILE TIME OUT");
|
||||
}
|
||||
|
||||
void RMTestProcess::load(QString path)
|
||||
{
|
||||
QFile file(path);
|
||||
if(!file.open(QIODevice::ReadOnly)) {
|
||||
QMessageBox::information(0, "error", file.errorString());
|
||||
}
|
||||
|
||||
QTextStream in(&file);
|
||||
while(!in.atEnd()) {
|
||||
QString line = in.readLine();
|
||||
|
||||
// comment 처리
|
||||
if(line.length() < 2 || line.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 전체 옵션 처리
|
||||
if(line.startsWith("$"))
|
||||
{
|
||||
if(line.toUpper() == "$LOG_DRAW_FRAME")
|
||||
{
|
||||
_optionLogDrawFrame = true;
|
||||
}
|
||||
else if(line.toUpper() == "$LOG_FILE_NAME")
|
||||
{
|
||||
_optionLogFileName = true;
|
||||
}
|
||||
else if(line.toUpper().startsWith("$PROCESS_DELAY") && line.contains("="))
|
||||
{
|
||||
_processDelay = line.split("=").last().toInt();
|
||||
}
|
||||
else if(line.toUpper().startsWith("$WATCH_TIMEOUT") && line.contains("="))
|
||||
{
|
||||
_nextFileTimeout = line.split("=").last().toInt();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
QStringList fields = line.split(",");
|
||||
processes.append(fields);
|
||||
//model->appendRow(fields);
|
||||
}
|
||||
file.close();
|
||||
filePath = path;
|
||||
_running = false;
|
||||
}
|
||||
int RMTestProcess::count()
|
||||
{
|
||||
return processes.count();
|
||||
}
|
||||
|
||||
bool RMTestProcess::isRunning()
|
||||
{
|
||||
return _running;
|
||||
}
|
||||
void RMTestProcess::onRun()
|
||||
{
|
||||
// foreach (QStringList process, processes) {
|
||||
// qInfo() << "CMD:" << process.first() << ":" << process.last();
|
||||
// }
|
||||
_processIndex = 0;
|
||||
_running = true;
|
||||
|
||||
elapsedTimer.start();
|
||||
_timer = new QTimer(this);
|
||||
_timer->setSingleShot(false);
|
||||
_timer->setInterval(100);
|
||||
connect(_timer,SIGNAL(timeout()),SLOT(onSyncTime()));
|
||||
_timer->start();
|
||||
//qInfo() << "TIMER START";
|
||||
_loop = 1;
|
||||
emit loopChange(_loop);
|
||||
|
||||
QTimer::singleShot(_processDelay,Qt::PreciseTimer,this,SLOT(onProcessNext()));
|
||||
}
|
||||
|
||||
void RMTestProcess::makeClick(QWidget* control,float x)
|
||||
{
|
||||
//qInfo() << __FUNCTION__ << control << x;
|
||||
QPoint pos = control->rect().center();
|
||||
if(x > 0.0f)
|
||||
{
|
||||
pos.setX( (int)(((float)control->rect().size().width()) * (float)x));
|
||||
}
|
||||
|
||||
//qInfo() << __FUNCTION__ << pos << " global:" << control->mapToGlobal(pos);
|
||||
|
||||
QMouseEvent* pEvent = new QMouseEvent(QEvent::MouseButtonPress,
|
||||
pos,
|
||||
control->mapToGlobal(pos),
|
||||
Qt::LeftButton,
|
||||
Qt::LeftButton,
|
||||
Qt::NoModifier);
|
||||
|
||||
QApplication::instance()->sendEvent(control,pEvent);
|
||||
QThread::msleep((rand() % 20) + 10);
|
||||
|
||||
pos.setX(pos.x() + ((rand() % 4) - 2));
|
||||
pos.setY(pos.y() + ((rand() % 4) - 2));
|
||||
QMouseEvent* pEventM = new QMouseEvent(QEvent::MouseMove,
|
||||
pos,
|
||||
control->mapToGlobal(pos),
|
||||
Qt::LeftButton,
|
||||
Qt::LeftButton,
|
||||
Qt::NoModifier);
|
||||
|
||||
QApplication::instance()->sendEvent(control,pEventM);
|
||||
QThread::msleep((rand() % 20) + 10);
|
||||
|
||||
pos.setX(pos.x() + ((rand() % 4) - 2));
|
||||
pos.setY(pos.y() + ((rand() % 4) - 2));
|
||||
QMouseEvent* pEvent2 = new QMouseEvent(QEvent::MouseButtonRelease,
|
||||
pos,
|
||||
control->mapToGlobal(pos),
|
||||
Qt::LeftButton,
|
||||
Qt::LeftButton,
|
||||
Qt::NoModifier);
|
||||
QApplication::instance()->sendEvent(control,pEvent2);
|
||||
}
|
||||
|
||||
// rand(0.7-0.9) 구문 처리
|
||||
float RMTestProcess::parseRandFloat(QString range)
|
||||
{
|
||||
if(range.startsWith("RAND(") && range.endsWith(")") && range.contains("-"))
|
||||
{
|
||||
QString cleared = range.remove(0,5); // "RAND("
|
||||
cleared = cleared.remove(cleared.length()-1,1); // ")"
|
||||
QStringList ls = cleared.split("-");
|
||||
int f1 = (int)(ls.first().toFloat() * 1000.0f);
|
||||
int f2 = (int)(ls.last().toFloat() * 1000.0f);
|
||||
|
||||
int res = (rand() % (f2 - f1)) + f1;
|
||||
return ((float)res) / 1000.0f;
|
||||
}
|
||||
return range.toFloat();
|
||||
}
|
||||
int RMTestProcess::parseRandInt(QString range)
|
||||
{
|
||||
if(range.startsWith("RAND(") && range.endsWith(")") && range.contains("-"))
|
||||
{
|
||||
QString cleared = range.remove(0,5);
|
||||
cleared = cleared.remove(cleared.length()-1,1); // ")"
|
||||
QStringList ls = cleared.split("-");
|
||||
int f1 = ls.first().toInt();
|
||||
int f2 = ls.last().toInt();
|
||||
|
||||
int res = (rand() % (f2 - f1)) + f1;
|
||||
return res;
|
||||
}
|
||||
return range.toInt();
|
||||
}
|
||||
|
||||
void RMTestProcess::onProcessNext()
|
||||
{
|
||||
if(_running == false)
|
||||
{
|
||||
//qInfo() << "STOP PROCESS";
|
||||
return;
|
||||
}
|
||||
|
||||
if(_processIndex >= processes.count())
|
||||
{
|
||||
_processIndex = 0;
|
||||
_loop += 1;
|
||||
emit loopChange(_loop);
|
||||
}
|
||||
QStringList list = processes.at(_processIndex);
|
||||
QString cmd = list.first().toUpper();
|
||||
|
||||
list.removeFirst();
|
||||
qint64 wait = _processDelay;
|
||||
|
||||
QMap<QString,QString> params;
|
||||
|
||||
foreach (QString param, list)
|
||||
{
|
||||
QStringList cmdp = param.split("=");
|
||||
|
||||
// 2의 배수 cmd = param
|
||||
if (cmdp.count() % 2 != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// PARAMETER 처리
|
||||
for(int i=0;i<cmdp.count()/2;i++)
|
||||
{
|
||||
QString scmd = cmdp.at((i*2)+0).toUpper();
|
||||
QString sparam = cmdp.at((i*2)+1).toUpper();
|
||||
params.insert(scmd,sparam);
|
||||
}
|
||||
}
|
||||
|
||||
// 프로세스 추가
|
||||
_processIndex += 1;
|
||||
|
||||
// LOOP 확인하여 처리
|
||||
if(params.contains("LOOP"))
|
||||
{
|
||||
int loop = params.value("LOOP","0").toInt();
|
||||
if(_loop != loop)
|
||||
{
|
||||
QTimer::singleShot(0,Qt::PreciseTimer,this,SLOT(onProcessNext()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 대기시작 확인
|
||||
if(params.contains("WAIT"))
|
||||
{
|
||||
wait = parseRandInt(params.value("WAIT","0"));
|
||||
}
|
||||
|
||||
QString statusMessage = cmd;
|
||||
|
||||
|
||||
WindowMain* pWin = (WindowMain*)RMApp::instance()->pMainWindow;
|
||||
|
||||
// 다음 명령 실행 or 대기
|
||||
bool runNext = true;
|
||||
|
||||
// 명령 실행
|
||||
if(cmd == "OPEN" && params.contains("PATH"))
|
||||
{
|
||||
// 연결 -> onLoadingListDone 에서 처리
|
||||
connect(RMVideoFileList::instance(),SIGNAL(listUpdateEnd(bool)),this,SLOT(onLoadingListEnd(bool)));
|
||||
pWin->_frameRight->frameList->openFolder(params.value("PATH"));
|
||||
runNext = false;
|
||||
}
|
||||
else if(cmd == "CLICK" && params.contains("CONTROL"))
|
||||
{
|
||||
QString buttonName = params.value("CONTROL");
|
||||
statusMessage += (" " + buttonName);
|
||||
|
||||
if(buttonName == "PLAY")
|
||||
{
|
||||
makeClick(pWin->_frameLeft->framePlay->playButton);
|
||||
_waitPlayEvent = PLAY_DID_PLAYED; // 재생 시작까지 대기
|
||||
runNext = false;
|
||||
}
|
||||
else if (buttonName == "SLIDER")
|
||||
{
|
||||
float x = 0.5;
|
||||
if(params.contains("X"))
|
||||
{
|
||||
x = parseRandFloat(params.value("X"));
|
||||
}
|
||||
makeClick(pWin->_frameLeft->frameSlider->playSlider->slider,x);
|
||||
}
|
||||
else if (buttonName == "SWAP")
|
||||
{
|
||||
makeClick(pWin->_frameRight->frameVideoSub->_toggleButton);
|
||||
}
|
||||
else if (buttonName == "VOLUME")
|
||||
{
|
||||
float x = 0.5;
|
||||
if(params.contains("X"))
|
||||
{
|
||||
x = parseRandFloat(params.value("X"));
|
||||
}
|
||||
makeClick(pWin->_frameLeft->frameSlider->volumeSlider,x);
|
||||
}
|
||||
|
||||
|
||||
//CLICK,button=play)
|
||||
}
|
||||
else if(cmd == "WAIT" && params.contains("FOR"))
|
||||
{
|
||||
QString eventName = params.value("FOR");
|
||||
if(eventName == "PLAY_DID_PLAYED")
|
||||
{
|
||||
statusMessage += " FOR NEXT PLAY";
|
||||
_waitPlayEvent = PLAY_DID_PLAYED;
|
||||
}
|
||||
else if(eventName == "PLAY_DID_LOADED")
|
||||
{
|
||||
statusMessage += " FOR NEXT LOADED";
|
||||
_waitPlayEvent = PLAY_DID_LOADED;
|
||||
}
|
||||
else if(eventName == "PLAY_DID_CLEARED")
|
||||
{
|
||||
statusMessage += " FOR NEXT CLEARED";
|
||||
_waitPlayEvent = PLAY_DID_CLEARED;
|
||||
}
|
||||
else if(eventName == "PLAY_CUSTOM_EVENT")
|
||||
{
|
||||
statusMessage += " FOR NEXT CUSTOM";
|
||||
_waitPlayEvent = PLAY_CUSTOM_EVENT;
|
||||
}
|
||||
runNext = false;
|
||||
}
|
||||
|
||||
emit statusChange(statusMessage);
|
||||
|
||||
|
||||
// 다음 명령 실행
|
||||
if(runNext == true)
|
||||
{
|
||||
QTimer::singleShot(wait,Qt::PreciseTimer,this,SLOT(onProcessNext()));
|
||||
}
|
||||
}
|
||||
|
||||
void RMTestProcess::onSyncTime()
|
||||
{
|
||||
//qInfo() << __FUNCTION__;
|
||||
emit timer(elapsedTimer.elapsed());
|
||||
}
|
||||
|
||||
void RMTestProcess::onStop()
|
||||
{
|
||||
elapsedTimer.invalidate();
|
||||
_running = false;
|
||||
}
|
||||
void RMTestProcess::onLoadingListEnd(bool bLoading)
|
||||
{
|
||||
Q_UNUSED(bLoading);
|
||||
disconnect(RMVideoFileList::instance(),SIGNAL(listUpdateEnd(bool)),this,SLOT(onLoadingListEnd(bool)));
|
||||
|
||||
// 다음 프로세스로 이동
|
||||
QTimer::singleShot(_processDelay,Qt::PreciseTimer,this,SLOT(onProcessNext()));
|
||||
|
||||
}
|
||||
|
||||
#endif // #if (RM_TESTING)
|
||||
73
project/fm_viewer/tester/rm_test_process.h
Normal file
73
project/fm_viewer/tester/rm_test_process.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#ifndef RM_TEST_PROCESS_H
|
||||
#define RM_TEST_PROCESS_H
|
||||
#if (RM_TESTING)
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include "../core/rm_player.h"
|
||||
#include "../core/rm_player_base.h"
|
||||
|
||||
//#define DVR_TESTER_VERSION "0.2"
|
||||
|
||||
class RMTestProcess : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RMTestProcess(QObject *parent,QString path);
|
||||
bool isRunning();
|
||||
QString filePath;
|
||||
int count();
|
||||
|
||||
// OPTION
|
||||
private:
|
||||
bool _optionLogDrawFrame; // 프레임 DRAW 확인
|
||||
bool _optionLogFileName; // 재생 파일명 확인
|
||||
int _nextFileTimeout; // 다음파일 대기
|
||||
QTimer* _nextFileWatchTimer; // 다음파일 대기 타이머
|
||||
private:
|
||||
QString lastFileName;
|
||||
|
||||
private:
|
||||
void load(QString path);
|
||||
QList<QStringList> processes;
|
||||
bool _running;
|
||||
int _loop;
|
||||
QTimer* _timer;
|
||||
qint64 _processDelay;
|
||||
QElapsedTimer elapsedTimer;
|
||||
|
||||
int _processIndex;
|
||||
|
||||
void connectEvents();
|
||||
|
||||
void makeClick(QWidget* control,float x = -1.0f);
|
||||
//bool _waitForEvent;
|
||||
|
||||
PLAY_EVENT _waitPlayEvent; // 대기중 플레이 이벤트
|
||||
|
||||
float parseRandFloat(QString range);
|
||||
int parseRandInt(QString range);
|
||||
|
||||
signals:
|
||||
void timer(qint64 timer);
|
||||
void loopChange(int loop);
|
||||
void statusChange(QString message);
|
||||
void log(QString log);
|
||||
void error(QString error);
|
||||
|
||||
public slots:
|
||||
void onRun();
|
||||
void onStop();
|
||||
void onSyncTime();
|
||||
void onProcessNext();
|
||||
|
||||
void onLoadingListEnd(bool bLoading);
|
||||
|
||||
void onPlayEvent(PLAY_EVENT event,RMVideoItem* item);
|
||||
void onFileTimeout();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // RM_TEST_PROCESS_H
|
||||
8
project/fm_viewer/tester/rm_tester.cpp
Normal file
8
project/fm_viewer/tester/rm_tester.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "rm_tester.h"
|
||||
#if (RM_LOG_LEVEL > RM_LOG_LEVEL_NONE)
|
||||
|
||||
QElapsedTimer RMTester::timer0 = QElapsedTimer();
|
||||
QElapsedTimer RMTester::timer1 = QElapsedTimer();
|
||||
QElapsedTimer RMTester::timer2 = QElapsedTimer();
|
||||
|
||||
#endif
|
||||
96
project/fm_viewer/tester/rm_tester.h
Normal file
96
project/fm_viewer/tester/rm_tester.h
Normal file
@@ -0,0 +1,96 @@
|
||||
#ifndef RM_TESTER_H
|
||||
#define RM_TESTER_H
|
||||
|
||||
// 로그 처리 레벨
|
||||
#define RM_LOG_LEVEL_NONE 0
|
||||
#define RM_LOG_LEVEL_TEST 1
|
||||
#define RM_LOG_LEVEL_ERROR 2
|
||||
#define RM_LOG_LEVEL_DEBUG 3
|
||||
#define RM_LOG_LEVEL_INFO 4
|
||||
|
||||
// 문제가 32 로 probe 되지 않는 파일
|
||||
// E:/EVENT/2/NEF_190622-172014-000001_2.avi
|
||||
// E:/EVENT/2/NEF_190622-181637-000001_2.avi
|
||||
// E:/EVENT/2/NEF_190622-192232-000001_2.avi
|
||||
// E:/EVENT/2/NEF_190624-103821-000009_2.avi
|
||||
// E:/EVENT/2/NEF_190624-105244-000032_2.avi
|
||||
|
||||
// 로그 레벨 설정
|
||||
#define RM_LOG_LEVEL RM_LOG_LEVEL_TEST
|
||||
|
||||
// 레벨에 따른 감추기
|
||||
#if defined(SUPPRESS_ALL_TESTER) || (RM_LOG_LEVEL < RM_LOG_LEVEL_INFO)
|
||||
#define LOG_INFO /##/
|
||||
#else
|
||||
#define LOG_INFO qInfo()
|
||||
#endif
|
||||
|
||||
#if defined(SUPPRESS_ALL_TESTER) || (RM_LOG_LEVEL < RM_LOG_LEVEL_DEBUG)
|
||||
#define LOG_DEBUG /##/
|
||||
#else
|
||||
#define LOG_DEBUG qInfo()
|
||||
#endif
|
||||
|
||||
#if defined(SUPPRESS_ALL_TESTER) || (RM_LOG_LEVEL < RM_LOG_LEVEL_ERROR)
|
||||
#define LOG_ERROR /##/
|
||||
#else
|
||||
#define LOG_ERROR qInfo()
|
||||
#endif
|
||||
|
||||
#if defined(SUPPRESS_ALL_TESTER) || (RM_LOG_LEVEL != RM_LOG_LEVEL_TEST)
|
||||
#define LOG_TEST /##/
|
||||
#else
|
||||
#define LOG_TEST qInfo() << __FUNCTION__
|
||||
#endif
|
||||
|
||||
// 커스텀 로그 설정
|
||||
// 비디오 프로파일 로그
|
||||
#define PROFILE_VIDEO_FILE_LOADING 0
|
||||
#define PROFILE_VIDEO_FILE_LOADING_AUTOPLAY 0
|
||||
#define PROFILE_TESTER_TIMER 1
|
||||
#if (RM_LOG_LEVEL > RM_LOG_LEVEL_NONE)
|
||||
|
||||
#if !defined(SUPPRESS_ALL_TESTER) && (PROFILE_TESTER_TIMER)
|
||||
#define TIMER_START RMTester::timer0.start();
|
||||
#define TIMER_NOW qInfo() << __FUNCTION__ << RMTester::timer0.elapsed() << "ms"
|
||||
#endif
|
||||
|
||||
// 비디오 개별 파일 로딩 테스트
|
||||
#if !defined(SUPPRESS_ALL_TESTER) && (PROFILE_VIDEO_FILE_LOADING)
|
||||
#define LOG_VLOAD qInfo()
|
||||
#define LOG_VLOAD_TS RMTester::timer0.start()
|
||||
#define LOG_VLOAD_T RMTester::timer0.elapsed() << "ms"
|
||||
#define LOG_VLOAD_TS2 RMTester::timer1.start()
|
||||
#define LOG_VLOAD_T2 RMTester::timer1.elapsed() << "ms"
|
||||
#else
|
||||
#define LOG_VLOAD /##/
|
||||
#define LOG_VLOAD_TS /##/
|
||||
#define LOG_VLOAD_T /##/
|
||||
#define LOG_VLOAD_TS2 /##/
|
||||
#define LOG_VLOAD_T2 /##/
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
// 클래스
|
||||
#include <QElapsedTimer>
|
||||
#include <QObject>
|
||||
|
||||
class RMTester : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// 최대 3개의 level timer 사용
|
||||
static QElapsedTimer timer0;
|
||||
static QElapsedTimer timer1;
|
||||
static QElapsedTimer timer2;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // (RM_LOG_LEVEL > RM_LOG_LEVEL_NONE)
|
||||
|
||||
|
||||
#endif // RM_TESTER_H
|
||||
32
project/fm_viewer/tester/rm_testing.cpp
Normal file
32
project/fm_viewer/tester/rm_testing.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "rm_testing.h"
|
||||
#if (RM_TESTING)
|
||||
#include <QMouseEvent>
|
||||
#include <QDebug>
|
||||
#include <QCursor>
|
||||
|
||||
RMTesting::RMTesting(QObject *parent) : QObject(parent)
|
||||
{
|
||||
//qInfo() << __FUNCTION__;
|
||||
}
|
||||
bool RMTesting::eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
if(event->type() == QEvent::MouseButtonPress)
|
||||
{
|
||||
if(QCursor::pos() == mouse && mouseFilterTimer.elapsed() < 10)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
mouseFilterTimer.start();
|
||||
mouse = QCursor::pos();
|
||||
|
||||
int x = QCursor::pos().x();
|
||||
int y = QCursor::pos().y();
|
||||
qInfo() << "MP -> (" + QString::number(x) + "," + QString::number(y) + ")" << object;
|
||||
return false; // make it unhandled and sent to other filters.
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
34
project/fm_viewer/tester/rm_testing.h
Normal file
34
project/fm_viewer/tester/rm_testing.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef RM_TESTING_H
|
||||
#define RM_TESTING_H
|
||||
|
||||
#if (RM_TESTING)
|
||||
#include <QObject>
|
||||
#include <QPoint>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
class RMTesting : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RMTesting(QObject *parent = nullptr);
|
||||
static RMTesting* instance()
|
||||
{
|
||||
static RMTesting * _instance = 0;
|
||||
if ( _instance == 0 ) {
|
||||
_instance = new RMTesting();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
private:
|
||||
QElapsedTimer mouseFilterTimer;
|
||||
QPoint mouse;
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject* object, QEvent* event);
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
};
|
||||
|
||||
#endif // RM_TESTING
|
||||
#endif // RM_TESTING_H
|
||||
383
project/fm_viewer/tester/rm_tune360_dialog.cpp
Normal file
383
project/fm_viewer/tester/rm_tune360_dialog.cpp
Normal file
@@ -0,0 +1,383 @@
|
||||
#include "rm_tune360_dialog.h"
|
||||
|
||||
#if (TUNE_360)
|
||||
#include "../fav/OpenGLVideo.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <QDebug>
|
||||
#include <QMainWindow>
|
||||
#include <QDesktopServices>
|
||||
#include <QUrl>
|
||||
#include <QFileDialog>
|
||||
#include <QStyle>
|
||||
#include <QMessageBox>
|
||||
#include <QScrollBar>
|
||||
#include "../rm_app.h"
|
||||
#include "../rm_settings.h"
|
||||
#include "../core/rm_player.h"
|
||||
//#include "../core/rm_player.h"
|
||||
//#include "../core/rm_play_process.h"
|
||||
|
||||
#define TUNE_360_RANGE 1000
|
||||
#define TUNE_360_RATIO_Y 20
|
||||
#define TUNE_360_RATIO_R 4
|
||||
#define TUNE_360_RATIO_X 5
|
||||
#define TUNE_360_RATIO_AR 20
|
||||
#define TUNE_360_RATIO_RB 2
|
||||
|
||||
RMTune360Dialog::RMTune360Dialog(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
QString version;
|
||||
version.sprintf("model:%s %d.%d.%d.%d",WINDOW_TITLE,RM_MODEL_VERSION_0,RM_MODEL_VERSION_1,RM_MODEL_VERSION_1,RM_MODEL_SVN_VERSION);
|
||||
this->setWindowModality(Qt::NonModal);
|
||||
this->setWindowTitle("360 TUNE (" + version + ")");
|
||||
this->setWindowFlags(Qt::Window | Qt::Tool | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
|
||||
this->setWindowModality(Qt::NonModal);
|
||||
setMinimumSize(300,500);
|
||||
|
||||
_layout = new QVBoxLayout(this);
|
||||
_layout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
_layout->setMargin(0);
|
||||
_layout->setSpacing(0);
|
||||
|
||||
|
||||
_swap = false;
|
||||
|
||||
createToolbar();
|
||||
createSliderPanel();
|
||||
createParamConsole();
|
||||
}
|
||||
RMTune360Dialog* RMTune360Dialog::instance(QWidget* parent)
|
||||
{
|
||||
static RMTune360Dialog * _instance = NULL;
|
||||
if ( _instance == NULL )
|
||||
{
|
||||
_instance = new RMTune360Dialog(parent);
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
void RMTune360Dialog::showEvent(QShowEvent * event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
QRect r = RMApp::instance()->pMainWindow->geometry();
|
||||
r.moveLeft(1420);
|
||||
r.moveTop(190);
|
||||
setGeometry(r.right(),r.top(),300,500);
|
||||
|
||||
loadPreset();
|
||||
}
|
||||
|
||||
void RMTune360Dialog::createToolbar()
|
||||
{
|
||||
_toolbar = new QWidget(this);
|
||||
_toolbar->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
|
||||
_toolbar->setFixedHeight(36);
|
||||
_layout->addWidget(_toolbar);
|
||||
|
||||
_toolbar->setStyleSheet("background-color: #818181;");
|
||||
//_toolbar->setObjectName("test_widget");
|
||||
|
||||
QHBoxLayout* toolLayout = new QHBoxLayout(_toolbar);
|
||||
toolLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
toolLayout->setSpacing(6);
|
||||
toolLayout->setMargin(2);
|
||||
|
||||
_resetButton = _button(_toolbar,toolLayout,"RESET");
|
||||
|
||||
_button(_toolbar,toolLayout,"VR");
|
||||
_button(_toolbar,toolLayout,"WIDE");
|
||||
|
||||
_button(_toolbar,toolLayout,"GET");
|
||||
|
||||
_button(_toolbar,toolLayout,"SET");
|
||||
|
||||
_button(_toolbar,toolLayout,"SWAP");
|
||||
}
|
||||
void RMTune360Dialog::createSliderPanel()
|
||||
{
|
||||
|
||||
QWidget* info = new QWidget(this);
|
||||
info->setStyleSheet("background-color: #616161;");
|
||||
//info->setObjectName("test_widget");
|
||||
info->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);
|
||||
//info->setFixedHeight(48);
|
||||
_layout->addWidget(info);
|
||||
|
||||
//info->setStyleSheet("background-color: #000000;");
|
||||
|
||||
|
||||
QVBoxLayout* infoLayout = new QVBoxLayout(info);
|
||||
infoLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||
infoLayout->setSpacing(2);
|
||||
infoLayout->setMargin(2);
|
||||
|
||||
_labels = new QList<QLabel*>();
|
||||
_sliders = new QList<QSlider*>();
|
||||
_resetButtons = new QList<QPushButton*>();
|
||||
|
||||
#if (TUNE4)
|
||||
_slider(info,infoLayout,"LX[0][0]",TUNE_360_RATIO_X);
|
||||
_slider(info,infoLayout,"LY[1][0]",TUNE_360_RATIO_Y);
|
||||
_slider(info,infoLayout,"LRX[2][0]",TUNE_360_RATIO_R);
|
||||
_slider(info,infoLayout,"LRY[3][0]",TUNE_360_RATIO_R);
|
||||
|
||||
_slider(info,infoLayout,"RX[0][1]",TUNE_360_RATIO_X);
|
||||
_slider(info,infoLayout,"RY[1][1]",TUNE_360_RATIO_Y);
|
||||
_slider(info,infoLayout,"RRX[2][1]",TUNE_360_RATIO_R);
|
||||
_slider(info,infoLayout,"RRY[3][1]",TUNE_360_RATIO_R);
|
||||
|
||||
_slider(info,infoLayout,"RX2[0][2]",TUNE_360_RATIO_X);
|
||||
_slider(info,infoLayout,"RY2[1][2]",TUNE_360_RATIO_X);
|
||||
_slider(info,infoLayout,"RRX2[2][2]",TUNE_360_RATIO_R);
|
||||
_slider(info,infoLayout,"RRY2[3][2]",TUNE_360_RATIO_RB);
|
||||
#else
|
||||
_slider(info,infoLayout,"LX",TUNE_360_RATIO_X);
|
||||
_slider(info,infoLayout,"LY",TUNE_360_RATIO_Y);
|
||||
_slider(info,infoLayout,"LR",TUNE_360_RATIO_R);
|
||||
|
||||
_slider(info,infoLayout,"RX",TUNE_360_RATIO_X);
|
||||
_slider(info,infoLayout,"RY",TUNE_360_RATIO_Y);
|
||||
_slider(info,infoLayout,"RR",TUNE_360_RATIO_R);
|
||||
|
||||
_slider(info,infoLayout,"AR",TUNE_360_RATIO_AR);
|
||||
_slider(info,infoLayout,"ARY",TUNE_360_RATIO_AR);
|
||||
#endif
|
||||
|
||||
}
|
||||
void RMTune360Dialog::createParamConsole()
|
||||
{
|
||||
_paramTextEdit = new QPlainTextEdit(this);
|
||||
//_paramTextEdit->setReadOnly(true);
|
||||
_paramTextEdit->setStyleSheet("font-family: Fixedsys;color : #00FF00;background-color: #111111;border:1px;border-style:solid;border-color:#313131;");
|
||||
_paramTextEdit->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
|
||||
_layout->addWidget(_paramTextEdit);
|
||||
QString scrollStyle = "QScrollBar:vertical\
|
||||
{\
|
||||
border-width: 0px;\
|
||||
border-style: solid;\
|
||||
background: #3B3B3B;\
|
||||
width: 10px;\
|
||||
margin: 21px 0 21px 0;\
|
||||
}\
|
||||
QScrollBar::handle:vertical:disabled{background: #3B3B3B;}\
|
||||
QScrollBar::handle:vertical\
|
||||
{\
|
||||
border-width: 0px;\
|
||||
background: #6A74FF;\
|
||||
min-height: 25px;\
|
||||
}\
|
||||
QScrollBar::add-line:vertical\
|
||||
{\
|
||||
border: none;\
|
||||
background: none;\
|
||||
height: 20px;\
|
||||
width: 15px;\
|
||||
subcontrol-position: bottom;\
|
||||
subcontrol-origin: margin;\
|
||||
}\
|
||||
QScrollBar::sub-line:vertical\
|
||||
{\
|
||||
border: none;\
|
||||
background: none;\
|
||||
height: 20px;\
|
||||
width: 15px;\
|
||||
subcontrol-position: top;\
|
||||
subcontrol-origin: margin;\
|
||||
}\
|
||||
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical\
|
||||
{\
|
||||
background: none;\
|
||||
}\
|
||||
QScrollBar::up-arrow:vertical\
|
||||
{\
|
||||
border: none;\
|
||||
background: #5A5A5A;\
|
||||
}\
|
||||
QScrollBar::down-arrow:vertical\
|
||||
{\
|
||||
border: none;\
|
||||
background: #5A5A5A;\
|
||||
}";
|
||||
_paramTextEdit->verticalScrollBar()->setStyleSheet(scrollStyle);
|
||||
}
|
||||
QSlider* RMTune360Dialog::_slider(QWidget* parent,QLayout* layout, QString title, float ratio)
|
||||
{
|
||||
QWidget* view = new QWidget(parent);
|
||||
QHBoxLayout* viewLayout = new QHBoxLayout(view);
|
||||
viewLayout->setAlignment(Qt::AlignCenter);
|
||||
|
||||
layout->addWidget(view);
|
||||
|
||||
QLabel* tl = new QLabel(view);
|
||||
tl->setText(title);
|
||||
tl->setStyleSheet("font-family: Fixedsys;color : #F0F0F0;");
|
||||
viewLayout->addWidget(tl);
|
||||
|
||||
QSlider* slider = new QSlider(view);
|
||||
slider->setOrientation(Qt::Horizontal);
|
||||
slider->setMinimum(-TUNE_360_RANGE);
|
||||
slider->setMaximum(TUNE_360_RANGE);
|
||||
slider->setValue(0);
|
||||
|
||||
connect(slider,SIGNAL(valueChanged(int)),SLOT(onSliderChange(int)));
|
||||
|
||||
_sliders->append(slider);
|
||||
|
||||
viewLayout->addWidget(slider);
|
||||
QLabel* label = new QLabel(view);
|
||||
label->setText("0.000");
|
||||
label->setStyleSheet("font-family: Fixedsys;color : #F0F0F0;");
|
||||
_labels->append(label);
|
||||
|
||||
viewLayout->addWidget(label);
|
||||
|
||||
QPushButton* reset = _button(view,viewLayout,"RS");
|
||||
_resetButtons->append(reset);
|
||||
|
||||
_ratios.append(ratio);
|
||||
return slider;
|
||||
}
|
||||
QPushButton* RMTune360Dialog::_button(QWidget* parent,QLayout* layout,QString title)
|
||||
{
|
||||
QPushButton* btn = new QPushButton(parent);
|
||||
btn->setText(title);
|
||||
//btn->setStyleSheet("font-family: Arial;font-size: 9px;");
|
||||
btn->setStyleSheet("QPushButton{font-family: Fixedsys;color : white;}"
|
||||
"QPushButton[enabled=\"false\"]{color : #AAAAAA;}");
|
||||
btn->setFixedWidth(title.length() * 10);
|
||||
layout->addWidget(btn);
|
||||
connect(btn,SIGNAL(clicked()),SLOT(onButton()));
|
||||
return btn;
|
||||
}
|
||||
|
||||
void RMTune360Dialog::onSliderChange(int value)
|
||||
{
|
||||
QSlider* slider = qobject_cast<QSlider*>(sender());
|
||||
int index = _sliders->indexOf(slider);
|
||||
QLabel* label = _labels->at(index);
|
||||
QString str;
|
||||
double v = ((double)value)/(TUNE_360_RANGE * _ratios.at(index));
|
||||
label->setText(str.sprintf("%.3f",v));
|
||||
|
||||
refresh();
|
||||
}
|
||||
void* RMTune360Dialog::gl()
|
||||
{
|
||||
return RMPlayer::instance()->playerF()->videoOutputs().first()->opengl();
|
||||
}
|
||||
void RMTune360Dialog::loadPreset()
|
||||
{
|
||||
FAV::OpenGLVideo* opengl = (FAV::OpenGLVideo*)gl();
|
||||
QMatrix4x4& m = opengl->tune360();
|
||||
|
||||
float ac[16];// = m.constData();
|
||||
m.copyDataTo(ac);
|
||||
|
||||
for(int i=0;i<_sliders->count();i++)
|
||||
{
|
||||
float fv = ac[i] * (TUNE_360_RANGE * _ratios.at(i));
|
||||
//qInfo() << i << ":" << fv;
|
||||
_sliders->at(i)->blockSignals(true);
|
||||
_sliders->at(i)->setValue(fv);
|
||||
_sliders->at(i)->blockSignals(false);
|
||||
|
||||
QLabel* label = _labels->at(i);
|
||||
QString str;
|
||||
//double v = ((double)value)/(TUNE_360_RANGE * _ratios.at(index));
|
||||
label->setText(str.sprintf("%.3f",ac[i]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RMTune360Dialog::refresh()
|
||||
{
|
||||
float ac[16] = {0,};
|
||||
for(int i=0;i<_sliders->count();i++)
|
||||
{
|
||||
ac[i] = ((double)_sliders->at(i)->value())/(TUNE_360_RANGE * _ratios.at(i));
|
||||
//qInfo() << "I:" << i << ":"<< ac[i];
|
||||
}
|
||||
//ac[8] = _swap ? 1.0 : 0.0; // 3*2+2 = 8
|
||||
QMatrix4x4 m(ac);
|
||||
|
||||
FAV::OpenGLVideo* opengl = (FAV::OpenGLVideo*)gl();
|
||||
opengl->setTune360(m);
|
||||
|
||||
RMPlayer::instance()->playWidgetF()->update();
|
||||
}
|
||||
void RMTune360Dialog::onButton()
|
||||
{
|
||||
QPushButton* btn = qobject_cast<QPushButton*>(sender());
|
||||
QString cmd = btn->text().toUpper();
|
||||
FAV::OpenGLVideo* opengl = (FAV::OpenGLVideo*)gl();
|
||||
|
||||
if(cmd == "RESET")
|
||||
{
|
||||
for(int i=0;i<_sliders->count();i++)
|
||||
{
|
||||
_sliders->at(i)->setValue(0);
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
else if(cmd == "VR")
|
||||
{
|
||||
opengl->setMode(1);
|
||||
RMPlayer::instance()->playWidgetF()->update();
|
||||
}
|
||||
else if(cmd == "WIDE")
|
||||
{
|
||||
opengl->setMode(0);
|
||||
RMPlayer::instance()->playWidgetF()->update();
|
||||
}
|
||||
else if (cmd == "GET")
|
||||
{
|
||||
QString a = "[";
|
||||
for(int i=0;i<_sliders->count();i++)
|
||||
{
|
||||
if(i>0)
|
||||
{
|
||||
a += ",";
|
||||
}
|
||||
|
||||
QString vf;
|
||||
float f = ((double)_sliders->at(i)->value())/(TUNE_360_RANGE * _ratios.at(i));
|
||||
vf.sprintf("%f",f);
|
||||
a += vf;
|
||||
}
|
||||
a += "];";
|
||||
_paramTextEdit->clear();
|
||||
_paramTextEdit->appendPlainText(a);
|
||||
}
|
||||
else if(cmd == "SET")
|
||||
{
|
||||
QString pt = _paramTextEdit->toPlainText();
|
||||
pt.replace("[","").replace("]","").replace(";","");
|
||||
QStringList sl = pt.split(",");
|
||||
if(sl.count() == _sliders->count())
|
||||
{
|
||||
for(int i=0;i<sl.count();i++)
|
||||
{
|
||||
QString sv = sl.at(i);
|
||||
float fv = sv.toFloat() * (TUNE_360_RANGE * _ratios.at(i));
|
||||
//qInfo() << sl << sv << fv;
|
||||
_sliders->at(i)->setValue(fv);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if(cmd == "SWAP")
|
||||
{
|
||||
_swap = !_swap;
|
||||
qInfo() << "swap:" << _swap;
|
||||
refresh();
|
||||
}
|
||||
else if (cmd == "RS")
|
||||
{
|
||||
int index = _resetButtons->indexOf(btn);
|
||||
_sliders->at(index)->setValue(0);
|
||||
refresh();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // #if (TUNE_360)
|
||||
56
project/fm_viewer/tester/rm_tune360_dialog.h
Normal file
56
project/fm_viewer/tester/rm_tune360_dialog.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef RM_TUNE360_DIALOG_H
|
||||
#define RM_TUNE360_DIALOG_H
|
||||
|
||||
#if (TUNE_360)
|
||||
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QLineEdit>
|
||||
#include <QSlider>
|
||||
|
||||
|
||||
class RMTune360Dialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static RMTune360Dialog* instance(QWidget* parent = nullptr);
|
||||
private:
|
||||
QVBoxLayout* _layout;
|
||||
|
||||
QWidget* _toolbar;
|
||||
QPushButton* _resetButton;
|
||||
|
||||
|
||||
QLineEdit* _filterEdit;
|
||||
|
||||
QList<QLabel*>* _labels;
|
||||
QList<QSlider*>* _sliders;
|
||||
QList<QPushButton*>* _resetButtons;
|
||||
QList<float> _ratios;
|
||||
QPlainTextEdit* _paramTextEdit;
|
||||
bool _swap;
|
||||
|
||||
explicit RMTune360Dialog(QWidget *parent = nullptr);
|
||||
void showEvent(QShowEvent * event);
|
||||
|
||||
void createToolbar();
|
||||
void createSliderPanel();
|
||||
void createParamConsole();
|
||||
|
||||
QPushButton* _button(QWidget* parent,QLayout* layout,QString title);
|
||||
QSlider* _slider(QWidget* parent,QLayout* layout, QString title, float ratio);
|
||||
void refresh();
|
||||
void loadPreset();
|
||||
void* gl();
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void onSliderChange(int value);
|
||||
void onButton();
|
||||
};
|
||||
|
||||
#endif // #if (TUNE_360)
|
||||
#endif // RM_TUNE360_DIALOG_H
|
||||
Reference in New Issue
Block a user