fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / writerfilter / source / dmapper / DomainMapper_Impl.cxx
blob21416e29c703b6790e4d051be447e9129ecafe73
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <DomainMapper_Impl.hxx>
21 #include <ConversionHelper.hxx>
22 #include <SdtHelper.hxx>
23 #include <DomainMapperTableHandler.hxx>
24 #include <com/sun/star/uno/XComponentContext.hpp>
25 #include <com/sun/star/graphic/XGraphic.hpp>
26 #include <com/sun/star/beans/XPropertyState.hpp>
27 #include <com/sun/star/container/XNamed.hpp>
28 #include <com/sun/star/document/PrinterIndependentLayout.hpp>
29 #include <com/sun/star/document/IndexedPropertyValues.hpp>
30 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
31 #include <com/sun/star/lang/XServiceInfo.hpp>
32 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
33 #include <com/sun/star/style/LineNumberPosition.hpp>
34 #include <com/sun/star/style/LineSpacing.hpp>
35 #include <com/sun/star/style/LineSpacingMode.hpp>
36 #include <com/sun/star/text/ChapterFormat.hpp>
37 #include <com/sun/star/text/FilenameDisplayFormat.hpp>
38 #include <com/sun/star/text/SetVariableType.hpp>
39 #include <com/sun/star/text/XFootnote.hpp>
40 #include <com/sun/star/text/XLineNumberingProperties.hpp>
41 #include <com/sun/star/text/PageNumberType.hpp>
42 #include <com/sun/star/text/HoriOrientation.hpp>
43 #include <com/sun/star/text/VertOrientation.hpp>
44 #include <com/sun/star/text/ReferenceFieldPart.hpp>
45 #include <com/sun/star/text/ReferenceFieldSource.hpp>
46 #include <com/sun/star/text/SizeType.hpp>
47 #include <com/sun/star/text/TextContentAnchorType.hpp>
48 #include <com/sun/star/text/WrapTextMode.hpp>
49 #include <com/sun/star/text/XDependentTextField.hpp>
50 #include <com/sun/star/text/XParagraphCursor.hpp>
51 #include <com/sun/star/text/XRedline.hpp>
52 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
53 #include <com/sun/star/style/DropCapFormat.hpp>
54 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
55 #include <com/sun/star/document/XViewDataSupplier.hpp>
56 #include <com/sun/star/container/XIndexContainer.hpp>
57 #include <com/sun/star/awt/XControlModel.hpp>
58 #include <com/sun/star/drawing/XControlShape.hpp>
59 #include <oox/mathml/import.hxx>
61 #ifdef DEBUG_DOMAINMAPPER
62 #include <resourcemodel/QNameToString.hxx>
63 #include <resourcemodel/util.hxx>
64 #include <dmapperLoggers.hxx>
65 #endif
66 #include <ooxml/OOXMLFastTokens.hxx>
68 #include <map>
70 #include <comphelper/configurationhelper.hxx>
71 #include <comphelper/stlunosequence.hxx>
72 #include <vcl/svapp.hxx>
73 #include <vcl/outdev.hxx>
74 #include <filter/msfilter/util.hxx>
76 using namespace ::com::sun::star;
77 using namespace ::rtl;
78 namespace writerfilter {
79 namespace dmapper{
81 sal_Bool lcl_IsUsingEnhancedFields( const uno::Reference< uno::XComponentContext >& rxContext )
83 bool bResult(sal_False);
84 try
86 OUString writerConfig = "org.openoffice.Office.Common";
88 uno::Reference< uno::XInterface > xCfgAccess = ::comphelper::ConfigurationHelper::openConfig( rxContext, writerConfig, ::comphelper::ConfigurationHelper::E_READONLY );
89 ::comphelper::ConfigurationHelper::readRelativeKey( xCfgAccess, OUString( "Filter/Microsoft/Import" ), OUString( "ImportWWFieldsAsEnhancedFields" ) ) >>= bResult;
92 catch( const uno::Exception& )
95 return bResult;
98 // Populate Dropdown Field properties from FFData structure
99 void lcl_handleDropdownField( const uno::Reference< beans::XPropertySet >& rxFieldProps, FFDataHandler::Pointer_t pFFDataHandler )
101 if ( rxFieldProps.is() )
103 if ( !pFFDataHandler->getName().isEmpty() )
104 rxFieldProps->setPropertyValue( "Name", uno::makeAny( pFFDataHandler->getName() ) );
106 const FFDataHandler::DropDownEntries_t& rEntries = pFFDataHandler->getDropDownEntries();
107 uno::Sequence< OUString > sItems( rEntries.size() );
108 ::std::copy( rEntries.begin(), rEntries.end(), ::comphelper::stl_begin(sItems));
109 if ( sItems.getLength() )
110 rxFieldProps->setPropertyValue( "Items", uno::makeAny( sItems ) );
112 sal_Int32 nResult = pFFDataHandler->getDropDownResult().toInt32();
113 if ( nResult )
114 rxFieldProps->setPropertyValue( "SelectedItem", uno::makeAny( sItems[ nResult ] ) );
115 if ( !pFFDataHandler->getHelpText().isEmpty() )
116 rxFieldProps->setPropertyValue( "Help", uno::makeAny( pFFDataHandler->getHelpText() ) );
120 void lcl_handleTextField( const uno::Reference< beans::XPropertySet >& rxFieldProps, FFDataHandler::Pointer_t pFFDataHandler, PropertyNameSupplier& rPropNameSupplier )
122 if ( rxFieldProps.is() && pFFDataHandler )
124 rxFieldProps->setPropertyValue
125 (rPropNameSupplier.GetName(PROP_HINT),
126 uno::makeAny(pFFDataHandler->getStatusText()));
127 rxFieldProps->setPropertyValue
128 (rPropNameSupplier.GetName(PROP_HELP),
129 uno::makeAny(pFFDataHandler->getHelpText()));
130 rxFieldProps->setPropertyValue
131 (rPropNameSupplier.GetName(PROP_CONTENT),
132 uno::makeAny(pFFDataHandler->getTextDefault()));
136 struct FieldConversion
138 OUString sWordCommand;
139 const sal_Char* cFieldServiceName;
140 const sal_Char* cFieldMasterServiceName;
141 FieldId eFieldId;
144 typedef ::std::map< OUString, FieldConversion>
145 FieldConversionMap_t;
148 void FIB::SetData( Id nName, sal_Int32 nValue )
150 OSL_ENSURE( nName >= NS_rtf::LN_WIDENT && nName <= NS_rtf::LN_LCBSTTBFUSSR, "invalid index in FIB");
151 if( nName >= NS_rtf::LN_WIDENT && nName <= NS_rtf::LN_LCBSTTBFUSSR)
152 aFIBData[nName - NS_rtf::LN_WIDENT] = nValue;
156 DomainMapper_Impl::DomainMapper_Impl(
157 DomainMapper& rDMapper,
158 uno::Reference < uno::XComponentContext > xContext,
159 uno::Reference< lang::XComponent > xModel,
160 SourceDocumentType eDocumentType,
161 uno::Reference< text::XTextRange > xInsertTextRange,
162 bool bIsNewDoc) :
163 m_eDocumentType( eDocumentType ),
164 m_rDMapper( rDMapper ),
165 m_xTextDocument( xModel, uno::UNO_QUERY ),
166 m_xTextFactory( xModel, uno::UNO_QUERY ),
167 m_xComponentContext( xContext ),
168 m_bSetUserFieldContent( false ),
169 m_bIsFirstSection( true ),
170 m_bIsColumnBreakDeferred( false ),
171 m_bIsPageBreakDeferred( false ),
172 m_pLastSectionContext( ),
173 m_pLastCharacterContext(),
174 m_nCurrentTabStopIndex( 0 ),
175 m_sCurrentParaStyleId(),
176 m_bInStyleSheetImport( false ),
177 m_bInAnyTableImport( false ),
178 m_bInHeaderFooterImport( false ),
179 m_bLineNumberingSet( false ),
180 m_bIsInFootnoteProperties( true ),
181 m_bIsCustomFtnMark( false ),
182 m_bIsParaChange( false ),
183 m_bParaChanged( false ),
184 m_bIsFirstParaInSection( true ),
185 m_bIsLastParaInSection( false ),
186 m_bIsInComments( false ),
187 m_bParaSectpr( false ),
188 m_bUsingEnhancedFields( false ),
189 m_bSdt(false),
190 m_xInsertTextRange(xInsertTextRange),
191 m_bIsNewDoc(bIsNewDoc),
192 m_bInTableStyleRunProps(false),
193 m_pSdtHelper(0),
194 m_nTableDepth(0)
197 appendTableManager( );
198 GetBodyText();
199 uno::Reference< text::XTextAppend > xBodyTextAppend = uno::Reference< text::XTextAppend >( m_xBodyText, uno::UNO_QUERY );
200 m_aTextAppendStack.push(TextAppendContext(xBodyTextAppend,
201 m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(m_xInsertTextRange)));
203 //todo: does it make sense to set the body text as static text interface?
204 uno::Reference< text::XTextAppendAndConvert > xBodyTextAppendAndConvert( m_xBodyText, uno::UNO_QUERY );
205 m_pTableHandler.reset
206 (new DomainMapperTableHandler(xBodyTextAppendAndConvert, *this));
207 getTableManager( ).setHandler(m_pTableHandler);
209 getTableManager( ).startLevel();
210 m_bUsingEnhancedFields = lcl_IsUsingEnhancedFields( m_xComponentContext );
212 m_pSdtHelper = new SdtHelper(*this);
214 m_aRedlines.push(std::vector<RedlineParamsPtr>());
218 DomainMapper_Impl::~DomainMapper_Impl()
220 RemoveLastParagraph( );
221 getTableManager( ).endLevel();
222 popTableManager( );
223 delete m_pSdtHelper;
227 uno::Reference< container::XNameContainer > DomainMapper_Impl::GetPageStyles()
229 if(!m_xPageStyles.is())
231 uno::Reference< style::XStyleFamiliesSupplier > xSupplier( m_xTextDocument, uno::UNO_QUERY );
232 if (xSupplier.is())
233 xSupplier->getStyleFamilies()->getByName("PageStyles") >>= m_xPageStyles;
235 return m_xPageStyles;
239 uno::Reference< text::XText > DomainMapper_Impl::GetBodyText()
241 if(!m_xBodyText.is())
243 if (m_xInsertTextRange.is())
244 m_xBodyText = m_xInsertTextRange->getText();
245 else if (m_xTextDocument.is())
246 m_xBodyText = m_xTextDocument->getText();
248 return m_xBodyText;
252 uno::Reference< beans::XPropertySet > DomainMapper_Impl::GetDocumentSettings()
254 if( !m_xDocumentSettings.is() && m_xTextFactory.is())
256 m_xDocumentSettings = uno::Reference< beans::XPropertySet >(
257 m_xTextFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY );
259 return m_xDocumentSettings;
263 void DomainMapper_Impl::SetDocumentSettingsProperty( const OUString& rPropName, const uno::Any& rValue )
265 uno::Reference< beans::XPropertySet > xSettings = GetDocumentSettings();
266 if( xSettings.is() )
270 xSettings->setPropertyValue( rPropName, rValue );
272 catch( const uno::Exception& )
278 void DomainMapper_Impl::RemoveLastParagraph( )
280 if (m_aTextAppendStack.empty())
281 return;
282 uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
283 if (!xTextAppend.is())
284 return;
287 uno::Reference< text::XTextCursor > xCursor;
288 if (m_bIsNewDoc)
290 xCursor = xTextAppend->createTextCursor();
291 xCursor->gotoEnd(false);
293 else
294 xCursor.set(m_aTextAppendStack.top().xCursor, uno::UNO_QUERY);
295 uno::Reference<container::XEnumerationAccess> xEnumerationAccess(xCursor, uno::UNO_QUERY);
296 // Keep the character properties of the last but one paragraph, even if
297 // it's empty. This works for headers/footers, and maybe in other cases
298 // as well, but surely not in textboxes.
299 // fdo#58327: also do this at the end of the document: when pasting,
300 // a table before the cursor position would be deleted
301 // (but only for paste/insert, not load; otherwise it can happen that
302 // flys anchored at the disposed paragraph are deleted (fdo47036.rtf))
303 bool const bEndOfDocument(m_aTextAppendStack.size() == 1);
304 if ((m_bInHeaderFooterImport || (bEndOfDocument && !m_bIsNewDoc))
305 && xEnumerationAccess.is())
307 uno::Reference<container::XEnumeration> xEnumeration = xEnumerationAccess->createEnumeration();
308 uno::Reference<lang::XComponent> xParagraph(xEnumeration->nextElement(), uno::UNO_QUERY);
309 xParagraph->dispose();
311 else if (xCursor.is())
313 xCursor->goLeft( 1, true );
314 // If this is a text on a shape, possibly the text has the trailing
315 // newline removed already.
316 #if defined(UNX)
317 if (xCursor->getString() == "\n")
318 #else
319 if (xCursor->getString() == "\r\n")
320 #endif
322 uno::Reference<beans::XPropertySet> xDocProps(GetTextDocument(), uno::UNO_QUERY);
323 const OUString aRecordChanges("RecordChanges");
324 uno::Any aPreviousValue(xDocProps->getPropertyValue(aRecordChanges));
326 // disable redlining for this operation, otherwise we might
327 // end up with an unwanted recorded deletion
328 xDocProps->setPropertyValue(aRecordChanges, uno::Any(sal_False));
330 // delete
331 xCursor->setString(OUString());
333 // restore again
334 xDocProps->setPropertyValue(aRecordChanges, aPreviousValue);
338 catch( const uno::Exception& )
343 void DomainMapper_Impl::SetIsLastParagraphInSection( bool bIsLast )
345 m_bIsLastParaInSection = bIsLast;
348 bool DomainMapper_Impl::GetIsLastParagraphInSection()
350 return m_bIsLastParaInSection;
353 void DomainMapper_Impl::SetIsFirstParagraphInSection( bool bIsFirst )
355 m_bIsFirstParaInSection = bIsFirst;
358 bool DomainMapper_Impl::GetIsFirstParagraphInSection()
360 return m_bIsFirstParaInSection;
363 void DomainMapper_Impl::SetParaSectpr(bool bParaSectpr)
365 m_bParaSectpr = bParaSectpr;
368 bool DomainMapper_Impl::GetParaSectpr()
370 return m_bParaSectpr;
373 void DomainMapper_Impl::SetSdt(bool bSdt)
375 m_bSdt = bSdt;
378 bool DomainMapper_Impl::GetSdt()
380 return m_bSdt;
383 bool DomainMapper_Impl::GetParaChanged()
385 return m_bParaChanged;
388 void DomainMapper_Impl::PushProperties(ContextType eId)
390 PropertyMapPtr pInsert(eId == CONTEXT_SECTION ?
391 (new SectionPropertyMap( m_bIsFirstSection )) :
392 eId == CONTEXT_PARAGRAPH ? new ParagraphPropertyMap : new PropertyMap);
393 if(eId == CONTEXT_SECTION)
395 if( m_bIsFirstSection )
396 m_bIsFirstSection = false;
397 // beginning with the second section group a section has to be inserted
398 // into the document
399 SectionPropertyMap* pSectionContext_ = dynamic_cast< SectionPropertyMap* >( pInsert.get() );
400 if (!m_aTextAppendStack.empty())
402 uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
403 if (xTextAppend.is())
404 pSectionContext_->SetStart( xTextAppend->getEnd() );
407 m_aPropertyStacks[eId].push( pInsert );
408 m_aContextStack.push(eId);
410 m_pTopContext = m_aPropertyStacks[eId].top();
414 void DomainMapper_Impl::PushStyleProperties( PropertyMapPtr pStyleProperties )
416 m_aPropertyStacks[CONTEXT_STYLESHEET].push( pStyleProperties );
417 m_aContextStack.push(CONTEXT_STYLESHEET);
419 m_pTopContext = m_aPropertyStacks[CONTEXT_STYLESHEET].top();
423 void DomainMapper_Impl::PushListProperties(PropertyMapPtr pListProperties)
425 m_aPropertyStacks[CONTEXT_LIST].push( pListProperties );
426 m_aContextStack.push(CONTEXT_LIST);
427 m_pTopContext = m_aPropertyStacks[CONTEXT_LIST].top();
431 void DomainMapper_Impl::PopProperties(ContextType eId)
433 OSL_ENSURE(!m_aPropertyStacks[eId].empty(), "section stack already empty");
434 if ( m_aPropertyStacks[eId].empty() )
435 return;
437 if ( eId == CONTEXT_SECTION )
439 m_pLastSectionContext = m_aPropertyStacks[eId].top( );
441 else if (eId == CONTEXT_CHARACTER)
443 m_pLastCharacterContext = m_aPropertyStacks[eId].top();
444 // Sadly an assert about deferredCharacterProperties being empty is not possible
445 // here, becase appendTextPortion() may not be called for every character section.
446 deferredCharacterProperties.clear();
449 m_aPropertyStacks[eId].pop();
450 m_aContextStack.pop();
451 if(!m_aContextStack.empty() && !m_aPropertyStacks[m_aContextStack.top()].empty())
453 m_pTopContext = m_aPropertyStacks[m_aContextStack.top()].top();
454 else
456 // OSL_ENSURE(eId == CONTEXT_SECTION, "this should happen at a section context end");
457 m_pTopContext.reset();
462 PropertyMapPtr DomainMapper_Impl::GetTopContextOfType(ContextType eId)
464 PropertyMapPtr pRet;
465 SAL_WARN_IF( m_aPropertyStacks[eId].empty(), "writerfilter",
466 "no context of type " << static_cast<int>(eId) << " available");
467 if(!m_aPropertyStacks[eId].empty())
468 pRet = m_aPropertyStacks[eId].top();
469 return pRet;
474 uno::Reference< text::XTextAppend > DomainMapper_Impl::GetTopTextAppend()
476 OSL_ENSURE(!m_aTextAppendStack.empty(), "text append stack is empty" );
477 return m_aTextAppendStack.top().xTextAppend;
482 void DomainMapper_Impl::InitTabStopFromStyle( const uno::Sequence< style::TabStop >& rInitTabStops )
484 OSL_ENSURE(!m_aCurrentTabStops.size(), "tab stops already initialized");
485 for( sal_Int32 nTab = 0; nTab < rInitTabStops.getLength(); ++nTab)
487 m_aCurrentTabStops.push_back( DeletableTabStop(rInitTabStops[nTab]) );
493 void DomainMapper_Impl::ModifyCurrentTabStop( Id nId, sal_Int32 nValue)
495 OSL_ENSURE(nId == NS_rtf::LN_dxaAdd || m_nCurrentTabStopIndex < m_aCurrentTabStops.size(),
496 "tab stop creation error");
498 if( nId != NS_rtf::LN_dxaAdd && m_nCurrentTabStopIndex >= m_aCurrentTabStops.size())
499 return;
500 static const style::TabAlign aTabAlignFromWord[] =
502 style::TabAlign_LEFT,
503 style::TabAlign_CENTER,
504 style::TabAlign_RIGHT,
505 style::TabAlign_DECIMAL,
506 style::TabAlign_LEFT
508 static const sal_Unicode aTabFillCharWord[] =
510 ' ',
511 '.',
512 '-',
513 '_',
514 '_',
515 0xb7
518 switch(nId)
520 case NS_rtf::LN_dxaAdd: //set tab
521 m_aCurrentTabStops.push_back(
522 DeletableTabStop(style::TabStop(ConversionHelper::convertTwipToMM100(nValue), style::TabAlign_LEFT, ' ', ' ')));
523 break;
524 case NS_rtf::LN_dxaDel: //deleted tab
526 //mark the tab stop at the given position as deleted
527 ::std::vector<DeletableTabStop>::iterator aIt = m_aCurrentTabStops.begin();
528 ::std::vector<DeletableTabStop>::iterator aEndIt = m_aCurrentTabStops.end();
529 sal_Int32 nConverted = ConversionHelper::convertTwipToMM100(nValue);
530 for( ; aIt != aEndIt; ++aIt)
532 if( aIt->Position == nConverted )
534 aIt->bDeleted = true;
535 break;
539 break;
540 case NS_rtf::LN_TLC: //tab leading characters - for decimal tabs
541 // 0 - no leader, 1- dotted, 2 - hyphenated, 3 - single line, 4 - heavy line, 5 - middle dot
542 if( nValue >= 0 && nValue < sal::static_int_cast<sal_Int32>(sizeof(aTabFillCharWord) / sizeof (sal_Unicode)))
543 m_aCurrentTabStops[m_nCurrentTabStopIndex].FillChar = aTabFillCharWord[nValue];
544 break;
545 case NS_rtf::LN_JC: //tab justification
546 //0 - left, 1 - centered, 2 - right, 3 - decimal 4 - bar
547 if( nValue >= 0 && nValue < sal::static_int_cast<sal_Int32>(sizeof(aTabAlignFromWord) / sizeof (style::TabAlign)))
548 m_aCurrentTabStops[m_nCurrentTabStopIndex].Alignment = aTabAlignFromWord[nValue];
549 break;
553 void DomainMapper_Impl::IncorporateTabStop( const DeletableTabStop & rTabStop )
555 ::std::vector<DeletableTabStop>::iterator aIt = m_aCurrentTabStops.begin();
556 ::std::vector<DeletableTabStop>::iterator aEndIt = m_aCurrentTabStops.end();
557 sal_Int32 nConverted = rTabStop.Position;
558 bool bFound = false;
559 for( ; aIt != aEndIt; ++aIt)
561 if( aIt->Position == nConverted )
563 bFound = true;
564 if( rTabStop.bDeleted )
565 m_aCurrentTabStops.erase( aIt );
566 else
567 *aIt = rTabStop;
568 break;
571 if( !bFound )
572 m_aCurrentTabStops.push_back( rTabStop );
576 uno::Sequence< style::TabStop > DomainMapper_Impl::GetCurrentTabStopAndClear()
578 uno::Sequence< style::TabStop > aRet( sal_Int32( m_aCurrentTabStops.size() ) );
579 style::TabStop* pArray = aRet.getArray();
580 ::std::vector<DeletableTabStop>::const_iterator aIt = m_aCurrentTabStops.begin();
581 ::std::vector<DeletableTabStop>::const_iterator aEndIt = m_aCurrentTabStops.end();
582 sal_Int32 nDeleted = 0;
583 for(sal_Int32 nIndex = 0; aIt != aEndIt; ++aIt)
585 if(!aIt->bDeleted)
586 pArray[nIndex++] = *aIt;
587 else
588 ++nDeleted;
590 m_aCurrentTabStops.clear();
591 m_nCurrentTabStopIndex = 0;
592 if(nDeleted)
594 aRet.realloc( aRet.getLength() - nDeleted);
596 return aRet;
599 /*-------------------------------------------------------------------------
600 returns a the value from the current paragraph style - if available
601 TODO: What about parent styles?
602 -----------------------------------------------------------------------*/
603 uno::Any DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId)
605 StyleSheetEntryPtr pEntry;
606 if( m_bInStyleSheetImport )
607 pEntry = GetStyleSheetTable()->FindParentStyleSheet(OUString());
608 else
609 pEntry =
610 GetStyleSheetTable()->FindStyleSheetByISTD(GetCurrentParaStyleId());
611 while(pEntry.get( ) )
613 //is there a tab stop set?
614 if(pEntry->pProperties)
616 PropertyMap::const_iterator aPropertyIter =
617 pEntry->pProperties->find(PropertyDefinition(eId, false ));
618 if( aPropertyIter != pEntry->pProperties->end())
620 return aPropertyIter->second;
623 //search until the property is set or no parent is available
624 StyleSheetEntryPtr pNewEntry = GetStyleSheetTable()->FindParentStyleSheet(pEntry->sBaseStyleIdentifier);
626 SAL_WARN_IF( pEntry == pNewEntry, "writerfilter", "circular loop in style hierarchy?");
628 if (pEntry == pNewEntry) //fdo#49587
629 break;
631 pEntry = pNewEntry;
633 return uno::Any();
637 ListsManager::Pointer DomainMapper_Impl::GetListTable()
639 if(!m_pListTable)
640 m_pListTable.reset(
641 new ListsManager( m_rDMapper, m_xTextFactory ));
642 return m_pListTable;
646 void DomainMapper_Impl::deferBreak( BreakType deferredBreakType)
648 switch (deferredBreakType)
650 case COLUMN_BREAK:
651 m_bIsColumnBreakDeferred = true;
652 break;
653 case PAGE_BREAK:
654 // See SwWW8ImplReader::HandlePageBreakChar(), page break should be
655 // ignored inside tables.
656 if (m_nTableDepth > 0)
657 return;
659 m_bIsPageBreakDeferred = true;
660 break;
661 default:
662 return;
666 bool DomainMapper_Impl::isBreakDeferred( BreakType deferredBreakType )
668 switch (deferredBreakType)
670 case COLUMN_BREAK:
671 return m_bIsColumnBreakDeferred;
672 case PAGE_BREAK:
673 return m_bIsPageBreakDeferred;
674 default:
675 return false;
679 void DomainMapper_Impl::clearDeferredBreak(BreakType deferredBreakType)
681 switch (deferredBreakType)
683 case COLUMN_BREAK:
684 m_bIsColumnBreakDeferred = false;
685 break;
686 case PAGE_BREAK:
687 m_bIsPageBreakDeferred = false;
688 break;
689 default:
690 break;
694 void DomainMapper_Impl::clearDeferredBreaks()
696 m_bIsColumnBreakDeferred = false;
697 m_bIsPageBreakDeferred = false;
701 void lcl_MoveBorderPropertiesToFrame(uno::Sequence<beans::PropertyValue>& rFrameProperties,
702 uno::Reference<text::XTextRange> xStartTextRange,
703 uno::Reference<text::XTextRange> xEndTextRange )
707 uno::Reference<text::XTextCursor> xRangeCursor = xStartTextRange->getText()->createTextCursorByRange( xStartTextRange );
708 xRangeCursor->gotoRange( xEndTextRange, true );
710 uno::Reference<beans::XPropertySet> xTextRangeProperties(xRangeCursor, uno::UNO_QUERY);
711 if(!xTextRangeProperties.is())
712 return ;
714 PropertyIds aBorderProperties[] =
716 PROP_LEFT_BORDER,
717 PROP_RIGHT_BORDER,
718 PROP_TOP_BORDER,
719 PROP_BOTTOM_BORDER,
720 PROP_LEFT_BORDER_DISTANCE,
721 PROP_RIGHT_BORDER_DISTANCE,
722 PROP_TOP_BORDER_DISTANCE,
723 PROP_BOTTOM_BORDER_DISTANCE
726 sal_uInt32 nStart = rFrameProperties.getLength();
727 sal_uInt32 nBorderPropertyCount = sizeof( aBorderProperties ) / sizeof(PropertyIds);
728 rFrameProperties.realloc(nStart + nBorderPropertyCount);
730 beans::PropertyValue* pFrameProperties = rFrameProperties.getArray();
731 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
732 for( sal_uInt32 nProperty = 0; nProperty < nBorderPropertyCount; ++nProperty)
734 OUString sPropertyName = rPropNameSupplier.GetName(aBorderProperties[nProperty]);
735 pFrameProperties[nStart].Name = sPropertyName;
736 pFrameProperties[nStart].Value = xTextRangeProperties->getPropertyValue(sPropertyName);
737 if( nProperty < 4 )
738 xTextRangeProperties->setPropertyValue( sPropertyName, uno::makeAny(table::BorderLine2()));
739 ++nStart;
741 rFrameProperties.realloc(nStart);
743 catch( const uno::Exception& )
749 void lcl_AddRangeAndStyle(
750 ParagraphPropertiesPtr& pToBeSavedProperties,
751 uno::Reference< text::XTextAppend > xTextAppend,
752 PropertyMapPtr pPropertyMap,
753 TextAppendContext& rAppendContext)
755 uno::Reference<text::XParagraphCursor> xParaCursor(
756 xTextAppend->createTextCursorByRange( rAppendContext.xInsertPosition.is() ? rAppendContext.xInsertPosition : xTextAppend->getEnd()), uno::UNO_QUERY_THROW );
757 pToBeSavedProperties->SetEndingRange(xParaCursor->getStart());
758 xParaCursor->gotoStartOfParagraph( false );
760 pToBeSavedProperties->SetStartingRange(xParaCursor->getStart());
761 if(pPropertyMap)
763 PropertyMap::iterator aParaStyleIter = pPropertyMap->find(PropertyDefinition( PROP_PARA_STYLE_NAME, false ) );
764 if( aParaStyleIter != pPropertyMap->end())
766 OUString sName;
767 aParaStyleIter->second >>= sName;
768 pToBeSavedProperties->SetParaStyleName(sName);
774 //define some default frame width - 0cm ATM: this allow the frame to be wrapped around the text
775 #define DEFAULT_FRAME_MIN_WIDTH 0
777 void DomainMapper_Impl::CheckUnregisteredFrameConversion( )
779 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
780 if (m_aTextAppendStack.empty())
781 return;
782 TextAppendContext& rAppendContext = m_aTextAppendStack.top();
783 // n#779642: ignore fly frame inside table as it could lead to messy situations
784 if( rAppendContext.pLastParagraphProperties.get() && rAppendContext.pLastParagraphProperties->IsFrameMode()
785 && !getTableManager().isInTable() )
789 StyleSheetEntryPtr pParaStyle =
790 GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(rAppendContext.pLastParagraphProperties->GetParaStyleName());
792 uno::Sequence< beans::PropertyValue > aFrameProperties(pParaStyle ? 16: 9);
794 if ( pParaStyle.get( ) )
796 beans::PropertyValue* pFrameProperties = aFrameProperties.getArray();
797 pFrameProperties[0].Name = rPropNameSupplier.GetName(PROP_WIDTH);
798 pFrameProperties[1].Name = rPropNameSupplier.GetName(PROP_HEIGHT);
799 pFrameProperties[2].Name = rPropNameSupplier.GetName(PROP_SIZE_TYPE);
800 pFrameProperties[3].Name = rPropNameSupplier.GetName(PROP_WIDTH_TYPE);
801 pFrameProperties[4].Name = rPropNameSupplier.GetName(PROP_HORI_ORIENT);
802 pFrameProperties[5].Name = rPropNameSupplier.GetName(PROP_HORI_ORIENT_POSITION);
803 pFrameProperties[6].Name = rPropNameSupplier.GetName(PROP_HORI_ORIENT_RELATION);
804 pFrameProperties[7].Name = rPropNameSupplier.GetName(PROP_VERT_ORIENT);
805 pFrameProperties[8].Name = rPropNameSupplier.GetName(PROP_VERT_ORIENT_POSITION);
806 pFrameProperties[9].Name = rPropNameSupplier.GetName(PROP_VERT_ORIENT_RELATION);
807 pFrameProperties[10].Name = rPropNameSupplier.GetName(PROP_SURROUND);
808 pFrameProperties[11].Name = rPropNameSupplier.GetName(PROP_LEFT_MARGIN);
809 pFrameProperties[12].Name = rPropNameSupplier.GetName(PROP_RIGHT_MARGIN);
810 pFrameProperties[13].Name = rPropNameSupplier.GetName(PROP_TOP_MARGIN);
811 pFrameProperties[14].Name = rPropNameSupplier.GetName(PROP_BOTTOM_MARGIN);
812 pFrameProperties[15].Name = rPropNameSupplier.GetName(PROP_BACK_COLOR_TRANSPARENCY);
814 const ParagraphProperties* pStyleProperties = dynamic_cast<const ParagraphProperties*>( pParaStyle->pProperties.get() );
815 sal_Int32 nWidth =
816 rAppendContext.pLastParagraphProperties->Getw() > 0 ?
817 rAppendContext.pLastParagraphProperties->Getw() :
818 pStyleProperties->Getw();
819 bool bAutoWidth = nWidth < 1;
820 if( bAutoWidth )
821 nWidth = DEFAULT_FRAME_MIN_WIDTH;
822 pFrameProperties[0].Value <<= nWidth;
824 pFrameProperties[1].Value <<=
825 rAppendContext.pLastParagraphProperties->Geth() > 0 ?
826 rAppendContext.pLastParagraphProperties->Geth() :
827 pStyleProperties->Geth();
829 pFrameProperties[2].Value <<= sal_Int16(
830 rAppendContext.pLastParagraphProperties->GethRule() >= 0 ?
831 rAppendContext.pLastParagraphProperties->GethRule() :
832 pStyleProperties->GethRule() >=0 ? pStyleProperties->GethRule() : text::SizeType::VARIABLE);
834 pFrameProperties[3].Value <<= bAutoWidth ? text::SizeType::MIN : text::SizeType::FIX;
836 sal_Int16 nHoriOrient = sal_Int16(
837 rAppendContext.pLastParagraphProperties->GetxAlign() >= 0 ?
838 rAppendContext.pLastParagraphProperties->GetxAlign() :
839 pStyleProperties->GetxAlign() >= 0 ? pStyleProperties->GetxAlign() : text::HoriOrientation::NONE );
840 pFrameProperties[4].Value <<= nHoriOrient;
842 pFrameProperties[5].Value <<=
843 rAppendContext.pLastParagraphProperties->IsxValid() ?
844 rAppendContext.pLastParagraphProperties->Getx() : pStyleProperties->Getx();
845 pFrameProperties[6].Value <<= sal_Int16(
846 rAppendContext.pLastParagraphProperties->GethAnchor() >= 0 ?
847 rAppendContext.pLastParagraphProperties->GethAnchor() :
848 pStyleProperties->GethAnchor() );
850 sal_Int16 nVertOrient = sal_Int16(
851 rAppendContext.pLastParagraphProperties->GetyAlign() >= 0 ?
852 rAppendContext.pLastParagraphProperties->GetyAlign() :
853 pStyleProperties->GetyAlign() >= 0 ? pStyleProperties->GetyAlign() : text::VertOrientation::NONE );
854 pFrameProperties[7].Value <<= nVertOrient;
856 pFrameProperties[8].Value <<=
857 rAppendContext.pLastParagraphProperties->IsyValid() ?
858 rAppendContext.pLastParagraphProperties->Gety() : pStyleProperties->Gety();
859 pFrameProperties[9].Value <<= sal_Int16(
860 rAppendContext.pLastParagraphProperties->GetvAnchor() >= 0 ?
861 rAppendContext.pLastParagraphProperties->GetvAnchor() :
862 pStyleProperties->GetvAnchor() );
864 pFrameProperties[10].Value <<= text::WrapTextMode(
865 rAppendContext.pLastParagraphProperties->GetWrap() >= 0 ?
866 rAppendContext.pLastParagraphProperties->GetWrap() :
867 pStyleProperties->GetWrap());
869 sal_Int32 nBottomDist;
870 sal_Int32 nTopDist = nBottomDist =
871 rAppendContext.pLastParagraphProperties->GethSpace() >= 0 ?
872 rAppendContext.pLastParagraphProperties->GethSpace() :
873 pStyleProperties->GethSpace();
875 pFrameProperties[11].Value <<= nVertOrient == text::VertOrientation::TOP ? 0 : nTopDist;
876 pFrameProperties[12].Value <<= nVertOrient == text::VertOrientation::BOTTOM ? 0 : nBottomDist;
878 sal_Int32 nRightDist;
879 sal_Int32 nLeftDist = nRightDist =
880 rAppendContext.pLastParagraphProperties->GetvSpace() >= 0 ?
881 rAppendContext.pLastParagraphProperties->GetvSpace() :
882 pStyleProperties->GetvSpace() >= 0 ? pStyleProperties->GetvSpace() : 0;
883 pFrameProperties[13].Value <<= nHoriOrient == text::HoriOrientation::LEFT ? 0 : nLeftDist;
884 pFrameProperties[14].Value <<= nHoriOrient == text::HoriOrientation::RIGHT ? 0 : nRightDist;
885 // If there is no fill, the Word default is 100% transparency.
886 // Otherwise CellColorHandler has priority, and this setting
887 // will be ignored.
888 pFrameProperties[15].Value <<= sal_Int32(100);
890 lcl_MoveBorderPropertiesToFrame(aFrameProperties,
891 rAppendContext.pLastParagraphProperties->GetStartingRange(),
892 rAppendContext.pLastParagraphProperties->GetEndingRange());
894 else
896 beans::PropertyValue* pFrameProperties = aFrameProperties.getArray();
897 pFrameProperties[0].Name = rPropNameSupplier.GetName(PROP_WIDTH);
898 pFrameProperties[1].Name = rPropNameSupplier.GetName(PROP_SIZE_TYPE);
899 pFrameProperties[2].Name = rPropNameSupplier.GetName(PROP_WIDTH_TYPE);
900 pFrameProperties[3].Name = rPropNameSupplier.GetName(PROP_HORI_ORIENT);
901 pFrameProperties[4].Name = rPropNameSupplier.GetName(PROP_VERT_ORIENT);
902 pFrameProperties[5].Name = rPropNameSupplier.GetName(PROP_LEFT_MARGIN);
903 pFrameProperties[6].Name = rPropNameSupplier.GetName(PROP_RIGHT_MARGIN);
904 pFrameProperties[7].Name = rPropNameSupplier.GetName(PROP_TOP_MARGIN);
905 pFrameProperties[8].Name = rPropNameSupplier.GetName(PROP_BOTTOM_MARGIN);
907 sal_Int32 nWidth = rAppendContext.pLastParagraphProperties->Getw();
908 bool bAutoWidth = nWidth < 1;
909 if( bAutoWidth )
910 nWidth = DEFAULT_FRAME_MIN_WIDTH;
911 pFrameProperties[0].Value <<= nWidth;
913 pFrameProperties[1].Value <<= sal_Int16(
914 rAppendContext.pLastParagraphProperties->GethRule() >= 0 ?
915 rAppendContext.pLastParagraphProperties->GethRule() :
916 text::SizeType::VARIABLE);
918 pFrameProperties[2].Value <<= bAutoWidth ? text::SizeType::MIN : text::SizeType::FIX;
920 sal_Int16 nHoriOrient = sal_Int16(
921 rAppendContext.pLastParagraphProperties->GetxAlign() >= 0 ?
922 rAppendContext.pLastParagraphProperties->GetxAlign() :
923 text::HoriOrientation::NONE );
924 pFrameProperties[3].Value <<= nHoriOrient;
926 sal_Int16 nVertOrient = sal_Int16(
927 rAppendContext.pLastParagraphProperties->GetyAlign() >= 0 ?
928 rAppendContext.pLastParagraphProperties->GetyAlign() :
929 text::VertOrientation::NONE );
930 pFrameProperties[4].Value <<= nVertOrient;
932 sal_Int32 nVertDist = rAppendContext.pLastParagraphProperties->GethSpace();
933 if( nVertDist < 0 )
934 nVertDist = 0;
935 pFrameProperties[5].Value <<= nVertOrient == text::VertOrientation::TOP ? 0 : nVertDist;
936 pFrameProperties[6].Value <<= nVertOrient == text::VertOrientation::BOTTOM ? 0 : nVertDist;
938 sal_Int32 nHoriDist = rAppendContext.pLastParagraphProperties->GetvSpace();
939 if( nHoriDist < 0 )
940 nHoriDist = 0;
941 pFrameProperties[7].Value <<= nHoriOrient == text::HoriOrientation::LEFT ? 0 : nHoriDist;
942 pFrameProperties[8].Value <<= nHoriOrient == text::HoriOrientation::RIGHT ? 0 : nHoriDist;
944 if( rAppendContext.pLastParagraphProperties->Geth() > 0 )
946 sal_Int32 nOldSize = aFrameProperties.getLength();
947 aFrameProperties.realloc( nOldSize + 1 );
948 pFrameProperties = aFrameProperties.getArray();
949 pFrameProperties[nOldSize].Name = rPropNameSupplier.GetName(PROP_HEIGHT);
950 pFrameProperties[nOldSize].Value <<= rAppendContext.pLastParagraphProperties->Geth();
953 if( rAppendContext.pLastParagraphProperties->IsxValid() )
955 sal_Int32 nOldSize = aFrameProperties.getLength();
956 aFrameProperties.realloc( nOldSize + 1 );
957 pFrameProperties = aFrameProperties.getArray();
958 pFrameProperties[nOldSize].Name = rPropNameSupplier.GetName(PROP_HORI_ORIENT_POSITION);
959 pFrameProperties[nOldSize].Value <<= rAppendContext.pLastParagraphProperties->Getx();
962 if( rAppendContext.pLastParagraphProperties->GethAnchor() >= 0 )
964 sal_Int32 nOldSize = aFrameProperties.getLength();
965 aFrameProperties.realloc( nOldSize + 1 );
966 pFrameProperties = aFrameProperties.getArray();
967 pFrameProperties[nOldSize].Name = rPropNameSupplier.GetName(PROP_HORI_ORIENT_RELATION);
968 pFrameProperties[nOldSize].Value <<= sal_Int16(
969 rAppendContext.pLastParagraphProperties->GethAnchor() );
972 if( rAppendContext.pLastParagraphProperties->IsyValid() )
974 sal_Int32 nOldSize = aFrameProperties.getLength();
975 aFrameProperties.realloc( nOldSize + 1 );
976 pFrameProperties = aFrameProperties.getArray();
977 pFrameProperties[nOldSize].Name = rPropNameSupplier.GetName(PROP_VERT_ORIENT_POSITION);
978 pFrameProperties[nOldSize].Value <<= rAppendContext.pLastParagraphProperties->Gety();
981 if( rAppendContext.pLastParagraphProperties->GetvAnchor() >= 0 )
983 sal_Int32 nOldSize = aFrameProperties.getLength();
984 aFrameProperties.realloc( nOldSize + 1 );
985 pFrameProperties = aFrameProperties.getArray();
986 pFrameProperties[nOldSize].Name = rPropNameSupplier.GetName(PROP_VERT_ORIENT_RELATION);
987 pFrameProperties[nOldSize].Value <<= sal_Int16(
988 rAppendContext.pLastParagraphProperties->GetvAnchor() );
991 if( rAppendContext.pLastParagraphProperties->GetWrap() >= 0 )
993 sal_Int32 nOldSize = aFrameProperties.getLength();
994 aFrameProperties.realloc( nOldSize + 1 );
995 pFrameProperties = aFrameProperties.getArray();
996 pFrameProperties[nOldSize].Name = rPropNameSupplier.GetName(PROP_SURROUND);
997 pFrameProperties[nOldSize].Value <<= text::WrapTextMode(
998 rAppendContext.pLastParagraphProperties->GetWrap() );
1001 lcl_MoveBorderPropertiesToFrame(aFrameProperties,
1002 rAppendContext.pLastParagraphProperties->GetStartingRange(),
1003 rAppendContext.pLastParagraphProperties->GetEndingRange());
1006 //frame conversion has to be executed after table conversion
1007 RegisterFrameConversion(
1008 rAppendContext.pLastParagraphProperties->GetStartingRange(),
1009 rAppendContext.pLastParagraphProperties->GetEndingRange(),
1010 aFrameProperties );
1012 catch( const uno::Exception& )
1018 void DomainMapper_Impl::finishParagraph( PropertyMapPtr pPropertyMap )
1020 #ifdef DEBUG_DOMAINMAPPER
1021 dmapper_logger->startElement("finishParagraph");
1022 #endif
1024 ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pPropertyMap.get() );
1025 if (!m_aTextAppendStack.size())
1026 return;
1027 TextAppendContext& rAppendContext = m_aTextAppendStack.top();
1028 uno::Reference< text::XTextAppend > xTextAppend;
1029 if (!m_aTextAppendStack.empty())
1030 xTextAppend = rAppendContext.xTextAppend;
1031 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1033 #ifdef DEBUG_DOMAINMAPPER
1034 dmapper_logger->attribute("isTextAppend", xTextAppend.is());
1035 #endif
1037 if(xTextAppend.is() && ! getTableManager( ).isIgnore() && pParaContext != NULL)
1041 /*the following combinations of previous and current frame settings can occur:
1042 (1) - no old frame and no current frame -> no special action
1043 (2) - no old frame and current DropCap -> save DropCap for later use, don't call finishParagraph
1044 remove character properties of the DropCap?
1045 (3) - no old frame and current Frame -> save Frame for later use
1046 (4) - old DropCap and no current frame -> add DropCap to the properties of the finished paragraph, delete previous setting
1047 (5) - old DropCap and current frame -> add DropCap to the properties of the finished paragraph, save current frame settings
1048 (6) - old Frame and new DropCap -> add old Frame, save DropCap for later use
1049 (7) - old Frame and new same Frame -> continue
1050 (8) - old Frame and new different Frame -> add old Frame, save new Frame for later use
1051 (9) - old Frame and no current frame -> add old Frame, delete previous settings
1053 old _and_ new DropCap must not occur
1056 bool bIsDropCap =
1057 pParaContext->IsFrameMode() &&
1058 sal::static_int_cast<Id>(pParaContext->GetDropCap()) != NS_ooxml::LN_Value_wordprocessingml_ST_DropCap_none;
1060 style::DropCapFormat aDrop;
1061 ParagraphPropertiesPtr pToBeSavedProperties;
1062 bool bKeepLastParagraphProperties = false;
1063 if( bIsDropCap )
1065 uno::Reference<text::XParagraphCursor> xParaCursor(
1066 xTextAppend->createTextCursorByRange(xTextAppend->getEnd()), uno::UNO_QUERY_THROW);
1067 //select paragraph
1068 xParaCursor->gotoStartOfParagraph( true );
1069 uno::Reference< beans::XPropertyState > xParaProperties( xParaCursor, uno::UNO_QUERY_THROW );
1070 xParaProperties->setPropertyToDefault(rPropNameSupplier.GetName(PROP_CHAR_ESCAPEMENT));
1071 xParaProperties->setPropertyToDefault(rPropNameSupplier.GetName(PROP_CHAR_HEIGHT));
1072 //handles (2) and part of (6)
1073 pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
1074 sal_Int32 nCount = xParaCursor->getString().getLength();
1075 pToBeSavedProperties->SetDropCapLength(nCount > 0 && nCount < 255 ? (sal_Int8)nCount : 1);
1077 if( rAppendContext.pLastParagraphProperties.get() )
1079 if( sal::static_int_cast<Id>(rAppendContext.pLastParagraphProperties->GetDropCap()) != NS_ooxml::LN_Value_wordprocessingml_ST_DropCap_none)
1081 //handles (4) and part of (5)
1082 //create a DropCap property, add it to the property sequence of finishParagraph
1083 sal_Int32 nLines = rAppendContext.pLastParagraphProperties->GetLines();
1084 aDrop.Lines = nLines > 0 && nLines < 254 ? (sal_Int8)++nLines : 2;
1085 aDrop.Count = rAppendContext.pLastParagraphProperties->GetDropCapLength();
1086 aDrop.Distance = 0; //TODO: find distance value
1087 //completes (5)
1088 if( pParaContext->IsFrameMode() )
1089 pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
1091 else if(*rAppendContext.pLastParagraphProperties == *pParaContext )
1093 //handles (7)
1094 rAppendContext.pLastParagraphProperties->SetEndingRange(rAppendContext.xInsertPosition.is() ? rAppendContext.xInsertPosition : xTextAppend->getEnd());
1095 bKeepLastParagraphProperties = true;
1097 else
1099 //handles (8)(9) and completes (6)
1100 CheckUnregisteredFrameConversion( );
1102 // If different frame properties are set on this paragraph, keep them.
1103 if ( !bIsDropCap && pParaContext->IsFrameMode() )
1105 pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
1106 lcl_AddRangeAndStyle(pToBeSavedProperties, xTextAppend, pPropertyMap, rAppendContext);
1111 else //
1113 // (1) doesn't need handling
1115 if( !bIsDropCap && pParaContext->IsFrameMode() )
1117 pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
1118 lcl_AddRangeAndStyle(pToBeSavedProperties, xTextAppend, pPropertyMap, rAppendContext);
1121 uno::Sequence< beans::PropertyValue > aProperties;
1122 if( pPropertyMap.get() )
1124 aProperties = pPropertyMap->GetPropertyValues();
1126 if( !bIsDropCap )
1128 if( aDrop.Lines > 1 )
1130 sal_uInt32 nLength = aProperties.getLength();
1131 aProperties.realloc( nLength + 1 );
1132 aProperties[nLength].Value <<= aDrop;
1133 aProperties[nLength].Name = rPropNameSupplier.GetName(PROP_DROP_CAP_FORMAT);
1135 uno::Reference< text::XTextRange > xTextRange;
1136 if (rAppendContext.xInsertPosition.is())
1138 xTextRange = xTextAppend->finishParagraphInsert( aProperties, rAppendContext.xInsertPosition );
1139 rAppendContext.xCursor->gotoNextParagraph(false);
1140 if (rAppendContext.pLastParagraphProperties.get())
1141 rAppendContext.pLastParagraphProperties->SetEndingRange(xTextRange->getEnd());
1143 else
1144 xTextRange = xTextAppend->finishParagraph( aProperties );
1145 getTableManager( ).handle(xTextRange);
1147 // Get the end of paragraph character inserted
1148 uno::Reference< text::XTextCursor > xCur = xTextRange->getText( )->createTextCursor( );
1149 if (rAppendContext.xInsertPosition.is())
1150 xCur->gotoRange( rAppendContext.xInsertPosition, false );
1151 else
1152 xCur->gotoEnd( false );
1153 xCur->goLeft( 1 , true );
1154 uno::Reference< text::XTextRange > xParaEnd( xCur, uno::UNO_QUERY );
1155 CheckParaRedline( xParaEnd );
1157 m_bIsFirstParaInSection = false;
1158 m_bIsLastParaInSection = false;
1159 m_bParaChanged = false;
1161 // Reset the frame properties for the next paragraph
1162 pParaContext->ResetFrameProperties();
1164 if( !bKeepLastParagraphProperties )
1165 rAppendContext.pLastParagraphProperties = pToBeSavedProperties;
1167 catch(const lang::IllegalArgumentException&)
1169 OSL_FAIL( "IllegalArgumentException in DomainMapper_Impl::finishParagraph" );
1171 catch(const uno::Exception&)
1176 #ifdef DEBUG_DOMAINMAPPER
1177 dmapper_logger->endElement();
1178 #endif
1182 util::DateTime lcl_DateStringToDateTime( const OUString& rDateTime )
1184 util::DateTime aDateTime;
1185 //xsd::DateTime in the format [-]CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm] example: 2008-01-21T10:42:00Z
1186 //OUString getToken( sal_Int32 token, sal_Unicode cTok, sal_Int32& index ) const SAL_THROW(())
1187 sal_Int32 nIndex = 0;
1188 OUString sDate = rDateTime.getToken( 0, 'T', nIndex );
1189 // HACK: this is broken according to the spec, but MSOffice always treats the time as local,
1190 // and writes it as Z (=UTC+0)
1191 OUString sTime = rDateTime.getToken( 0, 'Z', nIndex );
1192 nIndex = 0;
1193 aDateTime.Year = sal_uInt16( sDate.getToken( 0, '-', nIndex ).toInt32() );
1194 aDateTime.Month = sal_uInt16( sDate.getToken( 0, '-', nIndex ).toInt32() );
1195 aDateTime.Day = sal_uInt16( sDate.copy( nIndex ).toInt32() );
1197 nIndex = 0;
1198 aDateTime.Hours = sal_uInt16( sTime.getToken( 0, ':', nIndex ).toInt32() );
1199 aDateTime.Minutes = sal_uInt16( sTime.getToken( 0, ':', nIndex ).toInt32() );
1200 aDateTime.Seconds = sal_uInt16( sTime.copy( nIndex ).toInt32() );
1202 return aDateTime;
1204 void DomainMapper_Impl::appendTextPortion( const OUString& rString, PropertyMapPtr pPropertyMap )
1206 if (m_aTextAppendStack.empty())
1207 return;
1208 if( pPropertyMap == m_pTopContext && !deferredCharacterProperties.empty())
1209 processDeferredCharacterProperties();
1210 uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
1211 if(xTextAppend.is() && ! getTableManager( ).isIgnore())
1215 uno::Reference< text::XTextRange > xTextRange;
1216 if (m_aTextAppendStack.top().xInsertPosition.is())
1218 xTextRange = xTextAppend->insertTextPortion(rString, pPropertyMap->GetPropertyValues(), m_aTextAppendStack.top().xInsertPosition);
1219 m_aTextAppendStack.top().xCursor->gotoRange(xTextRange->getEnd(), false);
1221 else
1222 xTextRange = xTextAppend->appendTextPortion(rString, pPropertyMap->GetPropertyValues());
1223 CheckRedline( xTextRange );
1224 m_bParaChanged = true;
1226 //getTableManager( ).handle(xTextRange);
1228 catch(const lang::IllegalArgumentException&)
1230 OSL_FAIL( "IllegalArgumentException in DomainMapper_Impl::appendTextPortion" );
1232 catch(const uno::Exception&)
1234 OSL_FAIL( "Exception in DomainMapper_Impl::appendTextPortion" );
1240 void DomainMapper_Impl::appendTextContent(
1241 const uno::Reference< text::XTextContent > xContent,
1242 const uno::Sequence< beans::PropertyValue > xPropertyValues
1245 SAL_WARN_IF(m_aTextAppendStack.empty(), "writerfilter.dmapper", "no text append stack");
1246 if (m_aTextAppendStack.empty())
1247 return;
1248 uno::Reference< text::XTextAppendAndConvert > xTextAppendAndConvert( m_aTextAppendStack.top().xTextAppend, uno::UNO_QUERY );
1249 OSL_ENSURE( xTextAppendAndConvert.is(), "trying to append a text content without XTextAppendAndConvert" );
1250 if(xTextAppendAndConvert.is() && ! getTableManager( ).isIgnore())
1254 if (m_aTextAppendStack.top().xInsertPosition.is())
1255 xTextAppendAndConvert->insertTextContentWithProperties( xContent, xPropertyValues, m_aTextAppendStack.top().xInsertPosition );
1256 else
1257 xTextAppendAndConvert->appendTextContent( xContent, xPropertyValues );
1259 catch(const lang::IllegalArgumentException&)
1262 catch(const uno::Exception&)
1270 void DomainMapper_Impl::appendOLE( const OUString& rStreamName, OLEHandlerPtr pOLEHandler )
1272 static const OUString sEmbeddedService("com.sun.star.text.TextEmbeddedObject");
1275 uno::Reference< text::XTextContent > xOLE( m_xTextFactory->createInstance(sEmbeddedService), uno::UNO_QUERY_THROW );
1276 uno::Reference< beans::XPropertySet > xOLEProperties(xOLE, uno::UNO_QUERY_THROW);
1278 xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_STREAM_NAME ),
1279 uno::makeAny( rStreamName ));
1280 awt::Size aSize = pOLEHandler->getSize();
1281 if( !aSize.Width )
1282 aSize.Width = 1000;
1283 if( !aSize.Height )
1284 aSize.Height = 1000;
1285 xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_WIDTH ),
1286 uno::makeAny(aSize.Width));
1287 xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_HEIGHT ),
1288 uno::makeAny(aSize.Height));
1290 uno::Reference< graphic::XGraphic > xGraphic = pOLEHandler->getReplacement();
1291 xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_GRAPHIC ),
1292 uno::makeAny(xGraphic));
1293 // mimic the treatment of graphics here.. it seems anchoring as character
1294 // gives a better ( visually ) result
1295 xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_ANCHOR_TYPE ), uno::makeAny( text::TextContentAnchorType_AS_CHARACTER ) );
1296 // remove ( if valid ) associated shape ( used for graphic replacement )
1297 SAL_WARN_IF(m_aAnchoredStack.empty(), "writerfilter.dmapper", "no anchor stack");
1298 if (!m_aAnchoredStack.empty())
1299 m_aAnchoredStack.top( ).bToRemove = true;
1300 RemoveLastParagraph();
1301 m_aTextAppendStack.pop();
1304 appendTextContent( xOLE, uno::Sequence< beans::PropertyValue >() );
1307 catch( const uno::Exception& )
1309 OSL_FAIL( "Exception in creation of OLE object" );
1314 void DomainMapper_Impl::appendStarMath( const Value& val )
1316 uno::Reference< embed::XEmbeddedObject > formula;
1317 val.getAny() >>= formula;
1318 if( formula.is() )
1320 static const OUString sEmbeddedService("com.sun.star.text.TextEmbeddedObject");
1323 uno::Reference< text::XTextContent > xStarMath( m_xTextFactory->createInstance(sEmbeddedService), uno::UNO_QUERY_THROW );
1324 uno::Reference< beans::XPropertySet > xStarMathProperties(xStarMath, uno::UNO_QUERY_THROW);
1326 xStarMathProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_EMBEDDED_OBJECT ),
1327 val.getAny());
1329 uno::Reference< uno::XInterface > xInterface( formula->getComponent(), uno::UNO_QUERY );
1330 Size size( 1000, 1000 );
1331 if( oox::FormulaImportBase* formulaimport = dynamic_cast< oox::FormulaImportBase* >( xInterface.get()))
1332 size = formulaimport->getFormulaSize();
1333 xStarMathProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_WIDTH ),
1334 uno::makeAny( sal_Int32(size.Width())));
1335 xStarMathProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_HEIGHT ),
1336 uno::makeAny( sal_Int32(size.Height())));
1337 // mimic the treatment of graphics here.. it seems anchoring as character
1338 // gives a better ( visually ) result
1339 xStarMathProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_ANCHOR_TYPE ),
1340 uno::makeAny( text::TextContentAnchorType_AS_CHARACTER ) );
1341 appendTextContent( xStarMath, uno::Sequence< beans::PropertyValue >() );
1343 catch( const uno::Exception& )
1345 OSL_FAIL( "Exception in creation of StarMath object" );
1350 uno::Reference< beans::XPropertySet > DomainMapper_Impl::appendTextSectionAfter(
1351 uno::Reference< text::XTextRange >& xBefore )
1353 uno::Reference< beans::XPropertySet > xRet;
1354 if (m_aTextAppendStack.empty())
1355 return xRet;
1356 uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
1357 if(xTextAppend.is())
1361 uno::Reference< text::XParagraphCursor > xCursor(
1362 xTextAppend->createTextCursorByRange( xBefore ), uno::UNO_QUERY_THROW);
1363 //the cursor has been moved to the end of the paragraph because of the appendTextPortion() calls
1364 xCursor->gotoStartOfParagraph( false );
1365 if (m_aTextAppendStack.top().xInsertPosition.is())
1366 xCursor->gotoRange( m_aTextAppendStack.top().xInsertPosition, true );
1367 else
1368 xCursor->gotoEnd( true );
1369 //the paragraph after this new section is already inserted
1370 xCursor->goLeft(1, true);
1371 static const OUString sSectionService("com.sun.star.text.TextSection");
1372 uno::Reference< text::XTextContent > xSection( m_xTextFactory->createInstance(sSectionService), uno::UNO_QUERY_THROW );
1373 xSection->attach( uno::Reference< text::XTextRange >( xCursor, uno::UNO_QUERY_THROW) );
1374 xRet = uno::Reference< beans::XPropertySet > (xSection, uno::UNO_QUERY );
1376 catch(const uno::Exception&)
1382 return xRet;
1386 void DomainMapper_Impl::PushPageHeader(SectionPropertyMap::PageType eType)
1388 m_bInHeaderFooterImport = true;
1390 //get the section context
1391 PropertyMapPtr pContext = DomainMapper_Impl::GetTopContextOfType(CONTEXT_SECTION);
1392 //ask for the header name of the given type
1393 SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() );
1394 if(pSectionContext)
1396 uno::Reference< beans::XPropertySet > xPageStyle =
1397 pSectionContext->GetPageStyle(
1398 GetPageStyles(),
1399 m_xTextFactory,
1400 eType == SectionPropertyMap::PAGE_FIRST );
1401 if (!xPageStyle.is())
1402 return;
1405 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1406 //switch on header use
1407 xPageStyle->setPropertyValue(
1408 rPropNameSupplier.GetName(PROP_HEADER_IS_ON),
1409 uno::makeAny(sal_True) );
1410 // if a left header is available then header are not shared
1411 bool bLeft = eType == SectionPropertyMap::PAGE_LEFT;
1413 // If the 'Different Even & Odd Pages' flag is turned on - do not ignore it
1414 // Even if the 'Even' header is blank - the flag should be imported (so it would look in LO like in Word)
1415 if( m_pSettingsTable->GetEvenAndOddHeaders())
1416 xPageStyle->setPropertyValue(rPropNameSupplier.GetName(PROP_HEADER_IS_SHARED), uno::makeAny( false ));
1418 //set the interface
1419 uno::Reference< text::XText > xHeaderText;
1420 xPageStyle->getPropertyValue(rPropNameSupplier.GetName( bLeft ? PROP_HEADER_TEXT_LEFT : PROP_HEADER_TEXT) ) >>= xHeaderText;
1421 m_aTextAppendStack.push( TextAppendContext(uno::Reference< text::XTextAppend >( xHeaderText, uno::UNO_QUERY_THROW),
1422 m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(xHeaderText->getStart())));
1424 catch( const uno::Exception& )
1431 void DomainMapper_Impl::PushPageFooter(SectionPropertyMap::PageType eType)
1433 m_bInHeaderFooterImport = true;
1435 //get the section context
1436 PropertyMapPtr pContext = DomainMapper_Impl::GetTopContextOfType(CONTEXT_SECTION);
1437 //ask for the footer name of the given type
1438 SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() );
1439 if(pSectionContext)
1441 uno::Reference< beans::XPropertySet > xPageStyle =
1442 pSectionContext->GetPageStyle(
1443 GetPageStyles(),
1444 m_xTextFactory,
1445 eType == SectionPropertyMap::PAGE_FIRST );
1446 if (!xPageStyle.is())
1447 return;
1450 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1451 //switch on footer use
1452 xPageStyle->setPropertyValue(
1453 rPropNameSupplier.GetName(PROP_FOOTER_IS_ON),
1454 uno::makeAny(sal_True) );
1455 // if a left header is available then footer is not shared
1456 bool bLeft = eType == SectionPropertyMap::PAGE_LEFT;
1458 // If the 'Different Even & Odd Pages' flag is turned on - do not ignore it
1459 // Even if the 'Even' footer is blank - the flag should be imported (so it would look in LO like in Word)
1460 if( m_pSettingsTable->GetEvenAndOddHeaders())
1461 xPageStyle->setPropertyValue(rPropNameSupplier.GetName(PROP_FOOTER_IS_SHARED), uno::makeAny( false ));
1462 //set the interface
1463 uno::Reference< text::XText > xFooterText;
1464 xPageStyle->getPropertyValue(rPropNameSupplier.GetName( bLeft ? PROP_FOOTER_TEXT_LEFT : PROP_FOOTER_TEXT) ) >>= xFooterText;
1465 m_aTextAppendStack.push(TextAppendContext(uno::Reference< text::XTextAppend >( xFooterText, uno::UNO_QUERY_THROW ),
1466 m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(xFooterText->getStart())));
1468 catch( const uno::Exception& )
1475 void DomainMapper_Impl::PopPageHeaderFooter()
1477 //header and footer always have an empty paragraph at the end
1478 //this has to be removed
1479 RemoveLastParagraph( );
1480 if (!m_aTextAppendStack.empty())
1481 m_aTextAppendStack.pop();
1482 m_bInHeaderFooterImport = false;
1486 void DomainMapper_Impl::PushFootOrEndnote( bool bIsFootnote )
1490 // Redlines outside the footnote should not affect footnote content
1491 m_aRedlines.push(std::vector< RedlineParamsPtr >());
1493 PropertyMapPtr pTopContext = GetTopContext();
1494 uno::Reference< text::XText > xFootnoteText;
1495 if (GetTextFactory().is())
1496 xFootnoteText.set( GetTextFactory()->createInstance(
1497 bIsFootnote ?
1498 OUString( "com.sun.star.text.Footnote" ) : OUString( "com.sun.star.text.Endnote" )),
1499 uno::UNO_QUERY_THROW );
1500 uno::Reference< text::XFootnote > xFootnote( xFootnoteText, uno::UNO_QUERY_THROW );
1501 pTopContext->SetFootnote( xFootnote );
1502 if( pTopContext->GetFootnoteSymbol() != 0)
1504 xFootnote->setLabel( OUString( pTopContext->GetFootnoteSymbol() ) );
1506 FontTablePtr pFontTable = GetFontTable();
1507 uno::Sequence< beans::PropertyValue > aFontProperties;
1508 if( pFontTable && pTopContext->GetFootnoteFontId() >= 0 && pFontTable->size() > (size_t)pTopContext->GetFootnoteFontId() )
1510 const FontEntry::Pointer_t pFontEntry(pFontTable->getFontEntry(sal_uInt32(pTopContext->GetFootnoteFontId())));
1511 PropertyMapPtr aFontProps( new PropertyMap );
1512 aFontProps->Insert(PROP_CHAR_FONT_NAME, true, uno::makeAny( pFontEntry->sFontName ));
1513 aFontProps->Insert(PROP_CHAR_FONT_CHAR_SET, true, uno::makeAny( (sal_Int16)pFontEntry->nTextEncoding ));
1514 aFontProps->Insert(PROP_CHAR_FONT_PITCH, true, uno::makeAny( pFontEntry->nPitchRequest ));
1515 aFontProperties = aFontProps->GetPropertyValues();
1517 else if(!pTopContext->GetFootnoteFontName().isEmpty())
1519 PropertyMapPtr aFontProps( new PropertyMap );
1520 aFontProps->Insert(PROP_CHAR_FONT_NAME, true, uno::makeAny( pTopContext->GetFootnoteFontName() ));
1521 aFontProperties = aFontProps->GetPropertyValues();
1523 appendTextContent( uno::Reference< text::XTextContent >( xFootnoteText, uno::UNO_QUERY_THROW ), aFontProperties );
1524 m_aTextAppendStack.push(TextAppendContext(uno::Reference< text::XTextAppend >( xFootnoteText, uno::UNO_QUERY_THROW ),
1525 m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : xFootnoteText->createTextCursorByRange(xFootnoteText->getStart())));
1527 // Redlines for the footnote anchor
1528 CheckRedline( xFootnote->getAnchor( ) );
1530 catch( const uno::Exception& e )
1532 SAL_WARN("writerfilter", "exception in PushFootOrEndnote: " << e.Message);
1536 void DomainMapper_Impl::CreateRedline( uno::Reference< text::XTextRange > xRange, RedlineParamsPtr& pRedline )
1538 if ( pRedline.get( ) )
1542 OUString sType;
1543 PropertyNameSupplier & rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier( );
1544 switch ( pRedline->m_nToken & 0xffff )
1546 case ooxml::OOXML_mod:
1547 sType = rPropNameSupplier.GetName( PROP_FORMAT );
1548 break;
1549 case ooxml::OOXML_ins:
1550 sType = rPropNameSupplier.GetName( PROP_INSERT );
1551 break;
1552 case ooxml::OOXML_del:
1553 sType = rPropNameSupplier.GetName( PROP_DELETE );
1554 break;
1556 uno::Reference < text::XRedline > xRedline( xRange, uno::UNO_QUERY_THROW );
1557 beans::PropertyValues aRedlineProperties( 2 );
1558 beans::PropertyValue * pRedlineProperties = aRedlineProperties.getArray( );
1559 pRedlineProperties[0].Name = rPropNameSupplier.GetName( PROP_REDLINE_AUTHOR );
1560 pRedlineProperties[0].Value <<= pRedline->m_sAuthor;
1561 pRedlineProperties[1].Name = rPropNameSupplier.GetName( PROP_REDLINE_DATE_TIME );
1562 pRedlineProperties[1].Value <<= lcl_DateStringToDateTime( pRedline->m_sDate );
1564 xRedline->makeRedline( sType, aRedlineProperties );
1566 catch( const uno::Exception & )
1568 OSL_FAIL( "Exception in makeRedline" );
1573 void DomainMapper_Impl::CheckParaRedline( uno::Reference< text::XTextRange > xRange )
1575 if ( m_pParaRedline.get( ) )
1577 CreateRedline( xRange, m_pParaRedline );
1578 ResetParaRedline( );
1582 void DomainMapper_Impl::CheckRedline( uno::Reference< text::XTextRange > xRange )
1584 vector<RedlineParamsPtr>::iterator pIt = m_aRedlines.top().begin( );
1585 vector< RedlineParamsPtr > aCleaned;
1586 for (; pIt != m_aRedlines.top().end( ); ++pIt )
1588 CreateRedline( xRange, *pIt );
1590 // Adding the non-mod redlines to the temporary vector
1591 if ( pIt->get( ) && ( ( *pIt )->m_nToken & 0xffff ) != ooxml::OOXML_mod )
1593 aCleaned.push_back( *pIt );
1597 m_aRedlines.top().swap( aCleaned );
1600 void DomainMapper_Impl::StartParaChange( )
1602 m_bIsParaChange = true;
1605 void DomainMapper_Impl::EndParaChange( )
1607 m_bIsParaChange = false;
1612 void DomainMapper_Impl::PushAnnotation()
1616 PropertyMapPtr pTopContext = GetTopContext();
1617 m_bIsInComments = true;
1618 if (!GetTextFactory().is())
1619 return;
1620 m_xAnnotationField = uno::Reference< beans::XPropertySet >( GetTextFactory()->createInstance(
1621 "com.sun.star.text.TextField.Annotation" ),
1622 uno::UNO_QUERY_THROW );
1623 uno::Reference< text::XText > xAnnotationText;
1624 m_xAnnotationField->getPropertyValue("TextRange") >>= xAnnotationText;
1625 m_aTextAppendStack.push(TextAppendContext(uno::Reference< text::XTextAppend >( xAnnotationText, uno::UNO_QUERY_THROW ),
1626 m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : xAnnotationText->createTextCursorByRange(xAnnotationText->getStart())));
1628 catch( const uno::Exception& )
1630 OSL_FAIL( "exception in PushAnnotation" );
1635 void DomainMapper_Impl::PopFootOrEndnote()
1637 RemoveLastParagraph();
1638 if (!m_aTextAppendStack.empty())
1639 m_aTextAppendStack.pop();
1641 if (m_aRedlines.size() == 1)
1643 SAL_WARN("writerfilter", "PopFootOrEndnote() is called without PushFootOrEndnote()?");
1644 return;
1646 m_aRedlines.pop();
1650 void DomainMapper_Impl::PopAnnotation()
1652 RemoveLastParagraph();
1654 m_bIsInComments = false;
1655 m_aTextAppendStack.pop();
1659 // See if the annotation will be a single position or a range.
1660 if (!m_aAnnotationPosition.m_xStart.is() ||
1661 !m_aAnnotationPosition.m_xEnd.is())
1663 uno::Sequence< beans::PropertyValue > aEmptyProperties;
1664 appendTextContent(uno::Reference<text::XTextContent>(
1665 m_xAnnotationField, uno::UNO_QUERY_THROW), aEmptyProperties);
1667 else
1669 // Create a range that points to the annotation start/end.
1670 uno::Reference<text::XText> const xText =
1671 m_aAnnotationPosition.m_xStart->getText();
1672 uno::Reference<text::XTextCursor> const xCursor =
1673 xText->createTextCursorByRange(m_aAnnotationPosition.m_xStart);
1674 xCursor->gotoRange(m_aAnnotationPosition.m_xEnd, true);
1675 uno::Reference<text::XTextRange> const xTextRange(
1676 xCursor, uno::UNO_QUERY_THROW);
1678 // Attach the annotation to the range.
1679 uno::Reference<text::XTextAppend> const xTextAppend =
1680 m_aTextAppendStack.top().xTextAppend;
1681 xTextAppend->insertTextContent(xTextRange,
1682 uno::Reference<text::XTextContent>(m_xAnnotationField,
1683 uno::UNO_QUERY_THROW),
1684 !xCursor->isCollapsed());
1687 catch (uno::Exception const& e)
1689 SAL_WARN("writerfilter",
1690 "Cannot insert annotation field: exception: " << e.Message);
1693 m_aAnnotationPosition.m_xStart.clear();
1694 m_aAnnotationPosition.m_xEnd.clear();
1695 m_xAnnotationField.clear();
1699 void DomainMapper_Impl::PushPendingShape( const uno::Reference< drawing::XShape > xShape )
1701 m_aPendingShapes.push_back(xShape);
1704 uno::Reference<drawing::XShape> DomainMapper_Impl::PopPendingShape()
1706 uno::Reference<drawing::XShape> xRet;
1707 if (!m_aPendingShapes.empty())
1709 xRet = m_aPendingShapes.front();
1710 m_aPendingShapes.pop_front();
1712 return xRet;
1715 void DomainMapper_Impl::PushShapeContext( const uno::Reference< drawing::XShape > xShape )
1717 if (m_aTextAppendStack.empty())
1718 return;
1719 uno::Reference<text::XTextAppend> xTextAppend = m_aTextAppendStack.top().xTextAppend;
1721 appendTableManager( );
1722 appendTableHandler( );
1723 getTableManager().startLevel();
1726 uno::Reference< lang::XServiceInfo > xSInfo( xShape, uno::UNO_QUERY_THROW );
1727 if (xSInfo->supportsService("com.sun.star.drawing.GroupShape"))
1729 // A GroupShape doesn't implement text::XTextRange, but appending
1730 // an empty reference to the stacks still makes sense, because this
1731 // way bToRemove can be set, and we won't end up with duplicated
1732 // shapes for OLE objects.
1733 m_aTextAppendStack.push(TextAppendContext(uno::Reference<text::XTextAppend>(xShape, uno::UNO_QUERY), uno::Reference<text::XTextCursor>()));
1734 uno::Reference<text::XTextContent> xTxtContent(xShape, uno::UNO_QUERY);
1735 m_aAnchoredStack.push(xTxtContent);
1737 else
1739 uno::Reference< text::XTextRange > xShapeText( xShape, uno::UNO_QUERY_THROW);
1740 // Add the shape to the text append stack
1741 m_aTextAppendStack.push( TextAppendContext(uno::Reference< text::XTextAppend >( xShape, uno::UNO_QUERY_THROW ),
1742 m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(xShapeText->getStart() )));
1744 // Add the shape to the anchored objects stack
1745 uno::Reference< text::XTextContent > xTxtContent( xShape, uno::UNO_QUERY_THROW );
1746 m_aAnchoredStack.push( xTxtContent );
1748 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1750 uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY_THROW );
1751 #ifdef DEBUG_DOMAINMAPPER
1752 dmapper_logger->unoPropertySet(xProps);
1753 #endif
1754 bool bIsGraphic = xSInfo->supportsService( "com.sun.star.drawing.GraphicObjectShape" );
1756 // If there are position properties, the shape should not be inserted "as character".
1757 sal_Int32 nHoriPosition = 0, nVertPosition = 0;
1758 xProps->getPropertyValue(rPropNameSupplier.GetName(PROP_HORI_ORIENT_POSITION)) >>= nHoriPosition;
1759 xProps->getPropertyValue(rPropNameSupplier.GetName(PROP_VERT_ORIENT_POSITION)) >>= nVertPosition;
1760 if (nHoriPosition != 0 || nVertPosition != 0)
1761 bIsGraphic = false;
1762 text::TextContentAnchorType nAnchorType(text::TextContentAnchorType_AT_PARAGRAPH);
1763 xProps->getPropertyValue(rPropNameSupplier.GetName( PROP_ANCHOR_TYPE )) >>= nAnchorType;
1764 if (nAnchorType == text::TextContentAnchorType_AT_PAGE)
1765 bIsGraphic = false;
1767 if (!m_bInHeaderFooterImport)
1768 xProps->setPropertyValue(
1769 rPropNameSupplier.GetName( PROP_OPAQUE ),
1770 uno::makeAny( true ) );
1771 if (xSInfo->supportsService("com.sun.star.text.TextFrame"))
1773 uno::Reference<text::XTextContent> xTextContent(xShape, uno::UNO_QUERY_THROW);
1774 uno::Reference<text::XTextRange> xTextRange(xTextAppend->createTextCursorByRange(xTextAppend->getEnd()), uno::UNO_QUERY_THROW);
1775 xTextAppend->insertTextContent(xTextRange, xTextContent, sal_False);
1777 else if (nAnchorType != text::TextContentAnchorType_AS_CHARACTER)
1779 xProps->setPropertyValue( rPropNameSupplier.GetName( PROP_ANCHOR_TYPE ), bIsGraphic ? uno::makeAny( text::TextContentAnchorType_AS_CHARACTER ) : uno::makeAny( text::TextContentAnchorType_AT_PARAGRAPH ) );
1783 catch ( const uno::Exception& e )
1785 SAL_WARN("writerfilter", "Exception when adding shape: " << e.Message);
1791 void DomainMapper_Impl::PopShapeContext()
1793 getTableManager().endLevel();
1794 popTableManager();
1795 if ( m_aAnchoredStack.size() > 0 )
1797 // For OLE object replacement shape, the text append context was already removed
1798 // or the OLE object couldn't be inserted.
1799 if ( !m_aAnchoredStack.top().bToRemove )
1801 RemoveLastParagraph();
1802 m_aTextAppendStack.pop();
1805 uno::Reference< text::XTextContent > xObj = m_aAnchoredStack.top( ).xTextContent;
1808 appendTextContent( xObj, uno::Sequence< beans::PropertyValue >() );
1810 catch ( const uno::RuntimeException& )
1812 // this is normal: the shape is already attached
1815 // Remove the shape if required (most likely replacement shape for OLE object)
1816 if ( m_aAnchoredStack.top().bToRemove )
1820 uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(m_xTextDocument, uno::UNO_QUERY_THROW);
1821 uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
1822 if ( xDrawPage.is() )
1824 uno::Reference<drawing::XShape> xShape( xObj, uno::UNO_QUERY_THROW );
1825 xDrawPage->remove( xShape );
1828 catch( const uno::Exception& )
1832 m_aAnchoredStack.pop();
1836 sal_Int16 lcl_ParseNumberingType( const OUString& rCommand )
1838 sal_Int16 nRet = style::NumberingType::PAGE_DESCRIPTOR;
1840 // The command looks like: " PAGE \* Arabic "
1841 OUString sNumber = msfilter::util::findQuotedText(rCommand, "\\* ", ' ');
1843 if( !sNumber.isEmpty() )
1845 //todo: might make sense to hash this list, too
1846 struct NumberingPairs
1848 const sal_Char* cWordName;
1849 sal_Int16 nType;
1851 static const NumberingPairs aNumberingPairs[] =
1853 {"Arabic", style::NumberingType::ARABIC}
1854 ,{"ROMAN", style::NumberingType::ROMAN_UPPER}
1855 ,{"roman", style::NumberingType::ROMAN_LOWER}
1856 ,{"ALPHABETIC", style::NumberingType::CHARS_UPPER_LETTER}
1857 ,{"alphabetic", style::NumberingType::CHARS_LOWER_LETTER}
1858 ,{"CircleNum", style::NumberingType::CIRCLE_NUMBER}
1859 ,{"ThaiArabic", style::NumberingType::CHARS_THAI}
1860 ,{"ThaiCardText", style::NumberingType::CHARS_THAI}
1861 ,{"ThaiLetter", style::NumberingType::CHARS_THAI}
1862 // ,{"SBCHAR", style::NumberingType::}
1863 // ,{"DBCHAR", style::NumberingType::}
1864 // ,{"DBNUM1", style::NumberingType::}
1865 // ,{"DBNUM2", style::NumberingType::}
1866 // ,{"DBNUM3", style::NumberingType::}
1867 // ,{"DBNUM4", style::NumberingType::}
1868 ,{"Aiueo", style::NumberingType::AIU_FULLWIDTH_JA}
1869 ,{"Iroha", style::NumberingType::IROHA_FULLWIDTH_JA}
1870 // ,{"ZODIAC1", style::NumberingType::}
1871 // ,{"ZODIAC2", style::NumberingType::}
1872 // ,{"ZODIAC3", style::NumberingType::}
1873 // ,{"CHINESENUM1", style::NumberingType::}
1874 // ,{"CHINESENUM2", style::NumberingType::}
1875 // ,{"CHINESENUM3", style::NumberingType::}
1876 ,{"ArabicAlpha", style::NumberingType::CHARS_ARABIC}
1877 ,{"ArabicAbjad", style::NumberingType::FULLWIDTH_ARABIC}
1878 /* possible values:
1879 style::NumberingType::
1881 CHARS_UPPER_LETTER_N
1882 CHARS_LOWER_LETTER_N
1883 TRANSLITERATION
1884 NATIVE_NUMBERING
1885 CIRCLE_NUMBER
1886 NUMBER_LOWER_ZH
1887 NUMBER_UPPER_ZH
1888 NUMBER_UPPER_ZH_TW
1889 TIAN_GAN_ZH
1890 DI_ZI_ZH
1891 NUMBER_TRADITIONAL_JA
1892 AIU_HALFWIDTH_JA
1893 IROHA_HALFWIDTH_JA
1894 NUMBER_UPPER_KO
1895 NUMBER_HANGUL_KO
1896 HANGUL_JAMO_KO
1897 HANGUL_SYLLABLE_KO
1898 HANGUL_CIRCLED_JAMO_KO
1899 HANGUL_CIRCLED_SYLLABLE_KO
1900 CHARS_HEBREW
1901 CHARS_NEPALI
1902 CHARS_KHMER
1903 CHARS_LAO
1904 CHARS_TIBETAN
1905 CHARS_CYRILLIC_UPPER_LETTER_BG
1906 CHARS_CYRILLIC_LOWER_LETTER_BG
1907 CHARS_CYRILLIC_UPPER_LETTER_N_BG
1908 CHARS_CYRILLIC_LOWER_LETTER_N_BG
1909 CHARS_CYRILLIC_UPPER_LETTER_RU
1910 CHARS_CYRILLIC_LOWER_LETTER_RU
1911 CHARS_CYRILLIC_UPPER_LETTER_N_RU
1912 CHARS_CYRILLIC_LOWER_LETTER_N_RU
1913 CHARS_CYRILLIC_UPPER_LETTER_SR
1914 CHARS_CYRILLIC_LOWER_LETTER_SR
1915 CHARS_CYRILLIC_UPPER_LETTER_N_SR
1916 CHARS_CYRILLIC_LOWER_LETTER_N_SR*/
1919 for( sal_uInt32 nNum = 0; nNum < sizeof(aNumberingPairs)/sizeof( NumberingPairs ); ++nNum)
1921 if( /*sCommand*/sNumber.equalsAscii(aNumberingPairs[nNum].cWordName ))
1923 nRet = aNumberingPairs[nNum].nType;
1924 break;
1929 return nRet;
1933 OUString lcl_ParseFormat( const OUString& rCommand )
1935 // The command looks like: " DATE \@ "dd MMMM yyyy"
1936 return msfilter::util::findQuotedText(rCommand, "\\@ \"", '\"');
1938 /*-------------------------------------------------------------------------
1939 extract a parameter (with or without quotes) between the command and the following backslash
1940 -----------------------------------------------------------------------*/
1941 OUString lcl_ExtractParameter(const OUString& rCommand, sal_Int32 nCommandLength )
1943 sal_Int32 nStartIndex = nCommandLength;
1944 sal_Int32 nEndIndex = 0;
1945 sal_Int32 nQuoteIndex = rCommand.indexOf( '\"', nStartIndex);
1946 if( nQuoteIndex >= 0)
1948 nStartIndex = nQuoteIndex + 1;
1949 nEndIndex = rCommand.indexOf( '\"', nStartIndex + 1) - 1;
1951 else
1953 nEndIndex = rCommand.indexOf(" \\", nStartIndex);
1955 OUString sRet;
1956 if( nEndIndex > nStartIndex + 1 )
1958 //remove spaces at start and end of the result
1959 if(nQuoteIndex <= 0)
1961 const sal_Unicode* pCommandStr = rCommand.getStr();
1962 while( nStartIndex < nEndIndex && pCommandStr[nStartIndex] == ' ')
1963 ++nStartIndex;
1964 while( nEndIndex > nStartIndex && pCommandStr[nEndIndex] == ' ')
1965 --nEndIndex;
1967 sRet = rCommand.copy( nStartIndex, nEndIndex - nStartIndex + 1);
1969 return sRet;
1974 OUString lcl_ExctractAskVariableAndHint( const OUString& rCommand, OUString& rHint )
1976 // the first word after "ASK " is the variable
1977 // the text after the variable and before a '\' is the hint
1978 // if no hint is set the variable is used as hint
1979 // the quotes of the hint have to be removed
1980 sal_Int32 nIndex = rCommand.indexOf( ' ', 2);//find last space after 'ASK'
1981 while(rCommand.getStr()[nIndex] == ' ')
1982 ++nIndex;
1983 OUString sShortCommand( rCommand.copy( nIndex ) ); //cut off the " ASK "
1985 nIndex = 0;
1986 sShortCommand = sShortCommand.getToken( 0, '\\', nIndex);
1987 nIndex = 0;
1988 OUString sRet = sShortCommand.getToken( 0, ' ', nIndex);
1989 if( nIndex > 0)
1990 rHint = sShortCommand.copy( nIndex );
1991 if( rHint.isEmpty() )
1992 rHint = sRet;
1993 return sRet;
1997 bool lcl_FindInCommand(
1998 const OUString& rCommand,
1999 sal_Unicode cSwitch,
2000 OUString& rValue )
2002 bool bRet = false;
2003 OUString sSearch('\\');
2004 sSearch += OUString( cSwitch );
2005 sal_Int32 nIndex = rCommand.indexOf( sSearch );
2006 if( nIndex >= 0 )
2008 bRet = true;
2009 //find next '\' or end of string
2010 sal_Int32 nEndIndex = rCommand.indexOf( '\\', nIndex + 1);
2011 if( nEndIndex < 0 )
2012 nEndIndex = rCommand.getLength() - 1;
2013 if( nEndIndex - nIndex > 3 )
2014 rValue = rCommand.copy( nIndex + 3, nEndIndex - nIndex - 3);
2016 return bRet;
2020 void DomainMapper_Impl::GetCurrentLocale(lang::Locale& rLocale)
2022 PropertyMapPtr pTopContext = GetTopContext();
2023 PropertyDefinition aCharLocale( PROP_CHAR_LOCALE, true );
2024 PropertyMap::iterator aLocaleIter = pTopContext->find( aCharLocale );
2025 if( aLocaleIter != pTopContext->end())
2026 aLocaleIter->second >>= rLocale;
2027 else
2029 PropertyMapPtr pParaContext = GetTopContextOfType(CONTEXT_PARAGRAPH);
2030 aLocaleIter = pParaContext->find(aCharLocale);
2031 if( aLocaleIter != pParaContext->end())
2033 aLocaleIter->second >>= rLocale;
2038 /*-------------------------------------------------------------------------
2039 extract the number format from the command and apply the resulting number
2040 format to the XPropertySet
2041 -----------------------------------------------------------------------*/
2042 void DomainMapper_Impl::SetNumberFormat( const OUString& rCommand,
2043 uno::Reference< beans::XPropertySet >& xPropertySet )
2045 OUString sFormatString = lcl_ParseFormat( rCommand );
2046 // find \h - hijri/luna calendar todo: what about saka/era calendar?
2047 bool bHijri = 0 < rCommand.indexOf("\\h ");
2048 lang::Locale aUSLocale;
2049 aUSLocale.Language = "en";
2050 aUSLocale.Country = "US";
2052 //determine current locale - todo: is it necessary to initialize this locale?
2053 lang::Locale aCurrentLocale = aUSLocale;
2054 GetCurrentLocale( aCurrentLocale );
2055 OUString sFormat = ConversionHelper::ConvertMSFormatStringToSO( sFormatString, aCurrentLocale, bHijri);
2056 //get the number formatter and convert the string to a format value
2059 uno::Reference< util::XNumberFormatsSupplier > xNumberSupplier( m_xTextDocument, uno::UNO_QUERY_THROW );
2060 sal_Int32 nKey = xNumberSupplier->getNumberFormats()->addNewConverted( sFormat, aUSLocale, aCurrentLocale );
2061 xPropertySet->setPropertyValue(
2062 PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_NUMBER_FORMAT),
2063 uno::makeAny( nKey ));
2064 xPropertySet->getPropertyValue(
2065 PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_NUMBER_FORMAT ) ) >>= nKey;
2067 catch(const uno::Exception&)
2074 uno::Reference< beans::XPropertySet > DomainMapper_Impl::FindOrCreateFieldMaster(
2075 const sal_Char* pFieldMasterService, const OUString& rFieldMasterName )
2076 throw(::com::sun::star::uno::Exception)
2078 // query master, create if not available
2079 uno::Reference< text::XTextFieldsSupplier > xFieldsSupplier( GetTextDocument(), uno::UNO_QUERY_THROW );
2080 uno::Reference< container::XNameAccess > xFieldMasterAccess = xFieldsSupplier->getTextFieldMasters();
2081 uno::Reference< beans::XPropertySet > xMaster;
2082 OUString sFieldMasterService( OUString::createFromAscii(pFieldMasterService) );
2083 OUStringBuffer aFieldMasterName;
2084 aFieldMasterName.appendAscii( pFieldMasterService );
2085 aFieldMasterName.append(sal_Unicode('.'));
2086 aFieldMasterName.append(rFieldMasterName);
2087 OUString sFieldMasterName = aFieldMasterName.makeStringAndClear();
2088 if(xFieldMasterAccess->hasByName(sFieldMasterName))
2090 //get the master
2091 xMaster = uno::Reference< beans::XPropertySet >(xFieldMasterAccess->getByName(sFieldMasterName),
2092 uno::UNO_QUERY_THROW);
2094 else
2096 //create the master
2097 xMaster = uno::Reference< beans::XPropertySet >(
2098 m_xTextFactory->createInstance(sFieldMasterService), uno::UNO_QUERY_THROW);
2099 //set the master's name
2100 xMaster->setPropertyValue(
2101 PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_NAME),
2102 uno::makeAny(rFieldMasterName));
2104 return xMaster;
2107 /*-------------------------------------------------------------------------
2108 //field context starts with a 0x13
2109 -----------------------------------------------------------------------*/
2110 void DomainMapper_Impl::PushFieldContext()
2112 #ifdef DEBUG_DOMAINMAPPER
2113 dmapper_logger->element("pushFieldContext");
2114 #endif
2116 uno::Reference< text::XTextAppend > xTextAppend;
2117 if (!m_aTextAppendStack.empty())
2118 xTextAppend = m_aTextAppendStack.top().xTextAppend;
2119 uno::Reference< text::XTextRange > xStart;
2120 if (xTextAppend.is())
2122 uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange( xTextAppend->getEnd() );
2123 xStart = xCrsr->getStart();
2125 m_aFieldStack.push( FieldContextPtr( new FieldContext( xStart ) ) );
2127 /*-------------------------------------------------------------------------
2128 //the current field context waits for the completion of the command
2129 -----------------------------------------------------------------------*/
2130 bool DomainMapper_Impl::IsOpenFieldCommand() const
2132 return !m_aFieldStack.empty() && !m_aFieldStack.top()->IsCommandCompleted();
2134 /*-------------------------------------------------------------------------
2135 //the current field context waits for the completion of the command
2136 -----------------------------------------------------------------------*/
2137 bool DomainMapper_Impl::IsOpenField() const
2139 return !m_aFieldStack.empty();
2143 FieldContext::FieldContext(uno::Reference< text::XTextRange > xStart) :
2144 m_bFieldCommandCompleted( false )
2145 ,m_xStartRange( xStart )
2150 FieldContext::~FieldContext()
2155 void FieldContext::AppendCommand(const OUString& rPart)
2157 m_sCommand += rPart;
2160 ::std::vector<OUString> FieldContext::GetCommandParts() const
2162 ::std::vector<OUString> aResult;
2163 sal_Int32 nIndex = 0;
2164 bool bInString = false;
2165 OUString sPart;
2166 while (nIndex != -1)
2168 OUString sToken = GetCommand().getToken(0, ' ', nIndex);
2169 bool bInStringNext = bInString;
2171 if (sToken.isEmpty())
2172 continue;
2174 if (sToken.getStr()[0] == '"')
2176 bInStringNext = true;
2177 sToken = sToken.copy(1);
2179 if (sToken.getStr()[sToken.getLength() - 1] == '"')
2181 bInStringNext = false;
2182 sToken = sToken.copy(0, sToken.getLength() - 1);
2185 if (bInString)
2187 sPart += OUString(' ');
2188 sPart += sToken;
2189 if (!bInStringNext)
2191 aResult.push_back(sPart);
2194 else
2196 if (bInStringNext)
2198 sPart = sToken;
2200 else
2202 aResult.push_back(sToken);
2206 bInString = bInStringNext;
2209 return aResult;
2212 /*-------------------------------------------------------------------------
2213 //collect the pieces of the command
2214 -----------------------------------------------------------------------*/
2215 void DomainMapper_Impl::AppendFieldCommand(OUString& rPartOfCommand)
2217 #ifdef DEBUG_DOMAINMAPPER
2218 dmapper_logger->startElement("appendFieldCommand");
2219 dmapper_logger->chars(rPartOfCommand);
2220 dmapper_logger->endElement();
2221 #endif
2223 FieldContextPtr pContext = m_aFieldStack.top();
2224 OSL_ENSURE( pContext.get(), "no field context available");
2225 if( pContext.get() )
2227 pContext->AppendCommand( rPartOfCommand );
2232 typedef std::multimap < sal_Int32, OUString > TOCStyleMap;
2234 const FieldConversionMap_t & lcl_GetFieldConversion()
2236 static FieldConversionMap_t aFieldConversionMap;
2237 static FieldConversionMap_t aEnhancedFieldConversionMap;
2239 static bool bFilled = false;
2241 if(!bFilled)
2243 static const FieldConversion aFields[] =
2245 // {OUString("ADDRESSBLOCK"), "", "", FIELD_ADDRESSBLOCK },
2246 // {OUString("ADVANCE"), "", "", FIELD_ADVANCE },
2247 {OUString("ASK"), "SetExpression", "SetExpression", FIELD_ASK },
2248 {OUString("AUTONUM"), "SetExpression", "SetExpression", FIELD_AUTONUM },
2249 {OUString("AUTONUMLGL"), "SetExpression", "SetExpression", FIELD_AUTONUMLGL },
2250 {OUString("AUTONUMOUT"), "SetExpression", "SetExpression", FIELD_AUTONUMOUT },
2251 {OUString("AUTHOR"), "DocInfo.CreateAuthor", "", FIELD_AUTHOR },
2252 {OUString("DATE"), "DateTime", "", FIELD_DATE },
2253 {OUString("COMMENTS"), "DocInfo.Description", "", FIELD_COMMENTS },
2254 {OUString("CREATEDATE"), "DocInfo.CreateDateTime", "", FIELD_CREATEDATE },
2255 {OUString("DOCPROPERTY"), "", "", FIELD_DOCPROPERTY },
2256 {OUString("DOCVARIABLE"), "User", "", FIELD_DOCVARIABLE },
2257 {OUString("EDITTIME"), "DocInfo.EditTime", "", FIELD_EDITTIME },
2258 {OUString("EQ"), "", "", FIELD_EQ },
2259 {OUString("FILLIN"), "Input", "", FIELD_FILLIN },
2260 {OUString("FILENAME"), "FileName", "", FIELD_FILENAME },
2261 // {OUString("FILESIZE"), "", "", FIELD_FILESIZE },
2262 // {OUString("FORMULA"), "", "", FIELD_FORMULA },
2263 {OUString("FORMCHECKBOX"), "", "", FIELD_FORMCHECKBOX},
2264 {OUString("FORMDROPDOWN"), "DropDown", "", FIELD_FORMDROPDOWN},
2265 {OUString("FORMTEXT"), "Input", "", FIELD_FORMTEXT},
2266 // {OUString("GOTOBUTTON"), "", "", FIELD_GOTOBUTTON },
2267 {OUString("HYPERLINK"), "", "", FIELD_HYPERLINK },
2268 {OUString("IF"), "ConditionalText", "", FIELD_IF },
2269 // {OUString("INFO"), "","", FIELD_INFO },
2270 // {OUString("INCLUDEPICTURE"), "", "", FIELD_INCLUDEPICTURE},
2271 {OUString("KEYWORDS"), "DocInfo.KeyWords", "", FIELD_KEYWORDS },
2272 {OUString("LASTSAVEDBY"), "DocInfo.ChangeAuthor", "", FIELD_LASTSAVEDBY },
2273 {OUString("MACROBUTTON"), "Macro", "", FIELD_MACROBUTTON },
2274 {OUString("MERGEFIELD"), "Database", "Database", FIELD_MERGEFIELD},
2275 {OUString("MERGEREC"), "DatabaseNumberOfSet", "", FIELD_MERGEREC },
2276 // {OUString("MERGESEQ"), "", "", FIELD_MERGESEQ },
2277 {OUString("NEXT"), "DatabaseNextSet", "", FIELD_NEXT },
2278 {OUString("NEXTIF"), "DatabaseNextSet", "", FIELD_NEXTIF },
2279 {OUString("PAGE"), "PageNumber", "", FIELD_PAGE },
2280 {OUString("PAGEREF"), "GetReference", "", FIELD_PAGEREF },
2281 {OUString("REF"), "GetReference", "", FIELD_REF },
2282 {OUString("REVNUM"), "DocInfo.Revision", "", FIELD_REVNUM },
2283 {OUString("SAVEDATE"), "DocInfo.Change", "", FIELD_SAVEDATE },
2284 // {OUString("SECTION"), "", "", FIELD_SECTION },
2285 // {OUString("SECTIONPAGES"), "", "", FIELD_SECTIONPAGES },
2286 {OUString("SEQ"), "SetExpression", "SetExpression", FIELD_SEQ },
2287 // {OUString("SET"), "","", FIELD_SET },
2288 // {OUString("SKIPIF"),"", "", FIELD_SKIPIF },
2289 // {OUString("STYLEREF"),"", "", FIELD_STYLEREF },
2290 {OUString("SUBJECT"), "DocInfo.Subject", "", FIELD_SUBJECT },
2291 // {OUString("SYMBOL"),"", "", FIELD_SYMBOL },
2292 {OUString("TEMPLATE"), "TemplateName", "", FIELD_TEMPLATE},
2293 {OUString("TIME"), "DateTime", "", FIELD_TIME },
2294 {OUString("TITLE"), "DocInfo.Title", "", FIELD_TITLE },
2295 {OUString("USERINITIALS"), "Author", "", FIELD_USERINITIALS },
2296 // {OUString("USERADDRESS"), "", "", FIELD_USERADDRESS },
2297 {OUString("USERNAME"), "Author", "", FIELD_USERNAME },
2300 {OUString("TOC"), "com.sun.star.text.ContentIndex", "", FIELD_TOC},
2301 {OUString("TC"), "com.sun.star.text.ContentIndexMark", "", FIELD_TC},
2302 {OUString("NUMCHARS"), "CharacterCount", "", FIELD_NUMCHARS},
2303 {OUString("NUMWORDS"), "WordCount", "", FIELD_NUMWORDS},
2304 {OUString("NUMPAGES"), "PageCount", "", FIELD_NUMPAGES},
2306 // {OUString(""), "", "", FIELD_},
2309 size_t nConversions = SAL_N_ELEMENTS(aFields);
2310 for( size_t nConversion = 0; nConversion < nConversions; ++nConversion)
2312 aFieldConversionMap.insert( FieldConversionMap_t::value_type(
2313 aFields[nConversion].sWordCommand,
2314 aFields[nConversion] ));
2317 bFilled = true;
2320 return aFieldConversionMap;
2323 const FieldConversionMap_t & lcl_GetEnhancedFieldConversion()
2325 static FieldConversionMap_t aEnhancedFieldConversionMap;
2327 static bool bFilled = false;
2329 if(!bFilled)
2331 static const FieldConversion aEnhancedFields[] =
2333 {OUString("FORMCHECKBOX"), "FormFieldmark", "", FIELD_FORMCHECKBOX},
2334 {OUString("FORMDROPDOWN"), "FormFieldmark", "", FIELD_FORMDROPDOWN},
2335 {OUString("FORMTEXT"), "Fieldmark", "", FIELD_FORMTEXT},
2338 size_t nConversions = SAL_N_ELEMENTS(aEnhancedFields);
2339 for( size_t nConversion = 0; nConversion < nConversions; ++nConversion)
2341 aEnhancedFieldConversionMap.insert( FieldConversionMap_t::value_type(
2342 aEnhancedFields[nConversion].sWordCommand,
2343 aEnhancedFields[nConversion] ));
2346 return aEnhancedFieldConversionMap;
2349 void DomainMapper_Impl::handleFieldAsk
2350 (FieldContextPtr pContext,
2351 PropertyNameSupplier& rPropNameSupplier,
2352 uno::Reference< uno::XInterface > & xFieldInterface,
2353 uno::Reference< beans::XPropertySet > xFieldProperties)
2355 //doesn the command contain a variable name?
2356 OUString sVariable, sHint;
2358 sVariable = lcl_ExctractAskVariableAndHint( pContext->GetCommand(),
2359 sHint );
2360 if(!sVariable.isEmpty())
2362 // determine field master name
2363 uno::Reference< beans::XPropertySet > xMaster =
2364 FindOrCreateFieldMaster
2365 ("com.sun.star.text.FieldMaster.SetExpression", sVariable );
2366 // An ASK field is always a string of characters
2367 xMaster->setPropertyValue(rPropNameSupplier.GetName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING));
2369 // attach the master to the field
2370 uno::Reference< text::XDependentTextField > xDependentField
2371 ( xFieldInterface, uno::UNO_QUERY_THROW );
2372 xDependentField->attachTextFieldMaster( xMaster );
2374 // set input flag at the field
2375 xFieldProperties->setPropertyValue(
2376 rPropNameSupplier.GetName(PROP_IS_INPUT), uno::makeAny( true ));
2377 // set the prompt
2378 xFieldProperties->setPropertyValue(
2379 rPropNameSupplier.GetName(PROP_HINT),
2380 uno::makeAny( sHint ));
2381 xFieldProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING));
2382 // The ASK has no field value to display
2383 xFieldProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_IS_VISIBLE), uno::makeAny(sal_False));
2385 else
2387 //don't insert the field
2388 //todo: maybe import a 'normal' input field here?
2389 xFieldInterface = 0;
2393 void DomainMapper_Impl::handleAutoNum
2394 (FieldContextPtr pContext,
2395 PropertyNameSupplier& rPropNameSupplier,
2396 uno::Reference< uno::XInterface > & xFieldInterface,
2397 uno::Reference< beans::XPropertySet > xFieldProperties)
2399 //create a sequence field master "AutoNr"
2400 uno::Reference< beans::XPropertySet > xMaster =
2401 FindOrCreateFieldMaster
2402 ("com.sun.star.text.FieldMaster.SetExpression",
2403 "AutoNr");
2405 xMaster->setPropertyValue( rPropNameSupplier.GetName(PROP_SUB_TYPE),
2406 uno::makeAny(text::SetVariableType::SEQUENCE));
2408 //apply the numbering type
2409 xFieldProperties->setPropertyValue(
2410 rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
2411 uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) ));
2412 // attach the master to the field
2413 uno::Reference< text::XDependentTextField > xDependentField
2414 ( xFieldInterface, uno::UNO_QUERY_THROW );
2415 xDependentField->attachTextFieldMaster( xMaster );
2418 void DomainMapper_Impl::handleAuthor
2419 (FieldContextPtr pContext,
2420 PropertyNameSupplier& rPropNameSupplier,
2421 uno::Reference< uno::XInterface > & /*xFieldInterface*/,
2422 uno::Reference< beans::XPropertySet > xFieldProperties,
2423 FieldId eFieldId )
2425 if ( eFieldId != FIELD_USERINITIALS )
2426 xFieldProperties->setPropertyValue
2427 ( rPropNameSupplier.GetName(PROP_FULL_NAME), uno::makeAny( true ));
2429 sal_Int32 nLen = sizeof( " AUTHOR" );
2430 if ( eFieldId != FIELD_AUTHOR )
2432 if ( eFieldId == FIELD_USERINITIALS )
2433 nLen = sizeof( " USERINITIALS" );
2434 else if ( eFieldId == FIELD_USERNAME )
2435 nLen = sizeof( " USERNAME" );
2438 OUString sParam =
2439 lcl_ExtractParameter(pContext->GetCommand(), nLen );
2441 if(!sParam.isEmpty())
2443 xFieldProperties->setPropertyValue(
2444 rPropNameSupplier.GetName( PROP_IS_FIXED ),
2445 uno::makeAny( true ));
2446 //PROP_CURRENT_PRESENTATION is set later anyway
2450 void DomainMapper_Impl::handleDocProperty
2451 (FieldContextPtr pContext,
2452 PropertyNameSupplier& rPropNameSupplier,
2453 uno::Reference< uno::XInterface > & xFieldInterface,
2454 uno::Reference< beans::XPropertySet > xFieldProperties)
2456 //some docproperties should be imported as document statistic fields, some as DocInfo fields
2457 //others should be user fields
2458 OUString sParam =
2459 lcl_ExtractParameter(pContext->GetCommand(), sizeof(" DOCPROPERTY") );
2461 if(!sParam.isEmpty())
2463 #define SET_ARABIC 0x01
2464 #define SET_FULL_NAME 0x02
2465 #define SET_DATE 0x04
2466 struct DocPropertyMap
2468 const sal_Char* pDocPropertyName;
2469 const sal_Char* pServiceName;
2470 sal_uInt8 nFlags;
2472 static const DocPropertyMap aDocProperties[] =
2474 {"CreateTime", "DocInfo.CreateDateTime", SET_DATE},
2475 {"Characters", "CharacterCount", SET_ARABIC},
2476 {"Comments", "DocInfo.Description", 0},
2477 {"Keywords", "DocInfo.KeyWords", 0},
2478 {"LastPrinted", "DocInfo.PrintDateTime", 0},
2479 {"LastSavedBy", "DocInfo.ChangeAuthor", 0},
2480 {"LastSavedTime", "DocInfo.ChangeDateTime", SET_DATE},
2481 {"Paragraphs", "ParagraphCount", SET_ARABIC},
2482 {"RevisionNumber", "DocInfo.Revision", 0},
2483 {"Subject", "DocInfo.Subject", 0},
2484 {"Template", "TemplateName", 0},
2485 {"Title", "DocInfo.Title", 0},
2486 {"TotalEditingTime", "DocInfo.EditTime", 0},
2487 {"Words", "WordCount", SET_ARABIC}
2489 //other available DocProperties:
2490 //Bytes, Category, CharactersWithSpaces, Company
2491 //HyperlinkBase,
2492 //Lines, Manager, NameofApplication, ODMADocId, Pages,
2493 //Security,
2495 //search for a field mapping
2496 OUString sFieldServiceName;
2497 sal_uInt16 nMap = 0;
2498 for( ; nMap < sizeof(aDocProperties) / sizeof(DocPropertyMap);
2499 ++nMap )
2501 if(sParam.equalsAscii(aDocProperties[nMap].pDocPropertyName))
2503 sFieldServiceName =
2504 OUString::createFromAscii
2505 (aDocProperties[nMap].pServiceName);
2506 break;
2509 OUString sServiceName("com.sun.star.text.TextField.");
2510 bool bIsCustomField = false;
2511 if(sFieldServiceName.isEmpty())
2513 //create a custom property field
2514 sServiceName += "DocInfo.Custom";
2515 bIsCustomField = true;
2517 else
2519 sServiceName += sFieldServiceName;
2521 if (m_xTextFactory.is())
2522 xFieldInterface = m_xTextFactory->createInstance(sServiceName);
2523 xFieldProperties =
2524 uno::Reference< beans::XPropertySet >( xFieldInterface,
2525 uno::UNO_QUERY_THROW);
2526 if( bIsCustomField )
2527 xFieldProperties->setPropertyValue(
2528 rPropNameSupplier.GetName(PROP_NAME), uno::makeAny( sParam ));
2529 else
2531 if(0 != (aDocProperties[nMap].nFlags & SET_ARABIC))
2532 xFieldProperties->setPropertyValue(
2533 rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
2534 uno::makeAny( style::NumberingType::ARABIC ));
2535 else if(0 != (aDocProperties[nMap].nFlags & SET_FULL_NAME))
2536 xFieldProperties->setPropertyValue(
2537 rPropNameSupplier.GetName(PROP_FULL_NAME),
2538 uno::makeAny( true ));
2539 else if(0 != (aDocProperties[nMap].nFlags & SET_DATE))
2541 xFieldProperties->setPropertyValue(
2542 rPropNameSupplier.GetName(PROP_IS_DATE),
2543 uno::makeAny( true ));
2544 SetNumberFormat( pContext->GetCommand(), xFieldProperties );
2549 #undef SET_ARABIC
2550 #undef SET_FULL_NAME
2551 #undef SET_DATE
2554 uno::Sequence< beans::PropertyValues > lcl_createTOXLevelHyperlinks( bool bHyperlinks, OUString sChapterNoSeparator,
2555 uno::Sequence< beans::PropertyValues >aLevel,
2556 PropertyNameSupplier& rPropNameSupplier )
2558 //create a copy of the level and add two new entries - hyperlink start and end
2559 bool bChapterNoSeparator = !sChapterNoSeparator.isEmpty();
2560 sal_Int32 nAdd = (bHyperlinks && bChapterNoSeparator) ? 4 : 2;
2561 uno::Sequence< beans::PropertyValues > aNewLevel( aLevel.getLength() + nAdd);
2562 beans::PropertyValues* pNewLevel = aNewLevel.getArray();
2563 if( bHyperlinks )
2565 beans::PropertyValues aHyperlink(1);
2566 aHyperlink[0].Name = rPropNameSupplier.GetName( PROP_TOKEN_TYPE );
2567 aHyperlink[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_HYPERLINK_START );
2568 pNewLevel[0] = aHyperlink;
2569 aHyperlink[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_HYPERLINK_END );
2570 pNewLevel[aNewLevel.getLength() -1] = aHyperlink;
2572 if( bChapterNoSeparator )
2574 beans::PropertyValues aChapterNo(2);
2575 aChapterNo[0].Name = rPropNameSupplier.GetName( PROP_TOKEN_TYPE );
2576 aChapterNo[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_CHAPTER_INFO );
2577 aChapterNo[1].Name = rPropNameSupplier.GetName( PROP_CHAPTER_FORMAT );
2578 //todo: is ChapterFormat::Number correct?
2579 aChapterNo[1].Value <<= (sal_Int16)text::ChapterFormat::NUMBER;
2580 pNewLevel[aNewLevel.getLength() - (bHyperlinks ? 4 : 2) ] = aChapterNo;
2582 beans::PropertyValues aChapterSeparator(2);
2583 aChapterSeparator[0].Name = rPropNameSupplier.GetName( PROP_TOKEN_TYPE );
2584 aChapterSeparator[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_TEXT );
2585 aChapterSeparator[1].Name = rPropNameSupplier.GetName( PROP_TEXT );
2586 aChapterSeparator[1].Value <<= sChapterNoSeparator;
2587 pNewLevel[aNewLevel.getLength() - (bHyperlinks ? 3 : 1)] = aChapterSeparator;
2589 //copy the 'old' entries except the last (page no)
2590 for( sal_Int32 nToken = 0; nToken < aLevel.getLength() - 1; ++nToken)
2592 pNewLevel[nToken + 1] = aLevel[nToken];
2594 //copy page no entry (last or last but one depending on bHyperlinks
2595 sal_Int32 nPageNo = aNewLevel.getLength() - (bHyperlinks ? 2 : 3);
2596 pNewLevel[nPageNo] = aLevel[aLevel.getLength() - 1];
2598 return aNewLevel;
2601 void DomainMapper_Impl::handleToc
2602 (FieldContextPtr pContext,
2603 PropertyNameSupplier& rPropNameSupplier,
2604 uno::Reference< uno::XInterface > & /*xFieldInterface*/,
2605 uno::Reference< beans::XPropertySet > /*xFieldProperties*/,
2606 const OUString & sTOCServiceName)
2608 OUString sValue;
2609 bool bTableOfFigures = false;
2610 bool bHyperlinks = false;
2611 bool bFromOutline = false;
2612 bool bFromEntries = false;
2613 sal_Int16 nMaxLevel = 10;
2614 OUString sTemplate;
2615 OUString sChapterNoSeparator;
2616 OUString sFigureSequence;
2618 // \a Builds a table of figures but does not include the captions's label and number
2619 if( lcl_FindInCommand( pContext->GetCommand(), 'a', sValue ))
2620 { //make it a table of figures
2621 bTableOfFigures = true;
2623 // \b Uses a bookmark to specify area of document from which to build table of contents
2624 // if( lcl_FindInCommand( pContext->GetCommand(), 'b', sValue ))
2625 // { //todo: sValue contains the bookmark name - unsupported feature
2626 // }
2627 if( lcl_FindInCommand( pContext->GetCommand(), 'c', sValue ))
2628 // \c Builds a table of figures of the given label
2630 //todo: sValue contains the label's name
2631 bTableOfFigures = true;
2632 sFigureSequence = sValue.trim();
2633 sFigureSequence = sFigureSequence.replaceAll("\"", "").replaceAll("'","");
2635 // \d Defines the separator between sequence and page numbers
2636 if( lcl_FindInCommand( pContext->GetCommand(), 'd', sValue ))
2638 //todo: insert the chapter number into each level and insert the separator additionally
2639 sChapterNoSeparator = sValue;
2641 // \f Builds a table of contents using TC entries instead of outline levels
2642 if( lcl_FindInCommand( pContext->GetCommand(), 'f', sValue ))
2644 //todo: sValue can contain a TOC entry identifier - use unclear
2645 bFromEntries = true;
2647 // \h Hyperlinks the entries and page numbers within the table of contents
2648 if( lcl_FindInCommand( pContext->GetCommand(), 'h', sValue ))
2650 //todo: make all entries to hyperlinks
2651 bHyperlinks = true;
2653 // \l Defines the TC entries field level used to build a table of contents
2654 // if( lcl_FindInCommand( pContext->GetCommand(), 'l', sValue ))
2655 // {
2656 //todo: entries can only be included completely
2657 // }
2658 // \n Builds a table of contents or a range of entries, such as 1-9 in a table of contents without page numbers
2659 // if( lcl_FindInCommand( pContext->GetCommand(), 'n', sValue ))
2660 // {
2661 //todo: what does the description mean?
2662 // }
2663 // \o Builds a table of contents by using outline levels instead of TC entries
2664 if( lcl_FindInCommand( pContext->GetCommand(), 'o', sValue ))
2666 bFromOutline = true;
2667 if (sValue.isEmpty())
2668 nMaxLevel = WW_OUTLINE_MAX;
2669 else
2671 sal_Int32 nIndex = 0;
2672 sValue.getToken( 0, '-', nIndex );
2673 nMaxLevel = static_cast<sal_Int16>(nIndex != -1 ? sValue.copy(nIndex).toInt32() : 0);
2676 // \p Defines the separator between the table entry and its page number
2677 if( lcl_FindInCommand( pContext->GetCommand(), 'p', sValue ))
2679 // \s Builds a table of contents by using a sequence type
2680 if( lcl_FindInCommand( pContext->GetCommand(), 's', sValue ))
2682 // \t Builds a table of contents by using style names other than the standard outline styles
2683 if( lcl_FindInCommand( pContext->GetCommand(), 't', sValue ))
2685 sal_Int32 nPos = 0;
2686 OUString sToken = sValue.getToken( 1, '"', nPos);
2687 sTemplate = sToken.isEmpty() ? sValue : sToken;
2689 // \u Builds a table of contents by using the applied paragraph outline level
2690 if( lcl_FindInCommand( pContext->GetCommand(), 'u', sValue ))
2692 bFromOutline = true;
2693 //todo: what doesn 'the applied paragraph outline level' refer to?
2695 // \w Preserve tab characters within table entries
2696 // if( lcl_FindInCommand( pContext->GetCommand(), 'w', sValue ))
2697 // {
2698 //todo: not supported
2699 // }
2700 // \x Preserve newline characters within table entries
2701 // if( lcl_FindInCommand( pContext->GetCommand(), 'x', sValue ))
2702 // {
2703 //todo: unsupported
2704 // }
2705 // \z Hides page numbers within the table of contens when shown in Web Layout View
2706 // if( lcl_FindInCommand( pContext->GetCommand(), 'z', sValue ))
2707 // { //todo: unsupported feature }
2709 //if there's no option then it should be created from outline
2710 if( !bFromOutline && !bFromEntries && sTemplate.isEmpty() )
2711 bFromOutline = true;
2713 uno::Reference< beans::XPropertySet > xTOC;
2714 if (m_xTextFactory.is())
2715 xTOC.set(
2716 m_xTextFactory->createInstance
2717 ( bTableOfFigures ?
2718 "com.sun.star.text.IllustrationsIndex"
2719 : sTOCServiceName),
2720 uno::UNO_QUERY_THROW);
2721 if (xTOC.is())
2722 xTOC->setPropertyValue(rPropNameSupplier.GetName( PROP_TITLE ), uno::makeAny(OUString()));
2723 if( !bTableOfFigures && xTOC.is() )
2725 xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_LEVEL ), uno::makeAny( nMaxLevel ) );
2726 xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_CREATE_FROM_OUTLINE ), uno::makeAny( bFromOutline ));
2727 xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_CREATE_FROM_MARKS ), uno::makeAny( bFromEntries ));
2728 if( !sTemplate.isEmpty() )
2730 //the string contains comma separated the names and related levels
2731 //like: "Heading 1,1,Heading 2,2"
2732 TOCStyleMap aMap;
2733 sal_Int32 nLevel;
2734 sal_Int32 nPosition = 0;
2735 while( nPosition >= 0)
2737 OUString sStyleName = sTemplate.getToken( 0, ',', nPosition );
2738 //empty tokens should be skipped
2739 while( sStyleName.isEmpty() && nPosition > 0 )
2740 sStyleName = sTemplate.getToken( 0, ',', nPosition );
2741 nLevel = sTemplate.getToken( 0, ',', nPosition ).toInt32();
2742 if( !nLevel )
2743 nLevel = 1;
2744 if( !sStyleName.isEmpty() )
2745 aMap.insert( TOCStyleMap::value_type(nLevel, sStyleName) );
2747 uno::Reference< container::XIndexReplace> xParaStyles;
2748 xTOC->getPropertyValue(rPropNameSupplier.GetName(PROP_LEVEL_PARAGRAPH_STYLES)) >>= xParaStyles;
2749 for( nLevel = 1; nLevel < 10; ++nLevel)
2751 sal_Int32 nLevelCount = aMap.count( nLevel );
2752 if( nLevelCount )
2754 TOCStyleMap::iterator aTOCStyleIter = aMap.find( nLevel );
2756 uno::Sequence< OUString> aStyles( nLevelCount );
2757 for ( sal_Int32 nStyle = 0; nStyle < nLevelCount; ++nStyle, ++aTOCStyleIter )
2759 aStyles[nStyle] = aTOCStyleIter->second;
2761 xParaStyles->replaceByIndex(nLevel - 1, uno::makeAny(aStyles));
2764 xTOC->setPropertyValue(rPropNameSupplier.GetName(PROP_CREATE_FROM_LEVEL_PARAGRAPH_STYLES), uno::makeAny( true ));
2767 if(bHyperlinks || !sChapterNoSeparator.isEmpty())
2769 uno::Reference< container::XIndexReplace> xLevelFormats;
2770 xTOC->getPropertyValue(rPropNameSupplier.GetName(PROP_LEVEL_FORMAT)) >>= xLevelFormats;
2771 sal_Int32 nLevelCount = xLevelFormats->getCount();
2772 //start with level 1, 0 is the header level
2773 for( sal_Int32 nLevel = 1; nLevel < nLevelCount; ++nLevel)
2775 uno::Sequence< beans::PropertyValues > aLevel;
2776 xLevelFormats->getByIndex( nLevel ) >>= aLevel;
2778 uno::Sequence< beans::PropertyValues > aNewLevel = lcl_createTOXLevelHyperlinks(
2779 bHyperlinks, sChapterNoSeparator,
2780 aLevel, rPropNameSupplier );
2781 xLevelFormats->replaceByIndex( nLevel, uno::makeAny( aNewLevel ) );
2785 else if (bTableOfFigures && xTOC.is())
2787 if (!sFigureSequence.isEmpty())
2788 xTOC->setPropertyValue(rPropNameSupplier.GetName(PROP_LABEL_CATEGORY),
2789 uno::makeAny(sFigureSequence));
2791 if ( bHyperlinks )
2793 uno::Reference< container::XIndexReplace> xLevelFormats;
2794 xTOC->getPropertyValue(rPropNameSupplier.GetName(PROP_LEVEL_FORMAT)) >>= xLevelFormats;
2795 uno::Sequence< beans::PropertyValues > aLevel;
2796 xLevelFormats->getByIndex( 1 ) >>= aLevel;
2798 uno::Sequence< beans::PropertyValues > aNewLevel = lcl_createTOXLevelHyperlinks(
2799 bHyperlinks, sChapterNoSeparator,
2800 aLevel, rPropNameSupplier );
2801 xLevelFormats->replaceByIndex( 1, uno::makeAny( aNewLevel ) );
2804 pContext->SetTOC( xTOC );
2808 /*-------------------------------------------------------------------------
2809 //the field command has to be closed (0x14 appeared)
2810 -----------------------------------------------------------------------*/
2811 void DomainMapper_Impl::CloseFieldCommand()
2813 #ifdef DEBUG_DOMAINMAPPER
2814 dmapper_logger->element("closeFieldCommand");
2815 #endif
2817 FieldContextPtr pContext = m_aFieldStack.top();
2818 OSL_ENSURE( pContext.get(), "no field context available");
2819 if( pContext.get() )
2821 m_bSetUserFieldContent = false;
2822 FieldConversionMap_t aFieldConversionMap = lcl_GetFieldConversion();
2823 bool bCreateEnhancedField = false;
2827 uno::Reference< uno::XInterface > xFieldInterface;
2828 //at first determine the field type - erase leading and trailing whitespaces
2829 OUString sCommand( pContext->GetCommand().trim() );
2830 sal_Int32 nSpaceIndex = sCommand.indexOf( ' ' );
2831 if( 0 <= nSpaceIndex )
2832 sCommand = sCommand.copy( 0, nSpaceIndex );
2834 FieldConversionMap_t::iterator aIt = aFieldConversionMap.find(sCommand);
2835 if(aIt != aFieldConversionMap.end())
2837 uno::Reference< beans::XPropertySet > xFieldProperties;
2838 bool bCreateField = true;
2839 switch (aIt->second.eFieldId)
2841 case FIELD_HYPERLINK:
2842 case FIELD_DOCPROPERTY:
2843 case FIELD_TOC:
2844 case FIELD_TC:
2845 case FIELD_EQ:
2846 bCreateField = false;
2847 break;
2848 case FIELD_FORMCHECKBOX :
2849 case FIELD_FORMTEXT :
2850 case FIELD_FORMDROPDOWN :
2852 // If we use 'enhanced' fields then FIELD_FORMCHECKBOX,
2853 // FIELD_FORMTEXT & FIELD_FORMDROPDOWN are treated specially
2854 if ( m_bUsingEnhancedFields )
2856 bCreateField = false;
2857 bCreateEnhancedField = true;
2859 // for non enhanced fields checkboxes are displayed
2860 // as an awt control not a field
2861 else if ( aIt->second.eFieldId == FIELD_FORMCHECKBOX )
2862 bCreateField = false;
2863 break;
2865 default:
2866 break;
2869 if( bCreateField || bCreateEnhancedField )
2871 //add the service prefix
2872 OUString sServiceName("com.sun.star.text.");
2873 if ( bCreateEnhancedField )
2875 FieldConversionMap_t aEnhancedFieldConversionMap = lcl_GetEnhancedFieldConversion();
2876 FieldConversionMap_t::iterator aEnhancedIt = aEnhancedFieldConversionMap.find(sCommand);
2877 if ( aEnhancedIt != aEnhancedFieldConversionMap.end())
2878 sServiceName += OUString::createFromAscii(aEnhancedIt->second.cFieldServiceName );
2880 else
2882 sServiceName += "TextField.";
2883 sServiceName += OUString::createFromAscii(aIt->second.cFieldServiceName );
2886 #ifdef DEBUG_DOMAINMAPPER
2887 dmapper_logger->startElement("fieldService");
2888 dmapper_logger->chars(sServiceName);
2889 dmapper_logger->endElement();
2890 #endif
2892 if (m_xTextFactory.is())
2894 xFieldInterface = m_xTextFactory->createInstance(sServiceName);
2895 xFieldProperties = uno::Reference< beans::XPropertySet >( xFieldInterface, uno::UNO_QUERY_THROW);
2898 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
2899 switch( aIt->second.eFieldId )
2901 case FIELD_ADDRESSBLOCK: break;
2902 case FIELD_ADVANCE : break;
2903 case FIELD_ASK :
2904 handleFieldAsk(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties);
2905 break;
2906 case FIELD_AUTONUM :
2907 case FIELD_AUTONUMLGL :
2908 case FIELD_AUTONUMOUT :
2909 handleAutoNum(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties);
2910 break;
2911 case FIELD_AUTHOR :
2912 case FIELD_USERNAME :
2913 case FIELD_USERINITIALS :
2914 handleAuthor(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties, aIt->second.eFieldId );
2915 break;
2916 case FIELD_DATE:
2917 if (xFieldProperties.is())
2919 //not fixed,
2920 xFieldProperties->setPropertyValue(
2921 rPropNameSupplier.GetName(PROP_IS_FIXED),
2922 uno::makeAny( false ));
2923 xFieldProperties->setPropertyValue(
2924 rPropNameSupplier.GetName(PROP_IS_DATE),
2925 uno::makeAny( true ));
2926 SetNumberFormat( pContext->GetCommand(), xFieldProperties );
2928 break;
2929 case FIELD_COMMENTS :
2931 // OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" COMMENTS") );
2932 // A parameter with COMMENTS shouldn't set fixed
2933 // ( or at least the binary filter doesn't )
2934 // If we set fixed then we wont export a field cmd.
2935 // Additionally the para in COMMENTS is more like an
2936 // instruction to set the document property comments
2937 // with the param ( e.g. each COMMENT with a param will
2938 // overwrite the Comments document property
2939 // #TODO implement the above too
2940 xFieldProperties->setPropertyValue(
2941 rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( false ));
2942 //PROP_CURRENT_PRESENTATION is set later anyway
2944 break;
2945 case FIELD_CREATEDATE :
2947 xFieldProperties->setPropertyValue(
2948 rPropNameSupplier.GetName( PROP_IS_DATE ), uno::makeAny( true ));
2949 SetNumberFormat( pContext->GetCommand(), xFieldProperties );
2951 break;
2952 case FIELD_DOCPROPERTY :
2953 handleDocProperty(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties);
2954 break;
2955 case FIELD_DOCVARIABLE :
2957 OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" DOCVARIABLE") );
2958 //create a user field and type
2959 uno::Reference< beans::XPropertySet > xMaster =
2960 FindOrCreateFieldMaster( "com.sun.star.text.FieldMaster.User", sParam );
2961 uno::Reference< text::XDependentTextField > xDependentField( xFieldInterface, uno::UNO_QUERY_THROW );
2962 xDependentField->attachTextFieldMaster( xMaster );
2963 m_bSetUserFieldContent = true;
2965 break;
2966 case FIELD_EDITTIME :
2967 //it's a numbering type, no number format! SetNumberFormat( pContext->GetCommand(), xFieldProperties );
2968 break;
2969 case FIELD_EQ:
2971 OUString aCommand = pContext->GetCommand().trim();
2972 nSpaceIndex = aCommand.indexOf(' ');
2973 if(nSpaceIndex > 0)
2974 aCommand = aCommand.copy(nSpaceIndex).trim();
2975 if (aCommand.startsWith("\\s"))
2977 aCommand = aCommand.copy(2);
2978 if (aCommand.startsWith("\\do"))
2980 aCommand = aCommand.copy(3);
2981 sal_Int32 nStartIndex = aCommand.indexOf('(');
2982 sal_Int32 nEndIndex = aCommand.indexOf(')');
2983 if (nStartIndex > 0 && nEndIndex > 0)
2985 // nDown is the requested "lower by" value in points.
2986 sal_Int32 nDown = aCommand.copy(0, nStartIndex).toInt32();
2987 OUString aContent = aCommand.copy(nStartIndex + 1, nEndIndex - nStartIndex - 1);
2988 PropertyMapPtr pCharContext = GetTopContext();
2989 // dHeight is the font size of the current style.
2990 double dHeight = 0;
2991 if (GetPropertyFromStyleSheet(PROP_CHAR_HEIGHT) >>= dHeight)
2992 // Character escapement should be given in negative percents for subscripts.
2993 pCharContext->Insert(PROP_CHAR_ESCAPEMENT, true, uno::makeAny( sal_Int16(- 100 * nDown / dHeight) ) );
2994 appendTextPortion(aContent, pCharContext);
2999 break;
3000 case FIELD_FILLIN :
3002 sal_Int32 nIndex = 0;
3003 if (xFieldProperties.is())
3004 xFieldProperties->setPropertyValue(
3005 rPropNameSupplier.GetName(PROP_HINT), uno::makeAny( pContext->GetCommand().getToken( 1, '\"', nIndex)));
3007 break;
3008 case FIELD_FILENAME:
3010 sal_Int32 nNumberingTypeIndex = pContext->GetCommand().indexOf("\\p");
3011 if (xFieldProperties.is())
3012 xFieldProperties->setPropertyValue(
3013 rPropNameSupplier.GetName(PROP_FILE_FORMAT),
3014 uno::makeAny( nNumberingTypeIndex > 0 ? text::FilenameDisplayFormat::FULL : text::FilenameDisplayFormat::NAME ));
3016 break;
3017 case FIELD_FILESIZE : break;
3018 case FIELD_FORMULA : break;
3019 case FIELD_FORMCHECKBOX :
3020 case FIELD_FORMDROPDOWN :
3021 case FIELD_FORMTEXT :
3023 uno::Reference< text::XTextField > xTextField( xFieldInterface, uno::UNO_QUERY );
3024 if ( !xTextField.is() )
3026 FFDataHandler::Pointer_t
3027 pFFDataHandler(pContext->getFFDataHandler());
3028 FormControlHelper::Pointer_t
3029 pFormControlHelper(new FormControlHelper
3030 (m_bUsingEnhancedFields ? aIt->second.eFieldId : FIELD_FORMCHECKBOX,
3032 m_xTextDocument, pFFDataHandler));
3033 pContext->setFormControlHelper(pFormControlHelper);
3034 uno::Reference< text::XFormField > xFormField( xFieldInterface, uno::UNO_QUERY );
3035 uno::Reference< container::XNamed > xNamed( xFormField, uno::UNO_QUERY );
3036 if ( xNamed.is() )
3038 if ( pFFDataHandler && !pFFDataHandler->getName().isEmpty() )
3039 xNamed->setName( pFFDataHandler->getName() );
3040 pContext->SetFormField( xFormField );
3043 else
3045 if ( aIt->second.eFieldId == FIELD_FORMDROPDOWN )
3046 lcl_handleDropdownField( xFieldProperties, pContext->getFFDataHandler() );
3047 else
3048 lcl_handleTextField( xFieldProperties, pContext->getFFDataHandler(), rPropNameSupplier );
3051 break;
3052 case FIELD_GOTOBUTTON : break;
3053 case FIELD_HYPERLINK:
3055 ::std::vector<OUString> aParts = pContext->GetCommandParts();
3056 ::std::vector<OUString>::const_iterator aItEnd = aParts.end();
3057 ::std::vector<OUString>::const_iterator aPartIt = aParts.begin();
3059 OUString sURL;
3061 while (aPartIt != aItEnd)
3063 if ( *aPartIt == "\\l" )
3065 ++aPartIt;
3067 if (aPartIt == aItEnd)
3068 break;
3070 sURL += OUString('#');
3071 sURL += *aPartIt;
3073 else if ( *aPartIt == "\\m" || *aPartIt == "\\n" )
3076 else if ( *aPartIt == "\\o" || *aPartIt == "\\t" )
3078 ++aPartIt;
3080 if (aPartIt == aItEnd)
3081 break;
3083 else
3085 sURL = *aPartIt;
3088 ++aPartIt;
3091 if (!sURL.isEmpty())
3093 pContext->SetHyperlinkURL(sURL);
3096 break;
3097 case FIELD_IF : break;
3098 case FIELD_INFO : break;
3099 case FIELD_INCLUDEPICTURE: break;
3100 case FIELD_KEYWORDS :
3102 OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" KEYWORDS") );
3103 if(!sParam.isEmpty())
3105 xFieldProperties->setPropertyValue(
3106 rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( true ));
3107 //PROP_CURRENT_PRESENTATION is set later anyway
3110 break;
3111 case FIELD_LASTSAVEDBY : break;
3112 case FIELD_MACROBUTTON:
3114 //extract macro name
3115 sal_Int32 nIndex = sizeof(" MACROBUTTON ");
3116 OUString sMacro = pContext->GetCommand().getToken( 0, ' ', nIndex);
3117 if (xFieldProperties.is())
3118 xFieldProperties->setPropertyValue(
3119 rPropNameSupplier.GetName(PROP_MACRO_NAME), uno::makeAny( sMacro ));
3121 //extract quick help text
3122 if(xFieldProperties.is() && pContext->GetCommand().getLength() > nIndex + 1)
3124 xFieldProperties->setPropertyValue(
3125 rPropNameSupplier.GetName(PROP_HINT),
3126 uno::makeAny( pContext->GetCommand().copy( nIndex )));
3129 break;
3130 case FIELD_MERGEFIELD :
3132 //todo: create a database field and fieldmaster pointing to a column, only
3133 OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" MERGEFIELD") );
3134 //create a user field and type
3135 uno::Reference< beans::XPropertySet > xMaster =
3136 FindOrCreateFieldMaster( "com.sun.star.text.FieldMaster.Database", sParam );
3138 // xFieldProperties->setPropertyValue(
3139 // "FieldCode",
3140 // uno::makeAny( pContext->GetCommand().copy( nIndex + 1 )));
3141 uno::Reference< text::XDependentTextField > xDependentField( xFieldInterface, uno::UNO_QUERY_THROW );
3142 xDependentField->attachTextFieldMaster( xMaster );
3143 m_bSetUserFieldContent = true;
3145 break;
3146 case FIELD_MERGEREC : break;
3147 case FIELD_MERGESEQ : break;
3148 case FIELD_NEXT : break;
3149 case FIELD_NEXTIF : break;
3150 case FIELD_PAGE :
3151 if (xFieldProperties.is())
3153 xFieldProperties->setPropertyValue(
3154 rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
3155 uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) ));
3156 xFieldProperties->setPropertyValue(
3157 rPropNameSupplier.GetName(PROP_SUB_TYPE),
3158 uno::makeAny( text::PageNumberType_CURRENT ));
3161 break;
3162 case FIELD_PAGEREF:
3163 case FIELD_REF:
3164 if (xFieldProperties.is())
3166 bool bPageRef = aIt->second.eFieldId == FIELD_PAGEREF;
3167 OUString sBookmark = lcl_ExtractParameter(pContext->GetCommand(),
3168 (bPageRef ? sizeof(" PAGEREF") : sizeof(" REF")));
3170 // Do we need a GetReference (default) or a GetExpression field?
3171 uno::Reference< text::XTextFieldsSupplier > xFieldsSupplier( GetTextDocument(), uno::UNO_QUERY );
3172 uno::Reference< container::XNameAccess > xFieldMasterAccess = xFieldsSupplier->getTextFieldMasters();
3174 if (!xFieldMasterAccess->hasByName("com.sun.star.text.FieldMaster.SetExpression." + sBookmark))
3176 xFieldProperties->setPropertyValue(
3177 rPropNameSupplier.GetName(PROP_REFERENCE_FIELD_SOURCE),
3178 uno::makeAny( sal_Int16(text::ReferenceFieldSource::BOOKMARK)) );
3179 xFieldProperties->setPropertyValue(
3180 rPropNameSupplier.GetName(PROP_SOURCE_NAME),
3181 uno::makeAny( sBookmark) );
3182 sal_Int16 nFieldPart = (bPageRef ? text::ReferenceFieldPart::PAGE : text::ReferenceFieldPart::TEXT);
3183 OUString sValue;
3184 if( lcl_FindInCommand( pContext->GetCommand(), 'p', sValue ))
3186 //above-below
3187 nFieldPart = text::ReferenceFieldPart::UP_DOWN;
3189 else if( lcl_FindInCommand( pContext->GetCommand(), 'r', sValue ))
3191 //number
3192 nFieldPart = text::ReferenceFieldPart::NUMBER;
3194 else if( lcl_FindInCommand( pContext->GetCommand(), 'n', sValue ))
3196 //number-no-context
3197 nFieldPart = text::ReferenceFieldPart::NUMBER_NO_CONTEXT;
3199 else if( lcl_FindInCommand( pContext->GetCommand(), 'w', sValue ))
3201 //number-full-context
3202 nFieldPart = text::ReferenceFieldPart::NUMBER_FULL_CONTEXT;
3204 xFieldProperties->setPropertyValue(
3205 rPropNameSupplier.GetName( PROP_REFERENCE_FIELD_PART ), uno::makeAny( nFieldPart ));
3207 else
3209 xFieldInterface = m_xTextFactory->createInstance("com.sun.star.text.TextField.GetExpression");
3210 xFieldProperties.set(xFieldInterface, uno::UNO_QUERY);
3211 xFieldProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_CONTENT), uno::makeAny(sBookmark));
3212 xFieldProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING));
3215 break;
3216 case FIELD_REVNUM : break;
3217 case FIELD_SAVEDATE :
3218 SetNumberFormat( pContext->GetCommand(), xFieldProperties );
3219 break;
3220 case FIELD_SECTION : break;
3221 case FIELD_SECTIONPAGES : break;
3222 case FIELD_SEQ :
3224 // command looks like: " SEQ Table \* ARABIC "
3225 OUString sCmd(pContext->GetCommand());
3226 // find the sequence name, e.g. "SEQ"
3227 OUString sSeqName = msfilter::util::findQuotedText(sCmd, "SEQ ", '\\');
3228 sSeqName = sSeqName.trim();
3230 // create a sequence field master using the sequence name
3231 uno::Reference< beans::XPropertySet > xMaster = FindOrCreateFieldMaster(
3232 "com.sun.star.text.FieldMaster.SetExpression",
3233 sSeqName);
3235 xMaster->setPropertyValue(
3236 rPropNameSupplier.GetName(PROP_SUB_TYPE),
3237 uno::makeAny(text::SetVariableType::SEQUENCE));
3239 // apply the numbering type
3240 xFieldProperties->setPropertyValue(
3241 rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
3242 uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) ));
3244 // attach the master to the field
3245 uno::Reference< text::XDependentTextField > xDependentField( xFieldInterface, uno::UNO_QUERY_THROW );
3246 xDependentField->attachTextFieldMaster( xMaster );
3248 rtl::OUString sFormula = sSeqName + "+1";
3249 rtl::OUString sValue;
3250 if( lcl_FindInCommand( pContext->GetCommand(), 'c', sValue ))
3252 sFormula = sSeqName;
3254 else if( lcl_FindInCommand( pContext->GetCommand(), 'r', sValue ))
3256 sFormula = sValue;
3258 // TODO \s isn't handled, but the spec isn't easy to understand without
3259 // an example for this one.
3260 xFieldProperties->setPropertyValue(
3261 rPropNameSupplier.GetName(PROP_CONTENT),
3262 uno::makeAny(sFormula));
3264 // Take care of the numeric formatting definition, default is Arabic
3265 sal_Int16 nNumberingType = lcl_ParseNumberingType(pContext->GetCommand());
3266 if (nNumberingType == style::NumberingType::PAGE_DESCRIPTOR)
3267 nNumberingType = style::NumberingType::ARABIC;
3268 xFieldProperties->setPropertyValue(
3269 rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
3270 uno::makeAny(nNumberingType));
3272 break;
3273 case FIELD_SET : break;
3274 case FIELD_SKIPIF : break;
3275 case FIELD_STYLEREF : break;
3276 case FIELD_SUBJECT :
3278 OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" SUBJECT") );
3279 if(!sParam.isEmpty())
3281 xFieldProperties->setPropertyValue(
3282 rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( true ));
3283 //PROP_CURRENT_PRESENTATION is set later anyway
3286 break;
3287 case FIELD_SYMBOL : break;
3288 case FIELD_TEMPLATE: break;
3289 case FIELD_TIME :
3290 SetNumberFormat( pContext->GetCommand(), xFieldProperties );
3291 break;
3292 case FIELD_TITLE :
3294 OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" TITLE") );
3295 if(!sParam.isEmpty())
3297 xFieldProperties->setPropertyValue(
3298 rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( true ));
3299 //PROP_CURRENT_PRESENTATION is set later anyway
3302 break;
3303 case FIELD_USERADDRESS : //todo: user address collects street, city ...
3304 break;
3305 case FIELD_TOC:
3306 handleToc(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties,
3307 OUString::createFromAscii(aIt->second.cFieldServiceName));
3308 break;
3309 case FIELD_TC :
3311 uno::Reference< beans::XPropertySet > xTC(
3312 m_xTextFactory->createInstance(
3313 OUString::createFromAscii(aIt->second.cFieldServiceName)),
3314 uno::UNO_QUERY_THROW);
3315 OUString sTCText = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" TC") );
3316 if( !sTCText.isEmpty())
3317 xTC->setPropertyValue(rPropNameSupplier.GetName(PROP_ALTERNATIVE_TEXT),
3318 uno::makeAny(sTCText));
3319 OUString sValue;
3320 // \f TC entry in doc with multiple tables
3321 // if( lcl_FindInCommand( pContext->GetCommand(), 'f', sValue ))
3322 // {
3323 // todo: unsupported
3324 // }
3325 if( lcl_FindInCommand( pContext->GetCommand(), 'l', sValue ))
3326 // \l Outline Level
3328 sal_Int32 nLevel = sValue.toInt32();
3329 if( !sValue.isEmpty() && nLevel >= 0 && nLevel <= 10 )
3330 xTC->setPropertyValue(rPropNameSupplier.GetName(PROP_LEVEL), uno::makeAny( (sal_Int16)nLevel ));
3332 // if( lcl_FindInCommand( pContext->GetCommand(), 'n', sValue ))
3333 // \n Suppress page numbers
3334 // {
3335 //todo: unsupported feature
3336 // }
3337 pContext->SetTC( xTC );
3339 break;
3340 case FIELD_NUMCHARS:
3341 case FIELD_NUMWORDS:
3342 case FIELD_NUMPAGES:
3343 if (xFieldProperties.is())
3344 xFieldProperties->setPropertyValue(
3345 rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
3346 uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) ));
3347 break;
3350 //set the text field if there is any
3351 pContext->SetTextField( uno::Reference< text::XTextField >( xFieldInterface, uno::UNO_QUERY ) );
3353 catch( const uno::Exception& e )
3355 SAL_WARN( "writerfilter", "Exception in CloseFieldCommand(): " << e.Message );
3357 pContext->SetCommandCompleted();
3360 /*-------------------------------------------------------------------------
3361 //the _current_ fields require a string type result while TOCs accept richt results
3362 -----------------------------------------------------------------------*/
3363 bool DomainMapper_Impl::IsFieldResultAsString()
3365 bool bRet = false;
3366 OSL_ENSURE( !m_aFieldStack.empty(), "field stack empty?");
3367 FieldContextPtr pContext = m_aFieldStack.top();
3368 OSL_ENSURE( pContext.get(), "no field context available");
3369 if( pContext.get() )
3371 bRet = pContext->GetTextField().is();
3373 return bRet;
3377 void DomainMapper_Impl::SetFieldResult( OUString& rResult )
3379 #ifdef DEBUG_DOMAINMAPPER
3380 dmapper_logger->startElement("setFieldResult");
3381 dmapper_logger->chars(rResult);
3382 #endif
3384 FieldContextPtr pContext = m_aFieldStack.top();
3385 OSL_ENSURE( pContext.get(), "no field context available");
3386 if( pContext.get() )
3388 uno::Reference<text::XTextField> xTextField = pContext->GetTextField();
3391 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
3392 OSL_ENSURE( xTextField.is()
3393 //||m_xTOC.is() ||m_xTC.is()
3394 //||m_sHyperlinkURL.getLength()
3395 , "DomainMapper_Impl::SetFieldResult: field not created" );
3396 if(xTextField.is())
3400 if( m_bSetUserFieldContent )
3402 // user field content has to be set at the field master
3403 uno::Reference< text::XDependentTextField > xDependentField( xTextField, uno::UNO_QUERY_THROW );
3404 xDependentField->getTextFieldMaster()->setPropertyValue(
3405 rPropNameSupplier.GetName(PROP_CONTENT),
3406 uno::makeAny( rResult ));
3408 else
3410 uno::Reference< beans::XPropertySet > xFieldProperties( xTextField, uno::UNO_QUERY_THROW);
3411 // In case of SetExpression, the field result contains the content of the variable.
3412 uno::Reference<lang::XServiceInfo> xServiceInfo(xTextField, uno::UNO_QUERY);
3413 bool bIsSetExpression = xServiceInfo->supportsService("com.sun.star.text.TextField.SetExpression");
3414 // If we already have content set, then use the current presentation
3415 rtl::OUString sValue;
3416 if (bIsSetExpression)
3417 { // this will throw for field types without Content
3418 uno::Any aValue(xFieldProperties->getPropertyValue(
3419 rPropNameSupplier.GetName(PROP_CONTENT)));
3420 aValue >>= sValue;
3422 xFieldProperties->setPropertyValue(
3423 rPropNameSupplier.GetName(bIsSetExpression && sValue.isEmpty()? PROP_CONTENT : PROP_CURRENT_PRESENTATION),
3424 uno::makeAny( rResult ));
3427 catch( const beans::UnknownPropertyException& )
3429 //some fields don't have a CurrentPresentation (DateTime)
3433 catch( const uno::Exception& )
3440 void DomainMapper_Impl::SetFieldFFData(FFDataHandler::Pointer_t pFFDataHandler)
3442 #ifdef DEBUG_DOMAINMAPPER
3443 dmapper_logger->startElement("setFieldFFData");
3444 #endif
3446 if (m_aFieldStack.size())
3448 FieldContextPtr pContext = m_aFieldStack.top();
3449 if (pContext.get())
3451 pContext->setFFDataHandler(pFFDataHandler);
3455 #ifdef DEBUG_DOMAINMAPPER
3456 dmapper_logger->endElement();
3457 #endif
3460 /*-------------------------------------------------------------------------
3461 //the end of field is reached (0x15 appeared) - the command might still be open
3462 -----------------------------------------------------------------------*/
3463 void DomainMapper_Impl::PopFieldContext()
3465 #ifdef DEBUG_DOMAINMAPPER
3466 dmapper_logger->element("popFieldContext");
3467 #endif
3469 if (m_aFieldStack.empty())
3470 return;
3472 FieldContextPtr pContext = m_aFieldStack.top();
3473 OSL_ENSURE( pContext.get(), "no field context available");
3474 if( pContext.get() )
3476 if( !pContext->IsCommandCompleted() )
3477 CloseFieldCommand();
3479 //insert the field, TC or TOC
3480 uno::Reference< text::XTextAppend > xTextAppend;
3481 if (!m_aTextAppendStack.empty())
3482 xTextAppend = m_aTextAppendStack.top().xTextAppend;
3483 if(xTextAppend.is())
3487 uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange(pContext->GetStartRange());
3488 uno::Reference< text::XTextContent > xToInsert( pContext->GetTOC(), uno::UNO_QUERY );
3489 if( xToInsert.is() )
3491 xCrsr->gotoEnd( true );
3492 xToInsert->attach( uno::Reference< text::XTextRange >( xCrsr, uno::UNO_QUERY_THROW ));
3494 else
3496 xToInsert = uno::Reference< text::XTextContent >(pContext->GetTC(), uno::UNO_QUERY);
3497 if( !xToInsert.is() )
3498 xToInsert = uno::Reference< text::XTextContent >(pContext->GetTextField(), uno::UNO_QUERY);
3499 if( xToInsert.is() )
3501 uno::Sequence<beans::PropertyValue> aValues;
3502 // Character properties of the field show up here the
3503 // last (always empty) run. Inherit character
3504 // properties from there.
3505 if (m_pLastCharacterContext.get())
3506 aValues = m_pLastCharacterContext->GetPropertyValues();
3507 appendTextContent(xToInsert, aValues);
3509 else
3511 FormControlHelper::Pointer_t pFormControlHelper(pContext->getFormControlHelper());
3512 if (pFormControlHelper.get() != NULL && pFormControlHelper->hasFFDataHandler() )
3514 uno::Reference< text::XFormField > xFormField( pContext->GetFormField() );
3515 xToInsert.set(xFormField, uno::UNO_QUERY);
3516 if ( xFormField.is() && xToInsert.is() )
3518 xCrsr->gotoEnd( true );
3519 xToInsert->attach( uno::Reference< text::XTextRange >( xCrsr, uno::UNO_QUERY_THROW ));
3520 pFormControlHelper->processField( xFormField );
3522 else
3524 uno::Reference<text::XTextRange> xTxtRange(xCrsr, uno::UNO_QUERY);
3525 pFormControlHelper->insertControl(xTxtRange);
3528 else if(!pContext->GetHyperlinkURL().isEmpty())
3530 PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
3531 xCrsr->gotoEnd( true );
3533 uno::Reference< beans::XPropertySet > xCrsrProperties( xCrsr, uno::UNO_QUERY_THROW );
3534 xCrsrProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_HYPER_LINK_U_R_L), uno::
3535 makeAny(pContext->GetHyperlinkURL()));
3540 catch(const lang::IllegalArgumentException&)
3542 OSL_FAIL( "IllegalArgumentException in PopFieldContext()" );
3544 catch(const uno::Exception&)
3546 OSL_FAIL( "exception in PopFieldContext()" );
3550 //TOCs have to include all the imported content
3551 //...
3553 //remove the field context
3554 m_aFieldStack.pop();
3558 void DomainMapper_Impl::AddBookmark( const OUString& rBookmarkName, const OUString& rId )
3560 if (m_aTextAppendStack.empty())
3561 return;
3562 uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
3563 BookmarkMap_t::iterator aBookmarkIter = m_aBookmarkMap.find( rId );
3564 //is the bookmark name already registered?
3567 if( aBookmarkIter != m_aBookmarkMap.end() )
3569 static const OUString sBookmarkService("com.sun.star.text.Bookmark");
3570 if (m_xTextFactory.is())
3572 uno::Reference< text::XTextContent > xBookmark( m_xTextFactory->createInstance( sBookmarkService ), uno::UNO_QUERY_THROW );
3573 uno::Reference< text::XTextCursor > xCursor;
3574 uno::Reference< text::XText > xText = aBookmarkIter->second.m_xTextRange->getText();
3575 if( aBookmarkIter->second.m_bIsStartOfText )
3576 xCursor = xText->createTextCursorByRange( xText->getStart() );
3577 else
3579 xCursor = xText->createTextCursorByRange( aBookmarkIter->second.m_xTextRange );
3580 xCursor->goRight( 1, false );
3583 xCursor->gotoRange( xTextAppend->getEnd(), true );
3584 uno::Reference< container::XNamed > xBkmNamed( xBookmark, uno::UNO_QUERY_THROW );
3585 //todo: make sure the name is not used already!
3586 if ( !aBookmarkIter->second.m_sBookmarkName.isEmpty() )
3587 xBkmNamed->setName( aBookmarkIter->second.m_sBookmarkName );
3588 else
3589 xBkmNamed->setName( rBookmarkName );
3590 xTextAppend->insertTextContent( uno::Reference< text::XTextRange >( xCursor, uno::UNO_QUERY_THROW), xBookmark, !xCursor->isCollapsed() );
3592 m_aBookmarkMap.erase( aBookmarkIter );
3594 else
3596 //otherwise insert a text range as marker
3597 bool bIsStart = true;
3598 uno::Reference< text::XTextRange > xCurrent;
3599 if (xTextAppend.is())
3601 uno::Reference< text::XTextCursor > xCursor = xTextAppend->createTextCursorByRange( xTextAppend->getEnd() );
3602 bIsStart = !xCursor->goLeft(1, false);
3603 xCurrent = xCursor->getStart();
3605 m_aBookmarkMap.insert(BookmarkMap_t::value_type( rId, BookmarkInsertPosition( bIsStart, rBookmarkName, xCurrent ) ));
3608 catch( const uno::Exception& )
3610 //TODO: What happens to bookmarks where start and end are at different XText objects?
3614 void DomainMapper_Impl::AddAnnotationPosition(const bool bStart)
3616 if (m_aTextAppendStack.empty())
3617 return;
3619 // Create a cursor, pointing to the current position.
3620 uno::Reference<text::XTextAppend> xTextAppend = m_aTextAppendStack.top().xTextAppend;
3621 uno::Reference<text::XTextRange> xCurrent;
3622 if (xTextAppend.is())
3624 uno::Reference<text::XTextCursor> xCursor;
3625 if (m_bIsNewDoc)
3626 xCursor = xTextAppend->createTextCursorByRange(xTextAppend->getEnd());
3627 else
3628 xCursor = m_aTextAppendStack.top().xCursor;
3629 if (xCursor.is())
3630 xCurrent = xCursor->getStart();
3633 // And save it, to be used by PopAnnotation() later.
3634 if (bStart)
3635 m_aAnnotationPosition.m_xStart = xCurrent;
3636 else
3637 m_aAnnotationPosition.m_xEnd = xCurrent;
3640 GraphicImportPtr DomainMapper_Impl::GetGraphicImport(GraphicImportType eGraphicImportType)
3642 if(!m_pGraphicImport)
3643 m_pGraphicImport.reset( new GraphicImport( m_xComponentContext, m_xTextFactory, m_rDMapper, eGraphicImportType ) );
3644 return m_pGraphicImport;
3646 /*-------------------------------------------------------------------------
3647 reset graphic import if the last import resulted in a shape, not a graphic
3648 -----------------------------------------------------------------------*/
3649 void DomainMapper_Impl::ResetGraphicImport()
3651 m_pGraphicImport.reset();
3655 void DomainMapper_Impl::ImportGraphic(writerfilter::Reference< Properties >::Pointer_t ref, GraphicImportType eGraphicImportType)
3657 GetGraphicImport(eGraphicImportType);
3658 if( eGraphicImportType != IMPORT_AS_DETECTED_INLINE && eGraphicImportType != IMPORT_AS_DETECTED_ANCHOR )
3660 //create the graphic
3661 ref->resolve( *m_pGraphicImport );
3664 //insert it into the document at the current cursor position
3666 uno::Reference<text::XTextContent> xTextContent
3667 (m_pGraphicImport->GetGraphicObject());
3669 //insert it into the document at the current cursor position
3670 OSL_ENSURE( xTextContent.is(), "DomainMapper_Impl::ImportGraphic");
3671 if( xTextContent.is())
3672 appendTextContent( xTextContent, uno::Sequence< beans::PropertyValue >() );
3674 m_pGraphicImport.reset();
3679 void DomainMapper_Impl::SetLineNumbering( sal_Int32 nLnnMod, sal_Int32 nLnc, sal_Int32 ndxaLnn )
3681 if( !m_bLineNumberingSet )
3683 const PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
3687 uno::Reference< text::XLineNumberingProperties > xLineProperties( m_xTextDocument, uno::UNO_QUERY_THROW );
3688 uno::Reference< beans::XPropertySet > xProperties = xLineProperties->getLineNumberingProperties();
3689 uno::Any aTrue( uno::makeAny( true ));
3690 xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_IS_ON ), aTrue);
3691 xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_COUNT_EMPTY_LINES ), aTrue );
3692 xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_COUNT_LINES_IN_FRAMES ), uno::makeAny( false ) );
3693 xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_INTERVAL ), uno::makeAny( static_cast< sal_Int16 >( nLnnMod )));
3694 xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_DISTANCE ), uno::makeAny( ConversionHelper::convertTwipToMM100(ndxaLnn) ));
3695 xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_NUMBER_POSITION ), uno::makeAny( style::LineNumberPosition::LEFT));
3696 xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_NUMBERING_TYPE ), uno::makeAny( style::NumberingType::ARABIC));
3697 xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_RESTART_AT_EACH_PAGE ), uno::makeAny( nLnc == 0 ));
3699 catch( const uno::Exception& )
3702 m_bLineNumberingSet = true;
3706 void DomainMapper_Impl::SetPageMarginTwip( PageMarElement eElement, sal_Int32 nValue )
3708 nValue = ConversionHelper::convertTwipToMM100(nValue);
3709 switch(eElement)
3711 case PAGE_MAR_TOP : m_aPageMargins.top = nValue; break;
3712 case PAGE_MAR_RIGHT : m_aPageMargins.right = nValue; break;
3713 case PAGE_MAR_BOTTOM : m_aPageMargins.bottom = nValue; break;
3714 case PAGE_MAR_LEFT : m_aPageMargins.left = nValue; break;
3715 case PAGE_MAR_HEADER : m_aPageMargins.header = nValue; break;
3716 case PAGE_MAR_FOOTER : m_aPageMargins.footer = nValue; break;
3717 case PAGE_MAR_GUTTER : m_aPageMargins.gutter = nValue; break;
3723 _PageMar::_PageMar()
3725 header = footer = ConversionHelper::convertTwipToMM100(sal_Int32(720));
3726 top = bottom = ConversionHelper::convertTwipToMM100( sal_Int32(1440));
3727 // This is strange, the RTF spec says it's 1800, but it's clearly 1440 in Word
3728 // OOXML seems not to specify a default value
3729 right = left = ConversionHelper::convertTwipToMM100( sal_Int32(1440));
3730 gutter = 0;
3735 void DomainMapper_Impl::RegisterFrameConversion(
3736 uno::Reference< text::XTextRange > xFrameStartRange,
3737 uno::Reference< text::XTextRange > xFrameEndRange,
3738 uno::Sequence< beans::PropertyValue > aFrameProperties
3741 OSL_ENSURE(
3742 !m_aFrameProperties.getLength() && !m_xFrameStartRange.is() && !m_xFrameEndRange.is(),
3743 "frame properties not removed");
3744 m_aFrameProperties = aFrameProperties;
3745 m_xFrameStartRange = xFrameStartRange;
3746 m_xFrameEndRange = xFrameEndRange;
3750 bool DomainMapper_Impl::ExecuteFrameConversion()
3752 bool bRet = false;
3753 if( m_xFrameStartRange.is() && m_xFrameEndRange.is() )
3755 bRet = true;
3758 uno::Reference< text::XTextAppendAndConvert > xTextAppendAndConvert( GetTopTextAppend(), uno::UNO_QUERY_THROW );
3759 xTextAppendAndConvert->convertToTextFrame(
3760 m_xFrameStartRange,
3761 m_xFrameEndRange,
3762 m_aFrameProperties );
3764 catch( const uno::Exception& rEx)
3766 SAL_WARN( "writerfilter", "Exception caught when converting to frame: " + rEx.Message );
3767 bRet = false;
3769 m_xFrameStartRange = 0;
3770 m_xFrameEndRange = 0;
3771 m_aFrameProperties.realloc( 0 );
3773 return bRet;
3776 void DomainMapper_Impl::AddNewRedline( )
3778 RedlineParamsPtr pNew( new RedlineParams );
3779 pNew->m_nToken = ooxml::OOXML_mod;
3780 if ( !m_bIsParaChange )
3782 m_aRedlines.top().push_back( pNew );
3784 else
3786 m_pParaRedline.swap( pNew );
3790 RedlineParamsPtr DomainMapper_Impl::GetTopRedline( )
3792 RedlineParamsPtr pResult;
3793 if ( !m_bIsParaChange && m_aRedlines.top().size( ) > 0 )
3794 pResult = m_aRedlines.top().back( );
3795 else if ( m_bIsParaChange )
3796 pResult = m_pParaRedline;
3797 return pResult;
3800 sal_Int32 DomainMapper_Impl::GetCurrentRedlineToken( )
3802 sal_Int32 nToken = 0;
3803 RedlineParamsPtr pCurrent( GetTopRedline( ) );
3804 if ( pCurrent.get( ) )
3805 nToken = pCurrent->m_nToken;
3806 return nToken;
3809 void DomainMapper_Impl::SetCurrentRedlineAuthor( OUString sAuthor )
3811 if (!m_xAnnotationField.is())
3813 RedlineParamsPtr pCurrent( GetTopRedline( ) );
3814 if ( pCurrent.get( ) )
3815 pCurrent->m_sAuthor = sAuthor;
3817 else
3818 m_xAnnotationField->setPropertyValue("Author", uno::makeAny(sAuthor));
3821 void DomainMapper_Impl::SetCurrentRedlineInitials( OUString sInitials )
3823 if (m_xAnnotationField.is())
3824 m_xAnnotationField->setPropertyValue("Initials", uno::makeAny(sInitials));
3827 void DomainMapper_Impl::SetCurrentRedlineDate( OUString sDate )
3829 if (!m_xAnnotationField.is())
3831 RedlineParamsPtr pCurrent( GetTopRedline( ) );
3832 if ( pCurrent.get( ) )
3833 pCurrent->m_sDate = sDate;
3835 else
3836 m_xAnnotationField->setPropertyValue("DateTimeValue", uno::makeAny(lcl_DateStringToDateTime(sDate)));
3839 void DomainMapper_Impl::SetCurrentRedlineId( sal_Int32 sId )
3841 RedlineParamsPtr pCurrent( GetTopRedline( ) );
3842 if ( pCurrent.get( ) )
3843 pCurrent->m_nId = sId;
3846 void DomainMapper_Impl::SetCurrentRedlineToken( sal_Int32 nToken )
3848 RedlineParamsPtr pCurrent( GetTopRedline( ) );
3849 if ( pCurrent.get( ) )
3850 pCurrent->m_nToken = nToken;
3855 void DomainMapper_Impl::RemoveCurrentRedline( )
3857 if ( m_aRedlines.top().size( ) > 0 )
3859 m_aRedlines.top().pop_back( );
3863 void DomainMapper_Impl::ResetParaRedline( )
3865 if ( m_pParaRedline.get( ) )
3867 RedlineParamsPtr pEmpty;
3868 m_pParaRedline.swap( pEmpty );
3874 void DomainMapper_Impl::ApplySettingsTable()
3876 if( m_pSettingsTable && m_xTextFactory.is() )
3880 uno::Reference< beans::XPropertySet > xTextDefaults(m_xTextFactory->createInstance("com.sun.star.text.Defaults"), uno::UNO_QUERY_THROW );
3881 sal_Int32 nDefTab = m_pSettingsTable->GetDefaultTabStop();
3882 xTextDefaults->setPropertyValue( PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_TAB_STOP_DISTANCE ), uno::makeAny(nDefTab) );
3883 if (m_pSettingsTable->GetLinkStyles())
3885 PropertyNameSupplier& rSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
3886 // If linked styles are enabled, set paragraph defaults from Word's default template
3887 xTextDefaults->setPropertyValue(rSupplier.GetName(PROP_PARA_BOTTOM_MARGIN), uno::makeAny(ConversionHelper::convertTwipToMM100(200)));
3888 style::LineSpacing aSpacing;
3889 aSpacing.Mode = style::LineSpacingMode::PROP;
3890 aSpacing.Height = sal_Int16(115);
3891 xTextDefaults->setPropertyValue(rSupplier.GetName(PROP_PARA_LINE_SPACING), uno::makeAny(aSpacing));
3894 if (m_pSettingsTable->GetZoomFactor())
3896 uno::Sequence<beans::PropertyValue> aViewProps(3);
3897 aViewProps[0].Name = "ZoomFactor";
3898 aViewProps[0].Value <<= m_pSettingsTable->GetZoomFactor();
3899 aViewProps[1].Name = "VisibleBottom";
3900 aViewProps[1].Value <<= sal_Int32(0);
3901 aViewProps[2].Name = "ZoomType";
3902 aViewProps[2].Value <<= sal_Int16(0);
3904 uno::Reference<container::XIndexContainer> xBox = document::IndexedPropertyValues::create(m_xComponentContext);
3905 xBox->insertByIndex(sal_Int32(0), uno::makeAny(aViewProps));
3906 uno::Reference<container::XIndexAccess> xIndexAccess(xBox, uno::UNO_QUERY);
3907 uno::Reference<document::XViewDataSupplier> xViewDataSupplier(m_xTextDocument, uno::UNO_QUERY);
3908 xViewDataSupplier->setViewData(xIndexAccess);
3911 uno::Reference< beans::XPropertySet > xSettings(m_xTextFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY);
3912 if (m_pSettingsTable->GetUsePrinterMetrics())
3913 xSettings->setPropertyValue("PrinterIndependentLayout", uno::makeAny(document::PrinterIndependentLayout::DISABLED));
3914 if( m_pSettingsTable->GetEmbedTrueTypeFonts())
3915 xSettings->setPropertyValue( PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_EMBED_FONTS ), uno::makeAny(true) );
3916 if( m_pSettingsTable->GetEmbedSystemFonts())
3917 xSettings->setPropertyValue( PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_EMBED_SYSTEM_FONTS ), uno::makeAny(true) );
3918 xSettings->setPropertyValue("AddParaTableSpacing", uno::makeAny(m_pSettingsTable->GetDoNotUseHTMLParagraphAutoSpacing()));
3920 catch(const uno::Exception&)
3926 uno::Reference<container::XIndexAccess> DomainMapper_Impl::GetCurrentNumberingRules(sal_Int32* pListLevel)
3928 uno::Reference<container::XIndexAccess> xRet;
3931 OUString aStyle = GetCurrentParaStyleId();
3932 if (aStyle.isEmpty() || GetTopContextType() != CONTEXT_PARAGRAPH)
3933 return xRet;
3934 const StyleSheetEntryPtr pEntry = GetStyleSheetTable()->FindStyleSheetByISTD(aStyle);
3935 if (!pEntry)
3936 return xRet;
3937 const StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast<const StyleSheetPropertyMap*>(pEntry ? pEntry->pProperties.get() : 0);
3938 sal_Int32 nListId = pStyleSheetProperties->GetListId();
3939 if (nListId < 0)
3940 return xRet;
3941 if (pListLevel)
3942 *pListLevel = pStyleSheetProperties->GetListLevel();
3944 // So we are in a paragraph style and it has numbering. Look up the relevant numbering rules.
3945 OUString aListName = ListDef::GetStyleName(nListId);
3946 uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier(GetTextDocument(), uno::UNO_QUERY);
3947 uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies();
3948 uno::Reference<container::XNameAccess> xNumberingStyles;
3949 xStyleFamilies->getByName("NumberingStyles") >>= xNumberingStyles;
3950 uno::Reference<beans::XPropertySet> xStyle(xNumberingStyles->getByName(aListName), uno::UNO_QUERY);
3951 xRet.set(xStyle->getPropertyValue("NumberingRules"), uno::UNO_QUERY);
3953 catch( const uno::Exception& )
3956 return xRet;
3959 uno::Reference<beans::XPropertySet> DomainMapper_Impl::GetCurrentNumberingCharStyle()
3961 uno::Reference<beans::XPropertySet> xRet;
3964 sal_Int32 nListLevel = -1;
3965 uno::Reference<container::XIndexAccess> xLevels = GetCurrentNumberingRules(&nListLevel);
3966 if (!xLevels.is())
3967 return xRet;
3968 uno::Sequence<beans::PropertyValue> aProps;
3969 xLevels->getByIndex(nListLevel) >>= aProps;
3970 for (int i = 0; i < aProps.getLength(); ++i)
3972 const beans::PropertyValue& rProp = aProps[i];
3974 if (rProp.Name == "CharStyleName")
3976 OUString aCharStyle;
3977 rProp.Value >>= aCharStyle;
3978 uno::Reference<container::XNameAccess> xCharacterStyles;
3979 uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier(GetTextDocument(), uno::UNO_QUERY);
3980 uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies();
3981 xStyleFamilies->getByName("CharacterStyles") >>= xCharacterStyles;
3982 xRet.set(xCharacterStyles->getByName(aCharStyle), uno::UNO_QUERY_THROW);
3983 break;
3987 catch( const uno::Exception& )
3990 return xRet;
3993 SectionPropertyMap * DomainMapper_Impl::GetSectionContext()
3995 SectionPropertyMap* pSectionContext = 0;
3996 //the section context is not availabe before the first call of startSectionGroup()
3997 if( !IsAnyTableImport() )
3999 PropertyMapPtr pContext = GetTopContextOfType(CONTEXT_SECTION);
4000 OSL_ENSURE(pContext.get(), "Section context is not in the stack!");
4001 pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() );
4004 return pSectionContext;
4007 void DomainMapper_Impl::deferCharacterProperty( sal_Int32 id, com::sun::star::uno::Any value )
4009 deferredCharacterProperties[ id ] = value;
4012 void DomainMapper_Impl::processDeferredCharacterProperties()
4014 // ACtually process in DomainMapper, so that it's the same source file like normal processing.
4015 if( !deferredCharacterProperties.empty())
4017 m_rDMapper.processDeferredCharacterProperties( deferredCharacterProperties );
4018 deferredCharacterProperties.clear();
4022 sal_Int32 DomainMapper_Impl::getCurrentNumberingProperty(OUString aProp)
4024 sal_Int32 nRet = 0;
4026 PropertyMap::iterator it = m_pTopContext->find(PropertyDefinition( PROP_NUMBERING_RULES, true ) );
4027 uno::Reference<container::XIndexAccess> xNumberingRules;
4028 if (it != m_pTopContext->end())
4029 xNumberingRules.set(it->second, uno::UNO_QUERY);
4030 it = m_pTopContext->find(PropertyDefinition( PROP_NUMBERING_LEVEL, true ) );
4031 sal_Int32 nNumberingLevel = -1;
4032 if (it != m_pTopContext->end())
4033 it->second >>= nNumberingLevel;
4034 if (xNumberingRules.is() && nNumberingLevel != -1)
4036 uno::Sequence<beans::PropertyValue> aProps;
4037 xNumberingRules->getByIndex(nNumberingLevel) >>= aProps;
4038 for (int i = 0; i < aProps.getLength(); ++i)
4040 const beans::PropertyValue& rProp = aProps[i];
4042 if (rProp.Name == aProp)
4044 rProp.Value >>= nRet;
4045 break;
4050 return nRet;
4053 bool DomainMapper_Impl::IsNewDoc()
4055 return m_bIsNewDoc;
4060 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */