| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svtools.hxx" |
| #include "contentenumeration.hxx" |
| #include <svl/urlfilter.hxx> |
| #include <svtools/inettbc.hxx> |
| #include <svtools/imagemgr.hxx> |
| |
| /** === begin UNO includes === **/ |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <com/sun/star/sdbc/XResultSet.hpp> |
| #include <com/sun/star/sdbc/XRow.hpp> |
| #include <com/sun/star/ucb/XDynamicResultSet.hpp> |
| #include <com/sun/star/ucb/XContentAccess.hpp> |
| #include <com/sun/star/util/DateTime.hpp> |
| #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
| /** === end UNO includes === **/ |
| #include <comphelper/processfactory.hxx> |
| #include <tools/debug.hxx> |
| #include <vcl/svapp.hxx> |
| #include <vos/mutex.hxx> |
| |
| #include <memory> |
| |
| //........................................................................ |
| namespace svt |
| { |
| //........................................................................ |
| |
| #define ROW_TITLE 1 |
| #define ROW_SIZE 2 |
| #define ROW_DATE_MOD 3 |
| #define ROW_DATE_CREATE 4 |
| #define ROW_IS_FOLDER 5 |
| #define ROW_TARGET_URL 6 |
| #define ROW_IS_HIDDEN 7 |
| #define ROW_IS_VOLUME 8 |
| #define ROW_IS_REMOTE 9 |
| #define ROW_IS_REMOVEABLE 10 |
| #define ROW_IS_FLOPPY 11 |
| #define ROW_IS_COMPACTDISC 12 |
| |
| #define CONVERT_DATETIME( aUnoDT, aToolsDT ) \ |
| aToolsDT = ::DateTime( Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year ), \ |
| Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds ) ); |
| |
| using ::com::sun::star::uno::Reference; |
| using ::com::sun::star::uno::Sequence; |
| using ::com::sun::star::uno::Exception; |
| using ::com::sun::star::uno::UNO_QUERY; |
| using ::com::sun::star::uno::Any; |
| using ::com::sun::star::util::DateTime; |
| using ::com::sun::star::sdbc::XResultSet; |
| using ::com::sun::star::sdbc::XRow; |
| using ::com::sun::star::ucb::XDynamicResultSet; |
| using ::com::sun::star::ucb::CommandAbortedException; |
| using ::com::sun::star::ucb::XContentAccess; |
| using ::com::sun::star::ucb::XCommandEnvironment; |
| using ::com::sun::star::beans::XPropertySet; |
| using ::rtl::OUString; |
| using ::ucbhelper::ResultSetInclude; |
| using ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS; |
| |
| //==================================================================== |
| //= FileViewContentEnumerator |
| //==================================================================== |
| //-------------------------------------------------------------------- |
| FileViewContentEnumerator::FileViewContentEnumerator( |
| const Reference< XCommandEnvironment >& _rxCommandEnv, |
| ContentData& _rContentToFill, ::osl::Mutex& _rContentMutex, |
| const IContentTitleTranslation* _pTranslator ) |
| :m_rContent ( _rContentToFill ) |
| ,m_rContentMutex ( _rContentMutex ) |
| ,m_refCount ( 0 ) |
| ,m_xCommandEnv ( _rxCommandEnv ) |
| ,m_pFilter ( NULL ) |
| ,m_pTranslator ( _pTranslator ) |
| ,m_bCancelled ( false ) |
| ,m_rBlackList ( ::com::sun::star::uno::Sequence< ::rtl::OUString >() ) |
| { |
| } |
| |
| //-------------------------------------------------------------------- |
| FileViewContentEnumerator::~FileViewContentEnumerator() |
| { |
| } |
| |
| //-------------------------------------------------------------------- |
| void FileViewContentEnumerator::cancel() |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| m_bCancelled = true; |
| m_pResultHandler = NULL; |
| m_pTranslator = NULL; |
| m_pFilter = NULL; |
| m_aFolder.aContent = ::ucbhelper::Content(); |
| m_aFolder.sURL = String(); |
| } |
| |
| //-------------------------------------------------------------------- |
| EnumerationResult FileViewContentEnumerator::enumerateFolderContentSync( |
| const FolderDescriptor& _rFolder, |
| const IUrlFilter* _pFilter, |
| const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList ) |
| { |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| m_aFolder = _rFolder; |
| m_pFilter = _pFilter; |
| m_pResultHandler = NULL; |
| m_rBlackList = rBlackList; |
| } |
| return enumerateFolderContent(); |
| } |
| |
| //-------------------------------------------------------------------- |
| void FileViewContentEnumerator::enumerateFolderContent( |
| const FolderDescriptor& _rFolder, const IUrlFilter* _pFilter, IEnumerationResultHandler* _pResultHandler ) |
| { |
| // ensure that we don't get deleted while herein |
| acquire(); |
| // the matching "release" will be called in onTerminated |
| // Note that onTerminated is only called if run was left normally. |
| // If somebody terminates the thread from the outside, then onTerminated |
| // will never be called. However, our terminate method is not accessible |
| // to our clients, so the only class which could misbehave is this class |
| // here itself ... |
| |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| m_aFolder = _rFolder; |
| m_pFilter = _pFilter; |
| m_pResultHandler = _pResultHandler; |
| |
| OSL_ENSURE( m_aFolder.aContent.get().is() || m_aFolder.sURL.Len(), |
| "FileViewContentEnumerator::enumerateFolderContent: invalid folder descriptor!" ); |
| |
| // start the thread |
| create(); |
| } |
| |
| //-------------------------------------------------------------------- |
| oslInterlockedCount SAL_CALL FileViewContentEnumerator::acquire() |
| { |
| return osl_incrementInterlockedCount( &m_refCount ); |
| } |
| |
| //-------------------------------------------------------------------- |
| oslInterlockedCount SAL_CALL FileViewContentEnumerator::release() |
| { |
| if ( 0 == osl_decrementInterlockedCount( &m_refCount ) ) |
| { |
| delete this; |
| return 0; |
| } |
| return m_refCount; |
| } |
| |
| //-------------------------------------------------------------------- |
| EnumerationResult FileViewContentEnumerator::enumerateFolderContent() |
| { |
| EnumerationResult eResult = ERROR; |
| try |
| { |
| |
| Reference< XResultSet > xResultSet; |
| Sequence< OUString > aProps(12); |
| |
| aProps[0] = OUString::createFromAscii( "Title" ); |
| aProps[1] = OUString::createFromAscii( "Size" ); |
| aProps[2] = OUString::createFromAscii( "DateModified" ); |
| aProps[3] = OUString::createFromAscii( "DateCreated" ); |
| aProps[4] = OUString::createFromAscii( "IsFolder" ); |
| aProps[5] = OUString::createFromAscii( "TargetURL" ); |
| aProps[6] = OUString::createFromAscii( "IsHidden" ); |
| aProps[7] = OUString::createFromAscii( "IsVolume" ); |
| aProps[8] = OUString::createFromAscii( "IsRemote" ); |
| aProps[9] = OUString::createFromAscii( "IsRemoveable" ); |
| aProps[10] = OUString::createFromAscii( "IsFloppy" ); |
| aProps[11] = OUString::createFromAscii( "IsCompactDisc" ); |
| |
| Reference< XCommandEnvironment > xEnvironment; |
| try |
| { |
| FolderDescriptor aFolder; |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| aFolder = m_aFolder; |
| xEnvironment = m_xCommandEnv; |
| } |
| if ( !aFolder.aContent.get().is() ) |
| { |
| aFolder.aContent = ::ucbhelper::Content( aFolder.sURL, xEnvironment ); |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| m_aFolder.aContent = aFolder.aContent; |
| } |
| } |
| |
| Reference< XDynamicResultSet > xDynResultSet; |
| ResultSetInclude eInclude = INCLUDE_FOLDERS_AND_DOCUMENTS; |
| xDynResultSet = aFolder.aContent.createDynamicCursor( aProps, eInclude ); |
| |
| if ( xDynResultSet.is() ) |
| xResultSet = xDynResultSet->getStaticResultSet(); |
| } |
| catch( CommandAbortedException& ) |
| { |
| DBG_ERRORFILE( "createCursor: CommandAbortedException" ); |
| } |
| catch( Exception& ) |
| { |
| } |
| |
| bool bCancelled = false; |
| if ( xResultSet.is() ) |
| { |
| Reference< XRow > xRow( xResultSet, UNO_QUERY ); |
| Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY ); |
| |
| try |
| { |
| SortingData_Impl* pData; |
| DateTime aDT; |
| |
| while ( !bCancelled && xResultSet->next() ) |
| { |
| sal_Bool bIsHidden = xRow->getBoolean( ROW_IS_HIDDEN ); |
| // don't show hidden files |
| if ( !bIsHidden || xRow->wasNull() ) |
| { |
| pData = NULL; |
| |
| aDT = xRow->getTimestamp( ROW_DATE_MOD ); |
| sal_Bool bContainsDate = !xRow->wasNull(); |
| if ( !bContainsDate ) |
| { |
| aDT = xRow->getTimestamp( ROW_DATE_CREATE ); |
| bContainsDate = !xRow->wasNull(); |
| } |
| |
| OUString aContentURL = xContentAccess->queryContentIdentifierString(); |
| OUString aTargetURL = xRow->getString( ROW_TARGET_URL ); |
| sal_Bool bHasTargetURL = !xRow->wasNull() && aTargetURL.getLength() > 0; |
| |
| OUString sRealURL = bHasTargetURL ? aTargetURL : aContentURL; |
| |
| // check for restrictions |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| if ( m_pFilter && !m_pFilter->isUrlAllowed( sRealURL ) ) |
| continue; |
| |
| if ( /* m_rBlackList.hasElements() && */ URLOnBlackList ( sRealURL ) ) |
| continue; |
| } |
| |
| pData = new SortingData_Impl; |
| pData->maTargetURL = sRealURL; |
| |
| pData->mbIsFolder = xRow->getBoolean( ROW_IS_FOLDER ) && !xRow->wasNull(); |
| pData->mbIsVolume = xRow->getBoolean( ROW_IS_VOLUME ) && !xRow->wasNull(); |
| pData->mbIsRemote = xRow->getBoolean( ROW_IS_REMOTE ) && !xRow->wasNull(); |
| pData->mbIsRemoveable = xRow->getBoolean( ROW_IS_REMOVEABLE ) && !xRow->wasNull(); |
| pData->mbIsFloppy = xRow->getBoolean( ROW_IS_FLOPPY ) && !xRow->wasNull(); |
| pData->mbIsCompactDisc = xRow->getBoolean( ROW_IS_COMPACTDISC ) && !xRow->wasNull(); |
| pData->SetNewTitle( xRow->getString( ROW_TITLE ) ); |
| pData->maSize = xRow->getLong( ROW_SIZE ); |
| |
| if ( bHasTargetURL && |
| INetURLObject( aContentURL ).GetProtocol() == INET_PROT_VND_SUN_STAR_HIER ) |
| { |
| ::ucbhelper::Content aCnt( aTargetURL, xEnvironment ); |
| try |
| { |
| aCnt.getPropertyValue( OUString::createFromAscii( "Size" ) ) >>= pData->maSize; |
| aCnt.getPropertyValue( OUString::createFromAscii( "DateModified" ) ) >>= aDT; |
| } |
| catch (...) {} |
| } |
| |
| if ( bContainsDate ) |
| { |
| CONVERT_DATETIME( aDT, pData->maModDate ); |
| } |
| |
| if ( pData->mbIsFolder ) |
| { |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| ::svtools::VolumeInfo aVolInfo( pData->mbIsVolume, pData->mbIsRemote, |
| pData->mbIsRemoveable, pData->mbIsFloppy, |
| pData->mbIsCompactDisc ); |
| pData->maType = SvFileInformationManager::GetFolderDescription( aVolInfo ); |
| } |
| else |
| pData->maType = SvFileInformationManager::GetFileDescription( |
| INetURLObject( pData->maTargetURL ) ); |
| |
| // replace names on demand |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| if( m_pTranslator ) |
| { |
| OUString sNewTitle; |
| sal_Bool bTranslated = sal_False; |
| |
| if ( pData->mbIsFolder ) |
| bTranslated = m_pTranslator->GetTranslation( pData->GetTitle(), sNewTitle ); |
| else |
| bTranslated = implGetDocTitle( pData->maTargetURL, sNewTitle ); |
| |
| if ( bTranslated ) |
| pData->ChangeTitle( sNewTitle ); |
| } |
| } |
| |
| { |
| ::osl::MutexGuard aGuard( m_rContentMutex ); |
| m_rContent.push_back( pData ); |
| } |
| } |
| |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| bCancelled = m_bCancelled; |
| } |
| } |
| eResult = SUCCESS; |
| } |
| catch( CommandAbortedException& ) |
| { |
| DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an CommandAbortedException while enumerating!" ); |
| } |
| catch( Exception& ) |
| { |
| DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an exception other than CommandAbortedException while enumerating!" ); |
| } |
| } |
| } |
| catch( CommandAbortedException& ) |
| { |
| DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an CommandAbortedException!" ); |
| } |
| catch( Exception& ) |
| { |
| DBG_ERRORFILE( "FileViewContentEnumerator::enumerateFolderContent: caught an exception other than CommandAbortedException!" ); |
| } |
| |
| IEnumerationResultHandler* pHandler = NULL; |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| pHandler = m_pResultHandler; |
| if ( m_bCancelled ) |
| return ERROR; |
| } |
| |
| { |
| ::osl::MutexGuard aGuard( m_rContentMutex ); |
| if ( eResult != SUCCESS ) |
| // clear any "intermediate" and unfinished result |
| m_rContent.clear(); |
| } |
| |
| if ( pHandler ) |
| pHandler->enumerationDone( eResult ); |
| return eResult; |
| } |
| |
| //-------------------------------------------------------------------- |
| |
| sal_Bool FileViewContentEnumerator::URLOnBlackList ( const ::rtl::OUString& sRealURL ) |
| { |
| ::rtl::OUString entryName = sRealURL.copy( sRealURL.lastIndexOf( rtl::OUString::createFromAscii("/")) +1 ); |
| |
| for (int i = 0; i < m_rBlackList.getLength() ; i++) |
| { |
| if ( entryName.equals( m_rBlackList[i] ) ) |
| return true; |
| } |
| |
| return false; |
| } |
| |
| //-------------------------------------------------------------------- |
| sal_Bool FileViewContentEnumerator::implGetDocTitle( const OUString& _rTargetURL, OUString& _rRet ) const |
| { |
| sal_Bool bRet = sal_False; |
| |
| try |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| if( !m_xDocInfo.is() ) |
| { |
| m_xDocInfo = m_xDocInfo.query( |
| ::comphelper::getProcessServiceFactory()->createInstance( |
| String( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.StandaloneDocumentInfo") ) |
| ) |
| ); |
| } |
| |
| DBG_ASSERT( m_xDocInfo.is(), "FileViewContentEnumerator::implGetDocTitle: no DocumentProperties service!" ); |
| if ( !m_xDocInfo.is() ) |
| return sal_False; |
| |
| m_xDocInfo->loadFromURL( _rTargetURL ); |
| Reference< XPropertySet > xPropSet( m_xDocInfo, UNO_QUERY ); |
| |
| Any aAny = xPropSet->getPropertyValue( OUString::createFromAscii( "Title" ) ); |
| |
| OUString sTitle; |
| if ( ( aAny >>= sTitle ) && sTitle.getLength() > 0 ) |
| { |
| _rRet = sTitle; |
| bRet = sal_True; |
| } |
| } |
| catch ( const Exception& ) |
| { |
| } |
| |
| return bRet; |
| } |
| |
| //-------------------------------------------------------------------- |
| void SAL_CALL FileViewContentEnumerator::run() |
| { |
| enumerateFolderContent(); |
| } |
| |
| //-------------------------------------------------------------------- |
| void SAL_CALL FileViewContentEnumerator::onTerminated() |
| { |
| release(); |
| } |
| |
| //........................................................................ |
| } // namespace svt |
| //........................................................................ |
| |