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#include <wrtsh.hxx>
35
36using namespace com::sun::star;
37
38namespace
39{
40inline constexpr OUStringLiteral CURRENT_DATE_FORMAT = u"YYYY-MM-DD";
41}
42
44{
45 return new SwFormatContentControl(nWhich);
46}
47
49 : SfxPoolItem(nWhich)
50 , m_pTextAttr(nullptr)
51{
52}
53
55 const std::shared_ptr<SwContentControl>& pContentControl, sal_uInt16 nWhich)
56 : SfxPoolItem(nWhich)
57 , m_pContentControl(pContentControl)
58 , m_pTextAttr(nullptr)
59{
60 if (!pContentControl)
61 {
62 SAL_WARN("sw.core", "SwFormatContentControl ctor: no pContentControl?");
63 }
64 // Not calling m_pContentControl->SetFormatContentControl(this) here; only from SetTextAttr.
65}
66
68{
69 if (m_pContentControl && (m_pContentControl->GetFormatContentControl() == this))
70 {
71 NotifyChangeTextNode(nullptr);
72 m_pContentControl->SetFormatContentControl(nullptr);
73 }
74}
75
77{
78 return SfxPoolItem::operator==(rOther)
80 == static_cast<const SwFormatContentControl&>(rOther).m_pContentControl;
81}
82
84{
85 // If this is indeed a copy, then DoCopy will be called later.
87 {
89 }
90 else
91 {
92 return new SwFormatContentControl(Which());
93 }
94}
95
97{
98 if (m_pTextAttr && pTextAttr)
99 {
100 SAL_WARN("sw.core", "SwFormatContentControl::SetTextAttr: already has a text attribute");
101 }
102 if (!m_pTextAttr && !pTextAttr)
103 {
104 SAL_WARN("sw.core", "SwFormatContentControl::SetTextAttr: no attribute to remove");
105 }
106 m_pTextAttr = pTextAttr;
108 {
109 SAL_WARN("sw.core", "inserted SwFormatContentControl has no SwContentControl");
110 }
111 // The SwContentControl should be able to find the current text attribute.
113 {
114 if (pTextAttr)
115 {
116 m_pContentControl->SetFormatContentControl(this);
117 }
118 else if (m_pContentControl->GetFormatContentControl() == this)
119 {
120 // The text attribute is gone, so de-register from text node.
121 NotifyChangeTextNode(nullptr);
122 m_pContentControl->SetFormatContentControl(nullptr);
123 }
124 }
125}
126
128{
129 // Not deleting m_pTextAttr here, SwNodes::ChgNode() doesn't do that, either.
131 {
132 SAL_WARN("sw.core", "SwFormatContentControl::NotifyChangeTextNode: no content control?");
133 }
134 if (m_pContentControl && (m_pContentControl->GetFormatContentControl() == this))
135 {
136 // Not calling Modify, that would call SwXContentControl::SwClientNotify.
137 m_pContentControl->NotifyChangeTextNode(pTextNode);
138 }
139}
140
142{
144 {
145 return nullptr;
146 }
147
148 return m_pContentControl->GetTextNode();
149}
150
151// This SwFormatContentControl has been cloned and points at the same SwContentControl as the
152// source: this function copies the SwContentControl.
154{
156 {
157 SAL_WARN("sw.core", "SwFormatContentControl::DoCopy: called for SwFormatContentControl "
158 "with no SwContentControl.");
159 return;
160 }
161
162 m_pContentControl = std::make_shared<SwContentControl>(this);
163 m_pContentControl->NotifyChangeTextNode(&rTargetTextNode);
164}
165
167{
168 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwFormatContentControl"));
169 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
170 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("m_pTextAttr"), "%p", m_pTextAttr);
171 SfxPoolItem::dumpAsXml(pWriter);
172
174 {
175 m_pContentControl->dumpAsXml(pWriter);
176 }
177
178 (void)xmlTextWriterEndElement(pWriter);
179}
180
182 : sw::BroadcastingModify()
183 , m_pFormat(pFormat)
184 , m_pTextNode(nullptr)
185{
186}
187
189
191{
192 m_wXContentControl = xContentCnotrol.get();
193}
194
196{
197 return m_pFormat ? m_pFormat->GetTextAttr() : nullptr;
198}
199
201{
202 m_pTextNode = pTextNode;
203 if (m_pTextNode && (GetRegisteredIn() != m_pTextNode))
204 {
205 m_pTextNode->Add(this);
206 }
207 else if (!m_pTextNode)
208 {
209 EndListeningAll();
210 }
211 if (!pTextNode)
212 {
213 // If the text node is gone, then invalidate clients (e.g. UNO object).
214 GetNotifier().Broadcast(SfxHint(SfxHintId::Deinitializing));
215 }
216}
217
219{
220 if (rHint.GetId() != SfxHintId::SwLegacyModify)
221 return;
222
223 auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
224 CallSwClientNotify(rHint);
225 GetNotifier().Broadcast(SfxHint(SfxHintId::DataChanged));
226
227 if (pLegacy->GetWhich() == RES_REMOVE_UNO_OBJECT)
228 {
229 // Invalidate cached uno object.
230 SetXContentControl(nullptr);
231 GetNotifier().Broadcast(SfxHint(SfxHintId::Deinitializing));
232 }
233}
234
235bool SwContentControl::AddListItem(size_t nZIndex, const OUString& rDisplayText,
236 const OUString& rValue)
237{
238 SwContentControlListItem aListItem;
239 if (rValue.isEmpty())
240 {
241 if (rDisplayText.isEmpty())
242 return false;
243 aListItem.m_aValue = rDisplayText;
244 }
245 else
246 {
247 aListItem.m_aValue = rValue;
248 aListItem.m_aDisplayText = rDisplayText;
249 }
250
251 // Avoid adding duplicates
252 for (auto& rListItem : GetListItems())
253 {
254 if (rListItem == aListItem)
255 return false;
256 }
257
258 const size_t nLen = GetListItems().size();
259 nZIndex = std::min(nZIndex, nLen);
260 const std::optional<size_t> oSelected = GetSelectedListItem();
261 if (oSelected && *oSelected >= nZIndex)
262 {
263 if (*oSelected < nLen)
264 SetSelectedListItem(*oSelected + 1);
265 }
266 std::vector<SwContentControlListItem> vListItems = GetListItems();
267 vListItems.insert(vListItems.begin() + nZIndex, aListItem);
268 SetListItems(vListItems);
269 return true;
270}
271
273{
274 if (nZIndex >= GetListItems().size())
275 return;
276
277 const std::optional<size_t> oSelected = GetSelectedListItem();
278 if (oSelected)
279 {
280 if (*oSelected == nZIndex)
281 {
282 SetSelectedListItem(std::nullopt);
283 if (m_bDropDown && GetTextAttr())
285 }
286 else if (*oSelected < nZIndex)
287 SetSelectedListItem(*oSelected - 1);
288 }
289
290 std::vector<SwContentControlListItem> vListItems = GetListItems();
291 vListItems.erase(vListItems.begin() + nZIndex);
292 SetListItems(vListItems);
293 return;
294}
295
297{
298 SetSelectedListItem(std::nullopt);
299 SetListItems(std::vector<SwContentControlListItem>());
300 if (m_bDropDown && GetTextAttr())
302}
303
305{
306 SwDoc& rDoc = m_pTextNode->GetDoc();
307 SvNumberFormatter* pNumberFormatter = rDoc.GetNumberFormatter();
308 sal_uInt32 nFormat = pNumberFormatter->GetEntryKey(
309 m_aDateFormat, LanguageTag(m_aDateLanguage).getLanguageType());
310
311 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
312 {
313 // If not found, then create it.
314 sal_Int32 nCheckPos = 0;
316 OUString aFormat = m_aDateFormat;
317 pNumberFormatter->PutEntry(aFormat, nCheckPos, nType, nFormat,
318 LanguageTag(m_aDateLanguage).getLanguageType());
319 }
320
321 const Color* pColor = nullptr;
322 OUString aFormatted;
323 double fSelectedDate = 0;
324 if (m_oSelectedDate)
325 {
326 fSelectedDate = *m_oSelectedDate;
327 }
328 else
329 {
330 fSelectedDate = GetCurrentDateValue();
331 }
332
333 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
334 {
335 return OUString();
336 }
337
338 pNumberFormatter->GetOutputString(fSelectedDate, nFormat, aFormatted, &pColor, false);
339 return aFormatted;
340}
341
343{
344 SwDoc& rDoc = m_pTextNode->GetDoc();
345 SvNumberFormatter* pNumberFormatter = rDoc.GetNumberFormatter();
346 OUString aFormatted;
347 sal_uInt32 nFormat = pNumberFormatter->GetEntryKey(CURRENT_DATE_FORMAT, LANGUAGE_ENGLISH_US);
348 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
349 {
350 // If not found, then create it.
351 sal_Int32 nCheckPos = 0;
353 OUString sFormat = CURRENT_DATE_FORMAT;
354 pNumberFormatter->PutEntry(sFormat, nCheckPos, nType, nFormat, LANGUAGE_ENGLISH_US);
355 }
356
357 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
358 {
359 return;
360 }
361
362 const Color* pColor = nullptr;
363 pNumberFormatter->GetOutputString(fCurrentDate, nFormat, aFormatted, &pColor, false);
364 m_aCurrentDate = aFormatted + "T00:00:00Z";
365}
366
368{
369 if (m_aCurrentDate.isEmpty())
370 {
371 return 0;
372 }
373
374 SwDoc& rDoc = m_pTextNode->GetDoc();
375 SvNumberFormatter* pNumberFormatter = rDoc.GetNumberFormatter();
376 sal_uInt32 nFormat = pNumberFormatter->GetEntryKey(CURRENT_DATE_FORMAT, LANGUAGE_ENGLISH_US);
377 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
378 {
379 sal_Int32 nCheckPos = 0;
381 OUString sFormat = CURRENT_DATE_FORMAT;
382 pNumberFormatter->PutEntry(sFormat, nCheckPos, nType, nFormat, LANGUAGE_ENGLISH_US);
383 }
384
385 if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
386 {
387 return 0;
388 }
389
390 double dCurrentDate = 0;
391 OUString aCurrentDate = m_aCurrentDate.replaceAll("T00:00:00Z", "");
392 (void)pNumberFormatter->IsNumberFormat(aCurrentDate, nFormat, dCurrentDate);
393 return dCurrentDate;
394}
395
397{
398 if (GetCheckbox())
399 {
400 return cCh == ' ';
401 }
402
403 if (GetPicture())
404 {
405 return cCh == '\r';
406 }
407
408 return false;
409}
410
412{
413 switch (GetType())
414 {
418 {
419 // Alt-down opens the popup.
420 return rKeyCode.IsMod2() && rKeyCode.GetCode() == KEY_DOWN;
421 }
422 default:
423 break;
424 }
425
426 return false;
427}
428
430{
431 if (m_bCheckbox)
432 {
434 }
435
436 if (m_bComboBox)
437 {
439 }
440
441 if (m_bDropDown)
442 {
444 }
445
446 if (m_bPicture)
447 {
449 }
450
451 if (m_bDate)
452 {
454 }
455
456 if (m_bPlainText)
457 {
459 }
460
462}
463
465{
466 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwContentControl"));
467 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
468 (void)xmlTextWriterWriteFormatAttribute(
469 pWriter, BAD_CAST("showing-place-holder"), "%s",
470 BAD_CAST(OString::boolean(m_bShowingPlaceHolder).getStr()));
471 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("checkbox"), "%s",
472 BAD_CAST(OString::boolean(m_bCheckbox).getStr()));
473 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("checked"), "%s",
474 BAD_CAST(OString::boolean(m_bChecked).getStr()));
475 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("checked-state"), "%s",
476 BAD_CAST(m_aCheckedState.toUtf8().getStr()));
477 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("unchecked-state"), "%s",
478 BAD_CAST(m_aUncheckedState.toUtf8().getStr()));
479 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("picture"),
480 BAD_CAST(OString::boolean(m_bPicture).getStr()));
481 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("date"),
482 BAD_CAST(OString::boolean(m_bDate).getStr()));
483 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("date-format"),
484 BAD_CAST(m_aDateFormat.toUtf8().getStr()));
485 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("date-language"),
486 BAD_CAST(m_aDateLanguage.toUtf8().getStr()));
487 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("current-date"),
488 BAD_CAST(m_aCurrentDate.toUtf8().getStr()));
489 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("plain-text"),
490 BAD_CAST(OString::boolean(m_bPlainText).getStr()));
491 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("combo-box"),
492 BAD_CAST(OString::boolean(m_bComboBox).getStr()));
493 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("drop-down"),
494 BAD_CAST(OString::boolean(m_bDropDown).getStr()));
495 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("placeholder-doc-part"),
496 BAD_CAST(m_aPlaceholderDocPart.toUtf8().getStr()));
497 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("data-binding-prefix-mappings"),
498 BAD_CAST(m_aDataBindingPrefixMappings.toUtf8().getStr()));
499 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("data-binding-xpath"),
500 BAD_CAST(m_aDataBindingXpath.toUtf8().getStr()));
501 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("data-binding-store-item-id"),
502 BAD_CAST(m_aDataBindingStoreItemID.toUtf8().getStr()));
503 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("color"),
504 BAD_CAST(m_aColor.toUtf8().getStr()));
505 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("alias"),
506 BAD_CAST(m_aAlias.toUtf8().getStr()));
507 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("tag"), BAD_CAST(m_aTag.toUtf8().getStr()));
508 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("id"),
509 BAD_CAST(OString::number(m_nId).getStr()));
510
511 if (!m_aListItems.empty())
512 {
513 for (const auto& rListItem : m_aListItems)
514 {
515 rListItem.dumpAsXml(pWriter);
516 }
517 }
518
519 (void)xmlTextWriterEndElement(pWriter);
520}
521
523{
524 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwContentControlListItem"));
525 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
526 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("display-text"),
527 BAD_CAST(m_aDisplayText.toUtf8().getStr()));
528 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
529 BAD_CAST(m_aValue.toUtf8().getStr()));
530
531 (void)xmlTextWriterEndElement(pWriter);
532}
533
535{
536 if (!m_aDisplayText.isEmpty())
537 {
538 return m_aDisplayText;
539 }
540
541 return m_aValue;
542}
543
545{
546 return m_aDisplayText == rOther.m_aDisplayText && m_aValue == rOther.m_aValue;
547}
548
549void SwContentControlListItem::ItemsToAny(const std::vector<SwContentControlListItem>& rItems,
550 uno::Any& rVal)
551{
552 uno::Sequence<uno::Sequence<beans::PropertyValue>> aRet(rItems.size());
553
554 uno::Sequence<beans::PropertyValue>* pRet = aRet.getArray();
555 for (size_t i = 0; i < rItems.size(); ++i)
556 {
557 const SwContentControlListItem& rItem = rItems[i];
558 uno::Sequence<beans::PropertyValue> aItem = {
559 comphelper::makePropertyValue("DisplayText", rItem.m_aDisplayText),
561 };
562 pRet[i] = aItem;
563 }
564
565 rVal <<= aRet;
566}
567
568std::vector<SwContentControlListItem>
570{
571 std::vector<SwContentControlListItem> aRet;
572
573 uno::Sequence<uno::Sequence<beans::PropertyValue>> aSequence;
574 rVal >>= aSequence;
575 for (const auto& rItem : aSequence)
576 {
579 auto it = aMap.find("DisplayText");
580 if (it != aMap.end())
581 {
582 it->second >>= aItem.m_aDisplayText;
583 }
584 it = aMap.find("Value");
585 if (it != aMap.end())
586 {
587 it->second >>= aItem.m_aValue;
588 }
589 aRet.push_back(aItem);
590 }
591
592 return aRet;
593}
594
596 SwTextNode* pTargetTextNode,
598 sal_Int32 nStart,
599 sal_Int32 nEnd, bool bIsCopy)
600{
601 if (bIsCopy)
602 {
603 // rAttr is already cloned, now call DoCopy to copy the SwContentControl
604 if (!pTargetTextNode)
605 {
606 SAL_WARN("sw.core",
607 "SwTextContentControl ctor: cannot copy content control without target node");
608 }
609 rAttr.DoCopy(*pTargetTextNode);
610 }
612 auto pTextContentControl(new SwTextContentControl(pManager, rAttr, nStart, nEnd));
613 return pTextContentControl;
614}
615
617 SwFormatContentControl& rAttr, sal_Int32 nStart,
618 sal_Int32 nEnd)
619 : SwTextAttr(rAttr, nStart)
620 , SwTextAttrNesting(rAttr, nStart, nEnd)
621 , m_pManager(pManager)
622{
623 rAttr.SetTextAttr(this);
624 SetHasDummyChar(true);
625 m_pManager->Insert(this);
626}
627
629{
630 auto& rFormatContentControl = static_cast<SwFormatContentControl&>(GetAttr());
631 if (rFormatContentControl.GetTextAttr() == this)
632 {
633 rFormatContentControl.SetTextAttr(nullptr);
634 }
635}
636
638{
639 auto& rFormatContentControl = static_cast<SwFormatContentControl&>(GetAttr());
640 if (rFormatContentControl.GetTextAttr() == this)
641 {
642 rFormatContentControl.NotifyChangeTextNode(pNode);
643
644 if (pNode)
645 {
647 }
648 else
649 {
650 if (m_pManager)
651 {
652 m_pManager->Erase(this);
653 }
654 m_pManager = nullptr;
655 }
656 }
657}
658
660{
661 auto& rFormatContentControl = static_cast<const SwFormatContentControl&>(GetAttr());
662 return rFormatContentControl.GetTextNode();
663}
664
666{
667 SwDocShell* pDocShell = GetTextNode() ? GetTextNode()->GetDoc().GetDocShell() : nullptr;
668 if (!pDocShell || !pDocShell->GetWrtShell())
669 return;
670
671 // save the cursor
672 // NOTE: needs further testing to see if this is adequate (i.e. in auto-run macros...)
673 pDocShell->GetWrtShell()->Push();
674
675 // visit the control in the text (which makes any necessary visual changes)
676 // NOTE: simply going to a control indicates cancelling ShowingPlaceHolder, unless bOnlyRefresh
677 // NOTE: simply going to a checkbox causes a toggle, unless bOnlyRefresh
678 auto& rFormatContentControl = static_cast<SwFormatContentControl&>(GetAttr());
679 pDocShell->GetWrtShell()->GotoContentControl(rFormatContentControl, /*bOnlyRefresh=*/true);
680
682}
683
685{
686 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwTextContentControl"));
687 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
688 SwTextAttr::dumpAsXml(pWriter);
689
690 (void)xmlTextWriterEndElement(pWriter);
691}
692
694
696{
697 m_aContentControls.push_back(pTextContentControl);
698}
699
701{
702 m_aContentControls.erase(
703 std::remove(m_aContentControls.begin(), m_aContentControls.end(), pTextContentControl),
704 m_aContentControls.end());
705}
706
708{
709 // Only sort now: the items may not have an associated text node by the time they are inserted
710 // into the container.
711 std::sort(m_aContentControls.begin(), m_aContentControls.end(),
712 [](SwTextContentControl*& pLhs, SwTextContentControl*& pRhs) -> bool {
713 SwNodeOffset nIdxLHS = pLhs->GetTextNode()->GetIndex();
714 SwNodeOffset nIdxRHS = pRhs->GetTextNode()->GetIndex();
715 if (nIdxLHS == nIdxRHS)
716 {
717 return pLhs->GetStart() < pRhs->GetStart();
718 }
719
720 return nIdxLHS < nIdxRHS;
721 });
722
723 return m_aContentControls[nIndex];
724}
725
727{
728 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwContentControlManager"));
729 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
730 for (const auto& pContentControl : m_aContentControls)
731 {
732 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwTextContentControl"));
733 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", pContentControl);
734 (void)xmlTextWriterEndElement(pWriter);
735 }
736
737 (void)xmlTextWriterEndElement(pWriter);
738}
739
740/* 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)
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.
Knows all the text content controls in the document.
std::vector< SwTextContentControl * > m_aContentControls
Non-owning reference to text content controls.
SwTextContentControl * Get(size_t nIndex)
void Insert(SwTextContentControl *pTextContentControl)
void Erase(SwTextContentControl *pTextContentControl)
void dumpAsXml(xmlTextWriterPtr pWriter) const
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)
bool m_bDropDown
Same as combo box, but free-form input is not accepted.
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.
void SetListItems(const std::vector< SwContentControlListItem > &rListItems)
sal_Int32 m_nId
The id: just remembered.
SwTextContentControl * GetTextAttr() const
void dumpAsXml(xmlTextWriterPtr pWriter) const
bool AddListItem(size_t nZIndex, const OUString &rDisplayText, const OUString &rValue)
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.
const std::vector< SwContentControlListItem > & GetListItems() const
const std::optional< size_t > & GetSelectedListItem() const
bool m_bComboBox
Same as drop-down, but free-form input is also accepted.
SwContentControlType GetType() const
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?
OUString m_aTag
The tag: just remembered.
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.
OUString m_aAlias
The alias: just remembered.
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.
void SetSelectedListItem(std::optional< size_t > oSelectedListItem)
void DeleteListItem(size_t nZIndex)
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?
void Push()
store a copy of the current cursor on the cursor stack
Definition: crsrsh.cxx:2251
SwWrtShell * GetWrtShell()
Access to the SwWrtShell belonging to SwView.
Definition: docsh.hxx:225
Definition: doc.hxx:194
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
Definition: doc.hxx:1418
SwDocShell * GetDocShell()
Definition: doc.hxx:1359
::SwContentControlManager & GetContentControlManager()
Definition: doc.cxx:134
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
SwTextNode * GetTextNode() const
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
SwDoc & GetDoc()
Definition: node.hxx:233
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.
SwTextContentControl(SwContentControlManager *pManager, SwFormatContentControl &rAttr, sal_Int32 nStart, sal_Int32 nEnd)
static SwTextContentControl * CreateTextContentControl(SwDoc &rDoc, SwTextNode *pTargetTextNode, SwFormatContentControl &rAttr, sal_Int32 nStart, sal_Int32 nEnd, bool bIsCopy)
void ChgTextNode(SwTextNode *pNode)
SwTextNode * GetTextNode() const
SwContentControlManager * m_pManager
void dumpAsXml(xmlTextWriterPtr pWriter) const override
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:111
bool GotoContentControl(const SwFormatContentControl &rContentControl, bool bOnlyRefresh=false)
Definition: wrtsh3.cxx:96
bool Pop(SwCursorShell::PopMode, ::std::optional< SwCallLink > &roLink)
Definition: wrtsh1.cxx:2030
sal_uInt16 GetCode() const
bool IsMod2() const
float u
SwContentControlType
constexpr TypedWhichId< SwPtrMsgPoolItem > RES_REMOVE_UNO_OBJECT(181)
sal_Int32 nIndex
constexpr sal_uInt16 KEY_DOWN
#define LANGUAGE_ENGLISH_US
#define SAL_WARN(area, stream)
size
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
Dialog to specify the properties of date form field.
HashMap_OWString_Interface aMap
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
QPRO_FUNC_TYPE nType
ToolBarManager * m_pManager
sal_uInt16 sal_Unicode
SvNumFormatType
constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND