324 lines
13 KiB
C++
324 lines
13 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* 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 .
|
|
*/
|
|
|
|
#include "contentenumeration.hxx"
|
|
#include <svtools/imagemgr.hxx>
|
|
|
|
#include <com/sun/star/sdbc/XResultSet.hpp>
|
|
#include <com/sun/star/sdbc/XRow.hpp>
|
|
#include <com/sun/star/ucb/CommandAbortedException.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/document/DocumentProperties.hpp>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <comphelper/sequence.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <osl/mutex.hxx>
|
|
#include <osl/diagnose.h>
|
|
#include <comphelper/diagnose_ex.hxx>
|
|
#include <tools/urlobj.hxx>
|
|
|
|
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_REMOVABLE 10
|
|
#define ROW_IS_FLOPPY 11
|
|
#define ROW_IS_COMPACTDISC 12
|
|
|
|
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::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 ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
|
|
|
|
|
|
//= FileViewContentEnumerator
|
|
|
|
|
|
FileViewContentEnumerator::FileViewContentEnumerator(
|
|
const Reference< XCommandEnvironment >& _rxCommandEnv,
|
|
ContentData& _rContentToFill, ::osl::Mutex& _rContentMutex )
|
|
:Thread ( "FileViewContentEnumerator" )
|
|
,m_rContent ( _rContentToFill )
|
|
,m_rContentMutex ( _rContentMutex )
|
|
,m_xCommandEnv ( _rxCommandEnv )
|
|
,m_pResultHandler ( nullptr )
|
|
,m_bCancelled ( false )
|
|
{
|
|
}
|
|
|
|
|
|
FileViewContentEnumerator::~FileViewContentEnumerator()
|
|
{
|
|
}
|
|
|
|
|
|
void FileViewContentEnumerator::cancel()
|
|
{
|
|
std::unique_lock aGuard( m_aMutex );
|
|
m_bCancelled = true;
|
|
m_pResultHandler = nullptr;
|
|
m_aFolder.aContent = ::ucbhelper::Content();
|
|
m_aFolder.sURL.clear();
|
|
}
|
|
|
|
|
|
EnumerationResult FileViewContentEnumerator::enumerateFolderContentSync(
|
|
const FolderDescriptor& _rFolder,
|
|
const css::uno::Sequence< OUString >& rDenyList )
|
|
{
|
|
{
|
|
std::unique_lock aGuard( m_aMutex );
|
|
m_aFolder = _rFolder;
|
|
m_pResultHandler = nullptr;
|
|
m_rDenyList = rDenyList;
|
|
}
|
|
return enumerateFolderContent();
|
|
}
|
|
|
|
|
|
void FileViewContentEnumerator::enumerateFolderContent(
|
|
const FolderDescriptor& _rFolder, IEnumerationResultHandler* _pResultHandler )
|
|
{
|
|
std::unique_lock aGuard( m_aMutex );
|
|
m_aFolder = _rFolder;
|
|
m_pResultHandler = _pResultHandler;
|
|
|
|
OSL_ENSURE( m_aFolder.aContent.get().is() || !m_aFolder.sURL.isEmpty(),
|
|
"FileViewContentEnumerator::enumerateFolderContent: invalid folder descriptor!" );
|
|
|
|
launch();
|
|
//TODO: a protocol is missing how to join with the launched thread
|
|
// before exit(3), to ensure the thread is no longer relying on any
|
|
// infrastructure while that infrastructure is being shut down in
|
|
// atexit handlers
|
|
}
|
|
|
|
|
|
EnumerationResult FileViewContentEnumerator::enumerateFolderContent()
|
|
{
|
|
EnumerationResult eResult = EnumerationResult::ERROR;
|
|
try
|
|
{
|
|
|
|
Reference< XResultSet > xResultSet;
|
|
Sequence< OUString > aProps{ u"Title"_ustr,
|
|
u"Size"_ustr,
|
|
u"DateModified"_ustr,
|
|
u"DateCreated"_ustr,
|
|
u"IsFolder"_ustr,
|
|
u"TargetURL"_ustr,
|
|
u"IsHidden"_ustr,
|
|
u"IsVolume"_ustr,
|
|
u"IsRemote"_ustr,
|
|
u"IsRemoveable"_ustr,
|
|
u"IsFloppy"_ustr,
|
|
u"IsCompactDisc"_ustr };
|
|
|
|
Reference< XCommandEnvironment > xEnvironment;
|
|
try
|
|
{
|
|
FolderDescriptor aFolder;
|
|
{
|
|
std::unique_lock aGuard( m_aMutex );
|
|
aFolder = m_aFolder;
|
|
xEnvironment = m_xCommandEnv;
|
|
}
|
|
if ( !aFolder.aContent.get().is() )
|
|
{
|
|
aFolder.aContent = ::ucbhelper::Content( aFolder.sURL, xEnvironment, comphelper::getProcessComponentContext() );
|
|
{
|
|
std::unique_lock aGuard( m_aMutex );
|
|
m_aFolder.aContent = aFolder.aContent;
|
|
}
|
|
}
|
|
|
|
Reference< XDynamicResultSet > xDynResultSet = aFolder.aContent.createDynamicCursor( aProps, INCLUDE_FOLDERS_AND_DOCUMENTS );
|
|
|
|
if ( xDynResultSet.is() )
|
|
xResultSet = xDynResultSet->getStaticResultSet();
|
|
}
|
|
catch( CommandAbortedException& )
|
|
{
|
|
TOOLS_WARN_EXCEPTION( "svtools.contnr", "");
|
|
}
|
|
catch( Exception& )
|
|
{
|
|
}
|
|
|
|
if ( xResultSet.is() )
|
|
{
|
|
Reference< XRow > xRow( xResultSet, UNO_QUERY );
|
|
Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
|
|
|
|
try
|
|
{
|
|
DateTime aDT;
|
|
|
|
bool bCancelled = false;
|
|
while ( !bCancelled && xResultSet->next() )
|
|
{
|
|
bool bIsHidden = xRow->getBoolean( ROW_IS_HIDDEN );
|
|
// don't show hidden files
|
|
if ( !bIsHidden || xRow->wasNull() )
|
|
{
|
|
aDT = xRow->getTimestamp( ROW_DATE_MOD );
|
|
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 );
|
|
bool bHasTargetURL = !xRow->wasNull() && !aTargetURL.isEmpty();
|
|
|
|
OUString sRealURL = bHasTargetURL ? aTargetURL : aContentURL;
|
|
|
|
// check for restrictions
|
|
{
|
|
std::unique_lock aGuard( m_aMutex );
|
|
if ( /* m_rDenyList.hasElements() && */ URLOnDenyList ( sRealURL ) )
|
|
continue;
|
|
}
|
|
|
|
std::unique_ptr<SortingData_Impl> 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_REMOVABLE ) && !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() == INetProtocol::VndSunStarHier )
|
|
{
|
|
::ucbhelper::Content aCnt( aTargetURL, xEnvironment, comphelper::getProcessComponentContext() );
|
|
try
|
|
{
|
|
aCnt.getPropertyValue(u"Size"_ustr) >>= pData->maSize;
|
|
aCnt.getPropertyValue(u"DateModified"_ustr) >>= aDT;
|
|
}
|
|
catch (...) {}
|
|
}
|
|
|
|
if ( bContainsDate )
|
|
{
|
|
pData->maModDate = ::DateTime( aDT );
|
|
}
|
|
|
|
if ( pData->mbIsFolder )
|
|
{
|
|
::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 ) );
|
|
|
|
{
|
|
::osl::MutexGuard aGuard( m_rContentMutex );
|
|
m_rContent.push_back( std::move(pData) );
|
|
}
|
|
}
|
|
|
|
{
|
|
std::unique_lock aGuard( m_aMutex );
|
|
bCancelled = m_bCancelled;
|
|
}
|
|
}
|
|
eResult = EnumerationResult::SUCCESS;
|
|
}
|
|
catch( Exception const & )
|
|
{
|
|
TOOLS_WARN_EXCEPTION( "svtools.contnr", "FileViewContentEnumerator::enumerateFolderContent: caught an exception while enumerating");
|
|
}
|
|
}
|
|
}
|
|
catch( Exception const & )
|
|
{
|
|
TOOLS_WARN_EXCEPTION( "svtools.contnr", "FileViewContentEnumerator::enumerateFolderContent" );
|
|
}
|
|
|
|
IEnumerationResultHandler* pHandler = nullptr;
|
|
{
|
|
std::unique_lock aGuard( m_aMutex );
|
|
pHandler = m_pResultHandler;
|
|
if ( m_bCancelled )
|
|
return EnumerationResult::ERROR;
|
|
}
|
|
|
|
{
|
|
::osl::MutexGuard aGuard( m_rContentMutex );
|
|
if ( eResult != EnumerationResult::SUCCESS )
|
|
// clear any "intermediate" and unfinished result
|
|
m_rContent.clear();
|
|
}
|
|
|
|
if ( pHandler )
|
|
pHandler->enumerationDone( eResult );
|
|
return eResult;
|
|
}
|
|
|
|
|
|
bool FileViewContentEnumerator::URLOnDenyList ( std::u16string_view sRealURL )
|
|
{
|
|
std::u16string_view::size_type pos = sRealURL.rfind('/');
|
|
pos = (pos != std::u16string_view::npos) ? pos + 1 : 0;
|
|
std::u16string_view entryName = sRealURL.substr(pos);
|
|
|
|
return comphelper::findValue(m_rDenyList, entryName) != -1;
|
|
}
|
|
|
|
|
|
void FileViewContentEnumerator::execute()
|
|
{
|
|
enumerateFolderContent();
|
|
}
|
|
|
|
|
|
} // namespace svt
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|