summaryrefslogtreecommitdiff
path: root/src/webtab/webtab.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/webtab/webtab.cpp')
-rw-r--r--src/webtab/webtab.cpp419
1 files changed, 419 insertions, 0 deletions
diff --git a/src/webtab/webtab.cpp b/src/webtab/webtab.cpp
new file mode 100644
index 00000000..457e9006
--- /dev/null
+++ b/src/webtab/webtab.cpp
@@ -0,0 +1,419 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2008-2012 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2011 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 "webtab.h"
+#include "webtab.moc"
+
+// Auto Includes
+#include "rekonq.h"
+
+// Local Includes
+#include "application.h"
+#include "historymanager.h"
+#include "messagebar.h"
+#include "opensearchmanager.h"
+#include "previewselectorbar.h"
+#include "rsswidget.h"
+#include "searchenginebar.h"
+#include "sessionmanager.h"
+#include "syncmanager.h"
+#include "urlbar.h"
+#include "walletbar.h"
+#include "webpage.h"
+#include "websnap.h"
+#include "webshortcutwidget.h"
+
+// KDE Includes
+#include <KWebWallet>
+#include <KStandardShortcut>
+#include <KMenu>
+#include <KActionMenu>
+#include <KWebView>
+#include <KDebug>
+#include <KBuildSycocaProgressDialog>
+
+// Qt Includes
+#include <QVBoxLayout>
+
+
+WebTab::WebTab(QWidget *parent)
+ : QWidget(parent)
+ , m_webView(0)
+ , m_urlBar(new UrlBar(this))
+ , m_progress(0)
+ , m_part(0)
+{
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ QVBoxLayout *l = new QVBoxLayout(this);
+ l->setMargin(0);
+ l->setSpacing(0);
+
+ l->addWidget(view());
+ view()->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ // fix focus handling
+ setFocusProxy(view());
+
+ KWebWallet *wallet = page()->wallet();
+
+ if (wallet)
+ {
+ connect(wallet, SIGNAL(saveFormDataRequested(QString, QUrl)),
+ this, SLOT(createWalletBar(QString, QUrl)));
+ }
+
+ connect(view(), SIGNAL(loadProgress(int)), this, SLOT(updateProgress(int)));
+ connect(view(), SIGNAL(loadStarted()), this, SLOT(resetProgress()));
+ connect(view(), SIGNAL(titleChanged(QString)), this, SIGNAL(titleChanged(QString)));
+ connect(view(), SIGNAL(loadFinished(bool)), this, SLOT(loadFinished()));
+
+ // Session Manager
+ connect(view(), SIGNAL(loadFinished(bool)), rApp->sessionManager(), SLOT(saveSession()));
+}
+
+
+WebTab::~WebTab()
+{
+ m_walletBar.clear();
+ m_previewSelectorBar.clear();
+
+ // NOTE:
+ // Urlbar is reparented when inserted in StackedUrlBar, so we need
+ // to get sure it will be deleted. Deleting it later to ensure everything
+ // will be finished before ;)
+ m_urlBar->deleteLater();
+
+ // Get sure m_part will be deleted
+ delete m_part;
+}
+
+
+WebView *WebTab::view()
+{
+ if (!m_webView)
+ {
+ m_webView = new WebView(this);
+ }
+ return m_webView;
+}
+
+
+WebPage *WebTab::page()
+{
+ if (view())
+ return view()->page();
+
+ return 0;
+}
+
+
+KUrl WebTab::url()
+{
+ if (page() && page()->isOnRekonqPage())
+ {
+ return page()->loadingUrl();
+ }
+
+ if (view())
+ return view()->url();
+
+ kDebug() << "OOPS... NO web classes survived! Returning an empty url...";
+ return KUrl();
+}
+
+
+void WebTab::updateProgress(int p)
+{
+ m_progress = p;
+ emit loadProgressing();
+}
+
+
+void WebTab::resetProgress()
+{
+ m_progress = 1;
+}
+
+
+bool WebTab::isPageLoading()
+{
+ return m_progress != 0 && m_progress != 100;
+}
+
+
+void WebTab::createWalletBar(const QString &key, const QUrl &url)
+{
+ // check if the url is in the wallet blacklist
+ QString urlString = url.toString();
+ QStringList blackList = ReKonfig::walletBlackList();
+ if (blackList.contains(urlString))
+ return;
+
+ KWebWallet *wallet = page()->wallet();
+
+ if (!ReKonfig::passwordSavingEnabled())
+ {
+ wallet->rejectSaveFormDataRequest(key);
+ return;
+ }
+
+ if (m_walletBar.isNull())
+ {
+ m_walletBar = new WalletBar(this);
+ m_walletBar.data()->onSaveFormData(key, url);
+ qobject_cast<QVBoxLayout *>(layout())->insertWidget(0, m_walletBar.data());
+ m_walletBar.data()->animatedShow();
+ }
+ else
+ {
+ disconnect(wallet);
+ qobject_cast<QVBoxLayout *>(layout())->insertWidget(0, m_walletBar.data());
+ m_walletBar.data()->animatedShow();
+ }
+
+ connect(m_walletBar.data(), SIGNAL(saveFormDataAccepted(QString)),
+ wallet, SLOT(acceptSaveFormDataRequest(QString)), Qt::UniqueConnection);
+ connect(m_walletBar.data(), SIGNAL(saveFormDataRejected(QString)),
+ wallet, SLOT(rejectSaveFormDataRequest(QString)), Qt::UniqueConnection);
+
+ // sync passwords
+ connect(m_walletBar.data(), SIGNAL(saveFormDataAccepted(QString)),
+ rApp->syncManager(), SLOT(syncPasswords()), Qt::UniqueConnection);
+}
+
+
+void WebTab::createPreviewSelectorBar(int index)
+{
+ if (m_previewSelectorBar.isNull())
+ {
+ m_previewSelectorBar = new PreviewSelectorBar(index, this);
+ qobject_cast<QVBoxLayout *>(layout())->insertWidget(0, m_previewSelectorBar.data());
+ m_previewSelectorBar.data()->animatedShow();
+ }
+ else
+ {
+ disconnect(m_previewSelectorBar.data());
+ m_previewSelectorBar.data()->setIndex(index);
+ m_previewSelectorBar.data()->animatedHide();
+ }
+
+ connect(page(), SIGNAL(loadStarted()), m_previewSelectorBar.data(), SLOT(loadProgress()), Qt::UniqueConnection);
+ connect(page(), SIGNAL(loadProgress(int)), m_previewSelectorBar.data(), SLOT(loadProgress()), Qt::UniqueConnection);
+ connect(page(), SIGNAL(loadFinished(bool)), m_previewSelectorBar.data(), SLOT(loadFinished()), Qt::UniqueConnection);
+ connect(page()->mainFrame(), SIGNAL(urlChanged(QUrl)), m_previewSelectorBar.data(), SLOT(verifyUrl()), Qt::UniqueConnection);
+}
+
+
+bool WebTab::hasRSSInfo()
+{
+ QWebElementCollection col = page()->mainFrame()->findAllElements("link[type=\"application/rss+xml\"]");
+ col.append(page()->mainFrame()->findAllElements("link[type=\"application/atom+xml\"]"));
+ if (col.count() != 0)
+ return true;
+
+ return false;
+}
+
+
+void WebTab::showRSSInfo(const QPoint &pos)
+{
+ QWebElementCollection col = page()->mainFrame()->findAllElements("link[type=\"application/rss+xml\"]");
+ col.append(page()->mainFrame()->findAllElements("link[type=\"application/atom+xml\"]"));
+
+ QMap<KUrl, QString> map;
+
+ Q_FOREACH(const QWebElement & el, col)
+ {
+ QString urlString;
+ if (el.attribute("href").startsWith(QL1S("http")))
+ urlString = el.attribute("href");
+ else
+ {
+ KUrl u = url();
+ // NOTE
+ // cd() is probably better than setPath() here,
+ // for all those url sites just having a path
+ if (u.cd(el.attribute("href")))
+ urlString = u.toMimeDataString();
+ }
+
+ QString title = el.attribute("title");
+ if (title.isEmpty())
+ title = el.attribute("href");
+
+ map.insert(KUrl(urlString), title);
+ }
+
+ RSSWidget *widget = new RSSWidget(map, window());
+ widget->showAt(pos);
+}
+
+
+void WebTab::hideSelectorBar()
+{
+ m_previewSelectorBar.data()->animatedHide();
+}
+
+
+void WebTab::setPart(KParts::ReadOnlyPart *p, const KUrl &u)
+{
+ if (p)
+ {
+ // Ok, part exists. Insert & show it..
+ m_part = p;
+ qobject_cast<QVBoxLayout *>(layout())->insertWidget(1, p->widget());
+ p->openUrl(u);
+ m_webView->hide();
+
+ emit titleChanged(u.url());
+ return;
+ }
+
+ if (!m_part)
+ return;
+
+ // Part NO more exists. Let's clean up from webtab
+ m_webView->show();
+ qobject_cast<QVBoxLayout *>(layout())->removeWidget(m_part->widget());
+ delete m_part;
+ m_part = 0;
+}
+
+
+KUrl WebTab::extractOpensearchUrl(QWebElement e)
+{
+ QString href = e.attribute(QL1S("href"));
+ KUrl url = KUrl(href);
+ if (!href.contains(":"))
+ {
+ KUrl docUrl = m_webView->url();
+ QString host = docUrl.scheme() + "://" + docUrl.host();
+ if (docUrl.port() != -1)
+ {
+ host += QL1C(':') + QString::number(docUrl.port());
+ }
+ url = KUrl(docUrl, href);
+ }
+ return url;
+}
+
+
+bool WebTab::hasNewSearchEngine()
+{
+ QWebElement e = page()->mainFrame()->findFirstElement(QL1S("head >link[rel=\"search\"][ type=\"application/opensearchdescription+xml\"]"));
+ return !e.isNull() && !rApp->opensearchManager()->engineExists(extractOpensearchUrl(e));
+}
+
+
+void WebTab::showSearchEngine(const QPoint &pos)
+{
+ QWebElement e = page()->mainFrame()->findFirstElement(QL1S("head >link[rel=\"search\"][ type=\"application/opensearchdescription+xml\"]"));
+ QString title = e.attribute(QL1S("title"));
+ if (!title.isEmpty())
+ {
+ WebShortcutWidget *widget = new WebShortcutWidget(window());
+ widget->setWindowFlags(Qt::Popup);
+
+ connect(widget, SIGNAL(webShortcutSet(KUrl, QString, QString)),
+ rApp->opensearchManager(), SLOT(addOpenSearchEngine(KUrl, QString, QString)));
+ connect(rApp->opensearchManager(), SIGNAL(openSearchEngineAdded(QString)),
+ this, SLOT(openSearchEngineAdded()));
+
+ widget->show(extractOpensearchUrl(e), title, pos);
+ }
+}
+
+
+void WebTab::openSearchEngineAdded()
+{
+ // If the providers changed, tell sycoca to rebuild its database...
+ KBuildSycocaProgressDialog::rebuildKSycoca(this);
+
+ disconnect(rApp->opensearchManager(), SIGNAL(openSearchEngineAdded(QString, QString, QString)),
+ this, SLOT(openSearchEngineAdded()));
+}
+
+
+void WebTab::showMessageBar()
+{
+ MessageBar *msgBar = new MessageBar(i18n("It seems rekonq was not closed properly. Do you want "
+ "to restore the last saved session?"), this);
+
+ qobject_cast<QVBoxLayout *>(layout())->insertWidget(0, msgBar);
+ msgBar->animatedShow();
+
+ connect(msgBar, SIGNAL(accepted()), rApp->sessionManager(), SLOT(restoreCrashedSession()));
+}
+
+
+bool WebTab::hasAdBlockedElements()
+{
+ return page()->hasAdBlockedElements();
+}
+
+
+QPixmap WebTab::tabPreview(int width, int height)
+{
+ if (isPageLoading())
+ {
+ // no previews during load
+ return QPixmap();
+ }
+
+ if (!part())
+ {
+ return WebSnap::renderPagePreview(*page(), width, height);
+ }
+ else
+ {
+ QWidget *partWidget = part()->widget();
+ QPixmap partThumb(partWidget->size());
+
+ partWidget->render(&partThumb);
+
+ return partThumb.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ }
+}
+
+
+void WebTab::loadFinished()
+{
+ // add page to history
+ QString pageTitle = (page() && page()->isOnRekonqPage()) ? url().url() : m_webView->title();
+ rApp->historyManager()->addHistoryEntry(url(), pageTitle);
+}
+
+
+void WebTab::showSearchEngineBar()
+{
+ SearchEngineBar *seBar = new SearchEngineBar(this);
+
+ qobject_cast<QVBoxLayout *>(layout())->insertWidget(0, seBar);
+ seBar->animatedShow();
+}