blob: 8190595d9450ddaf752ab091256a7ab83f940b20 [file] [log] [blame]
/**************************************************************
*
* 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_framework.hxx"
//_________________________________________________________________________________________________________________
// my own includes
//_________________________________________________________________________________________________________________
#include <classes/droptargetlistener.hxx>
#include <threadhelp/readguard.hxx>
#include <threadhelp/writeguard.hxx>
#include <targets.h>
#include <services.h>
//_________________________________________________________________________________________________________________
// interface includes
//_________________________________________________________________________________________________________________
#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
#include <com/sun/star/frame/XDispatch.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/util/XURLTransformer.hpp>
//_________________________________________________________________________________________________________________
// includes of other projects
//_________________________________________________________________________________________________________________
#include <svtools/transfer.hxx>
#include <unotools/localfilehelper.hxx>
#include <sot/filelist.hxx>
#include <osl/file.hxx>
#include <vcl/svapp.hxx>
//_________________________________________________________________________________________________________________
// namespace
//_________________________________________________________________________________________________________________
namespace framework
{
DropTargetListener::DropTargetListener( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory,
const css::uno::Reference< css::frame::XFrame >& xFrame )
: ThreadHelpBase ( &Application::GetSolarMutex() )
, m_xFactory ( xFactory )
, m_xTargetFrame ( xFrame )
, m_pFormats ( new DataFlavorExVector )
{
}
// -----------------------------------------------------------------------------
DropTargetListener::~DropTargetListener()
{
m_xTargetFrame = css::uno::WeakReference< css::frame::XFrame >();
m_xFactory = css::uno::Reference< css::lang::XMultiServiceFactory >();
delete m_pFormats;
m_pFormats = NULL;
}
// -----------------------------------------------------------------------------
void SAL_CALL DropTargetListener::disposing( const css::lang::EventObject& ) throw( css::uno::RuntimeException )
{
m_xTargetFrame = css::uno::WeakReference< css::frame::XFrame >();
m_xFactory = css::uno::Reference< css::lang::XMultiServiceFactory >();
}
// -----------------------------------------------------------------------------
void SAL_CALL DropTargetListener::drop( const css::datatransfer::dnd::DropTargetDropEvent& dtde ) throw( css::uno::RuntimeException )
{
const sal_Int8 nAction = dtde.DropAction;
try
{
if ( css::datatransfer::dnd::DNDConstants::ACTION_NONE != nAction )
{
TransferableDataHelper aHelper( dtde.Transferable );
sal_Bool bFormatFound = sal_False;
FileList aFileList;
// at first check filelist format
if ( aHelper.GetFileList( SOT_FORMAT_FILE_LIST, aFileList ) )
{
sal_uLong i, nCount = aFileList.Count();
for ( i = 0; i < nCount; ++i )
implts_OpenFile( aFileList.GetFile(i) );
bFormatFound = sal_True;
}
// then, if necessary, the file format
String aFilePath;
if ( !bFormatFound && aHelper.GetString( SOT_FORMAT_FILE, aFilePath ) )
implts_OpenFile( aFilePath );
}
dtde.Context->dropComplete( css::datatransfer::dnd::DNDConstants::ACTION_NONE != nAction );
}
catch( const ::com::sun::star::uno::Exception& )
{
}
}
// -----------------------------------------------------------------------------
void SAL_CALL DropTargetListener::dragEnter( const css::datatransfer::dnd::DropTargetDragEnterEvent& dtdee ) throw( css::uno::RuntimeException )
{
try
{
implts_BeginDrag( dtdee.SupportedDataFlavors );
}
catch( const ::com::sun::star::uno::Exception& )
{
}
dragOver( dtdee );
}
// -----------------------------------------------------------------------------
void SAL_CALL DropTargetListener::dragExit( const css::datatransfer::dnd::DropTargetEvent& ) throw( css::uno::RuntimeException )
{
try
{
implts_EndDrag();
}
catch( const ::com::sun::star::uno::Exception& )
{
}
}
// -----------------------------------------------------------------------------
void SAL_CALL DropTargetListener::dragOver( const css::datatransfer::dnd::DropTargetDragEvent& dtde ) throw( css::uno::RuntimeException )
{
try
{
sal_Bool bAccept = ( implts_IsDropFormatSupported( SOT_FORMAT_FILE ) ||
implts_IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) );
if ( !bAccept )
dtde.Context->rejectDrag();
else
dtde.Context->acceptDrag( css::datatransfer::dnd::DNDConstants::ACTION_COPY );
}
catch( const ::com::sun::star::uno::Exception& )
{
}
}
// -----------------------------------------------------------------------------
void SAL_CALL DropTargetListener::dropActionChanged( const css::datatransfer::dnd::DropTargetDragEvent& ) throw( css::uno::RuntimeException )
{
}
void DropTargetListener::implts_BeginDrag( const css::uno::Sequence< css::datatransfer::DataFlavor >& rSupportedDataFlavors )
{
/* SAFE { */
WriteGuard aWriteLock(m_aLock);
m_pFormats->clear();
TransferableDataHelper::FillDataFlavorExVector(rSupportedDataFlavors,*m_pFormats);
aWriteLock.unlock();
/* } SAFE */
}
void DropTargetListener::implts_EndDrag()
{
/* SAFE { */
WriteGuard aWriteLock(m_aLock);
m_pFormats->clear();
aWriteLock.unlock();
/* } SAFE */
}
sal_Bool DropTargetListener::implts_IsDropFormatSupported( SotFormatStringId nFormat )
{
/* SAFE { */
ReadGuard aReadLock(m_aLock);
DataFlavorExVector::iterator aIter( m_pFormats->begin() ), aEnd( m_pFormats->end() );
sal_Bool bRet = sal_False;
while ( aIter != aEnd )
{
if ( nFormat == (*aIter++).mnSotId )
{
bRet = sal_True;
aIter = aEnd;
}
}
aReadLock.unlock();
/* } SAFE */
return bRet;
}
void DropTargetListener::implts_OpenFile( const String& rFilePath )
{
String aFileURL;
if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFilePath, aFileURL ) )
aFileURL = rFilePath;
::osl::FileStatus aStatus( FileStatusMask_FileURL );
::osl::DirectoryItem aItem;
if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
aFileURL = aStatus.getFileURL();
// open file
/* SAFE { */
ReadGuard aReadLock(m_aLock);
css::uno::Reference< css::frame::XFrame > xTargetFrame( m_xTargetFrame.get() , css::uno::UNO_QUERY );
css::uno::Reference< css::util::XURLTransformer > xParser ( m_xFactory->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY );
aReadLock.unlock();
/* } SAFE */
if (xTargetFrame.is() && xParser.is())
{
css::util::URL aURL;
aURL.Complete = aFileURL;
xParser->parseStrict(aURL);
css::uno::Reference < css::frame::XDispatchProvider > xProvider( xTargetFrame, css::uno::UNO_QUERY );
css::uno::Reference< css::frame::XDispatch > xDispatcher = xProvider->queryDispatch( aURL, SPECIALTARGET_DEFAULT, 0 );
if ( xDispatcher.is() )
xDispatcher->dispatch( aURL, css::uno::Sequence < css::beans::PropertyValue >() );
}
}
}