| /* |
| 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., 59 Temple Place - Suite 330, |
| Boston, MA 02111-1307, 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 <QDebug> |
| #include <QDragEnterEvent> |
| #include <QDragLeaveEvent> |
| #include <QDragMoveEvent> |
| #include <QDropEvent> |
| #include <QFileDialog> |
| #include <QHttpRequestHeader> |
| #include <QInputDialog> |
| #include <QMessageBox> |
| #include <QUndoStack> |
| #include <QUrl> |
| #include <QVBoxLayout> |
| |
| using namespace WebCore; |
| |
| QWebPagePrivate::QWebPagePrivate(QWebPage *qq) |
| : q(qq), modified(false) |
| { |
| q->setFocusPolicy(Qt::ClickFocus); |
| chromeClient = new ChromeClientQt(q); |
| contextMenuClient = new ContextMenuClientQt(); |
| editorClient = new EditorClientQt(q); |
| page = new Page(chromeClient, contextMenuClient, editorClient, |
| new DragClientQt(q)); |
| |
| undoStack = 0; |
| mainFrame = 0; |
| networkInterface = 0; |
| insideOpenCall = false; |
| } |
| |
| QWebPagePrivate::~QWebPagePrivate() |
| { |
| delete undoStack; |
| delete page; |
| } |
| |
| QWebPage::NavigationRequestResponse QWebPagePrivate::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request) |
| { |
| if (insideOpenCall |
| && frame == mainFrame) |
| return QWebPage::AcceptNavigationRequest; |
| return q->navigationRequested(frame, request); |
| } |
| |
| void QWebPagePrivate::createMainFrame() |
| { |
| if (!mainFrame) { |
| QWebFrameData frameData; |
| frameData.ownerElement = 0; |
| frameData.allowsScrolling = true; |
| frameData.marginWidth = 0; |
| frameData.marginHeight = 0; |
| mainFrame = q->createFrame(0, &frameData); |
| layout->addWidget(mainFrame); |
| } |
| } |
| |
| |
| QWebPage::QWebPage(QWidget *parent) |
| : QWidget(parent) |
| , d(new QWebPagePrivate(this)) |
| { |
| setSettings(QWebSettings::global()); |
| d->layout = new QVBoxLayout(this); |
| d->layout->setMargin(0); |
| d->layout->setSpacing(0); |
| setAcceptDrops(true); |
| } |
| |
| 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); |
| connect(f, SIGNAL(titleChanged(const QString&)), |
| SIGNAL(titleChanged(const QString&))); |
| connect(f, SIGNAL(hoveringOverLink(const QString&, const QString&)), |
| SIGNAL(hoveringOverLink(const QString&, const QString&))); |
| 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) |
| { |
| QMessageBox::information(frame, title(), msg, QMessageBox::Ok); |
| } |
| |
| bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg) |
| { |
| return 0 == QMessageBox::information(frame, title(), msg, QMessageBox::Yes, QMessageBox::No); |
| } |
| |
| bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result) |
| { |
| bool ok = false; |
| QString x = QInputDialog::getText(frame, title(), msg, QLineEdit::Normal, defaultValue, &ok); |
| if (ok && result) { |
| *result = x; |
| } |
| return ok; |
| } |
| |
| QWebPage *QWebPage::createWindow() |
| { |
| return 0; |
| } |
| |
| QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request) |
| { |
| Q_UNUSED(request) |
| return AcceptNavigationRequest; |
| } |
| |
| void QWebPage::setWindowGeometry(const QRect& geom) |
| { |
| Q_UNUSED(geom) |
| } |
| |
| /*! |
| 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::dragEnterEvent(QDragEnterEvent *ev) |
| { |
| 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(); |
| } |
| |
| void QWebPage::dragLeaveEvent(QDragLeaveEvent *ev) |
| { |
| DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone); |
| d->page->dragController()->dragExited(&dragData); |
| ev->accept(); |
| } |
| |
| void QWebPage::dragMoveEvent(QDragMoveEvent *ev) |
| { |
| 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(); |
| } |
| |
| void QWebPage::dropEvent(QDropEvent *ev) |
| { |
| DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), |
| dropActionToDragOp(ev->possibleActions())); |
| Qt::DropAction action = dragOpToDropAction(d->page->dragController()->performDrag(&dragData)); |
| ev->accept(); |
| } |
| |
| 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) { |
| return QPixmap(); |
| } |
| |
| QPixmap *icon = image->getPixmap(); |
| Q_ASSERT(icon); |
| Q_ASSERT(!icon->isNull()); |
| 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())); |
| } |
| |
| 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) |
| { |
| return QFileDialog::getOpenFileName(parentFrame, QString::null, oldFile); |
| } |
| |