📄 chromeclientgtk.cpp
字号:
/* * Copyright (C) 2007, 2008 Holger Hans Peter Freyther * Copyright (C) 2007, 2008 Christian Dywan <christian@imendio.com> * Copyright (C) 2008 Nuanti Ltd. * Copyright (C) 2008 Alp Toker <alp@atoker.com> * Copyright (C) 2008 Gustavo Noronha Silva <gns@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */#include "config.h"#include "ChromeClientGtk.h"#include "FileSystem.h"#include "FileChooser.h"#include "FloatRect.h"#include "FrameLoadRequest.h"#include "IntRect.h"#include "PlatformString.h"#include "CString.h"#include "HitTestResult.h"#include "KURL.h"#include "webkitwebview.h"#include "webkitnetworkrequest.h"#include "webkitprivate.h"#include "NotImplemented.h"#include "WindowFeatures.h"#if ENABLE(DATABASE)#include "DatabaseTracker.h"#endif#include <glib.h>#include <glib/gi18n.h>#include <gtk/gtk.h>using namespace WebCore;namespace WebKit {ChromeClient::ChromeClient(WebKitWebView* webView) : m_webView(webView){ ASSERT(m_webView);}void ChromeClient::chromeDestroyed(){ delete this;}FloatRect ChromeClient::windowRect(){ GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(m_webView)); if (GTK_WIDGET_TOPLEVEL(window)) { gint left, top, width, height; gtk_window_get_position(GTK_WINDOW(window), &left, &top); gtk_window_get_size(GTK_WINDOW(window), &width, &height); return IntRect(left, top, width, height); } return FloatRect();}void ChromeClient::setWindowRect(const FloatRect& rect){ IntRect intrect = IntRect(rect); WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView); g_object_set(webWindowFeatures, "x", intrect.x(), "y", intrect.y(), "width", intrect.width(), "height", intrect.height(), NULL);}FloatRect ChromeClient::pageRect(){ GtkAllocation allocation = GTK_WIDGET(m_webView)->allocation; return IntRect(allocation.x, allocation.y, allocation.width, allocation.height);}float ChromeClient::scaleFactor(){ // Not implementable return 1.0;}void ChromeClient::focus(){ gtk_widget_grab_focus(GTK_WIDGET(m_webView));}void ChromeClient::unfocus(){ GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(m_webView)); if (GTK_WIDGET_TOPLEVEL(window)) gtk_window_set_focus(GTK_WINDOW(window), NULL);}Page* ChromeClient::createWindow(Frame* frame, const FrameLoadRequest& frameLoadRequest, const WindowFeatures& coreFeatures){ WebKitWebView* webView = 0; g_signal_emit_by_name(m_webView, "create-web-view", kit(frame), &webView); if (!webView) return 0; WebKitWebWindowFeatures* webWindowFeatures = webkit_web_window_features_new_from_core_features(coreFeatures); g_object_set(webView, "window-features", webWindowFeatures, NULL); g_object_unref(webWindowFeatures); if (!frameLoadRequest.isEmpty()) webkit_web_view_open(webView, frameLoadRequest.resourceRequest().url().string().utf8().data()); return core(webView);}void ChromeClient::show(){ webkit_web_view_notify_ready(m_webView);}bool ChromeClient::canRunModal(){ notImplemented(); return false;}void ChromeClient::runModal(){ notImplemented();}void ChromeClient::setToolbarsVisible(bool visible){ WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView); g_object_set(webWindowFeatures, "toolbar-visible", visible, NULL);}bool ChromeClient::toolbarsVisible(){ WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView); gboolean visible; g_object_get(webWindowFeatures, "toolbar-visible", &visible, NULL); return visible;}void ChromeClient::setStatusbarVisible(bool visible){ WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView); g_object_set(webWindowFeatures, "statusbar-visible", visible, NULL);}bool ChromeClient::statusbarVisible(){ WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView); gboolean visible; g_object_get(webWindowFeatures, "statusbar-visible", &visible, NULL); return visible;}void ChromeClient::setScrollbarsVisible(bool visible){ WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView); g_object_set(webWindowFeatures, "scrollbar-visible", visible, NULL);}bool ChromeClient::scrollbarsVisible() { WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView); gboolean visible; g_object_get(webWindowFeatures, "scrollbar-visible", &visible, NULL); return visible;}void ChromeClient::setMenubarVisible(bool visible){ WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView); g_object_set(webWindowFeatures, "menubar-visible", visible, NULL);}bool ChromeClient::menubarVisible(){ WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView); gboolean visible; g_object_get(webWindowFeatures, "menubar-visible", &visible, NULL); return visible;}void ChromeClient::setResizable(bool){ // Ignored for now}void ChromeClient::closeWindowSoon(){ notImplemented();}bool ChromeClient::canTakeFocus(FocusDirection){ return GTK_WIDGET_CAN_FOCUS(m_webView);}void ChromeClient::takeFocus(FocusDirection){ unfocus();}bool ChromeClient::canRunBeforeUnloadConfirmPanel(){ return true;}bool ChromeClient::runBeforeUnloadConfirmPanel(const WebCore::String& message, WebCore::Frame* frame){ return runJavaScriptConfirm(frame, message);}void ChromeClient::addMessageToConsole(const WebCore::String& message, unsigned int lineNumber, const WebCore::String& sourceId){ gboolean retval; g_signal_emit_by_name(m_webView, "console-message", message.utf8().data(), lineNumber, sourceId.utf8().data(), &retval);}void ChromeClient::runJavaScriptAlert(Frame* frame, const String& message){ gboolean retval; g_signal_emit_by_name(m_webView, "script-alert", kit(frame), message.utf8().data(), &retval);}bool ChromeClient::runJavaScriptConfirm(Frame* frame, const String& message){ gboolean retval; gboolean didConfirm; g_signal_emit_by_name(m_webView, "script-confirm", kit(frame), message.utf8().data(), &didConfirm, &retval); return didConfirm == TRUE;}bool ChromeClient::runJavaScriptPrompt(Frame* frame, const String& message, const String& defaultValue, String& result){ gboolean retval; gchar* value = 0; g_signal_emit_by_name(m_webView, "script-prompt", kit(frame), message.utf8().data(), defaultValue.utf8().data(), &value, &retval); if (value) { result = String::fromUTF8(value); g_free(value); return true; } return false;}void ChromeClient::setStatusbarText(const String& string){ CString stringMessage = string.utf8(); g_signal_emit_by_name(m_webView, "status-bar-text-changed", stringMessage.data());}bool ChromeClient::shouldInterruptJavaScript(){ notImplemented(); return false;}bool ChromeClient::tabsToLinks() const{ return true;}IntRect ChromeClient::windowResizerRect() const{ notImplemented(); return IntRect();}void ChromeClient::repaint(const IntRect& windowRect, bool contentChanged, bool immediate, bool repaintContentOnly){ GdkRectangle rect = windowRect; GdkWindow* window = GTK_WIDGET(m_webView)->window; if (window) { if (contentChanged) gdk_window_invalidate_rect(window, &rect, FALSE); // We don't currently do immediate updates since they delay other UI elements. //if (immediate) // gdk_window_process_updates(window, FALSE); }}void ChromeClient::scroll(const IntSize& delta, const IntRect& rectToScroll, const IntRect& clipRect){ GdkWindow* window = GTK_WIDGET(m_webView)->window; if (!window) return; GdkRectangle area = clipRect; GdkRectangle moveRect; GdkRectangle sourceRect = area; sourceRect.x -= delta.width(); sourceRect.y -= delta.height(); GdkRegion* invalidRegion = gdk_region_rectangle(&area); if (gdk_rectangle_intersect(&area, &sourceRect, &moveRect)) { GdkRegion* moveRegion = gdk_region_rectangle(&moveRect); gdk_window_move_region(window, moveRegion, delta.width(), delta.height()); gdk_region_offset(moveRegion, delta.width(), delta.height()); gdk_region_subtract(invalidRegion, moveRegion); gdk_region_destroy(moveRegion); } gdk_window_invalidate_region(window, invalidRegion, FALSE); gdk_region_destroy(invalidRegion);}IntRect ChromeClient::windowToScreen(const IntRect& rect) const{ notImplemented(); return rect;}IntPoint ChromeClient::screenToWindow(const IntPoint& point) const{ notImplemented(); return point;}PlatformWidget ChromeClient::platformWindow() const{ return GTK_WIDGET(m_webView);}void ChromeClient::contentsSizeChanged(Frame*, const IntSize&) const{ notImplemented();}void ChromeClient::mouseDidMoveOverElement(const HitTestResult& hit, unsigned modifierFlags){ // check if the element is a link... bool isLink = hit.isLiveLink(); if (isLink) { KURL url = hit.absoluteLinkURL(); if (!url.isEmpty() && url != m_hoveredLinkURL) { CString titleString = hit.title().utf8(); CString urlString = url.prettyURL().utf8(); g_signal_emit_by_name(m_webView, "hovering-over-link", titleString.data(), urlString.data()); m_hoveredLinkURL = url; } } else if (!isLink && !m_hoveredLinkURL.isEmpty()) { g_signal_emit_by_name(m_webView, "hovering-over-link", 0, 0); m_hoveredLinkURL = KURL(); }}void ChromeClient::setToolTip(const String& toolTip){#if GTK_CHECK_VERSION(2,12,0) if (toolTip.isEmpty()) g_object_set(m_webView, "has-tooltip", FALSE, NULL); else gtk_widget_set_tooltip_text(GTK_WIDGET(m_webView), toolTip.utf8().data());#else // TODO: Support older GTK+ versions // See http://bugs.webkit.org/show_bug.cgi?id=15793 notImplemented();#endif}void ChromeClient::print(Frame* frame){ webkit_web_frame_print(kit(frame));}void ChromeClient::exceededDatabaseQuota(Frame* frame, const String&){#if ENABLE(DATABASE) // Set to 5M for testing // FIXME: Make this configurable notImplemented(); const unsigned long long defaultQuota = 5 * 1024 * 1024; DatabaseTracker::tracker().setQuota(frame->document()->securityOrigin(), defaultQuota);#endif}void ChromeClient::runOpenPanel(Frame*, PassRefPtr<FileChooser> prpFileChooser){ RefPtr<FileChooser> chooser = prpFileChooser; GtkWidget* dialog = gtk_file_chooser_dialog_new(_("Upload File"), GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(platformWindow()))), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), chooser->allowsMultipleFiles()); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { if (gtk_file_chooser_get_select_multiple(GTK_FILE_CHOOSER(dialog))) { GSList* filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); Vector<String> names; for (GSList* item = filenames ; item ; item = item->next) { if (!item->data) continue; names.append(filenameToString(static_cast<char*>(item->data))); g_free(item->data); } g_slist_free(filenames); chooser->chooseFiles(names); } else { gchar* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); if (filename) chooser->chooseFile(filenameToString(filename)); g_free(filename); } } gtk_widget_destroy(dialog);}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -