1 /*
2  * This file is part of the HTML widget for KDE.
3  *
4  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
5  *           (C) 2006 Germain Garand (germain@ebooksfrance.org)
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  */
23 #ifndef render_replaced_h
24 #define render_replaced_h
25 
26 #include "rendering/render_block.h"
27 #include <QObject>
28 #include <QAbstractScrollArea>
29 #include <QScrollBar>
30 #include <QPointer>
31 
32 class KHTMLView;
33 class QWidget;
34 
35 namespace khtml
36 {
37 
38 class RenderReplaced : public RenderBox
39 {
40 public:
41     RenderReplaced(DOM::NodeImpl *node);
42 
renderName()43     const char *renderName() const override
44     {
45         return "RenderReplaced";
46     }
isRenderReplaced()47     bool isRenderReplaced() const override
48     {
49         return true;
50     }
51 
childAllowed()52     bool childAllowed() const override
53     {
54         return false;
55     }
56 
57     void calcMinMaxWidth() override;
58 
intrinsicWidth()59     short intrinsicWidth() const override
60     {
61         return m_intrinsicWidth;
62     }
intrinsicHeight()63     int intrinsicHeight() const override
64     {
65         return m_intrinsicHeight;
66     }
67 
setIntrinsicWidth(int w)68     void setIntrinsicWidth(int w)
69     {
70         m_intrinsicWidth = w;
71     }
setIntrinsicHeight(int h)72     void setIntrinsicHeight(int h)
73     {
74         m_intrinsicHeight = h;
75     }
76 
77     // Return before, after (offset set to max), or inside the replaced element,
78     // at @p offset
79     virtual FindSelectionResult checkSelectionPoint(int _x, int _y, int _tx, int _ty,
80             DOM::NodeImpl *&node, int &offset,
81             SelPointState &);
82 
83     long caretMinOffset() const override;
84     long caretMaxOffset() const override;
85     unsigned long caretMaxRenderedOffset() const override;
86     RenderPosition positionForCoordinates(int x, int y) override;
forceTransparentText()87     virtual bool forceTransparentText() const
88     {
89         return false;
90     }
91 
92 protected:
93     short m_intrinsicWidth;
94     short m_intrinsicHeight;
95 };
96 
97 class RenderWidget : public QObject, public RenderReplaced, public khtml::Shared<RenderWidget>
98 {
99     Q_OBJECT
100 public:
101     RenderWidget(DOM::NodeImpl *node);
102     virtual ~RenderWidget();
103 
104     void setStyle(RenderStyle *style) override;
105     void paint(PaintInfo &i, int tx, int ty) override;
isWidget()106     bool isWidget() const override
107     {
108         return true;
109     }
110 
isFrame()111     virtual bool isFrame() const
112     {
113         return false;
114     }
115 
116     void detach() override;
117     void layout() override;
118 
119     void updateFromElement() override;
handleFocusOut()120     virtual void handleFocusOut() {}
121 
widget()122     QWidget *widget() const
123     {
124         return m_widget;
125     }
view()126     KHTMLView *view() const
127     {
128         return m_view;
129     }
130 
131     void deref();
132 
needsMask()133     bool needsMask() const
134     {
135         return m_needsMask;
136     }
137 
138     static void paintWidget(PaintInfo &pI, QWidget *widget, int tx, int ty, QPixmap *buffer[] = nullptr);
139     bool handleEvent(const DOM::EventImpl &ev) override;
140     bool isRedirectedWidget() const;
isDisabled()141     bool isDisabled() const
142     {
143         return m_widget && !m_widget->isEnabled();
144     }
145 
146 #ifdef ENABLE_DUMP
147     void dump(QTextStream &stream, const QString &ind) const override;
148 #endif
149 
150 public Q_SLOTS:
151     void slotWidgetDestructed();
152 
153 protected:
154     // Should be called by subclasses to ensure we don't memory-manage this..
setDoesNotOwnWidget()155     void setDoesNotOwnWidget()
156     {
157         m_ownsWidget = false;
158     }
159 
160     void paintBoxDecorations(PaintInfo &paintInfo, int _tx, int _ty) override;
161 
canHaveBorder()162     virtual bool canHaveBorder() const
163     {
164         return false;
165     }
includesPadding()166     virtual bool includesPadding() const
167     {
168         return false;
169     }
170 
shouldPaintCSSBorders()171     bool shouldPaintCSSBorders() const
172     {
173         // Don't paint borders if the border-style is native
174         // or borders are not supported on this widget
175         return shouldPaintBackgroundOrBorder() && canHaveBorder() &&
176                (style()->borderLeftStyle() != BNATIVE ||
177                 style()->borderRightStyle()  != BNATIVE ||
178                 style()->borderTopStyle()    != BNATIVE ||
179                 style()->borderBottomStyle() != BNATIVE);
180     }
181 
shouldDisableNativeBorders()182     bool shouldDisableNativeBorders() const
183     {
184         return (shouldPaintCSSBorders() || (!shouldPaintBackgroundOrBorder() && canHaveBorder()));
185     }
186 
acceptsSyntheticEvents()187     virtual bool acceptsSyntheticEvents() const
188     {
189         return true;
190     }
191 
192     bool event(QEvent *e) override;
193 
194     bool eventFilter(QObject * /*o*/, QEvent *e) override;
195     void setQWidget(QWidget *widget);
196     void resizeWidget(int w, int h);
197 
198     QWidget *m_widget;
199     KHTMLView *m_view;
200     QPointer<QWidget> m_underMouse;
201     QPixmap *m_buffer[2];
202 
203     QFrame::Shape m_nativeFrameShape;
204 
205     //Because we mess with normal detach due to ref/deref,
206     //we need to keep track of the arena ourselves
207     //so it doesn't get yanked from us, etc.
208     SharedPtr<RenderArena> m_arena;
209 
210     bool m_needsMask;
211     bool m_ownsWidget;
212 
213 public:
borderTop()214     int borderTop() const override
215     {
216         return canHaveBorder() ? RenderReplaced::borderTop() : 0;
217     }
borderBottom()218     int borderBottom() const override
219     {
220         return canHaveBorder() ? RenderReplaced::borderBottom() : 0;
221     }
borderLeft()222     int borderLeft() const override
223     {
224         return canHaveBorder() ? RenderReplaced::borderLeft() : 0;
225     }
borderRight()226     int borderRight() const override
227     {
228         return canHaveBorder() ? RenderReplaced::borderRight() : 0;
229     }
230 
231     class EventPropagator : public QWidget
232     {
233     public:
234         void sendEvent(QEvent *e);
235     };
236 };
237 
238 class KHTMLWidgetPrivate
239 {
240 public:
KHTMLWidgetPrivate()241     KHTMLWidgetPrivate(): m_rw(nullptr), m_redirected(false) {}
242     QPoint absolutePos();
243     KHTMLView *rootViewPos(QPoint &pos);
renderWidget()244     RenderWidget *renderWidget() const
245     {
246         return m_rw;
247     }
setRenderWidget(RenderWidget * rw)248     void setRenderWidget(RenderWidget *rw)
249     {
250         m_rw = rw;
251     }
isRedirected()252     bool isRedirected() const
253     {
254         return m_redirected;
255     }
256     void setIsRedirected(bool b);
setPos(const QPoint & p)257     void setPos(const QPoint &p)
258     {
259         m_pos = p;
260     }
261 private:
262     QPoint m_pos;
263     RenderWidget *m_rw;
264     bool m_redirected;
265 };
266 
267 extern bool allowWidgetPaintEvents;
268 
269 }
270 
271 #endif
272