LibreOffice Module sw (master) 1
attrcontentcontrol.cxx
Go to the documentation of this file.
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
21
22#include <libxml/xmlwriter.h>
23
24#include <sal/log.hxx>
27#include <svl/numformat.hxx>
28#include <vcl/keycod.hxx>
29
30#include <ndtxt.hxx>
32#include <doc.hxx>
33#include <unocontentcontrol.hxx>
34
35using namespace com::sun::star;
36
37namespace
38{
39inline constexpr OUStringLiteral CURRENT_DATE_FORMAT = u"YYYY-MM-DD";
40}
41
43{
44 return new SwFormatContentControl(nWhich);
45}
46
48 : SfxPoolItem(nWhich)
49 , m_pTextAttr(nullptr)
50{
51}
52
54 const std::shared_ptr<SwContentControl>& pContentControl, sal_uInt16 nWhich)
55 : SfxPoolItem(nWhich)
56 , m_pContentControl(pContentControl)
57 , m_pTextAttr(nullptr)
58{
59 if (!pContentControl)
60 {
61 SAL_WARN("sw.core", "SwFormatContentControl ctor: no pContentControl?");
62 }
63 // Not calling m_pContentControl->SetFormatContentControl(this) here; only from SetTextAttr.
64}
65
67{
68 if (m_pContentControl && (m_pContentControl->GetFormatContentControl() == this))
69 {
70 NotifyChangeTextNode(nullptr);
71 m_pContentControl->SetFormatContentControl(nullptr);
72 }
73}
74
76{
77 return SfxPoolItem::operator==(rOther)
79 == static_cast<const SwFormatContentControl&>(rOther).m_pContentControl;
80}
81
83{
84 // If this is indeed a copy, then DoCopy will be called later.
86 {
88 }
89 else
90 {
91 return new SwFormatContentControl(Which());
92 }
93}
94
96{
97 if (m_pTextAttr && pTextAttr)
98 {
99 SAL_WARN("sw.core", "SwFormatContentControl::SetTextAttr: already has a text attribute");
100 }
101 if (!m_pTextAttr && !pTextAttr)
102 {
103 SAL_WARN("sw.core", "SwFormatContentControl::SetTextAttr: no attribute to remove");
104 }
105 m_pTextAttr = pTextAttr;
107 {
108 SAL_WARN("sw.core", "inserted SwFormatContentControl has no SwContentControl");
109 }
110 // The SwContentControl should be able to find the current text attribute.
112 {
113 if (pTextAttr)
114 {
115 m_pContentControl->SetFormatContentControl(this);
116 }
117 else if (m_pContentControl->GetFormatContentControl() == this)
118 {
119 // The text attribute is gone, so de-register from text node.
120 NotifyChangeTextNode(nullptr);
121 m_pContentControl->SetFormatContentControl(nullptr);
122 }
123 }
124}
125
127{
128 // Not deleting m_pTextAttr here, SwNodes::ChgNode() doesn't do that, either.
130 {
131 SAL_WARN("sw.core", "SwFormatContentControl::NotifyChangeTextNode: no content control?");
132 }
133 if (m_pContentControl && (m_pContentControl->GetFormatContentControl() == this))
134 {
135 // Not calling Modify, that would call SwXContentControl::SwClientNotify.
136 m_pContentControl->NotifyChangeTextNode(pTextNode);
137 }
138}
139
140// This SwFormatContentControl has been cloned and points at the same SwContentControl as the
141// source: this function copies the SwContentControl.
143{
145 {
146 SAL_WARN("sw.core", "SwFormatContentControl::DoCopy: called for SwFormatContentControl "
147 "with no SwContentControl.");
148 return;
149 }
150
151 m_pContentControl = std::make_shared<SwContentControl>(this);
152 m_pContentControl->NotifyChangeTextNode(&rTargetTextNode);
153}
154
156{
157 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatContentControl"));
158 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
159 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("m_pTextAttr"), "%p", m_pTextAttr);
160 SfxPoolItem::dumpAsXml(pWriter);
161
163 {
164 m_pContentControl->dumpAsXml(pWriter);
165 }
166
167 (void)xmlTextWriterEndElement(pWriter);
168}
169
171 : sw::BroadcastingModify()
172 , m_pFormat(pFormat)
173 , m_pTextNode(nullptr)
174{
175}
176
178
180{
181 m_wXContentControl = xContentCnotrol.get();
182}
183
185{
186 return m_pFormat ? m_pFormat->GetTextAttr() : nullptr;
187}
188
190{
191 m_pTextNode = pTextNode;
193 {
194 m_pTextNode->Add(this);
195 }
196 else if (!m_pTextNode)
197 {
199 }
200 if (!pTextNode)
201 {
202 // If the text node is gone, then invalidate clients (e.g. UNO object).
203 GetNotifier().Broadcast(SfxHint(SfxHintId::Deinitializing));
204 }
205}
206
208{
209 if (rHint.GetId() != SfxHintId::SwLegacyModify)
210 return;
211
212 auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
213 CallSwClientNotify(rHint);
214 GetNotifier().Broadcast(SfxHint(SfxHintId::DataChanged));
215
216 if (pLegacy->GetWhich() == RES_REMOVE_UNO_OBJECT)
217 {
218 // Invalidate cached uno object.
219 SetXContentControl(nullptr);
220 GetNotifier().Broadcast(SfxHint(SfxHintId::Deinitializing));
221 }
222}
223
225{
226 SwDoc& rDoc = m_pTextNode->GetDoc();
227 SvNumberFormatter* pNumberFormatter = rDoc.GetNumberFormatter();
228 sal_uInt32 nFormat = pNumberFormatter->GetEntryKey(
229 m_aDateFormat, LanguageTag(m_aDateLanguage).getLanguageType());
230
231 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
232 {
233 // If not found, then create it.
234 sal_Int32 nCheckPos = 0;
236 OUString aFormat = m_aDateFormat;
237 pNumberFormatter->PutEntry(aFormat, nCheckPos, nType, nFormat,
238 LanguageTag(m_aDateLanguage).getLanguageType());
239 }
240
241 const Color* pColor = nullptr;
242 OUString aFormatted;
243 if (!m_oSelectedDate)
244 {
245 return OUString();
246 }
247
248 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
249 {
250 return OUString();
251 }
252
253 pNumberFormatter->GetOutputString(*m_oSelectedDate, nFormat, aFormatted, &pColor, false);
254 return aFormatted;
255}
256
258{
259 SwDoc& rDoc = m_pTextNode->GetDoc();
260 SvNumberFormatter* pNumberFormatter = rDoc.GetNumberFormatter();
261 OUString aFormatted;
262 sal_uInt32 nFormat = pNumberFormatter->GetEntryKey(CURRENT_DATE_FORMAT, LANGUAGE_ENGLISH_US);
263 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
264 {
265 // If not found, then create it.
266 sal_Int32 nCheckPos = 0;
268 OUString sFormat = CURRENT_DATE_FORMAT;
269 pNumberFormatter->PutEntry(sFormat, nCheckPos, nType, nFormat, LANGUAGE_ENGLISH_US);
270 }
271
272 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
273 {
274 return;
275 }
276
277 const Color* pColor = nullptr;
278 pNumberFormatter->GetOutputString(fCurrentDate, nFormat, aFormatted, &pColor, false);
279 m_aCurrentDate = aFormatted + "T00:00:00Z";
280}
281
283{
284 if (m_aCurrentDate.isEmpty())
285 {
286 return 0;
287 }
288
289 SwDoc& rDoc = m_pTextNode->GetDoc();
290 SvNumberFormatter* pNumberFormatter = rDoc.GetNumberFormatter();
291 sal_uInt32 nFormat = pNumberFormatter->GetEntryKey(CURRENT_DATE_FORMAT, LANGUAGE_ENGLISH_US);
292 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
293 {
294 sal_Int32 nCheckPos = 0;
296 OUString sFormat = CURRENT_DATE_FORMAT;
297 pNumberFormatter->PutEntry(sFormat, nCheckPos, nType, nFormat, LANGUAGE_ENGLISH_US);
298 }
299
300 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
301 {
302 return 0;
303 }
304
305 double dCurrentDate = 0;
306 OUString aCurrentDate = m_aCurrentDate.replaceAll("T00:00:00Z", "");
307 (void)pNumberFormatter->IsNumberFormat(aCurrentDate, nFormat, dCurrentDate);
308 return dCurrentDate;
309}
310
312{
313 if (GetCheckbox())
314 {
315 return cCh == ' ';
316 }
317
318 if (GetPicture())
319 {
320 return cCh == '\r';
321 }
322
323 return false;
324}
325
327{
328 if (HasListItems() || GetDate())
329 {
330 // Alt-down opens the popup.
331 return rKeyCode.IsMod2() && rKeyCode.GetCode() == KEY_DOWN;
332 }
333
334 return false;
335}
336
338{
339 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwContentControl"));
340 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
341 (void)xmlTextWriterWriteFormatAttribute(
342 pWriter, BAD_CAST("showing-place-holder"), "%s",
343 BAD_CAST(OString::boolean(m_bShowingPlaceHolder).getStr()));
344 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("checkbox"), "%s",
345 BAD_CAST(OString::boolean(m_bCheckbox).getStr()));
346 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("checked"), "%s",
347 BAD_CAST(OString::boolean(m_bChecked).getStr()));
348 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("checked-state"), "%s",
349 BAD_CAST(m_aCheckedState.toUtf8().getStr()));
350 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("unchecked-state"), "%s",
351 BAD_CAST(m_aUncheckedState.toUtf8().getStr()));
352 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("picture"),
353 BAD_CAST(OString::boolean(m_bPicture).getStr()));
354 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("date"),
355 BAD_CAST(OString::boolean(m_bDate).getStr()));
356 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("date-format"),
357 BAD_CAST(m_aDateFormat.toUtf8().getStr()));
358 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("date-language"),
359 BAD_CAST(m_aDateLanguage.toUtf8().getStr()));
360 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("current-date"),
361 BAD_CAST(m_aCurrentDate.toUtf8().getStr()));
362 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("plain-text"),
363 BAD_CAST(OString::boolean(m_bPlainText).getStr()));
364 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("placeholder-doc-part"),
365 BAD_CAST(m_aPlaceholderDocPart.toUtf8().getStr()));
366 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("data-binding-prefix-mappings"),
367 BAD_CAST(m_aDataBindingPrefixMappings.toUtf8().getStr()));
368 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("data-binding-xpath"),
369 BAD_CAST(m_aDataBindingXpath.toUtf8().getStr()));
370 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("data-binding-store-item-id"),
371 BAD_CAST(m_aDataBindingStoreItemID.toUtf8().getStr()));
372 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("color"),
373 BAD_CAST(m_aColor.toUtf8().getStr()));
374
375 if (!m_aListItems.empty())
376 {
377 for (const auto& rListItem : m_aListItems)
378 {
379 rListItem.dumpAsXml(pWriter);
380 }
381 }
382
383 (void)xmlTextWriterEndElement(pWriter);
384}
385
387{
388 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwContentControlListItem"));
389 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
390 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("display-text"),
391 BAD_CAST(m_aDisplayText.toUtf8().getStr()));
392 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
393 BAD_CAST(m_aValue.toUtf8().getStr()));
394
395 (void)xmlTextWriterEndElement(pWriter);
396}
397
399{
400 if (!m_aDisplayText.isEmpty())
401 {
402 return m_aDisplayText;
403 }
404
405 return m_aValue;
406}
407
409{
410 return m_aDisplayText == rOther.m_aDisplayText && m_aValue == rOther.m_aValue;
411}
412
413void SwContentControlListItem::ItemsToAny(const std::vector<SwContentControlListItem>& rItems,
414 uno::Any& rVal)
415{
416 uno::Sequence<uno::Sequence<beans::PropertyValue>> aRet(rItems.size());
417
418 uno::Sequence<beans::PropertyValue>* pRet = aRet.getArray();
419 for (size_t i = 0; i < rItems.size(); ++i)
420 {
421 const SwContentControlListItem& rItem = rItems[i];
422 uno::Sequence<beans::PropertyValue> aItem = {
423 comphelper::makePropertyValue("DisplayText", rItem.m_aDisplayText),
425 };
426 pRet[i] = aItem;
427 }
428
429 rVal <<= aRet;
430}
431
432std::vector<SwContentControlListItem>
434{
435 std::vector<SwContentControlListItem> aRet;
436
437 uno::Sequence<uno::Sequence<beans::PropertyValue>> aSequence;
438 rVal >>= aSequence;
439 for (const auto& rItem : aSequence)
440 {
443 auto it = aMap.find("DisplayText");
444 if (it != aMap.end())
445 {
446 it->second >>= aItem.m_aDisplayText;
447 }
448 it = aMap.find("Value");
449 if (it != aMap.end())
450 {
451 it->second >>= aItem.m_aValue;
452 }
453 aRet.push_back(aItem);
454 }
455
456 return aRet;
457}
458
461 sal_Int32 nStart,
462 sal_Int32 nEnd, bool bIsCopy)
463{
464 if (bIsCopy)
465 {
466 // rAttr is already cloned, now call DoCopy to copy the SwContentControl
467 if (!pTargetTextNode)
468 {
469 SAL_WARN("sw.core",
470 "SwTextContentControl ctor: cannot copy content control without target node");
471 }
472 rAttr.DoCopy(*pTargetTextNode);
473 }
474 auto pTextContentControl(new SwTextContentControl(rAttr, nStart, nEnd));
475 return pTextContentControl;
476}
477
479 sal_Int32 nEnd)
480 : SwTextAttr(rAttr, nStart)
481 , SwTextAttrNesting(rAttr, nStart, nEnd)
482{
483 rAttr.SetTextAttr(this);
484 SetHasDummyChar(true);
485}
486
488{
489 auto& rFormatContentControl = static_cast<SwFormatContentControl&>(GetAttr());
490 if (rFormatContentControl.GetTextAttr() == this)
491 {
492 rFormatContentControl.SetTextAttr(nullptr);
493 }
494}
495
497{
498 auto& rFormatContentControl = static_cast<SwFormatContentControl&>(GetAttr());
499 if (rFormatContentControl.GetTextAttr() == this)
500 {
501 rFormatContentControl.NotifyChangeTextNode(pNode);
502 }
503}
504
506{
507 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwTextContentControl"));
508 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
509 SwTextAttr::dumpAsXml(pWriter);
510
511 (void)xmlTextWriterEndElement(pWriter);
512}
513
514/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
struct _xmlTextWriter * xmlTextWriterPtr
SfxHintId GetId() const
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const
sal_uInt16 Which() const
virtual bool operator==(const SfxPoolItem &) const=0
bool PutEntry(OUString &rString, sal_Int32 &nCheckPos, SvNumFormatType &nType, sal_uInt32 &nKey, LanguageType eLnge=LANGUAGE_DONTKNOW, bool bReplaceBooleanEquivalent=true)
void GetOutputString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &sOutString, const Color **ppColor, bool bUseStarFormat=false)
sal_uInt32 GetEntryKey(std::u16string_view sStr, LanguageType eLnge=LANGUAGE_DONTKNOW)
bool IsNumberFormat(const OUString &sString, sal_uInt32 &F_Index, double &fOutNumber, SvNumInputOptions eInputOptions=SvNumInputOptions::NONE)
void Broadcast(const SfxHint &rHint)
const SwModify * GetRegisteredIn() const
Definition: calbck.hxx:164
void EndListeningAll()
Definition: calbck.cxx:136
Represents one list item in a content control dropdown list.
void dumpAsXml(xmlTextWriterPtr pWriter) const
bool operator==(const SwContentControlListItem &rOther) const
OUString m_aValue
This must not be empty.
const OUString & ToString() const
static std::vector< SwContentControlListItem > ItemsFromAny(const css::uno::Any &rVal)
static void ItemsToAny(const std::vector< SwContentControlListItem > &rItems, css::uno::Any &rVal)
OUString m_aDisplayText
This may be empty, ToString() falls back to m_aValue.
OUString m_aCheckedState
If m_bCheckbox is true, the value of a checked checkbox.
virtual ~SwContentControl() override
OUString m_aDataBindingXpath
The data bindings's XPath: just remembered.
void NotifyChangeTextNode(SwTextNode *pTextNode)
void SetXContentControl(const rtl::Reference< SwXContentControl > &xContentCnotrol)
SwFormatContentControl * m_pFormat
unotools::WeakReference< SwXContentControl > m_wXContentControl
OUString m_aDateLanguage
If m_bDate is true, the date's BCP 47 language tag.
SwContentControl(SwFormatContentControl *pFormat)
OUString GetDateString() const
Formats m_oSelectedDate, taking m_aDateFormat and m_aDateLanguage into account.
bool ShouldOpenPopup(const vcl::KeyCode &rKeyCode)
Given rKeyCode as a keyboard event, should a popup be opened for this content control?
bool m_bShowingPlaceHolder
Current content is placeholder text.
SwTextContentControl * GetTextAttr() const
void dumpAsXml(xmlTextWriterPtr pWriter) const
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
double GetCurrentDateValue() const
Parses m_aCurrentDate and returns it.
OUString m_aDataBindingPrefixMappings
The data bindings's prefix mappings: just remembered.
OUString m_aDateFormat
If m_bDate is true, the date format in a syntax accepted by SvNumberFormatter::PutEntry().
void SetCurrentDateValue(double fCurrentDate)
Formats fCurrentDate and sets it.
bool m_bChecked
If m_bCheckbox is true, is the checkbox checked?
std::optional< double > m_oSelectedDate
Stores a date timestamp, in case the doc model is not yet updated.
bool m_bCheckbox
Display the content control as a checkbox.
SwTextNode * m_pTextNode
Can be nullptr if not in a document for undo purposes.
bool m_bPlainText
Plain text, i.e. not rich text.
std::vector< SwContentControlListItem > m_aListItems
OUString m_aUncheckedState
If m_bCheckbox is true, the value of an unchecked checkbox.
OUString m_aCurrentDate
Date in YYYY-MM-DDT00:00:00Z format.
OUString m_aPlaceholderDocPart
The placeholder's doc part: just remembered.
OUString m_aColor
The color: just remembered.
OUString m_aDataBindingStoreItemID
The data bindings's store item ID: just remembered.
bool IsInteractingCharacter(sal_Unicode cCh)
Should this character (during key input) interact with the content control?
Definition: doc.hxx:192
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
Definition: doc.hxx:1415
SfxPoolItem subclass that wraps an SwContentControl.
void NotifyChangeTextNode(SwTextNode *pTextNode)
Notify clients registered at m_pContentControl that this content control is being (re-)moved.
std::shared_ptr< SwContentControl > m_pContentControl
SwFormatContentControl(sal_uInt16 nWhich)
SwTextContentControl * m_pTextAttr
SwTextContentControl * GetTextAttr()
bool operator==(const SfxPoolItem &) const override
SfxPoolItem.
void dumpAsXml(xmlTextWriterPtr pWriter) const override
void DoCopy(SwTextNode &rTargetTextNode)
This method must be called when the hint is actually copied.
static SwFormatContentControl * CreatePoolDefault(sal_uInt16 nWhich)
void SetTextAttr(SwTextContentControl *pTextAttr)
SwFormatContentControl * Clone(SfxItemPool *pPool=nullptr) const override
void Add(SwClient *pDepend)
Definition: calbck.cxx:172
SwDoc & GetDoc()
Definition: node.hxx:217
A wrapper around SfxPoolItem to store the start position of (usually) a text portion,...
Definition: txatbase.hxx:44
const SfxPoolItem & GetAttr() const
Definition: txatbase.hxx:167
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: txatbase.cxx:89
void SetHasDummyChar(const bool bFlag)
Definition: txatbase.hxx:78
SwTextAttr subclass that tracks the location of the wrapped SwFormatContentControl.
static SwTextContentControl * CreateTextContentControl(SwTextNode *pTargetTextNode, SwFormatContentControl &rAttr, sal_Int32 nStart, sal_Int32 nEnd, bool bIsCopy)
void ChgTextNode(SwTextNode *pNode)
SwTextContentControl(SwFormatContentControl &rAttr, sal_Int32 nStart, sal_Int32 nEnd)
void dumpAsXml(xmlTextWriterPtr pWriter) const override
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:86
SvtBroadcaster & GetNotifier()
Definition: calbck.hxx:101
virtual void CallSwClientNotify(const SfxHint &rHint) const override
Definition: calbck.cxx:325
sal_uInt16 GetCode() const
bool IsMod2() const
float u
constexpr TypedWhichId< SwPtrMsgPoolItem > RES_REMOVE_UNO_OBJECT(181)
constexpr sal_uInt16 KEY_DOWN
#define LANGUAGE_ENGLISH_US
#define SAL_WARN(area, stream)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
Dialog to specify the properties of date form field.
HashMap_OWString_Interface aMap
QPRO_FUNC_TYPE nType
sal_uInt16 sal_Unicode
SvNumFormatType
constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND