/* 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 "archivecontroller.h" #include "archivemodel.h" #include "archiveview.h" #include "pictureviewer2.h" #include "filepropertiesdialog.h" #include "smglobals.h" #include "helper.h" ArchiveController::ArchiveController(QObject *parent) : QObject(parent) { if(parent){ mParentWidget = qobject_cast(this->parent()); } readConfig(); } void ArchiveController::setArchiveView(ArchiveView *view){ mArchiveView = view; } void ArchiveController::setArchiveTree(ArchiveTree *atree, ArchiveProxy *aproxy){ mArchiveTree = atree; mArchiveProxy = aproxy; mArchiveSelection = mArchiveTree->selectionModel(); } void ArchiveController::setArchiveFiles(ArchiveFiles *afiles, ArchiveFilesProxy *afilesproxy){ mArchiveFiles = afiles; mArchiveFilesProxy = afilesproxy; mFileSelection = mArchiveFiles->selectionModel(); } void ArchiveController::setModels(ArchiveModel *amodel, ArchiveFilesModel *afilesmodel){ mArchiveModel = amodel; mArchiveFilesModel = afilesmodel; } void ArchiveController::setMappingModels(QStandardItemModel *actorModel, QStandardItemModel *genreModel){ mActorModel = actorModel; mGenreModel = genreModel; } void ArchiveController::init(){ connect(mArchiveSelection, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(treeSelectionChanged(QItemSelection,QItemSelection))); connect(mArchiveFiles, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(fileDoubleClicked(QModelIndex))); connect(mFileSelection, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(fileSelectionChanged(QItemSelection,QItemSelection))); } void ArchiveController::setSeriesPart(int seriesPartId){ QModelIndex res = mArchiveModel->findRecursive(seriesPartId, ArchiveModel::SeriesPartId, mArchiveModel->rootIndex()); if(res.isValid()){ mArchiveView->clearFilter(); QModelIndex real = mArchiveView->archiveProxy()->mapFromSource(res); mArchiveTree->scrollTo(real, QAbstractItemView::PositionAtCenter); mArchiveTree->selectionModel()->select(real, QItemSelectionModel::Rows | QItemSelectionModel::SelectCurrent); } } void ArchiveController::playSelectedFiles(){ QModelIndexList sel = mFileSelection->selectedRows(); QStringList files; foreach(QModelIndex i, sel){ if(i.data(ArchiveFilesModel::FileTypeRole).toInt() == FT_MOVIE){ QString fullPath = i.data(ArchiveFilesModel::FullPathRole).toString(); QFileInfo fi(fullPath); if(fi.exists()){ files << fullPath; } } } if(!files.isEmpty()){ QPair playerData = Helper::programData("movieviewer"); QStringList args = playerData.second; args << files; QProcess::startDetached(playerData.first, args); } } void ArchiveController::editQuality(){ QModelIndexList sel = mFileSelection->selectedRows(ArchiveFilesModel::Quality); if(sel.isEmpty()){ return; } bool ok; int quality = QInputDialog::getInt(mParentWidget, tr("Set Quality"), tr("Quality"), 7, 1, 10, 1, &ok); if(ok){ foreach(QModelIndex i, sel){ QModelIndex real = mArchiveFilesProxy->mapToSource(i); if(mArchiveFilesModel->isMovie(real)){ mArchiveFilesModel->setData(real, quality, ArchiveFilesModel::QualityRole); } } } } void ArchiveController::editDvdNo(){ QModelIndexList sel = mFileSelection->selectedRows(ArchiveFilesModel::DvdNo); if(sel.isEmpty()){ return; } bool ok; int dvdNo = QInputDialog::getInt(mParentWidget, tr("Set DVD no."), tr("Number (-1 for local)"), mArchiveFilesModel->nextDvd(), -1, 1024 * 1024, 1, &ok); if(ok){ foreach(QModelIndex i, sel){ QModelIndex real = mArchiveFilesProxy->mapToSource(i); if(mArchiveFilesModel->isMovie(real)){ mArchiveFilesModel->setData(real, dvdNo, ArchiveFilesModel::DvdNoRole); } } } } void ArchiveController::editFileType(){ QModelIndexList sel = mFileSelection->selectedRows(ArchiveFilesModel::FileType); if(sel.isEmpty()){ return; } bool ok; QStringList types = QStringList() << tr("Movie") << tr("Front Cover") << tr("Back Cover") << tr("General Cover"); QString item = QInputDialog::getItem(mParentWidget, tr("Set file type"), tr("Type:"), types, 0, false, &ok); if(ok && !item.isEmpty()){ int newType = 0; if(item == tr("Movie")){ newType = FT_MOVIE; }else if(item == tr("Front Cover")){ newType = FT_FRONTCOVER; }else if(item == tr("Back Cover")){ newType = FT_BACKCOVER; }else if(item == tr("General Cover")){ newType = FT_GENERALCOVER; } if(newType){ foreach(QModelIndex i, sel){ QModelIndex real = mArchiveFilesProxy->mapToSource(i); mArchiveFilesModel->setData(real, newType, ArchiveFilesModel::FileTypeRole); } mArchiveFilesModel->refresh(); mArchiveFiles->expandAll(); } } } void ArchiveController::editFileNo(){ QModelIndexList sel = mFileSelection->selectedRows(ArchiveFilesModel::FileNumber); if(sel.isEmpty()){ return; } bool ok; int fileNo = QInputDialog::getInt(mParentWidget, tr("Set DVD no."), tr("Number (-1 for none)"), -1, -1, 1024 * 1024, 1, &ok); if(ok){ foreach(QModelIndex i, sel){ QModelIndex real = mArchiveFilesProxy->mapToSource(i); if(mArchiveFilesModel->isMovie(real)){ mArchiveFilesModel->setData(real, fileNo, ArchiveFilesModel::FileNumberRole); } } } } void ArchiveController::showProperties(){ QModelIndexList sel = mFileSelection->selectedRows(ArchiveFilesModel::FullPath); if(sel.isEmpty()){ return; } QModelIndex first = sel.first(); FilePropertiesDialog dlg(first.data().toString()); dlg.exec(); } void ArchiveController::showPreview(){ QModelIndexList sel = mFileSelection->selectedRows(ArchiveFilesModel::FullPath); if(sel.isEmpty()){ return; } QString first = sel.first().data().toString(); PictureViewer2 *pv = SmGlobals::instance()->pictureViewer(); pv->setShowMappingItem(false); QFileInfo fi(first); if(!fi.exists()){ pv->setFile(); }else if(sel.first().data(ArchiveFilesModel::FileTypeRole).toInt() == FT_MOVIE){ qApp->setOverrideCursor(Qt::BusyCursor); QPixmap preview = Helper::preview(first); if(!preview.isNull()){ pv->setPixmap(preview); pv->show(); }else{ pv->setFile(); } qApp->restoreOverrideCursor(); }else{ pv->setFile(first); } pv->show(); } void ArchiveController::addActionForTree(QAction *a){ mActionsForTree << a; mArchiveTree->addAction(a); } void ArchiveController::addFiles(){ QSettings s; QString startDir = s.value("paths/coverpath").toString(); QStringList covers = QFileDialog::getOpenFileNames(mArchiveView, tr("Select covers"), startDir); if(covers.isEmpty()){ return; } QModelIndex part = mArchiveSelection->currentIndex(); if(!part.isValid()){ QMessageBox::critical(mArchiveView, tr("Error"), tr("No part selected!")); return; } mArchiveModel->addFiles(part.data(ArchiveModel::SeriesPartIdRole).toInt(), covers); mArchiveFilesModel->refresh(); mArchiveFiles->expandAll(); } void ArchiveController::readConfig(){ mActorIcon = SmGlobals::instance()->iconFor("actor"); mGenreIcon = SmGlobals::instance()->iconFor("genre"); mMetaIcon = SmGlobals::instance()->iconFor("meta"); } void ArchiveController::moveFilesToSeriespart(const QStringList &md5Sums, int newSeriesPart){ foreach(QString md5, md5Sums){ mArchiveFilesModel->updateSeriesPartForFile(md5, newSeriesPart); } mArchiveFilesModel->refresh(); } void ArchiveController::treeSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected){ Q_UNUSED(selected); Q_UNUSED(deselected); QModelIndexList sel = mapToSource(mArchiveProxy, mArchiveSelection->selectedRows()); if(sel.isEmpty()){ return; } QSet ids; foreach(QModelIndex idx, sel){ ids.unite(mArchiveModel->seriesPartIds(idx)); } mArchiveFilesModel->populate(ids); mArchiveFiles->expandToDepth(0); mArchiveView->setCurrentArchivePath(mArchiveModel->indexToPath(sel.first())); QStringList actors = mArchiveModel->actors(ids); mActorModel->clear(); foreach(QString actor, actors){ QStandardItem *newItem = new QStandardItem(mActorIcon, actor); mActorModel->appendRow(newItem); } QStringList genres = mArchiveModel->genres(ids); mGenreModel->clear(); foreach(QString genre, genres){ QStandardItem *newItem = new QStandardItem(mGenreIcon, genre); mGenreModel->appendRow(newItem); } getMetadata(ids); int nodeType = sel.first().data(ArchiveModel::TypeRole).toInt(); foreach(QAction *a, mActionsForTree){ int aData = a->data().toInt(); bool enabled = aData & nodeType; a->setEnabled(enabled); } } void ArchiveController::setMetadata(QTextEdit *metaEdit){ mMetaEdit = metaEdit; } void ArchiveController::getMetadata(QSet ids){ mMetaEdit->clear(); if(ids.isEmpty()){ return; } QString meta; if(ids.size() == 1){ QList metadata = mArchiveModel->metadataList(*ids.begin()); if(metadata.at(0).isValid()){ meta.append(""); meta.append(QString("").arg(metadata.at(ArchiveModel::ReleaseYear).toString())); meta.append(QString("").arg(metadata.at(ArchiveModel::Source).toString())); meta.append(QString("").arg(metadata.at(ArchiveModel::Subject).toString())); meta.append(QString("").arg(metadata.at(ArchiveModel::Added).toDateTime().toString())); meta.append("
Release year%1
Source%1
Subj./Name%1
Added%1
"); QString comment = metadata.at(ArchiveModel::Comment).toString(); if(comment.isEmpty()){ comment = tr("(none)"); } meta.append(QString("

Comments:

%1

").arg(comment)); meta.append(""); }else{ meta = tr("No metadata available"); } }else{ QStringList tmpH; for(int i = 0; i < ArchiveFilesModel::NumFields; ++i){ tmpH << ""; } tmpH.reserve(ArchiveFilesModel::NumFields); ArchiveFilesModel tmpFModel(tmpH, this); tmpFModel.populate(ids); quint64 totalSize = tmpFModel.totalSize(); QString sizeStr; QLocale l; if(totalSize / 1024 / 1024 / 1024 > 0){ //display GB double ts = (double)totalSize / 1024.0 / 1024.0 / 1024.0; sizeStr = QString("%1 GB").arg(l.toString(ts)); }else if(totalSize / 1024 / 1024 > 0){ //display MB double ts = (double)totalSize / 1024.0 / 1024.0; sizeStr = QString("%1 MB").arg(l.toString(ts)); }else if(totalSize == 0){ sizeStr = tr("n/a"); } meta.append(""); meta.append(QString("").arg(sizeStr)); quint64 totalDur = tmpFModel.totalDuration(); Helper::Duration dur(totalDur); meta.append(QString("").arg(dur.toString())); int moviefiles = tmpFModel.movieFilesCount(); meta.append(QString("").arg(QString::number(moviefiles))); int otherfiles = tmpFModel.otherFilesCount(); meta.append(QString("").arg(QString::number(otherfiles))); meta.append("
Total Size%1
Total Duration%1
Movie files%1
Other files%1
"); meta.append(""); } mMetaEdit->setHtml(meta); } void ArchiveController::fileSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected){ Q_UNUSED(selected); Q_UNUSED(deselected); QModelIndexList sel = mapToSource(mArchiveFilesProxy, mFileSelection->selectedRows()); if(sel.isEmpty()){ return; } qint64 size = 0; qint64 duration = 0; bool maybeMore = false; QSet seriesParts; foreach(QModelIndex i, sel){ seriesParts << i.data(ArchiveFilesModel::SeriesPartIdRole).toInt(); size += i.data(ArchiveFilesModel::SizeRole).toInt(); int type = i.data(ArchiveFilesModel::FileTypeRole).toInt(); if(type == FT_MOVIE){ int dur = i.data(ArchiveFilesModel::SizeDurRole).toInt(); duration += dur; if(dur == 0){ maybeMore = true; } } } getMetadata(seriesParts); emit sizeChanged(size); emit durationChanged(duration, maybeMore); } void ArchiveController::fileDoubleClicked(const QModelIndex &idx){ if(!idx.isValid()){ return; } int type = idx.data(ArchiveFilesModel::FileTypeRole).toInt(); if(type == FT_MOVIE){ QString fullPath = idx.data(ArchiveFilesModel::FullPathRole).toString(); QFileInfo fi(fullPath); if(!fi.exists()){ QString msg = QString(tr("%1 not available!")).arg(idx.data(ArchiveFilesModel::FilenameRole).toString()); QMessageBox::critical(mParentWidget, tr("Error"), msg); return; } QPair playerData = Helper::programData("movieviewer"); QStringList args = playerData.second; args << idx.data(ArchiveFilesModel::FullPathRole).toString(); QProcess::startDetached(playerData.first, args); return; } PictureViewer2 *pv = SmGlobals::instance()->pictureViewer(); QModelIndex parent = idx.parent(); QStringList paths; if(parent.isValid()){ int row = 0; QModelIndex child = parent.child(row, ArchiveFilesModel::FullPath); while(child.isValid()){ paths << child.data().toString(); ++row; child = parent.child(row, ArchiveFilesModel::FullPath); } } pv->setShowMarkItem(false); pv->addFiles(paths); pv->selectPic(idx.data(ArchiveFilesModel::FullPathRole).toString()); pv->show(); } QModelIndexList ArchiveController::mapToSource(const QSortFilterProxyModel *proxy, const QModelIndexList idxs) const{ QModelIndexList retval; foreach(QModelIndex idx, idxs){ retval << proxy->mapToSource(idx); } return retval; }