⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kwqwidget.cpp

📁 khtml在gtk上的移植版本
💻 CPP
字号:
/* * Copyright (C) 2003 Apple Computer, Inc.  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 <gtk/gtk.h>#include "KWQWidget.h"#include "KWQKHTMLPart.h"#include "KWQLogging.h"#include "KWQWindowWidget.h"#include "WebCoreBridge.h"#include "khtmlview.h"#include "render_canvas.h"#include "render_replaced.h"#include "render_style.h"#include "KWQEvent.h"#include "KWQNamespace.h"#include "KWQApplication.h"#include "GObjectMisc.h"/** callbacks */extern "C" {static gboolean focus_inout(GtkWidget *widget, GdkEventFocus *event, gpointer data);}using khtml::RenderWidget;class QWidgetPrivate{public:    QWidgetPrivate()	:inPaint(0), geom(QRect(0,0,0,0)) {}    QStyle *style;    QFont font;    QPalette pal;    GPtr<GtkWidget> safe_widget;    bool visible;    QWidget* parent;    int inPaint;    QRect geom;    QCursor currentCursor;};QWidget::QWidget(QWidget * parent, const char * name , int f )     : data(new QWidgetPrivate)      ,_widget(0){    QOBJECT_TYPE(QWidget);    static QStyle defaultStyle;    data->style = &defaultStyle;    data->parent = parent;    //data->widget = KWQRetain(view);    data->visible = true;}QWidget::QWidget(GtkWidget* awidget)    : data(new QWidgetPrivate)      ,_widget(0){    QOBJECT_TYPE(QWidget);    static QStyle defaultStyle;    data->style = &defaultStyle;    //data->widget = KWQRetain(view);    data->visible = true;    setGtkWidget(awidget);}QWidget::~QWidget() {    if (_widget) {	// window of widget	if (_widget->window) 	    gdk_window_set_cursor(_widget->window, NULL); 		data->safe_widget = 0; // unrefs etc    }        delete data;}QSize QWidget::sizeHint() const {    // May be overriden by subclasses.    ASSERT(_widget);    GtkRequisition r;    gtk_widget_size_request(_widget, &r);    return QSize(r.width, r.height);}void QWidget::resize(int w, int h) {    ASSERT(_widget);    LOG(KwiqLog, "this:%x size:%d,%d", (int)this, w, h);    QSize s(size());    if (s.width()!=w || s.height()!=h)	gtk_widget_set_size_request(_widget, w, h);}void QWidget::setActiveWindow() {    KWQKHTMLPart::bridgeForWidget(this)->focusWindow();}void QWidget::setEnabled(bool enabled){    gtk_widget_set_sensitive(_widget, enabled);}bool QWidget::isEnabled() const{    return GTK_WIDGET_IS_SENSITIVE(_widget);}long QWidget::winId() const{    return (long)this;}int QWidget::x() const{    ASSERT(_widget);    return  _widget->allocation.x;}int QWidget::y() const {    ASSERT(_widget);    return _widget->allocation.y;}int QWidget::width() const {     ASSERT(_widget);    return _widget->allocation.width;}int QWidget::height() const {    ASSERT(_widget);    return _widget->allocation.height;}QSize QWidget::size() const {    return QSize(_widget->allocation.width, _widget->allocation.height);}void QWidget::resize(const QSize &s) {    resize(s.width(), s.height());}QPoint QWidget::pos() const {    return QPoint(_widget->allocation.x, _widget->allocation.y);}void QWidget::move(int x, int y) {    LOG(KwiqLog, "this:%x, _widget:%x, size:%d,%d",(int)this, (int)_widget, x, y);    ASSERT(_widget);    QPoint p(pos());    if (p.x()!=x || p.y()!=y) {	GtkLayout *layout = GTK_LAYOUT (gtk_widget_get_parent(_widget));	if (layout) {	    gtk_layout_move(layout, _widget, x, y);	} else {	    GtkContainer *parent = GTK_CONTAINER (gtk_widget_get_parent(_widget));		    if (parent) {		GValue gval= {0,};		g_value_init(&gval, G_TYPE_INT);		g_value_set_int(&gval, x);		gtk_container_child_set_property(parent, _widget, "x", &gval);  		g_value_set_int(&gval, y);		gtk_container_child_set_property(parent, _widget, "y", &gval);  		g_value_unset(&gval);	    }	}    }}void QWidget::move(const QPoint &p) {    move(p.x(), p.y());}QRect QWidget::frameGeometry() const{    if (!_widget){	g_warning("widget was zero");	return QRect(-1,-1,-1,-1);	ASSERT(_widget);    }    return QRect( _widget->allocation.x,		  _widget->allocation.y,		  _widget->allocation.width,		  _widget->allocation.height);}void QWidget::setFrameGeometry(const QRect &rect){    LOG(KwiqLog, "this:%x, _widget==0, rect:(%d,%d; %d,%d)",	(int)this, 	rect.x(),	rect.y(),	rect.width(), 	rect.height());    ASSERT(_widget);    g_object_freeze_notify(G_OBJECT (_widget));    move(rect.x(), rect.y());    resize(rect.width(), rect.height());    g_object_thaw_notify(G_OBJECT (_widget));}int QWidget::baselinePosition(int height) const{    return (int)((16.0f/20.0f)*height);}bool QWidget::hasFocus() const{        if (!_widget) return  false;    return GTK_WIDGET_HAS_FOCUS (_widget);}void QWidget::setFocus(){    if (hasFocus()) {        return;    }    // KHTML will call setFocus on us without first putting us in our    // superview and positioning us. Normally layout computes the position    // and the drawing process positions the widget. Do both things explicitly.    RenderWidget *renderWidget = 0;    QObject *qo = const_cast<QObject *>(eventFilterObject());        if (qo && QOBJECT_IS_A(qo, khtml::RenderWidget))	renderWidget = static_cast<RenderWidget *>(qo);    int x, y;    if (renderWidget) {        if (renderWidget->canvas()->needsLayout()) {            renderWidget->view()->layout();        }        if (renderWidget->absolutePosition(x, y)) {            renderWidget->view()->addChild(this, x, y);        }    }    if (!_widget)	return;    if (GTK_WIDGET_CAN_FOCUS(_widget)) {        KWQKHTMLPart::bridgeForWidget(this)->makeFirstResponder(_widget);    }}void QWidget::clearFocus(){    if (!hasFocus()) {        return;    }    KWQKHTMLPart::clearDocumentFocus(this);}bool QWidget::checksDescendantsForFocus() const{    return false;}QWidget::FocusPolicy QWidget::focusPolicy() const{    // This provides support for controlling the widgets that take     // part in tab navigation. Widgets must:    // 1. not be hidden by css    // 2. be enabled    // 3. accept first responder    RenderWidget *widget = const_cast<RenderWidget *>	(static_cast<const RenderWidget *>(eventFilterObject()));    if (widget->style()->visibility() != khtml::VISIBLE)        return NoFocus;    if (!isEnabled())        return NoFocus;#if 0        KWQ_BLOCK_EXCEPTIONS;    if (![getView() acceptsFirstResponder])        return NoFocus;    KWQ_UNBLOCK_EXCEPTIONS;#endif        return TabFocus;}const QPalette& QWidget::palette() const{    return data->pal;}void QWidget::setPalette(const QPalette &palette){    data->pal = palette;}void QWidget::unsetPalette(){    // Only called by RenderFormElement::layout, which I suspect will    // have to be rewritten.  Do nothing.}QStyle &QWidget::style() const{    return *data->style;}void QWidget::setStyle(QStyle *style){    // According to the Qt implementation     /*    Sets the widget's GUI style to \a style. Ownership of the style    object is not transferred.    */    data->style = style;}QFont QWidget::font() const{    return data->font;}void QWidget::setFont(const QFont &font){    //g_warning("QWidget::setFont: size:%d, family:%s", font.pixelSize(), font.family().latin1());    data->font = font;    if (_widget){	PangoFontDescription *fd =        	createPangoFontDescription(&font);	gtk_widget_modify_font(_widget, fd);	pango_font_description_free(fd); //should be freed or not?    }}void QWidget::constPolish() const{}bool QWidget::isVisible() const{    if (!_widget) 	return false;    return GTK_WIDGET_VISIBLE(_widget);}void QWidget::setCursor(const QCursor &cur){    if (!_widget) return;    if (_widget->window) {	gdk_window_set_cursor(_widget->window, cur.handle()); // NULL means parent	data->currentCursor = cur;    }}QCursor QWidget::cursor(){    //x doesn't support this..    //in KHTMLView::viewPortMouseEvent this is needed for comparing current vs new    return data->currentCursor;}void QWidget::unsetCursor(){    setCursor(QCursor());}bool QWidget::focusNextPrevChild(bool){    // didn't find anything to focus to. return false, so the event can be    // handled by the parent (by returning FALSE for focus -signal)    return false;}bool QWidget::hasMouseTracking() const{    return true;}void QWidget::show(){    if (!_widget) return;    if (!data || isVisible())        return;    gtk_widget_show_all( _widget );}void QWidget::hide(){        if (!data || !isVisible())        return;    gtk_widget_hide( _widget );}QPoint QWidget::mapFromGlobal(const QPoint &p) const{#if 0    NSPoint bp = {0,0};    KWQ_BLOCK_EXCEPTIONS;    bp = [[KWQKHTMLPart::bridgeForWidget(this) window] convertScreenToBase:[data->view convertPoint:p toView:nil]];    KWQ_UNBLOCK_EXCEPTIONS;#endif    LOG(NotYetImplemented, "KWIQ");    return QPoint();}void QWidget::setGtkWidget(GtkWidget* widget){    if (widget == _widget) return;        _widget = widget;    data->safe_widget = widget;        if (_widget) {	data->safe_widget.connect("focus-in-event",			::focus_inout,			this);	data->safe_widget.connect("focus-out-event",			::focus_inout,			this);	if (widget->window) 	    gdk_window_set_cursor(widget->window, NULL);    }}void QWidget::lockDrawingFocus(){    LOG(NotYetImplemented, "KWIQ");}void QWidget::unlockDrawingFocus(){    LOG(NotYetImplemented, "KWIQ");}void QWidget::disableFlushDrawing(){    LOG(NotYetImplemented, "KWIQ");}void QWidget::enableFlushDrawing(){    LOG(NotYetImplemented, "KWIQ");}void QWidget::setDrawingAlpha(float alpha){    LOG(NotYetImplemented,"KWIQ");}void QWidget::paint(QPainter *p, const QRect &r){    if (p->paintingDisabled()) {        return;    }    data->inPaint++;    GdkEventExpose eev;    eev.type = GDK_EXPOSE;    eev.window = _widget->window;    eev.send_event = TRUE;    eev.count = 0;    eev.area.x =  r.x();    eev.area.y =  r.y();    eev.area.width =  r.width()+1;    eev.area.height = r.height()+1;    eev.region = gdk_region_rectangle(&eev.area);        gtk_widget_send_expose(_widget, (GdkEvent*)&eev);    gdk_region_destroy(eev.region);    data->inPaint--;}void QWidget::sendConsumedMouseUp(){#if 0        khtml::RenderWidget *widget = const_cast<khtml::RenderWidget *>	(static_cast<const khtml::RenderWidget *>(eventFilterObject()));    KWQ_BLOCK_EXCEPTIONS;    widget->sendConsumedMouseUp(QPoint([[NSApp currentEvent] locationInWindow]),			      // FIXME: should send real state and button			      0, 0);#endif        LOG(NotYetImplemented, "KWIQ");}void QWidget::setWritingDirection(QPainter::TextDirection direction){        GtkWidget *w = getGtkWidget();    PangoContext *pc = gtk_widget_get_pango_context( w );    PangoDirection pdir = pango_context_get_base_dir( pc );            switch (direction){    case QPainter::LTR:    {        // do nothing as direction is already correct        if ( pdir == PANGO_DIRECTION_LTR ) return;        pdir = PANGO_DIRECTION_LTR;    }    case QPainter::RTL:        // do nothing as direction is already correct        if ( pdir == PANGO_DIRECTION_RTL ) return;  	pdir = PANGO_DIRECTION_RTL;    }	    pango_context_set_base_dir( pc, pdir );}// caller should destroy descriptionPangoFontDescription* createPangoFontDescription(const QFont* font) {    PangoFontDescription* descr;    descr = pango_font_description_new();    pango_font_description_set_family(descr,	font->family().latin1());        pango_font_description_set_weight(descr,	(font->weight()==QFont::Bold)?PANGO_WEIGHT_BOLD:PANGO_WEIGHT_NORMAL);       pango_font_description_set_style(descr,       font->italic()?PANGO_STYLE_ITALIC:PANGO_STYLE_NORMAL);      if (font->pixelSize()<1){       pango_font_description_set_size(descr,(int)(PANGO_SCALE*12));       LOG(KwiqLog,"QFont::_size < 1");   }   else              pango_font_description_set_size(descr,(int)(PANGO_SCALE*font->pixelSize()));      return descr;}extern "C" {/** @return \TRUE if stops focus in event propagation, \FALSE if propagation continues */static gbooleanfocus_inout(GtkWidget *widget, GdkEventFocus *event, gpointer data){#if DEBUG    qDebug("%s: widget:%x data:%x in:%x\n",	   __PRETTY_FUNCTION__,	   widget,	   data, event->in);#endif    QWidget *self = static_cast<QWidget*>(data);    ASSERT(self);    if (!self->eventFilterObject()) return FALSE;    if (event->in == TRUE){        QFocusEvent event(QEvent::FocusIn);	const_cast<QObject *>(self->eventFilterObject())->eventFilter(self, &event);    } else {	QFocusEvent event(QEvent::FocusOut);        const_cast<QObject *>(self->eventFilterObject())->eventFilter(self, &event);    }    return FALSE;}} /* extern "C" */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -