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