xref: /AOO41X/main/framework/source/classes/droptargetlistener.cxx (revision 6d739b60ff8f4ed2134ae1442e284f9da90334b4)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26 
27 //_________________________________________________________________________________________________________________
28 //  my own includes
29 //_________________________________________________________________________________________________________________
30 #include <classes/droptargetlistener.hxx>
31 #include <threadhelp/readguard.hxx>
32 #include <threadhelp/writeguard.hxx>
33 #include <targets.h>
34 #include <services.h>
35 
36 //_________________________________________________________________________________________________________________
37 //  interface includes
38 //_________________________________________________________________________________________________________________
39 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
40 #include <com/sun/star/frame/XDispatch.hpp>
41 #include <com/sun/star/frame/XDispatchProvider.hpp>
42 #include <com/sun/star/beans/PropertyValue.hpp>
43 #include <com/sun/star/util/XURLTransformer.hpp>
44 
45 //_________________________________________________________________________________________________________________
46 //  includes of other projects
47 //_________________________________________________________________________________________________________________
48 #include <svtools/transfer.hxx>
49 #include <unotools/localfilehelper.hxx>
50 #include <sot/filelist.hxx>
51 
52 #include <osl/file.hxx>
53 #include <vcl/svapp.hxx>
54 
55 //_________________________________________________________________________________________________________________
56 //  namespace
57 //_________________________________________________________________________________________________________________
58 
59 namespace framework
60 {
61 
DropTargetListener(const css::uno::Reference<css::lang::XMultiServiceFactory> & xFactory,const css::uno::Reference<css::frame::XFrame> & xFrame)62 DropTargetListener::DropTargetListener( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory,
63                                         const css::uno::Reference< css::frame::XFrame >&              xFrame  )
64         : ThreadHelpBase  ( &Application::GetSolarMutex() )
65         , m_xFactory      ( xFactory                      )
66         , m_xTargetFrame  ( xFrame                        )
67         , m_pFormats      ( new DataFlavorExVector        )
68 {
69 }
70 
71 // -----------------------------------------------------------------------------
72 
~DropTargetListener()73 DropTargetListener::~DropTargetListener()
74 {
75     m_xTargetFrame = css::uno::WeakReference< css::frame::XFrame >();
76     m_xFactory     = css::uno::Reference< css::lang::XMultiServiceFactory >();
77     delete m_pFormats;
78     m_pFormats = NULL;
79 }
80 
81 // -----------------------------------------------------------------------------
82 
disposing(const css::lang::EventObject &)83 void SAL_CALL DropTargetListener::disposing( const css::lang::EventObject& ) throw( css::uno::RuntimeException )
84 {
85     m_xTargetFrame = css::uno::WeakReference< css::frame::XFrame >();
86     m_xFactory     = css::uno::Reference< css::lang::XMultiServiceFactory >();
87 }
88 
89 // -----------------------------------------------------------------------------
90 
drop(const css::datatransfer::dnd::DropTargetDropEvent & dtde)91 void SAL_CALL DropTargetListener::drop( const css::datatransfer::dnd::DropTargetDropEvent& dtde ) throw( css::uno::RuntimeException )
92 {
93     const sal_Int8 nAction = dtde.DropAction;
94 
95     try
96     {
97         if ( css::datatransfer::dnd::DNDConstants::ACTION_NONE != nAction )
98         {
99             TransferableDataHelper aHelper( dtde.Transferable );
100             sal_Bool bFormatFound = sal_False;
101             FileList aFileList;
102 
103             // at first check filelist format
104             if ( aHelper.GetFileList( SOT_FORMAT_FILE_LIST, aFileList ) )
105             {
106                 sal_uLong i, nCount = aFileList.Count();
107                 for ( i = 0; i < nCount; ++i )
108                     implts_OpenFile( aFileList.GetFile(i) );
109                 bFormatFound = sal_True;
110             }
111 
112             // then, if necessary, the file format
113             String aFilePath;
114             if ( !bFormatFound && aHelper.GetString( SOT_FORMAT_FILE, aFilePath ) )
115                 implts_OpenFile( aFilePath );
116         }
117         dtde.Context->dropComplete( css::datatransfer::dnd::DNDConstants::ACTION_NONE != nAction );
118     }
119     catch( const ::com::sun::star::uno::Exception& )
120     {
121     }
122 }
123 
124 // -----------------------------------------------------------------------------
125 
dragEnter(const css::datatransfer::dnd::DropTargetDragEnterEvent & dtdee)126 void SAL_CALL DropTargetListener::dragEnter( const css::datatransfer::dnd::DropTargetDragEnterEvent& dtdee ) throw( css::uno::RuntimeException )
127 {
128     try
129     {
130         implts_BeginDrag( dtdee.SupportedDataFlavors );
131     }
132     catch( const ::com::sun::star::uno::Exception& )
133     {
134     }
135 
136     dragOver( dtdee );
137 }
138 
139 // -----------------------------------------------------------------------------
140 
dragExit(const css::datatransfer::dnd::DropTargetEvent &)141 void SAL_CALL DropTargetListener::dragExit( const css::datatransfer::dnd::DropTargetEvent& ) throw( css::uno::RuntimeException )
142 {
143     try
144     {
145         implts_EndDrag();
146     }
147     catch( const ::com::sun::star::uno::Exception& )
148     {
149     }
150 }
151 
152 // -----------------------------------------------------------------------------
153 
dragOver(const css::datatransfer::dnd::DropTargetDragEvent & dtde)154 void SAL_CALL DropTargetListener::dragOver( const css::datatransfer::dnd::DropTargetDragEvent& dtde ) throw( css::uno::RuntimeException )
155 {
156     try
157     {
158         sal_Bool bAccept = ( implts_IsDropFormatSupported( SOT_FORMAT_FILE ) ||
159                              implts_IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) );
160 
161         if ( !bAccept )
162             dtde.Context->rejectDrag();
163         else
164             dtde.Context->acceptDrag( css::datatransfer::dnd::DNDConstants::ACTION_COPY );
165     }
166     catch( const ::com::sun::star::uno::Exception& )
167     {
168     }
169 }
170 
171 // -----------------------------------------------------------------------------
172 
dropActionChanged(const css::datatransfer::dnd::DropTargetDragEvent &)173 void SAL_CALL DropTargetListener::dropActionChanged( const css::datatransfer::dnd::DropTargetDragEvent& ) throw( css::uno::RuntimeException )
174 {
175 }
176 
implts_BeginDrag(const css::uno::Sequence<css::datatransfer::DataFlavor> & rSupportedDataFlavors)177 void DropTargetListener::implts_BeginDrag( const css::uno::Sequence< css::datatransfer::DataFlavor >& rSupportedDataFlavors )
178 {
179     /* SAFE { */
180     WriteGuard aWriteLock(m_aLock);
181     m_pFormats->clear();
182     TransferableDataHelper::FillDataFlavorExVector(rSupportedDataFlavors,*m_pFormats);
183     aWriteLock.unlock();
184     /* } SAFE */
185 }
186 
implts_EndDrag()187 void DropTargetListener::implts_EndDrag()
188 {
189     /* SAFE { */
190     WriteGuard aWriteLock(m_aLock);
191     m_pFormats->clear();
192     aWriteLock.unlock();
193     /* } SAFE */
194 }
195 
implts_IsDropFormatSupported(SotFormatStringId nFormat)196 sal_Bool DropTargetListener::implts_IsDropFormatSupported( SotFormatStringId nFormat )
197 {
198     /* SAFE { */
199     ReadGuard aReadLock(m_aLock);
200     DataFlavorExVector::iterator aIter( m_pFormats->begin() ), aEnd( m_pFormats->end() );
201     sal_Bool bRet = sal_False;
202 
203     while ( aIter != aEnd )
204     {
205         if ( nFormat == (*aIter++).mnSotId )
206         {
207             bRet = sal_True;
208             aIter = aEnd;
209         }
210     }
211     aReadLock.unlock();
212     /* } SAFE */
213 
214     return bRet;
215 }
216 
implts_OpenFile(const String & rFilePath)217 void DropTargetListener::implts_OpenFile( const String& rFilePath )
218 {
219     String aFileURL;
220     if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFilePath, aFileURL ) )
221         aFileURL = rFilePath;
222 
223     ::osl::FileStatus aStatus( FileStatusMask_FileURL );
224     ::osl::DirectoryItem aItem;
225     if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
226         ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
227             aFileURL = aStatus.getFileURL();
228 
229     // open file
230     /* SAFE { */
231     ReadGuard aReadLock(m_aLock);
232     css::uno::Reference< css::frame::XFrame >         xTargetFrame( m_xTargetFrame.get()                                  , css::uno::UNO_QUERY );
233     css::uno::Reference< css::util::XURLTransformer > xParser     ( m_xFactory->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY );
234     aReadLock.unlock();
235     /* } SAFE */
236     if (xTargetFrame.is() && xParser.is())
237     {
238         css::util::URL aURL;
239         aURL.Complete = aFileURL;
240         xParser->parseStrict(aURL);
241 
242         css::uno::Reference < css::frame::XDispatchProvider > xProvider( xTargetFrame, css::uno::UNO_QUERY );
243         css::uno::Reference< css::frame::XDispatch > xDispatcher = xProvider->queryDispatch( aURL, SPECIALTARGET_DEFAULT, 0 );
244         if ( xDispatcher.is() )
245             xDispatcher->dispatch( aURL, css::uno::Sequence < css::beans::PropertyValue >() );
246     }
247 }
248 
249 }
250 
251