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