1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
23 * export of all variable related text fields (and database display field)
25 #include <txtvfldi.hxx>
26 #include <xmloff/xmltoken.hxx>
27 #include <xmloff/txtimp.hxx>
28 #include <xmloff/xmlnamespace.hxx>
29 #include <xmloff/namespacemap.hxx>
30 #include <xmloff/i18nmap.hxx>
31 #include <xmloff/xmlimp.hxx>
32 #include <xmloff/xmluconv.hxx>
33 #include <xmloff/xmlement.hxx>
34 #include <com/sun/star/frame/XModel.hpp>
35 #include <com/sun/star/text/SetVariableType.hpp>
36 #include <com/sun/star/text/XDependentTextField.hpp>
37 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/beans/XPropertySetInfo.hpp>
40 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 #include <com/sun/star/style/NumberingType.hpp>
42 #include <com/sun/star/container/XIndexReplace.hpp>
44 #include <sax/tools/converter.hxx>
46 #include <rtl/ustring.hxx>
47 #include <osl/diagnose.h>
48 #include <sal/log.hxx>
50 #include <tools/debug.hxx>
51 #include <comphelper/diagnose_ex.hxx>
55 constexpr char16_t sAPI_fieldmaster_prefix
[] = u
"com.sun.star.text.FieldMaster.";
56 constexpr OUString sAPI_get_expression
= u
"GetExpression"_ustr
;
57 constexpr OUString sAPI_set_expression
= u
"SetExpression"_ustr
;
58 constexpr OUString sAPI_user
= u
"User"_ustr
;
59 constexpr OUString sAPI_database
= u
"com.sun.star.text.TextField.Database"_ustr
;
62 constexpr OUString sAPI_content
= u
"Content"_ustr
;
63 constexpr OUString sAPI_sub_type
= u
"SubType"_ustr
;
64 constexpr OUString sAPI_number_format
= u
"NumberFormat"_ustr
;
65 constexpr OUString sAPI_is_visible
= u
"IsVisible"_ustr
;
66 constexpr OUString sAPI_current_presentation
= u
"CurrentPresentation"_ustr
;
69 using namespace ::com::sun::star
;
70 using namespace ::com::sun::star::uno
;
71 using namespace ::com::sun::star::beans
;
72 using namespace ::com::sun::star::text
;
73 using namespace ::com::sun::star::style
;
74 using namespace ::xmloff::token
;
77 // XMLVarFieldImportContext: superclass for all variable related fields
80 XMLVarFieldImportContext::XMLVarFieldImportContext(
81 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
,
82 const OUString
& pServiceName
,
83 bool bFormula
, bool bFormulaDefault
,
84 bool bDescription
, bool bHelp
, bool bHint
, bool bVisible
,
85 bool bIsDisplayFormula
,
86 bool bType
, bool bStyle
, bool bValue
,
88 XMLTextFieldImportContext(rImport
, rHlp
, pServiceName
),
89 aValueHelper(rImport
, rHlp
, bType
, bStyle
, bValue
, false),
90 bDisplayFormula(false),
93 bDescriptionOK(false),
97 bSetFormula(bFormula
),
98 bSetFormulaDefault(bFormulaDefault
),
99 bSetDescription(bDescription
),
102 bSetVisible(bVisible
),
103 bSetDisplayFormula(bIsDisplayFormula
),
104 bSetPresentation(bPresentation
)
108 void XMLVarFieldImportContext::ProcessAttribute(
109 sal_Int32 nAttrToken
,
110 std::string_view sAttrValue
)
114 case XML_ELEMENT(TEXT
, XML_NAME
):
115 sName
= OUString::fromUtf8(sAttrValue
);
116 bValid
= true; // we assume: field with name is valid!
118 case XML_ELEMENT(TEXT
, XML_DESCRIPTION
):
119 sDescription
= OUString::fromUtf8(sAttrValue
);
120 bDescriptionOK
= true;
122 case XML_ELEMENT(TEXT
, XML_HELP
):
123 sHelp
= OUString::fromUtf8(sAttrValue
);
126 case XML_ELEMENT(TEXT
, XML_HINT
):
127 sHint
= OUString::fromUtf8(sAttrValue
);
130 case XML_ELEMENT(TEXT
, XML_FORMULA
):
133 sal_uInt16 nPrefix
= GetImport().GetNamespaceMap().
134 GetKeyByAttrValueQName(OUString::fromUtf8(sAttrValue
), &sTmp
);
135 if( XML_NAMESPACE_OOOW
== nPrefix
)
141 sFormula
= OUString::fromUtf8(sAttrValue
);
144 case XML_ELEMENT(TEXT
, XML_DISPLAY
):
145 if (IsXMLToken(sAttrValue
, XML_FORMULA
))
147 bDisplayFormula
= true;
148 bDisplayNone
= false;
151 else if (IsXMLToken(sAttrValue
, XML_VALUE
))
153 bDisplayFormula
= false;
154 bDisplayNone
= false;
157 else if (IsXMLToken(sAttrValue
, XML_NONE
))
159 bDisplayFormula
= false;
163 DBG_ASSERT(!(bDisplayFormula
&& bDisplayNone
),
164 "illegal display values");
167 // delegate all others to value helper
168 aValueHelper
.ProcessAttribute(nAttrToken
, sAttrValue
);
173 void XMLVarFieldImportContext::PrepareField(
174 const Reference
<XPropertySet
> & xPropertySet
)
176 // bSetName: not implemented
180 if (!bFormulaOK
&& bSetFormulaDefault
)
182 sFormula
= GetContent();
188 xPropertySet
->setPropertyValue(sAPI_content
, Any(sFormula
));
192 if (bSetDescription
&& bDescriptionOK
)
194 xPropertySet
->setPropertyValue(u
"Hint"_ustr
, Any(sDescription
));
197 if (bSetHelp
&& bHelpOK
)
199 xPropertySet
->setPropertyValue(u
"Help"_ustr
, Any(sHelp
));
202 if (bSetHint
&& bHintOK
)
204 xPropertySet
->setPropertyValue(u
"Tooltip"_ustr
, Any(sHint
));
207 if (bSetVisible
&& bDisplayOK
)
209 bool bTmp
= !bDisplayNone
;
210 xPropertySet
->setPropertyValue(sAPI_is_visible
, Any(bTmp
));
213 // workaround for #no-bug#: display formula by default
214 if (xPropertySet
->getPropertySetInfo()->
215 hasPropertyByName(u
"IsShowFormula"_ustr
) &&
218 bDisplayFormula
= false;
219 bSetDisplayFormula
= true;
223 if (bSetDisplayFormula
)
225 bool bTmp
= bDisplayFormula
&& bDisplayOK
;
226 xPropertySet
->setPropertyValue(u
"IsShowFormula"_ustr
, Any(bTmp
));
229 // delegate to value helper
230 aValueHelper
.SetDefault(GetContent());
231 aValueHelper
.PrepareField(xPropertySet
);
233 // finally, set the current presentation
234 if (bSetPresentation
)
237 aAny
<<= GetContent();
238 xPropertySet
->setPropertyValue(sAPI_current_presentation
, aAny
);
243 // variable set fields
246 XMLSetVarFieldImportContext::XMLSetVarFieldImportContext(
247 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
,
248 const OUString
& pServiceName
, VarType eVarType
,
249 bool bFormula
, bool bFormulaDefault
,
250 bool bDescription
, bool bHelp
, bool bHint
, bool bVisible
, bool bIsDisplayFormula
,
251 bool bType
, bool bStyle
, bool bValue
, bool bPresentation
) :
252 XMLVarFieldImportContext(rImport
, rHlp
, pServiceName
,
253 bFormula
, bFormulaDefault
,
254 bDescription
, bHelp
, bHint
, bVisible
, bIsDisplayFormula
,
255 bType
, bStyle
, bValue
, bPresentation
),
260 void XMLSetVarFieldImportContext::endFastElement(sal_Int32
)
262 // should we call PrepareField on the field, or rather on it's master?
263 // currently: call on field (just like superclass)
264 // possible alternatives: call on master
265 // call field or master depending on variable
266 // PrepareMaster() in addition to PrepareField()
268 DBG_ASSERT(!GetServiceName().isEmpty(), "no service name for element!");
272 DBG_ASSERT(!GetName().isEmpty(), "variable name needed!");
275 Reference
<XPropertySet
> xMaster
;
276 if (FindFieldMaster(xMaster
))
278 // create field/Service
279 Reference
<XPropertySet
> xPropSet
;
280 if (CreateField(xPropSet
, "com.sun.star.text.TextField." + GetServiceName()))
282 Reference
<XDependentTextField
> xDepTextField(xPropSet
, UNO_QUERY
);
283 if (xDepTextField
.is())
285 // attach field to field master
286 xDepTextField
->attachTextFieldMaster(xMaster
);
288 // attach field to document
289 Reference
<XTextContent
> xTextContent(xPropSet
, UNO_QUERY
);
290 if (xTextContent
.is())
293 // insert, set field properties and exit!
294 GetImportHelper().InsertTextContent(xTextContent
);
295 PrepareField(xPropSet
);
296 } catch (lang::IllegalArgumentException
& /*e*/)
298 // ignore e: #i54023#
307 // above: exit on success; so for all error cases we end up here!
308 // write element content
309 GetImportHelper().InsertString(GetContent());
312 bool XMLSetVarFieldImportContext::FindFieldMaster(
313 Reference
<XPropertySet
> & xMaster
)
315 // currently: delegate to XMLVariableDeclImportContext;
316 // should eventually go here
317 return XMLVariableDeclImportContext::FindFieldMaster(xMaster
,
328 XMLSequenceFieldImportContext::XMLSequenceFieldImportContext(
329 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
330 XMLSetVarFieldImportContext(rImport
, rHlp
, sAPI_set_expression
,
334 false, false, false, false,
336 false, false, false, true),
338 sNumFormat(OUString('1')),
339 sNumFormatSync(GetXMLToken(XML_FALSE
)),
344 void XMLSequenceFieldImportContext::ProcessAttribute(
345 sal_Int32 nAttrToken
, std::string_view sAttrValue
)
349 case XML_ELEMENT(STYLE
, XML_NUM_FORMAT
):
350 sNumFormat
= OUString::fromUtf8(sAttrValue
);
352 case XML_ELEMENT(STYLE
, XML_NUM_LETTER_SYNC
):
353 sNumFormatSync
= OUString::fromUtf8(sAttrValue
);
355 case XML_ELEMENT(TEXT
, XML_REF_NAME
):
356 sRefName
= OUString::fromUtf8(sAttrValue
);
360 // delegate to super class (name, formula)
361 XMLSetVarFieldImportContext::ProcessAttribute(nAttrToken
,
367 void XMLSequenceFieldImportContext::PrepareField(
368 const Reference
<XPropertySet
> & xPropertySet
)
370 // delegate to super class (formula)
371 XMLSetVarFieldImportContext::PrepareField(xPropertySet
);
374 sal_Int16 nNumType
= NumberingType::ARABIC
;
375 GetImport().GetMM100UnitConverter().convertNumFormat( nNumType
, sNumFormat
, sNumFormatSync
);
376 xPropertySet
->setPropertyValue(sAPI_number_format
, Any(nNumType
));
378 // handle reference name
381 Any aAny
= xPropertySet
->getPropertyValue(u
"SequenceValue"_ustr
);
382 sal_Int16 nValue
= 0;
384 GetImportHelper().InsertSequenceID(sRefName
, GetName(), nValue
);
389 // variable set field
392 XMLVariableSetFieldImportContext::XMLVariableSetFieldImportContext(
393 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
394 XMLSetVarFieldImportContext(rImport
, rHlp
, sAPI_set_expression
,
396 // formula, value&type, style,
406 void XMLVariableSetFieldImportContext::PrepareField(
407 const Reference
<XPropertySet
> & xPropertySet
)
411 aAny
<<= (IsStringValue()? SetVariableType::STRING
: SetVariableType::VAR
);
412 xPropertySet
->setPropertyValue(sAPI_sub_type
, aAny
);
414 // the remainder is handled by super class
415 XMLSetVarFieldImportContext::PrepareField(xPropertySet
);
419 // variable input field
422 XMLVariableInputFieldImportContext::XMLVariableInputFieldImportContext(
423 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
424 XMLSetVarFieldImportContext(rImport
, rHlp
, sAPI_set_expression
,
426 // description, display none/formula,
427 // value&type, style, formula
436 void XMLVariableInputFieldImportContext::PrepareField(
437 const Reference
<XPropertySet
> & xPropertySet
)
439 // set type (input field)
441 xPropertySet
->setPropertyValue(u
"Input"_ustr
, Any(true));
444 aAny
<<= (IsStringValue()? SetVariableType::STRING
: SetVariableType::VAR
);
445 xPropertySet
->setPropertyValue(sAPI_sub_type
, aAny
);
447 // the remainder is handled by super class
448 XMLSetVarFieldImportContext::PrepareField(xPropertySet
);
455 XMLUserFieldImportContext::XMLUserFieldImportContext(
456 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
457 XMLSetVarFieldImportContext(rImport
, rHlp
, sAPI_user
,
459 // display none/formula, style
461 false, false, false, true,
472 // bug: doesn't work (SO API lacking)
473 XMLUserFieldInputImportContext::XMLUserFieldInputImportContext(
474 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
475 XMLVarFieldImportContext(rImport
, rHlp
, u
"InputUser"_ustr
,
476 // description, style
480 false /*???*/, true, false,
485 void XMLUserFieldInputImportContext::PrepareField(
486 const Reference
<XPropertySet
> & xPropertySet
)
488 xPropertySet
->setPropertyValue(sAPI_content
, Any(GetName()));
490 // delegate to super class
491 XMLVarFieldImportContext::PrepareField(xPropertySet
);
495 // variable get field
498 XMLVariableGetFieldImportContext::XMLVariableGetFieldImportContext(
499 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
500 XMLVarFieldImportContext(rImport
, rHlp
, sAPI_get_expression
,
501 // style, display formula
510 void XMLVariableGetFieldImportContext::PrepareField(
511 const Reference
<XPropertySet
> & xPropertySet
)
514 xPropertySet
->setPropertyValue(sAPI_content
, Any(GetName()));
516 // the remainder is handled by super class
517 XMLVarFieldImportContext::PrepareField(xPropertySet
);
524 XMLExpressionFieldImportContext::XMLExpressionFieldImportContext(
525 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
526 XMLVarFieldImportContext(rImport
, rHlp
, sAPI_get_expression
,
527 // formula, type, style, display formula
534 bValid
= true; // always valid
538 void XMLExpressionFieldImportContext::PrepareField(
539 const Reference
<XPropertySet
> & xPropertySet
)
541 xPropertySet
->setPropertyValue(sAPI_sub_type
, Any(sal_Int16(SetVariableType::FORMULA
)));
543 // delegate to super class
544 XMLVarFieldImportContext::PrepareField(xPropertySet
);
551 XMLTextInputFieldImportContext::XMLTextInputFieldImportContext(
552 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
553 XMLVarFieldImportContext(rImport
, rHlp
, u
"Input"_ustr
,
561 bValid
= true; // always valid
564 void XMLTextInputFieldImportContext::PrepareField(
565 const Reference
<XPropertySet
> & xPropertySet
)
567 XMLVarFieldImportContext::PrepareField(xPropertySet
);
569 xPropertySet
->setPropertyValue(sAPI_content
, Any(GetContent()));
573 // table formula field
576 XMLTableFormulaImportContext::XMLTableFormulaImportContext(
577 SvXMLImport
& rImport
,
578 XMLTextImportHelper
& rHlp
) :
579 XMLTextFieldImportContext(rImport
, rHlp
, u
"TableFormula"_ustr
),
580 aValueHelper(rImport
, rHlp
, false, true, false, true),
581 bIsShowFormula(false)
585 void XMLTableFormulaImportContext::ProcessAttribute(
586 sal_Int32 nAttrToken
,
587 std::string_view sAttrValue
)
591 case XML_ELEMENT(TEXT
, XML_FORMULA
):
592 aValueHelper
.ProcessAttribute( nAttrToken
, sAttrValue
);
593 bValid
= true; // we need a formula!
596 case XML_ELEMENT(STYLE
, XML_DATA_STYLE_NAME
):
597 aValueHelper
.ProcessAttribute( nAttrToken
, sAttrValue
);
599 case XML_ELEMENT(TEXT
, XML_DISPLAY
):
600 if ( sAttrValue
== "formula" )
601 bIsShowFormula
= true;
604 // unknown attribute -> ignore
605 XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken
, sAttrValue
);
610 void XMLTableFormulaImportContext::PrepareField(
611 const Reference
<XPropertySet
> & xPropertySet
)
613 // set format and formula
614 aValueHelper
.PrepareField( xPropertySet
);
618 // set 'show formula' and presentation
619 xPropertySet
->setPropertyValue( u
"IsShowFormula"_ustr
, Any(bIsShowFormula
) );
621 aAny
<<= GetContent();
622 xPropertySet
->setPropertyValue( u
"CurrentPresentation"_ustr
, aAny
);
626 // variable declarations
628 // Should be adapted to XMLVarField-/XMLSetVarFieldImportContext scheme!
631 // declaration container import (<variable/user-field/sequence-decls>)
634 XMLVariableDeclsImportContext::XMLVariableDeclsImportContext(
635 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
, enum VarType eVarType
) :
636 SvXMLImportContext(rImport
),
637 eVarDeclsContextType(eVarType
),
642 css::uno::Reference
< css::xml::sax::XFastContextHandler
> XMLVariableDeclsImportContext::createFastChildContext(
644 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
646 if( IsTokenInNamespace(nElement
, XML_NAMESPACE_TEXT
) )
648 enum XMLTokenEnum eElementName
;
649 switch (eVarDeclsContextType
)
651 case VarTypeSequence
:
652 eElementName
= XML_SEQUENCE_DECL
;
655 eElementName
= XML_VARIABLE_DECL
;
657 case VarTypeUserField
:
658 eElementName
= XML_USER_FIELD_DECL
;
661 OSL_FAIL("unknown field type!");
662 eElementName
= XML_SEQUENCE_DECL
;
666 if( nElement
== XML_ELEMENT(TEXT
, eElementName
) )
668 return new XMLVariableDeclImportContext(
669 GetImport(), rImportHelper
, nElement
, xAttrList
,
670 eVarDeclsContextType
);
674 // if no context was created, use default context
679 // declaration import (<variable/user-field/sequence-decl> elements)
682 XMLVariableDeclImportContext::XMLVariableDeclImportContext(
683 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
,
685 const Reference
<xml::sax::XFastAttributeList
> & xAttrList
,
686 enum VarType eVarType
) :
687 SvXMLImportContext(rImport
)
689 // bug?? which properties for userfield/userfieldmaster
690 XMLValueImportHelper
aValueHelper(rImport
, rHlp
, true, false, true, false);
691 sal_Unicode
cSeparationChar('.');
693 sal_Int8
nNumLevel(-1);
696 if (nElement
!= XML_ELEMENT(TEXT
, XML_SEQUENCE_DECL
) &&
697 nElement
!= XML_ELEMENT(TEXT
, XML_VARIABLE_DECL
) &&
698 nElement
!= XML_ELEMENT(TEXT
, XML_USER_FIELD_DECL
) )
701 // TODO: check validity (need name!)
704 for (auto &aIter
: sax_fastparser::castToFastAttributeList( xAttrList
))
706 switch (aIter
.getToken())
708 case XML_ELEMENT(TEXT
, XML_NAME
):
709 sName
= aIter
.toString();
711 case XML_ELEMENT(TEXT
, XML_DISPLAY_OUTLINE_LEVEL
):
714 bool const bRet
= ::sax::Converter::convertNumber(
715 nLevel
, aIter
.toView(), 0,
716 GetImport().GetTextImport()->GetChapterNumbering()->
720 nNumLevel
= static_cast< sal_Int8
>( nLevel
-1 ); // API numbers -1..9
724 case XML_ELEMENT(TEXT
, XML_SEPARATION_CHARACTER
):
726 static_cast<char>(aIter
.toString().toChar());
730 // delegate to value helper
731 aValueHelper
.ProcessAttribute(aIter
.getToken(), aIter
.toView());
736 Reference
<XPropertySet
> xFieldMaster
;
737 if (!FindFieldMaster(xFieldMaster
, GetImport(), rHlp
,
741 // now we have a field master: process attributes!
746 case VarTypeSequence
:
747 xFieldMaster
->setPropertyValue(u
"ChapterNumberingLevel"_ustr
, Any(nNumLevel
));
751 OUString
sStr(&cSeparationChar
, 1);
752 xFieldMaster
->setPropertyValue(
753 u
"NumberingSeparator"_ustr
, Any(sStr
));
758 // set string or non-string SubType (#93192#)
759 // The SubType was already set in the FindFieldMaster
760 // method, but it needs to be adjusted if it's a string.
761 aAny
<<= aValueHelper
.IsStringValue()
762 ? SetVariableType::STRING
: SetVariableType::VAR
;
763 xFieldMaster
->setPropertyValue(sAPI_sub_type
, aAny
);
766 case VarTypeUserField
:
768 bool bTmp
= !aValueHelper
.IsStringValue();
769 xFieldMaster
->setPropertyValue(u
"IsExpression"_ustr
, Any(bTmp
));
770 aValueHelper
.PrepareField(xFieldMaster
);
774 OSL_FAIL("unknown varfield type");
779 bool XMLVariableDeclImportContext::FindFieldMaster(
780 Reference
<XPropertySet
> & xMaster
, SvXMLImport
& rImport
,
781 XMLTextImportHelper
& rImportHelper
,
782 const OUString
& sVarName
, enum VarType eVarType
)
784 static sal_Int32 nCollisionCount
= 0;
787 // currently: no family in use! Use 0.
788 OUString sName
= rImportHelper
.GetRenameMap().Get(
789 sal::static_int_cast
< sal_uInt16
>(eVarType
), sVarName
);
791 // get text fields supplier and field masters
792 Reference
<XTextFieldsSupplier
> xTextFieldsSupp(rImport
.GetModel(),
794 Reference
<container::XNameAccess
> xFieldMasterNameAccess
=
795 xTextFieldsSupp
->getTextFieldMasters();
797 OUString sVarServiceName
=
798 OUString::Concat(sAPI_fieldmaster_prefix
) +
799 sAPI_set_expression
+
803 OUString sUserServiceName
=
804 OUString::Concat(sAPI_fieldmaster_prefix
) +
809 if (xFieldMasterNameAccess
->hasByName(sVarServiceName
)) {
810 // variable field master already in document
812 Any aAny
= xFieldMasterNameAccess
->getByName(sVarServiceName
);
815 aAny
= xMaster
->getPropertyValue(sAPI_sub_type
);
819 enum VarType eFMVarType
=
820 (SetVariableType::SEQUENCE
== nType
) ?
821 VarTypeSequence
: VarTypeSimple
;
823 if (eFMVarType
!= eVarType
)
826 OUString
sNew(sName
+ "_renamed_" + OUString::number(nCollisionCount
));
828 // FIXME! can't find if name is taken already!!!!
830 rImportHelper
.GetRenameMap().Add(
831 sal::static_int_cast
< sal_uInt16
>(eVarType
), sName
, sNew
);
833 // call FindFieldMaster recursively to create new master
834 return FindFieldMaster(xMaster
, rImport
, rImportHelper
,
837 } else if (xFieldMasterNameAccess
->hasByName(sUserServiceName
)) {
838 // user field: get field master
839 Any aAny
= xFieldMasterNameAccess
->getByName(sUserServiceName
);
842 if (VarTypeUserField
!= eVarType
) {
844 // find new name that is not taken
845 OUString
sNew(sName
+ "_renamed_" + OUString::number(nCollisionCount
));
847 // FIXME! can't find if name is taken already!!!!
849 rImportHelper
.GetRenameMap().Add(
850 sal::static_int_cast
< sal_uInt16
>(eVarType
), sName
, sNew
);
852 // call FindFieldMaster recursively to create new master
853 return FindFieldMaster(xMaster
, rImport
, rImportHelper
,
857 // field name not used: create field master
859 // import -> model is MultiServiceFactory -> createInstance
860 Reference
<lang::XMultiServiceFactory
>
861 xFactory(rImport
.GetModel(),UNO_QUERY
);
862 if( xFactory
.is() ) {
864 OUString sService
= sAPI_fieldmaster_prefix
865 + ((eVarType
==VarTypeUserField
) ?
866 sAPI_user
: sAPI_set_expression
);
867 Reference
<XInterface
> xIfc
=
868 xFactory
->createInstance( sService
);
870 xMaster
.set(xIfc
, UNO_QUERY
);
873 xMaster
->setPropertyValue(u
"Name"_ustr
, Any(sName
));
875 if (eVarType
!= VarTypeUserField
) {
876 // set subtype for setexp field
878 aAny
<<= ((eVarType
== VarTypeSimple
) ?
879 SetVariableType::VAR
:
880 SetVariableType::SEQUENCE
);
881 xMaster
->setPropertyValue(sAPI_sub_type
, aAny
);
882 } // else : user field: no subtype
892 DBG_ASSERT(xMaster
.is(), "no field master found!?!");
897 // Database Display field import
900 XMLDatabaseDisplayImportContext::XMLDatabaseDisplayImportContext(
901 SvXMLImport
& rImport
, XMLTextImportHelper
& rHlp
) :
902 XMLDatabaseFieldImportContext(rImport
, rHlp
, sAPI_database
, false),
903 aValueHelper(rImport
, rHlp
, false, true, false, false),
910 void XMLDatabaseDisplayImportContext::ProcessAttribute(
911 sal_Int32 nAttrToken
, std::string_view sAttrValue
)
915 case XML_ELEMENT(TEXT
, XML_COLUMN_NAME
):
916 sColumnName
= OUString::fromUtf8(sAttrValue
);
919 case XML_ELEMENT(TEXT
, XML_DISPLAY
):
921 bool bNone
= IsXMLToken( sAttrValue
, XML_NONE
);
922 bool bValue
= IsXMLToken( sAttrValue
, XML_VALUE
);
924 bDisplayOK
= bNone
|| bValue
;
927 case XML_ELEMENT(TEXT
, XML_DATABASE_NAME
):
928 case XML_ELEMENT(TEXT
, XML_TABLE_NAME
):
929 case XML_ELEMENT(TEXT
, XML_TABLE_TYPE
):
930 // handled by super class
931 XMLDatabaseFieldImportContext::ProcessAttribute(nAttrToken
,
935 // remainder handled by value helper
936 aValueHelper
.ProcessAttribute(nAttrToken
, sAttrValue
);
940 bValid
= m_bTableOK
&& m_bDatabaseOK
&& bColumnOK
;
943 void XMLDatabaseDisplayImportContext::endFastElement(sal_Int32
)
945 // we have an EndElement of our own, because database fields need
946 // to be attached to a field master before they can be inserted into
947 // the document. Database stuff (database, table, column) all goes
948 // to the field master, value & style go to the field.
953 // so here goes: we start with the master
954 Reference
<XPropertySet
> xMaster
;
956 // create and prepare field master first
957 if (CreateField(xMaster
,
958 u
"com.sun.star.text.FieldMaster.Database"_ustr
))
961 xMaster
->setPropertyValue(u
"DataColumnName"_ustr
, Any(sColumnName
));
963 // fieldmaster takes database, table and column name
964 XMLDatabaseFieldImportContext::PrepareField(xMaster
);
967 Reference
<XPropertySet
> xField
;
968 if (CreateField(xField
,
971 // attach field master
972 Reference
<XDependentTextField
> xDepField(xField
, UNO_QUERY
);
975 // attach field to field master
976 xDepField
->attachTextFieldMaster(xMaster
);
978 // attach field to document
979 Reference
<XTextContent
> xTextContent(xField
, UNO_QUERY
);
980 if (xTextContent
.is())
982 // insert, set field properties and exit!
985 GetImportHelper().InsertTextContent(xTextContent
);
987 // prepare field: format from database?
988 bool bTmp
= !aValueHelper
.IsFormatOK();
989 xField
->setPropertyValue(u
"DataBaseFormat"_ustr
, Any(bTmp
));
991 // value, value-type and format done by value helper
992 aValueHelper
.PrepareField(xField
);
997 xField
->setPropertyValue(sAPI_is_visible
, Any(bDisplay
));
1001 aAny
<<= GetContent();
1002 xField
->setPropertyValue(sAPI_current_presentation
, aAny
);
1007 catch (const lang::IllegalArgumentException
&)
1009 TOOLS_WARN_EXCEPTION("xmloff.text", "Failed to insert text content");
1017 // above: exit on success; so for all error cases we end up here!
1018 // write element content
1019 GetImportHelper().InsertString(GetContent());
1023 // value import helper
1029 XML_VALUE_TYPE_STRING
,
1030 XML_VALUE_TYPE_FLOAT
,
1031 XML_VALUE_TYPE_CURRENCY
,
1032 XML_VALUE_TYPE_PERCENTAGE
,
1033 XML_VALUE_TYPE_DATE
,
1034 XML_VALUE_TYPE_TIME
,
1035 XML_VALUE_TYPE_BOOLEAN
1040 SvXMLEnumMapEntry
<ValueType
> const aValueTypeMap
[] =
1042 { XML_FLOAT
, XML_VALUE_TYPE_FLOAT
},
1043 { XML_CURRENCY
, XML_VALUE_TYPE_CURRENCY
},
1044 { XML_PERCENTAGE
, XML_VALUE_TYPE_PERCENTAGE
},
1045 { XML_DATE
, XML_VALUE_TYPE_DATE
},
1046 { XML_TIME
, XML_VALUE_TYPE_TIME
},
1047 { XML_BOOLEAN
, XML_VALUE_TYPE_BOOLEAN
},
1048 { XML_STRING
, XML_VALUE_TYPE_STRING
},
1049 { XML_TOKEN_INVALID
, ValueType(0) }
1052 XMLValueImportHelper::XMLValueImportHelper(
1053 SvXMLImport
& rImprt
,
1054 XMLTextImportHelper
& rHlp
,
1055 bool bType
, bool bStyle
, bool bValue
, bool bFormula
) :
1062 bIsDefaultLanguage(true),
1066 bStringValueOK(false),
1072 bSetFormula(bFormula
)
1076 void XMLValueImportHelper::ProcessAttribute(
1077 sal_Int32 nAttrToken
, std::string_view sAttrValue
)
1081 case XML_ELEMENT(TEXT
, XML_VALUE_TYPE
): // #i32362#: src680m48++ saves text:value-type
1082 case XML_ELEMENT(OFFICE
, XML_VALUE_TYPE
):
1085 ValueType eValueType
= XML_VALUE_TYPE_STRING
;
1086 bool bRet
= SvXMLUnitConverter::convertEnum(
1087 eValueType
, sAttrValue
, aValueTypeMap
);
1092 case XML_VALUE_TYPE_STRING
:
1095 case XML_VALUE_TYPE_FLOAT
:
1096 case XML_VALUE_TYPE_CURRENCY
:
1097 case XML_VALUE_TYPE_PERCENTAGE
:
1098 case XML_VALUE_TYPE_DATE
:
1099 case XML_VALUE_TYPE_TIME
:
1100 case XML_VALUE_TYPE_BOOLEAN
:
1101 bStringType
= false;
1105 OSL_FAIL("unknown value type");
1111 case XML_ELEMENT(TEXT
, XML_VALUE
):
1112 case XML_ELEMENT(OFFICE
, XML_VALUE
):
1115 bool const bRet
= ::sax::Converter::convertDouble(fTmp
,sAttrValue
);
1122 case XML_ELEMENT(TEXT
, XML_TIME_VALUE
):
1123 case XML_ELEMENT(OFFICE
, XML_TIME_VALUE
):
1127 ::sax::Converter::convertDuration(fTmp
, sAttrValue
);
1134 case XML_ELEMENT(TEXT
, XML_DATE_VALUE
):
1135 case XML_ELEMENT(OFFICE
, XML_DATE_VALUE
):
1138 bool bRet
= rImport
.GetMM100UnitConverter().
1139 convertDateTime(fTmp
,sAttrValue
);
1146 case XML_ELEMENT(OFFICE
, XML_BOOLEAN_VALUE
):
1149 bool bRet
= ::sax::Converter::convertBool(bTmp
, sAttrValue
);
1151 fValue
= (bTmp
? 1.0 : 0.0);
1156 bRet
= ::sax::Converter::convertDouble(fTmp
, sAttrValue
);
1164 case XML_ELEMENT(TEXT
, XML_STRING_VALUE
):
1165 case XML_ELEMENT(OFFICE
, XML_STRING_VALUE
):
1166 sValue
= OUString::fromUtf8(sAttrValue
);
1167 bStringValueOK
= true;
1170 case XML_ELEMENT(TEXT
, XML_FORMULA
):
1173 sal_uInt16 nPrefix
= rImport
.GetNamespaceMap().
1174 GetKeyByAttrValueQName(OUString::fromUtf8(sAttrValue
), &sTmp
);
1175 if( XML_NAMESPACE_OOOW
== nPrefix
)
1181 sFormula
= OUString::fromUtf8(sAttrValue
);
1185 case XML_ELEMENT(STYLE
, XML_DATA_STYLE_NAME
):
1187 sal_Int32 nKey
= rHelper
.GetDataStyleKey(
1188 OUString::fromUtf8(sAttrValue
), &bIsDefaultLanguage
);
1197 XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken
, sAttrValue
);
1201 void XMLValueImportHelper::PrepareField(
1202 const Reference
<XPropertySet
> & xPropertySet
)
1208 // ??? how to set type?
1213 aAny
<<= !bFormulaOK
? sDefault
: sFormula
;
1214 xPropertySet
->setPropertyValue(sAPI_content
, aAny
);
1218 if (bSetStyle
&& bFormatOK
)
1220 xPropertySet
->setPropertyValue(sAPI_number_format
, Any(nFormatKey
));
1222 if( xPropertySet
->getPropertySetInfo()->
1223 hasPropertyByName( u
"IsFixedLanguage"_ustr
) )
1225 bool bIsFixedLanguage
= ! bIsDefaultLanguage
;
1226 xPropertySet
->setPropertyValue( u
"IsFixedLanguage"_ustr
, Any(bIsFixedLanguage
) );
1230 // value: string or float
1235 aAny
<<= !bStringValueOK
? sDefault
: sValue
;
1236 xPropertySet
->setPropertyValue(sAPI_content
, aAny
);
1240 xPropertySet
->setPropertyValue(u
"Value"_ustr
, Any(fValue
));
1245 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */