diff options
author | Arno <am@disconnect.de> | 2013-07-28 07:46:16 +0200 |
---|---|---|
committer | Arno <am@disconnect.de> | 2013-07-28 07:46:16 +0200 |
commit | d6b178b1fdcdac519ded25e3f253d9eeffa84053 (patch) | |
tree | ba9a03e041fa72ccde37367ef07864884f0ced7b | |
parent | 5cfaa2c755c52c2ccbdd88ea3239dafb120a179b (diff) | |
download | SheMov-d6b178b1fdcdac519ded25e3f253d9eeffa84053.tar.gz SheMov-d6b178b1fdcdac519ded25e3f253d9eeffa84053.tar.bz2 SheMov-d6b178b1fdcdac519ded25e3f253d9eeffa84053.zip |
Implement file properties dialog
Show file properties in Filemanager and Archive, if the file is
available.
Also get rid of the palette stuff in SmGlobals. Just call setPalette()
early enough and set it in SmTreeView.
-rw-r--r-- | archivecontroller.cpp | 11 | ||||
-rw-r--r-- | archivecontroller.h | 1 | ||||
-rw-r--r-- | filepropertiesdialog.cpp | 214 | ||||
-rw-r--r-- | filepropertiesdialog.h | 34 | ||||
-rw-r--r-- | fileview.cpp | 11 | ||||
-rw-r--r-- | fileview.h | 1 | ||||
-rw-r--r-- | helper.cpp | 16 | ||||
-rw-r--r-- | helper.h | 2 | ||||
-rw-r--r-- | shemov.cpp | 17 | ||||
-rw-r--r-- | shemov.h | 3 | ||||
-rw-r--r-- | smglobals.cpp | 4 | ||||
-rw-r--r-- | smglobals.h | 7 | ||||
-rw-r--r-- | smtreeview.cpp | 5 |
13 files changed, 191 insertions, 135 deletions
diff --git a/archivecontroller.cpp b/archivecontroller.cpp index d75f52f..4475166 100644 --- a/archivecontroller.cpp +++ b/archivecontroller.cpp @@ -18,6 +18,7 @@ #include "archivemodel.h" #include "archiveview.h" #include "pictureviewer2.h" +#include "filepropertiesdialog.h" #include "smglobals.h" #include "helper.h" @@ -165,6 +166,16 @@ void ArchiveController::editFileNo(){ } } +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::addActionForTree(QAction *a){ mActionsForTree << a; mArchiveTree->addAction(a); diff --git a/archivecontroller.h b/archivecontroller.h index 4f24973..2fbde4e 100644 --- a/archivecontroller.h +++ b/archivecontroller.h @@ -51,6 +51,7 @@ class ArchiveController : public QObject { void editDvdNo(); void editFileType(); void editFileNo(); + void showProperties(); void addActionForTree(QAction *a); void readConfig(); diff --git a/filepropertiesdialog.cpp b/filepropertiesdialog.cpp index a22076c..f130b0b 100644 --- a/filepropertiesdialog.cpp +++ b/filepropertiesdialog.cpp @@ -5,121 +5,137 @@ 2 of the License, or (at your option) any later version. */ -#include <QtWidgets/QHBoxLayout> -#include <QtWidgets/QLabel> -#include <QtWidgets/QPushButton> -#include <QSettings> -#include <QApplication> +#include <QPushButton> +#include <QJsonDocument> +#include <QJsonArray> +#include <QJsonObject> +#include <QLabel> +#include <QHBoxLayout> +#include <QVBoxLayout> +#include <QTabWidget> +#include <QStackedWidget> +#include <QImage> #include "filepropertiesdialog.h" -#include "seriesmetadatamodel.h" +#include "smtreemodel.h" #include "smtreeitem.h" #include "smtreeview.h" #include "helper.h" -FilePropertiesDialog::FilePropertiesDialog(/*int seriesPartId, */QWidget *parent, Qt::WindowFlags f) : SmDialog(parent, f){ - //tab - mTab = new QTabWidget; +FilePropertiesDialog::FilePropertiesDialog(const QString &file, QWidget *parent, Qt::WindowFlags f) : SmDialog(parent, f), mFile(file){ + mStack = new QStackedWidget; + mTab = new QTabWidget; + QString lText = QString(tr("<b>Properties - %1</b>")).arg(mFile); + QLabel *l = new QLabel(lText); + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addWidget(l); - //stream data widget - QVBoxLayout *streamDataLayout = new QVBoxLayout; - QWidget *streamData = new QWidget; + QWidget *formatWidget = new QWidget; + mFormatView = new SmTreeView; + mFormatModel = new SmTreeModel(QStringList() << tr("Key") << tr("Value"), this); + mFormatView->setModel(mFormatModel); + QHBoxLayout *formatLayout = new QHBoxLayout; + formatLayout->addWidget(mFormatView); + formatWidget->setLayout(formatLayout); + mTab->addTab(formatWidget, tr("Format")); - //description - mDescriptionLabel = new QLabel(tr("Properties for [none]")); - mDescriptionLabel->setAutoFillBackground(true); - mDescriptionLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); - streamDataLayout->addWidget(mDescriptionLabel); - QSettings s; - QVariant varColor = s.value("ui/alternatecolor"); - QColor labelColor = varColor.value<QColor>(); - QPalette labelPalette = mDescriptionLabel->palette(); - labelPalette.setColor(QPalette::Window, labelColor); - mDescriptionLabel->setPalette(labelPalette); + QWidget *streamWidget = new QWidget; + mStreamView = new SmTreeView; + mStreamModel = new SmTreeModel(QStringList() << tr("Key") << tr("Value"), this); + mStreamView->setModel(mStreamModel); + QHBoxLayout *streamLayout = new QHBoxLayout; + streamLayout->addWidget(mStreamView); + streamWidget->setLayout(streamLayout); + mTab->addTab(streamWidget, tr("Streams")); + mStack->addWidget(mTab); - //the view + model - mModel = new SmTreeModel((QStringList() << QString() << QString()), this); - mView = new SmTreeView; - mView->setHeaderHidden(true); - mView->setEditTriggers(QAbstractItemView::NoEditTriggers); - mView->setModel(mModel); - streamDataLayout->addWidget(mView); - streamData->setLayout(streamDataLayout); - mTab->addTab(streamData, tr("Stream data")); + QWidget *picWidget = new QWidget; + mPicView = new SmTreeView; + mPicModel = new SmTreeModel(QStringList() << tr("Key") << tr("Value"), this); + mPicView->setModel(mPicModel); + QHBoxLayout *picLayout = new QHBoxLayout; + picLayout->addWidget(mPicView); + picWidget->setLayout(picLayout); + mStack->addWidget(picWidget); - //metadata widget - mMetadata = new MetadataWidget; - mTab->addTab(mMetadata, tr("Metadata")); + mainLayout->addWidget(mStack); + mOk = new QPushButton(tr("Ok")); + connect(mOk, SIGNAL(clicked()), this, SLOT(accept())); + QHBoxLayout *buttonLayout = new QHBoxLayout; + buttonLayout->addStretch(); + buttonLayout->addWidget(mOk); + buttonLayout->addStretch(); + mainLayout->addLayout(buttonLayout); + setLayout(mainLayout); - //buttons - QHBoxLayout *buttonLayout = new QHBoxLayout; - mOk = new QPushButton(tr("Ok")); - connect(mOk, SIGNAL(clicked()), this, SLOT(accept())); - connect(mOk, SIGNAL(clicked()), mMetadata, SLOT(accept())); - mCancel = new QPushButton(tr("Cancel")); - connect(mCancel, SIGNAL(clicked()), this, SLOT(reject())); - buttonLayout->setAlignment(Qt::AlignRight); - buttonLayout->addWidget(mOk); - buttonLayout->addWidget(mCancel); + QString mimeType = Helper::mimeType(mFile); + if(mimeType.startsWith("video")){ + mStack->setCurrentIndex(0); + movieData(); + }else if(mimeType.startsWith("image")){ + mStack->setCurrentIndex(1); + pictureData(); + } +} - //main layout - QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->addWidget(mTab); - mainLayout->addLayout(buttonLayout); - setLayout(mainLayout); - setMinimumWidth(450); +void FilePropertiesDialog::movieData(){ + QJsonDocument jsDoc = Helper::streamData(mFile); + if(jsDoc.isNull()){ + return; + } + QJsonObject obj = jsDoc.object(); + SmTreeItem *formatItem = new SmTreeItem(2); + movieDataRecursive(obj.value("format"), formatItem); + mFormatModel->setRoot(formatItem); + mFormatView->expandAll(); + SmTreeItem *streamItem = new SmTreeItem(2); + QJsonArray streamA = obj.value("streams").toArray(); + for(int i = 0; i < streamA.size(); ++i){ + QString itemName = QString(tr("Stream %1 [%2]")).arg(QString::number(i + 1)).arg(streamA.at(i).toObject().value("codec_type").toString()); + SmTreeItem *item = new SmTreeItem(QList<QVariant>() << itemName << QVariant(), streamItem); + streamItem->appendChild(item); + movieDataRecursive(streamA.at(i), item); + } + mStreamModel->setRoot(streamItem); + mStreamView->expandAll(); } -void FilePropertiesDialog::setFileName(const QString &fileName){ - QString text = QString(tr("Properties for %1")).arg(fileName); - mDescriptionLabel->setText(text); - setWindowTitle(text); +void FilePropertiesDialog::movieDataRecursive(QJsonValue start, SmTreeItem *appendTo){ + QJsonObject sObject = start.toObject(); + QJsonObject::const_iterator it; + for(it = sObject.constBegin(); it != sObject.constEnd(); ++it){ + QList<QVariant> data = QList<QVariant>() << it.key() << it.value().toVariant(); + if(it.key() == "duration"){ + qint64 seconds = it.value().toString().toDouble(); + Helper::Duration dur(seconds); + data[1] = dur.toString(); + } + if(it.key() == "bit_rate"){ + qint64 br = it.value().toString().toInt() / 1000; + data[1] = QString("%1 kb/s").arg(QString::number(br)); + } + SmTreeItem *newItem = new SmTreeItem(data, appendTo); + appendTo->appendChild(newItem); + movieDataRecursive(*it, newItem); + } } -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::pictureData(){ + QImage img = QImage(mFile); + if(img.isNull()){ + return; + } + SmTreeItem *rootItem = new SmTreeItem(2); + appendItem(QList<QVariant>() << tr("width") << img.width(), rootItem); + appendItem(QList<QVariant>() << tr("height") << img.height(), rootItem); + appendItem(QList<QVariant>() << tr("depth") << img.depth(), rootItem); + appendItem(QList<QVariant>() << tr("alpha channel") << (img.hasAlphaChannel() ? tr("yes") : tr("no")), rootItem); + appendItem(QList<QVariant>() << tr("qt format") << img.format(), rootItem); + appendItem(QList<QVariant>() << tr("byte count") << img.byteCount(), rootItem); + mPicModel->setRoot(rootItem); } -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); +void FilePropertiesDialog::appendItem(const QList<QVariant> &data, SmTreeItem *parent){ + SmTreeItem *item = new SmTreeItem(data, parent); + parent->appendChild(item); } diff --git a/filepropertiesdialog.h b/filepropertiesdialog.h index ee9aa96..425f6e6 100644 --- a/filepropertiesdialog.h +++ b/filepropertiesdialog.h @@ -10,29 +10,33 @@ #include "smdialog.h" +class QPushButton; class SmTreeView; -class QLabel; -class QTabWidget; +class SmTreeItem; class SmTreeModel; -class MetadataWidget; +class QTabWidget; +class QStackedWidget; class FilePropertiesDialog : public SmDialog { Q_OBJECT public: - explicit FilePropertiesDialog(/*int seriesPartId, */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); - MetadataWidget *metaWidget() { return mMetadata; }; + explicit FilePropertiesDialog(const QString &file, QWidget *parent = 0, Qt::WindowFlags f = 0); private: - QTabWidget *mTab; - MetadataWidget *mMetadata; - SmTreeView *mView; - QPushButton *mOk; - QPushButton *mCancel; - QLabel *mDescriptionLabel; - SmTreeModel *mModel; + void movieData(); + void movieDataRecursive(QJsonValue start, SmTreeItem *appendTo); + void pictureData(); + void appendItem(const QList<QVariant> &data, SmTreeItem *parent); + QTabWidget *mTab; + QStackedWidget *mStack; + QPushButton *mOk; + SmTreeModel *mFormatModel; + SmTreeView *mFormatView; + SmTreeModel *mStreamModel; + SmTreeView *mStreamView; + SmTreeModel *mPicModel; + SmTreeView *mPicView; + QString mFile; }; #endif // FILEPROPERTIESDIALOG_H diff --git a/fileview.cpp b/fileview.cpp index 336d179..80a81bd 100644 --- a/fileview.cpp +++ b/fileview.cpp @@ -32,6 +32,7 @@ #include "hoverwindow.h" #include "smglobals.h" #include "filesystemfileproxy.h" +#include "filepropertiesdialog.h" #include "smdirmodel.h" #include "framecache.h" @@ -231,6 +232,16 @@ void FileView::selectedFilesChanged(){ emit selectedDuration(dur, false); } +void FileView::properties(){ + QModelIndexList selected = selectionModel()->selectedRows(); + if(selected.isEmpty()){ + return; + } + QString fp = selected.at(0).data(SmDirModel::FullPathRole).toString(); + FilePropertiesDialog fpd(fp, this); + fpd.exec(); +} + void FileView::saveSelection(){ mMd5Sums.clear(); QModelIndexList selected = selectionModel()->selectedRows(SmDirModel::Md5sum); @@ -49,6 +49,7 @@ class FileView : public SmTreeView { void saveSelection(); void restoreSelection(); void selectedFilesChanged(); + void properties(); protected slots: virtual void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint); @@ -223,7 +223,6 @@ namespace Helper { QSettings s; QString ffProbe = s.value("paths/ffprobe").toString(); QStringList args; - QVariantMap retval; args << "-v" << "quiet" << "-print_format" << "json" << "-show_format" << path; QProcess ffproc; ffproc.start(ffProbe, args); @@ -236,6 +235,21 @@ namespace Helper { return jsDoc.object().value("format").toObject().toVariantMap(); } + QJsonDocument streamData(const QString &path){ + QSettings s; + QString ffProbe = s.value("paths/ffprobe").toString(); + QStringList args; + args << "-v" << "quiet" << "-print_format" << "json" << "-show_format" << "-show_streams" << path; + QProcess ffproc; + ffproc.start(ffProbe, args); + if(!ffproc.waitForStarted()){ + return QJsonDocument(); + } + ffproc.waitForFinished(); + QByteArray ffData = ffproc.readAllStandardOutput(); + return QJsonDocument::fromJson(ffData); + } + Duration::Duration() : mHours(0), mMinutes(0), mSeconds(0) {} Duration::Duration(qint64 seconds){ @@ -13,6 +13,7 @@ #include <QVariant> #include <QList> #include <QMetaType> +#include <QJsonDocument> #include <magic.h> @@ -33,6 +34,7 @@ namespace Helper { const QString colorToHtml(const QColor &color); void centerWidget(QWidget *widget); QVariantMap ffmpegData(const QString &path); + QJsonDocument streamData(const QString &path); class Duration { public: Duration(); @@ -40,6 +40,7 @@ SheMov::SheMov(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags), mOpenWithGroupFS(0), mOpenWithGroupAV(0) { //application icon qApp->setWindowIcon(QIcon(":/shemov.png")); + createPalette(); setAttribute(Qt::WA_DeleteOnClose); QSplashScreen splash(QPixmap(":/shemov_splash2.png")); splash.show(); @@ -435,6 +436,8 @@ void SheMov::createActions(){ //View menu (FS) mRefreshA = new QAction(tr("Refresh"), this); connect(mRefreshA, SIGNAL(triggered()), mFSWidget->fileModel(), SLOT(refresh())); + mFSViewPropertiesA = new QAction(tr("Properties..."), this); + connect(mFSViewPropertiesA, SIGNAL(triggered()), mFSWidget->fileView(), SLOT(properties())); //Help menu QString aboutLabel = QString(tr("About %1...")).arg(qApp->applicationName()); @@ -596,6 +599,9 @@ void SheMov::createActions(){ // set file no mArchiveFilesFileNoA = new QAction(tr("Set File No. ..."), this); connect(mArchiveFilesFileNoA, SIGNAL(triggered()), c, SLOT(editFileNo())); + // show properties + mArchiveFilesPropertiesA = new QAction(tr("Properties..."), this); + connect(mArchiveFilesPropertiesA, SIGNAL(triggered()), c, SLOT(showProperties())); // db analyzer dialogs // analyze actors @@ -756,6 +762,8 @@ void SheMov::createMenus(){ mFSWidget->fileView()->addAction(mArchiveSelectedPicsA); mFSWidget->fileView()->addAction(mArchiveSelectedMovsA); + mFSWidget->fileView()->addAction(createSeparator()); + mFSWidget->fileView()->addAction(mFSViewPropertiesA); // Movie archive ArchiveController *c = SmGlobals::instance()->archiveController(); @@ -775,6 +783,8 @@ void SheMov::createMenus(){ c->archiveFiles()->addAction(mArchiveFilesDvdNoA); c->archiveFiles()->addAction(mArchiveFilesTypeA); c->archiveFiles()->addAction(mArchiveFilesFileNoA); + c->archiveFiles()->addAction(createSeparator()); + c->archiveFiles()->addAction(mArchiveFilesPropertiesA); QMenu *archiveFilesM = new QMenu(tr("Files"), this); archiveFilesM->addActions(c->archiveFiles()->actions()); @@ -867,12 +877,7 @@ void SheMov::createPalette(){ pal.setColor(QPalette::Base, Qt::white); pal.setColor(QPalette::AlternateBase, Qt::white); } - foreach(QWidget *w, SmGlobals::instance()->treeWidgets()){ - SmTreeView *aiv = qobject_cast<SmTreeView*>(w); - if(aiv){ - aiv->setPalette(pal); - } - } + qApp->setPalette(pal); } void SheMov::rebuildFrameCache(){ @@ -16,7 +16,6 @@ class FilesystemWidget; class QLabel; class QSignalMapper; class QActionGroup; -//class ArchiveTreeView; class NewMovieWizard; class PicturesWidget; class SmTreeModel; @@ -108,6 +107,7 @@ class SheMov : public QMainWindow { QAction *mRebuildFrameCacheA; QAction *mNewMovieWizardA; QAction *mMoveToArchiveA; + QAction *mFSViewPropertiesA; //Filesystem View Actions QActionGroup *mFSHoverGroup; @@ -150,6 +150,7 @@ class SheMov : public QMainWindow { QAction *mArchiveFilesDvdNoA; QAction *mArchiveFilesTypeA; QAction *mArchiveFilesFileNoA; + QAction *mArchiveFilesPropertiesA; //DB analyze actions QAction *mAnalyzeActorsA; diff --git a/smglobals.cpp b/smglobals.cpp index 2ed698c..949b5ae 100644 --- a/smglobals.cpp +++ b/smglobals.cpp @@ -115,10 +115,6 @@ FrameCache *SmGlobals::frameCache() { return mFrameCache; } -SeriesTreeWidget *SmGlobals::seriesTreeWidget(){ - return mSeriesTreeWidget; -} - QSize SmGlobals::cursorSize() { if(!mCursorSize.isValid()){ Display *dpy = XOpenDisplay(0); diff --git a/smglobals.h b/smglobals.h index 5580f47..72604ab 100644 --- a/smglobals.h +++ b/smglobals.h @@ -9,11 +9,8 @@ #define SMUBERMODELSINGLETON_H #include <QObject> - #include <QHash> #include <QSize> -#include <QPair> -#include <QList> class QAbstractItemModel; class PictureViewer2; @@ -30,8 +27,6 @@ class SmGlobals : public QObject { QAbstractItemModel *model(const QString &which); PictureViewer2 *pictureViewer(); FrameCache *frameCache(); - void setSeriesTreeWidget(SeriesTreeWidget *stree) { mSeriesTreeWidget = stree; } - SeriesTreeWidget *seriesTreeWidget(); void setArchiveController(ArchiveController *c) { mArchiveController = c; } ArchiveController *archiveController() { return mArchiveController; } QSize cursorSize(); @@ -39,7 +34,6 @@ class SmGlobals : public QObject { const QSize minPVSize() const { return QSize(640, 480); } const QHash<QString, QString> & icons() const { return mIcons; } qint64 dvdSize() const { return mDvdSize; } - QList<QWidget*> &treeWidgets() { return mTreeWidgets; } QHash<int, QString> filetypeMap() const { return mFiletypeMap; } private: @@ -54,7 +48,6 @@ class SmGlobals : public QObject { QSize mCursorSize; QHash<QString, QString> mIcons; qint64 mDvdSize; - QList<QWidget*> mTreeWidgets; ArchiveController *mArchiveController; QHash<int, QString> mFiletypeMap; }; diff --git a/smtreeview.cpp b/smtreeview.cpp index d4faab8..7fd7b48 100644 --- a/smtreeview.cpp +++ b/smtreeview.cpp @@ -11,20 +11,21 @@ #include <QMenu> #include <QContextMenuEvent> #include <QSettings> +#include <QApplication> #include "smtreeview.h" #include "smglobals.h" SmTreeView::SmTreeView(QWidget *parent) : QTreeView(parent) { header()->setSectionResizeMode(QHeaderView::ResizeToContents); - SmGlobals::instance()->treeWidgets().append(this); setAlternatingRowColors(true); + setPalette(qApp->palette()); } SmTreeView::SmTreeView(const QString &hSetting, QWidget *parent) : QTreeView(parent), mHeaderSetting(hSetting){ header()->setSectionResizeMode(QHeaderView::ResizeToContents); - SmGlobals::instance()->treeWidgets().append(this); setAlternatingRowColors(true); + setPalette(qApp->palette()); } void SmTreeView::readHeaderConfig(){ |