/* 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 "pictureswidget.h" #include "picfilesmodel.h" #include "mappingtreewidget.h" #include "smtreeitem.h" #include "helper.h" #include "hoverwindow.h" #include "mappingtreemodel.h" #include "delegates.h" #include "smglobals.h" PicturesWidget::PicturesWidget(QWidget *parent) : QWidget(parent), mWindowTitleBase(tr("Picture archive")), mPicViewerA(0) { //setup gui QSplitter *splitter = new QSplitter; mMappingTree = new MappingTreeWidget; mPictureView = new PictureView; mPictureView->setItemDelegateForColumn(PicFilesModel::Size, new SizeDelegate(this)); connect(mMappingTree, SIGNAL(mappingChanged(int)), mPictureView, SLOT(mappingChanged(int))); //change window title when mapping selection changes connect(mMappingTree, SIGNAL(mappingChanged(int)), this, SLOT(constructWindowTitle())); connect(mPictureView, SIGNAL(editPicsMappings()), this, SLOT(editMappings())); connect(mPictureView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(showInPicViewer(QModelIndex))); connect(this, SIGNAL(editMappingsDone()), mPictureView, SLOT(refresh())); splitter->addWidget(mMappingTree); splitter->addWidget(mPictureView); splitter->setStretchFactor(0, 1); splitter->setStretchFactor(1, 3); //misc mEditDialog = new MappingEditDialog(this); mPicViewer = SmGlobals::instance()->pictureViewer(); mPictureView->setPV(mPicViewer); //put it all togehter QHBoxLayout *mainLayout = new QHBoxLayout; mainLayout->addWidget(splitter); setLayout(mainLayout); } void PicturesWidget::showPicViewer(bool toggled){ mPicViewer->setVisible(toggled); } void PicturesWidget::writeSettings(){ QSettings s; MappingData selected = mMappingTree->selectedItem(); if(selected.isValid()){ QStringList v; for(int i = 0; i< selected.parents.count(); ++i){ v << QString::number(selected.parents.at(i)); } s.setValue("ui/selectedmapping", v.join(",")); } mPictureView->writeHeaderConfig(); } void PicturesWidget::readSettings(){ QSettings s; QStringList ps = s.value("ui/selectedmapping").toString().split(","); QList path; for(int i = 0; i < ps.count(); ++i){ path << ps.at(i).toInt(); } mPictureView->readHeaderConfig(); } void PicturesWidget::editMappings(){ QModelIndexList selectedFids = mPictureView->selectionModel()->selectedRows(PicFilesModel::Id); QList fileIds; foreach(QModelIndex idx, selectedFids){ fileIds << idx.data().toInt(); } QList mappings = mPictureView->filesModel()->mappingDataFromFiles(fileIds); mEditDialog->editWidget()->setMappings(mappings); int retval = mEditDialog->exec(); if(retval == QDialog::Accepted){ QList selMappings = mEditDialog->editWidget()->model()->columnValues(MappingTreeResultModel::MappingId); if(selMappings.isEmpty()){ QMessageBox::critical(this, tr("Error"), tr("No mappings selected! Cowardly bailing out.")); return; } QModelIndexList selectedFids = mPictureView->selectionModel()->selectedRows(PicFilesModel::Id); QList fileIds; foreach(QModelIndex idx, selectedFids){ fileIds << idx.data().toInt(); } mPictureView->filesModel()->changeMappings(fileIds, selMappings); } emit editMappingsDone(); } void PicturesWidget::constructWindowTitle(){ QString windowTitle = mWindowTitleBase; MappingData selected = mMappingTree->selectedItem(); if(!selected.path.isEmpty()){ windowTitle = QString("%1 - [%2]").arg(mWindowTitleBase).arg(selected.path.join("/")); mPictureView->setHoverWinVisible(false); } emit needWindowTitleChange(windowTitle); } void PicturesWidget::showInPicViewer(const QModelIndex &idx){ QModelIndex real = mPictureView->proxy()->mapToSource(idx); if(!real.isValid()){ return; } PicData pData = mPictureView->filesModel()->dataList(real); mPicViewer->setShowInfoItem(true); mPicViewer->setShowMappingItem(true); mPicViewer->setShowMarkItem(false); mPicViewer->setFile(pData); mPictureView->setPVAll(); if(mPicViewerA){ mPicViewerA->setChecked(true); } } PictureView::PictureView(QWidget *parent) : SmTreeView("ui/picheaderpos", parent) { //setup models mModel = static_cast(SmGlobals::instance()->model("PicFiles")); mProxy = new QSortFilterProxyModel(this); mProxy->setSourceModel(mModel); setModel(mProxy); connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectedFilesChanged())); mMappingTreeModel = static_cast(SmGlobals::instance()->model("MappingTree")); //read settings QSettings s; QByteArray pvHeader = s.value("ui/pvheader").toByteArray(); mCursorOffset = s.value("ui/cursoroffset").toInt(); if(!pvHeader.isEmpty()){ header()->restoreState(pvHeader); } //hover window mHoverWin = new HoverWindow(this); //misc settings setSortingEnabled(true); setAttribute(Qt::WA_Hover); setSelectionMode(QAbstractItemView::ExtendedSelection); setAlternatingRowColors(true); setColumnHidden(1, true); setColumnHidden(4, true); } void PictureView::mappingChanged(int pMapId){ mModel->setMapping(pMapId); qApp->setOverrideCursor(Qt::WaitCursor); mModel->populate(); for(int i = 0; i < PicFilesModel::NumFields; ++i){ resizeColumnToContents(i); } qApp->restoreOverrideCursor(); } void PictureView::deletePics(){ QModelIndexList sel = selectionModel()->selectedRows(); if(sel.isEmpty()){ return; } QString msg = QString(tr("Really delete %1 pics from archive?")).arg(sel.count()); int retval = QMessageBox::question(this, tr("Question"), msg, QMessageBox::Yes | QMessageBox::No); if(retval == QMessageBox::No){ return; } QList > files; foreach(QModelIndex i, sel){ files << qMakePair(i.data(PicFilesModel::IdRole).toInt(), i.data(PicFilesModel::FullPathRole).toString()); } mModel->removeFiles(files); } void PictureView::refresh(){ mModel->populate(); } void PictureView::setPVData(int replace){ QModelIndexList sel = selectionModel()->selectedRows(); PicDataList pics; foreach(QModelIndex i, sel){ QModelIndex real = mProxy->mapToSource(i); pics << mModel->dataList(real); } mPV->addFiles(pics, replace); } void PictureView::setPVAll(){ PicDataList data = mModel->allFiles(); mPV->addFiles(data, true); } void PictureView::setHoverWinVisible(bool visible) const { mHoverWin->setVisible(visible); } void PictureView::hideEvent(QHideEvent *){ QByteArray pvHeader = header()->saveState(); QSettings s; s.setValue("ui/pvheader", pvHeader); } bool PictureView::event(QEvent *e){ if(e->type() == QEvent::Leave){ mHoverWin->setVisible(false); return SmTreeView::event(e); } QHoverEvent *hEvent = static_cast(e); if(!hEvent){ return SmTreeView::event(e); } QPoint hotSpot(hEvent->pos().x(), hEvent->pos().y() + mCursorOffset); QModelIndex curIdx = indexAt(hotSpot); if(e->type() == QEvent::HoverEnter || e->type() == QEvent::HoverMove){ if(!curIdx.isValid() || curIdx.column() != PicFilesModel::FileName){ mHoverWin->setVisible(false); mCurHover = QModelIndex(); return true; } } if(e->type() == QEvent::HoverEnter){ mCurHover = curIdx; QPixmap pm; pm.load(mCurHover.data(PicFilesModel::FullPathRole).toString()); mHoverWin->setPixmap(pm); mHoverWin->setPos(); mHoverWin->setCaption(mCurHover.data().toString()); mHoverWin->setVisible(true); return true; } if(e->type() == QEvent::HoverMove){ if(curIdx != mCurHover){ mCurHover = curIdx; QPixmap pm; pm.load(mCurHover.data(PicFilesModel::FullPathRole).toString()); mHoverWin->setPixmap(pm); mHoverWin->setPos(); mHoverWin->setVisible(true); mHoverWin->setCaption(mCurHover.data().toString()); return true; } } return SmTreeView::event(e); } void PictureView::contextMenuEvent(QContextMenuEvent *e){ QMenu ctxMenu; for(int i = 0; i < actions().count(); ++i){ if(actions().at(i)->text() == "Refresh"){ ctxMenu.addSeparator(); } ctxMenu.addAction(actions().at(i)); } ctxMenu.exec(e->globalPos()); } void PictureView::selectedFilesChanged(){ QModelIndexList sel = selectionModel()->selectedRows(); if(sel.isEmpty()){ return; } QList fileIds; qint64 selSize = 0; foreach(QModelIndex i, sel){ fileIds << i.data(PicFilesModel::IdRole); selSize += i.data(PicFilesModel::SizeRole).toInt(); } emit numSelected(sel.size()); emit selectedSize(selSize); }