LibreOffice Module sw (master) 1
vbaborders.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#include "vbaborders.hxx"
20#include <ooo/vba/word/XBorder.hpp>
21#include <ooo/vba/word/WdBorderType.hpp>
22#include <ooo/vba/word/WdLineStyle.hpp>
23#include <sal/macros.h>
25#include <com/sun/star/beans/XPropertySet.hpp>
26#include <com/sun/star/table/TableBorder.hpp>
27#include <utility>
28#include "vbapalette.hxx"
29
30using namespace ::com::sun::star;
31using namespace ::ooo::vba;
32
33typedef ::cppu::WeakImplHelper<container::XIndexAccess > RangeBorders_Base;
35
36// #TODO sort these indexes to match the order in which Word iterates over the
37// borders, the enumeration will match the order in this list
38const sal_Int16 supportedIndexTable[] = { word::WdBorderType::wdBorderBottom, word::WdBorderType::wdBorderDiagonalDown, word::WdBorderType::wdBorderDiagonalUp, word::WdBorderType::wdBorderHorizontal, word::WdBorderType::wdBorderLeft, word::WdBorderType::wdBorderRight, word::WdBorderType::wdBorderTop, word::WdBorderType::wdBorderVertical };
39
40// Equiv widths in 1/100 mm
41const sal_Int32 OOLineHairline = 2;
42
43namespace {
44
45class SwVbaBorder : public SwVbaBorder_Base
46{
47private:
48 uno::Reference< beans::XPropertySet > m_xProps;
49 sal_Int32 m_LineType;
50 void setBorderLine( table::BorderLine const & rBorderLine )
51 {
52 table::TableBorder aTableBorder;
53 m_xProps->getPropertyValue( "TableBorder" ) >>= aTableBorder;
54
55 switch ( m_LineType )
56 {
57 case word::WdBorderType::wdBorderLeft:
58 aTableBorder.IsLeftLineValid = true;
59 aTableBorder.LeftLine= rBorderLine;
60 break;
61 case word::WdBorderType::wdBorderTop:
62 aTableBorder.IsTopLineValid = true;
63 aTableBorder.TopLine = rBorderLine;
64 break;
65
66 case word::WdBorderType::wdBorderBottom:
67 aTableBorder.IsBottomLineValid = true;
68 aTableBorder.BottomLine = rBorderLine;
69 break;
70 case word::WdBorderType::wdBorderRight:
71 aTableBorder.IsRightLineValid = true;
72 aTableBorder.RightLine = rBorderLine;
73 break;
74 case word::WdBorderType::wdBorderVertical:
75 aTableBorder.IsVerticalLineValid = true;
76 aTableBorder.VerticalLine = rBorderLine;
77 break;
78 case word::WdBorderType::wdBorderHorizontal:
79 aTableBorder.IsHorizontalLineValid = true;
80 aTableBorder.HorizontalLine = rBorderLine;
81 break;
82 case word::WdBorderType::wdBorderDiagonalDown:
83 case word::WdBorderType::wdBorderDiagonalUp:
84 // #TODO have to ignore at the moment, would be
85 // nice to investigate what we can do here
86 break;
87 default:
88 return;
89 }
90 m_xProps->setPropertyValue( "TableBorder", uno::Any(aTableBorder) );
91 }
92
93 bool getBorderLine( table::BorderLine& rBorderLine )
94 {
95 table::TableBorder aTableBorder;
96 m_xProps->getPropertyValue( "TableBorder" ) >>= aTableBorder;
97 switch ( m_LineType )
98 {
99 case word::WdBorderType::wdBorderLeft:
100 if ( aTableBorder.IsLeftLineValid )
101 rBorderLine = aTableBorder.LeftLine;
102 break;
103 case word::WdBorderType::wdBorderTop:
104 if ( aTableBorder.IsTopLineValid )
105 rBorderLine = aTableBorder.TopLine;
106 break;
107 case word::WdBorderType::wdBorderBottom:
108 if ( aTableBorder.IsBottomLineValid )
109 rBorderLine = aTableBorder.BottomLine;
110 break;
111 case word::WdBorderType::wdBorderRight:
112 if ( aTableBorder.IsRightLineValid )
113 rBorderLine = aTableBorder.RightLine;
114 break;
115 case word::WdBorderType::wdBorderVertical:
116 if ( aTableBorder.IsVerticalLineValid )
117 rBorderLine = aTableBorder.VerticalLine;
118 break;
119 case word::WdBorderType::wdBorderHorizontal:
120 if ( aTableBorder.IsHorizontalLineValid )
121 rBorderLine = aTableBorder.HorizontalLine;
122 break;
123
124 case word::WdBorderType::wdBorderDiagonalDown:
125 case word::WdBorderType::wdBorderDiagonalUp:
126 // #TODO have to ignore at the moment, would be
127 // nice to investigate what we can do here
128 break;
129 default:
130 return false;
131 }
132 return true;
133 }
134
135protected:
136 virtual OUString getServiceImplName() override
137 {
138 return "SwVbaBorder";
139 }
140
141 virtual css::uno::Sequence<OUString> getServiceNames() override
142 {
143 static uno::Sequence< OUString > const aServiceNames
144 {
145 "ooo.vba.word.Border"
146 };
147 return aServiceNames;
148 }
149public:
150 SwVbaBorder( const uno::Reference< beans::XPropertySet > & xProps, const uno::Reference< uno::XComponentContext >& xContext, sal_Int32 lineType ) : SwVbaBorder_Base( uno::Reference< XHelperInterface >( xProps, uno::UNO_QUERY ), xContext ), m_xProps( xProps ), m_LineType( lineType ) {}
151
152 uno::Any SAL_CALL getLineStyle() override
153 {
154 sal_Int32 nLineStyle = word::WdLineStyle::wdLineStyleNone;
155 table::BorderLine aBorderLine;
156 if ( getBorderLine( aBorderLine ) )
157 {
158 if( aBorderLine.InnerLineWidth !=0 && aBorderLine.OuterLineWidth !=0 )
159 {
160 nLineStyle = word::WdLineStyle::wdLineStyleDouble;
161 }
162 else if( aBorderLine.InnerLineWidth !=0 || aBorderLine.OuterLineWidth !=0 )
163 {
164 nLineStyle = word::WdLineStyle::wdLineStyleSingle;
165 }
166 else
167 {
168 nLineStyle = word::WdLineStyle::wdLineStyleNone;
169 }
170 }
171 return uno::Any( nLineStyle );
172 }
173 void SAL_CALL setLineStyle( const uno::Any& _linestyle ) override
174 {
175 // Urk no choice but to silently ignore we don't support this attribute
176 // #TODO would be nice to support the word line styles
177 sal_Int32 nLineStyle = 0;
178 _linestyle >>= nLineStyle;
179 table::BorderLine aBorderLine;
180 if ( !getBorderLine( aBorderLine ) )
181 throw uno::RuntimeException("Method failed" );
182
183 switch ( nLineStyle )
184 {
185 case word::WdLineStyle::wdLineStyleNone:
186 {
187 aBorderLine.InnerLineWidth = 0;
188 aBorderLine.OuterLineWidth = 0;
189 break;
190 }
191 case word::WdLineStyle::wdLineStyleDashDot:
192 case word::WdLineStyle::wdLineStyleDashDotDot:
193 case word::WdLineStyle::wdLineStyleDashDotStroked:
194 case word::WdLineStyle::wdLineStyleDashLargeGap:
195 case word::WdLineStyle::wdLineStyleDashSmallGap:
196 case word::WdLineStyle::wdLineStyleDot:
197 case word::WdLineStyle::wdLineStyleDouble:
198 case word::WdLineStyle::wdLineStyleDoubleWavy:
199 case word::WdLineStyle::wdLineStyleEmboss3D:
200 case word::WdLineStyle::wdLineStyleEngrave3D:
201 case word::WdLineStyle::wdLineStyleInset:
202 case word::WdLineStyle::wdLineStyleOutset:
203 case word::WdLineStyle::wdLineStyleSingle:
204 case word::WdLineStyle::wdLineStyleSingleWavy:
205 case word::WdLineStyle::wdLineStyleThickThinLargeGap:
206 case word::WdLineStyle::wdLineStyleThickThinMedGap:
207 case word::WdLineStyle::wdLineStyleThickThinSmallGap:
208 case word::WdLineStyle::wdLineStyleThinThickLargeGap:
209 case word::WdLineStyle::wdLineStyleThinThickMedGap:
210 case word::WdLineStyle::wdLineStyleThinThickSmallGap:
211 case word::WdLineStyle::wdLineStyleThinThickThinLargeGap:
212 case word::WdLineStyle::wdLineStyleThinThickThinMedGap:
213 case word::WdLineStyle::wdLineStyleThinThickThinSmallGap:
214 case word::WdLineStyle::wdLineStyleTriple:
215 {
216 aBorderLine.InnerLineWidth = 0;
217 aBorderLine.OuterLineWidth = OOLineHairline;
218 break;
219 }
220 default:
221 throw uno::RuntimeException("Bad param" );
222 }
223 setBorderLine( aBorderLine );
224
225 }
226};
227
228class RangeBorders : public RangeBorders_Base
229{
230private:
231 uno::Reference< table::XCellRange > m_xRange;
232 uno::Reference< uno::XComponentContext > m_xContext;
233 VbaPalette m_Palette;
234 sal_Int32 getTableIndex( sal_Int32 nConst )
235 {
236 // okay return position of the index in the table
237 sal_Int32 nIndexes = getCount();
238 sal_Int32 realIndex = 0;
239 const sal_Int16* pTableEntry = supportedIndexTable;
240 for ( ; realIndex < nIndexes; ++realIndex, ++pTableEntry )
241 {
242 if ( *pTableEntry == nConst )
243 return realIndex;
244 }
245 return getCount(); // error condition
246 }
247public:
248 RangeBorders( uno::Reference< table::XCellRange > xRange, uno::Reference< uno::XComponentContext > xContext, VbaPalette aPalette ) : m_xRange(std::move( xRange )), m_xContext(std::move( xContext )), m_Palette(std::move( aPalette ))
249 {
250 }
251 // XIndexAccess
252 virtual ::sal_Int32 SAL_CALL getCount( ) override
253 {
255 }
256 virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
257 {
258
259 sal_Int32 nIndex = getTableIndex( Index );
260 if ( nIndex >= 0 && nIndex < getCount() )
261 {
262 uno::Reference< beans::XPropertySet > xProps( m_xRange, uno::UNO_QUERY_THROW );
263 return uno::Any( uno::Reference< word::XBorder >( new SwVbaBorder( xProps, m_xContext, supportedIndexTable[ nIndex ] )) );
264 }
265 throw lang::IndexOutOfBoundsException();
266 }
267 virtual uno::Type SAL_CALL getElementType( ) override
268 {
270 }
271 virtual sal_Bool SAL_CALL hasElements( ) override
272 {
273 return true;
274 }
275};
276
277}
278
279static uno::Reference< container::XIndexAccess >
280rangeToBorderIndexAccess( const uno::Reference< table::XCellRange >& xRange, const uno::Reference< uno::XComponentContext > & xContext, VbaPalette const & rPalette )
281{
282 return new RangeBorders( xRange, xContext, rPalette );
283}
284
285namespace {
286
287class RangeBorderEnumWrapper : public EnumerationHelper_BASE
288{
289 uno::Reference<container::XIndexAccess > m_xIndexAccess;
290 sal_Int32 m_nIndex;
291public:
292 explicit RangeBorderEnumWrapper( uno::Reference< container::XIndexAccess > xIndexAccess ) : m_xIndexAccess(std::move( xIndexAccess )), m_nIndex( 0 ) {}
293 virtual sal_Bool SAL_CALL hasMoreElements( ) override
294 {
295 return ( m_nIndex < m_xIndexAccess->getCount() );
296 }
297
298 virtual uno::Any SAL_CALL nextElement( ) override
299 {
300 if ( m_nIndex < m_xIndexAccess->getCount() )
301 return m_xIndexAccess->getByIndex( m_nIndex++ );
302 throw container::NoSuchElementException();
303 }
304};
305
306}
307
308// for Table borders
309SwVbaBorders::SwVbaBorders( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< table::XCellRange >& xRange, VbaPalette const & rPalette ): SwVbaBorders_BASE( xParent, xContext, rangeToBorderIndexAccess( xRange ,xContext, rPalette ) )
310{
311 m_xProps.set( xRange, uno::UNO_QUERY_THROW );
312}
313
314uno::Reference< container::XEnumeration >
316{
317 return new RangeBorderEnumWrapper( m_xIndexAccess );
318}
319
321SwVbaBorders::createCollectionObject( const css::uno::Any& aSource )
322{
323 return aSource; // it's already a Border object
324}
325
328{
330}
331
333SwVbaBorders::getItemByIntIndex( const sal_Int32 nIndex )
334{
335 return createCollectionObject( m_xIndexAccess->getByIndex( nIndex ) );
336}
337
339{
340 // always return False for table border in MS Word
341 return false;
342}
343
344void SAL_CALL SwVbaBorders::setShadow( sal_Bool /*_shadow*/ )
345{
346 // not support in Table border in Word
347 // TODO:
348}
349
350OUString
352{
353 return "SwVbaBorders";
354}
355
356uno::Sequence< OUString >
358{
359 static uno::Sequence< OUString > const aServiceNames
360 {
361 "ooo.vba.word.Borders"
362 };
363 return aServiceNames;
364}
365
366/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
struct _ADOIndex Index
Reference< XPropertySet > m_xProps
Reference< XComponentContext > m_xContext
virtual css::uno::Sequence< OUString > getServiceNames()=0
css::uno::Reference< css::container::XIndexAccess > m_xIndexAccess
virtual css::uno::Sequence< OUString > getServiceNames() override
Definition: vbaborders.cxx:357
virtual css::uno::Any getItemByIntIndex(const sal_Int32 nIndex) override
Definition: vbaborders.cxx:333
virtual OUString getServiceImplName() override
Definition: vbaborders.cxx:351
SwVbaBorders(const css::uno::Reference< ov::XHelperInterface > &xParent, const css::uno::Reference< css::uno::XComponentContext > &xContext, const css::uno::Reference< css::table::XCellRange > &xRange, VbaPalette const &rPalette)
Definition: vbaborders.cxx:309
virtual css::uno::Type SAL_CALL getElementType() override
Definition: vbaborders.cxx:327
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
Definition: vbaborders.cxx:315
virtual css::uno::Any createCollectionObject(const css::uno::Any &aSource) override
Definition: vbaborders.cxx:321
virtual void SAL_CALL setShadow(sal_Bool _shadow) override
Definition: vbaborders.cxx:344
css::uno::Reference< css::beans::XPropertySet > m_xProps
Definition: vbaborders.hxx:34
virtual sal_Bool SAL_CALL getShadow() override
Definition: vbaborders.cxx:338
css::uno::Type const & get()
Sequence< OUString > aServiceNames
sal_Int32 nIndex
#define SAL_N_ELEMENTS(arr)
unsigned char sal_Bool
static uno::Reference< container::XIndexAccess > rangeToBorderIndexAccess(const uno::Reference< table::XCellRange > &xRange, const uno::Reference< uno::XComponentContext > &xContext, VbaPalette const &rPalette)
Definition: vbaborders.cxx:280
::cppu::WeakImplHelper< container::XIndexAccess > RangeBorders_Base
Definition: vbaborders.cxx:33
const sal_Int32 OOLineHairline
Definition: vbaborders.cxx:41
InheritedHelperInterfaceWeakImpl< word::XBorder > SwVbaBorder_Base
Definition: vbaborders.cxx:34
const sal_Int16 supportedIndexTable[]
Definition: vbaborders.cxx:38
::cppu::WeakImplHelper< css::container::XEnumeration > EnumerationHelper_BASE