xref: /AOO41X/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