Files
fmviewer3/project/fm_viewer/ui/window_main.cpp
2026-02-21 17:11:31 +09:00

2488 lines
81 KiB
C++

#include "window_main.h"
#include "../fm_dimensions.h"
#include <QThreadPool>
#include <QFile>
#include <QDir>
#include <QFileDialog>
#include <QTimer>
#include <QAction>
#include <QMessageBox>
#include <QDesktopWidget>
#if (RM_MODEL == RM_MODEL_TYPE_TB4000)
#include <QPrinter>
#include <QPrintDialog>
#endif // RM_MODEL_TYPE_TB4000
#if (USE_VERSION_CHECK)
#include "module/fm_version_checker.h"
#endif
#if (FM_VIDEO_EDIT)
#include "../data/fm_video_edit.h"
#endif // FM_VIDEO_EDIT
#if (USE_DEVICE_SETTINGS)
#include "../cfg/window_settings.h"
#include "../cfg/rm_settings_cfg.h"
#endif // USE_DEVICE_SETTINGS
//#include "title_widget.h"
#include "fm_frame_title.h"
#include "fm_button.h"
#include "rm_application.h"
#include "rm_popup_info.h"
#include "rm_popup_select_disk.h"
#include "rm_popup_message.h"
#include "rm_popup_capture.h"
#include "rm_frame_left.h"
#include "rm_frame_right.h"
#include "rm_frame_list.h"
#include "rm_widget_video_list.h"
#include "../data/rm_video_list.h"
#include "rm_dialog_progress.h"
#include "../core/rm_player.h"
#include "../core/rm_play_process.h"
#if (FILE_LOAD_MESSAGE) // 파일열기 메시지 전송
#include <Windows.h>
#endif // #if (FILE_LOAD_MESSAGE) // 파일열기 메시지 전
#if (RM_MODEL == RM_MODEL_TYPE_TB4000)
#include <QInputDialog>
#include <QMenu>
#include <libcrypt_tb.h>
//#include "rm_popup_pw.h"
#include "../core/rm_math.h"
#endif
#if (SUPPORT_FORMAT_FREE)
#include "../module/bmff.h"
#endif // #if (SUPPORT_FORMAT_FREE)
#if (USE_WEBVIEW2)
#include "../ui/rm_webview2.h"
#else // WEBVIEW2
#include "../ui/rm_dialog_map.h"
#endif // WEBVIEW2
#include "../core/rm_excel_report.h"
#include "../ui/rm_frame_play.h"
#include "../core/fm_strings.h"
#include "../ui/rm_widget_drag.h"
#include <QDesktopServices>
#if (DUAL_VIEWER)
#include "../ui/rm_frame_top.h"
#endif
#include "../core/fm_video_split.h"
#if (MULTI_MODEL_VIEWER)
#include "../ui/rm_popup_select_model.h"
#endif
#include "../ui/rm_toolbar.h"
#include "../ui/rm_frame_video_sub.h"
#include "../ui/rm_frame_list.h"
#include "../ui/rm_dialog_bbviewer.h"
#include "../ui/rm_frame_graph.h"
#include "../ui/rm_speed_label.h"
#include "../core/rm_language.h"
#include "../core/rm_usb.h"
#if (USE_RM_KEYBOARD_EVENT)
#include "core/rm_key_event.h"
#endif
#include "ui/rm_frame_video_main.h"
#if (DESIGN_LAYOUT_MODE)
#include <QGraphicsOpacityEffect>
#endif
#if (FE_LOG_VERSION)
#include "../tester/fe_log.h"
#endif
#if (USE_DATE_TIME_LIST)
#include "fm_calendar.h"
#include "fm_daytime.h"
#endif // USE_DATE_TIME_LIST
#if (PLAYER_ONLY_LIBRARY_MODE)
#include "../rm_settings.h"
// 외부에서 창을 생성하는 팩토리 함수
extern "C" QMainWindow* createTB5000Window(QWidget* parent,
RMSettings* settings,
//RMPlayer** player360,
RMVideoItem* playItem,
RMVideoFileList* fileList,
onTB5000 callback)
{
RMSettings::updateInstance(settings);
RMVideoFileList::updateInstance(fileList);
//RMPlayer::instance()->clear();
RMPlayer::instance()->create();
//*player360 = RMPlayer::instance();
// 디버그 모드와 릴리즈모드를 동시에 사용하면 문제가 됨
//QApplication* app = qobject_cast<QApplication*>(QCoreApplication::instance());
WindowMain* wt5 = new WindowMain(parent);
// 감추기 모드로 시작
//wt5->setAttribute(Qt::WA_DontShowOnScreen,true);
wt5->_onTB5000 = callback;
RMApp::instance()->pMainWindow = wt5;
QThread::msleep(200);
if(playItem != NULL) {
RMPlayProcess::instance()->onVideoLoadingStart(playItem);
//RMPlayer::instance()->onLoad(playItem);
}
return wt5; //
}
extern "C" void playTB5000(RMVideoItem* playItem)
{
if(playItem != NULL) {
//qInfo() << playItem->anyFilePath() << __FUNCTION__;
//RMPlayer::instance()->stop();
//RMPlayer::instance()->onLoad(playItem);
RMPlayProcess::instance()->onVideoLoadingStart(playItem);
}
}
static bool bTB5000Showed = false;
void WindowMain::showEvent(QShowEvent *ev){
QMainWindow::showEvent(ev);
#if !(LIBRARY_DEVP_MODE)
if(!bTB5000Showed) {
//setHidden(true); // 전체화면 전환 후 표시
bTB5000Showed = true;
QTimer::singleShot(100, this, SLOT(onFullScreen()));
}
#endif // LIBRARY_DEVP_MODE
}
#endif // PLAYER_ONLY_LIBRARY_MODE
#if (NO_LOGO)
#if (RM_MODEL == RM_MODEL_TYPE_FC_DR232W)
WindowMain::WindowMain(QWidget *parent) : RMWindowBase(parent,"","title_logo_nx.png",false)
#else
WindowMain::WindowMain(QWidget *parent) : RMWindowBase(parent,"","",false)
#endif
#else // NO_LOGO
#if (RM_MODEL == RM_MODEL_TYPE_AN6000)
WindowMain::WindowMain(QWidget *parent) : RMWindowBase(parent,"","title_logo_yawata.png",false)
#else // AN6000
WindowMain::WindowMain(QWidget *parent) : RMWindowBase(parent,"","title_logo.png",false)
#endif // AN6000
#endif // NO_LOGO
{
#if (USE_VERSION_CHECK)
_versionDialog = NULL;
#endif //
_bFirstWindowLoad = true;
#if !(SINGLE_CH_VIEWER)
bSubFullScreen = false;
#endif // #if !(SINGLE_CH_VIEWER)
#if (USE_MAXIMIZE)
mFullScreenMode = 0;
#endif
#if (DESIGN_LAYOUT_MODE)
// GUIDE 와 비교해서 작업 모드
setStyleSheet("WindowMain { border-image: url(:/image/guide.png) 0 0 0 0 stretch stretch; }");
alpha = new QGraphicsOpacityEffect(this);
alpha->setOpacity(1.0);
_centralWidget->setGraphicsEffect(alpha);
_centralWidget->setAutoFillBackground(true);
#endif
// 가장 먼저 처리
RMApp::instance()->pMainWindow = this;
#if !(REMOVE_ALL_SHORT_CUTS)
RMApp::instance()->installGlobalShortcuts();
#endif
setWindowTitle(WINDOW_TITLE);
#if (PLAYER_ONLY_LIBRARY_MODE && !LIBRARY_DEVP_MODE)
setFixedSize(1,1);
#else // setFixedSize
setFixedSize(MAIN_WINDOW_WIDTH,MAIN_WINDOW_HEIGHT);
#endif // setFixedSize
//qInfo() << "MAIN WINDOW SIZE:" << MAIN_WINDOW_WIDTH << MAIN_WINDOW_HEIGHT << __FUNCTION__;
//setWindowFlags(Qt::Drawer);
//setWindowFlags(windowFlags() &(~Qt::WindowMaximizeButtonHint));
// Title (from super)
#if !(PLAYER_ONLY_LIBRARY_MODE)
connect(_title->_closeButton,SIGNAL(clicked()),this,SLOT(onCloseApplication()));
connect(_title->_minimizeButton,SIGNAL(clicked()),this,SLOT(onMinimize()));
#if (TOGGLE_PLAYER || FIXED_MAP_FRAME)
connect(_drag,SIGNAL(onWindowMove()),this,SLOT(onWindowMove()));
#endif
#if (MODEL_STANDARD)
#if (USE_DEVICE_SETTINGS)
#if (FE_LOG_VERSION)
connect(_title->_settingsButton,SIGNAL(clicked()),SLOT(onLogDialog()));
#else
connect(_title->_settingsButton,SIGNAL(clicked()),this,SLOT(onShowSettings()));
#endif
#endif // USE_DEVICE_SETTINGS
#if !(RM_MODEL == RM_MODEL_TYPE_TB4000)
connect(_title->_infoButton,SIGNAL(clicked()),this,SLOT(onShowInfo()));
#if !(TOGGLE_PLAYER || DO_NOT_USE_MAP)
connect(_title->_mapButton,SIGNAL(clicked()),this,SLOT(onMap()));
#endif
#endif // #if !(RM_MODEL == RM_MODEL_TYPE_TB4000)
#if (RM_MODEL == RM_MODEL_TYPE_TB4000)
connect(_title->_settingsButton,SIGNAL(clicked()),this,SLOT(onPassword()));
#endif
#if (USE_GOOGLE_MAP_AND_OSM)
connect(_title->_mapOSMButton,SIGNAL(clicked()),this,SLOT(onMap()));
#endif // USE_GOOGLE_MAP_AND_OSM
#if !(RM_MODEL == RM_MODEL_TYPE_TB4000)
#if !(REMOVE_ALL_SHORT_CUTS)
#if (USE_DEVICE_SETTINGS)
connect(_title->_settingsShortcut,SIGNAL(activated()),this,SLOT(onShowSettings()));
#endif
connect(_title->_infoShortcut,SIGNAL(activated()),this,SLOT(onShowInfo()));
#endif // REMOVE_ALL_SHORT_CUTS
#endif // #if !(RM_MODEL == RM_MODEL_TYPE_TB4000)
#endif
#endif // #endif // PLAYER_ONLY_LIBRARY_MODE
#if !(REMOVE_ALL_SHORT_CUTS)
escFullScreenShortcut = new QShortcut(QKeySequence(Qt::Key_Escape), this);
escFullScreenShortcut->setContext(Qt::ApplicationShortcut);
connect(escFullScreenShortcut,SIGNAL(activated()),this,SLOT(onFullScreen()));
escFullScreenShortcut->setEnabled(false);
toggleFullScreenShortcut = new QShortcut(QKeySequence(Qt::Key_Return), this);
toggleFullScreenShortcut->setContext(Qt::ApplicationShortcut);
connect(toggleFullScreenShortcut,SIGNAL(activated()),this,SLOT(onFullScreen()));
toggleFullScreenShortcut2 = new QShortcut(QKeySequence(Qt::Key_Enter), this);
toggleFullScreenShortcut2->setContext(Qt::ApplicationShortcut);
connect(toggleFullScreenShortcut2,SIGNAL(activated()),this,SLOT(onFullScreen()));
// toggleFullScreenShortcut3 = new QShortcut(QKeySequence(Qt::Key_Alt + Qt::Key_Enter), this);
// toggleFullScreenShortcut3->setContext(Qt::ApplicationShortcut);
// connect(toggleFullScreenShortcut3,SIGNAL(activated()),this,SLOT(onFullScreen()));
#endif
QWidget* parentWidget = _mainWidget;
#if (DUAL_VIEWER)
// Dual 모드에서는 상,하단으로 구분되어 하단 영역이 _mainLayout 이 됨
_dualMainLayout = new QVBoxLayout(_mainWidget);
_dualMainLayout->setSpacing(0);
_dualMainLayout->setContentsMargins(MAIN_DUAL_MARGIN);
_dualMainLayout->setAlignment(Qt::AlignTop);
_frameTop = new RMFrameTop(_mainWidget);
_dualMainLayout->addWidget(_frameTop);
_bottomMainWidget = new QWidget(_mainWidget);
//_bottomMainWidget->setObjectName("test_widget");
_dualMainLayout->addWidget(_bottomMainWidget);
_mainLayout = new QHBoxLayout(_bottomMainWidget);
_mainLayout->setAlignment(Qt::AlignTop);
_mainLayout->setSpacing(MAIN_LAYOUT_SPACING);
_mainLayout->setContentsMargins(MAIN_WIDGET_MARGIN);
parentWidget = _bottomMainWidget;
#else
_mainLayout = new QHBoxLayout(parentWidget);
_mainLayout->setMargin(MAIN_LAYOUT_SPACE);
_mainLayout->setSpacing(MAIN_LAYOUT_SPACE);
// ZERO_LAYOUT(_mainLayout);
// _mainLayout->setSpacing(MAIN_LAYOUT_SPACING);
// _mainLayout->setContentsMargins(MAIN_WIDGET_MARGIN);
#endif // DUAL_VIEWER
_frameLeft = new RMFrameLeft(parentWidget);
_mainLayout->addWidget(_frameLeft);
#if !(PLAYER_ONLY_LIBRARY_MODE)
_frameRight = new RMFrameRight(parentWidget);
_mainLayout->addWidget(_frameRight);
connect(RMVideoFileList::instance(),SIGNAL(listUpdateStarted(bool)),this,SLOT(onLoadingListStart(bool)));
connect(RMVideoFileList::instance(),SIGNAL(listUpdateEnd(bool,RMVideoItem*)),this,SLOT(onLoadingListEnd(bool,RMVideoItem*)));
connect(RMVideoFileList::instance(),SIGNAL(loadListEnd()),this,SLOT(onLoadEnd()));
RMPlayProcess::instance()->connectEvents(_frameRight->frameList->listWidget);
#else // PLAYER_ONLY_LIBRARY_MODE
RMPlayProcess::instance()->connectEvents();
#endif // PLAYER_ONLY_LIBRARY_MODE
#if !(DO_NOT_USE_MAP)
// 초기화
#if (USE_WEBVIEW2)
RMWebView::instance(this);//->show();
// ::std 충돌 발생하여 여기서 연결
connect(RMPlayer::instance(),SIGNAL(positionChanged(qint64,qint64)),RMWebView::instance(),SLOT(onPositionChanged(qint64,qint64)));
connect(RMPlayer::instance(),SIGNAL(playEvent(PLAY_EVENT,RMVideoItem*)),RMWebView::instance(),SLOT(onPlayEvent(PLAY_EVENT,RMVideoItem*)));
connect(RMPlayer::instance(),SIGNAL(playEvent(PLAY_EVENT,RMVideoItem*)),this,SLOT(onPlayEvent(PLAY_EVENT,RMVideoItem*)));
#if (USE_GOOGLE_MAP_AND_OSM)
RMWebView::instance2(this);//->show();
connect(RMPlayer::instance(),SIGNAL(positionChanged(qint64,qint64)),RMWebView::instance2(),SLOT(onPositionChanged(qint64,qint64)));
connect(RMPlayer::instance(),SIGNAL(playEvent(PLAY_EVENT,RMVideoItem*)),RMWebView::instance2(),SLOT(onPlayEvent(PLAY_EVENT,RMVideoItem*)));
#endif // USE_GOOGLE_MAP_AND_OSM
#else // WEBVIEW2
RMDialogMap::instance(this)->show(); // 실제 표시되지 않음
#endif // WEBVIEW2
#endif // #if !(DO_NOT_USE_MAP)
#if (MODEL_BBVIEWER)
// CROSS CONNECTION
// qInfo() << RMDialogMap::instance()->speedLabel;
// qInfo() << _frameLeft->frameGraph->speedLabel;
#if (MODEL_WATEX)
connect(_frameLeft->speedLabel->kmhButton,SIGNAL(clicked()),RMDialogMap::instance()->speedLabel,SLOT(onSpeednUnit()));
connect(RMDialogMap::instance()->speedLabel->kmhButton,SIGNAL(clicked()),_frameLeft->speedLabel,SLOT(onSpeednUnit()));
#else
connect(_frameLeft->frameGraph->speedLabel->kmhButton,SIGNAL(clicked()),RMDialogMap::instance()->speedLabel,SLOT(onSpeednUnit()));
connect(RMDialogMap::instance()->speedLabel->kmhButton,SIGNAL(clicked()),_frameLeft->frameGraph->speedLabel,SLOT(onSpeednUnit()));
#endif // MODEL_WATEX
#elif (KMH_MPH_TOGGLE)
connect(_frameLeft->frameGraph->speedLabel,SIGNAL(speedUnitChange()),RMDialogMap::instance(),SLOT(onSpeedUnitChange()));
RMDialogMap::instance()->onSpeedUnitChange();
#endif // MODEL_BBVIEWER
#if !(PLAYER_ONLY_LIBRARY_MODE)
#if !(RM_MODEL == RM_MODEL_TYPE_TB4000)
#if (MODEL_STANDARD)
connect(_title->_captureButton,SIGNAL(clicked()),SLOT(onStartCapture()));
#if !(REMOVE_REPORT)
connect(_title->_reportButton,SIGNAL(clicked()),SLOT(onStartReport()));
#endif
#if !(REMOVE_ALL_SHORT_CUTS)
connect(_title->_captureShortcut,SIGNAL(activated()),SLOT(onStartCapture()));
#if !(REMOVE_REPORT)
connect(_title->_reportShortcut,SIGNAL(activated()),SLOT(onStartReport()));
#endif
// connect(_title->captureShortcut,SIGNAL(activated()),SLOT(onStartCapture()));
#endif // REMOVE_REPORT
#endif // #if !(RM_MODEL == RM_MODEL_TYPE_TB4000)
#endif // REMOVE_ALL_SHORT_CUTS
#endif // #if !(PLAYER_ONLY_LIBRARY_MODE)
// 5CH 뷰어에서 무한 반복되는 경우가 발생함
connect(RMPlayer::instance(),SIGNAL(videoCaptureDone(QList<QString>*)),SLOT(onRequestVideoCaptureDone(QList<QString>*)));
#if (!PLAYER_ONLY_LIBRARY_MODE)
RMFrameList* lst = RMFrameList::getInstance();
connect(_frameLeft->framePlay->fileNextButton,SIGNAL(clicked()),SLOT(onNext()));
connect(_frameLeft->framePlay->filePreviousButton,SIGNAL(clicked()),SLOT(onPrevious()));
connect(_frameLeft->framePlay->openButton,SIGNAL(clicked()),lst,SLOT(onOpen()));
#if (RM_MODEL == RM_MODEL_TYPE_TB4000)
captureMenu = new QMenu(_frameLeft->framePlay->reportButton);
connect(_frameLeft->framePlay->reportButton,SIGNAL(clicked()),this,SLOT(onReportMenu()));
#if (TB5000_INSPECTION_VERSION)
connect(_frameLeft->framePlay->saveButton,SIGNAL(clicked()),this,SLOT(onSaveFile()));
#else // TB5000_INSPECTION_VERSION
connect(_frameLeft->framePlay->saveButton,SIGNAL(clicked()),this,SLOT(onSaveVideoFile()));
#endif // TB5000_INSPECTION_VERSION
connect(_frameLeft->framePlay->fSaveButton,SIGNAL(clicked()),this,SLOT(onSaveFile()));
connect(_frameLeft->framePlay->fPrintButton,SIGNAL(clicked()),this,SLOT(onPrintFile()));
connect(_frameLeft->framePlay->fReportButtonCH1,SIGNAL(clicked()),this,SLOT(onReportFileCHAuto()));
connect(_frameLeft->framePlay->fReportButtonCH2,SIGNAL(clicked()),this,SLOT(onReportFileCHAuto()));
#endif // TB4000
#endif // !PLAYER_ONLY_LIBRARY_MODE
#if !(PLAYER_ONLY_LIBRARY_MODE)
#if (USE_MAXIMIZE)
connect(_title->maximizeButton,SIGNAL(clicked()),this,SLOT(onMaximize()));
#endif
#endif // #if !(PLAYER_ONLY_LIBRARY_MODE)
#if (RM_MODEL_EMT_KR && (SUPPORT_AVI_SPLIT || SPLIT_MULTI_TRACK_VIDEO))
connect(_title->_btnExport,SIGNAL(clicked()),SLOT(onSplitVideo()));
#endif // SUPPORT_AVI_SPLIT
#if (FE_LOG_VERSION)
FELogDialog::instance(this)->show(); // 실제 표시되지 않음
#endif
#if (DETECT_USB_CHANGE)
RMApp::instance()->usb = new rm_usb(this);
RMApp::instance()->usb->registerEvent(this);
RMApplication::instance()->installNativeEventFilter(RMApp::instance()->usb);
connect(RMApp::instance()->usb,SIGNAL(usbChanged(bool,QString&)),SLOT(onUSBChange(bool,QString&)));
#endif // DETECT_USB_CHANGE
#if (USE_DATE_TIME_LIST)
// 날짜 변경 연결
connect(_frameRight->calendar->mCalendar,SIGNAL(dateSelected(QList<RMVideoItem*>*,QDateTime*,bool)),_frameLeft->frameDayTime,SLOT(onDateSelected(QList<RMVideoItem*>*,QDateTime*,bool)));
connect(_frameRight->calendar->mCalendar,SIGNAL(playTime(QDateTime*,bool)),_frameLeft->frameDayTime,SLOT(onPlayTime(QDateTime*,bool)));
connect(_frameRight->calendar->mCalendar,SIGNAL(clearDate()),_frameLeft->frameDayTime,SLOT(onClearDate()));
// 사용자 재생시
//connect(_frameRight->frameList->listWidget,SIGNAL(listSelected(RMVideoItem*)),_frameRight->calendar->mCalendar,SLOT(onSelectItem(RMVideoItem*)));
// 시간 변경시 리스트 이동
connect(_frameLeft->frameDayTime,SIGNAL(listMove(RMVideoItem*)),_frameRight->frameList->listWidget,SLOT(onSelectItem(RMVideoItem*)));
// 월 변경시 리스트 이동 -> 실제로는 월 변경시 해당월의 최초시간 및 최초분의 파일을 선택해야 하여 calendar 에서는 처리 불가
// connect(_frameRight->calendar->mCalendar,SIGNAL(listMove(RMVideoItem*)),_frameRight->frameList->listWidget,SLOT(onSelectItem(RMVideoItem*)));
#endif // frameDayTime
//frameDayTime
#if (USE_VERSION_CHECK)
// Ramda
connect(FMVersionChecker::instance(),&FMVersionChecker::updateFound,this,[=](QMap<QString,QString> info) {
if(_versionDialog != NULL) {
_versionDialog->close();
}
this->_versionDialog = new FMVersionDialog(info,this);
this->_versionDialog->exec();
this->_versionDialog = NULL;
//qInfo() << info << __FUNCTION__ << __LINE__;
});
#endif // USE_VERSION_CHECK
#if (PLAYER_ONLY_LIBRARY_MODE)
connect(_frameLeft->frameMainVideo->btnClose,SIGNAL(clicked()),this,SLOT(onCloseApplication()));
#endif // PLAYER_ONLY_LIBRARY_MODE
}
#if (RM_MODEL == RM_MODEL_TYPE_TB4000 && !PLAYER_ONLY_LIBRARY_MODE)
void WindowMain::allVideoOff()
{
_frameLeft->frameMainVideo->_videoOnOff(false);
_frameLeft->frameVideoSub->_videoOnOff(false);
}
#endif // RM_MODEL_TYPE_TB4000 + PLAYER_ONLY_LIBRARY_MODE
#if (SUPPORT_AVI_SPLIT)
void WindowMain::onSplitVideo()
{
RMVideoItem* item = RMPlayer::instance()->getCurrentItem();
if(item != NULL && !item->filePath.isEmpty()) {
if(FMVideoSplit::progress == NULL) {
FMVideoSplit::progress = new FMProgressDialog(this,FM_WSTR(L"ファイル分割中"));
FMVideoSplit::progress->setModal(false);
FMVideoSplit::progress->show();
}
//
RMPlayer::instance()->prepareForCapture();
QApplication::setOverrideCursor(Qt::WaitCursor);
this->setEnabled(false);
FMVideoSplit* sp = new FMVideoSplit(item->filePath);
connect(sp, SIGNAL(done()), SLOT(onSplitVideoDone()));
QThreadPool::globalInstance()->start(sp,LOADER_THREAD_PRIORITY);
}
}
void WindowMain::onSplitVideoDone()
{
if(FMVideoSplit::progress != NULL) {
FMVideoSplit::progress->hide();
delete FMVideoSplit::progress;
FMVideoSplit::progress = NULL;
}
QApplication::restoreOverrideCursor();
this->setEnabled(true);
}
#elif (SPLIT_MULTI_TRACK_VIDEO)
void WindowMain::onSplitVideo()
{
RMPlayer::instance()->prepareForCapture();
QString dir = RMApp::openFolder(RMApp::appPath(RMApp::CAPTURE),true,FMS::txt("split_files"));
if(dir.isEmpty() == false)
{
QString src = RMPlayer::instance()->getCurrentItem()->anyFilePath();
QFileInfo pinfo = QFileInfo(src);
// 최대 3CH
QString ch1 = QDir::cleanPath(dir + QDir::separator() + pinfo.baseName() + "_CH1.mp4");
QString ch2 = QDir::cleanPath(dir + QDir::separator() + pinfo.baseName() + "_CH2.mp4");
QString ch3 = QDir::cleanPath(dir + QDir::separator() + pinfo.baseName() + "_CH3.mp4");
// << ch3
FMVideoEdit* ed = new FMVideoEdit(QStringList() << src, QStringList() << ch1 << ch2 << ch3, FMVideoEdit::VideoTrackSplit,false);
connect(ed, SIGNAL(done(int)), SLOT(onEditVideoDone(int)));
QThreadPool::globalInstance()->start(ed,LOADER_THREAD_PRIORITY);
}
// RMVideoItem* item = RMPlayer::instance()->getCurrentItem();
// if(item != NULL && !item->filePath.isEmpty()) {
// if(FMVideoSplit::progress == NULL) {
// FMVideoSplit::progress = new FMProgressDialog(this,FM_WSTR(L"ファイル分割中"));
// FMVideoSplit::progress->setModal(false);
// FMVideoSplit::progress->show();
// }
// //
// RMPlayer::instance()->prepareForCapture();
// QApplication::setOverrideCursor(Qt::WaitCursor);
// this->setEnabled(false);
// FMVideoSplit* sp = new FMVideoSplit(item->filePath);
// connect(sp, SIGNAL(done()), SLOT(onSplitVideoDone()));
// QThreadPool::globalInstance()->start(sp,LOADER_THREAD_PRIORITY);
// }
}
#if (RM_MODEL_EMT_KR)
void WindowMain::onEditVideoDone(int errorCode)
{
qInfo() << "ERROR" << errorCode << __FUNCTION__;
// if(FMVideoSplit::progress != NULL) {
// FMVideoSplit::progress->hide();
// delete FMVideoSplit::progress;
// FMVideoSplit::progress = NULL;
// }
QApplication::restoreOverrideCursor();
this->setEnabled(true);
}
#endif // RM_MODEL_TYPE_EMT_KR
#endif // SUPPORT_AVI_SPLIT
#if (!PLAYER_ONLY_LIBRARY_MODE)
void WindowMain::onNext()
{
_frameLeft->framePlay->fileNextButton->blockFor(300);
RMFrameList::getInstance()->listWidget->onNext();
}
void WindowMain::onPrevious()
{
_frameLeft->framePlay->filePreviousButton->blockFor(300);
RMFrameList::getInstance()->listWidget->onPrevious();
}
#endif // #if (!PLAYER_ONLY_LIBRARY_MODE)
#if (USE_RM_KEYBOARD_EVENT && !REMOVE_ALL_SHORT_CUTS)
// @TODO -> MAP
void WindowMain::keyPressEvent(QKeyEvent *event)
{
if(event->isAutoRepeat() == false) {
RMKeyEvent::instance()->pressed(event->key());
}
}
void WindowMain::keyReleaseEvent(QKeyEvent *event)
{
if(event->isAutoRepeat() == false) {
RMKeyEvent::instance()->released(event->key());
}
}
#endif // USE_RM_KEYBOARD_EVENT
#if !(DO_NOT_USE_REPORT)
void WindowMain::onStartReport()
{
// Pressed focus 문제 발생하니 무시
if(RMKeyEvent::instance()->exist())
{
return;
}
RMExcelReport* report = new RMExcelReport(this);
if(report == NULL || RMPlayer::instance()->getCurrentItem() == NULL)
{
report->deleteLater();
return;
}
emit RMApp::instance()->hidePIPForCapture(true);
RMPlayer::instance()->prepareForCapture();
QString folderPath = RMApp::appPath(RMApp::REPORT);
// 동영상 촬영일
// QDate date = QDate::currentDate();
QDate date = RMPlayer::instance()->getCurrentItem()->startTime().date();
QString destPath;
int index = 0;
do
{
#if (RM_MODEL == RM_MODEL_TYPE_XLDR_88)
destPath = folderPath + QDir::separator() + "Accidents_report";
#else
destPath = folderPath + QDir::separator() + "report_" + date.toString("yyyyMMdd");
#endif
if(index > 0)
{
destPath += "_" + QString::number(index);
}
destPath += ".xls";
destPath = QDir::cleanPath(destPath);
index++;
} while(QFile::exists(destPath) == true);
// レポート保存
#if (RM_MODEL == RM_MODEL_TYPE_XLDR_88)
QString title = MKU8("\xe3\x83\xac\xe3\x83\x9d\xe3\x83\xbc\xe3\x83\x88\xe4\xbf\x9d\xe5\xad\x98");
#else
QString title = FMS::txt("save_report");
#endif
QString savePath = QFileDialog::getSaveFileName(0,
title,
destPath,
"Excel files (*.xls)",0,QFileDialog::DontConfirmOverwrite);
QApplication::setOverrideCursor(Qt::WaitCursor);
QApplication::processEvents();
// RMPlayer::instance()->getCurrentItem()
#if (USE_JP_ADDRESS)
double lon = 0;
double lat = 0;
QDateTime dt = RMPlayer::instance()->currentTime(&lon,&lat);
if(savePath.isEmpty() || report->prepare(savePath,&dt,lon,lat) == false)
#else
QDateTime dt = RMPlayer::instance()->currentTime();
if(savePath.isEmpty() || report->prepare(savePath,&dt) == false)
#endif
{
QApplication::restoreOverrideCursor();
delete report;
return;
}
delete report;
emit RMApp::instance()->hidePIPForCapture(false);
QDesktopServices::openUrl(QUrl(savePath.prepend( "file:///" )));
QApplication::restoreOverrideCursor();
}
#endif // #if !(DO_NOT_USE_REPORT)
#if !(DO_NOT_USE_MAP)
// 지도 표시 및 감추기
void WindowMain::onMap()
{
#if (USE_WEBVIEW2)
#if (USE_GOOGLE_MAP_AND_OSM)
FMButton* btn = qobject_cast<FMButton*>(sender());
RMWebView* wb = (btn == _title->_mapButton) ? RMWebView::instance() : RMWebView::instance2();
RMWebView* cwb = (btn == _title->_mapButton) ? RMWebView::instance2() : RMWebView::instance();
if(wb->isHiddenReal()) {
wb->show();
wb->setFocus();
} else {
wb->onClose();
}
cwb->onClose();
#else // USE_GOOGLE_MAP_AND_OSM
if(RMWebView::instance()->isHiddenReal()) {
RMWebView::instance()->show();
RMWebView::instance()->setFocus();
} else {
RMWebView::instance()->onClose();
}
#endif // #endif // USE_GOOGLE_MAP_AND_OSM
#else // USE_WEBVIEW2
//qInfo() << "size:" << _videoWidget->size();
if(RMDialogMap::instance()->isHiddenReal()) {
RMDialogMap::instance()->show();
RMDialogMap::instance()->setFocus();
}
else
{
RMDialogMap::instance()->onClose();
}
#endif // USE_WEBVIEW2
}
#endif // #if !(DO_NOT_USE_MAP)
void WindowMain::onRequestVideoCaptureDone(QList<QString>* fileList)
{
#if (!PLAYER_ONLY_LIBRARY_MODE)
#if (RM_MODEL == RM_MODEL_TYPE_TB4000)
if(fileList == NULL || fileList->size() < 1)
{
setEnabled(true);
return;
}
#if (KEEP_ROI_ON_CAPTURE)
RMPlayer* p = RMPlayer::instance();
qInfo() << __FUNCTION__;
if(p->isROI())
{
QString src = fileList->first();
// 캡쳐영상이 2개이며 전후방 SWAP 된 경우
if(fileList->size() > 1 && p->isSwapped()) {
src = fileList->last();
}
QImage image(src);
QImage crop = image.copy( p->_roiX, p->_roiY, p->_roiW, p->_roiH);
qInfo() << "CH1" <<p->_roiX << p->_roiY << p->_roiW << p->_roiH << __FUNCTION__;
crop.save(src);
//qInfo() << src << __FUNCTION__;
}
if(p->isROIRear()) {
QString src = fileList->last();
// 캡쳐영상이 2개이며 전후방 SWAP 된 경우
if(fileList->size() > 1 && p->isSwapped()) {
src = fileList->first();
}
QImage image(src);
QImage crop = image.copy( p->_roiX2, p->_roiY2, p->_roiW2, p->_roiH2);
qInfo() << "CH2" << p->_roiX2 << p->_roiY2 << p->_roiW2 << p->_roiH2 << __FUNCTION__;
crop.save(src);
}
#endif // KEEP_ROI_ON_CAPTURE
if(_reqestCaptureFor == REQUEST_CAPTURE_FOR_PRINT)
{
printCaptureFile(fileList);
}
else if(_reqestCaptureFor == REQUEST_CAPTURE_FOR_SAVE)
{
saveCaptureFile(fileList);
}
else if (_reqestCaptureFor == REQUEST_CAPTURE_FOR_CONTRAST)
{
// 경위도...
//editCaptureFile(fileList);
}
else if (_reqestCaptureFor == REQUEST_CAPTURE_FOR_REPORT)
{
//double lat = 0.0, lon = 0.0;
//RMPlayer::GetInstance()->getReportString(_reportDateString,_reportTimeString,&lat,&lon);
// RMUIManager::window->_regionLabel->string()
QString ca = RMApp::instance()->currentAddress;
if(ca.contains("<br>")) {
ca = ca.split("<br>").last();
if (ca.startsWith('(') && ca.endsWith(')')) {
// 인덱스 1번부터 (전체 길이 - 2)만큼 추출
ca = ca.mid(1, ca.length() - 2);
}
}
onSaveReportFile(ca,fileList);
}
setEnabled(true);
_reqestCaptureFor = REQUEST_CAPTURE_FOR_NONE; // 종료 후 초기화
#else // TB4000
//qInfo() << "capture done:" << *fileList;
RMPopupCapture* capture = new RMPopupCapture(this,fileList);
int res = capture->exec();
if(res == 1)
{
capture->saveFiles();
}
else
{
foreach (QString path, *fileList) {
QFile::setPermissions(path,QFile::permissions(path) | QFileDevice::WriteOther);
QFile::remove(path);
}
}
delete capture;
#endif // TB4000
#endif // #if (!PLAYER_ONLY_LIBRARY_MODE)
}
void WindowMain::onStartCapture()
{
// Pressed focus 문제 발생하니 무시
if(RMKeyEvent::instance()->exist())
{
return;
}
if(RMPlayer::instance()->requestVideoCapture() == true)
{
//RMUIManager::window->setEnabled(false);
}
}
WindowMain::~WindowMain()
{
}
void WindowMain::onMinimize()
{
// FMButton* fb = NULL;
// fb->setVisible(false);
this->showMinimized();
}
#include <QWindow>
#if (USE_MAXIMIZE)
void WindowMain::onMaximize()
{
RMApp::mMAXIMIZE = 1;
// Pressed focus 문제 발생하니 무시
if(RMKeyEvent::instance()->exist())
{
return;
}
bool bWillFullScreen = !this->isFullScreen();
setHidden(true); // 전환시 플리커 방지
emit RMApp::instance()->appEvent(bWillFullScreen ? RMApp::WillFullScreen : RMApp::WillNormalScreen,1);
if(bWillFullScreen)
{
mFullScreenMode = 1;
_mainLayout->setMargin(0);
_mainLayout->setSpacing(0);
this->showFullScreen();
#if !(REMOVE_ALL_SHORT_CUTS)
escFullScreenShortcut->setEnabled(true);
#endif
}
else
{
mFullScreenMode = 0;
_mainLayout->setMargin(MAIN_LAYOUT_SPACE);
_mainLayout->setSpacing(MAIN_LAYOUT_SPACE);
this->showNormal();
#if !(REMOVE_ALL_SHORT_CUTS)
escFullScreenShortcut->setEnabled(false);
#endif
// 전환 후 포커스 처리하지 않으면 shortcut 동작하지 않음
QTimer::singleShot(10, this, SLOT(setFocus()));
}
#if defined(MODEL_WATEX) // WATEX -> 위치 변경
_title->setHidden(bWillFullScreen);
#else
#endif // MODEL_WATEX
emit RMApp::instance()->appEvent(bWillFullScreen ? RMApp::DidFullScreen : RMApp::DidNormalScreen,1);
#if (TOGGLE_PLAYER || RM_MODEL == RM_MODEL_TYPE_TB4000)
#if (USE_WEBVIEW2)
RMWebView::instance()->snapTo(NULL);
#else // USE_WEBVIEW2
RMDialogMap::instance()->snapTo(NULL);
#endif // USE_WEBVIEW2
#endif // TOGGLE_PLAYER
// 전환시 플리커 방지
setHidden(false);
}
#endif // USE_MAXIMIZE
#if (FE_LOG_VERSION)
void WindowMain::onLogDialog()
{
//qInfo() << checked << __FUNCTION__;
//qInfo() << "size:" << _videoWidget->size();
if(FELogDialog::instance()->isHiddenReal()) {
FELogDialog::instance()->show();
FELogDialog::instance()->setFocus();
}
else
{
FELogDialog::instance()->onClose();
}
}
#endif // FE_LOG_VERSION
#if !(SINGLE_CH_VIEWER)
void WindowMain::onFullScreenSub()
{
setHidden(true); // 전환시 SWAP 감추기
bSubFullScreen = true;
RMPlayer::instance()->toggleSwap();
onFullScreen();
}
#endif // SINGLE_CH_VIEWER
void WindowMain::onFullScreen()
{
#if (USE_MAXIMIZE)
if(RMApp::mMAXIMIZE && this->isFullScreen()) {
onMaximize(); // 상태해제
}
#endif // USE_MAXIMIZE
// Pressed focus 문제 발생하니 무시
if(RMKeyEvent::instance()->exist())
{
return;
}
#if (USE_MAXIMIZE)
RMApp::mMAXIMIZE = 0;
#endif // #if (USE_MAXIMIZE)
bool bWillFullScreen = !this->isFullScreen();
// 보조모니터에서 뷰어를 실행할 경우 현재 SCREEN 을 확인하지 못한다.
QScreen* sc = this->windowHandle()->screen();
QDesktopWidget* m = QApplication::desktop();
const int cs = qApp->screens().indexOf(sc); // 현재 설정된 모니터
const int cps = m->screenNumber(this); // 실제 윈도우가 포함된 모니터
if(cs != cps) {
this->windowHandle()->setScreen(qApp->screens().at(cps));
}
setHidden(true); // 전환시 플리커 방지
#if !(SINGLE_CH_VIEWER || RM_MODEL == RM_MODEL_TYPE_TB4000)
emit RMApp::instance()->appEvent(bWillFullScreen ? RMApp::WillFullScreen : RMApp::WillNormalScreen,bSubFullScreen);
#else // SINGLE_CH_VIEWER
emit RMApp::instance()->appEvent(bWillFullScreen ? RMApp::WillFullScreen : RMApp::WillNormalScreen,false);
#endif // SINGLE_CH_VIEWER
//qInfo() << "SEND EVENT:" << bWillFullScreen << __FUNCTION__;
if(bWillFullScreen)
{
_mainLayout->setMargin(0);
_mainLayout->setSpacing(0);
this->showFullScreen();
#if !(REMOVE_ALL_SHORT_CUTS)
escFullScreenShortcut->setEnabled(true);
#endif
}
else
{
#if !(SINGLE_CH_VIEWER)
if(bSubFullScreen) {
RMPlayer::instance()->toggleSwap();
bSubFullScreen = false;
}
#endif // #if !(SINGLE_CH_VIEWER)
_mainLayout->setMargin(MAIN_LAYOUT_SPACE);
_mainLayout->setSpacing(MAIN_LAYOUT_SPACE);
this->showNormal();
#if !(REMOVE_ALL_SHORT_CUTS)
escFullScreenShortcut->setEnabled(false);
#endif
// 전환 후 포커스 처리하지 않으면 shortcut 동작하지 않음
QTimer::singleShot(10, this, SLOT(setFocus()));
}
#if defined(MODEL_WATEX) // WATEX -> 위치 변경
_title->setHidden(bWillFullScreen);
#else
#endif // MODEL_WATEX
#if (USE_MAXIMIZE)
#if (TOGGLE_PLAYER)
if(bWillFullScreen == false && mFullScreenMode == 1) {
#if (USE_WEBVIEW2)
RMWebView::instance()->snapTo(NULL);
#else // WEBVIEW2
RMDialogMap::instance()->snapTo(NULL);
#endif // WEBVIEW2
}
#endif // TOGGLE_PLAYER
emit RMApp::instance()->appEvent(bWillFullScreen ? RMApp::DidFullScreen : RMApp::DidNormalScreen,mFullScreenMode);
#else
emit RMApp::instance()->appEvent(bWillFullScreen ? RMApp::DidFullScreen : RMApp::DidNormalScreen,0);
#endif
// 전환시 플리커 방지
setHidden(false);
}
#if (USE_DEVICE_SETTINGS)
#define KEEP_LAST_SETTING_DRIVE 1
#if (MULTI_MODEL_VIEWER)
void WindowMain::onShowSettings()
{
// 일시정지
RMPlayer::instance()->prepareForCapture();
QStringList disks = RMApp::getRemovableDisks();
bool bShowDiskSelector = false;
// 드라이브가 없는 경우 -> 주의 메시지 표시 후 종료
if(disks.count() == 0)
{
// 注意
// 設定ファイルがありません。
QString title = MKU8("\xe6\xb3\xa8\xe6\x84\x8f");
QString msg = MKU8("\xe8\xa8\xad\xe5\xae\x9a\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\xe3\x81\x8c\xe3\x81\x82\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93\xe3\x80\x82");
RMPopupMessage* message = new RMPopupMessage(this,title,msg);
message->hideCloseButton();
message->exec();
delete message;
return;
}
// 디스크 1개이며
else if(disks.count() == 1)
{
// 동일 모델 확인될 경우 실행
char model[128] = {0,};
bool isEMS = false;
if(RMApp::isModelDisk(disks[0],&isEMS,model)) {
RMSettingsWindowBase::lastSettingDisk = disks[0];
// 별도 S/W 에서 설정된 파일일 경우 모델선택 창 표시
// EMS config 의 경우 17BYTE 로 모델은 선택되어 있지 않음
if(isEMS) {
RMPopupCreateModel* modelDialog = new RMPopupCreateModel(this);
int res = modelDialog->exec();
CFG::setModel(modelDialog->selectedModel);
delete modelDialog;
if(res == 0) { // 취소
return;
}
}
else
{
CFG::setModel(model);
}
}
// 동일 모델이 아니거나 포멧된 디스크의 경우
else
{
bShowDiskSelector = true;
}
}
// 1개 이상일 경우 무조건 선택창 표시
else
{
QString last = RMSettingsWindowBase::lastSettingDisk;
// 기존 디스크 존재하고 모델 디스크일 경우 디스크 선택창 표시하지 않는다.
bShowDiskSelector = !(last.length() > 0 && RMApp::isModelDisk(last,NULL) );
// 2개 이상인 경우에도 1개만 모델 디스크일 경우 자동 선택
QList<QPair<QString,QString>> found = RMApp::searchModelDisk();
if(found.size() == 1) // 검색된 모델이 1개 -> 표시없이 처리
{
RMSettingsWindowBase::lastSettingDisk = found.first().first;
bShowDiskSelector = false;
CFG::setModel(found.first().second);
}
else if (found.size() > 1) // 검색된 모델이 2개 이상
{
RMPopupSelectModel* modelDialog = new RMPopupSelectModel(found,this);
//modelDialog->models = found;
int res = modelDialog->exec();
if(res == 0) { // 취소
return;
}
RMSettingsWindowBase::lastSettingDisk = found.at(modelDialog->modelIndex).first;
CFG::setModel(found.at(modelDialog->modelIndex).second);
delete modelDialog;
bShowDiskSelector = false;
}
}
// 디스크 선택창 표시
if(bShowDiskSelector) {
RMPopupSelectDisk* diskDialog = new RMPopupSelectDisk(this);
int res = diskDialog->exec();
QString disk = diskDialog->selectedDisk;
delete diskDialog;
if(res == 0) { // 취소
return;
}
RMSettingsWindowBase::lastSettingDisk = disk;
char model[128] = {0,};
bool bEMS = false;
if(RMApp::isModelDisk(disk,&bEMS,model)) {
if(!bEMS) {
CFG::setModel(model);
}
}
else {
RMPopupCreateModel* modelDialog = new RMPopupCreateModel(this);
res = modelDialog->exec();
CFG::setModel(modelDialog->selectedModel);
delete modelDialog;
if(res == 0) { // 취소
return;
}
}
}
WindowSettings* ps = NULL;
if(CFG::model == MODEL_XDR_66) {
ps = new WindowSettings66(this);
}
else if(CFG::model == MODEL_XDR_88) {
ps = new WindowSettings88(this);
}
else {
return;
}
ps->move(x() + (width() - ps->width()) / 2,
y() + (height() - ps->height()) / 2);
ps->exec();
delete ps;
}
#elif (RM_MODEL_EMT_KR)
void WindowMain::onShowSettings()
{
// 설정버튼은 자동 활성화 되어 검증할 필요없음
WindowSettings* ps = new WindowSettings(this);
#if (RM_MODEL_EMT_KR)
connect(this,SIGNAL(usbRemoved()),ps,SLOT(onUsbRemoved()));
#endif // @RM_MODEL_EMT_KR
ps->move(x() + (width() - ps->width()) / 2,
y() + (height() - ps->height()) / 2);
ps->exec();
delete ps;
}
#else // MULTI_MODEL_VIEWER
void WindowMain::onShowSettings()
{
// 일시정지
RMPlayer::instance()->prepareForCapture();
QStringList disks = RMApp::getRemovableDisks();
// 2019/08/14 시나리오 변경
bool bShowDiskSelector = false;
// 드라이브가 없는 경우 -> 주의 메시지 표시 후 종료
if(disks.count() == 0)
{
#if (LIVE_LANGUAGE2)
QString title = FMS::txt("warning");
QString msg = FMS::txt("no_settings_file");
#else // LIVE_LANGUAGE2
// 注意
// 設定ファイルがありません。
QString title = MKU8("\xe6\xb3\xa8\xe6\x84\x8f");
QString msg = MKU8("\xe8\xa8\xad\xe5\xae\x9a\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\xe3\x81\x8c\xe3\x81\x82\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93\xe3\x80\x82");
#if (LIVE_LANGUAGE_CHANGE)
if(RMLanguage::isJP() == false)
{
title = "Warning";
msg = "Configuration file(SD Card) not found!";
}
#endif // LIVE_LANGUAGE_CHANGE
#endif // LIVE_LANGUAGE2
RMPopupMessage* message = new RMPopupMessage(this,title,msg);
message->hideCloseButton();
message->exec();
delete message;
return;
}
// 디스크 1개이며
else if(disks.count() == 1)
{
// 동일 모델 확인될 경우 실행
if(RMApp::isModelDisk(disks[0])) {
#if !(USE_DEVICE_SETTINGS_JSON)
RMSettingsWindowBase::lastSettingDisk = disks[0];
#else // USE_DEVICE_SETTINGS_JSON
#endif // USE_DEVICE_SETTINGS_JSON
}
// 동일 모델이 아니거나 포멧된 디스크의 경우
else {
bShowDiskSelector = true;
}
}
// 1개 이상일 경우 무조건 선택창 표시
else
{
QString last = "";
#if !(USE_DEVICE_SETTINGS_JSON)
last = RMSettingsWindowBase::lastSettingDisk;
#else
#endif // USE_DEVICE_SETTINGS_JSON
#if (KEEP_LAST_SETTING_DRIVE)
// 기존 디스크 존재하고 모델 디스크일 경우 디스크 선택창 표시하지 않는다.
bShowDiskSelector = !(last.length() > 0 && RMApp::isModelDisk(last) );
#else // KEEP_LAST_SETTING_DRIVE
bShowDiskSelector = true;
#endif // KEEP_LAST_SETTING_DRIVE
}
// 디스크 선택창 표시
if(bShowDiskSelector) {
RMPopupSelectDisk* diskDialog = new RMPopupSelectDisk(this);
int res = diskDialog->exec();
QString disk = diskDialog->selectedDisk;
delete diskDialog;
if(res == 0) { // 취소
return;
}
#if !(USE_DEVICE_SETTINGS_JSON)
RMSettingsWindowBase::lastSettingDisk = disk;
#else
#endif // USE_DEVICE_SETTINGS_JSON
}
WindowSettings* ps = new WindowSettings(this);
ps->move(x() + (width() - ps->width()) / 2,
y() + (height() - ps->height()) / 2);
ps->exec();
delete ps;
}
#endif // MULTI_MODEL_VIEWER
void WindowMain::onCloseSettings()
{
Q_ASSERT(_settingWindow != NULL);
disconnect(_settingWindow,SIGNAL(closeSignal()),this,SLOT(onCloseSettings()));
_settingWindow->close();
delete _settingWindow;
_settingWindow = NULL;
}
#endif // #if (USE_DEVICE_SETTINGS)
#if (PLAYER_ONLY_LIBRARY_MODE)
void WindowMain::onCloseApplication()
{
bTB5000Showed = false;
RMPlayer::instance()->playerF()->clearVideoRenderers();
RMPlayer::instance()->stop();
RMPlayer::instance()->clear();
close();
if(_onTB5000 != NULL) {
_onTB5000(0);
}
RMApp::instance()->pMainWindow->deleteLater();
//qInfo() << __FUNCTION__;
}
#else // PLAYER_ONLY_LIBRARY_MODE
void WindowMain::onCloseApplication()
{
#if (USER_LOGER)
if(RMApp::userLog) {
RMApp::instance()->saveLog();
}
#endif
#if (USE_WEBVIEW2)
RMWebView::instance()->closeWebView2(); // 내부에서 removeHtml 처리됨
#else // #if (USE_WEBVIEW2)
#if (USE_HTML_MAP)
RMDialogMap::instance()->removeHtml();
#endif
#endif // #if (USE_WEBVIEW2)
#if (RM_MODEL == RM_MODEL_TYPE_AN6000)
RMVideoFileList::instance()->removeTemps();
#endif // TYPE_AN6000
emit RMApp::instance()->appEvent(RMApp::WillCloseApplication,0);
QApplication::closeAllWindows();
QApplication::quit();
}
#endif // #if !(PLAYER_ONLY_LIBRARY_MODE)
#if !(PLAYER_ONLY_LIBRARY_MODE)
void WindowMain::onShowInfo()
{
RMPlayer::instance()->prepareForCapture();
#if (USE_DEVICE_SETTINGS && !USE_DEVICE_SETTINGS_JSON)
// 단말기 DISK
bool bDriverExist = false;
QString versionPath;
// 최종 설정 패스가 존재하고, VERSION.TXT 파일이 존재할 경우
if(WindowSettings::lastSettingDisk.length() > 0 ||
QFile::exists(WindowSettings::lastSettingDisk) == true &&
QFile::exists(QDir::cleanPath(WindowSettings::lastSettingDisk + "/VERSION.TXT")) == true) {
bDriverExist = true;
versionPath = QDir::cleanPath(WindowSettings::lastSettingDisk + "/VERSION.TXT");
}
else {
QString disk = RMApp::searchInfoDisk();
if(disk.length() > 0) {
bDriverExist = true;
versionPath = QDir::cleanPath(disk + "//VERSION.TXT");
}
}
QString fw;
QString gps;
FILE* f = NULL;
if (bDriverExist) {
f = fopen(versionPath.toLocal8Bit(),"r+b");
}
if(f != NULL)
{
char versions[1024] = {0,};
fread(versions,1,1024,f);
fclose(f);
QString listString(versions);
QStringList list = listString.split(QRegExp("[\r\n]"),QString::SkipEmptyParts);
if(list.count() > 0) {
fw = list[0];
if(list.count() > 1) {
gps = list[1];
}
}
}
const QString yearString = MKU8("\xe5\xb9\xb4 ");// 年
const QString monthString = MKU8("\xe6\x9c\x88\xe5\xba\xa6\xe7\x89\x88"); // 月度版
if(gps.isEmpty() == false) {
// GpsDB 2019060101
QStringList gpsList = gps.split(" ",QString::SkipEmptyParts);
if(gpsList.count() > 1)
{
QDateTime dateTime = QDateTime::fromString(gpsList[1],"yyyyMMddHH");
if(dateTime.isValid()) {
gps = dateTime.toString("yyyy") + yearString + dateTime.toString("MM") + monthString;
}
}
}
RMPopupInfo* infoDialog = new RMPopupInfo(this,fw,gps);
#else
RMPopupInfo* infoDialog = new RMPopupInfo(this,"","");
#endif
infoDialog->exec();
delete infoDialog;
}
#endif // #if !(PLAYER_ONLY_LIBRARY_MODE)
void WindowMain::onLoadingListStart(bool bLoading)
{
#if !(PLAYER_ONLY_LIBRARY_MODE)
_frameLeft->framePlay->openButton->setEnabled(false);
#endif // PLAYER_ONLY_LIBRARY_MODE
#if (PLAY_CONTINUE_EVENT)
RMPlayer::instance()->onUserStop();
#else
RMPlayer::instance()->stop();
#endif
#if (MODEL_BBVIEWER)
RMDialogMap::instance()->runScript(QString("clearPath();"));
#endif
if (bLoading) {
#if (FORCE_FM_STRING)
//RMOverwrite::gCurrent = OVERWRITE_OPTION_CANCEL;
RMDialogProgress::start(FMS::txt("open_title"),true,true); // SHOW PROGRESS
#else
// ファイルOPEN
#if (LIVE_LANGUAGE_CHANGE)
#if (MODEL_KOREAN_ONLY)
QString msg = FM_WSTR(L"파일 로딩 중...");
#else
QString msg = RMLanguage::isJP() ? MKU8("\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\x4f\x50\x45\x4e") : "Open files...";
#endif
RMDialogProgress::start(msg); // SHOW PROGRESS
#else
RMDialogProgress::start(MKU8("\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\x4f\x50\x45\x4e")); // SHOW PROGRESS
#endif
#endif
}
}
#if !(PLAYER_ONLY_LIBRARY_MODE)
void WindowMain::onLoadEnd() {
#if (RM_MODEL == RM_MODEL_TYPE_TB4000)
// 재생할 파일 존재할 경우 썸네일 표시 X
if(!RMApp::instance()->playPath.isEmpty() && QFile(RMApp::instance()->playPath).exists()) {
RMVideoItem* item = RMVideoFileList::instance()->itemWithPath(RMApp::instance()->playPath);
// 그냥 (현재 파일이 1시간 리스트에 포함되지 않을 경우) 상세 리스트로 전환
if(RMVideoFileList::instance()->get1HourList()) {
RMVideoFileList::instance()->set1HourList(false,true,item);
_frameRight->frameList->onTypeChanged();
}
if(item != NULL) {
RMVideoFileList::instance()->playItem(item);
}
RMApp::instance()->playPath = ""; // 삭제
return;
}
QString folder = RMApp::currentRoot;// RMSettings::instance()->lastMoviePath();
if(!folder.isEmpty() && RMFrameList::isRootFolder(folder)) {
QTimer::singleShot(500,Qt::PreciseTimer,_frameRight->frameList,SLOT(onThumbnail()));
}
#endif // TB4000
}
#endif // !(PLAYER_ONLY_LIBRARY_MODE)
void WindowMain::onLoadingListEnd(bool bLoading,RMVideoItem*)
{
QTimer::singleShot(200, this, SLOT(onLoadingListEndUI()));
if (bLoading) {
RMDialogProgress::stop();
}
QApplication::restoreOverrideCursor();
}
void WindowMain::onLoadingListEndUI() {
#if !(PLAYER_ONLY_LIBRARY_MODE)
_frameLeft->framePlay->openButton->setEnabled(true);
#endif // #if !(PLAYER_ONLY_LIBRARY_MODE)
}
#if !(PLAYER_ONLY_LIBRARY_MODE)
#if !(REMOVE_OLD_C)
void WindowMain::onOpenPopup()
{
// フォルダを開く
QString title = RMLanguage::isJP() ? MKU8("\xe3\x83\x95\xe3\x82\xa9\xe3\x83\xab\xe3\x83\x80\xe3\x82\x92\xe9\x96\x8b\xe3\x81\x8f") : "Open Folder";
RMDialogBBViewer* dialog = new RMDialogBBViewer(this,title);
dialog->createOpenLayout();
if(dialog->exec())
{
if(RMDialogBBViewer::selectedDisk.length() > 0)
{
if(RMDialogBBViewer::selectedDisk == "OPENFOLDER")
{
_frameRight->frameList->onOpen();
}
else
{
_frameRight->frameList->openFolder(RMDialogBBViewer::selectedDisk);
}
}
}
}
#endif // REMOVE_OLD_C
#endif // !(PLAYER_ONLY_LIBRARY_MODE)
#if ((TOGGLE_PLAYER || FIXED_MAP_FRAME) && !DO_NOT_USE_MAP) //
void WindowMain::onWindowMove()
{
#if (USE_WEBVIEW2)
#if (FIXED_MAP_FRAME)
//qInfo() << _frameRight->frameMap->size() << __FUNCTION__;
RMWebView::instance()->snapTo(_frameRight->frameMap);
#else // FIXED_MAP_FRAME
RMWebView::instance()->snapTo(NULL);
#endif // FIXED_MAP_FRAME
#else // USE_WEBVIEW2
RMDialogMap::instance()->snapTo(NULL);
#endif // USE_WEBVIEW2
}
#if (TOGGLE_PLAYER && !DO_NOT_USE_MAP)
void WindowMain::onSnapMap()
{
#if (USE_WEBVIEW2)
//qInfo() << "RMWebView::instance()->isHidden():" << RMWebView::instance()->isHidden() << __FUNCTION__;
if(RMWebView::instance()->isHiddenReal())
{
//qInfo() << "SHOW FIRST WEBVIEW2" << __FUNCTION__;
RMWebView::instance()->show();
//RMWebView::instance()->toggle(true,RMWebView::ON_USER_SWITCH);
}
RMWebView::instance()->snapTo(_frameRight->frameMap);
#else // WEBVIEW2
if(RMDialogMap::instance()->isHiddenReal())
{
RMDialogMap::instance()->show();
}
RMDialogMap::instance()->snapTo(_frameRight->frameMap);
#endif // WEBVIEW2
}
#endif // #if (TOGGLE_PLAYER)
#endif // #if (TOGGLE_PLAYER || FIXED_MAP_FRAME) //
#if (OPEN_WITH_FILE_EXT)
void WindowMain::onPlayFirstFile()
{
//QApplication::restoreOverrideCursor();
//setEnabled(true);
//setHidden(false);
// 현재 타입 업데이트
_frameRight->frameList->onTypeChanged();
// 직접 로딩했기 때문에 ...
emit RMVideoFileList::instance()->playItemFound(RMVideoFileList::instance()->allItems().first(),-1);
}
bool WindowMain::openWithFile()
{
#if(RM_MODEL == RM_MODEL_TYPE_TB4000)
if(!RMApp::currentRoot.isEmpty()) {
// 파일 존재하지 않을 경우 ...
if(!QFile(RMApp::currentRoot).exists()) {
RMApp::currentRoot = "";
return false;
}
QFileInfo info(RMApp::currentRoot);
if(info.suffix().toUpper() == "TB4") {
// 파일명 규칙 검사
QDateTime dt;
RMVideoItem::IsFeasible(RMApp::currentRoot,&dt);
if(dt.isValid()) {
// 경로가 USB 에 속해 있을 경우 (디스크 전체 오픈)
if(rm_usb::isRemovablePath(RMApp::currentRoot)) {
// 재생할 파일명 별도 저장
//RMApp::instance()->playPath = RMApp::currentRoot;
// 2026/01/08 재생없이 Thumbnail 표시
RMApp::instance()->playPath = "";
QString driver = RMApp::currentRoot.left(1) + ":\\";
RMApp::currentRoot = "";
_frameRight->frameList->openFolder(driver);
} else {
QApplication::setOverrideCursor(Qt::WaitCursor);
setEnabled(false);
//setHidden(true);
// qInfo() << "1Hour:" << RMVideoFileList::instance()->get1HourList() << __FUNCTION__;
//_frameRight->frameList->onTypeChanged();
QList<QUrl> l = QList<QUrl>() << QUrl::fromLocalFile(RMApp::currentRoot);
RMVideoFileList::instance()->loadFromList(l,true);
// 1개 파일 재생시에는 세부리스트로 시작
RMVideoFileList::instance()->set1HourList(false,false,NULL);
QTimer::singleShot(100,Qt::PreciseTimer,this,SLOT(onPlayFirstFile()));
}
return true;
}
}
RMApp::currentRoot = "";
return false;
}
#endif // #if(RM_MODEL == RM_MODEL_TYPE_TB4000)
return false;
}
#endif // OPEN_WITH_FILE_EXT
#if (START_WITH_USB_SD || DETECT_USB_CHANGE)
void WindowMain::openUSB()
{
#if(RM_MODEL_TB)
const bool loadCFG = false;
QString folder = rm_usb::getRemovableDisk("TB4000");
#elif (RM_MODEL_EMT_KR)
const bool loadCFG = true;
QString folder = rm_usb::getRemovableDisk();
#endif // RM_MODEL_EMT_KR
int code = rm_usb::isDeviceDriver(folder,loadCFG);
if(code == 0) {
_frameRight->frameList->openFolder(folder);
// 버전 정보 업데이트
#if (RM_MODEL_EMT_KR)
QString versionString = QString::number(CFG::version());
if(CFG::version() < 999) {
int versionInt = CFG::version();
// 각 자릿수 추출
int major = versionInt / 100; // 100의 자리 -> 1
int minor = (versionInt / 10) % 10; // 10의 자리 -> 0
int patch = versionInt % 10; // 1의 자리 -> 0
// 문자열 포맷팅
versionString = QString("%1.%2.%3")
.arg(major)
.arg(minor)
.arg(patch);
}
_title->_modelInfo->setText(CFG::modelName() + " v" + versionString);
_title->_settingsButton->setEnabled(true);
#endif // RM_MODEL_EMT_KR
#if (USE_VERSION_CHECK)
FMVersionChecker::instance()->start();
#endif // USE_VERSION_CHECK
}
#if (RM_MODEL_EMT_KR)
else if (code == CFG_CHECKSUM_ERROR) {
QTimer::singleShot(1000,Qt::PreciseTimer,this,SLOT(onWrongSDCard()));
}
#endif // @RM_MODEL_EMT_KR
else {
QTimer::singleShot(500, _frameRight->frameList, SLOT(onOpen()));
}
}
void WindowMain::onUSBChange(bool inserted, QString& drive)
{
// 제거시 리스트 삭제
if(!inserted && drive.toUpper() == RMApp::instance()->usb->_openDrive) {
if(RMApp::currentRoot.startsWith(RMApp::instance()->usb->_openDrive,Qt::CaseInsensitive)) {
// SSD 등에서 폴더를 열었을 경우 리스트는 제거하지 않는다
emit RMPlayer::instance()->userStop();
RMVideoFileList::instance()->clearList();
}
#if (RM_MODEL_EMT_KR)
CFG::clear();
_title->_modelInfo->setText("---");
_title->_settingsButton->setEnabled(false);
emit usbRemoved(); // 설정창에 USB 제거 알림
#endif // @RM_MODEL_EMT_KR
#if (RM_MODEL_TB)
QMessageBox msgBox(QMessageBox::Warning,
"TB4000",
FM_WSTR(L"SD 카드가 제거되었습니다."),
QMessageBox::Ok,
this);
msgBox.setButtonText(QMessageBox::Ok, FM_WSTR(L"확인"));
msgBox.exec();
#endif // @RM_MODEL_TB
}
#if (RM_MODEL_EMT_KR)
if(inserted) {
RMApp::closeOpenFolder();
QString folder = rm_usb::getRemovableDisk();
int code = rm_usb::isDeviceDriver(folder,true);
if(code == 0) {
_frameRight->frameList->openFolder(folder);
// 버전 정보 업데이트
_title->_modelInfo->setText(CFG::modelName() + " v" + QString::number(CFG::version()));
_title->_settingsButton->setEnabled(true);
} else if (code == CFG_CHECKSUM_ERROR) {
QTimer::singleShot(1000,Qt::PreciseTimer,this,SLOT(onWrongSDCard()));
}
}
#endif // @RM_MODEL_EMT_KR
}
#endif // DETECT_USB_CHANGE
#if (RM_MODEL_EMT_KR)
void WindowMain::onWrongSDCard()
{
QMessageBox msgBox(QMessageBox::Warning,
"NEXIAN",
FMS::txtLine("wrong_sd_card"),
QMessageBox::Ok,
this);
msgBox.setButtonText(QMessageBox::Ok, FM_WSTR(L"확인"));
msgBox.exec();
#if (USE_VERSION_CHECK)
FMVersionChecker::instance()->start();
#endif // USE_VERSION_CHECK
}
#endif // @RM_MODEL_EMT_KR
#if (LIVE_LANGUAGE_CHANGE)
#if (!PLAYER_ONLY_LIBRARY_MODE)
void WindowMain::showEvent(QShowEvent *ev)
{
Q_UNUSED(ev)
if(_bFirstWindowLoad == true)
{
#if (FFMPEG_VTHREAD_DEBUG)
_frameRight->frameList->openFolder("C:\\stroage\\testing\\NEW");
#endif // FFMPEG_VTHREAD_DEBUG
#if (RM_MODEL == RM_MODEL_TYPE_TB4000)
QString pw = RMApp::password();
if(pw.isEmpty())
{
onPassword();
} else
{
FAV::AVPlayer::setPassword(pw.toLatin1().data()); // "123456789#"
}
#endif // RM_MODEL_TYPE_TB4000
#if (SUPPORT_FORMAT_FREE)
//qInfo() << "DISK NUMBER:" << << __FUNCTION__;
BmFF bmFF;
bmFF.mMakeFactoryAging = false;
bmFF.mEmmc = false;
bmFF.mMstarPark = true; // SetMstarPark()함수 호출
// char format[] = "\\\\.\\?:";
int nDriverNo = GetPhysicalDrive('F');
if(nDriverNo >= 0) {
// "\\\\.\\F:"
QString physicalDriver = "\\\\.\\PhysicalDrive" + QString::number(nDriverNo);
//QString physicalDriver = "\\\\.\\F:";
if(bmFF.Init2(physicalDriver.toLocal8Bit().data(), 1920, 0, 24, 0) == 0)
{
bmFF.MakeDisk();
}
}
#endif // #if (SUPPORT_FORMAT_FREE)
_bFirstWindowLoad = false;
#if (TOGGLE_PLAYER) // || FIXED_MAP_FRAM
QTimer::singleShot(100, this, SLOT(onSnapMap()));
#endif
#if (FIXED_MAP_FRAME) // ||
RMWebView::instance()->snapTo(_frameRight->frameMap);
#endif
#if (OPEN_WITH_FILE_EXT)
if(openWithFile()){
return;
}
#endif // OPEN_WITH_FILE_EXT
#if (START_WITH_USB_SD)
openUSB();
#endif // START_WITH_USB_SD
}
#if(REMOVE_OLD_C)
if(RMLanguage::instance()->language() != RMLanguage::LANGUAGE_KR) {
RMLanguage::instance()->refresh();
}
#else // REMOVE_OLD_C
if(RMLanguage::isJP() == false)
{
RMLanguage::instance()->refresh();
}
#endif // REMOVE_OLD_C
}
#endif // #if (!PLAYER_ONLY_LIBRARY_MODE)
#if (RM_MODEL == RM_MODEL_TYPE_TB4000 && !PLAYER_ONLY_LIBRARY_MODE)
void WindowMain::onSaveVideoFile()
{
if (!RMPlayer::instance()->playerF()->isLoaded())
{
noPlayFileMessage();
return;
}
RMPlayer::instance()->requestVideoCapture();
QString documentPath = RMApp::lastPath("export");
if (documentPath.isEmpty() || !QFile::exists(documentPath)) {
QStringList list = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
if(list.count() > 0)
{
documentPath = list.first();
}
}
QString srcPath = RMPlayer::instance()->getCurrentItem()->filePath;
QFileInfo info(srcPath);
QString dest = documentPath + QDir::separator() + info.baseName() + QString(".mp4");
QString filter = "Video files (*.mp4)";
QString path = QFileDialog::getSaveFileName(this,
FM_WSTR(L"파일저장"),
dest,
"Video files (*.mp4)",
&filter,
QFileDialog::DontConfirmOverwrite);
QFileInfo pinfo = QFileInfo(path);
if(!path.isEmpty()) {
#if (USER_LOGER)
if(RMApp::userLog) {
RMApp::instance()->appendLog("INFO","EXPORT FILE:" + info.fileName());
}
#endif // USER_LOGER
RMApp::setLastPath("export",pinfo.dir().path());
QString tempPath = QDir::temp().absoluteFilePath(info.baseName() + ".mp4");
// qInfo() << "tempPath:" << tempPath << __FUNCTION__;
if(QFile::exists(tempPath)) {
QFile(tempPath).setPermissions(QFile::ReadOther | QFile::WriteOther);
QFile::remove(tempPath);
}
if(QFile::copy(srcPath, tempPath)) {
#if (SPLIT_MULTI_TRACK_VIDEO)
// 트랙 분리 사용시에는
// 디코딩도 임시 폴더에 저장
QString tpath = QDir::temp().absoluteFilePath(pinfo.baseName() + "_decoded.mp4");
if(QFile::exists(tpath)) {
QFile::remove(tpath);
}
//qInfo() << "INPUT:" << tpath << QFile(tpath).exists() << "SRC(TEMP):" << tempPath << QFile(tempPath).exists() << __FUNCTION__;
tb_decrypt_mp4(tempPath.toLocal8Bit().data(), tpath.toLocal8Bit().data(),(unsigned char*)RMApp::password().toLatin1().data());
// qInfo() << "tb_decrypt_mp4:" << ret << __FUNCTION__;
QString ch1 = QDir::cleanPath(pinfo.dir().absolutePath() + QDir::separator() + pinfo.baseName() + "_CH1.mp4");
QString ch2 = QDir::cleanPath(pinfo.dir().absolutePath() + QDir::separator() + pinfo.baseName() + "_CH2.mp4");
FMVideoEdit* ed = new FMVideoEdit(QStringList() << tpath, QStringList() << ch1 << ch2 ,FMVideoEdit::VideoTrackSplit);
connect(ed, SIGNAL(done(int)), SLOT(onEditVideoDone(int)));
QThreadPool::globalInstance()->start(ed,LOADER_THREAD_PRIORITY);
#else // 트랙분리
tb_decrypt_mp4(tempPath.toLocal8Bit().data(), path.toLocal8Bit().data(),(unsigned char*)RMApp::password().toLatin1().data());
#endif // SPLIT_MULTI_TRACK_VIDEO
// QFile(tempPath).remove()
QFile(tempPath).setPermissions(QFile::ReadOther | QFile::WriteOther);
QFile::remove(tempPath); // 복제된 (암호화된)SRC 파일 삭제
}
}
}
#if (SPLIT_MULTI_TRACK_VIDEO)
void WindowMain::onEditVideoDone(int errorCode)
{
if(errorCode != 0) {
}
#if (USER_LOGER)
if(RMApp::userLog) {
RMApp::instance()->appendLog("INFO",QString().sprintf("EXPORT FILE DONE:(%d)",errorCode));
}
#endif // USER_LOGER
//qInfo() << __FUNCTION__ << errorCode << __FUNCTION__;
}
#endif // #if (SPLIT_MULTI_TRACK_VIDEO)
void WindowMain::onSaveFile()
{
if (!RMPlayer::instance()->playerF()->isLoaded())
{
noPlayFileMessage();
return;
}
_reqestCaptureFor = REQUEST_CAPTURE_FOR_SAVE;
if(RMPlayer::instance()->requestVideoCapture())
{
this->setEnabled(false);
}
else if (!RMPlayer::instance()->playerF()->isLoaded())
{
noPlayFileMessage();
}
}
void WindowMain::noPlayFileMessage()
{
QMessageBox msgBox(QMessageBox::Warning,
"TB4000",
FM_WSTR(L"재생중인 파일이 없습니다."),
QMessageBox::Ok,
this);
msgBox.setButtonText(QMessageBox::Ok, FM_WSTR(L"확인"));
msgBox.exec();
}
void WindowMain::onSaveReportFile(QString locationString,QList<QString>* imageList)
{
// 파일 저장 먼저 확인
QString documentPath = "";
QStringList list = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
if(list.count() > 0)
{
documentPath = list.first();
}
QString destPath = QFileDialog::getSaveFileName(0, FM_WSTR(L"파일 저장"), documentPath + "\\uncover_report.xlsx","Excel files (*.xlsx)");
if(destPath.isEmpty() || destPath.isNull())
{
QApplication::restoreOverrideCursor();
setEnabled(true);
return;
}
// 기존 파일 삭제
QFile destFile(destPath);
if(destFile.exists() == true)
{
QFile::remove(destPath);
}
// 경로 변경해 주지 않으면 오류발생
destPath = destPath.replace("/","\\");
QDate date = QDate::currentDate(); // 현재 날짜
// 임시파일을 생성하지 않으면 SaveAs 호출할 수 없음 (Save As 는 이전 Excel 포멧을 위해 필수)
QString tempPath = QDir::temp().absoluteFilePath("report" + date.toString("yyyy_MMdd_HHmmss") + ".xlsx");
QFile tempFile(tempPath);
if(tempFile.exists() == true)
{
QApplication::restoreOverrideCursor();
setEnabled(true);
QFile::remove(tempPath);
}
QFile::copy(":/report/telebit_report.xlsx",tempPath);
tempPath = tempPath.replace("/","\\");
// https://forum.qt.io/topic/13303/qt-and-ms-excel/3
QAxObject* excel = new QAxObject( "Excel.Application", 0 );
if(excel == NULL)
{
QApplication::restoreOverrideCursor();
setEnabled(true);
QFile::remove(destPath);
return;
}
excel->setProperty("Visible", false);
excel->setProperty("DisplayAlerts", false);
QAxObject* workbooks = excel->querySubObject( "Workbooks" );
if(workbooks == NULL)
{
QApplication::restoreOverrideCursor();
setEnabled(true);
QFile::remove(destPath);
delete excel;
return;
}
bool bSuccess = false;
QAxObject* workbook = workbooks->querySubObject( "Open(const QString&)", tempPath );
if(workbook != NULL)
{
workbook->setProperty("DisplayAlerts", false); // 경고 표시 방지
QAxObject* sheets = workbook->querySubObject( "Worksheets" );
if(sheets != NULL)
{
QAxObject* sheet = sheets->querySubObject( "Item( int )", 1 ); // sheet 가져옴
if(sheet != NULL)
{
QAxObject * range;
range = sheet->querySubObject("Range(D6)");
// ex> 2018년 01월 02일 14시 25분
// _reportDateString, + " " + _reportTimeString
double lat = 0.0, lon = 0.0;
QString dd = RMPlayer::instance()->currentTimeString(&lat,&lon);
range->setProperty("Value",dd);
range = sheet->querySubObject("Range(D7)");
range->setProperty("Value",locationString);
range = sheet->querySubObject("Range(H14)");
QString line1 = locationString.replace("\n"," ");
range->setProperty("Value",line1);
delete range;
// 실제 파일1개라도 _reportCH2 가능함..
QString tempImagePath = imageList->first();
if(_reportCH1 == false)
{
tempImagePath = imageList->last();
}
// 엑셀 문서에서의 영역
QRect imageRect(50,350,390,290);
// 실제 이미지 비율 확인하여 영역 지정
QImage ci = QImage(tempImagePath);
QRect destRect = QRectFRound(QRectAspectFitRect(QSize(ci.width(),ci.height()),imageRect));
// 오피스 2010 경로를 처리하지 않으면 1004 out of range error!!
tempImagePath = tempImagePath.replace("/","\\");
// AddPicture 에서 automation 관련 process 에러 발생, paste 로 처리해야하나?
// -> addPicture 에서 발생하는 picture 를 해지하면 해결됨
// https://github.com/joonhwan/study/blob/master/qt/QtMoreActiveX/main.cpp
QAxObject * shapes = sheet->querySubObject("Shapes");
QAxObject *picture = shapes->querySubObject("AddPicture( QString&, bool, bool, double, double, double, double)",tempImagePath,true,true,destRect.left(),destRect.top(),destRect.width(),destRect.height());
delete picture;
delete shapes;
QFile::remove(tempImagePath);
workbook->dynamicCall("SaveAs (const QString&)", destPath);
bSuccess = true;
delete sheet;
} // sheet
delete sheets;
}
workbook->dynamicCall("Close()");
delete workbook;
}
delete workbooks;
excel->dynamicCall("Quit()");
delete excel;
if(bSuccess)
{
QDesktopServices::openUrl(QUrl(destPath.prepend( "file:///" )));
}
QApplication::restoreOverrideCursor();
setEnabled(true);
}
void WindowMain::onPrintFile()
{
if (!RMPlayer::instance()->playerF()->isLoaded())
{
noPlayFileMessage();
return;
}
_reqestCaptureFor = REQUEST_CAPTURE_FOR_PRINT;
if(RMPlayer::instance()->requestVideoCapture())
{
setEnabled(false);
}
else if (!RMPlayer::instance()->playerF()->isLoaded())
{
noPlayFileMessage();
}
}
void WindowMain::deleteFiles(QList<QString>* files)
{
foreach(QString file, *files)
{
if(QFile::exists(file) == true)
{
QFile::remove(file);
}
}
}
void WindowMain::saveCaptureFile(QList<QString>* list)
{
QString frontName;
#if !(SINGLE_CH_VIEWER)
QString rearName;
#endif
QString documentPath = "";
QStringList documentList = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
if(documentList.count() > 0)
{
documentPath = documentList.first();
}
do
{
// QFileDialog::DontUseNativeDialog
QString filter = "JPEG file (*.jpg)";
QString path = QFileDialog::getSaveFileName(this,
FM_WSTR(L"다른 이름으로 저장"),
documentPath,
"JPEG file (*.jpg)",
&filter,
QFileDialog::DontConfirmOverwrite);
if(path.isEmpty() == true)
{
deleteFiles(list);
return;
}
QFileInfo fileInfo(path);
#if (SINGLE_CH_VIEWER)
frontName = fileInfo.absoluteDir().path() + PATH_COMPONENT + fileInfo.baseName() + "-CH1.jpg";
if(QFile::exists(frontName))
{
QMessageBox msgBox(QMessageBox::Warning,
"TB4000",
FM_WSTR(L"파일이 이미 존재합니다.\n덮어쓰시겠습니까?"),
QMessageBox::Yes | QMessageBox::No,
this);
msgBox.setWindowFlags(Qt::WindowTitleHint | Qt::Dialog | Qt::CustomizeWindowHint);
msgBox.setButtonText(QMessageBox::Yes, FM_WSTR(L""));
msgBox.setButtonText(QMessageBox::No, FM_WSTR(L"아니오"));
if (QMessageBox::Yes == msgBox.exec())
{
if( QFile::exists(frontName))
{
QFile::remove(frontName);
}
}
}
#else // SINGLE_CH_VIEWER
QString suffix = RMPlayer::instance()->isSwapped() ? "-CH2.jpg" : "-CH1.jpg";
frontName = fileInfo.absoluteDir().path() + PATH_COMPONENT + fileInfo.baseName() + suffix;
suffix = RMPlayer::instance()->isSwapped() ? "-CH1.jpg" : "-CH2.jpg";
rearName = fileInfo.absoluteDir().path() + PATH_COMPONENT + fileInfo.baseName() + suffix;
if(QFile::exists(frontName) || QFile::exists(rearName))
{
QMessageBox msgBox(QMessageBox::Warning,
"TB4000",
FM_WSTR(L"파일이 이미 존재합니다.\n덮어쓰시겠습니까?"),
QMessageBox::Yes | QMessageBox::No,
this);
msgBox.setWindowFlags(Qt::WindowTitleHint | Qt::Dialog | Qt::CustomizeWindowHint);
msgBox.setButtonText(QMessageBox::Yes, FM_WSTR(L""));
msgBox.setButtonText(QMessageBox::No, FM_WSTR(L"아니오"));
if (QMessageBox::Yes == msgBox.exec())
{
if( QFile::exists(frontName))
{
QFile::remove(frontName);
}
if( QFile::exists(rearName))
{
QFile::remove(rearName);
}
}
}
#endif // SINGLE_CH_VIEWER
}
#if !(SINGLE_CH_VIEWER)
while(QFile::exists(frontName) || QFile::exists(rearName)); {
QFile::rename(list->first(),frontName);
QFile::rename(list->last(),rearName);
}
#else // SINGLE_CH_VIEWER
while(QFile::exists(frontName)); {
QFile::rename(list->first(),frontName);
}
#endif // SINGLE_CH_VIEWER
}
void WindowMain::printCaptureFile(QList<QString>* list)
{
QPrinter printer;
printer.setDocName("DRS");
QPrintDialog *dlg = new QPrintDialog(&printer,this);
if(dlg != NULL && printer.isValid() && dlg->exec() == QDialog::Accepted)
{
// TODO Qt 5.5 버전에서는 XPS 선택하고 파일 취소하면 내부에서 에러발생함.
QPainter painter(&printer);
int offset = painter.device()->width() * 0.05;
int w = painter.device()->width() - (offset * 2);
int h = (painter.device()->height() - (offset * 2)) / list->size();
int count = 0;
foreach(QString file,*list)
{
QRect area = QRect(offset,(h * count) + offset,w,h);
//qDebug() << "file" << file << " w:" << w << " h:" << h < " area w:" << area.width() << " area h:" << area.height();
QImage img(file);
QRectF drawAreaF = QRectAspectFitRect(img.size(),area);
QRect drawArea = QRectFRound(drawAreaF);
// const QRect &r
// painter.drawImage(drawArea,img.scaled(drawArea.size(),Qt::KeepAspectRatio));
painter.drawImage(drawArea,img);
count++;
}
painter.end();
}
foreach(QString fileName,*list)
{
QFile file (fileName);
file.remove();
}
dlg->close();
delete dlg;
}
void WindowMain::onReportFileCH1()
{
_reportCH1 = true;
onReportFile();
}
void WindowMain::onReportFileCH2()
{
_reportCH1 = false;
onReportFile();
}
void WindowMain::onReportFileCHAuto()
{
if (!RMPlayer::instance()->playerF()->isLoaded())
{
noPlayFileMessage();
return;
}
#if (SINGLE_CH_VIEWER)
onReportFileCH1();
#else // SINGLE_CH_VIEWER
bool isCH1 = !bSubFullScreen;
//isCH1 = player->getSwaped() ? !isCH1 : isCH1;
if(isCH1)
{
onReportFileCH1();
}
else
{
onReportFileCH2();
}
#endif // SINGLE_CH_VIEWER
}
void WindowMain::onReportFile()
{
_reqestCaptureFor = REQUEST_CAPTURE_FOR_REPORT;
if(RMPlayer::instance()->requestVideoCapture())
{
setEnabled(false);
}
else if (!RMPlayer::instance()->playerF()->isLoaded())
{
noPlayFileMessage();
}
}
void WindowMain::onReportMenu()
{
RMPlayer* player = RMPlayer::instance();
if (!player->playerF()->isLoaded())
{
captureMenu->clear();
noPlayFileMessage();
}
else
{
if(!captureMenu->isEmpty())
{
captureMenu->clear();
}
QAction *saveFileAction = new QAction(FM_WSTR(L"파일로..."), captureMenu);
connect(saveFileAction, SIGNAL(triggered()),this,SLOT(onSaveFile()));
captureMenu->addAction(saveFileAction);
QAction *printAction = new QAction(FM_WSTR(L"프린터로..."), captureMenu);
connect(printAction, SIGNAL(triggered()),this,SLOT(onPrintFile()));
captureMenu->addAction(printAction);
if(player->playerF()->isLoaded() == true) // true
{
if(isFullScreen()) // 전체화면의 경우 채널 선택 없음
{
QAction *reportAction = new QAction(FM_WSTR(L"보고서 작성..."), captureMenu);
#if (SINGLE_CH_VIEWER)
bool isCH1 = true;
#else // SINGLE_CH_VIEWER
bool isCH1 = !bSubFullScreen;
#endif // SINGLE_CH_VIEWER
//isCH1 = player->getSwaped() ? !isCH1 : isCH1;
if(isCH1)
{
connect(reportAction, SIGNAL(triggered()),this,SLOT(onReportFileCH1()));
}
else
{
connect(reportAction, SIGNAL(triggered()),this,SLOT(onReportFileCH2()));
}
captureMenu->addAction(reportAction);
}
else // 채널 선택해서 처리
{
QAction *reportActionCH1 = new QAction(FM_WSTR(L"1번 채널 보고서 작성 "), captureMenu);
connect(reportActionCH1, SIGNAL(triggered()),this,SLOT(onReportFileCH1()));
captureMenu->addAction(reportActionCH1);
// swaped 처리되었으 경우 2CH 보고서 존재, 가끔씩 표시 안되는 문제 있다고 함.
// TBA 타입은 항상 2채널
#if !(SINGLE_CH_VIEWER)
bool check2CH = player->playerR()->isLoaded();
if (check2CH)
{
QAction *reportActionCH2 = new QAction(FM_WSTR(L"2번 채널 보고서 작성"), captureMenu);
connect(reportActionCH2, SIGNAL(triggered()),this,SLOT(onReportFileCH2()));
captureMenu->addAction(reportActionCH2);
}
#endif // #if (SINGLE_CH_VIEWER)
}
}
}
if(captureMenu->actions().size() > 0) {
QPushButton* a = qobject_cast<QPushButton*>(sender());
captureMenu->exec(a->mapToGlobal(a->pos()));
}
}
void WindowMain::onPassword()
{
while(true)
{
Qt::WindowFlags flag = windowFlags();
flag &= ~Qt::WindowContextHelpButtonHint;
flag &= ~Qt::WindowMinimizeButtonHint;
flag &= ~Qt::WindowMaximizeButtonHint;
QInputDialog dialog(this,flag); //
dialog.setTextValue(RMApp::password());
dialog.setWindowTitle(FM_WSTR(L"비밀번호 설정"));
dialog.setInputMode(QInputDialog::TextInput);
dialog.setLabelText(FM_WSTR(L"비밀번호를 입력하여 주십시오."));
dialog.setTextEchoMode(QLineEdit::Password);
dialog.setOkButtonText(FM_WSTR(L"확인"));
dialog.setCancelButtonText(FM_WSTR(L"취소"));
_inputDialog = &dialog;
//connect(&dialog,SIGNAL(textValueChanged(QString)),this,SLOT(onTextValueChange(QString)));
dialog.exec();
QString message = FM_WSTR(L"비밀번호를 입력하여 주십시오.");
if(dialog.result() == QDialog::Accepted)
{
_inputDialog = NULL;
if(dialog.textValue().length() >= 8)
{
FAV::AVPlayer::setPassword(dialog.textValue().toLatin1().data()); // "123456789#"
bool bSuccess = RMApp::setPassword(dialog.textValue());
#if (USER_LOGER)
if(RMApp::userLog) {
QString bw = RMApp::password().toUtf8().toBase64();
RMApp::instance()->appendLog("INFO","SET PASSWORD(" + bw + ")" + (bSuccess ? " SUCCESS.." : " FAIL..") );
}
#endif // USER_LOGER
break;
}
message = FM_WSTR(L"비밀 번호는 8자리 이상으로 입력하여 주시기 바랍니다.");
}
// 취소할 경우
else
{
_inputDialog = NULL;
if (RMApp::password().length() < 1)
{
QApplication::closeAllWindows();
QApplication::quit();
}
break;
}
QMessageBox msgBox(QMessageBox::Warning,
FM_WSTR(L"비밀번호 설정"),
message,
QMessageBox::Ok,
this);
msgBox.setButtonText(QMessageBox::Ok, FM_WSTR(L"확인"));
msgBox.exec();
}
}
#endif // RM_MODEL_TYPE_TB4000
void WindowMain::onPlayEvent(PLAY_EVENT e,RMVideoItem* i)
{
#if !(USE_FFMPEG_PW)
Q_UNUSED(e)
#endif // USE_FFMPEG_PW
Q_UNUSED(i)
#if (USE_FFMPEG_PW)
if(e == PLAY_WRONG_PASSWD) {
// 뷰어 실행중 메시지로 파일 전달 시 뷰어 메인 윈도우 disabled 되어 있음
QApplication::restoreOverrideCursor();
// 0:OK
// -1:File open fail
// -2:“TBEN” tag가 없는 경우
// -3:Password error
// -5:File read error
// -6:moov tag not found
// -7:Memory alloc fail
int vr = (int)i;
QString emsg = (vr == -3) ? FMS::txt("password_wrong") : FMS::txt("invalid_media");
#if (USER_LOGER)
if(RMApp::instance()->userLog) {
RMApp::instance()->appendLog("ERROR","tb_verify_media(" + QString::number(vr) + ")");
}
#endif
// FMS::txt("password_wrong")
QMessageBox::warning(this,FMS::txt("warning"),emsg,QMessageBox::Ok,QMessageBox::NoButton);
setEnabled(true);
if(vr == -1) {
#if (!PLAYER_ONLY_LIBRARY_MODE)
onPassword(); // 패스워드창 표시?
#endif // !PLAYER_ONLY_LIBRARY_MODE
}
//showMessage();
} else if (e == PLAY_INVALID_MEDIA) {
QMessageBox::warning(this,FMS::txt("warning"),FMS::txt("invalid_media"),QMessageBox::Ok,QMessageBox::NoButton);
} else if (e == PLAY_OTHER_ERROR) {
QMessageBox::warning(this,FMS::txt("warning"),RMPlayer::instance()->lastError,QMessageBox::Ok,QMessageBox::NoButton);
}
// 파일로 재생
else if (e == PLAY_DID_PLAYED && !isEnabled()) {
setEnabled(true);
QApplication::restoreOverrideCursor();
}
#endif // #if (USE_FFMPEG_PW)
}
#if (FILE_LOAD_MESSAGE) // 파일열기 메시지 전송
bool WindowMain::nativeEvent(const QByteArray & eventType, void * message, long * result)
{
Q_UNUSED(eventType);
MSG *msg = (MSG*)message;
// msg->message == WM_COPYDATA
if( msg->message == WM_COPYDATA ) {
// extract the string from lParam
COPYDATASTRUCT * data = (COPYDATASTRUCT *) msg->lParam;
QString playFile = QString::fromLocal8Bit((char*)data->lpData,data->cbData);
RMVideoItem* item = RMVideoFileList::instance()->itemWithPath(playFile);
if(item == NULL) {
RMApp::currentRoot = playFile;
openWithFile();
} else { // 이미 로딩된 파일일 경우 바로 재생
// 그냥 (현재 파일이 1시간 리스트에 포함되지 않을 경우) 상세 리스트로 전환
if(RMVideoFileList::instance()->get1HourList()) {
RMVideoFileList::instance()->set1HourList(false,true,item);
_frameRight->frameList->onTypeChanged();
}
if(item != NULL) {
RMVideoFileList::instance()->playItem(item);
}
}
//qInfo() << "LOADED::" << str << __FUNCTION__;
// emit eventData(QString::fromAscii((const char *)data->lpData, data->cbData));
// keep the event from qt
*result = 0;
return true;
}
// give the event to qt
return false;
}
#endif // #if (FILE_LOAD_MESSAGE) // 파일열기 메시지 전송
#endif