/src/libreoffice/sfx2/source/doc/doctempl.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 | | |
21 | | #include <limits.h> |
22 | | #include <mutex> |
23 | | #include <string_view> |
24 | | |
25 | | #include <com/sun/star/uno/Any.h> |
26 | | #include <sal/log.hxx> |
27 | | |
28 | | #include <unotools/pathoptions.hxx> |
29 | | #include <tools/urlobj.hxx> |
30 | | #include <tools/debug.hxx> |
31 | | #include <comphelper/diagnose_ex.hxx> |
32 | | #include <comphelper/processfactory.hxx> |
33 | | #include <comphelper/propertyvalue.hxx> |
34 | | #include <ucbhelper/content.hxx> |
35 | | #include <com/sun/star/beans/PropertyValue.hpp> |
36 | | #include <com/sun/star/beans/XPropertySet.hpp> |
37 | | #include <com/sun/star/beans/XPropertySetInfo.hpp> |
38 | | #include <com/sun/star/document/XTypeDetection.hpp> |
39 | | #include <com/sun/star/document/DocumentProperties.hpp> |
40 | | #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> |
41 | | #include <com/sun/star/frame/Desktop.hpp> |
42 | | #include <com/sun/star/frame/DocumentTemplates.hpp> |
43 | | #include <com/sun/star/frame/XDocumentTemplates.hpp> |
44 | | #include <com/sun/star/io/IOException.hpp> |
45 | | #include <com/sun/star/io/XPersist.hpp> |
46 | | #include <com/sun/star/lang/XLocalizable.hpp> |
47 | | #include <com/sun/star/sdbc/XResultSet.hpp> |
48 | | #include <com/sun/star/sdbc/XRow.hpp> |
49 | | #include <com/sun/star/ucb/ContentCreationException.hpp> |
50 | | #include <com/sun/star/ucb/NameClash.hpp> |
51 | | #include <com/sun/star/ucb/TransferInfo.hpp> |
52 | | #include <com/sun/star/ucb/XContent.hpp> |
53 | | #include <com/sun/star/ucb/XContentAccess.hpp> |
54 | | #include <com/sun/star/ucb/AnyCompareFactory.hpp> |
55 | | #include <com/sun/star/ucb/NumberedSortingInfo.hpp> |
56 | | |
57 | | #include "doctemplateslocal.hxx" |
58 | | #include <sfxurlrelocator.hxx> |
59 | | |
60 | | #include <sfx2/doctempl.hxx> |
61 | | #include <sfx2/objsh.hxx> |
62 | | #include <sfx2/sfxresid.hxx> |
63 | | #include <sfx2/strings.hrc> |
64 | | #include <strings.hxx> |
65 | | #include <svtools/templatefoldercache.hxx> |
66 | | |
67 | | #include <memory> |
68 | | #include <utility> |
69 | | #include <vector> |
70 | | |
71 | | |
72 | | using namespace ::com::sun::star; |
73 | | using namespace ::com::sun::star::beans; |
74 | | using namespace ::com::sun::star::frame; |
75 | | using namespace ::com::sun::star::io; |
76 | | using namespace ::com::sun::star::lang; |
77 | | using namespace ::com::sun::star::sdbc; |
78 | | using namespace ::com::sun::star::uno; |
79 | | using namespace ::com::sun::star::ucb; |
80 | | using namespace ::com::sun::star::document; |
81 | | using namespace ::rtl; |
82 | | using namespace ::ucbhelper; |
83 | | |
84 | | constexpr OUString TITLE = u"Title"_ustr; |
85 | | constexpr OUString TARGET_URL = u"TargetURL"_ustr; |
86 | | |
87 | | constexpr OUStringLiteral COMMAND_TRANSFER = u"transfer"; |
88 | | |
89 | | namespace { |
90 | | |
91 | | class RegionData_Impl; |
92 | | |
93 | | } |
94 | | |
95 | | namespace DocTempl { |
96 | | |
97 | | namespace { |
98 | | |
99 | | class DocTempl_EntryData_Impl |
100 | | { |
101 | | // the following member must be SfxObjectShellLock since it controls that SfxObjectShell lifetime by design |
102 | | // and users of this class expect it to be so. |
103 | | SfxObjectShellLock mxObjShell; |
104 | | |
105 | | OUString maTitle; |
106 | | OUString maOwnURL; |
107 | | OUString maTargetURL; |
108 | | |
109 | | public: |
110 | | DocTempl_EntryData_Impl(const OUString& rTitle); |
111 | | |
112 | 0 | const OUString& GetTitle() const { return maTitle; } |
113 | | const OUString& GetTargetURL(const INetURLObject& rRootURL); |
114 | | const OUString& GetHierarchyURL(const INetURLObject& rRootURL); |
115 | | |
116 | 0 | void SetTitle( const OUString& rTitle ) { maTitle = rTitle; } |
117 | 0 | void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; } |
118 | 0 | void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; } |
119 | | |
120 | | int Compare( std::u16string_view rTitle ) const; |
121 | | }; |
122 | | |
123 | | } |
124 | | |
125 | | } |
126 | | |
127 | | using namespace ::DocTempl; |
128 | | |
129 | | namespace { |
130 | | |
131 | | class RegionData_Impl |
132 | | { |
133 | | std::vector<std::unique_ptr<DocTempl_EntryData_Impl>> maEntries; |
134 | | OUString maTitle; |
135 | | OUString maOwnURL; |
136 | | |
137 | | private: |
138 | | size_t GetEntryPos( std::u16string_view rTitle, |
139 | | bool& rFound ) const; |
140 | | |
141 | | public: |
142 | | RegionData_Impl(OUString aTitle); |
143 | | |
144 | 0 | void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; } |
145 | | |
146 | | DocTempl_EntryData_Impl* GetEntry( size_t nIndex ) const; |
147 | | DocTempl_EntryData_Impl* GetEntry( std::u16string_view rName ) const; |
148 | | |
149 | 0 | const OUString& GetTitle() const { return maTitle; } |
150 | | const OUString& GetHierarchyURL(const INetURLObject& rRootURL); |
151 | | |
152 | | size_t GetCount() const; |
153 | | |
154 | 0 | void SetTitle( const OUString& rTitle ) { maTitle = rTitle; } |
155 | | |
156 | | void AddEntry(const INetURLObject& rRootURL, |
157 | | const OUString& rTitle, |
158 | | const OUString& rTargetURL, |
159 | | const size_t *pPos); |
160 | | void DeleteEntry( size_t nIndex ); |
161 | | |
162 | | int Compare( RegionData_Impl const * pCompareWith ) const; |
163 | | }; |
164 | | |
165 | | } |
166 | | |
167 | | class SfxDocTemplate_Impl : public SvRefBase |
168 | | { |
169 | | uno::Reference< XPersist > mxInfo; |
170 | | uno::Reference< XDocumentTemplates > mxTemplates; |
171 | | |
172 | | mutable std::mutex maMutex; |
173 | | OUString maRootURL; |
174 | | OUString maStandardGroup; |
175 | | std::vector<std::unique_ptr<RegionData_Impl>> maRegions; |
176 | | bool mbConstructed; |
177 | | |
178 | | uno::Reference< XAnyCompareFactory > m_rCompareFactory; |
179 | | |
180 | | // the following member is intended to prevent clearing of the global data when it is in use |
181 | | // TODO/LATER: it still does not make the implementation complete thread-safe |
182 | | sal_Int32 mnLockCounter; |
183 | | |
184 | | private: |
185 | | void Clear(); |
186 | | |
187 | | public: |
188 | | SfxDocTemplate_Impl(); |
189 | | virtual ~SfxDocTemplate_Impl() override; |
190 | | |
191 | | void IncrementLock(); |
192 | | void DecrementLock(); |
193 | | |
194 | | bool Construct( ); |
195 | | void CreateFromHierarchy( std::unique_lock<std::mutex>& rGuard, Content &rTemplRoot ); |
196 | | void ReInitFromComponent(); |
197 | | void AddRegion( std::unique_lock<std::mutex>& rGuard, |
198 | | const OUString& rTitle, |
199 | | Content& rContent ); |
200 | | |
201 | | void Rescan(); |
202 | | |
203 | | void DeleteRegion( size_t nIndex ); |
204 | | |
205 | | size_t GetRegionCount() const |
206 | 0 | { return maRegions.size(); } |
207 | | RegionData_Impl* GetRegion( std::u16string_view rName ) const; |
208 | | RegionData_Impl* GetRegion( size_t nIndex ) const; |
209 | | |
210 | | bool GetTitleFromURL( const OUString& rURL, OUString& aTitle ); |
211 | | bool InsertRegion( std::unique_ptr<RegionData_Impl> pData, size_t nPos ); |
212 | | |
213 | | INetURLObject GetRootURL() const |
214 | 0 | { |
215 | 0 | std::unique_lock aGuard(maMutex); |
216 | 0 | return INetURLObject(maRootURL); |
217 | 0 | } |
218 | | |
219 | | uno::Reference<XDocumentTemplates> getDocTemplates() const |
220 | 0 | { |
221 | 0 | std::unique_lock aGuard(maMutex); |
222 | 0 | return mxTemplates; |
223 | 0 | } |
224 | | }; |
225 | | |
226 | | namespace { |
227 | | |
228 | | class DocTemplLocker_Impl |
229 | | { |
230 | | SfxDocTemplate_Impl& m_aDocTempl; |
231 | | public: |
232 | | explicit DocTemplLocker_Impl( SfxDocTemplate_Impl& aDocTempl ) |
233 | 0 | : m_aDocTempl( aDocTempl ) |
234 | 0 | { |
235 | 0 | m_aDocTempl.IncrementLock(); |
236 | 0 | } |
237 | | |
238 | | ~DocTemplLocker_Impl() |
239 | 0 | { |
240 | 0 | m_aDocTempl.DecrementLock(); |
241 | 0 | } |
242 | | }; |
243 | | |
244 | | } |
245 | | |
246 | | static SfxDocTemplate_Impl *gpTemplateData = nullptr; |
247 | | |
248 | | |
249 | | static bool getTextProperty_Impl( Content& rContent, |
250 | | const OUString& rPropName, |
251 | | OUString& rPropValue ); |
252 | | |
253 | | |
254 | | OUString SfxDocumentTemplates::GetFullRegionName |
255 | | ( |
256 | | sal_uInt16 nIdx // Region Index |
257 | | ) const |
258 | | |
259 | | /* [Description] |
260 | | |
261 | | Returns the logical name of a region and its path |
262 | | |
263 | | [Return value] Reference to the Region name |
264 | | |
265 | | */ |
266 | | |
267 | 0 | { |
268 | | // First: find the RegionData for the index |
269 | |
|
270 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
271 | |
|
272 | 0 | if ( pImp->Construct() ) |
273 | 0 | { |
274 | 0 | RegionData_Impl *pData1 = pImp->GetRegion( nIdx ); |
275 | |
|
276 | 0 | if ( pData1 ) |
277 | 0 | return pData1->GetTitle(); |
278 | | |
279 | | // --**-- here was some code which appended the path to the |
280 | | // group if there was more than one with the same name. |
281 | | // this should not happen anymore |
282 | 0 | } |
283 | | |
284 | 0 | return OUString(); |
285 | 0 | } |
286 | | |
287 | | |
288 | | OUString SfxDocumentTemplates::GetRegionName |
289 | | ( |
290 | | sal_uInt16 nIdx // Region Index |
291 | | ) const |
292 | | |
293 | | /* [Description] |
294 | | |
295 | | Returns the logical name of a region |
296 | | |
297 | | [Return value] |
298 | | |
299 | | const String& Reference to the Region name |
300 | | |
301 | | */ |
302 | 0 | { |
303 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
304 | |
|
305 | 0 | if ( pImp->Construct() ) |
306 | 0 | { |
307 | 0 | RegionData_Impl *pData = pImp->GetRegion( nIdx ); |
308 | |
|
309 | 0 | if ( pData ) |
310 | 0 | return pData->GetTitle(); |
311 | 0 | } |
312 | | |
313 | 0 | return OUString(); |
314 | 0 | } |
315 | | |
316 | | |
317 | | sal_uInt16 SfxDocumentTemplates::GetRegionCount() const |
318 | | |
319 | | /* [Description] |
320 | | |
321 | | Returns the number of Regions |
322 | | |
323 | | [Return value] |
324 | | |
325 | | sal_uInt16 Number of Regions |
326 | | */ |
327 | 0 | { |
328 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
329 | |
|
330 | 0 | if ( !pImp->Construct() ) |
331 | 0 | return 0; |
332 | | |
333 | 0 | return pImp->GetRegionCount(); |
334 | 0 | } |
335 | | |
336 | | |
337 | | sal_uInt16 SfxDocumentTemplates::GetCount |
338 | | ( |
339 | | sal_uInt16 nRegion /* Region index whose number is |
340 | | to be determined */ |
341 | | |
342 | | ) const |
343 | | |
344 | | /* [Description] |
345 | | |
346 | | Number of entries in Region |
347 | | |
348 | | [Return value] Number of entries |
349 | | */ |
350 | | |
351 | 0 | { |
352 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
353 | |
|
354 | 0 | if ( !pImp->Construct() ) |
355 | 0 | return 0; |
356 | | |
357 | 0 | RegionData_Impl *pData = pImp->GetRegion( nRegion ); |
358 | |
|
359 | 0 | if ( !pData ) |
360 | 0 | return 0; |
361 | | |
362 | 0 | return pData->GetCount(); |
363 | 0 | } |
364 | | |
365 | | |
366 | | OUString SfxDocumentTemplates::GetName |
367 | | ( |
368 | | sal_uInt16 nRegion, // Region Index, in which the entry lies |
369 | | sal_uInt16 nIdx // Index of the entry |
370 | | ) const |
371 | | |
372 | | /* [Description] |
373 | | |
374 | | Returns the logical name of an entry in Region |
375 | | |
376 | | [Return value] |
377 | | |
378 | | const String& Entry Name |
379 | | */ |
380 | | |
381 | 0 | { |
382 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
383 | |
|
384 | 0 | if ( pImp->Construct() ) |
385 | 0 | { |
386 | 0 | RegionData_Impl *pRegion = pImp->GetRegion( nRegion ); |
387 | |
|
388 | 0 | if ( pRegion ) |
389 | 0 | { |
390 | 0 | DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx ); |
391 | 0 | if ( pEntry ) |
392 | 0 | return pEntry->GetTitle(); |
393 | 0 | } |
394 | 0 | } |
395 | | |
396 | 0 | return OUString(); |
397 | 0 | } |
398 | | |
399 | | |
400 | | OUString SfxDocumentTemplates::GetPath |
401 | | ( |
402 | | sal_uInt16 nRegion, // Region Index, in which the entry lies |
403 | | sal_uInt16 nIdx // Index of the entry |
404 | | ) const |
405 | | |
406 | | /* [Description] |
407 | | |
408 | | Returns the file name with full path to the file assigned to an entry |
409 | | |
410 | | [Return value] |
411 | | |
412 | | String File name with full path |
413 | | */ |
414 | 0 | { |
415 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
416 | |
|
417 | 0 | if ( !pImp->Construct() ) |
418 | 0 | return OUString(); |
419 | | |
420 | 0 | RegionData_Impl *pRegion = pImp->GetRegion( nRegion ); |
421 | |
|
422 | 0 | if ( pRegion ) |
423 | 0 | { |
424 | 0 | DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx ); |
425 | 0 | if ( pEntry ) |
426 | 0 | return pEntry->GetTargetURL(pImp->GetRootURL()); |
427 | 0 | } |
428 | | |
429 | 0 | return OUString(); |
430 | 0 | } |
431 | | |
432 | | OUString SfxDocumentTemplates::GetTemplateTargetURLFromComponent( std::u16string_view aGroupName, |
433 | | std::u16string_view aTitle ) |
434 | 0 | { |
435 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
436 | |
|
437 | 0 | INetURLObject aTemplateObj( pImp->GetRootURL() ); |
438 | |
|
439 | 0 | aTemplateObj.insertName( aGroupName, false, |
440 | 0 | INetURLObject::LAST_SEGMENT, |
441 | 0 | INetURLObject::EncodeMechanism::All ); |
442 | |
|
443 | 0 | aTemplateObj.insertName( aTitle, false, |
444 | 0 | INetURLObject::LAST_SEGMENT, |
445 | 0 | INetURLObject::EncodeMechanism::All ); |
446 | | |
447 | |
|
448 | 0 | Content aTemplate; |
449 | 0 | uno::Reference< XCommandEnvironment > aCmdEnv; |
450 | 0 | if ( Content::create( aTemplateObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ), aCmdEnv, comphelper::getProcessComponentContext(), aTemplate ) ) |
451 | 0 | { |
452 | 0 | OUString aResult; |
453 | 0 | getTextProperty_Impl( aTemplate, TARGET_URL, aResult ); |
454 | 0 | return SvtPathOptions().SubstituteVariable( aResult ); |
455 | 0 | } |
456 | | |
457 | 0 | return OUString(); |
458 | 0 | } |
459 | | |
460 | | |
461 | | /** Convert a template name to its localised pair if it exists. |
462 | | @param rString |
463 | | Name to be translated. |
464 | | @return |
465 | | The localised pair of rString or rString if the former does not exist. |
466 | | */ |
467 | | OUString SfxDocumentTemplates::ConvertResourceString(const OUString& rString) |
468 | 0 | { |
469 | 0 | static constexpr OUString aTemplateNames[] = |
470 | 0 | { |
471 | 0 | STR_TEMPLATE_NAME1_DEF, |
472 | 0 | STR_TEMPLATE_NAME2_DEF, |
473 | 0 | STR_TEMPLATE_NAME3_DEF, |
474 | 0 | STR_TEMPLATE_NAME4_DEF, |
475 | 0 | STR_TEMPLATE_NAME5_DEF, |
476 | 0 | STR_TEMPLATE_NAME6_DEF, |
477 | 0 | STR_TEMPLATE_NAME7_DEF, |
478 | 0 | STR_TEMPLATE_NAME8_DEF, |
479 | 0 | STR_TEMPLATE_NAME9_DEF, |
480 | 0 | STR_TEMPLATE_NAME10_DEF, |
481 | 0 | STR_TEMPLATE_NAME11_DEF, |
482 | 0 | STR_TEMPLATE_NAME12_DEF, |
483 | 0 | STR_TEMPLATE_NAME13_DEF, |
484 | 0 | STR_TEMPLATE_NAME14_DEF, |
485 | 0 | STR_TEMPLATE_NAME15_DEF, |
486 | 0 | STR_TEMPLATE_NAME16_DEF, |
487 | 0 | STR_TEMPLATE_NAME17_DEF, |
488 | 0 | STR_TEMPLATE_NAME18_DEF, |
489 | 0 | STR_TEMPLATE_NAME19_DEF, |
490 | 0 | STR_TEMPLATE_NAME20_DEF, |
491 | 0 | STR_TEMPLATE_NAME21_DEF, |
492 | 0 | STR_TEMPLATE_NAME22_DEF, |
493 | 0 | STR_TEMPLATE_NAME23_DEF, |
494 | 0 | STR_TEMPLATE_NAME24_DEF, |
495 | 0 | STR_TEMPLATE_NAME25_DEF, |
496 | 0 | STR_TEMPLATE_NAME26_DEF, |
497 | 0 | STR_TEMPLATE_NAME27_DEF, |
498 | 0 | STR_TEMPLATE_NAME28_DEF, |
499 | 0 | STR_TEMPLATE_NAME29_DEF, |
500 | 0 | STR_TEMPLATE_NAME30_DEF, |
501 | 0 | STR_TEMPLATE_NAME31_DEF, |
502 | 0 | STR_TEMPLATE_NAME32_DEF, |
503 | 0 | STR_TEMPLATE_NAME33_DEF, |
504 | 0 | STR_TEMPLATE_NAME34_DEF |
505 | 0 | }; |
506 | |
|
507 | 0 | TranslateId STR_TEMPLATE_NAME[] = |
508 | 0 | { |
509 | 0 | STR_TEMPLATE_NAME1, |
510 | 0 | STR_TEMPLATE_NAME2, |
511 | 0 | STR_TEMPLATE_NAME3, |
512 | 0 | STR_TEMPLATE_NAME4, |
513 | 0 | STR_TEMPLATE_NAME5, |
514 | 0 | STR_TEMPLATE_NAME6, |
515 | 0 | STR_TEMPLATE_NAME7, |
516 | 0 | STR_TEMPLATE_NAME8, |
517 | 0 | STR_TEMPLATE_NAME9, |
518 | 0 | STR_TEMPLATE_NAME10, |
519 | 0 | STR_TEMPLATE_NAME11, |
520 | 0 | STR_TEMPLATE_NAME12, |
521 | 0 | STR_TEMPLATE_NAME13, |
522 | 0 | STR_TEMPLATE_NAME14, |
523 | 0 | STR_TEMPLATE_NAME15, |
524 | 0 | STR_TEMPLATE_NAME16, |
525 | 0 | STR_TEMPLATE_NAME17, |
526 | 0 | STR_TEMPLATE_NAME18, |
527 | 0 | STR_TEMPLATE_NAME19, |
528 | 0 | STR_TEMPLATE_NAME20, |
529 | 0 | STR_TEMPLATE_NAME21, |
530 | 0 | STR_TEMPLATE_NAME22, |
531 | 0 | STR_TEMPLATE_NAME23, |
532 | 0 | STR_TEMPLATE_NAME24, |
533 | 0 | STR_TEMPLATE_NAME25, |
534 | 0 | STR_TEMPLATE_NAME26, |
535 | 0 | STR_TEMPLATE_NAME27, |
536 | 0 | STR_TEMPLATE_NAME28, |
537 | 0 | STR_TEMPLATE_NAME29, |
538 | 0 | STR_TEMPLATE_NAME30, |
539 | 0 | STR_TEMPLATE_NAME31, |
540 | 0 | STR_TEMPLATE_NAME32, |
541 | 0 | STR_TEMPLATE_NAME33, |
542 | 0 | STR_TEMPLATE_NAME34 |
543 | 0 | }; |
544 | |
|
545 | 0 | static_assert(SAL_N_ELEMENTS(aTemplateNames) == SAL_N_ELEMENTS(STR_TEMPLATE_NAME)); |
546 | |
|
547 | 0 | for (size_t i = 0; i < SAL_N_ELEMENTS(STR_TEMPLATE_NAME); ++i) |
548 | 0 | { |
549 | 0 | if (rString == aTemplateNames[i]) |
550 | 0 | return SfxResId(STR_TEMPLATE_NAME[i]); |
551 | 0 | } |
552 | 0 | return rString; |
553 | 0 | } |
554 | | |
555 | | |
556 | | bool SfxDocumentTemplates::CopyOrMove |
557 | | ( |
558 | | sal_uInt16 nTargetRegion, // Target Region Index |
559 | | sal_uInt16 nTargetIdx, // Target position Index |
560 | | sal_uInt16 nSourceRegion, // Source Region Index |
561 | | sal_uInt16 nSourceIdx, /* Index to be copied / to moved template */ |
562 | | bool bMove // Copy / Move |
563 | | ) |
564 | | |
565 | | /* [Description] |
566 | | |
567 | | Copy or move a document template |
568 | | |
569 | | [Return value] |
570 | | |
571 | | sal_Bool sal_True, Action could be performed |
572 | | sal_False, Action could not be performed |
573 | | |
574 | | [Cross-references] |
575 | | |
576 | | <SfxDocumentTemplates::Move(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)> |
577 | | <SfxDocumentTemplates::Copy(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)> |
578 | | */ |
579 | | |
580 | 0 | { |
581 | | /* to perform a copy or move, we need to send a transfer command to |
582 | | the destination folder with the URL of the source as parameter. |
583 | | ( If the destination content doesn't support the transfer command, |
584 | | we could try a copy ( and delete ) instead. ) |
585 | | We need two transfers ( one for the real template and one for its |
586 | | representation in the hierarchy ) |
587 | | ... |
588 | | */ |
589 | |
|
590 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
591 | |
|
592 | 0 | if ( !pImp->Construct() ) |
593 | 0 | return false; |
594 | | |
595 | | // Don't copy or move any folders |
596 | 0 | if( nSourceIdx == USHRT_MAX ) |
597 | 0 | return false ; |
598 | | |
599 | 0 | if ( nSourceRegion == nTargetRegion ) |
600 | 0 | { |
601 | 0 | SAL_WARN( "sfx.doc", "Don't know, what to do!" ); |
602 | 0 | return false; |
603 | 0 | } |
604 | | |
605 | 0 | RegionData_Impl *pSourceRgn = pImp->GetRegion( nSourceRegion ); |
606 | 0 | if ( !pSourceRgn ) |
607 | 0 | return false; |
608 | | |
609 | 0 | DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nSourceIdx ); |
610 | 0 | if ( !pSource ) |
611 | 0 | return false; |
612 | | |
613 | 0 | RegionData_Impl *pTargetRgn = pImp->GetRegion( nTargetRegion ); |
614 | 0 | if ( !pTargetRgn ) |
615 | 0 | return false; |
616 | | |
617 | 0 | const OUString aTitle = pSource->GetTitle(); |
618 | |
|
619 | 0 | uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates(); |
620 | |
|
621 | 0 | if ( xTemplates->addTemplate( pTargetRgn->GetTitle(), |
622 | 0 | aTitle, |
623 | 0 | pSource->GetTargetURL(pImp->GetRootURL()) ) ) |
624 | 0 | { |
625 | 0 | const OUString aNewTargetURL = GetTemplateTargetURLFromComponent( pTargetRgn->GetTitle(), aTitle ); |
626 | 0 | if ( aNewTargetURL.isEmpty() ) |
627 | 0 | return false; |
628 | | |
629 | 0 | if ( bMove ) |
630 | 0 | { |
631 | | // --**-- delete the original file |
632 | 0 | bool bDeleted = xTemplates->removeTemplate( pSourceRgn->GetTitle(), |
633 | 0 | pSource->GetTitle() ); |
634 | 0 | if ( bDeleted ) |
635 | 0 | pSourceRgn->DeleteEntry( nSourceIdx ); |
636 | 0 | else |
637 | 0 | { |
638 | 0 | if ( xTemplates->removeTemplate( pTargetRgn->GetTitle(), aTitle ) ) |
639 | 0 | return false; // will trigger retry with copy instead of move |
640 | | |
641 | | // if it is not possible to remove just created template ( must be possible! ) |
642 | | // it is better to report success here, since at least the copy has succeeded |
643 | | // TODO/LATER: solve it more gracefully in future |
644 | 0 | } |
645 | 0 | } |
646 | | |
647 | | // todo: fix SfxDocumentTemplates to handle size_t instead of sal_uInt16 |
648 | 0 | size_t temp_nTargetIdx = nTargetIdx; |
649 | 0 | pTargetRgn->AddEntry(pImp->GetRootURL(), aTitle, aNewTargetURL, &temp_nTargetIdx); |
650 | |
|
651 | 0 | return true; |
652 | 0 | } |
653 | | |
654 | | // --**-- if the current file is opened, |
655 | | // it must be re-opened afterwards. |
656 | | |
657 | 0 | return false; |
658 | 0 | } |
659 | | |
660 | | bool SfxDocumentTemplates::Move |
661 | | ( |
662 | | sal_uInt16 nTargetRegion, // Target Region Index |
663 | | sal_uInt16 nTargetIdx, // Target position Index |
664 | | sal_uInt16 nSourceRegion, // Source Region Index |
665 | | sal_uInt16 nSourceIdx /* Index to be copied / to moved template */ |
666 | | ) |
667 | | |
668 | | /* [Description] |
669 | | |
670 | | Moving a template |
671 | | |
672 | | [Return value] |
673 | | |
674 | | sal_Bool sal_True, Action could be performed |
675 | | sal_False, Action could not be performed |
676 | | |
677 | | [Cross-references] |
678 | | |
679 | | <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)> |
680 | | */ |
681 | 0 | { |
682 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
683 | |
|
684 | 0 | return CopyOrMove( nTargetRegion, nTargetIdx, |
685 | 0 | nSourceRegion, nSourceIdx, true ); |
686 | 0 | } |
687 | | |
688 | | |
689 | | bool SfxDocumentTemplates::Copy |
690 | | ( |
691 | | sal_uInt16 nTargetRegion, // Target Region Index |
692 | | sal_uInt16 nTargetIdx, // Target position Index |
693 | | sal_uInt16 nSourceRegion, // Source Region Index |
694 | | sal_uInt16 nSourceIdx /* Index to be copied / to moved template */ |
695 | | ) |
696 | | |
697 | | /* [Description] |
698 | | |
699 | | Copying a template |
700 | | |
701 | | [Return value] |
702 | | |
703 | | sal_Bool sal_True, Action could be performed |
704 | | sal_False, Action could not be performed |
705 | | |
706 | | [Cross-references] |
707 | | |
708 | | <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)> |
709 | | */ |
710 | | |
711 | 0 | { |
712 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
713 | |
|
714 | 0 | return CopyOrMove( nTargetRegion, nTargetIdx, |
715 | 0 | nSourceRegion, nSourceIdx, false ); |
716 | 0 | } |
717 | | |
718 | | |
719 | | bool SfxDocumentTemplates::CopyTo |
720 | | ( |
721 | | sal_uInt16 nRegion, // Region of the template to be exported |
722 | | sal_uInt16 nIdx, // Index of the template to be exported |
723 | | std::u16string_view rName /* File name under which the template is to |
724 | | be created */ |
725 | | ) const |
726 | | |
727 | | /* [Description] |
728 | | |
729 | | Exporting a template into the file system |
730 | | |
731 | | [Return value] |
732 | | |
733 | | sal_Bool sal_True, Action could be performed |
734 | | sal_False, Action could not be performed |
735 | | |
736 | | [Cross-references] |
737 | | |
738 | | <SfxDocumentTemplates::CopyFrom(sal_uInt16,sal_uInt16,String&)> |
739 | | */ |
740 | | |
741 | 0 | { |
742 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
743 | |
|
744 | 0 | if ( ! pImp->Construct() ) |
745 | 0 | return false; |
746 | | |
747 | 0 | RegionData_Impl *pSourceRgn = pImp->GetRegion( nRegion ); |
748 | 0 | if ( !pSourceRgn ) |
749 | 0 | return false; |
750 | | |
751 | 0 | DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nIdx ); |
752 | 0 | if ( !pSource ) |
753 | 0 | return false; |
754 | | |
755 | 0 | INetURLObject aTargetURL( rName ); |
756 | |
|
757 | 0 | const OUString aTitle( aTargetURL.getName( INetURLObject::LAST_SEGMENT, true, |
758 | 0 | INetURLObject::DecodeMechanism::WithCharset ) ); |
759 | 0 | aTargetURL.removeSegment(); |
760 | |
|
761 | 0 | const OUString aParentURL = aTargetURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ); |
762 | |
|
763 | 0 | uno::Reference< XCommandEnvironment > aCmdEnv; |
764 | 0 | Content aTarget; |
765 | |
|
766 | 0 | try |
767 | 0 | { |
768 | 0 | aTarget = Content( aParentURL, aCmdEnv, comphelper::getProcessComponentContext() ); |
769 | |
|
770 | 0 | TransferInfo aTransferInfo; |
771 | 0 | aTransferInfo.MoveData = false; |
772 | 0 | aTransferInfo.SourceURL = pSource->GetTargetURL(pImp->GetRootURL()); |
773 | 0 | aTransferInfo.NewTitle = aTitle; |
774 | 0 | aTransferInfo.NameClash = NameClash::RENAME; |
775 | |
|
776 | 0 | Any aArg( aTransferInfo ); |
777 | 0 | aTarget.executeCommand( COMMAND_TRANSFER, aArg ); |
778 | 0 | } |
779 | 0 | catch ( ContentCreationException& ) |
780 | 0 | { return false; } |
781 | 0 | catch ( Exception& ) |
782 | 0 | { return false; } |
783 | | |
784 | 0 | return true; |
785 | 0 | } |
786 | | |
787 | | |
788 | | bool SfxDocumentTemplates::CopyFrom |
789 | | ( |
790 | | sal_uInt16 nRegion, /* Region in which the template is to be |
791 | | imported */ |
792 | | sal_uInt16 nIdx, // Index of the new template in this Region |
793 | | OUString& rName /* File name of the template to be imported |
794 | | as an out parameter of the (automatically |
795 | | generated from the file name) logical name |
796 | | of the template */ |
797 | | ) |
798 | | |
799 | | /* [Description] |
800 | | |
801 | | Import a template from the file system |
802 | | |
803 | | [Return value] Success (sal_True) or serfpTargetDirectory->GetContent()); |
804 | | |
805 | | sal_Bool sal_True, Action could be performed |
806 | | sal_False, Action could not be performed |
807 | | |
808 | | [Cross-references] |
809 | | |
810 | | <SfxDocumentTemplates::CopyTo(sal_uInt16,sal_uInt16,const String&)> |
811 | | */ |
812 | | |
813 | 0 | { |
814 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
815 | |
|
816 | 0 | if ( ! pImp->Construct() ) |
817 | 0 | return false; |
818 | | |
819 | 0 | RegionData_Impl *pTargetRgn = pImp->GetRegion( nRegion ); |
820 | |
|
821 | 0 | if ( !pTargetRgn ) |
822 | 0 | return false; |
823 | | |
824 | 0 | uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates(); |
825 | 0 | if ( !xTemplates.is() ) |
826 | 0 | return false; |
827 | | |
828 | 0 | OUString aTitle; |
829 | 0 | bool bTemplateAdded = false; |
830 | |
|
831 | 0 | if( pImp->GetTitleFromURL( rName, aTitle ) ) |
832 | 0 | { |
833 | 0 | bTemplateAdded = xTemplates->addTemplate( pTargetRgn->GetTitle(), aTitle, rName ); |
834 | 0 | } |
835 | 0 | else |
836 | 0 | { |
837 | 0 | uno::Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() ); |
838 | |
|
839 | 0 | Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(u"Hidden"_ustr, true) }; |
840 | |
|
841 | 0 | INetURLObject aTemplURL( rName ); |
842 | 0 | uno::Reference< XDocumentPropertiesSupplier > xDocPropsSupplier; |
843 | 0 | uno::Reference< XStorable > xStorable; |
844 | 0 | try |
845 | 0 | { |
846 | 0 | xStorable.set( |
847 | 0 | xDesktop->loadComponentFromURL( aTemplURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), |
848 | 0 | u"_blank"_ustr, |
849 | 0 | 0, |
850 | 0 | aArgs ), |
851 | 0 | UNO_QUERY ); |
852 | |
|
853 | 0 | xDocPropsSupplier.set( xStorable, UNO_QUERY ); |
854 | 0 | } |
855 | 0 | catch( Exception& ) |
856 | 0 | { |
857 | 0 | } |
858 | |
|
859 | 0 | if( xStorable.is() ) |
860 | 0 | { |
861 | | // get Title from XDocumentPropertiesSupplier |
862 | 0 | if( xDocPropsSupplier.is() ) |
863 | 0 | { |
864 | 0 | uno::Reference< XDocumentProperties > xDocProps |
865 | 0 | = xDocPropsSupplier->getDocumentProperties(); |
866 | 0 | if (xDocProps.is() ) { |
867 | 0 | aTitle = xDocProps->getTitle(); |
868 | 0 | } |
869 | 0 | } |
870 | |
|
871 | 0 | if( aTitle.isEmpty() ) |
872 | 0 | { |
873 | 0 | INetURLObject aURL(std::move(aTemplURL)); |
874 | 0 | aURL.CutExtension(); |
875 | 0 | aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, |
876 | 0 | INetURLObject::DecodeMechanism::WithCharset ); |
877 | 0 | } |
878 | | |
879 | | // write a template using XStorable interface |
880 | 0 | bTemplateAdded = xTemplates->storeTemplate( pTargetRgn->GetTitle(), aTitle, xStorable ); |
881 | 0 | } |
882 | 0 | } |
883 | | |
884 | |
|
885 | 0 | if( bTemplateAdded ) |
886 | 0 | { |
887 | 0 | INetURLObject aTemplObj(pTargetRgn->GetHierarchyURL(pImp->GetRootURL())); |
888 | 0 | aTemplObj.insertName( aTitle, false, |
889 | 0 | INetURLObject::LAST_SEGMENT, |
890 | 0 | INetURLObject::EncodeMechanism::All ); |
891 | 0 | const OUString aTemplURL = aTemplObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); |
892 | |
|
893 | 0 | uno::Reference< XCommandEnvironment > aCmdEnv; |
894 | 0 | Content aTemplCont; |
895 | |
|
896 | 0 | if( Content::create( aTemplURL, aCmdEnv, comphelper::getProcessComponentContext(), aTemplCont ) ) |
897 | 0 | { |
898 | 0 | OUString aTemplName; |
899 | 0 | if( getTextProperty_Impl( aTemplCont, TARGET_URL, aTemplName ) ) |
900 | 0 | { |
901 | 0 | if ( nIdx == USHRT_MAX ) |
902 | 0 | nIdx = 0; |
903 | 0 | else |
904 | 0 | ++nIdx; |
905 | | |
906 | | // todo: fix SfxDocumentTemplates to handle size_t instead of sal_uInt16 |
907 | 0 | size_t temp_nIdx = nIdx; |
908 | 0 | pTargetRgn->AddEntry(pImp->GetRootURL(), aTitle, aTemplName, &temp_nIdx); |
909 | 0 | rName = aTitle; |
910 | 0 | return true; |
911 | 0 | } |
912 | 0 | else |
913 | 0 | { |
914 | 0 | SAL_WARN( "sfx.doc", "CopyFrom(): The content should contain target URL!" ); |
915 | 0 | } |
916 | 0 | } |
917 | 0 | else |
918 | 0 | { |
919 | 0 | SAL_WARN( "sfx.doc", "CopyFrom(): The content just was created!" ); |
920 | 0 | } |
921 | 0 | } |
922 | | |
923 | 0 | return false; |
924 | 0 | } |
925 | | |
926 | | |
927 | | bool SfxDocumentTemplates::Delete |
928 | | ( |
929 | | sal_uInt16 nRegion, // Region Index |
930 | | sal_uInt16 nIdx /* Index of the entry or USHRT_MAX, |
931 | | if a directory is meant. */ |
932 | | ) |
933 | | |
934 | | /* [Description] |
935 | | |
936 | | Deleting an entry or a directory |
937 | | |
938 | | [Return value] |
939 | | |
940 | | sal_Bool sal_True, Action could be performed |
941 | | sal_False, Action could not be performed |
942 | | |
943 | | [Cross-references] |
944 | | |
945 | | <SfxDocumentTemplates::InsertDir(const String&,sal_uInt16)> |
946 | | <SfxDocumentTemplates::KillDir(SfxTemplateDir&)> |
947 | | */ |
948 | | |
949 | 0 | { |
950 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
951 | | |
952 | | /* delete the template or folder in the hierarchy and in the |
953 | | template folder by sending a delete command to the content. |
954 | | Then remove the data from the lists |
955 | | */ |
956 | 0 | if ( ! pImp->Construct() ) |
957 | 0 | return false; |
958 | | |
959 | 0 | RegionData_Impl *pRegion = pImp->GetRegion( nRegion ); |
960 | |
|
961 | 0 | if ( !pRegion ) |
962 | 0 | return false; |
963 | | |
964 | 0 | bool bRet; |
965 | 0 | uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates(); |
966 | |
|
967 | 0 | if ( nIdx == USHRT_MAX ) |
968 | 0 | { |
969 | 0 | bRet = xTemplates->removeGroup( pRegion->GetTitle() ); |
970 | 0 | if ( bRet ) |
971 | 0 | pImp->DeleteRegion( nRegion ); |
972 | 0 | } |
973 | 0 | else |
974 | 0 | { |
975 | 0 | DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx ); |
976 | |
|
977 | 0 | if ( !pEntry ) |
978 | 0 | return false; |
979 | | |
980 | 0 | bRet = xTemplates->removeTemplate( pRegion->GetTitle(), |
981 | 0 | pEntry->GetTitle() ); |
982 | 0 | if( bRet ) |
983 | 0 | pRegion->DeleteEntry( nIdx ); |
984 | 0 | } |
985 | | |
986 | 0 | return bRet; |
987 | 0 | } |
988 | | |
989 | | |
990 | | bool SfxDocumentTemplates::InsertDir |
991 | | ( |
992 | | const OUString& rText, // the logical name of the new Region |
993 | | sal_uInt16 nRegion // Region Index |
994 | | ) |
995 | | |
996 | | /* [Description] |
997 | | |
998 | | Insert an index |
999 | | |
1000 | | [Return value] |
1001 | | |
1002 | | sal_Bool sal_True, Action could be performed |
1003 | | sal_False, Action could not be performed |
1004 | | |
1005 | | [Cross-references] |
1006 | | |
1007 | | <SfxDocumentTemplates::KillDir(SfxTemplateDir&)> |
1008 | | */ |
1009 | 0 | { |
1010 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
1011 | |
|
1012 | 0 | if ( ! pImp->Construct() ) |
1013 | 0 | return false; |
1014 | | |
1015 | 0 | RegionData_Impl *pRegion = pImp->GetRegion( rText ); |
1016 | |
|
1017 | 0 | if ( pRegion ) |
1018 | 0 | return false; |
1019 | | |
1020 | 0 | uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates(); |
1021 | |
|
1022 | 0 | if (xTemplates->addGroup(rText)) |
1023 | 0 | return pImp->InsertRegion(std::make_unique<RegionData_Impl>(rText), nRegion); |
1024 | | |
1025 | 0 | return false; |
1026 | 0 | } |
1027 | | |
1028 | | bool SfxDocumentTemplates::InsertTemplate(sal_uInt16 nSourceRegion, sal_uInt16 nIdx, const OUString &rName, const OUString &rPath) |
1029 | 0 | { |
1030 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
1031 | |
|
1032 | 0 | if ( ! pImp->Construct() ) |
1033 | 0 | return false; |
1034 | | |
1035 | 0 | RegionData_Impl *pRegion = pImp->GetRegion( nSourceRegion ); |
1036 | |
|
1037 | 0 | if ( !pRegion ) |
1038 | 0 | return false; |
1039 | | |
1040 | 0 | size_t pos = nIdx; |
1041 | 0 | pRegion->AddEntry(pImp->GetRootURL(), rName, rPath, &pos); |
1042 | |
|
1043 | 0 | return true; |
1044 | 0 | } |
1045 | | |
1046 | | bool SfxDocumentTemplates::SetName( const OUString& rName, sal_uInt16 nRegion, sal_uInt16 nIdx ) |
1047 | | |
1048 | 0 | { |
1049 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
1050 | |
|
1051 | 0 | if ( ! pImp->Construct() ) |
1052 | 0 | return false; |
1053 | | |
1054 | 0 | RegionData_Impl *pRegion = pImp->GetRegion( nRegion ); |
1055 | |
|
1056 | 0 | if ( !pRegion ) |
1057 | 0 | return false; |
1058 | | |
1059 | 0 | uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates(); |
1060 | |
|
1061 | 0 | if ( nIdx == USHRT_MAX ) |
1062 | 0 | { |
1063 | 0 | if ( pRegion->GetTitle() == rName ) |
1064 | 0 | return true; |
1065 | | |
1066 | | // we have to rename a region |
1067 | 0 | if ( xTemplates->renameGroup( pRegion->GetTitle(), rName ) ) |
1068 | 0 | { |
1069 | 0 | pRegion->SetTitle( rName ); |
1070 | 0 | pRegion->SetHierarchyURL( u""_ustr ); |
1071 | 0 | return true; |
1072 | 0 | } |
1073 | 0 | } |
1074 | 0 | else |
1075 | 0 | { |
1076 | 0 | DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx ); |
1077 | |
|
1078 | 0 | if ( !pEntry ) |
1079 | 0 | return false; |
1080 | | |
1081 | 0 | if ( pEntry->GetTitle() == rName ) |
1082 | 0 | return true; |
1083 | | |
1084 | 0 | if ( xTemplates->renameTemplate( pRegion->GetTitle(), |
1085 | 0 | pEntry->GetTitle(), |
1086 | 0 | rName ) ) |
1087 | 0 | { |
1088 | 0 | pEntry->SetTitle( rName ); |
1089 | 0 | pEntry->SetTargetURL( u""_ustr ); |
1090 | 0 | pEntry->SetHierarchyURL( u""_ustr ); |
1091 | 0 | return true; |
1092 | 0 | } |
1093 | 0 | } |
1094 | | |
1095 | 0 | return false; |
1096 | 0 | } |
1097 | | |
1098 | | |
1099 | | bool SfxDocumentTemplates::GetFull |
1100 | | ( |
1101 | | std::u16string_view rRegion, // Region Name |
1102 | | std::u16string_view rName, // Template Name |
1103 | | OUString &rPath // Out: Path + File name |
1104 | | ) |
1105 | | |
1106 | | /* [Description] |
1107 | | |
1108 | | Returns Path + File name of the template specified by rRegion and rName. |
1109 | | |
1110 | | [Return value] |
1111 | | |
1112 | | sal_Bool sal_True, Action could be performed |
1113 | | sal_False, Action could not be performed |
1114 | | |
1115 | | [Cross-references] |
1116 | | |
1117 | | <SfxDocumentTemplates::GetLogicNames(const String&,String&,String&)> |
1118 | | */ |
1119 | | |
1120 | 0 | { |
1121 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
1122 | | |
1123 | | // We don't search for empty names! |
1124 | 0 | if ( rName.empty() ) |
1125 | 0 | return false; |
1126 | | |
1127 | 0 | if ( ! pImp->Construct() ) |
1128 | 0 | return false; |
1129 | | |
1130 | 0 | DocTempl_EntryData_Impl* pEntry = nullptr; |
1131 | 0 | const sal_uInt16 nCount = GetRegionCount(); |
1132 | |
|
1133 | 0 | for ( sal_uInt16 i = 0; i < nCount; ++i ) |
1134 | 0 | { |
1135 | 0 | RegionData_Impl *pRegion = pImp->GetRegion( i ); |
1136 | |
|
1137 | 0 | if( pRegion && |
1138 | 0 | ( rRegion.empty() || ( rRegion == pRegion->GetTitle() ) ) ) |
1139 | 0 | { |
1140 | 0 | pEntry = pRegion->GetEntry( rName ); |
1141 | |
|
1142 | 0 | if ( pEntry ) |
1143 | 0 | { |
1144 | 0 | rPath = pEntry->GetTargetURL(pImp->GetRootURL()); |
1145 | 0 | break; |
1146 | 0 | } |
1147 | 0 | } |
1148 | 0 | } |
1149 | |
|
1150 | 0 | return ( pEntry != nullptr ); |
1151 | 0 | } |
1152 | | |
1153 | | |
1154 | | bool SfxDocumentTemplates::GetLogicNames |
1155 | | ( |
1156 | | std::u16string_view rPath, // Full Path to the template |
1157 | | OUString &rRegion, // Out: Region name |
1158 | | OUString &rName // Out: Template name |
1159 | | ) const |
1160 | | |
1161 | | /* [Description] |
1162 | | |
1163 | | Returns and logical path name to the template specified by rPath |
1164 | | |
1165 | | [Return value] |
1166 | | |
1167 | | sal_Bool sal_True, Action could be performed |
1168 | | sal_False, Action could not be performed |
1169 | | |
1170 | | [Cross-references] |
1171 | | |
1172 | | <SfxDocumentTemplates::GetFull(const String&,const String&,DirEntry&)> |
1173 | | */ |
1174 | | |
1175 | 0 | { |
1176 | 0 | DocTemplLocker_Impl aLocker( *pImp ); |
1177 | |
|
1178 | 0 | if ( ! pImp->Construct() ) |
1179 | 0 | return false; |
1180 | | |
1181 | 0 | INetURLObject aFullPath; |
1182 | |
|
1183 | 0 | aFullPath.SetSmartProtocol( INetProtocol::File ); |
1184 | 0 | aFullPath.SetURL( rPath ); |
1185 | 0 | const OUString aPath( aFullPath.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ); |
1186 | |
|
1187 | 0 | const sal_uInt16 nCount = GetRegionCount(); |
1188 | |
|
1189 | 0 | for ( sal_uInt16 i=0; i<nCount; ++i ) |
1190 | 0 | { |
1191 | 0 | RegionData_Impl *pData = pImp->GetRegion( i ); |
1192 | 0 | if ( pData ) |
1193 | 0 | { |
1194 | 0 | const sal_uInt16 nChildCount = pData->GetCount(); |
1195 | |
|
1196 | 0 | for ( sal_uInt16 j=0; j<nChildCount; ++j ) |
1197 | 0 | { |
1198 | 0 | DocTempl_EntryData_Impl *pEntry = pData->GetEntry( j ); |
1199 | 0 | if ( pEntry && pEntry->GetTargetURL(pImp->GetRootURL()) == aPath ) |
1200 | 0 | { |
1201 | 0 | rRegion = pData->GetTitle(); |
1202 | 0 | rName = pEntry->GetTitle(); |
1203 | 0 | return true; |
1204 | 0 | } |
1205 | 0 | } |
1206 | 0 | } |
1207 | 0 | } |
1208 | | |
1209 | 0 | return false; |
1210 | 0 | } |
1211 | | |
1212 | | |
1213 | | SfxDocumentTemplates::SfxDocumentTemplates() |
1214 | | |
1215 | | /* [Description] |
1216 | | |
1217 | | Constructor |
1218 | | */ |
1219 | 0 | { |
1220 | 0 | if ( !gpTemplateData ) |
1221 | 0 | gpTemplateData = new SfxDocTemplate_Impl; |
1222 | |
|
1223 | 0 | pImp = gpTemplateData; |
1224 | 0 | } |
1225 | | |
1226 | | |
1227 | | SfxDocumentTemplates::~SfxDocumentTemplates() |
1228 | | |
1229 | | /* [Description] |
1230 | | |
1231 | | Destructor |
1232 | | Release of administrative data |
1233 | | */ |
1234 | | |
1235 | 0 | { |
1236 | 0 | pImp = nullptr; |
1237 | 0 | } |
1238 | | |
1239 | | void SfxDocumentTemplates::Update( ) |
1240 | 0 | { |
1241 | 0 | if ( ::svt::TemplateFolderCache( true ).needsUpdate() ) // update is really necessary |
1242 | 0 | { |
1243 | 0 | if ( pImp->Construct() ) |
1244 | 0 | pImp->Rescan(); |
1245 | 0 | } |
1246 | 0 | } |
1247 | | |
1248 | | void SfxDocumentTemplates::ReInitFromComponent() |
1249 | 0 | { |
1250 | 0 | pImp->ReInitFromComponent(); |
1251 | 0 | } |
1252 | | |
1253 | | DocTempl_EntryData_Impl::DocTempl_EntryData_Impl(const OUString& rTitle) |
1254 | 0 | : maTitle(SfxDocumentTemplates::ConvertResourceString(rTitle)) |
1255 | 0 | { |
1256 | 0 | } |
1257 | | |
1258 | | int DocTempl_EntryData_Impl::Compare( std::u16string_view rTitle ) const |
1259 | 0 | { |
1260 | 0 | return maTitle.compareTo( rTitle ); |
1261 | 0 | } |
1262 | | |
1263 | | const OUString& DocTempl_EntryData_Impl::GetHierarchyURL(const INetURLObject& rRootURL) |
1264 | 0 | { |
1265 | 0 | if ( maOwnURL.isEmpty() ) |
1266 | 0 | { |
1267 | 0 | INetURLObject aTemplateObj(rRootURL); |
1268 | |
|
1269 | 0 | aTemplateObj.insertName( GetTitle(), false, |
1270 | 0 | INetURLObject::LAST_SEGMENT, |
1271 | 0 | INetURLObject::EncodeMechanism::All ); |
1272 | |
|
1273 | 0 | maOwnURL = aTemplateObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); |
1274 | 0 | DBG_ASSERT( !maOwnURL.isEmpty(), "GetHierarchyURL(): Could not create URL!" ); |
1275 | 0 | } |
1276 | |
|
1277 | 0 | return maOwnURL; |
1278 | 0 | } |
1279 | | |
1280 | | const OUString& DocTempl_EntryData_Impl::GetTargetURL(const INetURLObject& rRootURL) |
1281 | 0 | { |
1282 | 0 | if ( maTargetURL.isEmpty() ) |
1283 | 0 | { |
1284 | 0 | uno::Reference< XCommandEnvironment > aCmdEnv; |
1285 | 0 | Content aRegion; |
1286 | |
|
1287 | 0 | if ( Content::create( GetHierarchyURL(rRootURL), aCmdEnv, comphelper::getProcessComponentContext(), aRegion ) ) |
1288 | 0 | { |
1289 | 0 | getTextProperty_Impl( aRegion, TARGET_URL, maTargetURL ); |
1290 | 0 | } |
1291 | 0 | else |
1292 | 0 | { |
1293 | 0 | SAL_WARN( "sfx.doc", "GetTargetURL(): Could not create hierarchy content!" ); |
1294 | 0 | } |
1295 | 0 | } |
1296 | | |
1297 | 0 | return maTargetURL; |
1298 | 0 | } |
1299 | | |
1300 | | RegionData_Impl::RegionData_Impl(OUString aTitle) |
1301 | 0 | : maTitle(std::move(aTitle)) |
1302 | 0 | { |
1303 | 0 | } |
1304 | | |
1305 | | |
1306 | | size_t RegionData_Impl::GetEntryPos( std::u16string_view rTitle, bool& rFound ) const |
1307 | 0 | { |
1308 | 0 | const size_t nCount = maEntries.size(); |
1309 | |
|
1310 | 0 | for ( size_t i=0; i<nCount; ++i ) |
1311 | 0 | { |
1312 | 0 | auto &pData = maEntries[ i ]; |
1313 | |
|
1314 | 0 | if ( pData->Compare( rTitle ) == 0 ) |
1315 | 0 | { |
1316 | 0 | rFound = true; |
1317 | 0 | return i; |
1318 | 0 | } |
1319 | 0 | } |
1320 | | |
1321 | 0 | rFound = false; |
1322 | 0 | return nCount; |
1323 | 0 | } |
1324 | | |
1325 | | void RegionData_Impl::AddEntry(const INetURLObject& rRootURL, |
1326 | | const OUString& rTitle, |
1327 | | const OUString& rTargetURL, |
1328 | | const size_t *pPos) |
1329 | 0 | { |
1330 | 0 | INetURLObject aLinkObj( GetHierarchyURL(rRootURL) ); |
1331 | 0 | aLinkObj.insertName( rTitle, false, |
1332 | 0 | INetURLObject::LAST_SEGMENT, |
1333 | 0 | INetURLObject::EncodeMechanism::All ); |
1334 | 0 | const OUString aLinkURL = aLinkObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); |
1335 | |
|
1336 | 0 | bool bFound = false; |
1337 | 0 | size_t nPos = GetEntryPos( rTitle, bFound ); |
1338 | |
|
1339 | 0 | if ( bFound ) |
1340 | 0 | return; |
1341 | | |
1342 | 0 | if ( pPos ) |
1343 | 0 | nPos = *pPos; |
1344 | |
|
1345 | 0 | auto pEntry = std::make_unique<DocTempl_EntryData_Impl>(rTitle); |
1346 | 0 | pEntry->SetTargetURL( rTargetURL ); |
1347 | 0 | pEntry->SetHierarchyURL( aLinkURL ); |
1348 | 0 | if ( nPos < maEntries.size() ) { |
1349 | 0 | auto it = maEntries.begin(); |
1350 | 0 | std::advance( it, nPos ); |
1351 | 0 | maEntries.insert( it, std::move(pEntry) ); |
1352 | 0 | } |
1353 | 0 | else |
1354 | 0 | maEntries.push_back( std::move(pEntry) ); |
1355 | 0 | } |
1356 | | |
1357 | | size_t RegionData_Impl::GetCount() const |
1358 | 0 | { |
1359 | 0 | return maEntries.size(); |
1360 | 0 | } |
1361 | | |
1362 | | const OUString& RegionData_Impl::GetHierarchyURL(const INetURLObject& rRootURL) |
1363 | 0 | { |
1364 | 0 | if ( maOwnURL.isEmpty() ) |
1365 | 0 | { |
1366 | 0 | INetURLObject aRegionObj(rRootURL); |
1367 | |
|
1368 | 0 | aRegionObj.insertName( GetTitle(), false, |
1369 | 0 | INetURLObject::LAST_SEGMENT, |
1370 | 0 | INetURLObject::EncodeMechanism::All ); |
1371 | |
|
1372 | 0 | maOwnURL = aRegionObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); |
1373 | 0 | DBG_ASSERT( !maOwnURL.isEmpty(), "GetHierarchyURL(): Could not create URL!" ); |
1374 | 0 | } |
1375 | |
|
1376 | 0 | return maOwnURL; |
1377 | 0 | } |
1378 | | |
1379 | | DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( std::u16string_view rName ) const |
1380 | 0 | { |
1381 | 0 | bool bFound = false; |
1382 | 0 | tools::Long nPos = GetEntryPos( rName, bFound ); |
1383 | |
|
1384 | 0 | if ( bFound ) |
1385 | 0 | return maEntries[ nPos ].get(); |
1386 | 0 | return nullptr; |
1387 | 0 | } |
1388 | | |
1389 | | |
1390 | | DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( size_t nIndex ) const |
1391 | 0 | { |
1392 | 0 | if ( nIndex < maEntries.size() ) |
1393 | 0 | return maEntries[ nIndex ].get(); |
1394 | 0 | return nullptr; |
1395 | 0 | } |
1396 | | |
1397 | | void RegionData_Impl::DeleteEntry( size_t nIndex ) |
1398 | 0 | { |
1399 | 0 | if ( nIndex < maEntries.size() ) |
1400 | 0 | { |
1401 | 0 | auto it = maEntries.begin(); |
1402 | 0 | std::advance( it, nIndex ); |
1403 | 0 | maEntries.erase( it ); |
1404 | 0 | } |
1405 | 0 | } |
1406 | | |
1407 | | int RegionData_Impl::Compare( RegionData_Impl const * pCompare ) const |
1408 | 0 | { |
1409 | 0 | return maTitle.compareTo( pCompare->maTitle ); |
1410 | 0 | } |
1411 | | |
1412 | | SfxDocTemplate_Impl::SfxDocTemplate_Impl() |
1413 | 0 | : maStandardGroup(DocTemplLocaleHelper::GetStandardGroupString()) |
1414 | 0 | , mbConstructed(false) |
1415 | 0 | , mnLockCounter(0) |
1416 | 0 | { |
1417 | 0 | } |
1418 | | |
1419 | | SfxDocTemplate_Impl::~SfxDocTemplate_Impl() |
1420 | 0 | { |
1421 | 0 | gpTemplateData = nullptr; |
1422 | 0 | } |
1423 | | |
1424 | | void SfxDocTemplate_Impl::IncrementLock() |
1425 | 0 | { |
1426 | 0 | std::unique_lock aGuard( maMutex ); |
1427 | 0 | mnLockCounter++; |
1428 | 0 | } |
1429 | | |
1430 | | void SfxDocTemplate_Impl::DecrementLock() |
1431 | 0 | { |
1432 | 0 | std::unique_lock aGuard( maMutex ); |
1433 | 0 | if ( mnLockCounter ) |
1434 | 0 | mnLockCounter--; |
1435 | 0 | } |
1436 | | |
1437 | | RegionData_Impl* SfxDocTemplate_Impl::GetRegion( size_t nIndex ) const |
1438 | 0 | { |
1439 | 0 | if ( nIndex < maRegions.size() ) |
1440 | 0 | return maRegions[ nIndex ].get(); |
1441 | 0 | return nullptr; |
1442 | 0 | } |
1443 | | |
1444 | | RegionData_Impl* SfxDocTemplate_Impl::GetRegion( std::u16string_view rName ) |
1445 | | const |
1446 | 0 | { |
1447 | 0 | for (auto& pData : maRegions) |
1448 | 0 | { |
1449 | 0 | if( pData->GetTitle() == rName ) |
1450 | 0 | return pData.get(); |
1451 | 0 | } |
1452 | 0 | return nullptr; |
1453 | 0 | } |
1454 | | |
1455 | | |
1456 | | void SfxDocTemplate_Impl::DeleteRegion( size_t nIndex ) |
1457 | 0 | { |
1458 | 0 | if ( nIndex < maRegions.size() ) |
1459 | 0 | { |
1460 | 0 | auto it = maRegions.begin(); |
1461 | 0 | std::advance( it, nIndex ); |
1462 | 0 | maRegions.erase( it ); |
1463 | 0 | } |
1464 | 0 | } |
1465 | | |
1466 | | |
1467 | | /* AddRegion adds a Region to the RegionList |
1468 | | */ |
1469 | | void SfxDocTemplate_Impl::AddRegion( std::unique_lock<std::mutex>& /*rGuard*/, |
1470 | | const OUString& rTitle, |
1471 | | Content& rContent ) |
1472 | 0 | { |
1473 | 0 | auto pRegion = std::make_unique<RegionData_Impl>(rTitle); |
1474 | 0 | auto pRegionTmp = pRegion.get(); |
1475 | |
|
1476 | 0 | if ( ! InsertRegion( std::move(pRegion), size_t(-1) ) ) |
1477 | 0 | { |
1478 | 0 | return; |
1479 | 0 | } |
1480 | | |
1481 | | // now get the content of the region |
1482 | 0 | uno::Reference< XResultSet > xResultSet; |
1483 | |
|
1484 | 0 | try |
1485 | 0 | { |
1486 | 0 | xResultSet = rContent.createSortedCursor( { TITLE, TARGET_URL }, { { 1, true } }, m_rCompareFactory, INCLUDE_DOCUMENTS_ONLY ); |
1487 | 0 | } |
1488 | 0 | catch ( Exception& ) {} |
1489 | |
|
1490 | 0 | if ( !xResultSet.is() ) |
1491 | 0 | return; |
1492 | | |
1493 | 0 | uno::Reference< XRow > xRow( xResultSet, UNO_QUERY ); |
1494 | |
|
1495 | 0 | try |
1496 | 0 | { |
1497 | 0 | while ( xResultSet->next() ) |
1498 | 0 | { |
1499 | 0 | pRegionTmp->AddEntry(INetURLObject(maRootURL), xRow->getString( 1 ), xRow->getString( 2 ), nullptr); |
1500 | 0 | } |
1501 | 0 | } |
1502 | 0 | catch ( Exception& ) {} |
1503 | 0 | } |
1504 | | |
1505 | | void SfxDocTemplate_Impl::CreateFromHierarchy( std::unique_lock<std::mutex>& rGuard, Content &rTemplRoot ) |
1506 | 0 | { |
1507 | 0 | uno::Reference< XResultSet > xResultSet; |
1508 | 0 | Sequence< OUString > aProps { TITLE }; |
1509 | |
|
1510 | 0 | try |
1511 | 0 | { |
1512 | 0 | xResultSet = rTemplRoot.createSortedCursor( |
1513 | 0 | aProps, |
1514 | 0 | { // Sequence |
1515 | 0 | { // NumberedSortingInfo |
1516 | 0 | /* ColumnIndex */ 1, /* Ascending */ true |
1517 | 0 | } |
1518 | 0 | }, |
1519 | 0 | m_rCompareFactory, |
1520 | 0 | INCLUDE_FOLDERS_ONLY |
1521 | 0 | ); |
1522 | 0 | } |
1523 | 0 | catch ( Exception& ) {} |
1524 | |
|
1525 | 0 | if ( !xResultSet.is() ) |
1526 | 0 | return; |
1527 | | |
1528 | 0 | uno::Reference< XCommandEnvironment > aCmdEnv; |
1529 | 0 | uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY ); |
1530 | 0 | uno::Reference< XRow > xRow( xResultSet, UNO_QUERY ); |
1531 | |
|
1532 | 0 | try |
1533 | 0 | { |
1534 | 0 | while ( xResultSet->next() ) |
1535 | 0 | { |
1536 | 0 | const OUString aId = xContentAccess->queryContentIdentifierString(); |
1537 | 0 | Content aContent( aId, aCmdEnv, comphelper::getProcessComponentContext() ); |
1538 | |
|
1539 | 0 | AddRegion( rGuard, xRow->getString( 1 ), aContent ); |
1540 | 0 | } |
1541 | 0 | } |
1542 | 0 | catch ( Exception& ) {} |
1543 | 0 | } |
1544 | | |
1545 | | |
1546 | | bool SfxDocTemplate_Impl::Construct( ) |
1547 | 0 | { |
1548 | 0 | std::unique_lock aGuard( maMutex ); |
1549 | |
|
1550 | 0 | if ( mbConstructed ) |
1551 | 0 | return true; |
1552 | | |
1553 | 0 | const uno::Reference< XComponentContext >& xContext = ::comphelper::getProcessComponentContext(); |
1554 | |
|
1555 | 0 | mxInfo.set(document::DocumentProperties::create(xContext), UNO_QUERY); |
1556 | |
|
1557 | 0 | mxTemplates = frame::DocumentTemplates::create(xContext); |
1558 | |
|
1559 | 0 | uno::Reference< XLocalizable > xLocalizable( mxTemplates, UNO_QUERY ); |
1560 | |
|
1561 | 0 | m_rCompareFactory = AnyCompareFactory::createWithLocale(xContext, xLocalizable->getLocale()); |
1562 | |
|
1563 | 0 | uno::Reference < XContent > aRootContent = mxTemplates->getContent(); |
1564 | 0 | uno::Reference < XCommandEnvironment > aCmdEnv; |
1565 | |
|
1566 | 0 | if ( ! aRootContent.is() ) |
1567 | 0 | return false; |
1568 | | |
1569 | 0 | mbConstructed = true; |
1570 | 0 | maRootURL = aRootContent->getIdentifier()->getContentIdentifier(); |
1571 | |
|
1572 | 0 | Content aTemplRoot( aRootContent, aCmdEnv, xContext ); |
1573 | 0 | CreateFromHierarchy( aGuard, aTemplRoot ); |
1574 | |
|
1575 | 0 | return true; |
1576 | 0 | } |
1577 | | |
1578 | | |
1579 | | void SfxDocTemplate_Impl::ReInitFromComponent() |
1580 | 0 | { |
1581 | 0 | uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates(); |
1582 | 0 | if ( xTemplates.is() ) |
1583 | 0 | { |
1584 | 0 | uno::Reference < XContent > aRootContent = xTemplates->getContent(); |
1585 | 0 | uno::Reference < XCommandEnvironment > aCmdEnv; |
1586 | 0 | Content aTemplRoot( aRootContent, aCmdEnv, comphelper::getProcessComponentContext() ); |
1587 | 0 | Clear(); |
1588 | 0 | std::unique_lock aGuard(maMutex); |
1589 | 0 | CreateFromHierarchy( aGuard, aTemplRoot ); |
1590 | 0 | } |
1591 | 0 | } |
1592 | | |
1593 | | |
1594 | | bool SfxDocTemplate_Impl::InsertRegion( std::unique_ptr<RegionData_Impl> pNew, size_t nPos ) |
1595 | 0 | { |
1596 | | // return false (not inserted) if the entry already exists |
1597 | 0 | for (auto const& pRegion : maRegions) |
1598 | 0 | if ( pRegion->Compare( pNew.get() ) == 0 ) |
1599 | 0 | return false; |
1600 | | |
1601 | 0 | size_t newPos = nPos; |
1602 | 0 | if ( pNew->GetTitle() == maStandardGroup ) |
1603 | 0 | newPos = 0; |
1604 | |
|
1605 | 0 | if ( newPos < maRegions.size() ) |
1606 | 0 | { |
1607 | 0 | auto it = maRegions.begin(); |
1608 | 0 | std::advance( it, newPos ); |
1609 | 0 | maRegions.emplace( it, std::move(pNew) ); |
1610 | 0 | } |
1611 | 0 | else |
1612 | 0 | maRegions.emplace_back( std::move(pNew) ); |
1613 | |
|
1614 | 0 | return true; |
1615 | 0 | } |
1616 | | |
1617 | | |
1618 | | void SfxDocTemplate_Impl::Rescan() |
1619 | 0 | { |
1620 | 0 | Clear(); |
1621 | |
|
1622 | 0 | try |
1623 | 0 | { |
1624 | 0 | uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates(); |
1625 | 0 | DBG_ASSERT( xTemplates.is(), "SfxDocTemplate_Impl::Rescan:invalid template instance!" ); |
1626 | 0 | if ( xTemplates.is() ) |
1627 | 0 | { |
1628 | 0 | xTemplates->update(); |
1629 | |
|
1630 | 0 | uno::Reference < XContent > aRootContent = xTemplates->getContent(); |
1631 | 0 | uno::Reference < XCommandEnvironment > aCmdEnv; |
1632 | |
|
1633 | 0 | Content aTemplRoot( aRootContent, aCmdEnv, comphelper::getProcessComponentContext() ); |
1634 | 0 | std::unique_lock aGuard(maMutex); |
1635 | 0 | CreateFromHierarchy( aGuard, aTemplRoot ); |
1636 | 0 | } |
1637 | 0 | } |
1638 | 0 | catch( const Exception& ) |
1639 | 0 | { |
1640 | 0 | TOOLS_WARN_EXCEPTION( "sfx.doc", "SfxDocTemplate_Impl::Rescan: caught an exception while doing the update" ); |
1641 | 0 | } |
1642 | 0 | } |
1643 | | |
1644 | | |
1645 | | bool SfxDocTemplate_Impl::GetTitleFromURL( const OUString& rURL, |
1646 | | OUString& aTitle ) |
1647 | 0 | { |
1648 | 0 | if ( mxInfo.is() ) |
1649 | 0 | { |
1650 | 0 | try |
1651 | 0 | { |
1652 | 0 | mxInfo->read( rURL ); |
1653 | 0 | } |
1654 | 0 | catch ( Exception& ) |
1655 | 0 | { |
1656 | | // the document is not a StarOffice document |
1657 | 0 | return false; |
1658 | 0 | } |
1659 | | |
1660 | | |
1661 | 0 | try |
1662 | 0 | { |
1663 | 0 | uno::Reference< XPropertySet > aPropSet( mxInfo, UNO_QUERY ); |
1664 | 0 | if ( aPropSet.is() ) |
1665 | 0 | { |
1666 | 0 | Any aValue = aPropSet->getPropertyValue( TITLE ); |
1667 | 0 | aValue >>= aTitle; |
1668 | 0 | } |
1669 | 0 | } |
1670 | 0 | catch ( IOException& ) {} |
1671 | 0 | catch ( UnknownPropertyException& ) {} |
1672 | 0 | catch ( Exception& ) {} |
1673 | 0 | } |
1674 | | |
1675 | 0 | if ( aTitle.isEmpty() ) |
1676 | 0 | { |
1677 | 0 | INetURLObject aURL( rURL ); |
1678 | 0 | aURL.CutExtension(); |
1679 | 0 | aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, |
1680 | 0 | INetURLObject::DecodeMechanism::WithCharset ); |
1681 | 0 | } |
1682 | |
|
1683 | 0 | return true; |
1684 | 0 | } |
1685 | | |
1686 | | |
1687 | | void SfxDocTemplate_Impl::Clear() |
1688 | 0 | { |
1689 | 0 | std::unique_lock aGuard( maMutex ); |
1690 | 0 | if ( mnLockCounter ) |
1691 | 0 | return; |
1692 | 0 | maRegions.clear(); |
1693 | 0 | } |
1694 | | |
1695 | | |
1696 | | bool getTextProperty_Impl( Content& rContent, |
1697 | | const OUString& rPropName, |
1698 | | OUString& rPropValue ) |
1699 | 0 | { |
1700 | 0 | bool bGotProperty = false; |
1701 | | |
1702 | | // Get the property |
1703 | 0 | try |
1704 | 0 | { |
1705 | 0 | uno::Reference< XPropertySetInfo > aPropInfo = rContent.getProperties(); |
1706 | | |
1707 | | // check, whether or not the property exists |
1708 | 0 | if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) ) |
1709 | 0 | { |
1710 | 0 | return false; |
1711 | 0 | } |
1712 | | |
1713 | | // now get the property |
1714 | 0 | Any aAnyValue = rContent.getPropertyValue( rPropName ); |
1715 | 0 | aAnyValue >>= rPropValue; |
1716 | |
|
1717 | 0 | if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName ) ) |
1718 | 0 | { |
1719 | 0 | SfxURLRelocator_Impl aRelocImpl( ::comphelper::getProcessComponentContext() ); |
1720 | 0 | aRelocImpl.makeAbsoluteURL( rPropValue ); |
1721 | 0 | } |
1722 | |
|
1723 | 0 | bGotProperty = true; |
1724 | 0 | } |
1725 | 0 | catch ( RuntimeException& ) {} |
1726 | 0 | catch ( Exception& ) {} |
1727 | | |
1728 | 0 | return bGotProperty; |
1729 | 0 | } |
1730 | | |
1731 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |