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  {
210  sal_Int32 nTmp;
211  if (!(aValue >>= nTmp) || nTmp < 0)
212  throw css::lang::IllegalArgumentException();
213  m_nSepLineWidth = o3tl::toTwips(nTmp, o3tl::Length::mm100);
214  break;
215  }
216  case WID_TXTCOL_LINE_COLOR:
217  if (!(aValue >>= m_nSepLineColor))
218  throw css::lang::IllegalArgumentException();
219  break;
220  case WID_TXTCOL_LINE_STYLE:
221  if (!(aValue >>= m_nSepLineStyle))
222  throw css::lang::IllegalArgumentException();
223  break;
224  case WID_TXTCOL_LINE_REL_HGT:
225  {
226  sal_Int32 nTmp;
227  if (!(aValue >>= nTmp) || nTmp < 0)
228  throw css::lang::IllegalArgumentException();
229  m_nSepLineHeightRelative = nTmp;
230  break;
231  }
232  case WID_TXTCOL_LINE_ALIGN:
233  if (css::style::VerticalAlignment eAlign; aValue >>= eAlign)
234  m_nSepLineVertAlign = eAlign;
235  else if (sal_Int8 nTmp; aValue >>= nTmp)
236  m_nSepLineVertAlign = static_cast<css::style::VerticalAlignment>(nTmp);
237  else
238  throw css::lang::IllegalArgumentException();
239  break;
240  case WID_TXTCOL_LINE_IS_ON:
241  if (!(aValue >>= m_bSepLineIsOn))
242  throw css::lang::IllegalArgumentException();
243  break;
244  case WID_TXTCOL_AUTO_DISTANCE:
245  {
246  sal_Int32 nTmp;
247  if (!(aValue >>= nTmp) || nTmp < 0 || nTmp >= m_nReference)
248  throw css::lang::IllegalArgumentException();
249  m_nAutoDistance = nTmp;
250  sal_Int32 nColumns = m_aTextColumns.getLength();
251  css::text::TextColumn* pCols = m_aTextColumns.getArray();
252  sal_Int32 nDist = m_nAutoDistance / 2;
253  for (sal_Int32 i = 0; i < nColumns; i++)
254  {
255  pCols[i].LeftMargin = i == 0 ? 0 : nDist;
256  pCols[i].RightMargin = i == nColumns - 1 ? 0 : nDist;
257  }
258  break;
259  }
260  }
261 }
262 
263 css::uno::Any SvxXTextColumns::getPropertyValue(const OUString& rPropertyName)
264 {
265  const SfxItemPropertyMapEntry* pEntry = m_aPropSet.getPropertyMap().getByName(rPropertyName);
266  if (!pEntry)
267  throw css::beans::UnknownPropertyException("Unknown property: " + rPropertyName,
268  static_cast<cppu::OWeakObject*>(this));
269 
270  css::uno::Any aRet;
271  switch (pEntry->nWID)
272  {
273  case WID_TXTCOL_LINE_WIDTH:
274  aRet <<= o3tl::narrowing<sal_Int32>(convertTwipToMm100(m_nSepLineWidth));
275  break;
276  case WID_TXTCOL_LINE_COLOR:
277  aRet <<= m_nSepLineColor;
278  break;
279  case WID_TXTCOL_LINE_STYLE:
280  aRet <<= m_nSepLineStyle;
281  break;
282  case WID_TXTCOL_LINE_REL_HGT:
283  aRet <<= m_nSepLineHeightRelative;
284  break;
285  case WID_TXTCOL_LINE_ALIGN:
286  aRet <<= m_nSepLineVertAlign;
287  break;
288  case WID_TXTCOL_LINE_IS_ON:
289  aRet <<= m_bSepLineIsOn;
290  break;
291  case WID_TXTCOL_IS_AUTOMATIC:
292  aRet <<= m_bIsAutomaticWidth;
293  break;
294  case WID_TXTCOL_AUTO_DISTANCE:
295  aRet <<= m_nAutoDistance;
296  break;
297  }
298  return aRet;
299 }
300 
301 void SvxXTextColumns::addPropertyChangeListener(
302  const OUString& /*rPropertyName*/,
303  const css::uno::Reference<css::beans::XPropertyChangeListener>& /*xListener*/)
304 {
305 }
306 
307 void SvxXTextColumns::removePropertyChangeListener(
308  const OUString& /*rPropertyName*/,
309  const css::uno::Reference<css::beans::XPropertyChangeListener>& /*xListener*/)
310 {
311 }
312 
313 void SvxXTextColumns::addVetoableChangeListener(
314  const OUString& /*rPropertyName*/,
315  const css::uno::Reference<css::beans::XVetoableChangeListener>& /*xListener*/)
316 {
317 }
318 
319 void SvxXTextColumns::removeVetoableChangeListener(
320  const OUString& /*rPropertyName*/,
321  const css::uno::Reference<css::beans::XVetoableChangeListener>& /*xListener*/)
322 {
323 }
324 }
325 
326 css::uno::Reference<css::uno::XInterface> SvxXTextColumns_createInstance() noexcept
327 {
328  return static_cast<cppu::OWeakObject*>(new SvxXTextColumns);
329 }
330 
331 extern "C" SVXCORE_DLLPUBLIC css::uno::XInterface*
333  css::uno::Sequence<css::uno::Any> const&)
334 {
335  return cppu::acquire(new SvxXTextColumns);
336 }
337 
338 /* 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