--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/WebKit/qt/Api/qwebpage.cpp Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,710 @@
+/*
+ Copyright (C) 2007 Trolltech ASA
+ Copyright (C) 2007 Staikos Computing Services Inc.
+ Copyright (C) 2007 Apple Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ This class provides all functionality needed for loading images, style sheets and html
+ pages from the web. It has a memory cache for these objects.
+*/
+
+#include "qwebpage.h"
+#include "qwebframe.h"
+#include "qwebpage_p.h"
+#include "qwebframe_p.h"
+#include "qwebnetworkinterface.h"
+#include "qwebpagehistory.h"
+#include "qwebpagehistory_p.h"
+#include "qwebsettings.h"
+
+#include "Frame.h"
+#include "ChromeClientQt.h"
+#include "ContextMenuClientQt.h"
+#include "DragClientQt.h"
+#include "DragController.h"
+#include "DragData.h"
+#include "EditorClientQt.h"
+#include "Settings.h"
+#include "Page.h"
+#include "FrameLoader.h"
+#include "KURL.h"
+#include "Image.h"
+#include "IconDatabase.h"
+#include "InspectorClientQt.h"
+#include "FocusController.h"
+#include "Editor.h"
+#include "PlatformScrollBar.h"
+#include "PlatformKeyboardEvent.h"
+#include "ProgressTracker.h"
+
+#include <QDebug>
+#include <QDragEnterEvent>
+#include <QDragLeaveEvent>
+#include <QDragMoveEvent>
+#include <QDropEvent>
+#include <QFileDialog>
+#include <QHttpRequestHeader>
+#include <QInputDialog>
+#include <QMessageBox>
+#include <QNetworkProxy>
+#include <QUndoStack>
+#include <QUrl>
+#include <QPainter>
+
+using namespace WebCore;
+
+QWebPagePrivate::QWebPagePrivate(QWebPage *qq)
+ : q(qq), modified(false)
+{
+ q->setMouseTracking(true);
+ q->setFocusPolicy(Qt::ClickFocus);
+ chromeClient = new ChromeClientQt(q);
+ contextMenuClient = new ContextMenuClientQt();
+ editorClient = new EditorClientQt(q);
+ page = new Page(chromeClient, contextMenuClient, editorClient,
+ new DragClientQt(q), new InspectorClientQt());
+
+ undoStack = 0;
+ mainFrame = 0;
+ networkInterface = 0;
+ insideOpenCall = false;
+}
+
+QWebPagePrivate::~QWebPagePrivate()
+{
+ delete undoStack;
+ delete page;
+}
+
+QWebPage::NavigationRequestResponse QWebPagePrivate::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
+{
+ if (insideOpenCall
+ && frame == mainFrame)
+ return QWebPage::AcceptNavigationRequest;
+ return q->navigationRequested(frame, request, type);
+}
+
+void QWebPagePrivate::createMainFrame()
+{
+ if (!mainFrame) {
+ QWebFrameData frameData;
+ frameData.ownerElement = 0;
+ frameData.allowsScrolling = true;
+ frameData.marginWidth = 0;
+ frameData.marginHeight = 0;
+ mainFrame = q->createFrame(0, &frameData);
+ QObject::connect(mainFrame, SIGNAL(titleChanged(const QString&)),
+ q, SIGNAL(titleChanged(const QString&)));
+ QObject::connect(mainFrame, SIGNAL(hoveringOverLink(const QString&, const QString&)),
+ q, SIGNAL(hoveringOverLink(const QString&, const QString&)));
+
+ mainFrame->d->frameView->setFrameGeometry(q->geometry());
+ }
+}
+
+
+QWebPage::QWebPage(QWidget *parent)
+ : QWidget(parent)
+ , d(new QWebPagePrivate(this))
+{
+ setSettings(QWebSettings::global());
+ QPalette pal = palette();
+ pal.setBrush(QPalette::Background, Qt::white);
+
+ setAttribute(Qt::WA_OpaquePaintEvent);
+
+ setPalette(pal);
+ setAcceptDrops(true);
+ connect(this, SIGNAL(loadProgressChanged(int)), this, SLOT(onLoadProgressChanged(int)));
+}
+
+QWebPage::~QWebPage()
+{
+ FrameLoader *loader = d->mainFrame->d->frame->loader();
+ if (loader)
+ loader->detachFromParent();
+ delete d;
+}
+
+QWebFrame *QWebPage::createFrame(QWebFrame *parentFrame, QWebFrameData *frameData)
+{
+ if (parentFrame)
+ return new QWebFrame(parentFrame, frameData);
+ QWebFrame *f = new QWebFrame(this, frameData);
+ return f;
+}
+
+void QWebPage::open(const QUrl &url)
+{
+ open(QWebNetworkRequest(url));
+}
+
+void QWebPage::open(const QWebNetworkRequest &req)
+{
+ d->insideOpenCall = true;
+
+ QUrl url = req.url();
+ QHttpRequestHeader httpHeader = req.httpHeader();
+ QByteArray postData = req.postData();
+
+ WebCore::ResourceRequest request(KURL(url.toString()));
+
+ QString method = httpHeader.method();
+ if (!method.isEmpty())
+ request.setHTTPMethod(method);
+
+ QList<QPair<QString, QString> > values = httpHeader.values();
+ for (int i = 0; i < values.size(); ++i) {
+ const QPair<QString, QString> &val = values.at(i);
+ request.addHTTPHeaderField(val.first, val.second);
+ }
+
+ if (!postData.isEmpty()) {
+ WTF::RefPtr<WebCore::FormData> formData = new WebCore::FormData(postData.constData(), postData.size());
+ request.setHTTPBody(formData);
+ }
+
+ mainFrame()->d->frame->loader()->load(request);
+ d->insideOpenCall = false;
+}
+
+QUrl QWebPage::url() const
+{
+ return QUrl((QString)mainFrame()->d->frame->loader()->url().url());
+}
+
+QString QWebPage::title() const
+{
+ return mainFrame()->title();
+}
+
+QWebFrame *QWebPage::mainFrame() const
+{
+ d->createMainFrame();
+ return d->mainFrame;
+}
+
+QSize QWebPage::sizeHint() const
+{
+ return QSize(800, 600);
+}
+
+void QWebPage::stop()
+{
+ FrameLoader *f = mainFrame()->d->frame->loader();
+ f->stopForUserCancel();
+}
+
+QWebPageHistory QWebPage::history() const
+{
+ WebCore::BackForwardList *lst = d->page->backForwardList();
+ QWebPageHistoryPrivate *priv = new QWebPageHistoryPrivate(lst);
+ return QWebPageHistory(priv);
+}
+
+void QWebPage::goBack()
+{
+ d->page->goBack();
+}
+
+void QWebPage::goForward()
+{
+ d->page->goForward();
+}
+
+void QWebPage::goToHistoryItem(const QWebHistoryItem &item)
+{
+ d->page->goToItem(item.d->item, FrameLoadTypeIndexedBackForward);
+}
+
+void QWebPage::javaScriptConsoleMessage(const QString& message, unsigned int lineNumber, const QString& sourceID)
+{
+}
+
+void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg)
+{
+ //FIXME frame pos...
+ QMessageBox::information(this, title(), msg, QMessageBox::Ok);
+}
+
+bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
+{
+ //FIXME frame pos...
+ return 0 == QMessageBox::information(this, title(), msg, QMessageBox::Yes, QMessageBox::No);
+}
+
+bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
+{
+ //FIXME frame pos...
+ bool ok = false;
+#ifndef QT_NO_INPUTDIALOG
+ QString x = QInputDialog::getText(this, title(), msg, QLineEdit::Normal, defaultValue, &ok);
+ if (ok && result) {
+ *result = x;
+ }
+#endif
+ return ok;
+}
+
+QWebPage *QWebPage::createWindow()
+{
+ return 0;
+}
+
+QWebPage *QWebPage::createModalDialog()
+{
+ return 0;
+}
+
+QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues)
+{
+ Q_UNUSED(classid)
+ Q_UNUSED(url)
+ Q_UNUSED(paramNames)
+ Q_UNUSED(paramValues)
+ return 0;
+}
+
+QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
+{
+ Q_UNUSED(request)
+ return AcceptNavigationRequest;
+}
+
+void QWebPage::setWindowGeometry(const QRect& geom)
+{
+ Q_UNUSED(geom)
+}
+
+bool QWebPage::canCut() const
+{
+ return d->page->focusController()->focusedOrMainFrame()->editor()->canCut();
+}
+
+bool QWebPage::canCopy() const
+{
+ return d->page->focusController()->focusedOrMainFrame()->editor()->canCopy();
+}
+
+bool QWebPage::canPaste() const
+{
+ return d->page->focusController()->focusedOrMainFrame()->editor()->canPaste();
+}
+
+void QWebPage::cut()
+{
+ d->page->focusController()->focusedOrMainFrame()->editor()->cut();
+}
+
+void QWebPage::copy()
+{
+ d->page->focusController()->focusedOrMainFrame()->editor()->copy();
+}
+
+void QWebPage::paste()
+{
+ d->page->focusController()->focusedOrMainFrame()->editor()->paste();
+}
+
+/*!
+ Returns true if the page contains unsubmitted form data.
+*/
+bool QWebPage::isModified() const
+{
+ return d->modified;
+}
+
+
+QUndoStack *QWebPage::undoStack()
+{
+ if (!d->undoStack)
+ d->undoStack = new QUndoStack(this);
+
+ return d->undoStack;
+}
+
+static inline DragOperation dropActionToDragOp(Qt::DropActions actions)
+{
+ unsigned result = 0;
+ if (actions & Qt::CopyAction)
+ result |= DragOperationCopy;
+ if (actions & Qt::MoveAction)
+ result |= DragOperationMove;
+ if (actions & Qt::LinkAction)
+ result |= DragOperationLink;
+ return (DragOperation)result;
+}
+
+static inline Qt::DropAction dragOpToDropAction(unsigned actions)
+{
+ Qt::DropAction result = Qt::IgnoreAction;
+ if (actions & DragOperationCopy)
+ result = Qt::CopyAction;
+ else if (actions & DragOperationMove)
+ result = Qt::MoveAction;
+ else if (actions & DragOperationLink)
+ result = Qt::LinkAction;
+ return result;
+}
+
+void QWebPage::resizeEvent(QResizeEvent *e)
+{
+ QWidget::resizeEvent(e);
+ if (mainFrame()->d->frame && mainFrame()->d->frameView) {
+ mainFrame()->d->frameView->setFrameGeometry(rect());
+ mainFrame()->d->frame->forceLayout();
+ mainFrame()->d->frame->view()->adjustViewSize();
+ }
+}
+
+void QWebPage::paintEvent(QPaintEvent *ev)
+{
+#ifdef QWEBKIT_TIME_RENDERING
+ QTime time;
+ time.start();
+#endif
+
+ QPainter p(this);
+
+ QVector<QRect> vector = ev->region().rects();
+ if (!vector.isEmpty()) {
+ for (int i = 0; i < vector.size(); ++i) {
+ mainFrame()->render(&p, vector.at(i));
+ }
+ } else {
+ mainFrame()->render(&p, ev->rect());
+ }
+
+#ifdef QWEBKIT_TIME_RENDERING
+ int elapsed = time.elapsed();
+ qDebug()<<"paint event on "<<ev->region()<<", took to render = "<<elapsed;
+#endif
+}
+
+void QWebPage::mouseMoveEvent(QMouseEvent *ev)
+{
+ mainFrame()->mouseMoveEvent(ev);
+}
+
+void QWebPage::mousePressEvent(QMouseEvent *ev)
+{
+ mainFrame()->mousePressEvent(ev);
+}
+
+void QWebPage::mouseDoubleClickEvent(QMouseEvent *ev)
+{
+ mainFrame()->mouseDoubleClickEvent(ev);
+}
+
+void QWebPage::mouseReleaseEvent(QMouseEvent *ev)
+{
+ mainFrame()->mouseReleaseEvent(ev);
+}
+
+void QWebPage::wheelEvent(QWheelEvent *ev)
+{
+ mainFrame()->wheelEvent(ev);
+ if (!ev->isAccepted())
+ QWidget::wheelEvent(ev);
+}
+
+void QWebPage::keyPressEvent(QKeyEvent *ev)
+{
+ PlatformKeyboardEvent kevent(ev, false);
+
+ if (!mainFrame()->d->eventHandler)
+ return;
+
+ bool handled = mainFrame()->d->eventHandler->keyEvent(kevent);
+ if (handled) {
+ } else {
+ handled = true;
+ PlatformScrollbar *h, *v;
+ h = mainFrame()->d->horizontalScrollBar();
+ v = mainFrame()->d->verticalScrollBar();
+
+ if (ev == QKeySequence::MoveToNextPage) {
+ if (v)
+ v->setValue(v->value() + height());
+ } else if (ev == QKeySequence::MoveToPreviousPage) {
+ if (v)
+ v->setValue(v->value() - height());
+ } else {
+ switch (ev->key()) {
+ case Qt::Key_Up:
+ if (v)
+ v->setValue(v->value() - 10);
+ break;
+ case Qt::Key_Down:
+ if (v)
+ v->setValue(v->value() + 10);
+ break;
+ case Qt::Key_Left:
+ if (h)
+ h->setValue(h->value() - 10);
+ break;
+ case Qt::Key_Right:
+ if (h)
+ h->setValue(h->value() + 10);
+ break;
+ default:
+ handled = false;
+ break;
+ }
+ }
+ }
+
+ ev->setAccepted(handled);
+}
+
+void QWebPage::keyReleaseEvent(QKeyEvent *ev)
+{
+ if (ev->isAutoRepeat()) {
+ ev->setAccepted(true);
+ return;
+ }
+
+ PlatformKeyboardEvent kevent(ev, true);
+
+ if (!mainFrame()->d->eventHandler)
+ return;
+
+ bool handled = mainFrame()->d->eventHandler->keyEvent(kevent);
+ ev->setAccepted(handled);
+}
+
+void QWebPage::focusInEvent(QFocusEvent *ev)
+{
+ if (ev->reason() != Qt::PopupFocusReason) {
+ mainFrame()->d->frame->page()->focusController()->setFocusedFrame(mainFrame()->d->frame);
+ mainFrame()->d->frame->setIsActive(true);
+ }
+ QWidget::focusInEvent(ev);
+}
+
+void QWebPage::focusOutEvent(QFocusEvent *ev)
+{
+ QWidget::focusOutEvent(ev);
+ if (ev->reason() != Qt::PopupFocusReason) {
+ mainFrame()->d->frame->selectionController()->clear();
+ mainFrame()->d->frame->setIsActive(false);
+ }
+}
+
+bool QWebPage::focusNextPrevChild(bool next)
+{
+ Q_UNUSED(next)
+ return false;
+}
+
+void QWebPage::dragEnterEvent(QDragEnterEvent *ev)
+{
+#ifndef QT_NO_DRAGANDDROP
+ DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(),
+ dropActionToDragOp(ev->possibleActions()));
+ Qt::DropAction action = dragOpToDropAction(d->page->dragController()->dragEntered(&dragData));
+ ev->setDropAction(action);
+ ev->accept();
+#endif
+}
+
+void QWebPage::dragLeaveEvent(QDragLeaveEvent *ev)
+{
+#ifndef QT_NO_DRAGANDDROP
+ DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
+ d->page->dragController()->dragExited(&dragData);
+ ev->accept();
+#endif
+}
+
+void QWebPage::dragMoveEvent(QDragMoveEvent *ev)
+{
+#ifndef QT_NO_DRAGANDDROP
+ DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(),
+ dropActionToDragOp(ev->possibleActions()));
+ Qt::DropAction action = dragOpToDropAction(d->page->dragController()->dragUpdated(&dragData));
+ ev->setDropAction(action);
+ ev->accept();
+#endif
+}
+
+void QWebPage::dropEvent(QDropEvent *ev)
+{
+#ifndef QT_NO_DRAGANDDROP
+ DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(),
+ dropActionToDragOp(ev->possibleActions()));
+ Qt::DropAction action = dragOpToDropAction(d->page->dragController()->performDrag(&dragData));
+ ev->accept();
+#endif
+}
+
+void QWebPage::setNetworkInterface(QWebNetworkInterface *interface)
+{
+ d->networkInterface = interface;
+}
+
+QWebNetworkInterface *QWebPage::networkInterface() const
+{
+ if (d->networkInterface)
+ return d->networkInterface;
+ else
+ return QWebNetworkInterface::defaultInterface();
+}
+
+QPixmap QWebPage::icon() const
+{
+ Image* image = iconDatabase()->iconForPageURL(url().toString(), IntSize(16, 16));
+ if (!image || image->isNull()) {
+ image = iconDatabase()->defaultIcon(IntSize(16, 16));
+ }
+
+ if (!image) {
+ return QPixmap();
+ }
+
+ QPixmap *icon = image->getPixmap();
+ if (!icon) {
+ return QPixmap();
+ }
+ return *icon;
+}
+
+void QWebPage::setSettings(const QWebSettings &settings)
+{
+ WebCore::Settings *wSettings = d->page->settings();
+
+ wSettings->setStandardFontFamily(
+ settings.fontFamily(QWebSettings::StandardFont));
+ wSettings->setFixedFontFamily(
+ settings.fontFamily(QWebSettings::FixedFont));
+ wSettings->setSerifFontFamily(
+ settings.fontFamily(QWebSettings::SerifFont));
+ wSettings->setSansSerifFontFamily(
+ settings.fontFamily(QWebSettings::SansSerifFont));
+ wSettings->setCursiveFontFamily(
+ settings.fontFamily(QWebSettings::CursiveFont));
+ wSettings->setFantasyFontFamily(
+ settings.fontFamily(QWebSettings::FantasyFont));
+
+ wSettings->setMinimumFontSize(settings.minimumFontSize());
+ wSettings->setMinimumLogicalFontSize(settings.minimumLogicalFontSize());
+ wSettings->setDefaultFontSize(settings.defaultFontSize());
+ wSettings->setDefaultFixedFontSize(settings.defaultFixedFontSize());
+
+ wSettings->setLoadsImagesAutomatically(
+ settings.testAttribute(QWebSettings::AutoLoadImages));
+ wSettings->setJavaScriptEnabled(
+ settings.testAttribute(QWebSettings::JavascriptEnabled));
+ wSettings->setJavaScriptCanOpenWindowsAutomatically(
+ settings.testAttribute(QWebSettings::JavascriptCanOpenWindows));
+ wSettings->setJavaEnabled(
+ settings.testAttribute(QWebSettings::JavaEnabled));
+ wSettings->setPluginsEnabled(
+ settings.testAttribute(QWebSettings::PluginsEnabled));
+ wSettings->setPrivateBrowsingEnabled(
+ settings.testAttribute(QWebSettings::PrivateBrowsingEnabled));
+
+ wSettings->setUserStyleSheetLocation(KURL(settings.userStyleSheetLocation()));
+
+ // ### should be configurable
+ wSettings->setDefaultTextEncodingName("iso-8859-1");
+}
+
+QWebSettings QWebPage::settings() const
+{
+ QWebSettings settings;
+ WebCore::Settings *wSettings = d->page->settings();
+
+ settings.setFontFamily(QWebSettings::StandardFont,
+ wSettings->standardFontFamily());
+ settings.setFontFamily(QWebSettings::FixedFont,
+ wSettings->fixedFontFamily());
+ settings.setFontFamily(QWebSettings::SerifFont,
+ wSettings->serifFontFamily());
+ settings.setFontFamily(QWebSettings::SansSerifFont,
+ wSettings->sansSerifFontFamily());
+ settings.setFontFamily(QWebSettings::CursiveFont,
+ wSettings->cursiveFontFamily());
+ settings.setFontFamily(QWebSettings::FantasyFont,
+ wSettings->fantasyFontFamily());
+
+ settings.setMinimumFontSize(wSettings->minimumFontSize());
+ settings.setMinimumLogicalFontSize(wSettings->minimumLogicalFontSize());
+ settings.setDefaultFontSize(wSettings->defaultFontSize());
+ settings.setDefaultFixedFontSize(wSettings->defaultFixedFontSize());
+
+ settings.setAttribute(QWebSettings::AutoLoadImages,
+ wSettings->loadsImagesAutomatically());
+ settings.setAttribute(QWebSettings::JavascriptEnabled,
+ wSettings->isJavaScriptEnabled());
+ settings.setAttribute(QWebSettings::JavascriptCanOpenWindows,
+ wSettings->JavaScriptCanOpenWindowsAutomatically());
+ settings.setAttribute(QWebSettings::JavaEnabled,
+ wSettings->isJavaEnabled());
+ settings.setAttribute(QWebSettings::PluginsEnabled,
+ wSettings->arePluginsEnabled());
+ settings.setAttribute(QWebSettings::PrivateBrowsingEnabled,
+ wSettings->privateBrowsingEnabled());
+
+ settings.setUserStyleSheetLocation(
+ wSettings->userStyleSheetLocation().url());
+
+ return settings;
+}
+
+QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& oldFile)
+{
+ //FIXME frame pos...
+#ifndef QT_NO_FILEDIALOG
+ return QFileDialog::getOpenFileName(this, QString::null, oldFile);
+#else
+ return QString::null;
+#endif
+}
+
+#ifndef QT_NO_NETWORKPROXY
+void QWebPage::setNetworkProxy(const QNetworkProxy& proxy)
+{
+ d->networkProxy = proxy;
+}
+
+QNetworkProxy QWebPage::networkProxy() const
+{
+ return d->networkProxy;
+}
+#endif
+
+QString QWebPage::userAgentStringForUrl(const QUrl& forUrl) const {
+ Q_UNUSED(forUrl)
+ return QLatin1String("Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/418.9.1 (KHTML, like Gecko) Safari/419.3 Qt");
+}
+
+
+void QWebPage::onLoadProgressChanged(int) {
+ d->m_totalBytes = d->page->progress()->totalPageAndResourceBytesToLoad();
+ d->m_bytesReceived = d->page->progress()->totalBytesReceived();
+}
+
+
+quint64 QWebPage::totalBytes() const {
+ return d->m_bytesReceived;
+}
+
+
+quint64 QWebPage::bytesReceived() const {
+ return d->m_totalBytes;
+}