From: Flavio Date: Sun, 22 Jul 2012 21:43:44 +0000 (+0200) Subject: Search filters X-Git-Tag: 1.9~23 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=f5b36303738136ef3dc3ffc7a853bdb134cf0e1c;p=minitube Search filters --- diff --git a/minitube.pro b/minitube.pro index 1ba822f..1c28998 100644 --- a/minitube.pro +++ b/minitube.pro @@ -1,6 +1,6 @@ CONFIG += release TEMPLATE = app -VERSION = 1.8 +VERSION = 1.9 DEFINES += APP_VERSION="$$VERSION" APP_NAME = Minitube @@ -60,7 +60,10 @@ HEADERS += src/MainWindow.h \ src/channelsuggest.h \ src/temporary.h \ src/segmentedcontrol.h \ - src/playlistview.h + src/playlistview.h \ + src/refinesearchwidget.h \ + src/refinesearchbutton.h \ + src/sidebarwidget.h SOURCES += src/main.cpp \ src/MainWindow.cpp \ src/SearchView.cpp \ @@ -100,7 +103,10 @@ SOURCES += src/main.cpp \ src/channelsuggest.cpp \ src/temporary.cpp \ src/segmentedcontrol.cpp \ - src/playlistview.cpp + src/playlistview.cpp \ + src/refinesearchwidget.cpp \ + src/refinesearchbutton.cpp \ + src/sidebarwidget.cpp RESOURCES += resources.qrc DESTDIR = build/target/ OBJECTS_DIR = build/obj/ diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 20bd4a7..5f3ee91 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -427,6 +427,15 @@ void MainWindow::createActions() { actions->insert("stopafterthis", action); connect(action, SIGNAL(toggled(bool)), SLOT(showStopAfterThisInStatusBar(bool))); + action = new QAction(tr("&Report an Issue..."), this); + actions->insert("report-issue", action); + connect(action, SIGNAL(triggered()), SLOT(reportIssue())); + + action = new QAction(tr("&Refine Search..."), this); + action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R)); + action->setCheckable(true); + actions->insert("refine-search", action); + // common action properties foreach (QAction *action, actions->values()) { @@ -490,6 +499,8 @@ void MainWindow::createMenus() { playlistMenu->addSeparator(); playlistMenu->addAction(moveUpAct); playlistMenu->addAction(moveDownAct); + playlistMenu->addSeparator(); + playlistMenu->addAction(The::globalActions()->value("refine-search")); QMenu* videoMenu = menuBar()->addMenu(tr("&Video")); menus->insert("video", videoMenu); @@ -526,6 +537,7 @@ void MainWindow::createMenus() { #if !defined(APP_MAC) && !defined(APP_WIN) helpMenu->addAction(donateAct); #endif + helpMenu->addAction(The::globalActions()->value("report-issue")); helpMenu->addAction(aboutAct); } @@ -780,6 +792,11 @@ void MainWindow::donate() { QDesktopServices::openUrl(url); } +void MainWindow::reportIssue() { + QUrl url("http://flavio.tordini.org/forums/forum/minitube-forums/minitube-troubleshooting"); + QDesktopServices::openUrl(url); +} + void MainWindow::quit() { #ifdef APP_MAC if (!confirmQuit()) { diff --git a/src/MainWindow.h b/src/MainWindow.h index 2bc6acd..6710e2c 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -48,6 +48,7 @@ private slots: void showSearch(); void visitSite(); void donate(); + void reportIssue(); void about(); void fullscreen(); void updateUIForFullscreen(); diff --git a/src/MediaView.cpp b/src/MediaView.cpp index 2418db6..dcfd054 100644 --- a/src/MediaView.cpp +++ b/src/MediaView.cpp @@ -9,6 +9,10 @@ #include "downloaditem.h" #include "MainWindow.h" #include "temporary.h" +#include "sidebarwidget.h" +#include "playlistwidget.h" +#include "refinesearchwidget.h" +#include "sidebarwidget.h" namespace The { NetworkAccess* http(); @@ -31,29 +35,6 @@ MediaView::MediaView(QWidget *parent) : QWidget(parent) { splitter = new MiniSplitter(this); splitter->setChildrenCollapsible(false); - sortBar = new SegmentedControl(this); - mostRelevantAction = new QAction(tr("Most relevant"), this); - QKeySequence keySequence(Qt::CTRL + Qt::Key_1); - mostRelevantAction->setShortcut(keySequence); - mostRelevantAction->setStatusTip(mostRelevantAction->text() + " (" + keySequence.toString(QKeySequence::NativeText) + ")"); - addAction(mostRelevantAction); - connect(mostRelevantAction, SIGNAL(triggered()), this, SLOT(searchMostRelevant()), Qt::QueuedConnection); - sortBar->addAction(mostRelevantAction); - mostRecentAction = new QAction(tr("Most recent"), this); - keySequence = QKeySequence(Qt::CTRL + Qt::Key_2); - mostRecentAction->setShortcut(keySequence); - mostRecentAction->setStatusTip(mostRecentAction->text() + " (" + keySequence.toString(QKeySequence::NativeText) + ")"); - addAction(mostRecentAction); - connect(mostRecentAction, SIGNAL(triggered()), this, SLOT(searchMostRecent()), Qt::QueuedConnection); - sortBar->addAction(mostRecentAction); - mostViewedAction = new QAction(tr("Most viewed"), this); - keySequence = QKeySequence(Qt::CTRL + Qt::Key_3); - mostViewedAction->setShortcut(keySequence); - mostViewedAction->setStatusTip(mostViewedAction->text() + " (" + keySequence.toString(QKeySequence::NativeText) + ")"); - addAction(mostViewedAction); - connect(mostViewedAction, SIGNAL(triggered()), this, SLOT(searchMostViewed()), Qt::QueuedConnection); - sortBar->addAction(mostViewedAction); - listView = new PlaylistView(this); listView->setItemDelegate(new PrettyItemDelegate(this)); listView->setSelectionMode(QAbstractItemView::ExtendedSelection); @@ -86,9 +67,11 @@ MediaView::MediaView(QWidget *parent) : QWidget(parent) { connect(listView, SIGNAL(authorPushed(QModelIndex)), SLOT(authorPushed(QModelIndex))); - playlistWidget = new PlaylistWidget(this, sortBar, listView); - - splitter->addWidget(playlistWidget); + sidebar = new SidebarWidget(this); + sidebar->setPlaylist(listView); + connect(sidebar->getRefineSearchWidget(), SIGNAL(searchRefined()), + SLOT(searchAgain())); + splitter->addWidget(sidebar); videoAreaWidget = new VideoAreaWidget(this); // videoAreaWidget->setMinimumSize(320,240); @@ -144,6 +127,10 @@ void MediaView::initialize() { connect(videoAreaWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showVideoContextMenu(QPoint))); */ + + QAction* refineSearchAction = The::globalActions()->value("refine-search"); + connect(refineSearchAction, SIGNAL(toggled(bool)), + sidebar, SLOT(toggleRefineSearch(bool))); } void MediaView::setMediaObject(Phonon::MediaObject *mediaObject) { @@ -172,9 +159,7 @@ void MediaView::search(SearchParams *searchParams) { // start serching for videos listModel->search(searchParams); - // this implies that the enum and the bar action order is the same - sortBar->setCheckedAction(searchParams->sortBy()-1); - + sidebar->showPlaylist(); listView->setFocus(); QString keyword = searchParams->keywords(); @@ -186,6 +171,11 @@ void MediaView::search(SearchParams *searchParams) { } } + sidebar->getRefineSearchWidget()->setSearchParams(searchParams); +} + +void MediaView::searchAgain() { + search(searchParams); } void MediaView::appear() { @@ -286,6 +276,7 @@ void MediaView::stop() { delete downloadItem; downloadItem = 0; } + qDebug() << searchParams->duration(); } void MediaView::activeRowChanged(int row) { @@ -626,7 +617,7 @@ void MediaView::searchMostViewed() { } void MediaView::setPlaylistVisible(bool visible) { - playlistWidget->setVisible(visible); + splitter->widget(0)->setVisible(visible); } void MediaView::timerPlay() { diff --git a/src/MediaView.h b/src/MediaView.h index 8bf2c8d..9a56597 100644 --- a/src/MediaView.h +++ b/src/MediaView.h @@ -10,12 +10,12 @@ #include "ListModel.h" #include "segmentedcontrol.h" #include "searchparams.h" -#include "playlistwidget.h" #include "loadingwidget.h" #include "videoareawidget.h" class DownloadItem; class PlaylistView; +class SidebarWidget; namespace The { QMap* globalActions(); @@ -93,6 +93,7 @@ private slots: void playbackFinished(); void playbackResume(); void authorPushed(QModelIndex); + void searchAgain(); /* void downloadProgress(int percent); @@ -107,7 +108,7 @@ private: QSplitter *splitter; - PlaylistWidget *playlistWidget; + SidebarWidget *sidebar; PlaylistView *listView; ListModel *listModel; diff --git a/src/fontutils.cpp b/src/fontutils.cpp index c5300b6..b3418d6 100644 --- a/src/fontutils.cpp +++ b/src/fontutils.cpp @@ -25,6 +25,27 @@ const QFont FontUtils::smallBold() { return font; } +const QFont FontUtils::medium() { + static QFont font; + static bool initialized = false; + if (!initialized) { + initialized = true; + font.setPointSize(font.pointSize()*1.1); + } + return font; +} + +const QFont FontUtils::mediumBold() { + static QFont font; + static bool initialized = false; + if (!initialized) { + initialized = true; + font.setPointSize(font.pointSize()*0.9); + font.setBold(true); + } + return font; +} + const QFont FontUtils::big() { static QFont font; static bool initialized = false; diff --git a/src/fontutils.h b/src/fontutils.h index 5fe99db..077b2d7 100644 --- a/src/fontutils.h +++ b/src/fontutils.h @@ -8,6 +8,8 @@ class FontUtils { public: static const QFont small(); static const QFont smallBold(); + static const QFont medium(); + static const QFont mediumBold(); static const QFont big(); static const QFont bigBold(); diff --git a/src/playlistview.cpp b/src/playlistview.cpp index 52bdb63..2705c4d 100644 --- a/src/playlistview.cpp +++ b/src/playlistview.cpp @@ -18,9 +18,7 @@ void PlaylistView::leaveEvent(QEvent * /* event */) { } void PlaylistView::mouseMoveEvent(QMouseEvent *event) { - // qDebug() << "PlaylistView::mouseMoveEvent" << event->pos(); - - QListView::mouseMoveEvent(event); + QWidget::mouseMoveEvent(event); if (isHoveringAuthor(event)) { diff --git a/src/playlistwidget.cpp b/src/playlistwidget.cpp index 58daf3e..1101e4d 100644 --- a/src/playlistwidget.cpp +++ b/src/playlistwidget.cpp @@ -1,11 +1,11 @@ #include "playlistwidget.h" +#include "segmentedcontrol.h" PlaylistWidget::PlaylistWidget (QWidget *parent, SegmentedControl *tabBar, QListView *listView) : QWidget(parent) { - QBoxLayout *layout = new QVBoxLayout(); + QBoxLayout *layout = new QVBoxLayout(this); layout->setMargin(0); layout->setSpacing(0); layout->addWidget(tabBar); layout->addWidget(listView); - setLayout(layout); } diff --git a/src/playlistwidget.h b/src/playlistwidget.h index 37208a0..5e3342c 100644 --- a/src/playlistwidget.h +++ b/src/playlistwidget.h @@ -2,12 +2,16 @@ #define PLAYLISTWIDGET_H #include -#include "segmentedcontrol.h" -class PlaylistWidget : public QWidget -{ +class SegmentedControl; + +class PlaylistWidget : public QWidget { + + Q_OBJECT + public: PlaylistWidget(QWidget *parent, SegmentedControl *tabBar, QListView *listView); + }; #endif // PLAYLISTWIDGET_H diff --git a/src/refinesearchbutton.cpp b/src/refinesearchbutton.cpp new file mode 100644 index 0000000..4917a96 --- /dev/null +++ b/src/refinesearchbutton.cpp @@ -0,0 +1,47 @@ +#include "refinesearchbutton.h" + +static const int refineButtonSize = 48; + +RefineSearchButton::RefineSearchButton(QWidget *parent) : + QPushButton(parent) { + + hovered = false; + + setMinimumSize(refineButtonSize, refineButtonSize); + setMaximumSize(refineButtonSize, refineButtonSize); + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + setStyleSheet( + "background: red url(:/images/refine-search.png) no-repeat center;" + "border: 0;" + ); +} + +void RefineSearchButton::paintBackground() const { + +} + +void RefineSearchButton::paintEvent(QPaintEvent *event) { + // QPushButton::paintEvent(event); + QPainter painter(this); + painter.setRenderHints(QPainter::Antialiasing, true); + painter.setBrush(QColor(0,0,0, hovered ? 192 : 170)); + QPen pen(Qt::white); + pen.setWidth(2); + painter.setPen(pen); + painter.drawEllipse(QPoint(width(), height()), width()-2, height()-2); + + QPixmap icon = QPixmap(":/images/refine-search.png"); + painter.drawPixmap(width() - icon.width() - 6, height() - icon.height() - 6, + icon.width(), icon.height(), + icon); +} + +void RefineSearchButton::enterEvent(QEvent *) { + hovered = true; + update(); +} + +void RefineSearchButton::leaveEvent(QEvent *) { + hovered = false; + update(); +} diff --git a/src/refinesearchbutton.h b/src/refinesearchbutton.h new file mode 100644 index 0000000..05c15cb --- /dev/null +++ b/src/refinesearchbutton.h @@ -0,0 +1,23 @@ +#ifndef REFINESEARCHBUTTON_H +#define REFINESEARCHBUTTON_H + +#include + +class RefineSearchButton : public QPushButton +{ + Q_OBJECT +public: + RefineSearchButton(QWidget *parent = 0); + +protected: + void paintEvent(QPaintEvent *); + void enterEvent(QEvent *); + void leaveEvent(QEvent *); + +private: + void paintBackground() const; + bool hovered; + +}; + +#endif // REFINESEARCHBUTTON_H diff --git a/src/refinesearchwidget.cpp b/src/refinesearchwidget.cpp new file mode 100644 index 0000000..69f143d --- /dev/null +++ b/src/refinesearchwidget.cpp @@ -0,0 +1,230 @@ +#include "refinesearchwidget.h" +#include "fontutils.h" +#include "searchparams.h" + +RefineSearchWidget::RefineSearchWidget(QWidget *parent) : + QWidget(parent) { + dirty = false; +} + +void RefineSearchWidget::setup() { + static bool isSetup = false; + if (isSetup) return; + isSetup = true; + + static const int spacing = 15; + setFont(FontUtils::medium()); + + QBoxLayout *layout = new QVBoxLayout(this); + layout->setAlignment(Qt::AlignTop | Qt::AlignHCenter); + layout->setMargin(spacing*2); + layout->setSpacing(spacing); + + QString paramName = "sortBy"; + setupLabel(tr("Sort by"), layout, paramName); + QToolBar *sortBar = setupBar(paramName); + QActionGroup* sortGroup = new QActionGroup(this); + QStringList sortOptions = QStringList() + << tr("Relevance") + << tr("Date") + << tr("View Count") + << tr("Rating"); + int i = 0; + foreach (QString actionName, sortOptions) { + QAction *action = new QAction(actionName, sortBar); + action->setCheckable(true); + action->setFont(FontUtils::medium()); + action->setProperty("paramValue", i); + sortGroup->addAction(action); + sortBar->addAction(action); + i++; + } + + paramName = "time"; + layout->addSpacing(spacing); + setupLabel(tr("Date"), layout, paramName); + QToolBar *timeBar = setupBar(paramName); + QActionGroup* timeGroup = new QActionGroup(this); + QStringList timeSpans = QStringList() + << tr("Anytime") + << tr("Today") + << tr("7 Days") + << tr("30 Days"); + i = 0; + foreach (QString actionName, timeSpans) { + QAction *action = new QAction(actionName, timeBar); + action->setCheckable(true); + action->setFont(FontUtils::medium()); + action->setProperty("paramValue", i); + timeGroup->addAction(action); + timeBar->addAction(action); + i++; + } + + paramName = "duration"; + layout->addSpacing(spacing); + setupLabel(tr("Duration"), layout, paramName); + QToolBar *lengthBar = setupBar(paramName); + QActionGroup* lengthGroup = new QActionGroup(this); + QStringList lengthOptions = QStringList() + << tr("All") + << tr("Short") + << tr("Medium") + << tr("Long"); + QStringList tips = QStringList() + << "" + << tr("Less than 4 minutes") + << tr("Between 4 and 20 minutes") + << tr("Longer than 20 minutes"); + i = 0; + foreach (QString actionName, lengthOptions) { + QAction *action = new QAction(actionName, timeBar); + action->setStatusTip(tips.at(i)); + action->setCheckable(true); + action->setFont(FontUtils::medium()); + action->setProperty("paramValue", i); + lengthGroup->addAction(action); + lengthBar->addAction(action); + i++; + } + + paramName = "quality"; + layout->addSpacing(spacing); + setupLabel(tr("Quality"), layout, paramName); + QToolBar *qualityBar = setupBar(paramName); + QActionGroup* qualityGroup = new QActionGroup(this); + QStringList qualityOptions = QStringList() + << tr("All") + << tr("High Definition"); + tips = QStringList() + << "" + << tr("720p or higher"); + i = 0; + foreach (QString actionName, qualityOptions) { + QAction *action = new QAction(actionName, timeBar); + action->setStatusTip(tips.at(i)); + action->setCheckable(true); + action->setFont(FontUtils::medium()); + action->setProperty("paramValue", i); + qualityGroup->addAction(action); + qualityBar->addAction(action); + i++; + } + + layout->addSpacing(spacing); + QPushButton *doneButton = new QPushButton(tr("Done"), this); + doneButton->setDefault(true); + doneButton->setFont(FontUtils::medium()); + doneButton->setProperty("custom", true); + doneButton->setProperty("important", true); + doneButton->setProperty("big", true); + connect(doneButton, SIGNAL(clicked()), SLOT(doneClicked())); + layout->addWidget(doneButton, 0, Qt::AlignLeft); +} + +void RefineSearchWidget::setupLabel(QString text, QBoxLayout *layout, QString paramName) { + QBoxLayout* hLayout = new QHBoxLayout(); + hLayout->setSpacing(8); + hLayout->setMargin(0); + hLayout->setAlignment(Qt::AlignVCenter); + + QLabel *icon = new QLabel(this); + icon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + // TODO + QPixmap pixmap = QPixmap(":/images/search-" + paramName + ".png"); + QPixmap translucentPixmap(pixmap.size()); + translucentPixmap.fill(Qt::transparent); + QPainter painter; + painter.begin(&translucentPixmap); + painter.setOpacity(0.5); + painter.drawPixmap(0, 0, pixmap); + painter.end(); + icon->setPixmap(translucentPixmap); + hLayout->addWidget(icon); + + QLabel *label = new QLabel(text.toUpper(), this); + label->setFont(FontUtils::mediumBold()); + label->setStyleSheet("color: rgba(0, 0, 0, 128);"); + hLayout->addWidget(label); + + icon->setMaximumHeight(label->height()); + + layout->addLayout(hLayout); +} + +QToolBar* RefineSearchWidget::setupBar(QString paramName) { + QToolBar* bar = new QToolBar(this); + bar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + // bar->setProperty("segmented", true); + bar->setFont(FontUtils::medium()); + bar->setProperty("paramName", paramName); + connect(bar, SIGNAL(actionTriggered(QAction*)), + SLOT(actionTriggered(QAction*))); + bars.insert(paramName, bar); + layout()->addWidget(bar); + return bar; +} + +void RefineSearchWidget::paintEvent(QPaintEvent * /*event*/) { +#if defined(APP_MAC) | defined(APP_WIN) + QBrush brush; + if (window()->isActiveWindow()) { + brush = QBrush(QColor(0xdd, 0xe4, 0xeb)); + } else { + brush = palette().window(); + } + QPainter painter(this); + painter.fillRect(0, 0, width(), height(), brush); +#endif +} + +void RefineSearchWidget::actionTriggered(QAction *action) { + QToolBar *bar = static_cast(sender()); + if (!bar) { + qDebug() << __PRETTY_FUNCTION__ << "Cannot get sender"; + return; + } + + QString paramName = bar->property("paramName").toString(); + QVariant paramValue = action->property("paramValue"); + + qDebug() << "param changed" << paramName << paramValue; + emit paramChanged(paramName, paramValue); + + qDebug() << __PRETTY_FUNCTION__; + dirty = true; +} + +void RefineSearchWidget::setSearchParams(SearchParams *params) { + setup(); + + QToolBar* bar; + QAction* action; + + bar = bars.value("sortBy"); + action = bar->actions().at(params->sortBy()); + if (action) action->setChecked(true); + + bar = bars.value("duration"); + action = bar->actions().at(params->duration()); + if (action) action->setChecked(true); + + bar = bars.value("time"); + action = bar->actions().at(params->time()); + if (action) action->setChecked(true); + + bar = bars.value("quality"); + action = bar->actions().at(params->quality()); + if (action) action->setChecked(true); + + connect(this, SIGNAL(paramChanged(QString,QVariant)), + params, SLOT(setParam(QString,QVariant)), + Qt::UniqueConnection); + + dirty = false; +} + +void RefineSearchWidget::doneClicked() { + if (dirty) emit searchRefined(); + emit done(); +} diff --git a/src/refinesearchwidget.h b/src/refinesearchwidget.h new file mode 100644 index 0000000..78c6e1e --- /dev/null +++ b/src/refinesearchwidget.h @@ -0,0 +1,41 @@ +#ifndef REFINESEARCHWIDGET_H +#define REFINESEARCHWIDGET_H + +#include + +class SearchParams; + +class RefineSearchWidget : public QWidget { + + Q_OBJECT + +public: + RefineSearchWidget(QWidget *parent = 0); + + bool isDirty() { return dirty; } + void setDirty(bool dirty) { this->dirty = dirty; } + void setSearchParams(SearchParams* params); + +signals: + void paramChanged(QString name, QVariant value); + void searchRefined(); + void done(); + +protected: + void paintEvent(QPaintEvent *); + +private slots: + void actionTriggered(QAction* action); + void doneClicked(); + +private: + void setup(); + void setupLabel(QString text, QBoxLayout* layout, QString paramName); + QToolBar *setupBar(QString paramName); + + QHash bars; + bool dirty; + +}; + +#endif // REFINESEARCHWIDGET_H diff --git a/src/searchparams.cpp b/src/searchparams.cpp index 800e248..56603cc 100644 --- a/src/searchparams.cpp +++ b/src/searchparams.cpp @@ -1,6 +1,14 @@ #include "searchparams.h" SearchParams::SearchParams() { - m_sortBy = SortByRelevance; m_transient = false; + m_sortBy = SortByRelevance; + m_duration = DurationAny; + m_quality = QualityAny; + m_time = TimeAny; +} + +void SearchParams::setParam(QString name, QVariant value) { + bool success = setProperty(name.toUtf8(), value); + if (!success) qWarning() << "Failed to set property" << name << value; } diff --git a/src/searchparams.h b/src/searchparams.h index 3717825..9af3f40 100644 --- a/src/searchparams.h +++ b/src/searchparams.h @@ -1,13 +1,44 @@ #ifndef SEARCHPARAMS_H #define SEARCHPARAMS_H -#include - - +#include class SearchParams : public QObject { + Q_OBJECT + Q_PROPERTY(int sortBy READ sortBy WRITE setSortBy) + Q_PROPERTY(int duration READ duration WRITE setDuration) + Q_PROPERTY(int quality READ quality WRITE setQuality) + Q_PROPERTY(int time READ time WRITE setTime) + public: + + enum SortBy { + SortByRelevance = 0, + SortByNewest, + SortByViewCount, + SortByRating + }; + + enum Duration { + DurationAny = 0, + DurationShort, + DurationMedium, + DurationLong + }; + + enum Quality { + QualityAny = 0, + QualityHD + }; + + enum Time { + TimeAny = 0, + TimeToday, + TimeWeek, + TimeMonth + }; + SearchParams(); const QString keywords() const { return m_keywords; } @@ -22,17 +53,26 @@ public: int isTransient() const { return m_transient; } void setTransient( int transient ) { m_transient = transient; } - enum SortBy { - SortByRelevance = 1, - SortByNewest, - SortByViewCount - }; + int duration() const { return m_duration; } + void setDuration( int duration ) { m_duration = duration; } + + int quality() const { return m_quality; } + void setQuality( int quality ) { m_quality = quality; } + + int time() const { return m_time; } + void setTime( int time ) { m_time = time; } + +public slots: + void setParam(QString name, QVariant value); private: QString m_keywords; QString m_author; - int m_sortBy; bool m_transient; + int m_sortBy; + int m_duration; + int m_quality; + int m_time; }; diff --git a/src/sidebarwidget.cpp b/src/sidebarwidget.cpp new file mode 100644 index 0000000..6717e30 --- /dev/null +++ b/src/sidebarwidget.cpp @@ -0,0 +1,121 @@ +#include "sidebarwidget.h" +#include "refinesearchbutton.h" +#include "refinesearchwidget.h" +#ifndef Q_WS_X11 +#include "extra.h" +#endif + +namespace The { +QMap* globalActions(); +} + +SidebarWidget::SidebarWidget(QWidget *parent) : + QWidget(parent) { + playlist = 0; + + QBoxLayout *layout = new QVBoxLayout(this); + layout->setMargin(0); + + stackedWidget = new QStackedWidget(this); + layout->addWidget(stackedWidget); + + setup(); +} + +void SidebarWidget::setup() { + static bool isSetup = false; + if (isSetup) return; + isSetup = true; + + refineSearchButton = new RefineSearchButton(this); + refineSearchButton->setStatusTip(tr("Refine Search") + + " (" + QKeySequence(Qt::CTRL + Qt::Key_R).toString(QKeySequence::NativeText) + ")"); + refineSearchButton->hide(); + connect(refineSearchButton, SIGNAL(clicked()), SLOT(showRefineSearchWidget())); + + refineSearchWidget = new RefineSearchWidget(this); + connect(refineSearchWidget, SIGNAL(done()), SLOT(hideRefineSearchWidget())); + stackedWidget->addWidget(refineSearchWidget); + + setMouseTracking(true); + mouseTimer = new QTimer(this); + mouseTimer->setInterval(5000); + mouseTimer->setSingleShot(true); + connect(mouseTimer, SIGNAL(timeout()), refineSearchButton, SLOT(hide())); +} + +void SidebarWidget::setPlaylist(QListView *playlist) { + this->playlist = playlist; + playlist->installEventFilter(this); + stackedWidget->addWidget(playlist); +} + +void SidebarWidget::showPlaylist() { + setup(); + stackedWidget->setCurrentWidget(playlist); +} + +void SidebarWidget::showRefineSearchWidget() { + refineSearchWidget->setDirty(false); + stackedWidget->setCurrentWidget(refineSearchWidget); + refineSearchWidget->setFocus(); +#ifndef Q_WS_X11 + Extra::fadeInWidget(playlist, refineSearchWidget); +#endif + refineSearchButton->hide(); + The::globalActions()->value("refine-search")->setChecked(true); +} + +void SidebarWidget::hideRefineSearchWidget() { + stackedWidget->setCurrentWidget(playlist); + playlist->setFocus(); +#ifndef Q_WS_X11 + Extra::fadeInWidget(refineSearchWidget, playlist); +#endif + The::globalActions()->value("refine-search")->setChecked(false); +} + +void SidebarWidget::toggleRefineSearch(bool show) { + if (show) showRefineSearchWidget(); + else hideRefineSearchWidget(); +} + +void SidebarWidget::resizeEvent(QResizeEvent *event) { + QWidget::resizeEvent(event); + refineSearchButton->move( + playlist->viewport()->width() - refineSearchButton->minimumWidth(), + height() - refineSearchButton->minimumHeight()); +} + +void SidebarWidget::enterEvent(QEvent *) { + if (stackedWidget->currentWidget() != refineSearchWidget) + showRefineSearchButton(); +} + +void SidebarWidget::leaveEvent(QEvent *) { + refineSearchButton->hide(); +} + +void SidebarWidget::mouseMoveEvent(QMouseEvent *event) { + QWidget::mouseMoveEvent(event); + handleMouseMove(); +} + +bool SidebarWidget::eventFilter(QObject *obj, QEvent *event) { + if (event->type() == QEvent::MouseMove) handleMouseMove(); + return QWidget::eventFilter(obj, event); +} + +void SidebarWidget::handleMouseMove() { + if (stackedWidget->currentWidget() != refineSearchWidget) { + showRefineSearchButton(); + mouseTimer->start(); + } +} + +void SidebarWidget::showRefineSearchButton() { + refineSearchButton->move( + playlist->viewport()->width() - refineSearchButton->minimumWidth(), + height() - refineSearchButton->minimumHeight()); + refineSearchButton->show(); +} diff --git a/src/sidebarwidget.h b/src/sidebarwidget.h new file mode 100644 index 0000000..e861299 --- /dev/null +++ b/src/sidebarwidget.h @@ -0,0 +1,44 @@ +#ifndef SIDEBARWIDGET_H +#define SIDEBARWIDGET_H + +#include + +class RefineSearchButton; +class RefineSearchWidget; + +class SidebarWidget : public QWidget { + + Q_OBJECT + +public: + SidebarWidget(QWidget *parent = 0); + void setPlaylist(QListView *playlist); + void showPlaylist(); + RefineSearchWidget* getRefineSearchWidget() { return refineSearchWidget; } + +public slots: + void showRefineSearchWidget(); + void hideRefineSearchWidget(); + void toggleRefineSearch(bool show = false); + +protected: + void resizeEvent(QResizeEvent *); + void enterEvent(QEvent *); + void leaveEvent(QEvent *); + void mouseMoveEvent(QMouseEvent *event); + bool eventFilter(QObject *, QEvent *); + +private: + void showRefineSearchButton(); + void setup(); + void handleMouseMove(); + + QStackedWidget *stackedWidget; + RefineSearchButton *refineSearchButton; + QListView *playlist; + RefineSearchWidget *refineSearchWidget; + QTimer *mouseTimer; + +}; + +#endif // SIDEBARWIDGET_H diff --git a/src/temporary.cpp b/src/temporary.cpp index a979cbd..362cbd8 100644 --- a/src/temporary.cpp +++ b/src/temporary.cpp @@ -24,6 +24,8 @@ QString Temporary::filename() { tempFile += "-" + userName; #endif + // tempFile += ".mp4"; + if (QFile::exists(tempFile) && !QFile::remove(tempFile)) { qDebug() << "Cannot remove temp file" << tempFile; } diff --git a/src/youtubesearch.cpp b/src/youtubesearch.cpp index 5eced60..67eee08 100644 --- a/src/youtubesearch.cpp +++ b/src/youtubesearch.cpp @@ -13,14 +13,18 @@ void YouTubeSearch::search(SearchParams *searchParams, int max, int skip) { this->abortFlag = false; QUrl url("http://gdata.youtube.com/feeds/api/videos/"); + url.addQueryItem("v", "2"); + url.addQueryItem("max-results", QString::number(max)); url.addQueryItem("start-index", QString::number(skip)); + if (!searchParams->keywords().isEmpty()) { if (searchParams->keywords().startsWith("http://") || searchParams->keywords().startsWith("https://")) { url.addQueryItem("q", YouTubeSearch::videoIdFromUrl(searchParams->keywords())); } else url.addQueryItem("q", searchParams->keywords()); } + if (!searchParams->author().isEmpty()) url.addQueryItem("author", searchParams->author()); @@ -31,6 +35,39 @@ void YouTubeSearch::search(SearchParams *searchParams, int max, int skip) { case SearchParams::SortByViewCount: url.addQueryItem("orderby", "viewCount"); break; + case SearchParams::SortByRating: + url.addQueryItem("orderby", "rating"); + break; + } + + switch (searchParams->duration()) { + case SearchParams::DurationShort: + url.addQueryItem("duration", "short"); + break; + case SearchParams::DurationMedium: + url.addQueryItem("duration", "medium"); + break; + case SearchParams::DurationLong: + url.addQueryItem("duration", "long"); + break; + } + + switch (searchParams->time()) { + case SearchParams::TimeToday: + url.addQueryItem("time", "today"); + break; + case SearchParams::TimeWeek: + url.addQueryItem("time", "this_week"); + break; + case SearchParams::TimeMonth: + url.addQueryItem("time", "this_month"); + break; + } + + switch (searchParams->quality()) { + case SearchParams::QualityHD: + url.addQueryItem("hd", "true"); + break; } QObject *reply = The::http()->get(url);