summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArno <am@disconnect.de>2015-01-24 21:35:12 +0100
committerArno <am@disconnect.de>2015-01-24 21:35:12 +0100
commitfb0626d4c624bdb640628b9c2dad93d62d90885c (patch)
tree008e7aa0d6791e73503b2468a89c9bedc47610b2
parenta152afc1005c72e16208f15d84a6c2b24d32f578 (diff)
downloadSheMov-fb0626d4c624bdb640628b9c2dad93d62d90885c.tar.gz
SheMov-fb0626d4c624bdb640628b9c2dad93d62d90885c.tar.bz2
SheMov-fb0626d4c624bdb640628b9c2dad93d62d90885c.zip
New: search dialog
-rw-r--r--archivecontroller.cpp10
-rw-r--r--archivecontroller.h1
-rw-r--r--archiveview.h3
-rw-r--r--searchdialog.cpp159
-rw-r--r--searchdialog.h47
-rw-r--r--shemov.cpp16
-rw-r--r--shemov.h4
-rw-r--r--shemov.pro6
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
diff --git a/shemov.cpp b/shemov.cpp
index b7ffc9a..202bd95 100644
--- a/shemov.cpp
+++ b/shemov.cpp
@@ -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);
+}
diff --git a/shemov.h b/shemov.h
index bc9c962..0d44cfe 100644
--- a/shemov.h
+++ b/shemov.h
@@ -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;
diff --git a/shemov.pro b/shemov.pro
index 7912847..739fc1d 100644
--- a/shemov.pro
+++ b/shemov.pro
@@ -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