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 :
20 : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
21 : #include <com/sun/star/beans/XPropertySet.hpp>
22 : #include <com/sun/star/beans/XPropertyContainer.hpp>
23 : #include <com/sun/star/document/XDocumentProperties.hpp>
24 : #include <DomainMapper_Impl.hxx>
25 : #include <ConversionHelper.hxx>
26 : #include <SdtHelper.hxx>
27 : #include <DomainMapperTableHandler.hxx>
28 : #include <com/sun/star/uno/XComponentContext.hpp>
29 : #include <com/sun/star/graphic/XGraphic.hpp>
30 : #include <com/sun/star/beans/XPropertyState.hpp>
31 : #include <com/sun/star/container/XNamed.hpp>
32 : #include <com/sun/star/document/PrinterIndependentLayout.hpp>
33 : #include <com/sun/star/document/IndexedPropertyValues.hpp>
34 : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
35 : #include <com/sun/star/lang/XServiceInfo.hpp>
36 : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
37 : #include <com/sun/star/style/LineNumberPosition.hpp>
38 : #include <com/sun/star/style/LineSpacing.hpp>
39 : #include <com/sun/star/style/LineSpacingMode.hpp>
40 : #include <com/sun/star/text/ChapterFormat.hpp>
41 : #include <com/sun/star/text/FilenameDisplayFormat.hpp>
42 : #include <com/sun/star/text/SetVariableType.hpp>
43 : #include <com/sun/star/text/XFootnote.hpp>
44 : #include <com/sun/star/text/XLineNumberingProperties.hpp>
45 : #include <com/sun/star/style/XStyle.hpp>
46 : #include <com/sun/star/text/PageNumberType.hpp>
47 : #include <com/sun/star/text/HoriOrientation.hpp>
48 : #include <com/sun/star/text/VertOrientation.hpp>
49 : #include <com/sun/star/text/ReferenceFieldPart.hpp>
50 : #include <com/sun/star/text/RelOrientation.hpp>
51 : #include <com/sun/star/text/ReferenceFieldSource.hpp>
52 : #include <com/sun/star/text/SizeType.hpp>
53 : #include <com/sun/star/text/TextContentAnchorType.hpp>
54 : #include <com/sun/star/text/WrapTextMode.hpp>
55 : #include <com/sun/star/text/XDependentTextField.hpp>
56 : #include <com/sun/star/text/XParagraphCursor.hpp>
57 : #include <com/sun/star/text/XRedline.hpp>
58 : #include <com/sun/star/text/XTextFieldsSupplier.hpp>
59 : #include <com/sun/star/style/DropCapFormat.hpp>
60 : #include <com/sun/star/util/NumberFormatter.hpp>
61 : #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
62 : #include <com/sun/star/util/XNumberFormatter.hpp>
63 : #include <com/sun/star/document/XViewDataSupplier.hpp>
64 : #include <com/sun/star/container/XIndexContainer.hpp>
65 : #include <com/sun/star/awt/XControlModel.hpp>
66 : #include <com/sun/star/drawing/XControlShape.hpp>
67 : #include <com/sun/star/text/ControlCharacter.hpp>
68 : #include <com/sun/star/text/XTextColumns.hpp>
69 : #include <oox/mathml/import.hxx>
70 : #include <GraphicHelpers.hxx>
71 : #include <dmapper/GraphicZOrderHelper.hxx>
72 :
73 : #include <oox/token/tokens.hxx>
74 :
75 : #include <map>
76 : #include <boost/tuple/tuple.hpp>
77 :
78 : #include <vcl/svapp.hxx>
79 : #include <vcl/outdev.hxx>
80 : #include <officecfg/Office/Common.hxx>
81 : #include <filter/msfilter/util.hxx>
82 : #include <comphelper/sequence.hxx>
83 : #include <comphelper/propertyvalue.hxx>
84 :
85 : using namespace ::com::sun::star;
86 : using namespace oox;
87 : namespace writerfilter {
88 : namespace dmapper{
89 :
90 : //line numbering for header/footer
91 54 : void lcl_linenumberingHeaderFooter( PropertyNameSupplier& rPropNameSupplier, uno::Reference<container::XNameContainer> xStyles, const OUString& rname, DomainMapper_Impl* dmapper )
92 : {
93 54 : const StyleSheetEntryPtr pEntry = dmapper->GetStyleSheetTable()->FindStyleSheetByISTD( rname );
94 54 : if (!pEntry)
95 8 : return;
96 46 : const StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast<const StyleSheetPropertyMap*>( pEntry->pProperties.get() );
97 46 : if ( !pStyleSheetProperties )
98 0 : return;
99 46 : sal_Int32 nListId = pStyleSheetProperties->GetListId();
100 46 : if( xStyles.is() )
101 : {
102 46 : if( xStyles->hasByName( rname ) )
103 : {
104 46 : uno::Reference< style::XStyle > xStyle;
105 46 : xStyles->getByName( rname ) >>= xStyle;
106 46 : if( !xStyle.is() )
107 0 : return;
108 92 : uno::Reference<beans::XPropertySet> xPropertySet( xStyle, uno::UNO_QUERY );
109 92 : xPropertySet->setPropertyValue( rPropNameSupplier.GetName( PROP_PARA_LINE_NUMBER_COUNT ), uno::makeAny( ( bool )( nListId >= 0 ) ) );
110 : }
111 46 : }
112 : }
113 :
114 : // Populate Dropdown Field properties from FFData structure
115 0 : void lcl_handleDropdownField( const uno::Reference< beans::XPropertySet >& rxFieldProps, FFDataHandler::Pointer_t pFFDataHandler )
116 : {
117 0 : if ( rxFieldProps.is() )
118 : {
119 0 : if ( !pFFDataHandler->getName().isEmpty() )
120 0 : rxFieldProps->setPropertyValue( "Name", uno::makeAny( pFFDataHandler->getName() ) );
121 :
122 0 : const FFDataHandler::DropDownEntries_t& rEntries = pFFDataHandler->getDropDownEntries();
123 0 : uno::Sequence< OUString > sItems( rEntries.size() );
124 0 : ::std::copy( rEntries.begin(), rEntries.end(), sItems.begin());
125 0 : if ( sItems.getLength() )
126 0 : rxFieldProps->setPropertyValue( "Items", uno::makeAny( sItems ) );
127 :
128 0 : sal_Int32 nResult = pFFDataHandler->getDropDownResult().toInt32();
129 0 : if ( nResult )
130 0 : rxFieldProps->setPropertyValue( "SelectedItem", uno::makeAny( sItems[ nResult ] ) );
131 0 : if ( !pFFDataHandler->getHelpText().isEmpty() )
132 0 : rxFieldProps->setPropertyValue( "Help", uno::makeAny( pFFDataHandler->getHelpText() ) );
133 : }
134 0 : }
135 :
136 0 : void lcl_handleTextField( const uno::Reference< beans::XPropertySet >& rxFieldProps, FFDataHandler::Pointer_t pFFDataHandler, PropertyNameSupplier& rPropNameSupplier )
137 : {
138 0 : if ( rxFieldProps.is() && pFFDataHandler )
139 : {
140 0 : rxFieldProps->setPropertyValue
141 : (rPropNameSupplier.GetName(PROP_HINT),
142 0 : uno::makeAny(pFFDataHandler->getStatusText()));
143 0 : rxFieldProps->setPropertyValue
144 : (rPropNameSupplier.GetName(PROP_HELP),
145 0 : uno::makeAny(pFFDataHandler->getHelpText()));
146 0 : rxFieldProps->setPropertyValue
147 : (rPropNameSupplier.GetName(PROP_CONTENT),
148 0 : uno::makeAny(pFFDataHandler->getTextDefault()));
149 : }
150 0 : }
151 :
152 189501 : struct FieldConversion
153 : {
154 : OUString sWordCommand;
155 : const sal_Char* cFieldServiceName;
156 : const sal_Char* cFieldMasterServiceName;
157 : FieldId eFieldId;
158 : };
159 :
160 : typedef ::std::map< OUString, FieldConversion>
161 : FieldConversionMap_t;
162 :
163 111 : uno::Any FloatingTableInfo::getPropertyValue(const OUString &propertyName)
164 : {
165 :
166 111 : beans::PropertyValue* pFrameProperties = m_aFrameProperties.getArray();
167 1184 : for( int i = 0 ; i < m_aFrameProperties.getLength(); i++ )
168 1184 : if( pFrameProperties[i].Name == propertyName )
169 111 : return pFrameProperties[i].Value ;
170 0 : return uno::Any() ;
171 : }
172 :
173 1985 : DomainMapper_Impl::DomainMapper_Impl(
174 : DomainMapper& rDMapper,
175 : uno::Reference<uno::XComponentContext> const& xContext,
176 : uno::Reference<lang::XComponent> const& xModel,
177 : SourceDocumentType eDocumentType,
178 : uno::Reference<text::XTextRange> const& xInsertTextRange,
179 : bool bIsNewDoc) :
180 : m_eDocumentType( eDocumentType ),
181 : m_rDMapper( rDMapper ),
182 : m_xTextDocument( xModel, uno::UNO_QUERY ),
183 : m_xTextFactory( xModel, uno::UNO_QUERY ),
184 : m_xComponentContext( xContext ),
185 : m_bSetUserFieldContent( false ),
186 : m_bSetCitation( false ),
187 : m_bSetDateValue( false ),
188 : m_bIsFirstSection( true ),
189 : m_bIsColumnBreakDeferred( false ),
190 : m_bIsPageBreakDeferred( false ),
191 : m_bSdtEndDeferred(false),
192 : m_bParaSdtEndDeferred(false),
193 : m_bStartTOC(false),
194 : m_bStartTOCHeaderFooter(false),
195 : m_bStartedTOC(false),
196 : m_bStartIndex(false),
197 : m_bStartBibliography(false),
198 : m_bTOCPageRef(false),
199 : m_bStartGenericField(false),
200 : m_bTextInserted(false),
201 : m_nSymboldata(-1),
202 : m_pLastSectionContext( ),
203 : m_pLastCharacterContext(),
204 : m_nCurrentTabStopIndex( 0 ),
205 : m_sCurrentParaStyleId(),
206 : m_bInStyleSheetImport( false ),
207 : m_bInAnyTableImport( false ),
208 : m_bInHeaderFooterImport( false ),
209 : m_bDiscardHeaderFooter( false ),
210 : m_bInFootOrEndnote(false),
211 : m_bLineNumberingSet( false ),
212 : m_bIsInFootnoteProperties( false ),
213 : m_bIsCustomFtnMark( false ),
214 : m_bIsParaMarkerChange( false ),
215 : m_bParaChanged( false ),
216 : m_bIsFirstParaInSection( true ),
217 : m_bDummyParaAddedForTableInSection( false ),
218 : m_bTextFrameInserted(false),
219 : m_bIsLastParaInSection( false ),
220 : m_bIsLastSectionGroup( false ),
221 : m_bIsInComments( false ),
222 : m_bParaSectpr( false ),
223 : m_bUsingEnhancedFields( false ),
224 : m_bSdt(false),
225 : m_bIsFirstRun(false),
226 : m_bIsOutsideAParagraph(true),
227 : m_xAnnotationField(),
228 : m_nAnnotationId( -1 ),
229 : m_aAnnotationPositions(),
230 : m_xInsertTextRange(xInsertTextRange),
231 : m_bIsNewDoc(bIsNewDoc),
232 : m_bInTableStyleRunProps(false),
233 : m_nTableDepth(0),
234 : m_bHasFtnSep(false),
235 : m_bIgnoreNextPara(false),
236 : m_bIgnoreNextTab(false),
237 : m_bFrameBtLr(false),
238 : m_bIsSplitPara(false),
239 : m_vTextFramesForChaining(),
240 1986 : m_bParaHadField(false)
241 :
242 : {
243 1985 : appendTableManager( );
244 1985 : GetBodyText();
245 1985 : uno::Reference< text::XTextAppend > xBodyTextAppend = uno::Reference< text::XTextAppend >( m_xBodyText, uno::UNO_QUERY );
246 : m_aTextAppendStack.push(TextAppendContext(xBodyTextAppend,
247 1985 : m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(m_xInsertTextRange)));
248 :
249 : //todo: does it make sense to set the body text as static text interface?
250 3968 : uno::Reference< text::XTextAppendAndConvert > xBodyTextAppendAndConvert( m_xBodyText, uno::UNO_QUERY );
251 : m_pTableHandler.reset
252 1984 : (new DomainMapperTableHandler(xBodyTextAppendAndConvert, *this));
253 1984 : getTableManager( ).setHandler(m_pTableHandler);
254 :
255 1984 : getTableManager( ).startLevel();
256 1984 : m_bUsingEnhancedFields = officecfg::Office::Common::Filter::Microsoft::Import::ImportWWFieldsAsEnhancedFields::get(m_xComponentContext);
257 :
258 1984 : m_pSdtHelper.reset(new SdtHelper(*this));
259 :
260 3969 : m_aRedlines.push(std::vector<RedlineParamsPtr>());
261 1984 : }
262 :
263 :
264 5952 : DomainMapper_Impl::~DomainMapper_Impl()
265 : {
266 1984 : ChainTextFrames();
267 : // Don't remove last paragraph when pasting, sw expects that empty paragraph.
268 1984 : if (m_bIsNewDoc)
269 1975 : RemoveLastParagraph();
270 1984 : getTableManager( ).endLevel();
271 1984 : popTableManager( );
272 3968 : }
273 :
274 :
275 6956 : uno::Reference< container::XNameContainer > DomainMapper_Impl::GetPageStyles()
276 : {
277 6956 : if(!m_xPageStyles.is())
278 : {
279 1993 : uno::Reference< style::XStyleFamiliesSupplier > xSupplier( m_xTextDocument, uno::UNO_QUERY );
280 1993 : if (xSupplier.is())
281 1953 : xSupplier->getStyleFamilies()->getByName("PageStyles") >>= m_xPageStyles;
282 : }
283 6956 : return m_xPageStyles;
284 : }
285 :
286 :
287 8167 : uno::Reference< text::XText > DomainMapper_Impl::GetBodyText()
288 : {
289 8167 : if(!m_xBodyText.is())
290 : {
291 2025 : if (m_xInsertTextRange.is())
292 9 : m_xBodyText = m_xInsertTextRange->getText();
293 2016 : else if (m_xTextDocument.is())
294 1950 : m_xBodyText = m_xTextDocument->getText();
295 : }
296 8167 : return m_xBodyText;
297 : }
298 :
299 :
300 7936 : uno::Reference< beans::XPropertySet > DomainMapper_Impl::GetDocumentSettings()
301 : {
302 7936 : if( !m_xDocumentSettings.is() && m_xTextFactory.is())
303 : {
304 3916 : m_xDocumentSettings = uno::Reference< beans::XPropertySet >(
305 3916 : m_xTextFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY );
306 : }
307 7936 : return m_xDocumentSettings;
308 : }
309 :
310 :
311 7936 : void DomainMapper_Impl::SetDocumentSettingsProperty( const OUString& rPropName, const uno::Any& rValue )
312 : {
313 7936 : uno::Reference< beans::XPropertySet > xSettings = GetDocumentSettings();
314 7936 : if( xSettings.is() )
315 : {
316 : try
317 : {
318 7832 : xSettings->setPropertyValue( rPropName, rValue );
319 : }
320 0 : catch( const uno::Exception& )
321 : {
322 : }
323 7936 : }
324 7936 : }
325 179 : void DomainMapper_Impl::RemoveDummyParaForTableInSection()
326 : {
327 179 : SetIsDummyParaAddedForTableInSection(false);
328 179 : PropertyMapPtr pContext = GetTopContextOfType(CONTEXT_SECTION);
329 179 : SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() );
330 179 : if (!pSectionContext)
331 179 : return;
332 358 : uno::Reference< text::XTextCursor > xCursor = GetTopTextAppend()->createTextCursorByRange(pSectionContext->GetStartingRange());
333 :
334 : // Remove the extra NumPicBullets from the document,
335 : // which get attached to the first paragraph in the
336 : // document
337 358 : ListsManager::Pointer pListTable = GetListTable();
338 179 : pListTable->DisposeNumPicBullets();
339 :
340 358 : uno::Reference<container::XEnumerationAccess> xEnumerationAccess(xCursor, uno::UNO_QUERY);
341 179 : if (xEnumerationAccess.is() && m_aTextAppendStack.size() == 1 )
342 : {
343 179 : uno::Reference<container::XEnumeration> xEnumeration = xEnumerationAccess->createEnumeration();
344 358 : uno::Reference<lang::XComponent> xParagraph(xEnumeration->nextElement(), uno::UNO_QUERY);
345 358 : xParagraph->dispose();
346 179 : }
347 : }
348 192 : void DomainMapper_Impl::AddDummyParaForTableInSection()
349 : {
350 : // Shapes can't have sections.
351 192 : if (IsInShape())
352 205 : return;
353 :
354 179 : if (!m_aTextAppendStack.empty())
355 : {
356 179 : uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
357 358 : uno::Reference< text::XTextCursor > xCrsr = xTextAppend->getText()->createTextCursor();
358 358 : uno::Reference< text::XText > xText = xTextAppend->getText();
359 179 : if(xCrsr.is() && xText.is())
360 : {
361 179 : xTextAppend->finishParagraph( uno::Sequence< beans::PropertyValue >() );
362 179 : SetIsDummyParaAddedForTableInSection(true);
363 179 : }
364 : }
365 : }
366 :
367 4793 : void DomainMapper_Impl::RemoveLastParagraph( )
368 : {
369 4793 : if (m_aTextAppendStack.empty())
370 165 : return;
371 4793 : uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
372 4793 : if (!xTextAppend.is())
373 165 : return;
374 : try
375 : {
376 4628 : uno::Reference< text::XTextCursor > xCursor;
377 4628 : if (m_bIsNewDoc)
378 : {
379 4627 : xCursor = xTextAppend->createTextCursor();
380 4626 : xCursor->gotoEnd(false);
381 : }
382 : else
383 1 : xCursor.set(m_aTextAppendStack.top().xCursor, uno::UNO_QUERY);
384 9254 : uno::Reference<container::XEnumerationAccess> xEnumerationAccess(xCursor, uno::UNO_QUERY);
385 : // Keep the character properties of the last but one paragraph, even if
386 : // it's empty. This works for headers/footers, and maybe in other cases
387 : // as well, but surely not in textboxes.
388 : // fdo#58327: also do this at the end of the document: when pasting,
389 : // a table before the cursor position would be deleted
390 : // (but only for paste/insert, not load; otherwise it can happen that
391 : // flys anchored at the disposed paragraph are deleted (fdo47036.rtf))
392 4627 : bool const bEndOfDocument(m_aTextAppendStack.size() == 1);
393 7747 : if ((m_bInHeaderFooterImport || (bEndOfDocument && !m_bIsNewDoc))
394 6134 : && xEnumerationAccess.is())
395 : {
396 1433 : uno::Reference<container::XEnumeration> xEnumeration = xEnumerationAccess->createEnumeration();
397 2866 : uno::Reference<lang::XComponent> xParagraph(xEnumeration->nextElement(), uno::UNO_QUERY);
398 2866 : xParagraph->dispose();
399 : }
400 3194 : else if (xCursor.is())
401 : {
402 3193 : xCursor->goLeft( 1, true );
403 : // If this is a text on a shape, possibly the text has the trailing
404 : // newline removed already.
405 3193 : if (xCursor->getString() == SAL_NEWLINE_STRING)
406 : {
407 2538 : uno::Reference<beans::XPropertySet> xDocProps(GetTextDocument(), uno::UNO_QUERY);
408 5076 : const OUString aRecordChanges("RecordChanges");
409 5076 : uno::Any aPreviousValue(xDocProps->getPropertyValue(aRecordChanges));
410 :
411 : // disable redlining for this operation, otherwise we might
412 : // end up with an unwanted recorded deletion
413 2538 : xDocProps->setPropertyValue(aRecordChanges, uno::Any(sal_False));
414 :
415 : // delete
416 2538 : xCursor->setString(OUString());
417 :
418 : // restore again
419 5076 : xDocProps->setPropertyValue(aRecordChanges, aPreviousValue);
420 : }
421 4628 : }
422 : }
423 1 : catch( const uno::Exception& )
424 : {
425 4628 : }
426 : }
427 :
428 10 : void DomainMapper_Impl::SetSymbolData( sal_Int32 nSymbolData )
429 : {
430 10 : m_nSymboldata = nSymbolData;
431 10 : }
432 :
433 :
434 4225 : void DomainMapper_Impl::SetIsLastSectionGroup( bool bIsLast )
435 : {
436 4225 : m_bIsLastSectionGroup = bIsLast;
437 4225 : }
438 :
439 1701 : void DomainMapper_Impl::SetIsLastParagraphInSection( bool bIsLast )
440 : {
441 1701 : m_bIsLastParaInSection = bIsLast;
442 1701 : }
443 :
444 :
445 4537 : void DomainMapper_Impl::SetIsFirstParagraphInSection( bool bIsFirst )
446 : {
447 4537 : m_bIsFirstParaInSection = bIsFirst;
448 4537 : }
449 :
450 :
451 :
452 358 : void DomainMapper_Impl::SetIsDummyParaAddedForTableInSection( bool bIsAdded )
453 : {
454 358 : m_bDummyParaAddedForTableInSection = bIsAdded;
455 358 : }
456 :
457 :
458 123 : void DomainMapper_Impl::SetIsTextFrameInserted( bool bIsInserted )
459 : {
460 123 : m_bTextFrameInserted = bIsInserted;
461 123 : }
462 :
463 :
464 29547 : void DomainMapper_Impl::SetParaSectpr(bool bParaSectpr)
465 : {
466 29547 : m_bParaSectpr = bParaSectpr;
467 29547 : }
468 :
469 :
470 892 : void DomainMapper_Impl::SetSdt(bool bSdt)
471 : {
472 892 : m_bSdt = bSdt;
473 892 : }
474 :
475 :
476 :
477 110285 : void DomainMapper_Impl::PushProperties(ContextType eId)
478 : {
479 110285 : PropertyMapPtr pInsert(eId == CONTEXT_SECTION ?
480 2261 : (new SectionPropertyMap( m_bIsFirstSection )) :
481 112546 : eId == CONTEXT_PARAGRAPH ? new ParagraphPropertyMap : new PropertyMap);
482 110285 : if(eId == CONTEXT_SECTION)
483 : {
484 2261 : if( m_bIsFirstSection )
485 1976 : m_bIsFirstSection = false;
486 : // beginning with the second section group a section has to be inserted
487 : // into the document
488 2261 : SectionPropertyMap* pSectionContext_ = dynamic_cast< SectionPropertyMap* >( pInsert.get() );
489 2261 : if (!m_aTextAppendStack.empty())
490 : {
491 2261 : uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
492 2261 : if (xTextAppend.is() && pSectionContext_)
493 2239 : pSectionContext_->SetStart( xTextAppend->getEnd() );
494 : }
495 : }
496 110285 : if(eId == CONTEXT_PARAGRAPH && m_bIsSplitPara)
497 : {
498 6 : m_aPropertyStacks[eId].push( GetTopContextOfType(eId));
499 6 : m_bIsSplitPara = false;
500 : }
501 : else
502 : {
503 110279 : m_aPropertyStacks[eId].push( pInsert );
504 : }
505 110285 : m_aContextStack.push(eId);
506 :
507 110285 : m_pTopContext = m_aPropertyStacks[eId].top();
508 110285 : }
509 :
510 :
511 100696 : void DomainMapper_Impl::PushStyleProperties( PropertyMapPtr pStyleProperties )
512 : {
513 100696 : m_aPropertyStacks[CONTEXT_STYLESHEET].push( pStyleProperties );
514 100696 : m_aContextStack.push(CONTEXT_STYLESHEET);
515 :
516 100696 : m_pTopContext = m_aPropertyStacks[CONTEXT_STYLESHEET].top();
517 100696 : }
518 :
519 :
520 26497 : void DomainMapper_Impl::PushListProperties(PropertyMapPtr pListProperties)
521 : {
522 26497 : m_aPropertyStacks[CONTEXT_LIST].push( pListProperties );
523 26497 : m_aContextStack.push(CONTEXT_LIST);
524 26497 : m_pTopContext = m_aPropertyStacks[CONTEXT_LIST].top();
525 26497 : }
526 :
527 :
528 237456 : void DomainMapper_Impl::PopProperties(ContextType eId)
529 : {
530 : OSL_ENSURE(!m_aPropertyStacks[eId].empty(), "section stack already empty");
531 237456 : if ( m_aPropertyStacks[eId].empty() )
532 237457 : return;
533 :
534 237455 : if ( eId == CONTEXT_SECTION )
535 : {
536 2256 : m_pLastSectionContext = m_aPropertyStacks[eId].top( );
537 : }
538 235199 : else if (eId == CONTEXT_CHARACTER)
539 : {
540 75316 : m_pLastCharacterContext = m_aPropertyStacks[eId].top();
541 : // Sadly an assert about deferredCharacterProperties being empty is not possible
542 : // here, because appendTextPortion() may not be called for every character section.
543 75316 : deferredCharacterProperties.clear();
544 : }
545 :
546 237455 : m_aPropertyStacks[eId].pop();
547 237455 : m_aContextStack.pop();
548 237455 : if(!m_aContextStack.empty() && !m_aPropertyStacks[m_aContextStack.top()].empty())
549 :
550 159436 : m_pTopContext = m_aPropertyStacks[m_aContextStack.top()].top();
551 : else
552 : {
553 : // OSL_ENSURE(eId == CONTEXT_SECTION, "this should happen at a section context end");
554 78019 : m_pTopContext.reset();
555 : }
556 : }
557 :
558 :
559 846297 : PropertyMapPtr DomainMapper_Impl::GetTopContextOfType(ContextType eId)
560 : {
561 846297 : PropertyMapPtr pRet;
562 : SAL_WARN_IF( m_aPropertyStacks[eId].empty(), "writerfilter",
563 : "no context of type " << static_cast<int>(eId) << " available");
564 846297 : if(!m_aPropertyStacks[eId].empty())
565 787930 : pRet = m_aPropertyStacks[eId].top();
566 846297 : return pRet;
567 : }
568 :
569 :
570 :
571 1356 : uno::Reference< text::XTextAppend > DomainMapper_Impl::GetTopTextAppend()
572 : {
573 : OSL_ENSURE(!m_aTextAppendStack.empty(), "text append stack is empty" );
574 1356 : return m_aTextAppendStack.top().xTextAppend;
575 : }
576 :
577 47 : FieldContextPtr DomainMapper_Impl::GetTopFieldContext()
578 : {
579 : SAL_WARN_IF(m_aFieldStack.empty(), "writerfilter", "Field stack is empty");
580 47 : return m_aFieldStack.top();
581 : }
582 :
583 244 : void DomainMapper_Impl::InitTabStopFromStyle( const uno::Sequence< style::TabStop >& rInitTabStops )
584 : {
585 : OSL_ENSURE(!m_aCurrentTabStops.size(), "tab stops already initialized");
586 575 : for( sal_Int32 nTab = 0; nTab < rInitTabStops.getLength(); ++nTab)
587 : {
588 331 : m_aCurrentTabStops.push_back( DeletableTabStop(rInitTabStops[nTab]) );
589 : }
590 244 : }
591 :
592 7900 : void DomainMapper_Impl::IncorporateTabStop( const DeletableTabStop & rTabStop )
593 : {
594 7900 : ::std::vector<DeletableTabStop>::iterator aIt = m_aCurrentTabStops.begin();
595 7900 : ::std::vector<DeletableTabStop>::iterator aEndIt = m_aCurrentTabStops.end();
596 7900 : sal_Int32 nConverted = rTabStop.Position;
597 7900 : bool bFound = false;
598 20333 : for( ; aIt != aEndIt; ++aIt)
599 : {
600 12666 : if( aIt->Position == nConverted )
601 : {
602 233 : bFound = true;
603 233 : if( rTabStop.bDeleted )
604 77 : m_aCurrentTabStops.erase( aIt );
605 : else
606 156 : *aIt = rTabStop;
607 233 : break;
608 : }
609 : }
610 7900 : if( !bFound )
611 7667 : m_aCurrentTabStops.push_back( rTabStop );
612 7900 : }
613 :
614 :
615 5013 : uno::Sequence< style::TabStop > DomainMapper_Impl::GetCurrentTabStopAndClear()
616 : {
617 5013 : std::vector<style::TabStop> aRet;
618 12934 : for (DeletableTabStop& rStop : m_aCurrentTabStops)
619 : {
620 7921 : if (!rStop.bDeleted)
621 7602 : aRet.push_back(rStop);
622 : }
623 5013 : m_aCurrentTabStops.clear();
624 5013 : m_nCurrentTabStopIndex = 0;
625 5013 : return comphelper::containerToSequence(aRet);
626 : }
627 :
628 : /*-------------------------------------------------------------------------
629 : returns a the value from the current paragraph style - if available
630 : TODO: What about parent styles?
631 : -----------------------------------------------------------------------*/
632 1577 : uno::Any DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId)
633 : {
634 1577 : StyleSheetEntryPtr pEntry;
635 1577 : if( m_bInStyleSheetImport )
636 0 : pEntry = GetStyleSheetTable()->FindParentStyleSheet(OUString());
637 : else
638 3154 : pEntry =
639 1577 : GetStyleSheetTable()->FindStyleSheetByISTD(GetCurrentParaStyleId());
640 5180 : while(pEntry.get( ) )
641 : {
642 : //is there a tab stop set?
643 2271 : if(pEntry->pProperties)
644 : {
645 : boost::optional<PropertyMap::Property> aProperty =
646 2271 : pEntry->pProperties->getProperty(eId);
647 2271 : if( aProperty )
648 : {
649 245 : return aProperty->second;
650 2026 : }
651 : }
652 : //search until the property is set or no parent is available
653 2026 : StyleSheetEntryPtr pNewEntry = GetStyleSheetTable()->FindParentStyleSheet(pEntry->sBaseStyleIdentifier);
654 :
655 : SAL_WARN_IF( pEntry == pNewEntry, "writerfilter", "circular loop in style hierarchy?");
656 :
657 2026 : if (pEntry == pNewEntry) //fdo#49587
658 0 : break;
659 :
660 2026 : pEntry = pNewEntry;
661 2026 : }
662 1332 : return uno::Any();
663 : }
664 :
665 :
666 4666 : ListsManager::Pointer DomainMapper_Impl::GetListTable()
667 : {
668 4666 : if(!m_pListTable)
669 : m_pListTable.reset(
670 494 : new ListsManager( m_rDMapper, m_xTextFactory ));
671 4666 : return m_pListTable;
672 : }
673 :
674 :
675 522 : void DomainMapper_Impl::deferBreak( BreakType deferredBreakType)
676 : {
677 522 : switch (deferredBreakType)
678 : {
679 : case COLUMN_BREAK:
680 141 : m_bIsColumnBreakDeferred = true;
681 141 : break;
682 : case PAGE_BREAK:
683 : // See SwWW8ImplReader::HandlePageBreakChar(), page break should be
684 : // ignored inside tables.
685 381 : if (m_nTableDepth > 0)
686 17 : return;
687 :
688 364 : m_bIsPageBreakDeferred = true;
689 364 : break;
690 : default:
691 0 : return;
692 : }
693 : }
694 :
695 170776 : bool DomainMapper_Impl::isBreakDeferred( BreakType deferredBreakType )
696 : {
697 170776 : switch (deferredBreakType)
698 : {
699 : case COLUMN_BREAK:
700 85604 : return m_bIsColumnBreakDeferred;
701 : case PAGE_BREAK:
702 85172 : return m_bIsPageBreakDeferred;
703 : default:
704 0 : return false;
705 : }
706 : }
707 :
708 1 : void DomainMapper_Impl::clearDeferredBreak(BreakType deferredBreakType)
709 : {
710 1 : switch (deferredBreakType)
711 : {
712 : case COLUMN_BREAK:
713 1 : m_bIsColumnBreakDeferred = false;
714 1 : break;
715 : case PAGE_BREAK:
716 0 : m_bIsPageBreakDeferred = false;
717 0 : break;
718 : default:
719 0 : break;
720 : }
721 1 : }
722 :
723 83753 : void DomainMapper_Impl::clearDeferredBreaks()
724 : {
725 83753 : m_bIsColumnBreakDeferred = false;
726 83753 : m_bIsPageBreakDeferred = false;
727 83753 : }
728 :
729 305 : void DomainMapper_Impl::setSdtEndDeferred(bool bSdtEndDeferred)
730 : {
731 305 : m_bSdtEndDeferred = bSdtEndDeferred;
732 305 : }
733 :
734 154663 : bool DomainMapper_Impl::isSdtEndDeferred()
735 : {
736 154663 : return m_bSdtEndDeferred;
737 : }
738 :
739 32860 : void DomainMapper_Impl::setParaSdtEndDeferred(bool bParaSdtEndDeferred)
740 : {
741 32860 : m_bParaSdtEndDeferred = bParaSdtEndDeferred;
742 32860 : }
743 :
744 32569 : bool DomainMapper_Impl::isParaSdtEndDeferred()
745 : {
746 32569 : return m_bParaSdtEndDeferred;
747 : }
748 :
749 97 : void lcl_MoveBorderPropertiesToFrame(std::vector<beans::PropertyValue>& rFrameProperties,
750 : uno::Reference<text::XTextRange> const& xStartTextRange,
751 : uno::Reference<text::XTextRange> const& xEndTextRange )
752 : {
753 : try
754 : {
755 97 : if (!xStartTextRange.is()) //rhbz#1077780
756 0 : return;
757 101 : uno::Reference<text::XTextCursor> xRangeCursor = xStartTextRange->getText()->createTextCursorByRange( xStartTextRange );
758 93 : xRangeCursor->gotoRange( xEndTextRange, true );
759 :
760 186 : uno::Reference<beans::XPropertySet> xTextRangeProperties(xRangeCursor, uno::UNO_QUERY);
761 93 : if(!xTextRangeProperties.is())
762 0 : return ;
763 :
764 : PropertyIds aBorderProperties[] =
765 : {
766 : PROP_LEFT_BORDER,
767 : PROP_RIGHT_BORDER,
768 : PROP_TOP_BORDER,
769 : PROP_BOTTOM_BORDER,
770 : PROP_LEFT_BORDER_DISTANCE,
771 : PROP_RIGHT_BORDER_DISTANCE,
772 : PROP_TOP_BORDER_DISTANCE,
773 : PROP_BOTTOM_BORDER_DISTANCE
774 93 : };
775 :
776 93 : sal_uInt32 nBorderPropertyCount = sizeof( aBorderProperties ) / sizeof(PropertyIds);
777 :
778 93 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
779 837 : for( sal_uInt32 nProperty = 0; nProperty < nBorderPropertyCount; ++nProperty)
780 : {
781 744 : OUString sPropertyName = rPropNameSupplier.GetName(aBorderProperties[nProperty]);
782 1488 : beans::PropertyValue aValue;
783 744 : aValue.Name = sPropertyName;
784 744 : aValue.Value = xTextRangeProperties->getPropertyValue(sPropertyName);
785 744 : rFrameProperties.push_back(aValue);
786 744 : if( nProperty < 4 )
787 372 : xTextRangeProperties->setPropertyValue( sPropertyName, uno::makeAny(table::BorderLine2()));
788 837 : }
789 : }
790 4 : catch( const uno::Exception& )
791 : {
792 : }
793 : }
794 :
795 :
796 111 : void lcl_AddRangeAndStyle(
797 : ParagraphPropertiesPtr& pToBeSavedProperties,
798 : uno::Reference< text::XTextAppend > const& xTextAppend,
799 : PropertyMapPtr pPropertyMap,
800 : TextAppendContext& rAppendContext)
801 : {
802 : uno::Reference<text::XParagraphCursor> xParaCursor(
803 111 : xTextAppend->createTextCursorByRange( rAppendContext.xInsertPosition.is() ? rAppendContext.xInsertPosition : xTextAppend->getEnd()), uno::UNO_QUERY_THROW );
804 111 : pToBeSavedProperties->SetEndingRange(xParaCursor->getStart());
805 111 : xParaCursor->gotoStartOfParagraph( false );
806 :
807 111 : pToBeSavedProperties->SetStartingRange(xParaCursor->getStart());
808 111 : if(pPropertyMap)
809 : {
810 111 : boost::optional<PropertyMap::Property> aParaStyle = pPropertyMap->getProperty(PROP_PARA_STYLE_NAME);
811 111 : if( aParaStyle )
812 : {
813 111 : OUString sName;
814 111 : aParaStyle->second >>= sName;
815 111 : pToBeSavedProperties->SetParaStyleName(sName);
816 111 : }
817 111 : }
818 111 : }
819 :
820 :
821 : //define some default frame width - 0cm ATM: this allow the frame to be wrapped around the text
822 : #define DEFAULT_FRAME_MIN_WIDTH 0
823 : #define DEFAULT_FRAME_MIN_HEIGHT 0
824 : #define DEFAULT_VALUE 0
825 :
826 2363 : void DomainMapper_Impl::CheckUnregisteredFrameConversion( )
827 : {
828 2363 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
829 2363 : if (m_aTextAppendStack.empty())
830 0 : return;
831 2363 : TextAppendContext& rAppendContext = m_aTextAppendStack.top();
832 : // n#779642: ignore fly frame inside table as it could lead to messy situations
833 4841 : if( rAppendContext.pLastParagraphProperties.get() && rAppendContext.pLastParagraphProperties->IsFrameMode()
834 2478 : && !getTableManager().isInTable() )
835 : {
836 : try
837 : {
838 : StyleSheetEntryPtr pParaStyle =
839 97 : GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(rAppendContext.pLastParagraphProperties->GetParaStyleName());
840 :
841 194 : std::vector<beans::PropertyValue> aFrameProperties;
842 :
843 97 : if ( pParaStyle.get( ) )
844 : {
845 75 : const ParagraphProperties* pStyleProperties = dynamic_cast<const ParagraphProperties*>( pParaStyle->pProperties.get() );
846 75 : if (!pStyleProperties)
847 0 : return;
848 : sal_Int32 nWidth =
849 75 : rAppendContext.pLastParagraphProperties->Getw() > 0 ?
850 6 : rAppendContext.pLastParagraphProperties->Getw() :
851 81 : pStyleProperties->Getw();
852 75 : bool bAutoWidth = nWidth < 1;
853 75 : if( bAutoWidth )
854 69 : nWidth = DEFAULT_FRAME_MIN_WIDTH;
855 75 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_WIDTH), nWidth));
856 :
857 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_HEIGHT),
858 75 : rAppendContext.pLastParagraphProperties->Geth() > 0 ?
859 5 : rAppendContext.pLastParagraphProperties->Geth() :
860 80 : pStyleProperties->Geth() > 0 ? pStyleProperties->Geth() : DEFAULT_FRAME_MIN_HEIGHT));
861 :
862 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_SIZE_TYPE), sal_Int16(
863 75 : rAppendContext.pLastParagraphProperties->GethRule() >= 0 ?
864 7 : rAppendContext.pLastParagraphProperties->GethRule() :
865 82 : pStyleProperties->GethRule() >=0 ? pStyleProperties->GethRule() : text::SizeType::VARIABLE)));
866 :
867 75 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_WIDTH_TYPE), bAutoWidth ? text::SizeType::MIN : text::SizeType::FIX));
868 :
869 : sal_Int16 nHoriOrient = sal_Int16(
870 75 : rAppendContext.pLastParagraphProperties->GetxAlign() >= 0 ?
871 38 : rAppendContext.pLastParagraphProperties->GetxAlign() :
872 113 : pStyleProperties->GetxAlign() >= 0 ? pStyleProperties->GetxAlign() : text::HoriOrientation::NONE );
873 75 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_HORI_ORIENT), nHoriOrient));
874 :
875 : //set a non negative default value
876 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_HORI_ORIENT_POSITION),
877 75 : rAppendContext.pLastParagraphProperties->IsxValid() ?
878 7 : rAppendContext.pLastParagraphProperties->Getx() :
879 82 : pStyleProperties->IsxValid() ? pStyleProperties->Getx() : DEFAULT_VALUE));
880 :
881 : //Default the anchor in case FramePr_hAnchor is missing ECMA 17.3.1.11
882 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_HORI_ORIENT_RELATION), sal_Int16(
883 75 : rAppendContext.pLastParagraphProperties->GethAnchor() >= 0 ?
884 52 : rAppendContext.pLastParagraphProperties->GethAnchor() :
885 127 : pStyleProperties->GethAnchor() >=0 ? pStyleProperties->GethAnchor() : text::RelOrientation::FRAME )));
886 :
887 : sal_Int16 nVertOrient = sal_Int16(
888 75 : rAppendContext.pLastParagraphProperties->GetyAlign() >= 0 ?
889 2 : rAppendContext.pLastParagraphProperties->GetyAlign() :
890 77 : pStyleProperties->GetyAlign() >= 0 ? pStyleProperties->GetyAlign() : text::VertOrientation::NONE );
891 75 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_VERT_ORIENT), nVertOrient));
892 :
893 : //set a non negative default value
894 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_VERT_ORIENT_POSITION),
895 75 : rAppendContext.pLastParagraphProperties->IsyValid() ?
896 50 : rAppendContext.pLastParagraphProperties->Gety() :
897 125 : pStyleProperties->IsyValid() ? pStyleProperties->Gety() : DEFAULT_VALUE));
898 :
899 : //Default the anchor in case FramePr_vAnchor is missing ECMA 17.3.1.11
900 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_VERT_ORIENT_RELATION), sal_Int16(
901 75 : rAppendContext.pLastParagraphProperties->GetvAnchor() >= 0 ?
902 75 : rAppendContext.pLastParagraphProperties->GetvAnchor() :
903 150 : pStyleProperties->GetvAnchor() >= 0 ? pStyleProperties->GetvAnchor() : text::RelOrientation::FRAME )));
904 :
905 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_SURROUND), text::WrapTextMode(
906 75 : rAppendContext.pLastParagraphProperties->GetWrap() >= 0 ?
907 68 : rAppendContext.pLastParagraphProperties->GetWrap() :
908 143 : pStyleProperties->GetWrap() >= 0 ? pStyleProperties->GetWrap() : 0 )));
909 :
910 : /** FDO#73546 : distL & distR should be unsigned intgers <Ecma 20.4.3.6>
911 : Swapped the array elements 11,12 & 13,14 since 11 & 12 are
912 : LEFT & RIGHT margins and 13,14 are TOP and BOTTOM margins respectively.
913 : */
914 : sal_Int32 nRightDist;
915 : sal_Int32 nLeftDist = nRightDist =
916 75 : rAppendContext.pLastParagraphProperties->GethSpace() >= 0 ?
917 1 : rAppendContext.pLastParagraphProperties->GethSpace() :
918 76 : pStyleProperties->GethSpace() >= 0 ? pStyleProperties->GethSpace() : 0;
919 :
920 75 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_LEFT_MARGIN), nHoriOrient == text::HoriOrientation::LEFT ? 0 : nLeftDist));
921 75 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_RIGHT_MARGIN), nHoriOrient == text::HoriOrientation::RIGHT ? 0 : nRightDist));
922 :
923 : sal_Int32 nBottomDist;
924 : sal_Int32 nTopDist = nBottomDist =
925 75 : rAppendContext.pLastParagraphProperties->GetvSpace() >= 0 ?
926 0 : rAppendContext.pLastParagraphProperties->GetvSpace() :
927 75 : pStyleProperties->GetvSpace() >= 0 ? pStyleProperties->GetvSpace() : 0;
928 :
929 75 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_TOP_MARGIN), nVertOrient == text::VertOrientation::TOP ? 0 : nTopDist));
930 75 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_BOTTOM_MARGIN), nVertOrient == text::VertOrientation::BOTTOM ? 0 : nBottomDist));
931 : // If there is no fill, the Word default is 100% transparency.
932 : // Otherwise CellColorHandler has priority, and this setting
933 : // will be ignored.
934 75 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_BACK_COLOR_TRANSPARENCY), sal_Int32(100)));
935 :
936 75 : beans::PropertyValue aRet;
937 150 : uno::Sequence<beans::PropertyValue> aGrabBag(1);
938 75 : aRet.Name = "ParaFrameProperties";
939 75 : aRet.Value <<= uno::Any(rAppendContext.pLastParagraphProperties->IsFrameMode());
940 75 : aGrabBag[0] = aRet;
941 75 : aFrameProperties.push_back(comphelper::makePropertyValue("FrameInteropGrabBag", aGrabBag));
942 :
943 : lcl_MoveBorderPropertiesToFrame(aFrameProperties,
944 : rAppendContext.pLastParagraphProperties->GetStartingRange(),
945 150 : rAppendContext.pLastParagraphProperties->GetEndingRange());
946 : }
947 : else
948 : {
949 22 : sal_Int32 nWidth = rAppendContext.pLastParagraphProperties->Getw();
950 22 : bool bAutoWidth = nWidth < 1;
951 22 : if( bAutoWidth )
952 3 : nWidth = DEFAULT_FRAME_MIN_WIDTH;
953 22 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_WIDTH), nWidth));
954 :
955 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_SIZE_TYPE), sal_Int16(
956 22 : rAppendContext.pLastParagraphProperties->GethRule() >= 0 ?
957 19 : rAppendContext.pLastParagraphProperties->GethRule() :
958 41 : text::SizeType::VARIABLE)));
959 :
960 22 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_WIDTH_TYPE), bAutoWidth ? text::SizeType::MIN : text::SizeType::FIX));
961 :
962 : sal_Int16 nHoriOrient = sal_Int16(
963 22 : rAppendContext.pLastParagraphProperties->GetxAlign() >= 0 ?
964 21 : rAppendContext.pLastParagraphProperties->GetxAlign() :
965 43 : text::HoriOrientation::NONE );
966 22 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_HORI_ORIENT), nHoriOrient));
967 :
968 : sal_Int16 nVertOrient = sal_Int16(
969 22 : rAppendContext.pLastParagraphProperties->GetyAlign() >= 0 ?
970 19 : rAppendContext.pLastParagraphProperties->GetyAlign() :
971 41 : text::VertOrientation::NONE );
972 22 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_VERT_ORIENT), nVertOrient));
973 :
974 22 : sal_Int32 nVertDist = rAppendContext.pLastParagraphProperties->GethSpace();
975 22 : if( nVertDist < 0 )
976 21 : nVertDist = 0;
977 22 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_LEFT_MARGIN), nVertOrient == text::VertOrientation::TOP ? 0 : nVertDist));
978 22 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_RIGHT_MARGIN), nVertOrient == text::VertOrientation::BOTTOM ? 0 : nVertDist));
979 :
980 22 : sal_Int32 nHoriDist = rAppendContext.pLastParagraphProperties->GetvSpace();
981 22 : if( nHoriDist < 0 )
982 21 : nHoriDist = 0;
983 22 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_TOP_MARGIN), nHoriOrient == text::HoriOrientation::LEFT ? 0 : nHoriDist));
984 22 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_BOTTOM_MARGIN), nHoriOrient == text::HoriOrientation::RIGHT ? 0 : nHoriDist));
985 :
986 22 : if( rAppendContext.pLastParagraphProperties->Geth() > 0 )
987 14 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_HEIGHT), rAppendContext.pLastParagraphProperties->Geth()));
988 :
989 22 : if( rAppendContext.pLastParagraphProperties->IsxValid() )
990 19 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_HORI_ORIENT_POSITION), rAppendContext.pLastParagraphProperties->Getx()));
991 :
992 22 : if( rAppendContext.pLastParagraphProperties->GethAnchor() >= 0 )
993 21 : aFrameProperties.push_back(comphelper::makePropertyValue("HoriOrientRelation", sal_Int16(rAppendContext.pLastParagraphProperties->GethAnchor())));
994 :
995 22 : if( rAppendContext.pLastParagraphProperties->IsyValid() )
996 21 : aFrameProperties.push_back(comphelper::makePropertyValue(rPropNameSupplier.GetName(PROP_VERT_ORIENT_POSITION), rAppendContext.pLastParagraphProperties->Gety()));
997 :
998 22 : if( rAppendContext.pLastParagraphProperties->GetvAnchor() >= 0 )
999 22 : aFrameProperties.push_back(comphelper::makePropertyValue("VertOrientRelation", sal_Int16(rAppendContext.pLastParagraphProperties->GetvAnchor())));
1000 :
1001 22 : if( rAppendContext.pLastParagraphProperties->GetWrap() >= 0 )
1002 4 : aFrameProperties.push_back(comphelper::makePropertyValue("Surround", text::WrapTextMode(rAppendContext.pLastParagraphProperties->GetWrap())));
1003 :
1004 : lcl_MoveBorderPropertiesToFrame(aFrameProperties,
1005 : rAppendContext.pLastParagraphProperties->GetStartingRange(),
1006 22 : rAppendContext.pLastParagraphProperties->GetEndingRange());
1007 : }
1008 :
1009 : //frame conversion has to be executed after table conversion
1010 : RegisterFrameConversion(
1011 : rAppendContext.pLastParagraphProperties->GetStartingRange(),
1012 : rAppendContext.pLastParagraphProperties->GetEndingRange(),
1013 194 : aFrameProperties );
1014 : }
1015 0 : catch( const uno::Exception& )
1016 : {
1017 : }
1018 : }
1019 : }
1020 :
1021 31091 : void DomainMapper_Impl::finishParagraph( PropertyMapPtr pPropertyMap )
1022 : {
1023 : #ifdef DEBUG_WRITERFILTER
1024 : TagLogger::getInstance().startElement("finishParagraph");
1025 : #endif
1026 :
1027 31091 : ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pPropertyMap.get() );
1028 31091 : if (!m_aTextAppendStack.size())
1029 31091 : return;
1030 31091 : TextAppendContext& rAppendContext = m_aTextAppendStack.top();
1031 31091 : uno::Reference< text::XTextAppend > xTextAppend;
1032 31091 : if (!m_aTextAppendStack.empty())
1033 31091 : xTextAppend = rAppendContext.xTextAppend;
1034 31091 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1035 :
1036 : #ifdef DEBUG_WRITERFILTER
1037 : TagLogger::getInstance().attribute("isTextAppend", sal_uInt32(xTextAppend.is()));
1038 : #endif
1039 :
1040 31091 : if (xTextAppend.is() && !getTableManager( ).isIgnore() && pParaContext != nullptr)
1041 : {
1042 : try
1043 : {
1044 : /*the following combinations of previous and current frame settings can occur:
1045 : (1) - no old frame and no current frame -> no special action
1046 : (2) - no old frame and current DropCap -> save DropCap for later use, don't call finishParagraph
1047 : remove character properties of the DropCap?
1048 : (3) - no old frame and current Frame -> save Frame for later use
1049 : (4) - old DropCap and no current frame -> add DropCap to the properties of the finished paragraph, delete previous setting
1050 : (5) - old DropCap and current frame -> add DropCap to the properties of the finished paragraph, save current frame settings
1051 : (6) - old Frame and new DropCap -> add old Frame, save DropCap for later use
1052 : (7) - old Frame and new same Frame -> continue
1053 : (8) - old Frame and new different Frame -> add old Frame, save new Frame for later use
1054 : (9) - old Frame and no current frame -> add old Frame, delete previous settings
1055 :
1056 : old _and_ new DropCap must not occur
1057 : */
1058 :
1059 : bool bIsDropCap =
1060 28218 : pParaContext->IsFrameMode() &&
1061 28218 : sal::static_int_cast<Id>(pParaContext->GetDropCap()) != NS_ooxml::LN_Value_doc_ST_DropCap_none;
1062 :
1063 27786 : style::DropCapFormat aDrop;
1064 27786 : ParagraphPropertiesPtr pToBeSavedProperties;
1065 27786 : bool bKeepLastParagraphProperties = false;
1066 27786 : if( bIsDropCap )
1067 : {
1068 : uno::Reference<text::XParagraphCursor> xParaCursor(
1069 0 : xTextAppend->createTextCursorByRange(xTextAppend->getEnd()), uno::UNO_QUERY_THROW);
1070 : //select paragraph
1071 0 : xParaCursor->gotoStartOfParagraph( true );
1072 0 : uno::Reference< beans::XPropertyState > xParaProperties( xParaCursor, uno::UNO_QUERY_THROW );
1073 0 : xParaProperties->setPropertyToDefault(rPropNameSupplier.GetName(PROP_CHAR_ESCAPEMENT));
1074 0 : xParaProperties->setPropertyToDefault(rPropNameSupplier.GetName(PROP_CHAR_HEIGHT));
1075 : //handles (2) and part of (6)
1076 0 : pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
1077 0 : sal_Int32 nCount = xParaCursor->getString().getLength();
1078 0 : pToBeSavedProperties->SetDropCapLength(nCount > 0 && nCount < 255 ? (sal_Int8)nCount : 1);
1079 : }
1080 27786 : if( rAppendContext.pLastParagraphProperties.get() )
1081 : {
1082 428 : if( sal::static_int_cast<Id>(rAppendContext.pLastParagraphProperties->GetDropCap()) != NS_ooxml::LN_Value_doc_ST_DropCap_none)
1083 : {
1084 : //handles (4) and part of (5)
1085 : //create a DropCap property, add it to the property sequence of finishParagraph
1086 0 : sal_Int32 nLines = rAppendContext.pLastParagraphProperties->GetLines();
1087 0 : aDrop.Lines = nLines > 0 && nLines < 254 ? (sal_Int8)++nLines : 2;
1088 0 : aDrop.Count = rAppendContext.pLastParagraphProperties->GetDropCapLength();
1089 0 : aDrop.Distance = 0; //TODO: find distance value
1090 : //completes (5)
1091 0 : if( pParaContext->IsFrameMode() )
1092 0 : pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
1093 : }
1094 428 : else if(*rAppendContext.pLastParagraphProperties == *pParaContext )
1095 : {
1096 : //handles (7)
1097 321 : rAppendContext.pLastParagraphProperties->SetEndingRange(rAppendContext.xInsertPosition.is() ? rAppendContext.xInsertPosition : xTextAppend->getEnd());
1098 321 : bKeepLastParagraphProperties = true;
1099 : }
1100 : else
1101 : {
1102 : //handles (8)(9) and completes (6)
1103 107 : CheckUnregisteredFrameConversion( );
1104 :
1105 : // If different frame properties are set on this paragraph, keep them.
1106 107 : if ( !bIsDropCap && pParaContext->IsFrameMode() )
1107 : {
1108 3 : pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
1109 3 : lcl_AddRangeAndStyle(pToBeSavedProperties, xTextAppend, pPropertyMap, rAppendContext);
1110 : }
1111 : }
1112 :
1113 : }
1114 : else
1115 : {
1116 : // (1) doesn't need handling
1117 :
1118 27358 : if( !bIsDropCap && pParaContext->IsFrameMode() )
1119 : {
1120 108 : pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
1121 108 : lcl_AddRangeAndStyle(pToBeSavedProperties, xTextAppend, pPropertyMap, rAppendContext);
1122 : }
1123 : }
1124 55572 : std::vector<beans::PropertyValue> aProperties;
1125 27786 : if (pPropertyMap.get())
1126 27786 : aProperties = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(pPropertyMap->GetPropertyValues());
1127 27786 : if( !bIsDropCap )
1128 : {
1129 27786 : if( aDrop.Lines > 1 )
1130 : {
1131 0 : beans::PropertyValue aValue;
1132 0 : aValue.Name = rPropNameSupplier.GetName(PROP_DROP_CAP_FORMAT);
1133 0 : aValue.Value <<= aDrop;
1134 0 : aProperties.push_back(aValue);
1135 : }
1136 27786 : uno::Reference< text::XTextRange > xTextRange;
1137 27786 : if (rAppendContext.xInsertPosition.is())
1138 : {
1139 753 : xTextRange = xTextAppend->finishParagraphInsert( comphelper::containerToSequence(aProperties), rAppendContext.xInsertPosition );
1140 753 : rAppendContext.xCursor->gotoNextParagraph(false);
1141 753 : if (rAppendContext.pLastParagraphProperties.get())
1142 0 : rAppendContext.pLastParagraphProperties->SetEndingRange(xTextRange->getEnd());
1143 : }
1144 : else
1145 : {
1146 27033 : uno::Reference<text::XTextCursor> xCursor;
1147 27033 : if (m_bParaHadField)
1148 : {
1149 : // Workaround to make sure char props of the field are not lost.
1150 745 : OUString sMarker("X");
1151 745 : xCursor = xTextAppend->getText()->createTextCursor();
1152 745 : if (xCursor.is())
1153 745 : xCursor->gotoEnd(false);
1154 1490 : PropertyMapPtr pEmpty(new PropertyMap());
1155 1490 : appendTextPortion(sMarker, pEmpty);
1156 : }
1157 :
1158 27033 : xTextRange = xTextAppend->finishParagraph( comphelper::containerToSequence(aProperties) );
1159 :
1160 26870 : if (xCursor.is())
1161 : {
1162 745 : xCursor->goLeft(1, true);
1163 745 : xCursor->setString(OUString());
1164 27033 : }
1165 : }
1166 27623 : getTableManager( ).handle(xTextRange);
1167 :
1168 : // Get the end of paragraph character inserted
1169 55246 : uno::Reference< text::XTextCursor > xCur = xTextRange->getText( )->createTextCursor( );
1170 27623 : if (rAppendContext.xInsertPosition.is())
1171 753 : xCur->gotoRange( rAppendContext.xInsertPosition, false );
1172 : else
1173 26870 : xCur->gotoEnd( false );
1174 27623 : xCur->goLeft( 1 , true );
1175 55246 : uno::Reference< text::XTextRange > xParaEnd( xCur, uno::UNO_QUERY );
1176 55409 : CheckParaMarkerRedline( xParaEnd );
1177 :
1178 : }
1179 27623 : if( !bKeepLastParagraphProperties )
1180 55088 : rAppendContext.pLastParagraphProperties = pToBeSavedProperties;
1181 : }
1182 0 : catch(const lang::IllegalArgumentException&)
1183 : {
1184 : OSL_FAIL( "IllegalArgumentException in DomainMapper_Impl::finishParagraph" );
1185 : }
1186 163 : catch(const uno::Exception& e)
1187 : {
1188 : SAL_WARN( "writerfilter", "finishParagraph() exception: " << e.Message );
1189 : }
1190 : }
1191 :
1192 31091 : m_bParaChanged = false;
1193 31091 : if (!pParaContext || !pParaContext->IsFrameMode())
1194 : { // If the paragraph is in a frame, it's not a paragraph of the section itself.
1195 30658 : m_bIsFirstParaInSection = false;
1196 30658 : m_bIsLastParaInSection = false;
1197 : }
1198 :
1199 31091 : if (pParaContext)
1200 : {
1201 : // Reset the frame properties for the next paragraph
1202 31090 : pParaContext->ResetFrameProperties();
1203 : }
1204 :
1205 31091 : SetIsOutsideAParagraph(true);
1206 31091 : m_bParaHadField = false;
1207 : #ifdef DEBUG_WRITERFILTER
1208 : TagLogger::getInstance().endElement();
1209 : #endif
1210 : }
1211 :
1212 48975 : void DomainMapper_Impl::appendTextPortion( const OUString& rString, PropertyMapPtr pPropertyMap )
1213 : {
1214 48975 : if (m_bDiscardHeaderFooter)
1215 214 : return;
1216 :
1217 48868 : if (m_aTextAppendStack.empty())
1218 0 : return;
1219 : // Before placing call to processDeferredCharacterProperties(), TopContextType should be CONTEXT_CHARACTER
1220 : // processDeferredCharacterProperties() invokes only if character inserted
1221 48868 : if( pPropertyMap == m_pTopContext && !deferredCharacterProperties.empty() && (GetTopContextType() == CONTEXT_CHARACTER) )
1222 16771 : processDeferredCharacterProperties();
1223 48868 : uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
1224 48868 : if(xTextAppend.is() && ! getTableManager( ).isIgnore())
1225 : {
1226 : try
1227 : {
1228 : // If we are in comments, then disable CharGrabBag, comment text doesn't support that.
1229 46293 : uno::Sequence< beans::PropertyValue > pValues = pPropertyMap->GetPropertyValues(/*bCharGrabBag=*/!m_bIsInComments);
1230 46293 : sal_Int32 len = pValues.getLength();
1231 :
1232 46293 : if (m_bStartTOC || m_bStartIndex || m_bStartBibliography)
1233 4375 : for( int i =0; i < len; ++i )
1234 : {
1235 2096 : if (pValues[i].Name == "CharHidden")
1236 698 : pValues[i].Value = uno::makeAny(sal_False);
1237 : }
1238 :
1239 92586 : uno::Reference< text::XTextRange > xTextRange;
1240 46293 : if (m_aTextAppendStack.top().xInsertPosition.is())
1241 : {
1242 2411 : xTextRange = xTextAppend->insertTextPortion(rString, pValues, m_aTextAppendStack.top().xInsertPosition);
1243 2411 : m_aTextAppendStack.top().xCursor->gotoRange(xTextRange->getEnd(), true);
1244 : }
1245 : else
1246 : {
1247 43882 : if (m_bStartTOC || m_bStartIndex || m_bStartBibliography || m_bStartGenericField)
1248 : {
1249 167 : if(m_bInHeaderFooterImport && !m_bStartTOCHeaderFooter)
1250 : {
1251 19 : xTextRange = xTextAppend->appendTextPortion(rString, pValues);
1252 : }
1253 : else
1254 : {
1255 148 : m_bStartedTOC = true;
1256 148 : uno::Reference< text::XTextCursor > xTOCTextCursor;
1257 148 : xTOCTextCursor = xTextAppend->getEnd()->getText( )->createTextCursor( );
1258 148 : xTOCTextCursor->gotoEnd(false);
1259 148 : if (xTOCTextCursor.is())
1260 : {
1261 148 : if (m_bStartIndex || m_bStartBibliography || m_bStartGenericField)
1262 93 : xTOCTextCursor->goLeft(1, false);
1263 148 : xTextRange = xTextAppend->insertTextPortion(rString, pValues, xTOCTextCursor);
1264 : SAL_WARN_IF(!xTextRange.is(), "writerfilter.dmapper", "insertTextPortion failed");
1265 148 : if (!xTextRange.is())
1266 0 : throw uno::Exception("insertTextPortion failed", nullptr);
1267 148 : m_bTextInserted = true;
1268 148 : xTOCTextCursor->gotoRange(xTextRange->getEnd(), true);
1269 148 : mxTOCTextCursor = xTOCTextCursor;
1270 : }
1271 : else
1272 : {
1273 0 : xTextRange = xTextAppend->appendTextPortion(rString, pValues);
1274 0 : xTOCTextCursor = xTextAppend->createTextCursor();
1275 0 : xTOCTextCursor->gotoRange(xTextRange->getEnd(), false);
1276 : }
1277 148 : m_aTextAppendStack.push(TextAppendContext(xTextAppend, xTOCTextCursor));
1278 167 : }
1279 : }
1280 : else
1281 43715 : xTextRange = xTextAppend->appendTextPortion(rString, pValues);
1282 : }
1283 :
1284 46293 : CheckRedline( xTextRange );
1285 92586 : m_bParaChanged = true;
1286 :
1287 : //getTableManager( ).handle(xTextRange);
1288 : }
1289 0 : catch(const lang::IllegalArgumentException&)
1290 : {
1291 : OSL_FAIL( "IllegalArgumentException in DomainMapper_Impl::appendTextPortion" );
1292 : }
1293 0 : catch(const uno::Exception&)
1294 : {
1295 : OSL_FAIL( "Exception in DomainMapper_Impl::appendTextPortion" );
1296 : }
1297 48868 : }
1298 : }
1299 :
1300 :
1301 3692 : void DomainMapper_Impl::appendTextContent(
1302 : const uno::Reference< text::XTextContent >& xContent,
1303 : const uno::Sequence< beans::PropertyValue >& xPropertyValues
1304 : )
1305 : {
1306 : SAL_WARN_IF(m_aTextAppendStack.empty(), "writerfilter.dmapper", "no text append stack");
1307 3692 : if (m_aTextAppendStack.empty())
1308 3692 : return;
1309 3692 : uno::Reference< text::XTextAppendAndConvert > xTextAppendAndConvert( m_aTextAppendStack.top().xTextAppend, uno::UNO_QUERY );
1310 : OSL_ENSURE( xTextAppendAndConvert.is(), "trying to append a text content without XTextAppendAndConvert" );
1311 3692 : if(xTextAppendAndConvert.is() && ! getTableManager( ).isIgnore())
1312 : {
1313 : try
1314 : {
1315 3691 : if (m_aTextAppendStack.top().xInsertPosition.is())
1316 17 : xTextAppendAndConvert->insertTextContentWithProperties( xContent, xPropertyValues, m_aTextAppendStack.top().xInsertPosition );
1317 : else
1318 3674 : xTextAppendAndConvert->appendTextContent( xContent, xPropertyValues );
1319 : }
1320 1067 : catch(const lang::IllegalArgumentException&)
1321 : {
1322 : }
1323 1333 : catch(const uno::Exception&)
1324 : {
1325 : }
1326 3692 : }
1327 : }
1328 :
1329 :
1330 :
1331 55 : void DomainMapper_Impl::appendOLE( const OUString& rStreamName, OLEHandlerPtr pOLEHandler )
1332 : {
1333 : static const char sEmbeddedService[] = "com.sun.star.text.TextEmbeddedObject";
1334 : try
1335 : {
1336 55 : uno::Reference< text::XTextContent > xOLE( m_xTextFactory->createInstance(sEmbeddedService), uno::UNO_QUERY_THROW );
1337 110 : uno::Reference< beans::XPropertySet > xOLEProperties(xOLE, uno::UNO_QUERY_THROW);
1338 :
1339 110 : OUString aCLSID = pOLEHandler->getCLSID(m_xComponentContext);
1340 55 : if (aCLSID.isEmpty())
1341 100 : xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_STREAM_NAME ),
1342 100 : uno::makeAny( rStreamName ));
1343 : else
1344 5 : xOLEProperties->setPropertyValue("CLSID", uno::makeAny(OUString(aCLSID)));
1345 :
1346 55 : awt::Size aSize = pOLEHandler->getSize();
1347 55 : if( !aSize.Width )
1348 0 : aSize.Width = 1000;
1349 55 : if( !aSize.Height )
1350 0 : aSize.Height = 1000;
1351 110 : xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_WIDTH ),
1352 110 : uno::makeAny(aSize.Width));
1353 110 : xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_HEIGHT ),
1354 110 : uno::makeAny(aSize.Height));
1355 :
1356 110 : uno::Reference< graphic::XGraphic > xGraphic = pOLEHandler->getReplacement();
1357 110 : xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_GRAPHIC ),
1358 110 : uno::makeAny(xGraphic));
1359 110 : uno::Reference<beans::XPropertySet> xReplacementProperties(pOLEHandler->getShape(), uno::UNO_QUERY);
1360 55 : if (xReplacementProperties.is())
1361 : {
1362 : OUString pProperties[] = {
1363 : OUString("AnchorType"),
1364 : OUString("Surround"),
1365 : OUString("HoriOrient"),
1366 : OUString("HoriOrientPosition"),
1367 : OUString("VertOrient"),
1368 : OUString("VertOrientPosition")
1369 385 : };
1370 385 : for (size_t i = 0; i < SAL_N_ELEMENTS(pProperties); ++i)
1371 715 : xOLEProperties->setPropertyValue(pProperties[i], xReplacementProperties->getPropertyValue(pProperties[i]));
1372 : }
1373 : else
1374 : // mimic the treatment of graphics here.. it seems anchoring as character
1375 : // gives a better ( visually ) result
1376 0 : xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_ANCHOR_TYPE ), uno::makeAny( text::TextContentAnchorType_AS_CHARACTER ) );
1377 : // remove ( if valid ) associated shape ( used for graphic replacement )
1378 : SAL_WARN_IF(m_aAnchoredStack.empty(), "writerfilter.dmapper", "no anchor stack");
1379 55 : if (!m_aAnchoredStack.empty())
1380 55 : m_aAnchoredStack.top( ).bToRemove = true;
1381 55 : RemoveLastParagraph();
1382 55 : m_aTextAppendStack.pop();
1383 :
1384 :
1385 55 : appendTextContent( xOLE, uno::Sequence< beans::PropertyValue >() );
1386 :
1387 55 : if (!aCLSID.isEmpty())
1388 60 : pOLEHandler->importStream(m_xComponentContext, GetTextDocument(), xOLE);
1389 :
1390 : }
1391 0 : catch( const uno::Exception& )
1392 : {
1393 : OSL_FAIL( "Exception in creation of OLE object" );
1394 : }
1395 :
1396 55 : }
1397 :
1398 267 : void DomainMapper_Impl::appendStarMath( const Value& val )
1399 : {
1400 267 : uno::Reference< embed::XEmbeddedObject > formula;
1401 267 : val.getAny() >>= formula;
1402 267 : if( formula.is() )
1403 : {
1404 : static const char sEmbeddedService[] = "com.sun.star.text.TextEmbeddedObject";
1405 : try
1406 : {
1407 267 : uno::Reference< text::XTextContent > xStarMath( m_xTextFactory->createInstance(sEmbeddedService), uno::UNO_QUERY_THROW );
1408 534 : uno::Reference< beans::XPropertySet > xStarMathProperties(xStarMath, uno::UNO_QUERY_THROW);
1409 :
1410 534 : xStarMathProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_EMBEDDED_OBJECT ),
1411 534 : val.getAny());
1412 :
1413 534 : uno::Reference< uno::XInterface > xInterface( formula->getComponent(), uno::UNO_QUERY );
1414 267 : Size size( 1000, 1000 );
1415 267 : if( oox::FormulaImportBase* formulaimport = dynamic_cast< oox::FormulaImportBase* >( xInterface.get()))
1416 267 : size = formulaimport->getFormulaSize();
1417 534 : xStarMathProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_WIDTH ),
1418 534 : uno::makeAny( sal_Int32(size.Width())));
1419 534 : xStarMathProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_HEIGHT ),
1420 534 : uno::makeAny( sal_Int32(size.Height())));
1421 : // mimic the treatment of graphics here.. it seems anchoring as character
1422 : // gives a better ( visually ) result
1423 534 : xStarMathProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_ANCHOR_TYPE ),
1424 534 : uno::makeAny( text::TextContentAnchorType_AS_CHARACTER ) );
1425 534 : appendTextContent( xStarMath, uno::Sequence< beans::PropertyValue >() );
1426 : }
1427 0 : catch( const uno::Exception& )
1428 : {
1429 : OSL_FAIL( "Exception in creation of StarMath object" );
1430 : }
1431 267 : }
1432 267 : }
1433 :
1434 112 : uno::Reference< beans::XPropertySet > DomainMapper_Impl::appendTextSectionAfter(
1435 : uno::Reference< text::XTextRange >& xBefore )
1436 : {
1437 112 : uno::Reference< beans::XPropertySet > xRet;
1438 112 : if (m_aTextAppendStack.empty())
1439 0 : return xRet;
1440 224 : uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
1441 112 : if(xTextAppend.is())
1442 : {
1443 : try
1444 : {
1445 : uno::Reference< text::XParagraphCursor > xCursor(
1446 112 : xTextAppend->createTextCursorByRange( xBefore ), uno::UNO_QUERY_THROW);
1447 : //the cursor has been moved to the end of the paragraph because of the appendTextPortion() calls
1448 112 : xCursor->gotoStartOfParagraph( false );
1449 112 : if (m_aTextAppendStack.top().xInsertPosition.is())
1450 0 : xCursor->gotoRange( m_aTextAppendStack.top().xInsertPosition, true );
1451 : else
1452 112 : xCursor->gotoEnd( true );
1453 : //the paragraph after this new section is already inserted
1454 112 : xCursor->goLeft(1, true);
1455 : static const char sSectionService[] = "com.sun.star.text.TextSection";
1456 224 : uno::Reference< text::XTextContent > xSection( m_xTextFactory->createInstance(sSectionService), uno::UNO_QUERY_THROW );
1457 112 : xSection->attach( uno::Reference< text::XTextRange >( xCursor, uno::UNO_QUERY_THROW) );
1458 224 : xRet = uno::Reference< beans::XPropertySet > (xSection, uno::UNO_QUERY );
1459 : }
1460 0 : catch(const uno::Exception&)
1461 : {
1462 : }
1463 :
1464 : }
1465 :
1466 112 : return xRet;
1467 : }
1468 :
1469 1337 : void DomainMapper_Impl::PushPageHeaderFooter(bool bHeader, SectionPropertyMap::PageType eType)
1470 : {
1471 1337 : m_aHeaderFooterStack.push(HeaderFooterContext(m_bTextInserted));
1472 1337 : m_bTextInserted = false;
1473 :
1474 1337 : const PropertyIds ePropIsOn = bHeader? PROP_HEADER_IS_ON: PROP_FOOTER_IS_ON;
1475 1337 : const PropertyIds ePropShared = bHeader? PROP_HEADER_IS_SHARED: PROP_FOOTER_IS_SHARED;
1476 1337 : const PropertyIds ePropTextLeft = bHeader? PROP_HEADER_TEXT_LEFT: PROP_FOOTER_TEXT_LEFT;
1477 1337 : const PropertyIds ePropText = bHeader? PROP_HEADER_TEXT: PROP_FOOTER_TEXT;
1478 :
1479 1337 : m_bInHeaderFooterImport = true;
1480 :
1481 : //get the section context
1482 1337 : PropertyMapPtr pContext = DomainMapper_Impl::GetTopContextOfType(CONTEXT_SECTION);
1483 : //ask for the header/footer name of the given type
1484 1337 : SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() );
1485 1337 : if(pSectionContext)
1486 : {
1487 : uno::Reference< beans::XPropertySet > xPageStyle =
1488 : pSectionContext->GetPageStyle(
1489 : GetPageStyles(),
1490 : m_xTextFactory,
1491 1337 : eType == SectionPropertyMap::PAGE_FIRST );
1492 1337 : if (!xPageStyle.is())
1493 1337 : return;
1494 : try
1495 : {
1496 1337 : bool bLeft = eType == SectionPropertyMap::PAGE_LEFT;
1497 1337 : bool bFirst = eType == SectionPropertyMap::PAGE_FIRST;
1498 1337 : if ((!bLeft && !GetSettingsTable()->GetEvenAndOddHeaders()) || (GetSettingsTable()->GetEvenAndOddHeaders()))
1499 : {
1500 1079 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1501 :
1502 : //switch on header/footer use
1503 1079 : xPageStyle->setPropertyValue(
1504 : rPropNameSupplier.GetName(ePropIsOn),
1505 1079 : uno::makeAny(sal_True));
1506 :
1507 1079 : if (bFirst)
1508 : {
1509 329 : OUString aFollowStyle = xPageStyle->getPropertyValue("FollowStyle").get<OUString>();
1510 329 : if (GetPageStyles()->hasByName(aFollowStyle))
1511 : {
1512 : // This is a first page and has a follow style, then enable the header/footer there as well to be consistent.
1513 329 : uno::Reference<beans::XPropertySet> xFollowStyle(GetPageStyles()->getByName(aFollowStyle), uno::UNO_QUERY);
1514 329 : xFollowStyle->setPropertyValue(rPropNameSupplier.GetName(ePropIsOn), uno::makeAny(sal_True));
1515 329 : }
1516 : }
1517 :
1518 : // If the 'Different Even & Odd Pages' flag is turned on - do not ignore it
1519 : // Even if the 'Even' header/footer is blank - the flag should be imported (so it would look in LO like in Word)
1520 1079 : if (!bFirst && GetSettingsTable()->GetEvenAndOddHeaders())
1521 129 : xPageStyle->setPropertyValue(rPropNameSupplier.GetName(ePropShared), uno::makeAny(false));
1522 :
1523 : //set the interface
1524 1079 : uno::Reference< text::XText > xText;
1525 1079 : xPageStyle->getPropertyValue(rPropNameSupplier.GetName(bLeft? ePropTextLeft: ePropText)) >>= xText;
1526 :
1527 : m_aTextAppendStack.push(TextAppendContext(uno::Reference< text::XTextAppend >(xText, uno::UNO_QUERY_THROW),
1528 1079 : m_bIsNewDoc? uno::Reference<text::XTextCursor>(): m_xBodyText->createTextCursorByRange(xText->getStart())));
1529 : }
1530 : else
1531 : {
1532 258 : m_bDiscardHeaderFooter = true;
1533 : }
1534 : }
1535 0 : catch( const uno::Exception& )
1536 : {
1537 1337 : }
1538 1337 : }
1539 : }
1540 :
1541 662 : void DomainMapper_Impl::PushPageHeader(SectionPropertyMap::PageType eType)
1542 : {
1543 662 : PushPageHeaderFooter(/* bHeader = */ true, eType);
1544 662 : }
1545 :
1546 675 : void DomainMapper_Impl::PushPageFooter(SectionPropertyMap::PageType eType)
1547 : {
1548 675 : PushPageHeaderFooter(/* bHeader = */ false, eType);
1549 675 : }
1550 :
1551 1337 : void DomainMapper_Impl::PopPageHeaderFooter()
1552 : {
1553 : //header and footer always have an empty paragraph at the end
1554 : //this has to be removed
1555 1337 : RemoveLastParagraph( );
1556 1337 : if (!m_aTextAppendStack.empty())
1557 : {
1558 1337 : if (!m_bDiscardHeaderFooter)
1559 : {
1560 1079 : m_aTextAppendStack.pop();
1561 : }
1562 1337 : m_bDiscardHeaderFooter = false;
1563 : }
1564 1337 : m_bInHeaderFooterImport = false;
1565 :
1566 1337 : if (!m_aHeaderFooterStack.empty())
1567 : {
1568 1337 : m_bTextInserted = m_aHeaderFooterStack.top().getTextInserted();
1569 1337 : m_aHeaderFooterStack.pop();
1570 : }
1571 1337 : }
1572 :
1573 :
1574 56 : void DomainMapper_Impl::PushFootOrEndnote( bool bIsFootnote )
1575 : {
1576 56 : m_bInFootOrEndnote = true;
1577 : try
1578 : {
1579 : // Redlines outside the footnote should not affect footnote content
1580 56 : m_aRedlines.push(std::vector< RedlineParamsPtr >());
1581 :
1582 56 : PropertyMapPtr pTopContext = GetTopContext();
1583 112 : uno::Reference< text::XText > xFootnoteText;
1584 56 : if (GetTextFactory().is())
1585 112 : xFootnoteText.set( GetTextFactory()->createInstance(
1586 : bIsFootnote ?
1587 56 : OUString( "com.sun.star.text.Footnote" ) : OUString( "com.sun.star.text.Endnote" )),
1588 56 : uno::UNO_QUERY_THROW );
1589 112 : uno::Reference< text::XFootnote > xFootnote( xFootnoteText, uno::UNO_QUERY_THROW );
1590 56 : pTopContext->SetFootnote( xFootnote );
1591 56 : if( pTopContext->GetFootnoteSymbol() != 0)
1592 : {
1593 0 : xFootnote->setLabel( OUString( pTopContext->GetFootnoteSymbol() ) );
1594 : }
1595 112 : FontTablePtr pFontTable = GetFontTable();
1596 112 : uno::Sequence< beans::PropertyValue > aFontProperties;
1597 56 : if( pFontTable && pTopContext->GetFootnoteFontId() >= 0 && pFontTable->size() > (size_t)pTopContext->GetFootnoteFontId() )
1598 : {
1599 0 : const FontEntry::Pointer_t pFontEntry(pFontTable->getFontEntry(sal_uInt32(pTopContext->GetFootnoteFontId())));
1600 0 : PropertyMapPtr aFontProps( new PropertyMap );
1601 0 : aFontProps->Insert(PROP_CHAR_FONT_NAME, uno::makeAny( pFontEntry->sFontName ));
1602 0 : aFontProps->Insert(PROP_CHAR_FONT_CHAR_SET, uno::makeAny( (sal_Int16)pFontEntry->nTextEncoding ));
1603 0 : aFontProps->Insert(PROP_CHAR_FONT_PITCH, uno::makeAny( pFontEntry->nPitchRequest ));
1604 0 : aFontProperties = aFontProps->GetPropertyValues();
1605 : }
1606 56 : else if(!pTopContext->GetFootnoteFontName().isEmpty())
1607 : {
1608 0 : PropertyMapPtr aFontProps( new PropertyMap );
1609 0 : aFontProps->Insert(PROP_CHAR_FONT_NAME, uno::makeAny( pTopContext->GetFootnoteFontName() ));
1610 0 : aFontProperties = aFontProps->GetPropertyValues();
1611 : }
1612 56 : appendTextContent( uno::Reference< text::XTextContent >( xFootnoteText, uno::UNO_QUERY_THROW ), aFontProperties );
1613 : m_aTextAppendStack.push(TextAppendContext(uno::Reference< text::XTextAppend >( xFootnoteText, uno::UNO_QUERY_THROW ),
1614 56 : xFootnoteText->createTextCursorByRange(xFootnoteText->getStart())));
1615 :
1616 : // Redlines for the footnote anchor
1617 56 : CheckRedline( xFootnote->getAnchor( ) );
1618 :
1619 : // Word has a leading tab on footnotes, but we don't implement space
1620 : // between the footnote number and text using a tab, so just ignore
1621 : // that for now.
1622 112 : m_bIgnoreNextTab = true;
1623 : }
1624 0 : catch( const uno::Exception& e )
1625 : {
1626 : SAL_WARN("writerfilter", "exception in PushFootOrEndnote: " << e.Message);
1627 : }
1628 56 : }
1629 :
1630 1447 : void DomainMapper_Impl::CreateRedline(uno::Reference<text::XTextRange> const& xRange,
1631 : RedlineParamsPtr pRedline)
1632 : {
1633 1447 : if ( pRedline.get( ) )
1634 : {
1635 : try
1636 : {
1637 1447 : OUString sType;
1638 1447 : PropertyNameSupplier & rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier( );
1639 1447 : switch ( pRedline->m_nToken & 0xffff )
1640 : {
1641 : case XML_mod:
1642 461 : sType = rPropNameSupplier.GetName( PROP_FORMAT );
1643 461 : break;
1644 : case XML_ins:
1645 73 : sType = rPropNameSupplier.GetName( PROP_INSERT );
1646 73 : break;
1647 : case XML_del:
1648 432 : sType = rPropNameSupplier.GetName( PROP_DELETE );
1649 432 : break;
1650 : case XML_ParagraphFormat:
1651 481 : sType = rPropNameSupplier.GetName( PROP_PARAGRAPH_FORMAT );
1652 481 : break;
1653 : default:
1654 0 : throw lang::IllegalArgumentException("illegal redline token type", nullptr, 0);
1655 : }
1656 1447 : uno::Reference < text::XRedline > xRedline( xRange, uno::UNO_QUERY_THROW );
1657 2894 : beans::PropertyValues aRedlineProperties( 3 );
1658 1447 : beans::PropertyValue * pRedlineProperties = aRedlineProperties.getArray( );
1659 1447 : pRedlineProperties[0].Name = rPropNameSupplier.GetName( PROP_REDLINE_AUTHOR );
1660 1447 : pRedlineProperties[0].Value <<= pRedline->m_sAuthor;
1661 1447 : pRedlineProperties[1].Name = rPropNameSupplier.GetName( PROP_REDLINE_DATE_TIME );
1662 1447 : pRedlineProperties[1].Value <<= ConversionHelper::ConvertDateStringToDateTime( pRedline->m_sDate );
1663 1447 : pRedlineProperties[2].Name = rPropNameSupplier.GetName( PROP_REDLINE_REVERT_PROPERTIES );
1664 1447 : pRedlineProperties[2].Value <<= pRedline->m_aRevertProperties;
1665 2894 : xRedline->makeRedline( sType, aRedlineProperties );
1666 : }
1667 2 : catch( const uno::Exception & )
1668 : {
1669 : OSL_FAIL( "Exception in makeRedline" );
1670 : }
1671 : }
1672 1447 : }
1673 :
1674 27623 : void DomainMapper_Impl::CheckParaMarkerRedline( uno::Reference< text::XTextRange > const& xRange )
1675 : {
1676 27623 : if ( m_pParaMarkerRedline.get( ) )
1677 : {
1678 117 : CreateRedline( xRange, m_pParaMarkerRedline );
1679 117 : ResetParaMarkerRedline( );
1680 : }
1681 27623 : }
1682 :
1683 46349 : void DomainMapper_Impl::CheckRedline( uno::Reference< text::XTextRange > const& xRange )
1684 : {
1685 : // Writer core "officially" does not like overlapping redlines, and its UNO interface is stupid enough
1686 : // to not prevent that. However, in practice in fact everything appears to work fine (except for the debug warnings
1687 : // about redline table corruption, which may possibly be harmless in reality). So leave this as it is, since this
1688 : // is a better representation of how the changes happened. If this will ever become a problem, overlapping redlines
1689 : // will need to be merged into one, just like doing the changes in the UI does, which will lose some information
1690 : // (and so if that happens, it may be better to fix Writer).
1691 : // Create the redlines here from lowest (formats) to highest (inserts/removals) priority, since the last one is
1692 : // what Writer presents graphically, so this will show deletes as deleted text and not as just formatted text being there.
1693 46349 : if( GetTopContextOfType(CONTEXT_PARAGRAPH) )
1694 : {
1695 46348 : std::vector<RedlineParamsPtr>& avRedLines = GetTopContextOfType(CONTEXT_PARAGRAPH)->Redlines();
1696 140487 : for( std::vector<RedlineParamsPtr>::const_iterator it = avRedLines.begin();
1697 93658 : it != avRedLines.end(); ++it )
1698 481 : CreateRedline( xRange, *it );
1699 : }
1700 46349 : if( GetTopContextOfType(CONTEXT_CHARACTER) )
1701 : {
1702 46333 : std::vector<RedlineParamsPtr>& avRedLines = GetTopContextOfType(CONTEXT_CHARACTER)->Redlines();
1703 140382 : for( std::vector<RedlineParamsPtr>::const_iterator it = avRedLines.begin();
1704 93588 : it != avRedLines.end(); ++it )
1705 461 : CreateRedline( xRange, *it );
1706 : }
1707 46349 : std::vector<RedlineParamsPtr>::iterator pIt = m_aRedlines.top().begin( );
1708 46737 : for (; pIt != m_aRedlines.top().end( ); ++pIt )
1709 388 : CreateRedline( xRange, *pIt );
1710 46349 : }
1711 :
1712 224 : void DomainMapper_Impl::StartParaMarkerChange( )
1713 : {
1714 224 : m_bIsParaMarkerChange = true;
1715 224 : }
1716 :
1717 993 : void DomainMapper_Impl::EndParaMarkerChange( )
1718 : {
1719 993 : m_bIsParaMarkerChange = false;
1720 993 : m_currentRedline.reset();
1721 993 : }
1722 :
1723 :
1724 :
1725 37 : void DomainMapper_Impl::PushAnnotation()
1726 : {
1727 : try
1728 : {
1729 37 : PropertyMapPtr pTopContext = GetTopContext();
1730 37 : m_bIsInComments = true;
1731 37 : if (!GetTextFactory().is())
1732 37 : return;
1733 111 : m_xAnnotationField = uno::Reference< beans::XPropertySet >( GetTextFactory()->createInstance(
1734 37 : "com.sun.star.text.TextField.Annotation" ),
1735 37 : uno::UNO_QUERY_THROW );
1736 74 : uno::Reference< text::XText > xAnnotationText;
1737 37 : m_xAnnotationField->getPropertyValue("TextRange") >>= xAnnotationText;
1738 : m_aTextAppendStack.push(TextAppendContext(uno::Reference< text::XTextAppend >( xAnnotationText, uno::UNO_QUERY_THROW ),
1739 74 : m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : xAnnotationText->createTextCursorByRange(xAnnotationText->getStart())));
1740 : }
1741 0 : catch( const uno::Exception& rException)
1742 : {
1743 : SAL_WARN("writerfilter", "exception in PushAnnotation: " << rException.Message);
1744 : }
1745 : }
1746 :
1747 :
1748 56 : void DomainMapper_Impl::PopFootOrEndnote()
1749 : {
1750 : // In case the foot or endnote did not contain a tab.
1751 56 : m_bIgnoreNextTab = false;
1752 :
1753 56 : if (!m_aTextAppendStack.empty())
1754 56 : m_aTextAppendStack.pop();
1755 :
1756 56 : if (m_aRedlines.size() == 1)
1757 : {
1758 : SAL_WARN("writerfilter", "PopFootOrEndnote() is called without PushFootOrEndnote()?");
1759 56 : return;
1760 : }
1761 56 : m_aRedlines.pop();
1762 56 : m_bInFootOrEndnote = false;
1763 : }
1764 :
1765 :
1766 37 : void DomainMapper_Impl::PopAnnotation()
1767 : {
1768 37 : RemoveLastParagraph();
1769 :
1770 37 : m_bIsInComments = false;
1771 37 : m_aTextAppendStack.pop();
1772 :
1773 : try
1774 : {
1775 : // See if the annotation will be a single position or a range.
1776 37 : if (m_nAnnotationId == -1 || !m_aAnnotationPositions[m_nAnnotationId].m_xStart.is() || !m_aAnnotationPositions[m_nAnnotationId].m_xEnd.is())
1777 : {
1778 17 : uno::Sequence< beans::PropertyValue > aEmptyProperties;
1779 17 : appendTextContent( uno::Reference< text::XTextContent >( m_xAnnotationField, uno::UNO_QUERY_THROW ), aEmptyProperties );
1780 : }
1781 : else
1782 : {
1783 20 : AnnotationPosition& aAnnotationPosition = m_aAnnotationPositions[m_nAnnotationId];
1784 : // Create a range that points to the annotation start/end.
1785 20 : uno::Reference<text::XText> const xText = aAnnotationPosition.m_xStart->getText();
1786 40 : uno::Reference<text::XTextCursor> const xCursor = xText->createTextCursorByRange(aAnnotationPosition.m_xStart);
1787 20 : xCursor->gotoRange(aAnnotationPosition.m_xEnd, true);
1788 40 : uno::Reference<text::XTextRange> const xTextRange(xCursor, uno::UNO_QUERY_THROW);
1789 :
1790 : // Attach the annotation to the range.
1791 40 : uno::Reference<text::XTextAppend> const xTextAppend = m_aTextAppendStack.top().xTextAppend;
1792 40 : xTextAppend->insertTextContent(xTextRange, uno::Reference<text::XTextContent>(m_xAnnotationField, uno::UNO_QUERY_THROW), !xCursor->isCollapsed());
1793 : }
1794 37 : m_aAnnotationPositions.erase( m_nAnnotationId );
1795 : }
1796 0 : catch (uno::Exception const& e)
1797 : {
1798 : SAL_WARN("writerfilter",
1799 : "Cannot insert annotation field: exception: " << e.Message);
1800 : }
1801 :
1802 37 : m_xAnnotationField.clear();
1803 37 : m_nAnnotationId = -1;
1804 37 : }
1805 :
1806 102 : void DomainMapper_Impl::PushPendingShape( const uno::Reference< drawing::XShape > & xShape )
1807 : {
1808 102 : m_aPendingShapes.push_back(xShape);
1809 102 : }
1810 :
1811 71 : uno::Reference<drawing::XShape> DomainMapper_Impl::PopPendingShape()
1812 : {
1813 71 : uno::Reference<drawing::XShape> xRet;
1814 71 : if (!m_aPendingShapes.empty())
1815 : {
1816 71 : xRet = m_aPendingShapes.front();
1817 71 : m_aPendingShapes.pop_front();
1818 : }
1819 71 : return xRet;
1820 : }
1821 :
1822 1419 : void DomainMapper_Impl::PushShapeContext( const uno::Reference< drawing::XShape > & xShape )
1823 : {
1824 1419 : if (m_aTextAppendStack.empty())
1825 1419 : return;
1826 1419 : uno::Reference<text::XTextAppend> xTextAppend = m_aTextAppendStack.top().xTextAppend;
1827 :
1828 1419 : appendTableManager( );
1829 1419 : appendTableHandler( );
1830 1419 : getTableManager().startLevel();
1831 : try
1832 : {
1833 1419 : uno::Reference< lang::XServiceInfo > xSInfo( xShape, uno::UNO_QUERY_THROW );
1834 1410 : if (xSInfo->supportsService("com.sun.star.drawing.GroupShape"))
1835 : {
1836 : // A GroupShape doesn't implement text::XTextRange, but appending
1837 : // an empty reference to the stacks still makes sense, because this
1838 : // way bToRemove can be set, and we won't end up with duplicated
1839 : // shapes for OLE objects.
1840 139 : m_aTextAppendStack.push(TextAppendContext(uno::Reference<text::XTextAppend>(xShape, uno::UNO_QUERY), uno::Reference<text::XTextCursor>()));
1841 139 : uno::Reference<text::XTextContent> xTxtContent(xShape, uno::UNO_QUERY);
1842 139 : m_aAnchoredStack.push(xTxtContent);
1843 : }
1844 1271 : else if (xSInfo->supportsService("com.sun.star.drawing.OLE2Shape"))
1845 : {
1846 : // OLE2Shape from oox should be converted to a TextEmbeddedObject for sw.
1847 86 : m_aTextAppendStack.push(TextAppendContext(uno::Reference<text::XTextAppend>(xShape, uno::UNO_QUERY), uno::Reference<text::XTextCursor>()));
1848 86 : uno::Reference<text::XTextContent> xTextContent(xShape, uno::UNO_QUERY);
1849 86 : m_aAnchoredStack.push(xTextContent);
1850 172 : uno::Reference<beans::XPropertySet> xShapePropertySet(xShape, uno::UNO_QUERY);
1851 :
1852 86 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1853 :
1854 86 : m_xEmbedded.set(m_xTextFactory->createInstance("com.sun.star.text.TextEmbeddedObject"), uno::UNO_QUERY_THROW);
1855 172 : uno::Reference<beans::XPropertySet> xEmbeddedProperties(m_xEmbedded, uno::UNO_QUERY_THROW);
1856 86 : xEmbeddedProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_EMBEDDED_OBJECT), xShapePropertySet->getPropertyValue(rPropNameSupplier.GetName(PROP_EMBEDDED_OBJECT)));
1857 86 : xEmbeddedProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_ANCHOR_TYPE), uno::makeAny(text::TextContentAnchorType_AS_CHARACTER));
1858 : // So that the original bitmap-only shape will be replaced by the embedded object.
1859 86 : m_aAnchoredStack.top().bToRemove = true;
1860 86 : m_aTextAppendStack.pop();
1861 172 : appendTextContent(m_xEmbedded, uno::Sequence<beans::PropertyValue>());
1862 : }
1863 : else
1864 : {
1865 1185 : uno::Reference< text::XTextRange > xShapeText( xShape, uno::UNO_QUERY_THROW);
1866 : // Add the shape to the text append stack
1867 : m_aTextAppendStack.push( TextAppendContext(uno::Reference< text::XTextAppend >( xShape, uno::UNO_QUERY_THROW ),
1868 1185 : m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(xShapeText->getStart() )));
1869 :
1870 : // Add the shape to the anchored objects stack
1871 2370 : uno::Reference< text::XTextContent > xTxtContent( xShape, uno::UNO_QUERY_THROW );
1872 1185 : m_aAnchoredStack.push( xTxtContent );
1873 :
1874 1185 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1875 :
1876 2370 : uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY_THROW );
1877 : #ifdef DEBUG_WRITERFILTER
1878 : TagLogger::getInstance().unoPropertySet(xProps);
1879 : #endif
1880 1185 : text::TextContentAnchorType nAnchorType(text::TextContentAnchorType_AT_PARAGRAPH);
1881 1185 : xProps->getPropertyValue(rPropNameSupplier.GetName( PROP_ANCHOR_TYPE )) >>= nAnchorType;
1882 1185 : bool checkZOrderStatus = false;
1883 1185 : if (xSInfo->supportsService("com.sun.star.text.TextFrame"))
1884 : {
1885 123 : SetIsTextFrameInserted(true);
1886 : // Extract the special "btLr text frame" mode, requested by oox, if needed.
1887 : // Extract vml ZOrder from FrameInteropGrabBag
1888 123 : uno::Reference<beans::XPropertySet> xShapePropertySet(xShape, uno::UNO_QUERY);
1889 246 : uno::Sequence<beans::PropertyValue> aGrabBag;
1890 123 : xShapePropertySet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag;
1891 123 : bool checkBtLrStatus = false;
1892 :
1893 198 : for (int i = 0; i < aGrabBag.getLength(); ++i)
1894 : {
1895 79 : if (aGrabBag[i].Name == "mso-layout-flow-alt")
1896 : {
1897 3 : m_bFrameBtLr = aGrabBag[i].Value.get<OUString>() == "bottom-to-top";
1898 3 : checkBtLrStatus = true;
1899 : }
1900 79 : if (aGrabBag[i].Name == "VML-Z-ORDER")
1901 : {
1902 75 : GraphicZOrderHelper* pZOrderHelper = m_rDMapper.graphicZOrderHelper();
1903 75 : sal_Int32 zOrder(0);
1904 75 : aGrabBag[i].Value >>= zOrder;
1905 75 : xShapePropertySet->setPropertyValue( "ZOrder", uno::makeAny(pZOrderHelper->findZOrder(zOrder)));
1906 74 : pZOrderHelper->addItem(xShapePropertySet, zOrder);
1907 74 : checkZOrderStatus = true;
1908 : }
1909 78 : if(checkBtLrStatus && checkZOrderStatus)
1910 3 : break;
1911 :
1912 75 : if ( aGrabBag[i].Name == "TxbxHasLink" )
1913 : {
1914 : //Chaining of textboxes will happen in ~DomainMapper_Impl
1915 : //i.e when all the textboxes are read and all its attributes
1916 : //have been set ( basically the Name/LinkedDisplayName )
1917 : //which is set in Graphic Import.
1918 0 : m_vTextFramesForChaining.push_back(xShape);
1919 : }
1920 : }
1921 :
1922 244 : uno::Reference<text::XTextContent> xTextContent(xShape, uno::UNO_QUERY_THROW);
1923 244 : uno::Reference<text::XTextRange> xTextRange(xTextAppend->createTextCursorByRange(xTextAppend->getEnd()), uno::UNO_QUERY_THROW);
1924 122 : xTextAppend->insertTextContent(xTextRange, xTextContent, sal_False);
1925 :
1926 244 : uno::Reference<beans::XPropertySet> xPropertySet(xTextContent, uno::UNO_QUERY);
1927 : // we need to re-set this value to xTextContent, then only values are preserved.
1928 245 : xPropertySet->setPropertyValue("FrameInteropGrabBag",uno::makeAny(aGrabBag));
1929 : }
1930 1062 : else if (nAnchorType == text::TextContentAnchorType_AS_CHARACTER)
1931 : {
1932 : // Fix spacing for as-character objects. If the paragraph has CT_Spacing_after set,
1933 : // it needs to be set on the object too, as that's what object placement code uses.
1934 105 : PropertyMapPtr paragraphContext = GetTopContextOfType( CONTEXT_PARAGRAPH );
1935 210 : boost::optional<PropertyMap::Property> aPropMargin = paragraphContext->getProperty(PROP_PARA_BOTTOM_MARGIN);
1936 105 : if(aPropMargin)
1937 118 : xProps->setPropertyValue( rPropNameSupplier.GetName( PROP_BOTTOM_MARGIN ), aPropMargin->second );
1938 : }
1939 : else
1940 : {
1941 957 : uno::Reference<beans::XPropertySet> xShapePropertySet(xShape, uno::UNO_QUERY);
1942 1914 : uno::Sequence<beans::PropertyValue> aGrabBag;
1943 957 : xShapePropertySet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
1944 4108 : for (int i = 0; i < aGrabBag.getLength(); ++i)
1945 : {
1946 3152 : if (aGrabBag[i].Name == "VML-Z-ORDER")
1947 : {
1948 67 : GraphicZOrderHelper* pZOrderHelper = m_rDMapper.graphicZOrderHelper();
1949 67 : sal_Int32 zOrder(0);
1950 67 : aGrabBag[i].Value >>= zOrder;
1951 67 : xShapePropertySet->setPropertyValue( "ZOrder", uno::makeAny(pZOrderHelper->findZOrder(zOrder)));
1952 66 : pZOrderHelper->addItem(xShapePropertySet, zOrder);
1953 66 : xShapePropertySet->setPropertyValue(rPropNameSupplier.GetName( PROP_OPAQUE ), uno::makeAny( false ) );
1954 66 : checkZOrderStatus = true;
1955 : }
1956 3085 : else if ( aGrabBag[i].Name == "TxbxHasLink" )
1957 : {
1958 : //Chaining of textboxes will happen in ~DomainMapper_Impl
1959 : //i.e when all the textboxes are read and all its attributes
1960 : //have been set ( basically the Name/LinkedDisplayName )
1961 : //which is set in Graphic Import.
1962 6 : m_vTextFramesForChaining.push_back(xShape);
1963 : }
1964 : }
1965 :
1966 956 : if(IsSdtEndBefore())
1967 : {
1968 6 : uno::Reference< beans::XPropertySetInfo > xPropSetInfo;
1969 6 : if(xShapePropertySet.is())
1970 : {
1971 6 : xPropSetInfo = xShapePropertySet->getPropertySetInfo();
1972 6 : if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("InteropGrabBag"))
1973 : {
1974 6 : uno::Sequence<beans::PropertyValue> aShapeGrabBag(1);
1975 12 : beans::PropertyValue aRet;
1976 6 : aRet.Name = "SdtEndBefore";
1977 6 : aRet.Value <<= uno::makeAny(true);
1978 6 : aShapeGrabBag[0] = aRet;
1979 12 : xShapePropertySet->setPropertyValue("InteropGrabBag",uno::makeAny(aShapeGrabBag));
1980 : }
1981 6 : }
1982 957 : }
1983 : }
1984 1183 : if (!m_bInHeaderFooterImport && !checkZOrderStatus)
1985 939 : xProps->setPropertyValue(
1986 : rPropNameSupplier.GetName( PROP_OPAQUE ),
1987 2124 : uno::makeAny( true ) );
1988 : }
1989 1408 : m_bParaChanged = true;
1990 1410 : getTableManager().setIsInShape(true);
1991 : }
1992 11 : catch ( const uno::Exception& e )
1993 : {
1994 : SAL_WARN("writerfilter", "Exception when adding shape: " << e.Message);
1995 1419 : }
1996 : }
1997 : /*
1998 : * Updating chart height and width after reading the actual values from wp:extent
1999 : */
2000 86 : void DomainMapper_Impl::UpdateEmbeddedShapeProps(const uno::Reference< drawing::XShape > & xShape)
2001 : {
2002 86 : if (!xShape.is())
2003 86 : return;
2004 :
2005 86 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
2006 86 : uno::Reference<beans::XPropertySet> xEmbeddedProperties(m_xEmbedded, uno::UNO_QUERY_THROW);
2007 86 : awt::Size aSize = xShape->getSize( );
2008 86 : xEmbeddedProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_WIDTH), uno::makeAny(sal_Int32(aSize.Width)));
2009 86 : xEmbeddedProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_HEIGHT), uno::makeAny(sal_Int32(aSize.Height)));
2010 : }
2011 :
2012 :
2013 1419 : void DomainMapper_Impl::PopShapeContext()
2014 : {
2015 1419 : getTableManager().endLevel();
2016 1419 : popTableManager();
2017 1419 : if ( m_aAnchoredStack.size() > 0 )
2018 : {
2019 : // For OLE object replacement shape, the text append context was already removed
2020 : // or the OLE object couldn't be inserted.
2021 1410 : if ( !m_aAnchoredStack.top().bToRemove )
2022 : {
2023 1269 : RemoveLastParagraph();
2024 1269 : m_aTextAppendStack.pop();
2025 : }
2026 :
2027 1410 : uno::Reference< text::XTextContent > xObj = m_aAnchoredStack.top( ).xTextContent;
2028 : try
2029 : {
2030 1410 : appendTextContent( xObj, uno::Sequence< beans::PropertyValue >() );
2031 : }
2032 0 : catch ( const uno::RuntimeException& )
2033 : {
2034 : // this is normal: the shape is already attached
2035 : }
2036 :
2037 : // Remove the shape if required (most likely replacement shape for OLE object)
2038 : // or anchored to a discarded header or footer
2039 1410 : if ( m_aAnchoredStack.top().bToRemove || m_bDiscardHeaderFooter )
2040 : {
2041 : try
2042 : {
2043 152 : uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(m_xTextDocument, uno::UNO_QUERY_THROW);
2044 304 : uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
2045 152 : if ( xDrawPage.is() )
2046 : {
2047 152 : uno::Reference<drawing::XShape> xShape( xObj, uno::UNO_QUERY_THROW );
2048 152 : xDrawPage->remove( xShape );
2049 152 : }
2050 : }
2051 0 : catch( const uno::Exception& )
2052 : {
2053 : }
2054 : }
2055 1410 : m_aAnchoredStack.pop();
2056 : }
2057 1419 : m_bFrameBtLr = false;
2058 1419 : }
2059 :
2060 2329 : bool DomainMapper_Impl::IsSdtEndBefore()
2061 : {
2062 2329 : bool bIsSdtEndBefore = false;;
2063 2329 : PropertyMapPtr pContext = GetTopContextOfType(CONTEXT_CHARACTER);
2064 2329 : if(pContext)
2065 : {
2066 2272 : uno::Sequence< beans::PropertyValue > currentCharProps = pContext->GetPropertyValues();
2067 9084 : for (int i =0; i< currentCharProps.getLength(); i++)
2068 : {
2069 6812 : if (currentCharProps[i].Name == "CharInteropGrabBag")
2070 : {
2071 691 : uno::Sequence<beans::PropertyValue> aCharGrabBag;
2072 691 : currentCharProps[i].Value >>= aCharGrabBag;
2073 2033 : for (int j=0; j < aCharGrabBag.getLength();j++)
2074 : {
2075 1342 : if(aCharGrabBag[j].Name == "SdtEndBefore")
2076 : {
2077 21 : aCharGrabBag[j].Value >>= bIsSdtEndBefore;
2078 : }
2079 691 : }
2080 : }
2081 2272 : }
2082 : }
2083 2329 : return bIsSdtEndBefore;
2084 : }
2085 :
2086 395 : bool DomainMapper_Impl::IsDiscardHeaderFooter()
2087 : {
2088 395 : return m_bDiscardHeaderFooter;
2089 : }
2090 :
2091 303 : sal_Int16 lcl_ParseNumberingType( const OUString& rCommand )
2092 : {
2093 303 : sal_Int16 nRet = style::NumberingType::PAGE_DESCRIPTOR;
2094 :
2095 : // The command looks like: " PAGE \* Arabic "
2096 303 : OUString sNumber = msfilter::util::findQuotedText(rCommand, "\\* ", ' ');
2097 :
2098 303 : if( !sNumber.isEmpty() )
2099 : {
2100 : //todo: might make sense to hash this list, too
2101 : struct NumberingPairs
2102 : {
2103 : const sal_Char* cWordName;
2104 : sal_Int16 nType;
2105 : };
2106 : static const NumberingPairs aNumberingPairs[] =
2107 : {
2108 : {"Arabic", style::NumberingType::ARABIC}
2109 : ,{"ROMAN", style::NumberingType::ROMAN_UPPER}
2110 : ,{"roman", style::NumberingType::ROMAN_LOWER}
2111 : ,{"ALPHABETIC", style::NumberingType::CHARS_UPPER_LETTER}
2112 : ,{"alphabetic", style::NumberingType::CHARS_LOWER_LETTER}
2113 : ,{"CircleNum", style::NumberingType::CIRCLE_NUMBER}
2114 : ,{"ThaiArabic", style::NumberingType::CHARS_THAI}
2115 : ,{"ThaiCardText", style::NumberingType::CHARS_THAI}
2116 : ,{"ThaiLetter", style::NumberingType::CHARS_THAI}
2117 : // ,{"SBCHAR", style::NumberingType::}
2118 : // ,{"DBCHAR", style::NumberingType::}
2119 : // ,{"DBNUM1", style::NumberingType::}
2120 : // ,{"DBNUM2", style::NumberingType::}
2121 : // ,{"DBNUM3", style::NumberingType::}
2122 : // ,{"DBNUM4", style::NumberingType::}
2123 : ,{"Aiueo", style::NumberingType::AIU_FULLWIDTH_JA}
2124 : ,{"Iroha", style::NumberingType::IROHA_FULLWIDTH_JA}
2125 : // ,{"ZODIAC1", style::NumberingType::}
2126 : // ,{"ZODIAC2", style::NumberingType::}
2127 : // ,{"ZODIAC3", style::NumberingType::}
2128 : // ,{"CHINESENUM1", style::NumberingType::}
2129 : // ,{"CHINESENUM2", style::NumberingType::}
2130 : // ,{"CHINESENUM3", style::NumberingType::}
2131 : ,{"ArabicAlpha", style::NumberingType::CHARS_ARABIC}
2132 : ,{"ArabicAbjad", style::NumberingType::FULLWIDTH_ARABIC}
2133 : /* possible values:
2134 : style::NumberingType::
2135 :
2136 : CHARS_UPPER_LETTER_N
2137 : CHARS_LOWER_LETTER_N
2138 : TRANSLITERATION
2139 : NATIVE_NUMBERING
2140 : CIRCLE_NUMBER
2141 : NUMBER_LOWER_ZH
2142 : NUMBER_UPPER_ZH
2143 : NUMBER_UPPER_ZH_TW
2144 : TIAN_GAN_ZH
2145 : DI_ZI_ZH
2146 : NUMBER_TRADITIONAL_JA
2147 : AIU_HALFWIDTH_JA
2148 : IROHA_HALFWIDTH_JA
2149 : NUMBER_UPPER_KO
2150 : NUMBER_HANGUL_KO
2151 : HANGUL_JAMO_KO
2152 : HANGUL_SYLLABLE_KO
2153 : HANGUL_CIRCLED_JAMO_KO
2154 : HANGUL_CIRCLED_SYLLABLE_KO
2155 : CHARS_HEBREW
2156 : CHARS_NEPALI
2157 : CHARS_KHMER
2158 : CHARS_LAO
2159 : CHARS_TIBETAN
2160 : CHARS_CYRILLIC_UPPER_LETTER_BG
2161 : CHARS_CYRILLIC_LOWER_LETTER_BG
2162 : CHARS_CYRILLIC_UPPER_LETTER_N_BG
2163 : CHARS_CYRILLIC_LOWER_LETTER_N_BG
2164 : CHARS_CYRILLIC_UPPER_LETTER_RU
2165 : CHARS_CYRILLIC_LOWER_LETTER_RU
2166 : CHARS_CYRILLIC_UPPER_LETTER_N_RU
2167 : CHARS_CYRILLIC_LOWER_LETTER_N_RU
2168 : CHARS_CYRILLIC_UPPER_LETTER_SR
2169 : CHARS_CYRILLIC_LOWER_LETTER_SR
2170 : CHARS_CYRILLIC_UPPER_LETTER_N_SR
2171 : CHARS_CYRILLIC_LOWER_LETTER_N_SR*/
2172 :
2173 : };
2174 2184 : for( sal_uInt32 nNum = 0; nNum < sizeof(aNumberingPairs)/sizeof( NumberingPairs ); ++nNum)
2175 : {
2176 2029 : if( /*sCommand*/sNumber.equalsAscii(aNumberingPairs[nNum].cWordName ))
2177 : {
2178 8 : nRet = aNumberingPairs[nNum].nType;
2179 8 : break;
2180 : }
2181 : }
2182 :
2183 : }
2184 303 : return nRet;
2185 : }
2186 :
2187 :
2188 13 : OUString lcl_ParseFormat( const OUString& rCommand )
2189 : {
2190 : // The command looks like: " DATE \@"dd MMMM yyyy"
2191 : // Remove whitespace permitted by standard between \@ and "
2192 13 : sal_Int32 delimPos = rCommand.indexOf("\\@");
2193 13 : sal_Int32 wsChars = rCommand.indexOf('\"') - delimPos - 2;
2194 13 : OUString command = rCommand.replaceAt(delimPos+2, wsChars, "");
2195 :
2196 13 : return msfilter::util::findQuotedText(command, "\\@\"", '\"');
2197 : }
2198 : /*-------------------------------------------------------------------------
2199 : extract a parameter (with or without quotes) between the command and the following backslash
2200 : -----------------------------------------------------------------------*/
2201 7339 : static OUString lcl_ExtractToken(OUString const& rCommand,
2202 : sal_Int32 & rIndex, bool & rHaveToken, bool & rIsSwitch)
2203 : {
2204 7339 : rHaveToken = false;
2205 7339 : rIsSwitch = false;
2206 :
2207 7339 : OUStringBuffer token;
2208 7339 : bool bQuoted(false);
2209 73438 : for (; rIndex < rCommand.getLength(); ++rIndex)
2210 : {
2211 72734 : sal_Unicode const currentChar(rCommand[rIndex]);
2212 72734 : switch (currentChar)
2213 : {
2214 : case '\\':
2215 : {
2216 1616 : if (rIndex == rCommand.getLength() - 1)
2217 : {
2218 : SAL_INFO("writerfilter.dmapper", "field: trailing escape");
2219 0 : ++rIndex;
2220 0 : return OUString();
2221 : }
2222 1616 : sal_Unicode const nextChar(rCommand[rIndex+1]);
2223 1616 : if (bQuoted || '\\' == nextChar)
2224 : {
2225 15 : ++rIndex; // read 2 chars
2226 15 : token.append(nextChar);
2227 : }
2228 : else // field switch (case insensitive)
2229 : {
2230 1601 : rHaveToken = true;
2231 1601 : if (token.isEmpty())
2232 : {
2233 1597 : rIsSwitch = true;
2234 1597 : rIndex += 2; // read 2 chars
2235 1597 : return rCommand.copy(rIndex - 2, 2).toAsciiUpperCase();
2236 : }
2237 : else
2238 : { // leave rIndex, read it again next time
2239 4 : return token.makeStringAndClear();
2240 : }
2241 : }
2242 : }
2243 15 : break;
2244 : case '\"':
2245 4035 : if (bQuoted || !token.isEmpty())
2246 : {
2247 2165 : rHaveToken = true;
2248 2165 : if (bQuoted)
2249 : {
2250 1869 : ++rIndex;
2251 : }
2252 2165 : return token.makeStringAndClear();
2253 : }
2254 : else
2255 : {
2256 1870 : bQuoted = true;
2257 : }
2258 1870 : break;
2259 : case ' ':
2260 7620 : if (bQuoted)
2261 : {
2262 379 : token.append(' ');
2263 : }
2264 : else
2265 : {
2266 7241 : if (!token.isEmpty())
2267 : {
2268 2869 : rHaveToken = true;
2269 2869 : ++rIndex;
2270 2869 : return token.makeStringAndClear();
2271 : }
2272 : }
2273 4751 : break;
2274 : default:
2275 59463 : token.append(currentChar);
2276 59463 : break;
2277 : }
2278 : }
2279 : assert(rIndex == rCommand.getLength());
2280 704 : if (bQuoted)
2281 : {
2282 : SAL_INFO("writerfilter.dmapper",
2283 : "field argument with unterminated quote");
2284 1 : return OUString();
2285 : }
2286 : else
2287 : {
2288 703 : rHaveToken = !token.isEmpty();
2289 703 : return token.makeStringAndClear();
2290 7339 : }
2291 : }
2292 :
2293 : boost::tuple<OUString, std::vector<OUString>, std::vector<OUString> >
2294 1987 : lcl_SplitFieldCommand(const OUString& rCommand)
2295 : {
2296 1987 : OUString sType;
2297 3974 : std::vector<OUString> arguments;
2298 3974 : std::vector<OUString> switches;
2299 1987 : sal_Int32 nStartIndex(0);
2300 :
2301 7339 : do
2302 : {
2303 : bool bHaveToken;
2304 : bool bIsSwitch;
2305 : OUString const token =
2306 7339 : lcl_ExtractToken(rCommand, nStartIndex, bHaveToken, bIsSwitch);
2307 : assert(nStartIndex <= rCommand.getLength());
2308 7339 : if (bHaveToken)
2309 : {
2310 6688 : if (sType.isEmpty())
2311 : {
2312 1987 : sType = token.toAsciiUpperCase();
2313 : }
2314 4701 : else if (bIsSwitch || !switches.empty())
2315 : {
2316 2509 : switches.push_back(token);
2317 : }
2318 : else
2319 : {
2320 2192 : arguments.push_back(token);
2321 : }
2322 7339 : }
2323 7339 : } while (nStartIndex < rCommand.getLength());
2324 :
2325 3974 : return boost::make_tuple(sType, arguments, switches);
2326 : }
2327 :
2328 :
2329 4 : OUString lcl_ExctractAskVariableAndHint( const OUString& rCommand, OUString& rHint )
2330 : {
2331 : // the first word after "ASK " is the variable
2332 : // the text after the variable and before a '\' is the hint
2333 : // if no hint is set the variable is used as hint
2334 : // the quotes of the hint have to be removed
2335 4 : sal_Int32 nIndex = rCommand.indexOf( ' ', 2); //find last space after 'ASK'
2336 4 : if (nIndex == -1)
2337 0 : return OUString();
2338 14 : while(rCommand[nIndex] == ' ')
2339 6 : ++nIndex;
2340 4 : OUString sShortCommand( rCommand.copy( nIndex ) ); //cut off the " ASK "
2341 :
2342 4 : nIndex = 0;
2343 4 : sShortCommand = sShortCommand.getToken( 0, '\\', nIndex);
2344 4 : nIndex = 0;
2345 8 : OUString sRet = sShortCommand.getToken( 0, ' ', nIndex);
2346 4 : if( nIndex > 0)
2347 4 : rHint = sShortCommand.copy( nIndex );
2348 4 : if( rHint.isEmpty() )
2349 0 : rHint = sRet;
2350 8 : return sRet;
2351 : }
2352 :
2353 :
2354 1097 : bool lcl_FindInCommand(
2355 : const OUString& rCommand,
2356 : sal_Unicode cSwitch,
2357 : OUString& rValue )
2358 : {
2359 1097 : bool bRet = false;
2360 1097 : OUString sSearch('\\');
2361 1097 : sSearch += OUString( cSwitch );
2362 1097 : sal_Int32 nIndex = rCommand.indexOf( sSearch );
2363 1097 : if( nIndex >= 0 )
2364 : {
2365 238 : bRet = true;
2366 : //find next '\' or end of string
2367 238 : sal_Int32 nEndIndex = rCommand.indexOf( '\\', nIndex + 1);
2368 238 : if( nEndIndex < 0 )
2369 59 : nEndIndex = rCommand.getLength() - 1;
2370 238 : if( nEndIndex - nIndex > 3 )
2371 79 : rValue = rCommand.copy( nIndex + 3, nEndIndex - nIndex - 3);
2372 : }
2373 1097 : return bRet;
2374 : }
2375 :
2376 :
2377 13 : void DomainMapper_Impl::GetCurrentLocale(lang::Locale& rLocale)
2378 : {
2379 13 : PropertyMapPtr pTopContext = GetTopContext();
2380 26 : boost::optional<PropertyMap::Property> pLocale = pTopContext->getProperty(PROP_CHAR_LOCALE);
2381 13 : if( pLocale )
2382 0 : pLocale->second >>= rLocale;
2383 : else
2384 : {
2385 13 : PropertyMapPtr pParaContext = GetTopContextOfType(CONTEXT_PARAGRAPH);
2386 13 : pLocale = pParaContext->getProperty(PROP_CHAR_LOCALE);
2387 13 : if( pLocale )
2388 : {
2389 1 : pLocale->second >>= rLocale;
2390 13 : }
2391 13 : }
2392 13 : }
2393 :
2394 : /*-------------------------------------------------------------------------
2395 : extract the number format from the command and apply the resulting number
2396 : format to the XPropertySet
2397 : -----------------------------------------------------------------------*/
2398 13 : void DomainMapper_Impl::SetNumberFormat( const OUString& rCommand,
2399 : uno::Reference< beans::XPropertySet > const& xPropertySet,
2400 : bool const bDetectFormat)
2401 : {
2402 13 : OUString sFormatString = lcl_ParseFormat( rCommand );
2403 : // find \h - hijri/luna calendar todo: what about saka/era calendar?
2404 13 : bool bHijri = 0 < rCommand.indexOf("\\h ");
2405 26 : lang::Locale aUSLocale;
2406 13 : aUSLocale.Language = "en";
2407 13 : aUSLocale.Country = "US";
2408 :
2409 : //determine current locale - todo: is it necessary to initialize this locale?
2410 26 : lang::Locale aCurrentLocale = aUSLocale;
2411 13 : GetCurrentLocale( aCurrentLocale );
2412 26 : OUString sFormat = ConversionHelper::ConvertMSFormatStringToSO( sFormatString, aCurrentLocale, bHijri);
2413 : //get the number formatter and convert the string to a format value
2414 : try
2415 : {
2416 13 : sal_Int32 nKey = 0;
2417 13 : uno::Reference< util::XNumberFormatsSupplier > xNumberSupplier( m_xTextDocument, uno::UNO_QUERY_THROW );
2418 13 : if( bDetectFormat )
2419 : {
2420 2 : uno::Reference< util::XNumberFormatter> xFormatter(util::NumberFormatter::create(m_xComponentContext), uno::UNO_QUERY_THROW);
2421 2 : xFormatter->attachNumberFormatsSupplier( xNumberSupplier );
2422 3 : nKey = xFormatter->detectNumberFormat( 0, rCommand );
2423 : }
2424 : else
2425 : {
2426 11 : nKey = xNumberSupplier->getNumberFormats()->addNewConverted( sFormat, aUSLocale, aCurrentLocale );
2427 : }
2428 12 : xPropertySet->setPropertyValue(
2429 12 : PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_NUMBER_FORMAT),
2430 24 : uno::makeAny( nKey ));
2431 12 : xPropertySet->getPropertyValue(
2432 12 : PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_NUMBER_FORMAT ) ) >>= nKey;
2433 : }
2434 1 : catch(const uno::Exception&)
2435 : {
2436 13 : }
2437 13 : }
2438 :
2439 18 : static uno::Any lcl_getGrabBagValue( const uno::Sequence<beans::PropertyValue>& grabBag, OUString const & name )
2440 : {
2441 93 : for (int i = 0; i < grabBag.getLength(); ++i)
2442 : {
2443 93 : if (grabBag[i].Name == name )
2444 18 : return grabBag[i].Value ;
2445 : }
2446 0 : return uno::Any();
2447 : }
2448 :
2449 : //Link the text frames.
2450 1984 : void DomainMapper_Impl::ChainTextFrames()
2451 : {
2452 1984 : if( 0 == m_vTextFramesForChaining.size() )
2453 3965 : return ;
2454 :
2455 : try
2456 : {
2457 3 : sal_Int32 nTxbxId1 = 0 ; //holds id for the shape in outer loop
2458 3 : sal_Int32 nTxbxId2 = 0 ; //holds id for the shape in inner loop
2459 3 : sal_Int32 nTxbxSeq1 = 0 ; //holds seq number for the shape in outer loop
2460 3 : sal_Int32 nTxbxSeq2 = 0 ; //holds seq number for the shape in inner loop
2461 3 : OUString sName1 ; //holds the text box Name for the shape in outer loop
2462 6 : OUString sName2 ; //holds the text box Name for the shape in outer loop
2463 6 : OUString sChainNextName("ChainNextName");
2464 6 : OUString sChainPrevName("ChainPrevName");
2465 :
2466 21 : for( std::vector<uno::Reference< drawing::XShape > >::iterator outer_itr = m_vTextFramesForChaining.begin();
2467 18 : outer_itr != m_vTextFramesForChaining.end(); )
2468 : {
2469 6 : bool bIsTxbxChained = false ;
2470 6 : uno::Reference<text::XTextContent> xTextContent1(*outer_itr, uno::UNO_QUERY_THROW);
2471 12 : uno::Reference<beans::XPropertySet> xPropertySet1(xTextContent1, uno::UNO_QUERY);
2472 12 : uno::Sequence<beans::PropertyValue> aGrabBag1;
2473 12 : uno::Reference<lang::XServiceInfo> xServiceInfo1(xPropertySet1, uno::UNO_QUERY);
2474 6 : if (xServiceInfo1->supportsService("com.sun.star.text.TextFrame"))
2475 : {
2476 0 : xPropertySet1->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag1;
2477 0 : xPropertySet1->getPropertyValue("LinkDisplayName") >>= sName1;
2478 : }
2479 : else
2480 : {
2481 6 : xPropertySet1->getPropertyValue("InteropGrabBag") >>= aGrabBag1;
2482 6 : xPropertySet1->getPropertyValue("ChainName") >>= sName1;
2483 : }
2484 :
2485 6 : lcl_getGrabBagValue( aGrabBag1, "Txbx-Id") >>= nTxbxId1;
2486 6 : lcl_getGrabBagValue( aGrabBag1, "Txbx-Seq") >>= nTxbxSeq1;
2487 :
2488 : //Check which text box in the document links/(is a link) to this one.
2489 6 : std::vector<uno::Reference< drawing::XShape > >::iterator inner_itr = ( outer_itr + 1 );
2490 6 : for( ; inner_itr != m_vTextFramesForChaining.end(); ++inner_itr )
2491 : {
2492 3 : uno::Reference<text::XTextContent> xTextContent2(*inner_itr, uno::UNO_QUERY_THROW);
2493 3 : uno::Reference<beans::XPropertySet> xPropertySet2(xTextContent2, uno::UNO_QUERY);
2494 3 : uno::Sequence<beans::PropertyValue> aGrabBag2;
2495 3 : uno::Reference<lang::XServiceInfo> xServiceInfo2(xPropertySet1, uno::UNO_QUERY);
2496 3 : if (xServiceInfo2->supportsService("com.sun.star.text.TextFrame"))
2497 : {
2498 0 : xPropertySet2->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag2;
2499 0 : xPropertySet2->getPropertyValue("LinkDisplayName") >>= sName2;
2500 : }
2501 : else
2502 : {
2503 3 : xPropertySet2->getPropertyValue("InteropGrabBag") >>= aGrabBag2;
2504 3 : xPropertySet2->getPropertyValue("ChainName") >>= sName2;
2505 : }
2506 :
2507 3 : lcl_getGrabBagValue( aGrabBag2, "Txbx-Id") >>= nTxbxId2;
2508 3 : lcl_getGrabBagValue( aGrabBag2, "Txbx-Seq") >>= nTxbxSeq2;
2509 :
2510 3 : if ( nTxbxId1 == nTxbxId2 )
2511 : {
2512 : //who connects whom ??
2513 3 : if ( nTxbxSeq1 == ( nTxbxSeq2 + 1 ) )
2514 : {
2515 2 : xPropertySet2->setPropertyValue(sChainNextName, uno::makeAny(sName1));
2516 2 : xPropertySet1->setPropertyValue(sChainPrevName, uno::makeAny(sName2));
2517 2 : bIsTxbxChained = true ;
2518 2 : break ; //there cannot be more than one previous/next frames
2519 : }
2520 1 : else if ( nTxbxSeq2 == ( nTxbxSeq1 + 1 ) )
2521 : {
2522 1 : xPropertySet1->setPropertyValue(sChainNextName, uno::makeAny(sName2));
2523 1 : xPropertySet2->setPropertyValue(sChainPrevName, uno::makeAny(sName1));
2524 1 : bIsTxbxChained = true ;
2525 1 : break ; //there cannot be more than one previous/next frames
2526 : }
2527 : }
2528 0 : }
2529 6 : if( bIsTxbxChained )
2530 : {
2531 : //This txt box is no longer needed for chaining since
2532 : //there cannot be more than one previous/next frames
2533 3 : outer_itr = m_vTextFramesForChaining.erase(outer_itr);
2534 : }
2535 : else
2536 3 : ++outer_itr ;
2537 6 : }
2538 6 : m_vTextFramesForChaining.clear(); //clear the vector
2539 : }
2540 0 : catch (const uno::Exception& rException)
2541 : {
2542 : SAL_WARN("writerfilter", "failed. message: " << rException.Message);
2543 : }
2544 : }
2545 :
2546 55 : uno::Reference<beans::XPropertySet> DomainMapper_Impl::FindOrCreateFieldMaster(const sal_Char* pFieldMasterService, const OUString& rFieldMasterName) throw(uno::Exception)
2547 : {
2548 : // query master, create if not available
2549 55 : uno::Reference< text::XTextFieldsSupplier > xFieldsSupplier( GetTextDocument(), uno::UNO_QUERY_THROW );
2550 110 : uno::Reference< container::XNameAccess > xFieldMasterAccess = xFieldsSupplier->getTextFieldMasters();
2551 55 : uno::Reference< beans::XPropertySet > xMaster;
2552 110 : OUString sFieldMasterService( OUString::createFromAscii(pFieldMasterService) );
2553 110 : OUStringBuffer aFieldMasterName;
2554 55 : aFieldMasterName.appendAscii( pFieldMasterService );
2555 55 : aFieldMasterName.append('.');
2556 55 : aFieldMasterName.append(rFieldMasterName);
2557 110 : OUString sFieldMasterName = aFieldMasterName.makeStringAndClear();
2558 55 : if(xFieldMasterAccess->hasByName(sFieldMasterName))
2559 : {
2560 : //get the master
2561 72 : xMaster = uno::Reference< beans::XPropertySet >(xFieldMasterAccess->getByName(sFieldMasterName),
2562 36 : uno::UNO_QUERY_THROW);
2563 : }
2564 : else
2565 : {
2566 : //create the master
2567 38 : xMaster = uno::Reference< beans::XPropertySet >(
2568 38 : m_xTextFactory->createInstance(sFieldMasterService), uno::UNO_QUERY_THROW);
2569 : //set the master's name
2570 19 : xMaster->setPropertyValue(
2571 19 : PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_NAME),
2572 38 : uno::makeAny(rFieldMasterName));
2573 : }
2574 110 : return xMaster;
2575 : }
2576 :
2577 2007 : void DomainMapper_Impl::PushFieldContext()
2578 : {
2579 2007 : m_bParaHadField = true;
2580 2007 : if(m_bDiscardHeaderFooter)
2581 2040 : return;
2582 : #ifdef DEBUG_WRITERFILTER
2583 : TagLogger::getInstance().element("pushFieldContext");
2584 : #endif
2585 :
2586 1974 : uno::Reference< text::XTextAppend > xTextAppend;
2587 1974 : if (!m_aTextAppendStack.empty())
2588 1974 : xTextAppend = m_aTextAppendStack.top().xTextAppend;
2589 3948 : uno::Reference< text::XTextRange > xStart;
2590 1974 : if (xTextAppend.is())
2591 : {
2592 1974 : uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange( xTextAppend->getEnd() );
2593 1974 : xStart = xCrsr->getStart();
2594 : }
2595 3948 : m_aFieldStack.push( FieldContextPtr( new FieldContext( xStart ) ) );
2596 : }
2597 : /*-------------------------------------------------------------------------
2598 : //the current field context waits for the completion of the command
2599 : -----------------------------------------------------------------------*/
2600 50894 : bool DomainMapper_Impl::IsOpenFieldCommand() const
2601 : {
2602 50894 : return !m_aFieldStack.empty() && !m_aFieldStack.top()->IsCommandCompleted();
2603 : }
2604 : /*-------------------------------------------------------------------------
2605 : //the current field context waits for the completion of the command
2606 : -----------------------------------------------------------------------*/
2607 48893 : bool DomainMapper_Impl::IsOpenField() const
2608 : {
2609 48893 : return !m_aFieldStack.empty();
2610 : }
2611 :
2612 : // Mark top field context as containing a fixed field
2613 12 : void DomainMapper_Impl::SetFieldLocked()
2614 : {
2615 12 : if (IsOpenField())
2616 12 : m_aFieldStack.top()->SetFieldLocked();
2617 12 : }
2618 :
2619 1337 : HeaderFooterContext::HeaderFooterContext(bool bTextInserted)
2620 1337 : : m_bTextInserted(bTextInserted)
2621 : {
2622 1337 : }
2623 :
2624 1337 : bool HeaderFooterContext::getTextInserted()
2625 : {
2626 1337 : return m_bTextInserted;
2627 : }
2628 :
2629 1974 : FieldContext::FieldContext(uno::Reference< text::XTextRange > const& xStart)
2630 : : m_bFieldCommandCompleted(false)
2631 : , m_xStartRange( xStart )
2632 1974 : , m_bFieldLocked( false )
2633 : {
2634 1974 : m_pProperties.reset(new PropertyMap());
2635 1974 : }
2636 :
2637 :
2638 1974 : FieldContext::~FieldContext()
2639 : {
2640 1974 : }
2641 :
2642 :
2643 2292 : void FieldContext::AppendCommand(const OUString& rPart)
2644 : {
2645 2292 : m_sCommand += rPart;
2646 2292 : }
2647 :
2648 777 : ::std::vector<OUString> FieldContext::GetCommandParts() const
2649 : {
2650 777 : ::std::vector<OUString> aResult;
2651 777 : sal_Int32 nIndex = 0;
2652 777 : bool bInString = false;
2653 1554 : OUString sPart;
2654 5028 : while (nIndex != -1)
2655 : {
2656 3474 : OUString sToken = GetCommand().getToken(0, ' ', nIndex);
2657 3474 : bool bInStringNext = bInString;
2658 :
2659 3474 : if (sToken.isEmpty())
2660 792 : continue;
2661 :
2662 2682 : if (sToken[0] == '"')
2663 : {
2664 1290 : bInStringNext = true;
2665 1290 : sToken = sToken.copy(1);
2666 : }
2667 2682 : if (sToken.endsWith("\""))
2668 : {
2669 1290 : bInStringNext = false;
2670 1290 : sToken = sToken.copy(0, sToken.getLength() - 1);
2671 : }
2672 :
2673 2682 : if (bInString)
2674 : {
2675 99 : sPart += OUString(' ');
2676 99 : sPart += sToken;
2677 99 : if (!bInStringNext)
2678 : {
2679 55 : aResult.push_back(sPart);
2680 : }
2681 : }
2682 : else
2683 : {
2684 2583 : if (bInStringNext)
2685 : {
2686 55 : sPart = sToken;
2687 : }
2688 : else
2689 : {
2690 2528 : aResult.push_back(sToken);
2691 : }
2692 : }
2693 :
2694 2682 : bInString = bInStringNext;
2695 2682 : }
2696 :
2697 1554 : return aResult;
2698 : }
2699 :
2700 : /*-------------------------------------------------------------------------
2701 : //collect the pieces of the command
2702 : -----------------------------------------------------------------------*/
2703 2292 : void DomainMapper_Impl::AppendFieldCommand(OUString& rPartOfCommand)
2704 : {
2705 : #ifdef DEBUG_WRITERFILTER
2706 : TagLogger::getInstance().startElement("appendFieldCommand");
2707 : TagLogger::getInstance().chars(rPartOfCommand);
2708 : TagLogger::getInstance().endElement();
2709 : #endif
2710 :
2711 2292 : FieldContextPtr pContext = m_aFieldStack.top();
2712 : OSL_ENSURE( pContext.get(), "no field context available");
2713 2292 : if( pContext.get() )
2714 : {
2715 2292 : pContext->AppendCommand( rPartOfCommand );
2716 2292 : }
2717 2292 : }
2718 :
2719 :
2720 : typedef std::multimap < sal_Int32, OUString > TOCStyleMap;
2721 :
2722 1974 : const FieldConversionMap_t & lcl_GetFieldConversion()
2723 : {
2724 1974 : static FieldConversionMap_t aFieldConversionMap;
2725 1974 : static FieldConversionMap_t aEnhancedFieldConversionMap;
2726 :
2727 : static bool bFilled = false;
2728 :
2729 1974 : if(!bFilled)
2730 : {
2731 : static const FieldConversion aFields[] =
2732 : {
2733 : // {OUString("ADDRESSBLOCK"), "", "", FIELD_ADDRESSBLOCK },
2734 : // {OUString("ADVANCE"), "", "", FIELD_ADVANCE },
2735 : {OUString("ASK"), "SetExpression", "SetExpression", FIELD_ASK },
2736 : {OUString("AUTONUM"), "SetExpression", "SetExpression", FIELD_AUTONUM },
2737 : {OUString("AUTONUMLGL"), "SetExpression", "SetExpression", FIELD_AUTONUMLGL },
2738 : {OUString("AUTONUMOUT"), "SetExpression", "SetExpression", FIELD_AUTONUMOUT },
2739 : {OUString("AUTHOR"), "DocInfo.CreateAuthor", "", FIELD_AUTHOR },
2740 : {OUString("DATE"), "DateTime", "", FIELD_DATE },
2741 : {OUString("COMMENTS"), "DocInfo.Description", "", FIELD_COMMENTS },
2742 : {OUString("CREATEDATE"), "DocInfo.CreateDateTime", "", FIELD_CREATEDATE },
2743 : {OUString("DOCPROPERTY"), "", "", FIELD_DOCPROPERTY },
2744 : {OUString("DOCVARIABLE"), "User", "", FIELD_DOCVARIABLE },
2745 : {OUString("EDITTIME"), "DocInfo.EditTime", "", FIELD_EDITTIME },
2746 : {OUString("EQ"), "", "", FIELD_EQ },
2747 : {OUString("FILLIN"), "Input", "", FIELD_FILLIN },
2748 : {OUString("FILENAME"), "FileName", "", FIELD_FILENAME },
2749 : // {OUString("FILESIZE"), "", "", FIELD_FILESIZE },
2750 : // {OUString("FORMULA"), "", "", FIELD_FORMULA },
2751 : {OUString("FORMCHECKBOX"), "", "", FIELD_FORMCHECKBOX},
2752 : {OUString("FORMDROPDOWN"), "DropDown", "", FIELD_FORMDROPDOWN},
2753 : {OUString("FORMTEXT"), "Input", "", FIELD_FORMTEXT},
2754 : // {OUString("GOTOBUTTON"), "", "", FIELD_GOTOBUTTON },
2755 : {OUString("HYPERLINK"), "", "", FIELD_HYPERLINK },
2756 : {OUString("IF"), "ConditionalText", "", FIELD_IF },
2757 : // {OUString("INFO"), "","", FIELD_INFO },
2758 : // {OUString("INCLUDEPICTURE"), "", "", FIELD_INCLUDEPICTURE},
2759 : {OUString("KEYWORDS"), "DocInfo.KeyWords", "", FIELD_KEYWORDS },
2760 : {OUString("LASTSAVEDBY"), "DocInfo.ChangeAuthor", "", FIELD_LASTSAVEDBY },
2761 : {OUString("MACROBUTTON"), "Macro", "", FIELD_MACROBUTTON },
2762 : {OUString("MERGEFIELD"), "Database", "Database", FIELD_MERGEFIELD},
2763 : {OUString("MERGEREC"), "DatabaseNumberOfSet", "", FIELD_MERGEREC },
2764 : // {OUString("MERGESEQ"), "", "", FIELD_MERGESEQ },
2765 : {OUString("NEXT"), "DatabaseNextSet", "", FIELD_NEXT },
2766 : {OUString("NEXTIF"), "DatabaseNextSet", "", FIELD_NEXTIF },
2767 : {OUString("PAGE"), "PageNumber", "", FIELD_PAGE },
2768 : {OUString("PAGEREF"), "GetReference", "", FIELD_PAGEREF },
2769 : {OUString("REF"), "GetReference", "", FIELD_REF },
2770 : {OUString("REVNUM"), "DocInfo.Revision", "", FIELD_REVNUM },
2771 : {OUString("SAVEDATE"), "DocInfo.Change", "", FIELD_SAVEDATE },
2772 : // {OUString("SECTION"), "", "", FIELD_SECTION },
2773 : // {OUString("SECTIONPAGES"), "", "", FIELD_SECTIONPAGES },
2774 : {OUString("SEQ"), "SetExpression", "SetExpression", FIELD_SEQ },
2775 : // {OUString("SET"), "","", FIELD_SET },
2776 : // {OUString("SKIPIF"),"", "", FIELD_SKIPIF },
2777 : // {OUString("STYLEREF"),"", "", FIELD_STYLEREF },
2778 : {OUString("SUBJECT"), "DocInfo.Subject", "", FIELD_SUBJECT },
2779 : // {OUString("SYMBOL"),"", "", FIELD_SYMBOL },
2780 : {OUString("TEMPLATE"), "TemplateName", "", FIELD_TEMPLATE},
2781 : {OUString("TIME"), "DateTime", "", FIELD_TIME },
2782 : {OUString("TITLE"), "DocInfo.Title", "", FIELD_TITLE },
2783 : {OUString("USERINITIALS"), "Author", "", FIELD_USERINITIALS },
2784 : // {OUString("USERADDRESS"), "", "", FIELD_USERADDRESS },
2785 : {OUString("USERNAME"), "Author", "", FIELD_USERNAME },
2786 :
2787 :
2788 : {OUString("TOC"), "com.sun.star.text.ContentIndex", "", FIELD_TOC},
2789 : {OUString("TC"), "com.sun.star.text.ContentIndexMark", "", FIELD_TC},
2790 : {OUString("NUMCHARS"), "CharacterCount", "", FIELD_NUMCHARS},
2791 : {OUString("NUMWORDS"), "WordCount", "", FIELD_NUMWORDS},
2792 : {OUString("NUMPAGES"), "PageCount", "", FIELD_NUMPAGES},
2793 : {OUString("INDEX"), "com.sun.star.text.DocumentIndex", "", FIELD_INDEX},
2794 : {OUString("XE"), "com.sun.star.text.DocumentIndexMark", "", FIELD_XE},
2795 : {OUString("BIBLIOGRAPHY"), "com.sun.star.text.Bibliography", "", FIELD_BIBLIOGRAPHY},
2796 : {OUString("CITATION"), "com.sun.star.text.TextField.Bibliography", "", FIELD_CITATION},
2797 :
2798 : // {OUString(""), "", "", FIELD_},
2799 :
2800 30 : };
2801 15 : size_t nConversions = SAL_N_ELEMENTS(aFields);
2802 720 : for( size_t nConversion = 0; nConversion < nConversions; ++nConversion)
2803 : {
2804 : aFieldConversionMap.insert( FieldConversionMap_t::value_type(
2805 : aFields[nConversion].sWordCommand,
2806 705 : aFields[nConversion] ));
2807 : }
2808 :
2809 15 : bFilled = true;
2810 : }
2811 :
2812 1974 : return aFieldConversionMap;
2813 : }
2814 :
2815 32 : const FieldConversionMap_t & lcl_GetEnhancedFieldConversion()
2816 : {
2817 32 : static FieldConversionMap_t aEnhancedFieldConversionMap;
2818 :
2819 : static bool bFilled = false;
2820 :
2821 32 : if(!bFilled)
2822 : {
2823 : static const FieldConversion aEnhancedFields[] =
2824 : {
2825 : {OUString("FORMCHECKBOX"), "FormFieldmark", "", FIELD_FORMCHECKBOX},
2826 : {OUString("FORMDROPDOWN"), "FormFieldmark", "", FIELD_FORMDROPDOWN},
2827 : {OUString("FORMTEXT"), "Fieldmark", "", FIELD_FORMTEXT},
2828 36 : };
2829 :
2830 32 : size_t nConversions = SAL_N_ELEMENTS(aEnhancedFields);
2831 128 : for( size_t nConversion = 0; nConversion < nConversions; ++nConversion)
2832 : {
2833 : aEnhancedFieldConversionMap.insert( FieldConversionMap_t::value_type(
2834 : aEnhancedFields[nConversion].sWordCommand,
2835 96 : aEnhancedFields[nConversion] ));
2836 : }
2837 : }
2838 32 : return aEnhancedFieldConversionMap;
2839 : }
2840 :
2841 4 : void DomainMapper_Impl::handleFieldAsk
2842 : (FieldContextPtr pContext,
2843 : PropertyNameSupplier& rPropNameSupplier,
2844 : uno::Reference< uno::XInterface > & xFieldInterface,
2845 : uno::Reference< beans::XPropertySet > const& xFieldProperties)
2846 : {
2847 : //doesn the command contain a variable name?
2848 8 : OUString sVariable, sHint;
2849 :
2850 8 : sVariable = lcl_ExctractAskVariableAndHint( pContext->GetCommand(),
2851 4 : sHint );
2852 4 : if(!sVariable.isEmpty())
2853 : {
2854 : // determine field master name
2855 : uno::Reference< beans::XPropertySet > xMaster =
2856 : FindOrCreateFieldMaster
2857 4 : ("com.sun.star.text.FieldMaster.SetExpression", sVariable );
2858 : // An ASK field is always a string of characters
2859 4 : xMaster->setPropertyValue(rPropNameSupplier.GetName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING));
2860 :
2861 : // attach the master to the field
2862 : uno::Reference< text::XDependentTextField > xDependentField
2863 8 : ( xFieldInterface, uno::UNO_QUERY_THROW );
2864 4 : xDependentField->attachTextFieldMaster( xMaster );
2865 :
2866 : // set input flag at the field
2867 4 : xFieldProperties->setPropertyValue(
2868 4 : rPropNameSupplier.GetName(PROP_IS_INPUT), uno::makeAny( true ));
2869 : // set the prompt
2870 4 : xFieldProperties->setPropertyValue(
2871 : rPropNameSupplier.GetName(PROP_HINT),
2872 4 : uno::makeAny( sHint ));
2873 4 : xFieldProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING));
2874 : // The ASK has no field value to display
2875 8 : xFieldProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_IS_VISIBLE), uno::makeAny(sal_False));
2876 : }
2877 : else
2878 : {
2879 : //don't insert the field
2880 : //todo: maybe import a 'normal' input field here?
2881 0 : xFieldInterface = nullptr;
2882 4 : }
2883 4 : }
2884 :
2885 0 : void DomainMapper_Impl::handleAutoNum
2886 : (FieldContextPtr pContext,
2887 : PropertyNameSupplier& rPropNameSupplier,
2888 : uno::Reference< uno::XInterface > & xFieldInterface,
2889 : uno::Reference< beans::XPropertySet > const& xFieldProperties)
2890 : {
2891 : //create a sequence field master "AutoNr"
2892 : uno::Reference< beans::XPropertySet > xMaster =
2893 : FindOrCreateFieldMaster
2894 : ("com.sun.star.text.FieldMaster.SetExpression",
2895 0 : "AutoNr");
2896 :
2897 0 : xMaster->setPropertyValue( rPropNameSupplier.GetName(PROP_SUB_TYPE),
2898 0 : uno::makeAny(text::SetVariableType::SEQUENCE));
2899 :
2900 : //apply the numbering type
2901 0 : xFieldProperties->setPropertyValue(
2902 : rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
2903 0 : uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) ));
2904 : // attach the master to the field
2905 : uno::Reference< text::XDependentTextField > xDependentField
2906 0 : ( xFieldInterface, uno::UNO_QUERY_THROW );
2907 0 : xDependentField->attachTextFieldMaster( xMaster );
2908 0 : }
2909 :
2910 1 : void DomainMapper_Impl::handleAuthor
2911 : (OUString const& rFirstParam,
2912 : PropertyNameSupplier& rPropNameSupplier,
2913 : uno::Reference< uno::XInterface > & /*xFieldInterface*/,
2914 : uno::Reference< beans::XPropertySet > const& xFieldProperties,
2915 : FieldId eFieldId )
2916 : {
2917 1 : if ( eFieldId != FIELD_USERINITIALS )
2918 1 : xFieldProperties->setPropertyValue
2919 1 : ( rPropNameSupplier.GetName(PROP_FULL_NAME), uno::makeAny( true ));
2920 :
2921 1 : if (!rFirstParam.isEmpty())
2922 : {
2923 0 : xFieldProperties->setPropertyValue(
2924 : rPropNameSupplier.GetName( PROP_IS_FIXED ),
2925 0 : uno::makeAny( true ));
2926 : //PROP_CURRENT_PRESENTATION is set later anyway
2927 : }
2928 1 : }
2929 :
2930 2 : void DomainMapper_Impl::handleDocProperty
2931 : (FieldContextPtr pContext,
2932 : OUString const& rFirstParam,
2933 : PropertyNameSupplier& rPropNameSupplier,
2934 : uno::Reference< uno::XInterface > & xFieldInterface,
2935 : uno::Reference< beans::XPropertySet > const&)
2936 : {
2937 : //some docproperties should be imported as document statistic fields, some as DocInfo fields
2938 : //others should be user fields
2939 2 : if (!rFirstParam.isEmpty())
2940 : {
2941 : #define SET_ARABIC 0x01
2942 : #define SET_FULL_NAME 0x02
2943 : #define SET_DATE 0x04
2944 : struct DocPropertyMap
2945 : {
2946 : const sal_Char* pDocPropertyName;
2947 : const sal_Char* pServiceName;
2948 : sal_uInt8 nFlags;
2949 : };
2950 : static const DocPropertyMap aDocProperties[] =
2951 : {
2952 : {"CreateTime", "DocInfo.CreateDateTime", SET_DATE},
2953 : {"Characters", "CharacterCount", SET_ARABIC},
2954 : {"Comments", "DocInfo.Description", 0},
2955 : {"Keywords", "DocInfo.KeyWords", 0},
2956 : {"LastPrinted", "DocInfo.PrintDateTime", 0},
2957 : {"LastSavedBy", "DocInfo.ChangeAuthor", 0},
2958 : {"LastSavedTime", "DocInfo.ChangeDateTime", SET_DATE},
2959 : {"Paragraphs", "ParagraphCount", SET_ARABIC},
2960 : {"RevisionNumber", "DocInfo.Revision", 0},
2961 : {"Subject", "DocInfo.Subject", 0},
2962 : {"Template", "TemplateName", 0},
2963 : {"Title", "DocInfo.Title", 0},
2964 : {"TotalEditingTime", "DocInfo.EditTime", 0},
2965 : {"Words", "WordCount", SET_ARABIC}
2966 :
2967 : //other available DocProperties:
2968 : //Bytes, Category, CharactersWithSpaces, Company
2969 : //HyperlinkBase,
2970 : //Lines, Manager, NameofApplication, ODMADocId, Pages,
2971 : //Security,
2972 : };
2973 2 : uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(m_xTextDocument, uno::UNO_QUERY);
2974 4 : uno::Reference<document::XDocumentProperties> xDocumentProperties = xDocumentPropertiesSupplier->getDocumentProperties();
2975 4 : const uno::Reference< beans::XPropertyContainer > xUserProps = xDocumentProperties->getUserDefinedProperties();
2976 4 : uno::Reference<beans::XPropertySet> xUserDefinedProps(xDocumentProperties->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
2977 4 : uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xUserDefinedProps->getPropertySetInfo();
2978 : //search for a field mapping
2979 4 : OUString sFieldServiceName;
2980 2 : sal_uInt16 nMap = 0;
2981 30 : for( ; nMap < sizeof(aDocProperties) / sizeof(DocPropertyMap);
2982 : ++nMap )
2983 : {
2984 28 : if ((rFirstParam.equalsAscii(aDocProperties[nMap].pDocPropertyName)) && (!xPropertySetInfo->hasPropertyByName(rFirstParam)))
2985 : {
2986 0 : sFieldServiceName =
2987 : OUString::createFromAscii
2988 0 : (aDocProperties[nMap].pServiceName);
2989 0 : break;
2990 : }
2991 : }
2992 4 : OUString sServiceName("com.sun.star.text.TextField.");
2993 2 : bool bIsCustomField = false;
2994 2 : if(sFieldServiceName.isEmpty())
2995 : {
2996 : //create a custom property field
2997 2 : sServiceName += "DocInfo.Custom";
2998 2 : bIsCustomField = true;
2999 : }
3000 : else
3001 : {
3002 0 : sServiceName += sFieldServiceName;
3003 : }
3004 2 : if (m_xTextFactory.is())
3005 2 : xFieldInterface = m_xTextFactory->createInstance(sServiceName);
3006 : uno::Reference<beans::XPropertySet> xFieldProperties =
3007 : uno::Reference< beans::XPropertySet >( xFieldInterface,
3008 4 : uno::UNO_QUERY_THROW);
3009 2 : if( bIsCustomField )
3010 : {
3011 2 : xFieldProperties->setPropertyValue(
3012 2 : rPropNameSupplier.GetName(PROP_NAME), uno::makeAny(rFirstParam));
3013 2 : pContext->SetCustomField( xFieldProperties );
3014 : }
3015 : else
3016 : {
3017 0 : if(0 != (aDocProperties[nMap].nFlags & SET_ARABIC))
3018 0 : xFieldProperties->setPropertyValue(
3019 : rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
3020 0 : uno::makeAny( style::NumberingType::ARABIC ));
3021 0 : else if(0 != (aDocProperties[nMap].nFlags & SET_FULL_NAME))
3022 0 : xFieldProperties->setPropertyValue(
3023 : rPropNameSupplier.GetName(PROP_FULL_NAME),
3024 0 : uno::makeAny( true ));
3025 0 : else if(0 != (aDocProperties[nMap].nFlags & SET_DATE))
3026 : {
3027 0 : xFieldProperties->setPropertyValue(
3028 : rPropNameSupplier.GetName(PROP_IS_DATE),
3029 0 : uno::makeAny( true ));
3030 0 : SetNumberFormat( pContext->GetCommand(), xFieldProperties );
3031 : }
3032 2 : }
3033 : }
3034 :
3035 : #undef SET_ARABIC
3036 : #undef SET_FULL_NAME
3037 : #undef SET_DATE
3038 2 : }
3039 :
3040 492 : uno::Sequence< beans::PropertyValues > lcl_createTOXLevelHyperlinks( bool bHyperlinks, const OUString& sChapterNoSeparator,
3041 : const uno::Sequence< beans::PropertyValues >& aLevel,
3042 : PropertyNameSupplier& rPropNameSupplier )
3043 : {
3044 : //create a copy of the level and add two new entries - hyperlink start and end
3045 492 : bool bChapterNoSeparator = !sChapterNoSeparator.isEmpty();
3046 492 : sal_Int32 nAdd = (bHyperlinks && bChapterNoSeparator) ? 4 : 2;
3047 492 : uno::Sequence< beans::PropertyValues > aNewLevel( aLevel.getLength() + nAdd);
3048 492 : beans::PropertyValues* pNewLevel = aNewLevel.getArray();
3049 492 : if( bHyperlinks )
3050 : {
3051 492 : beans::PropertyValues aHyperlink(1);
3052 492 : aHyperlink[0].Name = rPropNameSupplier.GetName( PROP_TOKEN_TYPE );
3053 492 : aHyperlink[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_HYPERLINK_START );
3054 492 : pNewLevel[0] = aHyperlink;
3055 492 : aHyperlink[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_HYPERLINK_END );
3056 492 : pNewLevel[aNewLevel.getLength() -1] = aHyperlink;
3057 : }
3058 492 : if( bChapterNoSeparator )
3059 : {
3060 0 : beans::PropertyValues aChapterNo(2);
3061 0 : aChapterNo[0].Name = rPropNameSupplier.GetName( PROP_TOKEN_TYPE );
3062 0 : aChapterNo[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_CHAPTER_INFO );
3063 0 : aChapterNo[1].Name = rPropNameSupplier.GetName( PROP_CHAPTER_FORMAT );
3064 : //todo: is ChapterFormat::Number correct?
3065 0 : aChapterNo[1].Value <<= (sal_Int16)text::ChapterFormat::NUMBER;
3066 0 : pNewLevel[aNewLevel.getLength() - (bHyperlinks ? 4 : 2) ] = aChapterNo;
3067 :
3068 0 : beans::PropertyValues aChapterSeparator(2);
3069 0 : aChapterSeparator[0].Name = rPropNameSupplier.GetName( PROP_TOKEN_TYPE );
3070 0 : aChapterSeparator[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_TEXT );
3071 0 : aChapterSeparator[1].Name = rPropNameSupplier.GetName( PROP_TEXT );
3072 0 : aChapterSeparator[1].Value <<= sChapterNoSeparator;
3073 0 : pNewLevel[aNewLevel.getLength() - (bHyperlinks ? 3 : 1)] = aChapterSeparator;
3074 : }
3075 : //copy the 'old' entries except the last (page no)
3076 2950 : for( sal_Int32 nToken = 0; nToken < aLevel.getLength() - 1; ++nToken)
3077 : {
3078 2458 : pNewLevel[nToken + 1] = aLevel[nToken];
3079 : }
3080 : //copy page no entry (last or last but one depending on bHyperlinks
3081 492 : sal_Int32 nPageNo = aNewLevel.getLength() - (bHyperlinks ? 2 : 3);
3082 492 : pNewLevel[nPageNo] = aLevel[aLevel.getLength() - 1];
3083 :
3084 492 : return aNewLevel;
3085 : }
3086 :
3087 59 : void DomainMapper_Impl::handleToc
3088 : (FieldContextPtr pContext,
3089 : PropertyNameSupplier& rPropNameSupplier,
3090 : uno::Reference< uno::XInterface > & /*xFieldInterface*/,
3091 : uno::Reference< beans::XPropertySet > const& /*xFieldProperties*/,
3092 : const OUString & sTOCServiceName)
3093 : {
3094 59 : OUString sValue;
3095 59 : m_bStartTOC = true;
3096 59 : if(m_bInHeaderFooterImport)
3097 0 : m_bStartTOCHeaderFooter = true;
3098 59 : bool bTableOfFigures = false;
3099 59 : bool bHyperlinks = false;
3100 59 : bool bFromOutline = false;
3101 59 : bool bFromEntries = false;
3102 59 : bool bHideTabLeaderPageNumbers = false ;
3103 59 : bool bIsTabEntry = false ;
3104 59 : bool bNewLine = false ;
3105 59 : bool bParagraphOutlineLevel = false;
3106 :
3107 59 : sal_Int16 nMaxLevel = 10;
3108 118 : OUString sTemplate;
3109 118 : OUString sChapterNoSeparator;
3110 118 : OUString sFigureSequence;
3111 118 : uno::Reference< beans::XPropertySet > xTOC;
3112 118 : OUString aBookmarkName;
3113 :
3114 : // \a Builds a table of figures but does not include the captions's label and number
3115 59 : if( lcl_FindInCommand( pContext->GetCommand(), 'a', sValue ))
3116 : { //make it a table of figures
3117 0 : bTableOfFigures = true;
3118 : }
3119 : // \b Uses a bookmark to specify area of document from which to build table of contents
3120 59 : if( lcl_FindInCommand( pContext->GetCommand(), 'b', sValue ))
3121 : {
3122 3 : aBookmarkName = sValue;
3123 : }
3124 59 : if( lcl_FindInCommand( pContext->GetCommand(), 'c', sValue ))
3125 : // \c Builds a table of figures of the given label
3126 : {
3127 : //todo: sValue contains the label's name
3128 6 : bTableOfFigures = true;
3129 6 : sFigureSequence = sValue.trim();
3130 6 : sFigureSequence = sFigureSequence.replaceAll("\"", "").replaceAll("'","");
3131 : }
3132 : // \d Defines the separator between sequence and page numbers
3133 59 : if( lcl_FindInCommand( pContext->GetCommand(), 'd', sValue ))
3134 : {
3135 : //todo: insert the chapter number into each level and insert the separator additionally
3136 0 : sChapterNoSeparator = sValue;
3137 : }
3138 : // \f Builds a table of contents using TC entries instead of outline levels
3139 59 : if( lcl_FindInCommand( pContext->GetCommand(), 'f', sValue ))
3140 : {
3141 : //todo: sValue can contain a TOC entry identifier - use unclear
3142 15 : bFromEntries = true;
3143 : }
3144 : // \h Hyperlinks the entries and page numbers within the table of contents
3145 59 : if( lcl_FindInCommand( pContext->GetCommand(), 'h', sValue ))
3146 : {
3147 : //todo: make all entries to hyperlinks
3148 51 : bHyperlinks = true;
3149 : }
3150 : // \l Defines the TC entries field level used to build a table of contents
3151 : // if( lcl_FindInCommand( pContext->GetCommand(), 'l', sValue ))
3152 : // {
3153 : //todo: entries can only be included completely
3154 : // }
3155 : // \n Builds a table of contents or a range of entries, such as 1-9 in a table of contents without page numbers
3156 : // if( lcl_FindInCommand( pContext->GetCommand(), 'n', sValue ))
3157 : // {
3158 : //todo: what does the description mean?
3159 : // }
3160 : // \o Builds a table of contents by using outline levels instead of TC entries
3161 59 : if( lcl_FindInCommand( pContext->GetCommand(), 'o', sValue ))
3162 : {
3163 50 : bFromOutline = true;
3164 50 : if (sValue.isEmpty())
3165 2 : nMaxLevel = WW_OUTLINE_MAX;
3166 : else
3167 : {
3168 48 : sal_Int32 nIndex = 0;
3169 48 : sValue.getToken( 0, '-', nIndex );
3170 48 : nMaxLevel = static_cast<sal_Int16>(nIndex != -1 ? sValue.copy(nIndex).toInt32() : 0);
3171 : }
3172 : }
3173 : // \p Defines the separator between the table entry and its page number
3174 59 : if( lcl_FindInCommand( pContext->GetCommand(), 'p', sValue ))
3175 : { }
3176 : // \s Builds a table of contents by using a sequence type
3177 59 : if( lcl_FindInCommand( pContext->GetCommand(), 's', sValue ))
3178 : { }
3179 : // \t Builds a table of contents by using style names other than the standard outline styles
3180 59 : if( lcl_FindInCommand( pContext->GetCommand(), 't', sValue ))
3181 : {
3182 4 : sal_Int32 nPos = 0;
3183 4 : OUString sToken = sValue.getToken( 1, '"', nPos);
3184 4 : sTemplate = sToken.isEmpty() ? sValue : sToken;
3185 : }
3186 : // \u Builds a table of contents by using the applied paragraph outline level
3187 59 : if( lcl_FindInCommand( pContext->GetCommand(), 'u', sValue ))
3188 : {
3189 37 : bFromOutline = true;
3190 37 : bParagraphOutlineLevel = true;
3191 : //todo: what doesn 'the applied paragraph outline level' refer to?
3192 : }
3193 : // \w Preserve tab characters within table entries
3194 59 : if( lcl_FindInCommand( pContext->GetCommand(), 'w', sValue ))
3195 : {
3196 3 : bIsTabEntry = true ;
3197 : }
3198 : // \x Preserve newline characters within table entries
3199 59 : if( lcl_FindInCommand( pContext->GetCommand(), 'x', sValue ))
3200 : {
3201 3 : bNewLine = true ;
3202 : }
3203 : // \z Hides page numbers within the table of contens when shown in Web Layout View
3204 59 : if( lcl_FindInCommand( pContext->GetCommand(), 'z', sValue ))
3205 : {
3206 45 : bHideTabLeaderPageNumbers = true ;
3207 : }
3208 :
3209 : //if there's no option then it should be created from outline
3210 59 : if( !bFromOutline && !bFromEntries && sTemplate.isEmpty() )
3211 6 : bFromOutline = true;
3212 :
3213 :
3214 59 : if (m_xTextFactory.is())
3215 : xTOC.set(
3216 59 : m_xTextFactory->createInstance
3217 : ( bTableOfFigures ?
3218 : "com.sun.star.text.IllustrationsIndex"
3219 59 : : sTOCServiceName),
3220 59 : uno::UNO_QUERY_THROW);
3221 59 : if (xTOC.is())
3222 59 : xTOC->setPropertyValue(rPropNameSupplier.GetName( PROP_TITLE ), uno::makeAny(OUString()));
3223 59 : if (!aBookmarkName.isEmpty())
3224 3 : xTOC->setPropertyValue(rPropNameSupplier.GetName(PROP_TOC_BOOKMARK), uno::makeAny(aBookmarkName));
3225 59 : if( !bTableOfFigures && xTOC.is() )
3226 : {
3227 53 : xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_LEVEL ), uno::makeAny( nMaxLevel ) );
3228 53 : xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_CREATE_FROM_OUTLINE ), uno::makeAny( bFromOutline ));
3229 53 : xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_CREATE_FROM_MARKS ), uno::makeAny( bFromEntries ));
3230 53 : xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_HIDE_TAB_LEADER_AND_PAGE_NUMBERS ), uno::makeAny( bHideTabLeaderPageNumbers ));
3231 53 : xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_TAB_IN_TOC ), uno::makeAny( bIsTabEntry ));
3232 53 : xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_TOC_NEW_LINE ), uno::makeAny( bNewLine ));
3233 53 : xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_TOC_PARAGRAPH_OUTLINE_LEVEL ), uno::makeAny( bParagraphOutlineLevel ));
3234 53 : if( !sTemplate.isEmpty() )
3235 : {
3236 : //the string contains comma separated the names and related levels
3237 : //like: "Heading 1,1,Heading 2,2"
3238 2 : TOCStyleMap aMap;
3239 : sal_Int32 nLevel;
3240 2 : sal_Int32 nPosition = 0;
3241 29 : while( nPosition >= 0)
3242 : {
3243 25 : OUString sStyleName = sTemplate.getToken( 0, ',', nPosition );
3244 : //empty tokens should be skipped
3245 50 : while( sStyleName.isEmpty() && nPosition > 0 )
3246 0 : sStyleName = sTemplate.getToken( 0, ',', nPosition );
3247 25 : nLevel = sTemplate.getToken( 0, ',', nPosition ).toInt32();
3248 25 : if( !nLevel )
3249 0 : nLevel = 1;
3250 25 : if( !sStyleName.isEmpty() )
3251 25 : aMap.insert( TOCStyleMap::value_type(nLevel, sStyleName) );
3252 25 : }
3253 4 : uno::Reference< container::XIndexReplace> xParaStyles;
3254 2 : xTOC->getPropertyValue(rPropNameSupplier.GetName(PROP_LEVEL_PARAGRAPH_STYLES)) >>= xParaStyles;
3255 20 : for( nLevel = 1; nLevel < 10; ++nLevel)
3256 : {
3257 18 : sal_Int32 nLevelCount = aMap.count( nLevel );
3258 18 : if( nLevelCount )
3259 : {
3260 2 : TOCStyleMap::iterator aTOCStyleIter = aMap.find( nLevel );
3261 :
3262 2 : uno::Sequence< OUString> aStyles( nLevelCount );
3263 27 : for ( sal_Int32 nStyle = 0; nStyle < nLevelCount; ++nStyle, ++aTOCStyleIter )
3264 : {
3265 25 : aStyles[nStyle] = aTOCStyleIter->second;
3266 : }
3267 2 : xParaStyles->replaceByIndex(nLevel - 1, uno::makeAny(aStyles));
3268 : }
3269 : }
3270 4 : xTOC->setPropertyValue(rPropNameSupplier.GetName(PROP_CREATE_FROM_LEVEL_PARAGRAPH_STYLES), uno::makeAny( true ));
3271 :
3272 : }
3273 53 : if(bHyperlinks || !sChapterNoSeparator.isEmpty())
3274 : {
3275 49 : uno::Reference< container::XIndexReplace> xLevelFormats;
3276 49 : xTOC->getPropertyValue(rPropNameSupplier.GetName(PROP_LEVEL_FORMAT)) >>= xLevelFormats;
3277 49 : sal_Int32 nLevelCount = xLevelFormats->getCount();
3278 : //start with level 1, 0 is the header level
3279 539 : for( sal_Int32 nLevel = 1; nLevel < nLevelCount; ++nLevel)
3280 : {
3281 490 : uno::Sequence< beans::PropertyValues > aLevel;
3282 490 : xLevelFormats->getByIndex( nLevel ) >>= aLevel;
3283 :
3284 : uno::Sequence< beans::PropertyValues > aNewLevel = lcl_createTOXLevelHyperlinks(
3285 : bHyperlinks, sChapterNoSeparator,
3286 980 : aLevel, rPropNameSupplier );
3287 490 : xLevelFormats->replaceByIndex( nLevel, uno::makeAny( aNewLevel ) );
3288 539 : }
3289 : }
3290 : }
3291 6 : else if (bTableOfFigures && xTOC.is())
3292 : {
3293 6 : if (!sFigureSequence.isEmpty())
3294 3 : xTOC->setPropertyValue(rPropNameSupplier.GetName(PROP_LABEL_CATEGORY),
3295 3 : uno::makeAny(sFigureSequence));
3296 :
3297 6 : if ( bHyperlinks )
3298 : {
3299 2 : uno::Reference< container::XIndexReplace> xLevelFormats;
3300 2 : xTOC->getPropertyValue(rPropNameSupplier.GetName(PROP_LEVEL_FORMAT)) >>= xLevelFormats;
3301 4 : uno::Sequence< beans::PropertyValues > aLevel;
3302 2 : xLevelFormats->getByIndex( 1 ) >>= aLevel;
3303 :
3304 : uno::Sequence< beans::PropertyValues > aNewLevel = lcl_createTOXLevelHyperlinks(
3305 : bHyperlinks, sChapterNoSeparator,
3306 4 : aLevel, rPropNameSupplier );
3307 4 : xLevelFormats->replaceByIndex( 1, uno::makeAny( aNewLevel ) );
3308 : }
3309 : }
3310 59 : pContext->SetTOC( xTOC );
3311 59 : m_bParaHadField = false;
3312 :
3313 118 : OUString sMarker("Y");
3314 : //insert index
3315 118 : uno::Reference< text::XTextContent > xToInsert( xTOC, uno::UNO_QUERY );
3316 118 : uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
3317 59 : if (xTextAppend.is())
3318 : {
3319 59 : uno::Reference< text::XTextCursor > xCrsr = xTextAppend->getText()->createTextCursor();
3320 :
3321 118 : uno::Reference< text::XText > xText = xTextAppend->getText();
3322 59 : if(xCrsr.is() && xText.is())
3323 : {
3324 59 : xCrsr->gotoEnd(false);
3325 59 : xText->insertString(xCrsr, sMarker, sal_False);
3326 59 : xText->insertTextContent(uno::Reference< text::XTextRange >( xCrsr, uno::UNO_QUERY_THROW ), xToInsert, sal_False);
3327 59 : xTOCMarkerCursor = xCrsr;
3328 59 : }
3329 59 : }
3330 59 : }
3331 :
3332 15 : void DomainMapper_Impl::handleBibliography
3333 : (FieldContextPtr pContext,
3334 : PropertyNameSupplier& rPropNameSupplier,
3335 : const OUString & sTOCServiceName)
3336 : {
3337 15 : uno::Reference< beans::XPropertySet > xTOC;
3338 15 : m_bStartTOC = true;
3339 15 : m_bStartBibliography = true;
3340 15 : if (m_xTextFactory.is())
3341 : xTOC.set(
3342 15 : m_xTextFactory->createInstance(
3343 15 : sTOCServiceName),
3344 15 : uno::UNO_QUERY_THROW);
3345 15 : if (xTOC.is())
3346 15 : xTOC->setPropertyValue(rPropNameSupplier.GetName( PROP_TITLE ), uno::makeAny(OUString()));
3347 :
3348 15 : pContext->SetTOC( xTOC );
3349 15 : m_bParaHadField = false;
3350 :
3351 30 : uno::Reference< text::XTextContent > xToInsert( xTOC, uno::UNO_QUERY );
3352 30 : appendTextContent(xToInsert, uno::Sequence< beans::PropertyValue >() );
3353 15 : }
3354 :
3355 18 : void DomainMapper_Impl::handleIndex
3356 : (FieldContextPtr pContext,
3357 : PropertyNameSupplier& rPropNameSupplier,
3358 : uno::Reference< uno::XInterface > & /*xFieldInterface*/,
3359 : uno::Reference< beans::XPropertySet > const& /*xFieldProperties*/,
3360 : const OUString & sTOCServiceName)
3361 : {
3362 18 : uno::Reference< beans::XPropertySet > xTOC;
3363 18 : m_bStartTOC = true;
3364 18 : m_bStartIndex = true;
3365 36 : OUString sValue;
3366 36 : OUString sIndexEntryType = "I"; // Default value for field flag '\f' is 'I'.
3367 :
3368 :
3369 18 : if (m_xTextFactory.is())
3370 : xTOC.set(
3371 18 : m_xTextFactory->createInstance(
3372 18 : sTOCServiceName),
3373 18 : uno::UNO_QUERY_THROW);
3374 18 : if (xTOC.is())
3375 : {
3376 18 : xTOC->setPropertyValue(rPropNameSupplier.GetName( PROP_TITLE ), uno::makeAny(OUString()));
3377 :
3378 18 : if( lcl_FindInCommand( pContext->GetCommand(), 'r', sValue ))
3379 : {
3380 0 : xTOC->setPropertyValue("IsCommaSeparated", uno::makeAny(true));
3381 : }
3382 18 : if( lcl_FindInCommand( pContext->GetCommand(), 'h', sValue ))
3383 : {
3384 3 : xTOC->setPropertyValue("UseAlphabeticalSeparators", uno::makeAny(true));
3385 : }
3386 18 : if( lcl_FindInCommand( pContext->GetCommand(), 'f', sValue ))
3387 : {
3388 3 : if(!sValue.isEmpty())
3389 3 : sIndexEntryType = sValue ;
3390 3 : xTOC->setPropertyValue(rPropNameSupplier.GetName( PROP_INDEX_ENTRY_TYPE ), uno::makeAny(sIndexEntryType));
3391 : }
3392 : }
3393 18 : pContext->SetTOC( xTOC );
3394 18 : m_bParaHadField = false;
3395 :
3396 36 : uno::Reference< text::XTextContent > xToInsert( xTOC, uno::UNO_QUERY );
3397 18 : appendTextContent(xToInsert, uno::Sequence< beans::PropertyValue >() );
3398 :
3399 18 : if( lcl_FindInCommand( pContext->GetCommand(), 'c', sValue ))
3400 : {
3401 13 : sValue = sValue.replaceAll("\"", "");
3402 13 : uno::Reference<text::XTextColumns> xTextColumns;
3403 13 : xTOC->getPropertyValue(rPropNameSupplier.GetName( PROP_TEXT_COLUMNS )) >>= xTextColumns;
3404 13 : if (xTextColumns.is())
3405 : {
3406 13 : xTextColumns->setColumnCount( sValue.toInt32() );
3407 13 : xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_TEXT_COLUMNS ), uno::makeAny( xTextColumns ) );
3408 13 : }
3409 18 : }
3410 18 : }
3411 :
3412 1991 : void DomainMapper_Impl::CloseFieldCommand()
3413 : {
3414 1991 : if(m_bDiscardHeaderFooter)
3415 2008 : return;
3416 : #ifdef DEBUG_WRITERFILTER
3417 : TagLogger::getInstance().element("closeFieldCommand");
3418 : #endif
3419 :
3420 1974 : FieldContextPtr pContext;
3421 1974 : if(!m_aFieldStack.empty())
3422 1974 : pContext = m_aFieldStack.top();
3423 : OSL_ENSURE( pContext.get(), "no field context available");
3424 1974 : if( pContext.get() )
3425 : {
3426 1974 : m_bSetUserFieldContent = false;
3427 1974 : m_bSetCitation = false;
3428 1974 : m_bSetDateValue = false;
3429 1974 : FieldConversionMap_t aFieldConversionMap = lcl_GetFieldConversion();
3430 :
3431 : try
3432 : {
3433 1974 : uno::Reference< uno::XInterface > xFieldInterface;
3434 :
3435 : boost::tuple<OUString, std::vector<OUString>, std::vector<OUString> > const
3436 3948 : field(lcl_SplitFieldCommand(pContext->GetCommand()));
3437 1974 : OUString const sFirstParam(boost::get<1>(field).empty()
3438 3948 : ? OUString() : boost::get<1>(field).front());
3439 :
3440 : FieldConversionMap_t::iterator const aIt =
3441 1974 : aFieldConversionMap.find(boost::get<0>(field));
3442 1974 : if(aIt != aFieldConversionMap.end())
3443 : {
3444 1873 : bool bCreateEnhancedField = false;
3445 1873 : uno::Reference< beans::XPropertySet > xFieldProperties;
3446 1873 : bool bCreateField = true;
3447 1873 : switch (aIt->second.eFieldId)
3448 : {
3449 : case FIELD_HYPERLINK:
3450 : case FIELD_DOCPROPERTY:
3451 : case FIELD_TOC:
3452 : case FIELD_INDEX:
3453 : case FIELD_XE:
3454 : case FIELD_BIBLIOGRAPHY:
3455 : case FIELD_CITATION:
3456 : case FIELD_TC:
3457 : case FIELD_EQ:
3458 1027 : bCreateField = false;
3459 1027 : break;
3460 : case FIELD_FORMCHECKBOX :
3461 : case FIELD_FORMTEXT :
3462 : case FIELD_FORMDROPDOWN :
3463 : {
3464 : // If we use 'enhanced' fields then FIELD_FORMCHECKBOX,
3465 : // FIELD_FORMTEXT & FIELD_FORMDROPDOWN are treated specially
3466 32 : if ( m_bUsingEnhancedFields )
3467 : {
3468 32 : bCreateField = false;
3469 32 : bCreateEnhancedField = true;
3470 : }
3471 : // for non enhanced fields checkboxes are displayed
3472 : // as an awt control not a field
3473 0 : else if ( aIt->second.eFieldId == FIELD_FORMCHECKBOX )
3474 0 : bCreateField = false;
3475 32 : break;
3476 : }
3477 : default:
3478 814 : break;
3479 : }
3480 1873 : if (m_bStartTOC && (aIt->second.eFieldId == FIELD_PAGEREF) )
3481 : {
3482 489 : m_bTOCPageRef = true;
3483 489 : bCreateField = false;
3484 : }
3485 :
3486 1873 : if( bCreateField || bCreateEnhancedField )
3487 : {
3488 : //add the service prefix
3489 357 : OUString sServiceName("com.sun.star.text.");
3490 357 : if ( bCreateEnhancedField )
3491 : {
3492 32 : FieldConversionMap_t aEnhancedFieldConversionMap = lcl_GetEnhancedFieldConversion();
3493 : FieldConversionMap_t::iterator aEnhancedIt =
3494 32 : aEnhancedFieldConversionMap.find(boost::get<0>(field));
3495 32 : if ( aEnhancedIt != aEnhancedFieldConversionMap.end())
3496 32 : sServiceName += OUString::createFromAscii(aEnhancedIt->second.cFieldServiceName );
3497 : }
3498 : else
3499 : {
3500 325 : sServiceName += "TextField.";
3501 325 : sServiceName += OUString::createFromAscii(aIt->second.cFieldServiceName );
3502 : }
3503 :
3504 : #ifdef DEBUG_WRITERFILTER
3505 : TagLogger::getInstance().startElement("fieldService");
3506 : TagLogger::getInstance().chars(sServiceName);
3507 : TagLogger::getInstance().endElement();
3508 : #endif
3509 :
3510 357 : if (m_xTextFactory.is())
3511 : {
3512 357 : xFieldInterface = m_xTextFactory->createInstance(sServiceName);
3513 355 : xFieldProperties = uno::Reference< beans::XPropertySet >( xFieldInterface, uno::UNO_QUERY_THROW);
3514 357 : }
3515 : }
3516 1871 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
3517 1871 : switch( aIt->second.eFieldId )
3518 : {
3519 0 : case FIELD_ADDRESSBLOCK: break;
3520 0 : case FIELD_ADVANCE : break;
3521 : case FIELD_ASK :
3522 4 : handleFieldAsk(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties);
3523 4 : break;
3524 : case FIELD_AUTONUM :
3525 : case FIELD_AUTONUMLGL :
3526 : case FIELD_AUTONUMOUT :
3527 0 : handleAutoNum(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties);
3528 0 : break;
3529 : case FIELD_AUTHOR :
3530 : case FIELD_USERNAME :
3531 : case FIELD_USERINITIALS :
3532 : handleAuthor(sFirstParam, rPropNameSupplier,
3533 : xFieldInterface, xFieldProperties,
3534 1 : aIt->second.eFieldId);
3535 1 : break;
3536 : case FIELD_DATE:
3537 10 : if (xFieldProperties.is())
3538 : {
3539 : // Get field fixed property from the context handler
3540 10 : if (pContext->IsFieldLocked())
3541 : {
3542 6 : xFieldProperties->setPropertyValue(
3543 : rPropNameSupplier.GetName(PROP_IS_FIXED),
3544 6 : uno::makeAny( true ));
3545 6 : m_bSetDateValue = true;
3546 : }
3547 : else
3548 4 : xFieldProperties->setPropertyValue(
3549 : rPropNameSupplier.GetName(PROP_IS_FIXED),
3550 4 : uno::makeAny( false ));
3551 :
3552 10 : xFieldProperties->setPropertyValue(
3553 : rPropNameSupplier.GetName(PROP_IS_DATE),
3554 10 : uno::makeAny( true ));
3555 10 : SetNumberFormat( pContext->GetCommand(), xFieldProperties );
3556 : }
3557 10 : break;
3558 : case FIELD_COMMENTS :
3559 : {
3560 : // OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" COMMENTS") );
3561 : // A parameter with COMMENTS shouldn't set fixed
3562 : // ( or at least the binary filter doesn't )
3563 : // If we set fixed then we wont export a field cmd.
3564 : // Additionally the para in COMMENTS is more like an
3565 : // instruction to set the document property comments
3566 : // with the param ( e.g. each COMMENT with a param will
3567 : // overwrite the Comments document property
3568 : // #TODO implement the above too
3569 0 : xFieldProperties->setPropertyValue(
3570 0 : rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( false ));
3571 : //PROP_CURRENT_PRESENTATION is set later anyway
3572 : }
3573 0 : break;
3574 : case FIELD_CREATEDATE :
3575 : {
3576 0 : xFieldProperties->setPropertyValue(
3577 0 : rPropNameSupplier.GetName( PROP_IS_DATE ), uno::makeAny( true ));
3578 0 : SetNumberFormat( pContext->GetCommand(), xFieldProperties );
3579 : }
3580 0 : break;
3581 : case FIELD_DOCPROPERTY :
3582 : handleDocProperty(pContext, sFirstParam, rPropNameSupplier,
3583 2 : xFieldInterface, xFieldProperties);
3584 2 : break;
3585 : case FIELD_DOCVARIABLE :
3586 : {
3587 : //create a user field and type
3588 : uno::Reference< beans::XPropertySet > xMaster =
3589 2 : FindOrCreateFieldMaster("com.sun.star.text.FieldMaster.User", sFirstParam);
3590 4 : uno::Reference< text::XDependentTextField > xDependentField( xFieldInterface, uno::UNO_QUERY_THROW );
3591 2 : xDependentField->attachTextFieldMaster( xMaster );
3592 4 : m_bSetUserFieldContent = true;
3593 : }
3594 2 : break;
3595 : case FIELD_EDITTIME :
3596 : //it's a numbering type, no number format! SetNumberFormat( pContext->GetCommand(), xFieldProperties );
3597 3 : break;
3598 : case FIELD_EQ:
3599 : {
3600 1 : OUString aCommand = pContext->GetCommand().trim();
3601 :
3602 2 : msfilter::util::EquationResult aResult(msfilter::util::ParseCombinedChars(aCommand));
3603 1 : if (!aResult.sType.isEmpty() && m_xTextFactory.is())
3604 : {
3605 0 : OUString sServiceName("com.sun.star.text.TextField.");
3606 0 : xFieldInterface = m_xTextFactory->createInstance(sServiceName + aResult.sType);
3607 0 : xFieldProperties =
3608 : uno::Reference< beans::XPropertySet >( xFieldInterface,
3609 0 : uno::UNO_QUERY_THROW);
3610 0 : xFieldProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_CONTENT), uno::makeAny(aResult.sResult));
3611 : }
3612 : else
3613 : {
3614 : //merge Read_SubF_Ruby into filter/.../util.cxx and reuse that ?
3615 1 : sal_Int32 nSpaceIndex = aCommand.indexOf(' ');
3616 1 : if(nSpaceIndex > 0)
3617 1 : aCommand = aCommand.copy(nSpaceIndex).trim();
3618 1 : if (aCommand.startsWith("\\s"))
3619 : {
3620 1 : aCommand = aCommand.copy(2);
3621 1 : if (aCommand.startsWith("\\do"))
3622 : {
3623 1 : aCommand = aCommand.copy(3);
3624 1 : sal_Int32 nStartIndex = aCommand.indexOf('(');
3625 1 : sal_Int32 nEndIndex = aCommand.indexOf(')');
3626 1 : if (nStartIndex > 0 && nEndIndex > 0)
3627 : {
3628 : // nDown is the requested "lower by" value in points.
3629 1 : sal_Int32 nDown = aCommand.copy(0, nStartIndex).toInt32();
3630 1 : OUString aContent = aCommand.copy(nStartIndex + 1, nEndIndex - nStartIndex - 1);
3631 2 : PropertyMapPtr pCharContext = GetTopContext();
3632 : // dHeight is the font size of the current style.
3633 1 : double dHeight = 0;
3634 1 : if (GetPropertyFromStyleSheet(PROP_CHAR_HEIGHT) >>= dHeight)
3635 : // Character escapement should be given in negative percents for subscripts.
3636 1 : pCharContext->Insert(PROP_CHAR_ESCAPEMENT, uno::makeAny( sal_Int16(- 100 * nDown / dHeight) ) );
3637 2 : appendTextPortion(aContent, pCharContext);
3638 : }
3639 : }
3640 : }
3641 1 : }
3642 : }
3643 1 : break;
3644 : case FIELD_FILLIN :
3645 : {
3646 0 : sal_Int32 nIndex = 0;
3647 0 : if (xFieldProperties.is())
3648 0 : xFieldProperties->setPropertyValue(
3649 0 : rPropNameSupplier.GetName(PROP_HINT), uno::makeAny( pContext->GetCommand().getToken( 1, '\"', nIndex)));
3650 : }
3651 0 : break;
3652 : case FIELD_FILENAME:
3653 : {
3654 6 : sal_Int32 nNumberingTypeIndex = pContext->GetCommand().indexOf("\\p");
3655 6 : if (xFieldProperties.is())
3656 6 : xFieldProperties->setPropertyValue(
3657 : rPropNameSupplier.GetName(PROP_FILE_FORMAT),
3658 6 : uno::makeAny( nNumberingTypeIndex > 0 ? text::FilenameDisplayFormat::FULL : text::FilenameDisplayFormat::NAME_AND_EXT ));
3659 : }
3660 6 : break;
3661 0 : case FIELD_FILESIZE : break;
3662 0 : case FIELD_FORMULA : break;
3663 : case FIELD_FORMCHECKBOX :
3664 : case FIELD_FORMDROPDOWN :
3665 : case FIELD_FORMTEXT :
3666 : {
3667 32 : uno::Reference< text::XTextField > xTextField( xFieldInterface, uno::UNO_QUERY );
3668 32 : if ( !xTextField.is() )
3669 : {
3670 : FFDataHandler::Pointer_t
3671 32 : pFFDataHandler(pContext->getFFDataHandler());
3672 : FormControlHelper::Pointer_t
3673 : pFormControlHelper(new FormControlHelper
3674 32 : (m_bUsingEnhancedFields ? aIt->second.eFieldId : FIELD_FORMCHECKBOX,
3675 :
3676 96 : m_xTextDocument, pFFDataHandler));
3677 32 : pContext->setFormControlHelper(pFormControlHelper);
3678 64 : uno::Reference< text::XFormField > xFormField( xFieldInterface, uno::UNO_QUERY );
3679 64 : uno::Reference< container::XNamed > xNamed( xFormField, uno::UNO_QUERY );
3680 32 : if ( xNamed.is() )
3681 : {
3682 32 : if ( pFFDataHandler && !pFFDataHandler->getName().isEmpty() )
3683 8 : xNamed->setName( pFFDataHandler->getName() );
3684 32 : pContext->SetFormField( xFormField );
3685 32 : }
3686 : }
3687 : else
3688 : {
3689 0 : if ( aIt->second.eFieldId == FIELD_FORMDROPDOWN )
3690 0 : lcl_handleDropdownField( xFieldProperties, pContext->getFFDataHandler() );
3691 : else
3692 0 : lcl_handleTextField( xFieldProperties, pContext->getFFDataHandler(), rPropNameSupplier );
3693 32 : }
3694 : }
3695 32 : break;
3696 0 : case FIELD_GOTOBUTTON : break;
3697 : case FIELD_HYPERLINK:
3698 : {
3699 777 : ::std::vector<OUString> aParts = pContext->GetCommandParts();
3700 :
3701 : // Syntax is either:
3702 : // HYPERLINK "" \l "link"
3703 : // or
3704 : // HYPERLINK \l "link"
3705 : // Make sure "HYPERLINK" doesn't end up as part of link in the second case.
3706 777 : if (!aParts.empty() && aParts[0] == "HYPERLINK")
3707 777 : aParts.erase(aParts.begin());
3708 :
3709 777 : ::std::vector<OUString>::const_iterator aItEnd = aParts.end();
3710 777 : ::std::vector<OUString>::const_iterator aPartIt = aParts.begin();
3711 :
3712 1554 : OUString sURL;
3713 :
3714 2844 : while (aPartIt != aItEnd)
3715 : {
3716 1290 : if ( *aPartIt == "\\l" )
3717 : {
3718 441 : ++aPartIt;
3719 :
3720 441 : if (aPartIt == aItEnd)
3721 0 : break;
3722 :
3723 441 : sURL += OUString('#');
3724 441 : sURL += *aPartIt;
3725 : }
3726 849 : else if ( *aPartIt == "\\m" || *aPartIt == "\\n" )
3727 : {
3728 : }
3729 849 : else if ( *aPartIt == "\\o" || *aPartIt == "\\t" )
3730 : {
3731 75 : ++aPartIt;
3732 :
3733 75 : if (aPartIt == aItEnd)
3734 0 : break;
3735 : }
3736 : else
3737 : {
3738 774 : sURL = *aPartIt;
3739 : }
3740 :
3741 1290 : ++aPartIt;
3742 : }
3743 :
3744 777 : if (!sURL.isEmpty())
3745 : {
3746 775 : pContext->SetHyperlinkURL(sURL);
3747 777 : }
3748 : }
3749 777 : break;
3750 0 : case FIELD_IF : break;
3751 0 : case FIELD_INFO : break;
3752 0 : case FIELD_INCLUDEPICTURE: break;
3753 : case FIELD_KEYWORDS :
3754 : {
3755 0 : if (!sFirstParam.isEmpty())
3756 : {
3757 0 : xFieldProperties->setPropertyValue(
3758 0 : rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( true ));
3759 : //PROP_CURRENT_PRESENTATION is set later anyway
3760 : }
3761 : }
3762 0 : break;
3763 3 : case FIELD_LASTSAVEDBY : break;
3764 : case FIELD_MACROBUTTON:
3765 : {
3766 : //extract macro name
3767 3 : sal_Int32 nIndex = sizeof(" MACROBUTTON ");
3768 3 : OUString sMacro = pContext->GetCommand().getToken( 0, ' ', nIndex);
3769 3 : if (xFieldProperties.is())
3770 3 : xFieldProperties->setPropertyValue(
3771 3 : rPropNameSupplier.GetName(PROP_MACRO_NAME), uno::makeAny( sMacro ));
3772 :
3773 : //extract quick help text
3774 3 : if(xFieldProperties.is() && pContext->GetCommand().getLength() > nIndex + 1)
3775 : {
3776 3 : xFieldProperties->setPropertyValue(
3777 : rPropNameSupplier.GetName(PROP_HINT),
3778 3 : uno::makeAny( pContext->GetCommand().copy( nIndex )));
3779 3 : }
3780 : }
3781 3 : break;
3782 : case FIELD_MERGEFIELD :
3783 : {
3784 : //todo: create a database field and fieldmaster pointing to a column, only
3785 : //create a user field and type
3786 : uno::Reference< beans::XPropertySet > xMaster =
3787 2 : FindOrCreateFieldMaster("com.sun.star.text.FieldMaster.Database", sFirstParam);
3788 :
3789 : // xFieldProperties->setPropertyValue(
3790 : // "FieldCode",
3791 : // uno::makeAny( pContext->GetCommand().copy( nIndex + 1 )));
3792 4 : uno::Reference< text::XDependentTextField > xDependentField( xFieldInterface, uno::UNO_QUERY_THROW );
3793 4 : xDependentField->attachTextFieldMaster( xMaster );
3794 : }
3795 2 : break;
3796 0 : case FIELD_MERGEREC : break;
3797 0 : case FIELD_MERGESEQ : break;
3798 0 : case FIELD_NEXT : break;
3799 0 : case FIELD_NEXTIF : break;
3800 : case FIELD_PAGE :
3801 195 : if (xFieldProperties.is())
3802 : {
3803 195 : xFieldProperties->setPropertyValue(
3804 : rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
3805 195 : uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) ));
3806 195 : xFieldProperties->setPropertyValue(
3807 : rPropNameSupplier.GetName(PROP_SUB_TYPE),
3808 195 : uno::makeAny( text::PageNumberType_CURRENT ));
3809 : }
3810 :
3811 195 : break;
3812 : case FIELD_PAGEREF:
3813 : case FIELD_REF:
3814 517 : if (xFieldProperties.is() && !m_bStartTOC)
3815 : {
3816 28 : bool bPageRef = aIt->second.eFieldId == FIELD_PAGEREF;
3817 :
3818 : // Do we need a GetReference (default) or a GetExpression field?
3819 28 : uno::Reference< text::XTextFieldsSupplier > xFieldsSupplier( GetTextDocument(), uno::UNO_QUERY );
3820 56 : uno::Reference< container::XNameAccess > xFieldMasterAccess = xFieldsSupplier->getTextFieldMasters();
3821 :
3822 84 : if (!xFieldMasterAccess->hasByName(
3823 : "com.sun.star.text.FieldMaster.SetExpression."
3824 56 : + sFirstParam))
3825 : {
3826 27 : xFieldProperties->setPropertyValue(
3827 : rPropNameSupplier.GetName(PROP_REFERENCE_FIELD_SOURCE),
3828 27 : uno::makeAny( sal_Int16(text::ReferenceFieldSource::BOOKMARK)) );
3829 27 : xFieldProperties->setPropertyValue(
3830 : rPropNameSupplier.GetName(PROP_SOURCE_NAME),
3831 27 : uno::makeAny(sFirstParam) );
3832 27 : sal_Int16 nFieldPart = (bPageRef ? text::ReferenceFieldPart::PAGE : text::ReferenceFieldPart::TEXT);
3833 27 : OUString sValue;
3834 27 : if( lcl_FindInCommand( pContext->GetCommand(), 'p', sValue ))
3835 : {
3836 : //above-below
3837 1 : nFieldPart = text::ReferenceFieldPart::UP_DOWN;
3838 : }
3839 26 : else if( lcl_FindInCommand( pContext->GetCommand(), 'r', sValue ))
3840 : {
3841 : //number
3842 0 : nFieldPart = text::ReferenceFieldPart::NUMBER;
3843 : }
3844 26 : else if( lcl_FindInCommand( pContext->GetCommand(), 'n', sValue ))
3845 : {
3846 : //number-no-context
3847 1 : nFieldPart = text::ReferenceFieldPart::NUMBER_NO_CONTEXT;
3848 : }
3849 25 : else if( lcl_FindInCommand( pContext->GetCommand(), 'w', sValue ))
3850 : {
3851 : //number-full-context
3852 0 : nFieldPart = text::ReferenceFieldPart::NUMBER_FULL_CONTEXT;
3853 : }
3854 27 : xFieldProperties->setPropertyValue(
3855 27 : rPropNameSupplier.GetName( PROP_REFERENCE_FIELD_PART ), uno::makeAny( nFieldPart ));
3856 : }
3857 : else
3858 : {
3859 1 : xFieldInterface = m_xTextFactory->createInstance("com.sun.star.text.TextField.GetExpression");
3860 1 : xFieldProperties.set(xFieldInterface, uno::UNO_QUERY);
3861 1 : xFieldProperties->setPropertyValue(
3862 : rPropNameSupplier.GetName(PROP_CONTENT),
3863 1 : uno::makeAny(sFirstParam));
3864 1 : xFieldProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING));
3865 28 : }
3866 : }
3867 517 : break;
3868 3 : case FIELD_REVNUM : break;
3869 : case FIELD_SAVEDATE :
3870 0 : SetNumberFormat( pContext->GetCommand(), xFieldProperties );
3871 0 : break;
3872 0 : case FIELD_SECTION : break;
3873 0 : case FIELD_SECTIONPAGES : break;
3874 : case FIELD_SEQ :
3875 : {
3876 : // command looks like: " SEQ Table \* ARABIC "
3877 47 : OUString sCmd(pContext->GetCommand());
3878 : // find the sequence name, e.g. "SEQ"
3879 94 : OUString sSeqName = msfilter::util::findQuotedText(sCmd, "SEQ ", '\\');
3880 47 : sSeqName = sSeqName.trim();
3881 :
3882 : // create a sequence field master using the sequence name
3883 : uno::Reference< beans::XPropertySet > xMaster = FindOrCreateFieldMaster(
3884 : "com.sun.star.text.FieldMaster.SetExpression",
3885 94 : sSeqName);
3886 :
3887 47 : xMaster->setPropertyValue(
3888 : rPropNameSupplier.GetName(PROP_SUB_TYPE),
3889 47 : uno::makeAny(text::SetVariableType::SEQUENCE));
3890 :
3891 : // apply the numbering type
3892 47 : xFieldProperties->setPropertyValue(
3893 : rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
3894 47 : uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) ));
3895 :
3896 : // attach the master to the field
3897 94 : uno::Reference< text::XDependentTextField > xDependentField( xFieldInterface, uno::UNO_QUERY_THROW );
3898 47 : xDependentField->attachTextFieldMaster( xMaster );
3899 :
3900 94 : rtl::OUString sFormula = sSeqName + "+1";
3901 94 : rtl::OUString sValue;
3902 47 : if( lcl_FindInCommand( pContext->GetCommand(), 'c', sValue ))
3903 : {
3904 0 : sFormula = sSeqName;
3905 : }
3906 47 : else if( lcl_FindInCommand( pContext->GetCommand(), 'r', sValue ))
3907 : {
3908 0 : sFormula = sValue;
3909 : }
3910 : // TODO \s isn't handled, but the spec isn't easy to understand without
3911 : // an example for this one.
3912 47 : xFieldProperties->setPropertyValue(
3913 : rPropNameSupplier.GetName(PROP_CONTENT),
3914 47 : uno::makeAny(sFormula));
3915 :
3916 : // Take care of the numeric formatting definition, default is Arabic
3917 47 : sal_Int16 nNumberingType = lcl_ParseNumberingType(pContext->GetCommand());
3918 47 : if (nNumberingType == style::NumberingType::PAGE_DESCRIPTOR)
3919 44 : nNumberingType = style::NumberingType::ARABIC;
3920 47 : xFieldProperties->setPropertyValue(
3921 : rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
3922 94 : uno::makeAny(nNumberingType));
3923 : }
3924 47 : break;
3925 0 : case FIELD_SET : break;
3926 0 : case FIELD_SKIPIF : break;
3927 0 : case FIELD_STYLEREF : break;
3928 : case FIELD_SUBJECT :
3929 : {
3930 0 : if (!sFirstParam.isEmpty())
3931 : {
3932 0 : xFieldProperties->setPropertyValue(
3933 0 : rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( true ));
3934 : //PROP_CURRENT_PRESENTATION is set later anyway
3935 : }
3936 : }
3937 0 : break;
3938 0 : case FIELD_SYMBOL : break;
3939 0 : case FIELD_TEMPLATE: break;
3940 : case FIELD_TIME :
3941 : {
3942 1 : if (pContext->IsFieldLocked())
3943 : {
3944 0 : xFieldProperties->setPropertyValue(
3945 : rPropNameSupplier.GetName(PROP_IS_FIXED),
3946 0 : uno::makeAny( true ));
3947 0 : m_bSetDateValue = true;
3948 : }
3949 1 : SetNumberFormat( pContext->GetCommand(), xFieldProperties );
3950 : }
3951 1 : break;
3952 : case FIELD_TITLE :
3953 : {
3954 1 : if (!sFirstParam.isEmpty())
3955 : {
3956 0 : xFieldProperties->setPropertyValue(
3957 0 : rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( true ));
3958 : //PROP_CURRENT_PRESENTATION is set later anyway
3959 : }
3960 : }
3961 1 : break;
3962 : case FIELD_USERADDRESS : //todo: user address collects street, city ...
3963 0 : break;
3964 : case FIELD_INDEX:
3965 : handleIndex(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties,
3966 18 : OUString::createFromAscii(aIt->second.cFieldServiceName));
3967 18 : break;
3968 : case FIELD_BIBLIOGRAPHY:
3969 : handleBibliography(pContext, rPropNameSupplier,
3970 15 : OUString::createFromAscii(aIt->second.cFieldServiceName));
3971 15 : break;
3972 : case FIELD_TOC:
3973 : handleToc(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties,
3974 59 : OUString::createFromAscii(aIt->second.cFieldServiceName));
3975 59 : break;
3976 : case FIELD_XE:
3977 : {
3978 : uno::Reference< beans::XPropertySet > xTC(
3979 133 : m_xTextFactory->createInstance(
3980 133 : OUString::createFromAscii(aIt->second.cFieldServiceName)),
3981 133 : uno::UNO_QUERY_THROW);
3982 133 : if (!sFirstParam.isEmpty())
3983 : {
3984 133 : xTC->setPropertyValue("PrimaryKey",
3985 133 : uno::makeAny(sFirstParam));
3986 : }
3987 266 : uno::Reference< text::XTextContent > xToInsert( xTC, uno::UNO_QUERY );
3988 266 : uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
3989 133 : if (xTextAppend.is())
3990 : {
3991 133 : uno::Reference< text::XTextCursor > xCrsr = xTextAppend->getText()->createTextCursor();
3992 :
3993 266 : uno::Reference< text::XText > xText = xTextAppend->getText();
3994 133 : if(xCrsr.is() && xText.is())
3995 : {
3996 133 : xCrsr->gotoEnd(false);
3997 133 : xText->insertTextContent(uno::Reference< text::XTextRange >( xCrsr, uno::UNO_QUERY_THROW ), xToInsert, sal_False);
3998 133 : }
3999 133 : }
4000 : }
4001 133 : break;
4002 : case FIELD_CITATION:
4003 : {
4004 63 : xFieldInterface = m_xTextFactory->createInstance(
4005 42 : OUString::createFromAscii(aIt->second.cFieldServiceName));
4006 : uno::Reference< beans::XPropertySet > xTC(xFieldInterface,
4007 21 : uno::UNO_QUERY_THROW);
4008 42 : OUString sCmd(pContext->GetCommand());//sCmd is the entire instrText inclusing the index e.g. CITATION Kra06 \l 1033
4009 21 : if( !sCmd.isEmpty()){
4010 21 : uno::Sequence<beans::PropertyValue> aValues(1);
4011 42 : beans::PropertyValue propertyVal;
4012 21 : propertyVal.Name = "Identifier";
4013 21 : propertyVal.Value = uno::makeAny(sCmd);
4014 21 : aValues[0] = propertyVal;
4015 21 : xTC->setPropertyValue("Fields",
4016 42 : uno::makeAny(aValues));
4017 : }
4018 42 : uno::Reference< text::XTextContent > xToInsert( xTC, uno::UNO_QUERY );
4019 :
4020 42 : uno::Sequence<beans::PropertyValue> aValues = m_aFieldStack.top()->getProperties()->GetPropertyValues();
4021 21 : appendTextContent(xToInsert, aValues);
4022 42 : m_bSetCitation = true;
4023 : }
4024 21 : break;
4025 :
4026 : case FIELD_TC :
4027 : {
4028 : uno::Reference< beans::XPropertySet > xTC(
4029 1 : m_xTextFactory->createInstance(
4030 1 : OUString::createFromAscii(aIt->second.cFieldServiceName)),
4031 1 : uno::UNO_QUERY_THROW);
4032 1 : if (!sFirstParam.isEmpty())
4033 : {
4034 1 : xTC->setPropertyValue(rPropNameSupplier.GetName(PROP_ALTERNATIVE_TEXT),
4035 1 : uno::makeAny(sFirstParam));
4036 : }
4037 2 : OUString sValue;
4038 : // \f TC entry in doc with multiple tables
4039 : // if( lcl_FindInCommand( pContext->GetCommand(), 'f', sValue ))
4040 : // {
4041 : // todo: unsupported
4042 : // }
4043 1 : if( lcl_FindInCommand( pContext->GetCommand(), 'l', sValue ))
4044 : // \l Outline Level
4045 : {
4046 0 : sal_Int32 nLevel = sValue.toInt32();
4047 0 : if( !sValue.isEmpty() && nLevel >= 0 && nLevel <= 10 )
4048 0 : xTC->setPropertyValue(rPropNameSupplier.GetName(PROP_LEVEL), uno::makeAny( (sal_Int16)nLevel ));
4049 : }
4050 : // if( lcl_FindInCommand( pContext->GetCommand(), 'n', sValue ))
4051 : // \n Suppress page numbers
4052 : // {
4053 : //todo: unsupported feature
4054 : // }
4055 2 : pContext->SetTC( xTC );
4056 : }
4057 1 : break;
4058 : case FIELD_NUMCHARS:
4059 : case FIELD_NUMWORDS:
4060 : case FIELD_NUMPAGES:
4061 14 : if (xFieldProperties.is())
4062 14 : xFieldProperties->setPropertyValue(
4063 : rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
4064 14 : uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) ));
4065 14 : break;
4066 1873 : }
4067 : }
4068 : else
4069 : {
4070 : /* Unsupported fields will be handled here for docx file.
4071 : * To handle unsupported fields used fieldmark API.
4072 : */
4073 101 : OUString aCode( pContext->GetCommand().trim() );
4074 : // Don't waste resources on wrapping shapes inside a fieldmark.
4075 101 : if (aCode != "SHAPE")
4076 : {
4077 94 : xFieldInterface = m_xTextFactory->createInstance("com.sun.star.text.Fieldmark");
4078 94 : const uno::Reference<text::XTextContent> xTextContent(xFieldInterface, uno::UNO_QUERY_THROW);
4079 188 : uno::Reference< text::XTextAppend > xTextAppend;
4080 94 : xTextAppend = m_aTextAppendStack.top().xTextAppend;
4081 188 : uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange(pContext->GetStartRange());
4082 94 : if (xTextContent.is())
4083 : {
4084 94 : xTextAppend->insertTextContent(xCrsr,xTextContent, sal_True);
4085 : }
4086 188 : const uno::Reference<uno::XInterface> xContent(xTextContent);
4087 188 : uno::Reference< text::XFormField> xFormField(xContent, uno::UNO_QUERY);
4088 94 : xFormField->setFieldType(aCode);
4089 94 : m_bStartGenericField = true;
4090 188 : pContext->SetFormField( xFormField );
4091 : }
4092 : else
4093 7 : m_bParaHadField = false;
4094 : }
4095 : //set the text field if there is any
4096 3946 : pContext->SetTextField( uno::Reference< text::XTextField >( xFieldInterface, uno::UNO_QUERY ) );
4097 : }
4098 2 : catch( const uno::Exception& e )
4099 : {
4100 : SAL_WARN( "writerfilter", "Exception in CloseFieldCommand(): " << e.Message );
4101 : }
4102 1974 : pContext->SetCommandCompleted();
4103 1974 : }
4104 : }
4105 : /*-------------------------------------------------------------------------
4106 : //the _current_ fields require a string type result while TOCs accept richt results
4107 : -----------------------------------------------------------------------*/
4108 3224 : bool DomainMapper_Impl::IsFieldResultAsString()
4109 : {
4110 3224 : bool bRet = false;
4111 : OSL_ENSURE( !m_aFieldStack.empty(), "field stack empty?");
4112 3224 : FieldContextPtr pContext = m_aFieldStack.top();
4113 : OSL_ENSURE( pContext.get(), "no field context available");
4114 3224 : if( pContext.get() )
4115 : {
4116 3224 : bRet = pContext->GetTextField().is();
4117 : }
4118 3224 : return bRet;
4119 : }
4120 :
4121 373 : void DomainMapper_Impl::AppendFieldResult(OUString const& rString)
4122 : {
4123 : assert(!m_aFieldStack.empty());
4124 373 : FieldContextPtr pContext = m_aFieldStack.top();
4125 : SAL_WARN_IF(!pContext.get(), "writerfilter.dmapper", "no field context");
4126 373 : if (pContext.get())
4127 : {
4128 373 : pContext->AppendResult(rString);
4129 373 : }
4130 373 : }
4131 :
4132 : // Calculates css::DateTime based on ddddd.sssss since 1900-1-0
4133 6 : util::DateTime lcl_dateTimeFromSerial(const double& dSerial)
4134 : {
4135 6 : const sal_uInt32 secondsPerDay = 86400;
4136 6 : const sal_uInt16 secondsPerHour = 3600;
4137 :
4138 6 : DateTime d(Date(30, 12, 1899));
4139 6 : d += (long)dSerial;
4140 :
4141 6 : double frac = dSerial - (long)dSerial;
4142 6 : sal_uInt32 seconds = frac * secondsPerDay;
4143 :
4144 6 : util::DateTime date;
4145 6 : date.Year = d.GetYear();
4146 6 : date.Month = d.GetMonth();
4147 6 : date.Day = d.GetDay();
4148 6 : date.Hours = seconds / secondsPerHour;
4149 6 : date.Minutes = (seconds % secondsPerHour) / 60;
4150 6 : date.Seconds = seconds % 60;
4151 :
4152 6 : return date;
4153 : }
4154 :
4155 336 : void DomainMapper_Impl::SetFieldResult(OUString const& rResult)
4156 : {
4157 : #ifdef DEBUG_WRITERFILTER
4158 : TagLogger::getInstance().startElement("setFieldResult");
4159 : TagLogger::getInstance().chars(rResult);
4160 : #endif
4161 :
4162 336 : FieldContextPtr pContext = m_aFieldStack.top();
4163 : OSL_ENSURE( pContext.get(), "no field context available");
4164 336 : if( pContext.get() )
4165 : {
4166 336 : uno::Reference<text::XTextField> xTextField = pContext->GetTextField();
4167 : try
4168 : {
4169 336 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
4170 : OSL_ENSURE( xTextField.is()
4171 : //||m_xTOC.is() ||m_xTC.is()
4172 : //||m_sHyperlinkURL.getLength()
4173 : , "DomainMapper_Impl::SetFieldResult: field not created" );
4174 336 : if(xTextField.is())
4175 : {
4176 : try
4177 : {
4178 336 : if( m_bSetUserFieldContent )
4179 : {
4180 : // user field content has to be set at the field master
4181 2 : uno::Reference< text::XDependentTextField > xDependentField( xTextField, uno::UNO_QUERY_THROW );
4182 4 : xDependentField->getTextFieldMaster()->setPropertyValue(
4183 : rPropNameSupplier.GetName(PROP_CONTENT),
4184 4 : uno::makeAny( rResult ));
4185 : }
4186 334 : else if ( m_bSetCitation )
4187 : {
4188 :
4189 21 : uno::Reference< beans::XPropertySet > xFieldProperties( xTextField, uno::UNO_QUERY_THROW);
4190 : // In case of SetExpression, the field result contains the content of the variable.
4191 42 : uno::Reference<lang::XServiceInfo> xServiceInfo(xTextField, uno::UNO_QUERY);
4192 :
4193 21 : bool bIsSetbiblio = xServiceInfo->supportsService("com.sun.star.text.TextField.Bibliography");
4194 21 : if( bIsSetbiblio )
4195 : {
4196 21 : uno::Any aProperty = xFieldProperties->getPropertyValue("Fields");
4197 42 : uno::Sequence<beans::PropertyValue> aValues ;
4198 21 : aProperty >>= aValues;
4199 42 : beans::PropertyValue propertyVal;
4200 21 : bool bTitleFound = false;
4201 21 : int i=0;
4202 441 : for (; i < aValues.getLength(); i++)
4203 : {
4204 441 : propertyVal = aValues[i];
4205 441 : if(propertyVal.Name == "Title")
4206 : {
4207 21 : bTitleFound = true;
4208 21 : break;
4209 : }
4210 : }
4211 21 : if(bTitleFound)
4212 : {
4213 21 : OUString titleStr;
4214 42 : uno::Any aValue(propertyVal.Value);
4215 21 : aValue >>= titleStr;
4216 21 : titleStr = titleStr + rResult;
4217 21 : propertyVal.Value = uno::makeAny(titleStr);
4218 42 : aValues[i] = propertyVal;
4219 : }
4220 : else
4221 : {
4222 0 : propertyVal.Name = "Title";
4223 0 : propertyVal.Value = uno::makeAny(rResult);
4224 0 : aValues[i] = propertyVal;
4225 : }
4226 21 : xFieldProperties->setPropertyValue("Fields",
4227 42 : uno::makeAny(aValues));
4228 21 : }
4229 : }
4230 313 : else if ( m_bSetDateValue )
4231 : {
4232 6 : uno::Reference< util::XNumberFormatsSupplier > xNumberSupplier( m_xTextDocument, uno::UNO_QUERY_THROW );
4233 :
4234 12 : uno::Reference<util::XNumberFormatter> xFormatter(util::NumberFormatter::create(m_xComponentContext), uno::UNO_QUERY_THROW);
4235 6 : xFormatter->attachNumberFormatsSupplier( xNumberSupplier );
4236 6 : sal_Int32 nKey = 0;
4237 :
4238 12 : uno::Reference< beans::XPropertySet > xFieldProperties( xTextField, uno::UNO_QUERY_THROW);
4239 :
4240 6 : xFieldProperties->getPropertyValue( "NumberFormat" ) >>= nKey;
4241 6 : xFieldProperties->setPropertyValue(
4242 : "DateTimeValue",
4243 12 : uno::makeAny( lcl_dateTimeFromSerial( xFormatter->convertStringToNumber( nKey, rResult ) ) ) );
4244 : }
4245 : else
4246 : {
4247 307 : uno::Reference< beans::XPropertySet > xFieldProperties( xTextField, uno::UNO_QUERY_THROW);
4248 : // In case of SetExpression, the field result contains the content of the variable.
4249 614 : uno::Reference<lang::XServiceInfo> xServiceInfo(xTextField, uno::UNO_QUERY);
4250 307 : bool bIsSetExpression = xServiceInfo->supportsService("com.sun.star.text.TextField.SetExpression");
4251 : // If we already have content set, then use the current presentation
4252 614 : rtl::OUString sValue;
4253 307 : if (bIsSetExpression)
4254 : { // this will throw for field types without Content
4255 50 : uno::Any aValue(xFieldProperties->getPropertyValue(
4256 50 : rPropNameSupplier.GetName(PROP_CONTENT)));
4257 50 : aValue >>= sValue;
4258 : }
4259 307 : xFieldProperties->setPropertyValue(
4260 50 : rPropNameSupplier.GetName(bIsSetExpression && sValue.isEmpty()? PROP_CONTENT : PROP_CURRENT_PRESENTATION),
4261 826 : uno::makeAny( rResult ));
4262 : }
4263 : }
4264 209 : catch( const beans::UnknownPropertyException& )
4265 : {
4266 : //some fields don't have a CurrentPresentation (DateTime)
4267 : }
4268 : }
4269 : }
4270 0 : catch (const uno::Exception& e)
4271 : {
4272 : SAL_WARN("writerfilter.dmapper",
4273 : "DomainMapper_Impl::SetFieldResult: exception: " << e.Message);
4274 336 : }
4275 336 : }
4276 336 : }
4277 :
4278 63 : void DomainMapper_Impl::SetFieldFFData(FFDataHandler::Pointer_t pFFDataHandler)
4279 : {
4280 : #ifdef DEBUG_WRITERFILTER
4281 : TagLogger::getInstance().startElement("setFieldFFData");
4282 : #endif
4283 :
4284 63 : if (m_aFieldStack.size())
4285 : {
4286 63 : FieldContextPtr pContext = m_aFieldStack.top();
4287 63 : if (pContext.get())
4288 : {
4289 63 : pContext->setFFDataHandler(pFFDataHandler);
4290 63 : }
4291 : }
4292 :
4293 : #ifdef DEBUG_WRITERFILTER
4294 : TagLogger::getInstance().endElement();
4295 : #endif
4296 63 : }
4297 :
4298 2007 : void DomainMapper_Impl::PopFieldContext()
4299 : {
4300 2007 : if(m_bDiscardHeaderFooter)
4301 67 : return;
4302 : #ifdef DEBUG_WRITERFILTER
4303 : TagLogger::getInstance().element("popFieldContext");
4304 : #endif
4305 :
4306 1974 : if (m_aFieldStack.empty())
4307 1 : return;
4308 :
4309 1973 : FieldContextPtr pContext = m_aFieldStack.top();
4310 : OSL_ENSURE( pContext.get(), "no field context available");
4311 1973 : if( pContext.get() )
4312 : {
4313 1973 : if( !pContext->IsCommandCompleted() )
4314 109 : CloseFieldCommand();
4315 :
4316 1973 : if (!pContext->GetResult().isEmpty())
4317 : {
4318 336 : uno::Reference< beans::XPropertySet > xFieldProperties = pContext->GetCustomField();
4319 336 : if(xFieldProperties.is())
4320 2 : SetNumberFormat( pContext->GetResult(), xFieldProperties, true );
4321 336 : SetFieldResult( pContext->GetResult() );
4322 : }
4323 :
4324 : //insert the field, TC or TOC
4325 1973 : uno::Reference< text::XTextAppend > xTextAppend;
4326 1973 : if (!m_aTextAppendStack.empty())
4327 1973 : xTextAppend = m_aTextAppendStack.top().xTextAppend;
4328 1973 : if(xTextAppend.is())
4329 : {
4330 : try
4331 : {
4332 1973 : uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange(pContext->GetStartRange());
4333 3946 : uno::Reference< text::XTextContent > xToInsert( pContext->GetTOC(), uno::UNO_QUERY );
4334 1973 : if( xToInsert.is() )
4335 : {
4336 92 : if(xTOCMarkerCursor.is() || m_bStartIndex || m_bStartBibliography)
4337 : {
4338 92 : if (m_bStartIndex || m_bStartBibliography)
4339 : {
4340 33 : if (mxTOCTextCursor.is())
4341 : {
4342 33 : mxTOCTextCursor->goLeft(1,true);
4343 33 : mxTOCTextCursor->setString(OUString());
4344 : }
4345 33 : xTextAppend->finishParagraph( uno::Sequence< beans::PropertyValue >() );
4346 : }
4347 : else
4348 : {
4349 59 : xTOCMarkerCursor->goLeft(1,sal_True);
4350 59 : xTOCMarkerCursor->setString(OUString());
4351 59 : xTOCMarkerCursor->goLeft(1,sal_True);
4352 59 : xTOCMarkerCursor->setString(OUString());
4353 : }
4354 : }
4355 92 : if (m_bStartedTOC || m_bStartIndex || m_bStartBibliography)
4356 : {
4357 88 : m_bStartedTOC = false;
4358 88 : m_aTextAppendStack.pop();
4359 88 : m_bTextInserted = false;
4360 : }
4361 92 : m_bStartTOC = false;
4362 92 : m_bStartIndex = false;
4363 92 : m_bStartBibliography = false;
4364 92 : if(m_bInHeaderFooterImport && m_bStartTOCHeaderFooter)
4365 0 : m_bStartTOCHeaderFooter = false;
4366 : }
4367 : else
4368 : {
4369 1881 : xToInsert = uno::Reference< text::XTextContent >(pContext->GetTC(), uno::UNO_QUERY);
4370 1881 : if( !xToInsert.is() && !m_bStartTOC && !m_bStartIndex && !m_bStartBibliography )
4371 1042 : xToInsert = uno::Reference< text::XTextContent >(pContext->GetTextField(), uno::UNO_QUERY);
4372 1881 : if( xToInsert.is() && !m_bStartTOC && !m_bStartIndex && !m_bStartBibliography)
4373 : {
4374 344 : PropertyMap aMap;
4375 : // Character properties of the field show up here the
4376 : // last (always empty) run. Inherit character
4377 : // properties from there.
4378 : // Also merge in the properties from the field context,
4379 : // e.g. SdtEndBefore.
4380 344 : if (m_pLastCharacterContext.get())
4381 344 : aMap.InsertProps(m_pLastCharacterContext);
4382 344 : aMap.InsertProps(m_aFieldStack.top()->getProperties());
4383 344 : appendTextContent(xToInsert, aMap.GetPropertyValues());
4384 : }
4385 : else
4386 : {
4387 1537 : FormControlHelper::Pointer_t pFormControlHelper(pContext->getFormControlHelper());
4388 1537 : if (pFormControlHelper.get() != nullptr && pFormControlHelper->hasFFDataHandler() )
4389 : {
4390 32 : uno::Reference< text::XFormField > xFormField( pContext->GetFormField() );
4391 32 : xToInsert.set(xFormField, uno::UNO_QUERY);
4392 32 : if ( xFormField.is() && xToInsert.is() )
4393 : {
4394 32 : xCrsr->gotoEnd( true );
4395 32 : xToInsert->attach( uno::Reference< text::XTextRange >( xCrsr, uno::UNO_QUERY_THROW ));
4396 32 : pFormControlHelper->processField( xFormField );
4397 : }
4398 : else
4399 : {
4400 0 : uno::Reference<text::XTextRange> xTxtRange(xCrsr, uno::UNO_QUERY);
4401 0 : pFormControlHelper->insertControl(xTxtRange);
4402 32 : }
4403 : }
4404 1505 : else if(!pContext->GetHyperlinkURL().isEmpty())
4405 : {
4406 775 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
4407 775 : xCrsr->gotoEnd( true );
4408 :
4409 775 : uno::Reference< beans::XPropertySet > xCrsrProperties( xCrsr, uno::UNO_QUERY_THROW );
4410 775 : xCrsrProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_HYPER_LINK_U_R_L), uno::
4411 775 : makeAny(pContext->GetHyperlinkURL()));
4412 :
4413 775 : if (m_bStartTOC) {
4414 343 : OUString sDisplayName("Index Link");
4415 343 : xCrsrProperties->setPropertyValue("VisitedCharStyleName",uno::makeAny(sDisplayName));
4416 343 : xCrsrProperties->setPropertyValue("UnvisitedCharStyleName",uno::makeAny(sDisplayName));
4417 775 : }
4418 : }
4419 730 : else if(m_bStartGenericField)
4420 : {
4421 93 : m_bStartGenericField = false;
4422 93 : if(m_bTextInserted)
4423 : {
4424 60 : m_aTextAppendStack.pop();
4425 60 : m_bTextInserted = false;
4426 : }
4427 1537 : }
4428 : }
4429 1973 : }
4430 : }
4431 0 : catch(const lang::IllegalArgumentException&)
4432 : {
4433 : OSL_FAIL( "IllegalArgumentException in PopFieldContext()" );
4434 : }
4435 0 : catch(const uno::Exception&)
4436 : {
4437 : OSL_FAIL( "exception in PopFieldContext()" );
4438 : }
4439 1973 : }
4440 :
4441 : //TOCs have to include all the imported content
4442 :
4443 : }
4444 : //remove the field context
4445 1973 : m_aFieldStack.pop();
4446 : }
4447 :
4448 :
4449 2925 : void DomainMapper_Impl::SetBookmarkName( const OUString& rBookmarkName )
4450 : {
4451 2925 : BookmarkMap_t::iterator aBookmarkIter = m_aBookmarkMap.find( m_sCurrentBkmkId );
4452 2925 : if( aBookmarkIter != m_aBookmarkMap.end() )
4453 2909 : aBookmarkIter->second.m_sBookmarkName = rBookmarkName;
4454 : else
4455 16 : m_sCurrentBkmkName = rBookmarkName;
4456 2925 : }
4457 :
4458 5645 : void DomainMapper_Impl::StartOrEndBookmark( const OUString& rId )
4459 : {
4460 : /*
4461 : * Add the dummy paragraph to handle section properties
4462 : * iff the first element in the section is a table. If the dummy para is not added yet, then add it;
4463 : * So bookmark is not attched to the wrong paragraph.
4464 : */
4465 11992 : if(getTableManager( ).isInCell() && m_nTableDepth == 0 && GetIsFirstParagraphInSection()
4466 5728 : && !GetIsDummyParaAddedForTableInSection() &&!GetIsTextFrameInserted())
4467 : {
4468 44 : AddDummyParaForTableInSection();
4469 : }
4470 :
4471 5645 : bool bIsAfterDummyPara = GetIsDummyParaAddedForTableInSection() && GetIsFirstParagraphInSection();
4472 5645 : if (m_aTextAppendStack.empty())
4473 5645 : return;
4474 5645 : uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
4475 5645 : BookmarkMap_t::iterator aBookmarkIter = m_aBookmarkMap.find( rId );
4476 : //is the bookmark name already registered?
4477 : try
4478 : {
4479 5645 : if( aBookmarkIter != m_aBookmarkMap.end() )
4480 : {
4481 : static const char sBookmarkService[] = "com.sun.star.text.Bookmark";
4482 2736 : if (m_xTextFactory.is())
4483 : {
4484 2736 : uno::Reference< text::XTextContent > xBookmark( m_xTextFactory->createInstance( sBookmarkService ), uno::UNO_QUERY_THROW );
4485 5472 : uno::Reference< text::XTextCursor > xCursor;
4486 5472 : uno::Reference< text::XText > xText = aBookmarkIter->second.m_xTextRange->getText();
4487 2736 : if( aBookmarkIter->second.m_bIsStartOfText && !bIsAfterDummyPara)
4488 : {
4489 409 : xCursor = xText->createTextCursorByRange( xText->getStart() );
4490 : }
4491 : else
4492 : {
4493 2327 : xCursor = xText->createTextCursorByRange( aBookmarkIter->second.m_xTextRange );
4494 2327 : xCursor->goRight( 1, false );
4495 : }
4496 :
4497 2737 : xCursor->gotoRange( xTextAppend->getEnd(), true );
4498 : // A Paragraph was recently finished, and a new Paragraph has not been started as yet
4499 : // then move the bookmark-End to the earlier paragraph
4500 2735 : if (IsOutsideAParagraph())
4501 : {
4502 129 : xCursor->goLeft( 1, false );
4503 : }
4504 5470 : uno::Reference< container::XNamed > xBkmNamed( xBookmark, uno::UNO_QUERY_THROW );
4505 : assert(!aBookmarkIter->second.m_sBookmarkName.isEmpty());
4506 : //todo: make sure the name is not used already!
4507 2735 : xBkmNamed->setName( aBookmarkIter->second.m_sBookmarkName );
4508 5900 : xTextAppend->insertTextContent( uno::Reference< text::XTextRange >( xCursor, uno::UNO_QUERY_THROW), xBookmark, !xCursor->isCollapsed() );
4509 : }
4510 2306 : m_aBookmarkMap.erase( aBookmarkIter );
4511 2306 : m_sCurrentBkmkId.clear();
4512 : }
4513 : else
4514 : {
4515 : //otherwise insert a text range as marker
4516 2909 : bool bIsStart = true;
4517 2909 : uno::Reference< text::XTextRange > xCurrent;
4518 2909 : if (xTextAppend.is())
4519 : {
4520 2909 : uno::Reference< text::XTextCursor > xCursor = xTextAppend->createTextCursorByRange( xTextAppend->getEnd() );
4521 :
4522 2909 : if(!bIsAfterDummyPara)
4523 2863 : bIsStart = !xCursor->goLeft(1, false);
4524 2909 : xCurrent = xCursor->getStart();
4525 : }
4526 2909 : m_sCurrentBkmkId = rId;
4527 2909 : m_aBookmarkMap.insert(BookmarkMap_t::value_type( rId, BookmarkInsertPosition( bIsStart, m_sCurrentBkmkName, xCurrent ) ));
4528 2909 : m_sCurrentBkmkName.clear();
4529 : }
4530 : }
4531 430 : catch( const uno::Exception& )
4532 : {
4533 : //TODO: What happens to bookmarks where start and end are at different XText objects?
4534 5645 : }
4535 : }
4536 :
4537 40 : void DomainMapper_Impl::AddAnnotationPosition(
4538 : const bool bStart,
4539 : const sal_Int32 nAnnotationId)
4540 : {
4541 40 : if (m_aTextAppendStack.empty())
4542 40 : return;
4543 :
4544 : // Create a cursor, pointing to the current position.
4545 40 : uno::Reference<text::XTextAppend> xTextAppend = m_aTextAppendStack.top().xTextAppend;
4546 80 : uno::Reference<text::XTextRange> xCurrent;
4547 40 : if (xTextAppend.is())
4548 : {
4549 40 : uno::Reference<text::XTextCursor> xCursor;
4550 40 : if (m_bIsNewDoc)
4551 38 : xCursor = xTextAppend->createTextCursorByRange(xTextAppend->getEnd());
4552 : else
4553 2 : xCursor = m_aTextAppendStack.top().xCursor;
4554 40 : if (xCursor.is())
4555 40 : xCurrent = xCursor->getStart();
4556 : }
4557 :
4558 : // And save it, to be used by PopAnnotation() later.
4559 40 : AnnotationPosition& aAnnotationPosition = m_aAnnotationPositions[ nAnnotationId ];
4560 40 : if (bStart)
4561 : {
4562 20 : aAnnotationPosition.m_xStart = xCurrent;
4563 : }
4564 : else
4565 : {
4566 20 : aAnnotationPosition.m_xEnd = xCurrent;
4567 : }
4568 80 : m_aAnnotationPositions[ nAnnotationId ] = aAnnotationPosition;
4569 : }
4570 :
4571 2746 : GraphicImportPtr DomainMapper_Impl::GetGraphicImport(GraphicImportType eGraphicImportType)
4572 : {
4573 2746 : if(!m_pGraphicImport)
4574 1373 : m_pGraphicImport.reset( new GraphicImport( m_xComponentContext, m_xTextFactory, m_rDMapper, eGraphicImportType, m_aPositionOffsets, m_aAligns, m_aPositivePercentages ) );
4575 2746 : return m_pGraphicImport;
4576 : }
4577 : /*-------------------------------------------------------------------------
4578 : reset graphic import if the last import resulted in a shape, not a graphic
4579 : -----------------------------------------------------------------------*/
4580 0 : void DomainMapper_Impl::ResetGraphicImport()
4581 : {
4582 0 : m_pGraphicImport.reset();
4583 0 : }
4584 :
4585 :
4586 1373 : void DomainMapper_Impl::ImportGraphic(writerfilter::Reference< Properties >::Pointer_t ref, GraphicImportType eGraphicImportType)
4587 : {
4588 1373 : GetGraphicImport(eGraphicImportType);
4589 1373 : if( eGraphicImportType != IMPORT_AS_DETECTED_INLINE && eGraphicImportType != IMPORT_AS_DETECTED_ANCHOR )
4590 : {
4591 : //create the graphic
4592 0 : ref->resolve( *m_pGraphicImport );
4593 : }
4594 :
4595 : //insert it into the document at the current cursor position
4596 :
4597 : uno::Reference<text::XTextContent> xTextContent
4598 1373 : (m_pGraphicImport->GetGraphicObject());
4599 :
4600 : // In case the SDT starts with the text portion of the graphic, then set the SDT properties here.
4601 1373 : bool bHasGrabBag = false;
4602 2746 : uno::Reference<beans::XPropertySet> xPropertySet(xTextContent, uno::UNO_QUERY);
4603 1373 : if (xPropertySet.is())
4604 : {
4605 1369 : uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
4606 1369 : bHasGrabBag = xPropertySetInfo->hasPropertyByName("FrameInteropGrabBag");
4607 : // In case we're outside a paragraph, then the SDT properties are stored in the paragraph grab-bag, not the frame one.
4608 1369 : if (!m_pSdtHelper->isInteropGrabBagEmpty() && bHasGrabBag && !m_pSdtHelper->isOutsideAParagraph())
4609 : {
4610 7 : comphelper::SequenceAsHashMap aFrameGrabBag(xPropertySet->getPropertyValue("FrameInteropGrabBag"));
4611 7 : aFrameGrabBag["SdtPr"] = uno::makeAny(m_pSdtHelper->getInteropGrabBagAndClear());
4612 7 : xPropertySet->setPropertyValue("FrameInteropGrabBag", uno::makeAny(aFrameGrabBag.getAsConstPropertyValueList()));
4613 1369 : }
4614 : }
4615 :
4616 : /* Set "SdtEndBefore" property on Drawing.
4617 : * It is required in a case when Drawing appears immediately after first run i.e.
4618 : * there is no text/space/tab in between two runs.
4619 : * In this case "SdtEndBefore" property needs to be set on Drawing.
4620 : */
4621 1373 : if(IsSdtEndBefore())
4622 : {
4623 15 : if(xPropertySet.is())
4624 : {
4625 15 : if (bHasGrabBag)
4626 : {
4627 8 : uno::Sequence<beans::PropertyValue> aFrameGrabBag(1);
4628 16 : beans::PropertyValue aRet;
4629 8 : aRet.Name = "SdtEndBefore";
4630 8 : aRet.Value <<= uno::makeAny(true);
4631 8 : aFrameGrabBag[0] = aRet;
4632 16 : xPropertySet->setPropertyValue("FrameInteropGrabBag",uno::makeAny(aFrameGrabBag));
4633 : }
4634 : }
4635 : }
4636 :
4637 :
4638 : // Update the shape properties if it is embedded object.
4639 1373 : if(m_xEmbedded.is()){
4640 86 : UpdateEmbeddedShapeProps(m_pGraphicImport->GetXShapeObject());
4641 : }
4642 : //insert it into the document at the current cursor position
4643 : OSL_ENSURE( xTextContent.is(), "DomainMapper_Impl::ImportGraphic");
4644 1373 : if( xTextContent.is())
4645 1369 : appendTextContent( xTextContent, uno::Sequence< beans::PropertyValue >() );
4646 :
4647 : // Clear the reference, so in case the embedded object is inside a
4648 : // TextFrame, we won't try to resize it (to match the size of the
4649 : // TextFrame) here.
4650 1373 : m_xEmbedded.clear();
4651 2746 : m_pGraphicImport.reset();
4652 1373 : }
4653 :
4654 :
4655 :
4656 27 : void DomainMapper_Impl::SetLineNumbering( sal_Int32 nLnnMod, sal_uInt32 nLnc, sal_Int32 ndxaLnn )
4657 : {
4658 27 : if( !m_bLineNumberingSet )
4659 : {
4660 9 : const PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
4661 :
4662 : try
4663 : {
4664 9 : uno::Reference< text::XLineNumberingProperties > xLineProperties( m_xTextDocument, uno::UNO_QUERY_THROW );
4665 18 : uno::Reference< beans::XPropertySet > xProperties = xLineProperties->getLineNumberingProperties();
4666 18 : uno::Any aTrue( uno::makeAny( true ));
4667 9 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_IS_ON ), aTrue);
4668 9 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_COUNT_EMPTY_LINES ), aTrue );
4669 9 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_COUNT_LINES_IN_FRAMES ), uno::makeAny( false ) );
4670 9 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_INTERVAL ), uno::makeAny( static_cast< sal_Int16 >( nLnnMod )));
4671 9 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_DISTANCE ), uno::makeAny( ConversionHelper::convertTwipToMM100(ndxaLnn) ));
4672 9 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_NUMBER_POSITION ), uno::makeAny( style::LineNumberPosition::LEFT));
4673 9 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_NUMBERING_TYPE ), uno::makeAny( style::NumberingType::ARABIC));
4674 18 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_RESTART_AT_EACH_PAGE ), uno::makeAny( nLnc == NS_ooxml::LN_Value_ST_LineNumberRestart_newPage ));
4675 : }
4676 0 : catch( const uno::Exception& )
4677 : {}
4678 : }
4679 27 : m_bLineNumberingSet = true;
4680 27 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
4681 27 : uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier( GetTextDocument(), uno::UNO_QUERY_THROW );
4682 54 : uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies();
4683 54 : uno::Reference<container::XNameContainer> xStyles;
4684 27 : xStyleFamilies->getByName(rPropNameSupplier.GetName( PROP_PARAGRAPH_STYLES )) >>= xStyles;
4685 27 : lcl_linenumberingHeaderFooter( rPropNameSupplier, xStyles, "Header", this );
4686 54 : lcl_linenumberingHeaderFooter( rPropNameSupplier, xStyles, "Footer", this );
4687 27 : }
4688 :
4689 :
4690 12721 : void DomainMapper_Impl::SetPageMarginTwip( PageMarElement eElement, sal_Int32 nValue )
4691 : {
4692 12721 : nValue = ConversionHelper::convertTwipToMM100(nValue);
4693 12721 : switch(eElement)
4694 : {
4695 1887 : case PAGE_MAR_TOP : m_aPageMargins.top = nValue; break;
4696 1890 : case PAGE_MAR_RIGHT : m_aPageMargins.right = nValue; break;
4697 1886 : case PAGE_MAR_BOTTOM : m_aPageMargins.bottom = nValue; break;
4698 1890 : case PAGE_MAR_LEFT : m_aPageMargins.left = nValue; break;
4699 1737 : case PAGE_MAR_HEADER : m_aPageMargins.header = nValue; break;
4700 1738 : case PAGE_MAR_FOOTER : m_aPageMargins.footer = nValue; break;
4701 1693 : case PAGE_MAR_GUTTER : m_aPageMargins.gutter = nValue; break;
4702 : }
4703 12721 : }
4704 :
4705 :
4706 :
4707 3877 : _PageMar::_PageMar()
4708 : {
4709 3877 : header = footer = ConversionHelper::convertTwipToMM100(sal_Int32(720));
4710 3877 : top = bottom = ConversionHelper::convertTwipToMM100( sal_Int32(1440));
4711 : // This is strange, the RTF spec says it's 1800, but it's clearly 1440 in Word
4712 : // OOXML seems not to specify a default value
4713 3877 : right = left = ConversionHelper::convertTwipToMM100( sal_Int32(1440));
4714 3877 : gutter = 0;
4715 3877 : }
4716 :
4717 :
4718 :
4719 97 : void DomainMapper_Impl::RegisterFrameConversion(
4720 : uno::Reference< text::XTextRange > const& xFrameStartRange,
4721 : uno::Reference< text::XTextRange > const& xFrameEndRange,
4722 : const std::vector<beans::PropertyValue>& rFrameProperties
4723 : )
4724 : {
4725 : OSL_ENSURE(
4726 : m_aFrameProperties.empty() && !m_xFrameStartRange.is() && !m_xFrameEndRange.is(),
4727 : "frame properties not removed");
4728 97 : m_aFrameProperties = rFrameProperties;
4729 97 : m_xFrameStartRange = xFrameStartRange;
4730 97 : m_xFrameEndRange = xFrameEndRange;
4731 97 : }
4732 :
4733 :
4734 34810 : bool DomainMapper_Impl::ExecuteFrameConversion()
4735 : {
4736 34810 : bool bRet = false;
4737 34810 : if( m_xFrameStartRange.is() && m_xFrameEndRange.is() && !m_bDiscardHeaderFooter )
4738 : {
4739 78 : bRet = true;
4740 : try
4741 : {
4742 78 : uno::Reference< text::XTextAppendAndConvert > xTextAppendAndConvert( GetTopTextAppend(), uno::UNO_QUERY_THROW );
4743 78 : xTextAppendAndConvert->convertToTextFrame(
4744 : m_xFrameStartRange,
4745 : m_xFrameEndRange,
4746 82 : comphelper::containerToSequence(m_aFrameProperties) );
4747 : }
4748 8 : catch( const uno::Exception& rEx)
4749 : {
4750 : SAL_WARN( "writerfilter", "Exception caught when converting to frame: " + rEx.Message );
4751 4 : bRet = false;
4752 : }
4753 : }
4754 34810 : m_xFrameStartRange = nullptr;
4755 34810 : m_xFrameEndRange = nullptr;
4756 34810 : m_aFrameProperties.clear();
4757 34810 : return bRet;
4758 : }
4759 :
4760 993 : void DomainMapper_Impl::AddNewRedline( sal_uInt32 sprmId )
4761 : {
4762 993 : RedlineParamsPtr pNew( new RedlineParams );
4763 993 : pNew->m_nToken = XML_mod;
4764 993 : if ( !m_bIsParaMarkerChange )
4765 : {
4766 : // <w:rPrChange> applies to the whole <w:r>, <w:pPrChange> applies to the whole <w:p>,
4767 : // so keep those two in CONTEXT_CHARACTERS and CONTEXT_PARAGRAPH, which will take
4768 : // care of their scope (i.e. when they should be used and discarded).
4769 : // Let's keep the rest the same way they used to be handled (explicitly dropped
4770 : // from a global stack by endtrackchange), but quite possibly they should not be handled
4771 : // that way either (I don't know).
4772 769 : if( sprmId == NS_ooxml::LN_EG_RPrContent_rPrChange )
4773 462 : GetTopContextOfType( CONTEXT_CHARACTER )->Redlines().push_back( pNew );
4774 307 : else if( sprmId == NS_ooxml::LN_CT_PPr_pPrChange )
4775 138 : GetTopContextOfType( CONTEXT_PARAGRAPH )->Redlines().push_back( pNew );
4776 : else
4777 169 : m_aRedlines.top().push_back( pNew );
4778 : }
4779 : else
4780 : {
4781 224 : m_pParaMarkerRedline = pNew;
4782 : }
4783 : // Newly read data will go into this redline.
4784 993 : m_currentRedline = pNew;
4785 993 : }
4786 :
4787 993 : void DomainMapper_Impl::SetCurrentRedlineIsRead()
4788 : {
4789 993 : m_currentRedline.reset();
4790 993 : }
4791 :
4792 993 : sal_Int32 DomainMapper_Impl::GetCurrentRedlineToken( )
4793 : {
4794 993 : sal_Int32 nToken = 0;
4795 : assert( m_currentRedline.get());
4796 993 : nToken = m_currentRedline->m_nToken;
4797 993 : return nToken;
4798 : }
4799 :
4800 1029 : void DomainMapper_Impl::SetCurrentRedlineAuthor( const OUString& sAuthor )
4801 : {
4802 1029 : if (!m_xAnnotationField.is())
4803 : {
4804 993 : if (m_currentRedline.get())
4805 993 : m_currentRedline->m_sAuthor = sAuthor;
4806 : else
4807 : SAL_INFO("writerfilter.dmapper", "numberingChange not implemented");
4808 : }
4809 : else
4810 36 : m_xAnnotationField->setPropertyValue("Author", uno::makeAny(sAuthor));
4811 1029 : }
4812 :
4813 35 : void DomainMapper_Impl::SetCurrentRedlineInitials( const OUString& sInitials )
4814 : {
4815 35 : if (m_xAnnotationField.is())
4816 35 : m_xAnnotationField->setPropertyValue("Initials", uno::makeAny(sInitials));
4817 35 : }
4818 :
4819 1012 : void DomainMapper_Impl::SetCurrentRedlineDate( const OUString& sDate )
4820 : {
4821 1012 : if (!m_xAnnotationField.is())
4822 : {
4823 976 : if (m_currentRedline.get())
4824 976 : m_currentRedline->m_sDate = sDate;
4825 : else
4826 : SAL_INFO("writerfilter.dmapper", "numberingChange not implemented");
4827 : }
4828 : else
4829 36 : m_xAnnotationField->setPropertyValue("DateTimeValue", uno::makeAny(ConversionHelper::ConvertDateStringToDateTime(sDate)));
4830 1012 : }
4831 :
4832 1061 : void DomainMapper_Impl::SetCurrentRedlineId( sal_Int32 sId )
4833 : {
4834 1061 : if (m_xAnnotationField.is())
4835 : {
4836 36 : m_nAnnotationId = sId;
4837 : }
4838 : else
4839 : {
4840 : // This should be an assert, but somebody had the smart idea to reuse this function also for comments and whatnot,
4841 : // and in some cases the id is actually not handled, which may be in fact a bug.
4842 1025 : if( m_currentRedline.get())
4843 991 : m_currentRedline->m_nId = sId;
4844 : else
4845 : SAL_INFO("writerfilter.dmapper", "no current redline");
4846 : }
4847 1061 : }
4848 :
4849 528 : void DomainMapper_Impl::SetCurrentRedlineToken( sal_Int32 nToken )
4850 : {
4851 : assert( m_currentRedline.get());
4852 528 : m_currentRedline->m_nToken = nToken;
4853 528 : }
4854 :
4855 599 : void DomainMapper_Impl::SetCurrentRedlineRevertProperties( const uno::Sequence<beans::PropertyValue>& aProperties )
4856 : {
4857 : assert( m_currentRedline.get());
4858 599 : m_currentRedline->m_aRevertProperties = aProperties;
4859 599 : }
4860 :
4861 :
4862 : // This removes only the last redline stored here, those stored in contexts are automatically removed when
4863 : // the context is destroyed.
4864 166 : void DomainMapper_Impl::RemoveTopRedline( )
4865 : {
4866 : assert( m_aRedlines.top().size( ) > 0 );
4867 166 : m_aRedlines.top().pop_back( );
4868 166 : m_currentRedline.reset();
4869 166 : }
4870 :
4871 117 : void DomainMapper_Impl::ResetParaMarkerRedline( )
4872 : {
4873 117 : if ( m_pParaMarkerRedline.get( ) )
4874 : {
4875 117 : m_pParaMarkerRedline.reset();
4876 117 : m_currentRedline.reset();
4877 : }
4878 117 : }
4879 :
4880 :
4881 1989 : void DomainMapper_Impl::ApplySettingsTable()
4882 : {
4883 1989 : if (m_pSettingsTable && m_xTextFactory.is())
4884 : {
4885 : try
4886 : {
4887 1967 : uno::Reference< beans::XPropertySet > xTextDefaults(m_xTextFactory->createInstance("com.sun.star.text.Defaults"), uno::UNO_QUERY_THROW );
4888 1967 : sal_Int32 nDefTab = m_pSettingsTable->GetDefaultTabStop();
4889 1967 : xTextDefaults->setPropertyValue( PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_TAB_STOP_DISTANCE ), uno::makeAny(nDefTab) );
4890 1967 : if (m_pSettingsTable->GetLinkStyles())
4891 : {
4892 8 : PropertyNameSupplier& rSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
4893 : // If linked styles are enabled, set paragraph defaults from Word's default template
4894 8 : xTextDefaults->setPropertyValue(rSupplier.GetName(PROP_PARA_BOTTOM_MARGIN), uno::makeAny(ConversionHelper::convertTwipToMM100(200)));
4895 8 : style::LineSpacing aSpacing;
4896 8 : aSpacing.Mode = style::LineSpacingMode::PROP;
4897 8 : aSpacing.Height = sal_Int16(115);
4898 8 : xTextDefaults->setPropertyValue(rSupplier.GetName(PROP_PARA_LINE_SPACING), uno::makeAny(aSpacing));
4899 : }
4900 :
4901 1967 : if (m_pSettingsTable->GetZoomFactor())
4902 : {
4903 1647 : uno::Sequence<beans::PropertyValue> aViewProps(3);
4904 1647 : aViewProps[0].Name = "ZoomFactor";
4905 1647 : aViewProps[0].Value <<= m_pSettingsTable->GetZoomFactor();
4906 1647 : aViewProps[1].Name = "VisibleBottom";
4907 1647 : aViewProps[1].Value <<= sal_Int32(0);
4908 1647 : aViewProps[2].Name = "ZoomType";
4909 1647 : aViewProps[2].Value <<= sal_Int16(0);
4910 :
4911 3294 : uno::Reference<container::XIndexContainer> xBox = document::IndexedPropertyValues::create(m_xComponentContext);
4912 1647 : xBox->insertByIndex(sal_Int32(0), uno::makeAny(aViewProps));
4913 3294 : uno::Reference<container::XIndexAccess> xIndexAccess(xBox, uno::UNO_QUERY);
4914 3294 : uno::Reference<document::XViewDataSupplier> xViewDataSupplier(m_xTextDocument, uno::UNO_QUERY);
4915 3294 : xViewDataSupplier->setViewData(xIndexAccess);
4916 : }
4917 :
4918 3934 : uno::Reference< beans::XPropertySet > xSettings(m_xTextFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY);
4919 1967 : if (m_pSettingsTable->GetUsePrinterMetrics())
4920 0 : xSettings->setPropertyValue("PrinterIndependentLayout", uno::makeAny(document::PrinterIndependentLayout::DISABLED));
4921 1967 : if( m_pSettingsTable->GetEmbedTrueTypeFonts())
4922 0 : xSettings->setPropertyValue( PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_EMBED_FONTS ), uno::makeAny(true) );
4923 1967 : if( m_pSettingsTable->GetEmbedSystemFonts())
4924 94 : xSettings->setPropertyValue( PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_EMBED_SYSTEM_FONTS ), uno::makeAny(true) );
4925 3934 : xSettings->setPropertyValue("AddParaTableSpacing", uno::makeAny(m_pSettingsTable->GetDoNotUseHTMLParagraphAutoSpacing()));
4926 : }
4927 0 : catch(const uno::Exception&)
4928 : {
4929 : }
4930 : }
4931 1989 : }
4932 :
4933 73355 : uno::Reference<container::XIndexAccess> DomainMapper_Impl::GetCurrentNumberingRules(sal_Int32* pListLevel)
4934 : {
4935 73355 : uno::Reference<container::XIndexAccess> xRet;
4936 : try
4937 : {
4938 73355 : OUString aStyle = GetCurrentParaStyleId();
4939 73355 : if (aStyle.isEmpty() || GetTopContextType() != CONTEXT_PARAGRAPH)
4940 58237 : return xRet;
4941 15159 : const StyleSheetEntryPtr pEntry = GetStyleSheetTable()->FindStyleSheetByISTD(aStyle);
4942 15118 : if (!pEntry)
4943 6996 : return xRet;
4944 8122 : const StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast<const StyleSheetPropertyMap*>(pEntry->pProperties.get());
4945 8122 : if (!pStyleSheetProperties)
4946 0 : return xRet;
4947 8122 : sal_Int32 nListId = pStyleSheetProperties->GetListId();
4948 8122 : if (nListId < 0)
4949 8081 : return xRet;
4950 41 : if (pListLevel)
4951 39 : *pListLevel = pStyleSheetProperties->GetListLevel();
4952 :
4953 : // So we are in a paragraph style and it has numbering. Look up the relevant numbering rules.
4954 82 : OUString aListName = ListDef::GetStyleName(nListId);
4955 82 : uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier(GetTextDocument(), uno::UNO_QUERY_THROW);
4956 82 : uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies();
4957 82 : uno::Reference<container::XNameAccess> xNumberingStyles;
4958 41 : xStyleFamilies->getByName("NumberingStyles") >>= xNumberingStyles;
4959 82 : uno::Reference<beans::XPropertySet> xStyle(xNumberingStyles->getByName(aListName), uno::UNO_QUERY);
4960 82 : xRet.set(xStyle->getPropertyValue("NumberingRules"), uno::UNO_QUERY);
4961 : }
4962 0 : catch (const uno::Exception& e)
4963 : {
4964 : SAL_WARN("writerfilter.dmapper",
4965 : "GetCurrentNumberingRules: exception caught: " << e.Message);
4966 : }
4967 41 : return xRet;
4968 : }
4969 :
4970 73353 : uno::Reference<beans::XPropertySet> DomainMapper_Impl::GetCurrentNumberingCharStyle()
4971 : {
4972 73353 : uno::Reference<beans::XPropertySet> xRet;
4973 : try
4974 : {
4975 73353 : sal_Int32 nListLevel = -1;
4976 73353 : uno::Reference<container::XIndexAccess> xLevels = GetCurrentNumberingRules(&nListLevel);
4977 73353 : if (!xLevels.is())
4978 : {
4979 : // Looking up the paragraph context explicitly (and not just taking
4980 : // the top context) is necessary for RTF, where formatting of a run
4981 : // and of the paragraph mark is not separated.
4982 73314 : PropertyMapPtr pContext = GetTopContextOfType(CONTEXT_PARAGRAPH);
4983 73314 : if (!pContext)
4984 27709 : return xRet;
4985 :
4986 : // In case numbering rules is not found via a style, try the direct formatting instead.
4987 50196 : boost::optional<PropertyMap::Property> oProp = pContext->getProperty(PROP_NUMBERING_RULES);
4988 45605 : if (oProp)
4989 : {
4990 4591 : xLevels.set(oProp->second, uno::UNO_QUERY);
4991 : // Found the rules, then also try to look up our numbering level.
4992 4591 : oProp = pContext->getProperty(PROP_NUMBERING_LEVEL);
4993 4591 : if (oProp)
4994 4583 : oProp->second >>= nListLevel;
4995 : else
4996 8 : nListLevel = 0;
4997 : }
4998 :
4999 45605 : if (!xLevels.is())
5000 45605 : return xRet;
5001 : }
5002 9260 : uno::Sequence<beans::PropertyValue> aProps;
5003 4630 : xLevels->getByIndex(nListLevel) >>= aProps;
5004 23085 : for (int i = 0; i < aProps.getLength(); ++i)
5005 : {
5006 23085 : const beans::PropertyValue& rProp = aProps[i];
5007 :
5008 23085 : if (rProp.Name == "CharStyleName")
5009 : {
5010 4617 : OUString aCharStyle;
5011 4617 : rProp.Value >>= aCharStyle;
5012 9234 : uno::Reference<container::XNameAccess> xCharacterStyles;
5013 9234 : uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier(GetTextDocument(), uno::UNO_QUERY);
5014 9234 : uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies();
5015 4617 : xStyleFamilies->getByName("CharacterStyles") >>= xCharacterStyles;
5016 4617 : xRet.set(xCharacterStyles->getByName(aCharStyle), uno::UNO_QUERY_THROW);
5017 6884 : break;
5018 : }
5019 4630 : }
5020 : }
5021 2363 : catch( const uno::Exception& )
5022 : {
5023 : }
5024 4630 : return xRet;
5025 : }
5026 :
5027 814680 : SectionPropertyMap * DomainMapper_Impl::GetSectionContext()
5028 : {
5029 814680 : SectionPropertyMap* pSectionContext = nullptr;
5030 : //the section context is not available before the first call of startSectionGroup()
5031 814680 : if( !IsAnyTableImport() )
5032 : {
5033 415939 : PropertyMapPtr pContext = GetTopContextOfType(CONTEXT_SECTION);
5034 : OSL_ENSURE(pContext.get(), "Section context is not in the stack!");
5035 415939 : pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() );
5036 : }
5037 :
5038 814680 : return pSectionContext;
5039 : }
5040 :
5041 48112 : void DomainMapper_Impl::deferCharacterProperty(sal_Int32 id, const css::uno::Any& value)
5042 : {
5043 48112 : deferredCharacterProperties[ id ] = value;
5044 48112 : }
5045 :
5046 16771 : void DomainMapper_Impl::processDeferredCharacterProperties()
5047 : {
5048 : // ACtually process in DomainMapper, so that it's the same source file like normal processing.
5049 16771 : if( !deferredCharacterProperties.empty())
5050 : {
5051 16771 : m_rDMapper.processDeferredCharacterProperties( deferredCharacterProperties );
5052 16771 : deferredCharacterProperties.clear();
5053 : }
5054 16771 : }
5055 :
5056 18885 : sal_Int32 DomainMapper_Impl::getCurrentNumberingProperty(const OUString& aProp)
5057 : {
5058 18885 : sal_Int32 nRet = 0;
5059 :
5060 18885 : boost::optional<PropertyMap::Property> pProp = m_pTopContext->getProperty(PROP_NUMBERING_RULES);
5061 37770 : uno::Reference<container::XIndexAccess> xNumberingRules;
5062 18885 : if (pProp)
5063 741 : xNumberingRules.set(pProp->second, uno::UNO_QUERY);
5064 18885 : pProp = m_pTopContext->getProperty(PROP_NUMBERING_LEVEL);
5065 18885 : sal_Int32 nNumberingLevel = -1;
5066 18885 : if (pProp)
5067 942 : pProp->second >>= nNumberingLevel;
5068 18885 : if (xNumberingRules.is() && nNumberingLevel != -1)
5069 : {
5070 729 : uno::Sequence<beans::PropertyValue> aProps;
5071 729 : xNumberingRules->getByIndex(nNumberingLevel) >>= aProps;
5072 7477 : for (int i = 0; i < aProps.getLength(); ++i)
5073 : {
5074 7477 : const beans::PropertyValue& rProp = aProps[i];
5075 :
5076 7477 : if (rProp.Name == aProp)
5077 : {
5078 729 : rProp.Value >>= nRet;
5079 729 : break;
5080 : }
5081 729 : }
5082 : }
5083 :
5084 37770 : return nRet;
5085 : }
5086 :
5087 :
5088 19018 : void DomainMapper_Impl::enableInteropGrabBag(const OUString& aName)
5089 : {
5090 19018 : m_aInteropGrabBagName = aName;
5091 19018 : }
5092 :
5093 19979 : void DomainMapper_Impl::disableInteropGrabBag()
5094 : {
5095 19979 : m_aInteropGrabBagName.clear();
5096 19979 : m_aInteropGrabBag.clear();
5097 19979 : m_aSubInteropGrabBag.clear();
5098 19979 : }
5099 :
5100 201817 : bool DomainMapper_Impl::isInteropGrabBagEnabled()
5101 : {
5102 201817 : return !(m_aInteropGrabBagName.isEmpty());
5103 : }
5104 :
5105 269720 : void DomainMapper_Impl::appendGrabBag(std::vector<beans::PropertyValue>& rInteropGrabBag, const OUString& aKey, const OUString& aValue)
5106 : {
5107 269720 : if (m_aInteropGrabBagName.isEmpty())
5108 488251 : return;
5109 51189 : beans::PropertyValue aProperty;
5110 51189 : aProperty.Name = aKey;
5111 51189 : aProperty.Value = uno::makeAny(aValue);
5112 51189 : rInteropGrabBag.push_back(aProperty);
5113 : }
5114 :
5115 131668 : void DomainMapper_Impl::appendGrabBag(std::vector<beans::PropertyValue>& rInteropGrabBag, const OUString& aKey, std::vector<beans::PropertyValue>& rValue)
5116 : {
5117 131668 : if (m_aInteropGrabBagName.isEmpty())
5118 261130 : return;
5119 2206 : beans::PropertyValue aProperty;
5120 2206 : aProperty.Name = aKey;
5121 :
5122 4412 : uno::Sequence<beans::PropertyValue> aSeq(rValue.size());
5123 2206 : beans::PropertyValue* pSeq = aSeq.getArray();
5124 7002 : for (std::vector<beans::PropertyValue>::iterator i = rValue.begin(); i != rValue.end(); ++i)
5125 4796 : *pSeq++ = *i;
5126 :
5127 2206 : rValue.clear();
5128 2206 : aProperty.Value = uno::makeAny(aSeq);
5129 4412 : rInteropGrabBag.push_back(aProperty);
5130 : }
5131 :
5132 1430 : void DomainMapper_Impl::substream(Id rName,
5133 : ::writerfilter::Reference<Stream>::Pointer_t const& ref)
5134 : {
5135 : #ifndef NDEBUG
5136 : size_t contextSize(m_aContextStack.size());
5137 : size_t propSize[NUMBER_OF_CONTEXTS];
5138 : for (int i = 0; i < NUMBER_OF_CONTEXTS; ++i) {
5139 : propSize[i] = m_aPropertyStacks[i].size();
5140 : }
5141 : #endif
5142 :
5143 1430 : appendTableManager();
5144 : // Appending a TableManager resets its TableHandler, so we need to append
5145 : // that as well, or tables won't be imported properly in headers/footers.
5146 1430 : appendTableHandler();
5147 1430 : getTableManager().startLevel();
5148 :
5149 : //import of page header/footer
5150 :
5151 1430 : switch( rName )
5152 : {
5153 : case NS_ooxml::LN_headerl:
5154 :
5155 159 : PushPageHeader(SectionPropertyMap::PAGE_LEFT);
5156 159 : break;
5157 : case NS_ooxml::LN_headerr:
5158 :
5159 329 : PushPageHeader(SectionPropertyMap::PAGE_RIGHT);
5160 329 : break;
5161 : case NS_ooxml::LN_headerf:
5162 :
5163 174 : PushPageHeader(SectionPropertyMap::PAGE_FIRST);
5164 174 : break;
5165 : case NS_ooxml::LN_footerl:
5166 :
5167 159 : PushPageFooter(SectionPropertyMap::PAGE_LEFT);
5168 159 : break;
5169 : case NS_ooxml::LN_footerr:
5170 :
5171 361 : PushPageFooter(SectionPropertyMap::PAGE_RIGHT);
5172 361 : break;
5173 : case NS_ooxml::LN_footerf:
5174 :
5175 155 : PushPageFooter(SectionPropertyMap::PAGE_FIRST);
5176 155 : break;
5177 : case NS_ooxml::LN_footnote:
5178 : case NS_ooxml::LN_endnote:
5179 56 : PushFootOrEndnote( NS_ooxml::LN_footnote == rName );
5180 56 : break;
5181 : case NS_ooxml::LN_annotation :
5182 37 : PushAnnotation();
5183 37 : break;
5184 : }
5185 1430 : ref->resolve(m_rDMapper);
5186 1430 : switch( rName )
5187 : {
5188 : case NS_ooxml::LN_headerl:
5189 : case NS_ooxml::LN_headerr:
5190 : case NS_ooxml::LN_headerf:
5191 : case NS_ooxml::LN_footerl:
5192 : case NS_ooxml::LN_footerr:
5193 : case NS_ooxml::LN_footerf:
5194 1337 : PopPageHeaderFooter();
5195 1337 : break;
5196 : case NS_ooxml::LN_footnote:
5197 : case NS_ooxml::LN_endnote:
5198 56 : PopFootOrEndnote();
5199 56 : break;
5200 : case NS_ooxml::LN_annotation :
5201 37 : PopAnnotation();
5202 37 : break;
5203 : }
5204 :
5205 1430 : getTableManager().endLevel();
5206 1430 : popTableManager();
5207 :
5208 : // check that stacks are the same as before substream
5209 : assert(m_aContextStack.size() == contextSize);
5210 1430 : for (int i = 0; i < NUMBER_OF_CONTEXTS; ++i) {
5211 : assert(m_aPropertyStacks[i].size() == propSize[i]);
5212 : }
5213 1430 : }
5214 :
5215 : }}
5216 :
5217 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|