File indexing completed on 2024-04-21 14:58:05

0001 /*
0002  * This file is part of the HTML widget for KDE.
0003  *
0004  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
0005  *           (C) 2006 Germain Garand (germain@ebooksfrance.org)
0006  *
0007  * This library is free software; you can redistribute it and/or
0008  * modify it under the terms of the GNU Library General Public
0009  * License as published by the Free Software Foundation; either
0010  * version 2 of the License, or (at your option) any later version.
0011  *
0012  * This library is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015  * Library General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU Library General Public License
0018  * along with this library; see the file COPYING.LIB.  If not, write to
0019  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020  * Boston, MA 02110-1301, USA.
0021  *
0022  */
0023 #ifndef render_replaced_h
0024 #define render_replaced_h
0025 
0026 #include "rendering/render_block.h"
0027 #include <QObject>
0028 #include <QAbstractScrollArea>
0029 #include <QScrollBar>
0030 #include <QPointer>
0031 
0032 class KHTMLView;
0033 class QWidget;
0034 
0035 namespace khtml
0036 {
0037 
0038 class RenderReplaced : public RenderBox
0039 {
0040 public:
0041     RenderReplaced(DOM::NodeImpl *node);
0042 
0043     const char *renderName() const override
0044     {
0045         return "RenderReplaced";
0046     }
0047     bool isRenderReplaced() const override
0048     {
0049         return true;
0050     }
0051 
0052     bool childAllowed() const override
0053     {
0054         return false;
0055     }
0056 
0057     void calcMinMaxWidth() override;
0058 
0059     short intrinsicWidth() const override
0060     {
0061         return m_intrinsicWidth;
0062     }
0063     int intrinsicHeight() const override
0064     {
0065         return m_intrinsicHeight;
0066     }
0067 
0068     void setIntrinsicWidth(int w)
0069     {
0070         m_intrinsicWidth = w;
0071     }
0072     void setIntrinsicHeight(int h)
0073     {
0074         m_intrinsicHeight = h;
0075     }
0076 
0077     // Return before, after (offset set to max), or inside the replaced element,
0078     // at @p offset
0079     virtual FindSelectionResult checkSelectionPoint(int _x, int _y, int _tx, int _ty,
0080             DOM::NodeImpl *&node, int &offset,
0081             SelPointState &);
0082 
0083     long caretMinOffset() const override;
0084     long caretMaxOffset() const override;
0085     unsigned long caretMaxRenderedOffset() const override;
0086     RenderPosition positionForCoordinates(int x, int y) override;
0087     virtual bool forceTransparentText() const
0088     {
0089         return false;
0090     }
0091 
0092 protected:
0093     short m_intrinsicWidth;
0094     short m_intrinsicHeight;
0095 };
0096 
0097 class RenderWidget : public QObject, public RenderReplaced, public khtml::Shared<RenderWidget>
0098 {
0099     Q_OBJECT
0100 public:
0101     RenderWidget(DOM::NodeImpl *node);
0102     virtual ~RenderWidget();
0103 
0104     void setStyle(RenderStyle *style) override;
0105     void paint(PaintInfo &i, int tx, int ty) override;
0106     bool isWidget() const override
0107     {
0108         return true;
0109     }
0110 
0111     virtual bool isFrame() const
0112     {
0113         return false;
0114     }
0115 
0116     void detach() override;
0117     void layout() override;
0118 
0119     void updateFromElement() override;
0120     virtual void handleFocusOut() {}
0121 
0122     QWidget *widget() const
0123     {
0124         return m_widget;
0125     }
0126     KHTMLView *view() const
0127     {
0128         return m_view;
0129     }
0130 
0131     void deref();
0132 
0133     bool needsMask() const
0134     {
0135         return m_needsMask;
0136     }
0137 
0138     static void paintWidget(PaintInfo &pI, QWidget *widget, int tx, int ty, QPixmap *buffer[] = nullptr);
0139     bool handleEvent(const DOM::EventImpl &ev) override;
0140     bool isRedirectedWidget() const;
0141     bool isDisabled() const
0142     {
0143         return m_widget && !m_widget->isEnabled();
0144     }
0145 
0146 #ifdef ENABLE_DUMP
0147     void dump(QTextStream &stream, const QString &ind) const override;
0148 #endif
0149 
0150 public Q_SLOTS:
0151     void slotWidgetDestructed();
0152 
0153 protected:
0154     // Should be called by subclasses to ensure we don't memory-manage this..
0155     void setDoesNotOwnWidget()
0156     {
0157         m_ownsWidget = false;
0158     }
0159 
0160     void paintBoxDecorations(PaintInfo &paintInfo, int _tx, int _ty) override;
0161 
0162     virtual bool canHaveBorder() const
0163     {
0164         return false;
0165     }
0166     virtual bool includesPadding() const
0167     {
0168         return false;
0169     }
0170 
0171     bool shouldPaintCSSBorders() const
0172     {
0173         // Don't paint borders if the border-style is native
0174         // or borders are not supported on this widget
0175         return shouldPaintBackgroundOrBorder() && canHaveBorder() &&
0176                (style()->borderLeftStyle() != BNATIVE ||
0177                 style()->borderRightStyle()  != BNATIVE ||
0178                 style()->borderTopStyle()    != BNATIVE ||
0179                 style()->borderBottomStyle() != BNATIVE);
0180     }
0181 
0182     bool shouldDisableNativeBorders() const
0183     {
0184         return (shouldPaintCSSBorders() || (!shouldPaintBackgroundOrBorder() && canHaveBorder()));
0185     }
0186 
0187     virtual bool acceptsSyntheticEvents() const
0188     {
0189         return true;
0190     }
0191 
0192     bool event(QEvent *e) override;
0193 
0194     bool eventFilter(QObject * /*o*/, QEvent *e) override;
0195     void setQWidget(QWidget *widget);
0196     void resizeWidget(int w, int h);
0197 
0198     QWidget *m_widget;
0199     KHTMLView *m_view;
0200     QPointer<QWidget> m_underMouse;
0201     QPixmap *m_buffer[2];
0202 
0203     QFrame::Shape m_nativeFrameShape;
0204 
0205     //Because we mess with normal detach due to ref/deref,
0206     //we need to keep track of the arena ourselves
0207     //so it doesn't get yanked from us, etc.
0208     SharedPtr<RenderArena> m_arena;
0209 
0210     bool m_needsMask;
0211     bool m_ownsWidget;
0212 
0213 public:
0214     int borderTop() const override
0215     {
0216         return canHaveBorder() ? RenderReplaced::borderTop() : 0;
0217     }
0218     int borderBottom() const override
0219     {
0220         return canHaveBorder() ? RenderReplaced::borderBottom() : 0;
0221     }
0222     int borderLeft() const override
0223     {
0224         return canHaveBorder() ? RenderReplaced::borderLeft() : 0;
0225     }
0226     int borderRight() const override
0227     {
0228         return canHaveBorder() ? RenderReplaced::borderRight() : 0;
0229     }
0230 
0231     class EventPropagator : public QWidget
0232     {
0233     public:
0234         void sendEvent(QEvent *e);
0235     };
0236 };
0237 
0238 class KHTMLWidgetPrivate
0239 {
0240 public:
0241     KHTMLWidgetPrivate(): m_rw(nullptr), m_redirected(false) {}
0242     QPoint absolutePos();
0243     KHTMLView *rootViewPos(QPoint &pos);
0244     RenderWidget *renderWidget() const
0245     {
0246         return m_rw;
0247     }
0248     void setRenderWidget(RenderWidget *rw)
0249     {
0250         m_rw = rw;
0251     }
0252     bool isRedirected() const
0253     {
0254         return m_redirected;
0255     }
0256     void setIsRedirected(bool b);
0257     void setPos(const QPoint &p)
0258     {
0259         m_pos = p;
0260     }
0261 private:
0262     QPoint m_pos;
0263     RenderWidget *m_rw;
0264     bool m_redirected;
0265 };
0266 
0267 extern bool allowWidgetPaintEvents;
0268 
0269 }
0270 
0271 #endif