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 44 ClipboardManager::ClipboardManager(): 45 WeakComponentImplHelper3< XClipboardManager, XEventListener, XServiceInfo > (m_aMutex), 46 m_aDefaultName(OUString::createFromAscii("default")) 47 { 48 } 49 50 // ------------------------------------------------------------------------ 51 52 ClipboardManager::~ClipboardManager() 53 { 54 } 55 56 // ------------------------------------------------------------------------ 57 58 OUString SAL_CALL ClipboardManager::getImplementationName( ) 59 throw(RuntimeException) 60 { 61 return OUString::createFromAscii(CLIPBOARDMANAGER_IMPLEMENTATION_NAME); 62 } 63 64 // ------------------------------------------------------------------------ 65 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 80 Sequence< OUString > SAL_CALL ClipboardManager::getSupportedServiceNames( ) 81 throw(RuntimeException) 82 { 83 return ClipboardManager_getSupportedServiceNames(); 84 } 85 86 // ------------------------------------------------------------------------ 87 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 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 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 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 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 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 243 Reference< XInterface > SAL_CALL ClipboardManager_createInstance( 244 const Reference< XMultiServiceFactory > & /*xMultiServiceFactory*/) 245 { 246 return Reference < XInterface >( ( OWeakObject * ) new ClipboardManager()); 247 } 248 249 // ------------------------------------------------------------------------ 250 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