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