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