Bring back QPixmap::grabWidget() (with a warning).
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Fri, 29 Jul 2011 11:47:23 +0000 (13:47 +0200)
committerSamuel Rødal <samuel.rodal@nokia.com>
Mon, 1 Aug 2011 07:51:38 +0000 (09:51 +0200)
Change-Id: I8bbf07da474bc3ab35980b25c41c2fc4c02e8896
Reviewed-on: http://codereview.qt.nokia.com/2394
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
src/gui/image/qpixmap.cpp
src/gui/image/qpixmap.h
src/widgets/kernel/qwidget.cpp
src/widgets/kernel/qwidget.h

index af27bae..d02da27 100644 (file)
@@ -1029,39 +1029,18 @@ static void sendResizeEvents(QWidget *target)
     \sa grabWindow()
 */
 
-QPixmap QPixmap::grabWidget(QPaintDevice *, const QRect &)
+QPixmap QPixmap::grabWidget(QObject *widget, const QRect &rectangle)
 {
+    QPixmap pixmap;
     // ### Qt5: should we keep or remove this method?
     // SC solution would be to install a callback form QtWidgets, but ugly.
-    qWarning() << "QPixmap::grabWidget is deprecated, use QWidget::render() instead";
-    return QPixmap();
-#if 0
+    qWarning("QPixmap::grabWidget is deprecated, use QWidget::grab() instead");
     if (!widget)
-        return QPixmap();
-
-    if (widget->testAttribute(Qt::WA_PendingResizeEvent) || !widget->testAttribute(Qt::WA_WState_Created))
-        sendResizeEvents(widget);
-
-    widget->d_func()->prepareToRender(QRegion(),
-        QWidget::DrawWindowBackground | QWidget::DrawChildren | QWidget::IgnoreMask);
-
-    QRect r(rect);
-    if (r.width() < 0)
-        r.setWidth(widget->width() - rect.x());
-    if (r.height() < 0)
-        r.setHeight(widget->height() - rect.y());
-
-    if (!r.intersects(widget->rect()))
-        return QPixmap();
-
-    QPixmap res(r.size());
-    if (!qt_widget_private(widget)->isOpaque)
-        res.fill(Qt::transparent);
-
-    widget->d_func()->render(&res, QPoint(), r, QWidget::DrawWindowBackground
-                             | QWidget::DrawChildren | QWidget::IgnoreMask, true);
-    return res;
-#endif
+        return pixmap;
+    QMetaObject::invokeMethod(widget, "grab", Qt::DirectConnection,
+                              Q_RETURN_ARG(QPixmap, pixmap),
+                              Q_ARG(QRect, rectangle));
+    return pixmap;
 }
 
 /*!
index 66f1eda..402708b 100644 (file)
@@ -113,8 +113,8 @@ public:
     QBitmap createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode = Qt::MaskInColor) const;
 
     static QPixmap grabWindow(WId, int x=0, int y=0, int w=-1, int h=-1);
-    static QPixmap grabWidget(QPaintDevice *widget, const QRect &rect);
-    static inline QPixmap grabWidget(QPaintDevice *widget, int x=0, int y=0, int w=-1, int h=-1)
+    static QPixmap grabWidget(QObject *widget, const QRect &rect);
+    static inline QPixmap grabWidget(QObject *widget, int x=0, int y=0, int w=-1, int h=-1)
     { return grabWidget(widget, QRect(x, y, w, h)); }
 
     inline QPixmap scaled(int w, int h, Qt::AspectRatioMode aspectMode = Qt::IgnoreAspectRatio,
index d48d5ae..0e7a12c 100644 (file)
@@ -5150,6 +5150,58 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
     d->extra->inRenderWithPainter = false;
 }
 
+static void sendResizeEvents(QWidget *target)
+{
+    QResizeEvent e(target->size(), QSize());
+    QApplication::sendEvent(target, &e);
+
+    const QObjectList children = target->children();
+    for (int i = 0; i < children.size(); ++i) {
+        QWidget *child = static_cast<QWidget*>(children.at(i));
+        if (child->isWidgetType() && !child->isWindow() && child->testAttribute(Qt::WA_PendingResizeEvent))
+            sendResizeEvents(child);
+    }
+}
+
+/*!
+    \since 5.0
+
+    Renders the widget into a pixmap restricted by the
+    given \a rectangle. If the \a widget has any children, then
+    they are also painted in the appropriate positions.
+
+    If no rectangle is specified (the default) the entire widget is
+    painted.
+
+    Replacement for Qt 4's QPixmap::grabWidget().
+
+    \sa render(), QPixmap
+*/
+
+/* INVOKABLE since used by QPixmap::grabWidget(). */
+QPixmap QWidget::grab(const QRect &rectangle)
+{
+    Q_D(const QWidget);
+    if (testAttribute(Qt::WA_PendingResizeEvent) || !testAttribute(Qt::WA_WState_Created))
+        sendResizeEvents(this);
+
+    QRect r(rectangle);
+    if (r.width() < 0)
+        r.setWidth(width() - rectangle.x());
+    if (r.height() < 0)
+        r.setHeight(height() - rectangle.y());
+
+    if (!r.intersects(rect()))
+        return QPixmap();
+
+    QPixmap res(r.size());
+    if (!d->isOpaque)
+        res.fill(Qt::transparent);
+    render(&res, QPoint(), QRegion(r), QWidget::DrawWindowBackground
+           | QWidget::DrawChildren | QWidget::IgnoreMask);
+    return res;
+}
+
 /*!
     \brief The graphicsEffect function returns a pointer to the
     widget's graphics effect.
index 755feb8..65d5f47 100644 (file)
@@ -104,6 +104,7 @@ class QGraphicsProxyWidget;
 class QGraphicsEffect;
 class QRasterWindowSurface;
 class QUnifiedToolbarSurface;
+class QPixmap;
 #if defined(Q_WS_X11)
 class QX11Info;
 #endif
@@ -362,6 +363,8 @@ public:
                 const QRegion &sourceRegion = QRegion(),
                 RenderFlags renderFlags = RenderFlags(DrawWindowBackground | DrawChildren));
 
+    Q_INVOKABLE QPixmap grab(const QRect &rectangle);
+
 #ifndef QT_NO_GRAPHICSEFFECT
     QGraphicsEffect *graphicsEffect() const;
     void setGraphicsEffect(QGraphicsEffect *effect);