]> git.sur5r.net Git - minitube/blobdiff - src/searchview.cpp
New upstream version 2.9
[minitube] / src / searchview.cpp
index e5fbae75625d8ac3c00e623407a89ace2a1333c5..bf48028953b1a01f0b66e2f1fb97adb7df614159 100644 (file)
@@ -34,87 +34,93 @@ $END_LICENSE */
 #endif
 #ifdef APP_ACTIVATION
 #include "activation.h"
+#include "activationview.h"
 #endif
 #include "mainwindow.h"
 #include "painterutils.h"
 #include "iconutils.h"
+#include "clickablelabel.h"
 
-namespace The {
-QHash<QString, QAction*>* globalActions();
-}
-
+namespace {
 static const QString recentKeywordsKey = "recentKeywords";
 static const QString recentChannelsKey = "recentChannels";
-static const int PADDING = 30;
+}
 
 SearchView::SearchView(QWidget *parent) : View(parent) {
+    const int padding = 30;
 
-#if defined(APP_MAC) | defined(APP_WIN)
     // speedup painting since we'll paint the whole background
     // by ourselves anyway in paintEvent()
     setAttribute(Qt::WA_OpaquePaintEvent);
-#endif
 
-    QBoxLayout *mainLayout = new QVBoxLayout(this);
-    mainLayout->setMargin(PADDING);
-    mainLayout->setSpacing(0);
+    QBoxLayout *vLayout = new QVBoxLayout(this);
+    vLayout->setMargin(padding);
+    vLayout->setSpacing(0);
 
     // hidden message widget
     message = new QLabel(this);
     message->hide();
-    mainLayout->addWidget(message);
+    vLayout->addWidget(message);
 
-    mainLayout->addStretch();
+    vLayout->addStretch();
 
     QBoxLayout *hLayout = new QHBoxLayout();
     hLayout->setAlignment(Qt::AlignCenter);
-    mainLayout->addLayout(hLayout);
 
-    QLabel *logo = new QLabel(this);
+    vLayout->addLayout(hLayout);
+
+    hLayout->addStretch();
+
+    logo = new ClickableLabel(this);
     logo->setPixmap(IconUtils::pixmap(":/images/app.png"));
+    connect(logo, &ClickableLabel::clicked, MainWindow::instance(), &MainWindow::visitSite);
     hLayout->addWidget(logo, 0, Qt::AlignTop);
-    hLayout->addSpacing(PADDING);
+    hLayout->addSpacing(padding);
 
     QVBoxLayout *layout = new QVBoxLayout();
     layout->setAlignment(Qt::AlignCenter);
     hLayout->addLayout(layout);
 
+    QColor titleColor = palette().color(QPalette::WindowText);
+    titleColor.setAlphaF(.75);
+    int r,g,b,a;
+    titleColor.getRgb(&r,&g,&b,&a);
+    QString cssColor = QString::asprintf("rgba(%d,%d,%d,%d)", r, g, b, a);
+
     QLabel *welcomeLabel =
-            new QLabel("<h1 style='font-weight:100'>" +
+            new QLabel(QString("<h1 style='font-weight:300;color:%1'>").arg(cssColor) +
                        tr("Welcome to <a href='%1'>%2</a>,")
-                       .replace("<a ", "<a style='text-decoration:none; color:palette(text);font-weight:normal' ")
+                       .replace("<a ", "<a style='text-decoration:none; color:palette(text)' ")
                        .arg(Constants::WEBSITE, Constants::NAME)
-                       + "</h1>", this);
+                       + "</h1>");
     welcomeLabel->setOpenExternalLinks(true);
     welcomeLabel->setProperty("heading", true);
-#ifdef APP_MAC
-    QFont f = welcomeLabel->font();
-    f.setFamily("Helvetica Neue");
-    f.setStyleName("Thin");
-    welcomeLabel->setFont(f);
-#elif APP_WIN
-    QFont f = welcomeLabel->font();
-    f.setFamily("Segoe UI Light");
-    welcomeLabel->setFont(f);
-#endif
+    welcomeLabel->setFont(FontUtils::light(welcomeLabel->font().pointSize() * 1.25));
     layout->addWidget(welcomeLabel);
 
-    layout->addSpacing(PADDING / 2);
-
-    QBoxLayout *tipLayout = new QHBoxLayout();
-    tipLayout->setSpacing(10);
+    layout->addSpacing(padding / 2);
 
 #ifndef APP_MAC
     const QFont &biggerFont = FontUtils::big();
 #endif
 
     //: "Enter", as in "type". The whole phrase says: "Enter a keyword to start watching videos"
-    QLabel *tipLabel = new QLabel(tr("Enter"), this);
+    // QLabel *tipLabel = new QLabel(tr("Enter"), this);
+
+    QString tip;
+    if (qApp->layoutDirection() == Qt::RightToLeft) {
+        tip = tr("to start watching videos.") + " " + tr("a keyword") + " " + tr("Enter");
+    } else {
+        tip = tr("Enter") + " " + tr("a keyword") + " " + tr("to start watching videos.");
+    }
+    QLabel *tipLabel = new QLabel(tip);
+
 #ifndef APP_MAC
     tipLabel->setFont(biggerFont);
 #endif
-    tipLayout->addWidget(tipLabel);
+    layout->addWidget(tipLabel);
 
+    /*
     typeCombo = new QComboBox(this);
     typeCombo->addItem(tr("a keyword"));
     typeCombo->addItem(tr("a channel"));
@@ -129,15 +135,17 @@ SearchView::SearchView(QWidget *parent) : View(parent) {
     tipLabel->setFont(biggerFont);
 #endif
     tipLayout->addWidget(tipLabel);
-    layout->addLayout(tipLayout);
+    */
 
-    layout->addSpacing(PADDING / 2);
+    layout->addSpacing(padding / 2);
 
     QHBoxLayout *searchLayout = new QHBoxLayout();
     searchLayout->setAlignment(Qt::AlignVCenter);
 
 #ifdef APP_MAC_SEARCHFIELD
-    queryEdit = new SearchLineEditMac(this);
+    SearchLineEditMac *slem = new SearchLineEditMac(this);
+    queryEdit = slem;
+    setFocusProxy(slem);
 #else
     SearchLineEdit *sle = new SearchLineEdit(this);
     sle->setFont(biggerFont);
@@ -146,16 +154,18 @@ SearchView::SearchView(QWidget *parent) : View(parent) {
 
     connect(queryEdit->toWidget(), SIGNAL(search(const QString&)), SLOT(watch(const QString&)));
     connect(queryEdit->toWidget(), SIGNAL(textChanged(const QString &)), SLOT(textChanged(const QString &)));
+    connect(queryEdit->toWidget(), SIGNAL(textEdited(const QString &)), SLOT(textChanged(const QString &)));
     connect(queryEdit->toWidget(), SIGNAL(suggestionAccepted(Suggestion*)), SLOT(suggestionAccepted(Suggestion*)));
 
     youtubeSuggest = new YTSuggester(this);
     channelSuggest = new ChannelSuggest(this);
+    connect(channelSuggest, SIGNAL(ready(QVector<Suggestion*>)), SLOT(onChannelSuggestions(QVector<Suggestion*>)));
     searchTypeChanged(0);
 
-    searchLayout->addWidget(queryEdit->toWidget());
-    searchLayout->addSpacing(10);
+    searchLayout->addWidget(queryEdit->toWidget(), 0, Qt::AlignBaseline);
+    searchLayout->addSpacing(padding);
 
-    watchButton = new QPushButton(tr("Watch"), this);
+    watchButton = new QPushButton(tr("Watch"));
 #ifndef APP_MAC
     watchButton->setFont(biggerFont);
 #endif
@@ -163,67 +173,85 @@ SearchView::SearchView(QWidget *parent) : View(parent) {
     watchButton->setEnabled(false);
     watchButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
     connect(watchButton, SIGNAL(clicked()), this, SLOT(watch()));
-    searchLayout->addWidget(watchButton);
+    searchLayout->addWidget(watchButton, 0, Qt::AlignBaseline);
 
     layout->addItem(searchLayout);
 
-    layout->addSpacing(PADDING / 2);
+    layout->addSpacing(padding);
 
-    QHBoxLayout *otherLayout = new QHBoxLayout();
-    otherLayout->setMargin(0);
-    otherLayout->setSpacing(10);
+    QHBoxLayout *recentLayout = new QHBoxLayout();
+    recentLayout->setMargin(0);
+    recentLayout->setSpacing(10);
 
     recentKeywordsLayout = new QVBoxLayout();
-    recentKeywordsLayout->setSpacing(5);
+    recentKeywordsLayout->setMargin(0);
+    recentKeywordsLayout->setSpacing(0);
     recentKeywordsLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
-    recentKeywordsLabel = new QLabel(tr("Recent keywords"), this);
+    recentKeywordsLabel = new QLabel(tr("Recent keywords"));
+    recentKeywordsLabel->setEnabled(false);
     recentKeywordsLabel->setProperty("recentHeader", true);
     recentKeywordsLabel->hide();
     recentKeywordsLayout->addWidget(recentKeywordsLabel);
+    recentLayout->addLayout(recentKeywordsLayout);
 
-    otherLayout->addLayout(recentKeywordsLayout);
-
-    // recent channels
     recentChannelsLayout = new QVBoxLayout();
-    recentChannelsLayout->setSpacing(5);
+    recentChannelsLayout->setMargin(0);
+    recentChannelsLayout->setSpacing(0);
     recentChannelsLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
-    recentChannelsLabel = new QLabel(tr("Recent channels"), this);
+    recentChannelsLabel = new QLabel(tr("Recent channels"));
+    recentChannelsLabel->setEnabled(false);
     recentChannelsLabel->setProperty("recentHeader", true);
-    recentChannelsLabel->setForegroundRole(QPalette::Dark);
     recentChannelsLabel->hide();
     recentChannelsLayout->addWidget(recentChannelsLabel);
+    recentLayout->addLayout(recentChannelsLayout);
 
-    otherLayout->addLayout(recentChannelsLayout);
+    layout->addLayout(recentLayout);
 
-    layout->addLayout(otherLayout);
+    hLayout->addStretch();
 
-    mainLayout->addStretch();
+    vLayout->addStretch();
 
 #ifdef APP_ACTIVATION
     if (!Activation::instance().isActivated())
-        mainLayout->addWidget(Extra::buyButton(tr("Get the full version")), 0, Qt::AlignRight);
+        vLayout->addWidget(ActivationView::buyButton(tr("Get the full version")), 0, Qt::AlignRight);
 #endif
 }
 
 void SearchView::appear() {
-    MainWindow::instance()->showActionInStatusBar(The::globalActions()->value("definition"), true);
+    MainWindow *w = MainWindow::instance();
+    w->showActionInStatusBar(w->getAction("manualplay"), true);
+    w->showActionInStatusBar(w->getAction("safeSearch"), true);
+    w->showActionInStatusBar(w->getAction("definition"), true);
 
     updateRecentKeywords();
     updateRecentChannels();
+
     queryEdit->selectAll();
     queryEdit->enableSuggest();
-
     if (!queryEdit->toWidget()->hasFocus()) queryEdit->toWidget()->setFocus();
+
+    connect(window()->windowHandle(), SIGNAL(screenChanged(QScreen*)), SLOT(screenChanged()), Qt::UniqueConnection);
+
+    qApp->processEvents();
+    update();
+
+#ifdef APP_MAC
+    // Workaround cursor bug on macOS
+    window()->unsetCursor();
+#endif
 }
 
 void SearchView::disappear() {
-    MainWindow::instance()->showActionInStatusBar(The::globalActions()->value("definition"), false);
+    MainWindow *w = MainWindow::instance();
+    w->showActionInStatusBar(w->getAction("safeSearch"), false);
+    w->showActionInStatusBar(w->getAction("definition"), false);
+    w->showActionInStatusBar(w->getAction("manualplay"), false);
 }
 
 void SearchView::updateRecentKeywords() {
     // load
     QSettings settings;
-    QStringList keywords = settings.value(recentKeywordsKey).toStringList();
+    const QStringList keywords = settings.value(recentKeywordsKey).toStringList();
     if (keywords == recentKeywords) return;
     recentKeywords = keywords;
 
@@ -235,37 +263,39 @@ void SearchView::updateRecentKeywords() {
     }
 
     recentKeywordsLabel->setVisible(!keywords.isEmpty());
-    The::globalActions()->value("clearRecentKeywords")->setEnabled(!keywords.isEmpty());
+    MainWindow::instance()->getAction("clearRecentKeywords")->setEnabled(!keywords.isEmpty());
 
-    foreach (const QString &keyword, keywords) {
+    const int maxDisplayLength = 25;
+
+    for (const QString &keyword : keywords) {
         QString link = keyword;
         QString display = keyword;
-        if (keyword.startsWith("http://") || keyword.startsWith("https://")) {
-            int separator = keyword.indexOf("|");
+        if (keyword.startsWith(QLatin1String("http://")) || keyword.startsWith(QLatin1String("https://"))) {
+            int separator = keyword.indexOf('|');
             if (separator > 0 && separator + 1 < keyword.length()) {
                 link = keyword.left(separator);
                 display = keyword.mid(separator+1);
             }
         }
         bool needStatusTip = false;
-        if (display.length() > 24) {
-            display.truncate(24);
-            display.append("...");
+        if (display.length() > maxDisplayLength) {
+            display.truncate(maxDisplayLength);
+            display.append(QStringLiteral("\u2026"));
             needStatusTip = true;
         }
-        QLabel *itemLabel = new QLabel("<a href=\"" + link
-                                       + "\" style=\"color:palette(text); text-decoration:none\">"
-                                       + display + "</a>", this);
-        itemLabel->setAttribute(Qt::WA_DeleteOnClose);
-        itemLabel->setProperty("recentItem", true);
-        itemLabel->setMaximumWidth(queryEdit->toWidget()->width() + watchButton->width());
-        itemLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
-        // Make links navigable with the keyboard too
-        itemLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse);
+        QPushButton *itemButton = new QPushButton(display);
+        itemButton->setAttribute(Qt::WA_DeleteOnClose);
+        itemButton->setProperty("recentItem", true);
+        itemButton->setCursor(Qt::PointingHandCursor);
+        itemButton->setFocusPolicy(Qt::TabFocus);
+        itemButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
         if (needStatusTip)
-            itemLabel->setStatusTip(link);
-        connect(itemLabel, SIGNAL(linkActivated(QString)), this, SLOT(watchKeywords(QString)));
-        recentKeywordsLayout->addWidget(itemLabel);
+            itemButton->setStatusTip(link);
+        connect(itemButton, &QPushButton::clicked, [this,link]() {
+            watchKeywords(link);
+        });
+
+        recentKeywordsLayout->addWidget(itemButton);
     }
 
 }
@@ -273,7 +303,7 @@ void SearchView::updateRecentKeywords() {
 void SearchView::updateRecentChannels() {
     // load
     QSettings settings;
-    QStringList keywords = settings.value(recentChannelsKey).toStringList();
+    const QStringList keywords = settings.value(recentChannelsKey).toStringList();
     if (keywords == recentChannels) return;
     recentChannels = keywords;
 
@@ -285,9 +315,9 @@ void SearchView::updateRecentChannels() {
     }
 
     recentChannelsLabel->setVisible(!keywords.isEmpty());
-    // TODO The::globalActions()->value("clearRecentKeywords")->setEnabled(!keywords.isEmpty());
+    // TODO MainWindow::instance()->getAction("clearRecentKeywords")->setEnabled(!keywords.isEmpty());
 
-    foreach (const QString &keyword, keywords) {
+    for (const QString &keyword : keywords) {
         QString link = keyword;
         QString display = keyword;
         int separator = keyword.indexOf('|');
@@ -295,20 +325,17 @@ void SearchView::updateRecentChannels() {
             link = keyword.left(separator);
             display = keyword.mid(separator+1);
         }
-        QLabel *itemLabel = new QLabel("<a href=\"" + link
-                                       + "\" style=\"color:palette(text); text-decoration:none\">"
-                                       + display + "</a>", this);
-        itemLabel->setAttribute(Qt::WA_DeleteOnClose);
-        itemLabel->setProperty("recentItem", true);
-        itemLabel->setMaximumWidth(queryEdit->toWidget()->width() + watchButton->width());
-        // itemLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
-        // Make links navigable with the keyboard too
-        itemLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse);
-
-        connect(itemLabel, SIGNAL(linkActivated(QString)), this, SLOT(watchChannel(QString)));
-        recentChannelsLayout->addWidget(itemLabel);
+        QPushButton *itemButton = new QPushButton(display);
+        itemButton->setAttribute(Qt::WA_DeleteOnClose);
+        itemButton->setProperty("recentItem", true);
+        itemButton->setCursor(Qt::PointingHandCursor);
+        itemButton->setFocusPolicy(Qt::TabFocus);
+        itemButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
+        connect(itemButton, &QPushButton::clicked, [this,link]() {
+            watchChannel(link);
+        });
+        recentChannelsLayout->addWidget(itemButton);
     }
-
 }
 
 void SearchView::watch() {
@@ -318,33 +345,35 @@ void SearchView::watch() {
 
 void SearchView::textChanged(const QString &text) {
     watchButton->setEnabled(!text.simplified().isEmpty());
+    lastChannelSuggestions.clear();
 }
 
 void SearchView::watch(const QString &query) {
     QString q = query.simplified();
 
     // check for empty query
-    if (q.length() == 0) {
+    if (q.isEmpty()) {
         queryEdit->toWidget()->setFocus(Qt::OtherFocusReason);
         return;
     }
 
-    SearchParams *searchParams = new SearchParams();
-    if (typeCombo->currentIndex() == 0)
-        searchParams->setKeywords(q);
-    else {
-        // remove spaces from channel name
-        q.remove(' ');
-        searchParams->setChannelId(q);
-        searchParams->setSortBy(SearchParams::SortByNewest);
+    /*
+    if (typeCombo->currentIndex() == 1) {
+        // Channel search
+        MainWindow::instance()->channelSearch(q);
+        return;
     }
+    */
+
+    SearchParams *searchParams = new SearchParams();
+    searchParams->setKeywords(q);
 
     // go!
     emit search(searchParams);
 }
 
 void SearchView::watchChannel(const QString &channelId) {
-    if (channelId.length() == 0) {
+    if (channelId.isEmpty()) {
         queryEdit->toWidget()->setFocus(Qt::OtherFocusReason);
         return;
     }
@@ -352,7 +381,8 @@ void SearchView::watchChannel(const QString &channelId) {
     QString id = channelId;
 
     // Fix old settings
-    if (!id.startsWith("UC")) id = "UC" + id;
+    const QLatin1String uc("UC");
+    if (!id.startsWith(uc)) id = uc + id;
 
     SearchParams *searchParams = new SearchParams();
     searchParams->setChannelId(id);
@@ -366,15 +396,15 @@ void SearchView::watchKeywords(const QString &query) {
     QString q = query.simplified();
 
     // check for empty query
-    if (query.length() == 0) {
+    if (q.isEmpty()) {
         queryEdit->toWidget()->setFocus(Qt::OtherFocusReason);
         return;
     }
 
-    if (typeCombo->currentIndex() == 0) {
+    // if (typeCombo->currentIndex() == 0) {
         queryEdit->setText(q);
         watchButton->setEnabled(true);
-    }
+    // }
 
     SearchParams *searchParams = new SearchParams();
     searchParams->setKeywords(q);
@@ -385,23 +415,14 @@ void SearchView::watchKeywords(const QString &query) {
 
 void SearchView::paintEvent(QPaintEvent *event) {
     QWidget::paintEvent(event);
-#if defined(APP_MAC) | defined(APP_WIN)
     QBrush brush;
     if (window()->isActiveWindow()) {
-        brush = Qt::white;
+        brush = palette().base();
     } else {
         brush = palette().window();
     }
     QPainter painter(this);
     painter.fillRect(0, 0, width(), height(), brush);
-    painter.end();
-#endif
-#ifdef APP_UBUNTU
-    QStyleOption o;
-    o.initFrom(this);
-    QPainter p(this);
-    style()->drawPrimitive(QStyle::PE_Widget, &o, &p, this);
-#endif
 }
 
 void SearchView::searchTypeChanged(int index) {
@@ -419,3 +440,11 @@ void SearchView::suggestionAccepted(Suggestion *suggestion) {
         watchChannel(suggestion->userData);
     } else watch(suggestion->value);
 }
+
+void SearchView::screenChanged() {
+    logo->setPixmap(IconUtils::pixmap(":/images/app.png"));
+}
+
+void SearchView::onChannelSuggestions(const QVector<Suggestion *> &suggestions) {
+    lastChannelSuggestions = suggestions;
+}