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 <swmodeltestbase.hxx>
12 #include <com/sun/star/awt/XBitmap.hpp>
13 #include <com/sun/star/graphic/XGraphic.hpp>
14 #include <officecfg/Office/Common.hxx>
15 #include <comphelper/processfactory.hxx>
16 #include <unotxdoc.hxx>
20 #include <drawdoc.hxx>
21 #include <unotools/fltrcfg.hxx>
23 class Test
: public SwModelTestBase
26 Test() : SwModelTestBase() {}
28 void testSwappedOutImageExport();
29 void testLinkedGraphicRT();
30 void testImageWithSpecialID();
31 void testGraphicShape();
32 void testCharHighlight();
33 void testCharHighlightBody();
34 void testMSCharBackgroundEditing();
35 void testCharBackgroundToHighlighting();
36 void testSkipImages();
38 CPPUNIT_TEST_SUITE(Test
);
39 CPPUNIT_TEST(testSwappedOutImageExport
);
40 CPPUNIT_TEST(testLinkedGraphicRT
);
41 CPPUNIT_TEST(testImageWithSpecialID
);
42 CPPUNIT_TEST(testGraphicShape
);
43 CPPUNIT_TEST(testCharHighlight
);
44 CPPUNIT_TEST(testMSCharBackgroundEditing
);
45 CPPUNIT_TEST(testCharBackgroundToHighlighting
);
47 CPPUNIT_TEST(testSkipImages
);
49 CPPUNIT_TEST_SUITE_END();
52 void Test::testSwappedOutImageExport()
54 const char* aFilterNames
[] = {
58 "Office Open XML Text",
61 for( size_t nFilter
= 0; nFilter
< SAL_N_ELEMENTS(aFilterNames
); ++nFilter
)
63 // Check whether the export code swaps in the image which was swapped out before by auto mechanism
65 // Set cache size to a very small value to make sure one of the images is swapped out
66 std::shared_ptr
< comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create());
67 officecfg::Office::Common::Cache::GraphicManager::TotalCacheSize::set(static_cast<sal_Int32
>(1), batch
);
71 mxComponent
->dispose();
72 mxComponent
= loadFromDesktop(getURLFromSrc("/sw/qa/extras/globalfilter/data/document_with_two_images.odt"), "com.sun.star.text.TextDocument");
74 // Export the document and import again for a check
75 uno::Reference
<frame::XStorable
> xStorable(mxComponent
, uno::UNO_QUERY
);
77 utl::MediaDescriptor aMediaDescriptor
;
78 aMediaDescriptor
["FilterName"] <<= OUString::createFromAscii(aFilterNames
[nFilter
]);
80 utl::TempFile aTempFile
;
81 aTempFile
.EnableKillingFile();
82 xStorable
->storeToURL(aTempFile
.GetURL(), aMediaDescriptor
.getAsConstPropertyValueList());
83 uno::Reference
< lang::XComponent
> xComponent(xStorable
, uno::UNO_QUERY
);
84 xComponent
->dispose();
85 mxComponent
= loadFromDesktop(aTempFile
.GetURL(), "com.sun.star.text.TextDocument");
87 // Check whether graphic exported well after it was swapped out
88 uno::Reference
<drawing::XDrawPageSupplier
> xDrawPageSupplier(mxComponent
, uno::UNO_QUERY
);
89 uno::Reference
<container::XIndexAccess
> xDraws(xDrawPageSupplier
->getDrawPage(), uno::UNO_QUERY
);
91 const OString sFailedMessage
= OString("Failed on filter: ") + aFilterNames
[nFilter
];
92 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(2), xDraws
->getCount());
95 uno::Reference
<drawing::XShape
> xImage(xDraws
->getByIndex(0), uno::UNO_QUERY
);
96 uno::Reference
< beans::XPropertySet
> XPropSet( xImage
, uno::UNO_QUERY_THROW
);
100 XPropSet
->getPropertyValue("GraphicURL") >>= sURL
;
101 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), sURL
!= "vnd.sun.star.GraphicObject:00000000000000000000000000000000");
105 uno::Reference
<graphic::XGraphic
> xGraphic
;
106 XPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
107 uno::Reference
<awt::XBitmap
> xBitmap(xGraphic
, uno::UNO_QUERY
);
108 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xBitmap
.is());
109 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(610), xBitmap
->getSize().Width
);
110 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(381), xBitmap
->getSize().Height
);
114 xImage
.set(xDraws
->getByIndex(1), uno::UNO_QUERY
);
115 XPropSet
.set( xImage
, uno::UNO_QUERY_THROW
);
119 XPropSet
->getPropertyValue("GraphicURL") >>= sURL
;
120 CPPUNIT_ASSERT_MESSAGE(
121 sFailedMessage
.getStr(), sURL
!= "vnd.sun.star.GraphicObject:00000000000000000000000000000000");
125 uno::Reference
<graphic::XGraphic
> xGraphic
;
126 XPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
127 uno::Reference
<awt::XBitmap
> xBitmap(xGraphic
, uno::UNO_QUERY
);
128 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xBitmap
.is());
129 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(900), xBitmap
->getSize().Width
);
130 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(600), xBitmap
->getSize().Height
);
135 void Test::testLinkedGraphicRT()
137 const std::vector
<OUString
> aFilterNames
= {
139 // "Rich Text Format", Note: picture is there, but SwGrfNode is not found?
141 "Office Open XML Text",
144 for( size_t nFilter
= 0; nFilter
< aFilterNames
.size(); ++nFilter
)
146 if (mxComponent
.is())
147 mxComponent
->dispose();
148 mxComponent
= loadFromDesktop(getURLFromSrc("/sw/qa/extras/globalfilter/data/document_with_linked_graphic.odt"), "com.sun.star.text.TextDocument");
150 const OString sFailedMessage
= OString("Failed on filter: ")
151 + OUStringToOString(aFilterNames
[nFilter
], RTL_TEXTENCODING_ASCII_US
);
154 // Export the document and import again for a check
155 uno::Reference
<frame::XStorable
> xStorable(mxComponent
, uno::UNO_QUERY
);
157 utl::MediaDescriptor aMediaDescriptor
;
158 aMediaDescriptor
["FilterName"] <<= aFilterNames
[nFilter
];
160 utl::TempFile aTempFile
;
161 aTempFile
.EnableKillingFile();
162 xStorable
->storeToURL(aTempFile
.GetURL(), aMediaDescriptor
.getAsConstPropertyValueList());
163 uno::Reference
< lang::XComponent
> xComponent(xStorable
, uno::UNO_QUERY
);
164 xComponent
->dispose();
165 mxComponent
= loadFromDesktop(aTempFile
.GetURL(), "com.sun.star.text.TextDocument");
167 SwXTextDocument
* pTextDoc
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
168 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), pTextDoc
);
169 SwDoc
* pDoc
= pTextDoc
->GetDocShell()->GetDoc();
170 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), pDoc
);
171 SwNodes
& aNodes
= pDoc
->GetNodes();
174 bool bImageFound
= false;
175 for( sal_uLong nIndex
= 0; nIndex
< aNodes
.Count(); ++nIndex
)
177 if( aNodes
[nIndex
]->IsGrfNode() )
179 SwGrfNode
* pGrfNode
= aNodes
[nIndex
]->GetGrfNode();
180 CPPUNIT_ASSERT(pGrfNode
);
181 // RT via DOCX makes linked graphic embedded?!
182 if( aFilterNames
[nFilter
] != "Office Open XML Text" )
184 CPPUNIT_ASSERT_MESSAGE( sFailedMessage
.getStr(), pGrfNode
->IsGrfLink());
186 const GraphicObject
& rGraphicObj
= pGrfNode
->GetGrfObj(true);
187 CPPUNIT_ASSERT_MESSAGE( sFailedMessage
.getStr(), !rGraphicObj
.IsSwappedOut());
188 CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage
.getStr(), GRAPHIC_BITMAP
, rGraphicObj
.GetType());
189 CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage
.getStr(), static_cast<sal_uLong
>(864900), rGraphicObj
.GetSizeBytes());
193 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), bImageFound
);
197 void Test::testImageWithSpecialID()
199 // Check how LO handles when the imported graphic's ID is different from that one
200 // which is generated by LO.
202 const char* aFilterNames
[] = {
206 "Office Open XML Text",
209 // Trigger swap out mechanism to test swapped state factor too.
210 std::shared_ptr
< comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create());
211 officecfg::Office::Common::Cache::GraphicManager::TotalCacheSize::set(static_cast<sal_Int32
>(1), batch
);
214 for( size_t nFilter
= 0; nFilter
< SAL_N_ELEMENTS(aFilterNames
); ++nFilter
)
216 if (mxComponent
.is())
217 mxComponent
->dispose();
218 mxComponent
= loadFromDesktop(getURLFromSrc("/sw/qa/extras/globalfilter/data/images_with_special_IDs.odt"), "com.sun.star.text.TextDocument");
220 // Export the document and import again for a check
221 uno::Reference
<frame::XStorable
> xStorable(mxComponent
, uno::UNO_QUERY
);
223 utl::MediaDescriptor aMediaDescriptor
;
224 aMediaDescriptor
["FilterName"] <<= OUString::createFromAscii(aFilterNames
[nFilter
]);
226 utl::TempFile aTempFile
;
227 aTempFile
.EnableKillingFile();
228 xStorable
->storeToURL(aTempFile
.GetURL(), aMediaDescriptor
.getAsConstPropertyValueList());
229 uno::Reference
< lang::XComponent
> xComponent(xStorable
, uno::UNO_QUERY
);
230 xComponent
->dispose();
231 mxComponent
= loadFromDesktop(aTempFile
.GetURL(), "com.sun.star.text.TextDocument");
233 // Check whether graphic exported well
234 uno::Reference
<drawing::XDrawPageSupplier
> xDrawPageSupplier(mxComponent
, uno::UNO_QUERY
);
235 uno::Reference
<container::XIndexAccess
> xDraws(xDrawPageSupplier
->getDrawPage(), uno::UNO_QUERY
);
237 const OString sFailedMessage
= OString("Failed on filter: ") + aFilterNames
[nFilter
];
238 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(2), xDraws
->getCount());
240 uno::Reference
<drawing::XShape
> xImage
= getShape(1);
241 uno::Reference
< beans::XPropertySet
> XPropSet( xImage
, uno::UNO_QUERY_THROW
);
245 XPropSet
->getPropertyValue("GraphicURL") >>= sURL
;
246 CPPUNIT_ASSERT(sURL
!= "vnd.sun.star.GraphicObject:00000000000000000000000000000000");
250 uno::Reference
<graphic::XGraphic
> xGraphic
;
251 XPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
252 uno::Reference
<awt::XBitmap
> xBitmap(xGraphic
, uno::UNO_QUERY
);
253 CPPUNIT_ASSERT(xBitmap
.is());
254 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(610), xBitmap
->getSize().Width
);
255 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(381), xBitmap
->getSize().Height
);
258 xImage
= getShape(2);
259 XPropSet
.set( xImage
, uno::UNO_QUERY_THROW
);
263 XPropSet
->getPropertyValue("GraphicURL") >>= sURL
;
264 CPPUNIT_ASSERT(sURL
!= "vnd.sun.star.GraphicObject:00000000000000000000000000000000");
268 uno::Reference
<graphic::XGraphic
> xGraphic
;
269 XPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
270 uno::Reference
<awt::XBitmap
> xBitmap(xGraphic
, uno::UNO_QUERY
);
271 CPPUNIT_ASSERT(xBitmap
.is());
272 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(900), xBitmap
->getSize().Width
);
273 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(600), xBitmap
->getSize().Height
);
278 void Test::testGraphicShape()
280 // There are two kind of images in Writer: 1) Writer specific handled by SwGrfNode and
281 // 2) graphic shape handled by SdrGrafObj (e.g. after copy&paste from Impress).
283 const char* aFilterNames
[] = {
287 "Office Open XML Text",
290 // Trigger swap out mechanism to test swapped state factor too.
291 std::shared_ptr
< comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create());
292 officecfg::Office::Common::Cache::GraphicManager::TotalCacheSize::set(static_cast<sal_Int32
>(1), batch
);
295 for( size_t nFilter
= 0; nFilter
< SAL_N_ELEMENTS(aFilterNames
); ++nFilter
)
297 if (mxComponent
.is())
298 mxComponent
->dispose();
299 mxComponent
= loadFromDesktop(getURLFromSrc("/sw/qa/extras/globalfilter/data/graphic_shape.odt"), "com.sun.star.text.TextDocument");
301 // Export the document and import again for a check
302 uno::Reference
<frame::XStorable
> xStorable(mxComponent
, uno::UNO_QUERY
);
304 utl::MediaDescriptor aMediaDescriptor
;
305 aMediaDescriptor
["FilterName"] <<= OUString::createFromAscii(aFilterNames
[nFilter
]);
307 utl::TempFile aTempFile
;
308 aTempFile
.EnableKillingFile();
309 xStorable
->storeToURL(aTempFile
.GetURL(), aMediaDescriptor
.getAsConstPropertyValueList());
310 uno::Reference
< lang::XComponent
> xComponent(xStorable
, uno::UNO_QUERY
);
311 xComponent
->dispose();
312 mxComponent
= loadFromDesktop(aTempFile
.GetURL(), "com.sun.star.text.TextDocument");
314 // Check whether graphic exported well
315 uno::Reference
<drawing::XDrawPageSupplier
> xDrawPageSupplier(mxComponent
, uno::UNO_QUERY
);
316 uno::Reference
<container::XIndexAccess
> xDraws(xDrawPageSupplier
->getDrawPage(), uno::UNO_QUERY
);
318 const OString sFailedMessage
= OString("Failed on filter: ") + aFilterNames
[nFilter
];
319 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(2), xDraws
->getCount());
321 uno::Reference
<drawing::XShape
> xImage
= getShape(1);
322 uno::Reference
< beans::XPropertySet
> XPropSet( xImage
, uno::UNO_QUERY_THROW
);
323 // First image is embedded
327 XPropSet
->getPropertyValue("GraphicURL") >>= sURL
;
328 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), sURL
!= "vnd.sun.star.GraphicObject:00000000000000000000000000000000");
332 uno::Reference
<graphic::XGraphic
> xGraphic
;
333 XPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
334 uno::Reference
<awt::XBitmap
> xBitmap(xGraphic
, uno::UNO_QUERY
);
335 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xBitmap
.is());
336 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(610), xBitmap
->getSize().Width
);
337 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(381), xBitmap
->getSize().Height
);
340 // MS filters make this kind of linked images broken !?
341 if( OUString::createFromAscii(aFilterNames
[nFilter
]) != "writer8" )
344 // Second image is a linked one
345 xImage
= getShape(2);
346 XPropSet
.set( xImage
, uno::UNO_QUERY_THROW
);
350 XPropSet
->getPropertyValue("GraphicURL") >>= sURL
;
351 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), sURL
.endsWith("linked_graphic.jpg"));
355 uno::Reference
<graphic::XGraphic
> xGraphic
;
356 XPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
357 uno::Reference
<awt::XBitmap
> xBitmap(xGraphic
, uno::UNO_QUERY
);
358 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xBitmap
.is());
359 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(620), xBitmap
->getSize().Width
);
360 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(465), xBitmap
->getSize().Height
);
365 void Test::testCharHighlightBody()
367 // MS Word has two kind of character backgrounds called character shading and highlighting
368 // MS filters handle these attributes separately, but ODF export merges them into one background attribute
370 const char* aFilterNames
[] = {
374 "Office Open XML Text",
377 for( size_t nFilter
= 0; nFilter
< SAL_N_ELEMENTS(aFilterNames
); ++nFilter
)
379 if (mxComponent
.is())
380 mxComponent
->dispose();
381 mxComponent
= loadFromDesktop(getURLFromSrc("/sw/qa/extras/globalfilter/data/char_highlight.docx"),
382 "com.sun.star.text.TextDocument");
384 const OString sFailedMessage
= OString("Failed on filter: ") + aFilterNames
[nFilter
];
386 // Export the document and import again for a check
387 uno::Reference
<frame::XStorable
> xStorable(mxComponent
, uno::UNO_QUERY
);
389 utl::MediaDescriptor aMediaDescriptor
;
390 aMediaDescriptor
["FilterName"] <<= OUString::createFromAscii(aFilterNames
[nFilter
]);
392 utl::TempFile aTempFile
;
393 aTempFile
.EnableKillingFile();
394 xStorable
->storeToURL(aTempFile
.GetURL(), aMediaDescriptor
.getAsConstPropertyValueList());
395 uno::Reference
< lang::XComponent
> xComponent(xStorable
, uno::UNO_QUERY
);
396 xComponent
->dispose();
397 mxComponent
= loadFromDesktop(aTempFile
.GetURL(), "com.sun.star.text.TextDocument");
399 const uno::Reference
< text::XTextRange
> xPara
= getParagraph(1);
400 // Both highlight and background
401 const sal_Int32
nBackColor(0x4F81BD);
402 for( int nRun
= 1; nRun
<= 16; ++nRun
)
404 const uno::Reference
<beans::XPropertySet
> xRun(getRun(xPara
,nRun
), uno::UNO_QUERY
);
405 sal_Int32 nHighlightColor
= 0;
408 case 1: nHighlightColor
= 0x000000; break; //black
409 case 2: nHighlightColor
= 0x0000ff; break; //blue
410 case 3: nHighlightColor
= 0x00ffff; break; //cyan
411 case 4: nHighlightColor
= 0x00ff00; break; //green
412 case 5: nHighlightColor
= 0xff00ff; break; //magenta
413 case 6: nHighlightColor
= 0xff0000; break; //red
414 case 7: nHighlightColor
= 0xffff00; break; //yellow
415 case 8: nHighlightColor
= 0xffffff; break; //white
416 case 9: nHighlightColor
= 0x000080; break;//dark blue
417 case 10: nHighlightColor
= 0x008080; break; //dark cyan
418 case 11: nHighlightColor
= 0x008000; break; //dark green
419 case 12: nHighlightColor
= 0x800080; break; //dark magenta
420 case 13: nHighlightColor
= 0x800000; break; //dark red
421 case 14: nHighlightColor
= 0x808000; break; //dark yellow
422 case 15: nHighlightColor
= 0x808080; break; //dark gray
423 case 16: nHighlightColor
= 0xC0C0C0; break; //light gray
426 if( strcmp(aFilterNames
[nFilter
], "writer8") == 0 )
428 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(COL_TRANSPARENT
), getProperty
<sal_Int32
>(xRun
,"CharHighlight"));
429 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), nHighlightColor
, getProperty
<sal_Int32
>(xRun
,"CharBackColor"));
433 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), nHighlightColor
, getProperty
<sal_Int32
>(xRun
,"CharHighlight"));
434 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), nBackColor
, getProperty
<sal_Int32
>(xRun
,"CharBackColor"));
440 const uno::Reference
<beans::XPropertySet
> xRun(getRun(xPara
,18), uno::UNO_QUERY
);
441 if( strcmp(aFilterNames
[nFilter
], "writer8") == 0 )
443 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(COL_TRANSPARENT
), getProperty
<sal_Int32
>(xRun
,"CharHighlight"));
444 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(0xff0000), getProperty
<sal_Int32
>(xRun
,"CharBackColor"));
448 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(0xff0000), getProperty
<sal_Int32
>(xRun
,"CharHighlight"));
449 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(COL_TRANSPARENT
), getProperty
<sal_Int32
>(xRun
,"CharBackColor"));
455 const uno::Reference
<beans::XPropertySet
> xRun(getRun(xPara
,19), uno::UNO_QUERY
);
456 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(COL_TRANSPARENT
), getProperty
<sal_Int32
>(xRun
,"CharHighlight"));
457 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(0x0000ff), getProperty
<sal_Int32
>(xRun
,"CharBackColor"));
462 void Test::testCharHighlight()
464 SvtFilterOptions
& rOpt
= SvtFilterOptions::Get();
465 rOpt
.SetCharBackground2Shading();
467 testCharHighlightBody();
469 rOpt
.SetCharBackground2Highlighting();
471 testCharHighlightBody();
474 void Test::testMSCharBackgroundEditing()
476 // Simulate the editing process of imported MSO character background attributes
477 // and check how export behaves.
479 const char* aFilterNames
[] = {
483 "Office Open XML Text",
486 for( size_t nFilter
= 0; nFilter
< SAL_N_ELEMENTS(aFilterNames
); ++nFilter
)
488 if (mxComponent
.is())
489 mxComponent
->dispose();
491 mxComponent
= loadFromDesktop(getURLFromSrc("/sw/qa/extras/globalfilter/data/char_background_editing.docx"),
492 "com.sun.star.text.TextDocument");
494 const OString sFailedMessage
= OString("Failed on filter: ") + aFilterNames
[nFilter
];
496 // Check whether import was done on the right way
497 uno::Reference
< text::XTextRange
> xPara
= getParagraph(1);
499 uno::Reference
<beans::XPropertySet
> xRun(getRun(xPara
,1), uno::UNO_QUERY
);
500 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(COL_TRANSPARENT
), getProperty
<sal_Int32
>(xRun
,"CharHighlight"));
501 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(0xff0000), getProperty
<sal_Int32
>(xRun
,"CharBackColor"));
503 xRun
.set(getRun(xPara
,2), uno::UNO_QUERY
);
504 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(0x0000ff), getProperty
<sal_Int32
>(xRun
,"CharHighlight"));
505 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(COL_TRANSPARENT
), getProperty
<sal_Int32
>(xRun
,"CharBackColor"));
507 xRun
.set(getRun(xPara
,3), uno::UNO_QUERY
);
508 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(0x0000ff), getProperty
<sal_Int32
>(xRun
,"CharHighlight"));
509 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(0xff0000), getProperty
<sal_Int32
>(xRun
,"CharBackColor"));
511 xRun
.set(getRun(xPara
,4), uno::UNO_QUERY
);
512 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(COL_TRANSPARENT
), getProperty
<sal_Int32
>(xRun
,"CharHighlight"));
513 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(COL_TRANSPARENT
), getProperty
<sal_Int32
>(xRun
,"CharBackColor"));
517 for( int i
= 1; i
<= 4; ++i
)
519 uno::Reference
<beans::XPropertySet
> xRun(getRun(xPara
,i
), uno::UNO_QUERY
);
521 sal_Int32 nBackColor
= 0;
524 case 1: nBackColor
= 0x000000; break; //black
525 case 2: nBackColor
= 0x00ffff; break; //cyan
526 case 3: nBackColor
= 0x00ff00; break; //green
527 case 4: nBackColor
= 0xff00ff; break; //magenta
529 xRun
->setPropertyValue("CharBackColor", uno::makeAny(static_cast<sal_Int32
>(nBackColor
)));
530 // Remove highlighting
531 xRun
->setPropertyValue("CharHighlight", uno::makeAny(static_cast<sal_Int32
>(COL_TRANSPARENT
)));
532 // Remove shading marker
533 uno::Sequence
<beans::PropertyValue
> aGrabBag
= getProperty
<uno::Sequence
<beans::PropertyValue
> >(xRun
,"CharInteropGrabBag");
534 for (int j
= 0; j
< aGrabBag
.getLength(); ++j
)
536 beans::PropertyValue
& rProp
= aGrabBag
[j
];
537 if (rProp
.Name
== "CharShadingMarker")
539 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), true, rProp
.Value
.get
<bool>());
540 rProp
.Value
= uno::makeAny(false);
543 xRun
->setPropertyValue("CharInteropGrabBag", uno::makeAny(aGrabBag
));
546 SvtFilterOptions
& rOpt
= SvtFilterOptions::Get();
547 rOpt
.SetCharBackground2Highlighting();
549 // Export the document and import again for a check
550 uno::Reference
<frame::XStorable
> xStorable(mxComponent
, uno::UNO_QUERY
);
552 utl::MediaDescriptor aMediaDescriptor
;
553 aMediaDescriptor
["FilterName"] <<= OUString::createFromAscii(aFilterNames
[nFilter
]);
555 utl::TempFile aTempFile
;
556 aTempFile
.EnableKillingFile();
557 xStorable
->storeToURL(aTempFile
.GetURL(), aMediaDescriptor
.getAsConstPropertyValueList());
558 uno::Reference
< lang::XComponent
> xComponent(xStorable
, uno::UNO_QUERY
);
559 xComponent
->dispose();
560 mxComponent
= loadFromDesktop(aTempFile
.GetURL(), "com.sun.star.text.TextDocument");
562 // Check whether background was exported as highlighting
563 xPara
.set(getParagraph(1));
564 for( int i
= 1; i
<= 4; ++i
)
566 sal_Int32 nBackColor
= 0;
569 case 1: nBackColor
= 0x000000; break; //black
570 case 2: nBackColor
= 0x00ffff; break; //cyan
571 case 3: nBackColor
= 0x00ff00; break; //green
572 case 4: nBackColor
= 0xff00ff; break; //magenta
574 const uno::Reference
<beans::XPropertySet
> xRun(getRun(xPara
,i
), uno::UNO_QUERY
);
575 if( strcmp(aFilterNames
[nFilter
], "writer8") == 0 )
577 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(COL_TRANSPARENT
), getProperty
<sal_Int32
>(xRun
,"CharHighlight"));
578 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(nBackColor
), getProperty
<sal_Int32
>(xRun
,"CharBackColor"));
582 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(nBackColor
), getProperty
<sal_Int32
>(xRun
,"CharHighlight"));
583 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(COL_TRANSPARENT
), getProperty
<sal_Int32
>(xRun
,"CharBackColor"));
589 void Test::testCharBackgroundToHighlighting()
591 // MSO highlighting has less kind of values so let's see how LO character background is converted
594 const char* aFilterNames
[] = {
597 "Office Open XML Text",
600 for( size_t nFilter
= 0; nFilter
< SAL_N_ELEMENTS(aFilterNames
); ++nFilter
)
602 if (mxComponent
.is())
603 mxComponent
->dispose();
604 mxComponent
= loadFromDesktop(getURLFromSrc("/sw/qa/extras/globalfilter/data/char_background.odt"),
605 "com.sun.star.text.TextDocument");
607 OString sFailedMessage
= OString("Failed on filter: ") + aFilterNames
[nFilter
];
610 SvtFilterOptions
& rOpt
= SvtFilterOptions::Get();
611 rOpt
.SetCharBackground2Highlighting();
613 // Export the document and import again for a check
614 uno::Reference
<frame::XStorable
> xStorable(mxComponent
, uno::UNO_QUERY
);
616 utl::MediaDescriptor aMediaDescriptor
;
617 aMediaDescriptor
["FilterName"] <<= OUString::createFromAscii(aFilterNames
[nFilter
]);
619 utl::TempFile aTempFile
;
620 aTempFile
.EnableKillingFile();
621 xStorable
->storeToURL(aTempFile
.GetURL(), aMediaDescriptor
.getAsConstPropertyValueList());
622 uno::Reference
< lang::XComponent
> xComponent(xStorable
, uno::UNO_QUERY
);
623 xComponent
->dispose();
624 mxComponent
= loadFromDesktop(aTempFile
.GetURL(), "com.sun.star.text.TextDocument");
626 // Check highlight color
627 const uno::Reference
< text::XTextRange
> xPara
= getParagraph(1);
628 for( int nRun
= 1; nRun
<= 19; ++nRun
)
630 const uno::Reference
<beans::XPropertySet
> xRun(getRun(xPara
,nRun
), uno::UNO_QUERY
);
631 sal_Int32 nHighlightColor
= 0;
634 case 1: nHighlightColor
= 0x000000; break; //black
635 case 2: nHighlightColor
= 0xffff00; break; //yellow
636 case 3: nHighlightColor
= 0xff00ff; break; //magenta
637 case 4: nHighlightColor
= 0x00ffff; break; //cyan
638 case 5: nHighlightColor
= 0xffff00; break; //yellow
639 case 6: nHighlightColor
= 0xff0000; break; //red
640 case 7: nHighlightColor
= 0x0000ff; break; //blue
641 case 8: nHighlightColor
= 0x00ff00; break; //green
642 case 9: nHighlightColor
= 0x008000; break; //dark green
643 case 10: nHighlightColor
= 0x800080; break; //dark magenta
644 case 11: nHighlightColor
= 0x000080; break; //dark blue
645 case 12: nHighlightColor
= 0x808000; break; //dark yellow
646 case 13: nHighlightColor
= 0x808080; break; //dark gray
647 case 14: nHighlightColor
= 0x000000; break; //black
648 case 15: nHighlightColor
= 0xff0000; break; //red
649 case 16: nHighlightColor
= 0xC0C0C0; break; //light gray
650 case 17: nHighlightColor
= 0x800000; break; //dark red
651 case 18: nHighlightColor
= 0x808080; break; //dark gray
652 case 19: nHighlightColor
= 0xffff00; break; //yellow
654 const OString sMessage
= sFailedMessage
+". Index of run with unmatched color: " + OString::number(nRun
);
655 CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage
.getStr(), nHighlightColor
, getProperty
<sal_Int32
>(xRun
,"CharHighlight"));
660 void Test::testSkipImages()
662 // Check how LO skips image loading (but not texts of textboxes and custom shapes)
663 // during DOC and DOCX import, using the "SkipImages" FilterOptions.
665 const char* aFilterNames
[][2] = {
666 { "/sw/qa/extras/globalfilter/data/skipimages.doc", NULL
},
667 { "/sw/qa/extras/globalfilter/data/skipimages.doc", "SkipImages" },
668 { "/sw/qa/extras/globalfilter/data/skipimages.docx", NULL
},
669 { "/sw/qa/extras/globalfilter/data/skipimages.docx", "SkipImages" }
672 for( size_t nFilter
= 0; nFilter
< SAL_N_ELEMENTS(aFilterNames
); ++nFilter
)
674 bool bSkipImages
= aFilterNames
[nFilter
][1] != NULL
;
675 OString sFailedMessage
= OString("Failed on filter: ") + aFilterNames
[nFilter
][0];
677 if (mxComponent
.is())
678 mxComponent
->dispose();
682 // FilterOptions parameter
683 uno::Sequence
<beans::PropertyValue
> args(1);
684 args
[0].Name
= "FilterOptions";
686 args
[0].Value
<<= OUString::createFromAscii(aFilterNames
[nFilter
][1]);
687 args
[0].State
= beans::PropertyState_DIRECT_VALUE
;
688 mxComponent
= loadFromDesktop(getURLFromSrc(aFilterNames
[nFilter
][0]), "com.sun.star.text.TextDocument", args
);
689 sFailedMessage
= sFailedMessage
+ " - " + aFilterNames
[nFilter
][1];
691 mxComponent
= loadFromDesktop(getURLFromSrc(aFilterNames
[nFilter
][0]), "com.sun.star.text.TextDocument");
693 // Check shapes (images, textboxes, custom shapes)
694 uno::Reference
<drawing::XDrawPageSupplier
> xDrawPageSupplier(mxComponent
, uno::UNO_QUERY
);
695 uno::Reference
<container::XIndexAccess
> xDraws(xDrawPageSupplier
->getDrawPage(), uno::UNO_QUERY
);
696 uno::Reference
<drawing::XShape
> xShape
;
697 uno::Reference
<graphic::XGraphic
> xGraphic
;
698 uno::Reference
< beans::XPropertySet
> XPropSet
;
699 uno::Reference
<awt::XBitmap
> xBitmap
;
701 bool bHasTextboxText
= false;
702 bool bHasCustomShapeText
= false;
703 sal_Int32 nImageCount
= 0;
705 for (int i
= 1; i
<= xDraws
->getCount(); i
++)
707 xShape
= getShape(i
);
708 XPropSet
.set( xShape
, uno::UNO_QUERY_THROW
);
711 XPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
712 xBitmap
.set(xGraphic
, uno::UNO_QUERY
);
716 catch (beans::UnknownPropertyException
&)
719 uno::Reference
<text::XTextRange
> xText(xShape
, uno::UNO_QUERY
);
722 OUString shapeText
= xText
->getString();
723 if (shapeText
.startsWith("Lorem ipsum"))
724 bHasTextboxText
= true;
725 else if (shapeText
.startsWith("Nam pretium"))
726 bHasCustomShapeText
= true;
730 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), bHasTextboxText
);
731 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), bHasCustomShapeText
);
732 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(bSkipImages
? 0 : 3), nImageCount
);
737 CPPUNIT_TEST_SUITE_REGISTRATION(Test
);
739 CPPUNIT_PLUGIN_IMPLEMENT();
741 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */