/src/libreoffice/sw/inc/formatcontentcontrol.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #pragma once |
21 | | |
22 | | #include <com/sun/star/text/XTextContent.hpp> |
23 | | #include <com/sun/star/beans/PropertyValue.hpp> |
24 | | |
25 | | #include <cppuhelper/weakref.hxx> |
26 | | #include <sal/types.h> |
27 | | #include <svl/poolitem.hxx> |
28 | | #include <unotools/weakref.hxx> |
29 | | |
30 | | #include "calbck.hxx" |
31 | | #include "swdllapi.h" |
32 | | |
33 | | namespace vcl |
34 | | { |
35 | | class KeyCode; |
36 | | } |
37 | | class SwContentControl; |
38 | | class SwTextContentControl; |
39 | | class SwTextNode; |
40 | | class SwXContentControl; |
41 | | |
42 | | enum class SwContentControlType |
43 | | { |
44 | | RICH_TEXT, |
45 | | CHECKBOX, |
46 | | DROP_DOWN_LIST, |
47 | | PICTURE, |
48 | | DATE, |
49 | | PLAIN_TEXT, |
50 | | COMBO_BOX, |
51 | | }; |
52 | | |
53 | | /// SfxPoolItem subclass that wraps an SwContentControl. |
54 | | class SW_DLLPUBLIC SwFormatContentControl final : public SfxPoolItem |
55 | | { |
56 | | std::shared_ptr<SwContentControl> m_pContentControl; |
57 | | SwTextContentControl* m_pTextAttr; |
58 | | |
59 | | public: |
60 | 9.90k | SwTextContentControl* GetTextAttr() { return m_pTextAttr; } |
61 | | void SetTextAttr(SwTextContentControl* pTextAttr); |
62 | | |
63 | | /// This method must be called when the hint is actually copied. |
64 | | void DoCopy(SwTextNode& rTargetTextNode); |
65 | | |
66 | | DECLARE_ITEM_TYPE_FUNCTION(SwFormatContentControl) |
67 | | explicit SwFormatContentControl(sal_uInt16 nWhich); |
68 | | |
69 | | explicit SwFormatContentControl(const std::shared_ptr<SwContentControl>& pContentControl, |
70 | | sal_uInt16 nWhich); |
71 | | ~SwFormatContentControl() override; |
72 | | |
73 | | /// SfxPoolItem |
74 | | bool operator==(const SfxPoolItem&) const override; |
75 | | SwFormatContentControl* Clone(SfxItemPool* pPool = nullptr) const override; |
76 | | |
77 | | /** |
78 | | * Notify clients registered at m_pContentControl that this content control is being |
79 | | * (re-)moved. |
80 | | */ |
81 | | void NotifyChangeTextNode(SwTextNode* pTextNode); |
82 | | SwTextNode* GetTextNode() const; |
83 | | static SwFormatContentControl* CreatePoolDefault(sal_uInt16 nWhich); |
84 | 2.66k | const std::shared_ptr<SwContentControl>& GetContentControl() const { return m_pContentControl; } |
85 | | |
86 | | void dumpAsXml(xmlTextWriterPtr pWriter) const override; |
87 | | }; |
88 | | |
89 | | /// Represents one list item in a content control dropdown list. |
90 | | class SW_DLLPUBLIC SwContentControlListItem |
91 | | { |
92 | | public: |
93 | | /// This may be empty, ToString() falls back to m_aValue. |
94 | | OUString m_aDisplayText; |
95 | | /// This must not be empty. |
96 | | OUString m_aValue; |
97 | | |
98 | | void dumpAsXml(xmlTextWriterPtr pWriter) const; |
99 | | |
100 | | const OUString& ToString() const; |
101 | | |
102 | | bool operator==(const SwContentControlListItem& rOther) const; |
103 | | |
104 | | static void ItemsToAny(const std::vector<SwContentControlListItem>& rItems, |
105 | | css::uno::Any& rVal); |
106 | | |
107 | | static std::vector<SwContentControlListItem> ItemsFromAny(const css::uno::Any& rVal); |
108 | | }; |
109 | | |
110 | | /// Stores the properties of a content control. |
111 | | class SW_DLLPUBLIC SwContentControl final : public sw::BroadcastingModify |
112 | | { |
113 | | unotools::WeakReference<SwXContentControl> m_wXContentControl; |
114 | | |
115 | | SwFormatContentControl* m_pFormat; |
116 | | |
117 | | /// Can be nullptr if not in a document for undo purposes. |
118 | | SwTextNode* m_pTextNode; |
119 | | |
120 | | /// Current content is placeholder text. |
121 | | bool m_bShowingPlaceHolder = false; |
122 | | |
123 | | /// Display the content control as a checkbox. |
124 | | bool m_bCheckbox = false; |
125 | | |
126 | | /// If m_bCheckbox is true, is the checkbox checked? |
127 | | bool m_bChecked = false; |
128 | | |
129 | | /// If m_bCheckbox is true, the value of a checked checkbox. |
130 | | OUString m_aCheckedState; |
131 | | |
132 | | /// If m_bCheckbox is true, the value of an unchecked checkbox. |
133 | | OUString m_aUncheckedState; |
134 | | |
135 | | std::vector<SwContentControlListItem> m_aListItems; |
136 | | |
137 | | bool m_bPicture = false; |
138 | | |
139 | | bool m_bDate = false; |
140 | | |
141 | | /// If m_bDate is true, the date format in a syntax accepted by SvNumberFormatter::PutEntry(). |
142 | | OUString m_aDateFormat; |
143 | | |
144 | | /// If m_bDate is true, the date's BCP 47 language tag. |
145 | | OUString m_aDateLanguage; |
146 | | |
147 | | /// Date in YYYY-MM-DDT00:00:00Z format. |
148 | | OUString m_aCurrentDate; |
149 | | |
150 | | /// Plain text, i.e. not rich text. |
151 | | bool m_bPlainText = false; |
152 | | |
153 | | /// Same as drop-down, but free-form input is also accepted. |
154 | | bool m_bComboBox = false; |
155 | | |
156 | | /// Same as combo box, but free-form input is not accepted. |
157 | | bool m_bDropDown = false; |
158 | | |
159 | | /// The placeholder's doc part: just remembered. |
160 | | OUString m_aPlaceholderDocPart; |
161 | | |
162 | | /// The data bindings's prefix mappings: just remembered. |
163 | | OUString m_aDataBindingPrefixMappings; |
164 | | |
165 | | /// The data bindings's XPath: just remembered. |
166 | | OUString m_aDataBindingXpath; |
167 | | |
168 | | /// The data bindings's store item ID: just remembered. |
169 | | OUString m_aDataBindingStoreItemID; |
170 | | |
171 | | /// The color: just remembered. |
172 | | OUString m_aColor; |
173 | | |
174 | | /// The appearance: just remembered. |
175 | | OUString m_aAppearance; |
176 | | |
177 | | /// The alias. |
178 | | OUString m_aAlias; |
179 | | |
180 | | /// The tag: just remembered. |
181 | | OUString m_aTag; |
182 | | |
183 | | /// The id: just remembered. |
184 | | sal_Int32 m_nId = 0; |
185 | | |
186 | | /// The tabIndex: just remembered. |
187 | | sal_uInt32 m_nTabIndex = 0; |
188 | | |
189 | | /// The control and content locks: mostly just remembered. |
190 | | OUString m_aLock; |
191 | | |
192 | | /// The multiline property: just remembered. |
193 | | OUString m_aMultiLine; |
194 | | |
195 | | /// Stores a list item index, in case the doc model is not yet updated. |
196 | | // i.e. temporarily store the selected item until the text is inserted by GotoContentControl. |
197 | | std::optional<size_t> m_oSelectedListItem; |
198 | | |
199 | | /// Stores a date timestamp, in case the doc model is not yet updated. |
200 | | // i.e. temporarily store the date until the text is inserted by GotoContentControl. |
201 | | std::optional<double> m_oSelectedDate; |
202 | | |
203 | | /** |
204 | | * E.g. checkbox is read-only by default, but we still update contents on interaction |
205 | | * internally. This flag is true for the duration of that interaction. |
206 | | */ |
207 | | bool m_bReadWrite = false; |
208 | | |
209 | | public: |
210 | | SwTextContentControl* GetTextAttr() const; |
211 | | |
212 | 0 | SwTextNode* GetTextNode() const { return m_pTextNode; } |
213 | | |
214 | 20.6k | SwFormatContentControl* GetFormatContentControl() const { return m_pFormat; } |
215 | | |
216 | 6.28k | void SetFormatContentControl(SwFormatContentControl* pFormat) { m_pFormat = pFormat; }; |
217 | | |
218 | | void NotifyChangeTextNode(SwTextNode* pTextNode); |
219 | | |
220 | | const unotools::WeakReference<SwXContentControl>& GetXContentControl() const |
221 | 0 | { |
222 | 0 | return m_wXContentControl; |
223 | 0 | } |
224 | | |
225 | | void SetXContentControl(const rtl::Reference<SwXContentControl>& xContentControl); |
226 | | |
227 | | virtual void SwClientNotify(const SwModify&, const SfxHint&) override; |
228 | | |
229 | | explicit SwContentControl(SwFormatContentControl* pFormat); |
230 | | |
231 | | virtual ~SwContentControl() override; |
232 | | |
233 | | void SetShowingPlaceHolder(bool bShowingPlaceHolder) |
234 | 3.14k | { |
235 | 3.14k | m_bShowingPlaceHolder = bShowingPlaceHolder; |
236 | 3.14k | } |
237 | | |
238 | 0 | bool GetShowingPlaceHolder() const { return m_bShowingPlaceHolder; } |
239 | | |
240 | 3.14k | void SetCheckbox(bool bCheckbox) { m_bCheckbox = bCheckbox; } |
241 | | |
242 | 0 | bool GetCheckbox() const { return m_bCheckbox; } |
243 | | |
244 | 3.14k | void SetChecked(bool bChecked) { m_bChecked = bChecked; } |
245 | | |
246 | 0 | bool GetChecked() const { return m_bChecked; } |
247 | | |
248 | 3.14k | void SetCheckedState(const OUString& rCheckedState) { m_aCheckedState = rCheckedState; } |
249 | | |
250 | 0 | const OUString& GetCheckedState() const { return m_aCheckedState; } |
251 | | |
252 | 3.14k | void SetUncheckedState(const OUString& rUncheckedState) { m_aUncheckedState = rUncheckedState; } |
253 | | |
254 | 0 | const OUString& GetUncheckedState() const { return m_aUncheckedState; } |
255 | | |
256 | 0 | const std::vector<SwContentControlListItem>& GetListItems() const { return m_aListItems; } |
257 | | |
258 | | void SetListItems(const std::vector<SwContentControlListItem>& rListItems) |
259 | 3.14k | { |
260 | 3.14k | m_aListItems = rListItems; |
261 | 3.14k | } |
262 | | void SetListItems(std::vector<SwContentControlListItem>&& rListItems) |
263 | 0 | { |
264 | 0 | m_aListItems = std::move(rListItems); |
265 | 0 | } |
266 | | |
267 | | bool AddListItem(size_t nZIndex, const OUString& rDisplayText, const OUString& rValue); |
268 | | void DeleteListItem(size_t nZIndex); |
269 | | void ClearListItems(); |
270 | | |
271 | 3.14k | void SetPicture(bool bPicture) { m_bPicture = bPicture; } |
272 | | |
273 | 0 | bool GetPicture() const { return m_bPicture; } |
274 | | |
275 | 3.14k | void SetDate(bool bDate) { m_bDate = bDate; } |
276 | | |
277 | 0 | bool GetDate() const { return m_bDate; } |
278 | | |
279 | 3.14k | void SetDateFormat(const OUString& rDateFormat) { m_aDateFormat = rDateFormat; } |
280 | | |
281 | 0 | const OUString& GetDateFormat() const { return m_aDateFormat; } |
282 | | |
283 | 3.14k | void SetDateLanguage(const OUString& rDateLanguage) { m_aDateLanguage = rDateLanguage; } |
284 | | |
285 | 0 | const OUString& GetDateLanguage() const { return m_aDateLanguage; } |
286 | | |
287 | 3.14k | void SetCurrentDate(const OUString& rCurrentDate) { m_aCurrentDate = rCurrentDate; } |
288 | | |
289 | 0 | const OUString& GetCurrentDate() const { return m_aCurrentDate; } |
290 | | |
291 | | /// Formats fCurrentDate and sets it. |
292 | | void SetCurrentDateValue(double fCurrentDate); |
293 | | |
294 | | /// Parses m_aCurrentDate and returns it. |
295 | | std::optional<double> GetCurrentDateValue() const; |
296 | | |
297 | | /// Formats m_oSelectedDate, taking m_aDateFormat and m_aDateLanguage into account. |
298 | | OUString GetDateString(bool bAsISO8601 = false) const; |
299 | | |
300 | 3.14k | void SetPlainText(bool bPlainText) { m_bPlainText = bPlainText; } |
301 | | |
302 | 0 | bool GetPlainText() const { return m_bPlainText; } |
303 | | |
304 | 3.14k | void SetComboBox(bool bComboBox) { m_bComboBox = bComboBox; } |
305 | | |
306 | 0 | bool GetComboBox() const { return m_bComboBox; } |
307 | | |
308 | 3.14k | void SetDropDown(bool bDropDown) { m_bDropDown = bDropDown; } |
309 | | |
310 | 0 | bool GetDropDown() const { return m_bDropDown; } |
311 | | |
312 | | void SetPlaceholderDocPart(const OUString& rPlaceholderDocPart) |
313 | 3.14k | { |
314 | 3.14k | m_aPlaceholderDocPart = rPlaceholderDocPart; |
315 | 3.14k | } |
316 | | |
317 | 0 | const OUString& GetPlaceholderDocPart() const { return m_aPlaceholderDocPart; } |
318 | | |
319 | | void SetSelectedListItem(std::optional<size_t> oSelectedListItem) |
320 | 0 | { |
321 | 0 | m_oSelectedListItem = oSelectedListItem; |
322 | 0 | } |
323 | | |
324 | 0 | const std::optional<size_t>& GetSelectedListItem() const { return m_oSelectedListItem; } |
325 | | |
326 | | /// Get a copy of selected list item's index, |
327 | | /// potentially even if the selection is already written out to text (i.e. validated). |
328 | | std::optional<size_t> GetSelectedListItem(bool bCheckDocModel) const; |
329 | | |
330 | 0 | void SetSelectedDate(std::optional<double> oSelectedDate) { m_oSelectedDate = oSelectedDate; } |
331 | | |
332 | 0 | const std::optional<double>& GetSelectedDate() const { return m_oSelectedDate; } |
333 | | |
334 | | /// Should this character (during key input) interact with the content control? |
335 | | bool IsInteractingCharacter(sal_Unicode cCh); |
336 | | |
337 | | /// Given rKeyCode as a keyboard event, should a popup be opened for this content control? |
338 | | bool ShouldOpenPopup(const vcl::KeyCode& rKeyCode); |
339 | | |
340 | | void dumpAsXml(xmlTextWriterPtr pWriter) const; |
341 | | |
342 | | void SetDataBindingPrefixMappings(const OUString& rDataBindingPrefixMappings) |
343 | 3.14k | { |
344 | 3.14k | m_aDataBindingPrefixMappings = rDataBindingPrefixMappings; |
345 | 3.14k | } |
346 | | |
347 | 0 | const OUString& GetDataBindingPrefixMappings() const { return m_aDataBindingPrefixMappings; } |
348 | | |
349 | | void SetDataBindingXpath(const OUString& rDataBindingXpath) |
350 | 3.14k | { |
351 | 3.14k | m_aDataBindingXpath = rDataBindingXpath; |
352 | 3.14k | } |
353 | | |
354 | 0 | const OUString& GetDataBindingXpath() const { return m_aDataBindingXpath; } |
355 | | |
356 | | void SetDataBindingStoreItemID(const OUString& rDataBindingStoreItemID) |
357 | 3.14k | { |
358 | 3.14k | m_aDataBindingStoreItemID = rDataBindingStoreItemID; |
359 | 3.14k | } |
360 | | |
361 | 0 | const OUString& GetDataBindingStoreItemID() const { return m_aDataBindingStoreItemID; } |
362 | | |
363 | 3.14k | void SetColor(const OUString& rColor) { m_aColor = rColor; } |
364 | | |
365 | 0 | const OUString& GetColor() const { return m_aColor; } |
366 | | |
367 | 3.14k | void SetAppearance(const OUString& rAppearance) { m_aAppearance = rAppearance; } |
368 | | |
369 | 0 | const OUString& GetAppearance() const { return m_aAppearance; } |
370 | | |
371 | 3.14k | void SetAlias(const OUString& rAlias) { m_aAlias = rAlias; } |
372 | | |
373 | 0 | const OUString& GetAlias() const { return m_aAlias; } |
374 | | |
375 | 3.14k | void SetTag(const OUString& rTag) { m_aTag = rTag; } |
376 | | |
377 | 0 | const OUString& GetTag() const { return m_aTag; } |
378 | | |
379 | 3.14k | void SetId(sal_Int32 nId) { m_nId = nId; } |
380 | | |
381 | 0 | sal_Int32 GetId() const { return m_nId; } |
382 | | |
383 | 3.14k | void SetTabIndex(sal_uInt32 nTabIndex) { m_nTabIndex = nTabIndex; } |
384 | | |
385 | 0 | sal_uInt32 GetTabIndex() const { return m_nTabIndex; } |
386 | | |
387 | | // At the design level, define how the control should be locked. No effect at implementation lvl |
388 | | void SetLock(bool bLockContent, bool bLockControl); |
389 | 3.14k | void SetLock(const OUString& rLock) { m_aLock = rLock; } |
390 | | |
391 | | // At the design level, get how the control is locked. Does not reflect actual implementation. |
392 | | std::optional<bool> GetLock(bool bControl) const; |
393 | 0 | const OUString& GetLock() const { return m_aLock; } |
394 | | |
395 | 0 | void SetReadWrite(bool bReadWrite) { m_bReadWrite = bReadWrite; } |
396 | | |
397 | | // At the implementation level, define whether the user can directly modify the contents. |
398 | 0 | bool GetReadWrite() const { return m_bReadWrite; } |
399 | | |
400 | 3.14k | void SetMultiLine(const OUString& rMultiline) { m_aMultiLine = rMultiline; } |
401 | | |
402 | 0 | const OUString& GetMultiLine() const { return m_aMultiLine; } |
403 | | |
404 | | SwContentControlType GetType() const; |
405 | | |
406 | | // Ballot Box with X |
407 | | static constexpr OUString CHECKED_STATE = u"\u2612"_ustr; |
408 | | // Ballot Box |
409 | | static constexpr OUString UNCHECKED_STATE = u"\u2610"_ustr; |
410 | | }; |
411 | | |
412 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |