/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pictureviewer2.h" #include "picfilesmodel.h" #include "pictureswidget.h" #include "smglobals.h" #include "mappingtreemodel.h" #include "mappingtreewidget.h" #include "smtreeitem.h" #include "configurationdialog.h" #include "newpicsdialog.h" #include "helper.h" const QString PictureViewer2::mDefaultFile = ":/picgone.png"; PictureViewer2::PictureViewer2(QWidget *parent) : QGraphicsView(parent), mCur(0), mCurPos(0), mFnItem(0), mMappingItem(0), mShowInfoItem(true), mShowMappingItem(true), mShowMarkItem(false) { setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setWindowState(Qt::WindowMaximized); mSlideDlg = new PictureViewerSlideDlg(this); connect(mSlideDlg, SIGNAL(accepted()), this, SLOT(doSlide())); //initial file list PicData initialData; for(int i = 0; i < PicFilesModel::NumFields; ++i){ initialData << QVariant(); } initialData[PicFilesModel::FullPath] = mDefaultFile; mFiles << initialData; //picture show mTimer = new QTimer(this); connect(mTimer, SIGNAL(timeout()), this, SLOT(nextSlide())); //models + dialogs mPicFilesModel = static_cast(SmGlobals::instance()->model("PicFiles")); mNewPicsDlg = new NewPicsDialog(this); //setup gui mScene = new PictureViewerGraphicsScene(this); setScene(mScene); readSettings(); setMinimumSize(QSize(800, 600)); showFile(mFiles.at(mCurPos)); } void PictureViewer2::addFiles(const PicDataList &files, bool clear){ if(files.isEmpty()){ return; } QVariant curMd5; if(!mFiles.isEmpty()){ curMd5 = mFiles.at(mCurPos).at(PicFilesModel::Md5Sum); } if(clear){ mFiles = files; }else{ foreach(const PicData &f, files){ if(!mFiles.contains(f)){ mFiles.append(f); } } } mCurPos = 0; for(int i = 0; i < mFiles.size(); ++i){ if(curMd5.isValid() && mFiles.at(i).at(PicFilesModel::Md5Sum) == curMd5){ mCurPos = i; break; } } if(mCurPos < mFiles.size()){ showFile(mFiles.at(mCurPos)); }else{ showFile(mFiles.at(0)); } } void PictureViewer2::addFiles(const QStringList &files, bool clear){ if(files.isEmpty()){ return; } PicDataList pd; foreach(QString f, files){ pd << picData(f); } addFiles(pd, clear); } void PictureViewer2::addFiles(const QString &dir, bool clear){ QFileInfo fi(dir); if(!fi.isDir()){ return; } PicDataList pd; QDir directory = QDir(dir); QFileInfoList files = directory.entryInfoList(QDir::Files, QDir::Name); foreach(QFileInfo fi, files){ pd << picData(fi.absoluteFilePath()); } addFiles(pd, clear); } void PictureViewer2::setFile(const PicData &file){ addFiles(PicDataList() << file, true); showFile(mFiles.at(mCurPos)); } void PictureViewer2::setFile(QString fullPath){ PicData pd = picData(fullPath); setFile(pd); } void PictureViewer2::setPixmap(const QPixmap &pm){ //ugly hack, I know.... QTemporaryFile tf; QDataStream stream(&tf); stream << pm; setFile(tf.fileName()); } PicData PictureViewer2::picData(const QString &fullPath, int fileId){ QFileInfo fi(fullPath); if(!fi.exists()){ return PicData(); } PicData retval; //fields defined by PicFilesModel::Fields. retval << fi.fileName() << fi.size(); retval << Helper::mimeType(fullPath); retval << fi.absoluteFilePath(); retval << fileId << QDateTime(); retval << Helper::md5Sum(fullPath); QLocale l; retval << l.toString(fi.size()); return retval; } void PictureViewer2::next(){ if(mFiles.size() == 0 || mFiles.size() == 1){ return; } if(mCurPos + 1 >= mFiles.size()){ mCurPos = 0; }else{ ++mCurPos; } mMarkA->setChecked(mMarkedFiles.contains(mFiles.at(mCurPos))); showFile(mFiles.at(mCurPos)); } void PictureViewer2::previous(){ if(mFiles.size() == 0 || mFiles.size() == 1){ return; } if(mCurPos - 1 < 0){ mCurPos = mFiles.size() - 1; }else{ --mCurPos; } mMarkA->setChecked(mMarkedFiles.contains(mFiles.at(mCurPos))); showFile(mFiles.at(mCurPos)); } void PictureViewer2::skip(int amount){ int next = mCurPos + amount; if(next >= mFiles.size()){ next = next - mFiles.size(); } if(next < 0){ next = mFiles.size() + next; } mMarkA->setChecked(mMarkedFiles.contains(mFiles.at(next))); showFile(mFiles.at(next)); mCurPos = next; } void PictureViewer2::selectPic(const QString &path){ for(int i = 0; i < mFiles.size(); ++i){ // This is the intial data from the constructor. // Don't crash trying to access FullPath if(mFiles.at(i).isEmpty()){ continue; } if(mFiles.at(i).at(PicFilesModel::FullPath) == path){ mCurPos = i; showFile(mFiles.at(mCurPos)); break; } } } void PictureViewer2::stopSlide(){ mTimer->stop(); } void PictureViewer2::startSlide(){ mTimer->start(); } void PictureViewer2::readSettings(){ QSettings s; mUseGradient = s.value("ui/pvgradient").toBool(); QVariant t = s.value("ui/pvbgcolor"); mBgColor = t.value(); mConfigInfoPos = s.value("ui/infoposition").toInt(); mInfoPos = s.value("ui/pvinfopos", QPointF(20, 20)).toPointF(); mConfigMapPos = s.value("ui/mappingposition").toInt(); mMappingPos = s.value("ui/pvmappingpos", QPointF(20, 20)).toPointF(); mScene->setSceneRect(QRectF(0, 0, width(), height())); mCursorOffset = s.value("ui/cursoroffset").toInt(); mScene->setCursorOffset(mCursorOffset); mArchiveDir = s.value("paths/archivedir").toString(); showFile(mCurPicData); int slideResult = s.value("ui/pvresult", PictureViewerSlideDlg::NoSlide).toInt(); mSlideDlg->setResult(slideResult); int days = s.value("ui/pvdays").toInt(); mSlideDlg->setDays(days); bool shuffle = s.value("ui/pvshuffle").toBool(); mSlideDlg->setShuffle(shuffle); mSlideDlg->mappingEditWidget()->loadMappings("ui/pvmappings"); } void PictureViewer2::writeSettings(){ QSettings s; if(mFnItem){ s.setValue("ui/pvinfopos", mFnItem->scenePos()); } s.setValue("ui/pvshuffle", mSlideDlg->shuffle()); s.setValue("ui/pvdays", mSlideDlg->days()); s.setValue("ui/pvresult", mSlideDlg->result()); mSlideDlg->mappingEditWidget()->saveMappings("ui/pvmappings"); } void PictureViewer2::initActions(){ foreach(QAction *a, actions()){ //never, ever forget this when casting to int //an invalid QVariant casts to a valid int! if(!a->data().isValid()){ continue; } if(a->data().toInt() == HideAction){ mHideA = a; } if(a->data().toInt() == MarkAction){ mMarkA = a; } if(a->data().toInt() == DeleteAction){ mDeleteA = a; } } } void PictureViewer2::copyCurrent(){ QString fullPath = mFiles.at(mCurPos).at(PicFilesModel::FullPath).toString(); QSettings s; QString lastDir = s.value("ui/pvlastdir", QDir::homePath()).toString(); QString destDir = QFileDialog::getExistingDirectory(this, tr("Copy picture"), lastDir); if(!destDir.isEmpty()){ QFileInfo fi(fullPath); QString copyTo = QString("%1/%2").arg(destDir).arg(fi.fileName()); bool success = QFile::copy(fullPath, copyTo); if(!success){ QString msg = QString(tr("File copy %1 -> %2 failed!")).arg(fullPath).arg(copyTo); QMessageBox::critical(this, tr("Error"), msg); }else{ s.setValue("ui/pvlastdir", destDir); } } } void PictureViewer2::deleteCurrent(){ int retval = QMessageBox::question(this, tr("Delete file"), tr("Are you sure?"), QMessageBox::No | QMessageBox::Yes); if(retval == QMessageBox::Yes){ if(mMarkedFiles.contains(mFiles.at(mCurPos))){ mMarkedFiles.removeAll(mFiles.at(mCurPos)); } QString fullPath = mFiles.at(mCurPos).at(PicFilesModel::FullPath).toString(); QFile f(fullPath); if(f.remove()){ mFiles.removeAt(mCurPos); } } } void PictureViewer2::showNewPicsDialog(){ mNewPicsDlg->clearFiles(); QStringList fileList; if(mMarkedFiles.isEmpty()){ if(!mCurrentDir.isEmpty()){ QDir d(mCurrentDir); foreach(QFileInfo fi, d.entryInfoList()){ fileList << fi.absoluteFilePath(); } }else{ return; } }else{ foreach(QVariantList v, mMarkedFiles){ fileList << v.at(PicFilesModel::FullPath).toString(); } } mNewPicsDlg->addFiles(fileList); mNewPicsDlg->setFocusToMappings(); mNewPicsDlg->exec(); } void PictureViewer2::addToNewPics(){ mNewPicsDlg->setFile(mCurPicData.at(PicFilesModel::FullPath).toString()); mNewPicsDlg->show(); } void PictureViewer2::markCurrent(){ if(!mMarkedFiles.contains(mCurPicData)){ mMarkedFiles << mCurPicData; mMarkA->setChecked(true); next(); }else{ mMarkedFiles.removeAll(mCurPicData); mMarkA->setChecked(false); } constructInfoItem(mCurPicData, QSize()); } void PictureViewer2::clearMarks(){ mMarkedFiles.clear(); constructInfoItem(mCurPicData, QSize()); } void PictureViewer2::showSlide(){ mSlideDlg->show(); } void PictureViewer2::doSlide(){ int result = mSlideDlg->result(); if(result == PictureViewerSlideDlg::NoSlide){ mTimer->stop(); return; } qApp->setOverrideCursor(Qt::BusyCursor); mNextSlideCtr = 0; if(result == PictureViewerSlideDlg::SlideAll){ mPicFilesModel->selectFromAll(); }else if (result == PictureViewerSlideDlg::SlideRecent){ int days = mSlideDlg->days(); mPicFilesModel->selectFromRecent(days); }else if (result == PictureViewerSlideDlg::SlideSelection){ MappingEditWidget *editWidget = mSlideDlg->mappingEditWidget(); QList mappingParentsIds = editWidget->model()->getMappings(editWidget->model()->root()); mPicFilesModel->selectFromSelection(mappingParentsIds); } mPicData = mPicFilesModel->allPics(); if(mSlideDlg->shuffle()){ unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); std::shuffle(mPicData.begin(), mPicData.end(), std::default_random_engine(seed)); } auto picDataOld = mPicData; mPicData.clear(); foreach(auto pd, picDataOld){ QList tmp; tmp << Helper::createArchivePath(pd.value(0).toString(), pd.value(1).toString()) << pd.value(2); mPicData << tmp; } mTotal = mPicData.count(); qApp->restoreOverrideCursor(); mTimer->start(5000); } void PictureViewer2::wheelEvent(QWheelEvent *event){ int steps = event->delta() / 8 / 15; if(steps < 0){ next(); }else{ previous(); } } void PictureViewer2::contextMenuEvent(QContextMenuEvent *e){ QMenu ctxMenu; foreach(QAction *a, actions()){ ctxMenu.addAction(a); } ctxMenu.exec(e->globalPos()); } void PictureViewer2::keyPressEvent(QKeyEvent *e){ Qt::KeyboardModifiers mod = e->modifiers(); if(mod & Qt::ControlModifier){ if(e->key() == Qt::Key_Down || e->key() == Qt::Key_Right){ skip(25); } if(e->key() == Qt::Key_Up || e->key() == Qt::Key_Left){ skip(-25); } if(e->key() == Qt::Key_Space){ if(mTimer->isActive()){ stopSlide(); }else{ startSlide(); } } return; } if(e->key() == Qt::Key_Escape){ stopSlide(); mHideA->toggle(); } if(e->key() == Qt::Key_Space){ if(mTimer->isActive()){ stopSlide(); }else{ startSlide(); } } if(e->key() == Qt::Key_M){ markCurrent(); } if((e->key() == Qt::Key_N) || (e->key() == Qt::Key_Down) || (e->key() == Qt::Key_Right)){ next(); } if((e->key() == Qt::Key_P) || (e->key() == Qt::Key_Up) || (e->key() == Qt::Key_Left)){ previous(); } if(e->key() == Qt::Key_Delete){ deleteCurrent(); next(); } if(e->key() == Qt::Key_PageDown){ skip(25); } if(e->key() == Qt::Key_PageUp){ skip(-25); } e->accept(); } void PictureViewer2::showEvent(QShowEvent *e){ mHideA->setChecked(true); QGraphicsView::showEvent(e); } void PictureViewer2::hideEvent(QHideEvent *e){ stopSlide(); mHideA->setChecked(false); QGraphicsView::hideEvent(e); } void PictureViewer2::resizeEvent(QResizeEvent *event){ QGraphicsView::resizeEvent(event); showFile(mCurPicData); } void PictureViewer2::nextSlide(){ if(mPicData.isEmpty()){ return; } if(mNextSlideCtr < mPicData.count()){ QString fullPath = mPicData.at(mNextSlideCtr).at(0).toString(); int fId = mPicData.at(mNextSlideCtr).at(1).toInt(); PicData pd = picData(fullPath, fId); setFile(pd); ++mNextSlideCtr; }else{ mNextSlideCtr = 0; QString fullPath = mPicData.at(mNextSlideCtr).at(0).toString(); int fId = mPicData.at(mNextSlideCtr).at(1).toInt(); PicData pd = picData(fullPath, fId); setFile(pd); ++mNextSlideCtr; } } void PictureViewer2::showFile(const PicData &file){ if(file.isEmpty()){ return; } mCurPicData = file; bool converted = false; QFileInfo fi(file.at(PicFilesModel::FullPath).toString()); if(!fi.exists()){ return; } QPixmap pixmap(file.at(PicFilesModel::FullPath).toString()); if(pixmap.isNull()){ if(fi.canonicalFilePath().startsWith(mArchiveDir)){ mCurPicData = Helper::convertArchivefileToPng(file); mFiles[mCurPos] = mCurPicData; if(!mCurPicData.isEmpty()){ pixmap = QPixmap(mCurPicData.at(3).toString()); converted = true; } } if(pixmap.isNull()){ pixmap = QPixmap(mDefaultFile); } } if(mUseGradient){ setGradient(pixmap); }else{ setBackgroundBrush(QBrush(mBgColor)); } if((pixmap.height() > height()) || (pixmap.width() > width())){ pixmap = pixmap.scaled(QSize(width() - 20, height() - 20), Qt::KeepAspectRatio, Qt::SmoothTransformation); } if(mCur){ mScene->removeItem(mCur); delete mCur; mCur = 0; } mScene->setSceneRect(rect()); mCur = new QGraphicsPixmapItem(pixmap); mScene->addItem(mCur); QRectF picRect = mCur->boundingRect(); picRect.moveCenter(rect().center()); mCur->setPos(picRect.topLeft()); setWindowTitle(constructWindowTitle()); if(mConfigInfoPos != ConfigurationDialog::NoDisplay && mShowInfoItem){ constructInfoItem(mCurPicData, pixmap.size(), converted); }else{ if(mFnItem){ mScene->removeItem(mFnItem); delete mFnItem; mFnItem = 0; } } if(mConfigMapPos != ConfigurationDialog::NoDisplay && mShowMappingItem){ constructMappingItem(mCurPicData); }else{ if(mMappingItem){ mScene->removeItem(mMappingItem); delete mMappingItem; mMappingItem = 0; } } } void PictureViewer2::constructInfoItem(const PicData &data, QSize picSize, bool converted){ if(mFnItem){ mInfoPos = mFnItem->scenePos(); mScene->removeItem(mFnItem); delete mFnItem; } if(!picSize.isValid()){ QPixmap pm = QPixmap(data.at(PicFilesModel::FullPath).toString()); picSize = pm.size(); } mFnItem = new PictureViewer2Item(data, mTotal, mNextSlideCtr, picSize); if(mShowMarkItem){ if(mMarkedFiles.contains(data)){ mFnItem->appendText("marked"); }else{ mFnItem->appendText("not marked"); } } if(converted){ mFnItem->appendText("converted!"); } mFnItem->setPos(getPos(mFnItem, mConfigInfoPos, mInfoPos)); mScene->addItem(mFnItem); } void PictureViewer2::constructMappingItem(const PicData &file){ SmTreeItem *mapData = mPicFilesModel->mappingTreeFromFile(file.at(PicFilesModel::Id).toInt()); QTextDocument *doc = new QTextDocument; doc->setIndentWidth(2); doc->setDocumentMargin(8); QTextCursor *cur = new QTextCursor(doc); docFromTree(mapData, cur, 0); if(mMappingItem){ mMappingPos = mMappingItem->scenePos(); mScene->removeItem(mMappingItem); delete mMappingItem; } mMappingItem = new PictureViewer2Item(doc); mMappingItem->setPos(getPos(mMappingItem, mConfigMapPos, mMappingPos)); mScene->addItem(mMappingItem); delete mapData; } void PictureViewer2::docFromTree(SmTreeItem *start, QTextCursor *cur, int indent){ if(!start){ return; } QChar bullet(0x2640); if(indent % 2){ bullet = QChar(0x2642); } for(int i = 0; i < start->childCount(); ++i){ SmTreeItem *child = start->child(i); if(!cur->atStart()){ cur->insertBlock(); } QTextBlockFormat fmt; fmt.setIndent(4 * indent); cur->setBlockFormat(fmt); QString text = QString("%1 %2").arg(bullet).arg(child->data(0).toString()); cur->insertText(text); if(child->childCount()){ docFromTree(child, cur, indent + 1); } } } void PictureViewer2::setGradient(const QPixmap &pic){ QPoint val1 = QPoint(qrand() % pic.width(), qrand() % pic.height()); QPoint val2 = QPoint(qrand() % pic.width(), qrand() % pic.height()); QImage img = pic.toImage(); QColor c1(img.pixel(val1)); QColor c2(img.pixel(val2)); QLinearGradient g(QPoint(0,0), QPoint(rect().bottomRight())); g.setColorAt(0, c1); g.setColorAt(1, c2); setBackgroundBrush(QBrush(g)); } QTextDocument *PictureViewer2::treeToString(const SmTreeItem *root) const{ QTextDocument *retval = new QTextDocument; retval->setIndentWidth(2); retval->setDocumentMargin(8); QTextCursor *cursor = new QTextCursor(retval); for(int i = 0; i < root->childCount(); ++i){ treeToStringRecursive(root->child(i), cursor, 0); QTextBlockFormat fmt; fmt.setIndent(0); cursor->insertBlock(fmt); } return retval; } void PictureViewer2::treeToStringRecursive(const SmTreeItem *parent, QTextCursor *cursor, int indent) const{ QChar bullet(0x2640); if(indent % 2){ bullet = QChar(0x2642); } cursor->insertText(QString("%1 %2").arg(bullet).arg(parent->data(0).toString())); if(parent->childCount()){ indent++; } for(int i = 0; i < parent->childCount(); ++i){ QTextBlockFormat fmt; fmt.setIndent(indent * 5); cursor->insertBlock(fmt); treeToStringRecursive(parent->child(i), cursor, indent); } } QPointF PictureViewer2::getPos(QGraphicsItem *item, int pos, const QPointF &movPos){ QSizeF curSize = size(); item->setFlags(0); if(pos == ConfigurationDialog::TopLeft){ return QPointF(5, 5); } int rightOffset = curSize.width() - 15 - item->boundingRect().width(); int bottomOffset = curSize.height() - 15 - item->boundingRect().height(); if(pos == ConfigurationDialog::TopRight){ return QPointF(rightOffset, 5); } if(pos == ConfigurationDialog::BottomLeft){ return QPointF(5, bottomOffset); } if(pos == ConfigurationDialog::BottomRigth){ return QPointF(rightOffset, bottomOffset); } if(pos == ConfigurationDialog::Moveable){ item->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable); return movPos; } return QPointF(5, 5); } QString PictureViewer2::constructWindowTitle() const { QString f; if(mCurPos < mFiles.size()){ f = mFiles.at(mCurPos).at(PicFilesModel::FileName).toString(); }else{ f = tr("Oh shit..."); } QString retval = QString(tr("PicViewer 2 - [%1]")).arg(f); return retval; } PictureViewerSlideDlg::PictureViewerSlideDlg(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f){ QGroupBox *slideGb = new QGroupBox(tr("Slide")); mSlideAll = new QRadioButton(tr("Slide all")); connect(mSlideAll, SIGNAL(toggled(bool)), this, SLOT(slideAllToggled(bool))); mRecent = new QRadioButton(tr("Slide recent")); connect(mRecent, SIGNAL(toggled(bool)), this, SLOT(recentToggled(bool))); mSelection = new QRadioButton(tr("Slide selection")); connect(mSelection, SIGNAL(toggled(bool)), this, SLOT(slideSelectionToggled(bool))); mNoSlide = new QRadioButton(tr("Stop slide")); connect(mNoSlide, SIGNAL(toggled(bool)), this, SLOT(noSlideToggled(bool))); QVBoxLayout *slideL = new QVBoxLayout; slideL->addWidget(mSlideAll); slideL->addWidget(mRecent); slideL->addWidget(mSelection); slideL->addWidget(mNoSlide); slideGb->setLayout(slideL); QGroupBox *miscGb = new QGroupBox(tr("Misc.")); mRecentDays = new QSpinBox; mRecentDays->setMinimum(1); mRecentDays->setPrefix(tr("Slide last ")); mRecentDays->setSuffix(tr(" days")); mShuffle = new QCheckBox(tr("Shuffle")); QVBoxLayout *miscL = new QVBoxLayout; miscL->addWidget(mRecentDays); miscL->addWidget(mShuffle); miscL->addStretch(); miscGb->setLayout(miscL); mMappingEditWidget = new MappingEditWidget; QGroupBox *selectionGb = new QGroupBox(tr("Selection")); QVBoxLayout *selectionL = new QVBoxLayout; selectionL->addWidget(mMappingEditWidget); selectionGb->setLayout(selectionL); mOk = new QPushButton(tr("Ok")); connect(mOk, SIGNAL(clicked()), this, SLOT(accept())); mCancel = new QPushButton(tr("Cancel")); connect(mCancel, SIGNAL(clicked()), this, SLOT(reject())); QHBoxLayout *buttonL = new QHBoxLayout; buttonL->addStretch(); buttonL->addWidget(mOk); buttonL->addWidget(mCancel); QGridLayout *mainL = new QGridLayout; mainL->addWidget(slideGb, 0, 0); mainL->addWidget(miscGb, 0, 1); mainL->addWidget(selectionGb, 1, 0, 1, 2); mainL->addLayout(buttonL, 2, 0, 1, 2); setLayout(mainL); mNoSlide->setChecked(true); } void PictureViewerSlideDlg::setResult(int result){ if(result == SlideAll){ mSlideAll->setChecked(true); }else if(result == SlideRecent){ mRecent->setChecked(true); }else if(result == SlideSelection){ mSelection->setChecked(true); }else if(result == NoSlide){ mNoSlide->setChecked(true); } } void PictureViewerSlideDlg::slideAllToggled(bool checked){ if(checked){ mRecentDays->setEnabled(false); mMappingEditWidget->setEnabled(false); mSlideResult = SlideAll; } } void PictureViewerSlideDlg::slideSelectionToggled(bool checked){ if(checked){ mRecentDays->setEnabled(false); mMappingEditWidget->setEnabled(true); mSlideResult = SlideSelection; } } void PictureViewerSlideDlg::recentToggled(bool checked){ if(checked){ mRecentDays->setEnabled(true); mMappingEditWidget->setEnabled(false); mSlideResult = SlideRecent; } } void PictureViewerSlideDlg::noSlideToggled(bool checked){ if(checked){ mRecentDays->setEnabled(false); mMappingEditWidget->setEnabled(false); mSlideResult = NoSlide; } } PictureViewer2Item::PictureViewer2Item(const PicData &data, const int numSelected, int cur, const QSize &picSize, QGraphicsItem *parent) : QGraphicsItem(parent), mDoc(0){ //prevent QStaticText from wrapping filesnames with spaces //we shouldn't allow this in the first place mTextList << data.at(PicFilesModel::FileName).toString().replace(' ', '_'); mTextList << QString("%1x%2").arg(QString::number(picSize.width())).arg(QString::number(picSize.height())); QLocale l; mTextList << QString(QObject::tr("%1 bytes")).arg(l.toString(data.at(PicFilesModel::Size).toInt())); mTextList << l.toString(data.at(PicFilesModel::Added).toDate()); mTextList << data.at(PicFilesModel::MimeType).toString(); mTextList << QString(QObject::tr("%1/%2 files")).arg(QString::number(cur + 1)).arg(QString::number(numSelected)); setZValue(1); } PictureViewer2Item::PictureViewer2Item(QTextDocument *doc, QGraphicsItem *parent) : QGraphicsItem(parent), mDoc(doc){ setZValue(1); } PictureViewer2Item::~PictureViewer2Item(){ delete mDoc; } QRectF PictureViewer2Item::boundingRect() const { QSizeF size; if(mDoc){ size = mDoc->size(); }else{ QStaticText text = QStaticText(mTextList.join("
")); size = text.size(); size += QSize(10, 10); } QRectF retval; retval.setWidth(size.width()); retval.setHeight(size.height()); return retval; } void PictureViewer2Item::appendText(const QString &text){ mTextList << text; } void PictureViewer2Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){ Q_UNUSED(option); Q_UNUSED(widget); painter->save(); painter->setRenderHint(QPainter::Antialiasing, true); painter->setRenderHint(QPainter::TextAntialiasing, true); QColor bgColor = QColor(Qt::white); bgColor.setAlpha(80); QColor fgColor = QColor(Qt::black); QBrush brush(bgColor); painter->setPen(QColor(Qt::yellow)); painter->setBrush(brush); painter->drawRoundedRect(boundingRect(), 15.0, 15.0); painter->setPen(QPen(fgColor)); if(mDoc){ mDoc->drawContents(painter); }else{ QStaticText text = QStaticText(mTextList.join("
")); painter->drawStaticText(5, 5, text); } painter->restore(); } void PictureViewerGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *e){ QGraphicsScene::mousePressEvent(e); QPointF curPos = e->scenePos(); curPos = QPointF(e->scenePos().x(), e->scenePos().y() - 16); QGraphicsItem *item = itemAt(curPos, QTransform()); if(item){ emit itemClicked(item); } }