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