From 8c6051a16b12f265d7a30b4b24da10b3ba63edae Mon Sep 17 00:00:00 2001 From: Arno Date: Fri, 2 Jul 2010 16:28:02 +0200 Subject: Started NewMovieWizard for adding movies Finished GUI for first page of NewMovieWizard. To make things easier I added two new member functions to SmTreeModel: -QModelIndex find() to find items by value of a column -void reparent() to remove an item from one parent and add it to another --- newmoviewizard.cpp | 226 +++++++++++++++++++++++++++++++++++++++++++++++++++++ newmoviewizard.h | 79 +++++++++++++++++++ shemov.pro | 6 +- smtreemodel.cpp | 35 +++++++++ smtreemodel.h | 2 + 5 files changed, 346 insertions(+), 2 deletions(-) create mode 100644 newmoviewizard.cpp create mode 100644 newmoviewizard.h diff --git a/newmoviewizard.cpp b/newmoviewizard.cpp new file mode 100644 index 0000000..313ca99 --- /dev/null +++ b/newmoviewizard.cpp @@ -0,0 +1,226 @@ +/* + 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 "newmoviewizard.h" +#include "smtreemodel.h" +#include "smtreeitem.h" +#include "seriestreemodel.h" +#include "smmodelsingleton.h" +#include "helper.h" + +NewMovieWizard::NewMovieWizard(QWidget *parent) : QWizard(parent){ + +} + +MovieInfoPage::MovieInfoPage(QWidget *parent) : QWizardPage(parent){ + //page setup + setTitle(tr("Collect files for movie")); + setSubTitle(tr("Select files by clicking the \"Add files...\" button. After adding files select one by one and set the appropriate file type. The series no is the number the movie has in the series: 14 in case of e.g. rogue adventures 14. The part number only has to be set if the movie is split in several parts.")); + setPixmap(QWizard::LogoPixmap, QPixmap(":/shemov.png")); + + //files model setup + QStringList modelHeaders = QStringList() << tr("File name") << tr("File type") << tr("Size") << tr("Full path"); + mFileModel = new WizardTreeModel(modelHeaders, this); + SmTreeItem *root = new SmTreeItem(4); + mMoviesItem= new SmTreeItem(QList() << tr("Movie files") << QVariant() << QVariant() << QVariant(), root); + root->appendChild(mMoviesItem); + mCoversItem = new SmTreeItem(QList() << tr("Cover files") << QVariant() << QVariant() << QVariant(), root); + root->appendChild(mCoversItem); + mFileModel->setRoot(root); + + //files view + mFileView = new QTreeView; + mFileView->setModel(mFileModel); + mFileView->setHeaderHidden(true); + + //add + remove files + QHBoxLayout *fileButtonLayout = new QHBoxLayout; + fileButtonLayout->addStretch(); + mAddFile = new QPushButton(tr("Add files...")); + fileButtonLayout->addWidget(mAddFile); + connect(mAddFile, SIGNAL(clicked()), this, SLOT(addFiles())); + mRemoveFile = new QPushButton(tr("Remove file")); + fileButtonLayout->addWidget(mRemoveFile); + connect(mRemoveFile, SIGNAL(clicked()), this, SLOT(removeFile())); + + //movie name + QHBoxLayout *movieTitleLayout = new QHBoxLayout; + QLabel *l1 = new QLabel(tr("Movie &title")); + mTitle = new QLineEdit; + movieTitleLayout->addWidget(l1); + movieTitleLayout->addWidget(mTitle); + SeriesTreeModel *seriesModel = static_cast(SmModelSingleton::instance()->model("SeriesModel")); + QCompleter *completer = new QCompleter(this); + completer->setModel(seriesModel); + mTitle->setCompleter(completer); + + //file type + QHBoxLayout *numberLayout = new QHBoxLayout; + QLabel *l2 = new QLabel(tr("File &type")); + mFileType = new QComboBox; + mFileType->addItems(mFileModel->types()); + numberLayout->addWidget(l2); + numberLayout->addWidget(mFileType); + numberLayout->addStretch(); + connect(mFileType, SIGNAL(currentIndexChanged(QString)), this, SLOT(typeChanged(QString))); + + //the numbers + QLabel *l3 = new QLabel(tr("&Series no.")); + mSeriesNo = new QSpinBox; + l3->setBuddy(mSeriesNo); + mSeriesNo->setMinimum(1); + numberLayout->addWidget(l3); + numberLayout->addWidget(mSeriesNo); + QLabel *l4 = new QLabel(tr("&Part no.")); + mPartno = new QSpinBox; + l4->setBuddy(mPartno); + mPartno->setMinimum(1); + QLabel *l5 = new QLabel(tr("&Quality")); + mQuality = new QSpinBox; + l5->setBuddy(mQuality); + mQuality->setMinimum(1); + mQuality->setMaximum(10); + numberLayout->addWidget(l5); + numberLayout->addWidget(mQuality); + + //main layout + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addWidget(mFileView); + mainLayout->addLayout(fileButtonLayout); + mainLayout->addLayout(numberLayout); + setLayout(mainLayout); + + //expose data + //later... +} + +void MovieInfoPage::addFiles(){ + QSettings s; + QString startDir = s.value("paths/selecteddir", QDir::homePath()).toString(); + QStringList files = QFileDialog::getOpenFileNames(this, tr("Select files"), startDir); + if(files.isEmpty()){ + return; + } + foreach(QString f, files){ + QFileInfo fi(f); + if(fi.exists()){ + QList itemData; + QModelIndex parent = QModelIndex(); + itemData << fi.fileName() << fi.size() << QVariant() << fi.absoluteFilePath(); + QString mimeType = Helper::mimeType(fi.absoluteFilePath()); + if(mimeType.startsWith("image")){ + itemData[WizardTreeModel::FileType] = WizardTreeModel::GeneralCover; + parent = mFileModel->find("Movie files"); + }else{ + itemData[WizardTreeModel::FileType] = WizardTreeModel::Movie; + parent = mFileModel->find("Cover files"); + } + if(parent.isValid()){ + mFileModel->addRow(itemData, parent); + } + } + } +} + +void MovieInfoPage::removeFile(){ + QModelIndexList selected = mFileView->selectionModel()->selectedRows(); + if(selected.isEmpty()){ + return; + } + mFileModel->removeRows(selected.at(0).row(), 1, selected.at(0).parent()); +} + +void MovieInfoPage::typeChanged(QString type){ + QModelIndexList selected = mFileView->selectionModel()->selectedRows(); + if(selected.isEmpty()){ + return; + } + int newTypeId = mFileModel->typeId(type); + if(newTypeId == -1){ + return; + } + QModelIndex item = selected.at(0); + QModelIndex typeIndex = mFileModel->index(item.row(), WizardTreeModel::FileType, item.parent()); + mFileModel->setData(typeIndex, newTypeId, Qt::EditRole); + QModelIndex newParent; + if(newTypeId == WizardTreeModel::Movie){ + newParent = mFileModel->find("Movie files"); + }else{ + newParent = mFileModel->find("Cover files"); + } + mFileModel->reparent(item, newParent); + +} + +WizardTreeModel::WizardTreeModel(QStringList &headers, QObject *parent) : SmTreeModel(headers, parent){ + mFileTypeMap.insert(1, tr("Movie")); + mFileTypeMap.insert(2, tr("Front cover")); + mFileTypeMap.insert(3, tr("Back cover")); + mFileTypeMap.insert(4, tr("General cover")); +} + +Qt::ItemFlags WizardTreeModel::flags(const QModelIndex &index) const{ + if(!index.parent().isValid()){ + return Qt::ItemIsEnabled; + } + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +QVariant WizardTreeModel::data(const QModelIndex &index, int role) const{ + SmTreeItem *item = static_cast(index.internalPointer()); + if(role == Qt::DisplayRole){ + if(index.column() == FileSize){ + QLocale l; + return l.toString(item->data(FileSize).toLongLong()); + } + if(index.column() == FileType){ + return mFileTypeMap.value(index.data().toInt()); + } + return item->data(index.column()); + } + if(role == FileNameRole){ + return item->data(FileName); + } + if(role == FileSizeRole){ + return item->data(FileSize); + } + if(role == FileTypeRole){ + return item->data(FileType); + } + if(role == FullPathRole){ + return item->data(FullPath); + } + return QVariant(); +} + +QStringList WizardTreeModel::types() const { + return mFileTypeMap.values(); +} + +int WizardTreeModel::typeId(const QString &value) const{ + QHash::const_iterator it = mFileTypeMap.constBegin(); + while(it != mFileTypeMap.constEnd()){ + if(it.value() == value){ + return it.key(); + } + } + return -1; +} diff --git a/newmoviewizard.h b/newmoviewizard.h new file mode 100644 index 0000000..a92d91d --- /dev/null +++ b/newmoviewizard.h @@ -0,0 +1,79 @@ +/* + 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 NEWMOVIEWIZARD_H +#define NEWMOVIEWIZARD_H + +#include +#include +#include + +#include "smtreemodel.h" + +class QTreeView; +class WizardTreeModel; +class SmTreeItem; +class QLineEdit; +class QSpinBox; +class QPushButton; +class QComboBox; + +class NewMovieWizard : public QWizard { + Q_OBJECT + public: + explicit NewMovieWizard(QWidget *parent = 0); + +}; + +class MovieInfoPage : public QWizardPage { + Q_OBJECT + public: + explicit MovieInfoPage(QWidget *parent = 0); + + private slots: + void addFiles(); + void removeFile(); + void typeChanged(QString); + + private: + QTreeView *mFileView; + QLineEdit *mTitle; + QSpinBox *mSeriesNo; + QSpinBox *mPartno; + QSpinBox *mQuality; + QSpinBox *mDvdNo; + QPushButton *mAddFile; + QPushButton *mRemoveFile; + QComboBox *mFileType; + WizardTreeModel *mFileModel; + SmTreeItem *mMoviesItem; + SmTreeItem *mCoversItem; +}; + +class WizardTreeModel : public SmTreeModel { + Q_OBJECT + public: + enum CustomRoles { FileNameRole = Qt::UserRole + 1, FileSizeRole = Qt::UserRole + 2, FileTypeRole = Qt::UserRole + 3, FullPathRole = Qt::UserRole + 4 }; + enum Fields { FileName = 0, FileSize = 1, FileType = 3, FullPath = 4 }; + enum Types { Movie = 1, FrontCover = 2, BackCover = 3, GeneralCover = 4 }; + explicit WizardTreeModel(QStringList &headers, QObject *parent = 0); + virtual ~WizardTreeModel() {} + + //data + flags + virtual QVariant data(const QModelIndex &index, int role) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + + //file types + QStringList types() const; + int typeId(const QString &value) const; + + private: + QHash mFileTypeMap; + +}; + +#endif diff --git a/shemov.pro b/shemov.pro index 6d54047..edebb64 100644 --- a/shemov.pro +++ b/shemov.pro @@ -55,7 +55,8 @@ SOURCES = main.cpp \ filestreemodel.cpp \ filestreewidget.cpp \ mappingtablemodel.cpp \ - mappingtablewidget.cpp + mappingtablewidget.cpp \ + newmoviewizard.cpp HEADERS = listitem.h \ listmodel.h \ movieitem.h \ @@ -106,6 +107,7 @@ HEADERS = listitem.h \ filestreemodel.h \ filestreewidget.h \ mappingtablemodel.h \ - mappingtablewidget.h + mappingtablewidget.h \ + newmoviewizard.h LIBS += -lmagic RESOURCES = shemov.qrc diff --git a/smtreemodel.cpp b/smtreemodel.cpp index 2a230cc..2026902 100644 --- a/smtreemodel.cpp +++ b/smtreemodel.cpp @@ -107,6 +107,22 @@ bool SmTreeModel::setData(const QModelIndex &index, const QVariant &value, int r return true; } +QModelIndex SmTreeModel::find(const QVariant &value, int column, const QModelIndex &parent) const{ + SmTreeItem *parentItem = 0; + if(!parent.isValid()){ + parentItem = root(); + }else{ + parentItem = static_cast(parent.internalPointer()); + } + for(int i = 0; i < parentItem->childCount(); ++i){ + SmTreeItem *child = parentItem->child(i); + if(child->data(column) == value){ + return index(i, column, parent); + } + } + return QModelIndex(); +} + bool SmTreeModel::setRoot(SmTreeItem *rootItem){ if(mRootItem){ beginResetModel(); @@ -126,6 +142,25 @@ SmTreeItem *SmTreeModel::parentItem(const QModelIndex &child) const{ return static_cast(child.parent().internalPointer()); } +void SmTreeModel::reparent(const QModelIndex &idx, const QModelIndex &newParent){ + if(!idx.isValid()){ + return; + } + SmTreeItem *parentItem = 0; + SmTreeItem *item = static_cast(idx.internalPointer()); + if(newParent == QModelIndex()){ + parentItem = root(); + }else{ + parentItem = static_cast(newParent.internalPointer()); + } + removeRows(idx.row(), 1, idx.parent()); + QList data; + for(int i = 0; i < item->columnCount(); ++i){ + data << item->data(i); + } + addRow(data, newParent); +} + bool SmTreeModel::insertRows(int row, int count, const QModelIndex &parent){ SmTreeItem *parentItem = itemAt(parent); bool retval; diff --git a/smtreemodel.h b/smtreemodel.h index ae3b5ce..6d89fb2 100644 --- a/smtreemodel.h +++ b/smtreemodel.h @@ -33,11 +33,13 @@ class SmTreeModel : public QAbstractItemModel { bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role); virtual QVariant data(const QModelIndex &index, int role) const; virtual bool setData(const QModelIndex &index, const QVariant &value, int role); + virtual QModelIndex find(const QVariant &value, int column = 0, const QModelIndex &parent = QModelIndex()) const; // root + parent item bool setRoot(SmTreeItem *rootItem); SmTreeItem *root() const { return mRootItem; } SmTreeItem *parentItem(const QModelIndex &child) const; + void reparent(const QModelIndex &idx, const QModelIndex &newParent); // row manipulation bool insertRows(int row, int count, const QModelIndex &parent); -- cgit v1.2.3-70-g09d2