]> git.sur5r.net Git - minitube/commitdiff
Search filters
authorFlavio <flavio@odisseo.local>
Sun, 22 Jul 2012 21:43:44 +0000 (23:43 +0200)
committerFlavio <flavio@odisseo.local>
Sun, 22 Jul 2012 21:47:46 +0000 (23:47 +0200)
20 files changed:
minitube.pro
src/MainWindow.cpp
src/MainWindow.h
src/MediaView.cpp
src/MediaView.h
src/fontutils.cpp
src/fontutils.h
src/playlistview.cpp
src/playlistwidget.cpp
src/playlistwidget.h
src/refinesearchbutton.cpp [new file with mode: 0644]
src/refinesearchbutton.h [new file with mode: 0644]
src/refinesearchwidget.cpp [new file with mode: 0644]
src/refinesearchwidget.h [new file with mode: 0644]
src/searchparams.cpp
src/searchparams.h
src/sidebarwidget.cpp [new file with mode: 0644]
src/sidebarwidget.h [new file with mode: 0644]
src/temporary.cpp
src/youtubesearch.cpp

index 1ba822f3d8013ee7566da8e5247e6d4ac7d26ae9..1c2899829d377393d861465a34820ed18914b64f 100644 (file)
@@ -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/
index 20bd4a75a53ed21c6a6ebe0b2dd113b6679e50f7..5f3ee91cd63a62fa22810a140662efd8462750bb 100644 (file)
@@ -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()) {
index 2bc6acd8770606fa25f8850ac287a7c9da48c107..6710e2cd05ac7b80c0b45740a4a6b97d6d18996a 100644 (file)
@@ -48,6 +48,7 @@ private slots:
     void showSearch();
     void visitSite();
     void donate();
+    void reportIssue();
     void about();
     void fullscreen();
     void updateUIForFullscreen();
index 2418db6ba73403a6c52351c91cf3ae14fbdf0360..dcfd0549f1472ce42f0b82b5b8f2d8eecce81854 100644 (file)
@@ -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() {
index 8bf2c8d075dac249cacf71fe27126942fd0b277e..9a56597dfcc9aa7acb522a096ce69bd9cb217f52 100644 (file)
 #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<QString, QAction*>* 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;
 
index c5300b6f75f0a039feb28ed8e564fa6b0b21f968..b3418d6d54d695781292d5929cedf1303d9466a4 100644 (file)
@@ -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;
index 5fe99db3a50031df1ac59c912fa230be60cc641c..077b2d71dfd3edc0d945fa9adabb4d77be677f7b 100644 (file)
@@ -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();
 
index 52bdb63789aa99a433dc62fe3b08a9122174281b..2705c4dd8590181950cbeec0c2e52cb2ebaebf49 100644 (file)
@@ -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)) {
 
index 58daf3e2291c470e3572dc97931c95c3562fb080..1101e4dd6e9bc7bd825d7a68085eec56472cb018 100644 (file)
@@ -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);
 }
index 37208a0e92c51819c32d5e390d4a640f1e84ffc7..5e3342c2ba95117ea5fd5a9cd0778ce054a737cc 100644 (file)
@@ -2,12 +2,16 @@
 #define PLAYLISTWIDGET_H
 
 #include <QtGui>
-#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 (file)
index 0000000..4917a96
--- /dev/null
@@ -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 (file)
index 0000000..05c15cb
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef REFINESEARCHBUTTON_H
+#define REFINESEARCHBUTTON_H
+
+#include <QtGui>
+
+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 (file)
index 0000000..69f143d
--- /dev/null
@@ -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<QToolBar *>(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 (file)
index 0000000..78c6e1e
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef REFINESEARCHWIDGET_H
+#define REFINESEARCHWIDGET_H
+
+#include <QtGui>
+
+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<QString, QToolBar*> bars;
+    bool dirty;
+
+};
+
+#endif // REFINESEARCHWIDGET_H
index 800e248244ab55992184b8fc66ef69bb96f572e3..56603cc674befbf91ccdf5532f430dad92f074dc 100644 (file)
@@ -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;
 }
index 3717825af68ef4233bd368485c93d74e18819e94..9af3f40e64c18f5571925963acb229d11e1d0cb2 100644 (file)
@@ -1,13 +1,44 @@
 #ifndef SEARCHPARAMS_H
 #define SEARCHPARAMS_H
 
-#include <QObject>
-
-
+#include <QtCore>
 
 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 (file)
index 0000000..6717e30
--- /dev/null
@@ -0,0 +1,121 @@
+#include "sidebarwidget.h"
+#include "refinesearchbutton.h"
+#include "refinesearchwidget.h"
+#ifndef Q_WS_X11
+#include "extra.h"
+#endif
+
+namespace The {
+QMap<QString, QAction*>* 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 (file)
index 0000000..e861299
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef SIDEBARWIDGET_H
+#define SIDEBARWIDGET_H
+
+#include <QtGui>
+
+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
index a979cbd6b44c78da639ef54f378d622bcd05dd31..362cbd8db0d4d595c77ac6e134ad71868897f448 100644 (file)
@@ -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;
     }
index 5eced6080b0bbc4b471a1f8fe33ea4d0466fc6c8..67eee080de0c4747ad6d82dba11644d52ed2c5a2 100644 (file)
@@ -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);