vcl/inc/qt5/QtBuilder.hxx     |    1 +
 vcl/inc/qt5/QtTools.hxx       |    1 +
 vcl/qt5/QtBuilder.cxx         |    9 +++++++++
 vcl/qt5/QtInstanceBuilder.cxx |    3 +--
 vcl/qt5/QtInstanceWindow.cxx  |   16 ++++++++++++++--
 vcl/qt5/QtTools.cxx           |   20 ++++++++++++++++++++
 6 files changed, 46 insertions(+), 4 deletions(-)

New commits:
commit 7c2e5de19ff49933ebf4e7f9dd0a013af1205cef
Author:     Michael Weghorn <[email protected]>
AuthorDate: Tue Oct 21 11:57:09 2025 +0200
Commit:     Michael Weghorn <[email protected]>
CommitDate: Tue Oct 21 18:49:09 2025 +0200

    tdf#130857 qt weld: Implement logic to take dialog screenshots
    
    Implement QtInstanceWindow::screenshot
    and QtInstanceBuilder::create_screenshot_window
    that are used to create screenshots of dialogs,
    e.g. using `make screenshot`.
    
    For example, when running
    
        SAL_USE_VCLPLUGIN=qt6 SAL_VCL_QT_USE_WELDED_WIDGETS=1 make 
CppunitTest_sd_dialogs_test
    
    , this will now generate a screenshot of the dialog for which
    support for using native Qt widgets was added in
    
        commit d8d17364ef1f2ff7b26e23a3618e30666ff570e3
        Author: Michael Weghorn <[email protected]>
        Date:   Sat Aug 2 20:10:00 2025 +0200
    
            tdf#130857 qt weld: Support sd "New Snap Guide" dialog
    
    and save that screenshot in
    workdir/screenshots/modules/sdraw/ui/dlgsnap/SnapObjectDialog.png .
    
    Change-Id: I67808102f6d8c5f92f91d8059f5393f84a96d900
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192778
    Reviewed-by: Michael Weghorn <[email protected]>
    Tested-by: Jenkins

diff --git a/vcl/inc/qt5/QtBuilder.hxx b/vcl/inc/qt5/QtBuilder.hxx
index f5f6bc7a395d..0c70f2feb9c0 100644
--- a/vcl/inc/qt5/QtBuilder.hxx
+++ b/vcl/inc/qt5/QtBuilder.hxx
@@ -44,6 +44,7 @@ public:
     virtual ~QtBuilder();
 
     template <typename T = QWidget> T* get(const OUString& rId);
+    OUString getDialogId();
 
     QObject* makeObject(QObject* pParent, std::u16string_view sName, 
std::string_view sType,
                         const OUString& rId, stringmap& rMap);
diff --git a/vcl/inc/qt5/QtTools.hxx b/vcl/inc/qt5/QtTools.hxx
index e441f5a2e8ad..72ea64904d8d 100644
--- a/vcl/inc/qt5/QtTools.hxx
+++ b/vcl/inc/qt5/QtTools.hxx
@@ -166,6 +166,7 @@ sal_uInt16 toVclMouseButtons(Qt::MouseButtons eButtons);
 MouseEvent toVclMouseEvent(QMouseEvent& rEvent);
 
 QImage toQImage(const Image& rImage);
+Image toImage(const QImage& rImage);
 
 QFont toQtFont(const vcl::Font& rVclFont);
 
diff --git a/vcl/qt5/QtBuilder.cxx b/vcl/qt5/QtBuilder.cxx
index 3b485f4542d2..5dbd3ad62400 100644
--- a/vcl/qt5/QtBuilder.cxx
+++ b/vcl/qt5/QtBuilder.cxx
@@ -84,6 +84,15 @@ QWidget* QtBuilder::get_by_name(const OUString& rId)
     return nullptr;
 }
 
