#include "fm_thumbnail_dialog.h" //#include "fm_thumbnail.h" #if (RM_MODEL == RM_MODEL_TYPE_TB4000) #include #include #include "../data/rm_video_list.h" #include "../data/rm_video_item_2ch.h" #include "../core/rm_math.h" #include "fm_button.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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> FMThumbnailDialog::_thumbnails = QList>(); QList FMThumbnailDialog::_items = QList(); #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("*.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 res = QList(); // 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 loaded = QtConcurrent::run(this,&thumbnail_cache::_load,path,wh); cache[path] = loaded; emit thumbnailLoaded(index); return _dummy; } #endif // #if (GENERATE_THUMBNAIL)