LibreOffice Module dbaccess (master) 1
ContentHelper.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <ContentHelper.hxx>
21#include <rtl/ref.hxx>
22#include <rtl/ustrbuf.hxx>
24#include <com/sun/star/ucb/UnsupportedCommandException.hpp>
25#include <com/sun/star/lang/IllegalArgumentException.hpp>
26#include <com/sun/star/lang/IllegalAccessException.hpp>
27#include <com/sun/star/beans/IllegalTypeException.hpp>
28#include <com/sun/star/beans/PropertyAttribute.hpp>
29#include <com/sun/star/beans/PropertyValue.hpp>
30#include <com/sun/star/beans/XPropertySet.hpp>
31#include <com/sun/star/container/ElementExistException.hpp>
36#include <sdbcoretools.hxx>
37#include <stringconstants.hxx>
38#include <strings.hxx>
39
40#include <map>
41#include <utility>
42
43namespace dbaccess
44{
45using namespace ::com::sun::star::uno;
46using namespace ::com::sun::star::ucb;
47using namespace ::com::sun::star::beans;
48using namespace ::com::sun::star::lang;
49using namespace ::com::sun::star::sdbc;
50using namespace ::com::sun::star::io;
51using namespace ::com::sun::star::util;
52using namespace ::com::sun::star::embed;
53using namespace ::com::sun::star::container;
54using namespace ::cppu;
55
57 : m_pDataSource(nullptr)
58{
59}
60
62{
63}
64
65OContentHelper::OContentHelper(const Reference< XComponentContext >& _xORB
66 ,const Reference< XInterface >& _xParentContainer
67 ,TContentPtr _pImpl)
69 ,m_aContentListeners(m_aMutex)
70 ,m_aPropertyChangeListeners(m_aMutex)
71 ,m_xParentContainer( _xParentContainer )
72 ,m_aContext( _xORB )
73 ,m_pImpl(std::move(_pImpl))
74 ,m_nCommandId(0)
75{
76}
77
79{
80 ::osl::MutexGuard aGuard(m_aMutex);
81
82 // say goodbye to our listeners
83 EventObject aEvt(*this);
85
86 m_xParentContainer = nullptr;
87}
88
90 {
91 return "com.sun.star.comp.sdb.Content";
92 }
93sal_Bool SAL_CALL OContentHelper::supportsService(const OUString& _rServiceName)
94 {
95 const css::uno::Sequence< OUString > aSupported(getSupportedServiceNames());
96 for (const OUString& s : aSupported)
97 if (s == _rServiceName)
98 return true;
99
100 return false;
101 }
102css::uno::Sequence< OUString > SAL_CALL OContentHelper::getSupportedServiceNames()
103{
104 return { "com.sun.star.ucb.Content" };
105}
106
107
108css::uno::Sequence<sal_Int8> OContentHelper::getImplementationId()
109{
110 return css::uno::Sequence<sal_Int8>();
111}
112
113// XContent
114Reference< XContentIdentifier > SAL_CALL OContentHelper::getIdentifier( )
115{
116 ::osl::MutexGuard aGuard(m_aMutex);
117 OUString aIdentifier( "private:" + impl_getHierarchicalName( true ) );
118 return new ::ucbhelper::ContentIdentifier( aIdentifier );
119}
120
121OUString OContentHelper::impl_getHierarchicalName( bool _includingRootContainer ) const
122{
123 OUStringBuffer aHierarchicalName( m_pImpl->m_aProps.aTitle );
124 Reference< XInterface > xParent = m_xParentContainer;
125 while( xParent.is() )
126 {
127 Reference<XPropertySet> xProp( xParent, UNO_QUERY );
128 Reference< XChild > xChild( xParent, UNO_QUERY );
129 xParent.set( xChild.is() ? xChild->getParent() : Reference< XInterface >(), UNO_QUERY );
130 if ( xProp.is() && xParent.is() )
131 {
132 OUString sName;
133 xProp->getPropertyValue( PROPERTY_NAME ) >>= sName;
134
135 OUString sPrevious = aHierarchicalName.makeStringAndClear();
136 aHierarchicalName.append( sName + "/" + sPrevious );
137 }
138 }
139 OUString sHierarchicalName( aHierarchicalName.makeStringAndClear() );
140 if ( !_includingRootContainer )
141 sHierarchicalName = sHierarchicalName.copy( sHierarchicalName.indexOf( '/' ) + 1 );
142 return sHierarchicalName;
143}
144
146{
147 ::osl::MutexGuard aGuard(m_aMutex);
148
149 if ( !m_pImpl->m_aProps.aContentType )
150 { // content type not yet retrieved
151 m_pImpl->m_aProps.aContentType = determineContentType();
152 }
153
154 return *m_pImpl->m_aProps.aContentType;
155}
156
157void SAL_CALL OContentHelper::addContentEventListener( const Reference< XContentEventListener >& _rxListener )
158{
159 ::osl::MutexGuard aGuard(m_aMutex);
160 if ( _rxListener.is() )
162}
163
164void SAL_CALL OContentHelper::removeContentEventListener( const Reference< XContentEventListener >& _rxListener )
165{
166 ::osl::MutexGuard aGuard(m_aMutex);
167 if (_rxListener.is())
169}
170
171// XCommandProcessor
173{
174 ::osl::MutexGuard aGuard(m_aMutex);
175 // Just increase counter on every call to generate an identifier.
176 return ++m_nCommandId;
177}
178
179Any SAL_CALL OContentHelper::execute( const Command& aCommand, sal_Int32 /*CommandId*/, const Reference< XCommandEnvironment >& Environment )
180{
181 Any aRet;
182 if ( aCommand.Name == "getPropertyValues" )
183 {
184 // getPropertyValues
185
186 Sequence< Property > Properties;
187 if ( !( aCommand.Argument >>= Properties ) )
188 {
189 OSL_FAIL( "Wrong argument type!" );
191 Any( IllegalArgumentException(
192 OUString(),
193 static_cast< cppu::OWeakObject * >( this ),
194 -1 ) ),
195 Environment );
196 // Unreachable
197 }
198 aRet <<= getPropertyValues( Properties);
199 }
200 else if ( aCommand.Name == "setPropertyValues" )
201 {
202 // setPropertyValues
203
204 Sequence< PropertyValue > aProperties;
205 if ( !( aCommand.Argument >>= aProperties ) )
206 {
207 OSL_FAIL( "Wrong argument type!" );
209 Any( IllegalArgumentException(
210 OUString(),
211 static_cast< cppu::OWeakObject * >( this ),
212 -1 ) ),
213 Environment );
214 // Unreachable
215 }
216
217 if ( !aProperties.hasElements() )
218 {
219 OSL_FAIL( "No properties!" );
221 Any( IllegalArgumentException(
222 OUString(),
223 static_cast< cppu::OWeakObject * >( this ),
224 -1 ) ),
225 Environment );
226 // Unreachable
227 }
228
229 aRet <<= setPropertyValues( aProperties );
230 }
231 else if ( aCommand.Name == "getPropertySetInfo" )
232 {
233 // getPropertySetInfo
234
235 Reference<XPropertySet> xProp(*this,UNO_QUERY);
236 if ( xProp.is() )
237 aRet <<= xProp->getPropertySetInfo();
238 // aRet <<= getPropertySetInfo(); // TODO
239 }
240 else
241 {
242 // Unsupported command
243
244 OSL_FAIL( "Content::execute - unsupported command!" );
245
247 Any( UnsupportedCommandException(
248 OUString(),
249 static_cast< cppu::OWeakObject * >( this ) ) ),
250 Environment );
251 // Unreachable
252 }
253
254 return aRet;
255}
256
257void SAL_CALL OContentHelper::abort( sal_Int32 /*CommandId*/ )
258{
259}
260
261// XPropertiesChangeNotifier
262void SAL_CALL OContentHelper::addPropertiesChangeListener( const Sequence< OUString >& PropertyNames, const Reference< XPropertiesChangeListener >& Listener )
263{
264 ::osl::MutexGuard aGuard(m_aMutex);
265 sal_Int32 nCount = PropertyNames.getLength();
266 if ( !nCount )
267 {
268 // Note: An empty sequence means a listener for "all" properties.
269 m_aPropertyChangeListeners.addInterface(OUString(), Listener );
270 }
271 else
272 {
273 const OUString* pSeq = PropertyNames.getConstArray();
274
275 for ( sal_Int32 n = 0; n < nCount; ++n )
276 {
277 const OUString& rName = pSeq[ n ];
278 if ( !rName.isEmpty() )
280 }
281 }
282}
283
284void SAL_CALL OContentHelper::removePropertiesChangeListener( const Sequence< OUString >& PropertyNames, const Reference< XPropertiesChangeListener >& Listener )
285{
286 ::osl::MutexGuard aGuard(m_aMutex);
287 sal_Int32 nCount = PropertyNames.getLength();
288 if ( !nCount )
289 {
290 // Note: An empty sequence means a listener for "all" properties.
291 m_aPropertyChangeListeners.removeInterface( OUString(), Listener );
292 }
293 else
294 {
295 const OUString* pSeq = PropertyNames.getConstArray();
296
297 for ( sal_Int32 n = 0; n < nCount; ++n )
298 {
299 const OUString& rName = pSeq[ n ];
300 if ( !rName.isEmpty() )
302 }
303 }
304}
305
306// XPropertyContainer
307void SAL_CALL OContentHelper::addProperty( const OUString& /*Name*/, sal_Int16 /*Attributes*/, const Any& /*DefaultValue*/ )
308{
309 OSL_FAIL( "OContentHelper::addProperty: not implemented!" );
310}
311
312void SAL_CALL OContentHelper::removeProperty( const OUString& /*Name*/ )
313{
314 OSL_FAIL( "OContentHelper::removeProperty: not implemented!" );
315}
316
317// XInitialization
318void SAL_CALL OContentHelper::initialize( const Sequence< Any >& _aArguments )
319{
320 const Any* pBegin = _aArguments.getConstArray();
321 const Any* pEnd = pBegin + _aArguments.getLength();
322 PropertyValue aValue;
323 for(;pBegin != pEnd;++pBegin)
324 {
325 *pBegin >>= aValue;
326 if ( aValue.Name == "Parent" )
327 {
328 m_xParentContainer.set(aValue.Value,UNO_QUERY);
329 }
330 else if ( aValue.Name == PROPERTY_NAME )
331 {
332 aValue.Value >>= m_pImpl->m_aProps.aTitle;
333 }
334 else if ( aValue.Name == PROPERTY_PERSISTENT_NAME )
335 {
336 aValue.Value >>= m_pImpl->m_aProps.sPersistentName;
337 }
338 }
339}
340
341Sequence< Any > OContentHelper::setPropertyValues(const Sequence< PropertyValue >& rValues )
342{
343 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
344
345 Sequence< Any > aRet( rValues.getLength() );
346 auto aRetRange = asNonConstRange(aRet);
347 Sequence< PropertyChangeEvent > aChanges( rValues.getLength() );
348 sal_Int32 nChanged = 0;
349
350 PropertyChangeEvent aEvent;
351 aEvent.Source = static_cast< cppu::OWeakObject * >( this );
352 aEvent.Further = false;
353 aEvent.PropertyHandle = -1;
354
355 const PropertyValue* pValues = rValues.getConstArray();
356 sal_Int32 nCount = rValues.getLength();
357
358 for ( sal_Int32 n = 0; n < nCount; ++n )
359 {
360 const PropertyValue& rValue = pValues[ n ];
361
362 if ( rValue.Name == "ContentType" || rValue.Name == "IsDocument" || rValue.Name == "IsFolder" )
363 {
364 // Read-only property!
365 aRetRange[ n ] <<= IllegalAccessException("Property is read-only!",
366 static_cast< cppu::OWeakObject * >( this ) );
367 }
368 else if ( rValue.Name == "Title" )
369 {
370 OUString aNewValue;
371 if ( rValue.Value >>= aNewValue )
372 {
373 if ( aNewValue != m_pImpl->m_aProps.aTitle )
374 {
375 aEvent.PropertyName = rValue.Name;
376 aEvent.OldValue <<= m_pImpl->m_aProps.aTitle;
377
378 try
379 {
380 impl_rename_throw( aNewValue ,false);
381 OSL_ENSURE( m_pImpl->m_aProps.aTitle == aNewValue, "OContentHelper::setPropertyValues('Title'): rename did not work!" );
382
383 aEvent.NewValue <<= aNewValue;
384 aChanges.getArray()[ nChanged ] = aEvent;
385 nChanged++;
386 }
387 catch( const Exception& )
388 {
389 TOOLS_WARN_EXCEPTION( "dbaccess", "OContentHelper::setPropertyValues('Title'): caught an exception while renaming!" );
390 }
391 }
392 else
393 {
394 // Old value equals new value. No error!
395 }
396 }
397 else
398 {
399 aRetRange[ n ] <<= IllegalTypeException("Property value has wrong type!",
400 static_cast< cppu::OWeakObject * >( this ) );
401 }
402 }
403
404 else
405 {
406 aRetRange[ n ] <<= Exception("No property set for storing the value!",
407 static_cast< cppu::OWeakObject * >( this ) );
408 }
409 }
410
411 if ( nChanged > 0 )
412 {
414 aGuard.clear();
415 aChanges.realloc( nChanged );
416 notifyPropertiesChange( aChanges );
417 }
418
419 return aRet;
420}
421
422// static
423Reference< XRow > OContentHelper::getPropertyValues( const Sequence< Property >& rProperties)
424{
425 // Note: Empty sequence means "get values of all supported properties".
426
428
429 sal_Int32 nCount = rProperties.getLength();
430 if ( nCount )
431 {
432 const Property* pProps = rProperties.getConstArray();
433 for ( sal_Int32 n = 0; n < nCount; ++n )
434 {
435 const Property& rProp = pProps[ n ];
436
437 // Process Core properties.
438
439 if ( rProp.Name == "ContentType" )
440 {
441 xRow->appendString ( rProp, getContentType() );
442 }
443 else if ( rProp.Name == "Title" )
444 {
445 xRow->appendString ( rProp, m_pImpl->m_aProps.aTitle );
446 }
447 else if ( rProp.Name == "IsDocument" )
448 {
449 xRow->appendBoolean( rProp, m_pImpl->m_aProps.bIsDocument );
450 }
451 else if ( rProp.Name == "IsFolder" )
452 {
453 xRow->appendBoolean( rProp, m_pImpl->m_aProps.bIsFolder );
454 }
455 else
456 xRow->appendVoid(rProp);
457 }
458 }
459 else
460 {
461 // Append all Core Properties.
462 xRow->appendString (
463 Property( "ContentType", -1,
465 PropertyAttribute::BOUND
466 | PropertyAttribute::READONLY ),
467 getContentType() );
468 xRow->appendString (
469 Property( "Title", -1,
471 PropertyAttribute::BOUND ),
472 m_pImpl->m_aProps.aTitle );
473 xRow->appendBoolean(
474 Property( "IsDocument", -1,
476 PropertyAttribute::BOUND
477 | PropertyAttribute::READONLY ),
478 m_pImpl->m_aProps.bIsDocument );
479 xRow->appendBoolean(
480 Property( "IsFolder", -1,
482 PropertyAttribute::BOUND
483 | PropertyAttribute::READONLY ),
484 m_pImpl->m_aProps.bIsFolder );
485
486 // @@@ Append other properties supported directly.
487 }
488
489 return xRow;
490}
491
492void OContentHelper::notifyPropertiesChange( const Sequence< PropertyChangeEvent >& evt ) const
493{
494
495 sal_Int32 nCount = evt.getLength();
496 if ( !nCount )
497 return;
498
499 // First, notify listeners interested in changes of every property.
501 if ( pAllPropsContainer )
502 pAllPropsContainer->notifyEach( &XPropertiesChangeListener::propertiesChange, evt );
503
504 typedef std::map< XPropertiesChangeListener*, Sequence< PropertyChangeEvent > > PropertiesEventListenerMap;
506
507 const PropertyChangeEvent* propertyChangeEvent = evt.getConstArray();
508
509 for ( sal_Int32 n = 0; n < nCount; ++n, ++propertyChangeEvent )
510 {
511 const PropertyChangeEvent& rEvent = *propertyChangeEvent;
512 const OUString& rName = rEvent.PropertyName;
513
515 if ( pPropsContainer )
516 {
517 comphelper::OInterfaceIteratorHelper3 aIter( *pPropsContainer );
518 while ( aIter.hasMoreElements() )
519 {
520 Sequence< PropertyChangeEvent >* propertyEvents;
521
522 XPropertiesChangeListener* pListener = aIter.next().get();
523 PropertiesEventListenerMap::iterator it = aListeners.find( pListener );
524 if ( it == aListeners.end() )
525 {
526 // Not in map - create and insert new entry.
527 auto pair = aListeners.emplace( pListener, Sequence< PropertyChangeEvent >( nCount ));
528 propertyEvents = &pair.first->second;
529 }
530 else
531 propertyEvents = &(*it).second;
532
533 propertyEvents->getArray()[n] = rEvent;
534 }
535 }
536 }
537
538 // Notify listeners.
539 for (auto & rPair : aListeners)
540 {
541 XPropertiesChangeListener* pListener = rPair.first;
542 Sequence< PropertyChangeEvent >& rSeq = rPair.second;
543
544 // Propagate event.
545 pListener->propertiesChange( rSeq );
546 }
547}
548
549Reference< XInterface > SAL_CALL OContentHelper::getParent( )
550{
551 ::osl::MutexGuard aGuard(m_aMutex);
552 return m_xParentContainer;
553}
554
555void SAL_CALL OContentHelper::setParent( const Reference< XInterface >& _xParent )
556{
557 ::osl::MutexGuard aGuard(m_aMutex);
558 m_xParentContainer = _xParent;
559}
560
561void OContentHelper::impl_rename_throw(const OUString& _sNewName,bool _bNotify )
562{
563 osl::ClearableGuard< osl::Mutex > aGuard(m_aMutex);
564 if ( _sNewName == m_pImpl->m_aProps.aTitle )
565 return;
566 try
567 {
568 Sequence<PropertyChangeEvent> aChanges{
569 { /* Source */ static_cast<cppu::OWeakObject*>(this),
570 /* PropertyName */ PROPERTY_NAME,
571 /* Further */ false,
572 /* PropertyHandle */ PROPERTY_ID_NAME,
573 /* OldValue */ Any(m_pImpl->m_aProps.aTitle),
574 /* NewValue */ Any(_sNewName) }
575 };
576
577 aGuard.clear();
578
579 m_pImpl->m_aProps.aTitle = _sNewName;
580 if ( _bNotify )
581 notifyPropertiesChange( aChanges );
583 }
584 catch(const PropertyVetoException&)
585 {
586 throw ElementExistException(_sNewName,*this);
587 }
588}
589
590void SAL_CALL OContentHelper::rename( const OUString& newName )
591{
592
594
595}
596
598{
600}
601
602} // namespace dbaccess
603
604/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const PropertyValue * pValues
OptionalString sName
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
PropertiesInfo aProperties
AnyEventRef aEvent
sal_Int32 addInterface(const css::uno::Reference< ListenerT > &rxIFace)
void disposeAndClear(const css::lang::EventObject &rEvt)
sal_Int32 removeInterface(const css::uno::Reference< ListenerT > &rxIFace)
void notifyEach(void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event)
css::uno::Reference< ListenerT > const & next()
sal_Int32 addInterface(const key &rKey, const css::uno::Reference< listener > &rListener)
sal_Int32 removeInterface(const key &rKey, const css::uno::Reference< listener > &rListener)
OInterfaceContainerHelper3< listener > * getContainer(const key &rKey) const
mutable::osl::Mutex m_aMutex
virtual void SAL_CALL addContentEventListener(const css::uno::Reference< css::ucb::XContentEventListener > &Listener) override
virtual void SAL_CALL setParent(const css::uno::Reference< css::uno::XInterface > &Parent) override
css::uno::Sequence< css::uno::Any > setPropertyValues(const css::uno::Sequence< css::beans::PropertyValue > &rValues)
OUString impl_getHierarchicalName(bool _includingRootContainer) const
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
::comphelper::OInterfaceContainerHelper3< css::ucb::XContentEventListener > m_aContentListeners
virtual OUString determineContentType() const =0
void notifyPropertiesChange(const css::uno::Sequence< css::beans::PropertyChangeEvent > &evt) const
This method can be used to propagate changes of property values.
virtual void SAL_CALL disposing() override
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent() override
virtual sal_Int32 SAL_CALL createCommandIdentifier() override
const css::uno::Reference< css::uno::XComponentContext > m_aContext
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &aArguments) override
virtual css::uno::Any SAL_CALL execute(const css::ucb::Command &aCommand, sal_Int32 CommandId, const css::uno::Reference< css::ucb::XCommandEnvironment > &Environment) override
virtual void SAL_CALL removeContentEventListener(const css::uno::Reference< css::ucb::XContentEventListener > &Listener) override
virtual void SAL_CALL addPropertiesChangeListener(const css::uno::Sequence< OUString > &PropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener > &Listener) override
virtual OUString SAL_CALL getImplementationName() override
virtual void SAL_CALL addProperty(const OUString &Name, sal_Int16 Attributes, const css::uno::Any &DefaultValue) override
virtual css::uno::Reference< css::ucb::XContentIdentifier > SAL_CALL getIdentifier() override
OContentHelper(const css::uno::Reference< css::uno::XComponentContext > &_xORB, const css::uno::Reference< css::uno::XInterface > &_xParentContainer, TContentPtr _pImpl)
virtual void SAL_CALL abort(sal_Int32 CommandId) override
virtual OUString SAL_CALL getContentType() override
virtual void SAL_CALL removePropertiesChangeListener(const css::uno::Sequence< OUString > &PropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener > &Listener) override
PropertyChangeListenerContainer m_aPropertyChangeListeners
void impl_rename_throw(const OUString &_sNewName, bool _bNotify=true)
virtual void SAL_CALL rename(const OUString &newName) override
css::uno::Reference< css::uno::XInterface > m_xParentContainer
virtual void SAL_CALL removeProperty(const OUString &Name) override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
css::uno::Reference< css::sdbc::XRow > getPropertyValues(const css::uno::Sequence< css::beans::Property > &rProperties)
int nCount
Reference< XComponentContext > m_aContext
Listeners aListeners
#define TOOLS_WARN_EXCEPTION(area, stream)
Reference< XContent > m_xParentContainer
std::mutex m_aMutex
sal_Int64 n
@ Exception
std::shared_ptr< OContentHelper_Impl > TContentPtr
void notifyDataSourceModified(const css::uno::Reference< css::uno::XInterface > &_rxObject)
::cppu::WeakComponentImplHelper< css::ucb::XContent, css::ucb::XCommandProcessor, css::lang::XServiceInfo, css::beans::XPropertiesChangeNotifier, css::beans::XPropertyContainer, css::lang::XInitialization, css::container::XChild, css::sdbcx::XRename > OContentHelper_COMPBASE
std::set< PropertyValue, PropertyValueLess > PropertyValueSet
OUString newName(std::u16string_view aNewPrefix, std::u16string_view aOldPrefix, std::u16string_view old_Name)
std::unordered_map< XPropertiesChangeListenerPtr, PropertyEventSequence, hashPtr, equalPtr > PropertiesEventListenerMap
void cancelCommandExecution(const uno::Any &rException, const uno::Reference< ucb::XCommandEnvironment > &xEnv)
#define PROPERTY_ID_NAME
constexpr OUStringLiteral PROPERTY_PERSISTENT_NAME(u"PersistentName")
constexpr OUStringLiteral PROPERTY_NAME(u"Name")
OUString aCommand
unsigned char sal_Bool