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 "mailmergetestbase.cxx"
12 #include <com/sun/star/text/XPageCursor.hpp>
13 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
14 #include <com/sun/star/util/URLTransformer.hpp>
15 #include <comphelper/sequence.hxx>
16 #include <comphelper/processfactory.hxx>
17 #include <comphelper/propertyvalue.hxx>
18 #include <comphelper/DirectoryHelper.hxx>
23 class MMTest2
: public MailMergeTestBase
27 DECLARE_SHELL_MAILMERGE_TEST(tdf125522_shell
, "tdf125522.odt", "10-testing-addresses.ods", "testing-addresses")
29 // prepare unit test and run
32 // there should be no any text frame in output
33 CPPUNIT_ASSERT(mxSwTextDocument
);
35 const auto & rNodes
= mxSwTextDocument
->GetDocShell()->GetDoc()->GetNodes();
36 for (SwNodeOffset
nodeIndex(0); nodeIndex
<rNodes
.Count(); nodeIndex
++)
38 SwNode
* aNode
= rNodes
[nodeIndex
];
39 if (aNode
->StartOfSectionNode())
41 CPPUNIT_ASSERT(!aNode
->StartOfSectionNode()->GetFlyFormat());
46 DECLARE_SHELL_MAILMERGE_TEST(testTd78611_shell
, "tdf78611.odt", "10-testing-addresses.ods", "testing-addresses")
48 // prepare unit test and run
51 // check: each page (one page is one sub doc) has different paragraphs and header paragraphs.
52 // All header paragraphs should have numbering.
53 xmlDocUniquePtr pXmlDoc
= parseLayoutDump(static_cast<SfxBaseModel
*>(mxSwTextDocument
.get()));
56 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[6]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u
"1");
57 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u
"1.1");
58 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u
"1.2");
60 // check some other pages
61 assertXPath(pXmlDoc
, "/root/page[3]/body/txt[6]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u
"1");
62 assertXPath(pXmlDoc
, "/root/page[5]/body/txt[8]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u
"1.1");
63 assertXPath(pXmlDoc
, "/root/page[7]/body/txt[10]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u
"1.2");
67 DECLARE_FILE_MAILMERGE_TEST(testTd78611_file
, "tdf78611.odt", "10-testing-addresses.ods", "testing-addresses")
69 executeMailMerge(true);
70 for (int doc
= 0; doc
< 10; ++doc
)
72 loadMailMergeDocument( doc
);
73 xmlDocUniquePtr pXmlDoc
= parseLayoutDump(static_cast<SfxBaseModel
*>(mxSwTextDocument
.get()));
74 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[6]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u
"1");
75 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u
"1.1");
76 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwFieldPortion", "expand", u
"1.2");
80 DECLARE_SHELL_MAILMERGE_TEST(testTdf122156_shell
, "linked-with-condition.odt", "5-with-blanks.ods",
83 // A document with a linked section hidden on an "empty field" condition
84 // For combined documents, hidden sections are removed completely
86 CPPUNIT_ASSERT(mxSwTextDocument
);
87 // 5 documents 1 page each, starting at odd page numbers => 9
88 CPPUNIT_ASSERT_EQUAL(sal_uInt16(9), mxSwTextDocument
->GetDocShell()->GetWrtShell()->GetPhyPageNum());
89 uno::Reference
<container::XIndexAccess
> xSections(mxSwTextDocument
->getTextSections(),
90 uno::UNO_QUERY_THROW
);
91 // 2 out of 5 dataset records have empty "Title" field => no sections in respective documents
92 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xSections
->getCount());
95 DECLARE_FILE_MAILMERGE_TEST(testTdf122156_file
, "linked-with-condition.odt", "5-with-blanks.ods",
98 // A document with a linked section hidden on an "empty field" condition
99 // For separate documents, the sections are removed
102 loadMailMergeDocument(0);
103 uno::Reference
<text::XTextSectionsSupplier
> xSectionsSupplier(mxComponent
,
104 uno::UNO_QUERY_THROW
);
105 uno::Reference
<container::XIndexAccess
> xSections(xSectionsSupplier
->getTextSections(),
106 uno::UNO_QUERY_THROW
);
107 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xSections
->getCount());
110 loadMailMergeDocument(1);
111 uno::Reference
<text::XTextSectionsSupplier
> xSectionsSupplier(mxComponent
,
112 uno::UNO_QUERY_THROW
);
113 uno::Reference
<container::XIndexAccess
> xSections(xSectionsSupplier
->getTextSections(),
114 uno::UNO_QUERY_THROW
);
115 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections
->getCount());
116 uno::Reference
<beans::XPropertySet
> xSect(xSections
->getByIndex(0), uno::UNO_QUERY_THROW
);
117 // Record 2 has non-empty "Title" field => section is shown
118 CPPUNIT_ASSERT_EQUAL(true, getProperty
<bool>(xSect
, u
"IsVisible"_ustr
));
121 loadMailMergeDocument(2);
122 uno::Reference
<text::XTextSectionsSupplier
> xSectionsSupplier(mxComponent
,
123 uno::UNO_QUERY_THROW
);
124 uno::Reference
<container::XIndexAccess
> xSections(xSectionsSupplier
->getTextSections(),
125 uno::UNO_QUERY_THROW
);
126 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections
->getCount());
127 uno::Reference
<beans::XPropertySet
> xSect(xSections
->getByIndex(0), uno::UNO_QUERY_THROW
);
128 // Record 3 has non-empty "Title" field => section is shown
129 CPPUNIT_ASSERT_EQUAL(true, getProperty
<bool>(xSect
, u
"IsVisible"_ustr
));
132 loadMailMergeDocument(3);
133 uno::Reference
<text::XTextSectionsSupplier
> xSectionsSupplier(mxComponent
,
134 uno::UNO_QUERY_THROW
);
135 uno::Reference
<container::XIndexAccess
> xSections(xSectionsSupplier
->getTextSections(),
136 uno::UNO_QUERY_THROW
);
137 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xSections
->getCount());
140 loadMailMergeDocument(4);
141 uno::Reference
<text::XTextSectionsSupplier
> xSectionsSupplier(mxComponent
,
142 uno::UNO_QUERY_THROW
);
143 uno::Reference
<container::XIndexAccess
> xSections(xSectionsSupplier
->getTextSections(),
144 uno::UNO_QUERY_THROW
);
145 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections
->getCount());
146 uno::Reference
<beans::XPropertySet
> xSect(xSections
->getByIndex(0), uno::UNO_QUERY_THROW
);
147 // Record 5 has non-empty "Title" field => section is shown
148 CPPUNIT_ASSERT_EQUAL(true, getProperty
<bool>(xSect
, u
"IsVisible"_ustr
));
152 DECLARE_SHELL_MAILMERGE_TEST(exportDirectToPDF_shell
, "linked-with-condition.odt", "5-with-blanks.ods",
157 CPPUNIT_ASSERT(mxSwTextDocument
.is());
159 uno::Reference
<css::frame::XController
> xController(mxSwTextDocument
->getCurrentController());
160 CPPUNIT_ASSERT(xController
.is());
162 uno::Reference
<css::text::XTextViewCursorSupplier
> xSupplier(xController
, uno::UNO_QUERY
);
163 CPPUNIT_ASSERT(xSupplier
.is());
165 uno::Reference
<css::text::XPageCursor
> xPageCursor(xSupplier
->getViewCursor(), uno::UNO_QUERY
);
166 CPPUNIT_ASSERT(xPageCursor
.is());
168 xPageCursor
->jumpToFirstPage();
169 CPPUNIT_ASSERT_EQUAL(sal_Int16(1), xPageCursor
->getPage());
171 uno::Reference
<css::frame::XFrame
> xFrame(xController
->getFrame());
172 CPPUNIT_ASSERT(xFrame
.is());
174 uno::Reference
<css::frame::XDispatchProvider
> xDispatchProvider(xFrame
, uno::UNO_QUERY
);
175 CPPUNIT_ASSERT(xDispatchProvider
.is());
178 aURL
.Complete
= ".uno:ExportDirectToPDF";
180 uno::Reference
<css::util::XURLTransformer
> xParser(css::util::URLTransformer::create(
181 comphelper::getProcessComponentContext()));
182 CPPUNIT_ASSERT(xParser
.is());
183 xParser
->parseStrict(aURL
);
186 uno::Reference
<css::frame::XDispatch
> xDispatch
= xDispatchProvider
->queryDispatch(aURL
, OUString(), 0);
187 CPPUNIT_ASSERT(xDispatch
.is());
189 const OUString
sExportTo(msMailMergeOutputURL
+ "/ExportDirectToPDF.pdf");
190 uno::Sequence
<css::beans::PropertyValue
> aArgs
{
191 comphelper::makePropertyValue(u
"SynchronMode"_ustr
, true),
192 comphelper::makePropertyValue(u
"URL"_ustr
, sExportTo
)
195 xDispatch
->dispatch(aURL
, aArgs
);
196 CPPUNIT_ASSERT(comphelper::DirectoryHelper::fileExists(sExportTo
));
198 SvFileStream
aPDFFile(sExportTo
, StreamMode::READ
);
199 SvMemoryStream aMemory
;
200 aMemory
.WriteStream(aPDFFile
);
201 std::shared_ptr
<vcl::pdf::PDFium
> pPDFium
= vcl::pdf::PDFiumLibrary::get();
205 std::unique_ptr
<vcl::pdf::PDFiumDocument
> pPdfDocument
206 = pPDFium
->openDocument(aMemory
.GetData(), aMemory
.GetSize(), OString());
207 CPPUNIT_ASSERT(pPdfDocument
);
208 CPPUNIT_ASSERT_EQUAL(5, pPdfDocument
->getPageCount());
210 std::unique_ptr
<vcl::pdf::PDFiumPage
> pPdfPage
= pPdfDocument
->openPage(0);
211 CPPUNIT_ASSERT(pPdfPage
);
212 CPPUNIT_ASSERT_EQUAL(4, pPdfPage
->getObjectCount());
215 DECLARE_SHELL_MAILMERGE_TEST(testTdf121168
, "section_ps.odt", "4_v01.ods", "Tabelle1")
217 // A document starting with a section on a page with non-default page style with header
219 CPPUNIT_ASSERT(mxSwTextDocument
);
220 // 4 documents 1 page each, starting at odd page numbers => 7
221 CPPUNIT_ASSERT_EQUAL(sal_uInt16(7), mxSwTextDocument
->GetDocShell()->GetWrtShell()->GetPhyPageNum());
223 SwDoc
* pDocMM
= mxSwTextDocument
->GetDocShell()->GetDoc();
224 SwNodeOffset nSizeMM
= pDocMM
->GetNodes().GetEndOfContent().GetIndex()
225 - pDocMM
->GetNodes().GetEndOfExtras().GetIndex() - 2;
226 CPPUNIT_ASSERT_EQUAL(SwNodeOffset(16), nSizeMM
);
228 // All even pages should be empty, all sub-documents have one page
229 const SwRootFrame
* pLayout
= pDocMM
->getIDocumentLayoutAccess().GetCurrentLayout();
230 const SwPageFrame
* pPageFrm
= static_cast<const SwPageFrame
*>(pLayout
->Lower());
233 sal_uInt16 nPageNum
= pPageFrm
->GetPhyPageNum();
234 bool bOdd
= (1 == (nPageNum
% 2));
235 CPPUNIT_ASSERT_EQUAL(!bOdd
, pPageFrm
->IsEmptyPage());
236 CPPUNIT_ASSERT_EQUAL(sal_uInt16(bOdd
? 1 : 2), pPageFrm
->GetVirtPageNum());
239 const SwPageDesc
* pDesc
= pPageFrm
->GetPageDesc();
240 CPPUNIT_ASSERT_EQUAL(OUString("Teststyle" + OUString::number(nPageNum
/ 2 + 1)),
243 pPageFrm
= static_cast<const SwPageFrame
*>(pPageFrm
->GetNext());
248 DECLARE_FILE_MAILMERGE_TEST(testTdf81782_file
, "tdf78611.odt", "10-testing-addresses.ods", "testing-addresses")
250 executeMailMerge(true);
251 for (int doc
= 0; doc
< 10; ++doc
)
253 loadMailMergeDocument( doc
);
255 // get document properties
256 uno::Reference
<document::XDocumentPropertiesSupplier
> xDocumentPropertiesSupplier(mxComponent
, uno::UNO_QUERY
);
257 uno::Reference
<document::XDocumentProperties
> xDocumentProperties(xDocumentPropertiesSupplier
->getDocumentProperties());
259 // check if properties were set
260 uno::Sequence
<OUString
> aKeywords(xDocumentProperties
->getKeywords());
261 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aKeywords
.getLength());
262 CPPUNIT_ASSERT_EQUAL(u
"one two"_ustr
, aKeywords
[0]);
264 // check title and subject
265 CPPUNIT_ASSERT_EQUAL(u
"my title"_ustr
, xDocumentProperties
->getTitle());
266 CPPUNIT_ASSERT_EQUAL(u
"my subject"_ustr
, xDocumentProperties
->getSubject());
270 // problem was: field content was duplicated & truncated
271 DECLARE_SHELL_MAILMERGE_TEST(testTdf81750_shell
, "tdf81750.odt", "10-testing-addresses.ods", "testing-addresses")
273 // prepare unit test and run
276 // check several pages page
277 OUString
aExpected(u
"Text: Foo "_ustr
);
278 xmlDocUniquePtr pXmlDoc
= parseLayoutDump(static_cast<SfxBaseModel
*>(mxSwTextDocument
.get()));
279 assertXPathContent(pXmlDoc
, "/root/page[1]/body/txt[2]", aExpected
);
280 assertXPathContent(pXmlDoc
, "/root/page[3]/body/txt[2]", aExpected
);
281 assertXPathContent(pXmlDoc
, "/root/page[5]/body/txt[2]", aExpected
);
282 assertXPathContent(pXmlDoc
, "/root/page[7]/body/txt[2]", aExpected
);
283 assertXPathContent(pXmlDoc
, "/root/page[9]/body/txt[2]", aExpected
);
287 DECLARE_FILE_MAILMERGE_TEST(testTdf123057_file
, "pagecounttest.ott", "db_pagecounttest.ods", "Sheet1")
289 uno::Reference
<beans::XPropertySet
> xSect0
, xSect1
;
290 executeMailMerge(true);
292 for (int doc
= 0; doc
< 4; ++doc
)
294 loadMailMergeDocument(doc
);
296 // get document properties
297 uno::Reference
<text::XTextSectionsSupplier
> xSectionsSupplier(mxComponent
, uno::UNO_QUERY_THROW
);
298 uno::Reference
<container::XIndexAccess
> xSections(xSectionsSupplier
->getTextSections(), uno::UNO_QUERY_THROW
);
303 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections
->getCount());
304 xSect0
.set(xSections
->getByIndex(0), uno::UNO_QUERY_THROW
);
305 xSect1
.set(xSections
->getByIndex(1), uno::UNO_QUERY_THROW
);
307 // both sections visible, page num is 2
308 CPPUNIT_ASSERT_EQUAL(2, getPages());
309 CPPUNIT_ASSERT_EQUAL(true, getProperty
<bool>(xSect0
, u
"IsVisible"_ustr
));
310 CPPUNIT_ASSERT_EQUAL(true, getProperty
<bool>(xSect1
, u
"IsVisible"_ustr
));
313 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections
->getCount());
314 xSect0
.set(xSections
->getByIndex(0), uno::UNO_QUERY_THROW
);
316 // second section removed, page num is 1
317 CPPUNIT_ASSERT_EQUAL(1, getPages());
318 CPPUNIT_ASSERT_EQUAL(true, getProperty
<bool>(xSect0
, u
"IsVisible"_ustr
));
321 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections
->getCount());
322 xSect0
.set(xSections
->getByIndex(0), uno::UNO_QUERY_THROW
);
324 // first section removed, page num is 1
325 CPPUNIT_ASSERT_EQUAL(1, getPages());
326 CPPUNIT_ASSERT_EQUAL(true, getProperty
<bool>(xSect0
, u
"IsVisible"_ustr
));
329 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xSections
->getCount());
330 // both sections removed, page num is 1
331 CPPUNIT_ASSERT_EQUAL(1, getPages());
337 // The document has a header with page number and total page count on page 2
338 // (which uses page style "Default Style") but doesn't have a header set
339 // for the first page (which uses page style "First Page").
340 // Fields in the header hadn't been replaced properly.
341 DECLARE_SHELL_MAILMERGE_TEST(testTdf128148
, "tdf128148.odt", "4_v01.ods", "Tabelle1")
344 CPPUNIT_ASSERT(mxSwTextDocument
);
346 // 4 documents with 2 pages each => 8 pages in total
347 CPPUNIT_ASSERT_EQUAL(sal_uInt16(8), mxSwTextDocument
->GetDocShell()->GetWrtShell()->GetPhyPageNum());
349 SwDoc
* pDocMM
= mxSwTextDocument
->GetDocShell()->GetDoc();
350 rtl::Reference
<SwXTextDocument
> xModel
= mxSwTextDocument
->GetDocShell()->GetBaseModel();
351 uno::Reference
<container::XNameAccess
> xStyleFamilies
= xModel
->getStyleFamilies();
352 uno::Reference
<container::XNameAccess
> xStyleFamily(xStyleFamilies
->getByName(u
"PageStyles"_ustr
), uno::UNO_QUERY
);
354 // All odd pages have no header, all even pages should have header with text "Page 2 of 2"
355 const SwRootFrame
* pLayout
= pDocMM
->getIDocumentLayoutAccess().GetCurrentLayout();
356 const SwPageFrame
* pPageFrm
= static_cast<const SwPageFrame
*>(pLayout
->Lower());
359 const sal_uInt16 nPageNum
= pPageFrm
->GetPhyPageNum();
360 const bool bIsEvenPage
= ((nPageNum
% 2) == 0);
362 const OUString
& sPageStyle
= pPageFrm
->GetPageDesc()->GetName();
363 uno::Reference
<beans::XPropertySet
> xPageStyle(xStyleFamily
->getByName(sPageStyle
), uno::UNO_QUERY
);
365 bool bHeaderIsOn
= false;
366 xPageStyle
->getPropertyValue(UNO_NAME_HEADER_IS_ON
) >>= bHeaderIsOn
;
368 // first page for every data record shouldn't have header, second should
369 CPPUNIT_ASSERT_EQUAL(bIsEvenPage
, bHeaderIsOn
);
372 // text in header on even pages with correctly replaced fields is "Page 2 of 2"
373 uno::Reference
<text::XText
> xHeaderText
;
374 xPageStyle
->getPropertyValue(UNO_NAME_HEADER_TEXT
) >>= xHeaderText
;
375 const OUString sHeaderText
= xHeaderText
->getString();
376 CPPUNIT_ASSERT_EQUAL(u
"Page 2 of 2"_ustr
, sHeaderText
);
379 pPageFrm
= static_cast<const SwPageFrame
*>(pPageFrm
->GetNext());
383 DECLARE_MAILMERGE_TEST(testGrabBag
, "grabbagtest.docx", "onecell.xlsx", "Sheet1", "MS Word 2007 XML", MMTest2
, 0, nullptr)
385 executeMailMerge(true);
387 loadMailMergeDocument(0, ".docx");
389 CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), getSwDocShell()->GetWrtShell()->GetPhyPageNum());
392 uno::Reference
<beans::XPropertySet
> const xModel(
393 mxComponent
, uno::UNO_QUERY_THROW
);
394 uno::Sequence
<beans::PropertyValue
> aInteropGrabBag
;
395 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
396 uno::Reference
<beans::XPropertySet
> xTextDocumentPropertySet(xTextDocument
, uno::UNO_QUERY
);
397 xTextDocumentPropertySet
->getPropertyValue(u
"InteropGrabBag"_ustr
) >>= aInteropGrabBag
;
398 CPPUNIT_ASSERT_EQUAL(sal_Int32(12), aInteropGrabBag
.getLength());
400 // check table border - comes from table style "Tabellenraster"
401 uno::Reference
<text::XTextTable
> const xTable(getParagraphOrTable(1, xTextDocument
->getText()), uno::UNO_QUERY_THROW
);
402 uno::Reference
<beans::XPropertySet
> const xTableProps(xTable
, uno::UNO_QUERY_THROW
);
403 CPPUNIT_ASSERT_EQUAL(table::TableBorder(
404 table::BorderLine(util::Color(0), 0, 18, 0), true,
405 table::BorderLine(util::Color(0), 0, 18, 0), true,
406 table::BorderLine(util::Color(0), 0, 18, 0), true,
407 table::BorderLine(util::Color(0), 0, 18, 0), true,
408 table::BorderLine(util::Color(0), 0, 18, 0), true,
409 table::BorderLine(util::Color(0), 0, 0, 0), true,
410 sal_Int16(191), true),
411 getProperty
<table::TableBorder
>(xTableProps
, u
"TableBorder"_ustr
));
413 // check font is Arial - comes from theme (wrong result was "" - nothing)
414 uno::Reference
<text::XText
> const xCell(xTable
->getCellByName(u
"A1"_ustr
), uno::UNO_QUERY_THROW
);
415 uno::Reference
<beans::XPropertySet
> const xParaA1(getParagraphOrTable(1, xCell
->getText()), uno::UNO_QUERY_THROW
);
416 CPPUNIT_ASSERT_EQUAL(u
"Arial"_ustr
, getProperty
<OUString
>(xParaA1
, u
"CharFontName"_ustr
));
419 } // end of anonymous namespace
420 namespace com::sun::star::table
{
422 static std::ostream
& operator<<(std::ostream
& rStream
, table::BorderLine
const& rLine
)
424 rStream
<< "BorderLine(" << rLine
.Color
<< "," << rLine
.InnerLineWidth
<< "," << rLine
.OuterLineWidth
<< "," << rLine
.LineDistance
<< ")";
428 static std::ostream
& operator<<(std::ostream
& rStream
, table::TableBorder
const& rBorder
)
430 rStream
<< "TableBorder(\n "
431 << rBorder
.TopLine
<< "," << static_cast<bool>(rBorder
.IsTopLineValid
) << ",\n "
432 << rBorder
.BottomLine
<< "," << static_cast<bool>(rBorder
.IsBottomLineValid
) << ",\n "
433 << rBorder
.LeftLine
<< "," << static_cast<bool>(rBorder
.IsLeftLineValid
) << ",\n "
434 << rBorder
.RightLine
<< "," << static_cast<bool>(rBorder
.IsRightLineValid
) << ",\n "
435 << rBorder
.HorizontalLine
<< "," << static_cast<bool>(rBorder
.IsHorizontalLineValid
) << ",\n "
436 << rBorder
.VerticalLine
<< "," << static_cast<bool>(rBorder
.IsVerticalLineValid
) << ",\n "
437 << rBorder
.Distance
<< "," << static_cast<bool>(rBorder
.IsDistanceValid
) << ")";
443 CPPUNIT_PLUGIN_IMPLEMENT();
444 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */