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