1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include "test/screenshot_test.hxx"
12 #include <com/sun/star/util/XCloseable.hpp>
13 #include <com/sun/star/frame/Desktop.hpp>
14 #include <comphelper/processfactory.hxx>
15 #include <vcl/abstdlg.hxx>
16 #include <vcl/pngwrite.hxx>
17 #include <vcl/svapp.hxx>
18 #include <unotools/configmgr.hxx>
19 #include <unotools/syslocaleoptions.hxx>
23 void splitHelpId( const OString
& rHelpId
, OUString
& rDirname
, OUString
&rBasename
)
25 sal_Int32 nIndex
= rHelpId
.lastIndexOf( '/' );
28 rDirname
= OStringToOUString( rHelpId
.copy( 0, nIndex
), RTL_TEXTENCODING_UTF8
);
30 if( rHelpId
.getLength() > nIndex
+1 )
31 rBasename
= OStringToOUString( rHelpId
.copy( nIndex
+1 ), RTL_TEXTENCODING_UTF8
);
36 using namespace css::uno
;
38 ScreenshotTest::ScreenshotTest()
39 : m_aScreenshotDirectory("/screenshots/"),
42 SvtSysLocaleOptions localeOptions
;
43 maCurrentLanguage
= localeOptions
.GetLocaleConfigString();
46 ScreenshotTest::~ScreenshotTest()
50 void ScreenshotTest::setUp()
52 test::BootstrapFixture::setUp();
54 mxDesktop
= css::frame::Desktop::create( comphelper::getComponentContext(getMultiServiceFactory()) );
55 CPPUNIT_ASSERT_MESSAGE("no desktop!", mxDesktop
.is());
57 osl::FileBase::RC err
= osl::Directory::create( m_directories
.getURLFromWorkdir( OUStringToOString(m_aScreenshotDirectory
, RTL_TEXTENCODING_UTF8
).getStr())) ;
58 CPPUNIT_ASSERT_MESSAGE(OUStringToOString("Failed to create screenshot directory - " + m_directories
.getURLFromWorkdir( OUStringToOString(m_aScreenshotDirectory
, RTL_TEXTENCODING_UTF8
).getStr()), RTL_TEXTENCODING_UTF8
).getStr(), (err
== osl::FileBase::E_None
|| err
== osl::FileBase::E_EXIST
) );
60 // initialize maKnownDialogs
61 if (maKnownDialogs
.empty())
63 registerKnownDialogsByID(maKnownDialogs
);
67 void ScreenshotTest::implSaveScreenshot(const Bitmap
& rScreenshot
, const OString
& rScreenshotId
)
69 OUString aDirname
, aBasename
;
70 splitHelpId(rScreenshotId
, aDirname
, aBasename
);
71 aDirname
= m_aScreenshotDirectory
+ maCurrentLanguage
+ "/" + aDirname
;
73 osl::FileBase::RC err
= osl::Directory::createPath(m_directories
.getURLFromWorkdir(OUStringToOString(aDirname
,RTL_TEXTENCODING_UTF8
).getStr()));
74 CPPUNIT_ASSERT_MESSAGE(OUStringToOString("Failed to create " + aDirname
, RTL_TEXTENCODING_UTF8
).getStr(),
75 (err
== osl::FileBase::E_None
|| err
== osl::FileBase::E_EXIST
));
77 OUString aFullPath
= m_directories
.getPathFromWorkdir(OUStringToOString(aDirname
+ "/" + aBasename
+ ".png",RTL_TEXTENCODING_UTF8
).getStr());
78 SvFileStream
aNew(aFullPath
, StreamMode::WRITE
| StreamMode::TRUNC
);
79 CPPUNIT_ASSERT_MESSAGE(OUStringToOString("Failed to open " + OUString::number(aNew
.GetErrorCode()), RTL_TEXTENCODING_UTF8
).getStr(), aNew
.IsOpen());
81 vcl::PNGWriter
aPNGWriter(rScreenshot
);
82 aPNGWriter
.Write(aNew
);
85 void ScreenshotTest::saveScreenshot(VclAbstractDialog
& rDialog
)
87 const Bitmap
aScreenshot(rDialog
.createScreenshot());
89 if (!aScreenshot
.IsEmpty())
91 const OString aScreenshotId
= rDialog
.GetScreenshotId();
93 if (!aScreenshotId
.isEmpty())
95 implSaveScreenshot(aScreenshot
, aScreenshotId
);
100 void ScreenshotTest::saveScreenshot(Dialog
& rDialog
)
102 const Bitmap
aScreenshot(rDialog
.createScreenshot());
104 if (!aScreenshot
.IsEmpty())
106 const OString aScreenshotId
= rDialog
.GetScreenshotId();
108 if (!aScreenshotId
.isEmpty())
110 implSaveScreenshot(aScreenshot
, aScreenshotId
);
115 VclPtr
<VclAbstractDialog
> ScreenshotTest::createDialogByName(const OString
& rName
)
117 const mapType::const_iterator aHit
= maKnownDialogs
.find(rName
);
119 if (aHit
!= maKnownDialogs
.end())
121 return createDialogByID((*aHit
).second
);
124 return VclPtr
<VclAbstractDialog
>();
127 void ScreenshotTest::dumpDialogToPath(VclAbstractDialog
& rDialog
)
129 const std::vector
<OString
> aPageDescriptions(rDialog
.getAllPageUIXMLDescriptions());
131 if (aPageDescriptions
.size())
133 for (size_t a(0); a
< aPageDescriptions
.size(); a
++)
135 if (rDialog
.selectPageByUIXMLDescription(aPageDescriptions
[a
]))
137 saveScreenshot(rDialog
);
141 CPPUNIT_ASSERT(false);
147 saveScreenshot(rDialog
);
151 void ScreenshotTest::dumpDialogToPath(Dialog
& rDialog
)
153 const std::vector
<OString
> aPageDescriptions(rDialog
.getAllPageUIXMLDescriptions());
155 if (aPageDescriptions
.size())
157 for (size_t a(0); a
< aPageDescriptions
.size(); a
++)
159 if (rDialog
.selectPageByUIXMLDescription(aPageDescriptions
[a
]))
161 saveScreenshot(rDialog
);
165 CPPUNIT_ASSERT(false);
171 saveScreenshot(rDialog
);
175 void ScreenshotTest::dumpDialogToPath(const OString
& rUIXMLDescription
)
177 if (!rUIXMLDescription
.isEmpty())
179 VclPtrInstance
<Dialog
> pDialog(Application::GetDefDialogParent(), WB_STDDIALOG
| WB_SIZEABLE
, Dialog::InitFlag::NoParent
);
182 VclBuilder
aBuilder(pDialog
, VclBuilderContainer::getUIRootDir(), OStringToOUString(rUIXMLDescription
, RTL_TEXTENCODING_UTF8
));
183 vcl::Window
*pRoot
= aBuilder
.get_widget_root();
184 Dialog
*pRealDialog
= dynamic_cast<Dialog
*>(pRoot
);
188 pRealDialog
= pDialog
;
191 pRealDialog
->SetText(utl::ConfigManager::getProductName());
192 pRealDialog
->SetStyle(pDialog
->GetStyle() | WB_CLOSEABLE
);
194 dumpDialogToPath(*pRealDialog
);
197 pDialog
.disposeAndClear();
201 void ScreenshotTest::processAllKnownDialogs()
203 for (mapType::const_iterator i
= getKnownDialogs().begin(); i
!= getKnownDialogs().end(); ++i
)
205 ScopedVclPtr
<VclAbstractDialog
> pDlg(createDialogByID((*i
).second
));
209 // known dialog, dump screenshot to path
210 dumpDialogToPath(*pDlg
);
214 // unknown dialog, should not happen in this basic loop.
215 // You have probably forgotten to add a case and
216 // implementastion to createDialogByID, please do this
221 void ScreenshotTest::processDialogBatchFile(const OUString
& rFile
)
223 test::Directories aDirectories
;
224 const OUString
aURL(aDirectories
.getURLFromSrc(rFile
));
225 SvFileStream
aStream(aURL
, StreamMode::READ
);
227 const OString
aComment("#");
229 while (aStream
.ReadLine(aNextUIFile
))
231 if (!aNextUIFile
.isEmpty() && !aNextUIFile
.startsWith(aComment
))
233 // first check if it's a known dialog
234 ScopedVclPtr
<VclAbstractDialog
> pDlg(createDialogByName(aNextUIFile
));
238 // known dialog, dump screenshot to path
239 dumpDialogToPath(*pDlg
);
243 // unknown dialog, try fallback to generic created
244 // VclBuilder-generated instance. Keep in mind that Dialogs
245 // using this mechanism will probably not be layouted well
246 // since the setup/initialization part is missing. Thus,
247 // only use for fallback when only the UI file is available.
248 dumpDialogToPath(aNextUIFile
);
254 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */