xref: /trunk/main/sw/source/core/unocore/unotbl.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 
28 // STL includes
29 #include <list>
30 
31 #include <svx/svxids.hrc>
32 #include <editeng/memberids.hrc>
33 #include <float.h> // for DBL_MIN
34 #include <swtypes.hxx>
35 #include <cmdid.h>
36 #include <unotbl.hxx>
37 #include <unostyle.hxx>
38 #include <section.hxx>
39 #include <unocrsr.hxx>
40 #include <svx/unomid.hxx>
41 #include <hints.hxx>
42 #include <swtblfmt.hxx>
43 #include <doc.hxx>
44 #include <IDocumentUndoRedo.hxx>
45 #include <shellres.hxx>
46 #include <docary.hxx>
47 #include <ndole.hxx>
48 #include <frame.hxx>
49 #include <vcl/svapp.hxx>
50 #include <fmtfsize.hxx>
51 #include <tblafmt.hxx>
52 #include <tabcol.hxx>
53 #include <cellatr.hxx>
54 #include <fmtpdsc.hxx>
55 #include <pagedesc.hxx>
56 #define _SVSTDARR_STRINGS
57 #include <svl/svstdarr.hxx>
58 #include <viewsh.hxx>
59 #include <tabfrm.hxx>
60 #include <redline.hxx>
61 #include <unoredline.hxx>
62 #include <unoprnms.hxx>
63 #include <unocrsrhelper.hxx>
64 #include <com/sun/star/text/WrapTextMode.hpp>
65 #include <com/sun/star/text/TextContentAnchorType.hpp>
66 #include <com/sun/star/text/TableColumnSeparator.hpp>
67 #include <com/sun/star/text/XTextSection.hpp>
68 #include <com/sun/star/table/ShadowFormat.hpp>
69 #include <com/sun/star/table/TableBorder.hpp>
70 #include <com/sun/star/table/TableBorderDistances.hpp>
71 #include <com/sun/star/style/PageStyleLayout.hpp>
72 #include <com/sun/star/style/BreakType.hpp>
73 #include <com/sun/star/style/GraphicLocation.hpp>
74 #include <com/sun/star/beans/PropertyAttribute.hpp>
75 #include <com/sun/star/chart/XChartDataChangeEventListener.hpp>
76 #include <com/sun/star/chart/ChartDataChangeEvent.hpp>
77 #include <com/sun/star/chart2/data/XDataSequence.hpp>
78 #include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
79 #include <com/sun/star/table/CellContentType.hpp>
80 #include <unotbl.hxx>
81 #include <unotextrange.hxx>
82 #include <unotextcursor.hxx>
83 #include <unoparagraph.hxx>
84 #include <svl/zforlist.hxx>     // SvNumberFormatter
85 #include <editeng/brkitem.hxx>
86 #include <editeng/shaditem.hxx>
87 #include <editeng/lrspitem.hxx>
88 #include <editeng/ulspitem.hxx>
89 #include <fmtornt.hxx>
90 #include <editeng/keepitem.hxx>
91 #include <fmtlsplt.hxx>
92 #include <swundo.hxx>
93 #include <vos/mutex.hxx>
94 #include <SwStyleNameMapper.hxx>
95 #include <frmatr.hxx>
96 #include <crsskip.hxx>
97 #include <unochart.hxx>
98 #include <sortopt.hxx>
99 #include <rtl/math.hxx>
100 #include <switerator.hxx>
101 
102 using namespace ::com::sun::star;
103 using ::rtl::OUString;
104 
105 
106 //-----------------------------------------------------------------------------
107 // from swtable.cxx
108 extern void lcl_GetTblBoxColStr( sal_uInt16 nCol, String& rNm );
109 
110 #define UNO_TABLE_COLUMN_SUM    10000
111 
lcl_SvxLineToLine(const SvxBorderLine * pLine)112 table::BorderLine lcl_SvxLineToLine(const SvxBorderLine* pLine)
113 {
114     table::BorderLine aLine;
115     if(pLine)
116     {
117         aLine.Color          = pLine->GetColor().GetColor() ;
118         aLine.InnerLineWidth = TWIP_TO_MM100_UNSIGNED( pLine->GetInWidth() );
119         aLine.OuterLineWidth = TWIP_TO_MM100_UNSIGNED( pLine->GetOutWidth() );
120         aLine.LineDistance   = TWIP_TO_MM100_UNSIGNED( pLine->GetDistance() );
121     }
122     else
123         aLine.Color          = aLine.InnerLineWidth = aLine.OuterLineWidth = aLine.LineDistance  = 0;
124     return aLine;
125 }
126 
lcl_LineToSvxLine(const table::BorderLine & rLine,SvxBorderLine & rSvxLine)127 sal_Bool lcl_LineToSvxLine(const table::BorderLine& rLine, SvxBorderLine& rSvxLine)
128 {
129     rSvxLine.SetColor(   Color(rLine.Color));
130     rSvxLine.SetInWidth( MM100_TO_TWIP( rLine.InnerLineWidth ) );
131     rSvxLine.SetOutWidth(MM100_TO_TWIP( rLine.OuterLineWidth ) );
132     rSvxLine.SetDistance(MM100_TO_TWIP( rLine.LineDistance  ) );
133     sal_Bool bRet = rLine.InnerLineWidth > 0 || rLine.OuterLineWidth > 0;
134     return bRet;
135 }
136 
lcl_SetSpecialProperty(SwFrmFmt * pFmt,const SfxItemPropertySimpleEntry * pEntry,const uno::Any & aValue)137 void lcl_SetSpecialProperty(SwFrmFmt* pFmt, const SfxItemPropertySimpleEntry* pEntry, const uno::Any& aValue)
138 {
139     //Sonderbehandlung fuer "Nicht-Items"
140     switch(pEntry->nWID)
141     {
142         case  FN_TABLE_HEADLINE_REPEAT:
143         case  FN_TABLE_HEADLINE_COUNT:
144         {
145             SwTable* pTable = SwTable::FindTable( pFmt );
146             {
147                 UnoActionContext aAction(pFmt->GetDoc());
148                 if( pEntry->nWID == FN_TABLE_HEADLINE_REPEAT)
149                 {
150                     sal_Bool bVal = *(sal_Bool*)aValue.getValue();
151                     pFmt->GetDoc()->SetRowsToRepeat( *pTable, bVal ? 1 : 0 );
152                 }
153                 else
154                 {
155                     sal_Int32 nRepeat = 0;
156                     aValue >>= nRepeat;
157                     if( nRepeat >= 0 && nRepeat < USHRT_MAX )
158                         pFmt->GetDoc()->SetRowsToRepeat( *pTable, (sal_uInt16) nRepeat );
159                 }
160             }
161         }
162         break;
163         case  FN_TABLE_IS_RELATIVE_WIDTH:
164         case  FN_TABLE_WIDTH:
165         case  FN_TABLE_RELATIVE_WIDTH:
166         {
167             sal_Int32 nWidth = 0;
168             SwFmtFrmSize aSz( pFmt->GetFrmSize() );
169             if(FN_TABLE_WIDTH == pEntry->nWID)
170             {
171                 aValue >>= nWidth;
172                 aSz.SetWidthPercent(0);
173                 aSz.SetWidth ( MM100_TO_TWIP ( nWidth ) );
174             }
175             else if(FN_TABLE_RELATIVE_WIDTH == pEntry->nWID)
176             {
177                 sal_Int16 nSet = 0;
178                 aValue >>= nSet;
179                 if(nSet && nSet <=100)
180                     aSz.SetWidthPercent( (sal_uInt8)nSet );
181             }
182             else if(FN_TABLE_IS_RELATIVE_WIDTH == pEntry->nWID)
183             {
184                 sal_Bool bPercent = *(sal_Bool*)aValue.getValue();
185                 if(!bPercent)
186                     aSz.SetWidthPercent(0);
187                 else
188                 {
189                     lang::IllegalArgumentException aExcept;
190                     aExcept.Message = C2U("relative width cannot be switched on with this property");
191                     throw aExcept;
192                 }
193             }
194             pFmt->GetDoc()->SetAttr(aSz, *pFmt);
195         }
196         break;
197         case RES_PAGEDESC:
198         {
199             OUString uTemp;
200             aValue >>= uTemp;
201             String sPageStyle = uTemp;
202             const SwPageDesc* pDesc = 0;
203             if(sPageStyle.Len())
204             {
205                 SwStyleNameMapper::FillUIName(sPageStyle, sPageStyle, nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC, sal_True );
206                 pDesc = ::GetPageDescByName_Impl(*pFmt->GetDoc(), sPageStyle);
207             }
208             SwFmtPageDesc aDesc( pDesc );
209             pFmt->GetDoc()->SetAttr(aDesc, *pFmt);
210         }
211         break;
212         default:
213             throw lang::IllegalArgumentException();
214     }
215 }
216 
lcl_GetSpecialProperty(SwFrmFmt * pFmt,const SfxItemPropertySimpleEntry * pEntry)217 uno::Any lcl_GetSpecialProperty(SwFrmFmt* pFmt, const SfxItemPropertySimpleEntry* pEntry )
218 {
219     uno::Any aRet;
220     switch(pEntry->nWID)
221     {
222         case  FN_TABLE_HEADLINE_REPEAT:
223         case  FN_TABLE_HEADLINE_COUNT:
224         {
225             SwTable* pTable = SwTable::FindTable( pFmt );
226             sal_uInt16 nRepeat = pTable->GetRowsToRepeat();
227             if(pEntry->nWID == FN_TABLE_HEADLINE_REPEAT)
228             {
229                 sal_Bool bTemp = nRepeat > 0;
230                 aRet.setValue(&bTemp, ::getCppuBooleanType());
231             }
232             else
233                 aRet <<= (sal_Int32)nRepeat;
234         }
235         break;
236         case  FN_TABLE_WIDTH:
237         case  FN_TABLE_IS_RELATIVE_WIDTH:
238         case  FN_TABLE_RELATIVE_WIDTH:
239         {
240             const SwFmtFrmSize& rSz = pFmt->GetFrmSize();
241             if(FN_TABLE_WIDTH == pEntry->nWID)
242                 rSz.QueryValue(aRet, MID_FRMSIZE_WIDTH|CONVERT_TWIPS);
243             else if(FN_TABLE_RELATIVE_WIDTH == pEntry->nWID)
244                 rSz.QueryValue(aRet, MID_FRMSIZE_REL_WIDTH);
245             else
246             {
247                 sal_Bool bTemp = 0 != rSz.GetWidthPercent();
248                 aRet.setValue(&bTemp, ::getBooleanCppuType());
249             }
250         }
251         break;
252         case RES_PAGEDESC:
253         {
254             const SfxItemSet& rSet = pFmt->GetAttrSet();
255             const SfxPoolItem* pItem;
256             String sPDesc;
257             if(SFX_ITEM_SET == rSet.GetItemState(RES_PAGEDESC, sal_False, &pItem))
258             {
259                 const SwPageDesc* pDsc = ((const SwFmtPageDesc*)pItem)->GetPageDesc();
260                 if(pDsc)
261                 {
262                    sPDesc = SwStyleNameMapper::GetProgName(pDsc->GetName(), nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC );
263                 }
264             }
265             aRet <<= OUString(sPDesc);
266         }
267         break;
268         case RES_ANCHOR :
269             aRet <<= text::TextContentAnchorType_AT_PARAGRAPH;
270         break;
271         case FN_UNO_ANCHOR_TYPES :
272         {
273             uno::Sequence<text::TextContentAnchorType> aTypes(1);
274             text::TextContentAnchorType* pArray = aTypes.getArray();
275             pArray[0] = text::TextContentAnchorType_AT_PARAGRAPH;
276             aRet <<= aTypes;
277         }
278         break;
279         case FN_UNO_WRAP :
280         {
281             aRet <<= text::WrapTextMode_NONE;
282         }
283         break;
284         case FN_PARAM_LINK_DISPLAY_NAME :
285             aRet <<= OUString(pFmt->GetName());
286         break;
287         case FN_UNO_REDLINE_NODE_START:
288         case FN_UNO_REDLINE_NODE_END:
289         {
290             SwTable* pTable = SwTable::FindTable( pFmt );
291             SwNode* pTblNode = pTable->GetTableNode();
292             if(FN_UNO_REDLINE_NODE_END == pEntry->nWID)
293                 pTblNode = pTblNode->EndOfSectionNode();
294             const SwRedlineTbl& rRedTbl = pFmt->GetDoc()->GetRedlineTbl();
295             for(sal_uInt16 nRed = 0; nRed < rRedTbl.Count(); nRed++)
296             {
297                 const SwRedline* pRedline = rRedTbl[nRed];
298                 const SwNode* pRedPointNode = pRedline->GetNode(sal_True);
299                 const SwNode* pRedMarkNode = pRedline->GetNode(sal_False);
300                 if(pRedPointNode == pTblNode || pRedMarkNode == pTblNode)
301                 {
302                     const SwNode* pStartOfRedline = SwNodeIndex(*pRedPointNode) <= SwNodeIndex(*pRedMarkNode) ?
303                         pRedPointNode : pRedMarkNode;
304                     sal_Bool bIsStart = pStartOfRedline == pTblNode;
305                     aRet <<= SwXRedlinePortion::CreateRedlineProperties(*pRedline, bIsStart);
306                     break;
307                 }
308             }
309         }
310         break;
311     }
312     return aRet;
313 }
314 
315 // returns the position for the cell with the specified name
316 // (note that the indices rColumn and rRow are 0 based here)
317 // Also since the implementations of tables does not really have
318 // columns using this function is appropriate only for tables
319 // that are not complex (i.e. where IsTblComplex() returns false).
320 //
321 // returns: both indices for column and row (all >= 0) if everything was Ok.
322 //          At least one value < 0 if sth was wrong.
323 //
324 // Sample for naming scheme of cell in a single row (in groups a 26):
325 // A1..Z1, a1..z1, AA1..AZ1, Aa1..Az1, BA1..BZ1, Ba1..Bz1, ...
lcl_GetCellPosition(const String & rCellName,sal_Int32 & rColumn,sal_Int32 & rRow)326 void lcl_GetCellPosition( const String &rCellName,
327         sal_Int32 &rColumn, sal_Int32 &rRow)
328 {
329     rColumn = rRow = -1;    // default return values indicating failure
330     xub_StrLen nLen = rCellName.Len();
331     if (nLen)
332     {
333         const sal_Unicode *pBuf = rCellName.GetBuffer();
334         const sal_Unicode *pEnd = pBuf + nLen;
335         while (pBuf < pEnd && !('0' <= *pBuf && *pBuf <= '9'))
336             ++pBuf;
337         // start of number found?
338         if (pBuf < pEnd && ('0' <= *pBuf && *pBuf <= '9'))
339         {
340             String aColTxt( rCellName.GetBuffer(), static_cast< xub_StrLen >(pBuf - rCellName.GetBuffer()) );
341             String aRowTxt( pBuf, static_cast< xub_StrLen >(rCellName.GetBuffer() + nLen - pBuf) );
342             if (aColTxt.Len() && aRowTxt.Len())
343             {
344                 sal_Int32 nColIdx = 0;
345                 sal_Int32 nLength = aColTxt.Len();
346                 for (xub_StrLen i = 0;  i < nLength;  ++i)
347                 {
348                     nColIdx = 52 * nColIdx;
349                     if (i < nLength - 1)
350                         ++nColIdx;
351                     sal_Unicode cChar = aColTxt.GetBuffer()[i];
352                     if ('A' <= cChar && cChar <= 'Z')
353                         nColIdx = nColIdx + (cChar - 'A');
354                     else if ('a' <= cChar && cChar <= 'z')
355                         nColIdx = nColIdx + (26 + cChar - 'a');
356                     else
357                     {
358                         nColIdx = -1;   // sth failed
359                         break;
360                     }
361                 }
362 
363                 rColumn = nColIdx;
364                 rRow    = aRowTxt.ToInt32() - 1;    // - 1 because indices ought to be 0 based
365             }
366         }
367     }
368 #if OSL_DEBUG_LEVEL > 1
369     DBG_ASSERT( rColumn != -1 && rRow != -1, "failed to get column or row index" );
370 #endif
371 }
372 
373 
374 // arguments: must be non-empty strings with valid cell names
375 //
376 // returns: -1 if first cell < second cell
377 //           0 if both cells are equal
378 //          +1 if the first cell > second cell
379 //
380 // Note: this function probably also make sense only
381 //      for cell names of non-complex tables
lcl_CompareCellsByRowFirst(const String & rCellName1,const String & rCellName2)382 int lcl_CompareCellsByRowFirst( const String &rCellName1, const String &rCellName2 )
383 {
384     sal_Int32 nCol1 = -1, nRow1 = -1, nCol2 = -1, nRow2 = -1;
385     lcl_GetCellPosition( rCellName1, nCol1, nRow1 );
386     lcl_GetCellPosition( rCellName2, nCol2, nRow2 );
387 
388     if (nRow1 < nRow2 || (nRow1 == nRow2 && nCol1 < nCol2))
389         return -1;
390     else if (nCol1 == nCol2 && nRow1 == nRow2)
391         return 0;
392     else
393         return +1;
394 }
395 
396 
397 // arguments: must be non-empty strings with valid cell names
398 //
399 // returns: -1 if first cell < second cell
400 //           0 if both cells are equal
401 //          +1 if the first cell > second cell
402 //
403 // Note: this function probably also make sense only
404 //      for cell names of non-complex tables
lcl_CompareCellsByColFirst(const String & rCellName1,const String & rCellName2)405 int lcl_CompareCellsByColFirst( const String &rCellName1, const String &rCellName2 )
406 {
407     sal_Int32 nCol1 = -1, nRow1 = -1, nCol2 = -1, nRow2 = -1;
408     lcl_GetCellPosition( rCellName1, nCol1, nRow1 );
409     lcl_GetCellPosition( rCellName2, nCol2, nRow2 );
410 
411     if (nCol1 < nCol2 || (nCol1 == nCol2 && nRow1 < nRow2))
412         return -1;
413     else if (nRow1 == nRow2 && nCol1 == nCol2)
414         return 0;
415     else
416         return +1;
417 }
418 
419 
420 // arguments: must be non-empty strings with valid cell names
421 //
422 // returns: -1 if first cell range < second cell range
423 //           0 if both cell ranges are identical
424 //          +1 if the first cell range > second cell range
425 //
426 // Note: this function probably also make sense only
427 //      for cell names of non-complex tables
lcl_CompareCellRanges(const String & rRange1StartCell,const String & rRange1EndCell,const String & rRange2StartCell,const String & rRange2EndCell,sal_Bool bCmpColsFirst)428 int lcl_CompareCellRanges(
429         const String &rRange1StartCell, const String &rRange1EndCell,
430         const String &rRange2StartCell, const String &rRange2EndCell,
431         sal_Bool bCmpColsFirst )
432 {
433     int (*pCompareCells)( const String &, const String & ) =
434             bCmpColsFirst ? &lcl_CompareCellsByColFirst : &lcl_CompareCellsByRowFirst;
435 
436     int nCmpResStartCells = pCompareCells( rRange1StartCell, rRange2StartCell );
437     if ((-1 == nCmpResStartCells ) ||
438          ( 0 == nCmpResStartCells &&
439           -1 == pCompareCells( rRange1EndCell, rRange2EndCell ) ))
440         return -1;
441     else if (0 == nCmpResStartCells &&
442              0 == pCompareCells( rRange1EndCell, rRange2EndCell ))
443         return 0;
444     else
445         return +1;
446 }
447 
448 
449 // returns the cell name for the cell at the specified position
450 // (note that the indices nColumn and nRow are 0 based here)
lcl_GetCellName(sal_Int32 nColumn,sal_Int32 nRow)451 String lcl_GetCellName( sal_Int32 nColumn, sal_Int32 nRow )
452 {
453 #if OSL_DEBUG_LEVEL > 1
454     {
455         sal_Int32 nCol, nRow2;
456         lcl_GetCellPosition( String::CreateFromAscii("z1"), nCol, nRow2);
457         DBG_ASSERT( nCol == 51, "lcl_GetCellPosition failed" );
458         lcl_GetCellPosition( String::CreateFromAscii("AA1"), nCol, nRow2);
459         DBG_ASSERT( nCol == 52, "lcl_GetCellPosition failed" );
460         lcl_GetCellPosition( String::CreateFromAscii("AB1"), nCol, nRow2);
461         DBG_ASSERT( nCol == 53, "lcl_GetCellPosition failed" );
462         lcl_GetCellPosition( String::CreateFromAscii("BB1"), nCol, nRow2);
463         DBG_ASSERT( nCol == 105, "lcl_GetCellPosition failed" );
464     }
465 #endif
466 
467     String sCellName;
468     if (nColumn < 0 || nRow < 0)
469         return sCellName;
470     lcl_GetTblBoxColStr( static_cast< sal_uInt16 >(nColumn), sCellName );
471     sCellName += String::CreateFromInt32( nRow + 1 );
472     return sCellName;
473 }
474 
475 /** Find the top left or bottom right corner box in given table.
476   Consider nested lines when finding the box.
477 
478   @param i_pTable the table
479 
480   @param i_bTopLeft if true, find top left box, otherwise find bottom
481          right box
482  */
483 
lcl_FindCornerTableBox(const SwTableLines & rTableLines,const bool i_bTopLeft)484 const SwTableBox* lcl_FindCornerTableBox(const SwTableLines& rTableLines, const bool i_bTopLeft)
485 {
486     bool bFirst = true;
487     const SwTableBox* pBox = 0;
488     do
489     {
490         const SwTableLines& rLines(bFirst ? rTableLines : pBox->GetTabLines());
491         bFirst = false;
492         OSL_ASSERT(rLines.Count() != 0);
493         if (rLines.Count() != 0)
494         {
495             const SwTableLine* pLine(rLines[i_bTopLeft ? 0 : rLines.Count() - 1]);
496             OSL_ASSERT(pLine);
497             const SwTableBoxes& rBoxes(pLine->GetTabBoxes());
498             OSL_ASSERT(rBoxes.Count() != 0);
499             pBox = rBoxes[i_bTopLeft ? 0 : rBoxes.Count() - 1];
500             OSL_ASSERT(pBox);
501         }
502         else
503         {
504             pBox = 0;
505         }
506     } while (pBox && !pBox->GetSttNd());
507     return pBox;
508 }
509 
510 // start cell should be in the upper-left corner of the range and
511 // end cell in the lower-right.
512 // I.e. from the four possible representation
513 //      A1:C5, C5:A1, A5:C1, C1:A5
514 // only A1:C5 is the one to use
lcl_NormalizeRange(String & rCell1,String & rCell2)515 void lcl_NormalizeRange(
516     String &rCell1,     // will hold the upper-left cell of the range upon return
517     String &rCell2 )    // will hold the lower-right cell of the range upon return
518 {
519     sal_Int32 nCol1 = -1, nRow1 = -1, nCol2 = -1, nRow2 = -1;
520     lcl_GetCellPosition( rCell1, nCol1, nRow1 );
521     lcl_GetCellPosition( rCell2, nCol2, nRow2 );
522     if (nCol2 < nCol1 || nRow2 < nRow1)
523     {
524         rCell1  = lcl_GetCellName( Min(nCol1, nCol2), Min(nRow1, nRow2) );
525         rCell2  = lcl_GetCellName( Max(nCol1, nCol2), Max(nRow1, nRow2) );
526     }
527 
528 }
529 
Normalize()530 void SwRangeDescriptor::Normalize()
531 {
532     if (nTop > nBottom)
533     {
534         sal_Int32 nTmp = nTop;
535         nTop = nBottom;
536         nBottom = nTmp;
537     }
538     if (nLeft > nRight)
539     {
540         sal_Int32 nTmp = nLeft;
541         nLeft = nRight;
542         nRight = nTmp;
543     }
544 }
545 
546 
lcl_CreateXCell(SwFrmFmt * pFmt,sal_Int32 nColumn,sal_Int32 nRow)547 SwXCell* lcl_CreateXCell(SwFrmFmt* pFmt, sal_Int32 nColumn, sal_Int32 nRow)
548 {
549     SwXCell* pXCell = 0;
550     String sCellName = lcl_GetCellName(nColumn, nRow);
551     SwTable* pTable = SwTable::FindTable( pFmt );
552     SwTableBox* pBox = (SwTableBox*)pTable->GetTblBox( sCellName );
553     if(pBox)
554     {
555         pXCell = SwXCell::CreateXCell(pFmt, pBox, pTable);
556     }
557     return pXCell;
558 }
559 
lcl_InspectLines(SwTableLines & rLines,SvStrings & rAllNames)560 void lcl_InspectLines(SwTableLines& rLines, SvStrings& rAllNames)
561 {
562     for( sal_uInt16 i = 0; i < rLines.Count(); i++ )
563     {
564         SwTableLine* pLine = rLines[i];
565         SwTableBoxes& rBoxes = pLine->GetTabBoxes();
566         for(sal_uInt16 j = 0; j < rBoxes.Count(); j++)
567         {
568             SwTableBox* pBox = rBoxes[j];
569             if(pBox->GetName().Len() && pBox->getRowSpan() > 0 )
570                 rAllNames.Insert(new String(pBox->GetName()), rAllNames.Count());
571             SwTableLines& rBoxLines = pBox->GetTabLines();
572             if(rBoxLines.Count())
573             {
574                 lcl_InspectLines(rBoxLines, rAllNames);
575             }
576         }
577     }
578 }
579 
lcl_FormatTable(SwFrmFmt * pTblFmt)580 void lcl_FormatTable(SwFrmFmt* pTblFmt)
581 {
582     SwIterator<SwFrm,SwFmt> aIter( *pTblFmt );
583     for( SwFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
584     {
585         // mba: no TYPEINFO for SwTabFrm
586         if( pFrm->IsTabFrm() )
587         {
588             if(pFrm->IsValid())
589                 pFrm->InvalidatePos();
590             ((SwTabFrm*)pFrm)->SetONECalcLowers();
591             ((SwTabFrm*)pFrm)->Calc();
592         }
593     }
594 }
595 
lcl_CrsrSelect(SwPaM * pCrsr,sal_Bool bExpand)596 void lcl_CrsrSelect(SwPaM* pCrsr, sal_Bool bExpand)
597 {
598     if(bExpand)
599     {
600         if(!pCrsr->HasMark())
601             pCrsr->SetMark();
602     }
603     else if(pCrsr->HasMark())
604         pCrsr->DeleteMark();
605 
606 }
607 
lcl_GetTblSeparators(uno::Any & rRet,SwTable * pTable,SwTableBox * pBox,sal_Bool bRow)608 void lcl_GetTblSeparators(uno::Any& rRet, SwTable* pTable, SwTableBox* pBox, sal_Bool bRow)
609 {
610     SwTabCols aCols;
611     aCols.SetLeftMin ( 0 );
612     aCols.SetLeft    ( 0 );
613     aCols.SetRight   ( UNO_TABLE_COLUMN_SUM );
614     aCols.SetRightMax( UNO_TABLE_COLUMN_SUM );
615 
616     pTable->GetTabCols( aCols, pBox, sal_False, bRow );
617 
618     sal_uInt16 nSepCount = aCols.Count();
619     uno::Sequence< text::TableColumnSeparator> aColSeq(nSepCount);
620     text::TableColumnSeparator* pArray = aColSeq.getArray();
621     sal_Bool bError = sal_False;
622     for(sal_uInt16 i = 0; i < nSepCount; i++)
623     {
624         pArray[i].Position = static_cast< sal_Int16 >(aCols[i]);
625         pArray[i].IsVisible = !aCols.IsHidden(i);
626         if(!bRow && !pArray[i].IsVisible)
627         {
628             bError = sal_True;
629             break;
630         }
631     }
632     if(!bError)
633         rRet.setValue(&aColSeq, ::getCppuType((uno::Sequence< text::TableColumnSeparator>*)0));
634 
635 }
636 
lcl_SetTblSeparators(const uno::Any & rVal,SwTable * pTable,SwTableBox * pBox,sal_Bool bRow,SwDoc * pDoc)637 void lcl_SetTblSeparators(const uno::Any& rVal, SwTable* pTable, SwTableBox* pBox, sal_Bool bRow, SwDoc* pDoc)
638 {
639     SwTabCols aOldCols;
640 
641     aOldCols.SetLeftMin ( 0 );
642     aOldCols.SetLeft    ( 0 );
643     aOldCols.SetRight   ( UNO_TABLE_COLUMN_SUM );
644     aOldCols.SetRightMax( UNO_TABLE_COLUMN_SUM );
645 
646     pTable->GetTabCols( aOldCols, pBox, sal_False, bRow );
647     sal_uInt16 nOldCount = aOldCols.Count();
648     //there's no use in setting tab cols if there's only one column
649     if( !nOldCount )
650         return;
651 
652     const uno::Sequence< text::TableColumnSeparator>* pSepSeq =
653                 (uno::Sequence< text::TableColumnSeparator>*) rVal.getValue();
654     if(pSepSeq && pSepSeq->getLength() == nOldCount)
655     {
656         SwTabCols aCols(aOldCols);
657         sal_Bool bError = sal_False;
658         const text::TableColumnSeparator* pArray = pSepSeq->getConstArray();
659         sal_Int32 nLastValue = 0;
660         //sal_Int32 nTblWidth = aCols.GetRight() - aCols.GetLeft();
661         for(sal_uInt16 i = 0; i < nOldCount; i++)
662         {
663             aCols[i] = pArray[i].Position;
664             if(pArray[i].IsVisible == aCols.IsHidden(i) ||
665                 (!bRow && aCols.IsHidden(i)) ||
666                 long(aCols[i] - long(nLastValue)) < 0 ||
667                 UNO_TABLE_COLUMN_SUM < aCols[i] )
668             {
669                 bError = sal_True;
670                 break;
671             }
672             nLastValue = aCols[i];
673         }
674         if(!bError)
675         {
676             pDoc->SetTabCols(*pTable, aCols, aOldCols, pBox, bRow );
677         }
678     }
679 }
680 
lcl_getString(SwXCell & rCell)681 inline rtl::OUString lcl_getString( SwXCell &rCell )
682 {
683     // getString is a member function of the base class...
684     return rCell.getString();
685 }
686 /*  non UNO function call to set string in SwXCell */
lcl_setString(SwXCell & rCell,const rtl::OUString & rTxt,sal_Bool bKeepNumberFmt)687 void lcl_setString( SwXCell &rCell, const rtl::OUString &rTxt,
688         sal_Bool bKeepNumberFmt )
689 {
690     if(rCell.IsValid())
691     {
692         SwFrmFmt* pBoxFmt = rCell.pBox->ClaimFrmFmt();
693         pBoxFmt->LockModify();
694         pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMULA );
695         pBoxFmt->ResetFmtAttr( RES_BOXATR_VALUE );
696         if (!bKeepNumberFmt)
697             pBoxFmt->SetFmtAttr( SwTblBoxNumFormat(NUMBERFORMAT_TEXT) );
698         pBoxFmt->UnlockModify();
699     }
700     rCell.SwXText::setString(rTxt);
701 }
702 /* non UNO function call to get value from SwXCell */
lcl_getValue(SwXCell & rCell)703 double lcl_getValue( SwXCell &rCell )
704 {
705     double fRet;
706     if(rCell.IsValid() && rCell.getString().getLength()!=0)
707         fRet = rCell.pBox->GetFrmFmt()->GetTblBoxValue().GetValue();
708     else
709         ::rtl::math::setNan( &fRet );
710     return fRet;
711 }
712 /* non UNO function call to set value in SwXCell */
lcl_setValue(SwXCell & rCell,double nVal)713 void lcl_setValue( SwXCell &rCell, double nVal )
714 {
715     if(rCell.IsValid())
716     {
717         // Der Text mu? zunaechst (vielleicht) geloescht werden
718         sal_uLong nNdPos = rCell.pBox->IsValidNumTxtNd( sal_True );
719         if(ULONG_MAX != nNdPos)
720             lcl_setString( rCell, OUString(), sal_True );   // sal_True == keep number format
721         SwDoc* pDoc = rCell.GetDoc();
722         UnoActionContext aAction(pDoc);
723         SwFrmFmt* pBoxFmt = rCell.pBox->ClaimFrmFmt();
724         SfxItemSet aSet(pDoc->GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_VALUE);
725         const SfxPoolItem* pItem;
726 
727         //!! do we need to set a new number format? Yes, if
728         // - there is no current number format
729         // - the current number format is not a number format according to the number formatter, but rather a text format
730         // - the current number format is not even a valid number formatter number format, but rather Writer's own 'special' text number format
731         if(SFX_ITEM_SET != pBoxFmt->GetAttrSet().GetItemState(RES_BOXATR_FORMAT, sal_True, &pItem)
732             ||  pDoc->GetNumberFormatter()->IsTextFormat(((SwTblBoxNumFormat*)pItem)->GetValue())
733             ||  ((SwTblBoxNumFormat*)pItem)->GetValue() == NUMBERFORMAT_TEXT)
734         {
735             aSet.Put(SwTblBoxNumFormat(0));
736         }
737 
738         SwTblBoxValue aVal(nVal);
739         aSet.Put(aVal);
740         pDoc->SetTblBoxFormulaAttrs( *rCell.pBox, aSet );
741         //Tabelle aktualisieren
742         SwTableFmlUpdate aTblUpdate( SwTable::FindTable( rCell.GetFrmFmt() ));
743         pDoc->UpdateTblFlds( &aTblUpdate );
744     }
745 }
746 /******************************************************************
747  * SwXCell
748  ******************************************************************/
749 TYPEINIT1(SwXCell, SwClient);
750 
SwXCell(SwFrmFmt * pTblFmt,SwTableBox * pBx,sal_uInt16 nPos)751 SwXCell::SwXCell(SwFrmFmt* pTblFmt, SwTableBox* pBx, sal_uInt16 nPos ) :
752     SwXText(pTblFmt->GetDoc(), CURSOR_TBLTEXT),
753     SwClient(pTblFmt),
754     m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TABLE_CELL)),
755     pBox(pBx),
756     pStartNode(0),
757     nFndPos(nPos)
758 {
759 }
760 
SwXCell(SwFrmFmt * pTblFmt,const SwStartNode & rStartNode)761 SwXCell::SwXCell(SwFrmFmt* pTblFmt, const SwStartNode& rStartNode) :
762     SwXText(pTblFmt->GetDoc(), CURSOR_TBLTEXT),
763     SwClient(pTblFmt),
764     m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TABLE_CELL)),
765     pBox(0),
766     pStartNode(&rStartNode),
767     nFndPos(USHRT_MAX)
768 {
769 }
770 
~SwXCell()771 SwXCell::~SwXCell()
772 {
773 
774 }
775 
getUnoTunnelId()776 const uno::Sequence< sal_Int8 > & SwXCell::getUnoTunnelId()
777 {
778     static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
779     return aSeq;
780 }
781 
getSomething(const uno::Sequence<sal_Int8> & rId)782 sal_Int64 SAL_CALL SwXCell::getSomething( const uno::Sequence< sal_Int8 >& rId )
783 {
784     if( rId.getLength() == 16
785         && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
786                                         rId.getConstArray(), 16 ) )
787     {
788         return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
789     }
790     else
791         return SwXText::getSomething(rId);
792 }
793 
getTypes()794 uno::Sequence< uno::Type > SAL_CALL SwXCell::getTypes(  )
795 {
796     static uno::Sequence< uno::Type > aRetTypes;
797     if(!aRetTypes.getLength())
798     {
799         aRetTypes = SwXCellBaseClass::getTypes();
800         uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
801 
802         long nIndex = aRetTypes.getLength();
803         aRetTypes.realloc(
804             aRetTypes.getLength() +
805             aTextTypes.getLength());
806 
807         uno::Type* pRetTypes = aRetTypes.getArray();
808 
809         const uno::Type* pTextTypes = aTextTypes.getConstArray();
810         for(long nPos = 0; nPos <aTextTypes.getLength(); nPos++)
811             pRetTypes[nIndex++] = pTextTypes[nPos];
812     }
813     return aRetTypes;
814 }
815 
getImplementationId()816 uno::Sequence< sal_Int8 > SAL_CALL SwXCell::getImplementationId(  )
817 {
818     vos::OGuard aGuard(Application::GetSolarMutex());
819     static uno::Sequence< sal_Int8 > aId( 16 );
820     static sal_Bool bInit = sal_False;
821     if(!bInit)
822     {
823         rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
824         bInit = sal_True;
825     }
826     return aId;
827 }
828 
acquire()829 void SAL_CALL SwXCell::acquire(  ) throw()
830 {
831     SwXCellBaseClass::acquire();
832 }
833 
release()834 void SAL_CALL SwXCell::release(  ) throw()
835 {
836     SwXCellBaseClass::release();
837 }
838 
queryInterface(const uno::Type & aType)839 uno::Any SAL_CALL SwXCell::queryInterface( const uno::Type& aType )
840 {
841     uno::Any aRet = SwXCellBaseClass::queryInterface(aType);
842     if(aRet.getValueType() == ::getCppuVoidType())
843         aRet = SwXText::queryInterface(aType);
844     return aRet;
845 }
846 
GetStartNode() const847 const SwStartNode *SwXCell::GetStartNode() const
848 {
849     const SwStartNode *pSttNd = 0;
850 
851     if( pStartNode || ((SwXCell *)this)->IsValid() )
852         pSttNd = pStartNode ? pStartNode : pBox->GetSttNd();
853 
854     return pSttNd;
855 }
856 
857 uno::Reference< text::XTextCursor >
CreateCursor()858 SwXCell::CreateCursor()
859 {
860     return createTextCursor();
861 }
862 
IsValid() const863 bool SwXCell::IsValid() const
864 {
865     // FIXME: this is now a const method, to make SwXText::IsValid invisible
866     // but the const_cast here are still ridiculous. TODO: find a better way.
867     SwFrmFmt* pTblFmt = pBox ? GetFrmFmt() : 0;
868     if(!pTblFmt)
869     {
870         const_cast<SwXCell*>(this)->pBox = 0;
871     }
872     else
873     {
874         SwTable* pTable = SwTable::FindTable( pTblFmt );
875         SwTableBox const*const pFoundBox =
876             const_cast<SwXCell*>(this)->FindBox(pTable, pBox);
877         if (!pFoundBox)
878         {
879             const_cast<SwXCell*>(this)->pBox = 0;
880         }
881     }
882     return 0 != pBox;
883 }
884 
getFormula(void)885 OUString SwXCell::getFormula(void)
886 {
887     vos::OGuard aGuard(Application::GetSolarMutex());
888     OUString sRet;
889     if(IsValid())
890     {
891         SwTblBoxFormula aFormula( pBox->GetFrmFmt()->GetTblBoxFormula() );
892         SwTable* pTable = SwTable::FindTable( GetFrmFmt() );
893         aFormula.PtrToBoxNm( pTable );
894         sRet = aFormula.GetFormula();
895     }
896     return sRet;
897 }
898 
setFormula(const OUString & rFormula)899 void SwXCell::setFormula(const OUString& rFormula)
900 {
901     vos::OGuard aGuard(Application::GetSolarMutex());
902     if(IsValid())
903     {
904         // Der Text mu? zunaechst (vielleicht) geloescht werden
905         sal_uInt32 nNdPos = pBox->IsValidNumTxtNd( sal_True );
906         if(USHRT_MAX == nNdPos)
907             lcl_setString( *this, OUString(), sal_True );
908         String sFml(rFormula);
909         if( sFml.EraseLeadingChars().Len() && '=' == sFml.GetChar( 0 ) )
910                     sFml.Erase( 0, 1 );
911         SwTblBoxFormula aFml( sFml );
912         SwDoc* pMyDoc = GetDoc();
913         UnoActionContext aAction(pMyDoc);
914         SfxItemSet aSet(pMyDoc->GetAttrPool(), RES_BOXATR_FORMAT, RES_BOXATR_FORMULA);
915         const SfxPoolItem* pItem;
916         SwFrmFmt* pBoxFmt = pBox->GetFrmFmt();
917         if(SFX_ITEM_SET != pBoxFmt->GetAttrSet().GetItemState(RES_BOXATR_FORMAT, sal_True, &pItem)
918             ||  pMyDoc->GetNumberFormatter()->IsTextFormat(((SwTblBoxNumFormat*)pItem)->GetValue()))
919         {
920             aSet.Put(SwTblBoxNumFormat(0));
921         }
922         aSet.Put(aFml);
923         GetDoc()->SetTblBoxFormulaAttrs( *pBox, aSet );
924         //Tabelle aktualisieren
925         SwTableFmlUpdate aTblUpdate( SwTable::FindTable( GetFrmFmt() ));
926         pMyDoc->UpdateTblFlds( &aTblUpdate );
927     }
928 }
929 
getValue(void)930 double SwXCell::getValue(void)
931 {
932     vos::OGuard aGuard(Application::GetSolarMutex());
933 
934     double const fRet = lcl_getValue( *this );
935     // #i112652# a table cell may contain NaN as a value, do not filter that
936     return fRet;
937 }
938 
setValue(double rValue)939 void SwXCell::setValue(double rValue)
940 {
941     vos::OGuard aGuard(Application::GetSolarMutex());
942     lcl_setValue( *this, rValue );
943 }
944 
getType(void)945 table::CellContentType SwXCell::getType(void)
946 {
947     vos::OGuard aGuard(Application::GetSolarMutex());
948 
949     table::CellContentType nRes = table::CellContentType_EMPTY;
950     sal_uInt32 nNdPos = pBox->IsFormulaOrValueBox();
951     switch (nNdPos)
952     {
953         case 0 :                    nRes = table::CellContentType_TEXT; break;
954         case USHRT_MAX :            nRes = table::CellContentType_EMPTY; break;
955         case RES_BOXATR_VALUE :     nRes = table::CellContentType_VALUE; break;
956         case RES_BOXATR_FORMULA :   nRes = table::CellContentType_FORMULA; break;
957         default :
958             DBG_ERROR( "unexpected case" );
959     }
960     return  nRes;
961 }
962 
setString(const OUString & aString)963 void SwXCell::setString(const OUString& aString)
964 {
965     vos::OGuard aGuard(Application::GetSolarMutex());
966     lcl_setString( *this, aString );
967 }
968 
969 
getError(void)970 sal_Int32 SwXCell::getError(void)
971 {
972     vos::OGuard aGuard(Application::GetSolarMutex());
973     OUString sContent = getString();
974     return sContent.equals(ViewShell::GetShellRes()->aCalc_Error);
975 }
976 
createTextCursor(void)977 uno::Reference< text::XTextCursor >  SwXCell::createTextCursor(void)
978 {
979     vos::OGuard aGuard(Application::GetSolarMutex());
980     uno::Reference< text::XTextCursor >     aRef;
981     if(pStartNode || IsValid())
982     {
983         const SwStartNode* pSttNd = pStartNode ? pStartNode : pBox->GetSttNd();
984         SwPosition aPos(*pSttNd);
985         SwXTextCursor *const pXCursor =
986             new SwXTextCursor(*GetDoc(), this, CURSOR_TBLTEXT, aPos);
987         SwUnoCrsr *const pUnoCrsr = pXCursor->GetCursor();
988         pUnoCrsr->Move(fnMoveForward, fnGoNode);
989         aRef =  static_cast<text::XWordCursor*>(pXCursor);
990 //      // no Cursor in protected sections
991 //      SwCrsrSaveState aSave( *pUnoCrsr );
992 //      if(pUnoCrsr->IsInProtectTable( sal_True ) ||
993 //          pUnoCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ))
994 //          throw( uno::RuntimeException() );
995     }
996     else
997         throw uno::RuntimeException();
998     return aRef;
999 }
1000 
createTextCursorByRange(const uno::Reference<text::XTextRange> & xTextPosition)1001 uno::Reference< text::XTextCursor >  SwXCell::createTextCursorByRange(const uno::Reference< text::XTextRange > & xTextPosition)
1002 {
1003     vos::OGuard aGuard(Application::GetSolarMutex());
1004     uno::Reference< text::XTextCursor >  aRef;
1005     SwUnoInternalPaM aPam(*GetDoc());
1006     if ((pStartNode || IsValid())
1007         && ::sw::XTextRangeToSwPaM(aPam, xTextPosition))
1008     {
1009         const SwStartNode* pSttNd = pStartNode ? pStartNode : pBox->GetSttNd();
1010         //skip sections
1011         SwStartNode* p1 = aPam.GetNode()->StartOfSectionNode();
1012         while(p1->IsSectionNode())
1013             p1 = p1->StartOfSectionNode();
1014 
1015         if( p1 == pSttNd )
1016         {
1017             aRef = static_cast<text::XWordCursor*>(
1018                     new SwXTextCursor(*GetDoc(), this, CURSOR_TBLTEXT,
1019                         *aPam.GetPoint(), aPam.GetMark()));
1020         }
1021     }
1022     else
1023         throw uno::RuntimeException();
1024     return aRef;
1025 }
1026 
getPropertySetInfo(void)1027 uno::Reference< beans::XPropertySetInfo >  SwXCell::getPropertySetInfo(void)
1028 {
1029     static uno::Reference< beans::XPropertySetInfo >  xRef = m_pPropSet->getPropertySetInfo();
1030     return xRef;
1031 }
1032 
setPropertyValue(const OUString & rPropertyName,const uno::Any & aValue)1033 void SwXCell::setPropertyValue(const OUString& rPropertyName, const uno::Any& aValue)
1034 {
1035     vos::OGuard aGuard(Application::GetSolarMutex());
1036     if(IsValid())
1037     {
1038         const SfxItemPropertySimpleEntry* pEntry =
1039             m_pPropSet->getPropertyMap()->getByName(rPropertyName);
1040         if( !pEntry )
1041         {
1042             beans::UnknownPropertyException aEx;
1043             aEx.Message = rPropertyName;
1044             throw( aEx );
1045         }
1046         if( pEntry->nWID == FN_UNO_CELL_ROW_SPAN )
1047         {
1048             sal_Int32 nRowSpan = 0;
1049             if( aValue >>= nRowSpan )
1050                 pBox->setRowSpan( nRowSpan );
1051         }
1052         else
1053         {
1054             SwFrmFmt* pBoxFmt = pBox->ClaimFrmFmt();
1055             SwAttrSet aSet(pBoxFmt->GetAttrSet());
1056             m_pPropSet->setPropertyValue(rPropertyName, aValue, aSet);
1057             pBoxFmt->GetDoc()->SetAttr(aSet, *pBoxFmt);
1058         }
1059     }
1060 }
1061 
getPropertyValue(const OUString & rPropertyName)1062 uno::Any SwXCell::getPropertyValue(const OUString& rPropertyName)
1063 {
1064     vos::OGuard aGuard(Application::GetSolarMutex());
1065     uno::Any aRet;
1066     if(IsValid())
1067     {
1068         const SfxItemPropertySimpleEntry* pEntry =
1069                                     m_pPropSet->getPropertyMap()->getByName(rPropertyName);
1070         if( !pEntry )
1071         {
1072             beans::UnknownPropertyException aEx;
1073             aEx.Message = rPropertyName;
1074             throw( aEx );
1075         }
1076         switch( pEntry->nWID )
1077         {
1078             case FN_UNO_CELL_ROW_SPAN:
1079                 aRet <<= pBox->getRowSpan();
1080             break;
1081             case FN_UNO_TEXT_SECTION:
1082             {
1083                 SwFrmFmt* pTblFmt = GetFrmFmt();
1084                 SwTable* pTable = SwTable::FindTable( pTblFmt );
1085                 SwTableNode* pTblNode = pTable->GetTableNode();
1086                 SwSectionNode* pSectionNode =  pTblNode->FindSectionNode();
1087                 if(pSectionNode)
1088                 {
1089                     const SwSection& rSect = pSectionNode->GetSection();
1090                     uno::Reference< text::XTextSection >  xSect =
1091                                     SwXTextSections::GetObject( *rSect.GetFmt() );
1092                     aRet <<= xSect;
1093                 }
1094             }
1095             break;
1096             case FN_UNO_CELL_NAME:
1097                 aRet <<= OUString ( pBox->GetName() );
1098             break;
1099             case FN_UNO_REDLINE_NODE_START:
1100             case FN_UNO_REDLINE_NODE_END:
1101             {
1102                 //redline can only be returned if it's a living object
1103                 aRet = SwXText::getPropertyValue(rPropertyName);
1104             }
1105             break;
1106             default:
1107             {
1108                 const SwFrmFmt* pBoxFmt = pBox->GetFrmFmt();
1109                 const SwAttrSet& rSet = pBoxFmt->GetAttrSet();
1110                 m_pPropSet->getPropertyValue(rPropertyName, rSet, aRet);
1111             }
1112         }
1113     }
1114     return aRet;
1115 }
1116 
addPropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1117 void SwXCell::addPropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
1118 {
1119     DBG_WARNING("not implemented");
1120 }
1121 
removePropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1122 void SwXCell::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
1123 {
1124     DBG_WARNING("not implemented");
1125 }
1126 
addVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1127 void SwXCell::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
1128 {
1129     DBG_WARNING("not implemented");
1130 }
1131 
removeVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1132 void SwXCell::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
1133 {
1134     DBG_WARNING("not implemented");
1135 }
1136 
createEnumeration(void)1137 uno::Reference< container::XEnumeration >  SwXCell::createEnumeration(void)
1138 {
1139     vos::OGuard aGuard(Application::GetSolarMutex());
1140     uno::Reference< container::XEnumeration >  aRef;
1141     if(IsValid())
1142     {
1143         const SwStartNode* pSttNd = pBox->GetSttNd();
1144         SwPosition aPos(*pSttNd);
1145         ::std::auto_ptr<SwUnoCrsr> pUnoCursor(
1146             GetDoc()->CreateUnoCrsr(aPos, sal_False));
1147         pUnoCursor->Move(fnMoveForward, fnGoNode);
1148 
1149         // remember table and start node for later travelling
1150         // (used in export of tables in tables)
1151         SwTable const*const pTable( & pSttNd->FindTableNode()->GetTable() );
1152         SwXParagraphEnumeration *const pEnum =
1153             new SwXParagraphEnumeration(this, pUnoCursor, CURSOR_TBLTEXT,
1154                     pSttNd, pTable);
1155 
1156         aRef = pEnum;
1157 //      // no Cursor in protected sections
1158 //      SwCrsrSaveState aSave( *pUnoCrsr );
1159 //      if(pUnoCrsr->IsInProtectTable( sal_True ) ||
1160 //          pUnoCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ))
1161 //          throw( uno::RuntimeException() );
1162     }
1163     return aRef;
1164 }
1165 
getElementType(void)1166 uno::Type SAL_CALL SwXCell::getElementType(void)
1167 {
1168     return ::getCppuType((const uno::Reference<text::XTextRange>*)0);
1169 
1170 }
1171 
hasElements(void)1172 sal_Bool SwXCell::hasElements(void)
1173 {
1174     return sal_True;
1175 }
1176 
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)1177 void SwXCell::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
1178 {
1179     ClientModify(this, pOld, pNew);
1180 }
1181 
CreateXCell(SwFrmFmt * pTblFmt,SwTableBox * pBox,SwTable * pTable)1182 SwXCell* SwXCell::CreateXCell(SwFrmFmt* pTblFmt, SwTableBox* pBox, SwTable *pTable )
1183 {
1184     SwXCell* pRet = 0;
1185     if(pTblFmt && pBox)
1186     {
1187         if( !pTable )
1188             pTable = SwTable::FindTable( pTblFmt );
1189         sal_uInt16 nPos = USHRT_MAX;
1190         SwTableBox* pFoundBox =
1191             pTable->GetTabSortBoxes().Seek_Entry( pBox, &nPos ) ? pBox : NULL;
1192 
1193         //wenn es die Box gibt, dann wird auch eine Zelle zurueckgegeben
1194         if(pFoundBox)
1195         {
1196             SwIterator<SwXCell,SwFmt> aIter( *pTblFmt );
1197             SwXCell* pXCell = aIter.First();
1198             while( pXCell )
1199             {
1200                 // gibt es eine passende Zelle bereits?
1201                 if(pXCell->GetTblBox() == pBox)
1202                     break;
1203                 pXCell = aIter.Next();
1204             }
1205             //sonst anlegen
1206             if(!pXCell)
1207                 pXCell = new SwXCell(pTblFmt, pBox, nPos );
1208             pRet = pXCell;
1209         }
1210     }
1211     return pRet;
1212 }
1213 /* does box exist in given table? */
FindBox(SwTable * pTable,SwTableBox * pBox2)1214 SwTableBox* SwXCell::FindBox(SwTable* pTable, SwTableBox* pBox2)
1215 {
1216     // check if nFndPos happens to point to the right table box
1217     if( nFndPos < pTable->GetTabSortBoxes().Count() &&
1218         pBox2 == pTable->GetTabSortBoxes()[ nFndPos ] )
1219         return pBox2;
1220 
1221     // if not, seek the entry (and return, if successful)
1222     if( pTable->GetTabSortBoxes().Seek_Entry( pBox2, &nFndPos ))
1223         return pBox2;
1224 
1225     // box not found: reset nFndPos pointer
1226     nFndPos = USHRT_MAX;
1227     return 0;
1228 }
1229 
getImplementationName(void)1230 OUString SwXCell::getImplementationName(void)
1231 {
1232     return C2U("SwXCell");
1233 }
1234 
supportsService(const OUString & rServiceName)1235 sal_Bool SwXCell::supportsService(const OUString& rServiceName)
1236 {
1237     String sServiceName(rServiceName);
1238     return sServiceName.EqualsAscii("com.sun.star.text.CellProperties");
1239 }
1240 
getSupportedServiceNames(void)1241 uno::Sequence< OUString > SwXCell::getSupportedServiceNames(void)
1242 {
1243     uno::Sequence< OUString > aRet(1);
1244     OUString* pArray = aRet.getArray();
1245     pArray[0] = C2U("com.sun.star.text.CellProperties");
1246     return aRet;
1247 }
1248 
1249 /******************************************************************
1250  * SwXTextTableRow
1251  ******************************************************************/
1252 
getImplementationName(void)1253 OUString SwXTextTableRow::getImplementationName(void)
1254 {
1255     return C2U("SwXTextTableRow");
1256 }
1257 
supportsService(const OUString & rServiceName)1258 sal_Bool SwXTextTableRow::supportsService(const OUString& rServiceName)
1259 {
1260     return C2U("com.sun.star.text.TextTableRow") == rServiceName;
1261 }
1262 
getSupportedServiceNames(void)1263 uno::Sequence< OUString > SwXTextTableRow::getSupportedServiceNames(void)
1264 {
1265     uno::Sequence< OUString > aRet(1);
1266     OUString* pArray = aRet.getArray();
1267     pArray[0] = C2U("com.sun.star.text.TextTableRow");
1268     return aRet;
1269 }
1270 TYPEINIT1(SwXTextTableRow, SwClient);
1271 
SwXTextTableRow(SwFrmFmt * pFmt,SwTableLine * pLn)1272 SwXTextTableRow::SwXTextTableRow(SwFrmFmt* pFmt, SwTableLine* pLn) :
1273     SwClient(pFmt),
1274     m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_TABLE_ROW)),
1275     pLine(pLn)
1276 {
1277 
1278 }
1279 
~SwXTextTableRow()1280 SwXTextTableRow::~SwXTextTableRow()
1281 {
1282 
1283 }
1284 
getPropertySetInfo(void)1285 uno::Reference< beans::XPropertySetInfo >  SwXTextTableRow::getPropertySetInfo(void)
1286 {
1287     static uno::Reference< beans::XPropertySetInfo >  xRef = m_pPropSet->getPropertySetInfo();
1288     return xRef;
1289 }
1290 
setPropertyValue(const OUString & rPropertyName,const uno::Any & aValue)1291 void SwXTextTableRow::setPropertyValue(const OUString& rPropertyName,
1292     const uno::Any& aValue)
1293 {
1294     vos::OGuard aGuard(Application::GetSolarMutex());
1295     SwFrmFmt* pFmt = GetFrmFmt();
1296     if(pFmt)
1297     {
1298         SwTable* pTable = SwTable::FindTable( pFmt );
1299         SwTableLine* pLn = SwXTextTableRow::FindLine(pTable, pLine);
1300         if(pLn)
1301         {
1302             const SfxItemPropertySimpleEntry* pEntry =
1303                 m_pPropSet->getPropertyMap()->getByName(rPropertyName);
1304             SwDoc* pDoc = pFmt->GetDoc();
1305             if (!pEntry)
1306                 throw beans::UnknownPropertyException(OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Unknown property: " ) ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
1307             if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
1308                 throw beans::PropertyVetoException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property is read-only: " ) ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
1309 
1310             switch(pEntry->nWID)
1311             {
1312                 case FN_UNO_ROW_HEIGHT:
1313                 case FN_UNO_ROW_AUTO_HEIGHT:
1314                 {
1315                     SwFmtFrmSize aFrmSize(pLn->GetFrmFmt()->GetFrmSize());
1316                     if(FN_UNO_ROW_AUTO_HEIGHT== pEntry->nWID)
1317                     {
1318                         sal_Bool bSet = *(sal_Bool*)aValue.getValue();
1319                         aFrmSize.SetHeightSizeType(bSet ? ATT_VAR_SIZE : ATT_FIX_SIZE);
1320                     }
1321                     else
1322                     {
1323                         sal_Int32 nHeight = 0;
1324                         aValue >>= nHeight;
1325                         Size aSz(aFrmSize.GetSize());
1326                         aSz.Height() = MM100_TO_TWIP(nHeight);
1327                         aFrmSize.SetSize(aSz);
1328                     }
1329                     pDoc->SetAttr(aFrmSize, *pLn->ClaimFrmFmt());
1330                 }
1331                 break;
1332                 case FN_UNO_TABLE_COLUMN_SEPARATORS:
1333                 {
1334                     UnoActionContext aContext(pDoc);
1335                     SwTable* pTable2 = SwTable::FindTable( pFmt );
1336                     lcl_SetTblSeparators(aValue, pTable2, pLine->GetTabBoxes()[0], sal_True, pDoc);
1337                 }
1338                 break;
1339                 default:
1340                 {
1341                     SwFrmFmt* pLnFmt = pLn->ClaimFrmFmt();
1342                     SwAttrSet aSet(pLnFmt->GetAttrSet());
1343                     m_pPropSet->setPropertyValue(*pEntry, aValue, aSet);
1344                     pDoc->SetAttr(aSet, *pLnFmt);
1345                 }
1346             }
1347         }
1348     }
1349 }
1350 
getPropertyValue(const OUString & rPropertyName)1351 uno::Any SwXTextTableRow::getPropertyValue(const OUString& rPropertyName)
1352 {
1353     vos::OGuard aGuard(Application::GetSolarMutex());
1354     uno::Any aRet;
1355     SwFrmFmt* pFmt = GetFrmFmt();
1356     if(pFmt)
1357     {
1358         SwTable* pTable = SwTable::FindTable( pFmt );
1359         SwTableLine* pLn = SwXTextTableRow::FindLine(pTable, pLine);
1360         if(pLn)
1361         {
1362             const SfxItemPropertySimpleEntry* pEntry =
1363                                     m_pPropSet->getPropertyMap()->getByName(rPropertyName);
1364             if (!pEntry)
1365                 throw beans::UnknownPropertyException(OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Unknown property: " ) ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
1366 
1367             switch(pEntry->nWID)
1368             {
1369                 case FN_UNO_ROW_HEIGHT:
1370                 case FN_UNO_ROW_AUTO_HEIGHT:
1371                 {
1372                     const SwFmtFrmSize& rSize = pLn->GetFrmFmt()->GetFrmSize();
1373                     if(FN_UNO_ROW_AUTO_HEIGHT== pEntry->nWID)
1374                     {
1375                         sal_Bool bTmp =  ATT_VAR_SIZE == rSize.GetHeightSizeType();
1376                         aRet.setValue(&bTmp, ::getCppuBooleanType());
1377                     }
1378                     else
1379                         aRet <<= (sal_Int32)(TWIP_TO_MM100(rSize.GetSize().Height()));
1380                 }
1381                 break;
1382                 case FN_UNO_TABLE_COLUMN_SEPARATORS:
1383                 {
1384                     lcl_GetTblSeparators(aRet, pTable, pLine->GetTabBoxes()[0], sal_True);
1385                 }
1386                 break;
1387                 default:
1388                 {
1389                     const SwAttrSet& rSet = pLn->GetFrmFmt()->GetAttrSet();
1390                     m_pPropSet->getPropertyValue(*pEntry, rSet, aRet);
1391                 }
1392             }
1393         }
1394     }
1395     return aRet;
1396 }
1397 
addPropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1398 void SwXTextTableRow::addPropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
1399 {
1400     DBG_WARNING("not implemented");
1401 }
1402 
removePropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1403 void SwXTextTableRow::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
1404 {
1405     DBG_WARNING("not implemented");
1406 }
1407 
addVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1408 void SwXTextTableRow::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
1409 {
1410     DBG_WARNING("not implemented");
1411 }
1412 
removeVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1413 void SwXTextTableRow::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
1414 {
1415     DBG_WARNING("not implemented");
1416 }
1417 
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)1418 void SwXTextTableRow::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
1419 {
1420     ClientModify(this, pOld, pNew);
1421 }
1422 
FindLine(SwTable * pTable,SwTableLine * pLine)1423 SwTableLine* SwXTextTableRow::FindLine(SwTable* pTable, SwTableLine* pLine)
1424 {
1425     SwTableLine* pRet = 0;
1426     SwTableLines &rLines = pTable->GetTabLines();
1427     for(sal_uInt16 i = 0; i < rLines.Count(); i++)
1428         if(rLines.GetObject(i) == pLine)
1429         {
1430             pRet = pLine;
1431             break;
1432         }
1433     return pRet;
1434 }
1435 
1436 /******************************************************************
1437  * SwXTextTableCursor
1438  ******************************************************************/
1439 
getImplementationName(void)1440 OUString SwXTextTableCursor::getImplementationName(void)
1441 {
1442     return C2U("SwXTextTableCursor");
1443 }
1444 
supportsService(const OUString & rServiceName)1445 sal_Bool SwXTextTableCursor::supportsService(const OUString& rServiceName)
1446 {
1447     return C2U("com.sun.star.text.TextTableCursor") == rServiceName;
1448 }
1449 // -----------------------------------------------------------------------------
IMPLEMENT_FORWARD_XINTERFACE2(SwXTextTableCursor,SwXTextTableCursor_Base,OTextCursorHelper) const1450 IMPLEMENT_FORWARD_XINTERFACE2(SwXTextTableCursor,SwXTextTableCursor_Base,OTextCursorHelper)
1451 const SwPaM*        SwXTextTableCursor::GetPaM() const  { return GetCrsr(); }
GetPaM()1452 SwPaM*              SwXTextTableCursor::GetPaM()        { return GetCrsr(); }
GetDoc() const1453 const SwDoc*        SwXTextTableCursor::GetDoc() const  { return GetFrmFmt()->GetDoc(); }
GetDoc()1454 SwDoc*              SwXTextTableCursor::GetDoc()        { return GetFrmFmt()->GetDoc(); }
GetCrsr() const1455 const SwUnoCrsr*    SwXTextTableCursor::GetCrsr() const { return (SwUnoCrsr*)aCrsrDepend.GetRegisteredIn(); }
GetCrsr()1456 SwUnoCrsr*          SwXTextTableCursor::GetCrsr()       { return (SwUnoCrsr*)aCrsrDepend.GetRegisteredIn(); }
1457 
getSupportedServiceNames(void)1458 uno::Sequence< OUString > SwXTextTableCursor::getSupportedServiceNames(void)
1459 {
1460     uno::Sequence< OUString > aRet(1);
1461     OUString* pArray = aRet.getArray();
1462     pArray[0] = C2U("com.sun.star.text.TextTableCursor");
1463     return aRet;
1464 }
1465 
SwXTextTableCursor(SwFrmFmt * pFmt,SwTableBox * pBox)1466 SwXTextTableCursor::SwXTextTableCursor(SwFrmFmt* pFmt, SwTableBox* pBox) :
1467     SwClient(pFmt),
1468     aCrsrDepend(this, 0),
1469     m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_TABLE_CURSOR))
1470 {
1471     SwDoc* pDoc = pFmt->GetDoc();
1472     const SwStartNode* pSttNd = pBox->GetSttNd();
1473     SwPosition aPos(*pSttNd);
1474     SwUnoCrsr* pUnoCrsr = pDoc->CreateUnoCrsr(aPos, sal_True);
1475     pUnoCrsr->Move( fnMoveForward, fnGoNode );
1476     pUnoCrsr->Add(&aCrsrDepend);
1477     SwUnoTableCrsr* pTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
1478     pTblCrsr->MakeBoxSels();
1479 }
1480 
SwXTextTableCursor(SwFrmFmt & rTableFmt,const SwTableCursor * pTableSelection)1481 SwXTextTableCursor::SwXTextTableCursor(SwFrmFmt& rTableFmt, const SwTableCursor* pTableSelection) :
1482     SwClient(&rTableFmt),
1483     aCrsrDepend(this, 0),
1484     m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_TABLE_CURSOR))
1485 {
1486     SwUnoCrsr* pUnoCrsr = pTableSelection->GetDoc()->CreateUnoCrsr(*pTableSelection->GetPoint(), sal_True);
1487     if(pTableSelection->HasMark())
1488     {
1489         pUnoCrsr->SetMark();
1490         *pUnoCrsr->GetMark() = *pTableSelection->GetMark();
1491     }
1492     const SwSelBoxes& rBoxes = pTableSelection->GetBoxes();
1493     SwTableCursor* pTableCrsr = dynamic_cast<SwTableCursor*>(pUnoCrsr);
1494     for(sal_uInt16 i = 0; i < rBoxes.Count(); i++)
1495         pTableCrsr->InsertBox( *rBoxes.GetObject(i) );
1496 
1497     pUnoCrsr->Add(&aCrsrDepend);
1498     SwUnoTableCrsr* pTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
1499     pTblCrsr->MakeBoxSels();
1500 }
1501 
~SwXTextTableCursor()1502 SwXTextTableCursor::~SwXTextTableCursor()
1503 {
1504     vos::OGuard aGuard(Application::GetSolarMutex());
1505     SwUnoCrsr* pUnoCrsr = GetCrsr();
1506     if(pUnoCrsr)
1507         delete pUnoCrsr;
1508 }
1509 
getRangeName(void)1510 OUString SwXTextTableCursor::getRangeName(void)
1511 {
1512     vos::OGuard aGuard(Application::GetSolarMutex());
1513     OUString aRet;
1514     SwUnoCrsr* pUnoCrsr = GetCrsr();
1515 
1516     //!! see also SwChartDataSequence::getSourceRangeRepresentation
1517     if(pUnoCrsr)
1518     {
1519         SwUnoTableCrsr* pTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
1520         pTblCrsr->MakeBoxSels();
1521         const SwStartNode* pNode = pTblCrsr->GetPoint()->nNode.GetNode().FindTableBoxStartNode();
1522         const SwTable* pTable = SwTable::FindTable( GetFrmFmt() );
1523         const SwTableBox* pEndBox = pTable->GetTblBox( pNode->GetIndex());
1524         String aTmp( pEndBox->GetName() );
1525 
1526         if(pTblCrsr->HasMark())
1527         {
1528             pNode = pTblCrsr->GetMark()->nNode.GetNode().FindTableBoxStartNode();
1529             const SwTableBox* pStartBox = pTable->GetTblBox( pNode->GetIndex());
1530             if(pEndBox != pStartBox)
1531             {
1532                 // need to switch start and end?
1533                 if (*pTblCrsr->GetPoint() < *pTblCrsr->GetMark())
1534                 {
1535                     const SwTableBox* pTmpBox = pStartBox;
1536                     pStartBox = pEndBox;
1537                     pEndBox = pTmpBox;
1538                 }
1539 
1540                 aTmp  = pStartBox->GetName();
1541                 aTmp += ':';
1542                 aTmp += pEndBox->GetName();
1543             }
1544         }
1545         aRet = aTmp;
1546     }
1547     return aRet;
1548 }
1549 
gotoCellByName(const OUString & CellName,sal_Bool Expand)1550 sal_Bool SwXTextTableCursor::gotoCellByName(const OUString& CellName, sal_Bool Expand)
1551 {
1552     vos::OGuard aGuard(Application::GetSolarMutex());
1553     sal_Bool bRet = sal_False;
1554     SwUnoCrsr* pUnoCrsr = GetCrsr();
1555     if(pUnoCrsr)
1556     {
1557         SwUnoTableCrsr* pTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
1558         lcl_CrsrSelect( pTblCrsr, Expand );
1559         String sCellName(CellName);
1560         bRet = pTblCrsr->GotoTblBox(sCellName);
1561     }
1562     return bRet;
1563 }
1564 
goLeft(sal_Int16 Count,sal_Bool Expand)1565 sal_Bool SwXTextTableCursor::goLeft(sal_Int16 Count, sal_Bool Expand)
1566 {
1567     vos::OGuard aGuard(Application::GetSolarMutex());
1568     sal_Bool bRet = sal_False;
1569     SwUnoCrsr* pUnoCrsr = GetCrsr();
1570     if(pUnoCrsr)
1571     {
1572         SwUnoTableCrsr* pTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
1573         lcl_CrsrSelect( pTblCrsr, Expand );
1574         bRet = pTblCrsr->Left( Count,CRSR_SKIP_CHARS, sal_False, sal_False);
1575     }
1576     return bRet;
1577 }
1578 
goRight(sal_Int16 Count,sal_Bool Expand)1579 sal_Bool SwXTextTableCursor::goRight(sal_Int16 Count, sal_Bool Expand)
1580 {
1581     vos::OGuard aGuard(Application::GetSolarMutex());
1582     sal_Bool bRet = sal_False;
1583     SwUnoCrsr* pUnoCrsr = GetCrsr();
1584     if(pUnoCrsr)
1585     {
1586         SwUnoTableCrsr* pTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
1587         lcl_CrsrSelect( pTblCrsr, Expand );
1588         bRet = pTblCrsr->Right( Count, CRSR_SKIP_CHARS, sal_False, sal_False);
1589     }
1590     return bRet;
1591 }
1592 
goUp(sal_Int16 Count,sal_Bool Expand)1593 sal_Bool SwXTextTableCursor::goUp(sal_Int16 Count, sal_Bool Expand)
1594 {
1595     vos::OGuard aGuard(Application::GetSolarMutex());
1596     sal_Bool bRet = sal_False;
1597     SwUnoCrsr* pUnoCrsr = GetCrsr();
1598     if(pUnoCrsr)
1599     {
1600         SwUnoTableCrsr* pTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
1601         lcl_CrsrSelect( pTblCrsr, Expand );
1602         bRet = pTblCrsr->UpDown(sal_True, Count, 0, 0);
1603     }
1604     return bRet;
1605 }
1606 
goDown(sal_Int16 Count,sal_Bool Expand)1607 sal_Bool SwXTextTableCursor::goDown(sal_Int16 Count, sal_Bool Expand)
1608 {
1609     vos::OGuard aGuard(Application::GetSolarMutex());
1610     sal_Bool bRet = sal_False;
1611     SwUnoCrsr* pUnoCrsr = GetCrsr();
1612     if(pUnoCrsr)
1613     {
1614         SwUnoTableCrsr* pTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
1615         lcl_CrsrSelect( pTblCrsr, Expand );
1616         bRet = pTblCrsr->UpDown(sal_False, Count, 0, 0);
1617     }
1618     return bRet;
1619 }
1620 
gotoStart(sal_Bool Expand)1621 void SwXTextTableCursor::gotoStart(sal_Bool Expand)
1622 {
1623     vos::OGuard aGuard(Application::GetSolarMutex());
1624     SwUnoCrsr* pUnoCrsr = GetCrsr();
1625     if(pUnoCrsr)
1626     {
1627         SwUnoTableCrsr* pTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
1628         lcl_CrsrSelect( pTblCrsr, Expand );
1629         pTblCrsr->MoveTable(fnTableCurr, fnTableStart);
1630     }
1631 }
1632 
gotoEnd(sal_Bool Expand)1633 void SwXTextTableCursor::gotoEnd(sal_Bool Expand)
1634 {
1635     vos::OGuard aGuard(Application::GetSolarMutex());
1636     SwUnoCrsr* pUnoCrsr = GetCrsr();
1637     if(pUnoCrsr)
1638     {
1639         SwUnoTableCrsr* pTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
1640         lcl_CrsrSelect( pTblCrsr, Expand );
1641         pTblCrsr->MoveTable(fnTableCurr, fnTableEnd);
1642     }
1643 }
1644 
mergeRange(void)1645 sal_Bool SwXTextTableCursor::mergeRange(void)
1646 {
1647     vos::OGuard aGuard(Application::GetSolarMutex());
1648     sal_Bool bRet = sal_False;
1649     SwUnoCrsr* pUnoCrsr = GetCrsr();
1650     if(pUnoCrsr)
1651     {
1652         {
1653             // hier muessen die Actions aufgehoben werden
1654             UnoActionRemoveContext aRemoveContext(pUnoCrsr->GetDoc());
1655         }
1656         SwUnoTableCrsr* pTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
1657         pTblCrsr->MakeBoxSels();
1658 
1659         {
1660             UnoActionContext aContext(pUnoCrsr->GetDoc());
1661             bRet = TBLMERGE_OK == pTblCrsr->GetDoc()->MergeTbl(*pTblCrsr);
1662             if(bRet)
1663             {
1664                 sal_uInt16 nCount = pTblCrsr->GetBoxesCount();
1665                 while(nCount--)
1666                     pTblCrsr->DeleteBox(nCount);
1667             }
1668         }
1669         pTblCrsr->MakeBoxSels();
1670     }
1671     return bRet;
1672 }
1673 
splitRange(sal_Int16 Count,sal_Bool Horizontal)1674 sal_Bool SwXTextTableCursor::splitRange(sal_Int16 Count, sal_Bool Horizontal)
1675 {
1676     vos::OGuard aGuard(Application::GetSolarMutex());
1677     if (Count <= 0)
1678         throw uno::RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( "Illegal first argument: needs to be > 0" ) ), static_cast < cppu::OWeakObject * > ( this ) );
1679     sal_Bool bRet = sal_False;
1680     SwUnoCrsr* pUnoCrsr = GetCrsr();
1681     if(pUnoCrsr)
1682     {
1683         {
1684             // hier muessen die Actions aufgehoben werden
1685             UnoActionRemoveContext aRemoveContext(pUnoCrsr->GetDoc());
1686         }
1687         SwUnoTableCrsr* pTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
1688         pTblCrsr->MakeBoxSels();
1689         {
1690             UnoActionContext aContext(pUnoCrsr->GetDoc());
1691             bRet = pTblCrsr->GetDoc()->SplitTbl( pTblCrsr->GetBoxes(), !Horizontal, Count );
1692         }
1693         pTblCrsr->MakeBoxSels();
1694     }
1695     return bRet;
1696 }
1697 
getPropertySetInfo(void)1698 uno::Reference< beans::XPropertySetInfo >  SwXTextTableCursor::getPropertySetInfo(void)
1699 {
1700     static uno::Reference< beans::XPropertySetInfo >  xRef = m_pPropSet->getPropertySetInfo();
1701     return xRef;
1702 }
1703 
setPropertyValue(const OUString & rPropertyName,const uno::Any & aValue)1704 void SwXTextTableCursor::setPropertyValue(const OUString& rPropertyName,
1705                                                         const uno::Any& aValue)
1706 {
1707     vos::OGuard aGuard(Application::GetSolarMutex());
1708     SwUnoCrsr* pUnoCrsr = GetCrsr();
1709     if(pUnoCrsr)
1710     {
1711         SwStartNode* pSttNode = pUnoCrsr->GetNode()->StartOfSectionNode();
1712         const SwTableNode* pTblNode = pSttNode->FindTableNode();
1713         lcl_FormatTable((SwFrmFmt*)pTblNode->GetTable().GetFrmFmt());
1714         SwUnoTableCrsr* pTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
1715         const SfxItemPropertySimpleEntry* pEntry =
1716                                     m_pPropSet->getPropertyMap()->getByName(rPropertyName);
1717         if(pEntry)
1718         {
1719             if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
1720                 throw beans::PropertyVetoException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property is read-only: " ) ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
1721             pTblCrsr->MakeBoxSels();
1722             SwDoc* pDoc = pUnoCrsr->GetDoc();
1723             switch(pEntry->nWID )
1724             {
1725                 case FN_UNO_TABLE_CELL_BACKGROUND:
1726                 {
1727                     SvxBrushItem aBrush( RES_BACKGROUND );
1728                     pDoc->GetBoxAttr( *pUnoCrsr, aBrush );
1729                     aBrush.PutValue(aValue, pEntry->nMemberId);
1730                     pDoc->SetBoxAttr( *pUnoCrsr, aBrush );
1731 
1732                 }
1733                 break;
1734                 case RES_BOXATR_FORMAT:
1735                 {
1736                     SfxUInt32Item aNumberFormat(RES_BOXATR_FORMAT);
1737                     aNumberFormat.PutValue(aValue, 0);
1738                     pDoc->SetBoxAttr( *pUnoCrsr, aNumberFormat);
1739                 }
1740                 break;
1741                 case FN_UNO_PARA_STYLE:
1742                     SwUnoCursorHelper::SetTxtFmtColl(aValue, *pUnoCrsr);
1743                 break;
1744                 default:
1745                 {
1746                     SfxItemSet aItemSet( pDoc->GetAttrPool(), pEntry->nWID, pEntry->nWID );
1747                     SwUnoCursorHelper::GetCrsrAttr(pTblCrsr->GetSelRing(),
1748                             aItemSet);
1749 
1750                     if (!SwUnoCursorHelper::SetCursorPropertyValue(
1751                             *pEntry, aValue, pTblCrsr->GetSelRing(), aItemSet))
1752                     {
1753                         m_pPropSet->setPropertyValue(*pEntry, aValue, aItemSet);
1754                     }
1755                     SwUnoCursorHelper::SetCrsrAttr(pTblCrsr->GetSelRing(),
1756                             aItemSet, nsSetAttrMode::SETATTR_DEFAULT, true);
1757                 }
1758             }
1759         }
1760         else
1761             throw beans::UnknownPropertyException(OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Unknown property: " ) ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
1762     }
1763 }
1764 
getPropertyValue(const OUString & rPropertyName)1765 uno::Any SwXTextTableCursor::getPropertyValue(const OUString& rPropertyName)
1766 {
1767     vos::OGuard aGuard(Application::GetSolarMutex());
1768     uno::Any aRet;
1769     SwUnoCrsr* pUnoCrsr = GetCrsr();
1770     if(pUnoCrsr)
1771     {
1772         SwStartNode* pSttNode = pUnoCrsr->GetNode()->StartOfSectionNode();
1773         const SwTableNode* pTblNode = pSttNode->FindTableNode();
1774         lcl_FormatTable((SwFrmFmt*)pTblNode->GetTable().GetFrmFmt());
1775         SwUnoTableCrsr* pTblCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
1776         const SfxItemPropertySimpleEntry* pEntry =
1777                                     m_pPropSet->getPropertyMap()->getByName(rPropertyName);
1778         if(pEntry)
1779         {
1780             pTblCrsr->MakeBoxSels();
1781             switch(pEntry->nWID )
1782             {
1783                 case FN_UNO_TABLE_CELL_BACKGROUND:
1784                 {
1785                     SvxBrushItem aBrush( RES_BACKGROUND );
1786                     if(pTblCrsr->GetDoc()->GetBoxAttr( *pUnoCrsr, aBrush ))
1787                         aBrush.QueryValue(aRet, pEntry->nMemberId);
1788 
1789                 }
1790                 break;
1791                 case RES_BOXATR_FORMAT:
1792                     //GetAttr fuer Tabellenselektion am Doc fehlt noch
1793                     DBG_WARNING("not implemented");
1794                 break;
1795                 case FN_UNO_PARA_STYLE:
1796                 {
1797                     SwFmtColl *const pFmt =
1798                         SwUnoCursorHelper::GetCurTxtFmtColl(*pUnoCrsr, sal_False);
1799                     OUString sRet;
1800                     if(pFmt)
1801                         sRet = pFmt->GetName();
1802                     aRet <<= sRet;
1803                 }
1804                 break;
1805                 default:
1806                 {
1807                     SfxItemSet aSet(pTblCrsr->GetDoc()->GetAttrPool(),
1808                         RES_CHRATR_BEGIN,       RES_FRMATR_END -1,
1809                         RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
1810                         0L);
1811                     // erstmal die Attribute des Cursors
1812                     SwUnoCursorHelper::GetCrsrAttr(pTblCrsr->GetSelRing(),
1813                             aSet);
1814                     m_pPropSet->getPropertyValue(*pEntry, aSet, aRet);
1815                 }
1816             }
1817         }
1818         else
1819             throw beans::UnknownPropertyException(OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Unknown property: " ) ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
1820     }
1821     return aRet;
1822 }
1823 
addPropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1824 void SwXTextTableCursor::addPropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
1825 {
1826     DBG_WARNING("not implemented");
1827 }
1828 
removePropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1829 void SwXTextTableCursor::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
1830 {
1831     DBG_WARNING("not implemented");
1832 }
1833 
addVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1834 void SwXTextTableCursor::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
1835 {
1836     DBG_WARNING("not implemented");
1837 }
1838 
removeVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1839 void SwXTextTableCursor::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
1840 {
1841     DBG_WARNING("not implemented");
1842 }
1843 
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)1844 void SwXTextTableCursor::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
1845 {
1846     ClientModify(this, pOld, pNew);
1847 }
1848 /******************************************************************
1849  * SwXTextTable
1850  ******************************************************************/
1851 /****************************************************************************
1852     Tabellenbeschreibung
1853 ****************************************************************************/
1854 
1855 class SwTableProperties_Impl
1856 {
1857     SwUnoCursorHelper::SwAnyMapHelper aAnyMap;
1858 public:
1859     SwTableProperties_Impl();
1860     ~SwTableProperties_Impl();
1861 
1862     void        SetProperty(sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any& aVal);
1863     sal_Bool    GetProperty(sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any*& rpAny);
1864 
1865     void        ApplyTblAttr(const SwTable& rTbl, SwDoc& rDoc);
1866 };
1867 
1868 
SwTableProperties_Impl()1869 SwTableProperties_Impl::SwTableProperties_Impl()
1870 {
1871 }
1872 
~SwTableProperties_Impl()1873 SwTableProperties_Impl::~SwTableProperties_Impl()
1874 {
1875 }
1876 
SetProperty(sal_uInt16 nWhichId,sal_uInt16 nMemberId,const uno::Any & rVal)1877 void SwTableProperties_Impl::SetProperty(sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any& rVal)
1878 {
1879     aAnyMap.SetValue( nWhichId, nMemberId, rVal );
1880 }
1881 
GetProperty(sal_uInt16 nWhichId,sal_uInt16 nMemberId,const uno::Any * & rpAny)1882 sal_Bool SwTableProperties_Impl::GetProperty(sal_uInt16 nWhichId, sal_uInt16 nMemberId, const uno::Any*& rpAny )
1883 {
1884     return aAnyMap.FillValue( nWhichId, nMemberId, rpAny );
1885 }
1886 
ApplyTblAttr(const SwTable & rTbl,SwDoc & rDoc)1887 void    SwTableProperties_Impl::ApplyTblAttr(const SwTable& rTbl, SwDoc& rDoc)
1888 {
1889     SfxItemSet aSet(rDoc.GetAttrPool(),
1890         RES_LAYOUT_SPLIT,   RES_LAYOUT_SPLIT,
1891         RES_BACKGROUND,     RES_BACKGROUND,
1892         RES_FRM_SIZE,       RES_UL_SPACE,
1893         RES_HORI_ORIENT,    RES_HORI_ORIENT,
1894         RES_BREAK,          RES_BREAK,
1895         RES_KEEP,           RES_KEEP,
1896         RES_SHADOW,         RES_SHADOW,
1897         RES_PAGEDESC,       RES_PAGEDESC,
1898         0
1899         );
1900     const uno::Any* pRepHead;
1901     const SwFrmFmt &rFrmFmt = *rTbl.GetFrmFmt();
1902     if(GetProperty(FN_TABLE_HEADLINE_REPEAT, 0xff, pRepHead ))
1903     {
1904         sal_Bool bVal = *(sal_Bool*)pRepHead->getValue();
1905         ((SwTable&)rTbl).SetRowsToRepeat( bVal ? 1 : 0 );  // TODO MULTIHEADER
1906     }
1907 
1908     const uno::Any* pBackColor   = 0;
1909     GetProperty(RES_BACKGROUND, MID_BACK_COLOR, pBackColor );
1910     const uno::Any* pBackTrans  = 0;
1911     GetProperty(RES_BACKGROUND, MID_GRAPHIC_TRANSPARENT, pBackTrans );
1912     const uno::Any* pGrLoc      = 0;
1913     GetProperty(RES_BACKGROUND, MID_GRAPHIC_POSITION, pGrLoc    );
1914     const uno::Any* pGrURL      = 0;
1915     GetProperty(RES_BACKGROUND, MID_GRAPHIC_URL, pGrURL     );
1916     const uno::Any* pGrFilter   = 0;
1917     GetProperty(RES_BACKGROUND, MID_GRAPHIC_FILTER, pGrFilter     );
1918 
1919     if(pBackColor||pBackTrans||pGrURL||pGrFilter||pGrLoc)
1920     {
1921         SvxBrushItem aBrush ( rFrmFmt.GetBackground() );
1922         if(pBackColor)
1923             aBrush.PutValue(*pBackColor, MID_BACK_COLOR);
1924         if(pBackTrans)
1925             aBrush.PutValue(*pBackTrans, MID_GRAPHIC_TRANSPARENT);
1926         if(pGrURL)
1927             aBrush.PutValue(*pGrURL, MID_GRAPHIC_URL);
1928         if(pGrFilter)
1929             aBrush.PutValue(*pGrFilter, MID_GRAPHIC_FILTER);
1930         if(pGrLoc)
1931             aBrush.PutValue(*pGrLoc, MID_GRAPHIC_POSITION);
1932         aSet.Put(aBrush);
1933     }
1934 
1935     sal_Bool bPutBreak = sal_True;
1936     const uno::Any* pPage;
1937     if(GetProperty(FN_UNO_PAGE_STYLE, 0, pPage) || GetProperty(RES_PAGEDESC, 0xff, pPage))
1938     {
1939         OUString uTmp;
1940         (*pPage) >>= uTmp;
1941         String sPageStyle = uTmp;
1942         if(sPageStyle.Len())
1943         {
1944             SwStyleNameMapper::FillUIName(sPageStyle, sPageStyle, nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC, sal_True );
1945             const SwPageDesc* pDesc = ::GetPageDescByName_Impl(rDoc, sPageStyle);
1946             if(pDesc)
1947             {
1948                 SwFmtPageDesc aDesc( pDesc );
1949                 const uno::Any* pPgNo;
1950                 if(GetProperty(RES_PAGEDESC, MID_PAGEDESC_PAGENUMOFFSET, pPgNo ))
1951                 {
1952                     sal_Int16 nTmp = 0;
1953                     (*pPgNo) >>= nTmp;
1954                     aDesc.SetNumOffset( nTmp );
1955                 }
1956                 aSet.Put(aDesc);
1957                 bPutBreak = sal_False;
1958             }
1959 
1960         }
1961     }
1962     const uno::Any* pBreak;
1963     if(bPutBreak && GetProperty(RES_BREAK, 0, pBreak))
1964     {
1965         SvxFmtBreakItem aBreak ( rFrmFmt.GetBreak() );
1966         aBreak.PutValue(*pBreak, 0);
1967         aSet.Put(aBreak);
1968     }
1969     const uno::Any* pShadow;
1970     if(GetProperty(RES_SHADOW, 0, pShadow))
1971     {
1972         SvxShadowItem aShd ( rFrmFmt.GetShadow() );
1973         aShd.PutValue(*pShadow, CONVERT_TWIPS);
1974         aSet.Put(aShd);
1975     }
1976     const uno::Any* pKeep;
1977     if(GetProperty(RES_KEEP, 0, pKeep))
1978     {
1979         SvxFmtKeepItem aKeep( rFrmFmt.GetKeep() );
1980         aKeep.PutValue(*pKeep, 0);
1981         aSet.Put(aKeep);
1982     }
1983 
1984     sal_Bool bFullAlign = sal_True;
1985     const uno::Any* pHOrient;
1986     if(GetProperty(RES_HORI_ORIENT, MID_HORIORIENT_ORIENT, pHOrient))
1987     {
1988         SwFmtHoriOrient aOrient ( rFrmFmt.GetHoriOrient() );
1989         ((SfxPoolItem&)aOrient).PutValue(*pHOrient, MID_HORIORIENT_ORIENT|CONVERT_TWIPS);
1990         bFullAlign = (aOrient.GetHoriOrient() == text::HoriOrientation::FULL);
1991         aSet.Put(aOrient);
1992     }
1993 
1994 
1995     const uno::Any* pSzRel       = 0;
1996     GetProperty(FN_TABLE_IS_RELATIVE_WIDTH, 0xff, pSzRel  );
1997     const uno::Any* pRelWidth   = 0;
1998     GetProperty(FN_TABLE_RELATIVE_WIDTH, 0xff, pRelWidth);
1999     const uno::Any* pWidth      = 0;
2000     GetProperty(FN_TABLE_WIDTH, 0xff, pWidth  );
2001 
2002     sal_Bool bPutSize = pWidth != 0;
2003     SwFmtFrmSize aSz( ATT_VAR_SIZE);
2004     if(pWidth)
2005     {
2006         ((SfxPoolItem&)aSz).PutValue(*pWidth, MID_FRMSIZE_WIDTH);
2007         bPutSize = sal_True;
2008     }
2009     sal_Bool bTemp = pSzRel ? *(sal_Bool*)pSzRel->getValue() : sal_False;
2010     if(pSzRel && bTemp && pRelWidth)
2011     {
2012         ((SfxPoolItem&)aSz).PutValue(*pRelWidth, MID_FRMSIZE_REL_WIDTH|CONVERT_TWIPS);
2013         bPutSize = sal_True;
2014     }
2015     if(bPutSize)
2016     {
2017         if(!aSz.GetWidth())
2018             aSz.SetWidth(MINLAY);
2019         aSet.Put(aSz);
2020     }
2021     const uno::Any* pL      = 0;
2022     GetProperty(RES_LR_SPACE, MID_L_MARGIN|CONVERT_TWIPS, pL);
2023     const uno::Any* pR      = 0;
2024     GetProperty(RES_LR_SPACE, MID_R_MARGIN|CONVERT_TWIPS, pR);
2025     if(pL||pR)
2026     {
2027         SvxLRSpaceItem aLR ( rFrmFmt.GetLRSpace() );
2028         if(pL)
2029             ((SfxPoolItem&)aLR).PutValue(*pL, MID_L_MARGIN|CONVERT_TWIPS);
2030         if(pR)
2031             ((SfxPoolItem&)aLR).PutValue(*pR, MID_R_MARGIN|CONVERT_TWIPS);
2032         aSet.Put(aLR);
2033     }
2034     const uno::Any* pU      = 0;
2035     GetProperty(RES_UL_SPACE, MID_UP_MARGIN|CONVERT_TWIPS, pU);
2036     const uno::Any* pLo     = 0;
2037     GetProperty(RES_UL_SPACE, MID_LO_MARGIN|CONVERT_TWIPS, pLo);
2038     if(pU||pLo)
2039     {
2040         SvxULSpaceItem aUL ( rFrmFmt.GetULSpace() );
2041         if(pU)
2042             ((SfxPoolItem&)aUL).PutValue(*pU, MID_UP_MARGIN|CONVERT_TWIPS);
2043         if(pLo)
2044             ((SfxPoolItem&)aUL).PutValue(*pLo, MID_LO_MARGIN|CONVERT_TWIPS);
2045         aSet.Put(aUL);
2046     }
2047     const::uno::Any* pSplit;
2048     if(GetProperty(RES_LAYOUT_SPLIT, 0, pSplit ))
2049     {
2050         sal_Bool bTmp = *(sal_Bool*)pSplit->getValue();
2051         SwFmtLayoutSplit aSp(bTmp);
2052         aSet.Put(aSp);
2053     }
2054 
2055     //TODO: folgende Propertiers noch impl.
2056 //  FN_UNO_RANGE_ROW_LABEL
2057 //  FN_UNO_RANGE_COL_LABEL
2058 //  FN_UNO_TABLE_BORDER
2059 
2060     if(aSet.Count())
2061     {
2062         rDoc.SetAttr( aSet, *rTbl.GetFrmFmt() );
2063     }
2064 }
2065 
getUnoTunnelId()2066 const uno::Sequence< sal_Int8 > & SwXTextTable::getUnoTunnelId()
2067 {
2068     static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
2069     return aSeq;
2070 }
2071 
getSomething(const uno::Sequence<sal_Int8> & rId)2072 sal_Int64 SAL_CALL SwXTextTable::getSomething( const uno::Sequence< sal_Int8 >& rId )
2073 {
2074     if( rId.getLength() == 16
2075         && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
2076                                         rId.getConstArray(), 16 ) )
2077     {
2078         return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
2079     }
2080     return 0;
2081 }
2082 
TYPEINIT1(SwXTextTable,SwClient)2083 TYPEINIT1(SwXTextTable, SwClient)
2084 
2085 
2086 SwXTextTable::SwXTextTable() :
2087     aLstnrCntnr( (text::XTextTable*)this),
2088     aChartLstnrCntnr( (text::XTextTable*)this),
2089     m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_TABLE)),
2090     pTableProps(new SwTableProperties_Impl),
2091     bIsDescriptor(sal_True),
2092     nRows(2),
2093     nColumns(2),
2094     bFirstRowAsLabel(sal_False),
2095     bFirstColumnAsLabel(sal_False)
2096 {
2097 }
2098 
SwXTextTable(SwFrmFmt & rFrmFmt)2099 SwXTextTable::SwXTextTable(SwFrmFmt& rFrmFmt) :
2100     SwClient( &rFrmFmt ),
2101     aLstnrCntnr( (text::XTextTable*)this),
2102     aChartLstnrCntnr( (text::XTextTable*)this),
2103     m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_TABLE)),
2104     pTableProps(0),
2105     bIsDescriptor(sal_False),
2106     nRows(0),
2107     nColumns(0),
2108     bFirstRowAsLabel(sal_False),
2109     bFirstColumnAsLabel(sal_False)
2110 {
2111 }
2112 
~SwXTextTable()2113 SwXTextTable::~SwXTextTable()
2114 {
2115     delete pTableProps;
2116 }
2117 
initialize(sal_Int32 nR,sal_Int32 nC)2118 void SwXTextTable::initialize(sal_Int32 nR, sal_Int32 nC)
2119 {
2120     if(!bIsDescriptor || nR <= 0 || nC <= 0 || nR >= USHRT_MAX || nC >= USHRT_MAX )
2121         throw uno::RuntimeException();
2122     else
2123     {
2124         nRows = (sal_uInt16)nR;
2125         nColumns = (sal_uInt16)nC;
2126     }
2127 }
2128 
getRows(void)2129 uno::Reference< table::XTableRows >  SwXTextTable::getRows(void)
2130 {
2131     vos::OGuard aGuard(Application::GetSolarMutex());
2132     uno::Reference< table::XTableRows >  xRet;
2133     if (SwFrmFmt* pFmt = GetFrmFmt())
2134     {
2135         SwXTableRows* pRows = SwIterator<SwXTableRows,SwFmt>::FirstElement(*pFmt);
2136         if (!pRows)
2137             pRows = new SwXTableRows(*pFmt);
2138         xRet = pRows;
2139     }
2140     if (!xRet.is())
2141         throw uno::RuntimeException();
2142     return xRet;
2143 }
2144 
getColumns(void)2145 uno::Reference< table::XTableColumns >  SwXTextTable::getColumns(void)
2146 {
2147     vos::OGuard aGuard(Application::GetSolarMutex());
2148     uno::Reference< table::XTableColumns >  xRet;
2149     if (SwFrmFmt* pFmt = GetFrmFmt())
2150     {
2151         SwXTableColumns* pCols = SwIterator<SwXTableColumns,SwFmt>::FirstElement(*pFmt);
2152         if (!pCols)
2153             pCols = new SwXTableColumns(*pFmt);
2154         xRet = pCols;
2155     }
2156     if (!xRet.is())
2157         throw uno::RuntimeException();
2158     return xRet;
2159 }
2160 
getCellByName(const OUString & CellName)2161 uno::Reference< table::XCell >  SwXTextTable::getCellByName(const OUString& CellName)
2162 {
2163     vos::OGuard aGuard(Application::GetSolarMutex());
2164     uno::Reference< table::XCell >  xRet;
2165     SwFrmFmt* pFmt = GetFrmFmt();
2166     if(pFmt)
2167     {
2168         SwTable* pTable = SwTable::FindTable( pFmt );
2169         String sCellName(CellName);
2170         SwTableBox* pBox = (SwTableBox*)pTable->GetTblBox( sCellName );
2171         if(pBox)
2172         {
2173             xRet = SwXCell::CreateXCell(pFmt, pBox);
2174         }
2175     }
2176     else
2177         throw uno::RuntimeException();
2178     return xRet;
2179 }
2180 
getCellNames(void)2181 uno::Sequence< OUString > SwXTextTable::getCellNames(void)
2182 {
2183     vos::OGuard aGuard(Application::GetSolarMutex());
2184     SwFrmFmt* pFmt = GetFrmFmt();
2185     if(pFmt)
2186     {
2187         SwTable* pTable = SwTable::FindTable( pFmt );
2188           // gibts an der Tabelle und an allen Boxen
2189         SwTableLines& rTblLines = pTable->GetTabLines();
2190         SvStrings aAllNames;
2191         lcl_InspectLines(rTblLines, aAllNames);
2192         uno::Sequence< OUString > aRet(aAllNames.Count());
2193         OUString* pArray = aRet.getArray();
2194         for(sal_uInt16 i = aAllNames.Count(); i; i--)
2195         {
2196             String* pObject = aAllNames.GetObject(i-1);
2197             pArray[i - 1] = *pObject;
2198             aAllNames.Remove(i - 1);
2199             delete pObject;
2200         }
2201         return aRet;
2202     }
2203     return uno::Sequence< OUString >();
2204 }
2205 
createCursorByCellName(const OUString & CellName)2206 uno::Reference< text::XTextTableCursor >  SwXTextTable::createCursorByCellName(const OUString& CellName)
2207 {
2208     vos::OGuard aGuard(Application::GetSolarMutex());
2209     uno::Reference< text::XTextTableCursor >  xRet;
2210     SwFrmFmt* pFmt = GetFrmFmt();
2211     if(pFmt)
2212     {
2213         SwTable* pTable = SwTable::FindTable( pFmt );
2214         String sCellName(CellName);
2215         SwTableBox* pBox = (SwTableBox*)pTable->GetTblBox( sCellName );
2216         if(pBox && pBox->getRowSpan() > 0 )
2217         {
2218             xRet = new SwXTextTableCursor(pFmt, pBox);
2219         }
2220     }
2221     if(!xRet.is())
2222         throw uno::RuntimeException();
2223     return xRet;
2224 }
2225 
attachToRange(const uno::Reference<text::XTextRange> & xTextRange)2226 void SwXTextTable::attachToRange(const uno::Reference< text::XTextRange > & xTextRange)
2227 {
2228     // attachToRange must only be called once
2229     if(!bIsDescriptor)  /* already attached ? */
2230         throw uno::RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "SwXTextTable: already attached to range." ) ), static_cast < cppu::OWeakObject * > ( this ) );
2231 
2232     uno::Reference<XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
2233     SwXTextRange* pRange = 0;
2234     OTextCursorHelper* pCursor = 0;
2235     if(xRangeTunnel.is())
2236     {
2237         pRange  = reinterpret_cast< SwXTextRange * >(
2238                 sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( SwXTextRange::getUnoTunnelId()) ));
2239         pCursor = reinterpret_cast< OTextCursorHelper * >(
2240                 sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( OTextCursorHelper::getUnoTunnelId()) ));
2241     }
2242     SwDoc* pDoc = pRange ? (SwDoc*)pRange->GetDoc() : pCursor ? (SwDoc*)pCursor->GetDoc() : 0;
2243     if(pDoc && nRows && nColumns)
2244     {
2245         SwUnoInternalPaM aPam(*pDoc);
2246         //das muss jetzt sal_True liefern
2247         ::sw::XTextRangeToSwPaM(aPam, xTextRange);
2248 
2249         {
2250             UnoActionContext aCont( pDoc );
2251 
2252             pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL);
2253             const SwTable *pTable = 0;
2254             if( 0 != aPam.Start()->nContent.GetIndex() )
2255             {
2256                 pDoc->SplitNode(*aPam.Start(), false );
2257             }
2258             //TODO: wenn es der letzte Absatz ist, dann muss noch ein Absatz angehaengt werden!
2259             if( aPam.HasMark() )
2260             {
2261                 pDoc->DeleteAndJoin(aPam);
2262                 aPam.DeleteMark();
2263             }
2264             pTable = pDoc->InsertTable( SwInsertTableOptions( tabopts::HEADLINE | tabopts::DEFAULT_BORDER | tabopts::SPLIT_LAYOUT, 0 ),
2265                                         *aPam.GetPoint(),
2266                                         nRows,
2267                                         nColumns,
2268                                         text::HoriOrientation::FULL );
2269             if(pTable)
2270             {
2271                 // hier muessen die Properties des Descriptors ausgewertet werden
2272                 pTableProps->ApplyTblAttr(*pTable, *pDoc);
2273                 SwFrmFmt* pTblFmt = pTable->GetFrmFmt();
2274                 lcl_FormatTable( pTblFmt );
2275 
2276                 pTblFmt->Add(this);
2277                 if(m_sTableName.Len())
2278                 {
2279                     sal_uInt16 nIndex = 1;
2280                     const String sTmpName(m_sTableName);
2281                     String sTmpNameIndex(sTmpName);
2282                     while(pDoc->FindTblFmtByName( sTmpNameIndex, sal_True ) && nIndex < USHRT_MAX)
2283                     {
2284                         sTmpNameIndex = sTmpName;
2285                         sTmpNameIndex += nIndex++;
2286                     }
2287                     pDoc->SetTableName( *pTblFmt, sTmpNameIndex);
2288                 }
2289 
2290                 const::uno::Any* pName;
2291                 if(pTableProps->GetProperty(FN_UNO_TABLE_NAME, 0, pName))
2292                 {
2293                     OUString sTmp;
2294                     (*pName) >>= sTmp;
2295                     setName(sTmp);
2296                 }
2297                 bIsDescriptor = sal_False;
2298                 DELETEZ(pTableProps);
2299             }
2300             pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
2301         }
2302     }
2303     else
2304         throw lang::IllegalArgumentException();
2305 }
2306 
attach(const uno::Reference<text::XTextRange> & xTextRange)2307 void SwXTextTable::attach(const uno::Reference< text::XTextRange > & xTextRange)
2308 {
2309     vos::OGuard aGuard(Application::GetSolarMutex());
2310     attachToRange( xTextRange );
2311 }
2312 
getAnchor(void)2313 uno::Reference< text::XTextRange >  SwXTextTable::getAnchor(void)
2314 {
2315     vos::OGuard aGuard(Application::GetSolarMutex());
2316     SwFrmFmt* pFmt = GetFrmFmt();
2317     if(!pFmt)
2318         throw uno::RuntimeException();
2319     uno::Reference< text::XTextRange >  xRet = new SwXTextRange(*pFmt);
2320     return xRet;
2321 }
2322 
dispose(void)2323 void SwXTextTable::dispose(void)
2324 {
2325     vos::OGuard aGuard(Application::GetSolarMutex());
2326     SwFrmFmt* pFmt = GetFrmFmt();
2327     if(pFmt)
2328     {
2329         SwTable* pTable = SwTable::FindTable( pFmt );
2330         SwTableSortBoxes& rBoxes = pTable->GetTabSortBoxes();
2331         SwSelBoxes aSelBoxes;
2332         aSelBoxes.Insert(rBoxes.GetData(), rBoxes.Count());
2333         pFmt->GetDoc()->DeleteRowCol(aSelBoxes);
2334     }
2335     else
2336         throw uno::RuntimeException();
2337 }
2338 
addEventListener(const uno::Reference<lang::XEventListener> & aListener)2339 void SwXTextTable::addEventListener(const uno::Reference< lang::XEventListener > & aListener)
2340 {
2341     if(!GetRegisteredIn())
2342         throw uno::RuntimeException();
2343     aLstnrCntnr.AddListener(aListener);
2344 }
2345 
removeEventListener(const uno::Reference<lang::XEventListener> & aListener)2346 void SwXTextTable::removeEventListener(const uno::Reference< lang::XEventListener > & aListener)
2347 {
2348     if(!GetRegisteredIn() || !aLstnrCntnr.RemoveListener(aListener))
2349         throw uno::RuntimeException();
2350 }
2351 
getCellByPosition(sal_Int32 nColumn,sal_Int32 nRow)2352 uno::Reference< table::XCell >  SwXTextTable::getCellByPosition(sal_Int32 nColumn, sal_Int32 nRow)
2353 {
2354     vos::OGuard aGuard(Application::GetSolarMutex());
2355     uno::Reference< table::XCell >  aRef;
2356     SwFrmFmt* pFmt = GetFrmFmt();
2357     // Sheet interessiert nicht
2358     if(nColumn >= 0 && nRow >= 0 && nColumn < USHRT_MAX && nRow < USHRT_MAX && pFmt)
2359     {
2360         SwXCell* pXCell = lcl_CreateXCell(pFmt, nColumn, nRow);
2361         if(pXCell)
2362             aRef = pXCell;
2363     }
2364     if(!aRef.is())
2365         throw lang::IndexOutOfBoundsException();
2366     return aRef;
2367 
2368 }
2369 
GetRangeByName(SwFrmFmt * pFmt,SwTable * pTable,const String & rTLName,const String & rBRName,SwRangeDescriptor & rDesc)2370 uno::Reference< table::XCellRange >  SwXTextTable::GetRangeByName(SwFrmFmt* pFmt, SwTable* pTable,
2371                     const String& rTLName, const String& rBRName,
2372                     SwRangeDescriptor& rDesc)
2373 {
2374     vos::OGuard aGuard(Application::GetSolarMutex());
2375     uno::Reference< table::XCellRange >  aRef;
2376     String sTLName(rTLName);
2377     String sBRName(rBRName);
2378     const SwTableBox* pTLBox = pTable->GetTblBox( sTLName );
2379     if(pTLBox)
2380     {
2381         // hier muessen die Actions aufgehoben werden
2382         UnoActionRemoveContext aRemoveContext(pFmt->GetDoc());
2383         const SwStartNode* pSttNd = pTLBox->GetSttNd();
2384         SwPosition aPos(*pSttNd);
2385         // Cursor in die obere linke Zelle des Ranges setzen
2386         SwUnoCrsr* pUnoCrsr = pFmt->GetDoc()->CreateUnoCrsr(aPos, sal_True);
2387         pUnoCrsr->Move( fnMoveForward, fnGoNode );
2388         pUnoCrsr->SetRemainInSection( sal_False );
2389         const SwTableBox* pBRBox = pTable->GetTblBox( sBRName );
2390         if(pBRBox)
2391         {
2392             pUnoCrsr->SetMark();
2393             pUnoCrsr->GetPoint()->nNode = *pBRBox->GetSttNd();
2394             pUnoCrsr->Move( fnMoveForward, fnGoNode );
2395             SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
2396             pCrsr->MakeBoxSels();
2397             // pUnoCrsr wird uebergeben und nicht geloescht
2398             SwXCellRange* pCellRange = new SwXCellRange(pUnoCrsr, *pFmt, rDesc);
2399             aRef = pCellRange;
2400         }
2401         else
2402             delete pUnoCrsr;
2403     }
2404     return aRef;
2405 }
2406 
getCellRangeByPosition(sal_Int32 nLeft,sal_Int32 nTop,sal_Int32 nRight,sal_Int32 nBottom)2407 uno::Reference< table::XCellRange >  SwXTextTable::getCellRangeByPosition(sal_Int32 nLeft, sal_Int32 nTop,
2408                 sal_Int32 nRight, sal_Int32 nBottom)
2409 {
2410     vos::OGuard aGuard(Application::GetSolarMutex());
2411     uno::Reference< table::XCellRange >  aRef;
2412     SwFrmFmt* pFmt = GetFrmFmt();
2413     if(pFmt && nRight < USHRT_MAX && nBottom < USHRT_MAX &&
2414         nLeft <= nRight && nTop <= nBottom &&
2415             nLeft >= 0 && nRight >= 0 && nTop >= 0 && nBottom >= 0 )
2416     {
2417         SwTable* pTable = SwTable::FindTable( pFmt );
2418         if(!pTable->IsTblComplex())
2419         {
2420             SwRangeDescriptor aDesc;
2421             aDesc.nTop    = nTop;
2422             aDesc.nBottom = nBottom;
2423             aDesc.nLeft   = nLeft;
2424             aDesc.nRight  = nRight;
2425             String sTLName = lcl_GetCellName(aDesc.nLeft, aDesc.nTop);
2426             String sBRName = lcl_GetCellName(aDesc.nRight, aDesc.nBottom);
2427 
2428             // please note that according to the 'if' statement at the begin
2429             // sTLName:sBRName already denotes the normalized range string
2430 
2431             aRef = GetRangeByName(pFmt, pTable, sTLName, sBRName, aDesc);
2432         }
2433     }
2434     if(!aRef.is())
2435         throw lang::IndexOutOfBoundsException();
2436     return aRef;
2437 }
2438 
getCellRangeByName(const OUString & aRange)2439 uno::Reference< table::XCellRange >  SwXTextTable::getCellRangeByName(const OUString& aRange)
2440 {
2441     vos::OGuard aGuard(Application::GetSolarMutex());
2442     uno::Reference< table::XCellRange >  aRef;
2443     SwFrmFmt* pFmt = GetFrmFmt();
2444     if(pFmt)
2445     {
2446         SwTable* pTable = SwTable::FindTable( pFmt );
2447         if(!pTable->IsTblComplex())
2448         {
2449             String sRange(aRange);
2450             String sTLName(sRange.GetToken(0, ':'));
2451             String sBRName(sRange.GetToken(1, ':'));
2452             if(!sTLName.Len() || !sBRName.Len())
2453                 throw uno::RuntimeException();
2454             SwRangeDescriptor aDesc;
2455             aDesc.nTop = aDesc.nLeft = aDesc.nBottom = aDesc.nRight = -1;
2456             lcl_GetCellPosition(sTLName, aDesc.nLeft, aDesc.nTop );
2457             lcl_GetCellPosition(sBRName, aDesc.nRight, aDesc.nBottom );
2458 
2459             // we should normalize the range now (e.g. A5:C1 will become A1:C5)
2460             // since (depending on what is done later) it will be troublesome
2461             // elsewhere when the cursor in the implementation does not
2462             // point to the top-left and bottom-right cells
2463             aDesc.Normalize();
2464 
2465             aRef = GetRangeByName(pFmt, pTable, sTLName, sBRName, aDesc);
2466         }
2467     }
2468     if(!aRef.is())
2469         throw uno::RuntimeException();
2470     return aRef;
2471 }
2472 
getDataArray()2473 uno::Sequence< uno::Sequence< uno::Any > > SAL_CALL SwXTextTable::getDataArray()
2474 {
2475     // see SwXTextTable::getData(...) also
2476 
2477     vos::OGuard aGuard(Application::GetSolarMutex());
2478     sal_Int16 nRowCount = getRowCount();
2479     sal_Int16 nColCount = getColumnCount();
2480     if(!nRowCount || !nColCount)
2481     {
2482         uno::RuntimeException aRuntime;
2483         aRuntime.Message = C2U("Table too complex");
2484         throw aRuntime;
2485     }
2486     SwFrmFmt* pFmt = GetFrmFmt();
2487     uno::Sequence< uno::Sequence< uno::Any > > aRowSeq(nRowCount);
2488     if(pFmt)
2489     {
2490         uno::Sequence< uno::Any > * pRowArray = aRowSeq.getArray();
2491         for(sal_uInt16 nRow = 0; nRow < nRowCount; nRow++)
2492         {
2493             uno::Sequence< uno::Any >  aColSeq(nColCount);
2494             uno::Any * pColArray = aColSeq.getArray();
2495             uno::Reference< table::XCell > xCellRef;
2496             for(sal_uInt16 nCol = 0; nCol < nColCount; nCol++)
2497             {
2498                 SwXCell* pXCell = lcl_CreateXCell(pFmt, nCol, nRow);
2499                 //! keep (additional) reference to object to prevent implicit destruction
2500                 //! in following UNO calls (when object will get referenced)
2501                 xCellRef = pXCell;
2502                 SwTableBox * pBox = pXCell ? pXCell->GetTblBox() : 0;
2503                 if(!pBox)
2504                 {
2505                     throw uno::RuntimeException();
2506                 }
2507                 else
2508                 {
2509                     // check if table box value item is set
2510                     SwFrmFmt* pBoxFmt = pBox->GetFrmFmt();
2511                     sal_Bool bIsNum = pBoxFmt->GetItemState( RES_BOXATR_VALUE, sal_False ) == SFX_ITEM_SET;
2512                     //const SfxPoolItem* pItem;
2513                     //SwDoc* pDoc = pXCell->GetDoc();
2514                     //sal_Bool bIsText = (SFX_ITEM_SET != pBoxFmt->GetAttrSet().GetItemState(RES_BOXATR_FORMAT, sal_True, &pItem)
2515                     //          ||  pDoc->GetNumberFormatter()->IsTextFormat(((SwTblBoxNumFormat*)pItem)->GetValue())
2516                     //          ||  ((SwTblBoxNumFormat*)pItem)->GetValue() == NUMBERFORMAT_TEXT);
2517 
2518                     if(!bIsNum/*bIsText*/)
2519                         pColArray[nCol] <<= lcl_getString(*pXCell);
2520                     else
2521                         pColArray[nCol] <<= lcl_getValue(*pXCell);
2522                 }
2523             }
2524             pRowArray[nRow] = aColSeq;
2525         }
2526     }
2527     else
2528         throw uno::RuntimeException();
2529     return aRowSeq;
2530 }
2531 
setDataArray(const uno::Sequence<uno::Sequence<uno::Any>> & rArray)2532 void SAL_CALL SwXTextTable::setDataArray(
2533         const uno::Sequence< uno::Sequence< uno::Any > >& rArray )
2534 {
2535     // see SwXTextTable::setData(...) also
2536 
2537     vos::OGuard aGuard(Application::GetSolarMutex());
2538     sal_Int16 nRowCount = getRowCount();
2539     sal_Int16 nColCount = getColumnCount();
2540 
2541     SwFrmFmt* pFmt = GetFrmFmt();
2542     if(pFmt)
2543     {
2544         SwTable* pTable = SwTable::FindTable( pFmt );
2545         if(pTable->IsTblComplex())
2546         {
2547             uno::RuntimeException aRuntime;
2548             aRuntime.Message = C2U("Table too complex");
2549             throw aRuntime;
2550         }
2551 
2552         if(rArray.getLength() != nRowCount)
2553         {
2554             throw uno::RuntimeException();
2555         }
2556         const uno::Sequence< uno::Any >* pRowArray = rArray.getConstArray();
2557         for(sal_uInt16 nRow = 0; nRow < nRowCount; nRow++)
2558         {
2559             const uno::Sequence< uno::Any >& rColSeq = pRowArray[nRow];
2560             if(rColSeq.getLength() != nColCount)
2561             {
2562                 throw uno::RuntimeException();
2563             }
2564             const uno::Any * pColArray = rColSeq.getConstArray();
2565             uno::Reference< table::XCell > xCellRef;
2566             for(sal_uInt16 nCol = 0; nCol < nColCount; nCol++)
2567             {
2568                 SwXCell* pXCell = lcl_CreateXCell(pFmt, nCol, nRow);
2569                 //! keep (additional) reference to object to prevent implicit destruction
2570                 //! in following UNO calls (when object will get referenced)
2571                 xCellRef = pXCell;
2572                 SwTableBox * pBox = pXCell ? pXCell->GetTblBox() : 0;
2573                 if(!pBox)
2574                 {
2575                     throw uno::RuntimeException();
2576                 }
2577                 else
2578                 {
2579                     const uno::Any &rAny = pColArray[nCol];
2580                     if (uno::TypeClass_STRING == rAny.getValueTypeClass())
2581                         lcl_setString( *pXCell, *(rtl::OUString *) rAny.getValue() );
2582                     else
2583                     {
2584                         double d = 0;
2585                         // #i20067# don't throw exception just do nothing if
2586                         // there is no value set
2587                         if( (rAny >>= d) )
2588                             lcl_setValue( *pXCell, d );
2589                         else
2590                             lcl_setString( *pXCell, OUString(), sal_True );
2591 
2592                     }
2593                 }
2594             }
2595         }
2596     }
2597 }
2598 
getData(void)2599 uno::Sequence< uno::Sequence< double > > SwXTextTable::getData(void)
2600 {
2601     vos::OGuard aGuard(Application::GetSolarMutex());
2602     sal_Int16 nRowCount = getRowCount();
2603     sal_Int16 nColCount = getColumnCount();
2604     if(!nRowCount || !nColCount)
2605     {
2606         uno::RuntimeException aRuntime;
2607         aRuntime.Message = C2U("Table too complex");
2608         throw aRuntime;
2609     }
2610     //
2611     SwFrmFmt* pFmt = GetFrmFmt();
2612     uno::Sequence< uno::Sequence< double > > aRowSeq(bFirstRowAsLabel ? nRowCount - 1 : nRowCount);
2613     if(pFmt)
2614     {
2615         uno::Sequence< double >* pArray = aRowSeq.getArray();
2616 
2617         sal_uInt16 nRowStart = bFirstRowAsLabel ? 1 : 0;
2618         for(sal_uInt16 nRow = nRowStart; nRow < nRowCount; nRow++)
2619         {
2620             uno::Sequence< double >  aColSeq(bFirstColumnAsLabel ? nColCount - 1 : nColCount);
2621             double* pColArray = aColSeq.getArray();
2622             sal_uInt16 nColStart = bFirstColumnAsLabel ? 1 : 0;
2623             for(sal_uInt16 nCol = nColStart; nCol < nColCount; nCol++)
2624             {
2625                 uno::Reference< table::XCell >  xCell = getCellByPosition(nCol, nRow);
2626                 if(!xCell.is())
2627                 {
2628                     throw uno::RuntimeException();
2629                 }
2630                 pColArray[nCol - nColStart] = xCell->getValue();
2631             }
2632             pArray[nRow - nRowStart] = aColSeq;
2633         }
2634     }
2635     else
2636         throw uno::RuntimeException();
2637     return aRowSeq;
2638 }
2639 
setData(const uno::Sequence<uno::Sequence<double>> & rData)2640 void SwXTextTable::setData(const uno::Sequence< uno::Sequence< double > >& rData)
2641 {
2642     vos::OGuard aGuard(Application::GetSolarMutex());
2643     sal_Int16 nRowCount = getRowCount();
2644     sal_Int16 nColCount = getColumnCount();
2645     sal_Bool bChanged = sal_False;
2646 
2647     if(!nRowCount || !nColCount)
2648     {
2649         uno::RuntimeException aRuntime;
2650         aRuntime.Message = C2U("Table too complex");
2651         throw aRuntime;
2652     }
2653     SwFrmFmt* pFmt = GetFrmFmt();
2654     if(pFmt )
2655     {
2656         sal_uInt16 nRowStart = bFirstRowAsLabel ? 1 : 0;
2657         if(rData.getLength() < nRowCount - nRowStart)
2658         {
2659             throw uno::RuntimeException();
2660         }
2661         const uno::Sequence< double >* pRowArray = rData.getConstArray();
2662         for(sal_uInt16 nRow = nRowStart; nRow < nRowCount; nRow++)
2663         {
2664             const uno::Sequence< double >& rColSeq = pRowArray[nRow - nRowStart];
2665             sal_uInt16 nColStart = bFirstColumnAsLabel ? 1 : 0;
2666             if(rColSeq.getLength() < nColCount - nColStart)
2667             {
2668                 throw uno::RuntimeException();
2669             }
2670             const double * pColArray = rColSeq.getConstArray();
2671             for(sal_uInt16 nCol = nColStart; nCol < nColCount; nCol++)
2672             {
2673                 uno::Reference< table::XCell >  xCell = getCellByPosition(nCol, nRow);
2674                 if(!xCell.is())
2675                 {
2676                     throw uno::RuntimeException();
2677                 }
2678                 xCell->setValue(pColArray[nCol - nColStart]);
2679                 bChanged=sal_True;
2680             }
2681         }
2682         if ( bChanged )
2683             aChartLstnrCntnr.ChartDataChanged();
2684     }
2685 }
2686 
getRowDescriptions(void)2687 uno::Sequence< OUString > SwXTextTable::getRowDescriptions(void)
2688 {
2689     vos::OGuard aGuard(Application::GetSolarMutex());
2690     sal_Int16 nRowCount = getRowCount();
2691     if(!nRowCount)
2692     {
2693         uno::RuntimeException aRuntime;
2694         aRuntime.Message = C2U("Table too complex");
2695         throw aRuntime;
2696     }
2697     uno::Sequence< OUString > aRet(bFirstColumnAsLabel ? nRowCount - 1 : nRowCount);
2698     SwFrmFmt* pFmt = GetFrmFmt();
2699     if(pFmt)
2700     {
2701         OUString* pArray = aRet.getArray();
2702         if(bFirstColumnAsLabel)
2703         {
2704             sal_uInt16 nStart = bFirstRowAsLabel ? 1 : 0;
2705             for(sal_uInt16 i = nStart; i < nRowCount; i++)
2706             {
2707                 uno::Reference< table::XCell >  xCell = getCellByPosition(0, i);
2708                 if(!xCell.is())
2709                 {
2710                     //exception ...
2711                     break;
2712                 }
2713                 uno::Reference< text::XText >  xText(xCell, uno::UNO_QUERY);
2714                 pArray[i - nStart] = xText->getString();
2715             }
2716         }
2717         else
2718         {
2719             DBG_ERROR("Wo kommen die Labels her?");
2720         }
2721     }
2722     else
2723         throw uno::RuntimeException();
2724     return aRet;
2725 }
2726 
setRowDescriptions(const uno::Sequence<OUString> & rRowDesc)2727 void SwXTextTable::setRowDescriptions(const uno::Sequence< OUString >& rRowDesc)
2728 {
2729     vos::OGuard aGuard(Application::GetSolarMutex());
2730     SwFrmFmt* pFmt = GetFrmFmt();
2731     if(pFmt)
2732     {
2733         sal_Int16 nRowCount = getRowCount();
2734         if(!nRowCount || rRowDesc.getLength() < (bFirstRowAsLabel ? nRowCount - 1 : nRowCount))
2735         {
2736             throw uno::RuntimeException();
2737         }
2738         const OUString* pArray = rRowDesc.getConstArray();
2739         if(bFirstColumnAsLabel)
2740         {
2741             sal_uInt16 nStart = bFirstRowAsLabel ? 1 : 0;
2742             for(sal_uInt16 i = nStart; i < nRowCount; i++)
2743             {
2744                 uno::Reference< table::XCell >  xCell = getCellByPosition(0, i);
2745                 if(!xCell.is())
2746                 {
2747                     throw uno::RuntimeException();
2748                 }
2749                 uno::Reference< text::XText >  xText(xCell, uno::UNO_QUERY);
2750                 xText->setString(pArray[i - nStart]);
2751             }
2752         }
2753         else
2754         {
2755             DBG_ERROR("Wohin mit den Labels?");
2756         }
2757     }
2758     else
2759         throw uno::RuntimeException();
2760 }
2761 
getColumnDescriptions(void)2762 uno::Sequence< OUString > SwXTextTable::getColumnDescriptions(void)
2763 {
2764     vos::OGuard aGuard(Application::GetSolarMutex());
2765     sal_Int16 nColCount = getColumnCount();
2766     if(!nColCount)
2767     {
2768         uno::RuntimeException aRuntime;
2769         aRuntime.Message = C2U("Table too complex");
2770         throw aRuntime;
2771     }
2772     uno::Sequence< OUString > aRet(bFirstRowAsLabel ? nColCount - 1 : nColCount);
2773     SwFrmFmt* pFmt = GetFrmFmt();
2774     if(pFmt)
2775     {
2776         OUString* pArray = aRet.getArray();
2777         if(bFirstRowAsLabel)
2778         {
2779             sal_uInt16 nStart = bFirstColumnAsLabel ? 1 : 0;
2780             for(sal_uInt16 i = nStart; i < nColCount; i++)
2781             {
2782                 uno::Reference< table::XCell >  xCell = getCellByPosition(i, 0);
2783                 if(!xCell.is())
2784                 {
2785                     throw uno::RuntimeException();
2786                 }
2787                 uno::Reference< text::XText >  xText(xCell, uno::UNO_QUERY);
2788 
2789                 pArray[i - nStart] = xText->getString();
2790             }
2791         }
2792         else
2793         {
2794             DBG_ERROR("Wo kommen die Labels her?");
2795         }
2796     }
2797     else
2798         throw uno::RuntimeException();
2799     return aRet;
2800 }
2801 
setColumnDescriptions(const uno::Sequence<OUString> & rColumnDesc)2802 void SwXTextTable::setColumnDescriptions(const uno::Sequence< OUString >& rColumnDesc)
2803 {
2804     vos::OGuard aGuard(Application::GetSolarMutex());
2805     sal_Int16 nColCount = getColumnCount();
2806     if(!nColCount)
2807     {
2808         uno::RuntimeException aRuntime;
2809         aRuntime.Message = C2U("Table too complex");
2810         throw aRuntime;
2811     }
2812     SwFrmFmt* pFmt = GetFrmFmt();
2813     if(pFmt)
2814     {
2815         const OUString* pArray = rColumnDesc.getConstArray();
2816         if(bFirstRowAsLabel && rColumnDesc.getLength() >= nColCount - bFirstColumnAsLabel ? 1 : 0)
2817         {
2818             sal_uInt16 nStart = bFirstColumnAsLabel ? 1 : 0;
2819             for(sal_uInt16 i = nStart; i < nColCount; i++)
2820             {
2821                 uno::Reference< table::XCell >  xCell = getCellByPosition(i, 0);
2822                 if(!xCell.is())
2823                 {
2824                     throw uno::RuntimeException();
2825                 }
2826                 uno::Reference< text::XText >  xText(xCell, uno::UNO_QUERY);
2827                 xText->setString(pArray[i - nStart]);
2828             }
2829         }
2830         else
2831         {
2832             DBG_ERROR("Wo kommen die Labels her?");
2833         }
2834     }
2835     else
2836         throw uno::RuntimeException();
2837 }
2838 
addChartDataChangeEventListener(const uno::Reference<chart::XChartDataChangeEventListener> & aListener)2839 void SwXTextTable::addChartDataChangeEventListener(
2840     const uno::Reference< chart::XChartDataChangeEventListener > & aListener)
2841 {
2842     if(!GetRegisteredIn())
2843         throw uno::RuntimeException();
2844     aChartLstnrCntnr.AddListener(aListener.get());
2845 }
2846 
removeChartDataChangeEventListener(const uno::Reference<chart::XChartDataChangeEventListener> & aListener)2847 void SwXTextTable::removeChartDataChangeEventListener(
2848     const uno::Reference< chart::XChartDataChangeEventListener > & aListener)
2849 {
2850     if(!GetRegisteredIn() || !aChartLstnrCntnr.RemoveListener(aListener.get()))
2851         throw uno::RuntimeException();
2852 }
2853 
isNotANumber(double nNumber)2854 sal_Bool SwXTextTable::isNotANumber(double nNumber)
2855 {
2856     // We use DBL_MIN because starcalc does (which uses it because chart
2857     // wants it that way!)
2858     return ( nNumber == DBL_MIN );
2859 }
2860 
getNotANumber(void)2861 double SwXTextTable::getNotANumber(void)
2862 {
2863     // We use DBL_MIN because starcalc does (which uses it because chart
2864     // wants it that way!)
2865     return DBL_MIN;
2866 }
2867 
createSortDescriptor(void)2868 uno::Sequence< beans::PropertyValue > SwXTextTable::createSortDescriptor(void)
2869 {
2870     vos::OGuard aGuard(Application::GetSolarMutex());
2871 
2872     return SwUnoCursorHelper::CreateSortDescriptor(true);
2873 }
2874 
sort(const uno::Sequence<beans::PropertyValue> & rDescriptor)2875 void SwXTextTable::sort(const uno::Sequence< beans::PropertyValue >& rDescriptor)
2876 {
2877     vos::OGuard aGuard(Application::GetSolarMutex());
2878     SwSortOptions aSortOpt;
2879     SwFrmFmt* pFmt = GetFrmFmt();
2880     if(pFmt &&
2881         SwUnoCursorHelper::ConvertSortProperties(rDescriptor, aSortOpt))
2882     {
2883         SwTable* pTable = SwTable::FindTable( pFmt );
2884         SwSelBoxes aBoxes;
2885         const SwTableSortBoxes& rTBoxes = pTable->GetTabSortBoxes();
2886         for( sal_uInt16 n = 0; n < rTBoxes.Count(); ++n )
2887         {
2888             SwTableBox* pBox = rTBoxes[ n ];
2889             aBoxes.Insert( pBox );
2890         }
2891         UnoActionContext aContext( pFmt->GetDoc() );
2892         pFmt->GetDoc()->SortTbl(aBoxes, aSortOpt);
2893     }
2894 }
2895 
autoFormat(const OUString & aName)2896 void SwXTextTable::autoFormat(const OUString& aName)
2897 {
2898     vos::OGuard aGuard(Application::GetSolarMutex());
2899     SwFrmFmt* pFmt = GetFrmFmt();
2900     if(pFmt)
2901     {
2902         SwTable* pTable = SwTable::FindTable( pFmt );
2903         if(!pTable->IsTblComplex())
2904         {
2905 
2906             String sAutoFmtName(aName);
2907             SwTableAutoFmtTbl aAutoFmtTbl;
2908             aAutoFmtTbl.Load();
2909             for( sal_uInt16 i = aAutoFmtTbl.Count(); i; )
2910                 if( sAutoFmtName == aAutoFmtTbl[ --i ]->GetName() )
2911                 {
2912                     SwSelBoxes aBoxes;
2913                     const SwTableSortBoxes& rTBoxes = pTable->GetTabSortBoxes();
2914                     for( sal_uInt16 n = 0; n < rTBoxes.Count(); ++n )
2915                     {
2916                         SwTableBox* pBox = rTBoxes[ n ];
2917                         aBoxes.Insert( pBox );
2918                     }
2919                     UnoActionContext aContext( pFmt->GetDoc() );
2920                     pFmt->GetDoc()->SetTableAutoFmt( aBoxes, *aAutoFmtTbl[i] );
2921                     break;
2922                 }
2923         }
2924     }
2925     else
2926         throw uno::RuntimeException();
2927 }
2928 
getPropertySetInfo(void)2929 uno::Reference< beans::XPropertySetInfo >  SwXTextTable::getPropertySetInfo(void)
2930 {
2931     static uno::Reference< beans::XPropertySetInfo >  xRef = m_pPropSet->getPropertySetInfo();
2932     return xRef;
2933 }
2934 
setPropertyValue(const OUString & rPropertyName,const uno::Any & aValue)2935 void SwXTextTable::setPropertyValue(const OUString& rPropertyName,
2936                                                     const uno::Any& aValue)
2937 {
2938     vos::OGuard aGuard(Application::GetSolarMutex());
2939     SwFrmFmt* pFmt = GetFrmFmt();
2940     if(!aValue.hasValue())
2941         throw lang::IllegalArgumentException();
2942     const SfxItemPropertySimpleEntry* pEntry =
2943                                 m_pPropSet->getPropertyMap()->getByName(rPropertyName);
2944     if( !pEntry )
2945         throw lang::IllegalArgumentException();
2946     if(pFmt)
2947     {
2948         if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
2949             throw beans::PropertyVetoException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property is read-only: " ) ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
2950 
2951         if(0xFF == pEntry->nMemberId)
2952         {
2953             lcl_SetSpecialProperty(pFmt, pEntry, aValue);
2954         }
2955         else
2956         {
2957             switch(pEntry->nWID)
2958             {
2959                 case UNO_NAME_TABLE_NAME :
2960                 {
2961                     ::rtl::OUString sName;
2962                     aValue >>= sName;
2963                     setName( sName );
2964                 }
2965                 break;
2966                 case FN_UNO_RANGE_ROW_LABEL:
2967                 {
2968                     sal_Bool bTmp = *(sal_Bool*)aValue.getValue();
2969                     if(bFirstRowAsLabel != bTmp)
2970                     {
2971                         aChartLstnrCntnr.ChartDataChanged();
2972                         bFirstRowAsLabel = bTmp;
2973                     }
2974                 }
2975                 break;
2976                 case FN_UNO_RANGE_COL_LABEL:
2977                 {
2978                     sal_Bool bTmp = *(sal_Bool*)aValue.getValue();
2979                     if(bFirstColumnAsLabel != bTmp)
2980                     {
2981                         aChartLstnrCntnr.ChartDataChanged();
2982                         bFirstColumnAsLabel = bTmp;
2983                     }
2984                 }
2985                 break;
2986                 case FN_UNO_TABLE_BORDER:
2987                 {
2988                     const table::TableBorder* pBorder =
2989                             (const table::TableBorder* )aValue.getValue();
2990                     if(aValue.getValueType() == ::getCppuType((const table::TableBorder* )0)
2991                         && pBorder)
2992                     {
2993                         SwDoc* pDoc = pFmt->GetDoc();
2994                         SwFrm* pFrm = SwIterator<SwFrm,SwFmt>::FirstElement( *pFmt );
2995                         //Tabellen ohne Layout (unsichtbare Header/Footer )
2996                         if( pFrm )
2997                         {
2998                             lcl_FormatTable(pFmt);
2999                             SwTable* pTable = SwTable::FindTable( pFmt );
3000                             SwTableLines &rLines = pTable->GetTabLines();
3001 
3002 
3003                             // hier muessen die Actions aufgehoben werden
3004                             UnoActionRemoveContext aRemoveContext(pDoc);
3005                             const SwTableBox* pTLBox = lcl_FindCornerTableBox(rLines, true);
3006                             const SwStartNode* pSttNd = pTLBox->GetSttNd();
3007                             SwPosition aPos(*pSttNd);
3008                             // Cursor in die obere linke Zelle des Ranges setzen
3009                             SwUnoCrsr* pUnoCrsr = pDoc->CreateUnoCrsr(aPos, sal_True);
3010                             pUnoCrsr->Move( fnMoveForward, fnGoNode );
3011                             pUnoCrsr->SetRemainInSection( sal_False );
3012 
3013 
3014 
3015                             const SwTableBox* pBRBox = lcl_FindCornerTableBox(rLines, false);
3016                             pUnoCrsr->SetMark();
3017                             pUnoCrsr->GetPoint()->nNode = *pBRBox->GetSttNd();
3018                             pUnoCrsr->Move( fnMoveForward, fnGoNode );
3019                             SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
3020                             pCrsr->MakeBoxSels();
3021 
3022                             SfxItemSet aSet(pDoc->GetAttrPool(),
3023                                             RES_BOX, RES_BOX,
3024                                             SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
3025                                             0);
3026 
3027                             SvxBoxItem aBox( RES_BOX );
3028                             SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER );
3029                             SvxBorderLine aLine;
3030 
3031                             sal_Bool bSet = lcl_LineToSvxLine(pBorder->TopLine, aLine);
3032                             aBox.SetLine(bSet ? &aLine : 0, BOX_LINE_TOP);
3033                             aBoxInfo.SetValid(VALID_TOP, pBorder->IsTopLineValid);
3034 
3035                             bSet = lcl_LineToSvxLine(pBorder->BottomLine, aLine);
3036                             aBox.SetLine(bSet ? &aLine : 0, BOX_LINE_BOTTOM);
3037                             aBoxInfo.SetValid(VALID_BOTTOM, pBorder->IsBottomLineValid);
3038 
3039                             bSet = lcl_LineToSvxLine(pBorder->LeftLine, aLine);
3040                             aBox.SetLine(bSet ? &aLine : 0, BOX_LINE_LEFT);
3041                             aBoxInfo.SetValid(VALID_LEFT, pBorder->IsLeftLineValid);
3042 
3043                             bSet = lcl_LineToSvxLine(pBorder->RightLine, aLine);
3044                             aBox.SetLine(bSet ? &aLine : 0, BOX_LINE_RIGHT);
3045                             aBoxInfo.SetValid(VALID_RIGHT, pBorder->IsRightLineValid);
3046 
3047                             bSet = lcl_LineToSvxLine(pBorder->HorizontalLine, aLine);
3048                             aBoxInfo.SetLine(bSet ? &aLine : 0, BOXINFO_LINE_HORI);
3049                             aBoxInfo.SetValid(VALID_HORI, pBorder->IsHorizontalLineValid);
3050 
3051                             bSet = lcl_LineToSvxLine(pBorder->VerticalLine, aLine);
3052                             aBoxInfo.SetLine(bSet ? &aLine : 0, BOXINFO_LINE_VERT);
3053                             aBoxInfo.SetValid(VALID_VERT, pBorder->IsVerticalLineValid);
3054 
3055                             aBox.SetDistance((sal_uInt16)MM100_TO_TWIP(pBorder->Distance));
3056                             aBoxInfo.SetValid(VALID_DISTANCE, pBorder->IsDistanceValid);
3057 
3058                             aSet.Put(aBox);
3059                             aSet.Put(aBoxInfo);
3060 
3061                             pDoc->SetTabBorders(*pCrsr, aSet);
3062                             delete pUnoCrsr;
3063                         }
3064                     }
3065                 }
3066                 break;
3067                 case FN_UNO_TABLE_BORDER_DISTANCES:
3068                 {
3069                     table::TableBorderDistances aTableBorderDistances;
3070                     if( !(aValue >>= aTableBorderDistances) ||
3071                         (!aTableBorderDistances.IsLeftDistanceValid &&
3072                         !aTableBorderDistances.IsRightDistanceValid &&
3073                         !aTableBorderDistances.IsTopDistanceValid &&
3074                         !aTableBorderDistances.IsBottomDistanceValid ))
3075                         break;
3076 
3077                     sal_uInt16 nLeftDistance =     MM100_TO_TWIP_UNSIGNED( aTableBorderDistances.LeftDistance);
3078                     sal_uInt16 nRightDistance =    MM100_TO_TWIP_UNSIGNED( aTableBorderDistances.RightDistance);
3079                     sal_uInt16 nTopDistance =      MM100_TO_TWIP_UNSIGNED( aTableBorderDistances.TopDistance);
3080                     sal_uInt16 nBottomDistance =   MM100_TO_TWIP_UNSIGNED( aTableBorderDistances.BottomDistance);
3081                     SwDoc* pDoc = pFmt->GetDoc();
3082                     SwTable* pTable = SwTable::FindTable( pFmt );
3083                     SwTableLines &rLines = pTable->GetTabLines();
3084                     pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_START, NULL);
3085                     for(sal_uInt16 i = 0; i < rLines.Count(); i++)
3086                     {
3087                         SwTableLine* pLine = rLines.GetObject(i);
3088                         SwTableBoxes& rBoxes = pLine->GetTabBoxes();
3089                         for(sal_uInt16 k = 0; k < rBoxes.Count(); k++)
3090                         {
3091                             SwTableBox* pBox = rBoxes.GetObject(k);
3092                             const SwFrmFmt* pBoxFmt = pBox->GetFrmFmt();
3093                             const SvxBoxItem& rBox = pBoxFmt->GetBox();
3094                             if(
3095                                 (aTableBorderDistances.IsLeftDistanceValid && nLeftDistance !=   rBox.GetDistance( BOX_LINE_LEFT )) ||
3096                                 (aTableBorderDistances.IsRightDistanceValid && nRightDistance !=  rBox.GetDistance( BOX_LINE_RIGHT )) ||
3097                                 (aTableBorderDistances.IsTopDistanceValid && nTopDistance !=    rBox.GetDistance( BOX_LINE_TOP )) ||
3098                                 (aTableBorderDistances.IsBottomDistanceValid && nBottomDistance != rBox.GetDistance( BOX_LINE_BOTTOM )))
3099                             {
3100                                 SvxBoxItem aSetBox( rBox );
3101                                 SwFrmFmt* pSetBoxFmt = pBox->ClaimFrmFmt();
3102                                 if( aTableBorderDistances.IsLeftDistanceValid )
3103                                     aSetBox.SetDistance( nLeftDistance, BOX_LINE_LEFT );
3104                                 if( aTableBorderDistances.IsRightDistanceValid )
3105                                     aSetBox.SetDistance( nRightDistance, BOX_LINE_RIGHT );
3106                                 if( aTableBorderDistances.IsTopDistanceValid )
3107                                     aSetBox.SetDistance( nTopDistance, BOX_LINE_TOP );
3108                                 if( aTableBorderDistances.IsBottomDistanceValid )
3109                                     aSetBox.SetDistance( nBottomDistance, BOX_LINE_BOTTOM );
3110                                 pDoc->SetAttr( aSetBox, *pSetBoxFmt );
3111                             }
3112                         }
3113                     }
3114                     pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_END, NULL);
3115                 }
3116                 break;
3117                 case FN_UNO_TABLE_COLUMN_SEPARATORS:
3118                 {
3119                     UnoActionContext aContext(pFmt->GetDoc());
3120                     SwTable* pTable = SwTable::FindTable( pFmt );
3121                     lcl_SetTblSeparators(aValue, pTable, pTable->GetTabLines()[0]->GetTabBoxes()[0], sal_False, pFmt->GetDoc());
3122                 }
3123                 break;
3124                 case FN_UNO_TABLE_COLUMN_RELATIVE_SUM:/*_readonly_*/ break;
3125                 default:
3126                 {
3127                     SwAttrSet aSet(pFmt->GetAttrSet());
3128                     m_pPropSet->setPropertyValue(*pEntry, aValue, aSet);
3129                     pFmt->GetDoc()->SetAttr(aSet, *pFmt);
3130                 }
3131             }
3132         }
3133     }
3134     else if(bIsDescriptor)
3135     {
3136         String aPropertyName(rPropertyName);
3137         pTableProps->SetProperty( pEntry->nWID, pEntry->nMemberId, aValue);
3138     }
3139     else
3140         throw uno::RuntimeException();
3141 }
3142 
getPropertyValue(const OUString & rPropertyName)3143 uno::Any SwXTextTable::getPropertyValue(const OUString& rPropertyName)
3144 {
3145     vos::OGuard aGuard(Application::GetSolarMutex());
3146     uno::Any aRet;
3147     SwFrmFmt* pFmt = GetFrmFmt();
3148     const SfxItemPropertySimpleEntry* pEntry =
3149                                 m_pPropSet->getPropertyMap()->getByName(rPropertyName);
3150     if(pFmt)
3151     {
3152         if (!pEntry)
3153             throw beans::UnknownPropertyException(OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Unknown property: " ) ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
3154 
3155         if(0xFF == pEntry->nMemberId)
3156         {
3157             aRet = lcl_GetSpecialProperty(pFmt, pEntry );
3158         }
3159         else
3160         {
3161             switch(pEntry->nWID)
3162             {
3163                 case UNO_NAME_TABLE_NAME:
3164                 {
3165                     aRet <<= getName();
3166                 }
3167                 break;
3168                 case  FN_UNO_ANCHOR_TYPES:
3169                 case  FN_UNO_TEXT_WRAP:
3170                 case  FN_UNO_ANCHOR_TYPE:
3171                     ::sw::GetDefaultTextContentValue(
3172                             aRet, OUString(), pEntry->nWID);
3173                 break;
3174                 case FN_UNO_RANGE_ROW_LABEL:
3175                 {
3176                     sal_Bool bTemp = bFirstRowAsLabel;
3177                     aRet.setValue(&bTemp, ::getCppuBooleanType());
3178                 }
3179                 break;
3180                 case FN_UNO_RANGE_COL_LABEL:
3181                 {
3182                     sal_Bool bTemp = bFirstColumnAsLabel;
3183                     aRet.setValue(&bTemp, ::getCppuBooleanType());
3184                 }
3185                 break;
3186                 case FN_UNO_TABLE_BORDER:
3187                 {
3188                     SwDoc* pDoc = pFmt->GetDoc();
3189                     SwFrm* pFrm = SwIterator<SwFrm,SwFmt>::FirstElement( *pFmt );
3190                     //Tabellen ohne Layout (unsichtbare Header/Footer )
3191                     if( pFrm )
3192                     {
3193                         lcl_FormatTable(pFmt);
3194                         SwTable* pTable = SwTable::FindTable( pFmt );
3195                         SwTableLines &rLines = pTable->GetTabLines();
3196 
3197                         // hier muessen die Actions aufgehoben werden
3198                         UnoActionRemoveContext aRemoveContext(pDoc);
3199                         const SwTableBox* pTLBox = lcl_FindCornerTableBox(rLines, true);
3200                         const SwStartNode* pSttNd = pTLBox->GetSttNd();
3201                         SwPosition aPos(*pSttNd);
3202                         // Cursor in die obere linke Zelle des Ranges setzen
3203                         SwUnoCrsr* pUnoCrsr = pDoc->CreateUnoCrsr(aPos, sal_True);
3204                         pUnoCrsr->Move( fnMoveForward, fnGoNode );
3205                         pUnoCrsr->SetRemainInSection( sal_False );
3206 
3207                         const SwTableBox* pBRBox = lcl_FindCornerTableBox(rLines, false);
3208                         pUnoCrsr->SetMark();
3209                         const SwStartNode* pLastNd = pBRBox->GetSttNd();
3210                         pUnoCrsr->GetPoint()->nNode = *pLastNd;
3211 
3212                         pUnoCrsr->Move( fnMoveForward, fnGoNode );
3213                         SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
3214                         pCrsr->MakeBoxSels();
3215 
3216                         SfxItemSet aSet(pDoc->GetAttrPool(),
3217                                         RES_BOX, RES_BOX,
3218                                         SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
3219                                         0);
3220                         aSet.Put(SvxBoxInfoItem( SID_ATTR_BORDER_INNER ));
3221                         pDoc->GetTabBorders(*pCrsr, aSet);
3222                         const SvxBoxInfoItem& rBoxInfoItem = (const SvxBoxInfoItem&)aSet.Get(SID_ATTR_BORDER_INNER);
3223                         const SvxBoxItem& rBox = (const SvxBoxItem&)aSet.Get(RES_BOX);
3224 
3225                         table::TableBorder aTableBorder;
3226                         aTableBorder.TopLine                = lcl_SvxLineToLine(rBox.GetTop());
3227                         aTableBorder.IsTopLineValid         = rBoxInfoItem.IsValid(VALID_TOP);
3228                         aTableBorder.BottomLine             = lcl_SvxLineToLine(rBox.GetBottom());
3229                         aTableBorder.IsBottomLineValid      = rBoxInfoItem.IsValid(VALID_BOTTOM);
3230                         aTableBorder.LeftLine               = lcl_SvxLineToLine(rBox.GetLeft());
3231                         aTableBorder.IsLeftLineValid        = rBoxInfoItem.IsValid(VALID_LEFT);
3232                         aTableBorder.RightLine              = lcl_SvxLineToLine(rBox.GetRight());
3233                         aTableBorder.IsRightLineValid       = rBoxInfoItem.IsValid(VALID_RIGHT );
3234                         aTableBorder.HorizontalLine         = lcl_SvxLineToLine(rBoxInfoItem.GetHori());
3235                         aTableBorder.IsHorizontalLineValid  = rBoxInfoItem.IsValid(VALID_HORI);
3236                         aTableBorder.VerticalLine           = lcl_SvxLineToLine(rBoxInfoItem.GetVert());
3237                         aTableBorder.IsVerticalLineValid    = rBoxInfoItem.IsValid(VALID_VERT);
3238                         aTableBorder.Distance               = TWIP_TO_MM100_UNSIGNED( rBox.GetDistance() );
3239                         aTableBorder.IsDistanceValid        = rBoxInfoItem.IsValid(VALID_DISTANCE);
3240                         aRet.setValue(&aTableBorder, ::getCppuType((const table::TableBorder*)0));
3241                         delete pUnoCrsr;
3242                     }
3243                 }
3244                 break;
3245                 case FN_UNO_TABLE_BORDER_DISTANCES :
3246                 {
3247                     table::TableBorderDistances aTableBorderDistances( 0, sal_True, 0, sal_True, 0, sal_True, 0, sal_True ) ;
3248                     SwTable* pTable = SwTable::FindTable( pFmt );
3249                     const SwTableLines &rLines = pTable->GetTabLines();
3250                     bool bFirst = true;
3251                     sal_uInt16 nLeftDistance = 0;
3252                     sal_uInt16 nRightDistance = 0;
3253                     sal_uInt16 nTopDistance = 0;
3254                     sal_uInt16 nBottomDistance = 0;
3255 
3256                     for(sal_uInt16 i = 0; i < rLines.Count(); i++)
3257                     {
3258                         const SwTableLine* pLine = rLines.GetObject(i);
3259                         const SwTableBoxes& rBoxes = pLine->GetTabBoxes();
3260                         for(sal_uInt16 k = 0; k < rBoxes.Count(); k++)
3261                         {
3262                             const SwTableBox* pBox = rBoxes.GetObject(k);
3263                             SwFrmFmt* pBoxFmt = pBox->GetFrmFmt();
3264                             const SvxBoxItem& rBox = pBoxFmt->GetBox();
3265                             if( bFirst )
3266                             {
3267                                 nLeftDistance =     TWIP_TO_MM100_UNSIGNED( rBox.GetDistance( BOX_LINE_LEFT   ));
3268                                 nRightDistance =    TWIP_TO_MM100_UNSIGNED( rBox.GetDistance( BOX_LINE_RIGHT  ));
3269                                 nTopDistance =      TWIP_TO_MM100_UNSIGNED( rBox.GetDistance( BOX_LINE_TOP    ));
3270                                 nBottomDistance =   TWIP_TO_MM100_UNSIGNED( rBox.GetDistance( BOX_LINE_BOTTOM ));
3271                                 bFirst = false;
3272                             }
3273                             else
3274                             {
3275                                 if( aTableBorderDistances.IsLeftDistanceValid &&
3276                                     nLeftDistance != TWIP_TO_MM100_UNSIGNED( rBox.GetDistance( BOX_LINE_LEFT   )))
3277                                     aTableBorderDistances.IsLeftDistanceValid = sal_False;
3278                                 if( aTableBorderDistances.IsRightDistanceValid &&
3279                                     nRightDistance != TWIP_TO_MM100_UNSIGNED( rBox.GetDistance( BOX_LINE_RIGHT   )))
3280                                     aTableBorderDistances.IsRightDistanceValid = sal_False;
3281                                 if( aTableBorderDistances.IsTopDistanceValid &&
3282                                     nTopDistance != TWIP_TO_MM100_UNSIGNED( rBox.GetDistance( BOX_LINE_TOP   )))
3283                                     aTableBorderDistances.IsTopDistanceValid = sal_False;
3284                                 if( aTableBorderDistances.IsBottomDistanceValid &&
3285                                     nBottomDistance != TWIP_TO_MM100_UNSIGNED( rBox.GetDistance( BOX_LINE_BOTTOM   )))
3286                                     aTableBorderDistances.IsBottomDistanceValid = sal_False;
3287                             }
3288 
3289                         }
3290                         if( !aTableBorderDistances.IsLeftDistanceValid &&
3291                                 !aTableBorderDistances.IsRightDistanceValid &&
3292                                 !aTableBorderDistances.IsTopDistanceValid &&
3293                                 !aTableBorderDistances.IsBottomDistanceValid )
3294                             break;
3295                     }
3296                     if( aTableBorderDistances.IsLeftDistanceValid)
3297                         aTableBorderDistances.LeftDistance = nLeftDistance;
3298                     if( aTableBorderDistances.IsRightDistanceValid)
3299                         aTableBorderDistances.RightDistance  = nRightDistance;
3300                     if( aTableBorderDistances.IsTopDistanceValid)
3301                         aTableBorderDistances.TopDistance    = nTopDistance;
3302                     if( aTableBorderDistances.IsBottomDistanceValid)
3303                         aTableBorderDistances.BottomDistance = nBottomDistance;
3304 
3305                     aRet <<= aTableBorderDistances;
3306                 }
3307                 break;
3308                 case FN_UNO_TABLE_COLUMN_SEPARATORS:
3309                 {
3310                     SwTable* pTable = SwTable::FindTable( pFmt );
3311                     lcl_GetTblSeparators(aRet, pTable, pTable->GetTabLines()[0]->GetTabBoxes()[0], sal_False);
3312                 }
3313                 break;
3314                 case FN_UNO_TABLE_COLUMN_RELATIVE_SUM:
3315                     aRet <<= (sal_Int16) UNO_TABLE_COLUMN_SUM;
3316                 break;
3317                 case RES_ANCHOR:
3318                     //AnchorType ist readonly und maybevoid und wird nicht geliefert
3319                 break;
3320                 case FN_UNO_TEXT_SECTION:
3321                 {
3322                     SwTable* pTable = SwTable::FindTable( pFmt );
3323                     SwTableNode* pTblNode = pTable->GetTableNode();
3324                     SwSectionNode* pSectionNode =  pTblNode->FindSectionNode();
3325                     if(pSectionNode)
3326                     {
3327                         const SwSection& rSect = pSectionNode->GetSection();
3328                         uno::Reference< text::XTextSection >  xSect =
3329                                         SwXTextSections::GetObject( *rSect.GetFmt() );
3330                         aRet <<= xSect;
3331                     }
3332                 }
3333                 break;
3334                 default:
3335                 {
3336                     const SwAttrSet& rSet = pFmt->GetAttrSet();
3337                     m_pPropSet->getPropertyValue(*pEntry, rSet, aRet);
3338                 }
3339             }
3340         }
3341     }
3342     else if(bIsDescriptor)
3343     {
3344         const uno::Any* pAny = 0;
3345         String aPropertyName(rPropertyName);
3346         if(!pTableProps->GetProperty(pEntry->nWID, pEntry->nMemberId, pAny))
3347             throw lang::IllegalArgumentException();
3348         else if(pAny)
3349             aRet = *pAny;
3350     }
3351     else
3352         throw uno::RuntimeException();
3353     return aRet;
3354 }
3355 
addPropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)3356 void SwXTextTable::addPropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
3357 {
3358     DBG_WARNING("not implemented");
3359 }
3360 
removePropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)3361 void SwXTextTable::removePropertyChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*xListener*/)
3362 {
3363     DBG_WARNING("not implemented");
3364 }
3365 
addVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)3366 void SwXTextTable::addVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
3367 {
3368     DBG_WARNING("not implemented");
3369 }
3370 
removeVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)3371 void SwXTextTable::removeVetoableChangeListener(const OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*xListener*/)
3372 {
3373     DBG_WARNING("not implemented");
3374 }
3375 
getName(void)3376 OUString SwXTextTable::getName(void)
3377 {
3378     vos::OGuard aGuard(Application::GetSolarMutex());
3379     String sRet;
3380     SwFrmFmt* pFmt = GetFrmFmt();
3381     if(!pFmt && !bIsDescriptor)
3382         throw uno::RuntimeException();
3383     if(pFmt)
3384     {
3385         sRet = pFmt->GetName();
3386     }
3387     else
3388         sRet = m_sTableName;
3389     return sRet;
3390 }
3391 
setName(const OUString & rName)3392 void SwXTextTable::setName(const OUString& rName)
3393 {
3394     vos::OGuard aGuard(Application::GetSolarMutex());
3395     SwFrmFmt* pFmt = GetFrmFmt();
3396     String sNewTblName(rName);
3397     if((!pFmt && !bIsDescriptor) ||
3398         !sNewTblName.Len() ||
3399             STRING_NOTFOUND != sNewTblName.Search('.') ||
3400                 STRING_NOTFOUND != sNewTblName.Search(' ')  )
3401         throw uno::RuntimeException();
3402 
3403     if(pFmt)
3404     {
3405         const String aOldName( pFmt->GetName() );
3406         sal_Bool bNameFound = sal_False;
3407         SwFrmFmt* pTmpFmt;
3408         const SwFrmFmts* pTbl = pFmt->GetDoc()->GetTblFrmFmts();
3409         for( sal_uInt16 i = pTbl->Count(); i; )
3410             if( !( pTmpFmt = (*pTbl)[ --i ] )->IsDefault() &&
3411                 pTmpFmt->GetName() == sNewTblName &&
3412                             pFmt->GetDoc()->IsUsed( *pTmpFmt ))
3413             {
3414                 bNameFound = sal_True;
3415                 break;
3416             }
3417 
3418         if(bNameFound)
3419         {
3420             throw uno::RuntimeException();
3421         }
3422         pFmt->SetName( sNewTblName );
3423 
3424 
3425         SwStartNode *pStNd;
3426         SwNodeIndex aIdx( *pFmt->GetDoc()->GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
3427         while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
3428         {
3429             aIdx++;
3430             SwNode *const pNd = & aIdx.GetNode();
3431             if ( pNd->IsOLENode() &&
3432                 aOldName == ((SwOLENode*)pNd)->GetChartTblName() )
3433             {
3434                 ((SwOLENode*)pNd)->SetChartTblName( sNewTblName );
3435 
3436                 ((SwOLENode*)pNd)->GetOLEObj();
3437 
3438                 SwTable* pTable = SwTable::FindTable( pFmt );
3439                 //TL_CHART2: chart needs to be notfied about name changes
3440                 pFmt->GetDoc()->UpdateCharts( pTable->GetFrmFmt()->GetName() );
3441             }
3442             aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
3443         }
3444         pFmt->GetDoc()->SetModified();
3445     }
3446     else
3447         m_sTableName = sNewTblName;
3448 }
3449 
getRowCount(void)3450 sal_uInt16 SwXTextTable::getRowCount(void)
3451 {
3452     vos::OGuard aGuard(Application::GetSolarMutex());
3453     sal_Int16 nRet = 0;
3454     SwFrmFmt* pFmt = GetFrmFmt();
3455     if(pFmt)
3456     {
3457         SwTable* pTable = SwTable::FindTable( pFmt );
3458         if(!pTable->IsTblComplex())
3459         {
3460             nRet = pTable->GetTabLines().Count();
3461         }
3462     }
3463     return nRet;
3464 }
3465 
getColumnCount(void)3466 sal_uInt16 SwXTextTable::getColumnCount(void)
3467 {
3468     vos::OGuard aGuard(Application::GetSolarMutex());
3469     SwFrmFmt* pFmt = GetFrmFmt();
3470     sal_Int16 nRet = 0;
3471     if(pFmt)
3472     {
3473         SwTable* pTable = SwTable::FindTable( pFmt );
3474         if(!pTable->IsTblComplex())
3475         {
3476             SwTableLines& rLines = pTable->GetTabLines();
3477             SwTableLine* pLine = rLines.GetObject(0);
3478             nRet = pLine->GetTabBoxes().Count();
3479         }
3480     }
3481     return nRet;
3482 }
3483 
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)3484 void SwXTextTable::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
3485 {
3486     if(pOld && pOld->Which() == RES_REMOVE_UNO_OBJECT &&
3487         (void*)GetRegisteredIn() == ((SwPtrMsgPoolItem *)pOld)->pObject )
3488             ((SwModify*)GetRegisteredIn())->Remove(this);
3489     else
3490         ClientModify(this, pOld, pNew);
3491     if(!GetRegisteredIn())
3492     {
3493         aLstnrCntnr.Disposing();
3494         aChartLstnrCntnr.Disposing();
3495     }
3496     else
3497         aChartLstnrCntnr.ChartDataChanged();
3498 }
3499 
getImplementationName(void)3500 OUString SAL_CALL SwXTextTable::getImplementationName(void)
3501 {
3502     return C2U("SwXTextTable");
3503 }
3504 
supportsService(const OUString & rServiceName)3505 sal_Bool SwXTextTable::supportsService(const OUString& rServiceName)
3506 {
3507     String sServiceName(rServiceName);
3508     return (sServiceName.EqualsAscii("com.sun.star.document.LinkTarget")  ||
3509             sServiceName.EqualsAscii("com.sun.star.text.TextTable")  ||
3510             sServiceName.EqualsAscii("com.sun.star.text.TextContent") ||
3511             sServiceName.EqualsAscii("com.sun.star.text.TextSortable"));
3512 }
3513 
getSupportedServiceNames(void)3514 uno::Sequence< OUString > SwXTextTable::getSupportedServiceNames(void)
3515 {
3516     uno::Sequence< OUString > aRet(4);
3517     OUString* pArr = aRet.getArray();
3518     pArr[0] = C2U("com.sun.star.document.LinkTarget");
3519     pArr[1] = C2U("com.sun.star.text.TextTable");
3520     pArr[2] = C2U("com.sun.star.text.TextContent");
3521     pArr[2] = C2U("com.sun.star.text.TextSortable");
3522     return aRet;
3523 }
3524 
3525 /******************************************************************
3526  *
3527  ******************************************************************/
3528 
getUnoTunnelId()3529 const uno::Sequence< sal_Int8 > & SwXCellRange::getUnoTunnelId()
3530 {
3531     static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
3532     return aSeq;
3533 }
3534 
getSomething(const uno::Sequence<sal_Int8> & rId)3535 sal_Int64 SAL_CALL SwXCellRange::getSomething( const uno::Sequence< sal_Int8 >& rId )
3536 {
3537     if( rId.getLength() == 16
3538         && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
3539                                         rId.getConstArray(), 16 ) )
3540     {
3541         return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
3542     }
3543     return 0;
3544 }
3545 
3546 TYPEINIT1(SwXCellRange, SwClient);
3547 
getImplementationName(void)3548 OUString SwXCellRange::getImplementationName(void)
3549 {
3550     return C2U("SwXCellRange");
3551 }
3552 
supportsService(const OUString & rServiceName)3553 sal_Bool SwXCellRange::supportsService(const OUString& rServiceName)
3554 {
3555     return
3556         rServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "com.sun.star.text.CellRange" ) ) ||
3557         rServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "com.sun.star.style.CharacterProperties" ) ) ||
3558         rServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "com.sun.star.style.CharacterPropertiesAsian" ) ) ||
3559         rServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "com.sun.star.style.CharacterPropertiesComplex") ) ||
3560         rServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "com.sun.star.style.ParagraphProperties" ) ) ||
3561         rServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "com.sun.star.style.ParagraphPropertiesAsian" ) ) ||
3562         rServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "com.sun.star.style.ParagraphPropertiesComplex" ) );
3563 }
3564 
getSupportedServiceNames(void)3565 uno::Sequence< OUString > SwXCellRange::getSupportedServiceNames(void)
3566 {
3567     uno::Sequence< OUString > aRet(7);
3568     OUString* pArray = aRet.getArray();
3569     pArray[0] = C2U("com.sun.star.text.CellRange");
3570     pArray[1] = C2U("com.sun.star.style.CharacterProperties");
3571     pArray[2] = C2U("com.sun.star.style.CharacterPropertiesAsian");
3572     pArray[3] = C2U("com.sun.star.style.CharacterPropertiesComplex");
3573     pArray[4] = C2U("com.sun.star.style.ParagraphProperties");
3574     pArray[5] = C2U("com.sun.star.style.ParagraphPropertiesAsian");
3575     pArray[6] = C2U("com.sun.star.style.ParagraphPropertiesComplex");
3576     return aRet;
3577 }
3578 
3579 
SwXCellRange(SwUnoCrsr * pCrsr,SwFrmFmt & rFrmFmt,SwRangeDescriptor & rDesc)3580 SwXCellRange::SwXCellRange(SwUnoCrsr* pCrsr, SwFrmFmt& rFrmFmt,
3581     SwRangeDescriptor& rDesc)
3582     :
3583     SwClient(&rFrmFmt),
3584     aCursorDepend(this, pCrsr),
3585     aChartLstnrCntnr((cppu::OWeakObject*)this),
3586     aRgDesc(rDesc),
3587     m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TABLE_RANGE)),
3588     pTblCrsr(pCrsr),
3589     bFirstRowAsLabel(sal_False),
3590     bFirstColumnAsLabel(sal_False)
3591 {
3592     aRgDesc.Normalize();
3593 }
3594 
~SwXCellRange()3595 SwXCellRange::~SwXCellRange()
3596 {
3597     vos::OGuard aGuard(Application::GetSolarMutex());
3598     delete pTblCrsr;
3599 }
3600 
getCellByPosition(sal_Int32 nColumn,sal_Int32 nRow)3601 uno::Reference< table::XCell >  SwXCellRange::getCellByPosition(sal_Int32 nColumn, sal_Int32 nRow)
3602 {
3603     vos::OGuard aGuard(Application::GetSolarMutex());
3604     uno::Reference< table::XCell >  aRet;
3605     SwFrmFmt* pFmt = GetFrmFmt();
3606     if(pFmt)
3607     {
3608         if(nColumn >= 0 && nRow >= 0 &&
3609              getColumnCount() > nColumn && getRowCount() > nRow )
3610         {
3611             SwXCell* pXCell = lcl_CreateXCell(pFmt,
3612                     aRgDesc.nLeft + nColumn, aRgDesc.nTop + nRow);
3613             if(pXCell)
3614                 aRet = pXCell;
3615         }
3616     }
3617     if(!aRet.is())
3618         throw lang::IndexOutOfBoundsException();
3619     return aRet;
3620 }
3621 
getCellRangeByPosition(sal_Int32 nLeft,sal_Int32 nTop,sal_Int32 nRight,sal_Int32 nBottom)3622 uno::Reference< table::XCellRange >  SwXCellRange::getCellRangeByPosition(
3623         sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom)
3624 {
3625     vos::OGuard aGuard(Application::GetSolarMutex());
3626     uno::Reference< table::XCellRange >  aRet;
3627     SwFrmFmt* pFmt = GetFrmFmt();
3628     if(pFmt && getColumnCount() > nRight && getRowCount() > nBottom &&
3629         nLeft <= nRight && nTop <= nBottom
3630         && nLeft >= 0 && nRight >= 0 && nTop >= 0 && nBottom >= 0 )
3631     {
3632         SwTable* pTable = SwTable::FindTable( pFmt );
3633         if(!pTable->IsTblComplex())
3634         {
3635             SwRangeDescriptor aNewDesc;
3636             aNewDesc.nTop    = nTop + aRgDesc.nTop;
3637             aNewDesc.nBottom = nBottom + aRgDesc.nTop;
3638             aNewDesc.nLeft   = nLeft + aRgDesc.nLeft;
3639             aNewDesc.nRight  = nRight + aRgDesc.nLeft;
3640             aNewDesc.Normalize();
3641             String sTLName = lcl_GetCellName(aNewDesc.nLeft, aNewDesc.nTop);
3642             String sBRName = lcl_GetCellName(aNewDesc.nRight, aNewDesc.nBottom);
3643             const SwTableBox* pTLBox = pTable->GetTblBox( sTLName );
3644             if(pTLBox)
3645             {
3646                 // hier muessen die Actions aufgehoben
3647                 UnoActionRemoveContext aRemoveContext(pFmt->GetDoc());
3648                 const SwStartNode* pSttNd = pTLBox->GetSttNd();
3649                 SwPosition aPos(*pSttNd);
3650                 // Cursor in die obere linke Zelle des Ranges setzen
3651                 SwUnoCrsr* pUnoCrsr = pFmt->GetDoc()->CreateUnoCrsr(aPos, sal_True);
3652                 pUnoCrsr->Move( fnMoveForward, fnGoNode );
3653                 pUnoCrsr->SetRemainInSection( sal_False );
3654                 const SwTableBox* pBRBox = pTable->GetTblBox( sBRName );
3655                 if(pBRBox)
3656                 {
3657                     pUnoCrsr->SetMark();
3658                     pUnoCrsr->GetPoint()->nNode = *pBRBox->GetSttNd();
3659                     pUnoCrsr->Move( fnMoveForward, fnGoNode );
3660                     SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
3661                     pCrsr->MakeBoxSels();
3662                     // pUnoCrsr wird uebergeben und nicht geloescht
3663                     SwXCellRange* pCellRange = new SwXCellRange(pUnoCrsr, *pFmt, aNewDesc);
3664                     aRet = pCellRange;
3665                 }
3666                 else
3667                     delete pUnoCrsr;
3668             }
3669         }
3670     }
3671     if(!aRet.is())
3672         throw lang::IndexOutOfBoundsException();
3673     return aRet;
3674 
3675 }
3676 
getCellRangeByName(const OUString & rRange)3677 uno::Reference< table::XCellRange >  SwXCellRange::getCellRangeByName(const OUString& rRange)
3678 {
3679     vos::OGuard aGuard(Application::GetSolarMutex());
3680     String sRange(rRange);
3681     String sTLName(sRange.GetToken(0, ':'));
3682     String sBRName(sRange.GetToken(1, ':'));
3683     if(!sTLName.Len() || !sBRName.Len())
3684         throw uno::RuntimeException();
3685     SwRangeDescriptor aDesc;
3686     aDesc.nTop = aDesc.nLeft = aDesc.nBottom = aDesc.nRight = -1;
3687     lcl_GetCellPosition( sTLName, aDesc.nLeft, aDesc.nTop );
3688     lcl_GetCellPosition( sBRName, aDesc.nRight, aDesc.nBottom );
3689     aDesc.Normalize();
3690     return getCellRangeByPosition(aDesc.nLeft - aRgDesc.nLeft, aDesc.nTop - aRgDesc.nTop,
3691                 aDesc.nRight - aRgDesc.nLeft, aDesc.nBottom - aRgDesc.nTop);
3692 }
3693 
getPropertySetInfo(void)3694 uno::Reference< beans::XPropertySetInfo >  SwXCellRange::getPropertySetInfo(void)
3695 {
3696     static uno::Reference< beans::XPropertySetInfo >  xRef = m_pPropSet->getPropertySetInfo();
3697     return xRef;
3698 }
3699 
setPropertyValue(const OUString & rPropertyName,const uno::Any & aValue)3700 void SwXCellRange::setPropertyValue(const OUString& rPropertyName,
3701     const uno::Any& aValue)
3702 {
3703     vos::OGuard aGuard(Application::GetSolarMutex());
3704     SwFrmFmt* pFmt = GetFrmFmt();
3705     if(pFmt)
3706     {
3707         /* ASK OLIVER
3708         lcl_FormatTable(pFmt);*/
3709         const SfxItemPropertySimpleEntry* pEntry =
3710                                     m_pPropSet->getPropertyMap()->getByName(rPropertyName);
3711         if(pEntry)
3712         {
3713             if ( pEntry->nFlags & beans::PropertyAttribute::READONLY)
3714                 throw beans::PropertyVetoException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property is read-only: " ) ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
3715 
3716             SwDoc* pDoc = pTblCrsr->GetDoc();
3717             {
3718                 // remove actions to enable box selection
3719                 UnoActionRemoveContext aRemoveContext(pDoc);
3720             }
3721             SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(pTblCrsr);
3722             pCrsr->MakeBoxSels();
3723             switch(pEntry->nWID )
3724             {
3725                 case FN_UNO_TABLE_CELL_BACKGROUND:
3726                 {
3727                     SvxBrushItem aBrush( RES_BACKGROUND );
3728                     pDoc->GetBoxAttr( *pTblCrsr, aBrush );
3729                     ((SfxPoolItem&)aBrush).PutValue(aValue, pEntry->nMemberId);
3730                     pDoc->SetBoxAttr( *pTblCrsr, aBrush );
3731 
3732                 }
3733                 break;
3734                 case RES_BOX :
3735                 {
3736                     SfxItemSet aSet(pDoc->GetAttrPool(),
3737                                     RES_BOX, RES_BOX,
3738                                     SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
3739                                     0);
3740                     SvxBoxInfoItem aBoxInfo( SID_ATTR_BORDER_INNER );
3741                     aBoxInfo.SetValid(0xff, sal_False);
3742                     sal_uInt8 nValid = 0;
3743                     switch(pEntry->nMemberId & ~CONVERT_TWIPS)
3744                     {
3745                         case  LEFT_BORDER :             nValid = VALID_LEFT; break;
3746                         case  RIGHT_BORDER:             nValid = VALID_RIGHT; break;
3747                         case  TOP_BORDER  :             nValid = VALID_TOP; break;
3748                         case  BOTTOM_BORDER:            nValid = VALID_BOTTOM; break;
3749                         case  LEFT_BORDER_DISTANCE :
3750                         case  RIGHT_BORDER_DISTANCE:
3751                         case  TOP_BORDER_DISTANCE  :
3752                         case  BOTTOM_BORDER_DISTANCE:
3753                             nValid = VALID_DISTANCE;
3754                         break;
3755                     }
3756                     aBoxInfo.SetValid(nValid, sal_True);
3757 
3758 
3759                     aSet.Put(aBoxInfo);
3760                     pDoc->GetTabBorders(*pCrsr, aSet);
3761 
3762                     aSet.Put(aBoxInfo);
3763                     SvxBoxItem aBoxItem((const SvxBoxItem&)aSet.Get(RES_BOX));
3764                     ((SfxPoolItem&)aBoxItem).PutValue(aValue, pEntry->nMemberId);
3765                     aSet.Put(aBoxItem);
3766                     pDoc->SetTabBorders( *pTblCrsr, aSet );
3767                 }
3768                 break;
3769                 case RES_BOXATR_FORMAT:
3770                 {
3771                     SfxUInt32Item aNumberFormat(RES_BOXATR_FORMAT);
3772                     ((SfxPoolItem&)aNumberFormat).PutValue(aValue, 0);
3773                     pDoc->SetBoxAttr( *pCrsr, aNumberFormat);
3774                 }
3775                 break;
3776                 case FN_UNO_RANGE_ROW_LABEL:
3777                 {
3778                     sal_Bool bTmp = *(sal_Bool*)aValue.getValue();
3779                     if(bFirstRowAsLabel != bTmp)
3780                     {
3781                         aChartLstnrCntnr.ChartDataChanged();
3782                         bFirstRowAsLabel = bTmp;
3783                     }
3784                 }
3785                 break;
3786                 case FN_UNO_RANGE_COL_LABEL:
3787                 {
3788                     sal_Bool bTmp = *(sal_Bool*)aValue.getValue();
3789                     if(bFirstColumnAsLabel != bTmp)
3790                     {
3791                         aChartLstnrCntnr.ChartDataChanged();
3792                         bFirstColumnAsLabel = bTmp;
3793                     }
3794                 }
3795                 break;
3796                 default:
3797                 {
3798                     SfxItemSet aItemSet( pDoc->GetAttrPool(), pEntry->nWID, pEntry->nWID );
3799                     SwUnoCursorHelper::GetCrsrAttr(pCrsr->GetSelRing(),
3800                             aItemSet);
3801 
3802                     if (!SwUnoCursorHelper::SetCursorPropertyValue(
3803                             *pEntry, aValue, pCrsr->GetSelRing(), aItemSet))
3804                     {
3805                         m_pPropSet->setPropertyValue(*pEntry, aValue, aItemSet);
3806                     }
3807                     SwUnoCursorHelper::SetCrsrAttr(pCrsr->GetSelRing(),
3808                             aItemSet, nsSetAttrMode::SETATTR_DEFAULT, true);
3809                 }
3810             }
3811         }
3812         else
3813             throw beans::UnknownPropertyException(OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Unknown property: " ) ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
3814     }
3815 }
3816 
getPropertyValue(const OUString & rPropertyName)3817 uno::Any SwXCellRange::getPropertyValue(const OUString& rPropertyName)
3818 {
3819     vos::OGuard aGuard(Application::GetSolarMutex());
3820     uno::Any aRet;
3821     SwFrmFmt* pFmt = GetFrmFmt();
3822     if(pFmt)
3823     {
3824         /* ASK OLIVER
3825         lcl_FormatTable(pFmt);*/
3826         const SfxItemPropertySimpleEntry* pEntry =
3827                                     m_pPropSet->getPropertyMap()->getByName(rPropertyName);
3828         if(pEntry)
3829         {
3830             switch(pEntry->nWID )
3831             {
3832                 case FN_UNO_TABLE_CELL_BACKGROUND:
3833                 {
3834                     SvxBrushItem aBrush( RES_BACKGROUND );
3835                     if(pTblCrsr->GetDoc()->GetBoxAttr( *pTblCrsr, aBrush ))
3836                         aBrush.QueryValue(aRet, pEntry->nMemberId);
3837 
3838                 }
3839                 break;
3840                 case RES_BOX :
3841                 {
3842                     SwDoc* pDoc = pTblCrsr->GetDoc();
3843                     SfxItemSet aSet(pDoc->GetAttrPool(),
3844                                     RES_BOX, RES_BOX,
3845                                     SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
3846                                     0);
3847                     aSet.Put(SvxBoxInfoItem( SID_ATTR_BORDER_INNER ));
3848                     pDoc->GetTabBorders(*pTblCrsr, aSet);
3849                     const SvxBoxItem& rBoxItem = ((const SvxBoxItem&)aSet.Get(RES_BOX));
3850                     rBoxItem.QueryValue(aRet, pEntry->nMemberId);
3851                 }
3852                 break;
3853                 case RES_BOXATR_FORMAT:
3854                     //GetAttr fuer Tabellenselektion am Doc fehlt noch
3855                     DBG_WARNING("not implemented");
3856                 break;
3857                 case FN_UNO_PARA_STYLE:
3858                 {
3859                     SwFmtColl *const pTmpFmt =
3860                         SwUnoCursorHelper::GetCurTxtFmtColl(*pTblCrsr, sal_False);
3861                     OUString sRet;
3862                     if(pFmt)
3863                         sRet = pTmpFmt->GetName();
3864                     aRet <<= sRet;
3865                 }
3866                 break;
3867                 case FN_UNO_RANGE_ROW_LABEL:
3868                 {
3869                     sal_Bool bTemp = bFirstRowAsLabel;
3870                     aRet.setValue(&bTemp, ::getCppuBooleanType());
3871                 }
3872                 break;
3873                 case FN_UNO_RANGE_COL_LABEL:
3874                 {
3875                     sal_Bool bTemp = bFirstColumnAsLabel;
3876                     aRet.setValue(&bTemp, ::getCppuBooleanType());
3877                 }
3878                 break;
3879                 default:
3880                 {
3881                     SfxItemSet aSet(pTblCrsr->GetDoc()->GetAttrPool(),
3882                         RES_CHRATR_BEGIN,       RES_FRMATR_END -1,
3883                         RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER,
3884                         RES_UNKNOWNATR_CONTAINER, RES_UNKNOWNATR_CONTAINER,
3885                         0L);
3886                     // erstmal die Attribute des Cursors
3887                     SwUnoTableCrsr* pCrsr = dynamic_cast<SwUnoTableCrsr*>(pTblCrsr);
3888                     SwUnoCursorHelper::GetCrsrAttr(pCrsr->GetSelRing(), aSet);
3889                     m_pPropSet->getPropertyValue(*pEntry, aSet, aRet);
3890                 }
3891             }
3892         }
3893         else
3894            throw beans::UnknownPropertyException(OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Unknown property: " ) ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) );
3895     }
3896     return aRet;
3897 }
3898 
addPropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)3899 void SwXCellRange::addPropertyChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
3900 {
3901     DBG_WARNING("not implemented");
3902 }
3903 
removePropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)3904 void SwXCellRange::removePropertyChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
3905 {
3906     DBG_WARNING("not implemented");
3907 }
3908 
addVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)3909 void SwXCellRange::addVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
3910 {
3911     DBG_WARNING("not implemented");
3912 }
3913 
removeVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)3914 void SwXCellRange::removeVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
3915 {
3916     DBG_WARNING("not implemented");
3917 }
3918 
GetDataSequence(uno::Sequence<uno::Any> * pAnySeq,uno::Sequence<OUString> * pTxtSeq,uno::Sequence<double> * pDblSeq,sal_Bool bForceNumberResults)3919 void SwXCellRange::GetDataSequence(
3920         uno::Sequence< uno::Any >   *pAnySeq,   //-> first pointer != 0 is used
3921         uno::Sequence< OUString >   *pTxtSeq,   //-> as output sequence
3922         uno::Sequence< double >     *pDblSeq,   //-> (previous data gets overwritten)
3923         sal_Bool bForceNumberResults )          //-> when 'true' requires to make an
3924                                                 // extra effort to return a value different
3925                                                 // from 0 even if the cell is formatted to text
3926 {
3927     vos::OGuard aGuard(Application::GetSolarMutex());
3928 
3929     // compare to SwXCellRange::getDataArray (note different return types though)
3930 
3931     sal_Int16 nRowCount = getRowCount();
3932     sal_Int16 nColCount = getColumnCount();
3933     //
3934     if(!nRowCount || !nColCount)
3935     {
3936         uno::RuntimeException aRuntime;
3937         aRuntime.Message = C2U("Table too complex");
3938         throw aRuntime;
3939     }
3940 
3941     sal_Int32 nSize = nRowCount * nColCount;
3942     if (pAnySeq)
3943         pAnySeq->realloc( nSize );
3944     else if (pTxtSeq)
3945         pTxtSeq->realloc( nSize );
3946     else if (pDblSeq)
3947         pDblSeq->realloc( nSize );
3948     else
3949     {
3950         DBG_ERROR( "argument missing" );
3951         return;
3952     }
3953     uno::Any   *pAnyData = pAnySeq ? pAnySeq->getArray() : 0;
3954     OUString   *pTxtData = pTxtSeq ? pTxtSeq->getArray() : 0;
3955     double     *pDblData = pDblSeq ? pDblSeq->getArray() : 0;
3956 
3957     sal_Int32 nDtaCnt = 0;
3958     SwFrmFmt* pFmt = GetFrmFmt();
3959     if(pFmt)
3960     {
3961         double fNan;
3962         ::rtl::math::setNan( & fNan );
3963 
3964         uno::Reference< table::XCell > xCellRef;
3965         for(sal_uInt16 nRow = 0; nRow < nRowCount; nRow++)
3966         {
3967             for(sal_uInt16 nCol = 0; nCol < nColCount; nCol++)
3968             {
3969                 SwXCell * pXCell = lcl_CreateXCell(pFmt,
3970                                     aRgDesc.nLeft + nCol,
3971                                     aRgDesc.nTop + nRow);
3972                 //! keep (additional) reference to object to prevent implicit destruction
3973                 //! in following UNO calls (when object will get referenced)
3974                 xCellRef = pXCell;
3975                 SwTableBox * pBox = pXCell ? pXCell->GetTblBox() : 0;
3976                 if(!pBox)
3977                 {
3978                     throw uno::RuntimeException();
3979                 }
3980                 else
3981                 {
3982                     if (pAnyData)
3983                     {
3984                         // check if table box value item is set
3985                         sal_Bool bIsNum = pBox->GetFrmFmt()->GetItemState( RES_BOXATR_VALUE, sal_False ) == SFX_ITEM_SET;
3986                         //sal_uLong nNdPos = pBox->IsValidNumTxtNd( sal_True );
3987                         if (!bIsNum/* && ULONG_MAX == nNdPos*/)
3988                             pAnyData[nDtaCnt++] <<= lcl_getString(*pXCell);
3989                         else
3990                             pAnyData[nDtaCnt++] <<= lcl_getValue(*pXCell);
3991                     }
3992                     else if (pTxtData)
3993                         pTxtData[nDtaCnt++] = lcl_getString(*pXCell);
3994                     else if (pDblData)
3995                     {
3996                         double fVal = fNan;
3997                         if (!bForceNumberResults || table::CellContentType_TEXT != pXCell->getType())
3998                             fVal = lcl_getValue(*pXCell);
3999                         else
4000                         {
4001                             DBG_ASSERT( table::CellContentType_TEXT == pXCell->getType(),
4002                                     "this branch of 'if' is only for text formatted cells" );
4003 
4004                             // now we'll try to get a useful numerical value
4005                             // from the text in the cell...
4006 
4007                             sal_uInt32 nFIndex;
4008                             SvNumberFormatter* pNumFormatter = pTblCrsr->GetDoc()->GetNumberFormatter();
4009 
4010                             // look for SwTblBoxNumFormat value in parents as well
4011                             const SfxPoolItem* pItem;
4012                             SwFrmFmt *pBoxFmt = pXCell->GetTblBox()->GetFrmFmt();
4013                             SfxItemState eState = pBoxFmt->GetAttrSet().GetItemState(RES_BOXATR_FORMAT, sal_True, &pItem);
4014 
4015                             if (eState == SFX_ITEM_SET)
4016                             {
4017                                 // please note that the language of the numberformat
4018                                 // is implicitly coded into the below value as well
4019                                 nFIndex = ((SwTblBoxNumFormat*)pItem)->GetValue();
4020 
4021                                 // since the current value indicates a text format but the call
4022                                 // to 'IsNumberFormat' below won't work for text formats
4023                                 // we need to get rid of the part that indicates the text format.
4024                                 // According to ER this can be done like this:
4025                                 nFIndex -= (nFIndex % SV_COUNTRY_LANGUAGE_OFFSET);
4026                             }
4027                             else
4028                             {
4029                                 // system language is probably not the best possible choice
4030                                 // but since we have to guess anyway (because the language of at
4031                                 // the text is NOT the one used for the number format!)
4032                                 // it is at least conform to to what is used in
4033                                 // SwTableShell::Execute when
4034                                 // SID_ATTR_NUMBERFORMAT_VALUE is set...
4035                                 LanguageType eLang = LANGUAGE_SYSTEM;
4036                                 nFIndex = pNumFormatter->GetStandardIndex( eLang );
4037                             }
4038 
4039                             OUString aTxt( lcl_getString(*pXCell) );
4040                             double fTmp;
4041                             if (pNumFormatter->IsNumberFormat( aTxt, nFIndex, fTmp ))
4042                                 fVal = fTmp;
4043                         }
4044                         pDblData[nDtaCnt++] = fVal;
4045                     }
4046                     else {
4047                         DBG_ERROR( "output sequence missing" );
4048                     }
4049                 }
4050             }
4051         }
4052     }
4053     DBG_ASSERT( nDtaCnt == nSize, "size mismatch. Invalid cell range?" );
4054     if (pAnySeq)
4055         pAnySeq->realloc( nDtaCnt );
4056     else if (pTxtSeq)
4057         pTxtSeq->realloc( nDtaCnt );
4058     else if (pDblSeq)
4059         pDblSeq->realloc( nDtaCnt );
4060 }
4061 
getDataArray()4062 uno::Sequence< uno::Sequence< uno::Any > > SAL_CALL SwXCellRange::getDataArray()
4063 {
4064     // see SwXCellRange::getData also
4065     // also see SwXCellRange::GetDataSequence
4066 
4067     vos::OGuard aGuard(Application::GetSolarMutex());
4068     sal_Int16 nRowCount = getRowCount();
4069     sal_Int16 nColCount = getColumnCount();
4070     //
4071     if(!nRowCount || !nColCount)
4072     {
4073         uno::RuntimeException aRuntime;
4074         aRuntime.Message = C2U("Table too complex");
4075         throw aRuntime;
4076     }
4077     uno::Sequence< uno::Sequence< uno::Any > > aRowSeq(nRowCount);
4078     SwFrmFmt* pFmt = GetFrmFmt();
4079     if(pFmt)
4080     {
4081         uno::Sequence< uno::Any >* pRowArray = aRowSeq.getArray();
4082         uno::Reference< table::XCell > xCellRef;
4083         for(sal_uInt16 nRow = 0; nRow < nRowCount; nRow++)
4084         {
4085             uno::Sequence< uno::Any > aColSeq(nColCount);
4086             uno::Any * pColArray = aColSeq.getArray();
4087             for(sal_uInt16 nCol = 0; nCol < nColCount; nCol++)
4088             {
4089                 SwXCell * pXCell = lcl_CreateXCell(pFmt,
4090                                     aRgDesc.nLeft + nCol,
4091                                     aRgDesc.nTop + nRow);
4092                 //! keep (additional) reference to object to prevent implicit destruction
4093                 //! in following UNO calls (when object will get referenced)
4094                 xCellRef = pXCell;
4095                 SwTableBox * pBox = pXCell ? pXCell->GetTblBox() : 0;
4096                 if(!pBox)
4097                 {
4098                     throw uno::RuntimeException();
4099                 }
4100                 else
4101                 {
4102                     // check if table box value item is set
4103                     SwFrmFmt* pBoxFmt = pBox->GetFrmFmt();
4104                     sal_Bool bIsNum = pBoxFmt->GetItemState( RES_BOXATR_VALUE, sal_False ) == SFX_ITEM_SET;
4105                     //const SfxPoolItem* pItem;
4106                     //SwDoc* pDoc = pXCell->GetDoc();
4107                     //sal_Bool bIsText = (SFX_ITEM_SET != pBoxFmt->GetAttrSet().GetItemState(RES_BOXATR_FORMAT, sal_True, &pItem)
4108                     //          ||  pDoc->GetNumberFormatter()->IsTextFormat(((SwTblBoxNumFormat*)pItem)->GetValue())
4109                     //          ||  ((SwTblBoxNumFormat*)pItem)->GetValue() == NUMBERFORMAT_TEXT);
4110 
4111                     if(!bIsNum/*bIsText*/)
4112                         pColArray[nCol] <<= lcl_getString(*pXCell);
4113                     else
4114                         pColArray[nCol] <<= lcl_getValue(*pXCell);
4115                 }
4116             }
4117             pRowArray[nRow] = aColSeq;
4118         }
4119     }
4120     return aRowSeq;
4121 }
4122 
setDataArray(const uno::Sequence<uno::Sequence<uno::Any>> & rArray)4123 void SAL_CALL SwXCellRange::setDataArray(
4124         const uno::Sequence< uno::Sequence< uno::Any > >& rArray )
4125 {
4126     // see SwXCellRange::setData also
4127 
4128     vos::OGuard aGuard(Application::GetSolarMutex());
4129     sal_Int16 nRowCount = getRowCount();
4130     sal_Int16 nColCount = getColumnCount();
4131     if(!nRowCount || !nColCount)
4132     {
4133         uno::RuntimeException aRuntime;
4134         aRuntime.Message = C2U("Table too complex");
4135         throw aRuntime;
4136     }
4137     SwFrmFmt* pFmt = GetFrmFmt();
4138     if(pFmt )
4139     {
4140         if(rArray.getLength() != nRowCount)
4141         {
4142             throw uno::RuntimeException();
4143         }
4144         const uno::Sequence< uno::Any >* pRowArray = rArray.getConstArray();
4145         for(sal_uInt16 nRow = 0; nRow < nRowCount; nRow++)
4146         {
4147             const uno::Sequence< uno::Any >& rColSeq = pRowArray[nRow];
4148             if(rColSeq.getLength() != nColCount)
4149             {
4150                 throw uno::RuntimeException();
4151             }
4152             const uno::Any * pColArray = rColSeq.getConstArray();
4153             uno::Reference< table::XCell > xCellRef;
4154             for(sal_uInt16 nCol = 0; nCol < nColCount; nCol++)
4155             {
4156                 SwXCell * pXCell = lcl_CreateXCell(pFmt,
4157                                     aRgDesc.nLeft + nCol,
4158                                     aRgDesc.nTop + nRow);
4159                 //! keep (additional) reference to object to prevent implicit destruction
4160                 //! in following UNO calls (when object will get referenced)
4161                 xCellRef = pXCell;
4162                 SwTableBox * pBox = pXCell ? pXCell->GetTblBox() : 0;
4163                 if(!pBox)
4164                 {
4165                     throw uno::RuntimeException();
4166                 }
4167                 else
4168                 {
4169                     const uno::Any &rAny = pColArray[nCol];
4170                     if (uno::TypeClass_STRING == rAny.getValueTypeClass())
4171                         lcl_setString( *pXCell, *(rtl::OUString *) rAny.getValue() );
4172                     else
4173                     {
4174                         double d = 0;
4175                         // #i20067# don't throw exception just do nothing if
4176                         // there is no value set
4177                         if( (rAny >>= d) )
4178                             lcl_setValue( *pXCell, d );
4179                         else
4180                             lcl_setString( *pXCell, OUString(), sal_True );
4181                     }
4182                 }
4183             }
4184         }
4185     }
4186 }
4187 
getData(void)4188 uno::Sequence< uno::Sequence< double > > SwXCellRange::getData(void)
4189 {
4190     vos::OGuard aGuard(Application::GetSolarMutex());
4191     sal_Int16 nRowCount = getRowCount();
4192     sal_Int16 nColCount = getColumnCount();
4193     //
4194     if(!nRowCount || !nColCount)
4195     {
4196         uno::RuntimeException aRuntime;
4197         aRuntime.Message = C2U("Table too complex");
4198         throw aRuntime;
4199     }
4200     uno::Sequence< uno::Sequence< double > > aRowSeq(bFirstRowAsLabel ? nRowCount - 1 : nRowCount);
4201     SwFrmFmt* pFmt = GetFrmFmt();
4202     if(pFmt)
4203     {
4204         uno::Sequence< double >* pRowArray = aRowSeq.getArray();
4205 
4206         sal_uInt16 nRowStart = bFirstRowAsLabel ? 1 : 0;
4207         for(sal_uInt16 nRow = nRowStart; nRow < nRowCount; nRow++)
4208         {
4209             uno::Sequence< double > aColSeq(bFirstColumnAsLabel ? nColCount - 1 : nColCount);
4210             double * pArray = aColSeq.getArray();
4211             sal_uInt16 nColStart = bFirstColumnAsLabel ? 1 : 0;
4212             for(sal_uInt16 nCol = nColStart; nCol < nColCount; nCol++)
4213             {
4214                 uno::Reference< table::XCell >  xCell = getCellByPosition(nCol, nRow);
4215                 if(!xCell.is())
4216                 {
4217                     throw uno::RuntimeException();
4218                 }
4219                 pArray[nCol - nColStart] = xCell->getValue();
4220             }
4221             pRowArray[nRow - nRowStart] = aColSeq;
4222         }
4223     }
4224     return aRowSeq;
4225 }
4226 
setData(const uno::Sequence<uno::Sequence<double>> & rData)4227 void SwXCellRange::setData(const uno::Sequence< uno::Sequence< double > >& rData)
4228 {
4229     vos::OGuard aGuard(Application::GetSolarMutex());
4230     sal_Int16 nRowCount = getRowCount();
4231     sal_Int16 nColCount = getColumnCount();
4232     if(!nRowCount || !nColCount)
4233     {
4234         uno::RuntimeException aRuntime;
4235         aRuntime.Message = C2U("Table too complex");
4236         throw aRuntime;
4237     }
4238     SwFrmFmt* pFmt = GetFrmFmt();
4239     if(pFmt )
4240     {
4241         sal_uInt16 nRowStart = bFirstRowAsLabel ? 1 : 0;
4242         if(rData.getLength() < nRowCount - nRowStart)
4243         {
4244             throw uno::RuntimeException();
4245         }
4246         const uno::Sequence< double >* pRowArray = rData.getConstArray();
4247         for(sal_uInt16 nRow = nRowStart; nRow < nRowCount; nRow++)
4248         {
4249             const uno::Sequence< double >& rColSeq = pRowArray[nRow - nRowStart];
4250             sal_uInt16 nColStart = bFirstColumnAsLabel ? 1 : 0;
4251             if(rColSeq.getLength() < nColCount - nColStart)
4252             {
4253                 throw uno::RuntimeException();
4254             }
4255             const double * pColArray = rColSeq.getConstArray();
4256             for(sal_uInt16 nCol = nColStart; nCol < nColCount; nCol++)
4257             {
4258                 uno::Reference< table::XCell >  xCell = getCellByPosition(nCol, nRow);
4259                 if(!xCell.is())
4260                 {
4261                     throw uno::RuntimeException();
4262                 }
4263                 xCell->setValue(pColArray[nCol - nColStart]);
4264             }
4265         }
4266     }
4267 }
4268 
getRowDescriptions(void)4269 uno::Sequence< OUString > SwXCellRange::getRowDescriptions(void)
4270 {
4271     vos::OGuard aGuard(Application::GetSolarMutex());
4272     sal_Int16 nRowCount = getRowCount();
4273     if(!nRowCount)
4274     {
4275         uno::RuntimeException aRuntime;
4276         aRuntime.Message = C2U("Table too complex");
4277         throw aRuntime;
4278     }
4279     uno::Sequence< OUString > aRet(bFirstColumnAsLabel ? nRowCount - 1 : nRowCount);
4280     SwFrmFmt* pFmt = GetFrmFmt();
4281     if(pFmt)
4282     {
4283         OUString* pArray = aRet.getArray();
4284         if(bFirstColumnAsLabel)
4285         {
4286             sal_uInt16 nStart = bFirstRowAsLabel ? 1 : 0;
4287             for(sal_uInt16 i = nStart; i < nRowCount; i++)
4288             {
4289                 uno::Reference< table::XCell >  xCell = getCellByPosition(0, i);
4290                 if(!xCell.is())
4291                 {
4292                     throw uno::RuntimeException();
4293                 }
4294                 uno::Reference< text::XText >  xText(xCell, uno::UNO_QUERY);
4295                 pArray[i - nStart] = xText->getString();
4296             }
4297         }
4298         else
4299         {
4300             DBG_ERROR("Wo kommen die Labels her?");
4301         }
4302     }
4303     else
4304         throw uno::RuntimeException();
4305     return aRet;
4306 }
4307 
setRowDescriptions(const uno::Sequence<OUString> & rRowDesc)4308 void SwXCellRange::setRowDescriptions(const uno::Sequence< OUString >& rRowDesc)
4309 {
4310     vos::OGuard aGuard(Application::GetSolarMutex());
4311     SwFrmFmt* pFmt = GetFrmFmt();
4312     if(pFmt)
4313     {
4314         sal_Int16 nRowCount = getRowCount();
4315         if(!nRowCount || rRowDesc.getLength() < bFirstRowAsLabel ? nRowCount - 1 : nRowCount)
4316         {
4317             throw uno::RuntimeException();
4318         }
4319         const OUString* pArray = rRowDesc.getConstArray();
4320         if(bFirstColumnAsLabel)
4321         {
4322             sal_uInt16 nStart = bFirstRowAsLabel ? 1 : 0;
4323             for(sal_uInt16 i = nStart; i < nRowCount; i++)
4324             {
4325                 uno::Reference< table::XCell >  xCell = getCellByPosition(0, i);
4326                 if(!xCell.is())
4327                 {
4328                     throw uno::RuntimeException();
4329                 }
4330                 uno::Reference< text::XText >  xText(xCell, uno::UNO_QUERY);
4331                 xText->setString(pArray[i - nStart]);
4332             }
4333         }
4334         else
4335         {
4336             DBG_ERROR("Wohin mit den Labels?");
4337         }
4338     }
4339 }
4340 
getColumnDescriptions(void)4341 uno::Sequence< OUString > SwXCellRange::getColumnDescriptions(void)
4342 {
4343     vos::OGuard aGuard(Application::GetSolarMutex());
4344     sal_Int16 nColCount = getColumnCount();
4345     if(!nColCount)
4346     {
4347         uno::RuntimeException aRuntime;
4348         aRuntime.Message = C2U("Table too complex");
4349         throw aRuntime;
4350     }
4351     uno::Sequence< OUString > aRet(bFirstRowAsLabel ? nColCount - 1 : nColCount);
4352     SwFrmFmt* pFmt = GetFrmFmt();
4353     if(pFmt)
4354     {
4355         OUString* pArray = aRet.getArray();
4356         if(bFirstRowAsLabel)
4357         {
4358             sal_uInt16 nStart = bFirstColumnAsLabel ? 1 : 0;
4359             for(sal_uInt16 i = nStart; i < nColCount; i++)
4360             {
4361                 uno::Reference< table::XCell >  xCell = getCellByPosition(i, 0);
4362                 if(!xCell.is())
4363                 {
4364                     throw uno::RuntimeException();
4365                 }
4366                 uno::Reference< text::XText >  xText(xCell, uno::UNO_QUERY);
4367                 pArray[i - nStart] = xText->getString();
4368             }
4369         }
4370         else
4371         {
4372             DBG_ERROR("Wo kommen die Labels her?");
4373         }
4374     }
4375     else
4376         throw uno::RuntimeException();
4377     return aRet;
4378 }
4379 
setColumnDescriptions(const uno::Sequence<OUString> & ColumnDesc)4380 void SwXCellRange::setColumnDescriptions(const uno::Sequence< OUString >& ColumnDesc)
4381 {
4382     vos::OGuard aGuard(Application::GetSolarMutex());
4383     sal_Int16 nColCount = getColumnCount();
4384     SwFrmFmt* pFmt = GetFrmFmt();
4385     if(pFmt)
4386     {
4387         const OUString* pArray = ColumnDesc.getConstArray();
4388         if(bFirstRowAsLabel && ColumnDesc.getLength() >= nColCount - bFirstColumnAsLabel ? 1 : 0)
4389         {
4390             sal_uInt16 nStart = bFirstColumnAsLabel ? 1 : 0;
4391             for(sal_uInt16 i = nStart; i < nColCount; i++)
4392             {
4393                 uno::Reference< table::XCell >  xCell = getCellByPosition(i, 0);
4394                 if(!xCell.is())
4395                 {
4396                     throw uno::RuntimeException();
4397                 }
4398                 uno::Reference< text::XText >  xText(xCell, uno::UNO_QUERY);
4399 
4400                 xText->setString(pArray[i - nStart]);
4401             }
4402         }
4403         else
4404         {
4405             DBG_ERROR("Wo kommen die Labels her?");
4406         }
4407     }
4408 }
4409 
addChartDataChangeEventListener(const uno::Reference<chart::XChartDataChangeEventListener> & aListener)4410 void SwXCellRange::addChartDataChangeEventListener(const uno::Reference< chart::XChartDataChangeEventListener > & aListener)
4411 {
4412     if(!GetRegisteredIn())
4413         throw uno::RuntimeException();
4414     aChartLstnrCntnr.AddListener(aListener.get());
4415 }
4416 
removeChartDataChangeEventListener(const uno::Reference<chart::XChartDataChangeEventListener> & aListener)4417 void SwXCellRange::removeChartDataChangeEventListener(const uno::Reference< chart::XChartDataChangeEventListener > & aListener)
4418 {
4419     if(!GetRegisteredIn() || !aChartLstnrCntnr.RemoveListener(aListener.get()))
4420         throw uno::RuntimeException();
4421 }
4422 
isNotANumber(double)4423 sal_Bool SwXCellRange::isNotANumber(double /*fNumber*/)
4424 {
4425     DBG_WARNING("not implemented");
4426     return sal_False;
4427 
4428 }
4429 
getNotANumber(void)4430 double SwXCellRange::getNotANumber(void)
4431 {
4432     DBG_WARNING("not implemented");
4433     return 0.;
4434 }
4435 
createSortDescriptor(void)4436 uno::Sequence< beans::PropertyValue > SwXCellRange::createSortDescriptor(void)
4437 {
4438     vos::OGuard aGuard(Application::GetSolarMutex());
4439 
4440     return SwUnoCursorHelper::CreateSortDescriptor(true);
4441 }
4442 
sort(const uno::Sequence<beans::PropertyValue> & rDescriptor)4443 void SAL_CALL SwXCellRange::sort(const uno::Sequence< beans::PropertyValue >& rDescriptor)
4444 {
4445     vos::OGuard aGuard(Application::GetSolarMutex());
4446     SwSortOptions aSortOpt;
4447     SwFrmFmt* pFmt = GetFrmFmt();
4448     if(pFmt &&
4449         SwUnoCursorHelper::ConvertSortProperties(rDescriptor, aSortOpt))
4450     {
4451         SwUnoTableCrsr* pTableCrsr = dynamic_cast<SwUnoTableCrsr*>(pTblCrsr);
4452         pTableCrsr->MakeBoxSels();
4453         UnoActionContext aContext( pFmt->GetDoc() );
4454         pFmt->GetDoc()->SortTbl(pTableCrsr->GetBoxes(), aSortOpt);
4455     }
4456 }
4457 
getColumnCount(void)4458 sal_uInt16 SwXCellRange::getColumnCount(void)
4459 {
4460     return static_cast< sal_uInt16 >(aRgDesc.nRight - aRgDesc.nLeft + 1);
4461 }
4462 
getRowCount(void)4463 sal_uInt16 SwXCellRange::getRowCount(void)
4464 {
4465     return static_cast< sal_uInt16 >(aRgDesc.nBottom - aRgDesc.nTop + 1);
4466 }
4467 
GetTblCrsr() const4468 const SwUnoCrsr* SwXCellRange::GetTblCrsr() const
4469 {
4470     const SwUnoCrsr* pRet = 0;
4471     SwFrmFmt* pFmt = GetFrmFmt();
4472     if(pFmt)
4473         pRet = pTblCrsr;
4474     return pRet;
4475 }
4476 
4477 
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)4478 void SwXCellRange::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
4479 {
4480     ClientModify(this, pOld, pNew );
4481     if(!GetRegisteredIn() || !aCursorDepend.GetRegisteredIn())
4482     {
4483         /*
4484          * Not sure if this will cause a memory leak - this pTblCrsr
4485          * is deleted in SwDoc and GPFs here when deleted again
4486          * if(!aCursorDepend.GetRegisteredIn())
4487             delete pTblCrsr;
4488          */
4489         pTblCrsr = 0;
4490         aChartLstnrCntnr.Disposing();
4491     }
4492     else
4493         aChartLstnrCntnr.ChartDataChanged();
4494 }
4495 
4496 /******************************************************************
4497  *  SwXTableRows
4498  ******************************************************************/
4499 
getImplementationName(void)4500 OUString SwXTableRows::getImplementationName(void)
4501 {
4502     return C2U("SwXTableRows");
4503 }
4504 
supportsService(const OUString & rServiceName)4505 sal_Bool SwXTableRows::supportsService(const OUString& rServiceName)
4506 {
4507     return C2U("com.sun.star.text.TableRows") == rServiceName;
4508 }
4509 
getSupportedServiceNames(void)4510 uno::Sequence< OUString > SwXTableRows::getSupportedServiceNames(void)
4511 {
4512     uno::Sequence< OUString > aRet(1);
4513     OUString* pArray = aRet.getArray();
4514     pArray[0] = C2U("com.sun.star.text.TableRows");
4515     return aRet;
4516 }
4517 TYPEINIT1(SwXTableRows, SwClient);
4518 
SwXTableRows(SwFrmFmt & rFrmFmt)4519 SwXTableRows::SwXTableRows(SwFrmFmt& rFrmFmt) :
4520     SwClient(&rFrmFmt)
4521 {
4522 }
4523 
~SwXTableRows()4524 SwXTableRows::~SwXTableRows()
4525 {
4526 }
4527 
getCount(void)4528 sal_Int32 SwXTableRows::getCount(void)
4529 {
4530     vos::OGuard aGuard(Application::GetSolarMutex());
4531     sal_Int32 nRet = 0;
4532     SwFrmFmt* pFrmFmt = GetFrmFmt();
4533     if(!pFrmFmt)
4534         throw uno::RuntimeException();
4535     else
4536     {
4537         SwTable* pTable = SwTable::FindTable( pFrmFmt );
4538         nRet = pTable->GetTabLines().Count();
4539     }
4540     return nRet;
4541 }
4542 
getByIndex(sal_Int32 nIndex)4543 uno::Any SwXTableRows::getByIndex(sal_Int32 nIndex)
4544 {
4545     vos::OGuard aGuard(Application::GetSolarMutex());
4546     uno::Any aRet;
4547     SwFrmFmt* pFrmFmt = GetFrmFmt();
4548     if(!pFrmFmt || nIndex < 0 )
4549         throw lang::IndexOutOfBoundsException();
4550     else
4551     {
4552         SwTable* pTable = SwTable::FindTable( pFrmFmt );
4553         if(pTable->GetTabLines().Count() > nIndex)
4554         {
4555             SwTableLine* pLine = pTable->GetTabLines().GetObject((sal_uInt16)nIndex);
4556             SwIterator<SwXTextTableRow,SwFmt> aIter( *pFrmFmt );
4557             SwXTextTableRow* pXRow = aIter.First();
4558             while( pXRow )
4559             {
4560                 // gibt es eine passende Zelle bereits?
4561                 if(pXRow->GetTblRow() == pLine)
4562                     break;
4563                 pXRow = aIter.Next();
4564             }
4565             //sonst anlegen
4566             if(!pXRow)
4567                 pXRow = new SwXTextTableRow(pFrmFmt, pLine);
4568             uno::Reference< beans::XPropertySet >  xRet =
4569                                     (beans::XPropertySet*)pXRow;
4570             aRet.setValue(&xRet, ::getCppuType((const uno::Reference<beans::XPropertySet>*)0));
4571         }
4572         else
4573             throw lang::IndexOutOfBoundsException();
4574     }
4575     return aRet;
4576 }
4577 
getElementType(void)4578 uno::Type SAL_CALL SwXTableRows::getElementType(void)
4579 {
4580     return ::getCppuType((const uno::Reference<beans::XPropertySet>*)0);
4581 }
4582 
hasElements(void)4583 sal_Bool SwXTableRows::hasElements(void)
4584 {
4585     vos::OGuard aGuard(Application::GetSolarMutex());
4586     SwFrmFmt* pFrmFmt = GetFrmFmt();
4587     if(!pFrmFmt)
4588         throw uno::RuntimeException();
4589     //es gibt keine Tabelle ohne Zeilen
4590     return sal_True;
4591 }
4592 
insertByIndex(sal_Int32 nIndex,sal_Int32 nCount)4593 void SwXTableRows::insertByIndex(sal_Int32 nIndex, sal_Int32 nCount)
4594 {
4595     vos::OGuard aGuard(Application::GetSolarMutex());
4596     if (nCount == 0)
4597         return;
4598     SwFrmFmt* pFrmFmt = GetFrmFmt();
4599     if(!pFrmFmt)
4600         throw uno::RuntimeException();
4601     else
4602     {
4603         SwTable* pTable = SwTable::FindTable( pFrmFmt );
4604         if(!pTable->IsTblComplex())
4605         {
4606             sal_uInt16 nRowCount = pTable->GetTabLines().Count();
4607             if (nCount <= 0 || !(0 <= nIndex && nIndex <= nRowCount))
4608             {
4609                 uno::RuntimeException aExcept;
4610                 aExcept.Message = C2U("Illegal arguments");
4611                 throw aExcept;
4612             }
4613 
4614             String sTLName = lcl_GetCellName(0, nIndex);
4615             const SwTableBox* pTLBox = pTable->GetTblBox( sTLName );
4616             sal_Bool bAppend = sal_False;
4617             if(!pTLBox)
4618             {
4619                 bAppend = sal_True;
4620                 // am Ende anfuegen, dazu muss der Cursor in die letzte Zeile!
4621                 SwTableLines& rLines = pTable->GetTabLines();
4622                 SwTableLine* pLine = rLines.GetObject(rLines.Count() -1);
4623                 SwTableBoxes& rBoxes = pLine->GetTabBoxes();
4624                 pTLBox = rBoxes.GetObject(0);
4625             }
4626             if(pTLBox)
4627             {
4628                 const SwStartNode* pSttNd = pTLBox->GetSttNd();
4629                 SwPosition aPos(*pSttNd);
4630                 // Cursor in die obere linke Zelle des Ranges setzen
4631                 UnoActionContext aAction(pFrmFmt->GetDoc());
4632                 SwUnoCrsr* pUnoCrsr = pFrmFmt->GetDoc()->CreateUnoCrsr(aPos, sal_True);
4633                 pUnoCrsr->Move( fnMoveForward, fnGoNode );
4634 
4635                 {
4636                     // remove actions
4637                     UnoActionRemoveContext aRemoveContext(pUnoCrsr->GetDoc());
4638                 }
4639 
4640                 pFrmFmt->GetDoc()->InsertRow(*pUnoCrsr, (sal_uInt16)nCount, bAppend);
4641                 delete pUnoCrsr;
4642             }
4643         }
4644     }
4645 }
4646 
removeByIndex(sal_Int32 nIndex,sal_Int32 nCount)4647 void SwXTableRows::removeByIndex(sal_Int32 nIndex, sal_Int32 nCount)
4648 {
4649     vos::OGuard aGuard(Application::GetSolarMutex());
4650     if (nCount == 0)
4651         return;
4652     SwFrmFmt* pFrmFmt = GetFrmFmt();
4653     if(!pFrmFmt || nIndex < 0 || nCount <=0 )
4654         throw uno::RuntimeException();
4655     else
4656     {
4657         sal_Bool bSuccess = sal_False;
4658         SwTable* pTable = SwTable::FindTable( pFrmFmt );
4659         if(!pTable->IsTblComplex())
4660         {
4661             String sTLName = lcl_GetCellName(0, nIndex);
4662             const SwTableBox* pTLBox = pTable->GetTblBox( sTLName );
4663             if(pTLBox)
4664             {
4665                 {
4666                     // hier muessen die Actions aufgehoben werden
4667                     UnoActionRemoveContext aRemoveContext(pFrmFmt->GetDoc());
4668                 }
4669                 const SwStartNode* pSttNd = pTLBox->GetSttNd();
4670                 SwPosition aPos(*pSttNd);
4671                 // Cursor in die obere linke Zelle des Ranges setzen
4672                 SwUnoCrsr* pUnoCrsr = pFrmFmt->GetDoc()->CreateUnoCrsr(aPos, sal_True);
4673                 pUnoCrsr->Move( fnMoveForward, fnGoNode );
4674                 pUnoCrsr->SetRemainInSection( sal_False );
4675                 String sBLName = lcl_GetCellName(0, nIndex + nCount - 1);
4676                 const SwTableBox* pBLBox = pTable->GetTblBox( sBLName );
4677                 if(pBLBox)
4678                 {
4679                     pUnoCrsr->SetMark();
4680                     pUnoCrsr->GetPoint()->nNode = *pBLBox->GetSttNd();
4681                     pUnoCrsr->Move( fnMoveForward, fnGoNode );
4682                     SwUnoTableCrsr* pCrsr =
4683                         dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
4684                     pCrsr->MakeBoxSels();
4685                     {   // Die Klammer ist wichtig
4686                         UnoActionContext aAction(pFrmFmt->GetDoc());
4687                         pFrmFmt->GetDoc()->DeleteRow(*pUnoCrsr);
4688                         delete pUnoCrsr;
4689                         bSuccess = sal_True;
4690                     }
4691                     {
4692                         // hier muessen die Actions aufgehoben werden
4693                         UnoActionRemoveContext aRemoveContext(pFrmFmt->GetDoc());
4694                     }
4695                 }
4696             }
4697         }
4698         if(!bSuccess)
4699         {
4700             uno::RuntimeException aExcept;
4701             aExcept.Message = C2U("Illegal arguments");
4702             throw aExcept;
4703         }
4704     }
4705 }
4706 
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)4707 void SwXTableRows::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
4708 {
4709     ClientModify(this, pOld, pNew);
4710 }
4711 
4712 /******************************************************************
4713  * SwXTableColumns
4714  ******************************************************************/
4715 
getImplementationName(void)4716 OUString SwXTableColumns::getImplementationName(void)
4717 {
4718     return C2U("SwXTableColumns");
4719 }
4720 
supportsService(const OUString & rServiceName)4721 sal_Bool SwXTableColumns::supportsService(const OUString& rServiceName)
4722 {
4723     return C2U("com.sun.star.text.TableColumns") == rServiceName;
4724 }
4725 
getSupportedServiceNames(void)4726 uno::Sequence< OUString > SwXTableColumns::getSupportedServiceNames(void)
4727 {
4728     uno::Sequence< OUString > aRet(1);
4729     OUString* pArray = aRet.getArray();
4730     pArray[0] = C2U("com.sun.star.text.TableColumns");
4731     return aRet;
4732 }
4733 TYPEINIT1(SwXTableColumns, SwClient);
4734 
SwXTableColumns(SwFrmFmt & rFrmFmt)4735 SwXTableColumns::SwXTableColumns(SwFrmFmt& rFrmFmt) :
4736     SwClient(&rFrmFmt)
4737 {
4738 }
4739 
~SwXTableColumns()4740 SwXTableColumns::~SwXTableColumns()
4741 {
4742 }
4743 
getCount(void)4744 sal_Int32 SwXTableColumns::getCount(void)
4745 {
4746     vos::OGuard aGuard(Application::GetSolarMutex());
4747     sal_Int32 nRet = 0;
4748     SwFrmFmt* pFrmFmt = GetFrmFmt();
4749     if(!pFrmFmt)
4750         throw uno::RuntimeException();
4751     else
4752     {
4753         SwTable* pTable = SwTable::FindTable( pFrmFmt );
4754         if(!pTable->IsTblComplex())
4755         {
4756             SwTableLines& rLines = pTable->GetTabLines();
4757             SwTableLine* pLine = rLines.GetObject(0);
4758             nRet = pLine->GetTabBoxes().Count();
4759         }
4760     }
4761     return nRet;
4762 }
4763 
getByIndex(sal_Int32 nIndex)4764 uno::Any SwXTableColumns::getByIndex(sal_Int32 nIndex)
4765 {
4766     vos::OGuard aGuard(Application::GetSolarMutex());
4767     uno::Reference< uno::XInterface >  xRet;
4768     SwFrmFmt* pFrmFmt = GetFrmFmt();
4769     if(!pFrmFmt)
4770         throw uno::RuntimeException();
4771     else
4772     {
4773         sal_uInt16 nCount = 0;
4774         SwTable* pTable = SwTable::FindTable( pFrmFmt );
4775         if(!pTable->IsTblComplex())
4776         {
4777             SwTableLines& rLines = pTable->GetTabLines();
4778             SwTableLine* pLine = rLines.GetObject(0);
4779             nCount = pLine->GetTabBoxes().Count();
4780         }
4781         if(nCount <= nIndex || nIndex < 0)
4782             throw lang::IndexOutOfBoundsException();
4783         xRet = uno::Reference<uno::XInterface>();   //!! writer tables do not have columns !!
4784     }
4785     return uno::Any(&xRet, ::getCppuType((const uno::Reference<uno::XInterface>*)0));
4786 }
4787 
getElementType(void)4788 uno::Type SAL_CALL SwXTableColumns::getElementType(void)
4789 {
4790     return ::getCppuType((uno::Reference<uno::XInterface>*)0);
4791 }
4792 
hasElements(void)4793 sal_Bool SwXTableColumns::hasElements(void)
4794 {
4795     vos::OGuard aGuard(Application::GetSolarMutex());
4796     SwFrmFmt* pFrmFmt = GetFrmFmt();
4797     if(!pFrmFmt)
4798         throw uno::RuntimeException();
4799     return sal_True;
4800 }
4801 
insertByIndex(sal_Int32 nIndex,sal_Int32 nCount)4802 void SwXTableColumns::insertByIndex(sal_Int32 nIndex, sal_Int32 nCount)
4803 {
4804     vos::OGuard aGuard(Application::GetSolarMutex());
4805     if (nCount == 0)
4806         return;
4807     SwFrmFmt* pFrmFmt = GetFrmFmt();
4808     if(!pFrmFmt)
4809         throw uno::RuntimeException();
4810     else
4811     {
4812         SwTable* pTable = SwTable::FindTable( pFrmFmt );
4813         if(!pTable->IsTblComplex())
4814         {
4815             SwTableLines& rLines = pTable->GetTabLines();
4816             SwTableLine* pLine = rLines.GetObject(0);
4817             sal_uInt16 nColCount = pLine->GetTabBoxes().Count();
4818             if (nCount <= 0 || !(0 <= nIndex && nIndex <= nColCount))
4819             {
4820                 uno::RuntimeException aExcept;
4821                 aExcept.Message = C2U("Illegal arguments");
4822                 throw aExcept;
4823             }
4824 
4825             String sTLName = lcl_GetCellName(nIndex, 0);
4826             const SwTableBox* pTLBox = pTable->GetTblBox( sTLName );
4827             sal_Bool bAppend = sal_False;
4828             if(!pTLBox)
4829             {
4830                 bAppend = sal_True;
4831                 // am Ende anfuegen, dazu muss der Cursor in die letzte Spalte!
4832                 SwTableBoxes& rBoxes = pLine->GetTabBoxes();
4833                 pTLBox = rBoxes.GetObject(rBoxes.Count() - 1);
4834             }
4835             if(pTLBox)
4836             {
4837                 const SwStartNode* pSttNd = pTLBox->GetSttNd();
4838                 SwPosition aPos(*pSttNd);
4839                 UnoActionContext aAction(pFrmFmt->GetDoc());
4840                 SwUnoCrsr* pUnoCrsr = pFrmFmt->GetDoc()->CreateUnoCrsr(aPos, sal_True);
4841                 pUnoCrsr->Move( fnMoveForward, fnGoNode );
4842 
4843                 {
4844                     // remove actions
4845                     UnoActionRemoveContext aRemoveContext(pUnoCrsr->GetDoc());
4846                 }
4847 
4848                 pFrmFmt->GetDoc()->InsertCol(*pUnoCrsr, (sal_uInt16)nCount, bAppend);
4849                 delete pUnoCrsr;
4850             }
4851         }
4852     }
4853 }
4854 
removeByIndex(sal_Int32 nIndex,sal_Int32 nCount)4855 void SwXTableColumns::removeByIndex(sal_Int32 nIndex, sal_Int32 nCount)
4856 {
4857     vos::OGuard aGuard(Application::GetSolarMutex());
4858     if (nCount == 0)
4859         return;
4860     SwFrmFmt* pFrmFmt = GetFrmFmt();
4861     if(!pFrmFmt|| nIndex < 0 || nCount <=0 )
4862         throw uno::RuntimeException();
4863     else
4864     {
4865         sal_Bool bSuccess = sal_False;
4866         SwTable* pTable = SwTable::FindTable( pFrmFmt );
4867         if(!pTable->IsTblComplex())
4868         {
4869             String sTLName = lcl_GetCellName(nIndex, 0);
4870             const SwTableBox* pTLBox = pTable->GetTblBox( sTLName );
4871             if(pTLBox)
4872             {
4873                 {
4874                     // hier muessen die Actions aufgehoben werden
4875                     UnoActionRemoveContext aRemoveContext(pFrmFmt->GetDoc());
4876                 }
4877                 const SwStartNode* pSttNd = pTLBox->GetSttNd();
4878                 SwPosition aPos(*pSttNd);
4879                 // Cursor in die obere linke Zelle des Ranges setzen
4880                 SwUnoCrsr* pUnoCrsr = pFrmFmt->GetDoc()->CreateUnoCrsr(aPos, sal_True);
4881                 pUnoCrsr->Move( fnMoveForward, fnGoNode );
4882                 pUnoCrsr->SetRemainInSection( sal_False );
4883                 String sTRName = lcl_GetCellName(nIndex + nCount - 1, 0);
4884                 const SwTableBox* pTRBox = pTable->GetTblBox( sTRName );
4885                 if(pTRBox)
4886                 {
4887                     pUnoCrsr->SetMark();
4888                     pUnoCrsr->GetPoint()->nNode = *pTRBox->GetSttNd();
4889                     pUnoCrsr->Move( fnMoveForward, fnGoNode );
4890                     SwUnoTableCrsr* pCrsr =
4891                         dynamic_cast<SwUnoTableCrsr*>(pUnoCrsr);
4892                     pCrsr->MakeBoxSels();
4893                     {   // Die Klammer ist wichtig
4894                         UnoActionContext aAction(pFrmFmt->GetDoc());
4895                         pFrmFmt->GetDoc()->DeleteCol(*pUnoCrsr);
4896                         delete pUnoCrsr;
4897                         bSuccess = sal_True;
4898                     }
4899                     {
4900                         // hier muessen die Actions aufgehoben werden
4901                         UnoActionRemoveContext aRemoveContext(pFrmFmt->GetDoc());
4902                     }
4903                 }
4904             }
4905         }
4906         if(!bSuccess)
4907         {
4908             uno::RuntimeException aExcept;
4909             aExcept.Message = C2U("Illegal arguments");
4910             throw aExcept;
4911         }
4912     }
4913 }
4914 
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)4915 void SwXTableColumns::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
4916 {
4917     ClientModify(this, pOld, pNew);
4918 }
4919 
ChartDataChanged()4920 void SwChartEventListenerContainer::ChartDataChanged()
4921 {
4922     if(pListenerArr)
4923     {
4924         //TODO: find appropriate settings of the Event
4925         lang::EventObject aObj(pxParent);
4926         chart::ChartDataChangeEvent aEvent;
4927         aEvent.Type = chart::ChartDataChangeType_ALL;
4928         aEvent.StartColumn = 0;
4929         aEvent.EndColumn = 1;
4930         aEvent.StartRow = 0;
4931         aEvent.EndRow = 1;
4932 
4933         for(sal_uInt16 i = 0; i < pListenerArr->Count(); i++)
4934         {
4935             try
4936             {
4937                 XEventListenerPtr pElem = pListenerArr->GetObject(i);
4938                 uno::Reference<lang::XEventListener> xEventListener = *pElem;
4939                 uno::Reference<chart::XChartDataChangeEventListener> xChartEventListener = (chart::XChartDataChangeEventListener*)(*pElem).get();
4940                 xChartEventListener->chartDataChanged( aEvent );
4941             }
4942             catch(uno::Exception const &)
4943             {
4944             }
4945         }
4946     }
4947 }
4948 
4949 ///////////////////////////////////////////////////////////////////////////
4950