/src/libreoffice/sc/source/ui/unoobj/fielduno.cxx
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 | | #include <memory> |
21 | | #include <fielduno.hxx> |
22 | | #include <textuno.hxx> |
23 | | #include <miscuno.hxx> |
24 | | #include <docsh.hxx> |
25 | | #include <hints.hxx> |
26 | | #include <editsrc.hxx> |
27 | | #include <unonames.hxx> |
28 | | #include <editutil.hxx> |
29 | | |
30 | | #include <svl/hint.hxx> |
31 | | #include <utility> |
32 | | #include <vcl/svapp.hxx> |
33 | | |
34 | | #include <editeng/eeitem.hxx> |
35 | | |
36 | | #include <editeng/editeng.hxx> |
37 | | #include <editeng/editobj.hxx> |
38 | | #include <editeng/flditem.hxx> |
39 | | #include <comphelper/sequence.hxx> |
40 | | #include <cppuhelper/supportsservice.hxx> |
41 | | |
42 | | #include <com/sun/star/beans/PropertyAttribute.hpp> |
43 | | #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> |
44 | | #include <com/sun/star/text/TextContentAnchorType.hpp> |
45 | | #include <com/sun/star/text/WrapTextMode.hpp> |
46 | | #include <com/sun/star/text/FilenameDisplayFormat.hpp> |
47 | | #include <com/sun/star/text/textfield/Type.hpp> |
48 | | |
49 | | using namespace com::sun::star; |
50 | | |
51 | | namespace { |
52 | | |
53 | | // no Which-ID here, map only for PropertySetInfo |
54 | | |
55 | | const SfxItemPropertySet* getDateTimePropertySet() |
56 | 11.7k | { |
57 | 11.7k | static const SfxItemPropertyMapEntry aMapContent[] = |
58 | 11.7k | { |
59 | 11.7k | { SC_UNONAME_DATETIME, 0, cppu::UnoType<util::DateTime>::get(), 0, 0 }, |
60 | 11.7k | { SC_UNONAME_ISFIXED, 0, cppu::UnoType<bool>::get(), 0, 0 }, |
61 | 11.7k | { SC_UNONAME_ISDATE, 0, cppu::UnoType<bool>::get(), 0, 0 }, |
62 | 11.7k | { SC_UNONAME_NUMFMT, 0, cppu::UnoType<sal_Int32>::get(), 0, 0 }, |
63 | 11.7k | }; |
64 | 11.7k | static SfxItemPropertySet aMap(aMapContent); |
65 | 11.7k | return &aMap; |
66 | 11.7k | } |
67 | | |
68 | | const SfxItemPropertySet* getEmptyPropertySet() |
69 | 172 | { |
70 | 172 | static SfxItemPropertySet aMap({}); |
71 | 172 | return &aMap; |
72 | 172 | } |
73 | | |
74 | | const SfxItemPropertySet* lcl_GetURLPropertySet() |
75 | 0 | { |
76 | 0 | static const SfxItemPropertyMapEntry aURLPropertyMap_Impl[] = |
77 | 0 | { |
78 | 0 | { SC_UNONAME_ANCTYPE, 0, cppu::UnoType<text::TextContentAnchorType>::get(), beans::PropertyAttribute::READONLY, 0 }, |
79 | 0 | { SC_UNONAME_ANCTYPES, 0, cppu::UnoType<uno::Sequence<text::TextContentAnchorType>>::get(), beans::PropertyAttribute::READONLY, 0 }, |
80 | 0 | { SC_UNONAME_REPR, 0, cppu::UnoType<OUString>::get(), 0, 0}, |
81 | 0 | { SC_UNONAME_TARGET, 0, cppu::UnoType<OUString>::get(), 0, 0}, |
82 | 0 | { SC_UNONAME_TEXTWRAP, 0, cppu::UnoType<text::WrapTextMode>::get(), beans::PropertyAttribute::READONLY, 0 }, |
83 | 0 | { SC_UNONAME_URL, 0, cppu::UnoType<OUString>::get(), 0, 0}, |
84 | 0 | { SC_UNONAME_FORMAT, 0, cppu::UnoType<sal_Int16>::get(), 0, 0 }, |
85 | 0 | }; |
86 | 0 | static SfxItemPropertySet aURLPropertySet_Impl( aURLPropertyMap_Impl ); |
87 | 0 | return &aURLPropertySet_Impl; |
88 | 0 | } |
89 | | |
90 | | const SfxItemPropertySet* lcl_GetHeaderFieldPropertySet() |
91 | 13.3k | { |
92 | 13.3k | static const SfxItemPropertyMapEntry aHeaderFieldPropertyMap_Impl[] = |
93 | 13.3k | { |
94 | 13.3k | { SC_UNONAME_ANCTYPE, 0, cppu::UnoType<text::TextContentAnchorType>::get(), beans::PropertyAttribute::READONLY, 0 }, |
95 | 13.3k | { SC_UNONAME_ANCTYPES, 0, cppu::UnoType<uno::Sequence<text::TextContentAnchorType>>::get(), beans::PropertyAttribute::READONLY, 0 }, |
96 | 13.3k | { SC_UNONAME_TEXTWRAP, 0, cppu::UnoType<text::WrapTextMode>::get(), beans::PropertyAttribute::READONLY, 0 }, |
97 | 13.3k | }; |
98 | 13.3k | static SfxItemPropertySet aHeaderFieldPropertySet_Impl( aHeaderFieldPropertyMap_Impl ); |
99 | 13.3k | return &aHeaderFieldPropertySet_Impl; |
100 | 13.3k | } |
101 | | |
102 | | const SfxItemPropertySet* lcl_GetFileFieldPropertySet() |
103 | 90 | { |
104 | 90 | static const SfxItemPropertyMapEntry aFileFieldPropertyMap_Impl[] = |
105 | 90 | { |
106 | 90 | { SC_UNONAME_ANCTYPE, 0, cppu::UnoType<text::TextContentAnchorType>::get(), beans::PropertyAttribute::READONLY, 0 }, |
107 | 90 | { SC_UNONAME_ANCTYPES, 0, cppu::UnoType<uno::Sequence<text::TextContentAnchorType>>::get(), beans::PropertyAttribute::READONLY, 0 }, |
108 | 90 | { SC_UNONAME_FILEFORM, 0, cppu::UnoType<sal_Int16>::get(), 0, 0 }, |
109 | 90 | { SC_UNONAME_TEXTWRAP, 0, cppu::UnoType<text::WrapTextMode>::get(), beans::PropertyAttribute::READONLY, 0 }, |
110 | 90 | }; |
111 | 90 | static SfxItemPropertySet aFileFieldPropertySet_Impl( aFileFieldPropertyMap_Impl ); |
112 | 90 | return &aFileFieldPropertySet_Impl; |
113 | 90 | } |
114 | | |
115 | | SvxFileFormat lcl_UnoToSvxFileFormat( sal_Int16 nUnoValue ) |
116 | 90 | { |
117 | 90 | switch( nUnoValue ) |
118 | 90 | { |
119 | 57 | case text::FilenameDisplayFormat::FULL: return SvxFileFormat::PathFull; |
120 | 0 | case text::FilenameDisplayFormat::PATH: return SvxFileFormat::PathOnly; |
121 | 0 | case text::FilenameDisplayFormat::NAME: return SvxFileFormat::NameOnly; |
122 | 33 | default: |
123 | 33 | return SvxFileFormat::NameAndExt; |
124 | 90 | } |
125 | 90 | } |
126 | | |
127 | | sal_Int16 lcl_SvxToUnoFileFormat( SvxFileFormat nSvxValue ) |
128 | 0 | { |
129 | 0 | switch( nSvxValue ) |
130 | 0 | { |
131 | 0 | case SvxFileFormat::NameAndExt: return text::FilenameDisplayFormat::NAME_AND_EXT; |
132 | 0 | case SvxFileFormat::PathFull: return text::FilenameDisplayFormat::FULL; |
133 | 0 | case SvxFileFormat::PathOnly: return text::FilenameDisplayFormat::PATH; |
134 | 0 | default: |
135 | 0 | return text::FilenameDisplayFormat::NAME; |
136 | 0 | } |
137 | 0 | } |
138 | | |
139 | | } |
140 | | |
141 | | SC_SIMPLE_SERVICE_INFO( ScCellFieldsObj, u"ScCellFieldsObj"_ustr, u"com.sun.star.text.TextFields"_ustr ) |
142 | | SC_SIMPLE_SERVICE_INFO( ScHeaderFieldsObj, u"ScHeaderFieldsObj"_ustr, u"com.sun.star.text.TextFields"_ustr ) |
143 | | |
144 | | namespace { |
145 | | |
146 | | enum ScUnoCollectMode |
147 | | { |
148 | | SC_UNO_COLLECT_NONE, |
149 | | SC_UNO_COLLECT_COUNT, |
150 | | SC_UNO_COLLECT_FINDINDEX, |
151 | | SC_UNO_COLLECT_FINDPOS |
152 | | }; |
153 | | |
154 | | /** |
155 | | * This class exists solely to allow searching through field items. TODO: |
156 | | * Look into providing the same functionality directly in EditEngine, to |
157 | | * avoid having this class altogether. |
158 | | */ |
159 | | class ScUnoEditEngine : public ScEditEngineDefaulter |
160 | | { |
161 | | ScUnoCollectMode eMode; |
162 | | sal_uInt16 nFieldCount; |
163 | | sal_Int32 mnFieldType; |
164 | | std::unique_ptr<SvxFieldData> |
165 | | pFound; // local copy |
166 | | sal_Int32 nFieldPar; |
167 | | sal_Int32 nFieldPos; |
168 | | sal_uInt16 nFieldIndex; |
169 | | |
170 | | public: |
171 | | explicit ScUnoEditEngine(ScEditEngineDefaulter* pSource); |
172 | | |
173 | | virtual OUString CalcFieldValue( const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos, |
174 | | std::optional<Color>& rTxtColor, std::optional<Color>& rFldColor, std::optional<FontLineStyle>& rFldLineStyle ) override; |
175 | | |
176 | | sal_uInt16 CountFields(); |
177 | | SvxFieldData* FindByIndex(sal_uInt16 nIndex); |
178 | | SvxFieldData* FindByPos(const EPaM& rPos, sal_Int32 nType); |
179 | | |
180 | 0 | sal_Int32 GetFieldPar() const { return nFieldPar; } |
181 | 0 | sal_Int32 GetFieldPos() const { return nFieldPos; } |
182 | | }; |
183 | | |
184 | | } |
185 | | |
186 | | ScUnoEditEngine::ScUnoEditEngine(ScEditEngineDefaulter* pSource) |
187 | 0 | : ScEditEngineDefaulter(*pSource) |
188 | 0 | , eMode(SC_UNO_COLLECT_NONE) |
189 | 0 | , nFieldCount(0) |
190 | 0 | , mnFieldType(text::textfield::Type::UNSPECIFIED) |
191 | 0 | , nFieldPar(0) |
192 | 0 | , nFieldPos(0) |
193 | 0 | , nFieldIndex(0) |
194 | 0 | { |
195 | 0 | std::unique_ptr<EditTextObject> pData = pSource->CreateTextObject(); |
196 | 0 | SetTextCurrentDefaults( *pData ); |
197 | 0 | } |
198 | | |
199 | | OUString ScUnoEditEngine::CalcFieldValue( const SvxFieldItem& rField, |
200 | | sal_Int32 nPara, sal_Int32 nPos, std::optional<Color>& rTxtColor, std::optional<Color>& rFldColor, std::optional<FontLineStyle>& rFldLineStyle ) |
201 | 0 | { |
202 | 0 | OUString aRet(EditEngine::CalcFieldValue( rField, nPara, nPos, rTxtColor, rFldColor, rFldLineStyle )); |
203 | 0 | if (eMode != SC_UNO_COLLECT_NONE) |
204 | 0 | { |
205 | 0 | const SvxFieldData* pFieldData = rField.GetField(); |
206 | 0 | if ( pFieldData ) |
207 | 0 | { |
208 | 0 | if (mnFieldType == text::textfield::Type::UNSPECIFIED || pFieldData->GetClassId() == mnFieldType) |
209 | 0 | { |
210 | 0 | if ( eMode == SC_UNO_COLLECT_FINDINDEX && !pFound && nFieldCount == nFieldIndex ) |
211 | 0 | { |
212 | 0 | pFound = pFieldData->Clone(); |
213 | 0 | nFieldPar = nPara; |
214 | 0 | nFieldPos = nPos; |
215 | 0 | } |
216 | 0 | if ( eMode == SC_UNO_COLLECT_FINDPOS && !pFound && |
217 | 0 | nPara == nFieldPar && nPos == nFieldPos ) |
218 | 0 | { |
219 | 0 | pFound = pFieldData->Clone(); |
220 | 0 | nFieldIndex = nFieldCount; |
221 | 0 | } |
222 | 0 | ++nFieldCount; |
223 | 0 | } |
224 | 0 | } |
225 | 0 | } |
226 | 0 | return aRet; |
227 | 0 | } |
228 | | |
229 | | sal_uInt16 ScUnoEditEngine::CountFields() |
230 | 0 | { |
231 | 0 | eMode = SC_UNO_COLLECT_COUNT; |
232 | 0 | mnFieldType = text::textfield::Type::UNSPECIFIED; |
233 | 0 | nFieldCount = 0; |
234 | 0 | UpdateFields(); |
235 | 0 | eMode = SC_UNO_COLLECT_NONE; |
236 | |
|
237 | 0 | return nFieldCount; |
238 | 0 | } |
239 | | |
240 | | SvxFieldData* ScUnoEditEngine::FindByIndex(sal_uInt16 nIndex) |
241 | 0 | { |
242 | 0 | eMode = SC_UNO_COLLECT_FINDINDEX; |
243 | 0 | nFieldIndex = nIndex; |
244 | 0 | mnFieldType = text::textfield::Type::UNSPECIFIED; |
245 | 0 | nFieldCount = 0; |
246 | 0 | UpdateFields(); |
247 | 0 | eMode = SC_UNO_COLLECT_NONE; |
248 | |
|
249 | 0 | return pFound.get(); |
250 | 0 | } |
251 | | |
252 | | SvxFieldData* ScUnoEditEngine::FindByPos(const EPaM& rPos, sal_Int32 nType) |
253 | 0 | { |
254 | 0 | eMode = SC_UNO_COLLECT_FINDPOS; |
255 | 0 | nFieldPar = rPos.nPara; |
256 | 0 | nFieldPos = rPos.nIndex; |
257 | 0 | mnFieldType = nType; |
258 | 0 | nFieldCount = 0; |
259 | 0 | UpdateFields(); |
260 | 0 | mnFieldType = text::textfield::Type::UNSPECIFIED; |
261 | 0 | eMode = SC_UNO_COLLECT_NONE; |
262 | |
|
263 | 0 | return pFound.get(); |
264 | 0 | } |
265 | | |
266 | | ScCellFieldsObj::ScCellFieldsObj( |
267 | | uno::Reference<text::XTextRange> xContent, |
268 | | ScDocShell* pDocSh, const ScAddress& rPos) : |
269 | 0 | mxContent(std::move(xContent)), |
270 | 0 | pDocShell( pDocSh ), |
271 | 0 | aCellPos( rPos ) |
272 | 0 | { |
273 | 0 | pDocShell->GetDocument().AddUnoObject(*this); |
274 | |
|
275 | 0 | mpEditSource.reset( new ScCellEditSource( pDocShell, aCellPos ) ); |
276 | 0 | } |
277 | | |
278 | | ScCellFieldsObj::~ScCellFieldsObj() |
279 | 0 | { |
280 | 0 | { |
281 | 0 | SolarMutexGuard g; |
282 | |
|
283 | 0 | if (pDocShell) |
284 | 0 | pDocShell->GetDocument().RemoveUnoObject(*this); |
285 | |
|
286 | 0 | mpEditSource.reset(); |
287 | 0 | } |
288 | | |
289 | | // increment refcount to prevent double call of dtor |
290 | 0 | osl_atomic_increment( &m_refCount ); |
291 | |
|
292 | 0 | std::unique_lock g(aMutex); |
293 | 0 | if (maRefreshListeners.getLength(g)) |
294 | 0 | { |
295 | 0 | lang::EventObject aEvent; |
296 | 0 | aEvent.Source.set(getXWeak()); |
297 | 0 | maRefreshListeners.disposeAndClear(g, aEvent); |
298 | 0 | } |
299 | 0 | } |
300 | | |
301 | | void ScCellFieldsObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) |
302 | 0 | { |
303 | 0 | if ( rHint.GetId() == SfxHintId::ScUpdateRef ) |
304 | 0 | { |
305 | | //! update of references |
306 | 0 | } |
307 | 0 | else if ( rHint.GetId() == SfxHintId::Dying ) |
308 | 0 | { |
309 | 0 | pDocShell = nullptr; // became invalid |
310 | 0 | } |
311 | | |
312 | | // EditSource registered itself as a listener |
313 | 0 | } |
314 | | |
315 | | // XIndexAccess (via XTextFields) |
316 | | |
317 | | uno::Reference<text::XTextField> ScCellFieldsObj::GetObjectByIndex_Impl(sal_Int32 Index) const |
318 | 0 | { |
319 | | //! Field functions have to be passed to the forwarder !!! |
320 | 0 | ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); |
321 | 0 | ScUnoEditEngine aTempEngine(pEditEngine); |
322 | 0 | SvxFieldData* pData = aTempEngine.FindByIndex(static_cast<sal_uInt16>(Index)); |
323 | 0 | if (!pData) |
324 | 0 | return uno::Reference<text::XTextField>(); |
325 | | |
326 | 0 | sal_Int32 nPar = aTempEngine.GetFieldPar(); |
327 | 0 | sal_Int32 nPos = aTempEngine.GetFieldPos(); |
328 | 0 | ESelection aSelection( nPar, nPos, nPar, nPos+1 ); // Field size is 1 character |
329 | |
|
330 | 0 | sal_Int32 eType = pData->GetClassId(); |
331 | 0 | uno::Reference<text::XTextField> xRet( |
332 | 0 | new ScEditFieldObj(mxContent, std::make_unique<ScCellEditSource>(pDocShell, aCellPos), eType, aSelection)); |
333 | 0 | return xRet; |
334 | 0 | } |
335 | | |
336 | | sal_Int32 SAL_CALL ScCellFieldsObj::getCount() |
337 | 0 | { |
338 | 0 | SolarMutexGuard aGuard; |
339 | | |
340 | | //! Field functions have to be passed to the forwarder !!! |
341 | 0 | ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); |
342 | 0 | ScUnoEditEngine aTempEngine(pEditEngine); |
343 | |
|
344 | 0 | return aTempEngine.CountFields(); // count the fields, we don't care about their type in the cell |
345 | 0 | } |
346 | | |
347 | | uno::Any SAL_CALL ScCellFieldsObj::getByIndex( sal_Int32 nIndex ) |
348 | 0 | { |
349 | 0 | SolarMutexGuard aGuard; |
350 | 0 | uno::Reference<text::XTextField> xField(GetObjectByIndex_Impl(nIndex)); |
351 | 0 | if (!xField.is()) |
352 | 0 | throw lang::IndexOutOfBoundsException(); |
353 | | |
354 | 0 | return uno::Any(xField); |
355 | 0 | } |
356 | | |
357 | | uno::Type SAL_CALL ScCellFieldsObj::getElementType() |
358 | 0 | { |
359 | 0 | return cppu::UnoType<text::XTextField>::get(); |
360 | 0 | } |
361 | | |
362 | | sal_Bool SAL_CALL ScCellFieldsObj::hasElements() |
363 | 0 | { |
364 | 0 | SolarMutexGuard aGuard; |
365 | 0 | return ( getCount() != 0 ); |
366 | 0 | } |
367 | | |
368 | | uno::Reference<container::XEnumeration> SAL_CALL ScCellFieldsObj::createEnumeration() |
369 | 0 | { |
370 | 0 | SolarMutexGuard aGuard; |
371 | 0 | return new ScIndexEnumeration(this, u"com.sun.star.text.TextFieldEnumeration"_ustr); |
372 | 0 | } |
373 | | |
374 | | void SAL_CALL ScCellFieldsObj::addContainerListener( |
375 | | const uno::Reference<container::XContainerListener>& /* xListener */ ) |
376 | 0 | { |
377 | 0 | OSL_FAIL("not implemented"); |
378 | 0 | } |
379 | | |
380 | | void SAL_CALL ScCellFieldsObj::removeContainerListener( |
381 | | const uno::Reference<container::XContainerListener>& /* xListener */ ) |
382 | 0 | { |
383 | 0 | OSL_FAIL("not implemented"); |
384 | 0 | } |
385 | | |
386 | | // XRefreshable |
387 | | void SAL_CALL ScCellFieldsObj::refresh( ) |
388 | 0 | { |
389 | 0 | std::unique_lock g(aMutex); |
390 | 0 | if (maRefreshListeners.getLength(g)) |
391 | 0 | { |
392 | | // Call all listeners. |
393 | 0 | lang::EventObject aEvent; |
394 | 0 | aEvent.Source.set(uno::Reference< util::XRefreshable >(this)); |
395 | 0 | maRefreshListeners.notifyEach( g, &util::XRefreshListener::refreshed, aEvent ); |
396 | 0 | } |
397 | 0 | } |
398 | | |
399 | | void SAL_CALL ScCellFieldsObj::addRefreshListener( const uno::Reference< util::XRefreshListener >& xListener ) |
400 | 0 | { |
401 | 0 | if (xListener.is()) |
402 | 0 | { |
403 | 0 | std::unique_lock g(aMutex); |
404 | 0 | maRefreshListeners.addInterface(g, xListener); |
405 | 0 | } |
406 | 0 | } |
407 | | |
408 | | void SAL_CALL ScCellFieldsObj::removeRefreshListener( const uno::Reference<util::XRefreshListener >& xListener ) |
409 | 0 | { |
410 | 0 | if (xListener.is()) |
411 | 0 | { |
412 | 0 | std::unique_lock g(aMutex); |
413 | 0 | maRefreshListeners.removeInterface(g, xListener); |
414 | 0 | } |
415 | 0 | } |
416 | | |
417 | | ScHeaderFieldsObj::ScHeaderFieldsObj(ScHeaderFooterTextData& rData) : |
418 | 0 | mrData(rData) |
419 | 0 | { |
420 | 0 | mpEditSource.reset( new ScHeaderFooterEditSource(rData) ); |
421 | 0 | } |
422 | | |
423 | | ScHeaderFieldsObj::~ScHeaderFieldsObj() |
424 | 0 | { |
425 | 0 | mpEditSource.reset(); |
426 | | |
427 | | // increment refcount to prevent double call of dtor |
428 | 0 | osl_atomic_increment( &m_refCount ); |
429 | |
|
430 | 0 | std::unique_lock g(aMutex); |
431 | 0 | if (maRefreshListeners.getLength(g)) |
432 | 0 | { |
433 | 0 | lang::EventObject aEvent; |
434 | 0 | aEvent.Source = getXWeak(); |
435 | 0 | maRefreshListeners.disposeAndClear(g, aEvent); |
436 | 0 | } |
437 | 0 | } |
438 | | |
439 | | // XIndexAccess (via XTextFields) |
440 | | |
441 | | uno::Reference<text::XTextField> ScHeaderFieldsObj::GetObjectByIndex_Impl(sal_Int32 Index) const |
442 | 0 | { |
443 | | //! Field functions have to be passed to the forwarder !!! |
444 | 0 | ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); |
445 | 0 | ScUnoEditEngine aTempEngine(pEditEngine); |
446 | |
|
447 | 0 | SvxFieldData* pData = aTempEngine.FindByIndex(static_cast<sal_uInt16>(Index)); |
448 | 0 | if (!pData) |
449 | 0 | return nullptr; |
450 | | |
451 | | // Get the parent text range instance. |
452 | 0 | uno::Reference<text::XTextRange> xTextRange; |
453 | 0 | rtl::Reference<ScHeaderFooterContentObj> xContentObj = mrData.GetContentObj(); |
454 | 0 | if (!xContentObj.is()) |
455 | 0 | throw uno::RuntimeException(u""_ustr); |
456 | | |
457 | 0 | uno::Reference<text::XText> xText; |
458 | |
|
459 | 0 | switch ( mrData.GetPart() ) |
460 | 0 | { |
461 | 0 | case ScHeaderFooterPart::LEFT: |
462 | 0 | xText = xContentObj->getLeftText(); |
463 | 0 | break; |
464 | 0 | case ScHeaderFooterPart::CENTER: |
465 | 0 | xText = xContentObj->getCenterText(); |
466 | 0 | break; |
467 | 0 | case ScHeaderFooterPart::RIGHT: |
468 | 0 | xText = xContentObj->getRightText(); |
469 | 0 | break; |
470 | 0 | } |
471 | | |
472 | 0 | xTextRange = xText; |
473 | |
|
474 | 0 | sal_Int32 nPar = aTempEngine.GetFieldPar(); |
475 | 0 | sal_Int32 nPos = aTempEngine.GetFieldPos(); |
476 | 0 | ESelection aSelection( nPar, nPos, nPar, nPos+1 ); // Field size is 1 character |
477 | |
|
478 | 0 | sal_Int32 eRealType = pData->GetClassId(); |
479 | 0 | uno::Reference<text::XTextField> xRet( |
480 | 0 | new ScEditFieldObj(xTextRange, std::make_unique<ScHeaderFooterEditSource>(mrData), eRealType, aSelection)); |
481 | 0 | return xRet; |
482 | 0 | } |
483 | | |
484 | | sal_Int32 SAL_CALL ScHeaderFieldsObj::getCount() |
485 | 0 | { |
486 | 0 | SolarMutexGuard aGuard; |
487 | | |
488 | | //! Field functions have to be passed to the forwarder !!! |
489 | 0 | ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); |
490 | 0 | ScUnoEditEngine aTempEngine(pEditEngine); |
491 | 0 | return aTempEngine.CountFields(); |
492 | 0 | } |
493 | | |
494 | | uno::Any SAL_CALL ScHeaderFieldsObj::getByIndex( sal_Int32 nIndex ) |
495 | 0 | { |
496 | 0 | SolarMutexGuard aGuard; |
497 | 0 | uno::Reference<text::XTextField> xField(GetObjectByIndex_Impl(nIndex)); |
498 | 0 | if (!xField.is()) |
499 | 0 | throw lang::IndexOutOfBoundsException(); |
500 | | |
501 | 0 | return uno::Any(xField); |
502 | 0 | } |
503 | | |
504 | | uno::Type SAL_CALL ScHeaderFieldsObj::getElementType() |
505 | 0 | { |
506 | 0 | return cppu::UnoType<text::XTextField>::get(); |
507 | 0 | } |
508 | | |
509 | | sal_Bool SAL_CALL ScHeaderFieldsObj::hasElements() |
510 | 0 | { |
511 | 0 | SolarMutexGuard aGuard; |
512 | 0 | return ( getCount() != 0 ); |
513 | 0 | } |
514 | | |
515 | | uno::Reference<container::XEnumeration> SAL_CALL ScHeaderFieldsObj::createEnumeration() |
516 | 0 | { |
517 | 0 | SolarMutexGuard aGuard; |
518 | 0 | return new ScIndexEnumeration(this, u"com.sun.star.text.TextFieldEnumeration"_ustr); |
519 | 0 | } |
520 | | |
521 | | void SAL_CALL ScHeaderFieldsObj::addContainerListener( |
522 | | const uno::Reference<container::XContainerListener>& /* xListener */ ) |
523 | 0 | { |
524 | 0 | OSL_FAIL("not implemented"); |
525 | 0 | } |
526 | | |
527 | | void SAL_CALL ScHeaderFieldsObj::removeContainerListener( |
528 | | const uno::Reference<container::XContainerListener>& /* xListener */ ) |
529 | 0 | { |
530 | 0 | OSL_FAIL("not implemented"); |
531 | 0 | } |
532 | | |
533 | | // XRefreshable |
534 | | void SAL_CALL ScHeaderFieldsObj::refresh( ) |
535 | 0 | { |
536 | 0 | std::unique_lock g(aMutex); |
537 | 0 | if (maRefreshListeners.getLength(g)) |
538 | 0 | { |
539 | | // Call all listeners. |
540 | 0 | lang::EventObject aEvent; |
541 | 0 | aEvent.Source.set(uno::Reference< util::XRefreshable >(this)); |
542 | 0 | maRefreshListeners.notifyEach( g, &util::XRefreshListener::refreshed, aEvent); |
543 | 0 | } |
544 | 0 | } |
545 | | |
546 | | void SAL_CALL ScHeaderFieldsObj::addRefreshListener( const uno::Reference< util::XRefreshListener >& xListener ) |
547 | 0 | { |
548 | 0 | if (xListener.is()) |
549 | 0 | { |
550 | 0 | std::unique_lock g(aMutex); |
551 | 0 | maRefreshListeners.addInterface(g, xListener); |
552 | 0 | } |
553 | 0 | } |
554 | | |
555 | | void SAL_CALL ScHeaderFieldsObj::removeRefreshListener( const uno::Reference<util::XRefreshListener >& xListener ) |
556 | 0 | { |
557 | 0 | if (xListener.is()) |
558 | 0 | { |
559 | 0 | std::unique_lock g(aMutex); |
560 | 0 | maRefreshListeners.removeInterface(g, xListener); |
561 | 0 | } |
562 | 0 | } |
563 | | |
564 | | SvxFieldData& ScEditFieldObj::getData() |
565 | 25.2k | { |
566 | 25.2k | if (!mpData) |
567 | 25.1k | { |
568 | 25.1k | switch (meType) |
569 | 25.1k | { |
570 | 0 | case text::textfield::Type::DATE: |
571 | 0 | mpData.reset(new SvxDateField); |
572 | 0 | break; |
573 | 90 | case text::textfield::Type::EXTENDED_FILE: |
574 | 90 | mpData.reset( |
575 | 90 | new SvxExtFileField(OUString(), SvxFileType::Var, SvxFileFormat::NameAndExt)); |
576 | 90 | break; |
577 | 1.93k | case text::textfield::Type::PAGE: |
578 | 1.93k | mpData.reset(new SvxPageField); |
579 | 1.93k | break; |
580 | 9.76k | case text::textfield::Type::PAGES: |
581 | 9.76k | mpData.reset(new SvxPagesField); |
582 | 9.76k | break; |
583 | 1.49k | case text::textfield::Type::TABLE: |
584 | 1.49k | mpData.reset(new SvxTableField); |
585 | 1.49k | break; |
586 | 0 | case text::textfield::Type::TIME: |
587 | 0 | mpData.reset(new SvxTimeField); |
588 | 0 | break; |
589 | 11.7k | case text::textfield::Type::EXTENDED_TIME: |
590 | 11.7k | { |
591 | 11.7k | if (mbIsDate) |
592 | 3.92k | mpData.reset(new SvxDateField); |
593 | 7.78k | else |
594 | 7.78k | mpData.reset(new SvxExtTimeField); |
595 | 11.7k | } |
596 | 11.7k | break; |
597 | 172 | case text::textfield::Type::DOCINFO_TITLE: |
598 | 172 | mpData.reset(new SvxFileField); |
599 | 172 | break; |
600 | 0 | case text::textfield::Type::URL: |
601 | 0 | mpData.reset( |
602 | 0 | new SvxURLField(OUString(), OUString(), SvxURLFormat::AppDefault)); |
603 | 0 | break; |
604 | 0 | default: |
605 | 0 | mpData.reset(new SvxFieldData); |
606 | 25.1k | } |
607 | 25.1k | } |
608 | 25.2k | return *mpData; |
609 | 25.2k | } |
610 | | |
611 | | void ScEditFieldObj::setPropertyValueURL(const OUString& rName, const css::uno::Any& rVal) |
612 | 0 | { |
613 | 0 | OUString aStrVal; |
614 | 0 | if (mpEditSource) |
615 | 0 | { |
616 | | // Edit engine instance already exists for this field item. Use it. |
617 | 0 | ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); |
618 | 0 | ScUnoEditEngine aTempEngine(pEditEngine); |
619 | | |
620 | | // don't care about the type (only URLs can be found in the cells) |
621 | 0 | SvxFieldData* pField = aTempEngine.FindByPos( |
622 | 0 | aSelection.start, text::textfield::Type::UNSPECIFIED); |
623 | 0 | OSL_ENSURE(pField,"setPropertyValue: Field not found"); |
624 | 0 | if (!pField) |
625 | 0 | return; |
626 | | |
627 | 0 | if (pField->GetClassId() != text::textfield::Type::URL) |
628 | | // Make sure this is indeed a URL field. |
629 | 0 | return; |
630 | | |
631 | 0 | SvxURLField* pURL = static_cast<SvxURLField*>(pField); |
632 | |
|
633 | 0 | if (rName == SC_UNONAME_URL) |
634 | 0 | { |
635 | 0 | if (rVal >>= aStrVal) |
636 | 0 | pURL->SetURL(aStrVal); |
637 | 0 | } |
638 | 0 | else if (rName == SC_UNONAME_REPR) |
639 | 0 | { |
640 | 0 | if (rVal >>= aStrVal) |
641 | 0 | pURL->SetRepresentation(aStrVal); |
642 | 0 | } |
643 | 0 | else if (rName == SC_UNONAME_TARGET) |
644 | 0 | { |
645 | 0 | if (rVal >>= aStrVal) |
646 | 0 | pURL->SetTargetFrame(aStrVal); |
647 | 0 | } |
648 | 0 | else if (rName == SC_UNONAME_FORMAT) |
649 | 0 | { |
650 | 0 | if (sal_Int16 nVal; rVal >>= nVal) |
651 | 0 | pURL->SetFormat(static_cast<SvxURLFormat>(nVal)); |
652 | 0 | } |
653 | 0 | else |
654 | 0 | throw beans::UnknownPropertyException(rName); |
655 | | |
656 | 0 | pEditEngine->QuickInsertField( SvxFieldItem(*pField, EE_FEATURE_FIELD), aSelection ); |
657 | 0 | mpEditSource->UpdateData(); |
658 | 0 | return; |
659 | 0 | } |
660 | | |
661 | | // Edit engine instance not yet present. Store the item data for later use. |
662 | 0 | SvxURLField& rData = static_cast<SvxURLField&>(getData()); |
663 | 0 | if (rName == SC_UNONAME_URL) |
664 | 0 | { |
665 | 0 | if (rVal >>= aStrVal) |
666 | 0 | rData.SetURL(aStrVal); |
667 | 0 | } |
668 | 0 | else if (rName == SC_UNONAME_REPR) |
669 | 0 | { |
670 | 0 | if (rVal >>= aStrVal) |
671 | 0 | rData.SetRepresentation(aStrVal); |
672 | 0 | } |
673 | 0 | else if (rName == SC_UNONAME_TARGET) |
674 | 0 | { |
675 | 0 | if (rVal >>= aStrVal) |
676 | 0 | rData.SetTargetFrame(aStrVal); |
677 | 0 | } |
678 | 0 | else if (rName == SC_UNONAME_FORMAT) |
679 | 0 | { |
680 | 0 | if (sal_Int16 nVal; rVal >>= nVal) |
681 | 0 | rData.SetFormat(static_cast<SvxURLFormat>(nVal)); |
682 | 0 | } |
683 | 0 | else |
684 | 0 | throw beans::UnknownPropertyException(rName); |
685 | 0 | } |
686 | | |
687 | | uno::Any ScEditFieldObj::getPropertyValueURL(const OUString& rName) |
688 | 0 | { |
689 | 0 | uno::Any aRet; |
690 | | |
691 | | // anchor type is always "as character", text wrap always "none" |
692 | |
|
693 | 0 | if (mpEditSource) |
694 | 0 | { |
695 | | //! Field functions have to be passed to the forwarder !!! |
696 | 0 | ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); |
697 | 0 | ScUnoEditEngine aTempEngine(pEditEngine); |
698 | | |
699 | | // don't care about the type (only URLs can be found in the cells) |
700 | 0 | const SvxFieldData* pField = aTempEngine.FindByPos( |
701 | 0 | aSelection.start, text::textfield::Type::UNSPECIFIED); |
702 | 0 | OSL_ENSURE(pField,"getPropertyValue: Field not found"); |
703 | 0 | if (!pField) |
704 | 0 | throw uno::RuntimeException(); |
705 | | |
706 | 0 | if (pField->GetClassId() != text::textfield::Type::URL) |
707 | 0 | throw uno::RuntimeException(); |
708 | | |
709 | 0 | const SvxURLField* pURL = static_cast<const SvxURLField*>(pField); |
710 | |
|
711 | 0 | if (rName == SC_UNONAME_URL) |
712 | 0 | aRet <<= pURL->GetURL(); |
713 | 0 | else if (rName == SC_UNONAME_REPR) |
714 | 0 | aRet <<= pURL->GetRepresentation(); |
715 | 0 | else if (rName == SC_UNONAME_TARGET) |
716 | 0 | aRet <<= pURL->GetTargetFrame(); |
717 | 0 | else if (rName == SC_UNONAME_FORMAT) |
718 | 0 | aRet <<= static_cast<sal_Int16>(pURL->GetFormat()); |
719 | 0 | else |
720 | 0 | throw beans::UnknownPropertyException(rName); |
721 | 0 | } |
722 | 0 | else // not inserted yet |
723 | 0 | { |
724 | 0 | const SvxURLField& rURL = static_cast<const SvxURLField&>(getData()); |
725 | |
|
726 | 0 | if (rName == SC_UNONAME_URL) |
727 | 0 | aRet <<= rURL.GetURL(); |
728 | 0 | else if (rName == SC_UNONAME_REPR) |
729 | 0 | aRet <<= rURL.GetRepresentation(); |
730 | 0 | else if (rName == SC_UNONAME_TARGET) |
731 | 0 | aRet <<= rURL.GetTargetFrame(); |
732 | 0 | else if (rName == SC_UNONAME_FORMAT) |
733 | 0 | aRet <<= static_cast<sal_Int16>(rURL.GetFormat()); |
734 | 0 | else |
735 | 0 | throw beans::UnknownPropertyException(rName); |
736 | 0 | } |
737 | 0 | return aRet; |
738 | 0 | } |
739 | | |
740 | | void ScEditFieldObj::setPropertyValueFile(const OUString& rName, const uno::Any& rVal) |
741 | 90 | { |
742 | 90 | if (rName != SC_UNONAME_FILEFORM) |
743 | 0 | throw beans::UnknownPropertyException(rName); |
744 | | |
745 | 90 | sal_Int16 nIntVal = 0; |
746 | 90 | if (!(rVal >>= nIntVal)) |
747 | 0 | return; |
748 | | |
749 | 90 | SvxFileFormat eFormat = lcl_UnoToSvxFileFormat(nIntVal); |
750 | 90 | if (mpEditSource) |
751 | 0 | { |
752 | 0 | ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); |
753 | 0 | ScUnoEditEngine aTempEngine(pEditEngine); |
754 | 0 | SvxFieldData* pField = aTempEngine.FindByPos( |
755 | 0 | aSelection.start, text::textfield::Type::EXTENDED_FILE); |
756 | 0 | OSL_ENSURE(pField, "setPropertyValueFile: Field not found"); |
757 | 0 | if (pField) |
758 | 0 | { |
759 | 0 | SvxExtFileField* pExtFile = static_cast<SvxExtFileField*>(pField); // local to the ScUnoEditEngine |
760 | 0 | pExtFile->SetFormat(eFormat); |
761 | 0 | pEditEngine->QuickInsertField(SvxFieldItem(*pField, EE_FEATURE_FIELD), aSelection); |
762 | 0 | mpEditSource->UpdateData(); |
763 | 0 | } |
764 | 0 | } |
765 | 90 | else |
766 | 90 | { |
767 | 90 | SvxExtFileField& rExtFile = static_cast<SvxExtFileField&>(getData()); |
768 | 90 | rExtFile.SetFormat(eFormat); |
769 | 90 | } |
770 | | |
771 | 90 | } |
772 | | |
773 | | uno::Any ScEditFieldObj::getPropertyValueFile(const OUString& rName) |
774 | 0 | { |
775 | 0 | uno::Any aRet; |
776 | 0 | if (rName != SC_UNONAME_FILEFORM) |
777 | 0 | throw beans::UnknownPropertyException(rName); |
778 | | |
779 | 0 | SvxFileFormat eFormat = SvxFileFormat::NameAndExt; |
780 | 0 | const SvxFieldData* pField = nullptr; |
781 | 0 | if (mpEditSource) |
782 | 0 | { |
783 | 0 | ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); |
784 | 0 | ScUnoEditEngine aTempEngine(pEditEngine); |
785 | 0 | pField = aTempEngine.FindByPos( |
786 | 0 | aSelection.start, text::textfield::Type::EXTENDED_FILE); |
787 | 0 | } |
788 | 0 | else |
789 | 0 | pField = &getData(); |
790 | |
|
791 | 0 | OSL_ENSURE(pField, "setPropertyValueFile: Field not found"); |
792 | 0 | if (!pField) |
793 | 0 | throw uno::RuntimeException(); |
794 | | |
795 | 0 | const SvxExtFileField* pExtFile = static_cast<const SvxExtFileField*>(pField); |
796 | 0 | eFormat = pExtFile->GetFormat(); |
797 | 0 | sal_Int16 nIntVal = lcl_SvxToUnoFileFormat(eFormat); |
798 | 0 | aRet <<= nIntVal; |
799 | |
|
800 | 0 | return aRet; |
801 | 0 | } |
802 | | |
803 | | void ScEditFieldObj::setPropertyValueDateTime(const OUString& rName, const uno::Any& rVal) |
804 | 23.3k | { |
805 | 23.3k | if (mpEditSource) |
806 | 0 | { |
807 | | // Field already inserted. |
808 | 0 | ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); |
809 | 0 | ScUnoEditEngine aTempEngine(pEditEngine); |
810 | 0 | SvxFieldData* pField = aTempEngine.FindByPos(aSelection.start, meType); |
811 | 0 | if (!pField) |
812 | 0 | return; |
813 | | |
814 | 0 | switch (meType) |
815 | 0 | { |
816 | 0 | case text::textfield::Type::DATE: |
817 | 0 | { |
818 | 0 | SvxDateField* p = static_cast<SvxDateField*>(pField); |
819 | 0 | if (rName == SC_UNONAME_ISDATE) |
820 | 0 | { |
821 | | // Do nothing for now. |
822 | 0 | } |
823 | 0 | else if (rName == SC_UNONAME_ISFIXED) |
824 | 0 | { |
825 | 0 | SvxDateType eType = rVal.get<bool>() ? SvxDateType::Fix : SvxDateType::Var; |
826 | 0 | p->SetType(eType); |
827 | 0 | } |
828 | 0 | else if (rName == SC_UNONAME_DATETIME) |
829 | 0 | { |
830 | 0 | maDateTime = rVal.get<util::DateTime>(); |
831 | 0 | Date aDate(maDateTime.Day, maDateTime.Month, maDateTime.Year); |
832 | 0 | p->SetFixDate(aDate); |
833 | 0 | } |
834 | 0 | else if (rName == SC_UNONAME_NUMFMT) |
835 | 0 | { |
836 | 0 | mnNumFormat = rVal.get<sal_Int32>(); |
837 | 0 | p->SetFormat(static_cast<SvxDateFormat>(mnNumFormat)); |
838 | 0 | } |
839 | 0 | else |
840 | 0 | throw beans::UnknownPropertyException(rName); |
841 | 0 | } |
842 | 0 | break; |
843 | 0 | case text::textfield::Type::TIME: |
844 | 0 | { |
845 | | // SvxTimeField doesn't have any attributes. |
846 | 0 | if (rName != SC_UNONAME_ISDATE && rName != SC_UNONAME_ISFIXED && |
847 | 0 | rName != SC_UNONAME_DATETIME && rName != SC_UNONAME_NUMFMT) |
848 | 0 | throw beans::UnknownPropertyException(rName); |
849 | 0 | } |
850 | 0 | break; |
851 | 0 | case text::textfield::Type::EXTENDED_TIME: |
852 | 0 | { |
853 | 0 | SvxExtTimeField* p = static_cast<SvxExtTimeField*>(pField); |
854 | 0 | if (rName == SC_UNONAME_ISDATE) |
855 | 0 | { |
856 | | // Do nothing for now. |
857 | 0 | } |
858 | 0 | else if (rName == SC_UNONAME_ISFIXED) |
859 | 0 | { |
860 | 0 | SvxTimeType eType = rVal.get<bool>() ? SvxTimeType::Fix : SvxTimeType::Var; |
861 | 0 | p->SetType(eType); |
862 | 0 | } |
863 | 0 | else if (rName == SC_UNONAME_DATETIME) |
864 | 0 | { |
865 | 0 | maDateTime = rVal.get<util::DateTime>(); |
866 | 0 | tools::Time aTime(maDateTime); |
867 | 0 | p->SetFixTime(aTime); |
868 | 0 | } |
869 | 0 | else if (rName == SC_UNONAME_NUMFMT) |
870 | 0 | { |
871 | 0 | mnNumFormat = rVal.get<sal_Int32>(); |
872 | 0 | p->SetFormat(static_cast<SvxTimeFormat>(mnNumFormat)); |
873 | 0 | } |
874 | 0 | else |
875 | 0 | throw beans::UnknownPropertyException(rName); |
876 | 0 | } |
877 | 0 | break; |
878 | 0 | default: |
879 | 0 | throw beans::UnknownPropertyException(rName); |
880 | 0 | } |
881 | 0 | } |
882 | 23.3k | else |
883 | 23.3k | { |
884 | 23.3k | if (rName == SC_UNONAME_ISDATE) |
885 | 11.7k | mbIsDate = rVal.get<bool>(); |
886 | 11.6k | else if (rName == SC_UNONAME_ISFIXED) |
887 | 11.5k | mbIsFixed = rVal.get<bool>(); |
888 | 28 | else if (rName == SC_UNONAME_DATETIME) |
889 | 0 | maDateTime = rVal.get<util::DateTime>(); |
890 | 28 | else if (rName == SC_UNONAME_NUMFMT) |
891 | 28 | mnNumFormat = rVal.get<sal_Int32>(); |
892 | 0 | else |
893 | 0 | throw beans::UnknownPropertyException(rName); |
894 | 23.3k | } |
895 | 23.3k | } |
896 | | |
897 | | uno::Any ScEditFieldObj::getPropertyValueDateTime(const OUString& rName) |
898 | 3 | { |
899 | 3 | if (mpEditSource) |
900 | 0 | { |
901 | | // Field already inserted. |
902 | 0 | ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); |
903 | 0 | ScUnoEditEngine aTempEngine(pEditEngine); |
904 | 0 | SvxFieldData* pField = aTempEngine.FindByPos(aSelection.start, meType); |
905 | 0 | if (!pField) |
906 | 0 | throw uno::RuntimeException(); |
907 | | |
908 | 0 | switch (meType) |
909 | 0 | { |
910 | 0 | case text::textfield::Type::DATE: |
911 | 0 | { |
912 | 0 | SvxDateField* p = static_cast<SvxDateField*>(pField); |
913 | 0 | if (rName == SC_UNONAME_ISDATE) |
914 | 0 | return uno::Any(true); |
915 | | |
916 | 0 | if (rName == SC_UNONAME_ISFIXED) |
917 | 0 | return uno::Any(p->GetType() == SvxDateType::Fix); |
918 | | |
919 | 0 | if (rName == SC_UNONAME_DATETIME) |
920 | 0 | { |
921 | 0 | Date aD(p->GetFixDate()); |
922 | 0 | maDateTime.Year = aD.GetYear(); |
923 | 0 | maDateTime.Month = aD.GetMonth(); |
924 | 0 | maDateTime.Day = aD.GetDay(); |
925 | 0 | maDateTime.Hours = 0; |
926 | 0 | maDateTime.Minutes = 0; |
927 | 0 | maDateTime.Seconds = 0; |
928 | 0 | maDateTime.NanoSeconds = 0; |
929 | 0 | return uno::Any(maDateTime); |
930 | 0 | } |
931 | | |
932 | 0 | if (rName == SC_UNONAME_NUMFMT) |
933 | 0 | return uno::Any(static_cast<sal_Int32>(p->GetFormat())); |
934 | 0 | } |
935 | 0 | break; |
936 | 0 | case text::textfield::Type::TIME: |
937 | 0 | { |
938 | | // SvxTimeField doesn't have any attributes. |
939 | 0 | if (rName == SC_UNONAME_ISDATE) |
940 | 0 | return uno::Any(false); |
941 | | |
942 | 0 | if (rName == SC_UNONAME_ISFIXED) |
943 | 0 | return uno::Any(false); |
944 | | |
945 | 0 | if (rName == SC_UNONAME_DATETIME) |
946 | | // This is the best we can do. |
947 | 0 | return uno::Any(maDateTime); |
948 | | |
949 | 0 | if (rName == SC_UNONAME_NUMFMT) |
950 | | // Same as above. |
951 | 0 | return uno::Any(sal_Int32(0)); |
952 | 0 | } |
953 | 0 | break; |
954 | 0 | case text::textfield::Type::EXTENDED_TIME: |
955 | 0 | { |
956 | 0 | SvxExtTimeField* p = static_cast<SvxExtTimeField*>(pField); |
957 | 0 | if (rName == SC_UNONAME_ISDATE) |
958 | 0 | return uno::Any(false); |
959 | | |
960 | 0 | if (rName == SC_UNONAME_ISFIXED) |
961 | 0 | return uno::Any(p->GetType() == SvxTimeType::Fix); |
962 | | |
963 | 0 | if (rName == SC_UNONAME_DATETIME) |
964 | 0 | { |
965 | 0 | tools::Time aT(tools::Time::fromEncodedTime(p->GetFixTime())); |
966 | 0 | maDateTime.Year = 0; |
967 | 0 | maDateTime.Month = 0; |
968 | 0 | maDateTime.Day = 0; |
969 | 0 | maDateTime.Hours = aT.GetHour(); |
970 | 0 | maDateTime.Minutes = aT.GetMin(); |
971 | 0 | maDateTime.Seconds = aT.GetSec(); |
972 | 0 | maDateTime.NanoSeconds = aT.GetNanoSec(); |
973 | 0 | return uno::Any(maDateTime); |
974 | 0 | } |
975 | | |
976 | 0 | if (rName == SC_UNONAME_NUMFMT) |
977 | 0 | return uno::Any(static_cast<sal_Int32>(p->GetFormat())); |
978 | 0 | } |
979 | 0 | break; |
980 | 0 | default: |
981 | 0 | ; |
982 | 0 | } |
983 | 0 | } |
984 | 3 | else |
985 | 3 | { |
986 | 3 | if (rName == SC_UNONAME_ISDATE) |
987 | 0 | return uno::Any(mbIsDate); |
988 | | |
989 | 3 | if (rName == SC_UNONAME_ISFIXED) |
990 | 0 | return uno::Any(mbIsFixed); |
991 | | |
992 | 3 | if (rName == SC_UNONAME_DATETIME) |
993 | 0 | return uno::Any(maDateTime); |
994 | | |
995 | 3 | if (rName == SC_UNONAME_NUMFMT) |
996 | 0 | return uno::Any(mnNumFormat); |
997 | 3 | } |
998 | | |
999 | 3 | throw beans::UnknownPropertyException(rName); |
1000 | 3 | } |
1001 | | |
1002 | | void ScEditFieldObj::setPropertyValueSheet(const OUString& rName, const uno::Any& rVal) |
1003 | 0 | { |
1004 | 0 | if (mpEditSource) |
1005 | 0 | { |
1006 | | // Edit engine instance already exists for this field item. Use it. |
1007 | 0 | ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); |
1008 | 0 | ScUnoEditEngine aTempEngine(pEditEngine); |
1009 | | |
1010 | | // don't care about the type (only URLs can be found in the cells) |
1011 | 0 | SvxFieldData* pField = aTempEngine.FindByPos( |
1012 | 0 | aSelection.start, text::textfield::Type::UNSPECIFIED); |
1013 | 0 | OSL_ENSURE(pField,"setPropertyValue: Field not found"); |
1014 | 0 | if (!pField) |
1015 | 0 | return; |
1016 | | |
1017 | 0 | if (pField->GetClassId() != text::textfield::Type::TABLE) |
1018 | | // Make sure this is indeed a URL field. |
1019 | 0 | return; |
1020 | | |
1021 | 0 | SvxTableField* p = static_cast<SvxTableField*>(pField); |
1022 | |
|
1023 | 0 | if (rName != SC_UNONAME_TABLEPOS) |
1024 | 0 | throw beans::UnknownPropertyException(rName); |
1025 | | |
1026 | 0 | sal_Int32 nTab = rVal.get<sal_Int32>(); |
1027 | 0 | p->SetTab(nTab); |
1028 | | |
1029 | |
|
1030 | 0 | pEditEngine->QuickInsertField(SvxFieldItem(*pField, EE_FEATURE_FIELD), aSelection); |
1031 | 0 | mpEditSource->UpdateData(); |
1032 | 0 | return; |
1033 | 0 | } |
1034 | | |
1035 | | // Edit engine instance not yet present. Store the item data for later use. |
1036 | 0 | SvxTableField& r = static_cast<SvxTableField&>(getData()); |
1037 | 0 | if (rName != SC_UNONAME_TABLEPOS) |
1038 | 0 | throw beans::UnknownPropertyException(rName); |
1039 | | |
1040 | 0 | sal_Int32 nTab = rVal.get<sal_Int32>(); |
1041 | 0 | r.SetTab(nTab); |
1042 | 0 | } |
1043 | | |
1044 | | ScEditFieldObj::ScEditFieldObj( |
1045 | | uno::Reference<text::XTextRange> xContent, |
1046 | | std::unique_ptr<ScEditSource> pEditSrc, sal_Int32 eType, const ESelection& rSel) : |
1047 | 25.2k | pPropSet(nullptr), |
1048 | 25.2k | mpEditSource(std::move(pEditSrc)), |
1049 | 25.2k | aSelection(rSel), |
1050 | 25.2k | meType(eType), mpContent(std::move(xContent)), mnNumFormat(0), mbIsDate(false), mbIsFixed(false) |
1051 | 25.2k | { |
1052 | 25.2k | switch (meType) |
1053 | 25.2k | { |
1054 | 172 | case text::textfield::Type::DOCINFO_TITLE: |
1055 | 172 | pPropSet = getEmptyPropertySet(); |
1056 | 172 | break; |
1057 | 90 | case text::textfield::Type::EXTENDED_FILE: |
1058 | 90 | pPropSet = lcl_GetFileFieldPropertySet(); |
1059 | 90 | break; |
1060 | 0 | case text::textfield::Type::URL: |
1061 | 0 | pPropSet = lcl_GetURLPropertySet(); |
1062 | 0 | break; |
1063 | 0 | case text::textfield::Type::DATE: |
1064 | 0 | case text::textfield::Type::TIME: |
1065 | 11.7k | case text::textfield::Type::EXTENDED_TIME: |
1066 | 11.7k | pPropSet = getDateTimePropertySet(); |
1067 | 11.7k | break; |
1068 | 13.3k | default: |
1069 | 13.3k | pPropSet = lcl_GetHeaderFieldPropertySet(); |
1070 | 25.2k | } |
1071 | | |
1072 | 25.2k | if (meType == text::textfield::Type::DATE) |
1073 | 0 | mbIsDate = true; |
1074 | 25.2k | } Unexecuted instantiation: ScEditFieldObj::ScEditFieldObj(com::sun::star::uno::Reference<com::sun::star::text::XTextRange>, std::__1::unique_ptr<ScEditSource, std::__1::default_delete<ScEditSource> >, int, ESelection const&) ScEditFieldObj::ScEditFieldObj(com::sun::star::uno::Reference<com::sun::star::text::XTextRange>, std::__1::unique_ptr<ScEditSource, std::__1::default_delete<ScEditSource> >, int, ESelection const&) Line | Count | Source | 1047 | 25.2k | pPropSet(nullptr), | 1048 | 25.2k | mpEditSource(std::move(pEditSrc)), | 1049 | 25.2k | aSelection(rSel), | 1050 | 25.2k | meType(eType), mpContent(std::move(xContent)), mnNumFormat(0), mbIsDate(false), mbIsFixed(false) | 1051 | 25.2k | { | 1052 | 25.2k | switch (meType) | 1053 | 25.2k | { | 1054 | 172 | case text::textfield::Type::DOCINFO_TITLE: | 1055 | 172 | pPropSet = getEmptyPropertySet(); | 1056 | 172 | break; | 1057 | 90 | case text::textfield::Type::EXTENDED_FILE: | 1058 | 90 | pPropSet = lcl_GetFileFieldPropertySet(); | 1059 | 90 | break; | 1060 | 0 | case text::textfield::Type::URL: | 1061 | 0 | pPropSet = lcl_GetURLPropertySet(); | 1062 | 0 | break; | 1063 | 0 | case text::textfield::Type::DATE: | 1064 | 0 | case text::textfield::Type::TIME: | 1065 | 11.7k | case text::textfield::Type::EXTENDED_TIME: | 1066 | 11.7k | pPropSet = getDateTimePropertySet(); | 1067 | 11.7k | break; | 1068 | 13.3k | default: | 1069 | 13.3k | pPropSet = lcl_GetHeaderFieldPropertySet(); | 1070 | 25.2k | } | 1071 | | | 1072 | 25.2k | if (meType == text::textfield::Type::DATE) | 1073 | 0 | mbIsDate = true; | 1074 | 25.2k | } |
|
1075 | | |
1076 | | void ScEditFieldObj::InitDoc( |
1077 | | const uno::Reference<text::XTextRange>& rContent, std::unique_ptr<ScEditSource> pEditSrc, const ESelection& rSel) |
1078 | 25.1k | { |
1079 | 25.1k | if (!mpEditSource) |
1080 | 25.1k | { |
1081 | 25.1k | mpContent = rContent; |
1082 | 25.1k | mpData.reset(); |
1083 | | |
1084 | 25.1k | aSelection = rSel; |
1085 | 25.1k | mpEditSource = std::move( pEditSrc ); |
1086 | 25.1k | } |
1087 | 25.1k | } |
1088 | | |
1089 | | ScEditFieldObj::~ScEditFieldObj() |
1090 | 25.2k | { |
1091 | 25.2k | } |
1092 | | |
1093 | | SvxFieldItem ScEditFieldObj::CreateFieldItem() |
1094 | 25.1k | { |
1095 | 25.1k | OSL_ENSURE( !mpEditSource, "CreateFieldItem with inserted field" ); |
1096 | 25.1k | return SvxFieldItem(getData(), EE_FEATURE_FIELD); |
1097 | 25.1k | } |
1098 | | |
1099 | | void ScEditFieldObj::DeleteField() |
1100 | 0 | { |
1101 | 0 | if (mpEditSource) |
1102 | 0 | { |
1103 | 0 | SvxTextForwarder* pForwarder = mpEditSource->GetTextForwarder(); |
1104 | 0 | pForwarder->QuickInsertText( OUString(), aSelection ); |
1105 | 0 | mpEditSource->UpdateData(); |
1106 | |
|
1107 | 0 | aSelection.CollapseToStart(); |
1108 | | |
1109 | | //! Broadcast in order to adjust selection in other objects |
1110 | | //! (also for other actions) |
1111 | 0 | } |
1112 | 0 | } |
1113 | | |
1114 | | bool ScEditFieldObj::IsInserted() const |
1115 | 25.1k | { |
1116 | 25.1k | return mpEditSource != nullptr; |
1117 | 25.1k | } |
1118 | | |
1119 | | // XTextField |
1120 | | |
1121 | | OUString SAL_CALL ScEditFieldObj::getPresentation( sal_Bool bShowCommand ) |
1122 | 0 | { |
1123 | 0 | SolarMutexGuard aGuard; |
1124 | |
|
1125 | 0 | if (!mpEditSource) |
1126 | 0 | return OUString(); |
1127 | | |
1128 | | //! Field functions have to be passed to the forwarder !!! |
1129 | 0 | ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); |
1130 | 0 | ScUnoEditEngine aTempEngine(pEditEngine); |
1131 | | |
1132 | | // don't care about the type (only URLs can be found in the cells) |
1133 | 0 | const SvxFieldData* pField = aTempEngine.FindByPos( |
1134 | 0 | aSelection.start, text::textfield::Type::UNSPECIFIED); |
1135 | 0 | OSL_ENSURE(pField,"getPresentation: Field not found"); |
1136 | 0 | if (!pField) |
1137 | 0 | return OUString(); |
1138 | | |
1139 | 0 | switch (meType) |
1140 | 0 | { |
1141 | 0 | case text::textfield::Type::URL: |
1142 | 0 | { |
1143 | 0 | if (pField->GetClassId() != text::textfield::Type::URL) |
1144 | | // Not a URL field, but URL is expected. |
1145 | 0 | throw uno::RuntimeException(); |
1146 | | |
1147 | 0 | const SvxURLField* pURL = static_cast<const SvxURLField*>(pField); |
1148 | 0 | return bShowCommand ? pURL->GetURL() : pURL->GetRepresentation(); |
1149 | 0 | } |
1150 | 0 | break; |
1151 | 0 | default: |
1152 | 0 | ; |
1153 | 0 | } |
1154 | 0 | return OUString(); |
1155 | 0 | } |
1156 | | |
1157 | | // XTextContent |
1158 | | |
1159 | | void SAL_CALL ScEditFieldObj::attach( const uno::Reference<text::XTextRange>& xTextRange ) |
1160 | 0 | { |
1161 | 0 | SolarMutexGuard aGuard; |
1162 | 0 | if (xTextRange.is()) |
1163 | 0 | { |
1164 | 0 | uno::Reference<text::XText> xText(xTextRange->getText()); |
1165 | 0 | if (xText.is()) |
1166 | 0 | { |
1167 | 0 | xText->insertTextContent( xTextRange, this, true ); |
1168 | 0 | } |
1169 | 0 | } |
1170 | 0 | } |
1171 | | |
1172 | | uno::Reference<text::XTextRange> SAL_CALL ScEditFieldObj::getAnchor() |
1173 | 0 | { |
1174 | 0 | SolarMutexGuard aGuard; |
1175 | 0 | return mpContent; |
1176 | 0 | } |
1177 | | |
1178 | | // XPropertySet |
1179 | | |
1180 | | uno::Reference<beans::XPropertySetInfo> SAL_CALL ScEditFieldObj::getPropertySetInfo() |
1181 | 22.7k | { |
1182 | 22.7k | SolarMutexGuard aGuard; |
1183 | 22.7k | rtl::Reference<SfxItemPropertySetInfo> aRef = pPropSet->getPropertySetInfo(); |
1184 | 22.7k | return aRef; |
1185 | 22.7k | } |
1186 | | |
1187 | | void SAL_CALL ScEditFieldObj::setPropertyValue( |
1188 | | const OUString& aPropertyName, const uno::Any& aValue ) |
1189 | 23.4k | { |
1190 | 23.4k | SolarMutexGuard aGuard; |
1191 | 23.4k | if (aPropertyName == SC_UNONAME_ANCHOR) |
1192 | 0 | { |
1193 | 0 | aValue >>= mpContent; |
1194 | 0 | return; |
1195 | 0 | } |
1196 | | |
1197 | 23.4k | switch (meType) |
1198 | 23.4k | { |
1199 | 0 | case text::textfield::Type::URL: |
1200 | 0 | setPropertyValueURL(aPropertyName, aValue); |
1201 | 0 | break; |
1202 | 90 | case text::textfield::Type::EXTENDED_FILE: |
1203 | 90 | setPropertyValueFile(aPropertyName, aValue); |
1204 | 90 | break; |
1205 | 0 | case text::textfield::Type::DATE: |
1206 | 0 | case text::textfield::Type::TIME: |
1207 | 23.3k | case text::textfield::Type::EXTENDED_TIME: |
1208 | 23.3k | setPropertyValueDateTime(aPropertyName, aValue); |
1209 | 23.3k | break; |
1210 | 0 | case text::textfield::Type::TABLE: |
1211 | 0 | setPropertyValueSheet(aPropertyName, aValue); |
1212 | 0 | break; |
1213 | 0 | case text::textfield::Type::DOCINFO_TITLE: |
1214 | 0 | default: |
1215 | 0 | throw beans::UnknownPropertyException(OUString::number(meType)); |
1216 | 23.4k | } |
1217 | 23.4k | } |
1218 | | |
1219 | | uno::Any SAL_CALL ScEditFieldObj::getPropertyValue( const OUString& aPropertyName ) |
1220 | 330 | { |
1221 | 330 | SolarMutexGuard aGuard; |
1222 | 330 | if (aPropertyName == SC_UNONAME_TEXTFIELD_TYPE) |
1223 | 0 | return uno::Any(meType); |
1224 | | |
1225 | 330 | if (aPropertyName == SC_UNONAME_ANCHOR) |
1226 | 0 | return uno::Any(mpContent); |
1227 | | |
1228 | 330 | if (aPropertyName == SC_UNONAME_ANCTYPE) |
1229 | 0 | { |
1230 | 0 | uno::Any aRet; |
1231 | 0 | aRet <<= text::TextContentAnchorType_AS_CHARACTER; |
1232 | 0 | return aRet; |
1233 | 0 | } |
1234 | 330 | if (aPropertyName == SC_UNONAME_ANCTYPES) |
1235 | 0 | { |
1236 | 0 | uno::Any aRet; |
1237 | 0 | uno::Sequence<text::TextContentAnchorType> aSeq { text::TextContentAnchorType_AS_CHARACTER }; |
1238 | 0 | aRet <<= aSeq; |
1239 | 0 | return aRet; |
1240 | 0 | } |
1241 | 330 | if (aPropertyName == SC_UNONAME_TEXTWRAP) |
1242 | 0 | { |
1243 | 0 | uno::Any aRet; |
1244 | 0 | aRet <<= text::WrapTextMode_NONE; |
1245 | 0 | return aRet; |
1246 | 0 | } |
1247 | | |
1248 | 330 | switch (meType) |
1249 | 330 | { |
1250 | 0 | case text::textfield::Type::URL: |
1251 | 0 | return getPropertyValueURL(aPropertyName); |
1252 | 0 | case text::textfield::Type::EXTENDED_FILE: |
1253 | 0 | return getPropertyValueFile(aPropertyName); |
1254 | 0 | case text::textfield::Type::DATE: |
1255 | 0 | case text::textfield::Type::TIME: |
1256 | 3 | case text::textfield::Type::EXTENDED_TIME: |
1257 | 3 | return getPropertyValueDateTime(aPropertyName); |
1258 | 0 | case text::textfield::Type::DOCINFO_TITLE: |
1259 | 327 | default: |
1260 | 327 | throw beans::UnknownPropertyException(OUString::number(meType)); |
1261 | 330 | } |
1262 | 330 | } |
1263 | | |
1264 | | SC_IMPL_DUMMY_PROPERTY_LISTENER( ScEditFieldObj ) |
1265 | | |
1266 | | // XServiceInfo |
1267 | | |
1268 | | OUString SAL_CALL ScEditFieldObj::getImplementationName() |
1269 | 0 | { |
1270 | 0 | return u"ScEditFieldObj"_ustr; |
1271 | 0 | } |
1272 | | |
1273 | | sal_Bool SAL_CALL ScEditFieldObj::supportsService( const OUString& rServiceName ) |
1274 | 0 | { |
1275 | 0 | return cppu::supportsService(this, rServiceName); |
1276 | 0 | } |
1277 | | |
1278 | | uno::Sequence<OUString> SAL_CALL ScEditFieldObj::getSupportedServiceNames() |
1279 | 0 | { |
1280 | 0 | return {u"com.sun.star.text.TextField"_ustr, |
1281 | 0 | u"com.sun.star.text.TextContent"_ustr}; |
1282 | 0 | } |
1283 | | |
1284 | | uno::Sequence<uno::Type> SAL_CALL ScEditFieldObj::getTypes() |
1285 | 0 | { |
1286 | 0 | return comphelper::concatSequences( |
1287 | 0 | ScEditFieldObj_Base::getTypes(), |
1288 | 0 | uno::Sequence<uno::Type> |
1289 | 0 | { |
1290 | 0 | cppu::UnoType<text::XTextField>::get(), |
1291 | 0 | cppu::UnoType<beans::XPropertySet>::get(), |
1292 | 0 | cppu::UnoType<lang::XUnoTunnel>::get(), |
1293 | 0 | cppu::UnoType<lang::XServiceInfo>::get() |
1294 | 0 | } ); |
1295 | 0 | } |
1296 | | |
1297 | | uno::Sequence<sal_Int8> SAL_CALL ScEditFieldObj::getImplementationId() |
1298 | 0 | { |
1299 | 0 | return css::uno::Sequence<sal_Int8>(); |
1300 | 0 | } |
1301 | | |
1302 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |