xref: /trunk/main/svx/source/table/svdotable.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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_svx.hxx"
30 
31 #define ITEMID_BOX SDRATTR_TABLE_BORDER
32 #define ITEMID_BOXINFO SDRATTR_TABLE_BORDER_INNER
33 
34 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
35 #include <com/sun/star/container/XNamed.hpp>
36 #include <com/sun/star/container/XNameAccess.hpp>
37 #include <com/sun/star/container/XIndexAccess.hpp>
38 
39 #include <vcl/canvastools.hxx>
40 #include <com/sun/star/style/XStyle.hpp>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <basegfx/polygon/b2dpolygontools.hxx>
43 #include <basegfx/polygon/b2dpolypolygon.hxx>
44 #include <basegfx/polygon/b2dpolygon.hxx>
45 #include <svl/style.hxx>
46 #include "editeng/editstat.hxx"
47 #include "editeng/outlobj.hxx"
48 #include "svx/svdview.hxx"
49 #include "svx/sdr/properties/textproperties.hxx"
50 #include "svx/svdotable.hxx"
51 #include "svx/svdhdl.hxx"
52 #include "viewcontactoftableobj.hxx"
53 #include "svx/svdoutl.hxx"
54 #include "svx/svddrag.hxx"
55 #include "svx/svdpagv.hxx"
56 #include "tablemodel.hxx"
57 #include "cell.hxx"
58 #include "svx/xflclit.hxx"
59 #include "tablelayouter.hxx"
60 #include "svx/svdetc.hxx"
61 #include "tablehandles.hxx"
62 #include "editeng/boxitem.hxx"
63 #include "svx/framelink.hxx"
64 #include "svx/sdr/table/tabledesign.hxx"
65 #include "svx/svdundo.hxx"
66 #include "svx/svdstr.hrc"
67 #include "svx/svdglob.hxx"
68 #include "editeng/writingmodeitem.hxx"
69 #include "editeng/frmdiritem.hxx"
70 #include "svx/xflhtit.hxx"
71 #include "svx/xflftrit.hxx"
72 #include "svx/xfltrit.hxx"
73 
74 // -----------------------------------------------------------------------------
75 
76 using ::rtl::OUString;
77 using ::com::sun::star::uno::Any;
78 using ::com::sun::star::uno::Reference;
79 using ::com::sun::star::uno::XInterface;
80 using ::com::sun::star::uno::UNO_QUERY;
81 using ::com::sun::star::uno::UNO_QUERY_THROW;
82 using ::com::sun::star::uno::Exception;
83 using ::com::sun::star::container::XIndexAccess;
84 using ::com::sun::star::style::XStyle;
85 using ::com::sun::star::table::XTableRows;
86 using ::com::sun::star::table::XTableColumns;
87 using ::com::sun::star::table::XTable;
88 using ::com::sun::star::beans::XPropertySet;
89 using ::com::sun::star::util::XModifyBroadcaster;
90 using sdr::properties::TextProperties;
91 using sdr::properties::BaseProperties;
92 using namespace ::com::sun::star::text;
93 using namespace ::com::sun::star::container;
94 using namespace ::com::sun::star::style;
95 
96 namespace sdr { namespace table {
97 
98 class TableProperties : public TextProperties
99 {
100 protected:
101     // create a new itemset
102     SfxItemSet& CreateObjectSpecificItemSet(SfxItemPool& rPool);
103 
104 public:
105     // basic constructor
106     TableProperties(SdrObject& rObj );
107 
108     // constructor for copying, but using new object
109     TableProperties(const TableProperties& rProps, SdrObject& rObj );
110 
111     // destructor
112     ~TableProperties();
113 
114     // Clone() operator, normally just calls the local copy constructor
115     BaseProperties& Clone(SdrObject& rObj) const;
116 
117     virtual void ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem);
118 };
119 
120 TableProperties::TableProperties(SdrObject& rObj)
121 : TextProperties(rObj)
122 {
123 }
124 
125 TableProperties::TableProperties(const TableProperties& rProps, SdrObject& rObj)
126 : TextProperties(rProps, rObj)
127 {
128 }
129 
130 TableProperties::~TableProperties()
131 {
132 }
133 
134 BaseProperties& TableProperties::Clone(SdrObject& rObj) const
135 {
136     return *(new TableProperties(*this, rObj));
137 }
138 
139 void TableProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem)
140 {
141     if( nWhich == SDRATTR_TEXTDIRECTION )
142         AttributeProperties::ItemChange( nWhich, pNewItem );
143     else
144         TextProperties::ItemChange( nWhich, pNewItem );
145 }
146 
147 // create a new itemset
148 SfxItemSet& TableProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool)
149 {
150     return *(new SfxItemSet(rPool,
151 
152         // range from SdrAttrObj
153         SDRATTR_START, SDRATTR_SHADOW_LAST,
154         SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST,
155         SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION,
156 
157         // range for SdrTableObj
158         SDRATTR_TABLE_FIRST, SDRATTR_TABLE_LAST,
159 
160         // range from SdrTextObj
161         EE_ITEMS_START, EE_ITEMS_END,
162 
163         // end
164         0, 0));
165 }
166 
167 class TableObjectGeoData : public SdrTextObjGeoData
168 {
169 public:
170     Rectangle   maLogicRect;
171 };
172 
173 //------------------------------------------------------------------------
174 // TableStyleSettings
175 //------------------------------------------------------------------------
176 
177 TableStyleSettings::TableStyleSettings()
178 : mbUseFirstRow(true)
179 , mbUseLastRow(false)
180 , mbUseFirstColumn(false)
181 , mbUseLastColumn(false)
182 , mbUseRowBanding(true)
183 , mbUseColumnBanding(false)
184 {
185 }
186 
187 TableStyleSettings::TableStyleSettings( const TableStyleSettings& rStyle )
188 {
189     (*this) = rStyle;
190 }
191 
192 TableStyleSettings& TableStyleSettings::operator=(const TableStyleSettings& rStyle)
193 {
194     mbUseFirstRow = rStyle.mbUseFirstRow;
195     mbUseLastRow = rStyle.mbUseLastRow;
196     mbUseFirstColumn = rStyle.mbUseFirstColumn;
197     mbUseLastColumn = rStyle.mbUseLastColumn;
198     mbUseRowBanding = rStyle.mbUseRowBanding;
199     mbUseColumnBanding = rStyle.mbUseColumnBanding;
200     return *this;
201 }
202 
203 bool TableStyleSettings::operator==( const TableStyleSettings& rStyle ) const
204 {
205     return
206         (mbUseFirstRow == rStyle.mbUseFirstRow) &&
207         (mbUseLastRow == rStyle.mbUseLastRow) &&
208         (mbUseFirstColumn == rStyle.mbUseFirstColumn) &&
209         (mbUseLastColumn == rStyle.mbUseLastColumn) &&
210         (mbUseRowBanding == rStyle.mbUseRowBanding) &&
211         (mbUseColumnBanding == rStyle.mbUseColumnBanding);
212 }
213 
214 // -----------------------------------------------------------------------------
215 
216 class SdrTableObjImpl : public TableDesignUser, public ::cppu::WeakImplHelper1< ::com::sun::star::util::XModifyListener >
217 {
218 public:
219     CellRef mxActiveCell;
220     TableModelRef mxTable;
221     SdrTableObj* mpTableObj;
222     TableLayouter* mpLayouter;
223     CellPos maEditPos;
224     TableStyleSettings maTableStyle;
225     Reference< XIndexAccess > mxTableStyle;
226     bool mbModifyPending;
227 //  sal_Int32 mnSavedEditRowHeight;
228 
229     void SetModel(SdrModel* pOldModel, SdrModel* pNewModel);
230 
231     CellRef getCell( const CellPos& rPos ) const;
232     void LayoutTable( Rectangle& rArea, bool bFitWidth, bool bFitHeight );
233 
234     bool ApplyCellStyles();
235     void UpdateCells( Rectangle& rArea );
236 
237     SdrTableObjImpl();
238     virtual ~SdrTableObjImpl();
239 
240     void init( SdrTableObj* pTable, sal_Int32 nColumns, sal_Int32 nRows );
241     void dispose();
242 
243     sal_Int32 getColumnCount() const;
244     sal_Int32 getRowCount() const;
245 
246     void DragEdge( bool mbHorizontal, int nEdge, sal_Int32 nOffset );
247 
248     const SfxPoolItem* GetCellItem( const CellPos& rPos, sal_uInt16 nWhich ) const;
249 //  void GetBorderLines( const CellPos& rPos, const SvxBorderLine** ppLeft, const SvxBorderLine** ppTop, const SvxBorderLine** ppRight, const SvxBorderLine** ppBottom ) const;
250 
251     void operator=( const SdrTableObjImpl& rSource );
252 
253     // XModifyListener
254     virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
255 
256     // XEventListener
257     virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
258 
259     void update();
260 
261     void connectTableStyle();
262     void disconnectTableStyle();
263     virtual bool isInUse();
264 
265     bool UpdateWritingMode();
266 };
267 
268 // -----------------------------------------------------------------------------
269 
270 SdrTableObjImpl::SdrTableObjImpl()
271 : mpTableObj( 0 )
272 , mpLayouter( 0 )
273 {
274 }
275 
276 // -----------------------------------------------------------------------------
277 
278 SdrTableObjImpl::~SdrTableObjImpl()
279 {
280 }
281 
282 // -----------------------------------------------------------------------------
283 
284 void SdrTableObjImpl::init( SdrTableObj* pTable, sal_Int32 nColumns, sal_Int32 nRows )
285 {
286     mpTableObj = pTable;
287     mxTable = new TableModel( pTable );
288     mxTable->init( nColumns, nRows );
289     mpLayouter = new TableLayouter( mxTable );
290     Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
291     mxTable->addModifyListener( xListener );
292     UpdateWritingMode();
293     LayoutTable( mpTableObj->aRect, true, true );
294     mpTableObj->maLogicRect = mpTableObj->aRect;
295 }
296 
297 // -----------------------------------------------------------------------------
298 
299 void SdrTableObjImpl::operator=( const SdrTableObjImpl& rSource )
300 {
301     if( mpLayouter )
302     {
303         delete mpLayouter;
304         mpLayouter = 0;
305     }
306 
307     if( mxTable.is() )
308     {
309         Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
310         mxTable->removeModifyListener( xListener );
311         mxTable->dispose();
312         mxTable.clear();
313     }
314 
315     maTableStyle = rSource.maTableStyle;
316 
317     mxTable = new TableModel( mpTableObj, rSource.mxTable );
318     mpLayouter = new TableLayouter( mxTable );
319     Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
320     mxTable->addModifyListener( xListener );
321     mxTableStyle = rSource.mxTableStyle;
322     UpdateWritingMode();
323     ApplyCellStyles();
324     mpTableObj->aRect = mpTableObj->maLogicRect;
325     LayoutTable( mpTableObj->aRect, false, false );
326 }
327 
328 // -----------------------------------------------------------------------------
329 
330 void SdrTableObjImpl::SetModel(SdrModel* /*pOldModel*/, SdrModel* pNewModel)
331 {
332     // try to find new table style
333     disconnectTableStyle();
334 
335     Reference< XIndexAccess > xNewTableStyle;
336     if( mxTableStyle.is() ) try
337     {
338         const OUString sStyleName( Reference< XNamed >( mxTableStyle, UNO_QUERY_THROW )->getName() );
339 
340         Reference< XStyleFamiliesSupplier > xSFS( pNewModel->getUnoModel(), UNO_QUERY_THROW );
341         Reference< XNameAccess > xFamilyNameAccess( xSFS->getStyleFamilies(), UNO_QUERY_THROW );
342         const rtl::OUString sFamilyName( RTL_CONSTASCII_USTRINGPARAM( "table" ) );
343         Reference< XNameAccess > xTableFamilyAccess( xFamilyNameAccess->getByName( sFamilyName ), UNO_QUERY_THROW );
344 
345         if( xTableFamilyAccess->hasByName( sStyleName ) )
346         {
347             // found table style with the same name
348             xTableFamilyAccess->getByName( sStyleName ) >>= xNewTableStyle;
349         }
350         else
351         {
352             // copy or?
353             Reference< XIndexAccess > xIndexAccess( xTableFamilyAccess, UNO_QUERY_THROW );
354             xIndexAccess->getByIndex( 0 ) >>= xNewTableStyle;
355         }
356     }
357     catch( Exception& )
358     {
359         DBG_ERROR("svx::SdrTableObjImpl::SetModel(), exception caught!");
360     }
361 
362     mxTableStyle = xNewTableStyle;
363 
364     connectTableStyle();
365     update();
366 }
367 
368 // -----------------------------------------------------------------------------
369 
370 bool SdrTableObjImpl::ApplyCellStyles()
371 {
372     if( !mxTable.is() || !mxTable.is() || !mxTableStyle.is() )
373         return false;
374 
375     bool bChanges = false;
376 
377     const sal_Int32 nColCount = getColumnCount();
378     const sal_Int32 nRowCount = getRowCount();
379 
380     const TableStyleSettings& rStyle = maTableStyle;
381 
382     CellPos aPos;
383     for( aPos.mnRow = 0; aPos.mnRow < nRowCount; ++aPos.mnRow )
384     {
385         const bool bFirstRow = (aPos.mnRow == 0) && rStyle.mbUseFirstRow;
386         const bool bLastRow = (aPos.mnRow == nRowCount-1) && rStyle.mbUseLastRow;
387 
388         for( aPos.mnCol = 0; aPos.mnCol < nColCount; ++aPos.mnCol )
389         {
390             Reference< XStyle > xStyle;
391 
392             // first and last row win first, if used and available
393             if( bFirstRow )
394             {
395                 mxTableStyle->getByIndex(first_row_style) >>= xStyle;
396             }
397             else if( bLastRow )
398             {
399                 mxTableStyle->getByIndex(last_row_style) >>= xStyle;
400             }
401 
402             if( !xStyle.is() )
403             {
404                 // next come first and last column, if used and available
405                 if( rStyle.mbUseFirstColumn && (aPos.mnCol == 0)  )
406                 {
407                     mxTableStyle->getByIndex(first_column_style) >>= xStyle;
408                 }
409                 else if( rStyle.mbUseLastColumn && (aPos.mnCol == nColCount-1) )
410                 {
411                     mxTableStyle->getByIndex(last_column_style) >>= xStyle;
412                 }
413             }
414 
415             if( !xStyle.is() && rStyle.mbUseRowBanding )
416             {
417                 if( (aPos.mnRow & 1) == 0 )
418                 {
419                     mxTableStyle->getByIndex(even_rows_style) >>= xStyle;
420                 }
421                 else
422                 {
423                     mxTableStyle->getByIndex(odd_rows_style) >>= xStyle;
424                 }
425             }
426 
427             if( !xStyle.is() && rStyle.mbUseColumnBanding )
428             {
429                 if( (aPos.mnCol & 1) == 0 )
430                 {
431                     mxTableStyle->getByIndex(even_columns_style) >>= xStyle;
432                 }
433                 else
434                 {
435                     mxTableStyle->getByIndex(odd_columns_style) >>= xStyle;
436                 }
437             }
438 
439             if( !xStyle.is() )
440             {
441                 // use default cell style if non found yet
442                 mxTableStyle->getByIndex(body_style) >>= xStyle;
443             }
444 
445 
446             if( xStyle.is() )
447             {
448                 SfxUnoStyleSheet* pStyle = SfxUnoStyleSheet::getUnoStyleSheet(xStyle);
449 
450                 if( pStyle )
451                 {
452                     CellRef xCell( getCell( aPos ) );
453                     if( xCell.is() && ( xCell->GetStyleSheet() != pStyle ) )
454                     {
455                         bChanges = true;
456                         xCell->SetStyleSheet( pStyle, sal_True );
457                     }
458                 }
459             }
460         }
461     }
462 
463     return bChanges;
464 }
465 
466 // -----------------------------------------------------------------------------
467 
468 void SdrTableObjImpl::dispose()
469 {
470     if( mxTable.is() )
471         mxTable->dispose();
472 }
473 
474 // -----------------------------------------------------------------------------
475 
476 void SdrTableObjImpl::DragEdge( bool mbHorizontal, int nEdge, sal_Int32 nOffset )
477 {
478     if( (nEdge > 0) && mxTable.is()) try
479     {
480         const OUString sSize( RTL_CONSTASCII_USTRINGPARAM( "Size" ) );
481         nEdge--;
482         if( mbHorizontal )
483         {
484             if( (nEdge >= 0) && (nEdge < getRowCount()) )
485             {
486                 sal_Int32 nHeigth = mpLayouter->getRowHeight( nEdge );
487                 nHeigth += nOffset;
488                 Reference< XIndexAccess > xRows( mxTable->getRows(), UNO_QUERY_THROW );
489                 Reference< XPropertySet > xRowSet( xRows->getByIndex( nEdge ), UNO_QUERY_THROW );
490                 xRowSet->setPropertyValue( sSize, Any( nHeigth ) );
491             }
492         }
493         else
494         {
495             if( (nEdge >= 0) && (nEdge < getColumnCount()) )
496             {
497                 sal_Int32 nWidth = mpLayouter->getColumnWidth( nEdge );
498                 nWidth += nOffset;
499 
500                 Reference< XIndexAccess > xCols( mxTable->getColumns(), UNO_QUERY_THROW );
501                 Reference< XPropertySet > xColSet( xCols->getByIndex( nEdge ), UNO_QUERY_THROW );
502                 xColSet->setPropertyValue( sSize, Any( nWidth ) );
503 
504                 if( nEdge > 0 && nEdge < mxTable->getColumnCount() )
505                 {
506                     const bool bRTL = mpLayouter->GetWritingMode() == WritingMode_RL_TB;
507 
508                     if( bRTL )
509                         nEdge--;
510                     else
511                         nEdge++;
512 
513                     if( (bRTL && (nEdge >= 0)) || (!bRTL && (nEdge < mxTable->getColumnCount())) )
514                     {
515                         nWidth = mpLayouter->getColumnWidth( nEdge );
516                         nWidth = std::max( (sal_Int32)(nWidth - nOffset), (sal_Int32)0 );
517 
518                         xColSet = Reference< XPropertySet >( xCols->getByIndex( nEdge ), UNO_QUERY_THROW );
519                         xColSet->setPropertyValue( sSize, Any( nWidth ) );
520                     }
521                 }
522             }
523         }
524     }
525     catch( Exception& )
526     {
527         DBG_ERROR( "svx::SdrTableObjImpl::DragEdge(), exception caught!" );
528     }
529 }
530 
531 // -----------------------------------------------------------------------------
532 // XModifyListener
533 // -----------------------------------------------------------------------------
534 
535 void SAL_CALL SdrTableObjImpl::modified( const ::com::sun::star::lang::EventObject& /*aEvent*/ ) throw (::com::sun::star::uno::RuntimeException)
536 {
537     update();
538 }
539 
540 void SdrTableObjImpl::update()
541 {
542     // source can be the table model itself or the assigned table template
543     TableModelNotifyGuard aGuard( mxTable.get() );
544     if( mpTableObj )
545     {
546         if( (maEditPos.mnRow >= getRowCount()) || (maEditPos.mnCol >= getColumnCount()) || (getCell( maEditPos ) != mxActiveCell) )
547         {
548             if(maEditPos.mnRow >= getRowCount())
549                 maEditPos.mnRow = getRowCount()-1;
550 
551             if(maEditPos.mnCol >= getColumnCount())
552                 maEditPos.mnCol = getColumnCount()-1;
553 
554             mpTableObj->setActiveCell( maEditPos );
555         }
556 
557         ApplyCellStyles();
558 
559         mpTableObj->aRect = mpTableObj->maLogicRect;
560         LayoutTable( mpTableObj->aRect, false, false );
561 
562         mpTableObj->SetRectsDirty();
563         mpTableObj->ActionChanged();
564         mpTableObj->BroadcastObjectChange();
565     }
566 }
567 
568 // -----------------------------------------------------------------------------
569 
570 void SdrTableObjImpl::connectTableStyle()
571 {
572     if( mxTableStyle.is() )
573     {
574         Reference< XModifyBroadcaster > xBroadcaster( mxTableStyle, UNO_QUERY );
575         if( xBroadcaster.is() )
576         {
577             Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
578             xBroadcaster->addModifyListener( xListener );
579         }
580     }
581 }
582 
583 // -----------------------------------------------------------------------------
584 
585 void SdrTableObjImpl::disconnectTableStyle()
586 {
587     if( mxTableStyle.is() )
588     {
589         Reference< XModifyBroadcaster > xBroadcaster( mxTableStyle, UNO_QUERY );
590         if( xBroadcaster.is() )
591         {
592             Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
593             xBroadcaster->removeModifyListener( xListener );
594         }
595     }
596 }
597 
598 // -----------------------------------------------------------------------------
599 
600 bool SdrTableObjImpl::isInUse()
601 {
602     return mpTableObj && mpTableObj->IsInserted();
603 }
604 
605 // -----------------------------------------------------------------------------
606 // XEventListener
607 // -----------------------------------------------------------------------------
608 
609 void SAL_CALL SdrTableObjImpl::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException)
610 {
611     mxActiveCell.clear();
612     mxTable.clear();
613     if( mpLayouter )
614     {
615         delete mpLayouter;
616         mpLayouter = 0;
617     }
618     mpTableObj = 0;
619 }
620 
621 // -----------------------------------------------------------------------------
622 
623 CellRef SdrTableObjImpl::getCell(  const CellPos& rPos  ) const
624 {
625     CellRef xCell;
626     if( mxTable.is() ) try
627     {
628         xCell.set( dynamic_cast< Cell* >( mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ).get() ) );
629     }
630     catch( Exception& )
631     {
632         DBG_ERROR( "svx::SdrTableObjImpl::getCell(), exception caught!" );
633     }
634     return xCell;
635 }
636 
637 // -----------------------------------------------------------------------------
638 
639 sal_Int32 SdrTableObjImpl::getColumnCount() const
640 {
641     return mxTable.is() ? mxTable->getColumnCount() : 0;
642 }
643 
644 // -----------------------------------------------------------------------------
645 
646 sal_Int32 SdrTableObjImpl::getRowCount() const
647 {
648     return mxTable.is() ? mxTable->getRowCount() : 0;
649 }
650 
651 // -----------------------------------------------------------------------------
652 
653 void SdrTableObjImpl::LayoutTable( Rectangle& rArea, bool bFitWidth, bool bFitHeight )
654 {
655     if( mpLayouter && mpTableObj->GetModel() )
656     {
657         TableModelNotifyGuard aGuard( mxTable.get() );
658         mpLayouter->LayoutTable( rArea, bFitWidth, bFitHeight );
659     }
660 }
661 
662 // -----------------------------------------------------------------------------
663 
664 bool SdrTableObjImpl::UpdateWritingMode()
665 {
666     if( mpTableObj && mpLayouter )
667     {
668         WritingMode eWritingMode = (WritingMode)static_cast< const SvxWritingModeItem& >( mpTableObj->GetObjectItem( SDRATTR_TEXTDIRECTION ) ).GetValue();
669 
670         if( eWritingMode != WritingMode_TB_RL )
671         {
672             if( static_cast< const SvxFrameDirectionItem& >( mpTableObj->GetObjectItem( EE_PARA_WRITINGDIR ) ).GetValue() == FRMDIR_HORI_LEFT_TOP )
673                 eWritingMode = WritingMode_LR_TB;
674             else
675                 eWritingMode = WritingMode_RL_TB;
676         }
677 
678         if( eWritingMode != mpLayouter->GetWritingMode() )
679         {
680             mpLayouter->SetWritingMode( eWritingMode );
681             return true;
682         }
683     }
684     return false;
685 }
686 
687 // -----------------------------------------------------------------------------
688 
689 void SdrTableObjImpl::UpdateCells( Rectangle& rArea )
690 {
691     if( mpLayouter && mxTable.is() )
692     {
693         TableModelNotifyGuard aGuard( mxTable.get() );
694         mpLayouter->updateCells( rArea );
695         mxTable->setModified(sal_True);
696     }
697 }
698 
699 // -----------------------------------------------------------------------------
700 
701 const SfxPoolItem* SdrTableObjImpl::GetCellItem( const CellPos& rPos, sal_uInt16 nWhich ) const
702 {
703     CellRef xCell( getCell( rPos  ) );
704     if( xCell.is() )
705         return xCell->GetItemSet().GetItem( nWhich );
706     else
707         return 0;
708 }
709 
710 // -----------------------------------------------------------------------------
711 // BaseProperties section
712 // -----------------------------------------------------------------------------
713 
714 sdr::properties::BaseProperties* SdrTableObj::CreateObjectSpecificProperties()
715 {
716     return new TableProperties(*this);
717 }
718 
719 // -----------------------------------------------------------------------------
720 // DrawContact section
721 // -----------------------------------------------------------------------------
722 
723 sdr::contact::ViewContact* SdrTableObj::CreateObjectSpecificViewContact()
724 {
725     return new sdr::contact::ViewContactOfTableObj(*this);
726 }
727 
728 // --------------------------------------------------------------------
729 
730 TYPEINIT1(SdrTableObj,SdrTextObj);
731 
732 // --------------------------------------------------------------------
733 
734 SdrTableObj::SdrTableObj(SdrModel* _pModel)
735 {
736     pModel = _pModel;
737     init( 1, 1 );
738 }
739 
740 // --------------------------------------------------------------------
741 
742 SdrTableObj::SdrTableObj(SdrModel* _pModel, const ::Rectangle& rNewRect, sal_Int32 nColumns, sal_Int32 nRows)
743 : SdrTextObj( rNewRect )
744 , maLogicRect( rNewRect )
745 {
746     pModel = _pModel;
747 
748     if( nColumns <= 0 )
749         nColumns = 1;
750 
751     if( nRows <= 0 )
752         nRows = 1;
753 
754     init( nColumns, nRows );
755 }
756 
757 // --------------------------------------------------------------------
758 
759 void SdrTableObj::init( sal_Int32 nColumns, sal_Int32 nRows )
760 {
761     bClosedObj = sal_True;
762 
763     mpImpl = new SdrTableObjImpl;
764     mpImpl->acquire();
765     mpImpl->init( this, nColumns, nRows );
766 }
767 
768 // --------------------------------------------------------------------
769 
770 SdrTableObj::~SdrTableObj()
771 {
772     mpImpl->dispose();
773     mpImpl->release();
774 }
775 
776 // --------------------------------------------------------------------
777 // table stuff
778 // --------------------------------------------------------------------
779 
780 Reference< XTable > SdrTableObj::getTable() const
781 {
782     return Reference< XTable >( mpImpl->mxTable.get() );
783 }
784 
785 // --------------------------------------------------------------------
786 
787 bool SdrTableObj::isValid( const CellPos& rPos ) const
788 {
789     return (rPos.mnCol >= 0) && (rPos.mnCol < mpImpl->getColumnCount()) && (rPos.mnRow >= 0) && (rPos.mnRow < mpImpl->getRowCount());
790 }
791 
792 // --------------------------------------------------------------------
793 
794 CellPos SdrTableObj::getFirstCell() const
795 {
796     return CellPos( 0,0 );
797 }
798 
799 // --------------------------------------------------------------------
800 
801 CellPos SdrTableObj::getLastCell() const
802 {
803     CellPos aPos;
804     if( mpImpl->mxTable.is() )
805     {
806         aPos.mnCol = mpImpl->getColumnCount()-1;
807         aPos.mnRow = mpImpl->getRowCount()-1;
808     }
809     return aPos;
810 }
811 
812 // --------------------------------------------------------------------
813 
814 CellPos SdrTableObj::getLeftCell( const CellPos& rPos, bool bEdgeTravel ) const
815 {
816     switch( GetWritingMode() )
817     {
818     default:
819     case WritingMode_LR_TB:
820         return getPreviousCell( rPos, bEdgeTravel );
821     case WritingMode_RL_TB:
822         return getNextCell( rPos, bEdgeTravel );
823     case WritingMode_TB_RL:
824         return getPreviousRow( rPos, bEdgeTravel );
825     }
826 }
827 
828 // --------------------------------------------------------------------
829 
830 CellPos SdrTableObj::getRightCell( const CellPos& rPos, bool bEdgeTravel  ) const
831 {
832     switch( GetWritingMode() )
833     {
834     default:
835     case WritingMode_LR_TB:
836         return getNextCell( rPos, bEdgeTravel );
837     case WritingMode_RL_TB:
838         return getPreviousCell( rPos, bEdgeTravel );
839     case WritingMode_TB_RL:
840         return getNextRow( rPos, bEdgeTravel );
841     }
842 }
843 
844 // --------------------------------------------------------------------
845 
846 CellPos SdrTableObj::getUpCell( const CellPos& rPos, bool bEdgeTravel ) const
847 {
848     switch( GetWritingMode() )
849     {
850     default:
851     case WritingMode_LR_TB:
852     case WritingMode_RL_TB:
853         return getPreviousRow( rPos, bEdgeTravel );
854     case WritingMode_TB_RL:
855         return getPreviousCell( rPos, bEdgeTravel );
856     }
857 }
858 
859 // --------------------------------------------------------------------
860 
861 CellPos SdrTableObj::getDownCell( const CellPos& rPos, bool bEdgeTravel ) const
862 {
863     switch( GetWritingMode() )
864     {
865     default:
866     case WritingMode_LR_TB:
867     case WritingMode_RL_TB:
868         return getNextRow( rPos, bEdgeTravel );
869     case WritingMode_TB_RL:
870         return getNextCell( rPos, bEdgeTravel );
871     }
872 }
873 
874 // --------------------------------------------------------------------
875 
876 CellPos SdrTableObj::getPreviousCell( const CellPos& rPos, bool bEdgeTravel ) const
877 {
878     CellPos aPos( rPos );
879     if( mpImpl )
880     {
881         CellRef xCell( mpImpl->getCell( aPos ) );
882         if( xCell.is() && xCell->isMerged() )
883         {
884             sal_Int32 nTemp = 0;
885             findMergeOrigin( mpImpl->mxTable.get(), aPos.mnCol, aPos.mnRow, aPos.mnCol, nTemp );
886         }
887 
888         if( aPos.mnCol > 0 )
889         {
890             --aPos.mnCol;
891         }
892 
893         else if( bEdgeTravel && (aPos.mnRow > 0) )
894         {
895             aPos.mnCol = mpImpl->mxTable->getColumnCount()-1;
896             --aPos.mnRow;
897         }
898     }
899     return aPos;
900 }
901 
902 // --------------------------------------------------------------------
903 
904 CellPos SdrTableObj::getNextCell( const CellPos& rPos, bool bEdgeTravel ) const
905 {
906     CellPos aPos( rPos );
907     if( mpImpl )
908     {
909         CellRef xCell( mpImpl->getCell( aPos ) );
910         if( xCell.is() )
911         {
912             if( xCell->isMerged() )
913             {
914                 findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, aPos.mnCol, aPos.mnRow );
915 
916                 xCell = mpImpl->getCell(aPos);
917 
918                 if( xCell.is() )
919                 {
920                     aPos.mnCol += xCell->getColumnSpan();
921                     aPos.mnRow = rPos.mnRow;
922                 }
923             }
924             else
925             {
926                 aPos.mnCol += xCell->getColumnSpan();
927             }
928 
929             if( aPos.mnCol < mpImpl->mxTable->getColumnCount() )
930                 return aPos;
931 
932             if( bEdgeTravel && ((aPos.mnRow + 1) < mpImpl->getRowCount()) )
933             {
934                 aPos.mnCol = 0;
935                 aPos.mnRow += 1;
936                 return aPos;
937             }
938         }
939     }
940 
941     // last cell reached, no traveling possible
942     return rPos;
943 }
944 
945 // --------------------------------------------------------------------
946 
947 CellPos SdrTableObj::getPreviousRow( const CellPos& rPos, bool bEdgeTravel ) const
948 {
949     CellPos aPos( rPos );
950     if( mpImpl )
951     {
952         CellRef xCell( mpImpl->getCell( aPos ) );
953         if( xCell.is() )
954         {
955             if( xCell->isMerged() )
956             {
957                 sal_Int32 nTemp = 0;
958                 findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, nTemp, aPos.mnRow );
959             }
960         }
961 
962         if( aPos.mnRow > 0 )
963         {
964             --aPos.mnRow;
965         }
966         else if( bEdgeTravel && (aPos.mnCol > 0) )
967         {
968             aPos.mnRow = mpImpl->mxTable->getRowCount()-1;
969             --aPos.mnCol;
970         }
971     }
972     return aPos;
973 }
974 
975 // --------------------------------------------------------------------
976 
977 CellPos SdrTableObj::getNextRow( const CellPos& rPos, bool bEdgeTravel ) const
978 {
979     CellPos aPos( rPos );
980 
981     if( mpImpl )
982     {
983         CellRef xCell( mpImpl->getCell( rPos ) );
984         if( xCell.is() )
985         {
986             if( xCell->isMerged() )
987             {
988                 findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, aPos.mnCol, aPos.mnRow );
989                 xCell = mpImpl->getCell(aPos);
990                 aPos.mnCol = rPos.mnCol;
991             }
992 
993             if( xCell.is() )
994                 aPos.mnRow += xCell->getRowSpan();
995 
996             if( aPos.mnRow < mpImpl->mxTable->getRowCount() )
997                 return aPos;
998 
999             if( bEdgeTravel && (aPos.mnCol + 1) < mpImpl->mxTable->getColumnCount() )
1000             {
1001                 aPos.mnRow = 0;
1002                 aPos.mnCol += 1;
1003 
1004                 while( aPos.mnCol < mpImpl->mxTable->getColumnCount() )
1005                 {
1006                     xCell = mpImpl->getCell( aPos );
1007                     if( xCell.is() && !xCell->isMerged() )
1008                         return aPos;
1009                     aPos.mnCol += 1;
1010                 }
1011             }
1012         }
1013     }
1014 
1015     // last position reached, no more traveling possible
1016     return rPos;
1017 }
1018 
1019 // --------------------------------------------------------------------
1020 
1021 const TableStyleSettings& SdrTableObj::getTableStyleSettings() const
1022 {
1023     if( mpImpl )
1024     {
1025         return mpImpl->maTableStyle;
1026     }
1027     else
1028     {
1029         static TableStyleSettings aTmp;
1030         return aTmp;
1031     }
1032 }
1033 
1034 // --------------------------------------------------------------------
1035 
1036 void SdrTableObj::setTableStyleSettings( const TableStyleSettings& rStyle )
1037 {
1038     if( mpImpl )
1039     {
1040         mpImpl->maTableStyle = rStyle;
1041         mpImpl->update();
1042     }
1043 }
1044 
1045 // --------------------------------------------------------------------
1046 
1047 TableHitKind SdrTableObj::CheckTableHit( const Point& rPos, sal_Int32& rnX, sal_Int32& rnY, int nTol ) const
1048 {
1049     if( !mpImpl || !mpImpl->mxTable.is() )
1050         return SDRTABLEHIT_NONE;
1051 
1052     rnX = 0;
1053     rnY = 0;
1054 
1055     const sal_Int32 nColCount = mpImpl->getColumnCount();
1056     const sal_Int32 nRowCount = mpImpl->getRowCount();
1057 
1058     sal_Int32 nX = rPos.X() + nTol - aRect.nLeft;
1059     sal_Int32 nY = rPos.Y() + nTol - aRect.nTop;
1060 
1061     if( (nX < 0) || (nX > (aRect.GetWidth() + nTol)) || (nY < 0) || (nY > (aRect.GetHeight() + nTol) ) )
1062         return SDRTABLEHIT_NONE;
1063 
1064     // get vertical edge number and check for a hit
1065     const bool bRTL = GetWritingMode() == WritingMode_RL_TB;
1066     bool bVrtHit = false;
1067     if( nX >= 0 )
1068     {
1069         if( !bRTL )
1070         {
1071             while( rnX <= nColCount )
1072             {
1073                 if( nX <= (2*nTol) )
1074                 {
1075                     bVrtHit = true;
1076                     break;
1077                 }
1078 
1079                 if( rnX == nColCount )
1080                     break;
1081 
1082                 nX -= mpImpl->mpLayouter->getColumnWidth( rnX );
1083                 if( nX < 0 )
1084                     break;
1085                 rnX++;
1086             }
1087         }
1088         else
1089         {
1090             rnX = nColCount;
1091             while( rnX >= 0 )
1092             {
1093                 if( nX <= (2*nTol) )
1094                 {
1095                     bVrtHit = true;
1096                     break;
1097                 }
1098 
1099                 if( rnX == 0 )
1100                     break;
1101 
1102                 rnX--;
1103                 nX -= mpImpl->mpLayouter->getColumnWidth( rnX );
1104                 if( nX < 0 )
1105                     break;
1106             }
1107         }
1108     }
1109 
1110     // rnX is now the edge number left to the pointer, if it was hit bHrzHit is also true
1111 
1112     // get vertical edge number and check for a hit
1113     bool bHrzHit = false;
1114     if( nY >= 0 )
1115     {
1116         while( rnY <= nRowCount )
1117         {
1118             if( nY <= (2*nTol) )
1119             {
1120                 bHrzHit = true;
1121                 break;
1122             }
1123 
1124             if( rnY == nRowCount )
1125                 break;
1126 
1127             nY -= mpImpl->mpLayouter->getRowHeight(rnY);
1128             if( nY < 0 )
1129                 break;
1130             rnY++;
1131         }
1132     }
1133 
1134     // rnY is now the edge number above the pointer, if it was hit bVrtHit is also true
1135 
1136     if( bVrtHit && mpImpl->mpLayouter->isEdgeVisible( rnX, rnY, false ) )
1137         return SDRTABLEHIT_VERTICAL_BORDER;
1138 
1139     if( bHrzHit && mpImpl->mpLayouter->isEdgeVisible( rnX, rnY, true ) )
1140         return SDRTABLEHIT_HORIZONTAL_BORDER;
1141 
1142     CellRef xCell( mpImpl->getCell( CellPos( rnX, rnY ) ) );
1143     if( xCell.is() && xCell->isMerged() )
1144         findMergeOrigin( mpImpl->mxTable.get(), rnX, rnY, rnX, rnY );
1145 
1146     if( xCell.is() )
1147     {
1148         nX += mpImpl->mpLayouter->getColumnWidth( rnX );
1149         if( nX < xCell->GetTextLeftDistance() )
1150             return SDRTABLEHIT_CELL;
1151     }
1152 
1153     return SDRTABLEHIT_CELLTEXTAREA;
1154 }
1155 
1156 const SfxItemSet& SdrTableObj::GetActiveCellItemSet() const
1157 {
1158     return getActiveCell()->GetItemSet();
1159 }
1160 
1161 // --------------------------------------------------------------------
1162 
1163 void SdrTableObj::InsertRows( sal_Int32 nIndex, sal_Int32 nCount /*= 1*/ )
1164 {
1165     if( mpImpl->mxTable.is() ) try
1166     {
1167         Reference< XTableRows > xRows( mpImpl->mxTable->getRows(), UNO_QUERY_THROW );
1168         xRows->insertByIndex( nIndex, nCount );
1169     }
1170     catch( Exception& )
1171     {
1172         DBG_ERROR("SdrTableObj::InsertRows(), exception caught!");
1173     }
1174 }
1175 
1176 // --------------------------------------------------------------------
1177 
1178 void SdrTableObj::InsertColumns( sal_Int32 nIndex, sal_Int32 nCount /*= 1*/ )
1179 {
1180     if( mpImpl->mxTable.is() ) try
1181     {
1182         Reference< XTableColumns > xColumns( mpImpl->mxTable->getColumns(), UNO_QUERY_THROW );
1183         xColumns->insertByIndex( nIndex, nCount );
1184     }
1185     catch( Exception& )
1186     {
1187         DBG_ERROR("SdrTableObj::InsertColumns(), exception caught!");
1188     }
1189 }
1190 
1191 // --------------------------------------------------------------------
1192 
1193 void SdrTableObj::DeleteRows( sal_Int32 nIndex, sal_Int32 nCount /*= 1*/ )
1194 {
1195     if( mpImpl->mxTable.is() ) try
1196     {
1197         Reference< XTableRows > xRows( mpImpl->mxTable->getRows(), UNO_QUERY_THROW );
1198         xRows->removeByIndex( nIndex, nCount );
1199     }
1200     catch( Exception& )
1201     {
1202         DBG_ERROR("SdrTableObj::DeleteRows(), exception caught!");
1203     }
1204 }
1205 
1206 // --------------------------------------------------------------------
1207 
1208 void SdrTableObj::DeleteColumns( sal_Int32 nIndex, sal_Int32 nCount /*= 1*/ )
1209 {
1210     if( mpImpl->mxTable.is() ) try
1211     {
1212         Reference< XTableColumns > xColumns( mpImpl->mxTable->getColumns(), UNO_QUERY_THROW );
1213         xColumns->removeByIndex( nIndex, nCount );
1214     }
1215     catch( Exception& )
1216     {
1217         DBG_ERROR("SdrTableObj::DeleteColumns(), exception caught!");
1218     }
1219 }
1220 
1221 // --------------------------------------------------------------------
1222 
1223 void SdrTableObj::setTableStyle( const Reference< XIndexAccess >& xTableStyle )
1224 {
1225     if( mpImpl && (mpImpl->mxTableStyle != xTableStyle) )
1226     {
1227         mpImpl->disconnectTableStyle();
1228         mpImpl->mxTableStyle = xTableStyle;
1229         mpImpl->connectTableStyle();
1230         mpImpl->update();
1231     }
1232 }
1233 
1234 // --------------------------------------------------------------------
1235 
1236 const Reference< XIndexAccess >& SdrTableObj::getTableStyle() const
1237 {
1238     if( mpImpl )
1239     {
1240         return mpImpl->mxTableStyle;
1241     }
1242     else
1243     {
1244         static Reference< XIndexAccess > aTmp;
1245         return aTmp;
1246     }
1247 }
1248 
1249 // --------------------------------------------------------------------
1250 // text stuff
1251 // --------------------------------------------------------------------
1252 
1253 /** returns the currently active text. */
1254 SdrText* SdrTableObj::getActiveText() const
1255 {
1256     return dynamic_cast< SdrText* >( getActiveCell().get() );
1257 }
1258 
1259 // --------------------------------------------------------------------
1260 
1261 /** returns the nth available text. */
1262 SdrText* SdrTableObj::getText( sal_Int32 nIndex ) const
1263 {
1264     if( mpImpl->mxTable.is() )
1265     {
1266         const sal_Int32 nColCount = mpImpl->getColumnCount();
1267         if( nColCount )
1268         {
1269             CellPos aPos( nIndex % nColCount, nIndex / nColCount );
1270 
1271             CellRef xCell( mpImpl->getCell( aPos ) );
1272             return dynamic_cast< SdrText* >( xCell.get() );
1273         }
1274     }
1275     return 0;
1276 }
1277 
1278 // --------------------------------------------------------------------
1279 
1280 /** returns the number of texts available for this object. */
1281 sal_Int32 SdrTableObj::getTextCount() const
1282 {
1283     if( mpImpl->mxTable.is() )
1284     {
1285         const sal_Int32 nColCount = mpImpl->getColumnCount();
1286         const sal_Int32 nRowCount = mpImpl->getRowCount();
1287 
1288         return nColCount * nRowCount;
1289     }
1290     else
1291     {
1292         return 0;
1293     }
1294 }
1295 
1296 // --------------------------------------------------------------------
1297 
1298 /** changes the current active text */
1299 void SdrTableObj::setActiveText( sal_Int32 nIndex )
1300 {
1301     if( mpImpl && mpImpl->mxTable.is() )
1302     {
1303         const sal_Int32 nColCount = mpImpl->mxTable->getColumnCount();
1304         if( nColCount )
1305         {
1306             CellPos aPos( nIndex % nColCount, nIndex / nColCount );
1307             if( isValid( aPos ) )
1308                 setActiveCell( aPos );
1309         }
1310     }
1311 }
1312 
1313 // --------------------------------------------------------------------
1314 
1315 /** returns the index of the text that contains the given point or -1 */
1316 sal_Int32 SdrTableObj::CheckTextHit(const Point& rPnt) const
1317 {
1318     if( mpImpl && mpImpl->mxTable.is() )
1319     {
1320         CellPos aPos;
1321         if( CheckTableHit( rPnt, aPos.mnCol, aPos.mnRow, 0 ) == SDRTABLEHIT_CELLTEXTAREA )
1322             return aPos.mnRow * mpImpl->mxTable->getColumnCount() + aPos.mnCol;
1323     }
1324 
1325     return 0;
1326 }
1327 
1328 // --------------------------------------------------------------------
1329 
1330 SdrOutliner* SdrTableObj::GetCellTextEditOutliner( const Cell& rCell ) const
1331 {
1332     if( mpImpl && (mpImpl->getCell( mpImpl->maEditPos ).get() == &rCell) )
1333         return pEdtOutl;
1334     else
1335         return 0;
1336 }
1337 
1338 
1339 // --------------------------------------------------------------------
1340 
1341 const TableLayouter& SdrTableObj::getTableLayouter() const
1342 {
1343     OSL_ENSURE(mpImpl && mpImpl->mpLayouter, "getTableLayouter() error: no mpImpl or mpLayouter (!)");
1344     return *(mpImpl->mpLayouter);
1345 }
1346 
1347 // --------------------------------------------------------------------
1348 
1349 void SdrTableObj::FitFrameToTextSize()
1350 {
1351     // todo
1352 }
1353 
1354 // --------------------------------------------------------------------
1355 
1356 FASTBOOL SdrTableObj::IsAutoGrowHeight() const
1357 {
1358     return sal_True;
1359 }
1360 
1361 // --------------------------------------------------------------------
1362 
1363 FASTBOOL SdrTableObj::IsAutoGrowWidth() const
1364 {
1365     return sal_True;
1366 }
1367 
1368 // --------------------------------------------------------------------
1369 
1370 bool SdrTableObj::HasText() const
1371 {
1372     return true;
1373 }
1374 
1375 // --------------------------------------------------------------------
1376 
1377 bool SdrTableObj::IsTextEditActive( const CellPos& rPos )
1378 {
1379     return pEdtOutl && mpImpl && (rPos == mpImpl->maEditPos);
1380 }
1381 
1382 // --------------------------------------------------------------------
1383 
1384 void SdrTableObj::onEditOutlinerStatusEvent( EditStatus* pEditStatus )
1385 {
1386     if( (pEditStatus->GetStatusWord() & EE_STAT_TEXTHEIGHTCHANGED) && mpImpl && mpImpl->mpLayouter )
1387     {
1388         Rectangle aRect0( aRect );
1389         aRect = maLogicRect;
1390 //      mpImpl->mpLayouter->setRowHeight( mpImpl->maEditPos.mnRow, mpImpl->mnSavedEditRowHeight );
1391         mpImpl->LayoutTable( aRect, false, false );
1392         SetRectsDirty();
1393         ActionChanged();
1394         BroadcastObjectChange();
1395         if( aRect0 != aRect )
1396             SendUserCall(SDRUSERCALL_RESIZE,aRect0);
1397     }
1398 }
1399 
1400 // --------------------------------------------------------------------
1401 
1402 void SdrTableObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
1403 {
1404     rInfo.bResizeFreeAllowed=sal_True;
1405     rInfo.bResizePropAllowed=sal_True;
1406     rInfo.bRotateFreeAllowed=sal_False;
1407     rInfo.bRotate90Allowed  =sal_False;
1408     rInfo.bMirrorFreeAllowed=sal_False;
1409     rInfo.bMirror45Allowed  =sal_False;
1410     rInfo.bMirror90Allowed  =sal_False;
1411 
1412     // allow transparence
1413     rInfo.bTransparenceAllowed = sal_True;
1414 
1415     // gradient depends on fillstyle
1416     XFillStyle eFillStyle = ((XFillStyleItem&)(GetObjectItem(XATTR_FILLSTYLE))).GetValue();
1417     rInfo.bGradientAllowed = (eFillStyle == XFILL_GRADIENT);
1418     rInfo.bShearAllowed     =sal_False;
1419     rInfo.bEdgeRadiusAllowed=sal_False;
1420     rInfo.bCanConvToPath    =sal_False;
1421     rInfo.bCanConvToPoly    =sal_False;
1422     rInfo.bCanConvToPathLineToArea=sal_False;
1423     rInfo.bCanConvToPolyLineToArea=sal_False;
1424     rInfo.bCanConvToContour = sal_False;
1425 }
1426 
1427 // --------------------------------------------------------------------
1428 
1429 sal_uInt16 SdrTableObj::GetObjIdentifier() const
1430 {
1431     return static_cast<sal_uInt16>(OBJ_TABLE);
1432 }
1433 
1434 // --------------------------------------------------------------------
1435 
1436 void SdrTableObj::SetPage(SdrPage* pNewPage)
1437 {
1438     SdrTextObj::SetPage(pNewPage);
1439 }
1440 
1441 // --------------------------------------------------------------------
1442 
1443 void SdrTableObj::SetModel(SdrModel* pNewModel)
1444 {
1445     SdrModel* pOldModel = GetModel();
1446     if( pNewModel != pOldModel )
1447     {
1448         SdrTextObj::SetModel(pNewModel);
1449 
1450         if( mpImpl )
1451         {
1452             mpImpl->SetModel( pOldModel, pNewModel );
1453 
1454             if( !maLogicRect.IsEmpty() )
1455             {
1456                 aRect = maLogicRect;
1457                 mpImpl->LayoutTable( aRect, false, false );
1458             }
1459         }
1460     }
1461 }
1462 
1463 // --------------------------------------------------------------------
1464 
1465 void SdrTableObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText, Rectangle* pAnchorRect, sal_Bool bLineWidth ) const
1466 {
1467     if( mpImpl )
1468         TakeTextRect( mpImpl->maEditPos, rOutliner, rTextRect, bNoEditText, pAnchorRect, bLineWidth );
1469 }
1470 
1471 // --------------------------------------------------------------------
1472 
1473 void SdrTableObj::TakeTextRect( const CellPos& rPos, SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText, Rectangle* pAnchorRect, sal_Bool /*bLineWidth*/ ) const
1474 {
1475     if( !mpImpl )
1476         return;
1477 
1478     CellRef xCell( mpImpl->getCell( rPos ) );
1479     if( !xCell.is() )
1480         return;
1481 
1482     Rectangle aAnkRect;
1483     TakeTextAnchorRect( rPos, aAnkRect );
1484 
1485     SdrTextVertAdjust eVAdj=xCell->GetTextVerticalAdjust();
1486 //  SdrTextHorzAdjust eHAdj=xCell->GetTextHorizontalAdjust();
1487 
1488     sal_uIntPtr nStat0=rOutliner.GetControlWord();
1489     Size aNullSize;
1490     nStat0 |= EE_CNTRL_AUTOPAGESIZE;
1491     rOutliner.SetControlWord(nStat0);
1492     rOutliner.SetMinAutoPaperSize(aNullSize);
1493     rOutliner.SetMaxAutoPaperSize(aAnkRect.GetSize());
1494     rOutliner.SetPaperSize(aAnkRect.GetSize());
1495 
1496     // #103516# New try with _BLOCK for hor and ver after completely
1497     // supporting full width for vertical text.
1498 //  if( SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
1499 //  {
1500         rOutliner.SetMinAutoPaperSize(Size(aAnkRect.GetWidth(), 0));
1501 //  }
1502 //  else if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
1503 //  {
1504 //      rOutliner.SetMinAutoPaperSize(Size(0, aAnkRect.GetHeight()));
1505 //  }
1506 
1507     // ---
1508 
1509     // set text at outliner, maybe from edit outliner
1510     OutlinerParaObject* pPara= xCell->GetOutlinerParaObject();
1511     if (pEdtOutl && !bNoEditText && mpImpl->mxActiveCell == xCell )
1512         pPara=pEdtOutl->CreateParaObject();
1513 
1514     if (pPara)
1515     {
1516         const bool bHitTest = pModel && (&pModel->GetHitTestOutliner() == &rOutliner);
1517 
1518         const SdrTextObj* pTestObj = rOutliner.GetTextObj();
1519         if( !pTestObj || !bHitTest || (pTestObj != this) || (pTestObj->GetOutlinerParaObject() != xCell->GetOutlinerParaObject()) )
1520         {
1521             if( bHitTest ) // #i33696# take back fix #i27510#
1522                 rOutliner.SetTextObj( this );
1523 
1524             rOutliner.SetUpdateMode(sal_True);
1525             rOutliner.SetText(*pPara);
1526         }
1527     }
1528     else
1529     {
1530         rOutliner.SetTextObj( NULL );
1531     }
1532 
1533     if (pEdtOutl && !bNoEditText && pPara && mpImpl->mxActiveCell == xCell )
1534         delete pPara;
1535 
1536     rOutliner.SetUpdateMode(sal_True);
1537     rOutliner.SetControlWord(nStat0);
1538 
1539     Point aTextPos(aAnkRect.TopLeft());
1540     Size aTextSiz(rOutliner.GetPaperSize());
1541 /*
1542     if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT)
1543     {
1544         long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width();
1545         if (eHAdj==SDRTEXTHORZADJUST_CENTER)
1546             aTextPos.X()+=nFreeWdt/2;
1547         if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
1548             aTextPos.X()+=nFreeWdt;
1549     }
1550 */
1551     if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM)
1552     {
1553         long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
1554         if (eVAdj==SDRTEXTVERTADJUST_CENTER)
1555             aTextPos.Y()+=nFreeHgt/2;
1556         if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
1557             aTextPos.Y()+=nFreeHgt;
1558     }
1559 
1560     if (pAnchorRect)
1561         *pAnchorRect=aAnkRect;
1562 
1563     rTextRect=Rectangle(aTextPos,aTextSiz);
1564 }
1565 
1566 // --------------------------------------------------------------------
1567 
1568 const CellRef& SdrTableObj::getActiveCell() const
1569 {
1570     if( mpImpl )
1571     {
1572         if( !mpImpl->mxActiveCell.is() )
1573         {
1574             CellPos aPos;
1575             const_cast< SdrTableObj* >(this)->setActiveCell( aPos );
1576         }
1577         return mpImpl->mxActiveCell;
1578     }
1579     else
1580     {
1581         static CellRef xCell;
1582         return xCell;
1583     }
1584 }
1585 
1586 // --------------------------------------------------------------------
1587 
1588 sal_Int32 SdrTableObj::getRowCount() const
1589 {
1590     return mpImpl ? mpImpl->getRowCount() : 0;
1591 }
1592 
1593 // --------------------------------------------------------------------
1594 
1595 sal_Int32 SdrTableObj::getColumnCount() const
1596 {
1597     return mpImpl ? mpImpl->getColumnCount() : 0;
1598 }
1599 
1600 // --------------------------------------------------------------------
1601 
1602 void SdrTableObj::setActiveCell( const CellPos& rPos )
1603 {
1604     if( mpImpl && mpImpl->mxTable.is() ) try
1605     {
1606         mpImpl->mxActiveCell.set( dynamic_cast< Cell* >( mpImpl->mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ).get() ) );
1607         if( mpImpl->mxActiveCell.is() && mpImpl->mxActiveCell->isMerged() )
1608         {
1609             CellPos aOrigin;
1610             findMergeOrigin( mpImpl->mxTable.get(), rPos.mnCol, rPos.mnRow, aOrigin.mnCol, aOrigin.mnRow );
1611             mpImpl->mxActiveCell.set( dynamic_cast< Cell* >( mpImpl->mxTable->getCellByPosition( aOrigin.mnCol, aOrigin.mnRow ).get() ) );
1612             mpImpl->maEditPos = aOrigin;
1613         }
1614         else
1615         {
1616             mpImpl->maEditPos = rPos;
1617         }
1618     }
1619     catch( Exception& )
1620     {
1621         DBG_ERROR("SdrTableObj::setActiveCell(), exception caught!");
1622     }
1623 }
1624 
1625 // --------------------------------------------------------------------
1626 
1627 void SdrTableObj::getActiveCellPos( CellPos& rPos ) const
1628 {
1629     rPos = mpImpl->maEditPos;
1630 }
1631 
1632 // --------------------------------------------------------------------
1633 
1634 void SdrTableObj::getCellBounds( const CellPos& rPos, ::Rectangle& rCellRect )
1635 {
1636     if( mpImpl )
1637     {
1638         CellRef xCell( mpImpl->getCell( rPos ) );
1639         if( xCell.is() )
1640             rCellRect = xCell->getCellRect();
1641     }
1642 }
1643 
1644 // --------------------------------------------------------------------
1645 
1646 void SdrTableObj::TakeTextAnchorRect(Rectangle& rAnchorRect) const
1647 {
1648     if( mpImpl )
1649         TakeTextAnchorRect( mpImpl->maEditPos, rAnchorRect );
1650 }
1651 
1652 // --------------------------------------------------------------------
1653 
1654 void SdrTableObj::TakeTextAnchorRect( const CellPos& rPos, Rectangle& rAnchorRect ) const
1655 {
1656     Rectangle aAnkRect(aRect);
1657 
1658     if( mpImpl )
1659     {
1660         CellRef xCell( mpImpl->getCell( rPos ) );
1661         if( xCell.is() )
1662             xCell->TakeTextAnchorRect( aAnkRect );
1663     }
1664 
1665     ImpJustifyRect(aAnkRect);
1666     rAnchorRect=aAnkRect;
1667 }
1668 
1669 // --------------------------------------------------------------------
1670 
1671 void SdrTableObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
1672 {
1673     if( mpImpl )
1674         TakeTextEditArea( mpImpl->maEditPos, pPaperMin, pPaperMax, pViewInit, pViewMin );
1675 }
1676 
1677 // --------------------------------------------------------------------
1678 
1679 void SdrTableObj::TakeTextEditArea( const CellPos& rPos, Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin ) const
1680 {
1681     Size aPaperMin,aPaperMax;
1682     Rectangle aViewInit;
1683     TakeTextAnchorRect( rPos, aViewInit );
1684 
1685     Size aAnkSiz(aViewInit.GetSize());
1686     aAnkSiz.Width()--; aAnkSiz.Height()--; // weil GetSize() ein draufaddiert
1687 
1688     Size aMaxSiz(aAnkSiz.Width(),1000000);
1689     if (pModel!=NULL)
1690     {
1691         Size aTmpSiz(pModel->GetMaxObjSize());
1692         if (aTmpSiz.Height()!=0)
1693             aMaxSiz.Height()=aTmpSiz.Height();
1694     }
1695 
1696     CellRef xCell( mpImpl->getCell( rPos ) );
1697     SdrTextVertAdjust eVAdj = xCell.is() ? xCell->GetTextVerticalAdjust() : SDRTEXTVERTADJUST_TOP;
1698 //  SdrTextHorzAdjust eHAdj = xCell.is() ? xCell->GetTextHorizontalAdjust() : SDRTEXTHORZADJUST_LEFT;
1699 
1700     aPaperMax=aMaxSiz;
1701 
1702 //  if((SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting()) || (SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting()))
1703         aPaperMin.Width() = aAnkSiz.Width();
1704 
1705     if (pViewMin!=NULL)
1706     {
1707         *pViewMin=aViewInit;
1708 /*
1709         long nXFree=aAnkSiz.Width()-aPaperMin.Width();
1710 
1711         if (eHAdj==SDRTEXTHORZADJUST_LEFT)
1712         {
1713             pViewMin->Right()-=nXFree;
1714         }
1715         else if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
1716         {
1717             pViewMin->Left()+=nXFree;
1718         }
1719         else
1720         {
1721             pViewMin->Left()+=nXFree/2;
1722             pViewMin->Right()=pViewMin->Left()+aPaperMin.Width();
1723         }
1724 */
1725         long nYFree=aAnkSiz.Height()-aPaperMin.Height();
1726 
1727         if (eVAdj==SDRTEXTVERTADJUST_TOP)
1728         {
1729             pViewMin->Bottom()-=nYFree;
1730         }
1731         else if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
1732         {
1733             pViewMin->Top()+=nYFree;
1734         }
1735         else
1736         {
1737             pViewMin->Top()+=nYFree/2;
1738             pViewMin->Bottom()=pViewMin->Top()+aPaperMin.Height();
1739         }
1740     }
1741 
1742 
1743     if(IsVerticalWriting())
1744         aPaperMin.Width() = 0;
1745     else
1746         aPaperMin.Height() = 0;
1747 
1748     if (pPaperMin!=NULL) *pPaperMin=aPaperMin;
1749     if (pPaperMax!=NULL) *pPaperMax=aPaperMax;
1750     if (pViewInit!=NULL) *pViewInit=aViewInit;
1751 }
1752 
1753 // --------------------------------------------------------------------
1754 
1755 sal_uInt16 SdrTableObj::GetOutlinerViewAnchorMode() const
1756 {
1757     EVAnchorMode eRet=ANCHOR_TOP_LEFT;
1758     CellRef xCell( getActiveCell() );
1759     if( xCell.is() )
1760     {
1761         SdrTextVertAdjust eV=xCell->GetTextVerticalAdjust();
1762 //      SdrTextHorzAdjust eH=xCell->GetTextHorizontalAdjust();
1763 
1764 //      if (eH==SDRTEXTHORZADJUST_LEFT)
1765         {
1766             if (eV==SDRTEXTVERTADJUST_TOP)
1767             {
1768                 eRet=ANCHOR_TOP_LEFT;
1769             }
1770             else if (eV==SDRTEXTVERTADJUST_BOTTOM)
1771             {
1772                 eRet=ANCHOR_BOTTOM_LEFT;
1773             }
1774             else
1775             {
1776                 eRet=ANCHOR_VCENTER_LEFT;
1777             }
1778         }
1779 /*
1780         else if (eH==SDRTEXTHORZADJUST_RIGHT)
1781         {
1782             if (eV==SDRTEXTVERTADJUST_TOP)
1783             {
1784                 eRet=ANCHOR_TOP_RIGHT;
1785             }
1786             else if (eV==SDRTEXTVERTADJUST_BOTTOM)
1787             {
1788                 eRet=ANCHOR_BOTTOM_RIGHT;
1789             }
1790             else
1791             {
1792                 eRet=ANCHOR_VCENTER_RIGHT;
1793             }
1794         }
1795         else
1796         {
1797             if (eV==SDRTEXTVERTADJUST_TOP)
1798             {
1799                 eRet=ANCHOR_TOP_HCENTER;
1800             }
1801             else if (eV==SDRTEXTVERTADJUST_BOTTOM)
1802             {
1803                 eRet=ANCHOR_BOTTOM_HCENTER;
1804             }
1805             else
1806             {
1807                 eRet=ANCHOR_VCENTER_HCENTER;
1808             }
1809         }
1810 */
1811     }
1812     return (sal_uInt16)eRet;
1813 }
1814 
1815 // --------------------------------------------------------------------
1816 
1817 OutlinerParaObject* SdrTableObj::GetEditOutlinerParaObject() const
1818 {
1819     return SdrTextObj::GetEditOutlinerParaObject();
1820 }
1821 
1822 // --------------------------------------------------------------------
1823 
1824 SdrOutliner* SdrTableObj::GetCellTextEditOutliner( const CellPos& rPos ) const
1825 {
1826     if( pEdtOutl && mpImpl && (mpImpl->maEditPos == rPos) )
1827         return pEdtOutl;
1828     else
1829         return 0;
1830 }
1831 
1832 // --------------------------------------------------------------------
1833 
1834 struct ImplTableShadowPaintInfo
1835 {
1836     Color maShadowColor;
1837     sal_uInt32 mnXDistance;
1838     sal_uInt32 mnYDistance;
1839     sal_uInt16 mnShadowTransparence;
1840 
1841     ImplTableShadowPaintInfo( const SfxItemSet& rSet )
1842     {
1843         const SdrShadowColorItem& rShadColItem = ((const SdrShadowColorItem&)(rSet.Get(SDRATTR_SHADOWCOLOR)));
1844         maShadowColor = rShadColItem.GetColorValue();
1845         mnShadowTransparence = ((const SdrShadowTransparenceItem&)(rSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue();
1846 
1847         mnXDistance = ((SdrShadowXDistItem&)(rSet.Get(SDRATTR_SHADOWXDIST))).GetValue();
1848         mnYDistance = ((SdrShadowYDistItem&)(rSet.Get(SDRATTR_SHADOWYDIST))).GetValue();
1849     }
1850 };
1851 
1852 // --------------------------------------------------------------------
1853 
1854 void lcl_VertLineEnds( OutputDevice& rDev, const Point& rTop, const Point& rBottom,
1855         const Color& rColor, long nXOffs, long nWidth,
1856         const svx::frame::Style& rTopLine, const svx::frame::Style& rBottomLine )
1857 {
1858     rDev.SetLineColor(rColor);              // PEN_NULL ???
1859     rDev.SetFillColor(rColor);
1860 
1861     //  Position oben/unten muss unabhaengig von der Liniendicke sein,
1862     //  damit der Winkel stimmt (oder X-Position auch anpassen)
1863     long nTopPos = rTop.Y();
1864     long nBotPos = rBottom.Y();
1865 
1866     long nTopLeft = rTop.X() + nXOffs;
1867     long nTopRight = nTopLeft + nWidth - 1;
1868 
1869     long nBotLeft = rBottom.X() + nXOffs;
1870     long nBotRight = nBotLeft + nWidth - 1;
1871 
1872     //  oben abschliessen
1873 
1874     if ( rTopLine.Prim() )
1875     {
1876         long nLineW = rTopLine.GetWidth();
1877         if (nLineW >= 2)
1878         {
1879             Point aTriangle[3];
1880             aTriangle[0] = Point( nTopLeft, nTopPos );      // wie aPoints[0]
1881             aTriangle[1] = Point( nTopRight, nTopPos );     // wie aPoints[1]
1882             aTriangle[2] = Point( rTop.X(), nTopPos - (nLineW - 1) / 2 );
1883             Polygon aTriPoly( 3, aTriangle );
1884             rDev.DrawPolygon( aTriPoly );
1885         }
1886     }
1887 
1888     //  unten abschliessen
1889 
1890     if ( rBottomLine.Prim() )
1891     {
1892         long nLineW = rBottomLine.GetWidth();
1893         if (nLineW >= 2)
1894         {
1895             Point aTriangle[3];
1896             aTriangle[0] = Point( nBotLeft, nBotPos );      // wie aPoints[3]
1897             aTriangle[1] = Point( nBotRight, nBotPos );     // wie aPoints[2]
1898             aTriangle[2] = Point( rBottom.X(), nBotPos - (nLineW - 1) / 2 + nLineW - 1 );
1899             Polygon aTriPoly( 3, aTriangle );
1900             rDev.DrawPolygon( aTriPoly );
1901         }
1902     }
1903 }
1904 
1905 void lcl_VertLine( OutputDevice& rDev, const Point& rTop, const Point& rBottom,
1906                     const svx::frame::Style& rLine,
1907                     const svx::frame::Style& rTopLine, const svx::frame::Style& rBottomLine,
1908                     const Color* pForceColor )
1909 {
1910     if( rLine.Prim() )
1911     {
1912         svx::frame::DrawVerFrameBorderSlanted( rDev, rTop, rBottom, rLine, pForceColor );
1913 
1914         svx::frame::Style aScaled( rLine );
1915         aScaled.ScaleSelf( 1.0 / cos( svx::frame::GetVerDiagAngle( rTop, rBottom ) ) );
1916         if( pForceColor )
1917             aScaled.SetColor( *pForceColor );
1918 
1919         long nXOffs = (aScaled.GetWidth() - 1) / -2L;
1920 
1921         lcl_VertLineEnds( rDev, rTop, rBottom, aScaled.GetColor(),
1922             nXOffs, aScaled.Prim(), rTopLine, rBottomLine );
1923 
1924         if( aScaled.Secn() )
1925             lcl_VertLineEnds( rDev, rTop, rBottom, aScaled.GetColor(),
1926                 nXOffs + aScaled.Prim() + aScaled.Dist(), aScaled.Secn(), rTopLine, rBottomLine );
1927     }
1928 }
1929 
1930 // --------------------------------------------------------------------
1931 
1932 void SdrTableObj::TakeObjNameSingul(XubString& rName) const
1933 {
1934     rName = ImpGetResStr(STR_ObjNameSingulTable);
1935 
1936     String aName( GetName() );
1937     if(aName.Len())
1938     {
1939         rName += sal_Unicode(' ');
1940         rName += sal_Unicode('\'');
1941         rName += aName;
1942         rName += sal_Unicode('\'');
1943     }
1944 }
1945 
1946 // --------------------------------------------------------------------
1947 
1948 void SdrTableObj::TakeObjNamePlural(XubString& rName) const
1949 {
1950     rName = ImpGetResStr(STR_ObjNamePluralTable);
1951 }
1952 
1953 // --------------------------------------------------------------------
1954 
1955 void SdrTableObj::operator=(const SdrObject& rObj)
1956 {
1957     // call parent
1958     SdrObject::operator=(rObj);
1959 
1960     const SdrTableObj* pTableObj = dynamic_cast< const SdrTableObj* >( &rObj );
1961     if (pTableObj!=NULL)
1962     {
1963         TableModelNotifyGuard aGuard( mpImpl ? mpImpl->mxTable.get() : 0 );
1964 
1965         maLogicRect = pTableObj->maLogicRect;
1966         aRect = pTableObj->aRect;
1967         aGeo = pTableObj->aGeo;
1968         eTextKind = pTableObj->eTextKind;
1969         bTextFrame = pTableObj->bTextFrame;
1970         aTextSize = pTableObj->aTextSize;
1971         bTextSizeDirty = pTableObj->bTextSizeDirty;
1972         bNoShear = pTableObj->bNoShear;
1973         bNoRotate = pTableObj->bNoRotate;
1974         bNoMirror = pTableObj->bNoMirror;
1975         bDisableAutoWidthOnDragging = pTableObj->bDisableAutoWidthOnDragging;
1976 
1977         if( pTableObj->mpImpl )
1978             *mpImpl = *pTableObj->mpImpl;
1979     }
1980 }
1981 
1982 // --------------------------------------------------------------------
1983 
1984 basegfx::B2DPolyPolygon SdrTableObj::TakeXorPoly() const
1985 {
1986     return SdrTextObj::TakeXorPoly();
1987 }
1988 
1989 // --------------------------------------------------------------------
1990 
1991 basegfx::B2DPolyPolygon SdrTableObj::TakeContour() const
1992 {
1993     return SdrTextObj::TakeContour();
1994 }
1995 
1996 // --------------------------------------------------------------------
1997 
1998 const Rectangle& SdrTableObj::GetSnapRect() const
1999 {
2000     return aRect;
2001 }
2002 
2003 // --------------------------------------------------------------------
2004 
2005 void SdrTableObj::NbcSetSnapRect(const Rectangle& rRect)
2006 {
2007     NbcSetLogicRect( rRect );
2008 }
2009 
2010 // --------------------------------------------------------------------
2011 
2012 const Rectangle& SdrTableObj::GetLogicRect() const
2013 {
2014     return maLogicRect;
2015 }
2016 
2017 // --------------------------------------------------------------------
2018 
2019 void SdrTableObj::RecalcSnapRect()
2020 {
2021 }
2022 
2023 // --------------------------------------------------------------------
2024 
2025 sal_uInt32 SdrTableObj::GetSnapPointCount() const
2026 {
2027     return SdrTextObj::GetSnapPointCount();
2028 }
2029 
2030 // --------------------------------------------------------------------
2031 
2032 
2033 Point SdrTableObj::GetSnapPoint(sal_uInt32 i) const
2034 {
2035     return SdrTextObj::GetSnapPoint(i);
2036 }
2037 
2038 // --------------------------------------------------------------------
2039 
2040 sal_Bool SdrTableObj::BegTextEdit(SdrOutliner& rOutl)
2041 {
2042     if( pEdtOutl != NULL )
2043         return sal_False;
2044 
2045     pEdtOutl=&rOutl;
2046 
2047 //  ForceOutlinerParaObject();
2048 
2049     mbInEditMode = sal_True;
2050 
2051     rOutl.Init( OUTLINERMODE_TEXTOBJECT );
2052     rOutl.SetRefDevice( pModel->GetRefDevice() );
2053 
2054 // --
2055         FASTBOOL bUpdMerk=rOutl.GetUpdateMode();
2056         if (bUpdMerk) rOutl.SetUpdateMode(sal_False);
2057         Size aPaperMin;
2058         Size aPaperMax;
2059         Rectangle aEditArea;
2060         TakeTextEditArea(&aPaperMin,&aPaperMax,&aEditArea,NULL);
2061 
2062         rOutl.SetMinAutoPaperSize(aPaperMin);
2063         rOutl.SetMaxAutoPaperSize(aPaperMax);
2064         rOutl.SetPaperSize(aPaperMax);
2065 
2066         if (bUpdMerk) rOutl.SetUpdateMode(sal_True);
2067 //---
2068 
2069     sal_uIntPtr nStat=rOutl.GetControlWord();
2070 //  nStat   &= ~EE_CNTRL_AUTOPAGESIZE;
2071     nStat   |= EE_CNTRL_AUTOPAGESIZE;
2072     nStat   &=~EE_CNTRL_STRETCHING;
2073     rOutl.SetControlWord(nStat);
2074 
2075     OutlinerParaObject* pPara = GetOutlinerParaObject();
2076     if(pPara)
2077         rOutl.SetText(*pPara);
2078 
2079     rOutl.UpdateFields();
2080     rOutl.ClearModifyFlag();
2081 
2082 //  mpImpl->mnSavedEditRowHeight = mpImpl->mpLayouter->getRowHeight( mpImpl->maEditPos.mnRow );
2083 
2084     return sal_True;
2085 }
2086 
2087 // --------------------------------------------------------------------
2088 
2089 void SdrTableObj::EndTextEdit(SdrOutliner& rOutl)
2090 {
2091     if(rOutl.IsModified())
2092     {
2093         if( GetModel() && GetModel()->IsUndoEnabled() )
2094             GetModel()->AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*this) );
2095 
2096         OutlinerParaObject* pNewText = 0;
2097         Paragraph* p1stPara = rOutl.GetParagraph( 0 );
2098         sal_uInt32 nParaAnz = rOutl.GetParagraphCount();
2099 
2100         if(p1stPara)
2101         {
2102             if(nParaAnz == 1)
2103             {
2104                 // if its only one paragraph, check if it is empty
2105                 XubString aStr(rOutl.GetText(p1stPara));
2106 
2107                 if(!aStr.Len())
2108                 {
2109                     // gotcha!
2110                     nParaAnz = 0;
2111                 }
2112             }
2113 
2114             // to remove the grey field background
2115             rOutl.UpdateFields();
2116 
2117             if(nParaAnz != 0)
2118             {
2119                 // create new text object
2120                 pNewText = rOutl.CreateParaObject( 0, (sal_uInt16)nParaAnz );
2121             }
2122         }
2123         SetOutlinerParaObject(pNewText);
2124     }
2125 
2126     pEdtOutl = 0;
2127     rOutl.Clear();
2128     sal_uInt32 nStat = rOutl.GetControlWord();
2129     nStat &= ~EE_CNTRL_AUTOPAGESIZE;
2130     rOutl.SetControlWord(nStat);
2131 
2132     mbInEditMode = sal_False;
2133 }
2134 
2135 // --------------------------------------------------------------------
2136 
2137 OutlinerParaObject* SdrTableObj::GetOutlinerParaObject() const
2138 {
2139     CellRef xCell( getActiveCell() );
2140     if( xCell.is() )
2141         return xCell->GetOutlinerParaObject();
2142     else
2143         return 0;
2144 }
2145 
2146 // --------------------------------------------------------------------
2147 
2148 void SdrTableObj::NbcSetOutlinerParaObject( OutlinerParaObject* pTextObject)
2149 {
2150     CellRef xCell( getActiveCell() );
2151     if( xCell.is() )
2152     {
2153         if( pModel )
2154         {
2155             // Update HitTestOutliner
2156             const SdrTextObj* pTestObj = pModel->GetHitTestOutliner().GetTextObj();
2157             if( pTestObj && pTestObj->GetOutlinerParaObject() == xCell->GetOutlinerParaObject() )
2158                 pModel->GetHitTestOutliner().SetTextObj( NULL );
2159         }
2160 
2161         xCell->SetOutlinerParaObject( pTextObject );
2162 
2163         SetTextSizeDirty();
2164         NbcAdjustTextFrameWidthAndHeight();
2165 //      ImpSetTextStyleSheetListeners();
2166 //      ImpCheckMasterCachable();
2167     }
2168 }
2169 
2170 // --------------------------------------------------------------------
2171 
2172 void SdrTableObj::NbcSetLogicRect(const Rectangle& rRect)
2173 {
2174     maLogicRect=rRect;
2175     ImpJustifyRect(maLogicRect);
2176     const bool bWidth = maLogicRect.getWidth() != aRect.getWidth();
2177     const bool bHeight = maLogicRect.getHeight() != aRect.getHeight();
2178     aRect=maLogicRect;
2179     NbcAdjustTextFrameWidthAndHeight( !bHeight, !bWidth );
2180     SetRectsDirty();
2181 }
2182 
2183 
2184 // --------------------------------------------------------------------
2185 
2186 void SdrTableObj::AdjustToMaxRect( const Rectangle& rMaxRect, bool /* bShrinkOnly = false */ )
2187 {
2188     Rectangle aAdjustRect( rMaxRect );
2189     aAdjustRect.setHeight( GetLogicRect().getHeight() );
2190     SetLogicRect( aAdjustRect );
2191 }
2192 
2193 // --------------------------------------------------------------------
2194 
2195 void SdrTableObj::NbcMove(const Size& rSiz)
2196 {
2197     MoveRect(maLogicRect,rSiz);
2198     SdrTextObj::NbcMove( rSiz );
2199     if( mpImpl )
2200         mpImpl->UpdateCells( aRect );
2201 }
2202 
2203 // --------------------------------------------------------------------
2204 
2205 void SdrTableObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
2206 {
2207     Rectangle aOldRect( maLogicRect );
2208     ResizeRect(maLogicRect,rRef,xFact,yFact);
2209 
2210     aRect = maLogicRect;
2211     NbcAdjustTextFrameWidthAndHeight( maLogicRect.GetHeight() == aOldRect.GetHeight(), maLogicRect.GetWidth() == aOldRect.GetWidth() );
2212     SetRectsDirty();
2213 }
2214 
2215 // --------------------------------------------------------------------
2216 
2217 FASTBOOL SdrTableObj::AdjustTextFrameWidthAndHeight(FASTBOOL bHgt, FASTBOOL bWdt)
2218 {
2219     Rectangle aNeuRect(maLogicRect);
2220     FASTBOOL bRet=AdjustTextFrameWidthAndHeight(aNeuRect,bHgt,bWdt);
2221     if (bRet)
2222     {
2223         Rectangle aBoundRect0;
2224         if (pUserCall!=NULL)
2225             aBoundRect0=GetLastBoundRect();
2226         aRect=aNeuRect;
2227         SetRectsDirty();
2228         SetChanged();
2229         BroadcastObjectChange();
2230         SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
2231     }
2232     return bRet;
2233 }
2234 
2235 // --------------------------------------------------------------------
2236 
2237 FASTBOOL SdrTableObj::AdjustTextFrameWidthAndHeight(Rectangle& rR, FASTBOOL bHeight, FASTBOOL bWidth) const
2238 {
2239     if((pModel == NULL) || rR.IsEmpty() || !mpImpl || !mpImpl->mxTable.is() )
2240         return sal_False;
2241 
2242     Rectangle aRectangle( rR );
2243     mpImpl->LayoutTable( aRectangle, !bWidth, !bHeight );
2244 
2245     if( aRectangle != rR )
2246     {
2247         rR = aRectangle;
2248         return sal_True;
2249     }
2250     else
2251     {
2252         return sal_False;
2253     }
2254 }
2255 
2256 // --------------------------------------------------------------------
2257 
2258 void SdrTableObj::NbcReformatText()
2259 {
2260     NbcAdjustTextFrameWidthAndHeight();
2261 }
2262 
2263 // --------------------------------------------------------------------
2264 
2265 void SdrTableObj::ReformatText()
2266 {
2267     Rectangle aBoundRect0;
2268     if (pUserCall!=NULL)
2269         aBoundRect0=GetLastBoundRect();
2270     NbcReformatText();
2271     SetChanged();
2272     BroadcastObjectChange();
2273     SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
2274 }
2275 
2276 // --------------------------------------------------------------------
2277 
2278 sal_Bool SdrTableObj::IsVerticalWriting() const
2279 {
2280     const SvxWritingModeItem* pModeItem = dynamic_cast< const SvxWritingModeItem* >( &GetObjectItem( SDRATTR_TEXTDIRECTION ) );
2281     return pModeItem && pModeItem->GetValue() == com::sun::star::text::WritingMode_TB_RL;
2282 }
2283 
2284 // --------------------------------------------------------------------
2285 
2286 void SdrTableObj::SetVerticalWriting(sal_Bool bVertical )
2287 {
2288     if( bVertical != IsVerticalWriting() )
2289     {
2290         SvxWritingModeItem aModeItem( com::sun::star::text::WritingMode_LR_TB, SDRATTR_TEXTDIRECTION );
2291         SetObjectItem( aModeItem );
2292     }
2293 }
2294 
2295 // --------------------------------------------------------------------
2296 
2297 WritingMode SdrTableObj::GetWritingMode() const
2298 {
2299     WritingMode eMode = WritingMode_LR_TB;
2300     if( mpImpl && mpImpl->mpLayouter )
2301         eMode = mpImpl->mpLayouter->GetWritingMode();
2302     return eMode;
2303 }
2304 
2305 // --------------------------------------------------------------------
2306 
2307 // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
2308 // with the base geometry and returns TRUE. Otherwise it returns FALSE.
2309 sal_Bool SdrTableObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& rPolyPolygon ) const
2310 {
2311     return SdrTextObj::TRGetBaseGeometry( rMatrix, rPolyPolygon );
2312 }
2313 
2314 // --------------------------------------------------------------------
2315 
2316 // sets the base geometry of the object using infos contained in the homogen 3x3 matrix.
2317 // If it's an SdrPathObj it will use the provided geometry information. The Polygon has
2318 // to use (0,0) as upper left and will be scaled to the given size in the matrix.
2319 void SdrTableObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& rPolyPolygon )
2320 {
2321     SdrTextObj::TRSetBaseGeometry( rMatrix, rPolyPolygon );
2322 }
2323 
2324 // --------------------------------------------------------------------
2325 
2326 bool SdrTableObj::IsRealyEdited() const
2327 {
2328     return pEdtOutl && pEdtOutl->IsModified();
2329 }
2330 
2331 // --------------------------------------------------------------------
2332 
2333 FASTBOOL SdrTableObj::IsFontwork() const
2334 {
2335     return sal_False;
2336 }
2337 
2338 // --------------------------------------------------------------------
2339 
2340 sal_uInt32 SdrTableObj::GetHdlCount() const
2341 {
2342     sal_uInt32 nCount = SdrTextObj::GetHdlCount();
2343     const sal_Int32 nRowCount = mpImpl->getRowCount();
2344     const sal_Int32 nColCount = mpImpl->getColumnCount();
2345 
2346     if( nRowCount && nColCount )
2347         nCount += nRowCount + nColCount + 2 + 1;
2348 
2349     return nCount;
2350 }
2351 
2352 // --------------------------------------------------------------------
2353 
2354 void SdrTableObj::AddToHdlList(SdrHdlList& rHdlList) const
2355 {
2356     const sal_Int32 nRowCount = mpImpl->getRowCount();
2357     const sal_Int32 nColCount = mpImpl->getColumnCount();
2358 
2359     // first add row handles
2360     std::vector< TableEdgeHdl* > aRowEdges( nRowCount + 1 );
2361 
2362     for( sal_Int32 nRow = 0; nRow <= nRowCount; nRow++ )
2363     {
2364         sal_Int32 nEdgeMin, nEdgeMax;
2365         const sal_Int32 nEdge = mpImpl->mpLayouter->getHorizontalEdge( nRow, &nEdgeMin, &nEdgeMax );
2366         nEdgeMin -= nEdge;
2367         nEdgeMax -= nEdge;
2368 
2369         Point aPoint( aRect.TopLeft() );
2370         aPoint.Y() += nEdge;
2371 
2372         TableEdgeHdl* pHdl= new TableEdgeHdl(aPoint,true,nEdgeMin,nEdgeMax,nColCount+1);
2373         pHdl->SetPointNum( nRow );
2374         rHdlList.AddHdl( pHdl );
2375         aRowEdges[nRow] = pHdl;
2376     }
2377 
2378     // second add column handles
2379     std::vector< TableEdgeHdl* > aColEdges( nColCount + 1 );
2380 
2381     for( sal_Int32 nCol = 0; nCol <= nColCount; nCol++ )
2382     {
2383         sal_Int32 nEdgeMin, nEdgeMax;
2384         const sal_Int32 nEdge = mpImpl->mpLayouter->getVerticalEdge( nCol, &nEdgeMin, &nEdgeMax );
2385         nEdgeMin -= nEdge;
2386         nEdgeMax -= nEdge;
2387 
2388         Point aPoint( aRect.TopLeft() );
2389         aPoint.X() += nEdge;
2390 
2391         TableEdgeHdl* pHdl = new TableEdgeHdl(aPoint,false,nEdgeMin,nEdgeMax, nRowCount+1);
2392         pHdl->SetPointNum( nCol );
2393         rHdlList.AddHdl( pHdl );
2394         aColEdges[nCol] = pHdl;
2395     }
2396 
2397     // now add visible edges to row and column handles
2398     if( mpImpl && mpImpl->mpLayouter )
2399     {
2400         TableLayouter& rLayouter = *mpImpl->mpLayouter;
2401 
2402         sal_Int32 nY = 0;
2403 
2404         for( sal_Int32 nRow = 0; nRow <= nRowCount; ++nRow )
2405         {
2406             const sal_Int32 nRowHeight = (nRow == nRowCount) ? 0 : rLayouter.getRowHeight(nRow);
2407             sal_Int32 nX = 0;
2408 
2409             for( sal_Int32 nCol = 0; nCol <= nColCount; ++nCol )
2410             {
2411                 const sal_Int32 nColWidth = (nCol == nColCount) ? 0 : rLayouter.getColumnWidth(nCol);
2412 
2413                 if( nRowHeight > 0 )
2414                 {
2415                     if( rLayouter.isEdgeVisible( nCol, nRow, false ) )
2416                         aColEdges[nCol]->SetEdge( nRow, nY, nY + nRowHeight, (rLayouter.getBorderLine( nCol, nRow, false ) == 0) ? Visible : Invisible);
2417                 }
2418 
2419                 if( nColWidth > 0 )
2420                 {
2421                     if( rLayouter.isEdgeVisible( nCol, nRow, true ) )
2422                         aRowEdges[nRow]->SetEdge( nCol, nX, nX + nColWidth, (rLayouter.getBorderLine( nCol, nRow, true ) == 0) ? Visible : Invisible);
2423                 }
2424 
2425                 nX += nColWidth;
2426             }
2427 
2428             nY += nRowHeight;
2429         }
2430     }
2431 
2432     // add remaining handles
2433     SdrHdl* pH=0;
2434     rHdlList.AddHdl( pH = new TableBorderHdl( aRect ) ); pH->SetMoveOutside( true );
2435     rHdlList.AddHdl( pH = new SdrHdl(aRect.TopLeft(),HDL_UPLFT) ); pH->SetMoveOutside( true );
2436     rHdlList.AddHdl( pH = new SdrHdl(aRect.TopCenter(),HDL_UPPER) ); pH->SetMoveOutside( true );
2437     rHdlList.AddHdl( pH = new SdrHdl(aRect.TopRight(),HDL_UPRGT) ); pH->SetMoveOutside( true );
2438     rHdlList.AddHdl( pH = new SdrHdl(aRect.LeftCenter(),HDL_LEFT) ); pH->SetMoveOutside( true );
2439     rHdlList.AddHdl( pH = new SdrHdl(aRect.RightCenter(),HDL_RIGHT) ); pH->SetMoveOutside( true );
2440     rHdlList.AddHdl( pH = new SdrHdl(aRect.BottomLeft(),HDL_LWLFT) ); pH->SetMoveOutside( true );
2441     rHdlList.AddHdl( pH = new SdrHdl(aRect.BottomCenter(),HDL_LOWER) ); pH->SetMoveOutside( true );
2442     rHdlList.AddHdl( pH = new SdrHdl(aRect.BottomRight(),HDL_LWRGT) ); pH->SetMoveOutside( true );
2443 
2444     sal_uIntPtr nHdlCount = rHdlList.GetHdlCount();
2445     for( sal_uIntPtr nHdl = 0; nHdl < nHdlCount; nHdl++ )
2446         rHdlList.GetHdl(nHdl)->SetObj((SdrObject*)this);
2447 }
2448 
2449 // --------------------------------------------------------------------
2450 
2451 SdrHdl* SdrTableObj::GetHdl(sal_uInt32 nHdlNum) const
2452 {
2453     // #i73248#
2454     // Warn the user that this is ineffective and show alternatives. Should not be used at all.
2455     OSL_ENSURE(false, "SdrTableObj::GetHdl(): ineffective, use AddToHdlList instead (!)");
2456 
2457     // to have an alternative, get single handle using the ineffective way
2458     SdrHdl* pRetval = 0;
2459     SdrHdlList aLocalList(0);
2460     AddToHdlList(aLocalList);
2461     const sal_uInt32 nHdlCount(aLocalList.GetHdlCount());
2462 
2463     if(nHdlCount && nHdlNum < nHdlCount)
2464     {
2465         // remove and remember. The other created handles will be deleted again with the
2466         // destruction of the local list
2467         pRetval = aLocalList.RemoveHdl(nHdlNum);
2468     }
2469 
2470     return pRetval;
2471 }
2472 
2473 ////////////////////////////////////////////////////////////////////////////////////////////////////
2474 // Draging
2475 
2476 bool SdrTableObj::hasSpecialDrag() const
2477 {
2478     return true;
2479 }
2480 
2481 bool SdrTableObj::beginSpecialDrag(SdrDragStat& rDrag) const
2482 {
2483     const SdrHdl* pHdl = rDrag.GetHdl();
2484     const SdrHdlKind eHdl((pHdl == NULL) ? HDL_MOVE : pHdl->GetKind());
2485 
2486     switch( eHdl )
2487     {
2488         case HDL_UPLFT:
2489         case HDL_UPPER:
2490         case HDL_UPRGT:
2491         case HDL_LEFT:
2492         case HDL_RIGHT:
2493         case HDL_LWLFT:
2494         case HDL_LOWER:
2495         case HDL_LWRGT:
2496         case HDL_MOVE:
2497         {
2498             break;
2499         }
2500 
2501         case HDL_USER:
2502         {
2503             rDrag.SetEndDragChangesAttributes(false);
2504             rDrag.SetNoSnap(true);
2505             break;
2506         }
2507 
2508         default:
2509         {
2510             return false;
2511         }
2512     }
2513 
2514     return true;
2515 }
2516 
2517 bool SdrTableObj::applySpecialDrag(SdrDragStat& rDrag)
2518 {
2519     bool bRet(true);
2520     const SdrHdl* pHdl = rDrag.GetHdl();
2521     const SdrHdlKind eHdl((pHdl == NULL) ? HDL_MOVE : pHdl->GetKind());
2522 
2523     switch( eHdl )
2524     {
2525         case HDL_UPLFT:
2526         case HDL_UPPER:
2527         case HDL_UPRGT:
2528         case HDL_LEFT:
2529         case HDL_RIGHT:
2530         case HDL_LWLFT:
2531         case HDL_LOWER:
2532         case HDL_LWRGT:
2533         {
2534             const Rectangle aNewRectangle(ImpDragCalcRect(rDrag));
2535 
2536             if(aNewRectangle != aRect)
2537             {
2538                 NbcSetLogicRect(aNewRectangle);
2539             }
2540 
2541             break;
2542         }
2543 
2544         case HDL_MOVE:
2545         {
2546             NbcMove( Size( rDrag.GetDX(), rDrag.GetDY() ) );
2547             break;
2548         }
2549 
2550         case HDL_USER:
2551         {
2552             rDrag.SetEndDragChangesAttributes(false);
2553             rDrag.SetNoSnap(true);
2554             const TableEdgeHdl* pEdgeHdl = dynamic_cast< const TableEdgeHdl* >( pHdl );
2555 
2556             if( pEdgeHdl )
2557             {
2558                 if( GetModel() && IsInserted() )
2559                 {
2560                     rDrag.SetEndDragChangesAttributes(true);
2561                 }
2562 
2563                 mpImpl->DragEdge( pEdgeHdl->IsHorizontalEdge(), pEdgeHdl->GetPointNum(), pEdgeHdl->GetValidDragOffset( rDrag ) );
2564             }
2565             break;
2566         }
2567 
2568         default:
2569         {
2570             bRet = false;
2571         }
2572     }
2573 
2574     return bRet;
2575 }
2576 
2577 String SdrTableObj::getSpecialDragComment(const SdrDragStat& rDrag) const
2578 {
2579     return SdrTextObj::getSpecialDragComment( rDrag );
2580 }
2581 
2582 basegfx::B2DPolyPolygon SdrTableObj::getSpecialDragPoly(const SdrDragStat& rDrag) const
2583 {
2584     basegfx::B2DPolyPolygon aRetval;
2585     const SdrHdl* pHdl = rDrag.GetHdl();
2586 
2587     if( pHdl && (HDL_USER == pHdl->GetKind()) )
2588     {
2589         const TableEdgeHdl* pEdgeHdl = dynamic_cast< const TableEdgeHdl* >( pHdl );
2590 
2591         if( pEdgeHdl )
2592         {
2593             aRetval = pEdgeHdl->getSpecialDragPoly( rDrag );
2594         }
2595     }
2596 
2597     return aRetval;
2598 }
2599 
2600 ////////////////////////////////////////////////////////////////////////////////////////////////////
2601 // Create
2602 // --------------------------------------------------------------------
2603 
2604 FASTBOOL SdrTableObj::BegCreate(SdrDragStat& rStat)
2605 {
2606     rStat.SetOrtho4Possible();
2607     Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
2608     aRect1.Justify();
2609     rStat.SetActionRect(aRect1);
2610     aRect = aRect1;
2611     return sal_True;
2612 }
2613 
2614 // --------------------------------------------------------------------
2615 
2616 FASTBOOL SdrTableObj::MovCreate(SdrDragStat& rStat)
2617 {
2618     Rectangle aRect1;
2619     rStat.TakeCreateRect(aRect1);
2620     ImpJustifyRect(aRect1);
2621     rStat.SetActionRect(aRect1);
2622     aRect=aRect1; // fuer ObjName
2623     SetBoundRectDirty();
2624     bSnapRectDirty=sal_True;
2625     return sal_True;
2626 }
2627 
2628 // --------------------------------------------------------------------
2629 
2630 FASTBOOL SdrTableObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
2631 {
2632     rStat.TakeCreateRect(aRect);
2633     ImpJustifyRect(aRect);
2634     return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
2635 }
2636 
2637 void SdrTableObj::BrkCreate(SdrDragStat& /*rStat*/)
2638 {
2639 }
2640 
2641 // --------------------------------------------------------------------
2642 
2643 FASTBOOL SdrTableObj::BckCreate(SdrDragStat& /*rStat*/)
2644 {
2645     return sal_True;
2646 }
2647 
2648 // --------------------------------------------------------------------
2649 
2650 basegfx::B2DPolyPolygon SdrTableObj::TakeCreatePoly(const SdrDragStat& rDrag) const
2651 {
2652     Rectangle aRect1;
2653     rDrag.TakeCreateRect(aRect1);
2654     aRect1.Justify();
2655 
2656     basegfx::B2DPolyPolygon aRetval;
2657     const basegfx::B2DRange aRange(aRect1.Left(), aRect1.Top(), aRect1.Right(), aRect1.Bottom());
2658     aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
2659     return aRetval;
2660 }
2661 
2662 // --------------------------------------------------------------------
2663 
2664 Pointer SdrTableObj::GetCreatePointer() const
2665 {
2666     return Pointer(POINTER_CROSS);
2667 }
2668 
2669 // --------------------------------------------------------------------
2670 
2671 void SdrTableObj::createCell( CellRef& xNewCell )
2672 {
2673     xNewCell = Cell::create( *this, 0 );
2674 }
2675 
2676 // --------------------------------------------------------------------
2677 
2678 SdrObjGeoData *SdrTableObj::NewGeoData() const
2679 {
2680     return new TableObjectGeoData;
2681 }
2682 
2683 // --------------------------------------------------------------------
2684 
2685 void SdrTableObj::SaveGeoData(SdrObjGeoData& rGeo) const
2686 {
2687     DBG_ASSERT( dynamic_cast< TableObjectGeoData* >( &rGeo ), "svx::SdrTableObj::SaveGeoData(), illegal geo data!" );
2688     SdrTextObj::SaveGeoData (rGeo);
2689 
2690     ((TableObjectGeoData &) rGeo).maLogicRect = maLogicRect;
2691 }
2692 
2693 // --------------------------------------------------------------------
2694 
2695 void SdrTableObj::RestGeoData(const SdrObjGeoData& rGeo)
2696 {
2697     DBG_ASSERT( dynamic_cast< const TableObjectGeoData* >( &rGeo ), "svx::SdrTableObj::SaveGeoData(), illegal geo data!" );
2698 
2699     maLogicRect = ((TableObjectGeoData &) rGeo).maLogicRect;
2700 
2701     SdrTextObj::RestGeoData (rGeo);
2702 
2703     if( mpImpl )
2704         mpImpl->LayoutTable( aRect, false, false );
2705     ActionChanged();
2706 }
2707 
2708 // --------------------------------------------------------------------
2709 
2710 SdrTableObj* SdrTableObj::CloneRange( const CellPos& rStart, const CellPos& rEnd )
2711 {
2712     const sal_Int32 nColumns = rEnd.mnCol - rStart.mnCol + 1;
2713     const sal_Int32 nRows = rEnd.mnRow - rStart.mnRow + 1;
2714 
2715     SdrTableObj* pNewTableObj = new SdrTableObj( GetModel(), GetCurrentBoundRect(), nColumns, nRows);
2716     pNewTableObj->setTableStyleSettings( getTableStyleSettings() );
2717     pNewTableObj->setTableStyle( getTableStyle() );
2718 
2719     Reference< XTable > xTable( getTable() );
2720     Reference< XTable > xNewTable( pNewTableObj->getTable() );
2721 
2722     if( !xTable.is() || !xNewTable.is() )
2723     {
2724         delete pNewTableObj;
2725         return 0;
2726     }
2727 
2728     // copy cells
2729     for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
2730     {
2731         for( sal_Int32 nCol = 0; nCol < nColumns; ++nCol ) try
2732         {
2733             CellRef xTargetCell( dynamic_cast< Cell* >( xNewTable->getCellByPosition( nCol, nRow ).get() ) );
2734             if( xTargetCell.is() )
2735                 xTargetCell->cloneFrom( dynamic_cast< Cell* >( xTable->getCellByPosition( rStart.mnCol + nCol, rStart.mnRow + nRow ).get() ) );
2736         }
2737         catch( Exception& )
2738         {
2739             DBG_ERROR( "svx::SvxTableController::GetMarkedObjModel(), exception caught!" );
2740         }
2741     }
2742 
2743     // copy row heights
2744     Reference< XTableRows > xNewRows( xNewTable->getRows(), UNO_QUERY_THROW );
2745     const OUString sHeight( RTL_CONSTASCII_USTRINGPARAM( "Height" ) );
2746     for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
2747     {
2748         Reference< XPropertySet > xNewSet( xNewRows->getByIndex( nRow ), UNO_QUERY_THROW );
2749         xNewSet->setPropertyValue( sHeight, Any( mpImpl->mpLayouter->getRowHeight( rStart.mnRow + nRow ) ) );
2750     }
2751 
2752     // copy column widths
2753     Reference< XTableColumns > xNewColumns( xNewTable->getColumns(), UNO_QUERY_THROW );
2754     const OUString sWidth( RTL_CONSTASCII_USTRINGPARAM( "Width" ) );
2755     for( sal_Int32 nCol = 0; nCol < nColumns; ++nCol )
2756     {
2757         Reference< XPropertySet > xNewSet( xNewColumns->getByIndex( nCol ), UNO_QUERY_THROW );
2758         xNewSet->setPropertyValue( sWidth, Any( mpImpl->mpLayouter->getColumnWidth( rStart.mnCol + nCol ) ) );
2759     }
2760 
2761     pNewTableObj->NbcReformatText();
2762     pNewTableObj->SetLogicRect( pNewTableObj->GetCurrentBoundRect() );
2763 
2764     return pNewTableObj;
2765 }
2766 
2767 // --------------------------------------------------------------------
2768 
2769 void SdrTableObj::DistributeColumns( sal_Int32 nFirstColumn, sal_Int32 nLastColumn )
2770 {
2771     if( mpImpl && mpImpl->mpLayouter )
2772     {
2773         TableModelNotifyGuard aGuard( mpImpl->mxTable.get() );
2774         mpImpl->mpLayouter->DistributeColumns( aRect, nFirstColumn, nLastColumn );
2775     }
2776 }
2777 
2778 // --------------------------------------------------------------------
2779 
2780 void SdrTableObj::DistributeRows( sal_Int32 nFirstRow, sal_Int32 nLastRow )
2781 {
2782     if( mpImpl && mpImpl->mpLayouter )
2783     {
2784         TableModelNotifyGuard aGuard( mpImpl->mxTable.get() );
2785         mpImpl->mpLayouter->DistributeRows( aRect, nFirstRow, nLastRow );
2786     }
2787 }
2788 
2789 // --------------------------------------------------------------------
2790 
2791 void SdrTableObj::SetChanged()
2792 {
2793     if( mpImpl )
2794     {
2795         if( mpImpl->UpdateWritingMode() )
2796             mpImpl->LayoutTable( aRect, false, false );
2797     }
2798 
2799     ::SdrTextObj::SetChanged();
2800 }
2801 
2802 // --------------------------------------------------------------------
2803 
2804 void SdrTableObj::uno_lock()
2805 {
2806     if( mpImpl && mpImpl->mxTable.is() )
2807         mpImpl->mxTable->lockBroadcasts();
2808 }
2809 
2810 // --------------------------------------------------------------------
2811 
2812 void SdrTableObj::uno_unlock()
2813 {
2814     if( mpImpl && mpImpl->mxTable.is() )
2815         mpImpl->mxTable->unlockBroadcasts();
2816 }
2817 
2818 // --------------------------------------------------------------------
2819 
2820 
2821 
2822 } }
2823