xref: /trunk/main/dtrans/source/generic/clipboardmanager.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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