summaryrefslogtreecommitdiff
path: root/src/urlbar
diff options
context:
space:
mode:
Diffstat (limited to 'src/urlbar')
-rw-r--r--src/urlbar/completionwidget.cpp280
-rw-r--r--src/urlbar/completionwidget.h90
-rw-r--r--src/urlbar/lineedit.cpp69
-rw-r--r--src/urlbar/listitem.cpp427
-rw-r--r--src/urlbar/listitem.h220
-rw-r--r--src/urlbar/rsswidget.cpp168
-rw-r--r--src/urlbar/rsswidget.h (renamed from src/urlbar/lineedit.h)51
-rw-r--r--src/urlbar/urlbar.cpp456
-rw-r--r--src/urlbar/urlbar.h106
-rw-r--r--src/urlbar/urlresolver.cpp245
-rw-r--r--src/urlbar/urlresolver.h90
11 files changed, 1886 insertions, 316 deletions
diff --git a/src/urlbar/completionwidget.cpp b/src/urlbar/completionwidget.cpp
new file mode 100644
index 00000000..1bb01785
--- /dev/null
+++ b/src/urlbar/completionwidget.cpp
@@ -0,0 +1,280 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation; either version 2 of
+* the License or (at your option) version 3 or any later version
+* accepted by the membership of KDE e.V. (or its successor approved
+* by the membership of KDE e.V.), which shall act as a proxy
+* defined in Section 14 of version 3 of the license.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* ============================================================ */
+
+
+// Self Includes
+#include "completionwidget.h"
+#include "completionwidget.moc"
+
+// Auto Includes
+#include "rekonq.h"
+
+// Local Includes
+#include "application.h"
+#include "urlresolver.h"
+#include "searchengine.h"
+
+// KDE Includes
+#include <KGlobalSettings>
+#include <KUrl>
+
+// Qt Includes
+#include <QtCore/QPoint>
+#include <QtCore/QSize>
+#include <QtCore/QEvent>
+
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QKeyEvent>
+
+
+
+CompletionWidget::CompletionWidget(QWidget *parent)
+ : QFrame(parent, Qt::ToolTip)
+ , _parent(parent)
+ , _currentIndex(-1)
+ , _searchEngine(SearchEngine::defaultEngine())
+{
+ setFrameStyle(QFrame::Panel);
+ setLayoutDirection(Qt::LeftToRight);
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->setMargin(0);
+ layout->setSpacing(0);
+ setLayout(layout);
+}
+
+
+void CompletionWidget::insertSearchList(const UrlSearchList &list, const QString& text)
+{
+ _list = list;
+ int i = 0;
+ foreach(const UrlSearchItem &item, _list)
+ {
+ ListItem *suggestion = ListItemFactory::create(item, text, this);
+ suggestion->setBackgroundRole(i % 2 ? QPalette::AlternateBase : QPalette::Base);
+ connect(suggestion, SIGNAL(itemClicked(ListItem *, Qt::MouseButton)), this, SLOT(itemChosen(ListItem *, Qt::MouseButton)));
+ connect(this, SIGNAL(nextItemSubChoice()), suggestion, SLOT(nextItemSubChoice()));
+ suggestion->setObjectName(QString::number(i++));
+ layout()->addWidget(suggestion);
+ }
+}
+
+
+void CompletionWidget::sizeAndPosition()
+{
+ setFixedWidth(_parent->width());
+ adjustSize();
+
+ // position
+ QPoint p = _parent->mapToGlobal(QPoint(0, 0));
+ move(p.x(), p.y() + _parent->height());
+}
+
+
+void CompletionWidget::popup()
+{
+ down();
+ sizeAndPosition();
+ if (!isVisible())
+ show();
+}
+
+
+void CompletionWidget::up()
+{
+ // deactivate previous
+ if (_currentIndex != -1)
+ {
+ ListItem *widget = findChild<ListItem *>(QString::number(_currentIndex));
+ widget->deactivate();
+ }
+
+ if (_currentIndex > 0)
+ _currentIndex--;
+ else
+ _currentIndex = layout()->count() - 1;
+
+ // activate "new" current
+ ListItem *widget = findChild<ListItem *>(QString::number(_currentIndex));
+ widget->activate();
+}
+
+
+void CompletionWidget::down()
+{
+ // deactivate previous
+ if (_currentIndex != -1)
+ {
+ ListItem *widget = findChild<ListItem *>(QString::number(_currentIndex));
+ widget->deactivate();
+ }
+
+ if (_currentIndex < _list.count() - 1)
+ _currentIndex++;
+ else
+ _currentIndex = 0;
+
+ // activate "new" current
+ ListItem *widget = findChild<ListItem *>(QString::number(_currentIndex));
+ widget->activate();
+}
+
+
+void CompletionWidget::clear()
+{
+ QLayoutItem *child;
+ while ((child = layout()->takeAt(0)) != 0)
+ {
+ delete child->widget();
+ delete child;
+ }
+ _currentIndex = -1;
+}
+
+
+bool CompletionWidget::eventFilter(QObject *o, QEvent *e)
+{
+ int type = e->type();
+ QWidget *wid = qobject_cast<QWidget*>(o);
+
+ if (o == this)
+ {
+ return false;
+ }
+
+ //hide conditions of the CompletionWidget
+ if (wid
+ && ((wid == _parent && (type == QEvent::Move || type == QEvent::Resize))
+ || ((wid->windowFlags() & Qt::Window)
+ && (type == QEvent::Move || type == QEvent::Hide || type == QEvent::WindowDeactivate)
+ && wid == _parent->window())
+ || (type == QEvent::MouseButtonPress && !isAncestorOf(wid)))
+ )
+ {
+ hide();
+ return false;
+ }
+
+ //actions on the CompletionWidget
+ if (wid && wid->isAncestorOf(_parent) && isVisible())
+ {
+ ListItem *child;
+
+ if (type == QEvent::KeyPress)
+ {
+ QKeyEvent *ev = static_cast<QKeyEvent *>(e);
+ switch (ev->key())
+ {
+ case Qt::Key_Up:
+ case Qt::Key_Backtab:
+ if (ev->modifiers() == Qt::NoButton || (ev->modifiers() & Qt::ShiftModifier))
+ {
+ up();
+ ev->accept();
+ return true;
+ }
+ break;
+
+ case Qt::Key_Down:
+ case Qt::Key_Tab:
+ if (ev->modifiers() == Qt::NoButton)
+ {
+ down();
+ ev->accept();
+ return true;
+ }
+ if (ev->modifiers() & Qt::ControlModifier)
+ {
+ emit nextItemSubChoice();
+ ev->accept();
+ return true;
+ }
+ break;
+
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ child = findChild<ListItem *>(QString::number(_currentIndex));
+ emit chosenUrl(child->url(), Rekonq::CurrentTab);
+ ev->accept();
+ hide();
+ return true;
+
+ case Qt::Key_Escape:
+ hide();
+ return true;
+ }
+ }
+ }
+
+ return QFrame::eventFilter(o, e);
+}
+
+
+void CompletionWidget::setVisible(bool visible)
+{
+ if (visible)
+ {
+ Application::instance()->installEventFilter(this);
+ }
+ else
+ {
+ Application::instance()->removeEventFilter(this);
+ }
+
+
+ QFrame::setVisible(visible);
+}
+
+
+void CompletionWidget::itemChosen(ListItem *item, Qt::MouseButton button)
+{
+ if (button == Qt::MidButton)
+ emit chosenUrl(item->url(), Rekonq::NewCurrentTab);
+ else
+ emit chosenUrl(item->url(), Rekonq::CurrentTab);
+ hide();
+}
+
+
+void CompletionWidget::suggestUrls(const QString &text)
+{
+ QWidget *w = qobject_cast<QWidget *>(parent());
+ if (!w->hasFocus())
+ return;
+
+ if (text.isEmpty())
+ {
+ hide();
+ return;
+ }
+
+ UrlResolver res(text);
+ UrlSearchList list = res.orderedSearchItems();
+ if (list.count() > 0)
+ {
+ clear();
+ insertSearchList(list, text);
+ popup();
+ }
+}
diff --git a/src/urlbar/completionwidget.h b/src/urlbar/completionwidget.h
new file mode 100644
index 00000000..4ce8248d
--- /dev/null
+++ b/src/urlbar/completionwidget.h
@@ -0,0 +1,90 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation; either version 2 of
+* the License or (at your option) version 3 or any later version
+* accepted by the membership of KDE e.V. (or its successor approved
+* by the membership of KDE e.V.), which shall act as a proxy
+* defined in Section 14 of version 3 of the license.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* ============================================================ */
+
+
+#ifndef COMPLETION_WIDGET_H
+#define COMPLETION_WIDGET_H
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// Local Includes
+#include "listitem.h"
+
+// KDE Includes
+#include <KService>
+
+// Qt Includes
+#include <QFrame>
+
+
+class CompletionWidget : public QFrame
+{
+ Q_OBJECT
+
+public:
+ CompletionWidget(QWidget *parent);
+
+ virtual bool eventFilter(QObject *obj, QEvent *ev);
+ void setVisible(bool visible);
+
+ KService::Ptr searchEngine()
+ {
+ return _searchEngine;
+ };
+
+ void setCurrentEngine(KService::Ptr engine)
+ {
+ _searchEngine = engine;
+ };
+
+ void suggestUrls(const QString &text);
+
+private slots:
+ void itemChosen(ListItem *item, Qt::MouseButton = Qt::LeftButton);
+
+signals:
+ void chosenUrl(const KUrl &, Rekonq::OpenType);
+ void nextItemSubChoice();
+
+private:
+ void insertSearchList(const UrlSearchList &list, const QString& text);
+ void popup();
+ void clear();
+
+ void sizeAndPosition();
+ void up();
+ void down();
+
+ QWidget *_parent;
+
+ UrlSearchList _list;
+ int _currentIndex;
+
+ KService::Ptr _searchEngine;
+};
+
+#endif // COMPLETION_WIDGET_H
diff --git a/src/urlbar/lineedit.cpp b/src/urlbar/lineedit.cpp
deleted file mode 100644
index f3c93e8e..00000000
--- a/src/urlbar/lineedit.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* ============================================================
-*
-* This file is a part of the rekonq project
-*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
-* Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com>
-* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr>
-*
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License as
-* published by the Free Software Foundation; either version 2 of
-* the License or (at your option) version 3 or any later version
-* accepted by the membership of KDE e.V. (or its successor approved
-* by the membership of KDE e.V.), which shall act as a proxy
-* defined in Section 14 of version 3 of the license.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* ============================================================ */
-
-
-// Self Includes
-#include "lineedit.h"
-#include "lineedit.moc"
-
-// Qt Includes
-#include <QtGui/QContextMenuEvent>
-#include <QtGui/QFocusEvent>
-#include <QtGui/QKeyEvent>
-
-
-LineEdit::LineEdit(QWidget* parent)
- : KLineEdit(parent)
-{
- setMinimumWidth(200);
- setFocusPolicy(Qt::WheelFocus);
- setHandleSignals(true);
- setClearButtonShown(true);
-}
-
-
-LineEdit::~LineEdit()
-{
-}
-
-
-void LineEdit::keyPressEvent(QKeyEvent *event)
-{
- if (event->key() == Qt::Key_Escape)
- {
- clearFocus();
- event->accept();
- }
-
- KLineEdit::keyPressEvent(event);
-}
-
-
-void LineEdit::mouseDoubleClickEvent(QMouseEvent *)
-{
- selectAll();
-}
diff --git a/src/urlbar/listitem.cpp b/src/urlbar/listitem.cpp
new file mode 100644
index 00000000..c6f75348
--- /dev/null
+++ b/src/urlbar/listitem.cpp
@@ -0,0 +1,427 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation; either version 2 of
+* the License or (at your option) version 3 or any later version
+* accepted by the membership of KDE e.V. (or its successor approved
+* by the membership of KDE e.V.), which shall act as a proxy
+* defined in Section 14 of version 3 of the license.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* ============================================================ */
+
+
+// Self Includes
+#include "listitem.h"
+#include "listitem.moc"
+
+// Auto Includes
+#include "rekonq.h"
+
+// Local Includes
+#include "urlresolver.h"
+#include "application.h"
+#include "websnap.h"
+#include "completionwidget.h"
+#include "searchengine.h"
+
+// KDE Includes
+#include <KIcon>
+#include <KAction>
+
+// Qt Includes
+#include <QActionGroup>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QLabel>
+#include <QSizePolicy>
+#include <QPixmap>
+#include <QStylePainter>
+#include <QMouseEvent>
+#include <QWebSettings>
+#include <QFile>
+
+
+ListItem::ListItem(const UrlSearchItem &item, QWidget *parent)
+ : QWidget(parent)
+ , m_option()
+ , m_url(item.url)
+{
+ setAutoFillBackground(true);
+
+ m_option.initFrom(this);
+ m_option.direction = Qt::LeftToRight;
+
+ QPalette p(palette());
+ p.setColor(QPalette::Base, Qt::white); // TODO: choose the correct color
+
+ p.setColor(QPalette::AlternateBase, QColor(247, 247, 247)); // TODO: choose the correct color
+ setPalette(p);
+
+ deactivate();
+}
+
+
+ListItem::~ListItem()
+{
+ disconnect();
+}
+
+
+
+void ListItem::activate()
+{
+ m_option.state |= QStyle::State_Selected;
+ update();
+}
+
+
+void ListItem::deactivate()
+{
+ m_option.state &= ~QStyle::State_Selected;
+ update();
+}
+
+
+void ListItem::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event);
+
+ if (m_option.state.testFlag(QStyle::State_Selected) || m_option.state.testFlag(QStyle::State_MouseOver))
+ {
+ QPainter painter(this);
+ m_option.rect = QRect(QPoint(), size());
+ style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &m_option, &painter, this);
+ }
+
+ QWidget::paintEvent(event);
+}
+
+
+void ListItem::enterEvent(QEvent *e)
+{
+ m_option.state |= QStyle::State_MouseOver;
+ update();
+ QWidget::enterEvent(e);
+}
+
+
+void ListItem::leaveEvent(QEvent *e)
+{
+ m_option.state &= ~QStyle::State_MouseOver;
+ update();
+ QWidget::enterEvent(e);
+}
+
+
+void ListItem::mousePressEvent(QMouseEvent *e)
+{
+ emit itemClicked(this, e->button());
+ QWidget::mousePressEvent(e);
+}
+
+
+KUrl ListItem::url()
+{
+ return m_url;
+}
+
+
+void ListItem::nextItemSubChoice()
+{
+ //will be override
+}
+
+
+// ---------------------------------------------------------------
+
+
+TypeIconLabel::TypeIconLabel(int type, QWidget *parent)
+ : QLabel(parent)
+{
+ setMinimumWidth(40);
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ hLayout->setMargin(0);
+ hLayout->setAlignment(Qt::AlignRight);
+ setLayout(hLayout);
+
+ if (type & UrlSearchItem::Search) hLayout->addWidget(getIcon("edit-find"));
+ if (type & UrlSearchItem::Browse) hLayout->addWidget(getIcon("applications-internet"));
+ if (type & UrlSearchItem::Bookmark) hLayout->addWidget(getIcon("rating"));
+ if (type & UrlSearchItem::History) hLayout->addWidget(getIcon("view-history"));
+}
+
+
+QLabel *TypeIconLabel::getIcon(QString icon)
+{
+ QLabel *iconLabel = new QLabel(this);
+ iconLabel->setFixedSize(16, 16);
+ QPixmap pixmap = KIcon(icon).pixmap(16);
+ iconLabel->setPixmap(pixmap);
+ return iconLabel;
+}
+
+
+// ---------------------------------------------------------------
+
+
+IconLabel::IconLabel(const QString &icon, QWidget *parent)
+ : QLabel(parent)
+{
+ QPixmap pixmapIcon = Application::icon(KUrl(icon)).pixmap(16);
+ setFixedSize(16, 16);
+ setPixmap(pixmapIcon);
+}
+
+
+// ---------------------------------------------------------------
+
+
+TextLabel::TextLabel(const QString &text, const QString &textToPointOut, QWidget *parent)
+ : QLabel(parent)
+{
+ QString t = text;
+ if (!textToPointOut.isEmpty())
+ t = t.replace(QRegExp('(' + textToPointOut + ')', Qt::CaseInsensitive), "<b>\\1</b>");
+
+ setText(t);
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
+}
+
+
+//--------------------------------------------------------------------------------------------
+
+
+PreviewListItem::PreviewListItem(const UrlSearchItem &item, const QString &text, QWidget *parent)
+ : ListItem(item, parent)
+{
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ hLayout->setSpacing(4);
+
+ QLabel *previewLabelIcon = new QLabel(this);
+ previewLabelIcon->setFixedSize(45, 33);
+ new PreviewLabel(item.url.url(), 38, 29, previewLabelIcon);
+ IconLabel* icon = new IconLabel(item.url.url(), previewLabelIcon);
+ icon->move(27, 16);
+ hLayout->addWidget(previewLabelIcon);
+
+ QVBoxLayout *vLayout = new QVBoxLayout;
+ vLayout->setMargin(0);
+ vLayout->addWidget(new TextLabel(item.title, text, this));
+ vLayout->addWidget(new TextLabel("<i>" + item.url.url() + "</i>", text, this));
+
+ hLayout->addLayout(vLayout);
+
+ hLayout->addWidget(new TypeIconLabel(item.type, this));
+
+ setLayout(hLayout);
+}
+
+
+// ---------------------------------------------------------------
+
+
+PreviewLabel::PreviewLabel(const QString &url, int width, int height, QWidget *parent)
+ : QLabel(parent)
+{
+ setFixedSize(width, height);
+ setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
+
+ KUrl u = KUrl(url);
+ if (WebSnap::existsImage(KUrl(u)))
+ {
+ QPixmap preview;
+ preview.load(WebSnap::imagePathFromUrl(u));
+ setPixmap(preview.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ }
+}
+
+
+// ---------------------------------------------------------------
+
+
+SearchListItem::SearchListItem(const UrlSearchItem &item, const QString &text, QWidget *parent)
+ : ListItem(item, parent)
+ , m_text(text)
+{
+ KService::Ptr currentEngine = SearchEngine::defaultEngine();
+
+ QString query = text;
+ KService::Ptr engine = SearchEngine::fromString(text);
+ if (engine)
+ {
+ query = query.remove(0, text.indexOf(SearchEngine::delimiter()) + 1);
+ }
+ else
+ {
+ engine = currentEngine;
+ }
+
+ m_url = SearchEngine::buildQuery(engine, query);
+
+ m_iconLabel = new IconLabel("edit-find", this); //TODO: get the default engine icon
+ m_titleLabel = new TextLabel(searchItemTitle(engine->name(), query), QString(), this);
+ m_engineBar = new EngineBar(currentEngine, parent);
+
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ hLayout->setSpacing(4);
+
+ hLayout->addWidget(m_iconLabel);
+ hLayout->addWidget(m_titleLabel);
+ hLayout->addWidget(new QLabel(i18n("Engines: "), this));
+ hLayout->addWidget(m_engineBar);
+ hLayout->addWidget(new TypeIconLabel(item.type, this));
+
+ setLayout(hLayout);
+
+ connect(m_engineBar, SIGNAL(searchEngineChanged(KService::Ptr)), this, SLOT(changeSearchEngine(KService::Ptr)));
+}
+
+
+QString SearchListItem::searchItemTitle(QString engine, QString text)
+{
+ return QString(i18nc("%1=search engine, e.g. Google, Wikipedia %2=text to search for", "Search %1 for <b>%2</b>", engine, text));
+}
+
+void SearchListItem::changeSearchEngine(KService::Ptr engine)
+{
+ m_titleLabel->setText(searchItemTitle(engine->name(), m_text));
+ m_iconLabel->setPixmap(Application::icon(KUrl(engine->property("Query").toString())).pixmap(16));
+ m_url = SearchEngine::buildQuery(engine, m_text);
+
+ CompletionWidget *w = qobject_cast<CompletionWidget *>(parent());
+ w->setCurrentEngine(engine);
+}
+
+
+void SearchListItem::nextItemSubChoice()
+{
+ m_engineBar->selectNextEngine();
+}
+
+
+// -----------------------------------------------------------------------------------------------
+
+
+EngineBar::EngineBar(KService::Ptr selectedEngine, QWidget *parent)
+ : KToolBar(parent)
+{
+ setIconSize(QSize(16, 16));
+ setToolButtonStyle(Qt::ToolButtonIconOnly);
+
+ m_engineGroup = new QActionGroup(this);
+ m_engineGroup->setExclusive(true);
+
+ m_engineGroup->addAction(newEngineAction(SearchEngine::defaultEngine(), selectedEngine));
+ foreach(KService::Ptr engine, SearchEngine::favorites())
+ {
+ if (engine->desktopEntryName() != SearchEngine::defaultEngine()->desktopEntryName())
+ {
+ m_engineGroup->addAction(newEngineAction(engine, selectedEngine));
+ }
+ }
+
+ addActions(m_engineGroup->actions());
+}
+
+
+KAction *EngineBar::newEngineAction(KService::Ptr engine, KService::Ptr selectedEngine)
+{
+ QString url = engine->property("Query").toString();
+ KAction *a = new KAction(Application::icon(url), engine->name(), this);
+ a->setCheckable(true);
+ if (engine->desktopEntryName() == selectedEngine->desktopEntryName()) a->setChecked(true);
+ a->setData(engine->entryPath());
+ connect(a, SIGNAL(triggered(bool)), this, SLOT(changeSearchEngine()));
+ return a;
+}
+
+
+void EngineBar::changeSearchEngine()
+{
+ KAction *a = qobject_cast<KAction*>(sender());
+ emit searchEngineChanged(KService::serviceByDesktopPath(a->data().toString()));
+}
+
+
+void EngineBar::selectNextEngine()
+{
+ QList<QAction *> e = m_engineGroup->actions();
+ int i = 0;
+ while (i < e.count() && !e.at(i)->isChecked())
+ {
+ i++;
+ }
+
+ if (i + 1 == e.count())
+ {
+ e.at(0)->setChecked(true);
+ e.at(0)->trigger();
+ }
+ else
+ {
+ e.at(i + 1)->setChecked(true);
+ e.at(i + 1)->trigger();
+ }
+}
+
+
+// ---------------------------------------------------------------
+
+
+BrowseListItem::BrowseListItem(const UrlSearchItem &item, const QString &text, QWidget *parent)
+ : ListItem(item, parent)
+{
+ QString url = text;
+
+ kDebug() << text;
+
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ hLayout->setSpacing(4);
+
+ hLayout->addWidget(new IconLabel(item.url.url(), this));
+ hLayout->addWidget(new TextLabel(item.url.url(), text, this));
+ hLayout->addWidget(new TypeIconLabel(item.type, this));
+
+ setLayout(hLayout);
+}
+
+
+// ---------------------------------------------------------------
+
+
+ListItem *ListItemFactory::create(const UrlSearchItem &item, const QString &text, QWidget *parent)
+{
+ ListItem *newItem;
+
+ if (item.type & UrlSearchItem::Browse)
+ {
+ newItem = new BrowseListItem(item, text, parent);
+ }
+ else
+ {
+ if (item.type & UrlSearchItem::Search)
+ {
+ newItem = new SearchListItem(item, text, parent);
+ }
+ else
+ {
+ newItem = new PreviewListItem(item, text, parent);
+ }
+ }
+
+ return newItem;
+}
diff --git a/src/urlbar/listitem.h b/src/urlbar/listitem.h
new file mode 100644
index 00000000..c26a1893
--- /dev/null
+++ b/src/urlbar/listitem.h
@@ -0,0 +1,220 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation; either version 2 of
+* the License or (at your option) version 3 or any later version
+* accepted by the membership of KDE e.V. (or its successor approved
+* by the membership of KDE e.V.), which shall act as a proxy
+* defined in Section 14 of version 3 of the license.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* ============================================================ */
+
+
+#ifndef LISTITEM_H
+#define LISTITEM_H
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// Local Includes
+#include "urlresolver.h"
+
+// KDE Includes
+#include <KToolBar>
+#include <KService>
+
+// Qt Includes
+#include <QWidget>
+#include <QStyleOptionViewItemV4>
+#include <QLabel>
+
+// Forward Declarations
+class UrlSearchItem;
+class KAction;
+class QActionGroup;
+
+
+class ListItem : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ListItem(const UrlSearchItem &item, QWidget *parent = 0);
+ virtual ~ListItem();
+
+ void activate();
+ void deactivate();
+
+ KUrl url();
+
+public slots:
+ virtual void nextItemSubChoice();
+
+signals:
+ void itemClicked(ListItem *item, Qt::MouseButton);
+
+protected:
+ virtual void paintEvent(QPaintEvent *event);
+ virtual void enterEvent(QEvent *);
+ virtual void leaveEvent(QEvent *);
+ virtual void mousePressEvent(QMouseEvent *e);
+
+private:
+ QStyleOptionViewItemV4 m_option;
+
+protected:
+ KUrl m_url;
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class TypeIconLabel : public QLabel
+{
+ Q_OBJECT
+
+public:
+ explicit TypeIconLabel(int type, QWidget *parent = 0);
+
+private:
+ QLabel *getIcon(QString icon);
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class IconLabel : public QLabel
+{
+ Q_OBJECT
+
+public:
+ explicit IconLabel(const QString &icon, QWidget *parent = 0);
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class TextLabel : public QLabel
+{
+ Q_OBJECT
+
+public:
+ explicit TextLabel(const QString &text, const QString &textToPointOut = QString(), QWidget *parent = 0);
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class EngineBar : public KToolBar
+{
+ Q_OBJECT
+
+public:
+ explicit EngineBar(KService::Ptr selectedEngine, QWidget *parent = 0);
+ void selectNextEngine();
+
+signals:
+ void searchEngineChanged(KService::Ptr engine);
+
+private slots:
+ void changeSearchEngine();
+
+private:
+ KAction *newEngineAction(KService::Ptr engine, KService::Ptr selectedEngine);
+ QActionGroup *m_engineGroup;
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class SearchListItem : public ListItem
+{
+ Q_OBJECT
+
+public:
+ explicit SearchListItem(const UrlSearchItem &item, const QString &text, QWidget *parent = 0);
+
+public slots:
+ virtual void nextItemSubChoice();
+
+private slots:
+ void changeSearchEngine(KService::Ptr engine);
+
+private:
+ QString searchItemTitle(QString engine, QString text);
+
+ TextLabel* m_titleLabel;
+ IconLabel* m_iconLabel;
+ EngineBar* m_engineBar;
+ QString m_text;
+ KService::Ptr m_currentEngine;
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class PreviewListItem : public ListItem
+{
+ Q_OBJECT
+
+public:
+ PreviewListItem(const UrlSearchItem &item, const QString &text, QWidget *parent = 0);
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class PreviewLabel : public QLabel
+{
+ Q_OBJECT
+
+public:
+ PreviewLabel(const QString &url, int width, int height, QWidget *parent = 0);
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class BrowseListItem : public ListItem
+{
+ Q_OBJECT
+
+public:
+ BrowseListItem(const UrlSearchItem &item, const QString &text, QWidget *parent = 0);
+};
+
+
+//-------------------------------------------------------------------------------------------------
+
+
+class ListItemFactory
+{
+public:
+ static ListItem *create(const UrlSearchItem &item, const QString &text, QWidget *parent);
+};
+
+
+#endif
diff --git a/src/urlbar/rsswidget.cpp b/src/urlbar/rsswidget.cpp
new file mode 100644
index 00000000..395d7bab
--- /dev/null
+++ b/src/urlbar/rsswidget.cpp
@@ -0,0 +1,168 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
+*
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation; either version 2 of
+* the License or (at your option) version 3 or any later version
+* accepted by the membership of KDE e.V. (or its successor approved
+* by the membership of KDE e.V.), which shall act as a proxy
+* defined in Section 14 of version 3 of the license.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* ============================================================ */
+
+
+// Auto Includes
+#include "rsswidget.h"
+#include "rsswidget.moc"
+
+// Local includes
+#include "application.h"
+#include "mainwindow.h"
+#include "webtab.h"
+#include "webview.h"
+
+// KDE Includes
+#include <KLocalizedString>
+#include <KIcon>
+#include <KProcess>
+#include <KMessageBox>
+
+// Qt Includes
+#include <QtGui/QFormLayout>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QLabel>
+#include <QtGui/QPushButton>
+
+#include <QtDBus/QDBusInterface>
+#include <QtDBus/QDBusConnectionInterface>
+
+
+
+RSSWidget::RSSWidget(const QMap< KUrl, QString > &map, QWidget *parent)
+ : QFrame(parent, Qt::Popup)
+ , m_map(map)
+{
+ setAttribute(Qt::WA_DeleteOnClose);
+ setFixedWidth(250);
+ setFrameStyle(Panel);
+
+ QFormLayout *layout = new QFormLayout(this);
+ setLayout(layout);
+
+ QLabel *agregator = new QLabel(this);
+ agregator->setText(i18n("Aggregator:"));
+
+ m_agregators = new KComboBox(this);
+ m_agregators->addItem(KIcon("application-rss+xml"), QString("Akregator"));
+ m_agregators->addItem(Application::icon(KUrl("http://google.com/reader")), i18n("Google Reader"));
+
+ layout->addRow(agregator, m_agregators);
+
+
+ QLabel *feed = new QLabel(this);
+ feed->setText(i18n("Feed:"));
+
+ m_feeds = new KComboBox(this);
+
+ foreach(const QString &title, m_map)
+ {
+ m_feeds->addItem(title);
+ }
+
+ layout->addRow(feed, m_feeds);
+
+
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
+ buttonBox->button(QDialogButtonBox::Ok)->setText(i18n("Add Feed"));
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+
+ layout->addWidget(buttonBox);
+}
+
+
+RSSWidget::~RSSWidget()
+{
+ delete m_agregators;
+ delete m_feeds;
+}
+
+
+void RSSWidget::showAt(const QPoint &pos)
+{
+ QPoint p;
+ p.setX(pos.x() - 200);
+ p.setY(pos.y() + 10);
+ move(p);
+ show();
+}
+
+
+void RSSWidget::accept()
+{
+ QString url = m_map.key(m_feeds->currentText()).toMimeDataString();
+
+ if (m_agregators->currentIndex() == 0)
+ addWithAkregator(url);
+ else
+ addWithGoogleReader(url);
+
+ reject();
+}
+
+
+void RSSWidget::reject()
+{
+ close();
+ this->deleteLater();
+}
+
+
+void RSSWidget::addWithGoogleReader(const QString &url)
+{
+ KUrl toLoad = KUrl("http://www.google.com/ig/add?feedurl=" + url);
+ Application::instance()->mainWindow()->currentTab()->view()->load(toLoad);
+}
+
+
+void RSSWidget::addWithAkregator(const QString &url)
+{
+ // Akregator is running
+ if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.akregator"))
+ {
+ QDBusInterface akregator("org.kde.akregator", "/Akregator", "org.kde.akregator.part");
+ QDBusReply<void> reply = akregator.call("addFeedsToGroup", QStringList(url) , i18n("Imported Feeds"));
+
+ if (!reply.isValid())
+ {
+ KMessageBox::error(0, QString(i18n("Could not add stream to akregator, Please add it manually :")
+ + "<br /><br /> <a href=\"" + url + "\">" + url + "</a>"));
+ }
+ }
+ // Akregator is not running
+ else
+ {
+ KProcess proc;
+ proc << "akregator" << "-g" << i18n("Imported Feeds");
+ proc << "-a" << url;
+ if (proc.startDetached() == 0)
+ {
+ KMessageBox::error(0, QString(i18n("There was an error. Please verify Akregator is installed on your system.")
+ + "<br /><br /> <a href=\"" + url + "\">" + url + "</a>"));
+ }
+
+ }
+}
diff --git a/src/urlbar/lineedit.h b/src/urlbar/rsswidget.h
index 67ded052..0272805e 100644
--- a/src/urlbar/lineedit.h
+++ b/src/urlbar/rsswidget.h
@@ -2,9 +2,7 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
-* Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com>
-* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -12,9 +10,9 @@
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
-* by the membership of KDE e.V.), which shall act as a proxy
+* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
-*
+*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -26,30 +24,45 @@
* ============================================================ */
-#ifndef LINEEDIT_H
-#define LINEEDIT_H
+#ifndef RSSWIDGET_H
+#define RSSWIDGET_H
+// Rekonq Includes
+#include "rekonq_defines.h"
// KDE Includes
-#include <KLineEdit>
+#include <KComboBox>
+#include <KUrl>
+
+// Qt Includes
+#include <QtCore/QMap>
-// Forward Declarations
-class QContextMenuEvent;
-class QFocusEvent;
-class QKeyEvent;
+#include <QtGui/QFrame>
-class LineEdit : public KLineEdit
+class RSSWidget : public QFrame
{
Q_OBJECT
public:
- explicit LineEdit(QWidget *parent = 0);
- virtual ~LineEdit();
+ // QMap< feedUrl, feedTitle>
+ RSSWidget(const QMap<KUrl, QString> &map, QWidget *parent = 0);
+ ~RSSWidget();
+
+ void showAt(const QPoint &pos);
+
+private slots:
+ void accept();
+ void reject();
+
+private:
+ void addWithAkregator(const QString &url);
+ void addWithGoogleReader(const QString &url);
+
+ QMap<KUrl, QString> m_map;
-protected:
- virtual void keyPressEvent(QKeyEvent*);
- virtual void mouseDoubleClickEvent(QMouseEvent *);
+ KComboBox *m_agregators;
+ KComboBox *m_feeds;
};
-#endif // LINEEDIT_H
+#endif // RSSWIDGET_H
diff --git a/src/urlbar/urlbar.cpp b/src/urlbar/urlbar.cpp
index be19dae4..e1e542b7 100644
--- a/src/urlbar/urlbar.cpp
+++ b/src/urlbar/urlbar.cpp
@@ -13,9 +13,9 @@
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
-* by the membership of KDE e.V.), which shall act as a proxy
+* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
-*
+*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -31,307 +31,383 @@
#include "urlbar.h"
#include "urlbar.moc"
+// Auto Includes
+#include "rekonq.h"
+
// Local Includes
#include "application.h"
-#include "lineedit.h"
#include "mainwindow.h"
+#include "webtab.h"
+#include "webpage.h"
#include "webview.h"
-#include "historymanager.h"
+#include "completionwidget.h"
// KDE Includes
-#include <KDebug>
#include <KCompletionBox>
-#include <KUrl>
// Qt Includes
-#include <QPainter>
-#include <QPaintEvent>
-#include <QPalette>
-#include <QTimer>
+#include <QtGui/QPainter>
+#include <QtGui/QPaintEvent>
+#include <QtGui/QPalette>
+#include <QtGui/QVBoxLayout>
-QColor UrlBar::s_defaultBaseColor;
+IconButton::IconButton(QWidget *parent)
+ : QToolButton(parent)
+{
+ setToolButtonStyle(Qt::ToolButtonIconOnly);
+ setStyleSheet("IconButton { background-color:transparent; border: none; padding: 0px}");
+ setCursor(Qt::ArrowCursor);
+}
-UrlBar::UrlBar(QWidget *parent)
- : KHistoryComboBox(true, parent)
- , m_lineEdit(new LineEdit)
- , m_progress(0)
+void IconButton::mouseReleaseEvent(QMouseEvent* event)
{
- setUrlDropsEnabled(true);
- setAutoDeleteCompletionObject(true);
+ emit clicked(event->globalPos());
+}
- //cosmetic
- setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- setMinimumWidth(180);
-
- setTrapReturnKey(true);
- setupLineEdit();
+// -----------------------------------------------------------------------------------------------------------
- // add every item to history
- connect(this, SIGNAL(returnPressed(const QString&)), SLOT(activated(const QString&)));
- connect(completionBox(), SIGNAL(activated(const QString&)), SLOT(activated(const QString&)));
- connect(this, SIGNAL(cleared()), SLOT(cleared()));
+UrlBar::UrlBar(QWidget *parent)
+ : KLineEdit(parent)
+ , _tab(0)
+ , _privateMode(false)
+ , _icon(new IconButton(this))
+ , _suggestionTimer(new QTimer(this))
+{
+ // initial style
+ setStyleSheet(QString("UrlBar { padding: 0 0 0 %1px;} ").arg(_icon->sizeHint().width()));
- // setup completion box
- setCompletionObject( Application::historyManager()->completionObject() );
-
- // set dropdown list background
- QPalette p = view()->palette();
- p.setColor(QPalette::Base, palette().color(QPalette::Base));
- view()->setPalette(p);
+ // cosmetic
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ setMinimumWidth(200);
+ setMinimumHeight(26);
- // load urls on activated urlbar signal
- connect(this, SIGNAL(activated(const KUrl&)), Application::instance(), SLOT(loadUrl(const KUrl&)));
-}
+ // doesn't show the clear button
+ setClearButtonShown(false);
+ // trap Key_Enter & Key_Return events, while emitting the returnPressed signal
+ setTrapReturnKey(true);
-UrlBar::~UrlBar()
-{
-}
+ // insert decoded URLs
+ setUrlDropsEnabled(true);
+ // accept focus, via tabbing, clicking & wheeling
+ setFocusPolicy(Qt::WheelFocus);
-void UrlBar::selectAll() const
-{
- lineEdit()->selectAll();
-}
+ // disable completion object (we have our own :) )
+ setCompletionObject(0);
+ _tab = qobject_cast<WebTab *>(parent);
-KUrl UrlBar::url() const
-{
- return m_currentUrl;
-}
+ connect(_tab->view(), SIGNAL(urlChanged(const QUrl &)), this, SLOT(setQUrl(const QUrl &)));
+ connect(_tab->view(), SIGNAL(loadFinished(bool)), this, SLOT(loadFinished()));
+ connect(_tab->view(), SIGNAL(loadStarted()), this, SLOT(clearRightIcons()));
+ // load typed urls
+ connect(this, SIGNAL(returnPressed(const QString &)), this, SLOT(loadTyped(const QString &)));
-KLineEdit *UrlBar::lineEdit() const
-{
- return m_lineEdit;
+ _suggestionTimer->setSingleShot(true);
+ connect(_suggestionTimer, SIGNAL(timeout()), this, SLOT(suggest()));
+
+ activateSuggestions(true);
}
-void UrlBar::setupLineEdit()
+UrlBar::~UrlBar()
{
- // Make m_lineEdit background transparent
- QPalette p = m_lineEdit->palette();
- p.setColor(QPalette::Base, Qt::transparent);
- m_lineEdit->setPalette(p);
-
- if (!s_defaultBaseColor.isValid())
- {
- s_defaultBaseColor = palette().color(QPalette::Base);
- }
-
- setLineEdit(m_lineEdit);
-
- // Make the lineedit consume the Qt::Key_Enter event...
- lineEdit()->setTrapReturnKey(true);
-
- lineEdit()->setHandleSignals(true);
-
- // clear the URL bar
- lineEdit()->clear();
+ activateSuggestions(false);
+ delete _icon;
+ _box.clear();
}
-void UrlBar::setUrl(const QUrl& url)
+void UrlBar::setQUrl(const QUrl& url)
{
- if(url.scheme() == "about")
+ if (url.scheme() == QL1S("about"))
{
- m_currentUrl = KUrl();
+ _icon->setIcon(KIcon("arrow-right"));
+ clear();
setFocus();
}
else
{
- m_currentUrl = KUrl(url);
+ clearFocus();
+ KLineEdit::setUrl(url);
+ setCursorPosition(0);
+ _icon->setIcon(Application::icon(url));
}
- updateUrl();
}
-void UrlBar::setProgress(int progress)
+void UrlBar::activated(const KUrl& url, Rekonq::OpenType type)
{
- m_progress = progress;
- repaint();
+ activateSuggestions(false);
+
+ clearFocus();
+ setUrl(url);
+ Application::instance()->loadUrl(url, type);
}
-void UrlBar::updateUrl()
+void UrlBar::paintEvent(QPaintEvent *event)
{
- // Don't change my typed url...
- // FIXME this is not a proper solution (also if it works...)
- if(hasFocus())
- {
- kDebug() << "Don't change my typed url...";
- return;
- }
-
- KIcon icon;
- if(m_currentUrl.isEmpty())
+ QColor backgroundColor;
+ if (_privateMode)
{
- icon = KIcon("arrow-right");
+ backgroundColor = QColor(220, 220, 220); // light gray
}
- else
+ else
{
- icon = Application::icon(m_currentUrl);
+ backgroundColor = Application::palette().color(QPalette::Base);
}
- if (count())
+ // set background color of UrlBar
+ QPalette p = palette();
+
+ int progr = _tab->progress();
+ if (progr == 0)
{
- changeUrl(0, icon, m_currentUrl);
+ if (_tab->url().scheme() == QL1S("https"))
+ {
+ backgroundColor = QColor(255, 255, 171); // light yellow
+ }
+ p.setBrush(QPalette::Base, backgroundColor);
}
else
{
- insertUrl(0, icon, m_currentUrl);
+ QColor loadingColor = QColor(116, 192, 250);
+
+ QLinearGradient gradient(0, 0, width(), 0);
+ gradient.setColorAt(0, loadingColor);
+ gradient.setColorAt(((double)progr) / 100, backgroundColor);
+ p.setBrush(QPalette::Base, gradient);
}
+ setPalette(p);
- setCurrentIndex(0);
+ // you need this before our code to draw inside the line edit..
+ KLineEdit::paintEvent(event);
- // important security consideration: always display the beginning
- // of the url rather than its end to prevent spoofing attempts.
- // Must be AFTER setCurrentIndex
- if (!hasFocus())
+ if (text().isEmpty())
{
- lineEdit()->setCursorPosition(0);
+ QStyleOptionFrame option;
+ initStyleOption(&option);
+ QRect textRect = style()->subElementRect(QStyle::SE_LineEditContents, &option, this);
+ QPainter painter(this);
+ painter.setPen(Qt::gray);
+ painter.drawText(textRect,
+ Qt::AlignCenter,
+ i18n("Start typing here to search your bookmarks, history and the web...")
+ );
}
}
-void UrlBar::activated(const QString& urlString)
+void UrlBar::keyPressEvent(QKeyEvent *event)
{
- if (urlString.isEmpty())
- return;
+ // this handles the Modifiers + Return key combinations
+ QString currentText = text().trimmed();
+ if ((event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)
+ && !currentText.startsWith(QL1S("http://"), Qt::CaseInsensitive))
+ {
+ QString append;
+ if (event->modifiers() == Qt::ControlModifier)
+ {
+ append = QL1S(".com");
+ }
+ else if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier))
+ {
+ append = QL1S(".org");
+ }
+ else if (event->modifiers() == Qt::ShiftModifier)
+ {
+ append = QL1S(".net");
+ }
- setUrl(urlString);
- emit activated(m_currentUrl);
+ QUrl url(QL1S("http://www.") + currentText);
+ QString host = url.host();
+ if (!host.endsWith(append, Qt::CaseInsensitive))
+ {
+ host += append;
+ url.setHost(host);
+ setText(url.toString());
+ }
+ }
+
+ if (event->key() == Qt::Key_Escape)
+ {
+ clearFocus();
+ event->accept();
+ }
+
+ KLineEdit::keyPressEvent(event);
}
-void UrlBar::cleared()
+void UrlBar::focusInEvent(QFocusEvent *event)
{
- // clear the history on user's request from context menu
- clear();
+ activateSuggestions(true);
+
+ KLineEdit::focusInEvent(event);
}
-void UrlBar::loadFinished(bool)
+void UrlBar::setPrivateMode(bool on)
{
- // reset progress bar after small delay
- m_progress = 0;
- QTimer::singleShot(200, this, SLOT(repaint()));
+ _privateMode = on;
}
-void UrlBar::updateProgress(int progress)
+void UrlBar::dropEvent(QDropEvent *event)
{
- m_progress = progress;
- repaint();
+ KLineEdit::dropEvent(event);
+ activated(text());
}
-void UrlBar::paintEvent(QPaintEvent *event)
+void UrlBar::loadFinished()
{
- // set background color of UrlBar
- QPalette p = palette();
- p.setColor(QPalette::Base, s_defaultBaseColor);
- setPalette(p);
+ if (_tab->progress() != 0)
+ return;
- KHistoryComboBox::paintEvent(event);
+ if (_tab->url().scheme() == QL1S("about"))
+ {
+ update();
+ return;
+ }
- if (!hasFocus())
+ // show KGet downloads??
+ if (ReKonfig::kgetList())
{
- QPainter painter(this);
+ IconButton *bt = addRightIcon(UrlBar::KGet);
+ connect(bt, SIGNAL(clicked(QPoint)), _tab->page(), SLOT(downloadAllContentsWithKGet(QPoint)));
+ }
- QColor loadingColor;
- if (m_currentUrl.scheme() == QLatin1String("https"))
- {
- loadingColor = QColor(248, 248, 100);
- }
- else
- {
- loadingColor = QColor(116, 192, 250);
- }
- painter.setBrush(generateGradient(loadingColor, height()));
- painter.setPen(Qt::transparent);
-
- QRect backgroundRect = lineEdit()->frameGeometry();
- int mid = backgroundRect.width() * m_progress / 100;
- QRect progressRect(backgroundRect.x(), backgroundRect.y(), mid, backgroundRect.height());
- painter.drawRect(progressRect);
- painter.end();
+ // show RSS
+ if (_tab->hasRSSInfo())
+ {
+ IconButton *bt = addRightIcon(UrlBar::RSS);
+ connect(bt, SIGNAL(clicked(QPoint)), _tab, SLOT(showRSSInfo(QPoint)));
+ }
+
+ // show SSL
+ if (_tab->url().scheme() == QL1S("https"))
+ {
+ IconButton *bt = addRightIcon(UrlBar::SSL);
+ connect(bt, SIGNAL(clicked(QPoint)), _tab->page(), SLOT(showSSLInfo(QPoint)));
}
+
+ update();
}
-QSize UrlBar::sizeHint() const
+void UrlBar::loadTyped(const QString &text)
{
- return lineEdit()->sizeHint();
+ activated(KUrl(text));
}
-QLinearGradient UrlBar::generateGradient(const QColor &color, int height)
+void UrlBar::activateSuggestions(bool b)
{
- QColor base = s_defaultBaseColor;
- base.setAlpha(0);
- QColor barColor = color;
- barColor.setAlpha(200);
- QLinearGradient gradient(0, 0, 0, height);
- gradient.setColorAt(0, base);
- gradient.setColorAt(0.25, barColor.lighter(120));
- gradient.setColorAt(0.5, barColor);
- gradient.setColorAt(0.75, barColor.lighter(120));
- gradient.setColorAt(1, base);
- return gradient;
+ if (b)
+ {
+ if (_box.isNull())
+ {
+ _box = new CompletionWidget(this);
+ installEventFilter(_box.data());
+ connect(_box.data(), SIGNAL(chosenUrl(const KUrl &, Rekonq::OpenType)), this, SLOT(activated(const KUrl &, Rekonq::OpenType)));
+
+ // activate suggestions on edit text
+ connect(this, SIGNAL(textChanged(const QString &)), this, SLOT(detectTypedString(const QString &)));
+ }
+ }
+ else
+ {
+ disconnect(this, SIGNAL(textChanged(const QString &)), this, SLOT(detectTypedString(const QString &)));
+ removeEventFilter(_box.data());
+ _box.data()->deleteLater();
+ }
}
-void UrlBar::setBackgroundColor(QColor c)
+void UrlBar::mouseDoubleClickEvent(QMouseEvent *)
{
- s_defaultBaseColor = c;
- repaint();
+ selectAll();
}
-bool UrlBar::isLoading()
+IconButton *UrlBar::addRightIcon(UrlBar::icon ic)
{
- if(m_progress == 0)
+ IconButton *rightIcon = new IconButton(this);
+
+ switch (ic)
{
- return false;
+ case UrlBar::KGet:
+ rightIcon->setIcon(KIcon("download"));
+ rightIcon->setToolTip(i18n("List all links with KGet"));
+ break;
+ case UrlBar::RSS:
+ rightIcon->setIcon(KIcon("application-rss+xml"));
+ rightIcon->setToolTip(i18n("List all available RSS feeds"));
+ break;
+ case UrlBar::SSL:
+ rightIcon->setIcon(KIcon("object-locked"));
+ rightIcon->setToolTip(i18n("Show SSL Info"));
+ break;
+ default:
+ kDebug() << "ERROR.. default non extant case!!";
+ break;
}
- return true;
+
+ _rightIconsList << rightIcon;
+ int iconsCount = _rightIconsList.count();
+ rightIcon->move(width() - 23*iconsCount, 6);
+ rightIcon->show();
+
+ return rightIcon;
}
-void UrlBar::keyPressEvent(QKeyEvent *event)
+
+void UrlBar::clearRightIcons()
{
- QString currentText = m_lineEdit->text().trimmed();
- if ((event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)
- && !currentText.startsWith(QLatin1String("http://"), Qt::CaseInsensitive))
- {
- QString append;
- if (event->modifiers() == Qt::ControlModifier)
- {
- append = QLatin1String(".com");
- }
- else if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier))
- {
- append = QLatin1String(".org");
- }
- else if (event->modifiers() == Qt::ShiftModifier)
- {
- append = QLatin1String(".net");
- }
+ qDeleteAll(_rightIconsList);
+ _rightIconsList.clear();
+}
- QUrl url(QLatin1String("http://www.") + currentText);
- QString host = url.host();
- if (!host.endsWith(append, Qt::CaseInsensitive))
- {
- host += append;
- url.setHost(host);
- m_lineEdit->setText(url.toString());
- }
+
+void UrlBar::resizeEvent(QResizeEvent *event)
+{
+ int newHeight = (height() - 19) / 2;
+ _icon->move(4, newHeight);
+
+ int iconsCount = _rightIconsList.count();
+ int w = width();
+
+ for (int i = 0; i < iconsCount; ++i)
+ {
+ IconButton *bt = _rightIconsList.at(i);
+ bt->move(w - 25*(i + 1), newHeight);
}
- KHistoryComboBox::keyPressEvent(event);
+ KLineEdit::resizeEvent(event);
+
+}
+
+
+void UrlBar::detectTypedString(const QString &typed)
+{
+ Q_UNUSED(typed);
+
+ if(_suggestionTimer->isActive())
+ _suggestionTimer->stop();
+ _suggestionTimer->start(200);
}
+
+void UrlBar::suggest()
+{
+ if(!_box.isNull())
+ _box.data()->suggestUrls( text() );
+} \ No newline at end of file
diff --git a/src/urlbar/urlbar.h b/src/urlbar/urlbar.h
index 8d267b2c..cda8a2e1 100644
--- a/src/urlbar/urlbar.h
+++ b/src/urlbar/urlbar.h
@@ -13,9 +13,9 @@
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
-* by the membership of KDE e.V.), which shall act as a proxy
+* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
-*
+*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -30,69 +30,99 @@
#ifndef URLBAR_H
#define URLBAR_H
-
-// Local Includes
-#include "lineedit.h"
+// Rekonq Includes
+#include "rekonq_defines.h"
// KDE Includes
#include <KUrl>
-#include <KHistoryComboBox>
+#include <KLineEdit>
// Qt Includes
-#include <QUrl>
+#include <QWeakPointer>
+#include <QToolButton>
// Forward Declarations
class QLinearGradient;
class QWidget;
-class KCompletion;
+class CompletionWidget;
+class WebTab;
+class QTimer;
+
+
+class IconButton : public QToolButton
+{
+ Q_OBJECT
+
+public:
+ IconButton(QWidget *parent = 0);
+
+signals:
+ void clicked(QPoint);
+
+protected:
+ void mouseReleaseEvent(QMouseEvent *event);
+
+};
-class UrlBar : public KHistoryComboBox
+// Definitions
+typedef QList<IconButton *> IconButtonPointerList;
+
+
+// ------------------------------------------------------------------------------------
+
+
+class REKONQ_TESTS_EXPORT UrlBar : public KLineEdit
{
Q_OBJECT
public:
- UrlBar(QWidget *parent = 0);
+
+ enum icon
+ {
+ KGet = 0x00000001,
+ RSS = 0x00000010,
+ SSL = 0x00000100,
+ };
+
+ explicit UrlBar(QWidget *parent = 0);
~UrlBar();
- void selectAll() const;
- KUrl url() const;
- QSize sizeHint() const;
- void setBackgroundColor(QColor);
- bool isLoading();
-
- void setProgress(int progress);
+ void setPrivateMode(bool on);
-signals:
- void activated(const KUrl&);
+private slots:
+ void activated(const KUrl& url, Rekonq::OpenType = Rekonq::CurrentTab);
+ void setQUrl(const QUrl &url);
-public slots:
- void setUrl(const QUrl &url);
- void updateProgress(int progress);
- void updateUrl();
+ void loadFinished();
+ void loadTyped(const QString &);
+
+ void clearRightIcons();
-private slots:
- void activated(const QString& url);
- void loadFinished(bool);
- void cleared();
+ void detectTypedString(const QString &);
+ void suggest();
protected:
- virtual void paintEvent(QPaintEvent *event);
- virtual void keyPressEvent(QKeyEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+ void focusInEvent(QFocusEvent *event);
+ void dropEvent(QDropEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *);
+ void resizeEvent(QResizeEvent *);
private:
- void setupLineEdit();
+ IconButton *addRightIcon(UrlBar::icon);
+ void activateSuggestions(bool);
- KLineEdit *lineEdit() const;
+ QWeakPointer<CompletionWidget> _box;
+ WebTab *_tab;
+ bool _privateMode;
- static QLinearGradient generateGradient(const QColor &color, int height);
+ IconButton *_icon;
+ IconButtonPointerList _rightIconsList;
- static QColor s_defaultBaseColor;
-
- LineEdit *m_lineEdit;
-
- KUrl m_currentUrl;
- int m_progress;
+ QTimer *_suggestionTimer;
};
+
#endif
diff --git a/src/urlbar/urlresolver.cpp b/src/urlbar/urlresolver.cpp
new file mode 100644
index 00000000..e86adc62
--- /dev/null
+++ b/src/urlbar/urlresolver.cpp
@@ -0,0 +1,245 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation; either version 2 of
+* the License or (at your option) version 3 or any later version
+* accepted by the membership of KDE e.V. (or its successor approved
+* by the membership of KDE e.V.), which shall act as a proxy
+* defined in Section 14 of version 3 of the license.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* ============================================================ */
+
+
+// Self Includes
+#include "urlresolver.h"
+
+// Local Includes
+#include "application.h"
+#include "historymanager.h"
+#include "bookmarksmanager.h"
+
+// KDE Includes
+#include <KUriFilter>
+#include <KCompletion>
+#include <KService>
+#include <KConfig>
+#include <KConfigGroup>
+
+// Qt Includes
+#include <QByteArray>
+
+// defines
+#define MAX_ELEMENTS 9
+
+
+// NOTE default kurifilter plugin list (at least in my box)
+// 1. "kshorturifilter"
+// 2. "kurisearchfilter"
+// 3. "localdomainurifilter"
+// 4 ."kuriikwsfilter"
+// 5. "fixhosturifilter"
+
+
+bool UrlSearchItem::operator==(const UrlSearchItem &i) const
+{
+ return url == i.url;
+}
+
+
+UrlResolver::UrlResolver(const QString &typedUrl)
+ : _typedString(typedUrl.trimmed())
+{
+}
+
+
+UrlSearchList UrlResolver::orderedSearchItems()
+{
+ // NOTE: the logic here is : "we wanna suggest (at least) 9 elements"
+ // so we have (more or less) 3 from first results (1 from QUrl Resolutions, 2 from
+ // default search engines).
+ // There are 6 remaining: if bookmarkResults + historyResults <= 6, catch all, else
+ // catch first 3 results from the two resulting lists :)
+
+ UrlSearchList list;
+
+ if(isHttp())
+ {
+ list << qurlFromUserInputResolution();
+ list << webSearchesResolution();
+ }
+ else
+ {
+ list << webSearchesResolution();
+ list << qurlFromUserInputResolution();
+ }
+
+
+ if (_typedString.length() >= 2)
+ {
+ int firstResults = list.count();
+ int checkPoint = 9 - firstResults;
+
+ UrlSearchList historyList = historyResolution();
+ int historyResults = historyList.count();
+
+ UrlSearchList bookmarksList = bookmarksResolution();
+ int bookmarkResults = bookmarksList.count();
+
+ if (historyResults + bookmarkResults > checkPoint)
+ {
+ historyList = historyList.mid(0, 3);
+ bookmarksList = bookmarksList.mid(0, 3);
+ }
+
+ QList<UrlSearchItem> common;
+
+ foreach(UrlSearchItem i, historyList)
+ {
+ if (!bookmarksList.contains(i))
+ {
+ list << i;
+ }
+ else
+ {
+ i.type |= UrlSearchItem::Bookmark;
+ common << i;
+ }
+ }
+
+ foreach(const UrlSearchItem &i, common)
+ {
+ list << i;
+ }
+
+ foreach(const UrlSearchItem &i, bookmarksList)
+ {
+ if (!common.contains(i))
+ list << i;
+ }
+ }
+
+ list = placeTypedDomaineNameOnTop(list);
+
+ return list;
+}
+
+
+bool UrlResolver::isHttp()
+{
+ QString ipv4 = "^0*([1-9]?\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.0*([1-9]?\\d|1\\d\\d|2[0-4]\\d|25[0-5])"\
+ "\\.0*([1-9]?\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.0*([1-9]?\\d|1\\d\\d|2[0-4]\\d|25[0-5])";
+
+ QString ipv6 = "^([0-9a-fA-F]{4}|0)(\\:([0-9a-fA-F]{4}|0)){7}";
+
+ QString address = "[\\d\\w-.]+\\.(a[cdefgilmnoqrstuwz]|b[abdefghijmnorstvwyz]|"\
+ "c[acdfghiklmnoruvxyz]|d[ejkmnoz]|e[ceghrst]|f[ijkmnor]|g[abdefghilmnpqrstuwy]|"\
+ "h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|"\
+ "m[acdghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eouw]|"\
+ "s[abcdeghijklmnortuvyz]|t[cdfghjkmnoprtvwz]|u[augkmsyz]|v[aceginu]|w[fs]|"\
+ "y[etu]|z[amw]|aero|arpa|biz|com|coop|edu|info|int|gov|mil|museum|name|net|org|"\
+ "pro)";
+
+ return _typedString.startsWith( QL1S("http://") )
+ || _typedString.startsWith( QL1S("https://") )
+ || (QRegExp(address, Qt::CaseInsensitive).indexIn(_typedString) != -1)
+ || (QRegExp(ipv4, Qt::CaseInsensitive).indexIn(_typedString) != -1)
+ || (QRegExp(ipv6, Qt::CaseInsensitive).indexIn(_typedString) != -1);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// PRIVATE ENGINES
+
+
+// STEP 1 = QUrl from User Input (easily the best solution... )
+UrlSearchList UrlResolver::qurlFromUserInputResolution()
+{
+ UrlSearchList list;
+ QString url2 = _typedString;
+ QUrl urlFromUserInput = QUrl::fromUserInput(url2);
+ if (urlFromUserInput.isValid())
+ {
+ QString gTitle = i18nc("Browse a website", "Browse");
+ UrlSearchItem gItem(UrlSearchItem::Browse, urlFromUserInput, gTitle);
+ list << gItem;
+ }
+
+ return list;
+}
+
+
+// STEP 2 = Web Searches
+UrlSearchList UrlResolver::webSearchesResolution()
+{
+ return UrlSearchList() << UrlSearchItem(UrlSearchItem::Search, KUrl(), QString());
+}
+
+
+// STEP 3 = history completion
+UrlSearchList UrlResolver::historyResolution()
+{
+ UrlSearchList list;
+
+ KCompletion *historyCompletion = Application::historyManager()->completionObject();
+ QStringList historyResults = historyCompletion->substringCompletion(_typedString);
+ Q_FOREACH(const QString &s, historyResults)
+ {
+ UrlSearchItem it(UrlSearchItem::History, KUrl(s), Application::historyManager()->titleForHistoryUrl(s));
+ list << it;
+ }
+
+ return list;
+}
+
+
+// STEP 4 = bookmarks completion
+UrlSearchList UrlResolver::bookmarksResolution()
+{
+ UrlSearchList list;
+
+ KCompletion *bookmarkCompletion = Application::bookmarkProvider()->completionObject();
+ QStringList bookmarkResults = bookmarkCompletion->substringCompletion(_typedString);
+ Q_FOREACH(const QString &s, bookmarkResults)
+ {
+ UrlSearchItem it(UrlSearchItem::Bookmark, KUrl(s), Application::bookmarkProvider()->titleForBookmarkUrl(s));
+ list << it;
+ }
+
+ return list;
+}
+
+
+UrlSearchList UrlResolver::placeTypedDomaineNameOnTop(UrlSearchList list)
+{
+ int i=0;
+ bool found = false;
+
+ while(i<list.count() && !found)
+ {
+ UrlSearchItem item = list.at(i);
+ if (item.url.url().contains("."+_typedString+".") || item.url.url().contains("/"+_typedString+"."))
+ {
+ list.removeAt(i);
+ list.insert(0,item);
+ found = true;
+ }
+ i++;
+ }
+
+ return list;
+}
+
diff --git a/src/urlbar/urlresolver.h b/src/urlbar/urlresolver.h
new file mode 100644
index 00000000..7a8262b3
--- /dev/null
+++ b/src/urlbar/urlresolver.h
@@ -0,0 +1,90 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+*
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation; either version 2 of
+* the License or (at your option) version 3 or any later version
+* accepted by the membership of KDE e.V. (or its successor approved
+* by the membership of KDE e.V.), which shall act as a proxy
+* defined in Section 14 of version 3 of the license.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* ============================================================ */
+
+
+#ifndef URL_RESOLVER_H
+#define URL_RESOLVER_H
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// KDE Includes
+#include <KUrl>
+
+// Qt Includes
+#include <QString>
+#include <QList>
+
+
+class UrlSearchItem
+{
+public:
+
+ enum types
+ {
+ Search = 0x00000001,
+ Browse = 0x00000010,
+ History = 0x00000100,
+ Bookmark = 0x00001000,
+ };
+
+ int type;
+ KUrl url;
+ QString title;
+
+ UrlSearchItem(const int &_type, const KUrl &_url, const QString &_title = QString())
+ : type(_type), url(_url), title(_title)
+ {};
+
+ bool operator==(const UrlSearchItem &i) const;
+};
+
+typedef QList <UrlSearchItem> UrlSearchList;
+
+
+// ----------------------------------------------------------------------
+
+
+class UrlResolver
+{
+public:
+ UrlResolver(const QString &typedUrl);
+
+ UrlSearchList orderedSearchItems();
+
+private:
+ QString _typedString;
+
+ UrlSearchList webSearchesResolution();
+ UrlSearchList historyResolution();
+ UrlSearchList qurlFromUserInputResolution();
+ UrlSearchList bookmarksResolution();
+ UrlSearchList placeTypedDomaineNameOnTop(UrlSearchList list);
+
+ bool isHttp();
+};
+
+#endif // URL_RESOLVER_H