diff options
-rw-r--r-- | archivecontroller.cpp | 10 | ||||
-rw-r--r-- | archivecontroller.h | 1 | ||||
-rw-r--r-- | archiveview.h | 3 | ||||
-rw-r--r-- | searchdialog.cpp | 159 | ||||
-rw-r--r-- | searchdialog.h | 47 | ||||
-rw-r--r-- | shemov.cpp | 16 | ||||
-rw-r--r-- | shemov.h | 4 | ||||
-rw-r--r-- | shemov.pro | 6 |
8 files changed, 242 insertions, 4 deletions
diff --git a/archivecontroller.cpp b/archivecontroller.cpp index 54838c4..338a698 100644 --- a/archivecontroller.cpp +++ b/archivecontroller.cpp @@ -68,6 +68,16 @@ void ArchiveController::init(){ 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; diff --git a/archivecontroller.h b/archivecontroller.h index 3b743bd..f262afc 100644 --- a/archivecontroller.h +++ b/archivecontroller.h @@ -41,6 +41,7 @@ class ArchiveController : public QObject { ArchiveModel *archiveTreeModel() { return mArchiveModel; } ArchiveTree *archiveTree() { return mArchiveTree; } ArchiveView *archiveView() { return mArchiveView; } + void setSeriesPart(int seriesPartId); void init(); public slots: diff --git a/archiveview.h b/archiveview.h index d0bb252..4b8f81b 100644 --- a/archiveview.h +++ b/archiveview.h @@ -47,15 +47,16 @@ class ArchiveView : public QWidget { void setCurrentArchivePath(const QStringList &p) { mCurrentArchivePath = p; } ArchiveModel *archiveModel() { return mArchiveModel; } ArchiveTree *archiveTree() { return mTree; } + ArchiveProxy *archiveProxy() { return mProxy; } QToolBar *toolBar() { return mToolBar; } public slots: void refreshArchive(); void doSelection(); + void clearFilter(); private slots: void setFilter(); - void clearFilter(); void showDatabaseError(const QString &errorMsg); void expandItem(const QModelIndex &idx); void collapseItem(const QModelIndex &idx); diff --git a/searchdialog.cpp b/searchdialog.cpp new file mode 100644 index 0000000..a55a36a --- /dev/null +++ b/searchdialog.cpp @@ -0,0 +1,159 @@ +/* + 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 <QLabel> +#include <QCheckBox> +#include <QLineEdit> +#include <QPushButton> +#include <QHBoxLayout> +#include <QVBoxLayout> +#include <QGroupBox> +#include <QSortFilterProxyModel> +#include <QSqlDatabase> +#include <QSqlQuery> + +#include "smtreeview.h" +#include "smtreeitem.h" +#include "smtreemodel.h" +#include "searchdialog.h" + +SearchDialog::SearchDialog(QWidget *parent, Qt::WindowFlags flags) : QDialog(parent, flags){ + // Define GUI items + setWindowTitle(tr("Search for")); + mExFilenames = new QCheckBox(tr("Filenames")); + mExFilenames->setChecked(true); + mExMeta = new QCheckBox(tr("Metadata")); + mExMeta->setChecked(true); + mSearch = new QLineEdit; + mResult = new SmTreeView; + mDoSearch = new QPushButton(tr("Search")); + mClose = new QPushButton(tr("Close")); + + // init Model and View + const QStringList headers = QStringList() << tr("Match") << tr("Series") << tr("SeriesPartId"); + mModel = new SmTreeModel(headers, this); + mProxy = new QSortFilterProxyModel(this); + mProxy->setSourceModel(mModel); + mResult->setModel(mProxy); + mResult->setColumnHidden(2, true); + mResult->setSortingEnabled(true); + mResult->setEditTriggers(QAbstractItemView::NoEditTriggers); + connect(mResult, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(searchDoubleclicked())); + + // Layout + QVBoxLayout *mainLayout = new QVBoxLayout; + QGroupBox *searchGb = new QGroupBox(tr("Search for:")); + QVBoxLayout *searchGbL = new QVBoxLayout; + searchGbL->addWidget(mSearch); + searchGb->setLayout(searchGbL); + mainLayout->addWidget(searchGb); + QGroupBox *excludeGb = new QGroupBox(tr("Include:")); + QHBoxLayout *excludeGbL = new QHBoxLayout; + excludeGbL->addWidget(mExFilenames); + excludeGbL->addStretch(); + excludeGbL->addWidget(mExMeta); + excludeGb->setLayout(excludeGbL); + mainLayout->addWidget(excludeGb); + QGroupBox *resultGb = new QGroupBox(tr("Search result:")); + QHBoxLayout *resultGbL = new QHBoxLayout; + resultGbL->addWidget(mResult); + resultGb->setLayout(resultGbL); + mainLayout->addWidget(resultGb); + QHBoxLayout *buttonLayout = new QHBoxLayout; + mDoSearch = new QPushButton(tr("Search")); + mClose = new QPushButton(tr("Close")); + buttonLayout->addStretch(); + buttonLayout->addWidget(mDoSearch); + buttonLayout->addWidget(mClose); + mainLayout->addLayout(buttonLayout); + setLayout(mainLayout); + setMinimumWidth(800); + + // connect the dots... + connect(mClose, SIGNAL(clicked()), this, SLOT(hide())); + connect(mDoSearch, SIGNAL(clicked()), this, SLOT(search())); + connect(mExFilenames, SIGNAL(clicked()), this, SLOT(disableSearch())); + connect(mExMeta, SIGNAL(clicked()), this, SLOT(disableSearch())); + +} + +void SearchDialog::search(){ + if(mSearch->text().isEmpty()){ + return; + } + QSqlDatabase db = QSqlDatabase::database("treedb"); + SmTreeItem *root = new SmTreeItem(3, 0); + if(mExMeta->isChecked()){ + QSqlQuery metadataQ(db); + metadataQ.prepare("SELECT iseriespart_id, tsubject, series.tseries_name, seriesparts.tsubtitle FROM metadata, seriesparts, series WHERE tsubject ~* :re AND metadata.iseriespart_id = seriesparts.iseriesparts_id AND seriesparts.iseries_id = series.iseries_id"); + metadataQ.bindValue(":re", mSearch->text()); + SmTreeItem *metadataItem = new SmTreeItem(QVariantList() << tr("Metadata") << QVariant() << QVariant(), root); + root->appendChild(metadataItem); + int ctr = 0; + metadataQ.exec(); + while(metadataQ.next()){ + ++ctr; + appendChild(metadataQ.value(0), metadataQ.value(1), metadataQ.value(2), metadataQ.value(3), metadataItem); + } + if(ctr == 0){ + appendEmpty(metadataItem); + } + } + + if(mExFilenames->isChecked()){ + QSqlQuery filenameQ(db); + filenameQ.prepare("SELECT tfilename, iseriespart_id, series.tseries_name, seriesparts.tsubtitle FROM files, seriesparts, series WHERE tfilename ~* :re AND files.iseriespart_id = seriesparts.iseriesparts_id AND seriesparts.iseries_id = series.iseries_id"); + filenameQ.bindValue(":re", mSearch->text()); + SmTreeItem *filenameItem = new SmTreeItem(QVariantList() << tr("Filenames") << QVariant() << QVariant(), root); + root->appendChild(filenameItem); + int ctr = 0; + filenameQ.exec(); + while(filenameQ.next()){ + ++ctr; + appendChild(filenameQ.value(1), filenameQ.value(0), filenameQ.value(2), filenameQ.value(3), filenameItem); + } + if(ctr == 0){ + appendEmpty(filenameItem); + } + } + mModel->setRoot(root); + mResult->expandAll(); +} + +void SearchDialog::disableSearch(){ + bool exFnChecked = mExFilenames->isChecked(); + bool exMetaChecked = mExMeta->isChecked(); + if(!exFnChecked && !exMetaChecked){ + mDoSearch->setEnabled(false); + }else{ + mDoSearch->setEnabled(true); + } +} + +void SearchDialog::appendChild(QVariant id, QVariant subject, QVariant name, QVariant sub, SmTreeItem *parent){ + QString match; + if(!sub.toString().isEmpty()){ + match = QString("%1 - %2").arg(name.toString()).arg(sub.toString()); + }else{ + match = name.toString(); + } + QVariantList itemData = QVariantList() << subject << match << id; + SmTreeItem *retval = new SmTreeItem(itemData, parent); + parent->appendChild(retval); +} + +void SearchDialog::appendEmpty(SmTreeItem *parent){ + SmTreeItem *emptyItem = new SmTreeItem(QVariantList() << tr("no match!") << QVariant() << QVariant(), parent); + parent->appendChild(emptyItem); +} + +void SearchDialog::searchDoubleclicked(){ + QPersistentModelIndex pIdx = mResult->currentIndex(); + QModelIndex idx = mProxy->mapToSource(pIdx); + SmTreeItem *curItem = static_cast<SmTreeItem*>(idx.internalPointer()); + emit searchResultClicked(curItem->data(2).toInt()); +} diff --git a/searchdialog.h b/searchdialog.h new file mode 100644 index 0000000..630f225 --- /dev/null +++ b/searchdialog.h @@ -0,0 +1,47 @@ +/* + 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 SEARCHDIALOG_H +#define SEARCHDIALOG_H + +#include <QDialog> + +class QCheckBox; +class QLineEdit; +class QPushButton; +class SmTreeView; +class SmTreeModel; +class SmTreeItem; +class QSortFilterProxyModel; + +class SearchDialog : public QDialog { + Q_OBJECT + public: + SearchDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0); + + signals: + void searchResultClicked(int); + + private slots: + void search(); + void disableSearch(); + void searchDoubleclicked(); + + private: + void appendChild(QVariant id, QVariant subject, QVariant name, QVariant sub, SmTreeItem *parent); + void appendEmpty(SmTreeItem *parent); + QLineEdit *mSearch; + QCheckBox *mExFilenames; + QCheckBox *mExMeta; + SmTreeView *mResult; + SmTreeModel *mModel; + QSortFilterProxyModel *mProxy; + QPushButton *mDoSearch; + QPushButton *mClose; +}; + +#endif // SEARCHDIALOG_H @@ -36,6 +36,7 @@ #include "archiveview.h" #include "archivecontroller.h" #include "archivebrowser.h" +#include "searchdialog.h" SheMov::SheMov(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags), mOpenWithGroupFS(0), mOpenWithGroupAV(0) { //application icon @@ -86,7 +87,7 @@ SheMov::SheMov(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, fla connect(mArchiveBrowser, SIGNAL(sizeChanged(qint64)), this, SLOT(setSize(qint64))); connect(mArchiveBrowser, SIGNAL(itemCountChanged(int)), this, SLOT(updateSelectedCount(int))); - //newmoviewizard + dbanalyzer + newpicsdialog + //newmoviewizard + dbanalyzer + newpicsdialog + searchdialog splash.showMessage(tr("Creating misc. Dialogs..."), Qt::AlignHCenter, Qt::yellow); qApp->processEvents(); mNewMovieWizard = new NewMovieWizard(this); @@ -94,6 +95,8 @@ SheMov::SheMov(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, fla ArchiveController *c = SmGlobals::instance()->archiveController(); connect(mNewMovieWizard, SIGNAL(accepted()), c->archiveTreeModel(), SLOT(refresh())); mNewPicsDialog = new NewPicsDialog(this); + mSearchDialog = new SearchDialog(this); + connect(mSearchDialog, SIGNAL(searchResultClicked(int)), this, SLOT(searchResult(int))); //experimental archive connect(c, SIGNAL(sizeChanged(qint64)), this, SLOT(setSize(qint64))); @@ -397,6 +400,9 @@ void SheMov::createActions(){ connect(mNewPicsA, SIGNAL(triggered()), this, SLOT(newPicsDialog())); mUnpackA = new QAction(QIcon(":/dog_hood.png"), tr("Unpack..."), this); connect(mUnpackA, SIGNAL(triggered()), mFSWidget, SLOT(unpack())); + mSearchDialogA = new QAction(tr("Search..."), this); + mSearchDialogA->setShortcut(tr("CTRL+f")); + connect(mSearchDialogA, SIGNAL(triggered()), mSearchDialog, SLOT(show())); //connnect mQuitA = new QAction(tr("Quit"), this); @@ -718,6 +724,7 @@ void SheMov::createMenus(){ QMenu *fileMenu = new QMenu(tr("&File"), this); fileMenu->addAction(mNewMovieWizardA); fileMenu->addAction(mNewPicsA); + fileMenu->addAction(mSearchDialogA); fileMenu->addSeparator(); fileMenu->addAction(mConsistencyA); QMenu *analyzeMenu = new QMenu(tr("Analyze"), this); @@ -1097,3 +1104,10 @@ void SheMov::skipBack(){ PictureViewer2 *picViewer = SmGlobals::instance()->pictureViewer(); picViewer->skip(-25); } + +void SheMov::searchResult(int seriesPartId){ + mSearchDialog->hide(); + mTab->setCurrentIndex(Movies); + ArchiveController *c = SmGlobals::instance()->archiveController(); + c->setSeriesPart(seriesPartId); +} @@ -22,6 +22,7 @@ class SmTreeModel; class NewPicsDialog; class ArchiveView; class ArchiveBrowser; +class SearchDialog; class SheMov : public QMainWindow { Q_OBJECT @@ -53,6 +54,7 @@ class SheMov : public QMainWindow { void newPicsDialogWithFiles(); void skipForward(); void skipBack(); + void searchResult(int seriesPartId); void analyzeActors(); void analyzeGenres(); @@ -111,6 +113,7 @@ class SheMov : public QMainWindow { QAction *mFSPreviewA; QAction *mFSResizeA; QAction *mUnpackA; + QAction *mSearchDialogA; //Filesystem View Actions QActionGroup *mOpenWithGroupFS; @@ -204,6 +207,7 @@ class SheMov : public QMainWindow { FilesystemWidget *mFSWidget; NewMovieWizard *mNewMovieWizard; NewPicsDialog *mNewPicsDialog; + SearchDialog *mSearchDialog; PicturesWidget *mPicWidget; ArchiveView *mArchive; ArchiveBrowser *mArchiveBrowser; @@ -43,7 +43,8 @@ SOURCES = main.cpp \ delegates.cpp \ archivebrowser.cpp \ archivebrowsermodel.cpp \ - unpacker.cpp + unpacker.cpp \ + searchdialog.cpp HEADERS = \ filesystemdirproxy.h \ filesystemwidget.h \ @@ -82,6 +83,7 @@ HEADERS = \ delegates.h \ archivebrowser.h \ archivebrowsermodel.h \ - unpacker.h + unpacker.h \ + searchdialog.h LIBS += -lmagic -lXfixes -lX11 RESOURCES = shemov.qrc |