last minute string fixes
[rekonq:nikhilms-mainline.git] / src / urlbar / urlbar.cpp
1 /* ============================================================
2 *
3 * This file is a part of the rekonq project
4 *
5 * Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
6 * Copyright (C) 2009 by Domrachev Alexandr <alexandr.domrachev@gmail.com>
7 * Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com>
8 * Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr>
9 *
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License or (at your option) version 3 or any later version
15 * accepted by the membership of KDE e.V. (or its successor approved
16 * by the membership of KDE e.V.), which shall act as a proxy
17 * defined in Section 14 of version 3 of the license.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
26 *
27 * ============================================================ */
28
29
30 // Self Includes
31 #include "urlbar.h"
32 #include "urlbar.moc"
33
34 // Auto Includes
35 #include "rekonq.h"
36
37 // Local Includes
38 #include "application.h"
39 #include "mainwindow.h"
40 #include "webtab.h"
41 #include "webpage.h"
42 #include "webview.h"
43 #include "completionwidget.h"
44
45 // KDE Includes
46 #include <KCompletionBox>
47
48 // Qt Includes
49 #include <QtGui/QPainter>
50 #include <QtGui/QPaintEvent>
51 #include <QtGui/QPalette>
52 #include <QtGui/QVBoxLayout>
53
54
55
56 IconButton::IconButton(QWidget *parent)
57         : QToolButton(parent)
58 {
59     setToolButtonStyle(Qt::ToolButtonIconOnly);
60     setStyleSheet("IconButton { background-color:transparent; border: none; padding: 0px}");
61     setCursor(Qt::ArrowCursor);
62 }
63
64
65 void IconButton::mouseReleaseEvent(QMouseEvent* event)
66 {
67     emit clicked(event->globalPos());
68 }
69
70
71 // -----------------------------------------------------------------------------------------------------------
72
73
74 UrlBar::UrlBar(QWidget *parent)
75         : KLineEdit(parent)
76         , _tab(0)
77         , _privateMode(false)
78         , _icon(new IconButton(this))
79         , _suggestionTimer(new QTimer(this))
80 {
81     // initial style
82     setStyleSheet(QString("UrlBar { padding: 0 0 0 %1px;} ").arg(_icon->sizeHint().width()));
83
84     // doesn't show the clear button
85     setClearButtonShown(false);
86
87     // trap Key_Enter & Key_Return events, while emitting the returnPressed signal
88     setTrapReturnKey(true);
89
90     // insert decoded URLs
91     setUrlDropsEnabled(true);
92
93     // tooltip
94     setToolTip(i18n("Type here to search your bookmarks, history and the web..."));
95
96     // accept focus, via tabbing, clicking & wheeling
97     setFocusPolicy(Qt::WheelFocus);
98
99     // disable completion object (we have our own :) )
100     setCompletionObject(0);
101
102     _tab = qobject_cast<WebTab *>(parent);
103
104     connect(_tab->view(), SIGNAL(urlChanged(const QUrl &)), this, SLOT(setQUrl(const QUrl &)));
105     connect(_tab->view(), SIGNAL(loadFinished(bool)), this, SLOT(loadFinished()));
106     connect(_tab->view(), SIGNAL(loadStarted()), this, SLOT(clearRightIcons()));
107
108     // load typed urls
109     connect(this, SIGNAL(returnPressed(const QString &)), this, SLOT(loadTyped(const QString &)));
110
111     _suggestionTimer->setSingleShot(true);
112     connect(_suggestionTimer, SIGNAL(timeout()), this, SLOT(suggest()));
113     
114     activateSuggestions(true);
115 }
116
117
118 UrlBar::~UrlBar()
119 {
120     activateSuggestions(false);
121     delete _icon;
122     _box.clear();
123 }
124
125
126 void UrlBar::setQUrl(const QUrl& url)
127 {
128     if (url.scheme() == QL1S("about"))
129     {
130         _icon->setIcon(KIcon("arrow-right"));
131         clear();
132         setFocus();
133     }
134     else
135     {
136         clearFocus();
137         KLineEdit::setUrl(url);
138         setCursorPosition(0);
139         _icon->setIcon(Application::icon(url));
140     }
141 }
142
143
144 void UrlBar::activated(const KUrl& url, Rekonq::OpenType type)
145 {
146     activateSuggestions(false);
147
148     clearFocus();
149     setUrl(url);
150     Application::instance()->loadUrl(url, type);
151 }
152
153
154 void UrlBar::paintEvent(QPaintEvent *event)
155 {
156     QColor backgroundColor;
157     if (_privateMode)
158     {
159         backgroundColor = QColor(220, 220, 220);  // light gray
160     }
161     else
162     {
163         backgroundColor = Application::palette().color(QPalette::Base);
164     }
165
166     // set background color of UrlBar
167     QPalette p = palette();
168
169     int progr = _tab->progress();
170     if (progr == 0)
171     {
172         if (_tab->url().scheme() == QL1S("https"))
173         {
174             backgroundColor = QColor(255, 255, 171);  // light yellow
175         }
176         p.setBrush(QPalette::Base, backgroundColor);
177     }
178     else
179     {
180         QColor loadingColor = QColor(116, 192, 250);
181
182         QLinearGradient gradient(0, 0, width(), 0);
183         gradient.setColorAt(0, loadingColor);
184         gradient.setColorAt(((double)progr) / 100, backgroundColor);
185         p.setBrush(QPalette::Base, gradient);
186     }
187     setPalette(p);
188
189     // you need this before our code to draw inside the line edit..
190     KLineEdit::paintEvent(event);
191
192     if( text().isEmpty() && progr == 0 )
193     {
194         QStyleOptionFrame option;
195         initStyleOption(&option);
196         QRect textRect = style()->subElementRect(QStyle::SE_LineEditContents, &option, this);
197         QPainter painter(this);
198         painter.setPen(Qt::gray);
199         painter.drawText(textRect,
200                          Qt::AlignVCenter | Qt::AlignCenter,
201                          i18n("Type here to search your bookmarks, history and the web..")
202                         );
203     }
204 }
205
206
207 void UrlBar::keyPressEvent(QKeyEvent *event)
208 {
209     // this handles the Modifiers + Return key combinations
210     QString currentText = text().trimmed();
211     if ((event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)
212             && !currentText.startsWith(QL1S("http://"), Qt::CaseInsensitive))
213     {
214         QString append;
215         if (event->modifiers() == Qt::ControlModifier)
216         {
217             append = QL1S(".com");
218         }
219         else if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier))
220         {
221             append = QL1S(".org");
222         }
223         else if (event->modifiers() == Qt::ShiftModifier)
224         {
225             append = QL1S(".net");
226         }
227
228         QUrl url(QL1S("http://www.") + currentText);
229         QString host = url.host();
230         if (!host.endsWith(append, Qt::CaseInsensitive))
231         {
232             host += append;
233             url.setHost(host);
234             setText(url.toString());
235         }
236     }
237
238     if (event->key() == Qt::Key_Escape)
239     {
240         clearFocus();
241         event->accept();
242     }
243
244     KLineEdit::keyPressEvent(event);
245 }
246
247
248 void UrlBar::focusInEvent(QFocusEvent *event)
249 {
250     activateSuggestions(true);
251
252     KLineEdit::focusInEvent(event);
253 }
254
255
256 void UrlBar::setPrivateMode(bool on)
257 {
258     _privateMode = on;
259 }
260
261
262 void UrlBar::dropEvent(QDropEvent *event)
263 {
264     KLineEdit::dropEvent(event);
265     activated(text());
266 }
267
268
269 void UrlBar::loadFinished()
270 {
271     if (_tab->progress() != 0)
272         return;
273
274     if (_tab->url().scheme() == QL1S("about"))
275     {
276         update();
277         return;
278     }
279
280     // show KGet downloads??
281     if (ReKonfig::kgetList())
282     {
283         IconButton *bt = addRightIcon(UrlBar::KGet);
284         connect(bt, SIGNAL(clicked(QPoint)), _tab->page(), SLOT(downloadAllContentsWithKGet(QPoint)));
285     }
286
287     // show RSS
288     if (_tab->hasRSSInfo())
289     {
290         IconButton *bt = addRightIcon(UrlBar::RSS);
291         connect(bt, SIGNAL(clicked(QPoint)), _tab, SLOT(showRSSInfo(QPoint)));
292     }
293
294     // show SSL
295     if (_tab->url().scheme() == QL1S("https"))
296     {
297         IconButton *bt = addRightIcon(UrlBar::SSL);
298         connect(bt, SIGNAL(clicked(QPoint)), _tab->page(), SLOT(showSSLInfo(QPoint)));
299     }
300
301     update();
302 }
303
304
305 void UrlBar::loadTyped(const QString &text)
306 {
307     activated( KUrl(text) );
308 }
309
310
311 void UrlBar::activateSuggestions(bool b)
312 {
313     if (b)
314     {
315         if (_box.isNull())
316         {
317             _box = new CompletionWidget(this);
318             installEventFilter(_box.data());
319             connect(_box.data(), SIGNAL(chosenUrl(const KUrl &, Rekonq::OpenType)), this, SLOT(activated(const KUrl &, Rekonq::OpenType)));
320
321             // activate suggestions on edit text
322             connect(this, SIGNAL(textChanged(const QString &)), this, SLOT(detectTypedString(const QString &)));
323         }
324     }
325     else
326     {
327         disconnect(this, SIGNAL(textChanged(const QString &)), this, SLOT(detectTypedString(const QString &)));
328         removeEventFilter(_box.data());
329         _box.data()->deleteLater();
330     }
331 }
332
333
334 void UrlBar::mouseDoubleClickEvent(QMouseEvent *)
335 {
336     selectAll();
337 }
338
339
340 IconButton *UrlBar::addRightIcon(UrlBar::icon ic)
341 {
342     IconButton *rightIcon = new IconButton(this);
343
344     switch (ic)
345     {
346     case UrlBar::KGet:
347         rightIcon->setIcon(KIcon("download"));
348         rightIcon->setToolTip(i18n("List all links with KGet"));
349         break;
350     case UrlBar::RSS:
351         rightIcon->setIcon(KIcon("application-rss+xml"));
352         rightIcon->setToolTip(i18n("List all available RSS feeds"));
353         break;
354     case UrlBar::SSL:
355         rightIcon->setIcon(KIcon("object-locked"));
356         rightIcon->setToolTip(i18n("Show SSL Info"));
357         break;
358     default:
359         kDebug() << "ERROR.. default non extant case!!";
360         break;
361     }
362
363     _rightIconsList << rightIcon;
364     int iconsCount = _rightIconsList.count();
365     int iconHeight = (height() - 18) / 2;
366     rightIcon->move(width() - 23*iconsCount, iconHeight);
367     rightIcon->show();
368
369     return rightIcon;
370 }
371
372
373 void UrlBar::clearRightIcons()
374 {
375     qDeleteAll(_rightIconsList);
376     _rightIconsList.clear();
377 }
378
379
380 void UrlBar::resizeEvent(QResizeEvent *event)
381 {
382     int newHeight = (height() - 18) / 2;
383     _icon->move(4, newHeight);
384
385     int iconsCount = _rightIconsList.count();
386     int w = width();
387
388     for (int i = 0; i < iconsCount; ++i)
389     {
390         IconButton *bt = _rightIconsList.at(i);
391         bt->move(w - 25*(i + 1), newHeight);
392     }
393
394     KLineEdit::resizeEvent(event);
395 }
396
397
398 void UrlBar::detectTypedString(const QString &typed)
399 {
400     if(typed.count() == 1)
401     {
402         QTimer::singleShot(0, this, SLOT(suggest()));
403         return;
404     }
405     
406     if(_suggestionTimer->isActive())
407         _suggestionTimer->stop();
408     _suggestionTimer->start(50);
409 }
410
411
412 void UrlBar::suggest()
413 {
414     if(!_box.isNull())
415         _box.data()->suggestUrls( text() );
416 }