Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <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>
60 :
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>
67 :
68 : #include <map>
69 :
70 : #include <comphelper/configurationhelper.hxx>
71 : #include <comphelper/stlunosequence.hxx>
72 : #include <vcl/svapp.hxx>
73 : #include <vcl/outdev.hxx>
74 :
75 : using namespace ::com::sun::star;
76 : using namespace ::rtl;
77 : namespace writerfilter {
78 : namespace dmapper{
79 :
80 356 : sal_Bool lcl_IsUsingEnhancedFields( const uno::Reference< uno::XComponentContext >& rxContext )
81 : {
82 356 : bool bResult(sal_False);
83 : try
84 : {
85 356 : OUString writerConfig = "org.openoffice.Office.Common";
86 :
87 712 : uno::Reference< uno::XInterface > xCfgAccess = ::comphelper::ConfigurationHelper::openConfig( rxContext, writerConfig, ::comphelper::ConfigurationHelper::E_READONLY );
88 712 : ::comphelper::ConfigurationHelper::readRelativeKey( xCfgAccess, OUString( "Filter/Microsoft/Import" ), OUString( "ImportWWFieldsAsEnhancedFields" ) ) >>= bResult;
89 :
90 : }
91 0 : catch( const uno::Exception& )
92 : {
93 : }
94 356 : return bResult;
95 : }
96 :
97 : // Populate Dropdown Field properties from FFData structure
98 0 : void lcl_handleDropdownField( const uno::Reference< beans::XPropertySet >& rxFieldProps, FFDataHandler::Pointer_t pFFDataHandler )
99 : {
100 0 : if ( rxFieldProps.is() )
101 : {
102 0 : if ( !pFFDataHandler->getName().isEmpty() )
103 0 : rxFieldProps->setPropertyValue( "Name", uno::makeAny( pFFDataHandler->getName() ) );
104 :
105 0 : const FFDataHandler::DropDownEntries_t& rEntries = pFFDataHandler->getDropDownEntries();
106 0 : uno::Sequence< OUString > sItems( rEntries.size() );
107 0 : ::std::copy( rEntries.begin(), rEntries.end(), ::comphelper::stl_begin(sItems));
108 0 : if ( sItems.getLength() )
109 0 : rxFieldProps->setPropertyValue( "Items", uno::makeAny( sItems ) );
110 :
111 0 : sal_Int32 nResult = pFFDataHandler->getDropDownResult().toInt32();
112 0 : if ( nResult )
113 0 : rxFieldProps->setPropertyValue( "SelectedItem", uno::makeAny( sItems[ nResult ] ) );
114 0 : if ( !pFFDataHandler->getHelpText().isEmpty() )
115 0 : rxFieldProps->setPropertyValue( "Help", uno::makeAny( pFFDataHandler->getHelpText() ) );
116 : }
117 0 : }
118 :
119 0 : void lcl_handleTextField( const uno::Reference< beans::XPropertySet >& rxFieldProps, FFDataHandler::Pointer_t pFFDataHandler, PropertyNameSupplier& rPropNameSupplier )
120 : {
121 0 : if ( rxFieldProps.is() && pFFDataHandler )
122 : {
123 0 : rxFieldProps->setPropertyValue
124 0 : (rPropNameSupplier.GetName(PROP_HINT),
125 0 : uno::makeAny(pFFDataHandler->getStatusText()));
126 0 : rxFieldProps->setPropertyValue
127 0 : (rPropNameSupplier.GetName(PROP_HELP),
128 0 : uno::makeAny(pFFDataHandler->getHelpText()));
129 0 : rxFieldProps->setPropertyValue
130 0 : (rPropNameSupplier.GetName(PROP_CONTENT),
131 0 : uno::makeAny(pFFDataHandler->getTextDefault()));
132 : }
133 0 : }
134 :
135 3251 : struct FieldConversion
136 : {
137 : OUString sWordCommand;
138 : const sal_Char* cFieldServiceName;
139 : const sal_Char* cFieldMasterServiceName;
140 : FieldId eFieldId;
141 : };
142 :
143 : typedef ::std::map< OUString, FieldConversion>
144 : FieldConversionMap_t;
145 :
146 :
147 0 : void FIB::SetData( Id nName, sal_Int32 nValue )
148 : {
149 : OSL_ENSURE( nName >= NS_rtf::LN_WIDENT && nName <= NS_rtf::LN_LCBSTTBFUSSR, "invalid index in FIB");
150 0 : if( nName >= NS_rtf::LN_WIDENT && nName <= NS_rtf::LN_LCBSTTBFUSSR)
151 0 : aFIBData[nName - NS_rtf::LN_WIDENT] = nValue;
152 0 : }
153 :
154 :
155 357 : DomainMapper_Impl::DomainMapper_Impl(
156 : DomainMapper& rDMapper,
157 : uno::Reference < uno::XComponentContext > xContext,
158 : uno::Reference< lang::XComponent > xModel,
159 : SourceDocumentType eDocumentType,
160 : uno::Reference< text::XTextRange > xInsertTextRange,
161 : bool bIsNewDoc) :
162 : m_eDocumentType( eDocumentType ),
163 : m_rDMapper( rDMapper ),
164 : m_xTextDocument( xModel, uno::UNO_QUERY ),
165 : m_xTextFactory( xModel, uno::UNO_QUERY ),
166 : m_xComponentContext( xContext ),
167 : m_bSetUserFieldContent( false ),
168 : m_bIsFirstSection( true ),
169 : m_bIsColumnBreakDeferred( false ),
170 : m_bIsPageBreakDeferred( false ),
171 : m_pLastSectionContext( ),
172 : m_pLastCharacterContext(),
173 : m_nCurrentTabStopIndex( 0 ),
174 : m_sCurrentParaStyleId(),
175 : m_bInStyleSheetImport( false ),
176 : m_bInAnyTableImport( false ),
177 : m_bInHeaderFooterImport( false ),
178 : m_bDiscardHeaderFooter( 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 358 : m_pSdtHelper(0)
194 :
195 : {
196 357 : appendTableManager( );
197 357 : GetBodyText();
198 357 : uno::Reference< text::XTextAppend > xBodyTextAppend = uno::Reference< text::XTextAppend >( m_xBodyText, uno::UNO_QUERY );
199 : m_aTextAppendStack.push(TextAppendContext(xBodyTextAppend,
200 357 : m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(m_xInsertTextRange)));
201 :
202 : //todo: does it make sense to set the body text as static text interface?
203 712 : uno::Reference< text::XTextAppendAndConvert > xBodyTextAppendAndConvert( m_xBodyText, uno::UNO_QUERY );
204 : m_pTableHandler.reset
205 356 : (new DomainMapperTableHandler(xBodyTextAppendAndConvert, *this));
206 356 : getTableManager( ).setHandler(m_pTableHandler);
207 :
208 356 : getTableManager( ).startLevel();
209 356 : m_bUsingEnhancedFields = lcl_IsUsingEnhancedFields( m_xComponentContext );
210 :
211 713 : m_pSdtHelper = new SdtHelper(*this);
212 356 : }
213 :
214 :
215 1068 : DomainMapper_Impl::~DomainMapper_Impl()
216 : {
217 356 : RemoveLastParagraph( );
218 356 : getTableManager( ).endLevel();
219 356 : popTableManager( );
220 356 : delete m_pSdtHelper;
221 712 : }
222 :
223 :
224 863 : uno::Reference< container::XNameContainer > DomainMapper_Impl::GetPageStyles()
225 : {
226 863 : if(!m_xPageStyles.is())
227 : {
228 355 : uno::Reference< style::XStyleFamiliesSupplier > xSupplier( m_xTextDocument, uno::UNO_QUERY );
229 355 : if (xSupplier.is())
230 339 : xSupplier->getStyleFamilies()->getByName("PageStyles") >>= m_xPageStyles;
231 : }
232 863 : return m_xPageStyles;
233 : }
234 :
235 :
236 1045 : uno::Reference< text::XText > DomainMapper_Impl::GetBodyText()
237 : {
238 1045 : if(!m_xBodyText.is())
239 : {
240 365 : if (m_xInsertTextRange.is())
241 3 : m_xBodyText = m_xInsertTextRange->getText();
242 362 : else if (m_xTextDocument.is())
243 341 : m_xBodyText = m_xTextDocument->getText();
244 : }
245 1045 : return m_xBodyText;
246 : }
247 :
248 :
249 356 : uno::Reference< beans::XPropertySet > DomainMapper_Impl::GetDocumentSettings()
250 : {
251 356 : if( !m_xDocumentSettings.is() && m_xTextFactory.is())
252 : {
253 686 : m_xDocumentSettings = uno::Reference< beans::XPropertySet >(
254 686 : m_xTextFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY );
255 : }
256 356 : return m_xDocumentSettings;
257 : }
258 :
259 :
260 356 : void DomainMapper_Impl::SetDocumentSettingsProperty( const OUString& rPropName, const uno::Any& rValue )
261 : {
262 356 : uno::Reference< beans::XPropertySet > xSettings = GetDocumentSettings();
263 356 : if( xSettings.is() )
264 : {
265 : try
266 : {
267 343 : xSettings->setPropertyValue( rPropName, rValue );
268 : }
269 0 : catch( const uno::Exception& )
270 : {
271 : }
272 356 : }
273 356 : }
274 :
275 547 : void DomainMapper_Impl::RemoveLastParagraph( )
276 : {
277 547 : if (m_aTextAppendStack.empty())
278 22 : return;
279 547 : uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
280 547 : if (!xTextAppend.is())
281 22 : return;
282 : try
283 : {
284 525 : uno::Reference< text::XTextCursor > xCursor;
285 525 : if (m_bIsNewDoc)
286 : {
287 521 : xCursor = xTextAppend->createTextCursor();
288 521 : xCursor->gotoEnd(false);
289 : }
290 : else
291 4 : xCursor.set(m_aTextAppendStack.top().xCursor, uno::UNO_QUERY);
292 1050 : uno::Reference<container::XEnumerationAccess> xEnumerationAccess(xCursor, uno::UNO_QUERY);
293 : // Keep the character properties of the last but one paragraph, even if
294 : // it's empty. This works for headers/footers, and maybe in other cases
295 : // as well, but surely not in textboxes.
296 : // fdo#58327: also do this at the end of the document: when pasting,
297 : // a table before the cursor position would be deleted
298 : // (but only for paste/insert, not load; otherwise it can happen that
299 : // flys anchored at the disposed paragraph are deleted (fdo47036.rtf))
300 525 : bool const bEndOfDocument(m_aTextAppendStack.size() == 1);
301 956 : if ((m_bInHeaderFooterImport || (bEndOfDocument && !m_bIsNewDoc))
302 622 : && xEnumerationAccess.is())
303 : {
304 91 : uno::Reference<container::XEnumeration> xEnumeration = xEnumerationAccess->createEnumeration();
305 182 : uno::Reference<lang::XComponent> xParagraph(xEnumeration->nextElement(), uno::UNO_QUERY);
306 182 : xParagraph->dispose();
307 : }
308 : else
309 : {
310 434 : xCursor->goLeft( 1, true );
311 : // If this is a text on a shape, possibly the text has the trailing
312 : // newline removed already.
313 434 : if (xCursor->getString() == "\n")
314 392 : xCursor->setString(OUString());
315 525 : }
316 : }
317 0 : catch( const uno::Exception& )
318 : {
319 525 : }
320 : }
321 :
322 176 : void DomainMapper_Impl::SetIsLastParagraphInSection( bool bIsLast )
323 : {
324 176 : m_bIsLastParaInSection = bIsLast;
325 176 : }
326 :
327 185 : bool DomainMapper_Impl::GetIsLastParagraphInSection()
328 : {
329 185 : return m_bIsLastParaInSection;
330 : }
331 :
332 373 : void DomainMapper_Impl::SetIsFirstParagraphInSection( bool bIsFirst )
333 : {
334 373 : m_bIsFirstParaInSection = bIsFirst;
335 373 : }
336 :
337 1273 : bool DomainMapper_Impl::GetIsFirstParagraphInSection()
338 : {
339 1273 : return m_bIsFirstParaInSection;
340 : }
341 :
342 1495 : void DomainMapper_Impl::SetParaSectpr(bool bParaSectpr)
343 : {
344 1495 : m_bParaSectpr = bParaSectpr;
345 1495 : }
346 :
347 1011 : bool DomainMapper_Impl::GetParaSectpr()
348 : {
349 1011 : return m_bParaSectpr;
350 : }
351 :
352 14 : void DomainMapper_Impl::SetSdt(bool bSdt)
353 : {
354 14 : m_bSdt = bSdt;
355 14 : }
356 :
357 25 : bool DomainMapper_Impl::GetSdt()
358 : {
359 25 : return m_bSdt;
360 : }
361 :
362 1273 : bool DomainMapper_Impl::GetParaChanged()
363 : {
364 1273 : return m_bParaChanged;
365 : }
366 :
367 9189 : void DomainMapper_Impl::PushProperties(ContextType eId)
368 : {
369 9189 : PropertyMapPtr pInsert(eId == CONTEXT_SECTION ?
370 375 : (new SectionPropertyMap( m_bIsFirstSection )) :
371 9564 : eId == CONTEXT_PARAGRAPH ? new ParagraphPropertyMap : new PropertyMap);
372 9189 : if(eId == CONTEXT_SECTION)
373 : {
374 375 : if( m_bIsFirstSection )
375 350 : m_bIsFirstSection = false;
376 : // beginning with the second section group a section has to be inserted
377 : // into the document
378 375 : SectionPropertyMap* pSectionContext_ = dynamic_cast< SectionPropertyMap* >( pInsert.get() );
379 375 : if (!m_aTextAppendStack.empty())
380 : {
381 375 : uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
382 375 : if (xTextAppend.is())
383 366 : pSectionContext_->SetStart( xTextAppend->getEnd() );
384 : }
385 : }
386 9189 : m_aPropertyStacks[eId].push( pInsert );
387 9189 : m_aContextStack.push(eId);
388 :
389 9189 : m_pTopContext = m_aPropertyStacks[eId].top();
390 9189 : }
391 :
392 :
393 5872 : void DomainMapper_Impl::PushStyleProperties( PropertyMapPtr pStyleProperties )
394 : {
395 5872 : m_aPropertyStacks[CONTEXT_STYLESHEET].push( pStyleProperties );
396 5872 : m_aContextStack.push(CONTEXT_STYLESHEET);
397 :
398 5872 : m_pTopContext = m_aPropertyStacks[CONTEXT_STYLESHEET].top();
399 5872 : }
400 :
401 :
402 449 : void DomainMapper_Impl::PushListProperties(PropertyMapPtr pListProperties)
403 : {
404 449 : m_aPropertyStacks[CONTEXT_LIST].push( pListProperties );
405 449 : m_aContextStack.push(CONTEXT_LIST);
406 449 : m_pTopContext = m_aPropertyStacks[CONTEXT_LIST].top();
407 449 : }
408 :
409 :
410 15347 : void DomainMapper_Impl::PopProperties(ContextType eId)
411 : {
412 : OSL_ENSURE(!m_aPropertyStacks[eId].empty(), "section stack already empty");
413 15347 : if ( m_aPropertyStacks[eId].empty() )
414 15347 : return;
415 :
416 15347 : if ( eId == CONTEXT_SECTION )
417 : {
418 373 : m_pLastSectionContext = m_aPropertyStacks[eId].top( );
419 : }
420 14974 : else if (eId == CONTEXT_CHARACTER)
421 : {
422 6427 : m_pLastCharacterContext = m_aPropertyStacks[eId].top();
423 : // Sadly an assert about deferredCharacterProperties being empty is not possible
424 : // here, becase appendTextPortion() may not be called for every character section.
425 6427 : deferredCharacterProperties.clear();
426 : }
427 :
428 15347 : m_aPropertyStacks[eId].pop();
429 15347 : m_aContextStack.pop();
430 15347 : if(!m_aContextStack.empty() && !m_aPropertyStacks[m_aContextStack.top()].empty())
431 :
432 12530 : m_pTopContext = m_aPropertyStacks[m_aContextStack.top()].top();
433 : else
434 : {
435 : // OSL_ENSURE(eId == CONTEXT_SECTION, "this should happen at a section context end");
436 2817 : m_pTopContext.reset();
437 : }
438 : }
439 :
440 :
441 31983 : PropertyMapPtr DomainMapper_Impl::GetTopContextOfType(ContextType eId)
442 : {
443 31983 : PropertyMapPtr pRet;
444 : SAL_WARN_IF( m_aPropertyStacks[eId].empty(), "writerfilter",
445 : "no context of type " << static_cast<int>(eId) << " available");
446 31983 : if(!m_aPropertyStacks[eId].empty())
447 31928 : pRet = m_aPropertyStacks[eId].top();
448 31983 : return pRet;
449 : }
450 :
451 :
452 :
453 17 : uno::Reference< text::XTextAppend > DomainMapper_Impl::GetTopTextAppend()
454 : {
455 : OSL_ENSURE(!m_aTextAppendStack.empty(), "text append stack is empty" );
456 17 : return m_aTextAppendStack.top().xTextAppend;
457 : }
458 :
459 :
460 :
461 0 : void DomainMapper_Impl::InitTabStopFromStyle( const uno::Sequence< style::TabStop >& rInitTabStops )
462 : {
463 : OSL_ENSURE(!m_aCurrentTabStops.size(), "tab stops already initialized");
464 0 : for( sal_Int32 nTab = 0; nTab < rInitTabStops.getLength(); ++nTab)
465 : {
466 0 : m_aCurrentTabStops.push_back( DeletableTabStop(rInitTabStops[nTab]) );
467 : }
468 0 : }
469 :
470 :
471 :
472 0 : void DomainMapper_Impl::ModifyCurrentTabStop( Id nId, sal_Int32 nValue)
473 : {
474 : OSL_ENSURE(nId == NS_rtf::LN_dxaAdd || m_nCurrentTabStopIndex < m_aCurrentTabStops.size(),
475 : "tab stop creation error");
476 :
477 0 : if( nId != NS_rtf::LN_dxaAdd && m_nCurrentTabStopIndex >= m_aCurrentTabStops.size())
478 0 : return;
479 : static const style::TabAlign aTabAlignFromWord[] =
480 : {
481 : style::TabAlign_LEFT,
482 : style::TabAlign_CENTER,
483 : style::TabAlign_RIGHT,
484 : style::TabAlign_DECIMAL,
485 : style::TabAlign_LEFT
486 : };
487 : static const sal_Unicode aTabFillCharWord[] =
488 : {
489 : ' ',
490 : '.',
491 : '-',
492 : '_',
493 : '_',
494 : 0xb7
495 : };
496 :
497 0 : switch(nId)
498 : {
499 : case NS_rtf::LN_dxaAdd: //set tab
500 : m_aCurrentTabStops.push_back(
501 0 : DeletableTabStop(style::TabStop(ConversionHelper::convertTwipToMM100(nValue), style::TabAlign_LEFT, ' ', ' ')));
502 0 : break;
503 : case NS_rtf::LN_dxaDel: //deleted tab
504 : {
505 : //mark the tab stop at the given position as deleted
506 0 : ::std::vector<DeletableTabStop>::iterator aIt = m_aCurrentTabStops.begin();
507 0 : ::std::vector<DeletableTabStop>::iterator aEndIt = m_aCurrentTabStops.end();
508 0 : sal_Int32 nConverted = ConversionHelper::convertTwipToMM100(nValue);
509 0 : for( ; aIt != aEndIt; ++aIt)
510 : {
511 0 : if( aIt->Position == nConverted )
512 : {
513 0 : aIt->bDeleted = true;
514 0 : break;
515 : }
516 : }
517 : }
518 0 : break;
519 : case NS_rtf::LN_TLC: //tab leading characters - for decimal tabs
520 : // 0 - no leader, 1- dotted, 2 - hyphenated, 3 - single line, 4 - heavy line, 5 - middle dot
521 0 : if( nValue >= 0 && nValue < sal::static_int_cast<sal_Int32>(sizeof(aTabFillCharWord) / sizeof (sal_Unicode)))
522 0 : m_aCurrentTabStops[m_nCurrentTabStopIndex].FillChar = aTabFillCharWord[nValue];
523 0 : break;
524 : case NS_rtf::LN_JC: //tab justification
525 : //0 - left, 1 - centered, 2 - right, 3 - decimal 4 - bar
526 0 : if( nValue >= 0 && nValue < sal::static_int_cast<sal_Int32>(sizeof(aTabAlignFromWord) / sizeof (style::TabAlign)))
527 0 : m_aCurrentTabStops[m_nCurrentTabStopIndex].Alignment = aTabAlignFromWord[nValue];
528 0 : break;
529 : }
530 : }
531 :
532 369 : void DomainMapper_Impl::IncorporateTabStop( const DeletableTabStop & rTabStop )
533 : {
534 369 : ::std::vector<DeletableTabStop>::iterator aIt = m_aCurrentTabStops.begin();
535 369 : ::std::vector<DeletableTabStop>::iterator aEndIt = m_aCurrentTabStops.end();
536 369 : sal_Int32 nConverted = rTabStop.Position;
537 369 : bool bFound = false;
538 1640 : for( ; aIt != aEndIt; ++aIt)
539 : {
540 1271 : if( aIt->Position == nConverted )
541 : {
542 0 : bFound = true;
543 0 : if( rTabStop.bDeleted )
544 0 : m_aCurrentTabStops.erase( aIt );
545 : else
546 0 : *aIt = rTabStop;
547 0 : break;
548 : }
549 : }
550 369 : if( !bFound )
551 369 : m_aCurrentTabStops.push_back( rTabStop );
552 369 : }
553 :
554 :
555 180 : uno::Sequence< style::TabStop > DomainMapper_Impl::GetCurrentTabStopAndClear()
556 : {
557 180 : uno::Sequence< style::TabStop > aRet( sal_Int32( m_aCurrentTabStops.size() ) );
558 180 : style::TabStop* pArray = aRet.getArray();
559 180 : ::std::vector<DeletableTabStop>::const_iterator aIt = m_aCurrentTabStops.begin();
560 180 : ::std::vector<DeletableTabStop>::const_iterator aEndIt = m_aCurrentTabStops.end();
561 180 : sal_Int32 nDeleted = 0;
562 549 : for(sal_Int32 nIndex = 0; aIt != aEndIt; ++aIt)
563 : {
564 369 : if(!aIt->bDeleted)
565 367 : pArray[nIndex++] = *aIt;
566 : else
567 2 : ++nDeleted;
568 : }
569 180 : m_aCurrentTabStops.clear();
570 180 : m_nCurrentTabStopIndex = 0;
571 180 : if(nDeleted)
572 : {
573 1 : aRet.realloc( aRet.getLength() - nDeleted);
574 : }
575 180 : return aRet;
576 : }
577 :
578 : /*-------------------------------------------------------------------------
579 : returns a the value from the current paragraph style - if available
580 : TODO: What about parent styles?
581 : -----------------------------------------------------------------------*/
582 33 : uno::Any DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId)
583 : {
584 33 : StyleSheetEntryPtr pEntry;
585 33 : if( m_bInStyleSheetImport )
586 0 : pEntry = GetStyleSheetTable()->FindParentStyleSheet(OUString());
587 : else
588 66 : pEntry =
589 33 : GetStyleSheetTable()->FindStyleSheetByISTD(GetCurrentParaStyleId());
590 73 : while(pEntry.get( ) )
591 : {
592 : //is there a tab stop set?
593 8 : if(pEntry->pProperties)
594 : {
595 : PropertyMap::const_iterator aPropertyIter =
596 8 : pEntry->pProperties->find(PropertyDefinition(eId));
597 8 : if( aPropertyIter != pEntry->pProperties->end())
598 : {
599 1 : return aPropertyIter->second;
600 : }
601 : }
602 : //search until the property is set or no parent is available
603 7 : StyleSheetEntryPtr pNewEntry = GetStyleSheetTable()->FindParentStyleSheet(pEntry->sBaseStyleIdentifier);
604 :
605 : SAL_WARN_IF( pEntry == pNewEntry, "writerfilter", "circular loop in style hierarchy?");
606 :
607 7 : if (pEntry == pNewEntry) //fdo#49587
608 0 : break;
609 :
610 7 : pEntry = pNewEntry;
611 7 : }
612 32 : return uno::Any();
613 : }
614 :
615 :
616 147 : ListsManager::Pointer DomainMapper_Impl::GetListTable()
617 : {
618 147 : if(!m_pListTable)
619 : m_pListTable.reset(
620 33 : new ListsManager( m_rDMapper, m_xTextFactory ));
621 147 : return m_pListTable;
622 : }
623 :
624 :
625 69 : void DomainMapper_Impl::deferBreak( BreakType deferredBreakType)
626 : {
627 69 : switch (deferredBreakType)
628 : {
629 : case COLUMN_BREAK:
630 0 : m_bIsColumnBreakDeferred = true;
631 0 : break;
632 : case PAGE_BREAK:
633 69 : m_bIsPageBreakDeferred = true;
634 69 : break;
635 : default:
636 0 : return;
637 : }
638 : }
639 :
640 14523 : bool DomainMapper_Impl::isBreakDeferred( BreakType deferredBreakType )
641 : {
642 14523 : switch (deferredBreakType)
643 : {
644 : case COLUMN_BREAK:
645 7183 : return m_bIsColumnBreakDeferred;
646 : case PAGE_BREAK:
647 7340 : return m_bIsPageBreakDeferred;
648 : default:
649 0 : return false;
650 : }
651 : }
652 :
653 0 : void DomainMapper_Impl::clearDeferredBreak(BreakType deferredBreakType)
654 : {
655 0 : switch (deferredBreakType)
656 : {
657 : case COLUMN_BREAK:
658 0 : m_bIsColumnBreakDeferred = false;
659 0 : break;
660 : case PAGE_BREAK:
661 0 : m_bIsPageBreakDeferred = false;
662 0 : break;
663 : default:
664 0 : break;
665 : }
666 0 : }
667 :
668 7251 : void DomainMapper_Impl::clearDeferredBreaks()
669 : {
670 7251 : m_bIsColumnBreakDeferred = false;
671 7251 : m_bIsPageBreakDeferred = false;
672 7251 : }
673 :
674 :
675 15 : void lcl_MoveBorderPropertiesToFrame(uno::Sequence<beans::PropertyValue>& rFrameProperties,
676 : uno::Reference<text::XTextRange> xStartTextRange,
677 : uno::Reference<text::XTextRange> xEndTextRange )
678 : {
679 : try
680 : {
681 16 : uno::Reference<text::XTextCursor> xRangeCursor = xStartTextRange->getText()->createTextCursorByRange( xStartTextRange );
682 14 : xRangeCursor->gotoRange( xEndTextRange, true );
683 :
684 28 : uno::Reference<beans::XPropertySet> xTextRangeProperties(xRangeCursor, uno::UNO_QUERY);
685 14 : if(!xTextRangeProperties.is())
686 15 : return ;
687 :
688 : PropertyIds aBorderProperties[] =
689 : {
690 : PROP_LEFT_BORDER,
691 : PROP_RIGHT_BORDER,
692 : PROP_TOP_BORDER,
693 : PROP_BOTTOM_BORDER,
694 : PROP_LEFT_BORDER_DISTANCE,
695 : PROP_RIGHT_BORDER_DISTANCE,
696 : PROP_TOP_BORDER_DISTANCE,
697 : PROP_BOTTOM_BORDER_DISTANCE
698 14 : };
699 :
700 14 : sal_uInt32 nStart = rFrameProperties.getLength();
701 14 : sal_uInt32 nBorderPropertyCount = sizeof( aBorderProperties ) / sizeof(PropertyIds);
702 14 : rFrameProperties.realloc(nStart + nBorderPropertyCount);
703 :
704 14 : beans::PropertyValue* pFrameProperties = rFrameProperties.getArray();
705 14 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
706 126 : for( sal_uInt32 nProperty = 0; nProperty < nBorderPropertyCount; ++nProperty)
707 : {
708 112 : OUString sPropertyName = rPropNameSupplier.GetName(aBorderProperties[nProperty]);
709 112 : pFrameProperties[nStart].Name = sPropertyName;
710 112 : pFrameProperties[nStart].Value = xTextRangeProperties->getPropertyValue(sPropertyName);
711 112 : if( nProperty < 4 )
712 56 : xTextRangeProperties->setPropertyValue( sPropertyName, uno::makeAny(table::BorderLine2()));
713 112 : ++nStart;
714 112 : }
715 28 : rFrameProperties.realloc(nStart);
716 : }
717 1 : catch( const uno::Exception& )
718 : {
719 : }
720 : }
721 :
722 :
723 15 : void lcl_AddRangeAndStyle(
724 : ParagraphPropertiesPtr& pToBeSavedProperties,
725 : uno::Reference< text::XTextAppend > xTextAppend,
726 : PropertyMapPtr pPropertyMap,
727 : TextAppendContext& rAppendContext)
728 : {
729 : uno::Reference<text::XParagraphCursor> xParaCursor(
730 15 : xTextAppend->createTextCursorByRange( rAppendContext.xInsertPosition.is() ? rAppendContext.xInsertPosition : xTextAppend->getEnd()), uno::UNO_QUERY_THROW );
731 15 : pToBeSavedProperties->SetEndingRange(xParaCursor->getStart());
732 15 : xParaCursor->gotoStartOfParagraph( false );
733 :
734 15 : pToBeSavedProperties->SetStartingRange(xParaCursor->getStart());
735 15 : if(pPropertyMap)
736 : {
737 15 : PropertyMap::iterator aParaStyleIter = pPropertyMap->find(PropertyDefinition( PROP_PARA_STYLE_NAME ) );
738 15 : if( aParaStyleIter != pPropertyMap->end())
739 : {
740 15 : OUString sName;
741 15 : aParaStyleIter->second >>= sName;
742 15 : pToBeSavedProperties->SetParaStyleName(sName);
743 : }
744 15 : }
745 15 : }
746 :
747 :
748 : //define some default frame width - 0cm ATM: this allow the frame to be wrapped around the text
749 : #define DEFAULT_FRAME_MIN_WIDTH 0
750 :
751 384 : void DomainMapper_Impl::CheckUnregisteredFrameConversion( )
752 : {
753 384 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
754 384 : if (m_aTextAppendStack.empty())
755 384 : return;
756 384 : TextAppendContext& rAppendContext = m_aTextAppendStack.top();
757 : // n#779642: ignore fly frame inside table as it could lead to messy situations
758 784 : if( rAppendContext.pLastParagraphProperties.get() && rAppendContext.pLastParagraphProperties->IsFrameMode()
759 400 : && !getTableManager().isInTable() )
760 : {
761 : try
762 : {
763 : StyleSheetEntryPtr pParaStyle =
764 15 : GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(rAppendContext.pLastParagraphProperties->GetParaStyleName());
765 :
766 30 : uno::Sequence< beans::PropertyValue > aFrameProperties(pParaStyle ? 16: 9);
767 :
768 15 : if ( pParaStyle.get( ) )
769 : {
770 0 : beans::PropertyValue* pFrameProperties = aFrameProperties.getArray();
771 0 : pFrameProperties[0].Name = rPropNameSupplier.GetName(PROP_WIDTH);
772 0 : pFrameProperties[1].Name = rPropNameSupplier.GetName(PROP_HEIGHT);
773 0 : pFrameProperties[2].Name = rPropNameSupplier.GetName(PROP_SIZE_TYPE);
774 0 : pFrameProperties[3].Name = rPropNameSupplier.GetName(PROP_WIDTH_TYPE);
775 0 : pFrameProperties[4].Name = rPropNameSupplier.GetName(PROP_HORI_ORIENT);
776 0 : pFrameProperties[5].Name = rPropNameSupplier.GetName(PROP_HORI_ORIENT_POSITION);
777 0 : pFrameProperties[6].Name = rPropNameSupplier.GetName(PROP_HORI_ORIENT_RELATION);
778 0 : pFrameProperties[7].Name = rPropNameSupplier.GetName(PROP_VERT_ORIENT);
779 0 : pFrameProperties[8].Name = rPropNameSupplier.GetName(PROP_VERT_ORIENT_POSITION);
780 0 : pFrameProperties[9].Name = rPropNameSupplier.GetName(PROP_VERT_ORIENT_RELATION);
781 0 : pFrameProperties[10].Name = rPropNameSupplier.GetName(PROP_SURROUND);
782 0 : pFrameProperties[11].Name = rPropNameSupplier.GetName(PROP_LEFT_MARGIN);
783 0 : pFrameProperties[12].Name = rPropNameSupplier.GetName(PROP_RIGHT_MARGIN);
784 0 : pFrameProperties[13].Name = rPropNameSupplier.GetName(PROP_TOP_MARGIN);
785 0 : pFrameProperties[14].Name = rPropNameSupplier.GetName(PROP_BOTTOM_MARGIN);
786 0 : pFrameProperties[15].Name = rPropNameSupplier.GetName(PROP_BACK_COLOR_TRANSPARENCY);
787 :
788 0 : const ParagraphProperties* pStyleProperties = dynamic_cast<const ParagraphProperties*>( pParaStyle->pProperties.get() );
789 : sal_Int32 nWidth =
790 0 : rAppendContext.pLastParagraphProperties->Getw() > 0 ?
791 0 : rAppendContext.pLastParagraphProperties->Getw() :
792 0 : pStyleProperties->Getw();
793 0 : bool bAutoWidth = nWidth < 1;
794 0 : if( bAutoWidth )
795 0 : nWidth = DEFAULT_FRAME_MIN_WIDTH;
796 0 : pFrameProperties[0].Value <<= nWidth;
797 :
798 0 : pFrameProperties[1].Value <<=
799 0 : rAppendContext.pLastParagraphProperties->Geth() > 0 ?
800 0 : rAppendContext.pLastParagraphProperties->Geth() :
801 0 : pStyleProperties->Geth();
802 :
803 0 : pFrameProperties[2].Value <<= sal_Int16(
804 0 : rAppendContext.pLastParagraphProperties->GethRule() >= 0 ?
805 0 : rAppendContext.pLastParagraphProperties->GethRule() :
806 0 : pStyleProperties->GethRule() >=0 ? pStyleProperties->GethRule() : text::SizeType::VARIABLE);
807 :
808 0 : pFrameProperties[3].Value <<= bAutoWidth ? text::SizeType::MIN : text::SizeType::FIX;
809 :
810 : sal_Int16 nHoriOrient = sal_Int16(
811 0 : rAppendContext.pLastParagraphProperties->GetxAlign() >= 0 ?
812 0 : rAppendContext.pLastParagraphProperties->GetxAlign() :
813 0 : pStyleProperties->GetxAlign() >= 0 ? pStyleProperties->GetxAlign() : text::HoriOrientation::NONE );
814 0 : pFrameProperties[4].Value <<= nHoriOrient;
815 :
816 0 : pFrameProperties[5].Value <<=
817 0 : rAppendContext.pLastParagraphProperties->IsxValid() ?
818 0 : rAppendContext.pLastParagraphProperties->Getx() : pStyleProperties->Getx();
819 0 : pFrameProperties[6].Value <<= sal_Int16(
820 0 : rAppendContext.pLastParagraphProperties->GethAnchor() >= 0 ?
821 0 : rAppendContext.pLastParagraphProperties->GethAnchor() :
822 0 : pStyleProperties->GethAnchor() );
823 :
824 : sal_Int16 nVertOrient = sal_Int16(
825 0 : rAppendContext.pLastParagraphProperties->GetyAlign() >= 0 ?
826 0 : rAppendContext.pLastParagraphProperties->GetyAlign() :
827 0 : pStyleProperties->GetyAlign() >= 0 ? pStyleProperties->GetyAlign() : text::VertOrientation::NONE );
828 0 : pFrameProperties[7].Value <<= nVertOrient;
829 :
830 0 : pFrameProperties[8].Value <<=
831 0 : rAppendContext.pLastParagraphProperties->IsyValid() ?
832 0 : rAppendContext.pLastParagraphProperties->Gety() : pStyleProperties->Gety();
833 0 : pFrameProperties[9].Value <<= sal_Int16(
834 0 : rAppendContext.pLastParagraphProperties->GetvAnchor() >= 0 ?
835 0 : rAppendContext.pLastParagraphProperties->GetvAnchor() :
836 0 : pStyleProperties->GetvAnchor() );
837 :
838 0 : pFrameProperties[10].Value <<= text::WrapTextMode(
839 0 : rAppendContext.pLastParagraphProperties->GetWrap() >= 0 ?
840 0 : rAppendContext.pLastParagraphProperties->GetWrap() :
841 0 : pStyleProperties->GetWrap());
842 :
843 : sal_Int32 nBottomDist;
844 : sal_Int32 nTopDist = nBottomDist =
845 0 : rAppendContext.pLastParagraphProperties->GethSpace() >= 0 ?
846 0 : rAppendContext.pLastParagraphProperties->GethSpace() :
847 0 : pStyleProperties->GethSpace();
848 :
849 0 : pFrameProperties[11].Value <<= nVertOrient == text::VertOrientation::TOP ? 0 : nTopDist;
850 0 : pFrameProperties[12].Value <<= nVertOrient == text::VertOrientation::BOTTOM ? 0 : nBottomDist;
851 :
852 : sal_Int32 nRightDist;
853 : sal_Int32 nLeftDist = nRightDist =
854 0 : rAppendContext.pLastParagraphProperties->GetvSpace() >= 0 ?
855 0 : rAppendContext.pLastParagraphProperties->GetvSpace() :
856 0 : pStyleProperties->GetvSpace() >= 0 ? pStyleProperties->GetvSpace() : 0;
857 0 : pFrameProperties[13].Value <<= nHoriOrient == text::HoriOrientation::LEFT ? 0 : nLeftDist;
858 0 : pFrameProperties[14].Value <<= nHoriOrient == text::HoriOrientation::RIGHT ? 0 : nRightDist;
859 : // If there is no fill, the Word default is 100% transparency.
860 : // Otherwise CellColorHandler has priority, and this setting
861 : // will be ignored.
862 0 : pFrameProperties[15].Value <<= sal_Int32(100);
863 :
864 : lcl_MoveBorderPropertiesToFrame(aFrameProperties,
865 : rAppendContext.pLastParagraphProperties->GetStartingRange(),
866 0 : rAppendContext.pLastParagraphProperties->GetEndingRange());
867 : }
868 : else
869 : {
870 15 : beans::PropertyValue* pFrameProperties = aFrameProperties.getArray();
871 15 : pFrameProperties[0].Name = rPropNameSupplier.GetName(PROP_WIDTH);
872 15 : pFrameProperties[1].Name = rPropNameSupplier.GetName(PROP_SIZE_TYPE);
873 15 : pFrameProperties[2].Name = rPropNameSupplier.GetName(PROP_WIDTH_TYPE);
874 15 : pFrameProperties[3].Name = rPropNameSupplier.GetName(PROP_HORI_ORIENT);
875 15 : pFrameProperties[4].Name = rPropNameSupplier.GetName(PROP_VERT_ORIENT);
876 15 : pFrameProperties[5].Name = rPropNameSupplier.GetName(PROP_LEFT_MARGIN);
877 15 : pFrameProperties[6].Name = rPropNameSupplier.GetName(PROP_RIGHT_MARGIN);
878 15 : pFrameProperties[7].Name = rPropNameSupplier.GetName(PROP_TOP_MARGIN);
879 15 : pFrameProperties[8].Name = rPropNameSupplier.GetName(PROP_BOTTOM_MARGIN);
880 :
881 15 : sal_Int32 nWidth = rAppendContext.pLastParagraphProperties->Getw();
882 15 : bool bAutoWidth = nWidth < 1;
883 15 : if( bAutoWidth )
884 0 : nWidth = DEFAULT_FRAME_MIN_WIDTH;
885 15 : pFrameProperties[0].Value <<= nWidth;
886 :
887 45 : pFrameProperties[1].Value <<= sal_Int16(
888 15 : rAppendContext.pLastParagraphProperties->GethRule() >= 0 ?
889 15 : rAppendContext.pLastParagraphProperties->GethRule() :
890 15 : text::SizeType::VARIABLE);
891 :
892 15 : pFrameProperties[2].Value <<= bAutoWidth ? text::SizeType::MIN : text::SizeType::FIX;
893 :
894 : sal_Int16 nHoriOrient = sal_Int16(
895 15 : rAppendContext.pLastParagraphProperties->GetxAlign() >= 0 ?
896 15 : rAppendContext.pLastParagraphProperties->GetxAlign() :
897 30 : text::HoriOrientation::NONE );
898 15 : pFrameProperties[3].Value <<= nHoriOrient;
899 :
900 : sal_Int16 nVertOrient = sal_Int16(
901 15 : rAppendContext.pLastParagraphProperties->GetyAlign() >= 0 ?
902 15 : rAppendContext.pLastParagraphProperties->GetyAlign() :
903 30 : text::VertOrientation::NONE );
904 15 : pFrameProperties[4].Value <<= nVertOrient;
905 :
906 15 : sal_Int32 nVertDist = rAppendContext.pLastParagraphProperties->GethSpace();
907 15 : if( nVertDist < 0 )
908 14 : nVertDist = 0;
909 15 : pFrameProperties[5].Value <<= nVertOrient == text::VertOrientation::TOP ? 0 : nVertDist;
910 15 : pFrameProperties[6].Value <<= nVertOrient == text::VertOrientation::BOTTOM ? 0 : nVertDist;
911 :
912 15 : sal_Int32 nHoriDist = rAppendContext.pLastParagraphProperties->GetvSpace();
913 15 : if( nHoriDist < 0 )
914 14 : nHoriDist = 0;
915 15 : pFrameProperties[7].Value <<= nHoriOrient == text::HoriOrientation::LEFT ? 0 : nHoriDist;
916 15 : pFrameProperties[8].Value <<= nHoriOrient == text::HoriOrientation::RIGHT ? 0 : nHoriDist;
917 :
918 15 : if( rAppendContext.pLastParagraphProperties->Geth() > 0 )
919 : {
920 13 : sal_Int32 nOldSize = aFrameProperties.getLength();
921 13 : aFrameProperties.realloc( nOldSize + 1 );
922 13 : pFrameProperties = aFrameProperties.getArray();
923 13 : pFrameProperties[nOldSize].Name = rPropNameSupplier.GetName(PROP_HEIGHT);
924 13 : pFrameProperties[nOldSize].Value <<= rAppendContext.pLastParagraphProperties->Geth();
925 : }
926 :
927 15 : if( rAppendContext.pLastParagraphProperties->IsxValid() )
928 : {
929 15 : sal_Int32 nOldSize = aFrameProperties.getLength();
930 15 : aFrameProperties.realloc( nOldSize + 1 );
931 15 : pFrameProperties = aFrameProperties.getArray();
932 15 : pFrameProperties[nOldSize].Name = rPropNameSupplier.GetName(PROP_HORI_ORIENT_POSITION);
933 15 : pFrameProperties[nOldSize].Value <<= rAppendContext.pLastParagraphProperties->Getx();
934 : }
935 :
936 15 : if( rAppendContext.pLastParagraphProperties->GethAnchor() >= 0 )
937 : {
938 15 : sal_Int32 nOldSize = aFrameProperties.getLength();
939 15 : aFrameProperties.realloc( nOldSize + 1 );
940 15 : pFrameProperties = aFrameProperties.getArray();
941 15 : pFrameProperties[nOldSize].Name = rPropNameSupplier.GetName(PROP_HORI_ORIENT_RELATION);
942 30 : pFrameProperties[nOldSize].Value <<= sal_Int16(
943 30 : rAppendContext.pLastParagraphProperties->GethAnchor() );
944 : }
945 :
946 15 : if( rAppendContext.pLastParagraphProperties->IsyValid() )
947 : {
948 15 : sal_Int32 nOldSize = aFrameProperties.getLength();
949 15 : aFrameProperties.realloc( nOldSize + 1 );
950 15 : pFrameProperties = aFrameProperties.getArray();
951 15 : pFrameProperties[nOldSize].Name = rPropNameSupplier.GetName(PROP_VERT_ORIENT_POSITION);
952 15 : pFrameProperties[nOldSize].Value <<= rAppendContext.pLastParagraphProperties->Gety();
953 : }
954 :
955 15 : if( rAppendContext.pLastParagraphProperties->GetvAnchor() >= 0 )
956 : {
957 15 : sal_Int32 nOldSize = aFrameProperties.getLength();
958 15 : aFrameProperties.realloc( nOldSize + 1 );
959 15 : pFrameProperties = aFrameProperties.getArray();
960 15 : pFrameProperties[nOldSize].Name = rPropNameSupplier.GetName(PROP_VERT_ORIENT_RELATION);
961 30 : pFrameProperties[nOldSize].Value <<= sal_Int16(
962 30 : rAppendContext.pLastParagraphProperties->GetvAnchor() );
963 : }
964 :
965 15 : if( rAppendContext.pLastParagraphProperties->GetWrap() >= 0 )
966 : {
967 1 : sal_Int32 nOldSize = aFrameProperties.getLength();
968 1 : aFrameProperties.realloc( nOldSize + 1 );
969 1 : pFrameProperties = aFrameProperties.getArray();
970 1 : pFrameProperties[nOldSize].Name = rPropNameSupplier.GetName(PROP_SURROUND);
971 2 : pFrameProperties[nOldSize].Value <<= text::WrapTextMode(
972 2 : rAppendContext.pLastParagraphProperties->GetWrap() );
973 : }
974 :
975 : lcl_MoveBorderPropertiesToFrame(aFrameProperties,
976 : rAppendContext.pLastParagraphProperties->GetStartingRange(),
977 15 : rAppendContext.pLastParagraphProperties->GetEndingRange());
978 : }
979 :
980 : //frame conversion has to be executed after table conversion
981 : RegisterFrameConversion(
982 : rAppendContext.pLastParagraphProperties->GetStartingRange(),
983 : rAppendContext.pLastParagraphProperties->GetEndingRange(),
984 30 : aFrameProperties );
985 : }
986 0 : catch( const uno::Exception& )
987 : {
988 : }
989 : }
990 : }
991 :
992 1992 : void DomainMapper_Impl::finishParagraph( PropertyMapPtr pPropertyMap )
993 : {
994 : #ifdef DEBUG_DOMAINMAPPER
995 : dmapper_logger->startElement("finishParagraph");
996 : #endif
997 :
998 1992 : ParagraphPropertyMap* pParaContext = dynamic_cast< ParagraphPropertyMap* >( pPropertyMap.get() );
999 1992 : if (!m_aTextAppendStack.size())
1000 1992 : return;
1001 1992 : TextAppendContext& rAppendContext = m_aTextAppendStack.top();
1002 1992 : uno::Reference< text::XTextAppend > xTextAppend;
1003 1992 : if (!m_aTextAppendStack.empty())
1004 1992 : xTextAppend = rAppendContext.xTextAppend;
1005 1992 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1006 :
1007 : #ifdef DEBUG_DOMAINMAPPER
1008 : dmapper_logger->attribute("isTextAppend", xTextAppend.is());
1009 : #endif
1010 :
1011 1992 : if(xTextAppend.is() && ! getTableManager( ).isIgnore() && pParaContext != NULL)
1012 : {
1013 : try
1014 : {
1015 : /*the following combinations of previous and current frame settings can occur:
1016 : (1) - no old frame and no current frame -> no special action
1017 : (2) - no old frame and current DropCap -> save DropCap for later use, don't call finishParagraph
1018 : remove character properties of the DropCap?
1019 : (3) - no old frame and current Frame -> save Frame for later use
1020 : (4) - old DropCap and no current frame -> add DropCap to the properties of the finished paragraph, delete previous setting
1021 : (5) - old DropCap and current frame -> add DropCap to the properties of the finished paragraph, save current frame settings
1022 : (6) - old Frame and new DropCap -> add old Frame, save DropCap for later use
1023 : (7) - old Frame and new same Frame -> continue
1024 : (8) - old Frame and new different Frame -> add old Frame, save new Frame for later use
1025 : (9) - old Frame and no current frame -> add old Frame, delete previous settings
1026 :
1027 : old _and_ new DropCap must not occur
1028 : */
1029 :
1030 : bool bIsDropCap =
1031 1632 : pParaContext->IsFrameMode() &&
1032 1632 : sal::static_int_cast<Id>(pParaContext->GetDropCap()) != NS_ooxml::LN_Value_wordprocessingml_ST_DropCap_none;
1033 :
1034 1610 : style::DropCapFormat aDrop;
1035 1610 : ParagraphPropertiesPtr pToBeSavedProperties;
1036 1610 : bool bKeepLastParagraphProperties = false;
1037 1610 : if( bIsDropCap )
1038 : {
1039 : uno::Reference<text::XParagraphCursor> xParaCursor(
1040 0 : xTextAppend->createTextCursorByRange(xTextAppend->getEnd()), uno::UNO_QUERY_THROW);
1041 : //select paragraph
1042 0 : xParaCursor->gotoStartOfParagraph( true );
1043 0 : uno::Reference< beans::XPropertyState > xParaProperties( xParaCursor, uno::UNO_QUERY_THROW );
1044 0 : xParaProperties->setPropertyToDefault(rPropNameSupplier.GetName(PROP_CHAR_ESCAPEMENT));
1045 0 : xParaProperties->setPropertyToDefault(rPropNameSupplier.GetName(PROP_CHAR_HEIGHT));
1046 : //handles (2) and part of (6)
1047 0 : pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
1048 0 : sal_Int32 nCount = xParaCursor->getString().getLength();
1049 0 : pToBeSavedProperties->SetDropCapLength(nCount > 0 && nCount < 255 ? (sal_Int8)nCount : 1);
1050 : }
1051 1610 : if( rAppendContext.pLastParagraphProperties.get() )
1052 : {
1053 18 : if( sal::static_int_cast<Id>(rAppendContext.pLastParagraphProperties->GetDropCap()) != NS_ooxml::LN_Value_wordprocessingml_ST_DropCap_none)
1054 : {
1055 : //handles (4) and part of (5)
1056 : //create a DropCap property, add it to the property sequence of finishParagraph
1057 0 : sal_Int32 nLines = rAppendContext.pLastParagraphProperties->GetLines();
1058 0 : aDrop.Lines = nLines > 0 && nLines < 254 ? (sal_Int8)++nLines : 2;
1059 0 : aDrop.Count = rAppendContext.pLastParagraphProperties->GetDropCapLength();
1060 0 : aDrop.Distance = 0; //TODO: find distance value
1061 : //completes (5)
1062 0 : if( pParaContext->IsFrameMode() )
1063 0 : pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
1064 : }
1065 18 : else if(*rAppendContext.pLastParagraphProperties == *pParaContext )
1066 : {
1067 : //handles (7)
1068 7 : rAppendContext.pLastParagraphProperties->SetEndingRange(rAppendContext.xInsertPosition.is() ? rAppendContext.xInsertPosition : xTextAppend->getEnd());
1069 7 : bKeepLastParagraphProperties = true;
1070 : }
1071 : else
1072 : {
1073 : //handles (8)(9) and completes (6)
1074 11 : CheckUnregisteredFrameConversion( );
1075 :
1076 : // If different frame properties are set on this paragraph, keep them.
1077 11 : if ( !bIsDropCap && pParaContext->IsFrameMode() )
1078 : {
1079 2 : pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
1080 2 : lcl_AddRangeAndStyle(pToBeSavedProperties, xTextAppend, pPropertyMap, rAppendContext);
1081 : }
1082 : }
1083 :
1084 : }
1085 : else //
1086 : {
1087 : // (1) doesn't need handling
1088 : //
1089 1592 : if( !bIsDropCap && pParaContext->IsFrameMode() )
1090 : {
1091 13 : pToBeSavedProperties.reset( new ParagraphProperties(*pParaContext) );
1092 13 : lcl_AddRangeAndStyle(pToBeSavedProperties, xTextAppend, pPropertyMap, rAppendContext);
1093 : }
1094 : }
1095 3220 : uno::Sequence< beans::PropertyValue > aProperties;
1096 1610 : if( pPropertyMap.get() )
1097 : {
1098 1610 : aProperties = pPropertyMap->GetPropertyValues();
1099 : }
1100 1610 : if( !bIsDropCap )
1101 : {
1102 1610 : if( aDrop.Lines > 1 )
1103 : {
1104 0 : sal_uInt32 nLength = aProperties.getLength();
1105 0 : aProperties.realloc( nLength + 1 );
1106 0 : aProperties[nLength].Value <<= aDrop;
1107 0 : aProperties[nLength].Name = rPropNameSupplier.GetName(PROP_DROP_CAP_FORMAT);
1108 : }
1109 1610 : uno::Reference< text::XTextRange > xTextRange;
1110 1610 : if (rAppendContext.xInsertPosition.is())
1111 : {
1112 4 : xTextRange = xTextAppend->finishParagraphInsert( aProperties, rAppendContext.xInsertPosition );
1113 4 : rAppendContext.xCursor->gotoNextParagraph(false);
1114 4 : if (rAppendContext.pLastParagraphProperties.get())
1115 0 : rAppendContext.pLastParagraphProperties->SetEndingRange(xTextRange->getEnd());
1116 : }
1117 : else
1118 1606 : xTextRange = xTextAppend->finishParagraph( aProperties );
1119 1605 : getTableManager( ).handle(xTextRange);
1120 :
1121 : // Get the end of paragraph character inserted
1122 3210 : uno::Reference< text::XTextCursor > xCur = xTextRange->getText( )->createTextCursor( );
1123 1605 : if (rAppendContext.xInsertPosition.is())
1124 4 : xCur->gotoRange( rAppendContext.xInsertPosition, false );
1125 : else
1126 1601 : xCur->gotoEnd( false );
1127 1605 : xCur->goLeft( 1 , true );
1128 3210 : uno::Reference< text::XTextRange > xParaEnd( xCur, uno::UNO_QUERY );
1129 1605 : CheckParaRedline( xParaEnd );
1130 :
1131 1605 : m_bIsFirstParaInSection = false;
1132 1605 : m_bIsLastParaInSection = false;
1133 1605 : m_bParaChanged = false;
1134 :
1135 : // Reset the frame properties for the next paragraph
1136 3215 : pParaContext->ResetFrameProperties();
1137 : }
1138 1605 : if( !bKeepLastParagraphProperties )
1139 3208 : rAppendContext.pLastParagraphProperties = pToBeSavedProperties;
1140 : }
1141 0 : catch(const lang::IllegalArgumentException&)
1142 : {
1143 : OSL_FAIL( "IllegalArgumentException in DomainMapper_Impl::finishParagraph" );
1144 : }
1145 5 : catch(const uno::Exception&)
1146 : {
1147 : }
1148 1992 : }
1149 :
1150 : #ifdef DEBUG_DOMAINMAPPER
1151 : dmapper_logger->endElement();
1152 : #endif
1153 : }
1154 :
1155 :
1156 12 : util::DateTime lcl_DateStringToDateTime( const OUString& rDateTime )
1157 : {
1158 12 : util::DateTime aDateTime;
1159 : //xsd::DateTime in the format [-]CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm] example: 2008-01-21T10:42:00Z
1160 : //OUString getToken( sal_Int32 token, sal_Unicode cTok, sal_Int32& index ) const SAL_THROW(())
1161 12 : sal_Int32 nIndex = 0;
1162 12 : OUString sDate = rDateTime.getToken( 0, 'T', nIndex );
1163 : // HACK: this is broken according to the spec, but MSOffice always treats the time as local,
1164 : // and writes it as Z (=UTC+0)
1165 24 : OUString sTime = rDateTime.getToken( 0, 'Z', nIndex );
1166 12 : nIndex = 0;
1167 12 : aDateTime.Year = sal_uInt16( sDate.getToken( 0, '-', nIndex ).toInt32() );
1168 12 : aDateTime.Month = sal_uInt16( sDate.getToken( 0, '-', nIndex ).toInt32() );
1169 12 : aDateTime.Day = sal_uInt16( sDate.copy( nIndex ).toInt32() );
1170 :
1171 12 : nIndex = 0;
1172 12 : aDateTime.Hours = sal_uInt16( sTime.getToken( 0, ':', nIndex ).toInt32() );
1173 12 : aDateTime.Minutes = sal_uInt16( sTime.getToken( 0, ':', nIndex ).toInt32() );
1174 12 : aDateTime.Seconds = sal_uInt16( sTime.copy( nIndex ).toInt32() );
1175 :
1176 24 : return aDateTime;
1177 : }
1178 :
1179 4856 : void DomainMapper_Impl::appendTextPortion( const OUString& rString, PropertyMapPtr pPropertyMap )
1180 : {
1181 4856 : if (m_bDiscardHeaderFooter)
1182 20 : return;
1183 :
1184 4846 : if (m_aTextAppendStack.empty())
1185 0 : return;
1186 :
1187 4846 : if( pPropertyMap == m_pTopContext && !deferredCharacterProperties.empty())
1188 4166 : processDeferredCharacterProperties();
1189 4846 : uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
1190 4846 : if(xTextAppend.is() && ! getTableManager( ).isIgnore())
1191 : {
1192 : try
1193 : {
1194 1058 : uno::Reference< text::XTextRange > xTextRange;
1195 1058 : if (m_aTextAppendStack.top().xInsertPosition.is())
1196 : {
1197 4 : xTextRange = xTextAppend->insertTextPortion(rString, pPropertyMap->GetPropertyValues(), m_aTextAppendStack.top().xInsertPosition);
1198 4 : m_aTextAppendStack.top().xCursor->gotoRange(xTextRange->getEnd(), false);
1199 : }
1200 : else
1201 1054 : xTextRange = xTextAppend->appendTextPortion(rString, pPropertyMap->GetPropertyValues());
1202 1058 : CheckRedline( xTextRange );
1203 1058 : m_bParaChanged = true;
1204 :
1205 : //getTableManager( ).handle(xTextRange);
1206 : }
1207 0 : catch(const lang::IllegalArgumentException&)
1208 : {
1209 : OSL_FAIL( "IllegalArgumentException in DomainMapper_Impl::appendTextPortion" );
1210 : }
1211 0 : catch(const uno::Exception&)
1212 : {
1213 : OSL_FAIL( "Exception in DomainMapper_Impl::appendTextPortion" );
1214 : }
1215 4846 : }
1216 : }
1217 :
1218 :
1219 289 : void DomainMapper_Impl::appendTextContent(
1220 : const uno::Reference< text::XTextContent > xContent,
1221 : const uno::Sequence< beans::PropertyValue > xPropertyValues
1222 : )
1223 : {
1224 289 : uno::Reference< text::XTextAppendAndConvert > xTextAppendAndConvert( m_aTextAppendStack.top().xTextAppend, uno::UNO_QUERY );
1225 : OSL_ENSURE( xTextAppendAndConvert.is(), "trying to append a text content without XTextAppendAndConvert" );
1226 289 : if(xTextAppendAndConvert.is() && ! getTableManager( ).isIgnore())
1227 : {
1228 : try
1229 : {
1230 289 : if (m_aTextAppendStack.top().xInsertPosition.is())
1231 1 : xTextAppendAndConvert->insertTextContentWithProperties( xContent, xPropertyValues, m_aTextAppendStack.top().xInsertPosition );
1232 : else
1233 288 : xTextAppendAndConvert->appendTextContent( xContent, xPropertyValues );
1234 : }
1235 2 : catch(const lang::IllegalArgumentException&)
1236 : {
1237 : }
1238 40 : catch(const uno::Exception&)
1239 : {
1240 : }
1241 289 : }
1242 289 : }
1243 :
1244 :
1245 :
1246 5 : void DomainMapper_Impl::appendOLE( const OUString& rStreamName, OLEHandlerPtr pOLEHandler )
1247 : {
1248 5 : static const OUString sEmbeddedService("com.sun.star.text.TextEmbeddedObject");
1249 : try
1250 : {
1251 5 : uno::Reference< text::XTextContent > xOLE( m_xTextFactory->createInstance(sEmbeddedService), uno::UNO_QUERY_THROW );
1252 10 : uno::Reference< beans::XPropertySet > xOLEProperties(xOLE, uno::UNO_QUERY_THROW);
1253 :
1254 10 : xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_STREAM_NAME ),
1255 10 : uno::makeAny( rStreamName ));
1256 5 : awt::Size aSize = pOLEHandler->getSize();
1257 5 : if( !aSize.Width )
1258 0 : aSize.Width = 1000;
1259 5 : if( !aSize.Height )
1260 0 : aSize.Height = 1000;
1261 10 : xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_WIDTH ),
1262 10 : uno::makeAny(aSize.Width));
1263 10 : xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_HEIGHT ),
1264 10 : uno::makeAny(aSize.Height));
1265 :
1266 10 : uno::Reference< graphic::XGraphic > xGraphic = pOLEHandler->getReplacement();
1267 10 : xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_GRAPHIC ),
1268 10 : uno::makeAny(xGraphic));
1269 : // mimic the treatment of graphics here.. it seems anchoring as character
1270 : // gives a better ( visually ) result
1271 5 : xOLEProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_ANCHOR_TYPE ), uno::makeAny( text::TextContentAnchorType_AS_CHARACTER ) );
1272 : // remove ( if valid ) associated shape ( used for graphic replacement )
1273 5 : m_aAnchoredStack.top( ).bToRemove = true;
1274 5 : RemoveLastParagraph();
1275 5 : m_aTextAppendStack.pop();
1276 :
1277 : //
1278 10 : appendTextContent( xOLE, uno::Sequence< beans::PropertyValue >() );
1279 :
1280 : }
1281 0 : catch( const uno::Exception& )
1282 : {
1283 : OSL_FAIL( "Exception in creation of OLE object" );
1284 : }
1285 :
1286 5 : }
1287 :
1288 148 : void DomainMapper_Impl::appendStarMath( const Value& val )
1289 : {
1290 148 : uno::Reference< embed::XEmbeddedObject > formula;
1291 148 : val.getAny() >>= formula;
1292 148 : if( formula.is() )
1293 : {
1294 148 : static const OUString sEmbeddedService("com.sun.star.text.TextEmbeddedObject");
1295 : try
1296 : {
1297 148 : uno::Reference< text::XTextContent > xStarMath( m_xTextFactory->createInstance(sEmbeddedService), uno::UNO_QUERY_THROW );
1298 296 : uno::Reference< beans::XPropertySet > xStarMathProperties(xStarMath, uno::UNO_QUERY_THROW);
1299 :
1300 296 : xStarMathProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_EMBEDDED_OBJECT ),
1301 296 : val.getAny());
1302 :
1303 296 : uno::Reference< uno::XInterface > xInterface( formula->getComponent(), uno::UNO_QUERY );
1304 148 : Size size( 1000, 1000 );
1305 148 : if( oox::FormulaImportBase* formulaimport = dynamic_cast< oox::FormulaImportBase* >( xInterface.get()))
1306 148 : size = formulaimport->getFormulaSize();
1307 296 : xStarMathProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_WIDTH ),
1308 296 : uno::makeAny( sal_Int32(size.Width())));
1309 296 : xStarMathProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_HEIGHT ),
1310 296 : uno::makeAny( sal_Int32(size.Height())));
1311 : // mimic the treatment of graphics here.. it seems anchoring as character
1312 : // gives a better ( visually ) result
1313 296 : xStarMathProperties->setPropertyValue(PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_ANCHOR_TYPE ),
1314 296 : uno::makeAny( text::TextContentAnchorType_AS_CHARACTER ) );
1315 296 : appendTextContent( xStarMath, uno::Sequence< beans::PropertyValue >() );
1316 : }
1317 0 : catch( const uno::Exception& )
1318 : {
1319 : OSL_FAIL( "Exception in creation of StarMath object" );
1320 : }
1321 148 : }
1322 148 : }
1323 :
1324 10 : uno::Reference< beans::XPropertySet > DomainMapper_Impl::appendTextSectionAfter(
1325 : uno::Reference< text::XTextRange >& xBefore )
1326 : {
1327 10 : uno::Reference< beans::XPropertySet > xRet;
1328 10 : if (m_aTextAppendStack.empty())
1329 0 : return xRet;
1330 20 : uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
1331 10 : if(xTextAppend.is())
1332 : {
1333 : try
1334 : {
1335 : uno::Reference< text::XParagraphCursor > xCursor(
1336 10 : xTextAppend->createTextCursorByRange( xBefore ), uno::UNO_QUERY_THROW);
1337 : //the cursor has been moved to the end of the paragraph because of the appendTextPortion() calls
1338 7 : xCursor->gotoStartOfParagraph( false );
1339 7 : if (m_aTextAppendStack.top().xInsertPosition.is())
1340 0 : xCursor->gotoRange( m_aTextAppendStack.top().xInsertPosition, true );
1341 : else
1342 7 : xCursor->gotoEnd( true );
1343 : //the paragraph after this new section is already inserted
1344 7 : xCursor->goLeft(1, true);
1345 7 : static const OUString sSectionService("com.sun.star.text.TextSection");
1346 14 : uno::Reference< text::XTextContent > xSection( m_xTextFactory->createInstance(sSectionService), uno::UNO_QUERY_THROW );
1347 7 : xSection->attach( uno::Reference< text::XTextRange >( xCursor, uno::UNO_QUERY_THROW) );
1348 14 : xRet = uno::Reference< beans::XPropertySet > (xSection, uno::UNO_QUERY );
1349 : }
1350 3 : catch(const uno::Exception&)
1351 : {
1352 : }
1353 :
1354 : }
1355 :
1356 10 : return xRet;
1357 : }
1358 :
1359 :
1360 44 : void DomainMapper_Impl::PushPageHeader(SectionPropertyMap::PageType eType)
1361 : {
1362 44 : m_bInHeaderFooterImport = true;
1363 :
1364 : //get the section context
1365 44 : PropertyMapPtr pContext = DomainMapper_Impl::GetTopContextOfType(CONTEXT_SECTION);
1366 : //ask for the header name of the given type
1367 44 : SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() );
1368 44 : if(pSectionContext)
1369 : {
1370 : uno::Reference< beans::XPropertySet > xPageStyle =
1371 : pSectionContext->GetPageStyle(
1372 : GetPageStyles(),
1373 : m_xTextFactory,
1374 44 : eType == SectionPropertyMap::PAGE_FIRST );
1375 44 : if (!xPageStyle.is())
1376 44 : return;
1377 : try
1378 : {
1379 44 : bool bLeft = eType == SectionPropertyMap::PAGE_LEFT;
1380 44 : if ((!bLeft && !m_pSettingsTable->GetEvenAndOddHeaders()) || (m_pSettingsTable->GetEvenAndOddHeaders()))
1381 : {
1382 36 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1383 :
1384 : //switch on header use
1385 36 : xPageStyle->setPropertyValue(
1386 36 : rPropNameSupplier.GetName(PROP_HEADER_IS_ON),
1387 72 : uno::makeAny(sal_True) );
1388 :
1389 : // If the 'Different Even & Odd Pages' flag is turned on - do not ignore it
1390 : // Even if the 'Even' header is blank - the flag should be imported (so it would look in LO like in Word)
1391 36 : if( m_pSettingsTable->GetEvenAndOddHeaders() )
1392 0 : xPageStyle->setPropertyValue(rPropNameSupplier.GetName(PROP_HEADER_IS_SHARED), uno::makeAny( false ));
1393 :
1394 : //set the interface
1395 36 : uno::Reference< text::XText > xHeaderText;
1396 36 : xPageStyle->getPropertyValue(rPropNameSupplier.GetName( bLeft ? PROP_HEADER_TEXT_LEFT : PROP_HEADER_TEXT) ) >>= xHeaderText;
1397 : m_aTextAppendStack.push( TextAppendContext(uno::Reference< text::XTextAppend >( xHeaderText, uno::UNO_QUERY_THROW),
1398 36 : m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(xHeaderText->getStart())));
1399 : }
1400 : else
1401 : {
1402 8 : m_bDiscardHeaderFooter = true;
1403 : }
1404 : }
1405 0 : catch( const uno::Exception& )
1406 : {
1407 44 : }
1408 44 : }
1409 : }
1410 :
1411 :
1412 41 : void DomainMapper_Impl::PushPageFooter(SectionPropertyMap::PageType eType)
1413 : {
1414 41 : m_bInHeaderFooterImport = true;
1415 :
1416 : //get the section context
1417 41 : PropertyMapPtr pContext = DomainMapper_Impl::GetTopContextOfType(CONTEXT_SECTION);
1418 : //ask for the footer name of the given type
1419 41 : SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() );
1420 41 : if(pSectionContext)
1421 : {
1422 : uno::Reference< beans::XPropertySet > xPageStyle =
1423 : pSectionContext->GetPageStyle(
1424 : GetPageStyles(),
1425 : m_xTextFactory,
1426 41 : eType == SectionPropertyMap::PAGE_FIRST );
1427 41 : if (!xPageStyle.is())
1428 41 : return;
1429 : try
1430 : {
1431 41 : bool bLeft = eType == SectionPropertyMap::PAGE_LEFT;
1432 41 : if ((!bLeft && !m_pSettingsTable->GetEvenAndOddHeaders()) || (m_pSettingsTable->GetEvenAndOddHeaders()))
1433 : {
1434 31 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1435 :
1436 : //switch on footer use
1437 31 : xPageStyle->setPropertyValue(
1438 31 : rPropNameSupplier.GetName(PROP_FOOTER_IS_ON),
1439 62 : uno::makeAny(sal_True) );
1440 :
1441 : // If the 'Different Even & Odd Pages' flag is turned on - do not ignore it
1442 : // Even if the 'Even' footer is blank - the flag should be imported (so it would look in LO like in Word)
1443 31 : if( m_pSettingsTable->GetEvenAndOddHeaders() )
1444 3 : xPageStyle->setPropertyValue(rPropNameSupplier.GetName(PROP_FOOTER_IS_SHARED), uno::makeAny( false ));
1445 :
1446 : //set the interface
1447 31 : uno::Reference< text::XText > xFooterText;
1448 31 : xPageStyle->getPropertyValue(rPropNameSupplier.GetName( bLeft ? PROP_FOOTER_TEXT_LEFT : PROP_FOOTER_TEXT) ) >>= xFooterText;
1449 : m_aTextAppendStack.push(TextAppendContext(uno::Reference< text::XTextAppend >( xFooterText, uno::UNO_QUERY_THROW ),
1450 31 : m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(xFooterText->getStart())));
1451 : }
1452 : else
1453 : {
1454 10 : m_bDiscardHeaderFooter = true;
1455 : }
1456 : }
1457 0 : catch( const uno::Exception& )
1458 : {
1459 41 : }
1460 41 : }
1461 : }
1462 :
1463 :
1464 85 : void DomainMapper_Impl::PopPageHeaderFooter()
1465 : {
1466 : //header and footer always have an empty paragraph at the end
1467 : //this has to be removed
1468 85 : RemoveLastParagraph( );
1469 85 : if (!m_aTextAppendStack.empty())
1470 : {
1471 85 : if (!m_bDiscardHeaderFooter)
1472 : {
1473 67 : m_aTextAppendStack.pop();
1474 : }
1475 85 : m_bDiscardHeaderFooter = false;
1476 : }
1477 85 : m_bInHeaderFooterImport = false;
1478 85 : }
1479 :
1480 :
1481 5 : void DomainMapper_Impl::PushFootOrEndnote( bool bIsFootnote )
1482 : {
1483 : try
1484 : {
1485 5 : PropertyMapPtr pTopContext = GetTopContext();
1486 10 : uno::Reference< text::XText > xFootnoteText;
1487 5 : if (GetTextFactory().is())
1488 10 : xFootnoteText.set( GetTextFactory()->createInstance(
1489 : bIsFootnote ?
1490 5 : OUString( "com.sun.star.text.Footnote" ) : OUString( "com.sun.star.text.Endnote" )),
1491 5 : uno::UNO_QUERY_THROW );
1492 10 : uno::Reference< text::XFootnote > xFootnote( xFootnoteText, uno::UNO_QUERY_THROW );
1493 5 : pTopContext->SetFootnote( xFootnote );
1494 5 : if( pTopContext->GetFootnoteSymbol() != 0)
1495 : {
1496 0 : xFootnote->setLabel( OUString( pTopContext->GetFootnoteSymbol() ) );
1497 : }
1498 10 : FontTablePtr pFontTable = GetFontTable();
1499 10 : uno::Sequence< beans::PropertyValue > aFontProperties;
1500 5 : if( pFontTable && pTopContext->GetFootnoteFontId() >= 0 && pFontTable->size() > (size_t)pTopContext->GetFootnoteFontId() )
1501 : {
1502 0 : const FontEntry::Pointer_t pFontEntry(pFontTable->getFontEntry(sal_uInt32(pTopContext->GetFootnoteFontId())));
1503 0 : PropertyMapPtr aFontProps( new PropertyMap );
1504 0 : aFontProps->Insert(PROP_CHAR_FONT_NAME, uno::makeAny( pFontEntry->sFontName ));
1505 0 : aFontProps->Insert(PROP_CHAR_FONT_CHAR_SET, uno::makeAny( (sal_Int16)pFontEntry->nTextEncoding ));
1506 0 : aFontProps->Insert(PROP_CHAR_FONT_PITCH, uno::makeAny( pFontEntry->nPitchRequest ));
1507 0 : aFontProperties = aFontProps->GetPropertyValues();
1508 : }
1509 5 : else if(!pTopContext->GetFootnoteFontName().isEmpty())
1510 : {
1511 0 : PropertyMapPtr aFontProps( new PropertyMap );
1512 0 : aFontProps->Insert(PROP_CHAR_FONT_NAME, uno::makeAny( pTopContext->GetFootnoteFontName() ));
1513 0 : aFontProperties = aFontProps->GetPropertyValues();
1514 : }
1515 5 : appendTextContent( uno::Reference< text::XTextContent >( xFootnoteText, uno::UNO_QUERY_THROW ), aFontProperties );
1516 : m_aTextAppendStack.push(TextAppendContext(uno::Reference< text::XTextAppend >( xFootnoteText, uno::UNO_QUERY_THROW ),
1517 5 : m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : xFootnoteText->createTextCursorByRange(xFootnoteText->getStart())));
1518 :
1519 : // Redlines for the footnote anchor
1520 10 : CheckRedline( xFootnote->getAnchor( ) );
1521 : }
1522 0 : catch( const uno::Exception& e )
1523 : {
1524 : SAL_WARN("writerfilter", "exception in PushFootOrEndnote: " << e.Message);
1525 : }
1526 5 : }
1527 :
1528 8 : void DomainMapper_Impl::CreateRedline( uno::Reference< text::XTextRange > xRange, RedlineParamsPtr& pRedline )
1529 : {
1530 8 : if ( pRedline.get( ) )
1531 : {
1532 : try
1533 : {
1534 8 : OUString sType;
1535 8 : PropertyNameSupplier & rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier( );
1536 8 : switch ( pRedline->m_nToken & 0xffff )
1537 : {
1538 : case ooxml::OOXML_mod:
1539 4 : sType = rPropNameSupplier.GetName( PROP_FORMAT );
1540 4 : break;
1541 : case ooxml::OOXML_ins:
1542 2 : sType = rPropNameSupplier.GetName( PROP_INSERT );
1543 2 : break;
1544 : case ooxml::OOXML_del:
1545 2 : sType = rPropNameSupplier.GetName( PROP_DELETE );
1546 2 : break;
1547 : }
1548 8 : uno::Reference < text::XRedline > xRedline( xRange, uno::UNO_QUERY_THROW );
1549 16 : beans::PropertyValues aRedlineProperties( 2 );
1550 8 : beans::PropertyValue * pRedlineProperties = aRedlineProperties.getArray( );
1551 8 : pRedlineProperties[0].Name = rPropNameSupplier.GetName( PROP_REDLINE_AUTHOR );
1552 8 : pRedlineProperties[0].Value <<= pRedline->m_sAuthor;
1553 8 : pRedlineProperties[1].Name = rPropNameSupplier.GetName( PROP_REDLINE_DATE_TIME );
1554 8 : pRedlineProperties[1].Value <<= lcl_DateStringToDateTime( pRedline->m_sDate );
1555 :
1556 16 : xRedline->makeRedline( sType, aRedlineProperties );
1557 : }
1558 0 : catch( const uno::Exception & )
1559 : {
1560 : OSL_FAIL( "Exception in makeRedline" );
1561 : }
1562 : }
1563 8 : }
1564 :
1565 1605 : void DomainMapper_Impl::CheckParaRedline( uno::Reference< text::XTextRange > xRange )
1566 : {
1567 1605 : if ( m_pParaRedline.get( ) )
1568 : {
1569 0 : CreateRedline( xRange, m_pParaRedline );
1570 0 : ResetParaRedline( );
1571 : }
1572 1605 : }
1573 :
1574 1063 : void DomainMapper_Impl::CheckRedline( uno::Reference< text::XTextRange > xRange )
1575 : {
1576 1063 : vector<RedlineParamsPtr>::iterator pIt = m_aRedlines.begin( );
1577 1063 : vector< RedlineParamsPtr > aCleaned;
1578 1071 : for (; pIt != m_aRedlines.end( ); ++pIt )
1579 : {
1580 8 : CreateRedline( xRange, *pIt );
1581 :
1582 : // Adding the non-mod redlines to the temporary vector
1583 8 : if ( pIt->get( ) && ( ( *pIt )->m_nToken & 0xffff ) != ooxml::OOXML_mod )
1584 : {
1585 4 : aCleaned.push_back( *pIt );
1586 : }
1587 : }
1588 :
1589 1063 : m_aRedlines.swap( aCleaned );
1590 1063 : }
1591 :
1592 0 : void DomainMapper_Impl::StartParaChange( )
1593 : {
1594 0 : m_bIsParaChange = true;
1595 0 : }
1596 :
1597 9 : void DomainMapper_Impl::EndParaChange( )
1598 : {
1599 9 : m_bIsParaChange = false;
1600 9 : }
1601 :
1602 :
1603 :
1604 4 : void DomainMapper_Impl::PushAnnotation()
1605 : {
1606 : try
1607 : {
1608 4 : PropertyMapPtr pTopContext = GetTopContext();
1609 4 : m_bIsInComments = true;
1610 4 : if (!GetTextFactory().is())
1611 4 : return;
1612 12 : m_xAnnotationField = uno::Reference< beans::XPropertySet >( GetTextFactory()->createInstance(
1613 4 : "com.sun.star.text.TextField.Annotation" ),
1614 4 : uno::UNO_QUERY_THROW );
1615 8 : uno::Reference< text::XText > xAnnotationText;
1616 4 : m_xAnnotationField->getPropertyValue("TextRange") >>= xAnnotationText;
1617 : m_aTextAppendStack.push(TextAppendContext(uno::Reference< text::XTextAppend >( xAnnotationText, uno::UNO_QUERY_THROW ),
1618 8 : m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(xAnnotationText->getStart())));
1619 : }
1620 0 : catch( const uno::Exception& )
1621 : {
1622 : OSL_FAIL( "exception in PushAnnotation" );
1623 : }
1624 : }
1625 :
1626 :
1627 5 : void DomainMapper_Impl::PopFootOrEndnote()
1628 : {
1629 5 : RemoveLastParagraph();
1630 5 : if (!m_aTextAppendStack.empty())
1631 5 : m_aTextAppendStack.pop();
1632 5 : }
1633 :
1634 :
1635 4 : void DomainMapper_Impl::PopAnnotation()
1636 : {
1637 4 : RemoveLastParagraph();
1638 :
1639 4 : m_bIsInComments = false;
1640 4 : m_aTextAppendStack.pop();
1641 :
1642 : try
1643 : {
1644 : // See if the annotation will be a single position or a range.
1645 8 : if (!m_aAnnotationPosition.m_xStart.is() ||
1646 4 : !m_aAnnotationPosition.m_xEnd.is())
1647 : {
1648 0 : uno::Sequence< beans::PropertyValue > aEmptyProperties;
1649 : appendTextContent(uno::Reference<text::XTextContent>(
1650 0 : m_xAnnotationField, uno::UNO_QUERY_THROW), aEmptyProperties);
1651 : }
1652 : else
1653 : {
1654 : // Create a range that points to the annotation start/end.
1655 : uno::Reference<text::XText> const xText =
1656 4 : m_aAnnotationPosition.m_xStart->getText();
1657 : uno::Reference<text::XTextCursor> const xCursor =
1658 8 : xText->createTextCursorByRange(m_aAnnotationPosition.m_xStart);
1659 4 : xCursor->gotoRange(m_aAnnotationPosition.m_xEnd, true);
1660 : uno::Reference<text::XTextRange> const xTextRange(
1661 8 : xCursor, uno::UNO_QUERY_THROW);
1662 :
1663 : // Attach the annotation to the range.
1664 : uno::Reference<text::XTextAppend> const xTextAppend =
1665 8 : m_aTextAppendStack.top().xTextAppend;
1666 4 : xTextAppend->insertTextContent(xTextRange,
1667 : uno::Reference<text::XTextContent>(m_xAnnotationField,
1668 : uno::UNO_QUERY_THROW),
1669 8 : !xCursor->isCollapsed());
1670 : }
1671 : }
1672 0 : catch (uno::Exception const& e)
1673 : {
1674 : SAL_WARN("writerfilter",
1675 : "Cannot insert annotation field: exception: " << e.Message);
1676 : }
1677 :
1678 4 : m_aAnnotationPosition.m_xStart.clear();
1679 4 : m_aAnnotationPosition.m_xEnd.clear();
1680 4 : m_xAnnotationField.clear();
1681 :
1682 4 : }
1683 :
1684 25 : void DomainMapper_Impl::PushPendingShape( const uno::Reference< drawing::XShape > xShape )
1685 : {
1686 25 : m_aPendingShapes.push_back(xShape);
1687 25 : }
1688 :
1689 9 : uno::Reference<drawing::XShape> DomainMapper_Impl::PopPendingShape()
1690 : {
1691 9 : uno::Reference<drawing::XShape> xRet;
1692 9 : if (!m_aPendingShapes.empty())
1693 : {
1694 9 : xRet = m_aPendingShapes.front();
1695 9 : m_aPendingShapes.pop_front();
1696 : }
1697 9 : return xRet;
1698 : }
1699 :
1700 89 : void DomainMapper_Impl::PushShapeContext( const uno::Reference< drawing::XShape > xShape )
1701 : {
1702 89 : if (m_aTextAppendStack.empty())
1703 89 : return;
1704 89 : uno::Reference<text::XTextAppend> xTextAppend = m_aTextAppendStack.top().xTextAppend;
1705 :
1706 89 : appendTableManager( );
1707 89 : appendTableHandler( );
1708 89 : getTableManager().startLevel();
1709 : try
1710 : {
1711 89 : uno::Reference< lang::XServiceInfo > xSInfo( xShape, uno::UNO_QUERY_THROW );
1712 88 : if (xSInfo->supportsService("com.sun.star.drawing.GroupShape"))
1713 : {
1714 : // A GroupShape doesn't implement text::XTextRange, but appending
1715 : // an empty reference to the stacks still makes sense, because this
1716 : // way bToRemove can be set, and we won't end up with duplicated
1717 : // shapes for OLE objects.
1718 9 : m_aTextAppendStack.push(TextAppendContext(uno::Reference<text::XTextAppend>(xShape, uno::UNO_QUERY), uno::Reference<text::XTextCursor>()));
1719 9 : uno::Reference<text::XTextContent> xTxtContent(xShape, uno::UNO_QUERY);
1720 9 : m_aAnchoredStack.push(xTxtContent);
1721 : }
1722 : else
1723 : {
1724 79 : uno::Reference< text::XTextRange > xShapeText( xShape, uno::UNO_QUERY_THROW);
1725 : // Add the shape to the text append stack
1726 : m_aTextAppendStack.push( TextAppendContext(uno::Reference< text::XTextAppend >( xShape, uno::UNO_QUERY_THROW ),
1727 79 : m_bIsNewDoc ? uno::Reference<text::XTextCursor>() : m_xBodyText->createTextCursorByRange(xShapeText->getStart() )));
1728 :
1729 : // Add the shape to the anchored objects stack
1730 158 : uno::Reference< text::XTextContent > xTxtContent( xShape, uno::UNO_QUERY_THROW );
1731 79 : m_aAnchoredStack.push( xTxtContent );
1732 :
1733 79 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
1734 :
1735 158 : uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY_THROW );
1736 : #ifdef DEBUG_DOMAINMAPPER
1737 : dmapper_logger->unoPropertySet(xProps);
1738 : #endif
1739 79 : bool bIsGraphic = xSInfo->supportsService( "com.sun.star.drawing.GraphicObjectShape" );
1740 :
1741 : // If there are position properties, the shape should not be inserted "as character".
1742 79 : sal_Int32 nHoriPosition = 0, nVertPosition = 0;
1743 79 : xProps->getPropertyValue(rPropNameSupplier.GetName(PROP_HORI_ORIENT_POSITION)) >>= nHoriPosition;
1744 79 : xProps->getPropertyValue(rPropNameSupplier.GetName(PROP_VERT_ORIENT_POSITION)) >>= nVertPosition;
1745 79 : if (nHoriPosition != 0 || nVertPosition != 0)
1746 46 : bIsGraphic = false;
1747 79 : text::TextContentAnchorType nAnchorType(text::TextContentAnchorType_AT_PARAGRAPH);
1748 79 : xProps->getPropertyValue(rPropNameSupplier.GetName( PROP_ANCHOR_TYPE )) >>= nAnchorType;
1749 79 : if (nAnchorType == text::TextContentAnchorType_AT_PAGE)
1750 13 : bIsGraphic = false;
1751 :
1752 79 : if (!m_bInHeaderFooterImport)
1753 70 : xProps->setPropertyValue(
1754 70 : rPropNameSupplier.GetName( PROP_OPAQUE ),
1755 140 : uno::makeAny( true ) );
1756 79 : if (xSInfo->supportsService("com.sun.star.text.TextFrame"))
1757 : {
1758 48 : uno::Reference<text::XTextContent> xTextContent(xShape, uno::UNO_QUERY_THROW);
1759 96 : uno::Reference<text::XTextRange> xTextRange(xTextAppend->createTextCursorByRange(xTextAppend->getEnd()), uno::UNO_QUERY_THROW);
1760 96 : xTextAppend->insertTextContent(xTextRange, xTextContent, sal_False);
1761 : }
1762 31 : else if (nAnchorType != text::TextContentAnchorType_AS_CHARACTER)
1763 : {
1764 25 : xProps->setPropertyValue( rPropNameSupplier.GetName( PROP_ANCHOR_TYPE ), bIsGraphic ? uno::makeAny( text::TextContentAnchorType_AS_CHARACTER ) : uno::makeAny( text::TextContentAnchorType_AT_PARAGRAPH ) );
1765 79 : }
1766 88 : }
1767 : }
1768 1 : catch ( const uno::Exception& e )
1769 : {
1770 : SAL_WARN("writerfilter", "Exception when adding shape: " << e.Message);
1771 89 : }
1772 : }
1773 :
1774 :
1775 :
1776 89 : void DomainMapper_Impl::PopShapeContext()
1777 : {
1778 89 : getTableManager().endLevel();
1779 89 : popTableManager();
1780 89 : if ( m_aAnchoredStack.size() > 0 )
1781 : {
1782 : // For OLE object replacement shape, the text append context was already removed
1783 : // or the OLE object couldn't be inserted.
1784 88 : if ( !m_aAnchoredStack.top().bToRemove )
1785 : {
1786 83 : RemoveLastParagraph();
1787 83 : m_aTextAppendStack.pop();
1788 : }
1789 :
1790 88 : uno::Reference< text::XTextContent > xObj = m_aAnchoredStack.top( ).xTextContent;
1791 : try
1792 : {
1793 88 : appendTextContent( xObj, uno::Sequence< beans::PropertyValue >() );
1794 : }
1795 0 : catch ( const uno::RuntimeException& )
1796 : {
1797 : // this is normal: the shape is already attached
1798 : }
1799 :
1800 : // Remove the shape if required (most likely replacement shape for OLE object)
1801 88 : if ( m_aAnchoredStack.top().bToRemove )
1802 : {
1803 : try
1804 : {
1805 5 : uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(m_xTextDocument, uno::UNO_QUERY_THROW);
1806 10 : uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
1807 5 : if ( xDrawPage.is() )
1808 : {
1809 5 : uno::Reference<drawing::XShape> xShape( xObj, uno::UNO_QUERY_THROW );
1810 5 : xDrawPage->remove( xShape );
1811 5 : }
1812 : }
1813 0 : catch( const uno::Exception& )
1814 : {
1815 : }
1816 : }
1817 88 : m_aAnchoredStack.pop();
1818 : }
1819 89 : }
1820 :
1821 :
1822 7 : OUString lcl_FindQuotedText( const OUString& rCommand,
1823 : const sal_Char* cStartQuote, const sal_Unicode uEndQuote )
1824 : {
1825 7 : OUString sRet;
1826 14 : OUString sStartQuote( OUString::createFromAscii(cStartQuote) );
1827 7 : sal_Int32 nStartIndex = rCommand.indexOf( sStartQuote );
1828 7 : if( nStartIndex >= 0 )
1829 : {
1830 2 : sal_Int32 nStartLength = sStartQuote.getLength();
1831 2 : sal_Int32 nEndIndex = rCommand.indexOf( uEndQuote, nStartIndex + nStartLength);
1832 2 : if( nEndIndex > nStartIndex )
1833 : {
1834 2 : sRet = rCommand.copy( nStartIndex + nStartLength, nEndIndex - nStartIndex - nStartLength);
1835 : }
1836 : }
1837 14 : return sRet;
1838 :
1839 : }
1840 :
1841 :
1842 6 : sal_Int16 lcl_ParseNumberingType( const OUString& rCommand )
1843 : {
1844 6 : sal_Int16 nRet = style::NumberingType::PAGE_DESCRIPTOR;
1845 :
1846 : // The command looks like: " PAGE \* Arabic "
1847 6 : OUString sNumber = lcl_FindQuotedText(rCommand, "\\* ", ' ');
1848 :
1849 6 : if( !sNumber.isEmpty() )
1850 : {
1851 : //todo: might make sense to hash this list, too
1852 : struct NumberingPairs
1853 : {
1854 : const sal_Char* cWordName;
1855 : sal_Int16 nType;
1856 : };
1857 : static const NumberingPairs aNumberingPairs[] =
1858 : {
1859 : {"Arabic", style::NumberingType::ARABIC}
1860 : ,{"ROMAN", style::NumberingType::ROMAN_UPPER}
1861 : ,{"roman", style::NumberingType::ROMAN_LOWER}
1862 : ,{"ALPHABETIC", style::NumberingType::CHARS_UPPER_LETTER}
1863 : ,{"alphabetic", style::NumberingType::CHARS_LOWER_LETTER}
1864 : ,{"CircleNum", style::NumberingType::CIRCLE_NUMBER}
1865 : ,{"ThaiArabic", style::NumberingType::CHARS_THAI}
1866 : ,{"ThaiCardText", style::NumberingType::CHARS_THAI}
1867 : ,{"ThaiLetter", style::NumberingType::CHARS_THAI}
1868 : // ,{"SBCHAR", style::NumberingType::}
1869 : // ,{"DBCHAR", style::NumberingType::}
1870 : // ,{"DBNUM1", style::NumberingType::}
1871 : // ,{"DBNUM2", style::NumberingType::}
1872 : // ,{"DBNUM3", style::NumberingType::}
1873 : // ,{"DBNUM4", style::NumberingType::}
1874 : ,{"Aiueo", style::NumberingType::AIU_FULLWIDTH_JA}
1875 : ,{"Iroha", style::NumberingType::IROHA_FULLWIDTH_JA}
1876 : // ,{"ZODIAC1", style::NumberingType::}
1877 : // ,{"ZODIAC2", style::NumberingType::}
1878 : // ,{"ZODIAC3", style::NumberingType::}
1879 : // ,{"CHINESENUM1", style::NumberingType::}
1880 : // ,{"CHINESENUM2", style::NumberingType::}
1881 : // ,{"CHINESENUM3", style::NumberingType::}
1882 : ,{"ArabicAlpha", style::NumberingType::CHARS_ARABIC}
1883 : ,{"ArabicAbjad", style::NumberingType::FULLWIDTH_ARABIC}
1884 : /* possible values:
1885 : style::NumberingType::
1886 :
1887 : CHARS_UPPER_LETTER_N
1888 : CHARS_LOWER_LETTER_N
1889 : TRANSLITERATION
1890 : NATIVE_NUMBERING
1891 : CIRCLE_NUMBER
1892 : NUMBER_LOWER_ZH
1893 : NUMBER_UPPER_ZH
1894 : NUMBER_UPPER_ZH_TW
1895 : TIAN_GAN_ZH
1896 : DI_ZI_ZH
1897 : NUMBER_TRADITIONAL_JA
1898 : AIU_HALFWIDTH_JA
1899 : IROHA_HALFWIDTH_JA
1900 : NUMBER_UPPER_KO
1901 : NUMBER_HANGUL_KO
1902 : HANGUL_JAMO_KO
1903 : HANGUL_SYLLABLE_KO
1904 : HANGUL_CIRCLED_JAMO_KO
1905 : HANGUL_CIRCLED_SYLLABLE_KO
1906 : CHARS_HEBREW
1907 : CHARS_NEPALI
1908 : CHARS_KHMER
1909 : CHARS_LAO
1910 : CHARS_TIBETAN
1911 : CHARS_CYRILLIC_UPPER_LETTER_BG
1912 : CHARS_CYRILLIC_LOWER_LETTER_BG
1913 : CHARS_CYRILLIC_UPPER_LETTER_N_BG
1914 : CHARS_CYRILLIC_LOWER_LETTER_N_BG
1915 : CHARS_CYRILLIC_UPPER_LETTER_RU
1916 : CHARS_CYRILLIC_LOWER_LETTER_RU
1917 : CHARS_CYRILLIC_UPPER_LETTER_N_RU
1918 : CHARS_CYRILLIC_LOWER_LETTER_N_RU
1919 : CHARS_CYRILLIC_UPPER_LETTER_SR
1920 : CHARS_CYRILLIC_LOWER_LETTER_SR
1921 : CHARS_CYRILLIC_UPPER_LETTER_N_SR
1922 : CHARS_CYRILLIC_LOWER_LETTER_N_SR*/
1923 :
1924 : };
1925 14 : for( sal_uInt32 nNum = 0; nNum < sizeof(aNumberingPairs)/sizeof( NumberingPairs ); ++nNum)
1926 : {
1927 13 : if( /*sCommand*/sNumber.equalsAscii(aNumberingPairs[nNum].cWordName ))
1928 : {
1929 0 : nRet = aNumberingPairs[nNum].nType;
1930 0 : break;
1931 : }
1932 : }
1933 :
1934 : }
1935 6 : return nRet;
1936 : }
1937 :
1938 :
1939 1 : OUString lcl_ParseFormat( const OUString& rCommand )
1940 : {
1941 : // The command looks like: " DATE \@ "dd MMMM yyyy"
1942 1 : return lcl_FindQuotedText(rCommand, "\\@ \"", '\"');
1943 : }
1944 : /*-------------------------------------------------------------------------
1945 : extract a parameter (with or without quotes) between the command and the following backslash
1946 : -----------------------------------------------------------------------*/
1947 1 : OUString lcl_ExtractParameter(const OUString& rCommand, sal_Int32 nCommandLength )
1948 : {
1949 1 : sal_Int32 nStartIndex = nCommandLength;
1950 1 : sal_Int32 nEndIndex = 0;
1951 1 : sal_Int32 nQuoteIndex = rCommand.indexOf( '\"', nStartIndex);
1952 1 : if( nQuoteIndex >= 0)
1953 : {
1954 0 : nStartIndex = nQuoteIndex + 1;
1955 0 : nEndIndex = rCommand.indexOf( '\"', nStartIndex + 1) - 1;
1956 : }
1957 : else
1958 : {
1959 1 : nEndIndex = rCommand.indexOf(" \\", nStartIndex);
1960 : }
1961 1 : OUString sRet;
1962 1 : if( nEndIndex > nStartIndex + 1 )
1963 : {
1964 : //remove spaces at start and end of the result
1965 1 : if(nQuoteIndex <= 0)
1966 : {
1967 1 : const sal_Unicode* pCommandStr = rCommand.getStr();
1968 2 : while( nStartIndex < nEndIndex && pCommandStr[nStartIndex] == ' ')
1969 0 : ++nStartIndex;
1970 4 : while( nEndIndex > nStartIndex && pCommandStr[nEndIndex] == ' ')
1971 2 : --nEndIndex;
1972 : }
1973 1 : sRet = rCommand.copy( nStartIndex, nEndIndex - nStartIndex + 1);
1974 : }
1975 1 : return sRet;
1976 : }
1977 :
1978 :
1979 :
1980 1 : OUString lcl_ExctractAskVariableAndHint( const OUString& rCommand, OUString& rHint )
1981 : {
1982 : // the first word after "ASK " is the variable
1983 : // the text after the variable and before a '\' is the hint
1984 : // if no hint is set the variable is used as hint
1985 : // the quotes of the hint have to be removed
1986 1 : sal_Int32 nIndex = rCommand.indexOf( ' ', 2);//find last space after 'ASK'
1987 3 : while(rCommand.getStr()[nIndex] == ' ')
1988 1 : ++nIndex;
1989 1 : OUString sShortCommand( rCommand.copy( nIndex ) ); //cut off the " ASK "
1990 :
1991 1 : nIndex = 0;
1992 1 : sShortCommand = sShortCommand.getToken( 0, '\\', nIndex);
1993 1 : nIndex = 0;
1994 1 : OUString sRet = sShortCommand.getToken( 0, ' ', nIndex);
1995 1 : if( nIndex > 0)
1996 1 : rHint = sShortCommand.copy( nIndex );
1997 1 : if( rHint.isEmpty() )
1998 0 : rHint = sRet;
1999 1 : return sRet;
2000 : }
2001 :
2002 :
2003 0 : bool lcl_FindInCommand(
2004 : const OUString& rCommand,
2005 : sal_Unicode cSwitch,
2006 : OUString& rValue )
2007 : {
2008 0 : bool bRet = false;
2009 0 : OUString sSearch('\\');
2010 0 : sSearch += OUString( cSwitch );
2011 0 : sal_Int32 nIndex = rCommand.indexOf( sSearch );
2012 0 : if( nIndex >= 0 )
2013 : {
2014 0 : bRet = true;
2015 : //find next '\' or end of string
2016 0 : sal_Int32 nEndIndex = rCommand.indexOf( '\\', nIndex + 1);
2017 0 : if( nEndIndex < 0 )
2018 0 : nEndIndex = rCommand.getLength() - 1;
2019 0 : if( nEndIndex - nIndex > 3 )
2020 0 : rValue = rCommand.copy( nIndex + 3, nEndIndex - nIndex - 3);
2021 : }
2022 0 : return bRet;
2023 : }
2024 :
2025 :
2026 1 : void DomainMapper_Impl::GetCurrentLocale(lang::Locale& rLocale)
2027 : {
2028 1 : PropertyMapPtr pTopContext = GetTopContext();
2029 1 : PropertyDefinition aCharLocale( PROP_CHAR_LOCALE );
2030 1 : PropertyMap::iterator aLocaleIter = pTopContext->find( aCharLocale );
2031 1 : if( aLocaleIter != pTopContext->end())
2032 0 : aLocaleIter->second >>= rLocale;
2033 : else
2034 : {
2035 1 : PropertyMapPtr pParaContext = GetTopContextOfType(CONTEXT_PARAGRAPH);
2036 1 : aLocaleIter = pParaContext->find(aCharLocale);
2037 1 : if( aLocaleIter != pParaContext->end())
2038 : {
2039 1 : aLocaleIter->second >>= rLocale;
2040 1 : }
2041 1 : }
2042 1 : }
2043 :
2044 : /*-------------------------------------------------------------------------
2045 : extract the number format from the command and apply the resulting number
2046 : format to the XPropertySet
2047 : -----------------------------------------------------------------------*/
2048 1 : void DomainMapper_Impl::SetNumberFormat( const OUString& rCommand,
2049 : uno::Reference< beans::XPropertySet >& xPropertySet )
2050 : {
2051 1 : OUString sFormatString = lcl_ParseFormat( rCommand );
2052 : // find \h - hijri/luna calendar todo: what about saka/era calendar?
2053 1 : bool bHijri = 0 < rCommand.indexOf("\\h ");
2054 2 : lang::Locale aUSLocale;
2055 1 : aUSLocale.Language = "en";
2056 1 : aUSLocale.Country = "US";
2057 :
2058 : //determine current locale - todo: is it necessary to initialize this locale?
2059 2 : lang::Locale aCurrentLocale = aUSLocale;
2060 1 : GetCurrentLocale( aCurrentLocale );
2061 2 : OUString sFormat = ConversionHelper::ConvertMSFormatStringToSO( sFormatString, aCurrentLocale, bHijri);
2062 : //get the number formatter and convert the string to a format value
2063 : try
2064 : {
2065 1 : uno::Reference< util::XNumberFormatsSupplier > xNumberSupplier( m_xTextDocument, uno::UNO_QUERY_THROW );
2066 1 : sal_Int32 nKey = xNumberSupplier->getNumberFormats()->addNewConverted( sFormat, aUSLocale, aCurrentLocale );
2067 1 : xPropertySet->setPropertyValue(
2068 1 : PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_NUMBER_FORMAT),
2069 2 : uno::makeAny( nKey ));
2070 1 : xPropertySet->getPropertyValue(
2071 1 : PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_NUMBER_FORMAT ) ) >>= nKey;
2072 : }
2073 0 : catch(const uno::Exception&)
2074 : {
2075 1 : }
2076 1 : }
2077 :
2078 :
2079 :
2080 1 : uno::Reference< beans::XPropertySet > DomainMapper_Impl::FindOrCreateFieldMaster(
2081 : const sal_Char* pFieldMasterService, const OUString& rFieldMasterName )
2082 : throw(::com::sun::star::uno::Exception)
2083 : {
2084 : // query master, create if not available
2085 1 : uno::Reference< text::XTextFieldsSupplier > xFieldsSupplier( GetTextDocument(), uno::UNO_QUERY_THROW );
2086 2 : uno::Reference< container::XNameAccess > xFieldMasterAccess = xFieldsSupplier->getTextFieldMasters();
2087 1 : uno::Reference< beans::XPropertySet > xMaster;
2088 2 : OUString sFieldMasterService( OUString::createFromAscii(pFieldMasterService) );
2089 2 : OUStringBuffer aFieldMasterName;
2090 1 : aFieldMasterName.appendAscii( pFieldMasterService );
2091 1 : aFieldMasterName.append(sal_Unicode('.'));
2092 1 : aFieldMasterName.append(rFieldMasterName);
2093 2 : OUString sFieldMasterName = aFieldMasterName.makeStringAndClear();
2094 1 : if(xFieldMasterAccess->hasByName(sFieldMasterName))
2095 : {
2096 : //get the master
2097 0 : xMaster = uno::Reference< beans::XPropertySet >(xFieldMasterAccess->getByName(sFieldMasterName),
2098 0 : uno::UNO_QUERY_THROW);
2099 : }
2100 : else
2101 : {
2102 : //create the master
2103 2 : xMaster = uno::Reference< beans::XPropertySet >(
2104 2 : m_xTextFactory->createInstance(sFieldMasterService), uno::UNO_QUERY_THROW);
2105 : //set the master's name
2106 1 : xMaster->setPropertyValue(
2107 1 : PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_NAME),
2108 2 : uno::makeAny(rFieldMasterName));
2109 : }
2110 2 : return xMaster;
2111 : }
2112 :
2113 : /*-------------------------------------------------------------------------
2114 : //field context starts with a 0x13
2115 : -----------------------------------------------------------------------*/
2116 27 : void DomainMapper_Impl::PushFieldContext()
2117 : {
2118 : #ifdef DEBUG_DOMAINMAPPER
2119 : dmapper_logger->element("pushFieldContext");
2120 : #endif
2121 :
2122 27 : uno::Reference< text::XTextAppend > xTextAppend;
2123 27 : if (!m_aTextAppendStack.empty())
2124 27 : xTextAppend = m_aTextAppendStack.top().xTextAppend;
2125 54 : uno::Reference< text::XTextRange > xStart;
2126 27 : if (xTextAppend.is())
2127 : {
2128 27 : uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange( xTextAppend->getEnd() );
2129 27 : xStart = xCrsr->getStart();
2130 : }
2131 54 : m_aFieldStack.push( FieldContextPtr( new FieldContext( xStart ) ) );
2132 27 : }
2133 : /*-------------------------------------------------------------------------
2134 : //the current field context waits for the completion of the command
2135 : -----------------------------------------------------------------------*/
2136 4921 : bool DomainMapper_Impl::IsOpenFieldCommand() const
2137 : {
2138 4921 : return !m_aFieldStack.empty() && !m_aFieldStack.top()->IsCommandCompleted();
2139 : }
2140 : /*-------------------------------------------------------------------------
2141 : //the current field context waits for the completion of the command
2142 : -----------------------------------------------------------------------*/
2143 4861 : bool DomainMapper_Impl::IsOpenField() const
2144 : {
2145 4861 : return !m_aFieldStack.empty();
2146 : }
2147 :
2148 :
2149 27 : FieldContext::FieldContext(uno::Reference< text::XTextRange > xStart) :
2150 : m_bFieldCommandCompleted( false )
2151 27 : ,m_xStartRange( xStart )
2152 : {
2153 27 : }
2154 :
2155 :
2156 27 : FieldContext::~FieldContext()
2157 : {
2158 27 : }
2159 :
2160 :
2161 60 : void FieldContext::AppendCommand(const OUString& rPart)
2162 : {
2163 60 : m_sCommand += rPart;
2164 60 : }
2165 :
2166 8 : ::std::vector<OUString> FieldContext::GetCommandParts() const
2167 : {
2168 8 : ::std::vector<OUString> aResult;
2169 8 : sal_Int32 nIndex = 0;
2170 8 : bool bInString = false;
2171 16 : OUString sPart;
2172 47 : while (nIndex != -1)
2173 : {
2174 31 : OUString sToken = GetCommand().getToken(0, ' ', nIndex);
2175 31 : bool bInStringNext = bInString;
2176 :
2177 31 : if (sToken.isEmpty())
2178 9 : continue;
2179 :
2180 22 : if (sToken.getStr()[0] == '"')
2181 : {
2182 11 : bInStringNext = true;
2183 11 : sToken = sToken.copy(1);
2184 : }
2185 22 : if (sToken.getStr()[sToken.getLength() - 1] == '"')
2186 : {
2187 11 : bInStringNext = false;
2188 11 : sToken = sToken.copy(0, sToken.getLength() - 1);
2189 : }
2190 :
2191 22 : if (bInString)
2192 : {
2193 0 : if (bInStringNext)
2194 : {
2195 0 : sPart += OUString(' ');
2196 0 : sPart += sToken;
2197 : }
2198 : else
2199 : {
2200 0 : sPart += sToken;
2201 0 : aResult.push_back(sPart);
2202 : }
2203 : }
2204 : else
2205 : {
2206 22 : if (bInStringNext)
2207 : {
2208 0 : sPart = sToken;
2209 : }
2210 : else
2211 : {
2212 22 : aResult.push_back(sToken);
2213 : }
2214 : }
2215 :
2216 22 : bInString = bInStringNext;
2217 22 : }
2218 :
2219 16 : return aResult;
2220 : }
2221 :
2222 : /*-------------------------------------------------------------------------
2223 : //collect the pieces of the command
2224 : -----------------------------------------------------------------------*/
2225 60 : void DomainMapper_Impl::AppendFieldCommand(OUString& rPartOfCommand)
2226 : {
2227 : #ifdef DEBUG_DOMAINMAPPER
2228 : dmapper_logger->startElement("appendFieldCommand");
2229 : dmapper_logger->chars(rPartOfCommand);
2230 : dmapper_logger->endElement();
2231 : #endif
2232 :
2233 60 : FieldContextPtr pContext = m_aFieldStack.top();
2234 : OSL_ENSURE( pContext.get(), "no field context available");
2235 60 : if( pContext.get() )
2236 : {
2237 60 : pContext->AppendCommand( rPartOfCommand );
2238 60 : }
2239 60 : }
2240 :
2241 :
2242 : typedef std::multimap < sal_Int32, OUString > TOCStyleMap;
2243 :
2244 27 : const FieldConversionMap_t & lcl_GetFieldConversion()
2245 : {
2246 27 : static FieldConversionMap_t aFieldConversionMap;
2247 27 : static FieldConversionMap_t aEnhancedFieldConversionMap;
2248 :
2249 : static bool bFilled = false;
2250 :
2251 27 : if(!bFilled)
2252 : {
2253 : static const FieldConversion aFields[] =
2254 : {
2255 : // {OUString("ADDRESSBLOCK"), "", "", FIELD_ADDRESSBLOCK },
2256 : // {OUString("ADVANCE"), "", "", FIELD_ADVANCE },
2257 : {OUString("ASK"), "SetExpression", "SetExpression", FIELD_ASK },
2258 : {OUString("AUTONUM"), "SetExpression", "SetExpression", FIELD_AUTONUM },
2259 : {OUString("AUTONUMLGL"), "SetExpression", "SetExpression", FIELD_AUTONUMLGL },
2260 : {OUString("AUTONUMOUT"), "SetExpression", "SetExpression", FIELD_AUTONUMOUT },
2261 : {OUString("AUTHOR"), "DocInfo.CreateAuthor", "", FIELD_AUTHOR },
2262 : {OUString("DATE"), "DateTime", "", FIELD_DATE },
2263 : {OUString("COMMENTS"), "DocInfo.Description", "", FIELD_COMMENTS },
2264 : {OUString("CREATEDATE"), "DocInfo.CreateDateTime", "", FIELD_CREATEDATE },
2265 : {OUString("DOCPROPERTY"), "", "", FIELD_DOCPROPERTY },
2266 : {OUString("DOCVARIABLE"), "User", "", FIELD_DOCVARIABLE },
2267 : {OUString("EDITTIME"), "DocInfo.EditTime", "", FIELD_EDITTIME },
2268 : {OUString("EQ"), "", "", FIELD_EQ },
2269 : {OUString("FILLIN"), "Input", "", FIELD_FILLIN },
2270 : {OUString("FILENAME"), "FileName", "", FIELD_FILENAME },
2271 : // {OUString("FILESIZE"), "", "", FIELD_FILESIZE },
2272 : // {OUString("FORMULA"), "", "", FIELD_FORMULA },
2273 : {OUString("FORMCHECKBOX"), "", "", FIELD_FORMCHECKBOX},
2274 : {OUString("FORMDROPDOWN"), "DropDown", "", FIELD_FORMDROPDOWN},
2275 : {OUString("FORMTEXT"), "Input", "", FIELD_FORMTEXT},
2276 : // {OUString("GOTOBUTTON"), "", "", FIELD_GOTOBUTTON },
2277 : {OUString("HYPERLINK"), "", "", FIELD_HYPERLINK },
2278 : {OUString("IF"), "ConditionalText", "", FIELD_IF },
2279 : // {OUString("INFO"), "","", FIELD_INFO },
2280 : // {OUString("INCLUDEPICTURE"), "", "", FIELD_INCLUDEPICTURE},
2281 : {OUString("KEYWORDS"), "DocInfo.KeyWords", "", FIELD_KEYWORDS },
2282 : {OUString("LASTSAVEDBY"), "DocInfo.ChangeAuthor", "", FIELD_LASTSAVEDBY },
2283 : {OUString("MACROBUTTON"), "Macro", "", FIELD_MACROBUTTON },
2284 : {OUString("MERGEFIELD"), "Database", "Database", FIELD_MERGEFIELD},
2285 : {OUString("MERGEREC"), "DatabaseNumberOfSet", "", FIELD_MERGEREC },
2286 : // {OUString("MERGESEQ"), "", "", FIELD_MERGESEQ },
2287 : {OUString("NEXT"), "DatabaseNextSet", "", FIELD_NEXT },
2288 : {OUString("NEXTIF"), "DatabaseNextSet", "", FIELD_NEXTIF },
2289 : {OUString("PAGE"), "PageNumber", "", FIELD_PAGE },
2290 : {OUString("PAGEREF"), "GetReference", "", FIELD_PAGEREF },
2291 : {OUString("REF"), "GetReference", "", FIELD_REF },
2292 : {OUString("REVNUM"), "DocInfo.Revision", "", FIELD_REVNUM },
2293 : {OUString("SAVEDATE"), "DocInfo.Change", "", FIELD_SAVEDATE },
2294 : // {OUString("SECTION"), "", "", FIELD_SECTION },
2295 : // {OUString("SECTIONPAGES"), "", "", FIELD_SECTIONPAGES },
2296 : {OUString("SEQ"), "SetExpression", "SetExpression", FIELD_SEQ },
2297 : // {OUString("SET"), "","", FIELD_SET },
2298 : // {OUString("SKIPIF"),"", "", FIELD_SKIPIF },
2299 : // {OUString("STYLEREF"),"", "", FIELD_STYLEREF },
2300 : {OUString("SUBJECT"), "DocInfo.Subject", "", FIELD_SUBJECT },
2301 : // {OUString("SYMBOL"),"", "", FIELD_SYMBOL },
2302 : {OUString("TEMPLATE"), "TemplateName", "", FIELD_TEMPLATE},
2303 : {OUString("TIME"), "DateTime", "", FIELD_TIME },
2304 : {OUString("TITLE"), "DocInfo.Title", "", FIELD_TITLE },
2305 : {OUString("USERINITIALS"), "Author", "", FIELD_USERINITIALS },
2306 : // {OUString("USERADDRESS"), "", "", FIELD_USERADDRESS },
2307 : {OUString("USERNAME"), "Author", "", FIELD_USERNAME },
2308 :
2309 :
2310 : {OUString("TOC"), "com.sun.star.text.ContentIndex", "", FIELD_TOC},
2311 : {OUString("TC"), "com.sun.star.text.ContentIndexMark", "", FIELD_TC},
2312 : {OUString("NUMCHARS"), "CharacterCount", "", FIELD_NUMCHARS},
2313 : {OUString("NUMWORDS"), "WordCount", "", FIELD_NUMWORDS},
2314 : {OUString("NUMPAGES"), "PageCount", "", FIELD_NUMPAGES},
2315 :
2316 : // {OUString(""), "", "", FIELD_},
2317 :
2318 8 : };
2319 4 : size_t nConversions = SAL_N_ELEMENTS(aFields);
2320 176 : for( size_t nConversion = 0; nConversion < nConversions; ++nConversion)
2321 : {
2322 : aFieldConversionMap.insert( FieldConversionMap_t::value_type(
2323 : aFields[nConversion].sWordCommand,
2324 172 : aFields[nConversion] ));
2325 : }
2326 :
2327 4 : bFilled = true;
2328 : }
2329 :
2330 27 : return aFieldConversionMap;
2331 : }
2332 :
2333 5 : const FieldConversionMap_t & lcl_GetEnhancedFieldConversion()
2334 : {
2335 5 : static FieldConversionMap_t aEnhancedFieldConversionMap;
2336 :
2337 : static bool bFilled = false;
2338 :
2339 5 : if(!bFilled)
2340 : {
2341 : static const FieldConversion aEnhancedFields[] =
2342 : {
2343 : {OUString("FORMCHECKBOX"), "FormFieldmark", "", FIELD_FORMCHECKBOX},
2344 : {OUString("FORMDROPDOWN"), "FormFieldmark", "", FIELD_FORMDROPDOWN},
2345 : {OUString("FORMTEXT"), "Fieldmark", "", FIELD_FORMTEXT},
2346 6 : };
2347 :
2348 5 : size_t nConversions = SAL_N_ELEMENTS(aEnhancedFields);
2349 20 : for( size_t nConversion = 0; nConversion < nConversions; ++nConversion)
2350 : {
2351 : aEnhancedFieldConversionMap.insert( FieldConversionMap_t::value_type(
2352 : aEnhancedFields[nConversion].sWordCommand,
2353 15 : aEnhancedFields[nConversion] ));
2354 : }
2355 : }
2356 5 : return aEnhancedFieldConversionMap;
2357 : }
2358 :
2359 1 : void DomainMapper_Impl::handleFieldAsk
2360 : (FieldContextPtr pContext,
2361 : PropertyNameSupplier& rPropNameSupplier,
2362 : uno::Reference< uno::XInterface > & xFieldInterface,
2363 : uno::Reference< beans::XPropertySet > xFieldProperties)
2364 : {
2365 : //doesn the command contain a variable name?
2366 2 : OUString sVariable, sHint;
2367 :
2368 2 : sVariable = lcl_ExctractAskVariableAndHint( pContext->GetCommand(),
2369 1 : sHint );
2370 1 : if(!sVariable.isEmpty())
2371 : {
2372 : // determine field master name
2373 : uno::Reference< beans::XPropertySet > xMaster =
2374 : FindOrCreateFieldMaster
2375 1 : ("com.sun.star.text.FieldMaster.SetExpression", sVariable );
2376 : // An ASK field is always a string of characters
2377 1 : xMaster->setPropertyValue(rPropNameSupplier.GetName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING));
2378 :
2379 : // attach the master to the field
2380 : uno::Reference< text::XDependentTextField > xDependentField
2381 2 : ( xFieldInterface, uno::UNO_QUERY_THROW );
2382 1 : xDependentField->attachTextFieldMaster( xMaster );
2383 :
2384 : // set input flag at the field
2385 1 : xFieldProperties->setPropertyValue(
2386 1 : rPropNameSupplier.GetName(PROP_IS_INPUT), uno::makeAny( true ));
2387 : // set the prompt
2388 1 : xFieldProperties->setPropertyValue(
2389 1 : rPropNameSupplier.GetName(PROP_HINT),
2390 2 : uno::makeAny( sHint ));
2391 1 : xFieldProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING));
2392 : // The ASK has no field value to display
2393 2 : xFieldProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_IS_VISIBLE), uno::makeAny(sal_False));
2394 : }
2395 : else
2396 : {
2397 : //don't insert the field
2398 : //todo: maybe import a 'normal' input field here?
2399 0 : xFieldInterface = 0;
2400 1 : }
2401 1 : }
2402 :
2403 0 : void DomainMapper_Impl::handleAutoNum
2404 : (FieldContextPtr pContext,
2405 : PropertyNameSupplier& rPropNameSupplier,
2406 : uno::Reference< uno::XInterface > & xFieldInterface,
2407 : uno::Reference< beans::XPropertySet > xFieldProperties)
2408 : {
2409 : //create a sequence field master "AutoNr"
2410 : uno::Reference< beans::XPropertySet > xMaster =
2411 : FindOrCreateFieldMaster
2412 : ("com.sun.star.text.FieldMaster.SetExpression",
2413 0 : "AutoNr");
2414 :
2415 0 : xMaster->setPropertyValue( rPropNameSupplier.GetName(PROP_SUB_TYPE),
2416 0 : uno::makeAny(text::SetVariableType::SEQUENCE));
2417 :
2418 : //apply the numbering type
2419 0 : xFieldProperties->setPropertyValue(
2420 0 : rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
2421 0 : uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) ));
2422 : // attach the master to the field
2423 : uno::Reference< text::XDependentTextField > xDependentField
2424 0 : ( xFieldInterface, uno::UNO_QUERY_THROW );
2425 0 : xDependentField->attachTextFieldMaster( xMaster );
2426 0 : }
2427 :
2428 0 : void DomainMapper_Impl::handleAuthor
2429 : (FieldContextPtr pContext,
2430 : PropertyNameSupplier& rPropNameSupplier,
2431 : uno::Reference< uno::XInterface > & /*xFieldInterface*/,
2432 : uno::Reference< beans::XPropertySet > xFieldProperties,
2433 : FieldId eFieldId )
2434 : {
2435 0 : if ( eFieldId != FIELD_USERINITIALS )
2436 0 : xFieldProperties->setPropertyValue
2437 0 : ( rPropNameSupplier.GetName(PROP_FULL_NAME), uno::makeAny( true ));
2438 :
2439 0 : sal_Int32 nLen = sizeof( " AUTHOR" );
2440 0 : if ( eFieldId != FIELD_AUTHOR )
2441 : {
2442 0 : if ( eFieldId == FIELD_USERINITIALS )
2443 0 : nLen = sizeof( " USERINITIALS" );
2444 0 : else if ( eFieldId == FIELD_USERNAME )
2445 0 : nLen = sizeof( " USERNAME" );
2446 : }
2447 :
2448 : OUString sParam =
2449 0 : lcl_ExtractParameter(pContext->GetCommand(), nLen );
2450 :
2451 0 : if(!sParam.isEmpty())
2452 : {
2453 0 : xFieldProperties->setPropertyValue(
2454 0 : rPropNameSupplier.GetName( PROP_IS_FIXED ),
2455 0 : uno::makeAny( true ));
2456 : //PROP_CURRENT_PRESENTATION is set later anyway
2457 0 : }
2458 0 : }
2459 :
2460 0 : void DomainMapper_Impl::handleDocProperty
2461 : (FieldContextPtr pContext,
2462 : PropertyNameSupplier& rPropNameSupplier,
2463 : uno::Reference< uno::XInterface > & xFieldInterface,
2464 : uno::Reference< beans::XPropertySet > xFieldProperties)
2465 : {
2466 : //some docproperties should be imported as document statistic fields, some as DocInfo fields
2467 : //others should be user fields
2468 : OUString sParam =
2469 0 : lcl_ExtractParameter(pContext->GetCommand(), sizeof(" DOCPROPERTY") );
2470 :
2471 0 : if(!sParam.isEmpty())
2472 : {
2473 : #define SET_ARABIC 0x01
2474 : #define SET_FULL_NAME 0x02
2475 : #define SET_DATE 0x04
2476 : struct DocPropertyMap
2477 : {
2478 : const sal_Char* pDocPropertyName;
2479 : const sal_Char* pServiceName;
2480 : sal_uInt8 nFlags;
2481 : };
2482 : static const DocPropertyMap aDocProperties[] =
2483 : {
2484 : {"CreateTime", "DocInfo.CreateDateTime", SET_DATE},
2485 : {"Characters", "CharacterCount", SET_ARABIC},
2486 : {"Comments", "DocInfo.Description", 0},
2487 : {"Keywords", "DocInfo.KeyWords", 0},
2488 : {"LastPrinted", "DocInfo.PrintDateTime", 0},
2489 : {"LastSavedBy", "DocInfo.ChangeAuthor", 0},
2490 : {"LastSavedTime", "DocInfo.ChangeDateTime", SET_DATE},
2491 : {"Paragraphs", "ParagraphCount", SET_ARABIC},
2492 : {"RevisionNumber", "DocInfo.Revision", 0},
2493 : {"Subject", "DocInfo.Subject", 0},
2494 : {"Template", "TemplateName", 0},
2495 : {"Title", "DocInfo.Title", 0},
2496 : {"TotalEditingTime", "DocInfo.EditTime", 0},
2497 : {"Words", "WordCount", SET_ARABIC}
2498 :
2499 : //other available DocProperties:
2500 : //Bytes, Category, CharactersWithSpaces, Company
2501 : //HyperlinkBase,
2502 : //Lines, Manager, NameofApplication, ODMADocId, Pages,
2503 : //Security,
2504 : };
2505 : //search for a field mapping
2506 0 : OUString sFieldServiceName;
2507 0 : sal_uInt16 nMap = 0;
2508 0 : for( ; nMap < sizeof(aDocProperties) / sizeof(DocPropertyMap);
2509 : ++nMap )
2510 : {
2511 0 : if(sParam.equalsAscii(aDocProperties[nMap].pDocPropertyName))
2512 : {
2513 0 : sFieldServiceName =
2514 : OUString::createFromAscii
2515 0 : (aDocProperties[nMap].pServiceName);
2516 0 : break;
2517 : }
2518 : }
2519 0 : OUString sServiceName("com.sun.star.text.TextField.");
2520 0 : bool bIsCustomField = false;
2521 0 : if(sFieldServiceName.isEmpty())
2522 : {
2523 : //create a custom property field
2524 0 : sServiceName += "DocInfo.Custom";
2525 0 : bIsCustomField = true;
2526 : }
2527 : else
2528 : {
2529 0 : sServiceName += sFieldServiceName;
2530 : }
2531 0 : if (m_xTextFactory.is())
2532 0 : xFieldInterface = m_xTextFactory->createInstance(sServiceName);
2533 0 : xFieldProperties =
2534 : uno::Reference< beans::XPropertySet >( xFieldInterface,
2535 0 : uno::UNO_QUERY_THROW);
2536 0 : if( bIsCustomField )
2537 0 : xFieldProperties->setPropertyValue(
2538 0 : rPropNameSupplier.GetName(PROP_NAME), uno::makeAny( sParam ));
2539 : else
2540 : {
2541 0 : if(0 != (aDocProperties[nMap].nFlags & SET_ARABIC))
2542 0 : xFieldProperties->setPropertyValue(
2543 0 : rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
2544 0 : uno::makeAny( style::NumberingType::ARABIC ));
2545 0 : else if(0 != (aDocProperties[nMap].nFlags & SET_FULL_NAME))
2546 0 : xFieldProperties->setPropertyValue(
2547 0 : rPropNameSupplier.GetName(PROP_FULL_NAME),
2548 0 : uno::makeAny( true ));
2549 0 : else if(0 != (aDocProperties[nMap].nFlags & SET_DATE))
2550 : {
2551 0 : xFieldProperties->setPropertyValue(
2552 0 : rPropNameSupplier.GetName(PROP_IS_DATE),
2553 0 : uno::makeAny( true ));
2554 0 : SetNumberFormat( pContext->GetCommand(), xFieldProperties );
2555 : }
2556 0 : }
2557 0 : }
2558 :
2559 : #undef SET_ARABIC
2560 : #undef SET_FULL_NAME
2561 : #undef SET_DATE
2562 0 : }
2563 :
2564 0 : void DomainMapper_Impl::handleToc
2565 : (FieldContextPtr pContext,
2566 : PropertyNameSupplier& rPropNameSupplier,
2567 : uno::Reference< uno::XInterface > & /*xFieldInterface*/,
2568 : uno::Reference< beans::XPropertySet > /*xFieldProperties*/,
2569 : const OUString & sTOCServiceName)
2570 : {
2571 0 : OUString sValue;
2572 0 : bool bTableOfFigures = false;
2573 0 : bool bHyperlinks = false;
2574 0 : bool bFromOutline = false;
2575 0 : bool bFromEntries = false;
2576 0 : sal_Int16 nMaxLevel = 10;
2577 0 : OUString sTemplate;
2578 0 : OUString sChapterNoSeparator;
2579 0 : OUString sFigureSequence;
2580 :
2581 : // \a Builds a table of figures but does not include the captions's label and number
2582 0 : if( lcl_FindInCommand( pContext->GetCommand(), 'a', sValue ))
2583 : { //make it a table of figures
2584 0 : bTableOfFigures = true;
2585 : }
2586 : // \b Uses a bookmark to specify area of document from which to build table of contents
2587 : // if( lcl_FindInCommand( pContext->GetCommand(), 'b', sValue ))
2588 : // { //todo: sValue contains the bookmark name - unsupported feature
2589 : // }
2590 0 : if( lcl_FindInCommand( pContext->GetCommand(), 'c', sValue ))
2591 : // \c Builds a table of figures of the given label
2592 : {
2593 : //todo: sValue contains the label's name
2594 0 : bTableOfFigures = true;
2595 0 : sFigureSequence = sValue.trim();
2596 0 : sFigureSequence = sFigureSequence.replaceAll("\"", "").replaceAll("'","");
2597 : }
2598 : // \d Defines the separator between sequence and page numbers
2599 0 : if( lcl_FindInCommand( pContext->GetCommand(), 'd', sValue ))
2600 : {
2601 : //todo: insert the chapter number into each level and insert the separator additionally
2602 0 : sChapterNoSeparator = sValue;
2603 : }
2604 : // \f Builds a table of contents using TC entries instead of outline levels
2605 0 : if( lcl_FindInCommand( pContext->GetCommand(), 'f', sValue ))
2606 : {
2607 : //todo: sValue can contain a TOC entry identifier - use unclear
2608 0 : bFromEntries = true;
2609 : }
2610 : // \h Hyperlinks the entries and page numbers within the table of contents
2611 0 : if( lcl_FindInCommand( pContext->GetCommand(), 'h', sValue ))
2612 : {
2613 : //todo: make all entries to hyperlinks
2614 0 : bHyperlinks = true;
2615 : }
2616 : // \l Defines the TC entries field level used to build a table of contents
2617 : // if( lcl_FindInCommand( pContext->GetCommand(), 'l', sValue ))
2618 : // {
2619 : //todo: entries can only be included completely
2620 : // }
2621 : // \n Builds a table of contents or a range of entries, such as 1-9 in a table of contents without page numbers
2622 : // if( lcl_FindInCommand( pContext->GetCommand(), 'n', sValue ))
2623 : // {
2624 : //todo: what does the description mean?
2625 : // }
2626 : // \o Builds a table of contents by using outline levels instead of TC entries
2627 0 : if( lcl_FindInCommand( pContext->GetCommand(), 'o', sValue ))
2628 : {
2629 0 : bFromOutline = true;
2630 0 : if (sValue.isEmpty())
2631 0 : nMaxLevel = WW_OUTLINE_MAX;
2632 : else
2633 : {
2634 0 : sal_Int32 nIndex = 0;
2635 0 : sValue.getToken( 0, '-', nIndex );
2636 0 : nMaxLevel = static_cast<sal_Int16>(nIndex != -1 ? sValue.copy(nIndex).toInt32() : 0);
2637 : }
2638 : }
2639 : // \p Defines the separator between the table entry and its page number
2640 0 : if( lcl_FindInCommand( pContext->GetCommand(), 'p', sValue ))
2641 : { }
2642 : // \s Builds a table of contents by using a sequence type
2643 0 : if( lcl_FindInCommand( pContext->GetCommand(), 's', sValue ))
2644 : { }
2645 : // \t Builds a table of contents by using style names other than the standard outline styles
2646 0 : if( lcl_FindInCommand( pContext->GetCommand(), 't', sValue ))
2647 : {
2648 0 : sal_Int32 nPos = 0;
2649 0 : OUString sToken = sValue.getToken( 1, '"', nPos);
2650 0 : sTemplate = sToken.isEmpty() ? sValue : sToken;
2651 : }
2652 : // \u Builds a table of contents by using the applied paragraph outline level
2653 0 : if( lcl_FindInCommand( pContext->GetCommand(), 'u', sValue ))
2654 : {
2655 0 : bFromOutline = true;
2656 : //todo: what doesn 'the applied paragraph outline level' refer to?
2657 : }
2658 : // \w Preserve tab characters within table entries
2659 : // if( lcl_FindInCommand( pContext->GetCommand(), 'w', sValue ))
2660 : // {
2661 : //todo: not supported
2662 : // }
2663 : // \x Preserve newline characters within table entries
2664 : // if( lcl_FindInCommand( pContext->GetCommand(), 'x', sValue ))
2665 : // {
2666 : //todo: unsupported
2667 : // }
2668 : // \z Hides page numbers within the table of contens when shown in Web Layout View
2669 : // if( lcl_FindInCommand( pContext->GetCommand(), 'z', sValue ))
2670 : // { //todo: unsupported feature }
2671 :
2672 : //if there's no option then it should be created from outline
2673 0 : if( !bFromOutline && !bFromEntries && sTemplate.isEmpty() )
2674 0 : bFromOutline = true;
2675 :
2676 0 : uno::Reference< beans::XPropertySet > xTOC;
2677 0 : if (m_xTextFactory.is())
2678 : xTOC.set(
2679 0 : m_xTextFactory->createInstance
2680 : ( bTableOfFigures ?
2681 : "com.sun.star.text.IllustrationsIndex"
2682 0 : : sTOCServiceName),
2683 0 : uno::UNO_QUERY_THROW);
2684 0 : if (xTOC.is())
2685 0 : xTOC->setPropertyValue(rPropNameSupplier.GetName( PROP_TITLE ), uno::makeAny(OUString()));
2686 0 : if( !bTableOfFigures && xTOC.is() )
2687 : {
2688 0 : xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_LEVEL ), uno::makeAny( nMaxLevel ) );
2689 0 : xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_CREATE_FROM_OUTLINE ), uno::makeAny( bFromOutline ));
2690 0 : xTOC->setPropertyValue( rPropNameSupplier.GetName( PROP_CREATE_FROM_MARKS ), uno::makeAny( bFromEntries ));
2691 0 : if( !sTemplate.isEmpty() )
2692 : {
2693 : //the string contains comma separated the names and related levels
2694 : //like: "Heading 1,1,Heading 2,2"
2695 0 : TOCStyleMap aMap;
2696 : sal_Int32 nLevel;
2697 0 : sal_Int32 nPosition = 0;
2698 0 : while( nPosition >= 0)
2699 : {
2700 0 : OUString sStyleName = sTemplate.getToken( 0, ',', nPosition );
2701 : //empty tokens should be skipped
2702 0 : while( sStyleName.isEmpty() && nPosition > 0 )
2703 0 : sStyleName = sTemplate.getToken( 0, ',', nPosition );
2704 0 : nLevel = sTemplate.getToken( 0, ',', nPosition ).toInt32();
2705 0 : if( !nLevel )
2706 0 : nLevel = 1;
2707 0 : if( !sStyleName.isEmpty() )
2708 0 : aMap.insert( TOCStyleMap::value_type(nLevel, sStyleName) );
2709 0 : }
2710 0 : uno::Reference< container::XIndexReplace> xParaStyles;
2711 0 : xTOC->getPropertyValue(rPropNameSupplier.GetName(PROP_LEVEL_PARAGRAPH_STYLES)) >>= xParaStyles;
2712 0 : for( nLevel = 1; nLevel < 10; ++nLevel)
2713 : {
2714 0 : sal_Int32 nLevelCount = aMap.count( nLevel );
2715 0 : if( nLevelCount )
2716 : {
2717 0 : TOCStyleMap::iterator aTOCStyleIter = aMap.find( nLevel );
2718 :
2719 0 : uno::Sequence< OUString> aStyles( nLevelCount );
2720 0 : for ( sal_Int32 nStyle = 0; nStyle < nLevelCount; ++nStyle, ++aTOCStyleIter )
2721 : {
2722 0 : aStyles[nStyle] = aTOCStyleIter->second;
2723 : }
2724 0 : xParaStyles->replaceByIndex(nLevel - 1, uno::makeAny(aStyles));
2725 : }
2726 : }
2727 0 : xTOC->setPropertyValue(rPropNameSupplier.GetName(PROP_CREATE_FROM_LEVEL_PARAGRAPH_STYLES), uno::makeAny( true ));
2728 :
2729 : }
2730 0 : if(bHyperlinks || !sChapterNoSeparator.isEmpty())
2731 : {
2732 0 : uno::Reference< container::XIndexReplace> xLevelFormats;
2733 0 : xTOC->getPropertyValue(rPropNameSupplier.GetName(PROP_LEVEL_FORMAT)) >>= xLevelFormats;
2734 0 : sal_Int32 nLevelCount = xLevelFormats->getCount();
2735 : //start with level 1, 0 is the header level
2736 0 : for( sal_Int32 nLevel = 1; nLevel < nLevelCount; ++nLevel)
2737 : {
2738 0 : uno::Sequence< beans::PropertyValues > aLevel;
2739 0 : xLevelFormats->getByIndex( nLevel ) >>= aLevel;
2740 : //create a copy of the level and add two new entries - hyperlink start and end
2741 0 : bool bChapterNoSeparator = !sChapterNoSeparator.isEmpty();
2742 0 : sal_Int32 nAdd = (bHyperlinks && bChapterNoSeparator) ? 4 : 2;
2743 0 : uno::Sequence< beans::PropertyValues > aNewLevel( aLevel.getLength() + nAdd);
2744 0 : beans::PropertyValues* pNewLevel = aNewLevel.getArray();
2745 0 : if( bHyperlinks )
2746 : {
2747 0 : beans::PropertyValues aHyperlink(1);
2748 0 : aHyperlink[0].Name = rPropNameSupplier.GetName( PROP_TOKEN_TYPE );
2749 0 : aHyperlink[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_HYPERLINK_START );
2750 0 : pNewLevel[0] = aHyperlink;
2751 0 : aHyperlink[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_HYPERLINK_END );
2752 0 : pNewLevel[aNewLevel.getLength() -1] = aHyperlink;
2753 : }
2754 0 : if( bChapterNoSeparator )
2755 : {
2756 0 : beans::PropertyValues aChapterNo(2);
2757 0 : aChapterNo[0].Name = rPropNameSupplier.GetName( PROP_TOKEN_TYPE );
2758 0 : aChapterNo[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_CHAPTER_INFO );
2759 0 : aChapterNo[1].Name = rPropNameSupplier.GetName( PROP_CHAPTER_FORMAT );
2760 : //todo: is ChapterFormat::Number correct?
2761 0 : aChapterNo[1].Value <<= (sal_Int16)text::ChapterFormat::NUMBER;
2762 0 : pNewLevel[aNewLevel.getLength() - (bHyperlinks ? 4 : 2) ] = aChapterNo;
2763 :
2764 0 : beans::PropertyValues aChapterSeparator(2);
2765 0 : aChapterSeparator[0].Name = rPropNameSupplier.GetName( PROP_TOKEN_TYPE );
2766 0 : aChapterSeparator[0].Value <<= rPropNameSupplier.GetName( PROP_TOKEN_TEXT );
2767 0 : aChapterSeparator[1].Name = rPropNameSupplier.GetName( PROP_TEXT );
2768 0 : aChapterSeparator[1].Value <<= sChapterNoSeparator;
2769 0 : pNewLevel[aNewLevel.getLength() - (bHyperlinks ? 3 : 1)] = aChapterSeparator;
2770 : }
2771 : //copy the 'old' entries except the last (page no)
2772 0 : for( sal_Int32 nToken = 0; nToken < aLevel.getLength() - 1; ++nToken)
2773 : {
2774 0 : pNewLevel[nToken + 1] = aLevel[nToken];
2775 : }
2776 : //copy page no entry (last or last but one depending on bHyperlinks
2777 0 : sal_Int32 nPageNo = aNewLevel.getLength() - (bHyperlinks ? 2 : 3);
2778 0 : pNewLevel[nPageNo] = aLevel[aLevel.getLength() - 1];
2779 :
2780 0 : xLevelFormats->replaceByIndex( nLevel, uno::makeAny( aNewLevel ) );
2781 0 : }
2782 : }
2783 : }
2784 0 : else if (bTableOfFigures && xTOC.is())
2785 : {
2786 0 : if (!sFigureSequence.isEmpty())
2787 0 : xTOC->setPropertyValue(rPropNameSupplier.GetName(PROP_LABEL_CATEGORY),
2788 0 : uno::makeAny(sFigureSequence));
2789 : }
2790 0 : pContext->SetTOC( xTOC );
2791 0 : }
2792 :
2793 :
2794 : /*-------------------------------------------------------------------------
2795 : //the field command has to be closed (0x14 appeared)
2796 : -----------------------------------------------------------------------*/
2797 27 : void DomainMapper_Impl::CloseFieldCommand()
2798 : {
2799 : #ifdef DEBUG_DOMAINMAPPER
2800 : dmapper_logger->element("closeFieldCommand");
2801 : #endif
2802 :
2803 27 : FieldContextPtr pContext = m_aFieldStack.top();
2804 : OSL_ENSURE( pContext.get(), "no field context available");
2805 27 : if( pContext.get() )
2806 : {
2807 27 : m_bSetUserFieldContent = false;
2808 27 : FieldConversionMap_t aFieldConversionMap = lcl_GetFieldConversion();
2809 27 : bool bCreateEnhancedField = false;
2810 :
2811 : try
2812 : {
2813 27 : uno::Reference< uno::XInterface > xFieldInterface;
2814 : //at first determine the field type - erase leading and trailing whitespaces
2815 54 : OUString sCommand( pContext->GetCommand().trim() );
2816 27 : sal_Int32 nSpaceIndex = sCommand.indexOf( ' ' );
2817 27 : if( 0 <= nSpaceIndex )
2818 14 : sCommand = sCommand.copy( 0, nSpaceIndex );
2819 :
2820 27 : FieldConversionMap_t::iterator aIt = aFieldConversionMap.find(sCommand);
2821 27 : if(aIt != aFieldConversionMap.end())
2822 : {
2823 24 : uno::Reference< beans::XPropertySet > xFieldProperties;
2824 24 : bool bCreateField = true;
2825 24 : switch (aIt->second.eFieldId)
2826 : {
2827 : case FIELD_HYPERLINK:
2828 : case FIELD_DOCPROPERTY:
2829 : case FIELD_TOC:
2830 : case FIELD_TC:
2831 : case FIELD_EQ:
2832 9 : bCreateField = false;
2833 9 : break;
2834 : case FIELD_FORMCHECKBOX :
2835 : case FIELD_FORMTEXT :
2836 : case FIELD_FORMDROPDOWN :
2837 : {
2838 : // If we use 'enhanced' fields then FIELD_FORMCHECKBOX,
2839 : // FIELD_FORMTEXT & FIELD_FORMDROPDOWN are treated specially
2840 5 : if ( m_bUsingEnhancedFields )
2841 : {
2842 5 : bCreateField = false;
2843 5 : bCreateEnhancedField = true;
2844 : }
2845 : // for non enhanced fields checkboxes are displayed
2846 : // as an awt control not a field
2847 0 : else if ( aIt->second.eFieldId == FIELD_FORMCHECKBOX )
2848 0 : bCreateField = false;
2849 5 : break;
2850 : }
2851 : default:
2852 10 : break;
2853 : }
2854 :
2855 24 : if( bCreateField || bCreateEnhancedField )
2856 : {
2857 : //add the service prefix
2858 15 : OUString sServiceName("com.sun.star.text.");
2859 15 : if ( bCreateEnhancedField )
2860 : {
2861 5 : FieldConversionMap_t aEnhancedFieldConversionMap = lcl_GetEnhancedFieldConversion();
2862 5 : FieldConversionMap_t::iterator aEnhancedIt = aEnhancedFieldConversionMap.find(sCommand);
2863 5 : if ( aEnhancedIt != aEnhancedFieldConversionMap.end())
2864 5 : sServiceName += OUString::createFromAscii(aEnhancedIt->second.cFieldServiceName );
2865 : }
2866 : else
2867 : {
2868 10 : sServiceName += "TextField.";
2869 10 : sServiceName += OUString::createFromAscii(aIt->second.cFieldServiceName );
2870 : }
2871 :
2872 : #ifdef DEBUG_DOMAINMAPPER
2873 : dmapper_logger->startElement("fieldService");
2874 : dmapper_logger->chars(sServiceName);
2875 : dmapper_logger->endElement();
2876 : #endif
2877 :
2878 15 : if (m_xTextFactory.is())
2879 : {
2880 15 : xFieldInterface = m_xTextFactory->createInstance(sServiceName);
2881 15 : xFieldProperties = uno::Reference< beans::XPropertySet >( xFieldInterface, uno::UNO_QUERY_THROW);
2882 15 : }
2883 : }
2884 24 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
2885 24 : switch( aIt->second.eFieldId )
2886 : {
2887 0 : case FIELD_ADDRESSBLOCK: break;
2888 0 : case FIELD_ADVANCE : break;
2889 : case FIELD_ASK :
2890 1 : handleFieldAsk(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties);
2891 1 : break;
2892 : case FIELD_AUTONUM :
2893 : case FIELD_AUTONUMLGL :
2894 : case FIELD_AUTONUMOUT :
2895 0 : handleAutoNum(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties);
2896 0 : break;
2897 : case FIELD_AUTHOR :
2898 : case FIELD_USERNAME :
2899 : case FIELD_USERINITIALS :
2900 0 : handleAuthor(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties, aIt->second.eFieldId );
2901 0 : break;
2902 : case FIELD_DATE:
2903 1 : if (xFieldProperties.is())
2904 : {
2905 : //not fixed,
2906 1 : xFieldProperties->setPropertyValue(
2907 1 : rPropNameSupplier.GetName(PROP_IS_FIXED),
2908 2 : uno::makeAny( false ));
2909 1 : xFieldProperties->setPropertyValue(
2910 1 : rPropNameSupplier.GetName(PROP_IS_DATE),
2911 2 : uno::makeAny( true ));
2912 1 : SetNumberFormat( pContext->GetCommand(), xFieldProperties );
2913 : }
2914 1 : break;
2915 : case FIELD_COMMENTS :
2916 : {
2917 : // OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" COMMENTS") );
2918 : // A parameter with COMMENTS shouldn't set fixed
2919 : // ( or at least the binary filter doesn't )
2920 : // If we set fixed then we wont export a field cmd.
2921 : // Additionally the para in COMMENTS is more like an
2922 : // instruction to set the document property comments
2923 : // with the param ( e.g. each COMMENT with a param will
2924 : // overwrite the Comments document property
2925 : // #TODO implement the above too
2926 0 : xFieldProperties->setPropertyValue(
2927 0 : rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( false ));
2928 : //PROP_CURRENT_PRESENTATION is set later anyway
2929 : }
2930 0 : break;
2931 : case FIELD_CREATEDATE :
2932 : {
2933 0 : xFieldProperties->setPropertyValue(
2934 0 : rPropNameSupplier.GetName( PROP_IS_DATE ), uno::makeAny( true ));
2935 0 : SetNumberFormat( pContext->GetCommand(), xFieldProperties );
2936 : }
2937 0 : break;
2938 : case FIELD_DOCPROPERTY :
2939 0 : handleDocProperty(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties);
2940 0 : break;
2941 : case FIELD_DOCVARIABLE :
2942 : {
2943 0 : OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" DOCVARIABLE") );
2944 : //create a user field and type
2945 : uno::Reference< beans::XPropertySet > xMaster =
2946 0 : FindOrCreateFieldMaster( "com.sun.star.text.FieldMaster.User", sParam );
2947 0 : uno::Reference< text::XDependentTextField > xDependentField( xFieldInterface, uno::UNO_QUERY_THROW );
2948 0 : xDependentField->attachTextFieldMaster( xMaster );
2949 0 : m_bSetUserFieldContent = true;
2950 : }
2951 0 : break;
2952 : case FIELD_EDITTIME :
2953 : //it's a numbering type, no number format! SetNumberFormat( pContext->GetCommand(), xFieldProperties );
2954 0 : break;
2955 : case FIELD_EQ:
2956 : {
2957 1 : OUString aCommand = pContext->GetCommand().trim();
2958 1 : nSpaceIndex = aCommand.indexOf(' ');
2959 1 : if(nSpaceIndex > 0)
2960 1 : aCommand = aCommand.copy(nSpaceIndex).trim();
2961 1 : if (aCommand.startsWith("\\s"))
2962 : {
2963 1 : aCommand = aCommand.copy(2);
2964 1 : if (aCommand.startsWith("\\do"))
2965 : {
2966 1 : aCommand = aCommand.copy(3);
2967 1 : sal_Int32 nStartIndex = aCommand.indexOf('(');
2968 1 : sal_Int32 nEndIndex = aCommand.indexOf(')');
2969 1 : if (nStartIndex > 0 && nEndIndex > 0)
2970 : {
2971 : // nDown is the requested "lower by" value in points.
2972 1 : sal_Int32 nDown = aCommand.copy(0, nStartIndex).toInt32();
2973 1 : OUString aContent = aCommand.copy(nStartIndex + 1, nEndIndex - nStartIndex - 1);
2974 2 : PropertyMapPtr pCharContext = GetTopContext();
2975 : // dHeight is the font size of the current style.
2976 1 : double dHeight = 0;
2977 1 : if (GetPropertyFromStyleSheet(PROP_CHAR_HEIGHT) >>= dHeight)
2978 : // Character escapement should be given in negative percents for subscripts.
2979 1 : pCharContext->Insert(PROP_CHAR_ESCAPEMENT, uno::makeAny( sal_Int16(- 100 * nDown / dHeight) ) );
2980 2 : appendTextPortion(aContent, pCharContext);
2981 : }
2982 : }
2983 1 : }
2984 : }
2985 1 : break;
2986 : case FIELD_FILLIN :
2987 : {
2988 0 : sal_Int32 nIndex = 0;
2989 0 : if (xFieldProperties.is())
2990 0 : xFieldProperties->setPropertyValue(
2991 0 : rPropNameSupplier.GetName(PROP_HINT), uno::makeAny( pContext->GetCommand().getToken( 1, '\"', nIndex)));
2992 : }
2993 0 : break;
2994 : case FIELD_FILENAME:
2995 : {
2996 0 : sal_Int32 nNumberingTypeIndex = pContext->GetCommand().indexOf("\\p");
2997 0 : if (xFieldProperties.is())
2998 0 : xFieldProperties->setPropertyValue(
2999 0 : rPropNameSupplier.GetName(PROP_FILE_FORMAT),
3000 0 : uno::makeAny( nNumberingTypeIndex > 0 ? text::FilenameDisplayFormat::FULL : text::FilenameDisplayFormat::NAME ));
3001 : }
3002 0 : break;
3003 0 : case FIELD_FILESIZE : break;
3004 0 : case FIELD_FORMULA : break;
3005 : case FIELD_FORMCHECKBOX :
3006 : case FIELD_FORMDROPDOWN :
3007 : case FIELD_FORMTEXT :
3008 : {
3009 5 : uno::Reference< text::XTextField > xTextField( xFieldInterface, uno::UNO_QUERY );
3010 5 : if ( !xTextField.is() )
3011 : {
3012 : FFDataHandler::Pointer_t
3013 5 : pFFDataHandler(pContext->getFFDataHandler());
3014 : FormControlHelper::Pointer_t
3015 : pFormControlHelper(new FormControlHelper
3016 5 : (m_bUsingEnhancedFields ? aIt->second.eFieldId : FIELD_FORMCHECKBOX,
3017 :
3018 15 : m_xTextDocument, pFFDataHandler));
3019 5 : pContext->setFormControlHelper(pFormControlHelper);
3020 10 : uno::Reference< text::XFormField > xFormField( xFieldInterface, uno::UNO_QUERY );
3021 10 : uno::Reference< container::XNamed > xNamed( xFormField, uno::UNO_QUERY );
3022 5 : if ( xNamed.is() )
3023 : {
3024 5 : if ( pFFDataHandler && !pFFDataHandler->getName().isEmpty() )
3025 3 : xNamed->setName( pFFDataHandler->getName() );
3026 5 : pContext->SetFormField( xFormField );
3027 5 : }
3028 : }
3029 : else
3030 : {
3031 0 : if ( aIt->second.eFieldId == FIELD_FORMDROPDOWN )
3032 0 : lcl_handleDropdownField( xFieldProperties, pContext->getFFDataHandler() );
3033 : else
3034 0 : lcl_handleTextField( xFieldProperties, pContext->getFFDataHandler(), rPropNameSupplier );
3035 5 : }
3036 : }
3037 5 : break;
3038 0 : case FIELD_GOTOBUTTON : break;
3039 : case FIELD_HYPERLINK:
3040 : {
3041 8 : ::std::vector<OUString> aParts = pContext->GetCommandParts();
3042 8 : ::std::vector<OUString>::const_iterator aItEnd = aParts.end();
3043 8 : ::std::vector<OUString>::const_iterator aPartIt = aParts.begin();
3044 :
3045 16 : OUString sURL;
3046 :
3047 35 : while (aPartIt != aItEnd)
3048 : {
3049 19 : if ( *aPartIt == "\\l" )
3050 : {
3051 3 : ++aPartIt;
3052 :
3053 3 : if (aPartIt == aItEnd)
3054 0 : break;
3055 :
3056 3 : sURL += OUString('#');
3057 3 : sURL += *aPartIt;
3058 : }
3059 16 : else if ( *aPartIt == "\\m" || *aPartIt == "\\n" )
3060 : {
3061 : }
3062 16 : else if ( *aPartIt == "\\o" || *aPartIt == "\\t" )
3063 : {
3064 0 : ++aPartIt;
3065 :
3066 0 : if (aPartIt == aItEnd)
3067 0 : break;
3068 : }
3069 : else
3070 : {
3071 16 : sURL = *aPartIt;
3072 : }
3073 :
3074 19 : ++aPartIt;
3075 : }
3076 :
3077 8 : if (!sURL.isEmpty())
3078 : {
3079 8 : pContext->SetHyperlinkURL(sURL);
3080 8 : }
3081 : }
3082 8 : break;
3083 0 : case FIELD_IF : break;
3084 0 : case FIELD_INFO : break;
3085 0 : case FIELD_INCLUDEPICTURE: break;
3086 : case FIELD_KEYWORDS :
3087 : {
3088 0 : OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" KEYWORDS") );
3089 0 : if(!sParam.isEmpty())
3090 : {
3091 0 : xFieldProperties->setPropertyValue(
3092 0 : rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( true ));
3093 : //PROP_CURRENT_PRESENTATION is set later anyway
3094 0 : }
3095 : }
3096 0 : break;
3097 0 : case FIELD_LASTSAVEDBY : break;
3098 : case FIELD_MACROBUTTON:
3099 : {
3100 : //extract macro name
3101 1 : sal_Int32 nIndex = sizeof(" MACROBUTTON ");
3102 1 : OUString sMacro = pContext->GetCommand().getToken( 0, ' ', nIndex);
3103 1 : if (xFieldProperties.is())
3104 1 : xFieldProperties->setPropertyValue(
3105 1 : rPropNameSupplier.GetName(PROP_MACRO_NAME), uno::makeAny( sMacro ));
3106 :
3107 : //extract quick help text
3108 1 : if(xFieldProperties.is() && pContext->GetCommand().getLength() > nIndex + 1)
3109 : {
3110 1 : xFieldProperties->setPropertyValue(
3111 1 : rPropNameSupplier.GetName(PROP_HINT),
3112 2 : uno::makeAny( pContext->GetCommand().copy( nIndex )));
3113 1 : }
3114 : }
3115 1 : break;
3116 : case FIELD_MERGEFIELD :
3117 : {
3118 : //todo: create a database field and fieldmaster pointing to a column, only
3119 0 : OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" MERGEFIELD") );
3120 : //create a user field and type
3121 : uno::Reference< beans::XPropertySet > xMaster =
3122 0 : FindOrCreateFieldMaster( "com.sun.star.text.FieldMaster.Database", sParam );
3123 :
3124 : // xFieldProperties->setPropertyValue(
3125 : // "FieldCode",
3126 : // uno::makeAny( pContext->GetCommand().copy( nIndex + 1 )));
3127 0 : uno::Reference< text::XDependentTextField > xDependentField( xFieldInterface, uno::UNO_QUERY_THROW );
3128 0 : xDependentField->attachTextFieldMaster( xMaster );
3129 0 : m_bSetUserFieldContent = true;
3130 : }
3131 0 : break;
3132 0 : case FIELD_MERGEREC : break;
3133 0 : case FIELD_MERGESEQ : break;
3134 0 : case FIELD_NEXT : break;
3135 0 : case FIELD_NEXTIF : break;
3136 : case FIELD_PAGE :
3137 6 : if (xFieldProperties.is())
3138 : {
3139 6 : xFieldProperties->setPropertyValue(
3140 6 : rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
3141 12 : uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) ));
3142 6 : xFieldProperties->setPropertyValue(
3143 6 : rPropNameSupplier.GetName(PROP_SUB_TYPE),
3144 12 : uno::makeAny( text::PageNumberType_CURRENT ));
3145 : }
3146 :
3147 6 : break;
3148 : case FIELD_PAGEREF:
3149 : case FIELD_REF:
3150 1 : if (xFieldProperties.is())
3151 : {
3152 1 : bool bPageRef = aIt->second.eFieldId == FIELD_PAGEREF;
3153 1 : OUString sBookmark = lcl_ExtractParameter(pContext->GetCommand(),
3154 2 : (bPageRef ? sizeof(" PAGEREF") : sizeof(" REF")));
3155 :
3156 : // Do we need a GetReference (default) or a GetExpression field?
3157 2 : uno::Reference< text::XTextFieldsSupplier > xFieldsSupplier( GetTextDocument(), uno::UNO_QUERY );
3158 2 : uno::Reference< container::XNameAccess > xFieldMasterAccess = xFieldsSupplier->getTextFieldMasters();
3159 :
3160 1 : if (!xFieldMasterAccess->hasByName("com.sun.star.text.FieldMaster.SetExpression." + sBookmark))
3161 : {
3162 0 : xFieldProperties->setPropertyValue(
3163 0 : rPropNameSupplier.GetName(PROP_REFERENCE_FIELD_SOURCE),
3164 0 : uno::makeAny( sal_Int16(text::ReferenceFieldSource::BOOKMARK)) );
3165 0 : xFieldProperties->setPropertyValue(
3166 0 : rPropNameSupplier.GetName(PROP_SOURCE_NAME),
3167 0 : uno::makeAny( sBookmark) );
3168 0 : sal_Int16 nFieldPart = (bPageRef ? text::ReferenceFieldPart::PAGE : text::ReferenceFieldPart::TEXT);
3169 0 : OUString sValue;
3170 0 : if( lcl_FindInCommand( pContext->GetCommand(), 'p', sValue ))
3171 : {
3172 : //above-below
3173 0 : nFieldPart = text::ReferenceFieldPart::UP_DOWN;
3174 : }
3175 0 : else if( lcl_FindInCommand( pContext->GetCommand(), 'r', sValue ))
3176 : {
3177 : //number
3178 0 : nFieldPart = text::ReferenceFieldPart::NUMBER;
3179 : }
3180 0 : else if( lcl_FindInCommand( pContext->GetCommand(), 'n', sValue ))
3181 : {
3182 : //number-no-context
3183 0 : nFieldPart = text::ReferenceFieldPart::NUMBER_NO_CONTEXT;
3184 : }
3185 0 : else if( lcl_FindInCommand( pContext->GetCommand(), 'w', sValue ))
3186 : {
3187 : //number-full-context
3188 0 : nFieldPart = text::ReferenceFieldPart::NUMBER_FULL_CONTEXT;
3189 : }
3190 0 : xFieldProperties->setPropertyValue(
3191 0 : rPropNameSupplier.GetName( PROP_REFERENCE_FIELD_PART ), uno::makeAny( nFieldPart ));
3192 : }
3193 : else
3194 : {
3195 1 : xFieldInterface = m_xTextFactory->createInstance("com.sun.star.text.TextField.GetExpression");
3196 1 : xFieldProperties.set(xFieldInterface, uno::UNO_QUERY);
3197 1 : xFieldProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_CONTENT), uno::makeAny(sBookmark));
3198 1 : xFieldProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING));
3199 1 : }
3200 : }
3201 1 : break;
3202 0 : case FIELD_REVNUM : break;
3203 : case FIELD_SAVEDATE :
3204 0 : SetNumberFormat( pContext->GetCommand(), xFieldProperties );
3205 0 : break;
3206 0 : case FIELD_SECTION : break;
3207 0 : case FIELD_SECTIONPAGES : break;
3208 : case FIELD_SEQ :
3209 : {
3210 : // command looks like: " SEQ Table \* ARABIC "
3211 0 : OUString sCmd(pContext->GetCommand());
3212 : // find the sequence name, e.g. "SEQ"
3213 0 : OUString sSeqName = lcl_FindQuotedText(sCmd, "SEQ ", '\\');
3214 0 : sSeqName = sSeqName.trim();
3215 :
3216 : // create a sequence field master using the sequence name
3217 : uno::Reference< beans::XPropertySet > xMaster = FindOrCreateFieldMaster(
3218 : "com.sun.star.text.FieldMaster.SetExpression",
3219 0 : sSeqName);
3220 :
3221 0 : xMaster->setPropertyValue(
3222 0 : rPropNameSupplier.GetName(PROP_SUB_TYPE),
3223 0 : uno::makeAny(text::SetVariableType::SEQUENCE));
3224 :
3225 : // apply the numbering type
3226 0 : xFieldProperties->setPropertyValue(
3227 0 : rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
3228 0 : uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) ));
3229 :
3230 : // attach the master to the field
3231 0 : uno::Reference< text::XDependentTextField > xDependentField( xFieldInterface, uno::UNO_QUERY_THROW );
3232 0 : xDependentField->attachTextFieldMaster( xMaster );
3233 :
3234 0 : rtl::OUString sFormula = sSeqName + "+1";
3235 0 : rtl::OUString sValue;
3236 0 : if( lcl_FindInCommand( pContext->GetCommand(), 'c', sValue ))
3237 : {
3238 0 : sFormula = sSeqName;
3239 : }
3240 0 : else if( lcl_FindInCommand( pContext->GetCommand(), 'r', sValue ))
3241 : {
3242 0 : sFormula = sValue;
3243 : }
3244 : // TODO \s isn't handled, but the spec isn't easy to understand without
3245 : // an example for this one.
3246 0 : xFieldProperties->setPropertyValue(
3247 0 : rPropNameSupplier.GetName(PROP_CONTENT),
3248 0 : uno::makeAny(sFormula));
3249 :
3250 : // Take care of the numeric formatting definition, default is Arabic
3251 0 : sal_Int16 nNumberingType = lcl_ParseNumberingType(pContext->GetCommand());
3252 0 : if (nNumberingType == style::NumberingType::PAGE_DESCRIPTOR)
3253 0 : nNumberingType = style::NumberingType::ARABIC;
3254 0 : xFieldProperties->setPropertyValue(
3255 0 : rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
3256 0 : uno::makeAny(nNumberingType));
3257 : }
3258 0 : break;
3259 0 : case FIELD_SET : break;
3260 0 : case FIELD_SKIPIF : break;
3261 0 : case FIELD_STYLEREF : break;
3262 : case FIELD_SUBJECT :
3263 : {
3264 0 : OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" SUBJECT") );
3265 0 : if(!sParam.isEmpty())
3266 : {
3267 0 : xFieldProperties->setPropertyValue(
3268 0 : rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( true ));
3269 : //PROP_CURRENT_PRESENTATION is set later anyway
3270 0 : }
3271 : }
3272 0 : break;
3273 0 : case FIELD_SYMBOL : break;
3274 0 : case FIELD_TEMPLATE: break;
3275 : case FIELD_TIME :
3276 0 : SetNumberFormat( pContext->GetCommand(), xFieldProperties );
3277 0 : break;
3278 : case FIELD_TITLE :
3279 : {
3280 0 : OUString sParam = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" TITLE") );
3281 0 : if(!sParam.isEmpty())
3282 : {
3283 0 : xFieldProperties->setPropertyValue(
3284 0 : rPropNameSupplier.GetName( PROP_IS_FIXED ), uno::makeAny( true ));
3285 : //PROP_CURRENT_PRESENTATION is set later anyway
3286 0 : }
3287 : }
3288 0 : break;
3289 : case FIELD_USERADDRESS : //todo: user address collects street, city ...
3290 0 : break;
3291 : case FIELD_TOC:
3292 : handleToc(pContext, rPropNameSupplier, xFieldInterface, xFieldProperties,
3293 0 : OUString::createFromAscii(aIt->second.cFieldServiceName));
3294 0 : break;
3295 : case FIELD_TC :
3296 : {
3297 : uno::Reference< beans::XPropertySet > xTC(
3298 0 : m_xTextFactory->createInstance(
3299 0 : OUString::createFromAscii(aIt->second.cFieldServiceName)),
3300 0 : uno::UNO_QUERY_THROW);
3301 0 : OUString sTCText = lcl_ExtractParameter(pContext->GetCommand(), sizeof(" TC") );
3302 0 : if( !sTCText.isEmpty())
3303 0 : xTC->setPropertyValue(rPropNameSupplier.GetName(PROP_ALTERNATIVE_TEXT),
3304 0 : uno::makeAny(sTCText));
3305 0 : OUString sValue;
3306 : // \f TC entry in doc with multiple tables
3307 : // if( lcl_FindInCommand( pContext->GetCommand(), 'f', sValue ))
3308 : // {
3309 : // todo: unsupported
3310 : // }
3311 0 : if( lcl_FindInCommand( pContext->GetCommand(), 'l', sValue ))
3312 : // \l Outline Level
3313 : {
3314 0 : sal_Int32 nLevel = sValue.toInt32();
3315 0 : if( !sValue.isEmpty() && nLevel >= 0 && nLevel <= 10 )
3316 0 : xTC->setPropertyValue(rPropNameSupplier.GetName(PROP_LEVEL), uno::makeAny( (sal_Int16)nLevel ));
3317 : }
3318 : // if( lcl_FindInCommand( pContext->GetCommand(), 'n', sValue ))
3319 : // \n Suppress page numbers
3320 : // {
3321 : //todo: unsupported feature
3322 : // }
3323 0 : pContext->SetTC( xTC );
3324 : }
3325 0 : break;
3326 : case FIELD_NUMCHARS:
3327 : case FIELD_NUMWORDS:
3328 : case FIELD_NUMPAGES:
3329 0 : if (xFieldProperties.is())
3330 0 : xFieldProperties->setPropertyValue(
3331 0 : rPropNameSupplier.GetName(PROP_NUMBERING_TYPE),
3332 0 : uno::makeAny( lcl_ParseNumberingType(pContext->GetCommand()) ));
3333 0 : break;
3334 24 : }
3335 : }
3336 : //set the text field if there is any
3337 54 : pContext->SetTextField( uno::Reference< text::XTextField >( xFieldInterface, uno::UNO_QUERY ) );
3338 : }
3339 0 : catch( const uno::Exception& e )
3340 : {
3341 : SAL_WARN( "writerfilter", "Exception in CloseFieldCommand(): " << e.Message );
3342 : }
3343 27 : pContext->SetCommandCompleted();
3344 27 : }
3345 27 : }
3346 : /*-------------------------------------------------------------------------
3347 : //the _current_ fields require a string type result while TOCs accept richt results
3348 : -----------------------------------------------------------------------*/
3349 23 : bool DomainMapper_Impl::IsFieldResultAsString()
3350 : {
3351 23 : bool bRet = false;
3352 : OSL_ENSURE( !m_aFieldStack.empty(), "field stack empty?");
3353 23 : FieldContextPtr pContext = m_aFieldStack.top();
3354 : OSL_ENSURE( pContext.get(), "no field context available");
3355 23 : if( pContext.get() )
3356 : {
3357 23 : bRet = pContext->GetTextField().is();
3358 : }
3359 23 : return bRet;
3360 : }
3361 :
3362 :
3363 6 : void DomainMapper_Impl::SetFieldResult( OUString& rResult )
3364 : {
3365 : #ifdef DEBUG_DOMAINMAPPER
3366 : dmapper_logger->startElement("setFieldResult");
3367 : dmapper_logger->chars(rResult);
3368 : #endif
3369 :
3370 6 : FieldContextPtr pContext = m_aFieldStack.top();
3371 : OSL_ENSURE( pContext.get(), "no field context available");
3372 6 : if( pContext.get() )
3373 : {
3374 6 : uno::Reference<text::XTextField> xTextField = pContext->GetTextField();
3375 : try
3376 : {
3377 6 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
3378 : OSL_ENSURE( xTextField.is()
3379 : //||m_xTOC.is() ||m_xTC.is()
3380 : //||m_sHyperlinkURL.getLength()
3381 : , "DomainMapper_Impl::SetFieldResult: field not created" );
3382 6 : if(xTextField.is())
3383 : {
3384 : try
3385 : {
3386 6 : if( m_bSetUserFieldContent )
3387 : {
3388 : // user field content has to be set at the field master
3389 0 : uno::Reference< text::XDependentTextField > xDependentField( xTextField, uno::UNO_QUERY_THROW );
3390 0 : xDependentField->getTextFieldMaster()->setPropertyValue(
3391 0 : rPropNameSupplier.GetName(PROP_CONTENT),
3392 0 : uno::makeAny( rResult ));
3393 : }
3394 : else
3395 : {
3396 6 : uno::Reference< beans::XPropertySet > xFieldProperties( xTextField, uno::UNO_QUERY_THROW);
3397 : // In case of SetExpression, the field result contains the content of the variable.
3398 12 : uno::Reference<lang::XServiceInfo> xServiceInfo(xTextField, uno::UNO_QUERY);
3399 6 : bool bIsSetExpression = xServiceInfo->supportsService("com.sun.star.text.TextField.SetExpression");
3400 : // If we already have content set, then use the current presentation
3401 12 : rtl::OUString sValue;
3402 6 : uno::Any aValue = xFieldProperties->getPropertyValue(
3403 8 : rPropNameSupplier.GetName(PROP_CONTENT));
3404 2 : aValue >>= sValue;
3405 2 : xFieldProperties->setPropertyValue(
3406 2 : rPropNameSupplier.GetName(bIsSetExpression && sValue.isEmpty()? PROP_CONTENT : PROP_CURRENT_PRESENTATION),
3407 10 : uno::makeAny( rResult ));
3408 : }
3409 : }
3410 4 : catch( const beans::UnknownPropertyException& )
3411 : {
3412 : //some fields don't have a CurrentPresentation (DateTime)
3413 : }
3414 : }
3415 : }
3416 0 : catch( const uno::Exception& )
3417 : {
3418 :
3419 6 : }
3420 6 : }
3421 6 : }
3422 :
3423 15 : void DomainMapper_Impl::SetFieldFFData(FFDataHandler::Pointer_t pFFDataHandler)
3424 : {
3425 : #ifdef DEBUG_DOMAINMAPPER
3426 : dmapper_logger->startElement("setFieldFFData");
3427 : #endif
3428 :
3429 15 : if (m_aFieldStack.size())
3430 : {
3431 14 : FieldContextPtr pContext = m_aFieldStack.top();
3432 14 : if (pContext.get())
3433 : {
3434 14 : pContext->setFFDataHandler(pFFDataHandler);
3435 14 : }
3436 : }
3437 :
3438 : #ifdef DEBUG_DOMAINMAPPER
3439 : dmapper_logger->endElement();
3440 : #endif
3441 15 : }
3442 :
3443 : /*-------------------------------------------------------------------------
3444 : //the end of field is reached (0x15 appeared) - the command might still be open
3445 : -----------------------------------------------------------------------*/
3446 27 : void DomainMapper_Impl::PopFieldContext()
3447 : {
3448 : #ifdef DEBUG_DOMAINMAPPER
3449 : dmapper_logger->element("popFieldContext");
3450 : #endif
3451 :
3452 27 : if (m_aFieldStack.empty())
3453 27 : return;
3454 :
3455 27 : FieldContextPtr pContext = m_aFieldStack.top();
3456 : OSL_ENSURE( pContext.get(), "no field context available");
3457 27 : if( pContext.get() )
3458 : {
3459 27 : if( !pContext->IsCommandCompleted() )
3460 4 : CloseFieldCommand();
3461 :
3462 : //insert the field, TC or TOC
3463 27 : uno::Reference< text::XTextAppend > xTextAppend;
3464 27 : if (!m_aTextAppendStack.empty())
3465 27 : xTextAppend = m_aTextAppendStack.top().xTextAppend;
3466 27 : if(xTextAppend.is())
3467 : {
3468 : try
3469 : {
3470 27 : uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange(pContext->GetStartRange());
3471 54 : uno::Reference< text::XTextContent > xToInsert( pContext->GetTOC(), uno::UNO_QUERY );
3472 27 : if( xToInsert.is() )
3473 : {
3474 0 : xCrsr->gotoEnd( true );
3475 0 : xToInsert->attach( uno::Reference< text::XTextRange >( xCrsr, uno::UNO_QUERY_THROW ));
3476 : }
3477 : else
3478 : {
3479 27 : xToInsert = uno::Reference< text::XTextContent >(pContext->GetTC(), uno::UNO_QUERY);
3480 27 : if( !xToInsert.is() )
3481 27 : xToInsert = uno::Reference< text::XTextContent >(pContext->GetTextField(), uno::UNO_QUERY);
3482 27 : if( xToInsert.is() )
3483 : {
3484 10 : uno::Sequence<beans::PropertyValue> aValues;
3485 : // Character properties of the field show up here the
3486 : // last (always empty) run. Inherit character
3487 : // properties from there.
3488 10 : if (m_pLastCharacterContext.get())
3489 10 : aValues = m_pLastCharacterContext->GetPropertyValues();
3490 10 : appendTextContent(xToInsert, aValues);
3491 : }
3492 : else
3493 : {
3494 17 : FormControlHelper::Pointer_t pFormControlHelper(pContext->getFormControlHelper());
3495 17 : if (pFormControlHelper.get() != NULL && pFormControlHelper->hasFFDataHandler() )
3496 : {
3497 5 : uno::Reference< text::XFormField > xFormField( pContext->GetFormField() );
3498 5 : xToInsert.set(xFormField, uno::UNO_QUERY);
3499 5 : if ( xFormField.is() && xToInsert.is() )
3500 : {
3501 5 : xCrsr->gotoEnd( true );
3502 5 : xToInsert->attach( uno::Reference< text::XTextRange >( xCrsr, uno::UNO_QUERY_THROW ));
3503 5 : pFormControlHelper->processField( xFormField );
3504 : }
3505 : else
3506 : {
3507 0 : uno::Reference<text::XTextRange> xTxtRange(xCrsr, uno::UNO_QUERY);
3508 0 : pFormControlHelper->insertControl(xTxtRange);
3509 5 : }
3510 : }
3511 12 : else if(!pContext->GetHyperlinkURL().isEmpty())
3512 : {
3513 8 : PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
3514 8 : xCrsr->gotoEnd( true );
3515 :
3516 8 : uno::Reference< beans::XPropertySet > xCrsrProperties( xCrsr, uno::UNO_QUERY_THROW );
3517 16 : xCrsrProperties->setPropertyValue(rPropNameSupplier.GetName(PROP_HYPER_LINK_U_R_L), uno::
3518 16 : makeAny(pContext->GetHyperlinkURL()));
3519 17 : }
3520 : }
3521 27 : }
3522 : }
3523 0 : catch(const lang::IllegalArgumentException&)
3524 : {
3525 : OSL_FAIL( "IllegalArgumentException in PopFieldContext()" );
3526 : }
3527 0 : catch(const uno::Exception&)
3528 : {
3529 : OSL_FAIL( "exception in PopFieldContext()" );
3530 : }
3531 27 : }
3532 : //
3533 : //TOCs have to include all the imported content
3534 : //...
3535 : }
3536 : //remove the field context
3537 27 : m_aFieldStack.pop();
3538 : }
3539 :
3540 :
3541 88 : void DomainMapper_Impl::AddBookmark( const OUString& rBookmarkName, const OUString& rId )
3542 : {
3543 88 : if (m_aTextAppendStack.empty())
3544 88 : return;
3545 88 : uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
3546 88 : BookmarkMap_t::iterator aBookmarkIter = m_aBookmarkMap.find( rId );
3547 : //is the bookmark name already registered?
3548 : try
3549 : {
3550 88 : if( aBookmarkIter != m_aBookmarkMap.end() )
3551 : {
3552 42 : static const OUString sBookmarkService("com.sun.star.text.Bookmark");
3553 42 : if (m_xTextFactory.is())
3554 : {
3555 42 : uno::Reference< text::XTextContent > xBookmark( m_xTextFactory->createInstance( sBookmarkService ), uno::UNO_QUERY_THROW );
3556 84 : uno::Reference< text::XTextCursor > xCursor;
3557 84 : uno::Reference< text::XText > xText = aBookmarkIter->second.m_xTextRange->getText();
3558 42 : if( aBookmarkIter->second.m_bIsStartOfText )
3559 19 : xCursor = xText->createTextCursorByRange( xText->getStart() );
3560 : else
3561 : {
3562 23 : xCursor = xText->createTextCursorByRange( aBookmarkIter->second.m_xTextRange );
3563 23 : xCursor->goRight( 1, false );
3564 : }
3565 :
3566 42 : xCursor->gotoRange( xTextAppend->getEnd(), true );
3567 84 : uno::Reference< container::XNamed > xBkmNamed( xBookmark, uno::UNO_QUERY_THROW );
3568 : //todo: make sure the name is not used already!
3569 42 : if ( !aBookmarkIter->second.m_sBookmarkName.isEmpty() )
3570 42 : xBkmNamed->setName( aBookmarkIter->second.m_sBookmarkName );
3571 : else
3572 0 : xBkmNamed->setName( rBookmarkName );
3573 84 : xTextAppend->insertTextContent( uno::Reference< text::XTextRange >( xCursor, uno::UNO_QUERY_THROW), xBookmark, !xCursor->isCollapsed() );
3574 : }
3575 42 : m_aBookmarkMap.erase( aBookmarkIter );
3576 : }
3577 : else
3578 : {
3579 : //otherwise insert a text range as marker
3580 46 : bool bIsStart = true;
3581 46 : uno::Reference< text::XTextRange > xCurrent;
3582 46 : if (xTextAppend.is())
3583 : {
3584 46 : uno::Reference< text::XTextCursor > xCursor = xTextAppend->createTextCursorByRange( xTextAppend->getEnd() );
3585 46 : bIsStart = !xCursor->goLeft(1, false);
3586 46 : xCurrent = xCursor->getStart();
3587 : }
3588 46 : m_aBookmarkMap.insert(BookmarkMap_t::value_type( rId, BookmarkInsertPosition( bIsStart, rBookmarkName, xCurrent ) ));
3589 : }
3590 : }
3591 0 : catch( const uno::Exception& )
3592 : {
3593 : //TODO: What happens to bookmarks where start and end are at different XText objects?
3594 88 : }
3595 : }
3596 :
3597 8 : void DomainMapper_Impl::AddAnnotationPosition(const bool bStart)
3598 : {
3599 8 : if (m_aTextAppendStack.empty())
3600 8 : return;
3601 :
3602 : // Create a cursor, pointing to the current position.
3603 8 : uno::Reference<text::XTextAppend> xTextAppend = m_aTextAppendStack.top().xTextAppend;
3604 16 : uno::Reference<text::XTextRange> xCurrent;
3605 8 : if (xTextAppend.is())
3606 : {
3607 8 : uno::Reference<text::XTextCursor> xCursor = xTextAppend->createTextCursorByRange(xTextAppend->getEnd());
3608 8 : xCurrent = xCursor->getStart();
3609 : }
3610 :
3611 : // And save it, to be used by PopAnnotation() later.
3612 8 : if (bStart)
3613 4 : m_aAnnotationPosition.m_xStart = xCurrent;
3614 : else
3615 12 : m_aAnnotationPosition.m_xEnd = xCurrent;
3616 : }
3617 :
3618 56 : GraphicImportPtr DomainMapper_Impl::GetGraphicImport(GraphicImportType eGraphicImportType)
3619 : {
3620 56 : if(!m_pGraphicImport)
3621 28 : m_pGraphicImport.reset( new GraphicImport( m_xComponentContext, m_xTextFactory, m_rDMapper, eGraphicImportType ) );
3622 56 : return m_pGraphicImport;
3623 : }
3624 : /*-------------------------------------------------------------------------
3625 : reset graphic import if the last import resulted in a shape, not a graphic
3626 : -----------------------------------------------------------------------*/
3627 0 : void DomainMapper_Impl::ResetGraphicImport()
3628 : {
3629 0 : m_pGraphicImport.reset();
3630 0 : }
3631 :
3632 :
3633 28 : void DomainMapper_Impl::ImportGraphic(writerfilter::Reference< Properties >::Pointer_t ref, GraphicImportType eGraphicImportType)
3634 : {
3635 28 : GetGraphicImport(eGraphicImportType);
3636 28 : if( eGraphicImportType != IMPORT_AS_DETECTED_INLINE && eGraphicImportType != IMPORT_AS_DETECTED_ANCHOR )
3637 : {
3638 : //create the graphic
3639 0 : ref->resolve( *m_pGraphicImport );
3640 : }
3641 :
3642 : //insert it into the document at the current cursor position
3643 :
3644 : uno::Reference<text::XTextContent> xTextContent
3645 28 : (m_pGraphicImport->GetGraphicObject());
3646 :
3647 : //insert it into the document at the current cursor position
3648 : OSL_ENSURE( xTextContent.is(), "DomainMapper_Impl::ImportGraphic");
3649 28 : if( xTextContent.is())
3650 28 : appendTextContent( xTextContent, uno::Sequence< beans::PropertyValue >() );
3651 :
3652 28 : m_pGraphicImport.reset();
3653 28 : }
3654 :
3655 :
3656 :
3657 3 : void DomainMapper_Impl::SetLineNumbering( sal_Int32 nLnnMod, sal_Int32 nLnc, sal_Int32 ndxaLnn )
3658 : {
3659 3 : if( !m_bLineNumberingSet )
3660 : {
3661 3 : const PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
3662 :
3663 : try
3664 : {
3665 3 : uno::Reference< text::XLineNumberingProperties > xLineProperties( m_xTextDocument, uno::UNO_QUERY_THROW );
3666 6 : uno::Reference< beans::XPropertySet > xProperties = xLineProperties->getLineNumberingProperties();
3667 6 : uno::Any aTrue( uno::makeAny( true ));
3668 3 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_IS_ON ), aTrue);
3669 3 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_COUNT_EMPTY_LINES ), aTrue );
3670 3 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_COUNT_LINES_IN_FRAMES ), uno::makeAny( false ) );
3671 3 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_INTERVAL ), uno::makeAny( static_cast< sal_Int16 >( nLnnMod )));
3672 3 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_DISTANCE ), uno::makeAny( ConversionHelper::convertTwipToMM100(ndxaLnn) ));
3673 3 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_NUMBER_POSITION ), uno::makeAny( style::LineNumberPosition::LEFT));
3674 3 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_NUMBERING_TYPE ), uno::makeAny( style::NumberingType::ARABIC));
3675 6 : xProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_RESTART_AT_EACH_PAGE ), uno::makeAny( nLnc == 0 ));
3676 : }
3677 0 : catch( const uno::Exception& )
3678 : {}
3679 : }
3680 3 : m_bLineNumberingSet = true;
3681 3 : }
3682 :
3683 :
3684 1550 : void DomainMapper_Impl::SetPageMarginTwip( PageMarElement eElement, sal_Int32 nValue )
3685 : {
3686 1550 : nValue = ConversionHelper::convertTwipToMM100(nValue);
3687 1550 : switch(eElement)
3688 : {
3689 254 : case PAGE_MAR_TOP : m_aPageMargins.top = nValue; break;
3690 256 : case PAGE_MAR_RIGHT : m_aPageMargins.right = nValue; break;
3691 253 : case PAGE_MAR_BOTTOM : m_aPageMargins.bottom = nValue; break;
3692 256 : case PAGE_MAR_LEFT : m_aPageMargins.left = nValue; break;
3693 179 : case PAGE_MAR_HEADER : m_aPageMargins.header = nValue; break;
3694 178 : case PAGE_MAR_FOOTER : m_aPageMargins.footer = nValue; break;
3695 174 : case PAGE_MAR_GUTTER : m_aPageMargins.gutter = nValue; break;
3696 : }
3697 1550 : }
3698 :
3699 :
3700 :
3701 615 : _PageMar::_PageMar()
3702 : {
3703 615 : header = footer = ConversionHelper::convertTwipToMM100(sal_Int32(720));
3704 615 : top = bottom = ConversionHelper::convertTwipToMM100( sal_Int32(1440));
3705 : // This is strange, the RTF spec says it's 1800, but it's clearly 1440 in Word
3706 : // OOXML seems not to specify a default value
3707 615 : right = left = ConversionHelper::convertTwipToMM100( sal_Int32(1440));
3708 615 : gutter = 0;
3709 615 : }
3710 :
3711 :
3712 :
3713 15 : void DomainMapper_Impl::RegisterFrameConversion(
3714 : uno::Reference< text::XTextRange > xFrameStartRange,
3715 : uno::Reference< text::XTextRange > xFrameEndRange,
3716 : uno::Sequence< beans::PropertyValue > aFrameProperties
3717 : )
3718 : {
3719 : OSL_ENSURE(
3720 : !m_aFrameProperties.getLength() && !m_xFrameStartRange.is() && !m_xFrameEndRange.is(),
3721 : "frame properties not removed");
3722 15 : m_aFrameProperties = aFrameProperties;
3723 15 : m_xFrameStartRange = xFrameStartRange;
3724 15 : m_xFrameEndRange = xFrameEndRange;
3725 15 : }
3726 :
3727 :
3728 2599 : bool DomainMapper_Impl::ExecuteFrameConversion()
3729 : {
3730 2599 : bool bRet = false;
3731 2599 : if( m_xFrameStartRange.is() && m_xFrameEndRange.is() )
3732 : {
3733 15 : bRet = true;
3734 : try
3735 : {
3736 15 : uno::Reference< text::XTextAppendAndConvert > xTextAppendAndConvert( GetTopTextAppend(), uno::UNO_QUERY_THROW );
3737 15 : xTextAppendAndConvert->convertToTextFrame(
3738 : m_xFrameStartRange,
3739 : m_xFrameEndRange,
3740 16 : m_aFrameProperties );
3741 : }
3742 2 : catch( const uno::Exception& rEx)
3743 : {
3744 : SAL_WARN( "writerfilter", "Exception caught when converting to frame: " + rEx.Message );
3745 1 : bRet = false;
3746 : }
3747 15 : m_xFrameStartRange = 0;
3748 15 : m_xFrameEndRange = 0;
3749 15 : m_aFrameProperties.realloc( 0 );
3750 : }
3751 2599 : return bRet;
3752 : }
3753 :
3754 9 : void DomainMapper_Impl::AddNewRedline( )
3755 : {
3756 9 : RedlineParamsPtr pNew( new RedlineParams );
3757 9 : pNew->m_nToken = ooxml::OOXML_mod;
3758 9 : if ( !m_bIsParaChange )
3759 : {
3760 9 : m_aRedlines.push_back( pNew );
3761 : }
3762 : else
3763 : {
3764 0 : m_pParaRedline.swap( pNew );
3765 9 : }
3766 9 : }
3767 :
3768 45 : RedlineParamsPtr DomainMapper_Impl::GetTopRedline( )
3769 : {
3770 45 : RedlineParamsPtr pResult;
3771 45 : if ( !m_bIsParaChange && m_aRedlines.size( ) > 0 )
3772 41 : pResult = m_aRedlines.back( );
3773 4 : else if ( m_bIsParaChange )
3774 0 : pResult = m_pParaRedline;
3775 45 : return pResult;
3776 : }
3777 :
3778 9 : sal_Int32 DomainMapper_Impl::GetCurrentRedlineToken( )
3779 : {
3780 9 : sal_Int32 nToken = 0;
3781 9 : RedlineParamsPtr pCurrent( GetTopRedline( ) );
3782 9 : if ( pCurrent.get( ) )
3783 9 : nToken = pCurrent->m_nToken;
3784 9 : return nToken;
3785 : }
3786 :
3787 13 : void DomainMapper_Impl::SetCurrentRedlineAuthor( OUString sAuthor )
3788 : {
3789 13 : if (!m_xAnnotationField.is())
3790 : {
3791 9 : RedlineParamsPtr pCurrent( GetTopRedline( ) );
3792 9 : if ( pCurrent.get( ) )
3793 9 : pCurrent->m_sAuthor = sAuthor;
3794 : }
3795 : else
3796 4 : m_xAnnotationField->setPropertyValue("Author", uno::makeAny(sAuthor));
3797 13 : }
3798 :
3799 4 : void DomainMapper_Impl::SetCurrentRedlineInitials( OUString sInitials )
3800 : {
3801 4 : if (m_xAnnotationField.is())
3802 4 : m_xAnnotationField->setPropertyValue("Initials", uno::makeAny(sInitials));
3803 4 : }
3804 :
3805 13 : void DomainMapper_Impl::SetCurrentRedlineDate( OUString sDate )
3806 : {
3807 13 : if (!m_xAnnotationField.is())
3808 : {
3809 9 : RedlineParamsPtr pCurrent( GetTopRedline( ) );
3810 9 : if ( pCurrent.get( ) )
3811 9 : pCurrent->m_sDate = sDate;
3812 : }
3813 : else
3814 4 : m_xAnnotationField->setPropertyValue("DateTimeValue", uno::makeAny(lcl_DateStringToDateTime(sDate)));
3815 13 : }
3816 :
3817 13 : void DomainMapper_Impl::SetCurrentRedlineId( sal_Int32 sId )
3818 : {
3819 13 : RedlineParamsPtr pCurrent( GetTopRedline( ) );
3820 13 : if ( pCurrent.get( ) )
3821 9 : pCurrent->m_nId = sId;
3822 13 : }
3823 :
3824 5 : void DomainMapper_Impl::SetCurrentRedlineToken( sal_Int32 nToken )
3825 : {
3826 5 : RedlineParamsPtr pCurrent( GetTopRedline( ) );
3827 5 : if ( pCurrent.get( ) )
3828 5 : pCurrent->m_nToken = nToken;
3829 5 : }
3830 :
3831 :
3832 :
3833 5 : void DomainMapper_Impl::RemoveCurrentRedline( )
3834 : {
3835 5 : if ( m_aRedlines.size( ) > 0 )
3836 : {
3837 5 : m_aRedlines.pop_back( );
3838 : }
3839 5 : }
3840 :
3841 0 : void DomainMapper_Impl::ResetParaRedline( )
3842 : {
3843 0 : if ( m_pParaRedline.get( ) )
3844 : {
3845 0 : RedlineParamsPtr pEmpty;
3846 0 : m_pParaRedline.swap( pEmpty );
3847 : }
3848 0 : }
3849 :
3850 :
3851 :
3852 346 : void DomainMapper_Impl::ApplySettingsTable()
3853 : {
3854 346 : if( m_pSettingsTable && m_xTextFactory.is() )
3855 : {
3856 : try
3857 : {
3858 337 : uno::Reference< beans::XPropertySet > xTextDefaults(m_xTextFactory->createInstance("com.sun.star.text.Defaults"), uno::UNO_QUERY_THROW );
3859 337 : sal_Int32 nDefTab = m_pSettingsTable->GetDefaultTabStop();
3860 337 : xTextDefaults->setPropertyValue( PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_TAB_STOP_DISTANCE ), uno::makeAny(nDefTab) );
3861 337 : if (m_pSettingsTable->GetLinkStyles())
3862 : {
3863 1 : PropertyNameSupplier& rSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
3864 : // If linked styles are enabled, set paragraph defaults from Word's default template
3865 1 : xTextDefaults->setPropertyValue(rSupplier.GetName(PROP_PARA_BOTTOM_MARGIN), uno::makeAny(ConversionHelper::convertTwipToMM100(200)));
3866 1 : style::LineSpacing aSpacing;
3867 1 : aSpacing.Mode = style::LineSpacingMode::PROP;
3868 1 : aSpacing.Height = sal_Int16(115);
3869 1 : xTextDefaults->setPropertyValue(rSupplier.GetName(PROP_PARA_LINE_SPACING), uno::makeAny(aSpacing));
3870 : }
3871 :
3872 337 : if (m_pSettingsTable->GetZoomFactor())
3873 : {
3874 199 : uno::Sequence<beans::PropertyValue> aViewProps(3);
3875 199 : aViewProps[0].Name = "ZoomFactor";
3876 199 : aViewProps[0].Value <<= m_pSettingsTable->GetZoomFactor();
3877 199 : aViewProps[1].Name = "VisibleBottom";
3878 199 : aViewProps[1].Value <<= sal_Int32(0);
3879 199 : aViewProps[2].Name = "ZoomType";
3880 199 : aViewProps[2].Value <<= sal_Int16(0);
3881 :
3882 398 : uno::Reference<container::XIndexContainer> xBox = document::IndexedPropertyValues::create(m_xComponentContext);
3883 199 : xBox->insertByIndex(sal_Int32(0), uno::makeAny(aViewProps));
3884 398 : uno::Reference<container::XIndexAccess> xIndexAccess(xBox, uno::UNO_QUERY);
3885 398 : uno::Reference<document::XViewDataSupplier> xViewDataSupplier(m_xTextDocument, uno::UNO_QUERY);
3886 398 : xViewDataSupplier->setViewData(xIndexAccess);
3887 : }
3888 :
3889 674 : uno::Reference< beans::XPropertySet > xSettings(m_xTextFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY);
3890 337 : if (m_pSettingsTable->GetUsePrinterMetrics())
3891 0 : xSettings->setPropertyValue("PrinterIndependentLayout", uno::makeAny(document::PrinterIndependentLayout::DISABLED));
3892 337 : if( m_pSettingsTable->GetEmbedTrueTypeFonts())
3893 0 : xSettings->setPropertyValue( PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_EMBED_FONTS ), uno::makeAny(true) );
3894 337 : if( m_pSettingsTable->GetEmbedSystemFonts())
3895 9 : xSettings->setPropertyValue( PropertyNameSupplier::GetPropertyNameSupplier().GetName( PROP_EMBED_SYSTEM_FONTS ), uno::makeAny(true) );
3896 674 : xSettings->setPropertyValue("AddParaTableSpacing", uno::makeAny(m_pSettingsTable->GetDoNotUseHTMLParagraphAutoSpacing()));
3897 : }
3898 0 : catch(const uno::Exception&)
3899 : {
3900 : }
3901 : }
3902 346 : }
3903 :
3904 5823 : uno::Reference<container::XIndexAccess> DomainMapper_Impl::GetCurrentNumberingRules(sal_Int32* pListLevel)
3905 : {
3906 5823 : uno::Reference<container::XIndexAccess> xRet;
3907 : try
3908 : {
3909 5823 : OUString aStyle = GetCurrentParaStyleId();
3910 5823 : if (aStyle.isEmpty() || GetTopContextType() != CONTEXT_PARAGRAPH)
3911 5527 : return xRet;
3912 300 : const StyleSheetEntryPtr pEntry = GetStyleSheetTable()->FindStyleSheetByISTD(aStyle);
3913 296 : if (!pEntry)
3914 76 : return xRet;
3915 220 : const StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast<const StyleSheetPropertyMap*>(pEntry ? pEntry->pProperties.get() : 0);
3916 220 : sal_Int32 nListId = pStyleSheetProperties->GetListId();
3917 220 : if (nListId < 0)
3918 216 : return xRet;
3919 4 : if (pListLevel)
3920 2 : *pListLevel = pStyleSheetProperties->GetListLevel();
3921 :
3922 : // So we are in a paragraph style and it has numbering. Look up the relevant numbering rules.
3923 8 : OUString aListName = ListDef::GetStyleName(nListId);
3924 8 : uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier(GetTextDocument(), uno::UNO_QUERY);
3925 8 : uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies();
3926 8 : uno::Reference<container::XNameAccess> xNumberingStyles;
3927 4 : xStyleFamilies->getByName("NumberingStyles") >>= xNumberingStyles;
3928 8 : uno::Reference<beans::XPropertySet> xStyle(xNumberingStyles->getByName(aListName), uno::UNO_QUERY);
3929 8 : xRet.set(xStyle->getPropertyValue("NumberingRules"), uno::UNO_QUERY);
3930 : }
3931 0 : catch( const uno::Exception& )
3932 : {
3933 : }
3934 4 : return xRet;
3935 : }
3936 :
3937 5821 : uno::Reference<beans::XPropertySet> DomainMapper_Impl::GetCurrentNumberingCharStyle()
3938 : {
3939 5821 : uno::Reference<beans::XPropertySet> xRet;
3940 : try
3941 : {
3942 5821 : sal_Int32 nListLevel = -1;
3943 5821 : uno::Reference<container::XIndexAccess> xLevels = GetCurrentNumberingRules(&nListLevel);
3944 5821 : if (!xLevels.is())
3945 5819 : return xRet;
3946 4 : uno::Sequence<beans::PropertyValue> aProps;
3947 2 : xLevels->getByIndex(nListLevel) >>= aProps;
3948 10 : for (int i = 0; i < aProps.getLength(); ++i)
3949 : {
3950 10 : const beans::PropertyValue& rProp = aProps[i];
3951 :
3952 10 : if (rProp.Name == "CharStyleName")
3953 : {
3954 2 : OUString aCharStyle;
3955 2 : rProp.Value >>= aCharStyle;
3956 4 : uno::Reference<container::XNameAccess> xCharacterStyles;
3957 4 : uno::Reference< style::XStyleFamiliesSupplier > xStylesSupplier(GetTextDocument(), uno::UNO_QUERY);
3958 4 : uno::Reference< container::XNameAccess > xStyleFamilies = xStylesSupplier->getStyleFamilies();
3959 2 : xStyleFamilies->getByName("CharacterStyles") >>= xCharacterStyles;
3960 2 : xRet.set(xCharacterStyles->getByName(aCharStyle), uno::UNO_QUERY_THROW);
3961 4 : break;
3962 : }
3963 2 : }
3964 : }
3965 0 : catch( const uno::Exception& )
3966 : {
3967 : }
3968 2 : return xRet;
3969 : }
3970 :
3971 45274 : SectionPropertyMap * DomainMapper_Impl::GetSectionContext()
3972 : {
3973 45274 : SectionPropertyMap* pSectionContext = 0;
3974 : //the section context is not availabe before the first call of startSectionGroup()
3975 45274 : if( !IsAnyTableImport() )
3976 : {
3977 28030 : PropertyMapPtr pContext = GetTopContextOfType(CONTEXT_SECTION);
3978 : OSL_ENSURE(pContext.get(), "Section context is not in the stack!");
3979 28030 : pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() );
3980 : }
3981 :
3982 45274 : return pSectionContext;
3983 : }
3984 :
3985 4943 : void DomainMapper_Impl::deferCharacterProperty( sal_Int32 id, com::sun::star::uno::Any value )
3986 : {
3987 4943 : deferredCharacterProperties[ id ] = value;
3988 4943 : }
3989 :
3990 4166 : void DomainMapper_Impl::processDeferredCharacterProperties()
3991 : {
3992 : // ACtually process in DomainMapper, so that it's the same source file like normal processing.
3993 4166 : if( !deferredCharacterProperties.empty())
3994 : {
3995 4166 : m_rDMapper.processDeferredCharacterProperties( deferredCharacterProperties );
3996 4166 : deferredCharacterProperties.clear();
3997 : }
3998 4166 : }
3999 :
4000 177 : sal_Int32 DomainMapper_Impl::getCurrentNumberingProperty(OUString aProp)
4001 : {
4002 177 : sal_Int32 nRet = 0;
4003 :
4004 177 : PropertyMap::iterator it = m_pTopContext->find(PropertyDefinition( PROP_NUMBERING_RULES ) );
4005 177 : uno::Reference<container::XIndexAccess> xNumberingRules;
4006 177 : if (it != m_pTopContext->end())
4007 4 : xNumberingRules.set(it->second, uno::UNO_QUERY);
4008 177 : it = m_pTopContext->find(PropertyDefinition( PROP_NUMBERING_LEVEL ) );
4009 177 : sal_Int32 nNumberingLevel = -1;
4010 177 : if (it != m_pTopContext->end())
4011 4 : it->second >>= nNumberingLevel;
4012 177 : if (xNumberingRules.is() && nNumberingLevel != -1)
4013 : {
4014 4 : uno::Sequence<beans::PropertyValue> aProps;
4015 4 : xNumberingRules->getByIndex(nNumberingLevel) >>= aProps;
4016 41 : for (int i = 0; i < aProps.getLength(); ++i)
4017 : {
4018 41 : const beans::PropertyValue& rProp = aProps[i];
4019 :
4020 41 : if (rProp.Name == aProp)
4021 : {
4022 4 : rProp.Value >>= nRet;
4023 4 : break;
4024 : }
4025 4 : }
4026 : }
4027 :
4028 177 : return nRet;
4029 : }
4030 :
4031 376 : bool DomainMapper_Impl::IsNewDoc()
4032 : {
4033 376 : return m_bIsNewDoc;
4034 : }
4035 :
4036 24 : }}
4037 :
4038 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|