diff options
-rw-r--r-- | actormodel.cpp | 117 | ||||
-rw-r--r-- | actormodel.h | 37 | ||||
-rw-r--r-- | actorwidget.cpp | 64 | ||||
-rw-r--r-- | actorwidget.h | 42 | ||||
-rw-r--r-- | configurationdialog.cpp | 12 | ||||
-rw-r--r-- | configurationdialog.h | 1 | ||||
-rw-r--r-- | filepropertiesdialog.cpp | 99 | ||||
-rw-r--r-- | filepropertiesdialog.h | 36 | ||||
-rw-r--r-- | filestreemodel.cpp | 76 | ||||
-rw-r--r-- | filestreemodel.h | 4 | ||||
-rw-r--r-- | filestreewidget.cpp | 33 | ||||
-rw-r--r-- | filestreewidget.h | 1 | ||||
-rw-r--r-- | helper.cpp | 17 | ||||
-rw-r--r-- | helper.h | 1 | ||||
-rw-r--r-- | moviepropertiesdialog.cpp | 214 | ||||
-rw-r--r-- | moviepropertiesdialog.h | 45 | ||||
-rw-r--r-- | shemov.cpp | 6 | ||||
-rw-r--r-- | shemov.h | 1 | ||||
-rw-r--r-- | shemov.pro | 16 | ||||
-rw-r--r-- | smtreeitem.cpp | 12 | ||||
-rw-r--r-- | smtreeitem.h | 1 |
21 files changed, 306 insertions, 529 deletions
diff --git a/actormodel.cpp b/actormodel.cpp deleted file mode 100644 index 14edcf8..0000000 --- a/actormodel.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - 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 <QIcon> - -#include "actormodel.h" - -ActorModel::ActorModel() {}; - -QModelIndex ActorModel::index(int row, int column, const QModelIndex &) const { - if((column != 0) || (row >= mItems.size()) || row < 0){ - return QModelIndex(); - } - return createIndex(row, 0, 0); -} - -QModelIndex ActorModel::index(const QVariant &item) const { - if(item == QVariant()){ - return QModelIndex(); - } - QString sItem = item.toString(); - for(int i = 0; i < mItems.size(); ++i){ - if(mItems.at(i) == sItem){ - return createIndex(i, 0, 0); - } - } - return QModelIndex(); -} - -int ActorModel::rowCount(const QModelIndex &) const { - return mItems.size(); -} - -QVariant ActorModel::data(const QModelIndex &index, int role) const { - if(!index.isValid() || (index.column() > 0) || (index.row() > mItems.size())){ - return QVariant(); - } - switch (role) { - case Qt::DisplayRole: - return mItems.at(index.row()); - break; - case Qt::DecorationRole: - return QIcon(":/dildo.png"); - break; - } - return QVariant(); -} - -bool ActorModel::insertRows(int row, int count, const QModelIndex &){ - beginInsertRows(QModelIndex(), row, row + count - 1); - for(int i = row; i < (row + count); ++i){ - mItems.insert(i, QString()); - } - endInsertRows(); - return true; -} - -bool ActorModel::removeRows(int row, int count, const QModelIndex &){ - if((row > mItems.size()) || ((row + count) > mItems.size())){ - return false; - } - beginRemoveRows(QModelIndex(), row, row + (count - 1)); - for(int i = row; i < (row + count); ++i){ - mItems.removeAt(i); - } - endRemoveRows(); - return true; -} - -bool ActorModel::setData(const QModelIndex &idx, const QVariant &data, int role){ - if(!idx.isValid() || (idx.column() != 0) || (role != Qt::EditRole)){ - return false; - } - mItems[idx.row()] = data.toString(); - qSort(mItems); - dataChanged(index(0, 0), index((mItems.size() - 1), 0)); - return true; -} - -bool ActorModel::addItem(const QVariant &data){ - if(mItems.contains(data.toString())){ - return false; - } - bool success = false; - if(insertRows(0, 1, QModelIndex())){ - QModelIndex idx = index(0, 0); - if(idx.isValid()){ - success = setData(idx, data, Qt::EditRole); - } - } - return success; -} - -bool ActorModel::removeItem(const QVariant &data){ - QModelIndex idx = index(data); - if(!idx.isValid()){ - return false; - } - bool retval = removeRows(idx.row(), 1, QModelIndex()); - if(retval){ - int lidx = mItems.indexOf(data.toString()); - if(lidx != -1){ - mItems.removeAt(lidx); - } - } - return retval; -} - -void ActorModel::clear() { - removeRows(0, mItems.size(), QModelIndex()); - mItems.clear(); -} - diff --git a/actormodel.h b/actormodel.h deleted file mode 100644 index 9f15423..0000000 --- a/actormodel.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - 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. -*/ - -#ifndef ACTORMODEL_H -#define ACTORMODEL_H - -#include <QAbstractItemModel> -#include <QList> - -class ActorModel : public QAbstractItemModel { - public: - ActorModel(); - ~ActorModel() {}; - QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const; - QModelIndex index(const QVariant &item) const; - QModelIndex parent(const QModelIndex &) const { return QModelIndex(); }; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &) const { return 1; }; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - bool insertRows(int row, int count, const QModelIndex &parent); - bool removeRows(int row, int count, const QModelIndex &parent); - bool setData(const QModelIndex &idx, const QVariant &data, int role = Qt::EditRole); - bool addItem(const QVariant &data); - bool removeItem(const QVariant &data); - void clear(); - const QList<QString> items() const { return mItems; }; - - private: - QList<QString> mItems; -}; - -#endif - diff --git a/actorwidget.cpp b/actorwidget.cpp deleted file mode 100644 index 2a98dfd..0000000 --- a/actorwidget.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - 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 <QVBoxLayout> -#include <QHBoxLayout> -#include <QPushButton> -#include <QTreeView> -#include <QLabel> - -#include "actorwidget.h" -#include "actormodel.h" - -ActorWidget::ActorWidget(QWidget *parent) : QWidget(parent) { - QVBoxLayout *mainLayout = new QVBoxLayout; - - QLabel *l1 = new QLabel(tr("Actors")); - - mModel = new ActorModel; - mView = new QTreeView; - mView->setModel(mModel); - mView->setRootIsDecorated(false); - mView->setSelectionMode(QAbstractItemView::ExtendedSelection); - mView->setHeaderHidden(true); - - QHBoxLayout *buttonLayout = new QHBoxLayout; - mRemoveActor = new QPushButton(tr("&Remove selected")); - connect(mRemoveActor, SIGNAL(clicked()), this, SLOT(removeActor())); - mClearAll = new QPushButton(tr("Remove &all")); - connect(mClearAll, SIGNAL(clicked()), this, SLOT(clear())); - buttonLayout->addStretch(); - buttonLayout->addWidget(mClearAll); - buttonLayout->addWidget(mRemoveActor); - - mainLayout->addWidget(l1); - mainLayout->addWidget(mView); - mainLayout->addLayout(buttonLayout); - mainLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(mainLayout); -} - -const QStringList ActorWidget::actors(){ - return mModel->items(); -} - -void ActorWidget::addActor(const QString &actor) { - mModel->addItem(actor); -} - -void ActorWidget::clear() { - mModel->clear(); -} - -void ActorWidget::removeActor() { - QModelIndexList idxs = mView->selectionModel()->selectedRows(); - foreach(QModelIndex idx, idxs){ - mModel->removeItem(idx.data()); - } -} - diff --git a/actorwidget.h b/actorwidget.h deleted file mode 100644 index 864d300..0000000 --- a/actorwidget.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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. -*/ - -#ifndef ACTORWIDGET_H -#define ACTORWIDGET_H - -#include <QWidget> -#include <QMap> - -class QPushButton; -class QHBoxLayout; -class QTreeView; -class ActorModel; - -class ActorWidget : public QWidget { - Q_OBJECT - Q_PROPERTY(QStringList actors READ actors()); - public: - ActorWidget(QWidget *parent = 0); - ~ActorWidget() {}; - const QStringList actors(); - - public slots: - void addActor(const QString &actor); - void clear(); - - private slots: - void removeActor(); - - private: - QPushButton *mRemoveActor; - QPushButton *mClearAll; - QTreeView *mView; - ActorModel *mModel; -}; - -#endif - diff --git a/configurationdialog.cpp b/configurationdialog.cpp index f453700..6d6899c 100644 --- a/configurationdialog.cpp +++ b/configurationdialog.cpp @@ -18,6 +18,7 @@ #include <QApplication> #include <QSettings> #include <QRegExp> +#include <QFileInfo> #include "configurationdialog.h" #include "programconfigurator.h" @@ -52,6 +53,11 @@ ConfigurationDialog::ConfigurationDialog(QWidget *parent, Qt::WindowFlags f) : Q mBurnDir->setCompleter(fsCompleter); miscGrid->addWidget(miscl3, 2, 0); miscGrid->addWidget(mBurnDir, 2, 1); + QLabel *miscl4 = new QLabel(tr("Path to ffprobe")); + mFfProbePath = new QLineEdit; + mFfProbePath->setCompleter(fsCompleter); + miscGrid->addWidget(miscl4, 3, 0); + miscGrid->addWidget(mFfProbePath, 3, 1); mTab->addTab(miscWidget, tr("Misc. settings")); // movie viewer @@ -124,6 +130,7 @@ void ConfigurationDialog::readSettings(){ } mArchiveDir->setText(s.value("paths/archivedir").toString()); mBurnDir->setText(s.value("paths/burn").toString()); + mFfProbePath->setText(s.value("paths/ffprobe").toString()); //read database mDatabaseHost->setText(s.value("database/hostname").toString()); @@ -140,6 +147,11 @@ void ConfigurationDialog::writeSettings(){ s.setValue("ui/folderIcon", mIconForFolder->currentText()); s.setValue("paths/archivedir", mArchiveDir->text()); s.setValue("paths/burn", mBurnDir->text()); + QString ffprobe = mFfProbePath->text(); + QFileInfo ffProbeInfo(ffprobe); + if(ffProbeInfo.exists() && ffProbeInfo.isExecutable()){ + s.setValue("paths/ffprobe", ffprobe); + } //write database s.setValue("database/hostname", mDatabaseHost->text()); diff --git a/configurationdialog.h b/configurationdialog.h index 1575f41..da04c7c 100644 --- a/configurationdialog.h +++ b/configurationdialog.h @@ -38,6 +38,7 @@ class ConfigurationDialog : public QDialog { ProgramConfigurator *mPicConfig; QLineEdit *mArchiveDir; QLineEdit *mBurnDir; + QLineEdit *mFfProbePath; QLineEdit *mDatabaseHost; QLineEdit *mDatabaseName; QLineEdit *mDatabaseUsername; diff --git a/filepropertiesdialog.cpp b/filepropertiesdialog.cpp new file mode 100644 index 0000000..969eac4 --- /dev/null +++ b/filepropertiesdialog.cpp @@ -0,0 +1,99 @@ +/* + 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 <QVBoxLayout> +#include <QHBoxLayout> +#include <QLabel> +#include <QTreeView> +#include <QPushButton> + +#include "filepropertiesdialog.h" +#include "smtreemodel.h" +#include "smtreeitem.h" +#include "helper.h" + +FilePropertiesDialog::FilePropertiesDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f){ + //main layout + QVBoxLayout *mainLayout = new QVBoxLayout; + + //description + mDescriptionLabel = new QLabel(tr("Properties for [none]")); + mainLayout->addWidget(mDescriptionLabel); + + //the view + model + mModel = new SmTreeModel((QStringList() << QString() << QString()), this); + mView = new QTreeView; + mView->setHeaderHidden(true); + mView->setEditTriggers(QAbstractItemView::NoEditTriggers); + mView->setModel(mModel); + mainLayout->addWidget(mView); + + //ok button + QHBoxLayout *buttonLayout = new QHBoxLayout; + mClose = new QPushButton(tr("Close")); + connect(mClose, SIGNAL(clicked()), this, SLOT(accept())); + buttonLayout->setAlignment(Qt::AlignCenter); + buttonLayout->addWidget(mClose); + mainLayout->addLayout(buttonLayout); + + setLayout(mainLayout); + setMinimumWidth(450); +} + +void FilePropertiesDialog::setFileName(const QString &fileName){ + QString text = QString(tr("Properties for %1")).arg(fileName); + mDescriptionLabel->setText(text); + setWindowTitle(text); +} + +void FilePropertiesDialog::setStreamData(const QList<QMap<QString, QString> > &streamData){ + SmTreeItem *root = new SmTreeItem(2); + for(int i = 0; i < streamData.size(); ++i){ + QList<QVariant> titleData; + QString title = QString(tr("Stream %1")).arg(QString::number(i)); + titleData << title << QVariant(); + SmTreeItem *titleItem = new SmTreeItem(titleData, root); + root->appendChild(titleItem); + QMap<QString, QString>::const_iterator it = streamData.at(i).constBegin(); + while(it != streamData.at(i).constEnd()){ + QList<QVariant> itemData; + if(it.key() == "duration" && it.value() != "N/A"){ + qint64 duration = it.value().toFloat(); + itemData << it.key() << Helper::durationFromSecs(duration); + }else{ + itemData << it.key() << it.value(); + } + SmTreeItem *item = new SmTreeItem(itemData, titleItem); + titleItem->appendChild(item); + ++it; + } + } + mModel->setRoot(root); + mView->expandAll(); + mView->resizeColumnToContents(0); + mView->resizeColumnToContents(1); +} + +void FilePropertiesDialog::addData(const QString &caption, const QMap<QString, QString> &data){ + SmTreeItem *root = new SmTreeItem(*mModel->root()); + QList<QVariant> titleData; + titleData << caption << QVariant(); + SmTreeItem *titleItem = new SmTreeItem(titleData, root); + root->appendChild(titleItem); + QMap<QString, QString>::const_iterator it = data.constBegin(); + while(it != data.constEnd()){ + QList<QVariant> itemData; + itemData << it.key() << it.value(); + SmTreeItem *item = new SmTreeItem(itemData, titleItem); + titleItem->appendChild(item); + ++it; + } + mModel->setRoot(root); + mView->expandAll(); + mView->resizeColumnToContents(0); + mView->resizeColumnToContents(1); +} diff --git a/filepropertiesdialog.h b/filepropertiesdialog.h new file mode 100644 index 0000000..a4f5da0 --- /dev/null +++ b/filepropertiesdialog.h @@ -0,0 +1,36 @@ +/* + 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. +*/ + +#ifndef FILEPROPERTIESDIALOG_H +#define FILEPROPERTIESDIALOG_H + +#include <QDialog> +#include <QList> +#include <QMap> + +class QPushButton; +class QTreeView; +class QLabel; +class SmTreeModel; + +class FilePropertiesDialog : public QDialog +{ + Q_OBJECT + public: + explicit FilePropertiesDialog(QWidget *parent = 0, Qt::WindowFlags f = 0); + void setFileName(const QString &fileName); + void setStreamData(const QList<QMap<QString, QString> > &streamData); + void addData(const QString &caption, const QMap<QString, QString> &data); + + private: + QTreeView *mView; + QPushButton *mClose; + QLabel *mDescriptionLabel; + SmTreeModel *mModel; +}; + +#endif // FILEPROPERTIESDIALOG_H diff --git a/filestreemodel.cpp b/filestreemodel.cpp index 1f224fd..9c17084 100644 --- a/filestreemodel.cpp +++ b/filestreemodel.cpp @@ -10,6 +10,9 @@ #include <QIcon> #include <QFileInfo> #include <QFile> +#include <QSettings> +#include <QProcess> +#include <QImage> #include "filestreemodel.h" #include "smtreeitem.h" @@ -235,6 +238,79 @@ QHash<QString, QString> FilesTreeModel::filesBySeriesPartId(int seriesPartId){ return retval; } +QList<QMap<QString, QString> > FilesTreeModel::streamInfo(const QModelIndex &idx){ + QList<QMap<QString, QString> > retval; + if(!idx.isValid()){ + return retval; + } + QSettings s; + QString ffProbe = s.value("paths/ffprobe").toString(); + QString fullPath = idx.data(FullPathRole).toString(); + QStringList args; + args << "-show_streams" << fullPath; + QProcess ffproc; + ffproc.start(ffProbe, args); + if(!ffproc.waitForStarted()){ + return retval; + } + ffproc.waitForFinished(); + QByteArray ffData = ffproc.readAllStandardOutput(); + QList<QByteArray> lines = ffData.split('\n'); + QMap<QString, QString> current; + foreach(QString l, lines){ + if(l.startsWith("[STREAM]")){ + continue; + } + if(l.startsWith("[/STREAM]")){ + retval << current; + current.clear(); + continue; + } + QStringList parts = l.split('='); + if(parts.size() == 2){ + current.insert(parts.at(0), parts.at(1)); + } + } + return retval; +} + +QMap<QString, QString> FilesTreeModel::pictureInfo(const QModelIndex &idx){ + QMap<QString, QString> retval; + if(!idx.isValid()){ + return retval; + } + QString fullPath = idx.data(FullPathRole).toString(); + QImage img(fullPath); + if(img.isNull()){ + return retval; + } + retval.insert("Width", QString::number(img.width())); + retval.insert("Height", QString::number(img.height())); + retval.insert("Colors", QString::number(img.colorCount())); + retval.insert("Color depth", QString::number(img.depth())); + retval.insert("Byte count", QString::number(img.byteCount())); + retval.insert("Bytes per line", QString::number(img.bytesPerLine())); + retval.insert("Alpha channel", img.hasAlphaChannel() ? tr("yes") : tr("no")); + retval.insert("Gray scale", img.isGrayscale() ? tr("yes") : tr("no")); + return retval; +} + +QMap<QString, QString> FilesTreeModel::pictureMetaInfo(const QModelIndex &idx){ + QMap<QString, QString> retval; + if(!idx.isValid()){ + return retval; + } + QString fullPath = idx.data(FullPathRole).toString(); + QImage img(fullPath); + if(img.isNull()){ + return retval; + } + foreach(QString v, img.textKeys()){ + retval.insert(v, img.text(v)); + } + return retval; +} + bool FilesTreeModel::addFile(const QString &fullPath, int type, int quality, int filePart, int seriesPartId, int dvd){ QFileInfo fi(fullPath); qint64 size = fi.size(); diff --git a/filestreemodel.h b/filestreemodel.h index 2408e35..bea1d5c 100644 --- a/filestreemodel.h +++ b/filestreemodel.h @@ -11,6 +11,7 @@ #include <QSqlDatabase> #include <QList> #include <QHash> +#include <QMap> #include "smtreemodel.h" @@ -37,6 +38,9 @@ class FilesTreeModel : public SmTreeModel { bool setData(const QModelIndex &index, const QVariant &value, int role); Qt::ItemFlags flags(const QModelIndex &index) const; QHash<QString, QString> filesBySeriesPartId(int seriesPartId); + QList<QMap<QString, QString> > streamInfo(const QModelIndex &idx); + QMap<QString, QString> pictureInfo(const QModelIndex &idx); + QMap<QString, QString> pictureMetaInfo(const QModelIndex &idx); //file manipulation bool addFile(const QString &fullPath, int type, int quality, int filePart, int seriesPartId, int dvd = -1); diff --git a/filestreewidget.cpp b/filestreewidget.cpp index a348ac4..3161e57 100644 --- a/filestreewidget.cpp +++ b/filestreewidget.cpp @@ -28,6 +28,7 @@ #include "seriestreemodel.h" #include "helper.h" #include "pictureviewer.h" +#include "filepropertiesdialog.h" FilesTreeWidget::FilesTreeWidget(QWidget *parent) : QWidget(parent), mSelectedSize(0){ //the view @@ -158,6 +159,38 @@ void FilesTreeWidget::moveToDirectory(){ } } +void FilesTreeWidget::fileProperties(){ + QModelIndexList selected = mView->selectionModel()->selectedRows(); + if(selected.isEmpty()){ + return; + } + QModelIndex real = mProxy->mapToSource(selected.at(0)); + if(real.isValid()){ + int dvd = real.data(FilesTreeModel::DvdNoRole).toInt(); + if(dvd != -1){ + QMessageBox::critical(this, tr("Error"), tr("File is not available!")); + return; + } + QString fullPath = real.data(FilesTreeModel::FullPathRole).toString(); + QString mimeType = Helper::mimeType(fullPath); + FilePropertiesDialog dlg(this); + dlg.setFileName(real.data(FilesTreeModel::FileNameRole).toString()); + if(mimeType.startsWith("video")){ + QList<QMap<QString, QString> > fileData = mModel->streamInfo(real); + dlg.setStreamData(fileData); + }else if(mimeType.startsWith("image")){ + QMap<QString, QString> imageData = mModel->pictureInfo(real); + dlg.addData("Image data", imageData); + QMap<QString, QString> textData = mModel->pictureMetaInfo(real); + if(!textData.isEmpty()){ + dlg.addData("Meta data", textData); + } + } + dlg.exec(); + } + +} + void FilesTreeWidget::fileSelectionChanged(const QModelIndex ¤t, const QModelIndex &previous){ Q_UNUSED(previous); int seriesPartId = current.data(FilesTreeModel::SeriesPartIdRole).toInt(); diff --git a/filestreewidget.h b/filestreewidget.h index c11431b..4afa20a 100644 --- a/filestreewidget.h +++ b/filestreewidget.h @@ -34,6 +34,7 @@ class FilesTreeWidget : public QWidget { void setDvdNo(); void removeFiles(); void moveToDirectory(); + void fileProperties(); private slots: void fileSelectionChanged(const QModelIndex ¤t, const QModelIndex &previous); @@ -15,6 +15,8 @@ #include <QSettings> #include <QDir> +#include <stdio.h> + #include "helper.h" namespace Helper { @@ -147,6 +149,21 @@ namespace Helper { return qMakePair(programData.value("path").toString(), programData.value("args").toStringList()); } + QString durationFromSecs(qint64 secs){ + int minutes = secs / 60; + int hours = 0; + int seconds = 0; + if(minutes > 60){ + hours = minutes / 60; + minutes -= hours * 60; + } + seconds = secs - hours * 60 * 60 - minutes * 60; + seconds = (seconds > 60) ? 59 : seconds; + QByteArray retval(10, '\0'); + ::snprintf(retval.data(), 9, "%.2d:%.2d:%.2d", hours, minutes, seconds); + return retval; + } + bool StringListContains::operator()(const QString s, const QString &part) const { return s.contains(part); } @@ -23,6 +23,7 @@ namespace Helper { bool removeFromArchive(const QString &filename, const QString &md5); const QString createArchivePath(const QString &path, const QString &md5, bool withMd5 = false); QPair<QString, QStringList> programData(const QString &prefix, const QString &preferred = QString()); + QString durationFromSecs(qint64 secs); class StringListContains : public std::binary_function<QString, QString, bool> { public: bool operator()(const QString s, const QString &part) const; diff --git a/moviepropertiesdialog.cpp b/moviepropertiesdialog.cpp deleted file mode 100644 index 843c447..0000000 --- a/moviepropertiesdialog.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - 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 <QHBoxLayout> -#include <QVBoxLayout> -#include <QGraphicsView> -#include <QGraphicsScene> -#include <QPushButton> -#include <QLabel> -#include <QSqlQuery> -#include <QFileInfo> -#include <QFont> -#include <QApplication> -#include <QGridLayout> -#include <QLocale> -#include <QGraphicsTextItem> -#include <QGraphicsPixmapItem> -#include <QPixmap> -#include <QTreeView> - -#include "moviepropertiesdialog.h" -#include "actormodel.h" -#include "helper.h" - -MoviePropertiesDialog::MoviePropertiesDialog(int movid, QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f), mId(movid), mIndex(-1){ - //gather data - covers(); - QSqlQuery q1; - q1.prepare("SELECT ttitle, tfilename, cmd5sum, bisize, genre.tgenrename, iquality, idvd FROM movies, genre WHERE movies.igenreid = genre.igenreid AND movies.imovid = :id"); - q1.bindValue(":id", mId); - q1.exec(); - QString title, filename, md5, genre; - quint64 size(0); - qint32 quality, dvd; - quality = dvd = 0; - q1.exec(); - while(q1.next()){ - title = q1.value(0).toString(); - filename = q1.value(1).toString(); - md5 = q1.value(2).toString(); - genre = q1.value(4).toString(); - size = q1.value(3).toLongLong(); - quality = q1.value(5).toInt(); - dvd = q1.value(6).toInt(); - } - //QStringList actors; - mActorModel = new ActorModel; - QSqlQuery q2; - q2.prepare("SELECT tactorname FROM actor, movieactormap WHERE movieactormap.iactorid = actor.iactorid AND movieactormap.imovid = :id"); - q2.bindValue(":id", mId); - q2.exec(); - while(q2.next()){ - //actors << q2.value(0).toString(); - mActorModel->addItem(q2.value(0)); - } - //layout - QVBoxLayout *mainLayout = new QVBoxLayout; - mView = new QGraphicsView; - mScene = new QGraphicsScene(this); - mView->setScene(mScene); - mainLayout->addWidget(mView); - - //cover buttons - QHBoxLayout *buttonPicLayout = new QHBoxLayout; - mPrev = new QPushButton(tr("Previous")); - connect(mPrev, SIGNAL(clicked()), this, SLOT(previousCover())); - mNext = new QPushButton(tr("Next")); - connect(mNext, SIGNAL(clicked()), this, SLOT(nextCover())); - buttonPicLayout->addWidget(mPrev); - buttonPicLayout->addStretch(); - buttonPicLayout->addWidget(mNext); - mainLayout->addLayout(buttonPicLayout); - - //actors - mActors = new QTreeView; - mActors->setRootIsDecorated(false); - mActors->setHeaderHidden(true); - mActors->setModel(mActorModel); - - //properties - QGridLayout *propertiesGrid = new QGridLayout; - QFont font = qApp->font(); - font.setWeight(QFont::Bold); - QLabel *l1 = new QLabel("Genre"); - l1->setFont(font); - QLabel *l2 = new QLabel(genre); - propertiesGrid->addWidget(l1, 0, 0); - propertiesGrid->addWidget(l2, 0, 1); - QLabel *l3 = new QLabel(tr("Title")); - l3->setFont(font); - QLabel *l4 = new QLabel(title); - propertiesGrid->addWidget(l3, 1, 0); - propertiesGrid->addWidget(l4, 1, 1); - QLabel *l5 = new QLabel(tr("Filename")); - l5->setFont(font); - QLabel *l6 = new QLabel(filename); - propertiesGrid->addWidget(l5, 2, 0); - propertiesGrid->addWidget(l6, 2, 1); - QLabel *l7 = new QLabel(tr("MD5")); - l7->setFont(font); - QLabel *l8 = new QLabel(md5); - propertiesGrid->addWidget(l7, 3, 0); - propertiesGrid->addWidget(l8, 3, 1); - QLabel *l9 = new QLabel(tr("Size")); - l9->setFont(font); - QLocale l; - QLabel *l10 = new QLabel(l.toString(size)); - propertiesGrid->addWidget(l9, 4, 0); - propertiesGrid->addWidget(l10, 4, 1); - QLabel *l11 = new QLabel(tr("Quality")); - l11->setFont(font); - QLabel *l12 = new QLabel(QString::number(quality)); - propertiesGrid->addWidget(l11, 5, 0); - propertiesGrid->addWidget(l12, 5, 1); - QLabel *l13 = new QLabel(tr("Archived")); - l13->setFont(font); - QLabel *l14 = new QLabel; - if(dvd < 0){ - l14->setText(tr("No - local")); - }else{ - QString s = QString(tr("On DVD #%1")).arg(QString::number(dvd)); - l14->setText(s); - } - propertiesGrid->addWidget(l13, 6, 0); - propertiesGrid->addWidget(l14, 6, 1); - QHBoxLayout *actorsPropertiesLayout = new QHBoxLayout; - actorsPropertiesLayout->addWidget(mActors); - actorsPropertiesLayout->addLayout(propertiesGrid); - mainLayout->addLayout(actorsPropertiesLayout); - - //close button - mClose = new QPushButton(tr("Close")); - connect(mClose, SIGNAL(clicked()), this, SLOT(reject())); - QHBoxLayout *closeButtonLayout = new QHBoxLayout; - closeButtonLayout->addStretch(); - closeButtonLayout->addWidget(mClose); - closeButtonLayout->addStretch(); - mainLayout->addLayout(closeButtonLayout); - - setLayout(mainLayout); - QString winTitle = QString("%1 - Properties of %2").arg(qApp->applicationName()).arg(title); - setWindowTitle(winTitle); - - if(!mCovers.isEmpty()){ - mIndex = 0; - } - setCover(mIndex); - -} - -MoviePropertiesDialog::~MoviePropertiesDialog() { - delete mActorModel; -} - -void MoviePropertiesDialog::setCover(int index){ - mScene->clear(); - if((index < 0) || (index >= mCovers.size())){ - QGraphicsTextItem *item = new QGraphicsTextItem(tr("No covers")); - QFont font = QFont("Courier new", 30 , QFont::Bold); - item->setFont(font); - item->setDefaultTextColor(Qt::red); - item->rotate(45); - mScene->addItem(item); - item->setPos(0, 0); - mNext->setEnabled(false); - mPrev->setEnabled(false); - }else{ - QPixmap pm(mCovers.at(index)); - QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pm); - mScene->addItem(item); - item->setPos(0, 0); - } -} - -void MoviePropertiesDialog::nextCover(){ - if(mIndex < 0){ - return; - } - ++mIndex; - if(mIndex >= mCovers.size()){ - mIndex = 0; - } - setCover(mIndex); -} - -void MoviePropertiesDialog::previousCover(){ - if(mIndex < 0){ - return; - } - --mIndex; - if(mIndex < 0){ - mIndex = mCovers.size() - 1; - } - setCover(mIndex); -} - -void MoviePropertiesDialog::covers(){ - QSqlQuery q; - q.prepare("SELECT tfilename, cmd5sum FROM covers WHERE imovid = :id"); - q.bindValue(":id", mId); - q.exec(); - while(q.next()){ - QString path = Helper::createArchivePath(q.value(0).toString(), q.value(1).toString()); - QFileInfo fi(path); - if(fi.exists()){ - mCovers << path; - } - } -} - diff --git a/moviepropertiesdialog.h b/moviepropertiesdialog.h deleted file mode 100644 index 2bf0fbf..0000000 --- a/moviepropertiesdialog.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - 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. -*/ - -#ifndef MOVIEPROPERTIESDIALOG_H -#define MOVIEPROPERTIESDIALOG_H - -#include <QDialog> - -class QGraphicsView; -class QGraphicsScene; -class QPushButton; -class ActorModel; -class QTreeView; - -class MoviePropertiesDialog : public QDialog { - Q_OBJECT - public: - MoviePropertiesDialog(int movid, QWidget *parent = 0, Qt::WindowFlags f = 0); - ~MoviePropertiesDialog(); - - private slots: - void setCover(int index); - void nextCover(); - void previousCover(); - - private: - void covers(); - QGraphicsView *mView; - QGraphicsScene *mScene; - QPushButton *mNext; - QPushButton *mPrev; - QPushButton *mClose; - QTreeView *mActors; - ActorModel *mActorModel; - int mId; - int mIndex; - QStringList mCovers; -}; - -#endif - @@ -373,6 +373,8 @@ void SheMov::createActions(){ connect(mSetDvdNoA, SIGNAL(triggered()), mATree->filesWidget(), SLOT(setDvdNo())); mDeleteFilesFromTreeA = new QAction(tr("Delete file(s)..."), this); connect(mDeleteFilesFromTreeA, SIGNAL(triggered()), mATree->filesWidget(), SLOT(removeFiles())); + mFilePropertiesA = new QAction(tr("Properties..."), this); + connect(mFilePropertiesA, SIGNAL(triggered()), mATree->filesWidget(), SLOT(fileProperties())); // misc mOpenWithMapperFS = new QSignalMapper(this); @@ -496,6 +498,10 @@ void SheMov::createMenus(){ sep8->setSeparator(true); mATree->filesWidget()->filesTree()->addAction(sep8); mATree->filesWidget()->filesTree()->addAction(mDeleteFilesFromTreeA); + QAction *sep9 = new QAction(this); + sep9->setSeparator(true); + mATree->filesWidget()->filesTree()->addAction(sep9); + mATree->filesWidget()->filesTree()->addAction(mFilePropertiesA); } void SheMov::createOpenWithMenuFS(){ @@ -104,6 +104,7 @@ class SheMov : public QMainWindow { QAction *mMoveFilesA; QAction *mSetDvdNoA; QAction *mDeleteFilesFromTreeA; + QAction *mFilePropertiesA; QActionGroup *mOpenWithGroupFS; QActionGroup *mOpenWithGroupAV; @@ -17,16 +17,13 @@ SOURCES = main.cpp \ messagedialog.cpp \ configurationdialog.cpp \ textenterdialog.cpp \ - moviepropertiesdialog.cpp \ statisticsdialog.cpp \ - actorwidget.cpp \ - actormodel.cpp \ programconfigurator.cpp \ pictureviewer.cpp \ pictureviewerinfoitem.cpp \ smtreeitem.cpp \ smtreemodel.cpp \ - smglobals.cpp \ + smglobals.cpp \ archivetreeview.cpp \ seriestreewidget.cpp \ seriestreemodel.cpp \ @@ -34,7 +31,8 @@ SOURCES = main.cpp \ filestreewidget.cpp \ mappingtablemodel.cpp \ mappingtablewidget.cpp \ - newmoviewizard.cpp + newmoviewizard.cpp \ + filepropertiesdialog.cpp HEADERS = listitem.h \ filesystemdirproxy.h \ filesystemwidget.h \ @@ -46,16 +44,13 @@ HEADERS = listitem.h \ messagedialog.h \ configurationdialog.h \ textenterdialog.h \ - moviepropertiesdialog.h \ statisticsdialog.h \ - actorwidget.h \ - actormodel.h \ programconfigurator.h \ pictureviewer.h \ pictureviewerinfoitem.h \ smtreeitem.h \ smtreemodel.h \ - smglobals.h \ + smglobals.h \ archivetreeview.h \ seriestreewidget.h \ seriestreemodel.h \ @@ -63,6 +58,7 @@ HEADERS = listitem.h \ filestreewidget.h \ mappingtablemodel.h \ mappingtablewidget.h \ - newmoviewizard.h + newmoviewizard.h \ + filepropertiesdialog.h LIBS += -lmagic RESOURCES = shemov.qrc diff --git a/smtreeitem.cpp b/smtreeitem.cpp index e7f4336..a13e76a 100644 --- a/smtreeitem.cpp +++ b/smtreeitem.cpp @@ -15,6 +15,18 @@ SmTreeItem::SmTreeItem(int rows, SmTreeItem *parent) : mParent(parent){ } } +SmTreeItem::SmTreeItem(const SmTreeItem &other){ + mData = other.mData; + if(other.mParent){ + mParent = new SmTreeItem(*mParent); + }else{ + mParent = 0; + } + foreach(SmTreeItem *child, other.mChildren){ + mChildren << new SmTreeItem(*child); + } +} + SmTreeItem::~SmTreeItem(){ qDeleteAll(mChildren); } diff --git a/smtreeitem.h b/smtreeitem.h index 402d73f..591f2a4 100644 --- a/smtreeitem.h +++ b/smtreeitem.h @@ -15,6 +15,7 @@ class SmTreeItem { public: SmTreeItem(const QList<QVariant> &data, SmTreeItem *parent = 0); SmTreeItem(int rows, SmTreeItem *parent = 0); + SmTreeItem(const SmTreeItem &other); ~SmTreeItem(); void appendChild(SmTreeItem *child); SmTreeItem *child(int row) const; |