1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "clipboardmanager.hxx"
21 #include <com/sun/star/container/ElementExistException.hpp>
22 #include <com/sun/star/container/NoSuchElementException.hpp>
23 #include <com/sun/star/lang/DisposedException.hpp>
24 #include <com/sun/star/lang/IllegalArgumentException.hpp>
25 #include <com/sun/star/uno/XComponentContext.hpp>
26 #include <cppuhelper/supportsservice.hxx>
27 #include <comphelper/sequence.hxx>
28 #include <rtl/ref.hxx>
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
;
39 using ::dtrans::ClipboardManager
;
41 static osl::Mutex g_InstanceGuard
;
42 static rtl::Reference
<ClipboardManager
> g_Instance
;
43 static bool g_Disposed
= false;
46 ClipboardManager::ClipboardManager():
47 WeakComponentImplHelper
< XClipboardManager
, XEventListener
, XServiceInfo
> (m_aMutex
),
48 m_aDefaultName(OUString("default"))
52 ClipboardManager::~ClipboardManager()
56 OUString SAL_CALL
ClipboardManager::getImplementationName( )
58 return "com.sun.star.comp.datatransfer.ClipboardManager";
61 sal_Bool SAL_CALL
ClipboardManager::supportsService( const OUString
& ServiceName
)
63 return cppu::supportsService(this, ServiceName
);
66 Sequence
< OUString
> SAL_CALL
ClipboardManager::getSupportedServiceNames( )
68 return { "com.sun.star.datatransfer.clipboard.ClipboardManager" };
71 Reference
< XClipboard
> SAL_CALL
ClipboardManager::getClipboard( const OUString
& aName
)
73 MutexGuard
aGuard(m_aMutex
);
75 // object is disposed already
76 if (rBHelper
.bDisposed
)
77 throw DisposedException("object is disposed.",
78 static_cast < XClipboardManager
* > (this));
80 ClipboardMap::iterator iter
=
81 m_aClipboardMap
.find(aName
.getLength() ? aName
: m_aDefaultName
);
83 if (iter
!= m_aClipboardMap
.end())
86 throw NoSuchElementException(aName
, static_cast < XClipboardManager
* > (this));
89 void SAL_CALL
ClipboardManager::addClipboard( const Reference
< XClipboard
>& xClipboard
)
91 OSL_ASSERT(xClipboard
.is());
95 throw IllegalArgumentException("empty reference",
96 static_cast < XClipboardManager
* > (this), 1);
98 // the name "default" is reserved for internal use
99 OUString aName
= xClipboard
->getName();
100 if ( m_aDefaultName
== aName
)
101 throw IllegalArgumentException("name reserved",
102 static_cast < XClipboardManager
* > (this), 1);
104 // try to add new clipboard to the list
105 ClearableMutexGuard
aGuard(m_aMutex
);
106 if (!rBHelper
.bDisposed
&& !rBHelper
.bInDispose
)
108 pair
< const OUString
, Reference
< XClipboard
> > value (
109 aName
.getLength() ? aName
: m_aDefaultName
,
112 pair
< ClipboardMap::iterator
, bool > p
= m_aClipboardMap
.insert(value
);
115 // insert failed, element must exist already
117 throw ElementExistException(aName
, static_cast < XClipboardManager
* > (this));
119 // request disposing notifications
120 Reference
< XComponent
> xComponent(xClipboard
, UNO_QUERY
);
122 xComponent
->addEventListener(static_cast < XEventListener
* > (this));
126 void SAL_CALL
ClipboardManager::removeClipboard( const OUString
& aName
)
128 MutexGuard
aGuard(m_aMutex
);
129 if (!rBHelper
.bDisposed
)
130 m_aClipboardMap
.erase(aName
.getLength() ? aName
: m_aDefaultName
);
133 Sequence
< OUString
> SAL_CALL
ClipboardManager::listClipboardNames()
135 MutexGuard
aGuard(m_aMutex
);
137 if (rBHelper
.bDisposed
)
138 throw DisposedException("object is disposed.",
139 static_cast < XClipboardManager
* > (this));
141 if (rBHelper
.bInDispose
)
142 return Sequence
< OUString
> ();
144 return comphelper::mapKeysToSequence(m_aClipboardMap
);
147 void SAL_CALL
ClipboardManager::dispose()
150 osl::MutexGuard
aGuard(g_InstanceGuard
);
155 ClearableMutexGuard
aGuard( rBHelper
.rMutex
);
156 if (!rBHelper
.bDisposed
&& !rBHelper
.bInDispose
)
158 rBHelper
.bInDispose
= true;
161 // give everyone a chance to save his clipboard instance
162 EventObject
aEvt(static_cast < XClipboardManager
* > (this));
163 rBHelper
.aLC
.disposeAndClear( aEvt
);
165 // removeClipboard is still allowed here, so make a copy of the
166 // list (to ensure integrity) and clear the original.
167 ClearableMutexGuard
aGuard2( rBHelper
.rMutex
);
168 ClipboardMap
aCopy(m_aClipboardMap
);
169 m_aClipboardMap
.clear();
172 // dispose all clipboards still in list
173 for (auto const& elem
: aCopy
)
175 Reference
< XComponent
> xComponent(elem
.second
, UNO_QUERY
);
180 xComponent
->removeEventListener(static_cast < XEventListener
* > (this));
181 xComponent
->dispose();
183 catch (const Exception
&)
185 // exceptions can be safely ignored here.
190 rBHelper
.bDisposed
= true;
191 rBHelper
.bInDispose
= false;
196 void SAL_CALL
ClipboardManager::disposing( const EventObject
& event
)
198 Reference
< XClipboard
> xClipboard(event
.Source
, UNO_QUERY
);
201 removeClipboard(xClipboard
->getName());
204 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
205 dtrans_ClipboardManager_get_implementation(
206 css::uno::XComponentContext
* , css::uno::Sequence
<css::uno::Any
> const&)
208 osl::MutexGuard
aGuard(g_InstanceGuard
);
212 g_Instance
.set(new ClipboardManager());
213 g_Instance
->acquire();
214 return static_cast<cppu::OWeakObject
*>(g_Instance
.get());
217 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */