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 .
23 #include <svl/itempool.hxx>
24 #include <svl/itemset.hxx>
25 #include <svl/style.hxx>
26 #include <comphelper/profilezone.hxx>
27 #include <comphelper/sequence.hxx>
28 #include <cppuhelper/supportsservice.hxx>
30 #include <svx/svdmodel.hxx>
31 #include "UnoNameItemTable.hxx"
32 #include <vcl/svapp.hxx>
34 #include <svx/unoapi.hxx>
37 using namespace ::com::sun::star
;
38 using namespace ::cppu
;
40 SvxUnoNameItemTable::SvxUnoNameItemTable( SdrModel
* pModel
, sal_uInt16 nWhich
, sal_uInt8 nMemberId
) throw()
42 mpModelPool( pModel
? &pModel
->GetItemPool() : nullptr ),
43 mnWhich( nWhich
), mnMemberId( nMemberId
)
46 StartListening( *pModel
);
49 SvxUnoNameItemTable::~SvxUnoNameItemTable() throw()
52 EndListening( *mpModel
);
56 bool SvxUnoNameItemTable::isValid( const NameOrIndex
* pItem
) const
58 return pItem
&& !pItem
->GetName().isEmpty();
61 void SvxUnoNameItemTable::dispose()
63 maItemSetVector
.clear();
66 void SvxUnoNameItemTable::Notify( SfxBroadcaster
&, const SfxHint
& rHint
) throw()
68 if (rHint
.GetId() != SfxHintId::ThisIsAnSdrHint
)
70 const SdrHint
* pSdrHint
= static_cast<const SdrHint
*>(&rHint
);
71 if( SdrHintKind::ModelCleared
== pSdrHint
->GetKind() )
75 sal_Bool SAL_CALL
SvxUnoNameItemTable::supportsService( const OUString
& ServiceName
)
77 return cppu::supportsService(this, ServiceName
);
80 void SvxUnoNameItemTable::ImplInsertByName( const OUString
& aName
, const uno::Any
& aElement
)
82 maItemSetVector
.push_back( std::make_unique
< SfxItemSet
>( *mpModelPool
, std::initializer_list
<SfxItemSet::Pair
>{{mnWhich
, mnWhich
}} ) );
84 std::unique_ptr
<NameOrIndex
> xNewItem(createItem());
85 xNewItem
->SetName(aName
);
86 xNewItem
->PutValue(aElement
, mnMemberId
);
87 xNewItem
->SetWhich(mnWhich
);
88 maItemSetVector
.back()->Put(*xNewItem
);
92 void SAL_CALL
SvxUnoNameItemTable::insertByName( const OUString
& aApiName
, const uno::Any
& aElement
)
94 SolarMutexGuard aGuard
;
95 comphelper::ProfileZone
aZone("SvxUnoNameItemTable::insertByName");
97 if( hasByName( aApiName
) )
98 throw container::ElementExistException();
100 OUString aName
= SvxUnogetInternalNameForItem(mnWhich
, aApiName
);
102 ImplInsertByName( aName
, aElement
);
106 void SAL_CALL
SvxUnoNameItemTable::removeByName( const OUString
& aApiName
)
108 SolarMutexGuard aGuard
;
109 comphelper::ProfileZone
aZone("SvxUnoNameItemTable::removeByName");
111 // a little quickfix for 2.0 to let applications clear api
112 // created items that are not used
113 if ( aApiName
== "~clear~" )
119 OUString sName
= SvxUnogetInternalNameForItem(mnWhich
, aApiName
);
121 auto aIter
= std::find_if(maItemSetVector
.begin(), maItemSetVector
.end(),
122 [&](const std::unique_ptr
<SfxItemSet
>& rpItem
) {
123 const NameOrIndex
*pItem
= static_cast<const NameOrIndex
*>(&(rpItem
->Get( mnWhich
) ));
124 return sName
== pItem
->GetName();
126 if (aIter
!= maItemSetVector
.end())
128 maItemSetVector
.erase( aIter
);
132 if (!hasByName(sName
))
133 throw container::NoSuchElementException();
137 void SAL_CALL
SvxUnoNameItemTable::replaceByName( const OUString
& aApiName
, const uno::Any
& aElement
)
139 SolarMutexGuard aGuard
;
141 OUString aName
= SvxUnogetInternalNameForItem(mnWhich
, aApiName
);
143 auto aIter
= std::find_if(maItemSetVector
.begin(), maItemSetVector
.end(),
144 [&](const std::unique_ptr
<SfxItemSet
>& rpItem
) {
145 const NameOrIndex
*pItem
= static_cast<const NameOrIndex
*>(&(rpItem
->Get( mnWhich
) ));
146 return aName
== pItem
->GetName();
148 if (aIter
!= maItemSetVector
.end())
150 std::unique_ptr
<NameOrIndex
> xNewItem(createItem());
151 xNewItem
->SetName(aName
);
152 if (!xNewItem
->PutValue(aElement
, mnMemberId
) || !isValid(xNewItem
.get()))
153 throw lang::IllegalArgumentException();
154 (*aIter
)->Put(*xNewItem
);
158 // if it is not in our own sets, modify the pool!
163 NameOrIndex
aSample(mnWhich
, aName
);
164 for (const SfxPoolItem
* pNameOrIndex
: mpModelPool
->FindItemSurrogate(mnWhich
, aSample
))
165 if (isValid(static_cast<const NameOrIndex
*>(pNameOrIndex
)))
167 const_cast<SfxPoolItem
*>(pNameOrIndex
)->PutValue( aElement
, mnMemberId
);
173 throw container::NoSuchElementException();
175 ImplInsertByName( aName
, aElement
);
177 if( !hasByName( aName
) )
178 throw container::NoSuchElementException();
182 uno::Any SAL_CALL
SvxUnoNameItemTable::getByName( const OUString
& aApiName
)
184 SolarMutexGuard aGuard
;
185 comphelper::ProfileZone
aZone("SvxUnoNameItemTable::getByName");
187 OUString aName
= SvxUnogetInternalNameForItem(mnWhich
, aApiName
);
189 if (mpModelPool
&& !aName
.isEmpty())
191 NameOrIndex
aSample(mnWhich
, aName
);
192 for (const SfxPoolItem
* pFindItem
: mpModelPool
->FindItemSurrogate(mnWhich
, aSample
))
193 if (isValid(static_cast<const NameOrIndex
*>(pFindItem
)))
196 pFindItem
->QueryValue( aAny
, mnMemberId
);
201 throw container::NoSuchElementException();
204 uno::Sequence
< OUString
> SAL_CALL
SvxUnoNameItemTable::getElementNames( )
206 SolarMutexGuard aGuard
;
208 std::set
< OUString
> aNameSet
;
212 for (const SfxPoolItem
* pItem
: mpModelPool
->GetItemSurrogates(mnWhich
))
214 const NameOrIndex
*pNameOrIndex
= static_cast<const NameOrIndex
*>(pItem
);
216 if( !isValid( pNameOrIndex
) )
219 OUString aApiName
= SvxUnogetApiNameForItem(mnWhich
, pNameOrIndex
->GetName());
220 aNameSet
.insert(aApiName
);
223 return comphelper::containerToSequence(aNameSet
);
226 sal_Bool SAL_CALL
SvxUnoNameItemTable::hasByName( const OUString
& aApiName
)
228 SolarMutexGuard aGuard
;
230 OUString aName
= SvxUnogetInternalNameForItem(mnWhich
, aApiName
);
238 NameOrIndex
aSample(mnWhich
, aName
);
239 for (const SfxPoolItem
* pFindItem
: mpModelPool
->FindItemSurrogate(mnWhich
, aSample
))
240 if (isValid(static_cast<const NameOrIndex
*>(pFindItem
)))
245 sal_Bool SAL_CALL
SvxUnoNameItemTable::hasElements( )
247 SolarMutexGuard aGuard
;
250 for (const SfxPoolItem
* pItem
: mpModelPool
->GetItemSurrogates(mnWhich
))
252 const NameOrIndex
*pNameOrIndex
= static_cast<const NameOrIndex
*>(pItem
);
254 if( isValid( pNameOrIndex
) )
261 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */