update dev300-m58
[ooovba.git] / svx / source / table / svdotable.cxx
blobd639b3e884ebe085cf2daf09a8e4f93d062b4a1a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svdotable.cxx,v $
10 * $Revision: 1.4.18.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #define ITEMID_BOX SDRATTR_TABLE_BORDER
35 #define ITEMID_BOXINFO SDRATTR_TABLE_BORDER_INNER
37 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
38 #include <com/sun/star/container/XNamed.hpp>
39 #include <com/sun/star/container/XNameAccess.hpp>
40 #include <com/sun/star/container/XIndexAccess.hpp>
42 #include <vcl/canvastools.hxx>
43 #include <com/sun/star/style/XStyle.hpp>
44 #include <com/sun/star/beans/XPropertySet.hpp>
45 #include <basegfx/polygon/b2dpolygontools.hxx>
46 #include <basegfx/polygon/b2dpolypolygon.hxx>
47 #include <basegfx/polygon/b2dpolygon.hxx>
48 #include <svtools/style.hxx>
49 #include "editstat.hxx"
50 #include "svx/outlobj.hxx"
51 #include "svx/svdview.hxx"
52 #include "svx/sdr/properties/textproperties.hxx"
53 #include "svx/svdotable.hxx"
54 #include "svx/svdhdl.hxx"
55 #include "viewcontactoftableobj.hxx"
56 #include "svx/svdoutl.hxx"
57 #include "svx/svddrag.hxx"
58 #include "svx/svdpagv.hxx"
59 #include "tablemodel.hxx"
60 #include "cell.hxx"
61 #include "svx/xflclit.hxx"
62 #include "tablelayouter.hxx"
63 #include "svx/svdetc.hxx"
64 #include "tablehandles.hxx"
65 #include "svx/boxitem.hxx"
66 #include "svx/framelink.hxx"
67 #include "svx/sdr/table/tabledesign.hxx"
68 #include "svx/svdundo.hxx"
69 #include "svdstr.hrc"
70 #include "svdglob.hxx"
71 #include "svx/writingmodeitem.hxx"
72 #include "svx/frmdiritem.hxx"
73 #include "svx/xflhtit.hxx"
74 #include "svx/xflftrit.hxx"
75 #include "svx/xfltrit.hxx"
77 // -----------------------------------------------------------------------------
79 using ::rtl::OUString;
80 using ::com::sun::star::uno::Any;
81 using ::com::sun::star::uno::Reference;
82 using ::com::sun::star::uno::XInterface;
83 using ::com::sun::star::uno::UNO_QUERY;
84 using ::com::sun::star::uno::UNO_QUERY_THROW;
85 using ::com::sun::star::uno::Exception;
86 using ::com::sun::star::container::XIndexAccess;
87 using ::com::sun::star::style::XStyle;
88 using ::com::sun::star::table::XTableRows;
89 using ::com::sun::star::table::XTableColumns;
90 using ::com::sun::star::table::XTable;
91 using ::com::sun::star::beans::XPropertySet;
92 using ::com::sun::star::util::XModifyBroadcaster;
93 using sdr::properties::TextProperties;
94 using sdr::properties::BaseProperties;
95 using namespace ::com::sun::star::text;
96 using namespace ::com::sun::star::container;
97 using namespace ::com::sun::star::style;
99 namespace sdr { namespace table {
101 class TableProperties : public TextProperties
103 protected:
104 // create a new itemset
105 SfxItemSet& CreateObjectSpecificItemSet(SfxItemPool& rPool);
107 public:
108 // basic constructor
109 TableProperties(SdrObject& rObj );
111 // constructor for copying, but using new object
112 TableProperties(const TableProperties& rProps, SdrObject& rObj );
114 // destructor
115 ~TableProperties();
117 // Clone() operator, normally just calls the local copy constructor
118 BaseProperties& Clone(SdrObject& rObj) const;
120 virtual void ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem);
123 TableProperties::TableProperties(SdrObject& rObj)
124 : TextProperties(rObj)
128 TableProperties::TableProperties(const TableProperties& rProps, SdrObject& rObj)
129 : TextProperties(rProps, rObj)
133 TableProperties::~TableProperties()
137 BaseProperties& TableProperties::Clone(SdrObject& rObj) const
139 return *(new TableProperties(*this, rObj));
142 void TableProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem)
144 if( nWhich == SDRATTR_TEXTDIRECTION )
145 AttributeProperties::ItemChange( nWhich, pNewItem );
146 else
147 TextProperties::ItemChange( nWhich, pNewItem );
150 // create a new itemset
151 SfxItemSet& TableProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool)
153 return *(new SfxItemSet(rPool,
155 // range from SdrAttrObj
156 SDRATTR_START, SDRATTR_SHADOW_LAST,
157 SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST,
158 SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION,
160 // range for SdrTableObj
161 SDRATTR_TABLE_FIRST, SDRATTR_TABLE_LAST,
163 // range from SdrTextObj
164 EE_ITEMS_START, EE_ITEMS_END,
166 // end
167 0, 0));
170 class TableObjectGeoData : public SdrTextObjGeoData
172 public:
173 Rectangle maLogicRect;
176 //------------------------------------------------------------------------
177 // TableStyleSettings
178 //------------------------------------------------------------------------
180 TableStyleSettings::TableStyleSettings()
181 : mbUseFirstRow(true)
182 , mbUseLastRow(false)
183 , mbUseFirstColumn(false)
184 , mbUseLastColumn(false)
185 , mbUseRowBanding(true)
186 , mbUseColumnBanding(false)
190 TableStyleSettings::TableStyleSettings( const TableStyleSettings& rStyle )
192 (*this) = rStyle;
195 TableStyleSettings& TableStyleSettings::operator=(const TableStyleSettings& rStyle)
197 mbUseFirstRow = rStyle.mbUseFirstRow;
198 mbUseLastRow = rStyle.mbUseLastRow;
199 mbUseFirstColumn = rStyle.mbUseFirstColumn;
200 mbUseLastColumn = rStyle.mbUseLastColumn;
201 mbUseRowBanding = rStyle.mbUseRowBanding;
202 mbUseColumnBanding = rStyle.mbUseColumnBanding;
203 return *this;
206 bool TableStyleSettings::operator==( const TableStyleSettings& rStyle ) const
208 return
209 (mbUseFirstRow == rStyle.mbUseFirstRow) &&
210 (mbUseLastRow == rStyle.mbUseLastRow) &&
211 (mbUseFirstColumn == rStyle.mbUseFirstColumn) &&
212 (mbUseLastColumn == rStyle.mbUseLastColumn) &&
213 (mbUseRowBanding == rStyle.mbUseRowBanding) &&
214 (mbUseColumnBanding == rStyle.mbUseColumnBanding);
217 // -----------------------------------------------------------------------------
219 class SdrTableObjImpl : public TableDesignUser, public ::cppu::WeakImplHelper1< ::com::sun::star::util::XModifyListener >
221 public:
222 CellRef mxActiveCell;
223 TableModelRef mxTable;
224 SdrTableObj* mpTableObj;
225 TableLayouter* mpLayouter;
226 CellPos maEditPos;
227 TableStyleSettings maTableStyle;
228 Reference< XIndexAccess > mxTableStyle;
229 bool mbModifyPending;
230 // sal_Int32 mnSavedEditRowHeight;
232 void SetModel(SdrModel* pOldModel, SdrModel* pNewModel);
234 CellRef getCell( const CellPos& rPos ) const;
235 void LayoutTable( Rectangle& rArea, bool bFitWidth, bool bFitHeight );
237 bool ApplyCellStyles();
238 void UpdateCells( Rectangle& rArea );
240 SdrTableObjImpl();
241 virtual ~SdrTableObjImpl();
243 void init( SdrTableObj* pTable, sal_Int32 nColumns, sal_Int32 nRows );
244 void dispose();
246 sal_Int32 getColumnCount() const;
247 sal_Int32 getRowCount() const;
249 void DragEdge( bool mbHorizontal, int nEdge, sal_Int32 nOffset );
251 const SfxPoolItem* GetCellItem( const CellPos& rPos, sal_uInt16 nWhich ) const;
252 // void GetBorderLines( const CellPos& rPos, const SvxBorderLine** ppLeft, const SvxBorderLine** ppTop, const SvxBorderLine** ppRight, const SvxBorderLine** ppBottom ) const;
254 void operator=( const SdrTableObjImpl& rSource );
256 // XModifyListener
257 virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
259 // XEventListener
260 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
262 void update();
264 void connectTableStyle();
265 void disconnectTableStyle();
266 virtual bool isInUse();
268 bool UpdateWritingMode();
271 // -----------------------------------------------------------------------------
273 SdrTableObjImpl::SdrTableObjImpl()
274 : mpTableObj( 0 )
275 , mpLayouter( 0 )
279 // -----------------------------------------------------------------------------
281 SdrTableObjImpl::~SdrTableObjImpl()
285 // -----------------------------------------------------------------------------
287 void SdrTableObjImpl::init( SdrTableObj* pTable, sal_Int32 nColumns, sal_Int32 nRows )
289 mpTableObj = pTable;
290 mxTable = new TableModel( pTable );
291 mxTable->init( nColumns, nRows );
292 mpLayouter = new TableLayouter( mxTable );
293 Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
294 mxTable->addModifyListener( xListener );
295 UpdateWritingMode();
296 LayoutTable( mpTableObj->aRect, true, true );
297 mpTableObj->maLogicRect = mpTableObj->aRect;
300 // -----------------------------------------------------------------------------
302 void SdrTableObjImpl::operator=( const SdrTableObjImpl& rSource )
304 if( mpLayouter )
306 delete mpLayouter;
307 mpLayouter = 0;
310 if( mxTable.is() )
312 Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
313 mxTable->removeModifyListener( xListener );
314 mxTable->dispose();
315 mxTable.clear();
318 maTableStyle = rSource.maTableStyle;
320 mxTable = new TableModel( mpTableObj, rSource.mxTable );
321 mpLayouter = new TableLayouter( mxTable );
322 Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
323 mxTable->addModifyListener( xListener );
324 mxTableStyle = rSource.mxTableStyle;
325 UpdateWritingMode();
326 ApplyCellStyles();
327 mpTableObj->aRect = mpTableObj->maLogicRect;
328 LayoutTable( mpTableObj->aRect, false, false );
331 // -----------------------------------------------------------------------------
333 void SdrTableObjImpl::SetModel(SdrModel* /*pOldModel*/, SdrModel* pNewModel)
335 // try to find new table style
337 Reference< XIndexAccess > xNewTableStyle;
338 if( mxTableStyle.is() ) try
340 const OUString sStyleName( Reference< XNamed >( mxTableStyle, UNO_QUERY_THROW )->getName() );
342 Reference< XStyleFamiliesSupplier > xSFS( pNewModel->getUnoModel(), UNO_QUERY_THROW );
343 Reference< XNameAccess > xFamilyNameAccess( xSFS->getStyleFamilies(), UNO_QUERY_THROW );
344 const rtl::OUString sFamilyName( RTL_CONSTASCII_USTRINGPARAM( "table" ) );
345 Reference< XNameAccess > xTableFamilyAccess( xFamilyNameAccess->getByName( sFamilyName ), UNO_QUERY_THROW );
347 if( xTableFamilyAccess->hasByName( sStyleName ) )
349 // found table style with the same name
350 xTableFamilyAccess->getByName( sStyleName ) >>= xNewTableStyle;
352 else
354 // copy or?
355 Reference< XIndexAccess > xIndexAccess( xTableFamilyAccess, UNO_QUERY_THROW );
356 xIndexAccess->getByIndex( 0 ) >>= xNewTableStyle;
359 catch( Exception& )
361 DBG_ERROR("svx::SdrTableObjImpl::SetModel(), exception caught!");
364 mxTableStyle = xNewTableStyle;
366 update();
369 // -----------------------------------------------------------------------------
371 bool SdrTableObjImpl::ApplyCellStyles()
373 if( !mxTable.is() || !mxTable.is() || !mxTableStyle.is() )
374 return false;
376 bool bChanges = false;
378 const sal_Int32 nColCount = getColumnCount();
379 const sal_Int32 nRowCount = getRowCount();
381 const TableStyleSettings& rStyle = maTableStyle;
383 CellPos aPos;
384 for( aPos.mnRow = 0; aPos.mnRow < nRowCount; ++aPos.mnRow )
386 const bool bFirstRow = (aPos.mnRow == 0) && rStyle.mbUseFirstRow;
387 const bool bLastRow = (aPos.mnRow == nRowCount-1) && rStyle.mbUseLastRow;
389 for( aPos.mnCol = 0; aPos.mnCol < nColCount; ++aPos.mnCol )
391 Reference< XStyle > xStyle;
393 // first and last row win first, if used and available
394 if( bFirstRow )
396 mxTableStyle->getByIndex(first_row_style) >>= xStyle;
398 else if( bLastRow )
400 mxTableStyle->getByIndex(last_row_style) >>= xStyle;
403 if( !xStyle.is() )
405 // next come first and last column, if used and available
406 if( rStyle.mbUseFirstColumn && (aPos.mnCol == 0) )
408 mxTableStyle->getByIndex(first_column_style) >>= xStyle;
410 else if( rStyle.mbUseLastColumn && (aPos.mnCol == nColCount-1) )
412 mxTableStyle->getByIndex(last_column_style) >>= xStyle;
416 if( !xStyle.is() && rStyle.mbUseRowBanding )
418 if( (aPos.mnRow & 1) == 0 )
420 mxTableStyle->getByIndex(even_rows_style) >>= xStyle;
422 else
424 mxTableStyle->getByIndex(odd_rows_style) >>= xStyle;
428 if( !xStyle.is() && rStyle.mbUseColumnBanding )
430 if( (aPos.mnCol & 1) == 0 )
432 mxTableStyle->getByIndex(even_columns_style) >>= xStyle;
434 else
436 mxTableStyle->getByIndex(odd_columns_style) >>= xStyle;
440 if( !xStyle.is() )
442 // use default cell style if non found yet
443 mxTableStyle->getByIndex(body_style) >>= xStyle;
447 if( xStyle.is() )
449 SfxUnoStyleSheet* pStyle = SfxUnoStyleSheet::getUnoStyleSheet(xStyle);
451 if( pStyle )
453 CellRef xCell( getCell( aPos ) );
454 if( xCell.is() && ( xCell->GetStyleSheet() != pStyle ) )
456 bChanges = true;
457 xCell->SetStyleSheet( pStyle, sal_True );
464 return bChanges;
467 // -----------------------------------------------------------------------------
469 void SdrTableObjImpl::dispose()
471 if( mxTable.is() )
472 mxTable->dispose();
475 // -----------------------------------------------------------------------------
477 void SdrTableObjImpl::DragEdge( bool mbHorizontal, int nEdge, sal_Int32 nOffset )
479 if( (nEdge > 0) && mxTable.is()) try
481 const OUString sSize( RTL_CONSTASCII_USTRINGPARAM( "Size" ) );
482 nEdge--;
483 if( mbHorizontal )
485 if( (nEdge >= 0) && (nEdge < getRowCount()) )
487 sal_Int32 nHeigth = mpLayouter->getRowHeight( nEdge );
488 nHeigth += nOffset;
489 Reference< XIndexAccess > xRows( mxTable->getRows(), UNO_QUERY_THROW );
490 Reference< XPropertySet > xRowSet( xRows->getByIndex( nEdge ), UNO_QUERY_THROW );
491 xRowSet->setPropertyValue( sSize, Any( nHeigth ) );
494 else
496 if( (nEdge >= 0) && (nEdge < getColumnCount()) )
498 sal_Int32 nWidth = mpLayouter->getColumnWidth( nEdge );
499 nWidth += nOffset;
501 Reference< XIndexAccess > xCols( mxTable->getColumns(), UNO_QUERY_THROW );
502 Reference< XPropertySet > xColSet( xCols->getByIndex( nEdge ), UNO_QUERY_THROW );
503 xColSet->setPropertyValue( sSize, Any( nWidth ) );
505 if( nEdge > 0 && nEdge < mxTable->getColumnCount() )
507 const bool bRTL = mpLayouter->GetWritingMode() == WritingMode_RL_TB;
509 if( bRTL )
510 nEdge--;
511 else
512 nEdge++;
514 if( (bRTL && (nEdge >= 0)) || (!bRTL && (nEdge < mxTable->getColumnCount())) )
516 nWidth = mpLayouter->getColumnWidth( nEdge );
517 nWidth = std::max( (sal_Int32)(nWidth - nOffset), (sal_Int32)0 );
519 xColSet = Reference< XPropertySet >( xCols->getByIndex( nEdge ), UNO_QUERY_THROW );
520 xColSet->setPropertyValue( sSize, Any( nWidth ) );
526 catch( Exception& )
528 DBG_ERROR( "svx::SdrTableObjImpl::DragEdge(), exception caught!" );
532 // -----------------------------------------------------------------------------
533 // XModifyListener
534 // -----------------------------------------------------------------------------
536 void SAL_CALL SdrTableObjImpl::modified( const ::com::sun::star::lang::EventObject& /*aEvent*/ ) throw (::com::sun::star::uno::RuntimeException)
538 update();
541 void SdrTableObjImpl::update()
543 // source can be the table model itself or the assigned table template
544 TableModelNotifyGuard aGuard( mxTable.get() );
545 if( mpTableObj )
547 if( (maEditPos.mnRow >= getRowCount()) || (maEditPos.mnCol >= getColumnCount()) || (getCell( maEditPos ) != mxActiveCell) )
549 if(maEditPos.mnRow >= getRowCount())
550 maEditPos.mnRow = getRowCount()-1;
552 if(maEditPos.mnCol >= getColumnCount())
553 maEditPos.mnCol = getColumnCount()-1;
555 mpTableObj->setActiveCell( maEditPos );
558 ApplyCellStyles();
560 mpTableObj->aRect = mpTableObj->maLogicRect;
561 LayoutTable( mpTableObj->aRect, false, false );
563 mpTableObj->SetRectsDirty();
564 mpTableObj->ActionChanged();
565 mpTableObj->BroadcastObjectChange();
569 // -----------------------------------------------------------------------------
571 void SdrTableObjImpl::connectTableStyle()
573 if( mxTableStyle.is() )
575 Reference< XModifyBroadcaster > xBroadcaster( mxTableStyle, UNO_QUERY );
576 if( xBroadcaster.is() )
578 Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
579 xBroadcaster->addModifyListener( xListener );
584 // -----------------------------------------------------------------------------
586 void SdrTableObjImpl::disconnectTableStyle()
588 if( mxTableStyle.is() )
590 Reference< XModifyBroadcaster > xBroadcaster( mxTableStyle, UNO_QUERY );
591 if( xBroadcaster.is() )
593 Reference< XModifyListener > xListener( static_cast< ::com::sun::star::util::XModifyListener* >(this) );
594 xBroadcaster->removeModifyListener( xListener );
599 // -----------------------------------------------------------------------------
601 bool SdrTableObjImpl::isInUse()
603 return mpTableObj && mpTableObj->IsInserted();
606 // -----------------------------------------------------------------------------
607 // XEventListener
608 // -----------------------------------------------------------------------------
610 void SAL_CALL SdrTableObjImpl::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException)
612 mxActiveCell.clear();
613 mxTable.clear();
614 if( mpLayouter )
616 delete mpLayouter;
617 mpLayouter = 0;
619 mpTableObj = 0;
622 // -----------------------------------------------------------------------------
624 CellRef SdrTableObjImpl::getCell( const CellPos& rPos ) const
626 CellRef xCell;
627 if( mxTable.is() ) try
629 xCell.set( dynamic_cast< Cell* >( mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ).get() ) );
631 catch( Exception& )
633 DBG_ERROR( "svx::SdrTableObjImpl::getCell(), exception caught!" );
635 return xCell;
638 // -----------------------------------------------------------------------------
640 sal_Int32 SdrTableObjImpl::getColumnCount() const
642 return mxTable.is() ? mxTable->getColumnCount() : 0;
645 // -----------------------------------------------------------------------------
647 sal_Int32 SdrTableObjImpl::getRowCount() const
649 return mxTable.is() ? mxTable->getRowCount() : 0;
652 // -----------------------------------------------------------------------------
654 void SdrTableObjImpl::LayoutTable( Rectangle& rArea, bool bFitWidth, bool bFitHeight )
656 if( mpLayouter && mpTableObj->GetModel() )
658 TableModelNotifyGuard aGuard( mxTable.get() );
659 mpLayouter->LayoutTable( rArea, bFitWidth, bFitHeight );
663 // -----------------------------------------------------------------------------
665 bool SdrTableObjImpl::UpdateWritingMode()
667 if( mpTableObj && mpLayouter )
669 WritingMode eWritingMode = (WritingMode)static_cast< const SvxWritingModeItem& >( mpTableObj->GetObjectItem( SDRATTR_TEXTDIRECTION ) ).GetValue();
671 if( eWritingMode != WritingMode_TB_RL )
673 if( static_cast< const SvxFrameDirectionItem& >( mpTableObj->GetObjectItem( EE_PARA_WRITINGDIR ) ).GetValue() == FRMDIR_HORI_LEFT_TOP )
674 eWritingMode = WritingMode_LR_TB;
675 else
676 eWritingMode = WritingMode_RL_TB;
679 if( eWritingMode != mpLayouter->GetWritingMode() )
681 mpLayouter->SetWritingMode( eWritingMode );
682 return true;
685 return false;
688 // -----------------------------------------------------------------------------
690 void SdrTableObjImpl::UpdateCells( Rectangle& rArea )
692 if( mpLayouter && mxTable.is() )
694 TableModelNotifyGuard aGuard( mxTable.get() );
695 mpLayouter->updateCells( rArea );
696 mxTable->setModified(sal_True);
700 // -----------------------------------------------------------------------------
702 const SfxPoolItem* SdrTableObjImpl::GetCellItem( const CellPos& rPos, sal_uInt16 nWhich ) const
704 CellRef xCell( getCell( rPos ) );
705 if( xCell.is() )
706 return xCell->GetItemSet().GetItem( nWhich );
707 else
708 return 0;
711 // -----------------------------------------------------------------------------
712 // BaseProperties section
713 // -----------------------------------------------------------------------------
715 sdr::properties::BaseProperties* SdrTableObj::CreateObjectSpecificProperties()
717 return new TableProperties(*this);
720 // -----------------------------------------------------------------------------
721 // DrawContact section
722 // -----------------------------------------------------------------------------
724 sdr::contact::ViewContact* SdrTableObj::CreateObjectSpecificViewContact()
726 return new sdr::contact::ViewContactOfTableObj(*this);
729 // --------------------------------------------------------------------
731 TYPEINIT1(SdrTableObj,SdrTextObj);
733 // --------------------------------------------------------------------
735 SdrTableObj::SdrTableObj(SdrModel* _pModel)
737 pModel = _pModel;
738 init( 1, 1 );
741 // --------------------------------------------------------------------
743 SdrTableObj::SdrTableObj(SdrModel* _pModel, const ::Rectangle& rNewRect, sal_Int32 nColumns, sal_Int32 nRows)
744 : SdrTextObj( rNewRect )
745 , maLogicRect( rNewRect )
747 pModel = _pModel;
749 if( nColumns <= 0 )
750 nColumns = 1;
752 if( nRows <= 0 )
753 nRows = 1;
755 init( nColumns, nRows );
758 // --------------------------------------------------------------------
760 void SdrTableObj::init( sal_Int32 nColumns, sal_Int32 nRows )
762 bClosedObj = TRUE;
764 mpImpl = new SdrTableObjImpl;
765 mpImpl->acquire();
766 mpImpl->init( this, nColumns, nRows );
769 // --------------------------------------------------------------------
771 SdrTableObj::~SdrTableObj()
773 mpImpl->dispose();
774 mpImpl->release();
777 // --------------------------------------------------------------------
778 // table stuff
779 // --------------------------------------------------------------------
781 Reference< XTable > SdrTableObj::getTable() const
783 return Reference< XTable >( mpImpl->mxTable.get() );
786 // --------------------------------------------------------------------
788 bool SdrTableObj::isValid( const CellPos& rPos ) const
790 return (rPos.mnCol >= 0) && (rPos.mnCol < mpImpl->getColumnCount()) && (rPos.mnRow >= 0) && (rPos.mnRow < mpImpl->getRowCount());
793 // --------------------------------------------------------------------
795 CellPos SdrTableObj::getFirstCell() const
797 return CellPos( 0,0 );
800 // --------------------------------------------------------------------
802 CellPos SdrTableObj::getLastCell() const
804 CellPos aPos;
805 if( mpImpl->mxTable.is() )
807 aPos.mnCol = mpImpl->getColumnCount()-1;
808 aPos.mnRow = mpImpl->getRowCount()-1;
810 return aPos;
813 // --------------------------------------------------------------------
815 CellPos SdrTableObj::getLeftCell( const CellPos& rPos, bool bEdgeTravel ) const
817 switch( GetWritingMode() )
819 default:
820 case WritingMode_LR_TB:
821 return getPreviousCell( rPos, bEdgeTravel );
822 case WritingMode_RL_TB:
823 return getNextCell( rPos, bEdgeTravel );
824 case WritingMode_TB_RL:
825 return getPreviousRow( rPos, bEdgeTravel );
829 // --------------------------------------------------------------------
831 CellPos SdrTableObj::getRightCell( const CellPos& rPos, bool bEdgeTravel ) const
833 switch( GetWritingMode() )
835 default:
836 case WritingMode_LR_TB:
837 return getNextCell( rPos, bEdgeTravel );
838 case WritingMode_RL_TB:
839 return getPreviousCell( rPos, bEdgeTravel );
840 case WritingMode_TB_RL:
841 return getNextRow( rPos, bEdgeTravel );
845 // --------------------------------------------------------------------
847 CellPos SdrTableObj::getUpCell( const CellPos& rPos, bool bEdgeTravel ) const
849 switch( GetWritingMode() )
851 default:
852 case WritingMode_LR_TB:
853 case WritingMode_RL_TB:
854 return getPreviousRow( rPos, bEdgeTravel );
855 case WritingMode_TB_RL:
856 return getPreviousCell( rPos, bEdgeTravel );
860 // --------------------------------------------------------------------
862 CellPos SdrTableObj::getDownCell( const CellPos& rPos, bool bEdgeTravel ) const
864 switch( GetWritingMode() )
866 default:
867 case WritingMode_LR_TB:
868 case WritingMode_RL_TB:
869 return getNextRow( rPos, bEdgeTravel );
870 case WritingMode_TB_RL:
871 return getNextCell( rPos, bEdgeTravel );
875 // --------------------------------------------------------------------
877 CellPos SdrTableObj::getPreviousCell( const CellPos& rPos, bool bEdgeTravel ) const
879 CellPos aPos( rPos );
880 if( mpImpl )
882 CellRef xCell( mpImpl->getCell( aPos ) );
883 if( xCell.is() && xCell->isMerged() )
885 sal_Int32 nTemp = 0;
886 findMergeOrigin( mpImpl->mxTable.get(), aPos.mnCol, aPos.mnRow, aPos.mnCol, nTemp );
889 if( aPos.mnCol > 0 )
891 --aPos.mnCol;
894 else if( bEdgeTravel && (aPos.mnRow > 0) )
896 aPos.mnCol = mpImpl->mxTable->getColumnCount()-1;
897 --aPos.mnRow;
900 return aPos;
903 // --------------------------------------------------------------------
905 CellPos SdrTableObj::getNextCell( const CellPos& rPos, bool bEdgeTravel ) const
907 CellPos aPos( rPos );
908 if( mpImpl )
910 CellRef xCell( mpImpl->getCell( aPos ) );
911 if( xCell.is() )
913 if( xCell->isMerged() )
915 findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, aPos.mnCol, aPos.mnRow );
917 xCell = mpImpl->getCell(aPos);
919 if( xCell.is() )
921 aPos.mnCol += xCell->getColumnSpan();
922 aPos.mnRow = rPos.mnRow;
925 else
927 aPos.mnCol += xCell->getColumnSpan();
930 if( aPos.mnCol < mpImpl->mxTable->getColumnCount() )
931 return aPos;
933 if( bEdgeTravel && ((aPos.mnRow + 1) < mpImpl->getRowCount()) )
935 aPos.mnCol = 0;
936 aPos.mnRow += 1;
937 return aPos;
942 // last cell reached, no traveling possible
943 return rPos;
946 // --------------------------------------------------------------------
948 CellPos SdrTableObj::getPreviousRow( const CellPos& rPos, bool bEdgeTravel ) const
950 CellPos aPos( rPos );
951 if( mpImpl )
953 CellRef xCell( mpImpl->getCell( aPos ) );
954 if( xCell.is() )
956 if( xCell->isMerged() )
958 sal_Int32 nTemp = 0;
959 findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, nTemp, aPos.mnRow );
963 if( aPos.mnRow > 0 )
965 --aPos.mnRow;
967 else if( bEdgeTravel && (aPos.mnCol > 0) )
969 aPos.mnRow = mpImpl->mxTable->getRowCount()-1;
970 --aPos.mnCol;
973 return aPos;
976 // --------------------------------------------------------------------
978 CellPos SdrTableObj::getNextRow( const CellPos& rPos, bool bEdgeTravel ) const
980 CellPos aPos( rPos );
982 if( mpImpl )
984 CellRef xCell( mpImpl->getCell( rPos ) );
985 if( xCell.is() )
987 if( xCell->isMerged() )
989 findMergeOrigin( mpImpl->mxTable, aPos.mnCol, aPos.mnRow, aPos.mnCol, aPos.mnRow );
990 xCell = mpImpl->getCell(aPos);
991 aPos.mnCol = rPos.mnCol;
994 if( xCell.is() )
995 aPos.mnRow += xCell->getRowSpan();
997 if( aPos.mnRow < mpImpl->mxTable->getRowCount() )
998 return aPos;
1000 if( bEdgeTravel && (aPos.mnCol + 1) < mpImpl->mxTable->getColumnCount() )
1002 aPos.mnRow = 0;
1003 aPos.mnCol += 1;
1005 while( aPos.mnCol < mpImpl->mxTable->getColumnCount() )
1007 xCell = mpImpl->getCell( aPos );
1008 if( xCell.is() && !xCell->isMerged() )
1009 return aPos;
1010 aPos.mnCol += 1;
1016 // last position reached, no more traveling possible
1017 return rPos;
1020 // --------------------------------------------------------------------
1022 const TableStyleSettings& SdrTableObj::getTableStyleSettings() const
1024 if( mpImpl )
1026 return mpImpl->maTableStyle;
1028 else
1030 static TableStyleSettings aTmp;
1031 return aTmp;
1035 // --------------------------------------------------------------------
1037 void SdrTableObj::setTableStyleSettings( const TableStyleSettings& rStyle )
1039 if( mpImpl )
1041 mpImpl->maTableStyle = rStyle;
1042 mpImpl->update();
1046 // --------------------------------------------------------------------
1048 TableHitKind SdrTableObj::CheckTableHit( const Point& rPos, sal_Int32& rnX, sal_Int32& rnY, int nTol ) const
1050 if( !mpImpl || !mpImpl->mxTable.is() )
1051 return SDRTABLEHIT_NONE;
1053 rnX = 0;
1054 rnY = 0;
1056 const sal_Int32 nColCount = mpImpl->getColumnCount();
1057 const sal_Int32 nRowCount = mpImpl->getRowCount();
1059 sal_Int32 nX = rPos.X() + nTol - aRect.nLeft;
1060 sal_Int32 nY = rPos.Y() + nTol - aRect.nTop;
1062 if( (nX < 0) || (nX > (aRect.GetWidth() + nTol)) || (nY < 0) || (nY > (aRect.GetHeight() + nTol) ) )
1063 return SDRTABLEHIT_NONE;
1065 // get vertical edge number and check for a hit
1066 const bool bRTL = GetWritingMode() == WritingMode_RL_TB;
1067 bool bVrtHit = false;
1068 if( nX >= 0 )
1070 if( !bRTL )
1072 while( rnX <= nColCount )
1074 if( nX <= (2*nTol) )
1076 bVrtHit = true;
1077 break;
1080 if( rnX == nColCount )
1081 break;
1083 nX -= mpImpl->mpLayouter->getColumnWidth( rnX );
1084 if( nX < 0 )
1085 break;
1086 rnX++;
1089 else
1091 rnX = nColCount;
1092 while( rnX >= 0 )
1094 if( nX <= (2*nTol) )
1096 bVrtHit = true;
1097 break;
1100 if( rnX == 0 )
1101 break;
1103 rnX--;
1104 nX -= mpImpl->mpLayouter->getColumnWidth( rnX );
1105 if( nX < 0 )
1106 break;
1111 // rnX is now the edge number left to the pointer, if it was hit bHrzHit is also true
1113 // get vertical edge number and check for a hit
1114 bool bHrzHit = false;
1115 if( nY >= 0 )
1117 while( rnY <= nRowCount )
1119 if( nY <= (2*nTol) )
1121 bHrzHit = true;
1122 break;
1125 if( rnY == nRowCount )
1126 break;
1128 nY -= mpImpl->mpLayouter->getRowHeight(rnY);
1129 if( nY < 0 )
1130 break;
1131 rnY++;
1135 // rnY is now the edge number above the pointer, if it was hit bVrtHit is also true
1137 if( bVrtHit && mpImpl->mpLayouter->isEdgeVisible( rnX, rnY, false ) )
1138 return SDRTABLEHIT_VERTICAL_BORDER;
1140 if( bHrzHit && mpImpl->mpLayouter->isEdgeVisible( rnX, rnY, true ) )
1141 return SDRTABLEHIT_HORIZONTAL_BORDER;
1143 CellRef xCell( mpImpl->getCell( CellPos( rnX, rnY ) ) );
1144 if( xCell.is() && xCell->isMerged() )
1145 findMergeOrigin( mpImpl->mxTable.get(), rnX, rnY, rnX, rnY );
1147 if( xCell.is() )
1149 nX += mpImpl->mpLayouter->getColumnWidth( rnX );
1150 if( nX < xCell->GetTextLeftDistance() )
1151 return SDRTABLEHIT_CELL;
1154 return SDRTABLEHIT_CELLTEXTAREA;
1157 const SfxItemSet& SdrTableObj::GetActiveCellItemSet() const
1159 return getActiveCell()->GetItemSet();
1162 // --------------------------------------------------------------------
1164 void SdrTableObj::InsertRows( sal_Int32 nIndex, sal_Int32 nCount /*= 1*/ )
1166 if( mpImpl->mxTable.is() ) try
1168 Reference< XTableRows > xRows( mpImpl->mxTable->getRows(), UNO_QUERY_THROW );
1169 xRows->insertByIndex( nIndex, nCount );
1171 catch( Exception& )
1173 DBG_ERROR("SdrTableObj::InsertRows(), exception caught!");
1177 // --------------------------------------------------------------------
1179 void SdrTableObj::InsertColumns( sal_Int32 nIndex, sal_Int32 nCount /*= 1*/ )
1181 if( mpImpl->mxTable.is() ) try
1183 Reference< XTableColumns > xColumns( mpImpl->mxTable->getColumns(), UNO_QUERY_THROW );
1184 xColumns->insertByIndex( nIndex, nCount );
1186 catch( Exception& )
1188 DBG_ERROR("SdrTableObj::InsertColumns(), exception caught!");
1192 // --------------------------------------------------------------------
1194 void SdrTableObj::DeleteRows( sal_Int32 nIndex, sal_Int32 nCount /*= 1*/ )
1196 if( mpImpl->mxTable.is() ) try
1198 Reference< XTableRows > xRows( mpImpl->mxTable->getRows(), UNO_QUERY_THROW );
1199 xRows->removeByIndex( nIndex, nCount );
1201 catch( Exception& )
1203 DBG_ERROR("SdrTableObj::DeleteRows(), exception caught!");
1207 // --------------------------------------------------------------------
1209 void SdrTableObj::DeleteColumns( sal_Int32 nIndex, sal_Int32 nCount /*= 1*/ )
1211 if( mpImpl->mxTable.is() ) try
1213 Reference< XTableColumns > xColumns( mpImpl->mxTable->getColumns(), UNO_QUERY_THROW );
1214 xColumns->removeByIndex( nIndex, nCount );
1216 catch( Exception& )
1218 DBG_ERROR("SdrTableObj::DeleteColumns(), exception caught!");
1222 // --------------------------------------------------------------------
1224 void SdrTableObj::setTableStyle( const Reference< XIndexAccess >& xTableStyle )
1226 if( mpImpl && (mpImpl->mxTableStyle != xTableStyle) )
1228 mpImpl->disconnectTableStyle();
1229 mpImpl->mxTableStyle = xTableStyle;
1230 mpImpl->connectTableStyle();
1231 mpImpl->update();
1235 // --------------------------------------------------------------------
1237 const Reference< XIndexAccess >& SdrTableObj::getTableStyle() const
1239 if( mpImpl )
1241 return mpImpl->mxTableStyle;
1243 else
1245 static Reference< XIndexAccess > aTmp;
1246 return aTmp;
1250 // --------------------------------------------------------------------
1251 // text stuff
1252 // --------------------------------------------------------------------
1254 /** returns the currently active text. */
1255 SdrText* SdrTableObj::getActiveText() const
1257 return dynamic_cast< SdrText* >( getActiveCell().get() );
1260 // --------------------------------------------------------------------
1262 /** returns the nth available text. */
1263 SdrText* SdrTableObj::getText( sal_Int32 nIndex ) const
1265 if( mpImpl->mxTable.is() )
1267 const sal_Int32 nColCount = mpImpl->getColumnCount();
1268 if( nColCount )
1270 CellPos aPos( nIndex % nColCount, nIndex / nColCount );
1272 CellRef xCell( mpImpl->getCell( aPos ) );
1273 return dynamic_cast< SdrText* >( xCell.get() );
1276 return 0;
1279 // --------------------------------------------------------------------
1281 /** returns the number of texts available for this object. */
1282 sal_Int32 SdrTableObj::getTextCount() const
1284 if( mpImpl->mxTable.is() )
1286 const sal_Int32 nColCount = mpImpl->getColumnCount();
1287 const sal_Int32 nRowCount = mpImpl->getRowCount();
1289 return nColCount * nRowCount;
1291 else
1293 return 0;
1297 // --------------------------------------------------------------------
1299 /** changes the current active text */
1300 void SdrTableObj::setActiveText( sal_Int32 nIndex )
1302 if( mpImpl && mpImpl->mxTable.is() )
1304 const sal_Int32 nColCount = mpImpl->mxTable->getColumnCount();
1305 if( nColCount )
1307 CellPos aPos( nIndex % nColCount, nIndex / nColCount );
1308 if( isValid( aPos ) )
1309 setActiveCell( aPos );
1314 // --------------------------------------------------------------------
1316 /** returns the index of the text that contains the given point or -1 */
1317 sal_Int32 SdrTableObj::CheckTextHit(const Point& rPnt) const
1319 if( mpImpl && mpImpl->mxTable.is() )
1321 CellPos aPos;
1322 if( CheckTableHit( rPnt, aPos.mnCol, aPos.mnRow, 0 ) == SDRTABLEHIT_CELLTEXTAREA )
1323 return aPos.mnRow * mpImpl->mxTable->getColumnCount() + aPos.mnCol;
1326 return 0;
1329 // --------------------------------------------------------------------
1331 SdrOutliner* SdrTableObj::GetCellTextEditOutliner( const Cell& rCell ) const
1333 if( mpImpl && (mpImpl->getCell( mpImpl->maEditPos ).get() == &rCell) )
1334 return pEdtOutl;
1335 else
1336 return 0;
1340 // --------------------------------------------------------------------
1342 const TableLayouter& SdrTableObj::getTableLayouter() const
1344 OSL_ENSURE(mpImpl && mpImpl->mpLayouter, "getTableLayouter() error: no mpImpl or mpLayouter (!)");
1345 return *(mpImpl->mpLayouter);
1348 // --------------------------------------------------------------------
1350 void SdrTableObj::FitFrameToTextSize()
1352 // todo
1355 // --------------------------------------------------------------------
1357 FASTBOOL SdrTableObj::IsAutoGrowHeight() const
1359 return TRUE;
1362 // --------------------------------------------------------------------
1364 FASTBOOL SdrTableObj::IsAutoGrowWidth() const
1366 return TRUE;
1369 // --------------------------------------------------------------------
1371 bool SdrTableObj::HasText() const
1373 return true;
1376 // --------------------------------------------------------------------
1378 bool SdrTableObj::IsTextEditActive( const CellPos& rPos )
1380 return pEdtOutl && mpImpl && (rPos == mpImpl->maEditPos);
1383 // --------------------------------------------------------------------
1385 void SdrTableObj::onEditOutlinerStatusEvent( EditStatus* pEditStatus )
1387 if( (pEditStatus->GetStatusWord() & EE_STAT_TEXTHEIGHTCHANGED) && mpImpl && mpImpl->mpLayouter )
1389 Rectangle aRect0( aRect );
1390 aRect = maLogicRect;
1391 // mpImpl->mpLayouter->setRowHeight( mpImpl->maEditPos.mnRow, mpImpl->mnSavedEditRowHeight );
1392 mpImpl->LayoutTable( aRect, false, false );
1393 SetRectsDirty();
1394 ActionChanged();
1395 BroadcastObjectChange();
1396 if( aRect0 != aRect )
1397 SendUserCall(SDRUSERCALL_RESIZE,aRect0);
1401 // --------------------------------------------------------------------
1403 void SdrTableObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
1405 rInfo.bResizeFreeAllowed=TRUE;
1406 rInfo.bResizePropAllowed=TRUE;
1407 rInfo.bRotateFreeAllowed=FALSE;
1408 rInfo.bRotate90Allowed =FALSE;
1409 rInfo.bMirrorFreeAllowed=FALSE;
1410 rInfo.bMirror45Allowed =FALSE;
1411 rInfo.bMirror90Allowed =FALSE;
1413 // allow transparence
1414 rInfo.bTransparenceAllowed = TRUE;
1416 // gradient depends on fillstyle
1417 XFillStyle eFillStyle = ((XFillStyleItem&)(GetObjectItem(XATTR_FILLSTYLE))).GetValue();
1418 rInfo.bGradientAllowed = (eFillStyle == XFILL_GRADIENT);
1419 rInfo.bShearAllowed =FALSE;
1420 rInfo.bEdgeRadiusAllowed=FALSE;
1421 rInfo.bCanConvToPath =FALSE;
1422 rInfo.bCanConvToPoly =FALSE;
1423 rInfo.bCanConvToPathLineToArea=FALSE;
1424 rInfo.bCanConvToPolyLineToArea=FALSE;
1425 rInfo.bCanConvToContour = FALSE;
1428 // --------------------------------------------------------------------
1430 UINT16 SdrTableObj::GetObjIdentifier() const
1432 return static_cast<UINT16>(OBJ_TABLE);
1435 // --------------------------------------------------------------------
1437 void SdrTableObj::SetPage(SdrPage* pNewPage)
1439 SdrTextObj::SetPage(pNewPage);
1442 // --------------------------------------------------------------------
1444 void SdrTableObj::SetModel(SdrModel* pNewModel)
1446 SdrModel* pOldModel = GetModel();
1447 if( pNewModel != pOldModel )
1449 SdrTextObj::SetModel(pNewModel);
1451 if( mpImpl )
1453 mpImpl->SetModel( pOldModel, pNewModel );
1455 if( !maLogicRect.IsEmpty() )
1457 aRect = maLogicRect;
1458 mpImpl->LayoutTable( aRect, false, false );
1464 // --------------------------------------------------------------------
1466 void SdrTableObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText, Rectangle* pAnchorRect, BOOL bLineWidth ) const
1468 if( mpImpl )
1469 TakeTextRect( mpImpl->maEditPos, rOutliner, rTextRect, bNoEditText, pAnchorRect, bLineWidth );
1472 // --------------------------------------------------------------------
1474 void SdrTableObj::TakeTextRect( const CellPos& rPos, SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText, Rectangle* pAnchorRect, BOOL /*bLineWidth*/ ) const
1476 if( !mpImpl )
1477 return;
1479 CellRef xCell( mpImpl->getCell( rPos ) );
1480 if( !xCell.is() )
1481 return;
1483 Rectangle aAnkRect;
1484 TakeTextAnchorRect( rPos, aAnkRect );
1486 SdrTextVertAdjust eVAdj=xCell->GetTextVerticalAdjust();
1487 // SdrTextHorzAdjust eHAdj=xCell->GetTextHorizontalAdjust();
1489 ULONG nStat0=rOutliner.GetControlWord();
1490 Size aNullSize;
1491 nStat0 |= EE_CNTRL_AUTOPAGESIZE;
1492 rOutliner.SetControlWord(nStat0);
1493 rOutliner.SetMinAutoPaperSize(aNullSize);
1494 rOutliner.SetMaxAutoPaperSize(aAnkRect.GetSize());
1495 rOutliner.SetPaperSize(aAnkRect.GetSize());
1497 // #103516# New try with _BLOCK for hor and ver after completely
1498 // supporting full width for vertical text.
1499 // if( SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
1500 // {
1501 rOutliner.SetMinAutoPaperSize(Size(aAnkRect.GetWidth(), 0));
1502 // }
1503 // else if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
1504 // {
1505 // rOutliner.SetMinAutoPaperSize(Size(0, aAnkRect.GetHeight()));
1506 // }
1508 // ---
1510 // set text at outliner, maybe from edit outliner
1511 OutlinerParaObject* pPara= xCell->GetOutlinerParaObject();
1512 if (pEdtOutl && !bNoEditText && mpImpl->mxActiveCell == xCell )
1513 pPara=pEdtOutl->CreateParaObject();
1515 if (pPara)
1517 const bool bHitTest = pModel && (&pModel->GetHitTestOutliner() == &rOutliner);
1519 const SdrTextObj* pTestObj = rOutliner.GetTextObj();
1520 if( !pTestObj || !bHitTest || (pTestObj != this) || (pTestObj->GetOutlinerParaObject() != xCell->GetOutlinerParaObject()) )
1522 if( bHitTest ) // #i33696# take back fix #i27510#
1523 rOutliner.SetTextObj( this );
1525 rOutliner.SetUpdateMode(TRUE);
1526 rOutliner.SetText(*pPara);
1529 else
1531 rOutliner.SetTextObj( NULL );
1534 if (pEdtOutl && !bNoEditText && pPara && mpImpl->mxActiveCell == xCell )
1535 delete pPara;
1537 rOutliner.SetUpdateMode(TRUE);
1538 rOutliner.SetControlWord(nStat0);
1540 Point aTextPos(aAnkRect.TopLeft());
1541 Size aTextSiz(rOutliner.GetPaperSize());
1543 if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT)
1545 long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width();
1546 if (eHAdj==SDRTEXTHORZADJUST_CENTER)
1547 aTextPos.X()+=nFreeWdt/2;
1548 if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
1549 aTextPos.X()+=nFreeWdt;
1552 if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM)
1554 long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
1555 if (eVAdj==SDRTEXTVERTADJUST_CENTER)
1556 aTextPos.Y()+=nFreeHgt/2;
1557 if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
1558 aTextPos.Y()+=nFreeHgt;
1561 if (pAnchorRect)
1562 *pAnchorRect=aAnkRect;
1564 rTextRect=Rectangle(aTextPos,aTextSiz);
1567 // --------------------------------------------------------------------
1569 const CellRef& SdrTableObj::getActiveCell() const
1571 if( mpImpl )
1573 if( !mpImpl->mxActiveCell.is() )
1575 CellPos aPos;
1576 const_cast< SdrTableObj* >(this)->setActiveCell( aPos );
1578 return mpImpl->mxActiveCell;
1580 else
1582 static CellRef xCell;
1583 return xCell;
1587 // --------------------------------------------------------------------
1589 sal_Int32 SdrTableObj::getRowCount() const
1591 return mpImpl ? mpImpl->getRowCount() : 0;
1594 // --------------------------------------------------------------------
1596 sal_Int32 SdrTableObj::getColumnCount() const
1598 return mpImpl ? mpImpl->getColumnCount() : 0;
1601 // --------------------------------------------------------------------
1603 void SdrTableObj::setActiveCell( const CellPos& rPos )
1605 if( mpImpl && mpImpl->mxTable.is() ) try
1607 mpImpl->mxActiveCell.set( dynamic_cast< Cell* >( mpImpl->mxTable->getCellByPosition( rPos.mnCol, rPos.mnRow ).get() ) );
1608 if( mpImpl->mxActiveCell.is() && mpImpl->mxActiveCell->isMerged() )
1610 CellPos aOrigin;
1611 findMergeOrigin( mpImpl->mxTable.get(), rPos.mnCol, rPos.mnRow, aOrigin.mnCol, aOrigin.mnRow );
1612 mpImpl->mxActiveCell.set( dynamic_cast< Cell* >( mpImpl->mxTable->getCellByPosition( aOrigin.mnCol, aOrigin.mnRow ).get() ) );
1613 mpImpl->maEditPos = aOrigin;
1615 else
1617 mpImpl->maEditPos = rPos;
1620 catch( Exception& )
1622 DBG_ERROR("SdrTableObj::setActiveCell(), exception caught!");
1626 // --------------------------------------------------------------------
1628 void SdrTableObj::getActiveCellPos( CellPos& rPos ) const
1630 rPos = mpImpl->maEditPos;
1633 // --------------------------------------------------------------------
1635 void SdrTableObj::getCellBounds( const CellPos& rPos, ::Rectangle& rCellRect )
1637 if( mpImpl )
1639 CellRef xCell( mpImpl->getCell( rPos ) );
1640 if( xCell.is() )
1641 rCellRect = xCell->getCellRect();
1645 // --------------------------------------------------------------------
1647 void SdrTableObj::TakeTextAnchorRect(Rectangle& rAnchorRect) const
1649 if( mpImpl )
1650 TakeTextAnchorRect( mpImpl->maEditPos, rAnchorRect );
1653 // --------------------------------------------------------------------
1655 void SdrTableObj::TakeTextAnchorRect( const CellPos& rPos, Rectangle& rAnchorRect ) const
1657 Rectangle aAnkRect(aRect);
1659 if( mpImpl )
1661 CellRef xCell( mpImpl->getCell( rPos ) );
1662 if( xCell.is() )
1663 xCell->TakeTextAnchorRect( aAnkRect );
1666 ImpJustifyRect(aAnkRect);
1667 rAnchorRect=aAnkRect;
1670 // --------------------------------------------------------------------
1672 void SdrTableObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
1674 if( mpImpl )
1675 TakeTextEditArea( mpImpl->maEditPos, pPaperMin, pPaperMax, pViewInit, pViewMin );
1678 // --------------------------------------------------------------------
1680 void SdrTableObj::TakeTextEditArea( const CellPos& rPos, Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin ) const
1682 Size aPaperMin,aPaperMax;
1683 Rectangle aViewInit;
1684 TakeTextAnchorRect( rPos, aViewInit );
1686 Size aAnkSiz(aViewInit.GetSize());
1687 aAnkSiz.Width()--; aAnkSiz.Height()--; // weil GetSize() ein draufaddiert
1689 Size aMaxSiz(aAnkSiz.Width(),1000000);
1690 if (pModel!=NULL)
1692 Size aTmpSiz(pModel->GetMaxObjSize());
1693 if (aTmpSiz.Height()!=0)
1694 aMaxSiz.Height()=aTmpSiz.Height();
1697 CellRef xCell( mpImpl->getCell( rPos ) );
1698 SdrTextVertAdjust eVAdj = xCell.is() ? xCell->GetTextVerticalAdjust() : SDRTEXTVERTADJUST_TOP;
1699 // SdrTextHorzAdjust eHAdj = xCell.is() ? xCell->GetTextHorizontalAdjust() : SDRTEXTHORZADJUST_LEFT;
1701 aPaperMax=aMaxSiz;
1703 // if((SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting()) || (SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting()))
1704 aPaperMin.Width() = aAnkSiz.Width();
1706 if (pViewMin!=NULL)
1708 *pViewMin=aViewInit;
1710 long nXFree=aAnkSiz.Width()-aPaperMin.Width();
1712 if (eHAdj==SDRTEXTHORZADJUST_LEFT)
1714 pViewMin->Right()-=nXFree;
1716 else if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
1718 pViewMin->Left()+=nXFree;
1720 else
1722 pViewMin->Left()+=nXFree/2;
1723 pViewMin->Right()=pViewMin->Left()+aPaperMin.Width();
1726 long nYFree=aAnkSiz.Height()-aPaperMin.Height();
1728 if (eVAdj==SDRTEXTVERTADJUST_TOP)
1730 pViewMin->Bottom()-=nYFree;
1732 else if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
1734 pViewMin->Top()+=nYFree;
1736 else
1738 pViewMin->Top()+=nYFree/2;
1739 pViewMin->Bottom()=pViewMin->Top()+aPaperMin.Height();
1744 if(IsVerticalWriting())
1745 aPaperMin.Width() = 0;
1746 else
1747 aPaperMin.Height() = 0;
1749 if (pPaperMin!=NULL) *pPaperMin=aPaperMin;
1750 if (pPaperMax!=NULL) *pPaperMax=aPaperMax;
1751 if (pViewInit!=NULL) *pViewInit=aViewInit;
1754 // --------------------------------------------------------------------
1756 USHORT SdrTableObj::GetOutlinerViewAnchorMode() const
1758 EVAnchorMode eRet=ANCHOR_TOP_LEFT;
1759 CellRef xCell( getActiveCell() );
1760 if( xCell.is() )
1762 SdrTextVertAdjust eV=xCell->GetTextVerticalAdjust();
1763 // SdrTextHorzAdjust eH=xCell->GetTextHorizontalAdjust();
1765 // if (eH==SDRTEXTHORZADJUST_LEFT)
1767 if (eV==SDRTEXTVERTADJUST_TOP)
1769 eRet=ANCHOR_TOP_LEFT;
1771 else if (eV==SDRTEXTVERTADJUST_BOTTOM)
1773 eRet=ANCHOR_BOTTOM_LEFT;
1775 else
1777 eRet=ANCHOR_VCENTER_LEFT;
1781 else if (eH==SDRTEXTHORZADJUST_RIGHT)
1783 if (eV==SDRTEXTVERTADJUST_TOP)
1785 eRet=ANCHOR_TOP_RIGHT;
1787 else if (eV==SDRTEXTVERTADJUST_BOTTOM)
1789 eRet=ANCHOR_BOTTOM_RIGHT;
1791 else
1793 eRet=ANCHOR_VCENTER_RIGHT;
1796 else
1798 if (eV==SDRTEXTVERTADJUST_TOP)
1800 eRet=ANCHOR_TOP_HCENTER;
1802 else if (eV==SDRTEXTVERTADJUST_BOTTOM)
1804 eRet=ANCHOR_BOTTOM_HCENTER;
1806 else
1808 eRet=ANCHOR_VCENTER_HCENTER;
1813 return (USHORT)eRet;
1816 // --------------------------------------------------------------------
1818 OutlinerParaObject* SdrTableObj::GetEditOutlinerParaObject() const
1820 return SdrTextObj::GetEditOutlinerParaObject();
1823 // --------------------------------------------------------------------
1825 SdrOutliner* SdrTableObj::GetCellTextEditOutliner( const CellPos& rPos ) const
1827 if( pEdtOutl && mpImpl && (mpImpl->maEditPos == rPos) )
1828 return pEdtOutl;
1829 else
1830 return 0;
1833 // --------------------------------------------------------------------
1835 struct ImplTableShadowPaintInfo
1837 Color maShadowColor;
1838 sal_uInt32 mnXDistance;
1839 sal_uInt32 mnYDistance;
1840 sal_uInt16 mnShadowTransparence;
1842 ImplTableShadowPaintInfo( const SfxItemSet& rSet )
1844 const SdrShadowColorItem& rShadColItem = ((const SdrShadowColorItem&)(rSet.Get(SDRATTR_SHADOWCOLOR)));
1845 maShadowColor = rShadColItem.GetColorValue();
1846 mnShadowTransparence = ((const SdrShadowTransparenceItem&)(rSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue();
1848 mnXDistance = ((SdrShadowXDistItem&)(rSet.Get(SDRATTR_SHADOWXDIST))).GetValue();
1849 mnYDistance = ((SdrShadowYDistItem&)(rSet.Get(SDRATTR_SHADOWYDIST))).GetValue();
1853 // --------------------------------------------------------------------
1855 void lcl_VertLineEnds( OutputDevice& rDev, const Point& rTop, const Point& rBottom,
1856 const Color& rColor, long nXOffs, long nWidth,
1857 const svx::frame::Style& rTopLine, const svx::frame::Style& rBottomLine )
1859 rDev.SetLineColor(rColor); // PEN_NULL ???
1860 rDev.SetFillColor(rColor);
1862 // Position oben/unten muss unabhaengig von der Liniendicke sein,
1863 // damit der Winkel stimmt (oder X-Position auch anpassen)
1864 long nTopPos = rTop.Y();
1865 long nBotPos = rBottom.Y();
1867 long nTopLeft = rTop.X() + nXOffs;
1868 long nTopRight = nTopLeft + nWidth - 1;
1870 long nBotLeft = rBottom.X() + nXOffs;
1871 long nBotRight = nBotLeft + nWidth - 1;
1873 // oben abschliessen
1875 if ( rTopLine.Prim() )
1877 long nLineW = rTopLine.GetWidth();
1878 if (nLineW >= 2)
1880 Point aTriangle[3];
1881 aTriangle[0] = Point( nTopLeft, nTopPos ); // wie aPoints[0]
1882 aTriangle[1] = Point( nTopRight, nTopPos ); // wie aPoints[1]
1883 aTriangle[2] = Point( rTop.X(), nTopPos - (nLineW - 1) / 2 );
1884 Polygon aTriPoly( 3, aTriangle );
1885 rDev.DrawPolygon( aTriPoly );
1889 // unten abschliessen
1891 if ( rBottomLine.Prim() )
1893 long nLineW = rBottomLine.GetWidth();
1894 if (nLineW >= 2)
1896 Point aTriangle[3];
1897 aTriangle[0] = Point( nBotLeft, nBotPos ); // wie aPoints[3]
1898 aTriangle[1] = Point( nBotRight, nBotPos ); // wie aPoints[2]
1899 aTriangle[2] = Point( rBottom.X(), nBotPos - (nLineW - 1) / 2 + nLineW - 1 );
1900 Polygon aTriPoly( 3, aTriangle );
1901 rDev.DrawPolygon( aTriPoly );
1906 void lcl_VertLine( OutputDevice& rDev, const Point& rTop, const Point& rBottom,
1907 const svx::frame::Style& rLine,
1908 const svx::frame::Style& rTopLine, const svx::frame::Style& rBottomLine,
1909 const Color* pForceColor )
1911 if( rLine.Prim() )
1913 svx::frame::DrawVerFrameBorderSlanted( rDev, rTop, rBottom, rLine, pForceColor );
1915 svx::frame::Style aScaled( rLine );
1916 aScaled.ScaleSelf( 1.0 / cos( svx::frame::GetVerDiagAngle( rTop, rBottom ) ) );
1917 if( pForceColor )
1918 aScaled.SetColor( *pForceColor );
1920 long nXOffs = (aScaled.GetWidth() - 1) / -2L;
1922 lcl_VertLineEnds( rDev, rTop, rBottom, aScaled.GetColor(),
1923 nXOffs, aScaled.Prim(), rTopLine, rBottomLine );
1925 if( aScaled.Secn() )
1926 lcl_VertLineEnds( rDev, rTop, rBottom, aScaled.GetColor(),
1927 nXOffs + aScaled.Prim() + aScaled.Dist(), aScaled.Secn(), rTopLine, rBottomLine );
1931 // --------------------------------------------------------------------
1933 void SdrTableObj::TakeObjNameSingul(XubString& rName) const
1935 rName = ImpGetResStr(STR_ObjNameSingulTable);
1937 String aName( GetName() );
1938 if(aName.Len())
1940 rName += sal_Unicode(' ');
1941 rName += sal_Unicode('\'');
1942 rName += aName;
1943 rName += sal_Unicode('\'');
1947 // --------------------------------------------------------------------
1949 void SdrTableObj::TakeObjNamePlural(XubString& rName) const
1951 rName = ImpGetResStr(STR_ObjNamePluralTable);
1954 // --------------------------------------------------------------------
1956 void SdrTableObj::operator=(const SdrObject& rObj)
1958 // call parent
1959 SdrObject::operator=(rObj);
1961 const SdrTableObj* pTableObj = dynamic_cast< const SdrTableObj* >( &rObj );
1962 if (pTableObj!=NULL)
1964 TableModelNotifyGuard aGuard( mpImpl ? mpImpl->mxTable.get() : 0 );
1966 maLogicRect = pTableObj->maLogicRect;
1967 aRect = pTableObj->aRect;
1968 aGeo = pTableObj->aGeo;
1969 eTextKind = pTableObj->eTextKind;
1970 bTextFrame = pTableObj->bTextFrame;
1971 aTextSize = pTableObj->aTextSize;
1972 bTextSizeDirty = pTableObj->bTextSizeDirty;
1973 bNoShear = pTableObj->bNoShear;
1974 bNoRotate = pTableObj->bNoRotate;
1975 bNoMirror = pTableObj->bNoMirror;
1976 bDisableAutoWidthOnDragging = pTableObj->bDisableAutoWidthOnDragging;
1978 if( pTableObj->mpImpl )
1979 *mpImpl = *pTableObj->mpImpl;
1983 // --------------------------------------------------------------------
1985 basegfx::B2DPolyPolygon SdrTableObj::TakeXorPoly() const
1987 return SdrTextObj::TakeXorPoly();
1990 // --------------------------------------------------------------------
1992 basegfx::B2DPolyPolygon SdrTableObj::TakeContour() const
1994 return SdrTextObj::TakeContour();
1997 // --------------------------------------------------------------------
1999 const Rectangle& SdrTableObj::GetSnapRect() const
2001 return aRect;
2004 // --------------------------------------------------------------------
2006 void SdrTableObj::NbcSetSnapRect(const Rectangle& rRect)
2008 NbcSetLogicRect( rRect );
2011 // --------------------------------------------------------------------
2013 const Rectangle& SdrTableObj::GetLogicRect() const
2015 return maLogicRect;
2018 // --------------------------------------------------------------------
2020 void SdrTableObj::RecalcSnapRect()
2024 // --------------------------------------------------------------------
2026 sal_uInt32 SdrTableObj::GetSnapPointCount() const
2028 return SdrTextObj::GetSnapPointCount();
2031 // --------------------------------------------------------------------
2034 Point SdrTableObj::GetSnapPoint(sal_uInt32 i) const
2036 return SdrTextObj::GetSnapPoint(i);
2039 // --------------------------------------------------------------------
2041 sal_Bool SdrTableObj::BegTextEdit(SdrOutliner& rOutl)
2043 if( pEdtOutl != NULL )
2044 return sal_False;
2046 pEdtOutl=&rOutl;
2048 // ForceOutlinerParaObject();
2050 mbInEditMode = TRUE;
2052 rOutl.Init( OUTLINERMODE_TEXTOBJECT );
2053 rOutl.SetRefDevice( pModel->GetRefDevice() );
2055 // --
2056 FASTBOOL bUpdMerk=rOutl.GetUpdateMode();
2057 if (bUpdMerk) rOutl.SetUpdateMode(FALSE);
2058 Size aPaperMin;
2059 Size aPaperMax;
2060 Rectangle aEditArea;
2061 TakeTextEditArea(&aPaperMin,&aPaperMax,&aEditArea,NULL);
2063 rOutl.SetMinAutoPaperSize(aPaperMin);
2064 rOutl.SetMaxAutoPaperSize(aPaperMax);
2065 rOutl.SetPaperSize(aPaperMax);
2067 if (bUpdMerk) rOutl.SetUpdateMode(TRUE);
2068 //---
2070 ULONG nStat=rOutl.GetControlWord();
2071 // nStat &= ~EE_CNTRL_AUTOPAGESIZE;
2072 nStat |= EE_CNTRL_AUTOPAGESIZE;
2073 nStat &=~EE_CNTRL_STRETCHING;
2074 rOutl.SetControlWord(nStat);
2076 OutlinerParaObject* pPara = GetOutlinerParaObject();
2077 if(pPara)
2078 rOutl.SetText(*pPara);
2080 rOutl.UpdateFields();
2081 rOutl.ClearModifyFlag();
2083 // mpImpl->mnSavedEditRowHeight = mpImpl->mpLayouter->getRowHeight( mpImpl->maEditPos.mnRow );
2085 return sal_True;
2088 // --------------------------------------------------------------------
2090 void SdrTableObj::EndTextEdit(SdrOutliner& rOutl)
2092 if(rOutl.IsModified())
2094 if( GetModel() && GetModel()->IsUndoEnabled() )
2095 GetModel()->AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*this) );
2097 OutlinerParaObject* pNewText = 0;
2098 Paragraph* p1stPara = rOutl.GetParagraph( 0 );
2099 UINT32 nParaAnz = rOutl.GetParagraphCount();
2101 if(p1stPara)
2103 if(nParaAnz == 1)
2105 // if its only one paragraph, check if it is empty
2106 XubString aStr(rOutl.GetText(p1stPara));
2108 if(!aStr.Len())
2110 // gotcha!
2111 nParaAnz = 0;
2115 // to remove the grey field background
2116 rOutl.UpdateFields();
2118 if(nParaAnz != 0)
2120 // create new text object
2121 pNewText = rOutl.CreateParaObject( 0, (sal_uInt16)nParaAnz );
2124 SetOutlinerParaObject(pNewText);
2127 pEdtOutl = 0;
2128 rOutl.Clear();
2129 UINT32 nStat = rOutl.GetControlWord();
2130 nStat &= ~EE_CNTRL_AUTOPAGESIZE;
2131 rOutl.SetControlWord(nStat);
2133 mbInEditMode = FALSE;
2136 // --------------------------------------------------------------------
2138 OutlinerParaObject* SdrTableObj::GetOutlinerParaObject() const
2140 CellRef xCell( getActiveCell() );
2141 if( xCell.is() )
2142 return xCell->GetOutlinerParaObject();
2143 else
2144 return 0;
2147 // --------------------------------------------------------------------
2149 void SdrTableObj::NbcSetOutlinerParaObject( OutlinerParaObject* pTextObject)
2151 CellRef xCell( getActiveCell() );
2152 if( xCell.is() )
2154 if( pModel )
2156 // Update HitTestOutliner
2157 const SdrTextObj* pTestObj = pModel->GetHitTestOutliner().GetTextObj();
2158 if( pTestObj && pTestObj->GetOutlinerParaObject() == xCell->GetOutlinerParaObject() )
2159 pModel->GetHitTestOutliner().SetTextObj( NULL );
2162 xCell->SetOutlinerParaObject( pTextObject );
2164 SetTextSizeDirty();
2165 NbcAdjustTextFrameWidthAndHeight();
2166 // ImpSetTextStyleSheetListeners();
2167 // ImpCheckMasterCachable();
2171 // --------------------------------------------------------------------
2173 void SdrTableObj::NbcSetLogicRect(const Rectangle& rRect)
2175 maLogicRect=rRect;
2176 ImpJustifyRect(maLogicRect);
2177 const bool bWidth = maLogicRect.getWidth() != aRect.getWidth();
2178 const bool bHeight = maLogicRect.getHeight() != aRect.getHeight();
2179 aRect=maLogicRect;
2180 NbcAdjustTextFrameWidthAndHeight( !bHeight, !bWidth );
2181 SetRectsDirty();
2184 // --------------------------------------------------------------------
2186 void SdrTableObj::NbcMove(const Size& rSiz)
2188 MoveRect(maLogicRect,rSiz);
2189 SdrTextObj::NbcMove( rSiz );
2190 if( mpImpl )
2191 mpImpl->UpdateCells( aRect );
2194 // --------------------------------------------------------------------
2196 void SdrTableObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
2198 Rectangle aOldRect( maLogicRect );
2199 ResizeRect(maLogicRect,rRef,xFact,yFact);
2201 aRect = maLogicRect;
2202 NbcAdjustTextFrameWidthAndHeight( maLogicRect.GetHeight() == aOldRect.GetHeight(), maLogicRect.GetWidth() == aOldRect.GetWidth() );
2203 SetRectsDirty();
2206 // --------------------------------------------------------------------
2208 FASTBOOL SdrTableObj::AdjustTextFrameWidthAndHeight(FASTBOOL bHgt, FASTBOOL bWdt)
2210 Rectangle aNeuRect(maLogicRect);
2211 FASTBOOL bRet=AdjustTextFrameWidthAndHeight(aNeuRect,bHgt,bWdt);
2212 if (bRet)
2214 Rectangle aBoundRect0;
2215 if (pUserCall!=NULL)
2216 aBoundRect0=GetLastBoundRect();
2217 aRect=aNeuRect;
2218 SetRectsDirty();
2219 SetChanged();
2220 BroadcastObjectChange();
2221 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
2223 return bRet;
2226 // --------------------------------------------------------------------
2228 FASTBOOL SdrTableObj::AdjustTextFrameWidthAndHeight(Rectangle& rR, FASTBOOL bHeight, FASTBOOL bWidth) const
2230 if((pModel == NULL) || rR.IsEmpty() || !mpImpl || !mpImpl->mxTable.is() )
2231 return FALSE;
2233 Rectangle aRectangle( rR );
2234 mpImpl->LayoutTable( aRectangle, !bWidth, !bHeight );
2236 if( aRectangle != rR )
2238 rR = aRectangle;
2239 return TRUE;
2241 else
2243 return FALSE;
2247 // --------------------------------------------------------------------
2249 void SdrTableObj::NbcReformatText()
2251 NbcAdjustTextFrameWidthAndHeight();
2254 // --------------------------------------------------------------------
2256 void SdrTableObj::ReformatText()
2258 Rectangle aBoundRect0;
2259 if (pUserCall!=NULL)
2260 aBoundRect0=GetLastBoundRect();
2261 NbcReformatText();
2262 SetChanged();
2263 BroadcastObjectChange();
2264 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
2267 // --------------------------------------------------------------------
2269 sal_Bool SdrTableObj::IsVerticalWriting() const
2271 const SvxWritingModeItem* pModeItem = dynamic_cast< const SvxWritingModeItem* >( &GetObjectItem( SDRATTR_TEXTDIRECTION ) );
2272 return pModeItem && pModeItem->GetValue() == com::sun::star::text::WritingMode_TB_RL;
2275 // --------------------------------------------------------------------
2277 void SdrTableObj::SetVerticalWriting(sal_Bool bVertical )
2279 if( bVertical != IsVerticalWriting() )
2281 SvxWritingModeItem aModeItem( com::sun::star::text::WritingMode_LR_TB, SDRATTR_TEXTDIRECTION );
2282 SetObjectItem( aModeItem );
2286 // --------------------------------------------------------------------
2288 WritingMode SdrTableObj::GetWritingMode() const
2290 WritingMode eMode = WritingMode_LR_TB;
2291 if( mpImpl && mpImpl->mpLayouter )
2292 eMode = mpImpl->mpLayouter->GetWritingMode();
2293 return eMode;
2296 // --------------------------------------------------------------------
2298 // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
2299 // with the base geometry and returns TRUE. Otherwise it returns FALSE.
2300 sal_Bool SdrTableObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& rPolyPolygon ) const
2302 return SdrTextObj::TRGetBaseGeometry( rMatrix, rPolyPolygon );
2305 // --------------------------------------------------------------------
2307 // sets the base geometry of the object using infos contained in the homogen 3x3 matrix.
2308 // If it's an SdrPathObj it will use the provided geometry information. The Polygon has
2309 // to use (0,0) as upper left and will be scaled to the given size in the matrix.
2310 void SdrTableObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& rPolyPolygon )
2312 SdrTextObj::TRSetBaseGeometry( rMatrix, rPolyPolygon );
2315 // --------------------------------------------------------------------
2317 bool SdrTableObj::IsRealyEdited() const
2319 return pEdtOutl && pEdtOutl->IsModified();
2322 // --------------------------------------------------------------------
2324 FASTBOOL SdrTableObj::IsFontwork() const
2326 return FALSE;
2329 // --------------------------------------------------------------------
2331 sal_uInt32 SdrTableObj::GetHdlCount() const
2333 sal_uInt32 nCount = SdrTextObj::GetHdlCount();
2334 const sal_Int32 nRowCount = mpImpl->getRowCount();
2335 const sal_Int32 nColCount = mpImpl->getColumnCount();
2337 if( nRowCount && nColCount )
2338 nCount += nRowCount + nColCount + 2 + 1;
2340 return nCount;
2343 // --------------------------------------------------------------------
2345 void SdrTableObj::AddToHdlList(SdrHdlList& rHdlList) const
2347 const sal_Int32 nRowCount = mpImpl->getRowCount();
2348 const sal_Int32 nColCount = mpImpl->getColumnCount();
2350 // first add row handles
2351 std::vector< TableEdgeHdl* > aRowEdges( nRowCount + 1 );
2353 for( sal_Int32 nRow = 0; nRow <= nRowCount; nRow++ )
2355 sal_Int32 nEdgeMin, nEdgeMax;
2356 const sal_Int32 nEdge = mpImpl->mpLayouter->getHorizontalEdge( nRow, &nEdgeMin, &nEdgeMax );
2357 nEdgeMin -= nEdge;
2358 nEdgeMax -= nEdge;
2360 Point aPoint( aRect.TopLeft() );
2361 aPoint.Y() += nEdge;
2363 TableEdgeHdl* pHdl= new TableEdgeHdl(aPoint,true,nEdgeMin,nEdgeMax,nColCount+1);
2364 pHdl->SetPointNum( nRow );
2365 rHdlList.AddHdl( pHdl );
2366 aRowEdges[nRow] = pHdl;
2369 // second add column handles
2370 std::vector< TableEdgeHdl* > aColEdges( nColCount + 1 );
2372 for( sal_Int32 nCol = 0; nCol <= nColCount; nCol++ )
2374 sal_Int32 nEdgeMin, nEdgeMax;
2375 const sal_Int32 nEdge = mpImpl->mpLayouter->getVerticalEdge( nCol, &nEdgeMin, &nEdgeMax );
2376 nEdgeMin -= nEdge;
2377 nEdgeMax -= nEdge;
2379 Point aPoint( aRect.TopLeft() );
2380 aPoint.X() += nEdge;
2382 TableEdgeHdl* pHdl = new TableEdgeHdl(aPoint,false,nEdgeMin,nEdgeMax, nRowCount+1);
2383 pHdl->SetPointNum( nCol );
2384 rHdlList.AddHdl( pHdl );
2385 aColEdges[nCol] = pHdl;
2388 // now add visible edges to row and column handles
2389 if( mpImpl && mpImpl->mpLayouter )
2391 TableLayouter& rLayouter = *mpImpl->mpLayouter;
2393 sal_Int32 nY = 0;
2395 for( sal_Int32 nRow = 0; nRow <= nRowCount; ++nRow )
2397 const sal_Int32 nRowHeight = (nRow == nRowCount) ? 0 : rLayouter.getRowHeight(nRow);
2398 sal_Int32 nX = 0;
2400 for( sal_Int32 nCol = 0; nCol <= nColCount; ++nCol )
2402 const sal_Int32 nColWidth = (nCol == nColCount) ? 0 : rLayouter.getColumnWidth(nCol);
2404 if( nRowHeight > 0 )
2406 if( rLayouter.isEdgeVisible( nCol, nRow, false ) )
2407 aColEdges[nCol]->SetEdge( nRow, nY, nY + nRowHeight, (rLayouter.getBorderLine( nCol, nRow, false ) == 0) ? Visible : Invisible);
2410 if( nColWidth > 0 )
2412 if( rLayouter.isEdgeVisible( nCol, nRow, true ) )
2413 aRowEdges[nRow]->SetEdge( nCol, nX, nX + nColWidth, (rLayouter.getBorderLine( nCol, nRow, true ) == 0) ? Visible : Invisible);
2416 nX += nColWidth;
2419 nY += nRowHeight;
2423 // add remaining handles
2424 SdrHdl* pH=0;
2425 rHdlList.AddHdl( pH = new TableBorderHdl( aRect ) ); pH->SetMoveOutside( true );
2426 rHdlList.AddHdl( pH = new SdrHdl(aRect.TopLeft(),HDL_UPLFT) ); pH->SetMoveOutside( true );
2427 rHdlList.AddHdl( pH = new SdrHdl(aRect.TopCenter(),HDL_UPPER) ); pH->SetMoveOutside( true );
2428 rHdlList.AddHdl( pH = new SdrHdl(aRect.TopRight(),HDL_UPRGT) ); pH->SetMoveOutside( true );
2429 rHdlList.AddHdl( pH = new SdrHdl(aRect.LeftCenter(),HDL_LEFT) ); pH->SetMoveOutside( true );
2430 rHdlList.AddHdl( pH = new SdrHdl(aRect.RightCenter(),HDL_RIGHT) ); pH->SetMoveOutside( true );
2431 rHdlList.AddHdl( pH = new SdrHdl(aRect.BottomLeft(),HDL_LWLFT) ); pH->SetMoveOutside( true );
2432 rHdlList.AddHdl( pH = new SdrHdl(aRect.BottomCenter(),HDL_LOWER) ); pH->SetMoveOutside( true );
2433 rHdlList.AddHdl( pH = new SdrHdl(aRect.BottomRight(),HDL_LWRGT) ); pH->SetMoveOutside( true );
2435 ULONG nHdlCount = rHdlList.GetHdlCount();
2436 for( ULONG nHdl = 0; nHdl < nHdlCount; nHdl++ )
2437 rHdlList.GetHdl(nHdl)->SetObj((SdrObject*)this);
2440 // --------------------------------------------------------------------
2442 SdrHdl* SdrTableObj::GetHdl(sal_uInt32 nHdlNum) const
2444 // #i73248#
2445 // Warn the user that this is ineffective and show alternatives. Should not be used at all.
2446 OSL_ENSURE(false, "SdrTableObj::GetHdl(): ineffective, use AddToHdlList instead (!)");
2448 // to have an alternative, get single handle using the ineffective way
2449 SdrHdl* pRetval = 0;
2450 SdrHdlList aLocalList(0);
2451 AddToHdlList(aLocalList);
2452 const sal_uInt32 nHdlCount(aLocalList.GetHdlCount());
2454 if(nHdlCount && nHdlNum < nHdlCount)
2456 // remove and remember. The other created handles will be deleted again with the
2457 // destruction of the local list
2458 pRetval = aLocalList.RemoveHdl(nHdlNum);
2461 return pRetval;
2464 ////////////////////////////////////////////////////////////////////////////////////////////////////
2465 // Draging
2467 bool SdrTableObj::hasSpecialDrag() const
2469 return true;
2472 bool SdrTableObj::beginSpecialDrag(SdrDragStat& rDrag) const
2474 const SdrHdl* pHdl = rDrag.GetHdl();
2475 const SdrHdlKind eHdl((pHdl == NULL) ? HDL_MOVE : pHdl->GetKind());
2477 switch( eHdl )
2479 case HDL_UPLFT:
2480 case HDL_UPPER:
2481 case HDL_UPRGT:
2482 case HDL_LEFT:
2483 case HDL_RIGHT:
2484 case HDL_LWLFT:
2485 case HDL_LOWER:
2486 case HDL_LWRGT:
2487 case HDL_MOVE:
2489 break;
2492 case HDL_USER:
2494 rDrag.SetEndDragChangesAttributes(false);
2495 rDrag.SetNoSnap(true);
2496 break;
2499 default:
2501 return false;
2505 return true;
2508 bool SdrTableObj::applySpecialDrag(SdrDragStat& rDrag)
2510 bool bRet(true);
2511 const SdrHdl* pHdl = rDrag.GetHdl();
2512 const SdrHdlKind eHdl((pHdl == NULL) ? HDL_MOVE : pHdl->GetKind());
2514 switch( eHdl )
2516 case HDL_UPLFT:
2517 case HDL_UPPER:
2518 case HDL_UPRGT:
2519 case HDL_LEFT:
2520 case HDL_RIGHT:
2521 case HDL_LWLFT:
2522 case HDL_LOWER:
2523 case HDL_LWRGT:
2525 const Rectangle aNewRectangle(ImpDragCalcRect(rDrag));
2527 if(aNewRectangle != aRect)
2529 NbcSetLogicRect(aNewRectangle);
2532 break;
2535 case HDL_MOVE:
2537 NbcMove( Size( rDrag.GetDX(), rDrag.GetDY() ) );
2538 break;
2541 case HDL_USER:
2543 rDrag.SetEndDragChangesAttributes(false);
2544 rDrag.SetNoSnap(true);
2545 const TableEdgeHdl* pEdgeHdl = dynamic_cast< const TableEdgeHdl* >( pHdl );
2547 if( pEdgeHdl )
2549 if( GetModel() && IsInserted() )
2551 rDrag.SetEndDragChangesAttributes(true);
2554 mpImpl->DragEdge( pEdgeHdl->IsHorizontalEdge(), pEdgeHdl->GetPointNum(), pEdgeHdl->GetValidDragOffset( rDrag ) );
2556 break;
2559 default:
2561 bRet = false;
2565 return bRet;
2568 String SdrTableObj::getSpecialDragComment(const SdrDragStat& rDrag) const
2570 return SdrTextObj::getSpecialDragComment( rDrag );
2573 basegfx::B2DPolyPolygon SdrTableObj::getSpecialDragPoly(const SdrDragStat& rDrag) const
2575 basegfx::B2DPolyPolygon aRetval;
2576 const SdrHdl* pHdl = rDrag.GetHdl();
2578 if(HDL_USER == pHdl->GetKind())
2580 const TableEdgeHdl* pEdgeHdl = dynamic_cast< const TableEdgeHdl* >( pHdl );
2582 if( pEdgeHdl )
2584 aRetval = pEdgeHdl->getSpecialDragPoly( rDrag );
2588 return aRetval;
2591 ////////////////////////////////////////////////////////////////////////////////////////////////////
2592 // Create
2593 // --------------------------------------------------------------------
2595 FASTBOOL SdrTableObj::BegCreate(SdrDragStat& rStat)
2597 rStat.SetOrtho4Possible();
2598 Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
2599 aRect1.Justify();
2600 rStat.SetActionRect(aRect1);
2601 aRect = aRect1;
2602 return TRUE;
2605 // --------------------------------------------------------------------
2607 FASTBOOL SdrTableObj::MovCreate(SdrDragStat& rStat)
2609 Rectangle aRect1;
2610 rStat.TakeCreateRect(aRect1);
2611 ImpJustifyRect(aRect1);
2612 rStat.SetActionRect(aRect1);
2613 aRect=aRect1; // fuer ObjName
2614 SetBoundRectDirty();
2615 bSnapRectDirty=TRUE;
2616 return TRUE;
2619 // --------------------------------------------------------------------
2621 FASTBOOL SdrTableObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
2623 rStat.TakeCreateRect(aRect);
2624 ImpJustifyRect(aRect);
2625 return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
2628 void SdrTableObj::BrkCreate(SdrDragStat& /*rStat*/)
2632 // --------------------------------------------------------------------
2634 FASTBOOL SdrTableObj::BckCreate(SdrDragStat& /*rStat*/)
2636 return TRUE;
2639 // --------------------------------------------------------------------
2641 basegfx::B2DPolyPolygon SdrTableObj::TakeCreatePoly(const SdrDragStat& rDrag) const
2643 Rectangle aRect1;
2644 rDrag.TakeCreateRect(aRect1);
2645 aRect1.Justify();
2647 basegfx::B2DPolyPolygon aRetval;
2648 const basegfx::B2DRange aRange(aRect1.Left(), aRect1.Top(), aRect1.Right(), aRect1.Bottom());
2649 aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
2650 return aRetval;
2653 // --------------------------------------------------------------------
2655 Pointer SdrTableObj::GetCreatePointer() const
2657 return Pointer(POINTER_CROSS);
2660 // --------------------------------------------------------------------
2662 void SdrTableObj::createCell( CellRef& xNewCell )
2664 xNewCell = Cell::create( *this, 0 );
2667 // --------------------------------------------------------------------
2669 SdrObjGeoData *SdrTableObj::NewGeoData() const
2671 return new TableObjectGeoData;
2674 // --------------------------------------------------------------------
2676 void SdrTableObj::SaveGeoData(SdrObjGeoData& rGeo) const
2678 DBG_ASSERT( dynamic_cast< TableObjectGeoData* >( &rGeo ), "svx::SdrTableObj::SaveGeoData(), illegal geo data!" );
2679 SdrTextObj::SaveGeoData (rGeo);
2681 ((TableObjectGeoData &) rGeo).maLogicRect = maLogicRect;
2684 // --------------------------------------------------------------------
2686 void SdrTableObj::RestGeoData(const SdrObjGeoData& rGeo)
2688 DBG_ASSERT( dynamic_cast< const TableObjectGeoData* >( &rGeo ), "svx::SdrTableObj::SaveGeoData(), illegal geo data!" );
2690 maLogicRect = ((TableObjectGeoData &) rGeo).maLogicRect;
2692 SdrTextObj::RestGeoData (rGeo);
2694 if( mpImpl )
2695 mpImpl->LayoutTable( aRect, false, false );
2696 ActionChanged();
2699 // --------------------------------------------------------------------
2701 SdrTableObj* SdrTableObj::CloneRange( const CellPos& rStart, const CellPos& rEnd )
2703 const sal_Int32 nColumns = rEnd.mnCol - rStart.mnCol + 1;
2704 const sal_Int32 nRows = rEnd.mnRow - rStart.mnRow + 1;
2706 SdrTableObj* pNewTableObj = new SdrTableObj( GetModel(), GetCurrentBoundRect(), nColumns, nRows);
2707 pNewTableObj->setTableStyleSettings( getTableStyleSettings() );
2708 pNewTableObj->setTableStyle( getTableStyle() );
2710 Reference< XTable > xTable( getTable() );
2711 Reference< XTable > xNewTable( pNewTableObj->getTable() );
2713 if( !xTable.is() || !xNewTable.is() )
2715 delete pNewTableObj;
2716 return 0;
2719 // copy cells
2720 for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
2722 for( sal_Int32 nCol = 0; nCol < nColumns; ++nCol ) try
2724 CellRef xTargetCell( dynamic_cast< Cell* >( xNewTable->getCellByPosition( nCol, nRow ).get() ) );
2725 if( xTargetCell.is() )
2726 xTargetCell->cloneFrom( dynamic_cast< Cell* >( xTable->getCellByPosition( rStart.mnCol + nCol, rStart.mnRow + nRow ).get() ) );
2728 catch( Exception& )
2730 DBG_ERROR( "svx::SvxTableController::GetMarkedObjModel(), exception caught!" );
2734 // copy row heights
2735 Reference< XTableRows > xNewRows( xNewTable->getRows(), UNO_QUERY_THROW );
2736 const OUString sHeight( RTL_CONSTASCII_USTRINGPARAM( "Height" ) );
2737 for( sal_Int32 nRow = 0; nRow < nRows; ++nRow )
2739 Reference< XPropertySet > xNewSet( xNewRows->getByIndex( nRow ), UNO_QUERY_THROW );
2740 xNewSet->setPropertyValue( sHeight, Any( mpImpl->mpLayouter->getRowHeight( rStart.mnRow + nRow ) ) );
2743 // copy column widths
2744 Reference< XTableColumns > xNewColumns( xNewTable->getColumns(), UNO_QUERY_THROW );
2745 const OUString sWidth( RTL_CONSTASCII_USTRINGPARAM( "Width" ) );
2746 for( sal_Int32 nCol = 0; nCol < nColumns; ++nCol )
2748 Reference< XPropertySet > xNewSet( xNewColumns->getByIndex( nCol ), UNO_QUERY_THROW );
2749 xNewSet->setPropertyValue( sWidth, Any( mpImpl->mpLayouter->getColumnWidth( rStart.mnCol + nCol ) ) );
2752 pNewTableObj->NbcReformatText();
2753 pNewTableObj->SetLogicRect( pNewTableObj->GetCurrentBoundRect() );
2755 return pNewTableObj;
2758 // --------------------------------------------------------------------
2760 void SdrTableObj::DistributeColumns( sal_Int32 nFirstColumn, sal_Int32 nLastColumn )
2762 if( mpImpl && mpImpl->mpLayouter )
2764 TableModelNotifyGuard aGuard( mpImpl->mxTable.get() );
2765 mpImpl->mpLayouter->DistributeColumns( aRect, nFirstColumn, nLastColumn );
2769 // --------------------------------------------------------------------
2771 void SdrTableObj::DistributeRows( sal_Int32 nFirstRow, sal_Int32 nLastRow )
2773 if( mpImpl && mpImpl->mpLayouter )
2775 TableModelNotifyGuard aGuard( mpImpl->mxTable.get() );
2776 mpImpl->mpLayouter->DistributeRows( aRect, nFirstRow, nLastRow );
2780 // --------------------------------------------------------------------
2782 void SdrTableObj::SetChanged()
2784 if( mpImpl )
2786 if( mpImpl->UpdateWritingMode() )
2787 mpImpl->LayoutTable( aRect, false, false );
2790 ::SdrTextObj::SetChanged();
2793 // --------------------------------------------------------------------
2795 void SdrTableObj::uno_lock()
2797 if( mpImpl && mpImpl->mxTable.is() )
2798 mpImpl->mxTable->lockBroadcasts();
2801 // --------------------------------------------------------------------
2803 void SdrTableObj::uno_unlock()
2805 if( mpImpl && mpImpl->mxTable.is() )
2806 mpImpl->mxTable->unlockBroadcasts();
2809 // --------------------------------------------------------------------