/* 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 "archiveviewwidget.h" #include "archivefileview.h" #include "moviemodel.h" #include "listmodel.h" #include "archiveproxy.h" #include "editarchiveitemdialog.h" #include "sizedelegate.h" #include "archiveddelegate.h" #include "coverarchiveeditor.h" #include "textenterdialog.h" #include "helper.h" #include "moviepropertiesdialog.h" ArchiveViewWidget::ArchiveViewWidget(MovieModel *model, ListModel *genre, ListModel *actors, QWidget *parent) : QWidget(parent), mMovieModel(model), mGenreModel(genre), mActorsModel(actors), mSize(0){ //filter bar QHBoxLayout *filterLayout = new QHBoxLayout; QLabel *l1 = new QLabel(tr("Filter by &genre")); mGenre = new QComboBox; l1->setBuddy(mGenre); mGenre->setModel(mGenreModel); connect(mGenre, SIGNAL(activated(const QString &)), this, SLOT(setGenreFilter(const QString &))); filterLayout->addWidget(l1); filterLayout->addWidget(mGenre); QLabel *l2 = new QLabel(tr("Filter by &actor")); mActors = new QComboBox; mActors->setModel(mActorsModel); connect(mActors, SIGNAL(activated(const QString &)), this, SLOT(setActorFilter(const QString &))); l2->setBuddy(mActors); filterLayout->addWidget(l2); filterLayout->addWidget(mActors); QLabel *l3 = new QLabel(tr("Filter by &title")); mName = new QLineEdit; l3->setBuddy(mName); filterLayout->addWidget(l3); filterLayout->addWidget(mName); mFilter = new QPushButton(tr("Filter")); connect(mFilter, SIGNAL(clicked()), this, SLOT(setFilter())); connect(mName, SIGNAL(returnPressed()), this, SLOT(setFilter())); filterLayout->addWidget(mFilter); mClearFilter = new QPushButton(tr("Clear filter")); filterLayout->addWidget(mClearFilter); //treeview mFileView = new ArchiveFileView; mFileView->setItemDelegateForColumn(MovieItem::Size, new SizeDelegate(this)); mFileView->setItemDelegateForColumn(MovieItem::Dvd, new ArchivedDelegate(this)); mProxy = new ArchiveProxy(this); mProxy->setSourceModel(mMovieModel); mFileView->setModel(mProxy); mFileView->setSortingEnabled(true); mFileView->setItemsExpandable(false); mFileView->setRootIsDecorated(false); mFileView->setSelectionBehavior(QAbstractItemView::SelectRows); mFileView->setSelectionMode(QAbstractItemView::ExtendedSelection); mFileView->setColumnHidden(MovieItem::Md5Sum, true); mFileView->setColumnHidden(MovieItem::SeriesNo, true); mFileView->setColumnHidden(MovieItem::PartNo, true); connect(mClearFilter, SIGNAL(clicked()), mProxy, SLOT(clearFilter())); connect(mMovieModel, SIGNAL(moviesChanged()), mProxy, SLOT(invalidate())); //main layout QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(filterLayout); mainLayout->addWidget(mFileView); connect(mFileView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex)), this, SLOT(rowChanged(const QModelIndex &, const QModelIndex &))); connect(mFileView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(showMovie(const QModelIndex &))); connect(mFileView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(calcSize())); mWindowTitle = QString("%1 - nothing selected").arg(qApp->applicationName()); setLayout(mainLayout); } void ArchiveViewWidget::editFile(){ QModelIndex real = getSourceColumnZero(); mEditDialog->setMovie(real); mEditDialog->show(); mEditDialog->raise(); mEditDialog->activateWindow(); } void ArchiveViewWidget::editCovers(){ QModelIndex real = getSourceColumnZero(); mCoverEditDialog->setMovie(real); mCoverEditDialog->show(); mCoverEditDialog->raise(); mCoverEditDialog->activateWindow(); } void ArchiveViewWidget::addMovie(){ TextEnterDialog dlg(tr("Enter movie title"), this); dlg.exec(); if(dlg.result() == QDialog::Accepted){ QString title = dlg.text().toLower().trimmed(); QList movieData; movieData << title; for(int i = 1; i < MovieItem::NumRows; ++i){ movieData << QVariant(); } QString md5(32, '0'); movieData[MovieItem::Md5Sum] = md5; movieData[MovieItem::Genre] = mGenreModel->defaultId(); movieData[MovieItem::Dvd] = -2; movieData[MovieItem::Filename] = tr("(DVD)"); movieData[MovieItem::Size] = Q_INT64_C(4707319808); movieData[MovieItem::Quality] = 0; mMovieModel->addMovie(movieData, QList(), QList()); } } void ArchiveViewWidget::showMovie(const QModelIndex &movie){ QModelIndex real = mProxy->mapToSource(movie); if(real.data(MovieModel::DvdRole).toInt() != -1){ emit statusbarMessage(tr("Movie is not present on filesystem")); return; } QSettings s; QString playerPath = s.value("paths/movieviewer").toString(); QStringList args = s.value("paths/movieviewerargs").toStringList(); args << real.data(MovieModel::FullPathRole).toString(); QProcess::startDetached(playerPath, args); } void ArchiveViewWidget::properties(){ QModelIndex real = getSourceColumnZero(); int movid = real.data(MovieModel::IdRole).toInt(); MoviePropertiesDialog dlg(movid, this); dlg.exec(); } void ArchiveViewWidget::setFilter(){ QString filter = mName->text().toLower(); if(filter.isEmpty()){ return; } mProxy->setFilter(filter, ArchiveProxy::TitleFilter); } void ArchiveViewWidget::setGenreFilter(const QString &filter){ mProxy->setFilter(filter, ArchiveProxy::GenreFilter); } void ArchiveViewWidget::setActorFilter(const QString &filter){ mProxy->setFilter(filter, ArchiveProxy::ActorFilter); } void ArchiveViewWidget::moveBurn(){ QModelIndexList sel = fileView()->selectionModel()->selectedRows(); if(sel.isEmpty()){ return; } QSettings s; QString destBase = QString("%1/%2").arg(s.value("paths/start").toString()).arg(tr("burn")); QFileInfo dbi(destBase); if(!dbi.exists()){ QDir bd(s.value("paths/start").toString()); bool success = bd.mkdir(tr("burn")); if(!success){ QString msg = QString("Failed to create dir %1 in %2").arg(s.value("paths/start").toString()).arg(tr("burn")); emit statusbarMessage(msg); return; } }else{ if(!dbi.isDir()){ QString msg = QString("%1 exists but is not a directory").arg(destBase); emit statusbarMessage(msg); return; } } QString question = QString(tr("Really move selected files and covers to %1?")).arg(destBase); int answer = QMessageBox::question(this, tr("Question"), question, QMessageBox::Yes | QMessageBox::No); if(answer == QMessageBox::Yes){ QDir destDir(destBase); foreach(QModelIndex idx, sel){ QModelIndex real = mProxy->mapToSource(idx); QString file = real.data(MovieModel::FullPathRole).toString(); QList covers = real.data(MovieModel::CoverPathRole).toList(); QFileInfo fi(file); if(!fi.exists()){ QString msg = QString(tr("%1 does not exist on the filesystem")).arg(file); emit statusbarMessage(msg); return; } QString destDirName(real.data(MovieModel::TitleBaseRole).toString()); if(real.data(MovieModel::SeriesNoRole).toInt() != -1){ destDirName.append(QString(".%1").arg(QString::number(real.data(MovieModel::SeriesNoRole).toInt()))); } QRegExp ws("\\s+"); destDirName.replace(ws, "."); destDir.mkdir(destDirName); QString finalDestDir = QString("%1/%2").arg(destBase).arg(destDirName); QString newFn = QString("%1/%2").arg(finalDestDir).arg(fi.fileName()); QFile::rename(file, newFn); foreach(QVariant c, covers){ QFileInfo ci(c.toString()); QString newCover = QString("%1/%2").arg(finalDestDir).arg(ci.fileName()); QFile::copy(c.toString(), newCover); } } emit refreshDir(destBase); } } void ArchiveViewWidget::setDvdNo(){ int dvdno = mMovieModel->maxValue(MovieItem::Dvd).toInt(); QModelIndexList idx = fileView()->selectionModel()->selectedRows(); if(idx.isEmpty()){ return; } if(dvdno != 0){ ++dvdno; TextEnterDialog dlg(tr("Enter Dvd No."), this); dlg.setText(QString::number(dvdno)); int retval = dlg.exec(); if(retval == QDialog::Accepted){ QString noString = dlg.text(); bool success(false); int no = noString.toLongLong(&success); if(success){ foreach(QModelIndex i, idx){ QModelIndex real = mProxy->mapToSource(i); if(real.column() != MovieItem::Dvd){ real = mMovieModel->index(real.row(), MovieItem::Dvd, QModelIndex()); } mMovieModel->setDataAt(real, no); } } } } } void ArchiveViewWidget::deleteFromArchive(){ QModelIndexList selected = fileView()->selectionModel()->selectedRows(); if(selected.isEmpty()){ return; } QString question = QString(tr("Really delete %1 file(s) from archive?")).arg(QString::number(selected.count())); int retval = QMessageBox::question(this, tr("Question"), question, QMessageBox::Yes | QMessageBox::No); if(retval == QMessageBox::Yes){ foreach(QModelIndex i, selected){ QModelIndex real = mProxy->mapToSource(i); QString path = real.data(MovieModel::FullPathRole).toString(); QList covers = real.data(MovieModel::CoverPathRole).toList(); bool r = QFile::remove(path); if(r){ mMovieModel->removeMovie(real); } foreach(QVariant c, covers){ QString cpath = c.toString(); QFile::remove(cpath); } } } } void ArchiveViewWidget::rowChanged(const QModelIndex &/*current*/, const QModelIndex & /*prev*/){ QModelIndex idx = getSourceColumnZero(); mWindowTitle = QString(tr("%1 - %2")).arg(qApp->applicationName()).arg(idx.data().toString()); emit windowTitle(mWindowTitle); } void ArchiveViewWidget::calcSize(){ QModelIndexList sel = mFileView->selectionModel()->selectedRows(MovieItem::Size); mSize = 0; foreach(QModelIndex idx, sel){ mSize += idx.data().toLongLong(); } } const QModelIndex ArchiveViewWidget::getSourceColumnZero(){ QModelIndex retval; QModelIndex idx = mFileView->currentIndex(); if(idx.column() != 0){ idx = mProxy->index(idx.row(), 0); } QModelIndex real = mProxy->mapToSource(idx); if(real.column() != 0){ retval = mMovieModel->index(real.row(), 0); }else{ retval = real; } return retval; }