blob: 5199a5a5ea64165cec8eabd3671427e8cdef737c [file] [log] [blame]
/*
* Copyright (C) 2006 Zack Rusin <zack@kde.org>
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "ChromeClientQt.h"
#include "FileChooser.h"
#include "Frame.h"
#include "FrameLoadRequest.h"
#include "FrameLoader.h"
#include "FrameLoaderClientQt.h"
#include "FrameView.h"
#include "HitTestResult.h"
#include "NotImplemented.h"
#include "WindowFeatures.h"
#include "DatabaseTracker.h"
#include "SecurityOrigin.h"
#include "qwebpage.h"
#include "qwebpage_p.h"
#include "qwebframe_p.h"
#include "qwebsecurityorigin.h"
#include "qwebsecurityorigin_p.h"
#include <qtooltip.h>
#include <qtextdocument.h>
namespace WebCore
{
ChromeClientQt::ChromeClientQt(QWebPage* webPage)
: m_webPage(webPage)
{
toolBarsVisible = statusBarVisible = menuBarVisible = true;
}
ChromeClientQt::~ChromeClientQt()
{
}
void ChromeClientQt::setWindowRect(const FloatRect& rect)
{
if (!m_webPage)
return;
emit m_webPage->geometryChangeRequested(QRect(qRound(rect.x()), qRound(rect.y()),
qRound(rect.width()), qRound(rect.height())));
}
FloatRect ChromeClientQt::windowRect()
{
if (!m_webPage)
return FloatRect();
QWidget* view = m_webPage->view();
if (!view)
return FloatRect();
return IntRect(view->topLevelWidget()->geometry());
}
FloatRect ChromeClientQt::pageRect()
{
if (!m_webPage)
return FloatRect();
return FloatRect(QRectF(QPointF(0,0), m_webPage->viewportSize()));
}
float ChromeClientQt::scaleFactor()
{
notImplemented();
return 1;
}
void ChromeClientQt::focus()
{
if (!m_webPage)
return;
QWidget* view = m_webPage->view();
if (!view)
return;
view->setFocus();
}
void ChromeClientQt::unfocus()
{
if (!m_webPage)
return;
QWidget* view = m_webPage->view();
if (!view)
return;
view->clearFocus();
}
bool ChromeClientQt::canTakeFocus(FocusDirection)
{
// This is called when cycling through links/focusable objects and we
// reach the last focusable object. Then we want to claim that we can
// take the focus to avoid wrapping.
return true;
}
void ChromeClientQt::takeFocus(FocusDirection)
{
// don't do anything. This is only called when cycling to links/focusable objects,
// which in turn is called from focusNextPrevChild. We let focusNextPrevChild
// call QWidget::focusNextPrevChild accordingly, so there is no need to do anything
// here.
}
Page* ChromeClientQt::createWindow(Frame*, const FrameLoadRequest& request, const WindowFeatures& features)
{
QWebPage *newPage = m_webPage->createWindow(features.dialog ? QWebPage::WebModalDialog : QWebPage::WebBrowserWindow);
if (!newPage)
return 0;
newPage->mainFrame()->load(request.resourceRequest().url());
return newPage->d->page;
}
void ChromeClientQt::show()
{
if (!m_webPage)
return;
QWidget* view = m_webPage->view();
if (!view)
return;
view->topLevelWidget()->show();
}
bool ChromeClientQt::canRunModal()
{
notImplemented();
return false;
}
void ChromeClientQt::runModal()
{
notImplemented();
}
void ChromeClientQt::setToolbarsVisible(bool visible)
{
toolBarsVisible = visible;
emit m_webPage->toolBarVisibilityChangeRequested(visible);
}
bool ChromeClientQt::toolbarsVisible()
{
return toolBarsVisible;
}
void ChromeClientQt::setStatusbarVisible(bool visible)
{
emit m_webPage->statusBarVisibilityChangeRequested(visible);
statusBarVisible = visible;
}
bool ChromeClientQt::statusbarVisible()
{
return statusBarVisible;
return false;
}
void ChromeClientQt::setScrollbarsVisible(bool)
{
notImplemented();
}
bool ChromeClientQt::scrollbarsVisible()
{
notImplemented();
return true;
}
void ChromeClientQt::setMenubarVisible(bool visible)
{
menuBarVisible = visible;
emit m_webPage->menuBarVisibilityChangeRequested(visible);
}
bool ChromeClientQt::menubarVisible()
{
return menuBarVisible;
}
void ChromeClientQt::setResizable(bool)
{
notImplemented();
}
void ChromeClientQt::addMessageToConsole(const String& message, unsigned int lineNumber,
const String& sourceID)
{
QString x = message;
QString y = sourceID;
m_webPage->javaScriptConsoleMessage(x, lineNumber, y);
}
void ChromeClientQt::chromeDestroyed()
{
delete this;
}
bool ChromeClientQt::canRunBeforeUnloadConfirmPanel()
{
return true;
}
bool ChromeClientQt::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
{
return runJavaScriptConfirm(frame, message);
}
void ChromeClientQt::closeWindowSoon()
{
m_webPage->mainFrame()->d->frame->loader()->stopAllLoaders();
emit m_webPage->windowCloseRequested();
}
void ChromeClientQt::runJavaScriptAlert(Frame* f, const String& msg)
{
QString x = msg;
FrameLoaderClientQt *fl = static_cast<FrameLoaderClientQt*>(f->loader()->client());
m_webPage->javaScriptAlert(fl->webFrame(), x);
}
bool ChromeClientQt::runJavaScriptConfirm(Frame* f, const String& msg)
{
QString x = msg;
FrameLoaderClientQt *fl = static_cast<FrameLoaderClientQt*>(f->loader()->client());
return m_webPage->javaScriptConfirm(fl->webFrame(), x);
}
bool ChromeClientQt::runJavaScriptPrompt(Frame* f, const String& message, const String& defaultValue, String& result)
{
QString x = result;
FrameLoaderClientQt *fl = static_cast<FrameLoaderClientQt*>(f->loader()->client());
bool rc = m_webPage->javaScriptPrompt(fl->webFrame(), (QString)message, (QString)defaultValue, &x);
result = x;
return rc;
}
void ChromeClientQt::setStatusbarText(const String& msg)
{
QString x = msg;
emit m_webPage->statusBarMessage(x);
}
bool ChromeClientQt::shouldInterruptJavaScript()
{
notImplemented();
return false;
}
bool ChromeClientQt::tabsToLinks() const
{
return m_webPage->settings()->testAttribute(QWebSettings::LinksIncludedInFocusChain);
}
IntRect ChromeClientQt::windowResizerRect() const
{
return IntRect();
}
void ChromeClientQt::repaint(const IntRect& windowRect, bool contentChanged, bool immediate, bool repaintContentOnly)
{
// No double buffer, so only update the QWidget if content changed.
if (contentChanged) {
QWidget* view = m_webPage->view();
if (view) {
QRect rect(windowRect);
rect = rect.intersected(QRect(QPoint(0, 0), m_webPage->viewportSize()));
if (!rect.isEmpty())
view->update(rect);
}
emit m_webPage->repaintRequested(windowRect);
}
// FIXME: There is no "immediate" support for window painting. This should be done always whenever the flag
// is set.
}
void ChromeClientQt::scroll(const IntSize& delta, const IntRect& scrollViewRect, const IntRect&)
{
QWidget* view = m_webPage->view();
if (view)
view->scroll(delta.width(), delta.height(), scrollViewRect);
emit m_webPage->scrollRequested(delta.width(), delta.height(), scrollViewRect);
}
IntRect ChromeClientQt::windowToScreen(const IntRect& rect) const
{
notImplemented();
return rect;
}
IntPoint ChromeClientQt::screenToWindow(const IntPoint& point) const
{
notImplemented();
return point;
}
PlatformWidget ChromeClientQt::platformWindow() const
{
return m_webPage->view();
}
void ChromeClientQt::contentsSizeChanged(Frame* frame, const IntSize& size) const
{
emit QWebFramePrivate::kit(frame)->contentsSizeChanged(size);
}
void ChromeClientQt::mouseDidMoveOverElement(const HitTestResult& result, unsigned modifierFlags)
{
if (result.absoluteLinkURL() != lastHoverURL
|| result.title() != lastHoverTitle
|| result.textContent() != lastHoverContent) {
lastHoverURL = result.absoluteLinkURL();
lastHoverTitle = result.title();
lastHoverContent = result.textContent();
emit m_webPage->linkHovered(lastHoverURL.prettyURL(),
lastHoverTitle, lastHoverContent);
}
}
void ChromeClientQt::setToolTip(const String &tip)
{
#ifndef QT_NO_TOOLTIP
QWidget* view = m_webPage->view();
if (!view)
return;
if (tip.isEmpty()) {
view->setToolTip(QString());
QToolTip::hideText();
} else {
QString dtip = QLatin1String("<p>") + Qt::escape(tip) + QLatin1String("</p>");
view->setToolTip(dtip);
}
#else
Q_UNUSED(tip);
#endif
}
void ChromeClientQt::print(Frame *frame)
{
emit m_webPage->printRequested(QWebFramePrivate::kit(frame));
}
#if ENABLE(DATABASE)
void ChromeClientQt::exceededDatabaseQuota(Frame* frame, const String& databaseName)
{
quint64 quota = QWebSettings::offlineStorageDefaultQuota();
if (!DatabaseTracker::tracker().hasEntryForOrigin(frame->document()->securityOrigin()))
DatabaseTracker::tracker().setQuota(frame->document()->securityOrigin(), quota);
emit m_webPage->databaseQuotaExceeded(QWebFramePrivate::kit(frame), databaseName);
}
#endif
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
void ChromeClientQt::reachedMaxAppCacheSize(int64_t spaceNeeded)
{
// FIXME: Free some space.
notImplemented();
}
#endif
void ChromeClientQt::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> prpFileChooser)
{
RefPtr<FileChooser> fileChooser = prpFileChooser;
bool supportMulti = m_webPage->supportsExtension(QWebPage::ChooseMultipleFilesExtension);
if (fileChooser->allowsMultipleFiles() && supportMulti) {
QWebPage::ChooseMultipleFilesExtensionOption option;
option.parentFrame = QWebFramePrivate::kit(frame);
if (!fileChooser->filenames().isEmpty())
for (int i = 0; i < fileChooser->filenames().size(); ++i)
option.suggestedFileNames += fileChooser->filenames()[i];
QWebPage::ChooseMultipleFilesExtensionReturn output;
m_webPage->extension(QWebPage::ChooseMultipleFilesExtension, &option, &output);
if (!output.fileNames.isEmpty()) {
Vector<String> names;
for (int i = 0; i < output.fileNames.count(); ++i)
names.append(output.fileNames.at(i));
fileChooser->chooseFiles(names);
}
} else {
QString suggestedFile;
if (!fileChooser->filenames().isEmpty())
suggestedFile = fileChooser->filenames()[0];
QString file = m_webPage->chooseFile(QWebFramePrivate::kit(frame), suggestedFile);
if (!file.isEmpty())
fileChooser->chooseFile(file);
}
}
}