]> git.sur5r.net Git - minitube/blob - src/searchview.cpp
Renamed uppercase filenames to lowercase
[minitube] / src / searchview.cpp
1 #include "searchview.h"
2 #include "constants.h"
3 #include "fontutils.h"
4 #include "searchparams.h"
5 #include "youtubesuggest.h"
6 #include "channelsuggest.h"
7 #ifdef APP_MAC
8 #include "searchlineedit_mac.h"
9 #else
10 #include "searchlineedit.h"
11 #endif
12 #ifndef Q_WS_X11
13 #include "extra.h"
14 #endif
15 #ifdef APP_ACTIVATION
16 #include "activation.h"
17 #endif
18 #include "mainwindow.h"
19
20 namespace The {
21 QMap<QString, QAction*>* globalActions();
22 }
23
24 static const QString recentKeywordsKey = "recentKeywords";
25 static const QString recentChannelsKey = "recentChannels";
26 static const int PADDING = 30;
27
28 SearchView::SearchView(QWidget *parent) : QWidget(parent) {
29
30     QFont biggerFont = FontUtils::big();
31     QFont smallerFont = FontUtils::smallBold();
32
33 #if defined(APP_MAC) | defined(APP_WIN)
34     // speedup painting since we'll paint the whole background
35     // by ourselves anyway in paintEvent()
36     setAttribute(Qt::WA_OpaquePaintEvent);
37 #endif
38
39     QBoxLayout *mainLayout = new QVBoxLayout();
40     mainLayout->setMargin(0);
41     mainLayout->setSpacing(0);
42
43     // hidden message widget
44     message = new QLabel(this);
45     message->hide();
46     mainLayout->addWidget(message);
47
48 #ifdef APP_ACTIVATION
49     if (!Activation::instance().isActivated())
50         mainLayout->addWidget(Extra::buyButton(tr("Get the full version")), 0, Qt::AlignCenter);
51 #endif
52
53     mainLayout->addStretch();
54     mainLayout->addSpacing(PADDING);
55
56     QBoxLayout *hLayout = new QHBoxLayout();
57     hLayout->setAlignment(Qt::AlignCenter);
58     mainLayout->addLayout(hLayout);
59
60     QLabel *logo = new QLabel(this);
61     logo->setPixmap(QPixmap(":/images/app.png"));
62     hLayout->addWidget(logo, 0, Qt::AlignTop);
63     hLayout->addSpacing(PADDING);
64
65     QVBoxLayout *layout = new QVBoxLayout();
66     layout->setAlignment(Qt::AlignCenter);
67     hLayout->addLayout(layout);
68
69     QLabel *welcomeLabel =
70             new QLabel("<h1 style='font-weight:normal'>" +
71                        tr("Welcome to <a href='%1'>%2</a>,")
72                        // .replace("<a ", "<a style='color:palette(text)'")
73                        .replace("<a href", "<a style='text-decoration:none; color:palette(text); font-weight:bold' href")
74                        .arg(Constants::WEBSITE, Constants::NAME)
75                        + "</h1>", this);
76     welcomeLabel->setOpenExternalLinks(true);
77     layout->addWidget(welcomeLabel);
78
79     layout->addSpacing(PADDING / 2);
80
81     QBoxLayout *tipLayout = new QHBoxLayout();
82     tipLayout->setSpacing(10);
83
84     //: "Enter", as in "type". The whole phrase says: "Enter a keyword to start watching videos"
85     QLabel *tipLabel = new QLabel(tr("Enter"), this);
86     tipLabel->setFont(biggerFont);
87     tipLayout->addWidget(tipLabel);
88
89     typeCombo = new QComboBox(this);
90     typeCombo->addItem(tr("a keyword"));
91     typeCombo->addItem(tr("a channel"));
92     typeCombo->setFont(biggerFont);
93     connect(typeCombo, SIGNAL(currentIndexChanged(int)), SLOT(searchTypeChanged(int)));
94     tipLayout->addWidget(typeCombo);
95
96     tipLabel = new QLabel(tr("to start watching videos."), this);
97     tipLabel->setFont(biggerFont);
98     tipLayout->addWidget(tipLabel);
99     layout->addLayout(tipLayout);
100
101     layout->addSpacing(PADDING / 2);
102
103     QHBoxLayout *searchLayout = new QHBoxLayout();
104     searchLayout->setAlignment(Qt::AlignVCenter);
105
106     queryEdit = new SearchLineEdit(this);
107     queryEdit->setFont(biggerFont);
108     queryEdit->setMinimumWidth(queryEdit->fontInfo().pixelSize()*15);
109     connect(queryEdit, SIGNAL(search(const QString&)), SLOT(watch(const QString&)));
110     connect(queryEdit, SIGNAL(textChanged(const QString &)), SLOT(textChanged(const QString &)));
111     connect(queryEdit, SIGNAL(suggestionAccepted(const QString&)), SLOT(watch(const QString&)));
112
113     youtubeSuggest = new YouTubeSuggest(this);
114     channelSuggest = new ChannelSuggest(this);
115     searchTypeChanged(0);
116
117     searchLayout->addWidget(queryEdit);
118     searchLayout->addSpacing(10);
119
120     watchButton = new QPushButton(tr("Watch"), this);
121     watchButton->setDefault(true);
122     watchButton->setEnabled(false);
123     watchButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
124     connect(watchButton, SIGNAL(clicked()), this, SLOT(watch()));
125     searchLayout->addWidget(watchButton);
126
127     layout->addItem(searchLayout);
128
129     layout->addSpacing(PADDING / 2);
130
131     QHBoxLayout *otherLayout = new QHBoxLayout();
132     otherLayout->setMargin(0);
133     otherLayout->setSpacing(10);
134
135     recentKeywordsLayout = new QVBoxLayout();
136     recentKeywordsLayout->setSpacing(5);
137     recentKeywordsLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
138     recentKeywordsLabel = new QLabel(tr("Recent keywords").toUpper(), this);
139     recentKeywordsLabel->setProperty("recentHeader", true);
140     recentKeywordsLabel->setForegroundRole(QPalette::Dark);
141     recentKeywordsLabel->hide();
142     recentKeywordsLabel->setFont(smallerFont);
143     recentKeywordsLayout->addWidget(recentKeywordsLabel);
144
145     otherLayout->addLayout(recentKeywordsLayout);
146
147     // recent channels
148     recentChannelsLayout = new QVBoxLayout();
149     recentChannelsLayout->setSpacing(5);
150     recentChannelsLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
151     recentChannelsLabel = new QLabel(tr("Recent channels").toUpper(), this);
152     recentChannelsLabel->setProperty("recentHeader", true);
153     recentChannelsLabel->setForegroundRole(QPalette::Dark);
154     recentChannelsLabel->hide();
155     recentChannelsLabel->setFont(smallerFont);
156     recentChannelsLayout->addWidget(recentChannelsLabel);
157
158     otherLayout->addLayout(recentChannelsLayout);
159
160     layout->addLayout(otherLayout);
161
162     mainLayout->addSpacing(PADDING);
163     mainLayout->addStretch();
164
165     setLayout(mainLayout);
166
167 }
168
169 void SearchView::appear() {
170     updateRecentKeywords();
171     updateRecentChannels();
172     queryEdit->selectAll();
173     queryEdit->enableSuggest();
174     QTimer::singleShot(0, queryEdit, SLOT(setFocus()));
175 }
176
177 void SearchView::updateRecentKeywords() {
178
179     // cleanup
180     QLayoutItem *item;
181     while ((item = recentKeywordsLayout->takeAt(1)) != 0) {
182         item->widget()->close();
183         delete item;
184     }
185
186     // load
187     QSettings settings;
188     QStringList keywords = settings.value(recentKeywordsKey).toStringList();
189     recentKeywordsLabel->setVisible(!keywords.isEmpty());
190     The::globalActions()->value("clearRecentKeywords")->setEnabled(!keywords.isEmpty());
191
192     foreach (QString keyword, keywords) {
193         QString link = keyword;
194         QString display = keyword;
195         if (keyword.startsWith("http://") || keyword.startsWith("https://")) {
196             int separator = keyword.indexOf("|");
197             if (separator > 0 && separator + 1 < keyword.length()) {
198                 link = keyword.left(separator);
199                 display = keyword.mid(separator+1);
200             }
201         }
202         bool needStatusTip = false;
203         if (display.length() > 24) {
204             display.truncate(24);
205             display.append("...");
206             needStatusTip = true;
207         }
208         QLabel *itemLabel = new QLabel("<a href=\"" + link
209                                        + "\" style=\"color:palette(text); text-decoration:none\">"
210                                        + display + "</a>", this);
211         itemLabel->setAttribute(Qt::WA_DeleteOnClose);
212         itemLabel->setProperty("recentItem", true);
213         itemLabel->setMaximumWidth(queryEdit->width() + watchButton->width());
214         // itemLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
215         // Make links navigable with the keyboard too
216         itemLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse);
217         if (needStatusTip)
218             itemLabel->setStatusTip(link);
219         connect(itemLabel, SIGNAL(linkActivated(QString)), this, SLOT(watchKeywords(QString)));
220         recentKeywordsLayout->addWidget(itemLabel);
221     }
222
223 }
224
225 void SearchView::updateRecentChannels() {
226
227     // cleanup
228     QLayoutItem *item;
229     while ((item = recentChannelsLayout->takeAt(1)) != 0) {
230         item->widget()->close();
231         delete item;
232     }
233
234     // load
235     QSettings settings;
236     QStringList keywords = settings.value(recentChannelsKey).toStringList();
237     recentChannelsLabel->setVisible(!keywords.isEmpty());
238     // TODO The::globalActions()->value("clearRecentKeywords")->setEnabled(!keywords.isEmpty());
239
240     foreach (QString keyword, keywords) {
241         QString link = keyword;
242         QString display = keyword;
243         if (keyword.startsWith("http://") || keyword.startsWith("https://")) {
244             int separator = keyword.indexOf("|");
245             if (separator > 0 && separator + 1 < keyword.length()) {
246                 link = keyword.left(separator);
247                 display = keyword.mid(separator+1);
248             }
249         }
250         QLabel *itemLabel = new QLabel("<a href=\"" + link
251                                        + "\" style=\"color:palette(text); text-decoration:none\">"
252                                        + display + "</a>", this);
253         itemLabel->setAttribute(Qt::WA_DeleteOnClose);
254         itemLabel->setProperty("recentItem", true);
255         itemLabel->setMaximumWidth(queryEdit->width() + watchButton->width());
256         // itemLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
257         // Make links navigable with the keyboard too
258         itemLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse);
259
260         connect(itemLabel, SIGNAL(linkActivated(QString)), this, SLOT(watchChannel(QString)));
261         recentChannelsLayout->addWidget(itemLabel);
262     }
263
264 }
265
266 void SearchView::watch() {
267     QString query = queryEdit->text();
268     watch(query);
269 }
270
271 void SearchView::textChanged(const QString &text) {
272     watchButton->setEnabled(!text.simplified().isEmpty());
273 }
274
275 void SearchView::watch(QString query) {
276
277     query = query.simplified();
278
279     // check for empty query
280     if (query.length() == 0) {
281         queryEdit->setFocus(Qt::OtherFocusReason);
282         return;
283     }
284
285     SearchParams *searchParams = new SearchParams();
286     if (typeCombo->currentIndex() == 0)
287         searchParams->setKeywords(query);
288     else {
289         // remove spaces from channel name
290         query = query.replace(" ", "");
291         searchParams->setAuthor(query);
292         searchParams->setSortBy(SearchParams::SortByNewest);
293     }
294
295     // go!
296     emit search(searchParams);
297 }
298
299 void SearchView::watchChannel(QString channel) {
300
301     channel = channel.simplified();
302
303     // check for empty query
304     if (channel.length() == 0) {
305         queryEdit->setFocus(Qt::OtherFocusReason);
306         return;
307     }
308
309     // remove spaces from channel name
310     channel = channel.remove(" ");
311
312     SearchParams *searchParams = new SearchParams();
313     searchParams->setAuthor(channel);
314     searchParams->setSortBy(SearchParams::SortByNewest);
315
316     // go!
317     emit search(searchParams);
318 }
319
320 void SearchView::watchKeywords(QString query) {
321
322     query = query.simplified();
323
324     // check for empty query
325     if (query.length() == 0) {
326         queryEdit->setFocus(Qt::OtherFocusReason);
327         return;
328     }
329
330     if (typeCombo->currentIndex() == 0) {
331         queryEdit->setText(query);
332         watchButton->setEnabled(true);
333     }
334
335     SearchParams *searchParams = new SearchParams();
336     searchParams->setKeywords(query);
337
338     // go!
339     emit search(searchParams);
340 }
341
342 void SearchView::paintEvent(QPaintEvent * /*event*/) {
343 #if defined(APP_MAC) | defined(APP_WIN)
344     QBrush brush;
345     if (window()->isActiveWindow()) {
346         brush = QBrush(QColor(0xdd, 0xe4, 0xeb));
347     } else {
348         brush = palette().window();
349     }
350     QPainter painter(this);
351     painter.fillRect(0, 0, width(), height(), brush);
352 #endif
353 }
354
355 void SearchView::searchTypeChanged(int index) {
356     if (index == 0) {
357         queryEdit->setSuggester(youtubeSuggest);
358     } else {
359         queryEdit->setSuggester(channelSuggest);
360     }
361     queryEdit->selectAll();
362     queryEdit->setFocus();
363 }