2011-02-06 Robert Hogan <robert@webkit.org>
[WebKit-https.git] / Source / WebKit / qt / WebCoreSupport / ChromeClientQt.cpp
1 /*
2  * Copyright (C) 2006 Zack Rusin <zack@kde.org>
3  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
4  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "ChromeClientQt.h"
32
33 #include "ApplicationCacheStorage.h"
34 #include "DatabaseTracker.h"
35 #include "FileChooser.h"
36 #include "Frame.h"
37 #include "FrameLoadRequest.h"
38 #include "FrameLoader.h"
39 #include "FrameLoaderClientQt.h"
40 #include "FrameView.h"
41 #include "Geolocation.h"
42 #if USE(ACCELERATED_COMPOSITING)
43 #include "GraphicsLayer.h"
44 #endif
45 #include "GeolocationPermissionClientQt.h"
46 #include "HitTestResult.h"
47 #include "Icon.h"
48 #include "NavigationAction.h"
49 #include "NetworkingContext.h"
50 #include "NotImplemented.h"
51 #include "NotificationPresenterClientQt.h"
52 #include "PageClientQt.h"
53 #include "PopupMenuQt.h"
54 #if defined(Q_WS_MAEMO_5)
55 #include "QtMaemoWebPopup.h"
56 #else
57 #include "QtFallbackWebPopup.h"
58 #endif
59 #include "QWebPageClient.h"
60 #include "ScrollbarTheme.h"
61 #include "SearchPopupMenuQt.h"
62 #include "SecurityOrigin.h"
63 #include "ViewportArguments.h"
64 #include "WindowFeatures.h"
65
66 #include "qgraphicswebview.h"
67 #include "qwebframe_p.h"
68 #include "qwebpage.h"
69 #include "qwebpage_p.h"
70 #include "qwebsecurityorigin.h"
71 #include "qwebsecurityorigin_p.h"
72 #include "qwebview.h"
73 #include <qdebug.h>
74 #include <qeventloop.h>
75 #include <qtextdocument.h>
76 #include <qtooltip.h>
77 #include <wtf/OwnPtr.h>
78
79 #if ENABLE(VIDEO) && ENABLE(QT_MULTIMEDIA)
80 #include "FullScreenVideoQt.h"
81 #include "HTMLMediaElement.h"
82 #include "HTMLNames.h"
83 #include "HTMLVideoElement.h"
84 #include "MediaPlayerPrivateQt.h"
85 #endif
86
87 namespace WebCore {
88
89 bool ChromeClientQt::dumpVisitedLinksCallbacks = false;
90
91 ChromeClientQt::ChromeClientQt(QWebPage* webPage)
92     : m_webPage(webPage)
93     , m_eventLoop(0)
94 #if ENABLE(VIDEO) && ENABLE(QT_MULTIMEDIA)
95     , m_fullScreenVideo(0)
96 #endif
97 {
98     toolBarsVisible = statusBarVisible = menuBarVisible = true;
99 }
100
101 ChromeClientQt::~ChromeClientQt()
102 {
103     if (m_eventLoop)
104         m_eventLoop->exit();
105
106 #if ENABLE(VIDEO) && ENABLE(QT_MULTIMEDIA)
107     delete m_fullScreenVideo;
108 #endif
109 }
110
111 void ChromeClientQt::setWindowRect(const FloatRect& rect)
112 {
113     if (!m_webPage)
114         return;
115     emit m_webPage->geometryChangeRequested(QRect(qRound(rect.x()), qRound(rect.y()),
116                             qRound(rect.width()), qRound(rect.height())));
117 }
118
119 /*!
120     windowRect represents the rect of the Window, including all interface elements
121     like toolbars/scrollbars etc. It is used by the viewport meta tag as well as
122     by the DOM Window object: outerHeight(), outerWidth(), screenX(), screenY().
123 */
124 FloatRect ChromeClientQt::windowRect()
125 {
126     if (!platformPageClient())
127         return FloatRect();
128     return platformPageClient()->windowRect();
129 }
130
131 FloatRect ChromeClientQt::pageRect()
132 {
133     if (!m_webPage)
134         return FloatRect();
135     return FloatRect(QRectF(QPointF(0, 0), m_webPage->viewportSize()));
136 }
137
138 float ChromeClientQt::scaleFactor()
139 {
140     if (!m_webPage)
141         return 1;
142     return m_webPage->d->pixelRatio;
143 }
144
145 void ChromeClientQt::focus()
146 {
147     if (!m_webPage)
148         return;
149     QWidget* view = m_webPage->view();
150     if (!view)
151         return;
152
153     view->setFocus();
154 }
155
156
157 void ChromeClientQt::unfocus()
158 {
159     if (!m_webPage)
160         return;
161     QWidget* view = m_webPage->view();
162     if (!view)
163         return;
164     view->clearFocus();
165 }
166
167 bool ChromeClientQt::canTakeFocus(FocusDirection)
168 {
169     // This is called when cycling through links/focusable objects and we
170     // reach the last focusable object. Then we want to claim that we can
171     // take the focus to avoid wrapping.
172     return true;
173 }
174
175 void ChromeClientQt::takeFocus(FocusDirection)
176 {
177     // don't do anything. This is only called when cycling to links/focusable objects,
178     // which in turn is called from focusNextPrevChild. We let focusNextPrevChild
179     // call QWidget::focusNextPrevChild accordingly, so there is no need to do anything
180     // here.
181 }
182
183
184 void ChromeClientQt::focusedNodeChanged(Node*)
185 {
186 }
187
188 void ChromeClientQt::focusedFrameChanged(Frame*)
189 {
190 }
191
192 Page* ChromeClientQt::createWindow(Frame*, const FrameLoadRequest& request, const WindowFeatures& features, const NavigationAction&)
193 {
194     QWebPage* newPage = m_webPage->createWindow(features.dialog ? QWebPage::WebModalDialog : QWebPage::WebBrowserWindow);
195     if (!newPage)
196         return 0;
197
198     // A call to QWebPage::mainFrame() implicitly creates the main frame.
199     // Make sure it exists, as WebCore expects it when returning from this call.
200     newPage->mainFrame();
201     return newPage->d->page;
202 }
203
204 void ChromeClientQt::show()
205 {
206     if (!m_webPage)
207         return;
208     QWidget* view = m_webPage->view();
209     if (!view)
210         return;
211     view->window()->show();
212 }
213
214
215 bool ChromeClientQt::canRunModal()
216 {
217     return true;
218 }
219
220
221 void ChromeClientQt::runModal()
222 {
223     m_eventLoop = new QEventLoop();
224     QEventLoop* eventLoop = m_eventLoop;
225     m_eventLoop->exec();
226     delete eventLoop;
227 }
228
229
230 void ChromeClientQt::setToolbarsVisible(bool visible)
231 {
232     toolBarsVisible = visible;
233     emit m_webPage->toolBarVisibilityChangeRequested(visible);
234 }
235
236
237 bool ChromeClientQt::toolbarsVisible()
238 {
239     return toolBarsVisible;
240 }
241
242
243 void ChromeClientQt::setStatusbarVisible(bool visible)
244 {
245     emit m_webPage->statusBarVisibilityChangeRequested(visible);
246     statusBarVisible = visible;
247 }
248
249
250 bool ChromeClientQt::statusbarVisible()
251 {
252     return statusBarVisible;
253 }
254
255
256 void ChromeClientQt::setScrollbarsVisible(bool)
257 {
258     notImplemented();
259 }
260
261
262 bool ChromeClientQt::scrollbarsVisible()
263 {
264     notImplemented();
265     return true;
266 }
267
268
269 void ChromeClientQt::setMenubarVisible(bool visible)
270 {
271     menuBarVisible = visible;
272     emit m_webPage->menuBarVisibilityChangeRequested(visible);
273 }
274
275 bool ChromeClientQt::menubarVisible()
276 {
277     return menuBarVisible;
278 }
279
280 void ChromeClientQt::setResizable(bool)
281 {
282     notImplemented();
283 }
284
285 void ChromeClientQt::addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message,
286                                          unsigned int lineNumber, const String& sourceID)
287 {
288     QString x = message;
289     QString y = sourceID;
290     m_webPage->javaScriptConsoleMessage(x, lineNumber, y);
291 }
292
293 void ChromeClientQt::chromeDestroyed()
294 {
295     delete this;
296 }
297
298 bool ChromeClientQt::canRunBeforeUnloadConfirmPanel()
299 {
300     return true;
301 }
302
303 bool ChromeClientQt::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
304 {
305     return runJavaScriptConfirm(frame, message);
306 }
307
308 void ChromeClientQt::closeWindowSoon()
309 {
310     m_webPage->d->page->setGroupName(String());
311     m_webPage->mainFrame()->d->frame->loader()->stopAllLoaders();
312     emit m_webPage->windowCloseRequested();
313 }
314
315 void ChromeClientQt::runJavaScriptAlert(Frame* f, const String& msg)
316 {
317     QString x = msg;
318     QWebFrame* webFrame = qobject_cast<QWebFrame*>(f->loader()->networkingContext()->originatingObject());
319     m_webPage->javaScriptAlert(webFrame, x);
320 }
321
322 bool ChromeClientQt::runJavaScriptConfirm(Frame* f, const String& msg)
323 {
324     QString x = msg;
325     QWebFrame* webFrame = qobject_cast<QWebFrame*>(f->loader()->networkingContext()->originatingObject());
326     return m_webPage->javaScriptConfirm(webFrame, x);
327 }
328
329 bool ChromeClientQt::runJavaScriptPrompt(Frame* f, const String& message, const String& defaultValue, String& result)
330 {
331     QString x = result;
332     QWebFrame* webFrame = qobject_cast<QWebFrame*>(f->loader()->networkingContext()->originatingObject());
333     bool rc = m_webPage->javaScriptPrompt(webFrame, (QString)message, (QString)defaultValue, &x);
334
335     // Fix up a quirk in the QInputDialog class. If no input happened the string should be empty
336     // but it is null. See https://bugs.webkit.org/show_bug.cgi?id=30914.
337     if (rc && x.isNull())
338         result = String("");
339     else
340         result = x;
341
342     return rc;
343 }
344
345 void ChromeClientQt::setStatusbarText(const String& msg)
346 {
347     QString x = msg;
348     emit m_webPage->statusBarMessage(x);
349 }
350
351 bool ChromeClientQt::shouldInterruptJavaScript()
352 {
353     bool shouldInterrupt = false;
354     QMetaObject::invokeMethod(m_webPage, "shouldInterruptJavaScript", Qt::DirectConnection, Q_RETURN_ARG(bool, shouldInterrupt));
355     return shouldInterrupt;
356 }
357
358 bool ChromeClientQt::tabsToLinks() const
359 {
360     return m_webPage->settings()->testAttribute(QWebSettings::LinksIncludedInFocusChain);
361 }
362
363 IntRect ChromeClientQt::windowResizerRect() const
364 {
365 #if defined(Q_WS_MAC)
366     if (!m_webPage)
367         return IntRect();
368
369     QWebPageClient* pageClient = platformPageClient();
370     if (!pageClient)
371         return IntRect();
372
373     QWidget* ownerWidget = pageClient->ownerWidget();
374     if (!ownerWidget)
375         return IntRect();
376
377     QWidget* topLevelWidget = ownerWidget->window();
378     QRect topLevelGeometry(topLevelWidget->geometry());
379
380     // There's no API in Qt to query for the size of the resizer, so we assume
381     // it has the same width and height as the scrollbar thickness.
382     int scollbarThickness = ScrollbarTheme::nativeTheme()->scrollbarThickness();
383
384     // There's no API in Qt to query for the position of the resizer. Sometimes
385     // it's drawn by the system, and sometimes it's a QSizeGrip. For RTL locales
386     // it might even be on the lower left side of the window, but in WebKit we
387     // always draw scrollbars on the right hand side, so we assume this to be the
388     // location when computing the resize rect to reserve for WebKit.
389     QPoint resizeCornerTopLeft = ownerWidget->mapFrom(topLevelWidget,
390             QPoint(topLevelGeometry.width(), topLevelGeometry.height())
391             - QPoint(scollbarThickness, scollbarThickness));
392
393     QRect resizeCornerRect = QRect(resizeCornerTopLeft, QSize(scollbarThickness, scollbarThickness));
394     return resizeCornerRect.intersected(pageClient->geometryRelativeToOwnerWidget());
395 #else
396     return IntRect();
397 #endif
398 }
399
400 void ChromeClientQt::invalidateWindow(const IntRect&, bool)
401 {
402     notImplemented();
403 }
404
405 void ChromeClientQt::invalidateContentsAndWindow(const IntRect& windowRect, bool immediate)
406 {
407     // No double buffer, so only update the QWidget if content changed.
408     if (platformPageClient()) {
409         QRect rect(windowRect);
410         rect = rect.intersected(QRect(QPoint(0, 0), m_webPage->viewportSize()));
411         if (!rect.isEmpty())
412             platformPageClient()->update(rect);
413     }
414     emit m_webPage->repaintRequested(windowRect);
415
416     // FIXME: There is no "immediate" support for window painting.  This should be done always whenever the flag
417     // is set.
418 }
419
420 void ChromeClientQt::invalidateContentsForSlowScroll(const IntRect& windowRect, bool immediate)
421 {
422     invalidateContentsAndWindow(windowRect, immediate);
423 }
424
425 void ChromeClientQt::scroll(const IntSize& delta, const IntRect& scrollViewRect, const IntRect&)
426 {
427     if (platformPageClient())
428         platformPageClient()->scroll(delta.width(), delta.height(), scrollViewRect);
429     emit m_webPage->scrollRequested(delta.width(), delta.height(), scrollViewRect);
430 }
431
432 #if ENABLE(TILED_BACKING_STORE)
433 void ChromeClientQt::delegatedScrollRequested(const IntSize& delta)
434 {
435     emit m_webPage->scrollRequested(delta.width(), delta.height(), QRect(QPoint(0, 0), m_webPage->viewportSize()));
436 }
437 #endif
438
439 IntRect ChromeClientQt::windowToScreen(const IntRect& rect) const
440 {
441     QWebPageClient* pageClient = platformPageClient();
442     if (!pageClient)
443         return rect;
444
445     QWidget* ownerWidget = pageClient->ownerWidget();
446     if (!ownerWidget)
447        return rect;
448
449     QRect screenRect(rect);
450     screenRect.translate(ownerWidget->mapToGlobal(QPoint(0, 0)));
451
452     return screenRect;
453 }
454
455 IntPoint ChromeClientQt::screenToWindow(const IntPoint& point) const
456 {
457     QWebPageClient* pageClient = platformPageClient();
458     if (!pageClient)
459         return point;
460
461     QWidget* ownerWidget = pageClient->ownerWidget();
462     if (!ownerWidget)
463         return point;
464
465     return ownerWidget->mapFromGlobal(point);
466 }
467
468 PlatformPageClient ChromeClientQt::platformPageClient() const
469 {
470     return m_webPage->d->client.get();
471 }
472
473 void ChromeClientQt::contentsSizeChanged(Frame* frame, const IntSize& size) const
474 {
475     if (frame->loader()->networkingContext())
476         QWebFramePrivate::kit(frame)->contentsSizeChanged(size);
477 }
478
479 void ChromeClientQt::mouseDidMoveOverElement(const HitTestResult& result, unsigned)
480 {
481     TextDirection dir;
482     if (result.absoluteLinkURL() != lastHoverURL
483         || result.title(dir) != lastHoverTitle
484         || result.textContent() != lastHoverContent) {
485         lastHoverURL = result.absoluteLinkURL();
486         lastHoverTitle = result.title(dir);
487         lastHoverContent = result.textContent();
488         emit m_webPage->linkHovered(lastHoverURL.prettyURL(),
489                 lastHoverTitle, lastHoverContent);
490     }
491 }
492
493 void ChromeClientQt::setToolTip(const String &tip, TextDirection)
494 {
495 #ifndef QT_NO_TOOLTIP
496     QWidget* view = m_webPage->view();
497     if (!view)
498         return;
499
500     if (tip.isEmpty()) {
501         view->setToolTip(QString());
502         QToolTip::hideText();
503     } else {
504         QString dtip = QLatin1String("<p>") + Qt::escape(tip) + QLatin1String("</p>");
505         view->setToolTip(dtip);
506     }
507 #else
508     Q_UNUSED(tip);
509 #endif
510 }
511
512 void ChromeClientQt::print(Frame* frame)
513 {
514     emit m_webPage->printRequested(QWebFramePrivate::kit(frame));
515 }
516
517 #if ENABLE(DATABASE)
518 void ChromeClientQt::exceededDatabaseQuota(Frame* frame, const String& databaseName)
519 {
520     quint64 quota = QWebSettings::offlineStorageDefaultQuota();
521
522     if (!DatabaseTracker::tracker().hasEntryForOrigin(frame->document()->securityOrigin()))
523         DatabaseTracker::tracker().setQuota(frame->document()->securityOrigin(), quota);
524
525     emit m_webPage->databaseQuotaExceeded(QWebFramePrivate::kit(frame), databaseName);
526 }
527 #endif
528
529 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
530 void ChromeClientQt::reachedMaxAppCacheSize(int64_t)
531 {
532     // FIXME: Free some space.
533     notImplemented();
534 }
535
536 void ChromeClientQt::reachedApplicationCacheOriginQuota(SecurityOrigin* origin)
537 {
538     int64_t quota;
539     quint64 defaultOriginQuota = WebCore::cacheStorage().defaultOriginQuota();
540
541     QWebSecurityOriginPrivate* priv = new QWebSecurityOriginPrivate(origin);
542     QWebSecurityOrigin* securityOrigin = new QWebSecurityOrigin(priv);
543
544     if (!WebCore::cacheStorage().quotaForOrigin(origin, quota))
545        WebCore::cacheStorage().storeUpdatedQuotaForOrigin(origin, defaultOriginQuota);
546
547     emit m_webPage->applicationCacheQuotaExceeded(securityOrigin, defaultOriginQuota);
548 }
549 #endif
550
551 #if ENABLE(NOTIFICATIONS)
552 NotificationPresenter* ChromeClientQt::notificationPresenter() const
553 {
554     return NotificationPresenterClientQt::notificationPresenter();
555 }
556 #endif
557
558 void ChromeClientQt::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> prpFileChooser)
559 {
560     RefPtr<FileChooser> fileChooser = prpFileChooser;
561     bool supportMulti = m_webPage->supportsExtension(QWebPage::ChooseMultipleFilesExtension);
562
563     if (fileChooser->allowsMultipleFiles() && supportMulti) {
564         QWebPage::ChooseMultipleFilesExtensionOption option;
565         option.parentFrame = QWebFramePrivate::kit(frame);
566
567         if (!fileChooser->filenames().isEmpty())
568             for (unsigned i = 0; i < fileChooser->filenames().size(); ++i)
569                 option.suggestedFileNames += fileChooser->filenames()[i];
570
571         QWebPage::ChooseMultipleFilesExtensionReturn output;
572         m_webPage->extension(QWebPage::ChooseMultipleFilesExtension, &option, &output);
573
574         if (!output.fileNames.isEmpty()) {
575             Vector<String> names;
576             for (int i = 0; i < output.fileNames.count(); ++i)
577                 names.append(output.fileNames.at(i));
578             fileChooser->chooseFiles(names);
579         }
580     } else {
581         QString suggestedFile;
582         if (!fileChooser->filenames().isEmpty())
583             suggestedFile = fileChooser->filenames()[0];
584         QString file = m_webPage->chooseFile(QWebFramePrivate::kit(frame), suggestedFile);
585         if (!file.isEmpty())
586             fileChooser->chooseFile(file);
587     }
588 }
589
590 void ChromeClientQt::chooseIconForFiles(const Vector<String>& filenames, FileChooser* chooser)
591 {
592     chooser->iconLoaded(Icon::createIconForFiles(filenames));
593 }
594
595 void ChromeClientQt::setCursor(const Cursor& cursor)
596 {
597 #ifndef QT_NO_CURSOR
598     QWebPageClient* pageClient = platformPageClient();
599     if (!pageClient)
600         return;
601     pageClient->setCursor(*cursor.platformCursor());
602 #else
603     UNUSED_PARAM(cursor);
604 #endif
605 }
606
607 void ChromeClientQt::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation)
608 {
609 #if ENABLE(GEOLOCATION)
610     QWebFrame* webFrame = QWebFramePrivate::kit(frame);
611     GeolocationPermissionClientQt::geolocationPermissionClient()->requestGeolocationPermissionForFrame(webFrame, geolocation);
612 #endif
613 }
614
615 void ChromeClientQt::cancelGeolocationPermissionRequestForFrame(Frame* frame, Geolocation* geolocation)
616 {
617 #if ENABLE(GEOLOCATION)
618     QWebFrame* webFrame = QWebFramePrivate::kit(frame);
619     GeolocationPermissionClientQt::geolocationPermissionClient()->cancelGeolocationPermissionRequestForFrame(webFrame, geolocation);
620 #endif
621 }
622
623 #if USE(ACCELERATED_COMPOSITING)
624 void ChromeClientQt::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer)
625 {
626     if (platformPageClient())
627         platformPageClient()->setRootGraphicsLayer(graphicsLayer ? graphicsLayer->platformLayer() : 0);
628 }
629
630 void ChromeClientQt::setNeedsOneShotDrawingSynchronization()
631 {
632     // we want the layers to synchronize next time we update the screen anyway
633     if (platformPageClient())
634         platformPageClient()->markForSync(false);
635 }
636
637 void ChromeClientQt::scheduleCompositingLayerSync()
638 {
639     // we want the layers to synchronize ASAP
640     if (platformPageClient())
641         platformPageClient()->markForSync(true);
642 }
643
644 ChromeClient::CompositingTriggerFlags ChromeClientQt::allowedCompositingTriggers() const
645 {
646     if (platformPageClient() && platformPageClient()->allowsAcceleratedCompositing())
647         return AllTriggers;
648
649     return 0;
650 }
651
652 #endif
653
654 #if ENABLE(TILED_BACKING_STORE)
655 IntRect ChromeClientQt::visibleRectForTiledBackingStore() const
656 {
657     if (!platformPageClient() || !m_webPage)
658         return IntRect();
659
660     if (!platformPageClient()->viewResizesToContentsEnabled())
661         return QRect(m_webPage->mainFrame()->scrollPosition(), m_webPage->mainFrame()->geometry().size());
662
663     return enclosingIntRect(FloatRect(platformPageClient()->graphicsItemVisibleRect()));
664 }
665 #endif
666
667 #if ENABLE(VIDEO) && ENABLE(QT_MULTIMEDIA)
668 FullScreenVideoQt* ChromeClientQt::fullScreenVideo()
669 {
670     if (!m_fullScreenVideo)
671         m_fullScreenVideo = new FullScreenVideoQt(this);
672     return m_fullScreenVideo;
673 }
674
675 bool ChromeClientQt::supportsFullscreenForNode(const Node* node)
676 {
677     ASSERT(node);
678     return node->hasTagName(HTMLNames::videoTag) && fullScreenVideo()->isValid();
679 }
680
681 bool ChromeClientQt::requiresFullscreenForVideoPlayback()
682 {
683     return fullScreenVideo()->requiresFullScreenForVideoPlayback();
684 }
685
686 void ChromeClientQt::enterFullscreenForNode(Node* node)
687 {
688     ASSERT(node && node->hasTagName(HTMLNames::videoTag));
689
690     HTMLVideoElement* videoElement = static_cast<HTMLVideoElement*>(node);
691     PlatformMedia platformMedia = videoElement->platformMedia();
692
693     ASSERT(platformMedia.type == PlatformMedia::QtMediaPlayerType);
694     if (platformMedia.type != PlatformMedia::QtMediaPlayerType)
695         return;
696
697     fullScreenVideo()->enterFullScreenForNode(node);
698 }
699
700 void ChromeClientQt::exitFullscreenForNode(Node* node)
701 {
702     ASSERT(node && node->hasTagName(HTMLNames::videoTag));
703
704     HTMLVideoElement* videoElement = static_cast<HTMLVideoElement*>(node);
705     PlatformMedia platformMedia = videoElement->platformMedia();
706
707     ASSERT(platformMedia.type == PlatformMedia::QtMediaPlayerType);
708     if (platformMedia.type != PlatformMedia::QtMediaPlayerType)
709         return;
710
711     fullScreenVideo()->exitFullScreenForNode(node);
712
713 #endif
714
715 QWebSelectMethod* ChromeClientQt::createSelectPopup() const
716 {
717     QWebSelectMethod* result = m_platformPlugin.createSelectInputMethod();
718     if (result)
719         return result;
720
721 #if defined(Q_WS_MAEMO_5)
722     return new QtMaemoWebPopup;
723 #elif !defined(QT_NO_COMBOBOX)
724     return new QtFallbackWebPopup(this);
725 #else
726     return 0;
727 #endif
728 }
729
730 void ChromeClientQt::dispatchViewportDataDidChange(const ViewportArguments&) const
731 {
732     emit m_webPage->viewportChangeRequested();
733 }
734
735 bool ChromeClientQt::selectItemWritingDirectionIsNatural()
736 {
737     return false;
738 }
739
740 bool ChromeClientQt::selectItemAlignmentFollowsMenuWritingDirection()
741 {
742     return false;
743 }
744
745 PassRefPtr<PopupMenu> ChromeClientQt::createPopupMenu(PopupMenuClient* client) const
746 {
747     return adoptRef(new PopupMenuQt(client, this));
748 }
749
750 PassRefPtr<SearchPopupMenu> ChromeClientQt::createSearchPopupMenu(PopupMenuClient* client) const
751 {
752     return adoptRef(new SearchPopupMenuQt(createPopupMenu(client)));
753 }
754
755 void ChromeClientQt::populateVisitedLinks()
756 {
757     // We don't need to do anything here because history is tied to QWebPage rather than stored
758     // in a separate database
759     if (dumpVisitedLinksCallbacks) {
760         printf("Asked to populate visited links for WebView \"%s\"\n",
761                 qPrintable(m_webPage->mainFrame()->url().toString()));
762     }
763 }
764
765 } // namespace WebCore