#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"));
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);
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
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;
}
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);
}
}
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;
}
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('|');
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() {
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;
}
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);
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);
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) {
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;
+}