LibreOffice Module svx (master)  1
SvxXTextColumns.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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 <com/sun/star/beans/PropertyAttribute.hpp>
23 #include <com/sun/star/beans/PropertyVetoException.hpp>
24 #include <com/sun/star/beans/UnknownPropertyException.hpp>
25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/lang/IllegalArgumentException.hpp>
27 #include <com/sun/star/lang/XServiceInfo.hpp>
28 #include <com/sun/star/style/VerticalAlignment.hpp>
29 #include <com/sun/star/text/ColumnSeparatorStyle.hpp>
30 #include <com/sun/star/text/XTextColumns.hpp>
31 #include <com/sun/star/uno/Any.h>
32 #include <com/sun/star/util/Color.hpp>
33 
35 #include <o3tl/safeint.hxx>
36 #include <svl/itemprop.hxx>
37 #include <svx/SvxXTextColumns.hxx>
38 #include <tools/UnitConversion.hxx>
39 #include <vcl/svapp.hxx>
40 
41 #include <numeric>
42 
43 namespace
44 {
45 enum : sal_uInt16
46 {
47  WID_TXTCOL_IS_AUTOMATIC,
48  WID_TXTCOL_AUTO_DISTANCE,
49  WID_TXTCOL_LINE_WIDTH,
50  WID_TXTCOL_LINE_COLOR,
51  WID_TXTCOL_LINE_REL_HGT,
52  WID_TXTCOL_LINE_ALIGN,
53  WID_TXTCOL_LINE_IS_ON,
54  WID_TXTCOL_LINE_STYLE,
55 };
56 
57 SfxItemPropertyMapEntry const saTextColumns_Impl[] = {
58  { u"IsAutomatic", WID_TXTCOL_IS_AUTOMATIC, cppu::UnoType<bool>::get(),
59  css::beans::PropertyAttribute::READONLY, 0 },
60  { u"AutomaticDistance", WID_TXTCOL_AUTO_DISTANCE, cppu::UnoType<sal_Int32>::get(), 0, 0 },
61  { u"SeparatorLineWidth", WID_TXTCOL_LINE_WIDTH, cppu::UnoType<sal_Int32>::get(), 0, 0 },
62  { u"SeparatorLineColor", WID_TXTCOL_LINE_COLOR,
64  { u"SeparatorLineRelativeHeight", WID_TXTCOL_LINE_REL_HGT, cppu::UnoType<sal_Int32>::get(), 0,
65  0 },
66  { u"SeparatorLineVerticalAlignment", WID_TXTCOL_LINE_ALIGN,
68  { u"SeparatorLineIsOn", WID_TXTCOL_LINE_IS_ON, cppu::UnoType<bool>::get(), 0, 0 },
69  { u"SeparatorLineStyle", WID_TXTCOL_LINE_STYLE, cppu::UnoType<sal_Int16>::get(), 0, 0 },
70  { u"", 0, css::uno::Type(), 0, 0 },
71 };
72 
73 class SvxXTextColumns final
74  : public cppu::WeakImplHelper<css::beans::XPropertySet, css::text::XTextColumns,
75  css::lang::XServiceInfo>
76 {
77 public:
78  SvxXTextColumns() = default;
79 
80  // XTextColumns
81  virtual sal_Int32 SAL_CALL getReferenceValue() override;
82  virtual sal_Int16 SAL_CALL getColumnCount() override;
83  virtual void SAL_CALL setColumnCount(sal_Int16 nColumns) override;
84  virtual css::uno::Sequence<css::text::TextColumn> SAL_CALL getColumns() override;
85  virtual void SAL_CALL
86  setColumns(const css::uno::Sequence<css::text::TextColumn>& Columns) override;
87 
88  // XPropertySet
89  virtual css::uno::Reference<css::beans::XPropertySetInfo>
90  SAL_CALL getPropertySetInfo() override;
91  virtual void SAL_CALL setPropertyValue(const OUString& aPropertyName,
92  const css::uno::Any& aValue) override;
93  virtual css::uno::Any SAL_CALL getPropertyValue(const OUString& PropertyName) override;
94  virtual void SAL_CALL addPropertyChangeListener(
95  const OUString& aPropertyName,
96  const css::uno::Reference<css::beans::XPropertyChangeListener>& xListener) override;
97  virtual void SAL_CALL removePropertyChangeListener(
98  const OUString& aPropertyName,
99  const css::uno::Reference<css::beans::XPropertyChangeListener>& aListener) override;
100  virtual void SAL_CALL addVetoableChangeListener(
101  const OUString& PropertyName,
102  const css::uno::Reference<css::beans::XVetoableChangeListener>& aListener) override;
103  virtual void SAL_CALL removeVetoableChangeListener(
104  const OUString& PropertyName,
105  const css::uno::Reference<css::beans::XVetoableChangeListener>& aListener) override;
106 
107  // XServiceInfo
108  virtual OUString SAL_CALL getImplementationName() override;
109  virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
110  virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
111 
112 private:
113  sal_Int32 m_nReference = USHRT_MAX;
114  css::uno::Sequence<css::text::TextColumn> m_aTextColumns;
115  bool m_bIsAutomaticWidth = true;
116  sal_Int32 m_nAutoDistance = 0;
117 
118  const SfxItemPropertySet m_aPropSet = { saTextColumns_Impl };
119 
120  //separator line
121  sal_Int32 m_nSepLineWidth = 0;
122  com::sun::star::util::Color m_nSepLineColor = 0; // black
123  sal_Int32 m_nSepLineHeightRelative = 100; // full height
124  css::style::VerticalAlignment m_nSepLineVertAlign = css::style::VerticalAlignment_MIDDLE;
125  bool m_bSepLineIsOn = false;
126  sal_Int16 m_nSepLineStyle = css::text::ColumnSeparatorStyle::NONE;
127 };
128 
129 OUString SvxXTextColumns::getImplementationName() { return "com.sun.star.comp.svx.TextColumns"; }
130 
131 sal_Bool SvxXTextColumns::supportsService(const OUString& rServiceName)
132 {
133  return cppu::supportsService(this, rServiceName);
134 }
135 
136 css::uno::Sequence<OUString> SvxXTextColumns::getSupportedServiceNames()
137 {
138  return { "com.sun.star.text.TextColumns" };
139 }
140 
141 sal_Int32 SvxXTextColumns::getReferenceValue()
142 {
143  SolarMutexGuard aGuard;
144  return m_nReference;
145 }
146 
147 sal_Int16 SvxXTextColumns::getColumnCount()
148 {
149  SolarMutexGuard aGuard;
150  return o3tl::narrowing<sal_Int16>(m_aTextColumns.getLength());
151 }
152 
153 void SvxXTextColumns::setColumnCount(sal_Int16 nColumns)
154 {
155  SolarMutexGuard aGuard;
156  if (nColumns <= 0)
157  throw css::uno::RuntimeException();
158  m_bIsAutomaticWidth = true;
159  m_aTextColumns.realloc(nColumns);
160  css::text::TextColumn* pCols = m_aTextColumns.getArray();
161  m_nReference = USHRT_MAX;
162  sal_Int32 nWidth = m_nReference / nColumns;
163  sal_Int32 nDiff = m_nReference - nWidth * nColumns;
164  sal_Int32 nDist = m_nAutoDistance / 2;
165  for (sal_Int16 i = 0; i < nColumns; i++)
166  {
167  pCols[i].Width = nWidth;
168  pCols[i].LeftMargin = i == 0 ? 0 : nDist;
169  pCols[i].RightMargin = i == nColumns - 1 ? 0 : nDist;
170  }
171  pCols[nColumns - 1].Width += nDiff;
172 }
173 
174 css::uno::Sequence<css::text::TextColumn> SvxXTextColumns::getColumns()
175 {
176  SolarMutexGuard aGuard;
177  return m_aTextColumns;
178 }
179 
180 void SvxXTextColumns::setColumns(const css::uno::Sequence<css::text::TextColumn>& rColumns)
181 {
182  SolarMutexGuard aGuard;
183  sal_Int32 nReferenceTemp = std::accumulate(
184  rColumns.begin(), rColumns.end(), sal_Int32(0),
185  [](const sal_Int32 nSum, const css::text::TextColumn& rCol) { return nSum + rCol.Width; });
186  m_bIsAutomaticWidth = false;
187  m_nReference = !nReferenceTemp ? USHRT_MAX : nReferenceTemp;
188  m_aTextColumns = rColumns;
189 }
190 
191 css::uno::Reference<css::beans::XPropertySetInfo> SvxXTextColumns::getPropertySetInfo()
192 {
193  return m_aPropSet.getPropertySetInfo();
194 }
195 
196 void SvxXTextColumns::setPropertyValue(const OUString& rPropertyName, const css::uno::Any& aValue)
197 {
198  const SfxItemPropertyMapEntry* pEntry = m_aPropSet.getPropertyMap().getByName(rPropertyName);
199  if (!pEntry)
200  throw css::beans::UnknownPropertyException("Unknown property: " + rPropertyName,
201  static_cast<cppu::OWeakObject*>(this));
202  if (pEntry->nFlags & css::beans::PropertyAttribute::READONLY)
203  throw css::beans::PropertyVetoException("Property is read-only: " + rPropertyName,
204  static_cast<cppu::OWeakObject*>(this));
205 
206  switch (pEntry->nWID)
207  {
208  case WID_TXTCOL_LINE_WIDTH:
209  if (sal_Int32 nTmp; !(aValue >>= nTmp) || nTmp < 0)
210  throw css::lang::IllegalArgumentException();
211  else
212  m_nSepLineWidth = o3tl::toTwips(nTmp, o3tl::Length::mm100);
213  break;
214  case WID_TXTCOL_LINE_COLOR:
215  if (!(aValue >>= m_nSepLineColor))
216  throw css::lang::IllegalArgumentException();
217  break;
218  case WID_TXTCOL_LINE_STYLE:
219  if (!(aValue >>= m_nSepLineStyle))
220  throw css::lang::IllegalArgumentException();
221  break;
222  case WID_TXTCOL_LINE_REL_HGT:
223  if (sal_Int32 nTmp; !(aValue >>= nTmp) || nTmp < 0)
224  throw css::lang::IllegalArgumentException();
225  else
226  m_nSepLineHeightRelative = nTmp;
227  break;
228  case WID_TXTCOL_LINE_ALIGN:
229  if (css::style::VerticalAlignment eAlign; aValue >>= eAlign)
230  m_nSepLineVertAlign = eAlign;
231  else if (sal_Int8 nTmp; aValue >>= nTmp)
232  m_nSepLineVertAlign = static_cast<css::style::VerticalAlignment>(nTmp);
233  else
234  throw css::lang::IllegalArgumentException();
235  break;
236  case WID_TXTCOL_LINE_IS_ON:
237  if (!(aValue >>= m_bSepLineIsOn))
238  throw css::lang::IllegalArgumentException();
239  break;
240  case WID_TXTCOL_AUTO_DISTANCE:
241  if (sal_Int32 nTmp; !(aValue >>= nTmp) || nTmp < 0 || nTmp >= m_nReference)
242  throw css::lang::IllegalArgumentException();
243  else
244  {
245  m_nAutoDistance = nTmp;
246  sal_Int32 nColumns = m_aTextColumns.getLength();
247  css::text::TextColumn* pCols = m_aTextColumns.getArray();
248  sal_Int32 nDist = m_nAutoDistance / 2;
249  for (sal_Int32 i = 0; i < nColumns; i++)
250  {
251  pCols[i].LeftMargin = i == 0 ? 0 : nDist;
252  pCols[i].RightMargin = i == nColumns - 1 ? 0 : nDist;
253  }
254  }
255  break;
256  }
257 }
258 
259 css::uno::Any SvxXTextColumns::getPropertyValue(const OUString& rPropertyName)
260 {
261  const SfxItemPropertyMapEntry* pEntry = m_aPropSet.getPropertyMap().getByName(rPropertyName);
262  if (!pEntry)
263  throw css::beans::UnknownPropertyException("Unknown property: " + rPropertyName,
264  static_cast<cppu::OWeakObject*>(this));
265 
266  css::uno::Any aRet;
267  switch (pEntry->nWID)
268  {
269  case WID_TXTCOL_LINE_WIDTH:
270  aRet <<= o3tl::narrowing<sal_Int32>(convertTwipToMm100(m_nSepLineWidth));
271  break;
272  case WID_TXTCOL_LINE_COLOR:
273  aRet <<= m_nSepLineColor;
274  break;
275  case WID_TXTCOL_LINE_STYLE:
276  aRet <<= m_nSepLineStyle;
277  break;
278  case WID_TXTCOL_LINE_REL_HGT:
279  aRet <<= m_nSepLineHeightRelative;
280  break;
281  case WID_TXTCOL_LINE_ALIGN:
282  aRet <<= m_nSepLineVertAlign;
283  break;
284  case WID_TXTCOL_LINE_IS_ON:
285  aRet <<= m_bSepLineIsOn;
286  break;
287  case WID_TXTCOL_IS_AUTOMATIC:
288  aRet <<= m_bIsAutomaticWidth;
289  break;
290  case WID_TXTCOL_AUTO_DISTANCE:
291  aRet <<= m_nAutoDistance;
292  break;
293  }
294  return aRet;
295 }
296 
297 void SvxXTextColumns::addPropertyChangeListener(
298  const OUString& /*rPropertyName*/,
299  const css::uno::Reference<css::beans::XPropertyChangeListener>& /*xListener*/)
300 {
301 }
302 
303 void SvxXTextColumns::removePropertyChangeListener(
304  const OUString& /*rPropertyName*/,
305  const css::uno::Reference<css::beans::XPropertyChangeListener>& /*xListener*/)
306 {
307 }
308 
309 void SvxXTextColumns::addVetoableChangeListener(
310  const OUString& /*rPropertyName*/,
311  const css::uno::Reference<css::beans::XVetoableChangeListener>& /*xListener*/)
312 {
313 }
314 
315 void SvxXTextColumns::removeVetoableChangeListener(
316  const OUString& /*rPropertyName*/,
317  const css::uno::Reference<css::beans::XVetoableChangeListener>& /*xListener*/)
318 {
319 }
320 }
321 
322 css::uno::Reference<css::uno::XInterface> SvxXTextColumns_createInstance() noexcept
323 {
324  return static_cast<cppu::OWeakObject*>(new SvxXTextColumns);
325 }
326 
327 extern "C" SVXCORE_DLLPUBLIC css::uno::XInterface*
329  css::uno::Sequence<css::uno::Any> const&)
330 {
331  return cppu::acquire(new SvxXTextColumns);
332 }
333 
334 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
constexpr auto toTwips(N number, Length from)
signed char sal_Int8
SVXCORE_DLLPUBLIC css::uno::XInterface * com_sun_star_comp_svx_TextColumns_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
css::uno::Reference< css::uno::XInterface > SvxXTextColumns_createInstance() noexcept
constexpr auto convertTwipToMm100(N n)
bool getPropertyValue(ValueType &rValue, css::uno::Reference< css::beans::XPropertySet > const &xPropSet, OUString const &propName)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
float u
unsigned char sal_Bool
css::uno::Type const & get()
bool setPropertyValue(uno::Sequence< beans::PropertyValue > &aProp, const OUString &aName, const uno::Any &aValue)
#define SVXCORE_DLLPUBLIC
Definition: svxdllapi.h:35