/* ============================================================ * * This file is a part of the rekonq project * * Copyright (C) 2008-2012 by Andrea Diamantini * Copyright (C) 2009-2011 by Lionel Chauvin * * * 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 . * * ============================================================ */ // 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 #include #include #include #include #include #include #include #include #include // Qt Includes #include 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; } WebWindow *WebTab::webWindow() { WebWindow *w = qobject_cast(parent()); return w; } 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(layout())->insertWidget(0, m_walletBar.data()); m_walletBar.data()->animatedShow(); } else { disconnect(wallet); qobject_cast(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(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 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(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(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(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(layout())->insertWidget(0, seBar); seBar->animatedShow(); } void WebTab::printFrame() { if (page()->isOnRekonqPage()) { // trigger print part action instead of ours.. KParts::ReadOnlyPart *p = part(); if (p) { KParts::BrowserExtension *ext = p->browserExtension(); if (ext) { KParts::BrowserExtension::ActionSlotMap *actionSlotMap = KParts::BrowserExtension::actionSlotMapPtr(); connect(this, SIGNAL(triggerPartPrint()), ext, actionSlotMap->value("print")); emit triggerPartPrint(); return; } } } QWebFrame *printFrame = 0; if (frame == 0) { printFrame = page()->mainFrame(); } else { printFrame = frame; } QPrinter printer; printer.setDocName(printFrame->title()); QPrintDialog *printDialog = KdePrint::createPrintDialog(&printer, this); if (printDialog) //check if the Dialog was created { if (printDialog->exec()) printFrame->print(&printer); delete printDialog; } }