LibreOffice Module svx (master)  1
xtable.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 <memory>
21 #include <svx/XPropertyTable.hxx>
22 #include <xmlxtexp.hxx>
23 #include <xmlxtimp.hxx>
24 #include <o3tl/safeint.hxx>
25 #include <tools/urlobj.hxx>
26 #include <svx/xtable.hxx>
27 #include <svx/xpool.hxx>
28 #include <svx/svdobj.hxx>
29 #include <svx/svdpool.hxx>
30 #include <vcl/outdev.hxx>
31 #include <tools/debug.hxx>
32 #include <stack>
33 
34 using namespace com::sun::star;
35 
36 XColorEntry::XColorEntry(const Color& rColor, const OUString& rName)
37 : XPropertyEntry(rName),
38  aColor(rColor)
39 {
40 }
41 
42 XLineEndEntry::XLineEndEntry(const basegfx::B2DPolyPolygon& rB2DPolyPolygon, const OUString& rName)
43 : XPropertyEntry(rName),
44  aB2DPolyPolygon(rB2DPolyPolygon)
45 {
46 }
47 
49 : XPropertyEntry(rOther),
50  aB2DPolyPolygon(rOther.aB2DPolyPolygon)
51 {
52 }
53 
54 XDashEntry::XDashEntry(const XDash& rDash, const OUString& rName)
55 : XPropertyEntry(rName),
56  aDash(rDash)
57 {
58 }
59 
61 : XPropertyEntry(rOther),
62 aDash(rOther.aDash)
63 {
64 }
65 
66 XHatchEntry::XHatchEntry(const XHatch& rHatch, const OUString& rName)
67 : XPropertyEntry(rName),
68  aHatch(rHatch)
69 {
70 }
71 
73 : XPropertyEntry(rOther),
74  aHatch(rOther.aHatch)
75 {
76 }
77 
78 XGradientEntry::XGradientEntry(const XGradient& rGradient, const OUString& rName)
79 : XPropertyEntry(rName),
80  aGradient(rGradient)
81 {
82 }
83 
85 : XPropertyEntry(rOther),
86  aGradient(rOther.aGradient)
87 {
88 }
89 
90 XBitmapEntry::XBitmapEntry(const GraphicObject& rGraphicObject, const OUString& rName)
91 : XPropertyEntry(rName),
92  maGraphicObject(rGraphicObject)
93 {
94 }
95 
97 : XPropertyEntry(rOther),
98  maGraphicObject(rOther.maGraphicObject)
99 {
100 }
101 
103  XPropertyListType type,
104  const OUString& rPath, const OUString& rReferer
105 ) : meType ( type ),
106  maName ( "standard" ),
107  maPath ( rPath ),
108  maReferer ( rReferer ),
109  mbListDirty ( true ),
110  mbEmbedInDocument( false )
111 {
112 // fprintf (stderr, "Create type %d count %d\n", (int)meType, count++);
113 }
114 
115 bool XPropertyList::isValidIdx(long nIndex) const
116 {
117  return (nIndex >= 0 && o3tl::make_unsigned(nIndex) < maList.size());
118 }
119 
120 
122 {
123 }
124 
126 {
127  if( mbListDirty )
128  {
129  if( !const_cast<XPropertyList*>(this)->Load() )
130  const_cast<XPropertyList*>(this)->Create();
131  }
132  return maList.size();
133 }
134 
135 XPropertyEntry* XPropertyList::Get( long nIndex ) const
136 {
137  if( mbListDirty )
138  {
139  if( !const_cast<XPropertyList*>(this)->Load() )
140  const_cast<XPropertyList*>(this)->Create();
141  }
142  if (!isValidIdx(nIndex))
143  return nullptr;
144 
145  return maList[nIndex].get();
146 }
147 
148 long XPropertyList::GetIndex(const OUString& rName) const
149 {
150  if( mbListDirty )
151  {
152  if( !const_cast<XPropertyList*>(this)->Load() )
153  const_cast<XPropertyList*>(this)->Create();
154  }
155 
156  for( long i = 0, n = maList.size(); i < n; ++i ) {
157  if (rName == maList[ i ]->GetName()) {
158  return i;
159  }
160  }
161  return -1;
162 }
163 
165 {
166  BitmapEx aRetval;
167  if (!isValidIdx(nIndex))
168  return aRetval;
169 
170  XPropertyEntry* pEntry = maList[nIndex].get();
171  aRetval = pEntry->GetUiBitmap();
172 
173  if(aRetval.IsEmpty())
174  {
175  aRetval = const_cast< XPropertyList* >(this)->CreateBitmapForUI(nIndex);
176  pEntry->SetUiBitmap(aRetval);
177  }
178  return aRetval;
179 }
180 
181 void XPropertyList::Insert(std::unique_ptr<XPropertyEntry> pEntry, long nIndex)
182 {
183  if (!pEntry)
184  {
185  assert(!"empty XPropertyEntry not allowed in XPropertyList");
186  return;
187  }
188 
189  if (isValidIdx(nIndex)) {
190  maList.insert( maList.begin()+nIndex, std::move(pEntry) );
191  } else {
192  maList.push_back( std::move(pEntry) );
193  }
194 }
195 
196 void XPropertyList::Replace(std::unique_ptr<XPropertyEntry> pEntry, long nIndex)
197 {
198  if (!pEntry)
199  {
200  assert(!"empty XPropertyEntry not allowed in XPropertyList");
201  return;
202  }
203  if (!isValidIdx(nIndex))
204  {
205  assert(!"trying to replace invalid entry in XPropertyList");
206  return;
207  }
208 
209  maList[nIndex] = std::move(pEntry);
210 }
211 
212 void XPropertyList::Remove(long nIndex)
213 {
214  if (!isValidIdx(nIndex))
215  {
216  assert(!"trying to remove invalid entry in XPropertyList");
217  return;
218  }
219 
220  maList.erase(maList.begin() + nIndex);
221 }
222 
223 void XPropertyList::SetName( const OUString& rString )
224 {
225  if(!rString.isEmpty())
226  {
227  maName = rString;
228  }
229 }
230 
232 {
233  if( mbListDirty )
234  {
235  mbListDirty = false;
236  std::stack<OUString> aDirs;
237 
238  sal_Int32 nIndex = 0;
239  do
240  {
241  aDirs.push(maPath.getToken(0, ';', nIndex));
242  }
243  while (nIndex >= 0);
244 
245  //try all entries palette path list working back to front until one
246  //succeeds
247  while (!aDirs.empty())
248  {
249  OUString aPath(aDirs.top());
250  aDirs.pop();
251 
252  INetURLObject aURL(aPath);
253 
254  if( INetProtocol::NotValid == aURL.GetProtocol() )
255  {
256  DBG_ASSERT( aPath.isEmpty(), "invalid URL" );
257  return false;
258  }
259 
260  aURL.Append( maName );
261 
262  if( aURL.getExtension().isEmpty() )
263  aURL.setExtension( GetDefaultExt() );
264 
266  maReferer, uno::Reference < embed::XStorage >(),
267  createInstance(), nullptr );
268  if (bRet)
269  return bRet;
270  }
271  }
272  return false;
273 }
274 
275 bool XPropertyList::LoadFrom( const uno::Reference < embed::XStorage > &xStorage,
276  const OUString &rURL, const OUString &rReferer )
277 {
278  if( !mbListDirty )
279  return false;
280  mbListDirty = false;
281  return SvxXMLXTableImport::load( rURL, rReferer, xStorage, createInstance(), &mbEmbedInDocument );
282 }
283 
285 {
286  //save to the last path in the palette path list
287  OUString aLastDir;
288  sal_Int32 nIndex = 0;
289  do
290  {
291  aLastDir = maPath.getToken(0, ';', nIndex);
292  }
293  while (nIndex >= 0);
294 
295  INetURLObject aURL(aLastDir);
296 
297  if( INetProtocol::NotValid == aURL.GetProtocol() )
298  {
299  DBG_ASSERT( aLastDir.isEmpty(), "invalid URL" );
300  return false;
301  }
302 
303  aURL.Append( maName );
304 
305  if( aURL.getExtension().isEmpty() )
306  aURL.setExtension( GetDefaultExt() );
307 
309  createInstance(),
310  uno::Reference< embed::XStorage >(), nullptr );
311 }
312 
313 bool XPropertyList::SaveTo( const uno::Reference< embed::XStorage > &xStorage,
314  const OUString &rURL, OUString *pOptName )
315 {
316  return SvxXMLXTableExportComponent::save( rURL, createInstance(), xStorage, pOptName );
317 }
318 
320  const OUString& rPath,
321  const OUString& rReferer )
322 {
323  XPropertyListRef pRet;
324 
325  switch (aType) {
327  pRet = XPropertyListRef(new XColorList(rPath, rReferer));
328  break;
330  pRet = XPropertyListRef(new XLineEndList(rPath, rReferer));
331  break;
333  pRet = XPropertyListRef(new XDashList(rPath, rReferer));
334  break;
336  pRet = XPropertyListRef(new XHatchList(rPath, rReferer));
337  break;
339  pRet = XPropertyListRef(new XGradientList(rPath, rReferer));
340  break;
342  pRet = XPropertyListRef(new XBitmapList(rPath, rReferer));
343  break;
345  pRet = XPropertyListRef(new XPatternList(rPath, rReferer));
346  break;
347  default:
348  OSL_FAIL("unknown xproperty type");
349  break;
350  }
351  OSL_ASSERT( !pRet.is() || pRet->meType == aType );
352 
353  return pRet;
354 }
355 
358  const OUString & rURLStr )
359 {
360  INetURLObject aURL( rURLStr );
361  INetURLObject aPathURL( aURL );
362 
363  aPathURL.removeSegment();
364  aPathURL.removeFinalSlash();
365 
368  pList->SetName( aURL.getName() );
369 
370  return pList;
371 }
372 
373 static struct {
375  const char *pExt;
376 } const pExtnMap[] = {
377  { XPropertyListType::Color, "soc" },
378  { XPropertyListType::LineEnd, "soe" },
379  { XPropertyListType::Dash, "sod" },
380  { XPropertyListType::Hatch, "soh" },
381  { XPropertyListType::Gradient, "sog" },
382  { XPropertyListType::Bitmap, "sob" },
384 };
385 
387 {
388  for (const auto & i : pExtnMap)
389  {
390  if( i.t == t )
391  return OUString::createFromAscii( i.pExt );
392  }
393  return OUString();
394 }
395 
396 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool LoadFrom(const css::uno::Reference< css::embed::XStorage > &xStorage, const OUString &rURL, const OUString &rReferer)
Definition: xtable.cxx:275
XPropertyEntry * Get(long nIndex) const
Definition: xtable.cxx:135
URL aURL
Any maPath
sal_Int32 nIndex
XBitmapEntry(const GraphicObject &rGraphicObject, const OUString &rName)
Definition: xtable.cxx:90
static bool save(const OUString &rURL, const css::uno::Reference< css::container::XNameContainer > &xTable, const css::uno::Reference< css::embed::XStorage > &xStorage, OUString *pOptName)
Definition: xmlxtexp.cxx:196
const OUString & GetName() const
Definition: xtable.hxx:186
OUString GetDefaultExt() const
Definition: xtable.hxx:197
sal_Int64 n
bool isValidIdx(long nIndex) const
Definition: xtable.cxx:115
XDashEntry(const XDash &rDash, const OUString &rName)
Definition: xtable.cxx:54
bool Load()
Definition: xtable.cxx:231
static bool load(const OUString &rPath, const OUString &rReferer, const css::uno::Reference< css::embed::XStorage > &xStorage, const css::uno::Reference< css::container::XNameContainer > &xTable, bool *bOptLoadedFromStorage)
Definition: xmlxtimp.cxx:352
virtual BitmapEx CreateBitmapForUI(long nIndex)=0
virtual bool Create()=0
XHatchEntry(const XHatch &rHatch, const OUString &rName)
Definition: xtable.cxx:66
void Insert(std::unique_ptr< XPropertyEntry > pEntry, long nIndex=std::numeric_limits< long >::max())
Definition: xtable.cxx:181
void Replace(std::unique_ptr< XPropertyEntry > pEntry, long nIndex)
Definition: xtable.cxx:196
Definition: xdash.hxx:31
XGradientEntry(const XGradient &rGradient, const OUString &rName)
Definition: xtable.cxx:78
bool setExtension(OUString const &rTheExtension, sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
XPropertyList(XPropertyListType t, const OUString &rPath, const OUString &rReferer)
Definition: xtable.cxx:102
OUString maName
Definition: xtable.hxx:157
OUString const maReferer
Definition: xtable.hxx:159
bool IsEmpty() const
XColorEntry(const Color &rColor, const OUString &rName)
Definition: xtable.cxx:36
XPropertyListType
Definition: xtable.hxx:131
#define DBG_ASSERT(sCon, aError)
bool Append(OUString const &rTheSegment, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
bool mbListDirty
Definition: xtable.hxx:163
OUString getName(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
int i
bool SaveTo(const css::uno::Reference< css::embed::XStorage > &xStorage, const OUString &rURL, OUString *pOptName)
Definition: xtable.cxx:313
void Remove(long nIndex)
Definition: xtable.cxx:212
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
static XPropertyListRef CreatePropertyList(XPropertyListType t, const OUString &rPath, const OUString &rReferer)
Definition: xtable.cxx:319
rtl::Reference< class XPropertyList > XPropertyListRef
Definition: xtable.hxx:143
bool removeFinalSlash()
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
void SetName(const OUString &rString)
Definition: xtable.cxx:223
XLineEndEntry(const basegfx::B2DPolyPolygon &rB2DPolyPolygon, const OUString &rName)
Definition: xtable.cxx:42
virtual ~XPropertyList() override
Definition: xtable.cxx:121
bool mbEmbedInDocument
Definition: xtable.hxx:164
const BitmapEx & GetUiBitmap() const
XPropertyListType const t
Definition: xtable.cxx:374
OUString maPath
Definition: xtable.hxx:158
OUString maName
static struct @1 pExtnMap[]
INetProtocol GetProtocol() const
long Count() const
Definition: xtable.cxx:125
BitmapEx GetUiBitmap(long nIndex) const
Definition: xtable.cxx:164
RedlineType const meType
const char * pExt
Definition: xtable.cxx:375
std::vector< std::unique_ptr< XPropertyEntry > > maList
Definition: xtable.hxx:161
long GetIndex(const OUString &rName) const
Definition: xtable.cxx:148
virtual css::uno::Reference< css::container::XNameContainer > createInstance()=0
void SetUiBitmap(const BitmapEx &rUiBitmap)
OUString getExtension(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
bool removeSegment(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true)
bool Save()
Definition: xtable.cxx:284
static XPropertyListRef CreatePropertyListFromURL(XPropertyListType t, const OUString &rUrl)
Definition: xtable.cxx:357