LibreOffice Module sw (master)  1
vbatablehelper.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 <vbahelper/vbahelper.hxx>
21 #include "vbatablehelper.hxx"
22 #include <swtable.hxx>
23 #include <unotbl.hxx>
24 #include <docsh.hxx>
25 
26 using namespace ::com::sun::star;
27 using namespace ::ooo::vba;
28 
29 #define UNO_TABLE_COLUMN_SUM 10000
30 
31 SwVbaTableHelper::SwVbaTableHelper( const uno::Reference< text::XTextTable >& xTextTable ) : mxTextTable( xTextTable )
32 {
34 }
35 
36 SwTable* SwVbaTableHelper::GetSwTable( const uno::Reference< text::XTextTable >& xTextTable )
37 {
38  uno::Reference< lang::XUnoTunnel > xTunnel( xTextTable, uno::UNO_QUERY_THROW );
39  SwXTextTable* pXTextTable = reinterpret_cast< SwXTextTable * >( sal::static_int_cast< sal_IntPtr >(xTunnel->getSomething(SwXTextTable::getUnoTunnelId())));
40  if( !pXTextTable )
41  throw uno::RuntimeException();
42 
43  SwFrameFormat* pFrameFormat = pXTextTable->GetFrameFormat();
44  if( !pFrameFormat )
45  throw uno::RuntimeException();
46 
47  SwTable* pTable = SwTable::FindTable( pFrameFormat );
48  return pTable;
49 }
50 
51 sal_Int32 SwVbaTableHelper::getTabColumnsCount( sal_Int32 nRowIndex )
52 {
53  sal_Int32 nRet = 0;
54  if(!pTable->IsTableComplex())
55  {
56  SwTableLines& rLines = pTable->GetTabLines();
57  SwTableLine* pLine = rLines[ nRowIndex ];
58  nRet = pLine->GetTabBoxes().size();
59  }
60  return nRet;
61 }
62 
64 {
65  sal_Int32 nRet = 0;
66  sal_Int32 nRowCount = pTable->GetTabLines().size();
67  for( sal_Int32 index = 0; index < nRowCount; index++ )
68  {
69  sal_Int32 nColCount = getTabColumnsCount( index );
70  if( nRet < nColCount )
71  nRet = nColCount;
72  }
73  return nRet;
74 }
75 
76 sal_Int32 SwVbaTableHelper::getTabRowIndex( const OUString& rCellName )
77 {
78  sal_Int32 nRet = 0;
79  SwTableBox* pBox = const_cast<SwTableBox*>(pTable->GetTableBox( rCellName ));
80  if( !pBox )
81  throw uno::RuntimeException();
82 
83  const SwTableLine* pLine = pBox->GetUpper();
84  const SwTableLines* pLines = pLine->GetUpper()
85  ? &pLine->GetUpper()->GetTabLines() : &pTable->GetTabLines();
86  nRet = pLines->GetPos( pLine );
87  return nRet;
88 }
89 
90 sal_Int32 SwVbaTableHelper::getTabColIndex( const OUString& rCellName )
91 {
92  const SwTableBox* pBox = pTable->GetTableBox( rCellName );
93  if( !pBox )
94  throw uno::RuntimeException();
95  return pBox->GetUpper()->GetBoxPos( pBox );
96 }
97 
98 OUString SwVbaTableHelper::getColumnStr( sal_Int32 nCol )
99 {
100  const sal_Int32 coDiff = 52; // 'A'-'Z' 'a' - 'z'
101  sal_Int32 nCalc = 0;
102 
103  OUString sRet;
104  do{
105  nCalc = nCol % coDiff;
106  if( nCalc >= 26 )
107  sRet = OUStringLiteral1( 'a' - 26 + nCalc ) + sRet;
108  else
109  sRet = OUStringLiteral1( 'A' + nCalc ) + sRet;
110 
111  if( 0 == ( nCol = nCol - nCalc ) )
112  break;
113  nCol /= coDiff;
114  --nCol;
115  }while(true);
116  return sRet;
117 }
118 
120 {
121  sal_Int32 nWidth = 0;
122  bool isWidthRelatvie = false;
123  uno::Reference< beans::XPropertySet > xTableProps( mxTextTable, uno::UNO_QUERY_THROW );
124  xTableProps->getPropertyValue("IsWidthRelative") >>= isWidthRelatvie;
125  if( isWidthRelatvie )
126  {
127  xTableProps->getPropertyValue("RelativeWidth") >>= nWidth;
128  }
129  else
130  {
131  xTableProps->getPropertyValue("Width") >>= nWidth;
132  }
133  return nWidth;
134 }
135 
136 SwTableBox* SwVbaTableHelper::GetTabBox( sal_Int32 nCol, sal_Int32 nRow )
137 {
138  SwTableLines& rLines = pTable->GetTabLines();
139  sal_Int32 nRowCount = rLines.size();
140  if (nRow < 0 || nRow >= nRowCount)
141  throw uno::RuntimeException();
142 
143  SwTableLine* pLine = rLines[ nRow ];
144  sal_Int32 nColCount = pLine->GetTabBoxes().size();
145  if (nCol < 0 || nCol >= nColCount)
146  throw uno::RuntimeException();
147 
148  SwTableBox* pStart = pLine->GetTabBoxes()[ nCol ];
149 
150  if( !pStart )
151  throw uno::RuntimeException();
152 
153  return pStart;
154 }
155 
157 {
158  rCols.SetLeftMin ( 0 );
159  rCols.SetLeft ( 0 );
160  rCols.SetRight ( UNO_TABLE_COLUMN_SUM );
162  pTable->GetTabCols( rCols, pStart );
163 }
164 
165 sal_Int32 SwVbaTableHelper::GetColCount( SwTabCols const & rCols )
166 {
167  sal_Int32 nCount = 0;
168  for( size_t i = 0; i < rCols.Count(); ++i )
169  if(rCols.IsHidden(i))
170  nCount ++;
171  return rCols.Count() - nCount;
172 }
173 
174 sal_Int32 SwVbaTableHelper::GetRightSeparator( SwTabCols const & rCols, sal_Int32 nNum)
175 {
176  OSL_ENSURE( nNum < GetColCount( rCols ) ,"Index out of range");
177  sal_Int32 i = 0;
178  while( nNum >= 0 )
179  {
180  if( !rCols.IsHidden(i) )
181  nNum--;
182  i++;
183  }
184  return i - 1;
185 }
186 
187 sal_Int32 SwVbaTableHelper::GetColWidth( sal_Int32 nCol, sal_Int32 nRow )
188 {
189  SwTableBox* pStart = GetTabBox( nCol, nRow );
190  SwTabCols aCols;
191  InitTabCols( aCols, pStart );
192  sal_Int32 nWidth = GetColWidth( aCols, nCol );
193 
194  sal_Int32 nTableWidth = getTableWidth( );
195  double dAbsWidth = ( static_cast<double>(nWidth) / UNO_TABLE_COLUMN_SUM ) * static_cast<double>(nTableWidth);
196  return static_cast<sal_Int32>(Millimeter::getInPoints( static_cast<int>(dAbsWidth) ));
197 }
198 
199 sal_Int32 SwVbaTableHelper::GetColWidth( SwTabCols& rCols, sal_Int32 nNum )
200 {
201  SwTwips nWidth = 0;
202 
203  if( rCols.Count() > 0 )
204  {
205  if(rCols.Count() == static_cast<size_t>(GetColCount( rCols )))
206  {
207  if(static_cast<size_t>(nNum) == rCols.Count())
208  nWidth = rCols.GetRight() - rCols[nNum-1];
209  else
210  {
211  nWidth = rCols[nNum];
212  if(nNum == 0)
213  nWidth -= rCols.GetLeft();
214  else
215  nWidth -= rCols[nNum-1];
216  }
217  }
218  else
219  {
220  SwTwips nRValid = nNum < GetColCount( rCols ) ?
221  rCols[GetRightSeparator( rCols, nNum )]:
222  rCols.GetRight();
223  SwTwips nLValid = nNum ?
224  rCols[GetRightSeparator( rCols, nNum - 1 )]:
225  rCols.GetLeft();
226  nWidth = nRValid - nLValid;
227  }
228  }
229  else
230  nWidth = rCols.GetRight();
231 
232  return nWidth;
233 }
234 
235 void SwVbaTableHelper::SetColWidth( sal_Int32 _width, sal_Int32 nCol, sal_Int32 nRow, bool bCurRowOnly )
236 {
237  double dAbsWidth = Millimeter::getInHundredthsOfOneMillimeter( _width );
238  sal_Int32 nTableWidth = getTableWidth( );
239  if (!nTableWidth)
240  throw uno::RuntimeException();
241  sal_Int32 nNewWidth = dAbsWidth/nTableWidth * UNO_TABLE_COLUMN_SUM;
242 
243  SwTableBox* pStart = GetTabBox( nCol, nRow );
244  SwTabCols aOldCols;
245  InitTabCols( aOldCols, pStart );
246 
247  SwTabCols aCols( aOldCols );
248  if ( aCols.Count() > 0 )
249  {
250  SwTwips nWidth = GetColWidth( aCols, nCol);
251 
252  int nDiff = nNewWidth - nWidth;
253  if( !nCol )
254  aCols[ GetRightSeparator(aCols, 0) ] += nDiff;
255  else if( nCol < GetColCount( aCols ) )
256  {
257  if(nDiff < GetColWidth( aCols, nCol + 1) - MINLAY)
258  aCols[ GetRightSeparator( aCols, nCol ) ] += nDiff;
259  else
260  {
261  int nDiffLeft = nDiff - static_cast<int>(GetColWidth( aCols, nCol + 1)) + int(MINLAY);
262  aCols[ GetRightSeparator( aCols, nCol ) ] += (nDiff - nDiffLeft);
263  aCols[ GetRightSeparator( aCols, nCol - 1 ) ] -= nDiffLeft;
264  }
265  }
266  else
267  aCols[ GetRightSeparator( aCols, nCol-1 ) ] -= nDiff;
268  }
269  else
270  aCols.SetRight( std::min( static_cast<long>(nNewWidth), aCols.GetRightMax()) );
271 
272  pTable->SetTabCols(aCols, aOldCols, pStart, bCurRowOnly );
273 }
274 
275 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool IsTableComplex() const
Definition: swtable.cxx:1445
const int nColCount
sal_Int32 getTableWidth()
const SwTableBox * GetTableBox(const OUString &rName, const bool bPerformValidCheck=false) const
Definition: swtable.cxx:1344
#define MINLAY
Definition: swtypes.hxx:66
long GetRightMax() const
Definition: tabcol.hxx:79
static sal_Int32 GetColWidth(SwTabCols &rCols, sal_Int32 nNum)
SwTableBox * GetTabBox(sal_Int32 nCol, sal_Int32 nRow)
SwTableLine is one table row in the document model.
Definition: swtable.hxx:344
long SwTwips
Definition: swtypes.hxx:49
#define UNO_TABLE_COLUMN_SUM
size_type size() const
Definition: swtable.hxx:74
void InitTabCols(SwTabCols &rCols, const SwTableBox *pStart)
sal_Int32 getTabColIndex(const OUString &sCellName)
void SetColWidth(sal_Int32 _width, sal_Int32 nCol, sal_Int32 nRow=0, bool bCurRowOnly=false)
long GetRight() const
Definition: tabcol.hxx:78
void GetTabCols(SwTabCols &rToFill, const SwTableBox *pStart, bool bHidden=false, bool bCurRowOnly=false) const
Definition: swtable.cxx:528
static sal_Int32 GetRightSeparator(SwTabCols const &rCols, sal_Int32 nNum)
sal_Int32 getTabColumnsCount(sal_Int32 nRowIndex)
void SetTabCols(const SwTabCols &rNew, const SwTabCols &rOld, const SwTableBox *pStart, bool bCurRowOnly)
Definition: swtable.cxx:833
bool IsHidden(size_t nPos) const
Definition: tabcol.hxx:66
static SwTable * FindTable(SwFrameFormat const *const pFormat)
Definition: swtable.cxx:1920
Style of a layout element.
Definition: frmfmt.hxx:57
css::uno::Reference< css::text::XTextTable > mxTextTable
int i
void SetLeft(long nNew)
Definition: tabcol.hxx:82
static OUString getColumnStr(sal_Int32 nCol)
sal_Int32 getTabColumnsMaxCount()
tuple index
sal_uInt16 GetBoxPos(const SwTableBox *pBox) const
Definition: swtable.hxx:356
SwTableLines & GetTabLines()
Definition: swtable.hxx:198
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:110
void SetRightMax(long nNew)
Definition: tabcol.hxx:84
SwTableLines & GetTabLines()
Definition: swtable.hxx:418
SwTableBoxes & GetTabBoxes()
Definition: swtable.hxx:354
void SetLeftMin(long nNew)
Definition: tabcol.hxx:81
SwVbaTableHelper(const css::uno::Reference< css::text::XTextTable > &xTextTable)
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:386
static sal_Int32 GetColCount(SwTabCols const &rCols)
SwTableBox * GetUpper()
Definition: swtable.hxx:362
static SwTable * GetSwTable(const css::uno::Reference< css::text::XTextTable > &xTextTable)
sal_uInt16 GetPos(const SwTableLine *pBox) const
Definition: swtable.hxx:96
sal_Int32 getTabRowIndex(const OUString &sCellName)
void SetRight(long nNew)
Definition: tabcol.hxx:83
SwTableLine * GetUpper()
Definition: swtable.hxx:421
static SW_DLLPUBLIC const css::uno::Sequence< sal_Int8 > & getUnoTunnelId()
Definition: unotbl.cxx:2014
long GetLeft() const
Definition: tabcol.hxx:77
size_t Count() const
Definition: tabcol.hxx:64
SW_DLLPUBLIC SwFrameFormat * GetFrameFormat()
Definition: unotbl.cxx:2057