1 #include "SearchView.h"
4 #include "searchparams.h"
5 #include "youtubesuggest.h"
6 #include "channelsuggest.h"
8 #include "searchlineedit_mac.h"
10 #include "searchlineedit.h"
14 QMap<QString, QAction*>* globalActions();
17 static const QString recentKeywordsKey = "recentKeywords";
18 static const QString recentChannelsKey = "recentChannels";
19 static const int PADDING = 30;
21 SearchView::SearchView(QWidget *parent) : QWidget(parent) {
23 QFont biggerFont = FontUtils::big();
24 QFont smallerFont = FontUtils::smallBold();
26 #if defined(APP_MAC) | defined(APP_WIN)
27 // speedup painting since we'll paint the whole background
28 // by ourselves anyway in paintEvent()
29 setAttribute(Qt::WA_OpaquePaintEvent);
32 QBoxLayout *mainLayout = new QVBoxLayout();
33 mainLayout->setMargin(0);
34 mainLayout->setSpacing(0);
36 // hidden message widget
37 message = new QLabel(this);
39 mainLayout->addWidget(message);
42 QLabel *buy = new QLabel(this);
43 buy->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
44 buy->setText(QString("<a style='color:palette(text);text-decoration:none' href='%1'>%2</a>").arg(
45 QString(Constants::WEBSITE) + "#download",
46 tr("Get the full version").toUpper()
48 buy->setOpenExternalLinks(true);
50 buy->setAlignment(Qt::AlignRight);
51 buy->setStyleSheet("QLabel {"
52 "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #CCD6E0, stop: 1 #ADBCCC);"
53 "border-bottom-left-radius: 8px;"
54 "border-bottom-right-radius: 8px;"
58 mainLayout->addWidget(buy, 0, Qt::AlignRight);
61 mainLayout->addStretch();
62 mainLayout->addSpacing(PADDING);
64 QBoxLayout *hLayout = new QHBoxLayout();
65 hLayout->setAlignment(Qt::AlignCenter);
66 mainLayout->addLayout(hLayout);
68 QLabel *logo = new QLabel(this);
69 logo->setPixmap(QPixmap(":/images/app.png"));
70 hLayout->addWidget(logo, 0, Qt::AlignTop);
71 hLayout->addSpacing(PADDING);
73 QVBoxLayout *layout = new QVBoxLayout();
74 layout->setAlignment(Qt::AlignCenter);
75 hLayout->addLayout(layout);
77 QLabel *welcomeLabel =
78 new QLabel("<h1 style='font-weight:normal'>" +
79 tr("Welcome to <a href='%1'>%2</a>,")
80 // .replace("<a ", "<a style='color:palette(text)'")
81 .replace("<a href", "<a style='text-decoration:none; color:palette(text); font-weight:bold' href")
82 .arg(Constants::WEBSITE, Constants::NAME)
84 welcomeLabel->setOpenExternalLinks(true);
85 layout->addWidget(welcomeLabel);
87 layout->addSpacing(PADDING / 2);
89 QBoxLayout *tipLayout = new QHBoxLayout();
90 tipLayout->setSpacing(10);
92 //: "Enter", as in "type". The whole frase says: "Enter a keyword to start watching videos"
93 QLabel *tipLabel = new QLabel(tr("Enter"), this);
94 tipLabel->setFont(biggerFont);
95 tipLayout->addWidget(tipLabel);
97 typeCombo = new QComboBox(this);
98 typeCombo->addItem(tr("a keyword"));
99 typeCombo->addItem(tr("a channel"));
100 typeCombo->setFont(biggerFont);
101 connect(typeCombo, SIGNAL(currentIndexChanged(int)), SLOT(searchTypeChanged(int)));
102 tipLayout->addWidget(typeCombo);
104 tipLabel = new QLabel(tr("to start watching videos."), this);
105 tipLabel->setFont(biggerFont);
106 tipLayout->addWidget(tipLabel);
107 layout->addLayout(tipLayout);
109 layout->addSpacing(PADDING / 2);
111 QHBoxLayout *searchLayout = new QHBoxLayout();
112 searchLayout->setAlignment(Qt::AlignVCenter);
114 queryEdit = new SearchLineEdit(this);
115 queryEdit->setFont(biggerFont);
116 queryEdit->setMinimumWidth(queryEdit->fontInfo().pixelSize()*15);
117 connect(queryEdit, SIGNAL(search(const QString&)), SLOT(watch(const QString&)));
118 connect(queryEdit, SIGNAL(textChanged(const QString &)), SLOT(textChanged(const QString &)));
119 connect(queryEdit, SIGNAL(suggestionAccepted(const QString&)), SLOT(watch(const QString&)));
121 youtubeSuggest = new YouTubeSuggest(this);
122 channelSuggest = new ChannelSuggest(this);
123 searchTypeChanged(0);
125 searchLayout->addWidget(queryEdit);
126 searchLayout->addSpacing(10);
128 watchButton = new QPushButton(tr("Watch"), this);
129 watchButton->setDefault(true);
130 watchButton->setEnabled(false);
131 watchButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
132 connect(watchButton, SIGNAL(clicked()), this, SLOT(watch()));
133 searchLayout->addWidget(watchButton);
135 layout->addItem(searchLayout);
137 layout->addSpacing(PADDING / 2);
139 QHBoxLayout *otherLayout = new QHBoxLayout();
140 otherLayout->setMargin(0);
141 otherLayout->setSpacing(10);
143 recentKeywordsLayout = new QVBoxLayout();
144 recentKeywordsLayout->setSpacing(5);
145 recentKeywordsLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
146 recentKeywordsLabel = new QLabel(tr("Recent keywords").toUpper(), this);
147 recentKeywordsLabel->setProperty("recentHeader", true);
148 recentKeywordsLabel->setForegroundRole(QPalette::Dark);
149 recentKeywordsLabel->hide();
150 recentKeywordsLabel->setFont(smallerFont);
151 recentKeywordsLayout->addWidget(recentKeywordsLabel);
153 otherLayout->addLayout(recentKeywordsLayout);
156 recentChannelsLayout = new QVBoxLayout();
157 recentChannelsLayout->setSpacing(5);
158 recentChannelsLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
159 recentChannelsLabel = new QLabel(tr("Recent channels").toUpper(), this);
160 recentChannelsLabel->setProperty("recentHeader", true);
161 recentChannelsLabel->setForegroundRole(QPalette::Dark);
162 recentChannelsLabel->hide();
163 recentChannelsLabel->setFont(smallerFont);
164 recentChannelsLayout->addWidget(recentChannelsLabel);
166 otherLayout->addLayout(recentChannelsLayout);
168 layout->addLayout(otherLayout);
170 mainLayout->addSpacing(PADDING);
171 mainLayout->addStretch();
173 setLayout(mainLayout);
177 void SearchView::appear() {
178 updateRecentKeywords();
179 updateRecentChannels();
180 queryEdit->selectAll();
181 queryEdit->enableSuggest();
182 QTimer::singleShot(0, queryEdit, SLOT(setFocus()));
185 void SearchView::updateRecentKeywords() {
189 while ((item = recentKeywordsLayout->takeAt(1)) != 0) {
190 item->widget()->close();
196 QStringList keywords = settings.value(recentKeywordsKey).toStringList();
197 recentKeywordsLabel->setVisible(!keywords.isEmpty());
198 The::globalActions()->value("clearRecentKeywords")->setEnabled(!keywords.isEmpty());
200 foreach (QString keyword, keywords) {
201 QString link = keyword;
202 QString display = keyword;
203 if (keyword.startsWith("http://") || keyword.startsWith("https://")) {
204 int separator = keyword.indexOf("|");
205 if (separator > 0 && separator + 1 < keyword.length()) {
206 link = keyword.left(separator);
207 display = keyword.mid(separator+1);
210 bool needStatusTip = false;
211 if (display.length() > 24) {
212 display.truncate(24);
213 display.append("...");
214 needStatusTip = true;
216 QLabel *itemLabel = new QLabel("<a href=\"" + link
217 + "\" style=\"color:palette(text); text-decoration:none\">"
218 + display + "</a>", this);
219 itemLabel->setAttribute(Qt::WA_DeleteOnClose);
220 itemLabel->setProperty("recentItem", true);
221 itemLabel->setMaximumWidth(queryEdit->width() + watchButton->width());
222 // itemLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
223 // Make links navigable with the keyboard too
224 itemLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse);
226 itemLabel->setStatusTip(link);
227 connect(itemLabel, SIGNAL(linkActivated(QString)), this, SLOT(watchKeywords(QString)));
228 recentKeywordsLayout->addWidget(itemLabel);
233 void SearchView::updateRecentChannels() {
237 while ((item = recentChannelsLayout->takeAt(1)) != 0) {
238 item->widget()->close();
244 QStringList keywords = settings.value(recentChannelsKey).toStringList();
245 recentChannelsLabel->setVisible(!keywords.isEmpty());
246 // TODO The::globalActions()->value("clearRecentKeywords")->setEnabled(!keywords.isEmpty());
248 foreach (QString keyword, keywords) {
249 QString link = keyword;
250 QString display = keyword;
251 if (keyword.startsWith("http://") || keyword.startsWith("https://")) {
252 int separator = keyword.indexOf("|");
253 if (separator > 0 && separator + 1 < keyword.length()) {
254 link = keyword.left(separator);
255 display = keyword.mid(separator+1);
258 QLabel *itemLabel = new QLabel("<a href=\"" + link
259 + "\" style=\"color:palette(text); text-decoration:none\">"
260 + display + "</a>", this);
261 itemLabel->setAttribute(Qt::WA_DeleteOnClose);
262 itemLabel->setProperty("recentItem", true);
263 itemLabel->setMaximumWidth(queryEdit->width() + watchButton->width());
264 // itemLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
265 // Make links navigable with the keyboard too
266 itemLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse);
268 connect(itemLabel, SIGNAL(linkActivated(QString)), this, SLOT(watchChannel(QString)));
269 recentChannelsLayout->addWidget(itemLabel);
274 void SearchView::watch() {
275 QString query = queryEdit->text();
279 void SearchView::textChanged(const QString &text) {
280 watchButton->setEnabled(!text.simplified().isEmpty());
283 void SearchView::watch(QString query) {
285 query = query.simplified();
287 // check for empty query
288 if (query.length() == 0) {
289 queryEdit->setFocus(Qt::OtherFocusReason);
293 SearchParams *searchParams = new SearchParams();
294 if (typeCombo->currentIndex() == 0)
295 searchParams->setKeywords(query);
297 // remove spaces from channel name
298 query = query.replace(" ", "");
299 searchParams->setAuthor(query);
300 searchParams->setSortBy(SearchParams::SortByNewest);
304 emit search(searchParams);
307 void SearchView::watchChannel(QString channel) {
309 channel = channel.simplified();
311 // check for empty query
312 if (channel.length() == 0) {
313 queryEdit->setFocus(Qt::OtherFocusReason);
317 // remove spaces from channel name
318 channel = channel.remove(" ");
320 SearchParams *searchParams = new SearchParams();
321 searchParams->setAuthor(channel);
322 searchParams->setSortBy(SearchParams::SortByNewest);
325 emit search(searchParams);
328 void SearchView::watchKeywords(QString query) {
330 query = query.simplified();
332 // check for empty query
333 if (query.length() == 0) {
334 queryEdit->setFocus(Qt::OtherFocusReason);
338 if (typeCombo->currentIndex() == 0)
339 queryEdit->setText(query);
341 SearchParams *searchParams = new SearchParams();
342 searchParams->setKeywords(query);
345 emit search(searchParams);
348 void SearchView::paintEvent(QPaintEvent * /*event*/) {
349 #if defined(APP_MAC) | defined(APP_WIN)
351 if (window()->isActiveWindow()) {
352 brush = QBrush(QColor(0xdd, 0xe4, 0xeb));
354 brush = palette().window();
356 QPainter painter(this);
357 painter.fillRect(0, 0, width(), height(), brush);
361 void SearchView::searchTypeChanged(int index) {
363 queryEdit->setSuggester(youtubeSuggest);
365 queryEdit->setSuggester(channelSuggest);
367 queryEdit->selectAll();
368 queryEdit->setFocus();