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 "SettingsTable.hxx"
21 
22 #include <vector>
23 
24 #include <rtl/ustring.hxx>
25 #include <sfx2/zoomitem.hxx>
26 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <com/sun/star/beans/XPropertyState.hpp>
29 #include <com/sun/star/container/XNameContainer.hpp>
30 #include <com/sun/star/style/XStyle.hpp>
31 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
32 #include <comphelper/sequence.hxx>
33 #include <ooxml/resourceids.hxx>
34 #include "ConversionHelper.hxx"
35 #include "DomainMapper.hxx"
36 #include "util.hxx"
37 
38 using namespace com::sun::star;
39 
40 namespace writerfilter {
41 namespace
42 {
43 /// Maps OOXML <w:zoom w:val="..."> to SvxZoomType.
lcl_GetZoomType(Id nType)44 sal_Int16 lcl_GetZoomType(Id nType)
45 {
46     switch (nType)
47     {
48         case NS_ooxml::LN_Value_doc_ST_Zoom_fullPage:
49             return sal_Int16(SvxZoomType::WHOLEPAGE);
50         case NS_ooxml::LN_Value_doc_ST_Zoom_bestFit:
51             return sal_Int16(SvxZoomType::PAGEWIDTH);
52         case NS_ooxml::LN_Value_doc_ST_Zoom_textFit:
53             return sal_Int16(SvxZoomType::OPTIMAL);
54     }
55 
56     return sal_Int16(SvxZoomType::PERCENT);
57 }
58 }
59 
60 namespace dmapper
61 {
62     /** Document protection restrictions
63      *
64      * This element specifies the set of document protection restrictions which have been applied to the contents of a
65      * WordprocessingML document.These restrictions should be enforced by applications editing this document
66      * when the enforcement attribute is turned on, and ignored(but persisted) otherwise.Document protection is a
67      * set of restrictions used to prevent unintentional changes to all or part of a WordprocessingML document.
68      */
69     struct DocumentProtection_Impl
70     {
71         /** Document Editing Restrictions
72          *
73          * Possible values:
74          *  - NS_ooxml::LN_Value_doc_ST_DocProtect_none
75          *  - NS_ooxml::LN_Value_doc_ST_DocProtect_readOnly
76          *  - NS_ooxml::LN_Value_doc_ST_DocProtect_comments
77          *  - NS_ooxml::LN_Value_doc_ST_DocProtect_trackedChanges
78          *  - NS_ooxml::LN_Value_doc_ST_DocProtect_forms
79          */
80         sal_Int32       m_nEdit;
81         bool            m_bEnforcement;
82         bool            m_bFormatting;
83 
84         /** Provider type
85          *
86          * Possible values:
87          *  "rsaAES"  - NS_ooxml::LN_Value_doc_ST_CryptProv_rsaAES
88          *  "rsaFull" - NS_ooxml::LN_Value_doc_ST_CryptProv_rsaFull
89          */
90         sal_Int32       m_nCryptProviderType;
91         OUString        m_sCryptAlgorithmClass;
92         OUString        m_sCryptAlgorithmType;
93         OUString        m_sCryptAlgorithmSid;
94         sal_Int32       m_CryptSpinCount;
95         OUString        m_sHash;
96         OUString        m_sSalt;
97 
DocumentProtection_Implwriterfilter::dmapper::DocumentProtection_Impl98         DocumentProtection_Impl()
99             : m_nEdit(NS_ooxml::LN_Value_doc_ST_DocProtect_none) // Specifies that no editing restrictions have been applied to the document
100             , m_bEnforcement(false)
101             , m_bFormatting(false)
102             , m_nCryptProviderType(NS_ooxml::LN_Value_doc_ST_CryptProv_rsaAES)
103             , m_sCryptAlgorithmClass("hash")
104             , m_sCryptAlgorithmType("typeAny")
105             , m_CryptSpinCount(0)
106         {
107         }
108 
109         css::uno::Sequence<css::beans::PropertyValue> toSequence() const;
110 
enabledwriterfilter::dmapper::DocumentProtection_Impl111         bool enabled() const
112         {
113             return ! isNone();
114         }
115 
isNonewriterfilter::dmapper::DocumentProtection_Impl116         bool isNone()           const { return m_nEdit == NS_ooxml::LN_Value_doc_ST_DocProtect_none; };
117     };
118 
toSequence() const119     css::uno::Sequence<css::beans::PropertyValue> DocumentProtection_Impl::toSequence() const
120     {
121         std::vector<beans::PropertyValue> documentProtection;
122 
123         if (enabled())
124         {
125             // w:edit
126             {
127                 beans::PropertyValue aValue;
128                 aValue.Name = "edit";
129 
130                 switch (m_nEdit)
131                 {
132                 case NS_ooxml::LN_Value_doc_ST_DocProtect_none:             aValue.Value <<= OUString("none"); break;
133                 case NS_ooxml::LN_Value_doc_ST_DocProtect_readOnly:         aValue.Value <<= OUString("readOnly"); break;
134                 case NS_ooxml::LN_Value_doc_ST_DocProtect_comments:         aValue.Value <<= OUString("comments"); break;
135                 case NS_ooxml::LN_Value_doc_ST_DocProtect_trackedChanges:   aValue.Value <<= OUString("trackedChanges"); break;
136                 case NS_ooxml::LN_Value_doc_ST_DocProtect_forms:            aValue.Value <<= OUString("forms"); break;
137                 default:
138                 {
139 #ifdef DBG_UTIL
140                     TagLogger::getInstance().element("unhandled");
141 #endif
142                 }
143                 }
144 
145                 documentProtection.push_back(aValue);
146             }
147 
148             // w:enforcement
149             if (m_bEnforcement)
150             {
151                 beans::PropertyValue aValue;
152                 aValue.Name = "enforcement";
153                 aValue.Value <<= OUString("1");
154                 documentProtection.push_back(aValue);
155             }
156 
157             // w:formatting
158             if (m_bFormatting)
159             {
160                 beans::PropertyValue aValue;
161                 aValue.Name = "formatting";
162                 aValue.Value <<= OUString("1");
163                 documentProtection.push_back(aValue);
164             }
165 
166             // w:cryptProviderType
167             {
168                 beans::PropertyValue aValue;
169                 aValue.Name = "cryptProviderType";
170                 if (m_nCryptProviderType == NS_ooxml::LN_Value_doc_ST_CryptProv_rsaAES)
171                     aValue.Value <<= OUString("rsaAES");
172                 else if (m_nCryptProviderType == NS_ooxml::LN_Value_doc_ST_CryptProv_rsaFull)
173                     aValue.Value <<= OUString("rsaFull");
174                 documentProtection.push_back(aValue);
175             }
176 
177             // w:cryptAlgorithmClass
178             {
179                 beans::PropertyValue aValue;
180                 aValue.Name = "cryptAlgorithmClass";
181                 aValue.Value <<= m_sCryptAlgorithmClass;
182                 documentProtection.push_back(aValue);
183             }
184 
185             // w:cryptAlgorithmType
186             {
187                 beans::PropertyValue aValue;
188                 aValue.Name = "cryptAlgorithmType";
189                 aValue.Value <<= m_sCryptAlgorithmType;
190                 documentProtection.push_back(aValue);
191             }
192 
193             // w:cryptAlgorithmSid
194             {
195                 beans::PropertyValue aValue;
196                 aValue.Name = "cryptAlgorithmSid";
197                 aValue.Value <<= m_sCryptAlgorithmSid;
198                 documentProtection.push_back(aValue);
199             }
200 
201             // w:cryptSpinCount
202             {
203                 beans::PropertyValue aValue;
204                 aValue.Name = "cryptSpinCount";
205                 aValue.Value <<= OUString::number(m_CryptSpinCount);
206                 documentProtection.push_back(aValue);
207             }
208 
209             // w:hash
210             {
211                 beans::PropertyValue aValue;
212                 aValue.Name = "hash";
213                 aValue.Value <<= m_sHash;
214                 documentProtection.push_back(aValue);
215             }
216 
217             // w:salt
218             {
219                 beans::PropertyValue aValue;
220                 aValue.Name = "salt";
221                 aValue.Value <<= m_sSalt;
222                 documentProtection.push_back(aValue);
223             }
224         }
225 
226         return comphelper::containerToSequence(documentProtection);
227     }
228 
229 struct SettingsTable_Impl
230 {
231     int                 m_nDefaultTabStop;
232 
233     bool                m_bRecordChanges;
234     bool                m_bShowInsDelChanges;
235     bool                m_bShowFormattingChanges;
236     bool                m_bShowMarkupChanges;
237     bool                m_bLinkStyles;
238     sal_Int16           m_nZoomFactor;
239     sal_Int16 m_nZoomType = 0;
240     Id                  m_nView;
241     bool                m_bEvenAndOddHeaders;
242     bool                m_bUsePrinterMetrics;
243     bool                embedTrueTypeFonts;
244     bool                embedSystemFonts;
245     bool                m_bDoNotUseHTMLParagraphAutoSpacing;
246     bool                m_bNoColumnBalance;
247     bool                m_bAutoHyphenation;
248     bool                m_bNoHyphenateCaps;
249     sal_Int16           m_nHyphenationZone;
250     bool                m_bWidowControl;
251     bool                m_bLongerSpaceSequence;
252     bool                m_bSplitPgBreakAndParaMark;
253     bool                m_bMirrorMargin;
254     bool                m_bDoNotExpandShiftReturn;
255     bool                m_bProtectForm;
256     bool                m_bRedlineProtection;
257     OUString            m_sRedlineProtectionKey;
258     bool                m_bDisplayBackgroundShape;
259 
260     uno::Sequence<beans::PropertyValue> m_pThemeFontLangProps;
261 
262     std::vector<beans::PropertyValue> m_aCompatSettings;
263     uno::Sequence<beans::PropertyValue> m_pCurrentCompatSetting;
264     OUString            m_sCurrentDatabaseDataSource;
265 
266     DocumentProtection_Impl m_DocumentProtection;
267 
SettingsTable_Implwriterfilter::dmapper::SettingsTable_Impl268     SettingsTable_Impl() :
269       m_nDefaultTabStop( 720 ) //default is 1/2 in
270     , m_bRecordChanges(false)
271     , m_bShowInsDelChanges(true)
272     , m_bShowFormattingChanges(false)
273     , m_bShowMarkupChanges(true)
274     , m_bLinkStyles(false)
275     , m_nZoomFactor(0)
276     , m_nView(0)
277     , m_bEvenAndOddHeaders(false)
278     , m_bUsePrinterMetrics(false)
279     , embedTrueTypeFonts(false)
280     , embedSystemFonts(false)
281     , m_bDoNotUseHTMLParagraphAutoSpacing(false)
282     , m_bNoColumnBalance(false)
283     , m_bAutoHyphenation(false)
284     , m_bNoHyphenateCaps(false)
285     , m_nHyphenationZone(0)
286     , m_bWidowControl(false)
287     , m_bLongerSpaceSequence(false)
288     , m_bSplitPgBreakAndParaMark(false)
289     , m_bMirrorMargin(false)
290     , m_bDoNotExpandShiftReturn(false)
291     , m_bProtectForm(false)
292     , m_bRedlineProtection(false)
293     , m_sRedlineProtectionKey()
294     , m_bDisplayBackgroundShape(false)
295     , m_pThemeFontLangProps(3)
296     , m_pCurrentCompatSetting(3)
297     {}
298 
299 };
300 
SettingsTable(const DomainMapper & rDomainMapper)301 SettingsTable::SettingsTable(const DomainMapper& rDomainMapper)
302 : LoggedProperties("SettingsTable")
303 , LoggedTable("SettingsTable")
304 , m_pImpl( new SettingsTable_Impl )
305 {
306     if (rDomainMapper.IsRTFImport())
307     {
308         // HTML paragraph auto-spacing is opt-in for RTF, opt-out for OOXML.
309         m_pImpl->m_bDoNotUseHTMLParagraphAutoSpacing = true;
310         // Longer space sequence is opt-in for RTF, and not in OOXML.
311         m_pImpl->m_bLongerSpaceSequence = true;
312     }
313 }
314 
~SettingsTable()315 SettingsTable::~SettingsTable()
316 {
317 }
318 
lcl_attribute(Id nName,Value & val)319 void SettingsTable::lcl_attribute(Id nName, Value & val)
320 {
321     int nIntValue = val.getInt();
322     OUString sStringValue = val.getString();
323 
324     switch(nName)
325     {
326     case NS_ooxml::LN_CT_Zoom_percent:
327         m_pImpl->m_nZoomFactor = nIntValue;
328     break;
329     case NS_ooxml::LN_CT_Zoom_val:
330         m_pImpl->m_nZoomType = lcl_GetZoomType(nIntValue);
331         break;
332     case NS_ooxml::LN_CT_Language_val:
333         m_pImpl->m_pThemeFontLangProps[0].Name = "val";
334         m_pImpl->m_pThemeFontLangProps[0].Value <<= sStringValue;
335         break;
336     case NS_ooxml::LN_CT_Language_eastAsia:
337         m_pImpl->m_pThemeFontLangProps[1].Name = "eastAsia";
338         m_pImpl->m_pThemeFontLangProps[1].Value <<= sStringValue;
339         break;
340     case NS_ooxml::LN_CT_Language_bidi:
341         m_pImpl->m_pThemeFontLangProps[2].Name = "bidi";
342         m_pImpl->m_pThemeFontLangProps[2].Value <<= sStringValue;
343         break;
344     case NS_ooxml::LN_CT_View_val:
345         m_pImpl->m_nView = nIntValue;
346         break;
347     case NS_ooxml::LN_CT_CompatSetting_name:
348         m_pImpl->m_pCurrentCompatSetting[0].Name = "name";
349         m_pImpl->m_pCurrentCompatSetting[0].Value <<= sStringValue;
350         break;
351     case NS_ooxml::LN_CT_CompatSetting_uri:
352         m_pImpl->m_pCurrentCompatSetting[1].Name = "uri";
353         m_pImpl->m_pCurrentCompatSetting[1].Value <<= sStringValue;
354         break;
355     case NS_ooxml::LN_CT_CompatSetting_val:
356         m_pImpl->m_pCurrentCompatSetting[2].Name = "val";
357         m_pImpl->m_pCurrentCompatSetting[2].Value <<= sStringValue;
358         break;
359     case NS_ooxml::LN_CT_DocProtect_edit: // 92037
360         m_pImpl->m_DocumentProtection.m_nEdit = nIntValue;
361         // multiple DocProtect_edits should not exist. If they do, last one wins
362         m_pImpl->m_bRedlineProtection = false;
363         m_pImpl->m_bProtectForm = false;
364         switch (nIntValue)
365         {
366         case NS_ooxml::LN_Value_doc_ST_DocProtect_trackedChanges:
367         {
368             m_pImpl->m_bRedlineProtection = true;
369             m_pImpl->m_sRedlineProtectionKey = m_pImpl->m_DocumentProtection.m_sHash;
370             break;
371         }
372         case NS_ooxml::LN_Value_doc_ST_DocProtect_forms:
373             m_pImpl->m_bProtectForm = true;
374             break;
375         }
376         break;
377     case NS_ooxml::LN_CT_DocProtect_enforcement: // 92039
378         m_pImpl->m_DocumentProtection.m_bEnforcement = (nIntValue != 0);
379         switch (m_pImpl->m_DocumentProtection.m_nEdit)
380         {
381         case NS_ooxml::LN_Value_doc_ST_DocProtect_trackedChanges:
382             m_pImpl->m_bRedlineProtection = (nIntValue != 0);
383             break;
384         case NS_ooxml::LN_Value_doc_ST_DocProtect_forms:
385             m_pImpl->m_bProtectForm = (nIntValue != 0);
386             break;
387         }
388         break;
389     case NS_ooxml::LN_CT_DocProtect_formatting: // 92038
390         m_pImpl->m_DocumentProtection.m_bFormatting = (nIntValue != 0);
391         break;
392     case NS_ooxml::LN_AG_Password_cryptProviderType: // 92025
393         m_pImpl->m_DocumentProtection.m_nCryptProviderType = nIntValue;
394         break;
395     case NS_ooxml::LN_AG_Password_cryptAlgorithmClass: // 92026
396         if (nIntValue == NS_ooxml::LN_Value_doc_ST_AlgClass_hash) // 92023
397             m_pImpl->m_DocumentProtection.m_sCryptAlgorithmClass = "hash";
398         break;
399     case NS_ooxml::LN_AG_Password_cryptAlgorithmType: // 92027
400         if (nIntValue == NS_ooxml::LN_Value_doc_ST_AlgType_typeAny) // 92024
401             m_pImpl->m_DocumentProtection.m_sCryptAlgorithmType = "typeAny";
402         break;
403     case NS_ooxml::LN_AG_Password_cryptAlgorithmSid: // 92028
404         m_pImpl->m_DocumentProtection.m_sCryptAlgorithmSid = sStringValue;
405         break;
406     case NS_ooxml::LN_AG_Password_cryptSpinCount: // 92029
407         m_pImpl->m_DocumentProtection.m_CryptSpinCount = nIntValue;
408         break;
409     case NS_ooxml::LN_AG_Password_hash: // 92035
410         m_pImpl->m_DocumentProtection.m_sHash = sStringValue;
411         break;
412     case NS_ooxml::LN_AG_Password_salt: // 92036
413         m_pImpl->m_DocumentProtection.m_sSalt = sStringValue;
414         break;
415     case NS_ooxml::LN_CT_TrackChangesView_insDel:
416         m_pImpl->m_bShowInsDelChanges = (nIntValue != 0);
417         break;
418     case NS_ooxml::LN_CT_TrackChangesView_formatting:
419         m_pImpl->m_bShowFormattingChanges = (nIntValue != 0);
420         break;
421     case NS_ooxml::LN_CT_TrackChangesView_markup:
422         m_pImpl->m_bShowMarkupChanges = (nIntValue != 0);
423         break;
424     default:
425     {
426 #ifdef DBG_UTIL
427         TagLogger::getInstance().element("unhandled");
428 #endif
429     }
430     }
431 }
432 
lcl_sprm(Sprm & rSprm)433 void SettingsTable::lcl_sprm(Sprm& rSprm)
434 {
435     sal_uInt32 nSprmId = rSprm.getId();
436 
437     Value::Pointer_t pValue = rSprm.getValue();
438     sal_Int32 nIntValue = pValue->getInt();
439 
440     switch(nSprmId)
441     {
442     case NS_ooxml::LN_CT_Settings_zoom: //  92469;
443     case NS_ooxml::LN_CT_Settings_proofState: //  92489;
444     case NS_ooxml::LN_CT_Settings_attachedTemplate: //  92491;
445     case NS_ooxml::LN_CT_Settings_hdrShapeDefaults: //  92544;
446     case NS_ooxml::LN_CT_Settings_footnotePr: //  92545;
447     case NS_ooxml::LN_CT_Settings_endnotePr: //  92546;
448     case NS_ooxml::LN_CT_Settings_compat: //  92547;
449     case NS_ooxml::LN_CT_Settings_themeFontLang: //  92552;
450     case NS_ooxml::LN_CT_Settings_shapeDefaults: //  92560;
451     case NS_ooxml::LN_CT_Settings_view:
452     //PropertySetValues - need to be resolved
453     {
454         resolveSprmProps(*this, rSprm);
455     }
456     break;
457     case NS_ooxml::LN_CT_Settings_stylePaneFormatFilter: // 92493;
458     break;
459     case NS_ooxml::LN_CT_Settings_defaultTabStop: //  92505;
460     m_pImpl->m_nDefaultTabStop = nIntValue;
461     break;
462     case NS_ooxml::LN_CT_Settings_linkStyles: // 92663;
463     m_pImpl->m_bLinkStyles = nIntValue;
464     break;
465     case NS_ooxml::LN_CT_Settings_evenAndOddHeaders:
466     m_pImpl->m_bEvenAndOddHeaders = nIntValue;
467     break;
468     case NS_ooxml::LN_CT_Settings_noPunctuationKerning: //  92526;
469     break;
470     case NS_ooxml::LN_CT_Settings_characterSpacingControl: //  92527;
471      // doNotCompress, compressPunctuation, compressPunctuationAndJapaneseKana
472     break;
473     case NS_ooxml::LN_CT_Settings_doNotIncludeSubdocsInStats: //  92554; // Do Not Include Content in Text Boxes, Footnotes, and Endnotes in Document Statistics)
474     break;
475     case NS_ooxml::LN_CT_Settings_decimalSymbol: //  92562;
476     break;
477     case NS_ooxml::LN_CT_Settings_listSeparator: //  92563;
478     break;
479     case NS_ooxml::LN_CT_Settings_rsids: //  92549; revision save Ids - probably not necessary
480     break;
481     case NS_ooxml::LN_CT_Settings_hyphenationZone: // 92508;
482         m_pImpl->m_nHyphenationZone = nIntValue;
483     break;
484     case NS_ooxml::LN_CT_Compat_useFELayout: // 92422;
485     // useFELayout (Do Not Bypass East Asian/Complex Script Layout Code - support of old versions of Word - ignored)
486     break;
487     case NS_ooxml::LN_CT_Settings_trackRevisions:
488     {
489         m_pImpl->m_bRecordChanges = bool(rSprm.getValue( )->getInt( ) );
490     }
491     break;
492     case NS_ooxml::LN_CT_Settings_revisionView:
493         resolveSprmProps(*this, rSprm);
494         break;
495     case NS_ooxml::LN_CT_Settings_documentProtection:
496         resolveSprmProps(*this, rSprm);
497         break;
498     case NS_ooxml::LN_CT_Compat_usePrinterMetrics:
499         m_pImpl->m_bUsePrinterMetrics = nIntValue;
500         break;
501     case NS_ooxml::LN_CT_Settings_embedTrueTypeFonts:
502         m_pImpl->embedTrueTypeFonts = nIntValue != 0;
503         break;
504     case NS_ooxml::LN_CT_Settings_embedSystemFonts:
505         m_pImpl->embedSystemFonts = nIntValue != 0;
506         break;
507     case NS_ooxml::LN_CT_Compat_doNotUseHTMLParagraphAutoSpacing:
508         m_pImpl->m_bDoNotUseHTMLParagraphAutoSpacing = nIntValue;
509         break;
510     case NS_ooxml::LN_CT_Compat_splitPgBreakAndParaMark:
511         m_pImpl->m_bSplitPgBreakAndParaMark = nIntValue;
512         break;
513     case NS_ooxml::LN_CT_Settings_mirrorMargins:
514         m_pImpl->m_bMirrorMargin = nIntValue;
515         break;
516     case NS_ooxml::LN_CT_Settings_mailMerge:
517     {
518         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
519         if (pProperties.get())
520             pProperties->resolve(*this);
521     }
522     break;
523     case NS_ooxml::LN_CT_MailMerge_query:
524     {
525         // try to get the "database.table" name from the query saved previously
526         OUString sVal = pValue->getString();
527         if ( sVal.endsWith("$") && sVal.indexOf(".dbo.") > 0 )
528         {
529             sal_Int32 nSpace = sVal.lastIndexOf(' ');
530             sal_Int32 nDbo = sVal.lastIndexOf(".dbo.");
531             if ( nSpace > 0 && nSpace < nDbo - 1 )
532             {
533                 m_pImpl->m_sCurrentDatabaseDataSource = sVal.copy(nSpace + 1, nDbo - nSpace - 1) +
534                             sVal.copy(nDbo + 4, sVal.getLength() - nDbo - 5);
535             }
536         }
537     }
538     break;
539     case NS_ooxml::LN_CT_Compat_compatSetting:
540     {
541         writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
542         if (pProperties.get())
543         {
544             pProperties->resolve(*this);
545 
546             beans::PropertyValue aValue;
547             aValue.Name = "compatSetting";
548             aValue.Value <<= m_pImpl->m_pCurrentCompatSetting;
549             m_pImpl->m_aCompatSettings.push_back(aValue);
550         }
551     }
552     break;
553     case NS_ooxml::LN_CT_Compat_noColumnBalance:
554         m_pImpl->m_bNoColumnBalance = nIntValue;
555         break;
556     case NS_ooxml::LN_CT_Settings_autoHyphenation:
557         m_pImpl->m_bAutoHyphenation = nIntValue;
558         break;
559     case NS_ooxml::LN_CT_Settings_doNotHyphenateCaps:
560         m_pImpl->m_bNoHyphenateCaps = nIntValue;
561         break;
562     case NS_ooxml::LN_CT_Settings_widowControl:
563         m_pImpl->m_bWidowControl = nIntValue;
564         break;
565     case NS_ooxml::LN_CT_Settings_longerSpaceSequence:
566         m_pImpl->m_bLongerSpaceSequence = nIntValue;
567         break;
568     case NS_ooxml::LN_CT_Compat_doNotExpandShiftReturn:
569         m_pImpl->m_bDoNotExpandShiftReturn = true;
570         break;
571     case NS_ooxml::LN_CT_Settings_displayBackgroundShape:
572         m_pImpl->m_bDisplayBackgroundShape = nIntValue;
573         break;
574     default:
575     {
576 #ifdef DBG_UTIL
577         TagLogger::getInstance().element("unhandled");
578 #endif
579     }
580     }
581 }
582 
lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref)583 void SettingsTable::lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref)
584 {
585     ref->resolve(*this);
586 }
587 
588 //returns default TabStop in 1/100th mm
GetDefaultTabStop() const589 int SettingsTable::GetDefaultTabStop() const
590 {
591     return ConversionHelper::convertTwipToMM100( m_pImpl->m_nDefaultTabStop );
592 }
593 
GetLinkStyles() const594 bool SettingsTable::GetLinkStyles() const
595 {
596     return m_pImpl->m_bLinkStyles;
597 }
598 
GetZoomFactor() const599 sal_Int16 SettingsTable::GetZoomFactor() const
600 {
601     return m_pImpl->m_nZoomFactor;
602 }
603 
GetZoomType() const604 sal_Int16 SettingsTable::GetZoomType() const { return m_pImpl->m_nZoomType; }
605 
GetView() const606 Id SettingsTable::GetView() const
607 {
608     return m_pImpl->m_nView;
609 }
610 
GetUsePrinterMetrics() const611 bool SettingsTable::GetUsePrinterMetrics() const
612 {
613     return m_pImpl->m_bUsePrinterMetrics;
614 }
615 
GetEvenAndOddHeaders() const616 bool SettingsTable::GetEvenAndOddHeaders() const
617 {
618     return m_pImpl->m_bEvenAndOddHeaders;
619 }
620 
GetEmbedTrueTypeFonts() const621 bool SettingsTable::GetEmbedTrueTypeFonts() const
622 {
623     return m_pImpl->embedTrueTypeFonts;
624 }
625 
GetEmbedSystemFonts() const626 bool SettingsTable::GetEmbedSystemFonts() const
627 {
628     return m_pImpl->embedSystemFonts;
629 }
630 
GetDoNotUseHTMLParagraphAutoSpacing() const631 bool SettingsTable::GetDoNotUseHTMLParagraphAutoSpacing() const
632 {
633     return m_pImpl->m_bDoNotUseHTMLParagraphAutoSpacing;
634 }
635 
GetNoColumnBalance() const636 bool SettingsTable::GetNoColumnBalance() const
637 {
638     return m_pImpl->m_bNoColumnBalance;
639 }
640 
GetSplitPgBreakAndParaMark() const641 bool SettingsTable::GetSplitPgBreakAndParaMark() const
642 {
643     return m_pImpl->m_bSplitPgBreakAndParaMark;
644 }
645 
GetMirrorMarginSettings() const646 bool SettingsTable::GetMirrorMarginSettings() const
647 {
648     return m_pImpl->m_bMirrorMargin;
649 }
650 
GetDisplayBackgroundShape() const651 bool SettingsTable::GetDisplayBackgroundShape() const
652 {
653     return m_pImpl->m_bDisplayBackgroundShape;
654 }
655 
GetDoNotExpandShiftReturn() const656 bool SettingsTable::GetDoNotExpandShiftReturn() const
657 {
658     return m_pImpl->m_bDoNotExpandShiftReturn;
659 }
660 
GetProtectForm() const661 bool SettingsTable::GetProtectForm() const
662 {
663     return m_pImpl->m_bProtectForm;
664 }
665 
GetNoHyphenateCaps() const666 bool SettingsTable::GetNoHyphenateCaps() const
667 {
668     return m_pImpl->m_bNoHyphenateCaps;
669 }
670 
GetHypenationZone() const671 sal_Int16 SettingsTable::GetHypenationZone() const
672 {
673     return m_pImpl->m_nHyphenationZone;
674 }
675 
GetThemeFontLangProperties() const676 uno::Sequence<beans::PropertyValue> const & SettingsTable::GetThemeFontLangProperties() const
677 {
678     return m_pImpl->m_pThemeFontLangProps;
679 }
680 
GetCompatSettings() const681 uno::Sequence<beans::PropertyValue> SettingsTable::GetCompatSettings() const
682 {
683     return comphelper::containerToSequence(m_pImpl->m_aCompatSettings);
684 }
685 
GetDocumentProtectionSettings() const686 css::uno::Sequence<css::beans::PropertyValue> SettingsTable::GetDocumentProtectionSettings() const
687 {
688     return m_pImpl->m_DocumentProtection.toSequence();
689 }
690 
GetCurrentDatabaseDataSource() const691 const OUString & SettingsTable::GetCurrentDatabaseDataSource() const
692 {
693     return m_pImpl->m_sCurrentDatabaseDataSource;
694 }
695 
lcl_isDefault(const uno::Reference<beans::XPropertyState> & xPropertyState,const OUString & rPropertyName)696 static bool lcl_isDefault(const uno::Reference<beans::XPropertyState>& xPropertyState, const OUString& rPropertyName)
697 {
698     return xPropertyState->getPropertyState(rPropertyName) == beans::PropertyState_DEFAULT_VALUE;
699 }
700 
ApplyProperties(uno::Reference<text::XTextDocument> const & xDoc)701 void SettingsTable::ApplyProperties(uno::Reference<text::XTextDocument> const& xDoc)
702 {
703     uno::Reference< beans::XPropertySet> xDocProps( xDoc, uno::UNO_QUERY );
704 
705     if (GetWordCompatibilityMode() <= 14)
706     {
707         uno::Reference<lang::XMultiServiceFactory> xTextFactory(xDoc, uno::UNO_QUERY_THROW);
708         uno::Reference<beans::XPropertySet> xDocumentSettings(xTextFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY_THROW);
709         xDocumentSettings->setPropertyValue("MsWordCompMinLineHeightByFly", uno::makeAny(true));
710     }
711 
712     // Show changes value
713     if (xDocProps.is())
714     {
715         bool bHideChanges = !m_pImpl->m_bShowInsDelChanges || !m_pImpl->m_bShowMarkupChanges;
716         xDocProps->setPropertyValue("ShowChanges", uno::makeAny( !bHideChanges || m_pImpl->m_bShowFormattingChanges ) );
717     }
718 
719     // Record changes value
720     if (xDocProps.is())
721     {
722         xDocProps->setPropertyValue("RecordChanges", uno::makeAny( m_pImpl->m_bRecordChanges ) );
723         // Password protected Record changes
724         if ( m_pImpl->m_bRecordChanges && m_pImpl->m_bRedlineProtection )
725         {
726             // use dummy protection key to forbid disabling of Record changes without a notice
727             // (extending the recent GrabBag support)    TODO support password verification...
728             css::uno::Sequence<sal_Int8> aDummyKey(1);
729             aDummyKey[0] = 1;
730             xDocProps->setPropertyValue("RedlineProtectionKey", uno::makeAny( aDummyKey ));
731         }
732     }
733 
734     // Auto hyphenation: turns on hyphenation by default, <w:suppressAutoHyphens/> may still disable it at a paragraph level.
735     // Situation is similar for RTF_WIDOWCTRL, which turns on widow / orphan control by default.
736     if (m_pImpl->m_bAutoHyphenation || m_pImpl->m_bNoHyphenateCaps || m_pImpl->m_bWidowControl)
737     {
738         uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(xDoc, uno::UNO_QUERY);
739         if (!xStyleFamiliesSupplier.is())
740             return;
741 
742         uno::Reference<container::XNameAccess> xStyleFamilies = xStyleFamiliesSupplier->getStyleFamilies();
743         uno::Reference<container::XNameContainer> xParagraphStyles = xStyleFamilies->getByName("ParagraphStyles").get< uno::Reference<container::XNameContainer> >();
744         uno::Reference<style::XStyle> xDefault = xParagraphStyles->getByName("Standard").get< uno::Reference<style::XStyle> >();
745         uno::Reference<beans::XPropertyState> xPropertyState(xDefault, uno::UNO_QUERY);
746         if (m_pImpl->m_bAutoHyphenation && lcl_isDefault(xPropertyState, "ParaIsHyphenation"))
747         {
748             uno::Reference<beans::XPropertySet> xPropertySet(xDefault, uno::UNO_QUERY);
749             xPropertySet->setPropertyValue("ParaIsHyphenation", uno::makeAny(true));
750         }
751         if (m_pImpl->m_bNoHyphenateCaps)
752         {
753             uno::Reference<beans::XPropertySet> xPropertySet(xDefault, uno::UNO_QUERY);
754             xPropertySet->setPropertyValue("ParaHyphenationNoCaps", uno::makeAny(true));
755         }
756         if (m_pImpl->m_bWidowControl && lcl_isDefault(xPropertyState, "ParaWidows") && lcl_isDefault(xPropertyState, "ParaOrphans"))
757         {
758             uno::Reference<beans::XPropertySet> xPropertySet(xDefault, uno::UNO_QUERY);
759             uno::Any aAny = uno::makeAny(static_cast<sal_Int8>(2));
760             xPropertySet->setPropertyValue("ParaWidows", aAny);
761             xPropertySet->setPropertyValue("ParaOrphans", aAny);
762         }
763     }
764 }
765 
GetWordCompatibilityMode() const766 sal_Int32 SettingsTable::GetWordCompatibilityMode() const
767 {
768     for (const auto& rProp : m_pImpl->m_aCompatSettings)
769     {
770         if (rProp.Name == "compatSetting")
771         {
772             css::uno::Sequence<css::beans::PropertyValue> aCurrentCompatSettings;
773             rProp.Value >>= aCurrentCompatSettings;
774 
775             OUString sName;
776             OUString sUri;
777             OUString sVal;
778 
779             aCurrentCompatSettings[0].Value >>= sName;
780             aCurrentCompatSettings[1].Value >>= sUri;
781             aCurrentCompatSettings[2].Value >>= sVal;
782 
783             if (sName == "compatibilityMode" && sUri == "http://schemas.microsoft.com/office/word")
784             {
785                 return sVal.toInt32();
786             }
787         }
788     }
789 
790     return -1; // Word compatibility mode not found
791 }
792 
GetLongerSpaceSequence() const793 bool SettingsTable::GetLongerSpaceSequence() const
794 {
795     return m_pImpl->m_bLongerSpaceSequence;
796 }
797 
798 }//namespace dmapper
799 } //namespace writerfilter
800 
801 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
802