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