Line data Source code
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 <list>
21 : #include <array>
22 : #include <utility>
23 : #include <vector>
24 : #include <algorithm>
25 :
26 : #include <svx/svxids.hrc>
27 : #include <editeng/memberids.hrc>
28 : #include <float.h>
29 : #include <swtypes.hxx>
30 : #include <cmdid.h>
31 : #include <unotbl.hxx>
32 : #include <unostyle.hxx>
33 : #include <section.hxx>
34 : #include <unocrsr.hxx>
35 : #include <svx/unomid.hxx>
36 : #include <hints.hxx>
37 : #include <swtblfmt.hxx>
38 : #include <doc.hxx>
39 : #include <IDocumentUndoRedo.hxx>
40 : #include <IDocumentContentOperations.hxx>
41 : #include <IDocumentFieldsAccess.hxx>
42 : #include <IDocumentState.hxx>
43 : #include <shellres.hxx>
44 : #include <docary.hxx>
45 : #include <ndole.hxx>
46 : #include <frame.hxx>
47 : #include <vcl/svapp.hxx>
48 : #include <fmtfsize.hxx>
49 : #include <tblafmt.hxx>
50 : #include <tabcol.hxx>
51 : #include <cellatr.hxx>
52 : #include <fmtpdsc.hxx>
53 : #include <pagedesc.hxx>
54 : #include <viewsh.hxx>
55 : #include <tabfrm.hxx>
56 : #include <redline.hxx>
57 : #include <unoport.hxx>
58 : #include <unoprnms.hxx>
59 : #include <unocrsrhelper.hxx>
60 : #include <com/sun/star/text/WrapTextMode.hpp>
61 : #include <com/sun/star/text/TextContentAnchorType.hpp>
62 : #include <com/sun/star/text/TableColumnSeparator.hpp>
63 : #include <com/sun/star/text/XTextSection.hpp>
64 : #include <com/sun/star/table/ShadowFormat.hpp>
65 : #include <com/sun/star/table/TableBorder.hpp>
66 : #include <com/sun/star/table/TableBorder2.hpp>
67 : #include <com/sun/star/table/BorderLine2.hpp>
68 : #include <com/sun/star/table/BorderLineStyle.hpp>
69 : #include <com/sun/star/table/TableBorderDistances.hpp>
70 : #include <com/sun/star/style/PageStyleLayout.hpp>
71 : #include <com/sun/star/style/BreakType.hpp>
72 : #include <com/sun/star/style/GraphicLocation.hpp>
73 : #include <com/sun/star/beans/PropertyAttribute.hpp>
74 : #include <com/sun/star/chart/XChartDataChangeEventListener.hpp>
75 : #include <com/sun/star/chart/ChartDataChangeEvent.hpp>
76 : #include <com/sun/star/chart2/data/XDataSequence.hpp>
77 : #include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
78 : #include <com/sun/star/table/CellContentType.hpp>
79 : #include <unotextrange.hxx>
80 : #include <unotextcursor.hxx>
81 : #include <unoparagraph.hxx>
82 : #include <svl/zforlist.hxx>
83 : #include <editeng/formatbreakitem.hxx>
84 : #include <editeng/shaditem.hxx>
85 : #include <editeng/lrspitem.hxx>
86 : #include <editeng/ulspitem.hxx>
87 : #include <fmtornt.hxx>
88 : #include <editeng/keepitem.hxx>
89 : #include <fmtlsplt.hxx>
90 : #include <swundo.hxx>
91 : #include <osl/mutex.hxx>
92 : #include <SwStyleNameMapper.hxx>
93 : #include <frmatr.hxx>
94 : #include <crsskip.hxx>
95 : #include <unochart.hxx>
96 : #include <sortopt.hxx>
97 : #include <rtl/math.hxx>
98 : #include <editeng/frmdiritem.hxx>
99 : #include <calbck.hxx>
100 : #include <comphelper/servicehelper.hxx>
101 : #include <comphelper/string.hxx>
102 : #include <cppuhelper/supportsservice.hxx>
103 : #include <comphelper/sequence.hxx>
104 : #include <comphelper/sequenceashashmap.hxx>
105 : #include <swtable.hxx>
106 :
107 : using namespace ::com::sun::star;
108 : using ::editeng::SvxBorderLine;
109 :
110 : namespace
111 : {
112 : template<typename Tcoretype, typename Tunotype>
113 16154 : struct FindUnoInstanceHint SAL_FINAL : SfxHint
114 : {
115 16154 : FindUnoInstanceHint(Tcoretype* pCore) : m_pCore(pCore), m_pResult(nullptr) {};
116 : void SetResult(Tunotype* pResult) const { m_pResult = pResult; };
117 : const Tcoretype* const m_pCore;
118 : mutable Tunotype* m_pResult;
119 : };
120 12983 : SwFrameFormat* lcl_EnsureCoreConnected(SwFrameFormat* pFormat, cppu::OWeakObject* pObject)
121 : {
122 12983 : if(!pFormat)
123 0 : throw uno::RuntimeException("Lost connection to core objects", pObject);
124 12983 : return pFormat;
125 : }
126 4 : SwTable* lcl_EnsureTableNotComplex(SwTable* pTable, cppu::OWeakObject* pObject)
127 : {
128 4 : if(pTable->IsTableComplex())
129 0 : throw uno::RuntimeException("Table too complex", pObject);
130 4 : return pTable;
131 : }
132 : }
133 :
134 : #define UNO_TABLE_COLUMN_SUM 10000
135 :
136 2 : static void lcl_SendChartEvent(::cppu::OWeakObject & rSource,
137 : ::cppu::OInterfaceContainerHelper & rListeners)
138 : {
139 2 : if (!rListeners.getLength())
140 2 : return;
141 : //TODO: find appropriate settings of the Event
142 2 : chart::ChartDataChangeEvent event;
143 2 : event.Source = & rSource;
144 2 : event.Type = chart::ChartDataChangeType_ALL;
145 2 : event.StartColumn = 0;
146 2 : event.EndColumn = 1;
147 2 : event.StartRow = 0;
148 2 : event.EndRow = 1;
149 : rListeners.notifyEach(
150 2 : & chart::XChartDataChangeEventListener::chartDataChanged, event);
151 : }
152 :
153 3756 : static void lcl_SendChartEvent(::cppu::OWeakObject & rSource,
154 : ::cppu::OMultiTypeInterfaceContainerHelper & rListeners)
155 : {
156 : ::cppu::OInterfaceContainerHelper *const pContainer(rListeners.getContainer(
157 3756 : cppu::UnoType<chart::XChartDataChangeEventListener>::get()));
158 3756 : if (pContainer)
159 : {
160 2 : lcl_SendChartEvent(rSource, *pContainer);
161 : }
162 3756 : }
163 :
164 3636 : static bool lcl_LineToSvxLine(const table::BorderLine& rLine, SvxBorderLine& rSvxLine)
165 : {
166 3636 : rSvxLine.SetColor(Color(rLine.Color));
167 :
168 : rSvxLine.GuessLinesWidths( table::BorderLineStyle::NONE,
169 3636 : convertMm100ToTwip( rLine.OuterLineWidth ),
170 3636 : convertMm100ToTwip( rLine.InnerLineWidth ),
171 10908 : convertMm100ToTwip( rLine.LineDistance ) );
172 :
173 3636 : return rLine.InnerLineWidth > 0 || rLine.OuterLineWidth > 0;
174 : }
175 :
176 1314 : static void lcl_SetSpecialProperty(SwFrameFormat* pFormat,
177 : const SfxItemPropertySimpleEntry* pEntry,
178 : const uno::Any& aValue)
179 : throw (lang::IllegalArgumentException,
180 : uno::RuntimeException)
181 : {
182 : // special treatment for "non-items"
183 1314 : switch(pEntry->nWID)
184 : {
185 : case FN_TABLE_HEADLINE_REPEAT:
186 : case FN_TABLE_HEADLINE_COUNT:
187 : {
188 : {
189 604 : SwTable* pTable = SwTable::FindTable( pFormat );
190 604 : UnoActionContext aAction(pFormat->GetDoc());
191 604 : if( pEntry->nWID == FN_TABLE_HEADLINE_REPEAT)
192 : {
193 1 : pFormat->GetDoc()->SetRowsToRepeat( *pTable, aValue.get<bool>() ? 1 : 0 );
194 : }
195 : else
196 : {
197 603 : sal_Int32 nRepeat = 0;
198 603 : aValue >>= nRepeat;
199 603 : if( nRepeat >= 0 && nRepeat < USHRT_MAX )
200 603 : pFormat->GetDoc()->SetRowsToRepeat( *pTable, (sal_uInt16) nRepeat );
201 604 : }
202 : }
203 : }
204 604 : break;
205 :
206 : case FN_TABLE_IS_RELATIVE_WIDTH:
207 : case FN_TABLE_WIDTH:
208 : case FN_TABLE_RELATIVE_WIDTH:
209 : {
210 678 : SwFormatFrmSize aSz( pFormat->GetFrmSize() );
211 678 : if(FN_TABLE_WIDTH == pEntry->nWID)
212 : {
213 535 : sal_Int32 nWidth = 0;
214 535 : aValue >>= nWidth;
215 535 : aSz.SetWidthPercent(0);
216 535 : aSz.SetWidth ( convertMm100ToTwip ( nWidth ) );
217 : }
218 143 : else if(FN_TABLE_RELATIVE_WIDTH == pEntry->nWID)
219 : {
220 74 : sal_Int16 nSet = 0;
221 74 : aValue >>= nSet;
222 74 : if(nSet && nSet <=100)
223 74 : aSz.SetWidthPercent( (sal_uInt8)nSet );
224 : }
225 69 : else if(FN_TABLE_IS_RELATIVE_WIDTH == pEntry->nWID)
226 : {
227 69 : if(!aValue.get<bool>())
228 1 : aSz.SetWidthPercent(0);
229 : else
230 : {
231 68 : lang::IllegalArgumentException aExcept;
232 68 : aExcept.Message = "relative width cannot be switched on with this property";
233 68 : throw aExcept;
234 : }
235 : }
236 678 : pFormat->GetDoc()->SetAttr(aSz, *pFormat);
237 : }
238 610 : break;
239 :
240 : case RES_PAGEDESC:
241 : {
242 32 : OUString sPageStyle;
243 32 : aValue >>= sPageStyle;
244 32 : const SwPageDesc* pDesc = 0;
245 32 : if (!sPageStyle.isEmpty())
246 : {
247 32 : SwStyleNameMapper::FillUIName(sPageStyle, sPageStyle, nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC, true );
248 32 : pDesc = SwPageDesc::GetByName(*pFormat->GetDoc(), sPageStyle);
249 : }
250 64 : SwFormatPageDesc aDesc( pDesc );
251 64 : pFormat->GetDoc()->SetAttr(aDesc, *pFormat);
252 : }
253 32 : break;
254 :
255 : default:
256 0 : throw lang::IllegalArgumentException();
257 : }
258 1246 : }
259 :
260 315 : static uno::Any lcl_GetSpecialProperty(SwFrameFormat* pFormat, const SfxItemPropertySimpleEntry* pEntry )
261 : {
262 315 : switch(pEntry->nWID)
263 : {
264 : case FN_TABLE_HEADLINE_REPEAT:
265 : case FN_TABLE_HEADLINE_COUNT:
266 : {
267 2 : SwTable* pTable = SwTable::FindTable( pFormat );
268 2 : const sal_uInt16 nRepeat = pTable->GetRowsToRepeat();
269 2 : if(pEntry->nWID == FN_TABLE_HEADLINE_REPEAT)
270 2 : return uno::makeAny<bool>(nRepeat > 0);
271 0 : return uno::makeAny<sal_Int32>(nRepeat);
272 : }
273 :
274 : case FN_TABLE_WIDTH:
275 : case FN_TABLE_IS_RELATIVE_WIDTH:
276 : case FN_TABLE_RELATIVE_WIDTH:
277 : {
278 285 : uno::Any aRet;
279 285 : const SwFormatFrmSize& rSz = pFormat->GetFrmSize();
280 285 : if(FN_TABLE_WIDTH == pEntry->nWID)
281 50 : rSz.QueryValue(aRet, MID_FRMSIZE_WIDTH|CONVERT_TWIPS);
282 235 : else if(FN_TABLE_RELATIVE_WIDTH == pEntry->nWID)
283 7 : rSz.QueryValue(aRet, MID_FRMSIZE_REL_WIDTH);
284 : else
285 228 : aRet = uno::makeAny<bool>(0 != rSz.GetWidthPercent());
286 285 : return aRet;
287 : }
288 :
289 : case RES_PAGEDESC:
290 : {
291 2 : const SfxItemSet& rSet = pFormat->GetAttrSet();
292 : const SfxPoolItem* pItem;
293 2 : if(SfxItemState::SET == rSet.GetItemState(RES_PAGEDESC, false, &pItem))
294 : {
295 1 : const SwPageDesc* pDsc = static_cast<const SwFormatPageDesc*>(pItem)->GetPageDesc();
296 1 : if(pDsc)
297 1 : return uno::makeAny<OUString>(SwStyleNameMapper::GetProgName(pDsc->GetName(), nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC ));
298 : }
299 1 : return uno::makeAny(OUString());
300 : }
301 :
302 : case RES_ANCHOR:
303 0 : return uno::makeAny(text::TextContentAnchorType_AT_PARAGRAPH);
304 :
305 : case FN_UNO_ANCHOR_TYPES:
306 : {
307 2 : uno::Sequence<text::TextContentAnchorType> aTypes{text::TextContentAnchorType_AT_PARAGRAPH};
308 2 : return uno::makeAny(aTypes);
309 : }
310 :
311 : case FN_UNO_WRAP :
312 0 : return uno::makeAny(text::WrapTextMode_NONE);
313 :
314 : case FN_PARAM_LINK_DISPLAY_NAME :
315 0 : return uno::makeAny(pFormat->GetName());
316 :
317 : case FN_UNO_REDLINE_NODE_START:
318 : case FN_UNO_REDLINE_NODE_END:
319 : {
320 24 : SwTable* pTable = SwTable::FindTable( pFormat );
321 24 : SwNode* pTableNode = pTable->GetTableNode();
322 24 : if(FN_UNO_REDLINE_NODE_END == pEntry->nWID)
323 12 : pTableNode = pTableNode->EndOfSectionNode();
324 24 : for(const SwRangeRedline* pRedline : pFormat->GetDoc()->getIDocumentRedlineAccess().GetRedlineTable())
325 : {
326 0 : const SwNode& rRedPointNode = pRedline->GetNode(true);
327 0 : const SwNode& rRedMarkNode = pRedline->GetNode(false);
328 0 : if(&rRedPointNode == pTableNode || &rRedMarkNode == pTableNode)
329 : {
330 0 : const SwNode& rStartOfRedline = SwNodeIndex(rRedPointNode) <= SwNodeIndex(rRedMarkNode) ?
331 0 : rRedPointNode : rRedMarkNode;
332 0 : bool bIsStart = &rStartOfRedline == pTableNode;
333 0 : return uno::makeAny(SwXRedlinePortion::CreateRedlineProperties(*pRedline, bIsStart));
334 : }
335 : }
336 : }
337 : }
338 24 : return uno::Any();
339 : }
340 :
341 : /** get position of a cell with a given name
342 : *
343 : * If everything was OK, the indices for column and row are changed (both >= 0).
344 : * In case of errors, at least one of them is < 0.
345 : *
346 : * Also since the implementations of tables does not really have columns using
347 : * this function is appropriate only for tables that are not complex (i.e.
348 : * where IsTableComplex() returns false).
349 : *
350 : * @param rCellName e.g. A1..Z1, a1..z1, AA1..AZ1, Aa1..Az1, BA1..BZ1, Ba1..Bz1, ...
351 : * @param [IN,OUT] rColumn (0-based)
352 : * @param [IN,OUT] rRow (0-based)
353 : */
354 : //TODO: potential for throwing proper exceptions instead of having every caller to check for errors
355 4 : void sw_GetCellPosition(const OUString &rCellName,
356 : sal_Int32 &rColumn, sal_Int32 &rRow)
357 : {
358 4 : rColumn = rRow = -1; // default return values indicating failure
359 4 : const sal_Int32 nLen = rCellName.getLength();
360 4 : if(!nLen)
361 : {
362 : SAL_WARN("sw.uno", "failed to get column or row index");
363 4 : return;
364 : }
365 4 : sal_Int32 nRowPos = 0;
366 12 : while (nRowPos<nLen)
367 : {
368 8 : if (rCellName[nRowPos]>='0' && rCellName[nRowPos]<='9')
369 : {
370 4 : break;
371 : }
372 4 : ++nRowPos;
373 : }
374 4 : if (nRowPos>0 && nRowPos<nLen)
375 : {
376 4 : sal_Int32 nColIdx = 0;
377 8 : for (sal_Int32 i = 0; i < nRowPos; ++i)
378 : {
379 4 : nColIdx *= 52;
380 4 : if (i < nRowPos - 1)
381 0 : ++nColIdx;
382 4 : const sal_Unicode cChar = rCellName[i];
383 4 : if ('A' <= cChar && cChar <= 'Z')
384 4 : nColIdx += cChar - 'A';
385 0 : else if ('a' <= cChar && cChar <= 'z')
386 0 : nColIdx += 26 + cChar - 'a';
387 : else
388 : {
389 0 : nColIdx = -1; // sth failed
390 0 : break;
391 : }
392 : }
393 :
394 4 : rColumn = nColIdx;
395 4 : rRow = rCellName.copy(nRowPos).toInt32() - 1; // - 1 because indices ought to be 0 based
396 : }
397 : }
398 :
399 : /** compare position of two cells (check rows first)
400 : *
401 : * @note this function probably also make sense only
402 : * for cell names of non-complex tables
403 : *
404 : * @param rCellName1 e.g. "A1" (non-empty string with valid cell name)
405 : * @param rCellName2 e.g. "A1" (non-empty string with valid cell name)
406 : * @return -1 if cell_1 < cell_2; 0 if both cells are equal; +1 if cell_1 > cell_2
407 : */
408 0 : int sw_CompareCellsByRowFirst( const OUString &rCellName1, const OUString &rCellName2 )
409 : {
410 0 : sal_Int32 nCol1 = -1, nRow1 = -1, nCol2 = -1, nRow2 = -1;
411 0 : sw_GetCellPosition( rCellName1, nCol1, nRow1 );
412 0 : sw_GetCellPosition( rCellName2, nCol2, nRow2 );
413 :
414 0 : if (nRow1 < nRow2 || (nRow1 == nRow2 && nCol1 < nCol2))
415 0 : return -1;
416 0 : else if (nCol1 == nCol2 && nRow1 == nRow2)
417 0 : return 0;
418 : else
419 0 : return +1;
420 : }
421 :
422 : /** compare position of two cells (check columns first)
423 : *
424 : * @note this function probably also make sense only
425 : * for cell names of non-complex tables
426 : *
427 : * @param rCellName1 e.g. "A1" (non-empty string with valid cell name)
428 : * @param rCellName2 e.g. "A1" (non-empty string with valid cell name)
429 : * @return -1 if cell_1 < cell_2; 0 if both cells are equal; +1 if cell_1 > cell_2
430 : */
431 0 : int sw_CompareCellsByColFirst( const OUString &rCellName1, const OUString &rCellName2 )
432 : {
433 0 : sal_Int32 nCol1 = -1, nRow1 = -1, nCol2 = -1, nRow2 = -1;
434 0 : sw_GetCellPosition( rCellName1, nCol1, nRow1 );
435 0 : sw_GetCellPosition( rCellName2, nCol2, nRow2 );
436 :
437 0 : if (nCol1 < nCol2 || (nCol1 == nCol2 && nRow1 < nRow2))
438 0 : return -1;
439 0 : else if (nRow1 == nRow2 && nCol1 == nCol2)
440 0 : return 0;
441 : else
442 0 : return +1;
443 : }
444 :
445 : /** compare position of two cell ranges
446 : *
447 : * @note this function probably also make sense only
448 : * for cell names of non-complex tables
449 : *
450 : * @param rRange1StartCell e.g. "A1" (non-empty string with valid cell name)
451 : * @param rRange1EndCell e.g. "A1" (non-empty string with valid cell name)
452 : * @param rRange2StartCell e.g. "A1" (non-empty string with valid cell name)
453 : * @param rRange2EndCell e.g. "A1" (non-empty string with valid cell name)
454 : * @param bCmpColsFirst if <true> position in columns will be compared first before rows
455 : *
456 : * @return -1 if cell_range_1 < cell_range_2; 0 if both cell ranges are equal; +1 if cell_range_1 > cell_range_2
457 : */
458 0 : int sw_CompareCellRanges(
459 : const OUString &rRange1StartCell, const OUString &rRange1EndCell,
460 : const OUString &rRange2StartCell, const OUString &rRange2EndCell,
461 : bool bCmpColsFirst )
462 : {
463 : int (*pCompareCells)( const OUString &, const OUString & ) =
464 0 : bCmpColsFirst ? &sw_CompareCellsByColFirst : &sw_CompareCellsByRowFirst;
465 :
466 0 : int nCmpResStartCells = pCompareCells( rRange1StartCell, rRange2StartCell );
467 0 : if ((-1 == nCmpResStartCells ) ||
468 0 : ( 0 == nCmpResStartCells &&
469 0 : -1 == pCompareCells( rRange1EndCell, rRange2EndCell ) ))
470 0 : return -1;
471 0 : else if (0 == nCmpResStartCells &&
472 0 : 0 == pCompareCells( rRange1EndCell, rRange2EndCell ))
473 0 : return 0;
474 : else
475 0 : return +1;
476 : }
477 :
478 : /** get cell name at a specified coordinate
479 : *
480 : * @param nColumn column index (0-based)
481 : * @param nRow row index (0-based)
482 : * @return the cell name
483 : */
484 11816 : OUString sw_GetCellName( sal_Int32 nColumn, sal_Int32 nRow )
485 : {
486 : #if OSL_DEBUG_LEVEL > 0
487 : {
488 : sal_Int32 nCol, nRow2;
489 : sw_GetCellPosition( OUString("z1"), nCol, nRow2);
490 : OSL_ENSURE( nCol == 51, "sw_GetCellPosition failed" );
491 : sw_GetCellPosition( OUString("AA1"), nCol, nRow2);
492 : OSL_ENSURE( nCol == 52, "sw_GetCellPosition failed" );
493 : sw_GetCellPosition( OUString("AB1"), nCol, nRow2);
494 : OSL_ENSURE( nCol == 53, "sw_GetCellPosition failed" );
495 : sw_GetCellPosition( OUString("BB1"), nCol, nRow2);
496 : OSL_ENSURE( nCol == 105, "sw_GetCellPosition failed" );
497 : }
498 : #endif
499 :
500 11816 : if (nColumn < 0 || nRow < 0)
501 0 : return OUString();
502 11816 : OUString sCellName;
503 11816 : sw_GetTableBoxColStr( static_cast< sal_uInt16 >(nColumn), sCellName );
504 11816 : return sCellName + OUString::number( nRow + 1 );
505 : }
506 :
507 : /** Find the top left or bottom right corner box in given table.
508 : Consider nested lines when finding the box.
509 :
510 : @param rTableLines the table
511 : @param i_bTopLeft if true, find top left box, otherwise find bottom
512 : right box
513 : */
514 38 : const SwTableBox* lcl_FindCornerTableBox(const SwTableLines& rTableLines, const bool i_bTopLeft)
515 : {
516 38 : const SwTableLines* pLines(&rTableLines);
517 : while(true)
518 : {
519 : assert(!pLines->empty());
520 38 : if(pLines->empty())
521 0 : return nullptr;
522 38 : const SwTableLine* pLine(i_bTopLeft ? pLines->front() : pLines->back());
523 : assert(pLine);
524 38 : const SwTableBoxes& rBoxes(pLine->GetTabBoxes());
525 : assert(rBoxes.size() != 0);
526 38 : const SwTableBox* pBox = i_bTopLeft ? rBoxes.front() : rBoxes.back();
527 : assert(pBox);
528 38 : if (pBox->GetSttNd())
529 38 : return pBox;
530 0 : pLines = &pBox->GetTabLines();
531 0 : }
532 : }
533 :
534 : /** cleanup order in a range
535 : *
536 : * Sorts the input to a uniform format. I.e. for the four possible representation
537 : * A1:C5, C5:A1, A5:C1, C1:A5
538 : * the result will be always A1:C5.
539 : *
540 : * @param [IN,OUT] rCell1 cell name (will be modified to upper-left corner), e.g. "A1" (non-empty string with valid cell name)
541 : * @param [IN,OUT] rCell2 cell name (will be modified to lower-right corner), e.g. "A1" (non-empty string with valid cell name)
542 : */
543 0 : void sw_NormalizeRange(OUString &rCell1, OUString &rCell2)
544 : {
545 0 : sal_Int32 nCol1 = -1, nRow1 = -1, nCol2 = -1, nRow2 = -1;
546 0 : sw_GetCellPosition( rCell1, nCol1, nRow1 );
547 0 : sw_GetCellPosition( rCell2, nCol2, nRow2 );
548 0 : if (nCol2 < nCol1 || nRow2 < nRow1)
549 : {
550 0 : rCell1 = sw_GetCellName( std::min(nCol1, nCol2), std::min(nRow1, nRow2) );
551 0 : rCell2 = sw_GetCellName( std::max(nCol1, nCol2), std::max(nRow1, nRow2) );
552 : }
553 0 : }
554 :
555 109 : void SwRangeDescriptor::Normalize()
556 : {
557 109 : if (nTop > nBottom)
558 0 : std::swap(nBottom, nTop);
559 109 : if (nLeft > nRight)
560 0 : std::swap(nLeft, nRight);
561 109 : }
562 :
563 11663 : static SwXCell* lcl_CreateXCell(SwFrameFormat* pFormat, sal_Int32 nColumn, sal_Int32 nRow)
564 : {
565 11663 : const OUString sCellName = sw_GetCellName(nColumn, nRow);
566 11663 : SwTable* pTable = SwTable::FindTable(pFormat);
567 11663 : SwTableBox* pBox = const_cast<SwTableBox*>(pTable->GetTableBox(sCellName));
568 11663 : if(!pBox)
569 1 : return nullptr;
570 11662 : return SwXCell::CreateXCell(pFormat, pBox, pTable);
571 : }
572 :
573 30 : static void lcl_InspectLines(SwTableLines& rLines, std::vector<OUString>& rAllNames)
574 : {
575 96 : for(auto pLine : rLines)
576 : {
577 409 : for(auto pBox : pLine->GetTabBoxes())
578 : {
579 343 : if(!pBox->GetName().isEmpty() && pBox->getRowSpan() > 0)
580 343 : rAllNames.push_back(pBox->GetName());
581 343 : SwTableLines& rBoxLines = pBox->GetTabLines();
582 343 : if(!rBoxLines.empty())
583 0 : lcl_InspectLines(rBoxLines, rAllNames);
584 : }
585 : }
586 30 : }
587 :
588 1039 : static bool lcl_FormatTable(SwFrameFormat* pTableFormat)
589 : {
590 1039 : bool bHasFrames = false;
591 1039 : SwIterator<SwFrm,SwFormat> aIter( *pTableFormat );
592 1394 : for(SwFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next())
593 : {
594 : // mba: no TYPEINFO for SwTabFrm
595 355 : if(!pFrm->IsTabFrm())
596 0 : continue;
597 355 : SwTabFrm* pTabFrm = static_cast<SwTabFrm*>(pFrm);
598 355 : if(pTabFrm->IsValid())
599 305 : pTabFrm->InvalidatePos();
600 355 : pTabFrm->SetONECalcLowers();
601 355 : pTabFrm->Calc();
602 355 : bHasFrames = true;
603 : }
604 1039 : return bHasFrames;
605 : }
606 :
607 21 : static void lcl_CrsrSelect(SwPaM& rCrsr, bool bExpand)
608 : {
609 21 : if(bExpand)
610 : {
611 5 : if(!rCrsr.HasMark())
612 5 : rCrsr.SetMark();
613 : }
614 16 : else if(rCrsr.HasMark())
615 2 : rCrsr.DeleteMark();
616 21 : }
617 :
618 20 : static void lcl_GetTableSeparators(uno::Any& rRet, SwTable* pTable, SwTableBox* pBox, bool bRow)
619 : {
620 20 : SwTabCols aCols;
621 20 : aCols.SetLeftMin ( 0 );
622 20 : aCols.SetLeft ( 0 );
623 20 : aCols.SetRight ( UNO_TABLE_COLUMN_SUM );
624 20 : aCols.SetRightMax( UNO_TABLE_COLUMN_SUM );
625 :
626 20 : pTable->GetTabCols( aCols, pBox, false, bRow );
627 :
628 20 : const size_t nSepCount = aCols.Count();
629 40 : uno::Sequence< text::TableColumnSeparator> aColSeq(nSepCount);
630 20 : text::TableColumnSeparator* pArray = aColSeq.getArray();
631 20 : bool bError = false;
632 84 : for(size_t i = 0; i < nSepCount; ++i)
633 : {
634 64 : pArray[i].Position = static_cast< sal_Int16 >(aCols[i]);
635 64 : pArray[i].IsVisible = !aCols.IsHidden(i);
636 64 : if(!bRow && !pArray[i].IsVisible)
637 : {
638 0 : bError = true;
639 0 : break;
640 : }
641 : }
642 20 : if(!bError)
643 40 : rRet.setValue(&aColSeq, cppu::UnoType<uno::Sequence< text::TableColumnSeparator>>::get());
644 :
645 20 : }
646 :
647 2898 : static void lcl_SetTableSeparators(const uno::Any& rVal, SwTable* pTable, SwTableBox* pBox, bool bRow, SwDoc* pDoc)
648 : {
649 2898 : SwTabCols aOldCols;
650 :
651 2898 : aOldCols.SetLeftMin ( 0 );
652 2898 : aOldCols.SetLeft ( 0 );
653 2898 : aOldCols.SetRight ( UNO_TABLE_COLUMN_SUM );
654 2898 : aOldCols.SetRightMax( UNO_TABLE_COLUMN_SUM );
655 :
656 2898 : pTable->GetTabCols( aOldCols, pBox, false, bRow );
657 2898 : const size_t nOldCount = aOldCols.Count();
658 : // there is no use in setting tab cols if there is only one column
659 2898 : if( !nOldCount )
660 380 : return;
661 :
662 : const uno::Sequence< text::TableColumnSeparator>* pSepSeq =
663 2518 : static_cast<uno::Sequence< text::TableColumnSeparator> const *>(rVal.getValue());
664 2518 : if(!pSepSeq || static_cast<size_t>(pSepSeq->getLength()) != nOldCount)
665 0 : return;
666 5034 : SwTabCols aCols(aOldCols);
667 2518 : const text::TableColumnSeparator* pArray = pSepSeq->getConstArray();
668 2518 : long nLastValue = 0;
669 : //sal_Int32 nTableWidth = aCols.GetRight() - aCols.GetLeft();
670 7760 : for(size_t i = 0; i < nOldCount; ++i)
671 : {
672 5244 : aCols[i] = pArray[i].Position;
673 15730 : if(bool(pArray[i].IsVisible) == aCols.IsHidden(i) ||
674 10484 : (!bRow && aCols.IsHidden(i)) ||
675 15728 : aCols[i] < nLastValue ||
676 5242 : UNO_TABLE_COLUMN_SUM < aCols[i] )
677 2 : return; // probably this should assert()
678 5242 : nLastValue = aCols[i];
679 : }
680 5032 : pDoc->SetTabCols(*pTable, aCols, aOldCols, pBox, bRow );
681 : }
682 :
683 32 : static inline OUString lcl_getString( SwXCell &rCell )
684 : {
685 : // getString is a member function of the base class...
686 32 : return rCell.getString();
687 : }
688 :
689 : /* non UNO function call to set string in SwXCell */
690 154 : void sw_setString( SwXCell &rCell, const OUString &rText,
691 : bool bKeepNumberFormat = false )
692 : {
693 154 : if(rCell.IsValid())
694 : {
695 154 : SwFrameFormat* pBoxFormat = rCell.pBox->ClaimFrameFormat();
696 154 : pBoxFormat->LockModify();
697 154 : pBoxFormat->ResetFormatAttr( RES_BOXATR_FORMULA );
698 154 : pBoxFormat->ResetFormatAttr( RES_BOXATR_VALUE );
699 154 : if (!bKeepNumberFormat)
700 64 : pBoxFormat->SetFormatAttr( SwTableBoxNumFormat(css::util::NumberFormat::TEXT) );
701 154 : pBoxFormat->UnlockModify();
702 : }
703 154 : rCell.SwXText::setString(rText);
704 154 : }
705 :
706 : /* non UNO function call to get value from SwXCell */
707 143 : double sw_getValue( SwXCell &rCell )
708 : {
709 : double fRet;
710 143 : if(rCell.IsValid() && !rCell.getString().isEmpty())
711 113 : fRet = rCell.pBox->GetFrameFormat()->GetTableBoxValue().GetValue();
712 : else
713 30 : ::rtl::math::setNan( &fRet );
714 143 : return fRet;
715 : }
716 :
717 : /* non UNO function call to set value in SwXCell */
718 90 : void sw_setValue( SwXCell &rCell, double nVal )
719 : {
720 90 : if(!rCell.IsValid())
721 90 : return;
722 : // first this text (maybe) needs to be deleted
723 90 : sal_uLong nNdPos = rCell.pBox->IsValidNumTextNd( true );
724 90 : if(ULONG_MAX != nNdPos)
725 90 : sw_setString( rCell, OUString(), true ); // true == keep number format
726 90 : SwDoc* pDoc = rCell.GetDoc();
727 90 : UnoActionContext aAction(pDoc);
728 90 : SwFrameFormat* pBoxFormat = rCell.pBox->ClaimFrameFormat();
729 180 : SfxItemSet aSet(pDoc->GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_VALUE);
730 : const SfxPoolItem* pItem;
731 :
732 : //!! do we need to set a new number format? Yes, if
733 : // - there is no current number format
734 : // - the current number format is not a number format according to the number formatter, but rather a text format
735 : // - the current number format is not even a valid number formatter number format, but rather Writer's own 'special' text number format
736 180 : if(SfxItemState::SET != pBoxFormat->GetAttrSet().GetItemState(RES_BOXATR_FORMAT, true, &pItem)
737 36 : || pDoc->GetNumberFormatter()->IsTextFormat(static_cast<const SwTableBoxNumFormat*>(pItem)->GetValue())
738 126 : || static_cast<sal_Int16>(static_cast<const SwTableBoxNumFormat*>(pItem)->GetValue()) == css::util::NumberFormat::TEXT)
739 : {
740 79 : aSet.Put(SwTableBoxNumFormat(0));
741 : }
742 :
743 180 : SwTableBoxValue aVal(nVal);
744 90 : aSet.Put(aVal);
745 90 : pDoc->SetTableBoxFormulaAttrs( *rCell.pBox, aSet );
746 : // update table
747 180 : SwTableFormulaUpdate aTableUpdate( SwTable::FindTable( rCell.GetFrameFormat() ));
748 180 : pDoc->getIDocumentFieldsAccess().UpdateTableFields( &aTableUpdate );
749 : }
750 :
751 684 : TYPEINIT1(SwXCell, SwClient);
752 :
753 13199 : SwXCell::SwXCell(SwFrameFormat* pTableFormat, SwTableBox* pBx, size_t const nPos) :
754 : SwXText(pTableFormat->GetDoc(), CURSOR_TBLTEXT),
755 : SwClient(pTableFormat),
756 13199 : m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TABLE_CELL)),
757 : pBox(pBx),
758 : pStartNode(nullptr),
759 26398 : nFndPos(nPos)
760 : {
761 13199 : }
762 :
763 0 : SwXCell::SwXCell(SwFrameFormat* pTableFormat, const SwStartNode& rStartNode) :
764 : SwXText(pTableFormat->GetDoc(), CURSOR_TBLTEXT),
765 : SwClient(pTableFormat),
766 0 : m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TABLE_CELL)),
767 : pBox(nullptr),
768 : pStartNode(&rStartNode),
769 0 : nFndPos(NOTFOUND)
770 : {
771 0 : }
772 :
773 26398 : SwXCell::~SwXCell()
774 : {
775 26398 : }
776 :
777 : namespace
778 : {
779 : class theSwXCellUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXCellUnoTunnelId > {};
780 : }
781 :
782 992 : const uno::Sequence< sal_Int8 > & SwXCell::getUnoTunnelId()
783 : {
784 992 : return theSwXCellUnoTunnelId::get().getSeq();
785 : }
786 :
787 992 : sal_Int64 SAL_CALL SwXCell::getSomething( const uno::Sequence< sal_Int8 >& rId )
788 : throw(uno::RuntimeException, std::exception)
789 : {
790 1984 : if( rId.getLength() == 16
791 2976 : && 0 == memcmp( getUnoTunnelId().getConstArray(),
792 1984 : rId.getConstArray(), 16 ) )
793 : {
794 0 : return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
795 : }
796 : else
797 992 : return SwXText::getSomething(rId);
798 : }
799 :
800 106 : uno::Sequence< uno::Type > SAL_CALL SwXCell::getTypes( ) throw(uno::RuntimeException, std::exception)
801 : {
802 106 : static uno::Sequence< uno::Type > aRetTypes;
803 :
804 106 : if(aRetTypes.getLength())
805 105 : return aRetTypes;
806 1 : const auto& rCellTypes = SwXCellBaseClass::getTypes();
807 2 : const auto& rTextTypes = SwXText::getTypes();
808 1 : aRetTypes = uno::Sequence<uno::Type>(rCellTypes.getLength() + rTextTypes.getLength());
809 1 : std::copy_n(rCellTypes.begin(), rCellTypes.getLength(), aRetTypes.begin());
810 1 : std::copy_n(rTextTypes.begin(), rTextTypes.getLength(), aRetTypes.begin()+rCellTypes.getLength());
811 2 : return aRetTypes;
812 : }
813 :
814 0 : uno::Sequence< sal_Int8 > SAL_CALL SwXCell::getImplementationId( ) throw(uno::RuntimeException, std::exception)
815 : {
816 0 : return css::uno::Sequence<sal_Int8>();
817 : }
818 :
819 196620 : void SAL_CALL SwXCell::acquire( ) throw()
820 : {
821 196620 : SwXCellBaseClass::acquire();
822 196620 : }
823 :
824 196620 : void SAL_CALL SwXCell::release( ) throw()
825 : {
826 196620 : SwXCellBaseClass::release();
827 196620 : }
828 :
829 29947 : uno::Any SAL_CALL SwXCell::queryInterface( const uno::Type& aType )
830 : throw (uno::RuntimeException, std::exception)
831 : {
832 29947 : uno::Any aRet = SwXCellBaseClass::queryInterface(aType);
833 29947 : if(aRet.getValueType() == cppu::UnoType<void>::get())
834 17436 : aRet = SwXText::queryInterface(aType);
835 29947 : return aRet;
836 : }
837 :
838 1001 : const SwStartNode *SwXCell::GetStartNode() const
839 : {
840 1001 : const SwStartNode* pSttNd = nullptr;
841 :
842 1001 : if( pStartNode || IsValid() )
843 1001 : pSttNd = pStartNode ? pStartNode : pBox->GetSttNd();
844 :
845 1001 : return pSttNd;
846 : }
847 :
848 : uno::Reference< text::XTextCursor >
849 456 : SwXCell::CreateCursor() throw (uno::RuntimeException)
850 : {
851 456 : return createTextCursor();
852 : }
853 :
854 113095 : bool SwXCell::IsValid() const
855 : {
856 : // FIXME: this is now a const method, to make SwXText::IsValid invisible
857 : // but the const_cast here are still ridiculous. TODO: find a better way.
858 113095 : SwFrameFormat* pTableFormat = pBox ? GetFrameFormat() : nullptr;
859 113095 : if(!pTableFormat)
860 : {
861 0 : const_cast<SwXCell*>(this)->pBox = nullptr;
862 : }
863 : else
864 : {
865 113095 : SwTable* pTable = SwTable::FindTable( pTableFormat );
866 : SwTableBox const*const pFoundBox =
867 113095 : const_cast<SwXCell*>(this)->FindBox(pTable, pBox);
868 113095 : if (!pFoundBox)
869 : {
870 0 : const_cast<SwXCell*>(this)->pBox = nullptr;
871 : }
872 : }
873 113095 : return nullptr != pBox;
874 : }
875 :
876 168 : OUString SwXCell::getFormula() throw( uno::RuntimeException, std::exception )
877 : {
878 168 : SolarMutexGuard aGuard;
879 168 : if(!IsValid())
880 0 : return OUString();
881 336 : SwTableBoxFormula aFormula( pBox->GetFrameFormat()->GetTableBoxFormula() );
882 168 : SwTable* pTable = SwTable::FindTable( GetFrameFormat() );
883 168 : aFormula.PtrToBoxNm( pTable );
884 336 : return aFormula.GetFormula();
885 : }
886 :
887 : ///@see sw_setValue (TODO: seems to be copy and paste programming here)
888 0 : void SwXCell::setFormula(const OUString& rFormula) throw( uno::RuntimeException, std::exception )
889 : {
890 0 : SolarMutexGuard aGuard;
891 0 : if(!IsValid())
892 0 : return;
893 : // first this text (maybe) needs to be deleted
894 0 : sal_uInt32 nNdPos = pBox->IsValidNumTextNd( true );
895 0 : if(USHRT_MAX == nNdPos)
896 0 : sw_setString( *this, OUString(), true );
897 0 : OUString sFormula(comphelper::string::stripStart(rFormula, ' '));
898 0 : if( !sFormula.isEmpty() && '=' == sFormula[0] )
899 0 : sFormula = sFormula.copy( 1 );
900 0 : SwTableBoxFormula aFormula( sFormula );
901 0 : SwDoc* pMyDoc = GetDoc();
902 0 : UnoActionContext aAction(pMyDoc);
903 0 : SfxItemSet aSet(pMyDoc->GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_FORMULA);
904 : const SfxPoolItem* pItem;
905 0 : SwFrameFormat* pBoxFormat = pBox->GetFrameFormat();
906 0 : if(SfxItemState::SET != pBoxFormat->GetAttrSet().GetItemState(RES_BOXATR_FORMAT, true, &pItem)
907 0 : || pMyDoc->GetNumberFormatter()->IsTextFormat(static_cast<const SwTableBoxNumFormat*>(pItem)->GetValue()))
908 : {
909 0 : aSet.Put(SwTableBoxNumFormat(0));
910 : }
911 0 : aSet.Put(aFormula);
912 0 : GetDoc()->SetTableBoxFormulaAttrs( *pBox, aSet );
913 : // update table
914 0 : SwTableFormulaUpdate aTableUpdate( SwTable::FindTable( GetFrameFormat() ));
915 0 : pMyDoc->getIDocumentFieldsAccess().UpdateTableFields( &aTableUpdate );
916 : }
917 :
918 111 : double SwXCell::getValue() throw( uno::RuntimeException, std::exception )
919 : {
920 111 : SolarMutexGuard aGuard;
921 : // #i112652# a table cell may contain NaN as a value, do not filter that
922 111 : return sw_getValue( *this );
923 : }
924 :
925 58 : void SwXCell::setValue(double rValue) throw( uno::RuntimeException, std::exception )
926 : {
927 58 : SolarMutexGuard aGuard;
928 58 : sw_setValue( *this, rValue );
929 58 : }
930 :
931 0 : table::CellContentType SwXCell::getType() throw( uno::RuntimeException, std::exception )
932 : {
933 0 : SolarMutexGuard aGuard;
934 :
935 0 : table::CellContentType nRes = table::CellContentType_EMPTY;
936 0 : sal_uInt32 nNdPos = pBox->IsFormulaOrValueBox();
937 0 : switch (nNdPos)
938 : {
939 0 : case 0 : nRes = table::CellContentType_TEXT; break;
940 0 : case USHRT_MAX : nRes = table::CellContentType_EMPTY; break;
941 0 : case RES_BOXATR_VALUE : nRes = table::CellContentType_VALUE; break;
942 0 : case RES_BOXATR_FORMULA : nRes = table::CellContentType_FORMULA; break;
943 : default :
944 : OSL_FAIL( "unexpected case" );
945 : }
946 0 : return nRes;
947 : }
948 :
949 32 : void SwXCell::setString(const OUString& aString) throw( uno::RuntimeException, std::exception )
950 : {
951 32 : SolarMutexGuard aGuard;
952 32 : sw_setString( *this, aString );
953 32 : }
954 :
955 0 : sal_Int32 SwXCell::getError() throw( uno::RuntimeException, std::exception )
956 : {
957 0 : SolarMutexGuard aGuard;
958 0 : OUString sContent = getString();
959 0 : return sal_Int32(sContent.equals(SwViewShell::GetShellRes()->aCalc_Error));
960 : }
961 :
962 16074 : uno::Reference<text::XTextCursor> SwXCell::createTextCursor() throw( uno::RuntimeException, std::exception )
963 : {
964 16074 : SolarMutexGuard aGuard;
965 16074 : if(!pStartNode && !IsValid())
966 0 : throw uno::RuntimeException();
967 16074 : const SwStartNode* pSttNd = pStartNode ? pStartNode : pBox->GetSttNd();
968 32148 : SwPosition aPos(*pSttNd);
969 : SwXTextCursor* const pXCursor =
970 16074 : new SwXTextCursor(*GetDoc(), this, CURSOR_TBLTEXT, aPos);
971 16074 : auto pUnoCrsr(pXCursor->GetCursor());
972 16074 : pUnoCrsr->Move(fnMoveForward, fnGoNode);
973 32148 : return static_cast<text::XWordCursor*>(pXCursor);
974 : }
975 :
976 1831 : uno::Reference<text::XTextCursor> SwXCell::createTextCursorByRange(const uno::Reference< text::XTextRange > & xTextPosition)
977 : throw( uno::RuntimeException, std::exception )
978 : {
979 1831 : SolarMutexGuard aGuard;
980 3662 : SwUnoInternalPaM aPam(*GetDoc());
981 1831 : if((!pStartNode && !IsValid()) || !::sw::XTextRangeToSwPaM(aPam, xTextPosition))
982 0 : throw uno::RuntimeException();
983 1831 : const SwStartNode* pSttNd = pStartNode ? pStartNode : pBox->GetSttNd();
984 : // skip sections
985 1831 : SwStartNode* p1 = aPam.GetNode().StartOfSectionNode();
986 3665 : while(p1->IsSectionNode())
987 3 : p1 = p1->StartOfSectionNode();
988 1831 : if( p1 != pSttNd )
989 0 : return nullptr;
990 : return static_cast<text::XWordCursor*>(
991 1831 : new SwXTextCursor(*GetDoc(), this, CURSOR_TBLTEXT,
992 3662 : *aPam.GetPoint(), aPam.GetMark()));
993 : }
994 :
995 55 : uno::Reference< beans::XPropertySetInfo > SwXCell::getPropertySetInfo() throw( uno::RuntimeException, std::exception )
996 : {
997 55 : static uno::Reference< beans::XPropertySetInfo > xRef = m_pPropSet->getPropertySetInfo();
998 55 : return xRef;
999 : }
1000 :
1001 89376 : void SwXCell::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
1002 : throw( beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
1003 : {
1004 89376 : SolarMutexGuard aGuard;
1005 89376 : if(!IsValid())
1006 73862 : return;
1007 : // Hack to support hidden property to transfer textDirection
1008 89376 : if(rPropertyName == "FRMDirection")
1009 : {
1010 34 : SvxFrameDirection eDir = FRMDIR_ENVIRONMENT;
1011 : try
1012 : {
1013 34 : const std::array<SvxFrameDirection, 3> vDirs = { FRMDIR_HORI_LEFT_TOP, FRMDIR_HORI_RIGHT_TOP, FRMDIR_VERT_TOP_RIGHT };
1014 34 : eDir = vDirs.at(aValue.get<sal_Int32>());
1015 0 : } catch(std::out_of_range) {
1016 : SAL_WARN("sw.uno", "unknown direction code, maybe it's a bitfield");
1017 : }
1018 34 : SvxFrameDirectionItem aItem(eDir, RES_FRAMEDIR);
1019 34 : pBox->GetFrameFormat()->SetFormatAttr(aItem);
1020 : }
1021 89342 : else if(rPropertyName == "TableRedlineParams")
1022 : {
1023 : // Get the table row properties
1024 6 : uno::Sequence<beans::PropertyValue> tableCellProperties;
1025 6 : tableCellProperties = aValue.get< uno::Sequence< beans::PropertyValue > >();
1026 12 : comphelper::SequenceAsHashMap aPropMap(tableCellProperties);
1027 12 : uno::Any sRedlineTypeValue = aPropMap.getUnpackedValueOrDefault("RedlineType", uno::Any());
1028 6 : if(!sRedlineTypeValue.has<OUString>())
1029 0 : throw beans::UnknownPropertyException("No redline type property: ", static_cast<cppu::OWeakObject*>(this));
1030 : // Create a 'Table Cell Redline' object
1031 12 : SwUnoCursorHelper::makeTableCellRedline(*pBox, sRedlineTypeValue.get<OUString>(), tableCellProperties);
1032 : }
1033 : else
1034 : {
1035 89336 : auto pEntry(m_pPropSet->getPropertyMap().getByName(rPropertyName));
1036 89336 : if(!pEntry)
1037 15514 : throw beans::UnknownPropertyException(rPropertyName, static_cast<cppu::OWeakObject*>(this));
1038 73822 : if(pEntry->nWID != FN_UNO_CELL_ROW_SPAN)
1039 : {
1040 73679 : SwFrameFormat* pBoxFormat = pBox->ClaimFrameFormat();
1041 73679 : SwAttrSet aSet(pBoxFormat->GetAttrSet());
1042 73679 : m_pPropSet->setPropertyValue(rPropertyName, aValue, aSet);
1043 73679 : pBoxFormat->GetDoc()->SetAttr(aSet, *pBoxFormat);
1044 : }
1045 143 : else if(aValue.isExtractableTo(cppu::UnoType<sal_Int32>::get()))
1046 143 : pBox->setRowSpan(aValue.get<sal_Int32>());
1047 89376 : }
1048 : }
1049 :
1050 1135 : uno::Any SwXCell::getPropertyValue(const OUString& rPropertyName)
1051 : throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
1052 : {
1053 1135 : SolarMutexGuard aGuard;
1054 1135 : if(!IsValid())
1055 0 : return uno::Any();
1056 1135 : auto pEntry(m_pPropSet->getPropertyMap().getByName(rPropertyName));
1057 1135 : if(!pEntry)
1058 0 : throw beans::UnknownPropertyException(rPropertyName, static_cast<cppu::OWeakObject*>(this));
1059 1135 : switch(pEntry->nWID)
1060 : {
1061 : case FN_UNO_CELL_ROW_SPAN:
1062 0 : return uno::makeAny(pBox->getRowSpan());
1063 : break;
1064 : case FN_UNO_TEXT_SECTION:
1065 : {
1066 26 : SwFrameFormat* pTableFormat = GetFrameFormat();
1067 26 : SwTable* pTable = SwTable::FindTable(pTableFormat);
1068 26 : SwTableNode* pTableNode = pTable->GetTableNode();
1069 26 : SwSectionNode* pSectionNode = pTableNode->FindSectionNode();
1070 26 : if(!pSectionNode)
1071 26 : return uno::Any();
1072 0 : SwSection& rSect = pSectionNode->GetSection();
1073 0 : return uno::makeAny(SwXTextSections::GetObject(*rSect.GetFormat()));
1074 : }
1075 : break;
1076 : case FN_UNO_CELL_NAME:
1077 4 : return uno::makeAny(pBox->GetName());
1078 : break;
1079 : case FN_UNO_REDLINE_NODE_START:
1080 : case FN_UNO_REDLINE_NODE_END:
1081 : {
1082 : //redline can only be returned if it's a living object
1083 338 : return SwXText::getPropertyValue(rPropertyName);
1084 : }
1085 : break;
1086 : default:
1087 : {
1088 767 : const SwAttrSet& rSet = pBox->GetFrameFormat()->GetAttrSet();
1089 767 : uno::Any aResult;
1090 767 : m_pPropSet->getPropertyValue(rPropertyName, rSet, aResult);
1091 767 : return aResult;
1092 : }
1093 1135 : }
1094 : }
1095 :
1096 0 : void SwXCell::addPropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
1097 0 : { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
1098 :
1099 0 : void SwXCell::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
1100 0 : { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
1101 :
1102 0 : void SwXCell::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
1103 0 : { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
1104 :
1105 0 : void SwXCell::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
1106 0 : { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
1107 :
1108 3123 : uno::Reference<container::XEnumeration> SwXCell::createEnumeration() throw( uno::RuntimeException, std::exception )
1109 : {
1110 3123 : SolarMutexGuard aGuard;
1111 3123 : if(!IsValid())
1112 0 : return uno::Reference<container::XEnumeration>();
1113 3123 : const SwStartNode* pSttNd = pBox->GetSttNd();
1114 6246 : SwPosition aPos(*pSttNd);
1115 6246 : auto pUnoCursor(GetDoc()->CreateUnoCrsr(aPos, false));
1116 3123 : pUnoCursor->Move(fnMoveForward, fnGoNode);
1117 : // remember table and start node for later travelling
1118 : // (used in export of tables in tables)
1119 3123 : SwTable const*const pTable(&pSttNd->FindTableNode()->GetTable());
1120 6246 : return SwXParagraphEnumeration::Create(this, pUnoCursor, CURSOR_TBLTEXT, pSttNd, pTable);
1121 : }
1122 :
1123 1 : uno::Type SAL_CALL SwXCell::getElementType() throw( uno::RuntimeException, std::exception )
1124 : {
1125 1 : return cppu::UnoType<text::XTextRange>::get();
1126 : }
1127 :
1128 1 : sal_Bool SwXCell::hasElements() throw( uno::RuntimeException, std::exception )
1129 : {
1130 1 : return sal_True;
1131 : }
1132 :
1133 163 : void SwXCell::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
1134 : {
1135 163 : ClientModify(this, pOld, pNew);
1136 163 : }
1137 :
1138 8204 : void SwXCell::SwClientNotify(const SwModify& rModify, const SfxHint& rHint)
1139 : {
1140 8204 : if(typeid(FindUnoInstanceHint<SwTableBox, SwXCell>) == typeid(rHint))
1141 : {
1142 8041 : auto* pFindHint(static_cast<const FindUnoInstanceHint<SwTableBox, SwXCell>* >(&rHint));
1143 8041 : if(!pFindHint->m_pCore && pFindHint->m_pCore == GetTableBox())
1144 0 : pFindHint->m_pResult = this;
1145 : }
1146 : else
1147 163 : SwClient::SwClientNotify(rModify, rHint);
1148 8204 : }
1149 :
1150 13199 : SwXCell* SwXCell::CreateXCell(SwFrameFormat* pTableFormat, SwTableBox* pBox, SwTable *pTable )
1151 : {
1152 13199 : if(!pTableFormat || !pBox)
1153 0 : return nullptr;
1154 13199 : if(!pTable)
1155 1194 : pTable = SwTable::FindTable(pTableFormat);
1156 13199 : SwTableSortBoxes::const_iterator it = pTable->GetTabSortBoxes().find(pBox);
1157 13199 : if(it == pTable->GetTabSortBoxes().end())
1158 0 : return nullptr;
1159 13199 : size_t const nPos = it - pTable->GetTabSortBoxes().begin();
1160 13199 : FindUnoInstanceHint<SwTableBox, SwXCell> aHint{pBox};
1161 13199 : pTableFormat->CallSwClientNotify(aHint);
1162 13199 : return aHint.m_pResult ? aHint.m_pResult : new SwXCell(pTableFormat, pBox, nPos);
1163 : }
1164 :
1165 : /** search if a box exists in a table
1166 : *
1167 : * @param pTable the table to search in
1168 : * @param pBox2 box model to find
1169 : * @return the box if existent in pTable, 0 (!!!) if not found
1170 : */
1171 113095 : SwTableBox* SwXCell::FindBox(SwTable* pTable, SwTableBox* pBox2)
1172 : {
1173 : // check if nFndPos happens to point to the right table box
1174 226190 : if( nFndPos < pTable->GetTabSortBoxes().size() &&
1175 113095 : pBox2 == pTable->GetTabSortBoxes()[ nFndPos ] )
1176 113095 : return pBox2;
1177 :
1178 : // if not, seek the entry (and return, if successful)
1179 0 : SwTableSortBoxes::const_iterator it = pTable->GetTabSortBoxes().find( pBox2 );
1180 0 : if( it != pTable->GetTabSortBoxes().end() )
1181 : {
1182 0 : nFndPos = it - pTable->GetTabSortBoxes().begin();
1183 0 : return pBox2;
1184 : }
1185 :
1186 : // box not found: reset nFndPos pointer
1187 0 : nFndPos = NOTFOUND;
1188 0 : return nullptr;
1189 : }
1190 :
1191 0 : OUString SwXCell::getImplementationName() throw( uno::RuntimeException, std::exception )
1192 0 : { return OUString("SwXCell"); }
1193 :
1194 1 : sal_Bool SwXCell::supportsService(const OUString& rServiceName) throw( uno::RuntimeException, std::exception )
1195 1 : { return cppu::supportsService(this, rServiceName); }
1196 :
1197 1 : uno::Sequence< OUString > SwXCell::getSupportedServiceNames() throw( uno::RuntimeException, std::exception )
1198 1 : { return {"com.sun.star.text.CellProperties"}; }
1199 :
1200 0 : OUString SwXTextTableRow::getImplementationName() throw( uno::RuntimeException, std::exception )
1201 0 : { return OUString("SwXTextTableRow"); }
1202 :
1203 1 : sal_Bool SwXTextTableRow::supportsService(const OUString& rServiceName) throw( uno::RuntimeException, std::exception )
1204 1 : { return cppu::supportsService(this, rServiceName); }
1205 :
1206 1 : uno::Sequence< OUString > SwXTextTableRow::getSupportedServiceNames() throw( uno::RuntimeException, std::exception )
1207 1 : { return {"com.sun.star.text.TextTableRow"}; }
1208 :
1209 9 : TYPEINIT1(SwXTextTableRow, SwClient);
1210 :
1211 2955 : SwXTextTableRow::SwXTextTableRow(SwFrameFormat* pFormat, SwTableLine* pLn) :
1212 : SwClient(pFormat),
1213 2955 : m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_TABLE_ROW)),
1214 5910 : pLine(pLn)
1215 2955 : { }
1216 :
1217 5910 : SwXTextTableRow::~SwXTextTableRow()
1218 5910 : { }
1219 :
1220 19 : uno::Reference< beans::XPropertySetInfo > SwXTextTableRow::getPropertySetInfo() throw( uno::RuntimeException, std::exception )
1221 : {
1222 19 : static uno::Reference<beans::XPropertySetInfo> xRef = m_pPropSet->getPropertySetInfo();
1223 19 : return xRef;
1224 : }
1225 :
1226 8938 : void SwXTextTableRow::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
1227 : throw (beans::UnknownPropertyException,
1228 : beans::PropertyVetoException,
1229 : lang::IllegalArgumentException,
1230 : lang::WrappedTargetException,
1231 : uno::RuntimeException,
1232 : std::exception)
1233 : {
1234 8938 : SolarMutexGuard aGuard;
1235 8938 : SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
1236 8938 : SwTable* pTable = SwTable::FindTable( pFormat );
1237 8938 : SwTableLine* pLn = SwXTextTableRow::FindLine(pTable, pLine);
1238 8938 : if(pLn)
1239 : {
1240 : // Check for a specific property
1241 8938 : if ( rPropertyName == "TableRedlineParams" )
1242 : {
1243 : // Get the table row properties
1244 28 : uno::Sequence< beans::PropertyValue > tableRowProperties;
1245 28 : tableRowProperties = aValue.get< uno::Sequence< beans::PropertyValue > >();
1246 56 : comphelper::SequenceAsHashMap aPropMap( tableRowProperties );
1247 56 : OUString sRedlineType;
1248 56 : uno::Any sRedlineTypeValue;
1249 28 : sRedlineTypeValue = aPropMap.getUnpackedValueOrDefault("RedlineType", sRedlineTypeValue);
1250 28 : if( sRedlineTypeValue >>= sRedlineType )
1251 : {
1252 : // Create a 'Table Row Redline' object
1253 28 : SwUnoCursorHelper::makeTableRowRedline( *pLn, sRedlineType, tableRowProperties);
1254 : }
1255 : else
1256 : {
1257 0 : throw beans::UnknownPropertyException("No redline type property: ", static_cast < cppu::OWeakObject * > ( this ) );
1258 28 : }
1259 : }
1260 : else
1261 : {
1262 : const SfxItemPropertySimpleEntry* pEntry =
1263 8910 : m_pPropSet->getPropertyMap().getByName(rPropertyName);
1264 8910 : SwDoc* pDoc = pFormat->GetDoc();
1265 8910 : if (!pEntry)
1266 0 : throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
1267 8910 : if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
1268 0 : throw beans::PropertyVetoException("Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
1269 :
1270 8910 : switch(pEntry->nWID)
1271 : {
1272 : case FN_UNO_ROW_HEIGHT:
1273 : case FN_UNO_ROW_AUTO_HEIGHT:
1274 : {
1275 1407 : SwFormatFrmSize aFrmSize(pLn->GetFrameFormat()->GetFrmSize());
1276 1407 : if(FN_UNO_ROW_AUTO_HEIGHT== pEntry->nWID)
1277 : {
1278 3 : bool bSet = *static_cast<sal_Bool const *>(aValue.getValue());
1279 3 : aFrmSize.SetHeightSizeType(bSet ? ATT_VAR_SIZE : ATT_FIX_SIZE);
1280 : }
1281 : else
1282 : {
1283 1404 : sal_Int32 nHeight = 0;
1284 1404 : aValue >>= nHeight;
1285 1404 : Size aSz(aFrmSize.GetSize());
1286 1404 : aSz.Height() = convertMm100ToTwip(nHeight);
1287 1404 : aFrmSize.SetSize(aSz);
1288 : }
1289 1407 : pDoc->SetAttr(aFrmSize, *pLn->ClaimFrameFormat());
1290 : }
1291 1407 : break;
1292 :
1293 : case FN_UNO_TABLE_COLUMN_SEPARATORS:
1294 : {
1295 2897 : UnoActionContext aContext(pDoc);
1296 2897 : SwTable* pTable2 = SwTable::FindTable( pFormat );
1297 2897 : lcl_SetTableSeparators(aValue, pTable2, pLine->GetTabBoxes()[0], true, pDoc);
1298 : }
1299 2897 : break;
1300 :
1301 : default:
1302 : {
1303 4606 : SwFrameFormat* pLnFormat = pLn->ClaimFrameFormat();
1304 4606 : SwAttrSet aSet(pLnFormat->GetAttrSet());
1305 4606 : m_pPropSet->setPropertyValue(*pEntry, aValue, aSet);
1306 4606 : pDoc->SetAttr(aSet, *pLnFormat);
1307 : }
1308 : }
1309 : }
1310 8938 : }
1311 8937 : }
1312 :
1313 83 : uno::Any SwXTextTableRow::getPropertyValue(const OUString& rPropertyName) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
1314 : {
1315 83 : SolarMutexGuard aGuard;
1316 83 : uno::Any aRet;
1317 83 : SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
1318 83 : SwTable* pTable = SwTable::FindTable( pFormat );
1319 83 : SwTableLine* pLn = SwXTextTableRow::FindLine(pTable, pLine);
1320 83 : if(pLn)
1321 : {
1322 : const SfxItemPropertySimpleEntry* pEntry =
1323 83 : m_pPropSet->getPropertyMap().getByName(rPropertyName);
1324 83 : if (!pEntry)
1325 0 : throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
1326 :
1327 83 : switch(pEntry->nWID)
1328 : {
1329 : case FN_UNO_ROW_HEIGHT:
1330 : case FN_UNO_ROW_AUTO_HEIGHT:
1331 : {
1332 16 : const SwFormatFrmSize& rSize = pLn->GetFrameFormat()->GetFrmSize();
1333 16 : if(FN_UNO_ROW_AUTO_HEIGHT== pEntry->nWID)
1334 : {
1335 7 : aRet <<= ATT_VAR_SIZE == rSize.GetHeightSizeType();
1336 : }
1337 : else
1338 9 : aRet <<= (sal_Int32)(convertTwipToMm100(rSize.GetSize().Height()));
1339 : }
1340 16 : break;
1341 :
1342 : case FN_UNO_TABLE_COLUMN_SEPARATORS:
1343 : {
1344 18 : lcl_GetTableSeparators(aRet, pTable, pLine->GetTabBoxes()[0], true);
1345 : }
1346 18 : break;
1347 :
1348 : default:
1349 : {
1350 49 : const SwAttrSet& rSet = pLn->GetFrameFormat()->GetAttrSet();
1351 49 : m_pPropSet->getPropertyValue(*pEntry, rSet, aRet);
1352 : }
1353 : }
1354 : }
1355 83 : return aRet;
1356 : }
1357 :
1358 0 : void SwXTextTableRow::addPropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
1359 0 : { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
1360 :
1361 0 : void SwXTextTableRow::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
1362 0 : { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
1363 :
1364 0 : void SwXTextTableRow::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
1365 0 : { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
1366 :
1367 0 : void SwXTextTableRow::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
1368 0 : { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
1369 :
1370 4 : void SwXTextTableRow::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
1371 4 : { ClientModify(this, pOld, pNew); }
1372 :
1373 26 : void SwXTextTableRow::SwClientNotify(const SwModify& rModify, const SfxHint& rHint)
1374 : {
1375 26 : if(typeid(FindUnoInstanceHint<SwTableLine, SwXTextTableRow>) == typeid(rHint))
1376 : {
1377 4 : auto* pFindHint(static_cast<const FindUnoInstanceHint<SwTableLine,SwXTextTableRow>* >(&rHint));
1378 4 : if(!pFindHint->m_pCore && pFindHint->m_pCore == GetTableRow())
1379 0 : pFindHint->m_pResult = this;
1380 : }
1381 : else
1382 22 : SwClient::SwClientNotify(rModify, rHint);
1383 26 : }
1384 :
1385 9021 : SwTableLine* SwXTextTableRow::FindLine(SwTable* pTable, SwTableLine* pLine)
1386 : {
1387 298875 : for(auto& pCurrentLine : pTable->GetTabLines())
1388 298875 : if(pCurrentLine == pLine)
1389 9021 : return pCurrentLine;
1390 0 : return nullptr;
1391 : }
1392 :
1393 : // SwXTextTableCursor
1394 :
1395 0 : OUString SwXTextTableCursor::getImplementationName() throw( uno::RuntimeException, std::exception )
1396 0 : { return OUString("SwXTextTableCursor"); }
1397 :
1398 3 : sal_Bool SwXTextTableCursor::supportsService(const OUString& rServiceName) throw( uno::RuntimeException, std::exception )
1399 3 : { return cppu::supportsService(this, rServiceName); }
1400 :
1401 80 : IMPLEMENT_FORWARD_XINTERFACE2(SwXTextTableCursor,SwXTextTableCursor_Base,OTextCursorHelper)
1402 0 : const SwPaM* SwXTextTableCursor::GetPaM() const { return GetCrsr(); }
1403 0 : SwPaM* SwXTextTableCursor::GetPaM() { return GetCrsr(); }
1404 0 : const SwDoc* SwXTextTableCursor::GetDoc() const { return GetFrameFormat()->GetDoc(); }
1405 0 : SwDoc* SwXTextTableCursor::GetDoc() { return GetFrameFormat()->GetDoc(); }
1406 0 : const SwUnoCrsr* SwXTextTableCursor::GetCrsr() const { return &(*m_pUnoCrsr); }
1407 321 : SwUnoCrsr* SwXTextTableCursor::GetCrsr() { return &(*m_pUnoCrsr); }
1408 :
1409 3 : uno::Sequence<OUString> SwXTextTableCursor::getSupportedServiceNames() throw( uno::RuntimeException, std::exception )
1410 3 : { return {"com.sun.star.text.TextTableCursor"}; }
1411 :
1412 6 : SwXTextTableCursor::SwXTextTableCursor(SwFrameFormat* pFormat, SwTableBox* pBox) :
1413 : SwClient(pFormat),
1414 6 : m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_TABLE_CURSOR))
1415 : {
1416 6 : SwDoc* pDoc = pFormat->GetDoc();
1417 6 : const SwStartNode* pSttNd = pBox->GetSttNd();
1418 6 : SwPosition aPos(*pSttNd);
1419 6 : m_pUnoCrsr = pDoc->CreateUnoCrsr(aPos, true);
1420 6 : m_pUnoCrsr->Move( fnMoveForward, fnGoNode );
1421 6 : SwUnoTableCrsr& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*m_pUnoCrsr);
1422 6 : rTableCrsr.MakeBoxSels();
1423 6 : }
1424 :
1425 0 : SwXTextTableCursor::SwXTextTableCursor(SwFrameFormat& rTableFormat, const SwTableCursor* pTableSelection) :
1426 : SwClient(&rTableFormat),
1427 0 : m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_TABLE_CURSOR))
1428 : {
1429 0 : m_pUnoCrsr = pTableSelection->GetDoc()->CreateUnoCrsr(*pTableSelection->GetPoint(), true);
1430 0 : if(pTableSelection->HasMark())
1431 : {
1432 0 : m_pUnoCrsr->SetMark();
1433 0 : *m_pUnoCrsr->GetMark() = *pTableSelection->GetMark();
1434 : }
1435 0 : const SwSelBoxes& rBoxes = pTableSelection->GetSelectedBoxes();
1436 0 : SwUnoTableCrsr& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*m_pUnoCrsr);
1437 0 : for(auto pBox : rBoxes)
1438 0 : rTableCrsr.InsertBox(*pBox);
1439 0 : rTableCrsr.MakeBoxSels();
1440 0 : }
1441 :
1442 7 : OUString SwXTextTableCursor::getRangeName()
1443 : throw (uno::RuntimeException, std::exception)
1444 : {
1445 7 : SolarMutexGuard aGuard;
1446 7 : SwUnoCrsr* pUnoCrsr = GetCrsr();
1447 7 : SwUnoTableCrsr* pTableCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
1448 : //!! see also SwChartDataSequence::getSourceRangeRepresentation
1449 7 : if(!pTableCrsr)
1450 0 : return OUString();
1451 7 : pTableCrsr->MakeBoxSels();
1452 7 : const SwStartNode* pNode = pTableCrsr->GetPoint()->nNode.GetNode().FindTableBoxStartNode();
1453 7 : const SwTable* pTable = SwTable::FindTable(GetFrameFormat());
1454 7 : const SwTableBox* pEndBox = pTable->GetTableBox(pNode->GetIndex());
1455 7 : if(pTableCrsr->HasMark())
1456 : {
1457 0 : pNode = pTableCrsr->GetMark()->nNode.GetNode().FindTableBoxStartNode();
1458 0 : const SwTableBox* pStartBox = pTable->GetTableBox(pNode->GetIndex());
1459 0 : if(pEndBox != pStartBox)
1460 : {
1461 : // need to switch start and end?
1462 0 : if(*pTableCrsr->GetPoint() < *pTableCrsr->GetMark())
1463 0 : std::swap(pStartBox, pEndBox);
1464 0 : return pStartBox->GetName() + ":" + pEndBox->GetName();
1465 : }
1466 : }
1467 7 : return pEndBox->GetName();
1468 : }
1469 :
1470 3 : sal_Bool SwXTextTableCursor::gotoCellByName(const OUString& sCellName, sal_Bool bExpand)
1471 : throw(uno::RuntimeException, std::exception)
1472 : {
1473 3 : SolarMutexGuard aGuard;
1474 3 : SwUnoCrsr* pUnoCrsr = GetCrsr();
1475 3 : if(!pUnoCrsr)
1476 0 : return false;
1477 3 : auto& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*pUnoCrsr);
1478 3 : lcl_CrsrSelect(rTableCrsr, bExpand);
1479 3 : return rTableCrsr.GotoTableBox(sCellName);
1480 : }
1481 :
1482 2 : sal_Bool SwXTextTableCursor::goLeft(sal_Int16 Count, sal_Bool bExpand) throw( uno::RuntimeException, std::exception )
1483 : {
1484 2 : SolarMutexGuard aGuard;
1485 2 : SwUnoCrsr* pUnoCrsr = GetCrsr();
1486 2 : if(!pUnoCrsr)
1487 0 : return false;
1488 2 : SwUnoTableCrsr& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*pUnoCrsr);
1489 2 : lcl_CrsrSelect(rTableCrsr, bExpand);
1490 2 : return rTableCrsr.Left(Count, CRSR_SKIP_CHARS, false, false);
1491 : }
1492 :
1493 2 : sal_Bool SwXTextTableCursor::goRight(sal_Int16 Count, sal_Bool bExpand) throw( uno::RuntimeException, std::exception )
1494 : {
1495 2 : SolarMutexGuard aGuard;
1496 2 : SwUnoCrsr* pUnoCrsr = GetCrsr();
1497 2 : if(!pUnoCrsr)
1498 0 : return false;
1499 2 : SwUnoTableCrsr& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*pUnoCrsr);
1500 2 : lcl_CrsrSelect(rTableCrsr, bExpand);
1501 2 : return rTableCrsr.Right(Count, CRSR_SKIP_CHARS, false, false);
1502 : }
1503 :
1504 2 : sal_Bool SwXTextTableCursor::goUp(sal_Int16 Count, sal_Bool bExpand) throw( uno::RuntimeException, std::exception )
1505 : {
1506 2 : SolarMutexGuard aGuard;
1507 2 : SwUnoCrsr* pUnoCrsr = GetCrsr();
1508 2 : if(!pUnoCrsr)
1509 0 : return false;
1510 2 : SwUnoTableCrsr& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*pUnoCrsr);
1511 2 : lcl_CrsrSelect(rTableCrsr, bExpand);
1512 2 : return rTableCrsr.UpDown(true, Count, 0, 0);
1513 : }
1514 :
1515 1 : sal_Bool SwXTextTableCursor::goDown(sal_Int16 Count, sal_Bool bExpand) throw( uno::RuntimeException, std::exception )
1516 : {
1517 1 : SolarMutexGuard aGuard;
1518 1 : SwUnoCrsr* pUnoCrsr = GetCrsr();
1519 1 : if(!pUnoCrsr)
1520 0 : return false;
1521 1 : SwUnoTableCrsr& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*pUnoCrsr);
1522 1 : lcl_CrsrSelect(rTableCrsr, bExpand);
1523 1 : return rTableCrsr.UpDown(false, Count, 0, 0);
1524 : }
1525 :
1526 4 : void SwXTextTableCursor::gotoStart(sal_Bool bExpand) throw( uno::RuntimeException, std::exception )
1527 : {
1528 4 : SolarMutexGuard aGuard;
1529 4 : SwUnoCrsr* pUnoCrsr = GetCrsr();
1530 4 : if(!pUnoCrsr)
1531 4 : return;
1532 4 : SwUnoTableCrsr& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*pUnoCrsr);
1533 4 : lcl_CrsrSelect(rTableCrsr, bExpand);
1534 4 : rTableCrsr.MoveTable(fnTableCurr, fnTableStart);
1535 : }
1536 :
1537 7 : void SwXTextTableCursor::gotoEnd(sal_Bool bExpand) throw( uno::RuntimeException, std::exception )
1538 : {
1539 7 : SolarMutexGuard aGuard;
1540 7 : SwUnoCrsr* pUnoCrsr = GetCrsr();
1541 7 : if(!pUnoCrsr)
1542 7 : return;
1543 7 : SwUnoTableCrsr& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*pUnoCrsr);
1544 7 : lcl_CrsrSelect(rTableCrsr, bExpand);
1545 7 : rTableCrsr.MoveTable(fnTableCurr, fnTableEnd);
1546 : }
1547 :
1548 3 : sal_Bool SwXTextTableCursor::mergeRange()
1549 : throw (uno::RuntimeException, std::exception)
1550 : {
1551 3 : SolarMutexGuard aGuard;
1552 3 : SwUnoCrsr* pUnoCrsr = GetCrsr();
1553 3 : if(!pUnoCrsr)
1554 0 : return false;
1555 : {
1556 : // The Actions need to be revoked here
1557 3 : UnoActionRemoveContext aRemoveContext(pUnoCrsr->GetDoc());
1558 : }
1559 3 : SwUnoTableCrsr& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*pUnoCrsr);
1560 3 : rTableCrsr.MakeBoxSels();
1561 : bool bResult;
1562 : {
1563 3 : UnoActionContext aContext(pUnoCrsr->GetDoc());
1564 3 : bResult = TBLMERGE_OK == rTableCrsr.GetDoc()->MergeTable(rTableCrsr);
1565 : }
1566 3 : if(bResult)
1567 : {
1568 3 : size_t nCount = rTableCrsr.GetSelectedBoxesCount();
1569 10 : while (nCount--)
1570 4 : rTableCrsr.DeleteBox(nCount);
1571 : }
1572 3 : rTableCrsr.MakeBoxSels();
1573 3 : return bResult;
1574 : }
1575 :
1576 2 : sal_Bool SwXTextTableCursor::splitRange(sal_Int16 Count, sal_Bool Horizontal)
1577 : throw (uno::RuntimeException, std::exception)
1578 : {
1579 2 : SolarMutexGuard aGuard;
1580 2 : if (Count <= 0)
1581 0 : throw uno::RuntimeException("Illegal first argument: needs to be > 0", static_cast<cppu::OWeakObject*>(this));
1582 2 : SwUnoCrsr* pUnoCrsr = GetCrsr();
1583 2 : if(!pUnoCrsr)
1584 0 : return false;
1585 : {
1586 : // here, all actions need to be revoked
1587 2 : UnoActionRemoveContext aRemoveContext(pUnoCrsr->GetDoc());
1588 : }
1589 2 : SwUnoTableCrsr& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*pUnoCrsr);
1590 2 : rTableCrsr.MakeBoxSels();
1591 : bool bResult;
1592 : {
1593 2 : UnoActionContext aContext(pUnoCrsr->GetDoc());
1594 2 : bResult = rTableCrsr.GetDoc()->SplitTable(rTableCrsr.GetSelectedBoxes(), !Horizontal, Count);
1595 : }
1596 2 : rTableCrsr.MakeBoxSels();
1597 2 : return bResult;
1598 : }
1599 :
1600 151 : uno::Reference< beans::XPropertySetInfo > SwXTextTableCursor::getPropertySetInfo() throw( uno::RuntimeException, std::exception )
1601 : {
1602 151 : static uno::Reference< beans::XPropertySetInfo > xRef = m_pPropSet->getPropertySetInfo();
1603 151 : return xRef;
1604 : }
1605 :
1606 93 : void SwXTextTableCursor::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
1607 : throw (beans::UnknownPropertyException,
1608 : beans::PropertyVetoException,
1609 : lang::IllegalArgumentException,
1610 : lang::WrappedTargetException,
1611 : uno::RuntimeException,
1612 : std::exception)
1613 : {
1614 93 : SolarMutexGuard aGuard;
1615 93 : SwUnoCrsr* pUnoCrsr = GetCrsr();
1616 93 : if(!pUnoCrsr)
1617 92 : return;
1618 93 : auto pEntry(m_pPropSet->getPropertyMap().getByName(rPropertyName));
1619 93 : if(!pEntry)
1620 0 : throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast<cppu::OWeakObject*>(this));
1621 93 : if(pEntry->nFlags & beans::PropertyAttribute::READONLY)
1622 0 : throw beans::PropertyVetoException("Property is read-only: " + rPropertyName, static_cast<cppu::OWeakObject*>(this));
1623 : {
1624 93 : auto pSttNode = pUnoCrsr->GetNode().StartOfSectionNode();
1625 93 : const SwTableNode* pTableNode = pSttNode->FindTableNode();
1626 93 : lcl_FormatTable(pTableNode->GetTable().GetFrameFormat());
1627 : }
1628 93 : auto& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*pUnoCrsr);
1629 93 : rTableCrsr.MakeBoxSels();
1630 93 : SwDoc* pDoc = pUnoCrsr->GetDoc();
1631 93 : switch(pEntry->nWID)
1632 : {
1633 : case FN_UNO_TABLE_CELL_BACKGROUND:
1634 : {
1635 0 : SvxBrushItem aBrush(RES_BACKGROUND);
1636 0 : SwDoc::GetBoxAttr(*pUnoCrsr, aBrush);
1637 0 : aBrush.PutValue(aValue, pEntry->nMemberId);
1638 0 : pDoc->SetBoxAttr(*pUnoCrsr, aBrush);
1639 :
1640 : }
1641 0 : break;
1642 : case RES_BOXATR_FORMAT:
1643 : {
1644 0 : SfxUInt32Item aNumberFormat(RES_BOXATR_FORMAT);
1645 0 : aNumberFormat.PutValue(aValue, 0);
1646 0 : pDoc->SetBoxAttr(*pUnoCrsr, aNumberFormat);
1647 : }
1648 0 : break;
1649 : case FN_UNO_PARA_STYLE:
1650 0 : SwUnoCursorHelper::SetTextFormatColl(aValue, *pUnoCrsr);
1651 0 : break;
1652 : default:
1653 : {
1654 93 : SfxItemSet aItemSet(pDoc->GetAttrPool(), pEntry->nWID, pEntry->nWID);
1655 93 : SwUnoCursorHelper::GetCrsrAttr(rTableCrsr.GetSelRing(),
1656 93 : aItemSet);
1657 :
1658 93 : if (!SwUnoCursorHelper::SetCursorPropertyValue(
1659 93 : *pEntry, aValue, rTableCrsr.GetSelRing(), aItemSet))
1660 : {
1661 92 : m_pPropSet->setPropertyValue(*pEntry, aValue, aItemSet);
1662 : }
1663 92 : SwUnoCursorHelper::SetCrsrAttr(rTableCrsr.GetSelRing(),
1664 93 : aItemSet, SetAttrMode::DEFAULT, true);
1665 : }
1666 93 : }
1667 : }
1668 :
1669 195 : uno::Any SwXTextTableCursor::getPropertyValue(const OUString& rPropertyName)
1670 : throw (beans::UnknownPropertyException,
1671 : lang::WrappedTargetException,
1672 : uno::RuntimeException,
1673 : std::exception)
1674 : {
1675 195 : SolarMutexGuard aGuard;
1676 195 : SwUnoCrsr* pUnoCrsr = GetCrsr();
1677 195 : if(!pUnoCrsr)
1678 0 : return uno::Any();
1679 : {
1680 195 : auto pSttNode = pUnoCrsr->GetNode().StartOfSectionNode();
1681 195 : const SwTableNode* pTableNode = pSttNode->FindTableNode();
1682 195 : lcl_FormatTable(pTableNode->GetTable().GetFrameFormat());
1683 : }
1684 195 : SwUnoTableCrsr& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*pUnoCrsr);
1685 195 : auto pEntry(m_pPropSet->getPropertyMap().getByName(rPropertyName));
1686 195 : if(!pEntry)
1687 0 : throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast<cppu::OWeakObject*>(this));
1688 195 : rTableCrsr.MakeBoxSels();
1689 390 : uno::Any aResult;
1690 195 : switch(pEntry->nWID)
1691 : {
1692 : case FN_UNO_TABLE_CELL_BACKGROUND:
1693 : {
1694 0 : SvxBrushItem aBrush(RES_BACKGROUND);
1695 0 : if (SwDoc::GetBoxAttr(*pUnoCrsr, aBrush))
1696 0 : aBrush.QueryValue(aResult, pEntry->nMemberId);
1697 : }
1698 0 : break;
1699 : case RES_BOXATR_FORMAT:
1700 : // TODO: GetAttr for table selections in a Doc is missing
1701 0 : throw uno::RuntimeException("Unknown property: " + rPropertyName, static_cast<cppu::OWeakObject*>(this));
1702 : break;
1703 : case FN_UNO_PARA_STYLE:
1704 : {
1705 0 : auto pFormat(SwUnoCursorHelper::GetCurTextFormatColl(*pUnoCrsr, false));
1706 0 : if(pFormat)
1707 0 : aResult = uno::makeAny(pFormat->GetName());
1708 : }
1709 0 : break;
1710 : default:
1711 : {
1712 195 : SfxItemSet aSet(rTableCrsr.GetDoc()->GetAttrPool(),
1713 : RES_CHRATR_BEGIN, RES_FRMATR_END-1,
1714 : RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
1715 195 : 0L);
1716 195 : SwUnoCursorHelper::GetCrsrAttr(rTableCrsr.GetSelRing(), aSet);
1717 195 : m_pPropSet->getPropertyValue(*pEntry, aSet, aResult);
1718 : }
1719 : }
1720 390 : return aResult;
1721 : }
1722 :
1723 0 : void SwXTextTableCursor::addPropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
1724 0 : { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
1725 :
1726 0 : void SwXTextTableCursor::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
1727 0 : { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
1728 :
1729 0 : void SwXTextTableCursor::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
1730 0 : { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
1731 :
1732 0 : void SwXTextTableCursor::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
1733 0 : { throw uno::RuntimeException("not implemented", static_cast<cppu::OWeakObject*>(this)); };
1734 :
1735 4 : void SwXTextTableCursor::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
1736 4 : { ClientModify(this, pOld, pNew); }
1737 :
1738 1340 : class SwXTextTable::Impl
1739 : {
1740 : private:
1741 : ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper
1742 :
1743 : public:
1744 : uno::WeakReference<uno::XInterface> m_wThis;
1745 : ::cppu::OMultiTypeInterfaceContainerHelper m_Listeners;
1746 :
1747 1340 : Impl() : m_Listeners(m_Mutex) { }
1748 :
1749 : // note: lock mutex before calling this to avoid concurrent update
1750 42 : static std::pair<sal_uInt16, sal_uInt16> ThrowIfComplex(SwXTextTable &rThis)
1751 : {
1752 42 : sal_uInt16 const nRowCount(rThis.getRowCount());
1753 42 : sal_uInt16 const nColCount(rThis.getColumnCount());
1754 42 : if (!nRowCount || !nColCount)
1755 : {
1756 : throw uno::RuntimeException("Table too complex",
1757 2 : static_cast<cppu::OWeakObject*>(&rThis));
1758 : }
1759 40 : return std::make_pair(nRowCount, nColCount);
1760 : }
1761 : };
1762 :
1763 : class SwTableProperties_Impl
1764 : {
1765 : SwUnoCursorHelper::SwAnyMapHelper aAnyMap;
1766 : public:
1767 : SwTableProperties_Impl();
1768 : ~SwTableProperties_Impl();
1769 :
1770 : void SetProperty(sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any& aVal);
1771 : bool GetProperty(sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any*& rpAny);
1772 : template<typename Tpoolitem>
1773 : inline void AddItemToSet(SfxItemSet& rSet, std::function<Tpoolitem()> aItemFactory, sal_uInt16 nWhich, std::initializer_list<sal_uInt16> vMember, bool bAddTwips = false);
1774 :
1775 : void ApplyTableAttr(const SwTable& rTable, SwDoc& rDoc);
1776 : };
1777 :
1778 138 : SwTableProperties_Impl::SwTableProperties_Impl()
1779 138 : { }
1780 :
1781 138 : SwTableProperties_Impl::~SwTableProperties_Impl()
1782 138 : { }
1783 :
1784 1 : void SwTableProperties_Impl::SetProperty(sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any& rVal)
1785 1 : { aAnyMap.SetValue( nWhichId, nMemberId, rVal ); }
1786 :
1787 2709 : bool SwTableProperties_Impl::GetProperty(sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any*& rpAny )
1788 2709 : { return aAnyMap.FillValue( nWhichId, nMemberId, rpAny ); }
1789 :
1790 : template<typename Tpoolitem>
1791 903 : void SwTableProperties_Impl::AddItemToSet(SfxItemSet& rSet, std::function<Tpoolitem()> aItemFactory, sal_uInt16 nWhich, std::initializer_list<sal_uInt16> vMember, bool bAddTwips)
1792 : {
1793 903 : std::list< std::pair<sal_uInt16, const uno::Any* > > vMemberAndAny;
1794 2580 : for(sal_uInt16 nMember : vMember)
1795 : {
1796 1677 : const uno::Any* pAny = nullptr;
1797 1677 : GetProperty(nWhich, nMember, pAny);
1798 1677 : if(pAny)
1799 1 : vMemberAndAny.push_back(std::make_pair(nMember, pAny));
1800 : }
1801 903 : if(!vMemberAndAny.empty())
1802 : {
1803 1 : Tpoolitem aItem = aItemFactory();
1804 2 : for(auto& aMemberAndAny : vMemberAndAny)
1805 1 : aItem.PutValue(*aMemberAndAny.second, aMemberAndAny.first | (bAddTwips ? CONVERT_TWIPS : 0) );
1806 1 : rSet.Put(aItem);
1807 903 : }
1808 903 : }
1809 129 : void SwTableProperties_Impl::ApplyTableAttr(const SwTable& rTable, SwDoc& rDoc)
1810 : {
1811 129 : SfxItemSet aSet(rDoc.GetAttrPool(),
1812 : RES_LAYOUT_SPLIT, RES_LAYOUT_SPLIT,
1813 : RES_BACKGROUND, RES_BACKGROUND,
1814 : RES_FRM_SIZE, RES_UL_SPACE,
1815 : RES_HORI_ORIENT, RES_HORI_ORIENT,
1816 : RES_BREAK, RES_BREAK,
1817 : RES_KEEP, RES_KEEP,
1818 : RES_SHADOW, RES_SHADOW,
1819 : RES_PAGEDESC, RES_PAGEDESC,
1820 : 0
1821 129 : );
1822 : const uno::Any* pRepHead;
1823 129 : const SwFrameFormat &rFrameFormat = *rTable.GetFrameFormat();
1824 129 : if(GetProperty(FN_TABLE_HEADLINE_REPEAT, 0xff, pRepHead ))
1825 : {
1826 0 : bool bVal(pRepHead->get<bool>());
1827 0 : const_cast<SwTable&>(rTable).SetRowsToRepeat( bVal ? 1 : 0 ); // TODO: MULTIHEADER
1828 : }
1829 :
1830 1 : AddItemToSet<SvxBrushItem>(aSet, [&rFrameFormat]() { return rFrameFormat.makeBackgroundBrushItem(); }, RES_BACKGROUND, {
1831 : MID_BACK_COLOR,
1832 : MID_GRAPHIC_TRANSPARENT,
1833 : MID_GRAPHIC_POSITION,
1834 : MID_GRAPHIC_URL,
1835 129 : MID_GRAPHIC_FILTER });
1836 :
1837 129 : bool bPutBreak = true;
1838 : const uno::Any* pPage;
1839 129 : if(GetProperty(FN_UNO_PAGE_STYLE, 0, pPage) || GetProperty(RES_PAGEDESC, 0xff, pPage))
1840 : {
1841 0 : OUString sPageStyle = pPage->get<OUString>();
1842 0 : if(!sPageStyle.isEmpty())
1843 : {
1844 0 : SwStyleNameMapper::FillUIName(sPageStyle, sPageStyle, nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC, true);
1845 0 : const SwPageDesc* pDesc = SwPageDesc::GetByName(rDoc, sPageStyle);
1846 0 : if(pDesc)
1847 : {
1848 0 : SwFormatPageDesc aDesc(pDesc);
1849 : const uno::Any* pPgNo;
1850 0 : if(GetProperty(RES_PAGEDESC, MID_PAGEDESC_PAGENUMOFFSET, pPgNo))
1851 : {
1852 0 : aDesc.SetNumOffset(pPgNo->get<sal_Int16>());
1853 : }
1854 0 : aSet.Put(aDesc);
1855 0 : bPutBreak = false;
1856 : }
1857 :
1858 0 : }
1859 : }
1860 :
1861 129 : if(bPutBreak)
1862 129 : AddItemToSet<SvxFormatBreakItem>(aSet, [&rFrameFormat]() { return rFrameFormat.GetBreak(); }, RES_BREAK, {0});
1863 129 : AddItemToSet<SvxShadowItem>(aSet, [&rFrameFormat]() { return rFrameFormat.GetShadow(); }, RES_SHADOW, {0}, true);
1864 129 : AddItemToSet<SvxFormatKeepItem>(aSet, [&rFrameFormat]() { return rFrameFormat.GetKeep(); }, RES_KEEP, {0});
1865 129 : AddItemToSet<SwFormatHoriOrient>(aSet, [&rFrameFormat]() { return rFrameFormat.GetHoriOrient(); }, RES_HORI_ORIENT, {MID_HORIORIENT_ORIENT}, true);
1866 :
1867 129 : const uno::Any* pSzRel(nullptr);
1868 129 : GetProperty(FN_TABLE_IS_RELATIVE_WIDTH, 0xff, pSzRel);
1869 129 : const uno::Any* pRelWidth(nullptr);
1870 129 : GetProperty(FN_TABLE_RELATIVE_WIDTH, 0xff, pRelWidth);
1871 129 : const uno::Any* pWidth(nullptr);
1872 129 : GetProperty(FN_TABLE_WIDTH, 0xff, pWidth);
1873 :
1874 129 : bool bPutSize = pWidth != nullptr;
1875 258 : SwFormatFrmSize aSz(ATT_VAR_SIZE);
1876 129 : if(pWidth)
1877 : {
1878 0 : aSz.PutValue(*pWidth, MID_FRMSIZE_WIDTH);
1879 0 : bPutSize = true;
1880 : }
1881 129 : if(pSzRel && pSzRel->get<bool>() && pRelWidth)
1882 : {
1883 0 : aSz.PutValue(*pRelWidth, MID_FRMSIZE_REL_WIDTH|CONVERT_TWIPS);
1884 0 : bPutSize = true;
1885 : }
1886 129 : if(bPutSize)
1887 : {
1888 0 : if(!aSz.GetWidth())
1889 0 : aSz.SetWidth(MINLAY);
1890 0 : aSet.Put(aSz);
1891 : }
1892 0 : AddItemToSet<SvxLRSpaceItem>(aSet, [&rFrameFormat]() { return rFrameFormat.GetLRSpace(); }, RES_LR_SPACE, {
1893 : MID_L_MARGIN|CONVERT_TWIPS,
1894 129 : MID_R_MARGIN|CONVERT_TWIPS });
1895 0 : AddItemToSet<SvxULSpaceItem>(aSet, [&rFrameFormat]() { return rFrameFormat.GetULSpace(); }, RES_UL_SPACE, {
1896 : MID_UP_MARGIN|CONVERT_TWIPS,
1897 129 : MID_LO_MARGIN|CONVERT_TWIPS });
1898 129 : const::uno::Any* pSplit(nullptr);
1899 129 : if(GetProperty(RES_LAYOUT_SPLIT, 0, pSplit))
1900 : {
1901 0 : SwFormatLayoutSplit aSp(pSplit->get<bool>());
1902 0 : aSet.Put(aSp);
1903 : }
1904 129 : if(aSet.Count())
1905 : {
1906 1 : rDoc.SetAttr(aSet, *rTable.GetFrameFormat());
1907 129 : }
1908 129 : }
1909 :
1910 : namespace
1911 : {
1912 : class theSwXTextTableUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXTextTableUnoTunnelId > {};
1913 : }
1914 :
1915 1081 : const uno::Sequence< sal_Int8 > & SwXTextTable::getUnoTunnelId()
1916 1081 : { return theSwXTextTableUnoTunnelId::get().getSeq(); }
1917 :
1918 943 : sal_Int64 SAL_CALL SwXTextTable::getSomething( const uno::Sequence< sal_Int8 >& rId )
1919 : throw(uno::RuntimeException, std::exception)
1920 : {
1921 1886 : if(rId.getLength() == 16
1922 943 : && 0 == memcmp(getUnoTunnelId().getConstArray(), rId.getConstArray(), 16))
1923 : {
1924 134 : return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
1925 : }
1926 809 : return 0;
1927 : }
1928 :
1929 3408 : TYPEINIT1(SwXTextTable, SwClient)
1930 :
1931 138 : SwXTextTable::SwXTextTable()
1932 138 : : m_pImpl(new Impl)
1933 : ,
1934 138 : m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_TABLE)),
1935 138 : pTableProps(new SwTableProperties_Impl),
1936 : bIsDescriptor(true),
1937 : nRows(2),
1938 : nColumns(2),
1939 : m_bFirstRowAsLabel(false),
1940 552 : m_bFirstColumnAsLabel(false)
1941 138 : { }
1942 :
1943 1202 : SwXTextTable::SwXTextTable(SwFrameFormat& rFrameFormat)
1944 : : SwClient( &rFrameFormat )
1945 1202 : , m_pImpl(new Impl)
1946 : ,
1947 1202 : m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_TABLE)),
1948 : pTableProps(0),
1949 : bIsDescriptor(false),
1950 : nRows(0),
1951 : nColumns(0),
1952 : m_bFirstRowAsLabel(false),
1953 3606 : m_bFirstColumnAsLabel(false)
1954 1202 : { }
1955 :
1956 4020 : SwXTextTable::~SwXTextTable()
1957 4020 : { delete pTableProps; }
1958 :
1959 1345 : uno::Reference<text::XTextTable> SwXTextTable::CreateXTextTable(SwFrameFormat* const pFrameFormat)
1960 : {
1961 1345 : uno::Reference<text::XTextTable> xTable;
1962 1345 : if(pFrameFormat)
1963 1207 : xTable.set(pFrameFormat->GetXObject(), uno::UNO_QUERY); // cached?
1964 1345 : if(xTable.is())
1965 5 : return xTable;
1966 1340 : SwXTextTable* const pNew( (pFrameFormat) ? new SwXTextTable(*pFrameFormat) : new SwXTextTable());
1967 1340 : xTable.set(pNew);
1968 1340 : if(pFrameFormat)
1969 1202 : pFrameFormat->SetXObject(xTable);
1970 : // need a permanent Reference to initialize m_wThis
1971 1340 : pNew->m_pImpl->m_wThis = xTable;
1972 1340 : return xTable;
1973 : }
1974 :
1975 121 : void SwXTextTable::initialize(sal_Int32 nR, sal_Int32 nC) throw( uno::RuntimeException, std::exception )
1976 : {
1977 121 : if(!bIsDescriptor || nR <= 0 || nC <= 0 || nR >= USHRT_MAX || nC >= USHRT_MAX )
1978 0 : throw uno::RuntimeException();
1979 121 : nRows = static_cast<sal_uInt16>(nR);
1980 121 : nColumns = static_cast<sal_uInt16>(nC);
1981 121 : }
1982 :
1983 626 : uno::Reference< table::XTableRows > SwXTextTable::getRows() throw( uno::RuntimeException, std::exception )
1984 : {
1985 626 : SolarMutexGuard aGuard;
1986 626 : uno::Reference<table::XTableRows> xResult(m_xRows);
1987 626 : if(xResult.is())
1988 0 : return xResult;
1989 626 : if(SwFrameFormat* pFormat = GetFrameFormat())
1990 626 : m_xRows = xResult = new SwXTableRows(*pFormat);
1991 626 : if(!xResult.is())
1992 0 : throw uno::RuntimeException();
1993 626 : return xResult;
1994 : }
1995 :
1996 7 : uno::Reference< table::XTableColumns > SwXTextTable::getColumns() throw( uno::RuntimeException, std::exception )
1997 : {
1998 7 : SolarMutexGuard aGuard;
1999 7 : uno::Reference<table::XTableColumns> xResult(m_xColumns);
2000 7 : if(xResult.is())
2001 0 : return xResult;
2002 7 : if(SwFrameFormat* pFormat = GetFrameFormat())
2003 7 : m_xColumns = xResult = new SwXTableColumns(*pFormat);
2004 7 : if(!xResult.is())
2005 0 : throw uno::RuntimeException();
2006 7 : return xResult;
2007 : }
2008 :
2009 337 : uno::Reference<table::XCell> SwXTextTable::getCellByName(const OUString& sCellName) throw( uno::RuntimeException, std::exception )
2010 : {
2011 337 : SolarMutexGuard aGuard;
2012 337 : SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
2013 337 : SwTable* pTable = SwTable::FindTable(pFormat);
2014 337 : SwTableBox* pBox = const_cast<SwTableBox*>(pTable->GetTableBox(sCellName));
2015 337 : if(!pBox)
2016 0 : return nullptr;
2017 337 : return SwXCell::CreateXCell(pFormat, pBox);
2018 : }
2019 :
2020 30 : uno::Sequence<OUString> SwXTextTable::getCellNames() throw( uno::RuntimeException, std::exception )
2021 : {
2022 30 : SolarMutexGuard aGuard;
2023 30 : SwFrameFormat* pFormat(GetFrameFormat());
2024 30 : if(!pFormat)
2025 0 : return {};
2026 30 : SwTable* pTable = SwTable::FindTable(pFormat);
2027 : // exists at the table and at all boxes
2028 30 : SwTableLines& rTableLines = pTable->GetTabLines();
2029 60 : std::vector<OUString> aAllNames;
2030 30 : lcl_InspectLines(rTableLines, aAllNames);
2031 60 : return comphelper::containerToSequence<OUString>(aAllNames);
2032 : }
2033 :
2034 6 : uno::Reference<text::XTextTableCursor> SwXTextTable::createCursorByCellName(const OUString& sCellName)
2035 : throw (uno::RuntimeException, std::exception)
2036 : {
2037 6 : SolarMutexGuard aGuard;
2038 6 : SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
2039 12 : uno::Reference<text::XTextTableCursor> xRet;
2040 6 : SwTable* pTable = SwTable::FindTable(pFormat);
2041 6 : SwTableBox* pBox = const_cast<SwTableBox*>(pTable->GetTableBox(sCellName));
2042 6 : if(!pBox || pBox->getRowSpan() == 0)
2043 0 : throw uno::RuntimeException();
2044 12 : return new SwXTextTableCursor(pFormat, pBox);
2045 : }
2046 :
2047 129 : void SwXTextTable::attachToRange(const uno::Reference< text::XTextRange > & xTextRange)
2048 : throw( lang::IllegalArgumentException, uno::RuntimeException )
2049 : {
2050 : // attachToRange must only be called once
2051 129 : if(!bIsDescriptor) /* already attached ? */
2052 0 : throw uno::RuntimeException("SwXTextTable: already attached to range.", static_cast<cppu::OWeakObject*>(this));
2053 :
2054 129 : uno::Reference<XUnoTunnel> xRangeTunnel(xTextRange, uno::UNO_QUERY);
2055 129 : SwXTextRange* pRange(nullptr);
2056 129 : OTextCursorHelper* pCursor(nullptr);
2057 129 : if(xRangeTunnel.is())
2058 : {
2059 : pRange = reinterpret_cast<SwXTextRange*>(
2060 129 : sal::static_int_cast<sal_IntPtr>(xRangeTunnel->getSomething(SwXTextRange::getUnoTunnelId())));
2061 : pCursor = reinterpret_cast<OTextCursorHelper*>(
2062 129 : sal::static_int_cast<sal_IntPtr>(xRangeTunnel->getSomething(OTextCursorHelper::getUnoTunnelId())));
2063 : }
2064 129 : SwDoc* pDoc = pRange ? pRange->GetDoc() : pCursor ? pCursor->GetDoc() : nullptr;
2065 129 : if(!pDoc || !nRows || !nColumns)
2066 0 : throw lang::IllegalArgumentException();
2067 258 : SwUnoInternalPaM aPam(*pDoc);
2068 : // this now needs to return TRUE
2069 129 : ::sw::XTextRangeToSwPaM(aPam, xTextRange);
2070 : {
2071 129 : UnoActionContext aCont(pDoc);
2072 :
2073 129 : pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL);
2074 129 : const SwTable* pTable(nullptr);
2075 129 : if( 0 != aPam.Start()->nContent.GetIndex() )
2076 : {
2077 0 : pDoc->getIDocumentContentOperations().SplitNode(*aPam.Start(), false);
2078 : }
2079 : //TODO: if it is the last paragraph than add another one!
2080 129 : if(aPam.HasMark())
2081 : {
2082 0 : pDoc->getIDocumentContentOperations().DeleteAndJoin(aPam);
2083 0 : aPam.DeleteMark();
2084 : }
2085 : pTable = pDoc->InsertTable(SwInsertTableOptions( tabopts::HEADLINE | tabopts::DEFAULT_BORDER | tabopts::SPLIT_LAYOUT, 0 ),
2086 129 : *aPam.GetPoint(),
2087 : nRows,
2088 : nColumns,
2089 258 : text::HoriOrientation::FULL);
2090 129 : if(pTable)
2091 : {
2092 : // here, the properties of the descriptor need to be analyzed
2093 129 : pTableProps->ApplyTableAttr(*pTable, *pDoc);
2094 129 : SwFrameFormat* pTableFormat(pTable->GetFrameFormat());
2095 129 : lcl_FormatTable(pTableFormat);
2096 :
2097 129 : pTableFormat->Add(this);
2098 129 : if(!m_sTableName.isEmpty())
2099 : {
2100 0 : sal_uInt16 nIndex = 1;
2101 0 : OUString sTmpNameIndex(m_sTableName);
2102 0 : while(pDoc->FindTableFormatByName(sTmpNameIndex, true) && nIndex < USHRT_MAX)
2103 : {
2104 0 : sTmpNameIndex = m_sTableName + OUString::number(nIndex++);
2105 : }
2106 0 : pDoc->SetTableName( *pTableFormat, sTmpNameIndex);
2107 : }
2108 :
2109 : const::uno::Any* pName;
2110 129 : if(pTableProps->GetProperty(FN_UNO_TABLE_NAME, 0, pName))
2111 0 : setName(pName->get<OUString>());
2112 129 : bIsDescriptor = false;
2113 129 : DELETEZ(pTableProps);
2114 : }
2115 129 : pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
2116 129 : }
2117 129 : }
2118 :
2119 129 : void SwXTextTable::attach(const uno::Reference< text::XTextRange > & xTextRange)
2120 : throw( lang::IllegalArgumentException, uno::RuntimeException, std::exception )
2121 : {
2122 129 : SolarMutexGuard aGuard;
2123 129 : attachToRange(xTextRange);
2124 129 : }
2125 :
2126 607 : uno::Reference<text::XTextRange> SwXTextTable::getAnchor()
2127 : throw( uno::RuntimeException, std::exception )
2128 : {
2129 607 : SolarMutexGuard aGuard;
2130 607 : SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
2131 607 : return new SwXTextRange(*pFormat);
2132 : }
2133 :
2134 3 : void SwXTextTable::dispose() throw( uno::RuntimeException, std::exception )
2135 : {
2136 3 : SolarMutexGuard aGuard;
2137 3 : SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
2138 3 : SwTable* pTable = SwTable::FindTable(pFormat);
2139 6 : SwSelBoxes aSelBoxes;
2140 63 : for(auto& rBox : pTable->GetTabSortBoxes() )
2141 60 : aSelBoxes.insert(rBox);
2142 6 : pFormat->GetDoc()->DeleteRowCol(aSelBoxes);
2143 3 : }
2144 :
2145 2 : void SAL_CALL SwXTextTable::addEventListener(
2146 : const uno::Reference<lang::XEventListener> & xListener)
2147 : throw (uno::RuntimeException, std::exception)
2148 : {
2149 : // no need to lock here as m_pImpl is const and container threadsafe
2150 2 : m_pImpl->m_Listeners.addInterface(
2151 4 : cppu::UnoType<lang::XEventListener>::get(), xListener);
2152 2 : }
2153 :
2154 1 : void SAL_CALL SwXTextTable::removeEventListener(
2155 : const uno::Reference< lang::XEventListener > & xListener)
2156 : throw (uno::RuntimeException, std::exception)
2157 : {
2158 : // no need to lock here as m_pImpl is const and container threadsafe
2159 1 : m_pImpl->m_Listeners.removeInterface(
2160 2 : cppu::UnoType<lang::XEventListener>::get(), xListener);
2161 1 : }
2162 :
2163 11319 : uno::Reference<table::XCell> SwXTextTable::getCellByPosition(sal_Int32 nColumn, sal_Int32 nRow)
2164 : throw( uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception )
2165 : {
2166 11319 : SolarMutexGuard aGuard;
2167 11319 : SwFrameFormat* pFormat(GetFrameFormat());
2168 : // sheet is unimportant
2169 11319 : if(nColumn >= 0 && nRow >= 0 && nColumn < USHRT_MAX && nRow < USHRT_MAX && pFormat)
2170 : {
2171 11318 : auto pXCell = lcl_CreateXCell(pFormat, nColumn, nRow);
2172 11318 : if(pXCell)
2173 22634 : return pXCell;
2174 : }
2175 2 : throw lang::IndexOutOfBoundsException();
2176 : }
2177 :
2178 45 : uno::Reference<table::XCellRange> SwXTextTable::GetRangeByName(SwFrameFormat* pFormat, SwTable* pTable,
2179 : const OUString& rTLName, const OUString& rBRName,
2180 : SwRangeDescriptor& rDesc)
2181 : {
2182 45 : SolarMutexGuard aGuard;
2183 45 : const SwTableBox* pTLBox = pTable->GetTableBox(rTLName);
2184 45 : if(!pTLBox)
2185 0 : return nullptr;
2186 : // invalidate all actions
2187 90 : UnoActionRemoveContext aRemoveContext(pFormat->GetDoc());
2188 45 : const SwStartNode* pSttNd = pTLBox->GetSttNd();
2189 90 : SwPosition aPos(*pSttNd);
2190 : // set cursor to the upper-left cell of the range
2191 90 : auto pUnoCrsr(pFormat->GetDoc()->CreateUnoCrsr(aPos, true));
2192 45 : pUnoCrsr->Move(fnMoveForward, fnGoNode);
2193 45 : pUnoCrsr->SetRemainInSection(false);
2194 45 : const SwTableBox* pBRBox(pTable->GetTableBox(rBRName));
2195 45 : if(!pBRBox)
2196 0 : return nullptr;
2197 45 : pUnoCrsr->SetMark();
2198 45 : pUnoCrsr->GetPoint()->nNode = *pBRBox->GetSttNd();
2199 45 : pUnoCrsr->Move( fnMoveForward, fnGoNode );
2200 45 : SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr.get());
2201 45 : pCrsr->MakeBoxSels();
2202 : // pUnoCrsr will be provided and will not be deleted
2203 90 : return new SwXCellRange(pUnoCrsr, *pFormat, rDesc);
2204 : }
2205 :
2206 45 : uno::Reference<table::XCellRange> SwXTextTable::getCellRangeByPosition(sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom)
2207 : throw(uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
2208 : {
2209 45 : SolarMutexGuard aGuard;
2210 45 : SwFrameFormat* pFormat(GetFrameFormat());
2211 45 : if(pFormat && nRight < USHRT_MAX && nBottom < USHRT_MAX &&
2212 45 : nLeft <= nRight && nTop <= nBottom &&
2213 44 : nLeft >= 0 && nRight >= 0 && nTop >= 0 && nBottom >= 0 )
2214 : {
2215 44 : SwTable* pTable = SwTable::FindTable(pFormat);
2216 44 : if(!pTable->IsTableComplex())
2217 : {
2218 : SwRangeDescriptor aDesc;
2219 44 : aDesc.nTop = nTop;
2220 44 : aDesc.nBottom = nBottom;
2221 44 : aDesc.nLeft = nLeft;
2222 44 : aDesc.nRight = nRight;
2223 44 : const OUString sTLName = sw_GetCellName(aDesc.nLeft, aDesc.nTop);
2224 88 : const OUString sBRName = sw_GetCellName(aDesc.nRight, aDesc.nBottom);
2225 : // please note that according to the 'if' statement at the begin
2226 : // sTLName:sBRName already denotes the normalized range string
2227 132 : return GetRangeByName(pFormat, pTable, sTLName, sBRName, aDesc);
2228 : }
2229 : }
2230 44 : throw lang::IndexOutOfBoundsException();
2231 : }
2232 :
2233 1 : uno::Reference<table::XCellRange> SwXTextTable::getCellRangeByName(const OUString& sRange)
2234 : throw (uno::RuntimeException, std::exception)
2235 : {
2236 1 : SolarMutexGuard aGuard;
2237 2 : uno::Reference< table::XCellRange > aRef;
2238 1 : SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
2239 1 : SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFormat), static_cast<cppu::OWeakObject*>(this));
2240 1 : sal_Int32 nPos = 0;
2241 2 : const OUString sTLName(sRange.getToken(0, ':', nPos));
2242 2 : const OUString sBRName(sRange.getToken(0, ':', nPos));
2243 1 : if(sTLName.isEmpty() || sBRName.isEmpty())
2244 0 : throw uno::RuntimeException();
2245 : SwRangeDescriptor aDesc;
2246 1 : aDesc.nTop = aDesc.nLeft = aDesc.nBottom = aDesc.nRight = -1;
2247 1 : sw_GetCellPosition(sTLName, aDesc.nLeft, aDesc.nTop );
2248 1 : sw_GetCellPosition(sBRName, aDesc.nRight, aDesc.nBottom );
2249 :
2250 : // we should normalize the range now (e.g. A5:C1 will become A1:C5)
2251 : // since (depending on what is done later) it will be troublesome
2252 : // elsewhere when the cursor in the implementation does not
2253 : // point to the top-left and bottom-right cells
2254 1 : aDesc.Normalize();
2255 2 : return GetRangeByName(pFormat, pTable, sTLName, sBRName, aDesc);
2256 : }
2257 :
2258 2 : uno::Sequence< uno::Sequence< uno::Any > > SAL_CALL SwXTextTable::getDataArray()
2259 : throw (uno::RuntimeException, std::exception)
2260 : {
2261 2 : SolarMutexGuard aGuard;
2262 2 : std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
2263 : uno::Reference<sheet::XCellRangeData> const xAllRange(
2264 2 : getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
2265 4 : uno::UNO_QUERY);
2266 4 : return xAllRange->getDataArray();
2267 : }
2268 :
2269 2 : void SAL_CALL SwXTextTable::setDataArray(const uno::Sequence< uno::Sequence< uno::Any > >& rArray)
2270 : throw (uno::RuntimeException, std::exception)
2271 : {
2272 2 : SolarMutexGuard aGuard;
2273 2 : std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
2274 : uno::Reference<sheet::XCellRangeData> const xAllRange(
2275 2 : getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
2276 4 : uno::UNO_QUERY);
2277 4 : return xAllRange->setDataArray(rArray);
2278 : }
2279 :
2280 9 : uno::Sequence< uno::Sequence< double > > SwXTextTable::getData()
2281 : throw( uno::RuntimeException, std::exception )
2282 : {
2283 9 : SolarMutexGuard aGuard;
2284 9 : std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
2285 : uno::Reference<chart::XChartDataArray> const xAllRange(
2286 9 : getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
2287 18 : uno::UNO_QUERY);
2288 9 : static_cast<SwXCellRange*>(xAllRange.get())->SetLabels(m_bFirstRowAsLabel, m_bFirstColumnAsLabel);
2289 18 : return xAllRange->getData();
2290 : }
2291 :
2292 7 : void SwXTextTable::setData(const uno::Sequence< uno::Sequence< double > >& rData)
2293 : throw( uno::RuntimeException, std::exception )
2294 : {
2295 7 : SolarMutexGuard aGuard;
2296 7 : std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
2297 : uno::Reference<chart::XChartDataArray> const xAllRange(
2298 7 : getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
2299 12 : uno::UNO_QUERY);
2300 7 : static_cast<SwXCellRange*>(xAllRange.get())->SetLabels(m_bFirstRowAsLabel, m_bFirstColumnAsLabel);
2301 7 : xAllRange->setData(rData);
2302 : // this is rather inconsistent: setData on XTextTable sends events, but e.g. CellRanges do not
2303 12 : lcl_SendChartEvent(*this, m_pImpl->m_Listeners);
2304 5 : }
2305 :
2306 8 : uno::Sequence<OUString> SwXTextTable::getRowDescriptions()
2307 : throw(uno::RuntimeException, std::exception)
2308 : {
2309 8 : SolarMutexGuard aGuard;
2310 8 : std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
2311 : uno::Reference<chart::XChartDataArray> const xAllRange(
2312 7 : getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
2313 14 : uno::UNO_QUERY);
2314 7 : static_cast<SwXCellRange*>(xAllRange.get())->SetLabels(m_bFirstRowAsLabel, m_bFirstColumnAsLabel);
2315 15 : return xAllRange->getRowDescriptions();
2316 : }
2317 :
2318 3 : void SwXTextTable::setRowDescriptions(const uno::Sequence<OUString>& rRowDesc)
2319 : throw(uno::RuntimeException, std::exception)
2320 : {
2321 3 : SolarMutexGuard aGuard;
2322 3 : std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
2323 : uno::Reference<chart::XChartDataArray> const xAllRange(
2324 3 : getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
2325 5 : uno::UNO_QUERY);
2326 3 : static_cast<SwXCellRange*>(xAllRange.get())->SetLabels(m_bFirstRowAsLabel, m_bFirstColumnAsLabel);
2327 6 : xAllRange->setRowDescriptions(rRowDesc);
2328 2 : }
2329 :
2330 8 : uno::Sequence<OUString> SwXTextTable::getColumnDescriptions()
2331 : throw(uno::RuntimeException, std::exception)
2332 : {
2333 8 : SolarMutexGuard aGuard;
2334 8 : std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
2335 : uno::Reference<chart::XChartDataArray> const xAllRange(
2336 7 : getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
2337 14 : uno::UNO_QUERY);
2338 7 : static_cast<SwXCellRange*>(xAllRange.get())->SetLabels(m_bFirstRowAsLabel, m_bFirstColumnAsLabel);
2339 15 : return xAllRange->getColumnDescriptions();
2340 : }
2341 :
2342 3 : void SwXTextTable::setColumnDescriptions(const uno::Sequence<OUString>& rColumnDesc)
2343 : throw(uno::RuntimeException, std::exception)
2344 : {
2345 3 : SolarMutexGuard aGuard;
2346 3 : std::pair<sal_uInt16, sal_uInt16> const RowsAndColumns(SwXTextTable::Impl::ThrowIfComplex(*this));
2347 : uno::Reference<chart::XChartDataArray> const xAllRange(
2348 3 : getCellRangeByPosition(0, 0, RowsAndColumns.second-1, RowsAndColumns.first-1),
2349 5 : uno::UNO_QUERY);
2350 3 : static_cast<SwXCellRange*>(xAllRange.get())->SetLabels(m_bFirstRowAsLabel, m_bFirstColumnAsLabel);
2351 6 : return xAllRange->setColumnDescriptions(rColumnDesc);
2352 : }
2353 :
2354 2 : void SAL_CALL SwXTextTable::addChartDataChangeEventListener(
2355 : const uno::Reference<chart::XChartDataChangeEventListener> & xListener)
2356 : throw (uno::RuntimeException, std::exception)
2357 : {
2358 : // no need to lock here as m_pImpl is const and container threadsafe
2359 2 : m_pImpl->m_Listeners.addInterface(
2360 4 : cppu::UnoType<chart::XChartDataChangeEventListener>::get(), xListener);
2361 2 : }
2362 :
2363 2 : void SAL_CALL SwXTextTable::removeChartDataChangeEventListener(
2364 : const uno::Reference<chart::XChartDataChangeEventListener> & xListener)
2365 : throw (uno::RuntimeException, std::exception)
2366 : {
2367 : // no need to lock here as m_pImpl is const and container threadsafe
2368 2 : m_pImpl->m_Listeners.removeInterface(
2369 4 : cppu::UnoType<chart::XChartDataChangeEventListener>::get(), xListener);
2370 2 : }
2371 :
2372 2 : sal_Bool SwXTextTable::isNotANumber(double nNumber) throw( uno::RuntimeException, std::exception )
2373 : {
2374 : // We use DBL_MIN because starcalc does (which uses it because chart
2375 : // wants it that way!)
2376 2 : return ( nNumber == DBL_MIN );
2377 : }
2378 :
2379 1 : double SwXTextTable::getNotANumber() throw( uno::RuntimeException, std::exception )
2380 : {
2381 : // We use DBL_MIN because starcalc does (which uses it because chart
2382 : // wants it that way!)
2383 1 : return DBL_MIN;
2384 : }
2385 :
2386 1 : uno::Sequence< beans::PropertyValue > SwXTextTable::createSortDescriptor()
2387 : throw( uno::RuntimeException, std::exception )
2388 : {
2389 1 : SolarMutexGuard aGuard;
2390 :
2391 1 : return SwUnoCursorHelper::CreateSortDescriptor(true);
2392 : }
2393 :
2394 4 : void SwXTextTable::sort(const uno::Sequence< beans::PropertyValue >& rDescriptor)
2395 : throw (uno::RuntimeException, std::exception)
2396 : {
2397 4 : SolarMutexGuard aGuard;
2398 8 : SwSortOptions aSortOpt;
2399 4 : SwFrameFormat* pFormat = GetFrameFormat();
2400 8 : if(pFormat &&
2401 4 : SwUnoCursorHelper::ConvertSortProperties(rDescriptor, aSortOpt))
2402 : {
2403 4 : SwTable* pTable = SwTable::FindTable( pFormat );
2404 4 : SwSelBoxes aBoxes;
2405 4 : const SwTableSortBoxes& rTBoxes = pTable->GetTabSortBoxes();
2406 52 : for (size_t n = 0; n < rTBoxes.size(); ++n)
2407 : {
2408 48 : SwTableBox* pBox = rTBoxes[ n ];
2409 48 : aBoxes.insert( pBox );
2410 : }
2411 8 : UnoActionContext aContext( pFormat->GetDoc() );
2412 8 : pFormat->GetDoc()->SortTable(aBoxes, aSortOpt);
2413 4 : }
2414 4 : }
2415 :
2416 0 : void SwXTextTable::autoFormat(const OUString& sAutoFormatName)
2417 : throw (lang::IllegalArgumentException, uno::RuntimeException,
2418 : std::exception)
2419 : {
2420 0 : SolarMutexGuard aGuard;
2421 0 : SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
2422 0 : SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFormat), static_cast<cppu::OWeakObject*>(this));
2423 0 : SwTableAutoFormatTable aAutoFormatTable;
2424 0 : aAutoFormatTable.Load();
2425 0 : for (size_t i = aAutoFormatTable.size(); i;)
2426 0 : if( sAutoFormatName == aAutoFormatTable[ --i ].GetName() )
2427 : {
2428 0 : SwSelBoxes aBoxes;
2429 0 : const SwTableSortBoxes& rTBoxes = pTable->GetTabSortBoxes();
2430 0 : for (size_t n = 0; n < rTBoxes.size(); ++n)
2431 : {
2432 0 : SwTableBox* pBox = rTBoxes[ n ];
2433 0 : aBoxes.insert( pBox );
2434 : }
2435 0 : UnoActionContext aContext( pFormat->GetDoc() );
2436 0 : pFormat->GetDoc()->SetTableAutoFormat( aBoxes, aAutoFormatTable[i] );
2437 0 : break;
2438 0 : }
2439 0 : }
2440 :
2441 74 : uno::Reference< beans::XPropertySetInfo > SwXTextTable::getPropertySetInfo() throw( uno::RuntimeException, std::exception )
2442 : {
2443 74 : static uno::Reference< beans::XPropertySetInfo > xRef = m_pPropSet->getPropertySetInfo();
2444 74 : return xRef;
2445 : }
2446 :
2447 7930 : void SwXTextTable::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
2448 : throw(beans::UnknownPropertyException, beans::PropertyVetoException,
2449 : lang::IllegalArgumentException, lang::WrappedTargetException,
2450 : uno::RuntimeException, std::exception)
2451 : {
2452 7930 : SolarMutexGuard aGuard;
2453 7930 : SwFrameFormat* pFormat = GetFrameFormat();
2454 7930 : if(!aValue.hasValue())
2455 0 : throw lang::IllegalArgumentException();
2456 : const SfxItemPropertySimpleEntry* pEntry =
2457 7930 : m_pPropSet->getPropertyMap().getByName(rPropertyName);
2458 7930 : if( !pEntry )
2459 2367 : throw lang::IllegalArgumentException();
2460 5563 : if(pFormat)
2461 : {
2462 5562 : if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
2463 4 : throw beans::PropertyVetoException("Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
2464 :
2465 5558 : if(0xFF == pEntry->nMemberId)
2466 : {
2467 1314 : lcl_SetSpecialProperty(pFormat, pEntry, aValue);
2468 : }
2469 : else
2470 : {
2471 4244 : switch(pEntry->nWID)
2472 : {
2473 : case FN_UNO_TABLE_NAME :
2474 : {
2475 0 : OUString sName;
2476 0 : aValue >>= sName;
2477 0 : setName( sName );
2478 : }
2479 0 : break;
2480 :
2481 : case FN_UNO_RANGE_ROW_LABEL:
2482 : {
2483 14 : bool bTmp = *static_cast<sal_Bool const *>(aValue.getValue());
2484 14 : if(m_bFirstRowAsLabel != bTmp)
2485 : {
2486 12 : lcl_SendChartEvent(*this, m_pImpl->m_Listeners);
2487 12 : m_bFirstRowAsLabel = bTmp;
2488 : }
2489 : }
2490 14 : break;
2491 :
2492 : case FN_UNO_RANGE_COL_LABEL:
2493 : {
2494 14 : bool bTmp = *static_cast<sal_Bool const *>(aValue.getValue());
2495 14 : if(m_bFirstColumnAsLabel != bTmp)
2496 : {
2497 10 : lcl_SendChartEvent(*this, m_pImpl->m_Listeners);
2498 10 : m_bFirstColumnAsLabel = bTmp;
2499 : }
2500 : }
2501 14 : break;
2502 :
2503 : case FN_UNO_TABLE_BORDER:
2504 : case FN_UNO_TABLE_BORDER2:
2505 : {
2506 608 : table::TableBorder oldBorder;
2507 608 : table::TableBorder2 aBorder;
2508 608 : SvxBorderLine aTopLine;
2509 608 : SvxBorderLine aBottomLine;
2510 608 : SvxBorderLine aLeftLine;
2511 608 : SvxBorderLine aRightLine;
2512 608 : SvxBorderLine aHoriLine;
2513 608 : SvxBorderLine aVertLine;
2514 608 : if (aValue >>= oldBorder)
2515 : {
2516 606 : aBorder.IsTopLineValid = oldBorder.IsTopLineValid;
2517 606 : aBorder.IsBottomLineValid = oldBorder.IsBottomLineValid;
2518 606 : aBorder.IsLeftLineValid = oldBorder.IsLeftLineValid;
2519 606 : aBorder.IsRightLineValid = oldBorder.IsRightLineValid;
2520 606 : aBorder.IsHorizontalLineValid = oldBorder.IsHorizontalLineValid;
2521 606 : aBorder.IsVerticalLineValid = oldBorder.IsVerticalLineValid;
2522 606 : aBorder.Distance = oldBorder.Distance;
2523 606 : aBorder.IsDistanceValid = oldBorder.IsDistanceValid;
2524 : lcl_LineToSvxLine(
2525 606 : oldBorder.TopLine, aTopLine);
2526 : lcl_LineToSvxLine(
2527 606 : oldBorder.BottomLine, aBottomLine);
2528 : lcl_LineToSvxLine(
2529 606 : oldBorder.LeftLine, aLeftLine);
2530 : lcl_LineToSvxLine(
2531 606 : oldBorder.RightLine, aRightLine);
2532 : lcl_LineToSvxLine(
2533 606 : oldBorder.HorizontalLine, aHoriLine);
2534 : lcl_LineToSvxLine(
2535 606 : oldBorder.VerticalLine, aVertLine);
2536 : }
2537 2 : else if (aValue >>= aBorder)
2538 : {
2539 : SvxBoxItem::LineToSvxLine(
2540 2 : aBorder.TopLine, aTopLine, true);
2541 : SvxBoxItem::LineToSvxLine(
2542 2 : aBorder.BottomLine, aBottomLine, true);
2543 : SvxBoxItem::LineToSvxLine(
2544 2 : aBorder.LeftLine, aLeftLine, true);
2545 : SvxBoxItem::LineToSvxLine(
2546 2 : aBorder.RightLine, aRightLine, true);
2547 : SvxBoxItem::LineToSvxLine(
2548 2 : aBorder.HorizontalLine, aHoriLine, true);
2549 : SvxBoxItem::LineToSvxLine(
2550 2 : aBorder.VerticalLine, aVertLine, true);
2551 : }
2552 : else
2553 : {
2554 603 : break; // something else
2555 : }
2556 608 : SwDoc* pDoc = pFormat->GetDoc();
2557 608 : if(!lcl_FormatTable(pFormat))
2558 603 : break;
2559 5 : SwTable* pTable = SwTable::FindTable( pFormat );
2560 5 : SwTableLines &rLines = pTable->GetTabLines();
2561 :
2562 : // invalidate all actions
2563 5 : UnoActionRemoveContext aRemoveContext(pDoc);
2564 5 : const SwTableBox* pTLBox = lcl_FindCornerTableBox(rLines, true);
2565 5 : const SwStartNode* pSttNd = pTLBox->GetSttNd();
2566 10 : SwPosition aPos(*pSttNd);
2567 : // set cursor to top left cell
2568 10 : auto pUnoCrsr(pDoc->CreateUnoCrsr(aPos, true));
2569 5 : pUnoCrsr->Move( fnMoveForward, fnGoNode );
2570 5 : pUnoCrsr->SetRemainInSection( false );
2571 :
2572 5 : const SwTableBox* pBRBox = lcl_FindCornerTableBox(rLines, false);
2573 5 : pUnoCrsr->SetMark();
2574 5 : pUnoCrsr->GetPoint()->nNode = *pBRBox->GetSttNd();
2575 5 : pUnoCrsr->Move( fnMoveForward, fnGoNode );
2576 5 : SwUnoTableCrsr& rCrsr = dynamic_cast<SwUnoTableCrsr&>(*pUnoCrsr);
2577 5 : rCrsr.MakeBoxSels();
2578 :
2579 5 : SfxItemSet aSet(pDoc->GetAttrPool(),
2580 : RES_BOX, RES_BOX,
2581 : SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
2582 10 : 0);
2583 :
2584 10 : SvxBoxItem aBox( RES_BOX );
2585 10 : SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER );
2586 :
2587 5 : aBox.SetLine(aTopLine.isEmpty() ? 0 : &aTopLine, SvxBoxItemLine::TOP);
2588 5 : aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::TOP, aBorder.IsTopLineValid);
2589 :
2590 5 : aBox.SetLine(aBottomLine.isEmpty() ? 0 : &aBottomLine, SvxBoxItemLine::BOTTOM);
2591 5 : aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::BOTTOM, aBorder.IsBottomLineValid);
2592 :
2593 5 : aBox.SetLine(aLeftLine.isEmpty() ? 0 : &aLeftLine, SvxBoxItemLine::LEFT);
2594 5 : aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::LEFT, aBorder.IsLeftLineValid);
2595 :
2596 5 : aBox.SetLine(aRightLine.isEmpty() ? 0 : &aRightLine, SvxBoxItemLine::RIGHT);
2597 5 : aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::RIGHT, aBorder.IsRightLineValid);
2598 :
2599 5 : aBoxInfo.SetLine(aHoriLine.isEmpty() ? 0 : &aHoriLine, SvxBoxInfoItemLine::HORI);
2600 5 : aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::HORI, aBorder.IsHorizontalLineValid);
2601 :
2602 5 : aBoxInfo.SetLine(aVertLine.isEmpty() ? 0 : &aVertLine, SvxBoxInfoItemLine::VERT);
2603 5 : aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::VERT, aBorder.IsVerticalLineValid);
2604 :
2605 5 : aBox.SetDistance((sal_uInt16)convertMm100ToTwip(aBorder.Distance));
2606 5 : aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::DISTANCE, aBorder.IsDistanceValid);
2607 :
2608 5 : aSet.Put(aBox);
2609 5 : aSet.Put(aBoxInfo);
2610 :
2611 10 : pDoc->SetTabBorders(rCrsr, aSet);
2612 : }
2613 5 : break;
2614 :
2615 : case FN_UNO_TABLE_BORDER_DISTANCES:
2616 : {
2617 603 : table::TableBorderDistances aTableBorderDistances;
2618 1206 : if( !(aValue >>= aTableBorderDistances) ||
2619 603 : (!aTableBorderDistances.IsLeftDistanceValid &&
2620 0 : !aTableBorderDistances.IsRightDistanceValid &&
2621 0 : !aTableBorderDistances.IsTopDistanceValid &&
2622 0 : !aTableBorderDistances.IsBottomDistanceValid ))
2623 0 : break;
2624 :
2625 603 : const sal_uInt16 nLeftDistance = convertMm100ToTwip(aTableBorderDistances.LeftDistance);
2626 603 : const sal_uInt16 nRightDistance = convertMm100ToTwip(aTableBorderDistances.RightDistance);
2627 603 : const sal_uInt16 nTopDistance = convertMm100ToTwip(aTableBorderDistances.TopDistance);
2628 603 : const sal_uInt16 nBottomDistance = convertMm100ToTwip(aTableBorderDistances.BottomDistance);
2629 603 : SwDoc* pDoc = pFormat->GetDoc();
2630 603 : SwTable* pTable = SwTable::FindTable( pFormat );
2631 603 : SwTableLines &rLines = pTable->GetTabLines();
2632 603 : pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_START, NULL);
2633 3533 : for(size_t i = 0; i < rLines.size(); ++i)
2634 : {
2635 2930 : SwTableLine* pLine = rLines[i];
2636 2930 : SwTableBoxes& rBoxes = pLine->GetTabBoxes();
2637 11153 : for(size_t k = 0; k < rBoxes.size(); ++k)
2638 : {
2639 8223 : SwTableBox* pBox = rBoxes[k];
2640 8223 : const SwFrameFormat* pBoxFormat = pBox->GetFrameFormat();
2641 8223 : const SvxBoxItem& rBox = pBoxFormat->GetBox();
2642 8223 : if(
2643 8223 : (aTableBorderDistances.IsLeftDistanceValid && nLeftDistance != rBox.GetDistance( SvxBoxItemLine::LEFT )) ||
2644 442 : (aTableBorderDistances.IsRightDistanceValid && nRightDistance != rBox.GetDistance( SvxBoxItemLine::RIGHT )) ||
2645 16446 : (aTableBorderDistances.IsTopDistanceValid && nTopDistance != rBox.GetDistance( SvxBoxItemLine::TOP )) ||
2646 382 : (aTableBorderDistances.IsBottomDistanceValid && nBottomDistance != rBox.GetDistance( SvxBoxItemLine::BOTTOM )))
2647 : {
2648 7841 : SvxBoxItem aSetBox( rBox );
2649 7841 : SwFrameFormat* pSetBoxFormat = pBox->ClaimFrameFormat();
2650 7841 : if( aTableBorderDistances.IsLeftDistanceValid )
2651 7841 : aSetBox.SetDistance( nLeftDistance, SvxBoxItemLine::LEFT );
2652 7841 : if( aTableBorderDistances.IsRightDistanceValid )
2653 7841 : aSetBox.SetDistance( nRightDistance, SvxBoxItemLine::RIGHT );
2654 7841 : if( aTableBorderDistances.IsTopDistanceValid )
2655 7841 : aSetBox.SetDistance( nTopDistance, SvxBoxItemLine::TOP );
2656 7841 : if( aTableBorderDistances.IsBottomDistanceValid )
2657 7841 : aSetBox.SetDistance( nBottomDistance, SvxBoxItemLine::BOTTOM );
2658 7841 : pDoc->SetAttr( aSetBox, *pSetBoxFormat );
2659 : }
2660 : }
2661 : }
2662 603 : pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_END, NULL);
2663 : }
2664 603 : break;
2665 :
2666 : case FN_UNO_TABLE_COLUMN_SEPARATORS:
2667 : {
2668 1 : UnoActionContext aContext(pFormat->GetDoc());
2669 1 : SwTable* pTable = SwTable::FindTable( pFormat );
2670 1 : lcl_SetTableSeparators(aValue, pTable, pTable->GetTabLines()[0]->GetTabBoxes()[0], false, pFormat->GetDoc());
2671 : }
2672 1 : break;
2673 :
2674 0 : case FN_UNO_TABLE_COLUMN_RELATIVE_SUM:/*_readonly_*/ break;
2675 :
2676 : default:
2677 : {
2678 3004 : SwAttrSet aSet(pFormat->GetAttrSet());
2679 3004 : m_pPropSet->setPropertyValue(*pEntry, aValue, aSet);
2680 3004 : pFormat->GetDoc()->SetAttr(aSet, *pFormat);
2681 : }
2682 : }
2683 : }
2684 : }
2685 1 : else if(bIsDescriptor)
2686 : {
2687 1 : pTableProps->SetProperty( pEntry->nWID, pEntry->nMemberId, aValue);
2688 : }
2689 : else
2690 0 : throw uno::RuntimeException();
2691 5491 : }
2692 :
2693 399 : uno::Any SwXTextTable::getPropertyValue(const OUString& rPropertyName)
2694 : throw (beans::UnknownPropertyException,
2695 : lang::WrappedTargetException,
2696 : uno::RuntimeException,
2697 : std::exception)
2698 : {
2699 399 : SolarMutexGuard aGuard;
2700 399 : uno::Any aRet;
2701 399 : SwFrameFormat* pFormat = GetFrameFormat();
2702 : const SfxItemPropertySimpleEntry* pEntry =
2703 399 : m_pPropSet->getPropertyMap().getByName(rPropertyName);
2704 :
2705 399 : if (!pEntry)
2706 0 : throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
2707 :
2708 399 : if(pFormat)
2709 : {
2710 399 : if(0xFF == pEntry->nMemberId)
2711 : {
2712 315 : aRet = lcl_GetSpecialProperty(pFormat, pEntry );
2713 : }
2714 : else
2715 : {
2716 84 : switch(pEntry->nWID)
2717 : {
2718 : case FN_UNO_TABLE_NAME:
2719 : {
2720 0 : aRet <<= getName();
2721 : }
2722 0 : break;
2723 :
2724 : case FN_UNO_ANCHOR_TYPES:
2725 : case FN_UNO_TEXT_WRAP:
2726 : case FN_UNO_ANCHOR_TYPE:
2727 : ::sw::GetDefaultTextContentValue(
2728 4 : aRet, OUString(), pEntry->nWID);
2729 4 : break;
2730 :
2731 : case FN_UNO_RANGE_ROW_LABEL:
2732 : {
2733 3 : aRet <<= m_bFirstRowAsLabel;
2734 : }
2735 3 : break;
2736 :
2737 : case FN_UNO_RANGE_COL_LABEL:
2738 3 : aRet <<= m_bFirstColumnAsLabel;
2739 3 : break;
2740 :
2741 : case FN_UNO_TABLE_BORDER:
2742 : case FN_UNO_TABLE_BORDER2:
2743 : {
2744 14 : SwDoc* pDoc = pFormat->GetDoc();
2745 : // tables without layout (invisible header/footer?)
2746 14 : if(!lcl_FormatTable(pFormat))
2747 0 : break;
2748 14 : SwTable* pTable = SwTable::FindTable( pFormat );
2749 14 : SwTableLines &rLines = pTable->GetTabLines();
2750 :
2751 : // invalidate all actions
2752 14 : UnoActionRemoveContext aRemoveContext(pDoc);
2753 14 : const SwTableBox* pTLBox = lcl_FindCornerTableBox(rLines, true);
2754 14 : const SwStartNode* pSttNd = pTLBox->GetSttNd();
2755 28 : SwPosition aPos(*pSttNd);
2756 : // set cursor to top left cell
2757 28 : auto pUnoCrsr(pDoc->CreateUnoCrsr(aPos, true));
2758 14 : pUnoCrsr->Move( fnMoveForward, fnGoNode );
2759 14 : pUnoCrsr->SetRemainInSection( false );
2760 :
2761 14 : const SwTableBox* pBRBox = lcl_FindCornerTableBox(rLines, false);
2762 14 : pUnoCrsr->SetMark();
2763 14 : const SwStartNode* pLastNd = pBRBox->GetSttNd();
2764 14 : pUnoCrsr->GetPoint()->nNode = *pLastNd;
2765 :
2766 14 : pUnoCrsr->Move( fnMoveForward, fnGoNode );
2767 14 : SwUnoTableCrsr& rCrsr = dynamic_cast<SwUnoTableCrsr&>(*pUnoCrsr);
2768 14 : rCrsr.MakeBoxSels();
2769 :
2770 14 : SfxItemSet aSet(pDoc->GetAttrPool(),
2771 : RES_BOX, RES_BOX,
2772 : SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
2773 28 : 0);
2774 14 : aSet.Put(SvxBoxInfoItem( SID_ATTR_BORDER_INNER ));
2775 14 : SwDoc::GetTabBorders(rCrsr, aSet);
2776 : const SvxBoxInfoItem& rBoxInfoItem =
2777 14 : static_cast<const SvxBoxInfoItem&>(aSet.Get(SID_ATTR_BORDER_INNER));
2778 14 : const SvxBoxItem& rBox = static_cast<const SvxBoxItem&>(aSet.Get(RES_BOX));
2779 :
2780 14 : if (FN_UNO_TABLE_BORDER == pEntry->nWID)
2781 : {
2782 7 : table::TableBorder aTableBorder;
2783 7 : aTableBorder.TopLine = SvxBoxItem::SvxLineToLine(rBox.GetTop(), true);
2784 7 : aTableBorder.IsTopLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::TOP);
2785 7 : aTableBorder.BottomLine = SvxBoxItem::SvxLineToLine(rBox.GetBottom(), true);
2786 7 : aTableBorder.IsBottomLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::BOTTOM);
2787 7 : aTableBorder.LeftLine = SvxBoxItem::SvxLineToLine(rBox.GetLeft(), true);
2788 7 : aTableBorder.IsLeftLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::LEFT);
2789 7 : aTableBorder.RightLine = SvxBoxItem::SvxLineToLine(rBox.GetRight(), true);
2790 7 : aTableBorder.IsRightLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::RIGHT );
2791 7 : aTableBorder.HorizontalLine = SvxBoxItem::SvxLineToLine(rBoxInfoItem.GetHori(), true);
2792 7 : aTableBorder.IsHorizontalLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::HORI);
2793 7 : aTableBorder.VerticalLine = SvxBoxItem::SvxLineToLine(rBoxInfoItem.GetVert(), true);
2794 7 : aTableBorder.IsVerticalLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::VERT);
2795 7 : aTableBorder.Distance = convertTwipToMm100( rBox.GetDistance() );
2796 7 : aTableBorder.IsDistanceValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::DISTANCE);
2797 7 : aRet <<= aTableBorder;
2798 : }
2799 : else
2800 : {
2801 7 : table::TableBorder2 aTableBorder;
2802 7 : aTableBorder.TopLine = SvxBoxItem::SvxLineToLine(rBox.GetTop(), true);
2803 7 : aTableBorder.IsTopLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::TOP);
2804 7 : aTableBorder.BottomLine = SvxBoxItem::SvxLineToLine(rBox.GetBottom(), true);
2805 7 : aTableBorder.IsBottomLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::BOTTOM);
2806 7 : aTableBorder.LeftLine = SvxBoxItem::SvxLineToLine(rBox.GetLeft(), true);
2807 7 : aTableBorder.IsLeftLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::LEFT);
2808 7 : aTableBorder.RightLine = SvxBoxItem::SvxLineToLine(rBox.GetRight(), true);
2809 7 : aTableBorder.IsRightLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::RIGHT );
2810 7 : aTableBorder.HorizontalLine = SvxBoxItem::SvxLineToLine(rBoxInfoItem.GetHori(), true);
2811 7 : aTableBorder.IsHorizontalLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::HORI);
2812 7 : aTableBorder.VerticalLine = SvxBoxItem::SvxLineToLine(rBoxInfoItem.GetVert(), true);
2813 7 : aTableBorder.IsVerticalLineValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::VERT);
2814 7 : aTableBorder.Distance = convertTwipToMm100( rBox.GetDistance() );
2815 7 : aTableBorder.IsDistanceValid = rBoxInfoItem.IsValid(SvxBoxInfoItemValidFlags::DISTANCE);
2816 7 : aRet <<= aTableBorder;
2817 14 : }
2818 : }
2819 14 : break;
2820 :
2821 : case FN_UNO_TABLE_BORDER_DISTANCES :
2822 : {
2823 0 : table::TableBorderDistances aTableBorderDistances( 0, sal_True, 0, sal_True, 0, sal_True, 0, sal_True ) ;
2824 0 : SwTable* pTable = SwTable::FindTable( pFormat );
2825 0 : const SwTableLines &rLines = pTable->GetTabLines();
2826 0 : bool bFirst = true;
2827 0 : sal_uInt16 nLeftDistance = 0;
2828 0 : sal_uInt16 nRightDistance = 0;
2829 0 : sal_uInt16 nTopDistance = 0;
2830 0 : sal_uInt16 nBottomDistance = 0;
2831 :
2832 0 : for(size_t i = 0; i < rLines.size(); ++i)
2833 : {
2834 0 : const SwTableLine* pLine = rLines[i];
2835 0 : const SwTableBoxes& rBoxes = pLine->GetTabBoxes();
2836 0 : for(size_t k = 0; k < rBoxes.size(); ++k)
2837 : {
2838 0 : const SwTableBox* pBox = rBoxes[k];
2839 0 : SwFrameFormat* pBoxFormat = pBox->GetFrameFormat();
2840 0 : const SvxBoxItem& rBox = pBoxFormat->GetBox();
2841 0 : if( bFirst )
2842 : {
2843 0 : nLeftDistance = convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::LEFT ));
2844 0 : nRightDistance = convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::RIGHT ));
2845 0 : nTopDistance = convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::TOP ));
2846 0 : nBottomDistance = convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::BOTTOM ));
2847 0 : bFirst = false;
2848 : }
2849 : else
2850 : {
2851 0 : if( aTableBorderDistances.IsLeftDistanceValid &&
2852 0 : nLeftDistance != convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::LEFT )))
2853 0 : aTableBorderDistances.IsLeftDistanceValid = sal_False;
2854 0 : if( aTableBorderDistances.IsRightDistanceValid &&
2855 0 : nRightDistance != convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::RIGHT )))
2856 0 : aTableBorderDistances.IsRightDistanceValid = sal_False;
2857 0 : if( aTableBorderDistances.IsTopDistanceValid &&
2858 0 : nTopDistance != convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::TOP )))
2859 0 : aTableBorderDistances.IsTopDistanceValid = sal_False;
2860 0 : if( aTableBorderDistances.IsBottomDistanceValid &&
2861 0 : nBottomDistance != convertTwipToMm100( rBox.GetDistance( SvxBoxItemLine::BOTTOM )))
2862 0 : aTableBorderDistances.IsBottomDistanceValid = sal_False;
2863 : }
2864 :
2865 : }
2866 0 : if( !aTableBorderDistances.IsLeftDistanceValid &&
2867 0 : !aTableBorderDistances.IsRightDistanceValid &&
2868 0 : !aTableBorderDistances.IsTopDistanceValid &&
2869 0 : !aTableBorderDistances.IsBottomDistanceValid )
2870 0 : break;
2871 : }
2872 0 : if( aTableBorderDistances.IsLeftDistanceValid)
2873 0 : aTableBorderDistances.LeftDistance = nLeftDistance;
2874 0 : if( aTableBorderDistances.IsRightDistanceValid)
2875 0 : aTableBorderDistances.RightDistance = nRightDistance;
2876 0 : if( aTableBorderDistances.IsTopDistanceValid)
2877 0 : aTableBorderDistances.TopDistance = nTopDistance;
2878 0 : if( aTableBorderDistances.IsBottomDistanceValid)
2879 0 : aTableBorderDistances.BottomDistance = nBottomDistance;
2880 :
2881 0 : aRet <<= aTableBorderDistances;
2882 : }
2883 0 : break;
2884 :
2885 : case FN_UNO_TABLE_COLUMN_SEPARATORS:
2886 : {
2887 2 : SwTable* pTable = SwTable::FindTable( pFormat );
2888 2 : lcl_GetTableSeparators(aRet, pTable, pTable->GetTabLines()[0]->GetTabBoxes()[0], false);
2889 : }
2890 2 : break;
2891 :
2892 : case FN_UNO_TABLE_COLUMN_RELATIVE_SUM:
2893 2 : aRet <<= (sal_Int16) UNO_TABLE_COLUMN_SUM;
2894 2 : break;
2895 :
2896 : case RES_ANCHOR:
2897 : // AnchorType is readonly and might be void (no return value)
2898 0 : break;
2899 :
2900 : case FN_UNO_TEXT_SECTION:
2901 : {
2902 14 : SwTable* pTable = SwTable::FindTable( pFormat );
2903 14 : SwTableNode* pTableNode = pTable->GetTableNode();
2904 14 : SwSectionNode* pSectionNode = pTableNode->FindSectionNode();
2905 14 : if(pSectionNode)
2906 : {
2907 0 : SwSection& rSect = pSectionNode->GetSection();
2908 : uno::Reference< text::XTextSection > xSect =
2909 0 : SwXTextSections::GetObject( *rSect.GetFormat() );
2910 0 : aRet <<= xSect;
2911 : }
2912 : }
2913 14 : break;
2914 :
2915 : default:
2916 : {
2917 42 : const SwAttrSet& rSet = pFormat->GetAttrSet();
2918 42 : m_pPropSet->getPropertyValue(*pEntry, rSet, aRet);
2919 : }
2920 : }
2921 : }
2922 : }
2923 0 : else if(bIsDescriptor)
2924 : {
2925 0 : const uno::Any* pAny = 0;
2926 0 : if(!pTableProps->GetProperty(pEntry->nWID, pEntry->nMemberId, pAny))
2927 0 : throw lang::IllegalArgumentException();
2928 0 : else if(pAny)
2929 0 : aRet = *pAny;
2930 : }
2931 : else
2932 0 : throw uno::RuntimeException();
2933 399 : return aRet;
2934 : }
2935 :
2936 0 : void SwXTextTable::addPropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
2937 0 : { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
2938 :
2939 0 : void SwXTextTable::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
2940 0 : { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
2941 :
2942 0 : void SwXTextTable::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
2943 0 : { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
2944 :
2945 0 : void SwXTextTable::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
2946 0 : { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
2947 :
2948 3 : OUString SwXTextTable::getName() throw( uno::RuntimeException, std::exception )
2949 : {
2950 3 : SolarMutexGuard aGuard;
2951 3 : SwFrameFormat* pFormat = GetFrameFormat();
2952 3 : if(!pFormat && !bIsDescriptor)
2953 0 : throw uno::RuntimeException();
2954 3 : if(pFormat)
2955 : {
2956 3 : return pFormat->GetName();
2957 : }
2958 0 : return m_sTableName;
2959 : }
2960 :
2961 2 : void SwXTextTable::setName(const OUString& rName) throw( uno::RuntimeException, std::exception )
2962 : {
2963 2 : SolarMutexGuard aGuard;
2964 2 : SwFrameFormat* pFormat = GetFrameFormat();
2965 4 : if((!pFormat && !bIsDescriptor) ||
2966 4 : rName.isEmpty() ||
2967 6 : rName.indexOf('.')>=0 ||
2968 2 : rName.indexOf(' ')>=0 )
2969 0 : throw uno::RuntimeException();
2970 :
2971 2 : if(pFormat)
2972 : {
2973 2 : const OUString aOldName( pFormat->GetName() );
2974 2 : const SwFrameFormats* pFrameFormats = pFormat->GetDoc()->GetTableFrameFormats();
2975 6 : for (size_t i = pFrameFormats->size(); i;)
2976 : {
2977 2 : const SwFrameFormat* pTmpFormat = (*pFrameFormats)[--i];
2978 10 : if( !pTmpFormat->IsDefault() &&
2979 10 : pTmpFormat->GetName() == rName &&
2980 0 : pFormat->GetDoc()->IsUsed( *pTmpFormat ))
2981 : {
2982 0 : throw uno::RuntimeException();
2983 : }
2984 : }
2985 :
2986 2 : pFormat->SetName( rName );
2987 :
2988 : SwStartNode *pStNd;
2989 4 : SwNodeIndex aIdx( *pFormat->GetDoc()->GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
2990 4 : while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
2991 : {
2992 0 : ++aIdx;
2993 0 : SwNode *const pNd = & aIdx.GetNode();
2994 0 : if ( pNd->IsOLENode() &&
2995 0 : aOldName == static_cast<const SwOLENode*>(pNd)->GetChartTableName() )
2996 : {
2997 0 : const_cast<SwOLENode*>(static_cast<const SwOLENode*>(pNd))->SetChartTableName( rName );
2998 :
2999 0 : static_cast<SwOLENode*>(pNd)->GetOLEObj();
3000 :
3001 0 : SwTable* pTable = SwTable::FindTable( pFormat );
3002 : //TL_CHART2: chart needs to be notfied about name changes
3003 0 : pFormat->GetDoc()->UpdateCharts( pTable->GetFrameFormat()->GetName() );
3004 : }
3005 0 : aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
3006 : }
3007 4 : pFormat->GetDoc()->getIDocumentState().SetModified();
3008 : }
3009 : else
3010 0 : m_sTableName = rName;
3011 2 : }
3012 :
3013 42 : sal_uInt16 SwXTextTable::getRowCount()
3014 : {
3015 42 : SolarMutexGuard aGuard;
3016 42 : sal_uInt16 nRet = 0;
3017 42 : SwFrameFormat* pFormat = GetFrameFormat();
3018 42 : if(pFormat)
3019 : {
3020 40 : SwTable* pTable = SwTable::FindTable( pFormat );
3021 40 : if(!pTable->IsTableComplex())
3022 : {
3023 40 : nRet = pTable->GetTabLines().size();
3024 : }
3025 : }
3026 42 : return nRet;
3027 : }
3028 :
3029 42 : sal_uInt16 SwXTextTable::getColumnCount()
3030 : {
3031 42 : SolarMutexGuard aGuard;
3032 42 : SwFrameFormat* pFormat = GetFrameFormat();
3033 42 : sal_uInt16 nRet = 0;
3034 42 : if(pFormat)
3035 : {
3036 40 : SwTable* pTable = SwTable::FindTable( pFormat );
3037 40 : if(!pTable->IsTableComplex())
3038 : {
3039 40 : SwTableLines& rLines = pTable->GetTabLines();
3040 40 : SwTableLine* pLine = rLines.front();
3041 40 : nRet = pLine->GetTabBoxes().size();
3042 : }
3043 : }
3044 42 : return nRet;
3045 : }
3046 :
3047 3769 : void SwXTextTable::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
3048 : {
3049 3809 : if(pOld && pOld->Which() == RES_REMOVE_UNO_OBJECT &&
3050 40 : static_cast<void*>(GetRegisteredIn()) == static_cast<const SwPtrMsgPoolItem *>(pOld)->pObject )
3051 40 : GetRegisteredIn()->Remove(this);
3052 : else
3053 3729 : ClientModify(this, pOld, pNew);
3054 3769 : if(!GetRegisteredIn())
3055 : {
3056 40 : uno::Reference<uno::XInterface> const xThis(m_pImpl->m_wThis);
3057 40 : if (!xThis.is())
3058 : { // fdo#72695: if UNO object is already dead, don't revive it with event
3059 3769 : return;
3060 : }
3061 80 : lang::EventObject const ev(xThis);
3062 80 : m_pImpl->m_Listeners.disposeAndClear(ev);
3063 : }
3064 : else
3065 : {
3066 3729 : lcl_SendChartEvent(*this, m_pImpl->m_Listeners);
3067 : }
3068 : }
3069 :
3070 0 : OUString SAL_CALL SwXTextTable::getImplementationName() throw( uno::RuntimeException, std::exception )
3071 0 : { return OUString("SwXTextTable"); }
3072 :
3073 56 : sal_Bool SwXTextTable::supportsService(const OUString& rServiceName) throw( uno::RuntimeException, std::exception )
3074 56 : { return cppu::supportsService(this, rServiceName); }
3075 :
3076 56 : uno::Sequence<OUString> SwXTextTable::getSupportedServiceNames() throw(uno::RuntimeException, std::exception)
3077 : {
3078 : return {
3079 : "com.sun.star.document.LinkTarget",
3080 : "com.sun.star.text.TextTable",
3081 : "com.sun.star.text.TextContent",
3082 56 : "com.sun.star.text.TextSortable" };
3083 : }
3084 :
3085 : namespace
3086 : {
3087 : class theSwXCellRangeUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXCellRangeUnoTunnelId > {};
3088 : }
3089 :
3090 0 : const uno::Sequence< sal_Int8 > & SwXCellRange::getUnoTunnelId()
3091 : {
3092 0 : return theSwXCellRangeUnoTunnelId::get().getSeq();
3093 : }
3094 :
3095 0 : sal_Int64 SAL_CALL SwXCellRange::getSomething( const uno::Sequence< sal_Int8 >& rId )
3096 : throw(uno::RuntimeException, std::exception)
3097 : {
3098 0 : if( rId.getLength() == 16
3099 0 : && 0 == memcmp( getUnoTunnelId().getConstArray(),
3100 0 : rId.getConstArray(), 16 ) )
3101 : {
3102 0 : return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
3103 : }
3104 0 : return 0;
3105 : }
3106 :
3107 0 : TYPEINIT1(SwXCellRange, SwClient);
3108 :
3109 3 : OUString SwXCellRange::getImplementationName() throw( uno::RuntimeException, std::exception )
3110 3 : { return OUString("SwXCellRange"); }
3111 :
3112 5 : sal_Bool SwXCellRange::supportsService(const OUString& rServiceName) throw( uno::RuntimeException, std::exception )
3113 5 : { return cppu::supportsService(this, rServiceName); }
3114 :
3115 5 : uno::Sequence<OUString> SwXCellRange::getSupportedServiceNames() throw( uno::RuntimeException, std::exception )
3116 : {
3117 : return {
3118 : "com.sun.star.text.CellRange",
3119 : "com.sun.star.style.CharacterProperties",
3120 : "com.sun.star.style.CharacterPropertiesAsian",
3121 : "com.sun.star.style.CharacterPropertiesComplex",
3122 : "com.sun.star.style.ParagraphProperties",
3123 : "com.sun.star.style.ParagraphPropertiesAsian",
3124 5 : "com.sun.star.style.ParagraphPropertiesComplex" };
3125 : }
3126 :
3127 76 : SwXCellRange::SwXCellRange(sw::UnoCursorPointer pCrsr, SwFrameFormat& rFrameFormat,
3128 : SwRangeDescriptor& rDesc)
3129 : : SwClient(&rFrameFormat)
3130 : , m_ChartListeners(m_Mutex)
3131 : , aRgDesc(rDesc)
3132 76 : , m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TABLE_RANGE))
3133 : , m_pTableCrsr(pCrsr)
3134 : , m_bFirstRowAsLabel(false)
3135 152 : , m_bFirstColumnAsLabel(false)
3136 : {
3137 76 : aRgDesc.Normalize();
3138 76 : }
3139 :
3140 44 : std::vector< uno::Reference< table::XCell > > SwXCellRange::getCells()
3141 : {
3142 44 : SwFrameFormat* const pFormat = GetFrameFormat();
3143 44 : const sal_Int32 nRowCount(getRowCount());
3144 44 : const sal_Int32 nColCount(getColumnCount());
3145 44 : std::vector< uno::Reference< table::XCell > > vResult;
3146 44 : vResult.reserve(static_cast<size_t>(nRowCount)*static_cast<size_t>(nColCount));
3147 206 : for(sal_Int32 nRow = 0; nRow < nRowCount; ++nRow)
3148 506 : for(sal_Int32 nCol = 0; nCol < nColCount; ++nCol)
3149 344 : vResult.push_back(uno::Reference< table::XCell >(lcl_CreateXCell(pFormat, aRgDesc.nLeft + nCol, aRgDesc.nTop + nRow)));
3150 44 : return vResult;
3151 : }
3152 :
3153 2 : uno::Reference< table::XCell > SwXCellRange::getCellByPosition(sal_Int32 nColumn, sal_Int32 nRow)
3154 : throw( uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception )
3155 : {
3156 2 : SolarMutexGuard aGuard;
3157 2 : uno::Reference< table::XCell > aRet;
3158 2 : SwFrameFormat* pFormat = GetFrameFormat();
3159 2 : if(pFormat)
3160 : {
3161 4 : if(nColumn >= 0 && nRow >= 0 &&
3162 4 : getColumnCount() > nColumn && getRowCount() > nRow )
3163 : {
3164 : SwXCell* pXCell = lcl_CreateXCell(pFormat,
3165 1 : aRgDesc.nLeft + nColumn, aRgDesc.nTop + nRow);
3166 1 : if(pXCell)
3167 1 : aRet = pXCell;
3168 : }
3169 : }
3170 2 : if(!aRet.is())
3171 1 : throw lang::IndexOutOfBoundsException();
3172 2 : return aRet;
3173 : }
3174 :
3175 32 : uno::Reference< table::XCellRange > SwXCellRange::getCellRangeByPosition(
3176 : sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom)
3177 : throw (uno::RuntimeException, lang::IndexOutOfBoundsException,
3178 : std::exception)
3179 : {
3180 32 : SolarMutexGuard aGuard;
3181 32 : uno::Reference< table::XCellRange > aRet;
3182 32 : SwFrameFormat* pFormat = GetFrameFormat();
3183 64 : if(pFormat && getColumnCount() > nRight && getRowCount() > nBottom &&
3184 32 : nLeft <= nRight && nTop <= nBottom
3185 64 : && nLeft >= 0 && nRight >= 0 && nTop >= 0 && nBottom >= 0 )
3186 : {
3187 31 : SwTable* pTable = SwTable::FindTable( pFormat );
3188 31 : if(!pTable->IsTableComplex())
3189 : {
3190 : SwRangeDescriptor aNewDesc;
3191 31 : aNewDesc.nTop = nTop + aRgDesc.nTop;
3192 31 : aNewDesc.nBottom = nBottom + aRgDesc.nTop;
3193 31 : aNewDesc.nLeft = nLeft + aRgDesc.nLeft;
3194 31 : aNewDesc.nRight = nRight + aRgDesc.nLeft;
3195 31 : aNewDesc.Normalize();
3196 31 : const OUString sTLName = sw_GetCellName(aNewDesc.nLeft, aNewDesc.nTop);
3197 62 : const OUString sBRName = sw_GetCellName(aNewDesc.nRight, aNewDesc.nBottom);
3198 31 : const SwTableBox* pTLBox = pTable->GetTableBox( sTLName );
3199 31 : if(pTLBox)
3200 : {
3201 : // invalidate all actions
3202 31 : UnoActionRemoveContext aRemoveContext(pFormat->GetDoc());
3203 31 : const SwStartNode* pSttNd = pTLBox->GetSttNd();
3204 62 : SwPosition aPos(*pSttNd);
3205 : // set cursor in the upper-left cell of the range
3206 62 : auto pUnoCrsr(pFormat->GetDoc()->CreateUnoCrsr(aPos, true));
3207 31 : pUnoCrsr->Move( fnMoveForward, fnGoNode );
3208 31 : pUnoCrsr->SetRemainInSection( false );
3209 31 : const SwTableBox* pBRBox = pTable->GetTableBox( sBRName );
3210 31 : if(pBRBox)
3211 : {
3212 31 : pUnoCrsr->SetMark();
3213 31 : pUnoCrsr->GetPoint()->nNode = *pBRBox->GetSttNd();
3214 31 : pUnoCrsr->Move( fnMoveForward, fnGoNode );
3215 31 : SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr.get());
3216 31 : pCrsr->MakeBoxSels();
3217 : // pUnoCrsr will be provided and will not be deleted
3218 31 : SwXCellRange* pCellRange = new SwXCellRange(pUnoCrsr, *pFormat, aNewDesc);
3219 31 : aRet = pCellRange;
3220 31 : }
3221 31 : }
3222 : }
3223 : }
3224 32 : if(!aRet.is())
3225 1 : throw lang::IndexOutOfBoundsException();
3226 32 : return aRet;
3227 : }
3228 :
3229 1 : uno::Reference< table::XCellRange > SwXCellRange::getCellRangeByName(const OUString& rRange)
3230 : throw( uno::RuntimeException, std::exception )
3231 : {
3232 1 : SolarMutexGuard aGuard;
3233 1 : sal_Int32 nPos = 0;
3234 2 : const OUString sTLName(rRange.getToken(0, ':', nPos));
3235 2 : const OUString sBRName(rRange.getToken(0, ':', nPos));
3236 1 : if(sTLName.isEmpty() || sBRName.isEmpty())
3237 0 : throw uno::RuntimeException();
3238 : SwRangeDescriptor aDesc;
3239 1 : aDesc.nTop = aDesc.nLeft = aDesc.nBottom = aDesc.nRight = -1;
3240 1 : sw_GetCellPosition( sTLName, aDesc.nLeft, aDesc.nTop );
3241 1 : sw_GetCellPosition( sBRName, aDesc.nRight, aDesc.nBottom );
3242 1 : aDesc.Normalize();
3243 : return getCellRangeByPosition(aDesc.nLeft - aRgDesc.nLeft, aDesc.nTop - aRgDesc.nTop,
3244 2 : aDesc.nRight - aRgDesc.nLeft, aDesc.nBottom - aRgDesc.nTop);
3245 : }
3246 :
3247 155 : uno::Reference< beans::XPropertySetInfo > SwXCellRange::getPropertySetInfo() throw( uno::RuntimeException, std::exception )
3248 : {
3249 155 : static uno::Reference< beans::XPropertySetInfo > xRef = m_pPropSet->getPropertySetInfo();
3250 155 : return xRef;
3251 : }
3252 :
3253 73 : void SwXCellRange::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
3254 : throw (beans::UnknownPropertyException,
3255 : beans::PropertyVetoException,
3256 : lang::IllegalArgumentException,
3257 : lang::WrappedTargetException,
3258 : uno::RuntimeException,
3259 : std::exception)
3260 : {
3261 73 : SolarMutexGuard aGuard;
3262 73 : SwFrameFormat* pFormat = GetFrameFormat();
3263 73 : if(pFormat)
3264 : {
3265 : const SfxItemPropertySimpleEntry* pEntry =
3266 73 : m_pPropSet->getPropertyMap().getByName(rPropertyName);
3267 73 : if(pEntry)
3268 : {
3269 73 : if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
3270 0 : throw beans::PropertyVetoException("Property is read-only: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
3271 :
3272 73 : SwDoc* pDoc = m_pTableCrsr->GetDoc();
3273 : {
3274 : // remove actions to enable box selection
3275 73 : UnoActionRemoveContext aRemoveContext(pDoc);
3276 : }
3277 73 : SwUnoTableCrsr& rCrsr = dynamic_cast<SwUnoTableCrsr&>(*m_pTableCrsr);
3278 73 : rCrsr.MakeBoxSels();
3279 73 : switch(pEntry->nWID )
3280 : {
3281 : case FN_UNO_TABLE_CELL_BACKGROUND:
3282 : {
3283 0 : SvxBrushItem aBrush( RES_BACKGROUND );
3284 0 : SwDoc::GetBoxAttr( *m_pTableCrsr, aBrush );
3285 0 : ((SfxPoolItem&)aBrush).PutValue(aValue, pEntry->nMemberId);
3286 0 : pDoc->SetBoxAttr( *m_pTableCrsr, aBrush );
3287 :
3288 : }
3289 0 : break;
3290 : case RES_BOX :
3291 : {
3292 0 : SfxItemSet aSet(pDoc->GetAttrPool(),
3293 : RES_BOX, RES_BOX,
3294 : SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
3295 0 : 0);
3296 0 : SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER );
3297 0 : aBoxInfo.SetValid(SvxBoxInfoItemValidFlags::ALL, false);
3298 0 : SvxBoxInfoItemValidFlags nValid = SvxBoxInfoItemValidFlags::NONE;
3299 0 : switch(pEntry->nMemberId & ~CONVERT_TWIPS)
3300 : {
3301 0 : case LEFT_BORDER : nValid = SvxBoxInfoItemValidFlags::LEFT; break;
3302 0 : case RIGHT_BORDER: nValid = SvxBoxInfoItemValidFlags::RIGHT; break;
3303 0 : case TOP_BORDER : nValid = SvxBoxInfoItemValidFlags::TOP; break;
3304 0 : case BOTTOM_BORDER: nValid = SvxBoxInfoItemValidFlags::BOTTOM; break;
3305 : case LEFT_BORDER_DISTANCE :
3306 : case RIGHT_BORDER_DISTANCE:
3307 : case TOP_BORDER_DISTANCE :
3308 : case BOTTOM_BORDER_DISTANCE:
3309 0 : nValid = SvxBoxInfoItemValidFlags::DISTANCE;
3310 0 : break;
3311 : }
3312 0 : aBoxInfo.SetValid(nValid, true);
3313 :
3314 0 : aSet.Put(aBoxInfo);
3315 0 : SwDoc::GetTabBorders(rCrsr, aSet);
3316 :
3317 0 : aSet.Put(aBoxInfo);
3318 0 : SvxBoxItem aBoxItem(static_cast<const SvxBoxItem&>(aSet.Get(RES_BOX)));
3319 0 : ((SfxPoolItem&)aBoxItem).PutValue(aValue, pEntry->nMemberId);
3320 0 : aSet.Put(aBoxItem);
3321 0 : pDoc->SetTabBorders( *m_pTableCrsr, aSet );
3322 : }
3323 0 : break;
3324 : case RES_BOXATR_FORMAT:
3325 : {
3326 0 : SfxUInt32Item aNumberFormat(RES_BOXATR_FORMAT);
3327 0 : ((SfxPoolItem&)aNumberFormat).PutValue(aValue, 0);
3328 0 : pDoc->SetBoxAttr(rCrsr, aNumberFormat);
3329 : }
3330 0 : break;
3331 : case FN_UNO_RANGE_ROW_LABEL:
3332 : {
3333 0 : bool bTmp = *static_cast<sal_Bool const *>(aValue.getValue());
3334 0 : if(m_bFirstRowAsLabel != bTmp)
3335 : {
3336 0 : lcl_SendChartEvent(*this, m_ChartListeners);
3337 0 : m_bFirstRowAsLabel = bTmp;
3338 : }
3339 : }
3340 0 : break;
3341 : case FN_UNO_RANGE_COL_LABEL:
3342 : {
3343 0 : bool bTmp = *static_cast<sal_Bool const *>(aValue.getValue());
3344 0 : if(m_bFirstColumnAsLabel != bTmp)
3345 : {
3346 0 : lcl_SendChartEvent(*this, m_ChartListeners);
3347 0 : m_bFirstColumnAsLabel = bTmp;
3348 : }
3349 : }
3350 0 : break;
3351 : default:
3352 : {
3353 73 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pEntry->nWID, pEntry->nWID );
3354 73 : SwUnoCursorHelper::GetCrsrAttr(rCrsr.GetSelRing(),
3355 73 : aItemSet);
3356 :
3357 73 : if (!SwUnoCursorHelper::SetCursorPropertyValue(
3358 73 : *pEntry, aValue, rCrsr.GetSelRing(), aItemSet))
3359 : {
3360 72 : m_pPropSet->setPropertyValue(*pEntry, aValue, aItemSet);
3361 : }
3362 73 : SwUnoCursorHelper::SetCrsrAttr(rCrsr.GetSelRing(),
3363 73 : aItemSet, SetAttrMode::DEFAULT, true);
3364 : }
3365 : }
3366 : }
3367 : else
3368 0 : throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
3369 73 : }
3370 73 : }
3371 :
3372 149 : uno::Any SwXCellRange::getPropertyValue(const OUString& rPropertyName)
3373 : throw (beans::UnknownPropertyException,
3374 : lang::WrappedTargetException,
3375 : uno::RuntimeException,
3376 : std::exception)
3377 : {
3378 149 : SolarMutexGuard aGuard;
3379 149 : uno::Any aRet;
3380 149 : SwFrameFormat* pFormat = GetFrameFormat();
3381 149 : if(pFormat)
3382 : {
3383 : const SfxItemPropertySimpleEntry* pEntry =
3384 149 : m_pPropSet->getPropertyMap().getByName(rPropertyName);
3385 149 : if(pEntry)
3386 : {
3387 149 : switch(pEntry->nWID )
3388 : {
3389 : case FN_UNO_TABLE_CELL_BACKGROUND:
3390 : {
3391 0 : SvxBrushItem aBrush( RES_BACKGROUND );
3392 0 : if(SwDoc::GetBoxAttr( *m_pTableCrsr, aBrush ))
3393 0 : aBrush.QueryValue(aRet, pEntry->nMemberId);
3394 :
3395 : }
3396 0 : break;
3397 : case RES_BOX :
3398 : {
3399 0 : SwDoc* pDoc = m_pTableCrsr->GetDoc();
3400 0 : SfxItemSet aSet(pDoc->GetAttrPool(),
3401 : RES_BOX, RES_BOX,
3402 : SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
3403 0 : 0);
3404 0 : aSet.Put(SvxBoxInfoItem( SID_ATTR_BORDER_INNER ));
3405 0 : SwDoc::GetTabBorders(*m_pTableCrsr, aSet);
3406 0 : const SvxBoxItem& rBoxItem = static_cast<const SvxBoxItem&>(aSet.Get(RES_BOX));
3407 0 : rBoxItem.QueryValue(aRet, pEntry->nMemberId);
3408 : }
3409 0 : break;
3410 : case RES_BOXATR_FORMAT:
3411 : OSL_FAIL("not implemented");
3412 0 : break;
3413 : case FN_UNO_PARA_STYLE:
3414 : {
3415 : SwFormatColl *const pTmpFormat =
3416 0 : SwUnoCursorHelper::GetCurTextFormatColl(*m_pTableCrsr, false);
3417 0 : OUString sRet;
3418 0 : if(pFormat)
3419 0 : sRet = pTmpFormat->GetName();
3420 0 : aRet <<= sRet;
3421 : }
3422 0 : break;
3423 : case FN_UNO_RANGE_ROW_LABEL:
3424 0 : aRet <<= m_bFirstRowAsLabel;
3425 0 : break;
3426 : case FN_UNO_RANGE_COL_LABEL:
3427 0 : aRet <<= m_bFirstColumnAsLabel;
3428 0 : break;
3429 : default:
3430 : {
3431 149 : SfxItemSet aSet(m_pTableCrsr->GetDoc()->GetAttrPool(),
3432 : RES_CHRATR_BEGIN, RES_FRMATR_END -1,
3433 : RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
3434 : RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
3435 149 : 0L);
3436 : // first look at the attributes of the cursor
3437 149 : SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(&(*m_pTableCrsr));
3438 149 : SwUnoCursorHelper::GetCrsrAttr(pCrsr->GetSelRing(), aSet);
3439 149 : m_pPropSet->getPropertyValue(*pEntry, aSet, aRet);
3440 : }
3441 : }
3442 : }
3443 : else
3444 0 : throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
3445 : }
3446 149 : return aRet;
3447 : }
3448 :
3449 0 : void SwXCellRange::addPropertyChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
3450 0 : { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
3451 :
3452 0 : void SwXCellRange::removePropertyChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
3453 0 : { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
3454 :
3455 0 : void SwXCellRange::addVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
3456 0 : { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
3457 :
3458 0 : void SwXCellRange::removeVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
3459 0 : { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
3460 :
3461 0 : void SwXCellRange::GetDataSequence(
3462 : uno::Sequence< uno::Any > *pAnySeq, //-> first pointer != 0 is used
3463 : uno::Sequence< OUString > *pTextSeq, //-> as output sequence
3464 : uno::Sequence< double > *pDblSeq, //-> (previous data gets overwritten)
3465 : bool bForceNumberResults ) //-> when 'true' requires to make an
3466 : // extra effort to return a value different
3467 : // from 0 even if the cell is formatted to text
3468 : throw (uno::RuntimeException)
3469 : {
3470 0 : SolarMutexGuard aGuard;
3471 :
3472 : // compare to SwXCellRange::getDataArray (note different return types though)
3473 :
3474 0 : const sal_Int32 nRowCount = getRowCount();
3475 0 : const sal_Int32 nColCount = getColumnCount();
3476 :
3477 0 : if(!nRowCount || !nColCount)
3478 : {
3479 0 : uno::RuntimeException aRuntime;
3480 0 : aRuntime.Message = "Table too complex";
3481 0 : throw aRuntime;
3482 : }
3483 :
3484 0 : const size_t nSize = static_cast<size_t>(nRowCount) * static_cast<size_t>(nColCount);
3485 0 : if (pAnySeq)
3486 0 : pAnySeq->realloc( nSize );
3487 0 : else if (pTextSeq)
3488 0 : pTextSeq->realloc( nSize );
3489 0 : else if (pDblSeq)
3490 0 : pDblSeq->realloc( nSize );
3491 : else
3492 : {
3493 : OSL_FAIL( "argument missing" );
3494 0 : return;
3495 : }
3496 0 : uno::Any *pAnyData = pAnySeq ? pAnySeq->getArray() : 0;
3497 0 : OUString *pTextData = pTextSeq ? pTextSeq->getArray() : 0;
3498 0 : double *pDblData = pDblSeq ? pDblSeq->getArray() : 0;
3499 :
3500 0 : size_t nDtaCnt = 0;
3501 0 : SwFrameFormat* pFormat = GetFrameFormat();
3502 0 : if(pFormat)
3503 : {
3504 : double fNan;
3505 0 : ::rtl::math::setNan( & fNan );
3506 :
3507 0 : uno::Reference< table::XCell > xCellRef;
3508 0 : for(sal_Int32 nRow = 0; nRow < nRowCount; ++nRow)
3509 : {
3510 0 : for(sal_Int32 nCol = 0; nCol < nColCount; ++nCol)
3511 : {
3512 : SwXCell * pXCell = lcl_CreateXCell(pFormat,
3513 : aRgDesc.nLeft + nCol,
3514 0 : aRgDesc.nTop + nRow);
3515 : //! keep (additional) reference to object to prevent implicit destruction
3516 : //! in following UNO calls (when object will get referenced)
3517 0 : xCellRef = pXCell;
3518 0 : SwTableBox * pBox = pXCell ? pXCell->GetTableBox() : 0;
3519 0 : if(!pBox)
3520 : {
3521 0 : throw uno::RuntimeException();
3522 : }
3523 : else
3524 : {
3525 0 : if (pAnyData)
3526 : {
3527 : // check if table box value item is set
3528 0 : bool bIsNum = pBox->GetFrameFormat()->GetItemState( RES_BOXATR_VALUE, false ) == SfxItemState::SET;
3529 0 : if (!bIsNum)
3530 0 : pAnyData[nDtaCnt++] <<= lcl_getString(*pXCell);
3531 : else
3532 0 : pAnyData[nDtaCnt++] <<= sw_getValue(*pXCell);
3533 : }
3534 0 : else if (pTextData)
3535 0 : pTextData[nDtaCnt++] = lcl_getString(*pXCell);
3536 0 : else if (pDblData)
3537 : {
3538 0 : double fVal = fNan;
3539 0 : if (!bForceNumberResults || table::CellContentType_TEXT != pXCell->getType())
3540 0 : fVal = sw_getValue(*pXCell);
3541 : else
3542 : {
3543 : OSL_ENSURE( table::CellContentType_TEXT == pXCell->getType(),
3544 : "this branch of 'if' is only for text formatted cells" );
3545 :
3546 : // now we'll try to get a useful numerical value
3547 : // from the text in the cell...
3548 :
3549 : sal_uInt32 nFIndex;
3550 0 : SvNumberFormatter* pNumFormatter = m_pTableCrsr->GetDoc()->GetNumberFormatter();
3551 :
3552 : // look for SwTableBoxNumFormat value in parents as well
3553 : const SfxPoolItem* pItem;
3554 0 : SwFrameFormat *pBoxFormat = pXCell->GetTableBox()->GetFrameFormat();
3555 0 : SfxItemState eState = pBoxFormat->GetAttrSet().GetItemState(RES_BOXATR_FORMAT, true, &pItem);
3556 :
3557 0 : if (eState == SfxItemState::SET)
3558 : {
3559 : // please note that the language of the numberformat
3560 : // is implicitly coded into the below value as well
3561 0 : nFIndex = static_cast<const SwTableBoxNumFormat*>(pItem)->GetValue();
3562 :
3563 : // since the current value indicates a text format but the call
3564 : // to 'IsNumberFormat' below won't work for text formats
3565 : // we need to get rid of the part that indicates the text format.
3566 : // According to ER this can be done like this:
3567 0 : nFIndex -= (nFIndex % SV_COUNTRY_LANGUAGE_OFFSET);
3568 : }
3569 : else
3570 : {
3571 : // system language is probably not the best possible choice
3572 : // but since we have to guess anyway (because the language of at
3573 : // the text is NOT the one used for the number format!)
3574 : // it is at least conform to what is used in
3575 : // SwTableShell::Execute when
3576 : // SID_ATTR_NUMBERFORMAT_VALUE is set...
3577 0 : LanguageType eLang = LANGUAGE_SYSTEM;
3578 0 : nFIndex = pNumFormatter->GetStandardIndex( eLang );
3579 : }
3580 :
3581 : double fTmp;
3582 0 : if (pNumFormatter->IsNumberFormat( lcl_getString(*pXCell), nFIndex, fTmp ))
3583 0 : fVal = fTmp;
3584 : }
3585 0 : pDblData[nDtaCnt++] = fVal;
3586 : }
3587 : else {
3588 : OSL_FAIL( "output sequence missing" );
3589 : }
3590 : }
3591 : }
3592 0 : }
3593 : }
3594 : OSL_ENSURE( nDtaCnt == nSize, "size mismatch. Invalid cell range?" );
3595 0 : if (pAnySeq)
3596 0 : pAnySeq->realloc( nDtaCnt );
3597 0 : else if (pTextSeq)
3598 0 : pTextSeq->realloc( nDtaCnt );
3599 0 : else if (pDblSeq)
3600 0 : pDblSeq->realloc( nDtaCnt );
3601 : }
3602 :
3603 : ///@see SwXCellRange::getData
3604 : ///@see SwXCellRange::GetDataSequence
3605 4 : uno::Sequence< uno::Sequence< uno::Any > > SAL_CALL SwXCellRange::getDataArray()
3606 : throw (uno::RuntimeException, std::exception)
3607 : {
3608 4 : SolarMutexGuard aGuard;
3609 4 : const sal_Int32 nRowCount = getRowCount();
3610 4 : const sal_Int32 nColCount = getColumnCount();
3611 4 : if(!nRowCount || !nColCount)
3612 0 : throw uno::RuntimeException("Table too complex", static_cast<cppu::OWeakObject*>(this));
3613 4 : lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
3614 4 : uno::Sequence< uno::Sequence< uno::Any > > aRowSeq(nRowCount);
3615 8 : auto vCells(getCells());
3616 4 : auto pCurrentCell(vCells.begin());
3617 26 : for(auto& rRow : aRowSeq)
3618 : {
3619 22 : rRow = uno::Sequence< uno::Any >(nColCount);
3620 86 : for(auto& rCellAny : rRow)
3621 : {
3622 64 : auto pCell(static_cast<SwXCell*>(pCurrentCell->get()));
3623 64 : SwTableBox* pBox = pCell ? pCell->GetTableBox() : nullptr;
3624 64 : if(!pBox)
3625 0 : throw uno::RuntimeException();
3626 : // check if table box value item is set
3627 64 : SwFrameFormat* pBoxFormat(pBox->GetFrameFormat());
3628 64 : const bool bIsNum = pBoxFormat->GetItemState(RES_BOXATR_VALUE, false) == SfxItemState::SET;
3629 64 : rCellAny = bIsNum ? uno::makeAny(sw_getValue(*pCell)) : uno::makeAny(lcl_getString(*pCell));
3630 64 : ++pCurrentCell;
3631 : }
3632 : }
3633 8 : return aRowSeq;
3634 : }
3635 :
3636 : ///@see SwXCellRange::setData
3637 4 : void SAL_CALL SwXCellRange::setDataArray(const uno::Sequence< uno::Sequence< uno::Any > >& rArray) throw (uno::RuntimeException, std::exception)
3638 : {
3639 4 : SolarMutexGuard aGuard;
3640 4 : const sal_Int32 nRowCount = getRowCount();
3641 4 : const sal_Int32 nColCount = getColumnCount();
3642 4 : if(!nRowCount || !nColCount)
3643 0 : throw uno::RuntimeException("Table too complex", static_cast<cppu::OWeakObject*>(this));
3644 4 : SwFrameFormat* pFormat = GetFrameFormat();
3645 4 : if(!pFormat)
3646 4 : return;
3647 4 : if(rArray.getLength() != nRowCount)
3648 0 : throw uno::RuntimeException("Row count mismatch. expected: " + OUString::number(nRowCount) + " got: " + OUString::number(rArray.getLength()), static_cast<cppu::OWeakObject*>(this));
3649 8 : auto vCells(getCells());
3650 4 : auto pCurrentCell(vCells.begin());
3651 26 : for(const auto& rColSeq : rArray)
3652 : {
3653 22 : if(rColSeq.getLength() != nColCount)
3654 0 : throw uno::RuntimeException("Column count mismatch. expected: " + OUString::number(nColCount) + " got: " + OUString::number(rColSeq.getLength()), static_cast<cppu::OWeakObject*>(this));
3655 86 : for(const auto& aValue : rColSeq)
3656 : {
3657 64 : auto pCell(static_cast<SwXCell*>(pCurrentCell->get()));
3658 64 : if(!pCell || !pCell->GetTableBox())
3659 0 : throw uno::RuntimeException("Box for cell missing", static_cast<cppu::OWeakObject*>(this));
3660 64 : if(aValue.isExtractableTo(cppu::UnoType<OUString>::get()))
3661 32 : sw_setString(*pCell, aValue.get<OUString>());
3662 32 : else if(aValue.isExtractableTo(cppu::UnoType<double>::get()))
3663 32 : sw_setValue(*pCell, aValue.get<double>());
3664 : else
3665 0 : sw_setString(*pCell, OUString(), true);
3666 64 : ++pCurrentCell;
3667 : }
3668 4 : }
3669 : }
3670 :
3671 18 : uno::Sequence< uno::Sequence< double > > SwXCellRange::getData() throw( uno::RuntimeException, std::exception )
3672 : {
3673 18 : SolarMutexGuard aGuard;
3674 18 : const sal_Int32 nRowCount = getRowCount();
3675 18 : const sal_Int32 nColCount = getColumnCount();
3676 18 : if(!nRowCount || !nColCount)
3677 0 : throw uno::RuntimeException("Table too complex", static_cast<cppu::OWeakObject*>(this));
3678 18 : if(m_bFirstColumnAsLabel || m_bFirstRowAsLabel)
3679 : {
3680 : uno::Reference<chart::XChartDataArray> xDataRange(getCellRangeByPosition(m_bFirstColumnAsLabel ? 1 : 0, m_bFirstRowAsLabel ? 1 : 0,
3681 7 : nColCount-1, nRowCount-1), uno::UNO_QUERY);
3682 7 : return xDataRange->getData();
3683 : }
3684 22 : uno::Sequence< uno::Sequence< double > > vRows(nRowCount);
3685 22 : auto vCells(getCells());
3686 11 : auto pCurrentCell(vCells.begin());
3687 59 : for(auto& rRow : vRows)
3688 : {
3689 48 : rRow = uno::Sequence<double>(nColCount);
3690 155 : for(auto& rValue : rRow)
3691 : {
3692 107 : rValue = (*pCurrentCell)->getValue();
3693 107 : ++pCurrentCell;
3694 : }
3695 : }
3696 29 : return vRows;
3697 : }
3698 :
3699 12 : void SwXCellRange::setData(const uno::Sequence< uno::Sequence< double > >& rData)
3700 : throw( uno::RuntimeException, std::exception )
3701 : {
3702 12 : SolarMutexGuard aGuard;
3703 12 : const sal_Int32 nRowCount = getRowCount();
3704 12 : const sal_Int32 nColCount = getColumnCount();
3705 12 : if(!nRowCount || !nColCount)
3706 0 : throw uno::RuntimeException("Table too complex", static_cast<cppu::OWeakObject*>(this));
3707 12 : if(m_bFirstColumnAsLabel || m_bFirstRowAsLabel)
3708 : {
3709 : uno::Reference<chart::XChartDataArray> xDataRange(getCellRangeByPosition(m_bFirstColumnAsLabel ? 1 : 0, m_bFirstRowAsLabel ? 1 : 0,
3710 4 : nColCount-1, nRowCount-1), uno::UNO_QUERY);
3711 14 : return xDataRange->setData(rData);
3712 : }
3713 8 : lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
3714 8 : if(rData.getLength() != nRowCount)
3715 1 : throw uno::RuntimeException("Row count mismatch. expected: " + OUString::number(nRowCount) + " got: " + OUString::number(rData.getLength()), static_cast<cppu::OWeakObject*>(this));
3716 14 : auto vCells(getCells());
3717 7 : auto pCurrentCell(vCells.begin());
3718 34 : for(const auto& rRow : rData)
3719 : {
3720 28 : if(rRow.getLength() != nColCount)
3721 1 : throw uno::RuntimeException("Column count mismatch. expected: " + OUString::number(nColCount) + " got: " + OUString::number(rRow.getLength()), static_cast<cppu::OWeakObject*>(this));
3722 80 : for(const auto& rValue : rRow)
3723 : {
3724 53 : uno::Reference<table::XCell>(*pCurrentCell, uno::UNO_QUERY)->setValue(rValue);
3725 53 : ++pCurrentCell;
3726 : }
3727 8 : }
3728 : }
3729 :
3730 24 : std::tuple<sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32> SwXCellRange::getLabelCoordinates(bool bRow)
3731 : {
3732 : sal_uInt32 nLeft, nTop, nRight, nBottom;
3733 24 : nLeft = nTop = nRight = nBottom = 0;
3734 24 : if(bRow)
3735 : {
3736 12 : nTop = m_bFirstRowAsLabel ? 1 : 0;
3737 12 : nBottom = getRowCount()-1;
3738 : }
3739 : else
3740 : {
3741 12 : nLeft = m_bFirstColumnAsLabel ? 1 : 0;
3742 12 : nRight = getColumnCount()-1;
3743 : }
3744 24 : return std::make_tuple(nLeft, nTop, nRight, nBottom);
3745 : }
3746 :
3747 18 : uno::Sequence<OUString> SwXCellRange::getLabelDescriptions(bool bRow)
3748 : {
3749 18 : SolarMutexGuard aGuard;
3750 : sal_uInt32 nLeft, nTop, nRight, nBottom;
3751 18 : std::tie(nLeft, nTop, nRight, nBottom) = getLabelCoordinates(bRow);
3752 18 : if(!nRight && !nBottom)
3753 0 : throw uno::RuntimeException("Table too complex", static_cast<cppu::OWeakObject*>(this));
3754 18 : lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
3755 18 : if(!(bRow ? m_bFirstColumnAsLabel : m_bFirstRowAsLabel))
3756 6 : return {}; // without labels we have no descriptions
3757 24 : auto xLabelRange(getCellRangeByPosition(nLeft, nTop, nRight, nBottom));
3758 24 : auto vCells(static_cast<SwXCellRange*>(xLabelRange.get())->getCells());
3759 24 : uno::Sequence<OUString> vResult(vCells.size());
3760 : std::transform(vCells.begin(), vCells.end(), vResult.begin(),
3761 42 : [](uno::Reference<table::XCell> xCell) -> OUString { return uno::Reference<text::XText>(xCell, uno::UNO_QUERY_THROW)->getString(); });
3762 30 : return vResult;
3763 : }
3764 :
3765 9 : uno::Sequence<OUString> SwXCellRange::getRowDescriptions()
3766 : throw( uno::RuntimeException, std::exception )
3767 9 : { return getLabelDescriptions(true); }
3768 :
3769 9 : uno::Sequence<OUString> SwXCellRange::getColumnDescriptions()
3770 : throw(uno::RuntimeException, std::exception)
3771 9 : { return getLabelDescriptions(false); }
3772 :
3773 6 : void SwXCellRange::setLabelDescriptions(const uno::Sequence<OUString>& rDesc, bool bRow)
3774 : {
3775 6 : SolarMutexGuard aGuard;
3776 6 : lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
3777 6 : if(!(bRow ? m_bFirstColumnAsLabel : m_bFirstRowAsLabel))
3778 4 : return; // if there are no labels we cannot set descriptions
3779 : sal_uInt32 nLeft, nTop, nRight, nBottom;
3780 6 : std::tie(nLeft, nTop, nRight, nBottom) = getLabelCoordinates(bRow);
3781 6 : if(!nRight && !nBottom)
3782 0 : throw uno::RuntimeException("Table too complex", static_cast<cppu::OWeakObject*>(this));
3783 12 : auto xLabelRange(getCellRangeByPosition(nLeft, nTop, nRight, nBottom));
3784 12 : auto vCells(static_cast<SwXCellRange*>(xLabelRange.get())->getCells());
3785 6 : if (sal::static_int_cast<sal_uInt32>(rDesc.getLength()) != vCells.size())
3786 2 : throw uno::RuntimeException("Too few or too many descriptions", static_cast<cppu::OWeakObject*>(this));
3787 4 : auto pDescIterator(rDesc.begin());
3788 14 : for(auto xCell : vCells)
3789 16 : uno::Reference<text::XText>(xCell, uno::UNO_QUERY_THROW)->setString(*pDescIterator++);
3790 : }
3791 3 : void SwXCellRange::setRowDescriptions(const uno::Sequence<OUString>& rRowDesc)
3792 : throw(uno::RuntimeException, std::exception)
3793 3 : { setLabelDescriptions(rRowDesc, true); }
3794 :
3795 3 : void SwXCellRange::setColumnDescriptions(const uno::Sequence<OUString>& rColumnDesc)
3796 : throw(uno::RuntimeException, std::exception)
3797 3 : { setLabelDescriptions(rColumnDesc, false); }
3798 :
3799 0 : void SAL_CALL SwXCellRange::addChartDataChangeEventListener(
3800 : const uno::Reference<chart::XChartDataChangeEventListener> & xListener)
3801 : throw (uno::RuntimeException, std::exception)
3802 : {
3803 : // no need to lock here as m_pImpl is const and container threadsafe
3804 0 : m_ChartListeners.addInterface(xListener);
3805 0 : }
3806 :
3807 0 : void SAL_CALL SwXCellRange::removeChartDataChangeEventListener(
3808 : const uno::Reference<chart::XChartDataChangeEventListener> & xListener)
3809 : throw (uno::RuntimeException, std::exception)
3810 : {
3811 : // no need to lock here as m_pImpl is const and container threadsafe
3812 0 : m_ChartListeners.removeInterface(xListener);
3813 0 : }
3814 :
3815 0 : sal_Bool SwXCellRange::isNotANumber(double /*fNumber*/) throw( uno::RuntimeException, std::exception )
3816 0 : { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
3817 :
3818 0 : double SwXCellRange::getNotANumber() throw( uno::RuntimeException, std::exception )
3819 0 : { throw uno::RuntimeException("Not implemented", static_cast<cppu::OWeakObject*>(this)); }
3820 :
3821 0 : uno::Sequence< beans::PropertyValue > SwXCellRange::createSortDescriptor() throw( uno::RuntimeException, std::exception )
3822 : {
3823 0 : SolarMutexGuard aGuard;
3824 0 : return SwUnoCursorHelper::CreateSortDescriptor(true);
3825 : }
3826 :
3827 0 : void SAL_CALL SwXCellRange::sort(const uno::Sequence< beans::PropertyValue >& rDescriptor)
3828 : throw (uno::RuntimeException,
3829 : std::exception)
3830 : {
3831 0 : SolarMutexGuard aGuard;
3832 0 : SwSortOptions aSortOpt;
3833 0 : SwFrameFormat* pFormat(GetFrameFormat());
3834 0 : if(pFormat && SwUnoCursorHelper::ConvertSortProperties(rDescriptor, aSortOpt))
3835 : {
3836 0 : SwUnoTableCrsr& rTableCrsr = dynamic_cast<SwUnoTableCrsr&>(*m_pTableCrsr);
3837 0 : rTableCrsr.MakeBoxSels();
3838 0 : UnoActionContext aContext(pFormat->GetDoc());
3839 0 : pFormat->GetDoc()->SortTable(rTableCrsr.GetSelectedBoxes(), aSortOpt);
3840 0 : }
3841 0 : }
3842 :
3843 127 : sal_uInt16 SwXCellRange::getColumnCount()
3844 127 : { return static_cast<sal_uInt16>(aRgDesc.nRight - aRgDesc.nLeft + 1); }
3845 :
3846 127 : sal_uInt16 SwXCellRange::getRowCount()
3847 127 : { return static_cast<sal_uInt16>(aRgDesc.nBottom - aRgDesc.nTop + 1); }
3848 :
3849 0 : const SwUnoCrsr* SwXCellRange::GetTableCrsr() const
3850 : {
3851 0 : SwFrameFormat* pFormat = GetFrameFormat();
3852 0 : return pFormat ? &(*m_pTableCrsr) : nullptr;
3853 : }
3854 :
3855 7 : void SwXCellRange::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
3856 : {
3857 7 : ClientModify(this, pOld, pNew );
3858 7 : if(!GetRegisteredIn() || !m_pTableCrsr)
3859 : {
3860 7 : m_pTableCrsr.reset(nullptr);
3861 7 : lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(*this));
3862 7 : m_ChartListeners.disposeAndClear(ev);
3863 : }
3864 : else
3865 : {
3866 0 : lcl_SendChartEvent(*this, m_ChartListeners);
3867 : }
3868 7 : }
3869 :
3870 : // SwXTableRows
3871 :
3872 0 : OUString SwXTableRows::getImplementationName() throw( uno::RuntimeException, std::exception )
3873 0 : { return OUString("SwXTableRows"); }
3874 :
3875 0 : sal_Bool SwXTableRows::supportsService(const OUString& rServiceName) throw( uno::RuntimeException, std::exception )
3876 0 : { return cppu::supportsService(this, rServiceName); }
3877 :
3878 0 : uno::Sequence< OUString > SwXTableRows::getSupportedServiceNames() throw( uno::RuntimeException, std::exception )
3879 0 : { return { "com.sun.star.text.TableRows" }; }
3880 :
3881 3 : TYPEINIT1(SwXTableRows, SwClient);
3882 :
3883 626 : SwXTableRows::SwXTableRows(SwFrameFormat& rFrameFormat) :
3884 626 : SwClient(&rFrameFormat)
3885 626 : { }
3886 :
3887 1252 : SwXTableRows::~SwXTableRows()
3888 1252 : { }
3889 :
3890 3540 : sal_Int32 SwXTableRows::getCount() throw( uno::RuntimeException, std::exception )
3891 : {
3892 3540 : SolarMutexGuard aGuard;
3893 3540 : SwFrameFormat* pFrameFormat = GetFrameFormat();
3894 3540 : if(!pFrameFormat)
3895 0 : throw uno::RuntimeException();
3896 3540 : SwTable* pTable = SwTable::FindTable(pFrameFormat);
3897 3540 : return pTable->GetTabLines().size();
3898 : }
3899 :
3900 : ///@see SwXCell::CreateXCell (TODO: seems to be copy and paste programming here)
3901 2956 : uno::Any SwXTableRows::getByIndex(sal_Int32 nIndex)
3902 : throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
3903 : {
3904 2956 : SolarMutexGuard aGuard;
3905 2956 : SwFrameFormat* pFrameFormat(lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this)));
3906 2956 : if(nIndex < 0)
3907 0 : throw lang::IndexOutOfBoundsException();
3908 2956 : SwTable* pTable = SwTable::FindTable( pFrameFormat );
3909 2956 : if(static_cast<size_t>(nIndex) >= pTable->GetTabLines().size())
3910 1 : throw lang::IndexOutOfBoundsException();
3911 2955 : SwTableLine* pLine = pTable->GetTabLines()[nIndex];
3912 5910 : FindUnoInstanceHint<SwTableLine,SwXTextTableRow> aHint{pLine};
3913 2955 : pFrameFormat->CallSwClientNotify(aHint);
3914 2955 : if(!aHint.m_pResult)
3915 2955 : aHint.m_pResult = new SwXTextTableRow(pFrameFormat, pLine);
3916 5910 : uno::Reference<beans::XPropertySet> xRet = static_cast<beans::XPropertySet*>(aHint.m_pResult);
3917 5911 : return uno::makeAny(xRet);
3918 : }
3919 :
3920 1 : uno::Type SAL_CALL SwXTableRows::getElementType() throw( uno::RuntimeException, std::exception )
3921 : {
3922 1 : return cppu::UnoType<beans::XPropertySet>::get();
3923 : }
3924 :
3925 1 : sal_Bool SwXTableRows::hasElements() throw( uno::RuntimeException, std::exception )
3926 : {
3927 1 : SolarMutexGuard aGuard;
3928 1 : SwFrameFormat* pFrameFormat = GetFrameFormat();
3929 1 : if(!pFrameFormat)
3930 0 : throw uno::RuntimeException();
3931 : // a table always has rows
3932 1 : return sal_True;
3933 : }
3934 :
3935 2 : void SwXTableRows::insertByIndex(sal_Int32 nIndex, sal_Int32 nCount)
3936 : throw (uno::RuntimeException, std::exception)
3937 : {
3938 2 : SolarMutexGuard aGuard;
3939 2 : if (nCount == 0)
3940 1 : return;
3941 2 : SwFrameFormat* pFrameFormat(lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this)));
3942 2 : SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFrameFormat), static_cast<cppu::OWeakObject*>(this));
3943 2 : const size_t nRowCount = pTable->GetTabLines().size();
3944 2 : if (nCount <= 0 || !(0 <= nIndex && static_cast<size_t>(nIndex) <= nRowCount))
3945 1 : throw uno::RuntimeException("Illegal arguments", static_cast<cppu::OWeakObject*>(this));
3946 2 : const OUString sTLName = sw_GetCellName(0, nIndex);
3947 1 : const SwTableBox* pTLBox = pTable->GetTableBox(sTLName);
3948 1 : bool bAppend = false;
3949 1 : if(!pTLBox)
3950 : {
3951 0 : bAppend = true;
3952 : // to append at the end the cursor must be in the last line
3953 0 : SwTableLines& rLines = pTable->GetTabLines();
3954 0 : SwTableLine* pLine = rLines.back();
3955 0 : SwTableBoxes& rBoxes = pLine->GetTabBoxes();
3956 0 : pTLBox = rBoxes.front();
3957 : }
3958 1 : if(!pTLBox)
3959 0 : throw uno::RuntimeException("Illegal arguments", static_cast<cppu::OWeakObject*>(this));
3960 1 : const SwStartNode* pSttNd = pTLBox->GetSttNd();
3961 2 : SwPosition aPos(*pSttNd);
3962 : // set cursor to the upper-left cell of the range
3963 2 : UnoActionContext aAction(pFrameFormat->GetDoc());
3964 2 : auto pUnoCrsr(pFrameFormat->GetDoc()->CreateUnoCrsr(aPos, true));
3965 1 : pUnoCrsr->Move( fnMoveForward, fnGoNode );
3966 : {
3967 : // remove actions
3968 1 : UnoActionRemoveContext aRemoveContext(pUnoCrsr->GetDoc());
3969 : }
3970 3 : pFrameFormat->GetDoc()->InsertRow(*pUnoCrsr, (sal_uInt16)nCount, bAppend);
3971 : }
3972 :
3973 2 : void SwXTableRows::removeByIndex(sal_Int32 nIndex, sal_Int32 nCount)
3974 : throw (uno::RuntimeException, std::exception)
3975 : {
3976 2 : SolarMutexGuard aGuard;
3977 2 : if (nCount == 0)
3978 1 : return;
3979 2 : SwFrameFormat* pFrameFormat(lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this)));
3980 2 : if(nIndex < 0 || nCount <=0 )
3981 1 : throw uno::RuntimeException();
3982 1 : SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFrameFormat), static_cast<cppu::OWeakObject*>(this));
3983 2 : OUString sTLName = sw_GetCellName(0, nIndex);
3984 1 : const SwTableBox* pTLBox = pTable->GetTableBox(sTLName);
3985 1 : if(!pTLBox)
3986 0 : throw uno::RuntimeException("Illegal arguments", static_cast<cppu::OWeakObject*>(this));
3987 : {
3988 : // invalidate all actions
3989 1 : UnoActionRemoveContext aRemoveContext(pFrameFormat->GetDoc());
3990 : }
3991 1 : const SwStartNode* pSttNd = pTLBox->GetSttNd();
3992 2 : SwPosition aPos(*pSttNd);
3993 : // set cursor to the upper-left cell of the range
3994 2 : auto pUnoCrsr(pFrameFormat->GetDoc()->CreateUnoCrsr(aPos, true));
3995 1 : pUnoCrsr->Move(fnMoveForward, fnGoNode);
3996 1 : pUnoCrsr->SetRemainInSection( false );
3997 2 : const OUString sBLName = sw_GetCellName(0, nIndex + nCount - 1);
3998 1 : const SwTableBox* pBLBox = pTable->GetTableBox( sBLName );
3999 1 : if(!pBLBox)
4000 0 : throw uno::RuntimeException("Illegal arguments", static_cast<cppu::OWeakObject*>(this));
4001 1 : pUnoCrsr->SetMark();
4002 1 : pUnoCrsr->GetPoint()->nNode = *pBLBox->GetSttNd();
4003 1 : pUnoCrsr->Move(fnMoveForward, fnGoNode);
4004 1 : SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr.get());
4005 1 : pCrsr->MakeBoxSels();
4006 : { // these braces are important
4007 1 : UnoActionContext aAction(pFrameFormat->GetDoc());
4008 1 : pFrameFormat->GetDoc()->DeleteRow(*pUnoCrsr);
4009 1 : pUnoCrsr.reset();
4010 : }
4011 : {
4012 : // invalidate all actions
4013 1 : UnoActionRemoveContext aRemoveContext(pFrameFormat->GetDoc());
4014 2 : }
4015 : }
4016 :
4017 3 : void SwXTableRows::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
4018 3 : { ClientModify(this, pOld, pNew); }
4019 :
4020 : // SwXTableColumns
4021 :
4022 0 : OUString SwXTableColumns::getImplementationName() throw( uno::RuntimeException, std::exception )
4023 0 : { return OUString("SwXTableColumns"); }
4024 :
4025 0 : sal_Bool SwXTableColumns::supportsService(const OUString& rServiceName) throw( uno::RuntimeException, std::exception )
4026 0 : { return cppu::supportsService(this, rServiceName); }
4027 :
4028 0 : uno::Sequence< OUString > SwXTableColumns::getSupportedServiceNames() throw( uno::RuntimeException, std::exception )
4029 0 : { return { "com.sun.star.text.TableColumns"}; }
4030 :
4031 0 : TYPEINIT1(SwXTableColumns, SwClient);
4032 :
4033 7 : SwXTableColumns::SwXTableColumns(SwFrameFormat& rFrameFormat) :
4034 7 : SwClient(&rFrameFormat)
4035 7 : { }
4036 :
4037 14 : SwXTableColumns::~SwXTableColumns()
4038 14 : { }
4039 :
4040 11 : sal_Int32 SwXTableColumns::getCount() throw( uno::RuntimeException, std::exception )
4041 : {
4042 11 : SolarMutexGuard aGuard;
4043 11 : SwFrameFormat* pFrameFormat(lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this)));
4044 11 : SwTable* pTable = SwTable::FindTable( pFrameFormat );
4045 : // if(!pTable->IsTableComplex())
4046 : // throw uno::RuntimeException("Table too complex", static_cast<cppu::OWeakObject*>(this));
4047 11 : SwTableLines& rLines = pTable->GetTabLines();
4048 11 : SwTableLine* pLine = rLines.front();
4049 11 : return pLine->GetTabBoxes().size();
4050 : }
4051 :
4052 4 : uno::Any SwXTableColumns::getByIndex(sal_Int32 nIndex)
4053 : throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
4054 : {
4055 4 : SolarMutexGuard aGuard;
4056 4 : if(nIndex < 0 || getCount() <= nIndex)
4057 1 : throw lang::IndexOutOfBoundsException();
4058 3 : return uno::makeAny(uno::Reference<uno::XInterface>()); // i#21699 not supported
4059 : }
4060 :
4061 1 : uno::Type SAL_CALL SwXTableColumns::getElementType() throw( uno::RuntimeException, std::exception )
4062 : {
4063 1 : return cppu::UnoType<uno::XInterface>::get();
4064 : }
4065 :
4066 1 : sal_Bool SwXTableColumns::hasElements() throw( uno::RuntimeException, std::exception )
4067 : {
4068 1 : SolarMutexGuard aGuard;
4069 1 : lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
4070 1 : return sal_True;
4071 : }
4072 :
4073 : ///@see SwXTableRows::insertByIndex (TODO: seems to be copy and paste programming here)
4074 0 : void SwXTableColumns::insertByIndex(sal_Int32 nIndex, sal_Int32 nCount)
4075 : throw (uno::RuntimeException, std::exception)
4076 : {
4077 0 : SolarMutexGuard aGuard;
4078 0 : if (nCount == 0)
4079 0 : return;
4080 0 : SwFrameFormat* pFrameFormat(lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this)));
4081 0 : SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFrameFormat), static_cast<cppu::OWeakObject*>(this));
4082 0 : SwTableLines& rLines = pTable->GetTabLines();
4083 0 : SwTableLine* pLine = rLines.front();
4084 0 : const size_t nColCount = pLine->GetTabBoxes().size();
4085 0 : if (nCount <= 0 || !(0 <= nIndex && static_cast<size_t>(nIndex) <= nColCount))
4086 0 : throw uno::RuntimeException("Illegal arguments", static_cast<cppu::OWeakObject*>(this));
4087 0 : const OUString sTLName = sw_GetCellName(nIndex, 0);
4088 0 : const SwTableBox* pTLBox = pTable->GetTableBox( sTLName );
4089 0 : bool bAppend = false;
4090 0 : if(!pTLBox)
4091 : {
4092 0 : bAppend = true;
4093 : // to append at the end the cursor must be in the last line
4094 0 : SwTableBoxes& rBoxes = pLine->GetTabBoxes();
4095 0 : pTLBox = rBoxes.back();
4096 : }
4097 0 : if(!pTLBox)
4098 0 : throw uno::RuntimeException("Illegal arguments", static_cast<cppu::OWeakObject*>(this));
4099 0 : const SwStartNode* pSttNd = pTLBox->GetSttNd();
4100 0 : SwPosition aPos(*pSttNd);
4101 0 : UnoActionContext aAction(pFrameFormat->GetDoc());
4102 0 : auto pUnoCrsr(pFrameFormat->GetDoc()->CreateUnoCrsr(aPos, true));
4103 0 : pUnoCrsr->Move(fnMoveForward, fnGoNode);
4104 :
4105 : {
4106 : // remove actions
4107 0 : UnoActionRemoveContext aRemoveContext(pUnoCrsr->GetDoc());
4108 : }
4109 :
4110 0 : pFrameFormat->GetDoc()->InsertCol(*pUnoCrsr, (sal_uInt16)nCount, bAppend);
4111 : }
4112 :
4113 : ///@see SwXTableRows::removeByIndex (TODO: seems to be copy and paste programming here)
4114 0 : void SwXTableColumns::removeByIndex(sal_Int32 nIndex, sal_Int32 nCount)
4115 : throw (uno::RuntimeException, std::exception)
4116 : {
4117 0 : SolarMutexGuard aGuard;
4118 0 : if (nCount == 0)
4119 0 : return;
4120 0 : SwFrameFormat* pFrameFormat(lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this)));
4121 0 : if(nIndex < 0 || nCount <=0 )
4122 0 : throw uno::RuntimeException();
4123 0 : SwTable* pTable = lcl_EnsureTableNotComplex(SwTable::FindTable(pFrameFormat), static_cast<cppu::OWeakObject*>(this));
4124 0 : const OUString sTLName = sw_GetCellName(nIndex, 0);
4125 0 : const SwTableBox* pTLBox = pTable->GetTableBox( sTLName );
4126 0 : if(!pTLBox)
4127 0 : throw uno::RuntimeException("Cell not found", static_cast<cppu::OWeakObject*>(this));
4128 : {
4129 : // invalidate all actions
4130 0 : UnoActionRemoveContext aRemoveContext(pFrameFormat->GetDoc());
4131 : }
4132 0 : const SwStartNode* pSttNd = pTLBox->GetSttNd();
4133 0 : SwPosition aPos(*pSttNd);
4134 : // set cursor to the upper-left cell of the range
4135 0 : auto pUnoCrsr(pFrameFormat->GetDoc()->CreateUnoCrsr(aPos, true));
4136 0 : pUnoCrsr->Move(fnMoveForward, fnGoNode);
4137 0 : pUnoCrsr->SetRemainInSection(false);
4138 0 : const OUString sTRName = sw_GetCellName(nIndex + nCount - 1, 0);
4139 0 : const SwTableBox* pTRBox = pTable->GetTableBox(sTRName);
4140 0 : if(!pTRBox)
4141 0 : throw uno::RuntimeException("Cell not found", static_cast<cppu::OWeakObject*>(this));
4142 0 : pUnoCrsr->SetMark();
4143 0 : pUnoCrsr->GetPoint()->nNode = *pTRBox->GetSttNd();
4144 0 : pUnoCrsr->Move(fnMoveForward, fnGoNode);
4145 0 : SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr.get());
4146 0 : pCrsr->MakeBoxSels();
4147 : { // these braces are important
4148 0 : UnoActionContext aAction(pFrameFormat->GetDoc());
4149 0 : pFrameFormat->GetDoc()->DeleteCol(*pUnoCrsr);
4150 0 : pUnoCrsr.reset();
4151 : }
4152 : {
4153 : // invalidate all actions
4154 0 : UnoActionRemoveContext aRemoveContext(pFrameFormat->GetDoc());
4155 0 : }
4156 : }
4157 :
4158 2 : void SwXTableColumns::Modify(const SfxPoolItem* pOld, const SfxPoolItem *pNew)
4159 179 : { ClientModify(this, pOld, pNew); }
4160 :
4161 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|