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_dtrans.hxx"
26 
27 #include <clipboardmanager.hxx>
28 #include <com/sun/star/lang/DisposedException.hpp>
29 
30 using namespace com::sun::star::container;
31 using namespace com::sun::star::datatransfer;
32 using namespace com::sun::star::datatransfer::clipboard;
33 using namespace com::sun::star::lang;
34 using namespace com::sun::star::uno;
35 using namespace cppu;
36 using namespace osl;
37 using namespace std;
38 
39 using ::dtrans::ClipboardManager;
40 using ::rtl::OUString;
41 
42 // ------------------------------------------------------------------------
43 
ClipboardManager()44 ClipboardManager::ClipboardManager():
45     WeakComponentImplHelper3< XClipboardManager, XEventListener, XServiceInfo > (m_aMutex),
46     m_aDefaultName(OUString::createFromAscii("default"))
47 {
48 }
49 
50 // ------------------------------------------------------------------------
51 
~ClipboardManager()52 ClipboardManager::~ClipboardManager()
53 {
54 }
55 
56 // ------------------------------------------------------------------------
57 
getImplementationName()58 OUString SAL_CALL ClipboardManager::getImplementationName(  )
59     throw(RuntimeException)
60 {
61     return OUString::createFromAscii(CLIPBOARDMANAGER_IMPLEMENTATION_NAME);
62 }
63 
64 // ------------------------------------------------------------------------
65 
supportsService(const OUString & ServiceName)66 sal_Bool SAL_CALL ClipboardManager::supportsService( const OUString& ServiceName )
67     throw(RuntimeException)
68 {
69     Sequence < OUString > SupportedServicesNames = ClipboardManager_getSupportedServiceNames();
70 
71     for ( sal_Int32 n = 0, nmax = SupportedServicesNames.getLength(); n < nmax; n++ )
72         if (SupportedServicesNames[n].compareTo(ServiceName) == 0)
73             return sal_True;
74 
75     return sal_False;
76 }
77 
78 // ------------------------------------------------------------------------
79 
getSupportedServiceNames()80 Sequence< OUString > SAL_CALL ClipboardManager::getSupportedServiceNames(  )
81     throw(RuntimeException)
82 {
83     return ClipboardManager_getSupportedServiceNames();
84 }
85 
86 // ------------------------------------------------------------------------
87 
getClipboard(const OUString & aName)88 Reference< XClipboard > SAL_CALL ClipboardManager::getClipboard( const OUString& aName )
89     throw(NoSuchElementException, RuntimeException)
90 {
91     MutexGuard aGuard(m_aMutex);
92 
93     // object is disposed already
94     if (rBHelper.bDisposed)
95         throw DisposedException(OUString::createFromAscii("object is disposed."),
96                                 static_cast < XClipboardManager * > (this));
97 
98     ClipboardMap::iterator iter =
99         m_aClipboardMap.find(aName.getLength() ? aName : m_aDefaultName);
100 
101     if (iter != m_aClipboardMap.end())
102         return iter->second;
103 
104     throw NoSuchElementException(aName, static_cast < XClipboardManager * > (this));
105 }
106 
107 // ------------------------------------------------------------------------
108 
addClipboard(const Reference<XClipboard> & xClipboard)109 void SAL_CALL ClipboardManager::addClipboard( const Reference< XClipboard >& xClipboard )
110     throw(IllegalArgumentException, ElementExistException, RuntimeException)
111 {
112     OSL_ASSERT(xClipboard.is());
113 
114     // check parameter
115     if (!xClipboard.is())
116         throw IllegalArgumentException(OUString::createFromAscii("empty reference"),
117                                        static_cast < XClipboardManager * > (this), 1);
118 
119     // the name "default" is reserved for internal use
120     OUString aName = xClipboard->getName();
121     if (m_aDefaultName.compareTo(aName) == 0)
122         throw IllegalArgumentException(OUString::createFromAscii("name reserved"),
123                                        static_cast < XClipboardManager * > (this), 1);
124 
125     // try to add new clipboard to the list
126     ClearableMutexGuard aGuard(m_aMutex);
127     if (!rBHelper.bDisposed && !rBHelper.bInDispose)
128     {
129         pair< const OUString, Reference< XClipboard > > value (
130             aName.getLength() ? aName : m_aDefaultName,
131             xClipboard );
132 
133         pair< ClipboardMap::iterator, bool > p = m_aClipboardMap.insert(value);
134         aGuard.clear();
135 
136         // insert failed, element must exist already
137         if (!p.second)
138             throw ElementExistException(aName, static_cast < XClipboardManager * > (this));
139 
140         // request disposing notifications
141         Reference< XComponent > xComponent(xClipboard, UNO_QUERY);
142         if (xComponent.is())
143             xComponent->addEventListener(static_cast < XEventListener * > (this));
144     }
145 }
146 
147 // ------------------------------------------------------------------------
148 
removeClipboard(const OUString & aName)149 void SAL_CALL ClipboardManager::removeClipboard( const OUString& aName )
150      throw(RuntimeException)
151 {
152     MutexGuard aGuard(m_aMutex);
153     if (!rBHelper.bDisposed)
154         m_aClipboardMap.erase(aName.getLength() ? aName : m_aDefaultName );
155 }
156 
157 // ------------------------------------------------------------------------
158 
listClipboardNames()159 Sequence< OUString > SAL_CALL ClipboardManager::listClipboardNames()
160     throw(RuntimeException)
161 {
162     MutexGuard aGuard(m_aMutex);
163 
164     if (rBHelper.bDisposed)
165         throw DisposedException(OUString::createFromAscii("object is disposed."),
166                                 static_cast < XClipboardManager * > (this));
167 
168     if (rBHelper.bInDispose)
169         return Sequence< OUString > ();
170 
171     Sequence< OUString > aRet(m_aClipboardMap.size());
172     ClipboardMap::iterator iter = m_aClipboardMap.begin();
173     ClipboardMap::iterator imax = m_aClipboardMap.end();
174 
175     for (sal_Int32 n = 0; iter != imax; iter++)
176         aRet[n++] = iter->first;
177 
178     return aRet;
179 }
180 
181 // ------------------------------------------------------------------------
182 
dispose()183 void SAL_CALL ClipboardManager::dispose()
184     throw(RuntimeException)
185 {
186     ClearableMutexGuard aGuard( rBHelper.rMutex );
187     if (!rBHelper.bDisposed && !rBHelper.bInDispose)
188     {
189         rBHelper.bInDispose = sal_True;
190         aGuard.clear();
191 
192         // give everyone a chance to save his clipboard instance
193         EventObject aEvt(static_cast < XClipboardManager * > (this));
194         rBHelper.aLC.disposeAndClear( aEvt );
195 
196         // removeClipboard is still allowed here,  so make a copy of the
197         // list (to ensure integrety) and clear the original.
198         ClearableMutexGuard aGuard2( rBHelper.rMutex );
199         ClipboardMap aCopy(m_aClipboardMap);
200         m_aClipboardMap.clear();
201         aGuard2.clear();
202 
203         // dispose all clipboards still in list
204         ClipboardMap::iterator iter = aCopy.begin();
205         ClipboardMap::iterator imax = aCopy.end();
206 
207         for (; iter != imax; iter++)
208         {
209             Reference< XComponent > xComponent(iter->second, UNO_QUERY);
210             if (xComponent.is())
211             {
212                 try
213                 {
214                     xComponent->removeEventListener(static_cast < XEventListener * > (this));
215                     xComponent->dispose();
216                 }
217 
218                 catch(Exception e)
219                 {
220                     // exceptions can be safely ignored here.
221                 }
222             }
223         }
224 
225         rBHelper.bDisposed = sal_True;
226         rBHelper.bInDispose = sal_False;
227     }
228 }
229 
230 // ------------------------------------------------------------------------
231 
disposing(const EventObject & event)232 void SAL_CALL  ClipboardManager::disposing( const EventObject& event )
233     throw(RuntimeException)
234 {
235     Reference < XClipboard > xClipboard(event.Source, UNO_QUERY);
236 
237     if (xClipboard.is())
238         removeClipboard(xClipboard->getName());
239 }
240 
241 // ------------------------------------------------------------------------
242 
ClipboardManager_createInstance(const Reference<XMultiServiceFactory> &)243 Reference< XInterface > SAL_CALL ClipboardManager_createInstance(
244     const Reference< XMultiServiceFactory > & /*xMultiServiceFactory*/)
245 {
246     return Reference < XInterface >( ( OWeakObject * ) new ClipboardManager());
247 }
248 
249 // ------------------------------------------------------------------------
250 
ClipboardManager_getSupportedServiceNames()251 Sequence< OUString > SAL_CALL ClipboardManager_getSupportedServiceNames()
252 {
253     Sequence < OUString > SupportedServicesNames( 1 );
254     SupportedServicesNames[0] =
255         OUString::createFromAscii("com.sun.star.datatransfer.clipboard.ClipboardManager");
256     return SupportedServicesNames;
257 }
258 
259 
260 
261 
262 
263