diff options
Diffstat (limited to 'WebKit/qt/Api/qwebpage.cpp')
-rw-r--r-- | WebKit/qt/Api/qwebpage.cpp | 628 |
1 files changed, 524 insertions, 104 deletions
diff --git a/WebKit/qt/Api/qwebpage.cpp b/WebKit/qt/Api/qwebpage.cpp index 8e40339..0acec48 100644 --- a/WebKit/qt/Api/qwebpage.cpp +++ b/WebKit/qt/Api/qwebpage.cpp @@ -27,6 +27,8 @@ #include "qwebframe_p.h" #include "qwebhistory.h" #include "qwebhistory_p.h" +#include "qwebinspector.h" +#include "qwebinspector_p.h" #include "qwebsettings.h" #include "qwebkitversion.h" @@ -64,8 +66,12 @@ #include "PluginDatabase.h" #include "ProgressTracker.h" #include "RefPtr.h" +#include "RenderTextControl.h" +#include "TextIterator.h" #include "HashMap.h" #include "HTMLFormElement.h" +#include "HTMLInputElement.h" +#include "HTMLNames.h" #include "HitTestResult.h" #include "WindowFeatures.h" #include "LocalizedStrings.h" @@ -76,7 +82,6 @@ #include <QBasicTimer> #include <QBitArray> #include <QDebug> -#include <QDesktopServices> #include <QDragEnterEvent> #include <QDragLeaveEvent> #include <QDragMoveEvent> @@ -94,6 +99,7 @@ #include <QSslSocket> #include <QStyle> #include <QSysInfo> +#include <QTextCharFormat> #if QT_VERSION >= 0x040400 #include <QNetworkAccessManager> #include <QNetworkRequest> @@ -108,7 +114,7 @@ void QWEBKIT_EXPORT qt_drt_overwritePluginDirectories() PluginDatabase* db = PluginDatabase::installedPlugins(/* populate */ false); Vector<String> paths; - String qtPath(getenv("QTWEBKIT_PLUGIN_PATH")); + String qtPath(qgetenv("QTWEBKIT_PLUGIN_PATH").data()); qtPath.split(UChar(':'), /* allowEmptyEntries */ false, paths); db->setPluginDirectories(paths); @@ -226,18 +232,6 @@ const char* QWebPagePrivate::editorCommandForWebActions(QWebPage::WebAction acti return 0; } -#ifndef QT_NO_CURSOR -SetCursorEvent::SetCursorEvent(const QCursor& cursor) - : QEvent(static_cast<QEvent::Type>(EventType)) - , m_cursor(cursor) -{} - -QCursor SetCursorEvent::cursor() const -{ - return m_cursor; -} -#endif - // If you change this make sure to also adjust the docs for QWebPage::userAgentForUrl #define WEBKIT_VERSION "527+" @@ -265,45 +259,25 @@ static inline Qt::DropAction dragOpToDropAction(unsigned actions) return result; } -static void initializeApplicationCachePathIfNecessary() -{ -#if ENABLE(OFFLINE_WEB_APPLICATIONS) - static bool initialized = false; - - if (initialized) - return; - - // Determine the path for HTML5 Application Cache DB - QString appCachePath; -#if QT_VERSION >= 0x040500 - appCachePath = QDesktopServices::storageLocation(QDesktopServices::CacheLocation); -#else - appCachePath = QDesktopServices::storageLocation(QDesktopServices::DataLocation); -#endif - - if (appCachePath.isEmpty()) - appCachePath = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName(); - - WebCore::cacheStorage().setCacheDirectory(appCachePath); - initialized = true; -#endif -} - QWebPagePrivate::QWebPagePrivate(QWebPage *qq) : q(qq) + , client(0) , view(0) + , inspectorFrontend(0) + , inspector(0) + , inspectorIsInternalOnly(false) , viewportSize(QSize(0, 0)) + , clickCausedFocus(false) { WebCore::InitializeLoggingChannelsIfNecessary(); JSC::initializeThreading(); - WebCore::FrameLoader::setLocalLoadPolicy(WebCore::FrameLoader::AllowLocalLoadsForLocalAndSubstituteData); - initializeApplicationCachePathIfNecessary(); + WebCore::SecurityOrigin::setLocalLoadPolicy(WebCore::SecurityOrigin::AllowLocalLoadsForLocalAndSubstituteData); chromeClient = new ChromeClientQt(q); contextMenuClient = new ContextMenuClientQt(); editorClient = new EditorClientQt(q); page = new Page(chromeClient, contextMenuClient, editorClient, - new DragClientQt(q), new InspectorClientQt(q)); + new DragClientQt(q), new InspectorClientQt(q), 0); // ### should be configurable page->settings()->setDefaultTextEncodingName("iso-8859-1"); @@ -465,13 +439,13 @@ void QWebPagePrivate::_q_webActionTriggered(bool checked) q->triggerAction(action, checked); } -#ifndef NDEBUG void QWebPagePrivate::_q_cleanupLeakMessages() { +#ifndef NDEBUG // Need this to make leak messages accurate. cache()->setCapacities(0, 0, 0); -} #endif +} void QWebPagePrivate::updateAction(QWebPage::WebAction action) { @@ -487,10 +461,10 @@ void QWebPagePrivate::updateAction(QWebPage::WebAction action) switch (action) { case QWebPage::Back: - enabled = loader->canGoBackOrForward(-1); + enabled = page->canGoBackOrForward(-1); break; case QWebPage::Forward: - enabled = loader->canGoBackOrForward(1); + enabled = page->canGoBackOrForward(1); break; case QWebPage::Stop: enabled = loader->isLoading(); @@ -608,6 +582,18 @@ void QWebPagePrivate::timerEvent(QTimerEvent *ev) q->QObject::timerEvent(ev); } +void QWebPagePrivate::mouseMoveEvent(QGraphicsSceneMouseEvent* ev) +{ + q->setView(ev->widget()); + + WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); + if (!frame->view()) + return; + + bool accepted = frame->eventHandler()->mouseMoved(PlatformMouseEvent(ev, 0)); + ev->setAccepted(accepted); +} + void QWebPagePrivate::mouseMoveEvent(QMouseEvent *ev) { WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); @@ -618,12 +604,40 @@ void QWebPagePrivate::mouseMoveEvent(QMouseEvent *ev) ev->setAccepted(accepted); } +void QWebPagePrivate::mousePressEvent(QGraphicsSceneMouseEvent* ev) +{ + q->setView(ev->widget()); + + WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); + if (!frame->view()) + return; + + if (tripleClickTimer.isActive() + && (ev->pos().toPoint() - tripleClick).manhattanLength() + < QApplication::startDragDistance()) { + mouseTripleClickEvent(ev); + return; + } + + bool accepted = false; + PlatformMouseEvent mev(ev, 1); + // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton + if (mev.button() != NoButton) + accepted = frame->eventHandler()->handleMousePressEvent(mev); + ev->setAccepted(accepted); +} + void QWebPagePrivate::mousePressEvent(QMouseEvent *ev) { WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); if (!frame->view()) return; + RefPtr<WebCore::Node> oldNode; + if (page->focusController()->focusedFrame() + && page->focusController()->focusedFrame()->document()) + oldNode = page->focusController()->focusedFrame()->document()->focusedNode(); + if (tripleClickTimer.isActive() && (ev->pos() - tripleClick).manhattanLength() < QApplication::startDragDistance()) { @@ -637,6 +651,33 @@ void QWebPagePrivate::mousePressEvent(QMouseEvent *ev) if (mev.button() != NoButton) accepted = frame->eventHandler()->handleMousePressEvent(mev); ev->setAccepted(accepted); + + RefPtr<WebCore::Node> newNode; + if (page->focusController()->focusedFrame() + && page->focusController()->focusedFrame()->document()) + newNode = page->focusController()->focusedFrame()->document()->focusedNode(); + + if (newNode && oldNode != newNode) + clickCausedFocus = true; +} + +void QWebPagePrivate::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *ev) +{ + q->setView(ev->widget()); + + WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); + if (!frame->view()) + return; + + bool accepted = false; + PlatformMouseEvent mev(ev, 2); + // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton + if (mev.button() != NoButton) + accepted = frame->eventHandler()->handleMousePressEvent(mev); + ev->setAccepted(accepted); + + tripleClickTimer.start(QApplication::doubleClickInterval(), q); + tripleClick = ev->pos().toPoint(); } void QWebPagePrivate::mouseDoubleClickEvent(QMouseEvent *ev) @@ -656,7 +697,7 @@ void QWebPagePrivate::mouseDoubleClickEvent(QMouseEvent *ev) tripleClick = ev->pos(); } -void QWebPagePrivate::mouseTripleClickEvent(QMouseEvent *ev) +void QWebPagePrivate::mouseTripleClickEvent(QGraphicsSceneMouseEvent *ev) { WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); if (!frame->view()) @@ -670,30 +711,33 @@ void QWebPagePrivate::mouseTripleClickEvent(QMouseEvent *ev) ev->setAccepted(accepted); } -void QWebPagePrivate::mouseReleaseEvent(QMouseEvent *ev) +void QWebPagePrivate::mouseTripleClickEvent(QMouseEvent *ev) { WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); if (!frame->view()) return; bool accepted = false; - PlatformMouseEvent mev(ev, 0); + PlatformMouseEvent mev(ev, 3); // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton if (mev.button() != NoButton) - accepted = frame->eventHandler()->handleMouseReleaseEvent(mev); + accepted = frame->eventHandler()->handleMousePressEvent(mev); ev->setAccepted(accepted); +} +void QWebPagePrivate::handleClipboard(QEvent* ev, Qt::MouseButton button) +{ #ifndef QT_NO_CLIPBOARD if (QApplication::clipboard()->supportsSelection()) { bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode(); Pasteboard::generalPasteboard()->setSelectionMode(true); WebCore::Frame* focusFrame = page->focusController()->focusedOrMainFrame(); - if (ev->button() == Qt::LeftButton) { + if (button == Qt::LeftButton) { if (focusFrame && (focusFrame->editor()->canCopy() || focusFrame->editor()->canDHTMLCopy())) { focusFrame->editor()->copy(); ev->setAccepted(true); } - } else if (ev->button() == Qt::MidButton) { + } else if (button == Qt::MidButton) { if (focusFrame && (focusFrame->editor()->canPaste() || focusFrame->editor()->canDHTMLPaste())) { focusFrame->editor()->paste(); ev->setAccepted(true); @@ -704,12 +748,65 @@ void QWebPagePrivate::mouseReleaseEvent(QMouseEvent *ev) #endif } +void QWebPagePrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev) +{ + q->setView(ev->widget()); + + WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); + if (!frame->view()) + return; + + bool accepted = false; + PlatformMouseEvent mev(ev, 0); + // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton + if (mev.button() != NoButton) + accepted = frame->eventHandler()->handleMouseReleaseEvent(mev); + ev->setAccepted(accepted); + + handleClipboard(ev, ev->button()); + handleSoftwareInputPanel(ev->button()); +} + +void QWebPagePrivate::handleSoftwareInputPanel(Qt::MouseButton button) +{ +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + if (view && view->testAttribute(Qt::WA_InputMethodEnabled) + && button == Qt::LeftButton && qApp->autoSipEnabled()) { + QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel( + view->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel)); + if (!clickCausedFocus || behavior == QStyle::RSIP_OnMouseClick) { + QEvent event(QEvent::RequestSoftwareInputPanel); + QApplication::sendEvent(view, &event); + } + } + + clickCausedFocus = false; +#endif +} + +void QWebPagePrivate::mouseReleaseEvent(QMouseEvent *ev) +{ + WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); + if (!frame->view()) + return; + + bool accepted = false; + PlatformMouseEvent mev(ev, 0); + // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton + if (mev.button() != NoButton) + accepted = frame->eventHandler()->handleMouseReleaseEvent(mev); + ev->setAccepted(accepted); + + handleClipboard(ev, ev->button()); + handleSoftwareInputPanel(ev->button()); +} + #ifndef QT_NO_CONTEXTMENU -void QWebPagePrivate::contextMenuEvent(QContextMenuEvent *ev) +void QWebPagePrivate::contextMenuEvent(const QPoint& globalPos) { QMenu *menu = q->createStandardContextMenu(); if (menu) { - menu->exec(ev->globalPos()); + menu->exec(globalPos); delete menu; } } @@ -734,6 +831,19 @@ QMenu *QWebPage::createStandardContextMenu() } #ifndef QT_NO_WHEELEVENT +void QWebPagePrivate::wheelEvent(QGraphicsSceneWheelEvent* ev) +{ + q->setView(ev->widget()); + + WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); + if (!frame->view()) + return; + + WebCore::PlatformWheelEvent pev(ev); + bool accepted = frame->eventHandler()->handleWheelEvent(pev); + ev->setAccepted(accepted); +} + void QWebPagePrivate::wheelEvent(QWheelEvent *ev) { WebCore::Frame* frame = QWebFramePrivate::core(mainFrame); @@ -804,7 +914,6 @@ void QWebPagePrivate::keyPressEvent(QKeyEvent *ev) { bool handled = false; WebCore::Frame* frame = page->focusController()->focusedOrMainFrame(); - WebCore::Editor* editor = frame->editor(); // we forward the key event to WebCore first to handle potential DOM // defined event handlers and later on end up in EditorClientQt::handleKeyboardEvent // to trigger editor commands via triggerAction(). @@ -816,7 +925,6 @@ void QWebPagePrivate::keyPressEvent(QKeyEvent *ev) if (view) defaultFont = view->font(); QFontMetrics fm(defaultFont); - int fontHeight = fm.height(); if (!handleScrolling(ev, frame)) { switch (ev->key()) { case Qt::Key_Back: @@ -859,7 +967,7 @@ void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev) ev->setAccepted(handled); } -void QWebPagePrivate::focusInEvent(QFocusEvent *ev) +void QWebPagePrivate::focusInEvent(QFocusEvent*) { FocusController *focusController = page->focusController(); Frame *frame = focusController->focusedFrame(); @@ -870,7 +978,7 @@ void QWebPagePrivate::focusInEvent(QFocusEvent *ev) focusController->setFocusedFrame(QWebFramePrivate::core(mainFrame)); } -void QWebPagePrivate::focusOutEvent(QFocusEvent *ev) +void QWebPagePrivate::focusOutEvent(QFocusEvent*) { // only set the focused frame inactive so that we stop painting the caret // and the focus frame. But don't tell the focus controller so that upon @@ -880,7 +988,21 @@ void QWebPagePrivate::focusOutEvent(QFocusEvent *ev) focusController->setFocused(false); } -void QWebPagePrivate::dragEnterEvent(QDragEnterEvent *ev) +void QWebPagePrivate::dragEnterEvent(QGraphicsSceneDragDropEvent* ev) +{ + q->setView(ev->widget()); + +#ifndef QT_NO_DRAGANDDROP + DragData dragData(ev->mimeData(), ev->pos().toPoint(), + QCursor::pos(), dropActionToDragOp(ev->possibleActions())); + Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData)); + ev->setDropAction(action); + if (action != Qt::IgnoreAction) + ev->accept(); +#endif +} + +void QWebPagePrivate::dragEnterEvent(QDragEnterEvent* ev) { #ifndef QT_NO_DRAGANDDROP DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), @@ -892,7 +1014,18 @@ void QWebPagePrivate::dragEnterEvent(QDragEnterEvent *ev) #endif } -void QWebPagePrivate::dragLeaveEvent(QDragLeaveEvent *ev) +void QWebPagePrivate::dragLeaveEvent(QGraphicsSceneDragDropEvent* ev) +{ + q->setView(ev->widget()); + +#ifndef QT_NO_DRAGANDDROP + DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone); + page->dragController()->dragExited(&dragData); + ev->accept(); +#endif +} + +void QWebPagePrivate::dragLeaveEvent(QDragLeaveEvent* ev) { #ifndef QT_NO_DRAGANDDROP DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone); @@ -901,7 +1034,21 @@ void QWebPagePrivate::dragLeaveEvent(QDragLeaveEvent *ev) #endif } -void QWebPagePrivate::dragMoveEvent(QDragMoveEvent *ev) +void QWebPagePrivate::dragMoveEvent(QGraphicsSceneDragDropEvent* ev) +{ + q->setView(ev->widget()); + +#ifndef QT_NO_DRAGANDDROP + DragData dragData(ev->mimeData(), ev->pos().toPoint(), + QCursor::pos(), dropActionToDragOp(ev->possibleActions())); + Qt::DropAction action = dragOpToDropAction(page->dragController()->dragUpdated(&dragData)); + ev->setDropAction(action); + if (action != Qt::IgnoreAction) + ev->accept(); +#endif +} + +void QWebPagePrivate::dragMoveEvent(QDragMoveEvent* ev) { #ifndef QT_NO_DRAGANDDROP DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), @@ -913,7 +1060,18 @@ void QWebPagePrivate::dragMoveEvent(QDragMoveEvent *ev) #endif } -void QWebPagePrivate::dropEvent(QDropEvent *ev) +void QWebPagePrivate::dropEvent(QGraphicsSceneDragDropEvent* ev) +{ +#ifndef QT_NO_DRAGANDDROP + DragData dragData(ev->mimeData(), ev->pos().toPoint(), + QCursor::pos(), dropActionToDragOp(ev->possibleActions())); + Qt::DropAction action = dragOpToDropAction(page->dragController()->performDrag(&dragData)); + if (action != Qt::IgnoreAction) + ev->accept(); +#endif +} + +void QWebPagePrivate::dropEvent(QDropEvent* ev) { #ifndef QT_NO_DRAGANDDROP DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), @@ -924,7 +1082,7 @@ void QWebPagePrivate::dropEvent(QDropEvent *ev) #endif } -void QWebPagePrivate::leaveEvent(QEvent *ev) +void QWebPagePrivate::leaveEvent(QEvent*) { // Fake a mouse move event just outside of the widget, since all // the interesting mouse-out behavior like invalidating scrollbars @@ -967,13 +1125,53 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev) return; } + RenderObject* renderer = 0; + RenderTextControl* renderTextControl = 0; + + if (frame->selection()->rootEditableElement()) + renderer = frame->selection()->rootEditableElement()->shadowAncestorNode()->renderer(); + + if (renderer && renderer->isTextControl()) + renderTextControl = toRenderTextControl(renderer); + + Vector<CompositionUnderline> underlines; + + for (int i = 0; i < ev->attributes().size(); ++i) { + const QInputMethodEvent::Attribute& a = ev->attributes().at(i); + switch (a.type) { + case QInputMethodEvent::TextFormat: { + QTextCharFormat textCharFormat = a.value.value<QTextFormat>().toCharFormat(); + QColor qcolor = textCharFormat.underlineColor(); + underlines.append(CompositionUnderline(a.start, a.length, Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha())), false)); + break; + } + case QInputMethodEvent::Cursor: { + frame->setCaretVisible(a.length); //if length is 0 cursor is invisible + if (a.length > 0) { + RenderObject* caretRenderer = frame->selection()->caretRenderer(); + if (caretRenderer) { + QColor qcolor = a.value.value<QColor>(); + caretRenderer->style()->setColor(Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha()))); + } + } + break; + } +#if QT_VERSION >= 0x040600 + case QInputMethodEvent::Selection: { + if (renderTextControl) { + renderTextControl->setSelectionStart(a.start); + renderTextControl->setSelectionEnd(a.start + a.length); + } + break; + } +#endif + } + } + if (!ev->commitString().isEmpty()) editor->confirmComposition(ev->commitString()); - else { + else if (!ev->preeditString().isEmpty()) { QString preedit = ev->preeditString(); - // ### FIXME: use the provided QTextCharFormat (use color at least) - Vector<CompositionUnderline> underlines; - underlines.append(CompositionUnderline(0, preedit.length(), Color(0, 0, 0), false)); editor->setComposition(preedit, underlines, preedit.length(), 0); } ev->accept(); @@ -1076,44 +1274,140 @@ bool QWebPagePrivate::handleScrolling(QKeyEvent *ev, Frame *frame) */ QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const { + Frame* frame = d->page->focusController()->focusedFrame(); + if (!frame) + return QVariant(); + + WebCore::Editor* editor = frame->editor(); + + RenderObject* renderer = 0; + RenderTextControl* renderTextControl = 0; + + if (frame->selection()->rootEditableElement()) + renderer = frame->selection()->rootEditableElement()->shadowAncestorNode()->renderer(); + + if (renderer && renderer->isTextControl()) + renderTextControl = toRenderTextControl(renderer); + switch (property) { - case Qt::ImMicroFocus: { - Frame *frame = d->page->focusController()->focusedFrame(); - if (frame) + case Qt::ImMicroFocus: { return QVariant(frame->selection()->absoluteCaretBounds()); - return QVariant(); - } - case Qt::ImFont: { - QWebView *webView = qobject_cast<QWebView *>(d->view); - if (webView) - return QVariant(webView->font()); - return QVariant(); - } - case Qt::ImCursorPosition: { - Frame *frame = d->page->focusController()->focusedFrame(); - if (frame) { - VisibleSelection selection = frame->selection()->selection(); - if (selection.isCaret()) - return QVariant(selection.start().deprecatedEditingOffset()); } - return QVariant(); - } - case Qt::ImSurroundingText: { - Frame *frame = d->page->focusController()->focusedFrame(); - if (frame) { - Document *document = frame->document(); - if (document->focusedNode()) - return QVariant(document->focusedNode()->nodeValue()); + case Qt::ImFont: { + if (renderTextControl) { + RenderStyle* renderStyle = renderTextControl->style(); + return QVariant(QFont(renderStyle->font().font())); + } + return QVariant(QFont()); } - return QVariant(); + case Qt::ImCursorPosition: { + if (renderTextControl) { + if (editor->hasComposition()) { + RefPtr<Range> range = editor->compositionRange(); + return QVariant(renderTextControl->selectionEnd() - TextIterator::rangeLength(range.get())); + } + return QVariant(renderTextControl->selectionEnd()); + } + return QVariant(); + } + case Qt::ImSurroundingText: { + if (renderTextControl) { + QString text = renderTextControl->text(); + RefPtr<Range> range = editor->compositionRange(); + if (range) { + text.remove(range->startPosition().offsetInContainerNode(), TextIterator::rangeLength(range.get())); + } + return QVariant(text); + } + return QVariant(); + } + case Qt::ImCurrentSelection: { + if (renderTextControl) { + int start = renderTextControl->selectionStart(); + int end = renderTextControl->selectionEnd(); + if (end > start) + return QVariant(QString(renderTextControl->text()).mid(start,end-start)); + } + return QVariant(); + + } +#if QT_VERSION >= 0x040600 + case Qt::ImAnchorPosition: { + if (renderTextControl) { + if (editor->hasComposition()) { + RefPtr<Range> range = editor->compositionRange(); + return QVariant(renderTextControl->selectionStart() - TextIterator::rangeLength(range.get())); + } + return QVariant(renderTextControl->selectionStart()); + } + return QVariant(); + } + case Qt::ImMaximumTextLength: { + if (frame->selection()->isContentEditable()) { + if (frame->document() && frame->document()->focusedNode()) { + if (frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag)) { + HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(frame->document()->focusedNode()); + return QVariant(inputElement->maxLength()); + } + } + return QVariant(InputElement::s_maximumLength); + } + return QVariant(0); + } +#endif + default: + return QVariant(); } - case Qt::ImCurrentSelection: - return QVariant(selectedText()); - default: - return QVariant(); +} + +/*! + \internal +*/ +void QWebPagePrivate::setInspector(QWebInspector* insp) +{ + if (inspector) + inspector->d->setFrontend(0); + + if (inspectorIsInternalOnly) { + QWebInspector* inspToDelete = inspector; + inspector = 0; + inspectorIsInternalOnly = false; + delete inspToDelete; // Delete after to prevent infinite recursion + } + + inspector = insp; + + // Give inspector frontend web view if previously created + if (inspector && inspectorFrontend) + inspector->d->setFrontend(inspectorFrontend); +} + +/*! + \internal + Returns the inspector and creates it if it wasn't created yet. + The instance created here will not be available through QWebPage's API. +*/ +QWebInspector* QWebPagePrivate::getOrCreateInspector() +{ + if (!inspector) { + QWebInspector* insp = new QWebInspector; + insp->setPage(q); + insp->connect(q, SIGNAL(webInspectorTriggered(const QWebElement&)), SLOT(show())); + insp->show(); // The inspector is expected to be shown on inspection + inspectorIsInternalOnly = true; + + Q_ASSERT(inspector); // Associated through QWebInspector::setPage(q) } + return inspector; } +/*! \internal */ +InspectorController* QWebPagePrivate::inspectorController() +{ + return page->inspectorController(); +} + + /*! \enum QWebPage::FindFlag @@ -1252,6 +1546,8 @@ QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const \since 4.4 \brief The QWebPage class provides an object to view and edit web documents. + \inmodule QtWebKit + QWebPage holds a main frame responsible for web content, settings, the history of navigated links and actions. This class can be used, together with QWebFrame, to provide functionality like QWebView in a widget-less environment. @@ -1321,9 +1617,12 @@ QWebPage::QWebPage(QObject *parent) */ QWebPage::~QWebPage() { + d->createMainFrame(); FrameLoader *loader = d->mainFrame->d->frame->loader(); if (loader) loader->detachFromParent(); + if (d->inspector) + d->inspector->setPage(0); delete d; } @@ -1348,6 +1647,7 @@ QWebFrame *QWebPage::mainFrame() const */ QWebFrame *QWebPage::currentFrame() const { + d->createMainFrame(); return static_cast<WebCore::FrameLoaderClientQt *>(d->page->focusController()->focusedOrMainFrame()->loader()->client())->webFrame(); } @@ -1373,6 +1673,7 @@ QWebFrame* QWebPage::frameAt(const QPoint& pos) const */ QWebHistory *QWebPage::history() const { + d->createMainFrame(); return &d->history; } @@ -1383,8 +1684,10 @@ QWebHistory *QWebPage::history() const */ void QWebPage::setView(QWidget *view) { - d->view = view; - setViewportSize(view ? view->size() : QSize(0, 0)); + if (d->view != view) { + d->view = view; + setViewportSize(view ? view->size() : QSize(0, 0)); + } } /*! @@ -1419,6 +1722,7 @@ void QWebPage::javaScriptConsoleMessage(const QString& message, int lineNumber, */ void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg) { + Q_UNUSED(frame) #ifndef QT_NO_MESSAGEBOX QMessageBox::information(d->view, tr("JavaScript Alert - %1").arg(mainFrame()->url().host()), msg, QMessageBox::Ok); #endif @@ -1432,6 +1736,7 @@ void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg) */ bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg) { + Q_UNUSED(frame) #ifdef QT_NO_MESSAGEBOX return true; #else @@ -1450,6 +1755,7 @@ bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg) */ bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result) { + Q_UNUSED(frame) bool ok = false; #ifndef QT_NO_INPUTDIALOG QString x = QInputDialog::getText(d->view, tr("JavaScript Prompt - %1").arg(mainFrame()->url().host()), msg, QLineEdit::Normal, defaultValue, &ok); @@ -1543,7 +1849,7 @@ static void openNewWindow(const QUrl& url, WebCore::Frame* frame) \sa action() */ -void QWebPage::triggerAction(WebAction action, bool checked) +void QWebPage::triggerAction(WebAction action, bool) { WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame(); if (!frame) @@ -1619,12 +1925,16 @@ void QWebPage::triggerAction(WebAction action, bool checked) case SetTextDirectionRightToLeft: editor->setBaseWritingDirection(RightToLeftWritingDirection); break; - case InspectElement: - if (!d->hitTestResult.isNull()) + case InspectElement: { + QWebElement inspectedElement(QWebElement::enclosingElement(d->hitTestResult.d->innerNonSharedNode.get())); + emit webInspectorTriggered(inspectedElement); + + if (!d->hitTestResult.isNull()) { + d->getOrCreateInspector(); // Make sure the inspector is created d->page->inspectorController()->inspect(d->hitTestResult.d->innerNonSharedNode.get()); - else - d->page->inspectorController()->show(); + } break; + } default: command = QWebPagePrivate::editorCommandForWebActions(action); break; @@ -1725,6 +2035,7 @@ bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest & bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type) #endif { + Q_UNUSED(frame) if (type == NavigationTypeLinkClicked) { switch (d->linkPolicy) { case DontDelegateLinks: @@ -1754,6 +2065,7 @@ bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QWebNetworkReques */ QString QWebPage::selectedText() const { + d->createMainFrame(); return d->page->focusController()->focusedOrMainFrame()->selectedText(); } @@ -2079,24 +2391,42 @@ bool QWebPage::event(QEvent *ev) case QEvent::MouseMove: d->mouseMoveEvent(static_cast<QMouseEvent*>(ev)); break; + case QEvent::GraphicsSceneMouseMove: + d->mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); + break; case QEvent::MouseButtonPress: d->mousePressEvent(static_cast<QMouseEvent*>(ev)); break; + case QEvent::GraphicsSceneMousePress: + d->mousePressEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); + break; case QEvent::MouseButtonDblClick: d->mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev)); break; + case QEvent::GraphicsSceneMouseDoubleClick: + d->mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); + break; case QEvent::MouseButtonRelease: d->mouseReleaseEvent(static_cast<QMouseEvent*>(ev)); break; + case QEvent::GraphicsSceneMouseRelease: + d->mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent*>(ev)); + break; #ifndef QT_NO_CONTEXTMENU case QEvent::ContextMenu: - d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev)); + d->contextMenuEvent(static_cast<QContextMenuEvent*>(ev)->globalPos()); + break; + case QEvent::GraphicsSceneContextMenu: + d->contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent*>(ev)->screenPos()); break; #endif #ifndef QT_NO_WHEELEVENT case QEvent::Wheel: d->wheelEvent(static_cast<QWheelEvent*>(ev)); break; + case QEvent::GraphicsSceneWheel: + d->wheelEvent(static_cast<QGraphicsSceneWheelEvent*>(ev)); + break; #endif case QEvent::KeyPress: d->keyPressEvent(static_cast<QKeyEvent*>(ev)); @@ -2114,15 +2444,27 @@ bool QWebPage::event(QEvent *ev) case QEvent::DragEnter: d->dragEnterEvent(static_cast<QDragEnterEvent*>(ev)); break; + case QEvent::GraphicsSceneDragEnter: + d->dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); + break; case QEvent::DragLeave: d->dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev)); break; + case QEvent::GraphicsSceneDragLeave: + d->dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); + break; case QEvent::DragMove: d->dragMoveEvent(static_cast<QDragMoveEvent*>(ev)); break; + case QEvent::GraphicsSceneDragMove: + d->dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); + break; case QEvent::Drop: d->dropEvent(static_cast<QDropEvent*>(ev)); break; + case QEvent::GraphicsSceneDrop: + d->dropEvent(static_cast<QGraphicsSceneDragDropEvent*>(ev)); + break; #endif case QEvent::InputMethod: d->inputMethodEvent(static_cast<QInputMethodEvent*>(ev)); @@ -2279,6 +2621,7 @@ void QWebPage::updatePositionDependentActions(const QPoint &pos) } } + d->createMainFrame(); WebCore::Frame* focusedFrame = d->page->focusController()->focusedOrMainFrame(); HitTestResult result = focusedFrame->eventHandler()->hitTestResultAtPoint(focusedFrame->view()->windowToContents(pos), /*allowShadowContent*/ false); @@ -2335,15 +2678,56 @@ void QWebPage::updatePositionDependentActions(const QPoint &pos) \since 4.4 \brief The ExtensionOption class provides an extended input argument to QWebPage's extension support. + \inmodule QtWebKit + \sa QWebPage::extension() */ /*! + \class QWebPage::ErrorPageExtensionOption + \since 4.6 + \brief The ErrorPageExtensionOption class describes the option + for the error page extension. + + \inmodule QtWebKit + + The ErrorPageExtensionOption class holds the \a url for which an error occoured as well as + the associated \a frame. + + The error itself is reported by an error \a domain, the \a error code as well as \a errorString. + + \sa QWebPage::ErrorPageExtensionReturn +*/ + +/*! + \class QWebPage::ErrorPageExtensionReturn + \since 4.6 + \brief The ErrorPageExtensionReturn describes the error page, which will be shown for the + frame for which the error occured. + + \inmodule QtWebKit + + The ErrorPageExtensionReturn class holds the data needed for creating an error page. Some are + optional such as \a contentType, which defaults to "text/html", as well as the \a encoding, which + is assumed to be UTF-8 if not indicated otherwise. + + The error page is stored in the \a content byte array, as HTML content. In order to convert a + QString to a byte array, the QString::toUtf8() method can be used. + + External objects such as stylesheets or images referenced in the HTML are located relative to + \a baseUrl. + + \sa QWebPage::ErrorPageExtensionOption, QString::toUtf8() +*/ + +/*! \class QWebPage::ChooseMultipleFilesExtensionOption \since 4.5 \brief The ChooseMultipleFilesExtensionOption class describes the option for the multiple files selection extension. + \inmodule QtWebKit + The ChooseMultipleFilesExtensionOption class holds the frame originating the request and the suggested filenames which might be provided. @@ -2356,6 +2740,8 @@ void QWebPage::updatePositionDependentActions(const QPoint &pos) \brief The ChooseMultipleFilesExtensionReturn describes the return value for the multiple files selection extension. + \inmodule QtWebKit + The ChooseMultipleFilesExtensionReturn class holds the filenames selected by the user when the extension is invoked. @@ -2460,6 +2846,7 @@ QWebSettings *QWebPage::settings() const */ QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& suggestedFile) { + Q_UNUSED(parentFrame) #ifndef QT_NO_FILEDIALOG return QFileDialog::getOpenFileName(d->view, QString::null, suggestedFile); #else @@ -2698,6 +3085,11 @@ QString QWebPage::userAgentForUrl(const QUrl& url) const case QSysInfo::WV_VISTA: ver = "Windows NT 6.0"; break; +#if QT_VERSION > 0x040500 + case QSysInfo::WV_WINDOWS7: + ver = "Windows NT 6.1"; + break; +#endif case QSysInfo::WV_CE: ver = "Windows CE"; break; @@ -2936,6 +3328,24 @@ quint64 QWebPage::bytesReceived() const */ /*! + \fn void QWebPage::webInspectorTriggered(const QWebElement& inspectedElement); + \since 4.6 + + This signal is emitted when the user triggered an inspection through the + context menu. If a QWebInspector is associated to this page, it should be + visible to the user after this signal has been emitted. + + If still no QWebInspector is associated to this QWebPage after the emission + of this signal, a privately owned inspector will be shown to the user. + + \note \a inspectedElement contains the QWebElement under the context menu. + It is not garanteed to be the same as the focused element in the web + inspector. + + \sa QWebInspector +*/ + +/*! \fn void QWebPage::toolBarVisibilityChangeRequested(bool visible) This signal is emitted whenever the visibility of the toolbar in a web browser @@ -2986,6 +3396,16 @@ quint64 QWebPage::bytesReceived() const */ /*! + \since 4.6 + \fn void QWebPage::networkRequestStarted(QWebFrame* frame, QNetworkRequest* request); + \preliminary + + This signal is emitted when a \a frame of the current page requests a web resource. The application + may want to associate the \a request with the \a frame that initiated it by storing the \a frame + as an attribute of the \a request. +*/ + +/*! \fn QWebPagePrivate* QWebPage::handle() const \internal */ |