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 <uielement/constitemcontainer.hxx>
21 #include <uielement/itemcontainer.hxx>
22
23 #include <com/sun/star/beans/PropertyAttribute.hpp>
24 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
25
26 #include <comphelper/propertysetinfo.hxx>
27 #include <comphelper/servicehelper.hxx>
28 #include <rtl/ref.hxx>
29
30 using namespace cppu;
31 using namespace com::sun::star::uno;
32 using namespace com::sun::star::lang;
33 using namespace com::sun::star::beans;
34 using namespace com::sun::star::container;
35
36 const int PROPHANDLE_UINAME = 1;
37 constexpr OUStringLiteral PROPNAME_UINAME = u"UIName";
38
39 namespace framework
40 {
41
ConstItemContainer()42 ConstItemContainer::ConstItemContainer()
43 {
44 }
45
ConstItemContainer(const ItemContainer & rItemContainer)46 ConstItemContainer::ConstItemContainer( const ItemContainer& rItemContainer )
47 {
48 ShareGuard aLock( rItemContainer.m_aShareMutex );
49 copyItemContainer( rItemContainer.m_aItemVector );
50 }
51
ConstItemContainer(const Reference<XIndexAccess> & rSourceContainer,bool bFastCopy)52 ConstItemContainer::ConstItemContainer( const Reference< XIndexAccess >& rSourceContainer, bool bFastCopy )
53 {
54 // We also have to copy the UIName property
55 try
56 {
57 Reference< XPropertySet > xPropSet( rSourceContainer, UNO_QUERY );
58 if ( xPropSet.is() )
59 {
60 xPropSet->getPropertyValue("UIName") >>= m_aUIName;
61 }
62 }
63 catch ( const Exception& )
64 {
65 }
66
67 if ( !rSourceContainer.is() )
68 return;
69
70 try
71 {
72 sal_Int32 nCount = rSourceContainer->getCount();
73 m_aItemVector.reserve(nCount);
74 if ( bFastCopy )
75 {
76 for ( sal_Int32 i = 0; i < nCount; i++ )
77 {
78 Sequence< PropertyValue > aPropSeq;
79 if ( rSourceContainer->getByIndex( i ) >>= aPropSeq )
80 m_aItemVector.push_back( aPropSeq );
81 }
82 }
83 else
84 {
85 for ( sal_Int32 i = 0; i < nCount; i++ )
86 {
87 Sequence< PropertyValue > aPropSeq;
88 if ( rSourceContainer->getByIndex( i ) >>= aPropSeq )
89 {
90 sal_Int32 nContainerIndex = -1;
91 Reference< XIndexAccess > xIndexAccess;
92 for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
93 {
94 if ( aPropSeq[j].Name == "ItemDescriptorContainer" )
95 {
96 aPropSeq[j].Value >>= xIndexAccess;
97 nContainerIndex = j;
98 break;
99 }
100 }
101
102 if ( xIndexAccess.is() && nContainerIndex >= 0 )
103 aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess );
104
105 m_aItemVector.push_back( aPropSeq );
106 }
107 }
108 }
109 }
110 catch ( const IndexOutOfBoundsException& )
111 {
112 }
113 }
114
~ConstItemContainer()115 ConstItemContainer::~ConstItemContainer()
116 {
117 }
118
119 // private
copyItemContainer(const std::vector<Sequence<PropertyValue>> & rSourceVector)120 void ConstItemContainer::copyItemContainer( const std::vector< Sequence< PropertyValue > >& rSourceVector )
121 {
122 const sal_uInt32 nCount = rSourceVector.size();
123 for ( sal_uInt32 i = 0; i < nCount; i++ )
124 {
125 sal_Int32 nContainerIndex = -1;
126 Sequence< PropertyValue > aPropSeq( rSourceVector[i] );
127 Reference< XIndexAccess > xIndexAccess;
128 for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
129 {
130 if ( aPropSeq[j].Name == "ItemDescriptorContainer" )
131 {
132 aPropSeq[j].Value >>= xIndexAccess;
133 nContainerIndex = j;
134 break;
135 }
136 }
137
138 if ( xIndexAccess.is() && nContainerIndex >= 0 )
139 aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess );
140
141 m_aItemVector.push_back( aPropSeq );
142 }
143 }
144
deepCopyContainer(const Reference<XIndexAccess> & rSubContainer)145 Reference< XIndexAccess > ConstItemContainer::deepCopyContainer( const Reference< XIndexAccess >& rSubContainer )
146 {
147 Reference< XIndexAccess > xReturn;
148 if ( rSubContainer.is() )
149 {
150 ItemContainer* pSource = comphelper::getUnoTunnelImplementation<ItemContainer>( rSubContainer );
151 rtl::Reference<ConstItemContainer> pSubContainer;
152 if ( pSource )
153 pSubContainer = new ConstItemContainer( *pSource );
154 else
155 pSubContainer = new ConstItemContainer( rSubContainer );
156 xReturn = pSubContainer;
157 }
158
159 return xReturn;
160 }
161
162 // XUnoTunnel
getSomething(const css::uno::Sequence<sal_Int8> & rIdentifier)163 sal_Int64 ConstItemContainer::getSomething( const css::uno::Sequence< sal_Int8 >& rIdentifier )
164 {
165 if( isUnoTunnelId<ConstItemContainer>(rIdentifier) )
166 {
167 return reinterpret_cast< sal_Int64 >( this );
168 }
169 return 0;
170 }
171
getUnoTunnelId()172 const Sequence< sal_Int8 >& ConstItemContainer::getUnoTunnelId() noexcept
173 {
174 static const UnoTunnelIdInit theConstItemContainerUnoTunnelId;
175 return theConstItemContainerUnoTunnelId.getSeq();
176 }
177
178 // XElementAccess
hasElements()179 sal_Bool SAL_CALL ConstItemContainer::hasElements()
180 {
181 return ( !m_aItemVector.empty() );
182 }
183
184 // XIndexAccess
getCount()185 sal_Int32 SAL_CALL ConstItemContainer::getCount()
186 {
187 return m_aItemVector.size();
188 }
189
getByIndex(sal_Int32 Index)190 Any SAL_CALL ConstItemContainer::getByIndex( sal_Int32 Index )
191 {
192 if ( sal_Int32( m_aItemVector.size()) <= Index )
193 throw IndexOutOfBoundsException( OUString(), static_cast<OWeakObject *>(this) );
194 return makeAny( m_aItemVector[Index] );
195 }
196
197 // XPropertySet
getPropertySetInfo()198 Reference< XPropertySetInfo > SAL_CALL ConstItemContainer::getPropertySetInfo()
199 {
200 // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
201 // (Use method "getInfoHelper()".)
202 static Reference< XPropertySetInfo > xInfo(new comphelper::PropertySetInfo(getInfoHelper().getProperties()));
203
204 return xInfo;
205 }
206
setPropertyValue(const OUString &,const Any &)207 void SAL_CALL ConstItemContainer::setPropertyValue( const OUString&, const Any& )
208 {
209 }
210
getPropertyValue(const OUString & PropertyName)211 Any SAL_CALL ConstItemContainer::getPropertyValue( const OUString& PropertyName )
212 {
213 if ( PropertyName == PROPNAME_UINAME )
214 return makeAny( m_aUIName );
215
216 throw UnknownPropertyException(PropertyName);
217 }
218
addPropertyChangeListener(const OUString &,const css::uno::Reference<css::beans::XPropertyChangeListener> &)219 void SAL_CALL ConstItemContainer::addPropertyChangeListener( const OUString&, const css::uno::Reference< css::beans::XPropertyChangeListener >& )
220 {
221 }
222
removePropertyChangeListener(const OUString &,const css::uno::Reference<css::beans::XPropertyChangeListener> &)223 void SAL_CALL ConstItemContainer::removePropertyChangeListener( const OUString&, const css::uno::Reference< css::beans::XPropertyChangeListener >& )
224 {
225 // Only read-only properties - do nothing
226 }
227
addVetoableChangeListener(const OUString &,const css::uno::Reference<css::beans::XVetoableChangeListener> &)228 void SAL_CALL ConstItemContainer::addVetoableChangeListener( const OUString&, const css::uno::Reference< css::beans::XVetoableChangeListener >& )
229 {
230 // Only read-only properties - do nothing
231 }
232
removeVetoableChangeListener(const OUString &,const css::uno::Reference<css::beans::XVetoableChangeListener> &)233 void SAL_CALL ConstItemContainer::removeVetoableChangeListener( const OUString&, const css::uno::Reference< css::beans::XVetoableChangeListener >& )
234 {
235 // Only read-only properties - do nothing
236 }
237
238 // XFastPropertySet
setFastPropertyValue(sal_Int32,const css::uno::Any &)239 void SAL_CALL ConstItemContainer::setFastPropertyValue( sal_Int32, const css::uno::Any& )
240 {
241 }
242
getFastPropertyValue(sal_Int32 nHandle)243 Any SAL_CALL ConstItemContainer::getFastPropertyValue( sal_Int32 nHandle )
244 {
245 if ( nHandle == PROPHANDLE_UINAME )
246 return makeAny( m_aUIName );
247
248 throw UnknownPropertyException(OUString::number(nHandle));
249 }
250
getInfoHelper()251 ::cppu::IPropertyArrayHelper& ConstItemContainer::getInfoHelper()
252 {
253 // Define static member to give structure of properties to baseclass "OPropertySetHelper".
254 // "impl_getStaticPropertyDescriptor" is a non exported and static function, who will define a static propertytable.
255 // "true" say: Table is sorted by name.
256 static ::cppu::OPropertyArrayHelper ourInfoHelper( impl_getStaticPropertyDescriptor(), true );
257
258 return ourInfoHelper;
259 }
260
impl_getStaticPropertyDescriptor()261 css::uno::Sequence< css::beans::Property > ConstItemContainer::impl_getStaticPropertyDescriptor()
262 {
263 // Create a property array to initialize sequence!
264 // Table of all predefined properties of this class. It's used from OPropertySetHelper-class!
265 // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
266 // It's necessary for methods of OPropertySetHelper.
267 // ATTENTION:
268 // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
269
270 return
271 {
272 css::beans::Property( PROPNAME_UINAME, PROPHANDLE_UINAME ,
273 cppu::UnoType<OUString>::get(),
274 css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY )
275 };
276 }
277
278 } // namespace framework
279
280 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
281