LibreOffice Module svx (master)  1
unomtabl.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 <sal/config.h>
21 
22 #include <memory>
23 #include <set>
24 #include <com/sun/star/lang/XServiceInfo.hpp>
25 #include <com/sun/star/container/XNameContainer.hpp>
26 #include <com/sun/star/drawing/PointSequence.hpp>
27 
28 #include <comphelper/sequence.hxx>
29 #include <cppuhelper/implbase.hxx>
31 #include <svl/itempool.hxx>
32 #include <svl/itemset.hxx>
33 #include <svl/lstner.hxx>
34 #include <svx/xlnedit.hxx>
35 #include <svx/xlnstit.hxx>
36 #include <svx/svdmodel.hxx>
37 #include <svx/xdef.hxx>
38 
39 #include <vector>
40 #include <vcl/svapp.hxx>
41 
42 
43 #include <svx/unofill.hxx>
44 
45 #include <svx/unoapi.hxx>
46 
47 using namespace ::com::sun::star;
48 using namespace ::cppu;
49 
50 typedef std::vector<std::unique_ptr<SfxItemSet>> ItemPoolVector;
51 
52 namespace {
53 
54 class SvxUnoMarkerTable : public WeakImplHelper< container::XNameContainer, lang::XServiceInfo >,
55  public SfxListener
56 {
57 private:
58  SdrModel* mpModel;
59  SfxItemPool* mpModelPool;
60 
61  ItemPoolVector maItemSetVector;
62 
63 public:
64  explicit SvxUnoMarkerTable( SdrModel* pModel ) throw();
65  virtual ~SvxUnoMarkerTable() throw() override;
66 
67  void dispose();
68 
69  // SfxListener
70  virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) throw () override;
71 
72  void ImplInsertByName( const OUString& aName, const uno::Any& aElement );
73 
74  // XServiceInfo
75  virtual OUString SAL_CALL getImplementationName( ) override;
76  virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
77  virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
78 
79  // XNameContainer
80  virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override;
81  virtual void SAL_CALL removeByName( const OUString& Name ) override;
82 
83  // XNameReplace
84  virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override;
85 
86  // XNameAccess
87  virtual uno::Any SAL_CALL getByName( const OUString& aName ) override;
88  virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override;
89  virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
90 
91  // XElementAccess
92  virtual uno::Type SAL_CALL getElementType( ) override;
93  virtual sal_Bool SAL_CALL hasElements( ) override;
94 };
95 
96 }
97 
98 SvxUnoMarkerTable::SvxUnoMarkerTable( SdrModel* pModel ) throw()
99 : mpModel( pModel ),
100  mpModelPool( pModel ? &pModel->GetItemPool() : nullptr )
101 {
102  if( pModel )
103  StartListening( *pModel );
104 }
105 
106 SvxUnoMarkerTable::~SvxUnoMarkerTable() throw()
107 {
108  if( mpModel )
109  EndListening( *mpModel );
110  dispose();
111 }
112 
113 void SvxUnoMarkerTable::dispose()
114 {
115  maItemSetVector.clear();
116 }
117 
118 // SfxListener
119 void SvxUnoMarkerTable::Notify( SfxBroadcaster&, const SfxHint& rHint ) throw()
120 {
121  if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint)
122  {
123  const SdrHint* pSdrHint = static_cast<const SdrHint*>(&rHint);
124  if( SdrHintKind::ModelCleared == pSdrHint->GetKind() )
125  dispose();
126  }
127 }
128 
129 sal_Bool SAL_CALL SvxUnoMarkerTable::supportsService( const OUString& ServiceName )
130 {
131  return cppu::supportsService(this, ServiceName);
132 }
133 
134 OUString SAL_CALL SvxUnoMarkerTable::getImplementationName()
135 {
136  return "SvxUnoMarkerTable";
137 }
138 
139 uno::Sequence< OUString > SAL_CALL SvxUnoMarkerTable::getSupportedServiceNames( )
140 {
141  uno::Sequence<OUString> aSNS { "com.sun.star.drawing.MarkerTable" };
142  return aSNS;
143 }
144 
145 void SvxUnoMarkerTable::ImplInsertByName( const OUString& aName, const uno::Any& aElement )
146 {
147  maItemSetVector.push_back(
148  std::make_unique<SfxItemSet>( *mpModelPool, svl::Items<XATTR_LINESTART, XATTR_LINEEND>{} ));
149  auto pInSet = maItemSetVector.back().get();
150 
151  XLineEndItem aEndMarker(XATTR_LINEEND);
152  aEndMarker.SetName( aName );
153  aEndMarker.PutValue( aElement, 0 );
154 
155  pInSet->Put( aEndMarker );
156 
157  XLineStartItem aStartMarker(XATTR_LINESTART);
158  aStartMarker.SetName( aName );
159  aStartMarker.PutValue( aElement, 0 );
160 
161  pInSet->Put( aStartMarker );
162 }
163 
164 // XNameContainer
165 void SAL_CALL SvxUnoMarkerTable::insertByName( const OUString& aApiName, const uno::Any& aElement )
166 {
167  SolarMutexGuard aGuard;
168 
169  if( hasByName( aApiName ) )
170  throw container::ElementExistException();
171 
172  OUString aName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aApiName);
173 
174  ImplInsertByName( aName, aElement );
175 }
176 
177 void SAL_CALL SvxUnoMarkerTable::removeByName( const OUString& aApiName )
178 {
179  SolarMutexGuard aGuard;
180 
181  // a little quickfix for 2.0 to let applications clear api
182  // created items that are not used
183  if ( aApiName == "~clear~" )
184  {
185  dispose();
186  return;
187  }
188 
189  OUString aName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aApiName);
190 
191  auto aIter = std::find_if(maItemSetVector.begin(), maItemSetVector.end(),
192  [&aName](const std::unique_ptr<SfxItemSet>& rpItem) {
193  const NameOrIndex *pItem = &(rpItem->Get( XATTR_LINEEND ) );
194  return pItem->GetName() == aName;
195  });
196  if (aIter != maItemSetVector.end())
197  {
198  maItemSetVector.erase( aIter );
199  return;
200  }
201 
202  if( !hasByName( aName ) )
203  throw container::NoSuchElementException();
204 }
205 
206 // XNameReplace
207 void SAL_CALL SvxUnoMarkerTable::replaceByName( const OUString& aApiName, const uno::Any& aElement )
208 {
209  SolarMutexGuard aGuard;
210 
211  const OUString aName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aApiName);
212 
213  auto aIter = std::find_if(maItemSetVector.begin(), maItemSetVector.end(),
214  [&aName](const std::unique_ptr<SfxItemSet>& rpItem) {
215  const NameOrIndex *pItem = &(rpItem->Get( XATTR_LINEEND ) );
216  return pItem->GetName() == aName;
217  });
218  if (aIter != maItemSetVector.end())
219  {
220  XLineEndItem aEndMarker(XATTR_LINEEND);
221  aEndMarker.SetName( aName );
222  if( !aEndMarker.PutValue( aElement, 0 ) )
223  throw lang::IllegalArgumentException();
224 
225  (*aIter)->Put( aEndMarker );
226 
227  XLineStartItem aStartMarker(XATTR_LINESTART);
228  aStartMarker.SetName( aName );
229  aStartMarker.PutValue( aElement, 0 );
230 
231  (*aIter)->Put( aStartMarker );
232  return;
233  }
234 
235  // if it is not in our own sets, modify the pool!
236  bool bFound = false;
237 
238  if (mpModelPool)
239  for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINESTART))
240  {
241  NameOrIndex *pItem = const_cast<NameOrIndex*>(static_cast<const NameOrIndex*>(p));
242  if( pItem && pItem->GetName() == aName )
243  {
244  pItem->PutValue( aElement, 0 );
245  bFound = true;
246  break;
247  }
248  }
249 
250  if (mpModelPool)
251  for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINEEND))
252  {
253  NameOrIndex *pItem = const_cast<NameOrIndex*>(static_cast<const NameOrIndex*>(p));
254  if( pItem && pItem->GetName() == aName )
255  {
256  pItem->PutValue( aElement, 0 );
257  bFound = true;
258  break;
259  }
260  }
261 
262  if( !bFound )
263  throw container::NoSuchElementException();
264 
265  ImplInsertByName( aName, aElement );
266 }
267 
268 static bool getByNameFromPool( const OUString& rSearchName, SfxItemPool const * pPool, sal_uInt16 nWhich, uno::Any& rAny )
269 {
270  if (pPool)
271  for (const SfxPoolItem* p : pPool->GetItemSurrogates(nWhich))
272  {
273  const NameOrIndex *pItem = static_cast<const NameOrIndex*>(p);
274 
275  if( pItem && pItem->GetName() == rSearchName )
276  {
277  pItem->QueryValue( rAny );
278  return true;
279  }
280  }
281 
282  return false;
283 }
284 
285 // XNameAccess
286 uno::Any SAL_CALL SvxUnoMarkerTable::getByName( const OUString& aApiName )
287 {
288  SolarMutexGuard aGuard;
289 
290  OUString aName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aApiName);
291 
292  uno::Any aAny;
293 
294  if (mpModelPool && !aName.isEmpty())
295  {
296  do
297  {
298  if (getByNameFromPool(aName, mpModelPool, XATTR_LINESTART, aAny))
299  break;
300 
301  if (getByNameFromPool(aName, mpModelPool, XATTR_LINEEND, aAny))
302  break;
303 
304  throw container::NoSuchElementException();
305  }
306  while(false);
307  }
308 
309  return aAny;
310 }
311 
312 static void createNamesForPool( SfxItemPool const * pPool, sal_uInt16 nWhich, std::set< OUString >& rNameSet )
313 {
314  for (const SfxPoolItem* p : pPool->GetItemSurrogates(nWhich))
315  {
316  const NameOrIndex* pItem = static_cast<const NameOrIndex*>(p);
317 
318  if( pItem == nullptr || pItem->GetName().isEmpty() )
319  continue;
320 
321  OUString aName = SvxUnogetApiNameForItem(XATTR_LINEEND, pItem->GetName());
322  rNameSet.insert( aName );
323  }
324 }
325 
326 uno::Sequence< OUString > SAL_CALL SvxUnoMarkerTable::getElementNames()
327 {
328  SolarMutexGuard aGuard;
329 
330  std::set< OUString > aNameSet;
331 
332  // search model pool for line starts
333  createNamesForPool( mpModelPool, XATTR_LINESTART, aNameSet );
334 
335  // search model pool for line ends
336  createNamesForPool( mpModelPool, XATTR_LINEEND, aNameSet );
337 
338  return comphelper::containerToSequence(aNameSet);
339 }
340 
341 sal_Bool SAL_CALL SvxUnoMarkerTable::hasByName( const OUString& aName )
342 {
343  SolarMutexGuard aGuard;
344 
345  if( aName.isEmpty() )
346  return false;
347 
348  OUString aSearchName;
349 
350  const NameOrIndex *pItem;
351 
352  aSearchName = SvxUnogetInternalNameForItem(XATTR_LINESTART, aName);
353  if (mpModelPool)
354  for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINESTART))
355  {
356  pItem = static_cast<const NameOrIndex*>(p);
357  if( pItem && pItem->GetName() == aSearchName )
358  return true;
359  }
360 
361  aSearchName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aName);
362  if (mpModelPool)
363  for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINEEND))
364  {
365  pItem = static_cast<const NameOrIndex*>(p);
366  if( pItem && pItem->GetName() == aSearchName )
367  return true;
368  }
369 
370  return false;
371 }
372 
373 // XElementAccess
374 uno::Type SAL_CALL SvxUnoMarkerTable::getElementType( )
375 {
377 }
378 
379 sal_Bool SAL_CALL SvxUnoMarkerTable::hasElements( )
380 {
381  SolarMutexGuard aGuard;
382 
383  const NameOrIndex *pItem;
384 
385  if (mpModelPool)
386  for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINESTART))
387  {
388  pItem = static_cast<const NameOrIndex*>(p);
389  if( pItem && !pItem->GetName().isEmpty() )
390  return true;
391  }
392 
393  if (mpModelPool)
394  for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINEEND))
395  {
396  pItem = static_cast<const NameOrIndex*>(p);
397  if( pItem && !pItem->GetName().isEmpty() )
398  return true;
399  }
400 
401  return false;
402 }
403 
407 uno::Reference< uno::XInterface > SvxUnoMarkerTable_createInstance( SdrModel* pModel )
408 {
409  return *new SvxUnoMarkerTable(pModel);
410 }
411 
412 
413 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual bool PutValue(const css::uno::Any &rVal, sal_uInt8 nMemberId) override
constexpr TypedWhichId< XLineEndItem > XATTR_LINEEND(XATTR_LINE_FIRST+5)
SdrHintKind GetKind() const
Definition: svdmodel.hxx:124
constexpr TypedWhichId< XLineStartItem > XATTR_LINESTART(XATTR_LINE_FIRST+4)
uno::Reference< uno::XInterface > SvxUnoMarkerTable_createInstance(SdrModel *pModel)
Create a hatchtable.
Definition: unomtabl.cxx:407
OUString SvxUnogetApiNameForItem(const sal_uInt16 nWhich, const OUString &rInternalName)
if the given name is a predefined name for the current language it is replaced by the corresponding a...
Definition: unoprov.cxx:1951
OUString Name
static void createNamesForPool(SfxItemPool const *pPool, sal_uInt16 nWhich, std::set< OUString > &rNameSet)
Definition: unomtabl.cxx:312
std::vector< std::unique_ptr< SfxItemSet > > ItemPoolVector
Definition: unomtabl.cxx:50
OUString SvxUnogetInternalNameForItem(const sal_uInt16 nWhich, const OUString &rApiName)
if the given name is a predefined api name it is replaced by the predefined name for the current lang...
Definition: unoprov.cxx:1984
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
virtual css::uno::Type SAL_CALL getElementType() override
Definition: unomod.cxx:583
unsigned char sal_Bool
css::uno::Type const & get()
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: unomod.cxx:652
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: unomod.cxx:647
virtual OUString SAL_CALL getImplementationName() override
Definition: unomod.cxx:642
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
OUString aName
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
void * p
void Notify(SwFlyFrame *pFly, SwPageFrame *pOld, const SwRect &rOld, const SwRect *pOldPrt)
OUString const & GetName() const
Definition: xit.hxx:52
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const override
void dispose()
virtual sal_Bool SAL_CALL hasElements() override
Definition: unomod.cxx:588
static bool getByNameFromPool(const OUString &rSearchName, SfxItemPool const *pPool, sal_uInt16 nWhich, uno::Any &rAny)
Definition: unomtabl.cxx:268