nss: upgrade to release 3.73
[LibreOffice.git] / xmloff / source / text / txtvfldi.cxx
blobabcbb51622feae16f3153e34b65510dbcee33210
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 /** @#file
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/xml/sax/XAttributeList.hpp>
42 #include <com/sun/star/style/NumberingType.hpp>
43 #include <com/sun/star/container/XIndexReplace.hpp>
45 #include <sax/tools/converter.hxx>
47 #include <rtl/ustring.hxx>
48 #include <osl/diagnose.h>
49 #include <sal/log.hxx>
51 #include <tools/debug.hxx>
52 #include <tools/diagnose_ex.h>
55 // service names
56 constexpr char16_t sAPI_fieldmaster_prefix[] = u"com.sun.star.text.FieldMaster.";
57 const char sAPI_get_expression[] = "GetExpression";
58 const char sAPI_set_expression[] = "SetExpression";
59 const char sAPI_user[] = "User";
60 const char sAPI_database[] = "com.sun.star.text.TextField.Database";
62 // property names
63 const char sAPI_content[] = "Content";
64 const char sAPI_sub_type[] = "SubType";
65 const char sAPI_number_format[] = "NumberFormat";
66 const char sAPI_is_visible[] = "IsVisible";
67 const char sAPI_current_presentation[] = "CurrentPresentation";
70 using namespace ::com::sun::star;
71 using namespace ::com::sun::star::uno;
72 using namespace ::com::sun::star::beans;
73 using namespace ::com::sun::star::text;
74 using namespace ::com::sun::star::style;
75 using namespace ::xmloff::token;
78 // XMLVarFieldImportContext: superclass for all variable related fields
81 XMLVarFieldImportContext::XMLVarFieldImportContext(
82 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
83 const char* pServiceName, sal_uInt16 nPrfx,
84 const OUString& rLocalName,
85 bool bFormula, bool bFormulaDefault,
86 bool bDescription, bool bHelp, bool bHint, bool bVisible,
87 bool bIsDisplayFormula,
88 bool bType, bool bStyle, bool bValue,
89 bool bPresentation) :
90 XMLTextFieldImportContext(rImport, rHlp, pServiceName, nPrfx, rLocalName),
91 aValueHelper(rImport, rHlp, bType, bStyle, bValue, false),
92 bDisplayFormula(false),
93 bDisplayNone(false),
94 bFormulaOK(false),
95 bDescriptionOK(false),
96 bHelpOK(false),
97 bHintOK(false),
98 bDisplayOK(false),
99 bSetFormula(bFormula),
100 bSetFormulaDefault(bFormulaDefault),
101 bSetDescription(bDescription),
102 bSetHelp(bHelp),
103 bSetHint(bHint),
104 bSetVisible(bVisible),
105 bSetDisplayFormula(bIsDisplayFormula),
106 bSetPresentation(bPresentation)
110 void XMLVarFieldImportContext::ProcessAttribute(
111 sal_Int32 nAttrToken,
112 const OUString& sAttrValue )
114 switch (nAttrToken)
116 case XML_ELEMENT(TEXT, XML_NAME):
117 sName = sAttrValue;
118 bValid = true; // we assume: field with name is valid!
119 break;
120 case XML_ELEMENT(TEXT, XML_DESCRIPTION):
121 sDescription = sAttrValue;
122 bDescriptionOK = true;
123 break;
124 case XML_ELEMENT(TEXT, XML_HELP):
125 sHelp = sAttrValue;
126 bHelpOK = true;
127 break;
128 case XML_ELEMENT(TEXT, XML_HINT):
129 sHint = sAttrValue;
130 bHintOK = true;
131 break;
132 case XML_ELEMENT(TEXT, XML_FORMULA):
134 OUString sTmp;
135 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
136 GetKeyByAttrValueQName(sAttrValue, &sTmp);
137 if( XML_NAMESPACE_OOOW == nPrefix )
139 sFormula = sTmp;
140 bFormulaOK = true;
142 else
143 sFormula = sAttrValue;
145 break;
146 case XML_ELEMENT(TEXT, XML_DISPLAY):
147 if (IsXMLToken(sAttrValue, XML_FORMULA))
149 bDisplayFormula = true;
150 bDisplayNone = false;
151 bDisplayOK = true;
153 else if (IsXMLToken(sAttrValue, XML_VALUE))
155 bDisplayFormula = false;
156 bDisplayNone = false;
157 bDisplayOK = true;
159 else if (IsXMLToken(sAttrValue, XML_NONE))
161 bDisplayFormula = false;
162 bDisplayNone = true;
163 bDisplayOK = true;
164 } // else: no change
165 DBG_ASSERT(!(bDisplayFormula && bDisplayNone),
166 "illegal display values");
167 break;
168 default:
169 // delegate all others to value helper
170 aValueHelper.ProcessAttribute(nAttrToken, sAttrValue);
171 break;
175 void XMLVarFieldImportContext::PrepareField(
176 const Reference<XPropertySet> & xPropertySet)
178 // bSetName: not implemented
180 if (bSetFormula)
182 if (!bFormulaOK && bSetFormulaDefault)
184 sFormula = GetContent();
185 bFormulaOK = true;
188 if (bFormulaOK)
190 xPropertySet->setPropertyValue(sAPI_content, Any(sFormula));
194 if (bSetDescription && bDescriptionOK)
196 xPropertySet->setPropertyValue("Hint", Any(sDescription));
199 if (bSetHelp && bHelpOK)
201 xPropertySet->setPropertyValue("Help", Any(sHelp));
204 if (bSetHint && bHintOK)
206 xPropertySet->setPropertyValue("Tooltip", Any(sHint));
209 if (bSetVisible && bDisplayOK)
211 bool bTmp = !bDisplayNone;
212 xPropertySet->setPropertyValue(sAPI_is_visible, Any(bTmp));
215 // workaround for #no-bug#: display formula by default
216 if (xPropertySet->getPropertySetInfo()->
217 hasPropertyByName("IsShowFormula") &&
218 !bSetDisplayFormula)
220 bDisplayFormula = false;
221 bSetDisplayFormula = true;
225 if (bSetDisplayFormula)
227 bool bTmp = bDisplayFormula && bDisplayOK;
228 xPropertySet->setPropertyValue("IsShowFormula", Any(bTmp));
231 // delegate to value helper
232 aValueHelper.SetDefault(GetContent());
233 aValueHelper.PrepareField(xPropertySet);
235 // finally, set the curren presentation
236 if (bSetPresentation)
238 Any aAny;
239 aAny <<= GetContent();
240 xPropertySet->setPropertyValue(sAPI_current_presentation, aAny);
245 // variable set fields
248 XMLSetVarFieldImportContext::XMLSetVarFieldImportContext(
249 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
250 const char* pServiceName, sal_uInt16 nPrfx,
251 const OUString& rLocalName, VarType eVarType,
252 bool bFormula, bool bFormulaDefault,
253 bool bDescription, bool bHelp, bool bHint, bool bVisible, bool bIsDisplayFormula,
254 bool bType, bool bStyle, bool bValue, bool bPresentation) :
255 XMLVarFieldImportContext(rImport, rHlp, pServiceName,
256 nPrfx, rLocalName,
257 bFormula, bFormulaDefault,
258 bDescription, bHelp, bHint, bVisible, bIsDisplayFormula,
259 bType, bStyle, bValue, bPresentation),
260 eFieldType(eVarType)
264 void XMLSetVarFieldImportContext::endFastElement(sal_Int32 )
266 // should we call PrepareField on the field, or rather on it's master?
267 // currently: call on field (just like superclass)
268 // possible alternatives: call on master
269 // call field or master depending on variable
270 // PrepareMaster() in addition to PrepareField()
272 DBG_ASSERT(!GetServiceName().isEmpty(), "no service name for element!");
274 if (bValid)
276 DBG_ASSERT(!GetName().isEmpty(), "variable name needed!");
278 // find field master
279 Reference<XPropertySet> xMaster;
280 if (FindFieldMaster(xMaster))
282 // create field/Service
283 Reference<XPropertySet> xPropSet;
284 if (CreateField(xPropSet, "com.sun.star.text.TextField." + GetServiceName()))
286 Reference<XDependentTextField> xDepTextField(xPropSet, UNO_QUERY);
287 if (xDepTextField.is())
289 // attach field to field master
290 xDepTextField->attachTextFieldMaster(xMaster);
292 // attach field to document
293 Reference<XTextContent> xTextContent(xPropSet, UNO_QUERY);
294 if (xTextContent.is())
296 try {
297 // insert, set field properties and exit!
298 GetImportHelper().InsertTextContent(xTextContent);
299 PrepareField(xPropSet);
300 } catch (lang::IllegalArgumentException & /*e*/)
302 // ignore e: #i54023#
304 return;
311 // above: exit on success; so for all error cases we end up here!
312 // write element content
313 GetImportHelper().InsertString(GetContent());
316 bool XMLSetVarFieldImportContext::FindFieldMaster(
317 Reference<XPropertySet> & xMaster)
319 // currently: delegate to XMLVariableDeclImportContext;
320 // should eventually go here
321 return XMLVariableDeclImportContext::FindFieldMaster(xMaster,
322 GetImport(),
323 GetImportHelper(),
324 GetName(),
325 eFieldType);
329 // sequence field
332 XMLSequenceFieldImportContext::XMLSequenceFieldImportContext(
333 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
334 sal_uInt16 nPrfx, const OUString& rLocalName) :
335 XMLSetVarFieldImportContext(rImport, rHlp, sAPI_set_expression,
336 nPrfx, rLocalName, VarTypeSequence,
337 // formula
338 true, true,
339 false, false, false, false,
340 false,
341 false, false, false, true),
343 sNumFormat(OUString('1')),
344 sNumFormatSync(GetXMLToken(XML_FALSE)),
345 bRefNameOK(false)
349 void XMLSequenceFieldImportContext::ProcessAttribute(
350 sal_Int32 nAttrToken, const OUString& sAttrValue )
352 switch (nAttrToken)
354 case XML_ELEMENT(STYLE, XML_NUM_FORMAT):
355 sNumFormat = sAttrValue;
356 break;
357 case XML_ELEMENT(STYLE, XML_NUM_LETTER_SYNC):
358 sNumFormatSync = sAttrValue;
359 break;
360 case XML_ELEMENT(TEXT, XML_REF_NAME):
361 sRefName = sAttrValue;
362 bRefNameOK = true;
363 break;
364 default:
365 // delegate to super class (name, formula)
366 XMLSetVarFieldImportContext::ProcessAttribute(nAttrToken,
367 sAttrValue);
368 break;
369 } // switch
372 void XMLSequenceFieldImportContext::PrepareField(
373 const Reference<XPropertySet> & xPropertySet)
375 // delegate to super class (formula)
376 XMLSetVarFieldImportContext::PrepareField(xPropertySet);
378 // set format
379 sal_Int16 nNumType = NumberingType::ARABIC;
380 GetImport().GetMM100UnitConverter().convertNumFormat( nNumType, sNumFormat, sNumFormatSync );
381 xPropertySet->setPropertyValue(sAPI_number_format, Any(nNumType));
383 // handle reference name
384 if (bRefNameOK)
386 Any aAny = xPropertySet->getPropertyValue("SequenceValue");
387 sal_Int16 nValue = 0;
388 aAny >>= nValue;
389 GetImportHelper().InsertSequenceID(sRefName, GetName(), nValue);
394 // variable set field
397 XMLVariableSetFieldImportContext::XMLVariableSetFieldImportContext(
398 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
399 sal_uInt16 nPrfx, const OUString& rLocalName) :
400 XMLSetVarFieldImportContext(rImport, rHlp, sAPI_set_expression,
401 nPrfx, rLocalName, VarTypeSimple,
402 // formula, value&type, style,
403 // display none
404 true, true,
405 false, false, false,
406 true, false,
407 true, true, true,
408 true)
412 void XMLVariableSetFieldImportContext::PrepareField(
413 const Reference<XPropertySet> & xPropertySet)
415 // set type
416 Any aAny;
417 aAny <<= (IsStringValue()? SetVariableType::STRING : SetVariableType::VAR);
418 xPropertySet->setPropertyValue(sAPI_sub_type, aAny);
420 // the remainder is handled by super class
421 XMLSetVarFieldImportContext::PrepareField(xPropertySet);
425 // variable input field
428 XMLVariableInputFieldImportContext::XMLVariableInputFieldImportContext(
429 SvXMLImport& rImport, XMLTextImportHelper& rHlp, sal_uInt16 nPrfx,
430 const OUString& rLocalName) :
431 XMLSetVarFieldImportContext(rImport, rHlp, sAPI_set_expression,
432 nPrfx, rLocalName, VarTypeSimple,
433 // description, display none/formula,
434 // value&type, style, formula
435 true, true,
436 true, true, true,
437 true, false,
438 true, true, true,
439 true)
443 void XMLVariableInputFieldImportContext::PrepareField(
444 const Reference<XPropertySet> & xPropertySet)
446 // set type (input field)
447 Any aAny;
448 xPropertySet->setPropertyValue("Input", Any(true));
450 // set type
451 aAny <<= (IsStringValue()? SetVariableType::STRING : SetVariableType::VAR);
452 xPropertySet->setPropertyValue(sAPI_sub_type, aAny);
454 // the remainder is handled by super class
455 XMLSetVarFieldImportContext::PrepareField(xPropertySet);
459 // user field
462 XMLUserFieldImportContext::XMLUserFieldImportContext(
463 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
464 sal_uInt16 nPrfx, const OUString& rLocalName) :
465 XMLSetVarFieldImportContext(rImport, rHlp, sAPI_user, nPrfx,
466 rLocalName, VarTypeUserField,
467 // display none/formula, style
468 false, false,
469 false, false, false, true,
470 true,
471 false, true, false,
472 false)
477 // user input field
480 // bug: doesn't work (SO API lacking)
481 XMLUserFieldInputImportContext::XMLUserFieldInputImportContext(
482 SvXMLImport& rImport, XMLTextImportHelper& rHlp, sal_uInt16 nPrfx,
483 const OUString& rLocalName) :
484 XMLVarFieldImportContext(rImport, rHlp, "InputUser",
485 nPrfx, rLocalName,
486 // description, style
487 false, false,
488 true, false, false,
489 false, false,
490 false /*???*/, true, false,
491 false)
495 void XMLUserFieldInputImportContext::PrepareField(
496 const Reference<XPropertySet> & xPropertySet)
498 xPropertySet->setPropertyValue(sAPI_content, Any(GetName()));
500 // delegate to super class
501 XMLVarFieldImportContext::PrepareField(xPropertySet);
505 // variable get field
508 XMLVariableGetFieldImportContext::XMLVariableGetFieldImportContext(
509 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
510 sal_uInt16 nPrfx, const OUString& rLocalName) :
511 XMLVarFieldImportContext(rImport, rHlp, sAPI_get_expression,
512 nPrfx, rLocalName,
513 // style, display formula
514 false, false,
515 false, false, false,
516 false, true,
517 true, true, false,
518 true)
522 void XMLVariableGetFieldImportContext::PrepareField(
523 const Reference<XPropertySet> & xPropertySet)
525 // set name
526 xPropertySet->setPropertyValue(sAPI_content, Any(GetName()));
528 // the remainder is handled by super class
529 XMLVarFieldImportContext::PrepareField(xPropertySet);
533 // expression field
536 XMLExpressionFieldImportContext::XMLExpressionFieldImportContext(
537 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
538 sal_uInt16 nPrfx, const OUString& rLocalName) :
539 XMLVarFieldImportContext(rImport, rHlp, sAPI_get_expression,
540 nPrfx, rLocalName,
541 // formula, type, style, display formula
542 true, true,
543 false, false, false,
544 false, true,
545 true, true, false,
546 true)
548 bValid = true; // always valid
552 void XMLExpressionFieldImportContext::PrepareField(
553 const Reference<XPropertySet> & xPropertySet)
555 xPropertySet->setPropertyValue(sAPI_sub_type, Any(sal_Int16(SetVariableType::FORMULA)));
557 // delegate to super class
558 XMLVarFieldImportContext::PrepareField(xPropertySet);
562 // text input field
565 XMLTextInputFieldImportContext::XMLTextInputFieldImportContext(
566 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
567 sal_uInt16 nPrfx, const OUString& sLocalName) :
568 XMLVarFieldImportContext(rImport, rHlp, "Input",
569 nPrfx, sLocalName,
570 // description
571 false, false,
572 true, true, true,
573 false, false,
574 false, false, false,
575 false)
577 bValid = true; // always valid
580 void XMLTextInputFieldImportContext::PrepareField(
581 const Reference<XPropertySet> & xPropertySet)
583 XMLVarFieldImportContext::PrepareField(xPropertySet);
585 xPropertySet->setPropertyValue(sAPI_content, Any(GetContent()));
589 // table formula field
592 XMLTableFormulaImportContext::XMLTableFormulaImportContext(
593 SvXMLImport& rImport,
594 XMLTextImportHelper& rHlp,
595 sal_uInt16 nPrfx,
596 const OUString& rLocalName) :
597 XMLTextFieldImportContext(rImport, rHlp, "TableFormula",
598 nPrfx, rLocalName),
599 aValueHelper(rImport, rHlp, false, true, false, true),
600 bIsShowFormula(false)
604 void XMLTableFormulaImportContext::ProcessAttribute(
605 sal_Int32 nAttrToken,
606 const OUString& sAttrValue )
608 switch (nAttrToken)
610 case XML_ELEMENT(TEXT, XML_FORMULA):
611 aValueHelper.ProcessAttribute( nAttrToken, sAttrValue );
612 bValid = true; // we need a formula!
613 break;
615 case XML_ELEMENT(STYLE, XML_DATA_STYLE_NAME):
616 aValueHelper.ProcessAttribute( nAttrToken, sAttrValue );
617 break;
618 case XML_ELEMENT(TEXT, XML_DISPLAY):
619 if ( sAttrValue == "formula" )
620 bIsShowFormula = true;
621 break;
622 default:
623 // unknown attribute -> ignore
624 XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
625 break;
629 void XMLTableFormulaImportContext::PrepareField(
630 const Reference<XPropertySet> & xPropertySet)
632 // set format and formula
633 aValueHelper.PrepareField( xPropertySet );
635 Any aAny;
637 // set 'show formula' and presentation
638 xPropertySet->setPropertyValue( "IsShowFormula", Any(bIsShowFormula) );
640 aAny <<= GetContent();
641 xPropertySet->setPropertyValue( "CurrentPresentation", aAny );
645 // variable declarations
647 // Should be adapted to XMLVarField-/XMLSetVarFieldImportContext scheme!
650 // declaration container import (<variable/user-field/sequence-decls>)
653 XMLVariableDeclsImportContext::XMLVariableDeclsImportContext(
654 SvXMLImport& rImport, XMLTextImportHelper& rHlp, sal_uInt16 nPrfx,
655 const OUString& rLocalName, enum VarType eVarType) :
656 SvXMLImportContext(rImport, nPrfx, rLocalName),
657 eVarDeclsContextType(eVarType),
658 rImportHelper(rHlp)
662 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLVariableDeclsImportContext::createFastChildContext(
663 sal_Int32 nElement,
664 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
666 SvXMLImportContextRef xImportContext;
668 if( IsTokenInNamespace(nElement, XML_NAMESPACE_TEXT) )
670 enum XMLTokenEnum eElementName;
671 switch (eVarDeclsContextType)
673 case VarTypeSequence:
674 eElementName = XML_SEQUENCE_DECL;
675 break;
676 case VarTypeSimple:
677 eElementName = XML_VARIABLE_DECL;
678 break;
679 case VarTypeUserField:
680 eElementName = XML_USER_FIELD_DECL;
681 break;
682 default:
683 OSL_FAIL("unknown field type!");
684 eElementName = XML_SEQUENCE_DECL;
685 break;
688 if( nElement == XML_ELEMENT(TEXT, eElementName) )
690 return new XMLVariableDeclImportContext(
691 GetImport(), rImportHelper, nElement, xAttrList,
692 eVarDeclsContextType);
696 // if no context was created, use default context
697 return nullptr;
701 // declaration import (<variable/user-field/sequence-decl> elements)
704 XMLVariableDeclImportContext::XMLVariableDeclImportContext(
705 SvXMLImport& rImport, XMLTextImportHelper& rHlp,
706 sal_Int32 nElement,
707 const Reference<xml::sax::XFastAttributeList> & xAttrList,
708 enum VarType eVarType) :
709 SvXMLImportContext(rImport)
711 // bug?? which properties for userfield/userfieldmaster
712 XMLValueImportHelper aValueHelper(rImport, rHlp, true, false, true, false);
713 sal_Unicode cSeparationChar('.');
715 sal_Int8 nNumLevel(-1);
716 OUString sName;
718 if (nElement != XML_ELEMENT(TEXT, XML_SEQUENCE_DECL) &&
719 nElement != XML_ELEMENT(TEXT, XML_VARIABLE_DECL) &&
720 nElement != XML_ELEMENT(TEXT, XML_USER_FIELD_DECL) )
721 return;
723 // TODO: check validity (need name!)
725 // parse attributes
726 for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
728 switch (aIter.getToken())
730 case XML_ELEMENT(TEXT, XML_NAME):
731 sName = aIter.toString();
732 break;
733 case XML_ELEMENT(TEXT, XML_DISPLAY_OUTLINE_LEVEL):
735 sal_Int32 nLevel;
736 bool const bRet = ::sax::Converter::convertNumber(
737 nLevel, aIter.toString(), 0,
738 GetImport().GetTextImport()->GetChapterNumbering()->
739 getCount());
740 if (bRet)
742 nNumLevel = static_cast< sal_Int8 >( nLevel-1 ); // API numbers -1..9
744 break;
746 case XML_ELEMENT(TEXT, XML_SEPARATION_CHARACTER):
747 cSeparationChar =
748 static_cast<char>(aIter.toString().toChar());
749 break;
751 default:
752 // delegate to value helper
753 aValueHelper.ProcessAttribute(aIter.getToken(), aIter.toString());
754 break;
758 Reference<XPropertySet> xFieldMaster;
759 if (!FindFieldMaster(xFieldMaster, GetImport(), rHlp,
760 sName, eVarType))
761 return;
763 // now we have a field master: process attributes!
764 Any aAny;
766 switch (eVarType)
768 case VarTypeSequence:
769 xFieldMaster->setPropertyValue("ChapterNumberingLevel", Any(nNumLevel));
771 if (nNumLevel >= 0)
773 OUString sStr(&cSeparationChar, 1);
774 xFieldMaster->setPropertyValue(
775 "NumberingSeparator", Any(sStr));
777 break;
778 case VarTypeSimple:
780 // set string or non-string SubType (#93192#)
781 // The SubType was already set in the FindFieldMaster
782 // method, but it needs to be adjusted if it's a string.
783 aAny <<= aValueHelper.IsStringValue()
784 ? SetVariableType::STRING : SetVariableType::VAR;
785 xFieldMaster->setPropertyValue(sAPI_sub_type, aAny);
787 break;
788 case VarTypeUserField:
790 bool bTmp = !aValueHelper.IsStringValue();
791 xFieldMaster->setPropertyValue("IsExpression", Any(bTmp));
792 aValueHelper.PrepareField(xFieldMaster);
793 break;
795 default:
796 OSL_FAIL("unknown varfield type");
797 } // switch
801 bool XMLVariableDeclImportContext::FindFieldMaster(
802 Reference<XPropertySet> & xMaster, SvXMLImport& rImport,
803 XMLTextImportHelper& rImportHelper,
804 const OUString& sVarName, enum VarType eVarType)
806 static sal_Int32 nCollisionCount = 0;
808 // rename field
809 // currently: no family in use! Use 0.
810 OUString sName = rImportHelper.GetRenameMap().Get(
811 sal::static_int_cast< sal_uInt16 >(eVarType), sVarName);
813 // get text fields supplier and field masters
814 Reference<XTextFieldsSupplier> xTextFieldsSupp(rImport.GetModel(),
815 UNO_QUERY);
816 Reference<container::XNameAccess> xFieldMasterNameAccess =
817 xTextFieldsSupp->getTextFieldMasters();
819 OUString sVarServiceName =
820 OUStringLiteral(sAPI_fieldmaster_prefix) +
821 sAPI_set_expression +
822 "." +
823 sName;
825 OUString sUserServiceName =
826 OUStringLiteral(sAPI_fieldmaster_prefix) +
827 sAPI_user +
828 "." +
829 sName;
831 if (xFieldMasterNameAccess->hasByName(sVarServiceName)) {
832 // variable field master already in document
834 Any aAny = xFieldMasterNameAccess->getByName(sVarServiceName);
835 aAny >>= xMaster;
837 aAny = xMaster->getPropertyValue(sAPI_sub_type);
838 sal_Int16 nType = 0;
839 aAny >>= nType;
841 enum VarType eFMVarType =
842 (SetVariableType::SEQUENCE == nType) ?
843 VarTypeSequence : VarTypeSimple;
845 if (eFMVarType != eVarType)
847 ++nCollisionCount;
848 OUString sNew(sName + "_renamed_" + OUString::number(nCollisionCount));
850 // FIXME! can't find if name is taken already!!!!
852 rImportHelper.GetRenameMap().Add(
853 sal::static_int_cast< sal_uInt16 >(eVarType), sName, sNew);
855 // call FindFieldMaster recursively to create new master
856 return FindFieldMaster(xMaster, rImport, rImportHelper,
857 sNew, eVarType);
859 } else if (xFieldMasterNameAccess->hasByName(sUserServiceName)) {
860 // user field: get field master
861 Any aAny = xFieldMasterNameAccess->getByName(sUserServiceName);
862 aAny >>= xMaster;
864 if (VarTypeUserField != eVarType) {
865 ++nCollisionCount;
866 // find new name that is not taken
867 OUString sNew(sName + "_renamed_" + OUString::number(nCollisionCount));
869 // FIXME! can't find if name is taken already!!!!
871 rImportHelper.GetRenameMap().Add(
872 sal::static_int_cast< sal_uInt16 >(eVarType), sName, sNew);
874 // call FindFieldMaster recursively to create new master
875 return FindFieldMaster(xMaster, rImport, rImportHelper,
876 sNew, eVarType);
878 } else {
879 // field name not used: create field master
881 // import -> model is MultiServiceFactory -> createInstance
882 Reference<lang::XMultiServiceFactory>
883 xFactory(rImport.GetModel(),UNO_QUERY);
884 if( xFactory.is() ) {
886 OUStringBuffer sService;
887 sService.append(sAPI_fieldmaster_prefix);
888 sService.appendAscii((eVarType==VarTypeUserField) ?
889 sAPI_user : sAPI_set_expression);
890 Reference<XInterface> xIfc =
891 xFactory->createInstance( sService.makeStringAndClear() );
892 if (xIfc.is()) {
893 Reference<XPropertySet> xTmp( xIfc, UNO_QUERY );
894 xMaster = xTmp;
896 // set name
897 xMaster->setPropertyValue("Name", Any(sName));
899 if (eVarType != VarTypeUserField) {
900 // set subtype for setexp field
901 Any aAny;
902 aAny <<= ((eVarType == VarTypeSimple) ?
903 SetVariableType::VAR :
904 SetVariableType::SEQUENCE);
905 xMaster->setPropertyValue(sAPI_sub_type, aAny);
906 } // else : user field: no subtype
908 } else {
909 return false;
911 } else {
912 return false;
916 DBG_ASSERT(xMaster.is(), "no field master found!?!");
917 return true;
921 // Database Display field import
924 XMLDatabaseDisplayImportContext::XMLDatabaseDisplayImportContext(
925 SvXMLImport& rImport, XMLTextImportHelper& rHlp, sal_uInt16 nPrfx,
926 const OUString& rLocalName) :
927 XMLDatabaseFieldImportContext(rImport, rHlp, sAPI_database,
928 nPrfx, rLocalName, false),
929 aValueHelper(rImport, rHlp, false, true, false, false),
930 bColumnOK(false),
931 bDisplay( true ),
932 bDisplayOK( false )
936 void XMLDatabaseDisplayImportContext::ProcessAttribute(
937 sal_Int32 nAttrToken, const OUString& sAttrValue )
939 switch (nAttrToken)
941 case XML_ELEMENT(TEXT, XML_COLUMN_NAME):
942 sColumnName = sAttrValue;
943 bColumnOK = true;
944 break;
945 case XML_ELEMENT(TEXT, XML_DISPLAY):
947 bool bNone = IsXMLToken( sAttrValue, XML_NONE );
948 bool bValue = IsXMLToken( sAttrValue, XML_VALUE );
949 bDisplay = bValue;
950 bDisplayOK = bNone || bValue;
952 break;
953 case XML_ELEMENT(TEXT, XML_DATABASE_NAME):
954 case XML_ELEMENT(TEXT, XML_TABLE_NAME):
955 case XML_ELEMENT(TEXT, XML_TABLE_TYPE):
956 // handled by super class
957 XMLDatabaseFieldImportContext::ProcessAttribute(nAttrToken,
958 sAttrValue);
959 break;
960 default:
961 // remainder handled by value helper
962 aValueHelper.ProcessAttribute(nAttrToken, sAttrValue);
963 break;
966 bValid = m_bTableOK && m_bDatabaseOK && bColumnOK;
969 void XMLDatabaseDisplayImportContext::endFastElement(sal_Int32 )
971 // we have an EndElement of our own, because database fields need
972 // to be attached to a field master before they can be inserted into
973 // the document. Database stuff (database, table, column) all goes
974 // to the field master, value & style go to the field.
976 if (bValid)
979 // so here goes: we start with the master
980 Reference<XPropertySet> xMaster;
982 // create and prepare field master first
983 if (CreateField(xMaster,
984 "com.sun.star.text.FieldMaster.Database"))
986 Any aAny;
987 xMaster->setPropertyValue("DataColumnName", Any(sColumnName));
989 // fieldmaster takes database, table and column name
990 XMLDatabaseFieldImportContext::PrepareField(xMaster);
992 // create field
993 Reference<XPropertySet> xField;
994 if (CreateField(xField,
995 sAPI_database))
997 // attach field master
998 Reference<XDependentTextField> xDepField(xField, UNO_QUERY);
999 if (xDepField.is())
1001 // attach field to field master
1002 xDepField->attachTextFieldMaster(xMaster);
1004 // attach field to document
1005 Reference<XTextContent> xTextContent(xField, UNO_QUERY);
1006 if (xTextContent.is())
1008 // insert, set field properties and exit!
1011 GetImportHelper().InsertTextContent(xTextContent);
1013 // prepare field: format from database?
1014 bool bTmp = !aValueHelper.IsFormatOK();
1015 xField->setPropertyValue("DataBaseFormat", Any(bTmp));
1017 // value, value-type and format done by value helper
1018 aValueHelper.PrepareField(xField);
1020 // visibility
1021 if( bDisplayOK )
1023 xField->setPropertyValue(sAPI_is_visible, Any(bDisplay));
1026 // set presentation
1027 aAny <<= GetContent();
1028 xField->setPropertyValue(sAPI_current_presentation, aAny);
1030 // success!
1031 return;
1033 catch (const lang::IllegalArgumentException&)
1035 TOOLS_WARN_EXCEPTION("xmloff.text", "Failed to insert text content");
1043 // above: exit on success; so for all error cases we end up here!
1044 // write element content
1045 GetImportHelper().InsertString(GetContent());
1049 // value import helper
1051 namespace {
1053 enum ValueType
1055 XML_VALUE_TYPE_STRING,
1056 XML_VALUE_TYPE_FLOAT,
1057 XML_VALUE_TYPE_CURRENCY,
1058 XML_VALUE_TYPE_PERCENTAGE,
1059 XML_VALUE_TYPE_DATE,
1060 XML_VALUE_TYPE_TIME,
1061 XML_VALUE_TYPE_BOOLEAN
1066 SvXMLEnumMapEntry<ValueType> const aValueTypeMap[] =
1068 { XML_FLOAT, XML_VALUE_TYPE_FLOAT },
1069 { XML_CURRENCY, XML_VALUE_TYPE_CURRENCY },
1070 { XML_PERCENTAGE, XML_VALUE_TYPE_PERCENTAGE },
1071 { XML_DATE, XML_VALUE_TYPE_DATE },
1072 { XML_TIME, XML_VALUE_TYPE_TIME },
1073 { XML_BOOLEAN, XML_VALUE_TYPE_BOOLEAN },
1074 { XML_STRING, XML_VALUE_TYPE_STRING },
1075 { XML_TOKEN_INVALID, ValueType(0) }
1078 XMLValueImportHelper::XMLValueImportHelper(
1079 SvXMLImport& rImprt,
1080 XMLTextImportHelper& rHlp,
1081 bool bType, bool bStyle, bool bValue, bool bFormula) :
1083 rImport(rImprt),
1084 rHelper(rHlp),
1086 fValue(0.0),
1087 nFormatKey(0),
1088 bIsDefaultLanguage(true),
1090 bStringType(false),
1091 bFormatOK(false),
1092 bStringValueOK(false),
1093 bFormulaOK(false),
1095 bSetType(bType),
1096 bSetValue(bValue),
1097 bSetStyle(bStyle),
1098 bSetFormula(bFormula)
1102 void XMLValueImportHelper::ProcessAttribute(
1103 sal_Int32 nAttrToken, const OUString& sAttrValue )
1105 switch (nAttrToken)
1107 case XML_ELEMENT(TEXT, XML_VALUE_TYPE):
1108 case XML_ELEMENT(OFFICE, XML_VALUE_TYPE):
1110 // convert enum
1111 ValueType eValueType = XML_VALUE_TYPE_STRING;
1112 bool bRet = SvXMLUnitConverter::convertEnum(
1113 eValueType, sAttrValue, aValueTypeMap);
1115 if (bRet) {
1116 switch (eValueType)
1118 case XML_VALUE_TYPE_STRING:
1119 bStringType = true;
1120 break;
1121 case XML_VALUE_TYPE_FLOAT:
1122 case XML_VALUE_TYPE_CURRENCY:
1123 case XML_VALUE_TYPE_PERCENTAGE:
1124 case XML_VALUE_TYPE_DATE:
1125 case XML_VALUE_TYPE_TIME:
1126 case XML_VALUE_TYPE_BOOLEAN:
1127 bStringType = false;
1128 break;
1130 default:
1131 OSL_FAIL("unknown value type");
1134 break;
1137 case XML_ELEMENT(TEXT, XML_VALUE):
1138 case XML_ELEMENT(OFFICE, XML_VALUE):
1140 double fTmp;
1141 bool const bRet = ::sax::Converter::convertDouble(fTmp,sAttrValue);
1142 if (bRet) {
1143 fValue = fTmp;
1145 break;
1148 case XML_ELEMENT(TEXT, XML_TIME_VALUE):
1149 case XML_ELEMENT(OFFICE, XML_TIME_VALUE):
1151 double fTmp;
1152 bool const bRet =
1153 ::sax::Converter::convertDuration(fTmp, sAttrValue);
1154 if (bRet) {
1155 fValue = fTmp;
1157 break;
1160 case XML_ELEMENT(TEXT, XML_DATE_VALUE):
1161 case XML_ELEMENT(OFFICE, XML_DATE_VALUE):
1163 double fTmp;
1164 bool bRet = rImport.GetMM100UnitConverter().
1165 convertDateTime(fTmp,sAttrValue);
1166 if (bRet) {
1167 fValue = fTmp;
1169 break;
1172 case XML_ELEMENT(OFFICE, XML_BOOLEAN_VALUE):
1174 bool bTmp(false);
1175 bool bRet = ::sax::Converter::convertBool(bTmp, sAttrValue);
1176 if (bRet) {
1177 fValue = (bTmp ? 1.0 : 0.0);
1179 else
1181 double fTmp;
1182 bRet = ::sax::Converter::convertDouble(fTmp, sAttrValue);
1183 if (bRet) {
1184 fValue = fTmp;
1187 break;
1190 case XML_ELEMENT(TEXT, XML_STRING_VALUE):
1191 case XML_ELEMENT(OFFICE, XML_STRING_VALUE):
1192 sValue = sAttrValue;
1193 bStringValueOK = true;
1194 break;
1196 case XML_ELEMENT(TEXT, XML_FORMULA):
1198 OUString sTmp;
1199 sal_uInt16 nPrefix = rImport.GetNamespaceMap().
1200 GetKeyByAttrValueQName(sAttrValue, &sTmp);
1201 if( XML_NAMESPACE_OOOW == nPrefix )
1203 sFormula = sTmp;
1204 bFormulaOK = true;
1206 else
1207 sFormula = sAttrValue;
1209 break;
1211 case XML_ELEMENT(STYLE, XML_DATA_STYLE_NAME):
1213 sal_Int32 nKey = rHelper.GetDataStyleKey(
1214 sAttrValue, &bIsDefaultLanguage);
1215 if (-1 != nKey)
1217 nFormatKey = nKey;
1218 bFormatOK = true;
1220 break;
1222 default:
1223 XMLOFF_WARN_UNKNOWN_ATTR("xmloff", nAttrToken, sAttrValue);
1224 } // switch
1227 void XMLValueImportHelper::PrepareField(
1228 const Reference<XPropertySet> & xPropertySet)
1230 Any aAny;
1232 if (bSetType)
1234 // ??? how to set type?
1237 if (bSetFormula)
1239 aAny <<= !bFormulaOK ? sDefault : sFormula;
1240 xPropertySet->setPropertyValue(sAPI_content, aAny);
1243 // format/style
1244 if (bSetStyle && bFormatOK)
1246 xPropertySet->setPropertyValue(sAPI_number_format, Any(nFormatKey));
1248 if( xPropertySet->getPropertySetInfo()->
1249 hasPropertyByName( "IsFixedLanguage" ) )
1251 bool bIsFixedLanguage = ! bIsDefaultLanguage;
1252 xPropertySet->setPropertyValue( "IsFixedLanguage", Any(bIsFixedLanguage) );
1256 // value: string or float
1257 if (bSetValue)
1259 if (bStringType)
1261 aAny <<= !bStringValueOK ? sDefault : sValue;
1262 xPropertySet->setPropertyValue(sAPI_content, aAny);
1264 else
1266 xPropertySet->setPropertyValue("Value", Any(fValue));
1271 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */