1*48123e16SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*48123e16SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*48123e16SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*48123e16SAndrew Rist  * distributed with this work for additional information
6*48123e16SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*48123e16SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*48123e16SAndrew Rist  * "License"); you may not use this file except in compliance
9*48123e16SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*48123e16SAndrew Rist  *
11*48123e16SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*48123e16SAndrew Rist  *
13*48123e16SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*48123e16SAndrew Rist  * software distributed under the License is distributed on an
15*48123e16SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*48123e16SAndrew Rist  * KIND, either express or implied.  See the License for the
17*48123e16SAndrew Rist  * specific language governing permissions and limitations
18*48123e16SAndrew Rist  * under the License.
19*48123e16SAndrew Rist  *
20*48123e16SAndrew Rist  *************************************************************/
21*48123e16SAndrew Rist 
22*48123e16SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_dtrans.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <clipboardmanager.hxx>
28cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir using namespace com::sun::star::container;
31cdf0e10cSrcweir using namespace com::sun::star::datatransfer;
32cdf0e10cSrcweir using namespace com::sun::star::datatransfer::clipboard;
33cdf0e10cSrcweir using namespace com::sun::star::lang;
34cdf0e10cSrcweir using namespace com::sun::star::uno;
35cdf0e10cSrcweir using namespace cppu;
36cdf0e10cSrcweir using namespace osl;
37cdf0e10cSrcweir using namespace std;
38cdf0e10cSrcweir 
39cdf0e10cSrcweir using ::dtrans::ClipboardManager;
40cdf0e10cSrcweir using ::rtl::OUString;
41cdf0e10cSrcweir 
42cdf0e10cSrcweir // ------------------------------------------------------------------------
43cdf0e10cSrcweir 
ClipboardManager()44cdf0e10cSrcweir ClipboardManager::ClipboardManager():
45cdf0e10cSrcweir     WeakComponentImplHelper3< XClipboardManager, XEventListener, XServiceInfo > (m_aMutex),
46cdf0e10cSrcweir     m_aDefaultName(OUString::createFromAscii("default"))
47cdf0e10cSrcweir {
48cdf0e10cSrcweir }
49cdf0e10cSrcweir 
50cdf0e10cSrcweir // ------------------------------------------------------------------------
51cdf0e10cSrcweir 
~ClipboardManager()52cdf0e10cSrcweir ClipboardManager::~ClipboardManager()
53cdf0e10cSrcweir {
54cdf0e10cSrcweir }
55cdf0e10cSrcweir 
56cdf0e10cSrcweir // ------------------------------------------------------------------------
57cdf0e10cSrcweir 
getImplementationName()58cdf0e10cSrcweir OUString SAL_CALL ClipboardManager::getImplementationName(  )
59cdf0e10cSrcweir     throw(RuntimeException)
60cdf0e10cSrcweir {
61cdf0e10cSrcweir     return OUString::createFromAscii(CLIPBOARDMANAGER_IMPLEMENTATION_NAME);
62cdf0e10cSrcweir }
63cdf0e10cSrcweir 
64cdf0e10cSrcweir // ------------------------------------------------------------------------
65cdf0e10cSrcweir 
supportsService(const OUString & ServiceName)66cdf0e10cSrcweir sal_Bool SAL_CALL ClipboardManager::supportsService( const OUString& ServiceName )
67cdf0e10cSrcweir     throw(RuntimeException)
68cdf0e10cSrcweir {
69cdf0e10cSrcweir     Sequence < OUString > SupportedServicesNames = ClipboardManager_getSupportedServiceNames();
70cdf0e10cSrcweir 
71cdf0e10cSrcweir     for ( sal_Int32 n = 0, nmax = SupportedServicesNames.getLength(); n < nmax; n++ )
72cdf0e10cSrcweir         if (SupportedServicesNames[n].compareTo(ServiceName) == 0)
73cdf0e10cSrcweir             return sal_True;
74cdf0e10cSrcweir 
75cdf0e10cSrcweir     return sal_False;
76cdf0e10cSrcweir }
77cdf0e10cSrcweir 
78cdf0e10cSrcweir // ------------------------------------------------------------------------
79cdf0e10cSrcweir 
getSupportedServiceNames()80cdf0e10cSrcweir Sequence< OUString > SAL_CALL ClipboardManager::getSupportedServiceNames(  )
81cdf0e10cSrcweir     throw(RuntimeException)
82cdf0e10cSrcweir {
83cdf0e10cSrcweir     return ClipboardManager_getSupportedServiceNames();
84cdf0e10cSrcweir }
85cdf0e10cSrcweir 
86cdf0e10cSrcweir // ------------------------------------------------------------------------
87cdf0e10cSrcweir 
getClipboard(const OUString & aName)88cdf0e10cSrcweir Reference< XClipboard > SAL_CALL ClipboardManager::getClipboard( const OUString& aName )
89cdf0e10cSrcweir     throw(NoSuchElementException, RuntimeException)
90cdf0e10cSrcweir {
91cdf0e10cSrcweir     MutexGuard aGuard(m_aMutex);
92cdf0e10cSrcweir 
93cdf0e10cSrcweir     // object is disposed already
94cdf0e10cSrcweir     if (rBHelper.bDisposed)
95cdf0e10cSrcweir         throw DisposedException(OUString::createFromAscii("object is disposed."),
96cdf0e10cSrcweir                                 static_cast < XClipboardManager * > (this));
97cdf0e10cSrcweir 
98cdf0e10cSrcweir     ClipboardMap::iterator iter =
99cdf0e10cSrcweir         m_aClipboardMap.find(aName.getLength() ? aName : m_aDefaultName);
100cdf0e10cSrcweir 
101cdf0e10cSrcweir     if (iter != m_aClipboardMap.end())
102cdf0e10cSrcweir         return iter->second;
103cdf0e10cSrcweir 
104cdf0e10cSrcweir     throw NoSuchElementException(aName, static_cast < XClipboardManager * > (this));
105cdf0e10cSrcweir }
106cdf0e10cSrcweir 
107cdf0e10cSrcweir // ------------------------------------------------------------------------
108cdf0e10cSrcweir 
addClipboard(const Reference<XClipboard> & xClipboard)109cdf0e10cSrcweir void SAL_CALL ClipboardManager::addClipboard( const Reference< XClipboard >& xClipboard )
110cdf0e10cSrcweir     throw(IllegalArgumentException, ElementExistException, RuntimeException)
111cdf0e10cSrcweir {
112cdf0e10cSrcweir     OSL_ASSERT(xClipboard.is());
113cdf0e10cSrcweir 
114cdf0e10cSrcweir     // check parameter
115cdf0e10cSrcweir     if (!xClipboard.is())
116cdf0e10cSrcweir         throw IllegalArgumentException(OUString::createFromAscii("empty reference"),
117cdf0e10cSrcweir                                        static_cast < XClipboardManager * > (this), 1);
118cdf0e10cSrcweir 
119cdf0e10cSrcweir     // the name "default" is reserved for internal use
120cdf0e10cSrcweir     OUString aName = xClipboard->getName();
121cdf0e10cSrcweir     if (m_aDefaultName.compareTo(aName) == 0)
122cdf0e10cSrcweir         throw IllegalArgumentException(OUString::createFromAscii("name reserved"),
123cdf0e10cSrcweir                                        static_cast < XClipboardManager * > (this), 1);
124cdf0e10cSrcweir 
125cdf0e10cSrcweir     // try to add new clipboard to the list
126cdf0e10cSrcweir     ClearableMutexGuard aGuard(m_aMutex);
127cdf0e10cSrcweir     if (!rBHelper.bDisposed && !rBHelper.bInDispose)
128cdf0e10cSrcweir     {
129cdf0e10cSrcweir         pair< const OUString, Reference< XClipboard > > value (
130cdf0e10cSrcweir             aName.getLength() ? aName : m_aDefaultName,
131cdf0e10cSrcweir             xClipboard );
132cdf0e10cSrcweir 
133cdf0e10cSrcweir         pair< ClipboardMap::iterator, bool > p = m_aClipboardMap.insert(value);
134cdf0e10cSrcweir         aGuard.clear();
135cdf0e10cSrcweir 
136cdf0e10cSrcweir         // insert failed, element must exist already
137cdf0e10cSrcweir         if (!p.second)
138cdf0e10cSrcweir             throw ElementExistException(aName, static_cast < XClipboardManager * > (this));
139cdf0e10cSrcweir 
140cdf0e10cSrcweir         // request disposing notifications
141cdf0e10cSrcweir         Reference< XComponent > xComponent(xClipboard, UNO_QUERY);
142cdf0e10cSrcweir         if (xComponent.is())
143cdf0e10cSrcweir             xComponent->addEventListener(static_cast < XEventListener * > (this));
144cdf0e10cSrcweir     }
145cdf0e10cSrcweir }
146cdf0e10cSrcweir 
147cdf0e10cSrcweir // ------------------------------------------------------------------------
148cdf0e10cSrcweir 
removeClipboard(const OUString & aName)149cdf0e10cSrcweir void SAL_CALL ClipboardManager::removeClipboard( const OUString& aName )
150cdf0e10cSrcweir      throw(RuntimeException)
151cdf0e10cSrcweir {
152cdf0e10cSrcweir     MutexGuard aGuard(m_aMutex);
153cdf0e10cSrcweir     if (!rBHelper.bDisposed)
154cdf0e10cSrcweir         m_aClipboardMap.erase(aName.getLength() ? aName : m_aDefaultName );
155cdf0e10cSrcweir }
156cdf0e10cSrcweir 
157cdf0e10cSrcweir // ------------------------------------------------------------------------
158cdf0e10cSrcweir 
listClipboardNames()159cdf0e10cSrcweir Sequence< OUString > SAL_CALL ClipboardManager::listClipboardNames()
160cdf0e10cSrcweir     throw(RuntimeException)
161cdf0e10cSrcweir {
162cdf0e10cSrcweir     MutexGuard aGuard(m_aMutex);
163cdf0e10cSrcweir 
164cdf0e10cSrcweir     if (rBHelper.bDisposed)
165cdf0e10cSrcweir         throw DisposedException(OUString::createFromAscii("object is disposed."),
166cdf0e10cSrcweir                                 static_cast < XClipboardManager * > (this));
167cdf0e10cSrcweir 
168cdf0e10cSrcweir     if (rBHelper.bInDispose)
169cdf0e10cSrcweir         return Sequence< OUString > ();
170cdf0e10cSrcweir 
171cdf0e10cSrcweir     Sequence< OUString > aRet(m_aClipboardMap.size());
172cdf0e10cSrcweir     ClipboardMap::iterator iter = m_aClipboardMap.begin();
173cdf0e10cSrcweir     ClipboardMap::iterator imax = m_aClipboardMap.end();
174cdf0e10cSrcweir 
175cdf0e10cSrcweir     for (sal_Int32 n = 0; iter != imax; iter++)
176cdf0e10cSrcweir         aRet[n++] = iter->first;
177cdf0e10cSrcweir 
178cdf0e10cSrcweir     return aRet;
179cdf0e10cSrcweir }
180cdf0e10cSrcweir 
181cdf0e10cSrcweir // ------------------------------------------------------------------------
182cdf0e10cSrcweir 
dispose()183cdf0e10cSrcweir void SAL_CALL ClipboardManager::dispose()
184cdf0e10cSrcweir     throw(RuntimeException)
185cdf0e10cSrcweir {
186cdf0e10cSrcweir     ClearableMutexGuard aGuard( rBHelper.rMutex );
187cdf0e10cSrcweir     if (!rBHelper.bDisposed && !rBHelper.bInDispose)
188cdf0e10cSrcweir     {
189cdf0e10cSrcweir         rBHelper.bInDispose = sal_True;
190cdf0e10cSrcweir         aGuard.clear();
191cdf0e10cSrcweir 
192cdf0e10cSrcweir         // give everyone a chance to save his clipboard instance
193cdf0e10cSrcweir         EventObject aEvt(static_cast < XClipboardManager * > (this));
194cdf0e10cSrcweir         rBHelper.aLC.disposeAndClear( aEvt );
195cdf0e10cSrcweir 
196cdf0e10cSrcweir         // removeClipboard is still allowed here,  so make a copy of the
197cdf0e10cSrcweir         // list (to ensure integrety) and clear the original.
198cdf0e10cSrcweir         ClearableMutexGuard aGuard2( rBHelper.rMutex );
199cdf0e10cSrcweir         ClipboardMap aCopy(m_aClipboardMap);
200cdf0e10cSrcweir         m_aClipboardMap.clear();
201cdf0e10cSrcweir         aGuard2.clear();
202cdf0e10cSrcweir 
203cdf0e10cSrcweir         // dispose all clipboards still in list
204cdf0e10cSrcweir         ClipboardMap::iterator iter = aCopy.begin();
205cdf0e10cSrcweir         ClipboardMap::iterator imax = aCopy.end();
206cdf0e10cSrcweir 
207cdf0e10cSrcweir         for (; iter != imax; iter++)
208cdf0e10cSrcweir         {
209cdf0e10cSrcweir             Reference< XComponent > xComponent(iter->second, UNO_QUERY);
210cdf0e10cSrcweir             if (xComponent.is())
211cdf0e10cSrcweir             {
212cdf0e10cSrcweir                 try
213cdf0e10cSrcweir                 {
214cdf0e10cSrcweir                     xComponent->removeEventListener(static_cast < XEventListener * > (this));
215cdf0e10cSrcweir                     xComponent->dispose();
216cdf0e10cSrcweir                 }
217cdf0e10cSrcweir 
218cdf0e10cSrcweir                 catch(Exception e)
219cdf0e10cSrcweir                 {
220cdf0e10cSrcweir                     // exceptions can be safely ignored here.
221cdf0e10cSrcweir                 }
222cdf0e10cSrcweir             }
223cdf0e10cSrcweir         }
224cdf0e10cSrcweir 
225cdf0e10cSrcweir         rBHelper.bDisposed = sal_True;
226cdf0e10cSrcweir         rBHelper.bInDispose = sal_False;
227cdf0e10cSrcweir     }
228cdf0e10cSrcweir }
229cdf0e10cSrcweir 
230cdf0e10cSrcweir // ------------------------------------------------------------------------
231cdf0e10cSrcweir 
disposing(const EventObject & event)232cdf0e10cSrcweir void SAL_CALL  ClipboardManager::disposing( const EventObject& event )
233cdf0e10cSrcweir     throw(RuntimeException)
234cdf0e10cSrcweir {
235cdf0e10cSrcweir     Reference < XClipboard > xClipboard(event.Source, UNO_QUERY);
236cdf0e10cSrcweir 
237cdf0e10cSrcweir     if (xClipboard.is())
238cdf0e10cSrcweir         removeClipboard(xClipboard->getName());
239cdf0e10cSrcweir }
240cdf0e10cSrcweir 
241cdf0e10cSrcweir // ------------------------------------------------------------------------
242cdf0e10cSrcweir 
ClipboardManager_createInstance(const Reference<XMultiServiceFactory> &)243cdf0e10cSrcweir Reference< XInterface > SAL_CALL ClipboardManager_createInstance(
244cdf0e10cSrcweir     const Reference< XMultiServiceFactory > & /*xMultiServiceFactory*/)
245cdf0e10cSrcweir {
246cdf0e10cSrcweir     return Reference < XInterface >( ( OWeakObject * ) new ClipboardManager());
247cdf0e10cSrcweir }
248cdf0e10cSrcweir 
249cdf0e10cSrcweir // ------------------------------------------------------------------------
250cdf0e10cSrcweir 
ClipboardManager_getSupportedServiceNames()251cdf0e10cSrcweir Sequence< OUString > SAL_CALL ClipboardManager_getSupportedServiceNames()
252cdf0e10cSrcweir {
253cdf0e10cSrcweir     Sequence < OUString > SupportedServicesNames( 1 );
254cdf0e10cSrcweir     SupportedServicesNames[0] =
255cdf0e10cSrcweir         OUString::createFromAscii("com.sun.star.datatransfer.clipboard.ClipboardManager");
256cdf0e10cSrcweir     return SupportedServicesNames;
257cdf0e10cSrcweir }
258cdf0e10cSrcweir 
259cdf0e10cSrcweir 
260cdf0e10cSrcweir 
261cdf0e10cSrcweir 
262cdf0e10cSrcweir 
263