715 lines
25 KiB
C++
715 lines
25 KiB
C++
#include "fm_thumbnail_dialog.h"
|
|
//#include "fm_thumbnail.h"
|
|
#if (RM_MODEL == RM_MODEL_TYPE_TB4000)
|
|
#include <QFileInfo>
|
|
#include <QGridLayout>
|
|
#include "../data/rm_video_list.h"
|
|
#include "../data/rm_video_item_2ch.h"
|
|
#include "../core/rm_math.h"
|
|
#include "fm_button.h"
|
|
#include <QLabel>
|
|
#include <QRunnable>
|
|
#include <QScrollArea>
|
|
#include <QApplication>
|
|
|
|
#include <QResizeEvent>
|
|
#include <QStyleOption>
|
|
#include <QPainter>
|
|
#include <QPushButton>
|
|
#include <QDir>
|
|
|
|
#include <QShortcut>
|
|
|
|
#include <QTableWidget>
|
|
#include <QHeaderView>
|
|
#include <QMainWindow>
|
|
|
|
#include <QtConcurrent>
|
|
#if (DETECT_USB_CHANGE)
|
|
#include "../core/rm_usb.h"
|
|
#endif // #if (DETECT_USB_CHANGE)
|
|
|
|
int g_thumbnail_dialog_width = 814;
|
|
int g_thumbnail_dialog_height = 600;
|
|
int g_thumbnail_column_count = 4;
|
|
const int g_thumbnail_row_count = 4; // 표시 줄...
|
|
const int g_thumbnail_title_height = 22; // 타이틀 높이
|
|
const int g_thumbnail_width = 200;
|
|
const int g_thumbnail_height = (int)((double)g_thumbnail_width / 480.0 * 320.0);
|
|
const int g_thumbnail_border_size = 4; // 선택영역 처리 ETC
|
|
const bool g_dual_ch_thumbnail = true; // 전후방 모두 처리
|
|
//const int td_width = 1024;
|
|
|
|
#if (USE_DATE_FILTER)
|
|
QStringList FMThumbnailDialog::_files = QStringList();
|
|
#endif // #if (USE_DATE_FILTER)
|
|
|
|
#if (USE_1HOUR_FILTER)
|
|
QList<QPair<QString,QString>> FMThumbnailDialog::_thumbnails = QList<QPair<QString,QString>>();
|
|
QList<RMVideoItem*> FMThumbnailDialog::_items = QList<RMVideoItem*>();
|
|
#endif
|
|
|
|
QRect rectAspectFit(QRect src,int w, int h) {
|
|
int l = src.left();
|
|
int t = src.top();
|
|
if(src.width() > w )
|
|
{
|
|
l += (src.width() - w) / 2;
|
|
}
|
|
if(src.height() > h )
|
|
{
|
|
t += (src.height() - h) / 2;
|
|
}
|
|
return QRect(l,t,w,h);
|
|
}
|
|
|
|
FM_COLOR_SET g_thumb_button_colors[5] = {
|
|
0x595959, // normal
|
|
0x2e2e2e, // pressed
|
|
0x343434, // hover
|
|
0x595959, // disabled
|
|
0x3a3a3a, // checked
|
|
};
|
|
|
|
|
|
void FMThumbnailDialog::closeEvent(QCloseEvent *event)
|
|
{
|
|
|
|
|
|
/*
|
|
// accept, reject 호출되지 않음
|
|
//qInfo() << playItems << __FUNCTION__;
|
|
selectedItem = NULL;
|
|
if(FMThumbnailLoader::bRunning) {
|
|
FMThumbnailLoader::bStop = true;
|
|
event->ignore();
|
|
#if !(THUMBNAIL_ITEM_CONNECT_EACH)
|
|
for(int i=0;i<_items.size();i++) {
|
|
disconnect(_items.at(i),SIGNAL(thumnbnailsLoaded(RMVideoItem*)),this,SLOT(onThumbnailLoaded(RMVideoItem*)));
|
|
// for(int j=0;j<_items.at(i)->thumbnails.size();j++)
|
|
// {
|
|
// FMThumbnail* thumbnail = _items.at(i)->thumbnails.at(j);
|
|
// total += thumbnail->size;
|
|
// delete _items.at(i)->thumbnails.at(j);
|
|
// }
|
|
// _items.at(i)->thumbnails.clear();
|
|
}
|
|
#endif // THUMBNAIL_ITEM_CONNECT_EACH
|
|
|
|
// 강제 종료 후 연결
|
|
FMThumbnailSignal::instance()->mode = FMThumbnailSignal::MODE_REJECT; // 종료 모드
|
|
connect(FMThumbnailSignal::instance(),SIGNAL(finished()),SLOT(onProcessFinished()));
|
|
|
|
}
|
|
*/
|
|
|
|
}
|
|
#if (USE_DATE_FILTER)
|
|
FMThumbnailDialog::FMThumbnailDialog(QWidget *parent, QString folder) : QDialog(parent,Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint)
|
|
#else // USE_DATE_FILTER
|
|
FMThumbnailDialog::FMThumbnailDialog(QWidget *parent, bool bAll) : QDialog(parent,Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint)
|
|
#endif // USE_DATE_FILTER
|
|
{
|
|
_bFirst = false;
|
|
_mode = MODE_SIMPLE;
|
|
#if (USE_DATE_FILTER)
|
|
_folder = folder;
|
|
#endif
|
|
|
|
|
|
if( RMApp::instance()->pMainWindow->isFullScreen()) {
|
|
int maxWidth = RMApp::instance()->pMainWindow->width() - 360;
|
|
g_thumbnail_column_count = (maxWidth / 400) * 2;
|
|
g_thumbnail_dialog_width = (g_thumbnail_column_count * 200) + 14;
|
|
g_thumbnail_dialog_height = RMApp::instance()->pMainWindow->height() - 240;
|
|
qInfo() << g_thumbnail_dialog_width << g_thumbnail_column_count << __FUNCTION__;
|
|
} else {
|
|
g_thumbnail_dialog_width = 814;
|
|
g_thumbnail_dialog_height = 600;
|
|
g_thumbnail_column_count = 4;
|
|
}
|
|
|
|
//qInfo() << "isMaximized:" << RMApp::instance()->pMainWindow->isFullScreen() << __FUNCTION__;
|
|
|
|
setFixedWidth(g_thumbnail_dialog_width+5);
|
|
resize(g_thumbnail_dialog_width+5,g_thumbnail_dialog_height);
|
|
|
|
QVBoxLayout* l = new QVBoxLayout(this);
|
|
ZERO_LAYOUT(l);
|
|
|
|
QWidget* top = new QWidget(this);
|
|
top->setStyleSheet("background-color: #595959;");
|
|
top->setFixedHeight(40);
|
|
l->addWidget(top);
|
|
QHBoxLayout* topL = new QHBoxLayout(top);
|
|
ZERO_LAYOUT(topL);
|
|
_titleBar = new QLabel(top);
|
|
_titleBar->setAlignment(Qt::AlignCenter);
|
|
_titleBar->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
|
|
_titleBar->setStyleSheet("font-family: Malgun Gothic;font-size: 16px; color : #FFFFFF;");
|
|
topL->addWidget(_titleBar);
|
|
//_titleBar->setText(FM_WSTR(L"1시간 대표 이미지"));
|
|
|
|
_backButton = FMButton::btnType0(top,topL,"thumbnail_back",FM_WSTR(L"1시간 리스트로 돌아가기"),QSize(40,40),g_thumb_button_colors);
|
|
_backButton->setHidden(true);
|
|
//l->addWidget(_backButton);
|
|
connect(_backButton,SIGNAL(clicked()),this,SLOT(onBack()));
|
|
|
|
_tableView = new QTableWidget(this);
|
|
_tableView->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
|
|
_tableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
|
_tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
_tableView->verticalHeader()->hide();
|
|
_tableView->horizontalHeader()->hide();
|
|
|
|
_tableView->verticalHeader()->setDefaultSectionSize(g_thumbnail_height + g_thumbnail_title_height);
|
|
_tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
|
|
_tableView->horizontalHeader()->setDefaultSectionSize(g_thumbnail_width);
|
|
_tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
|
|
_tableView->setAttribute(Qt::WA_Hover);
|
|
_tableView->viewport()->setAttribute(Qt::WA_Hover);
|
|
_tableView->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
_tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
|
|
_tableView->setShowGrid(false);
|
|
_tableView->setObjectName("thumbnail");
|
|
_tableView->setStyleSheet("QTableWidget#thumbnail{background-color: #333333;}");
|
|
|
|
_tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
|
|
_delegate = new FMThumbnailDelegate(this);
|
|
//_tableView->setItemDelegate(_delegate);
|
|
|
|
l->addWidget(_tableView);
|
|
|
|
// 배경색만 바꿈..
|
|
connect(_tableView->selectionModel(),SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),this,SLOT(onSelectionChanged(const QItemSelection &, const QItemSelection &)));
|
|
|
|
createLayout(MODE_SIMPLE);
|
|
|
|
connect(thumbnail_cache::instance(),SIGNAL(thumbnailLoaded(int)),this,SLOT(onThumbnailUpdated(int)));
|
|
|
|
if(bAll) {
|
|
_mode = MODE_SUB;
|
|
}
|
|
|
|
QTimer::singleShot(100,Qt::PreciseTimer,this,SLOT(onLoadThumbnails()));
|
|
|
|
connect(_tableView, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(onDoubleClickItem(int,int)));
|
|
|
|
#if (DETECT_USB_CHANGE)
|
|
connect(RMApp::instance()->usb,SIGNAL(usbChanged(bool,QString&)),SLOT(onUSBChange(bool,QString&)));
|
|
#endif // DETECT_USB_CHANGE
|
|
|
|
}
|
|
#if (DETECT_USB_CHANGE)
|
|
void FMThumbnailDialog::onUSBChange(bool inserted, QString& drive)
|
|
{
|
|
// 제거시 리스트 삭제
|
|
if(!inserted && drive.toUpper() == _usb->_openDrive) {
|
|
reject();
|
|
}
|
|
}
|
|
#endif // #if (DETECT_USB_CHANGE)
|
|
void FMThumbnailDialog::showEvent(QShowEvent * event)
|
|
{
|
|
Q_UNUSED(event)
|
|
_tableView->setItemDelegate(_delegate);
|
|
}
|
|
void FMThumbnailDialog::onThumbnailUpdated(int index)
|
|
{
|
|
int row_start = qMax(_tableView->verticalHeader()->visualIndexAt(0), 0);
|
|
int row_end = _tableView->verticalHeader()->visualIndexAt(_tableView->verticalHeader()->height());
|
|
if(row_end == -1) {
|
|
row_end = _tableView->rowCount() - 1;
|
|
}
|
|
|
|
if (index >= row_start && index <= row_end) {
|
|
_tableView->viewport()->update();
|
|
//qInfo() << "row_start:" << row_start << index << "row_end:" << row_end << "loaded";
|
|
}
|
|
}
|
|
void FMThumbnailDialog::scrollTo()
|
|
{
|
|
if(_lastIndex.isValid()) {
|
|
_tableView->setItemDelegate(_delegate);
|
|
_tableView->scrollTo(_lastIndex); // ,QTableView::PositionAtTop
|
|
_lastIndex = QModelIndex();
|
|
}
|
|
}
|
|
void FMThumbnailDialog::onDoubleClickItem(int row, int column)
|
|
{
|
|
if(_mode == MODE_SIMPLE) {
|
|
return;
|
|
}
|
|
|
|
int idx = ((row * g_thumbnail_column_count) + column) / 2;
|
|
bool ch1 = column % 2 == 0;// ? " - [CH1]" : " - [CH2]";
|
|
selectedFile = _items.at(idx)->filePath;// ch1 ? FMThumbnailDialog::_thumbnails.at(idx).first : FMThumbnailDialog::_thumbnails.at(idx).second;
|
|
accept();
|
|
//qInfo() << "idx:" << idx << selectedFile << __FUNCTION__;
|
|
}
|
|
void FMThumbnailDialog::onSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
|
|
{
|
|
//qInfo() << __FUNCTION__;
|
|
|
|
QModelIndex index = selected.indexes().first();
|
|
int idx = ((index.row() * g_thumbnail_column_count) + index.column()) / 2;
|
|
// bool ch1 = index.column() % 2 == 0;// ? " - [CH1]" : " - [CH2]"; // 더블클릭 재생으로 이동
|
|
#if (USE_DATE_FILTER)
|
|
selectedFile = FMThumbnailDialog::_files.at((idx * 2) + (ch1 ? 0 : 1));
|
|
accept();
|
|
#endif // USE_DATE_FILTER
|
|
|
|
#if (USE_1HOUR_FILTER)
|
|
if (FMThumbnailDialog::_thumbnails.size() <= idx) {
|
|
return;
|
|
}
|
|
if(_mode == MODE_SIMPLE) {
|
|
RMVideoItem* item = FMThumbnailDialog::_items.at(idx);
|
|
_selectedDateTime = item->startTime();
|
|
_mode = MODE_SUB;
|
|
onLoadThumbnails();
|
|
_tableView->setEnabled(false);
|
|
QTimer::singleShot(300,Qt::PreciseTimer,this,SLOT(onEnableClick()));
|
|
} else {
|
|
// 더블클릭 재생으로 변경
|
|
//selectedFile = ch1 ? FMThumbnailDialog::_thumbnails.at(idx).first : FMThumbnailDialog::_thumbnails.at(idx).second;
|
|
//accept();
|
|
}
|
|
#endif
|
|
}
|
|
void FMThumbnailDialog::onEnableClick()
|
|
{
|
|
_tableView->setEnabled(true);
|
|
}
|
|
void FMThumbnailDialog::createLayout(MODE mode,RMVideoItem* selected)
|
|
{
|
|
}
|
|
#if (USE_DATE_FILTER)
|
|
void FMThumbnailDialog::loadThumbnails(QString folder)
|
|
{
|
|
thumbnail_cache::instance()->clear();
|
|
QDir dir(folder);
|
|
dir.setFilter(QDir::Dirs);
|
|
foreach (const QString& eachFolder, dir.entryList()) {
|
|
|
|
if(eachFolder == "." || eachFolder == "..")
|
|
{
|
|
continue;
|
|
}
|
|
// 폴더는 탐색
|
|
QString fullPath = QDir::cleanPath(folder + PATH_COMPONENT + eachFolder);
|
|
loadThumbnails(fullPath);
|
|
}
|
|
|
|
QDir dirFile(folder);
|
|
dirFile.setNameFilters(QList<QString>() << QString("*.JPG"));
|
|
QStringList allFiles = dirFile.entryList();
|
|
foreach (const QString& eachFile, allFiles) {
|
|
//QDateTime dateTime;
|
|
QString fullPath = QDir::cleanPath(folder + PATH_COMPONENT + eachFile);
|
|
|
|
QRegExp regexp("[0-9]{8}-[0-9]{6}_(?:REC|MOT|PSR|EVT)[0,1,2]_[0-9]{4}_[0-9]{1}.jpg"); // $
|
|
//QRegExp regexp("[0-9]{8}-[0-9]{6}_(?:REC|EVT)_[0-9]{4}_[0-9]{1}.jpg"); // $
|
|
if(regexp.exactMatch(eachFile)) {
|
|
_files.append(fullPath);
|
|
//qInfo() << eachFile << __FUNCTION__;
|
|
}
|
|
}
|
|
}
|
|
void FMThumbnailDialog::onLoadThumbnails()
|
|
{
|
|
_files.clear();
|
|
_tableView->setItemDelegate(NULL);
|
|
loadThumbnails(_folder);
|
|
|
|
qSort(_files.begin(),_files.end());
|
|
|
|
int itemCount = _files.size(); // 파일개수
|
|
int rowCount = qMax((int)ceil((double)(itemCount) / ((double)g_thumbnail_column_count)),g_thumbnail_row_count);
|
|
|
|
//_tableView->clear();
|
|
_tableView->setItemDelegate(_delegate);
|
|
_tableView->setColumnCount(g_thumbnail_column_count);
|
|
_tableView->setRowCount(rowCount); // ON LOADED 에서 처리
|
|
//qInfo() << __FUNCTION__;
|
|
}
|
|
#else // USE_DATE_FILTER
|
|
void FMThumbnailDialog::loadThumbnails()
|
|
{
|
|
FMThumbnailDialog::_items.clear();
|
|
//QList<RMVideoItem*> res = QList<RMVideoItem*>();
|
|
// 1시간 단위
|
|
if(_mode == MODE_SIMPLE) {
|
|
RMVideoFileList::instance()->load1HourList(_items);
|
|
} else {
|
|
RMVideoFileList::instance()->load1HourInList(_selectedDateTime,_items);
|
|
}
|
|
RMVideoFileList::instance()->loadThumbnails(_items,_thumbnails);
|
|
}
|
|
void FMThumbnailDialog::onLoadThumbnails()
|
|
{
|
|
// 선택해제하지 않으면 이후 이전 선택된 CELL 선택이 안됨
|
|
_tableView->selectionModel()->blockSignals(true);
|
|
_tableView->clearSelection();
|
|
_tableView->selectionModel()->blockSignals(false);
|
|
|
|
_tableView->setItemDelegate(NULL);
|
|
|
|
loadThumbnails();
|
|
|
|
int itemCount = FMThumbnailDialog::_thumbnails.size() * 2;// 0;//_files.size(); // 파일개수
|
|
int rowCount = qMax((int)ceil((double)(itemCount) / ((double)g_thumbnail_column_count)),g_thumbnail_row_count);
|
|
|
|
_tableView->setItemDelegate(_delegate);
|
|
_tableView->setColumnCount(g_thumbnail_column_count);
|
|
_tableView->setRowCount(rowCount); // ON LOADED 에서 처리
|
|
|
|
_backButton->setHidden(_mode == MODE_SIMPLE);
|
|
QString wTitle = "";
|
|
QString barTitle = "";
|
|
if(_mode == MODE_SIMPLE) {
|
|
barTitle = FM_WSTR(L"1시간 대표 이미지");
|
|
wTitle = FM_WSTR(L"1시간리스트 (이미지 클릭 시 1시간내 전체 이미지를 볼 수 있습니다.)");
|
|
} else {
|
|
wTitle = FM_WSTR(L"세부리스트 (이미지 더블 클릭 시 해당 영상이 재생됩니다.)");
|
|
|
|
QString title = _items.first()->startTime().toString("yyyy-MM-dd HH:mm:ss");
|
|
title += " ~ ";
|
|
title += _items.last()->startTime().toString("yyyy-MM-dd HH:mm:ss");
|
|
barTitle = title;
|
|
}
|
|
_titleBar->setText(barTitle + QString().sprintf(" [%d]",_items.size()));
|
|
//setWindowTitle(wTitle + QString().sprintf(" [%d]",_items.size()));
|
|
setWindowTitle(wTitle);
|
|
|
|
}
|
|
void FMThumbnailDialog::onBack() {
|
|
_mode = MODE_SIMPLE;
|
|
onLoadThumbnails();
|
|
}
|
|
#endif // USE_DATE_FILTER
|
|
|
|
|
|
FMThumbnailDelegate::FMThumbnailDelegate(QObject *parent) :
|
|
QStyledItemDelegate(parent)
|
|
{
|
|
_dialog = (FMThumbnailDialog*)parent;
|
|
}
|
|
#if (USE_DATE_FILTER)
|
|
void FMThumbnailDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
|
const QModelIndex &index) const
|
|
{
|
|
QRect rect = option.rect;
|
|
|
|
painter->fillRect(rect,QColor(0x33,0x33,0x33));
|
|
|
|
//qInfo() << rect << index << index.column() << __FUNCTION__;
|
|
painter->setRenderHint(QPainter::NonCosmeticDefaultPen); // Antialiasing
|
|
int idx = ((index.row() * g_thumbnail_column_count) + index.column()) / 2;
|
|
bool ch1 = index.column() % 2 == 0;// ? " - [CH1]" : " - [CH2]";
|
|
|
|
// _dialog->_items.size()
|
|
bool drawItem = true;
|
|
// if(_dialog->_loadedCount <= idx) {
|
|
// drawItem = false;
|
|
// }
|
|
|
|
if(drawItem) {
|
|
//RMVideoItem* item = _dialog->_items.at(idx);
|
|
//qInfo() << idx << __FUNCTION__;
|
|
QString p1 = FMThumbnailDialog::_files.at((idx * 2) + (ch1 ? 0 : 1));
|
|
|
|
//painter->fillRect(option.rect,background);
|
|
QFont font = QFont("Arial", 1);
|
|
font.setPixelSize(12);
|
|
painter->setFont(font);
|
|
QRect tr = QRect(rect.left()+1,rect.bottom()-g_thumbnail_title_height,rect.width(),g_thumbnail_title_height);
|
|
//tr.adjust(0,tr.height() - g_thumbnail_title_height,0,- g_thumbnail_title_height);
|
|
//tr.setHeight(g_thumbnail_height);
|
|
|
|
painter->fillRect(tr,QColor(0x33,0x33,0x33)); // "#333333"
|
|
|
|
QFileInfo fi(p1);
|
|
|
|
painter->setPen(QPen(QColor(0xDD,0xDD,0xDD))); // "#DDDDDD"
|
|
painter->drawText(tr, Qt::AlignCenter | Qt::AlignVCenter, fi.baseName());
|
|
//qInfo() << "TR:" << tr << "RECT:" << rect.size() << __LINE__;
|
|
|
|
|
|
|
|
//QPixmap map;
|
|
if (fi.exists()) {
|
|
|
|
QRect ir = rect;
|
|
ir.adjust(0,0,-0,-g_thumbnail_title_height);
|
|
|
|
|
|
//int iid = (index.row() * g_thumbnail_column_count) + index.column();
|
|
QPixmap pix = thumbnail_cache::instance()->thumbnail(p1,index.row(),ir.size());
|
|
if (!pix.isNull()) {
|
|
painter->drawPixmap(rectAspectFit(ir,pix.width(),pix.height()),pix);
|
|
}
|
|
|
|
// if(p1.contains("040556_PSR0_0017_") || p1.contains("040536_PSR0_0016_")) {
|
|
// qInfo() << "DRAW:" << p1 << ir << __FUNCTION__;
|
|
// }
|
|
// painter->scale(1*((double)(ir.width())/(double)(map.width())),1*((double)(ir.height())/(double)(map.height())));
|
|
// painter->scale(1,1);
|
|
}
|
|
|
|
// IR: QRect(0,166 254x143) PIX SIZE: QSize(247, 138) RECT: QRect(0,166 254x165) 930
|
|
/*
|
|
if(thumbnails.size() > 1) {
|
|
QRect ir = rect;
|
|
ir.adjust(0,0,-0,-g_thumbnail_title_height);
|
|
//ir.adjust(g_thumbnail_border_size,g_thumbnail_border_size,-g_thumbnail_border_size,-(g_thumbnail_title_height+g_thumbnail_border_size));
|
|
|
|
FMThumbnail* thumb = item->thumbnails.at(ch1 ? 0 : 1);
|
|
|
|
//qInfo() << thumb->size << __FUNCTION__;
|
|
|
|
if(thumb->size == 0) {
|
|
painter->fillRect(ir,QColor(0x11,0x11,0x11));// "#111111"
|
|
painter->drawText(ir, Qt::AlignCenter | Qt::AlignVCenter, QString::fromWCharArray(L"로딩 실패"));
|
|
}
|
|
else {
|
|
QPixmap pix;
|
|
pix.loadFromData(thumb->buffer,thumb->size);
|
|
painter->drawPixmap(ir,pix);
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
|
|
// 외곽선 그리기
|
|
QPen pen2; // c5ff5f
|
|
pen2.setJoinStyle(Qt::MiterJoin);
|
|
pen2.setColor(QColor(0xd0,0xd5,0xef)); // d0d5ef,b8bee0
|
|
pen2.setWidth(4);
|
|
painter->setPen(pen2);
|
|
|
|
QLine lines[3];
|
|
int al = rect.left()+1;
|
|
int ar = rect.right() - (ch1 ? 0 : 1);
|
|
int at = rect.top()+1;
|
|
int ab = rect.bottom();
|
|
lines[0] = !ch1 ? QLine(al,at,ar,at) : QLine(ar,at,al,at);
|
|
lines[1] = !ch1 ? QLine(ar,at,ar,ab) : QLine(al,at,al,ab);
|
|
lines[2] = !ch1 ? QLine(ar,ab,al,ab) : QLine(al,ab,ar,ab);
|
|
|
|
painter->drawLines(lines,3);
|
|
|
|
// GRID LINE
|
|
pen2.setColor(QColor(0x31,0x33,0x4A)); // fcc186,31334a
|
|
pen2.setWidth(1);
|
|
painter->setPen(pen2);
|
|
if(!ch1) {
|
|
painter->drawLine(QLine(ar+1,at,ar+1,ab));
|
|
}
|
|
//painter->drawLine(QLine(al-1,ab,ar,ab));
|
|
|
|
if(drawItem) {
|
|
bool hover = option.state & QStyle::State_MouseOver;
|
|
if (hover) {
|
|
//qInfo() << "STATE:" << QString().sprintf("%0X",(int)option.state) << __FUNCTION__;
|
|
int iw = g_thumbnail_border_size / 2;
|
|
QRect br = rect;
|
|
br.adjust(iw,iw,-iw,-iw);
|
|
QPen pen; // c5ff5f
|
|
pen.setJoinStyle(Qt::MiterJoin);
|
|
pen.setColor(QColor(0xFF,0x99,0x33)); // "#FF9933"
|
|
pen.setWidth(g_thumbnail_border_size);
|
|
painter->setPen(pen);
|
|
//QPalette palette = _checkContainerWidget->palette();
|
|
//palette.setColor(_checkContainerWidget->backgroundRole(),background);
|
|
//qInfo() << "index:" << index << "option:" << option.rect << __FUNCTION__;
|
|
painter->drawRect(br);// fillRect(r, QColor(0,0,0,10));
|
|
}
|
|
}
|
|
|
|
}
|
|
#else // #if (USE_DATE_FILTER)
|
|
void FMThumbnailDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
|
const QModelIndex &index) const
|
|
{
|
|
QRect rect = option.rect;
|
|
|
|
painter->fillRect(rect,QColor(0x33,0x33,0x33));
|
|
|
|
painter->setRenderHint(QPainter::NonCosmeticDefaultPen); // Antialiasing
|
|
int idx = ((index.row() * g_thumbnail_column_count) + index.column()) / 2;
|
|
bool ch1 = index.column() % 2 == 0;// ? " - [CH1]" : " - [CH2]";
|
|
|
|
if(FMThumbnailDialog::_thumbnails.size() <= idx) {
|
|
return;
|
|
}
|
|
|
|
bool drawItem = true;
|
|
|
|
if(drawItem) {
|
|
QString p1 = ch1 ? FMThumbnailDialog::_thumbnails.at(idx).first : FMThumbnailDialog::_thumbnails.at(idx).second;
|
|
//painter->fillRect(option.rect,background);
|
|
QFont font = QFont("Arial", 1);
|
|
font.setPixelSize(12);
|
|
painter->setFont(font);
|
|
QRect tr = QRect(rect.left()+1,rect.bottom()-g_thumbnail_title_height,rect.width(),g_thumbnail_title_height);
|
|
//tr.adjust(0,tr.height() - g_thumbnail_title_height,0,- g_thumbnail_title_height);
|
|
//tr.setHeight(g_thumbnail_height);
|
|
|
|
painter->fillRect(tr,QColor(0x33,0x33,0x33)); // "#333333"
|
|
|
|
QFileInfo fi(p1);
|
|
|
|
painter->setPen(QPen(QColor(0xDD,0xDD,0xDD))); // "#DDDDDD"
|
|
//painter->drawText(tr, Qt::AlignCenter | Qt::AlignVCenter, fi.baseName());
|
|
if(ch1) {
|
|
painter->drawText(tr, Qt::AlignRight | Qt::AlignVCenter, fi.baseName().left(8));
|
|
} else {
|
|
painter->drawText(tr, Qt::AlignLeft | Qt::AlignVCenter, fi.baseName().mid(8, 7));
|
|
}
|
|
//qInfo() << "TR:" << tr << "RECT:" << rect.size() << __LINE__;
|
|
|
|
//QPixmap map;
|
|
|
|
|
|
QRect ir = rect;
|
|
ir.adjust(0,0,-0,-g_thumbnail_title_height);
|
|
|
|
QPixmap pix;
|
|
//int iid = (index.row() * g_thumbnail_column_count) + index.column();
|
|
if (fi.exists()) {
|
|
pix = thumbnail_cache::instance()->thumbnail(p1,index.row(),ir.size());
|
|
} else {
|
|
static QPixmap no_image;
|
|
// 200,133
|
|
//qInfo() << ir.size() << __FUNCTION__;
|
|
if(no_image.isNull()) {
|
|
QPixmap ni = QPixmap(":/image/no_thumbnail.png");
|
|
if(ni.width() != ir.size().width() || ni.height() != ir.size().width()) {
|
|
no_image = ni.scaled(ir.size().width(),ir.size().width(),Qt::KeepAspectRatio,Qt::SmoothTransformation);
|
|
} else {
|
|
no_image = ni;
|
|
}
|
|
}
|
|
pix = no_image;
|
|
}
|
|
if (!pix.isNull()) {
|
|
painter->drawPixmap(rectAspectFit(ir,pix.width(),pix.height()),pix);
|
|
}
|
|
}
|
|
|
|
|
|
// 외곽선 그리기
|
|
QPen pen2; // c5ff5f
|
|
pen2.setJoinStyle(Qt::MiterJoin);
|
|
pen2.setColor(QColor(0xd0,0xd5,0xef)); // d0d5ef,b8bee0
|
|
pen2.setWidth(4);
|
|
painter->setPen(pen2);
|
|
|
|
QLine lines[3];
|
|
int al = rect.left()+1;
|
|
int ar = rect.right() - (ch1 ? 0 : 1);
|
|
int at = rect.top()+1;
|
|
int ab = rect.bottom();
|
|
lines[0] = !ch1 ? QLine(al,at,ar,at) : QLine(ar,at,al,at);
|
|
lines[1] = !ch1 ? QLine(ar,at,ar,ab) : QLine(al,at,al,ab);
|
|
lines[2] = !ch1 ? QLine(ar,ab,al,ab) : QLine(al,ab,ar,ab);
|
|
|
|
painter->drawLines(lines,3);
|
|
|
|
// GRID LINE
|
|
pen2.setColor(QColor(0x31,0x33,0x4A)); // fcc186,31334a
|
|
pen2.setWidth(1);
|
|
painter->setPen(pen2);
|
|
if(!ch1) {
|
|
painter->drawLine(QLine(ar+1,at,ar+1,ab));
|
|
}
|
|
//painter->drawLine(QLine(al-1,ab,ar,ab));
|
|
|
|
if(drawItem) {
|
|
bool hover = option.state & QStyle::State_MouseOver;
|
|
if (hover) {
|
|
//qInfo() << "STATE:" << QString().sprintf("%0X",(int)option.state) << __FUNCTION__;
|
|
int iw = g_thumbnail_border_size / 2;
|
|
QRect br = rect;
|
|
br.adjust(iw,iw,-iw,-iw-g_thumbnail_title_height);
|
|
QPen pen; // c5ff5f
|
|
pen.setJoinStyle(Qt::MiterJoin);
|
|
pen.setColor(QColor(0xFF,0x99,0x33)); // "#FF9933"
|
|
pen.setWidth(g_thumbnail_border_size);
|
|
painter->setPen(pen);
|
|
painter->drawRect(br);// fillRect(r, QColor(0,0,0,10));
|
|
}
|
|
}
|
|
|
|
}
|
|
#endif // #else // #if (USE_DATE_FILTER)
|
|
|
|
void FMThumbnailDelegate::entered(const QModelIndex &index)
|
|
{
|
|
qInfo() << index << __FUNCTION__ << __LINE__;
|
|
}
|
|
|
|
|
|
thumbnail_cache::thumbnail_cache(QObject* parent) : QObject(parent)
|
|
{
|
|
|
|
}
|
|
QPixmap thumbnail_cache::_load(QString path, const QSize& wh)
|
|
{
|
|
QPixmap map;
|
|
map.load(path);
|
|
|
|
// 1:1 이미지 CROP
|
|
if((float)map.width() / (float)map.height() < 1.1) {
|
|
|
|
|
|
// 16:9 = 1.7777
|
|
qreal wr = (qreal)wh.width() / (qreal)wh.height(); // 1.7777
|
|
//qreal tw = wr; // 0.88888
|
|
|
|
int width = map.width();
|
|
int height = map.height() / wr;
|
|
|
|
// 50% 크롭 영역 계산 (가운데 50%만 남기기)
|
|
// 시작점은 너비와 높이의 25% 지점
|
|
|
|
// 잘라낼 영역의 너비와 높이는 원본의 50%
|
|
//int cropHeight = height * 0.5;
|
|
//int cropWidth = cropHeight * wr;
|
|
int yOffset = (map.width() - height) / 2;
|
|
//int xOffset = (width - cropWidth) / 2;
|
|
|
|
//qInfo() << "wh:" << wh << "width:" << width << "height:" << height << "X:" << xOffset << cropWidth << "Y:" << yOffset << cropHeight;
|
|
map = map.copy(QRect(0, yOffset, width, height));
|
|
}
|
|
|
|
|
|
// resize
|
|
if(map.width() > wh.width() || map.height() > wh.height())
|
|
{
|
|
map = map.scaled(wh.width(),wh.height(),Qt::KeepAspectRatio,Qt::SmoothTransformation);
|
|
}
|
|
return map;
|
|
}
|
|
|
|
const QPixmap thumbnail_cache::thumbnail(const QString path,int index, const QSize& wh)
|
|
{
|
|
// 존재할 경우 리턴
|
|
if(cache.contains(path)) {
|
|
//qInfo() << "E" << path << __FUNCTION__;
|
|
return cache.value(path);
|
|
}
|
|
|
|
// 없으면 생성
|
|
QFuture<QPixmap> loaded = QtConcurrent::run(this,&thumbnail_cache::_load,path,wh);
|
|
cache[path] = loaded;
|
|
|
|
emit thumbnailLoaded(index);
|
|
return _dummy;
|
|
}
|
|
|
|
#endif // #if (GENERATE_THUMBNAIL)
|