Update ooo320-m1
[ooovba.git] / vcl / aqua / source / dtrans / aqua_clipboard.cxx
blob51e946d5941666920f0ec13bff9872663a5de6b6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: aqua_clipboard.cxx,v $
10 * $Revision: 1.8 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
33 #include "aqua_clipboard.hxx"
35 #include "DataFlavorMapping.hxx"
36 #include "OSXTransferable.hxx"
38 #include "vcl/unohelp.hxx"
40 #include "comphelper/makesequence.hxx"
42 #include <boost/assert.hpp>
44 using namespace com::sun::star::datatransfer;
45 using namespace com::sun::star::datatransfer::clipboard;
46 using namespace com::sun::star::lang;
47 using namespace com::sun::star::uno;
48 using namespace cppu;
49 using namespace osl;
50 using namespace rtl;
51 using namespace std;
52 using namespace comphelper;
55 @implementation EventListener;
57 -(EventListener*)initWithAquaClipboard: (AquaClipboard*) pcb
59 self = [super init];
61 if (self)
62 pAquaClipboard = pcb;
64 return self;
67 -(void)pasteboard:(NSPasteboard*)sender provideDataForType:(NSString*)type
69 if( pAquaClipboard )
70 pAquaClipboard->provideDataForType(sender, type);
73 -(void)applicationDidBecomeActive:(NSNotification*)aNotification
75 if( pAquaClipboard )
76 pAquaClipboard->applicationDidBecomeActive(aNotification);
79 -(void)disposing
81 pAquaClipboard = NULL;
84 @end
87 OUString clipboard_getImplementationName()
89 return OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.datatransfer.clipboard.AquaClipboard"));
92 Sequence<OUString> clipboard_getSupportedServiceNames()
94 return makeSequence(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.datatransfer.clipboard.SystemClipboard")));
98 AquaClipboard::AquaClipboard(NSPasteboard* pasteboard, bool bUseSystemPasteboard) :
99 WeakComponentImplHelper4<XClipboardEx, XClipboardNotifier, XFlushableClipboard, XServiceInfo>(m_aMutex),
100 mIsSystemPasteboard(bUseSystemPasteboard)
102 Reference<XMultiServiceFactory> mrServiceMgr = vcl::unohelper::GetMultiServiceFactory();
104 mrXMimeCntFactory = Reference<XMimeContentTypeFactory>(mrServiceMgr->createInstance(
105 OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.datatransfer.MimeContentTypeFactory"))), UNO_QUERY);
107 if (!mrXMimeCntFactory.is())
109 throw RuntimeException(OUString(
110 RTL_CONSTASCII_USTRINGPARAM("AquaClipboard: Cannot create com.sun.star.datatransfer.MimeContentTypeFactory")),
111 static_cast<XClipboardEx*>(this));
114 mpDataFlavorMapper = DataFlavorMapperPtr_t(new DataFlavorMapper());
116 if (pasteboard != NULL)
118 mPasteboard = pasteboard;
119 mIsSystemPasteboard = false;
121 else
123 mPasteboard = bUseSystemPasteboard ? [NSPasteboard generalPasteboard] :
124 [NSPasteboard pasteboardWithName: NSDragPboard];
126 if (mPasteboard == nil)
128 throw RuntimeException(OUString(
129 RTL_CONSTASCII_USTRINGPARAM("AquaClipboard: Cannot create Cocoa pasteboard")),
130 static_cast<XClipboardEx*>(this));
134 [mPasteboard retain];
136 mEventListener = [[EventListener alloc] initWithAquaClipboard: this];
138 if (mEventListener == nil)
140 [mPasteboard release];
142 throw RuntimeException(
143 OUString(RTL_CONSTASCII_USTRINGPARAM("AquaClipboard: Cannot create pasteboard change listener")),
144 static_cast<XClipboardEx*>(this));
147 if (mIsSystemPasteboard)
149 NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];
151 [notificationCenter addObserver: mEventListener
152 selector: @selector(applicationDidBecomeActive:)
153 name: @"NSApplicationDidBecomeActiveNotification"
154 object: [NSApplication sharedApplication]];
157 mPasteboardChangeCount = [mPasteboard changeCount];
161 AquaClipboard::~AquaClipboard()
163 if (mIsSystemPasteboard)
165 [[NSNotificationCenter defaultCenter] removeObserver: mEventListener];
168 [mEventListener disposing];
169 [mEventListener release];
170 [mPasteboard release];
174 Reference<XTransferable> SAL_CALL AquaClipboard::getContents() throw(RuntimeException)
176 MutexGuard aGuard(m_aMutex);
178 // Shortcut: If we are clipboard owner already we don't need
179 // to drag the data through the system clipboard
180 if (mXClipboardContent.is())
182 return mXClipboardContent;
185 return Reference<XTransferable>(new OSXTransferable(mrXMimeCntFactory,
186 mpDataFlavorMapper,
187 mPasteboard));
191 void SAL_CALL AquaClipboard::setContents(const Reference<XTransferable>& xTransferable,
192 const Reference<XClipboardOwner>& xClipboardOwner)
193 throw( RuntimeException )
195 ClearableMutexGuard aGuard(m_aMutex);
197 Reference<XClipboardOwner> oldOwner(mXClipboardOwner);
198 mXClipboardOwner = xClipboardOwner;
200 Reference<XTransferable> oldContent(mXClipboardContent);
201 mXClipboardContent = xTransferable;
203 NSArray* types = mXClipboardContent.is() ?
204 mpDataFlavorMapper->flavorSequenceToTypesArray(mXClipboardContent->getTransferDataFlavors()) :
205 [NSArray array];
206 mPasteboardChangeCount = [mPasteboard declareTypes: types owner: mEventListener];
208 // if we are already the owner of the clipboard
209 // then fire lost ownership event
210 if (oldOwner.is())
212 fireLostClipboardOwnershipEvent(oldOwner, oldContent);
215 fireClipboardChangedEvent();
219 OUString SAL_CALL AquaClipboard::getName() throw( RuntimeException )
221 return OUString();
225 sal_Int8 SAL_CALL AquaClipboard::getRenderingCapabilities() throw( RuntimeException )
227 return 0;
231 void SAL_CALL AquaClipboard::addClipboardListener(const Reference< XClipboardListener >& listener)
232 throw( RuntimeException )
234 MutexGuard aGuard(m_aMutex);
236 if (!listener.is())
237 throw IllegalArgumentException(OUString(RTL_CONSTASCII_USTRINGPARAM("empty reference")),
238 static_cast<XClipboardEx*>(this), 1);
240 mClipboardListeners.push_back(listener);
244 void SAL_CALL AquaClipboard::removeClipboardListener(const Reference< XClipboardListener >& listener)
245 throw( RuntimeException )
247 MutexGuard aGuard(m_aMutex);
249 if (!listener.is())
250 throw IllegalArgumentException(OUString(RTL_CONSTASCII_USTRINGPARAM("empty reference")),
251 static_cast<XClipboardEx*>(this), 1);
253 mClipboardListeners.remove(listener);
257 void AquaClipboard::applicationDidBecomeActive(NSNotification* aNotification)
259 MutexGuard aGuard(m_aMutex);
261 int currentPboardChgCount = [mPasteboard changeCount];
263 if (currentPboardChgCount != mPasteboardChangeCount)
265 mPasteboardChangeCount = currentPboardChgCount;
267 // Clear clipboard content and owner and send lostOwnership
268 // notification to the old clipboard owner as well as
269 // ClipboardChanged notification to any clipboard listener
270 Reference<XClipboardOwner> oldOwner(mXClipboardOwner);
271 mXClipboardOwner = Reference<XClipboardOwner>();
273 Reference<XTransferable> oldContent(mXClipboardContent);
274 mXClipboardContent = Reference<XTransferable>();
276 if (oldOwner.is())
278 fireLostClipboardOwnershipEvent(oldOwner, oldContent);
281 fireClipboardChangedEvent();
286 void AquaClipboard::fireClipboardChangedEvent()
288 ClearableMutexGuard aGuard(m_aMutex);
290 list<Reference< XClipboardListener > > listeners(mClipboardListeners);
291 ClipboardEvent aEvent;
293 if (listeners.begin() != listeners.end())
295 aEvent = ClipboardEvent(static_cast<OWeakObject*>(this), getContents());
298 aGuard.clear();
300 while (listeners.begin() != listeners.end())
302 if (listeners.front().is())
304 try { listeners.front()->changedContents(aEvent); }
305 catch (RuntimeException&) { }
307 listeners.pop_front();
312 void AquaClipboard::fireLostClipboardOwnershipEvent(Reference<XClipboardOwner> oldOwner, Reference<XTransferable> oldContent)
314 BOOST_ASSERT(oldOwner.is());
316 try { oldOwner->lostOwnership(static_cast<XClipboardEx*>(this), oldContent); }
317 catch(RuntimeException&) { }
321 void AquaClipboard::provideDataForType(NSPasteboard* sender, NSString* type)
323 DataProviderPtr_t dp = mpDataFlavorMapper->getDataProvider(type, mXClipboardContent);
324 NSData* pBoardData = NULL;
326 if (dp.get() != NULL)
328 pBoardData = (NSData*)dp->getSystemData();
329 [sender setData: pBoardData forType: type];
334 //------------------------------------------------
335 // XFlushableClipboard
336 //------------------------------------------------
338 void SAL_CALL AquaClipboard::flushClipboard()
339 throw(RuntimeException)
341 if (mXClipboardContent.is())
343 Sequence<DataFlavor> flavorList = mXClipboardContent->getTransferDataFlavors();
344 sal_uInt32 nFlavors = flavorList.getLength();
346 for (sal_uInt32 i = 0; i < nFlavors; i++)
348 NSString* sysType = mpDataFlavorMapper->openOfficeToSystemFlavor(flavorList[i]);
350 if (sysType != NULL)
352 provideDataForType(mPasteboard, sysType);
359 NSPasteboard* AquaClipboard::getPasteboard() const
361 return mPasteboard;
365 //-------------------------------------------------
366 // XServiceInfo
367 //-------------------------------------------------
369 OUString SAL_CALL AquaClipboard::getImplementationName() throw( RuntimeException )
371 return clipboard_getImplementationName();
375 sal_Bool SAL_CALL AquaClipboard::supportsService( const OUString& ServiceName ) throw( RuntimeException )
377 return sal_False;
381 Sequence< OUString > SAL_CALL AquaClipboard::getSupportedServiceNames() throw( RuntimeException )
383 return clipboard_getSupportedServiceNames();