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