LibreOffice Module svtools (master) 1
templatefoldercache.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
22#include <osl/file.hxx>
25#include <com/sun/star/sdbc/XResultSet.hpp>
26#include <com/sun/star/ucb/XDynamicResultSet.hpp>
27#include <com/sun/star/sdbc/XRow.hpp>
28#include <com/sun/star/ucb/CommandAbortedException.hpp>
29#include <com/sun/star/ucb/XContentAccess.hpp>
30#include <com/sun/star/uno/XComponentContext.hpp>
31#include <com/sun/star/util/theOfficeInstallationDirectories.hpp>
32#include <ucbhelper/content.hxx>
33#include <osl/diagnose.h>
34#include <rtl/ref.hxx>
36#include <tools/time.hxx>
37#include <tools/urlobj.hxx>
38#include <tools/debug.hxx>
41
43
44#include <mutex>
45#include <utility>
46#include <vector>
47#include <algorithm>
48
49
50namespace svt
51{
52
53
54 using namespace ::utl;
55 using namespace ::com::sun::star;
56 using namespace ::com::sun::star::sdbc;
57 using namespace ::com::sun::star::ucb;
58 using namespace ::com::sun::star::uno;
59
60
61 //= helpers
62
63
64 static SvStream& WriteDateTime( SvStream& _rStorage, const util::DateTime& _rDate )
65 {
66 sal_uInt16 hundredthSeconds = static_cast< sal_uInt16 >( _rDate.NanoSeconds / tools::Time::nanoPerCenti );
67 _rStorage.WriteUInt16( hundredthSeconds );
68
69 _rStorage.WriteUInt16( _rDate.Seconds );
70 _rStorage.WriteUInt16( _rDate.Minutes );
71 _rStorage.WriteUInt16( _rDate.Hours );
72 _rStorage.WriteUInt16( _rDate.Day );
73 _rStorage.WriteUInt16( _rDate.Month );
74 _rStorage.WriteInt16( _rDate.Year );
75
76 return _rStorage;
77 }
78
79
80 static SvStream& operator >> ( SvStream& _rStorage, util::DateTime& _rDate )
81 {
82 sal_uInt16 hundredthSeconds;
83 _rStorage.ReadUInt16( hundredthSeconds );
84 _rDate.NanoSeconds = static_cast< sal_uInt32 >( hundredthSeconds ) * tools::Time::nanoPerCenti;
85
86 _rStorage.ReadUInt16( _rDate.Seconds );
87 _rStorage.ReadUInt16( _rDate.Minutes );
88 _rStorage.ReadUInt16( _rDate.Hours );
89 _rStorage.ReadUInt16( _rDate.Day );
90 _rStorage.ReadUInt16( _rDate.Month );
91 _rStorage.ReadInt16( _rDate.Year );
92
93 return _rStorage;
94 }
95
96 //= TemplateContent
97
98 namespace {
99
100 struct TemplateContent;
101
102 }
103
104 typedef ::std::vector< ::rtl::Reference< TemplateContent > > TemplateFolderContent;
105 typedef TemplateFolderContent::const_iterator ConstFolderIterator;
106 typedef TemplateFolderContent::iterator FolderIterator;
107
108 namespace {
109
112 struct TemplateContent : public ::salhelper::SimpleReferenceObject
113 {
114 public:
115
116 private:
118 util::DateTime m_aLastModified; // date of last modification as reported by UCP
119 TemplateFolderContent m_aSubContents; // sorted (by name) list of the children
120
121 private:
122 void implResetDate( )
123 {
124 m_aLastModified.NanoSeconds = m_aLastModified.Seconds = m_aLastModified.Minutes = m_aLastModified.Hours = 0;
125 m_aLastModified.Day = m_aLastModified.Month = m_aLastModified.Year = 0;
126 }
127
128 private:
129 virtual ~TemplateContent() override;
130
131 public:
132 explicit TemplateContent( INetURLObject _aURL );
133
134 // attribute access
135 OUString getURL( ) const { return m_aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ); }
136 void setModDate( const util::DateTime& _rDate ) { m_aLastModified = _rDate; }
137 const util::DateTime& getModDate( ) const { return m_aLastModified; }
138
139 TemplateFolderContent& getSubContents() { return m_aSubContents; }
140 const TemplateFolderContent& getSubContents() const { return m_aSubContents; }
141
142 ConstFolderIterator end() const { return m_aSubContents.end(); }
143 TemplateFolderContent::size_type
144 size() const { return m_aSubContents.size(); }
145
146 void push_back( const ::rtl::Reference< TemplateContent >& _rxNewElement )
147 { m_aSubContents.push_back( _rxNewElement ); }
148 };
149
150 }
151
152 TemplateContent::TemplateContent( INetURLObject _aURL )
153 :m_aURL(std::move( _aURL ))
154 {
155 DBG_ASSERT( INetProtocol::NotValid != m_aURL.GetProtocol(), "TemplateContent::TemplateContent: invalid URL!" );
156 implResetDate();
157 }
158
159
160 TemplateContent::~TemplateContent()
161 {
162 }
163
164
165 //= stl helpers
166
167 namespace {
168
170 struct TemplateContentURLLess
171 {
172 bool operator() ( const ::rtl::Reference< TemplateContent >& _rxLHS, const ::rtl::Reference< TemplateContent >& _rxRHS ) const
173 {
174 return _rxLHS->getURL() < _rxRHS->getURL();
175 }
176 };
177
178
180 struct SubContentSort
181 {
182 void operator() ( TemplateFolderContent& _rFolder ) const
183 {
184 // sort the directory by name
185 ::std::sort(
186 _rFolder.begin(),
187 _rFolder.end(),
188 TemplateContentURLLess()
189 );
190
191 // sort the sub directories by name
192 ::std::for_each(
193 _rFolder.begin(),
194 _rFolder.end(),
195 *this
196 );
197 }
198
199 void operator() ( const ::rtl::Reference< TemplateContent >& _rxContent ) const
200 {
201 if ( _rxContent.is() && _rxContent->size() )
202 {
203 operator()( _rxContent->getSubContents() );
204 }
205 }
206 };
207
210 struct TemplateContentEqual
211 {
212
213 bool operator() (const ::rtl::Reference< TemplateContent >& _rLHS, const ::rtl::Reference< TemplateContent >& _rRHS )
214 {
215 if ( !_rLHS.is() || !_rRHS.is() )
216 {
217 OSL_FAIL( "TemplateContentEqual::operator(): invalid contents!" );
218 return true;
219 // this is not strictly true, in case only one is invalid - but this is a heavy error anyway
220 }
221
222 if ( _rLHS->getURL() != _rRHS->getURL() )
223 return false;
224
225 if ( _rLHS->getModDate() != _rRHS->getModDate() )
226 return false;
227
228 if ( _rLHS->getSubContents().size() != _rRHS->getSubContents().size() )
229 return false;
230
231 if ( !_rLHS->getSubContents().empty() )
232 { // there are children
233 // -> compare them
234 ::std::pair< FolderIterator, FolderIterator > aFirstDifferent = ::std::mismatch(
235 _rLHS->getSubContents().begin(),
236 _rLHS->getSubContents().end(),
237 _rRHS->getSubContents().begin(),
238 *this
239 );
240 if ( aFirstDifferent.first != _rLHS->getSubContents().end() )
241 return false;// the sub contents differ
242 }
243
244 return true;
245 }
246 };
247
248
250 struct StorageHelper
251 {
252 protected:
254 explicit StorageHelper( SvStream& _rStorage ) : m_rStorage( _rStorage ) { }
255 };
256
257
258 struct StoreContentURL : public StorageHelper
259 {
260 uno::Reference< util::XOfficeInstallationDirectories > m_xOfficeInstDirs;
261
262 StoreContentURL( SvStream& _rStorage,
263 uno::Reference<
264 util::XOfficeInstallationDirectories > xOfficeInstDirs )
265 : StorageHelper( _rStorage ), m_xOfficeInstDirs(std::move( xOfficeInstDirs )) { }
266
267 void operator() ( const ::rtl::Reference< TemplateContent >& _rxContent ) const
268 {
269 // use the base class operator with the local name of the content
270 OUString sURL = _rxContent->getURL();
271 // #116281# Keep office installation relocatable. Never store
272 // any direct references to office installation directory.
273 sURL = m_xOfficeInstDirs->makeRelocatableURL( sURL );
275 }
276 };
277
278
280 struct StoreFolderContent : public StorageHelper
281 {
282 uno::Reference< util::XOfficeInstallationDirectories > m_xOfficeInstDirs;
283
284 public:
285 StoreFolderContent( SvStream& _rStorage,
286 uno::Reference<
287 util::XOfficeInstallationDirectories > xOfficeInstDirs )
288 : StorageHelper( _rStorage ), m_xOfficeInstDirs(std::move( xOfficeInstDirs )) { }
289
290
291 void operator() ( const TemplateContent& _rContent ) const
292 {
293 // store the info about this content
294 WriteDateTime( m_rStorage, _rContent.getModDate() );
295
296 // store the info about the children
297 // the number
298 m_rStorage.WriteInt32( _rContent.size() );
299 // their URLs ( the local name is not enough, since URL might be not a hierarchical one, "expand:" for example )
300 ::std::for_each(
301 _rContent.getSubContents().begin(),
302 _rContent.getSubContents().end(),
303 StoreContentURL( m_rStorage, m_xOfficeInstDirs )
304 );
305 // their content
306 ::std::for_each(
307 _rContent.getSubContents().begin(),
308 _rContent.getSubContents().end(),
309 *this
310 );
311 }
312
313
314 void operator() ( const ::rtl::Reference< TemplateContent >& _rxContent ) const
315 {
316 if ( _rxContent.is() )
317 {
318 operator()( *_rxContent );
319 }
320 }
321 };
322
323
325 struct ReadFolderContent : public StorageHelper
326 {
327 uno::Reference< util::XOfficeInstallationDirectories > m_xOfficeInstDirs;
328
329 ReadFolderContent( SvStream& _rStorage,
330 uno::Reference<
331 util::XOfficeInstallationDirectories > xOfficeInstDirs )
332 : StorageHelper( _rStorage ), m_xOfficeInstDirs(std::move( xOfficeInstDirs )) { }
333
334
335 void operator() ( TemplateContent& _rContent ) const
336 {
337 // store the info about this content
338 util::DateTime aModDate;
339 m_rStorage >> aModDate;
340 _rContent.setModDate( aModDate );
341
342 // store the info about the children
343 // the number
344 sal_Int32 nChildren = 0;
345 m_rStorage.ReadInt32( nChildren );
346 TemplateFolderContent& rChildren = _rContent.getSubContents();
347 rChildren.resize( 0 );
348 rChildren.reserve( nChildren );
349 // initialize them with their (local) names
350 while ( nChildren-- )
351 {
353 sURL = m_xOfficeInstDirs->makeAbsoluteURL( sURL );
354 rChildren.push_back( new TemplateContent( INetURLObject( sURL ) ) );
355 }
356
357 // their content
358 ::std::for_each(
359 _rContent.getSubContents().begin(),
360 _rContent.getSubContents().end(),
361 *this
362 );
363 }
364
365
366 void operator() ( const ::rtl::Reference< TemplateContent >& _rxContent ) const
367 {
368 if ( _rxContent.is() )
369 {
370 operator()( *_rxContent );
371 }
372 }
373 };
374
375 }
376
377 //= TemplateFolderCacheImpl
378
380 {
381 private:
382 TemplateFolderContent m_aPreviousState; // the current state of the template dirs (as found on the HD)
383 TemplateFolderContent m_aCurrentState; // the previous state of the template dirs (as found in the cache file)
384
385 std::mutex m_aMutex;
386 // will be lazy inited; never access directly; use getOfficeInstDirs().
387 uno::Reference< util::XOfficeInstallationDirectories > m_xOfficeInstDirs;
388
389 std::unique_ptr<SvStream> m_pCacheStream;
391 bool m_bKnowState : 1;
394
395 public:
396 explicit TemplateFolderCacheImpl( bool _bAutoStoreState );
398
399 bool needsUpdate();
400 void storeState();
401
402 private:
403 bool openCacheStream( bool _bForRead );
404 void closeCacheStream( );
405
407 bool readPreviousState();
409 bool readCurrentState();
410
411 static OUString implParseSmart( const OUString& _rPath );
412
413 bool implReadFolder( const ::rtl::Reference< TemplateContent >& _rxRoot );
414
415 static sal_Int32 getMagicNumber();
416 static void normalize( TemplateFolderContent& _rState );
417
418 // @return <TRUE/> if the states equal
419 static bool equalStates( const TemplateFolderContent& _rLHS, const TemplateFolderContent& _rRHS );
420
421 // late initialize m_xOfficeInstDirs
422 const uno::Reference< util::XOfficeInstallationDirectories >& getOfficeInstDirs();
423 };
424
425
426 TemplateFolderCacheImpl::TemplateFolderCacheImpl( bool _bAutoStoreState )
427 :m_bNeedsUpdate ( true )
428 ,m_bKnowState ( false )
429 ,m_bValidCurrentState ( false )
430 ,m_bAutoStoreState ( _bAutoStoreState )
431 {
432 }
433
434
436 {
437 // store the current state if possible and required
439 storeState();
440
442 }
443
444
446 {
447 return (sal_Int8('T') << 12)
448 | (sal_Int8('D') << 8)
449 | (sal_Int8('S') << 4)
450 | (sal_Int8('C'));
451 }
452
453
455 {
456 SubContentSort()( _rState );
457 }
458
459
461 {
462 if ( _rLHS.size() != _rRHS.size() )
463 return false;
464
465 // as both arrays are sorted (by definition - this is a precondition of this method)
466 // we can simply go from the front to the back and compare the single elements
467
468 ::std::pair< ConstFolderIterator, ConstFolderIterator > aFirstDifferent = ::std::mismatch(
469 _rLHS.begin(),
470 _rLHS.end(),
471 _rRHS.begin(),
472 TemplateContentEqual()
473 );
474
475 return aFirstDifferent.first == _rLHS.end();
476 }
477
478
480 {
483
484 if ( !(m_bValidCurrentState && openCacheStream( false )) )
485 return;
486
487 m_pCacheStream->WriteInt32( getMagicNumber() );
488
489 // store the template root folders
490 // the size
491 m_pCacheStream->WriteInt32( m_aCurrentState.size() );
492 // the complete URLs
493 ::std::for_each(
494 m_aCurrentState.begin(),
495 m_aCurrentState.end(),
496 StoreContentURL( *m_pCacheStream, getOfficeInstDirs() )
497 );
498
499 // the contents
500 ::std::for_each(
501 m_aCurrentState.begin(),
502 m_aCurrentState.end(),
503 StoreFolderContent( *m_pCacheStream, getOfficeInstDirs() )
504 );
505 }
506
507
508 OUString TemplateFolderCacheImpl::implParseSmart( const OUString& _rPath )
509 {
510 INetURLObject aParser;
511 aParser.SetSmartProtocol( INetProtocol::File );
512 aParser.SetURL( _rPath );
513 if ( INetProtocol::NotValid == aParser.GetProtocol() )
514 {
515 OUString sURL;
516 osl::FileBase::getFileURLFromSystemPath( _rPath, sURL );
517 aParser.SetURL( sURL );
518 }
520 }
521
522
524 {
525 m_pCacheStream.reset();
526 }
527
528
529 bool TemplateFolderCacheImpl::implReadFolder( const ::rtl::Reference< TemplateContent >& _rxRoot )
530 {
531 try
532 {
533 // create a content for the current folder root
534 Reference< XResultSet > xResultSet;
535 Sequence< OUString > aContentProperties{ "Title", "DateModified", "DateCreated",
536 "IsFolder" };
537
538 // get the set of sub contents in the folder
539 try
540 {
541 Reference< XDynamicResultSet > xDynResultSet;
542
544 xDynResultSet = aTemplateRoot.createDynamicCursor( aContentProperties );
545 if ( xDynResultSet.is() )
546 xResultSet = xDynResultSet->getStaticResultSet();
547 }
548 catch( CommandAbortedException& )
549 {
550 TOOLS_WARN_EXCEPTION( "svtools.misc", "" );
551 return false;
552 }
553 catch( css::uno::Exception& )
554 {
555 }
556
557 // collect the infos about the sub contents
558 if ( xResultSet.is() )
559 {
560 Reference< XRow > xRow( xResultSet, UNO_QUERY_THROW );
561 Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY_THROW );
562
563 while ( xResultSet->next() )
564 {
565 INetURLObject aSubContentURL( xContentAccess->queryContentIdentifierString() );
566
567 // a new content instance
568 ::rtl::Reference< TemplateContent > xChild = new TemplateContent( std::move(aSubContentURL) );
569
570 // the modified date
571 xChild->setModDate( xRow->getTimestamp( 2 ) ); // date modified
572 if ( xRow->wasNull() )
573 xChild->setModDate( xRow->getTimestamp( 3 ) ); // fallback: date created
574
575 // push back this content
576 _rxRoot->push_back( xChild );
577
578 // is it a folder?
579 if ( xRow->getBoolean( 4 ) && !xRow->wasNull() )
580 { // yes -> step down
581 ConstFolderIterator aNextLevelRoot = _rxRoot->end();
582 --aNextLevelRoot;
583 implReadFolder( *aNextLevelRoot );
584 }
585 }
586 }
587 }
588 catch( const Exception& )
589 {
590 TOOLS_WARN_EXCEPTION( "svtools", "TemplateFolderCacheImpl::implReadFolder" );
591 return false;
592 }
593 return true;
594 }
595
596
598 {
599 // reset
600 m_bValidCurrentState = false;
601 TemplateFolderContent aTemplateFolderContent;
602 m_aCurrentState.swap( aTemplateFolderContent );
603
604 // the template directories from the config
605 const SvtPathOptions aPathOptions;
606 const OUString& aDirs = aPathOptions.GetTemplatePath();
607
608 // loop through all the root-level template folders
609 sal_Int32 nIndex = 0;
610 do
611 {
612 OUString sTemplatePath( aDirs.getToken(0, ';', nIndex) );
613 sTemplatePath = aPathOptions.ExpandMacros( sTemplatePath );
614
615 // Make sure excess ".." path segments (from expanding bootstrap
616 // variables in paths) are normalized in the same way they are
617 // normalized for paths read from the .templdir.cache file (where
618 // paths have gone through makeRelocatable URL on writing out and
619 // then through makeAbsoluteURL when reading back in), as otherwise
620 // equalStates() in needsUpdate() could erroneously consider
621 // m_aCurrentState and m_aPreviousState as different:
622 sTemplatePath = getOfficeInstDirs()->makeAbsoluteURL(
623 getOfficeInstDirs()->makeRelocatableURL(sTemplatePath));
624
625 // create a new entry
626 m_aCurrentState.push_back( new TemplateContent( INetURLObject( sTemplatePath ) ) );
627 TemplateFolderContent::iterator aCurrentRoot = m_aCurrentState.end();
628 --aCurrentRoot;
629
630 if ( !implReadFolder( *aCurrentRoot ) )
631 return false;
632 }
633 while ( nIndex >= 0 );
634
635 // normalize the array (which basically means "sort it")
637
640 }
641
642
644 {
645 DBG_ASSERT( m_pCacheStream, "TemplateFolderCacheImpl::readPreviousState: not to be called without stream!" );
646
647 // reset
648 TemplateFolderContent aTemplateFolderContent;
649 m_aPreviousState.swap( aTemplateFolderContent );
650
651 // check the magic number
652 sal_Int32 nMagic = 0;
653 m_pCacheStream->ReadInt32( nMagic );
654 DBG_ASSERT( getMagicNumber() == nMagic, "TemplateFolderCacheImpl::readPreviousState: invalid cache file!" );
655 if ( getMagicNumber() != nMagic )
656 return false;
657
658 // the root directories
659 // their number
660 sal_Int32 nRootDirectories = 0;
661 m_pCacheStream->ReadInt32( nRootDirectories );
662 // init empty TemplateContents with the URLs
663 m_aPreviousState.reserve( nRootDirectories );
664 while ( nRootDirectories-- )
665 {
666 OUString sURL = m_pCacheStream->ReadUniOrByteString(m_pCacheStream->GetStreamCharSet());
667 // #116281# Keep office installation relocatable. Never store
668 // any direct references to office installation directory.
669 sURL = getOfficeInstDirs()->makeAbsoluteURL( sURL );
670 m_aPreviousState.push_back(
671 new TemplateContent( INetURLObject(sURL) ) );
672 }
673
674 // read the contents of the root folders
675 ::std::for_each(
676 m_aPreviousState.begin(),
677 m_aPreviousState.end(),
678 ReadFolderContent( *m_pCacheStream, getOfficeInstDirs() )
679 );
680
681 DBG_ASSERT( !m_pCacheStream->GetErrorCode(), "TemplateFolderCacheImpl::readPreviousState: unknown error during reading the state cache!" );
682
683 // normalize the array (which basically means "sort it")
685
686 return true;
687 }
688
689
691 {
692 // close any old stream instance
694
695 // get the storage directory
696 OUString sStorageURL = implParseSmart( SvtPathOptions().GetStoragePath() );
697 INetURLObject aStorageURL( sStorageURL );
698 if ( INetProtocol::NotValid == aStorageURL.GetProtocol() )
699 {
700 OSL_FAIL( "TemplateFolderCacheImpl::openCacheStream: invalid storage path!" );
701 return false;
702 }
703
704 // append our name
705 aStorageURL.Append( u".templdir.cache" );
706
707 // open the stream
708 m_pCacheStream = UcbStreamHelper::CreateStream( aStorageURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ),
709 _bForRead ? StreamMode::READ | StreamMode::NOCREATE : StreamMode::WRITE | StreamMode::TRUNC );
710 DBG_ASSERT( m_pCacheStream, "TemplateFolderCacheImpl::openCacheStream: could not open/create the cache stream!" );
711 if ( m_pCacheStream && m_pCacheStream->GetErrorCode() )
712 {
713 m_pCacheStream.reset();
714 }
715
716 if ( m_pCacheStream )
717 m_pCacheStream->SetStreamCharSet( RTL_TEXTENCODING_UTF8 );
718
719 return nullptr != m_pCacheStream;
720 }
721
722
724 {
725 if ( m_bKnowState )
726 return m_bNeedsUpdate;
727
728 m_bNeedsUpdate = true;
729 m_bKnowState = true;
730
731 if ( readCurrentState() )
732 {
733 // open the stream which contains the cached state of the directories
734 if ( openCacheStream( true ) )
735 { // opening the stream succeeded
736 if ( readPreviousState() )
737 {
739 }
740 else
741 {
743 }
744 }
745 }
746 return m_bNeedsUpdate;
747 }
748
749
750 const uno::Reference< util::XOfficeInstallationDirectories >&
752 {
753 if ( !m_xOfficeInstDirs.is() )
754 {
755 std::lock_guard aGuard( m_aMutex );
756 if ( !m_xOfficeInstDirs.is() )
757 {
758 uno::Reference< uno::XComponentContext > xCtx(
760 m_xOfficeInstDirs = util::theOfficeInstallationDirectories::get(xCtx);
761 }
762 }
763 return m_xOfficeInstDirs;
764 }
765
766
767 //= TemplateFolderCache
768
769
770 TemplateFolderCache::TemplateFolderCache( bool _bAutoStoreState )
771 :m_pImpl( new TemplateFolderCacheImpl( _bAutoStoreState ) )
772 {
773 }
774
775
776 TemplateFolderCache::~TemplateFolderCache( )
777 {
778 }
779
780
781 bool TemplateFolderCache::needsUpdate()
782 {
783 return m_pImpl->needsUpdate();
784 }
785
786
787 void TemplateFolderCache::storeState()
788 {
789 m_pImpl->storeState();
790 }
791
792
793} // namespace sfx2
794
795
796/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
void SetSmartProtocol(INetProtocol eTheSmartScheme)
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
INetProtocol GetProtocol() const
bool Append(std::u16string_view rTheSegment, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
bool SetURL(std::u16string_view rTheAbsURIRef, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
SvStream & WriteInt32(sal_Int32 nInt32)
SvStream & WriteUniOrByteString(std::u16string_view rStr, rtl_TextEncoding eDestCharSet)
OUString ReadUniOrByteString(rtl_TextEncoding eSrcCharSet)
SvStream & ReadInt16(sal_Int16 &rInt16)
SvStream & WriteInt16(sal_Int16 nInt16)
SvStream & WriteUInt16(sal_uInt16 nUInt16)
SvStream & ReadInt32(sal_Int32 &rInt32)
rtl_TextEncoding GetStreamCharSet() const
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
OUString ExpandMacros(const OUString &rPath) const
const OUString & GetTemplatePath() const
bool openCacheStream(bool _bForRead)
static void normalize(TemplateFolderContent &_rState)
static OUString implParseSmart(const OUString &_rPath)
static bool equalStates(const TemplateFolderContent &_rLHS, const TemplateFolderContent &_rRHS)
TemplateFolderContent m_aPreviousState
bool implReadFolder(const ::rtl::Reference< TemplateContent > &_rxRoot)
std::unique_ptr< SvStream > m_pCacheStream
bool readCurrentState()
read the current state of the dirs
TemplateFolderContent m_aCurrentState
bool readPreviousState()
read the state of the dirs from the cache file
const uno::Reference< util::XOfficeInstallationDirectories > & getOfficeInstDirs()
uno::Reference< util::XOfficeInstallationDirectories > m_xOfficeInstDirs
static const sal_Int64 nanoPerCenti
css::uno::Reference< css::ucb::XDynamicResultSet > createDynamicCursor(const css::uno::Sequence< OUString > &rPropertyNames, ResultSetInclude eMode=INCLUDE_FOLDERS_AND_DOCUMENTS)
#define DBG_ASSERT(sCon, aError)
#define TOOLS_WARN_EXCEPTION(area, stream)
float u
sal_Int32 nIndex
size
@ Exception
bool normalize(sal_uInt16 &rDay, sal_uInt16 &rMonth, sal_Int16 &rYear)
Reference< XComponentContext > getProcessComponentContext()
end
static SvStream & WriteDateTime(SvStream &_rStorage, const util::DateTime &_rDate)
::std::vector< ::rtl::Reference< TemplateContent > > TemplateFolderContent
TemplateFolderContent::iterator FolderIterator
TemplateFolderContent::const_iterator ConstFolderIterator
static SvStream & operator>>(SvStream &_rStorage, util::DateTime &_rDate)
const sal_uInt16 nMagic
TemplateFolderContent m_aSubContents
SvStream & m_rStorage
uno::Reference< util::XOfficeInstallationDirectories > m_xOfficeInstDirs
INetURLObject m_aURL
util::DateTime m_aLastModified
signed char sal_Int8