Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 : #include <PropertyMap.hxx>
20 : #include <ooxml/resourceids.hxx>
21 : #include <DomainMapper_Impl.hxx>
22 : #include <ConversionHelper.hxx>
23 : #include <i18nutil/paper.hxx>
24 : #include <rtl/ustring.hxx>
25 : #include <com/sun/star/beans/PropertyValue.hpp>
26 : #include <com/sun/star/beans/XMultiPropertySet.hpp>
27 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
28 : #include <com/sun/star/table/BorderLine2.hpp>
29 : #include <com/sun/star/container/XEnumeration.hpp>
30 : #include <com/sun/star/container/XEnumerationAccess.hpp>
31 : #include <com/sun/star/container/XNameContainer.hpp>
32 : #include <com/sun/star/style/BreakType.hpp>
33 : #include <com/sun/star/style/PageStyleLayout.hpp>
34 : #include <com/sun/star/text/RelOrientation.hpp>
35 : #include <com/sun/star/text/WritingMode.hpp>
36 : #include <com/sun/star/text/XTextColumns.hpp>
37 : #include <com/sun/star/text/XText.hpp>
38 : #include <com/sun/star/text/TextGridMode.hpp>
39 : #include <com/sun/star/text/XTextCopy.hpp>
40 : #include "dmapperLoggers.hxx"
41 : #include "PropertyMapHelper.hxx"
42 :
43 : using namespace ::com::sun::star;
44 :
45 : namespace writerfilter {
46 : namespace dmapper{
47 :
48 :
49 :
50 24808 : PropertyMap::PropertyMap() :
51 : m_cFootnoteSymbol( 0 ),
52 24808 : m_nFootnoteFontId( -1 )
53 : {
54 24808 : }
55 :
56 :
57 42312 : PropertyMap::~PropertyMap()
58 : {
59 42312 : }
60 :
61 :
62 5126 : uno::Sequence< beans::PropertyValue > PropertyMap::GetPropertyValues()
63 : {
64 5126 : if(!m_aValues.getLength() && size())
65 : {
66 4328 : m_aValues.realloc( size() );
67 4328 : ::com::sun::star::beans::PropertyValue* pValues = m_aValues.getArray();
68 : //style names have to be the first elements within the property sequence
69 : //otherwise they will overwrite 'hard' attributes
70 4328 : sal_Int32 nValue = 0;
71 4328 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
72 4328 : PropertyMap::iterator aParaStyleIter = find(PropertyDefinition( PROP_PARA_STYLE_NAME, false ) );
73 4328 : if( aParaStyleIter != end())
74 : {
75 1464 : pValues[nValue].Name = rPropNameSupplier.GetName( aParaStyleIter->first.eId );
76 1464 : pValues[nValue].Value = aParaStyleIter->second;
77 1464 : ++nValue;
78 : }
79 :
80 4328 : PropertyMap::iterator aCharStyleIter = find(PropertyDefinition( PROP_CHAR_STYLE_NAME, false ));
81 4328 : if( aCharStyleIter != end())
82 : {
83 12 : pValues[nValue].Name = rPropNameSupplier.GetName( aCharStyleIter->first.eId );
84 12 : pValues[nValue].Value = aCharStyleIter->second;
85 12 : ++nValue;
86 : }
87 4328 : PropertyMap::iterator aNumRuleIter = find(PropertyDefinition( PROP_NUMBERING_RULES, false ) );
88 4328 : if( aNumRuleIter != end())
89 : {
90 44 : pValues[nValue].Name = rPropNameSupplier.GetName( aNumRuleIter->first.eId );
91 44 : pValues[nValue].Value = aNumRuleIter->second;
92 44 : ++nValue;
93 : }
94 4328 : PropertyMap::iterator aMapIter = begin();
95 28660 : for( ; nValue < m_aValues.getLength(); ++aMapIter )
96 : {
97 24332 : if( aMapIter != aParaStyleIter && aMapIter != aCharStyleIter && aMapIter != aNumRuleIter )
98 : {
99 24076 : pValues[nValue].Name = rPropNameSupplier.GetName( aMapIter->first.eId );
100 24076 : pValues[nValue].Value = aMapIter->second;
101 24076 : ++nValue;
102 : }
103 : }
104 : }
105 5126 : return m_aValues;
106 : }
107 :
108 : #ifdef DEBUG_DMAPPER_PROPERTY_MAP
109 : static void lcl_AnyToTag(const uno::Any & rAny)
110 : {
111 : try {
112 : sal_Int32 aInt = 0;
113 : rAny >>= aInt;
114 : dmapper_logger->attribute("value", aInt);
115 :
116 : sal_uInt32 auInt = 0;
117 : rAny >>= auInt;
118 : dmapper_logger->attribute("unsignedValue", auInt);
119 :
120 : float aFloat = 0.0f;
121 : rAny >>= aFloat;
122 : dmapper_logger->attribute("floatValue", aFloat);
123 :
124 : OUString aStr;
125 : rAny >>= aStr;
126 : dmapper_logger->attribute("stringValue", aStr);
127 : }
128 : catch (...) {
129 : }
130 : }
131 : #endif
132 :
133 88760 : void PropertyMap::Insert( PropertyIds eId, bool bIsTextProperty, const uno::Any& rAny, bool bOverwrite )
134 : {
135 : #ifdef DEBUG_DMAPPER_PROPERTY_MAP
136 : const OUString& rInsert = PropertyNameSupplier::
137 : GetPropertyNameSupplier().GetName(eId);
138 :
139 : dmapper_logger->startElement("propertyMap.insert");
140 : dmapper_logger->attribute("name", rInsert);
141 : lcl_AnyToTag(rAny);
142 : dmapper_logger->endElement();
143 : #endif
144 :
145 88760 : PropertyMap::iterator aElement = find(PropertyDefinition( eId, bIsTextProperty ) );
146 88760 : if( aElement != end())
147 : {
148 4734 : if(!bOverwrite)
149 88760 : return;
150 2866 : erase( aElement );
151 : }
152 : _PropertyMap::insert( PropertyMap::value_type
153 : (PropertyDefinition( eId, bIsTextProperty),
154 86892 : rAny ));
155 86892 : Invalidate();
156 : }
157 :
158 : #if OSL_DEBUG_LEVEL > 1
159 : void PropertyMap::dumpXml( const TagLogger::Pointer_t pLogger ) const
160 : {
161 : pLogger->startElement("PropertyMap");
162 :
163 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
164 : PropertyMap::const_iterator aMapIter = begin();
165 : while (aMapIter != end())
166 : {
167 : pLogger->startElement("property");
168 :
169 : pLogger->attribute("name", rPropNameSupplier.GetName( aMapIter->first.eId ));
170 :
171 : switch (aMapIter->first.eId)
172 : {
173 : case PROP_TABLE_COLUMN_SEPARATORS:
174 : lcl_DumpTableColumnSeparators(pLogger, aMapIter->second);
175 : break;
176 : default:
177 : {
178 : try {
179 : sal_Int32 aInt = 0;
180 : aMapIter->second >>= aInt;
181 : pLogger->attribute("value", aInt);
182 :
183 : sal_uInt32 auInt = 0;
184 : aMapIter->second >>= auInt;
185 : pLogger->attribute("unsignedValue", auInt);
186 :
187 : float aFloat = 0.0;
188 : aMapIter->second >>= aFloat;
189 : pLogger->attribute("floatValue", aFloat);
190 :
191 : OUString aStr;
192 : aMapIter->second >>= auInt;
193 : pLogger->attribute("stringValue", aStr);
194 : }
195 : catch (...) {
196 : }
197 : }
198 : break;
199 : }
200 :
201 : pLogger->endElement();
202 :
203 : ++aMapIter;
204 : }
205 :
206 : pLogger->endElement();
207 : }
208 : #endif
209 :
210 :
211 :
212 : template<class T>
213 : struct removeExistingElements : public ::std::unary_function<T, void>
214 : {
215 : PropertyMap& rMap;
216 :
217 5872 : removeExistingElements(PropertyMap& _rMap ) : rMap(_rMap) {}
218 6512 : void operator() (T x)
219 : {
220 6512 : PropertyMap::iterator aElement = rMap.find(x.first);
221 6512 : if( aElement != rMap.end())
222 210 : rMap.erase( aElement );
223 6512 : }
224 : };
225 :
226 5872 : void PropertyMap::InsertProps(const PropertyMapPtr pMap)
227 : {
228 5872 : if( pMap.get() )
229 : {
230 11744 : ::std::for_each( pMap->begin(), pMap->end(),
231 17616 : removeExistingElements<PropertyMap::value_type>(*this) );
232 5872 : _PropertyMap::insert(pMap->begin(), pMap->end());
233 5872 : insertTableProperties(pMap.get());
234 :
235 5872 : Invalidate();
236 : }
237 5872 : }
238 :
239 17680 : const uno::Reference< text::XFootnote>& PropertyMap::GetFootnote() const
240 : {
241 17680 : return m_xFootnote;
242 : }
243 :
244 :
245 5278 : void PropertyMap::insertTableProperties( const PropertyMap* )
246 : {
247 : #ifdef DEBUG_DOMAINMAPPER
248 : dmapper_logger->element("PropertyMap.insertTableProperties");
249 : #endif
250 5278 : }
251 :
252 :
253 464 : SectionPropertyMap::SectionPropertyMap(bool bIsFirstSection) :
254 : m_bIsFirstSection( bIsFirstSection )
255 : ,m_nBorderParams( 0 )
256 : ,m_bTitlePage( false )
257 : ,m_nColumnCount( 0 )
258 : ,m_nColumnDistance( 1249 )
259 : ,m_bSeparatorLineIsOn( false )
260 : ,m_bEvenlySpaced( false )
261 : ,m_bIsLandscape( false )
262 : ,m_bPageNoRestart( false )
263 : ,m_nPageNumber( -1 )
264 : ,m_nBreakType( -1 )
265 : ,m_nPaperBin( -1 )
266 : ,m_nFirstPaperBin( -1 )
267 : ,m_nLeftMargin( 3175 ) //page left margin, default 0x708 (1800) twip -> 3175 1/100 mm
268 : ,m_nRightMargin( 3175 )//page right margin, default 0x708 (1800) twip -> 3175 1/100 mm
269 : ,m_nTopMargin( 2540 )
270 : ,m_nBottomMargin( 2540 )
271 : ,m_nHeaderTop( 1270 ) //720 twip
272 : ,m_nHeaderBottom( 1270 )//720 twip
273 : ,m_nDzaGutter( 0 )
274 : ,m_bGutterRTL( false )
275 : ,m_bSFBiDi( false )
276 : ,m_nGridType(0)
277 : ,m_nGridLinePitch( 1 )
278 : ,m_nDxtCharSpace( 0 )
279 : ,m_nLnnMod( 0 )
280 : ,m_nLnc( 0 )
281 : ,m_ndxaLnn( 0 )
282 464 : ,m_nLnnMin( 0 )
283 : {
284 : static sal_Int32 nNumber = 0;
285 464 : nSectionNumber = nNumber++;
286 464 : memset(&m_pBorderLines, 0x00, sizeof(m_pBorderLines));
287 2320 : for( sal_Int32 nBorder = 0; nBorder < 4; ++nBorder )
288 1856 : m_nBorderDistances[ nBorder ] = -1;
289 : //todo: set defaults in ApplyPropertiesToPageStyles
290 : //initialize defaults
291 464 : PaperInfo aLetter(PAPER_LETTER);
292 : //page height, 1/100mm
293 464 : Insert( PROP_HEIGHT, false, uno::makeAny( (sal_Int32) aLetter.getHeight() ) );
294 : //page width, 1/100mm
295 464 : Insert( PROP_WIDTH, false, uno::makeAny( (sal_Int32) aLetter.getWidth() ) );
296 : //page left margin, default 0x708 (1800) twip -> 3175 1/100 mm
297 464 : Insert( PROP_LEFT_MARGIN, false, uno::makeAny( (sal_Int32) 3175 ) );
298 : //page right margin, default 0x708 (1800) twip -> 3175 1/100 mm
299 464 : Insert( PROP_RIGHT_MARGIN, false, uno::makeAny( (sal_Int32) 3175 ) );
300 : //page top margin, default 0x5a0 (1440) twip -> 2540 1/100 mm
301 464 : Insert( PROP_TOP_MARGIN, false, uno::makeAny( (sal_Int32)2540 ) );
302 : //page bottom margin, default 0x5a0 (1440) twip -> 2540 1/100 mm
303 464 : Insert( PROP_BOTTOM_MARGIN, false, uno::makeAny( (sal_Int32) 2540 ) );
304 : //page style layout
305 464 : Insert(PROP_PAGE_STYLE_LAYOUT, false, uno::makeAny(style::PageStyleLayout_ALL));
306 464 : uno::Any aFalse( ::uno::makeAny( false ) );
307 464 : Insert( PROP_GRID_DISPLAY, false, aFalse);
308 464 : Insert( PROP_GRID_PRINT, false, aFalse);
309 464 : Insert( PROP_GRID_MODE, false, uno::makeAny(text::TextGridMode::NONE));
310 :
311 :
312 464 : if( m_bIsFirstSection )
313 : {
314 428 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
315 428 : m_sFirstPageStyleName = rPropNameSupplier.GetName( PROP_FIRST_PAGE );
316 428 : m_sFollowPageStyleName = rPropNameSupplier.GetName( PROP_STANDARD );
317 464 : }
318 464 : }
319 :
320 :
321 1392 : SectionPropertyMap::~SectionPropertyMap()
322 : {
323 2320 : for( sal_Int16 ePos = BORDER_LEFT; ePos <= BORDER_BOTTOM; ++ePos)
324 1856 : delete m_pBorderLines[ePos];
325 928 : }
326 :
327 :
328 32 : OUString lcl_FindUnusedPageStyleName(const uno::Sequence< OUString >& rPageStyleNames)
329 : {
330 : static const sal_Char cDefaultStyle[] = "Converted";
331 : //find the hightest number x in each style with the name "cDefaultStyle+x" and
332 : //return an incremented name
333 32 : sal_Int32 nMaxIndex = 0;
334 32 : const sal_Int32 nDefaultLength = sizeof(cDefaultStyle)/sizeof(sal_Char) - 1;
335 32 : const OUString sDefaultStyle( cDefaultStyle, nDefaultLength, RTL_TEXTENCODING_ASCII_US );
336 :
337 32 : const OUString* pStyleNames = rPageStyleNames.getConstArray();
338 370 : for( sal_Int32 nStyle = 0; nStyle < rPageStyleNames.getLength(); ++nStyle)
339 : {
340 420 : if( pStyleNames[nStyle].getLength() > nDefaultLength &&
341 82 : !rtl_ustr_compare_WithLength( sDefaultStyle.getStr(), nDefaultLength, pStyleNames[nStyle].getStr(), nDefaultLength))
342 : {
343 18 : sal_Int32 nIndex = pStyleNames[nStyle].copy( nDefaultLength ).toInt32();
344 18 : if( nIndex > nMaxIndex)
345 18 : nMaxIndex = nIndex;
346 : }
347 : }
348 32 : OUString sRet( sDefaultStyle );
349 32 : sRet += OUString::valueOf( nMaxIndex + 1);
350 32 : return sRet;
351 : }
352 :
353 :
354 :
355 1242 : uno::Reference< beans::XPropertySet > SectionPropertyMap::GetPageStyle(
356 : const uno::Reference< container::XNameContainer >& xPageStyles,
357 : const uno::Reference < lang::XMultiServiceFactory >& xTextFactory,
358 : bool bFirst )
359 : {
360 1242 : uno::Reference< beans::XPropertySet > xRet;
361 : try
362 : {
363 1242 : if( bFirst )
364 : {
365 392 : if( m_sFirstPageStyleName.isEmpty() && xPageStyles.is() )
366 : {
367 4 : uno::Sequence< OUString > aPageStyleNames = xPageStyles->getElementNames();
368 4 : m_sFirstPageStyleName = lcl_FindUnusedPageStyleName(aPageStyleNames);
369 : m_aFirstPageStyle = uno::Reference< beans::XPropertySet > (
370 4 : xTextFactory->createInstance("com.sun.star.style.PageStyle"),
371 4 : uno::UNO_QUERY);
372 4 : if (xPageStyles.is())
373 4 : xPageStyles->insertByName( m_sFirstPageStyleName, uno::makeAny(m_aFirstPageStyle) );
374 : }
375 388 : else if( !m_aFirstPageStyle.is() && xPageStyles.is() )
376 : {
377 346 : xPageStyles->getByName(m_sFirstPageStyleName) >>= m_aFirstPageStyle;
378 : }
379 392 : xRet = m_aFirstPageStyle;
380 : }
381 : else
382 : {
383 850 : if( m_sFollowPageStyleName.isEmpty() && xPageStyles.is() )
384 : {
385 28 : uno::Sequence< OUString > aPageStyleNames = xPageStyles->getElementNames();
386 28 : m_sFollowPageStyleName = lcl_FindUnusedPageStyleName(aPageStyleNames);
387 : m_aFollowPageStyle = uno::Reference< beans::XPropertySet > (
388 28 : xTextFactory->createInstance("com.sun.star.style.PageStyle"),
389 28 : uno::UNO_QUERY);
390 28 : xPageStyles->insertByName( m_sFollowPageStyleName, uno::makeAny(m_aFollowPageStyle) );
391 : }
392 822 : else if(!m_aFollowPageStyle.is() && xPageStyles.is() )
393 : {
394 348 : xPageStyles->getByName(m_sFollowPageStyleName) >>= m_aFollowPageStyle;
395 : }
396 850 : xRet = m_aFollowPageStyle;
397 : }
398 :
399 : }
400 0 : catch( const uno::Exception& )
401 : {
402 : }
403 :
404 1242 : return xRet;
405 : }
406 :
407 :
408 16 : void SectionPropertyMap::SetBorder( BorderPosition ePos, sal_Int32 nLineDistance, const table::BorderLine2& rBorderLine )
409 : {
410 16 : delete m_pBorderLines[ePos];
411 16 : m_pBorderLines[ePos] = new table::BorderLine2( rBorderLine );
412 16 : m_nBorderDistances[ePos] = nLineDistance;
413 16 : }
414 :
415 :
416 376 : void SectionPropertyMap::ApplyBorderToPageStyles(
417 : const uno::Reference< container::XNameContainer >& xPageStyles,
418 : const uno::Reference < lang::XMultiServiceFactory >& xTextFactory,
419 : sal_Int32 nValue )
420 : {
421 : /*
422 : page border applies to:
423 : nIntValue & 0x07 ->
424 : 0 all pages in this section
425 : 1 first page in this section
426 : 2 all pages in this section but first
427 : 3 whole document (all sections)
428 : nIntValue & 0x18 -> page border depth 0 - in front 1- in back
429 : nIntValue & 0xe0 ->
430 : page border offset from:
431 : 0 offset from text
432 : 1 offset from edge of page
433 : */
434 376 : uno::Reference< beans::XPropertySet > xFirst;
435 376 : uno::Reference< beans::XPropertySet > xSecond;
436 376 : sal_Int32 nOffsetFrom = (nValue & 0x00E0) >> 5;
437 : //todo: negative spacing (from ww8par6.cxx)
438 376 : switch( nValue & 0x07)
439 : {
440 : case 0: /*all styles*/
441 376 : if ( !m_sFollowPageStyleName.isEmpty() )
442 376 : xFirst = GetPageStyle( xPageStyles, xTextFactory, false );
443 376 : if ( !m_sFirstPageStyleName.isEmpty() )
444 354 : xSecond = GetPageStyle( xPageStyles, xTextFactory, true );
445 376 : break;
446 : case 1: /*first page*/
447 0 : if ( !m_sFirstPageStyleName.isEmpty() )
448 0 : xFirst = GetPageStyle( xPageStyles, xTextFactory, true );
449 0 : break;
450 : case 2: /*left and right*/
451 0 : if ( !m_sFollowPageStyleName.isEmpty() )
452 0 : xFirst = GetPageStyle( xPageStyles, xTextFactory, false );
453 0 : break;
454 : case 3: //whole document?
455 : //todo: how to apply a border to the whole document - find all sections or access all page styles?
456 : default:
457 376 : return;
458 : }
459 : //has to be sorted like enum BorderPosition: l-r-t-b
460 : static const PropertyIds aBorderIds[4] =
461 : {
462 : PROP_LEFT_BORDER,
463 : PROP_RIGHT_BORDER,
464 : PROP_TOP_BORDER,
465 : PROP_BOTTOM_BORDER
466 : };
467 : static const PropertyIds aBorderDistanceIds[4] =
468 : {
469 : PROP_LEFT_BORDER_DISTANCE,
470 : PROP_RIGHT_BORDER_DISTANCE,
471 : PROP_TOP_BORDER_DISTANCE,
472 : PROP_BOTTOM_BORDER_DISTANCE
473 : };
474 : static const PropertyIds aMarginIds[4] =
475 : {
476 : PROP_LEFT_MARGIN,
477 : PROP_RIGHT_MARGIN,
478 : PROP_TOP_MARGIN,
479 : PROP_BOTTOM_MARGIN
480 : };
481 :
482 376 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
483 1880 : for( sal_Int32 nBorder = 0; nBorder < 4; ++nBorder)
484 : {
485 1504 : if( m_pBorderLines[nBorder] )
486 : {
487 16 : const OUString sBorderName = rPropNameSupplier.GetName( aBorderIds[nBorder] );
488 16 : if (xFirst.is())
489 16 : xFirst->setPropertyValue( sBorderName, uno::makeAny( *m_pBorderLines[nBorder] ));
490 16 : if(xSecond.is())
491 16 : xSecond->setPropertyValue( sBorderName, uno::makeAny( *m_pBorderLines[nBorder] ));
492 : }
493 1504 : if( m_nBorderDistances[nBorder] >= 0 )
494 : {
495 16 : sal_uInt32 nLineWidth = 0;
496 16 : if (m_pBorderLines[nBorder])
497 16 : nLineWidth = m_pBorderLines[nBorder]->LineWidth;
498 16 : SetBorderDistance( xFirst, aMarginIds[nBorder], aBorderDistanceIds[nBorder],
499 32 : m_nBorderDistances[nBorder], nOffsetFrom, nLineWidth );
500 16 : if(xSecond.is())
501 16 : SetBorderDistance( xSecond, aMarginIds[nBorder], aBorderDistanceIds[nBorder],
502 32 : m_nBorderDistances[nBorder], nOffsetFrom, nLineWidth );
503 : }
504 376 : }
505 : }
506 :
507 32 : void SectionPropertyMap::SetBorderDistance( uno::Reference< beans::XPropertySet > xStyle,
508 : PropertyIds eMarginId, PropertyIds eDistId, sal_Int32 nDistance, sal_Int32 nOffsetFrom, sal_uInt32 nLineWidth )
509 : {
510 32 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
511 :
512 32 : sal_Int32 nDist = nDistance;
513 32 : if( nOffsetFrom == 1 )
514 : {
515 32 : const OUString sMarginName = rPropNameSupplier.GetName( eMarginId );
516 32 : uno::Any aMargin = xStyle->getPropertyValue( sMarginName );
517 32 : sal_Int32 nMargin = 0;
518 32 : aMargin >>= nMargin;
519 :
520 : // Change the margins with the ( border distance - line width )
521 32 : xStyle->setPropertyValue( sMarginName, uno::makeAny( nDistance - nLineWidth ) );
522 :
523 : // Set the distance to ( Margin - distance )
524 32 : nDist = nMargin - nDistance;
525 : }
526 32 : const OUString sBorderDistanceName = rPropNameSupplier.GetName( eDistId );
527 32 : if (xStyle.is())
528 32 : xStyle->setPropertyValue( sBorderDistanceName, uno::makeAny( nDist ));
529 32 : }
530 :
531 :
532 :
533 2 : uno::Reference< text::XTextColumns > SectionPropertyMap::ApplyColumnProperties(
534 : uno::Reference< beans::XPropertySet > xColumnContainer )
535 : {
536 2 : uno::Reference< text::XTextColumns > xColumns;
537 : try
538 : {
539 2 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
540 2 : const OUString sTextColumns = rPropNameSupplier.GetName( PROP_TEXT_COLUMNS );
541 2 : if (xColumnContainer.is())
542 2 : xColumnContainer->getPropertyValue(sTextColumns) >>= xColumns;
543 2 : uno::Reference< beans::XPropertySet > xColumnPropSet( xColumns, uno::UNO_QUERY_THROW );
544 6 : if( !m_bEvenlySpaced &&
545 2 : (sal_Int32(m_aColWidth.size()) == (m_nColumnCount + 1 )) &&
546 2 : (sal_Int32(m_aColDistance.size()) == m_nColumnCount))
547 : {
548 : //the column width in word is an absolute value, in OOo it's relative
549 : //the distances are both absolute
550 2 : sal_Int32 nColSum = 0;
551 6 : for( sal_Int32 nCol = 0; nCol <= m_nColumnCount; ++nCol)
552 : {
553 4 : nColSum += m_aColWidth[nCol];
554 4 : if(nCol)
555 2 : nColSum += m_aColDistance[nCol -1];
556 : }
557 :
558 2 : sal_Int32 nRefValue = xColumns->getReferenceValue();
559 2 : double fRel = double( nRefValue ) / double( nColSum );
560 2 : uno::Sequence< text::TextColumn > aColumns( m_nColumnCount + 1 );
561 2 : text::TextColumn* pColumn = aColumns.getArray();
562 :
563 2 : nColSum = 0;
564 6 : for( sal_Int32 nCol = 0; nCol <= m_nColumnCount; ++nCol)
565 : {
566 4 : pColumn[nCol].LeftMargin = nCol ? m_aColDistance[nCol - 1 ] / 2 : 0;
567 4 : pColumn[nCol].RightMargin = nCol == m_nColumnCount ? 0 : m_aColDistance[nCol] / 2;
568 4 : pColumn[nCol].Width = sal_Int32((double( m_aColWidth[nCol] + pColumn[nCol].RightMargin + pColumn[nCol].LeftMargin ) + 0.5 ) * fRel );
569 4 : nColSum += pColumn[nCol].Width;
570 : }
571 2 : if( nColSum != nRefValue )
572 2 : pColumn[m_nColumnCount].Width -= ( nColSum - nRefValue );
573 2 : xColumns->setColumns( aColumns );
574 : }
575 : else
576 : {
577 0 : xColumns->setColumnCount( m_nColumnCount + 1 );
578 0 : xColumnPropSet->setPropertyValue( rPropNameSupplier.GetName( PROP_AUTOMATIC_DISTANCE ), uno::makeAny( m_nColumnDistance ));
579 : }
580 :
581 2 : if(m_bSeparatorLineIsOn)
582 0 : xColumnPropSet->setPropertyValue(
583 0 : rPropNameSupplier.GetName( PROP_SEPARATOR_LINE_IS_ON ),
584 0 : uno::makeAny( m_bSeparatorLineIsOn ));
585 2 : xColumnContainer->setPropertyValue( sTextColumns, uno::makeAny( xColumns ) );
586 : }
587 0 : catch( const uno::Exception& )
588 : {
589 : OSL_FAIL( "Exception in SectionPropertyMap::ApplyColumnProperties");
590 : }
591 2 : return xColumns;
592 : }
593 :
594 :
595 :
596 394 : bool SectionPropertyMap::HasHeader(bool bFirstPage) const
597 : {
598 394 : bool bRet = false;
599 394 : if( (bFirstPage && m_aFirstPageStyle.is()) ||( !bFirstPage && m_aFollowPageStyle.is()) )
600 : {
601 376 : if( bFirstPage )
602 6 : m_aFirstPageStyle->getPropertyValue(
603 6 : PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_HEADER_IS_ON) ) >>= bRet;
604 : else
605 370 : m_aFollowPageStyle->getPropertyValue(
606 370 : PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_HEADER_IS_ON) ) >>= bRet;
607 : }
608 394 : return bRet;
609 : }
610 :
611 :
612 394 : bool SectionPropertyMap::HasFooter(bool bFirstPage) const
613 : {
614 394 : bool bRet = false;
615 394 : if( (bFirstPage && m_aFirstPageStyle.is()) ||( !bFirstPage && m_aFollowPageStyle.is()) )
616 : {
617 376 : if( bFirstPage )
618 6 : m_aFirstPageStyle->getPropertyValue(
619 6 : PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_FOOTER_IS_ON) ) >>= bRet;
620 : else
621 370 : m_aFollowPageStyle->getPropertyValue(
622 370 : PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_FOOTER_IS_ON) ) >>= bRet;
623 : }
624 394 : return bRet;
625 : }
626 :
627 :
628 : #define MIN_HEAD_FOOT_HEIGHT 100 //minimum header/footer height
629 :
630 394 : void SectionPropertyMap::CopyLastHeaderFooter( bool bFirstPage, DomainMapper_Impl& rDM_Impl )
631 : {
632 : SAL_INFO("writerfilter", "START>>> SectionPropertyMap::CopyLastHeaderFooter()");
633 394 : SectionPropertyMap* pLastContext = rDM_Impl.GetLastSectionContext( );
634 394 : if ( pLastContext )
635 : {
636 : uno::Reference< beans::XPropertySet > xPrevStyle = pLastContext->GetPageStyle(
637 : rDM_Impl.GetPageStyles(),
638 : rDM_Impl.GetTextFactory(),
639 30 : bFirstPage );
640 : uno::Reference< beans::XPropertySet > xStyle = GetPageStyle(
641 : rDM_Impl.GetPageStyles(),
642 : rDM_Impl.GetTextFactory(),
643 30 : bFirstPage );
644 :
645 30 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
646 :
647 : try {
648 : // Loop over the Header and Footer properties to copy them
649 : static PropertyIds aProperties[] =
650 : {
651 : PROP_HEADER_TEXT,
652 : PROP_FOOTER_TEXT,
653 : };
654 :
655 30 : bool bHasPrevHeader = false;
656 30 : bool bHasHeader = false;
657 :
658 30 : OUString sHeaderIsOn = rPropNameSupplier.GetName( PROP_HEADER_IS_ON );
659 30 : if (xPrevStyle.is())
660 30 : xPrevStyle->getPropertyValue( sHeaderIsOn ) >>= bHasPrevHeader;
661 30 : if (xStyle.is())
662 30 : xStyle->getPropertyValue( sHeaderIsOn ) >>= bHasHeader;
663 30 : bool bCopyHeader = bHasPrevHeader && !bHasHeader;
664 :
665 30 : if ( bCopyHeader )
666 0 : xStyle->setPropertyValue( sHeaderIsOn, uno::makeAny( sal_True ) );
667 :
668 30 : bool bHasPrevFooter = false;
669 30 : bool bHasFooter = false;
670 :
671 30 : OUString sFooterIsOn = rPropNameSupplier.GetName( PROP_FOOTER_IS_ON );
672 30 : if (xPrevStyle.is())
673 30 : xPrevStyle->getPropertyValue( sFooterIsOn ) >>= bHasPrevFooter;
674 30 : if (xStyle.is())
675 30 : xStyle->getPropertyValue( sFooterIsOn ) >>= bHasFooter;
676 30 : bool bCopyFooter = bHasPrevFooter && !bHasFooter;
677 :
678 30 : if ( bCopyFooter && xStyle.is() )
679 6 : xStyle->setPropertyValue( sFooterIsOn, uno::makeAny( sal_True ) );
680 :
681 : // Copying the text properties
682 90 : for ( int i = 0, nNbProps = 2; i < nNbProps; i++ )
683 : {
684 60 : bool bIsHeader = ( i < nNbProps / 2 );
685 60 : PropertyIds aPropId = aProperties[i];
686 60 : OUString sName = rPropNameSupplier.GetName( aPropId );
687 :
688 60 : if ( ( bIsHeader && bCopyHeader ) || ( !bIsHeader && bCopyFooter ) )
689 : {
690 : SAL_INFO("writerfilter", "Copying " << sName);
691 : // TODO has to be copied
692 6 : uno::Reference< text::XTextCopy > xTxt;
693 6 : if (xStyle.is())
694 6 : xTxt.set(xStyle->getPropertyValue( sName ), uno::UNO_QUERY_THROW );
695 :
696 6 : uno::Reference< text::XTextCopy > xPrevTxt;
697 6 : if (xPrevStyle.is())
698 6 : xPrevTxt.set(xPrevStyle->getPropertyValue( sName ), uno::UNO_QUERY_THROW );
699 :
700 6 : xTxt->copyText( xPrevTxt );
701 : }
702 90 : }
703 : }
704 0 : catch ( const uno::Exception& e )
705 : {
706 : SAL_INFO("writerfilter", "An exception occurred in SectionPropertyMap::CopyLastHeaderFooter( ) - " << e.Message);
707 30 : }
708 : }
709 : SAL_INFO("writerfilter", "END>>> SectionPropertyMap::CopyLastHeaderFooter()");
710 394 : }
711 :
712 394 : void SectionPropertyMap::PrepareHeaderFooterProperties( bool bFirstPage )
713 : {
714 394 : sal_Int32 nTopMargin = m_nTopMargin;
715 394 : sal_Int32 nHeaderTop = m_nHeaderTop;
716 394 : if(HasHeader(bFirstPage))
717 : {
718 28 : m_nTopMargin = m_nHeaderTop;
719 28 : if( nTopMargin > 0 && nTopMargin > m_nHeaderTop )
720 20 : m_nHeaderTop = nTopMargin - m_nHeaderTop;
721 : else
722 8 : m_nHeaderTop = 0;
723 :
724 : //minimum header height 1mm
725 28 : if( m_nHeaderTop < MIN_HEAD_FOOT_HEIGHT )
726 8 : m_nHeaderTop = MIN_HEAD_FOOT_HEIGHT;
727 : }
728 :
729 :
730 394 : if( nTopMargin >= 0 ) //fixed height header -> see WW8Par6.hxx
731 : {
732 394 : operator[]( PropertyDefinition( PROP_HEADER_IS_DYNAMIC_HEIGHT, false )) = uno::makeAny( true );
733 394 : operator[]( PropertyDefinition( PROP_HEADER_DYNAMIC_SPACING, false )) = uno::makeAny( true );
734 394 : operator[]( PropertyDefinition( PROP_HEADER_BODY_DISTANCE, false )) = uno::makeAny( m_nHeaderTop - MIN_HEAD_FOOT_HEIGHT );// ULSpace.Top()
735 394 : operator[]( PropertyDefinition( PROP_HEADER_HEIGHT, false )) = uno::makeAny( m_nHeaderTop );
736 :
737 : }
738 : else
739 : {
740 : //todo: old filter fakes a frame into the header/footer to support overlapping
741 : //current setting is completely wrong!
742 0 : operator[]( PropertyDefinition( PROP_HEADER_HEIGHT, false )) = uno::makeAny( m_nHeaderTop );
743 0 : operator[]( PropertyDefinition( PROP_HEADER_BODY_DISTANCE, false )) = uno::makeAny( nTopMargin - m_nHeaderTop );
744 0 : operator[]( PropertyDefinition( PROP_HEADER_IS_DYNAMIC_HEIGHT, false)) = uno::makeAny( false );
745 0 : operator[]( PropertyDefinition( PROP_HEADER_DYNAMIC_SPACING, false)) = uno::makeAny( false );
746 : }
747 :
748 394 : sal_Int32 nBottomMargin = m_nBottomMargin;
749 394 : sal_Int32 nHeaderBottom = m_nHeaderBottom;
750 394 : if( HasFooter( bFirstPage ) )
751 : {
752 18 : m_nBottomMargin = m_nHeaderBottom;
753 18 : if( nBottomMargin > 0 && nBottomMargin > m_nHeaderBottom )
754 12 : m_nHeaderBottom = nBottomMargin - m_nHeaderBottom;
755 : else
756 6 : m_nHeaderBottom = 0;
757 18 : if( m_nHeaderBottom < MIN_HEAD_FOOT_HEIGHT )
758 6 : m_nHeaderBottom = MIN_HEAD_FOOT_HEIGHT;
759 : }
760 :
761 394 : if( nBottomMargin >= 0 ) //fixed height footer -> see WW8Par6.hxx
762 : {
763 394 : operator[]( PropertyDefinition( PROP_FOOTER_IS_DYNAMIC_HEIGHT, false )) = uno::makeAny( true );
764 394 : operator[]( PropertyDefinition( PROP_FOOTER_DYNAMIC_SPACING, false )) = uno::makeAny( true );
765 394 : operator[]( PropertyDefinition( PROP_FOOTER_BODY_DISTANCE, false )) = uno::makeAny( m_nHeaderBottom - MIN_HEAD_FOOT_HEIGHT);
766 394 : operator[]( PropertyDefinition( PROP_FOOTER_HEIGHT, false )) = uno::makeAny( m_nHeaderBottom );
767 : }
768 : else
769 : {
770 : //todo: old filter fakes a frame into the header/footer to support overlapping
771 : //current setting is completely wrong!
772 0 : operator[]( PropertyDefinition( PROP_FOOTER_IS_DYNAMIC_HEIGHT, false)) = uno::makeAny( false );
773 0 : operator[]( PropertyDefinition( PROP_FOOTER_DYNAMIC_SPACING, false)) = uno::makeAny( false );
774 0 : operator[]( PropertyDefinition( PROP_FOOTER_HEIGHT, false )) = uno::makeAny( nBottomMargin - m_nHeaderBottom );
775 0 : operator[]( PropertyDefinition( PROP_FOOTER_BODY_DISTANCE, false )) = uno::makeAny( m_nHeaderBottom );
776 : }
777 :
778 : //now set the top/bottom margin for the follow page style
779 394 : operator[]( PropertyDefinition( PROP_TOP_MARGIN, false )) = uno::makeAny( m_nTopMargin );
780 394 : operator[]( PropertyDefinition( PROP_BOTTOM_MARGIN, false )) = uno::makeAny( m_nBottomMargin );
781 :
782 : // Restore original top margin, so we don't end up with a smaller margin in case we have to produce two page styles from one Word section.
783 394 : m_nTopMargin = nTopMargin;
784 394 : m_nHeaderTop = nHeaderTop;
785 394 : m_nHeaderBottom = nHeaderBottom;
786 394 : }
787 :
788 458 : uno::Reference<beans::XPropertySet> lcl_GetRangeProperties(bool bIsFirstSection, DomainMapper_Impl& rDM_Impl, uno::Reference<text::XTextRange> xStartingRange)
789 : {
790 458 : uno::Reference< beans::XPropertySet > xRangeProperties;
791 458 : if (bIsFirstSection && rDM_Impl.GetBodyText().is())
792 : {
793 410 : uno::Reference<container::XEnumerationAccess> xEnumAccess(rDM_Impl.GetBodyText(), uno::UNO_QUERY_THROW);
794 410 : uno::Reference<container::XEnumeration> xEnum = xEnumAccess->createEnumeration();
795 410 : xRangeProperties = uno::Reference<beans::XPropertySet>(xEnum->nextElement(), uno::UNO_QUERY_THROW);
796 : }
797 48 : else if (xStartingRange.is())
798 34 : xRangeProperties = uno::Reference<beans::XPropertySet>(xStartingRange, uno::UNO_QUERY_THROW);
799 458 : return xRangeProperties;
800 : }
801 :
802 460 : void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl )
803 : {
804 460 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
805 460 : if( m_nLnnMod )
806 : {
807 0 : bool bFirst = rDM_Impl.IsLineNumberingSet();
808 0 : rDM_Impl.SetLineNumbering( m_nLnnMod, m_nLnc, m_ndxaLnn );
809 0 : if( m_nLnnMin > 0 || (bFirst && m_nLnc == 1))
810 : {
811 : //set the starting value at the beginning of the section
812 : try
813 : {
814 0 : uno::Reference< beans::XPropertySet > xRangeProperties;
815 0 : if( m_xStartingRange.is() )
816 : {
817 0 : xRangeProperties = uno::Reference< beans::XPropertySet >( m_xStartingRange, uno::UNO_QUERY_THROW );
818 : }
819 : else
820 : {
821 : //set the start value at the beginning of the document
822 0 : xRangeProperties = uno::Reference< beans::XPropertySet >( rDM_Impl.GetTextDocument()->getText()->getStart(), uno::UNO_QUERY_THROW );
823 : }
824 0 : xRangeProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_PARA_LINE_NUMBER_START_VALUE ), uno::makeAny( m_nLnnMin + 1 ));
825 : }
826 0 : catch( const uno::Exception& )
827 : {
828 : OSL_FAIL( "Exception in SectionPropertyMap::CloseSectionGroup");
829 : }
830 : }
831 : }
832 :
833 : //depending on the break type no page styles should be created
834 460 : if(m_nBreakType == 0)
835 : {
836 : //todo: insert a section or access the already inserted section
837 : uno::Reference< beans::XPropertySet > xSection =
838 82 : rDM_Impl.appendTextSectionAfter( m_xStartingRange );
839 82 : if( m_nColumnCount > 0 && xSection.is())
840 0 : ApplyColumnProperties( xSection );
841 82 : uno::Reference<beans::XPropertySet> xRangeProperties(lcl_GetRangeProperties(m_bIsFirstSection, rDM_Impl, m_xStartingRange));
842 82 : if (xRangeProperties.is())
843 74 : xRangeProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_PAGE_DESC_NAME), uno::makeAny(m_bTitlePage ? m_sFirstPageStyleName : m_sFollowPageStyleName));
844 : }
845 : // If the section is of type "New column" (0x01), then simply insert a column break.
846 : // But only if there actually are columns on the page, otherwise a column break
847 : // seems to be handled like a page break by MSO.
848 378 : else if(m_nBreakType == 1 && m_nColumnCount > 0 )
849 : {
850 2 : uno::Reference< beans::XPropertySet > xRangeProperties;
851 2 : if( m_xStartingRange.is() )
852 : {
853 2 : xRangeProperties = uno::Reference< beans::XPropertySet >( m_xStartingRange, uno::UNO_QUERY_THROW );
854 : }
855 : else
856 : {
857 : //set the start value at the beginning of the document
858 0 : xRangeProperties = uno::Reference< beans::XPropertySet >( rDM_Impl.GetTextDocument()->getText()->getStart(), uno::UNO_QUERY_THROW );
859 : }
860 4 : xRangeProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_BREAK_TYPE ),
861 4 : uno::makeAny( com::sun::star::style::BreakType_COLUMN_BEFORE));
862 : }
863 : else
864 : {
865 : //get the properties and create appropriate page styles
866 376 : uno::Reference< beans::XPropertySet > xFollowPageStyle = GetPageStyle( rDM_Impl.GetPageStyles(), rDM_Impl.GetTextFactory(), false );
867 :
868 376 : if( m_nDzaGutter > 0 )
869 : {
870 : //todo: iGutterPos from DocProperties are missing
871 0 : if( m_bGutterRTL )
872 0 : m_nRightMargin += m_nDzaGutter;
873 : else
874 0 : m_nLeftMargin += m_nDzaGutter;
875 : }
876 376 : operator[]( PropertyDefinition( PROP_LEFT_MARGIN, false )) = uno::makeAny( m_nLeftMargin );
877 376 : operator[]( PropertyDefinition( PROP_RIGHT_MARGIN, false )) = uno::makeAny( m_nRightMargin );
878 :
879 : /*** if headers/footers are available then the top/bottom margins of the
880 : header/footer are copied to the top/bottom margin of the page
881 : */
882 376 : CopyLastHeaderFooter( false, rDM_Impl );
883 376 : PrepareHeaderFooterProperties( false );
884 :
885 376 : const OUString sTrayIndex = rPropNameSupplier.GetName( PROP_PRINTER_PAPER_TRAY_INDEX );
886 376 : if( m_nPaperBin >= 0 )
887 0 : xFollowPageStyle->setPropertyValue( sTrayIndex, uno::makeAny( m_nPaperBin ) );
888 376 : uno::Reference< text::XTextColumns > xColumns;
889 376 : if( m_nColumnCount > 0 )
890 2 : xColumns = ApplyColumnProperties( xFollowPageStyle );
891 :
892 : //prepare text grid properties
893 376 : sal_Int32 nHeight = 1;
894 376 : PropertyMap::iterator aElement = find(PropertyDefinition( PROP_HEIGHT, false ));
895 376 : if( aElement != end())
896 376 : aElement->second >>= nHeight;
897 :
898 376 : sal_Int32 nWidth = 1;
899 376 : aElement = find(PropertyDefinition( PROP_WIDTH, false ));
900 376 : if( aElement != end())
901 376 : aElement->second >>= nWidth;
902 :
903 376 : text::WritingMode eWritingMode = text::WritingMode_LR_TB;
904 376 : aElement = find(PropertyDefinition( PROP_WRITING_MODE, false ));
905 376 : if( aElement != end())
906 84 : aElement->second >>= eWritingMode;
907 :
908 : sal_Int32 nTextAreaHeight = eWritingMode == text::WritingMode_LR_TB ?
909 : nHeight - m_nTopMargin - m_nBottomMargin :
910 376 : nWidth - m_nLeftMargin - m_nRightMargin;
911 :
912 376 : sal_Int32 nGridLinePitch = m_nGridLinePitch;
913 : //sep.dyaLinePitch
914 376 : if (nGridLinePitch < 1 || nGridLinePitch > 31680)
915 : {
916 : SAL_WARN("writerfilter", "sep.dyaLinePitch outside legal range: " << nGridLinePitch);
917 0 : nGridLinePitch = 1;
918 : }
919 :
920 752 : operator[]( PropertyDefinition( PROP_GRID_LINES, false )) =
921 1128 : uno::makeAny( static_cast<sal_Int16>(nTextAreaHeight/nGridLinePitch));
922 :
923 376 : sal_Int32 nCharWidth = 423; //240 twip/ 12 pt
924 : //todo: is '0' the right index here?
925 376 : const StyleSheetEntryPtr pEntry = rDM_Impl.GetStyleSheetTable()->FindStyleSheetByISTD(OUString::valueOf(static_cast<sal_Int32>(0), 16));
926 376 : if( pEntry.get( ) )
927 : {
928 6 : PropertyMap::iterator aElement_ = pEntry->pProperties->find(PropertyDefinition( PROP_CHAR_HEIGHT_ASIAN, false ));
929 6 : if( aElement_ != pEntry->pProperties->end())
930 : {
931 6 : double fHeight = 0;
932 6 : if( aElement_->second >>= fHeight )
933 6 : nCharWidth = ConversionHelper::convertTwipToMM100( (long)( fHeight * 20.0 + 0.5 ));
934 : }
935 : }
936 :
937 : //dxtCharSpace
938 376 : if(m_nDxtCharSpace)
939 : {
940 14 : sal_Int32 nCharSpace = m_nDxtCharSpace;
941 : //main lives in top 20 bits, and is signed.
942 14 : sal_Int32 nMain = (nCharSpace & 0xFFFFF000);
943 14 : nMain /= 0x1000;
944 14 : nCharWidth += ConversionHelper::convertTwipToMM100( nMain * 20 );
945 :
946 14 : sal_Int32 nFraction = (nCharSpace & 0x00000FFF);
947 14 : nFraction = (nFraction * 20)/0xFFF;
948 14 : nCharWidth += ConversionHelper::convertTwipToMM100( nFraction );
949 : }
950 376 : operator[]( PropertyDefinition( PROP_GRID_BASE_HEIGHT, false )) = uno::makeAny( nCharWidth );
951 376 : sal_Int32 nRubyHeight = nGridLinePitch - nCharWidth;
952 376 : if(nRubyHeight < 0 )
953 216 : nRubyHeight = 0;
954 376 : operator[]( PropertyDefinition( PROP_GRID_RUBY_HEIGHT, false )) = uno::makeAny( nRubyHeight );
955 :
956 376 : sal_Int16 nGridMode = text::TextGridMode::NONE;
957 :
958 376 : switch (m_nGridType)
959 : {
960 : case NS_ooxml::LN_Value_wordprocessingml_ST_DocGrid_lines:
961 0 : nGridMode = text::TextGridMode::LINES;
962 0 : break;
963 : case NS_ooxml::LN_Value_wordprocessingml_ST_DocGrid_linesAndChars:
964 0 : nGridMode = text::TextGridMode::LINES_AND_CHARS;
965 0 : break;
966 : default:
967 376 : break;
968 : }
969 :
970 376 : operator[](PropertyDefinition(PROP_GRID_MODE, false)) = uno::makeAny(nGridMode);
971 :
972 376 : if (rDM_Impl.IsNewDoc())
973 376 : _ApplyProperties( xFollowPageStyle );
974 :
975 : //todo: creating a "First Page" style depends on HasTitlePage und _fFacingPage_
976 376 : if( m_bTitlePage )
977 : {
978 18 : CopyLastHeaderFooter( true, rDM_Impl );
979 18 : PrepareHeaderFooterProperties( true );
980 : uno::Reference< beans::XPropertySet > xFirstPageStyle = GetPageStyle(
981 18 : rDM_Impl.GetPageStyles(), rDM_Impl.GetTextFactory(), true );
982 18 : if (rDM_Impl.IsNewDoc())
983 18 : _ApplyProperties( xFirstPageStyle );
984 :
985 18 : sal_Int32 nPaperBin = m_nFirstPaperBin >= 0 ? m_nFirstPaperBin : m_nPaperBin >= 0 ? m_nPaperBin : 0;
986 18 : if( nPaperBin )
987 0 : xFollowPageStyle->setPropertyValue( sTrayIndex, uno::makeAny( nPaperBin ) );
988 18 : if( xColumns.is() )
989 0 : xFollowPageStyle->setPropertyValue(
990 0 : rPropNameSupplier.GetName( PROP_TEXT_COLUMNS ), uno::makeAny( xColumns ));
991 : }
992 :
993 376 : ApplyBorderToPageStyles( rDM_Impl.GetPageStyles( ), rDM_Impl.GetTextFactory( ), m_nBorderParams );
994 :
995 : try
996 : {
997 : {
998 : //now apply this break at the first paragraph of this section
999 376 : uno::Reference<beans::XPropertySet> xRangeProperties(lcl_GetRangeProperties(m_bIsFirstSection, rDM_Impl, m_xStartingRange));
1000 : /* break type
1001 : 0 - No break 1 - New Colunn 2 - New page 3 - Even page 4 - odd page */
1002 376 : if ((m_bTitlePage && m_bIsFirstSection) || !m_bTitlePage)
1003 : {
1004 740 : if (xRangeProperties.is())
1005 732 : xRangeProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_PAGE_DESC_NAME ),
1006 736 : uno::makeAny( m_bTitlePage ? m_sFirstPageStyleName : m_sFollowPageStyleName ));
1007 : }
1008 : else
1009 : {
1010 : // In this miserable situation (second or later section on a title page), make sure that the header / footer is not lost.
1011 4 : uno::Reference< container::XNameAccess > xPageStyles(rDM_Impl.GetPageStyles(), uno::UNO_QUERY);
1012 4 : if (xPageStyles->hasByName(m_sFollowPageStyleName))
1013 : {
1014 4 : uno::Reference<beans::XPropertySet> xCurrent(xPageStyles->getByName(rPropNameSupplier.GetName(PROP_STANDARD)), uno::UNO_QUERY);
1015 4 : uno::Reference<beans::XPropertySet> xFollow(xPageStyles->getByName(m_sFollowPageStyleName), uno::UNO_QUERY);
1016 :
1017 4 : if (xFollow->getPropertyValue(rPropNameSupplier.GetName(PROP_HEADER_IS_ON)).get<sal_Bool>())
1018 : {
1019 0 : xCurrent->setPropertyValue(rPropNameSupplier.GetName(PROP_HEADER_IS_ON), uno::makeAny(sal_True));
1020 0 : uno::Reference<text::XTextRange> xCurrentRange(xCurrent->getPropertyValue(rPropNameSupplier.GetName(PROP_HEADER_TEXT)), uno::UNO_QUERY_THROW);
1021 0 : xCurrentRange->setString("");
1022 0 : uno::Reference<text::XTextCopy> xCurrentTxt(xCurrentRange, uno::UNO_QUERY_THROW);
1023 0 : uno::Reference<text::XTextCopy> xFollowTxt(xFollow->getPropertyValue(rPropNameSupplier.GetName(PROP_HEADER_TEXT)), uno::UNO_QUERY_THROW);
1024 0 : xCurrentTxt->copyText(xFollowTxt);
1025 : }
1026 4 : if (xFollow->getPropertyValue(rPropNameSupplier.GetName(PROP_FOOTER_IS_ON)).get<sal_Bool>())
1027 : {
1028 2 : xCurrent->setPropertyValue(rPropNameSupplier.GetName(PROP_FOOTER_IS_ON), uno::makeAny(sal_True));
1029 2 : uno::Reference<text::XTextRange> xCurrentRange(xCurrent->getPropertyValue(rPropNameSupplier.GetName(PROP_FOOTER_TEXT)), uno::UNO_QUERY_THROW);
1030 2 : xCurrentRange->setString("");
1031 2 : uno::Reference<text::XTextCopy> xCurrentTxt(xCurrentRange, uno::UNO_QUERY_THROW);
1032 2 : uno::Reference<text::XTextCopy> xFollowTxt(xFollow->getPropertyValue(rPropNameSupplier.GetName(PROP_FOOTER_TEXT)), uno::UNO_QUERY_THROW);
1033 2 : xCurrentTxt->copyText(xFollowTxt);
1034 4 : }
1035 4 : }
1036 : }
1037 : // handle page breaks with odd/even page numbering
1038 372 : style::PageStyleLayout nPageStyleLayout(style::PageStyleLayout_ALL);
1039 372 : if (m_nBreakType == 3)
1040 2 : nPageStyleLayout = style::PageStyleLayout_LEFT;
1041 370 : else if (m_nBreakType == 4)
1042 2 : nPageStyleLayout = style::PageStyleLayout_RIGHT;
1043 372 : if (nPageStyleLayout)
1044 4 : xFollowPageStyle->setPropertyValue(rPropNameSupplier.GetName(PROP_PAGE_STYLE_LAYOUT), uno::makeAny(nPageStyleLayout));
1045 372 : if(m_bPageNoRestart || m_nPageNumber >= 0)
1046 : {
1047 0 : sal_Int16 nPageNumber = m_nPageNumber >= 0 ? static_cast< sal_Int16 >(m_nPageNumber) : 1;
1048 0 : xRangeProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_PAGE_NUMBER_OFFSET ),
1049 0 : uno::makeAny( nPageNumber ));
1050 376 : }
1051 : }
1052 : }
1053 4 : catch (const uno::Exception&)
1054 : {
1055 : OSL_FAIL( "Exception in SectionPropertyMap::CloseSectionGroup");
1056 376 : }
1057 : }
1058 460 : rDM_Impl.SetIsFirstParagraphInSection(true);
1059 460 : }
1060 :
1061 :
1062 394 : void SectionPropertyMap::_ApplyProperties( uno::Reference< beans::XPropertySet > xStyle )
1063 : {
1064 394 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1065 : uno::Reference<beans::XMultiPropertySet> const xMultiSet(xStyle,
1066 394 : uno::UNO_QUERY);
1067 394 : if (xMultiSet.is())
1068 : { // FIXME why is "this" a STL container???
1069 388 : uno::Sequence<OUString> names(this->size());
1070 388 : uno::Sequence<uno::Any> values(this->size());
1071 388 : PropertyMap::iterator it = this->begin();
1072 8852 : for (size_t i = 0; it != this->end(); ++it, ++i)
1073 : {
1074 8464 : names[i] = rPropNameSupplier.GetName(it->first.eId);
1075 8464 : values[i] = it->second;
1076 : }
1077 : try
1078 : {
1079 388 : xMultiSet->setPropertyValues(names, values);
1080 : }
1081 0 : catch( const uno::Exception& )
1082 : {
1083 : OSL_FAIL( "Exception in <PageStyle>::setPropertyValue");
1084 : }
1085 782 : return;
1086 : }
1087 6 : PropertyMap::iterator aMapIter = begin();
1088 140 : while( aMapIter != end())
1089 : {
1090 : try
1091 : {
1092 128 : if (xStyle.is())
1093 0 : xStyle->setPropertyValue( rPropNameSupplier.GetName( aMapIter->first.eId ), aMapIter->second );
1094 : }
1095 0 : catch( const uno::Exception& )
1096 : {
1097 : OSL_FAIL( "Exception in <PageStyle>::setPropertyValue");
1098 : }
1099 128 : ++aMapIter;
1100 394 : }
1101 : }
1102 0 : sal_Int32 lcl_AlignPaperBin( sal_Int32 nSet )
1103 : {
1104 : //default tray numbers are above 0xff
1105 0 : if( nSet > 0xff )
1106 0 : nSet = nSet >> 8;
1107 : //there are some special numbers which can't be handled easily
1108 : //1, 4, 15, manual tray, upper tray, auto select? see ww8atr.cxx
1109 : //todo: find out appropriate conversion
1110 0 : return nSet;
1111 : }
1112 :
1113 :
1114 0 : void SectionPropertyMap::SetPaperBin( sal_Int32 nSet )
1115 : {
1116 0 : m_nPaperBin = lcl_AlignPaperBin( nSet );
1117 0 : }
1118 :
1119 :
1120 0 : void SectionPropertyMap::SetFirstPaperBin( sal_Int32 nSet )
1121 : {
1122 0 : m_nFirstPaperBin = lcl_AlignPaperBin( nSet );
1123 0 : }
1124 :
1125 :
1126 2220 : StyleSheetPropertyMap::StyleSheetPropertyMap() :
1127 : mnCT_Spacing_line( 0 ),
1128 : mnCT_Spacing_lineRule( 0 ),
1129 : mbCT_TrPrBase_tblHeader( false ),
1130 : mnCT_TrPrBase_jc( 0 ),
1131 : mnCT_TcPrBase_vAlign( 0 ),
1132 : mnCT_TblWidth_w( 0 ),
1133 : mnCT_TblWidth_type( 0 ),
1134 : mbCT_Spacing_lineSet( false ),
1135 : mbCT_Spacing_lineRuleSet( false ),
1136 : mbCT_TrPrBase_tblHeaderSet( false ),
1137 : mbCT_TrPrBase_jcSet( false ),
1138 : mbCT_TcPrBase_vAlignSet( false ),
1139 : mbCT_TblWidth_wSet( false ),
1140 : mbCT_TblWidth_typeSet( false ),
1141 : mnListId( -1 ),
1142 : mnListLevel( -1 ),
1143 2220 : mnOutlineLevel( -1 )
1144 : {
1145 2220 : }
1146 :
1147 :
1148 4440 : StyleSheetPropertyMap::~StyleSheetPropertyMap()
1149 : {
1150 4440 : }
1151 :
1152 :
1153 4642 : ParagraphProperties::ParagraphProperties() :
1154 : m_bFrameMode( false ),
1155 : m_nDropCap(NS_ooxml::LN_Value_wordprocessingml_ST_DropCap_none),
1156 : m_nLines(0),
1157 : m_w(-1),
1158 : m_h(-1),
1159 : m_nWrap(-1),
1160 : m_hAnchor(-1),
1161 : m_vAnchor(text::RelOrientation::FRAME),
1162 : m_x(-1),
1163 : m_bxValid( false ),
1164 : m_y(-1),
1165 : m_byValid( false ),
1166 : m_hSpace(-1),
1167 : m_vSpace(-1),
1168 : m_hRule(-1),
1169 : m_xAlign(-1),
1170 : m_yAlign(-1),
1171 : m_bAnchorLock(false),
1172 4642 : m_nDropCapLength(0)
1173 : {
1174 4642 : }
1175 :
1176 :
1177 26 : ParagraphProperties::ParagraphProperties(const ParagraphProperties& rCopy) :
1178 : m_bFrameMode ( rCopy.m_bFrameMode),
1179 : m_nDropCap ( rCopy.m_nDropCap),
1180 : m_nLines ( rCopy.m_nLines),
1181 : m_w ( rCopy.m_w),
1182 : m_h ( rCopy.m_h),
1183 : m_nWrap ( rCopy.m_nWrap),
1184 : m_hAnchor ( rCopy.m_hAnchor),
1185 : m_vAnchor ( rCopy.m_vAnchor),
1186 : m_x ( rCopy.m_x),
1187 : m_bxValid ( rCopy.m_bxValid),
1188 : m_y ( rCopy.m_y),
1189 : m_byValid ( rCopy.m_byValid),
1190 : m_hSpace ( rCopy.m_hSpace),
1191 : m_vSpace ( rCopy.m_vSpace),
1192 : m_hRule ( rCopy.m_hRule),
1193 : m_xAlign ( rCopy.m_xAlign),
1194 : m_yAlign ( rCopy.m_yAlign),
1195 : m_bAnchorLock( rCopy.m_bAnchorLock),
1196 : m_nDropCapLength( rCopy.m_nDropCapLength ),
1197 : m_sParaStyleName( rCopy.m_sParaStyleName),
1198 : m_xStartingRange( rCopy.m_xStartingRange ),
1199 26 : m_xEndingRange( rCopy.m_xEndingRange)
1200 : {
1201 26 : }
1202 :
1203 :
1204 4668 : ParagraphProperties::~ParagraphProperties()
1205 : {
1206 4668 : }
1207 :
1208 :
1209 28 : int ParagraphProperties::operator==(const ParagraphProperties& rCompare)
1210 : {
1211 : return
1212 : m_bFrameMode == rCompare.m_bFrameMode &&
1213 : m_nDropCap == rCompare.m_nDropCap &&
1214 : m_nLines == rCompare.m_nLines &&
1215 : m_w == rCompare.m_w &&
1216 : m_h == rCompare.m_h &&
1217 : m_nWrap == rCompare.m_nWrap &&
1218 : m_hAnchor == rCompare.m_hAnchor &&
1219 : m_vAnchor == rCompare.m_vAnchor &&
1220 : m_x == rCompare.m_x &&
1221 : m_bxValid == rCompare.m_bxValid &&
1222 : m_y == rCompare.m_y &&
1223 : m_byValid == rCompare.m_byValid &&
1224 : m_hSpace == rCompare.m_hSpace &&
1225 : m_vSpace == rCompare.m_vSpace &&
1226 : m_hRule == rCompare.m_hRule &&
1227 : m_xAlign == rCompare.m_xAlign &&
1228 : m_yAlign == rCompare.m_yAlign &&
1229 28 : m_bAnchorLock== rCompare.m_bAnchorLock;
1230 : }
1231 :
1232 1478 : void ParagraphProperties::ResetFrameProperties()
1233 : {
1234 1478 : m_bFrameMode = false;
1235 1478 : m_nDropCap = NS_ooxml::LN_Value_wordprocessingml_ST_DropCap_none;
1236 1478 : m_nLines = 0;
1237 1478 : m_w = -1;
1238 1478 : m_h = -1;
1239 1478 : m_nWrap = -1;
1240 1478 : m_hAnchor = -1;
1241 1478 : m_vAnchor = text::RelOrientation::FRAME;
1242 1478 : m_x = -1;
1243 1478 : m_bxValid = false;
1244 1478 : m_y = -1;
1245 1478 : m_byValid = false;
1246 1478 : m_hSpace = -1;
1247 1478 : m_vSpace = -1;
1248 1478 : m_hRule = -1;
1249 1478 : m_xAlign = -1;
1250 1478 : m_yAlign = -1;
1251 1478 : m_bAnchorLock = false;
1252 1478 : m_nDropCapLength = 0;
1253 1478 : }
1254 :
1255 :
1256 2422 : ParagraphPropertyMap::ParagraphPropertyMap()
1257 : {
1258 2422 : }
1259 :
1260 :
1261 4844 : ParagraphPropertyMap::~ParagraphPropertyMap()
1262 : {
1263 4844 : }
1264 :
1265 :
1266 1768 : TablePropertyMap::TablePropertyMap()
1267 : {
1268 1768 : }
1269 :
1270 :
1271 3536 : TablePropertyMap::~TablePropertyMap()
1272 : {
1273 3536 : }
1274 :
1275 :
1276 816 : bool TablePropertyMap::getValue( TablePropertyMapTarget eWhich, sal_Int32& nFill )
1277 : {
1278 816 : if( eWhich < TablePropertyMapTarget_MAX )
1279 : {
1280 816 : if(m_aValidValues[eWhich].bValid)
1281 312 : nFill = m_aValidValues[eWhich].nValue;
1282 816 : return m_aValidValues[eWhich].bValid;
1283 : }
1284 : else
1285 : {
1286 : OSL_FAIL( "invalid TablePropertyMapTarget");
1287 0 : return false;
1288 : }
1289 : }
1290 :
1291 :
1292 928 : void TablePropertyMap::setValue( TablePropertyMapTarget eWhich, sal_Int32 nSet )
1293 : {
1294 928 : if( eWhich < TablePropertyMapTarget_MAX )
1295 : {
1296 928 : m_aValidValues[eWhich].bValid = true;
1297 928 : m_aValidValues[eWhich].nValue = nSet;
1298 : }
1299 : else
1300 : OSL_FAIL( "invalid TablePropertyMapTarget");
1301 928 : }
1302 :
1303 :
1304 594 : void TablePropertyMap::insertTableProperties( const PropertyMap* pMap )
1305 : {
1306 : #ifdef DEBUG_DOMAINMAPPER
1307 : dmapper_logger->startElement("TablePropertyMap.insertTableProperties");
1308 : pMap->dumpXml(dmapper_logger);
1309 : #endif
1310 :
1311 594 : const TablePropertyMap* pSource = dynamic_cast< const TablePropertyMap* >(pMap);
1312 594 : if( pSource )
1313 : {
1314 4824 : for( sal_Int32 eTarget = TablePropertyMapTarget_START;
1315 : eTarget < TablePropertyMapTarget_MAX; ++eTarget )
1316 : {
1317 4288 : if( pSource->m_aValidValues[eTarget].bValid )
1318 : {
1319 304 : m_aValidValues[eTarget].bValid = true;
1320 304 : m_aValidValues[eTarget].nValue = pSource->m_aValidValues[eTarget].nValue;
1321 : }
1322 : }
1323 : }
1324 : #ifdef DEBUG_DOMAINMAPPER
1325 : dumpXml( dmapper_logger );
1326 : dmapper_logger->endElement();
1327 : #endif
1328 594 : }
1329 :
1330 :
1331 : }//namespace dmapper
1332 30 : }//namespace writerfilter
1333 :
1334 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|