Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "contentenumeration.hxx"
30 : : #include <svl/urlfilter.hxx>
31 : : #include <svtools/inettbc.hxx>
32 : : #include <svtools/imagemgr.hxx>
33 : :
34 : : #include <com/sun/star/beans/XPropertySet.hpp>
35 : : #include <com/sun/star/sdbc/XResultSet.hpp>
36 : : #include <com/sun/star/sdbc/XRow.hpp>
37 : : #include <com/sun/star/ucb/XDynamicResultSet.hpp>
38 : : #include <com/sun/star/ucb/XContentAccess.hpp>
39 : : #include <com/sun/star/util/DateTime.hpp>
40 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 : : #include <comphelper/processfactory.hxx>
42 : : #include <tools/debug.hxx>
43 : : #include <vcl/svapp.hxx>
44 : : #include <osl/mutex.hxx>
45 : :
46 : : #include <memory>
47 : :
48 : : //........................................................................
49 : : namespace svt
50 : : {
51 : : //........................................................................
52 : :
53 : : #define ROW_TITLE 1
54 : : #define ROW_SIZE 2
55 : : #define ROW_DATE_MOD 3
56 : : #define ROW_DATE_CREATE 4
57 : : #define ROW_IS_FOLDER 5
58 : : #define ROW_TARGET_URL 6
59 : : #define ROW_IS_HIDDEN 7
60 : : #define ROW_IS_VOLUME 8
61 : : #define ROW_IS_REMOTE 9
62 : : #define ROW_IS_REMOVEABLE 10
63 : : #define ROW_IS_FLOPPY 11
64 : : #define ROW_IS_COMPACTDISC 12
65 : :
66 : : #define CONVERT_DATETIME( aUnoDT, aToolsDT ) \
67 : : aToolsDT = ::DateTime( Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year ), \
68 : : Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds ) );
69 : :
70 : : using ::com::sun::star::uno::Reference;
71 : : using ::com::sun::star::uno::Sequence;
72 : : using ::com::sun::star::uno::Exception;
73 : : using ::com::sun::star::uno::UNO_QUERY;
74 : : using ::com::sun::star::uno::Any;
75 : : using ::com::sun::star::util::DateTime;
76 : : using ::com::sun::star::sdbc::XResultSet;
77 : : using ::com::sun::star::sdbc::XRow;
78 : : using ::com::sun::star::ucb::XDynamicResultSet;
79 : : using ::com::sun::star::ucb::CommandAbortedException;
80 : : using ::com::sun::star::ucb::XContentAccess;
81 : : using ::com::sun::star::ucb::XCommandEnvironment;
82 : : using ::com::sun::star::beans::XPropertySet;
83 : : using ::rtl::OUString;
84 : : using ::ucbhelper::ResultSetInclude;
85 : : using ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
86 : :
87 : : //====================================================================
88 : : //= FileViewContentEnumerator
89 : : //====================================================================
90 : : //--------------------------------------------------------------------
91 : 0 : FileViewContentEnumerator::FileViewContentEnumerator(
92 : : const Reference< XCommandEnvironment >& _rxCommandEnv,
93 : : ContentData& _rContentToFill, ::osl::Mutex& _rContentMutex,
94 : : const IContentTitleTranslation* _pTranslator )
95 : : :Thread ( "FileViewContentEnumerator" )
96 : : ,m_rContent ( _rContentToFill )
97 : : ,m_rContentMutex ( _rContentMutex )
98 : : ,m_xCommandEnv ( _rxCommandEnv )
99 : : ,m_pFilter ( NULL )
100 : : ,m_pTranslator ( _pTranslator )
101 : : ,m_bCancelled ( false )
102 [ # # ][ # # ]: 0 : ,m_rBlackList ( ::com::sun::star::uno::Sequence< ::rtl::OUString >() )
[ # # ]
103 : : {
104 : 0 : }
105 : :
106 : : //--------------------------------------------------------------------
107 [ # # ][ # # ]: 0 : FileViewContentEnumerator::~FileViewContentEnumerator()
[ # # ]
108 : : {
109 [ # # ]: 0 : }
110 : :
111 : : //--------------------------------------------------------------------
112 : 0 : void FileViewContentEnumerator::cancel()
113 : : {
114 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
115 : 0 : m_bCancelled = true;
116 : 0 : m_pResultHandler = NULL;
117 : 0 : m_pTranslator = NULL;
118 : 0 : m_pFilter = NULL;
119 [ # # ][ # # ]: 0 : m_aFolder.aContent = ::ucbhelper::Content();
[ # # ]
120 [ # # ][ # # ]: 0 : m_aFolder.sURL = String();
[ # # ][ # # ]
121 : 0 : }
122 : :
123 : : //--------------------------------------------------------------------
124 : 0 : EnumerationResult FileViewContentEnumerator::enumerateFolderContentSync(
125 : : const FolderDescriptor& _rFolder,
126 : : const IUrlFilter* _pFilter,
127 : : const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList )
128 : : {
129 : : {
130 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
131 [ # # ]: 0 : m_aFolder = _rFolder;
132 : 0 : m_pFilter = _pFilter;
133 : 0 : m_pResultHandler = NULL;
134 [ # # ][ # # ]: 0 : m_rBlackList = rBlackList;
135 : : }
136 : 0 : return enumerateFolderContent();
137 : : }
138 : :
139 : : //--------------------------------------------------------------------
140 : 0 : void FileViewContentEnumerator::enumerateFolderContent(
141 : : const FolderDescriptor& _rFolder, const IUrlFilter* _pFilter, IEnumerationResultHandler* _pResultHandler )
142 : : {
143 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
144 [ # # ]: 0 : m_aFolder = _rFolder;
145 : 0 : m_pFilter = _pFilter;
146 : 0 : m_pResultHandler = _pResultHandler;
147 : :
148 : : OSL_ENSURE( m_aFolder.aContent.get().is() || m_aFolder.sURL.Len(),
149 : : "FileViewContentEnumerator::enumerateFolderContent: invalid folder descriptor!" );
150 : :
151 [ # # ][ # # ]: 0 : launch();
152 : : //TODO: a protocol is missing how to join with the launched thread
153 : : // before exit(3), to ensure the thread is no longer relying on any
154 : : // infrastructure while that infrastructure is being shut down in
155 : : // atexit handlers
156 : 0 : }
157 : :
158 : : //--------------------------------------------------------------------
159 : 0 : EnumerationResult FileViewContentEnumerator::enumerateFolderContent()
160 : : {
161 : 0 : EnumerationResult eResult = ERROR;
162 : : try
163 : : {
164 : :
165 : 0 : Reference< XResultSet > xResultSet;
166 [ # # ]: 0 : Sequence< OUString > aProps(12);
167 : :
168 [ # # ][ # # ]: 0 : aProps[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ));
169 [ # # ][ # # ]: 0 : aProps[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ));
170 [ # # ][ # # ]: 0 : aProps[2] = OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ));
171 [ # # ][ # # ]: 0 : aProps[3] = OUString( RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ));
172 [ # # ][ # # ]: 0 : aProps[4] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ));
173 [ # # ][ # # ]: 0 : aProps[5] = OUString( RTL_CONSTASCII_USTRINGPARAM( "TargetURL" ));
174 [ # # ][ # # ]: 0 : aProps[6] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ));
175 [ # # ][ # # ]: 0 : aProps[7] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVolume" ));
176 [ # # ][ # # ]: 0 : aProps[8] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsRemote" ));
177 [ # # ][ # # ]: 0 : aProps[9] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsRemoveable" ));
178 [ # # ][ # # ]: 0 : aProps[10] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFloppy" ));
179 [ # # ][ # # ]: 0 : aProps[11] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsCompactDisc" ));
180 : :
181 : 0 : Reference< XCommandEnvironment > xEnvironment;
182 : : try
183 : : {
184 [ # # ]: 0 : FolderDescriptor aFolder;
185 : : {
186 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
187 [ # # ]: 0 : aFolder = m_aFolder;
188 [ # # ][ # # ]: 0 : xEnvironment = m_xCommandEnv;
189 : : }
190 [ # # ][ # # ]: 0 : if ( !aFolder.aContent.get().is() )
191 : : {
192 [ # # ][ # # ]: 0 : aFolder.aContent = ::ucbhelper::Content( aFolder.sURL, xEnvironment );
[ # # ][ # # ]
193 : : {
194 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
195 [ # # ][ # # ]: 0 : m_aFolder.aContent = aFolder.aContent;
196 : : }
197 : : }
198 : :
199 : 0 : Reference< XDynamicResultSet > xDynResultSet;
200 : 0 : ResultSetInclude eInclude = INCLUDE_FOLDERS_AND_DOCUMENTS;
201 [ # # ][ # # ]: 0 : xDynResultSet = aFolder.aContent.createDynamicCursor( aProps, eInclude );
202 : :
203 [ # # ]: 0 : if ( xDynResultSet.is() )
204 [ # # ][ # # ]: 0 : xResultSet = xDynResultSet->getStaticResultSet();
[ # # ][ # # ]
[ # # # ]
205 : : }
206 [ # # ]: 0 : catch( CommandAbortedException& )
207 : : {
208 : : SAL_WARN( "svtools.contnr", "createCursor: CommandAbortedException" );
209 : : }
210 [ # # ]: 0 : catch( Exception& )
211 : : {
212 : : }
213 : :
214 : 0 : bool bCancelled = false;
215 [ # # ]: 0 : if ( xResultSet.is() )
216 : : {
217 [ # # ]: 0 : Reference< XRow > xRow( xResultSet, UNO_QUERY );
218 [ # # ]: 0 : Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
219 : :
220 : : try
221 : : {
222 : : SortingData_Impl* pData;
223 : 0 : DateTime aDT;
224 : :
225 [ # # ][ # # ]: 0 : while ( !bCancelled && xResultSet->next() )
[ # # ][ # # ]
[ # # ]
226 : : {
227 [ # # ][ # # ]: 0 : sal_Bool bIsHidden = xRow->getBoolean( ROW_IS_HIDDEN );
228 : : // don't show hidden files
229 [ # # ][ # # ]: 0 : if ( !bIsHidden || xRow->wasNull() )
[ # # ][ # # ]
[ # # ]
230 : : {
231 : 0 : pData = NULL;
232 : :
233 [ # # ][ # # ]: 0 : aDT = xRow->getTimestamp( ROW_DATE_MOD );
234 [ # # ][ # # ]: 0 : sal_Bool bContainsDate = !xRow->wasNull();
235 [ # # ]: 0 : if ( !bContainsDate )
236 : : {
237 [ # # ][ # # ]: 0 : aDT = xRow->getTimestamp( ROW_DATE_CREATE );
238 [ # # ][ # # ]: 0 : bContainsDate = !xRow->wasNull();
239 : : }
240 : :
241 [ # # ][ # # ]: 0 : OUString aContentURL = xContentAccess->queryContentIdentifierString();
242 [ # # ][ # # ]: 0 : OUString aTargetURL = xRow->getString( ROW_TARGET_URL );
243 [ # # ][ # # ]: 0 : sal_Bool bHasTargetURL = !xRow->wasNull() && !aTargetURL.isEmpty();
[ # # ][ # # ]
244 : :
245 [ # # ]: 0 : OUString sRealURL = bHasTargetURL ? aTargetURL : aContentURL;
246 : :
247 : : // check for restrictions
248 : : {
249 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
250 [ # # ][ # # ]: 0 : if ( m_pFilter && !m_pFilter->isUrlAllowed( sRealURL ) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
251 : 0 : continue;
252 : :
253 [ # # ][ # # ]: 0 : if ( /* m_rBlackList.hasElements() && */ URLOnBlackList ( sRealURL ) )
254 [ # # ][ # # ]: 0 : continue;
255 : : }
256 : :
257 [ # # ][ # # ]: 0 : pData = new SortingData_Impl;
258 : 0 : pData->maTargetURL = sRealURL;
259 : :
260 [ # # ][ # # ]: 0 : pData->mbIsFolder = xRow->getBoolean( ROW_IS_FOLDER ) && !xRow->wasNull();
[ # # ][ # # ]
[ # # ][ # # ]
261 [ # # ][ # # ]: 0 : pData->mbIsVolume = xRow->getBoolean( ROW_IS_VOLUME ) && !xRow->wasNull();
[ # # ][ # # ]
[ # # ][ # # ]
262 [ # # ][ # # ]: 0 : pData->mbIsRemote = xRow->getBoolean( ROW_IS_REMOTE ) && !xRow->wasNull();
[ # # ][ # # ]
[ # # ][ # # ]
263 [ # # ][ # # ]: 0 : pData->mbIsRemoveable = xRow->getBoolean( ROW_IS_REMOVEABLE ) && !xRow->wasNull();
[ # # ][ # # ]
[ # # ][ # # ]
264 [ # # ][ # # ]: 0 : pData->mbIsFloppy = xRow->getBoolean( ROW_IS_FLOPPY ) && !xRow->wasNull();
[ # # ][ # # ]
[ # # ][ # # ]
265 [ # # ][ # # ]: 0 : pData->mbIsCompactDisc = xRow->getBoolean( ROW_IS_COMPACTDISC ) && !xRow->wasNull();
[ # # ][ # # ]
[ # # ][ # # ]
266 [ # # ][ # # ]: 0 : pData->SetNewTitle( xRow->getString( ROW_TITLE ) );
[ # # ]
267 [ # # ][ # # ]: 0 : pData->maSize = xRow->getLong( ROW_SIZE );
268 : :
269 [ # # # # ]: 0 : if ( bHasTargetURL &&
[ # # ]
270 [ # # ][ # # ]: 0 : INetURLObject( aContentURL ).GetProtocol() == INET_PROT_VND_SUN_STAR_HIER )
[ # # ][ # # ]
271 : : {
272 [ # # ]: 0 : ::ucbhelper::Content aCnt( aTargetURL, xEnvironment );
273 : : try
274 : : {
275 [ # # ][ # # ]: 0 : aCnt.getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" )) ) >>= pData->maSize;
276 [ # # ][ # # ]: 0 : aCnt.getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" )) ) >>= aDT;
[ # # ]
277 : : }
278 [ # # ][ # # ]: 0 : catch (...) {}
279 : : }
280 : :
281 [ # # ]: 0 : if ( bContainsDate )
282 : : {
283 [ # # ][ # # ]: 0 : CONVERT_DATETIME( aDT, pData->maModDate );
[ # # ]
284 : : }
285 : :
286 [ # # ]: 0 : if ( pData->mbIsFolder )
287 : : {
288 [ # # ]: 0 : SolarMutexGuard aGuard;
289 : : ::svtools::VolumeInfo aVolInfo( pData->mbIsVolume, pData->mbIsRemote,
290 : : pData->mbIsRemoveable, pData->mbIsFloppy,
291 : 0 : pData->mbIsCompactDisc );
292 [ # # ][ # # ]: 0 : pData->maType = SvFileInformationManager::GetFolderDescription( aVolInfo );
[ # # ][ # # ]
293 : : }
294 : : else
295 : : pData->maType = SvFileInformationManager::GetFileDescription(
296 [ # # ][ # # ]: 0 : INetURLObject( pData->maTargetURL ) );
[ # # ][ # # ]
[ # # ]
297 : :
298 : : // replace names on demand
299 : : {
300 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
301 [ # # ]: 0 : if( m_pTranslator )
302 : : {
303 : 0 : OUString sNewTitle;
304 : 0 : sal_Bool bTranslated = sal_False;
305 : :
306 [ # # ]: 0 : if ( pData->mbIsFolder )
307 [ # # ]: 0 : bTranslated = m_pTranslator->GetTranslation( pData->GetTitle(), sNewTitle );
308 : : else
309 [ # # ]: 0 : bTranslated = implGetDocTitle( pData->maTargetURL, sNewTitle );
310 : :
311 [ # # ]: 0 : if ( bTranslated )
312 [ # # ]: 0 : pData->ChangeTitle( sNewTitle );
313 [ # # ]: 0 : }
314 : : }
315 : :
316 : : {
317 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_rContentMutex );
318 [ # # ][ # # ]: 0 : m_rContent.push_back( pData );
319 [ # # ][ # # ]: 0 : }
[ # # ]
[ # # # ]
320 : : }
321 : :
322 : : {
323 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
324 [ # # ]: 0 : bCancelled = m_bCancelled;
325 : : }
326 : : }
327 : 0 : eResult = SUCCESS;
328 : : }
329 [ # # ]: 0 : catch( CommandAbortedException& )
330 : : {
331 : : SAL_WARN( "svtools.contnr", "FileViewContentEnumerator::enumerateFolderContent: caught an CommandAbortedException while enumerating!" );
332 : : }
333 [ # # ]: 0 : catch( Exception& )
334 : : {
335 : : SAL_WARN( "svtools.contnr", "FileViewContentEnumerator::enumerateFolderContent: caught an exception other than CommandAbortedException while enumerating!" );
336 : 0 : }
337 [ # # ]: 0 : }
[ # # # ]
338 : : }
339 : 0 : catch( CommandAbortedException& )
340 : : {
341 : : SAL_WARN( "svtools.contnr", "FileViewContentEnumerator::enumerateFolderContent: caught an CommandAbortedException!" );
342 : : }
343 : 0 : catch( Exception& )
344 : : {
345 : : SAL_WARN( "svtools.contnr", "FileViewContentEnumerator::enumerateFolderContent: caught an exception other than CommandAbortedException!" );
346 : : }
347 : :
348 : 0 : IEnumerationResultHandler* pHandler = NULL;
349 : : {
350 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
351 : 0 : pHandler = m_pResultHandler;
352 [ # # ]: 0 : if ( m_bCancelled )
353 [ # # ][ # # ]: 0 : return ERROR;
354 : : }
355 : :
356 : : {
357 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_rContentMutex );
358 [ # # ]: 0 : if ( eResult != SUCCESS )
359 : : // clear any "intermediate" and unfinished result
360 [ # # ]: 0 : m_rContent.clear();
361 : : }
362 : :
363 [ # # ]: 0 : if ( pHandler )
364 : 0 : pHandler->enumerationDone( eResult );
365 : 0 : return eResult;
366 : : }
367 : :
368 : : //--------------------------------------------------------------------
369 : :
370 : 0 : sal_Bool FileViewContentEnumerator::URLOnBlackList ( const ::rtl::OUString& sRealURL )
371 : : {
372 : 0 : ::rtl::OUString entryName = sRealURL.copy( sRealURL.lastIndexOf( '/' ) + 1 );
373 : :
374 [ # # ]: 0 : for (int i = 0; i < m_rBlackList.getLength() ; i++)
375 : : {
376 [ # # ][ # # ]: 0 : if ( entryName.equals( m_rBlackList[i] ) )
377 : 0 : return true;
378 : : }
379 : :
380 : 0 : return false;
381 : : }
382 : :
383 : : //--------------------------------------------------------------------
384 : 0 : sal_Bool FileViewContentEnumerator::implGetDocTitle( const OUString& _rTargetURL, OUString& _rRet ) const
385 : : {
386 : 0 : sal_Bool bRet = sal_False;
387 : :
388 : : try
389 : : {
390 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
391 [ # # ]: 0 : if( !m_xDocInfo.is() )
392 : : {
393 : : m_xDocInfo = m_xDocInfo.query(
394 [ # # ][ # # ]: 0 : ::comphelper::getProcessServiceFactory()->createInstance(
395 : : String( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.StandaloneDocumentInfo") )
396 : 0 : )
397 [ # # ][ # # ]: 0 : );
[ # # ][ # # ]
[ # # ][ # # ]
398 : : }
399 : :
400 : : DBG_ASSERT( m_xDocInfo.is(), "FileViewContentEnumerator::implGetDocTitle: no DocumentProperties service!" );
401 [ # # ]: 0 : if ( !m_xDocInfo.is() )
402 : 0 : return sal_False;
403 : :
404 [ # # ][ # # ]: 0 : m_xDocInfo->loadFromURL( _rTargetURL );
405 [ # # ]: 0 : Reference< XPropertySet > xPropSet( m_xDocInfo, UNO_QUERY );
406 : :
407 [ # # ][ # # ]: 0 : Any aAny = xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" )) );
[ # # ]
408 : :
409 : 0 : OUString sTitle;
410 [ # # ][ # # ]: 0 : if ( ( aAny >>= sTitle ) && !sTitle.isEmpty() )
[ # # ]
411 : : {
412 : 0 : _rRet = sTitle;
413 : 0 : bRet = sal_True;
414 [ # # ][ # # ]: 0 : }
[ # # ]
415 : : }
416 : 0 : catch ( const Exception& )
417 : : {
418 : : }
419 : :
420 : 0 : return bRet;
421 : : }
422 : :
423 : : //--------------------------------------------------------------------
424 : 0 : void FileViewContentEnumerator::execute()
425 : : {
426 : 0 : enumerateFolderContent();
427 : 0 : }
428 : :
429 : : //........................................................................
430 : : } // namespace svt
431 : : //........................................................................
432 : :
433 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|