+OUString QtBuilder::getDialogId()
+{
+    for (const std::pair<const OUString, QWidget*>& rEntry : m_aWidgets)
+        if (qobject_cast<QDialog*>(rEntry.second))
+            return rEntry.first;
+
+    return OUString();
+}
+
 void QtBuilder::insertComboBoxOrListBoxItems(QObject* pObject, stringmap& rMap,
                                              const 
std::vector<ComboBoxTextItem>& rItems)
 {
diff --git a/vcl/qt5/QtInstanceBuilder.cxx b/vcl/qt5/QtInstanceBuilder.cxx
index 0d44afc9c867..45eae2e090be 100644
--- a/vcl/qt5/QtInstanceBuilder.cxx
+++ b/vcl/qt5/QtInstanceBuilder.cxx
@@ -323,8 +323,7 @@ std::unique_ptr<weld::Assistant> 
QtInstanceBuilder::weld_assistant(const OUStrin
 
 std::unique_ptr<weld::Window> QtInstanceBuilder::create_screenshot_window()
 {
-    assert(false && "Not implemented yet");
-    return nullptr;
+    return weld_dialog(m_xBuilder->getDialogId());
 }
 
 std::unique_ptr<weld::Widget> QtInstanceBuilder::weld_widget(const OUString& 
rId)
diff --git a/vcl/qt5/QtInstanceWindow.cxx b/vcl/qt5/QtInstanceWindow.cxx
index 8de97acbcbaf..f4f1b57e16d1 100644
--- a/vcl/qt5/QtInstanceWindow.cxx
+++ b/vcl/qt5/QtInstanceWindow.cxx
@@ -199,8 +199,20 @@ weld::ScreenShotCollection 
QtInstanceWindow::collect_screenshot_data()
 
 VclPtr<VirtualDevice> QtInstanceWindow::screenshot()
 {
-    assert(false && "Not implemented yet");
-    return nullptr;
+    SolarMutexGuard g;
+
+    VclPtr<VirtualDevice> 
xOutput(VclPtr<VirtualDevice>::Create(DeviceFormat::WITHOUT_ALPHA));
+    GetQtInstance().RunInMainThread([&] {
+        resize_to_request();
+
+        QImage aImage(getQWidget()->size(), QImage::Format_ARGB32);
+        getQWidget()->render(&aImage);
+
+        xOutput->SetOutputSize(toSize(aImage.size()));
+        xOutput->DrawImage(Point(0, 0), toImage(aImage));
+    });
+
+    return xOutput;
 }
 
 const vcl::ILibreOfficeKitNotifier* QtInstanceWindow::GetLOKNotifier() { 
return nullptr; }
diff --git a/vcl/qt5/QtTools.cxx b/vcl/qt5/QtTools.cxx
index ecb360c3d452..7c14e6289002 100644
--- a/vcl/qt5/QtTools.cxx
+++ b/vcl/qt5/QtTools.cxx
@@ -29,11 +29,13 @@
 #include <tools/stream.hxx>
 #include <vcl/event.hxx>
 #include <vcl/image.hxx>
+#include <vcl/filter/PngImageReader.hxx>
 #include <vcl/filter/PngImageWriter.hxx>
 #include <vcl/qt/QtUtils.hxx>
 #include <vcl/stdtext.hxx>
 #include <vcl/svapp.hxx>
 
+#include <QtCore/QBuffer>
 #include <QtGui/QImage>
 
 void CairoDeleter::operator()(cairo_surface_t* pSurface) const { 
cairo_surface_destroy(pSurface); }
@@ -279,6 +281,24 @@ QImage toQImage(const Image& rImage)
     return aImage;
 }
 
+Image toImage(const QImage& rImage)
+{
+    if (rImage.isNull())
+        return {};
+
+    QByteArray aByteArray;
+    QBuffer aBuffer(&aByteArray);
+    aBuffer.open(QIODevice::WriteOnly);
+    rImage.save(&aBuffer, "PNG");
+
+    Bitmap aBitmap;
+    SvMemoryStream aMemoryStream(aByteArray.data(), aByteArray.size(), 
StreamMode::READ);
+    vcl::PngImageReader aReader(aMemoryStream);
+    assert(aReader.read(aBitmap));
+
+    return Image(aBitmap);
+}
+
 QFont toQtFont(const vcl::Font& rVclFont)
 {
     QFont aQFont(toQString(rVclFont.GetFamilyName()), 
rVclFont.GetFontHeight());

Reply via email to