1 #include "SearchView.h"
4 #include "searchparams.h"
5 #include "youtubesuggest.h"
6 #include "channelsuggest.h"
9 QMap<QString, QAction*>* globalActions();
12 static const QString recentKeywordsKey = "recentKeywords";
13 static const QString recentChannelsKey = "recentChannels";
14 static const int PADDING = 30;
16 SearchView::SearchView(QWidget *parent) : QWidget(parent) {
18 QFont biggerFont = FontUtils::big();
19 QFont smallerFont = FontUtils::smallBold();
21 #if defined(APP_MAC) | defined(APP_WIN)
22 // speedup painting since we'll paint the whole background
23 // by ourselves anyway in paintEvent()
24 setAttribute(Qt::WA_OpaquePaintEvent);
27 QBoxLayout *mainLayout = new QVBoxLayout();
28 mainLayout->setMargin(0);
29 mainLayout->setSpacing(0);
31 // hidden message widget
32 message = new QLabel(this);
34 mainLayout->addWidget(message);
37 QLabel *buy = new QLabel(this);
38 buy->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
39 buy->setText(QString("<a style='color:palette(text);text-decoration:none' href='%1'>%2</a>").arg(
40 QString(Constants::WEBSITE) + "#download",
41 tr("Get the full version").toUpper()
43 buy->setOpenExternalLinks(true);
45 buy->setAlignment(Qt::AlignRight);
46 buy->setStyleSheet("QLabel {"
47 "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #CCD6E0, stop: 1 #ADBCCC);"
48 "border-bottom-left-radius: 8px;"
49 "border-bottom-right-radius: 8px;"
53 mainLayout->addWidget(buy, 0, Qt::AlignRight);
56 mainLayout->addStretch();
57 mainLayout->addSpacing(PADDING);
59 QBoxLayout *hLayout = new QHBoxLayout();
60 hLayout->setAlignment(Qt::AlignCenter);
61 mainLayout->addLayout(hLayout);
63 QLabel *logo = new QLabel(this);
64 logo->setPixmap(QPixmap(":/images/app.png"));
65 hLayout->addWidget(logo, 0, Qt::AlignTop);
66 hLayout->addSpacing(PADDING);
68 QVBoxLayout *layout = new QVBoxLayout();
69 layout->setAlignment(Qt::AlignCenter);
70 hLayout->addLayout(layout);
72 QLabel *welcomeLabel =
73 new QLabel("<h1 style='font-weight:normal'>" +
74 tr("Welcome to <a href='%1'>%2</a>,")
75 // .replace("<a ", "<a style='color:palette(text)'")
76 .replace("<a href", "<a style='text-decoration:none; color:palette(text); font-weight:bold' href")
77 .arg(Constants::WEBSITE, Constants::APP_NAME)
79 welcomeLabel->setOpenExternalLinks(true);
80 layout->addWidget(welcomeLabel);
82 layout->addSpacing(PADDING / 2);
84 QBoxLayout *tipLayout = new QHBoxLayout();
85 tipLayout->setSpacing(10);
87 //: "Enter", as in "type". The whole frase says: "Enter a keyword to start watching videos"
88 QLabel *tipLabel = new QLabel(tr("Enter"), this);
89 tipLabel->setFont(biggerFont);
90 tipLayout->addWidget(tipLabel);
92 typeCombo = new QComboBox(this);
93 typeCombo->addItem(tr("a keyword"));
94 typeCombo->addItem(tr("a channel"));
95 typeCombo->setFont(biggerFont);
96 connect(typeCombo, SIGNAL(currentIndexChanged(int)), SLOT(searchTypeChanged(int)));
97 tipLayout->addWidget(typeCombo);
99 tipLabel = new QLabel(tr("to start watching videos."), this);
100 tipLabel->setFont(biggerFont);
101 tipLayout->addWidget(tipLabel);
102 layout->addLayout(tipLayout);
104 layout->addSpacing(PADDING / 2);
106 QHBoxLayout *searchLayout = new QHBoxLayout();
107 searchLayout->setAlignment(Qt::AlignVCenter);
109 queryEdit = new SearchLineEdit(this);
110 queryEdit->setFont(biggerFont);
111 queryEdit->setMinimumWidth(queryEdit->fontInfo().pixelSize()*15);
112 queryEdit->sizeHint();
113 queryEdit->setFocus(Qt::OtherFocusReason);
114 connect(queryEdit, SIGNAL(search(const QString&)), this, SLOT(watch(const QString&)));
115 connect(queryEdit, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &)));
117 youtubeSuggest = new YouTubeSuggest(this);
118 channelSuggest = new ChannelSuggest(this);
119 searchTypeChanged(0);
121 searchLayout->addWidget(queryEdit);
122 searchLayout->addSpacing(10);
124 watchButton = new QPushButton(tr("Watch"), this);
125 watchButton->setDefault(true);
126 watchButton->setEnabled(false);
127 watchButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
128 connect(watchButton, SIGNAL(clicked()), this, SLOT(watch()));
129 searchLayout->addWidget(watchButton);
131 layout->addItem(searchLayout);
133 layout->addSpacing(PADDING / 2);
135 QHBoxLayout *otherLayout = new QHBoxLayout();
136 otherLayout->setMargin(0);
137 otherLayout->setSpacing(10);
139 recentKeywordsLayout = new QVBoxLayout();
140 recentKeywordsLayout->setSpacing(5);
141 recentKeywordsLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
142 recentKeywordsLabel = new QLabel(tr("Recent keywords").toUpper(), this);
143 #if defined(APP_MAC) | defined(APP_WIN)
144 QPalette palette = recentKeywordsLabel->palette();
145 palette.setColor(QPalette::WindowText, QColor(0x65, 0x71, 0x80));
146 recentKeywordsLabel->setPalette(palette);
148 recentKeywordsLabel->setForegroundRole(QPalette::Dark);
150 recentKeywordsLabel->hide();
151 recentKeywordsLabel->setFont(smallerFont);
152 recentKeywordsLayout->addWidget(recentKeywordsLabel);
154 otherLayout->addLayout(recentKeywordsLayout);
157 recentChannelsLayout = new QVBoxLayout();
158 recentChannelsLayout->setSpacing(5);
159 recentChannelsLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
160 recentChannelsLabel = new QLabel(tr("Recent channels").toUpper(), this);
161 #if defined(APP_MAC) | defined(APP_WIN)
162 palette = recentChannelsLabel->palette();
163 palette.setColor(QPalette::WindowText, QColor(0x65, 0x71, 0x80));
164 recentChannelsLabel->setPalette(palette);
166 recentChannelsLabel->setForegroundRole(QPalette::Dark);
168 recentChannelsLabel->hide();
169 recentChannelsLabel->setFont(smallerFont);
170 recentChannelsLayout->addWidget(recentChannelsLabel);
172 otherLayout->addLayout(recentChannelsLayout);
174 layout->addLayout(otherLayout);
176 mainLayout->addSpacing(PADDING);
177 mainLayout->addStretch();
179 setLayout(mainLayout);
183 #ifndef APP_MAC_STORE
189 void SearchView::updateRecentKeywords() {
193 while ((item = recentKeywordsLayout->takeAt(1)) != 0) {
194 item->widget()->close();
200 QStringList keywords = settings.value(recentKeywordsKey).toStringList();
201 recentKeywordsLabel->setVisible(!keywords.isEmpty());
202 The::globalActions()->value("clearRecentKeywords")->setEnabled(!keywords.isEmpty());
204 foreach (QString keyword, keywords) {
205 QString link = keyword;
206 QString display = keyword;
207 if (keyword.startsWith("http://") || keyword.startsWith("https://")) {
208 int separator = keyword.indexOf("|");
209 if (separator > 0 && separator + 1 < keyword.length()) {
210 link = keyword.left(separator);
211 display = keyword.mid(separator+1);
214 QLabel *itemLabel = new QLabel("<a href=\"" + link
215 + "\" style=\"color:palette(text); text-decoration:none\">"
216 + display + "</a>", this);
218 itemLabel->setMaximumWidth(queryEdit->width() + watchButton->width());
219 // itemLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
220 // Make links navigable with the keyboard too
221 itemLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse);
223 connect(itemLabel, SIGNAL(linkActivated(QString)), this, SLOT(watchKeywords(QString)));
224 recentKeywordsLayout->addWidget(itemLabel);
229 void SearchView::updateRecentChannels() {
233 while ((item = recentChannelsLayout->takeAt(1)) != 0) {
234 item->widget()->close();
240 QStringList keywords = settings.value(recentChannelsKey).toStringList();
241 recentChannelsLabel->setVisible(!keywords.isEmpty());
242 // TODO The::globalActions()->value("clearRecentKeywords")->setEnabled(!keywords.isEmpty());
244 foreach (QString keyword, keywords) {
245 QString link = keyword;
246 QString display = keyword;
247 if (keyword.startsWith("http://") || keyword.startsWith("https://")) {
248 int separator = keyword.indexOf("|");
249 if (separator > 0 && separator + 1 < keyword.length()) {
250 link = keyword.left(separator);
251 display = keyword.mid(separator+1);
254 QLabel *itemLabel = new QLabel("<a href=\"" + link
255 + "\" style=\"color:palette(text); text-decoration:none\">"
256 + display + "</a>", this);
258 itemLabel->setMaximumWidth(queryEdit->width() + watchButton->width());
259 // itemLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
260 // Make links navigable with the keyboard too
261 itemLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse);
263 connect(itemLabel, SIGNAL(linkActivated(QString)), this, SLOT(watchChannel(QString)));
264 recentChannelsLayout->addWidget(itemLabel);
269 void SearchView::watch() {
270 QString query = queryEdit->text();
274 void SearchView::textChanged(const QString &text) {
275 watchButton->setEnabled(!text.simplified().isEmpty());
278 void SearchView::watch(QString query) {
280 query = query.simplified();
282 // check for empty query
283 if (query.length() == 0) {
284 queryEdit->setFocus(Qt::OtherFocusReason);
288 SearchParams *searchParams = new SearchParams();
289 if (typeCombo->currentIndex() == 0)
290 searchParams->setKeywords(query);
292 // remove spaces from channel name
293 query = query.replace(" ", "");
294 searchParams->setAuthor(query);
295 searchParams->setSortBy(SearchParams::SortByNewest);
299 emit search(searchParams);
302 void SearchView::watchChannel(QString channel) {
304 channel = channel.simplified();
306 // check for empty query
307 if (channel.length() == 0) {
308 queryEdit->setFocus(Qt::OtherFocusReason);
312 // remove spaces from channel name
313 channel = channel.replace(" ", "");
315 SearchParams *searchParams = new SearchParams();
316 searchParams->setAuthor(channel);
317 searchParams->setSortBy(SearchParams::SortByNewest);
320 emit search(searchParams);
323 void SearchView::watchKeywords(QString query) {
325 query = query.simplified();
327 // check for empty query
328 if (query.length() == 0) {
329 queryEdit->setFocus(Qt::OtherFocusReason);
333 SearchParams *searchParams = new SearchParams();
334 searchParams->setKeywords(query);
337 emit search(searchParams);
340 void SearchView::checkForUpdate() {
341 static const QString updateCheckKey = "updateCheck";
345 uint unixTime = QDateTime::currentDateTime().toTime_t();
346 int lastCheck = settings.value(updateCheckKey).toInt();
347 int secondsSinceLastCheck = unixTime - lastCheck;
348 // qDebug() << "secondsSinceLastCheck" << unixTime << lastCheck << secondsSinceLastCheck;
349 if (secondsSinceLastCheck < 86400) return;
352 if (updateChecker) delete updateChecker;
353 updateChecker = new UpdateChecker();
354 connect(updateChecker, SIGNAL(newVersion(QString)),
355 this, SLOT(gotNewVersion(QString)));
356 updateChecker->checkForUpdate();
357 settings.setValue(updateCheckKey, unixTime);
361 void SearchView::gotNewVersion(QString version) {
363 tr("A new version of %1 is available. Please <a href='%2'>update to version %3</a>")
364 .replace("<a href", "<a style='text-decoration:none; color:palette(text); font-weight:bold' href")
367 QString(Constants::WEBSITE).append("#download"),
370 message->setOpenExternalLinks(true);
371 message->setMargin(10);
372 message->setAlignment(Qt::AlignCenter);
373 // message->setBackgroundRole(QPalette::ToolTipBase);
374 // message->setForegroundRole(QPalette::ToolTipText);
375 // message->setAutoFillBackground(true);
376 message->setStyleSheet("QLabel { border-bottom: 1px solid palette(mid); }");
378 if (updateChecker) delete updateChecker;
381 void SearchView::paintEvent(QPaintEvent * /*event*/) {
382 #if defined(APP_MAC) | defined(APP_WIN)
384 if (window()->isActiveWindow()) {
385 brush = QBrush(QColor(0xdd, 0xe4, 0xeb));
387 brush = palette().window();
389 QPainter painter(this);
390 painter.fillRect(0, 0, width(), height(), brush);
394 void SearchView::searchTypeChanged(int index) {
396 queryEdit->setSuggester(youtubeSuggest);
398 queryEdit->setSuggester(channelSuggest);
400 queryEdit->setFocus();